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/core/SkSurface.h"
19 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
20 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
21 #include "ui/gfx/geometry/rect_conversions.h"
23 using gpu::gles2::GLES2Interface
;
28 #if !defined(OS_ANDROID)
29 scoped_ptr
<RenderPass
> CreateTestRootRenderPass(RenderPassId id
,
30 const gfx::Rect
& rect
) {
31 scoped_ptr
<RenderPass
> pass
= RenderPass::Create();
32 const gfx::Rect output_rect
= rect
;
33 const gfx::Rect damage_rect
= rect
;
34 const gfx::Transform transform_to_root_target
;
35 pass
->SetNew(id
, output_rect
, damage_rect
, transform_to_root_target
);
39 scoped_ptr
<RenderPass
> CreateTestRenderPass(
41 const gfx::Rect
& rect
,
42 const gfx::Transform
& transform_to_root_target
) {
43 scoped_ptr
<RenderPass
> pass
= RenderPass::Create();
44 const gfx::Rect output_rect
= rect
;
45 const gfx::Rect damage_rect
= rect
;
46 pass
->SetNew(id
, output_rect
, damage_rect
, transform_to_root_target
);
50 SharedQuadState
* CreateTestSharedQuadState(
51 gfx::Transform quad_to_target_transform
,
52 const gfx::Rect
& rect
,
53 RenderPass
* render_pass
) {
54 const gfx::Size layer_bounds
= rect
.size();
55 const gfx::Rect visible_layer_rect
= rect
;
56 const gfx::Rect clip_rect
= rect
;
57 const bool is_clipped
= false;
58 const float opacity
= 1.0f
;
59 const SkXfermode::Mode blend_mode
= SkXfermode::kSrcOver_Mode
;
60 int sorting_context_id
= 0;
61 SharedQuadState
* shared_state
= render_pass
->CreateAndAppendSharedQuadState();
62 shared_state
->SetAll(quad_to_target_transform
, layer_bounds
,
63 visible_layer_rect
, clip_rect
, is_clipped
, opacity
,
64 blend_mode
, sorting_context_id
);
68 SharedQuadState
* CreateTestSharedQuadStateClipped(
69 gfx::Transform quad_to_target_transform
,
70 const gfx::Rect
& rect
,
71 const gfx::Rect
& clip_rect
,
72 RenderPass
* render_pass
) {
73 const gfx::Size layer_bounds
= rect
.size();
74 const gfx::Rect visible_layer_rect
= clip_rect
;
75 const bool is_clipped
= true;
76 const float opacity
= 1.0f
;
77 const SkXfermode::Mode blend_mode
= SkXfermode::kSrcOver_Mode
;
78 int sorting_context_id
= 0;
79 SharedQuadState
* shared_state
= render_pass
->CreateAndAppendSharedQuadState();
80 shared_state
->SetAll(quad_to_target_transform
, layer_bounds
,
81 visible_layer_rect
, clip_rect
, is_clipped
, opacity
,
82 blend_mode
, sorting_context_id
);
86 void CreateTestRenderPassDrawQuad(const SharedQuadState
* shared_state
,
87 const gfx::Rect
& rect
,
89 RenderPass
* render_pass
) {
90 RenderPassDrawQuad
* quad
=
91 render_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
92 quad
->SetNew(shared_state
,
96 0, // mask_resource_id
97 gfx::Vector2dF(), // mask_uv_scale
98 gfx::Size(), // mask_texture_size
99 FilterOperations(), // foreground filters
100 gfx::Vector2dF(), // filters scale
101 FilterOperations()); // background filters
104 void CreateTestTwoColoredTextureDrawQuad(const gfx::Rect
& rect
,
106 SkColor texel_stripe_color
,
107 SkColor background_color
,
108 bool premultiplied_alpha
,
109 const SharedQuadState
* shared_state
,
110 ResourceProvider
* resource_provider
,
111 RenderPass
* render_pass
) {
112 SkPMColor pixel_color
= premultiplied_alpha
113 ? SkPreMultiplyColor(texel_color
)
114 : SkPackARGB32NoCheck(SkColorGetA(texel_color
),
115 SkColorGetR(texel_color
),
116 SkColorGetG(texel_color
),
117 SkColorGetB(texel_color
));
118 SkPMColor pixel_stripe_color
=
120 ? SkPreMultiplyColor(texel_stripe_color
)
121 : SkPackARGB32NoCheck(SkColorGetA(texel_stripe_color
),
122 SkColorGetR(texel_stripe_color
),
123 SkColorGetG(texel_stripe_color
),
124 SkColorGetB(texel_stripe_color
));
125 std::vector
<uint32_t> pixels(rect
.size().GetArea(), pixel_color
);
126 for (int i
= rect
.height() / 4; i
< (rect
.height() * 3 / 4); ++i
) {
127 for (int k
= rect
.width() / 4; k
< (rect
.width() * 3 / 4); ++k
) {
128 pixels
[i
* rect
.width() + k
] = pixel_stripe_color
;
131 ResourceId resource
= resource_provider
->CreateResource(
132 rect
.size(), GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
134 resource_provider
->CopyToResource(
135 resource
, reinterpret_cast<uint8_t*>(&pixels
.front()), rect
.size());
137 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
138 const gfx::PointF
uv_top_left(0.0f
, 0.0f
);
139 const gfx::PointF
uv_bottom_right(1.0f
, 1.0f
);
140 const bool flipped
= false;
141 const bool nearest_neighbor
= false;
142 TextureDrawQuad
* quad
=
143 render_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
144 quad
->SetNew(shared_state
, rect
, gfx::Rect(), rect
, resource
,
145 premultiplied_alpha
, uv_top_left
, uv_bottom_right
,
146 background_color
, vertex_opacity
, flipped
, nearest_neighbor
);
149 void CreateTestTextureDrawQuad(const gfx::Rect
& rect
,
151 SkColor background_color
,
152 bool premultiplied_alpha
,
153 const SharedQuadState
* shared_state
,
154 ResourceProvider
* resource_provider
,
155 RenderPass
* render_pass
) {
156 SkPMColor pixel_color
= premultiplied_alpha
?
157 SkPreMultiplyColor(texel_color
) :
158 SkPackARGB32NoCheck(SkColorGetA(texel_color
),
159 SkColorGetR(texel_color
),
160 SkColorGetG(texel_color
),
161 SkColorGetB(texel_color
));
162 size_t num_pixels
= static_cast<size_t>(rect
.width()) * rect
.height();
163 std::vector
<uint32_t> pixels(num_pixels
, pixel_color
);
165 ResourceId resource
= resource_provider
->CreateResource(
166 rect
.size(), GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
168 resource_provider
->CopyToResource(
169 resource
, reinterpret_cast<uint8_t*>(&pixels
.front()), rect
.size());
171 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
173 const gfx::PointF
uv_top_left(0.0f
, 0.0f
);
174 const gfx::PointF
uv_bottom_right(1.0f
, 1.0f
);
175 const bool flipped
= false;
176 const bool nearest_neighbor
= false;
177 TextureDrawQuad
* quad
=
178 render_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
179 quad
->SetNew(shared_state
, rect
, gfx::Rect(), rect
, resource
,
180 premultiplied_alpha
, uv_top_left
, uv_bottom_right
,
181 background_color
, vertex_opacity
, flipped
, nearest_neighbor
);
184 void CreateTestYUVVideoDrawQuad_FromVideoFrame(
185 const SharedQuadState
* shared_state
,
186 scoped_refptr
<media::VideoFrame
> video_frame
,
188 const gfx::RectF
& tex_coord_rect
,
189 RenderPass
* render_pass
,
190 VideoResourceUpdater
* video_resource_updater
,
191 const gfx::Rect
& rect
,
192 const gfx::Rect
& visible_rect
,
193 ResourceProvider
* resource_provider
) {
194 const bool with_alpha
= (video_frame
->format() == media::PIXEL_FORMAT_YV12A
);
195 YUVVideoDrawQuad::ColorSpace color_space
= YUVVideoDrawQuad::REC_601
;
196 int video_frame_color_space
;
197 if (video_frame
->metadata()->GetInteger(
198 media::VideoFrameMetadata::COLOR_SPACE
, &video_frame_color_space
) &&
199 video_frame_color_space
== media::COLOR_SPACE_JPEG
) {
200 color_space
= YUVVideoDrawQuad::JPEG
;
203 const gfx::Rect
opaque_rect(0, 0, 0, 0);
206 memset(video_frame
->data(media::VideoFrame::kAPlane
), alpha_value
,
207 video_frame
->stride(media::VideoFrame::kAPlane
) *
208 video_frame
->rows(media::VideoFrame::kAPlane
));
211 VideoFrameExternalResources resources
=
212 video_resource_updater
->CreateExternalResourcesFromVideoFrame(
215 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE
, resources
.type
);
216 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame
->format()),
217 resources
.mailboxes
.size());
218 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame
->format()),
219 resources
.release_callbacks
.size());
221 ResourceId y_resource
= resource_provider
->CreateResourceFromTextureMailbox(
222 resources
.mailboxes
[media::VideoFrame::kYPlane
],
223 SingleReleaseCallbackImpl::Create(
224 resources
.release_callbacks
[media::VideoFrame::kYPlane
]));
225 ResourceId u_resource
= resource_provider
->CreateResourceFromTextureMailbox(
226 resources
.mailboxes
[media::VideoFrame::kUPlane
],
227 SingleReleaseCallbackImpl::Create(
228 resources
.release_callbacks
[media::VideoFrame::kUPlane
]));
229 ResourceId v_resource
= resource_provider
->CreateResourceFromTextureMailbox(
230 resources
.mailboxes
[media::VideoFrame::kVPlane
],
231 SingleReleaseCallbackImpl::Create(
232 resources
.release_callbacks
[media::VideoFrame::kVPlane
]));
233 ResourceId a_resource
= 0;
235 a_resource
= resource_provider
->CreateResourceFromTextureMailbox(
236 resources
.mailboxes
[media::VideoFrame::kAPlane
],
237 SingleReleaseCallbackImpl::Create(
238 resources
.release_callbacks
[media::VideoFrame::kAPlane
]));
241 const gfx::Size ya_tex_size
= video_frame
->coded_size();
242 const gfx::Size uv_tex_size
= media::VideoFrame::PlaneSize(
243 video_frame
->format(), media::VideoFrame::kUPlane
,
244 video_frame
->coded_size());
245 DCHECK(uv_tex_size
== media::VideoFrame::PlaneSize(
246 video_frame
->format(), media::VideoFrame::kVPlane
,
247 video_frame
->coded_size()));
249 DCHECK(ya_tex_size
== media::VideoFrame::PlaneSize(
250 video_frame
->format(), media::VideoFrame::kAPlane
,
251 video_frame
->coded_size()));
254 gfx::RectF
ya_tex_coord_rect(tex_coord_rect
.x() * ya_tex_size
.width(),
255 tex_coord_rect
.y() * ya_tex_size
.height(),
256 tex_coord_rect
.width() * ya_tex_size
.width(),
257 tex_coord_rect
.height() * ya_tex_size
.height());
258 gfx::RectF
uv_tex_coord_rect(tex_coord_rect
.x() * uv_tex_size
.width(),
259 tex_coord_rect
.y() * uv_tex_size
.height(),
260 tex_coord_rect
.width() * uv_tex_size
.width(),
261 tex_coord_rect
.height() * uv_tex_size
.height());
263 YUVVideoDrawQuad
* yuv_quad
=
264 render_pass
->CreateAndAppendDrawQuad
<YUVVideoDrawQuad
>();
265 yuv_quad
->SetNew(shared_state
, rect
, opaque_rect
, visible_rect
,
266 ya_tex_coord_rect
, uv_tex_coord_rect
, ya_tex_size
,
267 uv_tex_size
, y_resource
, u_resource
, v_resource
, a_resource
,
271 void CreateTestYUVVideoDrawQuad_Striped(
272 const SharedQuadState
* shared_state
,
273 media::VideoPixelFormat format
,
275 const gfx::RectF
& tex_coord_rect
,
276 RenderPass
* render_pass
,
277 VideoResourceUpdater
* video_resource_updater
,
278 const gfx::Rect
& rect
,
279 const gfx::Rect
& visible_rect
,
280 ResourceProvider
* resource_provider
) {
281 scoped_refptr
<media::VideoFrame
> video_frame
= media::VideoFrame::CreateFrame(
282 format
, rect
.size(), rect
, rect
.size(), base::TimeDelta());
284 // YUV values representing a striped pattern, for validating texture
285 // coordinates for sampling.
289 for (int i
= 0; i
< video_frame
->rows(media::VideoFrame::kYPlane
); ++i
) {
290 uint8_t* y_row
= video_frame
->data(media::VideoFrame::kYPlane
) +
291 video_frame
->stride(media::VideoFrame::kYPlane
) * i
;
292 for (int j
= 0; j
< video_frame
->row_bytes(media::VideoFrame::kYPlane
);
294 y_row
[j
] = (y_value
+= 1);
297 for (int i
= 0; i
< video_frame
->rows(media::VideoFrame::kUPlane
); ++i
) {
298 uint8_t* u_row
= video_frame
->data(media::VideoFrame::kUPlane
) +
299 video_frame
->stride(media::VideoFrame::kUPlane
) * i
;
300 uint8_t* v_row
= video_frame
->data(media::VideoFrame::kVPlane
) +
301 video_frame
->stride(media::VideoFrame::kVPlane
) * i
;
302 for (int j
= 0; j
< video_frame
->row_bytes(media::VideoFrame::kUPlane
);
304 u_row
[j
] = (u_value
+= 3);
305 v_row
[j
] = (v_value
+= 5);
308 uint8 alpha_value
= is_transparent
? 0 : 128;
309 CreateTestYUVVideoDrawQuad_FromVideoFrame(
310 shared_state
, video_frame
, alpha_value
, tex_coord_rect
, render_pass
,
311 video_resource_updater
, rect
, visible_rect
, resource_provider
);
314 // Creates a video frame of size background_size filled with yuv_background,
315 // and then draws a foreground rectangle in a different color on top of
316 // that. The foreground rectangle must have coordinates that are divisible
317 // by 2 because YUV is a block format.
318 void CreateTestYUVVideoDrawQuad_TwoColor(
319 const SharedQuadState
* shared_state
,
320 media::VideoPixelFormat format
,
321 media::ColorSpace color_space
,
323 const gfx::RectF
& tex_coord_rect
,
324 const gfx::Size
& background_size
,
325 const gfx::Rect
& visible_rect
,
329 const gfx::Rect
& foreground_rect
,
333 RenderPass
* render_pass
,
334 VideoResourceUpdater
* video_resource_updater
,
335 ResourceProvider
* resource_provider
) {
336 const gfx::Rect
rect(background_size
);
338 scoped_refptr
<media::VideoFrame
> video_frame
=
339 media::VideoFrame::CreateFrame(format
, background_size
, foreground_rect
,
340 foreground_rect
.size(), base::TimeDelta());
341 video_frame
->metadata()->SetInteger(media::VideoFrameMetadata::COLOR_SPACE
,
344 int planes
[] = {media::VideoFrame::kYPlane
,
345 media::VideoFrame::kUPlane
,
346 media::VideoFrame::kVPlane
};
347 uint8 yuv_background
[] = {y_background
, u_background
, v_background
};
348 uint8 yuv_foreground
[] = {y_foreground
, u_foreground
, v_foreground
};
349 int sample_size
[] = {1, 2, 2};
351 for (int i
= 0; i
< 3; ++i
) {
352 memset(video_frame
->data(planes
[i
]), yuv_background
[i
],
353 video_frame
->stride(planes
[i
]) * video_frame
->rows(planes
[i
]));
356 for (int i
= 0; i
< 3; ++i
) {
357 // Since yuv encoding uses block encoding, widths have to be divisible
358 // by the sample size in order for this function to behave properly.
359 DCHECK_EQ(foreground_rect
.x() % sample_size
[i
], 0);
360 DCHECK_EQ(foreground_rect
.y() % sample_size
[i
], 0);
361 DCHECK_EQ(foreground_rect
.width() % sample_size
[i
], 0);
362 DCHECK_EQ(foreground_rect
.height() % sample_size
[i
], 0);
364 gfx::Rect
sample_rect(foreground_rect
.x() / sample_size
[i
],
365 foreground_rect
.y() / sample_size
[i
],
366 foreground_rect
.width() / sample_size
[i
],
367 foreground_rect
.height() / sample_size
[i
]);
368 for (int y
= sample_rect
.y(); y
< sample_rect
.bottom(); ++y
) {
369 for (int x
= sample_rect
.x(); x
< sample_rect
.right(); ++x
) {
370 size_t offset
= y
* video_frame
->stride(planes
[i
]) + x
;
371 video_frame
->data(planes
[i
])[offset
] = yuv_foreground
[i
];
376 uint8 alpha_value
= 255;
377 CreateTestYUVVideoDrawQuad_FromVideoFrame(
378 shared_state
, video_frame
, alpha_value
, tex_coord_rect
, render_pass
,
379 video_resource_updater
, rect
, visible_rect
, resource_provider
);
382 void CreateTestYUVVideoDrawQuad_Solid(
383 const SharedQuadState
* shared_state
,
384 media::VideoPixelFormat format
,
385 media::ColorSpace color_space
,
387 const gfx::RectF
& tex_coord_rect
,
391 RenderPass
* render_pass
,
392 VideoResourceUpdater
* video_resource_updater
,
393 const gfx::Rect
& rect
,
394 const gfx::Rect
& visible_rect
,
395 ResourceProvider
* resource_provider
) {
396 scoped_refptr
<media::VideoFrame
> video_frame
= media::VideoFrame::CreateFrame(
397 format
, rect
.size(), rect
, rect
.size(), base::TimeDelta());
398 video_frame
->metadata()->SetInteger(media::VideoFrameMetadata::COLOR_SPACE
,
401 // YUV values of a solid, constant, color. Useful for testing that color
402 // space/color range are being handled properly.
403 memset(video_frame
->data(media::VideoFrame::kYPlane
), y
,
404 video_frame
->stride(media::VideoFrame::kYPlane
) *
405 video_frame
->rows(media::VideoFrame::kYPlane
));
406 memset(video_frame
->data(media::VideoFrame::kUPlane
), u
,
407 video_frame
->stride(media::VideoFrame::kUPlane
) *
408 video_frame
->rows(media::VideoFrame::kUPlane
));
409 memset(video_frame
->data(media::VideoFrame::kVPlane
), v
,
410 video_frame
->stride(media::VideoFrame::kVPlane
) *
411 video_frame
->rows(media::VideoFrame::kVPlane
));
413 uint8 alpha_value
= is_transparent
? 0 : 128;
414 CreateTestYUVVideoDrawQuad_FromVideoFrame(
415 shared_state
, video_frame
, alpha_value
, tex_coord_rect
, render_pass
,
416 video_resource_updater
, rect
, visible_rect
, resource_provider
);
419 typedef ::testing::Types
<GLRenderer
,
421 GLRendererWithExpandedViewport
,
422 SoftwareRendererWithExpandedViewport
> RendererTypes
;
423 TYPED_TEST_CASE(RendererPixelTest
, RendererTypes
);
425 template <typename RendererType
>
426 class SoftwareRendererPixelTest
: public RendererPixelTest
<RendererType
> {};
428 typedef ::testing::Types
<SoftwareRenderer
, SoftwareRendererWithExpandedViewport
>
429 SoftwareRendererTypes
;
430 TYPED_TEST_CASE(SoftwareRendererPixelTest
, SoftwareRendererTypes
);
432 template <typename RendererType
>
433 class FuzzyForSoftwareOnlyPixelComparator
: public PixelComparator
{
435 explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha
)
436 : fuzzy_(discard_alpha
), exact_(discard_alpha
) {}
438 bool Compare(const SkBitmap
& actual_bmp
,
439 const SkBitmap
& expected_bmp
) const override
;
442 FuzzyPixelOffByOneComparator fuzzy_
;
443 ExactPixelComparator exact_
;
447 bool FuzzyForSoftwareOnlyPixelComparator
<SoftwareRenderer
>::Compare(
448 const SkBitmap
& actual_bmp
,
449 const SkBitmap
& expected_bmp
) const {
450 return fuzzy_
.Compare(actual_bmp
, expected_bmp
);
454 bool FuzzyForSoftwareOnlyPixelComparator
<
455 SoftwareRendererWithExpandedViewport
>::Compare(
456 const SkBitmap
& actual_bmp
,
457 const SkBitmap
& expected_bmp
) const {
458 return fuzzy_
.Compare(actual_bmp
, expected_bmp
);
461 template<typename RendererType
>
462 bool FuzzyForSoftwareOnlyPixelComparator
<RendererType
>::Compare(
463 const SkBitmap
& actual_bmp
,
464 const SkBitmap
& expected_bmp
) const {
465 return exact_
.Compare(actual_bmp
, expected_bmp
);
468 TYPED_TEST(RendererPixelTest
, SimpleGreenRect
) {
469 gfx::Rect
rect(this->device_viewport_size_
);
471 RenderPassId
id(1, 1);
472 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
474 SharedQuadState
* shared_state
=
475 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
477 SolidColorDrawQuad
* color_quad
=
478 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
479 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorGREEN
, false);
481 RenderPassList pass_list
;
482 pass_list
.push_back(pass
.Pass());
484 EXPECT_TRUE(this->RunPixelTest(
486 base::FilePath(FILE_PATH_LITERAL("green.png")),
487 ExactPixelComparator(true)));
490 TYPED_TEST(RendererPixelTest
, SimpleGreenRect_NonRootRenderPass
) {
491 gfx::Rect
rect(this->device_viewport_size_
);
492 gfx::Rect
small_rect(100, 100);
494 RenderPassId
child_id(2, 1);
495 scoped_ptr
<RenderPass
> child_pass
=
496 CreateTestRenderPass(child_id
, small_rect
, gfx::Transform());
498 SharedQuadState
* child_shared_state
=
499 CreateTestSharedQuadState(gfx::Transform(), small_rect
, child_pass
.get());
501 SolidColorDrawQuad
* color_quad
=
502 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
503 color_quad
->SetNew(child_shared_state
, rect
, rect
, SK_ColorGREEN
, false);
505 RenderPassId
root_id(1, 1);
506 scoped_ptr
<RenderPass
> root_pass
=
507 CreateTestRenderPass(root_id
, rect
, gfx::Transform());
509 SharedQuadState
* root_shared_state
=
510 CreateTestSharedQuadState(gfx::Transform(), rect
, root_pass
.get());
512 CreateTestRenderPassDrawQuad(
513 root_shared_state
, small_rect
, child_id
, root_pass
.get());
515 RenderPass
* child_pass_ptr
= child_pass
.get();
517 RenderPassList pass_list
;
518 pass_list
.push_back(child_pass
.Pass());
519 pass_list
.push_back(root_pass
.Pass());
521 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
524 base::FilePath(FILE_PATH_LITERAL("green_small.png")),
525 ExactPixelComparator(true)));
528 TYPED_TEST(RendererPixelTest
, PremultipliedTextureWithoutBackground
) {
529 gfx::Rect
rect(this->device_viewport_size_
);
531 RenderPassId
id(1, 1);
532 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
534 SharedQuadState
* shared_state
=
535 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
537 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
538 SkColorSetARGB(128, 0, 255, 0), // Texel color.
539 SK_ColorTRANSPARENT
, // Background color.
540 true, // Premultiplied alpha.
542 this->resource_provider_
.get(),
545 SolidColorDrawQuad
* color_quad
=
546 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
547 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorWHITE
, false);
549 RenderPassList pass_list
;
550 pass_list
.push_back(pass
.Pass());
552 EXPECT_TRUE(this->RunPixelTest(
554 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
555 FuzzyPixelOffByOneComparator(true)));
558 TYPED_TEST(RendererPixelTest
, PremultipliedTextureWithBackground
) {
559 gfx::Rect
rect(this->device_viewport_size_
);
561 RenderPassId
id(1, 1);
562 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
564 SharedQuadState
* texture_quad_state
=
565 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
566 texture_quad_state
->opacity
= 0.8f
;
568 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
569 SkColorSetARGB(204, 120, 255, 120), // Texel color.
570 SK_ColorGREEN
, // Background color.
571 true, // Premultiplied alpha.
573 this->resource_provider_
.get(),
576 SharedQuadState
* color_quad_state
=
577 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
578 SolidColorDrawQuad
* color_quad
=
579 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
580 color_quad
->SetNew(color_quad_state
, rect
, rect
, SK_ColorWHITE
, false);
582 RenderPassList pass_list
;
583 pass_list
.push_back(pass
.Pass());
585 EXPECT_TRUE(this->RunPixelTest(
587 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
588 FuzzyPixelOffByOneComparator(true)));
591 template <typename QuadType
>
592 static const base::FilePath::CharType
* IntersectingQuadImage() {
593 return FILE_PATH_LITERAL("intersecting_blue_green_squares.png");
596 const base::FilePath::CharType
* IntersectingQuadImage
<SolidColorDrawQuad
>() {
597 return FILE_PATH_LITERAL("intersecting_blue_green.png");
600 const base::FilePath::CharType
* IntersectingQuadImage
<YUVVideoDrawQuad
>() {
601 return FILE_PATH_LITERAL("intersecting_blue_green_squares_video.png");
604 template <typename TypeParam
>
605 class IntersectingQuadPixelTest
: public RendererPixelTest
<TypeParam
> {
607 void SetupQuadStateAndRenderPass() {
608 // This sets up a pair of draw quads. They are both rotated
609 // relative to the root plane, they are also rotated relative to each other.
610 // The intersect in the middle at a non-perpendicular angle so that any
611 // errors are hopefully magnified.
612 // The quads should intersect correctly, as in the front quad should only
613 // be partially in front of the back quad, and partially behind.
615 viewport_rect_
= gfx::Rect(this->device_viewport_size_
);
616 quad_rect_
= gfx::Rect(0, 0, this->device_viewport_size_
.width(),
617 this->device_viewport_size_
.height() / 2.0);
619 RenderPassId
id(1, 1);
620 render_pass_
= CreateTestRootRenderPass(id
, viewport_rect_
);
622 // Create the front quad rotated on the Z and Y axis.
623 gfx::Transform trans
;
624 trans
.Translate3d(0, 0, 0.707 * this->device_viewport_size_
.width() / 2.0);
625 trans
.RotateAboutZAxis(45.0);
626 trans
.RotateAboutYAxis(45.0);
628 CreateTestSharedQuadState(trans
, viewport_rect_
, render_pass_
.get());
629 front_quad_state_
->clip_rect
= quad_rect_
;
630 // Make sure they end up in a 3d sorting context.
631 front_quad_state_
->sorting_context_id
= 1;
633 // Create the back quad, and rotate on just the y axis. This will intersect
634 // the first quad partially.
635 trans
= gfx::Transform();
636 trans
.Translate3d(0, 0, -0.707 * this->device_viewport_size_
.width() / 2.0);
637 trans
.RotateAboutYAxis(-45.0);
639 CreateTestSharedQuadState(trans
, viewport_rect_
, render_pass_
.get());
640 back_quad_state_
->sorting_context_id
= 1;
641 back_quad_state_
->clip_rect
= quad_rect_
;
643 template <typename T
>
644 void AppendBackgroundAndRunTest(const PixelComparator
& comparator
) {
645 SharedQuadState
* background_quad_state
= CreateTestSharedQuadState(
646 gfx::Transform(), viewport_rect_
, render_pass_
.get());
647 SolidColorDrawQuad
* background_quad
=
648 render_pass_
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
649 background_quad
->SetNew(background_quad_state
, viewport_rect_
,
650 viewport_rect_
, SK_ColorWHITE
, false);
651 pass_list_
.push_back(render_pass_
.Pass());
652 const base::FilePath::CharType
* fileName
= IntersectingQuadImage
<T
>();
654 this->RunPixelTest(&pass_list_
, base::FilePath(fileName
), comparator
));
656 template <typename T
>
657 T
* CreateAndAppendDrawQuad() {
658 return render_pass_
->CreateAndAppendDrawQuad
<T
>();
661 scoped_ptr
<RenderPass
> render_pass_
;
662 gfx::Rect viewport_rect_
;
663 SharedQuadState
* front_quad_state_
;
664 SharedQuadState
* back_quad_state_
;
665 gfx::Rect quad_rect_
;
666 RenderPassList pass_list_
;
669 template <typename TypeParam
>
670 class IntersectingQuadGLPixelTest
671 : public IntersectingQuadPixelTest
<TypeParam
> {
673 void SetUp() override
{
674 IntersectingQuadPixelTest
<TypeParam
>::SetUp();
675 video_resource_updater_
.reset(
676 new VideoResourceUpdater(this->output_surface_
->context_provider(),
677 this->resource_provider_
.get()));
678 video_resource_updater2_
.reset(
679 new VideoResourceUpdater(this->output_surface_
->context_provider(),
680 this->resource_provider_
.get()));
684 scoped_ptr
<VideoResourceUpdater
> video_resource_updater_
;
685 scoped_ptr
<VideoResourceUpdater
> video_resource_updater2_
;
688 template <typename TypeParam
>
689 class IntersectingQuadSoftwareTest
690 : public IntersectingQuadPixelTest
<TypeParam
> {};
692 typedef ::testing::Types
<SoftwareRenderer
, SoftwareRendererWithExpandedViewport
>
693 SoftwareRendererTypes
;
694 typedef ::testing::Types
<GLRenderer
, GLRendererWithExpandedViewport
>
697 TYPED_TEST_CASE(IntersectingQuadPixelTest
, RendererTypes
);
698 TYPED_TEST_CASE(IntersectingQuadGLPixelTest
, GLRendererTypes
);
699 TYPED_TEST_CASE(IntersectingQuadSoftwareTest
, SoftwareRendererTypes
);
701 TYPED_TEST(IntersectingQuadPixelTest
, SolidColorQuads
) {
702 this->SetupQuadStateAndRenderPass();
704 SolidColorDrawQuad
* quad
=
705 this->template CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
706 SolidColorDrawQuad
* quad2
=
707 this->template CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
709 quad
->SetNew(this->front_quad_state_
, this->quad_rect_
, this->quad_rect_
,
710 SK_ColorBLUE
, false);
711 quad2
->SetNew(this->back_quad_state_
, this->quad_rect_
, this->quad_rect_
,
712 SK_ColorGREEN
, false);
713 SCOPED_TRACE("IntersectingSolidColorQuads");
714 this->template AppendBackgroundAndRunTest
<SolidColorDrawQuad
>(
715 FuzzyPixelComparator(false, 2.f
, 0.f
, 256.f
, 256, 0.f
));
718 template <typename TypeParam
>
719 SkColor
GetColor(const SkColor
& color
) {
724 SkColor GetColor
<GLRenderer
>(const SkColor
& color
) {
725 return SkColorSetARGB(SkColorGetA(color
), SkColorGetB(color
),
726 SkColorGetG(color
), SkColorGetR(color
));
729 SkColor GetColor
<GLRendererWithExpandedViewport
>(const SkColor
& color
) {
730 return GetColor
<GLRenderer
>(color
);
733 TYPED_TEST(IntersectingQuadPixelTest
, TexturedQuads
) {
734 this->SetupQuadStateAndRenderPass();
735 CreateTestTwoColoredTextureDrawQuad(
736 this->quad_rect_
, GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 0, 0)),
737 GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT
,
738 true, this->front_quad_state_
, this->resource_provider_
.get(),
739 this->render_pass_
.get());
740 CreateTestTwoColoredTextureDrawQuad(
741 this->quad_rect_
, GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 255, 0)),
742 GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT
,
743 true, this->back_quad_state_
, this->resource_provider_
.get(),
744 this->render_pass_
.get());
746 SCOPED_TRACE("IntersectingTexturedQuads");
747 this->template AppendBackgroundAndRunTest
<TextureDrawQuad
>(
748 FuzzyPixelComparator(false, 2.f
, 0.f
, 256.f
, 256, 0.f
));
751 TYPED_TEST(IntersectingQuadSoftwareTest
, PictureQuads
) {
752 this->SetupQuadStateAndRenderPass();
753 gfx::Rect
outer_rect(this->quad_rect_
);
754 gfx::Rect
inner_rect(this->quad_rect_
.x() + (this->quad_rect_
.width() / 4),
755 this->quad_rect_
.y() + (this->quad_rect_
.height() / 4),
756 this->quad_rect_
.width() / 2,
757 this->quad_rect_
.height() / 2);
760 black_paint
.setColor(SK_ColorBLACK
);
762 blue_paint
.setColor(SK_ColorBLUE
);
764 green_paint
.setColor(SK_ColorGREEN
);
766 scoped_ptr
<FakePicturePile
> blue_recording
=
767 FakePicturePile::CreateFilledPile(gfx::Size(1000, 1000),
768 this->quad_rect_
.size());
769 blue_recording
->add_draw_rect_with_paint(outer_rect
, black_paint
);
770 blue_recording
->add_draw_rect_with_paint(inner_rect
, blue_paint
);
771 blue_recording
->Rerecord();
772 scoped_refptr
<FakePicturePileImpl
> blue_pile
=
773 FakePicturePileImpl::CreateFromPile(blue_recording
.get(), nullptr);
775 PictureDrawQuad
* blue_quad
=
776 this->render_pass_
->template CreateAndAppendDrawQuad
<PictureDrawQuad
>();
778 blue_quad
->SetNew(this->front_quad_state_
, this->quad_rect_
, gfx::Rect(),
779 this->quad_rect_
, gfx::RectF(this->quad_rect_
),
780 this->quad_rect_
.size(), false, RGBA_8888
, this->quad_rect_
,
783 scoped_ptr
<FakePicturePile
> green_recording
=
784 FakePicturePile::CreateFilledPile(this->quad_rect_
.size(),
785 this->quad_rect_
.size());
786 green_recording
->add_draw_rect_with_paint(outer_rect
, green_paint
);
787 green_recording
->add_draw_rect_with_paint(inner_rect
, black_paint
);
788 green_recording
->Rerecord();
789 scoped_refptr
<FakePicturePileImpl
> green_pile
=
790 FakePicturePileImpl::CreateFromPile(green_recording
.get(), nullptr);
792 PictureDrawQuad
* green_quad
=
793 this->render_pass_
->template CreateAndAppendDrawQuad
<PictureDrawQuad
>();
794 green_quad
->SetNew(this->back_quad_state_
, this->quad_rect_
, gfx::Rect(),
795 this->quad_rect_
, gfx::RectF(this->quad_rect_
),
796 this->quad_rect_
.size(), false, RGBA_8888
,
797 this->quad_rect_
, 1.f
, green_pile
);
798 SCOPED_TRACE("IntersectingPictureQuadsPass");
799 this->template AppendBackgroundAndRunTest
<PictureDrawQuad
>(
800 FuzzyPixelComparator(false, 2.f
, 0.f
, 256.f
, 256, 0.f
));
803 TYPED_TEST(IntersectingQuadPixelTest
, RenderPassQuads
) {
804 this->SetupQuadStateAndRenderPass();
805 RenderPassId
child_pass_id1(2, 2);
806 RenderPassId
child_pass_id2(2, 3);
807 scoped_ptr
<RenderPass
> child_pass1
=
808 CreateTestRenderPass(child_pass_id1
, this->quad_rect_
, gfx::Transform());
809 SharedQuadState
* child1_quad_state
= CreateTestSharedQuadState(
810 gfx::Transform(), this->quad_rect_
, child_pass1
.get());
811 scoped_ptr
<RenderPass
> child_pass2
=
812 CreateTestRenderPass(child_pass_id2
, this->quad_rect_
, gfx::Transform());
813 SharedQuadState
* child2_quad_state
= CreateTestSharedQuadState(
814 gfx::Transform(), this->quad_rect_
, child_pass2
.get());
816 CreateTestTwoColoredTextureDrawQuad(
817 this->quad_rect_
, GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 0, 0)),
818 GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT
,
819 true, child1_quad_state
, this->resource_provider_
.get(),
821 CreateTestTwoColoredTextureDrawQuad(
822 this->quad_rect_
, GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 255, 0)),
823 GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT
,
824 true, child2_quad_state
, this->resource_provider_
.get(),
827 CreateTestRenderPassDrawQuad(this->front_quad_state_
, this->quad_rect_
,
828 child_pass_id1
, this->render_pass_
.get());
829 CreateTestRenderPassDrawQuad(this->back_quad_state_
, this->quad_rect_
,
830 child_pass_id2
, this->render_pass_
.get());
832 this->pass_list_
.push_back(child_pass1
.Pass());
833 this->pass_list_
.push_back(child_pass2
.Pass());
834 SCOPED_TRACE("IntersectingRenderQuadsPass");
835 this->template AppendBackgroundAndRunTest
<RenderPassDrawQuad
>(
836 FuzzyPixelComparator(false, 2.f
, 0.f
, 256.f
, 256, 0.f
));
839 TYPED_TEST(IntersectingQuadGLPixelTest
, YUVVideoQuads
) {
840 this->SetupQuadStateAndRenderPass();
841 gfx::Rect
inner_rect(
842 ((this->quad_rect_
.x() + (this->quad_rect_
.width() / 4)) & ~0xF),
843 ((this->quad_rect_
.y() + (this->quad_rect_
.height() / 4)) & ~0xF),
844 (this->quad_rect_
.width() / 2) & ~0xF,
845 (this->quad_rect_
.height() / 2) & ~0xF);
847 CreateTestYUVVideoDrawQuad_TwoColor(
848 this->front_quad_state_
, media::PIXEL_FORMAT_YV12
,
849 media::COLOR_SPACE_JPEG
, false, gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
850 this->quad_rect_
.size(), this->quad_rect_
, 0, 128, 128, inner_rect
, 29,
851 255, 107, this->render_pass_
.get(), this->video_resource_updater_
.get(),
852 this->resource_provider_
.get());
854 CreateTestYUVVideoDrawQuad_TwoColor(
855 this->back_quad_state_
, media::PIXEL_FORMAT_YV12
, media::COLOR_SPACE_JPEG
,
856 false, gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
), this->quad_rect_
.size(),
857 this->quad_rect_
, 149, 43, 21, inner_rect
, 0, 128, 128,
858 this->render_pass_
.get(), this->video_resource_updater2_
.get(),
859 this->resource_provider_
.get());
861 SCOPED_TRACE("IntersectingVideoQuads");
862 this->template AppendBackgroundAndRunTest
<YUVVideoDrawQuad
>(
863 FuzzyPixelOffByOneComparator(false));
866 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
867 TEST_F(GLRendererPixelTest
, NonPremultipliedTextureWithoutBackground
) {
868 gfx::Rect
rect(this->device_viewport_size_
);
870 RenderPassId
id(1, 1);
871 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
873 SharedQuadState
* shared_state
=
874 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
876 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
877 SkColorSetARGB(128, 0, 255, 0), // Texel color.
878 SK_ColorTRANSPARENT
, // Background color.
879 false, // Premultiplied alpha.
881 this->resource_provider_
.get(),
884 SolidColorDrawQuad
* color_quad
=
885 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
886 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorWHITE
, false);
888 RenderPassList pass_list
;
889 pass_list
.push_back(pass
.Pass());
891 EXPECT_TRUE(this->RunPixelTest(
893 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
894 FuzzyPixelOffByOneComparator(true)));
897 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
898 TEST_F(GLRendererPixelTest
, NonPremultipliedTextureWithBackground
) {
899 gfx::Rect
rect(this->device_viewport_size_
);
901 RenderPassId
id(1, 1);
902 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
904 SharedQuadState
* texture_quad_state
=
905 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
906 texture_quad_state
->opacity
= 0.8f
;
908 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
909 SkColorSetARGB(204, 120, 255, 120), // Texel color.
910 SK_ColorGREEN
, // Background color.
911 false, // Premultiplied alpha.
913 this->resource_provider_
.get(),
916 SharedQuadState
* color_quad_state
=
917 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
918 SolidColorDrawQuad
* color_quad
=
919 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
920 color_quad
->SetNew(color_quad_state
, rect
, rect
, SK_ColorWHITE
, false);
922 RenderPassList pass_list
;
923 pass_list
.push_back(pass
.Pass());
925 EXPECT_TRUE(this->RunPixelTest(
927 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
928 FuzzyPixelOffByOneComparator(true)));
931 class VideoGLRendererPixelTest
: public GLRendererPixelTest
{
933 void CreateEdgeBleedPass(media::VideoPixelFormat format
,
934 media::ColorSpace color_space
,
935 RenderPassList
* pass_list
) {
936 gfx::Rect
rect(200, 200);
938 RenderPassId
id(1, 1);
939 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
941 // Scale the video up so that bilinear filtering kicks in to sample more
942 // than just nearest neighbor would.
943 gfx::Transform scale_by_2
;
944 scale_by_2
.Scale(2.f
, 2.f
);
945 gfx::Rect
half_rect(100, 100);
946 SharedQuadState
* shared_state
=
947 CreateTestSharedQuadState(scale_by_2
, half_rect
, pass
.get());
949 gfx::Size
background_size(200, 200);
950 gfx::Rect
green_rect(16, 20, 100, 100);
951 gfx::RectF
tex_coord_rect(
952 static_cast<float>(green_rect
.x()) / background_size
.width(),
953 static_cast<float>(green_rect
.y()) / background_size
.height(),
954 static_cast<float>(green_rect
.width()) / background_size
.width(),
955 static_cast<float>(green_rect
.height()) / background_size
.height());
957 // YUV of (149,43,21) should be green (0,255,0) in RGB.
958 // Create a video frame that has a non-green background rect, with a
959 // green sub-rectangle that should be the only thing displayed in
960 // the final image. Bleeding will appear on all four sides of the video
961 // if the tex coords are not clamped.
962 CreateTestYUVVideoDrawQuad_TwoColor(
963 shared_state
, format
, color_space
, false, tex_coord_rect
,
964 background_size
, gfx::Rect(background_size
), 128, 128, 128, green_rect
,
965 149, 43, 21, pass
.get(), video_resource_updater_
.get(),
966 resource_provider_
.get());
967 pass_list
->push_back(pass
.Pass());
970 void SetUp() override
{
971 GLRendererPixelTest::SetUp();
972 video_resource_updater_
.reset(new VideoResourceUpdater(
973 output_surface_
->context_provider(), resource_provider_
.get()));
976 scoped_ptr
<VideoResourceUpdater
> video_resource_updater_
;
979 TEST_F(VideoGLRendererPixelTest
, SimpleYUVRect
) {
980 gfx::Rect
rect(this->device_viewport_size_
);
982 RenderPassId
id(1, 1);
983 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
985 SharedQuadState
* shared_state
=
986 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
988 CreateTestYUVVideoDrawQuad_Striped(shared_state
, media::PIXEL_FORMAT_YV12
,
989 false, gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
990 pass
.get(), video_resource_updater_
.get(),
991 rect
, rect
, resource_provider_
.get());
993 RenderPassList pass_list
;
994 pass_list
.push_back(pass
.Pass());
997 this->RunPixelTest(&pass_list
,
998 base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
999 FuzzyPixelOffByOneComparator(true)));
1002 TEST_F(VideoGLRendererPixelTest
, ClippedYUVRect
) {
1003 gfx::Rect
viewport(this->device_viewport_size_
);
1004 gfx::Rect
draw_rect(this->device_viewport_size_
.width() * 1.5,
1005 this->device_viewport_size_
.height() * 1.5);
1007 RenderPassId
id(1, 1);
1008 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, viewport
);
1010 SharedQuadState
* shared_state
=
1011 CreateTestSharedQuadState(gfx::Transform(), viewport
, pass
.get());
1013 CreateTestYUVVideoDrawQuad_Striped(shared_state
, media::PIXEL_FORMAT_YV12
,
1014 false, gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
1015 pass
.get(), video_resource_updater_
.get(),
1016 draw_rect
, viewport
,
1017 resource_provider_
.get());
1018 RenderPassList pass_list
;
1019 pass_list
.push_back(pass
.Pass());
1021 EXPECT_TRUE(this->RunPixelTest(
1022 &pass_list
, base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png")),
1023 FuzzyPixelOffByOneComparator(true)));
1026 TEST_F(VideoGLRendererPixelTest
, OffsetYUVRect
) {
1027 gfx::Rect
rect(this->device_viewport_size_
);
1029 RenderPassId
id(1, 1);
1030 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1032 SharedQuadState
* shared_state
=
1033 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1035 // Intentionally sets frame format to I420 for testing coverage.
1036 CreateTestYUVVideoDrawQuad_Striped(
1037 shared_state
, media::PIXEL_FORMAT_I420
, false,
1038 gfx::RectF(0.125f
, 0.25f
, 0.75f
, 0.5f
), pass
.get(),
1039 video_resource_updater_
.get(), rect
, rect
, resource_provider_
.get());
1041 RenderPassList pass_list
;
1042 pass_list
.push_back(pass
.Pass());
1044 EXPECT_TRUE(this->RunPixelTest(
1046 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_offset.png")),
1047 FuzzyPixelOffByOneComparator(true)));
1050 TEST_F(VideoGLRendererPixelTest
, SimpleYUVRectBlack
) {
1051 gfx::Rect
rect(this->device_viewport_size_
);
1053 RenderPassId
id(1, 1);
1054 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1056 SharedQuadState
* shared_state
=
1057 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1059 // In MPEG color range YUV values of (15,128,128) should produce black.
1060 CreateTestYUVVideoDrawQuad_Solid(
1061 shared_state
, media::PIXEL_FORMAT_YV12
, media::COLOR_SPACE_UNSPECIFIED
,
1062 false, gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
), 15, 128, 128, pass
.get(),
1063 video_resource_updater_
.get(), rect
, rect
, resource_provider_
.get());
1065 RenderPassList pass_list
;
1066 pass_list
.push_back(pass
.Pass());
1068 // If we didn't get black out of the YUV values above, then we probably have a
1069 // color range issue.
1070 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
1071 base::FilePath(FILE_PATH_LITERAL("black.png")),
1072 FuzzyPixelOffByOneComparator(true)));
1075 TEST_F(VideoGLRendererPixelTest
, SimpleYUVJRect
) {
1076 gfx::Rect
rect(this->device_viewport_size_
);
1078 RenderPassId
id(1, 1);
1079 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1081 SharedQuadState
* shared_state
=
1082 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1084 // YUV of (149,43,21) should be green (0,255,0) in RGB.
1085 CreateTestYUVVideoDrawQuad_Solid(
1086 shared_state
, media::PIXEL_FORMAT_YV12
, media::COLOR_SPACE_JPEG
, false,
1087 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
), 149, 43, 21, pass
.get(),
1088 video_resource_updater_
.get(), rect
, rect
, resource_provider_
.get());
1090 RenderPassList pass_list
;
1091 pass_list
.push_back(pass
.Pass());
1093 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
1094 base::FilePath(FILE_PATH_LITERAL("green.png")),
1095 FuzzyPixelOffByOneComparator(true)));
1098 // Test that a YUV video doesn't bleed outside of its tex coords when the
1099 // tex coord rect is only a partial subrectangle of the coded contents.
1100 TEST_F(VideoGLRendererPixelTest
, YUVEdgeBleed
) {
1101 RenderPassList pass_list
;
1102 CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12
, media::COLOR_SPACE_JPEG
,
1104 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
1105 base::FilePath(FILE_PATH_LITERAL("green.png")),
1106 FuzzyPixelOffByOneComparator(true)));
1109 TEST_F(VideoGLRendererPixelTest
, YUVAEdgeBleed
) {
1110 RenderPassList pass_list
;
1111 CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12A
, media::COLOR_SPACE_UNSPECIFIED
,
1113 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
1114 base::FilePath(FILE_PATH_LITERAL("green.png")),
1115 FuzzyPixelOffByOneComparator(true)));
1118 TEST_F(VideoGLRendererPixelTest
, SimpleYUVJRectGrey
) {
1119 gfx::Rect
rect(this->device_viewport_size_
);
1121 RenderPassId
id(1, 1);
1122 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1124 SharedQuadState
* shared_state
=
1125 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1127 // Dark grey in JPEG color range (in MPEG, this is black).
1128 CreateTestYUVVideoDrawQuad_Solid(
1129 shared_state
, media::PIXEL_FORMAT_YV12
, media::COLOR_SPACE_JPEG
, false,
1130 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
), 15, 128, 128, pass
.get(),
1131 video_resource_updater_
.get(), rect
, rect
, resource_provider_
.get());
1133 RenderPassList pass_list
;
1134 pass_list
.push_back(pass
.Pass());
1137 this->RunPixelTest(&pass_list
,
1138 base::FilePath(FILE_PATH_LITERAL("dark_grey.png")),
1139 FuzzyPixelOffByOneComparator(true)));
1142 TEST_F(VideoGLRendererPixelTest
, SimpleYUVARect
) {
1143 gfx::Rect
rect(this->device_viewport_size_
);
1145 RenderPassId
id(1, 1);
1146 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1148 SharedQuadState
* shared_state
=
1149 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1151 CreateTestYUVVideoDrawQuad_Striped(shared_state
, media::PIXEL_FORMAT_YV12A
,
1152 false, gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
1153 pass
.get(), video_resource_updater_
.get(),
1154 rect
, rect
, resource_provider_
.get());
1156 SolidColorDrawQuad
* color_quad
=
1157 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1158 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorWHITE
, false);
1160 RenderPassList pass_list
;
1161 pass_list
.push_back(pass
.Pass());
1163 EXPECT_TRUE(this->RunPixelTest(
1165 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_alpha.png")),
1166 FuzzyPixelOffByOneComparator(true)));
1169 TEST_F(VideoGLRendererPixelTest
, FullyTransparentYUVARect
) {
1170 gfx::Rect
rect(this->device_viewport_size_
);
1172 RenderPassId
id(1, 1);
1173 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1175 SharedQuadState
* shared_state
=
1176 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1178 CreateTestYUVVideoDrawQuad_Striped(shared_state
, media::PIXEL_FORMAT_YV12A
,
1179 true, gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
1180 pass
.get(), video_resource_updater_
.get(),
1181 rect
, rect
, resource_provider_
.get());
1183 SolidColorDrawQuad
* color_quad
=
1184 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1185 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorBLACK
, false);
1187 RenderPassList pass_list
;
1188 pass_list
.push_back(pass
.Pass());
1190 EXPECT_TRUE(this->RunPixelTest(
1192 base::FilePath(FILE_PATH_LITERAL("black.png")),
1193 ExactPixelComparator(true)));
1196 TYPED_TEST(RendererPixelTest
, FastPassColorFilterAlpha
) {
1197 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1199 RenderPassId
root_pass_id(1, 1);
1200 scoped_ptr
<RenderPass
> root_pass
=
1201 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1203 RenderPassId
child_pass_id(2, 2);
1204 gfx::Rect
pass_rect(this->device_viewport_size_
);
1205 gfx::Transform transform_to_root
;
1206 scoped_ptr
<RenderPass
> child_pass
=
1207 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1209 gfx::Transform quad_to_target_transform
;
1210 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1211 quad_to_target_transform
, viewport_rect
, child_pass
.get());
1212 shared_state
->opacity
= 0.5f
;
1214 gfx::Rect
blue_rect(0,
1216 this->device_viewport_size_
.width(),
1217 this->device_viewport_size_
.height() / 2);
1218 SolidColorDrawQuad
* blue
=
1219 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1220 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1221 gfx::Rect
yellow_rect(0,
1222 this->device_viewport_size_
.height() / 2,
1223 this->device_viewport_size_
.width(),
1224 this->device_viewport_size_
.height() / 2);
1225 SolidColorDrawQuad
* yellow
=
1226 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1227 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1229 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
1230 quad_to_target_transform
, viewport_rect
, child_pass
.get());
1232 SolidColorDrawQuad
* white
=
1233 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1235 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
1237 SharedQuadState
* pass_shared_state
=
1238 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1240 SkScalar matrix
[20];
1241 float amount
= 0.5f
;
1242 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1243 matrix
[1] = 0.715f
- 0.715f
* amount
;
1244 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1245 matrix
[3] = matrix
[4] = 0;
1246 matrix
[5] = 0.213f
- 0.213f
* amount
;
1247 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1248 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1249 matrix
[8] = matrix
[9] = 0;
1250 matrix
[10] = 0.213f
- 0.213f
* amount
;
1251 matrix
[11] = 0.715f
- 0.715f
* amount
;
1252 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1253 matrix
[13] = matrix
[14] = 0;
1254 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1256 skia::RefPtr
<SkColorFilter
> colorFilter(
1257 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1258 skia::RefPtr
<SkImageFilter
> filter
=
1259 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter
.get(), NULL
));
1260 FilterOperations filters
;
1261 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1263 RenderPassDrawQuad
* render_pass_quad
=
1264 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1265 render_pass_quad
->SetNew(pass_shared_state
,
1274 FilterOperations());
1276 RenderPassList pass_list
;
1277 pass_list
.push_back(child_pass
.Pass());
1278 pass_list
.push_back(root_pass
.Pass());
1280 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1281 // renderer so use a fuzzy comparator.
1282 EXPECT_TRUE(this->RunPixelTest(
1284 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1285 FuzzyForSoftwareOnlyPixelComparator
<TypeParam
>(false)));
1288 TYPED_TEST(RendererPixelTest
, FastPassSaturateFilter
) {
1289 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1291 RenderPassId
root_pass_id(1, 1);
1292 scoped_ptr
<RenderPass
> root_pass
=
1293 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1295 RenderPassId
child_pass_id(2, 2);
1296 gfx::Rect
pass_rect(this->device_viewport_size_
);
1297 gfx::Transform transform_to_root
;
1298 scoped_ptr
<RenderPass
> child_pass
=
1299 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1301 gfx::Transform quad_to_target_transform
;
1302 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1303 quad_to_target_transform
, viewport_rect
, child_pass
.get());
1304 shared_state
->opacity
= 0.5f
;
1306 gfx::Rect
blue_rect(0,
1308 this->device_viewport_size_
.width(),
1309 this->device_viewport_size_
.height() / 2);
1310 SolidColorDrawQuad
* blue
=
1311 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1312 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1313 gfx::Rect
yellow_rect(0,
1314 this->device_viewport_size_
.height() / 2,
1315 this->device_viewport_size_
.width(),
1316 this->device_viewport_size_
.height() / 2);
1317 SolidColorDrawQuad
* yellow
=
1318 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1319 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1321 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
1322 quad_to_target_transform
, viewport_rect
, child_pass
.get());
1324 SolidColorDrawQuad
* white
=
1325 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1327 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
1329 SharedQuadState
* pass_shared_state
=
1330 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1332 FilterOperations filters
;
1333 filters
.Append(FilterOperation::CreateSaturateFilter(0.5f
));
1335 RenderPassDrawQuad
* render_pass_quad
=
1336 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1337 render_pass_quad
->SetNew(pass_shared_state
,
1346 FilterOperations());
1348 RenderPassList pass_list
;
1349 pass_list
.push_back(child_pass
.Pass());
1350 pass_list
.push_back(root_pass
.Pass());
1352 // This test blends slightly differently with the software renderer vs. the gl
1353 // renderer so use a fuzzy comparator.
1354 EXPECT_TRUE(this->RunPixelTest(
1355 &pass_list
, base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1356 FuzzyForSoftwareOnlyPixelComparator
<TypeParam
>(false)));
1359 TYPED_TEST(RendererPixelTest
, FastPassFilterChain
) {
1360 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1362 RenderPassId
root_pass_id(1, 1);
1363 scoped_ptr
<RenderPass
> root_pass
=
1364 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1366 RenderPassId
child_pass_id(2, 2);
1367 gfx::Rect
pass_rect(this->device_viewport_size_
);
1368 gfx::Transform transform_to_root
;
1369 scoped_ptr
<RenderPass
> child_pass
=
1370 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1372 gfx::Transform quad_to_target_transform
;
1373 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1374 quad_to_target_transform
, viewport_rect
, child_pass
.get());
1375 shared_state
->opacity
= 0.5f
;
1377 gfx::Rect
blue_rect(0,
1379 this->device_viewport_size_
.width(),
1380 this->device_viewport_size_
.height() / 2);
1381 SolidColorDrawQuad
* blue
=
1382 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1383 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1384 gfx::Rect
yellow_rect(0,
1385 this->device_viewport_size_
.height() / 2,
1386 this->device_viewport_size_
.width(),
1387 this->device_viewport_size_
.height() / 2);
1388 SolidColorDrawQuad
* yellow
=
1389 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1390 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1392 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
1393 quad_to_target_transform
, viewport_rect
, child_pass
.get());
1395 SolidColorDrawQuad
* white
=
1396 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1398 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
1400 SharedQuadState
* pass_shared_state
=
1401 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1403 FilterOperations filters
;
1404 filters
.Append(FilterOperation::CreateGrayscaleFilter(1.f
));
1405 filters
.Append(FilterOperation::CreateBrightnessFilter(0.5f
));
1407 RenderPassDrawQuad
* render_pass_quad
=
1408 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1409 render_pass_quad
->SetNew(pass_shared_state
,
1418 FilterOperations());
1420 RenderPassList pass_list
;
1421 pass_list
.push_back(child_pass
.Pass());
1422 pass_list
.push_back(root_pass
.Pass());
1424 // This test blends slightly differently with the software renderer vs. the gl
1425 // renderer so use a fuzzy comparator.
1426 EXPECT_TRUE(this->RunPixelTest(
1428 base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")),
1429 FuzzyForSoftwareOnlyPixelComparator
<TypeParam
>(false)));
1432 TYPED_TEST(RendererPixelTest
, FastPassColorFilterAlphaTranslation
) {
1433 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1435 RenderPassId
root_pass_id(1, 1);
1436 scoped_ptr
<RenderPass
> root_pass
=
1437 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1439 RenderPassId
child_pass_id(2, 2);
1440 gfx::Rect
pass_rect(this->device_viewport_size_
);
1441 gfx::Transform transform_to_root
;
1442 scoped_ptr
<RenderPass
> child_pass
=
1443 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1445 gfx::Transform quad_to_target_transform
;
1446 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1447 quad_to_target_transform
, viewport_rect
, child_pass
.get());
1448 shared_state
->opacity
= 0.5f
;
1450 gfx::Rect
blue_rect(0,
1452 this->device_viewport_size_
.width(),
1453 this->device_viewport_size_
.height() / 2);
1454 SolidColorDrawQuad
* blue
=
1455 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1456 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1457 gfx::Rect
yellow_rect(0,
1458 this->device_viewport_size_
.height() / 2,
1459 this->device_viewport_size_
.width(),
1460 this->device_viewport_size_
.height() / 2);
1461 SolidColorDrawQuad
* yellow
=
1462 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1463 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1465 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
1466 quad_to_target_transform
, viewport_rect
, child_pass
.get());
1468 SolidColorDrawQuad
* white
=
1469 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1471 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
1473 SharedQuadState
* pass_shared_state
=
1474 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1476 SkScalar matrix
[20];
1477 float amount
= 0.5f
;
1478 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1479 matrix
[1] = 0.715f
- 0.715f
* amount
;
1480 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1483 matrix
[5] = 0.213f
- 0.213f
* amount
;
1484 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1485 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1488 matrix
[10] = 0.213f
- 0.213f
* amount
;
1489 matrix
[11] = 0.715f
- 0.715f
* amount
;
1490 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1493 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1495 skia::RefPtr
<SkColorFilter
> colorFilter(
1496 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1497 skia::RefPtr
<SkImageFilter
> filter
=
1498 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter
.get(), NULL
));
1499 FilterOperations filters
;
1500 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1502 RenderPassDrawQuad
* render_pass_quad
=
1503 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1504 render_pass_quad
->SetNew(pass_shared_state
,
1513 FilterOperations());
1515 RenderPassList pass_list
;
1517 pass_list
.push_back(child_pass
.Pass());
1518 pass_list
.push_back(root_pass
.Pass());
1520 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1521 // renderer so use a fuzzy comparator.
1522 EXPECT_TRUE(this->RunPixelTest(
1524 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
1525 FuzzyForSoftwareOnlyPixelComparator
<TypeParam
>(false)));
1528 TYPED_TEST(RendererPixelTest
, EnlargedRenderPassTexture
) {
1529 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1531 RenderPassId
root_pass_id(1, 1);
1532 scoped_ptr
<RenderPass
> root_pass
=
1533 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1535 RenderPassId
child_pass_id(2, 2);
1536 gfx::Rect
pass_rect(this->device_viewport_size_
);
1537 gfx::Transform transform_to_root
;
1538 scoped_ptr
<RenderPass
> child_pass
=
1539 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1541 gfx::Transform quad_to_target_transform
;
1542 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1543 quad_to_target_transform
, viewport_rect
, child_pass
.get());
1545 gfx::Rect
blue_rect(0,
1547 this->device_viewport_size_
.width(),
1548 this->device_viewport_size_
.height() / 2);
1549 SolidColorDrawQuad
* blue
=
1550 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1551 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1552 gfx::Rect
yellow_rect(0,
1553 this->device_viewport_size_
.height() / 2,
1554 this->device_viewport_size_
.width(),
1555 this->device_viewport_size_
.height() / 2);
1556 SolidColorDrawQuad
* yellow
=
1557 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1558 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1560 SharedQuadState
* pass_shared_state
=
1561 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1562 CreateTestRenderPassDrawQuad(
1563 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
1565 RenderPassList pass_list
;
1566 pass_list
.push_back(child_pass
.Pass());
1567 pass_list
.push_back(root_pass
.Pass());
1569 this->renderer_
->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1571 EXPECT_TRUE(this->RunPixelTest(
1573 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
1574 ExactPixelComparator(true)));
1577 TYPED_TEST(RendererPixelTest
, EnlargedRenderPassTextureWithAntiAliasing
) {
1578 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1580 RenderPassId
root_pass_id(1, 1);
1581 scoped_ptr
<RenderPass
> root_pass
=
1582 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1584 RenderPassId
child_pass_id(2, 2);
1585 gfx::Rect
pass_rect(this->device_viewport_size_
);
1586 gfx::Transform transform_to_root
;
1587 scoped_ptr
<RenderPass
> child_pass
=
1588 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1590 gfx::Transform quad_to_target_transform
;
1591 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1592 quad_to_target_transform
, viewport_rect
, child_pass
.get());
1594 gfx::Rect
blue_rect(0,
1596 this->device_viewport_size_
.width(),
1597 this->device_viewport_size_
.height() / 2);
1598 SolidColorDrawQuad
* blue
=
1599 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1600 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1601 gfx::Rect
yellow_rect(0,
1602 this->device_viewport_size_
.height() / 2,
1603 this->device_viewport_size_
.width(),
1604 this->device_viewport_size_
.height() / 2);
1605 SolidColorDrawQuad
* yellow
=
1606 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1607 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1609 gfx::Transform aa_transform
;
1610 aa_transform
.Translate(0.5, 0.0);
1612 SharedQuadState
* pass_shared_state
=
1613 CreateTestSharedQuadState(aa_transform
, pass_rect
, root_pass
.get());
1614 CreateTestRenderPassDrawQuad(
1615 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
1617 SharedQuadState
* root_shared_state
= CreateTestSharedQuadState(
1618 gfx::Transform(), viewport_rect
, root_pass
.get());
1619 SolidColorDrawQuad
* background
=
1620 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1621 background
->SetNew(root_shared_state
,
1622 gfx::Rect(this->device_viewport_size_
),
1623 gfx::Rect(this->device_viewport_size_
),
1627 RenderPassList pass_list
;
1628 pass_list
.push_back(child_pass
.Pass());
1629 pass_list
.push_back(root_pass
.Pass());
1631 this->renderer_
->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1633 EXPECT_TRUE(this->RunPixelTest(
1635 base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")),
1636 FuzzyPixelOffByOneComparator(true)));
1639 // This tests the case where we have a RenderPass with a mask, but the quad
1640 // for the masked surface does not include the full surface texture.
1641 TYPED_TEST(RendererPixelTest
, RenderPassAndMaskWithPartialQuad
) {
1642 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1644 RenderPassId
root_pass_id(1, 1);
1645 scoped_ptr
<RenderPass
> root_pass
=
1646 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1647 SharedQuadState
* root_pass_shared_state
= CreateTestSharedQuadState(
1648 gfx::Transform(), viewport_rect
, root_pass
.get());
1650 RenderPassId
child_pass_id(2, 2);
1651 gfx::Transform transform_to_root
;
1652 scoped_ptr
<RenderPass
> child_pass
=
1653 CreateTestRenderPass(child_pass_id
, viewport_rect
, transform_to_root
);
1654 SharedQuadState
* child_pass_shared_state
= CreateTestSharedQuadState(
1655 gfx::Transform(), viewport_rect
, child_pass
.get());
1657 // The child render pass is just a green box.
1658 static const SkColor kCSSGreen
= 0xff008000;
1659 SolidColorDrawQuad
* green
=
1660 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1662 child_pass_shared_state
, viewport_rect
, viewport_rect
, kCSSGreen
, false);
1665 gfx::Rect mask_rect
= viewport_rect
;
1668 SkImageInfo::MakeN32Premul(mask_rect
.width(), mask_rect
.height()));
1669 SkCanvas
canvas(bitmap
);
1671 paint
.setStyle(SkPaint::kStroke_Style
);
1672 paint
.setStrokeWidth(SkIntToScalar(4));
1673 paint
.setColor(SK_ColorWHITE
);
1674 canvas
.clear(SK_ColorTRANSPARENT
);
1675 gfx::Rect rect
= mask_rect
;
1676 while (!rect
.IsEmpty()) {
1677 rect
.Inset(6, 6, 4, 4);
1679 SkRect::MakeXYWH(rect
.x(), rect
.y(), rect
.width(), rect
.height()),
1681 rect
.Inset(6, 6, 4, 4);
1684 ResourceId mask_resource_id
= this->resource_provider_
->CreateResource(
1685 mask_rect
.size(), GL_CLAMP_TO_EDGE
,
1686 ResourceProvider::TEXTURE_HINT_IMMUTABLE
, RGBA_8888
);
1688 SkAutoLockPixels
lock(bitmap
);
1689 this->resource_provider_
->CopyToResource(
1690 mask_resource_id
, reinterpret_cast<uint8_t*>(bitmap
.getPixels()),
1694 // This RenderPassDrawQuad does not include the full |viewport_rect| which is
1695 // the size of the child render pass.
1696 gfx::Rect sub_rect
= gfx::Rect(50, 50, 200, 100);
1697 EXPECT_NE(sub_rect
.x(), child_pass
->output_rect
.x());
1698 EXPECT_NE(sub_rect
.y(), child_pass
->output_rect
.y());
1699 EXPECT_NE(sub_rect
.right(), child_pass
->output_rect
.right());
1700 EXPECT_NE(sub_rect
.bottom(), child_pass
->output_rect
.bottom());
1702 // Set up a mask on the RenderPassDrawQuad.
1703 RenderPassDrawQuad
* mask_quad
=
1704 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1705 mask_quad
->SetNew(root_pass_shared_state
,
1710 gfx::Vector2dF(2.f
, 1.f
), // mask_uv_scale
1711 gfx::Size(mask_rect
.size()), // mask_texture_size
1712 FilterOperations(), // foreground filters
1713 gfx::Vector2dF(), // filters scale
1714 FilterOperations()); // background filters
1716 // White background behind the masked render pass.
1717 SolidColorDrawQuad
* white
=
1718 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1719 white
->SetNew(root_pass_shared_state
,
1725 RenderPassList pass_list
;
1726 pass_list
.push_back(child_pass
.Pass());
1727 pass_list
.push_back(root_pass
.Pass());
1729 EXPECT_TRUE(this->RunPixelTest(
1731 base::FilePath(FILE_PATH_LITERAL("mask_bottom_right.png")),
1732 ExactPixelComparator(true)));
1735 template <typename RendererType
>
1736 class RendererPixelTestWithBackgroundFilter
1737 : public RendererPixelTest
<RendererType
> {
1739 void SetUpRenderPassList() {
1740 gfx::Rect
device_viewport_rect(this->device_viewport_size_
);
1742 RenderPassId
root_id(1, 1);
1743 scoped_ptr
<RenderPass
> root_pass
=
1744 CreateTestRootRenderPass(root_id
, device_viewport_rect
);
1745 root_pass
->has_transparent_background
= false;
1747 gfx::Transform identity_quad_to_target_transform
;
1749 RenderPassId
filter_pass_id(2, 1);
1750 gfx::Transform transform_to_root
;
1751 scoped_ptr
<RenderPass
> filter_pass
= CreateTestRenderPass(
1752 filter_pass_id
, filter_pass_layer_rect_
, transform_to_root
);
1754 // A non-visible quad in the filtering render pass.
1756 SharedQuadState
* shared_state
=
1757 CreateTestSharedQuadState(identity_quad_to_target_transform
,
1758 filter_pass_layer_rect_
, filter_pass
.get());
1759 SolidColorDrawQuad
* color_quad
=
1760 filter_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1761 color_quad
->SetNew(shared_state
, filter_pass_layer_rect_
,
1762 filter_pass_layer_rect_
, SK_ColorTRANSPARENT
, false);
1766 SharedQuadState
* shared_state
=
1767 CreateTestSharedQuadState(filter_pass_to_target_transform_
,
1768 filter_pass_layer_rect_
, filter_pass
.get());
1769 RenderPassDrawQuad
* filter_pass_quad
=
1770 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1771 filter_pass_quad
->SetNew(shared_state
, filter_pass_layer_rect_
,
1772 filter_pass_layer_rect_
, filter_pass_id
,
1773 0, // mask_resource_id
1774 gfx::Vector2dF(), // mask_uv_scale
1775 gfx::Size(), // mask_texture_size
1776 FilterOperations(), // filters
1777 gfx::Vector2dF(), // filters_scale
1778 this->background_filters_
);
1781 const int kColumnWidth
= device_viewport_rect
.width() / 3;
1783 gfx::Rect left_rect
= gfx::Rect(0, 0, kColumnWidth
, 20);
1784 for (int i
= 0; left_rect
.y() < device_viewport_rect
.height(); ++i
) {
1785 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1786 identity_quad_to_target_transform
, left_rect
, root_pass
.get());
1787 SolidColorDrawQuad
* color_quad
=
1788 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1790 shared_state
, left_rect
, left_rect
, SK_ColorGREEN
, false);
1791 left_rect
+= gfx::Vector2d(0, left_rect
.height() + 1);
1794 gfx::Rect middle_rect
= gfx::Rect(kColumnWidth
+1, 0, kColumnWidth
, 20);
1795 for (int i
= 0; middle_rect
.y() < device_viewport_rect
.height(); ++i
) {
1796 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1797 identity_quad_to_target_transform
, middle_rect
, root_pass
.get());
1798 SolidColorDrawQuad
* color_quad
=
1799 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1801 shared_state
, middle_rect
, middle_rect
, SK_ColorRED
, false);
1802 middle_rect
+= gfx::Vector2d(0, middle_rect
.height() + 1);
1805 gfx::Rect right_rect
= gfx::Rect((kColumnWidth
+1)*2, 0, kColumnWidth
, 20);
1806 for (int i
= 0; right_rect
.y() < device_viewport_rect
.height(); ++i
) {
1807 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1808 identity_quad_to_target_transform
, right_rect
, root_pass
.get());
1809 SolidColorDrawQuad
* color_quad
=
1810 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1812 shared_state
, right_rect
, right_rect
, SK_ColorBLUE
, false);
1813 right_rect
+= gfx::Vector2d(0, right_rect
.height() + 1);
1816 SharedQuadState
* shared_state
=
1817 CreateTestSharedQuadState(identity_quad_to_target_transform
,
1818 device_viewport_rect
, root_pass
.get());
1819 SolidColorDrawQuad
* background_quad
=
1820 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1821 background_quad
->SetNew(shared_state
,
1822 device_viewport_rect
,
1823 device_viewport_rect
,
1827 pass_list_
.push_back(filter_pass
.Pass());
1828 pass_list_
.push_back(root_pass
.Pass());
1831 RenderPassList pass_list_
;
1832 FilterOperations background_filters_
;
1833 gfx::Transform filter_pass_to_target_transform_
;
1834 gfx::Rect filter_pass_layer_rect_
;
1837 typedef ::testing::Types
<GLRenderer
, SoftwareRenderer
>
1838 BackgroundFilterRendererTypes
;
1839 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter
,
1840 BackgroundFilterRendererTypes
);
1842 typedef RendererPixelTestWithBackgroundFilter
<GLRenderer
>
1843 GLRendererPixelTestWithBackgroundFilter
;
1845 // TODO(skaslev): The software renderer does not support filters yet.
1846 TEST_F(GLRendererPixelTestWithBackgroundFilter
, InvertFilter
) {
1847 this->background_filters_
.Append(
1848 FilterOperation::CreateInvertFilter(1.f
));
1850 this->filter_pass_layer_rect_
= gfx::Rect(this->device_viewport_size_
);
1851 this->filter_pass_layer_rect_
.Inset(12, 14, 16, 18);
1853 this->SetUpRenderPassList();
1854 EXPECT_TRUE(this->RunPixelTest(
1856 base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
1857 ExactPixelComparator(true)));
1860 class ExternalStencilPixelTest
: public GLRendererPixelTest
{
1862 void ClearBackgroundToGreen() {
1863 GLES2Interface
* gl
= output_surface_
->context_provider()->ContextGL();
1864 output_surface_
->EnsureBackbuffer();
1865 output_surface_
->Reshape(device_viewport_size_
, 1);
1866 gl
->ClearColor(0.f
, 1.f
, 0.f
, 1.f
);
1867 gl
->Clear(GL_COLOR_BUFFER_BIT
);
1870 void PopulateStencilBuffer() {
1871 // Set two quadrants of the stencil buffer to 1.
1872 GLES2Interface
* gl
= output_surface_
->context_provider()->ContextGL();
1873 output_surface_
->EnsureBackbuffer();
1874 output_surface_
->Reshape(device_viewport_size_
, 1);
1875 gl
->ClearStencil(0);
1876 gl
->Clear(GL_STENCIL_BUFFER_BIT
);
1877 gl
->Enable(GL_SCISSOR_TEST
);
1878 gl
->ClearStencil(1);
1881 device_viewport_size_
.width() / 2,
1882 device_viewport_size_
.height() / 2);
1883 gl
->Clear(GL_STENCIL_BUFFER_BIT
);
1884 gl
->Scissor(device_viewport_size_
.width() / 2,
1885 device_viewport_size_
.height() / 2,
1886 device_viewport_size_
.width(),
1887 device_viewport_size_
.height());
1888 gl
->Clear(GL_STENCIL_BUFFER_BIT
);
1892 TEST_F(ExternalStencilPixelTest
, StencilTestEnabled
) {
1893 ClearBackgroundToGreen();
1894 PopulateStencilBuffer();
1895 this->EnableExternalStencilTest();
1897 // Draw a blue quad that covers the entire device viewport. It should be
1898 // clipped to the bottom left and top right corners by the external stencil.
1899 gfx::Rect
rect(this->device_viewport_size_
);
1900 RenderPassId
id(1, 1);
1901 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1902 SharedQuadState
* blue_shared_state
=
1903 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1904 SolidColorDrawQuad
* blue
=
1905 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1906 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
1907 pass
->has_transparent_background
= false;
1908 RenderPassList pass_list
;
1909 pass_list
.push_back(pass
.Pass());
1911 EXPECT_TRUE(this->RunPixelTest(
1913 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1914 ExactPixelComparator(true)));
1917 TEST_F(ExternalStencilPixelTest
, StencilTestDisabled
) {
1918 PopulateStencilBuffer();
1920 // Draw a green quad that covers the entire device viewport. The stencil
1921 // buffer should be ignored.
1922 gfx::Rect
rect(this->device_viewport_size_
);
1923 RenderPassId
id(1, 1);
1924 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1925 SharedQuadState
* green_shared_state
=
1926 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1927 SolidColorDrawQuad
* green
=
1928 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1929 green
->SetNew(green_shared_state
, rect
, rect
, SK_ColorGREEN
, false);
1930 RenderPassList pass_list
;
1931 pass_list
.push_back(pass
.Pass());
1933 EXPECT_TRUE(this->RunPixelTest(
1935 base::FilePath(FILE_PATH_LITERAL("green.png")),
1936 ExactPixelComparator(true)));
1939 TEST_F(ExternalStencilPixelTest
, RenderSurfacesIgnoreStencil
) {
1940 // The stencil test should apply only to the final render pass.
1941 ClearBackgroundToGreen();
1942 PopulateStencilBuffer();
1943 this->EnableExternalStencilTest();
1945 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1947 RenderPassId
root_pass_id(1, 1);
1948 scoped_ptr
<RenderPass
> root_pass
=
1949 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1950 root_pass
->has_transparent_background
= false;
1952 RenderPassId
child_pass_id(2, 2);
1953 gfx::Rect
pass_rect(this->device_viewport_size_
);
1954 gfx::Transform transform_to_root
;
1955 scoped_ptr
<RenderPass
> child_pass
=
1956 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1958 gfx::Transform quad_to_target_transform
;
1959 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1960 quad_to_target_transform
, viewport_rect
, child_pass
.get());
1962 gfx::Rect
blue_rect(0,
1964 this->device_viewport_size_
.width(),
1965 this->device_viewport_size_
.height());
1966 SolidColorDrawQuad
* blue
=
1967 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1968 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1970 SharedQuadState
* pass_shared_state
=
1971 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1972 CreateTestRenderPassDrawQuad(
1973 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
1974 RenderPassList pass_list
;
1975 pass_list
.push_back(child_pass
.Pass());
1976 pass_list
.push_back(root_pass
.Pass());
1978 EXPECT_TRUE(this->RunPixelTest(
1980 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1981 ExactPixelComparator(true)));
1984 TEST_F(ExternalStencilPixelTest
, DeviceClip
) {
1985 ClearBackgroundToGreen();
1986 gfx::Rect
clip_rect(gfx::Point(150, 150), gfx::Size(50, 50));
1987 this->ForceDeviceClip(clip_rect
);
1989 // Draw a blue quad that covers the entire device viewport. It should be
1990 // clipped to the bottom right corner by the device clip.
1991 gfx::Rect
rect(this->device_viewport_size_
);
1992 RenderPassId
id(1, 1);
1993 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1994 SharedQuadState
* blue_shared_state
=
1995 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1996 SolidColorDrawQuad
* blue
=
1997 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1998 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
1999 RenderPassList pass_list
;
2000 pass_list
.push_back(pass
.Pass());
2002 EXPECT_TRUE(this->RunPixelTest(
2004 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
2005 ExactPixelComparator(true)));
2008 // Software renderer does not support anti-aliased edges.
2009 TEST_F(GLRendererPixelTest
, AntiAliasing
) {
2010 gfx::Rect
rect(this->device_viewport_size_
);
2012 RenderPassId
id(1, 1);
2013 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
2015 gfx::Transform red_quad_to_target_transform
;
2016 red_quad_to_target_transform
.Rotate(10);
2017 SharedQuadState
* red_shared_state
=
2018 CreateTestSharedQuadState(red_quad_to_target_transform
, rect
, pass
.get());
2020 SolidColorDrawQuad
* red
= pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2021 red
->SetNew(red_shared_state
, rect
, rect
, SK_ColorRED
, false);
2023 gfx::Transform yellow_quad_to_target_transform
;
2024 yellow_quad_to_target_transform
.Rotate(5);
2025 SharedQuadState
* yellow_shared_state
= CreateTestSharedQuadState(
2026 yellow_quad_to_target_transform
, rect
, pass
.get());
2028 SolidColorDrawQuad
* yellow
=
2029 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2030 yellow
->SetNew(yellow_shared_state
, rect
, rect
, SK_ColorYELLOW
, false);
2032 gfx::Transform blue_quad_to_target_transform
;
2033 SharedQuadState
* blue_shared_state
= CreateTestSharedQuadState(
2034 blue_quad_to_target_transform
, rect
, pass
.get());
2036 SolidColorDrawQuad
* blue
=
2037 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2038 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
2040 RenderPassList pass_list
;
2041 pass_list
.push_back(pass
.Pass());
2043 EXPECT_TRUE(this->RunPixelTest(
2045 base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")),
2046 FuzzyPixelOffByOneComparator(true)));
2049 // This test tests that anti-aliasing works for axis aligned quads.
2050 // Anti-aliasing is only supported in the gl renderer.
2051 TEST_F(GLRendererPixelTest
, AxisAligned
) {
2052 gfx::Rect
rect(this->device_viewport_size_
);
2054 RenderPassId
id(1, 1);
2055 gfx::Transform transform_to_root
;
2056 scoped_ptr
<RenderPass
> pass
=
2057 CreateTestRenderPass(id
, rect
, transform_to_root
);
2059 gfx::Transform red_quad_to_target_transform
;
2060 red_quad_to_target_transform
.Translate(50, 50);
2061 red_quad_to_target_transform
.Scale(0.5f
+ 1.0f
/ (rect
.width() * 2.0f
),
2062 0.5f
+ 1.0f
/ (rect
.height() * 2.0f
));
2063 SharedQuadState
* red_shared_state
=
2064 CreateTestSharedQuadState(red_quad_to_target_transform
, rect
, pass
.get());
2066 SolidColorDrawQuad
* red
= pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2067 red
->SetNew(red_shared_state
, rect
, rect
, SK_ColorRED
, false);
2069 gfx::Transform yellow_quad_to_target_transform
;
2070 yellow_quad_to_target_transform
.Translate(25.5f
, 25.5f
);
2071 yellow_quad_to_target_transform
.Scale(0.5f
, 0.5f
);
2072 SharedQuadState
* yellow_shared_state
= CreateTestSharedQuadState(
2073 yellow_quad_to_target_transform
, rect
, pass
.get());
2075 SolidColorDrawQuad
* yellow
=
2076 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2077 yellow
->SetNew(yellow_shared_state
, rect
, rect
, SK_ColorYELLOW
, false);
2079 gfx::Transform blue_quad_to_target_transform
;
2080 SharedQuadState
* blue_shared_state
= CreateTestSharedQuadState(
2081 blue_quad_to_target_transform
, rect
, pass
.get());
2083 SolidColorDrawQuad
* blue
=
2084 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2085 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
2087 RenderPassList pass_list
;
2088 pass_list
.push_back(pass
.Pass());
2090 EXPECT_TRUE(this->RunPixelTest(
2092 base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")),
2093 ExactPixelComparator(true)));
2096 // This test tests that forcing anti-aliasing off works as expected.
2097 // Anti-aliasing is only supported in the gl renderer.
2098 TEST_F(GLRendererPixelTest
, ForceAntiAliasingOff
) {
2099 gfx::Rect
rect(this->device_viewport_size_
);
2101 RenderPassId
id(1, 1);
2102 gfx::Transform transform_to_root
;
2103 scoped_ptr
<RenderPass
> pass
=
2104 CreateTestRenderPass(id
, rect
, transform_to_root
);
2106 gfx::Transform hole_quad_to_target_transform
;
2107 hole_quad_to_target_transform
.Translate(50, 50);
2108 hole_quad_to_target_transform
.Scale(0.5f
+ 1.0f
/ (rect
.width() * 2.0f
),
2109 0.5f
+ 1.0f
/ (rect
.height() * 2.0f
));
2110 SharedQuadState
* hole_shared_state
= CreateTestSharedQuadState(
2111 hole_quad_to_target_transform
, rect
, pass
.get());
2113 SolidColorDrawQuad
* hole
=
2114 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2116 hole_shared_state
, rect
, rect
, rect
, false, SK_ColorTRANSPARENT
, true);
2118 gfx::Transform green_quad_to_target_transform
;
2119 SharedQuadState
* green_shared_state
= CreateTestSharedQuadState(
2120 green_quad_to_target_transform
, rect
, pass
.get());
2122 SolidColorDrawQuad
* green
=
2123 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2124 green
->SetNew(green_shared_state
, rect
, rect
, SK_ColorGREEN
, false);
2126 RenderPassList pass_list
;
2127 pass_list
.push_back(pass
.Pass());
2129 EXPECT_TRUE(this->RunPixelTest(
2131 base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")),
2132 ExactPixelComparator(false)));
2135 TEST_F(GLRendererPixelTest
, AntiAliasingPerspective
) {
2136 gfx::Rect
rect(this->device_viewport_size_
);
2138 scoped_ptr
<RenderPass
> pass
=
2139 CreateTestRootRenderPass(RenderPassId(1, 1), rect
);
2141 gfx::Rect
red_rect(0, 0, 180, 500);
2142 gfx::Transform
red_quad_to_target_transform(
2143 1.0f
, 2.4520f
, 10.6206f
, 19.0f
, 0.0f
, 0.3528f
, 5.9737f
, 9.5f
, 0.0f
,
2144 -0.2250f
, -0.9744f
, 0.0f
, 0.0f
, 0.0225f
, 0.0974f
, 1.0f
);
2145 SharedQuadState
* red_shared_state
= CreateTestSharedQuadState(
2146 red_quad_to_target_transform
, red_rect
, pass
.get());
2147 SolidColorDrawQuad
* red
= pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2148 red
->SetNew(red_shared_state
, red_rect
, red_rect
, SK_ColorRED
, false);
2150 gfx::Rect
green_rect(19, 7, 180, 10);
2151 SharedQuadState
* green_shared_state
=
2152 CreateTestSharedQuadState(gfx::Transform(), green_rect
, pass
.get());
2153 SolidColorDrawQuad
* green
=
2154 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2156 green_shared_state
, green_rect
, green_rect
, SK_ColorGREEN
, false);
2158 SharedQuadState
* blue_shared_state
=
2159 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
2160 SolidColorDrawQuad
* blue
=
2161 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2162 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
2164 RenderPassList pass_list
;
2165 pass_list
.push_back(pass
.Pass());
2167 EXPECT_TRUE(this->RunPixelTest(
2169 base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")),
2170 FuzzyPixelOffByOneComparator(true)));
2173 TYPED_TEST(SoftwareRendererPixelTest
, PictureDrawQuadIdentityScale
) {
2174 gfx::Size
pile_tile_size(1000, 1000);
2175 gfx::Rect
viewport(this->device_viewport_size_
);
2176 // TODO(enne): the renderer should figure this out on its own.
2177 ResourceFormat texture_format
= RGBA_8888
;
2178 bool nearest_neighbor
= false;
2180 RenderPassId
id(1, 1);
2181 gfx::Transform transform_to_root
;
2182 scoped_ptr
<RenderPass
> pass
=
2183 CreateTestRenderPass(id
, viewport
, transform_to_root
);
2185 // One clipped blue quad in the lower right corner. Outside the clip
2186 // is red, which should not appear.
2187 gfx::Rect
blue_rect(gfx::Size(100, 100));
2188 gfx::Rect
blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50));
2190 scoped_ptr
<FakePicturePile
> blue_recording
=
2191 FakePicturePile::CreateFilledPile(pile_tile_size
, blue_rect
.size());
2193 red_paint
.setColor(SK_ColorRED
);
2194 blue_recording
->add_draw_rect_with_paint(blue_rect
, red_paint
);
2196 blue_paint
.setColor(SK_ColorBLUE
);
2197 blue_recording
->add_draw_rect_with_paint(blue_clip_rect
, blue_paint
);
2198 blue_recording
->Rerecord();
2200 scoped_refptr
<FakePicturePileImpl
> blue_pile
=
2201 FakePicturePileImpl::CreateFromPile(blue_recording
.get(), nullptr);
2203 gfx::Vector2d
offset(viewport
.bottom_right() - blue_rect
.bottom_right());
2204 gfx::Transform blue_quad_to_target_transform
;
2205 blue_quad_to_target_transform
.Translate(offset
.x(), offset
.y());
2206 gfx::Rect blue_target_clip_rect
= MathUtil::MapEnclosingClippedRect(
2207 blue_quad_to_target_transform
, blue_clip_rect
);
2208 SharedQuadState
* blue_shared_state
=
2209 CreateTestSharedQuadStateClipped(blue_quad_to_target_transform
, blue_rect
,
2210 blue_target_clip_rect
, pass
.get());
2212 PictureDrawQuad
* blue_quad
= pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2214 blue_quad
->SetNew(blue_shared_state
,
2215 viewport
, // Intentionally bigger than clip.
2216 gfx::Rect(), viewport
, gfx::RectF(viewport
),
2217 viewport
.size(), nearest_neighbor
, texture_format
, viewport
,
2218 1.f
, blue_pile
.get());
2220 // One viewport-filling green quad.
2221 scoped_ptr
<FakePicturePile
> green_recording
=
2222 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
2223 SkPaint green_paint
;
2224 green_paint
.setColor(SK_ColorGREEN
);
2225 green_recording
->add_draw_rect_with_paint(viewport
, green_paint
);
2226 green_recording
->Rerecord();
2227 scoped_refptr
<FakePicturePileImpl
> green_pile
=
2228 FakePicturePileImpl::CreateFromPile(green_recording
.get(), nullptr);
2230 gfx::Transform green_quad_to_target_transform
;
2231 SharedQuadState
* green_shared_state
= CreateTestSharedQuadState(
2232 green_quad_to_target_transform
, viewport
, pass
.get());
2234 PictureDrawQuad
* green_quad
=
2235 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2236 green_quad
->SetNew(green_shared_state
, viewport
, gfx::Rect(), viewport
,
2237 gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
), viewport
.size(),
2238 nearest_neighbor
, texture_format
, viewport
, 1.f
,
2241 RenderPassList pass_list
;
2242 pass_list
.push_back(pass
.Pass());
2244 EXPECT_TRUE(this->RunPixelTest(
2246 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
2247 ExactPixelComparator(true)));
2250 // Not WithSkiaGPUBackend since that path currently requires tiles for opacity.
2251 TYPED_TEST(SoftwareRendererPixelTest
, PictureDrawQuadOpacity
) {
2252 gfx::Size
pile_tile_size(1000, 1000);
2253 gfx::Rect
viewport(this->device_viewport_size_
);
2254 ResourceFormat texture_format
= RGBA_8888
;
2255 bool nearest_neighbor
= false;
2257 RenderPassId
id(1, 1);
2258 gfx::Transform transform_to_root
;
2259 scoped_ptr
<RenderPass
> pass
=
2260 CreateTestRenderPass(id
, viewport
, transform_to_root
);
2262 // One viewport-filling 0.5-opacity green quad.
2263 scoped_ptr
<FakePicturePile
> green_recording
=
2264 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
2265 SkPaint green_paint
;
2266 green_paint
.setColor(SK_ColorGREEN
);
2267 green_recording
->add_draw_rect_with_paint(viewport
, green_paint
);
2268 green_recording
->Rerecord();
2269 scoped_refptr
<FakePicturePileImpl
> green_pile
=
2270 FakePicturePileImpl::CreateFromPile(green_recording
.get(), nullptr);
2272 gfx::Transform green_quad_to_target_transform
;
2273 SharedQuadState
* green_shared_state
= CreateTestSharedQuadState(
2274 green_quad_to_target_transform
, viewport
, pass
.get());
2275 green_shared_state
->opacity
= 0.5f
;
2277 PictureDrawQuad
* green_quad
=
2278 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2279 green_quad
->SetNew(green_shared_state
, viewport
, gfx::Rect(), viewport
,
2280 gfx::RectF(0, 0, 1, 1), viewport
.size(), nearest_neighbor
,
2281 texture_format
, viewport
, 1.f
, green_pile
.get());
2283 // One viewport-filling white quad.
2284 scoped_ptr
<FakePicturePile
> white_recording
=
2285 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
2286 SkPaint white_paint
;
2287 white_paint
.setColor(SK_ColorWHITE
);
2288 white_recording
->add_draw_rect_with_paint(viewport
, white_paint
);
2289 white_recording
->Rerecord();
2290 scoped_refptr
<FakePicturePileImpl
> white_pile
=
2291 FakePicturePileImpl::CreateFromPile(white_recording
.get(), nullptr);
2293 gfx::Transform white_quad_to_target_transform
;
2294 SharedQuadState
* white_shared_state
= CreateTestSharedQuadState(
2295 white_quad_to_target_transform
, viewport
, pass
.get());
2297 PictureDrawQuad
* white_quad
=
2298 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2299 white_quad
->SetNew(white_shared_state
, viewport
, gfx::Rect(), viewport
,
2300 gfx::RectF(0, 0, 1, 1), viewport
.size(), nearest_neighbor
,
2301 texture_format
, viewport
, 1.f
, white_pile
.get());
2303 RenderPassList pass_list
;
2304 pass_list
.push_back(pass
.Pass());
2306 EXPECT_TRUE(this->RunPixelTest(
2308 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
2309 FuzzyPixelOffByOneComparator(true)));
2312 template<typename TypeParam
> bool IsSoftwareRenderer() {
2317 bool IsSoftwareRenderer
<SoftwareRenderer
>() {
2322 bool IsSoftwareRenderer
<SoftwareRendererWithExpandedViewport
>() {
2326 // If we disable image filtering, then a 2x2 bitmap should appear as four
2327 // huge sharp squares.
2328 TYPED_TEST(SoftwareRendererPixelTest
, PictureDrawQuadDisableImageFiltering
) {
2329 // We only care about this in software mode since bilinear filtering is
2330 // cheap in hardware.
2331 if (!IsSoftwareRenderer
<TypeParam
>())
2334 gfx::Size
pile_tile_size(1000, 1000);
2335 gfx::Rect
viewport(this->device_viewport_size_
);
2336 ResourceFormat texture_format
= RGBA_8888
;
2337 bool nearest_neighbor
= false;
2339 RenderPassId
id(1, 1);
2340 gfx::Transform transform_to_root
;
2341 scoped_ptr
<RenderPass
> pass
=
2342 CreateTestRenderPass(id
, viewport
, transform_to_root
);
2344 skia::RefPtr
<SkSurface
> surface
=
2345 skia::AdoptRef(SkSurface::NewRasterN32Premul(2, 2));
2346 ASSERT_NE(surface
, nullptr);
2347 SkCanvas
* canvas
= surface
->getCanvas();
2348 canvas
->drawPoint(0, 0, SK_ColorGREEN
);
2349 canvas
->drawPoint(0, 1, SK_ColorBLUE
);
2350 canvas
->drawPoint(1, 0, SK_ColorBLUE
);
2351 canvas
->drawPoint(1, 1, SK_ColorGREEN
);
2352 skia::RefPtr
<SkImage
> image
= skia::AdoptRef(surface
->newImageSnapshot());
2354 scoped_ptr
<FakePicturePile
> recording
=
2355 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
2357 paint
.setFilterQuality(kLow_SkFilterQuality
);
2358 recording
->add_draw_image_with_paint(image
.get(), gfx::Point(), paint
);
2359 recording
->Rerecord();
2360 scoped_refptr
<FakePicturePileImpl
> pile
=
2361 FakePicturePileImpl::CreateFromPile(recording
.get(), nullptr);
2363 gfx::Transform quad_to_target_transform
;
2364 SharedQuadState
* shared_state
=
2365 CreateTestSharedQuadState(quad_to_target_transform
, viewport
, pass
.get());
2367 PictureDrawQuad
* quad
= pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2368 quad
->SetNew(shared_state
, viewport
, gfx::Rect(), viewport
,
2369 gfx::RectF(0, 0, 2, 2), viewport
.size(), nearest_neighbor
,
2370 texture_format
, viewport
, 1.f
, pile
.get());
2372 RenderPassList pass_list
;
2373 pass_list
.push_back(pass
.Pass());
2375 this->disable_picture_quad_image_filtering_
= true;
2377 EXPECT_TRUE(this->RunPixelTest(
2379 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2380 ExactPixelComparator(true)));
2383 // This disables filtering by setting |nearest_neighbor| on the PictureDrawQuad.
2384 TYPED_TEST(SoftwareRendererPixelTest
, PictureDrawQuadNearestNeighbor
) {
2385 gfx::Size
pile_tile_size(1000, 1000);
2386 gfx::Rect
viewport(this->device_viewport_size_
);
2387 ResourceFormat texture_format
= RGBA_8888
;
2388 bool nearest_neighbor
= true;
2390 RenderPassId
id(1, 1);
2391 gfx::Transform transform_to_root
;
2392 scoped_ptr
<RenderPass
> pass
=
2393 CreateTestRenderPass(id
, viewport
, transform_to_root
);
2395 skia::RefPtr
<SkSurface
> surface
=
2396 skia::AdoptRef(SkSurface::NewRasterN32Premul(2, 2));
2397 ASSERT_NE(surface
, nullptr);
2398 SkCanvas
* canvas
= surface
->getCanvas();
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
);
2403 skia::RefPtr
<SkImage
> image
= skia::AdoptRef(surface
->newImageSnapshot());
2405 scoped_ptr
<FakePicturePile
> recording
=
2406 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
2408 paint
.setFilterQuality(kLow_SkFilterQuality
);
2409 recording
->add_draw_image_with_paint(image
.get(), 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::RectF(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_rectf_with_paint(blue_layer_rect1
, blue_paint
);
2686 recording
->add_draw_rectf_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)