| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <stddef.h> |
| |
| #include <utility> |
| #include <variant> |
| #include <vector> |
| |
| #include "base/containers/flat_map.h" |
| #include "base/functional/bind.h" |
| #include "base/functional/callback_helpers.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/unguessable_token.h" |
| #include "build/build_config.h" |
| #include "cc/test/fake_output_surface_client.h" |
| #include "cc/test/resource_provider_test_utils.h" |
| #include "components/viz/client/client_resource_provider.h" |
| #include "components/viz/common/frame_sinks/copy_output_request.h" |
| #include "components/viz/common/quads/aggregated_render_pass.h" |
| #include "components/viz/common/quads/aggregated_render_pass_draw_quad.h" |
| #include "components/viz/common/quads/compositor_render_pass.h" |
| #include "components/viz/common/quads/compositor_render_pass_draw_quad.h" |
| #include "components/viz/common/quads/solid_color_draw_quad.h" |
| #include "components/viz/common/quads/texture_draw_quad.h" |
| #include "components/viz/common/quads/video_hole_draw_quad.h" |
| #include "components/viz/common/resources/transferable_resource.h" |
| #include "components/viz/service/display/ca_layer_overlay.h" |
| #include "components/viz/service/display/display_resource_provider_skia.h" |
| #include "components/viz/service/display/output_surface.h" |
| #include "components/viz/service/display/output_surface_client.h" |
| #include "components/viz/service/display/output_surface_frame.h" |
| #include "components/viz/service/display/overlay_processor_mac.h" |
| #include "components/viz/test/fake_skia_output_surface.h" |
| #include "components/viz/test/overlay_candidate_matchers.h" |
| #include "components/viz/test/test_context_provider.h" |
| #include "components/viz/test/test_gles2_interface.h" |
| #include "gpu/command_buffer/client/client_shared_image.h" |
| #include "gpu/config/gpu_finch_features.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/gfx/geometry/rect_conversions.h" |
| #include "ui/gfx/video_types.h" |
| #include "ui/latency/latency_info.h" |
| |
| using testing::_; |
| using testing::Mock; |
| |
| namespace viz { |
| namespace { |
| |
| const gfx::Rect kOverlayRect(0, 0, 256, 256); |
| const gfx::PointF kUVTopLeft(0.1f, 0.2f); |
| const gfx::PointF kUVBottomRight(1.0f, 1.0f); |
| const gfx::Rect kRenderPassOutputRect(0, 0, 256, 256); |
| const gfx::Rect kOverlayDamageRect(0, 0, 100, 100); |
| |
| class CATestOverlayProcessor : public OverlayProcessorMac { |
| public: |
| CATestOverlayProcessor() : OverlayProcessorMac() {} |
| }; |
| |
| std::unique_ptr<AggregatedRenderPass> CreateRenderPass() { |
| AggregatedRenderPassId render_pass_id{1}; |
| |
| auto pass = std::make_unique<AggregatedRenderPass>(); |
| pass->SetNew(render_pass_id, kRenderPassOutputRect, kRenderPassOutputRect, |
| gfx::Transform()); |
| |
| SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState(); |
| shared_state->opacity = 1.f; |
| return pass; |
| } |
| |
| static ResourceId CreateResourceInLayerTree( |
| ClientResourceProvider* child_resource_provider, |
| const gfx::Size& size, |
| bool is_overlay_candidate) { |
| gpu::SharedImageUsageSet usage = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ; |
| if (is_overlay_candidate) { |
| usage |= gpu::SHARED_IMAGE_USAGE_SCANOUT; |
| } |
| auto resource = TransferableResource::Make( |
| gpu::ClientSharedImage::CreateForTesting( |
| {SinglePlaneFormat::kRGBA_8888, size, gfx::ColorSpace(), |
| kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, usage}, |
| GL_TEXTURE_2D), |
| TransferableResource::ResourceSource::kTest, gpu::SyncToken()); |
| |
| ResourceId resource_id = |
| child_resource_provider->ImportResource(resource, base::DoNothing()); |
| |
| return resource_id; |
| } |
| |
| ResourceId CreateResource(DisplayResourceProvider* parent_resource_provider, |
| ClientResourceProvider* child_resource_provider, |
| RasterContextProvider* child_context_provider, |
| const gfx::Size& size, |
| bool is_overlay_candidate) { |
| ResourceId resource_id = CreateResourceInLayerTree( |
| child_resource_provider, size, is_overlay_candidate); |
| |
| int child_id = |
| parent_resource_provider->CreateChild(base::DoNothing(), SurfaceId()); |
| |
| // Transfer resource to the parent. |
| std::vector<ResourceId> resource_ids_to_transfer; |
| resource_ids_to_transfer.push_back(resource_id); |
| std::vector<TransferableResource> list; |
| |
| CHECK(child_context_provider); |
| child_resource_provider->PrepareSendToParent( |
| resource_ids_to_transfer, &list, |
| child_context_provider->SharedImageInterface()); |
| parent_resource_provider->ReceiveFromChild(child_id, list); |
| |
| // Delete it in the child so it won't be leaked, and will be released once |
| // returned from the parent. |
| child_resource_provider->RemoveImportedResource(resource_id); |
| |
| // In DisplayResourceProvider's namespace, use the mapped resource id. |
| std::unordered_map<ResourceId, ResourceId, ResourceIdHasher> resource_map = |
| parent_resource_provider->GetChildToParentMap(child_id); |
| return resource_map[list[0].id]; |
| } |
| |
| TextureDrawQuad* CreateCandidateQuadAt( |
| DisplayResourceProvider* parent_resource_provider, |
| ClientResourceProvider* child_resource_provider, |
| RasterContextProvider* child_context_provider, |
| const SharedQuadState* shared_quad_state, |
| AggregatedRenderPass* render_pass, |
| const gfx::Rect& rect, |
| gfx::ProtectedVideoType protected_video_type) { |
| bool needs_blending = false; |
| bool nearest_neighbor = false; |
| gfx::Size resource_size_in_pixels = rect.size(); |
| bool is_overlay_candidate = true; |
| ResourceId resource_id = CreateResource( |
| parent_resource_provider, child_resource_provider, child_context_provider, |
| resource_size_in_pixels, is_overlay_candidate); |
| |
| auto* overlay_quad = render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); |
| overlay_quad->SetNew(shared_quad_state, rect, rect, needs_blending, |
| resource_id, kUVTopLeft, kUVBottomRight, |
| SkColors::kTransparent, nearest_neighbor, |
| /*secure_output_only=*/false, protected_video_type); |
| |
| return overlay_quad; |
| } |
| |
| TextureDrawQuad* CreateFullscreenCandidateQuad( |
| DisplayResourceProvider* parent_resource_provider, |
| ClientResourceProvider* child_resource_provider, |
| RasterContextProvider* child_context_provider, |
| const SharedQuadState* shared_quad_state, |
| AggregatedRenderPass* render_pass) { |
| return CreateCandidateQuadAt( |
| parent_resource_provider, child_resource_provider, child_context_provider, |
| shared_quad_state, render_pass, render_pass->output_rect, |
| gfx::ProtectedVideoType::kClear); |
| } |
| |
| SkM44 GetIdentityColorMatrix() { |
| return SkM44(); |
| } |
| |
| class CALayerOverlayTest : public testing::Test { |
| protected: |
| void SetUp() override { |
| output_surface_ = FakeSkiaOutputSurface::Create3d(); |
| output_surface_->BindToClient(&output_surface_client_); |
| |
| resource_provider_ = std::make_unique<DisplayResourceProviderSkia>(); |
| lock_set_for_external_use_.emplace(resource_provider_.get(), |
| output_surface_.get()); |
| |
| child_provider_ = TestContextProvider::Create(); |
| child_provider_->BindToCurrentSequence(); |
| child_resource_provider_ = std::make_unique<ClientResourceProvider>(); |
| |
| overlay_processor_ = std::make_unique<CATestOverlayProcessor>(); |
| } |
| |
| void TearDown() override { |
| overlay_processor_ = nullptr; |
| child_resource_provider_->ShutdownAndReleaseAllResources(); |
| child_resource_provider_ = nullptr; |
| child_provider_ = nullptr; |
| lock_set_for_external_use_.reset(); |
| resource_provider_ = nullptr; |
| output_surface_ = nullptr; |
| } |
| |
| std::optional<OverlayCandidate>& GetDefaultPrimaryPlane( |
| const gfx::Size& size) { |
| primary_plane_ = OverlayProcessorInterface::ProcessOutputSurfaceAsOverlay( |
| size, size, SinglePlaneFormat::kRGBA_8888, |
| gfx::ColorSpace::CreateSRGB(), false, 1.0, gpu::Mailbox()); |
| return primary_plane_; |
| } |
| |
| std::unique_ptr<SkiaOutputSurface> output_surface_; |
| cc::FakeOutputSurfaceClient output_surface_client_; |
| std::unique_ptr<DisplayResourceProviderSkia> resource_provider_; |
| std::optional<DisplayResourceProviderSkia::LockSetForExternalUse> |
| lock_set_for_external_use_; |
| scoped_refptr<TestContextProvider> child_provider_; |
| std::unique_ptr<ClientResourceProvider> child_resource_provider_; |
| std::unique_ptr<CATestOverlayProcessor> overlay_processor_; |
| gfx::Rect damage_rect_ = kOverlayDamageRect; |
| std::vector<gfx::Rect> content_bounds_; |
| |
| private: |
| std::optional<OverlayCandidate> primary_plane_; |
| }; |
| |
| TEST_F(CALayerOverlayTest, AllowNonAxisAlignedTransform) { |
| auto pass = CreateRenderPass(); |
| CreateFullscreenCandidateQuad( |
| resource_provider_.get(), child_resource_provider_.get(), |
| child_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); |
| pass->shared_quad_state_list.back() |
| ->quad_to_target_transform.RotateAboutZAxis(45.f); |
| |
| OverlayCandidateList ca_layer_list; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_filters; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; |
| AggregatedRenderPassList pass_list; |
| pass_list.push_back(std::move(pass)); |
| SurfaceDamageRectList surface_damage_rect_list; |
| |
| overlay_processor_->ProcessForOverlays( |
| resource_provider_.get(), &pass_list, GetIdentityColorMatrix(), |
| render_pass_filters, render_pass_backdrop_filters, |
| std::move(surface_damage_rect_list), |
| GetDefaultPrimaryPlane(pass_list.back()->output_rect.size()), |
| &ca_layer_list, &damage_rect_, &content_bounds_); |
| EXPECT_EQ(gfx::Rect(), damage_rect_); |
| EXPECT_EQ(1U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list)); |
| gfx::Rect overlay_damage = overlay_processor_->GetAndResetOverlayDamage(); |
| EXPECT_EQ(kRenderPassOutputRect, overlay_damage); |
| } |
| |
| TEST_F(CALayerOverlayTest, ThreeDTransform) { |
| auto pass = CreateRenderPass(); |
| CreateFullscreenCandidateQuad( |
| resource_provider_.get(), child_resource_provider_.get(), |
| child_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); |
| pass->shared_quad_state_list.back() |
| ->quad_to_target_transform.RotateAboutXAxis(45.f); |
| |
| OverlayCandidateList ca_layer_list; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_filters; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; |
| AggregatedRenderPassList pass_list; |
| pass_list.push_back(std::move(pass)); |
| SurfaceDamageRectList surface_damage_rect_list; |
| |
| overlay_processor_->ProcessForOverlays( |
| resource_provider_.get(), &pass_list, GetIdentityColorMatrix(), |
| render_pass_filters, render_pass_backdrop_filters, |
| std::move(surface_damage_rect_list), |
| GetDefaultPrimaryPlane(pass_list.back()->output_rect.size()), |
| &ca_layer_list, &damage_rect_, &content_bounds_); |
| EXPECT_EQ(1U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list)); |
| gfx::Rect overlay_damage = overlay_processor_->GetAndResetOverlayDamage(); |
| EXPECT_EQ(kRenderPassOutputRect, overlay_damage); |
| gfx::Transform expected_transform; |
| expected_transform.RotateAboutXAxis(45.f); |
| gfx::Transform actual_transform( |
| std::get<gfx::Transform>(ca_layer_list.back().transform)); |
| EXPECT_EQ(expected_transform.ToString(), actual_transform.ToString()); |
| } |
| |
| TEST_F(CALayerOverlayTest, AllowContainingClip) { |
| auto pass = CreateRenderPass(); |
| CreateFullscreenCandidateQuad( |
| resource_provider_.get(), child_resource_provider_.get(), |
| child_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); |
| pass->shared_quad_state_list.back()->clip_rect = kOverlayRect; |
| |
| OverlayCandidateList ca_layer_list; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_filters; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; |
| AggregatedRenderPassList pass_list; |
| pass_list.push_back(std::move(pass)); |
| SurfaceDamageRectList surface_damage_rect_list; |
| |
| overlay_processor_->ProcessForOverlays( |
| resource_provider_.get(), &pass_list, GetIdentityColorMatrix(), |
| render_pass_filters, render_pass_backdrop_filters, |
| std::move(surface_damage_rect_list), |
| GetDefaultPrimaryPlane(pass_list.back()->output_rect.size()), |
| &ca_layer_list, &damage_rect_, &content_bounds_); |
| EXPECT_EQ(gfx::Rect(), damage_rect_); |
| EXPECT_EQ(1U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list)); |
| } |
| |
| TEST_F(CALayerOverlayTest, NontrivialClip) { |
| auto pass = CreateRenderPass(); |
| CreateFullscreenCandidateQuad( |
| resource_provider_.get(), child_resource_provider_.get(), |
| child_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); |
| pass->shared_quad_state_list.back()->clip_rect = gfx::Rect(64, 64, 128, 128); |
| |
| OverlayCandidateList ca_layer_list; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_filters; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; |
| AggregatedRenderPassList pass_list; |
| pass_list.push_back(std::move(pass)); |
| SurfaceDamageRectList surface_damage_rect_list; |
| |
| overlay_processor_->ProcessForOverlays( |
| resource_provider_.get(), &pass_list, GetIdentityColorMatrix(), |
| render_pass_filters, render_pass_backdrop_filters, |
| std::move(surface_damage_rect_list), |
| GetDefaultPrimaryPlane(pass_list.back()->output_rect.size()), |
| &ca_layer_list, &damage_rect_, &content_bounds_); |
| EXPECT_EQ(gfx::Rect(), damage_rect_); |
| EXPECT_EQ(1U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list)); |
| EXPECT_EQ(gfx::Rect(64, 64, 128, 128), |
| ca_layer_list.back().clip_rect.value()); |
| } |
| |
| TEST_F(CALayerOverlayTest, SkipTransparent) { |
| auto pass = CreateRenderPass(); |
| CreateFullscreenCandidateQuad( |
| resource_provider_.get(), child_resource_provider_.get(), |
| child_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); |
| pass->shared_quad_state_list.back()->opacity = 0; |
| |
| OverlayCandidateList ca_layer_list; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_filters; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; |
| AggregatedRenderPassList pass_list; |
| pass_list.push_back(std::move(pass)); |
| SurfaceDamageRectList surface_damage_rect_list; |
| |
| overlay_processor_->ProcessForOverlays( |
| resource_provider_.get(), &pass_list, GetIdentityColorMatrix(), |
| render_pass_filters, render_pass_backdrop_filters, |
| std::move(surface_damage_rect_list), |
| GetDefaultPrimaryPlane(pass_list.back()->output_rect.size()), |
| &ca_layer_list, &damage_rect_, &content_bounds_); |
| EXPECT_EQ(gfx::Rect(), damage_rect_); |
| EXPECT_EQ(0U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list)); |
| } |
| |
| TEST_F(CALayerOverlayTest, SkipNonVisible) { |
| auto pass = CreateRenderPass(); |
| CreateFullscreenCandidateQuad( |
| resource_provider_.get(), child_resource_provider_.get(), |
| child_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); |
| pass->quad_list.back()->visible_rect.set_size(gfx::Size()); |
| |
| OverlayCandidateList ca_layer_list; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_filters; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; |
| AggregatedRenderPassList pass_list; |
| pass_list.push_back(std::move(pass)); |
| SurfaceDamageRectList surface_damage_rect_list; |
| |
| overlay_processor_->ProcessForOverlays( |
| resource_provider_.get(), &pass_list, GetIdentityColorMatrix(), |
| render_pass_filters, render_pass_backdrop_filters, |
| std::move(surface_damage_rect_list), |
| GetDefaultPrimaryPlane(pass_list.back()->output_rect.size()), |
| &ca_layer_list, &damage_rect_, &content_bounds_); |
| EXPECT_EQ(gfx::Rect(), damage_rect_); |
| EXPECT_EQ(0U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list)); |
| } |
| |
| TEST_F(CALayerOverlayTest, TextureDrawQuadVideoOverlay) { |
| const gfx::Size size(640, 480); |
| bool is_overlay_candidate = true; |
| ResourceId resource_id = |
| CreateResource(resource_provider_.get(), child_resource_provider_.get(), |
| child_provider_.get(), size, is_overlay_candidate); |
| |
| // Video frames of TextureDrawQuad should be promoted to overlays. |
| { |
| auto pass = CreateRenderPass(); |
| auto* texture_video_quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); |
| texture_video_quad->SetNew( |
| pass->shared_quad_state_list.back(), gfx::Rect(size), gfx::Rect(size), |
| /*needs_blending=*/false, resource_id, kUVTopLeft, kUVBottomRight, |
| SkColors::kTransparent, |
| /*nearest_neighbor=*/false, |
| /*secure_output_only=*/false, |
| /*video_type=*/gfx::ProtectedVideoType::kClear); |
| texture_video_quad->is_video_frame = true; |
| |
| OverlayCandidateList ca_layer_list; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_filters; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; |
| AggregatedRenderPassList pass_list; |
| pass_list.push_back(std::move(pass)); |
| SurfaceDamageRectList surface_damage_rect_list; |
| |
| overlay_processor_->ProcessForOverlays( |
| resource_provider_.get(), &pass_list, GetIdentityColorMatrix(), |
| render_pass_filters, render_pass_backdrop_filters, |
| std::move(surface_damage_rect_list), |
| GetDefaultPrimaryPlane(pass_list.back()->output_rect.size()), |
| &ca_layer_list, &damage_rect_, &content_bounds_); |
| EXPECT_EQ(gfx::Rect(), damage_rect_); |
| EXPECT_EQ(1U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list)); |
| } |
| } |
| |
| TEST_F(CALayerOverlayTest, OverlayErrorCode) { |
| OverlayProcessorInterface::FilterOperationsMap render_pass_filters; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; |
| |
| // Frame #1 |
| { |
| auto pass = CreateRenderPass(); |
| CreateFullscreenCandidateQuad( |
| resource_provider_.get(), child_resource_provider_.get(), |
| child_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); |
| |
| OverlayCandidateList ca_layer_list; |
| AggregatedRenderPassList pass_list; |
| pass_list.push_back(std::move(pass)); |
| SurfaceDamageRectList surface_damage_rect_list; |
| |
| overlay_processor_->ProcessForOverlays( |
| resource_provider_.get(), &pass_list, GetIdentityColorMatrix(), |
| render_pass_filters, render_pass_backdrop_filters, |
| std::move(surface_damage_rect_list), |
| GetDefaultPrimaryPlane(pass_list.back()->output_rect.size()), |
| &ca_layer_list, &damage_rect_, &content_bounds_); |
| |
| // There should be no error. |
| gfx::CALayerResult error_code = overlay_processor_->GetCALayerErrorCode(); |
| EXPECT_EQ(1U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list)); |
| // kCALayerSuccess = 0, |
| EXPECT_EQ(0, error_code); |
| } |
| |
| // Frame #2 |
| { |
| auto pass = CreateRenderPass(); |
| CreateFullscreenCandidateQuad( |
| resource_provider_.get(), child_resource_provider_.get(), |
| child_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); |
| |
| // Add a copy request to the render pass |
| pass->copy_requests.push_back(CopyOutputRequest::CreateStubForTesting()); |
| |
| OverlayCandidateList ca_layer_list; |
| AggregatedRenderPassList pass_list; |
| pass_list.push_back(std::move(pass)); |
| SurfaceDamageRectList surface_damage_rect_list; |
| |
| overlay_processor_->ProcessForOverlays( |
| resource_provider_.get(), &pass_list, GetIdentityColorMatrix(), |
| render_pass_filters, render_pass_backdrop_filters, |
| std::move(surface_damage_rect_list), |
| GetDefaultPrimaryPlane(pass_list.back()->output_rect.size()), |
| &ca_layer_list, &damage_rect_, &content_bounds_); |
| |
| // Overlay should fail when there is a copy request. |
| EXPECT_EQ(0U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list)); |
| |
| // kCALayerFailedCopyRequests = 31, |
| gfx::CALayerResult error_code = overlay_processor_->GetCALayerErrorCode(); |
| EXPECT_EQ(31, error_code); |
| } |
| } |
| |
| class CALayerOverlayRPDQTest : public CALayerOverlayTest { |
| protected: |
| void SetUp() override { |
| CALayerOverlayTest::SetUp(); |
| pass_list_.push_back(CreateRenderPass()); |
| pass_ = pass_list_.back().get(); |
| quad_ = pass_->CreateAndAppendDrawQuad<AggregatedRenderPassDrawQuad>(); |
| render_pass_id_ = AggregatedRenderPassId{3}; |
| } |
| |
| void ProcessForOverlays() { |
| overlay_processor_->ProcessForOverlays( |
| resource_provider_.get(), &pass_list_, GetIdentityColorMatrix(), |
| render_pass_filters_, render_pass_backdrop_filters_, |
| std::move(surface_damage_rect_list_), |
| GetDefaultPrimaryPlane(pass_->output_rect.size()), &ca_layer_list_, |
| &damage_rect_, &content_bounds_); |
| } |
| AggregatedRenderPassList pass_list_; |
| raw_ptr<AggregatedRenderPass> pass_; |
| raw_ptr<AggregatedRenderPassDrawQuad> quad_; |
| AggregatedRenderPassId render_pass_id_; |
| cc::FilterOperations filters_; |
| cc::FilterOperations backdrop_filters_; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_filters_; |
| OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters_; |
| OverlayCandidateList ca_layer_list_; |
| SurfaceDamageRectList surface_damage_rect_list_; |
| }; |
| |
| TEST_F(CALayerOverlayRPDQTest, RenderPassDrawQuadNoFilters) { |
| quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, |
| kOverlayRect, render_pass_id_, kInvalidResourceId, gfx::RectF(), |
| gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), |
| false, 1.0f); |
| ProcessForOverlays(); |
| |
| EXPECT_EQ(1U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list_)); |
| } |
| |
| TEST_F(CALayerOverlayRPDQTest, RenderPassDrawQuadAllValidFilters) { |
| filters_.Append(cc::FilterOperation::CreateGrayscaleFilter(0.1f)); |
| filters_.Append(cc::FilterOperation::CreateSepiaFilter(0.2f)); |
| filters_.Append(cc::FilterOperation::CreateSaturateFilter(0.3f)); |
| filters_.Append(cc::FilterOperation::CreateHueRotateFilter(0.4f)); |
| filters_.Append(cc::FilterOperation::CreateInvertFilter(0.5f)); |
| filters_.Append(cc::FilterOperation::CreateBrightnessFilter(0.6f)); |
| filters_.Append(cc::FilterOperation::CreateContrastFilter(0.7f)); |
| filters_.Append(cc::FilterOperation::CreateOpacityFilter(0.8f)); |
| filters_.Append(cc::FilterOperation::CreateBlurFilter(0.9f)); |
| filters_.Append(cc::FilterOperation::CreateDropShadowFilter( |
| gfx::Point(10, 20), 1.0f, SkColors::kGreen)); |
| render_pass_filters_[render_pass_id_] = &filters_; |
| quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, |
| kOverlayRect, render_pass_id_, kInvalidResourceId, gfx::RectF(), |
| gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), |
| false, 1.0f); |
| ProcessForOverlays(); |
| |
| EXPECT_EQ(1U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list_)); |
| } |
| |
| TEST_F(CALayerOverlayRPDQTest, RenderPassDrawQuadOpacityFilterScale) { |
| filters_.Append(cc::FilterOperation::CreateOpacityFilter(0.8f)); |
| render_pass_filters_[render_pass_id_] = &filters_; |
| quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, |
| kOverlayRect, render_pass_id_, kInvalidResourceId, gfx::RectF(), |
| gfx::Size(), gfx::Vector2dF(1, 2), gfx::PointF(), gfx::RectF(), |
| false, 1.0f); |
| ProcessForOverlays(); |
| EXPECT_EQ(1U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list_)); |
| } |
| |
| TEST_F(CALayerOverlayRPDQTest, RenderPassDrawQuadBlurFilterScale) { |
| filters_.Append(cc::FilterOperation::CreateBlurFilter(0.8f)); |
| render_pass_filters_[render_pass_id_] = &filters_; |
| quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, |
| kOverlayRect, render_pass_id_, kInvalidResourceId, gfx::RectF(), |
| gfx::Size(), gfx::Vector2dF(1, 2), gfx::PointF(), gfx::RectF(), |
| false, 1.0f); |
| ProcessForOverlays(); |
| EXPECT_EQ(1U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list_)); |
| } |
| |
| TEST_F(CALayerOverlayRPDQTest, RenderPassDrawQuadDropShadowFilterScale) { |
| filters_.Append(cc::FilterOperation::CreateDropShadowFilter( |
| gfx::Point(10, 20), 1.0f, SkColors::kGreen)); |
| render_pass_filters_[render_pass_id_] = &filters_; |
| quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, |
| kOverlayRect, render_pass_id_, kInvalidResourceId, gfx::RectF(), |
| gfx::Size(), gfx::Vector2dF(1, 2), gfx::PointF(), gfx::RectF(), |
| false, 1.0f); |
| ProcessForOverlays(); |
| EXPECT_EQ(1U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list_)); |
| } |
| |
| TEST_F(CALayerOverlayRPDQTest, RenderPassDrawQuadBackgroundFilter) { |
| backdrop_filters_.Append(cc::FilterOperation::CreateGrayscaleFilter(0.1f)); |
| render_pass_backdrop_filters_[render_pass_id_] = &backdrop_filters_; |
| quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, |
| kOverlayRect, render_pass_id_, kInvalidResourceId, gfx::RectF(), |
| gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), |
| false, 1.0f); |
| ProcessForOverlays(); |
| EXPECT_EQ(0U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list_)); |
| } |
| |
| TEST_F(CALayerOverlayRPDQTest, RenderPassDrawQuadMask) { |
| quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, |
| kOverlayRect, render_pass_id_, ResourceId(2), gfx::RectF(), |
| gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), |
| false, 1.0f); |
| ProcessForOverlays(); |
| EXPECT_EQ(1U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list_)); |
| } |
| |
| TEST_F(CALayerOverlayRPDQTest, RenderPassDrawQuadUnsupportedFilter) { |
| filters_.Append(cc::FilterOperation::CreateZoomFilter(0.9f, 1)); |
| render_pass_filters_[render_pass_id_] = &filters_; |
| quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, |
| kOverlayRect, render_pass_id_, kInvalidResourceId, gfx::RectF(), |
| gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), |
| false, 1.0f); |
| ProcessForOverlays(); |
| EXPECT_EQ(0U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list_)); |
| } |
| |
| TEST_F(CALayerOverlayRPDQTest, TooManyRenderPassDrawQuads) { |
| filters_.Append(cc::FilterOperation::CreateBlurFilter(0.8f)); |
| int count = 35; |
| quad_->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, |
| kOverlayRect, render_pass_id_, ResourceId(2), gfx::RectF(), |
| gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), |
| false, 1.0f); |
| for (int i = 1; i < count; ++i) { |
| auto* quad = pass_->CreateAndAppendDrawQuad<AggregatedRenderPassDrawQuad>(); |
| quad->SetNew(pass_->shared_quad_state_list.back(), kOverlayRect, |
| kOverlayRect, render_pass_id_, ResourceId(2), gfx::RectF(), |
| gfx::Size(), gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), |
| false, 1.0f); |
| } |
| |
| ProcessForOverlays(); |
| EXPECT_EQ(0U, test::NumOverlaysExcludingPrimaryPlane(ca_layer_list_)); |
| } |
| |
| } // namespace |
| } // namespace viz |