Add ICU message format support
[chromium-blink-merge.git] / cc / output / renderer_pixeltest.cc
blob608e3a5744c1e84b56fdd87cea952e9865b0227f
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::RectF outer_rect(this->quad_rect_);
753 gfx::RectF inner_rect(this->quad_rect_.x() + (this->quad_rect_.width() / 4),
754 this->quad_rect_.y() + (this->quad_rect_.height() / 4),
755 this->quad_rect_.width() / 2,
756 this->quad_rect_.height() / 2);
758 SkPaint black_paint;
759 black_paint.setColor(SK_ColorBLACK);
760 SkPaint blue_paint;
761 blue_paint.setColor(SK_ColorBLUE);
762 SkPaint green_paint;
763 green_paint.setColor(SK_ColorGREEN);
765 scoped_ptr<FakePicturePile> blue_recording =
766 FakePicturePile::CreateFilledPile(gfx::Size(1000, 1000),
767 this->quad_rect_.size());
768 blue_recording->add_draw_rect_with_paint(outer_rect, black_paint);
769 blue_recording->add_draw_rect_with_paint(inner_rect, blue_paint);
770 blue_recording->Rerecord();
771 scoped_refptr<FakePicturePileImpl> blue_pile =
772 FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);
774 PictureDrawQuad* blue_quad =
775 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
777 blue_quad->SetNew(this->front_quad_state_, this->quad_rect_, gfx::Rect(),
778 this->quad_rect_, this->quad_rect_, this->quad_rect_.size(),
779 false, RGBA_8888, this->quad_rect_, 1.f, blue_pile);
781 scoped_ptr<FakePicturePile> green_recording =
782 FakePicturePile::CreateFilledPile(this->quad_rect_.size(),
783 this->quad_rect_.size());
784 green_recording->add_draw_rect_with_paint(outer_rect, green_paint);
785 green_recording->add_draw_rect_with_paint(inner_rect, black_paint);
786 green_recording->Rerecord();
787 scoped_refptr<FakePicturePileImpl> green_pile =
788 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
790 PictureDrawQuad* green_quad =
791 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
792 green_quad->SetNew(this->back_quad_state_, this->quad_rect_, gfx::Rect(),
793 this->quad_rect_, this->quad_rect_,
794 this->quad_rect_.size(), false, RGBA_8888,
795 this->quad_rect_, 1.f, green_pile);
796 SCOPED_TRACE("IntersectingPictureQuadsPass");
797 this->template AppendBackgroundAndRunTest<PictureDrawQuad>(
798 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
801 TYPED_TEST(IntersectingQuadPixelTest, RenderPassQuads) {
802 this->SetupQuadStateAndRenderPass();
803 RenderPassId child_pass_id1(2, 2);
804 RenderPassId child_pass_id2(2, 3);
805 scoped_ptr<RenderPass> child_pass1 =
806 CreateTestRenderPass(child_pass_id1, this->quad_rect_, gfx::Transform());
807 SharedQuadState* child1_quad_state = CreateTestSharedQuadState(
808 gfx::Transform(), this->quad_rect_, child_pass1.get());
809 scoped_ptr<RenderPass> child_pass2 =
810 CreateTestRenderPass(child_pass_id2, this->quad_rect_, gfx::Transform());
811 SharedQuadState* child2_quad_state = CreateTestSharedQuadState(
812 gfx::Transform(), this->quad_rect_, child_pass2.get());
814 CreateTestTwoColoredTextureDrawQuad(
815 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
816 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
817 true, child1_quad_state, this->resource_provider_.get(),
818 child_pass1.get());
819 CreateTestTwoColoredTextureDrawQuad(
820 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
821 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
822 true, child2_quad_state, this->resource_provider_.get(),
823 child_pass2.get());
825 CreateTestRenderPassDrawQuad(this->front_quad_state_, this->quad_rect_,
826 child_pass_id1, this->render_pass_.get());
827 CreateTestRenderPassDrawQuad(this->back_quad_state_, this->quad_rect_,
828 child_pass_id2, this->render_pass_.get());
830 this->pass_list_.push_back(child_pass1.Pass());
831 this->pass_list_.push_back(child_pass2.Pass());
832 SCOPED_TRACE("IntersectingRenderQuadsPass");
833 this->template AppendBackgroundAndRunTest<RenderPassDrawQuad>(
834 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
837 TYPED_TEST(IntersectingQuadGLPixelTest, YUVVideoQuads) {
838 this->SetupQuadStateAndRenderPass();
839 gfx::Rect inner_rect(
840 ((this->quad_rect_.x() + (this->quad_rect_.width() / 4)) & ~0xF),
841 ((this->quad_rect_.y() + (this->quad_rect_.height() / 4)) & ~0xF),
842 (this->quad_rect_.width() / 2) & ~0xF,
843 (this->quad_rect_.height() / 2) & ~0xF);
845 CreateTestYUVVideoDrawQuad_TwoColor(
846 this->front_quad_state_, media::PIXEL_FORMAT_YV12,
847 media::COLOR_SPACE_JPEG, false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
848 this->quad_rect_.size(), this->quad_rect_, 0, 128, 128, inner_rect, 29,
849 255, 107, this->render_pass_.get(), this->video_resource_updater_.get(),
850 this->resource_provider_.get());
852 CreateTestYUVVideoDrawQuad_TwoColor(
853 this->back_quad_state_, media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG,
854 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(),
855 this->quad_rect_, 149, 43, 21, inner_rect, 0, 128, 128,
856 this->render_pass_.get(), this->video_resource_updater2_.get(),
857 this->resource_provider_.get());
859 SCOPED_TRACE("IntersectingVideoQuads");
860 this->template AppendBackgroundAndRunTest<YUVVideoDrawQuad>(
861 FuzzyPixelOffByOneComparator(false));
864 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
865 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) {
866 gfx::Rect rect(this->device_viewport_size_);
868 RenderPassId id(1, 1);
869 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
871 SharedQuadState* shared_state =
872 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
874 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
875 SkColorSetARGB(128, 0, 255, 0), // Texel color.
876 SK_ColorTRANSPARENT, // Background color.
877 false, // Premultiplied alpha.
878 shared_state,
879 this->resource_provider_.get(),
880 pass.get());
882 SolidColorDrawQuad* color_quad =
883 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
884 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
886 RenderPassList pass_list;
887 pass_list.push_back(pass.Pass());
889 EXPECT_TRUE(this->RunPixelTest(
890 &pass_list,
891 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
892 FuzzyPixelOffByOneComparator(true)));
895 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
896 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
897 gfx::Rect rect(this->device_viewport_size_);
899 RenderPassId id(1, 1);
900 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
902 SharedQuadState* texture_quad_state =
903 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
904 texture_quad_state->opacity = 0.8f;
906 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
907 SkColorSetARGB(204, 120, 255, 120), // Texel color.
908 SK_ColorGREEN, // Background color.
909 false, // Premultiplied alpha.
910 texture_quad_state,
911 this->resource_provider_.get(),
912 pass.get());
914 SharedQuadState* color_quad_state =
915 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
916 SolidColorDrawQuad* color_quad =
917 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
918 color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
920 RenderPassList pass_list;
921 pass_list.push_back(pass.Pass());
923 EXPECT_TRUE(this->RunPixelTest(
924 &pass_list,
925 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
926 FuzzyPixelOffByOneComparator(true)));
929 class VideoGLRendererPixelTest : public GLRendererPixelTest {
930 protected:
931 void CreateEdgeBleedPass(media::VideoPixelFormat format,
932 media::ColorSpace color_space,
933 RenderPassList* pass_list) {
934 gfx::Rect rect(200, 200);
936 RenderPassId id(1, 1);
937 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
939 // Scale the video up so that bilinear filtering kicks in to sample more
940 // than just nearest neighbor would.
941 gfx::Transform scale_by_2;
942 scale_by_2.Scale(2.f, 2.f);
943 gfx::Rect half_rect(100, 100);
944 SharedQuadState* shared_state =
945 CreateTestSharedQuadState(scale_by_2, half_rect, pass.get());
947 gfx::Size background_size(200, 200);
948 gfx::Rect green_rect(16, 20, 100, 100);
949 gfx::RectF tex_coord_rect(
950 static_cast<float>(green_rect.x()) / background_size.width(),
951 static_cast<float>(green_rect.y()) / background_size.height(),
952 static_cast<float>(green_rect.width()) / background_size.width(),
953 static_cast<float>(green_rect.height()) / background_size.height());
955 // YUV of (149,43,21) should be green (0,255,0) in RGB.
956 // Create a video frame that has a non-green background rect, with a
957 // green sub-rectangle that should be the only thing displayed in
958 // the final image. Bleeding will appear on all four sides of the video
959 // if the tex coords are not clamped.
960 CreateTestYUVVideoDrawQuad_TwoColor(
961 shared_state, format, color_space, false, tex_coord_rect,
962 background_size, gfx::Rect(background_size), 128, 128, 128, green_rect,
963 149, 43, 21, pass.get(), video_resource_updater_.get(),
964 resource_provider_.get());
965 pass_list->push_back(pass.Pass());
968 void SetUp() override {
969 GLRendererPixelTest::SetUp();
970 video_resource_updater_.reset(new VideoResourceUpdater(
971 output_surface_->context_provider(), resource_provider_.get()));
974 scoped_ptr<VideoResourceUpdater> video_resource_updater_;
977 TEST_F(VideoGLRendererPixelTest, SimpleYUVRect) {
978 gfx::Rect rect(this->device_viewport_size_);
980 RenderPassId id(1, 1);
981 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
983 SharedQuadState* shared_state =
984 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
986 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::PIXEL_FORMAT_YV12,
987 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
988 pass.get(), video_resource_updater_.get(),
989 rect, rect, resource_provider_.get());
991 RenderPassList pass_list;
992 pass_list.push_back(pass.Pass());
994 EXPECT_TRUE(
995 this->RunPixelTest(&pass_list,
996 base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
997 FuzzyPixelOffByOneComparator(true)));
1000 TEST_F(VideoGLRendererPixelTest, ClippedYUVRect) {
1001 gfx::Rect viewport(this->device_viewport_size_);
1002 gfx::Rect draw_rect(this->device_viewport_size_.width() * 1.5,
1003 this->device_viewport_size_.height() * 1.5);
1005 RenderPassId id(1, 1);
1006 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, viewport);
1008 SharedQuadState* shared_state =
1009 CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get());
1011 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::PIXEL_FORMAT_YV12,
1012 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1013 pass.get(), video_resource_updater_.get(),
1014 draw_rect, viewport,
1015 resource_provider_.get());
1016 RenderPassList pass_list;
1017 pass_list.push_back(pass.Pass());
1019 EXPECT_TRUE(this->RunPixelTest(
1020 &pass_list, base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png")),
1021 FuzzyPixelOffByOneComparator(true)));
1024 TEST_F(VideoGLRendererPixelTest, OffsetYUVRect) {
1025 gfx::Rect rect(this->device_viewport_size_);
1027 RenderPassId id(1, 1);
1028 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1030 SharedQuadState* shared_state =
1031 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1033 // Intentionally sets frame format to I420 for testing coverage.
1034 CreateTestYUVVideoDrawQuad_Striped(
1035 shared_state, media::PIXEL_FORMAT_I420, false,
1036 gfx::RectF(0.125f, 0.25f, 0.75f, 0.5f), pass.get(),
1037 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1039 RenderPassList pass_list;
1040 pass_list.push_back(pass.Pass());
1042 EXPECT_TRUE(this->RunPixelTest(
1043 &pass_list,
1044 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_offset.png")),
1045 FuzzyPixelOffByOneComparator(true)));
1048 TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) {
1049 gfx::Rect rect(this->device_viewport_size_);
1051 RenderPassId id(1, 1);
1052 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1054 SharedQuadState* shared_state =
1055 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1057 // In MPEG color range YUV values of (15,128,128) should produce black.
1058 CreateTestYUVVideoDrawQuad_Solid(
1059 shared_state, media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_UNSPECIFIED,
1060 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
1061 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1063 RenderPassList pass_list;
1064 pass_list.push_back(pass.Pass());
1066 // If we didn't get black out of the YUV values above, then we probably have a
1067 // color range issue.
1068 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1069 base::FilePath(FILE_PATH_LITERAL("black.png")),
1070 FuzzyPixelOffByOneComparator(true)));
1073 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
1074 gfx::Rect rect(this->device_viewport_size_);
1076 RenderPassId id(1, 1);
1077 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1079 SharedQuadState* shared_state =
1080 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1082 // YUV of (149,43,21) should be green (0,255,0) in RGB.
1083 CreateTestYUVVideoDrawQuad_Solid(
1084 shared_state, media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG, false,
1085 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(),
1086 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1088 RenderPassList pass_list;
1089 pass_list.push_back(pass.Pass());
1091 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1092 base::FilePath(FILE_PATH_LITERAL("green.png")),
1093 FuzzyPixelOffByOneComparator(true)));
1096 // Test that a YUV video doesn't bleed outside of its tex coords when the
1097 // tex coord rect is only a partial subrectangle of the coded contents.
1098 TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) {
1099 RenderPassList pass_list;
1100 CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG,
1101 &pass_list);
1102 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1103 base::FilePath(FILE_PATH_LITERAL("green.png")),
1104 FuzzyPixelOffByOneComparator(true)));
1107 TEST_F(VideoGLRendererPixelTest, YUVAEdgeBleed) {
1108 RenderPassList pass_list;
1109 CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12A, media::COLOR_SPACE_UNSPECIFIED,
1110 &pass_list);
1111 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1112 base::FilePath(FILE_PATH_LITERAL("green.png")),
1113 FuzzyPixelOffByOneComparator(true)));
1116 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
1117 gfx::Rect rect(this->device_viewport_size_);
1119 RenderPassId id(1, 1);
1120 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1122 SharedQuadState* shared_state =
1123 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1125 // Dark grey in JPEG color range (in MPEG, this is black).
1126 CreateTestYUVVideoDrawQuad_Solid(
1127 shared_state, media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG, false,
1128 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
1129 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1131 RenderPassList pass_list;
1132 pass_list.push_back(pass.Pass());
1134 EXPECT_TRUE(
1135 this->RunPixelTest(&pass_list,
1136 base::FilePath(FILE_PATH_LITERAL("dark_grey.png")),
1137 FuzzyPixelOffByOneComparator(true)));
1140 TEST_F(VideoGLRendererPixelTest, SimpleYUVARect) {
1141 gfx::Rect rect(this->device_viewport_size_);
1143 RenderPassId id(1, 1);
1144 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1146 SharedQuadState* shared_state =
1147 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1149 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::PIXEL_FORMAT_YV12A,
1150 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1151 pass.get(), video_resource_updater_.get(),
1152 rect, rect, resource_provider_.get());
1154 SolidColorDrawQuad* color_quad =
1155 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1156 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
1158 RenderPassList pass_list;
1159 pass_list.push_back(pass.Pass());
1161 EXPECT_TRUE(this->RunPixelTest(
1162 &pass_list,
1163 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_alpha.png")),
1164 FuzzyPixelOffByOneComparator(true)));
1167 TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) {
1168 gfx::Rect rect(this->device_viewport_size_);
1170 RenderPassId id(1, 1);
1171 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1173 SharedQuadState* shared_state =
1174 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1176 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::PIXEL_FORMAT_YV12A,
1177 true, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1178 pass.get(), video_resource_updater_.get(),
1179 rect, rect, resource_provider_.get());
1181 SolidColorDrawQuad* color_quad =
1182 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1183 color_quad->SetNew(shared_state, rect, rect, SK_ColorBLACK, false);
1185 RenderPassList pass_list;
1186 pass_list.push_back(pass.Pass());
1188 EXPECT_TRUE(this->RunPixelTest(
1189 &pass_list,
1190 base::FilePath(FILE_PATH_LITERAL("black.png")),
1191 ExactPixelComparator(true)));
1194 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) {
1195 gfx::Rect viewport_rect(this->device_viewport_size_);
1197 RenderPassId root_pass_id(1, 1);
1198 scoped_ptr<RenderPass> root_pass =
1199 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1201 RenderPassId child_pass_id(2, 2);
1202 gfx::Rect pass_rect(this->device_viewport_size_);
1203 gfx::Transform transform_to_root;
1204 scoped_ptr<RenderPass> child_pass =
1205 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1207 gfx::Transform quad_to_target_transform;
1208 SharedQuadState* shared_state = CreateTestSharedQuadState(
1209 quad_to_target_transform, viewport_rect, child_pass.get());
1210 shared_state->opacity = 0.5f;
1212 gfx::Rect blue_rect(0,
1214 this->device_viewport_size_.width(),
1215 this->device_viewport_size_.height() / 2);
1216 SolidColorDrawQuad* blue =
1217 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1218 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1219 gfx::Rect yellow_rect(0,
1220 this->device_viewport_size_.height() / 2,
1221 this->device_viewport_size_.width(),
1222 this->device_viewport_size_.height() / 2);
1223 SolidColorDrawQuad* yellow =
1224 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1225 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1227 SharedQuadState* blank_state = CreateTestSharedQuadState(
1228 quad_to_target_transform, viewport_rect, child_pass.get());
1230 SolidColorDrawQuad* white =
1231 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1232 white->SetNew(
1233 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1235 SharedQuadState* pass_shared_state =
1236 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1238 SkScalar matrix[20];
1239 float amount = 0.5f;
1240 matrix[0] = 0.213f + 0.787f * amount;
1241 matrix[1] = 0.715f - 0.715f * amount;
1242 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1243 matrix[3] = matrix[4] = 0;
1244 matrix[5] = 0.213f - 0.213f * amount;
1245 matrix[6] = 0.715f + 0.285f * amount;
1246 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1247 matrix[8] = matrix[9] = 0;
1248 matrix[10] = 0.213f - 0.213f * amount;
1249 matrix[11] = 0.715f - 0.715f * amount;
1250 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1251 matrix[13] = matrix[14] = 0;
1252 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1253 matrix[18] = 1;
1254 skia::RefPtr<SkColorFilter> colorFilter(
1255 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1256 skia::RefPtr<SkImageFilter> filter =
1257 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
1258 FilterOperations filters;
1259 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1261 RenderPassDrawQuad* render_pass_quad =
1262 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1263 render_pass_quad->SetNew(pass_shared_state,
1264 pass_rect,
1265 pass_rect,
1266 child_pass_id,
1268 gfx::Vector2dF(),
1269 gfx::Size(),
1270 filters,
1271 gfx::Vector2dF(),
1272 FilterOperations());
1274 RenderPassList pass_list;
1275 pass_list.push_back(child_pass.Pass());
1276 pass_list.push_back(root_pass.Pass());
1278 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1279 // renderer so use a fuzzy comparator.
1280 EXPECT_TRUE(this->RunPixelTest(
1281 &pass_list,
1282 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1283 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1286 TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) {
1287 gfx::Rect viewport_rect(this->device_viewport_size_);
1289 RenderPassId root_pass_id(1, 1);
1290 scoped_ptr<RenderPass> root_pass =
1291 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1293 RenderPassId child_pass_id(2, 2);
1294 gfx::Rect pass_rect(this->device_viewport_size_);
1295 gfx::Transform transform_to_root;
1296 scoped_ptr<RenderPass> child_pass =
1297 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1299 gfx::Transform quad_to_target_transform;
1300 SharedQuadState* shared_state = CreateTestSharedQuadState(
1301 quad_to_target_transform, viewport_rect, child_pass.get());
1302 shared_state->opacity = 0.5f;
1304 gfx::Rect blue_rect(0,
1306 this->device_viewport_size_.width(),
1307 this->device_viewport_size_.height() / 2);
1308 SolidColorDrawQuad* blue =
1309 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1310 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1311 gfx::Rect yellow_rect(0,
1312 this->device_viewport_size_.height() / 2,
1313 this->device_viewport_size_.width(),
1314 this->device_viewport_size_.height() / 2);
1315 SolidColorDrawQuad* yellow =
1316 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1317 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1319 SharedQuadState* blank_state = CreateTestSharedQuadState(
1320 quad_to_target_transform, viewport_rect, child_pass.get());
1322 SolidColorDrawQuad* white =
1323 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1324 white->SetNew(
1325 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1327 SharedQuadState* pass_shared_state =
1328 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1330 FilterOperations filters;
1331 filters.Append(FilterOperation::CreateSaturateFilter(0.5f));
1333 RenderPassDrawQuad* render_pass_quad =
1334 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1335 render_pass_quad->SetNew(pass_shared_state,
1336 pass_rect,
1337 pass_rect,
1338 child_pass_id,
1340 gfx::Vector2dF(),
1341 gfx::Size(),
1342 filters,
1343 gfx::Vector2dF(),
1344 FilterOperations());
1346 RenderPassList pass_list;
1347 pass_list.push_back(child_pass.Pass());
1348 pass_list.push_back(root_pass.Pass());
1350 // This test blends slightly differently with the software renderer vs. the gl
1351 // renderer so use a fuzzy comparator.
1352 EXPECT_TRUE(this->RunPixelTest(
1353 &pass_list, base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1354 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1357 TYPED_TEST(RendererPixelTest, FastPassFilterChain) {
1358 gfx::Rect viewport_rect(this->device_viewport_size_);
1360 RenderPassId root_pass_id(1, 1);
1361 scoped_ptr<RenderPass> root_pass =
1362 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1364 RenderPassId child_pass_id(2, 2);
1365 gfx::Rect pass_rect(this->device_viewport_size_);
1366 gfx::Transform transform_to_root;
1367 scoped_ptr<RenderPass> child_pass =
1368 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1370 gfx::Transform quad_to_target_transform;
1371 SharedQuadState* shared_state = CreateTestSharedQuadState(
1372 quad_to_target_transform, viewport_rect, child_pass.get());
1373 shared_state->opacity = 0.5f;
1375 gfx::Rect blue_rect(0,
1377 this->device_viewport_size_.width(),
1378 this->device_viewport_size_.height() / 2);
1379 SolidColorDrawQuad* blue =
1380 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1381 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1382 gfx::Rect yellow_rect(0,
1383 this->device_viewport_size_.height() / 2,
1384 this->device_viewport_size_.width(),
1385 this->device_viewport_size_.height() / 2);
1386 SolidColorDrawQuad* yellow =
1387 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1388 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1390 SharedQuadState* blank_state = CreateTestSharedQuadState(
1391 quad_to_target_transform, viewport_rect, child_pass.get());
1393 SolidColorDrawQuad* white =
1394 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1395 white->SetNew(
1396 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1398 SharedQuadState* pass_shared_state =
1399 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1401 FilterOperations filters;
1402 filters.Append(FilterOperation::CreateGrayscaleFilter(1.f));
1403 filters.Append(FilterOperation::CreateBrightnessFilter(0.5f));
1405 RenderPassDrawQuad* render_pass_quad =
1406 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1407 render_pass_quad->SetNew(pass_shared_state,
1408 pass_rect,
1409 pass_rect,
1410 child_pass_id,
1412 gfx::Vector2dF(),
1413 gfx::Size(),
1414 filters,
1415 gfx::Vector2dF(),
1416 FilterOperations());
1418 RenderPassList pass_list;
1419 pass_list.push_back(child_pass.Pass());
1420 pass_list.push_back(root_pass.Pass());
1422 // This test blends slightly differently with the software renderer vs. the gl
1423 // renderer so use a fuzzy comparator.
1424 EXPECT_TRUE(this->RunPixelTest(
1425 &pass_list,
1426 base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")),
1427 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1430 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) {
1431 gfx::Rect viewport_rect(this->device_viewport_size_);
1433 RenderPassId root_pass_id(1, 1);
1434 scoped_ptr<RenderPass> root_pass =
1435 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1437 RenderPassId child_pass_id(2, 2);
1438 gfx::Rect pass_rect(this->device_viewport_size_);
1439 gfx::Transform transform_to_root;
1440 scoped_ptr<RenderPass> child_pass =
1441 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1443 gfx::Transform quad_to_target_transform;
1444 SharedQuadState* shared_state = CreateTestSharedQuadState(
1445 quad_to_target_transform, viewport_rect, child_pass.get());
1446 shared_state->opacity = 0.5f;
1448 gfx::Rect blue_rect(0,
1450 this->device_viewport_size_.width(),
1451 this->device_viewport_size_.height() / 2);
1452 SolidColorDrawQuad* blue =
1453 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1454 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1455 gfx::Rect yellow_rect(0,
1456 this->device_viewport_size_.height() / 2,
1457 this->device_viewport_size_.width(),
1458 this->device_viewport_size_.height() / 2);
1459 SolidColorDrawQuad* yellow =
1460 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1461 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1463 SharedQuadState* blank_state = CreateTestSharedQuadState(
1464 quad_to_target_transform, viewport_rect, child_pass.get());
1466 SolidColorDrawQuad* white =
1467 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1468 white->SetNew(
1469 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1471 SharedQuadState* pass_shared_state =
1472 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1474 SkScalar matrix[20];
1475 float amount = 0.5f;
1476 matrix[0] = 0.213f + 0.787f * amount;
1477 matrix[1] = 0.715f - 0.715f * amount;
1478 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1479 matrix[3] = 0;
1480 matrix[4] = 20.f;
1481 matrix[5] = 0.213f - 0.213f * amount;
1482 matrix[6] = 0.715f + 0.285f * amount;
1483 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1484 matrix[8] = 0;
1485 matrix[9] = 200.f;
1486 matrix[10] = 0.213f - 0.213f * amount;
1487 matrix[11] = 0.715f - 0.715f * amount;
1488 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1489 matrix[13] = 0;
1490 matrix[14] = 1.5f;
1491 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1492 matrix[18] = 1;
1493 skia::RefPtr<SkColorFilter> colorFilter(
1494 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1495 skia::RefPtr<SkImageFilter> filter =
1496 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
1497 FilterOperations filters;
1498 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1500 RenderPassDrawQuad* render_pass_quad =
1501 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1502 render_pass_quad->SetNew(pass_shared_state,
1503 pass_rect,
1504 pass_rect,
1505 child_pass_id,
1507 gfx::Vector2dF(),
1508 gfx::Size(),
1509 filters,
1510 gfx::Vector2dF(),
1511 FilterOperations());
1513 RenderPassList pass_list;
1515 pass_list.push_back(child_pass.Pass());
1516 pass_list.push_back(root_pass.Pass());
1518 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1519 // renderer so use a fuzzy comparator.
1520 EXPECT_TRUE(this->RunPixelTest(
1521 &pass_list,
1522 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
1523 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1526 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) {
1527 gfx::Rect viewport_rect(this->device_viewport_size_);
1529 RenderPassId root_pass_id(1, 1);
1530 scoped_ptr<RenderPass> root_pass =
1531 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1533 RenderPassId child_pass_id(2, 2);
1534 gfx::Rect pass_rect(this->device_viewport_size_);
1535 gfx::Transform transform_to_root;
1536 scoped_ptr<RenderPass> child_pass =
1537 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1539 gfx::Transform quad_to_target_transform;
1540 SharedQuadState* shared_state = CreateTestSharedQuadState(
1541 quad_to_target_transform, viewport_rect, child_pass.get());
1543 gfx::Rect blue_rect(0,
1545 this->device_viewport_size_.width(),
1546 this->device_viewport_size_.height() / 2);
1547 SolidColorDrawQuad* blue =
1548 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1549 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1550 gfx::Rect yellow_rect(0,
1551 this->device_viewport_size_.height() / 2,
1552 this->device_viewport_size_.width(),
1553 this->device_viewport_size_.height() / 2);
1554 SolidColorDrawQuad* yellow =
1555 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1556 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1558 SharedQuadState* pass_shared_state =
1559 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1560 CreateTestRenderPassDrawQuad(
1561 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1563 RenderPassList pass_list;
1564 pass_list.push_back(child_pass.Pass());
1565 pass_list.push_back(root_pass.Pass());
1567 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1569 EXPECT_TRUE(this->RunPixelTest(
1570 &pass_list,
1571 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
1572 ExactPixelComparator(true)));
1575 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) {
1576 gfx::Rect viewport_rect(this->device_viewport_size_);
1578 RenderPassId root_pass_id(1, 1);
1579 scoped_ptr<RenderPass> root_pass =
1580 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1582 RenderPassId child_pass_id(2, 2);
1583 gfx::Rect pass_rect(this->device_viewport_size_);
1584 gfx::Transform transform_to_root;
1585 scoped_ptr<RenderPass> child_pass =
1586 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1588 gfx::Transform quad_to_target_transform;
1589 SharedQuadState* shared_state = CreateTestSharedQuadState(
1590 quad_to_target_transform, viewport_rect, child_pass.get());
1592 gfx::Rect blue_rect(0,
1594 this->device_viewport_size_.width(),
1595 this->device_viewport_size_.height() / 2);
1596 SolidColorDrawQuad* blue =
1597 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1598 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1599 gfx::Rect yellow_rect(0,
1600 this->device_viewport_size_.height() / 2,
1601 this->device_viewport_size_.width(),
1602 this->device_viewport_size_.height() / 2);
1603 SolidColorDrawQuad* yellow =
1604 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1605 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1607 gfx::Transform aa_transform;
1608 aa_transform.Translate(0.5, 0.0);
1610 SharedQuadState* pass_shared_state =
1611 CreateTestSharedQuadState(aa_transform, pass_rect, root_pass.get());
1612 CreateTestRenderPassDrawQuad(
1613 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1615 SharedQuadState* root_shared_state = CreateTestSharedQuadState(
1616 gfx::Transform(), viewport_rect, root_pass.get());
1617 SolidColorDrawQuad* background =
1618 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1619 background->SetNew(root_shared_state,
1620 gfx::Rect(this->device_viewport_size_),
1621 gfx::Rect(this->device_viewport_size_),
1622 SK_ColorWHITE,
1623 false);
1625 RenderPassList pass_list;
1626 pass_list.push_back(child_pass.Pass());
1627 pass_list.push_back(root_pass.Pass());
1629 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1631 EXPECT_TRUE(this->RunPixelTest(
1632 &pass_list,
1633 base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")),
1634 FuzzyPixelOffByOneComparator(true)));
1637 // This tests the case where we have a RenderPass with a mask, but the quad
1638 // for the masked surface does not include the full surface texture.
1639 TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) {
1640 gfx::Rect viewport_rect(this->device_viewport_size_);
1642 RenderPassId root_pass_id(1, 1);
1643 scoped_ptr<RenderPass> root_pass =
1644 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1645 SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState(
1646 gfx::Transform(), viewport_rect, root_pass.get());
1648 RenderPassId child_pass_id(2, 2);
1649 gfx::Transform transform_to_root;
1650 scoped_ptr<RenderPass> child_pass =
1651 CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root);
1652 SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState(
1653 gfx::Transform(), viewport_rect, child_pass.get());
1655 // The child render pass is just a green box.
1656 static const SkColor kCSSGreen = 0xff008000;
1657 SolidColorDrawQuad* green =
1658 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1659 green->SetNew(
1660 child_pass_shared_state, viewport_rect, viewport_rect, kCSSGreen, false);
1662 // Make a mask.
1663 gfx::Rect mask_rect = viewport_rect;
1664 SkBitmap bitmap;
1665 bitmap.allocPixels(
1666 SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height()));
1667 SkCanvas canvas(bitmap);
1668 SkPaint paint;
1669 paint.setStyle(SkPaint::kStroke_Style);
1670 paint.setStrokeWidth(SkIntToScalar(4));
1671 paint.setColor(SK_ColorWHITE);
1672 canvas.clear(SK_ColorTRANSPARENT);
1673 gfx::Rect rect = mask_rect;
1674 while (!rect.IsEmpty()) {
1675 rect.Inset(6, 6, 4, 4);
1676 canvas.drawRect(
1677 SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()),
1678 paint);
1679 rect.Inset(6, 6, 4, 4);
1682 ResourceId mask_resource_id = this->resource_provider_->CreateResource(
1683 mask_rect.size(), GL_CLAMP_TO_EDGE,
1684 ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
1686 SkAutoLockPixels lock(bitmap);
1687 this->resource_provider_->CopyToResource(
1688 mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
1689 mask_rect.size());
1692 // This RenderPassDrawQuad does not include the full |viewport_rect| which is
1693 // the size of the child render pass.
1694 gfx::Rect sub_rect = gfx::Rect(50, 50, 200, 100);
1695 EXPECT_NE(sub_rect.x(), child_pass->output_rect.x());
1696 EXPECT_NE(sub_rect.y(), child_pass->output_rect.y());
1697 EXPECT_NE(sub_rect.right(), child_pass->output_rect.right());
1698 EXPECT_NE(sub_rect.bottom(), child_pass->output_rect.bottom());
1700 // Set up a mask on the RenderPassDrawQuad.
1701 RenderPassDrawQuad* mask_quad =
1702 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1703 mask_quad->SetNew(root_pass_shared_state,
1704 sub_rect,
1705 sub_rect,
1706 child_pass_id,
1707 mask_resource_id,
1708 gfx::Vector2dF(2.f, 1.f), // mask_uv_scale
1709 gfx::Size(mask_rect.size()), // mask_texture_size
1710 FilterOperations(), // foreground filters
1711 gfx::Vector2dF(), // filters scale
1712 FilterOperations()); // background filters
1714 // White background behind the masked render pass.
1715 SolidColorDrawQuad* white =
1716 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1717 white->SetNew(root_pass_shared_state,
1718 viewport_rect,
1719 viewport_rect,
1720 SK_ColorWHITE,
1721 false);
1723 RenderPassList pass_list;
1724 pass_list.push_back(child_pass.Pass());
1725 pass_list.push_back(root_pass.Pass());
1727 EXPECT_TRUE(this->RunPixelTest(
1728 &pass_list,
1729 base::FilePath(FILE_PATH_LITERAL("mask_bottom_right.png")),
1730 ExactPixelComparator(true)));
1733 template <typename RendererType>
1734 class RendererPixelTestWithBackgroundFilter
1735 : public RendererPixelTest<RendererType> {
1736 protected:
1737 void SetUpRenderPassList() {
1738 gfx::Rect device_viewport_rect(this->device_viewport_size_);
1740 RenderPassId root_id(1, 1);
1741 scoped_ptr<RenderPass> root_pass =
1742 CreateTestRootRenderPass(root_id, device_viewport_rect);
1743 root_pass->has_transparent_background = false;
1745 gfx::Transform identity_quad_to_target_transform;
1747 RenderPassId filter_pass_id(2, 1);
1748 gfx::Transform transform_to_root;
1749 scoped_ptr<RenderPass> filter_pass = CreateTestRenderPass(
1750 filter_pass_id, filter_pass_layer_rect_, transform_to_root);
1752 // A non-visible quad in the filtering render pass.
1754 SharedQuadState* shared_state =
1755 CreateTestSharedQuadState(identity_quad_to_target_transform,
1756 filter_pass_layer_rect_, filter_pass.get());
1757 SolidColorDrawQuad* color_quad =
1758 filter_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1759 color_quad->SetNew(shared_state, filter_pass_layer_rect_,
1760 filter_pass_layer_rect_, SK_ColorTRANSPARENT, false);
1764 SharedQuadState* shared_state =
1765 CreateTestSharedQuadState(filter_pass_to_target_transform_,
1766 filter_pass_layer_rect_, filter_pass.get());
1767 RenderPassDrawQuad* filter_pass_quad =
1768 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1769 filter_pass_quad->SetNew(shared_state, filter_pass_layer_rect_,
1770 filter_pass_layer_rect_, filter_pass_id,
1771 0, // mask_resource_id
1772 gfx::Vector2dF(), // mask_uv_scale
1773 gfx::Size(), // mask_texture_size
1774 FilterOperations(), // filters
1775 gfx::Vector2dF(), // filters_scale
1776 this->background_filters_);
1779 const int kColumnWidth = device_viewport_rect.width() / 3;
1781 gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20);
1782 for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) {
1783 SharedQuadState* shared_state = CreateTestSharedQuadState(
1784 identity_quad_to_target_transform, left_rect, root_pass.get());
1785 SolidColorDrawQuad* color_quad =
1786 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1787 color_quad->SetNew(
1788 shared_state, left_rect, left_rect, SK_ColorGREEN, false);
1789 left_rect += gfx::Vector2d(0, left_rect.height() + 1);
1792 gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20);
1793 for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) {
1794 SharedQuadState* shared_state = CreateTestSharedQuadState(
1795 identity_quad_to_target_transform, middle_rect, root_pass.get());
1796 SolidColorDrawQuad* color_quad =
1797 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1798 color_quad->SetNew(
1799 shared_state, middle_rect, middle_rect, SK_ColorRED, false);
1800 middle_rect += gfx::Vector2d(0, middle_rect.height() + 1);
1803 gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20);
1804 for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) {
1805 SharedQuadState* shared_state = CreateTestSharedQuadState(
1806 identity_quad_to_target_transform, right_rect, root_pass.get());
1807 SolidColorDrawQuad* color_quad =
1808 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1809 color_quad->SetNew(
1810 shared_state, right_rect, right_rect, SK_ColorBLUE, false);
1811 right_rect += gfx::Vector2d(0, right_rect.height() + 1);
1814 SharedQuadState* shared_state =
1815 CreateTestSharedQuadState(identity_quad_to_target_transform,
1816 device_viewport_rect, root_pass.get());
1817 SolidColorDrawQuad* background_quad =
1818 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1819 background_quad->SetNew(shared_state,
1820 device_viewport_rect,
1821 device_viewport_rect,
1822 SK_ColorWHITE,
1823 false);
1825 pass_list_.push_back(filter_pass.Pass());
1826 pass_list_.push_back(root_pass.Pass());
1829 RenderPassList pass_list_;
1830 FilterOperations background_filters_;
1831 gfx::Transform filter_pass_to_target_transform_;
1832 gfx::Rect filter_pass_layer_rect_;
1835 typedef ::testing::Types<GLRenderer, SoftwareRenderer>
1836 BackgroundFilterRendererTypes;
1837 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter,
1838 BackgroundFilterRendererTypes);
1840 typedef RendererPixelTestWithBackgroundFilter<GLRenderer>
1841 GLRendererPixelTestWithBackgroundFilter;
1843 // TODO(skaslev): The software renderer does not support filters yet.
1844 TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) {
1845 this->background_filters_.Append(
1846 FilterOperation::CreateInvertFilter(1.f));
1848 this->filter_pass_layer_rect_ = gfx::Rect(this->device_viewport_size_);
1849 this->filter_pass_layer_rect_.Inset(12, 14, 16, 18);
1851 this->SetUpRenderPassList();
1852 EXPECT_TRUE(this->RunPixelTest(
1853 &this->pass_list_,
1854 base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
1855 ExactPixelComparator(true)));
1858 class ExternalStencilPixelTest : public GLRendererPixelTest {
1859 protected:
1860 void ClearBackgroundToGreen() {
1861 GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
1862 output_surface_->EnsureBackbuffer();
1863 output_surface_->Reshape(device_viewport_size_, 1);
1864 gl->ClearColor(0.f, 1.f, 0.f, 1.f);
1865 gl->Clear(GL_COLOR_BUFFER_BIT);
1868 void PopulateStencilBuffer() {
1869 // Set two quadrants of the stencil buffer to 1.
1870 GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
1871 output_surface_->EnsureBackbuffer();
1872 output_surface_->Reshape(device_viewport_size_, 1);
1873 gl->ClearStencil(0);
1874 gl->Clear(GL_STENCIL_BUFFER_BIT);
1875 gl->Enable(GL_SCISSOR_TEST);
1876 gl->ClearStencil(1);
1877 gl->Scissor(0,
1879 device_viewport_size_.width() / 2,
1880 device_viewport_size_.height() / 2);
1881 gl->Clear(GL_STENCIL_BUFFER_BIT);
1882 gl->Scissor(device_viewport_size_.width() / 2,
1883 device_viewport_size_.height() / 2,
1884 device_viewport_size_.width(),
1885 device_viewport_size_.height());
1886 gl->Clear(GL_STENCIL_BUFFER_BIT);
1890 TEST_F(ExternalStencilPixelTest, StencilTestEnabled) {
1891 ClearBackgroundToGreen();
1892 PopulateStencilBuffer();
1893 this->EnableExternalStencilTest();
1895 // Draw a blue quad that covers the entire device viewport. It should be
1896 // clipped to the bottom left and top right corners by the external stencil.
1897 gfx::Rect rect(this->device_viewport_size_);
1898 RenderPassId id(1, 1);
1899 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1900 SharedQuadState* blue_shared_state =
1901 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1902 SolidColorDrawQuad* blue =
1903 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1904 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1905 pass->has_transparent_background = false;
1906 RenderPassList pass_list;
1907 pass_list.push_back(pass.Pass());
1909 EXPECT_TRUE(this->RunPixelTest(
1910 &pass_list,
1911 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1912 ExactPixelComparator(true)));
1915 TEST_F(ExternalStencilPixelTest, StencilTestDisabled) {
1916 PopulateStencilBuffer();
1918 // Draw a green quad that covers the entire device viewport. The stencil
1919 // buffer should be ignored.
1920 gfx::Rect rect(this->device_viewport_size_);
1921 RenderPassId id(1, 1);
1922 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1923 SharedQuadState* green_shared_state =
1924 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1925 SolidColorDrawQuad* green =
1926 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1927 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
1928 RenderPassList pass_list;
1929 pass_list.push_back(pass.Pass());
1931 EXPECT_TRUE(this->RunPixelTest(
1932 &pass_list,
1933 base::FilePath(FILE_PATH_LITERAL("green.png")),
1934 ExactPixelComparator(true)));
1937 TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) {
1938 // The stencil test should apply only to the final render pass.
1939 ClearBackgroundToGreen();
1940 PopulateStencilBuffer();
1941 this->EnableExternalStencilTest();
1943 gfx::Rect viewport_rect(this->device_viewport_size_);
1945 RenderPassId root_pass_id(1, 1);
1946 scoped_ptr<RenderPass> root_pass =
1947 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1948 root_pass->has_transparent_background = false;
1950 RenderPassId child_pass_id(2, 2);
1951 gfx::Rect pass_rect(this->device_viewport_size_);
1952 gfx::Transform transform_to_root;
1953 scoped_ptr<RenderPass> child_pass =
1954 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1956 gfx::Transform quad_to_target_transform;
1957 SharedQuadState* shared_state = CreateTestSharedQuadState(
1958 quad_to_target_transform, viewport_rect, child_pass.get());
1960 gfx::Rect blue_rect(0,
1962 this->device_viewport_size_.width(),
1963 this->device_viewport_size_.height());
1964 SolidColorDrawQuad* blue =
1965 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1966 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1968 SharedQuadState* pass_shared_state =
1969 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1970 CreateTestRenderPassDrawQuad(
1971 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1972 RenderPassList pass_list;
1973 pass_list.push_back(child_pass.Pass());
1974 pass_list.push_back(root_pass.Pass());
1976 EXPECT_TRUE(this->RunPixelTest(
1977 &pass_list,
1978 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1979 ExactPixelComparator(true)));
1982 TEST_F(ExternalStencilPixelTest, DeviceClip) {
1983 ClearBackgroundToGreen();
1984 gfx::Rect clip_rect(gfx::Point(150, 150), gfx::Size(50, 50));
1985 this->ForceDeviceClip(clip_rect);
1987 // Draw a blue quad that covers the entire device viewport. It should be
1988 // clipped to the bottom right corner by the device clip.
1989 gfx::Rect rect(this->device_viewport_size_);
1990 RenderPassId id(1, 1);
1991 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1992 SharedQuadState* blue_shared_state =
1993 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1994 SolidColorDrawQuad* blue =
1995 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1996 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1997 RenderPassList pass_list;
1998 pass_list.push_back(pass.Pass());
2000 EXPECT_TRUE(this->RunPixelTest(
2001 &pass_list,
2002 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
2003 ExactPixelComparator(true)));
2006 // Software renderer does not support anti-aliased edges.
2007 TEST_F(GLRendererPixelTest, AntiAliasing) {
2008 gfx::Rect rect(this->device_viewport_size_);
2010 RenderPassId id(1, 1);
2011 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2013 gfx::Transform red_quad_to_target_transform;
2014 red_quad_to_target_transform.Rotate(10);
2015 SharedQuadState* red_shared_state =
2016 CreateTestSharedQuadState(red_quad_to_target_transform, rect, pass.get());
2018 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2019 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
2021 gfx::Transform yellow_quad_to_target_transform;
2022 yellow_quad_to_target_transform.Rotate(5);
2023 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
2024 yellow_quad_to_target_transform, rect, pass.get());
2026 SolidColorDrawQuad* yellow =
2027 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2028 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
2030 gfx::Transform blue_quad_to_target_transform;
2031 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2032 blue_quad_to_target_transform, rect, pass.get());
2034 SolidColorDrawQuad* blue =
2035 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2036 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2038 RenderPassList pass_list;
2039 pass_list.push_back(pass.Pass());
2041 EXPECT_TRUE(this->RunPixelTest(
2042 &pass_list,
2043 base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")),
2044 FuzzyPixelOffByOneComparator(true)));
2047 // This test tests that anti-aliasing works for axis aligned quads.
2048 // Anti-aliasing is only supported in the gl renderer.
2049 TEST_F(GLRendererPixelTest, AxisAligned) {
2050 gfx::Rect rect(this->device_viewport_size_);
2052 RenderPassId id(1, 1);
2053 gfx::Transform transform_to_root;
2054 scoped_ptr<RenderPass> pass =
2055 CreateTestRenderPass(id, rect, transform_to_root);
2057 gfx::Transform red_quad_to_target_transform;
2058 red_quad_to_target_transform.Translate(50, 50);
2059 red_quad_to_target_transform.Scale(0.5f + 1.0f / (rect.width() * 2.0f),
2060 0.5f + 1.0f / (rect.height() * 2.0f));
2061 SharedQuadState* red_shared_state =
2062 CreateTestSharedQuadState(red_quad_to_target_transform, rect, pass.get());
2064 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2065 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
2067 gfx::Transform yellow_quad_to_target_transform;
2068 yellow_quad_to_target_transform.Translate(25.5f, 25.5f);
2069 yellow_quad_to_target_transform.Scale(0.5f, 0.5f);
2070 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
2071 yellow_quad_to_target_transform, rect, pass.get());
2073 SolidColorDrawQuad* yellow =
2074 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2075 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
2077 gfx::Transform blue_quad_to_target_transform;
2078 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2079 blue_quad_to_target_transform, rect, pass.get());
2081 SolidColorDrawQuad* blue =
2082 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2083 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2085 RenderPassList pass_list;
2086 pass_list.push_back(pass.Pass());
2088 EXPECT_TRUE(this->RunPixelTest(
2089 &pass_list,
2090 base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")),
2091 ExactPixelComparator(true)));
2094 // This test tests that forcing anti-aliasing off works as expected.
2095 // Anti-aliasing is only supported in the gl renderer.
2096 TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) {
2097 gfx::Rect rect(this->device_viewport_size_);
2099 RenderPassId id(1, 1);
2100 gfx::Transform transform_to_root;
2101 scoped_ptr<RenderPass> pass =
2102 CreateTestRenderPass(id, rect, transform_to_root);
2104 gfx::Transform hole_quad_to_target_transform;
2105 hole_quad_to_target_transform.Translate(50, 50);
2106 hole_quad_to_target_transform.Scale(0.5f + 1.0f / (rect.width() * 2.0f),
2107 0.5f + 1.0f / (rect.height() * 2.0f));
2108 SharedQuadState* hole_shared_state = CreateTestSharedQuadState(
2109 hole_quad_to_target_transform, rect, pass.get());
2111 SolidColorDrawQuad* hole =
2112 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2113 hole->SetAll(
2114 hole_shared_state, rect, rect, rect, false, SK_ColorTRANSPARENT, true);
2116 gfx::Transform green_quad_to_target_transform;
2117 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2118 green_quad_to_target_transform, rect, pass.get());
2120 SolidColorDrawQuad* green =
2121 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2122 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
2124 RenderPassList pass_list;
2125 pass_list.push_back(pass.Pass());
2127 EXPECT_TRUE(this->RunPixelTest(
2128 &pass_list,
2129 base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")),
2130 ExactPixelComparator(false)));
2133 TEST_F(GLRendererPixelTest, AntiAliasingPerspective) {
2134 gfx::Rect rect(this->device_viewport_size_);
2136 scoped_ptr<RenderPass> pass =
2137 CreateTestRootRenderPass(RenderPassId(1, 1), rect);
2139 gfx::Rect red_rect(0, 0, 180, 500);
2140 gfx::Transform red_quad_to_target_transform(
2141 1.0f, 2.4520f, 10.6206f, 19.0f, 0.0f, 0.3528f, 5.9737f, 9.5f, 0.0f,
2142 -0.2250f, -0.9744f, 0.0f, 0.0f, 0.0225f, 0.0974f, 1.0f);
2143 SharedQuadState* red_shared_state = CreateTestSharedQuadState(
2144 red_quad_to_target_transform, red_rect, pass.get());
2145 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2146 red->SetNew(red_shared_state, red_rect, red_rect, SK_ColorRED, false);
2148 gfx::Rect green_rect(19, 7, 180, 10);
2149 SharedQuadState* green_shared_state =
2150 CreateTestSharedQuadState(gfx::Transform(), green_rect, pass.get());
2151 SolidColorDrawQuad* green =
2152 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2153 green->SetNew(
2154 green_shared_state, green_rect, green_rect, SK_ColorGREEN, false);
2156 SharedQuadState* blue_shared_state =
2157 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
2158 SolidColorDrawQuad* blue =
2159 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2160 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2162 RenderPassList pass_list;
2163 pass_list.push_back(pass.Pass());
2165 EXPECT_TRUE(this->RunPixelTest(
2166 &pass_list,
2167 base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")),
2168 FuzzyPixelOffByOneComparator(true)));
2171 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadIdentityScale) {
2172 gfx::Size pile_tile_size(1000, 1000);
2173 gfx::Rect viewport(this->device_viewport_size_);
2174 // TODO(enne): the renderer should figure this out on its own.
2175 ResourceFormat texture_format = RGBA_8888;
2176 bool nearest_neighbor = false;
2178 RenderPassId id(1, 1);
2179 gfx::Transform transform_to_root;
2180 scoped_ptr<RenderPass> pass =
2181 CreateTestRenderPass(id, viewport, transform_to_root);
2183 // One clipped blue quad in the lower right corner. Outside the clip
2184 // is red, which should not appear.
2185 gfx::Rect blue_rect(gfx::Size(100, 100));
2186 gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50));
2188 scoped_ptr<FakePicturePile> blue_recording =
2189 FakePicturePile::CreateFilledPile(pile_tile_size, blue_rect.size());
2190 SkPaint red_paint;
2191 red_paint.setColor(SK_ColorRED);
2192 blue_recording->add_draw_rect_with_paint(blue_rect, red_paint);
2193 SkPaint blue_paint;
2194 blue_paint.setColor(SK_ColorBLUE);
2195 blue_recording->add_draw_rect_with_paint(blue_clip_rect, blue_paint);
2196 blue_recording->Rerecord();
2198 scoped_refptr<FakePicturePileImpl> blue_pile =
2199 FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);
2201 gfx::Transform blue_quad_to_target_transform;
2202 gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right());
2203 blue_quad_to_target_transform.Translate(offset.x(), offset.y());
2204 gfx::RectF blue_scissor_rect = blue_clip_rect;
2205 blue_quad_to_target_transform.TransformRect(&blue_scissor_rect);
2206 SharedQuadState* blue_shared_state = CreateTestSharedQuadStateClipped(
2207 blue_quad_to_target_transform, blue_rect,
2208 gfx::ToEnclosingRect(blue_scissor_rect), pass.get());
2210 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2212 blue_quad->SetNew(blue_shared_state,
2213 viewport, // Intentionally bigger than clip.
2214 gfx::Rect(), viewport, gfx::RectF(viewport),
2215 viewport.size(), nearest_neighbor, texture_format, viewport,
2216 1.f, blue_pile.get());
2218 // One viewport-filling green quad.
2219 scoped_ptr<FakePicturePile> green_recording =
2220 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2221 SkPaint green_paint;
2222 green_paint.setColor(SK_ColorGREEN);
2223 green_recording->add_draw_rect_with_paint(viewport, green_paint);
2224 green_recording->Rerecord();
2225 scoped_refptr<FakePicturePileImpl> green_pile =
2226 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2228 gfx::Transform green_quad_to_target_transform;
2229 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2230 green_quad_to_target_transform, viewport, pass.get());
2232 PictureDrawQuad* green_quad =
2233 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2234 green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
2235 gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(),
2236 nearest_neighbor, texture_format, viewport, 1.f,
2237 green_pile.get());
2239 RenderPassList pass_list;
2240 pass_list.push_back(pass.Pass());
2242 EXPECT_TRUE(this->RunPixelTest(
2243 &pass_list,
2244 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
2245 ExactPixelComparator(true)));
2248 // Not WithSkiaGPUBackend since that path currently requires tiles for opacity.
2249 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadOpacity) {
2250 gfx::Size pile_tile_size(1000, 1000);
2251 gfx::Rect viewport(this->device_viewport_size_);
2252 ResourceFormat texture_format = RGBA_8888;
2253 bool nearest_neighbor = false;
2255 RenderPassId id(1, 1);
2256 gfx::Transform transform_to_root;
2257 scoped_ptr<RenderPass> pass =
2258 CreateTestRenderPass(id, viewport, transform_to_root);
2260 // One viewport-filling 0.5-opacity green quad.
2261 scoped_ptr<FakePicturePile> green_recording =
2262 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2263 SkPaint green_paint;
2264 green_paint.setColor(SK_ColorGREEN);
2265 green_recording->add_draw_rect_with_paint(viewport, green_paint);
2266 green_recording->Rerecord();
2267 scoped_refptr<FakePicturePileImpl> green_pile =
2268 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2270 gfx::Transform green_quad_to_target_transform;
2271 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2272 green_quad_to_target_transform, viewport, pass.get());
2273 green_shared_state->opacity = 0.5f;
2275 PictureDrawQuad* green_quad =
2276 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2277 green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
2278 gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
2279 texture_format, viewport, 1.f, green_pile.get());
2281 // One viewport-filling white quad.
2282 scoped_ptr<FakePicturePile> white_recording =
2283 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2284 SkPaint white_paint;
2285 white_paint.setColor(SK_ColorWHITE);
2286 white_recording->add_draw_rect_with_paint(viewport, white_paint);
2287 white_recording->Rerecord();
2288 scoped_refptr<FakePicturePileImpl> white_pile =
2289 FakePicturePileImpl::CreateFromPile(white_recording.get(), nullptr);
2291 gfx::Transform white_quad_to_target_transform;
2292 SharedQuadState* white_shared_state = CreateTestSharedQuadState(
2293 white_quad_to_target_transform, viewport, pass.get());
2295 PictureDrawQuad* white_quad =
2296 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2297 white_quad->SetNew(white_shared_state, viewport, gfx::Rect(), viewport,
2298 gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
2299 texture_format, viewport, 1.f, white_pile.get());
2301 RenderPassList pass_list;
2302 pass_list.push_back(pass.Pass());
2304 EXPECT_TRUE(this->RunPixelTest(
2305 &pass_list,
2306 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
2307 FuzzyPixelOffByOneComparator(true)));
2310 template<typename TypeParam> bool IsSoftwareRenderer() {
2311 return false;
2314 template<>
2315 bool IsSoftwareRenderer<SoftwareRenderer>() {
2316 return true;
2319 template<>
2320 bool IsSoftwareRenderer<SoftwareRendererWithExpandedViewport>() {
2321 return true;
2324 // If we disable image filtering, then a 2x2 bitmap should appear as four
2325 // huge sharp squares.
2326 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadDisableImageFiltering) {
2327 // We only care about this in software mode since bilinear filtering is
2328 // cheap in hardware.
2329 if (!IsSoftwareRenderer<TypeParam>())
2330 return;
2332 gfx::Size pile_tile_size(1000, 1000);
2333 gfx::Rect viewport(this->device_viewport_size_);
2334 ResourceFormat texture_format = RGBA_8888;
2335 bool nearest_neighbor = false;
2337 RenderPassId id(1, 1);
2338 gfx::Transform transform_to_root;
2339 scoped_ptr<RenderPass> pass =
2340 CreateTestRenderPass(id, viewport, transform_to_root);
2342 SkBitmap bitmap;
2343 bitmap.allocN32Pixels(2, 2);
2345 SkAutoLockPixels lock(bitmap);
2346 SkCanvas canvas(bitmap);
2347 canvas.drawPoint(0, 0, SK_ColorGREEN);
2348 canvas.drawPoint(0, 1, SK_ColorBLUE);
2349 canvas.drawPoint(1, 0, SK_ColorBLUE);
2350 canvas.drawPoint(1, 1, SK_ColorGREEN);
2353 scoped_ptr<FakePicturePile> recording =
2354 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2355 SkPaint paint;
2356 paint.setFilterQuality(kLow_SkFilterQuality);
2357 recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
2358 recording->Rerecord();
2359 scoped_refptr<FakePicturePileImpl> pile =
2360 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2362 gfx::Transform quad_to_target_transform;
2363 SharedQuadState* shared_state =
2364 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2366 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2367 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
2368 gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
2369 texture_format, viewport, 1.f, pile.get());
2371 RenderPassList pass_list;
2372 pass_list.push_back(pass.Pass());
2374 this->disable_picture_quad_image_filtering_ = true;
2376 EXPECT_TRUE(this->RunPixelTest(
2377 &pass_list,
2378 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2379 ExactPixelComparator(true)));
2382 // This disables filtering by setting |nearest_neighbor| on the PictureDrawQuad.
2383 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNearestNeighbor) {
2384 gfx::Size pile_tile_size(1000, 1000);
2385 gfx::Rect viewport(this->device_viewport_size_);
2386 ResourceFormat texture_format = RGBA_8888;
2387 bool nearest_neighbor = true;
2389 RenderPassId id(1, 1);
2390 gfx::Transform transform_to_root;
2391 scoped_ptr<RenderPass> pass =
2392 CreateTestRenderPass(id, viewport, transform_to_root);
2394 SkBitmap bitmap;
2395 bitmap.allocN32Pixels(2, 2);
2397 SkAutoLockPixels lock(bitmap);
2398 SkCanvas canvas(bitmap);
2399 canvas.drawPoint(0, 0, SK_ColorGREEN);
2400 canvas.drawPoint(0, 1, SK_ColorBLUE);
2401 canvas.drawPoint(1, 0, SK_ColorBLUE);
2402 canvas.drawPoint(1, 1, SK_ColorGREEN);
2405 scoped_ptr<FakePicturePile> recording =
2406 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2407 SkPaint paint;
2408 paint.setFilterQuality(kLow_SkFilterQuality);
2409 recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
2410 recording->Rerecord();
2411 scoped_refptr<FakePicturePileImpl> pile =
2412 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2414 gfx::Transform quad_to_target_transform;
2415 SharedQuadState* shared_state =
2416 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2418 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2419 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
2420 gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
2421 texture_format, viewport, 1.f, pile.get());
2423 RenderPassList pass_list;
2424 pass_list.push_back(pass.Pass());
2426 EXPECT_TRUE(this->RunPixelTest(
2427 &pass_list,
2428 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2429 ExactPixelComparator(true)));
2432 // This disables filtering by setting |nearest_neighbor| on the TileDrawQuad.
2433 TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) {
2434 gfx::Rect viewport(this->device_viewport_size_);
2435 bool swizzle_contents = true;
2436 bool nearest_neighbor = true;
2438 SkBitmap bitmap;
2439 bitmap.allocN32Pixels(2, 2);
2441 SkAutoLockPixels lock(bitmap);
2442 SkCanvas canvas(bitmap);
2443 canvas.drawPoint(0, 0, SK_ColorGREEN);
2444 canvas.drawPoint(0, 1, SK_ColorBLUE);
2445 canvas.drawPoint(1, 0, SK_ColorBLUE);
2446 canvas.drawPoint(1, 1, SK_ColorGREEN);
2449 gfx::Size tile_size(2, 2);
2450 ResourceId resource = this->resource_provider_->CreateResource(
2451 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2452 RGBA_8888);
2455 SkAutoLockPixels lock(bitmap);
2456 this->resource_provider_->CopyToResource(
2457 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
2460 RenderPassId id(1, 1);
2461 gfx::Transform transform_to_root;
2462 scoped_ptr<RenderPass> pass =
2463 CreateTestRenderPass(id, viewport, transform_to_root);
2465 gfx::Transform quad_to_target_transform;
2466 SharedQuadState* shared_state =
2467 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2469 TileDrawQuad* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>();
2470 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource,
2471 gfx::Rect(tile_size), tile_size, swizzle_contents,
2472 nearest_neighbor);
2474 RenderPassList pass_list;
2475 pass_list.push_back(pass.Pass());
2477 EXPECT_TRUE(this->RunPixelTest(
2478 &pass_list,
2479 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2480 ExactPixelComparator(true)));
2483 // This disables filtering by setting |nearest_neighbor| to true on the
2484 // TextureDrawQuad.
2485 TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadNearestNeighbor) {
2486 gfx::Rect viewport(this->device_viewport_size_);
2487 bool nearest_neighbor = true;
2489 SkBitmap bitmap;
2490 bitmap.allocN32Pixels(2, 2);
2492 SkAutoLockPixels lock(bitmap);
2493 SkCanvas canvas(bitmap);
2494 canvas.drawPoint(0, 0, SK_ColorGREEN);
2495 canvas.drawPoint(0, 1, SK_ColorBLUE);
2496 canvas.drawPoint(1, 0, SK_ColorBLUE);
2497 canvas.drawPoint(1, 1, SK_ColorGREEN);
2500 gfx::Size tile_size(2, 2);
2501 ResourceId resource = this->resource_provider_->CreateResource(
2502 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2503 RGBA_8888);
2506 SkAutoLockPixels lock(bitmap);
2507 this->resource_provider_->CopyToResource(
2508 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
2511 RenderPassId id(1, 1);
2512 gfx::Transform transform_to_root;
2513 scoped_ptr<RenderPass> pass =
2514 CreateTestRenderPass(id, viewport, transform_to_root);
2516 gfx::Transform quad_to_target_transform;
2517 SharedQuadState* shared_state =
2518 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2520 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2521 TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2522 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource, false,
2523 gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorBLACK,
2524 vertex_opacity, false, nearest_neighbor);
2526 RenderPassList pass_list;
2527 pass_list.push_back(pass.Pass());
2529 EXPECT_TRUE(this->RunPixelTest(
2530 &pass_list,
2531 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2532 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)));
2535 // This ensures filtering is enabled by setting |nearest_neighbor| to false on
2536 // the TextureDrawQuad.
2537 TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadLinear) {
2538 gfx::Rect viewport(this->device_viewport_size_);
2539 bool nearest_neighbor = false;
2541 SkBitmap bitmap;
2542 bitmap.allocN32Pixels(2, 2);
2544 SkAutoLockPixels lock(bitmap);
2545 SkCanvas canvas(bitmap);
2546 canvas.drawPoint(0, 0, SK_ColorGREEN);
2547 canvas.drawPoint(0, 1, SK_ColorBLUE);
2548 canvas.drawPoint(1, 0, SK_ColorBLUE);
2549 canvas.drawPoint(1, 1, SK_ColorGREEN);
2552 gfx::Size tile_size(2, 2);
2553 ResourceId resource = this->resource_provider_->CreateResource(
2554 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2555 RGBA_8888);
2558 SkAutoLockPixels lock(bitmap);
2559 this->resource_provider_->CopyToResource(
2560 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
2563 RenderPassId id(1, 1);
2564 gfx::Transform transform_to_root;
2565 scoped_ptr<RenderPass> pass =
2566 CreateTestRenderPass(id, viewport, transform_to_root);
2568 gfx::Transform quad_to_target_transform;
2569 SharedQuadState* shared_state =
2570 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2572 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2573 TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2574 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource, false,
2575 gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorBLACK,
2576 vertex_opacity, false, nearest_neighbor);
2578 RenderPassList pass_list;
2579 pass_list.push_back(pass.Pass());
2581 // Allow for a small amount of error as the blending alogrithm used by Skia is
2582 // affected by the offset in the expanded rect.
2583 EXPECT_TRUE(this->RunPixelTest(
2584 &pass_list,
2585 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers_linear.png")),
2586 FuzzyPixelComparator(false, 100.f, 0.f, 16.f, 16.f, 0.f)));
2589 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) {
2590 gfx::Size pile_tile_size(1000, 1000);
2591 gfx::Rect viewport(this->device_viewport_size_);
2592 // TODO(enne): the renderer should figure this out on its own.
2593 ResourceFormat texture_format = RGBA_8888;
2594 bool nearest_neighbor = false;
2596 RenderPassId id(1, 1);
2597 gfx::Transform transform_to_root;
2598 scoped_ptr<RenderPass> pass =
2599 CreateTestRenderPass(id, viewport, transform_to_root);
2601 // As scaling up the blue checkerboards will cause sampling on the GPU,
2602 // a few extra "cleanup rects" need to be added to clobber the blending
2603 // to make the output image more clean. This will also test subrects
2604 // of the layer.
2605 gfx::Transform green_quad_to_target_transform;
2606 gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100));
2607 gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20));
2609 scoped_ptr<FakePicturePile> green_recording =
2610 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2612 SkPaint red_paint;
2613 red_paint.setColor(SK_ColorRED);
2614 green_recording->add_draw_rect_with_paint(viewport, red_paint);
2615 SkPaint green_paint;
2616 green_paint.setColor(SK_ColorGREEN);
2617 green_recording->add_draw_rect_with_paint(green_rect1, green_paint);
2618 green_recording->add_draw_rect_with_paint(green_rect2, green_paint);
2619 green_recording->Rerecord();
2620 scoped_refptr<FakePicturePileImpl> green_pile =
2621 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2623 SharedQuadState* top_right_green_shared_quad_state =
2624 CreateTestSharedQuadState(green_quad_to_target_transform, viewport,
2625 pass.get());
2627 PictureDrawQuad* green_quad1 =
2628 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2629 green_quad1->SetNew(top_right_green_shared_quad_state, green_rect1,
2630 gfx::Rect(), green_rect1, gfx::RectF(green_rect1.size()),
2631 green_rect1.size(), nearest_neighbor, texture_format,
2632 green_rect1, 1.f, green_pile.get());
2634 PictureDrawQuad* green_quad2 =
2635 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2636 green_quad2->SetNew(top_right_green_shared_quad_state, green_rect2,
2637 gfx::Rect(), green_rect2, gfx::RectF(green_rect2.size()),
2638 green_rect2.size(), nearest_neighbor, texture_format,
2639 green_rect2, 1.f, green_pile.get());
2641 // Add a green clipped checkerboard in the bottom right to help test
2642 // interleaving picture quad content and solid color content.
2643 gfx::Rect bottom_right_rect(
2644 gfx::Point(viewport.width() / 2, viewport.height() / 2),
2645 gfx::Size(viewport.width() / 2, viewport.height() / 2));
2646 SharedQuadState* bottom_right_green_shared_state =
2647 CreateTestSharedQuadStateClipped(green_quad_to_target_transform, viewport,
2648 bottom_right_rect, pass.get());
2649 SolidColorDrawQuad* bottom_right_color_quad =
2650 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2651 bottom_right_color_quad->SetNew(bottom_right_green_shared_state,
2652 viewport,
2653 viewport,
2654 SK_ColorGREEN,
2655 false);
2657 // Add two blue checkerboards taking up the bottom left and top right,
2658 // but use content scales as content rects to make this happen.
2659 // The content is at a 4x content scale.
2660 gfx::Rect layer_rect(gfx::Size(20, 30));
2661 float contents_scale = 4.f;
2662 // Two rects that touch at their corners, arbitrarily placed in the layer.
2663 gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f));
2664 gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f));
2665 gfx::RectF union_layer_rect = blue_layer_rect1;
2666 union_layer_rect.Union(blue_layer_rect2);
2668 // Because scaling up will cause sampling outside the rects, add one extra
2669 // pixel of buffer at the final content scale.
2670 float inset = -1.f / contents_scale;
2671 blue_layer_rect1.Inset(inset, inset, inset, inset);
2672 blue_layer_rect2.Inset(inset, inset, inset, inset);
2674 scoped_ptr<FakePicturePile> recording =
2675 FakePicturePile::CreateFilledPile(pile_tile_size, layer_rect.size());
2677 Region outside(layer_rect);
2678 outside.Subtract(gfx::ToEnclosingRect(union_layer_rect));
2679 for (Region::Iterator iter(outside); iter.has_rect(); iter.next()) {
2680 recording->add_draw_rect_with_paint(iter.rect(), red_paint);
2683 SkPaint blue_paint;
2684 blue_paint.setColor(SK_ColorBLUE);
2685 recording->add_draw_rect_with_paint(blue_layer_rect1, blue_paint);
2686 recording->add_draw_rect_with_paint(blue_layer_rect2, blue_paint);
2687 recording->Rerecord();
2688 scoped_refptr<FakePicturePileImpl> pile =
2689 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2691 gfx::Rect content_rect(
2692 gfx::ScaleToEnclosingRect(layer_rect, contents_scale));
2693 gfx::Rect content_union_rect(
2694 gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale)));
2696 // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels,
2697 // so scale an additional 10x to make them 100x100.
2698 gfx::Transform quad_to_target_transform;
2699 quad_to_target_transform.Scale(10.0, 10.0);
2700 gfx::Rect quad_content_rect(gfx::Size(20, 20));
2701 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2702 quad_to_target_transform, quad_content_rect, pass.get());
2704 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2705 blue_quad->SetNew(blue_shared_state, quad_content_rect, gfx::Rect(),
2706 quad_content_rect, gfx::RectF(quad_content_rect),
2707 content_union_rect.size(), nearest_neighbor, texture_format,
2708 content_union_rect, contents_scale, pile.get());
2710 // Fill left half of viewport with green.
2711 gfx::Transform half_green_quad_to_target_transform;
2712 gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height()));
2713 SharedQuadState* half_green_shared_state = CreateTestSharedQuadState(
2714 half_green_quad_to_target_transform, half_green_rect, pass.get());
2715 SolidColorDrawQuad* half_color_quad =
2716 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2717 half_color_quad->SetNew(half_green_shared_state,
2718 half_green_rect,
2719 half_green_rect,
2720 SK_ColorGREEN,
2721 false);
2723 RenderPassList pass_list;
2724 pass_list.push_back(pass.Pass());
2726 EXPECT_TRUE(this->RunPixelTest(
2727 &pass_list,
2728 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2729 ExactPixelComparator(true)));
2732 typedef RendererPixelTest<GLRendererWithFlippedSurface>
2733 GLRendererPixelTestWithFlippedOutputSurface;
2735 TEST_F(GLRendererPixelTestWithFlippedOutputSurface, ExplicitFlipTest) {
2736 // This draws a blue rect above a yellow rect with an inverted output surface.
2737 gfx::Rect viewport_rect(this->device_viewport_size_);
2739 RenderPassId root_pass_id(1, 1);
2740 scoped_ptr<RenderPass> root_pass =
2741 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2743 RenderPassId child_pass_id(2, 2);
2744 gfx::Rect pass_rect(this->device_viewport_size_);
2745 gfx::Transform transform_to_root;
2746 scoped_ptr<RenderPass> child_pass =
2747 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2749 gfx::Transform quad_to_target_transform;
2750 SharedQuadState* shared_state = CreateTestSharedQuadState(
2751 quad_to_target_transform, viewport_rect, child_pass.get());
2753 gfx::Rect blue_rect(0,
2755 this->device_viewport_size_.width(),
2756 this->device_viewport_size_.height() / 2);
2757 SolidColorDrawQuad* blue =
2758 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2759 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2760 gfx::Rect yellow_rect(0,
2761 this->device_viewport_size_.height() / 2,
2762 this->device_viewport_size_.width(),
2763 this->device_viewport_size_.height() / 2);
2764 SolidColorDrawQuad* yellow =
2765 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2766 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
2768 SharedQuadState* pass_shared_state =
2769 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2770 CreateTestRenderPassDrawQuad(
2771 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2773 RenderPassList pass_list;
2774 pass_list.push_back(child_pass.Pass());
2775 pass_list.push_back(root_pass.Pass());
2777 EXPECT_TRUE(this->RunPixelTest(
2778 &pass_list,
2779 base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")),
2780 ExactPixelComparator(true)));
2783 TEST_F(GLRendererPixelTestWithFlippedOutputSurface, CheckChildPassUnflipped) {
2784 // This draws a blue rect above a yellow rect with an inverted output surface.
2785 gfx::Rect viewport_rect(this->device_viewport_size_);
2787 RenderPassId root_pass_id(1, 1);
2788 scoped_ptr<RenderPass> root_pass =
2789 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2791 RenderPassId child_pass_id(2, 2);
2792 gfx::Rect pass_rect(this->device_viewport_size_);
2793 gfx::Transform transform_to_root;
2794 scoped_ptr<RenderPass> child_pass =
2795 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2797 gfx::Transform quad_to_target_transform;
2798 SharedQuadState* shared_state = CreateTestSharedQuadState(
2799 quad_to_target_transform, viewport_rect, child_pass.get());
2801 gfx::Rect blue_rect(0,
2803 this->device_viewport_size_.width(),
2804 this->device_viewport_size_.height() / 2);
2805 SolidColorDrawQuad* blue =
2806 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2807 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2808 gfx::Rect yellow_rect(0,
2809 this->device_viewport_size_.height() / 2,
2810 this->device_viewport_size_.width(),
2811 this->device_viewport_size_.height() / 2);
2812 SolidColorDrawQuad* yellow =
2813 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2814 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
2816 SharedQuadState* pass_shared_state =
2817 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2818 CreateTestRenderPassDrawQuad(
2819 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2821 RenderPassList pass_list;
2822 pass_list.push_back(child_pass.Pass());
2823 pass_list.push_back(root_pass.Pass());
2825 // Check that the child pass remains unflipped.
2826 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
2827 &pass_list,
2828 pass_list.front(),
2829 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
2830 ExactPixelComparator(true)));
2833 TEST_F(GLRendererPixelTest, CheckReadbackSubset) {
2834 gfx::Rect viewport_rect(this->device_viewport_size_);
2836 RenderPassId root_pass_id(1, 1);
2837 scoped_ptr<RenderPass> root_pass =
2838 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2840 RenderPassId child_pass_id(2, 2);
2841 gfx::Rect pass_rect(this->device_viewport_size_);
2842 gfx::Transform transform_to_root;
2843 scoped_ptr<RenderPass> child_pass =
2844 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2846 gfx::Transform quad_to_target_transform;
2847 SharedQuadState* shared_state = CreateTestSharedQuadState(
2848 quad_to_target_transform, viewport_rect, child_pass.get());
2850 // Draw a green quad full-size with a blue quad in the lower-right corner.
2851 gfx::Rect blue_rect(this->device_viewport_size_.width() * 3 / 4,
2852 this->device_viewport_size_.height() * 3 / 4,
2853 this->device_viewport_size_.width() * 3 / 4,
2854 this->device_viewport_size_.height() * 3 / 4);
2855 SolidColorDrawQuad* blue =
2856 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2857 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2858 gfx::Rect green_rect(0,
2860 this->device_viewport_size_.width(),
2861 this->device_viewport_size_.height());
2862 SolidColorDrawQuad* green =
2863 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2864 green->SetNew(shared_state, green_rect, green_rect, SK_ColorGREEN, false);
2866 SharedQuadState* pass_shared_state =
2867 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2868 CreateTestRenderPassDrawQuad(
2869 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2871 RenderPassList pass_list;
2872 pass_list.push_back(child_pass.Pass());
2873 pass_list.push_back(root_pass.Pass());
2875 // Check that the child pass remains unflipped.
2876 gfx::Rect capture_rect(this->device_viewport_size_.width() / 2,
2877 this->device_viewport_size_.height() / 2,
2878 this->device_viewport_size_.width() / 2,
2879 this->device_viewport_size_.height() / 2);
2880 EXPECT_TRUE(this->RunPixelTestWithReadbackTargetAndArea(
2881 &pass_list,
2882 pass_list.front(),
2883 base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")),
2884 ExactPixelComparator(true),
2885 &capture_rect));
2888 TYPED_TEST(RendererPixelTest, WrapModeRepeat) {
2889 gfx::Rect rect(this->device_viewport_size_);
2891 RenderPassId id(1, 1);
2892 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2894 SharedQuadState* shared_state =
2895 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
2897 gfx::Size texture_size(4, 4);
2898 SkPMColor colors[4] = {
2899 SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)),
2900 SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)),
2901 SkPreMultiplyColor(SkColorSetARGB(255, 0, 64, 0)),
2902 SkPreMultiplyColor(SkColorSetARGB(255, 0, 0, 0)),
2904 uint32_t pixels[16] = {
2905 colors[0], colors[0], colors[1], colors[1],
2906 colors[0], colors[0], colors[1], colors[1],
2907 colors[2], colors[2], colors[3], colors[3],
2908 colors[2], colors[2], colors[3], colors[3],
2910 ResourceId resource = this->resource_provider_->CreateResource(
2911 texture_size, GL_REPEAT, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2912 RGBA_8888);
2913 this->resource_provider_->CopyToResource(
2914 resource, reinterpret_cast<uint8_t*>(pixels), texture_size);
2916 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2917 TextureDrawQuad* texture_quad =
2918 pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2919 texture_quad->SetNew(
2920 shared_state, gfx::Rect(this->device_viewport_size_), gfx::Rect(),
2921 gfx::Rect(this->device_viewport_size_), resource,
2922 true, // premultiplied_alpha
2923 gfx::PointF(0.0f, 0.0f), // uv_top_left
2924 gfx::PointF( // uv_bottom_right
2925 this->device_viewport_size_.width() / texture_size.width(),
2926 this->device_viewport_size_.height() / texture_size.height()),
2927 SK_ColorWHITE, vertex_opacity,
2928 false, // flipped
2929 false); // nearest_neighbor
2931 RenderPassList pass_list;
2932 pass_list.push_back(pass.Pass());
2934 EXPECT_TRUE(this->RunPixelTest(
2935 &pass_list,
2936 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
2937 FuzzyPixelOffByOneComparator(true)));
2940 #endif // !defined(OS_ANDROID)
2942 } // namespace
2943 } // namespace cc