OLD | NEW |
| (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 | |
OLD | NEW |