[Android WebView] Put AndroidStreamReaderURLRequestJob into a namespace
[chromium-blink-merge.git] / cc / output / renderer_pixeltest.cc
blob8179bfae4acbc4b4781b414796f18d35b574cad9
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/core/SkSurface.h"
19 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
20 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
21 #include "ui/gfx/geometry/rect_conversions.h"
23 using gpu::gles2::GLES2Interface;
25 namespace cc {
26 namespace {
28 #if !defined(OS_ANDROID)
29 scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPassId id,
30 const gfx::Rect& rect) {
31 scoped_ptr<RenderPass> pass = RenderPass::Create();
32 const gfx::Rect output_rect = rect;
33 const gfx::Rect damage_rect = rect;
34 const gfx::Transform transform_to_root_target;
35 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
36 return pass.Pass();
39 scoped_ptr<RenderPass> CreateTestRenderPass(
40 RenderPassId id,
41 const gfx::Rect& rect,
42 const gfx::Transform& transform_to_root_target) {
43 scoped_ptr<RenderPass> pass = RenderPass::Create();
44 const gfx::Rect output_rect = rect;
45 const gfx::Rect damage_rect = rect;
46 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
47 return pass.Pass();
50 SharedQuadState* CreateTestSharedQuadState(
51 gfx::Transform quad_to_target_transform,
52 const gfx::Rect& rect,
53 RenderPass* render_pass) {
54 const gfx::Size layer_bounds = rect.size();
55 const gfx::Rect visible_layer_rect = rect;
56 const gfx::Rect clip_rect = rect;
57 const bool is_clipped = false;
58 const float opacity = 1.0f;
59 const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
60 int sorting_context_id = 0;
61 SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
62 shared_state->SetAll(quad_to_target_transform, layer_bounds,
63 visible_layer_rect, clip_rect, is_clipped, opacity,
64 blend_mode, sorting_context_id);
65 return shared_state;
68 SharedQuadState* CreateTestSharedQuadStateClipped(
69 gfx::Transform quad_to_target_transform,
70 const gfx::Rect& rect,
71 const gfx::Rect& clip_rect,
72 RenderPass* render_pass) {
73 const gfx::Size layer_bounds = rect.size();
74 const gfx::Rect visible_layer_rect = clip_rect;
75 const bool is_clipped = true;
76 const float opacity = 1.0f;
77 const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
78 int sorting_context_id = 0;
79 SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
80 shared_state->SetAll(quad_to_target_transform, layer_bounds,
81 visible_layer_rect, clip_rect, is_clipped, opacity,
82 blend_mode, sorting_context_id);
83 return shared_state;
86 void CreateTestRenderPassDrawQuad(const SharedQuadState* shared_state,
87 const gfx::Rect& rect,
88 RenderPassId pass_id,
89 RenderPass* render_pass) {
90 RenderPassDrawQuad* quad =
91 render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
92 quad->SetNew(shared_state,
93 rect,
94 rect,
95 pass_id,
96 0, // mask_resource_id
97 gfx::Vector2dF(), // mask_uv_scale
98 gfx::Size(), // mask_texture_size
99 FilterOperations(), // foreground filters
100 gfx::Vector2dF(), // filters scale
101 FilterOperations()); // background filters
104 void CreateTestTwoColoredTextureDrawQuad(const gfx::Rect& rect,
105 SkColor texel_color,
106 SkColor texel_stripe_color,
107 SkColor background_color,
108 bool premultiplied_alpha,
109 const SharedQuadState* shared_state,
110 ResourceProvider* resource_provider,
111 RenderPass* render_pass) {
112 SkPMColor pixel_color = premultiplied_alpha
113 ? SkPreMultiplyColor(texel_color)
114 : SkPackARGB32NoCheck(SkColorGetA(texel_color),
115 SkColorGetR(texel_color),
116 SkColorGetG(texel_color),
117 SkColorGetB(texel_color));
118 SkPMColor pixel_stripe_color =
119 premultiplied_alpha
120 ? SkPreMultiplyColor(texel_stripe_color)
121 : SkPackARGB32NoCheck(SkColorGetA(texel_stripe_color),
122 SkColorGetR(texel_stripe_color),
123 SkColorGetG(texel_stripe_color),
124 SkColorGetB(texel_stripe_color));
125 std::vector<uint32_t> pixels(rect.size().GetArea(), pixel_color);
126 for (int i = rect.height() / 4; i < (rect.height() * 3 / 4); ++i) {
127 for (int k = rect.width() / 4; k < (rect.width() * 3 / 4); ++k) {
128 pixels[i * rect.width() + k] = pixel_stripe_color;
131 ResourceId resource = resource_provider->CreateResource(
132 rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
133 RGBA_8888);
134 resource_provider->CopyToResource(
135 resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size());
137 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
138 const gfx::PointF uv_top_left(0.0f, 0.0f);
139 const gfx::PointF uv_bottom_right(1.0f, 1.0f);
140 const bool flipped = false;
141 const bool nearest_neighbor = false;
142 TextureDrawQuad* quad =
143 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
144 quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource,
145 premultiplied_alpha, uv_top_left, uv_bottom_right,
146 background_color, vertex_opacity, flipped, nearest_neighbor);
149 void CreateTestTextureDrawQuad(const gfx::Rect& rect,
150 SkColor texel_color,
151 SkColor background_color,
152 bool premultiplied_alpha,
153 const SharedQuadState* shared_state,
154 ResourceProvider* resource_provider,
155 RenderPass* render_pass) {
156 SkPMColor pixel_color = premultiplied_alpha ?
157 SkPreMultiplyColor(texel_color) :
158 SkPackARGB32NoCheck(SkColorGetA(texel_color),
159 SkColorGetR(texel_color),
160 SkColorGetG(texel_color),
161 SkColorGetB(texel_color));
162 size_t num_pixels = static_cast<size_t>(rect.width()) * rect.height();
163 std::vector<uint32_t> pixels(num_pixels, pixel_color);
165 ResourceId resource = resource_provider->CreateResource(
166 rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
167 RGBA_8888);
168 resource_provider->CopyToResource(
169 resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size());
171 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
173 const gfx::PointF uv_top_left(0.0f, 0.0f);
174 const gfx::PointF uv_bottom_right(1.0f, 1.0f);
175 const bool flipped = false;
176 const bool nearest_neighbor = false;
177 TextureDrawQuad* quad =
178 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
179 quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource,
180 premultiplied_alpha, uv_top_left, uv_bottom_right,
181 background_color, vertex_opacity, flipped, nearest_neighbor);
184 void CreateTestYUVVideoDrawQuad_FromVideoFrame(
185 const SharedQuadState* shared_state,
186 scoped_refptr<media::VideoFrame> video_frame,
187 uint8 alpha_value,
188 const gfx::RectF& tex_coord_rect,
189 RenderPass* render_pass,
190 VideoResourceUpdater* video_resource_updater,
191 const gfx::Rect& rect,
192 const gfx::Rect& visible_rect,
193 ResourceProvider* resource_provider) {
194 const bool with_alpha = (video_frame->format() == media::PIXEL_FORMAT_YV12A);
195 YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::REC_601;
196 int video_frame_color_space;
197 if (video_frame->metadata()->GetInteger(
198 media::VideoFrameMetadata::COLOR_SPACE, &video_frame_color_space) &&
199 video_frame_color_space == media::COLOR_SPACE_JPEG) {
200 color_space = YUVVideoDrawQuad::JPEG;
203 const gfx::Rect opaque_rect(0, 0, 0, 0);
205 if (with_alpha) {
206 memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value,
207 video_frame->stride(media::VideoFrame::kAPlane) *
208 video_frame->rows(media::VideoFrame::kAPlane));
211 VideoFrameExternalResources resources =
212 video_resource_updater->CreateExternalResourcesFromVideoFrame(
213 video_frame);
215 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
216 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
217 resources.mailboxes.size());
218 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
219 resources.release_callbacks.size());
221 ResourceId y_resource = resource_provider->CreateResourceFromTextureMailbox(
222 resources.mailboxes[media::VideoFrame::kYPlane],
223 SingleReleaseCallbackImpl::Create(
224 resources.release_callbacks[media::VideoFrame::kYPlane]));
225 ResourceId u_resource = resource_provider->CreateResourceFromTextureMailbox(
226 resources.mailboxes[media::VideoFrame::kUPlane],
227 SingleReleaseCallbackImpl::Create(
228 resources.release_callbacks[media::VideoFrame::kUPlane]));
229 ResourceId v_resource = resource_provider->CreateResourceFromTextureMailbox(
230 resources.mailboxes[media::VideoFrame::kVPlane],
231 SingleReleaseCallbackImpl::Create(
232 resources.release_callbacks[media::VideoFrame::kVPlane]));
233 ResourceId a_resource = 0;
234 if (with_alpha) {
235 a_resource = resource_provider->CreateResourceFromTextureMailbox(
236 resources.mailboxes[media::VideoFrame::kAPlane],
237 SingleReleaseCallbackImpl::Create(
238 resources.release_callbacks[media::VideoFrame::kAPlane]));
241 const gfx::Size ya_tex_size = video_frame->coded_size();
242 const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize(
243 video_frame->format(), media::VideoFrame::kUPlane,
244 video_frame->coded_size());
245 DCHECK(uv_tex_size == media::VideoFrame::PlaneSize(
246 video_frame->format(), media::VideoFrame::kVPlane,
247 video_frame->coded_size()));
248 if (with_alpha) {
249 DCHECK(ya_tex_size == media::VideoFrame::PlaneSize(
250 video_frame->format(), media::VideoFrame::kAPlane,
251 video_frame->coded_size()));
254 gfx::RectF ya_tex_coord_rect(tex_coord_rect.x() * ya_tex_size.width(),
255 tex_coord_rect.y() * ya_tex_size.height(),
256 tex_coord_rect.width() * ya_tex_size.width(),
257 tex_coord_rect.height() * ya_tex_size.height());
258 gfx::RectF uv_tex_coord_rect(tex_coord_rect.x() * uv_tex_size.width(),
259 tex_coord_rect.y() * uv_tex_size.height(),
260 tex_coord_rect.width() * uv_tex_size.width(),
261 tex_coord_rect.height() * uv_tex_size.height());
263 YUVVideoDrawQuad* yuv_quad =
264 render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
265 yuv_quad->SetNew(shared_state, rect, opaque_rect, visible_rect,
266 ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size,
267 uv_tex_size, y_resource, u_resource, v_resource, a_resource,
268 color_space);
271 void CreateTestYUVVideoDrawQuad_Striped(
272 const SharedQuadState* shared_state,
273 media::VideoPixelFormat format,
274 bool is_transparent,
275 const gfx::RectF& tex_coord_rect,
276 RenderPass* render_pass,
277 VideoResourceUpdater* video_resource_updater,
278 const gfx::Rect& rect,
279 const gfx::Rect& visible_rect,
280 ResourceProvider* resource_provider) {
281 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
282 format, rect.size(), rect, rect.size(), base::TimeDelta());
284 // YUV values representing a striped pattern, for validating texture
285 // coordinates for sampling.
286 uint8_t y_value = 0;
287 uint8_t u_value = 0;
288 uint8_t v_value = 0;
289 for (int i = 0; i < video_frame->rows(media::VideoFrame::kYPlane); ++i) {
290 uint8_t* y_row = video_frame->data(media::VideoFrame::kYPlane) +
291 video_frame->stride(media::VideoFrame::kYPlane) * i;
292 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kYPlane);
293 ++j) {
294 y_row[j] = (y_value += 1);
297 for (int i = 0; i < video_frame->rows(media::VideoFrame::kUPlane); ++i) {
298 uint8_t* u_row = video_frame->data(media::VideoFrame::kUPlane) +
299 video_frame->stride(media::VideoFrame::kUPlane) * i;
300 uint8_t* v_row = video_frame->data(media::VideoFrame::kVPlane) +
301 video_frame->stride(media::VideoFrame::kVPlane) * i;
302 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kUPlane);
303 ++j) {
304 u_row[j] = (u_value += 3);
305 v_row[j] = (v_value += 5);
308 uint8 alpha_value = is_transparent ? 0 : 128;
309 CreateTestYUVVideoDrawQuad_FromVideoFrame(
310 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
311 video_resource_updater, rect, visible_rect, resource_provider);
314 // Creates a video frame of size background_size filled with yuv_background,
315 // and then draws a foreground rectangle in a different color on top of
316 // that. The foreground rectangle must have coordinates that are divisible
317 // by 2 because YUV is a block format.
318 void CreateTestYUVVideoDrawQuad_TwoColor(
319 const SharedQuadState* shared_state,
320 media::VideoPixelFormat format,
321 media::ColorSpace color_space,
322 bool is_transparent,
323 const gfx::RectF& tex_coord_rect,
324 const gfx::Size& background_size,
325 const gfx::Rect& visible_rect,
326 uint8 y_background,
327 uint8 u_background,
328 uint8 v_background,
329 const gfx::Rect& foreground_rect,
330 uint8 y_foreground,
331 uint8 u_foreground,
332 uint8 v_foreground,
333 RenderPass* render_pass,
334 VideoResourceUpdater* video_resource_updater,
335 ResourceProvider* resource_provider) {
336 const gfx::Rect rect(background_size);
338 scoped_refptr<media::VideoFrame> video_frame =
339 media::VideoFrame::CreateFrame(format, background_size, foreground_rect,
340 foreground_rect.size(), base::TimeDelta());
341 video_frame->metadata()->SetInteger(media::VideoFrameMetadata::COLOR_SPACE,
342 color_space);
344 int planes[] = {media::VideoFrame::kYPlane,
345 media::VideoFrame::kUPlane,
346 media::VideoFrame::kVPlane};
347 uint8 yuv_background[] = {y_background, u_background, v_background};
348 uint8 yuv_foreground[] = {y_foreground, u_foreground, v_foreground};
349 int sample_size[] = {1, 2, 2};
351 for (int i = 0; i < 3; ++i) {
352 memset(video_frame->data(planes[i]), yuv_background[i],
353 video_frame->stride(planes[i]) * video_frame->rows(planes[i]));
356 for (int i = 0; i < 3; ++i) {
357 // Since yuv encoding uses block encoding, widths have to be divisible
358 // by the sample size in order for this function to behave properly.
359 DCHECK_EQ(foreground_rect.x() % sample_size[i], 0);
360 DCHECK_EQ(foreground_rect.y() % sample_size[i], 0);
361 DCHECK_EQ(foreground_rect.width() % sample_size[i], 0);
362 DCHECK_EQ(foreground_rect.height() % sample_size[i], 0);
364 gfx::Rect sample_rect(foreground_rect.x() / sample_size[i],
365 foreground_rect.y() / sample_size[i],
366 foreground_rect.width() / sample_size[i],
367 foreground_rect.height() / sample_size[i]);
368 for (int y = sample_rect.y(); y < sample_rect.bottom(); ++y) {
369 for (int x = sample_rect.x(); x < sample_rect.right(); ++x) {
370 size_t offset = y * video_frame->stride(planes[i]) + x;
371 video_frame->data(planes[i])[offset] = yuv_foreground[i];
376 uint8 alpha_value = 255;
377 CreateTestYUVVideoDrawQuad_FromVideoFrame(
378 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
379 video_resource_updater, rect, visible_rect, resource_provider);
382 void CreateTestYUVVideoDrawQuad_Solid(
383 const SharedQuadState* shared_state,
384 media::VideoPixelFormat format,
385 media::ColorSpace color_space,
386 bool is_transparent,
387 const gfx::RectF& tex_coord_rect,
388 uint8 y,
389 uint8 u,
390 uint8 v,
391 RenderPass* render_pass,
392 VideoResourceUpdater* video_resource_updater,
393 const gfx::Rect& rect,
394 const gfx::Rect& visible_rect,
395 ResourceProvider* resource_provider) {
396 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
397 format, rect.size(), rect, rect.size(), base::TimeDelta());
398 video_frame->metadata()->SetInteger(media::VideoFrameMetadata::COLOR_SPACE,
399 color_space);
401 // YUV values of a solid, constant, color. Useful for testing that color
402 // space/color range are being handled properly.
403 memset(video_frame->data(media::VideoFrame::kYPlane), y,
404 video_frame->stride(media::VideoFrame::kYPlane) *
405 video_frame->rows(media::VideoFrame::kYPlane));
406 memset(video_frame->data(media::VideoFrame::kUPlane), u,
407 video_frame->stride(media::VideoFrame::kUPlane) *
408 video_frame->rows(media::VideoFrame::kUPlane));
409 memset(video_frame->data(media::VideoFrame::kVPlane), v,
410 video_frame->stride(media::VideoFrame::kVPlane) *
411 video_frame->rows(media::VideoFrame::kVPlane));
413 uint8 alpha_value = is_transparent ? 0 : 128;
414 CreateTestYUVVideoDrawQuad_FromVideoFrame(
415 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
416 video_resource_updater, rect, visible_rect, resource_provider);
419 typedef ::testing::Types<GLRenderer,
420 SoftwareRenderer,
421 GLRendererWithExpandedViewport,
422 SoftwareRendererWithExpandedViewport> RendererTypes;
423 TYPED_TEST_CASE(RendererPixelTest, RendererTypes);
425 template <typename RendererType>
426 class SoftwareRendererPixelTest : public RendererPixelTest<RendererType> {};
428 typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport>
429 SoftwareRendererTypes;
430 TYPED_TEST_CASE(SoftwareRendererPixelTest, SoftwareRendererTypes);
432 template <typename RendererType>
433 class FuzzyForSoftwareOnlyPixelComparator : public PixelComparator {
434 public:
435 explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha)
436 : fuzzy_(discard_alpha), exact_(discard_alpha) {}
438 bool Compare(const SkBitmap& actual_bmp,
439 const SkBitmap& expected_bmp) const override;
441 private:
442 FuzzyPixelOffByOneComparator fuzzy_;
443 ExactPixelComparator exact_;
446 template<>
447 bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare(
448 const SkBitmap& actual_bmp,
449 const SkBitmap& expected_bmp) const {
450 return fuzzy_.Compare(actual_bmp, expected_bmp);
453 template <>
454 bool FuzzyForSoftwareOnlyPixelComparator<
455 SoftwareRendererWithExpandedViewport>::Compare(
456 const SkBitmap& actual_bmp,
457 const SkBitmap& expected_bmp) const {
458 return fuzzy_.Compare(actual_bmp, expected_bmp);
461 template<typename RendererType>
462 bool FuzzyForSoftwareOnlyPixelComparator<RendererType>::Compare(
463 const SkBitmap& actual_bmp,
464 const SkBitmap& expected_bmp) const {
465 return exact_.Compare(actual_bmp, expected_bmp);
468 TYPED_TEST(RendererPixelTest, SimpleGreenRect) {
469 gfx::Rect rect(this->device_viewport_size_);
471 RenderPassId id(1, 1);
472 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
474 SharedQuadState* shared_state =
475 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
477 SolidColorDrawQuad* color_quad =
478 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
479 color_quad->SetNew(shared_state, rect, rect, SK_ColorGREEN, false);
481 RenderPassList pass_list;
482 pass_list.push_back(pass.Pass());
484 EXPECT_TRUE(this->RunPixelTest(
485 &pass_list,
486 base::FilePath(FILE_PATH_LITERAL("green.png")),
487 ExactPixelComparator(true)));
490 TYPED_TEST(RendererPixelTest, SimpleGreenRect_NonRootRenderPass) {
491 gfx::Rect rect(this->device_viewport_size_);
492 gfx::Rect small_rect(100, 100);
494 RenderPassId child_id(2, 1);
495 scoped_ptr<RenderPass> child_pass =
496 CreateTestRenderPass(child_id, small_rect, gfx::Transform());
498 SharedQuadState* child_shared_state =
499 CreateTestSharedQuadState(gfx::Transform(), small_rect, child_pass.get());
501 SolidColorDrawQuad* color_quad =
502 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
503 color_quad->SetNew(child_shared_state, rect, rect, SK_ColorGREEN, false);
505 RenderPassId root_id(1, 1);
506 scoped_ptr<RenderPass> root_pass =
507 CreateTestRenderPass(root_id, rect, gfx::Transform());
509 SharedQuadState* root_shared_state =
510 CreateTestSharedQuadState(gfx::Transform(), rect, root_pass.get());
512 CreateTestRenderPassDrawQuad(
513 root_shared_state, small_rect, child_id, root_pass.get());
515 RenderPass* child_pass_ptr = child_pass.get();
517 RenderPassList pass_list;
518 pass_list.push_back(child_pass.Pass());
519 pass_list.push_back(root_pass.Pass());
521 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
522 &pass_list,
523 child_pass_ptr,
524 base::FilePath(FILE_PATH_LITERAL("green_small.png")),
525 ExactPixelComparator(true)));
528 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithoutBackground) {
529 gfx::Rect rect(this->device_viewport_size_);
531 RenderPassId id(1, 1);
532 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
534 SharedQuadState* shared_state =
535 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
537 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
538 SkColorSetARGB(128, 0, 255, 0), // Texel color.
539 SK_ColorTRANSPARENT, // Background color.
540 true, // Premultiplied alpha.
541 shared_state,
542 this->resource_provider_.get(),
543 pass.get());
545 SolidColorDrawQuad* color_quad =
546 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
547 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
549 RenderPassList pass_list;
550 pass_list.push_back(pass.Pass());
552 EXPECT_TRUE(this->RunPixelTest(
553 &pass_list,
554 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
555 FuzzyPixelOffByOneComparator(true)));
558 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithBackground) {
559 gfx::Rect rect(this->device_viewport_size_);
561 RenderPassId id(1, 1);
562 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
564 SharedQuadState* texture_quad_state =
565 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
566 texture_quad_state->opacity = 0.8f;
568 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
569 SkColorSetARGB(204, 120, 255, 120), // Texel color.
570 SK_ColorGREEN, // Background color.
571 true, // Premultiplied alpha.
572 texture_quad_state,
573 this->resource_provider_.get(),
574 pass.get());
576 SharedQuadState* color_quad_state =
577 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
578 SolidColorDrawQuad* color_quad =
579 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
580 color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
582 RenderPassList pass_list;
583 pass_list.push_back(pass.Pass());
585 EXPECT_TRUE(this->RunPixelTest(
586 &pass_list,
587 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
588 FuzzyPixelOffByOneComparator(true)));
591 template <typename QuadType>
592 static const base::FilePath::CharType* IntersectingQuadImage() {
593 return FILE_PATH_LITERAL("intersecting_blue_green_squares.png");
595 template <>
596 const base::FilePath::CharType* IntersectingQuadImage<SolidColorDrawQuad>() {
597 return FILE_PATH_LITERAL("intersecting_blue_green.png");
599 template <>
600 const base::FilePath::CharType* IntersectingQuadImage<YUVVideoDrawQuad>() {
601 return FILE_PATH_LITERAL("intersecting_blue_green_squares_video.png");
604 template <typename TypeParam>
605 class IntersectingQuadPixelTest : public RendererPixelTest<TypeParam> {
606 protected:
607 void SetupQuadStateAndRenderPass() {
608 // This sets up a pair of draw quads. They are both rotated
609 // relative to the root plane, they are also rotated relative to each other.
610 // The intersect in the middle at a non-perpendicular angle so that any
611 // errors are hopefully magnified.
612 // The quads should intersect correctly, as in the front quad should only
613 // be partially in front of the back quad, and partially behind.
615 viewport_rect_ = gfx::Rect(this->device_viewport_size_);
616 quad_rect_ = gfx::Rect(0, 0, this->device_viewport_size_.width(),
617 this->device_viewport_size_.height() / 2.0);
619 RenderPassId id(1, 1);
620 render_pass_ = CreateTestRootRenderPass(id, viewport_rect_);
622 // Create the front quad rotated on the Z and Y axis.
623 gfx::Transform trans;
624 trans.Translate3d(0, 0, 0.707 * this->device_viewport_size_.width() / 2.0);
625 trans.RotateAboutZAxis(45.0);
626 trans.RotateAboutYAxis(45.0);
627 front_quad_state_ =
628 CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get());
629 front_quad_state_->clip_rect = quad_rect_;
630 // Make sure they end up in a 3d sorting context.
631 front_quad_state_->sorting_context_id = 1;
633 // Create the back quad, and rotate on just the y axis. This will intersect
634 // the first quad partially.
635 trans = gfx::Transform();
636 trans.Translate3d(0, 0, -0.707 * this->device_viewport_size_.width() / 2.0);
637 trans.RotateAboutYAxis(-45.0);
638 back_quad_state_ =
639 CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get());
640 back_quad_state_->sorting_context_id = 1;
641 back_quad_state_->clip_rect = quad_rect_;
643 template <typename T>
644 void AppendBackgroundAndRunTest(const PixelComparator& comparator) {
645 SharedQuadState* background_quad_state = CreateTestSharedQuadState(
646 gfx::Transform(), viewport_rect_, render_pass_.get());
647 SolidColorDrawQuad* background_quad =
648 render_pass_->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
649 background_quad->SetNew(background_quad_state, viewport_rect_,
650 viewport_rect_, SK_ColorWHITE, false);
651 pass_list_.push_back(render_pass_.Pass());
652 const base::FilePath::CharType* fileName = IntersectingQuadImage<T>();
653 EXPECT_TRUE(
654 this->RunPixelTest(&pass_list_, base::FilePath(fileName), comparator));
656 template <typename T>
657 T* CreateAndAppendDrawQuad() {
658 return render_pass_->CreateAndAppendDrawQuad<T>();
661 scoped_ptr<RenderPass> render_pass_;
662 gfx::Rect viewport_rect_;
663 SharedQuadState* front_quad_state_;
664 SharedQuadState* back_quad_state_;
665 gfx::Rect quad_rect_;
666 RenderPassList pass_list_;
669 template <typename TypeParam>
670 class IntersectingQuadGLPixelTest
671 : public IntersectingQuadPixelTest<TypeParam> {
672 public:
673 void SetUp() override {
674 IntersectingQuadPixelTest<TypeParam>::SetUp();
675 video_resource_updater_.reset(
676 new VideoResourceUpdater(this->output_surface_->context_provider(),
677 this->resource_provider_.get()));
678 video_resource_updater2_.reset(
679 new VideoResourceUpdater(this->output_surface_->context_provider(),
680 this->resource_provider_.get()));
683 protected:
684 scoped_ptr<VideoResourceUpdater> video_resource_updater_;
685 scoped_ptr<VideoResourceUpdater> video_resource_updater2_;
688 template <typename TypeParam>
689 class IntersectingQuadSoftwareTest
690 : public IntersectingQuadPixelTest<TypeParam> {};
692 typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport>
693 SoftwareRendererTypes;
694 typedef ::testing::Types<GLRenderer, GLRendererWithExpandedViewport>
695 GLRendererTypes;
697 TYPED_TEST_CASE(IntersectingQuadPixelTest, RendererTypes);
698 TYPED_TEST_CASE(IntersectingQuadGLPixelTest, GLRendererTypes);
699 TYPED_TEST_CASE(IntersectingQuadSoftwareTest, SoftwareRendererTypes);
701 TYPED_TEST(IntersectingQuadPixelTest, SolidColorQuads) {
702 this->SetupQuadStateAndRenderPass();
704 SolidColorDrawQuad* quad =
705 this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>();
706 SolidColorDrawQuad* quad2 =
707 this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>();
709 quad->SetNew(this->front_quad_state_, this->quad_rect_, this->quad_rect_,
710 SK_ColorBLUE, false);
711 quad2->SetNew(this->back_quad_state_, this->quad_rect_, this->quad_rect_,
712 SK_ColorGREEN, false);
713 SCOPED_TRACE("IntersectingSolidColorQuads");
714 this->template AppendBackgroundAndRunTest<SolidColorDrawQuad>(
715 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
718 template <typename TypeParam>
719 SkColor GetColor(const SkColor& color) {
720 return color;
723 template <>
724 SkColor GetColor<GLRenderer>(const SkColor& color) {
725 return SkColorSetARGB(SkColorGetA(color), SkColorGetB(color),
726 SkColorGetG(color), SkColorGetR(color));
728 template <>
729 SkColor GetColor<GLRendererWithExpandedViewport>(const SkColor& color) {
730 return GetColor<GLRenderer>(color);
733 TYPED_TEST(IntersectingQuadPixelTest, TexturedQuads) {
734 this->SetupQuadStateAndRenderPass();
735 CreateTestTwoColoredTextureDrawQuad(
736 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
737 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
738 true, this->front_quad_state_, this->resource_provider_.get(),
739 this->render_pass_.get());
740 CreateTestTwoColoredTextureDrawQuad(
741 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
742 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
743 true, this->back_quad_state_, this->resource_provider_.get(),
744 this->render_pass_.get());
746 SCOPED_TRACE("IntersectingTexturedQuads");
747 this->template AppendBackgroundAndRunTest<TextureDrawQuad>(
748 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
751 TYPED_TEST(IntersectingQuadSoftwareTest, PictureQuads) {
752 this->SetupQuadStateAndRenderPass();
753 gfx::Rect outer_rect(this->quad_rect_);
754 gfx::Rect inner_rect(this->quad_rect_.x() + (this->quad_rect_.width() / 4),
755 this->quad_rect_.y() + (this->quad_rect_.height() / 4),
756 this->quad_rect_.width() / 2,
757 this->quad_rect_.height() / 2);
759 SkPaint black_paint;
760 black_paint.setColor(SK_ColorBLACK);
761 SkPaint blue_paint;
762 blue_paint.setColor(SK_ColorBLUE);
763 SkPaint green_paint;
764 green_paint.setColor(SK_ColorGREEN);
766 scoped_ptr<FakePicturePile> blue_recording =
767 FakePicturePile::CreateFilledPile(gfx::Size(1000, 1000),
768 this->quad_rect_.size());
769 blue_recording->add_draw_rect_with_paint(outer_rect, black_paint);
770 blue_recording->add_draw_rect_with_paint(inner_rect, blue_paint);
771 blue_recording->Rerecord();
772 scoped_refptr<FakePicturePileImpl> blue_pile =
773 FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);
775 PictureDrawQuad* blue_quad =
776 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
778 blue_quad->SetNew(this->front_quad_state_, this->quad_rect_, gfx::Rect(),
779 this->quad_rect_, gfx::RectF(this->quad_rect_),
780 this->quad_rect_.size(), false, RGBA_8888, this->quad_rect_,
781 1.f, blue_pile);
783 scoped_ptr<FakePicturePile> green_recording =
784 FakePicturePile::CreateFilledPile(this->quad_rect_.size(),
785 this->quad_rect_.size());
786 green_recording->add_draw_rect_with_paint(outer_rect, green_paint);
787 green_recording->add_draw_rect_with_paint(inner_rect, black_paint);
788 green_recording->Rerecord();
789 scoped_refptr<FakePicturePileImpl> green_pile =
790 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
792 PictureDrawQuad* green_quad =
793 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
794 green_quad->SetNew(this->back_quad_state_, this->quad_rect_, gfx::Rect(),
795 this->quad_rect_, gfx::RectF(this->quad_rect_),
796 this->quad_rect_.size(), false, RGBA_8888,
797 this->quad_rect_, 1.f, green_pile);
798 SCOPED_TRACE("IntersectingPictureQuadsPass");
799 this->template AppendBackgroundAndRunTest<PictureDrawQuad>(
800 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
803 TYPED_TEST(IntersectingQuadPixelTest, RenderPassQuads) {
804 this->SetupQuadStateAndRenderPass();
805 RenderPassId child_pass_id1(2, 2);
806 RenderPassId child_pass_id2(2, 3);
807 scoped_ptr<RenderPass> child_pass1 =
808 CreateTestRenderPass(child_pass_id1, this->quad_rect_, gfx::Transform());
809 SharedQuadState* child1_quad_state = CreateTestSharedQuadState(
810 gfx::Transform(), this->quad_rect_, child_pass1.get());
811 scoped_ptr<RenderPass> child_pass2 =
812 CreateTestRenderPass(child_pass_id2, this->quad_rect_, gfx::Transform());
813 SharedQuadState* child2_quad_state = CreateTestSharedQuadState(
814 gfx::Transform(), this->quad_rect_, child_pass2.get());
816 CreateTestTwoColoredTextureDrawQuad(
817 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
818 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
819 true, child1_quad_state, this->resource_provider_.get(),
820 child_pass1.get());
821 CreateTestTwoColoredTextureDrawQuad(
822 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
823 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
824 true, child2_quad_state, this->resource_provider_.get(),
825 child_pass2.get());
827 CreateTestRenderPassDrawQuad(this->front_quad_state_, this->quad_rect_,
828 child_pass_id1, this->render_pass_.get());
829 CreateTestRenderPassDrawQuad(this->back_quad_state_, this->quad_rect_,
830 child_pass_id2, this->render_pass_.get());
832 this->pass_list_.push_back(child_pass1.Pass());
833 this->pass_list_.push_back(child_pass2.Pass());
834 SCOPED_TRACE("IntersectingRenderQuadsPass");
835 this->template AppendBackgroundAndRunTest<RenderPassDrawQuad>(
836 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
839 TYPED_TEST(IntersectingQuadGLPixelTest, YUVVideoQuads) {
840 this->SetupQuadStateAndRenderPass();
841 gfx::Rect inner_rect(
842 ((this->quad_rect_.x() + (this->quad_rect_.width() / 4)) & ~0xF),
843 ((this->quad_rect_.y() + (this->quad_rect_.height() / 4)) & ~0xF),
844 (this->quad_rect_.width() / 2) & ~0xF,
845 (this->quad_rect_.height() / 2) & ~0xF);
847 CreateTestYUVVideoDrawQuad_TwoColor(
848 this->front_quad_state_, media::PIXEL_FORMAT_YV12,
849 media::COLOR_SPACE_JPEG, false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
850 this->quad_rect_.size(), this->quad_rect_, 0, 128, 128, inner_rect, 29,
851 255, 107, this->render_pass_.get(), this->video_resource_updater_.get(),
852 this->resource_provider_.get());
854 CreateTestYUVVideoDrawQuad_TwoColor(
855 this->back_quad_state_, media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG,
856 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(),
857 this->quad_rect_, 149, 43, 21, inner_rect, 0, 128, 128,
858 this->render_pass_.get(), this->video_resource_updater2_.get(),
859 this->resource_provider_.get());
861 SCOPED_TRACE("IntersectingVideoQuads");
862 this->template AppendBackgroundAndRunTest<YUVVideoDrawQuad>(
863 FuzzyPixelOffByOneComparator(false));
866 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
867 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) {
868 gfx::Rect rect(this->device_viewport_size_);
870 RenderPassId id(1, 1);
871 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
873 SharedQuadState* shared_state =
874 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
876 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
877 SkColorSetARGB(128, 0, 255, 0), // Texel color.
878 SK_ColorTRANSPARENT, // Background color.
879 false, // Premultiplied alpha.
880 shared_state,
881 this->resource_provider_.get(),
882 pass.get());
884 SolidColorDrawQuad* color_quad =
885 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
886 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
888 RenderPassList pass_list;
889 pass_list.push_back(pass.Pass());
891 EXPECT_TRUE(this->RunPixelTest(
892 &pass_list,
893 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
894 FuzzyPixelOffByOneComparator(true)));
897 // TODO(skaslev): The software renderer does not support non-premultplied alpha.
898 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
899 gfx::Rect rect(this->device_viewport_size_);
901 RenderPassId id(1, 1);
902 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
904 SharedQuadState* texture_quad_state =
905 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
906 texture_quad_state->opacity = 0.8f;
908 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
909 SkColorSetARGB(204, 120, 255, 120), // Texel color.
910 SK_ColorGREEN, // Background color.
911 false, // Premultiplied alpha.
912 texture_quad_state,
913 this->resource_provider_.get(),
914 pass.get());
916 SharedQuadState* color_quad_state =
917 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
918 SolidColorDrawQuad* color_quad =
919 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
920 color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
922 RenderPassList pass_list;
923 pass_list.push_back(pass.Pass());
925 EXPECT_TRUE(this->RunPixelTest(
926 &pass_list,
927 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
928 FuzzyPixelOffByOneComparator(true)));
931 class VideoGLRendererPixelTest : public GLRendererPixelTest {
932 protected:
933 void CreateEdgeBleedPass(media::VideoPixelFormat format,
934 media::ColorSpace color_space,
935 RenderPassList* pass_list) {
936 gfx::Rect rect(200, 200);
938 RenderPassId id(1, 1);
939 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
941 // Scale the video up so that bilinear filtering kicks in to sample more
942 // than just nearest neighbor would.
943 gfx::Transform scale_by_2;
944 scale_by_2.Scale(2.f, 2.f);
945 gfx::Rect half_rect(100, 100);
946 SharedQuadState* shared_state =
947 CreateTestSharedQuadState(scale_by_2, half_rect, pass.get());
949 gfx::Size background_size(200, 200);
950 gfx::Rect green_rect(16, 20, 100, 100);
951 gfx::RectF tex_coord_rect(
952 static_cast<float>(green_rect.x()) / background_size.width(),
953 static_cast<float>(green_rect.y()) / background_size.height(),
954 static_cast<float>(green_rect.width()) / background_size.width(),
955 static_cast<float>(green_rect.height()) / background_size.height());
957 // YUV of (149,43,21) should be green (0,255,0) in RGB.
958 // Create a video frame that has a non-green background rect, with a
959 // green sub-rectangle that should be the only thing displayed in
960 // the final image. Bleeding will appear on all four sides of the video
961 // if the tex coords are not clamped.
962 CreateTestYUVVideoDrawQuad_TwoColor(
963 shared_state, format, color_space, false, tex_coord_rect,
964 background_size, gfx::Rect(background_size), 128, 128, 128, green_rect,
965 149, 43, 21, pass.get(), video_resource_updater_.get(),
966 resource_provider_.get());
967 pass_list->push_back(pass.Pass());
970 void SetUp() override {
971 GLRendererPixelTest::SetUp();
972 video_resource_updater_.reset(new VideoResourceUpdater(
973 output_surface_->context_provider(), resource_provider_.get()));
976 scoped_ptr<VideoResourceUpdater> video_resource_updater_;
979 TEST_F(VideoGLRendererPixelTest, SimpleYUVRect) {
980 gfx::Rect rect(this->device_viewport_size_);
982 RenderPassId id(1, 1);
983 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
985 SharedQuadState* shared_state =
986 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
988 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::PIXEL_FORMAT_YV12,
989 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
990 pass.get(), video_resource_updater_.get(),
991 rect, rect, resource_provider_.get());
993 RenderPassList pass_list;
994 pass_list.push_back(pass.Pass());
996 EXPECT_TRUE(
997 this->RunPixelTest(&pass_list,
998 base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
999 FuzzyPixelOffByOneComparator(true)));
1002 TEST_F(VideoGLRendererPixelTest, ClippedYUVRect) {
1003 gfx::Rect viewport(this->device_viewport_size_);
1004 gfx::Rect draw_rect(this->device_viewport_size_.width() * 1.5,
1005 this->device_viewport_size_.height() * 1.5);
1007 RenderPassId id(1, 1);
1008 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, viewport);
1010 SharedQuadState* shared_state =
1011 CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get());
1013 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::PIXEL_FORMAT_YV12,
1014 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1015 pass.get(), video_resource_updater_.get(),
1016 draw_rect, viewport,
1017 resource_provider_.get());
1018 RenderPassList pass_list;
1019 pass_list.push_back(pass.Pass());
1021 EXPECT_TRUE(this->RunPixelTest(
1022 &pass_list, base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png")),
1023 FuzzyPixelOffByOneComparator(true)));
1026 TEST_F(VideoGLRendererPixelTest, OffsetYUVRect) {
1027 gfx::Rect rect(this->device_viewport_size_);
1029 RenderPassId id(1, 1);
1030 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1032 SharedQuadState* shared_state =
1033 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1035 // Intentionally sets frame format to I420 for testing coverage.
1036 CreateTestYUVVideoDrawQuad_Striped(
1037 shared_state, media::PIXEL_FORMAT_I420, false,
1038 gfx::RectF(0.125f, 0.25f, 0.75f, 0.5f), pass.get(),
1039 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1041 RenderPassList pass_list;
1042 pass_list.push_back(pass.Pass());
1044 EXPECT_TRUE(this->RunPixelTest(
1045 &pass_list,
1046 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_offset.png")),
1047 FuzzyPixelOffByOneComparator(true)));
1050 TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) {
1051 gfx::Rect rect(this->device_viewport_size_);
1053 RenderPassId id(1, 1);
1054 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1056 SharedQuadState* shared_state =
1057 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1059 // In MPEG color range YUV values of (15,128,128) should produce black.
1060 CreateTestYUVVideoDrawQuad_Solid(
1061 shared_state, media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_UNSPECIFIED,
1062 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
1063 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1065 RenderPassList pass_list;
1066 pass_list.push_back(pass.Pass());
1068 // If we didn't get black out of the YUV values above, then we probably have a
1069 // color range issue.
1070 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1071 base::FilePath(FILE_PATH_LITERAL("black.png")),
1072 FuzzyPixelOffByOneComparator(true)));
1075 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
1076 gfx::Rect rect(this->device_viewport_size_);
1078 RenderPassId id(1, 1);
1079 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1081 SharedQuadState* shared_state =
1082 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1084 // YUV of (149,43,21) should be green (0,255,0) in RGB.
1085 CreateTestYUVVideoDrawQuad_Solid(
1086 shared_state, media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG, false,
1087 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(),
1088 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1090 RenderPassList pass_list;
1091 pass_list.push_back(pass.Pass());
1093 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1094 base::FilePath(FILE_PATH_LITERAL("green.png")),
1095 FuzzyPixelOffByOneComparator(true)));
1098 // Test that a YUV video doesn't bleed outside of its tex coords when the
1099 // tex coord rect is only a partial subrectangle of the coded contents.
1100 TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) {
1101 RenderPassList pass_list;
1102 CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG,
1103 &pass_list);
1104 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1105 base::FilePath(FILE_PATH_LITERAL("green.png")),
1106 FuzzyPixelOffByOneComparator(true)));
1109 TEST_F(VideoGLRendererPixelTest, YUVAEdgeBleed) {
1110 RenderPassList pass_list;
1111 CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12A, media::COLOR_SPACE_UNSPECIFIED,
1112 &pass_list);
1113 EXPECT_TRUE(this->RunPixelTest(&pass_list,
1114 base::FilePath(FILE_PATH_LITERAL("green.png")),
1115 FuzzyPixelOffByOneComparator(true)));
1118 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
1119 gfx::Rect rect(this->device_viewport_size_);
1121 RenderPassId id(1, 1);
1122 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1124 SharedQuadState* shared_state =
1125 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1127 // Dark grey in JPEG color range (in MPEG, this is black).
1128 CreateTestYUVVideoDrawQuad_Solid(
1129 shared_state, media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG, false,
1130 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(),
1131 video_resource_updater_.get(), rect, rect, resource_provider_.get());
1133 RenderPassList pass_list;
1134 pass_list.push_back(pass.Pass());
1136 EXPECT_TRUE(
1137 this->RunPixelTest(&pass_list,
1138 base::FilePath(FILE_PATH_LITERAL("dark_grey.png")),
1139 FuzzyPixelOffByOneComparator(true)));
1142 TEST_F(VideoGLRendererPixelTest, SimpleYUVARect) {
1143 gfx::Rect rect(this->device_viewport_size_);
1145 RenderPassId id(1, 1);
1146 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1148 SharedQuadState* shared_state =
1149 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1151 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::PIXEL_FORMAT_YV12A,
1152 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1153 pass.get(), video_resource_updater_.get(),
1154 rect, rect, resource_provider_.get());
1156 SolidColorDrawQuad* color_quad =
1157 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1158 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
1160 RenderPassList pass_list;
1161 pass_list.push_back(pass.Pass());
1163 EXPECT_TRUE(this->RunPixelTest(
1164 &pass_list,
1165 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_alpha.png")),
1166 FuzzyPixelOffByOneComparator(true)));
1169 TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) {
1170 gfx::Rect rect(this->device_viewport_size_);
1172 RenderPassId id(1, 1);
1173 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1175 SharedQuadState* shared_state =
1176 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1178 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::PIXEL_FORMAT_YV12A,
1179 true, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f),
1180 pass.get(), video_resource_updater_.get(),
1181 rect, rect, resource_provider_.get());
1183 SolidColorDrawQuad* color_quad =
1184 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1185 color_quad->SetNew(shared_state, rect, rect, SK_ColorBLACK, false);
1187 RenderPassList pass_list;
1188 pass_list.push_back(pass.Pass());
1190 EXPECT_TRUE(this->RunPixelTest(
1191 &pass_list,
1192 base::FilePath(FILE_PATH_LITERAL("black.png")),
1193 ExactPixelComparator(true)));
1196 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) {
1197 gfx::Rect viewport_rect(this->device_viewport_size_);
1199 RenderPassId root_pass_id(1, 1);
1200 scoped_ptr<RenderPass> root_pass =
1201 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1203 RenderPassId child_pass_id(2, 2);
1204 gfx::Rect pass_rect(this->device_viewport_size_);
1205 gfx::Transform transform_to_root;
1206 scoped_ptr<RenderPass> child_pass =
1207 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1209 gfx::Transform quad_to_target_transform;
1210 SharedQuadState* shared_state = CreateTestSharedQuadState(
1211 quad_to_target_transform, viewport_rect, child_pass.get());
1212 shared_state->opacity = 0.5f;
1214 gfx::Rect blue_rect(0,
1216 this->device_viewport_size_.width(),
1217 this->device_viewport_size_.height() / 2);
1218 SolidColorDrawQuad* blue =
1219 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1220 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1221 gfx::Rect yellow_rect(0,
1222 this->device_viewport_size_.height() / 2,
1223 this->device_viewport_size_.width(),
1224 this->device_viewport_size_.height() / 2);
1225 SolidColorDrawQuad* yellow =
1226 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1227 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1229 SharedQuadState* blank_state = CreateTestSharedQuadState(
1230 quad_to_target_transform, viewport_rect, child_pass.get());
1232 SolidColorDrawQuad* white =
1233 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1234 white->SetNew(
1235 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1237 SharedQuadState* pass_shared_state =
1238 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1240 SkScalar matrix[20];
1241 float amount = 0.5f;
1242 matrix[0] = 0.213f + 0.787f * amount;
1243 matrix[1] = 0.715f - 0.715f * amount;
1244 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1245 matrix[3] = matrix[4] = 0;
1246 matrix[5] = 0.213f - 0.213f * amount;
1247 matrix[6] = 0.715f + 0.285f * amount;
1248 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1249 matrix[8] = matrix[9] = 0;
1250 matrix[10] = 0.213f - 0.213f * amount;
1251 matrix[11] = 0.715f - 0.715f * amount;
1252 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1253 matrix[13] = matrix[14] = 0;
1254 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1255 matrix[18] = 1;
1256 skia::RefPtr<SkColorFilter> colorFilter(
1257 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1258 skia::RefPtr<SkImageFilter> filter =
1259 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
1260 FilterOperations filters;
1261 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1263 RenderPassDrawQuad* render_pass_quad =
1264 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1265 render_pass_quad->SetNew(pass_shared_state,
1266 pass_rect,
1267 pass_rect,
1268 child_pass_id,
1270 gfx::Vector2dF(),
1271 gfx::Size(),
1272 filters,
1273 gfx::Vector2dF(),
1274 FilterOperations());
1276 RenderPassList pass_list;
1277 pass_list.push_back(child_pass.Pass());
1278 pass_list.push_back(root_pass.Pass());
1280 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1281 // renderer so use a fuzzy comparator.
1282 EXPECT_TRUE(this->RunPixelTest(
1283 &pass_list,
1284 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1285 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1288 TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) {
1289 gfx::Rect viewport_rect(this->device_viewport_size_);
1291 RenderPassId root_pass_id(1, 1);
1292 scoped_ptr<RenderPass> root_pass =
1293 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1295 RenderPassId child_pass_id(2, 2);
1296 gfx::Rect pass_rect(this->device_viewport_size_);
1297 gfx::Transform transform_to_root;
1298 scoped_ptr<RenderPass> child_pass =
1299 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1301 gfx::Transform quad_to_target_transform;
1302 SharedQuadState* shared_state = CreateTestSharedQuadState(
1303 quad_to_target_transform, viewport_rect, child_pass.get());
1304 shared_state->opacity = 0.5f;
1306 gfx::Rect blue_rect(0,
1308 this->device_viewport_size_.width(),
1309 this->device_viewport_size_.height() / 2);
1310 SolidColorDrawQuad* blue =
1311 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1312 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1313 gfx::Rect yellow_rect(0,
1314 this->device_viewport_size_.height() / 2,
1315 this->device_viewport_size_.width(),
1316 this->device_viewport_size_.height() / 2);
1317 SolidColorDrawQuad* yellow =
1318 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1319 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1321 SharedQuadState* blank_state = CreateTestSharedQuadState(
1322 quad_to_target_transform, viewport_rect, child_pass.get());
1324 SolidColorDrawQuad* white =
1325 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1326 white->SetNew(
1327 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1329 SharedQuadState* pass_shared_state =
1330 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1332 FilterOperations filters;
1333 filters.Append(FilterOperation::CreateSaturateFilter(0.5f));
1335 RenderPassDrawQuad* render_pass_quad =
1336 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1337 render_pass_quad->SetNew(pass_shared_state,
1338 pass_rect,
1339 pass_rect,
1340 child_pass_id,
1342 gfx::Vector2dF(),
1343 gfx::Size(),
1344 filters,
1345 gfx::Vector2dF(),
1346 FilterOperations());
1348 RenderPassList pass_list;
1349 pass_list.push_back(child_pass.Pass());
1350 pass_list.push_back(root_pass.Pass());
1352 // This test blends slightly differently with the software renderer vs. the gl
1353 // renderer so use a fuzzy comparator.
1354 EXPECT_TRUE(this->RunPixelTest(
1355 &pass_list, base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
1356 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1359 TYPED_TEST(RendererPixelTest, FastPassFilterChain) {
1360 gfx::Rect viewport_rect(this->device_viewport_size_);
1362 RenderPassId root_pass_id(1, 1);
1363 scoped_ptr<RenderPass> root_pass =
1364 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1366 RenderPassId child_pass_id(2, 2);
1367 gfx::Rect pass_rect(this->device_viewport_size_);
1368 gfx::Transform transform_to_root;
1369 scoped_ptr<RenderPass> child_pass =
1370 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1372 gfx::Transform quad_to_target_transform;
1373 SharedQuadState* shared_state = CreateTestSharedQuadState(
1374 quad_to_target_transform, viewport_rect, child_pass.get());
1375 shared_state->opacity = 0.5f;
1377 gfx::Rect blue_rect(0,
1379 this->device_viewport_size_.width(),
1380 this->device_viewport_size_.height() / 2);
1381 SolidColorDrawQuad* blue =
1382 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1383 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1384 gfx::Rect yellow_rect(0,
1385 this->device_viewport_size_.height() / 2,
1386 this->device_viewport_size_.width(),
1387 this->device_viewport_size_.height() / 2);
1388 SolidColorDrawQuad* yellow =
1389 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1390 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1392 SharedQuadState* blank_state = CreateTestSharedQuadState(
1393 quad_to_target_transform, viewport_rect, child_pass.get());
1395 SolidColorDrawQuad* white =
1396 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1397 white->SetNew(
1398 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1400 SharedQuadState* pass_shared_state =
1401 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1403 FilterOperations filters;
1404 filters.Append(FilterOperation::CreateGrayscaleFilter(1.f));
1405 filters.Append(FilterOperation::CreateBrightnessFilter(0.5f));
1407 RenderPassDrawQuad* render_pass_quad =
1408 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1409 render_pass_quad->SetNew(pass_shared_state,
1410 pass_rect,
1411 pass_rect,
1412 child_pass_id,
1414 gfx::Vector2dF(),
1415 gfx::Size(),
1416 filters,
1417 gfx::Vector2dF(),
1418 FilterOperations());
1420 RenderPassList pass_list;
1421 pass_list.push_back(child_pass.Pass());
1422 pass_list.push_back(root_pass.Pass());
1424 // This test blends slightly differently with the software renderer vs. the gl
1425 // renderer so use a fuzzy comparator.
1426 EXPECT_TRUE(this->RunPixelTest(
1427 &pass_list,
1428 base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")),
1429 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1432 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) {
1433 gfx::Rect viewport_rect(this->device_viewport_size_);
1435 RenderPassId root_pass_id(1, 1);
1436 scoped_ptr<RenderPass> root_pass =
1437 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1439 RenderPassId child_pass_id(2, 2);
1440 gfx::Rect pass_rect(this->device_viewport_size_);
1441 gfx::Transform transform_to_root;
1442 scoped_ptr<RenderPass> child_pass =
1443 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1445 gfx::Transform quad_to_target_transform;
1446 SharedQuadState* shared_state = CreateTestSharedQuadState(
1447 quad_to_target_transform, viewport_rect, child_pass.get());
1448 shared_state->opacity = 0.5f;
1450 gfx::Rect blue_rect(0,
1452 this->device_viewport_size_.width(),
1453 this->device_viewport_size_.height() / 2);
1454 SolidColorDrawQuad* blue =
1455 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1456 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1457 gfx::Rect yellow_rect(0,
1458 this->device_viewport_size_.height() / 2,
1459 this->device_viewport_size_.width(),
1460 this->device_viewport_size_.height() / 2);
1461 SolidColorDrawQuad* yellow =
1462 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1463 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1465 SharedQuadState* blank_state = CreateTestSharedQuadState(
1466 quad_to_target_transform, viewport_rect, child_pass.get());
1468 SolidColorDrawQuad* white =
1469 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1470 white->SetNew(
1471 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
1473 SharedQuadState* pass_shared_state =
1474 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1476 SkScalar matrix[20];
1477 float amount = 0.5f;
1478 matrix[0] = 0.213f + 0.787f * amount;
1479 matrix[1] = 0.715f - 0.715f * amount;
1480 matrix[2] = 1.f - (matrix[0] + matrix[1]);
1481 matrix[3] = 0;
1482 matrix[4] = 20.f;
1483 matrix[5] = 0.213f - 0.213f * amount;
1484 matrix[6] = 0.715f + 0.285f * amount;
1485 matrix[7] = 1.f - (matrix[5] + matrix[6]);
1486 matrix[8] = 0;
1487 matrix[9] = 200.f;
1488 matrix[10] = 0.213f - 0.213f * amount;
1489 matrix[11] = 0.715f - 0.715f * amount;
1490 matrix[12] = 1.f - (matrix[10] + matrix[11]);
1491 matrix[13] = 0;
1492 matrix[14] = 1.5f;
1493 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
1494 matrix[18] = 1;
1495 skia::RefPtr<SkColorFilter> colorFilter(
1496 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
1497 skia::RefPtr<SkImageFilter> filter =
1498 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
1499 FilterOperations filters;
1500 filters.Append(FilterOperation::CreateReferenceFilter(filter));
1502 RenderPassDrawQuad* render_pass_quad =
1503 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1504 render_pass_quad->SetNew(pass_shared_state,
1505 pass_rect,
1506 pass_rect,
1507 child_pass_id,
1509 gfx::Vector2dF(),
1510 gfx::Size(),
1511 filters,
1512 gfx::Vector2dF(),
1513 FilterOperations());
1515 RenderPassList pass_list;
1517 pass_list.push_back(child_pass.Pass());
1518 pass_list.push_back(root_pass.Pass());
1520 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
1521 // renderer so use a fuzzy comparator.
1522 EXPECT_TRUE(this->RunPixelTest(
1523 &pass_list,
1524 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
1525 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
1528 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) {
1529 gfx::Rect viewport_rect(this->device_viewport_size_);
1531 RenderPassId root_pass_id(1, 1);
1532 scoped_ptr<RenderPass> root_pass =
1533 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1535 RenderPassId child_pass_id(2, 2);
1536 gfx::Rect pass_rect(this->device_viewport_size_);
1537 gfx::Transform transform_to_root;
1538 scoped_ptr<RenderPass> child_pass =
1539 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1541 gfx::Transform quad_to_target_transform;
1542 SharedQuadState* shared_state = CreateTestSharedQuadState(
1543 quad_to_target_transform, viewport_rect, child_pass.get());
1545 gfx::Rect blue_rect(0,
1547 this->device_viewport_size_.width(),
1548 this->device_viewport_size_.height() / 2);
1549 SolidColorDrawQuad* blue =
1550 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1551 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1552 gfx::Rect yellow_rect(0,
1553 this->device_viewport_size_.height() / 2,
1554 this->device_viewport_size_.width(),
1555 this->device_viewport_size_.height() / 2);
1556 SolidColorDrawQuad* yellow =
1557 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1558 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1560 SharedQuadState* pass_shared_state =
1561 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1562 CreateTestRenderPassDrawQuad(
1563 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1565 RenderPassList pass_list;
1566 pass_list.push_back(child_pass.Pass());
1567 pass_list.push_back(root_pass.Pass());
1569 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1571 EXPECT_TRUE(this->RunPixelTest(
1572 &pass_list,
1573 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
1574 ExactPixelComparator(true)));
1577 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) {
1578 gfx::Rect viewport_rect(this->device_viewport_size_);
1580 RenderPassId root_pass_id(1, 1);
1581 scoped_ptr<RenderPass> root_pass =
1582 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1584 RenderPassId child_pass_id(2, 2);
1585 gfx::Rect pass_rect(this->device_viewport_size_);
1586 gfx::Transform transform_to_root;
1587 scoped_ptr<RenderPass> child_pass =
1588 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1590 gfx::Transform quad_to_target_transform;
1591 SharedQuadState* shared_state = CreateTestSharedQuadState(
1592 quad_to_target_transform, viewport_rect, child_pass.get());
1594 gfx::Rect blue_rect(0,
1596 this->device_viewport_size_.width(),
1597 this->device_viewport_size_.height() / 2);
1598 SolidColorDrawQuad* blue =
1599 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1600 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1601 gfx::Rect yellow_rect(0,
1602 this->device_viewport_size_.height() / 2,
1603 this->device_viewport_size_.width(),
1604 this->device_viewport_size_.height() / 2);
1605 SolidColorDrawQuad* yellow =
1606 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1607 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
1609 gfx::Transform aa_transform;
1610 aa_transform.Translate(0.5, 0.0);
1612 SharedQuadState* pass_shared_state =
1613 CreateTestSharedQuadState(aa_transform, pass_rect, root_pass.get());
1614 CreateTestRenderPassDrawQuad(
1615 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1617 SharedQuadState* root_shared_state = CreateTestSharedQuadState(
1618 gfx::Transform(), viewport_rect, root_pass.get());
1619 SolidColorDrawQuad* background =
1620 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1621 background->SetNew(root_shared_state,
1622 gfx::Rect(this->device_viewport_size_),
1623 gfx::Rect(this->device_viewport_size_),
1624 SK_ColorWHITE,
1625 false);
1627 RenderPassList pass_list;
1628 pass_list.push_back(child_pass.Pass());
1629 pass_list.push_back(root_pass.Pass());
1631 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
1633 EXPECT_TRUE(this->RunPixelTest(
1634 &pass_list,
1635 base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")),
1636 FuzzyPixelOffByOneComparator(true)));
1639 // This tests the case where we have a RenderPass with a mask, but the quad
1640 // for the masked surface does not include the full surface texture.
1641 TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) {
1642 gfx::Rect viewport_rect(this->device_viewport_size_);
1644 RenderPassId root_pass_id(1, 1);
1645 scoped_ptr<RenderPass> root_pass =
1646 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1647 SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState(
1648 gfx::Transform(), viewport_rect, root_pass.get());
1650 RenderPassId child_pass_id(2, 2);
1651 gfx::Transform transform_to_root;
1652 scoped_ptr<RenderPass> child_pass =
1653 CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root);
1654 SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState(
1655 gfx::Transform(), viewport_rect, child_pass.get());
1657 // The child render pass is just a green box.
1658 static const SkColor kCSSGreen = 0xff008000;
1659 SolidColorDrawQuad* green =
1660 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1661 green->SetNew(
1662 child_pass_shared_state, viewport_rect, viewport_rect, kCSSGreen, false);
1664 // Make a mask.
1665 gfx::Rect mask_rect = viewport_rect;
1666 SkBitmap bitmap;
1667 bitmap.allocPixels(
1668 SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height()));
1669 SkCanvas canvas(bitmap);
1670 SkPaint paint;
1671 paint.setStyle(SkPaint::kStroke_Style);
1672 paint.setStrokeWidth(SkIntToScalar(4));
1673 paint.setColor(SK_ColorWHITE);
1674 canvas.clear(SK_ColorTRANSPARENT);
1675 gfx::Rect rect = mask_rect;
1676 while (!rect.IsEmpty()) {
1677 rect.Inset(6, 6, 4, 4);
1678 canvas.drawRect(
1679 SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()),
1680 paint);
1681 rect.Inset(6, 6, 4, 4);
1684 ResourceId mask_resource_id = this->resource_provider_->CreateResource(
1685 mask_rect.size(), GL_CLAMP_TO_EDGE,
1686 ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
1688 SkAutoLockPixels lock(bitmap);
1689 this->resource_provider_->CopyToResource(
1690 mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
1691 mask_rect.size());
1694 // This RenderPassDrawQuad does not include the full |viewport_rect| which is
1695 // the size of the child render pass.
1696 gfx::Rect sub_rect = gfx::Rect(50, 50, 200, 100);
1697 EXPECT_NE(sub_rect.x(), child_pass->output_rect.x());
1698 EXPECT_NE(sub_rect.y(), child_pass->output_rect.y());
1699 EXPECT_NE(sub_rect.right(), child_pass->output_rect.right());
1700 EXPECT_NE(sub_rect.bottom(), child_pass->output_rect.bottom());
1702 // Set up a mask on the RenderPassDrawQuad.
1703 RenderPassDrawQuad* mask_quad =
1704 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1705 mask_quad->SetNew(root_pass_shared_state,
1706 sub_rect,
1707 sub_rect,
1708 child_pass_id,
1709 mask_resource_id,
1710 gfx::Vector2dF(2.f, 1.f), // mask_uv_scale
1711 gfx::Size(mask_rect.size()), // mask_texture_size
1712 FilterOperations(), // foreground filters
1713 gfx::Vector2dF(), // filters scale
1714 FilterOperations()); // background filters
1716 // White background behind the masked render pass.
1717 SolidColorDrawQuad* white =
1718 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1719 white->SetNew(root_pass_shared_state,
1720 viewport_rect,
1721 viewport_rect,
1722 SK_ColorWHITE,
1723 false);
1725 RenderPassList pass_list;
1726 pass_list.push_back(child_pass.Pass());
1727 pass_list.push_back(root_pass.Pass());
1729 EXPECT_TRUE(this->RunPixelTest(
1730 &pass_list,
1731 base::FilePath(FILE_PATH_LITERAL("mask_bottom_right.png")),
1732 ExactPixelComparator(true)));
1735 template <typename RendererType>
1736 class RendererPixelTestWithBackgroundFilter
1737 : public RendererPixelTest<RendererType> {
1738 protected:
1739 void SetUpRenderPassList() {
1740 gfx::Rect device_viewport_rect(this->device_viewport_size_);
1742 RenderPassId root_id(1, 1);
1743 scoped_ptr<RenderPass> root_pass =
1744 CreateTestRootRenderPass(root_id, device_viewport_rect);
1745 root_pass->has_transparent_background = false;
1747 gfx::Transform identity_quad_to_target_transform;
1749 RenderPassId filter_pass_id(2, 1);
1750 gfx::Transform transform_to_root;
1751 scoped_ptr<RenderPass> filter_pass = CreateTestRenderPass(
1752 filter_pass_id, filter_pass_layer_rect_, transform_to_root);
1754 // A non-visible quad in the filtering render pass.
1756 SharedQuadState* shared_state =
1757 CreateTestSharedQuadState(identity_quad_to_target_transform,
1758 filter_pass_layer_rect_, filter_pass.get());
1759 SolidColorDrawQuad* color_quad =
1760 filter_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1761 color_quad->SetNew(shared_state, filter_pass_layer_rect_,
1762 filter_pass_layer_rect_, SK_ColorTRANSPARENT, false);
1766 SharedQuadState* shared_state =
1767 CreateTestSharedQuadState(filter_pass_to_target_transform_,
1768 filter_pass_layer_rect_, filter_pass.get());
1769 RenderPassDrawQuad* filter_pass_quad =
1770 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
1771 filter_pass_quad->SetNew(shared_state, filter_pass_layer_rect_,
1772 filter_pass_layer_rect_, filter_pass_id,
1773 0, // mask_resource_id
1774 gfx::Vector2dF(), // mask_uv_scale
1775 gfx::Size(), // mask_texture_size
1776 FilterOperations(), // filters
1777 gfx::Vector2dF(), // filters_scale
1778 this->background_filters_);
1781 const int kColumnWidth = device_viewport_rect.width() / 3;
1783 gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20);
1784 for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) {
1785 SharedQuadState* shared_state = CreateTestSharedQuadState(
1786 identity_quad_to_target_transform, left_rect, root_pass.get());
1787 SolidColorDrawQuad* color_quad =
1788 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1789 color_quad->SetNew(
1790 shared_state, left_rect, left_rect, SK_ColorGREEN, false);
1791 left_rect += gfx::Vector2d(0, left_rect.height() + 1);
1794 gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20);
1795 for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) {
1796 SharedQuadState* shared_state = CreateTestSharedQuadState(
1797 identity_quad_to_target_transform, middle_rect, root_pass.get());
1798 SolidColorDrawQuad* color_quad =
1799 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1800 color_quad->SetNew(
1801 shared_state, middle_rect, middle_rect, SK_ColorRED, false);
1802 middle_rect += gfx::Vector2d(0, middle_rect.height() + 1);
1805 gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20);
1806 for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) {
1807 SharedQuadState* shared_state = CreateTestSharedQuadState(
1808 identity_quad_to_target_transform, right_rect, root_pass.get());
1809 SolidColorDrawQuad* color_quad =
1810 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1811 color_quad->SetNew(
1812 shared_state, right_rect, right_rect, SK_ColorBLUE, false);
1813 right_rect += gfx::Vector2d(0, right_rect.height() + 1);
1816 SharedQuadState* shared_state =
1817 CreateTestSharedQuadState(identity_quad_to_target_transform,
1818 device_viewport_rect, root_pass.get());
1819 SolidColorDrawQuad* background_quad =
1820 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1821 background_quad->SetNew(shared_state,
1822 device_viewport_rect,
1823 device_viewport_rect,
1824 SK_ColorWHITE,
1825 false);
1827 pass_list_.push_back(filter_pass.Pass());
1828 pass_list_.push_back(root_pass.Pass());
1831 RenderPassList pass_list_;
1832 FilterOperations background_filters_;
1833 gfx::Transform filter_pass_to_target_transform_;
1834 gfx::Rect filter_pass_layer_rect_;
1837 typedef ::testing::Types<GLRenderer, SoftwareRenderer>
1838 BackgroundFilterRendererTypes;
1839 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter,
1840 BackgroundFilterRendererTypes);
1842 typedef RendererPixelTestWithBackgroundFilter<GLRenderer>
1843 GLRendererPixelTestWithBackgroundFilter;
1845 // TODO(skaslev): The software renderer does not support filters yet.
1846 TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) {
1847 this->background_filters_.Append(
1848 FilterOperation::CreateInvertFilter(1.f));
1850 this->filter_pass_layer_rect_ = gfx::Rect(this->device_viewport_size_);
1851 this->filter_pass_layer_rect_.Inset(12, 14, 16, 18);
1853 this->SetUpRenderPassList();
1854 EXPECT_TRUE(this->RunPixelTest(
1855 &this->pass_list_,
1856 base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
1857 ExactPixelComparator(true)));
1860 class ExternalStencilPixelTest : public GLRendererPixelTest {
1861 protected:
1862 void ClearBackgroundToGreen() {
1863 GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
1864 output_surface_->EnsureBackbuffer();
1865 output_surface_->Reshape(device_viewport_size_, 1);
1866 gl->ClearColor(0.f, 1.f, 0.f, 1.f);
1867 gl->Clear(GL_COLOR_BUFFER_BIT);
1870 void PopulateStencilBuffer() {
1871 // Set two quadrants of the stencil buffer to 1.
1872 GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
1873 output_surface_->EnsureBackbuffer();
1874 output_surface_->Reshape(device_viewport_size_, 1);
1875 gl->ClearStencil(0);
1876 gl->Clear(GL_STENCIL_BUFFER_BIT);
1877 gl->Enable(GL_SCISSOR_TEST);
1878 gl->ClearStencil(1);
1879 gl->Scissor(0,
1881 device_viewport_size_.width() / 2,
1882 device_viewport_size_.height() / 2);
1883 gl->Clear(GL_STENCIL_BUFFER_BIT);
1884 gl->Scissor(device_viewport_size_.width() / 2,
1885 device_viewport_size_.height() / 2,
1886 device_viewport_size_.width(),
1887 device_viewport_size_.height());
1888 gl->Clear(GL_STENCIL_BUFFER_BIT);
1892 TEST_F(ExternalStencilPixelTest, StencilTestEnabled) {
1893 ClearBackgroundToGreen();
1894 PopulateStencilBuffer();
1895 this->EnableExternalStencilTest();
1897 // Draw a blue quad that covers the entire device viewport. It should be
1898 // clipped to the bottom left and top right corners by the external stencil.
1899 gfx::Rect rect(this->device_viewport_size_);
1900 RenderPassId id(1, 1);
1901 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1902 SharedQuadState* blue_shared_state =
1903 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1904 SolidColorDrawQuad* blue =
1905 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1906 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1907 pass->has_transparent_background = false;
1908 RenderPassList pass_list;
1909 pass_list.push_back(pass.Pass());
1911 EXPECT_TRUE(this->RunPixelTest(
1912 &pass_list,
1913 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1914 ExactPixelComparator(true)));
1917 TEST_F(ExternalStencilPixelTest, StencilTestDisabled) {
1918 PopulateStencilBuffer();
1920 // Draw a green quad that covers the entire device viewport. The stencil
1921 // buffer should be ignored.
1922 gfx::Rect rect(this->device_viewport_size_);
1923 RenderPassId id(1, 1);
1924 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1925 SharedQuadState* green_shared_state =
1926 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1927 SolidColorDrawQuad* green =
1928 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1929 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
1930 RenderPassList pass_list;
1931 pass_list.push_back(pass.Pass());
1933 EXPECT_TRUE(this->RunPixelTest(
1934 &pass_list,
1935 base::FilePath(FILE_PATH_LITERAL("green.png")),
1936 ExactPixelComparator(true)));
1939 TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) {
1940 // The stencil test should apply only to the final render pass.
1941 ClearBackgroundToGreen();
1942 PopulateStencilBuffer();
1943 this->EnableExternalStencilTest();
1945 gfx::Rect viewport_rect(this->device_viewport_size_);
1947 RenderPassId root_pass_id(1, 1);
1948 scoped_ptr<RenderPass> root_pass =
1949 CreateTestRootRenderPass(root_pass_id, viewport_rect);
1950 root_pass->has_transparent_background = false;
1952 RenderPassId child_pass_id(2, 2);
1953 gfx::Rect pass_rect(this->device_viewport_size_);
1954 gfx::Transform transform_to_root;
1955 scoped_ptr<RenderPass> child_pass =
1956 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
1958 gfx::Transform quad_to_target_transform;
1959 SharedQuadState* shared_state = CreateTestSharedQuadState(
1960 quad_to_target_transform, viewport_rect, child_pass.get());
1962 gfx::Rect blue_rect(0,
1964 this->device_viewport_size_.width(),
1965 this->device_viewport_size_.height());
1966 SolidColorDrawQuad* blue =
1967 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1968 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
1970 SharedQuadState* pass_shared_state =
1971 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
1972 CreateTestRenderPassDrawQuad(
1973 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
1974 RenderPassList pass_list;
1975 pass_list.push_back(child_pass.Pass());
1976 pass_list.push_back(root_pass.Pass());
1978 EXPECT_TRUE(this->RunPixelTest(
1979 &pass_list,
1980 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
1981 ExactPixelComparator(true)));
1984 TEST_F(ExternalStencilPixelTest, DeviceClip) {
1985 ClearBackgroundToGreen();
1986 gfx::Rect clip_rect(gfx::Point(150, 150), gfx::Size(50, 50));
1987 this->ForceDeviceClip(clip_rect);
1989 // Draw a blue quad that covers the entire device viewport. It should be
1990 // clipped to the bottom right corner by the device clip.
1991 gfx::Rect rect(this->device_viewport_size_);
1992 RenderPassId id(1, 1);
1993 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
1994 SharedQuadState* blue_shared_state =
1995 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
1996 SolidColorDrawQuad* blue =
1997 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
1998 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
1999 RenderPassList pass_list;
2000 pass_list.push_back(pass.Pass());
2002 EXPECT_TRUE(this->RunPixelTest(
2003 &pass_list,
2004 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
2005 ExactPixelComparator(true)));
2008 // Software renderer does not support anti-aliased edges.
2009 TEST_F(GLRendererPixelTest, AntiAliasing) {
2010 gfx::Rect rect(this->device_viewport_size_);
2012 RenderPassId id(1, 1);
2013 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2015 gfx::Transform red_quad_to_target_transform;
2016 red_quad_to_target_transform.Rotate(10);
2017 SharedQuadState* red_shared_state =
2018 CreateTestSharedQuadState(red_quad_to_target_transform, rect, pass.get());
2020 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2021 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
2023 gfx::Transform yellow_quad_to_target_transform;
2024 yellow_quad_to_target_transform.Rotate(5);
2025 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
2026 yellow_quad_to_target_transform, rect, pass.get());
2028 SolidColorDrawQuad* yellow =
2029 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2030 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
2032 gfx::Transform blue_quad_to_target_transform;
2033 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2034 blue_quad_to_target_transform, rect, pass.get());
2036 SolidColorDrawQuad* blue =
2037 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2038 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2040 RenderPassList pass_list;
2041 pass_list.push_back(pass.Pass());
2043 EXPECT_TRUE(this->RunPixelTest(
2044 &pass_list,
2045 base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")),
2046 FuzzyPixelOffByOneComparator(true)));
2049 // This test tests that anti-aliasing works for axis aligned quads.
2050 // Anti-aliasing is only supported in the gl renderer.
2051 TEST_F(GLRendererPixelTest, AxisAligned) {
2052 gfx::Rect rect(this->device_viewport_size_);
2054 RenderPassId id(1, 1);
2055 gfx::Transform transform_to_root;
2056 scoped_ptr<RenderPass> pass =
2057 CreateTestRenderPass(id, rect, transform_to_root);
2059 gfx::Transform red_quad_to_target_transform;
2060 red_quad_to_target_transform.Translate(50, 50);
2061 red_quad_to_target_transform.Scale(0.5f + 1.0f / (rect.width() * 2.0f),
2062 0.5f + 1.0f / (rect.height() * 2.0f));
2063 SharedQuadState* red_shared_state =
2064 CreateTestSharedQuadState(red_quad_to_target_transform, rect, pass.get());
2066 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2067 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
2069 gfx::Transform yellow_quad_to_target_transform;
2070 yellow_quad_to_target_transform.Translate(25.5f, 25.5f);
2071 yellow_quad_to_target_transform.Scale(0.5f, 0.5f);
2072 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
2073 yellow_quad_to_target_transform, rect, pass.get());
2075 SolidColorDrawQuad* yellow =
2076 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2077 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
2079 gfx::Transform blue_quad_to_target_transform;
2080 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2081 blue_quad_to_target_transform, rect, pass.get());
2083 SolidColorDrawQuad* blue =
2084 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2085 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
2087 RenderPassList pass_list;
2088 pass_list.push_back(pass.Pass());
2090 EXPECT_TRUE(this->RunPixelTest(
2091 &pass_list,
2092 base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")),
2093 ExactPixelComparator(true)));
2096 // This test tests that forcing anti-aliasing off works as expected.
2097 // Anti-aliasing is only supported in the gl renderer.
2098 TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) {
2099 gfx::Rect rect(this->device_viewport_size_);
2101 RenderPassId id(1, 1);
2102 gfx::Transform transform_to_root;
2103 scoped_ptr<RenderPass> pass =
2104 CreateTestRenderPass(id, rect, transform_to_root);
2106 gfx::Transform hole_quad_to_target_transform;
2107 hole_quad_to_target_transform.Translate(50, 50);
2108 hole_quad_to_target_transform.Scale(0.5f + 1.0f / (rect.width() * 2.0f),
2109 0.5f + 1.0f / (rect.height() * 2.0f));
2110 SharedQuadState* hole_shared_state = CreateTestSharedQuadState(
2111 hole_quad_to_target_transform, rect, pass.get());
2113 SolidColorDrawQuad* hole =
2114 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2115 hole->SetAll(
2116 hole_shared_state, rect, rect, rect, false, SK_ColorTRANSPARENT, true);
2118 gfx::Transform green_quad_to_target_transform;
2119 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2120 green_quad_to_target_transform, rect, pass.get());
2122 SolidColorDrawQuad* green =
2123 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2124 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
2126 RenderPassList pass_list;
2127 pass_list.push_back(pass.Pass());
2129 EXPECT_TRUE(this->RunPixelTest(
2130 &pass_list,
2131 base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")),
2132 ExactPixelComparator(false)));
2135 TEST_F(GLRendererPixelTest, AntiAliasingPerspective) {
2136 gfx::Rect rect(this->device_viewport_size_);
2138 scoped_ptr<RenderPass> pass =
2139 CreateTestRootRenderPass(RenderPassId(1, 1), rect);
2141 gfx::Rect red_rect(0, 0, 180, 500);
2142 gfx::Transform red_quad_to_target_transform(
2143 1.0f, 2.4520f, 10.6206f, 19.0f, 0.0f, 0.3528f, 5.9737f, 9.5f, 0.0f,
2144 -0.2250f, -0.9744f, 0.0f, 0.0f, 0.0225f, 0.0974f, 1.0f);
2145 SharedQuadState* red_shared_state = CreateTestSharedQuadState(
2146 red_quad_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::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right());
2204 gfx::Transform blue_quad_to_target_transform;
2205 blue_quad_to_target_transform.Translate(offset.x(), offset.y());
2206 gfx::Rect blue_target_clip_rect = MathUtil::MapEnclosingClippedRect(
2207 blue_quad_to_target_transform, blue_clip_rect);
2208 SharedQuadState* blue_shared_state =
2209 CreateTestSharedQuadStateClipped(blue_quad_to_target_transform, blue_rect,
2210 blue_target_clip_rect, pass.get());
2212 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2214 blue_quad->SetNew(blue_shared_state,
2215 viewport, // Intentionally bigger than clip.
2216 gfx::Rect(), viewport, gfx::RectF(viewport),
2217 viewport.size(), nearest_neighbor, texture_format, viewport,
2218 1.f, blue_pile.get());
2220 // One viewport-filling green quad.
2221 scoped_ptr<FakePicturePile> green_recording =
2222 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2223 SkPaint green_paint;
2224 green_paint.setColor(SK_ColorGREEN);
2225 green_recording->add_draw_rect_with_paint(viewport, green_paint);
2226 green_recording->Rerecord();
2227 scoped_refptr<FakePicturePileImpl> green_pile =
2228 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2230 gfx::Transform green_quad_to_target_transform;
2231 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2232 green_quad_to_target_transform, viewport, pass.get());
2234 PictureDrawQuad* green_quad =
2235 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2236 green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
2237 gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(),
2238 nearest_neighbor, texture_format, viewport, 1.f,
2239 green_pile.get());
2241 RenderPassList pass_list;
2242 pass_list.push_back(pass.Pass());
2244 EXPECT_TRUE(this->RunPixelTest(
2245 &pass_list,
2246 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
2247 ExactPixelComparator(true)));
2250 // Not WithSkiaGPUBackend since that path currently requires tiles for opacity.
2251 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadOpacity) {
2252 gfx::Size pile_tile_size(1000, 1000);
2253 gfx::Rect viewport(this->device_viewport_size_);
2254 ResourceFormat texture_format = RGBA_8888;
2255 bool nearest_neighbor = false;
2257 RenderPassId id(1, 1);
2258 gfx::Transform transform_to_root;
2259 scoped_ptr<RenderPass> pass =
2260 CreateTestRenderPass(id, viewport, transform_to_root);
2262 // One viewport-filling 0.5-opacity green quad.
2263 scoped_ptr<FakePicturePile> green_recording =
2264 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2265 SkPaint green_paint;
2266 green_paint.setColor(SK_ColorGREEN);
2267 green_recording->add_draw_rect_with_paint(viewport, green_paint);
2268 green_recording->Rerecord();
2269 scoped_refptr<FakePicturePileImpl> green_pile =
2270 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2272 gfx::Transform green_quad_to_target_transform;
2273 SharedQuadState* green_shared_state = CreateTestSharedQuadState(
2274 green_quad_to_target_transform, viewport, pass.get());
2275 green_shared_state->opacity = 0.5f;
2277 PictureDrawQuad* green_quad =
2278 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2279 green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
2280 gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
2281 texture_format, viewport, 1.f, green_pile.get());
2283 // One viewport-filling white quad.
2284 scoped_ptr<FakePicturePile> white_recording =
2285 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2286 SkPaint white_paint;
2287 white_paint.setColor(SK_ColorWHITE);
2288 white_recording->add_draw_rect_with_paint(viewport, white_paint);
2289 white_recording->Rerecord();
2290 scoped_refptr<FakePicturePileImpl> white_pile =
2291 FakePicturePileImpl::CreateFromPile(white_recording.get(), nullptr);
2293 gfx::Transform white_quad_to_target_transform;
2294 SharedQuadState* white_shared_state = CreateTestSharedQuadState(
2295 white_quad_to_target_transform, viewport, pass.get());
2297 PictureDrawQuad* white_quad =
2298 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2299 white_quad->SetNew(white_shared_state, viewport, gfx::Rect(), viewport,
2300 gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
2301 texture_format, viewport, 1.f, white_pile.get());
2303 RenderPassList pass_list;
2304 pass_list.push_back(pass.Pass());
2306 EXPECT_TRUE(this->RunPixelTest(
2307 &pass_list,
2308 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
2309 FuzzyPixelOffByOneComparator(true)));
2312 template<typename TypeParam> bool IsSoftwareRenderer() {
2313 return false;
2316 template<>
2317 bool IsSoftwareRenderer<SoftwareRenderer>() {
2318 return true;
2321 template<>
2322 bool IsSoftwareRenderer<SoftwareRendererWithExpandedViewport>() {
2323 return true;
2326 // If we disable image filtering, then a 2x2 bitmap should appear as four
2327 // huge sharp squares.
2328 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadDisableImageFiltering) {
2329 // We only care about this in software mode since bilinear filtering is
2330 // cheap in hardware.
2331 if (!IsSoftwareRenderer<TypeParam>())
2332 return;
2334 gfx::Size pile_tile_size(1000, 1000);
2335 gfx::Rect viewport(this->device_viewport_size_);
2336 ResourceFormat texture_format = RGBA_8888;
2337 bool nearest_neighbor = false;
2339 RenderPassId id(1, 1);
2340 gfx::Transform transform_to_root;
2341 scoped_ptr<RenderPass> pass =
2342 CreateTestRenderPass(id, viewport, transform_to_root);
2344 skia::RefPtr<SkSurface> surface =
2345 skia::AdoptRef(SkSurface::NewRasterN32Premul(2, 2));
2346 ASSERT_NE(surface, nullptr);
2347 SkCanvas* canvas = surface->getCanvas();
2348 canvas->drawPoint(0, 0, SK_ColorGREEN);
2349 canvas->drawPoint(0, 1, SK_ColorBLUE);
2350 canvas->drawPoint(1, 0, SK_ColorBLUE);
2351 canvas->drawPoint(1, 1, SK_ColorGREEN);
2352 skia::RefPtr<SkImage> image = skia::AdoptRef(surface->newImageSnapshot());
2354 scoped_ptr<FakePicturePile> recording =
2355 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2356 SkPaint paint;
2357 paint.setFilterQuality(kLow_SkFilterQuality);
2358 recording->add_draw_image_with_paint(image.get(), gfx::Point(), paint);
2359 recording->Rerecord();
2360 scoped_refptr<FakePicturePileImpl> pile =
2361 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2363 gfx::Transform quad_to_target_transform;
2364 SharedQuadState* shared_state =
2365 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2367 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2368 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
2369 gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
2370 texture_format, viewport, 1.f, pile.get());
2372 RenderPassList pass_list;
2373 pass_list.push_back(pass.Pass());
2375 this->disable_picture_quad_image_filtering_ = true;
2377 EXPECT_TRUE(this->RunPixelTest(
2378 &pass_list,
2379 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2380 ExactPixelComparator(true)));
2383 // This disables filtering by setting |nearest_neighbor| on the PictureDrawQuad.
2384 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNearestNeighbor) {
2385 gfx::Size pile_tile_size(1000, 1000);
2386 gfx::Rect viewport(this->device_viewport_size_);
2387 ResourceFormat texture_format = RGBA_8888;
2388 bool nearest_neighbor = true;
2390 RenderPassId id(1, 1);
2391 gfx::Transform transform_to_root;
2392 scoped_ptr<RenderPass> pass =
2393 CreateTestRenderPass(id, viewport, transform_to_root);
2395 skia::RefPtr<SkSurface> surface =
2396 skia::AdoptRef(SkSurface::NewRasterN32Premul(2, 2));
2397 ASSERT_NE(surface, nullptr);
2398 SkCanvas* canvas = surface->getCanvas();
2399 canvas->drawPoint(0, 0, SK_ColorGREEN);
2400 canvas->drawPoint(0, 1, SK_ColorBLUE);
2401 canvas->drawPoint(1, 0, SK_ColorBLUE);
2402 canvas->drawPoint(1, 1, SK_ColorGREEN);
2403 skia::RefPtr<SkImage> image = skia::AdoptRef(surface->newImageSnapshot());
2405 scoped_ptr<FakePicturePile> recording =
2406 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2407 SkPaint paint;
2408 paint.setFilterQuality(kLow_SkFilterQuality);
2409 recording->add_draw_image_with_paint(image.get(), gfx::Point(), paint);
2410 recording->Rerecord();
2411 scoped_refptr<FakePicturePileImpl> pile =
2412 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2414 gfx::Transform quad_to_target_transform;
2415 SharedQuadState* shared_state =
2416 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2418 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2419 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
2420 gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
2421 texture_format, viewport, 1.f, pile.get());
2423 RenderPassList pass_list;
2424 pass_list.push_back(pass.Pass());
2426 EXPECT_TRUE(this->RunPixelTest(
2427 &pass_list,
2428 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2429 ExactPixelComparator(true)));
2432 // This disables filtering by setting |nearest_neighbor| on the TileDrawQuad.
2433 TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) {
2434 gfx::Rect viewport(this->device_viewport_size_);
2435 bool swizzle_contents = true;
2436 bool nearest_neighbor = true;
2438 SkBitmap bitmap;
2439 bitmap.allocN32Pixels(2, 2);
2441 SkAutoLockPixels lock(bitmap);
2442 SkCanvas canvas(bitmap);
2443 canvas.drawPoint(0, 0, SK_ColorGREEN);
2444 canvas.drawPoint(0, 1, SK_ColorBLUE);
2445 canvas.drawPoint(1, 0, SK_ColorBLUE);
2446 canvas.drawPoint(1, 1, SK_ColorGREEN);
2449 gfx::Size tile_size(2, 2);
2450 ResourceId resource = this->resource_provider_->CreateResource(
2451 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2452 RGBA_8888);
2455 SkAutoLockPixels lock(bitmap);
2456 this->resource_provider_->CopyToResource(
2457 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
2460 RenderPassId id(1, 1);
2461 gfx::Transform transform_to_root;
2462 scoped_ptr<RenderPass> pass =
2463 CreateTestRenderPass(id, viewport, transform_to_root);
2465 gfx::Transform quad_to_target_transform;
2466 SharedQuadState* shared_state =
2467 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2469 TileDrawQuad* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>();
2470 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource,
2471 gfx::RectF(gfx::Rect(tile_size)), tile_size, swizzle_contents,
2472 nearest_neighbor);
2474 RenderPassList pass_list;
2475 pass_list.push_back(pass.Pass());
2477 EXPECT_TRUE(this->RunPixelTest(
2478 &pass_list,
2479 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2480 ExactPixelComparator(true)));
2483 // This disables filtering by setting |nearest_neighbor| to true on the
2484 // TextureDrawQuad.
2485 TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadNearestNeighbor) {
2486 gfx::Rect viewport(this->device_viewport_size_);
2487 bool nearest_neighbor = true;
2489 SkBitmap bitmap;
2490 bitmap.allocN32Pixels(2, 2);
2492 SkAutoLockPixels lock(bitmap);
2493 SkCanvas canvas(bitmap);
2494 canvas.drawPoint(0, 0, SK_ColorGREEN);
2495 canvas.drawPoint(0, 1, SK_ColorBLUE);
2496 canvas.drawPoint(1, 0, SK_ColorBLUE);
2497 canvas.drawPoint(1, 1, SK_ColorGREEN);
2500 gfx::Size tile_size(2, 2);
2501 ResourceId resource = this->resource_provider_->CreateResource(
2502 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2503 RGBA_8888);
2506 SkAutoLockPixels lock(bitmap);
2507 this->resource_provider_->CopyToResource(
2508 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
2511 RenderPassId id(1, 1);
2512 gfx::Transform transform_to_root;
2513 scoped_ptr<RenderPass> pass =
2514 CreateTestRenderPass(id, viewport, transform_to_root);
2516 gfx::Transform quad_to_target_transform;
2517 SharedQuadState* shared_state =
2518 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2520 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2521 TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2522 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource, false,
2523 gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorBLACK,
2524 vertex_opacity, false, nearest_neighbor);
2526 RenderPassList pass_list;
2527 pass_list.push_back(pass.Pass());
2529 EXPECT_TRUE(this->RunPixelTest(
2530 &pass_list,
2531 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2532 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)));
2535 // This ensures filtering is enabled by setting |nearest_neighbor| to false on
2536 // the TextureDrawQuad.
2537 TYPED_TEST(SoftwareRendererPixelTest, TextureDrawQuadLinear) {
2538 gfx::Rect viewport(this->device_viewport_size_);
2539 bool nearest_neighbor = false;
2541 SkBitmap bitmap;
2542 bitmap.allocN32Pixels(2, 2);
2544 SkAutoLockPixels lock(bitmap);
2545 SkCanvas canvas(bitmap);
2546 canvas.drawPoint(0, 0, SK_ColorGREEN);
2547 canvas.drawPoint(0, 1, SK_ColorBLUE);
2548 canvas.drawPoint(1, 0, SK_ColorBLUE);
2549 canvas.drawPoint(1, 1, SK_ColorGREEN);
2552 gfx::Size tile_size(2, 2);
2553 ResourceId resource = this->resource_provider_->CreateResource(
2554 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2555 RGBA_8888);
2558 SkAutoLockPixels lock(bitmap);
2559 this->resource_provider_->CopyToResource(
2560 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
2563 RenderPassId id(1, 1);
2564 gfx::Transform transform_to_root;
2565 scoped_ptr<RenderPass> pass =
2566 CreateTestRenderPass(id, viewport, transform_to_root);
2568 gfx::Transform quad_to_target_transform;
2569 SharedQuadState* shared_state =
2570 CreateTestSharedQuadState(quad_to_target_transform, viewport, pass.get());
2572 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2573 TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2574 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource, false,
2575 gfx::PointF(0, 0), gfx::PointF(1, 1), SK_ColorBLACK,
2576 vertex_opacity, false, nearest_neighbor);
2578 RenderPassList pass_list;
2579 pass_list.push_back(pass.Pass());
2581 // Allow for a small amount of error as the blending alogrithm used by Skia is
2582 // affected by the offset in the expanded rect.
2583 EXPECT_TRUE(this->RunPixelTest(
2584 &pass_list,
2585 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers_linear.png")),
2586 FuzzyPixelComparator(false, 100.f, 0.f, 16.f, 16.f, 0.f)));
2589 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) {
2590 gfx::Size pile_tile_size(1000, 1000);
2591 gfx::Rect viewport(this->device_viewport_size_);
2592 // TODO(enne): the renderer should figure this out on its own.
2593 ResourceFormat texture_format = RGBA_8888;
2594 bool nearest_neighbor = false;
2596 RenderPassId id(1, 1);
2597 gfx::Transform transform_to_root;
2598 scoped_ptr<RenderPass> pass =
2599 CreateTestRenderPass(id, viewport, transform_to_root);
2601 // As scaling up the blue checkerboards will cause sampling on the GPU,
2602 // a few extra "cleanup rects" need to be added to clobber the blending
2603 // to make the output image more clean. This will also test subrects
2604 // of the layer.
2605 gfx::Transform green_quad_to_target_transform;
2606 gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100));
2607 gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20));
2609 scoped_ptr<FakePicturePile> green_recording =
2610 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
2612 SkPaint red_paint;
2613 red_paint.setColor(SK_ColorRED);
2614 green_recording->add_draw_rect_with_paint(viewport, red_paint);
2615 SkPaint green_paint;
2616 green_paint.setColor(SK_ColorGREEN);
2617 green_recording->add_draw_rect_with_paint(green_rect1, green_paint);
2618 green_recording->add_draw_rect_with_paint(green_rect2, green_paint);
2619 green_recording->Rerecord();
2620 scoped_refptr<FakePicturePileImpl> green_pile =
2621 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
2623 SharedQuadState* top_right_green_shared_quad_state =
2624 CreateTestSharedQuadState(green_quad_to_target_transform, viewport,
2625 pass.get());
2627 PictureDrawQuad* green_quad1 =
2628 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2629 green_quad1->SetNew(top_right_green_shared_quad_state, green_rect1,
2630 gfx::Rect(), green_rect1, gfx::RectF(green_rect1.size()),
2631 green_rect1.size(), nearest_neighbor, texture_format,
2632 green_rect1, 1.f, green_pile.get());
2634 PictureDrawQuad* green_quad2 =
2635 pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2636 green_quad2->SetNew(top_right_green_shared_quad_state, green_rect2,
2637 gfx::Rect(), green_rect2, gfx::RectF(green_rect2.size()),
2638 green_rect2.size(), nearest_neighbor, texture_format,
2639 green_rect2, 1.f, green_pile.get());
2641 // Add a green clipped checkerboard in the bottom right to help test
2642 // interleaving picture quad content and solid color content.
2643 gfx::Rect bottom_right_rect(
2644 gfx::Point(viewport.width() / 2, viewport.height() / 2),
2645 gfx::Size(viewport.width() / 2, viewport.height() / 2));
2646 SharedQuadState* bottom_right_green_shared_state =
2647 CreateTestSharedQuadStateClipped(green_quad_to_target_transform, viewport,
2648 bottom_right_rect, pass.get());
2649 SolidColorDrawQuad* bottom_right_color_quad =
2650 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2651 bottom_right_color_quad->SetNew(bottom_right_green_shared_state,
2652 viewport,
2653 viewport,
2654 SK_ColorGREEN,
2655 false);
2657 // Add two blue checkerboards taking up the bottom left and top right,
2658 // but use content scales as content rects to make this happen.
2659 // The content is at a 4x content scale.
2660 gfx::Rect layer_rect(gfx::Size(20, 30));
2661 float contents_scale = 4.f;
2662 // Two rects that touch at their corners, arbitrarily placed in the layer.
2663 gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f));
2664 gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f));
2665 gfx::RectF union_layer_rect = blue_layer_rect1;
2666 union_layer_rect.Union(blue_layer_rect2);
2668 // Because scaling up will cause sampling outside the rects, add one extra
2669 // pixel of buffer at the final content scale.
2670 float inset = -1.f / contents_scale;
2671 blue_layer_rect1.Inset(inset, inset, inset, inset);
2672 blue_layer_rect2.Inset(inset, inset, inset, inset);
2674 scoped_ptr<FakePicturePile> recording =
2675 FakePicturePile::CreateFilledPile(pile_tile_size, layer_rect.size());
2677 Region outside(layer_rect);
2678 outside.Subtract(gfx::ToEnclosingRect(union_layer_rect));
2679 for (Region::Iterator iter(outside); iter.has_rect(); iter.next()) {
2680 recording->add_draw_rect_with_paint(iter.rect(), red_paint);
2683 SkPaint blue_paint;
2684 blue_paint.setColor(SK_ColorBLUE);
2685 recording->add_draw_rectf_with_paint(blue_layer_rect1, blue_paint);
2686 recording->add_draw_rectf_with_paint(blue_layer_rect2, blue_paint);
2687 recording->Rerecord();
2688 scoped_refptr<FakePicturePileImpl> pile =
2689 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
2691 gfx::Rect content_rect(
2692 gfx::ScaleToEnclosingRect(layer_rect, contents_scale));
2693 gfx::Rect content_union_rect(
2694 gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale)));
2696 // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels,
2697 // so scale an additional 10x to make them 100x100.
2698 gfx::Transform quad_to_target_transform;
2699 quad_to_target_transform.Scale(10.0, 10.0);
2700 gfx::Rect quad_content_rect(gfx::Size(20, 20));
2701 SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
2702 quad_to_target_transform, quad_content_rect, pass.get());
2704 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
2705 blue_quad->SetNew(blue_shared_state, quad_content_rect, gfx::Rect(),
2706 quad_content_rect, gfx::RectF(quad_content_rect),
2707 content_union_rect.size(), nearest_neighbor, texture_format,
2708 content_union_rect, contents_scale, pile.get());
2710 // Fill left half of viewport with green.
2711 gfx::Transform half_green_quad_to_target_transform;
2712 gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height()));
2713 SharedQuadState* half_green_shared_state = CreateTestSharedQuadState(
2714 half_green_quad_to_target_transform, half_green_rect, pass.get());
2715 SolidColorDrawQuad* half_color_quad =
2716 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2717 half_color_quad->SetNew(half_green_shared_state,
2718 half_green_rect,
2719 half_green_rect,
2720 SK_ColorGREEN,
2721 false);
2723 RenderPassList pass_list;
2724 pass_list.push_back(pass.Pass());
2726 EXPECT_TRUE(this->RunPixelTest(
2727 &pass_list,
2728 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
2729 ExactPixelComparator(true)));
2732 typedef RendererPixelTest<GLRendererWithFlippedSurface>
2733 GLRendererPixelTestWithFlippedOutputSurface;
2735 TEST_F(GLRendererPixelTestWithFlippedOutputSurface, ExplicitFlipTest) {
2736 // This draws a blue rect above a yellow rect with an inverted output surface.
2737 gfx::Rect viewport_rect(this->device_viewport_size_);
2739 RenderPassId root_pass_id(1, 1);
2740 scoped_ptr<RenderPass> root_pass =
2741 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2743 RenderPassId child_pass_id(2, 2);
2744 gfx::Rect pass_rect(this->device_viewport_size_);
2745 gfx::Transform transform_to_root;
2746 scoped_ptr<RenderPass> child_pass =
2747 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2749 gfx::Transform quad_to_target_transform;
2750 SharedQuadState* shared_state = CreateTestSharedQuadState(
2751 quad_to_target_transform, viewport_rect, child_pass.get());
2753 gfx::Rect blue_rect(0,
2755 this->device_viewport_size_.width(),
2756 this->device_viewport_size_.height() / 2);
2757 SolidColorDrawQuad* blue =
2758 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2759 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2760 gfx::Rect yellow_rect(0,
2761 this->device_viewport_size_.height() / 2,
2762 this->device_viewport_size_.width(),
2763 this->device_viewport_size_.height() / 2);
2764 SolidColorDrawQuad* yellow =
2765 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2766 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
2768 SharedQuadState* pass_shared_state =
2769 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2770 CreateTestRenderPassDrawQuad(
2771 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2773 RenderPassList pass_list;
2774 pass_list.push_back(child_pass.Pass());
2775 pass_list.push_back(root_pass.Pass());
2777 EXPECT_TRUE(this->RunPixelTest(
2778 &pass_list,
2779 base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")),
2780 ExactPixelComparator(true)));
2783 TEST_F(GLRendererPixelTestWithFlippedOutputSurface, CheckChildPassUnflipped) {
2784 // This draws a blue rect above a yellow rect with an inverted output surface.
2785 gfx::Rect viewport_rect(this->device_viewport_size_);
2787 RenderPassId root_pass_id(1, 1);
2788 scoped_ptr<RenderPass> root_pass =
2789 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2791 RenderPassId child_pass_id(2, 2);
2792 gfx::Rect pass_rect(this->device_viewport_size_);
2793 gfx::Transform transform_to_root;
2794 scoped_ptr<RenderPass> child_pass =
2795 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2797 gfx::Transform quad_to_target_transform;
2798 SharedQuadState* shared_state = CreateTestSharedQuadState(
2799 quad_to_target_transform, viewport_rect, child_pass.get());
2801 gfx::Rect blue_rect(0,
2803 this->device_viewport_size_.width(),
2804 this->device_viewport_size_.height() / 2);
2805 SolidColorDrawQuad* blue =
2806 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2807 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2808 gfx::Rect yellow_rect(0,
2809 this->device_viewport_size_.height() / 2,
2810 this->device_viewport_size_.width(),
2811 this->device_viewport_size_.height() / 2);
2812 SolidColorDrawQuad* yellow =
2813 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2814 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
2816 SharedQuadState* pass_shared_state =
2817 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2818 CreateTestRenderPassDrawQuad(
2819 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2821 RenderPassList pass_list;
2822 pass_list.push_back(child_pass.Pass());
2823 pass_list.push_back(root_pass.Pass());
2825 // Check that the child pass remains unflipped.
2826 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
2827 &pass_list,
2828 pass_list.front(),
2829 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
2830 ExactPixelComparator(true)));
2833 TEST_F(GLRendererPixelTest, CheckReadbackSubset) {
2834 gfx::Rect viewport_rect(this->device_viewport_size_);
2836 RenderPassId root_pass_id(1, 1);
2837 scoped_ptr<RenderPass> root_pass =
2838 CreateTestRootRenderPass(root_pass_id, viewport_rect);
2840 RenderPassId child_pass_id(2, 2);
2841 gfx::Rect pass_rect(this->device_viewport_size_);
2842 gfx::Transform transform_to_root;
2843 scoped_ptr<RenderPass> child_pass =
2844 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
2846 gfx::Transform quad_to_target_transform;
2847 SharedQuadState* shared_state = CreateTestSharedQuadState(
2848 quad_to_target_transform, viewport_rect, child_pass.get());
2850 // Draw a green quad full-size with a blue quad in the lower-right corner.
2851 gfx::Rect blue_rect(this->device_viewport_size_.width() * 3 / 4,
2852 this->device_viewport_size_.height() * 3 / 4,
2853 this->device_viewport_size_.width() * 3 / 4,
2854 this->device_viewport_size_.height() * 3 / 4);
2855 SolidColorDrawQuad* blue =
2856 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2857 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
2858 gfx::Rect green_rect(0,
2860 this->device_viewport_size_.width(),
2861 this->device_viewport_size_.height());
2862 SolidColorDrawQuad* green =
2863 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
2864 green->SetNew(shared_state, green_rect, green_rect, SK_ColorGREEN, false);
2866 SharedQuadState* pass_shared_state =
2867 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
2868 CreateTestRenderPassDrawQuad(
2869 pass_shared_state, pass_rect, child_pass_id, root_pass.get());
2871 RenderPassList pass_list;
2872 pass_list.push_back(child_pass.Pass());
2873 pass_list.push_back(root_pass.Pass());
2875 // Check that the child pass remains unflipped.
2876 gfx::Rect capture_rect(this->device_viewport_size_.width() / 2,
2877 this->device_viewport_size_.height() / 2,
2878 this->device_viewport_size_.width() / 2,
2879 this->device_viewport_size_.height() / 2);
2880 EXPECT_TRUE(this->RunPixelTestWithReadbackTargetAndArea(
2881 &pass_list,
2882 pass_list.front(),
2883 base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")),
2884 ExactPixelComparator(true),
2885 &capture_rect));
2888 TYPED_TEST(RendererPixelTest, WrapModeRepeat) {
2889 gfx::Rect rect(this->device_viewport_size_);
2891 RenderPassId id(1, 1);
2892 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
2894 SharedQuadState* shared_state =
2895 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
2897 gfx::Size texture_size(4, 4);
2898 SkPMColor colors[4] = {
2899 SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)),
2900 SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)),
2901 SkPreMultiplyColor(SkColorSetARGB(255, 0, 64, 0)),
2902 SkPreMultiplyColor(SkColorSetARGB(255, 0, 0, 0)),
2904 uint32_t pixels[16] = {
2905 colors[0], colors[0], colors[1], colors[1],
2906 colors[0], colors[0], colors[1], colors[1],
2907 colors[2], colors[2], colors[3], colors[3],
2908 colors[2], colors[2], colors[3], colors[3],
2910 ResourceId resource = this->resource_provider_->CreateResource(
2911 texture_size, GL_REPEAT, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
2912 RGBA_8888);
2913 this->resource_provider_->CopyToResource(
2914 resource, reinterpret_cast<uint8_t*>(pixels), texture_size);
2916 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
2917 TextureDrawQuad* texture_quad =
2918 pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
2919 texture_quad->SetNew(
2920 shared_state, gfx::Rect(this->device_viewport_size_), gfx::Rect(),
2921 gfx::Rect(this->device_viewport_size_), resource,
2922 true, // premultiplied_alpha
2923 gfx::PointF(0.0f, 0.0f), // uv_top_left
2924 gfx::PointF( // uv_bottom_right
2925 this->device_viewport_size_.width() / texture_size.width(),
2926 this->device_viewport_size_.height() / texture_size.height()),
2927 SK_ColorWHITE, vertex_opacity,
2928 false, // flipped
2929 false); // nearest_neighbor
2931 RenderPassList pass_list;
2932 pass_list.push_back(pass.Pass());
2934 EXPECT_TRUE(this->RunPixelTest(
2935 &pass_list,
2936 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
2937 FuzzyPixelOffByOneComparator(true)));
2940 #endif // !defined(OS_ANDROID)
2942 } // namespace
2943 } // namespace cc