Roll src/third_party/WebKit d10c917:a1123a1 (svn 198729:198730)
[chromium-blink-merge.git] / cc / output / renderer_pixeltest.cc
blob8472ff50613ef60847f0b54a7b71671433194bcc
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.
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 "media/base/video_frame.h"
15 #include "third_party/skia/include/core/SkColorPriv.h"
16 #include "third_party/skia/include/core/SkImageFilter.h"
17 #include "third_party/skia/include/core/SkMatrix.h"
18 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
19 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
20 #include "ui/gfx/geometry/rect_conversions.h"
22 using gpu::gles2::GLES2Interface;
24 namespace cc {
25 namespace {
27 #if !defined(OS_ANDROID)
28 scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPassId id,
29 const gfx::Rect& rect) {
30 scoped_ptr<RenderPass> pass = RenderPass::Create();
31 const gfx::Rect output_rect = rect;
32 const gfx::Rect damage_rect = rect;
33 const gfx::Transform transform_to_root_target;
34 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
35 return pass.Pass();
38 scoped_ptr<RenderPass> CreateTestRenderPass(
39 RenderPassId id,
40 const gfx::Rect& rect,
41 const gfx::Transform& transform_to_root_target) {
42 scoped_ptr<RenderPass> pass = RenderPass::Create();
43 const gfx::Rect output_rect = rect;
44 const gfx::Rect damage_rect = rect;
45 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
46 return pass.Pass();
49 SharedQuadState* CreateTestSharedQuadState(
50 gfx::Transform quad_to_target_transform,
51 const gfx::Rect& rect,
52 RenderPass* render_pass) {
53 const gfx::Size layer_bounds = rect.size();
54 const gfx::Rect visible_layer_rect = rect;
55 const gfx::Rect clip_rect = rect;
56 const bool is_clipped = false;
57 const float opacity = 1.0f;
58 const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
59 int sorting_context_id = 0;
60 SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
61 shared_state->SetAll(quad_to_target_transform, layer_bounds,
62 visible_layer_rect, clip_rect, is_clipped, opacity,
63 blend_mode, sorting_context_id);
64 return shared_state;
67 SharedQuadState* CreateTestSharedQuadStateClipped(
68 gfx::Transform quad_to_target_transform,
69 const gfx::Rect& rect,
70 const gfx::Rect& clip_rect,
71 RenderPass* render_pass) {
72 const gfx::Size layer_bounds = rect.size();
73 const gfx::Rect visible_layer_rect = clip_rect;
74 const bool is_clipped = true;
75 const float opacity = 1.0f;
76 const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
77 int sorting_context_id = 0;
78 SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
79 shared_state->SetAll(quad_to_target_transform, layer_bounds,
80 visible_layer_rect, clip_rect, is_clipped, opacity,
81 blend_mode, sorting_context_id);
82 return shared_state;
85 void CreateTestRenderPassDrawQuad(const SharedQuadState* shared_state,
86 const gfx::Rect& rect,
87 RenderPassId pass_id,
88 RenderPass* render_pass) {
89 RenderPassDrawQuad* quad =
90 render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
91 quad->SetNew(shared_state,
92 rect,
93 rect,
94 pass_id,
95 0, // mask_resource_id
96 gfx::Vector2dF(), // mask_uv_scale
97 gfx::Size(), // mask_texture_size
98 FilterOperations(), // foreground filters
99 gfx::Vector2dF(), // filters scale
100 FilterOperations()); // background filters
103 void CreateTestTwoColoredTextureDrawQuad(const gfx::Rect& rect,
104 SkColor texel_color,
105 SkColor texel_stripe_color,
106 SkColor background_color,
107 bool premultiplied_alpha,
108 const SharedQuadState* shared_state,
109 ResourceProvider* resource_provider,
110 RenderPass* render_pass) {
111 SkPMColor pixel_color = premultiplied_alpha
112 ? SkPreMultiplyColor(texel_color)
113 : SkPackARGB32NoCheck(SkColorGetA(texel_color),
114 SkColorGetR(texel_color),
115 SkColorGetG(texel_color),
116 SkColorGetB(texel_color));
117 SkPMColor pixel_stripe_color =
118 premultiplied_alpha
119 ? SkPreMultiplyColor(texel_stripe_color)
120 : SkPackARGB32NoCheck(SkColorGetA(texel_stripe_color),
121 SkColorGetR(texel_stripe_color),
122 SkColorGetG(texel_stripe_color),
123 SkColorGetB(texel_stripe_color));
124 std::vector<uint32_t> pixels(rect.size().GetArea(), pixel_color);
125 for (int i = rect.height() / 4; i < (rect.height() * 3 / 4); ++i) {
126 for (int k = rect.width() / 4; k < (rect.width() * 3 / 4); ++k) {
127 pixels[i * rect.width() + k] = pixel_stripe_color;
130 ResourceId resource = resource_provider->CreateResource(
131 rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
132 RGBA_8888);
133 resource_provider->CopyToResource(
134 resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size());
136 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
137 const gfx::PointF uv_top_left(0.0f, 0.0f);
138 const gfx::PointF uv_bottom_right(1.0f, 1.0f);
139 const bool flipped = false;
140 const bool nearest_neighbor = false;
141 TextureDrawQuad* quad =
142 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
143 quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource,
144 premultiplied_alpha, uv_top_left, uv_bottom_right,
145 background_color, vertex_opacity, flipped, nearest_neighbor);
148 void CreateTestTextureDrawQuad(const gfx::Rect& rect,
149 SkColor texel_color,
150 SkColor background_color,
151 bool premultiplied_alpha,
152 const SharedQuadState* shared_state,
153 ResourceProvider* resource_provider,
154 RenderPass* render_pass) {
155 SkPMColor pixel_color = premultiplied_alpha ?
156 SkPreMultiplyColor(texel_color) :
157 SkPackARGB32NoCheck(SkColorGetA(texel_color),
158 SkColorGetR(texel_color),
159 SkColorGetG(texel_color),
160 SkColorGetB(texel_color));
161 size_t num_pixels = static_cast<size_t>(rect.width()) * rect.height();
162 std::vector<uint32_t> pixels(num_pixels, pixel_color);
164 ResourceId resource = resource_provider->CreateResource(
165 rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
166 RGBA_8888);
167 resource_provider->CopyToResource(
168 resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size());
170 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
172 const gfx::PointF uv_top_left(0.0f, 0.0f);
173 const gfx::PointF uv_bottom_right(1.0f, 1.0f);
174 const bool flipped = false;
175 const bool nearest_neighbor = false;
176 TextureDrawQuad* quad =
177 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
178 quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource,
179 premultiplied_alpha, uv_top_left, uv_bottom_right,
180 background_color, vertex_opacity, flipped, nearest_neighbor);
183 void CreateTestYUVVideoDrawQuad_FromVideoFrame(
184 const SharedQuadState* shared_state,
185 scoped_refptr<media::VideoFrame> video_frame,
186 uint8 alpha_value,
187 const gfx::RectF& tex_coord_rect,
188 RenderPass* render_pass,
189 VideoResourceUpdater* video_resource_updater,
190 const gfx::Rect& rect,
191 const gfx::Rect& visible_rect,
192 ResourceProvider* resource_provider) {
193 const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A);
194 YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::REC_601;
195 int video_frame_color_space;
196 if (video_frame->metadata()->GetInteger(
197 media::VideoFrameMetadata::COLOR_SPACE, &video_frame_color_space) &&
198 video_frame_color_space == media::VideoFrame::COLOR_SPACE_JPEG) {
199 color_space = YUVVideoDrawQuad::JPEG;
202 const gfx::Rect opaque_rect(0, 0, 0, 0);
204 if (with_alpha) {
205 memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value,
206 video_frame->stride(media::VideoFrame::kAPlane) *
207 video_frame->rows(media::VideoFrame::kAPlane));
210 VideoFrameExternalResources resources =
211 video_resource_updater->CreateExternalResourcesFromVideoFrame(
212 video_frame);
214 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
215 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
216 resources.mailboxes.size());
217 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
218 resources.release_callbacks.size());
220 ResourceId y_resource = resource_provider->CreateResourceFromTextureMailbox(
221 resources.mailboxes[media::VideoFrame::kYPlane],
222 SingleReleaseCallbackImpl::Create(
223 resources.release_callbacks[media::VideoFrame::kYPlane]));
224 ResourceId u_resource = resource_provider->CreateResourceFromTextureMailbox(
225 resources.mailboxes[media::VideoFrame::kUPlane],
226 SingleReleaseCallbackImpl::Create(
227 resources.release_callbacks[media::VideoFrame::kUPlane]));
228 ResourceId v_resource = resource_provider->CreateResourceFromTextureMailbox(
229 resources.mailboxes[media::VideoFrame::kVPlane],
230 SingleReleaseCallbackImpl::Create(
231 resources.release_callbacks[media::VideoFrame::kVPlane]));
232 ResourceId a_resource = 0;
233 if (with_alpha) {
234 a_resource = resource_provider->CreateResourceFromTextureMailbox(
235 resources.mailboxes[media::VideoFrame::kAPlane],
236 SingleReleaseCallbackImpl::Create(
237 resources.release_callbacks[media::VideoFrame::kAPlane]));
240 const gfx::Size ya_tex_size = video_frame->coded_size();
241 const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize(
242 video_frame->format(), media::VideoFrame::kUPlane,
243 video_frame->coded_size());
244 DCHECK(uv_tex_size == media::VideoFrame::PlaneSize(
245 video_frame->format(), media::VideoFrame::kVPlane,
246 video_frame->coded_size()));
247 if (with_alpha) {
248 DCHECK(ya_tex_size == media::VideoFrame::PlaneSize(
249 video_frame->format(), media::VideoFrame::kAPlane,
250 video_frame->coded_size()));
253 gfx::RectF ya_tex_coord_rect(tex_coord_rect.x() * ya_tex_size.width(),
254 tex_coord_rect.y() * ya_tex_size.height(),
255 tex_coord_rect.width() * ya_tex_size.width(),
256 tex_coord_rect.height() * ya_tex_size.height());
257 gfx::RectF uv_tex_coord_rect(tex_coord_rect.x() * uv_tex_size.width(),
258 tex_coord_rect.y() * uv_tex_size.height(),
259 tex_coord_rect.width() * uv_tex_size.width(),
260 tex_coord_rect.height() * uv_tex_size.height());
262 YUVVideoDrawQuad* yuv_quad =
263 render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
264 yuv_quad->SetNew(shared_state, rect, opaque_rect, visible_rect,
265 ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size,
266 uv_tex_size, y_resource, u_resource, v_resource, a_resource,
267 color_space);
270 void CreateTestYUVVideoDrawQuad_Striped(
271 const SharedQuadState* shared_state,
272 media::VideoFrame::Format format,
273 bool is_transparent,
274 const gfx::RectF& tex_coord_rect,
275 RenderPass* render_pass,
276 VideoResourceUpdater* video_resource_updater,
277 const gfx::Rect& rect,
278 const gfx::Rect& visible_rect,
279 ResourceProvider* resource_provider) {
280 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
281 format, rect.size(), rect, rect.size(), base::TimeDelta());
283 // YUV values representing a striped pattern, for validating texture
284 // coordinates for sampling.
285 uint8_t y_value = 0;
286 uint8_t u_value = 0;
287 uint8_t v_value = 0;
288 for (int i = 0; i < video_frame->rows(media::VideoFrame::kYPlane); ++i) {
289 uint8_t* y_row = video_frame->data(media::VideoFrame::kYPlane) +
290 video_frame->stride(media::VideoFrame::kYPlane) * i;
291 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kYPlane);
292 ++j) {
293 y_row[j] = (y_value += 1);
296 for (int i = 0; i < video_frame->rows(media::VideoFrame::kUPlane); ++i) {
297 uint8_t* u_row = video_frame->data(media::VideoFrame::kUPlane) +
298 video_frame->stride(media::VideoFrame::kUPlane) * i;
299 uint8_t* v_row = video_frame->data(media::VideoFrame::kVPlane) +
300 video_frame->stride(media::VideoFrame::kVPlane) * i;
301 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kUPlane);
302 ++j) {
303 u_row[j] = (u_value += 3);
304 v_row[j] = (v_value += 5);
307 uint8 alpha_value = is_transparent ? 0 : 128;
308 CreateTestYUVVideoDrawQuad_FromVideoFrame(
309 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
310 video_resource_updater, rect, visible_rect, resource_provider);
313 // Creates a video frame of size background_size filled with yuv_background,
314 // and then draws a foreground rectangle in a different color on top of
315 // that. The foreground rectangle must have coordinates that are divisible
316 // by 2 because YUV is a block format.
317 void CreateTestYUVVideoDrawQuad_TwoColor(
318 const SharedQuadState* shared_state,
319 media::VideoFrame::Format format,
320 media::VideoFrame::ColorSpace color_space,
321 bool is_transparent,
322 const gfx::RectF& tex_coord_rect,
323 const gfx::Size& background_size,
324 const gfx::Rect& visible_rect,
325 uint8 y_background,
326 uint8 u_background,
327 uint8 v_background,
328 const gfx::Rect& foreground_rect,
329 uint8 y_foreground,
330 uint8 u_foreground,
331 uint8 v_foreground,
332 RenderPass* render_pass,
333 VideoResourceUpdater* video_resource_updater,
334 ResourceProvider* resource_provider) {
335 const gfx::Rect rect(background_size);
337 scoped_refptr<media::VideoFrame> video_frame =
338 media::VideoFrame::CreateFrame(format, background_size, foreground_rect,
339 foreground_rect.size(), base::TimeDelta());
340 video_frame->metadata()->SetInteger(media::VideoFrameMetadata::COLOR_SPACE,
341 color_space);
343 int planes[] = {media::VideoFrame::kYPlane,
344 media::VideoFrame::kUPlane,
345 media::VideoFrame::kVPlane};
346 uint8 yuv_background[] = {y_background, u_background, v_background};
347 uint8 yuv_foreground[] = {y_foreground, u_foreground, v_foreground};
348 int sample_size[] = {1, 2, 2};
350 for (int i = 0; i < 3; ++i) {
351 memset(video_frame->data(planes[i]), yuv_background[i],
352 video_frame->stride(planes[i]) * video_frame->rows(planes[i]));
355 for (int i = 0; i < 3; ++i) {
356 // Since yuv encoding uses block encoding, widths have to be divisible
357 // by the sample size in order for this function to behave properly.
358 DCHECK_EQ(foreground_rect.x() % sample_size[i], 0);
359 DCHECK_EQ(foreground_rect.y() % sample_size[i], 0);
360 DCHECK_EQ(foreground_rect.width() % sample_size[i], 0);
361 DCHECK_EQ(foreground_rect.height() % sample_size[i], 0);
363 gfx::Rect sample_rect(foreground_rect.x() / sample_size[i],
364 foreground_rect.y() / sample_size[i],
365 foreground_rect.width() / sample_size[i],
366 foreground_rect.height() / sample_size[i]);
367 for (int y = sample_rect.y(); y < sample_rect.bottom(); ++y) {
368 for (int x = sample_rect.x(); x < sample_rect.right(); ++x) {
369 size_t offset = y * video_frame->stride(planes[i]) + x;
370 video_frame->data(planes[i])[offset] = yuv_foreground[i];
375 uint8 alpha_value = 255;
376 CreateTestYUVVideoDrawQuad_FromVideoFrame(
377 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
378 video_resource_updater, rect, visible_rect, resource_provider);
381 void CreateTestYUVVideoDrawQuad_Solid(
382 const SharedQuadState* shared_state,
383 media::VideoFrame::Format format,
384 media::VideoFrame::ColorSpace color_space,
385 bool is_transparent,
386 const gfx::RectF& tex_coord_rect,
387 uint8 y,
388 uint8 u,
389 uint8 v,
390 RenderPass* render_pass,
391 VideoResourceUpdater* video_resource_updater,
392 const gfx::Rect& rect,
393 const gfx::Rect& visible_rect,
394 ResourceProvider* resource_provider) {
395 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
396 format, rect.size(), rect, rect.size(), base::TimeDelta());
397 video_frame->metadata()->SetInteger(media::VideoFrameMetadata::COLOR_SPACE,
398 color_space);
400 // YUV values of a solid, constant, color. Useful for testing that color
401 // space/color range are being handled properly.
402 memset(video_frame->data(media::VideoFrame::kYPlane), y,
403 video_frame->stride(media::VideoFrame::kYPlane) *
404 video_frame->rows(media::VideoFrame::kYPlane));
405 memset(video_frame->data(media::VideoFrame::kUPlane), u,
406 video_frame->stride(media::VideoFrame::kUPlane) *
407 video_frame->rows(media::VideoFrame::kUPlane));
408 memset(video_frame->data(media::VideoFrame::kVPlane), v,
409 video_frame->stride(media::VideoFrame::kVPlane) *
410 video_frame->rows(media::VideoFrame::kVPlane));
412 uint8 alpha_value = is_transparent ? 0 : 128;
413 CreateTestYUVVideoDrawQuad_FromVideoFrame(
414 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
415 video_resource_updater, rect, visible_rect, resource_provider);
418 typedef ::testing::Types<GLRenderer,
419 SoftwareRenderer,
420 GLRendererWithExpandedViewport,
421 SoftwareRendererWithExpandedViewport> RendererTypes;
422 TYPED_TEST_CASE(RendererPixelTest, RendererTypes);
424 template <typename RendererType>
425 class SoftwareRendererPixelTest : public RendererPixelTest<RendererType> {};
427 typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport>
428 SoftwareRendererTypes;
429 TYPED_TEST_CASE(SoftwareRendererPixelTest, SoftwareRendererTypes);
431 template <typename RendererType>
432 class FuzzyForSoftwareOnlyPixelComparator : public PixelComparator {
433 public:
434 explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha)
435 : fuzzy_(discard_alpha), exact_(discard_alpha) {}
437 bool Compare(const SkBitmap& actual_bmp,
438 const SkBitmap& expected_bmp) const override;
440 private:
441 FuzzyPixelOffByOneComparator fuzzy_;
442 ExactPixelComparator exact_;
445 template<>
446 bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare(
447 const SkBitmap& actual_bmp,
448 const SkBitmap& expected_bmp) const {
449 return fuzzy_.Compare(actual_bmp, expected_bmp);
452 template <>
453 bool FuzzyForSoftwareOnlyPixelComparator<
454 SoftwareRendererWithExpandedViewport>::Compare(
455 const SkBitmap& actual_bmp,
456 const SkBitmap& expected_bmp) const {
457 return fuzzy_.Compare(actual_bmp, expected_bmp);
460 template<typename RendererType>
461 bool FuzzyForSoftwareOnlyPixelComparator<RendererType>::Compare(
462 const SkBitmap& actual_bmp,
463 const SkBitmap& expected_bmp) const {
464 return exact_.Compare(actual_bmp, expected_bmp);
467 TYPED_TEST(RendererPixelTest, SimpleGreenRect) {
468 gfx::Rect rect(this->device_viewport_size_);
470 RenderPassId id(1, 1);
471 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
473 SharedQuadState* shared_state =
474 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
476 SolidColorDrawQuad* color_quad =
477 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
478 color_quad->SetNew(shared_state, rect, rect, SK_ColorGREEN, false);
480 RenderPassList pass_list;
481 pass_list.push_back(pass.Pass());
483 EXPECT_TRUE(this->RunPixelTest(
484 &pass_list,
485 base::FilePath(FILE_PATH_LITERAL("green.png")),
486 ExactPixelComparator(true)));
489 TYPED_TEST(RendererPixelTest, SimpleGreenRect_NonRootRenderPass) {
490 gfx::Rect rect(this->device_viewport_size_);
491 gfx::Rect small_rect(100, 100);
493 RenderPassId child_id(2, 1);
494 scoped_ptr<RenderPass> child_pass =
495 CreateTestRenderPass(child_id, small_rect, gfx::Transform());
497 SharedQuadState* child_shared_state =
498 CreateTestSharedQuadState(gfx::Transform(), small_rect, child_pass.get());
500 SolidColorDrawQuad* color_quad =
501 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
502 color_quad->SetNew(child_shared_state, rect, rect, SK_ColorGREEN, false);
504 RenderPassId root_id(1, 1);
505 scoped_ptr<RenderPass> root_pass =
506 CreateTestRenderPass(root_id, rect, gfx::Transform());
508 SharedQuadState* root_shared_state =
509 CreateTestSharedQuadState(gfx::Transform(), rect, root_pass.get());
511 CreateTestRenderPassDrawQuad(
512 root_shared_state, small_rect, child_id, root_pass.get());
514 RenderPass* child_pass_ptr = child_pass.get();
516 RenderPassList pass_list;
517 pass_list.push_back(child_pass.Pass());
518 pass_list.push_back(root_pass.Pass());
520 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
521 &pass_list,
522 child_pass_ptr,
523 base::FilePath(FILE_PATH_LITERAL("green_small.png")),
524 ExactPixelComparator(true)));
527 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithoutBackground) {
528 gfx::Rect rect(this->device_viewport_size_);
530 RenderPassId id(1, 1);
531 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
533 SharedQuadState* shared_state =
534 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
536 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
537 SkColorSetARGB(128, 0, 255, 0), // Texel color.
538 SK_ColorTRANSPARENT, // Background color.
539 true, // Premultiplied alpha.
540 shared_state,
541 this->resource_provider_.get(),
542 pass.get());
544 SolidColorDrawQuad* color_quad =
545 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
546 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
548 RenderPassList pass_list;
549 pass_list.push_back(pass.Pass());
551 EXPECT_TRUE(this->RunPixelTest(
552 &pass_list,
553 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
554 FuzzyPixelOffByOneComparator(true)));
557 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithBackground) {
558 gfx::Rect rect(this->device_viewport_size_);
560 RenderPassId id(1, 1);
561 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
563 SharedQuadState* texture_quad_state =
564 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
565 texture_quad_state->opacity = 0.8f;
567 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
568 SkColorSetARGB(204, 120, 255, 120), // Texel color.
569 SK_ColorGREEN, // Background color.
570 true, // Premultiplied alpha.
571 texture_quad_state,
572 this->resource_provider_.get(),
573 pass.get());
575 SharedQuadState* color_quad_state =
576 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
577 SolidColorDrawQuad* color_quad =
578 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
579 color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
581 RenderPassList pass_list;
582 pass_list.push_back(pass.Pass());
584 EXPECT_TRUE(this->RunPixelTest(
585 &pass_list,
586 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
587 FuzzyPixelOffByOneComparator(true)));
590 template <typename QuadType>
591 static const base::FilePath::CharType* IntersectingQuadImage() {
592 return FILE_PATH_LITERAL("intersecting_blue_green_squares.png");
594 template <>
595 const base::FilePath::CharType* IntersectingQuadImage<SolidColorDrawQuad>() {
596 return FILE_PATH_LITERAL("intersecting_blue_green.png");
598 template <>
599 const base::FilePath::CharType* IntersectingQuadImage<YUVVideoDrawQuad>() {
600 return FILE_PATH_LITERAL("intersecting_blue_green_squares_video.png");
603 template <typename TypeParam>
604 class IntersectingQuadPixelTest : public RendererPixelTest<TypeParam> {
605 protected:
606 void SetupQuadStateAndRenderPass() {
607 // This sets up a pair of draw quads. They are both rotated
608 // relative to the root plane, they are also rotated relative to each other.
609 // The intersect in the middle at a non-perpendicular angle so that any
610 // errors are hopefully magnified.
611 // The quads should intersect correctly, as in the front quad should only
612 // be partially in front of the back quad, and partially behind.
614 viewport_rect_ = gfx::Rect(this->device_viewport_size_);
615 quad_rect_ = gfx::Rect(0, 0, this->device_viewport_size_.width(),
616 this->device_viewport_size_.height() / 2.0);
618 RenderPassId id(1, 1);
619 render_pass_ = CreateTestRootRenderPass(id, viewport_rect_);
621 // Create the front quad rotated on the Z and Y axis.
622 gfx::Transform trans;
623 trans.Translate3d(0, 0, 0.707 * this->device_viewport_size_.width() / 2.0);
624 trans.RotateAboutZAxis(45.0);
625 trans.RotateAboutYAxis(45.0);
626 front_quad_state_ =
627 CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get());
628 front_quad_state_->clip_rect = quad_rect_;
629 // Make sure they end up in a 3d sorting context.
630 front_quad_state_->sorting_context_id = 1;
632 // Create the back quad, and rotate on just the y axis. This will intersect
633 // the first quad partially.
634 trans = gfx::Transform();
635 trans.Translate3d(0, 0, -0.707 * this->device_viewport_size_.width() / 2.0);
636 trans.RotateAboutYAxis(-45.0);
637 back_quad_state_ =
638 CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get());
639 back_quad_state_->sorting_context_id = 1;
640 back_quad_state_->clip_rect = quad_rect_;
642 template <typename T>
643 void AppendBackgroundAndRunTest(const PixelComparator& comparator) {
644 SharedQuadState* background_quad_state = CreateTestSharedQuadState(
645 gfx::Transform(), viewport_rect_, render_pass_.get());
646 SolidColorDrawQuad* background_quad =
647 render_pass_->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
648 background_quad->SetNew(background_quad_state, viewport_rect_,
649 viewport_rect_, SK_ColorWHITE, false);
650 pass_list_.push_back(render_pass_.Pass());
651 const base::FilePath::CharType* fileName = IntersectingQuadImage<T>();
652 EXPECT_TRUE(
653 this->RunPixelTest(&pass_list_, base::FilePath(fileName), comparator));
655 template <typename T>
656 T* CreateAndAppendDrawQuad() {
657 return render_pass_->CreateAndAppendDrawQuad<T>();
660 scoped_ptr<RenderPass> render_pass_;
661 gfx::Rect viewport_rect_;
662 SharedQuadState* front_quad_state_;
663 SharedQuadState* back_quad_state_;
664 gfx::Rect quad_rect_;
665 RenderPassList pass_list_;
668 template <typename TypeParam>
669 class IntersectingQuadGLPixelTest
670 : public IntersectingQuadPixelTest<TypeParam> {
671 public:
672 void SetUp() override {
673 IntersectingQuadPixelTest<TypeParam>::SetUp();
674 video_resource_updater_.reset(
675 new VideoResourceUpdater(this->output_surface_->context_provider(),
676 this->resource_provider_.get()));
677 video_resource_updater2_.reset(
678 new VideoResourceUpdater(this->output_surface_->context_provider(),
679 this->resource_provider_.get()));
682 protected:
683 scoped_ptr<VideoResourceUpdater> video_resource_updater_;
684 scoped_ptr<VideoResourceUpdater> video_resource_updater2_;
687 template <typename TypeParam>
688 class IntersectingQuadSoftwareTest
689 : public IntersectingQuadPixelTest<TypeParam> {};
691 typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport>
692 SoftwareRendererTypes;
693 typedef ::testing::Types<GLRenderer, GLRendererWithExpandedViewport>
694 GLRendererTypes;
696 TYPED_TEST_CASE(IntersectingQuadPixelTest, RendererTypes);
697 TYPED_TEST_CASE(IntersectingQuadGLPixelTest, GLRendererTypes);
698 TYPED_TEST_CASE(IntersectingQuadSoftwareTest, SoftwareRendererTypes);
700 TYPED_TEST(IntersectingQuadPixelTest, SolidColorQuads) {
701 this->SetupQuadStateAndRenderPass();
703 SolidColorDrawQuad* quad =
704 this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>();
705 SolidColorDrawQuad* quad2 =
706 this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>();
708 quad->SetNew(this->front_quad_state_, this->quad_rect_, this->quad_rect_,
709 SK_ColorBLUE, false);
710 quad2->SetNew(this->back_quad_state_, this->quad_rect_, this->quad_rect_,
711 SK_ColorGREEN, false);
712 SCOPED_TRACE("IntersectingSolidColorQuads");
713 this->template AppendBackgroundAndRunTest<SolidColorDrawQuad>(
714 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
717 template <typename TypeParam>
718 SkColor GetColor(const SkColor& color) {
719 return color;
722 template <>
723 SkColor GetColor<GLRenderer>(const SkColor& color) {
724 return SkColorSetARGB(SkColorGetA(color), SkColorGetB(color),
725 SkColorGetG(color), SkColorGetR(color));
727 template <>
728 SkColor GetColor<GLRendererWithExpandedViewport>(const SkColor& color) {
729 return GetColor<GLRenderer>(color);
732 TYPED_TEST(IntersectingQuadPixelTest, TexturedQuads) {
733 this->SetupQuadStateAndRenderPass();
734 CreateTestTwoColoredTextureDrawQuad(
735 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
736 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
737 true, this->front_quad_state_, this->resource_provider_.get(),
738 this->render_pass_.get());
739 CreateTestTwoColoredTextureDrawQuad(
740 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
741 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
742 true, this->back_quad_state_, this->resource_provider_.get(),
743 this->render_pass_.get());
745 SCOPED_TRACE("IntersectingTexturedQuads");
746 this->template AppendBackgroundAndRunTest<TextureDrawQuad>(
747 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
750 TYPED_TEST(IntersectingQuadSoftwareTest, PictureQuads) {
751 this->SetupQuadStateAndRenderPass();
752 gfx::RectF outer_rect(this->quad_rect_);
753 gfx::RectF inner_rect(this->quad_rect_.x() + (this->quad_rect_.width() / 4),
754 this->quad_rect_.y() + (this->quad_rect_.height() / 4),
755 this->quad_rect_.width() / 2,
756 this->quad_rect_.height() / 2);
758 SkPaint black_paint;
759 black_paint.setColor(SK_ColorBLACK);
760 SkPaint blue_paint;
761 blue_paint.setColor(SK_ColorBLUE);
762 SkPaint green_paint;
763 green_paint.setColor(SK_ColorGREEN);
765 scoped_ptr<FakePicturePile> blue_recording =
766 FakePicturePile::CreateFilledPile(gfx::Size(1000, 1000),
767 this->quad_rect_.size());
768 blue_recording->add_draw_rect_with_paint(outer_rect, black_paint);
769 blue_recording->add_draw_rect_with_paint(inner_rect, blue_paint);
770 blue_recording->Rerecord();
771 scoped_refptr<FakePicturePileImpl> blue_pile =
772 FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);
774 PictureDrawQuad* blue_quad =
775 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
777 blue_quad->SetNew(this->front_quad_state_, this->quad_rect_, gfx::Rect(),
778 this->quad_rect_, this->quad_rect_, this->quad_rect_.size(),
779 false, RGBA_8888, this->quad_rect_, 1.f, blue_pile);
781 scoped_ptr<FakePicturePile> green_recording =
782 FakePicturePile::CreateFilledPile(this->quad_rect_.size(),
783 this->quad_rect_.size());
784 green_recording->add_draw_rect_with_paint(outer_rect, green_paint);
785 green_recording->add_draw_rect_with_paint(inner_rect, black_paint);
786 green_recording->Rerecord();
787 scoped_refptr<FakePicturePileImpl> green_pile =
788 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
790 PictureDrawQuad* green_quad =
791 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
792 green_quad->SetNew(this->back_quad_state_, this->quad_rect_, gfx::Rect(),
793 this->quad_rect_, this->quad_rect_,
794 this->quad_rect_.size(), false, RGBA_8888,
795 this->quad_rect_, 1.f, green_pile);
796 SCOPED_TRACE("IntersectingPictureQuadsPass");
797 this->template AppendBackgroundAndRunTest<PictureDrawQuad>(
798 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
801 TYPED_TEST(IntersectingQuadPixelTest, RenderPassQuads) {
802 this->SetupQuadStateAndRenderPass();
803 RenderPassId child_pass_id1(2, 2);
804 RenderPassId child_pass_id2(2, 3);
805 scoped_ptr<RenderPass> child_pass1 =
806 CreateTestRenderPass(child_pass_id1, this->quad_rect_, gfx::Transform());
807 SharedQuadState* child1_quad_state = CreateTestSharedQuadState(
808 gfx::Transform(), this->quad_rect_, child_pass1.get());
809 scoped_ptr<RenderPass> child_pass2 =
810 CreateTestRenderPass(child_pass_id2, this->quad_rect_, gfx::Transform());
811 SharedQuadState* child2_quad_state = CreateTestSharedQuadState(
812 gfx::Transform(), this->quad_rect_, child_pass2.get());
814 CreateTestTwoColoredTextureDrawQuad(
815 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
816 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
817 true, child1_quad_state, this->resource_provider_.get(),
818 child_pass1.get());
819 CreateTestTwoColoredTextureDrawQuad(
820 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
821 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
822 true, child2_quad_state, this->resource_provider_.get(),
823 child_pass2.get());
825 CreateTestRenderPassDrawQuad(this->front_quad_state_, this->quad_rect_,
826 child_pass_id1, this->render_pass_.get());
827 CreateTestRenderPassDrawQuad(this->back_quad_state_, this->quad_rect_,
828 child_pass_id2, this->render_pass_.get());
830 this->pass_list_.push_back(child_pass1.Pass());
831 this->pass_list_.push_back(child_pass2.Pass());
832 SCOPED_TRACE("IntersectingRenderQuadsPass");
833 this->template AppendBackgroundAndRunTest<RenderPassDrawQuad>(
834 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
837 TYPED_TEST(IntersectingQuadGLPixelTest, YUVVideoQuads) {
838 this->SetupQuadStateAndRenderPass();
839 gfx::Rect inner_rect(
840 ((this->quad_rect_.x() + (this->quad_rect_.width() / 4)) & ~0xF),
841 ((this->quad_rect_.y() + (this->quad_rect_.height() / 4)) & ~0xF),
842 (this->quad_rect_.width() / 2) & ~0xF,
843 (this->quad_rect_.height() / 2) & ~0xF);
845 CreateTestYUVVideoDrawQuad_TwoColor(
846 this->front_quad_state_, media::VideoFrame::YV12,
847 media::VideoFrame::COLOR_SPACE_JPEG, false,
848 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(),
849 this->quad_rect_, 0, 128, 128, inner_rect, 29, 255, 107,
850 this->render_pass_.get(), this->video_resource_updater_.get(),
851 this->resource_provider_.get());
853 CreateTestYUVVideoDrawQuad_TwoColor(
854 this->back_quad_state_, media::VideoFrame::YV12,
855 media::VideoFrame::COLOR_SPACE_JPEG, false,
856 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(),
857 this->quad_rect_, 149, 43, 21, inner_rect, 0, 128, 128,
858 this->render_pass_.get(), this->video_resource_updater2_.get(),
859 this->resource_provider_.get());
861 SCOPED_TRACE("IntersectingVideoQuads");
862 this->template AppendBackgroundAndRunTest<YUVVideoDrawQuad>(
863 FuzzyPixelOffByOneComparator(false));
866 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
867 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) {
868 gfx::Rect rect(this->device_viewport_size_);
870 RenderPassId id(1, 1);
871 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
873 SharedQuadState* shared_state =
874 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
876 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
877 SkColorSetARGB(128, 0, 255, 0), // Texel color.
878 SK_ColorTRANSPARENT, // Background color.
879 false, // Premultiplied alpha.
880 shared_state,
881 this->resource_provider_.get(),
882 pass.get());
884 SolidColorDrawQuad* color_quad =
885 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
886 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
888 RenderPassList pass_list;
889 pass_list.push_back(pass.Pass());
891 EXPECT_TRUE(this->RunPixelTest(
892 &pass_list,
893 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
894 FuzzyPixelOffByOneComparator(true)));
897 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
898 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
899 gfx::Rect rect(this->device_viewport_size_);
901 RenderPassId id(1, 1);
902 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
904 SharedQuadState* texture_quad_state =
905 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
906 texture_quad_state->opacity = 0.8f;
908 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
909 SkColorSetARGB(204, 120, 255, 120), // Texel color.
910 SK_ColorGREEN, // Background color.
911 false, // Premultiplied alpha.
912 texture_quad_state,
913 this->resource_provider_.get(),
914 pass.get());
916 SharedQuadState* color_quad_state =
917 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
918 SolidColorDrawQuad* color_quad =
919 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
920 color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
922 RenderPassList pass_list;
923 pass_list.push_back(pass.Pass());
925 EXPECT_TRUE(this->RunPixelTest(
926 &pass_list,
927 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
928 FuzzyPixelOffByOneComparator(true)));
931 class VideoGLRendererPixelTest : public GLRendererPixelTest {
932 protected:
933 void CreateEdgeBleedPass(media::VideoFrame::Format format,
934 media::VideoFrame::ColorSpace color_space,
935 RenderPassList* pass_list) {
936 gfx::Rect rect(200, 200);
938 RenderPassId id(1, 1);
939 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
941 // Scale the video up so that bilinear filtering kicks in to sample more
942 // than just nearest neighbor would.
943 gfx::Transform scale_by_2;
944 scale_by_2.Scale(2.f, 2.f);
945 gfx::Rect half_rect(100, 100);
946 SharedQuadState* shared_state =
947 CreateTestSharedQuadState(scale_by_2, half_rect, pass.get());
949 gfx::Size background_size(200, 200);
950 gfx::Rect green_rect(16, 20, 100, 100);
951 gfx::RectF tex_coord_rect(
952 static_cast<float>(green_rect.x()) / background_size.width(),
953 static_cast<float>(green_rect.y()) / background_size.height(),
954 static_cast<float>(green_rect.width()) / background_size.width(),
955 static_cast<float>(green_rect.height()) / background_size.height());
957 // YUV of (149,43,21) should be green (0,255,0) in RGB.
958 // Create a video frame that has a non-green background rect, with a
959 // green sub-rectangle that should be the only thing displayed in
960 // the final image. Bleeding will appear on all four sides of the video
961 // if the tex coords are not clamped.
962 CreateTestYUVVideoDrawQuad_TwoColor(
963 shared_state, format, color_space, false, tex_coord_rect,
964 background_size, gfx::Rect(background_size), 128, 128, 128, green_rect,
965 149, 43, 21, pass.get(), video_resource_updater_.get(),
966 resource_provider_.get());
967 pass_list->push_back(pass.Pass());
970 void SetUp() override {
971 GLRendererPixelTest::SetUp();
972 video_resource_updater_.reset(new VideoResourceUpdater(
973 output_surface_->context_provider(), resource_provider_.get()));
976 scoped_ptr<VideoResourceUpdater> video_resource_updater_;
979 TEST_F(VideoGLRendererPixelTest, SimpleYUVRect) {
980 gfx::Rect rect(this->device_viewport_size_);
982 RenderPassId id(1, 1);
983 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
985 SharedQuadState* shared_state =
986 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
988 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::VideoFrame::YV12,
989 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
990 pass.get(), video_resource_updater_.get(),
991 rect, rect, resource_provider_.get());
993 RenderPassList pass_list;
994 pass_list.push_back(pass.Pass());
996 EXPECT_TRUE(
997 this->RunPixelTest(&pass_list,
998 base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
999 FuzzyPixelOffByOneComparator(true)));
1002 TEST_F(VideoGLRendererPixelTest, ClippedYUVRect) {
1003 gfx::Rect viewport(this->device_viewport_size_);
1004 gfx::Rect draw_rect(this->device_viewport_size_.width() * 1.5,
1005 this->device_viewport_size_.height() * 1.5);
1007 RenderPassId id(1, 1);
1008 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, viewport);
1010 SharedQuadState* shared_state =
1011 CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get());
1013 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::VideoFrame::YV12,
1014 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1015 pass.get(), video_resource_updater_.get(),
1016 draw_rect, viewport,
1017 resource_provider_.get());
1018 RenderPassList pass_list;
1019 pass_list.push_back(pass.Pass());
1021 EXPECT_TRUE(this->RunPixelTest(
1022 &pass_list, base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png")),
1023 FuzzyPixelOffByOneComparator(true)));
1026 TEST_F(VideoGLRendererPixelTest, OffsetYUVRect) {
1027 gfx::Rect rect(this->device_viewport_size_);
1029 RenderPassId id(1, 1);
1030 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1032 SharedQuadState* shared_state =
1033 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1035 // Intentionally sets frame format to I420 for testing coverage.
1036 CreateTestYUVVideoDrawQuad_Striped(
1037 shared_state, media::VideoFrame::I420, false,
1038 gfx::RectF(0.125f, 0.25f, 0.75f, 0.5f), pass.get(),
1039 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1041 RenderPassList pass_list;
1042 pass_list.push_back(pass.Pass());
1044 EXPECT_TRUE(this->RunPixelTest(
1045 &pass_list,
1046 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_offset.png")),
1047 FuzzyPixelOffByOneComparator(true)));
1050 TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) {
1051 gfx::Rect rect(this->device_viewport_size_);
1053 RenderPassId id(1, 1);
1054 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1056 SharedQuadState* shared_state =
1057 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1059 // In MPEG color range YUV values of (15,128,128) should produce black.
1060 CreateTestYUVVideoDrawQuad_Solid(
1061 shared_state, media::VideoFrame::YV12,
1062 media::VideoFrame::COLOR_SPACE_UNSPECIFIED, false,
1063 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
1064 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1066 RenderPassList pass_list;
1067 pass_list.push_back(pass.Pass());
1069 // If we didn't get black out of the YUV values above, then we probably have a
1070 // color range issue.
1071 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1072 base::FilePath(FILE_PATH_LITERAL("black.png")),
1073 FuzzyPixelOffByOneComparator(true)));
1076 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
1077 gfx::Rect rect(this->device_viewport_size_);
1079 RenderPassId id(1, 1);
1080 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1082 SharedQuadState* shared_state =
1083 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1085 // YUV of (149,43,21) should be green (0,255,0) in RGB.
1086 CreateTestYUVVideoDrawQuad_Solid(
1087 shared_state, media::VideoFrame::YV12,
1088 media::VideoFrame::COLOR_SPACE_JPEG, false,
1089 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(),
1090 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1092 RenderPassList pass_list;
1093 pass_list.push_back(pass.Pass());
1095 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1096 base::FilePath(FILE_PATH_LITERAL("green.png")),
1097 FuzzyPixelOffByOneComparator(true)));
1100 // Test that a YUV video doesn't bleed outside of its tex coords when the
1101 // tex coord rect is only a partial subrectangle of the coded contents.
1102 TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) {
1103 RenderPassList pass_list;
1104 CreateEdgeBleedPass(media::VideoFrame::YV12,
1105 media::VideoFrame::COLOR_SPACE_JPEG, &pass_list);
1106 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1107 base::FilePath(FILE_PATH_LITERAL("green.png")),
1108 FuzzyPixelOffByOneComparator(true)));
1111 TEST_F(VideoGLRendererPixelTest, YUVAEdgeBleed) {
1112 RenderPassList pass_list;
1113 CreateEdgeBleedPass(media::VideoFrame::YV12A,
1114 media::VideoFrame::COLOR_SPACE_UNSPECIFIED, &pass_list);
1115 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1116 base::FilePath(FILE_PATH_LITERAL("green.png")),
1117 FuzzyPixelOffByOneComparator(true)));
1120 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
1121 gfx::Rect rect(this->device_viewport_size_);
1123 RenderPassId id(1, 1);
1124 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1126 SharedQuadState* shared_state =
1127 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1129 // Dark grey in JPEG color range (in MPEG, this is black).
1130 CreateTestYUVVideoDrawQuad_Solid(
1131 shared_state, media::VideoFrame::YV12,
1132 media::VideoFrame::COLOR_SPACE_JPEG, false,
1133 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
1134 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1136 RenderPassList pass_list;
1137 pass_list.push_back(pass.Pass());
1139 EXPECT_TRUE(
1140 this->RunPixelTest(&pass_list,
1141 base::FilePath(FILE_PATH_LITERAL("dark_grey.png")),
1142 FuzzyPixelOffByOneComparator(true)));
1145 TEST_F(VideoGLRendererPixelTest, SimpleYUVARect) {
1146 gfx::Rect rect(this->device_viewport_size_);
1148 RenderPassId id(1, 1);
1149 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1151 SharedQuadState* shared_state =
1152 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1154 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::VideoFrame::YV12A,
1155 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1156 pass.get(), video_resource_updater_.get(),
1157 rect, rect, resource_provider_.get());
1159 SolidColorDrawQuad* color_quad =
1160 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1161 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
1163 RenderPassList pass_list;
1164 pass_list.push_back(pass.Pass());
1166 EXPECT_TRUE(this->RunPixelTest(
1167 &pass_list,
1168 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_alpha.png")),
1169 FuzzyPixelOffByOneComparator(true)));
1172 TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) {
1173 gfx::Rect rect(this->device_viewport_size_);
1175 RenderPassId id(1, 1);
1176 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1178 SharedQuadState* shared_state =
1179 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1181 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::VideoFrame::YV12A,
1182 true, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1183 pass.get(), video_resource_updater_.get(),
1184 rect, rect, resource_provider_.get());
1186 SolidColorDrawQuad* color_quad =
1187 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1188 color_quad->SetNew(shared_state, rect, rect, SK_ColorBLACK, false);
1190 RenderPassList pass_list;
1191 pass_list.push_back(pass.Pass());
1193 EXPECT_TRUE(this->RunPixelTest(
1194 &pass_list,
1195 base::FilePath(FILE_PATH_LITERAL("black.png")),
1196 ExactPixelComparator(true)));
1199 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) {
1200 gfx::Rect viewport_rect(this->device_viewport_size_);
1202 RenderPassId root_pass_id(1, 1);
1203 scoped_ptr<RenderPass> root_pass =
1204 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1206 RenderPassId child_pass_id(2, 2);
1207 gfx::Rect pass_rect(this->device_viewport_size_);
1208 gfx::Transform transform_to_root;
1209 scoped_ptr<RenderPass> child_pass =
1210 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1212 gfx::Transform quad_to_target_transform;
1213 SharedQuadState* shared_state = CreateTestSharedQuadState(
1214 quad_to_target_transform, viewport_rect, child_pass.get());
1215 shared_state->opacity = 0.5f;
1217 gfx::Rect blue_rect(0,
1219 this->device_viewport_size_.width(),
1220 this->device_viewport_size_.height() / 2);
1221 SolidColorDrawQuad* blue =
1222 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1223 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1224 gfx::Rect yellow_rect(0,
1225 this->device_viewport_size_.height() / 2,
1226 this->device_viewport_size_.width(),
1227 this->device_viewport_size_.height() / 2);
1228 SolidColorDrawQuad* yellow =
1229 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1230 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1232 SharedQuadState* blank_state = CreateTestSharedQuadState(
1233 quad_to_target_transform, viewport_rect, child_pass.get());
1235 SolidColorDrawQuad* white =
1236 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1237 white->SetNew(
1238 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1240 SharedQuadState* pass_shared_state =
1241 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1243 SkScalar matrix[20];
1244 float amount = 0.5f;
1245 matrix[0] = 0.213f + 0.787f * amount;
1246 matrix[1] = 0.715f - 0.715f * amount;
1247 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1248 matrix[3] = matrix[4] = 0;
1249 matrix[5] = 0.213f - 0.213f * amount;
1250 matrix[6] = 0.715f + 0.285f * amount;
1251 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1252 matrix[8] = matrix[9] = 0;
1253 matrix[10] = 0.213f - 0.213f * amount;
1254 matrix[11] = 0.715f - 0.715f * amount;
1255 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1256 matrix[13] = matrix[14] = 0;
1257 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1258 matrix[18] = 1;
1259 skia::RefPtr<SkColorFilter> colorFilter(
1260 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1261 skia::RefPtr<SkImageFilter> filter =
1262 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
1263 FilterOperations filters;
1264 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1266 RenderPassDrawQuad* render_pass_quad =
1267 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1268 render_pass_quad->SetNew(pass_shared_state,
1269 pass_rect,
1270 pass_rect,
1271 child_pass_id,
1273 gfx::Vector2dF(),
1274 gfx::Size(),
1275 filters,
1276 gfx::Vector2dF(),
1277 FilterOperations());
1279 RenderPassList pass_list;
1280 pass_list.push_back(child_pass.Pass());
1281 pass_list.push_back(root_pass.Pass());
1283 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1284 // renderer so use a fuzzy comparator.
1285 EXPECT_TRUE(this->RunPixelTest(
1286 &pass_list,
1287 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1288 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1291 TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) {
1292 gfx::Rect viewport_rect(this->device_viewport_size_);
1294 RenderPassId root_pass_id(1, 1);
1295 scoped_ptr<RenderPass> root_pass =
1296 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1298 RenderPassId child_pass_id(2, 2);
1299 gfx::Rect pass_rect(this->device_viewport_size_);
1300 gfx::Transform transform_to_root;
1301 scoped_ptr<RenderPass> child_pass =
1302 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1304 gfx::Transform quad_to_target_transform;
1305 SharedQuadState* shared_state = CreateTestSharedQuadState(
1306 quad_to_target_transform, viewport_rect, child_pass.get());
1307 shared_state->opacity = 0.5f;
1309 gfx::Rect blue_rect(0,
1311 this->device_viewport_size_.width(),
1312 this->device_viewport_size_.height() / 2);
1313 SolidColorDrawQuad* blue =
1314 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1315 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1316 gfx::Rect yellow_rect(0,
1317 this->device_viewport_size_.height() / 2,
1318 this->device_viewport_size_.width(),
1319 this->device_viewport_size_.height() / 2);
1320 SolidColorDrawQuad* yellow =
1321 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1322 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1324 SharedQuadState* blank_state = CreateTestSharedQuadState(
1325 quad_to_target_transform, viewport_rect, child_pass.get());
1327 SolidColorDrawQuad* white =
1328 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1329 white->SetNew(
1330 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1332 SharedQuadState* pass_shared_state =
1333 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1335 FilterOperations filters;
1336 filters.Append(FilterOperation::CreateSaturateFilter(0.5f));
1338 RenderPassDrawQuad* render_pass_quad =
1339 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1340 render_pass_quad->SetNew(pass_shared_state,
1341 pass_rect,
1342 pass_rect,
1343 child_pass_id,
1345 gfx::Vector2dF(),
1346 gfx::Size(),
1347 filters,
1348 gfx::Vector2dF(),
1349 FilterOperations());
1351 RenderPassList pass_list;
1352 pass_list.push_back(child_pass.Pass());
1353 pass_list.push_back(root_pass.Pass());
1355 // This test blends slightly differently with the software renderer vs. the gl
1356 // renderer so use a fuzzy comparator.
1357 EXPECT_TRUE(this->RunPixelTest(
1358 &pass_list, base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1359 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1362 TYPED_TEST(RendererPixelTest, FastPassFilterChain) {
1363 gfx::Rect viewport_rect(this->device_viewport_size_);
1365 RenderPassId root_pass_id(1, 1);
1366 scoped_ptr<RenderPass> root_pass =
1367 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1369 RenderPassId child_pass_id(2, 2);
1370 gfx::Rect pass_rect(this->device_viewport_size_);
1371 gfx::Transform transform_to_root;
1372 scoped_ptr<RenderPass> child_pass =
1373 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1375 gfx::Transform quad_to_target_transform;
1376 SharedQuadState* shared_state = CreateTestSharedQuadState(
1377 quad_to_target_transform, viewport_rect, child_pass.get());
1378 shared_state->opacity = 0.5f;
1380 gfx::Rect blue_rect(0,
1382 this->device_viewport_size_.width(),
1383 this->device_viewport_size_.height() / 2);
1384 SolidColorDrawQuad* blue =
1385 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1386 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1387 gfx::Rect yellow_rect(0,
1388 this->device_viewport_size_.height() / 2,
1389 this->device_viewport_size_.width(),
1390 this->device_viewport_size_.height() / 2);
1391 SolidColorDrawQuad* yellow =
1392 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1393 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1395 SharedQuadState* blank_state = CreateTestSharedQuadState(
1396 quad_to_target_transform, viewport_rect, child_pass.get());
1398 SolidColorDrawQuad* white =
1399 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1400 white->SetNew(
1401 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1403 SharedQuadState* pass_shared_state =
1404 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1406 FilterOperations filters;
1407 filters.Append(FilterOperation::CreateGrayscaleFilter(1.f));
1408 filters.Append(FilterOperation::CreateBrightnessFilter(0.5f));
1410 RenderPassDrawQuad* render_pass_quad =
1411 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1412 render_pass_quad->SetNew(pass_shared_state,
1413 pass_rect,
1414 pass_rect,
1415 child_pass_id,
1417 gfx::Vector2dF(),
1418 gfx::Size(),
1419 filters,
1420 gfx::Vector2dF(),
1421 FilterOperations());
1423 RenderPassList pass_list;
1424 pass_list.push_back(child_pass.Pass());
1425 pass_list.push_back(root_pass.Pass());
1427 // This test blends slightly differently with the software renderer vs. the gl
1428 // renderer so use a fuzzy comparator.
1429 EXPECT_TRUE(this->RunPixelTest(
1430 &pass_list,
1431 base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")),
1432 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1435 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) {
1436 gfx::Rect viewport_rect(this->device_viewport_size_);
1438 RenderPassId root_pass_id(1, 1);
1439 scoped_ptr<RenderPass> root_pass =
1440 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1442 RenderPassId child_pass_id(2, 2);
1443 gfx::Rect pass_rect(this->device_viewport_size_);
1444 gfx::Transform transform_to_root;
1445 scoped_ptr<RenderPass> child_pass =
1446 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1448 gfx::Transform quad_to_target_transform;
1449 SharedQuadState* shared_state = CreateTestSharedQuadState(
1450 quad_to_target_transform, viewport_rect, child_pass.get());
1451 shared_state->opacity = 0.5f;
1453 gfx::Rect blue_rect(0,
1455 this->device_viewport_size_.width(),
1456 this->device_viewport_size_.height() / 2);
1457 SolidColorDrawQuad* blue =
1458 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1459 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1460 gfx::Rect yellow_rect(0,
1461 this->device_viewport_size_.height() / 2,
1462 this->device_viewport_size_.width(),
1463 this->device_viewport_size_.height() / 2);
1464 SolidColorDrawQuad* yellow =
1465 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1466 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1468 SharedQuadState* blank_state = CreateTestSharedQuadState(
1469 quad_to_target_transform, viewport_rect, child_pass.get());
1471 SolidColorDrawQuad* white =
1472 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1473 white->SetNew(
1474 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1476 SharedQuadState* pass_shared_state =
1477 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1479 SkScalar matrix[20];
1480 float amount = 0.5f;
1481 matrix[0] = 0.213f + 0.787f * amount;
1482 matrix[1] = 0.715f - 0.715f * amount;
1483 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1484 matrix[3] = 0;
1485 matrix[4] = 20.f;
1486 matrix[5] = 0.213f - 0.213f * amount;
1487 matrix[6] = 0.715f + 0.285f * amount;
1488 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1489 matrix[8] = 0;
1490 matrix[9] = 200.f;
1491 matrix[10] = 0.213f - 0.213f * amount;
1492 matrix[11] = 0.715f - 0.715f * amount;
1493 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1494 matrix[13] = 0;
1495 matrix[14] = 1.5f;
1496 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1497 matrix[18] = 1;
1498 skia::RefPtr<SkColorFilter> colorFilter(
1499 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1500 skia::RefPtr<SkImageFilter> filter =
1501 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
1502 FilterOperations filters;
1503 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1505 RenderPassDrawQuad* render_pass_quad =
1506 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1507 render_pass_quad->SetNew(pass_shared_state,
1508 pass_rect,
1509 pass_rect,
1510 child_pass_id,
1512 gfx::Vector2dF(),
1513 gfx::Size(),
1514 filters,
1515 gfx::Vector2dF(),
1516 FilterOperations());
1518 RenderPassList pass_list;
1520 pass_list.push_back(child_pass.Pass());
1521 pass_list.push_back(root_pass.Pass());
1523 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1524 // renderer so use a fuzzy comparator.
1525 EXPECT_TRUE(this->RunPixelTest(
1526 &pass_list,
1527 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
1528 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1531 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) {
1532 gfx::Rect viewport_rect(this->device_viewport_size_);
1534 RenderPassId root_pass_id(1, 1);
1535 scoped_ptr<RenderPass> root_pass =
1536 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1538 RenderPassId child_pass_id(2, 2);
1539 gfx::Rect pass_rect(this->device_viewport_size_);
1540 gfx::Transform transform_to_root;
1541 scoped_ptr<RenderPass> child_pass =
1542 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1544 gfx::Transform quad_to_target_transform;
1545 SharedQuadState* shared_state = CreateTestSharedQuadState(
1546 quad_to_target_transform, viewport_rect, child_pass.get());
1548 gfx::Rect blue_rect(0,
1550 this->device_viewport_size_.width(),
1551 this->device_viewport_size_.height() / 2);
1552 SolidColorDrawQuad* blue =
1553 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1554 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1555 gfx::Rect yellow_rect(0,
1556 this->device_viewport_size_.height() / 2,
1557 this->device_viewport_size_.width(),
1558 this->device_viewport_size_.height() / 2);
1559 SolidColorDrawQuad* yellow =
1560 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1561 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1563 SharedQuadState* pass_shared_state =
1564 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1565 CreateTestRenderPassDrawQuad(
1566 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1568 RenderPassList pass_list;
1569 pass_list.push_back(child_pass.Pass());
1570 pass_list.push_back(root_pass.Pass());
1572 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1574 EXPECT_TRUE(this->RunPixelTest(
1575 &pass_list,
1576 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
1577 ExactPixelComparator(true)));
1580 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) {
1581 gfx::Rect viewport_rect(this->device_viewport_size_);
1583 RenderPassId root_pass_id(1, 1);
1584 scoped_ptr<RenderPass> root_pass =
1585 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1587 RenderPassId child_pass_id(2, 2);
1588 gfx::Rect pass_rect(this->device_viewport_size_);
1589 gfx::Transform transform_to_root;
1590 scoped_ptr<RenderPass> child_pass =
1591 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1593 gfx::Transform quad_to_target_transform;
1594 SharedQuadState* shared_state = CreateTestSharedQuadState(
1595 quad_to_target_transform, viewport_rect, child_pass.get());
1597 gfx::Rect blue_rect(0,
1599 this->device_viewport_size_.width(),
1600 this->device_viewport_size_.height() / 2);
1601 SolidColorDrawQuad* blue =
1602 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1603 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1604 gfx::Rect yellow_rect(0,
1605 this->device_viewport_size_.height() / 2,
1606 this->device_viewport_size_.width(),
1607 this->device_viewport_size_.height() / 2);
1608 SolidColorDrawQuad* yellow =
1609 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1610 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1612 gfx::Transform aa_transform;
1613 aa_transform.Translate(0.5, 0.0);
1615 SharedQuadState* pass_shared_state =
1616 CreateTestSharedQuadState(aa_transform, pass_rect, root_pass.get());
1617 CreateTestRenderPassDrawQuad(
1618 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1620 SharedQuadState* root_shared_state = CreateTestSharedQuadState(
1621 gfx::Transform(), viewport_rect, root_pass.get());
1622 SolidColorDrawQuad* background =
1623 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1624 background->SetNew(root_shared_state,
1625 gfx::Rect(this->device_viewport_size_),
1626 gfx::Rect(this->device_viewport_size_),
1627 SK_ColorWHITE,
1628 false);
1630 RenderPassList pass_list;
1631 pass_list.push_back(child_pass.Pass());
1632 pass_list.push_back(root_pass.Pass());
1634 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1636 EXPECT_TRUE(this->RunPixelTest(
1637 &pass_list,
1638 base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")),
1639 FuzzyPixelOffByOneComparator(true)));
1642 // This tests the case where we have a RenderPass with a mask, but the quad
1643 // for the masked surface does not include the full surface texture.
1644 TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) {
1645 gfx::Rect viewport_rect(this->device_viewport_size_);
1647 RenderPassId root_pass_id(1, 1);
1648 scoped_ptr<RenderPass> root_pass =
1649 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1650 SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState(
1651 gfx::Transform(), viewport_rect, root_pass.get());
1653 RenderPassId child_pass_id(2, 2);
1654 gfx::Transform transform_to_root;
1655 scoped_ptr<RenderPass> child_pass =
1656 CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root);
1657 SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState(
1658 gfx::Transform(), viewport_rect, child_pass.get());
1660 // The child render pass is just a green box.
1661 static const SkColor kCSSGreen = 0xff008000;
1662 SolidColorDrawQuad* green =
1663 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1664 green->SetNew(
1665 child_pass_shared_state, viewport_rect, viewport_rect, kCSSGreen, false);
1667 // Make a mask.
1668 gfx::Rect mask_rect = viewport_rect;
1669 SkBitmap bitmap;
1670 bitmap.allocPixels(
1671 SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height()));
1672 SkCanvas canvas(bitmap);
1673 SkPaint paint;
1674 paint.setStyle(SkPaint::kStroke_Style);
1675 paint.setStrokeWidth(SkIntToScalar(4));
1676 paint.setColor(SK_ColorWHITE);
1677 canvas.clear(SK_ColorTRANSPARENT);
1678 gfx::Rect rect = mask_rect;
1679 while (!rect.IsEmpty()) {
1680 rect.Inset(6, 6, 4, 4);
1681 canvas.drawRect(
1682 SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()),
1683 paint);
1684 rect.Inset(6, 6, 4, 4);
1687 ResourceId mask_resource_id = this->resource_provider_->CreateResource(
1688 mask_rect.size(), GL_CLAMP_TO_EDGE,
1689 ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
1691 SkAutoLockPixels lock(bitmap);
1692 this->resource_provider_->CopyToResource(
1693 mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
1694 mask_rect.size());
1697 // This RenderPassDrawQuad does not include the full |viewport_rect| which is
1698 // the size of the child render pass.
1699 gfx::Rect sub_rect = gfx::Rect(50, 50, 200, 100);
1700 EXPECT_NE(sub_rect.x(), child_pass->output_rect.x());
1701 EXPECT_NE(sub_rect.y(), child_pass->output_rect.y());
1702 EXPECT_NE(sub_rect.right(), child_pass->output_rect.right());
1703 EXPECT_NE(sub_rect.bottom(), child_pass->output_rect.bottom());
1705 // Set up a mask on the RenderPassDrawQuad.
1706 RenderPassDrawQuad* mask_quad =
1707 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1708 mask_quad->SetNew(root_pass_shared_state,
1709 sub_rect,
1710 sub_rect,
1711 child_pass_id,
1712 mask_resource_id,
1713 gfx::Vector2dF(2.f, 1.f), // mask_uv_scale
1714 gfx::Size(mask_rect.size()), // mask_texture_size
1715 FilterOperations(), // foreground filters
1716 gfx::Vector2dF(), // filters scale
1717 FilterOperations()); // background filters
1719 // White background behind the masked render pass.
1720 SolidColorDrawQuad* white =
1721 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1722 white->SetNew(root_pass_shared_state,
1723 viewport_rect,
1724 viewport_rect,
1725 SK_ColorWHITE,
1726 false);
1728 RenderPassList pass_list;
1729 pass_list.push_back(child_pass.Pass());
1730 pass_list.push_back(root_pass.Pass());
1732 EXPECT_TRUE(this->RunPixelTest(
1733 &pass_list,
1734 base::FilePath(FILE_PATH_LITERAL("mask_bottom_right.png")),
1735 ExactPixelComparator(true)));
1738 template <typename RendererType>
1739 class RendererPixelTestWithBackgroundFilter
1740 : public RendererPixelTest<RendererType> {
1741 protected:
1742 void SetUpRenderPassList() {
1743 gfx::Rect device_viewport_rect(this->device_viewport_size_);
1745 RenderPassId root_id(1, 1);
1746 scoped_ptr<RenderPass> root_pass =
1747 CreateTestRootRenderPass(root_id, device_viewport_rect);
1748 root_pass->has_transparent_background = false;
1750 gfx::Transform identity_quad_to_target_transform;
1752 RenderPassId filter_pass_id(2, 1);
1753 gfx::Transform transform_to_root;
1754 scoped_ptr<RenderPass> filter_pass = CreateTestRenderPass(
1755 filter_pass_id, filter_pass_layer_rect_, transform_to_root);
1757 // A non-visible quad in the filtering render pass.
1759 SharedQuadState* shared_state =
1760 CreateTestSharedQuadState(identity_quad_to_target_transform,
1761 filter_pass_layer_rect_, filter_pass.get());
1762 SolidColorDrawQuad* color_quad =
1763 filter_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1764 color_quad->SetNew(shared_state, filter_pass_layer_rect_,
1765 filter_pass_layer_rect_, SK_ColorTRANSPARENT, false);
1769 SharedQuadState* shared_state =
1770 CreateTestSharedQuadState(filter_pass_to_target_transform_,
1771 filter_pass_layer_rect_, filter_pass.get());
1772 RenderPassDrawQuad* filter_pass_quad =
1773 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1774 filter_pass_quad->SetNew(shared_state, filter_pass_layer_rect_,
1775 filter_pass_layer_rect_, filter_pass_id,
1776 0, // mask_resource_id
1777 gfx::Vector2dF(), // mask_uv_scale
1778 gfx::Size(), // mask_texture_size
1779 FilterOperations(), // filters
1780 gfx::Vector2dF(), // filters_scale
1781 this->background_filters_);
1784 const int kColumnWidth = device_viewport_rect.width() / 3;
1786 gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20);
1787 for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) {
1788 SharedQuadState* shared_state = CreateTestSharedQuadState(
1789 identity_quad_to_target_transform, left_rect, root_pass.get());
1790 SolidColorDrawQuad* color_quad =
1791 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1792 color_quad->SetNew(
1793 shared_state, left_rect, left_rect, SK_ColorGREEN, false);
1794 left_rect += gfx::Vector2d(0, left_rect.height() + 1);
1797 gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20);
1798 for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) {
1799 SharedQuadState* shared_state = CreateTestSharedQuadState(
1800 identity_quad_to_target_transform, middle_rect, root_pass.get());
1801 SolidColorDrawQuad* color_quad =
1802 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1803 color_quad->SetNew(
1804 shared_state, middle_rect, middle_rect, SK_ColorRED, false);
1805 middle_rect += gfx::Vector2d(0, middle_rect.height() + 1);
1808 gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20);
1809 for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) {
1810 SharedQuadState* shared_state = CreateTestSharedQuadState(
1811 identity_quad_to_target_transform, right_rect, root_pass.get());
1812 SolidColorDrawQuad* color_quad =
1813 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1814 color_quad->SetNew(
1815 shared_state, right_rect, right_rect, SK_ColorBLUE, false);
1816 right_rect += gfx::Vector2d(0, right_rect.height() + 1);
1819 SharedQuadState* shared_state =
1820 CreateTestSharedQuadState(identity_quad_to_target_transform,
1821 device_viewport_rect, root_pass.get());
1822 SolidColorDrawQuad* background_quad =
1823 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1824 background_quad->SetNew(shared_state,
1825 device_viewport_rect,
1826 device_viewport_rect,
1827 SK_ColorWHITE,
1828 false);
1830 pass_list_.push_back(filter_pass.Pass());
1831 pass_list_.push_back(root_pass.Pass());
1834 RenderPassList pass_list_;
1835 FilterOperations background_filters_;
1836 gfx::Transform filter_pass_to_target_transform_;
1837 gfx::Rect filter_pass_layer_rect_;
1840 typedef ::testing::Types<GLRenderer, SoftwareRenderer>
1841 BackgroundFilterRendererTypes;
1842 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter,
1843 BackgroundFilterRendererTypes);
1845 typedef RendererPixelTestWithBackgroundFilter<GLRenderer>
1846 GLRendererPixelTestWithBackgroundFilter;
1848 // TODO(skaslev): The software renderer does not support filters yet.
1849 TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) {
1850 this->background_filters_.Append(
1851 FilterOperation::CreateInvertFilter(1.f));
1853 this->filter_pass_layer_rect_ = gfx::Rect(this->device_viewport_size_);
1854 this->filter_pass_layer_rect_.Inset(12, 14, 16, 18);
1856 this->SetUpRenderPassList();
1857 EXPECT_TRUE(this->RunPixelTest(
1858 &this->pass_list_,
1859 base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
1860 ExactPixelComparator(true)));
1863 class ExternalStencilPixelTest : public GLRendererPixelTest {
1864 protected:
1865 void ClearBackgroundToGreen() {
1866 GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
1867 output_surface_->EnsureBackbuffer();
1868 output_surface_->Reshape(device_viewport_size_, 1);
1869 gl->ClearColor(0.f, 1.f, 0.f, 1.f);
1870 gl->Clear(GL_COLOR_BUFFER_BIT);
1873 void PopulateStencilBuffer() {
1874 // Set two quadrants of the stencil buffer to 1.
1875 GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
1876 output_surface_->EnsureBackbuffer();
1877 output_surface_->Reshape(device_viewport_size_, 1);
1878 gl->ClearStencil(0);
1879 gl->Clear(GL_STENCIL_BUFFER_BIT);
1880 gl->Enable(GL_SCISSOR_TEST);
1881 gl->ClearStencil(1);
1882 gl->Scissor(0,
1884 device_viewport_size_.width() / 2,
1885 device_viewport_size_.height() / 2);
1886 gl->Clear(GL_STENCIL_BUFFER_BIT);
1887 gl->Scissor(device_viewport_size_.width() / 2,
1888 device_viewport_size_.height() / 2,
1889 device_viewport_size_.width(),
1890 device_viewport_size_.height());
1891 gl->Clear(GL_STENCIL_BUFFER_BIT);
1895 TEST_F(ExternalStencilPixelTest, StencilTestEnabled) {
1896 ClearBackgroundToGreen();
1897 PopulateStencilBuffer();
1898 this->EnableExternalStencilTest();
1900 // Draw a blue quad that covers the entire device viewport. It should be
1901 // clipped to the bottom left and top right corners by the external stencil.
1902 gfx::Rect rect(this->device_viewport_size_);
1903 RenderPassId id(1, 1);
1904 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1905 SharedQuadState* blue_shared_state =
1906 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1907 SolidColorDrawQuad* blue =
1908 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1909 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1910 pass->has_transparent_background = false;
1911 RenderPassList pass_list;
1912 pass_list.push_back(pass.Pass());
1914 EXPECT_TRUE(this->RunPixelTest(
1915 &pass_list,
1916 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1917 ExactPixelComparator(true)));
1920 TEST_F(ExternalStencilPixelTest, StencilTestDisabled) {
1921 PopulateStencilBuffer();
1923 // Draw a green quad that covers the entire device viewport. The stencil
1924 // buffer should be ignored.
1925 gfx::Rect rect(this->device_viewport_size_);
1926 RenderPassId id(1, 1);
1927 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1928 SharedQuadState* green_shared_state =
1929 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1930 SolidColorDrawQuad* green =
1931 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1932 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
1933 RenderPassList pass_list;
1934 pass_list.push_back(pass.Pass());
1936 EXPECT_TRUE(this->RunPixelTest(
1937 &pass_list,
1938 base::FilePath(FILE_PATH_LITERAL("green.png")),
1939 ExactPixelComparator(true)));
1942 TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) {
1943 // The stencil test should apply only to the final render pass.
1944 ClearBackgroundToGreen();
1945 PopulateStencilBuffer();
1946 this->EnableExternalStencilTest();
1948 gfx::Rect viewport_rect(this->device_viewport_size_);
1950 RenderPassId root_pass_id(1, 1);
1951 scoped_ptr<RenderPass> root_pass =
1952 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1953 root_pass->has_transparent_background = false;
1955 RenderPassId child_pass_id(2, 2);
1956 gfx::Rect pass_rect(this->device_viewport_size_);
1957 gfx::Transform transform_to_root;
1958 scoped_ptr<RenderPass> child_pass =
1959 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1961 gfx::Transform quad_to_target_transform;
1962 SharedQuadState* shared_state = CreateTestSharedQuadState(
1963 quad_to_target_transform, viewport_rect, child_pass.get());
1965 gfx::Rect blue_rect(0,
1967 this->device_viewport_size_.width(),
1968 this->device_viewport_size_.height());
1969 SolidColorDrawQuad* blue =
1970 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1971 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1973 SharedQuadState* pass_shared_state =
1974 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1975 CreateTestRenderPassDrawQuad(
1976 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1977 RenderPassList pass_list;
1978 pass_list.push_back(child_pass.Pass());
1979 pass_list.push_back(root_pass.Pass());
1981 EXPECT_TRUE(this->RunPixelTest(
1982 &pass_list,
1983 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1984 ExactPixelComparator(true)));
1987 TEST_F(ExternalStencilPixelTest, DeviceClip) {
1988 ClearBackgroundToGreen();
1989 gfx::Rect clip_rect(gfx::Point(150, 150), gfx::Size(50, 50));
1990 this->ForceDeviceClip(clip_rect);
1992 // Draw a blue quad that covers the entire device viewport. It should be
1993 // clipped to the bottom right corner by the device clip.
1994 gfx::Rect rect(this->device_viewport_size_);
1995 RenderPassId id(1, 1);
1996 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1997 SharedQuadState* blue_shared_state =
1998 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1999 SolidColorDrawQuad* blue =
2000 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2001 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2002 RenderPassList pass_list;
2003 pass_list.push_back(pass.Pass());
2005 EXPECT_TRUE(this->RunPixelTest(
2006 &pass_list,
2007 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
2008 ExactPixelComparator(true)));
2011 // Software renderer does not support anti-aliased edges.
2012 TEST_F(GLRendererPixelTest, AntiAliasing) {
2013 gfx::Rect rect(this->device_viewport_size_);
2015 RenderPassId id(1, 1);
2016 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2018 gfx::Transform red_quad_to_target_transform;
2019 red_quad_to_target_transform.Rotate(10);
2020 SharedQuadState* red_shared_state =
2021 CreateTestSharedQuadState(red_quad_to_target_transform, rect, pass.get());
2023 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2024 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
2026 gfx::Transform yellow_quad_to_target_transform;
2027 yellow_quad_to_target_transform.Rotate(5);
2028 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
2029 yellow_quad_to_target_transform, rect, pass.get());
2031 SolidColorDrawQuad* yellow =
2032 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2033 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
2035 gfx::Transform blue_quad_to_target_transform;
2036 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2037 blue_quad_to_target_transform, rect, pass.get());
2039 SolidColorDrawQuad* blue =
2040 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2041 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2043 RenderPassList pass_list;
2044 pass_list.push_back(pass.Pass());
2046 EXPECT_TRUE(this->RunPixelTest(
2047 &pass_list,
2048 base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")),
2049 FuzzyPixelOffByOneComparator(true)));
2052 // This test tests that anti-aliasing works for axis aligned quads.
2053 // Anti-aliasing is only supported in the gl renderer.
2054 TEST_F(GLRendererPixelTest, AxisAligned) {
2055 gfx::Rect rect(this->device_viewport_size_);
2057 RenderPassId id(1, 1);
2058 gfx::Transform transform_to_root;
2059 scoped_ptr<RenderPass> pass =
2060 CreateTestRenderPass(id, rect, transform_to_root);
2062 gfx::Transform red_quad_to_target_transform;
2063 red_quad_to_target_transform.Translate(50, 50);
2064 red_quad_to_target_transform.Scale(0.5f + 1.0f / (rect.width() * 2.0f),
2065 0.5f + 1.0f / (rect.height() * 2.0f));
2066 SharedQuadState* red_shared_state =
2067 CreateTestSharedQuadState(red_quad_to_target_transform, rect, pass.get());
2069 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2070 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
2072 gfx::Transform yellow_quad_to_target_transform;
2073 yellow_quad_to_target_transform.Translate(25.5f, 25.5f);
2074 yellow_quad_to_target_transform.Scale(0.5f, 0.5f);
2075 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
2076 yellow_quad_to_target_transform, rect, pass.get());
2078 SolidColorDrawQuad* yellow =
2079 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2080 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
2082 gfx::Transform blue_quad_to_target_transform;
2083 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2084 blue_quad_to_target_transform, rect, pass.get());
2086 SolidColorDrawQuad* blue =
2087 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2088 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2090 RenderPassList pass_list;
2091 pass_list.push_back(pass.Pass());
2093 EXPECT_TRUE(this->RunPixelTest(
2094 &pass_list,
2095 base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")),
2096 ExactPixelComparator(true)));
2099 // This test tests that forcing anti-aliasing off works as expected.
2100 // Anti-aliasing is only supported in the gl renderer.
2101 TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) {
2102 gfx::Rect rect(this->device_viewport_size_);
2104 RenderPassId id(1, 1);
2105 gfx::Transform transform_to_root;
2106 scoped_ptr<RenderPass> pass =
2107 CreateTestRenderPass(id, rect, transform_to_root);
2109 gfx::Transform hole_quad_to_target_transform;
2110 hole_quad_to_target_transform.Translate(50, 50);
2111 hole_quad_to_target_transform.Scale(0.5f + 1.0f / (rect.width() * 2.0f),
2112 0.5f + 1.0f / (rect.height() * 2.0f));
2113 SharedQuadState* hole_shared_state = CreateTestSharedQuadState(
2114 hole_quad_to_target_transform, rect, pass.get());
2116 SolidColorDrawQuad* hole =
2117 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2118 hole->SetAll(
2119 hole_shared_state, rect, rect, rect, false, SK_ColorTRANSPARENT, true);
2121 gfx::Transform green_quad_to_target_transform;
2122 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2123 green_quad_to_target_transform, rect, pass.get());
2125 SolidColorDrawQuad* green =
2126 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2127 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
2129 RenderPassList pass_list;
2130 pass_list.push_back(pass.Pass());
2132 EXPECT_TRUE(this->RunPixelTest(
2133 &pass_list,
2134 base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")),
2135 ExactPixelComparator(false)));
2138 TEST_F(GLRendererPixelTest, AntiAliasingPerspective) {
2139 gfx::Rect rect(this->device_viewport_size_);
2141 scoped_ptr<RenderPass> pass =
2142 CreateTestRootRenderPass(RenderPassId(1, 1), rect);
2144 gfx::Rect red_rect(0, 0, 180, 500);
2145 gfx::Transform red_quad_to_target_transform(
2146 1.0f, 2.4520f, 10.6206f, 19.0f, 0.0f, 0.3528f, 5.9737f, 9.5f, 0.0f,
2147 -0.2250f, -0.9744f, 0.0f, 0.0f, 0.0225f, 0.0974f, 1.0f);
2148 SharedQuadState* red_shared_state = CreateTestSharedQuadState(
2149 red_quad_to_target_transform, red_rect, pass.get());
2150 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2151 red->SetNew(red_shared_state, red_rect, red_rect, SK_ColorRED, false);
2153 gfx::Rect green_rect(19, 7, 180, 10);
2154 SharedQuadState* green_shared_state =
2155 CreateTestSharedQuadState(gfx::Transform(), green_rect, pass.get());
2156 SolidColorDrawQuad* green =
2157 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2158 green->SetNew(
2159 green_shared_state, green_rect, green_rect, SK_ColorGREEN, false);
2161 SharedQuadState* blue_shared_state =
2162 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
2163 SolidColorDrawQuad* blue =
2164 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2165 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2167 RenderPassList pass_list;
2168 pass_list.push_back(pass.Pass());
2170 EXPECT_TRUE(this->RunPixelTest(
2171 &pass_list,
2172 base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")),
2173 FuzzyPixelOffByOneComparator(true)));
2176 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadIdentityScale) {
2177 gfx::Size pile_tile_size(1000, 1000);
2178 gfx::Rect viewport(this->device_viewport_size_);
2179 // TODO(enne): the renderer should figure this out on its own.
2180 ResourceFormat texture_format = RGBA_8888;
2181 bool nearest_neighbor = false;
2183 RenderPassId id(1, 1);
2184 gfx::Transform transform_to_root;
2185 scoped_ptr<RenderPass> pass =
2186 CreateTestRenderPass(id, viewport, transform_to_root);
2188 // One clipped blue quad in the lower right corner. Outside the clip
2189 // is red, which should not appear.
2190 gfx::Rect blue_rect(gfx::Size(100, 100));
2191 gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50));
2193 scoped_ptr<FakePicturePile> blue_recording =
2194 FakePicturePile::CreateFilledPile(pile_tile_size, blue_rect.size());
2195 SkPaint red_paint;
2196 red_paint.setColor(SK_ColorRED);
2197 blue_recording->add_draw_rect_with_paint(blue_rect, red_paint);
2198 SkPaint blue_paint;
2199 blue_paint.setColor(SK_ColorBLUE);
2200 blue_recording->add_draw_rect_with_paint(blue_clip_rect, blue_paint);
2201 blue_recording->Rerecord();
2203 scoped_refptr<FakePicturePileImpl> blue_pile =
2204 FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);
2206 gfx::Transform blue_quad_to_target_transform;
2207 gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right());
2208 blue_quad_to_target_transform.Translate(offset.x(), offset.y());
2209 gfx::RectF blue_scissor_rect = blue_clip_rect;
2210 blue_quad_to_target_transform.TransformRect(&blue_scissor_rect);
2211 SharedQuadState* blue_shared_state = CreateTestSharedQuadStateClipped(
2212 blue_quad_to_target_transform, blue_rect,
2213 gfx::ToEnclosingRect(blue_scissor_rect), pass.get());
2215 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2217 blue_quad->SetNew(blue_shared_state,
2218 viewport, // Intentionally bigger than clip.
2219 gfx::Rect(), viewport, gfx::RectF(viewport),
2220 viewport.size(), nearest_neighbor, texture_format, viewport,
2221 1.f, blue_pile.get());
2223 // One viewport-filling green quad.
2224 scoped_ptr<FakePicturePile> green_recording =
2225 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2226 SkPaint green_paint;
2227 green_paint.setColor(SK_ColorGREEN);
2228 green_recording->add_draw_rect_with_paint(viewport, green_paint);
2229 green_recording->Rerecord();
2230 scoped_refptr<FakePicturePileImpl> green_pile =
2231 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2233 gfx::Transform green_quad_to_target_transform;
2234 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2235 green_quad_to_target_transform, viewport, pass.get());
2237 PictureDrawQuad* green_quad =
2238 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2239 green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
2240 gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(),
2241 nearest_neighbor, texture_format, viewport, 1.f,
2242 green_pile.get());
2244 RenderPassList pass_list;
2245 pass_list.push_back(pass.Pass());
2247 EXPECT_TRUE(this->RunPixelTest(
2248 &pass_list,
2249 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
2250 ExactPixelComparator(true)));
2253 // Not WithSkiaGPUBackend since that path currently requires tiles for opacity.
2254 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadOpacity) {
2255 gfx::Size pile_tile_size(1000, 1000);
2256 gfx::Rect viewport(this->device_viewport_size_);
2257 ResourceFormat texture_format = RGBA_8888;
2258 bool nearest_neighbor = false;
2260 RenderPassId id(1, 1);
2261 gfx::Transform transform_to_root;
2262 scoped_ptr<RenderPass> pass =
2263 CreateTestRenderPass(id, viewport, transform_to_root);
2265 // One viewport-filling 0.5-opacity green quad.
2266 scoped_ptr<FakePicturePile> green_recording =
2267 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2268 SkPaint green_paint;
2269 green_paint.setColor(SK_ColorGREEN);
2270 green_recording->add_draw_rect_with_paint(viewport, green_paint);
2271 green_recording->Rerecord();
2272 scoped_refptr<FakePicturePileImpl> green_pile =
2273 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2275 gfx::Transform green_quad_to_target_transform;
2276 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2277 green_quad_to_target_transform, viewport, pass.get());
2278 green_shared_state->opacity = 0.5f;
2280 PictureDrawQuad* green_quad =
2281 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2282 green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
2283 gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
2284 texture_format, viewport, 1.f, green_pile.get());
2286 // One viewport-filling white quad.
2287 scoped_ptr<FakePicturePile> white_recording =
2288 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2289 SkPaint white_paint;
2290 white_paint.setColor(SK_ColorWHITE);
2291 white_recording->add_draw_rect_with_paint(viewport, white_paint);
2292 white_recording->Rerecord();
2293 scoped_refptr<FakePicturePileImpl> white_pile =
2294 FakePicturePileImpl::CreateFromPile(white_recording.get(), nullptr);
2296 gfx::Transform white_quad_to_target_transform;
2297 SharedQuadState* white_shared_state = CreateTestSharedQuadState(
2298 white_quad_to_target_transform, viewport, pass.get());
2300 PictureDrawQuad* white_quad =
2301 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2302 white_quad->SetNew(white_shared_state, viewport, gfx::Rect(), viewport,
2303 gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
2304 texture_format, viewport, 1.f, white_pile.get());
2306 RenderPassList pass_list;
2307 pass_list.push_back(pass.Pass());
2309 EXPECT_TRUE(this->RunPixelTest(
2310 &pass_list,
2311 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
2312 FuzzyPixelOffByOneComparator(true)));
2315 template<typename TypeParam> bool IsSoftwareRenderer() {
2316 return false;
2319 template<>
2320 bool IsSoftwareRenderer<SoftwareRenderer>() {
2321 return true;
2324 template<>
2325 bool IsSoftwareRenderer<SoftwareRendererWithExpandedViewport>() {
2326 return true;
2329 // If we disable image filtering, then a 2x2 bitmap should appear as four
2330 // huge sharp squares.
2331 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadDisableImageFiltering) {
2332 // We only care about this in software mode since bilinear filtering is
2333 // cheap in hardware.
2334 if (!IsSoftwareRenderer<TypeParam>())
2335 return;
2337 gfx::Size pile_tile_size(1000, 1000);
2338 gfx::Rect viewport(this->device_viewport_size_);
2339 ResourceFormat texture_format = RGBA_8888;
2340 bool nearest_neighbor = false;
2342 RenderPassId id(1, 1);
2343 gfx::Transform transform_to_root;
2344 scoped_ptr<RenderPass> pass =
2345 CreateTestRenderPass(id, viewport, transform_to_root);
2347 SkBitmap bitmap;
2348 bitmap.allocN32Pixels(2, 2);
2350 SkAutoLockPixels lock(bitmap);
2351 SkCanvas canvas(bitmap);
2352 canvas.drawPoint(0, 0, SK_ColorGREEN);
2353 canvas.drawPoint(0, 1, SK_ColorBLUE);
2354 canvas.drawPoint(1, 0, SK_ColorBLUE);
2355 canvas.drawPoint(1, 1, SK_ColorGREEN);
2358 scoped_ptr<FakePicturePile> recording =
2359 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2360 SkPaint paint;
2361 paint.setFilterQuality(kLow_SkFilterQuality);
2362 recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
2363 recording->Rerecord();
2364 scoped_refptr<FakePicturePileImpl> pile =
2365 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2367 gfx::Transform quad_to_target_transform;
2368 SharedQuadState* shared_state =
2369 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2371 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2372 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
2373 gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
2374 texture_format, viewport, 1.f, pile.get());
2376 RenderPassList pass_list;
2377 pass_list.push_back(pass.Pass());
2379 this->disable_picture_quad_image_filtering_ = true;
2381 EXPECT_TRUE(this->RunPixelTest(
2382 &pass_list,
2383 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2384 ExactPixelComparator(true)));
2387 // This disables filtering by setting |nearest_neighbor| on the PictureDrawQuad.
2388 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNearestNeighbor) {
2389 gfx::Size pile_tile_size(1000, 1000);
2390 gfx::Rect viewport(this->device_viewport_size_);
2391 ResourceFormat texture_format = RGBA_8888;
2392 bool nearest_neighbor = true;
2394 RenderPassId id(1, 1);
2395 gfx::Transform transform_to_root;
2396 scoped_ptr<RenderPass> pass =
2397 CreateTestRenderPass(id, viewport, transform_to_root);
2399 SkBitmap bitmap;
2400 bitmap.allocN32Pixels(2, 2);
2402 SkAutoLockPixels lock(bitmap);
2403 SkCanvas canvas(bitmap);
2404 canvas.drawPoint(0, 0, SK_ColorGREEN);
2405 canvas.drawPoint(0, 1, SK_ColorBLUE);
2406 canvas.drawPoint(1, 0, SK_ColorBLUE);
2407 canvas.drawPoint(1, 1, SK_ColorGREEN);
2410 scoped_ptr<FakePicturePile> recording =
2411 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2412 SkPaint paint;
2413 paint.setFilterQuality(kLow_SkFilterQuality);
2414 recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
2415 recording->Rerecord();
2416 scoped_refptr<FakePicturePileImpl> pile =
2417 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2419 gfx::Transform quad_to_target_transform;
2420 SharedQuadState* shared_state =
2421 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2423 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2424 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
2425 gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
2426 texture_format, viewport, 1.f, pile.get());
2428 RenderPassList pass_list;
2429 pass_list.push_back(pass.Pass());
2431 EXPECT_TRUE(this->RunPixelTest(
2432 &pass_list,
2433 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2434 ExactPixelComparator(true)));
2437 // This disables filtering by setting |nearest_neighbor| on the TileDrawQuad.
2438 TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) {
2439 gfx::Rect viewport(this->device_viewport_size_);
2440 bool swizzle_contents = true;
2441 bool nearest_neighbor = true;
2443 SkBitmap bitmap;
2444 bitmap.allocN32Pixels(2, 2);
2446 SkAutoLockPixels lock(bitmap);
2447 SkCanvas canvas(bitmap);
2448 canvas.drawPoint(0, 0, SK_ColorGREEN);
2449 canvas.drawPoint(0, 1, SK_ColorBLUE);
2450 canvas.drawPoint(1, 0, SK_ColorBLUE);
2451 canvas.drawPoint(1, 1, SK_ColorGREEN);
2454 gfx::Size tile_size(2, 2);
2455 ResourceId resource = this->resource_provider_->CreateResource(
2456 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2457 RGBA_8888);
2460 SkAutoLockPixels lock(bitmap);
2461 this->resource_provider_->CopyToResource(
2462 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
2465 RenderPassId id(1, 1);
2466 gfx::Transform transform_to_root;
2467 scoped_ptr<RenderPass> pass =
2468 CreateTestRenderPass(id, viewport, transform_to_root);
2470 gfx::Transform quad_to_target_transform;
2471 SharedQuadState* shared_state =
2472 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2474 TileDrawQuad* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>();
2475 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource,
2476 gfx::Rect(tile_size), tile_size, swizzle_contents,
2477 nearest_neighbor);
2479 RenderPassList pass_list;
2480 pass_list.push_back(pass.Pass());
2482 EXPECT_TRUE(this->RunPixelTest(
2483 &pass_list,
2484 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2485 ExactPixelComparator(true)));
2488 // This disables filtering by setting |nearest_neighbor| to true on the
2489 // TextureDrawQuad.
2490 TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadNearestNeighbor) {
2491 gfx::Rect viewport(this->device_viewport_size_);
2492 bool nearest_neighbor = true;
2494 SkBitmap bitmap;
2495 bitmap.allocN32Pixels(2, 2);
2497 SkAutoLockPixels lock(bitmap);
2498 SkCanvas canvas(bitmap);
2499 canvas.drawPoint(0, 0, SK_ColorGREEN);
2500 canvas.drawPoint(0, 1, SK_ColorBLUE);
2501 canvas.drawPoint(1, 0, SK_ColorBLUE);
2502 canvas.drawPoint(1, 1, SK_ColorGREEN);
2505 gfx::Size tile_size(2, 2);
2506 ResourceId resource = this->resource_provider_->CreateResource(
2507 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2508 RGBA_8888);
2511 SkAutoLockPixels lock(bitmap);
2512 this->resource_provider_->CopyToResource(
2513 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
2516 RenderPassId id(1, 1);
2517 gfx::Transform transform_to_root;
2518 scoped_ptr<RenderPass> pass =
2519 CreateTestRenderPass(id, viewport, transform_to_root);
2521 gfx::Transform quad_to_target_transform;
2522 SharedQuadState* shared_state =
2523 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2525 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2526 TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2527 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource, false,
2528 gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorBLACK,
2529 vertex_opacity, false, nearest_neighbor);
2531 RenderPassList pass_list;
2532 pass_list.push_back(pass.Pass());
2534 EXPECT_TRUE(this->RunPixelTest(
2535 &pass_list,
2536 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2537 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)));
2540 // This ensures filtering is enabled by setting |nearest_neighbor| to false on
2541 // the TextureDrawQuad.
2542 TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadLinear) {
2543 gfx::Rect viewport(this->device_viewport_size_);
2544 bool nearest_neighbor = false;
2546 SkBitmap bitmap;
2547 bitmap.allocN32Pixels(2, 2);
2549 SkAutoLockPixels lock(bitmap);
2550 SkCanvas canvas(bitmap);
2551 canvas.drawPoint(0, 0, SK_ColorGREEN);
2552 canvas.drawPoint(0, 1, SK_ColorBLUE);
2553 canvas.drawPoint(1, 0, SK_ColorBLUE);
2554 canvas.drawPoint(1, 1, SK_ColorGREEN);
2557 gfx::Size tile_size(2, 2);
2558 ResourceId resource = this->resource_provider_->CreateResource(
2559 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2560 RGBA_8888);
2563 SkAutoLockPixels lock(bitmap);
2564 this->resource_provider_->CopyToResource(
2565 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
2568 RenderPassId id(1, 1);
2569 gfx::Transform transform_to_root;
2570 scoped_ptr<RenderPass> pass =
2571 CreateTestRenderPass(id, viewport, transform_to_root);
2573 gfx::Transform quad_to_target_transform;
2574 SharedQuadState* shared_state =
2575 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2577 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2578 TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2579 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource, false,
2580 gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorBLACK,
2581 vertex_opacity, false, nearest_neighbor);
2583 RenderPassList pass_list;
2584 pass_list.push_back(pass.Pass());
2586 // Allow for a small amount of error as the blending alogrithm used by Skia is
2587 // affected by the offset in the expanded rect.
2588 EXPECT_TRUE(this->RunPixelTest(
2589 &pass_list,
2590 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers_linear.png")),
2591 FuzzyPixelComparator(false, 100.f, 0.f, 16.f, 16.f, 0.f)));
2594 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) {
2595 gfx::Size pile_tile_size(1000, 1000);
2596 gfx::Rect viewport(this->device_viewport_size_);
2597 // TODO(enne): the renderer should figure this out on its own.
2598 ResourceFormat texture_format = RGBA_8888;
2599 bool nearest_neighbor = false;
2601 RenderPassId id(1, 1);
2602 gfx::Transform transform_to_root;
2603 scoped_ptr<RenderPass> pass =
2604 CreateTestRenderPass(id, viewport, transform_to_root);
2606 // As scaling up the blue checkerboards will cause sampling on the GPU,
2607 // a few extra "cleanup rects" need to be added to clobber the blending
2608 // to make the output image more clean. This will also test subrects
2609 // of the layer.
2610 gfx::Transform green_quad_to_target_transform;
2611 gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100));
2612 gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20));
2614 scoped_ptr<FakePicturePile> green_recording =
2615 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2617 SkPaint red_paint;
2618 red_paint.setColor(SK_ColorRED);
2619 green_recording->add_draw_rect_with_paint(viewport, red_paint);
2620 SkPaint green_paint;
2621 green_paint.setColor(SK_ColorGREEN);
2622 green_recording->add_draw_rect_with_paint(green_rect1, green_paint);
2623 green_recording->add_draw_rect_with_paint(green_rect2, green_paint);
2624 green_recording->Rerecord();
2625 scoped_refptr<FakePicturePileImpl> green_pile =
2626 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2628 SharedQuadState* top_right_green_shared_quad_state =
2629 CreateTestSharedQuadState(green_quad_to_target_transform, viewport,
2630 pass.get());
2632 PictureDrawQuad* green_quad1 =
2633 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2634 green_quad1->SetNew(top_right_green_shared_quad_state, green_rect1,
2635 gfx::Rect(), green_rect1, gfx::RectF(green_rect1.size()),
2636 green_rect1.size(), nearest_neighbor, texture_format,
2637 green_rect1, 1.f, green_pile.get());
2639 PictureDrawQuad* green_quad2 =
2640 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2641 green_quad2->SetNew(top_right_green_shared_quad_state, green_rect2,
2642 gfx::Rect(), green_rect2, gfx::RectF(green_rect2.size()),
2643 green_rect2.size(), nearest_neighbor, texture_format,
2644 green_rect2, 1.f, green_pile.get());
2646 // Add a green clipped checkerboard in the bottom right to help test
2647 // interleaving picture quad content and solid color content.
2648 gfx::Rect bottom_right_rect(
2649 gfx::Point(viewport.width() / 2, viewport.height() / 2),
2650 gfx::Size(viewport.width() / 2, viewport.height() / 2));
2651 SharedQuadState* bottom_right_green_shared_state =
2652 CreateTestSharedQuadStateClipped(green_quad_to_target_transform, viewport,
2653 bottom_right_rect, pass.get());
2654 SolidColorDrawQuad* bottom_right_color_quad =
2655 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2656 bottom_right_color_quad->SetNew(bottom_right_green_shared_state,
2657 viewport,
2658 viewport,
2659 SK_ColorGREEN,
2660 false);
2662 // Add two blue checkerboards taking up the bottom left and top right,
2663 // but use content scales as content rects to make this happen.
2664 // The content is at a 4x content scale.
2665 gfx::Rect layer_rect(gfx::Size(20, 30));
2666 float contents_scale = 4.f;
2667 // Two rects that touch at their corners, arbitrarily placed in the layer.
2668 gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f));
2669 gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f));
2670 gfx::RectF union_layer_rect = blue_layer_rect1;
2671 union_layer_rect.Union(blue_layer_rect2);
2673 // Because scaling up will cause sampling outside the rects, add one extra
2674 // pixel of buffer at the final content scale.
2675 float inset = -1.f / contents_scale;
2676 blue_layer_rect1.Inset(inset, inset, inset, inset);
2677 blue_layer_rect2.Inset(inset, inset, inset, inset);
2679 scoped_ptr<FakePicturePile> recording =
2680 FakePicturePile::CreateFilledPile(pile_tile_size, layer_rect.size());
2682 Region outside(layer_rect);
2683 outside.Subtract(gfx::ToEnclosingRect(union_layer_rect));
2684 for (Region::Iterator iter(outside); iter.has_rect(); iter.next()) {
2685 recording->add_draw_rect_with_paint(iter.rect(), red_paint);
2688 SkPaint blue_paint;
2689 blue_paint.setColor(SK_ColorBLUE);
2690 recording->add_draw_rect_with_paint(blue_layer_rect1, blue_paint);
2691 recording->add_draw_rect_with_paint(blue_layer_rect2, blue_paint);
2692 recording->Rerecord();
2693 scoped_refptr<FakePicturePileImpl> pile =
2694 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2696 gfx::Rect content_rect(
2697 gfx::ScaleToEnclosingRect(layer_rect, contents_scale));
2698 gfx::Rect content_union_rect(
2699 gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale)));
2701 // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels,
2702 // so scale an additional 10x to make them 100x100.
2703 gfx::Transform quad_to_target_transform;
2704 quad_to_target_transform.Scale(10.0, 10.0);
2705 gfx::Rect quad_content_rect(gfx::Size(20, 20));
2706 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2707 quad_to_target_transform, quad_content_rect, pass.get());
2709 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2710 blue_quad->SetNew(blue_shared_state, quad_content_rect, gfx::Rect(),
2711 quad_content_rect, gfx::RectF(quad_content_rect),
2712 content_union_rect.size(), nearest_neighbor, texture_format,
2713 content_union_rect, contents_scale, pile.get());
2715 // Fill left half of viewport with green.
2716 gfx::Transform half_green_quad_to_target_transform;
2717 gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height()));
2718 SharedQuadState* half_green_shared_state = CreateTestSharedQuadState(
2719 half_green_quad_to_target_transform, half_green_rect, pass.get());
2720 SolidColorDrawQuad* half_color_quad =
2721 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2722 half_color_quad->SetNew(half_green_shared_state,
2723 half_green_rect,
2724 half_green_rect,
2725 SK_ColorGREEN,
2726 false);
2728 RenderPassList pass_list;
2729 pass_list.push_back(pass.Pass());
2731 EXPECT_TRUE(this->RunPixelTest(
2732 &pass_list,
2733 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2734 ExactPixelComparator(true)));
2737 typedef RendererPixelTest<GLRendererWithFlippedSurface>
2738 GLRendererPixelTestWithFlippedOutputSurface;
2740 TEST_F(GLRendererPixelTestWithFlippedOutputSurface, ExplicitFlipTest) {
2741 // This draws a blue rect above a yellow rect with an inverted output surface.
2742 gfx::Rect viewport_rect(this->device_viewport_size_);
2744 RenderPassId root_pass_id(1, 1);
2745 scoped_ptr<RenderPass> root_pass =
2746 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2748 RenderPassId child_pass_id(2, 2);
2749 gfx::Rect pass_rect(this->device_viewport_size_);
2750 gfx::Transform transform_to_root;
2751 scoped_ptr<RenderPass> child_pass =
2752 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2754 gfx::Transform quad_to_target_transform;
2755 SharedQuadState* shared_state = CreateTestSharedQuadState(
2756 quad_to_target_transform, viewport_rect, child_pass.get());
2758 gfx::Rect blue_rect(0,
2760 this->device_viewport_size_.width(),
2761 this->device_viewport_size_.height() / 2);
2762 SolidColorDrawQuad* blue =
2763 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2764 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2765 gfx::Rect yellow_rect(0,
2766 this->device_viewport_size_.height() / 2,
2767 this->device_viewport_size_.width(),
2768 this->device_viewport_size_.height() / 2);
2769 SolidColorDrawQuad* yellow =
2770 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2771 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
2773 SharedQuadState* pass_shared_state =
2774 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2775 CreateTestRenderPassDrawQuad(
2776 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2778 RenderPassList pass_list;
2779 pass_list.push_back(child_pass.Pass());
2780 pass_list.push_back(root_pass.Pass());
2782 EXPECT_TRUE(this->RunPixelTest(
2783 &pass_list,
2784 base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")),
2785 ExactPixelComparator(true)));
2788 TEST_F(GLRendererPixelTestWithFlippedOutputSurface, CheckChildPassUnflipped) {
2789 // This draws a blue rect above a yellow rect with an inverted output surface.
2790 gfx::Rect viewport_rect(this->device_viewport_size_);
2792 RenderPassId root_pass_id(1, 1);
2793 scoped_ptr<RenderPass> root_pass =
2794 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2796 RenderPassId child_pass_id(2, 2);
2797 gfx::Rect pass_rect(this->device_viewport_size_);
2798 gfx::Transform transform_to_root;
2799 scoped_ptr<RenderPass> child_pass =
2800 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2802 gfx::Transform quad_to_target_transform;
2803 SharedQuadState* shared_state = CreateTestSharedQuadState(
2804 quad_to_target_transform, viewport_rect, child_pass.get());
2806 gfx::Rect blue_rect(0,
2808 this->device_viewport_size_.width(),
2809 this->device_viewport_size_.height() / 2);
2810 SolidColorDrawQuad* blue =
2811 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2812 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2813 gfx::Rect yellow_rect(0,
2814 this->device_viewport_size_.height() / 2,
2815 this->device_viewport_size_.width(),
2816 this->device_viewport_size_.height() / 2);
2817 SolidColorDrawQuad* yellow =
2818 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2819 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
2821 SharedQuadState* pass_shared_state =
2822 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2823 CreateTestRenderPassDrawQuad(
2824 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2826 RenderPassList pass_list;
2827 pass_list.push_back(child_pass.Pass());
2828 pass_list.push_back(root_pass.Pass());
2830 // Check that the child pass remains unflipped.
2831 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
2832 &pass_list,
2833 pass_list.front(),
2834 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
2835 ExactPixelComparator(true)));
2838 TEST_F(GLRendererPixelTest, CheckReadbackSubset) {
2839 gfx::Rect viewport_rect(this->device_viewport_size_);
2841 RenderPassId root_pass_id(1, 1);
2842 scoped_ptr<RenderPass> root_pass =
2843 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2845 RenderPassId child_pass_id(2, 2);
2846 gfx::Rect pass_rect(this->device_viewport_size_);
2847 gfx::Transform transform_to_root;
2848 scoped_ptr<RenderPass> child_pass =
2849 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2851 gfx::Transform quad_to_target_transform;
2852 SharedQuadState* shared_state = CreateTestSharedQuadState(
2853 quad_to_target_transform, viewport_rect, child_pass.get());
2855 // Draw a green quad full-size with a blue quad in the lower-right corner.
2856 gfx::Rect blue_rect(this->device_viewport_size_.width() * 3 / 4,
2857 this->device_viewport_size_.height() * 3 / 4,
2858 this->device_viewport_size_.width() * 3 / 4,
2859 this->device_viewport_size_.height() * 3 / 4);
2860 SolidColorDrawQuad* blue =
2861 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2862 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2863 gfx::Rect green_rect(0,
2865 this->device_viewport_size_.width(),
2866 this->device_viewport_size_.height());
2867 SolidColorDrawQuad* green =
2868 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2869 green->SetNew(shared_state, green_rect, green_rect, SK_ColorGREEN, false);
2871 SharedQuadState* pass_shared_state =
2872 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2873 CreateTestRenderPassDrawQuad(
2874 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2876 RenderPassList pass_list;
2877 pass_list.push_back(child_pass.Pass());
2878 pass_list.push_back(root_pass.Pass());
2880 // Check that the child pass remains unflipped.
2881 gfx::Rect capture_rect(this->device_viewport_size_.width() / 2,
2882 this->device_viewport_size_.height() / 2,
2883 this->device_viewport_size_.width() / 2,
2884 this->device_viewport_size_.height() / 2);
2885 EXPECT_TRUE(this->RunPixelTestWithReadbackTargetAndArea(
2886 &pass_list,
2887 pass_list.front(),
2888 base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")),
2889 ExactPixelComparator(true),
2890 &capture_rect));
2893 TYPED_TEST(RendererPixelTest, WrapModeRepeat) {
2894 gfx::Rect rect(this->device_viewport_size_);
2896 RenderPassId id(1, 1);
2897 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2899 SharedQuadState* shared_state =
2900 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
2902 gfx::Size texture_size(4, 4);
2903 SkPMColor colors[4] = {
2904 SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)),
2905 SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)),
2906 SkPreMultiplyColor(SkColorSetARGB(255, 0, 64, 0)),
2907 SkPreMultiplyColor(SkColorSetARGB(255, 0, 0, 0)),
2909 uint32_t pixels[16] = {
2910 colors[0], colors[0], colors[1], colors[1],
2911 colors[0], colors[0], colors[1], colors[1],
2912 colors[2], colors[2], colors[3], colors[3],
2913 colors[2], colors[2], colors[3], colors[3],
2915 ResourceId resource = this->resource_provider_->CreateResource(
2916 texture_size, GL_REPEAT, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2917 RGBA_8888);
2918 this->resource_provider_->CopyToResource(
2919 resource, reinterpret_cast<uint8_t*>(pixels), texture_size);
2921 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2922 TextureDrawQuad* texture_quad =
2923 pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2924 texture_quad->SetNew(
2925 shared_state, gfx::Rect(this->device_viewport_size_), gfx::Rect(),
2926 gfx::Rect(this->device_viewport_size_), resource,
2927 true, // premultiplied_alpha
2928 gfx::PointF(0.0f, 0.0f), // uv_top_left
2929 gfx::PointF( // uv_bottom_right
2930 this->device_viewport_size_.width() / texture_size.width(),
2931 this->device_viewport_size_.height() / texture_size.height()),
2932 SK_ColorWHITE, vertex_opacity,
2933 false, // flipped
2934 false); // nearest_neighbor
2936 RenderPassList pass_list;
2937 pass_list.push_back(pass.Pass());
2939 EXPECT_TRUE(this->RunPixelTest(
2940 &pass_list,
2941 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
2942 FuzzyPixelOffByOneComparator(true)));
2945 TYPED_TEST(RendererPixelTest, Checkerboards) {
2946 gfx::Rect rect(this->device_viewport_size_);
2948 RenderPassId id(1, 1);
2949 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2951 SharedQuadState* shared_state =
2952 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
2954 // The color's alpha value is not used.
2955 SkColor color1 = SK_ColorGREEN;
2956 color1 = SkColorSetA(color1, 0);
2957 SkColor color2 = SK_ColorBLUE;
2958 color2 = SkColorSetA(color2, 0);
2960 gfx::Rect content_rect(rect);
2962 gfx::Rect top_left(content_rect);
2963 gfx::Rect top_right(content_rect);
2964 gfx::Rect bottom_left(content_rect);
2965 gfx::Rect bottom_right(content_rect);
2966 // The format is Inset(left, top, right, bottom).
2967 top_left.Inset(0, 0, content_rect.width() / 2, content_rect.height() / 2);
2968 top_right.Inset(content_rect.width() / 2, 0, 0, content_rect.height() / 2);
2969 bottom_left.Inset(0, content_rect.height() / 2, content_rect.width() / 2, 0);
2970 bottom_right.Inset(content_rect.width() / 2, content_rect.height() / 2, 0, 0);
2972 // Appends checkerboard quads with a scale of 1.
2973 CheckerboardDrawQuad* quad =
2974 pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2975 quad->SetNew(shared_state, top_left, top_left, color1, 1.f);
2976 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2977 quad->SetNew(shared_state, top_right, top_right, color2, 1.f);
2978 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2979 quad->SetNew(shared_state, bottom_left, bottom_left, color2, 1.f);
2980 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2981 quad->SetNew(shared_state, bottom_right, bottom_right, color1, 1.f);
2983 RenderPassList pass_list;
2984 pass_list.push_back(pass.Pass());
2986 base::FilePath::StringType path =
2987 IsSoftwareRenderer<TypeParam>()
2988 ? FILE_PATH_LITERAL("four_blue_green_checkers.png")
2989 : FILE_PATH_LITERAL("checkers.png");
2990 EXPECT_TRUE(this->RunPixelTest(&pass_list, base::FilePath(path),
2991 ExactPixelComparator(true)));
2994 TYPED_TEST(RendererPixelTest, CheckerboardsScaled) {
2995 gfx::Rect rect(this->device_viewport_size_);
2997 RenderPassId id(1, 1);
2998 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
3000 gfx::Transform scale;
3001 scale.Scale(2.f, 2.f);
3003 SharedQuadState* shared_state =
3004 CreateTestSharedQuadState(scale, rect, pass.get());
3006 // The color's alpha value is not used.
3007 SkColor color1 = SK_ColorGREEN;
3008 color1 = SkColorSetA(color1, 0);
3009 SkColor color2 = SK_ColorBLUE;
3010 color2 = SkColorSetA(color2, 0);
3012 gfx::Rect content_rect(rect);
3013 content_rect.Inset(0, 0, rect.width() / 2, rect.height() / 2);
3015 gfx::Rect top_left(content_rect);
3016 gfx::Rect top_right(content_rect);
3017 gfx::Rect bottom_left(content_rect);
3018 gfx::Rect bottom_right(content_rect);
3019 // The format is Inset(left, top, right, bottom).
3020 top_left.Inset(0, 0, content_rect.width() / 2, content_rect.height() / 2);
3021 top_right.Inset(content_rect.width() / 2, 0, 0, content_rect.height() / 2);
3022 bottom_left.Inset(0, content_rect.height() / 2, content_rect.width() / 2, 0);
3023 bottom_right.Inset(content_rect.width() / 2, content_rect.height() / 2, 0, 0);
3025 // Appends checkerboard quads with a scale of 2, and a shared quad state
3026 // with a scale of 2. The checkers should be scaled by 2 * 2 = 4.
3027 CheckerboardDrawQuad* quad =
3028 pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
3029 quad->SetNew(shared_state, top_left, top_left, color1, 2.f);
3030 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
3031 quad->SetNew(shared_state, top_right, top_right, color2, 2.f);
3032 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
3033 quad->SetNew(shared_state, bottom_left, bottom_left, color2, 2.f);
3034 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
3035 quad->SetNew(shared_state, bottom_right, bottom_right, color1, 2.f);
3037 RenderPassList pass_list;
3038 pass_list.push_back(pass.Pass());
3040 base::FilePath::StringType path =
3041 IsSoftwareRenderer<TypeParam>()
3042 ? FILE_PATH_LITERAL("four_blue_green_checkers.png")
3043 : FILE_PATH_LITERAL("checkers_big.png");
3044 EXPECT_TRUE(this->RunPixelTest(&pass_list, base::FilePath(path),
3045 ExactPixelComparator(true)));
3048 #endif // !defined(OS_ANDROID)
3050 } // namespace
3051 } // namespace cc