Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / cc / output / renderer_pixeltest.cc
blob093801af50e1e99e72e825b36813f03d9f2901f0
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::PIXEL_FORMAT_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::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::VideoPixelFormat 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::VideoPixelFormat format,
320 media::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::VideoPixelFormat format,
384 media::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::Rect outer_rect(this->quad_rect_);
753 gfx::Rect 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_, gfx::RectF(this->quad_rect_),
779 this->quad_rect_.size(), false, RGBA_8888, this->quad_rect_,
780 1.f, blue_pile);
782 scoped_ptr<FakePicturePile> green_recording =
783 FakePicturePile::CreateFilledPile(this->quad_rect_.size(),
784 this->quad_rect_.size());
785 green_recording->add_draw_rect_with_paint(outer_rect, green_paint);
786 green_recording->add_draw_rect_with_paint(inner_rect, black_paint);
787 green_recording->Rerecord();
788 scoped_refptr<FakePicturePileImpl> green_pile =
789 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
791 PictureDrawQuad* green_quad =
792 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
793 green_quad->SetNew(this->back_quad_state_, this->quad_rect_, gfx::Rect(),
794 this->quad_rect_, gfx::RectF(this->quad_rect_),
795 this->quad_rect_.size(), false, RGBA_8888,
796 this->quad_rect_, 1.f, green_pile);
797 SCOPED_TRACE("IntersectingPictureQuadsPass");
798 this->template AppendBackgroundAndRunTest<PictureDrawQuad>(
799 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
802 TYPED_TEST(IntersectingQuadPixelTest, RenderPassQuads) {
803 this->SetupQuadStateAndRenderPass();
804 RenderPassId child_pass_id1(2, 2);
805 RenderPassId child_pass_id2(2, 3);
806 scoped_ptr<RenderPass> child_pass1 =
807 CreateTestRenderPass(child_pass_id1, this->quad_rect_, gfx::Transform());
808 SharedQuadState* child1_quad_state = CreateTestSharedQuadState(
809 gfx::Transform(), this->quad_rect_, child_pass1.get());
810 scoped_ptr<RenderPass> child_pass2 =
811 CreateTestRenderPass(child_pass_id2, this->quad_rect_, gfx::Transform());
812 SharedQuadState* child2_quad_state = CreateTestSharedQuadState(
813 gfx::Transform(), this->quad_rect_, child_pass2.get());
815 CreateTestTwoColoredTextureDrawQuad(
816 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
817 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
818 true, child1_quad_state, this->resource_provider_.get(),
819 child_pass1.get());
820 CreateTestTwoColoredTextureDrawQuad(
821 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
822 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
823 true, child2_quad_state, this->resource_provider_.get(),
824 child_pass2.get());
826 CreateTestRenderPassDrawQuad(this->front_quad_state_, this->quad_rect_,
827 child_pass_id1, this->render_pass_.get());
828 CreateTestRenderPassDrawQuad(this->back_quad_state_, this->quad_rect_,
829 child_pass_id2, this->render_pass_.get());
831 this->pass_list_.push_back(child_pass1.Pass());
832 this->pass_list_.push_back(child_pass2.Pass());
833 SCOPED_TRACE("IntersectingRenderQuadsPass");
834 this->template AppendBackgroundAndRunTest<RenderPassDrawQuad>(
835 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
838 TYPED_TEST(IntersectingQuadGLPixelTest, YUVVideoQuads) {
839 this->SetupQuadStateAndRenderPass();
840 gfx::Rect inner_rect(
841 ((this->quad_rect_.x() + (this->quad_rect_.width() / 4)) & ~0xF),
842 ((this->quad_rect_.y() + (this->quad_rect_.height() / 4)) & ~0xF),
843 (this->quad_rect_.width() / 2) & ~0xF,
844 (this->quad_rect_.height() / 2) & ~0xF);
846 CreateTestYUVVideoDrawQuad_TwoColor(
847 this->front_quad_state_, media::PIXEL_FORMAT_YV12,
848 media::COLOR_SPACE_JPEG, false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
849 this->quad_rect_.size(), this->quad_rect_, 0, 128, 128, inner_rect, 29,
850 255, 107, this->render_pass_.get(), this->video_resource_updater_.get(),
851 this->resource_provider_.get());
853 CreateTestYUVVideoDrawQuad_TwoColor(
854 this->back_quad_state_, media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG,
855 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(),
856 this->quad_rect_, 149, 43, 21, inner_rect, 0, 128, 128,
857 this->render_pass_.get(), this->video_resource_updater2_.get(),
858 this->resource_provider_.get());
860 SCOPED_TRACE("IntersectingVideoQuads");
861 this->template AppendBackgroundAndRunTest<YUVVideoDrawQuad>(
862 FuzzyPixelOffByOneComparator(false));
865 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
866 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) {
867 gfx::Rect rect(this->device_viewport_size_);
869 RenderPassId id(1, 1);
870 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
872 SharedQuadState* shared_state =
873 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
875 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
876 SkColorSetARGB(128, 0, 255, 0), // Texel color.
877 SK_ColorTRANSPARENT, // Background color.
878 false, // Premultiplied alpha.
879 shared_state,
880 this->resource_provider_.get(),
881 pass.get());
883 SolidColorDrawQuad* color_quad =
884 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
885 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
887 RenderPassList pass_list;
888 pass_list.push_back(pass.Pass());
890 EXPECT_TRUE(this->RunPixelTest(
891 &pass_list,
892 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
893 FuzzyPixelOffByOneComparator(true)));
896 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
897 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
898 gfx::Rect rect(this->device_viewport_size_);
900 RenderPassId id(1, 1);
901 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
903 SharedQuadState* texture_quad_state =
904 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
905 texture_quad_state->opacity = 0.8f;
907 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
908 SkColorSetARGB(204, 120, 255, 120), // Texel color.
909 SK_ColorGREEN, // Background color.
910 false, // Premultiplied alpha.
911 texture_quad_state,
912 this->resource_provider_.get(),
913 pass.get());
915 SharedQuadState* color_quad_state =
916 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
917 SolidColorDrawQuad* color_quad =
918 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
919 color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
921 RenderPassList pass_list;
922 pass_list.push_back(pass.Pass());
924 EXPECT_TRUE(this->RunPixelTest(
925 &pass_list,
926 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
927 FuzzyPixelOffByOneComparator(true)));
930 class VideoGLRendererPixelTest : public GLRendererPixelTest {
931 protected:
932 void CreateEdgeBleedPass(media::VideoPixelFormat format,
933 media::ColorSpace color_space,
934 RenderPassList* pass_list) {
935 gfx::Rect rect(200, 200);
937 RenderPassId id(1, 1);
938 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
940 // Scale the video up so that bilinear filtering kicks in to sample more
941 // than just nearest neighbor would.
942 gfx::Transform scale_by_2;
943 scale_by_2.Scale(2.f, 2.f);
944 gfx::Rect half_rect(100, 100);
945 SharedQuadState* shared_state =
946 CreateTestSharedQuadState(scale_by_2, half_rect, pass.get());
948 gfx::Size background_size(200, 200);
949 gfx::Rect green_rect(16, 20, 100, 100);
950 gfx::RectF tex_coord_rect(
951 static_cast<float>(green_rect.x()) / background_size.width(),
952 static_cast<float>(green_rect.y()) / background_size.height(),
953 static_cast<float>(green_rect.width()) / background_size.width(),
954 static_cast<float>(green_rect.height()) / background_size.height());
956 // YUV of (149,43,21) should be green (0,255,0) in RGB.
957 // Create a video frame that has a non-green background rect, with a
958 // green sub-rectangle that should be the only thing displayed in
959 // the final image. Bleeding will appear on all four sides of the video
960 // if the tex coords are not clamped.
961 CreateTestYUVVideoDrawQuad_TwoColor(
962 shared_state, format, color_space, false, tex_coord_rect,
963 background_size, gfx::Rect(background_size), 128, 128, 128, green_rect,
964 149, 43, 21, pass.get(), video_resource_updater_.get(),
965 resource_provider_.get());
966 pass_list->push_back(pass.Pass());
969 void SetUp() override {
970 GLRendererPixelTest::SetUp();
971 video_resource_updater_.reset(new VideoResourceUpdater(
972 output_surface_->context_provider(), resource_provider_.get()));
975 scoped_ptr<VideoResourceUpdater> video_resource_updater_;
978 TEST_F(VideoGLRendererPixelTest, SimpleYUVRect) {
979 gfx::Rect rect(this->device_viewport_size_);
981 RenderPassId id(1, 1);
982 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
984 SharedQuadState* shared_state =
985 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
987 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::PIXEL_FORMAT_YV12,
988 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
989 pass.get(), video_resource_updater_.get(),
990 rect, rect, resource_provider_.get());
992 RenderPassList pass_list;
993 pass_list.push_back(pass.Pass());
995 EXPECT_TRUE(
996 this->RunPixelTest(&pass_list,
997 base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
998 FuzzyPixelOffByOneComparator(true)));
1001 TEST_F(VideoGLRendererPixelTest, ClippedYUVRect) {
1002 gfx::Rect viewport(this->device_viewport_size_);
1003 gfx::Rect draw_rect(this->device_viewport_size_.width() * 1.5,
1004 this->device_viewport_size_.height() * 1.5);
1006 RenderPassId id(1, 1);
1007 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, viewport);
1009 SharedQuadState* shared_state =
1010 CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get());
1012 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::PIXEL_FORMAT_YV12,
1013 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1014 pass.get(), video_resource_updater_.get(),
1015 draw_rect, viewport,
1016 resource_provider_.get());
1017 RenderPassList pass_list;
1018 pass_list.push_back(pass.Pass());
1020 EXPECT_TRUE(this->RunPixelTest(
1021 &pass_list, base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png")),
1022 FuzzyPixelOffByOneComparator(true)));
1025 TEST_F(VideoGLRendererPixelTest, OffsetYUVRect) {
1026 gfx::Rect rect(this->device_viewport_size_);
1028 RenderPassId id(1, 1);
1029 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1031 SharedQuadState* shared_state =
1032 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1034 // Intentionally sets frame format to I420 for testing coverage.
1035 CreateTestYUVVideoDrawQuad_Striped(
1036 shared_state, media::PIXEL_FORMAT_I420, false,
1037 gfx::RectF(0.125f, 0.25f, 0.75f, 0.5f), pass.get(),
1038 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1040 RenderPassList pass_list;
1041 pass_list.push_back(pass.Pass());
1043 EXPECT_TRUE(this->RunPixelTest(
1044 &pass_list,
1045 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_offset.png")),
1046 FuzzyPixelOffByOneComparator(true)));
1049 TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) {
1050 gfx::Rect rect(this->device_viewport_size_);
1052 RenderPassId id(1, 1);
1053 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1055 SharedQuadState* shared_state =
1056 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1058 // In MPEG color range YUV values of (15,128,128) should produce black.
1059 CreateTestYUVVideoDrawQuad_Solid(
1060 shared_state, media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_UNSPECIFIED,
1061 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
1062 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1064 RenderPassList pass_list;
1065 pass_list.push_back(pass.Pass());
1067 // If we didn't get black out of the YUV values above, then we probably have a
1068 // color range issue.
1069 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1070 base::FilePath(FILE_PATH_LITERAL("black.png")),
1071 FuzzyPixelOffByOneComparator(true)));
1074 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
1075 gfx::Rect rect(this->device_viewport_size_);
1077 RenderPassId id(1, 1);
1078 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1080 SharedQuadState* shared_state =
1081 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1083 // YUV of (149,43,21) should be green (0,255,0) in RGB.
1084 CreateTestYUVVideoDrawQuad_Solid(
1085 shared_state, media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG, false,
1086 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(),
1087 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1089 RenderPassList pass_list;
1090 pass_list.push_back(pass.Pass());
1092 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1093 base::FilePath(FILE_PATH_LITERAL("green.png")),
1094 FuzzyPixelOffByOneComparator(true)));
1097 // Test that a YUV video doesn't bleed outside of its tex coords when the
1098 // tex coord rect is only a partial subrectangle of the coded contents.
1099 TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) {
1100 RenderPassList pass_list;
1101 CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG,
1102 &pass_list);
1103 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1104 base::FilePath(FILE_PATH_LITERAL("green.png")),
1105 FuzzyPixelOffByOneComparator(true)));
1108 TEST_F(VideoGLRendererPixelTest, YUVAEdgeBleed) {
1109 RenderPassList pass_list;
1110 CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12A, media::COLOR_SPACE_UNSPECIFIED,
1111 &pass_list);
1112 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1113 base::FilePath(FILE_PATH_LITERAL("green.png")),
1114 FuzzyPixelOffByOneComparator(true)));
1117 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
1118 gfx::Rect rect(this->device_viewport_size_);
1120 RenderPassId id(1, 1);
1121 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1123 SharedQuadState* shared_state =
1124 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1126 // Dark grey in JPEG color range (in MPEG, this is black).
1127 CreateTestYUVVideoDrawQuad_Solid(
1128 shared_state, media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG, false,
1129 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
1130 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1132 RenderPassList pass_list;
1133 pass_list.push_back(pass.Pass());
1135 EXPECT_TRUE(
1136 this->RunPixelTest(&pass_list,
1137 base::FilePath(FILE_PATH_LITERAL("dark_grey.png")),
1138 FuzzyPixelOffByOneComparator(true)));
1141 TEST_F(VideoGLRendererPixelTest, SimpleYUVARect) {
1142 gfx::Rect rect(this->device_viewport_size_);
1144 RenderPassId id(1, 1);
1145 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1147 SharedQuadState* shared_state =
1148 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1150 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::PIXEL_FORMAT_YV12A,
1151 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1152 pass.get(), video_resource_updater_.get(),
1153 rect, rect, resource_provider_.get());
1155 SolidColorDrawQuad* color_quad =
1156 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1157 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
1159 RenderPassList pass_list;
1160 pass_list.push_back(pass.Pass());
1162 EXPECT_TRUE(this->RunPixelTest(
1163 &pass_list,
1164 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_alpha.png")),
1165 FuzzyPixelOffByOneComparator(true)));
1168 TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) {
1169 gfx::Rect rect(this->device_viewport_size_);
1171 RenderPassId id(1, 1);
1172 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1174 SharedQuadState* shared_state =
1175 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1177 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::PIXEL_FORMAT_YV12A,
1178 true, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1179 pass.get(), video_resource_updater_.get(),
1180 rect, rect, resource_provider_.get());
1182 SolidColorDrawQuad* color_quad =
1183 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1184 color_quad->SetNew(shared_state, rect, rect, SK_ColorBLACK, false);
1186 RenderPassList pass_list;
1187 pass_list.push_back(pass.Pass());
1189 EXPECT_TRUE(this->RunPixelTest(
1190 &pass_list,
1191 base::FilePath(FILE_PATH_LITERAL("black.png")),
1192 ExactPixelComparator(true)));
1195 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) {
1196 gfx::Rect viewport_rect(this->device_viewport_size_);
1198 RenderPassId root_pass_id(1, 1);
1199 scoped_ptr<RenderPass> root_pass =
1200 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1202 RenderPassId child_pass_id(2, 2);
1203 gfx::Rect pass_rect(this->device_viewport_size_);
1204 gfx::Transform transform_to_root;
1205 scoped_ptr<RenderPass> child_pass =
1206 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1208 gfx::Transform quad_to_target_transform;
1209 SharedQuadState* shared_state = CreateTestSharedQuadState(
1210 quad_to_target_transform, viewport_rect, child_pass.get());
1211 shared_state->opacity = 0.5f;
1213 gfx::Rect blue_rect(0,
1215 this->device_viewport_size_.width(),
1216 this->device_viewport_size_.height() / 2);
1217 SolidColorDrawQuad* blue =
1218 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1219 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1220 gfx::Rect yellow_rect(0,
1221 this->device_viewport_size_.height() / 2,
1222 this->device_viewport_size_.width(),
1223 this->device_viewport_size_.height() / 2);
1224 SolidColorDrawQuad* yellow =
1225 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1226 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1228 SharedQuadState* blank_state = CreateTestSharedQuadState(
1229 quad_to_target_transform, viewport_rect, child_pass.get());
1231 SolidColorDrawQuad* white =
1232 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1233 white->SetNew(
1234 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1236 SharedQuadState* pass_shared_state =
1237 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1239 SkScalar matrix[20];
1240 float amount = 0.5f;
1241 matrix[0] = 0.213f + 0.787f * amount;
1242 matrix[1] = 0.715f - 0.715f * amount;
1243 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1244 matrix[3] = matrix[4] = 0;
1245 matrix[5] = 0.213f - 0.213f * amount;
1246 matrix[6] = 0.715f + 0.285f * amount;
1247 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1248 matrix[8] = matrix[9] = 0;
1249 matrix[10] = 0.213f - 0.213f * amount;
1250 matrix[11] = 0.715f - 0.715f * amount;
1251 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1252 matrix[13] = matrix[14] = 0;
1253 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1254 matrix[18] = 1;
1255 skia::RefPtr<SkColorFilter> colorFilter(
1256 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1257 skia::RefPtr<SkImageFilter> filter =
1258 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
1259 FilterOperations filters;
1260 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1262 RenderPassDrawQuad* render_pass_quad =
1263 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1264 render_pass_quad->SetNew(pass_shared_state,
1265 pass_rect,
1266 pass_rect,
1267 child_pass_id,
1269 gfx::Vector2dF(),
1270 gfx::Size(),
1271 filters,
1272 gfx::Vector2dF(),
1273 FilterOperations());
1275 RenderPassList pass_list;
1276 pass_list.push_back(child_pass.Pass());
1277 pass_list.push_back(root_pass.Pass());
1279 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1280 // renderer so use a fuzzy comparator.
1281 EXPECT_TRUE(this->RunPixelTest(
1282 &pass_list,
1283 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1284 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1287 TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) {
1288 gfx::Rect viewport_rect(this->device_viewport_size_);
1290 RenderPassId root_pass_id(1, 1);
1291 scoped_ptr<RenderPass> root_pass =
1292 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1294 RenderPassId child_pass_id(2, 2);
1295 gfx::Rect pass_rect(this->device_viewport_size_);
1296 gfx::Transform transform_to_root;
1297 scoped_ptr<RenderPass> child_pass =
1298 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1300 gfx::Transform quad_to_target_transform;
1301 SharedQuadState* shared_state = CreateTestSharedQuadState(
1302 quad_to_target_transform, viewport_rect, child_pass.get());
1303 shared_state->opacity = 0.5f;
1305 gfx::Rect blue_rect(0,
1307 this->device_viewport_size_.width(),
1308 this->device_viewport_size_.height() / 2);
1309 SolidColorDrawQuad* blue =
1310 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1311 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1312 gfx::Rect yellow_rect(0,
1313 this->device_viewport_size_.height() / 2,
1314 this->device_viewport_size_.width(),
1315 this->device_viewport_size_.height() / 2);
1316 SolidColorDrawQuad* yellow =
1317 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1318 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1320 SharedQuadState* blank_state = CreateTestSharedQuadState(
1321 quad_to_target_transform, viewport_rect, child_pass.get());
1323 SolidColorDrawQuad* white =
1324 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1325 white->SetNew(
1326 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1328 SharedQuadState* pass_shared_state =
1329 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1331 FilterOperations filters;
1332 filters.Append(FilterOperation::CreateSaturateFilter(0.5f));
1334 RenderPassDrawQuad* render_pass_quad =
1335 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1336 render_pass_quad->SetNew(pass_shared_state,
1337 pass_rect,
1338 pass_rect,
1339 child_pass_id,
1341 gfx::Vector2dF(),
1342 gfx::Size(),
1343 filters,
1344 gfx::Vector2dF(),
1345 FilterOperations());
1347 RenderPassList pass_list;
1348 pass_list.push_back(child_pass.Pass());
1349 pass_list.push_back(root_pass.Pass());
1351 // This test blends slightly differently with the software renderer vs. the gl
1352 // renderer so use a fuzzy comparator.
1353 EXPECT_TRUE(this->RunPixelTest(
1354 &pass_list, base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1355 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1358 TYPED_TEST(RendererPixelTest, FastPassFilterChain) {
1359 gfx::Rect viewport_rect(this->device_viewport_size_);
1361 RenderPassId root_pass_id(1, 1);
1362 scoped_ptr<RenderPass> root_pass =
1363 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1365 RenderPassId child_pass_id(2, 2);
1366 gfx::Rect pass_rect(this->device_viewport_size_);
1367 gfx::Transform transform_to_root;
1368 scoped_ptr<RenderPass> child_pass =
1369 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1371 gfx::Transform quad_to_target_transform;
1372 SharedQuadState* shared_state = CreateTestSharedQuadState(
1373 quad_to_target_transform, viewport_rect, child_pass.get());
1374 shared_state->opacity = 0.5f;
1376 gfx::Rect blue_rect(0,
1378 this->device_viewport_size_.width(),
1379 this->device_viewport_size_.height() / 2);
1380 SolidColorDrawQuad* blue =
1381 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1382 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1383 gfx::Rect yellow_rect(0,
1384 this->device_viewport_size_.height() / 2,
1385 this->device_viewport_size_.width(),
1386 this->device_viewport_size_.height() / 2);
1387 SolidColorDrawQuad* yellow =
1388 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1389 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1391 SharedQuadState* blank_state = CreateTestSharedQuadState(
1392 quad_to_target_transform, viewport_rect, child_pass.get());
1394 SolidColorDrawQuad* white =
1395 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1396 white->SetNew(
1397 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1399 SharedQuadState* pass_shared_state =
1400 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1402 FilterOperations filters;
1403 filters.Append(FilterOperation::CreateGrayscaleFilter(1.f));
1404 filters.Append(FilterOperation::CreateBrightnessFilter(0.5f));
1406 RenderPassDrawQuad* render_pass_quad =
1407 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1408 render_pass_quad->SetNew(pass_shared_state,
1409 pass_rect,
1410 pass_rect,
1411 child_pass_id,
1413 gfx::Vector2dF(),
1414 gfx::Size(),
1415 filters,
1416 gfx::Vector2dF(),
1417 FilterOperations());
1419 RenderPassList pass_list;
1420 pass_list.push_back(child_pass.Pass());
1421 pass_list.push_back(root_pass.Pass());
1423 // This test blends slightly differently with the software renderer vs. the gl
1424 // renderer so use a fuzzy comparator.
1425 EXPECT_TRUE(this->RunPixelTest(
1426 &pass_list,
1427 base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")),
1428 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1431 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) {
1432 gfx::Rect viewport_rect(this->device_viewport_size_);
1434 RenderPassId root_pass_id(1, 1);
1435 scoped_ptr<RenderPass> root_pass =
1436 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1438 RenderPassId child_pass_id(2, 2);
1439 gfx::Rect pass_rect(this->device_viewport_size_);
1440 gfx::Transform transform_to_root;
1441 scoped_ptr<RenderPass> child_pass =
1442 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1444 gfx::Transform quad_to_target_transform;
1445 SharedQuadState* shared_state = CreateTestSharedQuadState(
1446 quad_to_target_transform, viewport_rect, child_pass.get());
1447 shared_state->opacity = 0.5f;
1449 gfx::Rect blue_rect(0,
1451 this->device_viewport_size_.width(),
1452 this->device_viewport_size_.height() / 2);
1453 SolidColorDrawQuad* blue =
1454 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1455 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1456 gfx::Rect yellow_rect(0,
1457 this->device_viewport_size_.height() / 2,
1458 this->device_viewport_size_.width(),
1459 this->device_viewport_size_.height() / 2);
1460 SolidColorDrawQuad* yellow =
1461 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1462 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1464 SharedQuadState* blank_state = CreateTestSharedQuadState(
1465 quad_to_target_transform, viewport_rect, child_pass.get());
1467 SolidColorDrawQuad* white =
1468 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1469 white->SetNew(
1470 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1472 SharedQuadState* pass_shared_state =
1473 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1475 SkScalar matrix[20];
1476 float amount = 0.5f;
1477 matrix[0] = 0.213f + 0.787f * amount;
1478 matrix[1] = 0.715f - 0.715f * amount;
1479 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1480 matrix[3] = 0;
1481 matrix[4] = 20.f;
1482 matrix[5] = 0.213f - 0.213f * amount;
1483 matrix[6] = 0.715f + 0.285f * amount;
1484 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1485 matrix[8] = 0;
1486 matrix[9] = 200.f;
1487 matrix[10] = 0.213f - 0.213f * amount;
1488 matrix[11] = 0.715f - 0.715f * amount;
1489 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1490 matrix[13] = 0;
1491 matrix[14] = 1.5f;
1492 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1493 matrix[18] = 1;
1494 skia::RefPtr<SkColorFilter> colorFilter(
1495 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1496 skia::RefPtr<SkImageFilter> filter =
1497 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
1498 FilterOperations filters;
1499 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1501 RenderPassDrawQuad* render_pass_quad =
1502 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1503 render_pass_quad->SetNew(pass_shared_state,
1504 pass_rect,
1505 pass_rect,
1506 child_pass_id,
1508 gfx::Vector2dF(),
1509 gfx::Size(),
1510 filters,
1511 gfx::Vector2dF(),
1512 FilterOperations());
1514 RenderPassList pass_list;
1516 pass_list.push_back(child_pass.Pass());
1517 pass_list.push_back(root_pass.Pass());
1519 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1520 // renderer so use a fuzzy comparator.
1521 EXPECT_TRUE(this->RunPixelTest(
1522 &pass_list,
1523 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
1524 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1527 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) {
1528 gfx::Rect viewport_rect(this->device_viewport_size_);
1530 RenderPassId root_pass_id(1, 1);
1531 scoped_ptr<RenderPass> root_pass =
1532 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1534 RenderPassId child_pass_id(2, 2);
1535 gfx::Rect pass_rect(this->device_viewport_size_);
1536 gfx::Transform transform_to_root;
1537 scoped_ptr<RenderPass> child_pass =
1538 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1540 gfx::Transform quad_to_target_transform;
1541 SharedQuadState* shared_state = CreateTestSharedQuadState(
1542 quad_to_target_transform, viewport_rect, child_pass.get());
1544 gfx::Rect blue_rect(0,
1546 this->device_viewport_size_.width(),
1547 this->device_viewport_size_.height() / 2);
1548 SolidColorDrawQuad* blue =
1549 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1550 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1551 gfx::Rect yellow_rect(0,
1552 this->device_viewport_size_.height() / 2,
1553 this->device_viewport_size_.width(),
1554 this->device_viewport_size_.height() / 2);
1555 SolidColorDrawQuad* yellow =
1556 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1557 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1559 SharedQuadState* pass_shared_state =
1560 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1561 CreateTestRenderPassDrawQuad(
1562 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1564 RenderPassList pass_list;
1565 pass_list.push_back(child_pass.Pass());
1566 pass_list.push_back(root_pass.Pass());
1568 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1570 EXPECT_TRUE(this->RunPixelTest(
1571 &pass_list,
1572 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
1573 ExactPixelComparator(true)));
1576 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) {
1577 gfx::Rect viewport_rect(this->device_viewport_size_);
1579 RenderPassId root_pass_id(1, 1);
1580 scoped_ptr<RenderPass> root_pass =
1581 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1583 RenderPassId child_pass_id(2, 2);
1584 gfx::Rect pass_rect(this->device_viewport_size_);
1585 gfx::Transform transform_to_root;
1586 scoped_ptr<RenderPass> child_pass =
1587 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1589 gfx::Transform quad_to_target_transform;
1590 SharedQuadState* shared_state = CreateTestSharedQuadState(
1591 quad_to_target_transform, viewport_rect, child_pass.get());
1593 gfx::Rect blue_rect(0,
1595 this->device_viewport_size_.width(),
1596 this->device_viewport_size_.height() / 2);
1597 SolidColorDrawQuad* blue =
1598 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1599 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1600 gfx::Rect yellow_rect(0,
1601 this->device_viewport_size_.height() / 2,
1602 this->device_viewport_size_.width(),
1603 this->device_viewport_size_.height() / 2);
1604 SolidColorDrawQuad* yellow =
1605 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1606 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1608 gfx::Transform aa_transform;
1609 aa_transform.Translate(0.5, 0.0);
1611 SharedQuadState* pass_shared_state =
1612 CreateTestSharedQuadState(aa_transform, pass_rect, root_pass.get());
1613 CreateTestRenderPassDrawQuad(
1614 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1616 SharedQuadState* root_shared_state = CreateTestSharedQuadState(
1617 gfx::Transform(), viewport_rect, root_pass.get());
1618 SolidColorDrawQuad* background =
1619 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1620 background->SetNew(root_shared_state,
1621 gfx::Rect(this->device_viewport_size_),
1622 gfx::Rect(this->device_viewport_size_),
1623 SK_ColorWHITE,
1624 false);
1626 RenderPassList pass_list;
1627 pass_list.push_back(child_pass.Pass());
1628 pass_list.push_back(root_pass.Pass());
1630 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1632 EXPECT_TRUE(this->RunPixelTest(
1633 &pass_list,
1634 base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")),
1635 FuzzyPixelOffByOneComparator(true)));
1638 // This tests the case where we have a RenderPass with a mask, but the quad
1639 // for the masked surface does not include the full surface texture.
1640 TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) {
1641 gfx::Rect viewport_rect(this->device_viewport_size_);
1643 RenderPassId root_pass_id(1, 1);
1644 scoped_ptr<RenderPass> root_pass =
1645 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1646 SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState(
1647 gfx::Transform(), viewport_rect, root_pass.get());
1649 RenderPassId child_pass_id(2, 2);
1650 gfx::Transform transform_to_root;
1651 scoped_ptr<RenderPass> child_pass =
1652 CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root);
1653 SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState(
1654 gfx::Transform(), viewport_rect, child_pass.get());
1656 // The child render pass is just a green box.
1657 static const SkColor kCSSGreen = 0xff008000;
1658 SolidColorDrawQuad* green =
1659 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1660 green->SetNew(
1661 child_pass_shared_state, viewport_rect, viewport_rect, kCSSGreen, false);
1663 // Make a mask.
1664 gfx::Rect mask_rect = viewport_rect;
1665 SkBitmap bitmap;
1666 bitmap.allocPixels(
1667 SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height()));
1668 SkCanvas canvas(bitmap);
1669 SkPaint paint;
1670 paint.setStyle(SkPaint::kStroke_Style);
1671 paint.setStrokeWidth(SkIntToScalar(4));
1672 paint.setColor(SK_ColorWHITE);
1673 canvas.clear(SK_ColorTRANSPARENT);
1674 gfx::Rect rect = mask_rect;
1675 while (!rect.IsEmpty()) {
1676 rect.Inset(6, 6, 4, 4);
1677 canvas.drawRect(
1678 SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()),
1679 paint);
1680 rect.Inset(6, 6, 4, 4);
1683 ResourceId mask_resource_id = this->resource_provider_->CreateResource(
1684 mask_rect.size(), GL_CLAMP_TO_EDGE,
1685 ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
1687 SkAutoLockPixels lock(bitmap);
1688 this->resource_provider_->CopyToResource(
1689 mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
1690 mask_rect.size());
1693 // This RenderPassDrawQuad does not include the full |viewport_rect| which is
1694 // the size of the child render pass.
1695 gfx::Rect sub_rect = gfx::Rect(50, 50, 200, 100);
1696 EXPECT_NE(sub_rect.x(), child_pass->output_rect.x());
1697 EXPECT_NE(sub_rect.y(), child_pass->output_rect.y());
1698 EXPECT_NE(sub_rect.right(), child_pass->output_rect.right());
1699 EXPECT_NE(sub_rect.bottom(), child_pass->output_rect.bottom());
1701 // Set up a mask on the RenderPassDrawQuad.
1702 RenderPassDrawQuad* mask_quad =
1703 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1704 mask_quad->SetNew(root_pass_shared_state,
1705 sub_rect,
1706 sub_rect,
1707 child_pass_id,
1708 mask_resource_id,
1709 gfx::Vector2dF(2.f, 1.f), // mask_uv_scale
1710 gfx::Size(mask_rect.size()), // mask_texture_size
1711 FilterOperations(), // foreground filters
1712 gfx::Vector2dF(), // filters scale
1713 FilterOperations()); // background filters
1715 // White background behind the masked render pass.
1716 SolidColorDrawQuad* white =
1717 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1718 white->SetNew(root_pass_shared_state,
1719 viewport_rect,
1720 viewport_rect,
1721 SK_ColorWHITE,
1722 false);
1724 RenderPassList pass_list;
1725 pass_list.push_back(child_pass.Pass());
1726 pass_list.push_back(root_pass.Pass());
1728 EXPECT_TRUE(this->RunPixelTest(
1729 &pass_list,
1730 base::FilePath(FILE_PATH_LITERAL("mask_bottom_right.png")),
1731 ExactPixelComparator(true)));
1734 template <typename RendererType>
1735 class RendererPixelTestWithBackgroundFilter
1736 : public RendererPixelTest<RendererType> {
1737 protected:
1738 void SetUpRenderPassList() {
1739 gfx::Rect device_viewport_rect(this->device_viewport_size_);
1741 RenderPassId root_id(1, 1);
1742 scoped_ptr<RenderPass> root_pass =
1743 CreateTestRootRenderPass(root_id, device_viewport_rect);
1744 root_pass->has_transparent_background = false;
1746 gfx::Transform identity_quad_to_target_transform;
1748 RenderPassId filter_pass_id(2, 1);
1749 gfx::Transform transform_to_root;
1750 scoped_ptr<RenderPass> filter_pass = CreateTestRenderPass(
1751 filter_pass_id, filter_pass_layer_rect_, transform_to_root);
1753 // A non-visible quad in the filtering render pass.
1755 SharedQuadState* shared_state =
1756 CreateTestSharedQuadState(identity_quad_to_target_transform,
1757 filter_pass_layer_rect_, filter_pass.get());
1758 SolidColorDrawQuad* color_quad =
1759 filter_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1760 color_quad->SetNew(shared_state, filter_pass_layer_rect_,
1761 filter_pass_layer_rect_, SK_ColorTRANSPARENT, false);
1765 SharedQuadState* shared_state =
1766 CreateTestSharedQuadState(filter_pass_to_target_transform_,
1767 filter_pass_layer_rect_, filter_pass.get());
1768 RenderPassDrawQuad* filter_pass_quad =
1769 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1770 filter_pass_quad->SetNew(shared_state, filter_pass_layer_rect_,
1771 filter_pass_layer_rect_, filter_pass_id,
1772 0, // mask_resource_id
1773 gfx::Vector2dF(), // mask_uv_scale
1774 gfx::Size(), // mask_texture_size
1775 FilterOperations(), // filters
1776 gfx::Vector2dF(), // filters_scale
1777 this->background_filters_);
1780 const int kColumnWidth = device_viewport_rect.width() / 3;
1782 gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20);
1783 for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) {
1784 SharedQuadState* shared_state = CreateTestSharedQuadState(
1785 identity_quad_to_target_transform, left_rect, root_pass.get());
1786 SolidColorDrawQuad* color_quad =
1787 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1788 color_quad->SetNew(
1789 shared_state, left_rect, left_rect, SK_ColorGREEN, false);
1790 left_rect += gfx::Vector2d(0, left_rect.height() + 1);
1793 gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20);
1794 for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) {
1795 SharedQuadState* shared_state = CreateTestSharedQuadState(
1796 identity_quad_to_target_transform, middle_rect, root_pass.get());
1797 SolidColorDrawQuad* color_quad =
1798 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1799 color_quad->SetNew(
1800 shared_state, middle_rect, middle_rect, SK_ColorRED, false);
1801 middle_rect += gfx::Vector2d(0, middle_rect.height() + 1);
1804 gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20);
1805 for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) {
1806 SharedQuadState* shared_state = CreateTestSharedQuadState(
1807 identity_quad_to_target_transform, right_rect, root_pass.get());
1808 SolidColorDrawQuad* color_quad =
1809 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1810 color_quad->SetNew(
1811 shared_state, right_rect, right_rect, SK_ColorBLUE, false);
1812 right_rect += gfx::Vector2d(0, right_rect.height() + 1);
1815 SharedQuadState* shared_state =
1816 CreateTestSharedQuadState(identity_quad_to_target_transform,
1817 device_viewport_rect, root_pass.get());
1818 SolidColorDrawQuad* background_quad =
1819 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1820 background_quad->SetNew(shared_state,
1821 device_viewport_rect,
1822 device_viewport_rect,
1823 SK_ColorWHITE,
1824 false);
1826 pass_list_.push_back(filter_pass.Pass());
1827 pass_list_.push_back(root_pass.Pass());
1830 RenderPassList pass_list_;
1831 FilterOperations background_filters_;
1832 gfx::Transform filter_pass_to_target_transform_;
1833 gfx::Rect filter_pass_layer_rect_;
1836 typedef ::testing::Types<GLRenderer, SoftwareRenderer>
1837 BackgroundFilterRendererTypes;
1838 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter,
1839 BackgroundFilterRendererTypes);
1841 typedef RendererPixelTestWithBackgroundFilter<GLRenderer>
1842 GLRendererPixelTestWithBackgroundFilter;
1844 // TODO(skaslev): The software renderer does not support filters yet.
1845 TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) {
1846 this->background_filters_.Append(
1847 FilterOperation::CreateInvertFilter(1.f));
1849 this->filter_pass_layer_rect_ = gfx::Rect(this->device_viewport_size_);
1850 this->filter_pass_layer_rect_.Inset(12, 14, 16, 18);
1852 this->SetUpRenderPassList();
1853 EXPECT_TRUE(this->RunPixelTest(
1854 &this->pass_list_,
1855 base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
1856 ExactPixelComparator(true)));
1859 class ExternalStencilPixelTest : public GLRendererPixelTest {
1860 protected:
1861 void ClearBackgroundToGreen() {
1862 GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
1863 output_surface_->EnsureBackbuffer();
1864 output_surface_->Reshape(device_viewport_size_, 1);
1865 gl->ClearColor(0.f, 1.f, 0.f, 1.f);
1866 gl->Clear(GL_COLOR_BUFFER_BIT);
1869 void PopulateStencilBuffer() {
1870 // Set two quadrants of the stencil buffer to 1.
1871 GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
1872 output_surface_->EnsureBackbuffer();
1873 output_surface_->Reshape(device_viewport_size_, 1);
1874 gl->ClearStencil(0);
1875 gl->Clear(GL_STENCIL_BUFFER_BIT);
1876 gl->Enable(GL_SCISSOR_TEST);
1877 gl->ClearStencil(1);
1878 gl->Scissor(0,
1880 device_viewport_size_.width() / 2,
1881 device_viewport_size_.height() / 2);
1882 gl->Clear(GL_STENCIL_BUFFER_BIT);
1883 gl->Scissor(device_viewport_size_.width() / 2,
1884 device_viewport_size_.height() / 2,
1885 device_viewport_size_.width(),
1886 device_viewport_size_.height());
1887 gl->Clear(GL_STENCIL_BUFFER_BIT);
1891 TEST_F(ExternalStencilPixelTest, StencilTestEnabled) {
1892 ClearBackgroundToGreen();
1893 PopulateStencilBuffer();
1894 this->EnableExternalStencilTest();
1896 // Draw a blue quad that covers the entire device viewport. It should be
1897 // clipped to the bottom left and top right corners by the external stencil.
1898 gfx::Rect rect(this->device_viewport_size_);
1899 RenderPassId id(1, 1);
1900 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1901 SharedQuadState* blue_shared_state =
1902 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1903 SolidColorDrawQuad* blue =
1904 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1905 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1906 pass->has_transparent_background = false;
1907 RenderPassList pass_list;
1908 pass_list.push_back(pass.Pass());
1910 EXPECT_TRUE(this->RunPixelTest(
1911 &pass_list,
1912 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1913 ExactPixelComparator(true)));
1916 TEST_F(ExternalStencilPixelTest, StencilTestDisabled) {
1917 PopulateStencilBuffer();
1919 // Draw a green quad that covers the entire device viewport. The stencil
1920 // buffer should be ignored.
1921 gfx::Rect rect(this->device_viewport_size_);
1922 RenderPassId id(1, 1);
1923 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1924 SharedQuadState* green_shared_state =
1925 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1926 SolidColorDrawQuad* green =
1927 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1928 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
1929 RenderPassList pass_list;
1930 pass_list.push_back(pass.Pass());
1932 EXPECT_TRUE(this->RunPixelTest(
1933 &pass_list,
1934 base::FilePath(FILE_PATH_LITERAL("green.png")),
1935 ExactPixelComparator(true)));
1938 TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) {
1939 // The stencil test should apply only to the final render pass.
1940 ClearBackgroundToGreen();
1941 PopulateStencilBuffer();
1942 this->EnableExternalStencilTest();
1944 gfx::Rect viewport_rect(this->device_viewport_size_);
1946 RenderPassId root_pass_id(1, 1);
1947 scoped_ptr<RenderPass> root_pass =
1948 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1949 root_pass->has_transparent_background = false;
1951 RenderPassId child_pass_id(2, 2);
1952 gfx::Rect pass_rect(this->device_viewport_size_);
1953 gfx::Transform transform_to_root;
1954 scoped_ptr<RenderPass> child_pass =
1955 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1957 gfx::Transform quad_to_target_transform;
1958 SharedQuadState* shared_state = CreateTestSharedQuadState(
1959 quad_to_target_transform, viewport_rect, child_pass.get());
1961 gfx::Rect blue_rect(0,
1963 this->device_viewport_size_.width(),
1964 this->device_viewport_size_.height());
1965 SolidColorDrawQuad* blue =
1966 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1967 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1969 SharedQuadState* pass_shared_state =
1970 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1971 CreateTestRenderPassDrawQuad(
1972 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1973 RenderPassList pass_list;
1974 pass_list.push_back(child_pass.Pass());
1975 pass_list.push_back(root_pass.Pass());
1977 EXPECT_TRUE(this->RunPixelTest(
1978 &pass_list,
1979 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1980 ExactPixelComparator(true)));
1983 TEST_F(ExternalStencilPixelTest, DeviceClip) {
1984 ClearBackgroundToGreen();
1985 gfx::Rect clip_rect(gfx::Point(150, 150), gfx::Size(50, 50));
1986 this->ForceDeviceClip(clip_rect);
1988 // Draw a blue quad that covers the entire device viewport. It should be
1989 // clipped to the bottom right corner by the device clip.
1990 gfx::Rect rect(this->device_viewport_size_);
1991 RenderPassId id(1, 1);
1992 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1993 SharedQuadState* blue_shared_state =
1994 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1995 SolidColorDrawQuad* blue =
1996 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1997 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1998 RenderPassList pass_list;
1999 pass_list.push_back(pass.Pass());
2001 EXPECT_TRUE(this->RunPixelTest(
2002 &pass_list,
2003 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
2004 ExactPixelComparator(true)));
2007 // Software renderer does not support anti-aliased edges.
2008 TEST_F(GLRendererPixelTest, AntiAliasing) {
2009 gfx::Rect rect(this->device_viewport_size_);
2011 RenderPassId id(1, 1);
2012 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2014 gfx::Transform red_quad_to_target_transform;
2015 red_quad_to_target_transform.Rotate(10);
2016 SharedQuadState* red_shared_state =
2017 CreateTestSharedQuadState(red_quad_to_target_transform, rect, pass.get());
2019 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2020 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
2022 gfx::Transform yellow_quad_to_target_transform;
2023 yellow_quad_to_target_transform.Rotate(5);
2024 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
2025 yellow_quad_to_target_transform, rect, pass.get());
2027 SolidColorDrawQuad* yellow =
2028 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2029 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
2031 gfx::Transform blue_quad_to_target_transform;
2032 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2033 blue_quad_to_target_transform, rect, pass.get());
2035 SolidColorDrawQuad* blue =
2036 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2037 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2039 RenderPassList pass_list;
2040 pass_list.push_back(pass.Pass());
2042 EXPECT_TRUE(this->RunPixelTest(
2043 &pass_list,
2044 base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")),
2045 FuzzyPixelOffByOneComparator(true)));
2048 // This test tests that anti-aliasing works for axis aligned quads.
2049 // Anti-aliasing is only supported in the gl renderer.
2050 TEST_F(GLRendererPixelTest, AxisAligned) {
2051 gfx::Rect rect(this->device_viewport_size_);
2053 RenderPassId id(1, 1);
2054 gfx::Transform transform_to_root;
2055 scoped_ptr<RenderPass> pass =
2056 CreateTestRenderPass(id, rect, transform_to_root);
2058 gfx::Transform red_quad_to_target_transform;
2059 red_quad_to_target_transform.Translate(50, 50);
2060 red_quad_to_target_transform.Scale(0.5f + 1.0f / (rect.width() * 2.0f),
2061 0.5f + 1.0f / (rect.height() * 2.0f));
2062 SharedQuadState* red_shared_state =
2063 CreateTestSharedQuadState(red_quad_to_target_transform, rect, pass.get());
2065 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2066 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
2068 gfx::Transform yellow_quad_to_target_transform;
2069 yellow_quad_to_target_transform.Translate(25.5f, 25.5f);
2070 yellow_quad_to_target_transform.Scale(0.5f, 0.5f);
2071 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
2072 yellow_quad_to_target_transform, rect, pass.get());
2074 SolidColorDrawQuad* yellow =
2075 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2076 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
2078 gfx::Transform blue_quad_to_target_transform;
2079 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2080 blue_quad_to_target_transform, rect, pass.get());
2082 SolidColorDrawQuad* blue =
2083 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2084 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2086 RenderPassList pass_list;
2087 pass_list.push_back(pass.Pass());
2089 EXPECT_TRUE(this->RunPixelTest(
2090 &pass_list,
2091 base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")),
2092 ExactPixelComparator(true)));
2095 // This test tests that forcing anti-aliasing off works as expected.
2096 // Anti-aliasing is only supported in the gl renderer.
2097 TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) {
2098 gfx::Rect rect(this->device_viewport_size_);
2100 RenderPassId id(1, 1);
2101 gfx::Transform transform_to_root;
2102 scoped_ptr<RenderPass> pass =
2103 CreateTestRenderPass(id, rect, transform_to_root);
2105 gfx::Transform hole_quad_to_target_transform;
2106 hole_quad_to_target_transform.Translate(50, 50);
2107 hole_quad_to_target_transform.Scale(0.5f + 1.0f / (rect.width() * 2.0f),
2108 0.5f + 1.0f / (rect.height() * 2.0f));
2109 SharedQuadState* hole_shared_state = CreateTestSharedQuadState(
2110 hole_quad_to_target_transform, rect, pass.get());
2112 SolidColorDrawQuad* hole =
2113 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2114 hole->SetAll(
2115 hole_shared_state, rect, rect, rect, false, SK_ColorTRANSPARENT, true);
2117 gfx::Transform green_quad_to_target_transform;
2118 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2119 green_quad_to_target_transform, rect, pass.get());
2121 SolidColorDrawQuad* green =
2122 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2123 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
2125 RenderPassList pass_list;
2126 pass_list.push_back(pass.Pass());
2128 EXPECT_TRUE(this->RunPixelTest(
2129 &pass_list,
2130 base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")),
2131 ExactPixelComparator(false)));
2134 TEST_F(GLRendererPixelTest, AntiAliasingPerspective) {
2135 gfx::Rect rect(this->device_viewport_size_);
2137 scoped_ptr<RenderPass> pass =
2138 CreateTestRootRenderPass(RenderPassId(1, 1), rect);
2140 gfx::Rect red_rect(0, 0, 180, 500);
2141 gfx::Transform red_quad_to_target_transform(
2142 1.0f, 2.4520f, 10.6206f, 19.0f, 0.0f, 0.3528f, 5.9737f, 9.5f, 0.0f,
2143 -0.2250f, -0.9744f, 0.0f, 0.0f, 0.0225f, 0.0974f, 1.0f);
2144 SharedQuadState* red_shared_state = CreateTestSharedQuadState(
2145 red_quad_to_target_transform, red_rect, pass.get());
2146 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2147 red->SetNew(red_shared_state, red_rect, red_rect, SK_ColorRED, false);
2149 gfx::Rect green_rect(19, 7, 180, 10);
2150 SharedQuadState* green_shared_state =
2151 CreateTestSharedQuadState(gfx::Transform(), green_rect, pass.get());
2152 SolidColorDrawQuad* green =
2153 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2154 green->SetNew(
2155 green_shared_state, green_rect, green_rect, SK_ColorGREEN, false);
2157 SharedQuadState* blue_shared_state =
2158 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
2159 SolidColorDrawQuad* blue =
2160 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2161 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2163 RenderPassList pass_list;
2164 pass_list.push_back(pass.Pass());
2166 EXPECT_TRUE(this->RunPixelTest(
2167 &pass_list,
2168 base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")),
2169 FuzzyPixelOffByOneComparator(true)));
2172 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadIdentityScale) {
2173 gfx::Size pile_tile_size(1000, 1000);
2174 gfx::Rect viewport(this->device_viewport_size_);
2175 // TODO(enne): the renderer should figure this out on its own.
2176 ResourceFormat texture_format = RGBA_8888;
2177 bool nearest_neighbor = false;
2179 RenderPassId id(1, 1);
2180 gfx::Transform transform_to_root;
2181 scoped_ptr<RenderPass> pass =
2182 CreateTestRenderPass(id, viewport, transform_to_root);
2184 // One clipped blue quad in the lower right corner. Outside the clip
2185 // is red, which should not appear.
2186 gfx::Rect blue_rect(gfx::Size(100, 100));
2187 gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50));
2189 scoped_ptr<FakePicturePile> blue_recording =
2190 FakePicturePile::CreateFilledPile(pile_tile_size, blue_rect.size());
2191 SkPaint red_paint;
2192 red_paint.setColor(SK_ColorRED);
2193 blue_recording->add_draw_rect_with_paint(blue_rect, red_paint);
2194 SkPaint blue_paint;
2195 blue_paint.setColor(SK_ColorBLUE);
2196 blue_recording->add_draw_rect_with_paint(blue_clip_rect, blue_paint);
2197 blue_recording->Rerecord();
2199 scoped_refptr<FakePicturePileImpl> blue_pile =
2200 FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);
2202 gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right());
2203 gfx::Transform blue_quad_to_target_transform;
2204 blue_quad_to_target_transform.Translate(offset.x(), offset.y());
2205 gfx::Rect blue_target_clip_rect = MathUtil::MapEnclosingClippedRect(
2206 blue_quad_to_target_transform, blue_clip_rect);
2207 SharedQuadState* blue_shared_state =
2208 CreateTestSharedQuadStateClipped(blue_quad_to_target_transform, blue_rect,
2209 blue_target_clip_rect, pass.get());
2211 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2213 blue_quad->SetNew(blue_shared_state,
2214 viewport, // Intentionally bigger than clip.
2215 gfx::Rect(), viewport, gfx::RectF(viewport),
2216 viewport.size(), nearest_neighbor, texture_format, viewport,
2217 1.f, blue_pile.get());
2219 // One viewport-filling green quad.
2220 scoped_ptr<FakePicturePile> green_recording =
2221 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2222 SkPaint green_paint;
2223 green_paint.setColor(SK_ColorGREEN);
2224 green_recording->add_draw_rect_with_paint(viewport, green_paint);
2225 green_recording->Rerecord();
2226 scoped_refptr<FakePicturePileImpl> green_pile =
2227 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2229 gfx::Transform green_quad_to_target_transform;
2230 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2231 green_quad_to_target_transform, viewport, pass.get());
2233 PictureDrawQuad* green_quad =
2234 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2235 green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
2236 gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(),
2237 nearest_neighbor, texture_format, viewport, 1.f,
2238 green_pile.get());
2240 RenderPassList pass_list;
2241 pass_list.push_back(pass.Pass());
2243 EXPECT_TRUE(this->RunPixelTest(
2244 &pass_list,
2245 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
2246 ExactPixelComparator(true)));
2249 // Not WithSkiaGPUBackend since that path currently requires tiles for opacity.
2250 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadOpacity) {
2251 gfx::Size pile_tile_size(1000, 1000);
2252 gfx::Rect viewport(this->device_viewport_size_);
2253 ResourceFormat texture_format = RGBA_8888;
2254 bool nearest_neighbor = false;
2256 RenderPassId id(1, 1);
2257 gfx::Transform transform_to_root;
2258 scoped_ptr<RenderPass> pass =
2259 CreateTestRenderPass(id, viewport, transform_to_root);
2261 // One viewport-filling 0.5-opacity green quad.
2262 scoped_ptr<FakePicturePile> green_recording =
2263 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2264 SkPaint green_paint;
2265 green_paint.setColor(SK_ColorGREEN);
2266 green_recording->add_draw_rect_with_paint(viewport, green_paint);
2267 green_recording->Rerecord();
2268 scoped_refptr<FakePicturePileImpl> green_pile =
2269 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2271 gfx::Transform green_quad_to_target_transform;
2272 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2273 green_quad_to_target_transform, viewport, pass.get());
2274 green_shared_state->opacity = 0.5f;
2276 PictureDrawQuad* green_quad =
2277 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2278 green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
2279 gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
2280 texture_format, viewport, 1.f, green_pile.get());
2282 // One viewport-filling white quad.
2283 scoped_ptr<FakePicturePile> white_recording =
2284 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2285 SkPaint white_paint;
2286 white_paint.setColor(SK_ColorWHITE);
2287 white_recording->add_draw_rect_with_paint(viewport, white_paint);
2288 white_recording->Rerecord();
2289 scoped_refptr<FakePicturePileImpl> white_pile =
2290 FakePicturePileImpl::CreateFromPile(white_recording.get(), nullptr);
2292 gfx::Transform white_quad_to_target_transform;
2293 SharedQuadState* white_shared_state = CreateTestSharedQuadState(
2294 white_quad_to_target_transform, viewport, pass.get());
2296 PictureDrawQuad* white_quad =
2297 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2298 white_quad->SetNew(white_shared_state, viewport, gfx::Rect(), viewport,
2299 gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
2300 texture_format, viewport, 1.f, white_pile.get());
2302 RenderPassList pass_list;
2303 pass_list.push_back(pass.Pass());
2305 EXPECT_TRUE(this->RunPixelTest(
2306 &pass_list,
2307 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
2308 FuzzyPixelOffByOneComparator(true)));
2311 template<typename TypeParam> bool IsSoftwareRenderer() {
2312 return false;
2315 template<>
2316 bool IsSoftwareRenderer<SoftwareRenderer>() {
2317 return true;
2320 template<>
2321 bool IsSoftwareRenderer<SoftwareRendererWithExpandedViewport>() {
2322 return true;
2325 // If we disable image filtering, then a 2x2 bitmap should appear as four
2326 // huge sharp squares.
2327 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadDisableImageFiltering) {
2328 // We only care about this in software mode since bilinear filtering is
2329 // cheap in hardware.
2330 if (!IsSoftwareRenderer<TypeParam>())
2331 return;
2333 gfx::Size pile_tile_size(1000, 1000);
2334 gfx::Rect viewport(this->device_viewport_size_);
2335 ResourceFormat texture_format = RGBA_8888;
2336 bool nearest_neighbor = false;
2338 RenderPassId id(1, 1);
2339 gfx::Transform transform_to_root;
2340 scoped_ptr<RenderPass> pass =
2341 CreateTestRenderPass(id, viewport, transform_to_root);
2343 SkBitmap bitmap;
2344 bitmap.allocN32Pixels(2, 2);
2346 SkAutoLockPixels lock(bitmap);
2347 SkCanvas canvas(bitmap);
2348 canvas.drawPoint(0, 0, SK_ColorGREEN);
2349 canvas.drawPoint(0, 1, SK_ColorBLUE);
2350 canvas.drawPoint(1, 0, SK_ColorBLUE);
2351 canvas.drawPoint(1, 1, SK_ColorGREEN);
2354 scoped_ptr<FakePicturePile> recording =
2355 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2356 SkPaint paint;
2357 paint.setFilterQuality(kLow_SkFilterQuality);
2358 recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
2359 recording->Rerecord();
2360 scoped_refptr<FakePicturePileImpl> pile =
2361 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2363 gfx::Transform quad_to_target_transform;
2364 SharedQuadState* shared_state =
2365 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2367 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2368 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
2369 gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
2370 texture_format, viewport, 1.f, pile.get());
2372 RenderPassList pass_list;
2373 pass_list.push_back(pass.Pass());
2375 this->disable_picture_quad_image_filtering_ = true;
2377 EXPECT_TRUE(this->RunPixelTest(
2378 &pass_list,
2379 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2380 ExactPixelComparator(true)));
2383 // This disables filtering by setting |nearest_neighbor| on the PictureDrawQuad.
2384 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNearestNeighbor) {
2385 gfx::Size pile_tile_size(1000, 1000);
2386 gfx::Rect viewport(this->device_viewport_size_);
2387 ResourceFormat texture_format = RGBA_8888;
2388 bool nearest_neighbor = true;
2390 RenderPassId id(1, 1);
2391 gfx::Transform transform_to_root;
2392 scoped_ptr<RenderPass> pass =
2393 CreateTestRenderPass(id, viewport, transform_to_root);
2395 SkBitmap bitmap;
2396 bitmap.allocN32Pixels(2, 2);
2398 SkAutoLockPixels lock(bitmap);
2399 SkCanvas canvas(bitmap);
2400 canvas.drawPoint(0, 0, SK_ColorGREEN);
2401 canvas.drawPoint(0, 1, SK_ColorBLUE);
2402 canvas.drawPoint(1, 0, SK_ColorBLUE);
2403 canvas.drawPoint(1, 1, SK_ColorGREEN);
2406 scoped_ptr<FakePicturePile> recording =
2407 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2408 SkPaint paint;
2409 paint.setFilterQuality(kLow_SkFilterQuality);
2410 recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
2411 recording->Rerecord();
2412 scoped_refptr<FakePicturePileImpl> pile =
2413 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2415 gfx::Transform quad_to_target_transform;
2416 SharedQuadState* shared_state =
2417 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2419 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2420 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
2421 gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
2422 texture_format, viewport, 1.f, pile.get());
2424 RenderPassList pass_list;
2425 pass_list.push_back(pass.Pass());
2427 EXPECT_TRUE(this->RunPixelTest(
2428 &pass_list,
2429 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2430 ExactPixelComparator(true)));
2433 // This disables filtering by setting |nearest_neighbor| on the TileDrawQuad.
2434 TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) {
2435 gfx::Rect viewport(this->device_viewport_size_);
2436 bool swizzle_contents = true;
2437 bool nearest_neighbor = true;
2439 SkBitmap bitmap;
2440 bitmap.allocN32Pixels(2, 2);
2442 SkAutoLockPixels lock(bitmap);
2443 SkCanvas canvas(bitmap);
2444 canvas.drawPoint(0, 0, SK_ColorGREEN);
2445 canvas.drawPoint(0, 1, SK_ColorBLUE);
2446 canvas.drawPoint(1, 0, SK_ColorBLUE);
2447 canvas.drawPoint(1, 1, SK_ColorGREEN);
2450 gfx::Size tile_size(2, 2);
2451 ResourceId resource = this->resource_provider_->CreateResource(
2452 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2453 RGBA_8888);
2456 SkAutoLockPixels lock(bitmap);
2457 this->resource_provider_->CopyToResource(
2458 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
2461 RenderPassId id(1, 1);
2462 gfx::Transform transform_to_root;
2463 scoped_ptr<RenderPass> pass =
2464 CreateTestRenderPass(id, viewport, transform_to_root);
2466 gfx::Transform quad_to_target_transform;
2467 SharedQuadState* shared_state =
2468 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2470 TileDrawQuad* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>();
2471 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource,
2472 gfx::RectF(gfx::Rect(tile_size)), tile_size, swizzle_contents,
2473 nearest_neighbor);
2475 RenderPassList pass_list;
2476 pass_list.push_back(pass.Pass());
2478 EXPECT_TRUE(this->RunPixelTest(
2479 &pass_list,
2480 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2481 ExactPixelComparator(true)));
2484 // This disables filtering by setting |nearest_neighbor| to true on the
2485 // TextureDrawQuad.
2486 TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadNearestNeighbor) {
2487 gfx::Rect viewport(this->device_viewport_size_);
2488 bool nearest_neighbor = true;
2490 SkBitmap bitmap;
2491 bitmap.allocN32Pixels(2, 2);
2493 SkAutoLockPixels lock(bitmap);
2494 SkCanvas canvas(bitmap);
2495 canvas.drawPoint(0, 0, SK_ColorGREEN);
2496 canvas.drawPoint(0, 1, SK_ColorBLUE);
2497 canvas.drawPoint(1, 0, SK_ColorBLUE);
2498 canvas.drawPoint(1, 1, SK_ColorGREEN);
2501 gfx::Size tile_size(2, 2);
2502 ResourceId resource = this->resource_provider_->CreateResource(
2503 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2504 RGBA_8888);
2507 SkAutoLockPixels lock(bitmap);
2508 this->resource_provider_->CopyToResource(
2509 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
2512 RenderPassId id(1, 1);
2513 gfx::Transform transform_to_root;
2514 scoped_ptr<RenderPass> pass =
2515 CreateTestRenderPass(id, viewport, transform_to_root);
2517 gfx::Transform quad_to_target_transform;
2518 SharedQuadState* shared_state =
2519 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2521 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2522 TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2523 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource, false,
2524 gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorBLACK,
2525 vertex_opacity, false, nearest_neighbor);
2527 RenderPassList pass_list;
2528 pass_list.push_back(pass.Pass());
2530 EXPECT_TRUE(this->RunPixelTest(
2531 &pass_list,
2532 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2533 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)));
2536 // This ensures filtering is enabled by setting |nearest_neighbor| to false on
2537 // the TextureDrawQuad.
2538 TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadLinear) {
2539 gfx::Rect viewport(this->device_viewport_size_);
2540 bool nearest_neighbor = false;
2542 SkBitmap bitmap;
2543 bitmap.allocN32Pixels(2, 2);
2545 SkAutoLockPixels lock(bitmap);
2546 SkCanvas canvas(bitmap);
2547 canvas.drawPoint(0, 0, SK_ColorGREEN);
2548 canvas.drawPoint(0, 1, SK_ColorBLUE);
2549 canvas.drawPoint(1, 0, SK_ColorBLUE);
2550 canvas.drawPoint(1, 1, SK_ColorGREEN);
2553 gfx::Size tile_size(2, 2);
2554 ResourceId resource = this->resource_provider_->CreateResource(
2555 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2556 RGBA_8888);
2559 SkAutoLockPixels lock(bitmap);
2560 this->resource_provider_->CopyToResource(
2561 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
2564 RenderPassId id(1, 1);
2565 gfx::Transform transform_to_root;
2566 scoped_ptr<RenderPass> pass =
2567 CreateTestRenderPass(id, viewport, transform_to_root);
2569 gfx::Transform quad_to_target_transform;
2570 SharedQuadState* shared_state =
2571 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2573 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2574 TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2575 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource, false,
2576 gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorBLACK,
2577 vertex_opacity, false, nearest_neighbor);
2579 RenderPassList pass_list;
2580 pass_list.push_back(pass.Pass());
2582 // Allow for a small amount of error as the blending alogrithm used by Skia is
2583 // affected by the offset in the expanded rect.
2584 EXPECT_TRUE(this->RunPixelTest(
2585 &pass_list,
2586 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers_linear.png")),
2587 FuzzyPixelComparator(false, 100.f, 0.f, 16.f, 16.f, 0.f)));
2590 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) {
2591 gfx::Size pile_tile_size(1000, 1000);
2592 gfx::Rect viewport(this->device_viewport_size_);
2593 // TODO(enne): the renderer should figure this out on its own.
2594 ResourceFormat texture_format = RGBA_8888;
2595 bool nearest_neighbor = false;
2597 RenderPassId id(1, 1);
2598 gfx::Transform transform_to_root;
2599 scoped_ptr<RenderPass> pass =
2600 CreateTestRenderPass(id, viewport, transform_to_root);
2602 // As scaling up the blue checkerboards will cause sampling on the GPU,
2603 // a few extra "cleanup rects" need to be added to clobber the blending
2604 // to make the output image more clean. This will also test subrects
2605 // of the layer.
2606 gfx::Transform green_quad_to_target_transform;
2607 gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100));
2608 gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20));
2610 scoped_ptr<FakePicturePile> green_recording =
2611 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2613 SkPaint red_paint;
2614 red_paint.setColor(SK_ColorRED);
2615 green_recording->add_draw_rect_with_paint(viewport, red_paint);
2616 SkPaint green_paint;
2617 green_paint.setColor(SK_ColorGREEN);
2618 green_recording->add_draw_rect_with_paint(green_rect1, green_paint);
2619 green_recording->add_draw_rect_with_paint(green_rect2, green_paint);
2620 green_recording->Rerecord();
2621 scoped_refptr<FakePicturePileImpl> green_pile =
2622 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2624 SharedQuadState* top_right_green_shared_quad_state =
2625 CreateTestSharedQuadState(green_quad_to_target_transform, viewport,
2626 pass.get());
2628 PictureDrawQuad* green_quad1 =
2629 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2630 green_quad1->SetNew(top_right_green_shared_quad_state, green_rect1,
2631 gfx::Rect(), green_rect1, gfx::RectF(green_rect1.size()),
2632 green_rect1.size(), nearest_neighbor, texture_format,
2633 green_rect1, 1.f, green_pile.get());
2635 PictureDrawQuad* green_quad2 =
2636 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2637 green_quad2->SetNew(top_right_green_shared_quad_state, green_rect2,
2638 gfx::Rect(), green_rect2, gfx::RectF(green_rect2.size()),
2639 green_rect2.size(), nearest_neighbor, texture_format,
2640 green_rect2, 1.f, green_pile.get());
2642 // Add a green clipped checkerboard in the bottom right to help test
2643 // interleaving picture quad content and solid color content.
2644 gfx::Rect bottom_right_rect(
2645 gfx::Point(viewport.width() / 2, viewport.height() / 2),
2646 gfx::Size(viewport.width() / 2, viewport.height() / 2));
2647 SharedQuadState* bottom_right_green_shared_state =
2648 CreateTestSharedQuadStateClipped(green_quad_to_target_transform, viewport,
2649 bottom_right_rect, pass.get());
2650 SolidColorDrawQuad* bottom_right_color_quad =
2651 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2652 bottom_right_color_quad->SetNew(bottom_right_green_shared_state,
2653 viewport,
2654 viewport,
2655 SK_ColorGREEN,
2656 false);
2658 // Add two blue checkerboards taking up the bottom left and top right,
2659 // but use content scales as content rects to make this happen.
2660 // The content is at a 4x content scale.
2661 gfx::Rect layer_rect(gfx::Size(20, 30));
2662 float contents_scale = 4.f;
2663 // Two rects that touch at their corners, arbitrarily placed in the layer.
2664 gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f));
2665 gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f));
2666 gfx::RectF union_layer_rect = blue_layer_rect1;
2667 union_layer_rect.Union(blue_layer_rect2);
2669 // Because scaling up will cause sampling outside the rects, add one extra
2670 // pixel of buffer at the final content scale.
2671 float inset = -1.f / contents_scale;
2672 blue_layer_rect1.Inset(inset, inset, inset, inset);
2673 blue_layer_rect2.Inset(inset, inset, inset, inset);
2675 scoped_ptr<FakePicturePile> recording =
2676 FakePicturePile::CreateFilledPile(pile_tile_size, layer_rect.size());
2678 Region outside(layer_rect);
2679 outside.Subtract(gfx::ToEnclosingRect(union_layer_rect));
2680 for (Region::Iterator iter(outside); iter.has_rect(); iter.next()) {
2681 recording->add_draw_rect_with_paint(iter.rect(), red_paint);
2684 SkPaint blue_paint;
2685 blue_paint.setColor(SK_ColorBLUE);
2686 recording->add_draw_rectf_with_paint(blue_layer_rect1, blue_paint);
2687 recording->add_draw_rectf_with_paint(blue_layer_rect2, blue_paint);
2688 recording->Rerecord();
2689 scoped_refptr<FakePicturePileImpl> pile =
2690 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2692 gfx::Rect content_rect(
2693 gfx::ScaleToEnclosingRect(layer_rect, contents_scale));
2694 gfx::Rect content_union_rect(
2695 gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale)));
2697 // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels,
2698 // so scale an additional 10x to make them 100x100.
2699 gfx::Transform quad_to_target_transform;
2700 quad_to_target_transform.Scale(10.0, 10.0);
2701 gfx::Rect quad_content_rect(gfx::Size(20, 20));
2702 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2703 quad_to_target_transform, quad_content_rect, pass.get());
2705 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2706 blue_quad->SetNew(blue_shared_state, quad_content_rect, gfx::Rect(),
2707 quad_content_rect, gfx::RectF(quad_content_rect),
2708 content_union_rect.size(), nearest_neighbor, texture_format,
2709 content_union_rect, contents_scale, pile.get());
2711 // Fill left half of viewport with green.
2712 gfx::Transform half_green_quad_to_target_transform;
2713 gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height()));
2714 SharedQuadState* half_green_shared_state = CreateTestSharedQuadState(
2715 half_green_quad_to_target_transform, half_green_rect, pass.get());
2716 SolidColorDrawQuad* half_color_quad =
2717 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2718 half_color_quad->SetNew(half_green_shared_state,
2719 half_green_rect,
2720 half_green_rect,
2721 SK_ColorGREEN,
2722 false);
2724 RenderPassList pass_list;
2725 pass_list.push_back(pass.Pass());
2727 EXPECT_TRUE(this->RunPixelTest(
2728 &pass_list,
2729 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2730 ExactPixelComparator(true)));
2733 typedef RendererPixelTest<GLRendererWithFlippedSurface>
2734 GLRendererPixelTestWithFlippedOutputSurface;
2736 TEST_F(GLRendererPixelTestWithFlippedOutputSurface, ExplicitFlipTest) {
2737 // This draws a blue rect above a yellow rect with an inverted output surface.
2738 gfx::Rect viewport_rect(this->device_viewport_size_);
2740 RenderPassId root_pass_id(1, 1);
2741 scoped_ptr<RenderPass> root_pass =
2742 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2744 RenderPassId child_pass_id(2, 2);
2745 gfx::Rect pass_rect(this->device_viewport_size_);
2746 gfx::Transform transform_to_root;
2747 scoped_ptr<RenderPass> child_pass =
2748 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2750 gfx::Transform quad_to_target_transform;
2751 SharedQuadState* shared_state = CreateTestSharedQuadState(
2752 quad_to_target_transform, viewport_rect, child_pass.get());
2754 gfx::Rect blue_rect(0,
2756 this->device_viewport_size_.width(),
2757 this->device_viewport_size_.height() / 2);
2758 SolidColorDrawQuad* blue =
2759 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2760 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2761 gfx::Rect yellow_rect(0,
2762 this->device_viewport_size_.height() / 2,
2763 this->device_viewport_size_.width(),
2764 this->device_viewport_size_.height() / 2);
2765 SolidColorDrawQuad* yellow =
2766 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2767 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
2769 SharedQuadState* pass_shared_state =
2770 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2771 CreateTestRenderPassDrawQuad(
2772 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2774 RenderPassList pass_list;
2775 pass_list.push_back(child_pass.Pass());
2776 pass_list.push_back(root_pass.Pass());
2778 EXPECT_TRUE(this->RunPixelTest(
2779 &pass_list,
2780 base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")),
2781 ExactPixelComparator(true)));
2784 TEST_F(GLRendererPixelTestWithFlippedOutputSurface, CheckChildPassUnflipped) {
2785 // This draws a blue rect above a yellow rect with an inverted output surface.
2786 gfx::Rect viewport_rect(this->device_viewport_size_);
2788 RenderPassId root_pass_id(1, 1);
2789 scoped_ptr<RenderPass> root_pass =
2790 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2792 RenderPassId child_pass_id(2, 2);
2793 gfx::Rect pass_rect(this->device_viewport_size_);
2794 gfx::Transform transform_to_root;
2795 scoped_ptr<RenderPass> child_pass =
2796 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2798 gfx::Transform quad_to_target_transform;
2799 SharedQuadState* shared_state = CreateTestSharedQuadState(
2800 quad_to_target_transform, viewport_rect, child_pass.get());
2802 gfx::Rect blue_rect(0,
2804 this->device_viewport_size_.width(),
2805 this->device_viewport_size_.height() / 2);
2806 SolidColorDrawQuad* blue =
2807 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2808 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2809 gfx::Rect yellow_rect(0,
2810 this->device_viewport_size_.height() / 2,
2811 this->device_viewport_size_.width(),
2812 this->device_viewport_size_.height() / 2);
2813 SolidColorDrawQuad* yellow =
2814 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2815 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
2817 SharedQuadState* pass_shared_state =
2818 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2819 CreateTestRenderPassDrawQuad(
2820 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2822 RenderPassList pass_list;
2823 pass_list.push_back(child_pass.Pass());
2824 pass_list.push_back(root_pass.Pass());
2826 // Check that the child pass remains unflipped.
2827 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
2828 &pass_list,
2829 pass_list.front(),
2830 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
2831 ExactPixelComparator(true)));
2834 TEST_F(GLRendererPixelTest, CheckReadbackSubset) {
2835 gfx::Rect viewport_rect(this->device_viewport_size_);
2837 RenderPassId root_pass_id(1, 1);
2838 scoped_ptr<RenderPass> root_pass =
2839 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2841 RenderPassId child_pass_id(2, 2);
2842 gfx::Rect pass_rect(this->device_viewport_size_);
2843 gfx::Transform transform_to_root;
2844 scoped_ptr<RenderPass> child_pass =
2845 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2847 gfx::Transform quad_to_target_transform;
2848 SharedQuadState* shared_state = CreateTestSharedQuadState(
2849 quad_to_target_transform, viewport_rect, child_pass.get());
2851 // Draw a green quad full-size with a blue quad in the lower-right corner.
2852 gfx::Rect blue_rect(this->device_viewport_size_.width() * 3 / 4,
2853 this->device_viewport_size_.height() * 3 / 4,
2854 this->device_viewport_size_.width() * 3 / 4,
2855 this->device_viewport_size_.height() * 3 / 4);
2856 SolidColorDrawQuad* blue =
2857 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2858 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2859 gfx::Rect green_rect(0,
2861 this->device_viewport_size_.width(),
2862 this->device_viewport_size_.height());
2863 SolidColorDrawQuad* green =
2864 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2865 green->SetNew(shared_state, green_rect, green_rect, SK_ColorGREEN, false);
2867 SharedQuadState* pass_shared_state =
2868 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2869 CreateTestRenderPassDrawQuad(
2870 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2872 RenderPassList pass_list;
2873 pass_list.push_back(child_pass.Pass());
2874 pass_list.push_back(root_pass.Pass());
2876 // Check that the child pass remains unflipped.
2877 gfx::Rect capture_rect(this->device_viewport_size_.width() / 2,
2878 this->device_viewport_size_.height() / 2,
2879 this->device_viewport_size_.width() / 2,
2880 this->device_viewport_size_.height() / 2);
2881 EXPECT_TRUE(this->RunPixelTestWithReadbackTargetAndArea(
2882 &pass_list,
2883 pass_list.front(),
2884 base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")),
2885 ExactPixelComparator(true),
2886 &capture_rect));
2889 TYPED_TEST(RendererPixelTest, WrapModeRepeat) {
2890 gfx::Rect rect(this->device_viewport_size_);
2892 RenderPassId id(1, 1);
2893 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2895 SharedQuadState* shared_state =
2896 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
2898 gfx::Size texture_size(4, 4);
2899 SkPMColor colors[4] = {
2900 SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)),
2901 SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)),
2902 SkPreMultiplyColor(SkColorSetARGB(255, 0, 64, 0)),
2903 SkPreMultiplyColor(SkColorSetARGB(255, 0, 0, 0)),
2905 uint32_t pixels[16] = {
2906 colors[0], colors[0], colors[1], colors[1],
2907 colors[0], colors[0], colors[1], colors[1],
2908 colors[2], colors[2], colors[3], colors[3],
2909 colors[2], colors[2], colors[3], colors[3],
2911 ResourceId resource = this->resource_provider_->CreateResource(
2912 texture_size, GL_REPEAT, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2913 RGBA_8888);
2914 this->resource_provider_->CopyToResource(
2915 resource, reinterpret_cast<uint8_t*>(pixels), texture_size);
2917 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2918 TextureDrawQuad* texture_quad =
2919 pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2920 texture_quad->SetNew(
2921 shared_state, gfx::Rect(this->device_viewport_size_), gfx::Rect(),
2922 gfx::Rect(this->device_viewport_size_), resource,
2923 true, // premultiplied_alpha
2924 gfx::PointF(0.0f, 0.0f), // uv_top_left
2925 gfx::PointF( // uv_bottom_right
2926 this->device_viewport_size_.width() / texture_size.width(),
2927 this->device_viewport_size_.height() / texture_size.height()),
2928 SK_ColorWHITE, vertex_opacity,
2929 false, // flipped
2930 false); // nearest_neighbor
2932 RenderPassList pass_list;
2933 pass_list.push_back(pass.Pass());
2935 EXPECT_TRUE(this->RunPixelTest(
2936 &pass_list,
2937 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
2938 FuzzyPixelOffByOneComparator(true)));
2941 #endif // !defined(OS_ANDROID)
2943 } // namespace
2944 } // namespace cc