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

Unified Diff: cc/output/overlay_unittest.cc

Issue 197223003: Start of hardware overlay support in CC with Ubercompositor. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months 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/quads/render_pass.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..ab22cb485508442ad778d6188befc7fb53f5d2ef
--- /dev/null
+++ b/cc/output/overlay_unittest.cc
@@ -0,0 +1,426 @@
+// 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/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/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 "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+const gfx::Rect kOverlayRect(0, 0, 128, 128);
+const gfx::PointF kUVTopLeft(0.1f, 0.2f);
+const gfx::PointF kUVBottomRight(1.0f, 1.0f);
+
+void MailboxReleased(unsigned sync_point, bool lost_resource) {}
+
+class SingleOverlayValidator : public OverlayCandidateValidator {
+ public:
+ virtual void CheckOverlaySupport(OverlayCandidateList* surfaces) OVERRIDE;
+};
+
+void SingleOverlayValidator::CheckOverlaySupport(
+ OverlayCandidateList* surfaces) {
+ ASSERT_EQ(2U, surfaces->size());
+
+ OverlayCandidate& candidate = surfaces->back();
+ EXPECT_EQ(kOverlayRect.ToString(), candidate.display_rect.ToString());
+ 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.
+ virtual 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) {}
+
+ void InitWithSingleOverlayValidator() {
+ overlay_candidate_validator_.reset(new SingleOverlayValidator);
+ }
+};
+
+scoped_ptr<RenderPass> CreateRenderPass() {
+ RenderPass::Id 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,
+ RenderPass::NO_OVERLAY);
+
+ scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create();
+ shared_state->opacity = 1.f;
+ pass->shared_quad_state_list.push_back(shared_state.Pass());
+ return pass.Pass();
+}
+
+scoped_ptr<TextureDrawQuad> CreateCandidateQuad(
+ ResourceProvider* resource_provider,
+ const SharedQuadState* shared_quad_state) {
+ unsigned sync_point = 0;
+ TextureMailbox mailbox =
+ TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
+ mailbox.set_allow_overlay(true);
+ scoped_ptr<SingleReleaseCallback> release_callback =
+ SingleReleaseCallback::Create(base::Bind(&MailboxReleased));
+
+ ResourceProvider::ResourceId resource_id =
+ resource_provider->CreateResourceFromTextureMailbox(
+ mailbox, release_callback.Pass());
+ bool premultiplied_alpha = false;
+ bool flipped = false;
+ float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+
+ scoped_ptr<TextureDrawQuad> overlay_quad = TextureDrawQuad::Create();
+ overlay_quad->SetNew(shared_quad_state,
+ kOverlayRect,
+ kOverlayRect,
+ kOverlayRect,
+ resource_id,
+ premultiplied_alpha,
+ kUVTopLeft,
+ kUVBottomRight,
+ SK_ColorTRANSPARENT,
+ vertex_opacity,
+ flipped);
+
+ return overlay_quad.Pass();
+}
+
+scoped_ptr<DrawQuad> CreateCheckeredQuad(
+ ResourceProvider* resource_provider,
+ const SharedQuadState* shared_quad_state) {
+ scoped_ptr<CheckerboardDrawQuad> checkerboard_quad =
+ CheckerboardDrawQuad::Create();
+ checkerboard_quad->SetNew(
+ shared_quad_state, kOverlayRect, kOverlayRect, SkColor());
+ return checkerboard_quad.PassAs<DrawQuad>();
+}
+
+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_RECT_EQ(expected->output_rect, actual->output_rect);
+ EXPECT_EQ(expected->transform_to_root_target,
+ actual->transform_to_root_target);
+ EXPECT_RECT_EQ(expected->damage_rect, actual->damage_rect);
+ EXPECT_EQ(expected->has_transparent_background,
+ actual->has_transparent_background);
+ EXPECT_EQ(expected->overlay_state, actual->overlay_state);
+
+ 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 (size_t i = 0; i < expected->quad_list.size(); ++i) {
+ EXPECT_EQ(expected->quad_list[i]->rect.ToString(),
+ actual->quad_list[i]->rect.ToString());
+ EXPECT_EQ(
+ expected->quad_list[i]->shared_quad_state->content_bounds.ToString(),
+ actual->quad_list[i]->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<ResourceProvider> resource_provider(
+ ResourceProvider::Create(&output_surface, 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:
+ virtual void SetUp() {
+ 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);
+
+ resource_provider_ =
+ ResourceProvider::Create(output_surface_.get(), 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<ResourceProvider> resource_provider_;
+ scoped_ptr<SingleOverlayProcessor> overlay_processor_;
+};
+
+TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ scoped_ptr<TextureDrawQuad> original_quad = CreateCandidateQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back());
+
+ pass->quad_list.push_back(
+ original_quad->Copy(pass->shared_quad_state_list.back()));
+ // Add something behind it.
+ pass->quad_list.push_back(CreateCheckeredQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back()));
+ pass->quad_list.push_back(CreateCheckeredQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back()));
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ // Check for potential candidates.
+ overlay_processor_->ProcessForOverlays(&pass_list);
+
+ // This should have one more pass with an overlay.
+ ASSERT_EQ(2U, pass_list.size());
+
+ RenderPass* overlay_pass = pass_list.front();
+ EXPECT_EQ(RenderPass::SIMPLE_OVERLAY, overlay_pass->overlay_state);
+ RenderPass* main_pass = pass_list.back();
+ EXPECT_EQ(RenderPass::NO_OVERLAY, main_pass->overlay_state);
+
+ // Check that the quad is what we expect it to be.
+ EXPECT_EQ(1U, overlay_pass->quad_list.size());
+ const DrawQuad* overlay_quad = overlay_pass->quad_list.front();
+ EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, overlay_quad->material);
+ EXPECT_EQ(original_quad->resource_id,
+ TextureDrawQuad::MaterialCast(overlay_quad)->resource_id);
+}
+
+TEST_F(SingleOverlayOnTopTest, NoCandidates) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ pass->quad_list.push_back(CreateCheckeredQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back()));
+ pass->quad_list.push_back(CreateCheckeredQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back()));
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ RenderPassList original_pass_list;
+ RenderPass::CopyAll(pass_list, &original_pass_list);
+
+ overlay_processor_->ProcessForOverlays(&pass_list);
+ // There should be nothing new here.
+ CompareRenderPassLists(pass_list, original_pass_list);
+}
+
+TEST_F(SingleOverlayOnTopTest, OccludedCandidates) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ pass->quad_list.push_back(CreateCheckeredQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back()));
+ pass->quad_list.push_back(CreateCheckeredQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back()));
+
+ pass->quad_list.push_back(
+ CreateCandidateQuad(resource_provider_.get(),
+ pass->shared_quad_state_list.back())
+ .PassAs<DrawQuad>());
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ RenderPassList original_pass_list;
+ RenderPass::CopyAll(pass_list, &original_pass_list);
+
+ overlay_processor_->ProcessForOverlays(&pass_list);
+ // 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();
+ scoped_ptr<TextureDrawQuad> original_quad = CreateCandidateQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back());
+
+ pass->quad_list.push_back(
+ original_quad->Copy(pass->shared_quad_state_list.back()));
+ // Add something behind it.
+ pass->quad_list.push_back(CreateCheckeredQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back()));
+ pass->quad_list.push_back(CreateCheckeredQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back()));
+
+ pass_list.push_back(pass.Pass());
+
+ // Check for potential candidates.
+ overlay_processor_->ProcessForOverlays(&pass_list);
+
+ // This should have one more pass with an overlay.
+ ASSERT_EQ(3U, pass_list.size());
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back());
+ quad->premultiplied_alpha = true;
+
+ pass->quad_list.push_back(quad.PassAs<DrawQuad>());
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ overlay_processor_->ProcessForOverlays(&pass_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectBlending) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back());
+ quad->needs_blending = true;
+
+ pass->quad_list.push_back(quad.PassAs<DrawQuad>());
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ overlay_processor_->ProcessForOverlays(&pass_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back());
+ quad->background_color = SK_ColorBLACK;
+
+ pass->quad_list.push_back(quad.PassAs<DrawQuad>());
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ overlay_processor_->ProcessForOverlays(&pass_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectBlendMode) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back());
+ pass->shared_quad_state_list.back()->blend_mode = SkXfermode::kScreen_Mode;
+
+ pass->quad_list.push_back(quad.PassAs<DrawQuad>());
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ overlay_processor_->ProcessForOverlays(&pass_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectOpacity) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back());
+ pass->shared_quad_state_list.back()->opacity = 0.5f;
+
+ pass->quad_list.push_back(quad.PassAs<DrawQuad>());
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ overlay_processor_->ProcessForOverlays(&pass_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
+}
+
+TEST_F(SingleOverlayOnTopTest, RejectTransform) {
+ scoped_ptr<RenderPass> pass = CreateRenderPass();
+ scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad(
+ resource_provider_.get(), pass->shared_quad_state_list.back());
+ pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.f,
+ 2.f);
+
+ pass->quad_list.push_back(quad.PassAs<DrawQuad>());
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+ overlay_processor_->ProcessForOverlays(&pass_list);
+ ASSERT_EQ(1U, pass_list.size());
+ EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
+}
+
+} // namespace
+} // namespace cc
« no previous file with comments | « cc/output/overlay_strategy_single_on_top.cc ('k') | cc/quads/render_pass.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698