diff options
author | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-08 14:30:41 +0200 |
---|---|---|
committer | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-12 13:49:54 +0200 |
commit | ab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch) | |
tree | 498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/cc/output/overlay_unittest.cc | |
parent | 4ce69f7403811819800e7c5ae1318b2647e778d1 (diff) |
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca
Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/cc/output/overlay_unittest.cc')
-rw-r--r-- | chromium/cc/output/overlay_unittest.cc | 727 |
1 files changed, 727 insertions, 0 deletions
diff --git a/chromium/cc/output/overlay_unittest.cc b/chromium/cc/output/overlay_unittest.cc new file mode 100644 index 00000000000..932ad7a2bcd --- /dev/null +++ b/chromium/cc/output/overlay_unittest.cc @@ -0,0 +1,727 @@ +// 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/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/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::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); + + 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<SingleReleaseCallback> release_callback = + SingleReleaseCallback::Create(base::Bind(&MailboxReleased)); + + return resource_provider->CreateResourceFromTextureMailbox( + mailbox, release_callback.Pass()); +} + +scoped_ptr<TextureDrawQuad> CreateCandidateQuad( + ResourceProvider* resource_provider, + const SharedQuadState* shared_quad_state) { + ResourceProvider::ResourceId resource_id = CreateResource(resource_provider); + 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->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<SharedBitmapManager> shared_bitmap_manager( + new TestSharedBitmapManager()); + scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( + &output_surface, shared_bitmap_manager.get(), 0, false, 1, false)); + + 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); + + shared_bitmap_manager_.reset(new TestSharedBitmapManager()); + resource_provider_ = ResourceProvider::Create( + output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, + false); + + 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(); + 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. + 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_quad->resource_id, candidate_list.back().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); + + 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(); + 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); + + 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(); + 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()); + + 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(); + 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()); + 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(); + 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()); + 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(); + 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()); + 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(); + 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()); + 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(); + 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()); + 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, 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()); + OverlayCandidateList candidate_list; + overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list); + ASSERT_EQ(1U, pass_list.size()); + EXPECT_EQ(0U, candidate_list.size()); +} + +class OverlayInfoRendererGL : public GLRenderer { + public: + OverlayInfoRendererGL(RendererClient* client, + const LayerTreeSettings* settings, + OutputSurface* output_surface, + ResourceProvider* resource_provider) + : GLRenderer(client, + settings, + output_surface, + resource_provider, + NULL, + 0), + expect_overlays_(false) {} + + MOCK_METHOD2(DoDrawQuad, void(DrawingFrame* frame, const DrawQuad* quad)); + + virtual 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. + virtual void SetFullRootLayerDamage() OVERRIDE {} + virtual void RunOnDemandRasterTask(Task* on_demand_raster_task) 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, 0, false, 1, + false); + + 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()); } + + LayerTreeSettings 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(); + + pass->quad_list.push_back( + CreateCandidateQuad(resource_provider_.get(), + pass->shared_quad_state_list.back()) + .PassAs<DrawQuad>()); + + 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()); + + // 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(); + + 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()); + + // 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(); + + pass->quad_list.push_back( + CreateCandidateQuad(resource_provider_.get(), + pass->shared_quad_state_list.back()) + .PassAs<DrawQuad>()); + + 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()); + + // 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()); + + DirectRenderer::DrawingFrame frame1; + frame1.overlay_list.resize(2); + OverlayCandidate& overlay1 = frame1.overlay_list.back(); + overlay1.resource_id = resource1; + overlay1.plane_z_order = 1; + + DirectRenderer::DrawingFrame frame2; + 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_->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_->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_->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; + renderer_->set_expect_overlays(false); + 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_->FinishDrawingFrame(&frame1); + EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1)); + SwapBuffers(); + Mock::VerifyAndClearExpectations(&scheduler_); + + EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1); + 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_->FinishDrawingFrame(&frame3); + EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1)); + SwapBuffers(); + EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1)); + Mock::VerifyAndClearExpectations(&scheduler_); +} + +} // namespace +} // namespace cc |