Commit d3124385 authored by Juanmi Huertas's avatar Juanmi Huertas Committed by Commit Bot

Adding CreateSwapChainProvider and removing AcceleratedDirect2DUsage

Marking kAcceleratedDirect2DUsage as deprecated.
Refactoring tests to use directly CreateSwapChainProvider or
 CreateSharedImageProvider when needed.
Refactoring CanvaResourceProviderHost to stop using ::Create.

Bug: 1035589
Change-Id: I24ca7823809735654a3f57dc05be60d4b78a2638
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2198922Reviewed-by: default avatarFernando Serboncini <fserb@chromium.org>
Reviewed-by: default avatarYi Xu <yiyix@chromium.org>
Commit-Queue: Juanmi Huertas <juanmihd@chromium.org>
Cr-Commit-Position: refs/heads/master@{#772316}
parent 1fcfb869
......@@ -169,93 +169,74 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider3D(
void CanvasRenderingContextHost::CreateCanvasResourceProvider2D(
AccelerationHint hint) {
DCHECK(Is2d());
const bool want_acceleration =
hint == kPreferAcceleration && ShouldAccelerate2dContext();
base::WeakPtr<CanvasResourceDispatcher> dispatcher =
GetOrCreateResourceDispatcher()
? GetOrCreateResourceDispatcher()->GetWeakPtr()
: nullptr;
uint8_t presentation_mode = CanvasResourceProvider::kDefaultPresentationMode;
bool composited_mode = false;
// Allow GMB image resources if the runtime feature is enabled or if
// we want to use it for low latency mode.
if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled() ||
(base::FeatureList::IsEnabled(
features::kLowLatencyCanvas2dImageChromium) &&
LowLatencyEnabled() && want_acceleration)) {
presentation_mode |=
CanvasResourceProvider::kAllowImageChromiumPresentationMode;
composited_mode = true;
}
if (base::FeatureList::IsEnabled(features::kLowLatencyCanvas2dSwapChain) &&
LowLatencyEnabled() && want_acceleration) {
presentation_mode |=
CanvasResourceProvider::kAllowSwapChainPresentationMode;
}
bool try_swap_chain = false;
CanvasResourceProvider::ResourceUsage usage;
if (want_acceleration) {
if (LowLatencyEnabled()) {
// Allow swap chains only if the runtime feature is enabled and we're
// in low latency mode too.
usage = CanvasResourceProvider::ResourceUsage::
kAcceleratedDirect2DResourceUsage;
try_swap_chain = true;
} else {
usage = CanvasResourceProvider::ResourceUsage::
kAcceleratedCompositedResourceUsage;
}
} else {
usage =
CanvasResourceProvider::ResourceUsage::kSoftwareCompositedResourceUsage;
}
std::unique_ptr<CanvasResourceProvider> provider;
const bool use_gpu =
hint == kPreferAcceleration && ShouldAccelerate2dContext();
// It is important to not use the context's IsOriginTopLeft() here
// because that denotes the current state and could change after the
// new resource provider is created e.g. due to switching between
// unaccelerated and accelerated modes during tab switching.
const bool is_origin_top_left = !want_acceleration || LowLatencyEnabled();
// First try to be optimized for displaying on screen. In the case we are
// hardware compositing, we also try to enable the usage of the image as
// scanout buffer (overlay)
uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY;
if (composited_mode)
shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
if (try_swap_chain) {
// Swap Chain is used for low latency.
provider = CanvasResourceProvider::Create(
Size(), usage, SharedGpuContext::ContextProviderWrapper(),
GetMSAASampleCountFor2dContext(), FilterQuality(), ColorParams(),
presentation_mode, std::move(dispatcher), is_origin_top_left);
} else if (want_acceleration) {
const bool is_origin_top_left = !use_gpu || LowLatencyEnabled();
if (use_gpu && LowLatencyEnabled()) {
// If we can use the gpu and low latency is enabled, we will try to use a
// SwapChain if possible.
if (base::FeatureList::IsEnabled(features::kLowLatencyCanvas2dSwapChain)) {
provider = CanvasResourceProvider::CreateSwapChainProvider(
Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(),
ColorParams(), is_origin_top_left, std::move(dispatcher),
GetMSAASampleCountFor2dContext());
}
// If SwapChain failed or it was not possible, we will try a SharedImage
// with a set of flags trying to add Usage Display and Usage Scanout and
// Concurrent Read and Write if possible.
if (!provider) {
uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY;
if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled() ||
base::FeatureList::IsEnabled(
features::kLowLatencyCanvas2dImageChromium)) {
shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
shared_image_usage_flags |=
gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
}
provider = CanvasResourceProvider::CreateSharedImageProvider(
Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(),
ColorParams(), is_origin_top_left,
CanvasResourceProvider::RasterMode::kGPU, shared_image_usage_flags);
}
} else if (use_gpu) {
// First try to be optimized for displaying on screen. In the case we are
// hardware compositing, we also try to enable the usage of the image as
// scanout buffer (overlay)
uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY;
if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled())
shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
provider = CanvasResourceProvider::CreateSharedImageProvider(
Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(),
ColorParams(), is_origin_top_left,
CanvasResourceProvider::RasterMode::kGPU, shared_image_usage_flags);
} else if (composited_mode) {
} else if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) {
const uint32_t shared_image_usage_flags =
gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT;
provider = CanvasResourceProvider::CreateSharedImageProvider(
Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(),
ColorParams(), is_origin_top_left,
CanvasResourceProvider::RasterMode::kCPU, shared_image_usage_flags);
}
if (!provider && !try_swap_chain) {
// If the sharedImage Provider creation above failed, we try a
// SharedBitmap Provider before falling back to a Bitmap Provider
// If either of the other modes failed and / or it was not possible to do, we
// will backup with a SharedBitmap, and if that was not possible with a Bitmap
// provider.
if (!provider) {
provider = CanvasResourceProvider::CreateSharedBitmapProvider(
Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(),
ColorParams(), std::move(dispatcher));
}
if (!provider && !try_swap_chain) {
// If any of the above Create was able to create a valid provider, a
// BitmapProvider will be created here.
if (!provider) {
provider = CanvasResourceProvider::CreateBitmapProvider(
Size(), FilterQuality(), ColorParams());
}
......
......@@ -725,34 +725,6 @@ enum class CanvasResourceType {
const Vector<CanvasResourceType>& GetResourceTypeFallbackList(
CanvasResourceProvider::ResourceUsage usage) {
static const Vector<CanvasResourceType> kCompositedFallbackList({
CanvasResourceType::kSharedImage,
CanvasResourceType::kSharedBitmap,
// Fallback to no direct compositing support
CanvasResourceType::kBitmap,
});
static const Vector<CanvasResourceType> kCompositedFallbackListWithDawn({
CanvasResourceType::kWebGPUSharedImage,
CanvasResourceType::kSharedImage,
CanvasResourceType::kSharedBitmap,
// Fallback to no direct compositing support
CanvasResourceType::kBitmap,
});
static const Vector<CanvasResourceType> kAcceleratedDirect2DFallbackList({
// Needed for low latency canvas on Windows.
CanvasResourceType::kDirect2DSwapChain,
// The rest is equal to |kCompositedFallbackList|.
CanvasResourceType::kSharedImage,
CanvasResourceType::kSharedBitmap,
CanvasResourceType::kBitmap,
});
DCHECK(std::equal(kAcceleratedDirect2DFallbackList.begin() + 1,
kAcceleratedDirect2DFallbackList.end(),
kCompositedFallbackList.begin(),
kCompositedFallbackList.end()));
static const Vector<CanvasResourceType> kAcceleratedDirect3DFallbackList({
// This is used with single-buffered WebGL where the resource comes
// from an external source. The external site should take care of
......@@ -764,10 +736,6 @@ const Vector<CanvasResourceType>& GetResourceTypeFallbackList(
CanvasResourceType::kSharedBitmap,
CanvasResourceType::kBitmap,
});
DCHECK(std::equal(kAcceleratedDirect3DFallbackList.begin() + 1,
kAcceleratedDirect3DFallbackList.end(),
kCompositedFallbackList.begin(),
kCompositedFallbackList.end()));
static const Vector<CanvasResourceType> kEmptyList;
switch (usage) {
......@@ -776,15 +744,14 @@ const Vector<CanvasResourceType>& GetResourceTypeFallbackList(
case CanvasResourceProvider::ResourceUsage::kSoftwareResourceUsage:
case CanvasResourceProvider::ResourceUsage::
kSoftwareCompositedDirect2DResourceUsage:
case CanvasResourceProvider::ResourceUsage::
kAcceleratedDirect2DResourceUsage:
case CanvasResourceProvider::ResourceUsage::
kSoftwareCompositedResourceUsage:
case CanvasResourceProvider::ResourceUsage::
kAcceleratedCompositedResourceUsage:
NOTREACHED();
return kEmptyList;
case CanvasResourceProvider::ResourceUsage::
kAcceleratedDirect2DResourceUsage:
return kAcceleratedDirect2DFallbackList;
case CanvasResourceProvider::ResourceUsage::
kAcceleratedDirect3DResourceUsage:
return kAcceleratedDirect3DFallbackList;
......@@ -812,6 +779,7 @@ std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create(
DCHECK(usage != ResourceUsage::kSoftwareCompositedDirect2DResourceUsage);
DCHECK(usage != ResourceUsage::kSoftwareCompositedResourceUsage);
DCHECK(usage != ResourceUsage::kAcceleratedCompositedResourceUsage);
DCHECK(usage != ResourceUsage::kAcceleratedDirect2DResourceUsage);
std::unique_ptr<CanvasResourceProvider> provider;
......@@ -1015,10 +983,13 @@ CanvasResourceProvider::CreateSharedImageProvider(
if (raster_mode == RasterMode::kCPU && !is_gpu_memory_buffer_image_allowed)
return nullptr;
// If we cannot use overlay, we have to remove the scanout flag.
// If we cannot use overlay, we have to remove the scanout flag and the
// concurrent read write flag.
if (!is_gpu_memory_buffer_image_allowed ||
!capabilities.texture_storage_image)
!capabilities.texture_storage_image) {
shared_image_usage_flags &= ~gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
shared_image_usage_flags &= ~gpu::SHARED_IMAGE_USAGE_SCANOUT;
}
auto provider = std::make_unique<CanvasResourceProviderSharedImage>(
size, msaa_sample_count, filter_quality, color_params,
......@@ -1063,6 +1034,36 @@ CanvasResourceProvider::CreatePassThroughProvider(
return nullptr;
}
std::unique_ptr<CanvasResourceProvider>
CanvasResourceProvider::CreateSwapChainProvider(
const IntSize& size,
base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
SkFilterQuality filter_quality,
const CanvasColorParams& color_params,
bool is_origin_top_left,
base::WeakPtr<CanvasResourceDispatcher> resource_dispatcher,
unsigned msaa_sample_count) {
DCHECK(is_origin_top_left);
if (!SharedGpuContext::IsGpuCompositingEnabled() || !context_provider_wrapper)
return nullptr;
const auto& capabilities =
context_provider_wrapper->ContextProvider()->GetCapabilities();
if (size.Width() > capabilities.max_texture_size ||
size.Height() > capabilities.max_texture_size ||
!capabilities.shared_image_swap_chain) {
return nullptr;
}
auto provider = std::make_unique<CanvasResourceProviderSwapChain>(
size, msaa_sample_count, filter_quality, color_params,
context_provider_wrapper, resource_dispatcher);
if (provider->IsValid())
return provider;
return nullptr;
}
CanvasResourceProvider::CanvasImageProvider::CanvasImageProvider(
cc::ImageDecodeCache* cache_n32,
cc::ImageDecodeCache* cache_f16,
......
......@@ -69,7 +69,7 @@ class PLATFORM_EXPORT CanvasResourceProvider
kSoftwareCompositedResourceUsage = 1, // deprecated
kAcceleratedResourceUsage = 2, // deprecated
kAcceleratedCompositedResourceUsage = 3, // deprecated
kAcceleratedDirect2DResourceUsage = 4,
kAcceleratedDirect2DResourceUsage = 4, // deprecated
kAcceleratedDirect3DResourceUsage = 5,
kSoftwareCompositedDirect2DResourceUsage = 6, // deprecated
kMaxValue = kSoftwareCompositedDirect2DResourceUsage,
......@@ -143,6 +143,15 @@ class PLATFORM_EXPORT CanvasResourceProvider
bool is_origin_top_left,
base::WeakPtr<CanvasResourceDispatcher>);
static std::unique_ptr<CanvasResourceProvider> CreateSwapChainProvider(
const IntSize&,
base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
SkFilterQuality,
const CanvasColorParams&,
bool is_origin_top_left,
base::WeakPtr<CanvasResourceDispatcher>,
unsigned msaa_sample_count);
// TODO(juanmihd): Clean up creation methods/usage. See crbug.com/1035589.
static std::unique_ptr<CanvasResourceProvider> Create(
const IntSize&,
......
......@@ -78,13 +78,14 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderAcceleratedOverlay) {
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
kNonOpaque);
auto provider = CanvasResourceProvider::Create(
kSize,
CanvasResourceProvider::ResourceUsage::kAcceleratedDirect2DResourceUsage,
context_provider_wrapper_, 0 /* msaa_sample_count */,
kMedium_SkFilterQuality, kColorParams,
CanvasResourceProvider::kAllowImageChromiumPresentationMode,
nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
const uint32_t shared_image_usage_flags =
gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT |
gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
auto provider = CanvasResourceProvider::CreateSharedImageProvider(
kSize, context_provider_wrapper_, kMedium_SkFilterQuality, kColorParams,
true /* is_origin_top_left */, CanvasResourceProvider::RasterMode::kGPU,
shared_image_usage_flags);
EXPECT_EQ(provider->Size(), kSize);
EXPECT_TRUE(provider->IsValid());
......@@ -345,13 +346,14 @@ TEST_F(CanvasResourceProviderTest,
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
kNonOpaque);
auto provider = CanvasResourceProvider::Create(
kSize,
CanvasResourceProvider::ResourceUsage::kAcceleratedDirect2DResourceUsage,
context_provider_wrapper_, 0 /* msaa_sample_count */,
kLow_SkFilterQuality, kColorParams,
CanvasResourceProvider::kAllowImageChromiumPresentationMode,
nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
const uint32_t shared_image_usage_flags =
gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT |
gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
auto provider = CanvasResourceProvider::CreateSharedImageProvider(
kSize, context_provider_wrapper_, kMedium_SkFilterQuality, kColorParams,
true /* is_origin_top_left */, CanvasResourceProvider::RasterMode::kGPU,
shared_image_usage_flags);
EXPECT_EQ(provider->Size(), kSize);
EXPECT_TRUE(provider->IsValid());
......@@ -501,6 +503,31 @@ TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize_SharedImage) {
EXPECT_TRUE(!provider || !provider->IsValid());
}
TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize_SwapChain) {
const CanvasColorParams kColorParams(
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
kNonOpaque);
auto provider = CanvasResourceProvider::CreateSwapChainProvider(
IntSize(kMaxTextureSize - 1, kMaxTextureSize), context_provider_wrapper_,
kLow_SkFilterQuality, kColorParams, true /* is_origin_top_left */,
nullptr /* resource_dispatcher */, 0 /* msaa_sample_count */);
EXPECT_TRUE(provider->SupportsDirectCompositing());
provider = CanvasResourceProvider::CreateSwapChainProvider(
IntSize(kMaxTextureSize, kMaxTextureSize), context_provider_wrapper_,
kLow_SkFilterQuality, kColorParams, true /* is_origin_top_left */,
nullptr /* resource_dispatcher */, 0 /* msaa_sample_count */);
EXPECT_TRUE(provider->SupportsDirectCompositing());
provider = CanvasResourceProvider::CreateSwapChainProvider(
IntSize(kMaxTextureSize + 1, kMaxTextureSize), context_provider_wrapper_,
kLow_SkFilterQuality, kColorParams, true /* is_origin_top_left */,
nullptr /* resource_dispatcher */, 0 /* msaa_sample_count */);
// The CanvasResourceProvider for SwapChain should not be created or valid
// if the texture size is greater than the maximum value
EXPECT_TRUE(!provider || !provider->IsValid());
}
// TODO(crbug/1035589). There are tests missing for SharedBitmap
TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize) {
const CanvasColorParams kColorParams(
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
......@@ -526,42 +553,41 @@ TEST_F(CanvasResourceProviderTest, DimensionsExceedMaxTextureSize) {
continue;
case CanvasResourceProvider::ResourceUsage::
kSoftwareCompositedDirect2DResourceUsage:
FALLTHROUGH;
case CanvasResourceProvider::ResourceUsage::
kAcceleratedDirect2DResourceUsage:
FALLTHROUGH;
continue;
case CanvasResourceProvider::ResourceUsage::
kAcceleratedDirect3DResourceUsage:
should_support_compositing = true;
break;
}
provider = CanvasResourceProvider::Create(
IntSize(kMaxTextureSize - 1, kMaxTextureSize), usage,
context_provider_wrapper_, 0 /* msaa_sample_count */,
kLow_SkFilterQuality, kColorParams,
CanvasResourceProvider::kAllowImageChromiumPresentationMode,
nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
provider = CanvasResourceProvider::Create(
IntSize(kMaxTextureSize - 1, kMaxTextureSize), usage,
context_provider_wrapper_, 0 /* msaa_sample_count */,
kLow_SkFilterQuality, kColorParams,
CanvasResourceProvider::kAllowImageChromiumPresentationMode,
nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
EXPECT_EQ(provider->SupportsDirectCompositing(),
should_support_compositing);
provider = CanvasResourceProvider::Create(
IntSize(kMaxTextureSize, kMaxTextureSize), usage,
context_provider_wrapper_, 0 /* msaa_sample_count */,
kLow_SkFilterQuality, kColorParams,
CanvasResourceProvider::kAllowImageChromiumPresentationMode,
nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
provider = CanvasResourceProvider::Create(
IntSize(kMaxTextureSize, kMaxTextureSize), usage,
context_provider_wrapper_, 0 /* msaa_sample_count */,
kLow_SkFilterQuality, kColorParams,
CanvasResourceProvider::kAllowImageChromiumPresentationMode,
nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
EXPECT_EQ(provider->SupportsDirectCompositing(),
should_support_compositing);
provider = CanvasResourceProvider::Create(
IntSize(kMaxTextureSize + 1, kMaxTextureSize), usage,
context_provider_wrapper_, 0 /* msaa_sample_count */,
kLow_SkFilterQuality, kColorParams,
CanvasResourceProvider::kAllowImageChromiumPresentationMode,
nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
provider = CanvasResourceProvider::Create(
IntSize(kMaxTextureSize + 1, kMaxTextureSize), usage,
context_provider_wrapper_, 0 /* msaa_sample_count */,
kLow_SkFilterQuality, kColorParams,
CanvasResourceProvider::kAllowImageChromiumPresentationMode,
nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
EXPECT_FALSE(provider->SupportsDirectCompositing());
}
......@@ -573,13 +599,21 @@ TEST_F(CanvasResourceProviderTest, CanvasResourceProviderDirect2DSwapChain) {
CanvasColorSpace::kSRGB, CanvasColorParams::GetNativeCanvasPixelFormat(),
kNonOpaque);
auto provider = CanvasResourceProvider::Create(
kSize,
CanvasResourceProvider::ResourceUsage::kAcceleratedDirect2DResourceUsage,
context_provider_wrapper_, 0 /* msaa_sample_count */,
kLow_SkFilterQuality, kColorParams,
CanvasResourceProvider::kAllowSwapChainPresentationMode,
nullptr /* resource_dispatcher */, true /* is_origin_top_left */);
auto provider = CanvasResourceProvider::CreateSwapChainProvider(
kSize, context_provider_wrapper_, kLow_SkFilterQuality, kColorParams,
true /* is_origin_top_left */, nullptr /* resource_dispatcher */,
0 /* msaa_sample_count */);
if (!provider) {
const uint32_t shared_image_usage_flags =
gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT |
gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
provider = CanvasResourceProvider::CreateSharedImageProvider(
kSize, context_provider_wrapper_, kLow_SkFilterQuality, kColorParams,
true /* is_origin_top_left */, CanvasResourceProvider::RasterMode::kGPU,
shared_image_usage_flags);
}
EXPECT_EQ(provider->Size(), kSize);
EXPECT_TRUE(provider->IsValid());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment