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