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

Side by Side Diff: cc/output/overlay_unittest.cc

Issue 1533773002: Delete CC. (Closed) Base URL: git@github.com:domokit/mojo.git@cl-2e
Patch Set: rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/output/overlay_strategy_single_on_top.cc ('k') | cc/output/program_binding.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
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/quads/checkerboard_draw_quad.h"
14 #include "cc/quads/render_pass.h"
15 #include "cc/quads/stream_video_draw_quad.h"
16 #include "cc/quads/texture_draw_quad.h"
17 #include "cc/resources/resource_provider.h"
18 #include "cc/resources/texture_mailbox.h"
19 #include "cc/test/fake_output_surface_client.h"
20 #include "cc/test/geometry_test_utils.h"
21 #include "cc/test/test_context_provider.h"
22 #include "cc/test/test_shared_bitmap_manager.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 using testing::_;
27 using testing::Mock;
28
29 namespace cc {
30 namespace {
31
32 const gfx::Rect kOverlayRect(0, 0, 128, 128);
33 const gfx::Rect kOverlayTopLeftRect(0, 0, 64, 64);
34 const gfx::Rect kOverlayBottomRightRect(64, 64, 64, 64);
35 const gfx::PointF kUVTopLeft(0.1f, 0.2f);
36 const gfx::PointF kUVBottomRight(1.0f, 1.0f);
37 const gfx::Transform kNormalTransform =
38 gfx::Transform(0.9f, 0, 0, 0.8f, 0.1f, 0.2f); // x,y -> x,y.
39 const gfx::Transform kXMirrorTransform =
40 gfx::Transform(-0.9f, 0, 0, 0.8f, 1.0f, 0.2f); // x,y -> 1-x,y.
41 const gfx::Transform kYMirrorTransform =
42 gfx::Transform(0.9f, 0, 0, -0.8f, 0.1f, 1.0f); // x,y -> x,1-y.
43 const gfx::Transform kBothMirrorTransform =
44 gfx::Transform(-0.9f, 0, 0, -0.8f, 1.0f, 1.0f); // x,y -> 1-x,1-y.
45 const gfx::Transform kSwapTransform =
46 gfx::Transform(0, 1, 1, 0, 0, 0); // x,y -> y,x.
47
48 void MailboxReleased(unsigned sync_point,
49 bool lost_resource,
50 BlockingTaskRunner* main_thread_task_runner) {
51 }
52
53 class SingleOverlayValidator : public OverlayCandidateValidator {
54 public:
55 void CheckOverlaySupport(OverlayCandidateList* surfaces) override;
56 };
57
58 void SingleOverlayValidator::CheckOverlaySupport(
59 OverlayCandidateList* surfaces) {
60 ASSERT_EQ(2U, surfaces->size());
61
62 OverlayCandidate& candidate = surfaces->back();
63 if (candidate.display_rect.width() == 64)
64 EXPECT_EQ(kOverlayBottomRightRect, candidate.display_rect);
65 else
66 EXPECT_EQ(kOverlayRect, candidate.display_rect);
67 EXPECT_EQ(BoundingRect(kUVTopLeft, kUVBottomRight).ToString(),
68 candidate.uv_rect.ToString());
69 candidate.overlay_handled = true;
70 }
71
72 class SingleOverlayProcessor : public OverlayProcessor {
73 public:
74 SingleOverlayProcessor(OutputSurface* surface,
75 ResourceProvider* resource_provider);
76 // Virtual to allow testing different strategies.
77 void Initialize() override;
78 };
79
80 SingleOverlayProcessor::SingleOverlayProcessor(
81 OutputSurface* surface,
82 ResourceProvider* resource_provider)
83 : OverlayProcessor(surface, resource_provider) {
84 EXPECT_EQ(surface, surface_);
85 EXPECT_EQ(resource_provider, resource_provider_);
86 }
87
88 void SingleOverlayProcessor::Initialize() {
89 OverlayCandidateValidator* candidates =
90 surface_->overlay_candidate_validator();
91 ASSERT_TRUE(candidates != NULL);
92 strategies_.push_back(scoped_ptr<Strategy>(
93 new OverlayStrategySingleOnTop(candidates, resource_provider_)));
94 }
95
96 class DefaultOverlayProcessor : public OverlayProcessor {
97 public:
98 DefaultOverlayProcessor(OutputSurface* surface,
99 ResourceProvider* resource_provider);
100 size_t GetStrategyCount();
101 };
102
103 DefaultOverlayProcessor::DefaultOverlayProcessor(
104 OutputSurface* surface,
105 ResourceProvider* resource_provider)
106 : OverlayProcessor(surface, resource_provider) {}
107
108 size_t DefaultOverlayProcessor::GetStrategyCount() {
109 return strategies_.size();
110 }
111
112 class OverlayOutputSurface : public OutputSurface {
113 public:
114 explicit OverlayOutputSurface(scoped_refptr<ContextProvider> context_provider)
115 : OutputSurface(context_provider) {}
116
117 // OutputSurface implementation
118 void SwapBuffers(CompositorFrame* frame) override;
119
120 void InitWithSingleOverlayValidator() {
121 overlay_candidate_validator_.reset(new SingleOverlayValidator);
122 }
123 };
124
125 void OverlayOutputSurface::SwapBuffers(CompositorFrame* frame) {
126 client_->DidSwapBuffers();
127 client_->DidSwapBuffersComplete();
128 }
129
130 scoped_ptr<RenderPass> CreateRenderPass() {
131 RenderPassId id(1, 0);
132 gfx::Rect output_rect(0, 0, 256, 256);
133 bool has_transparent_background = true;
134
135 scoped_ptr<RenderPass> pass = RenderPass::Create();
136 pass->SetAll(id,
137 output_rect,
138 output_rect,
139 gfx::Transform(),
140 has_transparent_background);
141
142 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
143 shared_state->opacity = 1.f;
144 return pass.Pass();
145 }
146
147 ResourceProvider::ResourceId CreateResource(
148 ResourceProvider* resource_provider) {
149 unsigned sync_point = 0;
150 TextureMailbox mailbox =
151 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
152 mailbox.set_allow_overlay(true);
153 scoped_ptr<SingleReleaseCallbackImpl> release_callback =
154 SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
155
156 return resource_provider->CreateResourceFromTextureMailbox(
157 mailbox, release_callback.Pass());
158 }
159
160 SolidColorDrawQuad* CreateSolidColorQuadAt(
161 const SharedQuadState* shared_quad_state,
162 SkColor color,
163 RenderPass* render_pass,
164 const gfx::Rect& rect) {
165 SolidColorDrawQuad* quad =
166 render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
167 quad->SetNew(shared_quad_state, rect, rect, color, false);
168 return quad;
169 }
170
171 TextureDrawQuad* CreateCandidateQuadAt(ResourceProvider* resource_provider,
172 const SharedQuadState* shared_quad_state,
173 RenderPass* render_pass,
174 const gfx::Rect& rect) {
175 ResourceProvider::ResourceId resource_id = CreateResource(resource_provider);
176 bool premultiplied_alpha = false;
177 bool flipped = false;
178 bool nearest_neighbor = false;
179 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
180
181 TextureDrawQuad* overlay_quad =
182 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
183 overlay_quad->SetNew(shared_quad_state,
184 rect,
185 rect,
186 rect,
187 resource_id,
188 premultiplied_alpha,
189 kUVTopLeft,
190 kUVBottomRight,
191 SK_ColorTRANSPARENT,
192 vertex_opacity,
193 flipped,
194 nearest_neighbor);
195
196 return overlay_quad;
197 }
198
199 StreamVideoDrawQuad* CreateCandidateVideoQuadAt(
200 ResourceProvider* resource_provider,
201 const SharedQuadState* shared_quad_state,
202 RenderPass* render_pass,
203 const gfx::Rect& rect,
204 const gfx::Transform& transform) {
205 ResourceProvider::ResourceId resource_id = CreateResource(resource_provider);
206
207 StreamVideoDrawQuad* overlay_quad =
208 render_pass->CreateAndAppendDrawQuad<StreamVideoDrawQuad>();
209 overlay_quad->SetNew(shared_quad_state, rect, rect, rect, resource_id,
210 transform);
211
212 return overlay_quad;
213 }
214
215 TextureDrawQuad* CreateFullscreenCandidateQuad(
216 ResourceProvider* resource_provider,
217 const SharedQuadState* shared_quad_state,
218 RenderPass* render_pass) {
219 return CreateCandidateQuadAt(
220 resource_provider, shared_quad_state, render_pass, kOverlayRect);
221 }
222
223 StreamVideoDrawQuad* CreateFullscreenCandidateVideoQuad(
224 ResourceProvider* resource_provider,
225 const SharedQuadState* shared_quad_state,
226 RenderPass* render_pass,
227 const gfx::Transform& transform) {
228 return CreateCandidateVideoQuadAt(resource_provider, shared_quad_state,
229 render_pass, kOverlayRect, transform);
230 }
231
232 void CreateCheckeredQuadAt(ResourceProvider* resource_provider,
233 const SharedQuadState* shared_quad_state,
234 RenderPass* render_pass,
235 const gfx::Rect& rect) {
236 CheckerboardDrawQuad* checkerboard_quad =
237 render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
238 checkerboard_quad->SetNew(shared_quad_state, rect, rect, SkColor(), 1.f);
239 }
240
241 void CreateFullscreenCheckeredQuad(ResourceProvider* resource_provider,
242 const SharedQuadState* shared_quad_state,
243 RenderPass* render_pass) {
244 CreateCheckeredQuadAt(
245 resource_provider, shared_quad_state, render_pass, kOverlayRect);
246 }
247
248 static void CompareRenderPassLists(const RenderPassList& expected_list,
249 const RenderPassList& actual_list) {
250 EXPECT_EQ(expected_list.size(), actual_list.size());
251 for (size_t i = 0; i < actual_list.size(); ++i) {
252 RenderPass* expected = expected_list[i];
253 RenderPass* actual = actual_list[i];
254
255 EXPECT_EQ(expected->id, actual->id);
256 EXPECT_EQ(expected->output_rect, actual->output_rect);
257 EXPECT_EQ(expected->transform_to_root_target,
258 actual->transform_to_root_target);
259 EXPECT_EQ(expected->damage_rect, actual->damage_rect);
260 EXPECT_EQ(expected->has_transparent_background,
261 actual->has_transparent_background);
262
263 EXPECT_EQ(expected->shared_quad_state_list.size(),
264 actual->shared_quad_state_list.size());
265 EXPECT_EQ(expected->quad_list.size(), actual->quad_list.size());
266
267 for (auto exp_iter = expected->quad_list.cbegin(),
268 act_iter = actual->quad_list.cbegin();
269 exp_iter != expected->quad_list.cend();
270 ++exp_iter, ++act_iter) {
271 EXPECT_EQ(exp_iter->rect.ToString(), act_iter->rect.ToString());
272 EXPECT_EQ(exp_iter->shared_quad_state->content_bounds.ToString(),
273 act_iter->shared_quad_state->content_bounds.ToString());
274 }
275 }
276 }
277
278 TEST(OverlayTest, NoOverlaysByDefault) {
279 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
280 OverlayOutputSurface output_surface(provider);
281 EXPECT_EQ(NULL, output_surface.overlay_candidate_validator());
282
283 output_surface.InitWithSingleOverlayValidator();
284 EXPECT_TRUE(output_surface.overlay_candidate_validator() != NULL);
285 }
286
287 TEST(OverlayTest, OverlaysProcessorHasStrategy) {
288 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
289 OverlayOutputSurface output_surface(provider);
290 FakeOutputSurfaceClient client;
291 EXPECT_TRUE(output_surface.BindToClient(&client));
292 output_surface.InitWithSingleOverlayValidator();
293 EXPECT_TRUE(output_surface.overlay_candidate_validator() != NULL);
294
295 scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
296 new TestSharedBitmapManager());
297 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
298 &output_surface, shared_bitmap_manager.get(), NULL, NULL, 0, false, 1));
299
300 scoped_ptr<DefaultOverlayProcessor> overlay_processor(
301 new DefaultOverlayProcessor(&output_surface, resource_provider.get()));
302 overlay_processor->Initialize();
303 EXPECT_GE(1U, overlay_processor->GetStrategyCount());
304 }
305
306 class SingleOverlayOnTopTest : public testing::Test {
307 protected:
308 void SetUp() override {
309 provider_ = TestContextProvider::Create();
310 output_surface_.reset(new OverlayOutputSurface(provider_));
311 EXPECT_TRUE(output_surface_->BindToClient(&client_));
312 output_surface_->InitWithSingleOverlayValidator();
313 EXPECT_TRUE(output_surface_->overlay_candidate_validator() != NULL);
314
315 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
316 resource_provider_ = ResourceProvider::Create(output_surface_.get(),
317 shared_bitmap_manager_.get(),
318 NULL,
319 NULL,
320 0,
321 false,
322 1);
323
324 overlay_processor_.reset(new SingleOverlayProcessor(
325 output_surface_.get(), resource_provider_.get()));
326 overlay_processor_->Initialize();
327 }
328
329 scoped_refptr<TestContextProvider> provider_;
330 scoped_ptr<OverlayOutputSurface> output_surface_;
331 FakeOutputSurfaceClient client_;
332 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
333 scoped_ptr<ResourceProvider> resource_provider_;
334 scoped_ptr<SingleOverlayProcessor> overlay_processor_;
335 };
336
337 TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) {
338 scoped_ptr<RenderPass> pass = CreateRenderPass();
339 TextureDrawQuad* original_quad =
340 CreateFullscreenCandidateQuad(resource_provider_.get(),
341 pass->shared_quad_state_list.back(),
342 pass.get());
343 unsigned original_resource_id = original_quad->resource_id;
344
345 // Add something behind it.
346 CreateFullscreenCheckeredQuad(resource_provider_.get(),
347 pass->shared_quad_state_list.back(),
348 pass.get());
349 CreateFullscreenCheckeredQuad(resource_provider_.get(),
350 pass->shared_quad_state_list.back(),
351 pass.get());
352
353 RenderPassList pass_list;
354 pass_list.push_back(pass.Pass());
355
356 // Check for potential candidates.
357 OverlayCandidateList candidate_list;
358 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
359
360 ASSERT_EQ(1U, pass_list.size());
361 ASSERT_EQ(2U, candidate_list.size());
362
363 RenderPass* main_pass = pass_list.back();
364 // Check that the quad is gone.
365 EXPECT_EQ(2U, main_pass->quad_list.size());
366 const QuadList& quad_list = main_pass->quad_list;
367 for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin();
368 it != quad_list.BackToFrontEnd();
369 ++it) {
370 EXPECT_NE(DrawQuad::TEXTURE_CONTENT, it->material);
371 }
372
373 // Check that the right resource id got extracted.
374 EXPECT_EQ(original_resource_id, candidate_list.back().resource_id);
375 }
376
377 TEST_F(SingleOverlayOnTopTest, NoCandidates) {
378 scoped_ptr<RenderPass> pass = CreateRenderPass();
379 CreateFullscreenCheckeredQuad(resource_provider_.get(),
380 pass->shared_quad_state_list.back(),
381 pass.get());
382 CreateFullscreenCheckeredQuad(resource_provider_.get(),
383 pass->shared_quad_state_list.back(),
384 pass.get());
385
386 RenderPassList pass_list;
387 pass_list.push_back(pass.Pass());
388
389 RenderPassList original_pass_list;
390 RenderPass::CopyAll(pass_list, &original_pass_list);
391
392 OverlayCandidateList candidate_list;
393 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
394 EXPECT_EQ(0U, candidate_list.size());
395 // There should be nothing new here.
396 CompareRenderPassLists(pass_list, original_pass_list);
397 }
398
399 TEST_F(SingleOverlayOnTopTest, OccludedCandidates) {
400 scoped_ptr<RenderPass> pass = CreateRenderPass();
401 CreateFullscreenCheckeredQuad(resource_provider_.get(),
402 pass->shared_quad_state_list.back(),
403 pass.get());
404 CreateFullscreenCheckeredQuad(resource_provider_.get(),
405 pass->shared_quad_state_list.back(),
406 pass.get());
407
408 CreateFullscreenCandidateQuad(resource_provider_.get(),
409 pass->shared_quad_state_list.back(),
410 pass.get());
411
412 RenderPassList pass_list;
413 pass_list.push_back(pass.Pass());
414
415 RenderPassList original_pass_list;
416 RenderPass::CopyAll(pass_list, &original_pass_list);
417
418 OverlayCandidateList candidate_list;
419 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
420 EXPECT_EQ(0U, candidate_list.size());
421 // There should be nothing new here.
422 CompareRenderPassLists(pass_list, original_pass_list);
423 }
424
425 // Test with multiple render passes.
426 TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) {
427 RenderPassList pass_list;
428 pass_list.push_back(CreateRenderPass());
429
430 scoped_ptr<RenderPass> pass = CreateRenderPass();
431 CreateFullscreenCandidateQuad(resource_provider_.get(),
432 pass->shared_quad_state_list.back(),
433 pass.get());
434
435 // Add something behind it.
436 CreateFullscreenCheckeredQuad(resource_provider_.get(),
437 pass->shared_quad_state_list.back(),
438 pass.get());
439 CreateFullscreenCheckeredQuad(resource_provider_.get(),
440 pass->shared_quad_state_list.back(),
441 pass.get());
442
443 pass_list.push_back(pass.Pass());
444
445 RenderPassList original_pass_list;
446 RenderPass::CopyAll(pass_list, &original_pass_list);
447
448 // Check for potential candidates.
449 OverlayCandidateList candidate_list;
450 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
451 EXPECT_EQ(2U, candidate_list.size());
452
453 // This should be the same.
454 ASSERT_EQ(2U, pass_list.size());
455 }
456
457 TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) {
458 scoped_ptr<RenderPass> pass = CreateRenderPass();
459 TextureDrawQuad* quad =
460 CreateFullscreenCandidateQuad(resource_provider_.get(),
461 pass->shared_quad_state_list.back(),
462 pass.get());
463 quad->premultiplied_alpha = true;
464
465 RenderPassList pass_list;
466 pass_list.push_back(pass.Pass());
467 OverlayCandidateList candidate_list;
468 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
469 EXPECT_EQ(1U, pass_list.size());
470 EXPECT_EQ(0U, candidate_list.size());
471 }
472
473 TEST_F(SingleOverlayOnTopTest, RejectBlending) {
474 scoped_ptr<RenderPass> pass = CreateRenderPass();
475 TextureDrawQuad* quad =
476 CreateFullscreenCandidateQuad(resource_provider_.get(),
477 pass->shared_quad_state_list.back(),
478 pass.get());
479 quad->needs_blending = true;
480
481 RenderPassList pass_list;
482 pass_list.push_back(pass.Pass());
483 OverlayCandidateList candidate_list;
484 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
485 ASSERT_EQ(1U, pass_list.size());
486 EXPECT_EQ(0U, candidate_list.size());
487 }
488
489 TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {
490 scoped_ptr<RenderPass> pass = CreateRenderPass();
491 TextureDrawQuad* quad =
492 CreateFullscreenCandidateQuad(resource_provider_.get(),
493 pass->shared_quad_state_list.back(),
494 pass.get());
495 quad->background_color = SK_ColorBLACK;
496
497 RenderPassList pass_list;
498 pass_list.push_back(pass.Pass());
499 OverlayCandidateList candidate_list;
500 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
501 ASSERT_EQ(1U, pass_list.size());
502 EXPECT_EQ(0U, candidate_list.size());
503 }
504
505 TEST_F(SingleOverlayOnTopTest, RejectBlendMode) {
506 scoped_ptr<RenderPass> pass = CreateRenderPass();
507 CreateFullscreenCandidateQuad(resource_provider_.get(),
508 pass->shared_quad_state_list.back(),
509 pass.get());
510 pass->shared_quad_state_list.back()->blend_mode = SkXfermode::kScreen_Mode;
511
512 RenderPassList pass_list;
513 pass_list.push_back(pass.Pass());
514 OverlayCandidateList candidate_list;
515 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
516 ASSERT_EQ(1U, pass_list.size());
517 EXPECT_EQ(0U, candidate_list.size());
518 }
519
520 TEST_F(SingleOverlayOnTopTest, RejectOpacity) {
521 scoped_ptr<RenderPass> pass = CreateRenderPass();
522 CreateFullscreenCandidateQuad(resource_provider_.get(),
523 pass->shared_quad_state_list.back(),
524 pass.get());
525 pass->shared_quad_state_list.back()->opacity = 0.5f;
526
527 RenderPassList pass_list;
528 pass_list.push_back(pass.Pass());
529 OverlayCandidateList candidate_list;
530 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
531 ASSERT_EQ(1U, pass_list.size());
532 EXPECT_EQ(0U, candidate_list.size());
533 }
534
535 TEST_F(SingleOverlayOnTopTest, RejectNonScaleTransform) {
536 scoped_ptr<RenderPass> pass = CreateRenderPass();
537 CreateFullscreenCandidateQuad(resource_provider_.get(),
538 pass->shared_quad_state_list.back(),
539 pass.get());
540 pass->shared_quad_state_list.back()
541 ->content_to_target_transform.RotateAboutXAxis(45.f);
542
543 RenderPassList pass_list;
544 pass_list.push_back(pass.Pass());
545 OverlayCandidateList candidate_list;
546 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
547 ASSERT_EQ(1U, pass_list.size());
548 EXPECT_EQ(0U, candidate_list.size());
549 }
550
551 TEST_F(SingleOverlayOnTopTest, RejectNegativeScaleTransform) {
552 scoped_ptr<RenderPass> pass = CreateRenderPass();
553 CreateFullscreenCandidateQuad(resource_provider_.get(),
554 pass->shared_quad_state_list.back(),
555 pass.get());
556 pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f,
557 -1.0f);
558
559 RenderPassList pass_list;
560 pass_list.push_back(pass.Pass());
561 OverlayCandidateList candidate_list;
562 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
563 ASSERT_EQ(1U, pass_list.size());
564 EXPECT_EQ(0U, candidate_list.size());
565 }
566
567 TEST_F(SingleOverlayOnTopTest, AllowPositiveScaleTransform) {
568 gfx::Rect rect = kOverlayRect;
569 rect.set_width(rect.width() / 2);
570 scoped_ptr<RenderPass> pass = CreateRenderPass();
571 CreateCandidateQuadAt(resource_provider_.get(),
572 pass->shared_quad_state_list.back(), pass.get(), rect);
573 pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f,
574 1.0f);
575
576 RenderPassList pass_list;
577 pass_list.push_back(pass.Pass());
578 OverlayCandidateList candidate_list;
579 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
580 ASSERT_EQ(1U, pass_list.size());
581 EXPECT_EQ(2U, candidate_list.size());
582 }
583
584 TEST_F(SingleOverlayOnTopTest, AllowNotTopIfNotOccluded) {
585 scoped_ptr<RenderPass> pass = CreateRenderPass();
586 CreateCheckeredQuadAt(resource_provider_.get(),
587 pass->shared_quad_state_list.back(),
588 pass.get(),
589 kOverlayTopLeftRect);
590 CreateCandidateQuadAt(resource_provider_.get(),
591 pass->shared_quad_state_list.back(),
592 pass.get(),
593 kOverlayBottomRightRect);
594
595 RenderPassList pass_list;
596 pass_list.push_back(pass.Pass());
597
598 RenderPassList original_pass_list;
599 RenderPass::CopyAll(pass_list, &original_pass_list);
600
601 OverlayCandidateList candidate_list;
602 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
603 EXPECT_EQ(1U, pass_list.size());
604 EXPECT_EQ(2U, candidate_list.size());
605 }
606
607 TEST_F(SingleOverlayOnTopTest, AllowTransparentOnTop) {
608 scoped_ptr<RenderPass> pass = CreateRenderPass();
609 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
610 shared_state->opacity = 0.f;
611 CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(),
612 kOverlayBottomRightRect);
613 shared_state = pass->CreateAndAppendSharedQuadState();
614 shared_state->opacity = 1.f;
615 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
616 kOverlayBottomRightRect);
617
618 RenderPassList pass_list;
619 pass_list.push_back(pass.Pass());
620
621 RenderPassList original_pass_list;
622 RenderPass::CopyAll(pass_list, &original_pass_list);
623
624 OverlayCandidateList candidate_list;
625 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
626 EXPECT_EQ(1U, pass_list.size());
627 EXPECT_EQ(2U, candidate_list.size());
628 }
629
630 TEST_F(SingleOverlayOnTopTest, AllowTransparentColorOnTop) {
631 scoped_ptr<RenderPass> pass = CreateRenderPass();
632 CreateSolidColorQuadAt(pass->shared_quad_state_list.back(),
633 SK_ColorTRANSPARENT, pass.get(),
634 kOverlayBottomRightRect);
635 CreateCandidateQuadAt(resource_provider_.get(),
636 pass->shared_quad_state_list.back(), pass.get(),
637 kOverlayBottomRightRect);
638
639 RenderPassList pass_list;
640 pass_list.push_back(pass.Pass());
641
642 RenderPassList original_pass_list;
643 RenderPass::CopyAll(pass_list, &original_pass_list);
644
645 OverlayCandidateList candidate_list;
646 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
647 EXPECT_EQ(1U, pass_list.size());
648 EXPECT_EQ(2U, candidate_list.size());
649 }
650
651 TEST_F(SingleOverlayOnTopTest, RejectOpaqueColorOnTop) {
652 scoped_ptr<RenderPass> pass = CreateRenderPass();
653 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
654 shared_state->opacity = 0.5f;
655 CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(),
656 kOverlayBottomRightRect);
657 shared_state = pass->CreateAndAppendSharedQuadState();
658 shared_state->opacity = 1.f;
659 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
660 kOverlayBottomRightRect);
661
662 RenderPassList pass_list;
663 pass_list.push_back(pass.Pass());
664
665 RenderPassList original_pass_list;
666 RenderPass::CopyAll(pass_list, &original_pass_list);
667
668 OverlayCandidateList candidate_list;
669 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
670 EXPECT_EQ(1U, pass_list.size());
671 EXPECT_EQ(0U, candidate_list.size());
672 }
673
674 TEST_F(SingleOverlayOnTopTest, RejectTransparentColorOnTopWithoutBlending) {
675 scoped_ptr<RenderPass> pass = CreateRenderPass();
676 SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
677 CreateSolidColorQuadAt(shared_state, SK_ColorTRANSPARENT, pass.get(),
678 kOverlayBottomRightRect)->opaque_rect =
679 kOverlayBottomRightRect;
680 CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
681 kOverlayBottomRightRect);
682
683 RenderPassList pass_list;
684 pass_list.push_back(pass.Pass());
685
686 RenderPassList original_pass_list;
687 RenderPass::CopyAll(pass_list, &original_pass_list);
688
689 OverlayCandidateList candidate_list;
690 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
691 EXPECT_EQ(1U, pass_list.size());
692 EXPECT_EQ(0U, candidate_list.size());
693 }
694
695 TEST_F(SingleOverlayOnTopTest, RejectVideoSwapTransform) {
696 scoped_ptr<RenderPass> pass = CreateRenderPass();
697 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
698 pass->shared_quad_state_list.back(),
699 pass.get(), kSwapTransform);
700
701 RenderPassList pass_list;
702 pass_list.push_back(pass.Pass());
703 OverlayCandidateList candidate_list;
704 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
705 ASSERT_EQ(1U, pass_list.size());
706 EXPECT_EQ(0U, candidate_list.size());
707 }
708
709 TEST_F(SingleOverlayOnTopTest, AllowVideoXMirrorTransform) {
710 scoped_ptr<RenderPass> pass = CreateRenderPass();
711 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
712 pass->shared_quad_state_list.back(),
713 pass.get(), kXMirrorTransform);
714
715 RenderPassList pass_list;
716 pass_list.push_back(pass.Pass());
717 OverlayCandidateList candidate_list;
718 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
719 ASSERT_EQ(1U, pass_list.size());
720 EXPECT_EQ(2U, candidate_list.size());
721 }
722
723 TEST_F(SingleOverlayOnTopTest, AllowVideoBothMirrorTransform) {
724 scoped_ptr<RenderPass> pass = CreateRenderPass();
725 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
726 pass->shared_quad_state_list.back(),
727 pass.get(), kBothMirrorTransform);
728
729 RenderPassList pass_list;
730 pass_list.push_back(pass.Pass());
731 OverlayCandidateList candidate_list;
732 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
733 ASSERT_EQ(1U, pass_list.size());
734 EXPECT_EQ(2U, candidate_list.size());
735 }
736
737 TEST_F(SingleOverlayOnTopTest, AllowVideoNormalTransform) {
738 scoped_ptr<RenderPass> pass = CreateRenderPass();
739 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
740 pass->shared_quad_state_list.back(),
741 pass.get(), kNormalTransform);
742
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(2U, candidate_list.size());
749 }
750
751 TEST_F(SingleOverlayOnTopTest, AllowVideoYMirrorTransform) {
752 scoped_ptr<RenderPass> pass = CreateRenderPass();
753 CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
754 pass->shared_quad_state_list.back(),
755 pass.get(), kYMirrorTransform);
756
757 RenderPassList pass_list;
758 pass_list.push_back(pass.Pass());
759 OverlayCandidateList candidate_list;
760 overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
761 ASSERT_EQ(1U, pass_list.size());
762 EXPECT_EQ(2U, candidate_list.size());
763 }
764
765 class OverlayInfoRendererGL : public GLRenderer {
766 public:
767 OverlayInfoRendererGL(RendererClient* client,
768 const RendererSettings* settings,
769 OutputSurface* output_surface,
770 ResourceProvider* resource_provider)
771 : GLRenderer(client,
772 settings,
773 output_surface,
774 resource_provider,
775 NULL,
776 0),
777 expect_overlays_(false) {}
778
779 MOCK_METHOD3(DoDrawQuad,
780 void(DrawingFrame* frame,
781 const DrawQuad* quad,
782 const gfx::QuadF* draw_region));
783
784 using GLRenderer::BeginDrawingFrame;
785
786 void FinishDrawingFrame(DrawingFrame* frame) override {
787 GLRenderer::FinishDrawingFrame(frame);
788
789 if (!expect_overlays_) {
790 EXPECT_EQ(0U, frame->overlay_list.size());
791 return;
792 }
793
794 ASSERT_EQ(2U, frame->overlay_list.size());
795 EXPECT_NE(0U, frame->overlay_list.back().resource_id);
796 }
797
798 void set_expect_overlays(bool expect_overlays) {
799 expect_overlays_ = expect_overlays;
800 }
801
802 private:
803 bool expect_overlays_;
804 };
805
806 class FakeRendererClient : public RendererClient {
807 public:
808 // RendererClient methods.
809 void SetFullRootLayerDamage() override {}
810 };
811
812 class MockOverlayScheduler {
813 public:
814 MOCK_METHOD5(Schedule,
815 void(int plane_z_order,
816 gfx::OverlayTransform plane_transform,
817 unsigned overlay_texture_id,
818 const gfx::Rect& display_bounds,
819 const gfx::RectF& uv_rect));
820 };
821
822 class GLRendererWithOverlaysTest : public testing::Test {
823 protected:
824 GLRendererWithOverlaysTest() {
825 provider_ = TestContextProvider::Create();
826 output_surface_.reset(new OverlayOutputSurface(provider_));
827 CHECK(output_surface_->BindToClient(&output_surface_client_));
828 resource_provider_ = ResourceProvider::Create(
829 output_surface_.get(), NULL, NULL, NULL, 0, false, 1);
830
831 provider_->support()->SetScheduleOverlayPlaneCallback(base::Bind(
832 &MockOverlayScheduler::Schedule, base::Unretained(&scheduler_)));
833 }
834
835 void Init(bool use_validator) {
836 if (use_validator)
837 output_surface_->InitWithSingleOverlayValidator();
838
839 renderer_ =
840 make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_,
841 &settings_,
842 output_surface_.get(),
843 resource_provider_.get()));
844 }
845
846 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
847
848 RendererSettings settings_;
849 FakeOutputSurfaceClient output_surface_client_;
850 scoped_ptr<OverlayOutputSurface> output_surface_;
851 FakeRendererClient renderer_client_;
852 scoped_ptr<ResourceProvider> resource_provider_;
853 scoped_ptr<OverlayInfoRendererGL> renderer_;
854 scoped_refptr<TestContextProvider> provider_;
855 MockOverlayScheduler scheduler_;
856 };
857
858 TEST_F(GLRendererWithOverlaysTest, OverlayQuadNotDrawn) {
859 bool use_validator = true;
860 Init(use_validator);
861 renderer_->set_expect_overlays(true);
862 gfx::Rect viewport_rect(16, 16);
863
864 scoped_ptr<RenderPass> pass = CreateRenderPass();
865
866 CreateFullscreenCandidateQuad(resource_provider_.get(),
867 pass->shared_quad_state_list.back(),
868 pass.get());
869
870 CreateFullscreenCheckeredQuad(resource_provider_.get(),
871 pass->shared_quad_state_list.back(),
872 pass.get());
873 CreateFullscreenCheckeredQuad(resource_provider_.get(),
874 pass->shared_quad_state_list.back(),
875 pass.get());
876
877 RenderPassList pass_list;
878 pass_list.push_back(pass.Pass());
879
880 // Candidate pass was taken out and extra skipped pass added,
881 // so only draw 2 quads.
882 EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(2);
883 EXPECT_CALL(scheduler_,
884 Schedule(1,
885 gfx::OVERLAY_TRANSFORM_NONE,
886 _,
887 kOverlayRect,
888 BoundingRect(kUVTopLeft, kUVBottomRight))).Times(1);
889 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
890
891 SwapBuffers();
892
893 Mock::VerifyAndClearExpectations(renderer_.get());
894 Mock::VerifyAndClearExpectations(&scheduler_);
895 }
896
897 TEST_F(GLRendererWithOverlaysTest, OccludedQuadDrawn) {
898 bool use_validator = true;
899 Init(use_validator);
900 renderer_->set_expect_overlays(false);
901 gfx::Rect viewport_rect(16, 16);
902
903 scoped_ptr<RenderPass> pass = CreateRenderPass();
904
905 CreateFullscreenCheckeredQuad(resource_provider_.get(),
906 pass->shared_quad_state_list.back(),
907 pass.get());
908 CreateFullscreenCheckeredQuad(resource_provider_.get(),
909 pass->shared_quad_state_list.back(),
910 pass.get());
911
912 CreateFullscreenCandidateQuad(resource_provider_.get(),
913 pass->shared_quad_state_list.back(),
914 pass.get());
915
916 RenderPassList pass_list;
917 pass_list.push_back(pass.Pass());
918
919 // 3 quads in the pass, all should draw.
920 EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(3);
921 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
922 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
923
924 SwapBuffers();
925
926 Mock::VerifyAndClearExpectations(renderer_.get());
927 Mock::VerifyAndClearExpectations(&scheduler_);
928 }
929
930 TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) {
931 bool use_validator = false;
932 Init(use_validator);
933 renderer_->set_expect_overlays(false);
934 gfx::Rect viewport_rect(16, 16);
935
936 scoped_ptr<RenderPass> pass = CreateRenderPass();
937
938 CreateFullscreenCandidateQuad(resource_provider_.get(),
939 pass->shared_quad_state_list.back(),
940 pass.get());
941
942 CreateFullscreenCheckeredQuad(resource_provider_.get(),
943 pass->shared_quad_state_list.back(),
944 pass.get());
945 CreateFullscreenCheckeredQuad(resource_provider_.get(),
946 pass->shared_quad_state_list.back(),
947 pass.get());
948
949 RenderPassList pass_list;
950 pass_list.push_back(pass.Pass());
951
952 // Should see no overlays.
953 EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(3);
954 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
955 renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
956
957 SwapBuffers();
958
959 Mock::VerifyAndClearExpectations(renderer_.get());
960 Mock::VerifyAndClearExpectations(&scheduler_);
961 }
962
963 TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturned) {
964 bool use_validator = true;
965 Init(use_validator);
966 renderer_->set_expect_overlays(true);
967
968 ResourceProvider::ResourceId resource1 =
969 CreateResource(resource_provider_.get());
970 ResourceProvider::ResourceId resource2 =
971 CreateResource(resource_provider_.get());
972
973 scoped_ptr<RenderPass> pass = CreateRenderPass();
974 RenderPassList pass_list;
975 pass_list.push_back(pass.Pass());
976
977 DirectRenderer::DrawingFrame frame1;
978 frame1.render_passes_in_draw_order = &pass_list;
979 frame1.overlay_list.resize(2);
980 OverlayCandidate& overlay1 = frame1.overlay_list.back();
981 overlay1.resource_id = resource1;
982 overlay1.plane_z_order = 1;
983
984 DirectRenderer::DrawingFrame frame2;
985 frame2.render_passes_in_draw_order = &pass_list;
986 frame2.overlay_list.resize(2);
987 OverlayCandidate& overlay2 = frame2.overlay_list.back();
988 overlay2.resource_id = resource2;
989 overlay2.plane_z_order = 1;
990
991 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
992 renderer_->BeginDrawingFrame(&frame1);
993 renderer_->FinishDrawingFrame(&frame1);
994 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
995 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
996 SwapBuffers();
997 Mock::VerifyAndClearExpectations(&scheduler_);
998
999 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1000 renderer_->BeginDrawingFrame(&frame2);
1001 renderer_->FinishDrawingFrame(&frame2);
1002 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1003 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
1004 SwapBuffers();
1005 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1006 Mock::VerifyAndClearExpectations(&scheduler_);
1007
1008 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1009 renderer_->BeginDrawingFrame(&frame1);
1010 renderer_->FinishDrawingFrame(&frame1);
1011 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1012 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
1013 SwapBuffers();
1014 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
1015 Mock::VerifyAndClearExpectations(&scheduler_);
1016
1017 // No overlays, release the resource.
1018 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
1019 DirectRenderer::DrawingFrame frame3;
1020 frame3.render_passes_in_draw_order = &pass_list;
1021 renderer_->set_expect_overlays(false);
1022 renderer_->BeginDrawingFrame(&frame3);
1023 renderer_->FinishDrawingFrame(&frame3);
1024 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1025 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
1026 SwapBuffers();
1027 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1028 Mock::VerifyAndClearExpectations(&scheduler_);
1029
1030 // Use the same buffer twice.
1031 renderer_->set_expect_overlays(true);
1032 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1033 renderer_->BeginDrawingFrame(&frame1);
1034 renderer_->FinishDrawingFrame(&frame1);
1035 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1036 SwapBuffers();
1037 Mock::VerifyAndClearExpectations(&scheduler_);
1038
1039 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
1040 renderer_->BeginDrawingFrame(&frame1);
1041 renderer_->FinishDrawingFrame(&frame1);
1042 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1043 SwapBuffers();
1044 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1045 Mock::VerifyAndClearExpectations(&scheduler_);
1046
1047 EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
1048 renderer_->set_expect_overlays(false);
1049 renderer_->BeginDrawingFrame(&frame3);
1050 renderer_->FinishDrawingFrame(&frame3);
1051 EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
1052 SwapBuffers();
1053 EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
1054 Mock::VerifyAndClearExpectations(&scheduler_);
1055 }
1056
1057 } // namespace
1058 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/overlay_strategy_single_on_top.cc ('k') | cc/output/program_binding.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698