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