Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / cc / output / overlay_unittest.cc
blob545b5f54eb368d6bd809ed5480ba1252880df188
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_single_on_top.h"
13 #include "cc/output/overlay_strategy_underlay.h"
14 #include "cc/quads/checkerboard_draw_quad.h"
15 #include "cc/quads/render_pass.h"
16 #include "cc/quads/stream_video_draw_quad.h"
17 #include "cc/quads/texture_draw_quad.h"
18 #include "cc/resources/resource_provider.h"
19 #include "cc/resources/texture_mailbox.h"
20 #include "cc/test/fake_output_surface_client.h"
21 #include "cc/test/geometry_test_utils.h"
22 #include "cc/test/test_context_provider.h"
23 #include "cc/test/test_shared_bitmap_manager.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 using testing::_;
28 using testing::Mock;
30 namespace cc {
31 namespace {
33 const gfx::Rect kOverlayRect(0, 0, 128, 128);
34 const gfx::Rect kOverlayTopLeftRect(0, 0, 64, 64);
35 const gfx::Rect kOverlayBottomRightRect(64, 64, 64, 64);
36 const gfx::PointF kUVTopLeft(0.1f, 0.2f);
37 const gfx::PointF kUVBottomRight(1.0f, 1.0f);
38 const gfx::Transform kNormalTransform =
39 gfx::Transform(0.9f, 0, 0, 0.8f, 0.1f, 0.2f); // x,y -> x,y.
40 const gfx::Transform kXMirrorTransform =
41 gfx::Transform(-0.9f, 0, 0, 0.8f, 1.0f, 0.2f); // x,y -> 1-x,y.
42 const gfx::Transform kYMirrorTransform =
43 gfx::Transform(0.9f, 0, 0, -0.8f, 0.1f, 1.0f); // x,y -> x,1-y.
44 const gfx::Transform kBothMirrorTransform =
45 gfx::Transform(-0.9f, 0, 0, -0.8f, 1.0f, 1.0f); // x,y -> 1-x,1-y.
46 const gfx::Transform kSwapTransform =
47 gfx::Transform(0, 1, 1, 0, 0, 0); // x,y -> y,x.
49 void MailboxReleased(unsigned sync_point,
50 bool lost_resource,
51 BlockingTaskRunner* main_thread_task_runner) {
54 class SingleOverlayValidator : public OverlayCandidateValidator {
55 public:
56 void CheckOverlaySupport(OverlayCandidateList* surfaces) override;
59 void SingleOverlayValidator::CheckOverlaySupport(
60 OverlayCandidateList* surfaces) {
61 ASSERT_EQ(2U, surfaces->size());
63 OverlayCandidate& candidate = surfaces->back();
64 if (candidate.display_rect.width() == 64)
65 EXPECT_EQ(kOverlayBottomRightRect, candidate.display_rect);
66 else
67 EXPECT_EQ(kOverlayRect, candidate.display_rect);
68 EXPECT_EQ(BoundingRect(kUVTopLeft, kUVBottomRight).ToString(),
69 candidate.uv_rect.ToString());
70 candidate.overlay_handled = true;
73 template <typename OverlayStrategyType>
74 class SingleOverlayProcessor : public OverlayProcessor {
75 public:
76 SingleOverlayProcessor(OutputSurface* surface,
77 ResourceProvider* resource_provider)
78 : OverlayProcessor(surface, resource_provider) {
79 EXPECT_EQ(surface, surface_);
80 EXPECT_EQ(resource_provider, resource_provider_);
83 // Virtual to allow testing different strategies.
84 void Initialize() override {
85 OverlayCandidateValidator* candidates =
86 surface_->GetOverlayCandidateValidator();
87 ASSERT_TRUE(candidates != NULL);
88 strategies_.push_back(scoped_ptr<Strategy>(
89 new OverlayStrategyType(candidates, resource_provider_)));
93 class DefaultOverlayProcessor : public OverlayProcessor {
94 public:
95 DefaultOverlayProcessor(OutputSurface* surface,
96 ResourceProvider* resource_provider);
97 size_t GetStrategyCount();
100 DefaultOverlayProcessor::DefaultOverlayProcessor(
101 OutputSurface* surface,
102 ResourceProvider* resource_provider)
103 : OverlayProcessor(surface, resource_provider) {}
105 size_t DefaultOverlayProcessor::GetStrategyCount() {
106 return strategies_.size();
109 class OverlayOutputSurface : public OutputSurface {
110 public:
111 explicit OverlayOutputSurface(scoped_refptr<ContextProvider> context_provider)
112 : OutputSurface(context_provider) {}
114 // OutputSurface implementation
115 void SwapBuffers(CompositorFrame* frame) override;
117 void InitWithSingleOverlayValidator() {
118 overlay_candidate_validator_.reset(new SingleOverlayValidator);
121 OverlayCandidateValidator* GetOverlayCandidateValidator() const override {
122 return overlay_candidate_validator_.get();
125 private:
126 scoped_ptr<OverlayCandidateValidator> overlay_candidate_validator_;
129 void OverlayOutputSurface::SwapBuffers(CompositorFrame* frame) {
130 client_->DidSwapBuffers();
131 client_->DidSwapBuffersComplete();
134 scoped_ptr<RenderPass> CreateRenderPass() {
135 RenderPassId id(1, 0);
136 gfx::Rect output_rect(0, 0, 256, 256);
137 bool has_transparent_background = true;
139 scoped_ptr<RenderPass> pass = RenderPass::Create();
140 pass->SetAll(id,
141 output_rect,
142 output_rect,
143 gfx::Transform(),
144 has_transparent_background);
146 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
147 shared_state->opacity = 1.f;
148 return pass.Pass();
151 ResourceProvider::ResourceId CreateResource(
152 ResourceProvider* resource_provider) {
153 unsigned sync_point = 0;
154 TextureMailbox mailbox =
155 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
156 mailbox.set_allow_overlay(true);
157 scoped_ptr<SingleReleaseCallbackImpl> release_callback =
158 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
160 return resource_provider->CreateResourceFromTextureMailbox(
161 mailbox, release_callback.Pass());
164 SolidColorDrawQuad* CreateSolidColorQuadAt(
165 const SharedQuadState* shared_quad_state,
166 SkColor color,
167 RenderPass* render_pass,
168 const gfx::Rect& rect) {
169 SolidColorDrawQuad* quad =
170 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
171 quad->SetNew(shared_quad_state, rect, rect, color, false);
172 return quad;
175 TextureDrawQuad* CreateCandidateQuadAt(ResourceProvider* resource_provider,
176 const SharedQuadState* shared_quad_state,
177 RenderPass* render_pass,
178 const gfx::Rect& rect) {
179 ResourceProvider::ResourceId resource_id = CreateResource(resource_provider);
180 bool premultiplied_alpha = false;
181 bool flipped = false;
182 bool nearest_neighbor = false;
183 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
185 TextureDrawQuad* overlay_quad =
186 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
187 overlay_quad->SetNew(shared_quad_state,
188 rect,
189 rect,
190 rect,
191 resource_id,
192 premultiplied_alpha,
193 kUVTopLeft,
194 kUVBottomRight,
195 SK_ColorTRANSPARENT,
196 vertex_opacity,
197 flipped,
198 nearest_neighbor);
200 return overlay_quad;
203 StreamVideoDrawQuad* CreateCandidateVideoQuadAt(
204 ResourceProvider* resource_provider,
205 const SharedQuadState* shared_quad_state,
206 RenderPass* render_pass,
207 const gfx::Rect& rect,
208 const gfx::Transform& transform) {
209 ResourceProvider::ResourceId resource_id = CreateResource(resource_provider);
211 StreamVideoDrawQuad* overlay_quad =
212 render_pass->CreateAndAppendDrawQuad<StreamVideoDrawQuad>();
213 overlay_quad->SetNew(shared_quad_state, rect, rect, rect, resource_id,
214 transform);
216 return overlay_quad;
219 TextureDrawQuad* CreateFullscreenCandidateQuad(
220 ResourceProvider* resource_provider,
221 const SharedQuadState* shared_quad_state,
222 RenderPass* render_pass) {
223 return CreateCandidateQuadAt(
224 resource_provider, shared_quad_state, render_pass, kOverlayRect);
227 StreamVideoDrawQuad* CreateFullscreenCandidateVideoQuad(
228 ResourceProvider* resource_provider,
229 const SharedQuadState* shared_quad_state,
230 RenderPass* render_pass,
231 const gfx::Transform& transform) {
232 return CreateCandidateVideoQuadAt(resource_provider, shared_quad_state,
233 render_pass, kOverlayRect, transform);
236 void CreateCheckeredQuadAt(ResourceProvider* resource_provider,
237 const SharedQuadState* shared_quad_state,
238 RenderPass* render_pass,
239 const gfx::Rect& rect) {
240 CheckerboardDrawQuad* checkerboard_quad =
241 render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
242 checkerboard_quad->SetNew(shared_quad_state, rect, rect, SkColor(), 1.f);
245 void CreateFullscreenCheckeredQuad(ResourceProvider* resource_provider,
246 const SharedQuadState* shared_quad_state,
247 RenderPass* render_pass) {
248 CreateCheckeredQuadAt(
249 resource_provider, shared_quad_state, render_pass, kOverlayRect);
252 static void CompareRenderPassLists(const RenderPassList& expected_list,
253 const RenderPassList& actual_list) {
254 EXPECT_EQ(expected_list.size(), actual_list.size());
255 for (size_t i = 0; i < actual_list.size(); ++i) {
256 RenderPass* expected = expected_list[i];
257 RenderPass* actual = actual_list[i];
259 EXPECT_EQ(expected->id, actual->id);
260 EXPECT_EQ(expected->output_rect, actual->output_rect);
261 EXPECT_EQ(expected->transform_to_root_target,
262 actual->transform_to_root_target);
263 EXPECT_EQ(expected->damage_rect, actual->damage_rect);
264 EXPECT_EQ(expected->has_transparent_background,
265 actual->has_transparent_background);
267 EXPECT_EQ(expected->shared_quad_state_list.size(),
268 actual->shared_quad_state_list.size());
269 EXPECT_EQ(expected->quad_list.size(), actual->quad_list.size());
271 for (auto exp_iter = expected->quad_list.cbegin(),
272 act_iter = actual->quad_list.cbegin();
273 exp_iter != expected->quad_list.cend();
274 ++exp_iter, ++act_iter) {
275 EXPECT_EQ(exp_iter->rect.ToString(), act_iter->rect.ToString());
276 EXPECT_EQ(exp_iter->shared_quad_state->content_bounds.ToString(),
277 act_iter->shared_quad_state->content_bounds.ToString());
282 TEST(OverlayTest, NoOverlaysByDefault) {
283 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
284 OverlayOutputSurface output_surface(provider);
285 EXPECT_EQ(NULL, output_surface.GetOverlayCandidateValidator());
287 output_surface.InitWithSingleOverlayValidator();
288 EXPECT_TRUE(output_surface.GetOverlayCandidateValidator() != NULL);
291 TEST(OverlayTest, OverlaysProcessorHasStrategy) {
292 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
293 OverlayOutputSurface output_surface(provider);
294 FakeOutputSurfaceClient client;
295 EXPECT_TRUE(output_surface.BindToClient(&client));
296 output_surface.InitWithSingleOverlayValidator();
297 EXPECT_TRUE(output_surface.GetOverlayCandidateValidator() != NULL);
299 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
300 new TestSharedBitmapManager());
301 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
302 &output_surface, shared_bitmap_manager.get(), NULL, NULL, 0, false, 1));
304 scoped_ptr<DefaultOverlayProcessor> overlay_processor(
305 new DefaultOverlayProcessor(&output_surface, resource_provider.get()));
306 overlay_processor->Initialize();
307 EXPECT_GE(1U, overlay_processor->GetStrategyCount());
310 template <typename OverlayStrategyType>
311 class OverlayTest : public testing::Test {
312 protected:
313 void SetUp() override {
314 provider_ = TestContextProvider::Create();
315 output_surface_.reset(new OverlayOutputSurface(provider_));
316 EXPECT_TRUE(output_surface_->BindToClient(&client_));
317 output_surface_->InitWithSingleOverlayValidator();
318 EXPECT_TRUE(output_surface_->GetOverlayCandidateValidator() != NULL);
320 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
321 resource_provider_ = ResourceProvider::Create(output_surface_.get(),
322 shared_bitmap_manager_.get(),
323 NULL,
324 NULL,
326 false,
329 overlay_processor_.reset(new SingleOverlayProcessor<OverlayStrategyType>(
330 output_surface_.get(), resource_provider_.get()));
331 overlay_processor_->Initialize();
334 scoped_refptr<TestContextProvider> provider_;
335 scoped_ptr<OverlayOutputSurface> output_surface_;
336 FakeOutputSurfaceClient client_;
337 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
338 scoped_ptr<ResourceProvider> resource_provider_;
339 scoped_ptr<SingleOverlayProcessor<OverlayStrategyType>> overlay_processor_;
342 typedef OverlayTest<OverlayStrategySingleOnTop> SingleOverlayOnTopTest;
343 typedef OverlayTest<OverlayStrategyUnderlay> UnderlayTest;
345 TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) {
346 scoped_ptr<RenderPass> pass = CreateRenderPass();
347 TextureDrawQuad* original_quad =
348 CreateFullscreenCandidateQuad(resource_provider_.get(),
349 pass->shared_quad_state_list.back(),
350 pass.get());
351 unsigned original_resource_id = original_quad->resource_id;
353 // Add something behind it.
354 CreateFullscreenCheckeredQuad(resource_provider_.get(),
355 pass->shared_quad_state_list.back(),
356 pass.get());
357 CreateFullscreenCheckeredQuad(resource_provider_.get(),
358 pass->shared_quad_state_list.back(),
359 pass.get());
361 RenderPassList pass_list;
362 pass_list.push_back(pass.Pass());
364 // Check for potential candidates.
365 OverlayCandidateList candidate_list;
366 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
368 ASSERT_EQ(1U, pass_list.size());
369 ASSERT_EQ(2U, candidate_list.size());
371 RenderPass* main_pass = pass_list.back();
372 // Check that the quad is gone.
373 EXPECT_EQ(2U, main_pass->quad_list.size());
374 const QuadList& quad_list = main_pass->quad_list;
375 for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin();
376 it != quad_list.BackToFrontEnd();
377 ++it) {
378 EXPECT_NE(DrawQuad::TEXTURE_CONTENT, it->material);
381 // Check that the right resource id got extracted.
382 EXPECT_EQ(original_resource_id, candidate_list.back().resource_id);
385 TEST_F(SingleOverlayOnTopTest, NoCandidates) {
386 scoped_ptr<RenderPass> pass = CreateRenderPass();
387 CreateFullscreenCheckeredQuad(resource_provider_.get(),
388 pass->shared_quad_state_list.back(),
389 pass.get());
390 CreateFullscreenCheckeredQuad(resource_provider_.get(),
391 pass->shared_quad_state_list.back(),
392 pass.get());
394 RenderPassList pass_list;
395 pass_list.push_back(pass.Pass());
397 RenderPassList original_pass_list;
398 RenderPass::CopyAll(pass_list, &original_pass_list);
400 OverlayCandidateList candidate_list;
401 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
402 EXPECT_EQ(0U, candidate_list.size());
403 // There should be nothing new here.
404 CompareRenderPassLists(pass_list, original_pass_list);
407 TEST_F(SingleOverlayOnTopTest, OccludedCandidates) {
408 scoped_ptr<RenderPass> pass = CreateRenderPass();
409 CreateFullscreenCheckeredQuad(resource_provider_.get(),
410 pass->shared_quad_state_list.back(),
411 pass.get());
412 CreateFullscreenCheckeredQuad(resource_provider_.get(),
413 pass->shared_quad_state_list.back(),
414 pass.get());
416 CreateFullscreenCandidateQuad(resource_provider_.get(),
417 pass->shared_quad_state_list.back(),
418 pass.get());
420 RenderPassList pass_list;
421 pass_list.push_back(pass.Pass());
423 RenderPassList original_pass_list;
424 RenderPass::CopyAll(pass_list, &original_pass_list);
426 OverlayCandidateList candidate_list;
427 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
428 EXPECT_EQ(0U, candidate_list.size());
429 // There should be nothing new here.
430 CompareRenderPassLists(pass_list, original_pass_list);
433 // Test with multiple render passes.
434 TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) {
435 RenderPassList pass_list;
436 pass_list.push_back(CreateRenderPass());
438 scoped_ptr<RenderPass> pass = CreateRenderPass();
439 CreateFullscreenCandidateQuad(resource_provider_.get(),
440 pass->shared_quad_state_list.back(),
441 pass.get());
443 // Add something behind it.
444 CreateFullscreenCheckeredQuad(resource_provider_.get(),
445 pass->shared_quad_state_list.back(),
446 pass.get());
447 CreateFullscreenCheckeredQuad(resource_provider_.get(),
448 pass->shared_quad_state_list.back(),
449 pass.get());
451 pass_list.push_back(pass.Pass());
453 RenderPassList original_pass_list;
454 RenderPass::CopyAll(pass_list, &original_pass_list);
456 // Check for potential candidates.
457 OverlayCandidateList candidate_list;
458 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
459 EXPECT_EQ(2U, candidate_list.size());
461 // This should be the same.
462 ASSERT_EQ(2U, pass_list.size());
465 TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) {
466 scoped_ptr<RenderPass> pass = CreateRenderPass();
467 TextureDrawQuad* quad =
468 CreateFullscreenCandidateQuad(resource_provider_.get(),
469 pass->shared_quad_state_list.back(),
470 pass.get());
471 quad->premultiplied_alpha = true;
473 RenderPassList pass_list;
474 pass_list.push_back(pass.Pass());
475 OverlayCandidateList candidate_list;
476 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
477 EXPECT_EQ(1U, pass_list.size());
478 EXPECT_EQ(0U, candidate_list.size());
481 TEST_F(SingleOverlayOnTopTest, RejectBlending) {
482 scoped_ptr<RenderPass> pass = CreateRenderPass();
483 TextureDrawQuad* quad =
484 CreateFullscreenCandidateQuad(resource_provider_.get(),
485 pass->shared_quad_state_list.back(),
486 pass.get());
487 quad->needs_blending = true;
489 RenderPassList pass_list;
490 pass_list.push_back(pass.Pass());
491 OverlayCandidateList candidate_list;
492 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
493 ASSERT_EQ(1U, pass_list.size());
494 EXPECT_EQ(0U, candidate_list.size());
497 TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {
498 scoped_ptr<RenderPass> pass = CreateRenderPass();
499 TextureDrawQuad* quad =
500 CreateFullscreenCandidateQuad(resource_provider_.get(),
501 pass->shared_quad_state_list.back(),
502 pass.get());
503 quad->background_color = SK_ColorBLACK;
505 RenderPassList pass_list;
506 pass_list.push_back(pass.Pass());
507 OverlayCandidateList candidate_list;
508 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
509 ASSERT_EQ(1U, pass_list.size());
510 EXPECT_EQ(0U, candidate_list.size());
513 TEST_F(SingleOverlayOnTopTest, RejectBlendMode) {
514 scoped_ptr<RenderPass> pass = CreateRenderPass();
515 CreateFullscreenCandidateQuad(resource_provider_.get(),
516 pass->shared_quad_state_list.back(),
517 pass.get());
518 pass->shared_quad_state_list.back()->blend_mode = SkXfermode::kScreen_Mode;
520 RenderPassList pass_list;
521 pass_list.push_back(pass.Pass());
522 OverlayCandidateList candidate_list;
523 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
524 ASSERT_EQ(1U, pass_list.size());
525 EXPECT_EQ(0U, candidate_list.size());
528 TEST_F(SingleOverlayOnTopTest, RejectOpacity) {
529 scoped_ptr<RenderPass> pass = CreateRenderPass();
530 CreateFullscreenCandidateQuad(resource_provider_.get(),
531 pass->shared_quad_state_list.back(),
532 pass.get());
533 pass->shared_quad_state_list.back()->opacity = 0.5f;
535 RenderPassList pass_list;
536 pass_list.push_back(pass.Pass());
537 OverlayCandidateList candidate_list;
538 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
539 ASSERT_EQ(1U, pass_list.size());
540 EXPECT_EQ(0U, candidate_list.size());
543 TEST_F(SingleOverlayOnTopTest, RejectNonScaleTransform) {
544 scoped_ptr<RenderPass> pass = CreateRenderPass();
545 CreateFullscreenCandidateQuad(resource_provider_.get(),
546 pass->shared_quad_state_list.back(),
547 pass.get());
548 pass->shared_quad_state_list.back()
549 ->content_to_target_transform.RotateAboutXAxis(45.f);
551 RenderPassList pass_list;
552 pass_list.push_back(pass.Pass());
553 OverlayCandidateList candidate_list;
554 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
555 ASSERT_EQ(1U, pass_list.size());
556 EXPECT_EQ(0U, candidate_list.size());
559 TEST_F(SingleOverlayOnTopTest, RejectNegativeScaleTransform) {
560 scoped_ptr<RenderPass> pass = CreateRenderPass();
561 CreateFullscreenCandidateQuad(resource_provider_.get(),
562 pass->shared_quad_state_list.back(),
563 pass.get());
564 pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f,
565 -1.0f);
567 RenderPassList pass_list;
568 pass_list.push_back(pass.Pass());
569 OverlayCandidateList candidate_list;
570 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
571 ASSERT_EQ(1U, pass_list.size());
572 EXPECT_EQ(0U, candidate_list.size());
575 TEST_F(SingleOverlayOnTopTest, AllowPositiveScaleTransform) {
576 gfx::Rect rect = kOverlayRect;
577 rect.set_width(rect.width() / 2);
578 scoped_ptr<RenderPass> pass = CreateRenderPass();
579 CreateCandidateQuadAt(resource_provider_.get(),
580 pass->shared_quad_state_list.back(), pass.get(), rect);
581 pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f,
582 1.0f);
584 RenderPassList pass_list;
585 pass_list.push_back(pass.Pass());
586 OverlayCandidateList candidate_list;
587 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
588 ASSERT_EQ(1U, pass_list.size());
589 EXPECT_EQ(2U, candidate_list.size());
592 TEST_F(SingleOverlayOnTopTest, AllowNotTopIfNotOccluded) {
593 scoped_ptr<RenderPass> pass = CreateRenderPass();
594 CreateCheckeredQuadAt(resource_provider_.get(),
595 pass->shared_quad_state_list.back(),
596 pass.get(),
597 kOverlayTopLeftRect);
598 CreateCandidateQuadAt(resource_provider_.get(),
599 pass->shared_quad_state_list.back(),
600 pass.get(),
601 kOverlayBottomRightRect);
603 RenderPassList pass_list;
604 pass_list.push_back(pass.Pass());
606 RenderPassList original_pass_list;
607 RenderPass::CopyAll(pass_list, &original_pass_list);
609 OverlayCandidateList candidate_list;
610 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
611 EXPECT_EQ(1U, pass_list.size());
612 EXPECT_EQ(2U, candidate_list.size());
615 TEST_F(SingleOverlayOnTopTest, AllowTransparentOnTop) {
616 scoped_ptr<RenderPass> pass = CreateRenderPass();
617 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
618 shared_state->opacity = 0.f;
619 CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(),
620 kOverlayBottomRightRect);
621 shared_state = pass->CreateAndAppendSharedQuadState();
622 shared_state->opacity = 1.f;
623 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
624 kOverlayBottomRightRect);
626 RenderPassList pass_list;
627 pass_list.push_back(pass.Pass());
629 RenderPassList original_pass_list;
630 RenderPass::CopyAll(pass_list, &original_pass_list);
632 OverlayCandidateList candidate_list;
633 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
634 EXPECT_EQ(1U, pass_list.size());
635 EXPECT_EQ(2U, candidate_list.size());
638 TEST_F(SingleOverlayOnTopTest, AllowTransparentColorOnTop) {
639 scoped_ptr<RenderPass> pass = CreateRenderPass();
640 CreateSolidColorQuadAt(pass->shared_quad_state_list.back(),
641 SK_ColorTRANSPARENT, pass.get(),
642 kOverlayBottomRightRect);
643 CreateCandidateQuadAt(resource_provider_.get(),
644 pass->shared_quad_state_list.back(), pass.get(),
645 kOverlayBottomRightRect);
647 RenderPassList pass_list;
648 pass_list.push_back(pass.Pass());
650 RenderPassList original_pass_list;
651 RenderPass::CopyAll(pass_list, &original_pass_list);
653 OverlayCandidateList candidate_list;
654 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
655 EXPECT_EQ(1U, pass_list.size());
656 EXPECT_EQ(2U, candidate_list.size());
659 TEST_F(SingleOverlayOnTopTest, RejectOpaqueColorOnTop) {
660 scoped_ptr<RenderPass> pass = CreateRenderPass();
661 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
662 shared_state->opacity = 0.5f;
663 CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(),
664 kOverlayBottomRightRect);
665 shared_state = pass->CreateAndAppendSharedQuadState();
666 shared_state->opacity = 1.f;
667 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
668 kOverlayBottomRightRect);
670 RenderPassList pass_list;
671 pass_list.push_back(pass.Pass());
673 RenderPassList original_pass_list;
674 RenderPass::CopyAll(pass_list, &original_pass_list);
676 OverlayCandidateList candidate_list;
677 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
678 EXPECT_EQ(1U, pass_list.size());
679 EXPECT_EQ(0U, candidate_list.size());
682 TEST_F(SingleOverlayOnTopTest, RejectTransparentColorOnTopWithoutBlending) {
683 scoped_ptr<RenderPass> pass = CreateRenderPass();
684 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
685 CreateSolidColorQuadAt(shared_state, SK_ColorTRANSPARENT, pass.get(),
686 kOverlayBottomRightRect)->opaque_rect =
687 kOverlayBottomRightRect;
688 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
689 kOverlayBottomRightRect);
691 RenderPassList pass_list;
692 pass_list.push_back(pass.Pass());
694 RenderPassList original_pass_list;
695 RenderPass::CopyAll(pass_list, &original_pass_list);
697 OverlayCandidateList candidate_list;
698 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
699 EXPECT_EQ(1U, pass_list.size());
700 EXPECT_EQ(0U, candidate_list.size());
703 TEST_F(SingleOverlayOnTopTest, RejectVideoSwapTransform) {
704 scoped_ptr<RenderPass> pass = CreateRenderPass();
705 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
706 pass->shared_quad_state_list.back(),
707 pass.get(), kSwapTransform);
709 RenderPassList pass_list;
710 pass_list.push_back(pass.Pass());
711 OverlayCandidateList candidate_list;
712 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
713 ASSERT_EQ(1U, pass_list.size());
714 EXPECT_EQ(0U, candidate_list.size());
717 TEST_F(SingleOverlayOnTopTest, AllowVideoXMirrorTransform) {
718 scoped_ptr<RenderPass> pass = CreateRenderPass();
719 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
720 pass->shared_quad_state_list.back(),
721 pass.get(), kXMirrorTransform);
723 RenderPassList pass_list;
724 pass_list.push_back(pass.Pass());
725 OverlayCandidateList candidate_list;
726 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
727 ASSERT_EQ(1U, pass_list.size());
728 EXPECT_EQ(2U, candidate_list.size());
731 TEST_F(SingleOverlayOnTopTest, AllowVideoBothMirrorTransform) {
732 scoped_ptr<RenderPass> pass = CreateRenderPass();
733 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
734 pass->shared_quad_state_list.back(),
735 pass.get(), kBothMirrorTransform);
737 RenderPassList pass_list;
738 pass_list.push_back(pass.Pass());
739 OverlayCandidateList candidate_list;
740 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
741 ASSERT_EQ(1U, pass_list.size());
742 EXPECT_EQ(2U, candidate_list.size());
745 TEST_F(SingleOverlayOnTopTest, AllowVideoNormalTransform) {
746 scoped_ptr<RenderPass> pass = CreateRenderPass();
747 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
748 pass->shared_quad_state_list.back(),
749 pass.get(), kNormalTransform);
751 RenderPassList pass_list;
752 pass_list.push_back(pass.Pass());
753 OverlayCandidateList candidate_list;
754 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
755 ASSERT_EQ(1U, pass_list.size());
756 EXPECT_EQ(2U, candidate_list.size());
759 TEST_F(SingleOverlayOnTopTest, AllowVideoYMirrorTransform) {
760 scoped_ptr<RenderPass> pass = CreateRenderPass();
761 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
762 pass->shared_quad_state_list.back(),
763 pass.get(), kYMirrorTransform);
765 RenderPassList pass_list;
766 pass_list.push_back(pass.Pass());
767 OverlayCandidateList candidate_list;
768 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
769 ASSERT_EQ(1U, pass_list.size());
770 EXPECT_EQ(2U, candidate_list.size());
773 TEST_F(UnderlayTest, OverlayLayerUnderMainLayer) {
774 scoped_ptr<RenderPass> pass = CreateRenderPass();
775 CreateFullscreenCheckeredQuad(resource_provider_.get(),
776 pass->shared_quad_state_list.back(),
777 pass.get());
778 CreateCandidateQuadAt(resource_provider_.get(),
779 pass->shared_quad_state_list.back(), pass.get(),
780 kOverlayBottomRightRect);
782 RenderPassList pass_list;
783 pass_list.push_back(pass.Pass());
785 OverlayCandidateList candidate_list;
786 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
787 EXPECT_EQ(1U, pass_list.size());
788 ASSERT_EQ(2U, candidate_list.size());
789 EXPECT_EQ(0, candidate_list[0].plane_z_order);
790 EXPECT_EQ(-1, candidate_list[1].plane_z_order);
791 EXPECT_EQ(2U, pass_list[0]->quad_list.size());
792 // The overlay quad should have changed to a SOLID_COLOR quad.
793 EXPECT_EQ(pass_list[0]->quad_list.back()->material, DrawQuad::SOLID_COLOR);
796 TEST_F(UnderlayTest, AllowOnTop) {
797 scoped_ptr<RenderPass> pass = CreateRenderPass();
798 CreateFullscreenCandidateQuad(resource_provider_.get(),
799 pass->shared_quad_state_list.back(),
800 pass.get());
801 pass->CreateAndAppendSharedQuadState()->opacity = 0.5f;
802 CreateFullscreenCheckeredQuad(resource_provider_.get(),
803 pass->shared_quad_state_list.back(),
804 pass.get());
806 RenderPassList pass_list;
807 pass_list.push_back(pass.Pass());
809 OverlayCandidateList candidate_list;
810 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
811 EXPECT_EQ(1U, pass_list.size());
812 ASSERT_EQ(2U, candidate_list.size());
813 EXPECT_EQ(0, candidate_list[0].plane_z_order);
814 EXPECT_EQ(-1, candidate_list[1].plane_z_order);
815 // The overlay quad should have changed to a SOLID_COLOR quad.
816 EXPECT_EQ(pass_list[0]->quad_list.front()->material, DrawQuad::SOLID_COLOR);
819 class OverlayInfoRendererGL : public GLRenderer {
820 public:
821 OverlayInfoRendererGL(RendererClient* client,
822 const RendererSettings* settings,
823 OutputSurface* output_surface,
824 ResourceProvider* resource_provider)
825 : GLRenderer(client,
826 settings,
827 output_surface,
828 resource_provider,
829 NULL,
831 expect_overlays_(false) {}
833 MOCK_METHOD3(DoDrawQuad,
834 void(DrawingFrame* frame,
835 const DrawQuad* quad,
836 const gfx::QuadF* draw_region));
838 using GLRenderer::BeginDrawingFrame;
840 void FinishDrawingFrame(DrawingFrame* frame) override {
841 GLRenderer::FinishDrawingFrame(frame);
843 if (!expect_overlays_) {
844 EXPECT_EQ(0U, frame->overlay_list.size());
845 return;
848 ASSERT_EQ(2U, frame->overlay_list.size());
849 EXPECT_NE(0U, frame->overlay_list.back().resource_id);
852 void set_expect_overlays(bool expect_overlays) {
853 expect_overlays_ = expect_overlays;
856 private:
857 bool expect_overlays_;
860 class FakeRendererClient : public RendererClient {
861 public:
862 // RendererClient methods.
863 void SetFullRootLayerDamage() override {}
866 class MockOverlayScheduler {
867 public:
868 MOCK_METHOD5(Schedule,
869 void(int plane_z_order,
870 gfx::OverlayTransform plane_transform,
871 unsigned overlay_texture_id,
872 const gfx::Rect& display_bounds,
873 const gfx::RectF& uv_rect));
876 class GLRendererWithOverlaysTest : public testing::Test {
877 protected:
878 GLRendererWithOverlaysTest() {
879 provider_ = TestContextProvider::Create();
880 output_surface_.reset(new OverlayOutputSurface(provider_));
881 CHECK(output_surface_->BindToClient(&output_surface_client_));
882 resource_provider_ = ResourceProvider::Create(
883 output_surface_.get(), NULL, NULL, NULL, 0, false, 1);
885 provider_->support()->SetScheduleOverlayPlaneCallback(base::Bind(
886 &MockOverlayScheduler::Schedule, base::Unretained(&scheduler_)));
889 void Init(bool use_validator) {
890 if (use_validator)
891 output_surface_->InitWithSingleOverlayValidator();
893 renderer_ =
894 make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_,
895 &settings_,
896 output_surface_.get(),
897 resource_provider_.get()));
900 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
902 RendererSettings settings_;
903 FakeOutputSurfaceClient output_surface_client_;
904 scoped_ptr<OverlayOutputSurface> output_surface_;
905 FakeRendererClient renderer_client_;
906 scoped_ptr<ResourceProvider> resource_provider_;
907 scoped_ptr<OverlayInfoRendererGL> renderer_;
908 scoped_refptr<TestContextProvider> provider_;
909 MockOverlayScheduler scheduler_;
912 TEST_F(GLRendererWithOverlaysTest, OverlayQuadNotDrawn) {
913 bool use_validator = true;
914 Init(use_validator);
915 renderer_->set_expect_overlays(true);
916 gfx::Rect viewport_rect(16, 16);
918 scoped_ptr<RenderPass> pass = CreateRenderPass();
920 CreateFullscreenCandidateQuad(resource_provider_.get(),
921 pass->shared_quad_state_list.back(),
922 pass.get());
924 CreateFullscreenCheckeredQuad(resource_provider_.get(),
925 pass->shared_quad_state_list.back(),
926 pass.get());
927 CreateFullscreenCheckeredQuad(resource_provider_.get(),
928 pass->shared_quad_state_list.back(),
929 pass.get());
931 RenderPassList pass_list;
932 pass_list.push_back(pass.Pass());
934 // Candidate pass was taken out and extra skipped pass added,
935 // so only draw 2 quads.
936 EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(2);
937 EXPECT_CALL(scheduler_,
938 Schedule(1,
939 gfx::OVERLAY_TRANSFORM_NONE,
941 kOverlayRect,
942 BoundingRect(kUVTopLeft, kUVBottomRight))).Times(1);
943 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
945 SwapBuffers();
947 Mock::VerifyAndClearExpectations(renderer_.get());
948 Mock::VerifyAndClearExpectations(&scheduler_);
951 TEST_F(GLRendererWithOverlaysTest, OccludedQuadDrawn) {
952 bool use_validator = true;
953 Init(use_validator);
954 renderer_->set_expect_overlays(false);
955 gfx::Rect viewport_rect(16, 16);
957 scoped_ptr<RenderPass> pass = CreateRenderPass();
959 CreateFullscreenCheckeredQuad(resource_provider_.get(),
960 pass->shared_quad_state_list.back(),
961 pass.get());
962 CreateFullscreenCheckeredQuad(resource_provider_.get(),
963 pass->shared_quad_state_list.back(),
964 pass.get());
966 CreateFullscreenCandidateQuad(resource_provider_.get(),
967 pass->shared_quad_state_list.back(),
968 pass.get());
970 RenderPassList pass_list;
971 pass_list.push_back(pass.Pass());
973 // 3 quads in the pass, all should draw.
974 EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(3);
975 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
976 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
978 SwapBuffers();
980 Mock::VerifyAndClearExpectations(renderer_.get());
981 Mock::VerifyAndClearExpectations(&scheduler_);
984 TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) {
985 bool use_validator = false;
986 Init(use_validator);
987 renderer_->set_expect_overlays(false);
988 gfx::Rect viewport_rect(16, 16);
990 scoped_ptr<RenderPass> pass = CreateRenderPass();
992 CreateFullscreenCandidateQuad(resource_provider_.get(),
993 pass->shared_quad_state_list.back(),
994 pass.get());
996 CreateFullscreenCheckeredQuad(resource_provider_.get(),
997 pass->shared_quad_state_list.back(),
998 pass.get());
999 CreateFullscreenCheckeredQuad(resource_provider_.get(),
1000 pass->shared_quad_state_list.back(),
1001 pass.get());
1003 RenderPassList pass_list;
1004 pass_list.push_back(pass.Pass());
1006 // Should see no overlays.
1007 EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(3);
1008 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
1009 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
1011 SwapBuffers();
1013 Mock::VerifyAndClearExpectations(renderer_.get());
1014 Mock::VerifyAndClearExpectations(&scheduler_);
1017 TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturned) {
1018 bool use_validator = true;
1019 Init(use_validator);
1020 renderer_->set_expect_overlays(true);
1022 ResourceProvider::ResourceId resource1 =
1023 CreateResource(resource_provider_.get());
1024 ResourceProvider::ResourceId resource2 =
1025 CreateResource(resource_provider_.get());
1027 scoped_ptr<RenderPass> pass = CreateRenderPass();
1028 RenderPassList pass_list;
1029 pass_list.push_back(pass.Pass());
1031 DirectRenderer::DrawingFrame frame1;
1032 frame1.render_passes_in_draw_order = &pass_list;
1033 frame1.overlay_list.resize(2);
1034 OverlayCandidate& overlay1 = frame1.overlay_list.back();
1035 overlay1.resource_id = resource1;
1036 overlay1.plane_z_order = 1;
1038 DirectRenderer::DrawingFrame frame2;
1039 frame2.render_passes_in_draw_order = &pass_list;
1040 frame2.overlay_list.resize(2);
1041 OverlayCandidate& overlay2 = frame2.overlay_list.back();
1042 overlay2.resource_id = resource2;
1043 overlay2.plane_z_order = 1;
1045 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1046 renderer_->BeginDrawingFrame(&frame1);
1047 renderer_->FinishDrawingFrame(&frame1);
1048 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1049 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
1050 SwapBuffers();
1051 Mock::VerifyAndClearExpectations(&scheduler_);
1053 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1054 renderer_->BeginDrawingFrame(&frame2);
1055 renderer_->FinishDrawingFrame(&frame2);
1056 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1057 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
1058 SwapBuffers();
1059 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1060 Mock::VerifyAndClearExpectations(&scheduler_);
1062 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1063 renderer_->BeginDrawingFrame(&frame1);
1064 renderer_->FinishDrawingFrame(&frame1);
1065 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1066 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
1067 SwapBuffers();
1068 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
1069 Mock::VerifyAndClearExpectations(&scheduler_);
1071 // No overlays, release the resource.
1072 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
1073 DirectRenderer::DrawingFrame frame3;
1074 frame3.render_passes_in_draw_order = &pass_list;
1075 renderer_->set_expect_overlays(false);
1076 renderer_->BeginDrawingFrame(&frame3);
1077 renderer_->FinishDrawingFrame(&frame3);
1078 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1079 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
1080 SwapBuffers();
1081 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1082 Mock::VerifyAndClearExpectations(&scheduler_);
1084 // Use the same buffer twice.
1085 renderer_->set_expect_overlays(true);
1086 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1087 renderer_->BeginDrawingFrame(&frame1);
1088 renderer_->FinishDrawingFrame(&frame1);
1089 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1090 SwapBuffers();
1091 Mock::VerifyAndClearExpectations(&scheduler_);
1093 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1094 renderer_->BeginDrawingFrame(&frame1);
1095 renderer_->FinishDrawingFrame(&frame1);
1096 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1097 SwapBuffers();
1098 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1099 Mock::VerifyAndClearExpectations(&scheduler_);
1101 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
1102 renderer_->set_expect_overlays(false);
1103 renderer_->BeginDrawingFrame(&frame3);
1104 renderer_->FinishDrawingFrame(&frame3);
1105 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1106 SwapBuffers();
1107 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1108 Mock::VerifyAndClearExpectations(&scheduler_);
1111 } // namespace
1112 } // namespace cc