Move onConsoleMessage implementation to chromium layer
[chromium-blink-merge.git] / cc / output / overlay_unittest.cc
blob5590ec3d53eeb809fa4aa3b81c1e7f63ed511e15
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/gl_renderer.h"
7 #include "cc/output/output_surface.h"
8 #include "cc/output/output_surface_client.h"
9 #include "cc/output/overlay_candidate_validator.h"
10 #include "cc/output/overlay_processor.h"
11 #include "cc/output/overlay_strategy_single_on_top.h"
12 #include "cc/quads/checkerboard_draw_quad.h"
13 #include "cc/quads/render_pass.h"
14 #include "cc/quads/stream_video_draw_quad.h"
15 #include "cc/quads/texture_draw_quad.h"
16 #include "cc/resources/resource_provider.h"
17 #include "cc/resources/texture_mailbox.h"
18 #include "cc/test/fake_output_surface_client.h"
19 #include "cc/test/geometry_test_utils.h"
20 #include "cc/test/test_context_provider.h"
21 #include "cc/test/test_shared_bitmap_manager.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 using testing::_;
26 using testing::Mock;
28 namespace cc {
29 namespace {
31 const gfx::Rect kOverlayRect(0, 0, 128, 128);
32 const gfx::Rect kOverlayTopLeftRect(0, 0, 64, 64);
33 const gfx::Rect kOverlayBottomRightRect(64, 64, 64, 64);
34 const gfx::PointF kUVTopLeft(0.1f, 0.2f);
35 const gfx::PointF kUVBottomRight(1.0f, 1.0f);
36 const gfx::Transform kNormalTransform =
37 gfx::Transform(0.9f, 0, 0, 0.8f, 0.1f, 0.2f); // x,y -> x,y.
38 const gfx::Transform kXMirrorTransform =
39 gfx::Transform(-0.9f, 0, 0, 0.8f, 1.0f, 0.2f); // x,y -> 1-x,y.
40 const gfx::Transform kYMirrorTransform =
41 gfx::Transform(0.9f, 0, 0, -0.8f, 0.1f, 1.0f); // x,y -> x,1-y.
42 const gfx::Transform kBothMirrorTransform =
43 gfx::Transform(-0.9f, 0, 0, -0.8f, 1.0f, 1.0f); // x,y -> 1-x,1-y.
44 const gfx::Transform kSwapTransform =
45 gfx::Transform(0, 1, 1, 0, 0, 0); // x,y -> y,x.
47 void MailboxReleased(unsigned sync_point,
48 bool lost_resource,
49 BlockingTaskRunner* main_thread_task_runner) {
52 class SingleOverlayValidator : public OverlayCandidateValidator {
53 public:
54 void CheckOverlaySupport(OverlayCandidateList* surfaces) override;
57 void SingleOverlayValidator::CheckOverlaySupport(
58 OverlayCandidateList* surfaces) {
59 ASSERT_EQ(2U, surfaces->size());
61 OverlayCandidate& candidate = surfaces->back();
62 if (candidate.display_rect.width() == 64)
63 EXPECT_EQ(kOverlayBottomRightRect, candidate.display_rect);
64 else
65 EXPECT_EQ(kOverlayRect, candidate.display_rect);
66 EXPECT_EQ(BoundingRect(kUVTopLeft, kUVBottomRight).ToString(),
67 candidate.uv_rect.ToString());
68 candidate.overlay_handled = true;
71 class SingleOverlayProcessor : public OverlayProcessor {
72 public:
73 SingleOverlayProcessor(OutputSurface* surface,
74 ResourceProvider* resource_provider);
75 // Virtual to allow testing different strategies.
76 void Initialize() override;
79 SingleOverlayProcessor::SingleOverlayProcessor(
80 OutputSurface* surface,
81 ResourceProvider* resource_provider)
82 : OverlayProcessor(surface, resource_provider) {
83 EXPECT_EQ(surface, surface_);
84 EXPECT_EQ(resource_provider, resource_provider_);
87 void SingleOverlayProcessor::Initialize() {
88 OverlayCandidateValidator* candidates =
89 surface_->overlay_candidate_validator();
90 ASSERT_TRUE(candidates != NULL);
91 strategies_.push_back(scoped_ptr<Strategy>(
92 new OverlayStrategySingleOnTop(candidates, resource_provider_)));
95 class DefaultOverlayProcessor : public OverlayProcessor {
96 public:
97 DefaultOverlayProcessor(OutputSurface* surface,
98 ResourceProvider* resource_provider);
99 size_t GetStrategyCount();
102 DefaultOverlayProcessor::DefaultOverlayProcessor(
103 OutputSurface* surface,
104 ResourceProvider* resource_provider)
105 : OverlayProcessor(surface, resource_provider) {}
107 size_t DefaultOverlayProcessor::GetStrategyCount() {
108 return strategies_.size();
111 class OverlayOutputSurface : public OutputSurface {
112 public:
113 explicit OverlayOutputSurface(scoped_refptr<ContextProvider> context_provider)
114 : OutputSurface(context_provider) {}
116 // OutputSurface implementation
117 void SwapBuffers(CompositorFrame* frame) override;
119 void InitWithSingleOverlayValidator() {
120 overlay_candidate_validator_.reset(new SingleOverlayValidator);
124 void OverlayOutputSurface::SwapBuffers(CompositorFrame* frame) {
125 client_->DidSwapBuffers();
126 client_->DidSwapBuffersComplete();
129 scoped_ptr<RenderPass> CreateRenderPass() {
130 RenderPassId id(1, 0);
131 gfx::Rect output_rect(0, 0, 256, 256);
132 bool has_transparent_background = true;
134 scoped_ptr<RenderPass> pass = RenderPass::Create();
135 pass->SetAll(id,
136 output_rect,
137 output_rect,
138 gfx::Transform(),
139 has_transparent_background);
141 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
142 shared_state->opacity = 1.f;
143 return pass.Pass();
146 ResourceProvider::ResourceId CreateResource(
147 ResourceProvider* resource_provider) {
148 unsigned sync_point = 0;
149 TextureMailbox mailbox =
150 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
151 mailbox.set_allow_overlay(true);
152 scoped_ptr<SingleReleaseCallbackImpl> release_callback =
153 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
155 return resource_provider->CreateResourceFromTextureMailbox(
156 mailbox, release_callback.Pass());
159 SolidColorDrawQuad* CreateSolidColorQuadAt(
160 const SharedQuadState* shared_quad_state,
161 SkColor color,
162 RenderPass* render_pass,
163 const gfx::Rect& rect) {
164 SolidColorDrawQuad* quad =
165 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
166 quad->SetNew(shared_quad_state, rect, rect, color, false);
167 return quad;
170 TextureDrawQuad* CreateCandidateQuadAt(ResourceProvider* resource_provider,
171 const SharedQuadState* shared_quad_state,
172 RenderPass* render_pass,
173 const gfx::Rect& rect) {
174 ResourceProvider::ResourceId resource_id = CreateResource(resource_provider);
175 bool premultiplied_alpha = false;
176 bool flipped = false;
177 bool nearest_neighbor = false;
178 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
180 TextureDrawQuad* overlay_quad =
181 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
182 overlay_quad->SetNew(shared_quad_state,
183 rect,
184 rect,
185 rect,
186 resource_id,
187 premultiplied_alpha,
188 kUVTopLeft,
189 kUVBottomRight,
190 SK_ColorTRANSPARENT,
191 vertex_opacity,
192 flipped,
193 nearest_neighbor);
195 return overlay_quad;
198 StreamVideoDrawQuad* CreateCandidateVideoQuadAt(
199 ResourceProvider* resource_provider,
200 const SharedQuadState* shared_quad_state,
201 RenderPass* render_pass,
202 const gfx::Rect& rect,
203 const gfx::Transform& transform) {
204 ResourceProvider::ResourceId resource_id = CreateResource(resource_provider);
206 StreamVideoDrawQuad* overlay_quad =
207 render_pass->CreateAndAppendDrawQuad<StreamVideoDrawQuad>();
208 overlay_quad->SetNew(shared_quad_state, rect, rect, rect, resource_id,
209 transform);
211 return overlay_quad;
214 TextureDrawQuad* CreateFullscreenCandidateQuad(
215 ResourceProvider* resource_provider,
216 const SharedQuadState* shared_quad_state,
217 RenderPass* render_pass) {
218 return CreateCandidateQuadAt(
219 resource_provider, shared_quad_state, render_pass, kOverlayRect);
222 StreamVideoDrawQuad* CreateFullscreenCandidateVideoQuad(
223 ResourceProvider* resource_provider,
224 const SharedQuadState* shared_quad_state,
225 RenderPass* render_pass,
226 const gfx::Transform& transform) {
227 return CreateCandidateVideoQuadAt(resource_provider, shared_quad_state,
228 render_pass, kOverlayRect, transform);
231 void CreateCheckeredQuadAt(ResourceProvider* resource_provider,
232 const SharedQuadState* shared_quad_state,
233 RenderPass* render_pass,
234 const gfx::Rect& rect) {
235 CheckerboardDrawQuad* checkerboard_quad =
236 render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
237 checkerboard_quad->SetNew(shared_quad_state, rect, rect, SkColor(), 1.f);
240 void CreateFullscreenCheckeredQuad(ResourceProvider* resource_provider,
241 const SharedQuadState* shared_quad_state,
242 RenderPass* render_pass) {
243 CreateCheckeredQuadAt(
244 resource_provider, shared_quad_state, render_pass, kOverlayRect);
247 static void CompareRenderPassLists(const RenderPassList& expected_list,
248 const RenderPassList& actual_list) {
249 EXPECT_EQ(expected_list.size(), actual_list.size());
250 for (size_t i = 0; i < actual_list.size(); ++i) {
251 RenderPass* expected = expected_list[i];
252 RenderPass* actual = actual_list[i];
254 EXPECT_EQ(expected->id, actual->id);
255 EXPECT_EQ(expected->output_rect, actual->output_rect);
256 EXPECT_EQ(expected->transform_to_root_target,
257 actual->transform_to_root_target);
258 EXPECT_EQ(expected->damage_rect, actual->damage_rect);
259 EXPECT_EQ(expected->has_transparent_background,
260 actual->has_transparent_background);
262 EXPECT_EQ(expected->shared_quad_state_list.size(),
263 actual->shared_quad_state_list.size());
264 EXPECT_EQ(expected->quad_list.size(), actual->quad_list.size());
266 for (auto exp_iter = expected->quad_list.cbegin(),
267 act_iter = actual->quad_list.cbegin();
268 exp_iter != expected->quad_list.cend();
269 ++exp_iter, ++act_iter) {
270 EXPECT_EQ(exp_iter->rect.ToString(), act_iter->rect.ToString());
271 EXPECT_EQ(exp_iter->shared_quad_state->content_bounds.ToString(),
272 act_iter->shared_quad_state->content_bounds.ToString());
277 TEST(OverlayTest, NoOverlaysByDefault) {
278 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
279 OverlayOutputSurface output_surface(provider);
280 EXPECT_EQ(NULL, output_surface.overlay_candidate_validator());
282 output_surface.InitWithSingleOverlayValidator();
283 EXPECT_TRUE(output_surface.overlay_candidate_validator() != NULL);
286 TEST(OverlayTest, OverlaysProcessorHasStrategy) {
287 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
288 OverlayOutputSurface output_surface(provider);
289 FakeOutputSurfaceClient client;
290 EXPECT_TRUE(output_surface.BindToClient(&client));
291 output_surface.InitWithSingleOverlayValidator();
292 EXPECT_TRUE(output_surface.overlay_candidate_validator() != NULL);
294 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
295 new TestSharedBitmapManager());
296 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
297 &output_surface, shared_bitmap_manager.get(), NULL, NULL, 0, false, 1));
299 scoped_ptr<DefaultOverlayProcessor> overlay_processor(
300 new DefaultOverlayProcessor(&output_surface, resource_provider.get()));
301 overlay_processor->Initialize();
302 EXPECT_GE(1U, overlay_processor->GetStrategyCount());
305 class SingleOverlayOnTopTest : public testing::Test {
306 protected:
307 void SetUp() override {
308 provider_ = TestContextProvider::Create();
309 output_surface_.reset(new OverlayOutputSurface(provider_));
310 EXPECT_TRUE(output_surface_->BindToClient(&client_));
311 output_surface_->InitWithSingleOverlayValidator();
312 EXPECT_TRUE(output_surface_->overlay_candidate_validator() != NULL);
314 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
315 resource_provider_ = ResourceProvider::Create(output_surface_.get(),
316 shared_bitmap_manager_.get(),
317 NULL,
318 NULL,
320 false,
323 overlay_processor_.reset(new SingleOverlayProcessor(
324 output_surface_.get(), resource_provider_.get()));
325 overlay_processor_->Initialize();
328 scoped_refptr<TestContextProvider> provider_;
329 scoped_ptr<OverlayOutputSurface> output_surface_;
330 FakeOutputSurfaceClient client_;
331 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
332 scoped_ptr<ResourceProvider> resource_provider_;
333 scoped_ptr<SingleOverlayProcessor> overlay_processor_;
336 TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) {
337 scoped_ptr<RenderPass> pass = CreateRenderPass();
338 TextureDrawQuad* original_quad =
339 CreateFullscreenCandidateQuad(resource_provider_.get(),
340 pass->shared_quad_state_list.back(),
341 pass.get());
342 unsigned original_resource_id = original_quad->resource_id;
344 // Add something behind it.
345 CreateFullscreenCheckeredQuad(resource_provider_.get(),
346 pass->shared_quad_state_list.back(),
347 pass.get());
348 CreateFullscreenCheckeredQuad(resource_provider_.get(),
349 pass->shared_quad_state_list.back(),
350 pass.get());
352 RenderPassList pass_list;
353 pass_list.push_back(pass.Pass());
355 // Check for potential candidates.
356 OverlayCandidateList candidate_list;
357 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
359 ASSERT_EQ(1U, pass_list.size());
360 ASSERT_EQ(2U, candidate_list.size());
362 RenderPass* main_pass = pass_list.back();
363 // Check that the quad is gone.
364 EXPECT_EQ(2U, main_pass->quad_list.size());
365 const QuadList& quad_list = main_pass->quad_list;
366 for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin();
367 it != quad_list.BackToFrontEnd();
368 ++it) {
369 EXPECT_NE(DrawQuad::TEXTURE_CONTENT, it->material);
372 // Check that the right resource id got extracted.
373 EXPECT_EQ(original_resource_id, candidate_list.back().resource_id);
376 TEST_F(SingleOverlayOnTopTest, NoCandidates) {
377 scoped_ptr<RenderPass> pass = CreateRenderPass();
378 CreateFullscreenCheckeredQuad(resource_provider_.get(),
379 pass->shared_quad_state_list.back(),
380 pass.get());
381 CreateFullscreenCheckeredQuad(resource_provider_.get(),
382 pass->shared_quad_state_list.back(),
383 pass.get());
385 RenderPassList pass_list;
386 pass_list.push_back(pass.Pass());
388 RenderPassList original_pass_list;
389 RenderPass::CopyAll(pass_list, &original_pass_list);
391 OverlayCandidateList candidate_list;
392 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
393 EXPECT_EQ(0U, candidate_list.size());
394 // There should be nothing new here.
395 CompareRenderPassLists(pass_list, original_pass_list);
398 TEST_F(SingleOverlayOnTopTest, OccludedCandidates) {
399 scoped_ptr<RenderPass> pass = CreateRenderPass();
400 CreateFullscreenCheckeredQuad(resource_provider_.get(),
401 pass->shared_quad_state_list.back(),
402 pass.get());
403 CreateFullscreenCheckeredQuad(resource_provider_.get(),
404 pass->shared_quad_state_list.back(),
405 pass.get());
407 CreateFullscreenCandidateQuad(resource_provider_.get(),
408 pass->shared_quad_state_list.back(),
409 pass.get());
411 RenderPassList pass_list;
412 pass_list.push_back(pass.Pass());
414 RenderPassList original_pass_list;
415 RenderPass::CopyAll(pass_list, &original_pass_list);
417 OverlayCandidateList candidate_list;
418 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
419 EXPECT_EQ(0U, candidate_list.size());
420 // There should be nothing new here.
421 CompareRenderPassLists(pass_list, original_pass_list);
424 // Test with multiple render passes.
425 TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) {
426 RenderPassList pass_list;
427 pass_list.push_back(CreateRenderPass());
429 scoped_ptr<RenderPass> pass = CreateRenderPass();
430 CreateFullscreenCandidateQuad(resource_provider_.get(),
431 pass->shared_quad_state_list.back(),
432 pass.get());
434 // Add something behind it.
435 CreateFullscreenCheckeredQuad(resource_provider_.get(),
436 pass->shared_quad_state_list.back(),
437 pass.get());
438 CreateFullscreenCheckeredQuad(resource_provider_.get(),
439 pass->shared_quad_state_list.back(),
440 pass.get());
442 pass_list.push_back(pass.Pass());
444 RenderPassList original_pass_list;
445 RenderPass::CopyAll(pass_list, &original_pass_list);
447 // Check for potential candidates.
448 OverlayCandidateList candidate_list;
449 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
450 EXPECT_EQ(2U, candidate_list.size());
452 // This should be the same.
453 ASSERT_EQ(2U, pass_list.size());
456 TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) {
457 scoped_ptr<RenderPass> pass = CreateRenderPass();
458 TextureDrawQuad* quad =
459 CreateFullscreenCandidateQuad(resource_provider_.get(),
460 pass->shared_quad_state_list.back(),
461 pass.get());
462 quad->premultiplied_alpha = true;
464 RenderPassList pass_list;
465 pass_list.push_back(pass.Pass());
466 OverlayCandidateList candidate_list;
467 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
468 EXPECT_EQ(1U, pass_list.size());
469 EXPECT_EQ(0U, candidate_list.size());
472 TEST_F(SingleOverlayOnTopTest, RejectBlending) {
473 scoped_ptr<RenderPass> pass = CreateRenderPass();
474 TextureDrawQuad* quad =
475 CreateFullscreenCandidateQuad(resource_provider_.get(),
476 pass->shared_quad_state_list.back(),
477 pass.get());
478 quad->needs_blending = true;
480 RenderPassList pass_list;
481 pass_list.push_back(pass.Pass());
482 OverlayCandidateList candidate_list;
483 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
484 ASSERT_EQ(1U, pass_list.size());
485 EXPECT_EQ(0U, candidate_list.size());
488 TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {
489 scoped_ptr<RenderPass> pass = CreateRenderPass();
490 TextureDrawQuad* quad =
491 CreateFullscreenCandidateQuad(resource_provider_.get(),
492 pass->shared_quad_state_list.back(),
493 pass.get());
494 quad->background_color = SK_ColorBLACK;
496 RenderPassList pass_list;
497 pass_list.push_back(pass.Pass());
498 OverlayCandidateList candidate_list;
499 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
500 ASSERT_EQ(1U, pass_list.size());
501 EXPECT_EQ(0U, candidate_list.size());
504 TEST_F(SingleOverlayOnTopTest, RejectBlendMode) {
505 scoped_ptr<RenderPass> pass = CreateRenderPass();
506 CreateFullscreenCandidateQuad(resource_provider_.get(),
507 pass->shared_quad_state_list.back(),
508 pass.get());
509 pass->shared_quad_state_list.back()->blend_mode = SkXfermode::kScreen_Mode;
511 RenderPassList pass_list;
512 pass_list.push_back(pass.Pass());
513 OverlayCandidateList candidate_list;
514 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
515 ASSERT_EQ(1U, pass_list.size());
516 EXPECT_EQ(0U, candidate_list.size());
519 TEST_F(SingleOverlayOnTopTest, RejectOpacity) {
520 scoped_ptr<RenderPass> pass = CreateRenderPass();
521 CreateFullscreenCandidateQuad(resource_provider_.get(),
522 pass->shared_quad_state_list.back(),
523 pass.get());
524 pass->shared_quad_state_list.back()->opacity = 0.5f;
526 RenderPassList pass_list;
527 pass_list.push_back(pass.Pass());
528 OverlayCandidateList candidate_list;
529 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
530 ASSERT_EQ(1U, pass_list.size());
531 EXPECT_EQ(0U, candidate_list.size());
534 TEST_F(SingleOverlayOnTopTest, RejectNonScaleTransform) {
535 scoped_ptr<RenderPass> pass = CreateRenderPass();
536 CreateFullscreenCandidateQuad(resource_provider_.get(),
537 pass->shared_quad_state_list.back(),
538 pass.get());
539 pass->shared_quad_state_list.back()
540 ->content_to_target_transform.RotateAboutXAxis(45.f);
542 RenderPassList pass_list;
543 pass_list.push_back(pass.Pass());
544 OverlayCandidateList candidate_list;
545 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
546 ASSERT_EQ(1U, pass_list.size());
547 EXPECT_EQ(0U, candidate_list.size());
550 TEST_F(SingleOverlayOnTopTest, RejectNegativeScaleTransform) {
551 scoped_ptr<RenderPass> pass = CreateRenderPass();
552 CreateFullscreenCandidateQuad(resource_provider_.get(),
553 pass->shared_quad_state_list.back(),
554 pass.get());
555 pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f,
556 -1.0f);
558 RenderPassList pass_list;
559 pass_list.push_back(pass.Pass());
560 OverlayCandidateList candidate_list;
561 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
562 ASSERT_EQ(1U, pass_list.size());
563 EXPECT_EQ(0U, candidate_list.size());
566 TEST_F(SingleOverlayOnTopTest, AllowPositiveScaleTransform) {
567 gfx::Rect rect = kOverlayRect;
568 rect.set_width(rect.width() / 2);
569 scoped_ptr<RenderPass> pass = CreateRenderPass();
570 CreateCandidateQuadAt(resource_provider_.get(),
571 pass->shared_quad_state_list.back(), pass.get(), rect);
572 pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f,
573 1.0f);
575 RenderPassList pass_list;
576 pass_list.push_back(pass.Pass());
577 OverlayCandidateList candidate_list;
578 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
579 ASSERT_EQ(1U, pass_list.size());
580 EXPECT_EQ(2U, candidate_list.size());
583 TEST_F(SingleOverlayOnTopTest, AllowNotTopIfNotOccluded) {
584 scoped_ptr<RenderPass> pass = CreateRenderPass();
585 CreateCheckeredQuadAt(resource_provider_.get(),
586 pass->shared_quad_state_list.back(),
587 pass.get(),
588 kOverlayTopLeftRect);
589 CreateCandidateQuadAt(resource_provider_.get(),
590 pass->shared_quad_state_list.back(),
591 pass.get(),
592 kOverlayBottomRightRect);
594 RenderPassList pass_list;
595 pass_list.push_back(pass.Pass());
597 RenderPassList original_pass_list;
598 RenderPass::CopyAll(pass_list, &original_pass_list);
600 OverlayCandidateList candidate_list;
601 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
602 EXPECT_EQ(1U, pass_list.size());
603 EXPECT_EQ(2U, candidate_list.size());
606 TEST_F(SingleOverlayOnTopTest, AllowTransparentOnTop) {
607 scoped_ptr<RenderPass> pass = CreateRenderPass();
608 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
609 shared_state->opacity = 0.f;
610 CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(),
611 kOverlayBottomRightRect);
612 shared_state = pass->CreateAndAppendSharedQuadState();
613 shared_state->opacity = 1.f;
614 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
615 kOverlayBottomRightRect);
617 RenderPassList pass_list;
618 pass_list.push_back(pass.Pass());
620 RenderPassList original_pass_list;
621 RenderPass::CopyAll(pass_list, &original_pass_list);
623 OverlayCandidateList candidate_list;
624 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
625 EXPECT_EQ(1U, pass_list.size());
626 EXPECT_EQ(2U, candidate_list.size());
629 TEST_F(SingleOverlayOnTopTest, AllowTransparentColorOnTop) {
630 scoped_ptr<RenderPass> pass = CreateRenderPass();
631 CreateSolidColorQuadAt(pass->shared_quad_state_list.back(),
632 SK_ColorTRANSPARENT, pass.get(),
633 kOverlayBottomRightRect);
634 CreateCandidateQuadAt(resource_provider_.get(),
635 pass->shared_quad_state_list.back(), pass.get(),
636 kOverlayBottomRightRect);
638 RenderPassList pass_list;
639 pass_list.push_back(pass.Pass());
641 RenderPassList original_pass_list;
642 RenderPass::CopyAll(pass_list, &original_pass_list);
644 OverlayCandidateList candidate_list;
645 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
646 EXPECT_EQ(1U, pass_list.size());
647 EXPECT_EQ(2U, candidate_list.size());
650 TEST_F(SingleOverlayOnTopTest, RejectOpaqueColorOnTop) {
651 scoped_ptr<RenderPass> pass = CreateRenderPass();
652 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
653 shared_state->opacity = 0.5f;
654 CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(),
655 kOverlayBottomRightRect);
656 shared_state = pass->CreateAndAppendSharedQuadState();
657 shared_state->opacity = 1.f;
658 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
659 kOverlayBottomRightRect);
661 RenderPassList pass_list;
662 pass_list.push_back(pass.Pass());
664 RenderPassList original_pass_list;
665 RenderPass::CopyAll(pass_list, &original_pass_list);
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, RejectTransparentColorOnTopWithoutBlending) {
674 scoped_ptr<RenderPass> pass = CreateRenderPass();
675 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
676 CreateSolidColorQuadAt(shared_state, SK_ColorTRANSPARENT, pass.get(),
677 kOverlayBottomRightRect)->opaque_rect =
678 kOverlayBottomRightRect;
679 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
680 kOverlayBottomRightRect);
682 RenderPassList pass_list;
683 pass_list.push_back(pass.Pass());
685 RenderPassList original_pass_list;
686 RenderPass::CopyAll(pass_list, &original_pass_list);
688 OverlayCandidateList candidate_list;
689 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
690 EXPECT_EQ(1U, pass_list.size());
691 EXPECT_EQ(0U, candidate_list.size());
694 TEST_F(SingleOverlayOnTopTest, RejectVideoSwapTransform) {
695 scoped_ptr<RenderPass> pass = CreateRenderPass();
696 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
697 pass->shared_quad_state_list.back(),
698 pass.get(), kSwapTransform);
700 RenderPassList pass_list;
701 pass_list.push_back(pass.Pass());
702 OverlayCandidateList candidate_list;
703 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
704 ASSERT_EQ(1U, pass_list.size());
705 EXPECT_EQ(0U, candidate_list.size());
708 TEST_F(SingleOverlayOnTopTest, AllowVideoXMirrorTransform) {
709 scoped_ptr<RenderPass> pass = CreateRenderPass();
710 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
711 pass->shared_quad_state_list.back(),
712 pass.get(), kXMirrorTransform);
714 RenderPassList pass_list;
715 pass_list.push_back(pass.Pass());
716 OverlayCandidateList candidate_list;
717 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
718 ASSERT_EQ(1U, pass_list.size());
719 EXPECT_EQ(2U, candidate_list.size());
722 TEST_F(SingleOverlayOnTopTest, AllowVideoBothMirrorTransform) {
723 scoped_ptr<RenderPass> pass = CreateRenderPass();
724 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
725 pass->shared_quad_state_list.back(),
726 pass.get(), kBothMirrorTransform);
728 RenderPassList pass_list;
729 pass_list.push_back(pass.Pass());
730 OverlayCandidateList candidate_list;
731 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
732 ASSERT_EQ(1U, pass_list.size());
733 EXPECT_EQ(2U, candidate_list.size());
736 TEST_F(SingleOverlayOnTopTest, AllowVideoNormalTransform) {
737 scoped_ptr<RenderPass> pass = CreateRenderPass();
738 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
739 pass->shared_quad_state_list.back(),
740 pass.get(), kNormalTransform);
742 RenderPassList pass_list;
743 pass_list.push_back(pass.Pass());
744 OverlayCandidateList candidate_list;
745 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
746 ASSERT_EQ(1U, pass_list.size());
747 EXPECT_EQ(2U, candidate_list.size());
750 TEST_F(SingleOverlayOnTopTest, AllowVideoYMirrorTransform) {
751 scoped_ptr<RenderPass> pass = CreateRenderPass();
752 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
753 pass->shared_quad_state_list.back(),
754 pass.get(), kYMirrorTransform);
756 RenderPassList pass_list;
757 pass_list.push_back(pass.Pass());
758 OverlayCandidateList candidate_list;
759 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
760 ASSERT_EQ(1U, pass_list.size());
761 EXPECT_EQ(2U, candidate_list.size());
764 class OverlayInfoRendererGL : public GLRenderer {
765 public:
766 OverlayInfoRendererGL(RendererClient* client,
767 const RendererSettings* settings,
768 OutputSurface* output_surface,
769 ResourceProvider* resource_provider)
770 : GLRenderer(client,
771 settings,
772 output_surface,
773 resource_provider,
774 NULL,
776 expect_overlays_(false) {}
778 MOCK_METHOD2(DoDrawQuad, void(DrawingFrame* frame, const DrawQuad* quad));
780 using GLRenderer::BeginDrawingFrame;
782 void FinishDrawingFrame(DrawingFrame* frame) override {
783 GLRenderer::FinishDrawingFrame(frame);
785 if (!expect_overlays_) {
786 EXPECT_EQ(0U, frame->overlay_list.size());
787 return;
790 ASSERT_EQ(2U, frame->overlay_list.size());
791 EXPECT_NE(0U, frame->overlay_list.back().resource_id);
794 void set_expect_overlays(bool expect_overlays) {
795 expect_overlays_ = expect_overlays;
798 private:
799 bool expect_overlays_;
802 class FakeRendererClient : public RendererClient {
803 public:
804 // RendererClient methods.
805 void SetFullRootLayerDamage() override {}
808 class MockOverlayScheduler {
809 public:
810 MOCK_METHOD5(Schedule,
811 void(int plane_z_order,
812 gfx::OverlayTransform plane_transform,
813 unsigned overlay_texture_id,
814 const gfx::Rect& display_bounds,
815 const gfx::RectF& uv_rect));
818 class GLRendererWithOverlaysTest : public testing::Test {
819 protected:
820 GLRendererWithOverlaysTest() {
821 provider_ = TestContextProvider::Create();
822 output_surface_.reset(new OverlayOutputSurface(provider_));
823 CHECK(output_surface_->BindToClient(&output_surface_client_));
824 resource_provider_ = ResourceProvider::Create(
825 output_surface_.get(), NULL, NULL, NULL, 0, false, 1);
827 provider_->support()->SetScheduleOverlayPlaneCallback(base::Bind(
828 &MockOverlayScheduler::Schedule, base::Unretained(&scheduler_)));
831 void Init(bool use_validator) {
832 if (use_validator)
833 output_surface_->InitWithSingleOverlayValidator();
835 renderer_ =
836 make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_,
837 &settings_,
838 output_surface_.get(),
839 resource_provider_.get()));
842 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
844 RendererSettings settings_;
845 FakeOutputSurfaceClient output_surface_client_;
846 scoped_ptr<OverlayOutputSurface> output_surface_;
847 FakeRendererClient renderer_client_;
848 scoped_ptr<ResourceProvider> resource_provider_;
849 scoped_ptr<OverlayInfoRendererGL> renderer_;
850 scoped_refptr<TestContextProvider> provider_;
851 MockOverlayScheduler scheduler_;
854 TEST_F(GLRendererWithOverlaysTest, OverlayQuadNotDrawn) {
855 bool use_validator = true;
856 Init(use_validator);
857 renderer_->set_expect_overlays(true);
858 gfx::Rect viewport_rect(16, 16);
860 scoped_ptr<RenderPass> pass = CreateRenderPass();
862 CreateFullscreenCandidateQuad(resource_provider_.get(),
863 pass->shared_quad_state_list.back(),
864 pass.get());
866 CreateFullscreenCheckeredQuad(resource_provider_.get(),
867 pass->shared_quad_state_list.back(),
868 pass.get());
869 CreateFullscreenCheckeredQuad(resource_provider_.get(),
870 pass->shared_quad_state_list.back(),
871 pass.get());
873 RenderPassList pass_list;
874 pass_list.push_back(pass.Pass());
876 // Candidate pass was taken out and extra skipped pass added,
877 // so only draw 2 quads.
878 EXPECT_CALL(*renderer_, DoDrawQuad(_, _)).Times(2);
879 EXPECT_CALL(scheduler_,
880 Schedule(1,
881 gfx::OVERLAY_TRANSFORM_NONE,
883 kOverlayRect,
884 BoundingRect(kUVTopLeft, kUVBottomRight))).Times(1);
885 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
887 SwapBuffers();
889 Mock::VerifyAndClearExpectations(renderer_.get());
890 Mock::VerifyAndClearExpectations(&scheduler_);
893 TEST_F(GLRendererWithOverlaysTest, OccludedQuadDrawn) {
894 bool use_validator = true;
895 Init(use_validator);
896 renderer_->set_expect_overlays(false);
897 gfx::Rect viewport_rect(16, 16);
899 scoped_ptr<RenderPass> pass = CreateRenderPass();
901 CreateFullscreenCheckeredQuad(resource_provider_.get(),
902 pass->shared_quad_state_list.back(),
903 pass.get());
904 CreateFullscreenCheckeredQuad(resource_provider_.get(),
905 pass->shared_quad_state_list.back(),
906 pass.get());
908 CreateFullscreenCandidateQuad(resource_provider_.get(),
909 pass->shared_quad_state_list.back(),
910 pass.get());
912 RenderPassList pass_list;
913 pass_list.push_back(pass.Pass());
915 // 3 quads in the pass, all should draw.
916 EXPECT_CALL(*renderer_, DoDrawQuad(_, _)).Times(3);
917 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
918 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
920 SwapBuffers();
922 Mock::VerifyAndClearExpectations(renderer_.get());
923 Mock::VerifyAndClearExpectations(&scheduler_);
926 TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) {
927 bool use_validator = false;
928 Init(use_validator);
929 renderer_->set_expect_overlays(false);
930 gfx::Rect viewport_rect(16, 16);
932 scoped_ptr<RenderPass> pass = CreateRenderPass();
934 CreateFullscreenCandidateQuad(resource_provider_.get(),
935 pass->shared_quad_state_list.back(),
936 pass.get());
938 CreateFullscreenCheckeredQuad(resource_provider_.get(),
939 pass->shared_quad_state_list.back(),
940 pass.get());
941 CreateFullscreenCheckeredQuad(resource_provider_.get(),
942 pass->shared_quad_state_list.back(),
943 pass.get());
945 RenderPassList pass_list;
946 pass_list.push_back(pass.Pass());
948 // Should see no overlays.
949 EXPECT_CALL(*renderer_, DoDrawQuad(_, _)).Times(3);
950 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
951 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
953 SwapBuffers();
955 Mock::VerifyAndClearExpectations(renderer_.get());
956 Mock::VerifyAndClearExpectations(&scheduler_);
959 TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturned) {
960 bool use_validator = true;
961 Init(use_validator);
962 renderer_->set_expect_overlays(true);
964 ResourceProvider::ResourceId resource1 =
965 CreateResource(resource_provider_.get());
966 ResourceProvider::ResourceId resource2 =
967 CreateResource(resource_provider_.get());
969 scoped_ptr<RenderPass> pass = CreateRenderPass();
970 RenderPassList pass_list;
971 pass_list.push_back(pass.Pass());
973 DirectRenderer::DrawingFrame frame1;
974 frame1.render_passes_in_draw_order = &pass_list;
975 frame1.overlay_list.resize(2);
976 OverlayCandidate& overlay1 = frame1.overlay_list.back();
977 overlay1.resource_id = resource1;
978 overlay1.plane_z_order = 1;
980 DirectRenderer::DrawingFrame frame2;
981 frame2.render_passes_in_draw_order = &pass_list;
982 frame2.overlay_list.resize(2);
983 OverlayCandidate& overlay2 = frame2.overlay_list.back();
984 overlay2.resource_id = resource2;
985 overlay2.plane_z_order = 1;
987 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
988 renderer_->BeginDrawingFrame(&frame1);
989 renderer_->FinishDrawingFrame(&frame1);
990 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
991 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
992 SwapBuffers();
993 Mock::VerifyAndClearExpectations(&scheduler_);
995 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
996 renderer_->BeginDrawingFrame(&frame2);
997 renderer_->FinishDrawingFrame(&frame2);
998 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
999 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
1000 SwapBuffers();
1001 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1002 Mock::VerifyAndClearExpectations(&scheduler_);
1004 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1005 renderer_->BeginDrawingFrame(&frame1);
1006 renderer_->FinishDrawingFrame(&frame1);
1007 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1008 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
1009 SwapBuffers();
1010 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
1011 Mock::VerifyAndClearExpectations(&scheduler_);
1013 // No overlays, release the resource.
1014 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
1015 DirectRenderer::DrawingFrame frame3;
1016 frame3.render_passes_in_draw_order = &pass_list;
1017 renderer_->set_expect_overlays(false);
1018 renderer_->BeginDrawingFrame(&frame3);
1019 renderer_->FinishDrawingFrame(&frame3);
1020 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1021 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
1022 SwapBuffers();
1023 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1024 Mock::VerifyAndClearExpectations(&scheduler_);
1026 // Use the same buffer twice.
1027 renderer_->set_expect_overlays(true);
1028 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1029 renderer_->BeginDrawingFrame(&frame1);
1030 renderer_->FinishDrawingFrame(&frame1);
1031 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1032 SwapBuffers();
1033 Mock::VerifyAndClearExpectations(&scheduler_);
1035 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1036 renderer_->BeginDrawingFrame(&frame1);
1037 renderer_->FinishDrawingFrame(&frame1);
1038 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1039 SwapBuffers();
1040 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1041 Mock::VerifyAndClearExpectations(&scheduler_);
1043 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
1044 renderer_->set_expect_overlays(false);
1045 renderer_->BeginDrawingFrame(&frame3);
1046 renderer_->FinishDrawingFrame(&frame3);
1047 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1048 SwapBuffers();
1049 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1050 Mock::VerifyAndClearExpectations(&scheduler_);
1053 } // namespace
1054 } // namespace cc