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/layers/append_quads_data.h"
7 #include "cc/output/gl_renderer.h"
8 #include "cc/quads/draw_quad.h"
9 #include "cc/quads/picture_draw_quad.h"
10 #include "cc/quads/texture_draw_quad.h"
11 #include "cc/resources/video_resource_updater.h"
12 #include "cc/test/fake_picture_pile_impl.h"
13 #include "cc/test/pixel_test.h"
14 #include "gpu/command_buffer/client/gles2_interface.h"
15 #include "media/base/video_frame.h"
16 #include "third_party/skia/include/core/SkColorPriv.h"
17 #include "third_party/skia/include/core/SkImageFilter.h"
18 #include "third_party/skia/include/core/SkMatrix.h"
19 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
20 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
21 #include "ui/gfx/geometry/rect_conversions.h"
23 using gpu::gles2::GLES2Interface
;
28 #if !defined(OS_ANDROID)
29 scoped_ptr
<RenderPass
> CreateTestRootRenderPass(RenderPassId id
,
30 const gfx::Rect
& rect
) {
31 scoped_ptr
<RenderPass
> pass
= RenderPass::Create();
32 const gfx::Rect output_rect
= rect
;
33 const gfx::Rect damage_rect
= rect
;
34 const gfx::Transform transform_to_root_target
;
35 pass
->SetNew(id
, output_rect
, damage_rect
, transform_to_root_target
);
39 scoped_ptr
<RenderPass
> CreateTestRenderPass(
41 const gfx::Rect
& rect
,
42 const gfx::Transform
& transform_to_root_target
) {
43 scoped_ptr
<RenderPass
> pass
= RenderPass::Create();
44 const gfx::Rect output_rect
= rect
;
45 const gfx::Rect damage_rect
= rect
;
46 pass
->SetNew(id
, output_rect
, damage_rect
, transform_to_root_target
);
50 SharedQuadState
* CreateTestSharedQuadState(
51 gfx::Transform content_to_target_transform
,
52 const gfx::Rect
& rect
,
53 RenderPass
* render_pass
) {
54 const gfx::Size content_bounds
= rect
.size();
55 const gfx::Rect visible_content_rect
= rect
;
56 const gfx::Rect clip_rect
= rect
;
57 const bool is_clipped
= false;
58 const float opacity
= 1.0f
;
59 const SkXfermode::Mode blend_mode
= SkXfermode::kSrcOver_Mode
;
60 int sorting_context_id
= 0;
61 SharedQuadState
* shared_state
= render_pass
->CreateAndAppendSharedQuadState();
62 shared_state
->SetAll(content_to_target_transform
,
73 SharedQuadState
* CreateTestSharedQuadStateClipped(
74 gfx::Transform content_to_target_transform
,
75 const gfx::Rect
& rect
,
76 const gfx::Rect
& clip_rect
,
77 RenderPass
* render_pass
) {
78 const gfx::Size content_bounds
= rect
.size();
79 const gfx::Rect visible_content_rect
= clip_rect
;
80 const bool is_clipped
= true;
81 const float opacity
= 1.0f
;
82 const SkXfermode::Mode blend_mode
= SkXfermode::kSrcOver_Mode
;
83 int sorting_context_id
= 0;
84 SharedQuadState
* shared_state
= render_pass
->CreateAndAppendSharedQuadState();
85 shared_state
->SetAll(content_to_target_transform
,
96 void CreateTestRenderPassDrawQuad(const SharedQuadState
* shared_state
,
97 const gfx::Rect
& rect
,
99 RenderPass
* render_pass
) {
100 RenderPassDrawQuad
* quad
=
101 render_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
102 quad
->SetNew(shared_state
,
106 0, // mask_resource_id
107 gfx::Vector2dF(), // mask_uv_scale
108 gfx::Size(), // mask_texture_size
109 FilterOperations(), // foreground filters
110 gfx::Vector2dF(), // filters scale
111 FilterOperations()); // background filters
114 void CreateTestTextureDrawQuad(const gfx::Rect
& rect
,
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 size_t num_pixels
= static_cast<size_t>(rect
.width()) * rect
.height();
128 std::vector
<uint32_t> pixels(num_pixels
, pixel_color
);
130 ResourceProvider::ResourceId resource
= resource_provider
->CreateResource(
131 rect
.size(), GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
133 resource_provider
->CopyToResource(
134 resource
, reinterpret_cast<uint8_t*>(&pixels
.front()), rect
.size());
136 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
138 TextureDrawQuad
* quad
=
139 render_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
140 quad
->SetNew(shared_state
,
146 gfx::PointF(0.0f
, 0.0f
), // uv_top_left
147 gfx::PointF(1.0f
, 1.0f
), // uv_bottom_right
151 false); // nearest_neighbor
154 typedef ::testing::Types
<GLRenderer
,
156 GLRendererWithExpandedViewport
,
157 SoftwareRendererWithExpandedViewport
> RendererTypes
;
158 TYPED_TEST_CASE(RendererPixelTest
, RendererTypes
);
160 template <typename RendererType
>
161 class SoftwareRendererPixelTest
: public RendererPixelTest
<RendererType
> {};
163 typedef ::testing::Types
<SoftwareRenderer
, SoftwareRendererWithExpandedViewport
>
164 SoftwareRendererTypes
;
165 TYPED_TEST_CASE(SoftwareRendererPixelTest
, SoftwareRendererTypes
);
167 template <typename RendererType
>
168 class FuzzyForSoftwareOnlyPixelComparator
: public PixelComparator
{
170 explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha
)
171 : fuzzy_(discard_alpha
), exact_(discard_alpha
) {}
173 bool Compare(const SkBitmap
& actual_bmp
,
174 const SkBitmap
& expected_bmp
) const override
;
177 FuzzyPixelOffByOneComparator fuzzy_
;
178 ExactPixelComparator exact_
;
182 bool FuzzyForSoftwareOnlyPixelComparator
<SoftwareRenderer
>::Compare(
183 const SkBitmap
& actual_bmp
,
184 const SkBitmap
& expected_bmp
) const {
185 return fuzzy_
.Compare(actual_bmp
, expected_bmp
);
189 bool FuzzyForSoftwareOnlyPixelComparator
<
190 SoftwareRendererWithExpandedViewport
>::Compare(
191 const SkBitmap
& actual_bmp
,
192 const SkBitmap
& expected_bmp
) const {
193 return fuzzy_
.Compare(actual_bmp
, expected_bmp
);
196 template<typename RendererType
>
197 bool FuzzyForSoftwareOnlyPixelComparator
<RendererType
>::Compare(
198 const SkBitmap
& actual_bmp
,
199 const SkBitmap
& expected_bmp
) const {
200 return exact_
.Compare(actual_bmp
, expected_bmp
);
203 TYPED_TEST(RendererPixelTest
, SimpleGreenRect
) {
204 gfx::Rect
rect(this->device_viewport_size_
);
206 RenderPassId
id(1, 1);
207 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
209 SharedQuadState
* shared_state
=
210 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
212 SolidColorDrawQuad
* color_quad
=
213 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
214 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorGREEN
, false);
216 RenderPassList pass_list
;
217 pass_list
.push_back(pass
.Pass());
219 EXPECT_TRUE(this->RunPixelTest(
221 base::FilePath(FILE_PATH_LITERAL("green.png")),
222 ExactPixelComparator(true)));
225 TYPED_TEST(RendererPixelTest
, SimpleGreenRect_NonRootRenderPass
) {
226 gfx::Rect
rect(this->device_viewport_size_
);
227 gfx::Rect
small_rect(100, 100);
229 RenderPassId
child_id(2, 1);
230 scoped_ptr
<RenderPass
> child_pass
=
231 CreateTestRenderPass(child_id
, small_rect
, gfx::Transform());
233 SharedQuadState
* child_shared_state
=
234 CreateTestSharedQuadState(gfx::Transform(), small_rect
, child_pass
.get());
236 SolidColorDrawQuad
* color_quad
=
237 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
238 color_quad
->SetNew(child_shared_state
, rect
, rect
, SK_ColorGREEN
, false);
240 RenderPassId
root_id(1, 1);
241 scoped_ptr
<RenderPass
> root_pass
=
242 CreateTestRenderPass(root_id
, rect
, gfx::Transform());
244 SharedQuadState
* root_shared_state
=
245 CreateTestSharedQuadState(gfx::Transform(), rect
, root_pass
.get());
247 CreateTestRenderPassDrawQuad(
248 root_shared_state
, small_rect
, child_id
, root_pass
.get());
250 RenderPass
* child_pass_ptr
= child_pass
.get();
252 RenderPassList pass_list
;
253 pass_list
.push_back(child_pass
.Pass());
254 pass_list
.push_back(root_pass
.Pass());
256 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
259 base::FilePath(FILE_PATH_LITERAL("green_small.png")),
260 ExactPixelComparator(true)));
263 TYPED_TEST(RendererPixelTest
, PremultipliedTextureWithoutBackground
) {
264 gfx::Rect
rect(this->device_viewport_size_
);
266 RenderPassId
id(1, 1);
267 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
269 SharedQuadState
* shared_state
=
270 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
272 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
273 SkColorSetARGB(128, 0, 255, 0), // Texel color.
274 SK_ColorTRANSPARENT
, // Background color.
275 true, // Premultiplied alpha.
277 this->resource_provider_
.get(),
280 SolidColorDrawQuad
* color_quad
=
281 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
282 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorWHITE
, false);
284 RenderPassList pass_list
;
285 pass_list
.push_back(pass
.Pass());
287 EXPECT_TRUE(this->RunPixelTest(
289 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
290 FuzzyPixelOffByOneComparator(true)));
293 TYPED_TEST(RendererPixelTest
, PremultipliedTextureWithBackground
) {
294 gfx::Rect
rect(this->device_viewport_size_
);
296 RenderPassId
id(1, 1);
297 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
299 SharedQuadState
* texture_quad_state
=
300 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
301 texture_quad_state
->opacity
= 0.8f
;
303 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
304 SkColorSetARGB(204, 120, 255, 120), // Texel color.
305 SK_ColorGREEN
, // Background color.
306 true, // Premultiplied alpha.
308 this->resource_provider_
.get(),
311 SharedQuadState
* color_quad_state
=
312 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
313 SolidColorDrawQuad
* color_quad
=
314 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
315 color_quad
->SetNew(color_quad_state
, rect
, rect
, SK_ColorWHITE
, false);
317 RenderPassList pass_list
;
318 pass_list
.push_back(pass
.Pass());
320 EXPECT_TRUE(this->RunPixelTest(
322 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
323 FuzzyPixelOffByOneComparator(true)));
326 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
327 TEST_F(GLRendererPixelTest
, NonPremultipliedTextureWithoutBackground
) {
328 gfx::Rect
rect(this->device_viewport_size_
);
330 RenderPassId
id(1, 1);
331 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
333 SharedQuadState
* shared_state
=
334 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
336 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
337 SkColorSetARGB(128, 0, 255, 0), // Texel color.
338 SK_ColorTRANSPARENT
, // Background color.
339 false, // Premultiplied alpha.
341 this->resource_provider_
.get(),
344 SolidColorDrawQuad
* color_quad
=
345 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
346 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorWHITE
, false);
348 RenderPassList pass_list
;
349 pass_list
.push_back(pass
.Pass());
351 EXPECT_TRUE(this->RunPixelTest(
353 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
354 FuzzyPixelOffByOneComparator(true)));
357 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
358 TEST_F(GLRendererPixelTest
, NonPremultipliedTextureWithBackground
) {
359 gfx::Rect
rect(this->device_viewport_size_
);
361 RenderPassId
id(1, 1);
362 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
364 SharedQuadState
* texture_quad_state
=
365 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
366 texture_quad_state
->opacity
= 0.8f
;
368 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
369 SkColorSetARGB(204, 120, 255, 120), // Texel color.
370 SK_ColorGREEN
, // Background color.
371 false, // Premultiplied alpha.
373 this->resource_provider_
.get(),
376 SharedQuadState
* color_quad_state
=
377 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
378 SolidColorDrawQuad
* color_quad
=
379 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
380 color_quad
->SetNew(color_quad_state
, rect
, rect
, SK_ColorWHITE
, false);
382 RenderPassList pass_list
;
383 pass_list
.push_back(pass
.Pass());
385 EXPECT_TRUE(this->RunPixelTest(
387 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
388 FuzzyPixelOffByOneComparator(true)));
391 class VideoGLRendererPixelTest
: public GLRendererPixelTest
{
393 void CreateTestYUVVideoDrawQuad_Striped(const SharedQuadState
* shared_state
,
394 media::VideoFrame::Format format
,
396 const gfx::RectF
& tex_coord_rect
,
397 RenderPass
* render_pass
) {
398 const gfx::Rect
rect(this->device_viewport_size_
);
400 scoped_refptr
<media::VideoFrame
> video_frame
=
401 media::VideoFrame::CreateFrame(
402 format
, rect
.size(), rect
, rect
.size(), base::TimeDelta());
404 // YUV values representing a striped pattern, for validating texture
405 // coordinates for sampling.
409 for (int i
= 0; i
< video_frame
->rows(media::VideoFrame::kYPlane
); ++i
) {
410 uint8_t* y_row
= video_frame
->data(media::VideoFrame::kYPlane
) +
411 video_frame
->stride(media::VideoFrame::kYPlane
) * i
;
412 for (int j
= 0; j
< video_frame
->row_bytes(media::VideoFrame::kYPlane
);
414 y_row
[j
] = (y_value
+= 1);
417 for (int i
= 0; i
< video_frame
->rows(media::VideoFrame::kUPlane
); ++i
) {
418 uint8_t* u_row
= video_frame
->data(media::VideoFrame::kUPlane
) +
419 video_frame
->stride(media::VideoFrame::kUPlane
) * i
;
420 uint8_t* v_row
= video_frame
->data(media::VideoFrame::kVPlane
) +
421 video_frame
->stride(media::VideoFrame::kVPlane
) * i
;
422 for (int j
= 0; j
< video_frame
->row_bytes(media::VideoFrame::kUPlane
);
424 u_row
[j
] = (u_value
+= 3);
425 v_row
[j
] = (v_value
+= 5);
428 uint8 alpha_value
= is_transparent
? 0 : 128;
429 CreateTestYUVVideoDrawQuad_FromVideoFrame(
430 shared_state
, video_frame
, alpha_value
, tex_coord_rect
, render_pass
);
433 void CreateTestYUVVideoDrawQuad_Solid(const SharedQuadState
* shared_state
,
434 media::VideoFrame::Format format
,
436 const gfx::RectF
& tex_coord_rect
,
440 RenderPass
* render_pass
) {
441 const gfx::Rect
rect(this->device_viewport_size_
);
443 scoped_refptr
<media::VideoFrame
> video_frame
=
444 media::VideoFrame::CreateFrame(
445 format
, rect
.size(), rect
, rect
.size(), base::TimeDelta());
447 // YUV values of a solid, constant, color. Useful for testing that color
448 // space/color range are being handled properly.
449 memset(video_frame
->data(media::VideoFrame::kYPlane
),
451 video_frame
->stride(media::VideoFrame::kYPlane
) *
452 video_frame
->rows(media::VideoFrame::kYPlane
));
453 memset(video_frame
->data(media::VideoFrame::kUPlane
),
455 video_frame
->stride(media::VideoFrame::kUPlane
) *
456 video_frame
->rows(media::VideoFrame::kUPlane
));
457 memset(video_frame
->data(media::VideoFrame::kVPlane
),
459 video_frame
->stride(media::VideoFrame::kVPlane
) *
460 video_frame
->rows(media::VideoFrame::kVPlane
));
462 uint8 alpha_value
= is_transparent
? 0 : 128;
463 CreateTestYUVVideoDrawQuad_FromVideoFrame(
464 shared_state
, video_frame
, alpha_value
, tex_coord_rect
, render_pass
);
467 void CreateEdgeBleedPass(media::VideoFrame::Format format
,
468 RenderPassList
* pass_list
) {
469 gfx::Rect
rect(200, 200);
471 RenderPassId
id(1, 1);
472 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
474 // Scale the video up so that bilinear filtering kicks in to sample more
475 // than just nearest neighbor would.
476 gfx::Transform scale_by_2
;
477 scale_by_2
.Scale(2.f
, 2.f
);
478 gfx::Rect
half_rect(100, 100);
479 SharedQuadState
* shared_state
=
480 CreateTestSharedQuadState(scale_by_2
, half_rect
, pass
.get());
482 gfx::Size
background_size(200, 200);
483 gfx::Rect
green_rect(16, 20, 100, 100);
484 gfx::RectF
tex_coord_rect(
485 static_cast<float>(green_rect
.x()) / background_size
.width(),
486 static_cast<float>(green_rect
.y()) / background_size
.height(),
487 static_cast<float>(green_rect
.width()) / background_size
.width(),
488 static_cast<float>(green_rect
.height()) / background_size
.height());
490 // YUV of (149,43,21) should be green (0,255,0) in RGB.
491 // Create a video frame that has a non-green background rect, with a
492 // green sub-rectangle that should be the only thing displayed in
493 // the final image. Bleeding will appear on all four sides of the video
494 // if the tex coords are not clamped.
495 CreateTestYUVVideoDrawQuad_TwoColor(shared_state
, format
, false,
496 tex_coord_rect
, background_size
, 0, 0,
497 0, green_rect
, 149, 43, 21, pass
.get());
498 pass_list
->push_back(pass
.Pass());
501 // Creates a video frame of size background_size filled with yuv_background,
502 // and then draws a foreground rectangle in a different color on top of
503 // that. The foreground rectangle must have coordinates that are divisible
504 // by 2 because YUV is a block format.
505 void CreateTestYUVVideoDrawQuad_TwoColor(const SharedQuadState
* shared_state
,
506 media::VideoFrame::Format format
,
508 const gfx::RectF
& tex_coord_rect
,
509 const gfx::Size
& background_size
,
513 const gfx::Rect
& foreground_rect
,
517 RenderPass
* render_pass
) {
518 const gfx::Rect
rect(background_size
);
520 scoped_refptr
<media::VideoFrame
> video_frame
=
521 media::VideoFrame::CreateFrame(format
, background_size
, foreground_rect
,
522 foreground_rect
.size(),
525 int planes
[] = {media::VideoFrame::kYPlane
,
526 media::VideoFrame::kUPlane
,
527 media::VideoFrame::kVPlane
};
528 uint8 yuv_background
[] = {y_background
, u_background
, v_background
};
529 uint8 yuv_foreground
[] = {y_foreground
, u_foreground
, v_foreground
};
530 int sample_size
[] = {1, 2, 2};
532 for (int i
= 0; i
< 3; ++i
) {
533 memset(video_frame
->data(planes
[i
]), yuv_background
[i
],
534 video_frame
->stride(planes
[i
]) * video_frame
->rows(planes
[i
]));
537 for (int i
= 0; i
< 3; ++i
) {
538 // Since yuv encoding uses block encoding, widths have to be divisible
539 // by the sample size in order for this function to behave properly.
540 DCHECK_EQ(foreground_rect
.x() % sample_size
[i
], 0);
541 DCHECK_EQ(foreground_rect
.y() % sample_size
[i
], 0);
542 DCHECK_EQ(foreground_rect
.width() % sample_size
[i
], 0);
543 DCHECK_EQ(foreground_rect
.height() % sample_size
[i
], 0);
545 gfx::Rect
sample_rect(foreground_rect
.x() / sample_size
[i
],
546 foreground_rect
.y() / sample_size
[i
],
547 foreground_rect
.width() / sample_size
[i
],
548 foreground_rect
.height() / sample_size
[i
]);
549 for (int y
= sample_rect
.y(); y
< sample_rect
.bottom(); ++y
) {
550 for (int x
= sample_rect
.x(); x
< sample_rect
.right(); ++x
) {
551 size_t offset
= y
* video_frame
->stride(planes
[i
]) + x
;
552 video_frame
->data(planes
[i
])[offset
] = yuv_foreground
[i
];
557 uint8 alpha_value
= 255;
558 CreateTestYUVVideoDrawQuad_FromVideoFrame(
559 shared_state
, video_frame
, alpha_value
, tex_coord_rect
, render_pass
);
562 void CreateTestYUVVideoDrawQuad_FromVideoFrame(
563 const SharedQuadState
* shared_state
,
564 scoped_refptr
<media::VideoFrame
> video_frame
,
566 const gfx::RectF
& tex_coord_rect
,
567 RenderPass
* render_pass
) {
568 const bool with_alpha
= (video_frame
->format() == media::VideoFrame::YV12A
);
569 const YUVVideoDrawQuad::ColorSpace color_space
=
570 (video_frame
->format() == media::VideoFrame::YV12J
571 ? YUVVideoDrawQuad::JPEG
572 : YUVVideoDrawQuad::REC_601
);
573 const gfx::Rect
rect(shared_state
->content_bounds
);
574 const gfx::Rect
opaque_rect(0, 0, 0, 0);
577 memset(video_frame
->data(media::VideoFrame::kAPlane
), alpha_value
,
578 video_frame
->stride(media::VideoFrame::kAPlane
) *
579 video_frame
->rows(media::VideoFrame::kAPlane
));
581 VideoFrameExternalResources resources
=
582 video_resource_updater_
->CreateExternalResourcesFromVideoFrame(
585 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE
, resources
.type
);
586 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame
->format()),
587 resources
.mailboxes
.size());
588 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame
->format()),
589 resources
.release_callbacks
.size());
591 ResourceProvider::ResourceId y_resource
=
592 resource_provider_
->CreateResourceFromTextureMailbox(
593 resources
.mailboxes
[media::VideoFrame::kYPlane
],
594 SingleReleaseCallbackImpl::Create(
595 resources
.release_callbacks
[media::VideoFrame::kYPlane
]));
596 ResourceProvider::ResourceId u_resource
=
597 resource_provider_
->CreateResourceFromTextureMailbox(
598 resources
.mailboxes
[media::VideoFrame::kUPlane
],
599 SingleReleaseCallbackImpl::Create(
600 resources
.release_callbacks
[media::VideoFrame::kUPlane
]));
601 ResourceProvider::ResourceId v_resource
=
602 resource_provider_
->CreateResourceFromTextureMailbox(
603 resources
.mailboxes
[media::VideoFrame::kVPlane
],
604 SingleReleaseCallbackImpl::Create(
605 resources
.release_callbacks
[media::VideoFrame::kVPlane
]));
606 ResourceProvider::ResourceId a_resource
= 0;
608 a_resource
= resource_provider_
->CreateResourceFromTextureMailbox(
609 resources
.mailboxes
[media::VideoFrame::kAPlane
],
610 SingleReleaseCallbackImpl::Create(
611 resources
.release_callbacks
[media::VideoFrame::kAPlane
]));
614 YUVVideoDrawQuad
* yuv_quad
=
615 render_pass
->CreateAndAppendDrawQuad
<YUVVideoDrawQuad
>();
616 yuv_quad
->SetNew(shared_state
, rect
, opaque_rect
, rect
, tex_coord_rect
,
617 video_frame
->coded_size(), y_resource
, u_resource
,
618 v_resource
, a_resource
, color_space
);
621 void SetUp() override
{
622 GLRendererPixelTest::SetUp();
623 video_resource_updater_
.reset(new VideoResourceUpdater(
624 output_surface_
->context_provider(), resource_provider_
.get()));
628 scoped_ptr
<VideoResourceUpdater
> video_resource_updater_
;
631 TEST_F(VideoGLRendererPixelTest
, SimpleYUVRect
) {
632 gfx::Rect
rect(this->device_viewport_size_
);
634 RenderPassId
id(1, 1);
635 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
637 SharedQuadState
* shared_state
=
638 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
640 CreateTestYUVVideoDrawQuad_Striped(shared_state
,
641 media::VideoFrame::YV12
,
643 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
646 RenderPassList pass_list
;
647 pass_list
.push_back(pass
.Pass());
650 this->RunPixelTest(&pass_list
,
651 base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
652 FuzzyPixelOffByOneComparator(true)));
655 TEST_F(VideoGLRendererPixelTest
, OffsetYUVRect
) {
656 gfx::Rect
rect(this->device_viewport_size_
);
658 RenderPassId
id(1, 1);
659 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
661 SharedQuadState
* shared_state
=
662 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
664 // Intentionally sets frame format to I420 for testing coverage.
665 CreateTestYUVVideoDrawQuad_Striped(shared_state
,
666 media::VideoFrame::I420
,
668 gfx::RectF(0.125f
, 0.25f
, 0.75f
, 0.5f
),
671 RenderPassList pass_list
;
672 pass_list
.push_back(pass
.Pass());
674 EXPECT_TRUE(this->RunPixelTest(
676 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_offset.png")),
677 FuzzyPixelOffByOneComparator(true)));
680 TEST_F(VideoGLRendererPixelTest
, SimpleYUVRectBlack
) {
681 gfx::Rect
rect(this->device_viewport_size_
);
683 RenderPassId
id(1, 1);
684 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
686 SharedQuadState
* shared_state
=
687 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
689 // In MPEG color range YUV values of (15,128,128) should produce black.
690 CreateTestYUVVideoDrawQuad_Solid(shared_state
,
691 media::VideoFrame::YV12
,
693 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
699 RenderPassList pass_list
;
700 pass_list
.push_back(pass
.Pass());
702 // If we didn't get black out of the YUV values above, then we probably have a
703 // color range issue.
704 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
705 base::FilePath(FILE_PATH_LITERAL("black.png")),
706 FuzzyPixelOffByOneComparator(true)));
709 TEST_F(VideoGLRendererPixelTest
, SimpleYUVJRect
) {
710 gfx::Rect
rect(this->device_viewport_size_
);
712 RenderPassId
id(1, 1);
713 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
715 SharedQuadState
* shared_state
=
716 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
718 // YUV of (149,43,21) should be green (0,255,0) in RGB.
719 CreateTestYUVVideoDrawQuad_Solid(shared_state
,
720 media::VideoFrame::YV12J
,
722 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
728 RenderPassList pass_list
;
729 pass_list
.push_back(pass
.Pass());
731 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
732 base::FilePath(FILE_PATH_LITERAL("green.png")),
733 FuzzyPixelOffByOneComparator(true)));
736 // Test that a YUV video doesn't bleed outside of its tex coords when the
737 // tex coord rect is only a partial subrectangle of the coded contents.
738 TEST_F(VideoGLRendererPixelTest
, YUVEdgeBleed
) {
739 RenderPassList pass_list
;
740 CreateEdgeBleedPass(media::VideoFrame::YV12J
, &pass_list
);
741 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
742 base::FilePath(FILE_PATH_LITERAL("green.png")),
743 FuzzyPixelOffByOneComparator(true)));
746 TEST_F(VideoGLRendererPixelTest
, YUVAEdgeBleed
) {
747 RenderPassList pass_list
;
748 CreateEdgeBleedPass(media::VideoFrame::YV12A
, &pass_list
);
749 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
750 base::FilePath(FILE_PATH_LITERAL("green.png")),
751 FuzzyPixelOffByOneComparator(true)));
754 TEST_F(VideoGLRendererPixelTest
, SimpleYUVJRectGrey
) {
755 gfx::Rect
rect(this->device_viewport_size_
);
757 RenderPassId
id(1, 1);
758 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
760 SharedQuadState
* shared_state
=
761 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
763 // Dark grey in JPEG color range (in MPEG, this is black).
764 CreateTestYUVVideoDrawQuad_Solid(shared_state
,
765 media::VideoFrame::YV12J
,
767 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
773 RenderPassList pass_list
;
774 pass_list
.push_back(pass
.Pass());
777 this->RunPixelTest(&pass_list
,
778 base::FilePath(FILE_PATH_LITERAL("dark_grey.png")),
779 FuzzyPixelOffByOneComparator(true)));
782 TEST_F(VideoGLRendererPixelTest
, SimpleYUVARect
) {
783 gfx::Rect
rect(this->device_viewport_size_
);
785 RenderPassId
id(1, 1);
786 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
788 SharedQuadState
* shared_state
=
789 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
791 CreateTestYUVVideoDrawQuad_Striped(shared_state
,
792 media::VideoFrame::YV12A
,
794 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
797 SolidColorDrawQuad
* color_quad
=
798 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
799 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorWHITE
, false);
801 RenderPassList pass_list
;
802 pass_list
.push_back(pass
.Pass());
804 EXPECT_TRUE(this->RunPixelTest(
806 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_alpha.png")),
807 FuzzyPixelOffByOneComparator(true)));
810 TEST_F(VideoGLRendererPixelTest
, FullyTransparentYUVARect
) {
811 gfx::Rect
rect(this->device_viewport_size_
);
813 RenderPassId
id(1, 1);
814 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
816 SharedQuadState
* shared_state
=
817 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
819 CreateTestYUVVideoDrawQuad_Striped(shared_state
,
820 media::VideoFrame::YV12A
,
822 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
825 SolidColorDrawQuad
* color_quad
=
826 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
827 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorBLACK
, false);
829 RenderPassList pass_list
;
830 pass_list
.push_back(pass
.Pass());
832 EXPECT_TRUE(this->RunPixelTest(
834 base::FilePath(FILE_PATH_LITERAL("black.png")),
835 ExactPixelComparator(true)));
838 TYPED_TEST(RendererPixelTest
, FastPassColorFilterAlpha
) {
839 gfx::Rect
viewport_rect(this->device_viewport_size_
);
841 RenderPassId
root_pass_id(1, 1);
842 scoped_ptr
<RenderPass
> root_pass
=
843 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
845 RenderPassId
child_pass_id(2, 2);
846 gfx::Rect
pass_rect(this->device_viewport_size_
);
847 gfx::Transform transform_to_root
;
848 scoped_ptr
<RenderPass
> child_pass
=
849 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
851 gfx::Transform content_to_target_transform
;
852 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
853 content_to_target_transform
, viewport_rect
, child_pass
.get());
854 shared_state
->opacity
= 0.5f
;
856 gfx::Rect
blue_rect(0,
858 this->device_viewport_size_
.width(),
859 this->device_viewport_size_
.height() / 2);
860 SolidColorDrawQuad
* blue
=
861 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
862 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
863 gfx::Rect
yellow_rect(0,
864 this->device_viewport_size_
.height() / 2,
865 this->device_viewport_size_
.width(),
866 this->device_viewport_size_
.height() / 2);
867 SolidColorDrawQuad
* yellow
=
868 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
869 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
871 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
872 content_to_target_transform
, viewport_rect
, child_pass
.get());
874 SolidColorDrawQuad
* white
=
875 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
877 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
879 SharedQuadState
* pass_shared_state
=
880 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
884 matrix
[0] = 0.213f
+ 0.787f
* amount
;
885 matrix
[1] = 0.715f
- 0.715f
* amount
;
886 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
887 matrix
[3] = matrix
[4] = 0;
888 matrix
[5] = 0.213f
- 0.213f
* amount
;
889 matrix
[6] = 0.715f
+ 0.285f
* amount
;
890 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
891 matrix
[8] = matrix
[9] = 0;
892 matrix
[10] = 0.213f
- 0.213f
* amount
;
893 matrix
[11] = 0.715f
- 0.715f
* amount
;
894 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
895 matrix
[13] = matrix
[14] = 0;
896 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
898 skia::RefPtr
<SkColorFilter
> colorFilter(
899 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
900 skia::RefPtr
<SkImageFilter
> filter
=
901 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter
.get(), NULL
));
902 FilterOperations filters
;
903 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
905 RenderPassDrawQuad
* render_pass_quad
=
906 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
907 render_pass_quad
->SetNew(pass_shared_state
,
918 RenderPassList pass_list
;
919 pass_list
.push_back(child_pass
.Pass());
920 pass_list
.push_back(root_pass
.Pass());
922 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
923 // renderer so use a fuzzy comparator.
924 EXPECT_TRUE(this->RunPixelTest(
926 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
927 FuzzyForSoftwareOnlyPixelComparator
<TypeParam
>(false)));
930 TYPED_TEST(RendererPixelTest
, FastPassSaturateFilter
) {
931 gfx::Rect
viewport_rect(this->device_viewport_size_
);
933 RenderPassId
root_pass_id(1, 1);
934 scoped_ptr
<RenderPass
> root_pass
=
935 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
937 RenderPassId
child_pass_id(2, 2);
938 gfx::Rect
pass_rect(this->device_viewport_size_
);
939 gfx::Transform transform_to_root
;
940 scoped_ptr
<RenderPass
> child_pass
=
941 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
943 gfx::Transform content_to_target_transform
;
944 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
945 content_to_target_transform
, viewport_rect
, child_pass
.get());
946 shared_state
->opacity
= 0.5f
;
948 gfx::Rect
blue_rect(0,
950 this->device_viewport_size_
.width(),
951 this->device_viewport_size_
.height() / 2);
952 SolidColorDrawQuad
* blue
=
953 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
954 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
955 gfx::Rect
yellow_rect(0,
956 this->device_viewport_size_
.height() / 2,
957 this->device_viewport_size_
.width(),
958 this->device_viewport_size_
.height() / 2);
959 SolidColorDrawQuad
* yellow
=
960 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
961 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
963 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
964 content_to_target_transform
, viewport_rect
, child_pass
.get());
966 SolidColorDrawQuad
* white
=
967 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
969 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
971 SharedQuadState
* pass_shared_state
=
972 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
974 FilterOperations filters
;
975 filters
.Append(FilterOperation::CreateSaturateFilter(0.5f
));
977 RenderPassDrawQuad
* render_pass_quad
=
978 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
979 render_pass_quad
->SetNew(pass_shared_state
,
990 RenderPassList pass_list
;
991 pass_list
.push_back(child_pass
.Pass());
992 pass_list
.push_back(root_pass
.Pass());
994 EXPECT_TRUE(this->RunPixelTest(
996 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
997 ExactPixelComparator(true)));
1000 TYPED_TEST(RendererPixelTest
, FastPassFilterChain
) {
1001 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1003 RenderPassId
root_pass_id(1, 1);
1004 scoped_ptr
<RenderPass
> root_pass
=
1005 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1007 RenderPassId
child_pass_id(2, 2);
1008 gfx::Rect
pass_rect(this->device_viewport_size_
);
1009 gfx::Transform transform_to_root
;
1010 scoped_ptr
<RenderPass
> child_pass
=
1011 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1013 gfx::Transform content_to_target_transform
;
1014 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1015 content_to_target_transform
, viewport_rect
, child_pass
.get());
1016 shared_state
->opacity
= 0.5f
;
1018 gfx::Rect
blue_rect(0,
1020 this->device_viewport_size_
.width(),
1021 this->device_viewport_size_
.height() / 2);
1022 SolidColorDrawQuad
* blue
=
1023 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1024 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1025 gfx::Rect
yellow_rect(0,
1026 this->device_viewport_size_
.height() / 2,
1027 this->device_viewport_size_
.width(),
1028 this->device_viewport_size_
.height() / 2);
1029 SolidColorDrawQuad
* yellow
=
1030 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1031 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1033 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
1034 content_to_target_transform
, viewport_rect
, child_pass
.get());
1036 SolidColorDrawQuad
* white
=
1037 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1039 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
1041 SharedQuadState
* pass_shared_state
=
1042 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1044 FilterOperations filters
;
1045 filters
.Append(FilterOperation::CreateGrayscaleFilter(1.f
));
1046 filters
.Append(FilterOperation::CreateBrightnessFilter(0.5f
));
1048 RenderPassDrawQuad
* render_pass_quad
=
1049 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1050 render_pass_quad
->SetNew(pass_shared_state
,
1059 FilterOperations());
1061 RenderPassList pass_list
;
1062 pass_list
.push_back(child_pass
.Pass());
1063 pass_list
.push_back(root_pass
.Pass());
1065 EXPECT_TRUE(this->RunPixelTest(
1067 base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")),
1068 ExactPixelComparator(true)));
1071 TYPED_TEST(RendererPixelTest
, FastPassColorFilterAlphaTranslation
) {
1072 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1074 RenderPassId
root_pass_id(1, 1);
1075 scoped_ptr
<RenderPass
> root_pass
=
1076 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1078 RenderPassId
child_pass_id(2, 2);
1079 gfx::Rect
pass_rect(this->device_viewport_size_
);
1080 gfx::Transform transform_to_root
;
1081 scoped_ptr
<RenderPass
> child_pass
=
1082 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1084 gfx::Transform content_to_target_transform
;
1085 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1086 content_to_target_transform
, viewport_rect
, child_pass
.get());
1087 shared_state
->opacity
= 0.5f
;
1089 gfx::Rect
blue_rect(0,
1091 this->device_viewport_size_
.width(),
1092 this->device_viewport_size_
.height() / 2);
1093 SolidColorDrawQuad
* blue
=
1094 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1095 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1096 gfx::Rect
yellow_rect(0,
1097 this->device_viewport_size_
.height() / 2,
1098 this->device_viewport_size_
.width(),
1099 this->device_viewport_size_
.height() / 2);
1100 SolidColorDrawQuad
* yellow
=
1101 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1102 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1104 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
1105 content_to_target_transform
, viewport_rect
, child_pass
.get());
1107 SolidColorDrawQuad
* white
=
1108 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1110 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
1112 SharedQuadState
* pass_shared_state
=
1113 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1115 SkScalar matrix
[20];
1116 float amount
= 0.5f
;
1117 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1118 matrix
[1] = 0.715f
- 0.715f
* amount
;
1119 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1122 matrix
[5] = 0.213f
- 0.213f
* amount
;
1123 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1124 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1127 matrix
[10] = 0.213f
- 0.213f
* amount
;
1128 matrix
[11] = 0.715f
- 0.715f
* amount
;
1129 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1132 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1134 skia::RefPtr
<SkColorFilter
> colorFilter(
1135 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1136 skia::RefPtr
<SkImageFilter
> filter
=
1137 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter
.get(), NULL
));
1138 FilterOperations filters
;
1139 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1141 RenderPassDrawQuad
* render_pass_quad
=
1142 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1143 render_pass_quad
->SetNew(pass_shared_state
,
1152 FilterOperations());
1154 RenderPassList pass_list
;
1156 pass_list
.push_back(child_pass
.Pass());
1157 pass_list
.push_back(root_pass
.Pass());
1159 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1160 // renderer so use a fuzzy comparator.
1161 EXPECT_TRUE(this->RunPixelTest(
1163 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
1164 FuzzyForSoftwareOnlyPixelComparator
<TypeParam
>(false)));
1167 TYPED_TEST(RendererPixelTest
, EnlargedRenderPassTexture
) {
1168 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1170 RenderPassId
root_pass_id(1, 1);
1171 scoped_ptr
<RenderPass
> root_pass
=
1172 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1174 RenderPassId
child_pass_id(2, 2);
1175 gfx::Rect
pass_rect(this->device_viewport_size_
);
1176 gfx::Transform transform_to_root
;
1177 scoped_ptr
<RenderPass
> child_pass
=
1178 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1180 gfx::Transform content_to_target_transform
;
1181 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1182 content_to_target_transform
, viewport_rect
, child_pass
.get());
1184 gfx::Rect
blue_rect(0,
1186 this->device_viewport_size_
.width(),
1187 this->device_viewport_size_
.height() / 2);
1188 SolidColorDrawQuad
* blue
=
1189 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1190 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1191 gfx::Rect
yellow_rect(0,
1192 this->device_viewport_size_
.height() / 2,
1193 this->device_viewport_size_
.width(),
1194 this->device_viewport_size_
.height() / 2);
1195 SolidColorDrawQuad
* yellow
=
1196 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1197 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1199 SharedQuadState
* pass_shared_state
=
1200 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1201 CreateTestRenderPassDrawQuad(
1202 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
1204 RenderPassList pass_list
;
1205 pass_list
.push_back(child_pass
.Pass());
1206 pass_list
.push_back(root_pass
.Pass());
1208 this->renderer_
->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1210 EXPECT_TRUE(this->RunPixelTest(
1212 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
1213 ExactPixelComparator(true)));
1216 TYPED_TEST(RendererPixelTest
, EnlargedRenderPassTextureWithAntiAliasing
) {
1217 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1219 RenderPassId
root_pass_id(1, 1);
1220 scoped_ptr
<RenderPass
> root_pass
=
1221 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1223 RenderPassId
child_pass_id(2, 2);
1224 gfx::Rect
pass_rect(this->device_viewport_size_
);
1225 gfx::Transform transform_to_root
;
1226 scoped_ptr
<RenderPass
> child_pass
=
1227 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1229 gfx::Transform content_to_target_transform
;
1230 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1231 content_to_target_transform
, viewport_rect
, child_pass
.get());
1233 gfx::Rect
blue_rect(0,
1235 this->device_viewport_size_
.width(),
1236 this->device_viewport_size_
.height() / 2);
1237 SolidColorDrawQuad
* blue
=
1238 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1239 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1240 gfx::Rect
yellow_rect(0,
1241 this->device_viewport_size_
.height() / 2,
1242 this->device_viewport_size_
.width(),
1243 this->device_viewport_size_
.height() / 2);
1244 SolidColorDrawQuad
* yellow
=
1245 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1246 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1248 gfx::Transform aa_transform
;
1249 aa_transform
.Translate(0.5, 0.0);
1251 SharedQuadState
* pass_shared_state
=
1252 CreateTestSharedQuadState(aa_transform
, pass_rect
, root_pass
.get());
1253 CreateTestRenderPassDrawQuad(
1254 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
1256 SharedQuadState
* root_shared_state
= CreateTestSharedQuadState(
1257 gfx::Transform(), viewport_rect
, root_pass
.get());
1258 SolidColorDrawQuad
* background
=
1259 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1260 background
->SetNew(root_shared_state
,
1261 gfx::Rect(this->device_viewport_size_
),
1262 gfx::Rect(this->device_viewport_size_
),
1266 RenderPassList pass_list
;
1267 pass_list
.push_back(child_pass
.Pass());
1268 pass_list
.push_back(root_pass
.Pass());
1270 this->renderer_
->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1272 EXPECT_TRUE(this->RunPixelTest(
1274 base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")),
1275 FuzzyPixelOffByOneComparator(true)));
1278 // This tests the case where we have a RenderPass with a mask, but the quad
1279 // for the masked surface does not include the full surface texture.
1280 TYPED_TEST(RendererPixelTest
, RenderPassAndMaskWithPartialQuad
) {
1281 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1283 RenderPassId
root_pass_id(1, 1);
1284 scoped_ptr
<RenderPass
> root_pass
=
1285 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1286 SharedQuadState
* root_pass_shared_state
= CreateTestSharedQuadState(
1287 gfx::Transform(), viewport_rect
, root_pass
.get());
1289 RenderPassId
child_pass_id(2, 2);
1290 gfx::Transform transform_to_root
;
1291 scoped_ptr
<RenderPass
> child_pass
=
1292 CreateTestRenderPass(child_pass_id
, viewport_rect
, transform_to_root
);
1293 SharedQuadState
* child_pass_shared_state
= CreateTestSharedQuadState(
1294 gfx::Transform(), viewport_rect
, child_pass
.get());
1296 // The child render pass is just a green box.
1297 static const SkColor kCSSGreen
= 0xff008000;
1298 SolidColorDrawQuad
* green
=
1299 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1301 child_pass_shared_state
, viewport_rect
, viewport_rect
, kCSSGreen
, false);
1304 gfx::Rect mask_rect
= viewport_rect
;
1307 SkImageInfo::MakeN32Premul(mask_rect
.width(), mask_rect
.height()));
1308 SkCanvas
canvas(bitmap
);
1310 paint
.setStyle(SkPaint::kStroke_Style
);
1311 paint
.setStrokeWidth(SkIntToScalar(4));
1312 paint
.setColor(SK_ColorWHITE
);
1313 canvas
.clear(SK_ColorTRANSPARENT
);
1314 gfx::Rect rect
= mask_rect
;
1315 while (!rect
.IsEmpty()) {
1316 rect
.Inset(6, 6, 4, 4);
1318 SkRect::MakeXYWH(rect
.x(), rect
.y(), rect
.width(), rect
.height()),
1320 rect
.Inset(6, 6, 4, 4);
1323 ResourceProvider::ResourceId mask_resource_id
=
1324 this->resource_provider_
->CreateResource(
1325 mask_rect
.size(), GL_CLAMP_TO_EDGE
,
1326 ResourceProvider::TEXTURE_HINT_IMMUTABLE
, RGBA_8888
);
1328 SkAutoLockPixels
lock(bitmap
);
1329 this->resource_provider_
->CopyToResource(
1330 mask_resource_id
, reinterpret_cast<uint8_t*>(bitmap
.getPixels()),
1334 // This RenderPassDrawQuad does not include the full |viewport_rect| which is
1335 // the size of the child render pass.
1336 gfx::Rect sub_rect
= gfx::Rect(50, 50, 200, 100);
1337 EXPECT_NE(sub_rect
.x(), child_pass
->output_rect
.x());
1338 EXPECT_NE(sub_rect
.y(), child_pass
->output_rect
.y());
1339 EXPECT_NE(sub_rect
.right(), child_pass
->output_rect
.right());
1340 EXPECT_NE(sub_rect
.bottom(), child_pass
->output_rect
.bottom());
1342 // Set up a mask on the RenderPassDrawQuad.
1343 RenderPassDrawQuad
* mask_quad
=
1344 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1345 mask_quad
->SetNew(root_pass_shared_state
,
1350 gfx::Vector2dF(2.f
, 1.f
), // mask_uv_scale
1351 gfx::Size(mask_rect
.size()), // mask_texture_size
1352 FilterOperations(), // foreground filters
1353 gfx::Vector2dF(), // filters scale
1354 FilterOperations()); // background filters
1356 // White background behind the masked render pass.
1357 SolidColorDrawQuad
* white
=
1358 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1359 white
->SetNew(root_pass_shared_state
,
1365 RenderPassList pass_list
;
1366 pass_list
.push_back(child_pass
.Pass());
1367 pass_list
.push_back(root_pass
.Pass());
1369 EXPECT_TRUE(this->RunPixelTest(
1371 base::FilePath(FILE_PATH_LITERAL("mask_bottom_right.png")),
1372 ExactPixelComparator(true)));
1375 template <typename RendererType
>
1376 class RendererPixelTestWithBackgroundFilter
1377 : public RendererPixelTest
<RendererType
> {
1379 void SetUpRenderPassList() {
1380 gfx::Rect
device_viewport_rect(this->device_viewport_size_
);
1382 RenderPassId
root_id(1, 1);
1383 scoped_ptr
<RenderPass
> root_pass
=
1384 CreateTestRootRenderPass(root_id
, device_viewport_rect
);
1385 root_pass
->has_transparent_background
= false;
1387 gfx::Transform identity_content_to_target_transform
;
1389 RenderPassId
filter_pass_id(2, 1);
1390 gfx::Transform transform_to_root
;
1391 scoped_ptr
<RenderPass
> filter_pass
=
1392 CreateTestRenderPass(filter_pass_id
,
1393 filter_pass_content_rect_
,
1396 // A non-visible quad in the filtering render pass.
1398 SharedQuadState
* shared_state
=
1399 CreateTestSharedQuadState(identity_content_to_target_transform
,
1400 filter_pass_content_rect_
,
1402 SolidColorDrawQuad
* color_quad
=
1403 filter_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1404 color_quad
->SetNew(shared_state
,
1405 filter_pass_content_rect_
,
1406 filter_pass_content_rect_
,
1407 SK_ColorTRANSPARENT
,
1412 SharedQuadState
* shared_state
=
1413 CreateTestSharedQuadState(filter_pass_to_target_transform_
,
1414 filter_pass_content_rect_
,
1416 RenderPassDrawQuad
* filter_pass_quad
=
1417 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1418 filter_pass_quad
->SetNew(shared_state
,
1419 filter_pass_content_rect_
,
1420 filter_pass_content_rect_
,
1422 0, // mask_resource_id
1423 gfx::Vector2dF(), // mask_uv_scale
1424 gfx::Size(), // mask_texture_size
1425 FilterOperations(), // filters
1426 gfx::Vector2dF(), // filters_scale
1427 this->background_filters_
);
1430 const int kColumnWidth
= device_viewport_rect
.width() / 3;
1432 gfx::Rect left_rect
= gfx::Rect(0, 0, kColumnWidth
, 20);
1433 for (int i
= 0; left_rect
.y() < device_viewport_rect
.height(); ++i
) {
1434 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1435 identity_content_to_target_transform
, left_rect
, root_pass
.get());
1436 SolidColorDrawQuad
* color_quad
=
1437 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1439 shared_state
, left_rect
, left_rect
, SK_ColorGREEN
, false);
1440 left_rect
+= gfx::Vector2d(0, left_rect
.height() + 1);
1443 gfx::Rect middle_rect
= gfx::Rect(kColumnWidth
+1, 0, kColumnWidth
, 20);
1444 for (int i
= 0; middle_rect
.y() < device_viewport_rect
.height(); ++i
) {
1445 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1446 identity_content_to_target_transform
, middle_rect
, root_pass
.get());
1447 SolidColorDrawQuad
* color_quad
=
1448 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1450 shared_state
, middle_rect
, middle_rect
, SK_ColorRED
, false);
1451 middle_rect
+= gfx::Vector2d(0, middle_rect
.height() + 1);
1454 gfx::Rect right_rect
= gfx::Rect((kColumnWidth
+1)*2, 0, kColumnWidth
, 20);
1455 for (int i
= 0; right_rect
.y() < device_viewport_rect
.height(); ++i
) {
1456 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1457 identity_content_to_target_transform
, right_rect
, root_pass
.get());
1458 SolidColorDrawQuad
* color_quad
=
1459 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1461 shared_state
, right_rect
, right_rect
, SK_ColorBLUE
, false);
1462 right_rect
+= gfx::Vector2d(0, right_rect
.height() + 1);
1465 SharedQuadState
* shared_state
=
1466 CreateTestSharedQuadState(identity_content_to_target_transform
,
1467 device_viewport_rect
,
1469 SolidColorDrawQuad
* background_quad
=
1470 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1471 background_quad
->SetNew(shared_state
,
1472 device_viewport_rect
,
1473 device_viewport_rect
,
1477 pass_list_
.push_back(filter_pass
.Pass());
1478 pass_list_
.push_back(root_pass
.Pass());
1481 RenderPassList pass_list_
;
1482 FilterOperations background_filters_
;
1483 gfx::Transform filter_pass_to_target_transform_
;
1484 gfx::Rect filter_pass_content_rect_
;
1487 typedef ::testing::Types
<GLRenderer
, SoftwareRenderer
>
1488 BackgroundFilterRendererTypes
;
1489 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter
,
1490 BackgroundFilterRendererTypes
);
1492 typedef RendererPixelTestWithBackgroundFilter
<GLRenderer
>
1493 GLRendererPixelTestWithBackgroundFilter
;
1495 // TODO(skaslev): The software renderer does not support filters yet.
1496 TEST_F(GLRendererPixelTestWithBackgroundFilter
, InvertFilter
) {
1497 this->background_filters_
.Append(
1498 FilterOperation::CreateInvertFilter(1.f
));
1500 this->filter_pass_content_rect_
= gfx::Rect(this->device_viewport_size_
);
1501 this->filter_pass_content_rect_
.Inset(12, 14, 16, 18);
1503 this->SetUpRenderPassList();
1504 EXPECT_TRUE(this->RunPixelTest(
1506 base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
1507 ExactPixelComparator(true)));
1510 class ExternalStencilPixelTest
: public GLRendererPixelTest
{
1512 void ClearBackgroundToGreen() {
1513 GLES2Interface
* gl
= output_surface_
->context_provider()->ContextGL();
1514 output_surface_
->EnsureBackbuffer();
1515 output_surface_
->Reshape(device_viewport_size_
, 1);
1516 gl
->ClearColor(0.f
, 1.f
, 0.f
, 1.f
);
1517 gl
->Clear(GL_COLOR_BUFFER_BIT
);
1520 void PopulateStencilBuffer() {
1521 // Set two quadrants of the stencil buffer to 1.
1522 GLES2Interface
* gl
= output_surface_
->context_provider()->ContextGL();
1523 output_surface_
->EnsureBackbuffer();
1524 output_surface_
->Reshape(device_viewport_size_
, 1);
1525 gl
->ClearStencil(0);
1526 gl
->Clear(GL_STENCIL_BUFFER_BIT
);
1527 gl
->Enable(GL_SCISSOR_TEST
);
1528 gl
->ClearStencil(1);
1531 device_viewport_size_
.width() / 2,
1532 device_viewport_size_
.height() / 2);
1533 gl
->Clear(GL_STENCIL_BUFFER_BIT
);
1534 gl
->Scissor(device_viewport_size_
.width() / 2,
1535 device_viewport_size_
.height() / 2,
1536 device_viewport_size_
.width(),
1537 device_viewport_size_
.height());
1538 gl
->Clear(GL_STENCIL_BUFFER_BIT
);
1542 TEST_F(ExternalStencilPixelTest
, StencilTestEnabled
) {
1543 ClearBackgroundToGreen();
1544 PopulateStencilBuffer();
1545 this->EnableExternalStencilTest();
1547 // Draw a blue quad that covers the entire device viewport. It should be
1548 // clipped to the bottom left and top right corners by the external stencil.
1549 gfx::Rect
rect(this->device_viewport_size_
);
1550 RenderPassId
id(1, 1);
1551 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1552 SharedQuadState
* blue_shared_state
=
1553 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1554 SolidColorDrawQuad
* blue
=
1555 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1556 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
1557 pass
->has_transparent_background
= false;
1558 RenderPassList pass_list
;
1559 pass_list
.push_back(pass
.Pass());
1561 EXPECT_TRUE(this->RunPixelTest(
1563 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1564 ExactPixelComparator(true)));
1567 TEST_F(ExternalStencilPixelTest
, StencilTestDisabled
) {
1568 PopulateStencilBuffer();
1570 // Draw a green quad that covers the entire device viewport. The stencil
1571 // buffer should be ignored.
1572 gfx::Rect
rect(this->device_viewport_size_
);
1573 RenderPassId
id(1, 1);
1574 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1575 SharedQuadState
* green_shared_state
=
1576 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1577 SolidColorDrawQuad
* green
=
1578 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1579 green
->SetNew(green_shared_state
, rect
, rect
, SK_ColorGREEN
, false);
1580 RenderPassList pass_list
;
1581 pass_list
.push_back(pass
.Pass());
1583 EXPECT_TRUE(this->RunPixelTest(
1585 base::FilePath(FILE_PATH_LITERAL("green.png")),
1586 ExactPixelComparator(true)));
1589 TEST_F(ExternalStencilPixelTest
, RenderSurfacesIgnoreStencil
) {
1590 // The stencil test should apply only to the final render pass.
1591 ClearBackgroundToGreen();
1592 PopulateStencilBuffer();
1593 this->EnableExternalStencilTest();
1595 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1597 RenderPassId
root_pass_id(1, 1);
1598 scoped_ptr
<RenderPass
> root_pass
=
1599 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1600 root_pass
->has_transparent_background
= false;
1602 RenderPassId
child_pass_id(2, 2);
1603 gfx::Rect
pass_rect(this->device_viewport_size_
);
1604 gfx::Transform transform_to_root
;
1605 scoped_ptr
<RenderPass
> child_pass
=
1606 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1608 gfx::Transform content_to_target_transform
;
1609 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1610 content_to_target_transform
, viewport_rect
, child_pass
.get());
1612 gfx::Rect
blue_rect(0,
1614 this->device_viewport_size_
.width(),
1615 this->device_viewport_size_
.height());
1616 SolidColorDrawQuad
* blue
=
1617 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1618 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1620 SharedQuadState
* pass_shared_state
=
1621 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1622 CreateTestRenderPassDrawQuad(
1623 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
1624 RenderPassList pass_list
;
1625 pass_list
.push_back(child_pass
.Pass());
1626 pass_list
.push_back(root_pass
.Pass());
1628 EXPECT_TRUE(this->RunPixelTest(
1630 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1631 ExactPixelComparator(true)));
1634 TEST_F(ExternalStencilPixelTest
, DeviceClip
) {
1635 ClearBackgroundToGreen();
1636 gfx::Rect
clip_rect(gfx::Point(150, 150), gfx::Size(50, 50));
1637 this->ForceDeviceClip(clip_rect
);
1639 // Draw a blue quad that covers the entire device viewport. It should be
1640 // clipped to the bottom right corner by the device clip.
1641 gfx::Rect
rect(this->device_viewport_size_
);
1642 RenderPassId
id(1, 1);
1643 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1644 SharedQuadState
* blue_shared_state
=
1645 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1646 SolidColorDrawQuad
* blue
=
1647 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1648 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
1649 RenderPassList pass_list
;
1650 pass_list
.push_back(pass
.Pass());
1652 EXPECT_TRUE(this->RunPixelTest(
1654 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
1655 ExactPixelComparator(true)));
1658 // Software renderer does not support anti-aliased edges.
1659 TEST_F(GLRendererPixelTest
, AntiAliasing
) {
1660 gfx::Rect
rect(this->device_viewport_size_
);
1662 RenderPassId
id(1, 1);
1663 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1665 gfx::Transform red_content_to_target_transform
;
1666 red_content_to_target_transform
.Rotate(10);
1667 SharedQuadState
* red_shared_state
= CreateTestSharedQuadState(
1668 red_content_to_target_transform
, rect
, pass
.get());
1670 SolidColorDrawQuad
* red
= pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1671 red
->SetNew(red_shared_state
, rect
, rect
, SK_ColorRED
, false);
1673 gfx::Transform yellow_content_to_target_transform
;
1674 yellow_content_to_target_transform
.Rotate(5);
1675 SharedQuadState
* yellow_shared_state
= CreateTestSharedQuadState(
1676 yellow_content_to_target_transform
, rect
, pass
.get());
1678 SolidColorDrawQuad
* yellow
=
1679 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1680 yellow
->SetNew(yellow_shared_state
, rect
, rect
, SK_ColorYELLOW
, false);
1682 gfx::Transform blue_content_to_target_transform
;
1683 SharedQuadState
* blue_shared_state
= CreateTestSharedQuadState(
1684 blue_content_to_target_transform
, rect
, pass
.get());
1686 SolidColorDrawQuad
* blue
=
1687 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1688 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
1690 RenderPassList pass_list
;
1691 pass_list
.push_back(pass
.Pass());
1693 EXPECT_TRUE(this->RunPixelTest(
1695 base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")),
1696 FuzzyPixelOffByOneComparator(true)));
1699 // This test tests that anti-aliasing works for axis aligned quads.
1700 // Anti-aliasing is only supported in the gl renderer.
1701 TEST_F(GLRendererPixelTest
, AxisAligned
) {
1702 gfx::Rect
rect(this->device_viewport_size_
);
1704 RenderPassId
id(1, 1);
1705 gfx::Transform transform_to_root
;
1706 scoped_ptr
<RenderPass
> pass
=
1707 CreateTestRenderPass(id
, rect
, transform_to_root
);
1709 gfx::Transform red_content_to_target_transform
;
1710 red_content_to_target_transform
.Translate(50, 50);
1711 red_content_to_target_transform
.Scale(
1712 0.5f
+ 1.0f
/ (rect
.width() * 2.0f
),
1713 0.5f
+ 1.0f
/ (rect
.height() * 2.0f
));
1714 SharedQuadState
* red_shared_state
= CreateTestSharedQuadState(
1715 red_content_to_target_transform
, rect
, pass
.get());
1717 SolidColorDrawQuad
* red
= pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1718 red
->SetNew(red_shared_state
, rect
, rect
, SK_ColorRED
, false);
1720 gfx::Transform yellow_content_to_target_transform
;
1721 yellow_content_to_target_transform
.Translate(25.5f
, 25.5f
);
1722 yellow_content_to_target_transform
.Scale(0.5f
, 0.5f
);
1723 SharedQuadState
* yellow_shared_state
= CreateTestSharedQuadState(
1724 yellow_content_to_target_transform
, rect
, pass
.get());
1726 SolidColorDrawQuad
* yellow
=
1727 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1728 yellow
->SetNew(yellow_shared_state
, rect
, rect
, SK_ColorYELLOW
, false);
1730 gfx::Transform blue_content_to_target_transform
;
1731 SharedQuadState
* blue_shared_state
= CreateTestSharedQuadState(
1732 blue_content_to_target_transform
, rect
, pass
.get());
1734 SolidColorDrawQuad
* blue
=
1735 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1736 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
1738 RenderPassList pass_list
;
1739 pass_list
.push_back(pass
.Pass());
1741 EXPECT_TRUE(this->RunPixelTest(
1743 base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")),
1744 ExactPixelComparator(true)));
1747 // This test tests that forcing anti-aliasing off works as expected.
1748 // Anti-aliasing is only supported in the gl renderer.
1749 TEST_F(GLRendererPixelTest
, ForceAntiAliasingOff
) {
1750 gfx::Rect
rect(this->device_viewport_size_
);
1752 RenderPassId
id(1, 1);
1753 gfx::Transform transform_to_root
;
1754 scoped_ptr
<RenderPass
> pass
=
1755 CreateTestRenderPass(id
, rect
, transform_to_root
);
1757 gfx::Transform hole_content_to_target_transform
;
1758 hole_content_to_target_transform
.Translate(50, 50);
1759 hole_content_to_target_transform
.Scale(
1760 0.5f
+ 1.0f
/ (rect
.width() * 2.0f
),
1761 0.5f
+ 1.0f
/ (rect
.height() * 2.0f
));
1762 SharedQuadState
* hole_shared_state
= CreateTestSharedQuadState(
1763 hole_content_to_target_transform
, rect
, pass
.get());
1765 SolidColorDrawQuad
* hole
=
1766 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1768 hole_shared_state
, rect
, rect
, rect
, false, SK_ColorTRANSPARENT
, true);
1770 gfx::Transform green_content_to_target_transform
;
1771 SharedQuadState
* green_shared_state
= CreateTestSharedQuadState(
1772 green_content_to_target_transform
, rect
, pass
.get());
1774 SolidColorDrawQuad
* green
=
1775 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1776 green
->SetNew(green_shared_state
, rect
, rect
, SK_ColorGREEN
, false);
1778 RenderPassList pass_list
;
1779 pass_list
.push_back(pass
.Pass());
1781 EXPECT_TRUE(this->RunPixelTest(
1783 base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")),
1784 ExactPixelComparator(false)));
1787 TEST_F(GLRendererPixelTest
, AntiAliasingPerspective
) {
1788 gfx::Rect
rect(this->device_viewport_size_
);
1790 scoped_ptr
<RenderPass
> pass
=
1791 CreateTestRootRenderPass(RenderPassId(1, 1), rect
);
1793 gfx::Rect
red_rect(0, 0, 180, 500);
1794 gfx::Transform
red_content_to_target_transform(
1795 1.0f
, 2.4520f
, 10.6206f
, 19.0f
,
1796 0.0f
, 0.3528f
, 5.9737f
, 9.5f
,
1797 0.0f
, -0.2250f
, -0.9744f
, 0.0f
,
1798 0.0f
, 0.0225f
, 0.0974f
, 1.0f
);
1799 SharedQuadState
* red_shared_state
= CreateTestSharedQuadState(
1800 red_content_to_target_transform
, red_rect
, pass
.get());
1801 SolidColorDrawQuad
* red
= pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1802 red
->SetNew(red_shared_state
, red_rect
, red_rect
, SK_ColorRED
, false);
1804 gfx::Rect
green_rect(19, 7, 180, 10);
1805 SharedQuadState
* green_shared_state
=
1806 CreateTestSharedQuadState(gfx::Transform(), green_rect
, pass
.get());
1807 SolidColorDrawQuad
* green
=
1808 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1810 green_shared_state
, green_rect
, green_rect
, SK_ColorGREEN
, false);
1812 SharedQuadState
* blue_shared_state
=
1813 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1814 SolidColorDrawQuad
* blue
=
1815 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1816 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
1818 RenderPassList pass_list
;
1819 pass_list
.push_back(pass
.Pass());
1821 EXPECT_TRUE(this->RunPixelTest(
1823 base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")),
1824 FuzzyPixelOffByOneComparator(true)));
1827 TYPED_TEST(SoftwareRendererPixelTest
, PictureDrawQuadIdentityScale
) {
1828 gfx::Size
pile_tile_size(1000, 1000);
1829 gfx::Rect
viewport(this->device_viewport_size_
);
1830 // TODO(enne): the renderer should figure this out on its own.
1831 ResourceFormat texture_format
= RGBA_8888
;
1832 bool nearest_neighbor
= false;
1834 RenderPassId
id(1, 1);
1835 gfx::Transform transform_to_root
;
1836 scoped_ptr
<RenderPass
> pass
=
1837 CreateTestRenderPass(id
, viewport
, transform_to_root
);
1839 // One clipped blue quad in the lower right corner. Outside the clip
1840 // is red, which should not appear.
1841 gfx::Rect
blue_rect(gfx::Size(100, 100));
1842 gfx::Rect
blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50));
1844 scoped_ptr
<FakePicturePile
> blue_recording
=
1845 FakePicturePile::CreateFilledPile(pile_tile_size
, blue_rect
.size());
1847 red_paint
.setColor(SK_ColorRED
);
1848 blue_recording
->add_draw_rect_with_paint(blue_rect
, red_paint
);
1850 blue_paint
.setColor(SK_ColorBLUE
);
1851 blue_recording
->add_draw_rect_with_paint(blue_clip_rect
, blue_paint
);
1852 blue_recording
->RerecordPile();
1854 scoped_refptr
<FakePicturePileImpl
> blue_pile
=
1855 FakePicturePileImpl::CreateFromPile(blue_recording
.get(), nullptr);
1857 gfx::Transform blue_content_to_target_transform
;
1858 gfx::Vector2d
offset(viewport
.bottom_right() - blue_rect
.bottom_right());
1859 blue_content_to_target_transform
.Translate(offset
.x(), offset
.y());
1860 gfx::RectF blue_scissor_rect
= blue_clip_rect
;
1861 blue_content_to_target_transform
.TransformRect(&blue_scissor_rect
);
1862 SharedQuadState
* blue_shared_state
=
1863 CreateTestSharedQuadStateClipped(blue_content_to_target_transform
,
1865 gfx::ToEnclosingRect(blue_scissor_rect
),
1868 PictureDrawQuad
* blue_quad
= pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
1870 blue_quad
->SetNew(blue_shared_state
,
1871 viewport
, // Intentionally bigger than clip.
1872 gfx::Rect(), viewport
, gfx::RectF(viewport
),
1873 viewport
.size(), nearest_neighbor
, texture_format
, viewport
,
1874 1.f
, blue_pile
.get());
1876 // One viewport-filling green quad.
1877 scoped_ptr
<FakePicturePile
> green_recording
=
1878 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
1879 SkPaint green_paint
;
1880 green_paint
.setColor(SK_ColorGREEN
);
1881 green_recording
->add_draw_rect_with_paint(viewport
, green_paint
);
1882 green_recording
->RerecordPile();
1883 scoped_refptr
<FakePicturePileImpl
> green_pile
=
1884 FakePicturePileImpl::CreateFromPile(green_recording
.get(), nullptr);
1886 gfx::Transform green_content_to_target_transform
;
1887 SharedQuadState
* green_shared_state
= CreateTestSharedQuadState(
1888 green_content_to_target_transform
, viewport
, pass
.get());
1890 PictureDrawQuad
* green_quad
=
1891 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
1892 green_quad
->SetNew(green_shared_state
, viewport
, gfx::Rect(), viewport
,
1893 gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
), viewport
.size(),
1894 nearest_neighbor
, texture_format
, viewport
, 1.f
,
1897 RenderPassList pass_list
;
1898 pass_list
.push_back(pass
.Pass());
1900 EXPECT_TRUE(this->RunPixelTest(
1902 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
1903 ExactPixelComparator(true)));
1906 // Not WithSkiaGPUBackend since that path currently requires tiles for opacity.
1907 TYPED_TEST(SoftwareRendererPixelTest
, PictureDrawQuadOpacity
) {
1908 gfx::Size
pile_tile_size(1000, 1000);
1909 gfx::Rect
viewport(this->device_viewport_size_
);
1910 ResourceFormat texture_format
= RGBA_8888
;
1911 bool nearest_neighbor
= false;
1913 RenderPassId
id(1, 1);
1914 gfx::Transform transform_to_root
;
1915 scoped_ptr
<RenderPass
> pass
=
1916 CreateTestRenderPass(id
, viewport
, transform_to_root
);
1918 // One viewport-filling 0.5-opacity green quad.
1919 scoped_ptr
<FakePicturePile
> green_recording
=
1920 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
1921 SkPaint green_paint
;
1922 green_paint
.setColor(SK_ColorGREEN
);
1923 green_recording
->add_draw_rect_with_paint(viewport
, green_paint
);
1924 green_recording
->RerecordPile();
1925 scoped_refptr
<FakePicturePileImpl
> green_pile
=
1926 FakePicturePileImpl::CreateFromPile(green_recording
.get(), nullptr);
1928 gfx::Transform green_content_to_target_transform
;
1929 SharedQuadState
* green_shared_state
= CreateTestSharedQuadState(
1930 green_content_to_target_transform
, viewport
, pass
.get());
1931 green_shared_state
->opacity
= 0.5f
;
1933 PictureDrawQuad
* green_quad
=
1934 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
1935 green_quad
->SetNew(green_shared_state
, viewport
, gfx::Rect(), viewport
,
1936 gfx::RectF(0, 0, 1, 1), viewport
.size(), nearest_neighbor
,
1937 texture_format
, viewport
, 1.f
, green_pile
.get());
1939 // One viewport-filling white quad.
1940 scoped_ptr
<FakePicturePile
> white_recording
=
1941 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
1942 SkPaint white_paint
;
1943 white_paint
.setColor(SK_ColorWHITE
);
1944 white_recording
->add_draw_rect_with_paint(viewport
, white_paint
);
1945 white_recording
->RerecordPile();
1946 scoped_refptr
<FakePicturePileImpl
> white_pile
=
1947 FakePicturePileImpl::CreateFromPile(white_recording
.get(), nullptr);
1949 gfx::Transform white_content_to_target_transform
;
1950 SharedQuadState
* white_shared_state
= CreateTestSharedQuadState(
1951 white_content_to_target_transform
, viewport
, pass
.get());
1953 PictureDrawQuad
* white_quad
=
1954 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
1955 white_quad
->SetNew(white_shared_state
, viewport
, gfx::Rect(), viewport
,
1956 gfx::RectF(0, 0, 1, 1), viewport
.size(), nearest_neighbor
,
1957 texture_format
, viewport
, 1.f
, white_pile
.get());
1959 RenderPassList pass_list
;
1960 pass_list
.push_back(pass
.Pass());
1962 EXPECT_TRUE(this->RunPixelTest(
1964 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
1965 FuzzyPixelOffByOneComparator(true)));
1968 template<typename TypeParam
> bool IsSoftwareRenderer() {
1973 bool IsSoftwareRenderer
<SoftwareRenderer
>() {
1978 bool IsSoftwareRenderer
<SoftwareRendererWithExpandedViewport
>() {
1982 // If we disable image filtering, then a 2x2 bitmap should appear as four
1983 // huge sharp squares.
1984 TYPED_TEST(SoftwareRendererPixelTest
, PictureDrawQuadDisableImageFiltering
) {
1985 // We only care about this in software mode since bilinear filtering is
1986 // cheap in hardware.
1987 if (!IsSoftwareRenderer
<TypeParam
>())
1990 gfx::Size
pile_tile_size(1000, 1000);
1991 gfx::Rect
viewport(this->device_viewport_size_
);
1992 ResourceFormat texture_format
= RGBA_8888
;
1993 bool nearest_neighbor
= false;
1995 RenderPassId
id(1, 1);
1996 gfx::Transform transform_to_root
;
1997 scoped_ptr
<RenderPass
> pass
=
1998 CreateTestRenderPass(id
, viewport
, transform_to_root
);
2001 bitmap
.allocN32Pixels(2, 2);
2003 SkAutoLockPixels
lock(bitmap
);
2004 SkCanvas
canvas(bitmap
);
2005 canvas
.drawPoint(0, 0, SK_ColorGREEN
);
2006 canvas
.drawPoint(0, 1, SK_ColorBLUE
);
2007 canvas
.drawPoint(1, 0, SK_ColorBLUE
);
2008 canvas
.drawPoint(1, 1, SK_ColorGREEN
);
2011 scoped_ptr
<FakePicturePile
> recording
=
2012 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
2014 paint
.setFilterLevel(SkPaint::kLow_FilterLevel
);
2015 recording
->add_draw_bitmap_with_paint(bitmap
, gfx::Point(), paint
);
2016 recording
->RerecordPile();
2017 scoped_refptr
<FakePicturePileImpl
> pile
=
2018 FakePicturePileImpl::CreateFromPile(recording
.get(), nullptr);
2020 gfx::Transform content_to_target_transform
;
2021 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
2022 content_to_target_transform
, viewport
, pass
.get());
2024 PictureDrawQuad
* quad
= pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2025 quad
->SetNew(shared_state
, viewport
, gfx::Rect(), viewport
,
2026 gfx::RectF(0, 0, 2, 2), viewport
.size(), nearest_neighbor
,
2027 texture_format
, viewport
, 1.f
, pile
.get());
2029 RenderPassList pass_list
;
2030 pass_list
.push_back(pass
.Pass());
2032 this->disable_picture_quad_image_filtering_
= true;
2034 EXPECT_TRUE(this->RunPixelTest(
2036 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2037 ExactPixelComparator(true)));
2040 // This disables filtering by setting |nearest_neighbor| on the PictureDrawQuad.
2041 TYPED_TEST(SoftwareRendererPixelTest
, PictureDrawQuadNearestNeighbor
) {
2042 gfx::Size
pile_tile_size(1000, 1000);
2043 gfx::Rect
viewport(this->device_viewport_size_
);
2044 ResourceFormat texture_format
= RGBA_8888
;
2045 bool nearest_neighbor
= true;
2047 RenderPassId
id(1, 1);
2048 gfx::Transform transform_to_root
;
2049 scoped_ptr
<RenderPass
> pass
=
2050 CreateTestRenderPass(id
, viewport
, transform_to_root
);
2053 bitmap
.allocN32Pixels(2, 2);
2055 SkAutoLockPixels
lock(bitmap
);
2056 SkCanvas
canvas(bitmap
);
2057 canvas
.drawPoint(0, 0, SK_ColorGREEN
);
2058 canvas
.drawPoint(0, 1, SK_ColorBLUE
);
2059 canvas
.drawPoint(1, 0, SK_ColorBLUE
);
2060 canvas
.drawPoint(1, 1, SK_ColorGREEN
);
2063 scoped_ptr
<FakePicturePile
> recording
=
2064 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
2066 paint
.setFilterLevel(SkPaint::kLow_FilterLevel
);
2067 recording
->add_draw_bitmap_with_paint(bitmap
, gfx::Point(), paint
);
2068 recording
->RerecordPile();
2069 scoped_refptr
<FakePicturePileImpl
> pile
=
2070 FakePicturePileImpl::CreateFromPile(recording
.get(), nullptr);
2072 gfx::Transform content_to_target_transform
;
2073 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
2074 content_to_target_transform
, viewport
, pass
.get());
2076 PictureDrawQuad
* quad
= pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2077 quad
->SetNew(shared_state
, viewport
, gfx::Rect(), viewport
,
2078 gfx::RectF(0, 0, 2, 2), viewport
.size(), nearest_neighbor
,
2079 texture_format
, viewport
, 1.f
, pile
.get());
2081 RenderPassList pass_list
;
2082 pass_list
.push_back(pass
.Pass());
2084 EXPECT_TRUE(this->RunPixelTest(
2086 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2087 ExactPixelComparator(true)));
2090 // This disables filtering by setting |nearest_neighbor| on the TileDrawQuad.
2091 TYPED_TEST(RendererPixelTest
, TileDrawQuadNearestNeighbor
) {
2092 gfx::Rect
viewport(this->device_viewport_size_
);
2093 bool swizzle_contents
= true;
2094 bool nearest_neighbor
= true;
2097 bitmap
.allocN32Pixels(2, 2);
2099 SkAutoLockPixels
lock(bitmap
);
2100 SkCanvas
canvas(bitmap
);
2101 canvas
.drawPoint(0, 0, SK_ColorGREEN
);
2102 canvas
.drawPoint(0, 1, SK_ColorBLUE
);
2103 canvas
.drawPoint(1, 0, SK_ColorBLUE
);
2104 canvas
.drawPoint(1, 1, SK_ColorGREEN
);
2107 gfx::Size
tile_size(2, 2);
2108 ResourceProvider::ResourceId resource
=
2109 this->resource_provider_
->CreateResource(
2110 tile_size
, GL_CLAMP_TO_EDGE
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
2114 SkAutoLockPixels
lock(bitmap
);
2115 this->resource_provider_
->CopyToResource(
2116 resource
, static_cast<uint8_t*>(bitmap
.getPixels()), tile_size
);
2119 RenderPassId
id(1, 1);
2120 gfx::Transform transform_to_root
;
2121 scoped_ptr
<RenderPass
> pass
=
2122 CreateTestRenderPass(id
, viewport
, transform_to_root
);
2124 gfx::Transform content_to_target_transform
;
2125 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
2126 content_to_target_transform
, viewport
, pass
.get());
2128 TileDrawQuad
* quad
= pass
->CreateAndAppendDrawQuad
<TileDrawQuad
>();
2129 quad
->SetNew(shared_state
, viewport
, gfx::Rect(), viewport
, resource
,
2130 gfx::Rect(tile_size
), tile_size
, swizzle_contents
,
2133 RenderPassList pass_list
;
2134 pass_list
.push_back(pass
.Pass());
2136 EXPECT_TRUE(this->RunPixelTest(
2138 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2139 ExactPixelComparator(true)));
2142 TYPED_TEST(SoftwareRendererPixelTest
, PictureDrawQuadNonIdentityScale
) {
2143 gfx::Size
pile_tile_size(1000, 1000);
2144 gfx::Rect
viewport(this->device_viewport_size_
);
2145 // TODO(enne): the renderer should figure this out on its own.
2146 ResourceFormat texture_format
= RGBA_8888
;
2147 bool nearest_neighbor
= false;
2149 RenderPassId
id(1, 1);
2150 gfx::Transform transform_to_root
;
2151 scoped_ptr
<RenderPass
> pass
=
2152 CreateTestRenderPass(id
, viewport
, transform_to_root
);
2154 // As scaling up the blue checkerboards will cause sampling on the GPU,
2155 // a few extra "cleanup rects" need to be added to clobber the blending
2156 // to make the output image more clean. This will also test subrects
2158 gfx::Transform green_content_to_target_transform
;
2159 gfx::Rect
green_rect1(gfx::Point(80, 0), gfx::Size(20, 100));
2160 gfx::Rect
green_rect2(gfx::Point(0, 80), gfx::Size(100, 20));
2162 scoped_ptr
<FakePicturePile
> green_recording
=
2163 FakePicturePile::CreateFilledPile(pile_tile_size
, viewport
.size());
2166 red_paint
.setColor(SK_ColorRED
);
2167 green_recording
->add_draw_rect_with_paint(viewport
, red_paint
);
2168 SkPaint green_paint
;
2169 green_paint
.setColor(SK_ColorGREEN
);
2170 green_recording
->add_draw_rect_with_paint(green_rect1
, green_paint
);
2171 green_recording
->add_draw_rect_with_paint(green_rect2
, green_paint
);
2172 green_recording
->RerecordPile();
2173 scoped_refptr
<FakePicturePileImpl
> green_pile
=
2174 FakePicturePileImpl::CreateFromPile(green_recording
.get(), nullptr);
2176 SharedQuadState
* top_right_green_shared_quad_state
=
2177 CreateTestSharedQuadState(
2178 green_content_to_target_transform
, viewport
, pass
.get());
2180 PictureDrawQuad
* green_quad1
=
2181 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2182 green_quad1
->SetNew(top_right_green_shared_quad_state
, green_rect1
,
2183 gfx::Rect(), green_rect1
, gfx::RectF(green_rect1
.size()),
2184 green_rect1
.size(), nearest_neighbor
, texture_format
,
2185 green_rect1
, 1.f
, green_pile
.get());
2187 PictureDrawQuad
* green_quad2
=
2188 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2189 green_quad2
->SetNew(top_right_green_shared_quad_state
, green_rect2
,
2190 gfx::Rect(), green_rect2
, gfx::RectF(green_rect2
.size()),
2191 green_rect2
.size(), nearest_neighbor
, texture_format
,
2192 green_rect2
, 1.f
, green_pile
.get());
2194 // Add a green clipped checkerboard in the bottom right to help test
2195 // interleaving picture quad content and solid color content.
2196 gfx::Rect
bottom_right_rect(
2197 gfx::Point(viewport
.width() / 2, viewport
.height() / 2),
2198 gfx::Size(viewport
.width() / 2, viewport
.height() / 2));
2199 SharedQuadState
* bottom_right_green_shared_state
=
2200 CreateTestSharedQuadStateClipped(green_content_to_target_transform
,
2204 SolidColorDrawQuad
* bottom_right_color_quad
=
2205 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2206 bottom_right_color_quad
->SetNew(bottom_right_green_shared_state
,
2212 // Add two blue checkerboards taking up the bottom left and top right,
2213 // but use content scales as content rects to make this happen.
2214 // The content is at a 4x content scale.
2215 gfx::Rect
layer_rect(gfx::Size(20, 30));
2216 float contents_scale
= 4.f
;
2217 // Two rects that touch at their corners, arbitrarily placed in the layer.
2218 gfx::RectF
blue_layer_rect1(gfx::PointF(5.5f
, 9.0f
), gfx::SizeF(2.5f
, 2.5f
));
2219 gfx::RectF
blue_layer_rect2(gfx::PointF(8.0f
, 6.5f
), gfx::SizeF(2.5f
, 2.5f
));
2220 gfx::RectF union_layer_rect
= blue_layer_rect1
;
2221 union_layer_rect
.Union(blue_layer_rect2
);
2223 // Because scaling up will cause sampling outside the rects, add one extra
2224 // pixel of buffer at the final content scale.
2225 float inset
= -1.f
/ contents_scale
;
2226 blue_layer_rect1
.Inset(inset
, inset
, inset
, inset
);
2227 blue_layer_rect2
.Inset(inset
, inset
, inset
, inset
);
2229 scoped_ptr
<FakePicturePile
> recording
=
2230 FakePicturePile::CreateFilledPile(pile_tile_size
, layer_rect
.size());
2232 Region
outside(layer_rect
);
2233 outside
.Subtract(gfx::ToEnclosingRect(union_layer_rect
));
2234 for (Region::Iterator
iter(outside
); iter
.has_rect(); iter
.next()) {
2235 recording
->add_draw_rect_with_paint(iter
.rect(), red_paint
);
2239 blue_paint
.setColor(SK_ColorBLUE
);
2240 recording
->add_draw_rect_with_paint(blue_layer_rect1
, blue_paint
);
2241 recording
->add_draw_rect_with_paint(blue_layer_rect2
, blue_paint
);
2242 recording
->RerecordPile();
2243 scoped_refptr
<FakePicturePileImpl
> pile
=
2244 FakePicturePileImpl::CreateFromPile(recording
.get(), nullptr);
2246 gfx::Rect
content_rect(
2247 gfx::ScaleToEnclosingRect(layer_rect
, contents_scale
));
2248 gfx::Rect
content_union_rect(
2249 gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect
, contents_scale
)));
2251 // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels,
2252 // so scale an additional 10x to make them 100x100.
2253 gfx::Transform content_to_target_transform
;
2254 content_to_target_transform
.Scale(10.0, 10.0);
2255 gfx::Rect
quad_content_rect(gfx::Size(20, 20));
2256 SharedQuadState
* blue_shared_state
= CreateTestSharedQuadState(
2257 content_to_target_transform
, quad_content_rect
, pass
.get());
2259 PictureDrawQuad
* blue_quad
= pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2260 blue_quad
->SetNew(blue_shared_state
, quad_content_rect
, gfx::Rect(),
2261 quad_content_rect
, gfx::RectF(quad_content_rect
),
2262 content_union_rect
.size(), nearest_neighbor
, texture_format
,
2263 content_union_rect
, contents_scale
, pile
.get());
2265 // Fill left half of viewport with green.
2266 gfx::Transform half_green_content_to_target_transform
;
2267 gfx::Rect
half_green_rect(gfx::Size(viewport
.width() / 2, viewport
.height()));
2268 SharedQuadState
* half_green_shared_state
= CreateTestSharedQuadState(
2269 half_green_content_to_target_transform
, half_green_rect
, pass
.get());
2270 SolidColorDrawQuad
* half_color_quad
=
2271 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2272 half_color_quad
->SetNew(half_green_shared_state
,
2278 RenderPassList pass_list
;
2279 pass_list
.push_back(pass
.Pass());
2281 EXPECT_TRUE(this->RunPixelTest(
2283 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2284 ExactPixelComparator(true)));
2287 typedef RendererPixelTest
<GLRendererWithFlippedSurface
>
2288 GLRendererPixelTestWithFlippedOutputSurface
;
2290 TEST_F(GLRendererPixelTestWithFlippedOutputSurface
, ExplicitFlipTest
) {
2291 // This draws a blue rect above a yellow rect with an inverted output surface.
2292 gfx::Rect
viewport_rect(this->device_viewport_size_
);
2294 RenderPassId
root_pass_id(1, 1);
2295 scoped_ptr
<RenderPass
> root_pass
=
2296 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
2298 RenderPassId
child_pass_id(2, 2);
2299 gfx::Rect
pass_rect(this->device_viewport_size_
);
2300 gfx::Transform transform_to_root
;
2301 scoped_ptr
<RenderPass
> child_pass
=
2302 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
2304 gfx::Transform content_to_target_transform
;
2305 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
2306 content_to_target_transform
, viewport_rect
, child_pass
.get());
2308 gfx::Rect
blue_rect(0,
2310 this->device_viewport_size_
.width(),
2311 this->device_viewport_size_
.height() / 2);
2312 SolidColorDrawQuad
* blue
=
2313 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2314 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
2315 gfx::Rect
yellow_rect(0,
2316 this->device_viewport_size_
.height() / 2,
2317 this->device_viewport_size_
.width(),
2318 this->device_viewport_size_
.height() / 2);
2319 SolidColorDrawQuad
* yellow
=
2320 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2321 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
2323 SharedQuadState
* pass_shared_state
=
2324 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
2325 CreateTestRenderPassDrawQuad(
2326 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
2328 RenderPassList pass_list
;
2329 pass_list
.push_back(child_pass
.Pass());
2330 pass_list
.push_back(root_pass
.Pass());
2332 EXPECT_TRUE(this->RunPixelTest(
2334 base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")),
2335 ExactPixelComparator(true)));
2338 TEST_F(GLRendererPixelTestWithFlippedOutputSurface
, CheckChildPassUnflipped
) {
2339 // This draws a blue rect above a yellow rect with an inverted output surface.
2340 gfx::Rect
viewport_rect(this->device_viewport_size_
);
2342 RenderPassId
root_pass_id(1, 1);
2343 scoped_ptr
<RenderPass
> root_pass
=
2344 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
2346 RenderPassId
child_pass_id(2, 2);
2347 gfx::Rect
pass_rect(this->device_viewport_size_
);
2348 gfx::Transform transform_to_root
;
2349 scoped_ptr
<RenderPass
> child_pass
=
2350 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
2352 gfx::Transform content_to_target_transform
;
2353 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
2354 content_to_target_transform
, viewport_rect
, child_pass
.get());
2356 gfx::Rect
blue_rect(0,
2358 this->device_viewport_size_
.width(),
2359 this->device_viewport_size_
.height() / 2);
2360 SolidColorDrawQuad
* blue
=
2361 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2362 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
2363 gfx::Rect
yellow_rect(0,
2364 this->device_viewport_size_
.height() / 2,
2365 this->device_viewport_size_
.width(),
2366 this->device_viewport_size_
.height() / 2);
2367 SolidColorDrawQuad
* yellow
=
2368 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2369 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
2371 SharedQuadState
* pass_shared_state
=
2372 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
2373 CreateTestRenderPassDrawQuad(
2374 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
2376 RenderPassList pass_list
;
2377 pass_list
.push_back(child_pass
.Pass());
2378 pass_list
.push_back(root_pass
.Pass());
2380 // Check that the child pass remains unflipped.
2381 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
2384 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
2385 ExactPixelComparator(true)));
2388 TEST_F(GLRendererPixelTest
, CheckReadbackSubset
) {
2389 gfx::Rect
viewport_rect(this->device_viewport_size_
);
2391 RenderPassId
root_pass_id(1, 1);
2392 scoped_ptr
<RenderPass
> root_pass
=
2393 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
2395 RenderPassId
child_pass_id(2, 2);
2396 gfx::Rect
pass_rect(this->device_viewport_size_
);
2397 gfx::Transform transform_to_root
;
2398 scoped_ptr
<RenderPass
> child_pass
=
2399 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
2401 gfx::Transform content_to_target_transform
;
2402 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
2403 content_to_target_transform
, viewport_rect
, child_pass
.get());
2405 // Draw a green quad full-size with a blue quad in the lower-right corner.
2406 gfx::Rect
blue_rect(this->device_viewport_size_
.width() * 3 / 4,
2407 this->device_viewport_size_
.height() * 3 / 4,
2408 this->device_viewport_size_
.width() * 3 / 4,
2409 this->device_viewport_size_
.height() * 3 / 4);
2410 SolidColorDrawQuad
* blue
=
2411 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2412 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
2413 gfx::Rect
green_rect(0,
2415 this->device_viewport_size_
.width(),
2416 this->device_viewport_size_
.height());
2417 SolidColorDrawQuad
* green
=
2418 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2419 green
->SetNew(shared_state
, green_rect
, green_rect
, SK_ColorGREEN
, false);
2421 SharedQuadState
* pass_shared_state
=
2422 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
2423 CreateTestRenderPassDrawQuad(
2424 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
2426 RenderPassList pass_list
;
2427 pass_list
.push_back(child_pass
.Pass());
2428 pass_list
.push_back(root_pass
.Pass());
2430 // Check that the child pass remains unflipped.
2431 gfx::Rect
capture_rect(this->device_viewport_size_
.width() / 2,
2432 this->device_viewport_size_
.height() / 2,
2433 this->device_viewport_size_
.width() / 2,
2434 this->device_viewport_size_
.height() / 2);
2435 EXPECT_TRUE(this->RunPixelTestWithReadbackTargetAndArea(
2438 base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")),
2439 ExactPixelComparator(true),
2443 TYPED_TEST(RendererPixelTest
, WrapModeRepeat
) {
2444 gfx::Rect
rect(this->device_viewport_size_
);
2446 RenderPassId
id(1, 1);
2447 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
2449 SharedQuadState
* shared_state
=
2450 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
2452 gfx::Size
texture_size(4, 4);
2453 SkPMColor colors
[4] = {
2454 SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)),
2455 SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)),
2456 SkPreMultiplyColor(SkColorSetARGB(255, 0, 64, 0)),
2457 SkPreMultiplyColor(SkColorSetARGB(255, 0, 0, 0)),
2459 uint32_t pixels
[16] = {
2460 colors
[0], colors
[0], colors
[1], colors
[1],
2461 colors
[0], colors
[0], colors
[1], colors
[1],
2462 colors
[2], colors
[2], colors
[3], colors
[3],
2463 colors
[2], colors
[2], colors
[3], colors
[3],
2465 ResourceProvider::ResourceId resource
=
2466 this->resource_provider_
->CreateResource(
2467 texture_size
, GL_REPEAT
, ResourceProvider::TEXTURE_HINT_IMMUTABLE
,
2469 this->resource_provider_
->CopyToResource(
2470 resource
, reinterpret_cast<uint8_t*>(pixels
), texture_size
);
2472 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
2473 TextureDrawQuad
* texture_quad
=
2474 pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2475 texture_quad
->SetNew(
2476 shared_state
, gfx::Rect(this->device_viewport_size_
), gfx::Rect(),
2477 gfx::Rect(this->device_viewport_size_
), resource
,
2478 true, // premultiplied_alpha
2479 gfx::PointF(0.0f
, 0.0f
), // uv_top_left
2480 gfx::PointF( // uv_bottom_right
2481 this->device_viewport_size_
.width() / texture_size
.width(),
2482 this->device_viewport_size_
.height() / texture_size
.height()),
2483 SK_ColorWHITE
, vertex_opacity
,
2485 false); // nearest_neighbor
2487 RenderPassList pass_list
;
2488 pass_list
.push_back(pass
.Pass());
2490 EXPECT_TRUE(this->RunPixelTest(
2492 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
2493 FuzzyPixelOffByOneComparator(true)));
2496 #endif // !defined(OS_ANDROID)