1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/message_loop/message_loop.h"
6 #include "cc/output/gl_renderer.h"
7 #include "cc/quads/draw_quad.h"
8 #include "cc/quads/picture_draw_quad.h"
9 #include "cc/quads/texture_draw_quad.h"
10 #include "cc/resources/video_resource_updater.h"
11 #include "cc/test/fake_picture_pile_impl.h"
12 #include "cc/test/pixel_test.h"
13 #include "gpu/command_buffer/client/gles2_interface.h"
14 #include "media/base/video_frame.h"
15 #include "third_party/skia/include/core/SkColorPriv.h"
16 #include "third_party/skia/include/core/SkImageFilter.h"
17 #include "third_party/skia/include/core/SkMatrix.h"
18 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
19 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
20 #include "ui/gfx/geometry/rect_conversions.h"
22 using gpu::gles2::GLES2Interface
;
27 #if !defined(OS_ANDROID)
28 scoped_ptr
<RenderPass
> CreateTestRootRenderPass(RenderPassId id
,
29 const gfx::Rect
& rect
) {
30 scoped_ptr
<RenderPass
> pass
= RenderPass::Create();
31 const gfx::Rect output_rect
= rect
;
32 const gfx::Rect damage_rect
= rect
;
33 const gfx::Transform transform_to_root_target
;
34 pass
->SetNew(id
, output_rect
, damage_rect
, transform_to_root_target
);
38 scoped_ptr
<RenderPass
> CreateTestRenderPass(
40 const gfx::Rect
& rect
,
41 const gfx::Transform
& transform_to_root_target
) {
42 scoped_ptr
<RenderPass
> pass
= RenderPass::Create();
43 const gfx::Rect output_rect
= rect
;
44 const gfx::Rect damage_rect
= rect
;
45 pass
->SetNew(id
, output_rect
, damage_rect
, transform_to_root_target
);
49 SharedQuadState
* CreateTestSharedQuadState(
50 gfx::Transform content_to_target_transform
,
51 const gfx::Rect
& rect
,
52 RenderPass
* render_pass
) {
53 const gfx::Size content_bounds
= rect
.size();
54 const gfx::Rect visible_content_rect
= rect
;
55 const gfx::Rect clip_rect
= rect
;
56 const bool is_clipped
= false;
57 const float opacity
= 1.0f
;
58 const SkXfermode::Mode blend_mode
= SkXfermode::kSrcOver_Mode
;
59 int sorting_context_id
= 0;
60 SharedQuadState
* shared_state
= render_pass
->CreateAndAppendSharedQuadState();
61 shared_state
->SetAll(content_to_target_transform
,
72 SharedQuadState
* CreateTestSharedQuadStateClipped(
73 gfx::Transform content_to_target_transform
,
74 const gfx::Rect
& rect
,
75 const gfx::Rect
& clip_rect
,
76 RenderPass
* render_pass
) {
77 const gfx::Size content_bounds
= rect
.size();
78 const gfx::Rect visible_content_rect
= clip_rect
;
79 const bool is_clipped
= true;
80 const float opacity
= 1.0f
;
81 const SkXfermode::Mode blend_mode
= SkXfermode::kSrcOver_Mode
;
82 int sorting_context_id
= 0;
83 SharedQuadState
* shared_state
= render_pass
->CreateAndAppendSharedQuadState();
84 shared_state
->SetAll(content_to_target_transform
,
95 void CreateTestRenderPassDrawQuad(const SharedQuadState
* shared_state
,
96 const gfx::Rect
& rect
,
98 RenderPass
* render_pass
) {
99 RenderPassDrawQuad
* quad
=
100 render_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
101 quad
->SetNew(shared_state
,
105 0, // mask_resource_id
106 gfx::Vector2dF(), // mask_uv_scale
107 gfx::Size(), // mask_texture_size
108 FilterOperations(), // foreground filters
109 gfx::Vector2dF(), // filters scale
110 FilterOperations()); // background filters
113 void CreateTestTwoColoredTextureDrawQuad(const gfx::Rect
& rect
,
115 SkColor texel_stripe_color
,
116 SkColor background_color
,
117 bool premultiplied_alpha
,
118 const SharedQuadState
* shared_state
,
119 ResourceProvider
* resource_provider
,
120 RenderPass
* render_pass
) {
121 SkPMColor pixel_color
= premultiplied_alpha
122 ? SkPreMultiplyColor(texel_color
)
123 : SkPackARGB32NoCheck(SkColorGetA(texel_color
),
124 SkColorGetR(texel_color
),
125 SkColorGetG(texel_color
),
126 SkColorGetB(texel_color
));
127 SkPMColor pixel_stripe_color
=
129 ? SkPreMultiplyColor(texel_stripe_color
)
130 : SkPackARGB32NoCheck(SkColorGetA(texel_stripe_color
),
131 SkColorGetR(texel_stripe_color
),
132 SkColorGetG(texel_stripe_color
),
133 SkColorGetB(texel_stripe_color
));
134 std::vector
<uint32_t> pixels(rect
.size().GetArea(), pixel_color
);
135 for (int i
= rect
.height() / 4; i
< (rect
.height() * 3 / 4); ++i
) {
136 for (int k
= rect
.width() / 4; k
< (rect
.width() * 3 / 4); ++k
) {
137 pixels
[i
* rect
.width() + k
] = pixel_stripe_color
;
140 ResourceProvider::ResourceId resource
= resource_provider
->CreateResource(
141 rect
.size(), GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
143 resource_provider
->SetPixels(resource
,
144 reinterpret_cast<uint8_t*>(&pixels
.front()),
145 rect
, rect
, gfx::Vector2d());
147 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
148 const gfx::PointF
uv_top_left(0.0f
, 0.0f
);
149 const gfx::PointF
uv_bottom_right(1.0f
, 1.0f
);
150 const bool flipped
= false;
151 const bool nearest_neighbor
= false;
152 TextureDrawQuad
* quad
=
153 render_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
154 quad
->SetNew(shared_state
, rect
, gfx::Rect(), rect
, resource
,
155 premultiplied_alpha
, uv_top_left
, uv_bottom_right
,
156 background_color
, vertex_opacity
, flipped
, nearest_neighbor
);
159 void CreateTestTextureDrawQuad(const gfx::Rect
& rect
,
161 SkColor background_color
,
162 bool premultiplied_alpha
,
163 const SharedQuadState
* shared_state
,
164 ResourceProvider
* resource_provider
,
165 RenderPass
* render_pass
) {
166 SkPMColor pixel_color
= premultiplied_alpha
?
167 SkPreMultiplyColor(texel_color
) :
168 SkPackARGB32NoCheck(SkColorGetA(texel_color
),
169 SkColorGetR(texel_color
),
170 SkColorGetG(texel_color
),
171 SkColorGetB(texel_color
));
172 size_t num_pixels
= static_cast<size_t>(rect
.width()) * rect
.height();
173 std::vector
<uint32_t> pixels(num_pixels
, pixel_color
);
175 ResourceProvider::ResourceId resource
= resource_provider
->CreateResource(
176 rect
.size(), GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
178 resource_provider
->CopyToResource(
179 resource
, reinterpret_cast<uint8_t*>(&pixels
.front()), rect
.size());
181 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
183 const gfx::PointF
uv_top_left(0.0f
, 0.0f
);
184 const gfx::PointF
uv_bottom_right(1.0f
, 1.0f
);
185 const bool flipped
= false;
186 const bool nearest_neighbor
= false;
187 TextureDrawQuad
* quad
=
188 render_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
189 quad
->SetNew(shared_state
, rect
, gfx::Rect(), rect
, resource
,
190 premultiplied_alpha
, uv_top_left
, uv_bottom_right
,
191 background_color
, vertex_opacity
, flipped
, nearest_neighbor
);
194 void CreateTestYUVVideoDrawQuad_FromVideoFrame(
195 const SharedQuadState
* shared_state
,
196 scoped_refptr
<media::VideoFrame
> video_frame
,
198 const gfx::RectF
& tex_coord_rect
,
199 RenderPass
* render_pass
,
200 VideoResourceUpdater
* video_resource_updater
,
201 const gfx::Rect
& rect
,
202 const gfx::Rect
& visible_rect
,
203 ResourceProvider
* resource_provider
) {
204 const bool with_alpha
= (video_frame
->format() == media::VideoFrame::YV12A
);
205 const YUVVideoDrawQuad::ColorSpace color_space
=
206 (video_frame
->format() == media::VideoFrame::YV12J
207 ? YUVVideoDrawQuad::JPEG
208 : YUVVideoDrawQuad::REC_601
);
209 const gfx::Rect
opaque_rect(0, 0, 0, 0);
212 memset(video_frame
->data(media::VideoFrame::kAPlane
), alpha_value
,
213 video_frame
->stride(media::VideoFrame::kAPlane
) *
214 video_frame
->rows(media::VideoFrame::kAPlane
));
217 VideoFrameExternalResources resources
=
218 video_resource_updater
->CreateExternalResourcesFromVideoFrame(
221 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE
, resources
.type
);
222 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame
->format()),
223 resources
.mailboxes
.size());
224 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame
->format()),
225 resources
.release_callbacks
.size());
227 ResourceProvider::ResourceId y_resource
=
228 resource_provider
->CreateResourceFromTextureMailbox(
229 resources
.mailboxes
[media::VideoFrame::kYPlane
],
230 SingleReleaseCallbackImpl::Create(
231 resources
.release_callbacks
[media::VideoFrame::kYPlane
]));
232 ResourceProvider::ResourceId u_resource
=
233 resource_provider
->CreateResourceFromTextureMailbox(
234 resources
.mailboxes
[media::VideoFrame::kUPlane
],
235 SingleReleaseCallbackImpl::Create(
236 resources
.release_callbacks
[media::VideoFrame::kUPlane
]));
237 ResourceProvider::ResourceId v_resource
=
238 resource_provider
->CreateResourceFromTextureMailbox(
239 resources
.mailboxes
[media::VideoFrame::kVPlane
],
240 SingleReleaseCallbackImpl::Create(
241 resources
.release_callbacks
[media::VideoFrame::kVPlane
]));
242 ResourceProvider::ResourceId a_resource
= 0;
244 a_resource
= resource_provider
->CreateResourceFromTextureMailbox(
245 resources
.mailboxes
[media::VideoFrame::kAPlane
],
246 SingleReleaseCallbackImpl::Create(
247 resources
.release_callbacks
[media::VideoFrame::kAPlane
]));
250 const gfx::Size ya_tex_size
= video_frame
->coded_size();
251 const gfx::Size uv_tex_size
= media::VideoFrame::PlaneSize(
252 video_frame
->format(), media::VideoFrame::kUPlane
,
253 video_frame
->coded_size());
254 DCHECK(uv_tex_size
== media::VideoFrame::PlaneSize(
255 video_frame
->format(), media::VideoFrame::kVPlane
,
256 video_frame
->coded_size()));
258 DCHECK(ya_tex_size
== media::VideoFrame::PlaneSize(
259 video_frame
->format(), media::VideoFrame::kAPlane
,
260 video_frame
->coded_size()));
263 YUVVideoDrawQuad
* yuv_quad
=
264 render_pass
->CreateAndAppendDrawQuad
<YUVVideoDrawQuad
>();
265 yuv_quad
->SetNew(shared_state
, rect
, opaque_rect
, visible_rect
,
266 tex_coord_rect
, ya_tex_size
, uv_tex_size
, y_resource
,
267 u_resource
, v_resource
, a_resource
, color_space
);
270 void CreateTestYUVVideoDrawQuad_Striped(
271 const SharedQuadState
* shared_state
,
272 media::VideoFrame::Format format
,
274 const gfx::RectF
& tex_coord_rect
,
275 RenderPass
* render_pass
,
276 VideoResourceUpdater
* video_resource_updater
,
277 const gfx::Rect
& rect
,
278 const gfx::Rect
& visible_rect
,
279 ResourceProvider
* resource_provider
) {
280 scoped_refptr
<media::VideoFrame
> video_frame
= media::VideoFrame::CreateFrame(
281 format
, rect
.size(), rect
, rect
.size(), base::TimeDelta());
283 // YUV values representing a striped pattern, for validating texture
284 // coordinates for sampling.
288 for (int i
= 0; i
< video_frame
->rows(media::VideoFrame::kYPlane
); ++i
) {
289 uint8_t* y_row
= video_frame
->data(media::VideoFrame::kYPlane
) +
290 video_frame
->stride(media::VideoFrame::kYPlane
) * i
;
291 for (int j
= 0; j
< video_frame
->row_bytes(media::VideoFrame::kYPlane
);
293 y_row
[j
] = (y_value
+= 1);
296 for (int i
= 0; i
< video_frame
->rows(media::VideoFrame::kUPlane
); ++i
) {
297 uint8_t* u_row
= video_frame
->data(media::VideoFrame::kUPlane
) +
298 video_frame
->stride(media::VideoFrame::kUPlane
) * i
;
299 uint8_t* v_row
= video_frame
->data(media::VideoFrame::kVPlane
) +
300 video_frame
->stride(media::VideoFrame::kVPlane
) * i
;
301 for (int j
= 0; j
< video_frame
->row_bytes(media::VideoFrame::kUPlane
);
303 u_row
[j
] = (u_value
+= 3);
304 v_row
[j
] = (v_value
+= 5);
307 uint8 alpha_value
= is_transparent
? 0 : 128;
308 CreateTestYUVVideoDrawQuad_FromVideoFrame(
309 shared_state
, video_frame
, alpha_value
, tex_coord_rect
, render_pass
,
310 video_resource_updater
, rect
, visible_rect
, resource_provider
);
313 // Creates a video frame of size background_size filled with yuv_background,
314 // and then draws a foreground rectangle in a different color on top of
315 // that. The foreground rectangle must have coordinates that are divisible
316 // by 2 because YUV is a block format.
317 void CreateTestYUVVideoDrawQuad_TwoColor(
318 const SharedQuadState
* shared_state
,
319 media::VideoFrame::Format format
,
321 const gfx::RectF
& tex_coord_rect
,
322 const gfx::Size
& background_size
,
323 const gfx::Rect
& visible_rect
,
327 const gfx::Rect
& foreground_rect
,
331 RenderPass
* render_pass
,
332 VideoResourceUpdater
* video_resource_updater
,
333 ResourceProvider
* resource_provider
) {
334 const gfx::Rect
rect(background_size
);
336 scoped_refptr
<media::VideoFrame
> video_frame
=
337 media::VideoFrame::CreateFrame(format
, background_size
, foreground_rect
,
338 foreground_rect
.size(), base::TimeDelta());
340 int planes
[] = {media::VideoFrame::kYPlane
,
341 media::VideoFrame::kUPlane
,
342 media::VideoFrame::kVPlane
};
343 uint8 yuv_background
[] = {y_background
, u_background
, v_background
};
344 uint8 yuv_foreground
[] = {y_foreground
, u_foreground
, v_foreground
};
345 int sample_size
[] = {1, 2, 2};
347 for (int i
= 0; i
< 3; ++i
) {
348 memset(video_frame
->data(planes
[i
]), yuv_background
[i
],
349 video_frame
->stride(planes
[i
]) * video_frame
->rows(planes
[i
]));
352 for (int i
= 0; i
< 3; ++i
) {
353 // Since yuv encoding uses block encoding, widths have to be divisible
354 // by the sample size in order for this function to behave properly.
355 DCHECK_EQ(foreground_rect
.x() % sample_size
[i
], 0);
356 DCHECK_EQ(foreground_rect
.y() % sample_size
[i
], 0);
357 DCHECK_EQ(foreground_rect
.width() % sample_size
[i
], 0);
358 DCHECK_EQ(foreground_rect
.height() % sample_size
[i
], 0);
360 gfx::Rect
sample_rect(foreground_rect
.x() / sample_size
[i
],
361 foreground_rect
.y() / sample_size
[i
],
362 foreground_rect
.width() / sample_size
[i
],
363 foreground_rect
.height() / sample_size
[i
]);
364 for (int y
= sample_rect
.y(); y
< sample_rect
.bottom(); ++y
) {
365 for (int x
= sample_rect
.x(); x
< sample_rect
.right(); ++x
) {
366 size_t offset
= y
* video_frame
->stride(planes
[i
]) + x
;
367 video_frame
->data(planes
[i
])[offset
] = yuv_foreground
[i
];
372 uint8 alpha_value
= 255;
373 CreateTestYUVVideoDrawQuad_FromVideoFrame(
374 shared_state
, video_frame
, alpha_value
, tex_coord_rect
, render_pass
,
375 video_resource_updater
, rect
, visible_rect
, resource_provider
);
378 void CreateTestYUVVideoDrawQuad_Solid(
379 const SharedQuadState
* shared_state
,
380 media::VideoFrame::Format format
,
382 const gfx::RectF
& tex_coord_rect
,
386 RenderPass
* render_pass
,
387 VideoResourceUpdater
* video_resource_updater
,
388 const gfx::Rect
& rect
,
389 const gfx::Rect
& visible_rect
,
390 ResourceProvider
* resource_provider
) {
391 scoped_refptr
<media::VideoFrame
> video_frame
= media::VideoFrame::CreateFrame(
392 format
, rect
.size(), rect
, rect
.size(), base::TimeDelta());
394 // YUV values of a solid, constant, color. Useful for testing that color
395 // space/color range are being handled properly.
396 memset(video_frame
->data(media::VideoFrame::kYPlane
), y
,
397 video_frame
->stride(media::VideoFrame::kYPlane
) *
398 video_frame
->rows(media::VideoFrame::kYPlane
));
399 memset(video_frame
->data(media::VideoFrame::kUPlane
), u
,
400 video_frame
->stride(media::VideoFrame::kUPlane
) *
401 video_frame
->rows(media::VideoFrame::kUPlane
));
402 memset(video_frame
->data(media::VideoFrame::kVPlane
), v
,
403 video_frame
->stride(media::VideoFrame::kVPlane
) *
404 video_frame
->rows(media::VideoFrame::kVPlane
));
406 uint8 alpha_value
= is_transparent
? 0 : 128;
407 CreateTestYUVVideoDrawQuad_FromVideoFrame(
408 shared_state
, video_frame
, alpha_value
, tex_coord_rect
, render_pass
,
409 video_resource_updater
, rect
, visible_rect
, resource_provider
);
412 typedef ::testing::Types
<GLRenderer
,
414 GLRendererWithExpandedViewport
,
415 SoftwareRendererWithExpandedViewport
> RendererTypes
;
416 TYPED_TEST_CASE(RendererPixelTest
, RendererTypes
);
418 template <typename RendererType
>
419 class SoftwareRendererPixelTest
: public RendererPixelTest
<RendererType
> {};
421 typedef ::testing::Types
<SoftwareRenderer
, SoftwareRendererWithExpandedViewport
>
422 SoftwareRendererTypes
;
423 TYPED_TEST_CASE(SoftwareRendererPixelTest
, SoftwareRendererTypes
);
425 template <typename RendererType
>
426 class FuzzyForSoftwareOnlyPixelComparator
: public PixelComparator
{
428 explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha
)
429 : fuzzy_(discard_alpha
), exact_(discard_alpha
) {}
431 bool Compare(const SkBitmap
& actual_bmp
,
432 const SkBitmap
& expected_bmp
) const override
;
435 FuzzyPixelOffByOneComparator fuzzy_
;
436 ExactPixelComparator exact_
;
440 bool FuzzyForSoftwareOnlyPixelComparator
<SoftwareRenderer
>::Compare(
441 const SkBitmap
& actual_bmp
,
442 const SkBitmap
& expected_bmp
) const {
443 return fuzzy_
.Compare(actual_bmp
, expected_bmp
);
447 bool FuzzyForSoftwareOnlyPixelComparator
<
448 SoftwareRendererWithExpandedViewport
>::Compare(
449 const SkBitmap
& actual_bmp
,
450 const SkBitmap
& expected_bmp
) const {
451 return fuzzy_
.Compare(actual_bmp
, expected_bmp
);
454 template<typename RendererType
>
455 bool FuzzyForSoftwareOnlyPixelComparator
<RendererType
>::Compare(
456 const SkBitmap
& actual_bmp
,
457 const SkBitmap
& expected_bmp
) const {
458 return exact_
.Compare(actual_bmp
, expected_bmp
);
461 TYPED_TEST(RendererPixelTest
, SimpleGreenRect
) {
462 gfx::Rect
rect(this->device_viewport_size_
);
464 RenderPassId
id(1, 1);
465 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
467 SharedQuadState
* shared_state
=
468 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
470 SolidColorDrawQuad
* color_quad
=
471 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
472 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorGREEN
, false);
474 RenderPassList pass_list
;
475 pass_list
.push_back(pass
.Pass());
477 EXPECT_TRUE(this->RunPixelTest(
479 base::FilePath(FILE_PATH_LITERAL("green.png")),
480 ExactPixelComparator(true)));
483 TYPED_TEST(RendererPixelTest
, SimpleGreenRect_NonRootRenderPass
) {
484 gfx::Rect
rect(this->device_viewport_size_
);
485 gfx::Rect
small_rect(100, 100);
487 RenderPassId
child_id(2, 1);
488 scoped_ptr
<RenderPass
> child_pass
=
489 CreateTestRenderPass(child_id
, small_rect
, gfx::Transform());
491 SharedQuadState
* child_shared_state
=
492 CreateTestSharedQuadState(gfx::Transform(), small_rect
, child_pass
.get());
494 SolidColorDrawQuad
* color_quad
=
495 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
496 color_quad
->SetNew(child_shared_state
, rect
, rect
, SK_ColorGREEN
, false);
498 RenderPassId
root_id(1, 1);
499 scoped_ptr
<RenderPass
> root_pass
=
500 CreateTestRenderPass(root_id
, rect
, gfx::Transform());
502 SharedQuadState
* root_shared_state
=
503 CreateTestSharedQuadState(gfx::Transform(), rect
, root_pass
.get());
505 CreateTestRenderPassDrawQuad(
506 root_shared_state
, small_rect
, child_id
, root_pass
.get());
508 RenderPass
* child_pass_ptr
= child_pass
.get();
510 RenderPassList pass_list
;
511 pass_list
.push_back(child_pass
.Pass());
512 pass_list
.push_back(root_pass
.Pass());
514 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
517 base::FilePath(FILE_PATH_LITERAL("green_small.png")),
518 ExactPixelComparator(true)));
521 TYPED_TEST(RendererPixelTest
, PremultipliedTextureWithoutBackground
) {
522 gfx::Rect
rect(this->device_viewport_size_
);
524 RenderPassId
id(1, 1);
525 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
527 SharedQuadState
* shared_state
=
528 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
530 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
531 SkColorSetARGB(128, 0, 255, 0), // Texel color.
532 SK_ColorTRANSPARENT
, // Background color.
533 true, // Premultiplied alpha.
535 this->resource_provider_
.get(),
538 SolidColorDrawQuad
* color_quad
=
539 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
540 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorWHITE
, false);
542 RenderPassList pass_list
;
543 pass_list
.push_back(pass
.Pass());
545 EXPECT_TRUE(this->RunPixelTest(
547 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
548 FuzzyPixelOffByOneComparator(true)));
551 TYPED_TEST(RendererPixelTest
, PremultipliedTextureWithBackground
) {
552 gfx::Rect
rect(this->device_viewport_size_
);
554 RenderPassId
id(1, 1);
555 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
557 SharedQuadState
* texture_quad_state
=
558 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
559 texture_quad_state
->opacity
= 0.8f
;
561 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
562 SkColorSetARGB(204, 120, 255, 120), // Texel color.
563 SK_ColorGREEN
, // Background color.
564 true, // Premultiplied alpha.
566 this->resource_provider_
.get(),
569 SharedQuadState
* color_quad_state
=
570 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
571 SolidColorDrawQuad
* color_quad
=
572 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
573 color_quad
->SetNew(color_quad_state
, rect
, rect
, SK_ColorWHITE
, false);
575 RenderPassList pass_list
;
576 pass_list
.push_back(pass
.Pass());
578 EXPECT_TRUE(this->RunPixelTest(
580 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
581 FuzzyPixelOffByOneComparator(true)));
584 template <typename QuadType
>
585 static const base::FilePath::CharType
* IntersectingQuadImage() {
586 return FILE_PATH_LITERAL("intersecting_blue_green_squares.png");
589 const base::FilePath::CharType
* IntersectingQuadImage
<SolidColorDrawQuad
>() {
590 return FILE_PATH_LITERAL("intersecting_blue_green.png");
593 const base::FilePath::CharType
* IntersectingQuadImage
<YUVVideoDrawQuad
>() {
594 return FILE_PATH_LITERAL("intersecting_blue_green_squares_video.png");
597 template <typename TypeParam
>
598 class IntersectingQuadPixelTest
: public RendererPixelTest
<TypeParam
> {
600 void SetupQuadStateAndRenderPass() {
601 // This sets up a pair of draw quads. They are both rotated
602 // relative to the root plane, they are also rotated relative to each other.
603 // The intersect in the middle at a non-perpendicular angle so that any
604 // errors are hopefully magnified.
605 // The quads should intersect correctly, as in the front quad should only
606 // be partially in front of the back quad, and partially behind.
608 viewport_rect_
= gfx::Rect(this->device_viewport_size_
);
609 quad_rect_
= gfx::Rect(0, 0, this->device_viewport_size_
.width(),
610 this->device_viewport_size_
.height() / 2.0);
612 RenderPassId
id(1, 1);
613 render_pass_
= CreateTestRootRenderPass(id
, viewport_rect_
);
615 // Create the front quad rotated on the Z and Y axis.
616 gfx::Transform trans
;
617 trans
.Translate3d(0, 0, 0.707 * this->device_viewport_size_
.width() / 2.0);
618 trans
.RotateAboutZAxis(45.0);
619 trans
.RotateAboutYAxis(45.0);
621 CreateTestSharedQuadState(trans
, viewport_rect_
, render_pass_
.get());
622 front_quad_state_
->clip_rect
= quad_rect_
;
623 // Make sure they end up in a 3d sorting context.
624 front_quad_state_
->sorting_context_id
= 1;
626 // Create the back quad, and rotate on just the y axis. This will intersect
627 // the first quad partially.
628 trans
= gfx::Transform();
629 trans
.Translate3d(0, 0, -0.707 * this->device_viewport_size_
.width() / 2.0);
630 trans
.RotateAboutYAxis(-45.0);
632 CreateTestSharedQuadState(trans
, viewport_rect_
, render_pass_
.get());
633 back_quad_state_
->sorting_context_id
= 1;
634 back_quad_state_
->clip_rect
= quad_rect_
;
636 template <typename T
>
637 void AppendBackgroundAndRunTest(const PixelComparator
& comparator
) {
638 SharedQuadState
* background_quad_state
= CreateTestSharedQuadState(
639 gfx::Transform(), viewport_rect_
, render_pass_
.get());
640 SolidColorDrawQuad
* background_quad
=
641 render_pass_
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
642 background_quad
->SetNew(background_quad_state
, viewport_rect_
,
643 viewport_rect_
, SK_ColorWHITE
, false);
644 pass_list_
.push_back(render_pass_
.Pass());
645 const base::FilePath::CharType
* fileName
= IntersectingQuadImage
<T
>();
647 this->RunPixelTest(&pass_list_
, base::FilePath(fileName
), comparator
));
649 template <typename T
>
650 T
* CreateAndAppendDrawQuad() {
651 return render_pass_
->CreateAndAppendDrawQuad
<T
>();
654 scoped_ptr
<RenderPass
> render_pass_
;
655 gfx::Rect viewport_rect_
;
656 SharedQuadState
* front_quad_state_
;
657 SharedQuadState
* back_quad_state_
;
658 gfx::Rect quad_rect_
;
659 RenderPassList pass_list_
;
662 template <typename TypeParam
>
663 class IntersectingQuadGLPixelTest
664 : public IntersectingQuadPixelTest
<TypeParam
> {
666 void SetUp() override
{
667 IntersectingQuadPixelTest
<TypeParam
>::SetUp();
668 video_resource_updater_
.reset(
669 new VideoResourceUpdater(this->output_surface_
->context_provider(),
670 this->resource_provider_
.get()));
671 video_resource_updater2_
.reset(
672 new VideoResourceUpdater(this->output_surface_
->context_provider(),
673 this->resource_provider_
.get()));
677 scoped_ptr
<VideoResourceUpdater
> video_resource_updater_
;
678 scoped_ptr
<VideoResourceUpdater
> video_resource_updater2_
;
681 template <typename TypeParam
>
682 class IntersectingQuadSoftwareTest
683 : public IntersectingQuadPixelTest
<TypeParam
> {};
685 typedef ::testing::Types
<SoftwareRenderer
, SoftwareRendererWithExpandedViewport
>
686 SoftwareRendererTypes
;
687 typedef ::testing::Types
<GLRenderer
, GLRendererWithExpandedViewport
>
690 TYPED_TEST_CASE(IntersectingQuadPixelTest
, RendererTypes
);
691 TYPED_TEST_CASE(IntersectingQuadGLPixelTest
, GLRendererTypes
);
692 TYPED_TEST_CASE(IntersectingQuadSoftwareTest
, SoftwareRendererTypes
);
694 TYPED_TEST(IntersectingQuadPixelTest
, SolidColorQuads
) {
695 this->SetupQuadStateAndRenderPass();
697 SolidColorDrawQuad
* quad
=
698 this->template CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
699 SolidColorDrawQuad
* quad2
=
700 this->template CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
702 quad
->SetNew(this->front_quad_state_
, this->quad_rect_
, this->quad_rect_
,
703 SK_ColorBLUE
, false);
704 quad2
->SetNew(this->back_quad_state_
, this->quad_rect_
, this->quad_rect_
,
705 SK_ColorGREEN
, false);
706 SCOPED_TRACE("IntersectingSolidColorQuads");
707 this->template AppendBackgroundAndRunTest
<SolidColorDrawQuad
>(
708 FuzzyPixelComparator(false, 2.f
, 0.f
, 256.f
, 256, 0.f
));
711 template <typename TypeParam
>
712 SkColor
GetColor(const SkColor
& color
) {
717 SkColor GetColor
<GLRenderer
>(const SkColor
& color
) {
718 return SkColorSetARGB(SkColorGetA(color
), SkColorGetB(color
),
719 SkColorGetG(color
), SkColorGetR(color
));
722 SkColor GetColor
<GLRendererWithExpandedViewport
>(const SkColor
& color
) {
723 return GetColor
<GLRenderer
>(color
);
726 TYPED_TEST(IntersectingQuadPixelTest
, TexturedQuads
) {
727 this->SetupQuadStateAndRenderPass();
728 CreateTestTwoColoredTextureDrawQuad(
729 this->quad_rect_
, GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 0, 0)),
730 GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT
,
731 true, this->front_quad_state_
, this->resource_provider_
.get(),
732 this->render_pass_
.get());
733 CreateTestTwoColoredTextureDrawQuad(
734 this->quad_rect_
, GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 255, 0)),
735 GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT
,
736 true, this->back_quad_state_
, this->resource_provider_
.get(),
737 this->render_pass_
.get());
739 SCOPED_TRACE("IntersectingTexturedQuads");
740 this->template AppendBackgroundAndRunTest
<TextureDrawQuad
>(
741 FuzzyPixelComparator(false, 2.f
, 0.f
, 256.f
, 256, 0.f
));
744 TYPED_TEST(IntersectingQuadSoftwareTest
, PictureQuads
) {
745 this->SetupQuadStateAndRenderPass();
746 gfx::RectF
outer_rect(this->quad_rect_
);
747 gfx::RectF
inner_rect(this->quad_rect_
.x() + (this->quad_rect_
.width() / 4),
748 this->quad_rect_
.y() + (this->quad_rect_
.height() / 4),
749 this->quad_rect_
.width() / 2,
750 this->quad_rect_
.height() / 2);
753 black_paint
.setColor(SK_ColorBLACK
);
755 blue_paint
.setColor(SK_ColorBLUE
);
757 green_paint
.setColor(SK_ColorGREEN
);
759 scoped_ptr
<FakePicturePile
> blue_recording
=
760 FakePicturePile::CreateFilledPile(gfx::Size(1000, 1000),
761 this->quad_rect_
.size());
762 blue_recording
->add_draw_rect_with_paint(outer_rect
, black_paint
);
763 blue_recording
->add_draw_rect_with_paint(inner_rect
, blue_paint
);
764 blue_recording
->Rerecord();
765 scoped_refptr
<FakePicturePileImpl
> blue_pile
=
766 FakePicturePileImpl::CreateFromPile(blue_recording
.get(), nullptr);
768 PictureDrawQuad
* blue_quad
=
769 this->render_pass_
->template CreateAndAppendDrawQuad
<PictureDrawQuad
>();
771 blue_quad
->SetNew(this->front_quad_state_
, this->quad_rect_
, gfx::Rect(),
772 this->quad_rect_
, this->quad_rect_
, this->quad_rect_
.size(),
773 false, RGBA_8888
, this->quad_rect_
, 1.f
, blue_pile
);
775 scoped_ptr
<FakePicturePile
> green_recording
=
776 FakePicturePile::CreateFilledPile(this->quad_rect_
.size(),
777 this->quad_rect_
.size());
778 green_recording
->add_draw_rect_with_paint(outer_rect
, green_paint
);
779 green_recording
->add_draw_rect_with_paint(inner_rect
, black_paint
);
780 green_recording
->Rerecord();
781 scoped_refptr
<FakePicturePileImpl
> green_pile
=
782 FakePicturePileImpl::CreateFromPile(green_recording
.get(), nullptr);
784 PictureDrawQuad
* green_quad
=
785 this->render_pass_
->template CreateAndAppendDrawQuad
<PictureDrawQuad
>();
786 green_quad
->SetNew(this->back_quad_state_
, this->quad_rect_
, gfx::Rect(),
787 this->quad_rect_
, this->quad_rect_
,
788 this->quad_rect_
.size(), false, RGBA_8888
,
789 this->quad_rect_
, 1.f
, green_pile
);
790 SCOPED_TRACE("IntersectingPictureQuadsPass");
791 this->template AppendBackgroundAndRunTest
<PictureDrawQuad
>(
792 FuzzyPixelComparator(false, 2.f
, 0.f
, 256.f
, 256, 0.f
));
795 TYPED_TEST(IntersectingQuadPixelTest
, RenderPassQuads
) {
796 this->SetupQuadStateAndRenderPass();
797 RenderPassId
child_pass_id1(2, 2);
798 RenderPassId
child_pass_id2(2, 3);
799 scoped_ptr
<RenderPass
> child_pass1
=
800 CreateTestRenderPass(child_pass_id1
, this->quad_rect_
, gfx::Transform());
801 SharedQuadState
* child1_quad_state
= CreateTestSharedQuadState(
802 gfx::Transform(), this->quad_rect_
, child_pass1
.get());
803 scoped_ptr
<RenderPass
> child_pass2
=
804 CreateTestRenderPass(child_pass_id2
, this->quad_rect_
, gfx::Transform());
805 SharedQuadState
* child2_quad_state
= CreateTestSharedQuadState(
806 gfx::Transform(), this->quad_rect_
, child_pass2
.get());
808 CreateTestTwoColoredTextureDrawQuad(
809 this->quad_rect_
, GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 0, 0)),
810 GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT
,
811 true, child1_quad_state
, this->resource_provider_
.get(),
813 CreateTestTwoColoredTextureDrawQuad(
814 this->quad_rect_
, GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 255, 0)),
815 GetColor
<TypeParam
>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT
,
816 true, child2_quad_state
, this->resource_provider_
.get(),
819 CreateTestRenderPassDrawQuad(this->front_quad_state_
, this->quad_rect_
,
820 child_pass_id1
, this->render_pass_
.get());
821 CreateTestRenderPassDrawQuad(this->back_quad_state_
, this->quad_rect_
,
822 child_pass_id2
, this->render_pass_
.get());
824 this->pass_list_
.push_back(child_pass1
.Pass());
825 this->pass_list_
.push_back(child_pass2
.Pass());
826 SCOPED_TRACE("IntersectingRenderQuadsPass");
827 this->template AppendBackgroundAndRunTest
<RenderPassDrawQuad
>(
828 FuzzyPixelComparator(false, 2.f
, 0.f
, 256.f
, 256, 0.f
));
831 TYPED_TEST(IntersectingQuadGLPixelTest
, YUVVideoQuads
) {
832 this->SetupQuadStateAndRenderPass();
833 gfx::Rect
inner_rect(
834 ((this->quad_rect_
.x() + (this->quad_rect_
.width() / 4)) & ~0xF),
835 ((this->quad_rect_
.y() + (this->quad_rect_
.height() / 4)) & ~0xF),
836 (this->quad_rect_
.width() / 2) & ~0xF,
837 (this->quad_rect_
.height() / 2) & ~0xF);
839 CreateTestYUVVideoDrawQuad_TwoColor(
840 this->front_quad_state_
, media::VideoFrame::YV12J
, false,
841 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
), this->quad_rect_
.size(),
842 this->quad_rect_
, 0, 128, 128, inner_rect
, 29, 255, 107,
843 this->render_pass_
.get(), this->video_resource_updater_
.get(),
844 this->resource_provider_
.get());
846 CreateTestYUVVideoDrawQuad_TwoColor(
847 this->back_quad_state_
, media::VideoFrame::YV12J
, false,
848 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
), this->quad_rect_
.size(),
849 this->quad_rect_
, 149, 43, 21, inner_rect
, 0, 128, 128,
850 this->render_pass_
.get(), this->video_resource_updater2_
.get(),
851 this->resource_provider_
.get());
853 SCOPED_TRACE("IntersectingVideoQuads");
854 this->template AppendBackgroundAndRunTest
<YUVVideoDrawQuad
>(
855 FuzzyPixelOffByOneComparator(false));
858 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
859 TEST_F(GLRendererPixelTest
, NonPremultipliedTextureWithoutBackground
) {
860 gfx::Rect
rect(this->device_viewport_size_
);
862 RenderPassId
id(1, 1);
863 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
865 SharedQuadState
* shared_state
=
866 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
868 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
869 SkColorSetARGB(128, 0, 255, 0), // Texel color.
870 SK_ColorTRANSPARENT
, // Background color.
871 false, // Premultiplied alpha.
873 this->resource_provider_
.get(),
876 SolidColorDrawQuad
* color_quad
=
877 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
878 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorWHITE
, false);
880 RenderPassList pass_list
;
881 pass_list
.push_back(pass
.Pass());
883 EXPECT_TRUE(this->RunPixelTest(
885 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
886 FuzzyPixelOffByOneComparator(true)));
889 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
890 TEST_F(GLRendererPixelTest
, NonPremultipliedTextureWithBackground
) {
891 gfx::Rect
rect(this->device_viewport_size_
);
893 RenderPassId
id(1, 1);
894 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
896 SharedQuadState
* texture_quad_state
=
897 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
898 texture_quad_state
->opacity
= 0.8f
;
900 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
901 SkColorSetARGB(204, 120, 255, 120), // Texel color.
902 SK_ColorGREEN
, // Background color.
903 false, // Premultiplied alpha.
905 this->resource_provider_
.get(),
908 SharedQuadState
* color_quad_state
=
909 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
910 SolidColorDrawQuad
* color_quad
=
911 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
912 color_quad
->SetNew(color_quad_state
, rect
, rect
, SK_ColorWHITE
, false);
914 RenderPassList pass_list
;
915 pass_list
.push_back(pass
.Pass());
917 EXPECT_TRUE(this->RunPixelTest(
919 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
920 FuzzyPixelOffByOneComparator(true)));
923 class VideoGLRendererPixelTest
: public GLRendererPixelTest
{
925 void CreateEdgeBleedPass(media::VideoFrame::Format format
,
926 RenderPassList
* pass_list
) {
927 gfx::Rect
rect(200, 200);
929 RenderPassId
id(1, 1);
930 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
932 // Scale the video up so that bilinear filtering kicks in to sample more
933 // than just nearest neighbor would.
934 gfx::Transform scale_by_2
;
935 scale_by_2
.Scale(2.f
, 2.f
);
936 gfx::Rect
half_rect(100, 100);
937 SharedQuadState
* shared_state
=
938 CreateTestSharedQuadState(scale_by_2
, half_rect
, pass
.get());
940 gfx::Size
background_size(200, 200);
941 gfx::Rect
green_rect(16, 20, 100, 100);
942 gfx::RectF
tex_coord_rect(
943 static_cast<float>(green_rect
.x()) / background_size
.width(),
944 static_cast<float>(green_rect
.y()) / background_size
.height(),
945 static_cast<float>(green_rect
.width()) / background_size
.width(),
946 static_cast<float>(green_rect
.height()) / background_size
.height());
948 // YUV of (149,43,21) should be green (0,255,0) in RGB.
949 // Create a video frame that has a non-green background rect, with a
950 // green sub-rectangle that should be the only thing displayed in
951 // the final image. Bleeding will appear on all four sides of the video
952 // if the tex coords are not clamped.
953 CreateTestYUVVideoDrawQuad_TwoColor(
954 shared_state
, format
, false, tex_coord_rect
, background_size
,
955 gfx::Rect(background_size
), 128, 128, 128, green_rect
, 149, 43, 21,
956 pass
.get(), video_resource_updater_
.get(), resource_provider_
.get());
957 pass_list
->push_back(pass
.Pass());
960 void SetUp() override
{
961 GLRendererPixelTest::SetUp();
962 video_resource_updater_
.reset(new VideoResourceUpdater(
963 output_surface_
->context_provider(), resource_provider_
.get()));
966 scoped_ptr
<VideoResourceUpdater
> video_resource_updater_
;
969 TEST_F(VideoGLRendererPixelTest
, SimpleYUVRect
) {
970 gfx::Rect
rect(this->device_viewport_size_
);
972 RenderPassId
id(1, 1);
973 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
975 SharedQuadState
* shared_state
=
976 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
978 CreateTestYUVVideoDrawQuad_Striped(shared_state
, media::VideoFrame::YV12
,
979 false, gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
980 pass
.get(), video_resource_updater_
.get(),
981 rect
, rect
, resource_provider_
.get());
983 RenderPassList pass_list
;
984 pass_list
.push_back(pass
.Pass());
987 this->RunPixelTest(&pass_list
,
988 base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
989 FuzzyPixelOffByOneComparator(true)));
992 TEST_F(VideoGLRendererPixelTest
, ClippedYUVRect
) {
993 gfx::Rect
viewport(this->device_viewport_size_
);
994 gfx::Rect
draw_rect(this->device_viewport_size_
.width() * 1.5,
995 this->device_viewport_size_
.height() * 1.5);
997 RenderPassId
id(1, 1);
998 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, viewport
);
1000 SharedQuadState
* shared_state
=
1001 CreateTestSharedQuadState(gfx::Transform(), viewport
, pass
.get());
1003 CreateTestYUVVideoDrawQuad_Striped(shared_state
, media::VideoFrame::YV12
,
1004 false, gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
1005 pass
.get(), video_resource_updater_
.get(),
1006 draw_rect
, viewport
,
1007 resource_provider_
.get());
1008 RenderPassList pass_list
;
1009 pass_list
.push_back(pass
.Pass());
1011 EXPECT_TRUE(this->RunPixelTest(
1012 &pass_list
, base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png")),
1013 FuzzyPixelOffByOneComparator(true)));
1016 TEST_F(VideoGLRendererPixelTest
, OffsetYUVRect
) {
1017 gfx::Rect
rect(this->device_viewport_size_
);
1019 RenderPassId
id(1, 1);
1020 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1022 SharedQuadState
* shared_state
=
1023 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1025 // Intentionally sets frame format to I420 for testing coverage.
1026 CreateTestYUVVideoDrawQuad_Striped(
1027 shared_state
, media::VideoFrame::I420
, false,
1028 gfx::RectF(0.125f
, 0.25f
, 0.75f
, 0.5f
), pass
.get(),
1029 video_resource_updater_
.get(), rect
, rect
, resource_provider_
.get());
1031 RenderPassList pass_list
;
1032 pass_list
.push_back(pass
.Pass());
1034 EXPECT_TRUE(this->RunPixelTest(
1036 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_offset.png")),
1037 FuzzyPixelOffByOneComparator(true)));
1040 TEST_F(VideoGLRendererPixelTest
, SimpleYUVRectBlack
) {
1041 gfx::Rect
rect(this->device_viewport_size_
);
1043 RenderPassId
id(1, 1);
1044 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1046 SharedQuadState
* shared_state
=
1047 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1049 // In MPEG color range YUV values of (15,128,128) should produce black.
1050 CreateTestYUVVideoDrawQuad_Solid(
1051 shared_state
, media::VideoFrame::YV12
, false,
1052 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
), 15, 128, 128, pass
.get(),
1053 video_resource_updater_
.get(), rect
, rect
, resource_provider_
.get());
1055 RenderPassList pass_list
;
1056 pass_list
.push_back(pass
.Pass());
1058 // If we didn't get black out of the YUV values above, then we probably have a
1059 // color range issue.
1060 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
1061 base::FilePath(FILE_PATH_LITERAL("black.png")),
1062 FuzzyPixelOffByOneComparator(true)));
1065 TEST_F(VideoGLRendererPixelTest
, SimpleYUVJRect
) {
1066 gfx::Rect
rect(this->device_viewport_size_
);
1068 RenderPassId
id(1, 1);
1069 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1071 SharedQuadState
* shared_state
=
1072 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1074 // YUV of (149,43,21) should be green (0,255,0) in RGB.
1075 CreateTestYUVVideoDrawQuad_Solid(
1076 shared_state
, media::VideoFrame::YV12J
, false,
1077 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
), 149, 43, 21, pass
.get(),
1078 video_resource_updater_
.get(), rect
, rect
, resource_provider_
.get());
1080 RenderPassList pass_list
;
1081 pass_list
.push_back(pass
.Pass());
1083 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
1084 base::FilePath(FILE_PATH_LITERAL("green.png")),
1085 FuzzyPixelOffByOneComparator(true)));
1088 // Test that a YUV video doesn't bleed outside of its tex coords when the
1089 // tex coord rect is only a partial subrectangle of the coded contents.
1090 TEST_F(VideoGLRendererPixelTest
, YUVEdgeBleed
) {
1091 RenderPassList pass_list
;
1092 CreateEdgeBleedPass(media::VideoFrame::YV12J
, &pass_list
);
1093 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
1094 base::FilePath(FILE_PATH_LITERAL("green.png")),
1095 FuzzyPixelOffByOneComparator(true)));
1098 TEST_F(VideoGLRendererPixelTest
, YUVAEdgeBleed
) {
1099 RenderPassList pass_list
;
1100 CreateEdgeBleedPass(media::VideoFrame::YV12A
, &pass_list
);
1101 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
1102 base::FilePath(FILE_PATH_LITERAL("green.png")),
1103 FuzzyPixelOffByOneComparator(true)));
1106 TEST_F(VideoGLRendererPixelTest
, SimpleYUVJRectGrey
) {
1107 gfx::Rect
rect(this->device_viewport_size_
);
1109 RenderPassId
id(1, 1);
1110 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1112 SharedQuadState
* shared_state
=
1113 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1115 // Dark grey in JPEG color range (in MPEG, this is black).
1116 CreateTestYUVVideoDrawQuad_Solid(
1117 shared_state
, media::VideoFrame::YV12J
, false,
1118 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
), 15, 128, 128, pass
.get(),
1119 video_resource_updater_
.get(), rect
, rect
, resource_provider_
.get());
1121 RenderPassList pass_list
;
1122 pass_list
.push_back(pass
.Pass());
1125 this->RunPixelTest(&pass_list
,
1126 base::FilePath(FILE_PATH_LITERAL("dark_grey.png")),
1127 FuzzyPixelOffByOneComparator(true)));
1130 TEST_F(VideoGLRendererPixelTest
, SimpleYUVARect
) {
1131 gfx::Rect
rect(this->device_viewport_size_
);
1133 RenderPassId
id(1, 1);
1134 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1136 SharedQuadState
* shared_state
=
1137 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1139 CreateTestYUVVideoDrawQuad_Striped(shared_state
, media::VideoFrame::YV12A
,
1140 false, gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
1141 pass
.get(), video_resource_updater_
.get(),
1142 rect
, rect
, resource_provider_
.get());
1144 SolidColorDrawQuad
* color_quad
=
1145 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1146 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorWHITE
, false);
1148 RenderPassList pass_list
;
1149 pass_list
.push_back(pass
.Pass());
1151 EXPECT_TRUE(this->RunPixelTest(
1153 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_alpha.png")),
1154 FuzzyPixelOffByOneComparator(true)));
1157 TEST_F(VideoGLRendererPixelTest
, FullyTransparentYUVARect
) {
1158 gfx::Rect
rect(this->device_viewport_size_
);
1160 RenderPassId
id(1, 1);
1161 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1163 SharedQuadState
* shared_state
=
1164 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1166 CreateTestYUVVideoDrawQuad_Striped(shared_state
, media::VideoFrame::YV12A
,
1167 true, gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
1168 pass
.get(), video_resource_updater_
.get(),
1169 rect
, rect
, resource_provider_
.get());
1171 SolidColorDrawQuad
* color_quad
=
1172 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1173 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorBLACK
, false);
1175 RenderPassList pass_list
;
1176 pass_list
.push_back(pass
.Pass());
1178 EXPECT_TRUE(this->RunPixelTest(
1180 base::FilePath(FILE_PATH_LITERAL("black.png")),
1181 ExactPixelComparator(true)));
1184 TYPED_TEST(RendererPixelTest
, FastPassColorFilterAlpha
) {
1185 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1187 RenderPassId
root_pass_id(1, 1);
1188 scoped_ptr
<RenderPass
> root_pass
=
1189 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1191 RenderPassId
child_pass_id(2, 2);
1192 gfx::Rect
pass_rect(this->device_viewport_size_
);
1193 gfx::Transform transform_to_root
;
1194 scoped_ptr
<RenderPass
> child_pass
=
1195 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1197 gfx::Transform content_to_target_transform
;
1198 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1199 content_to_target_transform
, viewport_rect
, child_pass
.get());
1200 shared_state
->opacity
= 0.5f
;
1202 gfx::Rect
blue_rect(0,
1204 this->device_viewport_size_
.width(),
1205 this->device_viewport_size_
.height() / 2);
1206 SolidColorDrawQuad
* blue
=
1207 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1208 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1209 gfx::Rect
yellow_rect(0,
1210 this->device_viewport_size_
.height() / 2,
1211 this->device_viewport_size_
.width(),
1212 this->device_viewport_size_
.height() / 2);
1213 SolidColorDrawQuad
* yellow
=
1214 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1215 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1217 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
1218 content_to_target_transform
, viewport_rect
, child_pass
.get());
1220 SolidColorDrawQuad
* white
=
1221 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1223 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
1225 SharedQuadState
* pass_shared_state
=
1226 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1228 SkScalar matrix
[20];
1229 float amount
= 0.5f
;
1230 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1231 matrix
[1] = 0.715f
- 0.715f
* amount
;
1232 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1233 matrix
[3] = matrix
[4] = 0;
1234 matrix
[5] = 0.213f
- 0.213f
* amount
;
1235 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1236 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1237 matrix
[8] = matrix
[9] = 0;
1238 matrix
[10] = 0.213f
- 0.213f
* amount
;
1239 matrix
[11] = 0.715f
- 0.715f
* amount
;
1240 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1241 matrix
[13] = matrix
[14] = 0;
1242 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1244 skia::RefPtr
<SkColorFilter
> colorFilter(
1245 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1246 skia::RefPtr
<SkImageFilter
> filter
=
1247 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter
.get(), NULL
));
1248 FilterOperations filters
;
1249 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1251 RenderPassDrawQuad
* render_pass_quad
=
1252 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1253 render_pass_quad
->SetNew(pass_shared_state
,
1262 FilterOperations());
1264 RenderPassList pass_list
;
1265 pass_list
.push_back(child_pass
.Pass());
1266 pass_list
.push_back(root_pass
.Pass());
1268 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1269 // renderer so use a fuzzy comparator.
1270 EXPECT_TRUE(this->RunPixelTest(
1272 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1273 FuzzyForSoftwareOnlyPixelComparator
<TypeParam
>(false)));
1276 TYPED_TEST(RendererPixelTest
, FastPassSaturateFilter
) {
1277 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1279 RenderPassId
root_pass_id(1, 1);
1280 scoped_ptr
<RenderPass
> root_pass
=
1281 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1283 RenderPassId
child_pass_id(2, 2);
1284 gfx::Rect
pass_rect(this->device_viewport_size_
);
1285 gfx::Transform transform_to_root
;
1286 scoped_ptr
<RenderPass
> child_pass
=
1287 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1289 gfx::Transform content_to_target_transform
;
1290 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1291 content_to_target_transform
, viewport_rect
, child_pass
.get());
1292 shared_state
->opacity
= 0.5f
;
1294 gfx::Rect
blue_rect(0,
1296 this->device_viewport_size_
.width(),
1297 this->device_viewport_size_
.height() / 2);
1298 SolidColorDrawQuad
* blue
=
1299 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1300 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1301 gfx::Rect
yellow_rect(0,
1302 this->device_viewport_size_
.height() / 2,
1303 this->device_viewport_size_
.width(),
1304 this->device_viewport_size_
.height() / 2);
1305 SolidColorDrawQuad
* yellow
=
1306 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1307 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1309 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
1310 content_to_target_transform
, viewport_rect
, child_pass
.get());
1312 SolidColorDrawQuad
* white
=
1313 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1315 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
1317 SharedQuadState
* pass_shared_state
=
1318 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1320 FilterOperations filters
;
1321 filters
.Append(FilterOperation::CreateSaturateFilter(0.5f
));
1323 RenderPassDrawQuad
* render_pass_quad
=
1324 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1325 render_pass_quad
->SetNew(pass_shared_state
,
1334 FilterOperations());
1336 RenderPassList pass_list
;
1337 pass_list
.push_back(child_pass
.Pass());
1338 pass_list
.push_back(root_pass
.Pass());
1340 EXPECT_TRUE(this->RunPixelTest(
1342 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1343 ExactPixelComparator(true)));
1346 TYPED_TEST(RendererPixelTest
, FastPassFilterChain
) {
1347 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1349 RenderPassId
root_pass_id(1, 1);
1350 scoped_ptr
<RenderPass
> root_pass
=
1351 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1353 RenderPassId
child_pass_id(2, 2);
1354 gfx::Rect
pass_rect(this->device_viewport_size_
);
1355 gfx::Transform transform_to_root
;
1356 scoped_ptr
<RenderPass
> child_pass
=
1357 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1359 gfx::Transform content_to_target_transform
;
1360 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1361 content_to_target_transform
, viewport_rect
, child_pass
.get());
1362 shared_state
->opacity
= 0.5f
;
1364 gfx::Rect
blue_rect(0,
1366 this->device_viewport_size_
.width(),
1367 this->device_viewport_size_
.height() / 2);
1368 SolidColorDrawQuad
* blue
=
1369 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1370 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1371 gfx::Rect
yellow_rect(0,
1372 this->device_viewport_size_
.height() / 2,
1373 this->device_viewport_size_
.width(),
1374 this->device_viewport_size_
.height() / 2);
1375 SolidColorDrawQuad
* yellow
=
1376 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1377 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1379 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
1380 content_to_target_transform
, viewport_rect
, child_pass
.get());
1382 SolidColorDrawQuad
* white
=
1383 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1385 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
1387 SharedQuadState
* pass_shared_state
=
1388 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1390 FilterOperations filters
;
1391 filters
.Append(FilterOperation::CreateGrayscaleFilter(1.f
));
1392 filters
.Append(FilterOperation::CreateBrightnessFilter(0.5f
));
1394 RenderPassDrawQuad
* render_pass_quad
=
1395 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1396 render_pass_quad
->SetNew(pass_shared_state
,
1405 FilterOperations());
1407 RenderPassList pass_list
;
1408 pass_list
.push_back(child_pass
.Pass());
1409 pass_list
.push_back(root_pass
.Pass());
1411 EXPECT_TRUE(this->RunPixelTest(
1413 base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")),
1414 ExactPixelComparator(true)));
1417 TYPED_TEST(RendererPixelTest
, FastPassColorFilterAlphaTranslation
) {
1418 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1420 RenderPassId
root_pass_id(1, 1);
1421 scoped_ptr
<RenderPass
> root_pass
=
1422 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1424 RenderPassId
child_pass_id(2, 2);
1425 gfx::Rect
pass_rect(this->device_viewport_size_
);
1426 gfx::Transform transform_to_root
;
1427 scoped_ptr
<RenderPass
> child_pass
=
1428 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1430 gfx::Transform content_to_target_transform
;
1431 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1432 content_to_target_transform
, viewport_rect
, child_pass
.get());
1433 shared_state
->opacity
= 0.5f
;
1435 gfx::Rect
blue_rect(0,
1437 this->device_viewport_size_
.width(),
1438 this->device_viewport_size_
.height() / 2);
1439 SolidColorDrawQuad
* blue
=
1440 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1441 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1442 gfx::Rect
yellow_rect(0,
1443 this->device_viewport_size_
.height() / 2,
1444 this->device_viewport_size_
.width(),
1445 this->device_viewport_size_
.height() / 2);
1446 SolidColorDrawQuad
* yellow
=
1447 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1448 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1450 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
1451 content_to_target_transform
, viewport_rect
, child_pass
.get());
1453 SolidColorDrawQuad
* white
=
1454 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1456 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
1458 SharedQuadState
* pass_shared_state
=
1459 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1461 SkScalar matrix
[20];
1462 float amount
= 0.5f
;
1463 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1464 matrix
[1] = 0.715f
- 0.715f
* amount
;
1465 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1468 matrix
[5] = 0.213f
- 0.213f
* amount
;
1469 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1470 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1473 matrix
[10] = 0.213f
- 0.213f
* amount
;
1474 matrix
[11] = 0.715f
- 0.715f
* amount
;
1475 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1478 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1480 skia::RefPtr
<SkColorFilter
> colorFilter(
1481 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1482 skia::RefPtr
<SkImageFilter
> filter
=
1483 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter
.get(), NULL
));
1484 FilterOperations filters
;
1485 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1487 RenderPassDrawQuad
* render_pass_quad
=
1488 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1489 render_pass_quad
->SetNew(pass_shared_state
,
1498 FilterOperations());
1500 RenderPassList pass_list
;
1502 pass_list
.push_back(child_pass
.Pass());
1503 pass_list
.push_back(root_pass
.Pass());
1505 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1506 // renderer so use a fuzzy comparator.
1507 EXPECT_TRUE(this->RunPixelTest(
1509 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
1510 FuzzyForSoftwareOnlyPixelComparator
<TypeParam
>(false)));
1513 TYPED_TEST(RendererPixelTest
, EnlargedRenderPassTexture
) {
1514 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1516 RenderPassId
root_pass_id(1, 1);
1517 scoped_ptr
<RenderPass
> root_pass
=
1518 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1520 RenderPassId
child_pass_id(2, 2);
1521 gfx::Rect
pass_rect(this->device_viewport_size_
);
1522 gfx::Transform transform_to_root
;
1523 scoped_ptr
<RenderPass
> child_pass
=
1524 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1526 gfx::Transform content_to_target_transform
;
1527 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1528 content_to_target_transform
, viewport_rect
, child_pass
.get());
1530 gfx::Rect
blue_rect(0,
1532 this->device_viewport_size_
.width(),
1533 this->device_viewport_size_
.height() / 2);
1534 SolidColorDrawQuad
* blue
=
1535 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1536 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1537 gfx::Rect
yellow_rect(0,
1538 this->device_viewport_size_
.height() / 2,
1539 this->device_viewport_size_
.width(),
1540 this->device_viewport_size_
.height() / 2);
1541 SolidColorDrawQuad
* yellow
=
1542 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1543 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1545 SharedQuadState
* pass_shared_state
=
1546 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1547 CreateTestRenderPassDrawQuad(
1548 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
1550 RenderPassList pass_list
;
1551 pass_list
.push_back(child_pass
.Pass());
1552 pass_list
.push_back(root_pass
.Pass());
1554 this->renderer_
->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1556 EXPECT_TRUE(this->RunPixelTest(
1558 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
1559 ExactPixelComparator(true)));
1562 TYPED_TEST(RendererPixelTest
, EnlargedRenderPassTextureWithAntiAliasing
) {
1563 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1565 RenderPassId
root_pass_id(1, 1);
1566 scoped_ptr
<RenderPass
> root_pass
=
1567 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1569 RenderPassId
child_pass_id(2, 2);
1570 gfx::Rect
pass_rect(this->device_viewport_size_
);
1571 gfx::Transform transform_to_root
;
1572 scoped_ptr
<RenderPass
> child_pass
=
1573 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1575 gfx::Transform content_to_target_transform
;
1576 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1577 content_to_target_transform
, viewport_rect
, child_pass
.get());
1579 gfx::Rect
blue_rect(0,
1581 this->device_viewport_size_
.width(),
1582 this->device_viewport_size_
.height() / 2);
1583 SolidColorDrawQuad
* blue
=
1584 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1585 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1586 gfx::Rect
yellow_rect(0,
1587 this->device_viewport_size_
.height() / 2,
1588 this->device_viewport_size_
.width(),
1589 this->device_viewport_size_
.height() / 2);
1590 SolidColorDrawQuad
* yellow
=
1591 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1592 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1594 gfx::Transform aa_transform
;
1595 aa_transform
.Translate(0.5, 0.0);
1597 SharedQuadState
* pass_shared_state
=
1598 CreateTestSharedQuadState(aa_transform
, pass_rect
, root_pass
.get());
1599 CreateTestRenderPassDrawQuad(
1600 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
1602 SharedQuadState
* root_shared_state
= CreateTestSharedQuadState(
1603 gfx::Transform(), viewport_rect
, root_pass
.get());
1604 SolidColorDrawQuad
* background
=
1605 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1606 background
->SetNew(root_shared_state
,
1607 gfx::Rect(this->device_viewport_size_
),
1608 gfx::Rect(this->device_viewport_size_
),
1612 RenderPassList pass_list
;
1613 pass_list
.push_back(child_pass
.Pass());
1614 pass_list
.push_back(root_pass
.Pass());
1616 this->renderer_
->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1618 EXPECT_TRUE(this->RunPixelTest(
1620 base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")),
1621 FuzzyPixelOffByOneComparator(true)));
1624 // This tests the case where we have a RenderPass with a mask, but the quad
1625 // for the masked surface does not include the full surface texture.
1626 TYPED_TEST(RendererPixelTest
, RenderPassAndMaskWithPartialQuad
) {
1627 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1629 RenderPassId
root_pass_id(1, 1);
1630 scoped_ptr
<RenderPass
> root_pass
=
1631 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1632 SharedQuadState
* root_pass_shared_state
= CreateTestSharedQuadState(
1633 gfx::Transform(), viewport_rect
, root_pass
.get());
1635 RenderPassId
child_pass_id(2, 2);
1636 gfx::Transform transform_to_root
;
1637 scoped_ptr
<RenderPass
> child_pass
=
1638 CreateTestRenderPass(child_pass_id
, viewport_rect
, transform_to_root
);
1639 SharedQuadState
* child_pass_shared_state
= CreateTestSharedQuadState(
1640 gfx::Transform(), viewport_rect
, child_pass
.get());
1642 // The child render pass is just a green box.
1643 static const SkColor kCSSGreen
= 0xff008000;
1644 SolidColorDrawQuad
* green
=
1645 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1647 child_pass_shared_state
, viewport_rect
, viewport_rect
, kCSSGreen
, false);
1650 gfx::Rect mask_rect
= viewport_rect
;
1653 SkImageInfo::MakeN32Premul(mask_rect
.width(), mask_rect
.height()));
1654 SkCanvas
canvas(bitmap
);
1656 paint
.setStyle(SkPaint::kStroke_Style
);
1657 paint
.setStrokeWidth(SkIntToScalar(4));
1658 paint
.setColor(SK_ColorWHITE
);
1659 canvas
.clear(SK_ColorTRANSPARENT
);
1660 gfx::Rect rect
= mask_rect
;
1661 while (!rect
.IsEmpty()) {
1662 rect
.Inset(6, 6, 4, 4);
1664 SkRect::MakeXYWH(rect
.x(), rect
.y(), rect
.width(), rect
.height()),
1666 rect
.Inset(6, 6, 4, 4);
1669 ResourceProvider::ResourceId mask_resource_id
=
1670 this->resource_provider_
->CreateResource(
1671 mask_rect
.size(), GL_CLAMP_TO_EDGE
,
1672 ResourceProvider::TEXTURE_HINT_IMMUTABLE
, RGBA_8888
);
1674 SkAutoLockPixels
lock(bitmap
);
1675 this->resource_provider_
->CopyToResource(
1676 mask_resource_id
, reinterpret_cast<uint8_t*>(bitmap
.getPixels()),
1680 // This RenderPassDrawQuad does not include the full |viewport_rect| which is
1681 // the size of the child render pass.
1682 gfx::Rect sub_rect
= gfx::Rect(50, 50, 200, 100);
1683 EXPECT_NE(sub_rect
.x(), child_pass
->output_rect
.x());
1684 EXPECT_NE(sub_rect
.y(), child_pass
->output_rect
.y());
1685 EXPECT_NE(sub_rect
.right(), child_pass
->output_rect
.right());
1686 EXPECT_NE(sub_rect
.bottom(), child_pass
->output_rect
.bottom());
1688 // Set up a mask on the RenderPassDrawQuad.
1689 RenderPassDrawQuad
* mask_quad
=
1690 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1691 mask_quad
->SetNew(root_pass_shared_state
,
1696 gfx::Vector2dF(2.f
, 1.f
), // mask_uv_scale
1697 gfx::Size(mask_rect
.size()), // mask_texture_size
1698 FilterOperations(), // foreground filters
1699 gfx::Vector2dF(), // filters scale
1700 FilterOperations()); // background filters
1702 // White background behind the masked render pass.
1703 SolidColorDrawQuad
* white
=
1704 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1705 white
->SetNew(root_pass_shared_state
,
1711 RenderPassList pass_list
;
1712 pass_list
.push_back(child_pass
.Pass());
1713 pass_list
.push_back(root_pass
.Pass());
1715 EXPECT_TRUE(this->RunPixelTest(
1717 base::FilePath(FILE_PATH_LITERAL("mask_bottom_right.png")),
1718 ExactPixelComparator(true)));
1721 template <typename RendererType
>
1722 class RendererPixelTestWithBackgroundFilter
1723 : public RendererPixelTest
<RendererType
> {
1725 void SetUpRenderPassList() {
1726 gfx::Rect
device_viewport_rect(this->device_viewport_size_
);
1728 RenderPassId
root_id(1, 1);
1729 scoped_ptr
<RenderPass
> root_pass
=
1730 CreateTestRootRenderPass(root_id
, device_viewport_rect
);
1731 root_pass
->has_transparent_background
= false;
1733 gfx::Transform identity_content_to_target_transform
;
1735 RenderPassId
filter_pass_id(2, 1);
1736 gfx::Transform transform_to_root
;
1737 scoped_ptr
<RenderPass
> filter_pass
=
1738 CreateTestRenderPass(filter_pass_id
,
1739 filter_pass_content_rect_
,
1742 // A non-visible quad in the filtering render pass.
1744 SharedQuadState
* shared_state
=
1745 CreateTestSharedQuadState(identity_content_to_target_transform
,
1746 filter_pass_content_rect_
,
1748 SolidColorDrawQuad
* color_quad
=
1749 filter_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1750 color_quad
->SetNew(shared_state
,
1751 filter_pass_content_rect_
,
1752 filter_pass_content_rect_
,
1753 SK_ColorTRANSPARENT
,
1758 SharedQuadState
* shared_state
=
1759 CreateTestSharedQuadState(filter_pass_to_target_transform_
,
1760 filter_pass_content_rect_
,
1762 RenderPassDrawQuad
* filter_pass_quad
=
1763 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1764 filter_pass_quad
->SetNew(shared_state
,
1765 filter_pass_content_rect_
,
1766 filter_pass_content_rect_
,
1768 0, // mask_resource_id
1769 gfx::Vector2dF(), // mask_uv_scale
1770 gfx::Size(), // mask_texture_size
1771 FilterOperations(), // filters
1772 gfx::Vector2dF(), // filters_scale
1773 this->background_filters_
);
1776 const int kColumnWidth
= device_viewport_rect
.width() / 3;
1778 gfx::Rect left_rect
= gfx::Rect(0, 0, kColumnWidth
, 20);
1779 for (int i
= 0; left_rect
.y() < device_viewport_rect
.height(); ++i
) {
1780 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1781 identity_content_to_target_transform
, left_rect
, root_pass
.get());
1782 SolidColorDrawQuad
* color_quad
=
1783 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1785 shared_state
, left_rect
, left_rect
, SK_ColorGREEN
, false);
1786 left_rect
+= gfx::Vector2d(0, left_rect
.height() + 1);
1789 gfx::Rect middle_rect
= gfx::Rect(kColumnWidth
+1, 0, kColumnWidth
, 20);
1790 for (int i
= 0; middle_rect
.y() < device_viewport_rect
.height(); ++i
) {
1791 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1792 identity_content_to_target_transform
, middle_rect
, root_pass
.get());
1793 SolidColorDrawQuad
* color_quad
=
1794 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1796 shared_state
, middle_rect
, middle_rect
, SK_ColorRED
, false);
1797 middle_rect
+= gfx::Vector2d(0, middle_rect
.height() + 1);
1800 gfx::Rect right_rect
= gfx::Rect((kColumnWidth
+1)*2, 0, kColumnWidth
, 20);
1801 for (int i
= 0; right_rect
.y() < device_viewport_rect
.height(); ++i
) {
1802 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1803 identity_content_to_target_transform
, right_rect
, root_pass
.get());
1804 SolidColorDrawQuad
* color_quad
=
1805 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1807 shared_state
, right_rect
, right_rect
, SK_ColorBLUE
, false);
1808 right_rect
+= gfx::Vector2d(0, right_rect
.height() + 1);
1811 SharedQuadState
* shared_state
=
1812 CreateTestSharedQuadState(identity_content_to_target_transform
,
1813 device_viewport_rect
,
1815 SolidColorDrawQuad
* background_quad
=
1816 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1817 background_quad
->SetNew(shared_state
,
1818 device_viewport_rect
,
1819 device_viewport_rect
,
1823 pass_list_
.push_back(filter_pass
.Pass());
1824 pass_list_
.push_back(root_pass
.Pass());
1827 RenderPassList pass_list_
;
1828 FilterOperations background_filters_
;
1829 gfx::Transform filter_pass_to_target_transform_
;
1830 gfx::Rect filter_pass_content_rect_
;
1833 typedef ::testing::Types
<GLRenderer
, SoftwareRenderer
>
1834 BackgroundFilterRendererTypes
;
1835 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter
,
1836 BackgroundFilterRendererTypes
);
1838 typedef RendererPixelTestWithBackgroundFilter
<GLRenderer
>
1839 GLRendererPixelTestWithBackgroundFilter
;
1841 // TODO(skaslev): The software renderer does not support filters yet.
1842 TEST_F(GLRendererPixelTestWithBackgroundFilter
, InvertFilter
) {
1843 this->background_filters_
.Append(
1844 FilterOperation::CreateInvertFilter(1.f
));
1846 this->filter_pass_content_rect_
= gfx::Rect(this->device_viewport_size_
);
1847 this->filter_pass_content_rect_
.Inset(12, 14, 16, 18);
1849 this->SetUpRenderPassList();
1850 EXPECT_TRUE(this->RunPixelTest(
1852 base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
1853 ExactPixelComparator(true)));
1856 class ExternalStencilPixelTest
: public GLRendererPixelTest
{
1858 void ClearBackgroundToGreen() {
1859 GLES2Interface
* gl
= output_surface_
->context_provider()->ContextGL();
1860 output_surface_
->EnsureBackbuffer();
1861 output_surface_
->Reshape(device_viewport_size_
, 1);
1862 gl
->ClearColor(0.f
, 1.f
, 0.f
, 1.f
);
1863 gl
->Clear(GL_COLOR_BUFFER_BIT
);
1866 void PopulateStencilBuffer() {
1867 // Set two quadrants of the stencil buffer to 1.
1868 GLES2Interface
* gl
= output_surface_
->context_provider()->ContextGL();
1869 output_surface_
->EnsureBackbuffer();
1870 output_surface_
->Reshape(device_viewport_size_
, 1);
1871 gl
->ClearStencil(0);
1872 gl
->Clear(GL_STENCIL_BUFFER_BIT
);
1873 gl
->Enable(GL_SCISSOR_TEST
);
1874 gl
->ClearStencil(1);
1877 device_viewport_size_
.width() / 2,
1878 device_viewport_size_
.height() / 2);
1879 gl
->Clear(GL_STENCIL_BUFFER_BIT
);
1880 gl
->Scissor(device_viewport_size_
.width() / 2,
1881 device_viewport_size_
.height() / 2,
1882 device_viewport_size_
.width(),
1883 device_viewport_size_
.height());
1884 gl
->Clear(GL_STENCIL_BUFFER_BIT
);
1888 TEST_F(ExternalStencilPixelTest
, StencilTestEnabled
) {
1889 ClearBackgroundToGreen();
1890 PopulateStencilBuffer();
1891 this->EnableExternalStencilTest();
1893 // Draw a blue quad that covers the entire device viewport. It should be
1894 // clipped to the bottom left and top right corners by the external stencil.
1895 gfx::Rect
rect(this->device_viewport_size_
);
1896 RenderPassId
id(1, 1);
1897 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1898 SharedQuadState
* blue_shared_state
=
1899 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1900 SolidColorDrawQuad
* blue
=
1901 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1902 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
1903 pass
->has_transparent_background
= false;
1904 RenderPassList pass_list
;
1905 pass_list
.push_back(pass
.Pass());
1907 EXPECT_TRUE(this->RunPixelTest(
1909 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1910 ExactPixelComparator(true)));
1913 TEST_F(ExternalStencilPixelTest
, StencilTestDisabled
) {
1914 PopulateStencilBuffer();
1916 // Draw a green quad that covers the entire device viewport. The stencil
1917 // buffer should be ignored.
1918 gfx::Rect
rect(this->device_viewport_size_
);
1919 RenderPassId
id(1, 1);
1920 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1921 SharedQuadState
* green_shared_state
=
1922 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1923 SolidColorDrawQuad
* green
=
1924 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1925 green
->SetNew(green_shared_state
, rect
, rect
, SK_ColorGREEN
, false);
1926 RenderPassList pass_list
;
1927 pass_list
.push_back(pass
.Pass());
1929 EXPECT_TRUE(this->RunPixelTest(
1931 base::FilePath(FILE_PATH_LITERAL("green.png")),
1932 ExactPixelComparator(true)));
1935 TEST_F(ExternalStencilPixelTest
, RenderSurfacesIgnoreStencil
) {
1936 // The stencil test should apply only to the final render pass.
1937 ClearBackgroundToGreen();
1938 PopulateStencilBuffer();
1939 this->EnableExternalStencilTest();
1941 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1943 RenderPassId
root_pass_id(1, 1);
1944 scoped_ptr
<RenderPass
> root_pass
=
1945 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1946 root_pass
->has_transparent_background
= false;
1948 RenderPassId
child_pass_id(2, 2);
1949 gfx::Rect
pass_rect(this->device_viewport_size_
);
1950 gfx::Transform transform_to_root
;
1951 scoped_ptr
<RenderPass
> child_pass
=
1952 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1954 gfx::Transform content_to_target_transform
;
1955 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1956 content_to_target_transform
, viewport_rect
, child_pass
.get());
1958 gfx::Rect
blue_rect(0,
1960 this->device_viewport_size_
.width(),
1961 this->device_viewport_size_
.height());
1962 SolidColorDrawQuad
* blue
=
1963 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1964 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1966 SharedQuadState
* pass_shared_state
=
1967 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1968 CreateTestRenderPassDrawQuad(
1969 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
1970 RenderPassList pass_list
;
1971 pass_list
.push_back(child_pass
.Pass());
1972 pass_list
.push_back(root_pass
.Pass());
1974 EXPECT_TRUE(this->RunPixelTest(
1976 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1977 ExactPixelComparator(true)));
1980 TEST_F(ExternalStencilPixelTest
, DeviceClip
) {
1981 ClearBackgroundToGreen();
1982 gfx::Rect
clip_rect(gfx::Point(150, 150), gfx::Size(50, 50));
1983 this->ForceDeviceClip(clip_rect
);
1985 // Draw a blue quad that covers the entire device viewport. It should be
1986 // clipped to the bottom right corner by the device clip.
1987 gfx::Rect
rect(this->device_viewport_size_
);
1988 RenderPassId
id(1, 1);
1989 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1990 SharedQuadState
* blue_shared_state
=
1991 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1992 SolidColorDrawQuad
* blue
=
1993 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1994 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
1995 RenderPassList pass_list
;
1996 pass_list
.push_back(pass
.Pass());
1998 EXPECT_TRUE(this->RunPixelTest(
2000 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
2001 ExactPixelComparator(true)));
2004 // Software renderer does not support anti-aliased edges.
2005 TEST_F(GLRendererPixelTest
, AntiAliasing
) {
2006 gfx::Rect
rect(this->device_viewport_size_
);
2008 RenderPassId
id(1, 1);
2009 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
2011 gfx::Transform red_content_to_target_transform
;
2012 red_content_to_target_transform
.Rotate(10);
2013 SharedQuadState
* red_shared_state
= CreateTestSharedQuadState(
2014 red_content_to_target_transform
, rect
, pass
.get());
2016 SolidColorDrawQuad
* red
= pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2017 red
->SetNew(red_shared_state
, rect
, rect
, SK_ColorRED
, false);
2019 gfx::Transform yellow_content_to_target_transform
;
2020 yellow_content_to_target_transform
.Rotate(5);
2021 SharedQuadState
* yellow_shared_state
= CreateTestSharedQuadState(
2022 yellow_content_to_target_transform
, rect
, pass
.get());
2024 SolidColorDrawQuad
* yellow
=
2025 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2026 yellow
->SetNew(yellow_shared_state
, rect
, rect
, SK_ColorYELLOW
, false);
2028 gfx::Transform blue_content_to_target_transform
;
2029 SharedQuadState
* blue_shared_state
= CreateTestSharedQuadState(
2030 blue_content_to_target_transform
, rect
, pass
.get());
2032 SolidColorDrawQuad
* blue
=
2033 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2034 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
2036 RenderPassList pass_list
;
2037 pass_list
.push_back(pass
.Pass());
2039 EXPECT_TRUE(this->RunPixelTest(
2041 base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")),
2042 FuzzyPixelOffByOneComparator(true)));
2045 // This test tests that anti-aliasing works for axis aligned quads.
2046 // Anti-aliasing is only supported in the gl renderer.
2047 TEST_F(GLRendererPixelTest
, AxisAligned
) {
2048 gfx::Rect
rect(this->device_viewport_size_
);
2050 RenderPassId
id(1, 1);
2051 gfx::Transform transform_to_root
;
2052 scoped_ptr
<RenderPass
> pass
=
2053 CreateTestRenderPass(id
, rect
, transform_to_root
);
2055 gfx::Transform red_content_to_target_transform
;
2056 red_content_to_target_transform
.Translate(50, 50);
2057 red_content_to_target_transform
.Scale(
2058 0.5f
+ 1.0f
/ (rect
.width() * 2.0f
),
2059 0.5f
+ 1.0f
/ (rect
.height() * 2.0f
));
2060 SharedQuadState
* red_shared_state
= CreateTestSharedQuadState(
2061 red_content_to_target_transform
, rect
, pass
.get());
2063 SolidColorDrawQuad
* red
= pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2064 red
->SetNew(red_shared_state
, rect
, rect
, SK_ColorRED
, false);
2066 gfx::Transform yellow_content_to_target_transform
;
2067 yellow_content_to_target_transform
.Translate(25.5f
, 25.5f
);
2068 yellow_content_to_target_transform
.Scale(0.5f
, 0.5f
);
2069 SharedQuadState
* yellow_shared_state
= CreateTestSharedQuadState(
2070 yellow_content_to_target_transform
, rect
, pass
.get());
2072 SolidColorDrawQuad
* yellow
=
2073 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2074 yellow
->SetNew(yellow_shared_state
, rect
, rect
, SK_ColorYELLOW
, false);
2076 gfx::Transform blue_content_to_target_transform
;
2077 SharedQuadState
* blue_shared_state
= CreateTestSharedQuadState(
2078 blue_content_to_target_transform
, rect
, pass
.get());
2080 SolidColorDrawQuad
* blue
=
2081 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2082 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
2084 RenderPassList pass_list
;
2085 pass_list
.push_back(pass
.Pass());
2087 EXPECT_TRUE(this->RunPixelTest(
2089 base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")),
2090 ExactPixelComparator(true)));
2093 // This test tests that forcing anti-aliasing off works as expected.
2094 // Anti-aliasing is only supported in the gl renderer.
2095 TEST_F(GLRendererPixelTest
, ForceAntiAliasingOff
) {
2096 gfx::Rect
rect(this->device_viewport_size_
);
2098 RenderPassId
id(1, 1);
2099 gfx::Transform transform_to_root
;
2100 scoped_ptr
<RenderPass
> pass
=
2101 CreateTestRenderPass(id
, rect
, transform_to_root
);
2103 gfx::Transform hole_content_to_target_transform
;
2104 hole_content_to_target_transform
.Translate(50, 50);
2105 hole_content_to_target_transform
.Scale(
2106 0.5f
+ 1.0f
/ (rect
.width() * 2.0f
),
2107 0.5f
+ 1.0f
/ (rect
.height() * 2.0f
));
2108 SharedQuadState
* hole_shared_state
= CreateTestSharedQuadState(
2109 hole_content_to_target_transform
, rect
, pass
.get());
2111 SolidColorDrawQuad
* hole
=
2112 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2114 hole_shared_state
, rect
, rect
, rect
, false, SK_ColorTRANSPARENT
, true);
2116 gfx::Transform green_content_to_target_transform
;
2117 SharedQuadState
* green_shared_state
= CreateTestSharedQuadState(
2118 green_content_to_target_transform
, rect
, pass
.get());
2120 SolidColorDrawQuad
* green
=
2121 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2122 green
->SetNew(green_shared_state
, rect
, rect
, SK_ColorGREEN
, false);
2124 RenderPassList pass_list
;
2125 pass_list
.push_back(pass
.Pass());
2127 EXPECT_TRUE(this->RunPixelTest(
2129 base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")),
2130 ExactPixelComparator(false)));
2133 TEST_F(GLRendererPixelTest
, AntiAliasingPerspective
) {
2134 gfx::Rect
rect(this->device_viewport_size_
);
2136 scoped_ptr
<RenderPass
> pass
=
2137 CreateTestRootRenderPass(RenderPassId(1, 1), rect
);
2139 gfx::Rect
red_rect(0, 0, 180, 500);
2140 gfx::Transform
red_content_to_target_transform(
2141 1.0f
, 2.4520f
, 10.6206f
, 19.0f
,
2142 0.0f
, 0.3528f
, 5.9737f
, 9.5f
,
2143 0.0f
, -0.2250f
, -0.9744f
, 0.0f
,
2144 0.0f
, 0.0225f
, 0.0974f
, 1.0f
);
2145 SharedQuadState
* red_shared_state
= CreateTestSharedQuadState(
2146 red_content_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::Transform blue_content_to_target_transform
;
2204 gfx::Vector2d
offset(viewport
.bottom_right() - blue_rect
.bottom_right());
2205 blue_content_to_target_transform
.Translate(offset
.x(), offset
.y());
2206 gfx::RectF blue_scissor_rect
= blue_clip_rect
;
2207 blue_content_to_target_transform
.TransformRect(&blue_scissor_rect
);
2208 SharedQuadState
* blue_shared_state
=
2209 CreateTestSharedQuadStateClipped(blue_content_to_target_transform
,
2211 gfx::ToEnclosingRect(blue_scissor_rect
),
2214 PictureDrawQuad
* blue_quad
= pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2216 blue_quad
->SetNew(blue_shared_state
,
2217 viewport
, // Intentionally bigger than clip.
2218 gfx::Rect(), viewport
, gfx::RectF(viewport
),
2219 viewport
.size(), nearest_neighbor
, texture_format
, viewport
,
2220 1.f
, blue_pile
.get());
2222 // One viewport-filling green quad.
2223 scoped_ptr
<FakePicturePile
> green_recording
=
2224 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
2225 SkPaint green_paint
;
2226 green_paint
.setColor(SK_ColorGREEN
);
2227 green_recording
->add_draw_rect_with_paint(viewport
, green_paint
);
2228 green_recording
->Rerecord();
2229 scoped_refptr
<FakePicturePileImpl
> green_pile
=
2230 FakePicturePileImpl::CreateFromPile(green_recording
.get(), nullptr);
2232 gfx::Transform green_content_to_target_transform
;
2233 SharedQuadState
* green_shared_state
= CreateTestSharedQuadState(
2234 green_content_to_target_transform
, viewport
, pass
.get());
2236 PictureDrawQuad
* green_quad
=
2237 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2238 green_quad
->SetNew(green_shared_state
, viewport
, gfx::Rect(), viewport
,
2239 gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
), viewport
.size(),
2240 nearest_neighbor
, texture_format
, viewport
, 1.f
,
2243 RenderPassList pass_list
;
2244 pass_list
.push_back(pass
.Pass());
2246 EXPECT_TRUE(this->RunPixelTest(
2248 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
2249 ExactPixelComparator(true)));
2252 // Not WithSkiaGPUBackend since that path currently requires tiles for opacity.
2253 TYPED_TEST(SoftwareRendererPixelTest
, PictureDrawQuadOpacity
) {
2254 gfx::Size
pile_tile_size(1000, 1000);
2255 gfx::Rect
viewport(this->device_viewport_size_
);
2256 ResourceFormat texture_format
= RGBA_8888
;
2257 bool nearest_neighbor
= false;
2259 RenderPassId
id(1, 1);
2260 gfx::Transform transform_to_root
;
2261 scoped_ptr
<RenderPass
> pass
=
2262 CreateTestRenderPass(id
, viewport
, transform_to_root
);
2264 // One viewport-filling 0.5-opacity green quad.
2265 scoped_ptr
<FakePicturePile
> green_recording
=
2266 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
2267 SkPaint green_paint
;
2268 green_paint
.setColor(SK_ColorGREEN
);
2269 green_recording
->add_draw_rect_with_paint(viewport
, green_paint
);
2270 green_recording
->Rerecord();
2271 scoped_refptr
<FakePicturePileImpl
> green_pile
=
2272 FakePicturePileImpl::CreateFromPile(green_recording
.get(), nullptr);
2274 gfx::Transform green_content_to_target_transform
;
2275 SharedQuadState
* green_shared_state
= CreateTestSharedQuadState(
2276 green_content_to_target_transform
, viewport
, pass
.get());
2277 green_shared_state
->opacity
= 0.5f
;
2279 PictureDrawQuad
* green_quad
=
2280 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2281 green_quad
->SetNew(green_shared_state
, viewport
, gfx::Rect(), viewport
,
2282 gfx::RectF(0, 0, 1, 1), viewport
.size(), nearest_neighbor
,
2283 texture_format
, viewport
, 1.f
, green_pile
.get());
2285 // One viewport-filling white quad.
2286 scoped_ptr
<FakePicturePile
> white_recording
=
2287 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
2288 SkPaint white_paint
;
2289 white_paint
.setColor(SK_ColorWHITE
);
2290 white_recording
->add_draw_rect_with_paint(viewport
, white_paint
);
2291 white_recording
->Rerecord();
2292 scoped_refptr
<FakePicturePileImpl
> white_pile
=
2293 FakePicturePileImpl::CreateFromPile(white_recording
.get(), nullptr);
2295 gfx::Transform white_content_to_target_transform
;
2296 SharedQuadState
* white_shared_state
= CreateTestSharedQuadState(
2297 white_content_to_target_transform
, viewport
, pass
.get());
2299 PictureDrawQuad
* white_quad
=
2300 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2301 white_quad
->SetNew(white_shared_state
, viewport
, gfx::Rect(), viewport
,
2302 gfx::RectF(0, 0, 1, 1), viewport
.size(), nearest_neighbor
,
2303 texture_format
, viewport
, 1.f
, white_pile
.get());
2305 RenderPassList pass_list
;
2306 pass_list
.push_back(pass
.Pass());
2308 EXPECT_TRUE(this->RunPixelTest(
2310 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
2311 FuzzyPixelOffByOneComparator(true)));
2314 template<typename TypeParam
> bool IsSoftwareRenderer() {
2319 bool IsSoftwareRenderer
<SoftwareRenderer
>() {
2324 bool IsSoftwareRenderer
<SoftwareRendererWithExpandedViewport
>() {
2328 // If we disable image filtering, then a 2x2 bitmap should appear as four
2329 // huge sharp squares.
2330 TYPED_TEST(SoftwareRendererPixelTest
, PictureDrawQuadDisableImageFiltering
) {
2331 // We only care about this in software mode since bilinear filtering is
2332 // cheap in hardware.
2333 if (!IsSoftwareRenderer
<TypeParam
>())
2336 gfx::Size
pile_tile_size(1000, 1000);
2337 gfx::Rect
viewport(this->device_viewport_size_
);
2338 ResourceFormat texture_format
= RGBA_8888
;
2339 bool nearest_neighbor
= false;
2341 RenderPassId
id(1, 1);
2342 gfx::Transform transform_to_root
;
2343 scoped_ptr
<RenderPass
> pass
=
2344 CreateTestRenderPass(id
, viewport
, transform_to_root
);
2347 bitmap
.allocN32Pixels(2, 2);
2349 SkAutoLockPixels
lock(bitmap
);
2350 SkCanvas
canvas(bitmap
);
2351 canvas
.drawPoint(0, 0, SK_ColorGREEN
);
2352 canvas
.drawPoint(0, 1, SK_ColorBLUE
);
2353 canvas
.drawPoint(1, 0, SK_ColorBLUE
);
2354 canvas
.drawPoint(1, 1, SK_ColorGREEN
);
2357 scoped_ptr
<FakePicturePile
> recording
=
2358 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
2360 paint
.setFilterQuality(kLow_SkFilterQuality
);
2361 recording
->add_draw_bitmap_with_paint(bitmap
, gfx::Point(), paint
);
2362 recording
->Rerecord();
2363 scoped_refptr
<FakePicturePileImpl
> pile
=
2364 FakePicturePileImpl::CreateFromPile(recording
.get(), nullptr);
2366 gfx::Transform content_to_target_transform
;
2367 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
2368 content_to_target_transform
, viewport
, pass
.get());
2370 PictureDrawQuad
* quad
= pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2371 quad
->SetNew(shared_state
, viewport
, gfx::Rect(), viewport
,
2372 gfx::RectF(0, 0, 2, 2), viewport
.size(), nearest_neighbor
,
2373 texture_format
, viewport
, 1.f
, pile
.get());
2375 RenderPassList pass_list
;
2376 pass_list
.push_back(pass
.Pass());
2378 this->disable_picture_quad_image_filtering_
= true;
2380 EXPECT_TRUE(this->RunPixelTest(
2382 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2383 ExactPixelComparator(true)));
2386 // This disables filtering by setting |nearest_neighbor| on the PictureDrawQuad.
2387 TYPED_TEST(SoftwareRendererPixelTest
, PictureDrawQuadNearestNeighbor
) {
2388 gfx::Size
pile_tile_size(1000, 1000);
2389 gfx::Rect
viewport(this->device_viewport_size_
);
2390 ResourceFormat texture_format
= RGBA_8888
;
2391 bool nearest_neighbor
= true;
2393 RenderPassId
id(1, 1);
2394 gfx::Transform transform_to_root
;
2395 scoped_ptr
<RenderPass
> pass
=
2396 CreateTestRenderPass(id
, viewport
, transform_to_root
);
2399 bitmap
.allocN32Pixels(2, 2);
2401 SkAutoLockPixels
lock(bitmap
);
2402 SkCanvas
canvas(bitmap
);
2403 canvas
.drawPoint(0, 0, SK_ColorGREEN
);
2404 canvas
.drawPoint(0, 1, SK_ColorBLUE
);
2405 canvas
.drawPoint(1, 0, SK_ColorBLUE
);
2406 canvas
.drawPoint(1, 1, SK_ColorGREEN
);
2409 scoped_ptr
<FakePicturePile
> recording
=
2410 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
2412 paint
.setFilterQuality(kLow_SkFilterQuality
);
2413 recording
->add_draw_bitmap_with_paint(bitmap
, gfx::Point(), paint
);
2414 recording
->Rerecord();
2415 scoped_refptr
<FakePicturePileImpl
> pile
=
2416 FakePicturePileImpl::CreateFromPile(recording
.get(), nullptr);
2418 gfx::Transform content_to_target_transform
;
2419 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
2420 content_to_target_transform
, viewport
, pass
.get());
2422 PictureDrawQuad
* quad
= pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2423 quad
->SetNew(shared_state
, viewport
, gfx::Rect(), viewport
,
2424 gfx::RectF(0, 0, 2, 2), viewport
.size(), nearest_neighbor
,
2425 texture_format
, viewport
, 1.f
, pile
.get());
2427 RenderPassList pass_list
;
2428 pass_list
.push_back(pass
.Pass());
2430 EXPECT_TRUE(this->RunPixelTest(
2432 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2433 ExactPixelComparator(true)));
2436 // This disables filtering by setting |nearest_neighbor| on the TileDrawQuad.
2437 TYPED_TEST(RendererPixelTest
, TileDrawQuadNearestNeighbor
) {
2438 gfx::Rect
viewport(this->device_viewport_size_
);
2439 bool swizzle_contents
= true;
2440 bool nearest_neighbor
= true;
2443 bitmap
.allocN32Pixels(2, 2);
2445 SkAutoLockPixels
lock(bitmap
);
2446 SkCanvas
canvas(bitmap
);
2447 canvas
.drawPoint(0, 0, SK_ColorGREEN
);
2448 canvas
.drawPoint(0, 1, SK_ColorBLUE
);
2449 canvas
.drawPoint(1, 0, SK_ColorBLUE
);
2450 canvas
.drawPoint(1, 1, SK_ColorGREEN
);
2453 gfx::Size
tile_size(2, 2);
2454 ResourceProvider::ResourceId resource
=
2455 this->resource_provider_
->CreateResource(
2456 tile_size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
2460 SkAutoLockPixels
lock(bitmap
);
2461 this->resource_provider_
->CopyToResource(
2462 resource
, static_cast<uint8_t*>(bitmap
.getPixels()), tile_size
);
2465 RenderPassId
id(1, 1);
2466 gfx::Transform transform_to_root
;
2467 scoped_ptr
<RenderPass
> pass
=
2468 CreateTestRenderPass(id
, viewport
, transform_to_root
);
2470 gfx::Transform content_to_target_transform
;
2471 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
2472 content_to_target_transform
, viewport
, pass
.get());
2474 TileDrawQuad
* quad
= pass
->CreateAndAppendDrawQuad
<TileDrawQuad
>();
2475 quad
->SetNew(shared_state
, viewport
, gfx::Rect(), viewport
, resource
,
2476 gfx::Rect(tile_size
), tile_size
, swizzle_contents
,
2479 RenderPassList pass_list
;
2480 pass_list
.push_back(pass
.Pass());
2482 EXPECT_TRUE(this->RunPixelTest(
2484 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2485 ExactPixelComparator(true)));
2488 TYPED_TEST(SoftwareRendererPixelTest
, PictureDrawQuadNonIdentityScale
) {
2489 gfx::Size
pile_tile_size(1000, 1000);
2490 gfx::Rect
viewport(this->device_viewport_size_
);
2491 // TODO(enne): the renderer should figure this out on its own.
2492 ResourceFormat texture_format
= RGBA_8888
;
2493 bool nearest_neighbor
= false;
2495 RenderPassId
id(1, 1);
2496 gfx::Transform transform_to_root
;
2497 scoped_ptr
<RenderPass
> pass
=
2498 CreateTestRenderPass(id
, viewport
, transform_to_root
);
2500 // As scaling up the blue checkerboards will cause sampling on the GPU,
2501 // a few extra "cleanup rects" need to be added to clobber the blending
2502 // to make the output image more clean. This will also test subrects
2504 gfx::Transform green_content_to_target_transform
;
2505 gfx::Rect
green_rect1(gfx::Point(80, 0), gfx::Size(20, 100));
2506 gfx::Rect
green_rect2(gfx::Point(0, 80), gfx::Size(100, 20));
2508 scoped_ptr
<FakePicturePile
> green_recording
=
2509 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
2512 red_paint
.setColor(SK_ColorRED
);
2513 green_recording
->add_draw_rect_with_paint(viewport
, red_paint
);
2514 SkPaint green_paint
;
2515 green_paint
.setColor(SK_ColorGREEN
);
2516 green_recording
->add_draw_rect_with_paint(green_rect1
, green_paint
);
2517 green_recording
->add_draw_rect_with_paint(green_rect2
, green_paint
);
2518 green_recording
->Rerecord();
2519 scoped_refptr
<FakePicturePileImpl
> green_pile
=
2520 FakePicturePileImpl::CreateFromPile(green_recording
.get(), nullptr);
2522 SharedQuadState
* top_right_green_shared_quad_state
=
2523 CreateTestSharedQuadState(
2524 green_content_to_target_transform
, viewport
, pass
.get());
2526 PictureDrawQuad
* green_quad1
=
2527 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2528 green_quad1
->SetNew(top_right_green_shared_quad_state
, green_rect1
,
2529 gfx::Rect(), green_rect1
, gfx::RectF(green_rect1
.size()),
2530 green_rect1
.size(), nearest_neighbor
, texture_format
,
2531 green_rect1
, 1.f
, green_pile
.get());
2533 PictureDrawQuad
* green_quad2
=
2534 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2535 green_quad2
->SetNew(top_right_green_shared_quad_state
, green_rect2
,
2536 gfx::Rect(), green_rect2
, gfx::RectF(green_rect2
.size()),
2537 green_rect2
.size(), nearest_neighbor
, texture_format
,
2538 green_rect2
, 1.f
, green_pile
.get());
2540 // Add a green clipped checkerboard in the bottom right to help test
2541 // interleaving picture quad content and solid color content.
2542 gfx::Rect
bottom_right_rect(
2543 gfx::Point(viewport
.width() / 2, viewport
.height() / 2),
2544 gfx::Size(viewport
.width() / 2, viewport
.height() / 2));
2545 SharedQuadState
* bottom_right_green_shared_state
=
2546 CreateTestSharedQuadStateClipped(green_content_to_target_transform
,
2550 SolidColorDrawQuad
* bottom_right_color_quad
=
2551 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2552 bottom_right_color_quad
->SetNew(bottom_right_green_shared_state
,
2558 // Add two blue checkerboards taking up the bottom left and top right,
2559 // but use content scales as content rects to make this happen.
2560 // The content is at a 4x content scale.
2561 gfx::Rect
layer_rect(gfx::Size(20, 30));
2562 float contents_scale
= 4.f
;
2563 // Two rects that touch at their corners, arbitrarily placed in the layer.
2564 gfx::RectF
blue_layer_rect1(gfx::PointF(5.5f
, 9.0f
), gfx::SizeF(2.5f
, 2.5f
));
2565 gfx::RectF
blue_layer_rect2(gfx::PointF(8.0f
, 6.5f
), gfx::SizeF(2.5f
, 2.5f
));
2566 gfx::RectF union_layer_rect
= blue_layer_rect1
;
2567 union_layer_rect
.Union(blue_layer_rect2
);
2569 // Because scaling up will cause sampling outside the rects, add one extra
2570 // pixel of buffer at the final content scale.
2571 float inset
= -1.f
/ contents_scale
;
2572 blue_layer_rect1
.Inset(inset
, inset
, inset
, inset
);
2573 blue_layer_rect2
.Inset(inset
, inset
, inset
, inset
);
2575 scoped_ptr
<FakePicturePile
> recording
=
2576 FakePicturePile::CreateFilledPile(pile_tile_size
, layer_rect
.size());
2578 Region
outside(layer_rect
);
2579 outside
.Subtract(gfx::ToEnclosingRect(union_layer_rect
));
2580 for (Region::Iterator
iter(outside
); iter
.has_rect(); iter
.next()) {
2581 recording
->add_draw_rect_with_paint(iter
.rect(), red_paint
);
2585 blue_paint
.setColor(SK_ColorBLUE
);
2586 recording
->add_draw_rect_with_paint(blue_layer_rect1
, blue_paint
);
2587 recording
->add_draw_rect_with_paint(blue_layer_rect2
, blue_paint
);
2588 recording
->Rerecord();
2589 scoped_refptr
<FakePicturePileImpl
> pile
=
2590 FakePicturePileImpl::CreateFromPile(recording
.get(), nullptr);
2592 gfx::Rect
content_rect(
2593 gfx::ScaleToEnclosingRect(layer_rect
, contents_scale
));
2594 gfx::Rect
content_union_rect(
2595 gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect
, contents_scale
)));
2597 // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels,
2598 // so scale an additional 10x to make them 100x100.
2599 gfx::Transform content_to_target_transform
;
2600 content_to_target_transform
.Scale(10.0, 10.0);
2601 gfx::Rect
quad_content_rect(gfx::Size(20, 20));
2602 SharedQuadState
* blue_shared_state
= CreateTestSharedQuadState(
2603 content_to_target_transform
, quad_content_rect
, pass
.get());
2605 PictureDrawQuad
* blue_quad
= pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2606 blue_quad
->SetNew(blue_shared_state
, quad_content_rect
, gfx::Rect(),
2607 quad_content_rect
, gfx::RectF(quad_content_rect
),
2608 content_union_rect
.size(), nearest_neighbor
, texture_format
,
2609 content_union_rect
, contents_scale
, pile
.get());
2611 // Fill left half of viewport with green.
2612 gfx::Transform half_green_content_to_target_transform
;
2613 gfx::Rect
half_green_rect(gfx::Size(viewport
.width() / 2, viewport
.height()));
2614 SharedQuadState
* half_green_shared_state
= CreateTestSharedQuadState(
2615 half_green_content_to_target_transform
, half_green_rect
, pass
.get());
2616 SolidColorDrawQuad
* half_color_quad
=
2617 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2618 half_color_quad
->SetNew(half_green_shared_state
,
2624 RenderPassList pass_list
;
2625 pass_list
.push_back(pass
.Pass());
2627 EXPECT_TRUE(this->RunPixelTest(
2629 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2630 ExactPixelComparator(true)));
2633 typedef RendererPixelTest
<GLRendererWithFlippedSurface
>
2634 GLRendererPixelTestWithFlippedOutputSurface
;
2636 TEST_F(GLRendererPixelTestWithFlippedOutputSurface
, ExplicitFlipTest
) {
2637 // This draws a blue rect above a yellow rect with an inverted output surface.
2638 gfx::Rect
viewport_rect(this->device_viewport_size_
);
2640 RenderPassId
root_pass_id(1, 1);
2641 scoped_ptr
<RenderPass
> root_pass
=
2642 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
2644 RenderPassId
child_pass_id(2, 2);
2645 gfx::Rect
pass_rect(this->device_viewport_size_
);
2646 gfx::Transform transform_to_root
;
2647 scoped_ptr
<RenderPass
> child_pass
=
2648 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
2650 gfx::Transform content_to_target_transform
;
2651 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
2652 content_to_target_transform
, viewport_rect
, child_pass
.get());
2654 gfx::Rect
blue_rect(0,
2656 this->device_viewport_size_
.width(),
2657 this->device_viewport_size_
.height() / 2);
2658 SolidColorDrawQuad
* blue
=
2659 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2660 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
2661 gfx::Rect
yellow_rect(0,
2662 this->device_viewport_size_
.height() / 2,
2663 this->device_viewport_size_
.width(),
2664 this->device_viewport_size_
.height() / 2);
2665 SolidColorDrawQuad
* yellow
=
2666 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2667 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
2669 SharedQuadState
* pass_shared_state
=
2670 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
2671 CreateTestRenderPassDrawQuad(
2672 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
2674 RenderPassList pass_list
;
2675 pass_list
.push_back(child_pass
.Pass());
2676 pass_list
.push_back(root_pass
.Pass());
2678 EXPECT_TRUE(this->RunPixelTest(
2680 base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")),
2681 ExactPixelComparator(true)));
2684 TEST_F(GLRendererPixelTestWithFlippedOutputSurface
, CheckChildPassUnflipped
) {
2685 // This draws a blue rect above a yellow rect with an inverted output surface.
2686 gfx::Rect
viewport_rect(this->device_viewport_size_
);
2688 RenderPassId
root_pass_id(1, 1);
2689 scoped_ptr
<RenderPass
> root_pass
=
2690 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
2692 RenderPassId
child_pass_id(2, 2);
2693 gfx::Rect
pass_rect(this->device_viewport_size_
);
2694 gfx::Transform transform_to_root
;
2695 scoped_ptr
<RenderPass
> child_pass
=
2696 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
2698 gfx::Transform content_to_target_transform
;
2699 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
2700 content_to_target_transform
, viewport_rect
, child_pass
.get());
2702 gfx::Rect
blue_rect(0,
2704 this->device_viewport_size_
.width(),
2705 this->device_viewport_size_
.height() / 2);
2706 SolidColorDrawQuad
* blue
=
2707 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2708 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
2709 gfx::Rect
yellow_rect(0,
2710 this->device_viewport_size_
.height() / 2,
2711 this->device_viewport_size_
.width(),
2712 this->device_viewport_size_
.height() / 2);
2713 SolidColorDrawQuad
* yellow
=
2714 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2715 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
2717 SharedQuadState
* pass_shared_state
=
2718 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
2719 CreateTestRenderPassDrawQuad(
2720 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
2722 RenderPassList pass_list
;
2723 pass_list
.push_back(child_pass
.Pass());
2724 pass_list
.push_back(root_pass
.Pass());
2726 // Check that the child pass remains unflipped.
2727 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
2730 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
2731 ExactPixelComparator(true)));
2734 TEST_F(GLRendererPixelTest
, CheckReadbackSubset
) {
2735 gfx::Rect
viewport_rect(this->device_viewport_size_
);
2737 RenderPassId
root_pass_id(1, 1);
2738 scoped_ptr
<RenderPass
> root_pass
=
2739 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
2741 RenderPassId
child_pass_id(2, 2);
2742 gfx::Rect
pass_rect(this->device_viewport_size_
);
2743 gfx::Transform transform_to_root
;
2744 scoped_ptr
<RenderPass
> child_pass
=
2745 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
2747 gfx::Transform content_to_target_transform
;
2748 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
2749 content_to_target_transform
, viewport_rect
, child_pass
.get());
2751 // Draw a green quad full-size with a blue quad in the lower-right corner.
2752 gfx::Rect
blue_rect(this->device_viewport_size_
.width() * 3 / 4,
2753 this->device_viewport_size_
.height() * 3 / 4,
2754 this->device_viewport_size_
.width() * 3 / 4,
2755 this->device_viewport_size_
.height() * 3 / 4);
2756 SolidColorDrawQuad
* blue
=
2757 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2758 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
2759 gfx::Rect
green_rect(0,
2761 this->device_viewport_size_
.width(),
2762 this->device_viewport_size_
.height());
2763 SolidColorDrawQuad
* green
=
2764 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2765 green
->SetNew(shared_state
, green_rect
, green_rect
, SK_ColorGREEN
, false);
2767 SharedQuadState
* pass_shared_state
=
2768 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
2769 CreateTestRenderPassDrawQuad(
2770 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
2772 RenderPassList pass_list
;
2773 pass_list
.push_back(child_pass
.Pass());
2774 pass_list
.push_back(root_pass
.Pass());
2776 // Check that the child pass remains unflipped.
2777 gfx::Rect
capture_rect(this->device_viewport_size_
.width() / 2,
2778 this->device_viewport_size_
.height() / 2,
2779 this->device_viewport_size_
.width() / 2,
2780 this->device_viewport_size_
.height() / 2);
2781 EXPECT_TRUE(this->RunPixelTestWithReadbackTargetAndArea(
2784 base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")),
2785 ExactPixelComparator(true),
2789 TYPED_TEST(RendererPixelTest
, WrapModeRepeat
) {
2790 gfx::Rect
rect(this->device_viewport_size_
);
2792 RenderPassId
id(1, 1);
2793 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
2795 SharedQuadState
* shared_state
=
2796 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
2798 gfx::Size
texture_size(4, 4);
2799 SkPMColor colors
[4] = {
2800 SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)),
2801 SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)),
2802 SkPreMultiplyColor(SkColorSetARGB(255, 0, 64, 0)),
2803 SkPreMultiplyColor(SkColorSetARGB(255, 0, 0, 0)),
2805 uint32_t pixels
[16] = {
2806 colors
[0], colors
[0], colors
[1], colors
[1],
2807 colors
[0], colors
[0], colors
[1], colors
[1],
2808 colors
[2], colors
[2], colors
[3], colors
[3],
2809 colors
[2], colors
[2], colors
[3], colors
[3],
2811 ResourceProvider::ResourceId resource
=
2812 this->resource_provider_
->CreateResource(
2813 texture_size
, GL_REPEAT
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
2815 this->resource_provider_
->CopyToResource(
2816 resource
, reinterpret_cast<uint8_t*>(pixels
), texture_size
);
2818 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
2819 TextureDrawQuad
* texture_quad
=
2820 pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2821 texture_quad
->SetNew(
2822 shared_state
, gfx::Rect(this->device_viewport_size_
), gfx::Rect(),
2823 gfx::Rect(this->device_viewport_size_
), resource
,
2824 true, // premultiplied_alpha
2825 gfx::PointF(0.0f
, 0.0f
), // uv_top_left
2826 gfx::PointF( // uv_bottom_right
2827 this->device_viewport_size_
.width() / texture_size
.width(),
2828 this->device_viewport_size_
.height() / texture_size
.height()),
2829 SK_ColorWHITE
, vertex_opacity
,
2831 false); // nearest_neighbor
2833 RenderPassList pass_list
;
2834 pass_list
.push_back(pass
.Pass());
2836 EXPECT_TRUE(this->RunPixelTest(
2838 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
2839 FuzzyPixelOffByOneComparator(true)));
2842 TYPED_TEST(RendererPixelTest
, Checkerboards
) {
2843 gfx::Rect
rect(this->device_viewport_size_
);
2845 RenderPassId
id(1, 1);
2846 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
2848 SharedQuadState
* shared_state
=
2849 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
2851 // The color's alpha value is not used.
2852 SkColor color1
= SK_ColorGREEN
;
2853 color1
= SkColorSetA(color1
, 0);
2854 SkColor color2
= SK_ColorBLUE
;
2855 color2
= SkColorSetA(color2
, 0);
2857 gfx::Rect
content_rect(rect
);
2859 gfx::Rect
top_left(content_rect
);
2860 gfx::Rect
top_right(content_rect
);
2861 gfx::Rect
bottom_left(content_rect
);
2862 gfx::Rect
bottom_right(content_rect
);
2863 // The format is Inset(left, top, right, bottom).
2864 top_left
.Inset(0, 0, content_rect
.width() / 2, content_rect
.height() / 2);
2865 top_right
.Inset(content_rect
.width() / 2, 0, 0, content_rect
.height() / 2);
2866 bottom_left
.Inset(0, content_rect
.height() / 2, content_rect
.width() / 2, 0);
2867 bottom_right
.Inset(content_rect
.width() / 2, content_rect
.height() / 2, 0, 0);
2869 // Appends checkerboard quads with a scale of 1.
2870 CheckerboardDrawQuad
* quad
=
2871 pass
->CreateAndAppendDrawQuad
<CheckerboardDrawQuad
>();
2872 quad
->SetNew(shared_state
, top_left
, top_left
, color1
, 1.f
);
2873 quad
= pass
->CreateAndAppendDrawQuad
<CheckerboardDrawQuad
>();
2874 quad
->SetNew(shared_state
, top_right
, top_right
, color2
, 1.f
);
2875 quad
= pass
->CreateAndAppendDrawQuad
<CheckerboardDrawQuad
>();
2876 quad
->SetNew(shared_state
, bottom_left
, bottom_left
, color2
, 1.f
);
2877 quad
= pass
->CreateAndAppendDrawQuad
<CheckerboardDrawQuad
>();
2878 quad
->SetNew(shared_state
, bottom_right
, bottom_right
, color1
, 1.f
);
2880 RenderPassList pass_list
;
2881 pass_list
.push_back(pass
.Pass());
2883 base::FilePath::StringType path
=
2884 IsSoftwareRenderer
<TypeParam
>()
2885 ? FILE_PATH_LITERAL("four_blue_green_checkers.png")
2886 : FILE_PATH_LITERAL("checkers.png");
2887 EXPECT_TRUE(this->RunPixelTest(&pass_list
, base::FilePath(path
),
2888 ExactPixelComparator(true)));
2891 TYPED_TEST(RendererPixelTest
, CheckerboardsScaled
) {
2892 gfx::Rect
rect(this->device_viewport_size_
);
2894 RenderPassId
id(1, 1);
2895 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
2897 gfx::Transform scale
;
2898 scale
.Scale(2.f
, 2.f
);
2900 SharedQuadState
* shared_state
=
2901 CreateTestSharedQuadState(scale
, rect
, pass
.get());
2903 // The color's alpha value is not used.
2904 SkColor color1
= SK_ColorGREEN
;
2905 color1
= SkColorSetA(color1
, 0);
2906 SkColor color2
= SK_ColorBLUE
;
2907 color2
= SkColorSetA(color2
, 0);
2909 gfx::Rect
content_rect(rect
);
2910 content_rect
.Inset(0, 0, rect
.width() / 2, rect
.height() / 2);
2912 gfx::Rect
top_left(content_rect
);
2913 gfx::Rect
top_right(content_rect
);
2914 gfx::Rect
bottom_left(content_rect
);
2915 gfx::Rect
bottom_right(content_rect
);
2916 // The format is Inset(left, top, right, bottom).
2917 top_left
.Inset(0, 0, content_rect
.width() / 2, content_rect
.height() / 2);
2918 top_right
.Inset(content_rect
.width() / 2, 0, 0, content_rect
.height() / 2);
2919 bottom_left
.Inset(0, content_rect
.height() / 2, content_rect
.width() / 2, 0);
2920 bottom_right
.Inset(content_rect
.width() / 2, content_rect
.height() / 2, 0, 0);
2922 // Appends checkerboard quads with a scale of 2, and a shared quad state
2923 // with a scale of 2. The checkers should be scaled by 2 * 2 = 4.
2924 CheckerboardDrawQuad
* quad
=
2925 pass
->CreateAndAppendDrawQuad
<CheckerboardDrawQuad
>();
2926 quad
->SetNew(shared_state
, top_left
, top_left
, color1
, 2.f
);
2927 quad
= pass
->CreateAndAppendDrawQuad
<CheckerboardDrawQuad
>();
2928 quad
->SetNew(shared_state
, top_right
, top_right
, color2
, 2.f
);
2929 quad
= pass
->CreateAndAppendDrawQuad
<CheckerboardDrawQuad
>();
2930 quad
->SetNew(shared_state
, bottom_left
, bottom_left
, color2
, 2.f
);
2931 quad
= pass
->CreateAndAppendDrawQuad
<CheckerboardDrawQuad
>();
2932 quad
->SetNew(shared_state
, bottom_right
, bottom_right
, color1
, 2.f
);
2934 RenderPassList pass_list
;
2935 pass_list
.push_back(pass
.Pass());
2937 base::FilePath::StringType path
=
2938 IsSoftwareRenderer
<TypeParam
>()
2939 ? FILE_PATH_LITERAL("four_blue_green_checkers.png")
2940 : FILE_PATH_LITERAL("checkers_big.png");
2941 EXPECT_TRUE(this->RunPixelTest(&pass_list
, base::FilePath(path
),
2942 ExactPixelComparator(true)));
2945 #endif // !defined(OS_ANDROID)