Adds initial key systems support for Chromecast.
[chromium-blink-merge.git] / cc / output / renderer_pixeltest.cc
blob32e34ccb58b008df1a7df3ac684d8d653c2e8b73
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;
26 namespace cc {
27 namespace {
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);
37 return pass.Pass();
40 scoped_ptr<RenderPass> CreateTestRenderPass(
41 RenderPassId id,
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);
48 return pass.Pass();
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,
64 content_bounds,
65 visible_content_rect,
66 clip_rect,
67 is_clipped,
68 opacity,
69 blend_mode,
70 sorting_context_id);
71 return shared_state;
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,
87 content_bounds,
88 visible_content_rect,
89 clip_rect,
90 is_clipped,
91 opacity,
92 blend_mode,
93 sorting_context_id);
94 return shared_state;
97 void CreateTestRenderPassDrawQuad(const SharedQuadState* shared_state,
98 const gfx::Rect& rect,
99 RenderPassId pass_id,
100 RenderPass* render_pass) {
101 RenderPassDrawQuad* quad =
102 render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
103 quad->SetNew(shared_state,
104 rect,
105 rect,
106 pass_id,
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,
115 SkColor texel_color,
116 SkColor background_color,
117 bool premultiplied_alpha,
118 const SharedQuadState* shared_state,
119 ResourceProvider* resource_provider,
120 RenderPass* render_pass) {
121 SkPMColor pixel_color = premultiplied_alpha ?
122 SkPreMultiplyColor(texel_color) :
123 SkPackARGB32NoCheck(SkColorGetA(texel_color),
124 SkColorGetR(texel_color),
125 SkColorGetG(texel_color),
126 SkColorGetB(texel_color));
127 std::vector<uint32_t> pixels(rect.size().GetArea(), pixel_color);
129 ResourceProvider::ResourceId resource =
130 resource_provider->CreateResource(rect.size(),
131 GL_CLAMP_TO_EDGE,
132 ResourceProvider::TextureHintImmutable,
133 RGBA_8888);
134 resource_provider->SetPixels(
135 resource,
136 reinterpret_cast<uint8_t*>(&pixels.front()),
137 rect,
138 rect,
139 gfx::Vector2d());
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,
146 rect,
147 gfx::Rect(),
148 rect,
149 resource,
150 premultiplied_alpha,
151 gfx::PointF(0.0f, 0.0f), // uv_top_left
152 gfx::PointF(1.0f, 1.0f), // uv_bottom_right
153 background_color,
154 vertex_opacity,
155 false); // flipped
158 typedef ::testing::Types<GLRenderer,
159 SoftwareRenderer,
160 GLRendererWithExpandedViewport,
161 SoftwareRendererWithExpandedViewport> RendererTypes;
162 TYPED_TEST_CASE(RendererPixelTest, RendererTypes);
164 template <typename RendererType>
165 class FuzzyForSoftwareOnlyPixelComparator : public PixelComparator {
166 public:
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;
173 private:
174 FuzzyPixelOffByOneComparator fuzzy_;
175 ExactPixelComparator exact_;
178 template<>
179 bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare(
180 const SkBitmap& actual_bmp,
181 const SkBitmap& expected_bmp) const {
182 return fuzzy_.Compare(actual_bmp, expected_bmp);
185 template <>
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(
217 &pass_list,
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(
254 &pass_list,
255 child_pass_ptr,
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.
273 shared_state,
274 this->resource_provider_.get(),
275 pass.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(
285 &pass_list,
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.
304 texture_quad_state,
305 this->resource_provider_.get(),
306 pass.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(
318 &pass_list,
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.
337 shared_state,
338 this->resource_provider_.get(),
339 pass.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(
349 &pass_list,
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.
369 texture_quad_state,
370 this->resource_provider_.get(),
371 pass.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(
383 &pass_list,
384 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
385 FuzzyPixelOffByOneComparator(true)));
388 class VideoGLRendererPixelTest : public GLRendererPixelTest {
389 protected:
390 void CreateTestYUVVideoDrawQuad_Striped(const SharedQuadState* shared_state,
391 media::VideoFrame::Format format,
392 bool is_transparent,
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.
403 uint8_t y_value = 0;
404 uint8_t u_value = 0;
405 uint8_t v_value = 0;
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);
410 ++j) {
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);
420 ++j) {
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,
431 bool is_transparent,
432 const gfx::RectF& tex_coord_rect,
433 uint8 y,
434 uint8 u,
435 uint8 v,
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,
465 bool is_transparent,
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);
476 if (with_alpha)
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(
484 video_frame);
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;
508 if (with_alpha) {
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,
518 rect,
519 opaque_rect,
520 rect,
521 tex_coord_rect,
522 y_resource,
523 u_resource,
524 v_resource,
525 a_resource,
526 color_space);
529 virtual void SetUp() OVERRIDE {
530 GLRendererPixelTest::SetUp();
531 video_resource_updater_.reset(new VideoResourceUpdater(
532 output_surface_->context_provider(), resource_provider_.get()));
535 private:
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,
550 false,
551 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
552 pass.get());
554 RenderPassList pass_list;
555 pass_list.push_back(pass.Pass());
557 EXPECT_TRUE(
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,
575 false,
576 gfx::RectF(0.125f, 0.25f, 0.75f, 0.5f),
577 pass.get());
579 RenderPassList pass_list;
580 pass_list.push_back(pass.Pass());
582 EXPECT_TRUE(this->RunPixelTest(
583 &pass_list,
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,
600 false,
601 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
603 128,
604 128,
605 pass.get());
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,
629 false,
630 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
631 149,
634 pass.get());
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,
656 false,
657 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
659 128,
660 128,
661 pass.get());
663 RenderPassList pass_list;
664 pass_list.push_back(pass.Pass());
666 EXPECT_TRUE(
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,
683 false,
684 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
685 pass.get());
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(
695 &pass_list,
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,
711 true,
712 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
713 pass.get());
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(
723 &pass_list,
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>();
766 white->SetNew(
767 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
769 SharedQuadState* pass_shared_state =
770 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
772 SkScalar matrix[20];
773 float amount = 0.5f;
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;
787 matrix[18] = 1;
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,
798 pass_rect,
799 pass_rect,
800 child_pass_id,
802 gfx::RectF(),
803 filters,
804 gfx::Vector2dF(),
805 FilterOperations());
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(
814 &pass_list,
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>();
857 white->SetNew(
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,
869 pass_rect,
870 pass_rect,
871 child_pass_id,
873 gfx::RectF(),
874 filters,
875 gfx::Vector2dF(),
876 FilterOperations());
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(
883 &pass_list,
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>();
926 white->SetNew(
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,
939 pass_rect,
940 pass_rect,
941 child_pass_id,
943 gfx::RectF(),
944 filters,
945 gfx::Vector2dF(),
946 FilterOperations());
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(
953 &pass_list,
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>();
996 white->SetNew(
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]);
1007 matrix[3] = 0;
1008 matrix[4] = 20.f;
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]);
1012 matrix[8] = 0;
1013 matrix[9] = 200.f;
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]);
1017 matrix[13] = 0;
1018 matrix[14] = 1.5f;
1019 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1020 matrix[18] = 1;
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,
1031 pass_rect,
1032 pass_rect,
1033 child_pass_id,
1035 gfx::RectF(),
1036 filters,
1037 gfx::Vector2dF(),
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(
1048 &pass_list,
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(
1097 &pass_list,
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_),
1149 SK_ColorWHITE,
1150 false);
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(
1159 &pass_list,
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>();
1186 green->SetNew(
1187 child_pass_shared_state, viewport_rect, viewport_rect, kCSSGreen, false);
1189 // Make a mask.
1190 gfx::Rect mask_rect = viewport_rect;
1191 SkBitmap bitmap;
1192 bitmap.allocPixels(
1193 SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height()));
1194 SkCanvas canvas(bitmap);
1195 SkPaint paint;
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);
1203 canvas.drawRect(
1204 SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()),
1205 paint);
1206 rect.Inset(6, 6, 4, 4);
1209 ResourceProvider::ResourceId mask_resource_id =
1210 this->resource_provider_->CreateResource(
1211 mask_rect.size(),
1212 GL_CLAMP_TO_EDGE,
1213 ResourceProvider::TextureHintImmutable,
1214 RGBA_8888);
1216 SkAutoLockPixels lock(bitmap);
1217 this->resource_provider_->SetPixels(
1218 mask_resource_id,
1219 reinterpret_cast<uint8_t*>(bitmap.getPixels()),
1220 mask_rect,
1221 mask_rect,
1222 gfx::Vector2d());
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,
1238 sub_rect,
1239 sub_rect,
1240 child_pass_id,
1241 mask_resource_id,
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,
1251 viewport_rect,
1252 viewport_rect,
1253 SK_ColorWHITE,
1254 false);
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(
1261 &pass_list,
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> {
1269 protected:
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_,
1285 transform_to_root);
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_,
1292 filter_pass.get());
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,
1299 false);
1303 SharedQuadState* shared_state =
1304 CreateTestSharedQuadState(filter_pass_to_target_transform_,
1305 filter_pass_content_rect_,
1306 filter_pass.get());
1307 RenderPassDrawQuad* filter_pass_quad =
1308 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1309 filter_pass_quad->SetNew(
1310 shared_state,
1311 filter_pass_content_rect_,
1312 filter_pass_content_rect_,
1313 filter_pass_id,
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>();
1329 color_quad->SetNew(
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>();
1340 color_quad->SetNew(
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>();
1351 color_quad->SetNew(
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,
1359 root_pass.get());
1360 SolidColorDrawQuad* background_quad =
1361 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1362 background_quad->SetNew(shared_state,
1363 device_viewport_rect,
1364 device_viewport_rect,
1365 SK_ColorWHITE,
1366 false);
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(
1396 &this->pass_list_,
1397 base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
1398 ExactPixelComparator(true)));
1401 class ExternalStencilPixelTest : public GLRendererPixelTest {
1402 protected:
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);
1420 gl->Scissor(0,
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(
1453 &pass_list,
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(
1475 &pass_list,
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(
1520 &pass_list,
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(
1544 &pass_list,
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(
1585 &pass_list,
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(
1633 &pass_list,
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>();
1658 hole->SetAll(
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(
1673 &pass_list,
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>();
1700 green->SetNew(
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(
1713 &pass_list,
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());
1735 SkPaint red_paint;
1736 red_paint.setColor(SK_ColorRED);
1737 blue_pile->add_draw_rect_with_paint(blue_rect, red_paint);
1738 SkPaint blue_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,
1750 blue_rect,
1751 gfx::ToEnclosingRect(blue_scissor_rect),
1752 pass.get());
1754 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
1756 blue_quad->SetNew(blue_shared_state,
1757 viewport, // Intentionally bigger than clip.
1758 gfx::Rect(),
1759 viewport,
1760 gfx::RectF(viewport),
1761 viewport.size(),
1762 texture_format,
1763 viewport,
1764 1.f,
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,
1782 viewport,
1783 gfx::Rect(),
1784 viewport,
1785 gfx::RectF(0.f, 0.f, 1.f, 1.f),
1786 viewport.size(),
1787 texture_format,
1788 viewport,
1789 1.f,
1790 PicturePileImpl::CreateFromOther(green_pile.get()));
1792 RenderPassList pass_list;
1793 pass_list.push_back(pass.Pass());
1795 EXPECT_TRUE(this->RunPixelTest(
1796 &pass_list,
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,
1828 viewport,
1829 gfx::Rect(),
1830 viewport,
1831 gfx::RectF(0, 0, 1, 1),
1832 viewport.size(),
1833 texture_format,
1834 viewport,
1835 1.f,
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,
1853 viewport,
1854 gfx::Rect(),
1855 viewport,
1856 gfx::RectF(0, 0, 1, 1),
1857 viewport.size(),
1858 texture_format,
1859 viewport,
1860 1.f,
1861 PicturePileImpl::CreateFromOther(white_pile.get()));
1863 RenderPassList pass_list;
1864 pass_list.push_back(pass.Pass());
1866 EXPECT_TRUE(this->RunPixelTest(
1867 &pass_list,
1868 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
1869 FuzzyPixelOffByOneComparator(true)));
1872 template<typename TypeParam> bool IsSoftwareRenderer() {
1873 return false;
1876 template<>
1877 bool IsSoftwareRenderer<SoftwareRenderer>() {
1878 return true;
1881 template<>
1882 bool IsSoftwareRenderer<SoftwareRendererWithExpandedViewport>() {
1883 return true;
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>())
1892 return;
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);
1903 SkBitmap bitmap;
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());
1916 SkPaint paint;
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,
1927 viewport,
1928 gfx::Rect(),
1929 viewport,
1930 gfx::RectF(0, 0, 2, 2),
1931 viewport.size(),
1932 texture_format,
1933 viewport,
1934 1.f,
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(
1943 &pass_list,
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
1962 // of the layer.
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());
1968 SkPaint red_paint;
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,
1984 green_rect1,
1985 gfx::Rect(),
1986 green_rect1,
1987 gfx::RectF(green_rect1.size()),
1988 green_rect1.size(),
1989 texture_format,
1990 green_rect1,
1991 1.f,
1992 PicturePileImpl::CreateFromOther(green_pile.get()));
1994 PictureDrawQuad* green_quad2 =
1995 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
1996 green_quad2->SetNew(top_right_green_shared_quad_state,
1997 green_rect2,
1998 gfx::Rect(),
1999 green_rect2,
2000 gfx::RectF(green_rect2.size()),
2001 green_rect2.size(),
2002 texture_format,
2003 green_rect2,
2004 1.f,
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,
2014 viewport,
2015 bottom_right_rect,
2016 pass.get());
2017 SolidColorDrawQuad* bottom_right_color_quad =
2018 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2019 bottom_right_color_quad->SetNew(bottom_right_green_shared_state,
2020 viewport,
2021 viewport,
2022 SK_ColorGREEN,
2023 false);
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);
2051 SkPaint blue_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,
2072 quad_content_rect,
2073 gfx::Rect(),
2074 quad_content_rect,
2075 gfx::RectF(quad_content_rect),
2076 content_union_rect.size(),
2077 texture_format,
2078 content_union_rect,
2079 contents_scale,
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,
2090 half_green_rect,
2091 half_green_rect,
2092 SK_ColorGREEN,
2093 false);
2095 RenderPassList pass_list;
2096 pass_list.push_back(pass.Pass());
2098 EXPECT_TRUE(this->RunPixelTest(
2099 &pass_list,
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());
2117 SkPaint blue_paint;
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,
2128 viewport,
2129 gfx::Rect(),
2130 viewport,
2131 gfx::RectF(0.f, 0.f, 1.f, 1.f),
2132 viewport.size(),
2133 texture_format,
2134 viewport,
2135 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(),
2171 GL_REPEAT,
2172 ResourceProvider::TextureHintImmutable,
2173 RGBA_8888);
2174 this->resource_provider_->SetPixels(
2175 resource,
2176 reinterpret_cast<uint8_t*>(pixels),
2177 texture_rect,
2178 texture_rect,
2179 gfx::Vector2d());
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(
2185 shared_state,
2186 gfx::Rect(this->device_viewport_size_),
2187 gfx::Rect(),
2188 gfx::Rect(this->device_viewport_size_),
2189 resource,
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()),
2195 SK_ColorWHITE,
2196 vertex_opacity,
2197 false); // flipped
2199 RenderPassList pass_list;
2200 pass_list.push_back(pass.Pass());
2202 EXPECT_TRUE(this->RunPixelTest(
2203 &pass_list,
2204 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
2205 FuzzyPixelOffByOneComparator(true)));
2208 #endif // !defined(OS_ANDROID)
2210 } // namespace
2211 } // namespace cc