Task Manager: Remove goat teleporter.
[chromium-blink-merge.git] / cc / output / renderer_pixeltest.cc
blobf53d66421359a2523a4a515a39f93acc396296f6
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 // All pixels can be off by one, but any more than that is an error.
165 class FuzzyPixelOffByOneComparator : public FuzzyPixelComparator {
166 public:
167 explicit FuzzyPixelOffByOneComparator(bool discard_alpha)
168 : FuzzyPixelComparator(discard_alpha, 100.f, 0.f, 1.f, 1, 0) {}
171 template <typename RendererType>
172 class FuzzyForSoftwareOnlyPixelComparator : public PixelComparator {
173 public:
174 explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha)
175 : fuzzy_(discard_alpha), exact_(discard_alpha) {}
177 virtual bool Compare(const SkBitmap& actual_bmp,
178 const SkBitmap& expected_bmp) const;
180 private:
181 FuzzyPixelOffByOneComparator fuzzy_;
182 ExactPixelComparator exact_;
185 template<>
186 bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare(
187 const SkBitmap& actual_bmp,
188 const SkBitmap& expected_bmp) const {
189 return fuzzy_.Compare(actual_bmp, expected_bmp);
192 template <>
193 bool FuzzyForSoftwareOnlyPixelComparator<
194 SoftwareRendererWithExpandedViewport>::Compare(
195 const SkBitmap& actual_bmp,
196 const SkBitmap& expected_bmp) const {
197 return fuzzy_.Compare(actual_bmp, expected_bmp);
200 template<typename RendererType>
201 bool FuzzyForSoftwareOnlyPixelComparator<RendererType>::Compare(
202 const SkBitmap& actual_bmp,
203 const SkBitmap& expected_bmp) const {
204 return exact_.Compare(actual_bmp, expected_bmp);
207 TYPED_TEST(RendererPixelTest, SimpleGreenRect) {
208 gfx::Rect rect(this->device_viewport_size_);
210 RenderPassId id(1, 1);
211 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
213 SharedQuadState* shared_state =
214 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
216 SolidColorDrawQuad* color_quad =
217 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
218 color_quad->SetNew(shared_state, rect, rect, SK_ColorGREEN, false);
220 RenderPassList pass_list;
221 pass_list.push_back(pass.Pass());
223 EXPECT_TRUE(this->RunPixelTest(
224 &pass_list,
225 base::FilePath(FILE_PATH_LITERAL("green.png")),
226 ExactPixelComparator(true)));
229 TYPED_TEST(RendererPixelTest, SimpleGreenRect_NonRootRenderPass) {
230 gfx::Rect rect(this->device_viewport_size_);
231 gfx::Rect small_rect(100, 100);
233 RenderPassId child_id(2, 1);
234 scoped_ptr<RenderPass> child_pass =
235 CreateTestRenderPass(child_id, small_rect, gfx::Transform());
237 SharedQuadState* child_shared_state =
238 CreateTestSharedQuadState(gfx::Transform(), small_rect, child_pass.get());
240 SolidColorDrawQuad* color_quad =
241 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
242 color_quad->SetNew(child_shared_state, rect, rect, SK_ColorGREEN, false);
244 RenderPassId root_id(1, 1);
245 scoped_ptr<RenderPass> root_pass =
246 CreateTestRenderPass(root_id, rect, gfx::Transform());
248 SharedQuadState* root_shared_state =
249 CreateTestSharedQuadState(gfx::Transform(), rect, root_pass.get());
251 CreateTestRenderPassDrawQuad(
252 root_shared_state, small_rect, child_id, root_pass.get());
254 RenderPass* child_pass_ptr = child_pass.get();
256 RenderPassList pass_list;
257 pass_list.push_back(child_pass.Pass());
258 pass_list.push_back(root_pass.Pass());
260 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
261 &pass_list,
262 child_pass_ptr,
263 base::FilePath(FILE_PATH_LITERAL("green_small.png")),
264 ExactPixelComparator(true)));
267 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithoutBackground) {
268 gfx::Rect rect(this->device_viewport_size_);
270 RenderPassId id(1, 1);
271 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
273 SharedQuadState* shared_state =
274 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
276 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
277 SkColorSetARGB(128, 0, 255, 0), // Texel color.
278 SK_ColorTRANSPARENT, // Background color.
279 true, // Premultiplied alpha.
280 shared_state,
281 this->resource_provider_.get(),
282 pass.get());
284 SolidColorDrawQuad* color_quad =
285 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
286 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
288 RenderPassList pass_list;
289 pass_list.push_back(pass.Pass());
291 EXPECT_TRUE(this->RunPixelTest(
292 &pass_list,
293 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
294 FuzzyPixelOffByOneComparator(true)));
297 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithBackground) {
298 gfx::Rect rect(this->device_viewport_size_);
300 RenderPassId id(1, 1);
301 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
303 SharedQuadState* texture_quad_state =
304 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
305 texture_quad_state->opacity = 0.8f;
307 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
308 SkColorSetARGB(204, 120, 255, 120), // Texel color.
309 SK_ColorGREEN, // Background color.
310 true, // Premultiplied alpha.
311 texture_quad_state,
312 this->resource_provider_.get(),
313 pass.get());
315 SharedQuadState* color_quad_state =
316 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
317 SolidColorDrawQuad* color_quad =
318 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
319 color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
321 RenderPassList pass_list;
322 pass_list.push_back(pass.Pass());
324 EXPECT_TRUE(this->RunPixelTest(
325 &pass_list,
326 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
327 FuzzyPixelOffByOneComparator(true)));
330 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
331 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) {
332 gfx::Rect rect(this->device_viewport_size_);
334 RenderPassId id(1, 1);
335 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
337 SharedQuadState* shared_state =
338 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
340 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
341 SkColorSetARGB(128, 0, 255, 0), // Texel color.
342 SK_ColorTRANSPARENT, // Background color.
343 false, // Premultiplied alpha.
344 shared_state,
345 this->resource_provider_.get(),
346 pass.get());
348 SolidColorDrawQuad* color_quad =
349 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
350 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
352 RenderPassList pass_list;
353 pass_list.push_back(pass.Pass());
355 EXPECT_TRUE(this->RunPixelTest(
356 &pass_list,
357 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
358 FuzzyPixelOffByOneComparator(true)));
361 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
362 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
363 gfx::Rect rect(this->device_viewport_size_);
365 RenderPassId id(1, 1);
366 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
368 SharedQuadState* texture_quad_state =
369 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
370 texture_quad_state->opacity = 0.8f;
372 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
373 SkColorSetARGB(204, 120, 255, 120), // Texel color.
374 SK_ColorGREEN, // Background color.
375 false, // Premultiplied alpha.
376 texture_quad_state,
377 this->resource_provider_.get(),
378 pass.get());
380 SharedQuadState* color_quad_state =
381 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
382 SolidColorDrawQuad* color_quad =
383 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
384 color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
386 RenderPassList pass_list;
387 pass_list.push_back(pass.Pass());
389 EXPECT_TRUE(this->RunPixelTest(
390 &pass_list,
391 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
392 FuzzyPixelOffByOneComparator(true)));
395 class VideoGLRendererPixelTest : public GLRendererPixelTest {
396 protected:
397 void CreateTestYUVVideoDrawQuad_Striped(const SharedQuadState* shared_state,
398 media::VideoFrame::Format format,
399 bool is_transparent,
400 const gfx::RectF& tex_coord_rect,
401 RenderPass* render_pass) {
402 const gfx::Rect rect(this->device_viewport_size_);
404 scoped_refptr<media::VideoFrame> video_frame =
405 media::VideoFrame::CreateFrame(
406 format, rect.size(), rect, rect.size(), base::TimeDelta());
408 // YUV values representing a striped pattern, for validating texture
409 // coordinates for sampling.
410 uint8_t y_value = 0;
411 uint8_t u_value = 0;
412 uint8_t v_value = 0;
413 for (int i = 0; i < video_frame->rows(media::VideoFrame::kYPlane); ++i) {
414 uint8_t* y_row = video_frame->data(media::VideoFrame::kYPlane) +
415 video_frame->stride(media::VideoFrame::kYPlane) * i;
416 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kYPlane);
417 ++j) {
418 y_row[j] = (y_value += 1);
421 for (int i = 0; i < video_frame->rows(media::VideoFrame::kUPlane); ++i) {
422 uint8_t* u_row = video_frame->data(media::VideoFrame::kUPlane) +
423 video_frame->stride(media::VideoFrame::kUPlane) * i;
424 uint8_t* v_row = video_frame->data(media::VideoFrame::kVPlane) +
425 video_frame->stride(media::VideoFrame::kVPlane) * i;
426 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kUPlane);
427 ++j) {
428 u_row[j] = (u_value += 3);
429 v_row[j] = (v_value += 5);
432 CreateTestYUVVideoDrawQuad_FromVideoFrame(
433 shared_state, video_frame, is_transparent, tex_coord_rect, render_pass);
436 void CreateTestYUVVideoDrawQuad_Solid(const SharedQuadState* shared_state,
437 media::VideoFrame::Format format,
438 bool is_transparent,
439 const gfx::RectF& tex_coord_rect,
440 uint8 y,
441 uint8 u,
442 uint8 v,
443 RenderPass* render_pass) {
444 const gfx::Rect rect(this->device_viewport_size_);
446 scoped_refptr<media::VideoFrame> video_frame =
447 media::VideoFrame::CreateFrame(
448 format, rect.size(), rect, rect.size(), base::TimeDelta());
450 // YUV values of a solid, constant, color. Useful for testing that color
451 // space/color range are being handled properly.
452 memset(video_frame->data(media::VideoFrame::kYPlane),
454 video_frame->stride(media::VideoFrame::kYPlane) *
455 video_frame->rows(media::VideoFrame::kYPlane));
456 memset(video_frame->data(media::VideoFrame::kUPlane),
458 video_frame->stride(media::VideoFrame::kUPlane) *
459 video_frame->rows(media::VideoFrame::kUPlane));
460 memset(video_frame->data(media::VideoFrame::kVPlane),
462 video_frame->stride(media::VideoFrame::kVPlane) *
463 video_frame->rows(media::VideoFrame::kVPlane));
465 CreateTestYUVVideoDrawQuad_FromVideoFrame(
466 shared_state, video_frame, is_transparent, tex_coord_rect, render_pass);
469 void CreateTestYUVVideoDrawQuad_FromVideoFrame(
470 const SharedQuadState* shared_state,
471 scoped_refptr<media::VideoFrame> video_frame,
472 bool is_transparent,
473 const gfx::RectF& tex_coord_rect,
474 RenderPass* render_pass) {
475 const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A);
476 const YUVVideoDrawQuad::ColorSpace color_space =
477 (video_frame->format() == media::VideoFrame::YV12J
478 ? YUVVideoDrawQuad::REC_601_JPEG
479 : YUVVideoDrawQuad::REC_601);
480 const gfx::Rect rect(this->device_viewport_size_);
481 const gfx::Rect opaque_rect(0, 0, 0, 0);
483 if (with_alpha)
484 memset(video_frame->data(media::VideoFrame::kAPlane),
485 is_transparent ? 0 : 128,
486 video_frame->stride(media::VideoFrame::kAPlane) *
487 video_frame->rows(media::VideoFrame::kAPlane));
489 VideoFrameExternalResources resources =
490 video_resource_updater_->CreateExternalResourcesFromVideoFrame(
491 video_frame);
493 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
494 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
495 resources.mailboxes.size());
496 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
497 resources.release_callbacks.size());
499 ResourceProvider::ResourceId y_resource =
500 resource_provider_->CreateResourceFromTextureMailbox(
501 resources.mailboxes[media::VideoFrame::kYPlane],
502 SingleReleaseCallbackImpl::Create(
503 resources.release_callbacks[media::VideoFrame::kYPlane]));
504 ResourceProvider::ResourceId u_resource =
505 resource_provider_->CreateResourceFromTextureMailbox(
506 resources.mailboxes[media::VideoFrame::kUPlane],
507 SingleReleaseCallbackImpl::Create(
508 resources.release_callbacks[media::VideoFrame::kUPlane]));
509 ResourceProvider::ResourceId v_resource =
510 resource_provider_->CreateResourceFromTextureMailbox(
511 resources.mailboxes[media::VideoFrame::kVPlane],
512 SingleReleaseCallbackImpl::Create(
513 resources.release_callbacks[media::VideoFrame::kVPlane]));
514 ResourceProvider::ResourceId a_resource = 0;
515 if (with_alpha) {
516 a_resource = resource_provider_->CreateResourceFromTextureMailbox(
517 resources.mailboxes[media::VideoFrame::kAPlane],
518 SingleReleaseCallbackImpl::Create(
519 resources.release_callbacks[media::VideoFrame::kAPlane]));
522 YUVVideoDrawQuad* yuv_quad =
523 render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
524 yuv_quad->SetNew(shared_state,
525 rect,
526 opaque_rect,
527 rect,
528 tex_coord_rect,
529 y_resource,
530 u_resource,
531 v_resource,
532 a_resource,
533 color_space);
536 virtual void SetUp() OVERRIDE {
537 GLRendererPixelTest::SetUp();
538 video_resource_updater_.reset(new VideoResourceUpdater(
539 output_surface_->context_provider(), resource_provider_.get()));
542 private:
543 scoped_ptr<VideoResourceUpdater> video_resource_updater_;
546 TEST_F(VideoGLRendererPixelTest, SimpleYUVRect) {
547 gfx::Rect rect(this->device_viewport_size_);
549 RenderPassId id(1, 1);
550 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
552 SharedQuadState* shared_state =
553 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
555 CreateTestYUVVideoDrawQuad_Striped(shared_state,
556 media::VideoFrame::YV12,
557 false,
558 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
559 pass.get());
561 RenderPassList pass_list;
562 pass_list.push_back(pass.Pass());
564 EXPECT_TRUE(
565 this->RunPixelTest(&pass_list,
566 base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
567 FuzzyPixelOffByOneComparator(true)));
570 TEST_F(VideoGLRendererPixelTest, OffsetYUVRect) {
571 gfx::Rect rect(this->device_viewport_size_);
573 RenderPassId id(1, 1);
574 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
576 SharedQuadState* shared_state =
577 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
579 // Intentionally sets frame format to I420 for testing coverage.
580 CreateTestYUVVideoDrawQuad_Striped(shared_state,
581 media::VideoFrame::I420,
582 false,
583 gfx::RectF(0.125f, 0.25f, 0.75f, 0.5f),
584 pass.get());
586 RenderPassList pass_list;
587 pass_list.push_back(pass.Pass());
589 EXPECT_TRUE(this->RunPixelTest(
590 &pass_list,
591 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_offset.png")),
592 FuzzyPixelOffByOneComparator(true)));
595 TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) {
596 gfx::Rect rect(this->device_viewport_size_);
598 RenderPassId id(1, 1);
599 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
601 SharedQuadState* shared_state =
602 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
604 // In MPEG color range YUV values of (15,128,128) should produce black.
605 CreateTestYUVVideoDrawQuad_Solid(shared_state,
606 media::VideoFrame::YV12,
607 false,
608 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
610 128,
611 128,
612 pass.get());
614 RenderPassList pass_list;
615 pass_list.push_back(pass.Pass());
617 // If we didn't get black out of the YUV values above, then we probably have a
618 // color range issue.
619 EXPECT_TRUE(this->RunPixelTest(&pass_list,
620 base::FilePath(FILE_PATH_LITERAL("black.png")),
621 FuzzyPixelOffByOneComparator(true)));
624 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
625 gfx::Rect rect(this->device_viewport_size_);
627 RenderPassId id(1, 1);
628 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
630 SharedQuadState* shared_state =
631 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
633 // YUV of (149,43,21) should be green (0,255,0) in RGB.
634 CreateTestYUVVideoDrawQuad_Solid(shared_state,
635 media::VideoFrame::YV12J,
636 false,
637 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
638 149,
641 pass.get());
643 RenderPassList pass_list;
644 pass_list.push_back(pass.Pass());
646 EXPECT_TRUE(this->RunPixelTest(&pass_list,
647 base::FilePath(FILE_PATH_LITERAL("green.png")),
648 FuzzyPixelOffByOneComparator(true)));
651 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
652 gfx::Rect rect(this->device_viewport_size_);
654 RenderPassId id(1, 1);
655 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
657 SharedQuadState* shared_state =
658 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
660 // Dark grey in JPEG color range (in MPEG, this is black).
661 CreateTestYUVVideoDrawQuad_Solid(shared_state,
662 media::VideoFrame::YV12J,
663 false,
664 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
666 128,
667 128,
668 pass.get());
670 RenderPassList pass_list;
671 pass_list.push_back(pass.Pass());
673 EXPECT_TRUE(
674 this->RunPixelTest(&pass_list,
675 base::FilePath(FILE_PATH_LITERAL("dark_grey.png")),
676 FuzzyPixelOffByOneComparator(true)));
679 TEST_F(VideoGLRendererPixelTest, SimpleYUVARect) {
680 gfx::Rect rect(this->device_viewport_size_);
682 RenderPassId id(1, 1);
683 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
685 SharedQuadState* shared_state =
686 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
688 CreateTestYUVVideoDrawQuad_Striped(shared_state,
689 media::VideoFrame::YV12A,
690 false,
691 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
692 pass.get());
694 SolidColorDrawQuad* color_quad =
695 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
696 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
698 RenderPassList pass_list;
699 pass_list.push_back(pass.Pass());
701 EXPECT_TRUE(this->RunPixelTest(
702 &pass_list,
703 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_alpha.png")),
704 FuzzyPixelOffByOneComparator(true)));
707 TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) {
708 gfx::Rect rect(this->device_viewport_size_);
710 RenderPassId id(1, 1);
711 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
713 SharedQuadState* shared_state =
714 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
716 CreateTestYUVVideoDrawQuad_Striped(shared_state,
717 media::VideoFrame::YV12A,
718 true,
719 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
720 pass.get());
722 SolidColorDrawQuad* color_quad =
723 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
724 color_quad->SetNew(shared_state, rect, rect, SK_ColorBLACK, false);
726 RenderPassList pass_list;
727 pass_list.push_back(pass.Pass());
729 EXPECT_TRUE(this->RunPixelTest(
730 &pass_list,
731 base::FilePath(FILE_PATH_LITERAL("black.png")),
732 ExactPixelComparator(true)));
735 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) {
736 gfx::Rect viewport_rect(this->device_viewport_size_);
738 RenderPassId root_pass_id(1, 1);
739 scoped_ptr<RenderPass> root_pass =
740 CreateTestRootRenderPass(root_pass_id, viewport_rect);
742 RenderPassId child_pass_id(2, 2);
743 gfx::Rect pass_rect(this->device_viewport_size_);
744 gfx::Transform transform_to_root;
745 scoped_ptr<RenderPass> child_pass =
746 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
748 gfx::Transform content_to_target_transform;
749 SharedQuadState* shared_state = CreateTestSharedQuadState(
750 content_to_target_transform, viewport_rect, child_pass.get());
751 shared_state->opacity = 0.5f;
753 gfx::Rect blue_rect(0,
755 this->device_viewport_size_.width(),
756 this->device_viewport_size_.height() / 2);
757 SolidColorDrawQuad* blue =
758 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
759 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
760 gfx::Rect yellow_rect(0,
761 this->device_viewport_size_.height() / 2,
762 this->device_viewport_size_.width(),
763 this->device_viewport_size_.height() / 2);
764 SolidColorDrawQuad* yellow =
765 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
766 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
768 SharedQuadState* blank_state = CreateTestSharedQuadState(
769 content_to_target_transform, viewport_rect, child_pass.get());
771 SolidColorDrawQuad* white =
772 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
773 white->SetNew(
774 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
776 SharedQuadState* pass_shared_state =
777 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
779 SkScalar matrix[20];
780 float amount = 0.5f;
781 matrix[0] = 0.213f + 0.787f * amount;
782 matrix[1] = 0.715f - 0.715f * amount;
783 matrix[2] = 1.f - (matrix[0] + matrix[1]);
784 matrix[3] = matrix[4] = 0;
785 matrix[5] = 0.213f - 0.213f * amount;
786 matrix[6] = 0.715f + 0.285f * amount;
787 matrix[7] = 1.f - (matrix[5] + matrix[6]);
788 matrix[8] = matrix[9] = 0;
789 matrix[10] = 0.213f - 0.213f * amount;
790 matrix[11] = 0.715f - 0.715f * amount;
791 matrix[12] = 1.f - (matrix[10] + matrix[11]);
792 matrix[13] = matrix[14] = 0;
793 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
794 matrix[18] = 1;
795 skia::RefPtr<SkColorFilter> colorFilter(
796 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
797 skia::RefPtr<SkImageFilter> filter =
798 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
799 FilterOperations filters;
800 filters.Append(FilterOperation::CreateReferenceFilter(filter));
802 RenderPassDrawQuad* render_pass_quad =
803 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
804 render_pass_quad->SetNew(pass_shared_state,
805 pass_rect,
806 pass_rect,
807 child_pass_id,
809 gfx::RectF(),
810 filters,
811 gfx::Vector2dF(),
812 FilterOperations());
814 RenderPassList pass_list;
815 pass_list.push_back(child_pass.Pass());
816 pass_list.push_back(root_pass.Pass());
818 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
819 // renderer so use a fuzzy comparator.
820 EXPECT_TRUE(this->RunPixelTest(
821 &pass_list,
822 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
823 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
826 TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) {
827 gfx::Rect viewport_rect(this->device_viewport_size_);
829 RenderPassId root_pass_id(1, 1);
830 scoped_ptr<RenderPass> root_pass =
831 CreateTestRootRenderPass(root_pass_id, viewport_rect);
833 RenderPassId child_pass_id(2, 2);
834 gfx::Rect pass_rect(this->device_viewport_size_);
835 gfx::Transform transform_to_root;
836 scoped_ptr<RenderPass> child_pass =
837 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
839 gfx::Transform content_to_target_transform;
840 SharedQuadState* shared_state = CreateTestSharedQuadState(
841 content_to_target_transform, viewport_rect, child_pass.get());
842 shared_state->opacity = 0.5f;
844 gfx::Rect blue_rect(0,
846 this->device_viewport_size_.width(),
847 this->device_viewport_size_.height() / 2);
848 SolidColorDrawQuad* blue =
849 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
850 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
851 gfx::Rect yellow_rect(0,
852 this->device_viewport_size_.height() / 2,
853 this->device_viewport_size_.width(),
854 this->device_viewport_size_.height() / 2);
855 SolidColorDrawQuad* yellow =
856 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
857 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
859 SharedQuadState* blank_state = CreateTestSharedQuadState(
860 content_to_target_transform, viewport_rect, child_pass.get());
862 SolidColorDrawQuad* white =
863 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
864 white->SetNew(
865 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
867 SharedQuadState* pass_shared_state =
868 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
870 FilterOperations filters;
871 filters.Append(FilterOperation::CreateSaturateFilter(0.5f));
873 RenderPassDrawQuad* render_pass_quad =
874 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
875 render_pass_quad->SetNew(pass_shared_state,
876 pass_rect,
877 pass_rect,
878 child_pass_id,
880 gfx::RectF(),
881 filters,
882 gfx::Vector2dF(),
883 FilterOperations());
885 RenderPassList pass_list;
886 pass_list.push_back(child_pass.Pass());
887 pass_list.push_back(root_pass.Pass());
889 EXPECT_TRUE(this->RunPixelTest(
890 &pass_list,
891 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
892 ExactPixelComparator(true)));
895 TYPED_TEST(RendererPixelTest, FastPassFilterChain) {
896 gfx::Rect viewport_rect(this->device_viewport_size_);
898 RenderPassId root_pass_id(1, 1);
899 scoped_ptr<RenderPass> root_pass =
900 CreateTestRootRenderPass(root_pass_id, viewport_rect);
902 RenderPassId child_pass_id(2, 2);
903 gfx::Rect pass_rect(this->device_viewport_size_);
904 gfx::Transform transform_to_root;
905 scoped_ptr<RenderPass> child_pass =
906 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
908 gfx::Transform content_to_target_transform;
909 SharedQuadState* shared_state = CreateTestSharedQuadState(
910 content_to_target_transform, viewport_rect, child_pass.get());
911 shared_state->opacity = 0.5f;
913 gfx::Rect blue_rect(0,
915 this->device_viewport_size_.width(),
916 this->device_viewport_size_.height() / 2);
917 SolidColorDrawQuad* blue =
918 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
919 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
920 gfx::Rect yellow_rect(0,
921 this->device_viewport_size_.height() / 2,
922 this->device_viewport_size_.width(),
923 this->device_viewport_size_.height() / 2);
924 SolidColorDrawQuad* yellow =
925 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
926 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
928 SharedQuadState* blank_state = CreateTestSharedQuadState(
929 content_to_target_transform, viewport_rect, child_pass.get());
931 SolidColorDrawQuad* white =
932 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
933 white->SetNew(
934 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
936 SharedQuadState* pass_shared_state =
937 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
939 FilterOperations filters;
940 filters.Append(FilterOperation::CreateGrayscaleFilter(1.f));
941 filters.Append(FilterOperation::CreateBrightnessFilter(0.5f));
943 RenderPassDrawQuad* render_pass_quad =
944 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
945 render_pass_quad->SetNew(pass_shared_state,
946 pass_rect,
947 pass_rect,
948 child_pass_id,
950 gfx::RectF(),
951 filters,
952 gfx::Vector2dF(),
953 FilterOperations());
955 RenderPassList pass_list;
956 pass_list.push_back(child_pass.Pass());
957 pass_list.push_back(root_pass.Pass());
959 EXPECT_TRUE(this->RunPixelTest(
960 &pass_list,
961 base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")),
962 ExactPixelComparator(true)));
965 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) {
966 gfx::Rect viewport_rect(this->device_viewport_size_);
968 RenderPassId root_pass_id(1, 1);
969 scoped_ptr<RenderPass> root_pass =
970 CreateTestRootRenderPass(root_pass_id, viewport_rect);
972 RenderPassId child_pass_id(2, 2);
973 gfx::Rect pass_rect(this->device_viewport_size_);
974 gfx::Transform transform_to_root;
975 scoped_ptr<RenderPass> child_pass =
976 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
978 gfx::Transform content_to_target_transform;
979 SharedQuadState* shared_state = CreateTestSharedQuadState(
980 content_to_target_transform, viewport_rect, child_pass.get());
981 shared_state->opacity = 0.5f;
983 gfx::Rect blue_rect(0,
985 this->device_viewport_size_.width(),
986 this->device_viewport_size_.height() / 2);
987 SolidColorDrawQuad* blue =
988 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
989 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
990 gfx::Rect yellow_rect(0,
991 this->device_viewport_size_.height() / 2,
992 this->device_viewport_size_.width(),
993 this->device_viewport_size_.height() / 2);
994 SolidColorDrawQuad* yellow =
995 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
996 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
998 SharedQuadState* blank_state = CreateTestSharedQuadState(
999 content_to_target_transform, viewport_rect, child_pass.get());
1001 SolidColorDrawQuad* white =
1002 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1003 white->SetNew(
1004 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1006 SharedQuadState* pass_shared_state =
1007 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1009 SkScalar matrix[20];
1010 float amount = 0.5f;
1011 matrix[0] = 0.213f + 0.787f * amount;
1012 matrix[1] = 0.715f - 0.715f * amount;
1013 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1014 matrix[3] = 0;
1015 matrix[4] = 20.f;
1016 matrix[5] = 0.213f - 0.213f * amount;
1017 matrix[6] = 0.715f + 0.285f * amount;
1018 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1019 matrix[8] = 0;
1020 matrix[9] = 200.f;
1021 matrix[10] = 0.213f - 0.213f * amount;
1022 matrix[11] = 0.715f - 0.715f * amount;
1023 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1024 matrix[13] = 0;
1025 matrix[14] = 1.5f;
1026 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1027 matrix[18] = 1;
1028 skia::RefPtr<SkColorFilter> colorFilter(
1029 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1030 skia::RefPtr<SkImageFilter> filter =
1031 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
1032 FilterOperations filters;
1033 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1035 RenderPassDrawQuad* render_pass_quad =
1036 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1037 render_pass_quad->SetNew(pass_shared_state,
1038 pass_rect,
1039 pass_rect,
1040 child_pass_id,
1042 gfx::RectF(),
1043 filters,
1044 gfx::Vector2dF(),
1045 FilterOperations());
1047 RenderPassList pass_list;
1049 pass_list.push_back(child_pass.Pass());
1050 pass_list.push_back(root_pass.Pass());
1052 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1053 // renderer so use a fuzzy comparator.
1054 EXPECT_TRUE(this->RunPixelTest(
1055 &pass_list,
1056 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
1057 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1060 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) {
1061 gfx::Rect viewport_rect(this->device_viewport_size_);
1063 RenderPassId root_pass_id(1, 1);
1064 scoped_ptr<RenderPass> root_pass =
1065 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1067 RenderPassId child_pass_id(2, 2);
1068 gfx::Rect pass_rect(this->device_viewport_size_);
1069 gfx::Transform transform_to_root;
1070 scoped_ptr<RenderPass> child_pass =
1071 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1073 gfx::Transform content_to_target_transform;
1074 SharedQuadState* shared_state = CreateTestSharedQuadState(
1075 content_to_target_transform, viewport_rect, child_pass.get());
1077 gfx::Rect blue_rect(0,
1079 this->device_viewport_size_.width(),
1080 this->device_viewport_size_.height() / 2);
1081 SolidColorDrawQuad* blue =
1082 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1083 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1084 gfx::Rect yellow_rect(0,
1085 this->device_viewport_size_.height() / 2,
1086 this->device_viewport_size_.width(),
1087 this->device_viewport_size_.height() / 2);
1088 SolidColorDrawQuad* yellow =
1089 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1090 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1092 SharedQuadState* pass_shared_state =
1093 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1094 CreateTestRenderPassDrawQuad(
1095 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1097 RenderPassList pass_list;
1098 pass_list.push_back(child_pass.Pass());
1099 pass_list.push_back(root_pass.Pass());
1101 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1103 EXPECT_TRUE(this->RunPixelTest(
1104 &pass_list,
1105 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
1106 ExactPixelComparator(true)));
1109 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) {
1110 gfx::Rect viewport_rect(this->device_viewport_size_);
1112 RenderPassId root_pass_id(1, 1);
1113 scoped_ptr<RenderPass> root_pass =
1114 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1116 RenderPassId child_pass_id(2, 2);
1117 gfx::Rect pass_rect(this->device_viewport_size_);
1118 gfx::Transform transform_to_root;
1119 scoped_ptr<RenderPass> child_pass =
1120 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1122 gfx::Transform content_to_target_transform;
1123 SharedQuadState* shared_state = CreateTestSharedQuadState(
1124 content_to_target_transform, viewport_rect, child_pass.get());
1126 gfx::Rect blue_rect(0,
1128 this->device_viewport_size_.width(),
1129 this->device_viewport_size_.height() / 2);
1130 SolidColorDrawQuad* blue =
1131 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1132 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1133 gfx::Rect yellow_rect(0,
1134 this->device_viewport_size_.height() / 2,
1135 this->device_viewport_size_.width(),
1136 this->device_viewport_size_.height() / 2);
1137 SolidColorDrawQuad* yellow =
1138 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1139 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1141 gfx::Transform aa_transform;
1142 aa_transform.Translate(0.5, 0.0);
1144 SharedQuadState* pass_shared_state =
1145 CreateTestSharedQuadState(aa_transform, pass_rect, root_pass.get());
1146 CreateTestRenderPassDrawQuad(
1147 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1149 SharedQuadState* root_shared_state = CreateTestSharedQuadState(
1150 gfx::Transform(), viewport_rect, root_pass.get());
1151 SolidColorDrawQuad* background =
1152 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1153 background->SetNew(root_shared_state,
1154 gfx::Rect(this->device_viewport_size_),
1155 gfx::Rect(this->device_viewport_size_),
1156 SK_ColorWHITE,
1157 false);
1159 RenderPassList pass_list;
1160 pass_list.push_back(child_pass.Pass());
1161 pass_list.push_back(root_pass.Pass());
1163 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1165 EXPECT_TRUE(this->RunPixelTest(
1166 &pass_list,
1167 base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")),
1168 FuzzyPixelOffByOneComparator(true)));
1171 // This tests the case where we have a RenderPass with a mask, but the quad
1172 // for the masked surface does not include the full surface texture.
1173 TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) {
1174 gfx::Rect viewport_rect(this->device_viewport_size_);
1176 RenderPassId root_pass_id(1, 1);
1177 scoped_ptr<RenderPass> root_pass =
1178 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1179 SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState(
1180 gfx::Transform(), viewport_rect, root_pass.get());
1182 RenderPassId child_pass_id(2, 2);
1183 gfx::Transform transform_to_root;
1184 scoped_ptr<RenderPass> child_pass =
1185 CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root);
1186 SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState(
1187 gfx::Transform(), viewport_rect, child_pass.get());
1189 // The child render pass is just a green box.
1190 static const SkColor kCSSGreen = 0xff008000;
1191 SolidColorDrawQuad* green =
1192 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1193 green->SetNew(
1194 child_pass_shared_state, viewport_rect, viewport_rect, kCSSGreen, false);
1196 // Make a mask.
1197 gfx::Rect mask_rect = viewport_rect;
1198 SkBitmap bitmap;
1199 bitmap.allocPixels(
1200 SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height()));
1201 SkCanvas canvas(bitmap);
1202 SkPaint paint;
1203 paint.setStyle(SkPaint::kStroke_Style);
1204 paint.setStrokeWidth(SkIntToScalar(4));
1205 paint.setColor(SK_ColorWHITE);
1206 canvas.clear(SK_ColorTRANSPARENT);
1207 gfx::Rect rect = mask_rect;
1208 while (!rect.IsEmpty()) {
1209 rect.Inset(6, 6, 4, 4);
1210 canvas.drawRect(
1211 SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()),
1212 paint);
1213 rect.Inset(6, 6, 4, 4);
1216 ResourceProvider::ResourceId mask_resource_id =
1217 this->resource_provider_->CreateResource(
1218 mask_rect.size(),
1219 GL_CLAMP_TO_EDGE,
1220 ResourceProvider::TextureHintImmutable,
1221 RGBA_8888);
1223 SkAutoLockPixels lock(bitmap);
1224 this->resource_provider_->SetPixels(
1225 mask_resource_id,
1226 reinterpret_cast<uint8_t*>(bitmap.getPixels()),
1227 mask_rect,
1228 mask_rect,
1229 gfx::Vector2d());
1232 // This RenderPassDrawQuad does not include the full |viewport_rect| which is
1233 // the size of the child render pass.
1234 gfx::Rect sub_rect = gfx::Rect(50, 50, 100, 100);
1235 EXPECT_NE(sub_rect.x(), child_pass->output_rect.x());
1236 EXPECT_NE(sub_rect.y(), child_pass->output_rect.y());
1237 EXPECT_NE(sub_rect.right(), child_pass->output_rect.right());
1238 EXPECT_NE(sub_rect.bottom(), child_pass->output_rect.bottom());
1239 EXPECT_TRUE(child_pass->output_rect.Contains(sub_rect));
1241 // Set up a mask on the RenderPassDrawQuad.
1242 RenderPassDrawQuad* mask_quad =
1243 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1244 mask_quad->SetNew(root_pass_shared_state,
1245 sub_rect,
1246 sub_rect,
1247 child_pass_id,
1248 mask_resource_id,
1249 gfx::RectF(1.f, 1.f), // mask_uv_rect
1250 FilterOperations(), // foreground filters
1251 gfx::Vector2dF(), // filters scale
1252 FilterOperations()); // background filters
1254 // White background behind the masked render pass.
1255 SolidColorDrawQuad* white =
1256 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1257 white->SetNew(root_pass_shared_state,
1258 viewport_rect,
1259 viewport_rect,
1260 SK_ColorWHITE,
1261 false);
1263 RenderPassList pass_list;
1264 pass_list.push_back(child_pass.Pass());
1265 pass_list.push_back(root_pass.Pass());
1267 EXPECT_TRUE(this->RunPixelTest(
1268 &pass_list,
1269 base::FilePath(FILE_PATH_LITERAL("image_mask_of_layer.png")),
1270 ExactPixelComparator(true)));
1273 template <typename RendererType>
1274 class RendererPixelTestWithBackgroundFilter
1275 : public RendererPixelTest<RendererType> {
1276 protected:
1277 void SetUpRenderPassList() {
1278 gfx::Rect device_viewport_rect(this->device_viewport_size_);
1280 RenderPassId root_id(1, 1);
1281 scoped_ptr<RenderPass> root_pass =
1282 CreateTestRootRenderPass(root_id, device_viewport_rect);
1283 root_pass->has_transparent_background = false;
1285 gfx::Transform identity_content_to_target_transform;
1287 RenderPassId filter_pass_id(2, 1);
1288 gfx::Transform transform_to_root;
1289 scoped_ptr<RenderPass> filter_pass =
1290 CreateTestRenderPass(filter_pass_id,
1291 filter_pass_content_rect_,
1292 transform_to_root);
1294 // A non-visible quad in the filtering render pass.
1296 SharedQuadState* shared_state =
1297 CreateTestSharedQuadState(identity_content_to_target_transform,
1298 filter_pass_content_rect_,
1299 filter_pass.get());
1300 SolidColorDrawQuad* color_quad =
1301 filter_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1302 color_quad->SetNew(shared_state,
1303 filter_pass_content_rect_,
1304 filter_pass_content_rect_,
1305 SK_ColorTRANSPARENT,
1306 false);
1310 SharedQuadState* shared_state =
1311 CreateTestSharedQuadState(filter_pass_to_target_transform_,
1312 filter_pass_content_rect_,
1313 filter_pass.get());
1314 RenderPassDrawQuad* filter_pass_quad =
1315 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1316 filter_pass_quad->SetNew(
1317 shared_state,
1318 filter_pass_content_rect_,
1319 filter_pass_content_rect_,
1320 filter_pass_id,
1321 0, // mask_resource_id
1322 gfx::RectF(), // mask_uv_rect
1323 FilterOperations(), // filters
1324 gfx::Vector2dF(), // filters_scale
1325 this->background_filters_);
1328 const int kColumnWidth = device_viewport_rect.width() / 3;
1330 gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20);
1331 for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) {
1332 SharedQuadState* shared_state = CreateTestSharedQuadState(
1333 identity_content_to_target_transform, left_rect, root_pass.get());
1334 SolidColorDrawQuad* color_quad =
1335 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1336 color_quad->SetNew(
1337 shared_state, left_rect, left_rect, SK_ColorGREEN, false);
1338 left_rect += gfx::Vector2d(0, left_rect.height() + 1);
1341 gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20);
1342 for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) {
1343 SharedQuadState* shared_state = CreateTestSharedQuadState(
1344 identity_content_to_target_transform, middle_rect, root_pass.get());
1345 SolidColorDrawQuad* color_quad =
1346 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1347 color_quad->SetNew(
1348 shared_state, middle_rect, middle_rect, SK_ColorRED, false);
1349 middle_rect += gfx::Vector2d(0, middle_rect.height() + 1);
1352 gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20);
1353 for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) {
1354 SharedQuadState* shared_state = CreateTestSharedQuadState(
1355 identity_content_to_target_transform, right_rect, root_pass.get());
1356 SolidColorDrawQuad* color_quad =
1357 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1358 color_quad->SetNew(
1359 shared_state, right_rect, right_rect, SK_ColorBLUE, false);
1360 right_rect += gfx::Vector2d(0, right_rect.height() + 1);
1363 SharedQuadState* shared_state =
1364 CreateTestSharedQuadState(identity_content_to_target_transform,
1365 device_viewport_rect,
1366 root_pass.get());
1367 SolidColorDrawQuad* background_quad =
1368 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1369 background_quad->SetNew(shared_state,
1370 device_viewport_rect,
1371 device_viewport_rect,
1372 SK_ColorWHITE,
1373 false);
1375 pass_list_.push_back(filter_pass.Pass());
1376 pass_list_.push_back(root_pass.Pass());
1379 RenderPassList pass_list_;
1380 FilterOperations background_filters_;
1381 gfx::Transform filter_pass_to_target_transform_;
1382 gfx::Rect filter_pass_content_rect_;
1385 typedef ::testing::Types<GLRenderer, SoftwareRenderer>
1386 BackgroundFilterRendererTypes;
1387 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter,
1388 BackgroundFilterRendererTypes);
1390 typedef RendererPixelTestWithBackgroundFilter<GLRenderer>
1391 GLRendererPixelTestWithBackgroundFilter;
1393 // TODO(skaslev): The software renderer does not support filters yet.
1394 TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) {
1395 this->background_filters_.Append(
1396 FilterOperation::CreateInvertFilter(1.f));
1398 this->filter_pass_content_rect_ = gfx::Rect(this->device_viewport_size_);
1399 this->filter_pass_content_rect_.Inset(12, 14, 16, 18);
1401 this->SetUpRenderPassList();
1402 EXPECT_TRUE(this->RunPixelTest(
1403 &this->pass_list_,
1404 base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
1405 ExactPixelComparator(true)));
1408 class ExternalStencilPixelTest : public GLRendererPixelTest {
1409 protected:
1410 void ClearBackgroundToGreen() {
1411 GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
1412 output_surface_->EnsureBackbuffer();
1413 output_surface_->Reshape(device_viewport_size_, 1);
1414 gl->ClearColor(0.f, 1.f, 0.f, 1.f);
1415 gl->Clear(GL_COLOR_BUFFER_BIT);
1418 void PopulateStencilBuffer() {
1419 // Set two quadrants of the stencil buffer to 1.
1420 GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
1421 output_surface_->EnsureBackbuffer();
1422 output_surface_->Reshape(device_viewport_size_, 1);
1423 gl->ClearStencil(0);
1424 gl->Clear(GL_STENCIL_BUFFER_BIT);
1425 gl->Enable(GL_SCISSOR_TEST);
1426 gl->ClearStencil(1);
1427 gl->Scissor(0,
1429 device_viewport_size_.width() / 2,
1430 device_viewport_size_.height() / 2);
1431 gl->Clear(GL_STENCIL_BUFFER_BIT);
1432 gl->Scissor(device_viewport_size_.width() / 2,
1433 device_viewport_size_.height() / 2,
1434 device_viewport_size_.width(),
1435 device_viewport_size_.height());
1436 gl->Clear(GL_STENCIL_BUFFER_BIT);
1440 TEST_F(ExternalStencilPixelTest, StencilTestEnabled) {
1441 ClearBackgroundToGreen();
1442 PopulateStencilBuffer();
1443 this->EnableExternalStencilTest();
1445 // Draw a blue quad that covers the entire device viewport. It should be
1446 // clipped to the bottom left and top right corners by the external stencil.
1447 gfx::Rect rect(this->device_viewport_size_);
1448 RenderPassId id(1, 1);
1449 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1450 SharedQuadState* blue_shared_state =
1451 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1452 SolidColorDrawQuad* blue =
1453 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1454 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1455 pass->has_transparent_background = false;
1456 RenderPassList pass_list;
1457 pass_list.push_back(pass.Pass());
1459 EXPECT_TRUE(this->RunPixelTest(
1460 &pass_list,
1461 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1462 ExactPixelComparator(true)));
1465 TEST_F(ExternalStencilPixelTest, StencilTestDisabled) {
1466 PopulateStencilBuffer();
1468 // Draw a green quad that covers the entire device viewport. The stencil
1469 // buffer should be ignored.
1470 gfx::Rect rect(this->device_viewport_size_);
1471 RenderPassId id(1, 1);
1472 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1473 SharedQuadState* green_shared_state =
1474 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1475 SolidColorDrawQuad* green =
1476 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1477 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
1478 RenderPassList pass_list;
1479 pass_list.push_back(pass.Pass());
1481 EXPECT_TRUE(this->RunPixelTest(
1482 &pass_list,
1483 base::FilePath(FILE_PATH_LITERAL("green.png")),
1484 ExactPixelComparator(true)));
1487 TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) {
1488 // The stencil test should apply only to the final render pass.
1489 ClearBackgroundToGreen();
1490 PopulateStencilBuffer();
1491 this->EnableExternalStencilTest();
1493 gfx::Rect viewport_rect(this->device_viewport_size_);
1495 RenderPassId root_pass_id(1, 1);
1496 scoped_ptr<RenderPass> root_pass =
1497 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1498 root_pass->has_transparent_background = false;
1500 RenderPassId child_pass_id(2, 2);
1501 gfx::Rect pass_rect(this->device_viewport_size_);
1502 gfx::Transform transform_to_root;
1503 scoped_ptr<RenderPass> child_pass =
1504 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1506 gfx::Transform content_to_target_transform;
1507 SharedQuadState* shared_state = CreateTestSharedQuadState(
1508 content_to_target_transform, viewport_rect, child_pass.get());
1510 gfx::Rect blue_rect(0,
1512 this->device_viewport_size_.width(),
1513 this->device_viewport_size_.height());
1514 SolidColorDrawQuad* blue =
1515 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1516 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1518 SharedQuadState* pass_shared_state =
1519 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1520 CreateTestRenderPassDrawQuad(
1521 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1522 RenderPassList pass_list;
1523 pass_list.push_back(child_pass.Pass());
1524 pass_list.push_back(root_pass.Pass());
1526 EXPECT_TRUE(this->RunPixelTest(
1527 &pass_list,
1528 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1529 ExactPixelComparator(true)));
1532 TEST_F(ExternalStencilPixelTest, DeviceClip) {
1533 ClearBackgroundToGreen();
1534 gfx::Rect clip_rect(gfx::Point(150, 150), gfx::Size(50, 50));
1535 this->ForceDeviceClip(clip_rect);
1537 // Draw a blue quad that covers the entire device viewport. It should be
1538 // clipped to the bottom right corner by the device clip.
1539 gfx::Rect rect(this->device_viewport_size_);
1540 RenderPassId id(1, 1);
1541 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1542 SharedQuadState* blue_shared_state =
1543 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1544 SolidColorDrawQuad* blue =
1545 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1546 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1547 RenderPassList pass_list;
1548 pass_list.push_back(pass.Pass());
1550 EXPECT_TRUE(this->RunPixelTest(
1551 &pass_list,
1552 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
1553 ExactPixelComparator(true)));
1556 // Software renderer does not support anti-aliased edges.
1557 TEST_F(GLRendererPixelTest, AntiAliasing) {
1558 gfx::Rect rect(this->device_viewport_size_);
1560 RenderPassId id(1, 1);
1561 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1563 gfx::Transform red_content_to_target_transform;
1564 red_content_to_target_transform.Rotate(10);
1565 SharedQuadState* red_shared_state = CreateTestSharedQuadState(
1566 red_content_to_target_transform, rect, pass.get());
1568 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1569 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
1571 gfx::Transform yellow_content_to_target_transform;
1572 yellow_content_to_target_transform.Rotate(5);
1573 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
1574 yellow_content_to_target_transform, rect, pass.get());
1576 SolidColorDrawQuad* yellow =
1577 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1578 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
1580 gfx::Transform blue_content_to_target_transform;
1581 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
1582 blue_content_to_target_transform, rect, pass.get());
1584 SolidColorDrawQuad* blue =
1585 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1586 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1588 RenderPassList pass_list;
1589 pass_list.push_back(pass.Pass());
1591 EXPECT_TRUE(this->RunPixelTest(
1592 &pass_list,
1593 base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")),
1594 FuzzyPixelOffByOneComparator(true)));
1597 // This test tests that anti-aliasing works for axis aligned quads.
1598 // Anti-aliasing is only supported in the gl renderer.
1599 TEST_F(GLRendererPixelTest, AxisAligned) {
1600 gfx::Rect rect(this->device_viewport_size_);
1602 RenderPassId id(1, 1);
1603 gfx::Transform transform_to_root;
1604 scoped_ptr<RenderPass> pass =
1605 CreateTestRenderPass(id, rect, transform_to_root);
1607 gfx::Transform red_content_to_target_transform;
1608 red_content_to_target_transform.Translate(50, 50);
1609 red_content_to_target_transform.Scale(
1610 0.5f + 1.0f / (rect.width() * 2.0f),
1611 0.5f + 1.0f / (rect.height() * 2.0f));
1612 SharedQuadState* red_shared_state = CreateTestSharedQuadState(
1613 red_content_to_target_transform, rect, pass.get());
1615 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1616 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
1618 gfx::Transform yellow_content_to_target_transform;
1619 yellow_content_to_target_transform.Translate(25.5f, 25.5f);
1620 yellow_content_to_target_transform.Scale(0.5f, 0.5f);
1621 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
1622 yellow_content_to_target_transform, rect, pass.get());
1624 SolidColorDrawQuad* yellow =
1625 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1626 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
1628 gfx::Transform blue_content_to_target_transform;
1629 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
1630 blue_content_to_target_transform, rect, pass.get());
1632 SolidColorDrawQuad* blue =
1633 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1634 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1636 RenderPassList pass_list;
1637 pass_list.push_back(pass.Pass());
1639 EXPECT_TRUE(this->RunPixelTest(
1640 &pass_list,
1641 base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")),
1642 ExactPixelComparator(true)));
1645 // This test tests that forcing anti-aliasing off works as expected.
1646 // Anti-aliasing is only supported in the gl renderer.
1647 TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) {
1648 gfx::Rect rect(this->device_viewport_size_);
1650 RenderPassId id(1, 1);
1651 gfx::Transform transform_to_root;
1652 scoped_ptr<RenderPass> pass =
1653 CreateTestRenderPass(id, rect, transform_to_root);
1655 gfx::Transform hole_content_to_target_transform;
1656 hole_content_to_target_transform.Translate(50, 50);
1657 hole_content_to_target_transform.Scale(
1658 0.5f + 1.0f / (rect.width() * 2.0f),
1659 0.5f + 1.0f / (rect.height() * 2.0f));
1660 SharedQuadState* hole_shared_state = CreateTestSharedQuadState(
1661 hole_content_to_target_transform, rect, pass.get());
1663 SolidColorDrawQuad* hole =
1664 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1665 hole->SetAll(
1666 hole_shared_state, rect, rect, rect, false, SK_ColorTRANSPARENT, true);
1668 gfx::Transform green_content_to_target_transform;
1669 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
1670 green_content_to_target_transform, rect, pass.get());
1672 SolidColorDrawQuad* green =
1673 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1674 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
1676 RenderPassList pass_list;
1677 pass_list.push_back(pass.Pass());
1679 EXPECT_TRUE(this->RunPixelTest(
1680 &pass_list,
1681 base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")),
1682 ExactPixelComparator(false)));
1685 TEST_F(GLRendererPixelTest, AntiAliasingPerspective) {
1686 gfx::Rect rect(this->device_viewport_size_);
1688 scoped_ptr<RenderPass> pass =
1689 CreateTestRootRenderPass(RenderPassId(1, 1), rect);
1691 gfx::Rect red_rect(0, 0, 180, 500);
1692 gfx::Transform red_content_to_target_transform(
1693 1.0f, 2.4520f, 10.6206f, 19.0f,
1694 0.0f, 0.3528f, 5.9737f, 9.5f,
1695 0.0f, -0.2250f, -0.9744f, 0.0f,
1696 0.0f, 0.0225f, 0.0974f, 1.0f);
1697 SharedQuadState* red_shared_state = CreateTestSharedQuadState(
1698 red_content_to_target_transform, red_rect, pass.get());
1699 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1700 red->SetNew(red_shared_state, red_rect, red_rect, SK_ColorRED, false);
1702 gfx::Rect green_rect(19, 7, 180, 10);
1703 SharedQuadState* green_shared_state =
1704 CreateTestSharedQuadState(gfx::Transform(), green_rect, pass.get());
1705 SolidColorDrawQuad* green =
1706 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1707 green->SetNew(
1708 green_shared_state, green_rect, green_rect, SK_ColorGREEN, false);
1710 SharedQuadState* blue_shared_state =
1711 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1712 SolidColorDrawQuad* blue =
1713 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1714 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1716 RenderPassList pass_list;
1717 pass_list.push_back(pass.Pass());
1719 EXPECT_TRUE(this->RunPixelTest(
1720 &pass_list,
1721 base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")),
1722 FuzzyPixelOffByOneComparator(true)));
1725 TYPED_TEST(RendererPixelTest, PictureDrawQuadIdentityScale) {
1726 gfx::Size pile_tile_size(1000, 1000);
1727 gfx::Rect viewport(this->device_viewport_size_);
1728 // TODO(enne): the renderer should figure this out on its own.
1729 ResourceFormat texture_format = RGBA_8888;
1731 RenderPassId id(1, 1);
1732 gfx::Transform transform_to_root;
1733 scoped_ptr<RenderPass> pass =
1734 CreateTestRenderPass(id, viewport, transform_to_root);
1736 // One clipped blue quad in the lower right corner. Outside the clip
1737 // is red, which should not appear.
1738 gfx::Rect blue_rect(gfx::Size(100, 100));
1739 gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50));
1740 scoped_refptr<FakePicturePileImpl> blue_pile =
1741 FakePicturePileImpl::CreateFilledPile(pile_tile_size, blue_rect.size());
1742 SkPaint red_paint;
1743 red_paint.setColor(SK_ColorRED);
1744 blue_pile->add_draw_rect_with_paint(blue_rect, red_paint);
1745 SkPaint blue_paint;
1746 blue_paint.setColor(SK_ColorBLUE);
1747 blue_pile->add_draw_rect_with_paint(blue_clip_rect, blue_paint);
1748 blue_pile->RerecordPile();
1750 gfx::Transform blue_content_to_target_transform;
1751 gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right());
1752 blue_content_to_target_transform.Translate(offset.x(), offset.y());
1753 gfx::RectF blue_scissor_rect = blue_clip_rect;
1754 blue_content_to_target_transform.TransformRect(&blue_scissor_rect);
1755 SharedQuadState* blue_shared_state =
1756 CreateTestSharedQuadStateClipped(blue_content_to_target_transform,
1757 blue_rect,
1758 gfx::ToEnclosingRect(blue_scissor_rect),
1759 pass.get());
1761 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
1763 blue_quad->SetNew(blue_shared_state,
1764 viewport, // Intentionally bigger than clip.
1765 gfx::Rect(),
1766 viewport,
1767 gfx::RectF(viewport),
1768 viewport.size(),
1769 texture_format,
1770 viewport,
1771 1.f,
1772 PicturePileImpl::CreateFromOther(blue_pile.get()));
1774 // One viewport-filling green quad.
1775 scoped_refptr<FakePicturePileImpl> green_pile =
1776 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size());
1777 SkPaint green_paint;
1778 green_paint.setColor(SK_ColorGREEN);
1779 green_pile->add_draw_rect_with_paint(viewport, green_paint);
1780 green_pile->RerecordPile();
1782 gfx::Transform green_content_to_target_transform;
1783 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
1784 green_content_to_target_transform, viewport, pass.get());
1786 PictureDrawQuad* green_quad =
1787 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
1788 green_quad->SetNew(green_shared_state,
1789 viewport,
1790 gfx::Rect(),
1791 viewport,
1792 gfx::RectF(0.f, 0.f, 1.f, 1.f),
1793 viewport.size(),
1794 texture_format,
1795 viewport,
1796 1.f,
1797 PicturePileImpl::CreateFromOther(green_pile.get()));
1799 RenderPassList pass_list;
1800 pass_list.push_back(pass.Pass());
1802 EXPECT_TRUE(this->RunPixelTest(
1803 &pass_list,
1804 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
1805 ExactPixelComparator(true)));
1808 // Not WithSkiaGPUBackend since that path currently requires tiles for opacity.
1809 TYPED_TEST(RendererPixelTest, PictureDrawQuadOpacity) {
1810 gfx::Size pile_tile_size(1000, 1000);
1811 gfx::Rect viewport(this->device_viewport_size_);
1812 ResourceFormat texture_format = RGBA_8888;
1814 RenderPassId id(1, 1);
1815 gfx::Transform transform_to_root;
1816 scoped_ptr<RenderPass> pass =
1817 CreateTestRenderPass(id, viewport, transform_to_root);
1819 // One viewport-filling 0.5-opacity green quad.
1820 scoped_refptr<FakePicturePileImpl> green_pile =
1821 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size());
1822 SkPaint green_paint;
1823 green_paint.setColor(SK_ColorGREEN);
1824 green_pile->add_draw_rect_with_paint(viewport, green_paint);
1825 green_pile->RerecordPile();
1827 gfx::Transform green_content_to_target_transform;
1828 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
1829 green_content_to_target_transform, viewport, pass.get());
1830 green_shared_state->opacity = 0.5f;
1832 PictureDrawQuad* green_quad =
1833 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
1834 green_quad->SetNew(green_shared_state,
1835 viewport,
1836 gfx::Rect(),
1837 viewport,
1838 gfx::RectF(0, 0, 1, 1),
1839 viewport.size(),
1840 texture_format,
1841 viewport,
1842 1.f,
1843 PicturePileImpl::CreateFromOther(green_pile.get()));
1845 // One viewport-filling white quad.
1846 scoped_refptr<FakePicturePileImpl> white_pile =
1847 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size());
1848 SkPaint white_paint;
1849 white_paint.setColor(SK_ColorWHITE);
1850 white_pile->add_draw_rect_with_paint(viewport, white_paint);
1851 white_pile->RerecordPile();
1853 gfx::Transform white_content_to_target_transform;
1854 SharedQuadState* white_shared_state = CreateTestSharedQuadState(
1855 white_content_to_target_transform, viewport, pass.get());
1857 PictureDrawQuad* white_quad =
1858 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
1859 white_quad->SetNew(white_shared_state,
1860 viewport,
1861 gfx::Rect(),
1862 viewport,
1863 gfx::RectF(0, 0, 1, 1),
1864 viewport.size(),
1865 texture_format,
1866 viewport,
1867 1.f,
1868 PicturePileImpl::CreateFromOther(white_pile.get()));
1870 RenderPassList pass_list;
1871 pass_list.push_back(pass.Pass());
1873 EXPECT_TRUE(this->RunPixelTest(
1874 &pass_list,
1875 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
1876 FuzzyPixelOffByOneComparator(true)));
1879 template<typename TypeParam> bool IsSoftwareRenderer() {
1880 return false;
1883 template<>
1884 bool IsSoftwareRenderer<SoftwareRenderer>() {
1885 return true;
1888 template<>
1889 bool IsSoftwareRenderer<SoftwareRendererWithExpandedViewport>() {
1890 return true;
1893 // If we disable image filtering, then a 2x2 bitmap should appear as four
1894 // huge sharp squares.
1895 TYPED_TEST(RendererPixelTest, PictureDrawQuadDisableImageFiltering) {
1896 // We only care about this in software mode since bilinear filtering is
1897 // cheap in hardware.
1898 if (!IsSoftwareRenderer<TypeParam>())
1899 return;
1901 gfx::Size pile_tile_size(1000, 1000);
1902 gfx::Rect viewport(this->device_viewport_size_);
1903 ResourceFormat texture_format = RGBA_8888;
1905 RenderPassId id(1, 1);
1906 gfx::Transform transform_to_root;
1907 scoped_ptr<RenderPass> pass =
1908 CreateTestRenderPass(id, viewport, transform_to_root);
1910 SkBitmap bitmap;
1911 bitmap.allocN32Pixels(2, 2);
1913 SkAutoLockPixels lock(bitmap);
1914 SkCanvas canvas(bitmap);
1915 canvas.drawPoint(0, 0, SK_ColorGREEN);
1916 canvas.drawPoint(0, 1, SK_ColorBLUE);
1917 canvas.drawPoint(1, 0, SK_ColorBLUE);
1918 canvas.drawPoint(1, 1, SK_ColorGREEN);
1921 scoped_refptr<FakePicturePileImpl> pile =
1922 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size());
1923 SkPaint paint;
1924 paint.setFilterLevel(SkPaint::kLow_FilterLevel);
1925 pile->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
1926 pile->RerecordPile();
1928 gfx::Transform content_to_target_transform;
1929 SharedQuadState* shared_state = CreateTestSharedQuadState(
1930 content_to_target_transform, viewport, pass.get());
1932 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
1933 quad->SetNew(shared_state,
1934 viewport,
1935 gfx::Rect(),
1936 viewport,
1937 gfx::RectF(0, 0, 2, 2),
1938 viewport.size(),
1939 texture_format,
1940 viewport,
1941 1.f,
1942 PicturePileImpl::CreateFromOther(pile.get()));
1944 RenderPassList pass_list;
1945 pass_list.push_back(pass.Pass());
1947 this->disable_picture_quad_image_filtering_ = true;
1949 EXPECT_TRUE(this->RunPixelTest(
1950 &pass_list,
1951 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1952 ExactPixelComparator(true)));
1955 TYPED_TEST(RendererPixelTest, PictureDrawQuadNonIdentityScale) {
1956 gfx::Size pile_tile_size(1000, 1000);
1957 gfx::Rect viewport(this->device_viewport_size_);
1958 // TODO(enne): the renderer should figure this out on its own.
1959 ResourceFormat texture_format = RGBA_8888;
1961 RenderPassId id(1, 1);
1962 gfx::Transform transform_to_root;
1963 scoped_ptr<RenderPass> pass =
1964 CreateTestRenderPass(id, viewport, transform_to_root);
1966 // As scaling up the blue checkerboards will cause sampling on the GPU,
1967 // a few extra "cleanup rects" need to be added to clobber the blending
1968 // to make the output image more clean. This will also test subrects
1969 // of the layer.
1970 gfx::Transform green_content_to_target_transform;
1971 gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100));
1972 gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20));
1973 scoped_refptr<FakePicturePileImpl> green_pile =
1974 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size());
1975 SkPaint red_paint;
1976 red_paint.setColor(SK_ColorRED);
1977 green_pile->add_draw_rect_with_paint(viewport, red_paint);
1978 SkPaint green_paint;
1979 green_paint.setColor(SK_ColorGREEN);
1980 green_pile->add_draw_rect_with_paint(green_rect1, green_paint);
1981 green_pile->add_draw_rect_with_paint(green_rect2, green_paint);
1982 green_pile->RerecordPile();
1984 SharedQuadState* top_right_green_shared_quad_state =
1985 CreateTestSharedQuadState(
1986 green_content_to_target_transform, viewport, pass.get());
1988 PictureDrawQuad* green_quad1 =
1989 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
1990 green_quad1->SetNew(top_right_green_shared_quad_state,
1991 green_rect1,
1992 gfx::Rect(),
1993 green_rect1,
1994 gfx::RectF(green_rect1.size()),
1995 green_rect1.size(),
1996 texture_format,
1997 green_rect1,
1998 1.f,
1999 PicturePileImpl::CreateFromOther(green_pile.get()));
2001 PictureDrawQuad* green_quad2 =
2002 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2003 green_quad2->SetNew(top_right_green_shared_quad_state,
2004 green_rect2,
2005 gfx::Rect(),
2006 green_rect2,
2007 gfx::RectF(green_rect2.size()),
2008 green_rect2.size(),
2009 texture_format,
2010 green_rect2,
2011 1.f,
2012 PicturePileImpl::CreateFromOther(green_pile.get()));
2014 // Add a green clipped checkerboard in the bottom right to help test
2015 // interleaving picture quad content and solid color content.
2016 gfx::Rect bottom_right_rect(
2017 gfx::Point(viewport.width() / 2, viewport.height() / 2),
2018 gfx::Size(viewport.width() / 2, viewport.height() / 2));
2019 SharedQuadState* bottom_right_green_shared_state =
2020 CreateTestSharedQuadStateClipped(green_content_to_target_transform,
2021 viewport,
2022 bottom_right_rect,
2023 pass.get());
2024 SolidColorDrawQuad* bottom_right_color_quad =
2025 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2026 bottom_right_color_quad->SetNew(bottom_right_green_shared_state,
2027 viewport,
2028 viewport,
2029 SK_ColorGREEN,
2030 false);
2032 // Add two blue checkerboards taking up the bottom left and top right,
2033 // but use content scales as content rects to make this happen.
2034 // The content is at a 4x content scale.
2035 gfx::Rect layer_rect(gfx::Size(20, 30));
2036 float contents_scale = 4.f;
2037 // Two rects that touch at their corners, arbitrarily placed in the layer.
2038 gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f));
2039 gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f));
2040 gfx::RectF union_layer_rect = blue_layer_rect1;
2041 union_layer_rect.Union(blue_layer_rect2);
2043 // Because scaling up will cause sampling outside the rects, add one extra
2044 // pixel of buffer at the final content scale.
2045 float inset = -1.f / contents_scale;
2046 blue_layer_rect1.Inset(inset, inset, inset, inset);
2047 blue_layer_rect2.Inset(inset, inset, inset, inset);
2049 scoped_refptr<FakePicturePileImpl> pile =
2050 FakePicturePileImpl::CreateFilledPile(pile_tile_size, layer_rect.size());
2052 Region outside(layer_rect);
2053 outside.Subtract(gfx::ToEnclosingRect(union_layer_rect));
2054 for (Region::Iterator iter(outside); iter.has_rect(); iter.next()) {
2055 pile->add_draw_rect_with_paint(iter.rect(), red_paint);
2058 SkPaint blue_paint;
2059 blue_paint.setColor(SK_ColorBLUE);
2060 pile->add_draw_rect_with_paint(blue_layer_rect1, blue_paint);
2061 pile->add_draw_rect_with_paint(blue_layer_rect2, blue_paint);
2062 pile->RerecordPile();
2064 gfx::Rect content_rect(
2065 gfx::ScaleToEnclosingRect(layer_rect, contents_scale));
2066 gfx::Rect content_union_rect(
2067 gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale)));
2069 // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels,
2070 // so scale an additional 10x to make them 100x100.
2071 gfx::Transform content_to_target_transform;
2072 content_to_target_transform.Scale(10.0, 10.0);
2073 gfx::Rect quad_content_rect(gfx::Size(20, 20));
2074 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2075 content_to_target_transform, quad_content_rect, pass.get());
2077 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2078 blue_quad->SetNew(blue_shared_state,
2079 quad_content_rect,
2080 gfx::Rect(),
2081 quad_content_rect,
2082 gfx::RectF(quad_content_rect),
2083 content_union_rect.size(),
2084 texture_format,
2085 content_union_rect,
2086 contents_scale,
2087 PicturePileImpl::CreateFromOther(pile.get()));
2089 // Fill left half of viewport with green.
2090 gfx::Transform half_green_content_to_target_transform;
2091 gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height()));
2092 SharedQuadState* half_green_shared_state = CreateTestSharedQuadState(
2093 half_green_content_to_target_transform, half_green_rect, pass.get());
2094 SolidColorDrawQuad* half_color_quad =
2095 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2096 half_color_quad->SetNew(half_green_shared_state,
2097 half_green_rect,
2098 half_green_rect,
2099 SK_ColorGREEN,
2100 false);
2102 RenderPassList pass_list;
2103 pass_list.push_back(pass.Pass());
2105 EXPECT_TRUE(this->RunPixelTest(
2106 &pass_list,
2107 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2108 ExactPixelComparator(true)));
2111 TEST_F(GLRendererPixelTest, PictureDrawQuadTexture4444) {
2112 gfx::Size pile_tile_size(1000, 1000);
2113 gfx::Rect viewport(this->device_viewport_size_);
2114 ResourceFormat texture_format = RGBA_4444;
2116 RenderPassId id(1, 1);
2117 gfx::Transform transform_to_root;
2118 scoped_ptr<RenderPass> pass =
2119 CreateTestRenderPass(id, viewport, transform_to_root);
2121 // One viewport-filling blue quad
2122 scoped_refptr<FakePicturePileImpl> blue_pile =
2123 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size());
2124 SkPaint blue_paint;
2125 blue_paint.setColor(SK_ColorBLUE);
2126 blue_pile->add_draw_rect_with_paint(viewport, blue_paint);
2127 blue_pile->RerecordPile();
2129 gfx::Transform blue_content_to_target_transform;
2130 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2131 blue_content_to_target_transform, viewport, pass.get());
2133 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2134 blue_quad->SetNew(blue_shared_state,
2135 viewport,
2136 gfx::Rect(),
2137 viewport,
2138 gfx::RectF(0.f, 0.f, 1.f, 1.f),
2139 viewport.size(),
2140 texture_format,
2141 viewport,
2142 1.f,
2143 PicturePileImpl::CreateFromOther(blue_pile.get()));
2145 RenderPassList pass_list;
2146 pass_list.push_back(pass.Pass());
2148 EXPECT_TRUE(this->RunPixelTest(&pass_list,
2149 base::FilePath(FILE_PATH_LITERAL("blue.png")),
2150 ExactPixelComparator(true)));
2153 TYPED_TEST(RendererPixelTest, WrapModeRepeat) {
2154 gfx::Rect rect(this->device_viewport_size_);
2156 RenderPassId id(1, 1);
2157 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2159 SharedQuadState* shared_state =
2160 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
2162 gfx::Rect texture_rect(4, 4);
2163 SkPMColor colors[4] = {
2164 SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)),
2165 SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)),
2166 SkPreMultiplyColor(SkColorSetARGB(255, 0, 64, 0)),
2167 SkPreMultiplyColor(SkColorSetARGB(255, 0, 0, 0)),
2169 uint32_t pixels[16] = {
2170 colors[0], colors[0], colors[1], colors[1],
2171 colors[0], colors[0], colors[1], colors[1],
2172 colors[2], colors[2], colors[3], colors[3],
2173 colors[2], colors[2], colors[3], colors[3],
2175 ResourceProvider::ResourceId resource =
2176 this->resource_provider_->CreateResource(
2177 texture_rect.size(),
2178 GL_REPEAT,
2179 ResourceProvider::TextureHintImmutable,
2180 RGBA_8888);
2181 this->resource_provider_->SetPixels(
2182 resource,
2183 reinterpret_cast<uint8_t*>(pixels),
2184 texture_rect,
2185 texture_rect,
2186 gfx::Vector2d());
2188 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2189 TextureDrawQuad* texture_quad =
2190 pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2191 texture_quad->SetNew(
2192 shared_state,
2193 gfx::Rect(this->device_viewport_size_),
2194 gfx::Rect(),
2195 gfx::Rect(this->device_viewport_size_),
2196 resource,
2197 true, // premultiplied_alpha
2198 gfx::PointF(0.0f, 0.0f), // uv_top_left
2199 gfx::PointF( // uv_bottom_right
2200 this->device_viewport_size_.width() / texture_rect.width(),
2201 this->device_viewport_size_.height() / texture_rect.height()),
2202 SK_ColorWHITE,
2203 vertex_opacity,
2204 false); // flipped
2206 RenderPassList pass_list;
2207 pass_list.push_back(pass.Pass());
2209 EXPECT_TRUE(this->RunPixelTest(
2210 &pass_list,
2211 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
2212 FuzzyPixelOffByOneComparator(true)));
2215 #endif // !defined(OS_ANDROID)
2217 } // namespace
2218 } // namespace cc