Revert "Fix broken channel icon in chrome://help on CrOS" and try again
[chromium-blink-merge.git] / cc / output / overlay_unittest.cc
blob684349caf788f64b3a224c06589343aa7c9707f6
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/base/scoped_ptr_vector.h"
6 #include "cc/output/compositor_frame_metadata.h"
7 #include "cc/output/gl_renderer.h"
8 #include "cc/output/output_surface.h"
9 #include "cc/output/output_surface_client.h"
10 #include "cc/output/overlay_candidate_validator.h"
11 #include "cc/output/overlay_processor.h"
12 #include "cc/output/overlay_strategy_sandwich.h"
13 #include "cc/output/overlay_strategy_single_on_top.h"
14 #include "cc/output/overlay_strategy_underlay.h"
15 #include "cc/quads/render_pass.h"
16 #include "cc/quads/solid_color_draw_quad.h"
17 #include "cc/quads/stream_video_draw_quad.h"
18 #include "cc/quads/texture_draw_quad.h"
19 #include "cc/resources/resource_provider.h"
20 #include "cc/resources/texture_mailbox.h"
21 #include "cc/test/fake_output_surface_client.h"
22 #include "cc/test/fake_resource_provider.h"
23 #include "cc/test/geometry_test_utils.h"
24 #include "cc/test/test_context_provider.h"
25 #include "cc/test/test_shared_bitmap_manager.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
29 using testing::_;
30 using testing::Mock;
32 namespace cc {
33 namespace {
35 const gfx::Size kDisplaySize(256, 256);
36 const gfx::Rect kOverlayRect(0, 0, 128, 128);
37 const gfx::Rect kOverlayTopLeftRect(0, 0, 64, 64);
38 const gfx::Rect kOverlayBottomRightRect(64, 64, 64, 64);
39 const gfx::PointF kUVTopLeft(0.1f, 0.2f);
40 const gfx::PointF kUVBottomRight(1.0f, 1.0f);
41 const gfx::Transform kNormalTransform =
42 gfx::Transform(0.9f, 0, 0, 0.8f, 0.1f, 0.2f); // x,y -> x,y.
43 const gfx::Transform kXMirrorTransform =
44 gfx::Transform(-0.9f, 0, 0, 0.8f, 1.0f, 0.2f); // x,y -> 1-x,y.
45 const gfx::Transform kYMirrorTransform =
46 gfx::Transform(0.9f, 0, 0, -0.8f, 0.1f, 1.0f); // x,y -> x,1-y.
47 const gfx::Transform kBothMirrorTransform =
48 gfx::Transform(-0.9f, 0, 0, -0.8f, 1.0f, 1.0f); // x,y -> 1-x,1-y.
49 const gfx::Transform kSwapTransform =
50 gfx::Transform(0, 1, 1, 0, 0, 0); // x,y -> y,x.
52 void MailboxReleased(unsigned sync_point,
53 bool lost_resource,
54 BlockingTaskRunner* main_thread_task_runner) {
57 class SingleOverlayValidator : public OverlayCandidateValidator {
58 public:
59 void GetStrategies(OverlayProcessor::StrategyList* strategies) override {
60 strategies->push_back(scoped_ptr<OverlayProcessor::Strategy>(
61 new OverlayStrategyCommon(this, new OverlayStrategySingleOnTop)));
62 strategies->push_back(scoped_ptr<OverlayProcessor::Strategy>(
63 new OverlayStrategyCommon(this, new OverlayStrategyUnderlay)));
65 void CheckOverlaySupport(OverlayCandidateList* surfaces) override {
66 ASSERT_EQ(2U, surfaces->size());
68 OverlayCandidate& candidate = surfaces->back();
69 if (candidate.display_rect.width() == 64) {
70 EXPECT_EQ(kOverlayBottomRightRect, candidate.display_rect);
71 } else {
72 EXPECT_NEAR(kOverlayRect.x(), candidate.display_rect.x(), 0.01f);
73 EXPECT_NEAR(kOverlayRect.y(), candidate.display_rect.y(), 0.01f);
74 EXPECT_NEAR(kOverlayRect.width(), candidate.display_rect.width(), 0.01f);
75 EXPECT_NEAR(kOverlayRect.height(), candidate.display_rect.height(),
76 0.01f);
78 EXPECT_EQ(BoundingRect(kUVTopLeft, kUVBottomRight).ToString(),
79 candidate.uv_rect.ToString());
80 candidate.overlay_handled = true;
84 class SandwichOverlayValidator : public OverlayCandidateValidator {
85 public:
86 void GetStrategies(OverlayProcessor::StrategyList* strategies) override {
87 strategies->push_back(scoped_ptr<OverlayProcessor::Strategy>(
88 new OverlayStrategyCommon(this, new OverlayStrategySandwich)));
90 void CheckOverlaySupport(OverlayCandidateList* surfaces) override {
91 for (OverlayCandidate& candidate : *surfaces)
92 candidate.overlay_handled = true;
96 template <typename OverlayStrategyType>
97 class SingleOverlayProcessor : public OverlayProcessor {
98 public:
99 explicit SingleOverlayProcessor(OutputSurface* surface)
100 : OverlayProcessor(surface) {
101 EXPECT_EQ(surface, surface_);
104 // Virtual to allow testing different strategies.
105 void Initialize() override {
106 OverlayCandidateValidator* validator =
107 surface_->GetOverlayCandidateValidator();
108 ASSERT_TRUE(validator != NULL);
109 strategies_.push_back(scoped_ptr<Strategy>(
110 new OverlayStrategyCommon(validator, new OverlayStrategyType)));
114 class DefaultOverlayProcessor : public OverlayProcessor {
115 public:
116 explicit DefaultOverlayProcessor(OutputSurface* surface);
117 size_t GetStrategyCount();
120 DefaultOverlayProcessor::DefaultOverlayProcessor(OutputSurface* surface)
121 : OverlayProcessor(surface) {
124 size_t DefaultOverlayProcessor::GetStrategyCount() {
125 return strategies_.size();
128 class OverlayOutputSurface : public OutputSurface {
129 public:
130 explicit OverlayOutputSurface(scoped_refptr<ContextProvider> context_provider)
131 : OutputSurface(context_provider) {
132 surface_size_ = kDisplaySize;
133 device_scale_factor_ = 1;
136 void SetScaleFactor(float scale_factor) {
137 device_scale_factor_ = scale_factor;
140 // OutputSurface implementation
141 void SwapBuffers(CompositorFrame* frame) override;
143 void InitWithSingleOverlayValidator() {
144 overlay_candidate_validator_.reset(new SingleOverlayValidator);
146 void InitWithSandwichOverlayValidator() {
147 overlay_candidate_validator_.reset(new SandwichOverlayValidator);
150 OverlayCandidateValidator* GetOverlayCandidateValidator() const override {
151 return overlay_candidate_validator_.get();
154 private:
155 scoped_ptr<OverlayCandidateValidator> overlay_candidate_validator_;
158 void OverlayOutputSurface::SwapBuffers(CompositorFrame* frame) {
159 client_->DidSwapBuffers();
160 client_->DidSwapBuffersComplete();
163 scoped_ptr<RenderPass> CreateRenderPass() {
164 RenderPassId id(1, 0);
165 gfx::Rect output_rect(0, 0, 256, 256);
166 bool has_transparent_background = true;
168 scoped_ptr<RenderPass> pass = RenderPass::Create();
169 pass->SetAll(id,
170 output_rect,
171 output_rect,
172 gfx::Transform(),
173 has_transparent_background);
175 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
176 shared_state->opacity = 1.f;
177 return pass.Pass();
180 ResourceId CreateResource(ResourceProvider* resource_provider) {
181 unsigned sync_point = 0;
182 TextureMailbox mailbox =
183 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
184 scoped_ptr<SingleReleaseCallbackImpl> release_callback =
185 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
187 return resource_provider->CreateResourceFromTextureMailbox(
188 mailbox, release_callback.Pass());
191 SolidColorDrawQuad* CreateSolidColorQuadAt(
192 const SharedQuadState* shared_quad_state,
193 SkColor color,
194 RenderPass* render_pass,
195 const gfx::Rect& rect) {
196 SolidColorDrawQuad* quad =
197 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
198 quad->SetNew(shared_quad_state, rect, rect, color, false);
199 return quad;
202 TextureDrawQuad* CreateCandidateQuadAt(ResourceProvider* resource_provider,
203 const SharedQuadState* shared_quad_state,
204 RenderPass* render_pass,
205 const gfx::Rect& rect) {
206 ResourceId resource_id = CreateResource(resource_provider);
207 bool premultiplied_alpha = false;
208 bool flipped = false;
209 bool nearest_neighbor = false;
210 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
211 gfx::Size resource_size_in_pixels = gfx::Size(64, 64);
212 bool allow_overlay = true;
214 TextureDrawQuad* overlay_quad =
215 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
216 overlay_quad->SetNew(shared_quad_state,
217 rect,
218 rect,
219 rect,
220 resource_id,
221 premultiplied_alpha,
222 kUVTopLeft,
223 kUVBottomRight,
224 SK_ColorTRANSPARENT,
225 vertex_opacity,
226 flipped,
227 nearest_neighbor);
228 overlay_quad->set_allow_overlay(allow_overlay);
229 overlay_quad->set_resource_size_in_pixels(resource_size_in_pixels);
231 return overlay_quad;
234 StreamVideoDrawQuad* CreateCandidateVideoQuadAt(
235 ResourceProvider* resource_provider,
236 const SharedQuadState* shared_quad_state,
237 RenderPass* render_pass,
238 const gfx::Rect& rect,
239 const gfx::Transform& transform) {
240 ResourceId resource_id = CreateResource(resource_provider);
241 gfx::Size resource_size_in_pixels = gfx::Size(64, 64);
242 bool allow_overlay = true;
244 StreamVideoDrawQuad* overlay_quad =
245 render_pass->CreateAndAppendDrawQuad<StreamVideoDrawQuad>();
246 overlay_quad->SetNew(shared_quad_state, rect, rect, rect, resource_id,
247 resource_size_in_pixels, allow_overlay, transform);
249 return overlay_quad;
252 TextureDrawQuad* CreateFullscreenCandidateQuad(
253 ResourceProvider* resource_provider,
254 const SharedQuadState* shared_quad_state,
255 RenderPass* render_pass) {
256 return CreateCandidateQuadAt(
257 resource_provider, shared_quad_state, render_pass, kOverlayRect);
260 StreamVideoDrawQuad* CreateFullscreenCandidateVideoQuad(
261 ResourceProvider* resource_provider,
262 const SharedQuadState* shared_quad_state,
263 RenderPass* render_pass,
264 const gfx::Transform& transform) {
265 return CreateCandidateVideoQuadAt(resource_provider, shared_quad_state,
266 render_pass, kOverlayRect, transform);
269 void CreateOpaqueQuadAt(ResourceProvider* resource_provider,
270 const SharedQuadState* shared_quad_state,
271 RenderPass* render_pass,
272 const gfx::Rect& rect) {
273 SolidColorDrawQuad* color_quad =
274 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
275 color_quad->SetNew(shared_quad_state, rect, rect, SK_ColorBLACK, false);
278 void CreateFullscreenOpaqueQuad(ResourceProvider* resource_provider,
279 const SharedQuadState* shared_quad_state,
280 RenderPass* render_pass) {
281 CreateOpaqueQuadAt(resource_provider, shared_quad_state, render_pass,
282 kOverlayRect);
285 static void CompareRenderPassLists(const RenderPassList& expected_list,
286 const RenderPassList& actual_list) {
287 EXPECT_EQ(expected_list.size(), actual_list.size());
288 for (size_t i = 0; i < actual_list.size(); ++i) {
289 RenderPass* expected = expected_list[i];
290 RenderPass* actual = actual_list[i];
292 EXPECT_EQ(expected->id, actual->id);
293 EXPECT_EQ(expected->output_rect, actual->output_rect);
294 EXPECT_EQ(expected->transform_to_root_target,
295 actual->transform_to_root_target);
296 EXPECT_EQ(expected->damage_rect, actual->damage_rect);
297 EXPECT_EQ(expected->has_transparent_background,
298 actual->has_transparent_background);
300 EXPECT_EQ(expected->shared_quad_state_list.size(),
301 actual->shared_quad_state_list.size());
302 EXPECT_EQ(expected->quad_list.size(), actual->quad_list.size());
304 for (auto exp_iter = expected->quad_list.cbegin(),
305 act_iter = actual->quad_list.cbegin();
306 exp_iter != expected->quad_list.cend();
307 ++exp_iter, ++act_iter) {
308 EXPECT_EQ(exp_iter->rect.ToString(), act_iter->rect.ToString());
309 EXPECT_EQ(exp_iter->shared_quad_state->quad_layer_bounds.ToString(),
310 act_iter->shared_quad_state->quad_layer_bounds.ToString());
315 TEST(OverlayTest, NoOverlaysByDefault) {
316 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
317 OverlayOutputSurface output_surface(provider);
318 EXPECT_EQ(NULL, output_surface.GetOverlayCandidateValidator());
320 output_surface.InitWithSingleOverlayValidator();
321 EXPECT_TRUE(output_surface.GetOverlayCandidateValidator() != NULL);
324 TEST(OverlayTest, OverlaysProcessorHasStrategy) {
325 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
326 OverlayOutputSurface output_surface(provider);
327 FakeOutputSurfaceClient client;
328 EXPECT_TRUE(output_surface.BindToClient(&client));
329 output_surface.InitWithSingleOverlayValidator();
330 EXPECT_TRUE(output_surface.GetOverlayCandidateValidator() != NULL);
332 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
333 new TestSharedBitmapManager());
334 scoped_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(
335 &output_surface, shared_bitmap_manager.get());
337 scoped_ptr<DefaultOverlayProcessor> overlay_processor(
338 new DefaultOverlayProcessor(&output_surface));
339 overlay_processor->Initialize();
340 EXPECT_GE(2U, overlay_processor->GetStrategyCount());
343 template <typename OverlayStrategyType>
344 class OverlayTest : public testing::Test {
345 protected:
346 void SetUp() override {
347 provider_ = TestContextProvider::Create();
348 output_surface_.reset(new OverlayOutputSurface(provider_));
349 EXPECT_TRUE(output_surface_->BindToClient(&client_));
350 output_surface_->InitWithSingleOverlayValidator();
351 EXPECT_TRUE(output_surface_->GetOverlayCandidateValidator() != NULL);
353 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
354 resource_provider_ = FakeResourceProvider::Create(
355 output_surface_.get(), shared_bitmap_manager_.get());
357 overlay_processor_.reset(
358 new SingleOverlayProcessor<OverlayStrategyType>(output_surface_.get()));
359 overlay_processor_->Initialize();
362 scoped_refptr<TestContextProvider> provider_;
363 scoped_ptr<OverlayOutputSurface> output_surface_;
364 FakeOutputSurfaceClient client_;
365 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
366 scoped_ptr<ResourceProvider> resource_provider_;
367 scoped_ptr<SingleOverlayProcessor<OverlayStrategyType>> overlay_processor_;
370 typedef OverlayTest<OverlayStrategySingleOnTop> SingleOverlayOnTopTest;
371 typedef OverlayTest<OverlayStrategyUnderlay> UnderlayTest;
373 class SandwichTest : public testing::Test {
374 protected:
375 void SetUp() override {
376 provider_ = TestContextProvider::Create();
377 output_surface_.reset(new OverlayOutputSurface(provider_));
378 EXPECT_TRUE(output_surface_->BindToClient(&client_));
379 output_surface_->InitWithSandwichOverlayValidator();
380 EXPECT_TRUE(output_surface_->GetOverlayCandidateValidator() != NULL);
382 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
383 resource_provider_ = FakeResourceProvider::Create(
384 output_surface_.get(), shared_bitmap_manager_.get());
386 overlay_processor_.reset(new OverlayProcessor(output_surface_.get()));
387 overlay_processor_->Initialize();
390 scoped_refptr<TestContextProvider> provider_;
391 scoped_ptr<OverlayOutputSurface> output_surface_;
392 FakeOutputSurfaceClient client_;
393 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
394 scoped_ptr<ResourceProvider> resource_provider_;
395 scoped_ptr<OverlayProcessor> overlay_processor_;
398 TEST_F(SandwichTest, SuccessfulSingleOverlay) {
399 scoped_ptr<RenderPass> pass = CreateRenderPass();
400 TextureDrawQuad* original_quad = CreateFullscreenCandidateQuad(
401 resource_provider_.get(), pass->shared_quad_state_list.back(),
402 pass.get());
403 unsigned original_resource_id = original_quad->resource_id();
405 // Add something behind it.
406 CreateFullscreenOpaqueQuad(resource_provider_.get(),
407 pass->shared_quad_state_list.back(), pass.get());
408 CreateFullscreenOpaqueQuad(resource_provider_.get(),
409 pass->shared_quad_state_list.back(), pass.get());
411 RenderPassList pass_list;
412 pass_list.push_back(pass.Pass());
414 // Check for potential candidates.
415 OverlayCandidateList candidate_list;
416 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
418 ASSERT_EQ(1U, pass_list.size());
419 ASSERT_EQ(2U, candidate_list.size());
421 RenderPass* main_pass = pass_list.back();
422 // Check that the quad is gone.
423 EXPECT_EQ(2U, main_pass->quad_list.size());
424 const QuadList& quad_list = main_pass->quad_list;
425 for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin();
426 it != quad_list.BackToFrontEnd(); ++it) {
427 EXPECT_NE(DrawQuad::TEXTURE_CONTENT, it->material);
430 // Check that the right resource id got extracted.
431 EXPECT_EQ(original_resource_id, candidate_list.back().resource_id);
434 TEST_F(SandwichTest, SuccessfulSandwichOverlay) {
435 scoped_ptr<RenderPass> pass = CreateRenderPass();
437 CreateOpaqueQuadAt(resource_provider_.get(),
438 pass->shared_quad_state_list.back(), pass.get(),
439 gfx::Rect(16, 16, 32, 32));
440 unsigned candidate_id =
441 CreateCandidateQuadAt(resource_provider_.get(),
442 pass->shared_quad_state_list.back(), pass.get(),
443 gfx::Rect(32, 32, 32, 32))
444 ->resource_id();
445 CreateOpaqueQuadAt(resource_provider_.get(),
446 pass->shared_quad_state_list.back(), pass.get(),
447 gfx::Rect(kDisplaySize));
449 RenderPassList pass_list;
450 pass_list.push_back(pass.Pass());
452 // Check for potential candidates.
453 OverlayCandidateList candidate_list;
454 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
456 ASSERT_EQ(1U, pass_list.size());
457 ASSERT_EQ(3U, candidate_list.size());
459 RenderPass* main_pass = pass_list.back();
460 // Check that the quad is gone.
461 EXPECT_EQ(3U, main_pass->quad_list.size());
462 const QuadList& quad_list = main_pass->quad_list;
463 for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin();
464 it != quad_list.BackToFrontEnd(); ++it) {
465 EXPECT_NE(DrawQuad::TEXTURE_CONTENT, it->material);
468 EXPECT_FALSE(candidate_list[0].use_output_surface_for_resource);
469 EXPECT_EQ(candidate_id, candidate_list[1].resource_id);
470 EXPECT_EQ(gfx::Rect(32, 32, 32, 32), candidate_list[1].display_rect);
471 EXPECT_TRUE(candidate_list[2].use_output_surface_for_resource);
472 EXPECT_EQ(gfx::Rect(32, 32, 16, 16), candidate_list[2].display_rect);
473 EXPECT_EQ(gfx::RectF(32. / 256, 32. / 256, 16. / 256, 16. / 256),
474 candidate_list[2].uv_rect);
477 TEST_F(SandwichTest, GrowTopOverlayForToAlignWithDIP) {
478 output_surface_->SetScaleFactor(2);
479 scoped_ptr<RenderPass> pass = CreateRenderPass();
481 // The opaque quad on top is not DIP aligned, so it should be enlarged to
482 // include the surrounding DIP.
483 CreateOpaqueQuadAt(resource_provider_.get(),
484 pass->shared_quad_state_list.back(), pass.get(),
485 gfx::Rect(16, 16, 33, 33));
486 unsigned candidate_id =
487 CreateCandidateQuadAt(resource_provider_.get(),
488 pass->shared_quad_state_list.back(), pass.get(),
489 gfx::Rect(32, 32, 32, 32))
490 ->resource_id();
491 CreateOpaqueQuadAt(resource_provider_.get(),
492 pass->shared_quad_state_list.back(), pass.get(),
493 gfx::Rect(kDisplaySize));
495 RenderPassList pass_list;
496 pass_list.push_back(pass.Pass());
498 // Check for potential candidates.
499 OverlayCandidateList candidate_list;
500 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
501 ASSERT_EQ(1U, pass_list.size());
502 ASSERT_EQ(3U, candidate_list.size());
504 // Check that the quad is gone.
505 RenderPass* main_pass = pass_list.back();
506 EXPECT_EQ(3U, main_pass->quad_list.size());
507 const QuadList& quad_list = main_pass->quad_list;
508 for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin();
509 it != quad_list.BackToFrontEnd(); ++it) {
510 EXPECT_NE(DrawQuad::TEXTURE_CONTENT, it->material);
513 EXPECT_FALSE(candidate_list[0].use_output_surface_for_resource);
514 EXPECT_EQ(candidate_id, candidate_list[1].resource_id);
515 EXPECT_EQ(gfx::Rect(32, 32, 32, 32), candidate_list[1].display_rect);
516 EXPECT_TRUE(candidate_list[2].use_output_surface_for_resource);
517 EXPECT_EQ(gfx::Rect(32, 32, 18, 18), candidate_list[2].display_rect);
518 EXPECT_EQ(gfx::RectF(32. / 256, 32. / 256, 18. / 256, 18. / 256),
519 candidate_list[2].uv_rect);
522 TEST_F(SandwichTest, MisalignedOverlay) {
523 output_surface_->SetScaleFactor(2);
524 scoped_ptr<RenderPass> pass = CreateRenderPass();
526 // We can't create an overlay for a candidate that is not DIP aligned.
527 CreateCandidateQuadAt(resource_provider_.get(),
528 pass->shared_quad_state_list.back(), pass.get(),
529 gfx::Rect(32, 32, 33, 33))
530 ->resource_id();
531 CreateOpaqueQuadAt(resource_provider_.get(),
532 pass->shared_quad_state_list.back(), pass.get(),
533 gfx::Rect(kDisplaySize));
535 RenderPassList pass_list;
536 pass_list.push_back(pass.Pass());
538 OverlayCandidateList candidate_list;
539 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
541 ASSERT_EQ(1U, pass_list.size());
542 ASSERT_EQ(0U, candidate_list.size());
545 TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) {
546 scoped_ptr<RenderPass> pass = CreateRenderPass();
547 TextureDrawQuad* original_quad =
548 CreateFullscreenCandidateQuad(resource_provider_.get(),
549 pass->shared_quad_state_list.back(),
550 pass.get());
551 unsigned original_resource_id = original_quad->resource_id();
553 // Add something behind it.
554 CreateFullscreenOpaqueQuad(resource_provider_.get(),
555 pass->shared_quad_state_list.back(), pass.get());
556 CreateFullscreenOpaqueQuad(resource_provider_.get(),
557 pass->shared_quad_state_list.back(), pass.get());
559 RenderPassList pass_list;
560 pass_list.push_back(pass.Pass());
562 // Check for potential candidates.
563 OverlayCandidateList candidate_list;
564 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
566 ASSERT_EQ(1U, pass_list.size());
567 ASSERT_EQ(2U, candidate_list.size());
569 RenderPass* main_pass = pass_list.back();
570 // Check that the quad is gone.
571 EXPECT_EQ(2U, main_pass->quad_list.size());
572 const QuadList& quad_list = main_pass->quad_list;
573 for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin();
574 it != quad_list.BackToFrontEnd();
575 ++it) {
576 EXPECT_NE(DrawQuad::TEXTURE_CONTENT, it->material);
579 // Check that the right resource id got extracted.
580 EXPECT_EQ(original_resource_id, candidate_list.back().resource_id);
583 TEST_F(SingleOverlayOnTopTest, NoCandidates) {
584 scoped_ptr<RenderPass> pass = CreateRenderPass();
585 CreateFullscreenOpaqueQuad(resource_provider_.get(),
586 pass->shared_quad_state_list.back(), pass.get());
587 CreateFullscreenOpaqueQuad(resource_provider_.get(),
588 pass->shared_quad_state_list.back(), pass.get());
590 RenderPassList pass_list;
591 pass_list.push_back(pass.Pass());
593 RenderPassList original_pass_list;
594 RenderPass::CopyAll(pass_list, &original_pass_list);
596 OverlayCandidateList candidate_list;
597 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
598 EXPECT_EQ(0U, candidate_list.size());
599 // There should be nothing new here.
600 CompareRenderPassLists(pass_list, original_pass_list);
603 TEST_F(SingleOverlayOnTopTest, OccludedCandidates) {
604 scoped_ptr<RenderPass> pass = CreateRenderPass();
605 CreateFullscreenOpaqueQuad(resource_provider_.get(),
606 pass->shared_quad_state_list.back(), pass.get());
607 CreateFullscreenOpaqueQuad(resource_provider_.get(),
608 pass->shared_quad_state_list.back(), pass.get());
610 CreateFullscreenCandidateQuad(resource_provider_.get(),
611 pass->shared_quad_state_list.back(),
612 pass.get());
614 RenderPassList pass_list;
615 pass_list.push_back(pass.Pass());
617 RenderPassList original_pass_list;
618 RenderPass::CopyAll(pass_list, &original_pass_list);
620 OverlayCandidateList candidate_list;
621 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
622 EXPECT_EQ(0U, candidate_list.size());
623 // There should be nothing new here.
624 CompareRenderPassLists(pass_list, original_pass_list);
627 // Test with multiple render passes.
628 TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) {
629 RenderPassList pass_list;
630 pass_list.push_back(CreateRenderPass());
632 scoped_ptr<RenderPass> pass = CreateRenderPass();
633 CreateFullscreenCandidateQuad(resource_provider_.get(),
634 pass->shared_quad_state_list.back(),
635 pass.get());
637 // Add something behind it.
638 CreateFullscreenOpaqueQuad(resource_provider_.get(),
639 pass->shared_quad_state_list.back(), pass.get());
640 CreateFullscreenOpaqueQuad(resource_provider_.get(),
641 pass->shared_quad_state_list.back(), pass.get());
643 pass_list.push_back(pass.Pass());
645 RenderPassList original_pass_list;
646 RenderPass::CopyAll(pass_list, &original_pass_list);
648 // Check for potential candidates.
649 OverlayCandidateList candidate_list;
650 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
651 EXPECT_EQ(2U, candidate_list.size());
653 // This should be the same.
654 ASSERT_EQ(2U, pass_list.size());
657 TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) {
658 scoped_ptr<RenderPass> pass = CreateRenderPass();
659 TextureDrawQuad* quad =
660 CreateFullscreenCandidateQuad(resource_provider_.get(),
661 pass->shared_quad_state_list.back(),
662 pass.get());
663 quad->premultiplied_alpha = true;
665 RenderPassList pass_list;
666 pass_list.push_back(pass.Pass());
667 OverlayCandidateList candidate_list;
668 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
669 EXPECT_EQ(1U, pass_list.size());
670 EXPECT_EQ(0U, candidate_list.size());
673 TEST_F(SingleOverlayOnTopTest, RejectBlending) {
674 scoped_ptr<RenderPass> pass = CreateRenderPass();
675 TextureDrawQuad* quad =
676 CreateFullscreenCandidateQuad(resource_provider_.get(),
677 pass->shared_quad_state_list.back(),
678 pass.get());
679 quad->needs_blending = true;
681 RenderPassList pass_list;
682 pass_list.push_back(pass.Pass());
683 OverlayCandidateList candidate_list;
684 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
685 ASSERT_EQ(1U, pass_list.size());
686 EXPECT_EQ(0U, candidate_list.size());
689 TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {
690 scoped_ptr<RenderPass> pass = CreateRenderPass();
691 TextureDrawQuad* quad =
692 CreateFullscreenCandidateQuad(resource_provider_.get(),
693 pass->shared_quad_state_list.back(),
694 pass.get());
695 quad->background_color = SK_ColorBLACK;
697 RenderPassList pass_list;
698 pass_list.push_back(pass.Pass());
699 OverlayCandidateList candidate_list;
700 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
701 ASSERT_EQ(1U, pass_list.size());
702 EXPECT_EQ(0U, candidate_list.size());
705 TEST_F(SingleOverlayOnTopTest, RejectBlendMode) {
706 scoped_ptr<RenderPass> pass = CreateRenderPass();
707 CreateFullscreenCandidateQuad(resource_provider_.get(),
708 pass->shared_quad_state_list.back(),
709 pass.get());
710 pass->shared_quad_state_list.back()->blend_mode = SkXfermode::kScreen_Mode;
712 RenderPassList pass_list;
713 pass_list.push_back(pass.Pass());
714 OverlayCandidateList candidate_list;
715 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
716 ASSERT_EQ(1U, pass_list.size());
717 EXPECT_EQ(0U, candidate_list.size());
720 TEST_F(SingleOverlayOnTopTest, RejectOpacity) {
721 scoped_ptr<RenderPass> pass = CreateRenderPass();
722 CreateFullscreenCandidateQuad(resource_provider_.get(),
723 pass->shared_quad_state_list.back(),
724 pass.get());
725 pass->shared_quad_state_list.back()->opacity = 0.5f;
727 RenderPassList pass_list;
728 pass_list.push_back(pass.Pass());
729 OverlayCandidateList candidate_list;
730 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
731 ASSERT_EQ(1U, pass_list.size());
732 EXPECT_EQ(0U, candidate_list.size());
735 TEST_F(SingleOverlayOnTopTest, RejectNonAxisAlignedTransform) {
736 scoped_ptr<RenderPass> pass = CreateRenderPass();
737 CreateFullscreenCandidateQuad(resource_provider_.get(),
738 pass->shared_quad_state_list.back(),
739 pass.get());
740 pass->shared_quad_state_list.back()
741 ->quad_to_target_transform.RotateAboutXAxis(45.f);
743 RenderPassList pass_list;
744 pass_list.push_back(pass.Pass());
745 OverlayCandidateList candidate_list;
746 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
747 ASSERT_EQ(1U, pass_list.size());
748 EXPECT_EQ(0U, candidate_list.size());
751 TEST_F(SingleOverlayOnTopTest, AllowVerticalFlip) {
752 gfx::Rect rect = kOverlayRect;
753 rect.set_width(rect.width() / 2);
754 rect.Offset(0, -rect.height());
755 scoped_ptr<RenderPass> pass = CreateRenderPass();
756 CreateCandidateQuadAt(resource_provider_.get(),
757 pass->shared_quad_state_list.back(), pass.get(), rect);
758 pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(2.0f,
759 -1.0f);
761 RenderPassList pass_list;
762 pass_list.push_back(pass.Pass());
763 OverlayCandidateList candidate_list;
764 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
765 ASSERT_EQ(1U, pass_list.size());
766 ASSERT_EQ(2U, candidate_list.size());
767 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL,
768 candidate_list.back().transform);
771 TEST_F(SingleOverlayOnTopTest, AllowHorizontalFlip) {
772 gfx::Rect rect = kOverlayRect;
773 rect.set_height(rect.height() / 2);
774 rect.Offset(-rect.width(), 0);
775 scoped_ptr<RenderPass> pass = CreateRenderPass();
776 CreateCandidateQuadAt(resource_provider_.get(),
777 pass->shared_quad_state_list.back(), pass.get(), rect);
778 pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(-1.0f,
779 2.0f);
781 RenderPassList pass_list;
782 pass_list.push_back(pass.Pass());
783 OverlayCandidateList candidate_list;
784 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
785 ASSERT_EQ(1U, pass_list.size());
786 ASSERT_EQ(2U, candidate_list.size());
787 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL,
788 candidate_list.back().transform);
791 TEST_F(SingleOverlayOnTopTest, AllowPositiveScaleTransform) {
792 gfx::Rect rect = kOverlayRect;
793 rect.set_width(rect.width() / 2);
794 scoped_ptr<RenderPass> pass = CreateRenderPass();
795 CreateCandidateQuadAt(resource_provider_.get(),
796 pass->shared_quad_state_list.back(), pass.get(), rect);
797 pass->shared_quad_state_list.back()->quad_to_target_transform.Scale(2.0f,
798 1.0f);
800 RenderPassList pass_list;
801 pass_list.push_back(pass.Pass());
802 OverlayCandidateList candidate_list;
803 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
804 ASSERT_EQ(1U, pass_list.size());
805 EXPECT_EQ(2U, candidate_list.size());
808 TEST_F(SingleOverlayOnTopTest, Allow90DegreeRotation) {
809 gfx::Rect rect = kOverlayRect;
810 rect.Offset(0, -rect.height());
811 scoped_ptr<RenderPass> pass = CreateRenderPass();
812 CreateCandidateQuadAt(resource_provider_.get(),
813 pass->shared_quad_state_list.back(), pass.get(), rect);
814 pass->shared_quad_state_list.back()
815 ->quad_to_target_transform.RotateAboutZAxis(90.f);
817 RenderPassList pass_list;
818 pass_list.push_back(pass.Pass());
819 OverlayCandidateList candidate_list;
820 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
821 ASSERT_EQ(1U, pass_list.size());
822 ASSERT_EQ(2U, candidate_list.size());
823 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_90, candidate_list.back().transform);
826 TEST_F(SingleOverlayOnTopTest, Allow180DegreeRotation) {
827 gfx::Rect rect = kOverlayRect;
828 rect.Offset(-rect.width(), -rect.height());
829 scoped_ptr<RenderPass> pass = CreateRenderPass();
830 CreateCandidateQuadAt(resource_provider_.get(),
831 pass->shared_quad_state_list.back(), pass.get(), rect);
832 pass->shared_quad_state_list.back()
833 ->quad_to_target_transform.RotateAboutZAxis(180.f);
835 RenderPassList pass_list;
836 pass_list.push_back(pass.Pass());
837 OverlayCandidateList candidate_list;
838 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
839 ASSERT_EQ(1U, pass_list.size());
840 ASSERT_EQ(2U, candidate_list.size());
841 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_180, candidate_list.back().transform);
844 TEST_F(SingleOverlayOnTopTest, Allow270DegreeRotation) {
845 gfx::Rect rect = kOverlayRect;
846 rect.Offset(-rect.width(), 0);
847 scoped_ptr<RenderPass> pass = CreateRenderPass();
848 CreateCandidateQuadAt(resource_provider_.get(),
849 pass->shared_quad_state_list.back(), pass.get(), rect);
850 pass->shared_quad_state_list.back()
851 ->quad_to_target_transform.RotateAboutZAxis(270.f);
853 RenderPassList pass_list;
854 pass_list.push_back(pass.Pass());
855 OverlayCandidateList candidate_list;
856 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
857 ASSERT_EQ(1U, pass_list.size());
858 ASSERT_EQ(2U, candidate_list.size());
859 EXPECT_EQ(gfx::OVERLAY_TRANSFORM_ROTATE_270, candidate_list.back().transform);
862 TEST_F(SingleOverlayOnTopTest, AllowNotTopIfNotOccluded) {
863 scoped_ptr<RenderPass> pass = CreateRenderPass();
864 CreateOpaqueQuadAt(resource_provider_.get(),
865 pass->shared_quad_state_list.back(), pass.get(),
866 kOverlayTopLeftRect);
867 CreateCandidateQuadAt(resource_provider_.get(),
868 pass->shared_quad_state_list.back(),
869 pass.get(),
870 kOverlayBottomRightRect);
872 RenderPassList pass_list;
873 pass_list.push_back(pass.Pass());
875 RenderPassList original_pass_list;
876 RenderPass::CopyAll(pass_list, &original_pass_list);
878 OverlayCandidateList candidate_list;
879 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
880 EXPECT_EQ(1U, pass_list.size());
881 EXPECT_EQ(2U, candidate_list.size());
884 TEST_F(SingleOverlayOnTopTest, AllowTransparentOnTop) {
885 scoped_ptr<RenderPass> pass = CreateRenderPass();
886 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
887 shared_state->opacity = 0.f;
888 CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(),
889 kOverlayBottomRightRect);
890 shared_state = pass->CreateAndAppendSharedQuadState();
891 shared_state->opacity = 1.f;
892 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
893 kOverlayBottomRightRect);
895 RenderPassList pass_list;
896 pass_list.push_back(pass.Pass());
898 RenderPassList original_pass_list;
899 RenderPass::CopyAll(pass_list, &original_pass_list);
901 OverlayCandidateList candidate_list;
902 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
903 EXPECT_EQ(1U, pass_list.size());
904 EXPECT_EQ(2U, candidate_list.size());
907 TEST_F(SingleOverlayOnTopTest, AllowTransparentColorOnTop) {
908 scoped_ptr<RenderPass> pass = CreateRenderPass();
909 CreateSolidColorQuadAt(pass->shared_quad_state_list.back(),
910 SK_ColorTRANSPARENT, pass.get(),
911 kOverlayBottomRightRect);
912 CreateCandidateQuadAt(resource_provider_.get(),
913 pass->shared_quad_state_list.back(), pass.get(),
914 kOverlayBottomRightRect);
916 RenderPassList pass_list;
917 pass_list.push_back(pass.Pass());
919 RenderPassList original_pass_list;
920 RenderPass::CopyAll(pass_list, &original_pass_list);
922 OverlayCandidateList candidate_list;
923 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
924 EXPECT_EQ(1U, pass_list.size());
925 EXPECT_EQ(2U, candidate_list.size());
928 TEST_F(SingleOverlayOnTopTest, RejectOpaqueColorOnTop) {
929 scoped_ptr<RenderPass> pass = CreateRenderPass();
930 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
931 shared_state->opacity = 0.5f;
932 CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(),
933 kOverlayBottomRightRect);
934 shared_state = pass->CreateAndAppendSharedQuadState();
935 shared_state->opacity = 1.f;
936 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
937 kOverlayBottomRightRect);
939 RenderPassList pass_list;
940 pass_list.push_back(pass.Pass());
942 RenderPassList original_pass_list;
943 RenderPass::CopyAll(pass_list, &original_pass_list);
945 OverlayCandidateList candidate_list;
946 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
947 EXPECT_EQ(1U, pass_list.size());
948 EXPECT_EQ(0U, candidate_list.size());
951 TEST_F(SingleOverlayOnTopTest, RejectTransparentColorOnTopWithoutBlending) {
952 scoped_ptr<RenderPass> pass = CreateRenderPass();
953 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
954 CreateSolidColorQuadAt(shared_state, SK_ColorTRANSPARENT, pass.get(),
955 kOverlayBottomRightRect)->opaque_rect =
956 kOverlayBottomRightRect;
957 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
958 kOverlayBottomRightRect);
960 RenderPassList pass_list;
961 pass_list.push_back(pass.Pass());
963 RenderPassList original_pass_list;
964 RenderPass::CopyAll(pass_list, &original_pass_list);
966 OverlayCandidateList candidate_list;
967 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
968 EXPECT_EQ(1U, pass_list.size());
969 EXPECT_EQ(0U, candidate_list.size());
972 TEST_F(SingleOverlayOnTopTest, RejectVideoSwapTransform) {
973 scoped_ptr<RenderPass> pass = CreateRenderPass();
974 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
975 pass->shared_quad_state_list.back(),
976 pass.get(), kSwapTransform);
978 RenderPassList pass_list;
979 pass_list.push_back(pass.Pass());
980 OverlayCandidateList candidate_list;
981 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
982 ASSERT_EQ(1U, pass_list.size());
983 EXPECT_EQ(0U, candidate_list.size());
986 TEST_F(SingleOverlayOnTopTest, AllowVideoXMirrorTransform) {
987 scoped_ptr<RenderPass> pass = CreateRenderPass();
988 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
989 pass->shared_quad_state_list.back(),
990 pass.get(), kXMirrorTransform);
992 RenderPassList pass_list;
993 pass_list.push_back(pass.Pass());
994 OverlayCandidateList candidate_list;
995 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
996 ASSERT_EQ(1U, pass_list.size());
997 EXPECT_EQ(2U, candidate_list.size());
1000 TEST_F(SingleOverlayOnTopTest, AllowVideoBothMirrorTransform) {
1001 scoped_ptr<RenderPass> pass = CreateRenderPass();
1002 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
1003 pass->shared_quad_state_list.back(),
1004 pass.get(), kBothMirrorTransform);
1006 RenderPassList pass_list;
1007 pass_list.push_back(pass.Pass());
1008 OverlayCandidateList candidate_list;
1009 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
1010 ASSERT_EQ(1U, pass_list.size());
1011 EXPECT_EQ(2U, candidate_list.size());
1014 TEST_F(SingleOverlayOnTopTest, AllowVideoNormalTransform) {
1015 scoped_ptr<RenderPass> pass = CreateRenderPass();
1016 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
1017 pass->shared_quad_state_list.back(),
1018 pass.get(), kNormalTransform);
1020 RenderPassList pass_list;
1021 pass_list.push_back(pass.Pass());
1022 OverlayCandidateList candidate_list;
1023 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
1024 ASSERT_EQ(1U, pass_list.size());
1025 EXPECT_EQ(2U, candidate_list.size());
1028 TEST_F(SingleOverlayOnTopTest, AllowVideoYMirrorTransform) {
1029 scoped_ptr<RenderPass> pass = CreateRenderPass();
1030 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
1031 pass->shared_quad_state_list.back(),
1032 pass.get(), kYMirrorTransform);
1034 RenderPassList pass_list;
1035 pass_list.push_back(pass.Pass());
1036 OverlayCandidateList candidate_list;
1037 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
1038 ASSERT_EQ(1U, pass_list.size());
1039 EXPECT_EQ(2U, candidate_list.size());
1042 TEST_F(UnderlayTest, OverlayLayerUnderMainLayer) {
1043 scoped_ptr<RenderPass> pass = CreateRenderPass();
1044 CreateFullscreenOpaqueQuad(resource_provider_.get(),
1045 pass->shared_quad_state_list.back(), pass.get());
1046 CreateCandidateQuadAt(resource_provider_.get(),
1047 pass->shared_quad_state_list.back(), pass.get(),
1048 kOverlayBottomRightRect);
1050 RenderPassList pass_list;
1051 pass_list.push_back(pass.Pass());
1053 OverlayCandidateList candidate_list;
1054 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
1055 EXPECT_EQ(1U, pass_list.size());
1056 ASSERT_EQ(2U, candidate_list.size());
1057 EXPECT_EQ(0, candidate_list[0].plane_z_order);
1058 EXPECT_EQ(-1, candidate_list[1].plane_z_order);
1059 EXPECT_EQ(2U, pass_list[0]->quad_list.size());
1060 // The overlay quad should have changed to a SOLID_COLOR quad.
1061 EXPECT_EQ(pass_list[0]->quad_list.back()->material, DrawQuad::SOLID_COLOR);
1064 TEST_F(UnderlayTest, AllowOnTop) {
1065 scoped_ptr<RenderPass> pass = CreateRenderPass();
1066 CreateFullscreenCandidateQuad(resource_provider_.get(),
1067 pass->shared_quad_state_list.back(),
1068 pass.get());
1069 pass->CreateAndAppendSharedQuadState()->opacity = 0.5f;
1070 CreateFullscreenOpaqueQuad(resource_provider_.get(),
1071 pass->shared_quad_state_list.back(), pass.get());
1073 RenderPassList pass_list;
1074 pass_list.push_back(pass.Pass());
1076 OverlayCandidateList candidate_list;
1077 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
1078 EXPECT_EQ(1U, pass_list.size());
1079 ASSERT_EQ(2U, candidate_list.size());
1080 EXPECT_EQ(0, candidate_list[0].plane_z_order);
1081 EXPECT_EQ(-1, candidate_list[1].plane_z_order);
1082 // The overlay quad should have changed to a SOLID_COLOR quad.
1083 EXPECT_EQ(pass_list[0]->quad_list.front()->material, DrawQuad::SOLID_COLOR);
1086 class OverlayInfoRendererGL : public GLRenderer {
1087 public:
1088 OverlayInfoRendererGL(RendererClient* client,
1089 const RendererSettings* settings,
1090 OutputSurface* output_surface,
1091 ResourceProvider* resource_provider)
1092 : GLRenderer(client,
1093 settings,
1094 output_surface,
1095 resource_provider,
1096 NULL,
1098 expect_overlays_(false) {}
1100 MOCK_METHOD3(DoDrawQuad,
1101 void(DrawingFrame* frame,
1102 const DrawQuad* quad,
1103 const gfx::QuadF* draw_region));
1105 using GLRenderer::BeginDrawingFrame;
1107 void FinishDrawingFrame(DrawingFrame* frame) override {
1108 GLRenderer::FinishDrawingFrame(frame);
1110 if (!expect_overlays_) {
1111 EXPECT_EQ(0U, frame->overlay_list.size());
1112 return;
1115 ASSERT_EQ(2U, frame->overlay_list.size());
1116 EXPECT_NE(0U, frame->overlay_list.back().resource_id);
1119 void set_expect_overlays(bool expect_overlays) {
1120 expect_overlays_ = expect_overlays;
1123 private:
1124 bool expect_overlays_;
1127 class FakeRendererClient : public RendererClient {
1128 public:
1129 // RendererClient methods.
1130 void SetFullRootLayerDamage() override {}
1133 class MockOverlayScheduler {
1134 public:
1135 MOCK_METHOD5(Schedule,
1136 void(int plane_z_order,
1137 gfx::OverlayTransform plane_transform,
1138 unsigned overlay_texture_id,
1139 const gfx::Rect& display_bounds,
1140 const gfx::RectF& uv_rect));
1143 class GLRendererWithOverlaysTest : public testing::Test {
1144 protected:
1145 GLRendererWithOverlaysTest() {
1146 provider_ = TestContextProvider::Create();
1147 output_surface_.reset(new OverlayOutputSurface(provider_));
1148 CHECK(output_surface_->BindToClient(&output_surface_client_));
1149 resource_provider_ =
1150 FakeResourceProvider::Create(output_surface_.get(), nullptr);
1152 provider_->support()->SetScheduleOverlayPlaneCallback(base::Bind(
1153 &MockOverlayScheduler::Schedule, base::Unretained(&scheduler_)));
1156 void Init(bool use_validator) {
1157 if (use_validator)
1158 output_surface_->InitWithSingleOverlayValidator();
1160 renderer_ =
1161 make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_,
1162 &settings_,
1163 output_surface_.get(),
1164 resource_provider_.get()));
1167 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
1169 RendererSettings settings_;
1170 FakeOutputSurfaceClient output_surface_client_;
1171 scoped_ptr<OverlayOutputSurface> output_surface_;
1172 FakeRendererClient renderer_client_;
1173 scoped_ptr<ResourceProvider> resource_provider_;
1174 scoped_ptr<OverlayInfoRendererGL> renderer_;
1175 scoped_refptr<TestContextProvider> provider_;
1176 MockOverlayScheduler scheduler_;
1179 TEST_F(GLRendererWithOverlaysTest, OverlayQuadNotDrawn) {
1180 bool use_validator = true;
1181 Init(use_validator);
1182 renderer_->set_expect_overlays(true);
1183 gfx::Rect viewport_rect(16, 16);
1185 scoped_ptr<RenderPass> pass = CreateRenderPass();
1187 CreateFullscreenCandidateQuad(resource_provider_.get(),
1188 pass->shared_quad_state_list.back(),
1189 pass.get());
1191 CreateFullscreenOpaqueQuad(resource_provider_.get(),
1192 pass->shared_quad_state_list.back(), pass.get());
1193 CreateFullscreenOpaqueQuad(resource_provider_.get(),
1194 pass->shared_quad_state_list.back(), pass.get());
1196 RenderPassList pass_list;
1197 pass_list.push_back(pass.Pass());
1199 // Candidate pass was taken out and extra skipped pass added,
1200 // so only draw 2 quads.
1201 EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(2);
1202 EXPECT_CALL(scheduler_,
1203 Schedule(1,
1204 gfx::OVERLAY_TRANSFORM_NONE,
1206 kOverlayRect,
1207 BoundingRect(kUVTopLeft, kUVBottomRight))).Times(1);
1208 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
1210 SwapBuffers();
1212 Mock::VerifyAndClearExpectations(renderer_.get());
1213 Mock::VerifyAndClearExpectations(&scheduler_);
1216 TEST_F(GLRendererWithOverlaysTest, OccludedQuadInUnderlay) {
1217 bool use_validator = true;
1218 Init(use_validator);
1219 renderer_->set_expect_overlays(true);
1220 gfx::Rect viewport_rect(16, 16);
1222 scoped_ptr<RenderPass> pass = CreateRenderPass();
1224 CreateFullscreenOpaqueQuad(resource_provider_.get(),
1225 pass->shared_quad_state_list.back(), pass.get());
1226 CreateFullscreenOpaqueQuad(resource_provider_.get(),
1227 pass->shared_quad_state_list.back(), pass.get());
1229 CreateFullscreenCandidateQuad(resource_provider_.get(),
1230 pass->shared_quad_state_list.back(),
1231 pass.get());
1233 RenderPassList pass_list;
1234 pass_list.push_back(pass.Pass());
1236 // Candidate quad should fail to be overlaid on top because of occlusion.
1237 // Expect to be replaced with transparent hole quad and placed in underlay.
1238 EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(3);
1239 EXPECT_CALL(scheduler_,
1240 Schedule(-1, gfx::OVERLAY_TRANSFORM_NONE, _, kOverlayRect,
1241 BoundingRect(kUVTopLeft, kUVBottomRight))).Times(1);
1242 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
1244 SwapBuffers();
1246 Mock::VerifyAndClearExpectations(renderer_.get());
1247 Mock::VerifyAndClearExpectations(&scheduler_);
1250 TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) {
1251 bool use_validator = false;
1252 Init(use_validator);
1253 renderer_->set_expect_overlays(false);
1254 gfx::Rect viewport_rect(16, 16);
1256 scoped_ptr<RenderPass> pass = CreateRenderPass();
1258 CreateFullscreenCandidateQuad(resource_provider_.get(),
1259 pass->shared_quad_state_list.back(),
1260 pass.get());
1262 CreateFullscreenOpaqueQuad(resource_provider_.get(),
1263 pass->shared_quad_state_list.back(), pass.get());
1264 CreateFullscreenOpaqueQuad(resource_provider_.get(),
1265 pass->shared_quad_state_list.back(), pass.get());
1267 RenderPassList pass_list;
1268 pass_list.push_back(pass.Pass());
1270 // Should see no overlays.
1271 EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(3);
1272 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
1273 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
1275 SwapBuffers();
1277 Mock::VerifyAndClearExpectations(renderer_.get());
1278 Mock::VerifyAndClearExpectations(&scheduler_);
1281 TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturned) {
1282 bool use_validator = true;
1283 Init(use_validator);
1284 renderer_->set_expect_overlays(true);
1286 ResourceId resource1 = CreateResource(resource_provider_.get());
1287 ResourceId resource2 = CreateResource(resource_provider_.get());
1289 scoped_ptr<RenderPass> pass = CreateRenderPass();
1290 RenderPassList pass_list;
1291 pass_list.push_back(pass.Pass());
1293 DirectRenderer::DrawingFrame frame1;
1294 frame1.render_passes_in_draw_order = &pass_list;
1295 frame1.overlay_list.resize(2);
1296 OverlayCandidate& overlay1 = frame1.overlay_list.back();
1297 overlay1.resource_id = resource1;
1298 overlay1.plane_z_order = 1;
1300 DirectRenderer::DrawingFrame frame2;
1301 frame2.render_passes_in_draw_order = &pass_list;
1302 frame2.overlay_list.resize(2);
1303 OverlayCandidate& overlay2 = frame2.overlay_list.back();
1304 overlay2.resource_id = resource2;
1305 overlay2.plane_z_order = 1;
1307 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1308 renderer_->BeginDrawingFrame(&frame1);
1309 renderer_->FinishDrawingFrame(&frame1);
1310 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1311 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
1312 SwapBuffers();
1313 Mock::VerifyAndClearExpectations(&scheduler_);
1315 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1316 renderer_->BeginDrawingFrame(&frame2);
1317 renderer_->FinishDrawingFrame(&frame2);
1318 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1319 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
1320 SwapBuffers();
1321 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1322 Mock::VerifyAndClearExpectations(&scheduler_);
1324 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1325 renderer_->BeginDrawingFrame(&frame1);
1326 renderer_->FinishDrawingFrame(&frame1);
1327 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1328 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
1329 SwapBuffers();
1330 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
1331 Mock::VerifyAndClearExpectations(&scheduler_);
1333 // No overlays, release the resource.
1334 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
1335 DirectRenderer::DrawingFrame frame3;
1336 frame3.render_passes_in_draw_order = &pass_list;
1337 renderer_->set_expect_overlays(false);
1338 renderer_->BeginDrawingFrame(&frame3);
1339 renderer_->FinishDrawingFrame(&frame3);
1340 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1341 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
1342 SwapBuffers();
1343 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1344 Mock::VerifyAndClearExpectations(&scheduler_);
1346 // Use the same buffer twice.
1347 renderer_->set_expect_overlays(true);
1348 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1349 renderer_->BeginDrawingFrame(&frame1);
1350 renderer_->FinishDrawingFrame(&frame1);
1351 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1352 SwapBuffers();
1353 Mock::VerifyAndClearExpectations(&scheduler_);
1355 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1356 renderer_->BeginDrawingFrame(&frame1);
1357 renderer_->FinishDrawingFrame(&frame1);
1358 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1359 SwapBuffers();
1360 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1361 Mock::VerifyAndClearExpectations(&scheduler_);
1363 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
1364 renderer_->set_expect_overlays(false);
1365 renderer_->BeginDrawingFrame(&frame3);
1366 renderer_->FinishDrawingFrame(&frame3);
1367 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1368 SwapBuffers();
1369 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1370 Mock::VerifyAndClearExpectations(&scheduler_);
1373 } // namespace
1374 } // namespace cc