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/SkBitmapDevice.h"
17 #include "third_party/skia/include/core/SkColorPriv.h"
18 #include "third_party/skia/include/core/SkImageFilter.h"
19 #include "third_party/skia/include/core/SkMatrix.h"
20 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
21 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
22 #include "ui/gfx/geometry/rect_conversions.h"
24 using gpu::gles2::GLES2Interface
;
29 #if !defined(OS_ANDROID)
30 scoped_ptr
<RenderPass
> CreateTestRootRenderPass(RenderPassId id
,
31 const gfx::Rect
& rect
) {
32 scoped_ptr
<RenderPass
> pass
= RenderPass::Create();
33 const gfx::Rect output_rect
= rect
;
34 const gfx::Rect damage_rect
= rect
;
35 const gfx::Transform transform_to_root_target
;
36 pass
->SetNew(id
, output_rect
, damage_rect
, transform_to_root_target
);
40 scoped_ptr
<RenderPass
> CreateTestRenderPass(
42 const gfx::Rect
& rect
,
43 const gfx::Transform
& transform_to_root_target
) {
44 scoped_ptr
<RenderPass
> pass
= RenderPass::Create();
45 const gfx::Rect output_rect
= rect
;
46 const gfx::Rect damage_rect
= rect
;
47 pass
->SetNew(id
, output_rect
, damage_rect
, transform_to_root_target
);
51 SharedQuadState
* CreateTestSharedQuadState(
52 gfx::Transform content_to_target_transform
,
53 const gfx::Rect
& rect
,
54 RenderPass
* render_pass
) {
55 const gfx::Size content_bounds
= rect
.size();
56 const gfx::Rect visible_content_rect
= rect
;
57 const gfx::Rect clip_rect
= rect
;
58 const bool is_clipped
= false;
59 const float opacity
= 1.0f
;
60 const SkXfermode::Mode blend_mode
= SkXfermode::kSrcOver_Mode
;
61 int sorting_context_id
= 0;
62 SharedQuadState
* shared_state
= render_pass
->CreateAndAppendSharedQuadState();
63 shared_state
->SetAll(content_to_target_transform
,
74 SharedQuadState
* CreateTestSharedQuadStateClipped(
75 gfx::Transform content_to_target_transform
,
76 const gfx::Rect
& rect
,
77 const gfx::Rect
& clip_rect
,
78 RenderPass
* render_pass
) {
79 const gfx::Size content_bounds
= rect
.size();
80 const gfx::Rect visible_content_rect
= clip_rect
;
81 const bool is_clipped
= true;
82 const float opacity
= 1.0f
;
83 const SkXfermode::Mode blend_mode
= SkXfermode::kSrcOver_Mode
;
84 int sorting_context_id
= 0;
85 SharedQuadState
* shared_state
= render_pass
->CreateAndAppendSharedQuadState();
86 shared_state
->SetAll(content_to_target_transform
,
97 void CreateTestRenderPassDrawQuad(const SharedQuadState
* shared_state
,
98 const gfx::Rect
& rect
,
100 RenderPass
* render_pass
) {
101 RenderPassDrawQuad
* quad
=
102 render_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
103 quad
->SetNew(shared_state
,
107 0, // mask_resource_id
108 gfx::RectF(1.f
, 1.f
), // mask_uv_rect
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 std::vector
<uint32_t> pixels(rect
.size().GetArea(), pixel_color
);
129 ResourceProvider::ResourceId resource
=
130 resource_provider
->CreateResource(rect
.size(),
132 ResourceProvider::TextureHintImmutable
,
134 resource_provider
->SetPixels(
136 reinterpret_cast<uint8_t*>(&pixels
.front()),
141 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
143 TextureDrawQuad
* quad
=
144 render_pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
145 quad
->SetNew(shared_state
,
151 gfx::PointF(0.0f
, 0.0f
), // uv_top_left
152 gfx::PointF(1.0f
, 1.0f
), // uv_bottom_right
158 typedef ::testing::Types
<GLRenderer
,
160 GLRendererWithExpandedViewport
,
161 SoftwareRendererWithExpandedViewport
> RendererTypes
;
162 TYPED_TEST_CASE(RendererPixelTest
, RendererTypes
);
164 template <typename RendererType
>
165 class FuzzyForSoftwareOnlyPixelComparator
: public PixelComparator
{
167 explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha
)
168 : fuzzy_(discard_alpha
), exact_(discard_alpha
) {}
170 virtual bool Compare(const SkBitmap
& actual_bmp
,
171 const SkBitmap
& expected_bmp
) const;
174 FuzzyPixelOffByOneComparator fuzzy_
;
175 ExactPixelComparator exact_
;
179 bool FuzzyForSoftwareOnlyPixelComparator
<SoftwareRenderer
>::Compare(
180 const SkBitmap
& actual_bmp
,
181 const SkBitmap
& expected_bmp
) const {
182 return fuzzy_
.Compare(actual_bmp
, expected_bmp
);
186 bool FuzzyForSoftwareOnlyPixelComparator
<
187 SoftwareRendererWithExpandedViewport
>::Compare(
188 const SkBitmap
& actual_bmp
,
189 const SkBitmap
& expected_bmp
) const {
190 return fuzzy_
.Compare(actual_bmp
, expected_bmp
);
193 template<typename RendererType
>
194 bool FuzzyForSoftwareOnlyPixelComparator
<RendererType
>::Compare(
195 const SkBitmap
& actual_bmp
,
196 const SkBitmap
& expected_bmp
) const {
197 return exact_
.Compare(actual_bmp
, expected_bmp
);
200 TYPED_TEST(RendererPixelTest
, SimpleGreenRect
) {
201 gfx::Rect
rect(this->device_viewport_size_
);
203 RenderPassId
id(1, 1);
204 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
206 SharedQuadState
* shared_state
=
207 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
209 SolidColorDrawQuad
* color_quad
=
210 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
211 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorGREEN
, false);
213 RenderPassList pass_list
;
214 pass_list
.push_back(pass
.Pass());
216 EXPECT_TRUE(this->RunPixelTest(
218 base::FilePath(FILE_PATH_LITERAL("green.png")),
219 ExactPixelComparator(true)));
222 TYPED_TEST(RendererPixelTest
, SimpleGreenRect_NonRootRenderPass
) {
223 gfx::Rect
rect(this->device_viewport_size_
);
224 gfx::Rect
small_rect(100, 100);
226 RenderPassId
child_id(2, 1);
227 scoped_ptr
<RenderPass
> child_pass
=
228 CreateTestRenderPass(child_id
, small_rect
, gfx::Transform());
230 SharedQuadState
* child_shared_state
=
231 CreateTestSharedQuadState(gfx::Transform(), small_rect
, child_pass
.get());
233 SolidColorDrawQuad
* color_quad
=
234 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
235 color_quad
->SetNew(child_shared_state
, rect
, rect
, SK_ColorGREEN
, false);
237 RenderPassId
root_id(1, 1);
238 scoped_ptr
<RenderPass
> root_pass
=
239 CreateTestRenderPass(root_id
, rect
, gfx::Transform());
241 SharedQuadState
* root_shared_state
=
242 CreateTestSharedQuadState(gfx::Transform(), rect
, root_pass
.get());
244 CreateTestRenderPassDrawQuad(
245 root_shared_state
, small_rect
, child_id
, root_pass
.get());
247 RenderPass
* child_pass_ptr
= child_pass
.get();
249 RenderPassList pass_list
;
250 pass_list
.push_back(child_pass
.Pass());
251 pass_list
.push_back(root_pass
.Pass());
253 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
256 base::FilePath(FILE_PATH_LITERAL("green_small.png")),
257 ExactPixelComparator(true)));
260 TYPED_TEST(RendererPixelTest
, PremultipliedTextureWithoutBackground
) {
261 gfx::Rect
rect(this->device_viewport_size_
);
263 RenderPassId
id(1, 1);
264 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
266 SharedQuadState
* shared_state
=
267 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
269 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
270 SkColorSetARGB(128, 0, 255, 0), // Texel color.
271 SK_ColorTRANSPARENT
, // Background color.
272 true, // Premultiplied alpha.
274 this->resource_provider_
.get(),
277 SolidColorDrawQuad
* color_quad
=
278 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
279 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorWHITE
, false);
281 RenderPassList pass_list
;
282 pass_list
.push_back(pass
.Pass());
284 EXPECT_TRUE(this->RunPixelTest(
286 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
287 FuzzyPixelOffByOneComparator(true)));
290 TYPED_TEST(RendererPixelTest
, PremultipliedTextureWithBackground
) {
291 gfx::Rect
rect(this->device_viewport_size_
);
293 RenderPassId
id(1, 1);
294 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
296 SharedQuadState
* texture_quad_state
=
297 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
298 texture_quad_state
->opacity
= 0.8f
;
300 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
301 SkColorSetARGB(204, 120, 255, 120), // Texel color.
302 SK_ColorGREEN
, // Background color.
303 true, // Premultiplied alpha.
305 this->resource_provider_
.get(),
308 SharedQuadState
* color_quad_state
=
309 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
310 SolidColorDrawQuad
* color_quad
=
311 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
312 color_quad
->SetNew(color_quad_state
, rect
, rect
, SK_ColorWHITE
, false);
314 RenderPassList pass_list
;
315 pass_list
.push_back(pass
.Pass());
317 EXPECT_TRUE(this->RunPixelTest(
319 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
320 FuzzyPixelOffByOneComparator(true)));
323 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
324 TEST_F(GLRendererPixelTest
, NonPremultipliedTextureWithoutBackground
) {
325 gfx::Rect
rect(this->device_viewport_size_
);
327 RenderPassId
id(1, 1);
328 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
330 SharedQuadState
* shared_state
=
331 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
333 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
334 SkColorSetARGB(128, 0, 255, 0), // Texel color.
335 SK_ColorTRANSPARENT
, // Background color.
336 false, // Premultiplied alpha.
338 this->resource_provider_
.get(),
341 SolidColorDrawQuad
* color_quad
=
342 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
343 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorWHITE
, false);
345 RenderPassList pass_list
;
346 pass_list
.push_back(pass
.Pass());
348 EXPECT_TRUE(this->RunPixelTest(
350 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
351 FuzzyPixelOffByOneComparator(true)));
354 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
355 TEST_F(GLRendererPixelTest
, NonPremultipliedTextureWithBackground
) {
356 gfx::Rect
rect(this->device_viewport_size_
);
358 RenderPassId
id(1, 1);
359 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
361 SharedQuadState
* texture_quad_state
=
362 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
363 texture_quad_state
->opacity
= 0.8f
;
365 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_
),
366 SkColorSetARGB(204, 120, 255, 120), // Texel color.
367 SK_ColorGREEN
, // Background color.
368 false, // Premultiplied alpha.
370 this->resource_provider_
.get(),
373 SharedQuadState
* color_quad_state
=
374 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
375 SolidColorDrawQuad
* color_quad
=
376 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
377 color_quad
->SetNew(color_quad_state
, rect
, rect
, SK_ColorWHITE
, false);
379 RenderPassList pass_list
;
380 pass_list
.push_back(pass
.Pass());
382 EXPECT_TRUE(this->RunPixelTest(
384 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
385 FuzzyPixelOffByOneComparator(true)));
388 class VideoGLRendererPixelTest
: public GLRendererPixelTest
{
390 void CreateTestYUVVideoDrawQuad_Striped(const SharedQuadState
* shared_state
,
391 media::VideoFrame::Format format
,
393 const gfx::RectF
& tex_coord_rect
,
394 RenderPass
* render_pass
) {
395 const gfx::Rect
rect(this->device_viewport_size_
);
397 scoped_refptr
<media::VideoFrame
> video_frame
=
398 media::VideoFrame::CreateFrame(
399 format
, rect
.size(), rect
, rect
.size(), base::TimeDelta());
401 // YUV values representing a striped pattern, for validating texture
402 // coordinates for sampling.
406 for (int i
= 0; i
< video_frame
->rows(media::VideoFrame::kYPlane
); ++i
) {
407 uint8_t* y_row
= video_frame
->data(media::VideoFrame::kYPlane
) +
408 video_frame
->stride(media::VideoFrame::kYPlane
) * i
;
409 for (int j
= 0; j
< video_frame
->row_bytes(media::VideoFrame::kYPlane
);
411 y_row
[j
] = (y_value
+= 1);
414 for (int i
= 0; i
< video_frame
->rows(media::VideoFrame::kUPlane
); ++i
) {
415 uint8_t* u_row
= video_frame
->data(media::VideoFrame::kUPlane
) +
416 video_frame
->stride(media::VideoFrame::kUPlane
) * i
;
417 uint8_t* v_row
= video_frame
->data(media::VideoFrame::kVPlane
) +
418 video_frame
->stride(media::VideoFrame::kVPlane
) * i
;
419 for (int j
= 0; j
< video_frame
->row_bytes(media::VideoFrame::kUPlane
);
421 u_row
[j
] = (u_value
+= 3);
422 v_row
[j
] = (v_value
+= 5);
425 CreateTestYUVVideoDrawQuad_FromVideoFrame(
426 shared_state
, video_frame
, is_transparent
, tex_coord_rect
, render_pass
);
429 void CreateTestYUVVideoDrawQuad_Solid(const SharedQuadState
* shared_state
,
430 media::VideoFrame::Format format
,
432 const gfx::RectF
& tex_coord_rect
,
436 RenderPass
* render_pass
) {
437 const gfx::Rect
rect(this->device_viewport_size_
);
439 scoped_refptr
<media::VideoFrame
> video_frame
=
440 media::VideoFrame::CreateFrame(
441 format
, rect
.size(), rect
, rect
.size(), base::TimeDelta());
443 // YUV values of a solid, constant, color. Useful for testing that color
444 // space/color range are being handled properly.
445 memset(video_frame
->data(media::VideoFrame::kYPlane
),
447 video_frame
->stride(media::VideoFrame::kYPlane
) *
448 video_frame
->rows(media::VideoFrame::kYPlane
));
449 memset(video_frame
->data(media::VideoFrame::kUPlane
),
451 video_frame
->stride(media::VideoFrame::kUPlane
) *
452 video_frame
->rows(media::VideoFrame::kUPlane
));
453 memset(video_frame
->data(media::VideoFrame::kVPlane
),
455 video_frame
->stride(media::VideoFrame::kVPlane
) *
456 video_frame
->rows(media::VideoFrame::kVPlane
));
458 CreateTestYUVVideoDrawQuad_FromVideoFrame(
459 shared_state
, video_frame
, is_transparent
, tex_coord_rect
, render_pass
);
462 void CreateTestYUVVideoDrawQuad_FromVideoFrame(
463 const SharedQuadState
* shared_state
,
464 scoped_refptr
<media::VideoFrame
> video_frame
,
466 const gfx::RectF
& tex_coord_rect
,
467 RenderPass
* render_pass
) {
468 const bool with_alpha
= (video_frame
->format() == media::VideoFrame::YV12A
);
469 const YUVVideoDrawQuad::ColorSpace color_space
=
470 (video_frame
->format() == media::VideoFrame::YV12J
471 ? YUVVideoDrawQuad::REC_601_JPEG
472 : YUVVideoDrawQuad::REC_601
);
473 const gfx::Rect
rect(this->device_viewport_size_
);
474 const gfx::Rect
opaque_rect(0, 0, 0, 0);
477 memset(video_frame
->data(media::VideoFrame::kAPlane
),
478 is_transparent
? 0 : 128,
479 video_frame
->stride(media::VideoFrame::kAPlane
) *
480 video_frame
->rows(media::VideoFrame::kAPlane
));
482 VideoFrameExternalResources resources
=
483 video_resource_updater_
->CreateExternalResourcesFromVideoFrame(
486 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE
, resources
.type
);
487 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame
->format()),
488 resources
.mailboxes
.size());
489 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame
->format()),
490 resources
.release_callbacks
.size());
492 ResourceProvider::ResourceId y_resource
=
493 resource_provider_
->CreateResourceFromTextureMailbox(
494 resources
.mailboxes
[media::VideoFrame::kYPlane
],
495 SingleReleaseCallbackImpl::Create(
496 resources
.release_callbacks
[media::VideoFrame::kYPlane
]));
497 ResourceProvider::ResourceId u_resource
=
498 resource_provider_
->CreateResourceFromTextureMailbox(
499 resources
.mailboxes
[media::VideoFrame::kUPlane
],
500 SingleReleaseCallbackImpl::Create(
501 resources
.release_callbacks
[media::VideoFrame::kUPlane
]));
502 ResourceProvider::ResourceId v_resource
=
503 resource_provider_
->CreateResourceFromTextureMailbox(
504 resources
.mailboxes
[media::VideoFrame::kVPlane
],
505 SingleReleaseCallbackImpl::Create(
506 resources
.release_callbacks
[media::VideoFrame::kVPlane
]));
507 ResourceProvider::ResourceId a_resource
= 0;
509 a_resource
= resource_provider_
->CreateResourceFromTextureMailbox(
510 resources
.mailboxes
[media::VideoFrame::kAPlane
],
511 SingleReleaseCallbackImpl::Create(
512 resources
.release_callbacks
[media::VideoFrame::kAPlane
]));
515 YUVVideoDrawQuad
* yuv_quad
=
516 render_pass
->CreateAndAppendDrawQuad
<YUVVideoDrawQuad
>();
517 yuv_quad
->SetNew(shared_state
,
529 virtual void SetUp() OVERRIDE
{
530 GLRendererPixelTest::SetUp();
531 video_resource_updater_
.reset(new VideoResourceUpdater(
532 output_surface_
->context_provider(), resource_provider_
.get()));
536 scoped_ptr
<VideoResourceUpdater
> video_resource_updater_
;
539 TEST_F(VideoGLRendererPixelTest
, SimpleYUVRect
) {
540 gfx::Rect
rect(this->device_viewport_size_
);
542 RenderPassId
id(1, 1);
543 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
545 SharedQuadState
* shared_state
=
546 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
548 CreateTestYUVVideoDrawQuad_Striped(shared_state
,
549 media::VideoFrame::YV12
,
551 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
554 RenderPassList pass_list
;
555 pass_list
.push_back(pass
.Pass());
558 this->RunPixelTest(&pass_list
,
559 base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
560 FuzzyPixelOffByOneComparator(true)));
563 TEST_F(VideoGLRendererPixelTest
, OffsetYUVRect
) {
564 gfx::Rect
rect(this->device_viewport_size_
);
566 RenderPassId
id(1, 1);
567 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
569 SharedQuadState
* shared_state
=
570 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
572 // Intentionally sets frame format to I420 for testing coverage.
573 CreateTestYUVVideoDrawQuad_Striped(shared_state
,
574 media::VideoFrame::I420
,
576 gfx::RectF(0.125f
, 0.25f
, 0.75f
, 0.5f
),
579 RenderPassList pass_list
;
580 pass_list
.push_back(pass
.Pass());
582 EXPECT_TRUE(this->RunPixelTest(
584 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_offset.png")),
585 FuzzyPixelOffByOneComparator(true)));
588 TEST_F(VideoGLRendererPixelTest
, SimpleYUVRectBlack
) {
589 gfx::Rect
rect(this->device_viewport_size_
);
591 RenderPassId
id(1, 1);
592 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
594 SharedQuadState
* shared_state
=
595 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
597 // In MPEG color range YUV values of (15,128,128) should produce black.
598 CreateTestYUVVideoDrawQuad_Solid(shared_state
,
599 media::VideoFrame::YV12
,
601 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
607 RenderPassList pass_list
;
608 pass_list
.push_back(pass
.Pass());
610 // If we didn't get black out of the YUV values above, then we probably have a
611 // color range issue.
612 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
613 base::FilePath(FILE_PATH_LITERAL("black.png")),
614 FuzzyPixelOffByOneComparator(true)));
617 TEST_F(VideoGLRendererPixelTest
, SimpleYUVJRect
) {
618 gfx::Rect
rect(this->device_viewport_size_
);
620 RenderPassId
id(1, 1);
621 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
623 SharedQuadState
* shared_state
=
624 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
626 // YUV of (149,43,21) should be green (0,255,0) in RGB.
627 CreateTestYUVVideoDrawQuad_Solid(shared_state
,
628 media::VideoFrame::YV12J
,
630 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
636 RenderPassList pass_list
;
637 pass_list
.push_back(pass
.Pass());
639 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
640 base::FilePath(FILE_PATH_LITERAL("green.png")),
641 FuzzyPixelOffByOneComparator(true)));
644 TEST_F(VideoGLRendererPixelTest
, SimpleYUVJRectGrey
) {
645 gfx::Rect
rect(this->device_viewport_size_
);
647 RenderPassId
id(1, 1);
648 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
650 SharedQuadState
* shared_state
=
651 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
653 // Dark grey in JPEG color range (in MPEG, this is black).
654 CreateTestYUVVideoDrawQuad_Solid(shared_state
,
655 media::VideoFrame::YV12J
,
657 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
663 RenderPassList pass_list
;
664 pass_list
.push_back(pass
.Pass());
667 this->RunPixelTest(&pass_list
,
668 base::FilePath(FILE_PATH_LITERAL("dark_grey.png")),
669 FuzzyPixelOffByOneComparator(true)));
672 TEST_F(VideoGLRendererPixelTest
, SimpleYUVARect
) {
673 gfx::Rect
rect(this->device_viewport_size_
);
675 RenderPassId
id(1, 1);
676 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
678 SharedQuadState
* shared_state
=
679 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
681 CreateTestYUVVideoDrawQuad_Striped(shared_state
,
682 media::VideoFrame::YV12A
,
684 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
687 SolidColorDrawQuad
* color_quad
=
688 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
689 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorWHITE
, false);
691 RenderPassList pass_list
;
692 pass_list
.push_back(pass
.Pass());
694 EXPECT_TRUE(this->RunPixelTest(
696 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_alpha.png")),
697 FuzzyPixelOffByOneComparator(true)));
700 TEST_F(VideoGLRendererPixelTest
, FullyTransparentYUVARect
) {
701 gfx::Rect
rect(this->device_viewport_size_
);
703 RenderPassId
id(1, 1);
704 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
706 SharedQuadState
* shared_state
=
707 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
709 CreateTestYUVVideoDrawQuad_Striped(shared_state
,
710 media::VideoFrame::YV12A
,
712 gfx::RectF(0.0f
, 0.0f
, 1.0f
, 1.0f
),
715 SolidColorDrawQuad
* color_quad
=
716 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
717 color_quad
->SetNew(shared_state
, rect
, rect
, SK_ColorBLACK
, false);
719 RenderPassList pass_list
;
720 pass_list
.push_back(pass
.Pass());
722 EXPECT_TRUE(this->RunPixelTest(
724 base::FilePath(FILE_PATH_LITERAL("black.png")),
725 ExactPixelComparator(true)));
728 TYPED_TEST(RendererPixelTest
, FastPassColorFilterAlpha
) {
729 gfx::Rect
viewport_rect(this->device_viewport_size_
);
731 RenderPassId
root_pass_id(1, 1);
732 scoped_ptr
<RenderPass
> root_pass
=
733 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
735 RenderPassId
child_pass_id(2, 2);
736 gfx::Rect
pass_rect(this->device_viewport_size_
);
737 gfx::Transform transform_to_root
;
738 scoped_ptr
<RenderPass
> child_pass
=
739 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
741 gfx::Transform content_to_target_transform
;
742 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
743 content_to_target_transform
, viewport_rect
, child_pass
.get());
744 shared_state
->opacity
= 0.5f
;
746 gfx::Rect
blue_rect(0,
748 this->device_viewport_size_
.width(),
749 this->device_viewport_size_
.height() / 2);
750 SolidColorDrawQuad
* blue
=
751 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
752 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
753 gfx::Rect
yellow_rect(0,
754 this->device_viewport_size_
.height() / 2,
755 this->device_viewport_size_
.width(),
756 this->device_viewport_size_
.height() / 2);
757 SolidColorDrawQuad
* yellow
=
758 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
759 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
761 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
762 content_to_target_transform
, viewport_rect
, child_pass
.get());
764 SolidColorDrawQuad
* white
=
765 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
767 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
769 SharedQuadState
* pass_shared_state
=
770 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
774 matrix
[0] = 0.213f
+ 0.787f
* amount
;
775 matrix
[1] = 0.715f
- 0.715f
* amount
;
776 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
777 matrix
[3] = matrix
[4] = 0;
778 matrix
[5] = 0.213f
- 0.213f
* amount
;
779 matrix
[6] = 0.715f
+ 0.285f
* amount
;
780 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
781 matrix
[8] = matrix
[9] = 0;
782 matrix
[10] = 0.213f
- 0.213f
* amount
;
783 matrix
[11] = 0.715f
- 0.715f
* amount
;
784 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
785 matrix
[13] = matrix
[14] = 0;
786 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
788 skia::RefPtr
<SkColorFilter
> colorFilter(
789 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
790 skia::RefPtr
<SkImageFilter
> filter
=
791 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter
.get(), NULL
));
792 FilterOperations filters
;
793 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
795 RenderPassDrawQuad
* render_pass_quad
=
796 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
797 render_pass_quad
->SetNew(pass_shared_state
,
807 RenderPassList pass_list
;
808 pass_list
.push_back(child_pass
.Pass());
809 pass_list
.push_back(root_pass
.Pass());
811 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
812 // renderer so use a fuzzy comparator.
813 EXPECT_TRUE(this->RunPixelTest(
815 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
816 FuzzyForSoftwareOnlyPixelComparator
<TypeParam
>(false)));
819 TYPED_TEST(RendererPixelTest
, FastPassSaturateFilter
) {
820 gfx::Rect
viewport_rect(this->device_viewport_size_
);
822 RenderPassId
root_pass_id(1, 1);
823 scoped_ptr
<RenderPass
> root_pass
=
824 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
826 RenderPassId
child_pass_id(2, 2);
827 gfx::Rect
pass_rect(this->device_viewport_size_
);
828 gfx::Transform transform_to_root
;
829 scoped_ptr
<RenderPass
> child_pass
=
830 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
832 gfx::Transform content_to_target_transform
;
833 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
834 content_to_target_transform
, viewport_rect
, child_pass
.get());
835 shared_state
->opacity
= 0.5f
;
837 gfx::Rect
blue_rect(0,
839 this->device_viewport_size_
.width(),
840 this->device_viewport_size_
.height() / 2);
841 SolidColorDrawQuad
* blue
=
842 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
843 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
844 gfx::Rect
yellow_rect(0,
845 this->device_viewport_size_
.height() / 2,
846 this->device_viewport_size_
.width(),
847 this->device_viewport_size_
.height() / 2);
848 SolidColorDrawQuad
* yellow
=
849 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
850 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
852 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
853 content_to_target_transform
, viewport_rect
, child_pass
.get());
855 SolidColorDrawQuad
* white
=
856 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
858 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
860 SharedQuadState
* pass_shared_state
=
861 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
863 FilterOperations filters
;
864 filters
.Append(FilterOperation::CreateSaturateFilter(0.5f
));
866 RenderPassDrawQuad
* render_pass_quad
=
867 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
868 render_pass_quad
->SetNew(pass_shared_state
,
878 RenderPassList pass_list
;
879 pass_list
.push_back(child_pass
.Pass());
880 pass_list
.push_back(root_pass
.Pass());
882 EXPECT_TRUE(this->RunPixelTest(
884 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
885 ExactPixelComparator(true)));
888 TYPED_TEST(RendererPixelTest
, FastPassFilterChain
) {
889 gfx::Rect
viewport_rect(this->device_viewport_size_
);
891 RenderPassId
root_pass_id(1, 1);
892 scoped_ptr
<RenderPass
> root_pass
=
893 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
895 RenderPassId
child_pass_id(2, 2);
896 gfx::Rect
pass_rect(this->device_viewport_size_
);
897 gfx::Transform transform_to_root
;
898 scoped_ptr
<RenderPass
> child_pass
=
899 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
901 gfx::Transform content_to_target_transform
;
902 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
903 content_to_target_transform
, viewport_rect
, child_pass
.get());
904 shared_state
->opacity
= 0.5f
;
906 gfx::Rect
blue_rect(0,
908 this->device_viewport_size_
.width(),
909 this->device_viewport_size_
.height() / 2);
910 SolidColorDrawQuad
* blue
=
911 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
912 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
913 gfx::Rect
yellow_rect(0,
914 this->device_viewport_size_
.height() / 2,
915 this->device_viewport_size_
.width(),
916 this->device_viewport_size_
.height() / 2);
917 SolidColorDrawQuad
* yellow
=
918 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
919 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
921 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
922 content_to_target_transform
, viewport_rect
, child_pass
.get());
924 SolidColorDrawQuad
* white
=
925 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
927 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
929 SharedQuadState
* pass_shared_state
=
930 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
932 FilterOperations filters
;
933 filters
.Append(FilterOperation::CreateGrayscaleFilter(1.f
));
934 filters
.Append(FilterOperation::CreateBrightnessFilter(0.5f
));
936 RenderPassDrawQuad
* render_pass_quad
=
937 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
938 render_pass_quad
->SetNew(pass_shared_state
,
948 RenderPassList pass_list
;
949 pass_list
.push_back(child_pass
.Pass());
950 pass_list
.push_back(root_pass
.Pass());
952 EXPECT_TRUE(this->RunPixelTest(
954 base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")),
955 ExactPixelComparator(true)));
958 TYPED_TEST(RendererPixelTest
, FastPassColorFilterAlphaTranslation
) {
959 gfx::Rect
viewport_rect(this->device_viewport_size_
);
961 RenderPassId
root_pass_id(1, 1);
962 scoped_ptr
<RenderPass
> root_pass
=
963 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
965 RenderPassId
child_pass_id(2, 2);
966 gfx::Rect
pass_rect(this->device_viewport_size_
);
967 gfx::Transform transform_to_root
;
968 scoped_ptr
<RenderPass
> child_pass
=
969 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
971 gfx::Transform content_to_target_transform
;
972 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
973 content_to_target_transform
, viewport_rect
, child_pass
.get());
974 shared_state
->opacity
= 0.5f
;
976 gfx::Rect
blue_rect(0,
978 this->device_viewport_size_
.width(),
979 this->device_viewport_size_
.height() / 2);
980 SolidColorDrawQuad
* blue
=
981 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
982 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
983 gfx::Rect
yellow_rect(0,
984 this->device_viewport_size_
.height() / 2,
985 this->device_viewport_size_
.width(),
986 this->device_viewport_size_
.height() / 2);
987 SolidColorDrawQuad
* yellow
=
988 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
989 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
991 SharedQuadState
* blank_state
= CreateTestSharedQuadState(
992 content_to_target_transform
, viewport_rect
, child_pass
.get());
994 SolidColorDrawQuad
* white
=
995 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
997 blank_state
, viewport_rect
, viewport_rect
, SK_ColorWHITE
, false);
999 SharedQuadState
* pass_shared_state
=
1000 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1002 SkScalar matrix
[20];
1003 float amount
= 0.5f
;
1004 matrix
[0] = 0.213f
+ 0.787f
* amount
;
1005 matrix
[1] = 0.715f
- 0.715f
* amount
;
1006 matrix
[2] = 1.f
- (matrix
[0] + matrix
[1]);
1009 matrix
[5] = 0.213f
- 0.213f
* amount
;
1010 matrix
[6] = 0.715f
+ 0.285f
* amount
;
1011 matrix
[7] = 1.f
- (matrix
[5] + matrix
[6]);
1014 matrix
[10] = 0.213f
- 0.213f
* amount
;
1015 matrix
[11] = 0.715f
- 0.715f
* amount
;
1016 matrix
[12] = 1.f
- (matrix
[10] + matrix
[11]);
1019 matrix
[15] = matrix
[16] = matrix
[17] = matrix
[19] = 0;
1021 skia::RefPtr
<SkColorFilter
> colorFilter(
1022 skia::AdoptRef(SkColorMatrixFilter::Create(matrix
)));
1023 skia::RefPtr
<SkImageFilter
> filter
=
1024 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter
.get(), NULL
));
1025 FilterOperations filters
;
1026 filters
.Append(FilterOperation::CreateReferenceFilter(filter
));
1028 RenderPassDrawQuad
* render_pass_quad
=
1029 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1030 render_pass_quad
->SetNew(pass_shared_state
,
1038 FilterOperations());
1040 RenderPassList pass_list
;
1042 pass_list
.push_back(child_pass
.Pass());
1043 pass_list
.push_back(root_pass
.Pass());
1045 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1046 // renderer so use a fuzzy comparator.
1047 EXPECT_TRUE(this->RunPixelTest(
1049 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
1050 FuzzyForSoftwareOnlyPixelComparator
<TypeParam
>(false)));
1053 TYPED_TEST(RendererPixelTest
, EnlargedRenderPassTexture
) {
1054 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1056 RenderPassId
root_pass_id(1, 1);
1057 scoped_ptr
<RenderPass
> root_pass
=
1058 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1060 RenderPassId
child_pass_id(2, 2);
1061 gfx::Rect
pass_rect(this->device_viewport_size_
);
1062 gfx::Transform transform_to_root
;
1063 scoped_ptr
<RenderPass
> child_pass
=
1064 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1066 gfx::Transform content_to_target_transform
;
1067 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1068 content_to_target_transform
, viewport_rect
, child_pass
.get());
1070 gfx::Rect
blue_rect(0,
1072 this->device_viewport_size_
.width(),
1073 this->device_viewport_size_
.height() / 2);
1074 SolidColorDrawQuad
* blue
=
1075 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1076 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1077 gfx::Rect
yellow_rect(0,
1078 this->device_viewport_size_
.height() / 2,
1079 this->device_viewport_size_
.width(),
1080 this->device_viewport_size_
.height() / 2);
1081 SolidColorDrawQuad
* yellow
=
1082 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1083 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1085 SharedQuadState
* pass_shared_state
=
1086 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1087 CreateTestRenderPassDrawQuad(
1088 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
1090 RenderPassList pass_list
;
1091 pass_list
.push_back(child_pass
.Pass());
1092 pass_list
.push_back(root_pass
.Pass());
1094 this->renderer_
->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1096 EXPECT_TRUE(this->RunPixelTest(
1098 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
1099 ExactPixelComparator(true)));
1102 TYPED_TEST(RendererPixelTest
, EnlargedRenderPassTextureWithAntiAliasing
) {
1103 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1105 RenderPassId
root_pass_id(1, 1);
1106 scoped_ptr
<RenderPass
> root_pass
=
1107 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1109 RenderPassId
child_pass_id(2, 2);
1110 gfx::Rect
pass_rect(this->device_viewport_size_
);
1111 gfx::Transform transform_to_root
;
1112 scoped_ptr
<RenderPass
> child_pass
=
1113 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1115 gfx::Transform content_to_target_transform
;
1116 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1117 content_to_target_transform
, viewport_rect
, child_pass
.get());
1119 gfx::Rect
blue_rect(0,
1121 this->device_viewport_size_
.width(),
1122 this->device_viewport_size_
.height() / 2);
1123 SolidColorDrawQuad
* blue
=
1124 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1125 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1126 gfx::Rect
yellow_rect(0,
1127 this->device_viewport_size_
.height() / 2,
1128 this->device_viewport_size_
.width(),
1129 this->device_viewport_size_
.height() / 2);
1130 SolidColorDrawQuad
* yellow
=
1131 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1132 yellow
->SetNew(shared_state
, yellow_rect
, yellow_rect
, SK_ColorYELLOW
, false);
1134 gfx::Transform aa_transform
;
1135 aa_transform
.Translate(0.5, 0.0);
1137 SharedQuadState
* pass_shared_state
=
1138 CreateTestSharedQuadState(aa_transform
, pass_rect
, root_pass
.get());
1139 CreateTestRenderPassDrawQuad(
1140 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
1142 SharedQuadState
* root_shared_state
= CreateTestSharedQuadState(
1143 gfx::Transform(), viewport_rect
, root_pass
.get());
1144 SolidColorDrawQuad
* background
=
1145 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1146 background
->SetNew(root_shared_state
,
1147 gfx::Rect(this->device_viewport_size_
),
1148 gfx::Rect(this->device_viewport_size_
),
1152 RenderPassList pass_list
;
1153 pass_list
.push_back(child_pass
.Pass());
1154 pass_list
.push_back(root_pass
.Pass());
1156 this->renderer_
->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1158 EXPECT_TRUE(this->RunPixelTest(
1160 base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")),
1161 FuzzyPixelOffByOneComparator(true)));
1164 // This tests the case where we have a RenderPass with a mask, but the quad
1165 // for the masked surface does not include the full surface texture.
1166 TYPED_TEST(RendererPixelTest
, RenderPassAndMaskWithPartialQuad
) {
1167 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1169 RenderPassId
root_pass_id(1, 1);
1170 scoped_ptr
<RenderPass
> root_pass
=
1171 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1172 SharedQuadState
* root_pass_shared_state
= CreateTestSharedQuadState(
1173 gfx::Transform(), viewport_rect
, root_pass
.get());
1175 RenderPassId
child_pass_id(2, 2);
1176 gfx::Transform transform_to_root
;
1177 scoped_ptr
<RenderPass
> child_pass
=
1178 CreateTestRenderPass(child_pass_id
, viewport_rect
, transform_to_root
);
1179 SharedQuadState
* child_pass_shared_state
= CreateTestSharedQuadState(
1180 gfx::Transform(), viewport_rect
, child_pass
.get());
1182 // The child render pass is just a green box.
1183 static const SkColor kCSSGreen
= 0xff008000;
1184 SolidColorDrawQuad
* green
=
1185 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1187 child_pass_shared_state
, viewport_rect
, viewport_rect
, kCSSGreen
, false);
1190 gfx::Rect mask_rect
= viewport_rect
;
1193 SkImageInfo::MakeN32Premul(mask_rect
.width(), mask_rect
.height()));
1194 SkCanvas
canvas(bitmap
);
1196 paint
.setStyle(SkPaint::kStroke_Style
);
1197 paint
.setStrokeWidth(SkIntToScalar(4));
1198 paint
.setColor(SK_ColorWHITE
);
1199 canvas
.clear(SK_ColorTRANSPARENT
);
1200 gfx::Rect rect
= mask_rect
;
1201 while (!rect
.IsEmpty()) {
1202 rect
.Inset(6, 6, 4, 4);
1204 SkRect::MakeXYWH(rect
.x(), rect
.y(), rect
.width(), rect
.height()),
1206 rect
.Inset(6, 6, 4, 4);
1209 ResourceProvider::ResourceId mask_resource_id
=
1210 this->resource_provider_
->CreateResource(
1213 ResourceProvider::TextureHintImmutable
,
1216 SkAutoLockPixels
lock(bitmap
);
1217 this->resource_provider_
->SetPixels(
1219 reinterpret_cast<uint8_t*>(bitmap
.getPixels()),
1225 // This RenderPassDrawQuad does not include the full |viewport_rect| which is
1226 // the size of the child render pass.
1227 gfx::Rect sub_rect
= gfx::Rect(50, 50, 100, 100);
1228 EXPECT_NE(sub_rect
.x(), child_pass
->output_rect
.x());
1229 EXPECT_NE(sub_rect
.y(), child_pass
->output_rect
.y());
1230 EXPECT_NE(sub_rect
.right(), child_pass
->output_rect
.right());
1231 EXPECT_NE(sub_rect
.bottom(), child_pass
->output_rect
.bottom());
1232 EXPECT_TRUE(child_pass
->output_rect
.Contains(sub_rect
));
1234 // Set up a mask on the RenderPassDrawQuad.
1235 RenderPassDrawQuad
* mask_quad
=
1236 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1237 mask_quad
->SetNew(root_pass_shared_state
,
1242 gfx::RectF(1.f
, 1.f
), // mask_uv_rect
1243 FilterOperations(), // foreground filters
1244 gfx::Vector2dF(), // filters scale
1245 FilterOperations()); // background filters
1247 // White background behind the masked render pass.
1248 SolidColorDrawQuad
* white
=
1249 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1250 white
->SetNew(root_pass_shared_state
,
1256 RenderPassList pass_list
;
1257 pass_list
.push_back(child_pass
.Pass());
1258 pass_list
.push_back(root_pass
.Pass());
1260 EXPECT_TRUE(this->RunPixelTest(
1262 base::FilePath(FILE_PATH_LITERAL("image_mask_of_layer.png")),
1263 ExactPixelComparator(true)));
1266 template <typename RendererType
>
1267 class RendererPixelTestWithBackgroundFilter
1268 : public RendererPixelTest
<RendererType
> {
1270 void SetUpRenderPassList() {
1271 gfx::Rect
device_viewport_rect(this->device_viewport_size_
);
1273 RenderPassId
root_id(1, 1);
1274 scoped_ptr
<RenderPass
> root_pass
=
1275 CreateTestRootRenderPass(root_id
, device_viewport_rect
);
1276 root_pass
->has_transparent_background
= false;
1278 gfx::Transform identity_content_to_target_transform
;
1280 RenderPassId
filter_pass_id(2, 1);
1281 gfx::Transform transform_to_root
;
1282 scoped_ptr
<RenderPass
> filter_pass
=
1283 CreateTestRenderPass(filter_pass_id
,
1284 filter_pass_content_rect_
,
1287 // A non-visible quad in the filtering render pass.
1289 SharedQuadState
* shared_state
=
1290 CreateTestSharedQuadState(identity_content_to_target_transform
,
1291 filter_pass_content_rect_
,
1293 SolidColorDrawQuad
* color_quad
=
1294 filter_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1295 color_quad
->SetNew(shared_state
,
1296 filter_pass_content_rect_
,
1297 filter_pass_content_rect_
,
1298 SK_ColorTRANSPARENT
,
1303 SharedQuadState
* shared_state
=
1304 CreateTestSharedQuadState(filter_pass_to_target_transform_
,
1305 filter_pass_content_rect_
,
1307 RenderPassDrawQuad
* filter_pass_quad
=
1308 root_pass
->CreateAndAppendDrawQuad
<RenderPassDrawQuad
>();
1309 filter_pass_quad
->SetNew(
1311 filter_pass_content_rect_
,
1312 filter_pass_content_rect_
,
1314 0, // mask_resource_id
1315 gfx::RectF(), // mask_uv_rect
1316 FilterOperations(), // filters
1317 gfx::Vector2dF(), // filters_scale
1318 this->background_filters_
);
1321 const int kColumnWidth
= device_viewport_rect
.width() / 3;
1323 gfx::Rect left_rect
= gfx::Rect(0, 0, kColumnWidth
, 20);
1324 for (int i
= 0; left_rect
.y() < device_viewport_rect
.height(); ++i
) {
1325 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1326 identity_content_to_target_transform
, left_rect
, root_pass
.get());
1327 SolidColorDrawQuad
* color_quad
=
1328 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1330 shared_state
, left_rect
, left_rect
, SK_ColorGREEN
, false);
1331 left_rect
+= gfx::Vector2d(0, left_rect
.height() + 1);
1334 gfx::Rect middle_rect
= gfx::Rect(kColumnWidth
+1, 0, kColumnWidth
, 20);
1335 for (int i
= 0; middle_rect
.y() < device_viewport_rect
.height(); ++i
) {
1336 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1337 identity_content_to_target_transform
, middle_rect
, root_pass
.get());
1338 SolidColorDrawQuad
* color_quad
=
1339 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1341 shared_state
, middle_rect
, middle_rect
, SK_ColorRED
, false);
1342 middle_rect
+= gfx::Vector2d(0, middle_rect
.height() + 1);
1345 gfx::Rect right_rect
= gfx::Rect((kColumnWidth
+1)*2, 0, kColumnWidth
, 20);
1346 for (int i
= 0; right_rect
.y() < device_viewport_rect
.height(); ++i
) {
1347 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1348 identity_content_to_target_transform
, right_rect
, root_pass
.get());
1349 SolidColorDrawQuad
* color_quad
=
1350 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1352 shared_state
, right_rect
, right_rect
, SK_ColorBLUE
, false);
1353 right_rect
+= gfx::Vector2d(0, right_rect
.height() + 1);
1356 SharedQuadState
* shared_state
=
1357 CreateTestSharedQuadState(identity_content_to_target_transform
,
1358 device_viewport_rect
,
1360 SolidColorDrawQuad
* background_quad
=
1361 root_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1362 background_quad
->SetNew(shared_state
,
1363 device_viewport_rect
,
1364 device_viewport_rect
,
1368 pass_list_
.push_back(filter_pass
.Pass());
1369 pass_list_
.push_back(root_pass
.Pass());
1372 RenderPassList pass_list_
;
1373 FilterOperations background_filters_
;
1374 gfx::Transform filter_pass_to_target_transform_
;
1375 gfx::Rect filter_pass_content_rect_
;
1378 typedef ::testing::Types
<GLRenderer
, SoftwareRenderer
>
1379 BackgroundFilterRendererTypes
;
1380 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter
,
1381 BackgroundFilterRendererTypes
);
1383 typedef RendererPixelTestWithBackgroundFilter
<GLRenderer
>
1384 GLRendererPixelTestWithBackgroundFilter
;
1386 // TODO(skaslev): The software renderer does not support filters yet.
1387 TEST_F(GLRendererPixelTestWithBackgroundFilter
, InvertFilter
) {
1388 this->background_filters_
.Append(
1389 FilterOperation::CreateInvertFilter(1.f
));
1391 this->filter_pass_content_rect_
= gfx::Rect(this->device_viewport_size_
);
1392 this->filter_pass_content_rect_
.Inset(12, 14, 16, 18);
1394 this->SetUpRenderPassList();
1395 EXPECT_TRUE(this->RunPixelTest(
1397 base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
1398 ExactPixelComparator(true)));
1401 class ExternalStencilPixelTest
: public GLRendererPixelTest
{
1403 void ClearBackgroundToGreen() {
1404 GLES2Interface
* gl
= output_surface_
->context_provider()->ContextGL();
1405 output_surface_
->EnsureBackbuffer();
1406 output_surface_
->Reshape(device_viewport_size_
, 1);
1407 gl
->ClearColor(0.f
, 1.f
, 0.f
, 1.f
);
1408 gl
->Clear(GL_COLOR_BUFFER_BIT
);
1411 void PopulateStencilBuffer() {
1412 // Set two quadrants of the stencil buffer to 1.
1413 GLES2Interface
* gl
= output_surface_
->context_provider()->ContextGL();
1414 output_surface_
->EnsureBackbuffer();
1415 output_surface_
->Reshape(device_viewport_size_
, 1);
1416 gl
->ClearStencil(0);
1417 gl
->Clear(GL_STENCIL_BUFFER_BIT
);
1418 gl
->Enable(GL_SCISSOR_TEST
);
1419 gl
->ClearStencil(1);
1422 device_viewport_size_
.width() / 2,
1423 device_viewport_size_
.height() / 2);
1424 gl
->Clear(GL_STENCIL_BUFFER_BIT
);
1425 gl
->Scissor(device_viewport_size_
.width() / 2,
1426 device_viewport_size_
.height() / 2,
1427 device_viewport_size_
.width(),
1428 device_viewport_size_
.height());
1429 gl
->Clear(GL_STENCIL_BUFFER_BIT
);
1433 TEST_F(ExternalStencilPixelTest
, StencilTestEnabled
) {
1434 ClearBackgroundToGreen();
1435 PopulateStencilBuffer();
1436 this->EnableExternalStencilTest();
1438 // Draw a blue quad that covers the entire device viewport. It should be
1439 // clipped to the bottom left and top right corners by the external stencil.
1440 gfx::Rect
rect(this->device_viewport_size_
);
1441 RenderPassId
id(1, 1);
1442 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1443 SharedQuadState
* blue_shared_state
=
1444 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1445 SolidColorDrawQuad
* blue
=
1446 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1447 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
1448 pass
->has_transparent_background
= false;
1449 RenderPassList pass_list
;
1450 pass_list
.push_back(pass
.Pass());
1452 EXPECT_TRUE(this->RunPixelTest(
1454 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1455 ExactPixelComparator(true)));
1458 TEST_F(ExternalStencilPixelTest
, StencilTestDisabled
) {
1459 PopulateStencilBuffer();
1461 // Draw a green quad that covers the entire device viewport. The stencil
1462 // buffer should be ignored.
1463 gfx::Rect
rect(this->device_viewport_size_
);
1464 RenderPassId
id(1, 1);
1465 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1466 SharedQuadState
* green_shared_state
=
1467 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1468 SolidColorDrawQuad
* green
=
1469 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1470 green
->SetNew(green_shared_state
, rect
, rect
, SK_ColorGREEN
, false);
1471 RenderPassList pass_list
;
1472 pass_list
.push_back(pass
.Pass());
1474 EXPECT_TRUE(this->RunPixelTest(
1476 base::FilePath(FILE_PATH_LITERAL("green.png")),
1477 ExactPixelComparator(true)));
1480 TEST_F(ExternalStencilPixelTest
, RenderSurfacesIgnoreStencil
) {
1481 // The stencil test should apply only to the final render pass.
1482 ClearBackgroundToGreen();
1483 PopulateStencilBuffer();
1484 this->EnableExternalStencilTest();
1486 gfx::Rect
viewport_rect(this->device_viewport_size_
);
1488 RenderPassId
root_pass_id(1, 1);
1489 scoped_ptr
<RenderPass
> root_pass
=
1490 CreateTestRootRenderPass(root_pass_id
, viewport_rect
);
1491 root_pass
->has_transparent_background
= false;
1493 RenderPassId
child_pass_id(2, 2);
1494 gfx::Rect
pass_rect(this->device_viewport_size_
);
1495 gfx::Transform transform_to_root
;
1496 scoped_ptr
<RenderPass
> child_pass
=
1497 CreateTestRenderPass(child_pass_id
, pass_rect
, transform_to_root
);
1499 gfx::Transform content_to_target_transform
;
1500 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1501 content_to_target_transform
, viewport_rect
, child_pass
.get());
1503 gfx::Rect
blue_rect(0,
1505 this->device_viewport_size_
.width(),
1506 this->device_viewport_size_
.height());
1507 SolidColorDrawQuad
* blue
=
1508 child_pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1509 blue
->SetNew(shared_state
, blue_rect
, blue_rect
, SK_ColorBLUE
, false);
1511 SharedQuadState
* pass_shared_state
=
1512 CreateTestSharedQuadState(gfx::Transform(), pass_rect
, root_pass
.get());
1513 CreateTestRenderPassDrawQuad(
1514 pass_shared_state
, pass_rect
, child_pass_id
, root_pass
.get());
1515 RenderPassList pass_list
;
1516 pass_list
.push_back(child_pass
.Pass());
1517 pass_list
.push_back(root_pass
.Pass());
1519 EXPECT_TRUE(this->RunPixelTest(
1521 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1522 ExactPixelComparator(true)));
1525 TEST_F(ExternalStencilPixelTest
, DeviceClip
) {
1526 ClearBackgroundToGreen();
1527 gfx::Rect
clip_rect(gfx::Point(150, 150), gfx::Size(50, 50));
1528 this->ForceDeviceClip(clip_rect
);
1530 // Draw a blue quad that covers the entire device viewport. It should be
1531 // clipped to the bottom right corner by the device clip.
1532 gfx::Rect
rect(this->device_viewport_size_
);
1533 RenderPassId
id(1, 1);
1534 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1535 SharedQuadState
* blue_shared_state
=
1536 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1537 SolidColorDrawQuad
* blue
=
1538 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1539 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
1540 RenderPassList pass_list
;
1541 pass_list
.push_back(pass
.Pass());
1543 EXPECT_TRUE(this->RunPixelTest(
1545 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
1546 ExactPixelComparator(true)));
1549 // Software renderer does not support anti-aliased edges.
1550 TEST_F(GLRendererPixelTest
, AntiAliasing
) {
1551 gfx::Rect
rect(this->device_viewport_size_
);
1553 RenderPassId
id(1, 1);
1554 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
1556 gfx::Transform red_content_to_target_transform
;
1557 red_content_to_target_transform
.Rotate(10);
1558 SharedQuadState
* red_shared_state
= CreateTestSharedQuadState(
1559 red_content_to_target_transform
, rect
, pass
.get());
1561 SolidColorDrawQuad
* red
= pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1562 red
->SetNew(red_shared_state
, rect
, rect
, SK_ColorRED
, false);
1564 gfx::Transform yellow_content_to_target_transform
;
1565 yellow_content_to_target_transform
.Rotate(5);
1566 SharedQuadState
* yellow_shared_state
= CreateTestSharedQuadState(
1567 yellow_content_to_target_transform
, rect
, pass
.get());
1569 SolidColorDrawQuad
* yellow
=
1570 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1571 yellow
->SetNew(yellow_shared_state
, rect
, rect
, SK_ColorYELLOW
, false);
1573 gfx::Transform blue_content_to_target_transform
;
1574 SharedQuadState
* blue_shared_state
= CreateTestSharedQuadState(
1575 blue_content_to_target_transform
, rect
, pass
.get());
1577 SolidColorDrawQuad
* blue
=
1578 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1579 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
1581 RenderPassList pass_list
;
1582 pass_list
.push_back(pass
.Pass());
1584 EXPECT_TRUE(this->RunPixelTest(
1586 base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")),
1587 FuzzyPixelOffByOneComparator(true)));
1590 // This test tests that anti-aliasing works for axis aligned quads.
1591 // Anti-aliasing is only supported in the gl renderer.
1592 TEST_F(GLRendererPixelTest
, AxisAligned
) {
1593 gfx::Rect
rect(this->device_viewport_size_
);
1595 RenderPassId
id(1, 1);
1596 gfx::Transform transform_to_root
;
1597 scoped_ptr
<RenderPass
> pass
=
1598 CreateTestRenderPass(id
, rect
, transform_to_root
);
1600 gfx::Transform red_content_to_target_transform
;
1601 red_content_to_target_transform
.Translate(50, 50);
1602 red_content_to_target_transform
.Scale(
1603 0.5f
+ 1.0f
/ (rect
.width() * 2.0f
),
1604 0.5f
+ 1.0f
/ (rect
.height() * 2.0f
));
1605 SharedQuadState
* red_shared_state
= CreateTestSharedQuadState(
1606 red_content_to_target_transform
, rect
, pass
.get());
1608 SolidColorDrawQuad
* red
= pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1609 red
->SetNew(red_shared_state
, rect
, rect
, SK_ColorRED
, false);
1611 gfx::Transform yellow_content_to_target_transform
;
1612 yellow_content_to_target_transform
.Translate(25.5f
, 25.5f
);
1613 yellow_content_to_target_transform
.Scale(0.5f
, 0.5f
);
1614 SharedQuadState
* yellow_shared_state
= CreateTestSharedQuadState(
1615 yellow_content_to_target_transform
, rect
, pass
.get());
1617 SolidColorDrawQuad
* yellow
=
1618 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1619 yellow
->SetNew(yellow_shared_state
, rect
, rect
, SK_ColorYELLOW
, false);
1621 gfx::Transform blue_content_to_target_transform
;
1622 SharedQuadState
* blue_shared_state
= CreateTestSharedQuadState(
1623 blue_content_to_target_transform
, rect
, pass
.get());
1625 SolidColorDrawQuad
* blue
=
1626 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1627 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
1629 RenderPassList pass_list
;
1630 pass_list
.push_back(pass
.Pass());
1632 EXPECT_TRUE(this->RunPixelTest(
1634 base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")),
1635 ExactPixelComparator(true)));
1638 // This test tests that forcing anti-aliasing off works as expected.
1639 // Anti-aliasing is only supported in the gl renderer.
1640 TEST_F(GLRendererPixelTest
, ForceAntiAliasingOff
) {
1641 gfx::Rect
rect(this->device_viewport_size_
);
1643 RenderPassId
id(1, 1);
1644 gfx::Transform transform_to_root
;
1645 scoped_ptr
<RenderPass
> pass
=
1646 CreateTestRenderPass(id
, rect
, transform_to_root
);
1648 gfx::Transform hole_content_to_target_transform
;
1649 hole_content_to_target_transform
.Translate(50, 50);
1650 hole_content_to_target_transform
.Scale(
1651 0.5f
+ 1.0f
/ (rect
.width() * 2.0f
),
1652 0.5f
+ 1.0f
/ (rect
.height() * 2.0f
));
1653 SharedQuadState
* hole_shared_state
= CreateTestSharedQuadState(
1654 hole_content_to_target_transform
, rect
, pass
.get());
1656 SolidColorDrawQuad
* hole
=
1657 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1659 hole_shared_state
, rect
, rect
, rect
, false, SK_ColorTRANSPARENT
, true);
1661 gfx::Transform green_content_to_target_transform
;
1662 SharedQuadState
* green_shared_state
= CreateTestSharedQuadState(
1663 green_content_to_target_transform
, rect
, pass
.get());
1665 SolidColorDrawQuad
* green
=
1666 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1667 green
->SetNew(green_shared_state
, rect
, rect
, SK_ColorGREEN
, false);
1669 RenderPassList pass_list
;
1670 pass_list
.push_back(pass
.Pass());
1672 EXPECT_TRUE(this->RunPixelTest(
1674 base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")),
1675 ExactPixelComparator(false)));
1678 TEST_F(GLRendererPixelTest
, AntiAliasingPerspective
) {
1679 gfx::Rect
rect(this->device_viewport_size_
);
1681 scoped_ptr
<RenderPass
> pass
=
1682 CreateTestRootRenderPass(RenderPassId(1, 1), rect
);
1684 gfx::Rect
red_rect(0, 0, 180, 500);
1685 gfx::Transform
red_content_to_target_transform(
1686 1.0f
, 2.4520f
, 10.6206f
, 19.0f
,
1687 0.0f
, 0.3528f
, 5.9737f
, 9.5f
,
1688 0.0f
, -0.2250f
, -0.9744f
, 0.0f
,
1689 0.0f
, 0.0225f
, 0.0974f
, 1.0f
);
1690 SharedQuadState
* red_shared_state
= CreateTestSharedQuadState(
1691 red_content_to_target_transform
, red_rect
, pass
.get());
1692 SolidColorDrawQuad
* red
= pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1693 red
->SetNew(red_shared_state
, red_rect
, red_rect
, SK_ColorRED
, false);
1695 gfx::Rect
green_rect(19, 7, 180, 10);
1696 SharedQuadState
* green_shared_state
=
1697 CreateTestSharedQuadState(gfx::Transform(), green_rect
, pass
.get());
1698 SolidColorDrawQuad
* green
=
1699 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1701 green_shared_state
, green_rect
, green_rect
, SK_ColorGREEN
, false);
1703 SharedQuadState
* blue_shared_state
=
1704 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
1705 SolidColorDrawQuad
* blue
=
1706 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
1707 blue
->SetNew(blue_shared_state
, rect
, rect
, SK_ColorBLUE
, false);
1709 RenderPassList pass_list
;
1710 pass_list
.push_back(pass
.Pass());
1712 EXPECT_TRUE(this->RunPixelTest(
1714 base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")),
1715 FuzzyPixelOffByOneComparator(true)));
1718 TYPED_TEST(RendererPixelTest
, PictureDrawQuadIdentityScale
) {
1719 gfx::Size
pile_tile_size(1000, 1000);
1720 gfx::Rect
viewport(this->device_viewport_size_
);
1721 // TODO(enne): the renderer should figure this out on its own.
1722 ResourceFormat texture_format
= RGBA_8888
;
1724 RenderPassId
id(1, 1);
1725 gfx::Transform transform_to_root
;
1726 scoped_ptr
<RenderPass
> pass
=
1727 CreateTestRenderPass(id
, viewport
, transform_to_root
);
1729 // One clipped blue quad in the lower right corner. Outside the clip
1730 // is red, which should not appear.
1731 gfx::Rect
blue_rect(gfx::Size(100, 100));
1732 gfx::Rect
blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50));
1733 scoped_refptr
<FakePicturePileImpl
> blue_pile
=
1734 FakePicturePileImpl::CreateFilledPile(pile_tile_size
, blue_rect
.size());
1736 red_paint
.setColor(SK_ColorRED
);
1737 blue_pile
->add_draw_rect_with_paint(blue_rect
, red_paint
);
1739 blue_paint
.setColor(SK_ColorBLUE
);
1740 blue_pile
->add_draw_rect_with_paint(blue_clip_rect
, blue_paint
);
1741 blue_pile
->RerecordPile();
1743 gfx::Transform blue_content_to_target_transform
;
1744 gfx::Vector2d
offset(viewport
.bottom_right() - blue_rect
.bottom_right());
1745 blue_content_to_target_transform
.Translate(offset
.x(), offset
.y());
1746 gfx::RectF blue_scissor_rect
= blue_clip_rect
;
1747 blue_content_to_target_transform
.TransformRect(&blue_scissor_rect
);
1748 SharedQuadState
* blue_shared_state
=
1749 CreateTestSharedQuadStateClipped(blue_content_to_target_transform
,
1751 gfx::ToEnclosingRect(blue_scissor_rect
),
1754 PictureDrawQuad
* blue_quad
= pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
1756 blue_quad
->SetNew(blue_shared_state
,
1757 viewport
, // Intentionally bigger than clip.
1760 gfx::RectF(viewport
),
1765 PicturePileImpl::CreateFromOther(blue_pile
.get()));
1767 // One viewport-filling green quad.
1768 scoped_refptr
<FakePicturePileImpl
> green_pile
=
1769 FakePicturePileImpl::CreateFilledPile(pile_tile_size
, viewport
.size());
1770 SkPaint green_paint
;
1771 green_paint
.setColor(SK_ColorGREEN
);
1772 green_pile
->add_draw_rect_with_paint(viewport
, green_paint
);
1773 green_pile
->RerecordPile();
1775 gfx::Transform green_content_to_target_transform
;
1776 SharedQuadState
* green_shared_state
= CreateTestSharedQuadState(
1777 green_content_to_target_transform
, viewport
, pass
.get());
1779 PictureDrawQuad
* green_quad
=
1780 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
1781 green_quad
->SetNew(green_shared_state
,
1785 gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
),
1790 PicturePileImpl::CreateFromOther(green_pile
.get()));
1792 RenderPassList pass_list
;
1793 pass_list
.push_back(pass
.Pass());
1795 EXPECT_TRUE(this->RunPixelTest(
1797 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
1798 ExactPixelComparator(true)));
1801 // Not WithSkiaGPUBackend since that path currently requires tiles for opacity.
1802 TYPED_TEST(RendererPixelTest
, PictureDrawQuadOpacity
) {
1803 gfx::Size
pile_tile_size(1000, 1000);
1804 gfx::Rect
viewport(this->device_viewport_size_
);
1805 ResourceFormat texture_format
= RGBA_8888
;
1807 RenderPassId
id(1, 1);
1808 gfx::Transform transform_to_root
;
1809 scoped_ptr
<RenderPass
> pass
=
1810 CreateTestRenderPass(id
, viewport
, transform_to_root
);
1812 // One viewport-filling 0.5-opacity green quad.
1813 scoped_refptr
<FakePicturePileImpl
> green_pile
=
1814 FakePicturePileImpl::CreateFilledPile(pile_tile_size
, viewport
.size());
1815 SkPaint green_paint
;
1816 green_paint
.setColor(SK_ColorGREEN
);
1817 green_pile
->add_draw_rect_with_paint(viewport
, green_paint
);
1818 green_pile
->RerecordPile();
1820 gfx::Transform green_content_to_target_transform
;
1821 SharedQuadState
* green_shared_state
= CreateTestSharedQuadState(
1822 green_content_to_target_transform
, viewport
, pass
.get());
1823 green_shared_state
->opacity
= 0.5f
;
1825 PictureDrawQuad
* green_quad
=
1826 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
1827 green_quad
->SetNew(green_shared_state
,
1831 gfx::RectF(0, 0, 1, 1),
1836 PicturePileImpl::CreateFromOther(green_pile
.get()));
1838 // One viewport-filling white quad.
1839 scoped_refptr
<FakePicturePileImpl
> white_pile
=
1840 FakePicturePileImpl::CreateFilledPile(pile_tile_size
, viewport
.size());
1841 SkPaint white_paint
;
1842 white_paint
.setColor(SK_ColorWHITE
);
1843 white_pile
->add_draw_rect_with_paint(viewport
, white_paint
);
1844 white_pile
->RerecordPile();
1846 gfx::Transform white_content_to_target_transform
;
1847 SharedQuadState
* white_shared_state
= CreateTestSharedQuadState(
1848 white_content_to_target_transform
, viewport
, pass
.get());
1850 PictureDrawQuad
* white_quad
=
1851 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
1852 white_quad
->SetNew(white_shared_state
,
1856 gfx::RectF(0, 0, 1, 1),
1861 PicturePileImpl::CreateFromOther(white_pile
.get()));
1863 RenderPassList pass_list
;
1864 pass_list
.push_back(pass
.Pass());
1866 EXPECT_TRUE(this->RunPixelTest(
1868 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
1869 FuzzyPixelOffByOneComparator(true)));
1872 template<typename TypeParam
> bool IsSoftwareRenderer() {
1877 bool IsSoftwareRenderer
<SoftwareRenderer
>() {
1882 bool IsSoftwareRenderer
<SoftwareRendererWithExpandedViewport
>() {
1886 // If we disable image filtering, then a 2x2 bitmap should appear as four
1887 // huge sharp squares.
1888 TYPED_TEST(RendererPixelTest
, PictureDrawQuadDisableImageFiltering
) {
1889 // We only care about this in software mode since bilinear filtering is
1890 // cheap in hardware.
1891 if (!IsSoftwareRenderer
<TypeParam
>())
1894 gfx::Size
pile_tile_size(1000, 1000);
1895 gfx::Rect
viewport(this->device_viewport_size_
);
1896 ResourceFormat texture_format
= RGBA_8888
;
1898 RenderPassId
id(1, 1);
1899 gfx::Transform transform_to_root
;
1900 scoped_ptr
<RenderPass
> pass
=
1901 CreateTestRenderPass(id
, viewport
, transform_to_root
);
1904 bitmap
.allocN32Pixels(2, 2);
1906 SkAutoLockPixels
lock(bitmap
);
1907 SkCanvas
canvas(bitmap
);
1908 canvas
.drawPoint(0, 0, SK_ColorGREEN
);
1909 canvas
.drawPoint(0, 1, SK_ColorBLUE
);
1910 canvas
.drawPoint(1, 0, SK_ColorBLUE
);
1911 canvas
.drawPoint(1, 1, SK_ColorGREEN
);
1914 scoped_refptr
<FakePicturePileImpl
> pile
=
1915 FakePicturePileImpl::CreateFilledPile(pile_tile_size
, viewport
.size());
1917 paint
.setFilterLevel(SkPaint::kLow_FilterLevel
);
1918 pile
->add_draw_bitmap_with_paint(bitmap
, gfx::Point(), paint
);
1919 pile
->RerecordPile();
1921 gfx::Transform content_to_target_transform
;
1922 SharedQuadState
* shared_state
= CreateTestSharedQuadState(
1923 content_to_target_transform
, viewport
, pass
.get());
1925 PictureDrawQuad
* quad
= pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
1926 quad
->SetNew(shared_state
,
1930 gfx::RectF(0, 0, 2, 2),
1935 PicturePileImpl::CreateFromOther(pile
.get()));
1937 RenderPassList pass_list
;
1938 pass_list
.push_back(pass
.Pass());
1940 this->disable_picture_quad_image_filtering_
= true;
1942 EXPECT_TRUE(this->RunPixelTest(
1944 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1945 ExactPixelComparator(true)));
1948 TYPED_TEST(RendererPixelTest
, PictureDrawQuadNonIdentityScale
) {
1949 gfx::Size
pile_tile_size(1000, 1000);
1950 gfx::Rect
viewport(this->device_viewport_size_
);
1951 // TODO(enne): the renderer should figure this out on its own.
1952 ResourceFormat texture_format
= RGBA_8888
;
1954 RenderPassId
id(1, 1);
1955 gfx::Transform transform_to_root
;
1956 scoped_ptr
<RenderPass
> pass
=
1957 CreateTestRenderPass(id
, viewport
, transform_to_root
);
1959 // As scaling up the blue checkerboards will cause sampling on the GPU,
1960 // a few extra "cleanup rects" need to be added to clobber the blending
1961 // to make the output image more clean. This will also test subrects
1963 gfx::Transform green_content_to_target_transform
;
1964 gfx::Rect
green_rect1(gfx::Point(80, 0), gfx::Size(20, 100));
1965 gfx::Rect
green_rect2(gfx::Point(0, 80), gfx::Size(100, 20));
1966 scoped_refptr
<FakePicturePileImpl
> green_pile
=
1967 FakePicturePileImpl::CreateFilledPile(pile_tile_size
, viewport
.size());
1969 red_paint
.setColor(SK_ColorRED
);
1970 green_pile
->add_draw_rect_with_paint(viewport
, red_paint
);
1971 SkPaint green_paint
;
1972 green_paint
.setColor(SK_ColorGREEN
);
1973 green_pile
->add_draw_rect_with_paint(green_rect1
, green_paint
);
1974 green_pile
->add_draw_rect_with_paint(green_rect2
, green_paint
);
1975 green_pile
->RerecordPile();
1977 SharedQuadState
* top_right_green_shared_quad_state
=
1978 CreateTestSharedQuadState(
1979 green_content_to_target_transform
, viewport
, pass
.get());
1981 PictureDrawQuad
* green_quad1
=
1982 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
1983 green_quad1
->SetNew(top_right_green_shared_quad_state
,
1987 gfx::RectF(green_rect1
.size()),
1992 PicturePileImpl::CreateFromOther(green_pile
.get()));
1994 PictureDrawQuad
* green_quad2
=
1995 pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
1996 green_quad2
->SetNew(top_right_green_shared_quad_state
,
2000 gfx::RectF(green_rect2
.size()),
2005 PicturePileImpl::CreateFromOther(green_pile
.get()));
2007 // Add a green clipped checkerboard in the bottom right to help test
2008 // interleaving picture quad content and solid color content.
2009 gfx::Rect
bottom_right_rect(
2010 gfx::Point(viewport
.width() / 2, viewport
.height() / 2),
2011 gfx::Size(viewport
.width() / 2, viewport
.height() / 2));
2012 SharedQuadState
* bottom_right_green_shared_state
=
2013 CreateTestSharedQuadStateClipped(green_content_to_target_transform
,
2017 SolidColorDrawQuad
* bottom_right_color_quad
=
2018 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2019 bottom_right_color_quad
->SetNew(bottom_right_green_shared_state
,
2025 // Add two blue checkerboards taking up the bottom left and top right,
2026 // but use content scales as content rects to make this happen.
2027 // The content is at a 4x content scale.
2028 gfx::Rect
layer_rect(gfx::Size(20, 30));
2029 float contents_scale
= 4.f
;
2030 // Two rects that touch at their corners, arbitrarily placed in the layer.
2031 gfx::RectF
blue_layer_rect1(gfx::PointF(5.5f
, 9.0f
), gfx::SizeF(2.5f
, 2.5f
));
2032 gfx::RectF
blue_layer_rect2(gfx::PointF(8.0f
, 6.5f
), gfx::SizeF(2.5f
, 2.5f
));
2033 gfx::RectF union_layer_rect
= blue_layer_rect1
;
2034 union_layer_rect
.Union(blue_layer_rect2
);
2036 // Because scaling up will cause sampling outside the rects, add one extra
2037 // pixel of buffer at the final content scale.
2038 float inset
= -1.f
/ contents_scale
;
2039 blue_layer_rect1
.Inset(inset
, inset
, inset
, inset
);
2040 blue_layer_rect2
.Inset(inset
, inset
, inset
, inset
);
2042 scoped_refptr
<FakePicturePileImpl
> pile
=
2043 FakePicturePileImpl::CreateFilledPile(pile_tile_size
, layer_rect
.size());
2045 Region
outside(layer_rect
);
2046 outside
.Subtract(gfx::ToEnclosingRect(union_layer_rect
));
2047 for (Region::Iterator
iter(outside
); iter
.has_rect(); iter
.next()) {
2048 pile
->add_draw_rect_with_paint(iter
.rect(), red_paint
);
2052 blue_paint
.setColor(SK_ColorBLUE
);
2053 pile
->add_draw_rect_with_paint(blue_layer_rect1
, blue_paint
);
2054 pile
->add_draw_rect_with_paint(blue_layer_rect2
, blue_paint
);
2055 pile
->RerecordPile();
2057 gfx::Rect
content_rect(
2058 gfx::ScaleToEnclosingRect(layer_rect
, contents_scale
));
2059 gfx::Rect
content_union_rect(
2060 gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect
, contents_scale
)));
2062 // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels,
2063 // so scale an additional 10x to make them 100x100.
2064 gfx::Transform content_to_target_transform
;
2065 content_to_target_transform
.Scale(10.0, 10.0);
2066 gfx::Rect
quad_content_rect(gfx::Size(20, 20));
2067 SharedQuadState
* blue_shared_state
= CreateTestSharedQuadState(
2068 content_to_target_transform
, quad_content_rect
, pass
.get());
2070 PictureDrawQuad
* blue_quad
= pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2071 blue_quad
->SetNew(blue_shared_state
,
2075 gfx::RectF(quad_content_rect
),
2076 content_union_rect
.size(),
2080 PicturePileImpl::CreateFromOther(pile
.get()));
2082 // Fill left half of viewport with green.
2083 gfx::Transform half_green_content_to_target_transform
;
2084 gfx::Rect
half_green_rect(gfx::Size(viewport
.width() / 2, viewport
.height()));
2085 SharedQuadState
* half_green_shared_state
= CreateTestSharedQuadState(
2086 half_green_content_to_target_transform
, half_green_rect
, pass
.get());
2087 SolidColorDrawQuad
* half_color_quad
=
2088 pass
->CreateAndAppendDrawQuad
<SolidColorDrawQuad
>();
2089 half_color_quad
->SetNew(half_green_shared_state
,
2095 RenderPassList pass_list
;
2096 pass_list
.push_back(pass
.Pass());
2098 EXPECT_TRUE(this->RunPixelTest(
2100 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2101 ExactPixelComparator(true)));
2104 TEST_F(GLRendererPixelTest
, PictureDrawQuadTexture4444
) {
2105 gfx::Size
pile_tile_size(1000, 1000);
2106 gfx::Rect
viewport(this->device_viewport_size_
);
2107 ResourceFormat texture_format
= RGBA_4444
;
2109 RenderPassId
id(1, 1);
2110 gfx::Transform transform_to_root
;
2111 scoped_ptr
<RenderPass
> pass
=
2112 CreateTestRenderPass(id
, viewport
, transform_to_root
);
2114 // One viewport-filling blue quad
2115 scoped_refptr
<FakePicturePileImpl
> blue_pile
=
2116 FakePicturePileImpl::CreateFilledPile(pile_tile_size
, viewport
.size());
2118 blue_paint
.setColor(SK_ColorBLUE
);
2119 blue_pile
->add_draw_rect_with_paint(viewport
, blue_paint
);
2120 blue_pile
->RerecordPile();
2122 gfx::Transform blue_content_to_target_transform
;
2123 SharedQuadState
* blue_shared_state
= CreateTestSharedQuadState(
2124 blue_content_to_target_transform
, viewport
, pass
.get());
2126 PictureDrawQuad
* blue_quad
= pass
->CreateAndAppendDrawQuad
<PictureDrawQuad
>();
2127 blue_quad
->SetNew(blue_shared_state
,
2131 gfx::RectF(0.f
, 0.f
, 1.f
, 1.f
),
2136 PicturePileImpl::CreateFromOther(blue_pile
.get()));
2138 RenderPassList pass_list
;
2139 pass_list
.push_back(pass
.Pass());
2141 EXPECT_TRUE(this->RunPixelTest(&pass_list
,
2142 base::FilePath(FILE_PATH_LITERAL("blue.png")),
2143 ExactPixelComparator(true)));
2146 TYPED_TEST(RendererPixelTest
, WrapModeRepeat
) {
2147 gfx::Rect
rect(this->device_viewport_size_
);
2149 RenderPassId
id(1, 1);
2150 scoped_ptr
<RenderPass
> pass
= CreateTestRootRenderPass(id
, rect
);
2152 SharedQuadState
* shared_state
=
2153 CreateTestSharedQuadState(gfx::Transform(), rect
, pass
.get());
2155 gfx::Rect
texture_rect(4, 4);
2156 SkPMColor colors
[4] = {
2157 SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)),
2158 SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)),
2159 SkPreMultiplyColor(SkColorSetARGB(255, 0, 64, 0)),
2160 SkPreMultiplyColor(SkColorSetARGB(255, 0, 0, 0)),
2162 uint32_t pixels
[16] = {
2163 colors
[0], colors
[0], colors
[1], colors
[1],
2164 colors
[0], colors
[0], colors
[1], colors
[1],
2165 colors
[2], colors
[2], colors
[3], colors
[3],
2166 colors
[2], colors
[2], colors
[3], colors
[3],
2168 ResourceProvider::ResourceId resource
=
2169 this->resource_provider_
->CreateResource(
2170 texture_rect
.size(),
2172 ResourceProvider::TextureHintImmutable
,
2174 this->resource_provider_
->SetPixels(
2176 reinterpret_cast<uint8_t*>(pixels
),
2181 float vertex_opacity
[4] = {1.0f
, 1.0f
, 1.0f
, 1.0f
};
2182 TextureDrawQuad
* texture_quad
=
2183 pass
->CreateAndAppendDrawQuad
<TextureDrawQuad
>();
2184 texture_quad
->SetNew(
2186 gfx::Rect(this->device_viewport_size_
),
2188 gfx::Rect(this->device_viewport_size_
),
2190 true, // premultiplied_alpha
2191 gfx::PointF(0.0f
, 0.0f
), // uv_top_left
2192 gfx::PointF( // uv_bottom_right
2193 this->device_viewport_size_
.width() / texture_rect
.width(),
2194 this->device_viewport_size_
.height() / texture_rect
.height()),
2199 RenderPassList pass_list
;
2200 pass_list
.push_back(pass
.Pass());
2202 EXPECT_TRUE(this->RunPixelTest(
2204 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
2205 FuzzyPixelOffByOneComparator(true)));
2208 #endif // !defined(OS_ANDROID)