From fa5503b828721a5e007df7d1d8abdd81f8115b58 Mon Sep 17 00:00:00 2001 From: Eric Karl Date: Fri, 23 Feb 2018 03:31:20 +0000 Subject: [PATCH] Use glUnpremultiplyAndDitherCopyCHROMIUM in GPU Raster This change addresses banding issues by using the newly added glUnpremultiplyAndDitherCopyCHROMIUM. In cases where we previously rasterized into a RGBA4444 target, we instead rasterize into a temporary RGBA8888 target, then do an unpremultiply/dither copy into the RGBA4444 target. This means that tiles may be either unpremultiplied or premultiplied, so we need a way to pipe this information to the GLRenderer so it can blend correctly. This change introduces a is_premultiplied property to ContentDrawQuadBase to handle this. Bug: 789153 Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.android:android_optional_gpu_tests_rel Change-Id: I8bb2af2a94934ca7fe79a180d65bff253163c98c Reviewed-on: https://chromium-review.googlesource.com/899866 Reviewed-by: enne Reviewed-by: Ken Buchanan Commit-Queue: Eric Karl Cr-Commit-Position: refs/heads/master@{#538686} --- cc/ipc/cc_param_traits_unittest.cc | 8 +- cc/ipc/cc_serialization_perftest.cc | 9 +- cc/layers/picture_layer_impl.cc | 2 +- cc/layers/render_surface_unittest.cc | 2 +- cc/raster/bitmap_raster_buffer_provider.cc | 5 + cc/raster/bitmap_raster_buffer_provider.h | 1 + cc/raster/gpu_raster_buffer_provider.cc | 96 ++++++++++++++++-- cc/raster/gpu_raster_buffer_provider.h | 1 + cc/raster/one_copy_raster_buffer_provider.cc | 7 ++ cc/raster/one_copy_raster_buffer_provider.h | 1 + cc/raster/raster_buffer_provider.h | 3 + cc/raster/zero_copy_raster_buffer_provider.cc | 5 + cc/raster/zero_copy_raster_buffer_provider.h | 1 + cc/resources/layer_tree_resource_provider.cc | 24 +++-- cc/resources/layer_tree_resource_provider.h | 3 + cc/test/fake_raster_buffer_provider.cc | 5 + cc/test/fake_raster_buffer_provider.h | 1 + cc/test/render_pass_test_utils.cc | 22 ++-- cc/tiles/tile_draw_info.cc | 5 +- cc/tiles/tile_draw_info.h | 5 +- cc/tiles/tile_manager.cc | 4 +- cc/tiles/tile_manager.h | 2 +- cc/trees/layer_tree_host_impl_unittest.cc | 2 +- cc/trees/layer_tree_host_pixeltest_tiles.cc | 28 +++++ .../common/quads/content_draw_quad_base.cc | 4 + .../viz/common/quads/content_draw_quad_base.h | 3 + .../viz/common/quads/draw_quad_unittest.cc | 11 +- .../viz/common/quads/picture_draw_quad.cc | 8 +- components/viz/common/quads/tile_draw_quad.cc | 10 +- components/viz/common/quads/tile_draw_quad.h | 2 + components/viz/service/display/gl_renderer.cc | 8 +- .../service/display/gl_renderer_unittest.cc | 60 +++++++---- .../viz/service/display/program_binding.cc | 2 + .../viz/service/display/program_binding.h | 1 + .../viz/service/display/renderer_pixeltest.cc | 12 ++- .../display/software_renderer_unittest.cc | 6 +- .../test/data/blue_yellow_flipped_dither.png | Bin 0 -> 824 bytes .../blue_yellow_partial_flipped_dither.png | Bin 0 -> 1330 bytes .../cpp/compositing/quads_struct_traits.cc | 1 + .../cpp/compositing/quads_struct_traits.h | 5 + .../public/interfaces/compositing/quads.mojom | 1 + 41 files changed, 296 insertions(+), 80 deletions(-) create mode 100644 components/viz/test/data/blue_yellow_flipped_dither.png create mode 100644 components/viz/test/data/blue_yellow_partial_flipped_dither.png diff --git a/cc/ipc/cc_param_traits_unittest.cc b/cc/ipc/cc_param_traits_unittest.cc index 97e58901e1cf53..867bb9c39b0042 100644 --- a/cc/ipc/cc_param_traits_unittest.cc +++ b/cc/ipc/cc_param_traits_unittest.cc @@ -405,10 +405,10 @@ TEST_F(CCParamTraitsTest, AllQuads) { pass_cmp->CopyFromAndAppendDrawQuad(texture_in); TileDrawQuad* tile_in = pass_in->CreateAndAppendDrawQuad(); - tile_in->SetAll(shared_state3_in, arbitrary_rect2, - arbitrary_rect1_inside_rect2, arbitrary_bool1, - arbitrary_resourceid3, arbitrary_rectf1, arbitrary_size1, - arbitrary_bool2, arbitrary_bool3, arbitrary_bool4); + tile_in->SetAll( + shared_state3_in, arbitrary_rect2, arbitrary_rect1_inside_rect2, + arbitrary_bool1, arbitrary_resourceid3, arbitrary_rectf1, arbitrary_size1, + arbitrary_bool2, arbitrary_bool3, arbitrary_bool4, arbitrary_bool5); pass_cmp->CopyFromAndAppendDrawQuad(tile_in); YUVVideoDrawQuad* yuvvideo_in = diff --git a/cc/ipc/cc_serialization_perftest.cc b/cc/ipc/cc_serialization_perftest.cc index d8741b8de02647..19baf092177f81 100644 --- a/cc/ipc/cc_serialization_perftest.cc +++ b/cc/ipc/cc_serialization_perftest.cc @@ -361,10 +361,11 @@ class CCSerializationPerfTest : public testing::Test { arbitrary_blend_mode2, arbitrary_context_id2); for (uint32_t j = 0; j < 6; ++j) { auto* tile_in = pass_in->CreateAndAppendDrawQuad(); - tile_in->SetAll( - shared_state2_in, arbitrary_rect2, arbitrary_rect1_inside_rect2, - arbitrary_bool1, arbitrary_resourceid3, arbitrary_rectf1, - arbitrary_size1, arbitrary_bool2, arbitrary_bool3, arbitrary_bool4); + tile_in->SetAll(shared_state2_in, arbitrary_rect2, + arbitrary_rect1_inside_rect2, arbitrary_bool1, + arbitrary_resourceid3, arbitrary_rectf1, + arbitrary_size1, arbitrary_bool2, arbitrary_bool3, + arbitrary_bool4, arbitrary_bool5); } } diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index bc1573be04f61f..d9ef0774e7fa60 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -470,7 +470,7 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass, offset_visible_geometry_rect, needs_blending, draw_info.resource_id_for_export(), texture_rect, draw_info.resource_size(), draw_info.contents_swizzled(), - nearest_neighbor_, + draw_info.is_premultiplied(), nearest_neighbor_, !layer_tree_impl()->settings().enable_edge_anti_aliasing); ValidateQuadResources(quad); has_draw_quad = true; diff --git a/cc/layers/render_surface_unittest.cc b/cc/layers/render_surface_unittest.cc index 8385acee84484b..714ddd499167c1 100644 --- a/cc/layers/render_surface_unittest.cc +++ b/cc/layers/render_surface_unittest.cc @@ -68,7 +68,7 @@ class FakePictureLayerImplForRenderSurfaceTest : public FakePictureLayerImpl { for (const auto& rect : quad_rects_) { auto* quad = render_pass->CreateAndAppendDrawQuad(); quad->SetNew(shared_quad_state, rect, rect, needs_blending, 0, - gfx::RectF(rect), bounds(), false, false, false); + gfx::RectF(rect), bounds(), false, false, false, false); } } diff --git a/cc/raster/bitmap_raster_buffer_provider.cc b/cc/raster/bitmap_raster_buffer_provider.cc index 288e51035a5a70..27eaa2e7deb3a2 100644 --- a/cc/raster/bitmap_raster_buffer_provider.cc +++ b/cc/raster/bitmap_raster_buffer_provider.cc @@ -118,6 +118,11 @@ bool BitmapRasterBufferProvider::IsResourceSwizzleRequired( return ResourceFormatRequiresSwizzle(viz::RGBA_8888); } +bool BitmapRasterBufferProvider::IsResourcePremultiplied( + bool must_support_alpha) const { + return true; +} + bool BitmapRasterBufferProvider::CanPartialRasterIntoProvidedResource() const { return true; } diff --git a/cc/raster/bitmap_raster_buffer_provider.h b/cc/raster/bitmap_raster_buffer_provider.h index 2b50e4a9754596..e26fa4975743d9 100644 --- a/cc/raster/bitmap_raster_buffer_provider.h +++ b/cc/raster/bitmap_raster_buffer_provider.h @@ -40,6 +40,7 @@ class CC_EXPORT BitmapRasterBufferProvider : public RasterBufferProvider { void Flush() override; viz::ResourceFormat GetResourceFormat(bool must_support_alpha) const override; bool IsResourceSwizzleRequired(bool must_support_alpha) const override; + bool IsResourcePremultiplied(bool must_support_alpha) const override; bool CanPartialRasterIntoProvidedResource() const override; bool IsResourceReadyToDraw( const ResourcePool::InUsePoolResource& resource) const override; diff --git a/cc/raster/gpu_raster_buffer_provider.cc b/cc/raster/gpu_raster_buffer_provider.cc index 70b5547f34834b..93dc6ab6a5bcdb 100644 --- a/cc/raster/gpu_raster_buffer_provider.cc +++ b/cc/raster/gpu_raster_buffer_provider.cc @@ -28,6 +28,7 @@ #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/client/raster_interface.h" #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" +#include "skia/ext/texture_handle.h" #include "third_party/skia/include/core/SkMultiPictureDraw.h" #include "third_party/skia/include/core/SkPictureRecorder.h" #include "third_party/skia/include/core/SkSurface.h" @@ -38,6 +39,54 @@ namespace cc { namespace { +class ScopedSkSurfaceForUnpremultiplyAndDither { + public: + ScopedSkSurfaceForUnpremultiplyAndDither( + viz::RasterContextProvider* context_provider, + const gfx::Rect& playback_rect, + const gfx::Rect& raster_full_rect, + GLuint texture_id, + const gfx::Size& size, + bool use_distance_field_text, + bool can_use_lcd_text, + int msaa_sample_count) + : context_provider_(context_provider), + texture_id_(texture_id), + offset_(playback_rect.OffsetFromOrigin() - + raster_full_rect.OffsetFromOrigin()), + size_(playback_rect.size()) { + // Allocate a 32-bit surface for raster. We will copy from that into our + // actual surface in destruction. + SkImageInfo n32Info = + SkImageInfo::MakeN32Premul(size.width(), size.height()); + SkSurfaceProps surface_props = + LayerTreeResourceProvider::ScopedSkSurface::ComputeSurfaceProps( + use_distance_field_text, can_use_lcd_text); + surface_ = SkSurface::MakeRenderTarget( + context_provider->GrContext(), SkBudgeted::kYes, n32Info, + msaa_sample_count, kTopLeft_GrSurfaceOrigin, &surface_props); + } + + ~ScopedSkSurfaceForUnpremultiplyAndDither() { + GrBackendObject handle = + surface_->getTextureHandle(SkSurface::kFlushRead_BackendHandleAccess); + const GrGLTextureInfo* info = + skia::GrBackendObjectToGrGLTextureInfo(handle); + context_provider_->RasterInterface()->UnpremultiplyAndDitherCopyCHROMIUM( + info->fID, texture_id_, offset_.x(), offset_.y(), size_.width(), + size_.height()); + } + + SkSurface* surface() { return surface_.get(); } + + private: + viz::RasterContextProvider* context_provider_; + GLuint texture_id_; + gfx::Vector2d offset_; + gfx::Size size_; + sk_sp surface_; +}; + static void RasterizeSourceOOP( const RasterSource* raster_source, bool resource_has_previous_content, @@ -85,6 +134,9 @@ static void RasterizeSourceOOP( raster_source->requires_clear()); ri->EndRasterCHROMIUM(); + // TODO(ericrk): Handle unpremultiply+dither for 4444 cases. + // https://crbug.com/789153 + ri->DeleteTextures(1, &texture_id); } @@ -125,7 +177,8 @@ static void RasterizeSource( const RasterSource::PlaybackSettings& playback_settings, viz::RasterContextProvider* context_provider, bool use_distance_field_text, - int msaa_sample_count) { + int msaa_sample_count, + bool unpremultiply_and_dither) { ScopedGrContextAccess gr_context_access(context_provider); gpu::raster::RasterInterface* ri = context_provider->RasterInterface(); @@ -139,12 +192,23 @@ static void RasterizeSource( } { - LayerTreeResourceProvider::ScopedSkSurface scoped_surface( - context_provider->GrContext(), texture_id, texture_target, - resource_size, resource_format, use_distance_field_text, - playback_settings.use_lcd_text, msaa_sample_count); - - SkSurface* surface = scoped_surface.surface(); + base::Optional scoped_surface; + base::Optional + scoped_dither_surface; + SkSurface* surface; + if (!unpremultiply_and_dither) { + scoped_surface.emplace(context_provider->GrContext(), texture_id, + texture_target, resource_size, resource_format, + use_distance_field_text, + playback_settings.use_lcd_text, msaa_sample_count); + surface = scoped_surface->surface(); + } else { + scoped_dither_surface.emplace( + context_provider, playback_rect, raster_full_rect, texture_id, + resource_size, use_distance_field_text, + playback_settings.use_lcd_text, msaa_sample_count); + surface = scoped_dither_surface->surface(); + } // Allocating an SkSurface will fail after a lost context. Pretend we // rasterized, as the contents of the resource don't matter anymore. @@ -168,6 +232,15 @@ static void RasterizeSource( ri->DeleteTextures(1, &texture_id); } +bool ShouldUnpremultiplyAndDitherResource(viz::ResourceFormat format) { + switch (format) { + case viz::RGBA_4444: + return true; + default: + return false; + } +} + } // namespace // Subclass for InUsePoolResource that holds ownership of a gpu-rastered backing @@ -357,6 +430,12 @@ bool GpuRasterBufferProvider::IsResourceSwizzleRequired( return false; } +bool GpuRasterBufferProvider::IsResourcePremultiplied( + bool must_support_alpha) const { + return !ShouldUnpremultiplyAndDitherResource( + GetResourceFormat(must_support_alpha)); +} + bool GpuRasterBufferProvider::CanPartialRasterIntoProvidedResource() const { // Partial raster doesn't support MSAA, as the MSAA resolve is unaware of clip // rects. @@ -467,7 +546,8 @@ gpu::SyncToken GpuRasterBufferProvider::PlaybackOnWorkerThread( texture_storage_allocated, resource_size, resource_format, color_space, raster_full_rect, playback_rect, transform, playback_settings, worker_context_provider_, - use_distance_field_text_, msaa_sample_count_); + use_distance_field_text_, msaa_sample_count_, + ShouldUnpremultiplyAndDitherResource(resource_format)); } // Generate sync token for cross context synchronization. diff --git a/cc/raster/gpu_raster_buffer_provider.h b/cc/raster/gpu_raster_buffer_provider.h index 15b40be705106d..544417d97de22d 100644 --- a/cc/raster/gpu_raster_buffer_provider.h +++ b/cc/raster/gpu_raster_buffer_provider.h @@ -40,6 +40,7 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider { void Flush() override; viz::ResourceFormat GetResourceFormat(bool must_support_alpha) const override; bool IsResourceSwizzleRequired(bool must_support_alpha) const override; + bool IsResourcePremultiplied(bool must_support_alpha) const override; bool CanPartialRasterIntoProvidedResource() const override; bool IsResourceReadyToDraw( const ResourcePool::InUsePoolResource& resource) const override; diff --git a/cc/raster/one_copy_raster_buffer_provider.cc b/cc/raster/one_copy_raster_buffer_provider.cc index 62c3dbdb24d9e7..f1ad0a0f6e64be 100644 --- a/cc/raster/one_copy_raster_buffer_provider.cc +++ b/cc/raster/one_copy_raster_buffer_provider.cc @@ -246,6 +246,13 @@ bool OneCopyRasterBufferProvider::IsResourceSwizzleRequired( return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha)); } +bool OneCopyRasterBufferProvider::IsResourcePremultiplied( + bool must_support_alpha) const { + // TODO(ericrk): Handle unpremultiply/dither in one-copy case as well. + // https://crbug.com/789153 + return true; +} + bool OneCopyRasterBufferProvider::CanPartialRasterIntoProvidedResource() const { // While OneCopyRasterBufferProvider has an internal partial raster // implementation, it cannot directly partial raster into the externally diff --git a/cc/raster/one_copy_raster_buffer_provider.h b/cc/raster/one_copy_raster_buffer_provider.h index 5ad055628f91ed..b723ef84116f39 100644 --- a/cc/raster/one_copy_raster_buffer_provider.h +++ b/cc/raster/one_copy_raster_buffer_provider.h @@ -45,6 +45,7 @@ class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider { void Flush() override; viz::ResourceFormat GetResourceFormat(bool must_support_alpha) const override; bool IsResourceSwizzleRequired(bool must_support_alpha) const override; + bool IsResourcePremultiplied(bool must_support_alpha) const override; bool CanPartialRasterIntoProvidedResource() const override; bool IsResourceReadyToDraw( const ResourcePool::InUsePoolResource& resource) const override; diff --git a/cc/raster/raster_buffer_provider.h b/cc/raster/raster_buffer_provider.h index 2d7622c589aff6..58119e844aae8e 100644 --- a/cc/raster/raster_buffer_provider.h +++ b/cc/raster/raster_buffer_provider.h @@ -69,6 +69,9 @@ class CC_EXPORT RasterBufferProvider { // Determine if the resource requires swizzling. virtual bool IsResourceSwizzleRequired(bool must_support_alpha) const = 0; + // Determines if the resource is premultiplied. + virtual bool IsResourcePremultiplied(bool must_support_alpha) const = 0; + // Determine if the RasterBufferProvider can handle partial raster into // the Resource provided in AcquireBufferForRaster. virtual bool CanPartialRasterIntoProvidedResource() const = 0; diff --git a/cc/raster/zero_copy_raster_buffer_provider.cc b/cc/raster/zero_copy_raster_buffer_provider.cc index b0e9a1ab4e42fa..ab59073c090708 100644 --- a/cc/raster/zero_copy_raster_buffer_provider.cc +++ b/cc/raster/zero_copy_raster_buffer_provider.cc @@ -254,6 +254,11 @@ bool ZeroCopyRasterBufferProvider::IsResourceSwizzleRequired( return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha)); } +bool ZeroCopyRasterBufferProvider::IsResourcePremultiplied( + bool must_support_alpha) const { + return true; +} + bool ZeroCopyRasterBufferProvider::CanPartialRasterIntoProvidedResource() const { return false; diff --git a/cc/raster/zero_copy_raster_buffer_provider.h b/cc/raster/zero_copy_raster_buffer_provider.h index 2e4c8dc0a4bb91..ed0bd7e7c6c064 100644 --- a/cc/raster/zero_copy_raster_buffer_provider.h +++ b/cc/raster/zero_copy_raster_buffer_provider.h @@ -43,6 +43,7 @@ class CC_EXPORT ZeroCopyRasterBufferProvider : public RasterBufferProvider { void Flush() override; viz::ResourceFormat GetResourceFormat(bool must_support_alpha) const override; bool IsResourceSwizzleRequired(bool must_support_alpha) const override; + bool IsResourcePremultiplied(bool must_support_alpha) const override; bool CanPartialRasterIntoProvidedResource() const override; bool IsResourceReadyToDraw( const ResourcePool::InUsePoolResource& resource) const override; diff --git a/cc/resources/layer_tree_resource_provider.cc b/cc/resources/layer_tree_resource_provider.cc index 38f17c03d255c5..665aa54764c04a 100644 --- a/cc/resources/layer_tree_resource_provider.cc +++ b/cc/resources/layer_tree_resource_provider.cc @@ -996,6 +996,21 @@ LayerTreeResourceProvider::ScopedSkSurface::ScopedSkSurface( texture_info.fFormat = TextureStorageFormat(format); GrBackendTexture backend_texture(size.width(), size.height(), GrMipMapped::kNo, texture_info); + SkSurfaceProps surface_props = + ComputeSurfaceProps(use_distance_field_text, can_use_lcd_text); + surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget( + gr_context, backend_texture, kTopLeft_GrSurfaceOrigin, msaa_sample_count, + ResourceFormatToClosestSkColorType(format), nullptr, &surface_props); +} + +LayerTreeResourceProvider::ScopedSkSurface::~ScopedSkSurface() { + if (surface_) + surface_->prepareForExternalIO(); +} + +SkSurfaceProps LayerTreeResourceProvider::ScopedSkSurface::ComputeSurfaceProps( + bool use_distance_field_text, + bool can_use_lcd_text) { uint32_t flags = use_distance_field_text ? SkSurfaceProps::kUseDistanceFieldFonts_Flag : 0; // Use unknown pixel geometry to disable LCD text. @@ -1005,14 +1020,7 @@ LayerTreeResourceProvider::ScopedSkSurface::ScopedSkSurface( surface_props = SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType); } - surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget( - gr_context, backend_texture, kTopLeft_GrSurfaceOrigin, msaa_sample_count, - ResourceFormatToClosestSkColorType(format), nullptr, &surface_props); -} - -LayerTreeResourceProvider::ScopedSkSurface::~ScopedSkSurface() { - if (surface_) - surface_->prepareForExternalIO(); + return surface_props; } void LayerTreeResourceProvider::ValidateResource(viz::ResourceId id) const { diff --git a/cc/resources/layer_tree_resource_provider.h b/cc/resources/layer_tree_resource_provider.h index 92ae354a77f4d3..71c1c374aae96c 100644 --- a/cc/resources/layer_tree_resource_provider.h +++ b/cc/resources/layer_tree_resource_provider.h @@ -292,6 +292,9 @@ class CC_EXPORT LayerTreeResourceProvider : public ResourceProvider { SkSurface* surface() const { return surface_.get(); } + static SkSurfaceProps ComputeSurfaceProps(bool use_distance_field_text, + bool can_use_lcd_text); + private: sk_sp surface_; diff --git a/cc/test/fake_raster_buffer_provider.cc b/cc/test/fake_raster_buffer_provider.cc index 88de976add39ac..b748f524d0c46c 100644 --- a/cc/test/fake_raster_buffer_provider.cc +++ b/cc/test/fake_raster_buffer_provider.cc @@ -46,6 +46,11 @@ bool FakeRasterBufferProviderImpl::IsResourceSwizzleRequired( return ResourceFormatRequiresSwizzle(GetResourceFormat(must_support_alpha)); } +bool FakeRasterBufferProviderImpl::IsResourcePremultiplied( + bool must_support_alpha) const { + return true; +} + bool FakeRasterBufferProviderImpl::CanPartialRasterIntoProvidedResource() const { return true; diff --git a/cc/test/fake_raster_buffer_provider.h b/cc/test/fake_raster_buffer_provider.h index e19487342b7e81..c71ae4b167a84a 100644 --- a/cc/test/fake_raster_buffer_provider.h +++ b/cc/test/fake_raster_buffer_provider.h @@ -24,6 +24,7 @@ class FakeRasterBufferProviderImpl : public RasterBufferProvider { void Flush() override; viz::ResourceFormat GetResourceFormat(bool must_support_alpha) const override; bool IsResourceSwizzleRequired(bool must_support_alpha) const override; + bool IsResourcePremultiplied(bool must_support_alpha) const override; bool CanPartialRasterIntoProvidedResource() const override; bool IsResourceReadyToDraw( const ResourcePool::InUsePoolResource& resource) const override; diff --git a/cc/test/render_pass_test_utils.cc b/cc/test/render_pass_test_utils.cc index ded7460210cf5c..2a4aa335455ace 100644 --- a/cc/test/render_pass_test_utils.cc +++ b/cc/test/render_pass_test_utils.cc @@ -218,7 +218,7 @@ void AddOneOfEveryQuadType(viz::RenderPass* to_pass, to_pass->CreateAndAppendDrawQuad(); scaled_tile_quad->SetNew(shared_state, rect, visible_rect, needs_blending, resource2, gfx::RectF(0, 0, 50, 50), - gfx::Size(50, 50), false, false, false); + gfx::Size(50, 50), false, false, false, false); viz::SharedQuadState* transformed_state = to_pass->CreateAndAppendSharedQuadState(); @@ -229,9 +229,10 @@ void AddOneOfEveryQuadType(viz::RenderPass* to_pass, transformed_state->quad_to_target_transform * rotation; auto* transformed_tile_quad = to_pass->CreateAndAppendDrawQuad(); - transformed_tile_quad->SetNew( - transformed_state, rect, visible_rect, needs_blending, resource3, - gfx::RectF(0, 0, 100, 100), gfx::Size(100, 100), false, false, false); + transformed_tile_quad->SetNew(transformed_state, rect, visible_rect, + needs_blending, resource3, + gfx::RectF(0, 0, 100, 100), gfx::Size(100, 100), + false, false, false, false); viz::SharedQuadState* shared_state2 = to_pass->CreateAndAppendSharedQuadState(); @@ -241,7 +242,7 @@ void AddOneOfEveryQuadType(viz::RenderPass* to_pass, auto* tile_quad = to_pass->CreateAndAppendDrawQuad(); tile_quad->SetNew(shared_state2, rect, visible_rect, needs_blending, resource4, gfx::RectF(0, 0, 100, 100), gfx::Size(100, 100), - false, false, false); + false, false, false, false); viz::ResourceId plane_resources[4]; for (int i = 0; i < 4; ++i) { @@ -419,7 +420,7 @@ void AddOneOfEveryQuadTypeInDisplayResourceProvider( to_pass->CreateAndAppendDrawQuad(); scaled_tile_quad->SetNew(shared_state, rect, visible_rect, needs_blending, mapped_resource2, gfx::RectF(0, 0, 50, 50), - gfx::Size(50, 50), false, false, false); + gfx::Size(50, 50), false, false, false, false); viz::SharedQuadState* transformed_state = to_pass->CreateAndAppendSharedQuadState(); @@ -430,9 +431,10 @@ void AddOneOfEveryQuadTypeInDisplayResourceProvider( transformed_state->quad_to_target_transform * rotation; viz::TileDrawQuad* transformed_tile_quad = to_pass->CreateAndAppendDrawQuad(); - transformed_tile_quad->SetNew( - transformed_state, rect, visible_rect, needs_blending, mapped_resource3, - gfx::RectF(0, 0, 100, 100), gfx::Size(100, 100), false, false, false); + transformed_tile_quad->SetNew(transformed_state, rect, visible_rect, + needs_blending, mapped_resource3, + gfx::RectF(0, 0, 100, 100), gfx::Size(100, 100), + false, false, false, false); viz::SharedQuadState* shared_state2 = to_pass->CreateAndAppendSharedQuadState(); @@ -443,7 +445,7 @@ void AddOneOfEveryQuadTypeInDisplayResourceProvider( to_pass->CreateAndAppendDrawQuad(); tile_quad->SetNew(shared_state2, rect, visible_rect, needs_blending, mapped_resource4, gfx::RectF(0, 0, 100, 100), - gfx::Size(100, 100), false, false, false); + gfx::Size(100, 100), false, false, false, false); viz::YUVVideoDrawQuad* yuv_quad = to_pass->CreateAndAppendDrawQuad(); diff --git a/cc/tiles/tile_draw_info.cc b/cc/tiles/tile_draw_info.cc index 0e51c2b2402d49..0c09fa281d7417 100644 --- a/cc/tiles/tile_draw_info.cc +++ b/cc/tiles/tile_draw_info.cc @@ -22,7 +22,8 @@ void TileDrawInfo::AsValueInto(base::trace_event::TracedValue* state) const { void TileDrawInfo::SetResource(ResourcePool::InUsePoolResource resource, bool resource_is_checker_imaged, - bool contents_swizzled) { + bool contents_swizzled, + bool is_premultiplied) { DCHECK(!resource_); DCHECK(resource); @@ -30,6 +31,7 @@ void TileDrawInfo::SetResource(ResourcePool::InUsePoolResource resource, is_resource_ready_to_draw_ = false; resource_is_checker_imaged_ = resource_is_checker_imaged; contents_swizzled_ = contents_swizzled; + is_premultiplied_ = is_premultiplied; resource_ = std::move(resource); } @@ -45,6 +47,7 @@ ResourcePool::InUsePoolResource TileDrawInfo::TakeResource() { is_resource_ready_to_draw_ = false; resource_is_checker_imaged_ = false; contents_swizzled_ = false; + is_premultiplied_ = false; return std::move(resource_); } diff --git a/cc/tiles/tile_draw_info.h b/cc/tiles/tile_draw_info.h index 5ae3cbe0f62287..c401258c103e0e 100644 --- a/cc/tiles/tile_draw_info.h +++ b/cc/tiles/tile_draw_info.h @@ -73,6 +73,7 @@ class CC_EXPORT TileDrawInfo { } bool contents_swizzled() const { return contents_swizzled_; } + bool is_premultiplied() const { return is_premultiplied_; } bool requires_resource() const { return mode_ == RESOURCE_MODE || mode_ == OOM_MODE; @@ -101,7 +102,8 @@ class CC_EXPORT TileDrawInfo { void SetResource(ResourcePool::InUsePoolResource resource, bool resource_is_checker_imaged, - bool contents_swizzled); + bool contents_swizzled, + bool is_premultiplied); ResourcePool::InUsePoolResource TakeResource(); void set_resource_ready_for_draw() { @@ -120,6 +122,7 @@ class CC_EXPORT TileDrawInfo { SkColor solid_color_ = SK_ColorWHITE; ResourcePool::InUsePoolResource resource_; bool contents_swizzled_ = false; + bool is_premultiplied_ = false; bool is_resource_ready_to_draw_ = false; // Set to true if |resource_| was rasterized with checker-imaged content. The diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc index 6f24e98a2ad5a9..24ca5e11b43743 100644 --- a/cc/tiles/tile_manager.cc +++ b/cc/tiles/tile_manager.cc @@ -1291,9 +1291,11 @@ void TileManager::OnRasterTaskCompleted( TileDrawInfo& draw_info = tile->draw_info(); bool needs_swizzle = raster_buffer_provider_->IsResourceSwizzleRequired(!tile->is_opaque()); + bool is_premultiplied = + raster_buffer_provider_->IsResourcePremultiplied(!tile->is_opaque()); draw_info.SetResource(std::move(resource), raster_task_was_scheduled_with_checker_images, - needs_swizzle); + needs_swizzle, is_premultiplied); if (raster_task_was_scheduled_with_checker_images) num_of_tiles_with_checker_images_++; diff --git a/cc/tiles/tile_manager.h b/cc/tiles/tile_manager.h index 1c4a90d631aa98..4170c158149ca8 100644 --- a/cc/tiles/tile_manager.h +++ b/cc/tiles/tile_manager.h @@ -205,7 +205,7 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient { gpu::GPU_IO, gpu::CommandBufferId::FromUnsafeValue(1), 1); } resource_pool_->PrepareForExport(resource); - draw_info.SetResource(std::move(resource), false, false); + draw_info.SetResource(std::move(resource), false, false, false); draw_info.set_resource_ready_for_draw(); } } diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 522e3de270f6c9..eeafd5e371021b 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -8213,7 +8213,7 @@ class BlendStateCheckLayer : public LayerImpl { test_blending_draw_quad->SetNew( shared_quad_state, quad_rect_, visible_quad_rect, needs_blending, resource_id_, gfx::RectF(0.f, 0.f, 1.f, 1.f), gfx::Size(1, 1), false, - false, false); + false, false, false); EXPECT_EQ(blend_, test_blending_draw_quad->ShouldDrawWithBlending()); EXPECT_EQ(has_render_surface_, diff --git a/cc/trees/layer_tree_host_pixeltest_tiles.cc b/cc/trees/layer_tree_host_pixeltest_tiles.cc index 7156d699a1e3d7..5f7046332c75b6 100644 --- a/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/cc/trees/layer_tree_host_pixeltest_tiles.cc @@ -24,6 +24,8 @@ enum RasterMode { FULL_ONE_COPY, PARTIAL_GPU, FULL_GPU, + PARTIAL_GPU_LOW_BIT_DEPTH, + FULL_GPU_LOW_BIT_DEPTH, PARTIAL_BITMAP, FULL_BITMAP, }; @@ -55,6 +57,16 @@ class LayerTreeHostTilesPixelTest : public LayerTreePixelTest { settings->gpu_rasterization_forced = true; settings->use_partial_raster = false; break; + case PARTIAL_GPU_LOW_BIT_DEPTH: + settings->gpu_rasterization_forced = true; + settings->use_partial_raster = true; + settings->preferred_tile_format = viz::RGBA_4444; + break; + case FULL_GPU_LOW_BIT_DEPTH: + settings->gpu_rasterization_forced = true; + settings->use_partial_raster = false; + settings->preferred_tile_format = viz::RGBA_4444; + break; } } @@ -81,6 +93,8 @@ class LayerTreeHostTilesPixelTest : public LayerTreePixelTest { case FULL_ONE_COPY: case PARTIAL_GPU: case FULL_GPU: + case PARTIAL_GPU_LOW_BIT_DEPTH: + case FULL_GPU_LOW_BIT_DEPTH: test_type = PIXEL_TEST_GL; break; case PARTIAL_BITMAP: @@ -247,6 +261,20 @@ TEST_F(LayerTreeHostTilesTestPartialInvalidation, base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png"))); } +TEST_F(LayerTreeHostTilesTestPartialInvalidation, + PartialRaster_SingleThread_GpuRaster_LowBitDepth) { + RunRasterPixelTest(false, PARTIAL_GPU_LOW_BIT_DEPTH, picture_layer_, + base::FilePath(FILE_PATH_LITERAL( + "blue_yellow_partial_flipped_dither.png"))); +} + +TEST_F(LayerTreeHostTilesTestPartialInvalidation, + FullRaster_SingleThread_GpuRaster_LowBitDepth) { + RunRasterPixelTest( + false, FULL_GPU_LOW_BIT_DEPTH, picture_layer_, + base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped_dither.png"))); +} + } // namespace } // namespace cc diff --git a/components/viz/common/quads/content_draw_quad_base.cc b/components/viz/common/quads/content_draw_quad_base.cc index f19b0b2ba4b81d..fc84e356a11697 100644 --- a/components/viz/common/quads/content_draw_quad_base.cc +++ b/components/viz/common/quads/content_draw_quad_base.cc @@ -23,6 +23,7 @@ void ContentDrawQuadBase::SetNew(const SharedQuadState* shared_quad_state, const gfx::RectF& tex_coord_rect, const gfx::Size& texture_size, bool swizzle_contents, + bool is_premultiplied, bool nearest_neighbor, bool force_anti_aliasing_off) { DrawQuad::SetAll(shared_quad_state, material, rect, visible_rect, @@ -30,6 +31,7 @@ void ContentDrawQuadBase::SetNew(const SharedQuadState* shared_quad_state, this->tex_coord_rect = tex_coord_rect; this->texture_size = texture_size; this->swizzle_contents = swizzle_contents; + this->is_premultiplied = is_premultiplied; this->nearest_neighbor = nearest_neighbor; this->force_anti_aliasing_off = force_anti_aliasing_off; } @@ -42,6 +44,7 @@ void ContentDrawQuadBase::SetAll(const SharedQuadState* shared_quad_state, const gfx::RectF& tex_coord_rect, const gfx::Size& texture_size, bool swizzle_contents, + bool is_premultiplied, bool nearest_neighbor, bool force_anti_aliasing_off) { DrawQuad::SetAll(shared_quad_state, material, rect, visible_rect, @@ -49,6 +52,7 @@ void ContentDrawQuadBase::SetAll(const SharedQuadState* shared_quad_state, this->tex_coord_rect = tex_coord_rect; this->texture_size = texture_size; this->swizzle_contents = swizzle_contents; + this->is_premultiplied = is_premultiplied; this->nearest_neighbor = nearest_neighbor; this->force_anti_aliasing_off = force_anti_aliasing_off; } diff --git a/components/viz/common/quads/content_draw_quad_base.h b/components/viz/common/quads/content_draw_quad_base.h index 473fb4a71fe5a4..9b738be9afaf43 100644 --- a/components/viz/common/quads/content_draw_quad_base.h +++ b/components/viz/common/quads/content_draw_quad_base.h @@ -28,6 +28,7 @@ class VIZ_COMMON_EXPORT ContentDrawQuadBase : public DrawQuad { const gfx::RectF& tex_coord_rect, const gfx::Size& texture_size, bool swizzle_contents, + bool is_premultiplied, bool nearest_neighbor, bool force_anti_aliasing_off); @@ -39,12 +40,14 @@ class VIZ_COMMON_EXPORT ContentDrawQuadBase : public DrawQuad { const gfx::RectF& tex_coord_rect, const gfx::Size& texture_size, bool swizzle_contents, + bool is_premultiplied, bool nearest_neighbor, bool force_anti_aliasing_off); gfx::RectF tex_coord_rect; gfx::Size texture_size; bool swizzle_contents = false; + bool is_premultiplied = false; bool nearest_neighbor = false; bool force_anti_aliasing_off = false; diff --git a/components/viz/common/quads/draw_quad_unittest.cc b/components/viz/common/quads/draw_quad_unittest.cc index d53adc0dac56a4..c225a7cac25dc6 100644 --- a/components/viz/common/quads/draw_quad_unittest.cc +++ b/components/viz/common/quads/draw_quad_unittest.cc @@ -352,13 +352,15 @@ TEST(DrawQuadTest, CopyTileDrawQuad) { gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f); gfx::Size texture_size(85, 32); bool swizzle_contents = true; + bool contents_premultiplied = true; bool nearest_neighbor = true; bool force_anti_aliasing_off = false; CREATE_SHARED_STATE(); CREATE_QUAD_NEW(TileDrawQuad, visible_rect, needs_blending, resource_id, tex_coord_rect, texture_size, swizzle_contents, - nearest_neighbor, force_anti_aliasing_off); + contents_premultiplied, nearest_neighbor, + force_anti_aliasing_off); EXPECT_EQ(DrawQuad::TILED_CONTENT, copy_quad->material); EXPECT_EQ(visible_rect, copy_quad->visible_rect); EXPECT_EQ(needs_blending, copy_quad->needs_blending); @@ -369,7 +371,8 @@ TEST(DrawQuadTest, CopyTileDrawQuad) { EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor); CREATE_QUAD_ALL(TileDrawQuad, resource_id, tex_coord_rect, texture_size, - swizzle_contents, nearest_neighbor, force_anti_aliasing_off); + swizzle_contents, contents_premultiplied, nearest_neighbor, + force_anti_aliasing_off); EXPECT_EQ(DrawQuad::TILED_CONTENT, copy_quad->material); EXPECT_EQ(resource_id, copy_quad->resource_id()); EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect); @@ -599,13 +602,15 @@ TEST_F(DrawQuadIteratorTest, TileDrawQuad) { gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f); gfx::Size texture_size(85, 32); bool swizzle_contents = true; + bool contents_premultiplied = true; bool nearest_neighbor = true; bool force_anti_aliasing_off = false; CREATE_SHARED_STATE(); CREATE_QUAD_NEW(TileDrawQuad, visible_rect, needs_blending, resource_id, tex_coord_rect, texture_size, swizzle_contents, - nearest_neighbor, force_anti_aliasing_off); + contents_premultiplied, nearest_neighbor, + force_anti_aliasing_off); EXPECT_EQ(resource_id, quad_new->resource_id()); EXPECT_EQ(1, IterateAndCount(quad_new)); EXPECT_EQ(resource_id + 1, quad_new->resource_id()); diff --git a/components/viz/common/quads/picture_draw_quad.cc b/components/viz/common/quads/picture_draw_quad.cc index 4df5c55564e81f..2a51e856907389 100644 --- a/components/viz/common/quads/picture_draw_quad.cc +++ b/components/viz/common/quads/picture_draw_quad.cc @@ -32,8 +32,8 @@ void PictureDrawQuad::SetNew( ContentDrawQuadBase::SetNew( shared_quad_state, DrawQuad::PICTURE_CONTENT, rect, visible_rect, needs_blending, tex_coord_rect, texture_size, - !PlatformColor::SameComponentOrder(texture_format), nearest_neighbor, - false); + !PlatformColor::SameComponentOrder(texture_format), false, + nearest_neighbor, false); this->content_rect = content_rect; this->contents_scale = contents_scale; this->display_item_list = std::move(display_item_list); @@ -55,8 +55,8 @@ void PictureDrawQuad::SetAll( ContentDrawQuadBase::SetAll( shared_quad_state, DrawQuad::PICTURE_CONTENT, rect, visible_rect, needs_blending, tex_coord_rect, texture_size, - !PlatformColor::SameComponentOrder(texture_format), nearest_neighbor, - false); + !PlatformColor::SameComponentOrder(texture_format), false, + nearest_neighbor, false); this->content_rect = content_rect; this->contents_scale = contents_scale; this->display_item_list = std::move(display_item_list); diff --git a/components/viz/common/quads/tile_draw_quad.cc b/components/viz/common/quads/tile_draw_quad.cc index 07836c0709f488..72e8dee2018014 100644 --- a/components/viz/common/quads/tile_draw_quad.cc +++ b/components/viz/common/quads/tile_draw_quad.cc @@ -22,12 +22,13 @@ void TileDrawQuad::SetNew(const SharedQuadState* shared_quad_state, const gfx::RectF& tex_coord_rect, const gfx::Size& texture_size, bool swizzle_contents, + bool is_premultiplied, bool nearest_neighbor, bool force_anti_aliasing_off) { ContentDrawQuadBase::SetNew(shared_quad_state, DrawQuad::TILED_CONTENT, rect, visible_rect, needs_blending, tex_coord_rect, - texture_size, swizzle_contents, nearest_neighbor, - force_anti_aliasing_off); + texture_size, swizzle_contents, is_premultiplied, + nearest_neighbor, force_anti_aliasing_off); resources.ids[kResourceIdIndex] = resource_id; resources.count = 1; } @@ -40,12 +41,13 @@ void TileDrawQuad::SetAll(const SharedQuadState* shared_quad_state, const gfx::RectF& tex_coord_rect, const gfx::Size& texture_size, bool swizzle_contents, + bool is_premultiplied, bool nearest_neighbor, bool force_anti_aliasing_off) { ContentDrawQuadBase::SetAll(shared_quad_state, DrawQuad::TILED_CONTENT, rect, visible_rect, needs_blending, tex_coord_rect, - texture_size, swizzle_contents, nearest_neighbor, - force_anti_aliasing_off); + texture_size, swizzle_contents, is_premultiplied, + nearest_neighbor, force_anti_aliasing_off); resources.ids[kResourceIdIndex] = resource_id; resources.count = 1; } diff --git a/components/viz/common/quads/tile_draw_quad.h b/components/viz/common/quads/tile_draw_quad.h index 3d51c5dfaf2914..3fd00edd11c57d 100644 --- a/components/viz/common/quads/tile_draw_quad.h +++ b/components/viz/common/quads/tile_draw_quad.h @@ -30,6 +30,7 @@ class VIZ_COMMON_EXPORT TileDrawQuad : public ContentDrawQuadBase { const gfx::RectF& tex_coord_rect, const gfx::Size& texture_size, bool swizzle_contents, + bool is_premultiplied, bool nearest_neighbor, bool force_anti_aliasing_off); @@ -44,6 +45,7 @@ class VIZ_COMMON_EXPORT TileDrawQuad : public ContentDrawQuadBase { const gfx::RectF& tex_coord_rect, const gfx::Size& texture_size, bool swizzle_contents, + bool is_premultiplied, bool nearest_neighbor, bool force_anti_aliasing_off); diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc index a9c9a2dca05254..1bf0aacdb03682 100644 --- a/components/viz/service/display/gl_renderer.cc +++ b/components/viz/service/display/gl_renderer.cc @@ -2066,8 +2066,10 @@ void GLRenderer::DrawContentQuadAA(const ContentDrawQuadBase* quad, SetUseProgram( ProgramKey::Tile(tex_coord_precision, sampler, USE_AA, - quad->swizzle_contents ? DO_SWIZZLE : NO_SWIZZLE, false, - false, tint_gl_composited_content_), + quad->swizzle_contents ? DO_SWIZZLE : NO_SWIZZLE, + quad->is_premultiplied ? PREMULTIPLIED_ALPHA + : NON_PREMULTIPLIED_ALPHA, + false, false, tint_gl_composited_content_), quad_resource_lock.color_space(), current_frame()->current_render_pass->color_space); @@ -2168,6 +2170,8 @@ void GLRenderer::DrawContentQuadNoAA(const ContentDrawQuadBase* quad, SetUseProgram( ProgramKey::Tile(tex_coord_precision, sampler, NO_AA, quad->swizzle_contents ? DO_SWIZZLE : NO_SWIZZLE, + quad->is_premultiplied ? PREMULTIPLIED_ALPHA + : NON_PREMULTIPLIED_ALPHA, !quad->ShouldDrawWithBlending(), has_tex_clamp_rect, tint_gl_composited_content_), quad_resource_lock.color_space(), diff --git a/components/viz/service/display/gl_renderer_unittest.cc b/components/viz/service/display/gl_renderer_unittest.cc index 3da911f1cede16..94a288da834af3 100644 --- a/components/viz/service/display/gl_renderer_unittest.cc +++ b/components/viz/service/display/gl_renderer_unittest.cc @@ -290,26 +290,46 @@ class GLRendererShaderPixelTest : public cc::GLRendererPixelTest { TestShader(ProgramKey::Texture(precision, sampler, NON_PREMULTIPLIED_ALPHA, true, false, false)); - TestShader(ProgramKey::Tile(precision, sampler, USE_AA, NO_SWIZZLE, false, - false, false)); - TestShader(ProgramKey::Tile(precision, sampler, USE_AA, DO_SWIZZLE, false, - false, false)); - TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, false, - false, false)); - TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, false, - false, false)); - TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, true, - false, false)); - TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, true, - false, false)); - TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, false, - true, false)); - TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, false, - true, false)); - TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, true, - true, false)); - TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, true, - true, false)); + TestShader(ProgramKey::Tile(precision, sampler, USE_AA, NO_SWIZZLE, + PREMULTIPLIED_ALPHA, false, false, false)); + TestShader(ProgramKey::Tile(precision, sampler, USE_AA, DO_SWIZZLE, + PREMULTIPLIED_ALPHA, false, false, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, + PREMULTIPLIED_ALPHA, false, false, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, + PREMULTIPLIED_ALPHA, false, false, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, + PREMULTIPLIED_ALPHA, true, false, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, + PREMULTIPLIED_ALPHA, true, false, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, + PREMULTIPLIED_ALPHA, false, true, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, + PREMULTIPLIED_ALPHA, false, true, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, + PREMULTIPLIED_ALPHA, true, true, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, + PREMULTIPLIED_ALPHA, true, true, false)); + TestShader(ProgramKey::Tile(precision, sampler, USE_AA, NO_SWIZZLE, + NON_PREMULTIPLIED_ALPHA, false, false, false)); + TestShader(ProgramKey::Tile(precision, sampler, USE_AA, DO_SWIZZLE, + NON_PREMULTIPLIED_ALPHA, false, false, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, + NON_PREMULTIPLIED_ALPHA, false, false, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, + NON_PREMULTIPLIED_ALPHA, false, false, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, + NON_PREMULTIPLIED_ALPHA, true, false, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, + NON_PREMULTIPLIED_ALPHA, true, false, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, + NON_PREMULTIPLIED_ALPHA, false, true, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, + NON_PREMULTIPLIED_ALPHA, false, true, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, NO_SWIZZLE, + NON_PREMULTIPLIED_ALPHA, true, true, false)); + TestShader(ProgramKey::Tile(precision, sampler, NO_AA, DO_SWIZZLE, + NON_PREMULTIPLIED_ALPHA, true, true, false)); // Iterate over alpha plane, nv12, and color_lut parameters. UVTextureMode uv_modes[2] = {UV_TEXTURE_MODE_UV, UV_TEXTURE_MODE_U_V}; diff --git a/components/viz/service/display/program_binding.cc b/components/viz/service/display/program_binding.cc index 742c7a25971dbd..9436dc3d784010 100644 --- a/components/viz/service/display/program_binding.cc +++ b/components/viz/service/display/program_binding.cc @@ -63,6 +63,7 @@ ProgramKey ProgramKey::Tile(TexCoordPrecision precision, SamplerType sampler, AAMode aa_mode, SwizzleMode swizzle_mode, + PremultipliedAlphaMode premultiplied_alpha, bool is_opaque, bool has_tex_clamp_rect, bool tint_color) { @@ -75,6 +76,7 @@ ProgramKey ProgramKey::Tile(TexCoordPrecision precision, result.is_opaque_ = is_opaque; result.has_tex_clamp_rect_ = has_tex_clamp_rect; result.has_tint_color_matrix_ = tint_color; + result.premultiplied_alpha_ = premultiplied_alpha; return result; } diff --git a/components/viz/service/display/program_binding.h b/components/viz/service/display/program_binding.h index 42fed4dc73f48a..8b28c57f854e79 100644 --- a/components/viz/service/display/program_binding.h +++ b/components/viz/service/display/program_binding.h @@ -82,6 +82,7 @@ class VIZ_SERVICE_EXPORT ProgramKey { SamplerType sampler, AAMode aa_mode, SwizzleMode swizzle_mode, + PremultipliedAlphaMode premultiplied_alpha, bool is_opaque, bool has_tex_clamp_rect, bool tint_color); diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc index 3ab4d60efcb218..9083535bc2b857 100644 --- a/components/viz/service/display/renderer_pixeltest.cc +++ b/components/viz/service/display/renderer_pixeltest.cc @@ -2802,6 +2802,7 @@ TEST_F(GLRendererPixelTest, TileDrawQuadForceAntiAliasingOff) { CreateTestRenderPass(id, rect, transform_to_root); bool swizzle_contents = true; + bool contents_premultiplied = true; bool needs_blending = false; bool nearest_neighbor = true; bool force_anti_aliasing_off = true; @@ -2814,7 +2815,8 @@ TEST_F(GLRendererPixelTest, TileDrawQuadForceAntiAliasingOff) { TileDrawQuad* hole = pass->CreateAndAppendDrawQuad(); hole->SetNew(hole_shared_state, rect, rect, needs_blending, mapped_resource, gfx::RectF(gfx::Rect(tile_size)), tile_size, swizzle_contents, - nearest_neighbor, force_anti_aliasing_off); + contents_premultiplied, nearest_neighbor, + force_anti_aliasing_off); gfx::Transform green_quad_to_target_transform; SharedQuadState* green_shared_state = CreateTestSharedQuadState( @@ -3197,6 +3199,7 @@ TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNearestNeighbor) { TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) { gfx::Rect viewport(this->device_viewport_size_); bool swizzle_contents = true; + bool contents_premultiplied = true; bool needs_blending = true; bool nearest_neighbor = true; bool force_anti_aliasing_off = false; @@ -3239,7 +3242,8 @@ TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) { auto* quad = pass->CreateAndAppendDrawQuad(); quad->SetNew(shared_state, viewport, viewport, needs_blending, mapped_resource, gfx::RectF(gfx::Rect(tile_size)), tile_size, - swizzle_contents, nearest_neighbor, force_anti_aliasing_off); + swizzle_contents, contents_premultiplied, nearest_neighbor, + force_anti_aliasing_off); RenderPassList pass_list; pass_list.push_back(std::move(pass)); @@ -3727,6 +3731,7 @@ TEST_F(GLRendererPixelTest, TextureQuadBatching) { TEST_F(GLRendererPixelTest, TileQuadClamping) { gfx::Rect viewport(this->device_viewport_size_); bool swizzle_contents = true; + bool contents_premultiplied = true; bool needs_blending = true; bool nearest_neighbor = false; bool use_aa = false; @@ -3780,7 +3785,8 @@ TEST_F(GLRendererPixelTest, TileQuadClamping) { auto* quad = pass->CreateAndAppendDrawQuad(); quad->SetNew(quad_shared, gfx::Rect(layer_size), gfx::Rect(layer_size), needs_blending, mapped_resource, tex_coord_rect, tile_size, - swizzle_contents, nearest_neighbor, use_aa); + swizzle_contents, contents_premultiplied, nearest_neighbor, + use_aa); // Green background. SharedQuadState* background_shared = diff --git a/components/viz/service/display/software_renderer_unittest.cc b/components/viz/service/display/software_renderer_unittest.cc index 1ba2f6fe9fc227..9308b0c7fe5805 100644 --- a/components/viz/service/display/software_renderer_unittest.cc +++ b/components/viz/service/display/software_renderer_unittest.cc @@ -198,11 +198,11 @@ TEST_F(SoftwareRendererTest, TileQuad) { auto* inner_quad = root_render_pass->CreateAndAppendDrawQuad(); inner_quad->SetNew(shared_quad_state, inner_rect, inner_rect, needs_blending, mapped_resource_cyan, gfx::RectF(gfx::SizeF(inner_size)), - inner_size, false, false, false); + inner_size, false, false, false, false); auto* outer_quad = root_render_pass->CreateAndAppendDrawQuad(); outer_quad->SetNew(shared_quad_state, outer_rect, outer_rect, needs_blending, mapped_resource_yellow, gfx::RectF(gfx::SizeF(outer_size)), - outer_size, false, false, false); + outer_size, false, false, false, false); RenderPassList list; list.push_back(std::move(root_render_pass)); @@ -260,7 +260,7 @@ TEST_F(SoftwareRendererTest, TileQuadVisibleRect) { auto* quad = root_render_pass->CreateAndAppendDrawQuad(); quad->SetNew(shared_quad_state, tile_rect, tile_rect, needs_blending, mapped_resource_cyan, gfx::RectF(gfx::SizeF(tile_size)), - tile_size, false, false, false); + tile_size, false, false, false, false); quad->visible_rect = visible_rect; RenderPassList list; diff --git a/components/viz/test/data/blue_yellow_flipped_dither.png b/components/viz/test/data/blue_yellow_flipped_dither.png new file mode 100644 index 0000000000000000000000000000000000000000..c81d4fe8cda3570dd17c8d1842214f30d85b01a3 GIT binary patch literal 824 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k2}mkgS)OEIVEXUr;uumf=k2wNorf8CSOOnD znDFm*@4@foF^qA3LhsXOFo~7D+Gqbg_WR#`>mL2lv|qLE{q|MsUTdA3|7r27uT`Rt zHrv!~Z~LKQ{m1bBbE$6knB>G3DQ@F8ACA||&(@JE>}?gy(mAu?u>9xRbsH;=n2Ncr z*l2K=ul~&UoyQ&tUXPGicB1{LhYctA72PDgB)P$H({S zJ=&Fj{!2b~lY1T+`u_8pRg*t2k4gU6k*#wj!lGTOJ6p%@xT#o{&K&37qo!i>A4_qY zik(|{?2%OWd0krX$7p%nL}hz)$1I&+R4dTr6mnyC}fZX)KF z{IGP+u_hC-HO^Ap%Qt?o@=JD<;=ZQX+j=>oLU#E^g$(dRwm(X-(ey?*_l;JU7@~Qq%K!S5D9O z=gB|*uiLQxs;jhiZG)4K{DJ!m4*hQqmw#M(-|X0XiMIdmxqfSX_J8sGVf^%m|92nS z7bgCpVx;xhh#m)2pw7+Po8HSBk6t@cU27%}@#| zT+1M}TKzKn2lEvL{h2ya*^}-0SHdZH7|d9V@3@fy(=UC`0vjf63DvdhdLuj?Ixw9SJ8X?qk3t{rE31$2$Wvx#A#I(Ds3U YeIWnLKjJTmdKI;Vst0HUXm@Bjb+ literal 0 HcmV?d00001 diff --git a/services/viz/public/cpp/compositing/quads_struct_traits.cc b/services/viz/public/cpp/compositing/quads_struct_traits.cc index 412c5d372174ff..d7967fc9ce9c94 100644 --- a/services/viz/public/cpp/compositing/quads_struct_traits.cc +++ b/services/viz/public/cpp/compositing/quads_struct_traits.cc @@ -158,6 +158,7 @@ bool StructTraits::Read( } quad->swizzle_contents = data.swizzle_contents(); + quad->is_premultiplied = data.is_premultiplied(); quad->nearest_neighbor = data.nearest_neighbor(); quad->force_anti_aliasing_off = data.force_anti_aliasing_off(); quad->resources.ids[viz::TileDrawQuad::kResourceIdIndex] = data.resource_id(); diff --git a/services/viz/public/cpp/compositing/quads_struct_traits.h b/services/viz/public/cpp/compositing/quads_struct_traits.h index c7b07abc330768..c5fd0ec9b2850b 100644 --- a/services/viz/public/cpp/compositing/quads_struct_traits.h +++ b/services/viz/public/cpp/compositing/quads_struct_traits.h @@ -350,6 +350,11 @@ struct StructTraits { return quad->swizzle_contents; } + static bool is_premultiplied(const viz::DrawQuad& input) { + const viz::TileDrawQuad* quad = viz::TileDrawQuad::MaterialCast(&input); + return quad->is_premultiplied; + } + static bool nearest_neighbor(const viz::DrawQuad& input) { const viz::TileDrawQuad* quad = viz::TileDrawQuad::MaterialCast(&input); return quad->nearest_neighbor; diff --git a/services/viz/public/interfaces/compositing/quads.mojom b/services/viz/public/interfaces/compositing/quads.mojom index a8b9bc116077ec..39dcb534d35c37 100644 --- a/services/viz/public/interfaces/compositing/quads.mojom +++ b/services/viz/public/interfaces/compositing/quads.mojom @@ -78,6 +78,7 @@ struct TileQuadState { gfx.mojom.RectF tex_coord_rect; gfx.mojom.Size texture_size; bool swizzle_contents; + bool is_premultiplied; uint32 resource_id; bool nearest_neighbor; bool force_anti_aliasing_off;