User interface of Apps Developer Tool:
[chromium-blink-merge.git] / cc / output / renderer_pixeltest.cc
blob9508aa291669c1c108d73d68523941dd9ee2e943
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/platform_color.h"
12 #include "cc/resources/sync_point_helper.h"
13 #include "cc/test/fake_picture_pile_impl.h"
14 #include "cc/test/pixel_test.h"
15 #include "gpu/GLES2/gl2extchromium.h"
16 #include "third_party/skia/include/core/SkImageFilter.h"
17 #include "third_party/skia/include/core/SkMatrix.h"
18 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
19 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
20 #include "ui/gfx/rect_conversions.h"
22 namespace cc {
23 namespace {
25 scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPass::Id id,
26 gfx::Rect rect) {
27 scoped_ptr<RenderPass> pass = RenderPass::Create();
28 const gfx::Rect output_rect = rect;
29 const gfx::RectF damage_rect = rect;
30 const gfx::Transform transform_to_root_target;
31 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
32 return pass.Pass();
35 scoped_ptr<RenderPass> CreateTestRenderPass(
36 RenderPass::Id id,
37 gfx::Rect rect,
38 const gfx::Transform& transform_to_root_target) {
39 scoped_ptr<RenderPass> pass = RenderPass::Create();
40 const gfx::Rect output_rect = rect;
41 const gfx::RectF damage_rect = rect;
42 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
43 return pass.Pass();
46 scoped_ptr<SharedQuadState> CreateTestSharedQuadState(
47 gfx::Transform content_to_target_transform, gfx::Rect rect) {
48 const gfx::Size content_bounds = rect.size();
49 const gfx::Rect visible_content_rect = rect;
50 const gfx::Rect clip_rect = rect;
51 const bool is_clipped = false;
52 const float opacity = 1.0f;
53 scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create();
54 shared_state->SetAll(content_to_target_transform,
55 content_bounds,
56 visible_content_rect,
57 clip_rect,
58 is_clipped,
59 opacity);
60 return shared_state.Pass();
63 scoped_ptr<SharedQuadState> CreateTestSharedQuadStateClipped(
64 gfx::Transform content_to_target_transform,
65 gfx::Rect rect,
66 gfx::Rect clip_rect) {
67 const gfx::Size content_bounds = rect.size();
68 const gfx::Rect visible_content_rect = clip_rect;
69 const bool is_clipped = true;
70 const float opacity = 1.0f;
71 scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create();
72 shared_state->SetAll(content_to_target_transform,
73 content_bounds,
74 visible_content_rect,
75 clip_rect,
76 is_clipped,
77 opacity);
78 return shared_state.Pass();
81 scoped_ptr<DrawQuad> CreateTestRenderPassDrawQuad(
82 SharedQuadState* shared_state, gfx::Rect rect, RenderPass::Id pass_id) {
83 scoped_ptr<RenderPassDrawQuad> quad = RenderPassDrawQuad::Create();
84 quad->SetNew(shared_state,
85 rect,
86 pass_id,
87 false, // is_replica
88 0, // mask_resource_id
89 rect, // contents_changed_since_last_frame
90 gfx::RectF(), // mask_uv_rect
91 FilterOperations(), // foreground filters
92 skia::RefPtr<SkImageFilter>(), // foreground filter
93 FilterOperations()); // background filters
95 return quad.PassAs<DrawQuad>();
98 scoped_ptr<TextureDrawQuad> CreateTestTextureDrawQuad(
99 gfx::Rect rect,
100 SkColor texel_color,
101 SkColor background_color,
102 bool premultiplied_alpha,
103 SharedQuadState* shared_state,
104 ResourceProvider* resource_provider) {
105 SkPMColor pixel_color = premultiplied_alpha ?
106 SkPreMultiplyColor(texel_color) :
107 SkPackARGB32NoCheck(SkColorGetA(texel_color),
108 SkColorGetR(texel_color),
109 SkColorGetG(texel_color),
110 SkColorGetB(texel_color));
111 std::vector<uint32_t> pixels(rect.size().GetArea(), pixel_color);
113 ResourceProvider::ResourceId resource = resource_provider->CreateResource(
114 rect.size(), GL_RGBA, ResourceProvider::TextureUsageAny);
115 resource_provider->SetPixels(
116 resource,
117 reinterpret_cast<uint8_t*>(&pixels.front()),
118 rect,
119 rect,
120 gfx::Vector2d());
122 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
124 scoped_ptr<TextureDrawQuad> quad = TextureDrawQuad::Create();
125 quad->SetNew(shared_state,
126 rect,
127 gfx::Rect(),
128 resource,
129 premultiplied_alpha,
130 gfx::PointF(0.0f, 0.0f), // uv_top_left
131 gfx::PointF(1.0f, 1.0f), // uv_bottom_right
132 background_color,
133 vertex_opacity,
134 false); // flipped
135 return quad.Pass();
138 typedef ::testing::Types<GLRenderer,
139 SoftwareRenderer,
140 GLRendererWithExpandedViewport,
141 SoftwareRendererWithExpandedViewport> RendererTypes;
142 TYPED_TEST_CASE(RendererPixelTest, RendererTypes);
144 typedef ::testing::Types<GLRenderer,
145 GLRendererWithSkiaGPUBackend,
146 SoftwareRenderer> RendererTypesWithSkiaGPUBackend;
147 template <typename RendererType>
148 class RendererPixelTestWithSkiaGPUBackend
149 : public RendererPixelTest<RendererType> {
151 TYPED_TEST_CASE(RendererPixelTestWithSkiaGPUBackend,
152 RendererTypesWithSkiaGPUBackend);
154 // All pixels can be off by one, but any more than that is an error.
155 class FuzzyPixelOffByOneComparator : public FuzzyPixelComparator {
156 public:
157 explicit FuzzyPixelOffByOneComparator(bool discard_alpha)
158 : FuzzyPixelComparator(discard_alpha, 100.f, 0.f, 1.f, 1, 0) {}
161 template <typename RendererType>
162 class FuzzyForSoftwareOnlyPixelComparator : public PixelComparator {
163 public:
164 explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha)
165 : fuzzy_(discard_alpha), exact_(discard_alpha) {}
167 virtual bool Compare(const SkBitmap& actual_bmp,
168 const SkBitmap& expected_bmp) const;
170 private:
171 FuzzyPixelOffByOneComparator fuzzy_;
172 ExactPixelComparator exact_;
175 template<>
176 bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare(
177 const SkBitmap& actual_bmp,
178 const SkBitmap& expected_bmp) const {
179 return fuzzy_.Compare(actual_bmp, expected_bmp);
182 template <>
183 bool FuzzyForSoftwareOnlyPixelComparator<
184 SoftwareRendererWithExpandedViewport>::Compare(
185 const SkBitmap& actual_bmp,
186 const SkBitmap& expected_bmp) const {
187 return fuzzy_.Compare(actual_bmp, expected_bmp);
190 template<typename RendererType>
191 bool FuzzyForSoftwareOnlyPixelComparator<RendererType>::Compare(
192 const SkBitmap& actual_bmp,
193 const SkBitmap& expected_bmp) const {
194 return exact_.Compare(actual_bmp, expected_bmp);
197 #if !defined(OS_ANDROID)
198 TYPED_TEST(RendererPixelTest, SimpleGreenRect) {
199 gfx::Rect rect(this->device_viewport_size_);
201 RenderPass::Id id(1, 1);
202 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
204 scoped_ptr<SharedQuadState> shared_state =
205 CreateTestSharedQuadState(gfx::Transform(), rect);
207 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
208 color_quad->SetNew(shared_state.get(), rect, SK_ColorGREEN, false);
210 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
212 RenderPassList pass_list;
213 pass_list.push_back(pass.Pass());
215 EXPECT_TRUE(this->RunPixelTest(
216 &pass_list,
217 base::FilePath(FILE_PATH_LITERAL("green.png")),
218 ExactPixelComparator(true)));
221 TYPED_TEST(RendererPixelTest, SimpleGreenRect_NonRootRenderPass) {
222 gfx::Rect rect(this->device_viewport_size_);
223 gfx::Rect small_rect(100, 100);
225 RenderPass::Id child_id(2, 1);
226 scoped_ptr<RenderPass> child_pass =
227 CreateTestRenderPass(child_id, small_rect, gfx::Transform());
229 scoped_ptr<SharedQuadState> child_shared_state =
230 CreateTestSharedQuadState(gfx::Transform(), small_rect);
232 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
233 color_quad->SetNew(child_shared_state.get(), rect, SK_ColorGREEN, false);
234 child_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
236 RenderPass::Id root_id(1, 1);
237 scoped_ptr<RenderPass> root_pass =
238 CreateTestRenderPass(root_id, rect, gfx::Transform());
240 scoped_ptr<SharedQuadState> root_shared_state =
241 CreateTestSharedQuadState(gfx::Transform(), rect);
243 scoped_ptr<DrawQuad> render_pass_quad =
244 CreateTestRenderPassDrawQuad(root_shared_state.get(),
245 small_rect,
246 child_id);
247 root_pass->quad_list.push_back(render_pass_quad.PassAs<DrawQuad>());
249 RenderPass* child_pass_ptr = child_pass.get();
251 RenderPassList pass_list;
252 pass_list.push_back(child_pass.Pass());
253 pass_list.push_back(root_pass.Pass());
255 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
256 &pass_list,
257 child_pass_ptr,
258 base::FilePath(FILE_PATH_LITERAL("green_small.png")),
259 ExactPixelComparator(true)));
262 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithoutBackground) {
263 gfx::Rect rect(this->device_viewport_size_);
265 RenderPass::Id id(1, 1);
266 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
268 scoped_ptr<SharedQuadState> shared_state =
269 CreateTestSharedQuadState(gfx::Transform(), rect);
271 scoped_ptr<TextureDrawQuad> texture_quad = CreateTestTextureDrawQuad(
272 gfx::Rect(this->device_viewport_size_),
273 SkColorSetARGB(128, 0, 255, 0), // Texel color.
274 SK_ColorTRANSPARENT, // Background color.
275 true, // Premultiplied alpha.
276 shared_state.get(),
277 this->resource_provider_.get());
278 pass->quad_list.push_back(texture_quad.PassAs<DrawQuad>());
280 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
281 color_quad->SetNew(shared_state.get(), rect, SK_ColorWHITE, false);
282 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
284 RenderPassList pass_list;
285 pass_list.push_back(pass.Pass());
287 EXPECT_TRUE(this->RunPixelTest(
288 &pass_list,
289 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
290 FuzzyPixelOffByOneComparator(true)));
293 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithBackground) {
294 gfx::Rect rect(this->device_viewport_size_);
296 RenderPass::Id id(1, 1);
297 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
299 scoped_ptr<SharedQuadState> texture_quad_state =
300 CreateTestSharedQuadState(gfx::Transform(), rect);
301 texture_quad_state->opacity = 0.8f;
303 scoped_ptr<TextureDrawQuad> texture_quad = CreateTestTextureDrawQuad(
304 gfx::Rect(this->device_viewport_size_),
305 SkColorSetARGB(204, 120, 255, 120), // Texel color.
306 SK_ColorGREEN, // Background color.
307 true, // Premultiplied alpha.
308 texture_quad_state.get(),
309 this->resource_provider_.get());
310 pass->quad_list.push_back(texture_quad.PassAs<DrawQuad>());
312 scoped_ptr<SharedQuadState> color_quad_state =
313 CreateTestSharedQuadState(gfx::Transform(), rect);
314 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
315 color_quad->SetNew(color_quad_state.get(), rect, SK_ColorWHITE, false);
316 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
318 RenderPassList pass_list;
319 pass_list.push_back(pass.Pass());
321 EXPECT_TRUE(this->RunPixelTest(
322 &pass_list,
323 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
324 FuzzyPixelOffByOneComparator(true)));
327 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
328 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) {
329 gfx::Rect rect(this->device_viewport_size_);
331 RenderPass::Id id(1, 1);
332 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
334 scoped_ptr<SharedQuadState> shared_state =
335 CreateTestSharedQuadState(gfx::Transform(), rect);
337 scoped_ptr<TextureDrawQuad> texture_quad = CreateTestTextureDrawQuad(
338 gfx::Rect(this->device_viewport_size_),
339 SkColorSetARGB(128, 0, 255, 0), // Texel color.
340 SK_ColorTRANSPARENT, // Background color.
341 false, // Premultiplied alpha.
342 shared_state.get(),
343 this->resource_provider_.get());
344 pass->quad_list.push_back(texture_quad.PassAs<DrawQuad>());
346 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
347 color_quad->SetNew(shared_state.get(), rect, SK_ColorWHITE, false);
348 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
350 RenderPassList pass_list;
351 pass_list.push_back(pass.Pass());
353 EXPECT_TRUE(this->RunPixelTest(
354 &pass_list,
355 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
356 FuzzyPixelOffByOneComparator(true)));
359 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
360 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
361 gfx::Rect rect(this->device_viewport_size_);
363 RenderPass::Id id(1, 1);
364 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
366 scoped_ptr<SharedQuadState> texture_quad_state =
367 CreateTestSharedQuadState(gfx::Transform(), rect);
368 texture_quad_state->opacity = 0.8f;
370 scoped_ptr<TextureDrawQuad> texture_quad = CreateTestTextureDrawQuad(
371 gfx::Rect(this->device_viewport_size_),
372 SkColorSetARGB(204, 120, 255, 120), // Texel color.
373 SK_ColorGREEN, // Background color.
374 false, // Premultiplied alpha.
375 texture_quad_state.get(),
376 this->resource_provider_.get());
377 pass->quad_list.push_back(texture_quad.PassAs<DrawQuad>());
379 scoped_ptr<SharedQuadState> color_quad_state =
380 CreateTestSharedQuadState(gfx::Transform(), rect);
381 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
382 color_quad->SetNew(color_quad_state.get(), rect, SK_ColorWHITE, false);
383 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
385 RenderPassList pass_list;
386 pass_list.push_back(pass.Pass());
388 EXPECT_TRUE(this->RunPixelTest(
389 &pass_list,
390 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
391 FuzzyPixelOffByOneComparator(true)));
394 class VideoGLRendererPixelTest : public GLRendererPixelTest {
395 protected:
396 scoped_ptr<YUVVideoDrawQuad> CreateTestYUVVideoDrawQuad(
397 SharedQuadState* shared_state, bool with_alpha, bool is_transparent) {
398 gfx::Rect rect(this->device_viewport_size_);
399 gfx::Rect opaque_rect(0, 0, 0, 0);
401 ResourceProvider::ResourceId y_resource =
402 resource_provider_->CreateResource(
403 this->device_viewport_size_,
404 GL_LUMINANCE,
405 ResourceProvider::TextureUsageAny);
406 ResourceProvider::ResourceId u_resource =
407 resource_provider_->CreateResource(
408 this->device_viewport_size_,
409 GL_LUMINANCE,
410 ResourceProvider::TextureUsageAny);
411 ResourceProvider::ResourceId v_resource =
412 resource_provider_->CreateResource(
413 this->device_viewport_size_,
414 GL_LUMINANCE,
415 ResourceProvider::TextureUsageAny);
416 ResourceProvider::ResourceId a_resource = 0;
417 if (with_alpha) {
418 a_resource = resource_provider_->CreateResource(
419 this->device_viewport_size_,
420 GL_LUMINANCE,
421 ResourceProvider::TextureUsageAny);
424 int w = this->device_viewport_size_.width();
425 int h = this->device_viewport_size_.height();
426 const int y_plane_size = w * h;
427 gfx::Rect uv_rect((w + 1) / 2, (h + 1) / 2);
428 const int uv_plane_size = uv_rect.size().GetArea();
429 scoped_ptr<uint8_t[]> y_plane(new uint8_t[y_plane_size]);
430 scoped_ptr<uint8_t[]> u_plane(new uint8_t[uv_plane_size]);
431 scoped_ptr<uint8_t[]> v_plane(new uint8_t[uv_plane_size]);
432 scoped_ptr<uint8_t[]> a_plane;
433 if (with_alpha)
434 a_plane.reset(new uint8_t[y_plane_size]);
435 // YUV values representing Green.
436 memset(y_plane.get(), 149, y_plane_size);
437 memset(u_plane.get(), 43, uv_plane_size);
438 memset(v_plane.get(), 21, uv_plane_size);
439 if (with_alpha)
440 memset(a_plane.get(), is_transparent ? 0 : 128, y_plane_size);
442 resource_provider_->SetPixels(y_resource, y_plane.get(), rect, rect,
443 gfx::Vector2d());
444 resource_provider_->SetPixels(u_resource, u_plane.get(), uv_rect, uv_rect,
445 gfx::Vector2d());
446 resource_provider_->SetPixels(v_resource, v_plane.get(), uv_rect, uv_rect,
447 gfx::Vector2d());
448 if (with_alpha) {
449 resource_provider_->SetPixels(a_resource, a_plane.get(), rect, rect,
450 gfx::Vector2d());
453 scoped_ptr<YUVVideoDrawQuad> yuv_quad = cc::YUVVideoDrawQuad::Create();
454 yuv_quad->SetNew(shared_state, rect, opaque_rect, gfx::Size(),
455 y_resource, u_resource, v_resource, a_resource);
456 return yuv_quad.Pass();
460 TEST_F(VideoGLRendererPixelTest, SimpleYUVRect) {
461 gfx::Rect rect(this->device_viewport_size_);
463 RenderPass::Id id(1, 1);
464 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
466 scoped_ptr<SharedQuadState> shared_state =
467 CreateTestSharedQuadState(gfx::Transform(), rect);
469 scoped_ptr<YUVVideoDrawQuad> yuv_quad =
470 CreateTestYUVVideoDrawQuad(shared_state.get(), false, false);
472 pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>());
474 RenderPassList pass_list;
475 pass_list.push_back(pass.Pass());
477 EXPECT_TRUE(this->RunPixelTest(
478 &pass_list,
479 base::FilePath(FILE_PATH_LITERAL("green.png")),
480 ExactPixelComparator(true)));
483 TEST_F(VideoGLRendererPixelTest, SimpleYUVARect) {
484 gfx::Rect rect(this->device_viewport_size_);
486 RenderPass::Id id(1, 1);
487 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
489 scoped_ptr<SharedQuadState> shared_state =
490 CreateTestSharedQuadState(gfx::Transform(), rect);
492 scoped_ptr<YUVVideoDrawQuad> yuv_quad =
493 CreateTestYUVVideoDrawQuad(shared_state.get(), true, false);
495 pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>());
497 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
498 color_quad->SetNew(shared_state.get(), rect, SK_ColorWHITE, false);
500 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
502 RenderPassList pass_list;
503 pass_list.push_back(pass.Pass());
505 EXPECT_TRUE(this->RunPixelTest(
506 &pass_list,
507 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
508 ExactPixelComparator(true)));
511 TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) {
512 gfx::Rect rect(this->device_viewport_size_);
514 RenderPass::Id id(1, 1);
515 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
517 scoped_ptr<SharedQuadState> shared_state =
518 CreateTestSharedQuadState(gfx::Transform(), rect);
520 scoped_ptr<YUVVideoDrawQuad> yuv_quad =
521 CreateTestYUVVideoDrawQuad(shared_state.get(), true, true);
523 pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>());
525 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
526 color_quad->SetNew(shared_state.get(), rect, SK_ColorBLACK, false);
528 pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
530 RenderPassList pass_list;
531 pass_list.push_back(pass.Pass());
533 EXPECT_TRUE(this->RunPixelTest(
534 &pass_list,
535 base::FilePath(FILE_PATH_LITERAL("black.png")),
536 ExactPixelComparator(true)));
539 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) {
540 gfx::Rect viewport_rect(this->device_viewport_size_);
542 RenderPass::Id root_pass_id(1, 1);
543 scoped_ptr<RenderPass> root_pass =
544 CreateTestRootRenderPass(root_pass_id, viewport_rect);
546 RenderPass::Id child_pass_id(2, 2);
547 gfx::Rect pass_rect(this->device_viewport_size_);
548 gfx::Transform transform_to_root;
549 scoped_ptr<RenderPass> child_pass =
550 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
552 gfx::Transform content_to_target_transform;
553 scoped_ptr<SharedQuadState> shared_state =
554 CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
555 shared_state->opacity = 0.5f;
557 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
558 blue->SetNew(shared_state.get(),
559 gfx::Rect(0,
561 this->device_viewport_size_.width(),
562 this->device_viewport_size_.height() / 2),
563 SK_ColorBLUE,
564 false);
565 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
566 yellow->SetNew(shared_state.get(),
567 gfx::Rect(0,
568 this->device_viewport_size_.height() / 2,
569 this->device_viewport_size_.width(),
570 this->device_viewport_size_.height() / 2),
571 SK_ColorYELLOW,
572 false);
574 scoped_ptr<SharedQuadState> blank_state =
575 CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
577 scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create();
578 white->SetNew(blank_state.get(),
579 viewport_rect,
580 SK_ColorWHITE,
581 false);
583 child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
584 child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
585 child_pass->quad_list.push_back(white.PassAs<DrawQuad>());
587 scoped_ptr<SharedQuadState> pass_shared_state =
588 CreateTestSharedQuadState(gfx::Transform(), pass_rect);
590 SkScalar matrix[20];
591 float amount = 0.5f;
592 matrix[0] = 0.213f + 0.787f * amount;
593 matrix[1] = 0.715f - 0.715f * amount;
594 matrix[2] = 1.f - (matrix[0] + matrix[1]);
595 matrix[3] = matrix[4] = 0;
596 matrix[5] = 0.213f - 0.213f * amount;
597 matrix[6] = 0.715f + 0.285f * amount;
598 matrix[7] = 1.f - (matrix[5] + matrix[6]);
599 matrix[8] = matrix[9] = 0;
600 matrix[10] = 0.213f - 0.213f * amount;
601 matrix[11] = 0.715f - 0.715f * amount;
602 matrix[12] = 1.f - (matrix[10] + matrix[11]);
603 matrix[13] = matrix[14] = 0;
604 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
605 matrix[18] = 1;
606 skia::RefPtr<SkColorFilter> colorFilter(skia::AdoptRef(
607 new SkColorMatrixFilter(matrix)));
608 skia::RefPtr<SkImageFilter> filter =
609 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
611 scoped_ptr<RenderPassDrawQuad> render_pass_quad =
612 RenderPassDrawQuad::Create();
613 render_pass_quad->SetNew(pass_shared_state.get(),
614 pass_rect,
615 child_pass_id,
616 false,
618 pass_rect,
619 gfx::RectF(),
620 FilterOperations(),
621 filter,
622 FilterOperations());
624 root_pass->quad_list.push_back(render_pass_quad.PassAs<DrawQuad>());
626 RenderPassList pass_list;
627 pass_list.push_back(child_pass.Pass());
628 pass_list.push_back(root_pass.Pass());
630 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
631 // renderer so use a fuzzy comparator.
632 EXPECT_TRUE(this->RunPixelTest(
633 &pass_list,
634 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
635 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
638 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) {
639 gfx::Rect viewport_rect(this->device_viewport_size_);
641 RenderPass::Id root_pass_id(1, 1);
642 scoped_ptr<RenderPass> root_pass =
643 CreateTestRootRenderPass(root_pass_id, viewport_rect);
645 RenderPass::Id child_pass_id(2, 2);
646 gfx::Rect pass_rect(this->device_viewport_size_);
647 gfx::Transform transform_to_root;
648 scoped_ptr<RenderPass> child_pass =
649 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
651 gfx::Transform content_to_target_transform;
652 scoped_ptr<SharedQuadState> shared_state =
653 CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
654 shared_state->opacity = 0.5f;
656 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
657 blue->SetNew(shared_state.get(),
658 gfx::Rect(0,
660 this->device_viewport_size_.width(),
661 this->device_viewport_size_.height() / 2),
662 SK_ColorBLUE,
663 false);
664 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
665 yellow->SetNew(shared_state.get(),
666 gfx::Rect(0,
667 this->device_viewport_size_.height() / 2,
668 this->device_viewport_size_.width(),
669 this->device_viewport_size_.height() / 2),
670 SK_ColorYELLOW,
671 false);
673 scoped_ptr<SharedQuadState> blank_state =
674 CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
676 scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create();
677 white->SetNew(blank_state.get(),
678 viewport_rect,
679 SK_ColorWHITE,
680 false);
682 child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
683 child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
684 child_pass->quad_list.push_back(white.PassAs<DrawQuad>());
686 scoped_ptr<SharedQuadState> pass_shared_state =
687 CreateTestSharedQuadState(gfx::Transform(), pass_rect);
689 SkScalar matrix[20];
690 float amount = 0.5f;
691 matrix[0] = 0.213f + 0.787f * amount;
692 matrix[1] = 0.715f - 0.715f * amount;
693 matrix[2] = 1.f - (matrix[0] + matrix[1]);
694 matrix[3] = 0;
695 matrix[4] = 20.f;
696 matrix[5] = 0.213f - 0.213f * amount;
697 matrix[6] = 0.715f + 0.285f * amount;
698 matrix[7] = 1.f - (matrix[5] + matrix[6]);
699 matrix[8] = 0;
700 matrix[9] = 200.f;
701 matrix[10] = 0.213f - 0.213f * amount;
702 matrix[11] = 0.715f - 0.715f * amount;
703 matrix[12] = 1.f - (matrix[10] + matrix[11]);
704 matrix[13] = 0;
705 matrix[14] = 1.5f;
706 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
707 matrix[18] = 1;
708 skia::RefPtr<SkColorFilter> colorFilter(skia::AdoptRef(
709 new SkColorMatrixFilter(matrix)));
710 skia::RefPtr<SkImageFilter> filter =
711 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
713 scoped_ptr<RenderPassDrawQuad> render_pass_quad =
714 RenderPassDrawQuad::Create();
715 render_pass_quad->SetNew(pass_shared_state.get(),
716 pass_rect,
717 child_pass_id,
718 false,
720 pass_rect,
721 gfx::RectF(),
722 FilterOperations(),
723 filter,
724 FilterOperations());
726 root_pass->quad_list.push_back(render_pass_quad.PassAs<DrawQuad>());
727 RenderPassList pass_list;
729 pass_list.push_back(child_pass.Pass());
730 pass_list.push_back(root_pass.Pass());
732 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
733 // renderer so use a fuzzy comparator.
734 EXPECT_TRUE(this->RunPixelTest(
735 &pass_list,
736 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
737 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
740 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) {
741 gfx::Rect viewport_rect(this->device_viewport_size_);
743 RenderPass::Id root_pass_id(1, 1);
744 scoped_ptr<RenderPass> root_pass =
745 CreateTestRootRenderPass(root_pass_id, viewport_rect);
747 RenderPass::Id child_pass_id(2, 2);
748 gfx::Rect pass_rect(this->device_viewport_size_);
749 gfx::Transform transform_to_root;
750 scoped_ptr<RenderPass> child_pass =
751 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
753 gfx::Transform content_to_target_transform;
754 scoped_ptr<SharedQuadState> shared_state =
755 CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
757 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
758 blue->SetNew(shared_state.get(),
759 gfx::Rect(0,
761 this->device_viewport_size_.width(),
762 this->device_viewport_size_.height() / 2),
763 SK_ColorBLUE,
764 false);
765 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
766 yellow->SetNew(shared_state.get(),
767 gfx::Rect(0,
768 this->device_viewport_size_.height() / 2,
769 this->device_viewport_size_.width(),
770 this->device_viewport_size_.height() / 2),
771 SK_ColorYELLOW,
772 false);
774 child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
775 child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
777 scoped_ptr<SharedQuadState> pass_shared_state =
778 CreateTestSharedQuadState(gfx::Transform(), pass_rect);
779 root_pass->quad_list.push_back(
780 CreateTestRenderPassDrawQuad(pass_shared_state.get(),
781 pass_rect,
782 child_pass_id));
784 RenderPassList pass_list;
785 pass_list.push_back(child_pass.Pass());
786 pass_list.push_back(root_pass.Pass());
788 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
790 EXPECT_TRUE(this->RunPixelTest(
791 &pass_list,
792 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
793 ExactPixelComparator(true)));
796 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) {
797 gfx::Rect viewport_rect(this->device_viewport_size_);
799 RenderPass::Id root_pass_id(1, 1);
800 scoped_ptr<RenderPass> root_pass =
801 CreateTestRootRenderPass(root_pass_id, viewport_rect);
803 RenderPass::Id child_pass_id(2, 2);
804 gfx::Rect pass_rect(this->device_viewport_size_);
805 gfx::Transform transform_to_root;
806 scoped_ptr<RenderPass> child_pass =
807 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
809 gfx::Transform content_to_target_transform;
810 scoped_ptr<SharedQuadState> shared_state =
811 CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
813 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
814 blue->SetNew(shared_state.get(),
815 gfx::Rect(0,
817 this->device_viewport_size_.width(),
818 this->device_viewport_size_.height() / 2),
819 SK_ColorBLUE,
820 false);
821 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
822 yellow->SetNew(shared_state.get(),
823 gfx::Rect(0,
824 this->device_viewport_size_.height() / 2,
825 this->device_viewport_size_.width(),
826 this->device_viewport_size_.height() / 2),
827 SK_ColorYELLOW,
828 false);
830 child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
831 child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
833 gfx::Transform aa_transform;
834 aa_transform.Translate(0.5, 0.0);
836 scoped_ptr<SharedQuadState> pass_shared_state =
837 CreateTestSharedQuadState(aa_transform, pass_rect);
838 root_pass->quad_list.push_back(
839 CreateTestRenderPassDrawQuad(pass_shared_state.get(),
840 pass_rect,
841 child_pass_id));
843 scoped_ptr<SharedQuadState> root_shared_state =
844 CreateTestSharedQuadState(gfx::Transform(), viewport_rect);
845 scoped_ptr<SolidColorDrawQuad> background = SolidColorDrawQuad::Create();
846 background->SetNew(root_shared_state.get(),
847 gfx::Rect(this->device_viewport_size_),
848 SK_ColorWHITE,
849 false);
850 root_pass->quad_list.push_back(background.PassAs<DrawQuad>());
852 RenderPassList pass_list;
853 pass_list.push_back(child_pass.Pass());
854 pass_list.push_back(root_pass.Pass());
856 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
858 EXPECT_TRUE(this->RunPixelTest(
859 &pass_list,
860 base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")),
861 FuzzyPixelOffByOneComparator(true)));
864 template <typename RendererType>
865 class RendererPixelTestWithBackgroundFilter
866 : public RendererPixelTest<RendererType> {
867 protected:
868 void SetUpRenderPassList() {
869 gfx::Rect device_viewport_rect(this->device_viewport_size_);
871 RenderPass::Id root_id(1, 1);
872 scoped_ptr<RenderPass> root_pass =
873 CreateTestRootRenderPass(root_id, device_viewport_rect);
874 root_pass->has_transparent_background = false;
876 gfx::Transform identity_content_to_target_transform;
878 RenderPass::Id filter_pass_id(2, 1);
879 gfx::Transform transform_to_root;
880 scoped_ptr<RenderPass> filter_pass =
881 CreateTestRenderPass(filter_pass_id,
882 filter_pass_content_rect_,
883 transform_to_root);
885 // A non-visible quad in the filtering render pass.
887 scoped_ptr<SharedQuadState> shared_state =
888 CreateTestSharedQuadState(identity_content_to_target_transform,
889 filter_pass_content_rect_);
890 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
891 color_quad->SetNew(shared_state.get(),
892 filter_pass_content_rect_,
893 SK_ColorTRANSPARENT,
894 false);
895 filter_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
896 filter_pass->shared_quad_state_list.push_back(shared_state.Pass());
900 scoped_ptr<SharedQuadState> shared_state =
901 CreateTestSharedQuadState(filter_pass_to_target_transform_,
902 filter_pass_content_rect_);
903 scoped_ptr<RenderPassDrawQuad> filter_pass_quad =
904 RenderPassDrawQuad::Create();
905 filter_pass_quad->SetNew(
906 shared_state.get(),
907 filter_pass_content_rect_,
908 filter_pass_id,
909 false, // is_replica
910 0, // mask_resource_id
911 filter_pass_content_rect_, // contents_changed_since_last_frame
912 gfx::RectF(), // mask_uv_rect
913 FilterOperations(), // filters
914 skia::RefPtr<SkImageFilter>(), // filter
915 this->background_filters_);
916 root_pass->quad_list.push_back(filter_pass_quad.PassAs<DrawQuad>());
917 root_pass->shared_quad_state_list.push_back(shared_state.Pass());
920 const int kColumnWidth = device_viewport_rect.width() / 3;
922 gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20);
923 for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) {
924 scoped_ptr<SharedQuadState> shared_state =
925 CreateTestSharedQuadState(identity_content_to_target_transform,
926 left_rect);
927 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
928 color_quad->SetNew(shared_state.get(), left_rect, SK_ColorGREEN, false);
929 root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
930 root_pass->shared_quad_state_list.push_back(shared_state.Pass());
931 left_rect += gfx::Vector2d(0, left_rect.height() + 1);
934 gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20);
935 for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) {
936 scoped_ptr<SharedQuadState> shared_state =
937 CreateTestSharedQuadState(identity_content_to_target_transform,
938 middle_rect);
939 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
940 color_quad->SetNew(shared_state.get(), middle_rect, SK_ColorRED, false);
941 root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
942 root_pass->shared_quad_state_list.push_back(shared_state.Pass());
943 middle_rect += gfx::Vector2d(0, middle_rect.height() + 1);
946 gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20);
947 for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) {
948 scoped_ptr<SharedQuadState> shared_state =
949 CreateTestSharedQuadState(identity_content_to_target_transform,
950 right_rect);
951 scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
952 color_quad->SetNew(shared_state.get(), right_rect, SK_ColorBLUE, false);
953 root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
954 root_pass->shared_quad_state_list.push_back(shared_state.Pass());
955 right_rect += gfx::Vector2d(0, right_rect.height() + 1);
958 scoped_ptr<SharedQuadState> shared_state =
959 CreateTestSharedQuadState(identity_content_to_target_transform,
960 device_viewport_rect);
961 scoped_ptr<SolidColorDrawQuad> background_quad =
962 SolidColorDrawQuad::Create();
963 background_quad->SetNew(shared_state.get(),
964 device_viewport_rect,
965 SK_ColorWHITE,
966 false);
967 root_pass->quad_list.push_back(background_quad.PassAs<DrawQuad>());
968 root_pass->shared_quad_state_list.push_back(shared_state.Pass());
970 pass_list_.push_back(filter_pass.Pass());
971 pass_list_.push_back(root_pass.Pass());
974 RenderPassList pass_list_;
975 FilterOperations background_filters_;
976 gfx::Transform filter_pass_to_target_transform_;
977 gfx::Rect filter_pass_content_rect_;
980 typedef ::testing::Types<GLRenderer, SoftwareRenderer>
981 BackgroundFilterRendererTypes;
982 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter,
983 BackgroundFilterRendererTypes);
985 typedef RendererPixelTestWithBackgroundFilter<GLRenderer>
986 GLRendererPixelTestWithBackgroundFilter;
988 // TODO(skaslev): The software renderer does not support filters yet.
989 TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) {
990 this->background_filters_.Append(
991 FilterOperation::CreateInvertFilter(1.f));
993 this->filter_pass_content_rect_ = gfx::Rect(this->device_viewport_size_);
994 this->filter_pass_content_rect_.Inset(12, 14, 16, 18);
996 this->SetUpRenderPassList();
997 EXPECT_TRUE(this->RunPixelTest(
998 &this->pass_list_,
999 base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
1000 ExactPixelComparator(true)));
1003 class ExternalStencilPixelTest : public GLRendererPixelTest {
1004 protected:
1005 void ClearBackgroundToGreen() {
1006 WebKit::WebGraphicsContext3D* context3d = output_surface_->context3d();
1007 output_surface_->EnsureBackbuffer();
1008 output_surface_->Reshape(device_viewport_size_, 1);
1009 context3d->clearColor(0.f, 1.f, 0.f, 1.f);
1010 context3d->clear(GL_COLOR_BUFFER_BIT);
1013 void PopulateStencilBuffer() {
1014 // Set two quadrants of the stencil buffer to 1.
1015 WebKit::WebGraphicsContext3D* context3d = output_surface_->context3d();
1016 ASSERT_TRUE(context3d->getContextAttributes().stencil);
1017 output_surface_->EnsureBackbuffer();
1018 output_surface_->Reshape(device_viewport_size_, 1);
1019 context3d->clearStencil(0);
1020 context3d->clear(GL_STENCIL_BUFFER_BIT);
1021 context3d->enable(GL_SCISSOR_TEST);
1022 context3d->clearStencil(1);
1023 context3d->scissor(0,
1025 device_viewport_size_.width() / 2,
1026 device_viewport_size_.height() / 2);
1027 context3d->clear(GL_STENCIL_BUFFER_BIT);
1028 context3d->scissor(device_viewport_size_.width() / 2,
1029 device_viewport_size_.height() / 2,
1030 device_viewport_size_.width(),
1031 device_viewport_size_.height());
1032 context3d->clear(GL_STENCIL_BUFFER_BIT);
1036 TEST_F(ExternalStencilPixelTest, StencilTestEnabled) {
1037 ClearBackgroundToGreen();
1038 PopulateStencilBuffer();
1039 this->EnableExternalStencilTest();
1041 // Draw a blue quad that covers the entire device viewport. It should be
1042 // clipped to the bottom left and top right corners by the external stencil.
1043 gfx::Rect rect(this->device_viewport_size_);
1044 RenderPass::Id id(1, 1);
1045 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1046 scoped_ptr<SharedQuadState> blue_shared_state =
1047 CreateTestSharedQuadState(gfx::Transform(), rect);
1048 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
1049 blue->SetNew(blue_shared_state.get(), rect, SK_ColorBLUE, false);
1050 pass->quad_list.push_back(blue.PassAs<DrawQuad>());
1051 pass->has_transparent_background = false;
1052 RenderPassList pass_list;
1053 pass_list.push_back(pass.Pass());
1055 EXPECT_TRUE(this->RunPixelTest(
1056 &pass_list,
1057 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1058 ExactPixelComparator(true)));
1061 TEST_F(ExternalStencilPixelTest, StencilTestDisabled) {
1062 PopulateStencilBuffer();
1064 // Draw a green quad that covers the entire device viewport. The stencil
1065 // buffer should be ignored.
1066 gfx::Rect rect(this->device_viewport_size_);
1067 RenderPass::Id id(1, 1);
1068 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1069 scoped_ptr<SharedQuadState> green_shared_state =
1070 CreateTestSharedQuadState(gfx::Transform(), rect);
1071 scoped_ptr<SolidColorDrawQuad> green = SolidColorDrawQuad::Create();
1072 green->SetNew(green_shared_state.get(), rect, SK_ColorGREEN, false);
1073 pass->quad_list.push_back(green.PassAs<DrawQuad>());
1074 RenderPassList pass_list;
1075 pass_list.push_back(pass.Pass());
1077 EXPECT_TRUE(this->RunPixelTest(
1078 &pass_list,
1079 base::FilePath(FILE_PATH_LITERAL("green.png")),
1080 ExactPixelComparator(true)));
1083 TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) {
1084 // The stencil test should apply only to the final render pass.
1085 ClearBackgroundToGreen();
1086 PopulateStencilBuffer();
1087 this->EnableExternalStencilTest();
1089 gfx::Rect viewport_rect(this->device_viewport_size_);
1091 RenderPass::Id root_pass_id(1, 1);
1092 scoped_ptr<RenderPass> root_pass =
1093 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1094 root_pass->has_transparent_background = false;
1096 RenderPass::Id child_pass_id(2, 2);
1097 gfx::Rect pass_rect(this->device_viewport_size_);
1098 gfx::Transform transform_to_root;
1099 scoped_ptr<RenderPass> child_pass =
1100 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1102 gfx::Transform content_to_target_transform;
1103 scoped_ptr<SharedQuadState> shared_state =
1104 CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
1106 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
1107 blue->SetNew(shared_state.get(),
1108 gfx::Rect(0,
1110 this->device_viewport_size_.width(),
1111 this->device_viewport_size_.height()),
1112 SK_ColorBLUE,
1113 false);
1114 child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
1116 scoped_ptr<SharedQuadState> pass_shared_state =
1117 CreateTestSharedQuadState(gfx::Transform(), pass_rect);
1118 root_pass->quad_list.push_back(
1119 CreateTestRenderPassDrawQuad(pass_shared_state.get(),
1120 pass_rect,
1121 child_pass_id));
1122 RenderPassList pass_list;
1123 pass_list.push_back(child_pass.Pass());
1124 pass_list.push_back(root_pass.Pass());
1126 EXPECT_TRUE(this->RunPixelTest(
1127 &pass_list,
1128 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1129 ExactPixelComparator(true)));
1132 // Software renderer does not support anti-aliased edges.
1133 TEST_F(GLRendererPixelTest, AntiAliasing) {
1134 gfx::Rect rect(this->device_viewport_size_);
1136 RenderPass::Id id(1, 1);
1137 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1139 gfx::Transform red_content_to_target_transform;
1140 red_content_to_target_transform.Rotate(10);
1141 scoped_ptr<SharedQuadState> red_shared_state =
1142 CreateTestSharedQuadState(red_content_to_target_transform, rect);
1144 scoped_ptr<SolidColorDrawQuad> red = SolidColorDrawQuad::Create();
1145 red->SetNew(red_shared_state.get(), rect, SK_ColorRED, false);
1147 pass->quad_list.push_back(red.PassAs<DrawQuad>());
1149 gfx::Transform yellow_content_to_target_transform;
1150 yellow_content_to_target_transform.Rotate(5);
1151 scoped_ptr<SharedQuadState> yellow_shared_state =
1152 CreateTestSharedQuadState(yellow_content_to_target_transform, rect);
1154 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
1155 yellow->SetNew(yellow_shared_state.get(), rect, SK_ColorYELLOW, false);
1157 pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
1159 gfx::Transform blue_content_to_target_transform;
1160 scoped_ptr<SharedQuadState> blue_shared_state =
1161 CreateTestSharedQuadState(blue_content_to_target_transform, rect);
1163 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
1164 blue->SetNew(blue_shared_state.get(), rect, SK_ColorBLUE, false);
1166 pass->quad_list.push_back(blue.PassAs<DrawQuad>());
1168 RenderPassList pass_list;
1169 pass_list.push_back(pass.Pass());
1171 EXPECT_TRUE(this->RunPixelTest(
1172 &pass_list,
1173 base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")),
1174 FuzzyPixelOffByOneComparator(true)));
1177 // This test tests that anti-aliasing works for axis aligned quads.
1178 // Anti-aliasing is only supported in the gl renderer.
1179 TEST_F(GLRendererPixelTest, AxisAligned) {
1180 gfx::Rect rect(this->device_viewport_size_);
1182 RenderPass::Id id(1, 1);
1183 gfx::Transform transform_to_root;
1184 scoped_ptr<RenderPass> pass =
1185 CreateTestRenderPass(id, rect, transform_to_root);
1187 gfx::Transform red_content_to_target_transform;
1188 red_content_to_target_transform.Translate(50, 50);
1189 red_content_to_target_transform.Scale(
1190 0.5f + 1.0f / (rect.width() * 2.0f),
1191 0.5f + 1.0f / (rect.height() * 2.0f));
1192 scoped_ptr<SharedQuadState> red_shared_state =
1193 CreateTestSharedQuadState(red_content_to_target_transform, rect);
1195 scoped_ptr<SolidColorDrawQuad> red = SolidColorDrawQuad::Create();
1196 red->SetNew(red_shared_state.get(), rect, SK_ColorRED, false);
1198 pass->quad_list.push_back(red.PassAs<DrawQuad>());
1200 gfx::Transform yellow_content_to_target_transform;
1201 yellow_content_to_target_transform.Translate(25.5f, 25.5f);
1202 yellow_content_to_target_transform.Scale(0.5f, 0.5f);
1203 scoped_ptr<SharedQuadState> yellow_shared_state =
1204 CreateTestSharedQuadState(yellow_content_to_target_transform, rect);
1206 scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
1207 yellow->SetNew(yellow_shared_state.get(), rect, SK_ColorYELLOW, false);
1209 pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
1211 gfx::Transform blue_content_to_target_transform;
1212 scoped_ptr<SharedQuadState> blue_shared_state =
1213 CreateTestSharedQuadState(blue_content_to_target_transform, rect);
1215 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
1216 blue->SetNew(blue_shared_state.get(), rect, SK_ColorBLUE, false);
1218 pass->quad_list.push_back(blue.PassAs<DrawQuad>());
1220 RenderPassList pass_list;
1221 pass_list.push_back(pass.Pass());
1223 EXPECT_TRUE(this->RunPixelTest(
1224 &pass_list,
1225 base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")),
1226 ExactPixelComparator(true)));
1229 // This test tests that forcing anti-aliasing off works as expected.
1230 // Anti-aliasing is only supported in the gl renderer.
1231 TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) {
1232 gfx::Rect rect(this->device_viewport_size_);
1234 RenderPass::Id id(1, 1);
1235 gfx::Transform transform_to_root;
1236 scoped_ptr<RenderPass> pass =
1237 CreateTestRenderPass(id, rect, transform_to_root);
1239 gfx::Transform hole_content_to_target_transform;
1240 hole_content_to_target_transform.Translate(50, 50);
1241 hole_content_to_target_transform.Scale(
1242 0.5f + 1.0f / (rect.width() * 2.0f),
1243 0.5f + 1.0f / (rect.height() * 2.0f));
1244 scoped_ptr<SharedQuadState> hole_shared_state =
1245 CreateTestSharedQuadState(hole_content_to_target_transform, rect);
1247 scoped_ptr<SolidColorDrawQuad> hole = SolidColorDrawQuad::Create();
1248 hole->SetAll(hole_shared_state.get(), rect, rect, rect, false,
1249 SK_ColorTRANSPARENT, true);
1250 pass->quad_list.push_back(hole.PassAs<DrawQuad>());
1252 gfx::Transform green_content_to_target_transform;
1253 scoped_ptr<SharedQuadState> green_shared_state =
1254 CreateTestSharedQuadState(green_content_to_target_transform, rect);
1256 scoped_ptr<SolidColorDrawQuad> green = SolidColorDrawQuad::Create();
1257 green->SetNew(green_shared_state.get(), rect, SK_ColorGREEN, false);
1259 pass->quad_list.push_back(green.PassAs<DrawQuad>());
1261 RenderPassList pass_list;
1262 pass_list.push_back(pass.Pass());
1264 EXPECT_TRUE(this->RunPixelTest(
1265 &pass_list,
1266 base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")),
1267 ExactPixelComparator(false)));
1270 TEST_F(GLRendererPixelTest, AntiAliasingPerspective) {
1271 gfx::Rect rect(this->device_viewport_size_);
1273 scoped_ptr<RenderPass> pass =
1274 CreateTestRootRenderPass(RenderPass::Id(1, 1), rect);
1276 gfx::Rect red_rect(0, 0, 180, 500);
1277 gfx::Transform red_content_to_target_transform(
1278 1.0, 2.4520, 10.6206, 19.0,
1279 0.0, 0.3528, 5.9737, 9.5,
1280 0.0, -0.2250, -0.9744, 0.0,
1281 0.0, 0.0225, 0.0974, 1.0);
1282 scoped_ptr<SharedQuadState> red_shared_state =
1283 CreateTestSharedQuadState(red_content_to_target_transform, red_rect);
1284 scoped_ptr<SolidColorDrawQuad> red = SolidColorDrawQuad::Create();
1285 red->SetNew(red_shared_state.get(), red_rect, SK_ColorRED, false);
1286 pass->quad_list.push_back(red.PassAs<DrawQuad>());
1288 gfx::Rect green_rect(19, 7, 180, 10);
1289 scoped_ptr<SharedQuadState> green_shared_state =
1290 CreateTestSharedQuadState(gfx::Transform(), green_rect);
1291 scoped_ptr<SolidColorDrawQuad> green = SolidColorDrawQuad::Create();
1292 green->SetNew(green_shared_state.get(), green_rect, SK_ColorGREEN, false);
1293 pass->quad_list.push_back(green.PassAs<DrawQuad>());
1295 scoped_ptr<SharedQuadState> blue_shared_state =
1296 CreateTestSharedQuadState(gfx::Transform(), rect);
1297 scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
1298 blue->SetNew(blue_shared_state.get(), rect, SK_ColorBLUE, false);
1299 pass->quad_list.push_back(blue.PassAs<DrawQuad>());
1301 RenderPassList pass_list;
1302 pass_list.push_back(pass.Pass());
1304 EXPECT_TRUE(this->RunPixelTest(
1305 &pass_list,
1306 base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")),
1307 FuzzyPixelOffByOneComparator(true)));
1310 TYPED_TEST(RendererPixelTestWithSkiaGPUBackend, PictureDrawQuadIdentityScale) {
1311 gfx::Size pile_tile_size(1000, 1000);
1312 gfx::Rect viewport(this->device_viewport_size_);
1313 bool use_skia_gpu_backend = this->UseSkiaGPUBackend();
1314 // TODO(enne): the renderer should figure this out on its own.
1315 bool contents_swizzled = !PlatformColor::SameComponentOrder(GL_RGBA);
1317 RenderPass::Id id(1, 1);
1318 gfx::Transform transform_to_root;
1319 scoped_ptr<RenderPass> pass =
1320 CreateTestRenderPass(id, viewport, transform_to_root);
1322 // One clipped blue quad in the lower right corner. Outside the clip
1323 // is red, which should not appear.
1324 gfx::Rect blue_rect(gfx::Size(100, 100));
1325 gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50));
1326 scoped_refptr<FakePicturePileImpl> blue_pile =
1327 FakePicturePileImpl::CreateFilledPile(pile_tile_size, blue_rect.size());
1328 SkPaint red_paint;
1329 red_paint.setColor(SK_ColorRED);
1330 blue_pile->add_draw_rect_with_paint(blue_rect, red_paint);
1331 SkPaint blue_paint;
1332 blue_paint.setColor(SK_ColorBLUE);
1333 blue_pile->add_draw_rect_with_paint(blue_clip_rect, blue_paint);
1334 blue_pile->RerecordPile();
1336 gfx::Transform blue_content_to_target_transform;
1337 gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right());
1338 blue_content_to_target_transform.Translate(offset.x(), offset.y());
1339 gfx::RectF blue_scissor_rect = blue_clip_rect;
1340 blue_content_to_target_transform.TransformRect(&blue_scissor_rect);
1341 scoped_ptr<SharedQuadState> blue_shared_state =
1342 CreateTestSharedQuadStateClipped(blue_content_to_target_transform,
1343 blue_rect,
1344 gfx::ToEnclosingRect(blue_scissor_rect));
1346 scoped_ptr<PictureDrawQuad> blue_quad = PictureDrawQuad::Create();
1348 blue_quad->SetNew(blue_shared_state.get(),
1349 viewport, // Intentionally bigger than clip.
1350 gfx::Rect(),
1351 viewport,
1352 viewport.size(),
1353 contents_swizzled,
1354 viewport,
1355 1.f,
1356 use_skia_gpu_backend,
1357 blue_pile);
1358 pass->quad_list.push_back(blue_quad.PassAs<DrawQuad>());
1360 // One viewport-filling green quad.
1361 scoped_refptr<FakePicturePileImpl> green_pile =
1362 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size());
1363 SkPaint green_paint;
1364 green_paint.setColor(SK_ColorGREEN);
1365 green_pile->add_draw_rect_with_paint(viewport, green_paint);
1366 green_pile->RerecordPile();
1368 gfx::Transform green_content_to_target_transform;
1369 scoped_ptr<SharedQuadState> green_shared_state =
1370 CreateTestSharedQuadState(green_content_to_target_transform, viewport);
1372 scoped_ptr<PictureDrawQuad> green_quad = PictureDrawQuad::Create();
1373 green_quad->SetNew(green_shared_state.get(),
1374 viewport,
1375 gfx::Rect(),
1376 gfx::RectF(0.f, 0.f, 1.f, 1.f),
1377 viewport.size(),
1378 contents_swizzled,
1379 viewport,
1380 1.f,
1381 use_skia_gpu_backend,
1382 green_pile);
1383 pass->quad_list.push_back(green_quad.PassAs<DrawQuad>());
1385 RenderPassList pass_list;
1386 pass_list.push_back(pass.Pass());
1388 EXPECT_TRUE(this->RunPixelTest(
1389 &pass_list,
1390 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
1391 ExactPixelComparator(true)));
1394 TYPED_TEST(RendererPixelTestWithSkiaGPUBackend,
1395 PictureDrawQuadNonIdentityScale) {
1396 gfx::Size pile_tile_size(1000, 1000);
1397 gfx::Rect viewport(this->device_viewport_size_);
1398 bool use_skia_gpu_backend = this->UseSkiaGPUBackend();
1399 // TODO(enne): the renderer should figure this out on its own.
1400 bool contents_swizzled = !PlatformColor::SameComponentOrder(GL_RGBA);
1402 RenderPass::Id id(1, 1);
1403 gfx::Transform transform_to_root;
1404 scoped_ptr<RenderPass> pass =
1405 CreateTestRenderPass(id, viewport, transform_to_root);
1407 // As scaling up the blue checkerboards will cause sampling on the GPU,
1408 // a few extra "cleanup rects" need to be added to clobber the blending
1409 // to make the output image more clean. This will also test subrects
1410 // of the layer.
1411 gfx::Transform green_content_to_target_transform;
1412 gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100));
1413 gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20));
1414 scoped_refptr<FakePicturePileImpl> green_pile =
1415 FakePicturePileImpl::CreateFilledPile(pile_tile_size, viewport.size());
1416 SkPaint red_paint;
1417 red_paint.setColor(SK_ColorRED);
1418 green_pile->add_draw_rect_with_paint(viewport, red_paint);
1419 SkPaint green_paint;
1420 green_paint.setColor(SK_ColorGREEN);
1421 green_pile->add_draw_rect_with_paint(green_rect1, green_paint);
1422 green_pile->add_draw_rect_with_paint(green_rect2, green_paint);
1423 green_pile->RerecordPile();
1425 scoped_ptr<SharedQuadState> top_right_green_shared_quad_state =
1426 CreateTestSharedQuadState(green_content_to_target_transform, viewport);
1428 scoped_ptr<PictureDrawQuad> green_quad1 = PictureDrawQuad::Create();
1429 green_quad1->SetNew(top_right_green_shared_quad_state.get(),
1430 green_rect1,
1431 gfx::Rect(),
1432 gfx::RectF(green_rect1.size()),
1433 green_rect1.size(),
1434 contents_swizzled,
1435 green_rect1,
1436 1.f,
1437 use_skia_gpu_backend,
1438 green_pile);
1439 pass->quad_list.push_back(green_quad1.PassAs<DrawQuad>());
1441 scoped_ptr<PictureDrawQuad> green_quad2 = PictureDrawQuad::Create();
1442 green_quad2->SetNew(top_right_green_shared_quad_state.get(),
1443 green_rect2,
1444 gfx::Rect(),
1445 gfx::RectF(green_rect2.size()),
1446 green_rect2.size(),
1447 contents_swizzled,
1448 green_rect2,
1449 1.f,
1450 use_skia_gpu_backend,
1451 green_pile);
1452 pass->quad_list.push_back(green_quad2.PassAs<DrawQuad>());
1454 // Add a green clipped checkerboard in the bottom right to help test
1455 // interleaving picture quad content and solid color content.
1456 gfx::Rect bottom_right_rect(
1457 gfx::Point(viewport.width() / 2, viewport.height() / 2),
1458 gfx::Size(viewport.width() / 2, viewport.height() / 2));
1459 scoped_ptr<SharedQuadState> bottom_right_green_shared_state =
1460 CreateTestSharedQuadStateClipped(
1461 green_content_to_target_transform, viewport, bottom_right_rect);
1462 scoped_ptr<SolidColorDrawQuad> bottom_right_color_quad =
1463 SolidColorDrawQuad::Create();
1464 bottom_right_color_quad->SetNew(
1465 bottom_right_green_shared_state.get(), viewport, SK_ColorGREEN, false);
1466 pass->quad_list.push_back(bottom_right_color_quad.PassAs<DrawQuad>());
1468 // Add two blue checkerboards taking up the bottom left and top right,
1469 // but use content scales as content rects to make this happen.
1470 // The content is at a 4x content scale.
1471 gfx::Rect layer_rect(gfx::Size(20, 30));
1472 float contents_scale = 4.f;
1473 // Two rects that touch at their corners, arbitrarily placed in the layer.
1474 gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f));
1475 gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f));
1476 gfx::RectF union_layer_rect = blue_layer_rect1;
1477 union_layer_rect.Union(blue_layer_rect2);
1479 // Because scaling up will cause sampling outside the rects, add one extra
1480 // pixel of buffer at the final content scale.
1481 float inset = -1.f / contents_scale;
1482 blue_layer_rect1.Inset(inset, inset, inset, inset);
1483 blue_layer_rect2.Inset(inset, inset, inset, inset);
1485 scoped_refptr<FakePicturePileImpl> pile =
1486 FakePicturePileImpl::CreateFilledPile(pile_tile_size, layer_rect.size());
1488 Region outside(layer_rect);
1489 outside.Subtract(gfx::ToEnclosingRect(union_layer_rect));
1490 for (Region::Iterator iter(outside); iter.has_rect(); iter.next()) {
1491 pile->add_draw_rect_with_paint(iter.rect(), red_paint);
1494 SkPaint blue_paint;
1495 blue_paint.setColor(SK_ColorBLUE);
1496 pile->add_draw_rect_with_paint(blue_layer_rect1, blue_paint);
1497 pile->add_draw_rect_with_paint(blue_layer_rect2, blue_paint);
1498 pile->RerecordPile();
1500 gfx::Rect content_rect(
1501 gfx::ScaleToEnclosingRect(layer_rect, contents_scale));
1502 gfx::Rect content_union_rect(
1503 gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale)));
1505 // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels,
1506 // so scale an additional 10x to make them 100x100.
1507 gfx::Transform content_to_target_transform;
1508 content_to_target_transform.Scale(10.0, 10.0);
1509 gfx::Rect quad_content_rect(gfx::Size(20, 20));
1510 scoped_ptr<SharedQuadState> blue_shared_state =
1511 CreateTestSharedQuadState(content_to_target_transform, quad_content_rect);
1513 scoped_ptr<PictureDrawQuad> blue_quad = PictureDrawQuad::Create();
1514 blue_quad->SetNew(blue_shared_state.get(),
1515 quad_content_rect,
1516 gfx::Rect(),
1517 quad_content_rect,
1518 content_union_rect.size(),
1519 contents_swizzled,
1520 content_union_rect,
1521 contents_scale,
1522 use_skia_gpu_backend,
1523 pile);
1524 pass->quad_list.push_back(blue_quad.PassAs<DrawQuad>());
1526 // Fill left half of viewport with green.
1527 gfx::Transform half_green_content_to_target_transform;
1528 gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height()));
1529 scoped_ptr<SharedQuadState> half_green_shared_state =
1530 CreateTestSharedQuadState(half_green_content_to_target_transform,
1531 half_green_rect);
1532 scoped_ptr<SolidColorDrawQuad> half_color_quad = SolidColorDrawQuad::Create();
1533 half_color_quad->SetNew(
1534 half_green_shared_state.get(), half_green_rect, SK_ColorGREEN, false);
1535 pass->quad_list.push_back(half_color_quad.PassAs<DrawQuad>());
1537 RenderPassList pass_list;
1538 pass_list.push_back(pass.Pass());
1540 EXPECT_TRUE(this->RunPixelTest(
1541 &pass_list,
1542 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1543 ExactPixelComparator(true)));
1545 #endif // !defined(OS_ANDROID)
1547 } // namespace
1548 } // namespace cc