Use multiline attribute to check for IA2_STATE_MULTILINE.
[chromium-blink-merge.git] / cc / output / renderer_pixeltest.cc
blobbfad4ba0c1e9d45e49035ebd938d205376499c8f
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/output/gl_renderer.h"
7 #include "cc/quads/draw_quad.h"
8 #include "cc/quads/picture_draw_quad.h"
9 #include "cc/quads/texture_draw_quad.h"
10 #include "cc/resources/video_resource_updater.h"
11 #include "cc/test/fake_picture_pile_impl.h"
12 #include "cc/test/pixel_test.h"
13 #include "gpu/command_buffer/client/gles2_interface.h"
14 #include "media/base/video_frame.h"
15 #include "third_party/skia/include/core/SkColorPriv.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/geometry/rect_conversions.h"
22 using gpu::gles2::GLES2Interface;
24 namespace cc {
25 namespace {
27 #if !defined(OS_ANDROID)
28 scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPassId id,
29 const gfx::Rect& rect) {
30 scoped_ptr<RenderPass> pass = RenderPass::Create();
31 const gfx::Rect output_rect = rect;
32 const gfx::Rect damage_rect = rect;
33 const gfx::Transform transform_to_root_target;
34 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
35 return pass.Pass();
38 scoped_ptr<RenderPass> CreateTestRenderPass(
39 RenderPassId id,
40 const gfx::Rect& rect,
41 const gfx::Transform& transform_to_root_target) {
42 scoped_ptr<RenderPass> pass = RenderPass::Create();
43 const gfx::Rect output_rect = rect;
44 const gfx::Rect damage_rect = rect;
45 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
46 return pass.Pass();
49 SharedQuadState* CreateTestSharedQuadState(
50 gfx::Transform content_to_target_transform,
51 const gfx::Rect& rect,
52 RenderPass* render_pass) {
53 const gfx::Size content_bounds = rect.size();
54 const gfx::Rect visible_content_rect = rect;
55 const gfx::Rect clip_rect = rect;
56 const bool is_clipped = false;
57 const float opacity = 1.0f;
58 const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
59 int sorting_context_id = 0;
60 SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
61 shared_state->SetAll(content_to_target_transform,
62 content_bounds,
63 visible_content_rect,
64 clip_rect,
65 is_clipped,
66 opacity,
67 blend_mode,
68 sorting_context_id);
69 return shared_state;
72 SharedQuadState* CreateTestSharedQuadStateClipped(
73 gfx::Transform content_to_target_transform,
74 const gfx::Rect& rect,
75 const gfx::Rect& clip_rect,
76 RenderPass* render_pass) {
77 const gfx::Size content_bounds = rect.size();
78 const gfx::Rect visible_content_rect = clip_rect;
79 const bool is_clipped = true;
80 const float opacity = 1.0f;
81 const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
82 int sorting_context_id = 0;
83 SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
84 shared_state->SetAll(content_to_target_transform,
85 content_bounds,
86 visible_content_rect,
87 clip_rect,
88 is_clipped,
89 opacity,
90 blend_mode,
91 sorting_context_id);
92 return shared_state;
95 void CreateTestRenderPassDrawQuad(const SharedQuadState* shared_state,
96 const gfx::Rect& rect,
97 RenderPassId pass_id,
98 RenderPass* render_pass) {
99 RenderPassDrawQuad* quad =
100 render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
101 quad->SetNew(shared_state,
102 rect,
103 rect,
104 pass_id,
105 0, // mask_resource_id
106 gfx::Vector2dF(), // mask_uv_scale
107 gfx::Size(), // mask_texture_size
108 FilterOperations(), // foreground filters
109 gfx::Vector2dF(), // filters scale
110 FilterOperations()); // background filters
113 void CreateTestTwoColoredTextureDrawQuad(const gfx::Rect& rect,
114 SkColor texel_color,
115 SkColor texel_stripe_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 SkPMColor pixel_stripe_color =
128 premultiplied_alpha
129 ? SkPreMultiplyColor(texel_stripe_color)
130 : SkPackARGB32NoCheck(SkColorGetA(texel_stripe_color),
131 SkColorGetR(texel_stripe_color),
132 SkColorGetG(texel_stripe_color),
133 SkColorGetB(texel_stripe_color));
134 std::vector<uint32_t> pixels(rect.size().GetArea(), pixel_color);
135 for (int i = rect.height() / 4; i < (rect.height() * 3 / 4); ++i) {
136 for (int k = rect.width() / 4; k < (rect.width() * 3 / 4); ++k) {
137 pixels[i * rect.width() + k] = pixel_stripe_color;
140 ResourceProvider::ResourceId resource = resource_provider->CreateResource(
141 rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
142 RGBA_8888);
143 resource_provider->SetPixels(resource,
144 reinterpret_cast<uint8_t*>(&pixels.front()),
145 rect, rect, gfx::Vector2d());
147 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
148 const gfx::PointF uv_top_left(0.0f, 0.0f);
149 const gfx::PointF uv_bottom_right(1.0f, 1.0f);
150 const bool flipped = false;
151 const bool nearest_neighbor = false;
152 TextureDrawQuad* quad =
153 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
154 quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource,
155 premultiplied_alpha, uv_top_left, uv_bottom_right,
156 background_color, vertex_opacity, flipped, nearest_neighbor);
159 void CreateTestTextureDrawQuad(const gfx::Rect& rect,
160 SkColor texel_color,
161 SkColor background_color,
162 bool premultiplied_alpha,
163 const SharedQuadState* shared_state,
164 ResourceProvider* resource_provider,
165 RenderPass* render_pass) {
166 SkPMColor pixel_color = premultiplied_alpha ?
167 SkPreMultiplyColor(texel_color) :
168 SkPackARGB32NoCheck(SkColorGetA(texel_color),
169 SkColorGetR(texel_color),
170 SkColorGetG(texel_color),
171 SkColorGetB(texel_color));
172 size_t num_pixels = static_cast<size_t>(rect.width()) * rect.height();
173 std::vector<uint32_t> pixels(num_pixels, pixel_color);
175 ResourceProvider::ResourceId resource = resource_provider->CreateResource(
176 rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
177 RGBA_8888);
178 resource_provider->CopyToResource(
179 resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size());
181 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
183 const gfx::PointF uv_top_left(0.0f, 0.0f);
184 const gfx::PointF uv_bottom_right(1.0f, 1.0f);
185 const bool flipped = false;
186 const bool nearest_neighbor = false;
187 TextureDrawQuad* quad =
188 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
189 quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource,
190 premultiplied_alpha, uv_top_left, uv_bottom_right,
191 background_color, vertex_opacity, flipped, nearest_neighbor);
194 void CreateTestYUVVideoDrawQuad_FromVideoFrame(
195 const SharedQuadState* shared_state,
196 scoped_refptr<media::VideoFrame> video_frame,
197 uint8 alpha_value,
198 const gfx::RectF& tex_coord_rect,
199 RenderPass* render_pass,
200 VideoResourceUpdater* video_resource_updater,
201 const gfx::Rect& rect,
202 const gfx::Rect& visible_rect,
203 ResourceProvider* resource_provider) {
204 const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A);
205 const YUVVideoDrawQuad::ColorSpace color_space =
206 (video_frame->format() == media::VideoFrame::YV12J
207 ? YUVVideoDrawQuad::JPEG
208 : YUVVideoDrawQuad::REC_601);
209 const gfx::Rect opaque_rect(0, 0, 0, 0);
211 if (with_alpha) {
212 memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value,
213 video_frame->stride(media::VideoFrame::kAPlane) *
214 video_frame->rows(media::VideoFrame::kAPlane));
217 VideoFrameExternalResources resources =
218 video_resource_updater->CreateExternalResourcesFromVideoFrame(
219 video_frame);
221 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
222 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
223 resources.mailboxes.size());
224 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
225 resources.release_callbacks.size());
227 ResourceProvider::ResourceId y_resource =
228 resource_provider->CreateResourceFromTextureMailbox(
229 resources.mailboxes[media::VideoFrame::kYPlane],
230 SingleReleaseCallbackImpl::Create(
231 resources.release_callbacks[media::VideoFrame::kYPlane]));
232 ResourceProvider::ResourceId u_resource =
233 resource_provider->CreateResourceFromTextureMailbox(
234 resources.mailboxes[media::VideoFrame::kUPlane],
235 SingleReleaseCallbackImpl::Create(
236 resources.release_callbacks[media::VideoFrame::kUPlane]));
237 ResourceProvider::ResourceId v_resource =
238 resource_provider->CreateResourceFromTextureMailbox(
239 resources.mailboxes[media::VideoFrame::kVPlane],
240 SingleReleaseCallbackImpl::Create(
241 resources.release_callbacks[media::VideoFrame::kVPlane]));
242 ResourceProvider::ResourceId a_resource = 0;
243 if (with_alpha) {
244 a_resource = resource_provider->CreateResourceFromTextureMailbox(
245 resources.mailboxes[media::VideoFrame::kAPlane],
246 SingleReleaseCallbackImpl::Create(
247 resources.release_callbacks[media::VideoFrame::kAPlane]));
250 const gfx::Size ya_tex_size = video_frame->coded_size();
251 const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize(
252 video_frame->format(), media::VideoFrame::kUPlane,
253 video_frame->coded_size());
254 DCHECK(uv_tex_size == media::VideoFrame::PlaneSize(
255 video_frame->format(), media::VideoFrame::kVPlane,
256 video_frame->coded_size()));
257 if (with_alpha) {
258 DCHECK(ya_tex_size == media::VideoFrame::PlaneSize(
259 video_frame->format(), media::VideoFrame::kAPlane,
260 video_frame->coded_size()));
263 YUVVideoDrawQuad* yuv_quad =
264 render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
265 yuv_quad->SetNew(shared_state, rect, opaque_rect, visible_rect,
266 tex_coord_rect, ya_tex_size, uv_tex_size, y_resource,
267 u_resource, v_resource, a_resource, color_space);
270 void CreateTestYUVVideoDrawQuad_Striped(
271 const SharedQuadState* shared_state,
272 media::VideoFrame::Format format,
273 bool is_transparent,
274 const gfx::RectF& tex_coord_rect,
275 RenderPass* render_pass,
276 VideoResourceUpdater* video_resource_updater,
277 const gfx::Rect& rect,
278 const gfx::Rect& visible_rect,
279 ResourceProvider* resource_provider) {
280 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
281 format, rect.size(), rect, rect.size(), base::TimeDelta());
283 // YUV values representing a striped pattern, for validating texture
284 // coordinates for sampling.
285 uint8_t y_value = 0;
286 uint8_t u_value = 0;
287 uint8_t v_value = 0;
288 for (int i = 0; i < video_frame->rows(media::VideoFrame::kYPlane); ++i) {
289 uint8_t* y_row = video_frame->data(media::VideoFrame::kYPlane) +
290 video_frame->stride(media::VideoFrame::kYPlane) * i;
291 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kYPlane);
292 ++j) {
293 y_row[j] = (y_value += 1);
296 for (int i = 0; i < video_frame->rows(media::VideoFrame::kUPlane); ++i) {
297 uint8_t* u_row = video_frame->data(media::VideoFrame::kUPlane) +
298 video_frame->stride(media::VideoFrame::kUPlane) * i;
299 uint8_t* v_row = video_frame->data(media::VideoFrame::kVPlane) +
300 video_frame->stride(media::VideoFrame::kVPlane) * i;
301 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kUPlane);
302 ++j) {
303 u_row[j] = (u_value += 3);
304 v_row[j] = (v_value += 5);
307 uint8 alpha_value = is_transparent ? 0 : 128;
308 CreateTestYUVVideoDrawQuad_FromVideoFrame(
309 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
310 video_resource_updater, rect, visible_rect, resource_provider);
313 // Creates a video frame of size background_size filled with yuv_background,
314 // and then draws a foreground rectangle in a different color on top of
315 // that. The foreground rectangle must have coordinates that are divisible
316 // by 2 because YUV is a block format.
317 void CreateTestYUVVideoDrawQuad_TwoColor(
318 const SharedQuadState* shared_state,
319 media::VideoFrame::Format format,
320 bool is_transparent,
321 const gfx::RectF& tex_coord_rect,
322 const gfx::Size& background_size,
323 const gfx::Rect& visible_rect,
324 uint8 y_background,
325 uint8 u_background,
326 uint8 v_background,
327 const gfx::Rect& foreground_rect,
328 uint8 y_foreground,
329 uint8 u_foreground,
330 uint8 v_foreground,
331 RenderPass* render_pass,
332 VideoResourceUpdater* video_resource_updater,
333 ResourceProvider* resource_provider) {
334 const gfx::Rect rect(background_size);
336 scoped_refptr<media::VideoFrame> video_frame =
337 media::VideoFrame::CreateFrame(format, background_size, foreground_rect,
338 foreground_rect.size(), base::TimeDelta());
340 int planes[] = {media::VideoFrame::kYPlane,
341 media::VideoFrame::kUPlane,
342 media::VideoFrame::kVPlane};
343 uint8 yuv_background[] = {y_background, u_background, v_background};
344 uint8 yuv_foreground[] = {y_foreground, u_foreground, v_foreground};
345 int sample_size[] = {1, 2, 2};
347 for (int i = 0; i < 3; ++i) {
348 memset(video_frame->data(planes[i]), yuv_background[i],
349 video_frame->stride(planes[i]) * video_frame->rows(planes[i]));
352 for (int i = 0; i < 3; ++i) {
353 // Since yuv encoding uses block encoding, widths have to be divisible
354 // by the sample size in order for this function to behave properly.
355 DCHECK_EQ(foreground_rect.x() % sample_size[i], 0);
356 DCHECK_EQ(foreground_rect.y() % sample_size[i], 0);
357 DCHECK_EQ(foreground_rect.width() % sample_size[i], 0);
358 DCHECK_EQ(foreground_rect.height() % sample_size[i], 0);
360 gfx::Rect sample_rect(foreground_rect.x() / sample_size[i],
361 foreground_rect.y() / sample_size[i],
362 foreground_rect.width() / sample_size[i],
363 foreground_rect.height() / sample_size[i]);
364 for (int y = sample_rect.y(); y < sample_rect.bottom(); ++y) {
365 for (int x = sample_rect.x(); x < sample_rect.right(); ++x) {
366 size_t offset = y * video_frame->stride(planes[i]) + x;
367 video_frame->data(planes[i])[offset] = yuv_foreground[i];
372 uint8 alpha_value = 255;
373 CreateTestYUVVideoDrawQuad_FromVideoFrame(
374 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
375 video_resource_updater, rect, visible_rect, resource_provider);
378 void CreateTestYUVVideoDrawQuad_Solid(
379 const SharedQuadState* shared_state,
380 media::VideoFrame::Format format,
381 bool is_transparent,
382 const gfx::RectF& tex_coord_rect,
383 uint8 y,
384 uint8 u,
385 uint8 v,
386 RenderPass* render_pass,
387 VideoResourceUpdater* video_resource_updater,
388 const gfx::Rect& rect,
389 const gfx::Rect& visible_rect,
390 ResourceProvider* resource_provider) {
391 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
392 format, rect.size(), rect, rect.size(), base::TimeDelta());
394 // YUV values of a solid, constant, color. Useful for testing that color
395 // space/color range are being handled properly.
396 memset(video_frame->data(media::VideoFrame::kYPlane), y,
397 video_frame->stride(media::VideoFrame::kYPlane) *
398 video_frame->rows(media::VideoFrame::kYPlane));
399 memset(video_frame->data(media::VideoFrame::kUPlane), u,
400 video_frame->stride(media::VideoFrame::kUPlane) *
401 video_frame->rows(media::VideoFrame::kUPlane));
402 memset(video_frame->data(media::VideoFrame::kVPlane), v,
403 video_frame->stride(media::VideoFrame::kVPlane) *
404 video_frame->rows(media::VideoFrame::kVPlane));
406 uint8 alpha_value = is_transparent ? 0 : 128;
407 CreateTestYUVVideoDrawQuad_FromVideoFrame(
408 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
409 video_resource_updater, rect, visible_rect, resource_provider);
412 typedef ::testing::Types<GLRenderer,
413 SoftwareRenderer,
414 GLRendererWithExpandedViewport,
415 SoftwareRendererWithExpandedViewport> RendererTypes;
416 TYPED_TEST_CASE(RendererPixelTest, RendererTypes);
418 template <typename RendererType>
419 class SoftwareRendererPixelTest : public RendererPixelTest<RendererType> {};
421 typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport>
422 SoftwareRendererTypes;
423 TYPED_TEST_CASE(SoftwareRendererPixelTest, SoftwareRendererTypes);
425 template <typename RendererType>
426 class FuzzyForSoftwareOnlyPixelComparator : public PixelComparator {
427 public:
428 explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha)
429 : fuzzy_(discard_alpha), exact_(discard_alpha) {}
431 bool Compare(const SkBitmap& actual_bmp,
432 const SkBitmap& expected_bmp) const override;
434 private:
435 FuzzyPixelOffByOneComparator fuzzy_;
436 ExactPixelComparator exact_;
439 template<>
440 bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare(
441 const SkBitmap& actual_bmp,
442 const SkBitmap& expected_bmp) const {
443 return fuzzy_.Compare(actual_bmp, expected_bmp);
446 template <>
447 bool FuzzyForSoftwareOnlyPixelComparator<
448 SoftwareRendererWithExpandedViewport>::Compare(
449 const SkBitmap& actual_bmp,
450 const SkBitmap& expected_bmp) const {
451 return fuzzy_.Compare(actual_bmp, expected_bmp);
454 template<typename RendererType>
455 bool FuzzyForSoftwareOnlyPixelComparator<RendererType>::Compare(
456 const SkBitmap& actual_bmp,
457 const SkBitmap& expected_bmp) const {
458 return exact_.Compare(actual_bmp, expected_bmp);
461 TYPED_TEST(RendererPixelTest, SimpleGreenRect) {
462 gfx::Rect rect(this->device_viewport_size_);
464 RenderPassId id(1, 1);
465 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
467 SharedQuadState* shared_state =
468 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
470 SolidColorDrawQuad* color_quad =
471 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
472 color_quad->SetNew(shared_state, rect, rect, SK_ColorGREEN, false);
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 TYPED_TEST(RendererPixelTest, SimpleGreenRect_NonRootRenderPass) {
484 gfx::Rect rect(this->device_viewport_size_);
485 gfx::Rect small_rect(100, 100);
487 RenderPassId child_id(2, 1);
488 scoped_ptr<RenderPass> child_pass =
489 CreateTestRenderPass(child_id, small_rect, gfx::Transform());
491 SharedQuadState* child_shared_state =
492 CreateTestSharedQuadState(gfx::Transform(), small_rect, child_pass.get());
494 SolidColorDrawQuad* color_quad =
495 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
496 color_quad->SetNew(child_shared_state, rect, rect, SK_ColorGREEN, false);
498 RenderPassId root_id(1, 1);
499 scoped_ptr<RenderPass> root_pass =
500 CreateTestRenderPass(root_id, rect, gfx::Transform());
502 SharedQuadState* root_shared_state =
503 CreateTestSharedQuadState(gfx::Transform(), rect, root_pass.get());
505 CreateTestRenderPassDrawQuad(
506 root_shared_state, small_rect, child_id, root_pass.get());
508 RenderPass* child_pass_ptr = child_pass.get();
510 RenderPassList pass_list;
511 pass_list.push_back(child_pass.Pass());
512 pass_list.push_back(root_pass.Pass());
514 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
515 &pass_list,
516 child_pass_ptr,
517 base::FilePath(FILE_PATH_LITERAL("green_small.png")),
518 ExactPixelComparator(true)));
521 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithoutBackground) {
522 gfx::Rect rect(this->device_viewport_size_);
524 RenderPassId id(1, 1);
525 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
527 SharedQuadState* shared_state =
528 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
530 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
531 SkColorSetARGB(128, 0, 255, 0), // Texel color.
532 SK_ColorTRANSPARENT, // Background color.
533 true, // Premultiplied alpha.
534 shared_state,
535 this->resource_provider_.get(),
536 pass.get());
538 SolidColorDrawQuad* color_quad =
539 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
540 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
542 RenderPassList pass_list;
543 pass_list.push_back(pass.Pass());
545 EXPECT_TRUE(this->RunPixelTest(
546 &pass_list,
547 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
548 FuzzyPixelOffByOneComparator(true)));
551 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithBackground) {
552 gfx::Rect rect(this->device_viewport_size_);
554 RenderPassId id(1, 1);
555 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
557 SharedQuadState* texture_quad_state =
558 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
559 texture_quad_state->opacity = 0.8f;
561 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
562 SkColorSetARGB(204, 120, 255, 120), // Texel color.
563 SK_ColorGREEN, // Background color.
564 true, // Premultiplied alpha.
565 texture_quad_state,
566 this->resource_provider_.get(),
567 pass.get());
569 SharedQuadState* color_quad_state =
570 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
571 SolidColorDrawQuad* color_quad =
572 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
573 color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
575 RenderPassList pass_list;
576 pass_list.push_back(pass.Pass());
578 EXPECT_TRUE(this->RunPixelTest(
579 &pass_list,
580 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
581 FuzzyPixelOffByOneComparator(true)));
584 template <typename QuadType>
585 static const base::FilePath::CharType* IntersectingQuadImage() {
586 return FILE_PATH_LITERAL("intersecting_blue_green_squares.png");
588 template <>
589 const base::FilePath::CharType* IntersectingQuadImage<SolidColorDrawQuad>() {
590 return FILE_PATH_LITERAL("intersecting_blue_green.png");
592 template <>
593 const base::FilePath::CharType* IntersectingQuadImage<YUVVideoDrawQuad>() {
594 return FILE_PATH_LITERAL("intersecting_blue_green_squares_video.png");
597 template <typename TypeParam>
598 class IntersectingQuadPixelTest : public RendererPixelTest<TypeParam> {
599 protected:
600 void SetupQuadStateAndRenderPass() {
601 // This sets up a pair of draw quads. They are both rotated
602 // relative to the root plane, they are also rotated relative to each other.
603 // The intersect in the middle at a non-perpendicular angle so that any
604 // errors are hopefully magnified.
605 // The quads should intersect correctly, as in the front quad should only
606 // be partially in front of the back quad, and partially behind.
608 viewport_rect_ = gfx::Rect(this->device_viewport_size_);
609 quad_rect_ = gfx::Rect(0, 0, this->device_viewport_size_.width(),
610 this->device_viewport_size_.height() / 2.0);
612 RenderPassId id(1, 1);
613 render_pass_ = CreateTestRootRenderPass(id, viewport_rect_);
615 // Create the front quad rotated on the Z and Y axis.
616 gfx::Transform trans;
617 trans.Translate3d(0, 0, 0.707 * this->device_viewport_size_.width() / 2.0);
618 trans.RotateAboutZAxis(45.0);
619 trans.RotateAboutYAxis(45.0);
620 front_quad_state_ =
621 CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get());
622 front_quad_state_->clip_rect = quad_rect_;
623 // Make sure they end up in a 3d sorting context.
624 front_quad_state_->sorting_context_id = 1;
626 // Create the back quad, and rotate on just the y axis. This will intersect
627 // the first quad partially.
628 trans = gfx::Transform();
629 trans.Translate3d(0, 0, -0.707 * this->device_viewport_size_.width() / 2.0);
630 trans.RotateAboutYAxis(-45.0);
631 back_quad_state_ =
632 CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get());
633 back_quad_state_->sorting_context_id = 1;
634 back_quad_state_->clip_rect = quad_rect_;
636 template <typename T>
637 void AppendBackgroundAndRunTest(const PixelComparator& comparator) {
638 SharedQuadState* background_quad_state = CreateTestSharedQuadState(
639 gfx::Transform(), viewport_rect_, render_pass_.get());
640 SolidColorDrawQuad* background_quad =
641 render_pass_->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
642 background_quad->SetNew(background_quad_state, viewport_rect_,
643 viewport_rect_, SK_ColorWHITE, false);
644 pass_list_.push_back(render_pass_.Pass());
645 const base::FilePath::CharType* fileName = IntersectingQuadImage<T>();
646 EXPECT_TRUE(
647 this->RunPixelTest(&pass_list_, base::FilePath(fileName), comparator));
649 template <typename T>
650 T* CreateAndAppendDrawQuad() {
651 return render_pass_->CreateAndAppendDrawQuad<T>();
654 scoped_ptr<RenderPass> render_pass_;
655 gfx::Rect viewport_rect_;
656 SharedQuadState* front_quad_state_;
657 SharedQuadState* back_quad_state_;
658 gfx::Rect quad_rect_;
659 RenderPassList pass_list_;
662 template <typename TypeParam>
663 class IntersectingQuadGLPixelTest
664 : public IntersectingQuadPixelTest<TypeParam> {
665 public:
666 void SetUp() override {
667 IntersectingQuadPixelTest<TypeParam>::SetUp();
668 video_resource_updater_.reset(
669 new VideoResourceUpdater(this->output_surface_->context_provider(),
670 this->resource_provider_.get()));
671 video_resource_updater2_.reset(
672 new VideoResourceUpdater(this->output_surface_->context_provider(),
673 this->resource_provider_.get()));
676 protected:
677 scoped_ptr<VideoResourceUpdater> video_resource_updater_;
678 scoped_ptr<VideoResourceUpdater> video_resource_updater2_;
681 template <typename TypeParam>
682 class IntersectingQuadSoftwareTest
683 : public IntersectingQuadPixelTest<TypeParam> {};
685 typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport>
686 SoftwareRendererTypes;
687 typedef ::testing::Types<GLRenderer, GLRendererWithExpandedViewport>
688 GLRendererTypes;
690 TYPED_TEST_CASE(IntersectingQuadPixelTest, RendererTypes);
691 TYPED_TEST_CASE(IntersectingQuadGLPixelTest, GLRendererTypes);
692 TYPED_TEST_CASE(IntersectingQuadSoftwareTest, SoftwareRendererTypes);
694 TYPED_TEST(IntersectingQuadPixelTest, SolidColorQuads) {
695 this->SetupQuadStateAndRenderPass();
697 SolidColorDrawQuad* quad =
698 this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>();
699 SolidColorDrawQuad* quad2 =
700 this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>();
702 quad->SetNew(this->front_quad_state_, this->quad_rect_, this->quad_rect_,
703 SK_ColorBLUE, false);
704 quad2->SetNew(this->back_quad_state_, this->quad_rect_, this->quad_rect_,
705 SK_ColorGREEN, false);
706 SCOPED_TRACE("IntersectingSolidColorQuads");
707 this->template AppendBackgroundAndRunTest<SolidColorDrawQuad>(
708 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
711 template <typename TypeParam>
712 SkColor GetColor(const SkColor& color) {
713 return color;
716 template <>
717 SkColor GetColor<GLRenderer>(const SkColor& color) {
718 return SkColorSetARGB(SkColorGetA(color), SkColorGetB(color),
719 SkColorGetG(color), SkColorGetR(color));
721 template <>
722 SkColor GetColor<GLRendererWithExpandedViewport>(const SkColor& color) {
723 return GetColor<GLRenderer>(color);
726 TYPED_TEST(IntersectingQuadPixelTest, TexturedQuads) {
727 this->SetupQuadStateAndRenderPass();
728 CreateTestTwoColoredTextureDrawQuad(
729 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
730 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
731 true, this->front_quad_state_, this->resource_provider_.get(),
732 this->render_pass_.get());
733 CreateTestTwoColoredTextureDrawQuad(
734 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
735 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
736 true, this->back_quad_state_, this->resource_provider_.get(),
737 this->render_pass_.get());
739 SCOPED_TRACE("IntersectingTexturedQuads");
740 this->template AppendBackgroundAndRunTest<TextureDrawQuad>(
741 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
744 TYPED_TEST(IntersectingQuadSoftwareTest, PictureQuads) {
745 this->SetupQuadStateAndRenderPass();
746 gfx::RectF outer_rect(this->quad_rect_);
747 gfx::RectF inner_rect(this->quad_rect_.x() + (this->quad_rect_.width() / 4),
748 this->quad_rect_.y() + (this->quad_rect_.height() / 4),
749 this->quad_rect_.width() / 2,
750 this->quad_rect_.height() / 2);
752 SkPaint black_paint;
753 black_paint.setColor(SK_ColorBLACK);
754 SkPaint blue_paint;
755 blue_paint.setColor(SK_ColorBLUE);
756 SkPaint green_paint;
757 green_paint.setColor(SK_ColorGREEN);
759 scoped_ptr<FakePicturePile> blue_recording =
760 FakePicturePile::CreateFilledPile(gfx::Size(1000, 1000),
761 this->quad_rect_.size());
762 blue_recording->add_draw_rect_with_paint(outer_rect, black_paint);
763 blue_recording->add_draw_rect_with_paint(inner_rect, blue_paint);
764 blue_recording->Rerecord();
765 scoped_refptr<FakePicturePileImpl> blue_pile =
766 FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);
768 PictureDrawQuad* blue_quad =
769 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
771 blue_quad->SetNew(this->front_quad_state_, this->quad_rect_, gfx::Rect(),
772 this->quad_rect_, this->quad_rect_, this->quad_rect_.size(),
773 false, RGBA_8888, this->quad_rect_, 1.f, blue_pile);
775 scoped_ptr<FakePicturePile> green_recording =
776 FakePicturePile::CreateFilledPile(this->quad_rect_.size(),
777 this->quad_rect_.size());
778 green_recording->add_draw_rect_with_paint(outer_rect, green_paint);
779 green_recording->add_draw_rect_with_paint(inner_rect, black_paint);
780 green_recording->Rerecord();
781 scoped_refptr<FakePicturePileImpl> green_pile =
782 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
784 PictureDrawQuad* green_quad =
785 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
786 green_quad->SetNew(this->back_quad_state_, this->quad_rect_, gfx::Rect(),
787 this->quad_rect_, this->quad_rect_,
788 this->quad_rect_.size(), false, RGBA_8888,
789 this->quad_rect_, 1.f, green_pile);
790 SCOPED_TRACE("IntersectingPictureQuadsPass");
791 this->template AppendBackgroundAndRunTest<PictureDrawQuad>(
792 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
795 TYPED_TEST(IntersectingQuadPixelTest, RenderPassQuads) {
796 this->SetupQuadStateAndRenderPass();
797 RenderPassId child_pass_id1(2, 2);
798 RenderPassId child_pass_id2(2, 3);
799 scoped_ptr<RenderPass> child_pass1 =
800 CreateTestRenderPass(child_pass_id1, this->quad_rect_, gfx::Transform());
801 SharedQuadState* child1_quad_state = CreateTestSharedQuadState(
802 gfx::Transform(), this->quad_rect_, child_pass1.get());
803 scoped_ptr<RenderPass> child_pass2 =
804 CreateTestRenderPass(child_pass_id2, this->quad_rect_, gfx::Transform());
805 SharedQuadState* child2_quad_state = CreateTestSharedQuadState(
806 gfx::Transform(), this->quad_rect_, child_pass2.get());
808 CreateTestTwoColoredTextureDrawQuad(
809 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
810 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
811 true, child1_quad_state, this->resource_provider_.get(),
812 child_pass1.get());
813 CreateTestTwoColoredTextureDrawQuad(
814 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
815 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
816 true, child2_quad_state, this->resource_provider_.get(),
817 child_pass2.get());
819 CreateTestRenderPassDrawQuad(this->front_quad_state_, this->quad_rect_,
820 child_pass_id1, this->render_pass_.get());
821 CreateTestRenderPassDrawQuad(this->back_quad_state_, this->quad_rect_,
822 child_pass_id2, this->render_pass_.get());
824 this->pass_list_.push_back(child_pass1.Pass());
825 this->pass_list_.push_back(child_pass2.Pass());
826 SCOPED_TRACE("IntersectingRenderQuadsPass");
827 this->template AppendBackgroundAndRunTest<RenderPassDrawQuad>(
828 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
831 TYPED_TEST(IntersectingQuadGLPixelTest, YUVVideoQuads) {
832 this->SetupQuadStateAndRenderPass();
833 gfx::Rect inner_rect(
834 ((this->quad_rect_.x() + (this->quad_rect_.width() / 4)) & ~0xF),
835 ((this->quad_rect_.y() + (this->quad_rect_.height() / 4)) & ~0xF),
836 (this->quad_rect_.width() / 2) & ~0xF,
837 (this->quad_rect_.height() / 2) & ~0xF);
839 CreateTestYUVVideoDrawQuad_TwoColor(
840 this->front_quad_state_, media::VideoFrame::YV12J, false,
841 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(),
842 this->quad_rect_, 0, 128, 128, inner_rect, 29, 255, 107,
843 this->render_pass_.get(), this->video_resource_updater_.get(),
844 this->resource_provider_.get());
846 CreateTestYUVVideoDrawQuad_TwoColor(
847 this->back_quad_state_, media::VideoFrame::YV12J, false,
848 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(),
849 this->quad_rect_, 149, 43, 21, inner_rect, 0, 128, 128,
850 this->render_pass_.get(), this->video_resource_updater2_.get(),
851 this->resource_provider_.get());
853 SCOPED_TRACE("IntersectingVideoQuads");
854 this->template AppendBackgroundAndRunTest<YUVVideoDrawQuad>(
855 FuzzyPixelOffByOneComparator(false));
858 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
859 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) {
860 gfx::Rect rect(this->device_viewport_size_);
862 RenderPassId id(1, 1);
863 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
865 SharedQuadState* shared_state =
866 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
868 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
869 SkColorSetARGB(128, 0, 255, 0), // Texel color.
870 SK_ColorTRANSPARENT, // Background color.
871 false, // Premultiplied alpha.
872 shared_state,
873 this->resource_provider_.get(),
874 pass.get());
876 SolidColorDrawQuad* color_quad =
877 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
878 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
880 RenderPassList pass_list;
881 pass_list.push_back(pass.Pass());
883 EXPECT_TRUE(this->RunPixelTest(
884 &pass_list,
885 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
886 FuzzyPixelOffByOneComparator(true)));
889 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
890 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
891 gfx::Rect rect(this->device_viewport_size_);
893 RenderPassId id(1, 1);
894 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
896 SharedQuadState* texture_quad_state =
897 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
898 texture_quad_state->opacity = 0.8f;
900 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
901 SkColorSetARGB(204, 120, 255, 120), // Texel color.
902 SK_ColorGREEN, // Background color.
903 false, // Premultiplied alpha.
904 texture_quad_state,
905 this->resource_provider_.get(),
906 pass.get());
908 SharedQuadState* color_quad_state =
909 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
910 SolidColorDrawQuad* color_quad =
911 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
912 color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
914 RenderPassList pass_list;
915 pass_list.push_back(pass.Pass());
917 EXPECT_TRUE(this->RunPixelTest(
918 &pass_list,
919 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
920 FuzzyPixelOffByOneComparator(true)));
923 class VideoGLRendererPixelTest : public GLRendererPixelTest {
924 protected:
925 void CreateEdgeBleedPass(media::VideoFrame::Format format,
926 RenderPassList* pass_list) {
927 gfx::Rect rect(200, 200);
929 RenderPassId id(1, 1);
930 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
932 // Scale the video up so that bilinear filtering kicks in to sample more
933 // than just nearest neighbor would.
934 gfx::Transform scale_by_2;
935 scale_by_2.Scale(2.f, 2.f);
936 gfx::Rect half_rect(100, 100);
937 SharedQuadState* shared_state =
938 CreateTestSharedQuadState(scale_by_2, half_rect, pass.get());
940 gfx::Size background_size(200, 200);
941 gfx::Rect green_rect(16, 20, 100, 100);
942 gfx::RectF tex_coord_rect(
943 static_cast<float>(green_rect.x()) / background_size.width(),
944 static_cast<float>(green_rect.y()) / background_size.height(),
945 static_cast<float>(green_rect.width()) / background_size.width(),
946 static_cast<float>(green_rect.height()) / background_size.height());
948 // YUV of (149,43,21) should be green (0,255,0) in RGB.
949 // Create a video frame that has a non-green background rect, with a
950 // green sub-rectangle that should be the only thing displayed in
951 // the final image. Bleeding will appear on all four sides of the video
952 // if the tex coords are not clamped.
953 CreateTestYUVVideoDrawQuad_TwoColor(
954 shared_state, format, false, tex_coord_rect, background_size,
955 gfx::Rect(background_size), 128, 128, 128, green_rect, 149, 43, 21,
956 pass.get(), video_resource_updater_.get(), resource_provider_.get());
957 pass_list->push_back(pass.Pass());
960 void SetUp() override {
961 GLRendererPixelTest::SetUp();
962 video_resource_updater_.reset(new VideoResourceUpdater(
963 output_surface_->context_provider(), resource_provider_.get()));
966 scoped_ptr<VideoResourceUpdater> video_resource_updater_;
969 TEST_F(VideoGLRendererPixelTest, SimpleYUVRect) {
970 gfx::Rect rect(this->device_viewport_size_);
972 RenderPassId id(1, 1);
973 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
975 SharedQuadState* shared_state =
976 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
978 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::VideoFrame::YV12,
979 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
980 pass.get(), video_resource_updater_.get(),
981 rect, rect, resource_provider_.get());
983 RenderPassList pass_list;
984 pass_list.push_back(pass.Pass());
986 EXPECT_TRUE(
987 this->RunPixelTest(&pass_list,
988 base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
989 FuzzyPixelOffByOneComparator(true)));
992 TEST_F(VideoGLRendererPixelTest, ClippedYUVRect) {
993 gfx::Rect viewport(this->device_viewport_size_);
994 gfx::Rect draw_rect(this->device_viewport_size_.width() * 1.5,
995 this->device_viewport_size_.height() * 1.5);
997 RenderPassId id(1, 1);
998 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, viewport);
1000 SharedQuadState* shared_state =
1001 CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get());
1003 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::VideoFrame::YV12,
1004 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1005 pass.get(), video_resource_updater_.get(),
1006 draw_rect, viewport,
1007 resource_provider_.get());
1008 RenderPassList pass_list;
1009 pass_list.push_back(pass.Pass());
1011 EXPECT_TRUE(this->RunPixelTest(
1012 &pass_list, base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png")),
1013 FuzzyPixelOffByOneComparator(true)));
1016 TEST_F(VideoGLRendererPixelTest, OffsetYUVRect) {
1017 gfx::Rect rect(this->device_viewport_size_);
1019 RenderPassId id(1, 1);
1020 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1022 SharedQuadState* shared_state =
1023 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1025 // Intentionally sets frame format to I420 for testing coverage.
1026 CreateTestYUVVideoDrawQuad_Striped(
1027 shared_state, media::VideoFrame::I420, false,
1028 gfx::RectF(0.125f, 0.25f, 0.75f, 0.5f), pass.get(),
1029 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1031 RenderPassList pass_list;
1032 pass_list.push_back(pass.Pass());
1034 EXPECT_TRUE(this->RunPixelTest(
1035 &pass_list,
1036 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_offset.png")),
1037 FuzzyPixelOffByOneComparator(true)));
1040 TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) {
1041 gfx::Rect rect(this->device_viewport_size_);
1043 RenderPassId id(1, 1);
1044 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1046 SharedQuadState* shared_state =
1047 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1049 // In MPEG color range YUV values of (15,128,128) should produce black.
1050 CreateTestYUVVideoDrawQuad_Solid(
1051 shared_state, media::VideoFrame::YV12, false,
1052 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
1053 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1055 RenderPassList pass_list;
1056 pass_list.push_back(pass.Pass());
1058 // If we didn't get black out of the YUV values above, then we probably have a
1059 // color range issue.
1060 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1061 base::FilePath(FILE_PATH_LITERAL("black.png")),
1062 FuzzyPixelOffByOneComparator(true)));
1065 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
1066 gfx::Rect rect(this->device_viewport_size_);
1068 RenderPassId id(1, 1);
1069 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1071 SharedQuadState* shared_state =
1072 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1074 // YUV of (149,43,21) should be green (0,255,0) in RGB.
1075 CreateTestYUVVideoDrawQuad_Solid(
1076 shared_state, media::VideoFrame::YV12J, false,
1077 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(),
1078 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1080 RenderPassList pass_list;
1081 pass_list.push_back(pass.Pass());
1083 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1084 base::FilePath(FILE_PATH_LITERAL("green.png")),
1085 FuzzyPixelOffByOneComparator(true)));
1088 // Test that a YUV video doesn't bleed outside of its tex coords when the
1089 // tex coord rect is only a partial subrectangle of the coded contents.
1090 TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) {
1091 RenderPassList pass_list;
1092 CreateEdgeBleedPass(media::VideoFrame::YV12J, &pass_list);
1093 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1094 base::FilePath(FILE_PATH_LITERAL("green.png")),
1095 FuzzyPixelOffByOneComparator(true)));
1098 TEST_F(VideoGLRendererPixelTest, YUVAEdgeBleed) {
1099 RenderPassList pass_list;
1100 CreateEdgeBleedPass(media::VideoFrame::YV12A, &pass_list);
1101 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1102 base::FilePath(FILE_PATH_LITERAL("green.png")),
1103 FuzzyPixelOffByOneComparator(true)));
1106 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
1107 gfx::Rect rect(this->device_viewport_size_);
1109 RenderPassId id(1, 1);
1110 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1112 SharedQuadState* shared_state =
1113 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1115 // Dark grey in JPEG color range (in MPEG, this is black).
1116 CreateTestYUVVideoDrawQuad_Solid(
1117 shared_state, media::VideoFrame::YV12J, false,
1118 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
1119 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1121 RenderPassList pass_list;
1122 pass_list.push_back(pass.Pass());
1124 EXPECT_TRUE(
1125 this->RunPixelTest(&pass_list,
1126 base::FilePath(FILE_PATH_LITERAL("dark_grey.png")),
1127 FuzzyPixelOffByOneComparator(true)));
1130 TEST_F(VideoGLRendererPixelTest, SimpleYUVARect) {
1131 gfx::Rect rect(this->device_viewport_size_);
1133 RenderPassId id(1, 1);
1134 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1136 SharedQuadState* shared_state =
1137 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1139 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::VideoFrame::YV12A,
1140 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1141 pass.get(), video_resource_updater_.get(),
1142 rect, rect, resource_provider_.get());
1144 SolidColorDrawQuad* color_quad =
1145 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1146 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
1148 RenderPassList pass_list;
1149 pass_list.push_back(pass.Pass());
1151 EXPECT_TRUE(this->RunPixelTest(
1152 &pass_list,
1153 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_alpha.png")),
1154 FuzzyPixelOffByOneComparator(true)));
1157 TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) {
1158 gfx::Rect rect(this->device_viewport_size_);
1160 RenderPassId id(1, 1);
1161 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1163 SharedQuadState* shared_state =
1164 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1166 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::VideoFrame::YV12A,
1167 true, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1168 pass.get(), video_resource_updater_.get(),
1169 rect, rect, resource_provider_.get());
1171 SolidColorDrawQuad* color_quad =
1172 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1173 color_quad->SetNew(shared_state, rect, rect, SK_ColorBLACK, false);
1175 RenderPassList pass_list;
1176 pass_list.push_back(pass.Pass());
1178 EXPECT_TRUE(this->RunPixelTest(
1179 &pass_list,
1180 base::FilePath(FILE_PATH_LITERAL("black.png")),
1181 ExactPixelComparator(true)));
1184 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) {
1185 gfx::Rect viewport_rect(this->device_viewport_size_);
1187 RenderPassId root_pass_id(1, 1);
1188 scoped_ptr<RenderPass> root_pass =
1189 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1191 RenderPassId child_pass_id(2, 2);
1192 gfx::Rect pass_rect(this->device_viewport_size_);
1193 gfx::Transform transform_to_root;
1194 scoped_ptr<RenderPass> child_pass =
1195 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1197 gfx::Transform content_to_target_transform;
1198 SharedQuadState* shared_state = CreateTestSharedQuadState(
1199 content_to_target_transform, viewport_rect, child_pass.get());
1200 shared_state->opacity = 0.5f;
1202 gfx::Rect blue_rect(0,
1204 this->device_viewport_size_.width(),
1205 this->device_viewport_size_.height() / 2);
1206 SolidColorDrawQuad* blue =
1207 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1208 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1209 gfx::Rect yellow_rect(0,
1210 this->device_viewport_size_.height() / 2,
1211 this->device_viewport_size_.width(),
1212 this->device_viewport_size_.height() / 2);
1213 SolidColorDrawQuad* yellow =
1214 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1215 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1217 SharedQuadState* blank_state = CreateTestSharedQuadState(
1218 content_to_target_transform, viewport_rect, child_pass.get());
1220 SolidColorDrawQuad* white =
1221 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1222 white->SetNew(
1223 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1225 SharedQuadState* pass_shared_state =
1226 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1228 SkScalar matrix[20];
1229 float amount = 0.5f;
1230 matrix[0] = 0.213f + 0.787f * amount;
1231 matrix[1] = 0.715f - 0.715f * amount;
1232 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1233 matrix[3] = matrix[4] = 0;
1234 matrix[5] = 0.213f - 0.213f * amount;
1235 matrix[6] = 0.715f + 0.285f * amount;
1236 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1237 matrix[8] = matrix[9] = 0;
1238 matrix[10] = 0.213f - 0.213f * amount;
1239 matrix[11] = 0.715f - 0.715f * amount;
1240 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1241 matrix[13] = matrix[14] = 0;
1242 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1243 matrix[18] = 1;
1244 skia::RefPtr<SkColorFilter> colorFilter(
1245 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1246 skia::RefPtr<SkImageFilter> filter =
1247 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
1248 FilterOperations filters;
1249 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1251 RenderPassDrawQuad* render_pass_quad =
1252 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1253 render_pass_quad->SetNew(pass_shared_state,
1254 pass_rect,
1255 pass_rect,
1256 child_pass_id,
1258 gfx::Vector2dF(),
1259 gfx::Size(),
1260 filters,
1261 gfx::Vector2dF(),
1262 FilterOperations());
1264 RenderPassList pass_list;
1265 pass_list.push_back(child_pass.Pass());
1266 pass_list.push_back(root_pass.Pass());
1268 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1269 // renderer so use a fuzzy comparator.
1270 EXPECT_TRUE(this->RunPixelTest(
1271 &pass_list,
1272 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1273 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1276 TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) {
1277 gfx::Rect viewport_rect(this->device_viewport_size_);
1279 RenderPassId root_pass_id(1, 1);
1280 scoped_ptr<RenderPass> root_pass =
1281 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1283 RenderPassId child_pass_id(2, 2);
1284 gfx::Rect pass_rect(this->device_viewport_size_);
1285 gfx::Transform transform_to_root;
1286 scoped_ptr<RenderPass> child_pass =
1287 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1289 gfx::Transform content_to_target_transform;
1290 SharedQuadState* shared_state = CreateTestSharedQuadState(
1291 content_to_target_transform, viewport_rect, child_pass.get());
1292 shared_state->opacity = 0.5f;
1294 gfx::Rect blue_rect(0,
1296 this->device_viewport_size_.width(),
1297 this->device_viewport_size_.height() / 2);
1298 SolidColorDrawQuad* blue =
1299 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1300 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1301 gfx::Rect yellow_rect(0,
1302 this->device_viewport_size_.height() / 2,
1303 this->device_viewport_size_.width(),
1304 this->device_viewport_size_.height() / 2);
1305 SolidColorDrawQuad* yellow =
1306 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1307 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1309 SharedQuadState* blank_state = CreateTestSharedQuadState(
1310 content_to_target_transform, viewport_rect, child_pass.get());
1312 SolidColorDrawQuad* white =
1313 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1314 white->SetNew(
1315 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1317 SharedQuadState* pass_shared_state =
1318 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1320 FilterOperations filters;
1321 filters.Append(FilterOperation::CreateSaturateFilter(0.5f));
1323 RenderPassDrawQuad* render_pass_quad =
1324 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1325 render_pass_quad->SetNew(pass_shared_state,
1326 pass_rect,
1327 pass_rect,
1328 child_pass_id,
1330 gfx::Vector2dF(),
1331 gfx::Size(),
1332 filters,
1333 gfx::Vector2dF(),
1334 FilterOperations());
1336 RenderPassList pass_list;
1337 pass_list.push_back(child_pass.Pass());
1338 pass_list.push_back(root_pass.Pass());
1340 EXPECT_TRUE(this->RunPixelTest(
1341 &pass_list,
1342 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1343 ExactPixelComparator(true)));
1346 TYPED_TEST(RendererPixelTest, FastPassFilterChain) {
1347 gfx::Rect viewport_rect(this->device_viewport_size_);
1349 RenderPassId root_pass_id(1, 1);
1350 scoped_ptr<RenderPass> root_pass =
1351 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1353 RenderPassId child_pass_id(2, 2);
1354 gfx::Rect pass_rect(this->device_viewport_size_);
1355 gfx::Transform transform_to_root;
1356 scoped_ptr<RenderPass> child_pass =
1357 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1359 gfx::Transform content_to_target_transform;
1360 SharedQuadState* shared_state = CreateTestSharedQuadState(
1361 content_to_target_transform, viewport_rect, child_pass.get());
1362 shared_state->opacity = 0.5f;
1364 gfx::Rect blue_rect(0,
1366 this->device_viewport_size_.width(),
1367 this->device_viewport_size_.height() / 2);
1368 SolidColorDrawQuad* blue =
1369 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1370 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1371 gfx::Rect yellow_rect(0,
1372 this->device_viewport_size_.height() / 2,
1373 this->device_viewport_size_.width(),
1374 this->device_viewport_size_.height() / 2);
1375 SolidColorDrawQuad* yellow =
1376 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1377 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1379 SharedQuadState* blank_state = CreateTestSharedQuadState(
1380 content_to_target_transform, viewport_rect, child_pass.get());
1382 SolidColorDrawQuad* white =
1383 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1384 white->SetNew(
1385 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1387 SharedQuadState* pass_shared_state =
1388 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1390 FilterOperations filters;
1391 filters.Append(FilterOperation::CreateGrayscaleFilter(1.f));
1392 filters.Append(FilterOperation::CreateBrightnessFilter(0.5f));
1394 RenderPassDrawQuad* render_pass_quad =
1395 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1396 render_pass_quad->SetNew(pass_shared_state,
1397 pass_rect,
1398 pass_rect,
1399 child_pass_id,
1401 gfx::Vector2dF(),
1402 gfx::Size(),
1403 filters,
1404 gfx::Vector2dF(),
1405 FilterOperations());
1407 RenderPassList pass_list;
1408 pass_list.push_back(child_pass.Pass());
1409 pass_list.push_back(root_pass.Pass());
1411 EXPECT_TRUE(this->RunPixelTest(
1412 &pass_list,
1413 base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")),
1414 ExactPixelComparator(true)));
1417 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) {
1418 gfx::Rect viewport_rect(this->device_viewport_size_);
1420 RenderPassId root_pass_id(1, 1);
1421 scoped_ptr<RenderPass> root_pass =
1422 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1424 RenderPassId child_pass_id(2, 2);
1425 gfx::Rect pass_rect(this->device_viewport_size_);
1426 gfx::Transform transform_to_root;
1427 scoped_ptr<RenderPass> child_pass =
1428 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1430 gfx::Transform content_to_target_transform;
1431 SharedQuadState* shared_state = CreateTestSharedQuadState(
1432 content_to_target_transform, viewport_rect, child_pass.get());
1433 shared_state->opacity = 0.5f;
1435 gfx::Rect blue_rect(0,
1437 this->device_viewport_size_.width(),
1438 this->device_viewport_size_.height() / 2);
1439 SolidColorDrawQuad* blue =
1440 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1441 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1442 gfx::Rect yellow_rect(0,
1443 this->device_viewport_size_.height() / 2,
1444 this->device_viewport_size_.width(),
1445 this->device_viewport_size_.height() / 2);
1446 SolidColorDrawQuad* yellow =
1447 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1448 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1450 SharedQuadState* blank_state = CreateTestSharedQuadState(
1451 content_to_target_transform, viewport_rect, child_pass.get());
1453 SolidColorDrawQuad* white =
1454 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1455 white->SetNew(
1456 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1458 SharedQuadState* pass_shared_state =
1459 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1461 SkScalar matrix[20];
1462 float amount = 0.5f;
1463 matrix[0] = 0.213f + 0.787f * amount;
1464 matrix[1] = 0.715f - 0.715f * amount;
1465 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1466 matrix[3] = 0;
1467 matrix[4] = 20.f;
1468 matrix[5] = 0.213f - 0.213f * amount;
1469 matrix[6] = 0.715f + 0.285f * amount;
1470 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1471 matrix[8] = 0;
1472 matrix[9] = 200.f;
1473 matrix[10] = 0.213f - 0.213f * amount;
1474 matrix[11] = 0.715f - 0.715f * amount;
1475 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1476 matrix[13] = 0;
1477 matrix[14] = 1.5f;
1478 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1479 matrix[18] = 1;
1480 skia::RefPtr<SkColorFilter> colorFilter(
1481 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1482 skia::RefPtr<SkImageFilter> filter =
1483 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
1484 FilterOperations filters;
1485 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1487 RenderPassDrawQuad* render_pass_quad =
1488 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1489 render_pass_quad->SetNew(pass_shared_state,
1490 pass_rect,
1491 pass_rect,
1492 child_pass_id,
1494 gfx::Vector2dF(),
1495 gfx::Size(),
1496 filters,
1497 gfx::Vector2dF(),
1498 FilterOperations());
1500 RenderPassList pass_list;
1502 pass_list.push_back(child_pass.Pass());
1503 pass_list.push_back(root_pass.Pass());
1505 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1506 // renderer so use a fuzzy comparator.
1507 EXPECT_TRUE(this->RunPixelTest(
1508 &pass_list,
1509 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
1510 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1513 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) {
1514 gfx::Rect viewport_rect(this->device_viewport_size_);
1516 RenderPassId root_pass_id(1, 1);
1517 scoped_ptr<RenderPass> root_pass =
1518 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1520 RenderPassId child_pass_id(2, 2);
1521 gfx::Rect pass_rect(this->device_viewport_size_);
1522 gfx::Transform transform_to_root;
1523 scoped_ptr<RenderPass> child_pass =
1524 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1526 gfx::Transform content_to_target_transform;
1527 SharedQuadState* shared_state = CreateTestSharedQuadState(
1528 content_to_target_transform, viewport_rect, child_pass.get());
1530 gfx::Rect blue_rect(0,
1532 this->device_viewport_size_.width(),
1533 this->device_viewport_size_.height() / 2);
1534 SolidColorDrawQuad* blue =
1535 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1536 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1537 gfx::Rect yellow_rect(0,
1538 this->device_viewport_size_.height() / 2,
1539 this->device_viewport_size_.width(),
1540 this->device_viewport_size_.height() / 2);
1541 SolidColorDrawQuad* yellow =
1542 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1543 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1545 SharedQuadState* pass_shared_state =
1546 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1547 CreateTestRenderPassDrawQuad(
1548 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1550 RenderPassList pass_list;
1551 pass_list.push_back(child_pass.Pass());
1552 pass_list.push_back(root_pass.Pass());
1554 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1556 EXPECT_TRUE(this->RunPixelTest(
1557 &pass_list,
1558 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
1559 ExactPixelComparator(true)));
1562 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) {
1563 gfx::Rect viewport_rect(this->device_viewport_size_);
1565 RenderPassId root_pass_id(1, 1);
1566 scoped_ptr<RenderPass> root_pass =
1567 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1569 RenderPassId child_pass_id(2, 2);
1570 gfx::Rect pass_rect(this->device_viewport_size_);
1571 gfx::Transform transform_to_root;
1572 scoped_ptr<RenderPass> child_pass =
1573 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1575 gfx::Transform content_to_target_transform;
1576 SharedQuadState* shared_state = CreateTestSharedQuadState(
1577 content_to_target_transform, viewport_rect, child_pass.get());
1579 gfx::Rect blue_rect(0,
1581 this->device_viewport_size_.width(),
1582 this->device_viewport_size_.height() / 2);
1583 SolidColorDrawQuad* blue =
1584 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1585 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1586 gfx::Rect yellow_rect(0,
1587 this->device_viewport_size_.height() / 2,
1588 this->device_viewport_size_.width(),
1589 this->device_viewport_size_.height() / 2);
1590 SolidColorDrawQuad* yellow =
1591 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1592 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1594 gfx::Transform aa_transform;
1595 aa_transform.Translate(0.5, 0.0);
1597 SharedQuadState* pass_shared_state =
1598 CreateTestSharedQuadState(aa_transform, pass_rect, root_pass.get());
1599 CreateTestRenderPassDrawQuad(
1600 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1602 SharedQuadState* root_shared_state = CreateTestSharedQuadState(
1603 gfx::Transform(), viewport_rect, root_pass.get());
1604 SolidColorDrawQuad* background =
1605 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1606 background->SetNew(root_shared_state,
1607 gfx::Rect(this->device_viewport_size_),
1608 gfx::Rect(this->device_viewport_size_),
1609 SK_ColorWHITE,
1610 false);
1612 RenderPassList pass_list;
1613 pass_list.push_back(child_pass.Pass());
1614 pass_list.push_back(root_pass.Pass());
1616 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1618 EXPECT_TRUE(this->RunPixelTest(
1619 &pass_list,
1620 base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")),
1621 FuzzyPixelOffByOneComparator(true)));
1624 // This tests the case where we have a RenderPass with a mask, but the quad
1625 // for the masked surface does not include the full surface texture.
1626 TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) {
1627 gfx::Rect viewport_rect(this->device_viewport_size_);
1629 RenderPassId root_pass_id(1, 1);
1630 scoped_ptr<RenderPass> root_pass =
1631 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1632 SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState(
1633 gfx::Transform(), viewport_rect, root_pass.get());
1635 RenderPassId child_pass_id(2, 2);
1636 gfx::Transform transform_to_root;
1637 scoped_ptr<RenderPass> child_pass =
1638 CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root);
1639 SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState(
1640 gfx::Transform(), viewport_rect, child_pass.get());
1642 // The child render pass is just a green box.
1643 static const SkColor kCSSGreen = 0xff008000;
1644 SolidColorDrawQuad* green =
1645 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1646 green->SetNew(
1647 child_pass_shared_state, viewport_rect, viewport_rect, kCSSGreen, false);
1649 // Make a mask.
1650 gfx::Rect mask_rect = viewport_rect;
1651 SkBitmap bitmap;
1652 bitmap.allocPixels(
1653 SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height()));
1654 SkCanvas canvas(bitmap);
1655 SkPaint paint;
1656 paint.setStyle(SkPaint::kStroke_Style);
1657 paint.setStrokeWidth(SkIntToScalar(4));
1658 paint.setColor(SK_ColorWHITE);
1659 canvas.clear(SK_ColorTRANSPARENT);
1660 gfx::Rect rect = mask_rect;
1661 while (!rect.IsEmpty()) {
1662 rect.Inset(6, 6, 4, 4);
1663 canvas.drawRect(
1664 SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()),
1665 paint);
1666 rect.Inset(6, 6, 4, 4);
1669 ResourceProvider::ResourceId mask_resource_id =
1670 this->resource_provider_->CreateResource(
1671 mask_rect.size(), GL_CLAMP_TO_EDGE,
1672 ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
1674 SkAutoLockPixels lock(bitmap);
1675 this->resource_provider_->CopyToResource(
1676 mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
1677 mask_rect.size());
1680 // This RenderPassDrawQuad does not include the full |viewport_rect| which is
1681 // the size of the child render pass.
1682 gfx::Rect sub_rect = gfx::Rect(50, 50, 200, 100);
1683 EXPECT_NE(sub_rect.x(), child_pass->output_rect.x());
1684 EXPECT_NE(sub_rect.y(), child_pass->output_rect.y());
1685 EXPECT_NE(sub_rect.right(), child_pass->output_rect.right());
1686 EXPECT_NE(sub_rect.bottom(), child_pass->output_rect.bottom());
1688 // Set up a mask on the RenderPassDrawQuad.
1689 RenderPassDrawQuad* mask_quad =
1690 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1691 mask_quad->SetNew(root_pass_shared_state,
1692 sub_rect,
1693 sub_rect,
1694 child_pass_id,
1695 mask_resource_id,
1696 gfx::Vector2dF(2.f, 1.f), // mask_uv_scale
1697 gfx::Size(mask_rect.size()), // mask_texture_size
1698 FilterOperations(), // foreground filters
1699 gfx::Vector2dF(), // filters scale
1700 FilterOperations()); // background filters
1702 // White background behind the masked render pass.
1703 SolidColorDrawQuad* white =
1704 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1705 white->SetNew(root_pass_shared_state,
1706 viewport_rect,
1707 viewport_rect,
1708 SK_ColorWHITE,
1709 false);
1711 RenderPassList pass_list;
1712 pass_list.push_back(child_pass.Pass());
1713 pass_list.push_back(root_pass.Pass());
1715 EXPECT_TRUE(this->RunPixelTest(
1716 &pass_list,
1717 base::FilePath(FILE_PATH_LITERAL("mask_bottom_right.png")),
1718 ExactPixelComparator(true)));
1721 template <typename RendererType>
1722 class RendererPixelTestWithBackgroundFilter
1723 : public RendererPixelTest<RendererType> {
1724 protected:
1725 void SetUpRenderPassList() {
1726 gfx::Rect device_viewport_rect(this->device_viewport_size_);
1728 RenderPassId root_id(1, 1);
1729 scoped_ptr<RenderPass> root_pass =
1730 CreateTestRootRenderPass(root_id, device_viewport_rect);
1731 root_pass->has_transparent_background = false;
1733 gfx::Transform identity_content_to_target_transform;
1735 RenderPassId filter_pass_id(2, 1);
1736 gfx::Transform transform_to_root;
1737 scoped_ptr<RenderPass> filter_pass =
1738 CreateTestRenderPass(filter_pass_id,
1739 filter_pass_content_rect_,
1740 transform_to_root);
1742 // A non-visible quad in the filtering render pass.
1744 SharedQuadState* shared_state =
1745 CreateTestSharedQuadState(identity_content_to_target_transform,
1746 filter_pass_content_rect_,
1747 filter_pass.get());
1748 SolidColorDrawQuad* color_quad =
1749 filter_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1750 color_quad->SetNew(shared_state,
1751 filter_pass_content_rect_,
1752 filter_pass_content_rect_,
1753 SK_ColorTRANSPARENT,
1754 false);
1758 SharedQuadState* shared_state =
1759 CreateTestSharedQuadState(filter_pass_to_target_transform_,
1760 filter_pass_content_rect_,
1761 filter_pass.get());
1762 RenderPassDrawQuad* filter_pass_quad =
1763 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1764 filter_pass_quad->SetNew(shared_state,
1765 filter_pass_content_rect_,
1766 filter_pass_content_rect_,
1767 filter_pass_id,
1768 0, // mask_resource_id
1769 gfx::Vector2dF(), // mask_uv_scale
1770 gfx::Size(), // mask_texture_size
1771 FilterOperations(), // filters
1772 gfx::Vector2dF(), // filters_scale
1773 this->background_filters_);
1776 const int kColumnWidth = device_viewport_rect.width() / 3;
1778 gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20);
1779 for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) {
1780 SharedQuadState* shared_state = CreateTestSharedQuadState(
1781 identity_content_to_target_transform, left_rect, root_pass.get());
1782 SolidColorDrawQuad* color_quad =
1783 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1784 color_quad->SetNew(
1785 shared_state, left_rect, left_rect, SK_ColorGREEN, false);
1786 left_rect += gfx::Vector2d(0, left_rect.height() + 1);
1789 gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20);
1790 for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) {
1791 SharedQuadState* shared_state = CreateTestSharedQuadState(
1792 identity_content_to_target_transform, middle_rect, root_pass.get());
1793 SolidColorDrawQuad* color_quad =
1794 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1795 color_quad->SetNew(
1796 shared_state, middle_rect, middle_rect, SK_ColorRED, false);
1797 middle_rect += gfx::Vector2d(0, middle_rect.height() + 1);
1800 gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20);
1801 for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) {
1802 SharedQuadState* shared_state = CreateTestSharedQuadState(
1803 identity_content_to_target_transform, right_rect, root_pass.get());
1804 SolidColorDrawQuad* color_quad =
1805 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1806 color_quad->SetNew(
1807 shared_state, right_rect, right_rect, SK_ColorBLUE, false);
1808 right_rect += gfx::Vector2d(0, right_rect.height() + 1);
1811 SharedQuadState* shared_state =
1812 CreateTestSharedQuadState(identity_content_to_target_transform,
1813 device_viewport_rect,
1814 root_pass.get());
1815 SolidColorDrawQuad* background_quad =
1816 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1817 background_quad->SetNew(shared_state,
1818 device_viewport_rect,
1819 device_viewport_rect,
1820 SK_ColorWHITE,
1821 false);
1823 pass_list_.push_back(filter_pass.Pass());
1824 pass_list_.push_back(root_pass.Pass());
1827 RenderPassList pass_list_;
1828 FilterOperations background_filters_;
1829 gfx::Transform filter_pass_to_target_transform_;
1830 gfx::Rect filter_pass_content_rect_;
1833 typedef ::testing::Types<GLRenderer, SoftwareRenderer>
1834 BackgroundFilterRendererTypes;
1835 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter,
1836 BackgroundFilterRendererTypes);
1838 typedef RendererPixelTestWithBackgroundFilter<GLRenderer>
1839 GLRendererPixelTestWithBackgroundFilter;
1841 // TODO(skaslev): The software renderer does not support filters yet.
1842 TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) {
1843 this->background_filters_.Append(
1844 FilterOperation::CreateInvertFilter(1.f));
1846 this->filter_pass_content_rect_ = gfx::Rect(this->device_viewport_size_);
1847 this->filter_pass_content_rect_.Inset(12, 14, 16, 18);
1849 this->SetUpRenderPassList();
1850 EXPECT_TRUE(this->RunPixelTest(
1851 &this->pass_list_,
1852 base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
1853 ExactPixelComparator(true)));
1856 class ExternalStencilPixelTest : public GLRendererPixelTest {
1857 protected:
1858 void ClearBackgroundToGreen() {
1859 GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
1860 output_surface_->EnsureBackbuffer();
1861 output_surface_->Reshape(device_viewport_size_, 1);
1862 gl->ClearColor(0.f, 1.f, 0.f, 1.f);
1863 gl->Clear(GL_COLOR_BUFFER_BIT);
1866 void PopulateStencilBuffer() {
1867 // Set two quadrants of the stencil buffer to 1.
1868 GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
1869 output_surface_->EnsureBackbuffer();
1870 output_surface_->Reshape(device_viewport_size_, 1);
1871 gl->ClearStencil(0);
1872 gl->Clear(GL_STENCIL_BUFFER_BIT);
1873 gl->Enable(GL_SCISSOR_TEST);
1874 gl->ClearStencil(1);
1875 gl->Scissor(0,
1877 device_viewport_size_.width() / 2,
1878 device_viewport_size_.height() / 2);
1879 gl->Clear(GL_STENCIL_BUFFER_BIT);
1880 gl->Scissor(device_viewport_size_.width() / 2,
1881 device_viewport_size_.height() / 2,
1882 device_viewport_size_.width(),
1883 device_viewport_size_.height());
1884 gl->Clear(GL_STENCIL_BUFFER_BIT);
1888 TEST_F(ExternalStencilPixelTest, StencilTestEnabled) {
1889 ClearBackgroundToGreen();
1890 PopulateStencilBuffer();
1891 this->EnableExternalStencilTest();
1893 // Draw a blue quad that covers the entire device viewport. It should be
1894 // clipped to the bottom left and top right corners by the external stencil.
1895 gfx::Rect rect(this->device_viewport_size_);
1896 RenderPassId id(1, 1);
1897 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1898 SharedQuadState* blue_shared_state =
1899 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1900 SolidColorDrawQuad* blue =
1901 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1902 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1903 pass->has_transparent_background = false;
1904 RenderPassList pass_list;
1905 pass_list.push_back(pass.Pass());
1907 EXPECT_TRUE(this->RunPixelTest(
1908 &pass_list,
1909 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1910 ExactPixelComparator(true)));
1913 TEST_F(ExternalStencilPixelTest, StencilTestDisabled) {
1914 PopulateStencilBuffer();
1916 // Draw a green quad that covers the entire device viewport. The stencil
1917 // buffer should be ignored.
1918 gfx::Rect rect(this->device_viewport_size_);
1919 RenderPassId id(1, 1);
1920 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1921 SharedQuadState* green_shared_state =
1922 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1923 SolidColorDrawQuad* green =
1924 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1925 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
1926 RenderPassList pass_list;
1927 pass_list.push_back(pass.Pass());
1929 EXPECT_TRUE(this->RunPixelTest(
1930 &pass_list,
1931 base::FilePath(FILE_PATH_LITERAL("green.png")),
1932 ExactPixelComparator(true)));
1935 TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) {
1936 // The stencil test should apply only to the final render pass.
1937 ClearBackgroundToGreen();
1938 PopulateStencilBuffer();
1939 this->EnableExternalStencilTest();
1941 gfx::Rect viewport_rect(this->device_viewport_size_);
1943 RenderPassId root_pass_id(1, 1);
1944 scoped_ptr<RenderPass> root_pass =
1945 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1946 root_pass->has_transparent_background = false;
1948 RenderPassId child_pass_id(2, 2);
1949 gfx::Rect pass_rect(this->device_viewport_size_);
1950 gfx::Transform transform_to_root;
1951 scoped_ptr<RenderPass> child_pass =
1952 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1954 gfx::Transform content_to_target_transform;
1955 SharedQuadState* shared_state = CreateTestSharedQuadState(
1956 content_to_target_transform, viewport_rect, child_pass.get());
1958 gfx::Rect blue_rect(0,
1960 this->device_viewport_size_.width(),
1961 this->device_viewport_size_.height());
1962 SolidColorDrawQuad* blue =
1963 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1964 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1966 SharedQuadState* pass_shared_state =
1967 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1968 CreateTestRenderPassDrawQuad(
1969 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1970 RenderPassList pass_list;
1971 pass_list.push_back(child_pass.Pass());
1972 pass_list.push_back(root_pass.Pass());
1974 EXPECT_TRUE(this->RunPixelTest(
1975 &pass_list,
1976 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1977 ExactPixelComparator(true)));
1980 TEST_F(ExternalStencilPixelTest, DeviceClip) {
1981 ClearBackgroundToGreen();
1982 gfx::Rect clip_rect(gfx::Point(150, 150), gfx::Size(50, 50));
1983 this->ForceDeviceClip(clip_rect);
1985 // Draw a blue quad that covers the entire device viewport. It should be
1986 // clipped to the bottom right corner by the device clip.
1987 gfx::Rect rect(this->device_viewport_size_);
1988 RenderPassId id(1, 1);
1989 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1990 SharedQuadState* blue_shared_state =
1991 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1992 SolidColorDrawQuad* blue =
1993 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1994 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1995 RenderPassList pass_list;
1996 pass_list.push_back(pass.Pass());
1998 EXPECT_TRUE(this->RunPixelTest(
1999 &pass_list,
2000 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
2001 ExactPixelComparator(true)));
2004 // Software renderer does not support anti-aliased edges.
2005 TEST_F(GLRendererPixelTest, AntiAliasing) {
2006 gfx::Rect rect(this->device_viewport_size_);
2008 RenderPassId id(1, 1);
2009 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2011 gfx::Transform red_content_to_target_transform;
2012 red_content_to_target_transform.Rotate(10);
2013 SharedQuadState* red_shared_state = CreateTestSharedQuadState(
2014 red_content_to_target_transform, rect, pass.get());
2016 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2017 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
2019 gfx::Transform yellow_content_to_target_transform;
2020 yellow_content_to_target_transform.Rotate(5);
2021 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
2022 yellow_content_to_target_transform, rect, pass.get());
2024 SolidColorDrawQuad* yellow =
2025 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2026 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
2028 gfx::Transform blue_content_to_target_transform;
2029 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2030 blue_content_to_target_transform, rect, pass.get());
2032 SolidColorDrawQuad* blue =
2033 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2034 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2036 RenderPassList pass_list;
2037 pass_list.push_back(pass.Pass());
2039 EXPECT_TRUE(this->RunPixelTest(
2040 &pass_list,
2041 base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")),
2042 FuzzyPixelOffByOneComparator(true)));
2045 // This test tests that anti-aliasing works for axis aligned quads.
2046 // Anti-aliasing is only supported in the gl renderer.
2047 TEST_F(GLRendererPixelTest, AxisAligned) {
2048 gfx::Rect rect(this->device_viewport_size_);
2050 RenderPassId id(1, 1);
2051 gfx::Transform transform_to_root;
2052 scoped_ptr<RenderPass> pass =
2053 CreateTestRenderPass(id, rect, transform_to_root);
2055 gfx::Transform red_content_to_target_transform;
2056 red_content_to_target_transform.Translate(50, 50);
2057 red_content_to_target_transform.Scale(
2058 0.5f + 1.0f / (rect.width() * 2.0f),
2059 0.5f + 1.0f / (rect.height() * 2.0f));
2060 SharedQuadState* red_shared_state = CreateTestSharedQuadState(
2061 red_content_to_target_transform, rect, pass.get());
2063 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2064 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
2066 gfx::Transform yellow_content_to_target_transform;
2067 yellow_content_to_target_transform.Translate(25.5f, 25.5f);
2068 yellow_content_to_target_transform.Scale(0.5f, 0.5f);
2069 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
2070 yellow_content_to_target_transform, rect, pass.get());
2072 SolidColorDrawQuad* yellow =
2073 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2074 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
2076 gfx::Transform blue_content_to_target_transform;
2077 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2078 blue_content_to_target_transform, rect, pass.get());
2080 SolidColorDrawQuad* blue =
2081 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2082 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2084 RenderPassList pass_list;
2085 pass_list.push_back(pass.Pass());
2087 EXPECT_TRUE(this->RunPixelTest(
2088 &pass_list,
2089 base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")),
2090 ExactPixelComparator(true)));
2093 // This test tests that forcing anti-aliasing off works as expected.
2094 // Anti-aliasing is only supported in the gl renderer.
2095 TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) {
2096 gfx::Rect rect(this->device_viewport_size_);
2098 RenderPassId id(1, 1);
2099 gfx::Transform transform_to_root;
2100 scoped_ptr<RenderPass> pass =
2101 CreateTestRenderPass(id, rect, transform_to_root);
2103 gfx::Transform hole_content_to_target_transform;
2104 hole_content_to_target_transform.Translate(50, 50);
2105 hole_content_to_target_transform.Scale(
2106 0.5f + 1.0f / (rect.width() * 2.0f),
2107 0.5f + 1.0f / (rect.height() * 2.0f));
2108 SharedQuadState* hole_shared_state = CreateTestSharedQuadState(
2109 hole_content_to_target_transform, rect, pass.get());
2111 SolidColorDrawQuad* hole =
2112 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2113 hole->SetAll(
2114 hole_shared_state, rect, rect, rect, false, SK_ColorTRANSPARENT, true);
2116 gfx::Transform green_content_to_target_transform;
2117 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2118 green_content_to_target_transform, rect, pass.get());
2120 SolidColorDrawQuad* green =
2121 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2122 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
2124 RenderPassList pass_list;
2125 pass_list.push_back(pass.Pass());
2127 EXPECT_TRUE(this->RunPixelTest(
2128 &pass_list,
2129 base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")),
2130 ExactPixelComparator(false)));
2133 TEST_F(GLRendererPixelTest, AntiAliasingPerspective) {
2134 gfx::Rect rect(this->device_viewport_size_);
2136 scoped_ptr<RenderPass> pass =
2137 CreateTestRootRenderPass(RenderPassId(1, 1), rect);
2139 gfx::Rect red_rect(0, 0, 180, 500);
2140 gfx::Transform red_content_to_target_transform(
2141 1.0f, 2.4520f, 10.6206f, 19.0f,
2142 0.0f, 0.3528f, 5.9737f, 9.5f,
2143 0.0f, -0.2250f, -0.9744f, 0.0f,
2144 0.0f, 0.0225f, 0.0974f, 1.0f);
2145 SharedQuadState* red_shared_state = CreateTestSharedQuadState(
2146 red_content_to_target_transform, red_rect, pass.get());
2147 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2148 red->SetNew(red_shared_state, red_rect, red_rect, SK_ColorRED, false);
2150 gfx::Rect green_rect(19, 7, 180, 10);
2151 SharedQuadState* green_shared_state =
2152 CreateTestSharedQuadState(gfx::Transform(), green_rect, pass.get());
2153 SolidColorDrawQuad* green =
2154 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2155 green->SetNew(
2156 green_shared_state, green_rect, green_rect, SK_ColorGREEN, false);
2158 SharedQuadState* blue_shared_state =
2159 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
2160 SolidColorDrawQuad* blue =
2161 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2162 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2164 RenderPassList pass_list;
2165 pass_list.push_back(pass.Pass());
2167 EXPECT_TRUE(this->RunPixelTest(
2168 &pass_list,
2169 base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")),
2170 FuzzyPixelOffByOneComparator(true)));
2173 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadIdentityScale) {
2174 gfx::Size pile_tile_size(1000, 1000);
2175 gfx::Rect viewport(this->device_viewport_size_);
2176 // TODO(enne): the renderer should figure this out on its own.
2177 ResourceFormat texture_format = RGBA_8888;
2178 bool nearest_neighbor = false;
2180 RenderPassId id(1, 1);
2181 gfx::Transform transform_to_root;
2182 scoped_ptr<RenderPass> pass =
2183 CreateTestRenderPass(id, viewport, transform_to_root);
2185 // One clipped blue quad in the lower right corner. Outside the clip
2186 // is red, which should not appear.
2187 gfx::Rect blue_rect(gfx::Size(100, 100));
2188 gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50));
2190 scoped_ptr<FakePicturePile> blue_recording =
2191 FakePicturePile::CreateFilledPile(pile_tile_size, blue_rect.size());
2192 SkPaint red_paint;
2193 red_paint.setColor(SK_ColorRED);
2194 blue_recording->add_draw_rect_with_paint(blue_rect, red_paint);
2195 SkPaint blue_paint;
2196 blue_paint.setColor(SK_ColorBLUE);
2197 blue_recording->add_draw_rect_with_paint(blue_clip_rect, blue_paint);
2198 blue_recording->Rerecord();
2200 scoped_refptr<FakePicturePileImpl> blue_pile =
2201 FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);
2203 gfx::Transform blue_content_to_target_transform;
2204 gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right());
2205 blue_content_to_target_transform.Translate(offset.x(), offset.y());
2206 gfx::RectF blue_scissor_rect = blue_clip_rect;
2207 blue_content_to_target_transform.TransformRect(&blue_scissor_rect);
2208 SharedQuadState* blue_shared_state =
2209 CreateTestSharedQuadStateClipped(blue_content_to_target_transform,
2210 blue_rect,
2211 gfx::ToEnclosingRect(blue_scissor_rect),
2212 pass.get());
2214 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2216 blue_quad->SetNew(blue_shared_state,
2217 viewport, // Intentionally bigger than clip.
2218 gfx::Rect(), viewport, gfx::RectF(viewport),
2219 viewport.size(), nearest_neighbor, texture_format, viewport,
2220 1.f, blue_pile.get());
2222 // One viewport-filling green quad.
2223 scoped_ptr<FakePicturePile> green_recording =
2224 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2225 SkPaint green_paint;
2226 green_paint.setColor(SK_ColorGREEN);
2227 green_recording->add_draw_rect_with_paint(viewport, green_paint);
2228 green_recording->Rerecord();
2229 scoped_refptr<FakePicturePileImpl> green_pile =
2230 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2232 gfx::Transform green_content_to_target_transform;
2233 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2234 green_content_to_target_transform, viewport, pass.get());
2236 PictureDrawQuad* green_quad =
2237 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2238 green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
2239 gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(),
2240 nearest_neighbor, texture_format, viewport, 1.f,
2241 green_pile.get());
2243 RenderPassList pass_list;
2244 pass_list.push_back(pass.Pass());
2246 EXPECT_TRUE(this->RunPixelTest(
2247 &pass_list,
2248 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
2249 ExactPixelComparator(true)));
2252 // Not WithSkiaGPUBackend since that path currently requires tiles for opacity.
2253 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadOpacity) {
2254 gfx::Size pile_tile_size(1000, 1000);
2255 gfx::Rect viewport(this->device_viewport_size_);
2256 ResourceFormat texture_format = RGBA_8888;
2257 bool nearest_neighbor = false;
2259 RenderPassId id(1, 1);
2260 gfx::Transform transform_to_root;
2261 scoped_ptr<RenderPass> pass =
2262 CreateTestRenderPass(id, viewport, transform_to_root);
2264 // One viewport-filling 0.5-opacity green quad.
2265 scoped_ptr<FakePicturePile> green_recording =
2266 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2267 SkPaint green_paint;
2268 green_paint.setColor(SK_ColorGREEN);
2269 green_recording->add_draw_rect_with_paint(viewport, green_paint);
2270 green_recording->Rerecord();
2271 scoped_refptr<FakePicturePileImpl> green_pile =
2272 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2274 gfx::Transform green_content_to_target_transform;
2275 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2276 green_content_to_target_transform, viewport, pass.get());
2277 green_shared_state->opacity = 0.5f;
2279 PictureDrawQuad* green_quad =
2280 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2281 green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
2282 gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
2283 texture_format, viewport, 1.f, green_pile.get());
2285 // One viewport-filling white quad.
2286 scoped_ptr<FakePicturePile> white_recording =
2287 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2288 SkPaint white_paint;
2289 white_paint.setColor(SK_ColorWHITE);
2290 white_recording->add_draw_rect_with_paint(viewport, white_paint);
2291 white_recording->Rerecord();
2292 scoped_refptr<FakePicturePileImpl> white_pile =
2293 FakePicturePileImpl::CreateFromPile(white_recording.get(), nullptr);
2295 gfx::Transform white_content_to_target_transform;
2296 SharedQuadState* white_shared_state = CreateTestSharedQuadState(
2297 white_content_to_target_transform, viewport, pass.get());
2299 PictureDrawQuad* white_quad =
2300 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2301 white_quad->SetNew(white_shared_state, viewport, gfx::Rect(), viewport,
2302 gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
2303 texture_format, viewport, 1.f, white_pile.get());
2305 RenderPassList pass_list;
2306 pass_list.push_back(pass.Pass());
2308 EXPECT_TRUE(this->RunPixelTest(
2309 &pass_list,
2310 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
2311 FuzzyPixelOffByOneComparator(true)));
2314 template<typename TypeParam> bool IsSoftwareRenderer() {
2315 return false;
2318 template<>
2319 bool IsSoftwareRenderer<SoftwareRenderer>() {
2320 return true;
2323 template<>
2324 bool IsSoftwareRenderer<SoftwareRendererWithExpandedViewport>() {
2325 return true;
2328 // If we disable image filtering, then a 2x2 bitmap should appear as four
2329 // huge sharp squares.
2330 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadDisableImageFiltering) {
2331 // We only care about this in software mode since bilinear filtering is
2332 // cheap in hardware.
2333 if (!IsSoftwareRenderer<TypeParam>())
2334 return;
2336 gfx::Size pile_tile_size(1000, 1000);
2337 gfx::Rect viewport(this->device_viewport_size_);
2338 ResourceFormat texture_format = RGBA_8888;
2339 bool nearest_neighbor = false;
2341 RenderPassId id(1, 1);
2342 gfx::Transform transform_to_root;
2343 scoped_ptr<RenderPass> pass =
2344 CreateTestRenderPass(id, viewport, transform_to_root);
2346 SkBitmap bitmap;
2347 bitmap.allocN32Pixels(2, 2);
2349 SkAutoLockPixels lock(bitmap);
2350 SkCanvas canvas(bitmap);
2351 canvas.drawPoint(0, 0, SK_ColorGREEN);
2352 canvas.drawPoint(0, 1, SK_ColorBLUE);
2353 canvas.drawPoint(1, 0, SK_ColorBLUE);
2354 canvas.drawPoint(1, 1, SK_ColorGREEN);
2357 scoped_ptr<FakePicturePile> recording =
2358 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2359 SkPaint paint;
2360 paint.setFilterQuality(kLow_SkFilterQuality);
2361 recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
2362 recording->Rerecord();
2363 scoped_refptr<FakePicturePileImpl> pile =
2364 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2366 gfx::Transform content_to_target_transform;
2367 SharedQuadState* shared_state = CreateTestSharedQuadState(
2368 content_to_target_transform, viewport, pass.get());
2370 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2371 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
2372 gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
2373 texture_format, viewport, 1.f, pile.get());
2375 RenderPassList pass_list;
2376 pass_list.push_back(pass.Pass());
2378 this->disable_picture_quad_image_filtering_ = true;
2380 EXPECT_TRUE(this->RunPixelTest(
2381 &pass_list,
2382 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2383 ExactPixelComparator(true)));
2386 // This disables filtering by setting |nearest_neighbor| on the PictureDrawQuad.
2387 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNearestNeighbor) {
2388 gfx::Size pile_tile_size(1000, 1000);
2389 gfx::Rect viewport(this->device_viewport_size_);
2390 ResourceFormat texture_format = RGBA_8888;
2391 bool nearest_neighbor = true;
2393 RenderPassId id(1, 1);
2394 gfx::Transform transform_to_root;
2395 scoped_ptr<RenderPass> pass =
2396 CreateTestRenderPass(id, viewport, transform_to_root);
2398 SkBitmap bitmap;
2399 bitmap.allocN32Pixels(2, 2);
2401 SkAutoLockPixels lock(bitmap);
2402 SkCanvas canvas(bitmap);
2403 canvas.drawPoint(0, 0, SK_ColorGREEN);
2404 canvas.drawPoint(0, 1, SK_ColorBLUE);
2405 canvas.drawPoint(1, 0, SK_ColorBLUE);
2406 canvas.drawPoint(1, 1, SK_ColorGREEN);
2409 scoped_ptr<FakePicturePile> recording =
2410 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2411 SkPaint paint;
2412 paint.setFilterQuality(kLow_SkFilterQuality);
2413 recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
2414 recording->Rerecord();
2415 scoped_refptr<FakePicturePileImpl> pile =
2416 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2418 gfx::Transform content_to_target_transform;
2419 SharedQuadState* shared_state = CreateTestSharedQuadState(
2420 content_to_target_transform, viewport, pass.get());
2422 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2423 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
2424 gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
2425 texture_format, viewport, 1.f, pile.get());
2427 RenderPassList pass_list;
2428 pass_list.push_back(pass.Pass());
2430 EXPECT_TRUE(this->RunPixelTest(
2431 &pass_list,
2432 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2433 ExactPixelComparator(true)));
2436 // This disables filtering by setting |nearest_neighbor| on the TileDrawQuad.
2437 TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) {
2438 gfx::Rect viewport(this->device_viewport_size_);
2439 bool swizzle_contents = true;
2440 bool nearest_neighbor = true;
2442 SkBitmap bitmap;
2443 bitmap.allocN32Pixels(2, 2);
2445 SkAutoLockPixels lock(bitmap);
2446 SkCanvas canvas(bitmap);
2447 canvas.drawPoint(0, 0, SK_ColorGREEN);
2448 canvas.drawPoint(0, 1, SK_ColorBLUE);
2449 canvas.drawPoint(1, 0, SK_ColorBLUE);
2450 canvas.drawPoint(1, 1, SK_ColorGREEN);
2453 gfx::Size tile_size(2, 2);
2454 ResourceProvider::ResourceId resource =
2455 this->resource_provider_->CreateResource(
2456 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2457 RGBA_8888);
2460 SkAutoLockPixels lock(bitmap);
2461 this->resource_provider_->CopyToResource(
2462 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
2465 RenderPassId id(1, 1);
2466 gfx::Transform transform_to_root;
2467 scoped_ptr<RenderPass> pass =
2468 CreateTestRenderPass(id, viewport, transform_to_root);
2470 gfx::Transform content_to_target_transform;
2471 SharedQuadState* shared_state = CreateTestSharedQuadState(
2472 content_to_target_transform, viewport, pass.get());
2474 TileDrawQuad* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>();
2475 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource,
2476 gfx::Rect(tile_size), tile_size, swizzle_contents,
2477 nearest_neighbor);
2479 RenderPassList pass_list;
2480 pass_list.push_back(pass.Pass());
2482 EXPECT_TRUE(this->RunPixelTest(
2483 &pass_list,
2484 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2485 ExactPixelComparator(true)));
2488 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) {
2489 gfx::Size pile_tile_size(1000, 1000);
2490 gfx::Rect viewport(this->device_viewport_size_);
2491 // TODO(enne): the renderer should figure this out on its own.
2492 ResourceFormat texture_format = RGBA_8888;
2493 bool nearest_neighbor = false;
2495 RenderPassId id(1, 1);
2496 gfx::Transform transform_to_root;
2497 scoped_ptr<RenderPass> pass =
2498 CreateTestRenderPass(id, viewport, transform_to_root);
2500 // As scaling up the blue checkerboards will cause sampling on the GPU,
2501 // a few extra "cleanup rects" need to be added to clobber the blending
2502 // to make the output image more clean. This will also test subrects
2503 // of the layer.
2504 gfx::Transform green_content_to_target_transform;
2505 gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100));
2506 gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20));
2508 scoped_ptr<FakePicturePile> green_recording =
2509 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2511 SkPaint red_paint;
2512 red_paint.setColor(SK_ColorRED);
2513 green_recording->add_draw_rect_with_paint(viewport, red_paint);
2514 SkPaint green_paint;
2515 green_paint.setColor(SK_ColorGREEN);
2516 green_recording->add_draw_rect_with_paint(green_rect1, green_paint);
2517 green_recording->add_draw_rect_with_paint(green_rect2, green_paint);
2518 green_recording->Rerecord();
2519 scoped_refptr<FakePicturePileImpl> green_pile =
2520 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2522 SharedQuadState* top_right_green_shared_quad_state =
2523 CreateTestSharedQuadState(
2524 green_content_to_target_transform, viewport, pass.get());
2526 PictureDrawQuad* green_quad1 =
2527 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2528 green_quad1->SetNew(top_right_green_shared_quad_state, green_rect1,
2529 gfx::Rect(), green_rect1, gfx::RectF(green_rect1.size()),
2530 green_rect1.size(), nearest_neighbor, texture_format,
2531 green_rect1, 1.f, green_pile.get());
2533 PictureDrawQuad* green_quad2 =
2534 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2535 green_quad2->SetNew(top_right_green_shared_quad_state, green_rect2,
2536 gfx::Rect(), green_rect2, gfx::RectF(green_rect2.size()),
2537 green_rect2.size(), nearest_neighbor, texture_format,
2538 green_rect2, 1.f, green_pile.get());
2540 // Add a green clipped checkerboard in the bottom right to help test
2541 // interleaving picture quad content and solid color content.
2542 gfx::Rect bottom_right_rect(
2543 gfx::Point(viewport.width() / 2, viewport.height() / 2),
2544 gfx::Size(viewport.width() / 2, viewport.height() / 2));
2545 SharedQuadState* bottom_right_green_shared_state =
2546 CreateTestSharedQuadStateClipped(green_content_to_target_transform,
2547 viewport,
2548 bottom_right_rect,
2549 pass.get());
2550 SolidColorDrawQuad* bottom_right_color_quad =
2551 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2552 bottom_right_color_quad->SetNew(bottom_right_green_shared_state,
2553 viewport,
2554 viewport,
2555 SK_ColorGREEN,
2556 false);
2558 // Add two blue checkerboards taking up the bottom left and top right,
2559 // but use content scales as content rects to make this happen.
2560 // The content is at a 4x content scale.
2561 gfx::Rect layer_rect(gfx::Size(20, 30));
2562 float contents_scale = 4.f;
2563 // Two rects that touch at their corners, arbitrarily placed in the layer.
2564 gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f));
2565 gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f));
2566 gfx::RectF union_layer_rect = blue_layer_rect1;
2567 union_layer_rect.Union(blue_layer_rect2);
2569 // Because scaling up will cause sampling outside the rects, add one extra
2570 // pixel of buffer at the final content scale.
2571 float inset = -1.f / contents_scale;
2572 blue_layer_rect1.Inset(inset, inset, inset, inset);
2573 blue_layer_rect2.Inset(inset, inset, inset, inset);
2575 scoped_ptr<FakePicturePile> recording =
2576 FakePicturePile::CreateFilledPile(pile_tile_size, layer_rect.size());
2578 Region outside(layer_rect);
2579 outside.Subtract(gfx::ToEnclosingRect(union_layer_rect));
2580 for (Region::Iterator iter(outside); iter.has_rect(); iter.next()) {
2581 recording->add_draw_rect_with_paint(iter.rect(), red_paint);
2584 SkPaint blue_paint;
2585 blue_paint.setColor(SK_ColorBLUE);
2586 recording->add_draw_rect_with_paint(blue_layer_rect1, blue_paint);
2587 recording->add_draw_rect_with_paint(blue_layer_rect2, blue_paint);
2588 recording->Rerecord();
2589 scoped_refptr<FakePicturePileImpl> pile =
2590 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2592 gfx::Rect content_rect(
2593 gfx::ScaleToEnclosingRect(layer_rect, contents_scale));
2594 gfx::Rect content_union_rect(
2595 gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale)));
2597 // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels,
2598 // so scale an additional 10x to make them 100x100.
2599 gfx::Transform content_to_target_transform;
2600 content_to_target_transform.Scale(10.0, 10.0);
2601 gfx::Rect quad_content_rect(gfx::Size(20, 20));
2602 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2603 content_to_target_transform, quad_content_rect, pass.get());
2605 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2606 blue_quad->SetNew(blue_shared_state, quad_content_rect, gfx::Rect(),
2607 quad_content_rect, gfx::RectF(quad_content_rect),
2608 content_union_rect.size(), nearest_neighbor, texture_format,
2609 content_union_rect, contents_scale, pile.get());
2611 // Fill left half of viewport with green.
2612 gfx::Transform half_green_content_to_target_transform;
2613 gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height()));
2614 SharedQuadState* half_green_shared_state = CreateTestSharedQuadState(
2615 half_green_content_to_target_transform, half_green_rect, pass.get());
2616 SolidColorDrawQuad* half_color_quad =
2617 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2618 half_color_quad->SetNew(half_green_shared_state,
2619 half_green_rect,
2620 half_green_rect,
2621 SK_ColorGREEN,
2622 false);
2624 RenderPassList pass_list;
2625 pass_list.push_back(pass.Pass());
2627 EXPECT_TRUE(this->RunPixelTest(
2628 &pass_list,
2629 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2630 ExactPixelComparator(true)));
2633 typedef RendererPixelTest<GLRendererWithFlippedSurface>
2634 GLRendererPixelTestWithFlippedOutputSurface;
2636 TEST_F(GLRendererPixelTestWithFlippedOutputSurface, ExplicitFlipTest) {
2637 // This draws a blue rect above a yellow rect with an inverted output surface.
2638 gfx::Rect viewport_rect(this->device_viewport_size_);
2640 RenderPassId root_pass_id(1, 1);
2641 scoped_ptr<RenderPass> root_pass =
2642 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2644 RenderPassId child_pass_id(2, 2);
2645 gfx::Rect pass_rect(this->device_viewport_size_);
2646 gfx::Transform transform_to_root;
2647 scoped_ptr<RenderPass> child_pass =
2648 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2650 gfx::Transform content_to_target_transform;
2651 SharedQuadState* shared_state = CreateTestSharedQuadState(
2652 content_to_target_transform, viewport_rect, child_pass.get());
2654 gfx::Rect blue_rect(0,
2656 this->device_viewport_size_.width(),
2657 this->device_viewport_size_.height() / 2);
2658 SolidColorDrawQuad* blue =
2659 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2660 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2661 gfx::Rect yellow_rect(0,
2662 this->device_viewport_size_.height() / 2,
2663 this->device_viewport_size_.width(),
2664 this->device_viewport_size_.height() / 2);
2665 SolidColorDrawQuad* yellow =
2666 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2667 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
2669 SharedQuadState* pass_shared_state =
2670 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2671 CreateTestRenderPassDrawQuad(
2672 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2674 RenderPassList pass_list;
2675 pass_list.push_back(child_pass.Pass());
2676 pass_list.push_back(root_pass.Pass());
2678 EXPECT_TRUE(this->RunPixelTest(
2679 &pass_list,
2680 base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")),
2681 ExactPixelComparator(true)));
2684 TEST_F(GLRendererPixelTestWithFlippedOutputSurface, CheckChildPassUnflipped) {
2685 // This draws a blue rect above a yellow rect with an inverted output surface.
2686 gfx::Rect viewport_rect(this->device_viewport_size_);
2688 RenderPassId root_pass_id(1, 1);
2689 scoped_ptr<RenderPass> root_pass =
2690 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2692 RenderPassId child_pass_id(2, 2);
2693 gfx::Rect pass_rect(this->device_viewport_size_);
2694 gfx::Transform transform_to_root;
2695 scoped_ptr<RenderPass> child_pass =
2696 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2698 gfx::Transform content_to_target_transform;
2699 SharedQuadState* shared_state = CreateTestSharedQuadState(
2700 content_to_target_transform, viewport_rect, child_pass.get());
2702 gfx::Rect blue_rect(0,
2704 this->device_viewport_size_.width(),
2705 this->device_viewport_size_.height() / 2);
2706 SolidColorDrawQuad* blue =
2707 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2708 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2709 gfx::Rect yellow_rect(0,
2710 this->device_viewport_size_.height() / 2,
2711 this->device_viewport_size_.width(),
2712 this->device_viewport_size_.height() / 2);
2713 SolidColorDrawQuad* yellow =
2714 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2715 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
2717 SharedQuadState* pass_shared_state =
2718 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2719 CreateTestRenderPassDrawQuad(
2720 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2722 RenderPassList pass_list;
2723 pass_list.push_back(child_pass.Pass());
2724 pass_list.push_back(root_pass.Pass());
2726 // Check that the child pass remains unflipped.
2727 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
2728 &pass_list,
2729 pass_list.front(),
2730 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
2731 ExactPixelComparator(true)));
2734 TEST_F(GLRendererPixelTest, CheckReadbackSubset) {
2735 gfx::Rect viewport_rect(this->device_viewport_size_);
2737 RenderPassId root_pass_id(1, 1);
2738 scoped_ptr<RenderPass> root_pass =
2739 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2741 RenderPassId child_pass_id(2, 2);
2742 gfx::Rect pass_rect(this->device_viewport_size_);
2743 gfx::Transform transform_to_root;
2744 scoped_ptr<RenderPass> child_pass =
2745 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2747 gfx::Transform content_to_target_transform;
2748 SharedQuadState* shared_state = CreateTestSharedQuadState(
2749 content_to_target_transform, viewport_rect, child_pass.get());
2751 // Draw a green quad full-size with a blue quad in the lower-right corner.
2752 gfx::Rect blue_rect(this->device_viewport_size_.width() * 3 / 4,
2753 this->device_viewport_size_.height() * 3 / 4,
2754 this->device_viewport_size_.width() * 3 / 4,
2755 this->device_viewport_size_.height() * 3 / 4);
2756 SolidColorDrawQuad* blue =
2757 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2758 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2759 gfx::Rect green_rect(0,
2761 this->device_viewport_size_.width(),
2762 this->device_viewport_size_.height());
2763 SolidColorDrawQuad* green =
2764 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2765 green->SetNew(shared_state, green_rect, green_rect, SK_ColorGREEN, false);
2767 SharedQuadState* pass_shared_state =
2768 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2769 CreateTestRenderPassDrawQuad(
2770 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2772 RenderPassList pass_list;
2773 pass_list.push_back(child_pass.Pass());
2774 pass_list.push_back(root_pass.Pass());
2776 // Check that the child pass remains unflipped.
2777 gfx::Rect capture_rect(this->device_viewport_size_.width() / 2,
2778 this->device_viewport_size_.height() / 2,
2779 this->device_viewport_size_.width() / 2,
2780 this->device_viewport_size_.height() / 2);
2781 EXPECT_TRUE(this->RunPixelTestWithReadbackTargetAndArea(
2782 &pass_list,
2783 pass_list.front(),
2784 base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")),
2785 ExactPixelComparator(true),
2786 &capture_rect));
2789 TYPED_TEST(RendererPixelTest, WrapModeRepeat) {
2790 gfx::Rect rect(this->device_viewport_size_);
2792 RenderPassId id(1, 1);
2793 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2795 SharedQuadState* shared_state =
2796 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
2798 gfx::Size texture_size(4, 4);
2799 SkPMColor colors[4] = {
2800 SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)),
2801 SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)),
2802 SkPreMultiplyColor(SkColorSetARGB(255, 0, 64, 0)),
2803 SkPreMultiplyColor(SkColorSetARGB(255, 0, 0, 0)),
2805 uint32_t pixels[16] = {
2806 colors[0], colors[0], colors[1], colors[1],
2807 colors[0], colors[0], colors[1], colors[1],
2808 colors[2], colors[2], colors[3], colors[3],
2809 colors[2], colors[2], colors[3], colors[3],
2811 ResourceProvider::ResourceId resource =
2812 this->resource_provider_->CreateResource(
2813 texture_size, GL_REPEAT, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2814 RGBA_8888);
2815 this->resource_provider_->CopyToResource(
2816 resource, reinterpret_cast<uint8_t*>(pixels), texture_size);
2818 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2819 TextureDrawQuad* texture_quad =
2820 pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2821 texture_quad->SetNew(
2822 shared_state, gfx::Rect(this->device_viewport_size_), gfx::Rect(),
2823 gfx::Rect(this->device_viewport_size_), resource,
2824 true, // premultiplied_alpha
2825 gfx::PointF(0.0f, 0.0f), // uv_top_left
2826 gfx::PointF( // uv_bottom_right
2827 this->device_viewport_size_.width() / texture_size.width(),
2828 this->device_viewport_size_.height() / texture_size.height()),
2829 SK_ColorWHITE, vertex_opacity,
2830 false, // flipped
2831 false); // nearest_neighbor
2833 RenderPassList pass_list;
2834 pass_list.push_back(pass.Pass());
2836 EXPECT_TRUE(this->RunPixelTest(
2837 &pass_list,
2838 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
2839 FuzzyPixelOffByOneComparator(true)));
2842 TYPED_TEST(RendererPixelTest, Checkerboards) {
2843 gfx::Rect rect(this->device_viewport_size_);
2845 RenderPassId id(1, 1);
2846 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2848 SharedQuadState* shared_state =
2849 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
2851 // The color's alpha value is not used.
2852 SkColor color1 = SK_ColorGREEN;
2853 color1 = SkColorSetA(color1, 0);
2854 SkColor color2 = SK_ColorBLUE;
2855 color2 = SkColorSetA(color2, 0);
2857 gfx::Rect content_rect(rect);
2859 gfx::Rect top_left(content_rect);
2860 gfx::Rect top_right(content_rect);
2861 gfx::Rect bottom_left(content_rect);
2862 gfx::Rect bottom_right(content_rect);
2863 // The format is Inset(left, top, right, bottom).
2864 top_left.Inset(0, 0, content_rect.width() / 2, content_rect.height() / 2);
2865 top_right.Inset(content_rect.width() / 2, 0, 0, content_rect.height() / 2);
2866 bottom_left.Inset(0, content_rect.height() / 2, content_rect.width() / 2, 0);
2867 bottom_right.Inset(content_rect.width() / 2, content_rect.height() / 2, 0, 0);
2869 // Appends checkerboard quads with a scale of 1.
2870 CheckerboardDrawQuad* quad =
2871 pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2872 quad->SetNew(shared_state, top_left, top_left, color1, 1.f);
2873 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2874 quad->SetNew(shared_state, top_right, top_right, color2, 1.f);
2875 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2876 quad->SetNew(shared_state, bottom_left, bottom_left, color2, 1.f);
2877 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2878 quad->SetNew(shared_state, bottom_right, bottom_right, color1, 1.f);
2880 RenderPassList pass_list;
2881 pass_list.push_back(pass.Pass());
2883 base::FilePath::StringType path =
2884 IsSoftwareRenderer<TypeParam>()
2885 ? FILE_PATH_LITERAL("four_blue_green_checkers.png")
2886 : FILE_PATH_LITERAL("checkers.png");
2887 EXPECT_TRUE(this->RunPixelTest(&pass_list, base::FilePath(path),
2888 ExactPixelComparator(true)));
2891 TYPED_TEST(RendererPixelTest, CheckerboardsScaled) {
2892 gfx::Rect rect(this->device_viewport_size_);
2894 RenderPassId id(1, 1);
2895 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2897 gfx::Transform scale;
2898 scale.Scale(2.f, 2.f);
2900 SharedQuadState* shared_state =
2901 CreateTestSharedQuadState(scale, rect, pass.get());
2903 // The color's alpha value is not used.
2904 SkColor color1 = SK_ColorGREEN;
2905 color1 = SkColorSetA(color1, 0);
2906 SkColor color2 = SK_ColorBLUE;
2907 color2 = SkColorSetA(color2, 0);
2909 gfx::Rect content_rect(rect);
2910 content_rect.Inset(0, 0, rect.width() / 2, rect.height() / 2);
2912 gfx::Rect top_left(content_rect);
2913 gfx::Rect top_right(content_rect);
2914 gfx::Rect bottom_left(content_rect);
2915 gfx::Rect bottom_right(content_rect);
2916 // The format is Inset(left, top, right, bottom).
2917 top_left.Inset(0, 0, content_rect.width() / 2, content_rect.height() / 2);
2918 top_right.Inset(content_rect.width() / 2, 0, 0, content_rect.height() / 2);
2919 bottom_left.Inset(0, content_rect.height() / 2, content_rect.width() / 2, 0);
2920 bottom_right.Inset(content_rect.width() / 2, content_rect.height() / 2, 0, 0);
2922 // Appends checkerboard quads with a scale of 2, and a shared quad state
2923 // with a scale of 2. The checkers should be scaled by 2 * 2 = 4.
2924 CheckerboardDrawQuad* quad =
2925 pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2926 quad->SetNew(shared_state, top_left, top_left, color1, 2.f);
2927 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2928 quad->SetNew(shared_state, top_right, top_right, color2, 2.f);
2929 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2930 quad->SetNew(shared_state, bottom_left, bottom_left, color2, 2.f);
2931 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
2932 quad->SetNew(shared_state, bottom_right, bottom_right, color1, 2.f);
2934 RenderPassList pass_list;
2935 pass_list.push_back(pass.Pass());
2937 base::FilePath::StringType path =
2938 IsSoftwareRenderer<TypeParam>()
2939 ? FILE_PATH_LITERAL("four_blue_green_checkers.png")
2940 : FILE_PATH_LITERAL("checkers_big.png");
2941 EXPECT_TRUE(this->RunPixelTest(&pass_list, base::FilePath(path),
2942 ExactPixelComparator(true)));
2945 #endif // !defined(OS_ANDROID)
2947 } // namespace
2948 } // namespace cc