Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1392)

Unified Diff: cc/output/overlay_unittest.cc

Issue 1531403002: Revert "Delete CC." (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/output/overlay_strategy_single_on_top.cc ('k') | cc/output/program_binding.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/output/overlay_unittest.cc
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..75fbb6ebaf1059ce8a71cf32b2434e9cf2f50d3e
--- /dev/null
+++ b/cc/output/overlay_unittest.cc
@@ -0,0 +1,1058 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/base/scoped_ptr_vector.h"
+#include "cc/output/compositor_frame_metadata.h"
+#include "cc/output/gl_renderer.h"
+#include "cc/output/output_surface.h"
+#include "cc/output/output_surface_client.h"
+#include "cc/output/overlay_candidate_validator.h"
+#include "cc/output/overlay_processor.h"
+#include "cc/output/overlay_strategy_single_on_top.h"
+#include "cc/quads/checkerboard_draw_quad.h"
+#include "cc/quads/render_pass.h"
+#include "cc/quads/stream_video_draw_quad.h"
+#include "cc/quads/texture_draw_quad.h"
+#include "cc/resources/resource_provider.h"
+#include "cc/resources/texture_mailbox.h"
+#include "cc/test/fake_output_surface_client.h"
+#include "cc/test/geometry_test_utils.h"
+#include "cc/test/test_context_provider.h"
+#include "cc/test/test_shared_bitmap_manager.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::Mock;
+
+namespace cc {
+namespace {
+
+const gfx::Rect kOverlayRect(0, 0, 128, 128);
+const gfx::Rect kOverlayTopLeftRect(0, 0, 64, 64);
+const gfx::Rect kOverlayBottomRightRect(64, 64, 64, 64);
+const gfx::PointF kUVTopLeft(0.1f, 0.2f);
+const gfx::PointF kUVBottomRight(1.0f, 1.0f);
+const gfx::Transform kNormalTransform =
+ gfx::Transform(0.9f, 0, 0, 0.8f, 0.1f, 0.2f); // x,y -> x,y.
+const gfx::Transform kXMirrorTransform =
+ gfx::Transform(-0.9f, 0, 0, 0.8f, 1.0f, 0.2f); // x,y -> 1-x,y.
+const gfx::Transform kYMirrorTransform =
+ gfx::Transform(0.9f, 0, 0, -0.8f, 0.1f, 1.0f); // x,y -> x,1-y.
+const gfx::Transform kBothMirrorTransform =
+ gfx::Transform(-0.9f, 0, 0, -0.8f, 1.0f, 1.0f); // x,y -> 1-x,1-y.
+const gfx::Transform kSwapTransform =
+ gfx::Transform(0, 1, 1, 0, 0, 0); // x,y -> y,x.
+
+void MailboxReleased(unsigned sync_point,
+ bool lost_resource,
+ BlockingTaskRunner* main_thread_task_runner) {
+}
+
+class SingleOverlayValidator : public OverlayCandidateValidator {
+ public:
+ void CheckOverlaySupport(OverlayCandidateList* surfaces) override;
+};
+
+void SingleOverlayValidator::CheckOverlaySupport(
+ OverlayCandidateList* surfaces) {
+ ASSERT_EQ(2U, surfaces->size());
+
+ OverlayCandidate& candidate = surfaces->back();
+ if (candidate.display_rect.width() == 64)
+ EXPECT_EQ(kOverlayBottomRightRect, candidate.display_rect);
+ else
+ EXPECT_EQ(kOverlayRect, candidate.display_rect);
+ EXPECT_EQ(BoundingRect(kUVTopLeft, kUVBottomRight).ToString(),
+ candidate.uv_rect.ToString());
+ candidate.overlay_handled = true;
+}
+
+class SingleOverlayProcessor : public OverlayProcessor {
+ public:
+ SingleOverlayProcessor(OutputSurface* surface,
+ ResourceProvider* resource_provider);
+ // Virtual to allow testing different strategies.
+ void Initialize() override;
+};
+
+SingleOverlayProcessor::SingleOverlayProcessor(
+ OutputSurface* surface,
+ ResourceProvider* resource_provider)
+ : OverlayProcessor(surface, resource_provider) {
+ EXPECT_EQ(surface, surface_);
+ EXPECT_EQ(resource_provider, resource_provider_);
+}
+
+void SingleOverlayProcessor::Initialize() {
+ OverlayCandidateValidator* candidates =
+ surface_->overlay_candidate_validator();
+ ASSERT_TRUE(candidates != NULL);
+ strategies_.push_back(scoped_ptr<Strategy>(
+ new OverlayStrategySingleOnTop(candidates, resource_provider_)));
+}
+
+class DefaultOverlayProcessor : public OverlayProcessor {
+ public:
+ DefaultOverlayProcessor(OutputSurface* surface,
+ ResourceProvider* resource_provider);
+ size_t GetStrategyCount();
+};
+
+DefaultOverlayProcessor::DefaultOverlayProcessor(
+ OutputSurface* surface,
+ ResourceProvider* resource_provider)
+ : OverlayProcessor(surface, resource_provider) {}
+
+size_t DefaultOverlayProcessor::GetStrategyCount() {
+ return strategies_.size();
+}
+
+class OverlayOutputSurface : public OutputSurface {
+ public:
+ explicit OverlayOutputSurface(scoped_refptr<ContextProvider> context_provider)
+ : OutputSurface(context_provider) {}
+
+ // OutputSurface implementation
+ void SwapBuffers(CompositorFrame* frame) override;
+
+ void InitWithSingleOverlayValidator() {
+ overlay_candidate_validator_.reset(new SingleOverlayValidator);
+ }
+};
+
+void OverlayOutputSurface::SwapBuffers(CompositorFrame* frame) {
+ client_->DidSwapBuffers();
+ client_->DidSwapBuffersComplete();
+}
+
+scoped_ptr<RenderPass> CreateRenderPass() {
+ RenderPassId id(1, 0);
+ gfx::Rect output_rect(0, 0, 256, 256);
+ bool has_transparent_background = true;
+
+ scoped_ptr<RenderPass> pass = RenderPass::Create();
+ pass->SetAll(id,
+ output_rect,
+ output_rect,
+ gfx::Transform(),
+ has_transparent_background);
+
+ SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
+ shared_state->opacity = 1.f;
+ return pass.Pass();
+}
+
+ResourceProvider::ResourceId CreateResource(
+ ResourceProvider* resource_provider) {
+ unsigned sync_point = 0;
+ TextureMailbox mailbox =
+ TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
+ mailbox.set_allow_overlay(true);
+ scoped_ptr<SingleReleaseCallbackImpl> release_callback =
+ SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
+
+ return resource_provider->CreateResourceFromTextureMailbox(
+ mailbox, release_callback.Pass());
+}
+
+SolidColorDrawQuad* CreateSolidColorQuadAt(
+ const SharedQuadState* shared_quad_state,
+ SkColor color,
+ RenderPass* render_pass,
+ const gfx::Rect& rect) {
+ SolidColorDrawQuad* quad =
+ render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
+ quad->SetNew(shared_quad_state, rect, rect, color, false);
+ return quad;
+}
+
+TextureDrawQuad* CreateCandidateQuadAt(ResourceProvider* resource_provider,
+ const SharedQuadState* shared_quad_state,
+ RenderPass* render_pass,
+ const gfx::Rect& rect) {
+ ResourceProvider::ResourceId resource_id = CreateResource(resource_provider);
+ bool premultiplied_alpha = false;
+ bool flipped = false;
+ bool nearest_neighbor = false;
+ float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+
+ TextureDrawQuad* overlay_quad =
+ render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
+ overlay_quad->SetNew(shared_quad_state,
+ rect,
+ rect,
+ rect,
+ resource_id,
+ premultiplied_alpha,
+ kUVTopLeft,
+ kUVBottomRight,
+ SK_ColorTRANSPARENT,
+ vertex_opacity,
+ flipped,
+ nearest_neighbor);
+
+ return overlay_quad;
+}
+
+StreamVideoDrawQuad* CreateCandidateVideoQuadAt(
+ ResourceProvider* resource_provider,
+ const SharedQuadState* shared_quad_state,
+ RenderPass* render_pass,
+ const gfx::Rect& rect,
+ const gfx::Transform& transform) {
+ ResourceProvider::ResourceId resource_id = CreateResource(resource_provider);
+
+ StreamVideoDrawQuad* overlay_quad =
+ render_pass->CreateAndAppendDrawQuad<StreamVideoDrawQuad>();
+ overlay_quad->SetNew(shared_quad_state, rect, rect, rect, resource_id,
+ transform);
+
+ return overlay_quad;
+}
+
+TextureDrawQuad* CreateFullscreenCandidateQuad(
+ ResourceProvider* resource_provider,
+ const SharedQuadState* shared_quad_state,
+ RenderPass* render_pass) {
+ return CreateCandidateQuadAt(
+ resource_provider, shared_quad_state, render_pass, kOverlayRect);
+}
+
+StreamVideoDrawQuad* CreateFullscreenCandidateVideoQuad(
+ ResourceProvider* resource_provider,
+ const SharedQuadState* shared_quad_state,
+ RenderPass* render_pass,
+ const gfx::Transform& transform) {
+ return CreateCandidateVideoQuadAt(resource_provider, shared_quad_state,
+ render_pass, kOverlayRect, transform);
+}
+
+void CreateCheckeredQuadAt(ResourceProvider* resource_provider,
+ const SharedQuadState* shared_quad_state,
+ RenderPass* render_pass,
+ const gfx::Rect& rect) {
+ CheckerboardDrawQuad* checkerboard_quad =
+ render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
+ checkerboard_quad->SetNew(shared_quad_state, rect, rect, SkColor(), 1.f);
+}
+
+void CreateFullscreenCheckeredQuad(ResourceProvider* resource_provider,
+ const SharedQuadState* shared_quad_state,
+ RenderPass* render_pass) {
+ CreateCheckeredQuadAt(
+ resource_provider, shared_quad_state, render_pass, kOverlayRect);
+}
+
+static void CompareRenderPassLists(const RenderPassList& expected_list,
+ const RenderPassList& actual_list) {
+ EXPECT_EQ(expected_list.size(), actual_list.size());
+ for (size_t i = 0; i < actual_list.size(); ++i) {
+ RenderPass* expected = expected_list[i];
+ RenderPass* actual = actual_list[i];
+
+ EXPECT_EQ(expected->id, actual->id);
+ EXPECT_EQ(expected->output_rect, actual->output_rect);
+ EXPECT_EQ(expected->transform_to_root_target,
+ actual->transform_to_root_target);
+ EXPECT_EQ(expected->damage_rect, actual->damage_rect);
+ EXPECT_EQ(expected->has_transparent_background,
+ actual->has_transparent_background);
+
+ EXPECT_EQ(expected->shared_quad_state_list.size(),
+ actual->shared_quad_state_list.size());
+ EXPECT_EQ(expected->quad_list.size(), actual->quad_list.size());
+
+ for (auto exp_iter = expected->quad_list.cbegin(),
+ act_iter = actual->quad_list.cbegin();
+ exp_iter != expected->quad_list.cend();
+ ++exp_iter, ++act_iter) {
+ EXPECT_EQ(exp_iter->rect.ToString(), act_iter->rect.ToString());
+ EXPECT_EQ(exp_iter->shared_quad_state->content_bounds.ToString(),
+ act_iter->shared_quad_state->content_bounds.ToString());
+ }
+ }
+}
+
+TEST(OverlayTest, NoOverlaysByDefault) {
+ scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
+ OverlayOutputSurface output_surface(provider);
+ EXPECT_EQ(NULL, output_surface.overlay_candidate_validator());
+
+ output_surface.InitWithSingleOverlayValidator();
+ EXPECT_TRUE(output_surface.overlay_candidate_validator() != NULL);
+}
+
+TEST(OverlayTest, OverlaysProcessorHasStrategy) {
+ scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
+ OverlayOutputSurface output_surface(provider);
+ FakeOutputSurfaceClient client;
+ EXPECT_TRUE(output_surface.BindToClient(&client));
+ output_surface.InitWithSingleOverlayValidator();
+ EXPECT_TRUE(output_surface.overlay_candidate_validator() != NULL);
+
+ scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
+ new TestSharedBitmapManager());
+ scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
+ &output_surface, shared_bitmap_manager.get(), NULL, NULL, 0, false, 1));
+
+ scoped_ptr<DefaultOverlayProcessor> overlay_processor(
+ new DefaultOverlayProcessor(&output_surface, resource_provider.get()));
+ overlay_processor->Initialize();
+ EXPECT_GE(1U, overlay_processor->GetStrategyCount());
+}
+
+class SingleOverlayOnTopTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ provider_ = TestContextProvider::Create();
+ output_surface_.reset(new OverlayOutputSurface(provider_));
+ EXPECT_TRUE(output_surface_->BindToClient(&client_));
+ output_surface_->InitWithSingleOverlayValidator();
+ EXPECT_TRUE(output_surface_->overlay_candidate_validator() != NULL);
+
+ shared_bitmap_manager_.reset(new TestSharedBitmapManager());
+ resource_provider_ = ResourceProvider::Create(output_surface_.get(),
+ shared_bitmap_manager_.get(),
+ NULL,
+ NULL,
+ 0,
+ false,
+ 1);
+
+ overlay_processor_.reset(new SingleOverlayProcessor(
+ output_surface_.get(), resource_provider_.get()));
+ overlay_processor_->Initialize();
+ }
+
+ scoped_refptr<TestContextProvider> provider_;
+ scoped_ptr<OverlayOutputSurface> output_surface_;
+ FakeOutputSurfaceClient client_;
+ scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
+ scoped_ptr<ResourceProvider> resource_provider_;
+ scoped_ptr<SingleOverlayProcessor> overlay_processor_;
+};
+
+TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ TextureDrawQuad* original_quad =
+ CreateFullscreenCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ unsigned original_resource_id = original_quad->resource_id;
+
+ // Add something behind it.
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ // Check for potential candidates.
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+
+ ASSERT_EQ(1U, pass_list.size());
+ ASSERT_EQ(2U, candidate_list.size());
+
+ RenderPass* main_pass = pass_list.back();
+ // Check that the quad is gone.
+ EXPECT_EQ(2U, main_pass->quad_list.size());
+ const QuadList& quad_list = main_pass->quad_list;
+ for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin();
+ it != quad_list.BackToFrontEnd();
+ ++it) {
+ EXPECT_NE(DrawQuad::TEXTURE_CONTENT, it->material);
+ }
+
+ // Check that the right resource id got extracted.
+ EXPECT_EQ(original_resource_id, candidate_list.back().resource_id);
+}
+
+TEST_F(SingleOverlayOnTopTest, NoCandidates) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ RenderPassList original_pass_list;
+ RenderPass::CopyAll(pass_list, &original_pass_list);
+
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(0U, candidate_list.size());
+ // There should be nothing new here.
+ CompareRenderPassLists(pass_list, original_pass_list);
+}
+
+TEST_F(SingleOverlayOnTopTest, OccludedCandidates) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+
+ CreateFullscreenCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ RenderPassList original_pass_list;
+ RenderPass::CopyAll(pass_list, &original_pass_list);
+
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(0U, candidate_list.size());
+ // There should be nothing new here.
+ CompareRenderPassLists(pass_list, original_pass_list);
+}
+
+// Test with multiple render passes.
+TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) {
+ RenderPassList pass_list;
+ pass_list.push_back(CreateRenderPass());
+
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateFullscreenCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+
+ // Add something behind it.
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+
+ pass_list.push_back(pass.Pass());
+
+ RenderPassList original_pass_list;
+ RenderPass::CopyAll(pass_list, &original_pass_list);
+
+ // Check for potential candidates.
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(2U, candidate_list.size());
+
+ // This should be the same.
+ ASSERT_EQ(2U, pass_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ TextureDrawQuad* quad =
+ CreateFullscreenCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ quad->premultiplied_alpha = true;
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(1U, pass_list.size());
+ EXPECT_EQ(0U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectBlending) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ TextureDrawQuad* quad =
+ CreateFullscreenCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ quad->needs_blending = true;
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(0U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ TextureDrawQuad* quad =
+ CreateFullscreenCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ quad->background_color = SK_ColorBLACK;
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(0U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectBlendMode) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateFullscreenCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ pass->shared_quad_state_list.back()->blend_mode = SkXfermode::kScreen_Mode;
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(0U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectOpacity) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateFullscreenCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ pass->shared_quad_state_list.back()->opacity = 0.5f;
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(0U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectNonScaleTransform) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateFullscreenCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ pass->shared_quad_state_list.back()
+ ->content_to_target_transform.RotateAboutXAxis(45.f);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(0U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectNegativeScaleTransform) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateFullscreenCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f,
+ -1.0f);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(0U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, AllowPositiveScaleTransform) {
+ gfx::Rect rect = kOverlayRect;
+ rect.set_width(rect.width() / 2);
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateCandidateQuadAt(resource_provider_.get(),
+ pass->shared_quad_state_list.back(), pass.get(), rect);
+ pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f,
+ 1.0f);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(2U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, AllowNotTopIfNotOccluded) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateCheckeredQuadAt(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get(),
+ kOverlayTopLeftRect);
+ CreateCandidateQuadAt(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get(),
+ kOverlayBottomRightRect);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ RenderPassList original_pass_list;
+ RenderPass::CopyAll(pass_list, &original_pass_list);
+
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(1U, pass_list.size());
+ EXPECT_EQ(2U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, AllowTransparentOnTop) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
+ shared_state->opacity = 0.f;
+ CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(),
+ kOverlayBottomRightRect);
+ shared_state = pass->CreateAndAppendSharedQuadState();
+ shared_state->opacity = 1.f;
+ CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
+ kOverlayBottomRightRect);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ RenderPassList original_pass_list;
+ RenderPass::CopyAll(pass_list, &original_pass_list);
+
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(1U, pass_list.size());
+ EXPECT_EQ(2U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, AllowTransparentColorOnTop) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateSolidColorQuadAt(pass->shared_quad_state_list.back(),
+ SK_ColorTRANSPARENT, pass.get(),
+ kOverlayBottomRightRect);
+ CreateCandidateQuadAt(resource_provider_.get(),
+ pass->shared_quad_state_list.back(), pass.get(),
+ kOverlayBottomRightRect);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ RenderPassList original_pass_list;
+ RenderPass::CopyAll(pass_list, &original_pass_list);
+
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(1U, pass_list.size());
+ EXPECT_EQ(2U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectOpaqueColorOnTop) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
+ shared_state->opacity = 0.5f;
+ CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(),
+ kOverlayBottomRightRect);
+ shared_state = pass->CreateAndAppendSharedQuadState();
+ shared_state->opacity = 1.f;
+ CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
+ kOverlayBottomRightRect);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ RenderPassList original_pass_list;
+ RenderPass::CopyAll(pass_list, &original_pass_list);
+
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(1U, pass_list.size());
+ EXPECT_EQ(0U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectTransparentColorOnTopWithoutBlending) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
+ CreateSolidColorQuadAt(shared_state, SK_ColorTRANSPARENT, pass.get(),
+ kOverlayBottomRightRect)->opaque_rect =
+ kOverlayBottomRightRect;
+ CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
+ kOverlayBottomRightRect);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ RenderPassList original_pass_list;
+ RenderPass::CopyAll(pass_list, &original_pass_list);
+
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ EXPECT_EQ(1U, pass_list.size());
+ EXPECT_EQ(0U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectVideoSwapTransform) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get(), kSwapTransform);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(0U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, AllowVideoXMirrorTransform) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get(), kXMirrorTransform);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(2U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, AllowVideoBothMirrorTransform) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get(), kBothMirrorTransform);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(2U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, AllowVideoNormalTransform) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get(), kNormalTransform);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(2U, candidate_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, AllowVideoYMirrorTransform) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get(), kYMirrorTransform);
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ OverlayCandidateList candidate_list;
+ overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(2U, candidate_list.size());
+}
+
+class OverlayInfoRendererGL : public GLRenderer {
+ public:
+ OverlayInfoRendererGL(RendererClient* client,
+ const RendererSettings* settings,
+ OutputSurface* output_surface,
+ ResourceProvider* resource_provider)
+ : GLRenderer(client,
+ settings,
+ output_surface,
+ resource_provider,
+ NULL,
+ 0),
+ expect_overlays_(false) {}
+
+ MOCK_METHOD3(DoDrawQuad,
+ void(DrawingFrame* frame,
+ const DrawQuad* quad,
+ const gfx::QuadF* draw_region));
+
+ using GLRenderer::BeginDrawingFrame;
+
+ void FinishDrawingFrame(DrawingFrame* frame) override {
+ GLRenderer::FinishDrawingFrame(frame);
+
+ if (!expect_overlays_) {
+ EXPECT_EQ(0U, frame->overlay_list.size());
+ return;
+ }
+
+ ASSERT_EQ(2U, frame->overlay_list.size());
+ EXPECT_NE(0U, frame->overlay_list.back().resource_id);
+ }
+
+ void set_expect_overlays(bool expect_overlays) {
+ expect_overlays_ = expect_overlays;
+ }
+
+ private:
+ bool expect_overlays_;
+};
+
+class FakeRendererClient : public RendererClient {
+ public:
+ // RendererClient methods.
+ void SetFullRootLayerDamage() override {}
+};
+
+class MockOverlayScheduler {
+ public:
+ MOCK_METHOD5(Schedule,
+ void(int plane_z_order,
+ gfx::OverlayTransform plane_transform,
+ unsigned overlay_texture_id,
+ const gfx::Rect& display_bounds,
+ const gfx::RectF& uv_rect));
+};
+
+class GLRendererWithOverlaysTest : public testing::Test {
+ protected:
+ GLRendererWithOverlaysTest() {
+ provider_ = TestContextProvider::Create();
+ output_surface_.reset(new OverlayOutputSurface(provider_));
+ CHECK(output_surface_->BindToClient(&output_surface_client_));
+ resource_provider_ = ResourceProvider::Create(
+ output_surface_.get(), NULL, NULL, NULL, 0, false, 1);
+
+ provider_->support()->SetScheduleOverlayPlaneCallback(base::Bind(
+ &MockOverlayScheduler::Schedule, base::Unretained(&scheduler_)));
+ }
+
+ void Init(bool use_validator) {
+ if (use_validator)
+ output_surface_->InitWithSingleOverlayValidator();
+
+ renderer_ =
+ make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_,
+ &settings_,
+ output_surface_.get(),
+ resource_provider_.get()));
+ }
+
+ void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
+
+ RendererSettings settings_;
+ FakeOutputSurfaceClient output_surface_client_;
+ scoped_ptr<OverlayOutputSurface> output_surface_;
+ FakeRendererClient renderer_client_;
+ scoped_ptr<ResourceProvider> resource_provider_;
+ scoped_ptr<OverlayInfoRendererGL> renderer_;
+ scoped_refptr<TestContextProvider> provider_;
+ MockOverlayScheduler scheduler_;
+};
+
+TEST_F(GLRendererWithOverlaysTest, OverlayQuadNotDrawn) {
+ bool use_validator = true;
+ Init(use_validator);
+ renderer_->set_expect_overlays(true);
+ gfx::Rect viewport_rect(16, 16);
+
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+
+ CreateFullscreenCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ // Candidate pass was taken out and extra skipped pass added,
+ // so only draw 2 quads.
+ EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(2);
+ EXPECT_CALL(scheduler_,
+ Schedule(1,
+ gfx::OVERLAY_TRANSFORM_NONE,
+ _,
+ kOverlayRect,
+ BoundingRect(kUVTopLeft, kUVBottomRight))).Times(1);
+ renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
+
+ SwapBuffers();
+
+ Mock::VerifyAndClearExpectations(renderer_.get());
+ Mock::VerifyAndClearExpectations(&scheduler_);
+}
+
+TEST_F(GLRendererWithOverlaysTest, OccludedQuadDrawn) {
+ bool use_validator = true;
+ Init(use_validator);
+ renderer_->set_expect_overlays(false);
+ gfx::Rect viewport_rect(16, 16);
+
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+
+ CreateFullscreenCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ // 3 quads in the pass, all should draw.
+ EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(3);
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
+ renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
+
+ SwapBuffers();
+
+ Mock::VerifyAndClearExpectations(renderer_.get());
+ Mock::VerifyAndClearExpectations(&scheduler_);
+}
+
+TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) {
+ bool use_validator = false;
+ Init(use_validator);
+ renderer_->set_expect_overlays(false);
+ gfx::Rect viewport_rect(16, 16);
+
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+
+ CreateFullscreenCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+ CreateFullscreenCheckeredQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back(),
+ pass.get());
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ // Should see no overlays.
+ EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(3);
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
+ renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
+
+ SwapBuffers();
+
+ Mock::VerifyAndClearExpectations(renderer_.get());
+ Mock::VerifyAndClearExpectations(&scheduler_);
+}
+
+TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturned) {
+ bool use_validator = true;
+ Init(use_validator);
+ renderer_->set_expect_overlays(true);
+
+ ResourceProvider::ResourceId resource1 =
+ CreateResource(resource_provider_.get());
+ ResourceProvider::ResourceId resource2 =
+ CreateResource(resource_provider_.get());
+
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ DirectRenderer::DrawingFrame frame1;
+ frame1.render_passes_in_draw_order = &pass_list;
+ frame1.overlay_list.resize(2);
+ OverlayCandidate& overlay1 = frame1.overlay_list.back();
+ overlay1.resource_id = resource1;
+ overlay1.plane_z_order = 1;
+
+ DirectRenderer::DrawingFrame frame2;
+ frame2.render_passes_in_draw_order = &pass_list;
+ frame2.overlay_list.resize(2);
+ OverlayCandidate& overlay2 = frame2.overlay_list.back();
+ overlay2.resource_id = resource2;
+ overlay2.plane_z_order = 1;
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
+ renderer_->BeginDrawingFrame(&frame1);
+ renderer_->FinishDrawingFrame(&frame1);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+ SwapBuffers();
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
+ renderer_->BeginDrawingFrame(&frame2);
+ renderer_->FinishDrawingFrame(&frame2);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
+ SwapBuffers();
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
+ renderer_->BeginDrawingFrame(&frame1);
+ renderer_->FinishDrawingFrame(&frame1);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
+ SwapBuffers();
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ // No overlays, release the resource.
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
+ DirectRenderer::DrawingFrame frame3;
+ frame3.render_passes_in_draw_order = &pass_list;
+ renderer_->set_expect_overlays(false);
+ renderer_->BeginDrawingFrame(&frame3);
+ renderer_->FinishDrawingFrame(&frame3);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
+ SwapBuffers();
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ // Use the same buffer twice.
+ renderer_->set_expect_overlays(true);
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
+ renderer_->BeginDrawingFrame(&frame1);
+ renderer_->FinishDrawingFrame(&frame1);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ SwapBuffers();
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
+ renderer_->BeginDrawingFrame(&frame1);
+ renderer_->FinishDrawingFrame(&frame1);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ SwapBuffers();
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+
+ EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
+ renderer_->set_expect_overlays(false);
+ renderer_->BeginDrawingFrame(&frame3);
+ renderer_->FinishDrawingFrame(&frame3);
+ EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
+ SwapBuffers();
+ EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
+ Mock::VerifyAndClearExpectations(&scheduler_);
+}
+
+} // namespace
+} // namespace cc
« no previous file with comments | « cc/output/overlay_strategy_single_on_top.cc ('k') | cc/output/program_binding.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698