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

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

Issue 1535833002: Delete CC. (Closed) Base URL: git@github.com:domokit/mojo.git@moz-5
Patch Set: rebase Created 4 years, 11 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
« no previous file with comments | « cc/output/renderer_capabilities.cc ('k') | cc/output/renderer_settings.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 2012 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 "base/message_loop/message_loop.h"
6 #include "cc/output/gl_renderer.h"
7 #include "cc/quads/draw_quad.h"
8 #include "cc/quads/picture_draw_quad.h"
9 #include "cc/quads/texture_draw_quad.h"
10 #include "cc/resources/video_resource_updater.h"
11 #include "cc/test/fake_picture_pile_impl.h"
12 #include "cc/test/pixel_test.h"
13 #include "gpu/command_buffer/client/gles2_interface.h"
14 #include "third_party/skia/include/core/SkColorPriv.h"
15 #include "third_party/skia/include/core/SkImageFilter.h"
16 #include "third_party/skia/include/core/SkMatrix.h"
17 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
18 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
19 #include "ui/gfx/geometry/rect_conversions.h"
20
21 using gpu::gles2::GLES2Interface;
22
23 namespace cc {
24 namespace {
25
26 #if !defined(OS_ANDROID)
27 scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPassId id,
28 const gfx::Rect& rect) {
29 scoped_ptr<RenderPass> pass = RenderPass::Create();
30 const gfx::Rect output_rect = rect;
31 const gfx::Rect damage_rect = rect;
32 const gfx::Transform transform_to_root_target;
33 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
34 return pass.Pass();
35 }
36
37 scoped_ptr<RenderPass> CreateTestRenderPass(
38 RenderPassId id,
39 const gfx::Rect& rect,
40 const gfx::Transform& transform_to_root_target) {
41 scoped_ptr<RenderPass> pass = RenderPass::Create();
42 const gfx::Rect output_rect = rect;
43 const gfx::Rect damage_rect = rect;
44 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
45 return pass.Pass();
46 }
47
48 SharedQuadState* CreateTestSharedQuadState(
49 gfx::Transform content_to_target_transform,
50 const gfx::Rect& rect,
51 RenderPass* render_pass) {
52 const gfx::Size content_bounds = rect.size();
53 const gfx::Rect visible_content_rect = rect;
54 const gfx::Rect clip_rect = rect;
55 const bool is_clipped = false;
56 const float opacity = 1.0f;
57 const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
58 int sorting_context_id = 0;
59 SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
60 shared_state->SetAll(content_to_target_transform,
61 content_bounds,
62 visible_content_rect,
63 clip_rect,
64 is_clipped,
65 opacity,
66 blend_mode,
67 sorting_context_id);
68 return shared_state;
69 }
70
71 SharedQuadState* CreateTestSharedQuadStateClipped(
72 gfx::Transform content_to_target_transform,
73 const gfx::Rect& rect,
74 const gfx::Rect& clip_rect,
75 RenderPass* render_pass) {
76 const gfx::Size content_bounds = rect.size();
77 const gfx::Rect visible_content_rect = clip_rect;
78 const bool is_clipped = true;
79 const float opacity = 1.0f;
80 const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
81 int sorting_context_id = 0;
82 SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
83 shared_state->SetAll(content_to_target_transform,
84 content_bounds,
85 visible_content_rect,
86 clip_rect,
87 is_clipped,
88 opacity,
89 blend_mode,
90 sorting_context_id);
91 return shared_state;
92 }
93
94 void CreateTestRenderPassDrawQuad(const SharedQuadState* shared_state,
95 const gfx::Rect& rect,
96 RenderPassId pass_id,
97 RenderPass* render_pass) {
98 RenderPassDrawQuad* quad =
99 render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
100 quad->SetNew(shared_state,
101 rect,
102 rect,
103 pass_id,
104 0, // mask_resource_id
105 gfx::Vector2dF(), // mask_uv_scale
106 gfx::Size(), // mask_texture_size
107 FilterOperations(), // foreground filters
108 gfx::Vector2dF(), // filters scale
109 FilterOperations()); // background filters
110 }
111
112 void CreateTestTwoColoredTextureDrawQuad(const gfx::Rect& rect,
113 SkColor texel_color,
114 SkColor texel_stripe_color,
115 SkColor background_color,
116 bool premultiplied_alpha,
117 const SharedQuadState* shared_state,
118 ResourceProvider* resource_provider,
119 RenderPass* render_pass) {
120 SkPMColor pixel_color = premultiplied_alpha
121 ? SkPreMultiplyColor(texel_color)
122 : SkPackARGB32NoCheck(SkColorGetA(texel_color),
123 SkColorGetR(texel_color),
124 SkColorGetG(texel_color),
125 SkColorGetB(texel_color));
126 SkPMColor pixel_stripe_color =
127 premultiplied_alpha
128 ? SkPreMultiplyColor(texel_stripe_color)
129 : SkPackARGB32NoCheck(SkColorGetA(texel_stripe_color),
130 SkColorGetR(texel_stripe_color),
131 SkColorGetG(texel_stripe_color),
132 SkColorGetB(texel_stripe_color));
133 std::vector<uint32_t> pixels(rect.size().GetArea(), pixel_color);
134 for (int i = rect.height() / 4; i < (rect.height() * 3 / 4); ++i) {
135 for (int k = rect.width() / 4; k < (rect.width() * 3 / 4); ++k) {
136 pixels[i * rect.width() + k] = pixel_stripe_color;
137 }
138 }
139 ResourceProvider::ResourceId resource = resource_provider->CreateResource(
140 rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
141 RGBA_8888);
142 resource_provider->SetPixels(resource,
143 reinterpret_cast<uint8_t*>(&pixels.front()),
144 rect, rect, gfx::Vector2d());
145
146 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
147 const gfx::PointF uv_top_left(0.0f, 0.0f);
148 const gfx::PointF uv_bottom_right(1.0f, 1.0f);
149 const bool flipped = false;
150 const bool nearest_neighbor = false;
151 TextureDrawQuad* quad =
152 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
153 quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource,
154 premultiplied_alpha, uv_top_left, uv_bottom_right,
155 background_color, vertex_opacity, flipped, nearest_neighbor);
156 }
157
158 void CreateTestTextureDrawQuad(const gfx::Rect& rect,
159 SkColor texel_color,
160 SkColor background_color,
161 bool premultiplied_alpha,
162 const SharedQuadState* shared_state,
163 ResourceProvider* resource_provider,
164 RenderPass* render_pass) {
165 SkPMColor pixel_color = premultiplied_alpha ?
166 SkPreMultiplyColor(texel_color) :
167 SkPackARGB32NoCheck(SkColorGetA(texel_color),
168 SkColorGetR(texel_color),
169 SkColorGetG(texel_color),
170 SkColorGetB(texel_color));
171 size_t num_pixels = static_cast<size_t>(rect.width()) * rect.height();
172 std::vector<uint32_t> pixels(num_pixels, pixel_color);
173
174 ResourceProvider::ResourceId resource = resource_provider->CreateResource(
175 rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
176 RGBA_8888);
177 resource_provider->CopyToResource(
178 resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size());
179
180 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
181
182 const gfx::PointF uv_top_left(0.0f, 0.0f);
183 const gfx::PointF uv_bottom_right(1.0f, 1.0f);
184 const bool flipped = false;
185 const bool nearest_neighbor = false;
186 TextureDrawQuad* quad =
187 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
188 quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource,
189 premultiplied_alpha, uv_top_left, uv_bottom_right,
190 background_color, vertex_opacity, flipped, nearest_neighbor);
191 }
192
193 void CreateTestYUVVideoDrawQuad_FromVideoFrame(
194 const SharedQuadState* shared_state,
195 scoped_refptr<media::VideoFrame> video_frame,
196 uint8 alpha_value,
197 const gfx::RectF& tex_coord_rect,
198 RenderPass* render_pass,
199 VideoResourceUpdater* video_resource_updater,
200 const gfx::Rect& rect,
201 const gfx::Rect& visible_rect,
202 ResourceProvider* resource_provider) {
203 const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A);
204 const YUVVideoDrawQuad::ColorSpace color_space =
205 (video_frame->format() == media::VideoFrame::YV12J
206 ? YUVVideoDrawQuad::JPEG
207 : YUVVideoDrawQuad::REC_601);
208 const gfx::Rect opaque_rect(0, 0, 0, 0);
209
210 if (with_alpha) {
211 memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value,
212 video_frame->stride(media::VideoFrame::kAPlane) *
213 video_frame->rows(media::VideoFrame::kAPlane));
214 }
215
216 VideoFrameExternalResources resources =
217 video_resource_updater->CreateExternalResourcesFromVideoFrame(
218 video_frame);
219
220 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
221 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
222 resources.mailboxes.size());
223 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
224 resources.release_callbacks.size());
225
226 ResourceProvider::ResourceId y_resource =
227 resource_provider->CreateResourceFromTextureMailbox(
228 resources.mailboxes[media::VideoFrame::kYPlane],
229 SingleReleaseCallbackImpl::Create(
230 resources.release_callbacks[media::VideoFrame::kYPlane]));
231 ResourceProvider::ResourceId u_resource =
232 resource_provider->CreateResourceFromTextureMailbox(
233 resources.mailboxes[media::VideoFrame::kUPlane],
234 SingleReleaseCallbackImpl::Create(
235 resources.release_callbacks[media::VideoFrame::kUPlane]));
236 ResourceProvider::ResourceId v_resource =
237 resource_provider->CreateResourceFromTextureMailbox(
238 resources.mailboxes[media::VideoFrame::kVPlane],
239 SingleReleaseCallbackImpl::Create(
240 resources.release_callbacks[media::VideoFrame::kVPlane]));
241 ResourceProvider::ResourceId a_resource = 0;
242 if (with_alpha) {
243 a_resource = resource_provider->CreateResourceFromTextureMailbox(
244 resources.mailboxes[media::VideoFrame::kAPlane],
245 SingleReleaseCallbackImpl::Create(
246 resources.release_callbacks[media::VideoFrame::kAPlane]));
247 }
248
249 YUVVideoDrawQuad* yuv_quad =
250 render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
251 yuv_quad->SetNew(shared_state, rect, opaque_rect, visible_rect,
252 tex_coord_rect, video_frame->coded_size(), y_resource,
253 u_resource, v_resource, a_resource, color_space);
254 }
255
256 void CreateTestYUVVideoDrawQuad_Striped(
257 const SharedQuadState* shared_state,
258 media::VideoFrame::Format format,
259 bool is_transparent,
260 const gfx::RectF& tex_coord_rect,
261 RenderPass* render_pass,
262 VideoResourceUpdater* video_resource_updater,
263 const gfx::Rect& rect,
264 const gfx::Rect& visible_rect,
265 ResourceProvider* resource_provider) {
266 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
267 format, rect.size(), rect, rect.size(), base::TimeDelta());
268
269 // YUV values representing a striped pattern, for validating texture
270 // coordinates for sampling.
271 uint8_t y_value = 0;
272 uint8_t u_value = 0;
273 uint8_t v_value = 0;
274 for (int i = 0; i < video_frame->rows(media::VideoFrame::kYPlane); ++i) {
275 uint8_t* y_row = video_frame->data(media::VideoFrame::kYPlane) +
276 video_frame->stride(media::VideoFrame::kYPlane) * i;
277 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kYPlane);
278 ++j) {
279 y_row[j] = (y_value += 1);
280 }
281 }
282 for (int i = 0; i < video_frame->rows(media::VideoFrame::kUPlane); ++i) {
283 uint8_t* u_row = video_frame->data(media::VideoFrame::kUPlane) +
284 video_frame->stride(media::VideoFrame::kUPlane) * i;
285 uint8_t* v_row = video_frame->data(media::VideoFrame::kVPlane) +
286 video_frame->stride(media::VideoFrame::kVPlane) * i;
287 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kUPlane);
288 ++j) {
289 u_row[j] = (u_value += 3);
290 v_row[j] = (v_value += 5);
291 }
292 }
293 uint8 alpha_value = is_transparent ? 0 : 128;
294 CreateTestYUVVideoDrawQuad_FromVideoFrame(
295 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
296 video_resource_updater, rect, visible_rect, resource_provider);
297 }
298
299 // Creates a video frame of size background_size filled with yuv_background,
300 // and then draws a foreground rectangle in a different color on top of
301 // that. The foreground rectangle must have coordinates that are divisible
302 // by 2 because YUV is a block format.
303 void CreateTestYUVVideoDrawQuad_TwoColor(
304 const SharedQuadState* shared_state,
305 media::VideoFrame::Format format,
306 bool is_transparent,
307 const gfx::RectF& tex_coord_rect,
308 const gfx::Size& background_size,
309 const gfx::Rect& visible_rect,
310 uint8 y_background,
311 uint8 u_background,
312 uint8 v_background,
313 const gfx::Rect& foreground_rect,
314 uint8 y_foreground,
315 uint8 u_foreground,
316 uint8 v_foreground,
317 RenderPass* render_pass,
318 VideoResourceUpdater* video_resource_updater,
319 ResourceProvider* resource_provider) {
320 const gfx::Rect rect(background_size);
321
322 scoped_refptr<media::VideoFrame> video_frame =
323 media::VideoFrame::CreateFrame(format, background_size, foreground_rect,
324 foreground_rect.size(), base::TimeDelta());
325
326 int planes[] = {media::VideoFrame::kYPlane,
327 media::VideoFrame::kUPlane,
328 media::VideoFrame::kVPlane};
329 uint8 yuv_background[] = {y_background, u_background, v_background};
330 uint8 yuv_foreground[] = {y_foreground, u_foreground, v_foreground};
331 int sample_size[] = {1, 2, 2};
332
333 for (int i = 0; i < 3; ++i) {
334 memset(video_frame->data(planes[i]), yuv_background[i],
335 video_frame->stride(planes[i]) * video_frame->rows(planes[i]));
336 }
337
338 for (int i = 0; i < 3; ++i) {
339 // Since yuv encoding uses block encoding, widths have to be divisible
340 // by the sample size in order for this function to behave properly.
341 DCHECK_EQ(foreground_rect.x() % sample_size[i], 0);
342 DCHECK_EQ(foreground_rect.y() % sample_size[i], 0);
343 DCHECK_EQ(foreground_rect.width() % sample_size[i], 0);
344 DCHECK_EQ(foreground_rect.height() % sample_size[i], 0);
345
346 gfx::Rect sample_rect(foreground_rect.x() / sample_size[i],
347 foreground_rect.y() / sample_size[i],
348 foreground_rect.width() / sample_size[i],
349 foreground_rect.height() / sample_size[i]);
350 for (int y = sample_rect.y(); y < sample_rect.bottom(); ++y) {
351 for (int x = sample_rect.x(); x < sample_rect.right(); ++x) {
352 size_t offset = y * video_frame->stride(planes[i]) + x;
353 video_frame->data(planes[i])[offset] = yuv_foreground[i];
354 }
355 }
356 }
357
358 uint8 alpha_value = 255;
359 CreateTestYUVVideoDrawQuad_FromVideoFrame(
360 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
361 video_resource_updater, rect, visible_rect, resource_provider);
362 }
363
364 void CreateTestYUVVideoDrawQuad_Solid(
365 const SharedQuadState* shared_state,
366 media::VideoFrame::Format format,
367 bool is_transparent,
368 const gfx::RectF& tex_coord_rect,
369 uint8 y,
370 uint8 u,
371 uint8 v,
372 RenderPass* render_pass,
373 VideoResourceUpdater* video_resource_updater,
374 const gfx::Rect& rect,
375 const gfx::Rect& visible_rect,
376 ResourceProvider* resource_provider) {
377 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
378 format, rect.size(), rect, rect.size(), base::TimeDelta());
379
380 // YUV values of a solid, constant, color. Useful for testing that color
381 // space/color range are being handled properly.
382 memset(video_frame->data(media::VideoFrame::kYPlane), y,
383 video_frame->stride(media::VideoFrame::kYPlane) *
384 video_frame->rows(media::VideoFrame::kYPlane));
385 memset(video_frame->data(media::VideoFrame::kUPlane), u,
386 video_frame->stride(media::VideoFrame::kUPlane) *
387 video_frame->rows(media::VideoFrame::kUPlane));
388 memset(video_frame->data(media::VideoFrame::kVPlane), v,
389 video_frame->stride(media::VideoFrame::kVPlane) *
390 video_frame->rows(media::VideoFrame::kVPlane));
391
392 uint8 alpha_value = is_transparent ? 0 : 128;
393 CreateTestYUVVideoDrawQuad_FromVideoFrame(
394 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
395 video_resource_updater, rect, visible_rect, resource_provider);
396 }
397
398 typedef ::testing::Types<GLRenderer,
399 SoftwareRenderer,
400 GLRendererWithExpandedViewport,
401 SoftwareRendererWithExpandedViewport> RendererTypes;
402 TYPED_TEST_CASE(RendererPixelTest, RendererTypes);
403
404 template <typename RendererType>
405 class SoftwareRendererPixelTest : public RendererPixelTest<RendererType> {};
406
407 typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport>
408 SoftwareRendererTypes;
409 TYPED_TEST_CASE(SoftwareRendererPixelTest, SoftwareRendererTypes);
410
411 template <typename RendererType>
412 class FuzzyForSoftwareOnlyPixelComparator : public PixelComparator {
413 public:
414 explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha)
415 : fuzzy_(discard_alpha), exact_(discard_alpha) {}
416
417 bool Compare(const SkBitmap& actual_bmp,
418 const SkBitmap& expected_bmp) const override;
419
420 private:
421 FuzzyPixelOffByOneComparator fuzzy_;
422 ExactPixelComparator exact_;
423 };
424
425 template<>
426 bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare(
427 const SkBitmap& actual_bmp,
428 const SkBitmap& expected_bmp) const {
429 return fuzzy_.Compare(actual_bmp, expected_bmp);
430 }
431
432 template <>
433 bool FuzzyForSoftwareOnlyPixelComparator<
434 SoftwareRendererWithExpandedViewport>::Compare(
435 const SkBitmap& actual_bmp,
436 const SkBitmap& expected_bmp) const {
437 return fuzzy_.Compare(actual_bmp, expected_bmp);
438 }
439
440 template<typename RendererType>
441 bool FuzzyForSoftwareOnlyPixelComparator<RendererType>::Compare(
442 const SkBitmap& actual_bmp,
443 const SkBitmap& expected_bmp) const {
444 return exact_.Compare(actual_bmp, expected_bmp);
445 }
446
447 TYPED_TEST(RendererPixelTest, SimpleGreenRect) {
448 gfx::Rect rect(this->device_viewport_size_);
449
450 RenderPassId id(1, 1);
451 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
452
453 SharedQuadState* shared_state =
454 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
455
456 SolidColorDrawQuad* color_quad =
457 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
458 color_quad->SetNew(shared_state, rect, rect, SK_ColorGREEN, false);
459
460 RenderPassList pass_list;
461 pass_list.push_back(pass.Pass());
462
463 EXPECT_TRUE(this->RunPixelTest(
464 &pass_list,
465 base::FilePath(FILE_PATH_LITERAL("green.png")),
466 ExactPixelComparator(true)));
467 }
468
469 TYPED_TEST(RendererPixelTest, SimpleGreenRect_NonRootRenderPass) {
470 gfx::Rect rect(this->device_viewport_size_);
471 gfx::Rect small_rect(100, 100);
472
473 RenderPassId child_id(2, 1);
474 scoped_ptr<RenderPass> child_pass =
475 CreateTestRenderPass(child_id, small_rect, gfx::Transform());
476
477 SharedQuadState* child_shared_state =
478 CreateTestSharedQuadState(gfx::Transform(), small_rect, child_pass.get());
479
480 SolidColorDrawQuad* color_quad =
481 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
482 color_quad->SetNew(child_shared_state, rect, rect, SK_ColorGREEN, false);
483
484 RenderPassId root_id(1, 1);
485 scoped_ptr<RenderPass> root_pass =
486 CreateTestRenderPass(root_id, rect, gfx::Transform());
487
488 SharedQuadState* root_shared_state =
489 CreateTestSharedQuadState(gfx::Transform(), rect, root_pass.get());
490
491 CreateTestRenderPassDrawQuad(
492 root_shared_state, small_rect, child_id, root_pass.get());
493
494 RenderPass* child_pass_ptr = child_pass.get();
495
496 RenderPassList pass_list;
497 pass_list.push_back(child_pass.Pass());
498 pass_list.push_back(root_pass.Pass());
499
500 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
501 &pass_list,
502 child_pass_ptr,
503 base::FilePath(FILE_PATH_LITERAL("green_small.png")),
504 ExactPixelComparator(true)));
505 }
506
507 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithoutBackground) {
508 gfx::Rect rect(this->device_viewport_size_);
509
510 RenderPassId id(1, 1);
511 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
512
513 SharedQuadState* shared_state =
514 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
515
516 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
517 SkColorSetARGB(128, 0, 255, 0), // Texel color.
518 SK_ColorTRANSPARENT, // Background color.
519 true, // Premultiplied alpha.
520 shared_state,
521 this->resource_provider_.get(),
522 pass.get());
523
524 SolidColorDrawQuad* color_quad =
525 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
526 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
527
528 RenderPassList pass_list;
529 pass_list.push_back(pass.Pass());
530
531 EXPECT_TRUE(this->RunPixelTest(
532 &pass_list,
533 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
534 FuzzyPixelOffByOneComparator(true)));
535 }
536
537 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithBackground) {
538 gfx::Rect rect(this->device_viewport_size_);
539
540 RenderPassId id(1, 1);
541 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
542
543 SharedQuadState* texture_quad_state =
544 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
545 texture_quad_state->opacity = 0.8f;
546
547 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
548 SkColorSetARGB(204, 120, 255, 120), // Texel color.
549 SK_ColorGREEN, // Background color.
550 true, // Premultiplied alpha.
551 texture_quad_state,
552 this->resource_provider_.get(),
553 pass.get());
554
555 SharedQuadState* color_quad_state =
556 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
557 SolidColorDrawQuad* color_quad =
558 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
559 color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
560
561 RenderPassList pass_list;
562 pass_list.push_back(pass.Pass());
563
564 EXPECT_TRUE(this->RunPixelTest(
565 &pass_list,
566 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
567 FuzzyPixelOffByOneComparator(true)));
568 }
569
570 template <typename QuadType>
571 static const base::FilePath::CharType* IntersectingQuadImage() {
572 return FILE_PATH_LITERAL("intersecting_blue_green_squares.png");
573 }
574 template <>
575 const base::FilePath::CharType* IntersectingQuadImage<SolidColorDrawQuad>() {
576 return FILE_PATH_LITERAL("intersecting_blue_green.png");
577 }
578 template <>
579 const base::FilePath::CharType* IntersectingQuadImage<YUVVideoDrawQuad>() {
580 return FILE_PATH_LITERAL("intersecting_blue_green_squares_video.png");
581 }
582
583 template <typename TypeParam>
584 class IntersectingQuadPixelTest : public RendererPixelTest<TypeParam> {
585 protected:
586 void SetupQuadStateAndRenderPass() {
587 // This sets up a pair of draw quads. They are both rotated
588 // relative to the root plane, they are also rotated relative to each other.
589 // The intersect in the middle at a non-perpendicular angle so that any
590 // errors are hopefully magnified.
591 // The quads should intersect correctly, as in the front quad should only
592 // be partially in front of the back quad, and partially behind.
593
594 viewport_rect_ = gfx::Rect(this->device_viewport_size_);
595 quad_rect_ = gfx::Rect(0, 0, this->device_viewport_size_.width(),
596 this->device_viewport_size_.height() / 2.0);
597
598 RenderPassId id(1, 1);
599 render_pass_ = CreateTestRootRenderPass(id, viewport_rect_);
600
601 // Create the front quad rotated on the Z and Y axis.
602 gfx::Transform trans;
603 trans.Translate3d(0, 0, 0.707 * this->device_viewport_size_.width() / 2.0);
604 trans.RotateAboutZAxis(45.0);
605 trans.RotateAboutYAxis(45.0);
606 front_quad_state_ =
607 CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get());
608 front_quad_state_->clip_rect = quad_rect_;
609 // Make sure they end up in a 3d sorting context.
610 front_quad_state_->sorting_context_id = 1;
611
612 // Create the back quad, and rotate on just the y axis. This will intersect
613 // the first quad partially.
614 trans = gfx::Transform();
615 trans.Translate3d(0, 0, -0.707 * this->device_viewport_size_.width() / 2.0);
616 trans.RotateAboutYAxis(-45.0);
617 back_quad_state_ =
618 CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get());
619 back_quad_state_->sorting_context_id = 1;
620 back_quad_state_->clip_rect = quad_rect_;
621 }
622 template <typename T>
623 void AppendBackgroundAndRunTest(const PixelComparator& comparator) {
624 SharedQuadState* background_quad_state = CreateTestSharedQuadState(
625 gfx::Transform(), viewport_rect_, render_pass_.get());
626 SolidColorDrawQuad* background_quad =
627 render_pass_->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
628 background_quad->SetNew(background_quad_state, viewport_rect_,
629 viewport_rect_, SK_ColorWHITE, false);
630 pass_list_.push_back(render_pass_.Pass());
631 const base::FilePath::CharType* fileName = IntersectingQuadImage<T>();
632 EXPECT_TRUE(
633 this->RunPixelTest(&pass_list_, base::FilePath(fileName), comparator));
634 }
635 template <typename T>
636 T* CreateAndAppendDrawQuad() {
637 return render_pass_->CreateAndAppendDrawQuad<T>();
638 }
639
640 scoped_ptr<RenderPass> render_pass_;
641 gfx::Rect viewport_rect_;
642 SharedQuadState* front_quad_state_;
643 SharedQuadState* back_quad_state_;
644 gfx::Rect quad_rect_;
645 RenderPassList pass_list_;
646 };
647
648 template <typename TypeParam>
649 class IntersectingQuadGLPixelTest
650 : public IntersectingQuadPixelTest<TypeParam> {
651 public:
652 void SetUp() override {
653 IntersectingQuadPixelTest<TypeParam>::SetUp();
654 video_resource_updater_.reset(
655 new VideoResourceUpdater(this->output_surface_->context_provider(),
656 this->resource_provider_.get()));
657 video_resource_updater2_.reset(
658 new VideoResourceUpdater(this->output_surface_->context_provider(),
659 this->resource_provider_.get()));
660 }
661
662 protected:
663 scoped_ptr<VideoResourceUpdater> video_resource_updater_;
664 scoped_ptr<VideoResourceUpdater> video_resource_updater2_;
665 };
666
667 template <typename TypeParam>
668 class IntersectingQuadSoftwareTest
669 : public IntersectingQuadPixelTest<TypeParam> {};
670
671 typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport>
672 SoftwareRendererTypes;
673 typedef ::testing::Types<GLRenderer, GLRendererWithExpandedViewport>
674 GLRendererTypes;
675
676 TYPED_TEST_CASE(IntersectingQuadPixelTest, RendererTypes);
677 TYPED_TEST_CASE(IntersectingQuadGLPixelTest, GLRendererTypes);
678 TYPED_TEST_CASE(IntersectingQuadSoftwareTest, SoftwareRendererTypes);
679
680 TYPED_TEST(IntersectingQuadPixelTest, SolidColorQuads) {
681 this->SetupQuadStateAndRenderPass();
682
683 SolidColorDrawQuad* quad =
684 this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>();
685 SolidColorDrawQuad* quad2 =
686 this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>();
687
688 quad->SetNew(this->front_quad_state_, this->quad_rect_, this->quad_rect_,
689 SK_ColorBLUE, false);
690 quad2->SetNew(this->back_quad_state_, this->quad_rect_, this->quad_rect_,
691 SK_ColorGREEN, false);
692 SCOPED_TRACE("IntersectingSolidColorQuads");
693 this->template AppendBackgroundAndRunTest<SolidColorDrawQuad>(
694 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
695 }
696
697 template <typename TypeParam>
698 SkColor GetColor(const SkColor& color) {
699 return color;
700 }
701
702 template <>
703 SkColor GetColor<GLRenderer>(const SkColor& color) {
704 return SkColorSetARGB(SkColorGetA(color), SkColorGetB(color),
705 SkColorGetG(color), SkColorGetR(color));
706 }
707 template <>
708 SkColor GetColor<GLRendererWithExpandedViewport>(const SkColor& color) {
709 return GetColor<GLRenderer>(color);
710 }
711
712 TYPED_TEST(IntersectingQuadPixelTest, TexturedQuads) {
713 this->SetupQuadStateAndRenderPass();
714 CreateTestTwoColoredTextureDrawQuad(
715 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
716 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
717 true, this->front_quad_state_, this->resource_provider_.get(),
718 this->render_pass_.get());
719 CreateTestTwoColoredTextureDrawQuad(
720 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
721 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
722 true, this->back_quad_state_, this->resource_provider_.get(),
723 this->render_pass_.get());
724
725 SCOPED_TRACE("IntersectingTexturedQuads");
726 this->template AppendBackgroundAndRunTest<TextureDrawQuad>(
727 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
728 }
729
730 TYPED_TEST(IntersectingQuadSoftwareTest, PictureQuads) {
731 this->SetupQuadStateAndRenderPass();
732 gfx::RectF outer_rect(this->quad_rect_);
733 gfx::RectF inner_rect(this->quad_rect_.x() + (this->quad_rect_.width() / 4),
734 this->quad_rect_.y() + (this->quad_rect_.height() / 4),
735 this->quad_rect_.width() / 2,
736 this->quad_rect_.height() / 2);
737
738 SkPaint black_paint;
739 black_paint.setColor(SK_ColorBLACK);
740 SkPaint blue_paint;
741 blue_paint.setColor(SK_ColorBLUE);
742 SkPaint green_paint;
743 green_paint.setColor(SK_ColorGREEN);
744
745 scoped_ptr<FakePicturePile> blue_recording =
746 FakePicturePile::CreateFilledPile(gfx::Size(1000, 1000),
747 this->quad_rect_.size());
748 blue_recording->add_draw_rect_with_paint(outer_rect, black_paint);
749 blue_recording->add_draw_rect_with_paint(inner_rect, blue_paint);
750 blue_recording->RerecordPile();
751 scoped_refptr<FakePicturePileImpl> blue_pile =
752 FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);
753
754 PictureDrawQuad* blue_quad =
755 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
756
757 blue_quad->SetNew(this->front_quad_state_, this->quad_rect_, gfx::Rect(),
758 this->quad_rect_, this->quad_rect_, this->quad_rect_.size(),
759 false, RGBA_8888, this->quad_rect_, 1.f, blue_pile);
760
761 scoped_ptr<FakePicturePile> green_recording =
762 FakePicturePile::CreateFilledPile(this->quad_rect_.size(),
763 this->quad_rect_.size());
764 green_recording->add_draw_rect_with_paint(outer_rect, green_paint);
765 green_recording->add_draw_rect_with_paint(inner_rect, black_paint);
766 green_recording->RerecordPile();
767 scoped_refptr<FakePicturePileImpl> green_pile =
768 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
769
770 PictureDrawQuad* green_quad =
771 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
772 green_quad->SetNew(this->back_quad_state_, this->quad_rect_, gfx::Rect(),
773 this->quad_rect_, this->quad_rect_,
774 this->quad_rect_.size(), false, RGBA_8888,
775 this->quad_rect_, 1.f, green_pile);
776 SCOPED_TRACE("IntersectingPictureQuadsPass");
777 this->template AppendBackgroundAndRunTest<PictureDrawQuad>(
778 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
779 }
780
781 TYPED_TEST(IntersectingQuadPixelTest, RenderPassQuads) {
782 this->SetupQuadStateAndRenderPass();
783 RenderPassId child_pass_id1(2, 2);
784 RenderPassId child_pass_id2(2, 3);
785 scoped_ptr<RenderPass> child_pass1 =
786 CreateTestRenderPass(child_pass_id1, this->quad_rect_, gfx::Transform());
787 SharedQuadState* child1_quad_state = CreateTestSharedQuadState(
788 gfx::Transform(), this->quad_rect_, child_pass1.get());
789 scoped_ptr<RenderPass> child_pass2 =
790 CreateTestRenderPass(child_pass_id2, this->quad_rect_, gfx::Transform());
791 SharedQuadState* child2_quad_state = CreateTestSharedQuadState(
792 gfx::Transform(), this->quad_rect_, child_pass2.get());
793
794 CreateTestTwoColoredTextureDrawQuad(
795 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
796 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
797 true, child1_quad_state, this->resource_provider_.get(),
798 child_pass1.get());
799 CreateTestTwoColoredTextureDrawQuad(
800 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
801 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
802 true, child2_quad_state, this->resource_provider_.get(),
803 child_pass2.get());
804
805 CreateTestRenderPassDrawQuad(this->front_quad_state_, this->quad_rect_,
806 child_pass_id1, this->render_pass_.get());
807 CreateTestRenderPassDrawQuad(this->back_quad_state_, this->quad_rect_,
808 child_pass_id2, this->render_pass_.get());
809
810 this->pass_list_.push_back(child_pass1.Pass());
811 this->pass_list_.push_back(child_pass2.Pass());
812 SCOPED_TRACE("IntersectingRenderQuadsPass");
813 this->template AppendBackgroundAndRunTest<RenderPassDrawQuad>(
814 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
815 }
816
817 TYPED_TEST(IntersectingQuadGLPixelTest, YUVVideoQuads) {
818 this->SetupQuadStateAndRenderPass();
819 gfx::Rect inner_rect(
820 ((this->quad_rect_.x() + (this->quad_rect_.width() / 4)) & ~0xF),
821 ((this->quad_rect_.y() + (this->quad_rect_.height() / 4)) & ~0xF),
822 (this->quad_rect_.width() / 2) & ~0xF,
823 (this->quad_rect_.height() / 2) & ~0xF);
824
825 CreateTestYUVVideoDrawQuad_TwoColor(
826 this->front_quad_state_, media::VideoFrame::YV12J, false,
827 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(),
828 this->quad_rect_, 0, 128, 128, inner_rect, 29, 255, 107,
829 this->render_pass_.get(), this->video_resource_updater_.get(),
830 this->resource_provider_.get());
831
832 CreateTestYUVVideoDrawQuad_TwoColor(
833 this->back_quad_state_, media::VideoFrame::YV12J, false,
834 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(),
835 this->quad_rect_, 149, 43, 21, inner_rect, 0, 128, 128,
836 this->render_pass_.get(), this->video_resource_updater2_.get(),
837 this->resource_provider_.get());
838
839 SCOPED_TRACE("IntersectingVideoQuads");
840 this->template AppendBackgroundAndRunTest<YUVVideoDrawQuad>(
841 FuzzyPixelOffByOneComparator(false));
842 }
843
844 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
845 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) {
846 gfx::Rect rect(this->device_viewport_size_);
847
848 RenderPassId id(1, 1);
849 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
850
851 SharedQuadState* shared_state =
852 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
853
854 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
855 SkColorSetARGB(128, 0, 255, 0), // Texel color.
856 SK_ColorTRANSPARENT, // Background color.
857 false, // Premultiplied alpha.
858 shared_state,
859 this->resource_provider_.get(),
860 pass.get());
861
862 SolidColorDrawQuad* color_quad =
863 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
864 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
865
866 RenderPassList pass_list;
867 pass_list.push_back(pass.Pass());
868
869 EXPECT_TRUE(this->RunPixelTest(
870 &pass_list,
871 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
872 FuzzyPixelOffByOneComparator(true)));
873 }
874
875 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
876 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
877 gfx::Rect rect(this->device_viewport_size_);
878
879 RenderPassId id(1, 1);
880 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
881
882 SharedQuadState* texture_quad_state =
883 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
884 texture_quad_state->opacity = 0.8f;
885
886 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
887 SkColorSetARGB(204, 120, 255, 120), // Texel color.
888 SK_ColorGREEN, // Background color.
889 false, // Premultiplied alpha.
890 texture_quad_state,
891 this->resource_provider_.get(),
892 pass.get());
893
894 SharedQuadState* color_quad_state =
895 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
896 SolidColorDrawQuad* color_quad =
897 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
898 color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
899
900 RenderPassList pass_list;
901 pass_list.push_back(pass.Pass());
902
903 EXPECT_TRUE(this->RunPixelTest(
904 &pass_list,
905 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
906 FuzzyPixelOffByOneComparator(true)));
907 }
908
909 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) {
910 gfx::Rect viewport_rect(this->device_viewport_size_);
911
912 RenderPassId root_pass_id(1, 1);
913 scoped_ptr<RenderPass> root_pass =
914 CreateTestRootRenderPass(root_pass_id, viewport_rect);
915
916 RenderPassId child_pass_id(2, 2);
917 gfx::Rect pass_rect(this->device_viewport_size_);
918 gfx::Transform transform_to_root;
919 scoped_ptr<RenderPass> child_pass =
920 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
921
922 gfx::Transform content_to_target_transform;
923 SharedQuadState* shared_state = CreateTestSharedQuadState(
924 content_to_target_transform, viewport_rect, child_pass.get());
925 shared_state->opacity = 0.5f;
926
927 gfx::Rect blue_rect(0,
928 0,
929 this->device_viewport_size_.width(),
930 this->device_viewport_size_.height() / 2);
931 SolidColorDrawQuad* blue =
932 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
933 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
934 gfx::Rect yellow_rect(0,
935 this->device_viewport_size_.height() / 2,
936 this->device_viewport_size_.width(),
937 this->device_viewport_size_.height() / 2);
938 SolidColorDrawQuad* yellow =
939 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
940 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
941
942 SharedQuadState* blank_state = CreateTestSharedQuadState(
943 content_to_target_transform, viewport_rect, child_pass.get());
944
945 SolidColorDrawQuad* white =
946 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
947 white->SetNew(
948 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
949
950 SharedQuadState* pass_shared_state =
951 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
952
953 SkScalar matrix[20];
954 float amount = 0.5f;
955 matrix[0] = 0.213f + 0.787f * amount;
956 matrix[1] = 0.715f - 0.715f * amount;
957 matrix[2] = 1.f - (matrix[0] + matrix[1]);
958 matrix[3] = matrix[4] = 0;
959 matrix[5] = 0.213f - 0.213f * amount;
960 matrix[6] = 0.715f + 0.285f * amount;
961 matrix[7] = 1.f - (matrix[5] + matrix[6]);
962 matrix[8] = matrix[9] = 0;
963 matrix[10] = 0.213f - 0.213f * amount;
964 matrix[11] = 0.715f - 0.715f * amount;
965 matrix[12] = 1.f - (matrix[10] + matrix[11]);
966 matrix[13] = matrix[14] = 0;
967 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
968 matrix[18] = 1;
969 skia::RefPtr<SkColorFilter> colorFilter(
970 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
971 skia::RefPtr<SkImageFilter> filter =
972 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
973 FilterOperations filters;
974 filters.Append(FilterOperation::CreateReferenceFilter(filter));
975
976 RenderPassDrawQuad* render_pass_quad =
977 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
978 render_pass_quad->SetNew(pass_shared_state,
979 pass_rect,
980 pass_rect,
981 child_pass_id,
982 0,
983 gfx::Vector2dF(),
984 gfx::Size(),
985 filters,
986 gfx::Vector2dF(),
987 FilterOperations());
988
989 RenderPassList pass_list;
990 pass_list.push_back(child_pass.Pass());
991 pass_list.push_back(root_pass.Pass());
992
993 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
994 // renderer so use a fuzzy comparator.
995 EXPECT_TRUE(this->RunPixelTest(
996 &pass_list,
997 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
998 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
999 }
1000
1001 TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) {
1002 gfx::Rect viewport_rect(this->device_viewport_size_);
1003
1004 RenderPassId root_pass_id(1, 1);
1005 scoped_ptr<RenderPass> root_pass =
1006 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1007
1008 RenderPassId child_pass_id(2, 2);
1009 gfx::Rect pass_rect(this->device_viewport_size_);
1010 gfx::Transform transform_to_root;
1011 scoped_ptr<RenderPass> child_pass =
1012 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1013
1014 gfx::Transform content_to_target_transform;
1015 SharedQuadState* shared_state = CreateTestSharedQuadState(
1016 content_to_target_transform, viewport_rect, child_pass.get());
1017 shared_state->opacity = 0.5f;
1018
1019 gfx::Rect blue_rect(0,
1020 0,
1021 this->device_viewport_size_.width(),
1022 this->device_viewport_size_.height() / 2);
1023 SolidColorDrawQuad* blue =
1024 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1025 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1026 gfx::Rect yellow_rect(0,
1027 this->device_viewport_size_.height() / 2,
1028 this->device_viewport_size_.width(),
1029 this->device_viewport_size_.height() / 2);
1030 SolidColorDrawQuad* yellow =
1031 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1032 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1033
1034 SharedQuadState* blank_state = CreateTestSharedQuadState(
1035 content_to_target_transform, viewport_rect, child_pass.get());
1036
1037 SolidColorDrawQuad* white =
1038 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1039 white->SetNew(
1040 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1041
1042 SharedQuadState* pass_shared_state =
1043 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1044
1045 FilterOperations filters;
1046 filters.Append(FilterOperation::CreateSaturateFilter(0.5f));
1047
1048 RenderPassDrawQuad* render_pass_quad =
1049 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1050 render_pass_quad->SetNew(pass_shared_state,
1051 pass_rect,
1052 pass_rect,
1053 child_pass_id,
1054 0,
1055 gfx::Vector2dF(),
1056 gfx::Size(),
1057 filters,
1058 gfx::Vector2dF(),
1059 FilterOperations());
1060
1061 RenderPassList pass_list;
1062 pass_list.push_back(child_pass.Pass());
1063 pass_list.push_back(root_pass.Pass());
1064
1065 EXPECT_TRUE(this->RunPixelTest(
1066 &pass_list,
1067 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1068 ExactPixelComparator(true)));
1069 }
1070
1071 TYPED_TEST(RendererPixelTest, FastPassFilterChain) {
1072 gfx::Rect viewport_rect(this->device_viewport_size_);
1073
1074 RenderPassId root_pass_id(1, 1);
1075 scoped_ptr<RenderPass> root_pass =
1076 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1077
1078 RenderPassId child_pass_id(2, 2);
1079 gfx::Rect pass_rect(this->device_viewport_size_);
1080 gfx::Transform transform_to_root;
1081 scoped_ptr<RenderPass> child_pass =
1082 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1083
1084 gfx::Transform content_to_target_transform;
1085 SharedQuadState* shared_state = CreateTestSharedQuadState(
1086 content_to_target_transform, viewport_rect, child_pass.get());
1087 shared_state->opacity = 0.5f;
1088
1089 gfx::Rect blue_rect(0,
1090 0,
1091 this->device_viewport_size_.width(),
1092 this->device_viewport_size_.height() / 2);
1093 SolidColorDrawQuad* blue =
1094 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1095 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1096 gfx::Rect yellow_rect(0,
1097 this->device_viewport_size_.height() / 2,
1098 this->device_viewport_size_.width(),
1099 this->device_viewport_size_.height() / 2);
1100 SolidColorDrawQuad* yellow =
1101 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1102 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1103
1104 SharedQuadState* blank_state = CreateTestSharedQuadState(
1105 content_to_target_transform, viewport_rect, child_pass.get());
1106
1107 SolidColorDrawQuad* white =
1108 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1109 white->SetNew(
1110 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1111
1112 SharedQuadState* pass_shared_state =
1113 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1114
1115 FilterOperations filters;
1116 filters.Append(FilterOperation::CreateGrayscaleFilter(1.f));
1117 filters.Append(FilterOperation::CreateBrightnessFilter(0.5f));
1118
1119 RenderPassDrawQuad* render_pass_quad =
1120 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1121 render_pass_quad->SetNew(pass_shared_state,
1122 pass_rect,
1123 pass_rect,
1124 child_pass_id,
1125 0,
1126 gfx::Vector2dF(),
1127 gfx::Size(),
1128 filters,
1129 gfx::Vector2dF(),
1130 FilterOperations());
1131
1132 RenderPassList pass_list;
1133 pass_list.push_back(child_pass.Pass());
1134 pass_list.push_back(root_pass.Pass());
1135
1136 EXPECT_TRUE(this->RunPixelTest(
1137 &pass_list,
1138 base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")),
1139 ExactPixelComparator(true)));
1140 }
1141
1142 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) {
1143 gfx::Rect viewport_rect(this->device_viewport_size_);
1144
1145 RenderPassId root_pass_id(1, 1);
1146 scoped_ptr<RenderPass> root_pass =
1147 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1148
1149 RenderPassId child_pass_id(2, 2);
1150 gfx::Rect pass_rect(this->device_viewport_size_);
1151 gfx::Transform transform_to_root;
1152 scoped_ptr<RenderPass> child_pass =
1153 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1154
1155 gfx::Transform content_to_target_transform;
1156 SharedQuadState* shared_state = CreateTestSharedQuadState(
1157 content_to_target_transform, viewport_rect, child_pass.get());
1158 shared_state->opacity = 0.5f;
1159
1160 gfx::Rect blue_rect(0,
1161 0,
1162 this->device_viewport_size_.width(),
1163 this->device_viewport_size_.height() / 2);
1164 SolidColorDrawQuad* blue =
1165 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1166 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1167 gfx::Rect yellow_rect(0,
1168 this->device_viewport_size_.height() / 2,
1169 this->device_viewport_size_.width(),
1170 this->device_viewport_size_.height() / 2);
1171 SolidColorDrawQuad* yellow =
1172 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1173 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1174
1175 SharedQuadState* blank_state = CreateTestSharedQuadState(
1176 content_to_target_transform, viewport_rect, child_pass.get());
1177
1178 SolidColorDrawQuad* white =
1179 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1180 white->SetNew(
1181 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1182
1183 SharedQuadState* pass_shared_state =
1184 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1185
1186 SkScalar matrix[20];
1187 float amount = 0.5f;
1188 matrix[0] = 0.213f + 0.787f * amount;
1189 matrix[1] = 0.715f - 0.715f * amount;
1190 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1191 matrix[3] = 0;
1192 matrix[4] = 20.f;
1193 matrix[5] = 0.213f - 0.213f * amount;
1194 matrix[6] = 0.715f + 0.285f * amount;
1195 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1196 matrix[8] = 0;
1197 matrix[9] = 200.f;
1198 matrix[10] = 0.213f - 0.213f * amount;
1199 matrix[11] = 0.715f - 0.715f * amount;
1200 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1201 matrix[13] = 0;
1202 matrix[14] = 1.5f;
1203 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1204 matrix[18] = 1;
1205 skia::RefPtr<SkColorFilter> colorFilter(
1206 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1207 skia::RefPtr<SkImageFilter> filter =
1208 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
1209 FilterOperations filters;
1210 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1211
1212 RenderPassDrawQuad* render_pass_quad =
1213 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1214 render_pass_quad->SetNew(pass_shared_state,
1215 pass_rect,
1216 pass_rect,
1217 child_pass_id,
1218 0,
1219 gfx::Vector2dF(),
1220 gfx::Size(),
1221 filters,
1222 gfx::Vector2dF(),
1223 FilterOperations());
1224
1225 RenderPassList pass_list;
1226
1227 pass_list.push_back(child_pass.Pass());
1228 pass_list.push_back(root_pass.Pass());
1229
1230 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1231 // renderer so use a fuzzy comparator.
1232 EXPECT_TRUE(this->RunPixelTest(
1233 &pass_list,
1234 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
1235 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1236 }
1237
1238 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) {
1239 gfx::Rect viewport_rect(this->device_viewport_size_);
1240
1241 RenderPassId root_pass_id(1, 1);
1242 scoped_ptr<RenderPass> root_pass =
1243 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1244
1245 RenderPassId child_pass_id(2, 2);
1246 gfx::Rect pass_rect(this->device_viewport_size_);
1247 gfx::Transform transform_to_root;
1248 scoped_ptr<RenderPass> child_pass =
1249 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1250
1251 gfx::Transform content_to_target_transform;
1252 SharedQuadState* shared_state = CreateTestSharedQuadState(
1253 content_to_target_transform, viewport_rect, child_pass.get());
1254
1255 gfx::Rect blue_rect(0,
1256 0,
1257 this->device_viewport_size_.width(),
1258 this->device_viewport_size_.height() / 2);
1259 SolidColorDrawQuad* blue =
1260 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1261 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1262 gfx::Rect yellow_rect(0,
1263 this->device_viewport_size_.height() / 2,
1264 this->device_viewport_size_.width(),
1265 this->device_viewport_size_.height() / 2);
1266 SolidColorDrawQuad* yellow =
1267 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1268 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1269
1270 SharedQuadState* pass_shared_state =
1271 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1272 CreateTestRenderPassDrawQuad(
1273 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1274
1275 RenderPassList pass_list;
1276 pass_list.push_back(child_pass.Pass());
1277 pass_list.push_back(root_pass.Pass());
1278
1279 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1280
1281 EXPECT_TRUE(this->RunPixelTest(
1282 &pass_list,
1283 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
1284 ExactPixelComparator(true)));
1285 }
1286
1287 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) {
1288 gfx::Rect viewport_rect(this->device_viewport_size_);
1289
1290 RenderPassId root_pass_id(1, 1);
1291 scoped_ptr<RenderPass> root_pass =
1292 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1293
1294 RenderPassId child_pass_id(2, 2);
1295 gfx::Rect pass_rect(this->device_viewport_size_);
1296 gfx::Transform transform_to_root;
1297 scoped_ptr<RenderPass> child_pass =
1298 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1299
1300 gfx::Transform content_to_target_transform;
1301 SharedQuadState* shared_state = CreateTestSharedQuadState(
1302 content_to_target_transform, viewport_rect, child_pass.get());
1303
1304 gfx::Rect blue_rect(0,
1305 0,
1306 this->device_viewport_size_.width(),
1307 this->device_viewport_size_.height() / 2);
1308 SolidColorDrawQuad* blue =
1309 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1310 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1311 gfx::Rect yellow_rect(0,
1312 this->device_viewport_size_.height() / 2,
1313 this->device_viewport_size_.width(),
1314 this->device_viewport_size_.height() / 2);
1315 SolidColorDrawQuad* yellow =
1316 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1317 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1318
1319 gfx::Transform aa_transform;
1320 aa_transform.Translate(0.5, 0.0);
1321
1322 SharedQuadState* pass_shared_state =
1323 CreateTestSharedQuadState(aa_transform, pass_rect, root_pass.get());
1324 CreateTestRenderPassDrawQuad(
1325 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1326
1327 SharedQuadState* root_shared_state = CreateTestSharedQuadState(
1328 gfx::Transform(), viewport_rect, root_pass.get());
1329 SolidColorDrawQuad* background =
1330 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1331 background->SetNew(root_shared_state,
1332 gfx::Rect(this->device_viewport_size_),
1333 gfx::Rect(this->device_viewport_size_),
1334 SK_ColorWHITE,
1335 false);
1336
1337 RenderPassList pass_list;
1338 pass_list.push_back(child_pass.Pass());
1339 pass_list.push_back(root_pass.Pass());
1340
1341 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1342
1343 EXPECT_TRUE(this->RunPixelTest(
1344 &pass_list,
1345 base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")),
1346 FuzzyPixelOffByOneComparator(true)));
1347 }
1348
1349 // This tests the case where we have a RenderPass with a mask, but the quad
1350 // for the masked surface does not include the full surface texture.
1351 TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) {
1352 gfx::Rect viewport_rect(this->device_viewport_size_);
1353
1354 RenderPassId root_pass_id(1, 1);
1355 scoped_ptr<RenderPass> root_pass =
1356 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1357 SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState(
1358 gfx::Transform(), viewport_rect, root_pass.get());
1359
1360 RenderPassId child_pass_id(2, 2);
1361 gfx::Transform transform_to_root;
1362 scoped_ptr<RenderPass> child_pass =
1363 CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root);
1364 SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState(
1365 gfx::Transform(), viewport_rect, child_pass.get());
1366
1367 // The child render pass is just a green box.
1368 static const SkColor kCSSGreen = 0xff008000;
1369 SolidColorDrawQuad* green =
1370 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1371 green->SetNew(
1372 child_pass_shared_state, viewport_rect, viewport_rect, kCSSGreen, false);
1373
1374 // Make a mask.
1375 gfx::Rect mask_rect = viewport_rect;
1376 SkBitmap bitmap;
1377 bitmap.allocPixels(
1378 SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height()));
1379 SkCanvas canvas(bitmap);
1380 SkPaint paint;
1381 paint.setStyle(SkPaint::kStroke_Style);
1382 paint.setStrokeWidth(SkIntToScalar(4));
1383 paint.setColor(SK_ColorWHITE);
1384 canvas.clear(SK_ColorTRANSPARENT);
1385 gfx::Rect rect = mask_rect;
1386 while (!rect.IsEmpty()) {
1387 rect.Inset(6, 6, 4, 4);
1388 canvas.drawRect(
1389 SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()),
1390 paint);
1391 rect.Inset(6, 6, 4, 4);
1392 }
1393
1394 ResourceProvider::ResourceId mask_resource_id =
1395 this->resource_provider_->CreateResource(
1396 mask_rect.size(), GL_CLAMP_TO_EDGE,
1397 ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
1398 {
1399 SkAutoLockPixels lock(bitmap);
1400 this->resource_provider_->CopyToResource(
1401 mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
1402 mask_rect.size());
1403 }
1404
1405 // This RenderPassDrawQuad does not include the full |viewport_rect| which is
1406 // the size of the child render pass.
1407 gfx::Rect sub_rect = gfx::Rect(50, 50, 200, 100);
1408 EXPECT_NE(sub_rect.x(), child_pass->output_rect.x());
1409 EXPECT_NE(sub_rect.y(), child_pass->output_rect.y());
1410 EXPECT_NE(sub_rect.right(), child_pass->output_rect.right());
1411 EXPECT_NE(sub_rect.bottom(), child_pass->output_rect.bottom());
1412
1413 // Set up a mask on the RenderPassDrawQuad.
1414 RenderPassDrawQuad* mask_quad =
1415 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1416 mask_quad->SetNew(root_pass_shared_state,
1417 sub_rect,
1418 sub_rect,
1419 child_pass_id,
1420 mask_resource_id,
1421 gfx::Vector2dF(2.f, 1.f), // mask_uv_scale
1422 gfx::Size(mask_rect.size()), // mask_texture_size
1423 FilterOperations(), // foreground filters
1424 gfx::Vector2dF(), // filters scale
1425 FilterOperations()); // background filters
1426
1427 // White background behind the masked render pass.
1428 SolidColorDrawQuad* white =
1429 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1430 white->SetNew(root_pass_shared_state,
1431 viewport_rect,
1432 viewport_rect,
1433 SK_ColorWHITE,
1434 false);
1435
1436 RenderPassList pass_list;
1437 pass_list.push_back(child_pass.Pass());
1438 pass_list.push_back(root_pass.Pass());
1439
1440 EXPECT_TRUE(this->RunPixelTest(
1441 &pass_list,
1442 base::FilePath(FILE_PATH_LITERAL("mask_bottom_right.png")),
1443 ExactPixelComparator(true)));
1444 }
1445
1446 template <typename RendererType>
1447 class RendererPixelTestWithBackgroundFilter
1448 : public RendererPixelTest<RendererType> {
1449 protected:
1450 void SetUpRenderPassList() {
1451 gfx::Rect device_viewport_rect(this->device_viewport_size_);
1452
1453 RenderPassId root_id(1, 1);
1454 scoped_ptr<RenderPass> root_pass =
1455 CreateTestRootRenderPass(root_id, device_viewport_rect);
1456 root_pass->has_transparent_background = false;
1457
1458 gfx::Transform identity_content_to_target_transform;
1459
1460 RenderPassId filter_pass_id(2, 1);
1461 gfx::Transform transform_to_root;
1462 scoped_ptr<RenderPass> filter_pass =
1463 CreateTestRenderPass(filter_pass_id,
1464 filter_pass_content_rect_,
1465 transform_to_root);
1466
1467 // A non-visible quad in the filtering render pass.
1468 {
1469 SharedQuadState* shared_state =
1470 CreateTestSharedQuadState(identity_content_to_target_transform,
1471 filter_pass_content_rect_,
1472 filter_pass.get());
1473 SolidColorDrawQuad* color_quad =
1474 filter_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1475 color_quad->SetNew(shared_state,
1476 filter_pass_content_rect_,
1477 filter_pass_content_rect_,
1478 SK_ColorTRANSPARENT,
1479 false);
1480 }
1481
1482 {
1483 SharedQuadState* shared_state =
1484 CreateTestSharedQuadState(filter_pass_to_target_transform_,
1485 filter_pass_content_rect_,
1486 filter_pass.get());
1487 RenderPassDrawQuad* filter_pass_quad =
1488 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1489 filter_pass_quad->SetNew(shared_state,
1490 filter_pass_content_rect_,
1491 filter_pass_content_rect_,
1492 filter_pass_id,
1493 0, // mask_resource_id
1494 gfx::Vector2dF(), // mask_uv_scale
1495 gfx::Size(), // mask_texture_size
1496 FilterOperations(), // filters
1497 gfx::Vector2dF(), // filters_scale
1498 this->background_filters_);
1499 }
1500
1501 const int kColumnWidth = device_viewport_rect.width() / 3;
1502
1503 gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20);
1504 for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) {
1505 SharedQuadState* shared_state = CreateTestSharedQuadState(
1506 identity_content_to_target_transform, left_rect, root_pass.get());
1507 SolidColorDrawQuad* color_quad =
1508 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1509 color_quad->SetNew(
1510 shared_state, left_rect, left_rect, SK_ColorGREEN, false);
1511 left_rect += gfx::Vector2d(0, left_rect.height() + 1);
1512 }
1513
1514 gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20);
1515 for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) {
1516 SharedQuadState* shared_state = CreateTestSharedQuadState(
1517 identity_content_to_target_transform, middle_rect, root_pass.get());
1518 SolidColorDrawQuad* color_quad =
1519 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1520 color_quad->SetNew(
1521 shared_state, middle_rect, middle_rect, SK_ColorRED, false);
1522 middle_rect += gfx::Vector2d(0, middle_rect.height() + 1);
1523 }
1524
1525 gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20);
1526 for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) {
1527 SharedQuadState* shared_state = CreateTestSharedQuadState(
1528 identity_content_to_target_transform, right_rect, root_pass.get());
1529 SolidColorDrawQuad* color_quad =
1530 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1531 color_quad->SetNew(
1532 shared_state, right_rect, right_rect, SK_ColorBLUE, false);
1533 right_rect += gfx::Vector2d(0, right_rect.height() + 1);
1534 }
1535
1536 SharedQuadState* shared_state =
1537 CreateTestSharedQuadState(identity_content_to_target_transform,
1538 device_viewport_rect,
1539 root_pass.get());
1540 SolidColorDrawQuad* background_quad =
1541 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1542 background_quad->SetNew(shared_state,
1543 device_viewport_rect,
1544 device_viewport_rect,
1545 SK_ColorWHITE,
1546 false);
1547
1548 pass_list_.push_back(filter_pass.Pass());
1549 pass_list_.push_back(root_pass.Pass());
1550 }
1551
1552 RenderPassList pass_list_;
1553 FilterOperations background_filters_;
1554 gfx::Transform filter_pass_to_target_transform_;
1555 gfx::Rect filter_pass_content_rect_;
1556 };
1557
1558 typedef ::testing::Types<GLRenderer, SoftwareRenderer>
1559 BackgroundFilterRendererTypes;
1560 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter,
1561 BackgroundFilterRendererTypes);
1562
1563 typedef RendererPixelTestWithBackgroundFilter<GLRenderer>
1564 GLRendererPixelTestWithBackgroundFilter;
1565
1566 // TODO(skaslev): The software renderer does not support filters yet.
1567 TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) {
1568 this->background_filters_.Append(
1569 FilterOperation::CreateInvertFilter(1.f));
1570
1571 this->filter_pass_content_rect_ = gfx::Rect(this->device_viewport_size_);
1572 this->filter_pass_content_rect_.Inset(12, 14, 16, 18);
1573
1574 this->SetUpRenderPassList();
1575 EXPECT_TRUE(this->RunPixelTest(
1576 &this->pass_list_,
1577 base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
1578 ExactPixelComparator(true)));
1579 }
1580
1581 class ExternalStencilPixelTest : public GLRendererPixelTest {
1582 protected:
1583 void ClearBackgroundToGreen() {
1584 GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
1585 output_surface_->EnsureBackbuffer();
1586 output_surface_->Reshape(device_viewport_size_, 1);
1587 gl->ClearColor(0.f, 1.f, 0.f, 1.f);
1588 gl->Clear(GL_COLOR_BUFFER_BIT);
1589 }
1590
1591 void PopulateStencilBuffer() {
1592 // Set two quadrants of the stencil buffer to 1.
1593 GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
1594 output_surface_->EnsureBackbuffer();
1595 output_surface_->Reshape(device_viewport_size_, 1);
1596 gl->ClearStencil(0);
1597 gl->Clear(GL_STENCIL_BUFFER_BIT);
1598 gl->Enable(GL_SCISSOR_TEST);
1599 gl->ClearStencil(1);
1600 gl->Scissor(0,
1601 0,
1602 device_viewport_size_.width() / 2,
1603 device_viewport_size_.height() / 2);
1604 gl->Clear(GL_STENCIL_BUFFER_BIT);
1605 gl->Scissor(device_viewport_size_.width() / 2,
1606 device_viewport_size_.height() / 2,
1607 device_viewport_size_.width(),
1608 device_viewport_size_.height());
1609 gl->Clear(GL_STENCIL_BUFFER_BIT);
1610 }
1611 };
1612
1613 TEST_F(ExternalStencilPixelTest, StencilTestEnabled) {
1614 ClearBackgroundToGreen();
1615 PopulateStencilBuffer();
1616 this->EnableExternalStencilTest();
1617
1618 // Draw a blue quad that covers the entire device viewport. It should be
1619 // clipped to the bottom left and top right corners by the external stencil.
1620 gfx::Rect rect(this->device_viewport_size_);
1621 RenderPassId id(1, 1);
1622 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1623 SharedQuadState* blue_shared_state =
1624 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1625 SolidColorDrawQuad* blue =
1626 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1627 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1628 pass->has_transparent_background = false;
1629 RenderPassList pass_list;
1630 pass_list.push_back(pass.Pass());
1631
1632 EXPECT_TRUE(this->RunPixelTest(
1633 &pass_list,
1634 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1635 ExactPixelComparator(true)));
1636 }
1637
1638 TEST_F(ExternalStencilPixelTest, StencilTestDisabled) {
1639 PopulateStencilBuffer();
1640
1641 // Draw a green quad that covers the entire device viewport. The stencil
1642 // buffer should be ignored.
1643 gfx::Rect rect(this->device_viewport_size_);
1644 RenderPassId id(1, 1);
1645 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1646 SharedQuadState* green_shared_state =
1647 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1648 SolidColorDrawQuad* green =
1649 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1650 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
1651 RenderPassList pass_list;
1652 pass_list.push_back(pass.Pass());
1653
1654 EXPECT_TRUE(this->RunPixelTest(
1655 &pass_list,
1656 base::FilePath(FILE_PATH_LITERAL("green.png")),
1657 ExactPixelComparator(true)));
1658 }
1659
1660 TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) {
1661 // The stencil test should apply only to the final render pass.
1662 ClearBackgroundToGreen();
1663 PopulateStencilBuffer();
1664 this->EnableExternalStencilTest();
1665
1666 gfx::Rect viewport_rect(this->device_viewport_size_);
1667
1668 RenderPassId root_pass_id(1, 1);
1669 scoped_ptr<RenderPass> root_pass =
1670 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1671 root_pass->has_transparent_background = false;
1672
1673 RenderPassId child_pass_id(2, 2);
1674 gfx::Rect pass_rect(this->device_viewport_size_);
1675 gfx::Transform transform_to_root;
1676 scoped_ptr<RenderPass> child_pass =
1677 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1678
1679 gfx::Transform content_to_target_transform;
1680 SharedQuadState* shared_state = CreateTestSharedQuadState(
1681 content_to_target_transform, viewport_rect, child_pass.get());
1682
1683 gfx::Rect blue_rect(0,
1684 0,
1685 this->device_viewport_size_.width(),
1686 this->device_viewport_size_.height());
1687 SolidColorDrawQuad* blue =
1688 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1689 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1690
1691 SharedQuadState* pass_shared_state =
1692 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1693 CreateTestRenderPassDrawQuad(
1694 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1695 RenderPassList pass_list;
1696 pass_list.push_back(child_pass.Pass());
1697 pass_list.push_back(root_pass.Pass());
1698
1699 EXPECT_TRUE(this->RunPixelTest(
1700 &pass_list,
1701 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1702 ExactPixelComparator(true)));
1703 }
1704
1705 TEST_F(ExternalStencilPixelTest, DeviceClip) {
1706 ClearBackgroundToGreen();
1707 gfx::Rect clip_rect(gfx::Point(150, 150), gfx::Size(50, 50));
1708 this->ForceDeviceClip(clip_rect);
1709
1710 // Draw a blue quad that covers the entire device viewport. It should be
1711 // clipped to the bottom right corner by the device clip.
1712 gfx::Rect rect(this->device_viewport_size_);
1713 RenderPassId id(1, 1);
1714 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1715 SharedQuadState* blue_shared_state =
1716 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1717 SolidColorDrawQuad* blue =
1718 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1719 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1720 RenderPassList pass_list;
1721 pass_list.push_back(pass.Pass());
1722
1723 EXPECT_TRUE(this->RunPixelTest(
1724 &pass_list,
1725 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
1726 ExactPixelComparator(true)));
1727 }
1728
1729 // Software renderer does not support anti-aliased edges.
1730 TEST_F(GLRendererPixelTest, AntiAliasing) {
1731 gfx::Rect rect(this->device_viewport_size_);
1732
1733 RenderPassId id(1, 1);
1734 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1735
1736 gfx::Transform red_content_to_target_transform;
1737 red_content_to_target_transform.Rotate(10);
1738 SharedQuadState* red_shared_state = CreateTestSharedQuadState(
1739 red_content_to_target_transform, rect, pass.get());
1740
1741 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1742 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
1743
1744 gfx::Transform yellow_content_to_target_transform;
1745 yellow_content_to_target_transform.Rotate(5);
1746 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
1747 yellow_content_to_target_transform, rect, pass.get());
1748
1749 SolidColorDrawQuad* yellow =
1750 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1751 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
1752
1753 gfx::Transform blue_content_to_target_transform;
1754 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
1755 blue_content_to_target_transform, rect, pass.get());
1756
1757 SolidColorDrawQuad* blue =
1758 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1759 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1760
1761 RenderPassList pass_list;
1762 pass_list.push_back(pass.Pass());
1763
1764 EXPECT_TRUE(this->RunPixelTest(
1765 &pass_list,
1766 base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")),
1767 FuzzyPixelOffByOneComparator(true)));
1768 }
1769
1770 // This test tests that anti-aliasing works for axis aligned quads.
1771 // Anti-aliasing is only supported in the gl renderer.
1772 TEST_F(GLRendererPixelTest, AxisAligned) {
1773 gfx::Rect rect(this->device_viewport_size_);
1774
1775 RenderPassId id(1, 1);
1776 gfx::Transform transform_to_root;
1777 scoped_ptr<RenderPass> pass =
1778 CreateTestRenderPass(id, rect, transform_to_root);
1779
1780 gfx::Transform red_content_to_target_transform;
1781 red_content_to_target_transform.Translate(50, 50);
1782 red_content_to_target_transform.Scale(
1783 0.5f + 1.0f / (rect.width() * 2.0f),
1784 0.5f + 1.0f / (rect.height() * 2.0f));
1785 SharedQuadState* red_shared_state = CreateTestSharedQuadState(
1786 red_content_to_target_transform, rect, pass.get());
1787
1788 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1789 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
1790
1791 gfx::Transform yellow_content_to_target_transform;
1792 yellow_content_to_target_transform.Translate(25.5f, 25.5f);
1793 yellow_content_to_target_transform.Scale(0.5f, 0.5f);
1794 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
1795 yellow_content_to_target_transform, rect, pass.get());
1796
1797 SolidColorDrawQuad* yellow =
1798 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1799 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
1800
1801 gfx::Transform blue_content_to_target_transform;
1802 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
1803 blue_content_to_target_transform, rect, pass.get());
1804
1805 SolidColorDrawQuad* blue =
1806 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1807 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1808
1809 RenderPassList pass_list;
1810 pass_list.push_back(pass.Pass());
1811
1812 EXPECT_TRUE(this->RunPixelTest(
1813 &pass_list,
1814 base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")),
1815 ExactPixelComparator(true)));
1816 }
1817
1818 // This test tests that forcing anti-aliasing off works as expected.
1819 // Anti-aliasing is only supported in the gl renderer.
1820 TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) {
1821 gfx::Rect rect(this->device_viewport_size_);
1822
1823 RenderPassId id(1, 1);
1824 gfx::Transform transform_to_root;
1825 scoped_ptr<RenderPass> pass =
1826 CreateTestRenderPass(id, rect, transform_to_root);
1827
1828 gfx::Transform hole_content_to_target_transform;
1829 hole_content_to_target_transform.Translate(50, 50);
1830 hole_content_to_target_transform.Scale(
1831 0.5f + 1.0f / (rect.width() * 2.0f),
1832 0.5f + 1.0f / (rect.height() * 2.0f));
1833 SharedQuadState* hole_shared_state = CreateTestSharedQuadState(
1834 hole_content_to_target_transform, rect, pass.get());
1835
1836 SolidColorDrawQuad* hole =
1837 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1838 hole->SetAll(
1839 hole_shared_state, rect, rect, rect, false, SK_ColorTRANSPARENT, true);
1840
1841 gfx::Transform green_content_to_target_transform;
1842 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
1843 green_content_to_target_transform, rect, pass.get());
1844
1845 SolidColorDrawQuad* green =
1846 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1847 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
1848
1849 RenderPassList pass_list;
1850 pass_list.push_back(pass.Pass());
1851
1852 EXPECT_TRUE(this->RunPixelTest(
1853 &pass_list,
1854 base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")),
1855 ExactPixelComparator(false)));
1856 }
1857
1858 TEST_F(GLRendererPixelTest, AntiAliasingPerspective) {
1859 gfx::Rect rect(this->device_viewport_size_);
1860
1861 scoped_ptr<RenderPass> pass =
1862 CreateTestRootRenderPass(RenderPassId(1, 1), rect);
1863
1864 gfx::Rect red_rect(0, 0, 180, 500);
1865 gfx::Transform red_content_to_target_transform(
1866 1.0f, 2.4520f, 10.6206f, 19.0f,
1867 0.0f, 0.3528f, 5.9737f, 9.5f,
1868 0.0f, -0.2250f, -0.9744f, 0.0f,
1869 0.0f, 0.0225f, 0.0974f, 1.0f);
1870 SharedQuadState* red_shared_state = CreateTestSharedQuadState(
1871 red_content_to_target_transform, red_rect, pass.get());
1872 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1873 red->SetNew(red_shared_state, red_rect, red_rect, SK_ColorRED, false);
1874
1875 gfx::Rect green_rect(19, 7, 180, 10);
1876 SharedQuadState* green_shared_state =
1877 CreateTestSharedQuadState(gfx::Transform(), green_rect, pass.get());
1878 SolidColorDrawQuad* green =
1879 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1880 green->SetNew(
1881 green_shared_state, green_rect, green_rect, SK_ColorGREEN, false);
1882
1883 SharedQuadState* blue_shared_state =
1884 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1885 SolidColorDrawQuad* blue =
1886 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1887 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1888
1889 RenderPassList pass_list;
1890 pass_list.push_back(pass.Pass());
1891
1892 EXPECT_TRUE(this->RunPixelTest(
1893 &pass_list,
1894 base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")),
1895 FuzzyPixelOffByOneComparator(true)));
1896 }
1897
1898 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadIdentityScale) {
1899 gfx::Size pile_tile_size(1000, 1000);
1900 gfx::Rect viewport(this->device_viewport_size_);
1901 // TODO(enne): the renderer should figure this out on its own.
1902 ResourceFormat texture_format = RGBA_8888;
1903 bool nearest_neighbor = false;
1904
1905 RenderPassId id(1, 1);
1906 gfx::Transform transform_to_root;
1907 scoped_ptr<RenderPass> pass =
1908 CreateTestRenderPass(id, viewport, transform_to_root);
1909
1910 // One clipped blue quad in the lower right corner. Outside the clip
1911 // is red, which should not appear.
1912 gfx::Rect blue_rect(gfx::Size(100, 100));
1913 gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50));
1914
1915 scoped_ptr<FakePicturePile> blue_recording =
1916 FakePicturePile::CreateFilledPile(pile_tile_size, blue_rect.size());
1917 SkPaint red_paint;
1918 red_paint.setColor(SK_ColorRED);
1919 blue_recording->add_draw_rect_with_paint(blue_rect, red_paint);
1920 SkPaint blue_paint;
1921 blue_paint.setColor(SK_ColorBLUE);
1922 blue_recording->add_draw_rect_with_paint(blue_clip_rect, blue_paint);
1923 blue_recording->RerecordPile();
1924
1925 scoped_refptr<FakePicturePileImpl> blue_pile =
1926 FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);
1927
1928 gfx::Transform blue_content_to_target_transform;
1929 gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right());
1930 blue_content_to_target_transform.Translate(offset.x(), offset.y());
1931 gfx::RectF blue_scissor_rect = blue_clip_rect;
1932 blue_content_to_target_transform.TransformRect(&blue_scissor_rect);
1933 SharedQuadState* blue_shared_state =
1934 CreateTestSharedQuadStateClipped(blue_content_to_target_transform,
1935 blue_rect,
1936 gfx::ToEnclosingRect(blue_scissor_rect),
1937 pass.get());
1938
1939 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
1940
1941 blue_quad->SetNew(blue_shared_state,
1942 viewport, // Intentionally bigger than clip.
1943 gfx::Rect(), viewport, gfx::RectF(viewport),
1944 viewport.size(), nearest_neighbor, texture_format, viewport,
1945 1.f, blue_pile.get());
1946
1947 // One viewport-filling green quad.
1948 scoped_ptr<FakePicturePile> green_recording =
1949 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
1950 SkPaint green_paint;
1951 green_paint.setColor(SK_ColorGREEN);
1952 green_recording->add_draw_rect_with_paint(viewport, green_paint);
1953 green_recording->RerecordPile();
1954 scoped_refptr<FakePicturePileImpl> green_pile =
1955 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
1956
1957 gfx::Transform green_content_to_target_transform;
1958 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
1959 green_content_to_target_transform, viewport, pass.get());
1960
1961 PictureDrawQuad* green_quad =
1962 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
1963 green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
1964 gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(),
1965 nearest_neighbor, texture_format, viewport, 1.f,
1966 green_pile.get());
1967
1968 RenderPassList pass_list;
1969 pass_list.push_back(pass.Pass());
1970
1971 EXPECT_TRUE(this->RunPixelTest(
1972 &pass_list,
1973 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
1974 ExactPixelComparator(true)));
1975 }
1976
1977 // Not WithSkiaGPUBackend since that path currently requires tiles for opacity.
1978 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadOpacity) {
1979 gfx::Size pile_tile_size(1000, 1000);
1980 gfx::Rect viewport(this->device_viewport_size_);
1981 ResourceFormat texture_format = RGBA_8888;
1982 bool nearest_neighbor = false;
1983
1984 RenderPassId id(1, 1);
1985 gfx::Transform transform_to_root;
1986 scoped_ptr<RenderPass> pass =
1987 CreateTestRenderPass(id, viewport, transform_to_root);
1988
1989 // One viewport-filling 0.5-opacity green quad.
1990 scoped_ptr<FakePicturePile> green_recording =
1991 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
1992 SkPaint green_paint;
1993 green_paint.setColor(SK_ColorGREEN);
1994 green_recording->add_draw_rect_with_paint(viewport, green_paint);
1995 green_recording->RerecordPile();
1996 scoped_refptr<FakePicturePileImpl> green_pile =
1997 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
1998
1999 gfx::Transform green_content_to_target_transform;
2000 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2001 green_content_to_target_transform, viewport, pass.get());
2002 green_shared_state->opacity = 0.5f;
2003
2004 PictureDrawQuad* green_quad =
2005 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2006 green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
2007 gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
2008 texture_format, viewport, 1.f, green_pile.get());
2009
2010 // One viewport-filling white quad.
2011 scoped_ptr<FakePicturePile> white_recording =
2012 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2013 SkPaint white_paint;
2014 white_paint.setColor(SK_ColorWHITE);
2015 white_recording->add_draw_rect_with_paint(viewport, white_paint);
2016 white_recording->RerecordPile();
2017 scoped_refptr<FakePicturePileImpl> white_pile =
2018 FakePicturePileImpl::CreateFromPile(white_recording.get(), nullptr);
2019
2020 gfx::Transform white_content_to_target_transform;
2021 SharedQuadState* white_shared_state = CreateTestSharedQuadState(
2022 white_content_to_target_transform, viewport, pass.get());
2023
2024 PictureDrawQuad* white_quad =
2025 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2026 white_quad->SetNew(white_shared_state, viewport, gfx::Rect(), viewport,
2027 gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
2028 texture_format, viewport, 1.f, white_pile.get());
2029
2030 RenderPassList pass_list;
2031 pass_list.push_back(pass.Pass());
2032
2033 EXPECT_TRUE(this->RunPixelTest(
2034 &pass_list,
2035 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
2036 FuzzyPixelOffByOneComparator(true)));
2037 }
2038
2039 template<typename TypeParam> bool IsSoftwareRenderer() {
2040 return false;
2041 }
2042
2043 template<>
2044 bool IsSoftwareRenderer<SoftwareRenderer>() {
2045 return true;
2046 }
2047
2048 template<>
2049 bool IsSoftwareRenderer<SoftwareRendererWithExpandedViewport>() {
2050 return true;
2051 }
2052
2053 // If we disable image filtering, then a 2x2 bitmap should appear as four
2054 // huge sharp squares.
2055 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadDisableImageFiltering) {
2056 // We only care about this in software mode since bilinear filtering is
2057 // cheap in hardware.
2058 if (!IsSoftwareRenderer<TypeParam>())
2059 return;
2060
2061 gfx::Size pile_tile_size(1000, 1000);
2062 gfx::Rect viewport(this->device_viewport_size_);
2063 ResourceFormat texture_format = RGBA_8888;
2064 bool nearest_neighbor = false;
2065
2066 RenderPassId id(1, 1);
2067 gfx::Transform transform_to_root;
2068 scoped_ptr<RenderPass> pass =
2069 CreateTestRenderPass(id, viewport, transform_to_root);
2070
2071 SkBitmap bitmap;
2072 bitmap.allocN32Pixels(2, 2);
2073 {
2074 SkAutoLockPixels lock(bitmap);
2075 SkCanvas canvas(bitmap);
2076 canvas.drawPoint(0, 0, SK_ColorGREEN);
2077 canvas.drawPoint(0, 1, SK_ColorBLUE);
2078 canvas.drawPoint(1, 0, SK_ColorBLUE);
2079 canvas.drawPoint(1, 1, SK_ColorGREEN);
2080 }
2081
2082 scoped_ptr<FakePicturePile> recording =
2083 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2084 SkPaint paint;
2085 paint.setFilterQuality(kLow_SkFilterQuality);
2086 recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
2087 recording->RerecordPile();
2088 scoped_refptr<FakePicturePileImpl> pile =
2089 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2090
2091 gfx::Transform content_to_target_transform;
2092 SharedQuadState* shared_state = CreateTestSharedQuadState(
2093 content_to_target_transform, viewport, pass.get());
2094
2095 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2096 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
2097 gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
2098 texture_format, viewport, 1.f, pile.get());
2099
2100 RenderPassList pass_list;
2101 pass_list.push_back(pass.Pass());
2102
2103 this->disable_picture_quad_image_filtering_ = true;
2104
2105 EXPECT_TRUE(this->RunPixelTest(
2106 &pass_list,
2107 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2108 ExactPixelComparator(true)));
2109 }
2110
2111 // This disables filtering by setting |nearest_neighbor| on the PictureDrawQuad.
2112 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNearestNeighbor) {
2113 gfx::Size pile_tile_size(1000, 1000);
2114 gfx::Rect viewport(this->device_viewport_size_);
2115 ResourceFormat texture_format = RGBA_8888;
2116 bool nearest_neighbor = true;
2117
2118 RenderPassId id(1, 1);
2119 gfx::Transform transform_to_root;
2120 scoped_ptr<RenderPass> pass =
2121 CreateTestRenderPass(id, viewport, transform_to_root);
2122
2123 SkBitmap bitmap;
2124 bitmap.allocN32Pixels(2, 2);
2125 {
2126 SkAutoLockPixels lock(bitmap);
2127 SkCanvas canvas(bitmap);
2128 canvas.drawPoint(0, 0, SK_ColorGREEN);
2129 canvas.drawPoint(0, 1, SK_ColorBLUE);
2130 canvas.drawPoint(1, 0, SK_ColorBLUE);
2131 canvas.drawPoint(1, 1, SK_ColorGREEN);
2132 }
2133
2134 scoped_ptr<FakePicturePile> recording =
2135 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2136 SkPaint paint;
2137 paint.setFilterQuality(kLow_SkFilterQuality);
2138 recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
2139 recording->RerecordPile();
2140 scoped_refptr<FakePicturePileImpl> pile =
2141 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2142
2143 gfx::Transform content_to_target_transform;
2144 SharedQuadState* shared_state = CreateTestSharedQuadState(
2145 content_to_target_transform, viewport, pass.get());
2146
2147 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2148 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
2149 gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
2150 texture_format, viewport, 1.f, pile.get());
2151
2152 RenderPassList pass_list;
2153 pass_list.push_back(pass.Pass());
2154
2155 EXPECT_TRUE(this->RunPixelTest(
2156 &pass_list,
2157 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2158 ExactPixelComparator(true)));
2159 }
2160
2161 // This disables filtering by setting |nearest_neighbor| on the TileDrawQuad.
2162 TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) {
2163 gfx::Rect viewport(this->device_viewport_size_);
2164 bool swizzle_contents = true;
2165 bool nearest_neighbor = true;
2166
2167 SkBitmap bitmap;
2168 bitmap.allocN32Pixels(2, 2);
2169 {
2170 SkAutoLockPixels lock(bitmap);
2171 SkCanvas canvas(bitmap);
2172 canvas.drawPoint(0, 0, SK_ColorGREEN);
2173 canvas.drawPoint(0, 1, SK_ColorBLUE);
2174 canvas.drawPoint(1, 0, SK_ColorBLUE);
2175 canvas.drawPoint(1, 1, SK_ColorGREEN);
2176 }
2177
2178 gfx::Size tile_size(2, 2);
2179 ResourceProvider::ResourceId resource =
2180 this->resource_provider_->CreateResource(
2181 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2182 RGBA_8888);
2183
2184 {
2185 SkAutoLockPixels lock(bitmap);
2186 this->resource_provider_->CopyToResource(
2187 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
2188 }
2189
2190 RenderPassId id(1, 1);
2191 gfx::Transform transform_to_root;
2192 scoped_ptr<RenderPass> pass =
2193 CreateTestRenderPass(id, viewport, transform_to_root);
2194
2195 gfx::Transform content_to_target_transform;
2196 SharedQuadState* shared_state = CreateTestSharedQuadState(
2197 content_to_target_transform, viewport, pass.get());
2198
2199 TileDrawQuad* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>();
2200 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource,
2201 gfx::Rect(tile_size), tile_size, swizzle_contents,
2202 nearest_neighbor);
2203
2204 RenderPassList pass_list;
2205 pass_list.push_back(pass.Pass());
2206
2207 EXPECT_TRUE(this->RunPixelTest(
2208 &pass_list,
2209 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2210 ExactPixelComparator(true)));
2211 }
2212
2213 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) {
2214 gfx::Size pile_tile_size(1000, 1000);
2215 gfx::Rect viewport(this->device_viewport_size_);
2216 // TODO(enne): the renderer should figure this out on its own.
2217 ResourceFormat texture_format = RGBA_8888;
2218 bool nearest_neighbor = false;
2219
2220 RenderPassId id(1, 1);
2221 gfx::Transform transform_to_root;
2222 scoped_ptr<RenderPass> pass =
2223 CreateTestRenderPass(id, viewport, transform_to_root);
2224
2225 // As scaling up the blue checkerboards will cause sampling on the GPU,
2226 // a few extra "cleanup rects" need to be added to clobber the blending
2227 // to make the output image more clean. This will also test subrects
2228 // of the layer.
2229 gfx::Transform green_content_to_target_transform;
2230 gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100));
2231 gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20));
2232
2233 scoped_ptr<FakePicturePile> green_recording =
2234 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2235
2236 SkPaint red_paint;
2237 red_paint.setColor(SK_ColorRED);
2238 green_recording->add_draw_rect_with_paint(viewport, red_paint);
2239 SkPaint green_paint;
2240 green_paint.setColor(SK_ColorGREEN);
2241 green_recording->add_draw_rect_with_paint(green_rect1, green_paint);
2242 green_recording->add_draw_rect_with_paint(green_rect2, green_paint);
2243 green_recording->RerecordPile();
2244 scoped_refptr<FakePicturePileImpl> green_pile =
2245 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2246
2247 SharedQuadState* top_right_green_shared_quad_state =
2248 CreateTestSharedQuadState(
2249 green_content_to_target_transform, viewport, pass.get());
2250
2251 PictureDrawQuad* green_quad1 =
2252 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2253 green_quad1->SetNew(top_right_green_shared_quad_state, green_rect1,
2254 gfx::Rect(), green_rect1, gfx::RectF(green_rect1.size()),
2255 green_rect1.size(), nearest_neighbor, texture_format,
2256 green_rect1, 1.f, green_pile.get());
2257
2258 PictureDrawQuad* green_quad2 =
2259 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2260 green_quad2->SetNew(top_right_green_shared_quad_state, green_rect2,
2261 gfx::Rect(), green_rect2, gfx::RectF(green_rect2.size()),
2262 green_rect2.size(), nearest_neighbor, texture_format,
2263 green_rect2, 1.f, green_pile.get());
2264
2265 // Add a green clipped checkerboard in the bottom right to help test
2266 // interleaving picture quad content and solid color content.
2267 gfx::Rect bottom_right_rect(
2268 gfx::Point(viewport.width() / 2, viewport.height() / 2),
2269 gfx::Size(viewport.width() / 2, viewport.height() / 2));
2270 SharedQuadState* bottom_right_green_shared_state =
2271 CreateTestSharedQuadStateClipped(green_content_to_target_transform,
2272 viewport,
2273 bottom_right_rect,
2274 pass.get());
2275 SolidColorDrawQuad* bottom_right_color_quad =
2276 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2277 bottom_right_color_quad->SetNew(bottom_right_green_shared_state,
2278 viewport,
2279 viewport,
2280 SK_ColorGREEN,
2281 false);
2282
2283 // Add two blue checkerboards taking up the bottom left and top right,
2284 // but use content scales as content rects to make this happen.
2285 // The content is at a 4x content scale.
2286 gfx::Rect layer_rect(gfx::Size(20, 30));
2287 float contents_scale = 4.f;
2288 // Two rects that touch at their corners, arbitrarily placed in the layer.
2289 gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f));
2290 gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f));
2291 gfx::RectF union_layer_rect = blue_layer_rect1;
2292 union_layer_rect.Union(blue_layer_rect2);
2293
2294 // Because scaling up will cause sampling outside the rects, add one extra
2295 // pixel of buffer at the final content scale.
2296 float inset = -1.f / contents_scale;
2297 blue_layer_rect1.Inset(inset, inset, inset, inset);
2298 blue_layer_rect2.Inset(inset, inset, inset, inset);
2299
2300 scoped_ptr<FakePicturePile> recording =
2301 FakePicturePile::CreateFilledPile(pile_tile_size, layer_rect.size());
2302
2303 Region outside(layer_rect);
2304 outside.Subtract(gfx::ToEnclosingRect(union_layer_rect));
2305 for (Region::Iterator iter(outside); iter.has_rect(); iter.next()) {
2306 recording->add_draw_rect_with_paint(iter.rect(), red_paint);
2307 }
2308
2309 SkPaint blue_paint;
2310 blue_paint.setColor(SK_ColorBLUE);
2311 recording->add_draw_rect_with_paint(blue_layer_rect1, blue_paint);
2312 recording->add_draw_rect_with_paint(blue_layer_rect2, blue_paint);
2313 recording->RerecordPile();
2314 scoped_refptr<FakePicturePileImpl> pile =
2315 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2316
2317 gfx::Rect content_rect(
2318 gfx::ScaleToEnclosingRect(layer_rect, contents_scale));
2319 gfx::Rect content_union_rect(
2320 gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale)));
2321
2322 // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels,
2323 // so scale an additional 10x to make them 100x100.
2324 gfx::Transform content_to_target_transform;
2325 content_to_target_transform.Scale(10.0, 10.0);
2326 gfx::Rect quad_content_rect(gfx::Size(20, 20));
2327 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2328 content_to_target_transform, quad_content_rect, pass.get());
2329
2330 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2331 blue_quad->SetNew(blue_shared_state, quad_content_rect, gfx::Rect(),
2332 quad_content_rect, gfx::RectF(quad_content_rect),
2333 content_union_rect.size(), nearest_neighbor, texture_format,
2334 content_union_rect, contents_scale, pile.get());
2335
2336 // Fill left half of viewport with green.
2337 gfx::Transform half_green_content_to_target_transform;
2338 gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height()));
2339 SharedQuadState* half_green_shared_state = CreateTestSharedQuadState(
2340 half_green_content_to_target_transform, half_green_rect, pass.get());
2341 SolidColorDrawQuad* half_color_quad =
2342 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2343 half_color_quad->SetNew(half_green_shared_state,
2344 half_green_rect,
2345 half_green_rect,
2346 SK_ColorGREEN,
2347 false);
2348
2349 RenderPassList pass_list;
2350 pass_list.push_back(pass.Pass());
2351
2352 EXPECT_TRUE(this->RunPixelTest(
2353 &pass_list,
2354 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2355 ExactPixelComparator(true)));
2356 }
2357
2358 typedef RendererPixelTest<GLRendererWithFlippedSurface>
2359 GLRendererPixelTestWithFlippedOutputSurface;
2360
2361 TEST_F(GLRendererPixelTestWithFlippedOutputSurface, ExplicitFlipTest) {
2362 // This draws a blue rect above a yellow rect with an inverted output surface.
2363 gfx::Rect viewport_rect(this->device_viewport_size_);
2364
2365 RenderPassId root_pass_id(1, 1);
2366 scoped_ptr<RenderPass> root_pass =
2367 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2368
2369 RenderPassId child_pass_id(2, 2);
2370 gfx::Rect pass_rect(this->device_viewport_size_);
2371 gfx::Transform transform_to_root;
2372 scoped_ptr<RenderPass> child_pass =
2373 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2374
2375 gfx::Transform content_to_target_transform;
2376 SharedQuadState* shared_state = CreateTestSharedQuadState(
2377 content_to_target_transform, viewport_rect, child_pass.get());
2378
2379 gfx::Rect blue_rect(0,
2380 0,
2381 this->device_viewport_size_.width(),
2382 this->device_viewport_size_.height() / 2);
2383 SolidColorDrawQuad* blue =
2384 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2385 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2386 gfx::Rect yellow_rect(0,
2387 this->device_viewport_size_.height() / 2,
2388 this->device_viewport_size_.width(),
2389 this->device_viewport_size_.height() / 2);
2390 SolidColorDrawQuad* yellow =
2391 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2392 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
2393
2394 SharedQuadState* pass_shared_state =
2395 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2396 CreateTestRenderPassDrawQuad(
2397 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2398
2399 RenderPassList pass_list;
2400 pass_list.push_back(child_pass.Pass());
2401 pass_list.push_back(root_pass.Pass());
2402
2403 EXPECT_TRUE(this->RunPixelTest(
2404 &pass_list,
2405 base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")),
2406 ExactPixelComparator(true)));
2407 }
2408
2409 TEST_F(GLRendererPixelTestWithFlippedOutputSurface, CheckChildPassUnflipped) {
2410 // This draws a blue rect above a yellow rect with an inverted output surface.
2411 gfx::Rect viewport_rect(this->device_viewport_size_);
2412
2413 RenderPassId root_pass_id(1, 1);
2414 scoped_ptr<RenderPass> root_pass =
2415 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2416
2417 RenderPassId child_pass_id(2, 2);
2418 gfx::Rect pass_rect(this->device_viewport_size_);
2419 gfx::Transform transform_to_root;
2420 scoped_ptr<RenderPass> child_pass =
2421 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2422
2423 gfx::Transform content_to_target_transform;
2424 SharedQuadState* shared_state = CreateTestSharedQuadState(
2425 content_to_target_transform, viewport_rect, child_pass.get());
2426
2427 gfx::Rect blue_rect(0,
2428 0,
2429 this->device_viewport_size_.width(),
2430 this->device_viewport_size_.height() / 2);
2431 SolidColorDrawQuad* blue =
2432 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2433 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2434 gfx::Rect yellow_rect(0,
2435 this->device_viewport_size_.height() / 2,
2436 this->device_viewport_size_.width(),
2437 this->device_viewport_size_.height() / 2);
2438 SolidColorDrawQuad* yellow =
2439 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2440 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
2441
2442 SharedQuadState* pass_shared_state =
2443 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2444 CreateTestRenderPassDrawQuad(
2445 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2446
2447 RenderPassList pass_list;
2448 pass_list.push_back(child_pass.Pass());
2449 pass_list.push_back(root_pass.Pass());
2450
2451 // Check that the child pass remains unflipped.
2452 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
2453 &pass_list,
2454 pass_list.front(),
2455 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
2456 ExactPixelComparator(true)));
2457 }
2458
2459 TEST_F(GLRendererPixelTest, CheckReadbackSubset) {
2460 gfx::Rect viewport_rect(this->device_viewport_size_);
2461
2462 RenderPassId root_pass_id(1, 1);
2463 scoped_ptr<RenderPass> root_pass =
2464 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2465
2466 RenderPassId child_pass_id(2, 2);
2467 gfx::Rect pass_rect(this->device_viewport_size_);
2468 gfx::Transform transform_to_root;
2469 scoped_ptr<RenderPass> child_pass =
2470 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2471
2472 gfx::Transform content_to_target_transform;
2473 SharedQuadState* shared_state = CreateTestSharedQuadState(
2474 content_to_target_transform, viewport_rect, child_pass.get());
2475
2476 // Draw a green quad full-size with a blue quad in the lower-right corner.
2477 gfx::Rect blue_rect(this->device_viewport_size_.width() * 3 / 4,
2478 this->device_viewport_size_.height() * 3 / 4,
2479 this->device_viewport_size_.width() * 3 / 4,
2480 this->device_viewport_size_.height() * 3 / 4);
2481 SolidColorDrawQuad* blue =
2482 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2483 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2484 gfx::Rect green_rect(0,
2485 0,
2486 this->device_viewport_size_.width(),
2487 this->device_viewport_size_.height());
2488 SolidColorDrawQuad* green =
2489 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2490 green->SetNew(shared_state, green_rect, green_rect, SK_ColorGREEN, false);
2491
2492 SharedQuadState* pass_shared_state =
2493 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2494 CreateTestRenderPassDrawQuad(
2495 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2496
2497 RenderPassList pass_list;
2498 pass_list.push_back(child_pass.Pass());
2499 pass_list.push_back(root_pass.Pass());
2500
2501 // Check that the child pass remains unflipped.
2502 gfx::Rect capture_rect(this->device_viewport_size_.width() / 2,
2503 this->device_viewport_size_.height() / 2,
2504 this->device_viewport_size_.width() / 2,
2505 this->device_viewport_size_.height() / 2);
2506 EXPECT_TRUE(this->RunPixelTestWithReadbackTargetAndArea(
2507 &pass_list,
2508 pass_list.front(),
2509 base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")),
2510 ExactPixelComparator(true),
2511 &capture_rect));
2512 }
2513
2514 TYPED_TEST(RendererPixelTest, WrapModeRepeat) {
2515 gfx::Rect rect(this->device_viewport_size_);
2516
2517 RenderPassId id(1, 1);
2518 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2519
2520 SharedQuadState* shared_state =
2521 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
2522
2523 gfx::Size texture_size(4, 4);
2524 SkPMColor colors[4] = {
2525 SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)),
2526 SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)),
2527 SkPreMultiplyColor(SkColorSetARGB(255, 0, 64, 0)),
2528 SkPreMultiplyColor(SkColorSetARGB(255, 0, 0, 0)),
2529 };
2530 uint32_t pixels[16] = {
2531 colors[0], colors[0], colors[1], colors[1],
2532 colors[0], colors[0], colors[1], colors[1],
2533 colors[2], colors[2], colors[3], colors[3],
2534 colors[2], colors[2], colors[3], colors[3],
2535 };
2536 ResourceProvider::ResourceId resource =
2537 this->resource_provider_->CreateResource(
2538 texture_size, GL_REPEAT, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2539 RGBA_8888);
2540 this->resource_provider_->CopyToResource(
2541 resource, reinterpret_cast<uint8_t*>(pixels), texture_size);
2542
2543 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2544 TextureDrawQuad* texture_quad =
2545 pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2546 texture_quad->SetNew(
2547 shared_state, gfx::Rect(this->device_viewport_size_), gfx::Rect(),
2548 gfx::Rect(this->device_viewport_size_), resource,
2549 true, // premultiplied_alpha
2550 gfx::PointF(0.0f, 0.0f), // uv_top_left
2551 gfx::PointF( // uv_bottom_right
2552 this->device_viewport_size_.width() / texture_size.width(),
2553 this->device_viewport_size_.height() / texture_size.height()),
2554 SK_ColorWHITE, vertex_opacity,
2555 false, // flipped
2556 false); // nearest_neighbor
2557
2558 RenderPassList pass_list;
2559 pass_list.push_back(pass.Pass());
2560
2561 EXPECT_TRUE(this->RunPixelTest(
2562 &pass_list,
2563 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
2564 FuzzyPixelOffByOneComparator(true)));
2565 }
2566
2567 TYPED_TEST(RendererPixelTest, Checkerboards) {
2568 gfx::Rect rect(this->device_viewport_size_);
2569
2570 RenderPassId id(1, 1);
2571 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2572
2573 SharedQuadState* shared_state =
2574 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
2575
2576 // The color's alpha value is not used.
2577 SkColor color1 = SK_ColorGREEN;
2578 color1 = SkColorSetA(color1, 0);
2579 SkColor color2 = SK_ColorBLUE;
2580 color2 = SkColorSetA(color2, 0);
2581
2582 gfx::Rect content_rect(rect);
2583
2584 gfx::Rect top_left(content_rect);
2585 gfx::Rect top_right(content_rect);
2586 gfx::Rect bottom_left(content_rect);
2587 gfx::Rect bottom_right(content_rect);
2588 // The format is Inset(left, top, right, bottom).
2589 top_left.Inset(0, 0, content_rect.width() / 2, content_rect.height() / 2);
2590 top_right.Inset(content_rect.width() / 2, 0, 0, content_rect.height() / 2);
2591 bottom_left.Inset(0, content_rect.height() / 2, content_rect.width() / 2, 0);
2592 bottom_right.Inset(content_rect.width() / 2, content_rect.height() / 2, 0, 0);
2593
2594 // Appends checkerboard quads with a scale of 1.
2595 CheckerboardDrawQuad* quad =
2596 pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2597 quad->SetNew(shared_state, top_left, top_left, color1, 1.f);
2598 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2599 quad->SetNew(shared_state, top_right, top_right, color2, 1.f);
2600 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2601 quad->SetNew(shared_state, bottom_left, bottom_left, color2, 1.f);
2602 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2603 quad->SetNew(shared_state, bottom_right, bottom_right, color1, 1.f);
2604
2605 RenderPassList pass_list;
2606 pass_list.push_back(pass.Pass());
2607
2608 base::FilePath::StringType path =
2609 IsSoftwareRenderer<TypeParam>()
2610 ? FILE_PATH_LITERAL("four_blue_green_checkers.png")
2611 : FILE_PATH_LITERAL("checkers.png");
2612 EXPECT_TRUE(this->RunPixelTest(&pass_list, base::FilePath(path),
2613 ExactPixelComparator(true)));
2614 }
2615
2616 TYPED_TEST(RendererPixelTest, CheckerboardsScaled) {
2617 gfx::Rect rect(this->device_viewport_size_);
2618
2619 RenderPassId id(1, 1);
2620 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2621
2622 gfx::Transform scale;
2623 scale.Scale(2.f, 2.f);
2624
2625 SharedQuadState* shared_state =
2626 CreateTestSharedQuadState(scale, rect, pass.get());
2627
2628 // The color's alpha value is not used.
2629 SkColor color1 = SK_ColorGREEN;
2630 color1 = SkColorSetA(color1, 0);
2631 SkColor color2 = SK_ColorBLUE;
2632 color2 = SkColorSetA(color2, 0);
2633
2634 gfx::Rect content_rect(rect);
2635 content_rect.Inset(0, 0, rect.width() / 2, rect.height() / 2);
2636
2637 gfx::Rect top_left(content_rect);
2638 gfx::Rect top_right(content_rect);
2639 gfx::Rect bottom_left(content_rect);
2640 gfx::Rect bottom_right(content_rect);
2641 // The format is Inset(left, top, right, bottom).
2642 top_left.Inset(0, 0, content_rect.width() / 2, content_rect.height() / 2);
2643 top_right.Inset(content_rect.width() / 2, 0, 0, content_rect.height() / 2);
2644 bottom_left.Inset(0, content_rect.height() / 2, content_rect.width() / 2, 0);
2645 bottom_right.Inset(content_rect.width() / 2, content_rect.height() / 2, 0, 0);
2646
2647 // Appends checkerboard quads with a scale of 2, and a shared quad state
2648 // with a scale of 2. The checkers should be scaled by 2 * 2 = 4.
2649 CheckerboardDrawQuad* quad =
2650 pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2651 quad->SetNew(shared_state, top_left, top_left, color1, 2.f);
2652 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2653 quad->SetNew(shared_state, top_right, top_right, color2, 2.f);
2654 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2655 quad->SetNew(shared_state, bottom_left, bottom_left, color2, 2.f);
2656 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2657 quad->SetNew(shared_state, bottom_right, bottom_right, color1, 2.f);
2658
2659 RenderPassList pass_list;
2660 pass_list.push_back(pass.Pass());
2661
2662 base::FilePath::StringType path =
2663 IsSoftwareRenderer<TypeParam>()
2664 ? FILE_PATH_LITERAL("four_blue_green_checkers.png")
2665 : FILE_PATH_LITERAL("checkers_big.png");
2666 EXPECT_TRUE(this->RunPixelTest(&pass_list, base::FilePath(path),
2667 ExactPixelComparator(true)));
2668 }
2669
2670 #endif // !defined(OS_ANDROID)
2671
2672 } // namespace
2673 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/renderer_capabilities.cc ('k') | cc/output/renderer_settings.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698