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

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

Issue 197223003: Start of hardware overlay support in CC with Ubercompositor. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months 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 | Annotate | Revision Log
« no previous file with comments | « cc/output/overlay_strategy_single_on_top.cc ('k') | cc/quads/render_pass.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/output_surface.h"
7 #include "cc/output/output_surface_client.h"
8 #include "cc/output/overlay_candidate_validator.h"
9 #include "cc/output/overlay_processor.h"
10 #include "cc/output/overlay_strategy_single_on_top.h"
11 #include "cc/quads/checkerboard_draw_quad.h"
12 #include "cc/quads/render_pass.h"
13 #include "cc/quads/texture_draw_quad.h"
14 #include "cc/resources/resource_provider.h"
15 #include "cc/resources/texture_mailbox.h"
16 #include "cc/test/fake_output_surface_client.h"
17 #include "cc/test/geometry_test_utils.h"
18 #include "cc/test/test_context_provider.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace cc {
22 namespace {
23
24 const gfx::Rect kOverlayRect(0, 0, 128, 128);
25 const gfx::PointF kUVTopLeft(0.1f, 0.2f);
26 const gfx::PointF kUVBottomRight(1.0f, 1.0f);
27
28 void MailboxReleased(unsigned sync_point, bool lost_resource) {}
29
30 class SingleOverlayValidator : public OverlayCandidateValidator {
31 public:
32 virtual void CheckOverlaySupport(OverlayCandidateList* surfaces) OVERRIDE;
33 };
34
35 void SingleOverlayValidator::CheckOverlaySupport(
36 OverlayCandidateList* surfaces) {
37 ASSERT_EQ(2U, surfaces->size());
38
39 OverlayCandidate& candidate = surfaces->back();
40 EXPECT_EQ(kOverlayRect.ToString(), candidate.display_rect.ToString());
41 EXPECT_EQ(BoundingRect(kUVTopLeft, kUVBottomRight).ToString(),
42 candidate.uv_rect.ToString());
43 candidate.overlay_handled = true;
44 }
45
46 class SingleOverlayProcessor : public OverlayProcessor {
47 public:
48 SingleOverlayProcessor(OutputSurface* surface,
49 ResourceProvider* resource_provider);
50 // Virtual to allow testing different strategies.
51 virtual void Initialize() OVERRIDE;
52 };
53
54 SingleOverlayProcessor::SingleOverlayProcessor(
55 OutputSurface* surface,
56 ResourceProvider* resource_provider)
57 : OverlayProcessor(surface, resource_provider) {
58 EXPECT_EQ(surface, surface_);
59 EXPECT_EQ(resource_provider, resource_provider_);
60 }
61
62 void SingleOverlayProcessor::Initialize() {
63 OverlayCandidateValidator* candidates =
64 surface_->overlay_candidate_validator();
65 ASSERT_TRUE(candidates != NULL);
66 strategies_.push_back(scoped_ptr<Strategy>(
67 new OverlayStrategySingleOnTop(candidates, resource_provider_)));
68 }
69
70 class DefaultOverlayProcessor : public OverlayProcessor {
71 public:
72 DefaultOverlayProcessor(OutputSurface* surface,
73 ResourceProvider* resource_provider);
74 size_t GetStrategyCount();
75 };
76
77 DefaultOverlayProcessor::DefaultOverlayProcessor(
78 OutputSurface* surface,
79 ResourceProvider* resource_provider)
80 : OverlayProcessor(surface, resource_provider) {}
81
82 size_t DefaultOverlayProcessor::GetStrategyCount() {
83 return strategies_.size();
84 }
85
86 class OverlayOutputSurface : public OutputSurface {
87 public:
88 explicit OverlayOutputSurface(scoped_refptr<ContextProvider> context_provider)
89 : OutputSurface(context_provider) {}
90
91 void InitWithSingleOverlayValidator() {
92 overlay_candidate_validator_.reset(new SingleOverlayValidator);
93 }
94 };
95
96 scoped_ptr<RenderPass> CreateRenderPass() {
97 RenderPass::Id id(1, 0);
98 gfx::Rect output_rect(0, 0, 256, 256);
99 bool has_transparent_background = true;
100
101 scoped_ptr<RenderPass> pass = RenderPass::Create();
102 pass->SetAll(id,
103 output_rect,
104 output_rect,
105 gfx::Transform(),
106 has_transparent_background,
107 RenderPass::NO_OVERLAY);
108
109 scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create();
110 shared_state->opacity = 1.f;
111 pass->shared_quad_state_list.push_back(shared_state.Pass());
112 return pass.Pass();
113 }
114
115 scoped_ptr<TextureDrawQuad> CreateCandidateQuad(
116 ResourceProvider* resource_provider,
117 const SharedQuadState* shared_quad_state) {
118 unsigned sync_point = 0;
119 TextureMailbox mailbox =
120 TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
121 mailbox.set_allow_overlay(true);
122 scoped_ptr<SingleReleaseCallback> release_callback =
123 SingleReleaseCallback::Create(base::Bind(&MailboxReleased));
124
125 ResourceProvider::ResourceId resource_id =
126 resource_provider->CreateResourceFromTextureMailbox(
127 mailbox, release_callback.Pass());
128 bool premultiplied_alpha = false;
129 bool flipped = false;
130 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
131
132 scoped_ptr<TextureDrawQuad> overlay_quad = TextureDrawQuad::Create();
133 overlay_quad->SetNew(shared_quad_state,
134 kOverlayRect,
135 kOverlayRect,
136 kOverlayRect,
137 resource_id,
138 premultiplied_alpha,
139 kUVTopLeft,
140 kUVBottomRight,
141 SK_ColorTRANSPARENT,
142 vertex_opacity,
143 flipped);
144
145 return overlay_quad.Pass();
146 }
147
148 scoped_ptr<DrawQuad> CreateCheckeredQuad(
149 ResourceProvider* resource_provider,
150 const SharedQuadState* shared_quad_state) {
151 scoped_ptr<CheckerboardDrawQuad> checkerboard_quad =
152 CheckerboardDrawQuad::Create();
153 checkerboard_quad->SetNew(
154 shared_quad_state, kOverlayRect, kOverlayRect, SkColor());
155 return checkerboard_quad.PassAs<DrawQuad>();
156 }
157
158 static void CompareRenderPassLists(const RenderPassList& expected_list,
159 const RenderPassList& actual_list) {
160 EXPECT_EQ(expected_list.size(), actual_list.size());
161 for (size_t i = 0; i < actual_list.size(); ++i) {
162 RenderPass* expected = expected_list[i];
163 RenderPass* actual = actual_list[i];
164
165 EXPECT_EQ(expected->id, actual->id);
166 EXPECT_RECT_EQ(expected->output_rect, actual->output_rect);
167 EXPECT_EQ(expected->transform_to_root_target,
168 actual->transform_to_root_target);
169 EXPECT_RECT_EQ(expected->damage_rect, actual->damage_rect);
170 EXPECT_EQ(expected->has_transparent_background,
171 actual->has_transparent_background);
172 EXPECT_EQ(expected->overlay_state, actual->overlay_state);
173
174 EXPECT_EQ(expected->shared_quad_state_list.size(),
175 actual->shared_quad_state_list.size());
176 EXPECT_EQ(expected->quad_list.size(), actual->quad_list.size());
177
178 for (size_t i = 0; i < expected->quad_list.size(); ++i) {
179 EXPECT_EQ(expected->quad_list[i]->rect.ToString(),
180 actual->quad_list[i]->rect.ToString());
181 EXPECT_EQ(
182 expected->quad_list[i]->shared_quad_state->content_bounds.ToString(),
183 actual->quad_list[i]->shared_quad_state->content_bounds.ToString());
184 }
185 }
186 }
187
188 TEST(OverlayTest, NoOverlaysByDefault) {
189 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
190 OverlayOutputSurface output_surface(provider);
191 EXPECT_EQ(NULL, output_surface.overlay_candidate_validator());
192
193 output_surface.InitWithSingleOverlayValidator();
194 EXPECT_TRUE(output_surface.overlay_candidate_validator() != NULL);
195 }
196
197 TEST(OverlayTest, OverlaysProcessorHasStrategy) {
198 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
199 OverlayOutputSurface output_surface(provider);
200 FakeOutputSurfaceClient client;
201 EXPECT_TRUE(output_surface.BindToClient(&client));
202 output_surface.InitWithSingleOverlayValidator();
203 EXPECT_TRUE(output_surface.overlay_candidate_validator() != NULL);
204
205 scoped_ptr<ResourceProvider> resource_provider(
206 ResourceProvider::Create(&output_surface, NULL, 0, false, 1));
207
208 scoped_ptr<DefaultOverlayProcessor> overlay_processor(
209 new DefaultOverlayProcessor(&output_surface, resource_provider.get()));
210 overlay_processor->Initialize();
211 EXPECT_GE(1U, overlay_processor->GetStrategyCount());
212 }
213
214 class SingleOverlayOnTopTest : public testing::Test {
215 protected:
216 virtual void SetUp() {
217 provider_ = TestContextProvider::Create();
218 output_surface_.reset(new OverlayOutputSurface(provider_));
219 EXPECT_TRUE(output_surface_->BindToClient(&client_));
220 output_surface_->InitWithSingleOverlayValidator();
221 EXPECT_TRUE(output_surface_->overlay_candidate_validator() != NULL);
222
223 resource_provider_ =
224 ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1);
225
226 overlay_processor_.reset(new SingleOverlayProcessor(
227 output_surface_.get(), resource_provider_.get()));
228 overlay_processor_->Initialize();
229 }
230
231 scoped_refptr<TestContextProvider> provider_;
232 scoped_ptr<OverlayOutputSurface> output_surface_;
233 FakeOutputSurfaceClient client_;
234 scoped_ptr<ResourceProvider> resource_provider_;
235 scoped_ptr<SingleOverlayProcessor> overlay_processor_;
236 };
237
238 TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) {
239 scoped_ptr<RenderPass> pass = CreateRenderPass();
240 scoped_ptr<TextureDrawQuad> original_quad = CreateCandidateQuad(
241 resource_provider_.get(), pass->shared_quad_state_list.back());
242
243 pass->quad_list.push_back(
244 original_quad->Copy(pass->shared_quad_state_list.back()));
245 // Add something behind it.
246 pass->quad_list.push_back(CreateCheckeredQuad(
247 resource_provider_.get(), pass->shared_quad_state_list.back()));
248 pass->quad_list.push_back(CreateCheckeredQuad(
249 resource_provider_.get(), pass->shared_quad_state_list.back()));
250
251 RenderPassList pass_list;
252 pass_list.push_back(pass.Pass());
253
254 // Check for potential candidates.
255 overlay_processor_->ProcessForOverlays(&pass_list);
256
257 // This should have one more pass with an overlay.
258 ASSERT_EQ(2U, pass_list.size());
259
260 RenderPass* overlay_pass = pass_list.front();
261 EXPECT_EQ(RenderPass::SIMPLE_OVERLAY, overlay_pass->overlay_state);
262 RenderPass* main_pass = pass_list.back();
263 EXPECT_EQ(RenderPass::NO_OVERLAY, main_pass->overlay_state);
264
265 // Check that the quad is what we expect it to be.
266 EXPECT_EQ(1U, overlay_pass->quad_list.size());
267 const DrawQuad* overlay_quad = overlay_pass->quad_list.front();
268 EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, overlay_quad->material);
269 EXPECT_EQ(original_quad->resource_id,
270 TextureDrawQuad::MaterialCast(overlay_quad)->resource_id);
271 }
272
273 TEST_F(SingleOverlayOnTopTest, NoCandidates) {
274 scoped_ptr<RenderPass> pass = CreateRenderPass();
275 pass->quad_list.push_back(CreateCheckeredQuad(
276 resource_provider_.get(), pass->shared_quad_state_list.back()));
277 pass->quad_list.push_back(CreateCheckeredQuad(
278 resource_provider_.get(), pass->shared_quad_state_list.back()));
279
280 RenderPassList pass_list;
281 pass_list.push_back(pass.Pass());
282
283 RenderPassList original_pass_list;
284 RenderPass::CopyAll(pass_list, &original_pass_list);
285
286 overlay_processor_->ProcessForOverlays(&pass_list);
287 // There should be nothing new here.
288 CompareRenderPassLists(pass_list, original_pass_list);
289 }
290
291 TEST_F(SingleOverlayOnTopTest, OccludedCandidates) {
292 scoped_ptr<RenderPass> pass = CreateRenderPass();
293 pass->quad_list.push_back(CreateCheckeredQuad(
294 resource_provider_.get(), pass->shared_quad_state_list.back()));
295 pass->quad_list.push_back(CreateCheckeredQuad(
296 resource_provider_.get(), pass->shared_quad_state_list.back()));
297
298 pass->quad_list.push_back(
299 CreateCandidateQuad(resource_provider_.get(),
300 pass->shared_quad_state_list.back())
301 .PassAs<DrawQuad>());
302
303 RenderPassList pass_list;
304 pass_list.push_back(pass.Pass());
305
306 RenderPassList original_pass_list;
307 RenderPass::CopyAll(pass_list, &original_pass_list);
308
309 overlay_processor_->ProcessForOverlays(&pass_list);
310 // There should be nothing new here.
311 CompareRenderPassLists(pass_list, original_pass_list);
312 }
313
314 // Test with multiple render passes.
315 TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) {
316 RenderPassList pass_list;
317 pass_list.push_back(CreateRenderPass());
318
319 scoped_ptr<RenderPass> pass = CreateRenderPass();
320 scoped_ptr<TextureDrawQuad> original_quad = CreateCandidateQuad(
321 resource_provider_.get(), pass->shared_quad_state_list.back());
322
323 pass->quad_list.push_back(
324 original_quad->Copy(pass->shared_quad_state_list.back()));
325 // Add something behind it.
326 pass->quad_list.push_back(CreateCheckeredQuad(
327 resource_provider_.get(), pass->shared_quad_state_list.back()));
328 pass->quad_list.push_back(CreateCheckeredQuad(
329 resource_provider_.get(), pass->shared_quad_state_list.back()));
330
331 pass_list.push_back(pass.Pass());
332
333 // Check for potential candidates.
334 overlay_processor_->ProcessForOverlays(&pass_list);
335
336 // This should have one more pass with an overlay.
337 ASSERT_EQ(3U, pass_list.size());
338 }
339
340 TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) {
341 scoped_ptr<RenderPass> pass = CreateRenderPass();
342 scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad(
343 resource_provider_.get(), pass->shared_quad_state_list.back());
344 quad->premultiplied_alpha = true;
345
346 pass->quad_list.push_back(quad.PassAs<DrawQuad>());
347 RenderPassList pass_list;
348 pass_list.push_back(pass.Pass());
349 overlay_processor_->ProcessForOverlays(&pass_list);
350 ASSERT_EQ(1U, pass_list.size());
351 EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
352 }
353
354 TEST_F(SingleOverlayOnTopTest, RejectBlending) {
355 scoped_ptr<RenderPass> pass = CreateRenderPass();
356 scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad(
357 resource_provider_.get(), pass->shared_quad_state_list.back());
358 quad->needs_blending = true;
359
360 pass->quad_list.push_back(quad.PassAs<DrawQuad>());
361 RenderPassList pass_list;
362 pass_list.push_back(pass.Pass());
363 overlay_processor_->ProcessForOverlays(&pass_list);
364 ASSERT_EQ(1U, pass_list.size());
365 EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
366 }
367
368 TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {
369 scoped_ptr<RenderPass> pass = CreateRenderPass();
370 scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad(
371 resource_provider_.get(), pass->shared_quad_state_list.back());
372 quad->background_color = SK_ColorBLACK;
373
374 pass->quad_list.push_back(quad.PassAs<DrawQuad>());
375 RenderPassList pass_list;
376 pass_list.push_back(pass.Pass());
377 overlay_processor_->ProcessForOverlays(&pass_list);
378 ASSERT_EQ(1U, pass_list.size());
379 EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
380 }
381
382 TEST_F(SingleOverlayOnTopTest, RejectBlendMode) {
383 scoped_ptr<RenderPass> pass = CreateRenderPass();
384 scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad(
385 resource_provider_.get(), pass->shared_quad_state_list.back());
386 pass->shared_quad_state_list.back()->blend_mode = SkXfermode::kScreen_Mode;
387
388 pass->quad_list.push_back(quad.PassAs<DrawQuad>());
389 RenderPassList pass_list;
390 pass_list.push_back(pass.Pass());
391 overlay_processor_->ProcessForOverlays(&pass_list);
392 ASSERT_EQ(1U, pass_list.size());
393 EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
394 }
395
396 TEST_F(SingleOverlayOnTopTest, RejectOpacity) {
397 scoped_ptr<RenderPass> pass = CreateRenderPass();
398 scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad(
399 resource_provider_.get(), pass->shared_quad_state_list.back());
400 pass->shared_quad_state_list.back()->opacity = 0.5f;
401
402 pass->quad_list.push_back(quad.PassAs<DrawQuad>());
403 RenderPassList pass_list;
404 pass_list.push_back(pass.Pass());
405 overlay_processor_->ProcessForOverlays(&pass_list);
406 ASSERT_EQ(1U, pass_list.size());
407 EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
408 }
409
410 TEST_F(SingleOverlayOnTopTest, RejectTransform) {
411 scoped_ptr<RenderPass> pass = CreateRenderPass();
412 scoped_ptr<TextureDrawQuad> quad = CreateCandidateQuad(
413 resource_provider_.get(), pass->shared_quad_state_list.back());
414 pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.f,
415 2.f);
416
417 pass->quad_list.push_back(quad.PassAs<DrawQuad>());
418 RenderPassList pass_list;
419 pass_list.push_back(pass.Pass());
420 overlay_processor_->ProcessForOverlays(&pass_list);
421 ASSERT_EQ(1U, pass_list.size());
422 EXPECT_EQ(RenderPass::NO_OVERLAY, pass_list.back()->overlay_state);
423 }
424
425 } // namespace
426 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/overlay_strategy_single_on_top.cc ('k') | cc/quads/render_pass.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698