OLD | NEW |
| (Empty) |
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. | |
4 | |
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 "third_party/skia/include/core/SkColorPriv.h" | |
15 #include "third_party/skia/include/core/SkImageFilter.h" | |
16 #include "third_party/skia/include/core/SkMatrix.h" | |
17 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" | |
18 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" | |
19 #include "ui/gfx/geometry/rect_conversions.h" | |
20 | |
21 using gpu::gles2::GLES2Interface; | |
22 | |
23 namespace cc { | |
24 namespace { | |
25 | |
26 #if !defined(OS_ANDROID) | |
27 scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPassId id, | |
28 const gfx::Rect& rect) { | |
29 scoped_ptr<RenderPass> pass = RenderPass::Create(); | |
30 const gfx::Rect output_rect = rect; | |
31 const gfx::Rect damage_rect = rect; | |
32 const gfx::Transform transform_to_root_target; | |
33 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target); | |
34 return pass.Pass(); | |
35 } | |
36 | |
37 scoped_ptr<RenderPass> CreateTestRenderPass( | |
38 RenderPassId id, | |
39 const gfx::Rect& rect, | |
40 const gfx::Transform& transform_to_root_target) { | |
41 scoped_ptr<RenderPass> pass = RenderPass::Create(); | |
42 const gfx::Rect output_rect = rect; | |
43 const gfx::Rect damage_rect = rect; | |
44 pass->SetNew(id, output_rect, damage_rect, transform_to_root_target); | |
45 return pass.Pass(); | |
46 } | |
47 | |
48 SharedQuadState* CreateTestSharedQuadState( | |
49 gfx::Transform content_to_target_transform, | |
50 const gfx::Rect& rect, | |
51 RenderPass* render_pass) { | |
52 const gfx::Size content_bounds = rect.size(); | |
53 const gfx::Rect visible_content_rect = rect; | |
54 const gfx::Rect clip_rect = rect; | |
55 const bool is_clipped = false; | |
56 const float opacity = 1.0f; | |
57 const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode; | |
58 int sorting_context_id = 0; | |
59 SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState(); | |
60 shared_state->SetAll(content_to_target_transform, | |
61 content_bounds, | |
62 visible_content_rect, | |
63 clip_rect, | |
64 is_clipped, | |
65 opacity, | |
66 blend_mode, | |
67 sorting_context_id); | |
68 return shared_state; | |
69 } | |
70 | |
71 SharedQuadState* CreateTestSharedQuadStateClipped( | |
72 gfx::Transform content_to_target_transform, | |
73 const gfx::Rect& rect, | |
74 const gfx::Rect& clip_rect, | |
75 RenderPass* render_pass) { | |
76 const gfx::Size content_bounds = rect.size(); | |
77 const gfx::Rect visible_content_rect = clip_rect; | |
78 const bool is_clipped = true; | |
79 const float opacity = 1.0f; | |
80 const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode; | |
81 int sorting_context_id = 0; | |
82 SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState(); | |
83 shared_state->SetAll(content_to_target_transform, | |
84 content_bounds, | |
85 visible_content_rect, | |
86 clip_rect, | |
87 is_clipped, | |
88 opacity, | |
89 blend_mode, | |
90 sorting_context_id); | |
91 return shared_state; | |
92 } | |
93 | |
94 void CreateTestRenderPassDrawQuad(const SharedQuadState* shared_state, | |
95 const gfx::Rect& rect, | |
96 RenderPassId pass_id, | |
97 RenderPass* render_pass) { | |
98 RenderPassDrawQuad* quad = | |
99 render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | |
100 quad->SetNew(shared_state, | |
101 rect, | |
102 rect, | |
103 pass_id, | |
104 0, // mask_resource_id | |
105 gfx::Vector2dF(), // mask_uv_scale | |
106 gfx::Size(), // mask_texture_size | |
107 FilterOperations(), // foreground filters | |
108 gfx::Vector2dF(), // filters scale | |
109 FilterOperations()); // background filters | |
110 } | |
111 | |
112 void CreateTestTwoColoredTextureDrawQuad(const gfx::Rect& rect, | |
113 SkColor texel_color, | |
114 SkColor texel_stripe_color, | |
115 SkColor background_color, | |
116 bool premultiplied_alpha, | |
117 const SharedQuadState* shared_state, | |
118 ResourceProvider* resource_provider, | |
119 RenderPass* render_pass) { | |
120 SkPMColor pixel_color = premultiplied_alpha | |
121 ? SkPreMultiplyColor(texel_color) | |
122 : SkPackARGB32NoCheck(SkColorGetA(texel_color), | |
123 SkColorGetR(texel_color), | |
124 SkColorGetG(texel_color), | |
125 SkColorGetB(texel_color)); | |
126 SkPMColor pixel_stripe_color = | |
127 premultiplied_alpha | |
128 ? SkPreMultiplyColor(texel_stripe_color) | |
129 : SkPackARGB32NoCheck(SkColorGetA(texel_stripe_color), | |
130 SkColorGetR(texel_stripe_color), | |
131 SkColorGetG(texel_stripe_color), | |
132 SkColorGetB(texel_stripe_color)); | |
133 std::vector<uint32_t> pixels(rect.size().GetArea(), pixel_color); | |
134 for (int i = rect.height() / 4; i < (rect.height() * 3 / 4); ++i) { | |
135 for (int k = rect.width() / 4; k < (rect.width() * 3 / 4); ++k) { | |
136 pixels[i * rect.width() + k] = pixel_stripe_color; | |
137 } | |
138 } | |
139 ResourceProvider::ResourceId resource = resource_provider->CreateResource( | |
140 rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, | |
141 RGBA_8888); | |
142 resource_provider->SetPixels(resource, | |
143 reinterpret_cast<uint8_t*>(&pixels.front()), | |
144 rect, rect, gfx::Vector2d()); | |
145 | |
146 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; | |
147 const gfx::PointF uv_top_left(0.0f, 0.0f); | |
148 const gfx::PointF uv_bottom_right(1.0f, 1.0f); | |
149 const bool flipped = false; | |
150 const bool nearest_neighbor = false; | |
151 TextureDrawQuad* quad = | |
152 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); | |
153 quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource, | |
154 premultiplied_alpha, uv_top_left, uv_bottom_right, | |
155 background_color, vertex_opacity, flipped, nearest_neighbor); | |
156 } | |
157 | |
158 void CreateTestTextureDrawQuad(const gfx::Rect& rect, | |
159 SkColor texel_color, | |
160 SkColor background_color, | |
161 bool premultiplied_alpha, | |
162 const SharedQuadState* shared_state, | |
163 ResourceProvider* resource_provider, | |
164 RenderPass* render_pass) { | |
165 SkPMColor pixel_color = premultiplied_alpha ? | |
166 SkPreMultiplyColor(texel_color) : | |
167 SkPackARGB32NoCheck(SkColorGetA(texel_color), | |
168 SkColorGetR(texel_color), | |
169 SkColorGetG(texel_color), | |
170 SkColorGetB(texel_color)); | |
171 size_t num_pixels = static_cast<size_t>(rect.width()) * rect.height(); | |
172 std::vector<uint32_t> pixels(num_pixels, pixel_color); | |
173 | |
174 ResourceProvider::ResourceId resource = resource_provider->CreateResource( | |
175 rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, | |
176 RGBA_8888); | |
177 resource_provider->CopyToResource( | |
178 resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size()); | |
179 | |
180 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; | |
181 | |
182 const gfx::PointF uv_top_left(0.0f, 0.0f); | |
183 const gfx::PointF uv_bottom_right(1.0f, 1.0f); | |
184 const bool flipped = false; | |
185 const bool nearest_neighbor = false; | |
186 TextureDrawQuad* quad = | |
187 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); | |
188 quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource, | |
189 premultiplied_alpha, uv_top_left, uv_bottom_right, | |
190 background_color, vertex_opacity, flipped, nearest_neighbor); | |
191 } | |
192 | |
193 void CreateTestYUVVideoDrawQuad_FromVideoFrame( | |
194 const SharedQuadState* shared_state, | |
195 scoped_refptr<media::VideoFrame> video_frame, | |
196 uint8 alpha_value, | |
197 const gfx::RectF& tex_coord_rect, | |
198 RenderPass* render_pass, | |
199 VideoResourceUpdater* video_resource_updater, | |
200 const gfx::Rect& rect, | |
201 const gfx::Rect& visible_rect, | |
202 ResourceProvider* resource_provider) { | |
203 const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A); | |
204 const YUVVideoDrawQuad::ColorSpace color_space = | |
205 (video_frame->format() == media::VideoFrame::YV12J | |
206 ? YUVVideoDrawQuad::JPEG | |
207 : YUVVideoDrawQuad::REC_601); | |
208 const gfx::Rect opaque_rect(0, 0, 0, 0); | |
209 | |
210 if (with_alpha) { | |
211 memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value, | |
212 video_frame->stride(media::VideoFrame::kAPlane) * | |
213 video_frame->rows(media::VideoFrame::kAPlane)); | |
214 } | |
215 | |
216 VideoFrameExternalResources resources = | |
217 video_resource_updater->CreateExternalResourcesFromVideoFrame( | |
218 video_frame); | |
219 | |
220 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type); | |
221 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()), | |
222 resources.mailboxes.size()); | |
223 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()), | |
224 resources.release_callbacks.size()); | |
225 | |
226 ResourceProvider::ResourceId y_resource = | |
227 resource_provider->CreateResourceFromTextureMailbox( | |
228 resources.mailboxes[media::VideoFrame::kYPlane], | |
229 SingleReleaseCallbackImpl::Create( | |
230 resources.release_callbacks[media::VideoFrame::kYPlane])); | |
231 ResourceProvider::ResourceId u_resource = | |
232 resource_provider->CreateResourceFromTextureMailbox( | |
233 resources.mailboxes[media::VideoFrame::kUPlane], | |
234 SingleReleaseCallbackImpl::Create( | |
235 resources.release_callbacks[media::VideoFrame::kUPlane])); | |
236 ResourceProvider::ResourceId v_resource = | |
237 resource_provider->CreateResourceFromTextureMailbox( | |
238 resources.mailboxes[media::VideoFrame::kVPlane], | |
239 SingleReleaseCallbackImpl::Create( | |
240 resources.release_callbacks[media::VideoFrame::kVPlane])); | |
241 ResourceProvider::ResourceId a_resource = 0; | |
242 if (with_alpha) { | |
243 a_resource = resource_provider->CreateResourceFromTextureMailbox( | |
244 resources.mailboxes[media::VideoFrame::kAPlane], | |
245 SingleReleaseCallbackImpl::Create( | |
246 resources.release_callbacks[media::VideoFrame::kAPlane])); | |
247 } | |
248 | |
249 YUVVideoDrawQuad* yuv_quad = | |
250 render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>(); | |
251 yuv_quad->SetNew(shared_state, rect, opaque_rect, visible_rect, | |
252 tex_coord_rect, video_frame->coded_size(), y_resource, | |
253 u_resource, v_resource, a_resource, color_space); | |
254 } | |
255 | |
256 void CreateTestYUVVideoDrawQuad_Striped( | |
257 const SharedQuadState* shared_state, | |
258 media::VideoFrame::Format format, | |
259 bool is_transparent, | |
260 const gfx::RectF& tex_coord_rect, | |
261 RenderPass* render_pass, | |
262 VideoResourceUpdater* video_resource_updater, | |
263 const gfx::Rect& rect, | |
264 const gfx::Rect& visible_rect, | |
265 ResourceProvider* resource_provider) { | |
266 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame( | |
267 format, rect.size(), rect, rect.size(), base::TimeDelta()); | |
268 | |
269 // YUV values representing a striped pattern, for validating texture | |
270 // coordinates for sampling. | |
271 uint8_t y_value = 0; | |
272 uint8_t u_value = 0; | |
273 uint8_t v_value = 0; | |
274 for (int i = 0; i < video_frame->rows(media::VideoFrame::kYPlane); ++i) { | |
275 uint8_t* y_row = video_frame->data(media::VideoFrame::kYPlane) + | |
276 video_frame->stride(media::VideoFrame::kYPlane) * i; | |
277 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kYPlane); | |
278 ++j) { | |
279 y_row[j] = (y_value += 1); | |
280 } | |
281 } | |
282 for (int i = 0; i < video_frame->rows(media::VideoFrame::kUPlane); ++i) { | |
283 uint8_t* u_row = video_frame->data(media::VideoFrame::kUPlane) + | |
284 video_frame->stride(media::VideoFrame::kUPlane) * i; | |
285 uint8_t* v_row = video_frame->data(media::VideoFrame::kVPlane) + | |
286 video_frame->stride(media::VideoFrame::kVPlane) * i; | |
287 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kUPlane); | |
288 ++j) { | |
289 u_row[j] = (u_value += 3); | |
290 v_row[j] = (v_value += 5); | |
291 } | |
292 } | |
293 uint8 alpha_value = is_transparent ? 0 : 128; | |
294 CreateTestYUVVideoDrawQuad_FromVideoFrame( | |
295 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass, | |
296 video_resource_updater, rect, visible_rect, resource_provider); | |
297 } | |
298 | |
299 // Creates a video frame of size background_size filled with yuv_background, | |
300 // and then draws a foreground rectangle in a different color on top of | |
301 // that. The foreground rectangle must have coordinates that are divisible | |
302 // by 2 because YUV is a block format. | |
303 void CreateTestYUVVideoDrawQuad_TwoColor( | |
304 const SharedQuadState* shared_state, | |
305 media::VideoFrame::Format format, | |
306 bool is_transparent, | |
307 const gfx::RectF& tex_coord_rect, | |
308 const gfx::Size& background_size, | |
309 const gfx::Rect& visible_rect, | |
310 uint8 y_background, | |
311 uint8 u_background, | |
312 uint8 v_background, | |
313 const gfx::Rect& foreground_rect, | |
314 uint8 y_foreground, | |
315 uint8 u_foreground, | |
316 uint8 v_foreground, | |
317 RenderPass* render_pass, | |
318 VideoResourceUpdater* video_resource_updater, | |
319 ResourceProvider* resource_provider) { | |
320 const gfx::Rect rect(background_size); | |
321 | |
322 scoped_refptr<media::VideoFrame> video_frame = | |
323 media::VideoFrame::CreateFrame(format, background_size, foreground_rect, | |
324 foreground_rect.size(), base::TimeDelta()); | |
325 | |
326 int planes[] = {media::VideoFrame::kYPlane, | |
327 media::VideoFrame::kUPlane, | |
328 media::VideoFrame::kVPlane}; | |
329 uint8 yuv_background[] = {y_background, u_background, v_background}; | |
330 uint8 yuv_foreground[] = {y_foreground, u_foreground, v_foreground}; | |
331 int sample_size[] = {1, 2, 2}; | |
332 | |
333 for (int i = 0; i < 3; ++i) { | |
334 memset(video_frame->data(planes[i]), yuv_background[i], | |
335 video_frame->stride(planes[i]) * video_frame->rows(planes[i])); | |
336 } | |
337 | |
338 for (int i = 0; i < 3; ++i) { | |
339 // Since yuv encoding uses block encoding, widths have to be divisible | |
340 // by the sample size in order for this function to behave properly. | |
341 DCHECK_EQ(foreground_rect.x() % sample_size[i], 0); | |
342 DCHECK_EQ(foreground_rect.y() % sample_size[i], 0); | |
343 DCHECK_EQ(foreground_rect.width() % sample_size[i], 0); | |
344 DCHECK_EQ(foreground_rect.height() % sample_size[i], 0); | |
345 | |
346 gfx::Rect sample_rect(foreground_rect.x() / sample_size[i], | |
347 foreground_rect.y() / sample_size[i], | |
348 foreground_rect.width() / sample_size[i], | |
349 foreground_rect.height() / sample_size[i]); | |
350 for (int y = sample_rect.y(); y < sample_rect.bottom(); ++y) { | |
351 for (int x = sample_rect.x(); x < sample_rect.right(); ++x) { | |
352 size_t offset = y * video_frame->stride(planes[i]) + x; | |
353 video_frame->data(planes[i])[offset] = yuv_foreground[i]; | |
354 } | |
355 } | |
356 } | |
357 | |
358 uint8 alpha_value = 255; | |
359 CreateTestYUVVideoDrawQuad_FromVideoFrame( | |
360 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass, | |
361 video_resource_updater, rect, visible_rect, resource_provider); | |
362 } | |
363 | |
364 void CreateTestYUVVideoDrawQuad_Solid( | |
365 const SharedQuadState* shared_state, | |
366 media::VideoFrame::Format format, | |
367 bool is_transparent, | |
368 const gfx::RectF& tex_coord_rect, | |
369 uint8 y, | |
370 uint8 u, | |
371 uint8 v, | |
372 RenderPass* render_pass, | |
373 VideoResourceUpdater* video_resource_updater, | |
374 const gfx::Rect& rect, | |
375 const gfx::Rect& visible_rect, | |
376 ResourceProvider* resource_provider) { | |
377 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame( | |
378 format, rect.size(), rect, rect.size(), base::TimeDelta()); | |
379 | |
380 // YUV values of a solid, constant, color. Useful for testing that color | |
381 // space/color range are being handled properly. | |
382 memset(video_frame->data(media::VideoFrame::kYPlane), y, | |
383 video_frame->stride(media::VideoFrame::kYPlane) * | |
384 video_frame->rows(media::VideoFrame::kYPlane)); | |
385 memset(video_frame->data(media::VideoFrame::kUPlane), u, | |
386 video_frame->stride(media::VideoFrame::kUPlane) * | |
387 video_frame->rows(media::VideoFrame::kUPlane)); | |
388 memset(video_frame->data(media::VideoFrame::kVPlane), v, | |
389 video_frame->stride(media::VideoFrame::kVPlane) * | |
390 video_frame->rows(media::VideoFrame::kVPlane)); | |
391 | |
392 uint8 alpha_value = is_transparent ? 0 : 128; | |
393 CreateTestYUVVideoDrawQuad_FromVideoFrame( | |
394 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass, | |
395 video_resource_updater, rect, visible_rect, resource_provider); | |
396 } | |
397 | |
398 typedef ::testing::Types<GLRenderer, | |
399 SoftwareRenderer, | |
400 GLRendererWithExpandedViewport, | |
401 SoftwareRendererWithExpandedViewport> RendererTypes; | |
402 TYPED_TEST_CASE(RendererPixelTest, RendererTypes); | |
403 | |
404 template <typename RendererType> | |
405 class SoftwareRendererPixelTest : public RendererPixelTest<RendererType> {}; | |
406 | |
407 typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport> | |
408 SoftwareRendererTypes; | |
409 TYPED_TEST_CASE(SoftwareRendererPixelTest, SoftwareRendererTypes); | |
410 | |
411 template <typename RendererType> | |
412 class FuzzyForSoftwareOnlyPixelComparator : public PixelComparator { | |
413 public: | |
414 explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha) | |
415 : fuzzy_(discard_alpha), exact_(discard_alpha) {} | |
416 | |
417 bool Compare(const SkBitmap& actual_bmp, | |
418 const SkBitmap& expected_bmp) const override; | |
419 | |
420 private: | |
421 FuzzyPixelOffByOneComparator fuzzy_; | |
422 ExactPixelComparator exact_; | |
423 }; | |
424 | |
425 template<> | |
426 bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare( | |
427 const SkBitmap& actual_bmp, | |
428 const SkBitmap& expected_bmp) const { | |
429 return fuzzy_.Compare(actual_bmp, expected_bmp); | |
430 } | |
431 | |
432 template <> | |
433 bool FuzzyForSoftwareOnlyPixelComparator< | |
434 SoftwareRendererWithExpandedViewport>::Compare( | |
435 const SkBitmap& actual_bmp, | |
436 const SkBitmap& expected_bmp) const { | |
437 return fuzzy_.Compare(actual_bmp, expected_bmp); | |
438 } | |
439 | |
440 template<typename RendererType> | |
441 bool FuzzyForSoftwareOnlyPixelComparator<RendererType>::Compare( | |
442 const SkBitmap& actual_bmp, | |
443 const SkBitmap& expected_bmp) const { | |
444 return exact_.Compare(actual_bmp, expected_bmp); | |
445 } | |
446 | |
447 TYPED_TEST(RendererPixelTest, SimpleGreenRect) { | |
448 gfx::Rect rect(this->device_viewport_size_); | |
449 | |
450 RenderPassId id(1, 1); | |
451 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | |
452 | |
453 SharedQuadState* shared_state = | |
454 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | |
455 | |
456 SolidColorDrawQuad* color_quad = | |
457 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
458 color_quad->SetNew(shared_state, rect, rect, SK_ColorGREEN, false); | |
459 | |
460 RenderPassList pass_list; | |
461 pass_list.push_back(pass.Pass()); | |
462 | |
463 EXPECT_TRUE(this->RunPixelTest( | |
464 &pass_list, | |
465 base::FilePath(FILE_PATH_LITERAL("green.png")), | |
466 ExactPixelComparator(true))); | |
467 } | |
468 | |
469 TYPED_TEST(RendererPixelTest, SimpleGreenRect_NonRootRenderPass) { | |
470 gfx::Rect rect(this->device_viewport_size_); | |
471 gfx::Rect small_rect(100, 100); | |
472 | |
473 RenderPassId child_id(2, 1); | |
474 scoped_ptr<RenderPass> child_pass = | |
475 CreateTestRenderPass(child_id, small_rect, gfx::Transform()); | |
476 | |
477 SharedQuadState* child_shared_state = | |
478 CreateTestSharedQuadState(gfx::Transform(), small_rect, child_pass.get()); | |
479 | |
480 SolidColorDrawQuad* color_quad = | |
481 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
482 color_quad->SetNew(child_shared_state, rect, rect, SK_ColorGREEN, false); | |
483 | |
484 RenderPassId root_id(1, 1); | |
485 scoped_ptr<RenderPass> root_pass = | |
486 CreateTestRenderPass(root_id, rect, gfx::Transform()); | |
487 | |
488 SharedQuadState* root_shared_state = | |
489 CreateTestSharedQuadState(gfx::Transform(), rect, root_pass.get()); | |
490 | |
491 CreateTestRenderPassDrawQuad( | |
492 root_shared_state, small_rect, child_id, root_pass.get()); | |
493 | |
494 RenderPass* child_pass_ptr = child_pass.get(); | |
495 | |
496 RenderPassList pass_list; | |
497 pass_list.push_back(child_pass.Pass()); | |
498 pass_list.push_back(root_pass.Pass()); | |
499 | |
500 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget( | |
501 &pass_list, | |
502 child_pass_ptr, | |
503 base::FilePath(FILE_PATH_LITERAL("green_small.png")), | |
504 ExactPixelComparator(true))); | |
505 } | |
506 | |
507 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithoutBackground) { | |
508 gfx::Rect rect(this->device_viewport_size_); | |
509 | |
510 RenderPassId id(1, 1); | |
511 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | |
512 | |
513 SharedQuadState* shared_state = | |
514 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | |
515 | |
516 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_), | |
517 SkColorSetARGB(128, 0, 255, 0), // Texel color. | |
518 SK_ColorTRANSPARENT, // Background color. | |
519 true, // Premultiplied alpha. | |
520 shared_state, | |
521 this->resource_provider_.get(), | |
522 pass.get()); | |
523 | |
524 SolidColorDrawQuad* color_quad = | |
525 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
526 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false); | |
527 | |
528 RenderPassList pass_list; | |
529 pass_list.push_back(pass.Pass()); | |
530 | |
531 EXPECT_TRUE(this->RunPixelTest( | |
532 &pass_list, | |
533 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), | |
534 FuzzyPixelOffByOneComparator(true))); | |
535 } | |
536 | |
537 TYPED_TEST(RendererPixelTest, PremultipliedTextureWithBackground) { | |
538 gfx::Rect rect(this->device_viewport_size_); | |
539 | |
540 RenderPassId id(1, 1); | |
541 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | |
542 | |
543 SharedQuadState* texture_quad_state = | |
544 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | |
545 texture_quad_state->opacity = 0.8f; | |
546 | |
547 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_), | |
548 SkColorSetARGB(204, 120, 255, 120), // Texel color. | |
549 SK_ColorGREEN, // Background color. | |
550 true, // Premultiplied alpha. | |
551 texture_quad_state, | |
552 this->resource_provider_.get(), | |
553 pass.get()); | |
554 | |
555 SharedQuadState* color_quad_state = | |
556 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | |
557 SolidColorDrawQuad* color_quad = | |
558 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
559 color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false); | |
560 | |
561 RenderPassList pass_list; | |
562 pass_list.push_back(pass.Pass()); | |
563 | |
564 EXPECT_TRUE(this->RunPixelTest( | |
565 &pass_list, | |
566 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), | |
567 FuzzyPixelOffByOneComparator(true))); | |
568 } | |
569 | |
570 template <typename QuadType> | |
571 static const base::FilePath::CharType* IntersectingQuadImage() { | |
572 return FILE_PATH_LITERAL("intersecting_blue_green_squares.png"); | |
573 } | |
574 template <> | |
575 const base::FilePath::CharType* IntersectingQuadImage<SolidColorDrawQuad>() { | |
576 return FILE_PATH_LITERAL("intersecting_blue_green.png"); | |
577 } | |
578 template <> | |
579 const base::FilePath::CharType* IntersectingQuadImage<YUVVideoDrawQuad>() { | |
580 return FILE_PATH_LITERAL("intersecting_blue_green_squares_video.png"); | |
581 } | |
582 | |
583 template <typename TypeParam> | |
584 class IntersectingQuadPixelTest : public RendererPixelTest<TypeParam> { | |
585 protected: | |
586 void SetupQuadStateAndRenderPass() { | |
587 // This sets up a pair of draw quads. They are both rotated | |
588 // relative to the root plane, they are also rotated relative to each other. | |
589 // The intersect in the middle at a non-perpendicular angle so that any | |
590 // errors are hopefully magnified. | |
591 // The quads should intersect correctly, as in the front quad should only | |
592 // be partially in front of the back quad, and partially behind. | |
593 | |
594 viewport_rect_ = gfx::Rect(this->device_viewport_size_); | |
595 quad_rect_ = gfx::Rect(0, 0, this->device_viewport_size_.width(), | |
596 this->device_viewport_size_.height() / 2.0); | |
597 | |
598 RenderPassId id(1, 1); | |
599 render_pass_ = CreateTestRootRenderPass(id, viewport_rect_); | |
600 | |
601 // Create the front quad rotated on the Z and Y axis. | |
602 gfx::Transform trans; | |
603 trans.Translate3d(0, 0, 0.707 * this->device_viewport_size_.width() / 2.0); | |
604 trans.RotateAboutZAxis(45.0); | |
605 trans.RotateAboutYAxis(45.0); | |
606 front_quad_state_ = | |
607 CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get()); | |
608 front_quad_state_->clip_rect = quad_rect_; | |
609 // Make sure they end up in a 3d sorting context. | |
610 front_quad_state_->sorting_context_id = 1; | |
611 | |
612 // Create the back quad, and rotate on just the y axis. This will intersect | |
613 // the first quad partially. | |
614 trans = gfx::Transform(); | |
615 trans.Translate3d(0, 0, -0.707 * this->device_viewport_size_.width() / 2.0); | |
616 trans.RotateAboutYAxis(-45.0); | |
617 back_quad_state_ = | |
618 CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get()); | |
619 back_quad_state_->sorting_context_id = 1; | |
620 back_quad_state_->clip_rect = quad_rect_; | |
621 } | |
622 template <typename T> | |
623 void AppendBackgroundAndRunTest(const PixelComparator& comparator) { | |
624 SharedQuadState* background_quad_state = CreateTestSharedQuadState( | |
625 gfx::Transform(), viewport_rect_, render_pass_.get()); | |
626 SolidColorDrawQuad* background_quad = | |
627 render_pass_->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
628 background_quad->SetNew(background_quad_state, viewport_rect_, | |
629 viewport_rect_, SK_ColorWHITE, false); | |
630 pass_list_.push_back(render_pass_.Pass()); | |
631 const base::FilePath::CharType* fileName = IntersectingQuadImage<T>(); | |
632 EXPECT_TRUE( | |
633 this->RunPixelTest(&pass_list_, base::FilePath(fileName), comparator)); | |
634 } | |
635 template <typename T> | |
636 T* CreateAndAppendDrawQuad() { | |
637 return render_pass_->CreateAndAppendDrawQuad<T>(); | |
638 } | |
639 | |
640 scoped_ptr<RenderPass> render_pass_; | |
641 gfx::Rect viewport_rect_; | |
642 SharedQuadState* front_quad_state_; | |
643 SharedQuadState* back_quad_state_; | |
644 gfx::Rect quad_rect_; | |
645 RenderPassList pass_list_; | |
646 }; | |
647 | |
648 template <typename TypeParam> | |
649 class IntersectingQuadGLPixelTest | |
650 : public IntersectingQuadPixelTest<TypeParam> { | |
651 public: | |
652 void SetUp() override { | |
653 IntersectingQuadPixelTest<TypeParam>::SetUp(); | |
654 video_resource_updater_.reset( | |
655 new VideoResourceUpdater(this->output_surface_->context_provider(), | |
656 this->resource_provider_.get())); | |
657 video_resource_updater2_.reset( | |
658 new VideoResourceUpdater(this->output_surface_->context_provider(), | |
659 this->resource_provider_.get())); | |
660 } | |
661 | |
662 protected: | |
663 scoped_ptr<VideoResourceUpdater> video_resource_updater_; | |
664 scoped_ptr<VideoResourceUpdater> video_resource_updater2_; | |
665 }; | |
666 | |
667 template <typename TypeParam> | |
668 class IntersectingQuadSoftwareTest | |
669 : public IntersectingQuadPixelTest<TypeParam> {}; | |
670 | |
671 typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport> | |
672 SoftwareRendererTypes; | |
673 typedef ::testing::Types<GLRenderer, GLRendererWithExpandedViewport> | |
674 GLRendererTypes; | |
675 | |
676 TYPED_TEST_CASE(IntersectingQuadPixelTest, RendererTypes); | |
677 TYPED_TEST_CASE(IntersectingQuadGLPixelTest, GLRendererTypes); | |
678 TYPED_TEST_CASE(IntersectingQuadSoftwareTest, SoftwareRendererTypes); | |
679 | |
680 TYPED_TEST(IntersectingQuadPixelTest, SolidColorQuads) { | |
681 this->SetupQuadStateAndRenderPass(); | |
682 | |
683 SolidColorDrawQuad* quad = | |
684 this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
685 SolidColorDrawQuad* quad2 = | |
686 this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
687 | |
688 quad->SetNew(this->front_quad_state_, this->quad_rect_, this->quad_rect_, | |
689 SK_ColorBLUE, false); | |
690 quad2->SetNew(this->back_quad_state_, this->quad_rect_, this->quad_rect_, | |
691 SK_ColorGREEN, false); | |
692 SCOPED_TRACE("IntersectingSolidColorQuads"); | |
693 this->template AppendBackgroundAndRunTest<SolidColorDrawQuad>( | |
694 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)); | |
695 } | |
696 | |
697 template <typename TypeParam> | |
698 SkColor GetColor(const SkColor& color) { | |
699 return color; | |
700 } | |
701 | |
702 template <> | |
703 SkColor GetColor<GLRenderer>(const SkColor& color) { | |
704 return SkColorSetARGB(SkColorGetA(color), SkColorGetB(color), | |
705 SkColorGetG(color), SkColorGetR(color)); | |
706 } | |
707 template <> | |
708 SkColor GetColor<GLRendererWithExpandedViewport>(const SkColor& color) { | |
709 return GetColor<GLRenderer>(color); | |
710 } | |
711 | |
712 TYPED_TEST(IntersectingQuadPixelTest, TexturedQuads) { | |
713 this->SetupQuadStateAndRenderPass(); | |
714 CreateTestTwoColoredTextureDrawQuad( | |
715 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), | |
716 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT, | |
717 true, this->front_quad_state_, this->resource_provider_.get(), | |
718 this->render_pass_.get()); | |
719 CreateTestTwoColoredTextureDrawQuad( | |
720 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)), | |
721 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT, | |
722 true, this->back_quad_state_, this->resource_provider_.get(), | |
723 this->render_pass_.get()); | |
724 | |
725 SCOPED_TRACE("IntersectingTexturedQuads"); | |
726 this->template AppendBackgroundAndRunTest<TextureDrawQuad>( | |
727 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)); | |
728 } | |
729 | |
730 TYPED_TEST(IntersectingQuadSoftwareTest, PictureQuads) { | |
731 this->SetupQuadStateAndRenderPass(); | |
732 gfx::RectF outer_rect(this->quad_rect_); | |
733 gfx::RectF inner_rect(this->quad_rect_.x() + (this->quad_rect_.width() / 4), | |
734 this->quad_rect_.y() + (this->quad_rect_.height() / 4), | |
735 this->quad_rect_.width() / 2, | |
736 this->quad_rect_.height() / 2); | |
737 | |
738 SkPaint black_paint; | |
739 black_paint.setColor(SK_ColorBLACK); | |
740 SkPaint blue_paint; | |
741 blue_paint.setColor(SK_ColorBLUE); | |
742 SkPaint green_paint; | |
743 green_paint.setColor(SK_ColorGREEN); | |
744 | |
745 scoped_ptr<FakePicturePile> blue_recording = | |
746 FakePicturePile::CreateFilledPile(gfx::Size(1000, 1000), | |
747 this->quad_rect_.size()); | |
748 blue_recording->add_draw_rect_with_paint(outer_rect, black_paint); | |
749 blue_recording->add_draw_rect_with_paint(inner_rect, blue_paint); | |
750 blue_recording->RerecordPile(); | |
751 scoped_refptr<FakePicturePileImpl> blue_pile = | |
752 FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr); | |
753 | |
754 PictureDrawQuad* blue_quad = | |
755 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>(); | |
756 | |
757 blue_quad->SetNew(this->front_quad_state_, this->quad_rect_, gfx::Rect(), | |
758 this->quad_rect_, this->quad_rect_, this->quad_rect_.size(), | |
759 false, RGBA_8888, this->quad_rect_, 1.f, blue_pile); | |
760 | |
761 scoped_ptr<FakePicturePile> green_recording = | |
762 FakePicturePile::CreateFilledPile(this->quad_rect_.size(), | |
763 this->quad_rect_.size()); | |
764 green_recording->add_draw_rect_with_paint(outer_rect, green_paint); | |
765 green_recording->add_draw_rect_with_paint(inner_rect, black_paint); | |
766 green_recording->RerecordPile(); | |
767 scoped_refptr<FakePicturePileImpl> green_pile = | |
768 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr); | |
769 | |
770 PictureDrawQuad* green_quad = | |
771 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>(); | |
772 green_quad->SetNew(this->back_quad_state_, this->quad_rect_, gfx::Rect(), | |
773 this->quad_rect_, this->quad_rect_, | |
774 this->quad_rect_.size(), false, RGBA_8888, | |
775 this->quad_rect_, 1.f, green_pile); | |
776 SCOPED_TRACE("IntersectingPictureQuadsPass"); | |
777 this->template AppendBackgroundAndRunTest<PictureDrawQuad>( | |
778 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)); | |
779 } | |
780 | |
781 TYPED_TEST(IntersectingQuadPixelTest, RenderPassQuads) { | |
782 this->SetupQuadStateAndRenderPass(); | |
783 RenderPassId child_pass_id1(2, 2); | |
784 RenderPassId child_pass_id2(2, 3); | |
785 scoped_ptr<RenderPass> child_pass1 = | |
786 CreateTestRenderPass(child_pass_id1, this->quad_rect_, gfx::Transform()); | |
787 SharedQuadState* child1_quad_state = CreateTestSharedQuadState( | |
788 gfx::Transform(), this->quad_rect_, child_pass1.get()); | |
789 scoped_ptr<RenderPass> child_pass2 = | |
790 CreateTestRenderPass(child_pass_id2, this->quad_rect_, gfx::Transform()); | |
791 SharedQuadState* child2_quad_state = CreateTestSharedQuadState( | |
792 gfx::Transform(), this->quad_rect_, child_pass2.get()); | |
793 | |
794 CreateTestTwoColoredTextureDrawQuad( | |
795 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), | |
796 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT, | |
797 true, child1_quad_state, this->resource_provider_.get(), | |
798 child_pass1.get()); | |
799 CreateTestTwoColoredTextureDrawQuad( | |
800 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)), | |
801 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT, | |
802 true, child2_quad_state, this->resource_provider_.get(), | |
803 child_pass2.get()); | |
804 | |
805 CreateTestRenderPassDrawQuad(this->front_quad_state_, this->quad_rect_, | |
806 child_pass_id1, this->render_pass_.get()); | |
807 CreateTestRenderPassDrawQuad(this->back_quad_state_, this->quad_rect_, | |
808 child_pass_id2, this->render_pass_.get()); | |
809 | |
810 this->pass_list_.push_back(child_pass1.Pass()); | |
811 this->pass_list_.push_back(child_pass2.Pass()); | |
812 SCOPED_TRACE("IntersectingRenderQuadsPass"); | |
813 this->template AppendBackgroundAndRunTest<RenderPassDrawQuad>( | |
814 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)); | |
815 } | |
816 | |
817 TYPED_TEST(IntersectingQuadGLPixelTest, YUVVideoQuads) { | |
818 this->SetupQuadStateAndRenderPass(); | |
819 gfx::Rect inner_rect( | |
820 ((this->quad_rect_.x() + (this->quad_rect_.width() / 4)) & ~0xF), | |
821 ((this->quad_rect_.y() + (this->quad_rect_.height() / 4)) & ~0xF), | |
822 (this->quad_rect_.width() / 2) & ~0xF, | |
823 (this->quad_rect_.height() / 2) & ~0xF); | |
824 | |
825 CreateTestYUVVideoDrawQuad_TwoColor( | |
826 this->front_quad_state_, media::VideoFrame::YV12J, false, | |
827 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(), | |
828 this->quad_rect_, 0, 128, 128, inner_rect, 29, 255, 107, | |
829 this->render_pass_.get(), this->video_resource_updater_.get(), | |
830 this->resource_provider_.get()); | |
831 | |
832 CreateTestYUVVideoDrawQuad_TwoColor( | |
833 this->back_quad_state_, media::VideoFrame::YV12J, false, | |
834 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(), | |
835 this->quad_rect_, 149, 43, 21, inner_rect, 0, 128, 128, | |
836 this->render_pass_.get(), this->video_resource_updater2_.get(), | |
837 this->resource_provider_.get()); | |
838 | |
839 SCOPED_TRACE("IntersectingVideoQuads"); | |
840 this->template AppendBackgroundAndRunTest<YUVVideoDrawQuad>( | |
841 FuzzyPixelOffByOneComparator(false)); | |
842 } | |
843 | |
844 // TODO(skaslev): The software renderer does not support non-premultplied alpha. | |
845 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) { | |
846 gfx::Rect rect(this->device_viewport_size_); | |
847 | |
848 RenderPassId id(1, 1); | |
849 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | |
850 | |
851 SharedQuadState* shared_state = | |
852 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | |
853 | |
854 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_), | |
855 SkColorSetARGB(128, 0, 255, 0), // Texel color. | |
856 SK_ColorTRANSPARENT, // Background color. | |
857 false, // Premultiplied alpha. | |
858 shared_state, | |
859 this->resource_provider_.get(), | |
860 pass.get()); | |
861 | |
862 SolidColorDrawQuad* color_quad = | |
863 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
864 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false); | |
865 | |
866 RenderPassList pass_list; | |
867 pass_list.push_back(pass.Pass()); | |
868 | |
869 EXPECT_TRUE(this->RunPixelTest( | |
870 &pass_list, | |
871 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), | |
872 FuzzyPixelOffByOneComparator(true))); | |
873 } | |
874 | |
875 // TODO(skaslev): The software renderer does not support non-premultplied alpha. | |
876 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) { | |
877 gfx::Rect rect(this->device_viewport_size_); | |
878 | |
879 RenderPassId id(1, 1); | |
880 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | |
881 | |
882 SharedQuadState* texture_quad_state = | |
883 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | |
884 texture_quad_state->opacity = 0.8f; | |
885 | |
886 CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_), | |
887 SkColorSetARGB(204, 120, 255, 120), // Texel color. | |
888 SK_ColorGREEN, // Background color. | |
889 false, // Premultiplied alpha. | |
890 texture_quad_state, | |
891 this->resource_provider_.get(), | |
892 pass.get()); | |
893 | |
894 SharedQuadState* color_quad_state = | |
895 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | |
896 SolidColorDrawQuad* color_quad = | |
897 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
898 color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false); | |
899 | |
900 RenderPassList pass_list; | |
901 pass_list.push_back(pass.Pass()); | |
902 | |
903 EXPECT_TRUE(this->RunPixelTest( | |
904 &pass_list, | |
905 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), | |
906 FuzzyPixelOffByOneComparator(true))); | |
907 } | |
908 | |
909 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) { | |
910 gfx::Rect viewport_rect(this->device_viewport_size_); | |
911 | |
912 RenderPassId root_pass_id(1, 1); | |
913 scoped_ptr<RenderPass> root_pass = | |
914 CreateTestRootRenderPass(root_pass_id, viewport_rect); | |
915 | |
916 RenderPassId child_pass_id(2, 2); | |
917 gfx::Rect pass_rect(this->device_viewport_size_); | |
918 gfx::Transform transform_to_root; | |
919 scoped_ptr<RenderPass> child_pass = | |
920 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | |
921 | |
922 gfx::Transform content_to_target_transform; | |
923 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
924 content_to_target_transform, viewport_rect, child_pass.get()); | |
925 shared_state->opacity = 0.5f; | |
926 | |
927 gfx::Rect blue_rect(0, | |
928 0, | |
929 this->device_viewport_size_.width(), | |
930 this->device_viewport_size_.height() / 2); | |
931 SolidColorDrawQuad* blue = | |
932 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
933 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | |
934 gfx::Rect yellow_rect(0, | |
935 this->device_viewport_size_.height() / 2, | |
936 this->device_viewport_size_.width(), | |
937 this->device_viewport_size_.height() / 2); | |
938 SolidColorDrawQuad* yellow = | |
939 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
940 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | |
941 | |
942 SharedQuadState* blank_state = CreateTestSharedQuadState( | |
943 content_to_target_transform, viewport_rect, child_pass.get()); | |
944 | |
945 SolidColorDrawQuad* white = | |
946 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
947 white->SetNew( | |
948 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false); | |
949 | |
950 SharedQuadState* pass_shared_state = | |
951 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | |
952 | |
953 SkScalar matrix[20]; | |
954 float amount = 0.5f; | |
955 matrix[0] = 0.213f + 0.787f * amount; | |
956 matrix[1] = 0.715f - 0.715f * amount; | |
957 matrix[2] = 1.f - (matrix[0] + matrix[1]); | |
958 matrix[3] = matrix[4] = 0; | |
959 matrix[5] = 0.213f - 0.213f * amount; | |
960 matrix[6] = 0.715f + 0.285f * amount; | |
961 matrix[7] = 1.f - (matrix[5] + matrix[6]); | |
962 matrix[8] = matrix[9] = 0; | |
963 matrix[10] = 0.213f - 0.213f * amount; | |
964 matrix[11] = 0.715f - 0.715f * amount; | |
965 matrix[12] = 1.f - (matrix[10] + matrix[11]); | |
966 matrix[13] = matrix[14] = 0; | |
967 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0; | |
968 matrix[18] = 1; | |
969 skia::RefPtr<SkColorFilter> colorFilter( | |
970 skia::AdoptRef(SkColorMatrixFilter::Create(matrix))); | |
971 skia::RefPtr<SkImageFilter> filter = | |
972 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL)); | |
973 FilterOperations filters; | |
974 filters.Append(FilterOperation::CreateReferenceFilter(filter)); | |
975 | |
976 RenderPassDrawQuad* render_pass_quad = | |
977 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | |
978 render_pass_quad->SetNew(pass_shared_state, | |
979 pass_rect, | |
980 pass_rect, | |
981 child_pass_id, | |
982 0, | |
983 gfx::Vector2dF(), | |
984 gfx::Size(), | |
985 filters, | |
986 gfx::Vector2dF(), | |
987 FilterOperations()); | |
988 | |
989 RenderPassList pass_list; | |
990 pass_list.push_back(child_pass.Pass()); | |
991 pass_list.push_back(root_pass.Pass()); | |
992 | |
993 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl | |
994 // renderer so use a fuzzy comparator. | |
995 EXPECT_TRUE(this->RunPixelTest( | |
996 &pass_list, | |
997 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")), | |
998 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false))); | |
999 } | |
1000 | |
1001 TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) { | |
1002 gfx::Rect viewport_rect(this->device_viewport_size_); | |
1003 | |
1004 RenderPassId root_pass_id(1, 1); | |
1005 scoped_ptr<RenderPass> root_pass = | |
1006 CreateTestRootRenderPass(root_pass_id, viewport_rect); | |
1007 | |
1008 RenderPassId child_pass_id(2, 2); | |
1009 gfx::Rect pass_rect(this->device_viewport_size_); | |
1010 gfx::Transform transform_to_root; | |
1011 scoped_ptr<RenderPass> child_pass = | |
1012 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | |
1013 | |
1014 gfx::Transform content_to_target_transform; | |
1015 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
1016 content_to_target_transform, viewport_rect, child_pass.get()); | |
1017 shared_state->opacity = 0.5f; | |
1018 | |
1019 gfx::Rect blue_rect(0, | |
1020 0, | |
1021 this->device_viewport_size_.width(), | |
1022 this->device_viewport_size_.height() / 2); | |
1023 SolidColorDrawQuad* blue = | |
1024 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1025 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | |
1026 gfx::Rect yellow_rect(0, | |
1027 this->device_viewport_size_.height() / 2, | |
1028 this->device_viewport_size_.width(), | |
1029 this->device_viewport_size_.height() / 2); | |
1030 SolidColorDrawQuad* yellow = | |
1031 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1032 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | |
1033 | |
1034 SharedQuadState* blank_state = CreateTestSharedQuadState( | |
1035 content_to_target_transform, viewport_rect, child_pass.get()); | |
1036 | |
1037 SolidColorDrawQuad* white = | |
1038 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1039 white->SetNew( | |
1040 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false); | |
1041 | |
1042 SharedQuadState* pass_shared_state = | |
1043 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | |
1044 | |
1045 FilterOperations filters; | |
1046 filters.Append(FilterOperation::CreateSaturateFilter(0.5f)); | |
1047 | |
1048 RenderPassDrawQuad* render_pass_quad = | |
1049 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | |
1050 render_pass_quad->SetNew(pass_shared_state, | |
1051 pass_rect, | |
1052 pass_rect, | |
1053 child_pass_id, | |
1054 0, | |
1055 gfx::Vector2dF(), | |
1056 gfx::Size(), | |
1057 filters, | |
1058 gfx::Vector2dF(), | |
1059 FilterOperations()); | |
1060 | |
1061 RenderPassList pass_list; | |
1062 pass_list.push_back(child_pass.Pass()); | |
1063 pass_list.push_back(root_pass.Pass()); | |
1064 | |
1065 EXPECT_TRUE(this->RunPixelTest( | |
1066 &pass_list, | |
1067 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")), | |
1068 ExactPixelComparator(true))); | |
1069 } | |
1070 | |
1071 TYPED_TEST(RendererPixelTest, FastPassFilterChain) { | |
1072 gfx::Rect viewport_rect(this->device_viewport_size_); | |
1073 | |
1074 RenderPassId root_pass_id(1, 1); | |
1075 scoped_ptr<RenderPass> root_pass = | |
1076 CreateTestRootRenderPass(root_pass_id, viewport_rect); | |
1077 | |
1078 RenderPassId child_pass_id(2, 2); | |
1079 gfx::Rect pass_rect(this->device_viewport_size_); | |
1080 gfx::Transform transform_to_root; | |
1081 scoped_ptr<RenderPass> child_pass = | |
1082 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | |
1083 | |
1084 gfx::Transform content_to_target_transform; | |
1085 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
1086 content_to_target_transform, viewport_rect, child_pass.get()); | |
1087 shared_state->opacity = 0.5f; | |
1088 | |
1089 gfx::Rect blue_rect(0, | |
1090 0, | |
1091 this->device_viewport_size_.width(), | |
1092 this->device_viewport_size_.height() / 2); | |
1093 SolidColorDrawQuad* blue = | |
1094 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1095 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | |
1096 gfx::Rect yellow_rect(0, | |
1097 this->device_viewport_size_.height() / 2, | |
1098 this->device_viewport_size_.width(), | |
1099 this->device_viewport_size_.height() / 2); | |
1100 SolidColorDrawQuad* yellow = | |
1101 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1102 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | |
1103 | |
1104 SharedQuadState* blank_state = CreateTestSharedQuadState( | |
1105 content_to_target_transform, viewport_rect, child_pass.get()); | |
1106 | |
1107 SolidColorDrawQuad* white = | |
1108 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1109 white->SetNew( | |
1110 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false); | |
1111 | |
1112 SharedQuadState* pass_shared_state = | |
1113 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | |
1114 | |
1115 FilterOperations filters; | |
1116 filters.Append(FilterOperation::CreateGrayscaleFilter(1.f)); | |
1117 filters.Append(FilterOperation::CreateBrightnessFilter(0.5f)); | |
1118 | |
1119 RenderPassDrawQuad* render_pass_quad = | |
1120 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | |
1121 render_pass_quad->SetNew(pass_shared_state, | |
1122 pass_rect, | |
1123 pass_rect, | |
1124 child_pass_id, | |
1125 0, | |
1126 gfx::Vector2dF(), | |
1127 gfx::Size(), | |
1128 filters, | |
1129 gfx::Vector2dF(), | |
1130 FilterOperations()); | |
1131 | |
1132 RenderPassList pass_list; | |
1133 pass_list.push_back(child_pass.Pass()); | |
1134 pass_list.push_back(root_pass.Pass()); | |
1135 | |
1136 EXPECT_TRUE(this->RunPixelTest( | |
1137 &pass_list, | |
1138 base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")), | |
1139 ExactPixelComparator(true))); | |
1140 } | |
1141 | |
1142 TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) { | |
1143 gfx::Rect viewport_rect(this->device_viewport_size_); | |
1144 | |
1145 RenderPassId root_pass_id(1, 1); | |
1146 scoped_ptr<RenderPass> root_pass = | |
1147 CreateTestRootRenderPass(root_pass_id, viewport_rect); | |
1148 | |
1149 RenderPassId child_pass_id(2, 2); | |
1150 gfx::Rect pass_rect(this->device_viewport_size_); | |
1151 gfx::Transform transform_to_root; | |
1152 scoped_ptr<RenderPass> child_pass = | |
1153 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | |
1154 | |
1155 gfx::Transform content_to_target_transform; | |
1156 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
1157 content_to_target_transform, viewport_rect, child_pass.get()); | |
1158 shared_state->opacity = 0.5f; | |
1159 | |
1160 gfx::Rect blue_rect(0, | |
1161 0, | |
1162 this->device_viewport_size_.width(), | |
1163 this->device_viewport_size_.height() / 2); | |
1164 SolidColorDrawQuad* blue = | |
1165 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1166 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | |
1167 gfx::Rect yellow_rect(0, | |
1168 this->device_viewport_size_.height() / 2, | |
1169 this->device_viewport_size_.width(), | |
1170 this->device_viewport_size_.height() / 2); | |
1171 SolidColorDrawQuad* yellow = | |
1172 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1173 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | |
1174 | |
1175 SharedQuadState* blank_state = CreateTestSharedQuadState( | |
1176 content_to_target_transform, viewport_rect, child_pass.get()); | |
1177 | |
1178 SolidColorDrawQuad* white = | |
1179 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1180 white->SetNew( | |
1181 blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false); | |
1182 | |
1183 SharedQuadState* pass_shared_state = | |
1184 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | |
1185 | |
1186 SkScalar matrix[20]; | |
1187 float amount = 0.5f; | |
1188 matrix[0] = 0.213f + 0.787f * amount; | |
1189 matrix[1] = 0.715f - 0.715f * amount; | |
1190 matrix[2] = 1.f - (matrix[0] + matrix[1]); | |
1191 matrix[3] = 0; | |
1192 matrix[4] = 20.f; | |
1193 matrix[5] = 0.213f - 0.213f * amount; | |
1194 matrix[6] = 0.715f + 0.285f * amount; | |
1195 matrix[7] = 1.f - (matrix[5] + matrix[6]); | |
1196 matrix[8] = 0; | |
1197 matrix[9] = 200.f; | |
1198 matrix[10] = 0.213f - 0.213f * amount; | |
1199 matrix[11] = 0.715f - 0.715f * amount; | |
1200 matrix[12] = 1.f - (matrix[10] + matrix[11]); | |
1201 matrix[13] = 0; | |
1202 matrix[14] = 1.5f; | |
1203 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0; | |
1204 matrix[18] = 1; | |
1205 skia::RefPtr<SkColorFilter> colorFilter( | |
1206 skia::AdoptRef(SkColorMatrixFilter::Create(matrix))); | |
1207 skia::RefPtr<SkImageFilter> filter = | |
1208 skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL)); | |
1209 FilterOperations filters; | |
1210 filters.Append(FilterOperation::CreateReferenceFilter(filter)); | |
1211 | |
1212 RenderPassDrawQuad* render_pass_quad = | |
1213 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | |
1214 render_pass_quad->SetNew(pass_shared_state, | |
1215 pass_rect, | |
1216 pass_rect, | |
1217 child_pass_id, | |
1218 0, | |
1219 gfx::Vector2dF(), | |
1220 gfx::Size(), | |
1221 filters, | |
1222 gfx::Vector2dF(), | |
1223 FilterOperations()); | |
1224 | |
1225 RenderPassList pass_list; | |
1226 | |
1227 pass_list.push_back(child_pass.Pass()); | |
1228 pass_list.push_back(root_pass.Pass()); | |
1229 | |
1230 // This test has alpha=254 for the software renderer vs. alpha=255 for the gl | |
1231 // renderer so use a fuzzy comparator. | |
1232 EXPECT_TRUE(this->RunPixelTest( | |
1233 &pass_list, | |
1234 base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")), | |
1235 FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false))); | |
1236 } | |
1237 | |
1238 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) { | |
1239 gfx::Rect viewport_rect(this->device_viewport_size_); | |
1240 | |
1241 RenderPassId root_pass_id(1, 1); | |
1242 scoped_ptr<RenderPass> root_pass = | |
1243 CreateTestRootRenderPass(root_pass_id, viewport_rect); | |
1244 | |
1245 RenderPassId child_pass_id(2, 2); | |
1246 gfx::Rect pass_rect(this->device_viewport_size_); | |
1247 gfx::Transform transform_to_root; | |
1248 scoped_ptr<RenderPass> child_pass = | |
1249 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | |
1250 | |
1251 gfx::Transform content_to_target_transform; | |
1252 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
1253 content_to_target_transform, viewport_rect, child_pass.get()); | |
1254 | |
1255 gfx::Rect blue_rect(0, | |
1256 0, | |
1257 this->device_viewport_size_.width(), | |
1258 this->device_viewport_size_.height() / 2); | |
1259 SolidColorDrawQuad* blue = | |
1260 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1261 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | |
1262 gfx::Rect yellow_rect(0, | |
1263 this->device_viewport_size_.height() / 2, | |
1264 this->device_viewport_size_.width(), | |
1265 this->device_viewport_size_.height() / 2); | |
1266 SolidColorDrawQuad* yellow = | |
1267 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1268 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | |
1269 | |
1270 SharedQuadState* pass_shared_state = | |
1271 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | |
1272 CreateTestRenderPassDrawQuad( | |
1273 pass_shared_state, pass_rect, child_pass_id, root_pass.get()); | |
1274 | |
1275 RenderPassList pass_list; | |
1276 pass_list.push_back(child_pass.Pass()); | |
1277 pass_list.push_back(root_pass.Pass()); | |
1278 | |
1279 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75)); | |
1280 | |
1281 EXPECT_TRUE(this->RunPixelTest( | |
1282 &pass_list, | |
1283 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")), | |
1284 ExactPixelComparator(true))); | |
1285 } | |
1286 | |
1287 TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) { | |
1288 gfx::Rect viewport_rect(this->device_viewport_size_); | |
1289 | |
1290 RenderPassId root_pass_id(1, 1); | |
1291 scoped_ptr<RenderPass> root_pass = | |
1292 CreateTestRootRenderPass(root_pass_id, viewport_rect); | |
1293 | |
1294 RenderPassId child_pass_id(2, 2); | |
1295 gfx::Rect pass_rect(this->device_viewport_size_); | |
1296 gfx::Transform transform_to_root; | |
1297 scoped_ptr<RenderPass> child_pass = | |
1298 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | |
1299 | |
1300 gfx::Transform content_to_target_transform; | |
1301 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
1302 content_to_target_transform, viewport_rect, child_pass.get()); | |
1303 | |
1304 gfx::Rect blue_rect(0, | |
1305 0, | |
1306 this->device_viewport_size_.width(), | |
1307 this->device_viewport_size_.height() / 2); | |
1308 SolidColorDrawQuad* blue = | |
1309 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1310 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | |
1311 gfx::Rect yellow_rect(0, | |
1312 this->device_viewport_size_.height() / 2, | |
1313 this->device_viewport_size_.width(), | |
1314 this->device_viewport_size_.height() / 2); | |
1315 SolidColorDrawQuad* yellow = | |
1316 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1317 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | |
1318 | |
1319 gfx::Transform aa_transform; | |
1320 aa_transform.Translate(0.5, 0.0); | |
1321 | |
1322 SharedQuadState* pass_shared_state = | |
1323 CreateTestSharedQuadState(aa_transform, pass_rect, root_pass.get()); | |
1324 CreateTestRenderPassDrawQuad( | |
1325 pass_shared_state, pass_rect, child_pass_id, root_pass.get()); | |
1326 | |
1327 SharedQuadState* root_shared_state = CreateTestSharedQuadState( | |
1328 gfx::Transform(), viewport_rect, root_pass.get()); | |
1329 SolidColorDrawQuad* background = | |
1330 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1331 background->SetNew(root_shared_state, | |
1332 gfx::Rect(this->device_viewport_size_), | |
1333 gfx::Rect(this->device_viewport_size_), | |
1334 SK_ColorWHITE, | |
1335 false); | |
1336 | |
1337 RenderPassList pass_list; | |
1338 pass_list.push_back(child_pass.Pass()); | |
1339 pass_list.push_back(root_pass.Pass()); | |
1340 | |
1341 this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75)); | |
1342 | |
1343 EXPECT_TRUE(this->RunPixelTest( | |
1344 &pass_list, | |
1345 base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")), | |
1346 FuzzyPixelOffByOneComparator(true))); | |
1347 } | |
1348 | |
1349 // This tests the case where we have a RenderPass with a mask, but the quad | |
1350 // for the masked surface does not include the full surface texture. | |
1351 TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) { | |
1352 gfx::Rect viewport_rect(this->device_viewport_size_); | |
1353 | |
1354 RenderPassId root_pass_id(1, 1); | |
1355 scoped_ptr<RenderPass> root_pass = | |
1356 CreateTestRootRenderPass(root_pass_id, viewport_rect); | |
1357 SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState( | |
1358 gfx::Transform(), viewport_rect, root_pass.get()); | |
1359 | |
1360 RenderPassId child_pass_id(2, 2); | |
1361 gfx::Transform transform_to_root; | |
1362 scoped_ptr<RenderPass> child_pass = | |
1363 CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root); | |
1364 SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState( | |
1365 gfx::Transform(), viewport_rect, child_pass.get()); | |
1366 | |
1367 // The child render pass is just a green box. | |
1368 static const SkColor kCSSGreen = 0xff008000; | |
1369 SolidColorDrawQuad* green = | |
1370 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1371 green->SetNew( | |
1372 child_pass_shared_state, viewport_rect, viewport_rect, kCSSGreen, false); | |
1373 | |
1374 // Make a mask. | |
1375 gfx::Rect mask_rect = viewport_rect; | |
1376 SkBitmap bitmap; | |
1377 bitmap.allocPixels( | |
1378 SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height())); | |
1379 SkCanvas canvas(bitmap); | |
1380 SkPaint paint; | |
1381 paint.setStyle(SkPaint::kStroke_Style); | |
1382 paint.setStrokeWidth(SkIntToScalar(4)); | |
1383 paint.setColor(SK_ColorWHITE); | |
1384 canvas.clear(SK_ColorTRANSPARENT); | |
1385 gfx::Rect rect = mask_rect; | |
1386 while (!rect.IsEmpty()) { | |
1387 rect.Inset(6, 6, 4, 4); | |
1388 canvas.drawRect( | |
1389 SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()), | |
1390 paint); | |
1391 rect.Inset(6, 6, 4, 4); | |
1392 } | |
1393 | |
1394 ResourceProvider::ResourceId mask_resource_id = | |
1395 this->resource_provider_->CreateResource( | |
1396 mask_rect.size(), GL_CLAMP_TO_EDGE, | |
1397 ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); | |
1398 { | |
1399 SkAutoLockPixels lock(bitmap); | |
1400 this->resource_provider_->CopyToResource( | |
1401 mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()), | |
1402 mask_rect.size()); | |
1403 } | |
1404 | |
1405 // This RenderPassDrawQuad does not include the full |viewport_rect| which is | |
1406 // the size of the child render pass. | |
1407 gfx::Rect sub_rect = gfx::Rect(50, 50, 200, 100); | |
1408 EXPECT_NE(sub_rect.x(), child_pass->output_rect.x()); | |
1409 EXPECT_NE(sub_rect.y(), child_pass->output_rect.y()); | |
1410 EXPECT_NE(sub_rect.right(), child_pass->output_rect.right()); | |
1411 EXPECT_NE(sub_rect.bottom(), child_pass->output_rect.bottom()); | |
1412 | |
1413 // Set up a mask on the RenderPassDrawQuad. | |
1414 RenderPassDrawQuad* mask_quad = | |
1415 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | |
1416 mask_quad->SetNew(root_pass_shared_state, | |
1417 sub_rect, | |
1418 sub_rect, | |
1419 child_pass_id, | |
1420 mask_resource_id, | |
1421 gfx::Vector2dF(2.f, 1.f), // mask_uv_scale | |
1422 gfx::Size(mask_rect.size()), // mask_texture_size | |
1423 FilterOperations(), // foreground filters | |
1424 gfx::Vector2dF(), // filters scale | |
1425 FilterOperations()); // background filters | |
1426 | |
1427 // White background behind the masked render pass. | |
1428 SolidColorDrawQuad* white = | |
1429 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1430 white->SetNew(root_pass_shared_state, | |
1431 viewport_rect, | |
1432 viewport_rect, | |
1433 SK_ColorWHITE, | |
1434 false); | |
1435 | |
1436 RenderPassList pass_list; | |
1437 pass_list.push_back(child_pass.Pass()); | |
1438 pass_list.push_back(root_pass.Pass()); | |
1439 | |
1440 EXPECT_TRUE(this->RunPixelTest( | |
1441 &pass_list, | |
1442 base::FilePath(FILE_PATH_LITERAL("mask_bottom_right.png")), | |
1443 ExactPixelComparator(true))); | |
1444 } | |
1445 | |
1446 template <typename RendererType> | |
1447 class RendererPixelTestWithBackgroundFilter | |
1448 : public RendererPixelTest<RendererType> { | |
1449 protected: | |
1450 void SetUpRenderPassList() { | |
1451 gfx::Rect device_viewport_rect(this->device_viewport_size_); | |
1452 | |
1453 RenderPassId root_id(1, 1); | |
1454 scoped_ptr<RenderPass> root_pass = | |
1455 CreateTestRootRenderPass(root_id, device_viewport_rect); | |
1456 root_pass->has_transparent_background = false; | |
1457 | |
1458 gfx::Transform identity_content_to_target_transform; | |
1459 | |
1460 RenderPassId filter_pass_id(2, 1); | |
1461 gfx::Transform transform_to_root; | |
1462 scoped_ptr<RenderPass> filter_pass = | |
1463 CreateTestRenderPass(filter_pass_id, | |
1464 filter_pass_content_rect_, | |
1465 transform_to_root); | |
1466 | |
1467 // A non-visible quad in the filtering render pass. | |
1468 { | |
1469 SharedQuadState* shared_state = | |
1470 CreateTestSharedQuadState(identity_content_to_target_transform, | |
1471 filter_pass_content_rect_, | |
1472 filter_pass.get()); | |
1473 SolidColorDrawQuad* color_quad = | |
1474 filter_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1475 color_quad->SetNew(shared_state, | |
1476 filter_pass_content_rect_, | |
1477 filter_pass_content_rect_, | |
1478 SK_ColorTRANSPARENT, | |
1479 false); | |
1480 } | |
1481 | |
1482 { | |
1483 SharedQuadState* shared_state = | |
1484 CreateTestSharedQuadState(filter_pass_to_target_transform_, | |
1485 filter_pass_content_rect_, | |
1486 filter_pass.get()); | |
1487 RenderPassDrawQuad* filter_pass_quad = | |
1488 root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); | |
1489 filter_pass_quad->SetNew(shared_state, | |
1490 filter_pass_content_rect_, | |
1491 filter_pass_content_rect_, | |
1492 filter_pass_id, | |
1493 0, // mask_resource_id | |
1494 gfx::Vector2dF(), // mask_uv_scale | |
1495 gfx::Size(), // mask_texture_size | |
1496 FilterOperations(), // filters | |
1497 gfx::Vector2dF(), // filters_scale | |
1498 this->background_filters_); | |
1499 } | |
1500 | |
1501 const int kColumnWidth = device_viewport_rect.width() / 3; | |
1502 | |
1503 gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20); | |
1504 for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) { | |
1505 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
1506 identity_content_to_target_transform, left_rect, root_pass.get()); | |
1507 SolidColorDrawQuad* color_quad = | |
1508 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1509 color_quad->SetNew( | |
1510 shared_state, left_rect, left_rect, SK_ColorGREEN, false); | |
1511 left_rect += gfx::Vector2d(0, left_rect.height() + 1); | |
1512 } | |
1513 | |
1514 gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20); | |
1515 for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) { | |
1516 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
1517 identity_content_to_target_transform, middle_rect, root_pass.get()); | |
1518 SolidColorDrawQuad* color_quad = | |
1519 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1520 color_quad->SetNew( | |
1521 shared_state, middle_rect, middle_rect, SK_ColorRED, false); | |
1522 middle_rect += gfx::Vector2d(0, middle_rect.height() + 1); | |
1523 } | |
1524 | |
1525 gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20); | |
1526 for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) { | |
1527 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
1528 identity_content_to_target_transform, right_rect, root_pass.get()); | |
1529 SolidColorDrawQuad* color_quad = | |
1530 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1531 color_quad->SetNew( | |
1532 shared_state, right_rect, right_rect, SK_ColorBLUE, false); | |
1533 right_rect += gfx::Vector2d(0, right_rect.height() + 1); | |
1534 } | |
1535 | |
1536 SharedQuadState* shared_state = | |
1537 CreateTestSharedQuadState(identity_content_to_target_transform, | |
1538 device_viewport_rect, | |
1539 root_pass.get()); | |
1540 SolidColorDrawQuad* background_quad = | |
1541 root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1542 background_quad->SetNew(shared_state, | |
1543 device_viewport_rect, | |
1544 device_viewport_rect, | |
1545 SK_ColorWHITE, | |
1546 false); | |
1547 | |
1548 pass_list_.push_back(filter_pass.Pass()); | |
1549 pass_list_.push_back(root_pass.Pass()); | |
1550 } | |
1551 | |
1552 RenderPassList pass_list_; | |
1553 FilterOperations background_filters_; | |
1554 gfx::Transform filter_pass_to_target_transform_; | |
1555 gfx::Rect filter_pass_content_rect_; | |
1556 }; | |
1557 | |
1558 typedef ::testing::Types<GLRenderer, SoftwareRenderer> | |
1559 BackgroundFilterRendererTypes; | |
1560 TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter, | |
1561 BackgroundFilterRendererTypes); | |
1562 | |
1563 typedef RendererPixelTestWithBackgroundFilter<GLRenderer> | |
1564 GLRendererPixelTestWithBackgroundFilter; | |
1565 | |
1566 // TODO(skaslev): The software renderer does not support filters yet. | |
1567 TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) { | |
1568 this->background_filters_.Append( | |
1569 FilterOperation::CreateInvertFilter(1.f)); | |
1570 | |
1571 this->filter_pass_content_rect_ = gfx::Rect(this->device_viewport_size_); | |
1572 this->filter_pass_content_rect_.Inset(12, 14, 16, 18); | |
1573 | |
1574 this->SetUpRenderPassList(); | |
1575 EXPECT_TRUE(this->RunPixelTest( | |
1576 &this->pass_list_, | |
1577 base::FilePath(FILE_PATH_LITERAL("background_filter.png")), | |
1578 ExactPixelComparator(true))); | |
1579 } | |
1580 | |
1581 class ExternalStencilPixelTest : public GLRendererPixelTest { | |
1582 protected: | |
1583 void ClearBackgroundToGreen() { | |
1584 GLES2Interface* gl = output_surface_->context_provider()->ContextGL(); | |
1585 output_surface_->EnsureBackbuffer(); | |
1586 output_surface_->Reshape(device_viewport_size_, 1); | |
1587 gl->ClearColor(0.f, 1.f, 0.f, 1.f); | |
1588 gl->Clear(GL_COLOR_BUFFER_BIT); | |
1589 } | |
1590 | |
1591 void PopulateStencilBuffer() { | |
1592 // Set two quadrants of the stencil buffer to 1. | |
1593 GLES2Interface* gl = output_surface_->context_provider()->ContextGL(); | |
1594 output_surface_->EnsureBackbuffer(); | |
1595 output_surface_->Reshape(device_viewport_size_, 1); | |
1596 gl->ClearStencil(0); | |
1597 gl->Clear(GL_STENCIL_BUFFER_BIT); | |
1598 gl->Enable(GL_SCISSOR_TEST); | |
1599 gl->ClearStencil(1); | |
1600 gl->Scissor(0, | |
1601 0, | |
1602 device_viewport_size_.width() / 2, | |
1603 device_viewport_size_.height() / 2); | |
1604 gl->Clear(GL_STENCIL_BUFFER_BIT); | |
1605 gl->Scissor(device_viewport_size_.width() / 2, | |
1606 device_viewport_size_.height() / 2, | |
1607 device_viewport_size_.width(), | |
1608 device_viewport_size_.height()); | |
1609 gl->Clear(GL_STENCIL_BUFFER_BIT); | |
1610 } | |
1611 }; | |
1612 | |
1613 TEST_F(ExternalStencilPixelTest, StencilTestEnabled) { | |
1614 ClearBackgroundToGreen(); | |
1615 PopulateStencilBuffer(); | |
1616 this->EnableExternalStencilTest(); | |
1617 | |
1618 // Draw a blue quad that covers the entire device viewport. It should be | |
1619 // clipped to the bottom left and top right corners by the external stencil. | |
1620 gfx::Rect rect(this->device_viewport_size_); | |
1621 RenderPassId id(1, 1); | |
1622 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | |
1623 SharedQuadState* blue_shared_state = | |
1624 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | |
1625 SolidColorDrawQuad* blue = | |
1626 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1627 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false); | |
1628 pass->has_transparent_background = false; | |
1629 RenderPassList pass_list; | |
1630 pass_list.push_back(pass.Pass()); | |
1631 | |
1632 EXPECT_TRUE(this->RunPixelTest( | |
1633 &pass_list, | |
1634 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), | |
1635 ExactPixelComparator(true))); | |
1636 } | |
1637 | |
1638 TEST_F(ExternalStencilPixelTest, StencilTestDisabled) { | |
1639 PopulateStencilBuffer(); | |
1640 | |
1641 // Draw a green quad that covers the entire device viewport. The stencil | |
1642 // buffer should be ignored. | |
1643 gfx::Rect rect(this->device_viewport_size_); | |
1644 RenderPassId id(1, 1); | |
1645 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | |
1646 SharedQuadState* green_shared_state = | |
1647 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | |
1648 SolidColorDrawQuad* green = | |
1649 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1650 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false); | |
1651 RenderPassList pass_list; | |
1652 pass_list.push_back(pass.Pass()); | |
1653 | |
1654 EXPECT_TRUE(this->RunPixelTest( | |
1655 &pass_list, | |
1656 base::FilePath(FILE_PATH_LITERAL("green.png")), | |
1657 ExactPixelComparator(true))); | |
1658 } | |
1659 | |
1660 TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) { | |
1661 // The stencil test should apply only to the final render pass. | |
1662 ClearBackgroundToGreen(); | |
1663 PopulateStencilBuffer(); | |
1664 this->EnableExternalStencilTest(); | |
1665 | |
1666 gfx::Rect viewport_rect(this->device_viewport_size_); | |
1667 | |
1668 RenderPassId root_pass_id(1, 1); | |
1669 scoped_ptr<RenderPass> root_pass = | |
1670 CreateTestRootRenderPass(root_pass_id, viewport_rect); | |
1671 root_pass->has_transparent_background = false; | |
1672 | |
1673 RenderPassId child_pass_id(2, 2); | |
1674 gfx::Rect pass_rect(this->device_viewport_size_); | |
1675 gfx::Transform transform_to_root; | |
1676 scoped_ptr<RenderPass> child_pass = | |
1677 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | |
1678 | |
1679 gfx::Transform content_to_target_transform; | |
1680 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
1681 content_to_target_transform, viewport_rect, child_pass.get()); | |
1682 | |
1683 gfx::Rect blue_rect(0, | |
1684 0, | |
1685 this->device_viewport_size_.width(), | |
1686 this->device_viewport_size_.height()); | |
1687 SolidColorDrawQuad* blue = | |
1688 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1689 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | |
1690 | |
1691 SharedQuadState* pass_shared_state = | |
1692 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | |
1693 CreateTestRenderPassDrawQuad( | |
1694 pass_shared_state, pass_rect, child_pass_id, root_pass.get()); | |
1695 RenderPassList pass_list; | |
1696 pass_list.push_back(child_pass.Pass()); | |
1697 pass_list.push_back(root_pass.Pass()); | |
1698 | |
1699 EXPECT_TRUE(this->RunPixelTest( | |
1700 &pass_list, | |
1701 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), | |
1702 ExactPixelComparator(true))); | |
1703 } | |
1704 | |
1705 TEST_F(ExternalStencilPixelTest, DeviceClip) { | |
1706 ClearBackgroundToGreen(); | |
1707 gfx::Rect clip_rect(gfx::Point(150, 150), gfx::Size(50, 50)); | |
1708 this->ForceDeviceClip(clip_rect); | |
1709 | |
1710 // Draw a blue quad that covers the entire device viewport. It should be | |
1711 // clipped to the bottom right corner by the device clip. | |
1712 gfx::Rect rect(this->device_viewport_size_); | |
1713 RenderPassId id(1, 1); | |
1714 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | |
1715 SharedQuadState* blue_shared_state = | |
1716 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | |
1717 SolidColorDrawQuad* blue = | |
1718 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1719 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false); | |
1720 RenderPassList pass_list; | |
1721 pass_list.push_back(pass.Pass()); | |
1722 | |
1723 EXPECT_TRUE(this->RunPixelTest( | |
1724 &pass_list, | |
1725 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")), | |
1726 ExactPixelComparator(true))); | |
1727 } | |
1728 | |
1729 // Software renderer does not support anti-aliased edges. | |
1730 TEST_F(GLRendererPixelTest, AntiAliasing) { | |
1731 gfx::Rect rect(this->device_viewport_size_); | |
1732 | |
1733 RenderPassId id(1, 1); | |
1734 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | |
1735 | |
1736 gfx::Transform red_content_to_target_transform; | |
1737 red_content_to_target_transform.Rotate(10); | |
1738 SharedQuadState* red_shared_state = CreateTestSharedQuadState( | |
1739 red_content_to_target_transform, rect, pass.get()); | |
1740 | |
1741 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1742 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false); | |
1743 | |
1744 gfx::Transform yellow_content_to_target_transform; | |
1745 yellow_content_to_target_transform.Rotate(5); | |
1746 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState( | |
1747 yellow_content_to_target_transform, rect, pass.get()); | |
1748 | |
1749 SolidColorDrawQuad* yellow = | |
1750 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1751 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false); | |
1752 | |
1753 gfx::Transform blue_content_to_target_transform; | |
1754 SharedQuadState* blue_shared_state = CreateTestSharedQuadState( | |
1755 blue_content_to_target_transform, rect, pass.get()); | |
1756 | |
1757 SolidColorDrawQuad* blue = | |
1758 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1759 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false); | |
1760 | |
1761 RenderPassList pass_list; | |
1762 pass_list.push_back(pass.Pass()); | |
1763 | |
1764 EXPECT_TRUE(this->RunPixelTest( | |
1765 &pass_list, | |
1766 base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")), | |
1767 FuzzyPixelOffByOneComparator(true))); | |
1768 } | |
1769 | |
1770 // This test tests that anti-aliasing works for axis aligned quads. | |
1771 // Anti-aliasing is only supported in the gl renderer. | |
1772 TEST_F(GLRendererPixelTest, AxisAligned) { | |
1773 gfx::Rect rect(this->device_viewport_size_); | |
1774 | |
1775 RenderPassId id(1, 1); | |
1776 gfx::Transform transform_to_root; | |
1777 scoped_ptr<RenderPass> pass = | |
1778 CreateTestRenderPass(id, rect, transform_to_root); | |
1779 | |
1780 gfx::Transform red_content_to_target_transform; | |
1781 red_content_to_target_transform.Translate(50, 50); | |
1782 red_content_to_target_transform.Scale( | |
1783 0.5f + 1.0f / (rect.width() * 2.0f), | |
1784 0.5f + 1.0f / (rect.height() * 2.0f)); | |
1785 SharedQuadState* red_shared_state = CreateTestSharedQuadState( | |
1786 red_content_to_target_transform, rect, pass.get()); | |
1787 | |
1788 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1789 red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false); | |
1790 | |
1791 gfx::Transform yellow_content_to_target_transform; | |
1792 yellow_content_to_target_transform.Translate(25.5f, 25.5f); | |
1793 yellow_content_to_target_transform.Scale(0.5f, 0.5f); | |
1794 SharedQuadState* yellow_shared_state = CreateTestSharedQuadState( | |
1795 yellow_content_to_target_transform, rect, pass.get()); | |
1796 | |
1797 SolidColorDrawQuad* yellow = | |
1798 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1799 yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false); | |
1800 | |
1801 gfx::Transform blue_content_to_target_transform; | |
1802 SharedQuadState* blue_shared_state = CreateTestSharedQuadState( | |
1803 blue_content_to_target_transform, rect, pass.get()); | |
1804 | |
1805 SolidColorDrawQuad* blue = | |
1806 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1807 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false); | |
1808 | |
1809 RenderPassList pass_list; | |
1810 pass_list.push_back(pass.Pass()); | |
1811 | |
1812 EXPECT_TRUE(this->RunPixelTest( | |
1813 &pass_list, | |
1814 base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")), | |
1815 ExactPixelComparator(true))); | |
1816 } | |
1817 | |
1818 // This test tests that forcing anti-aliasing off works as expected. | |
1819 // Anti-aliasing is only supported in the gl renderer. | |
1820 TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) { | |
1821 gfx::Rect rect(this->device_viewport_size_); | |
1822 | |
1823 RenderPassId id(1, 1); | |
1824 gfx::Transform transform_to_root; | |
1825 scoped_ptr<RenderPass> pass = | |
1826 CreateTestRenderPass(id, rect, transform_to_root); | |
1827 | |
1828 gfx::Transform hole_content_to_target_transform; | |
1829 hole_content_to_target_transform.Translate(50, 50); | |
1830 hole_content_to_target_transform.Scale( | |
1831 0.5f + 1.0f / (rect.width() * 2.0f), | |
1832 0.5f + 1.0f / (rect.height() * 2.0f)); | |
1833 SharedQuadState* hole_shared_state = CreateTestSharedQuadState( | |
1834 hole_content_to_target_transform, rect, pass.get()); | |
1835 | |
1836 SolidColorDrawQuad* hole = | |
1837 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1838 hole->SetAll( | |
1839 hole_shared_state, rect, rect, rect, false, SK_ColorTRANSPARENT, true); | |
1840 | |
1841 gfx::Transform green_content_to_target_transform; | |
1842 SharedQuadState* green_shared_state = CreateTestSharedQuadState( | |
1843 green_content_to_target_transform, rect, pass.get()); | |
1844 | |
1845 SolidColorDrawQuad* green = | |
1846 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1847 green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false); | |
1848 | |
1849 RenderPassList pass_list; | |
1850 pass_list.push_back(pass.Pass()); | |
1851 | |
1852 EXPECT_TRUE(this->RunPixelTest( | |
1853 &pass_list, | |
1854 base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")), | |
1855 ExactPixelComparator(false))); | |
1856 } | |
1857 | |
1858 TEST_F(GLRendererPixelTest, AntiAliasingPerspective) { | |
1859 gfx::Rect rect(this->device_viewport_size_); | |
1860 | |
1861 scoped_ptr<RenderPass> pass = | |
1862 CreateTestRootRenderPass(RenderPassId(1, 1), rect); | |
1863 | |
1864 gfx::Rect red_rect(0, 0, 180, 500); | |
1865 gfx::Transform red_content_to_target_transform( | |
1866 1.0f, 2.4520f, 10.6206f, 19.0f, | |
1867 0.0f, 0.3528f, 5.9737f, 9.5f, | |
1868 0.0f, -0.2250f, -0.9744f, 0.0f, | |
1869 0.0f, 0.0225f, 0.0974f, 1.0f); | |
1870 SharedQuadState* red_shared_state = CreateTestSharedQuadState( | |
1871 red_content_to_target_transform, red_rect, pass.get()); | |
1872 SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1873 red->SetNew(red_shared_state, red_rect, red_rect, SK_ColorRED, false); | |
1874 | |
1875 gfx::Rect green_rect(19, 7, 180, 10); | |
1876 SharedQuadState* green_shared_state = | |
1877 CreateTestSharedQuadState(gfx::Transform(), green_rect, pass.get()); | |
1878 SolidColorDrawQuad* green = | |
1879 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1880 green->SetNew( | |
1881 green_shared_state, green_rect, green_rect, SK_ColorGREEN, false); | |
1882 | |
1883 SharedQuadState* blue_shared_state = | |
1884 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | |
1885 SolidColorDrawQuad* blue = | |
1886 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
1887 blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false); | |
1888 | |
1889 RenderPassList pass_list; | |
1890 pass_list.push_back(pass.Pass()); | |
1891 | |
1892 EXPECT_TRUE(this->RunPixelTest( | |
1893 &pass_list, | |
1894 base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")), | |
1895 FuzzyPixelOffByOneComparator(true))); | |
1896 } | |
1897 | |
1898 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadIdentityScale) { | |
1899 gfx::Size pile_tile_size(1000, 1000); | |
1900 gfx::Rect viewport(this->device_viewport_size_); | |
1901 // TODO(enne): the renderer should figure this out on its own. | |
1902 ResourceFormat texture_format = RGBA_8888; | |
1903 bool nearest_neighbor = false; | |
1904 | |
1905 RenderPassId id(1, 1); | |
1906 gfx::Transform transform_to_root; | |
1907 scoped_ptr<RenderPass> pass = | |
1908 CreateTestRenderPass(id, viewport, transform_to_root); | |
1909 | |
1910 // One clipped blue quad in the lower right corner. Outside the clip | |
1911 // is red, which should not appear. | |
1912 gfx::Rect blue_rect(gfx::Size(100, 100)); | |
1913 gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50)); | |
1914 | |
1915 scoped_ptr<FakePicturePile> blue_recording = | |
1916 FakePicturePile::CreateFilledPile(pile_tile_size, blue_rect.size()); | |
1917 SkPaint red_paint; | |
1918 red_paint.setColor(SK_ColorRED); | |
1919 blue_recording->add_draw_rect_with_paint(blue_rect, red_paint); | |
1920 SkPaint blue_paint; | |
1921 blue_paint.setColor(SK_ColorBLUE); | |
1922 blue_recording->add_draw_rect_with_paint(blue_clip_rect, blue_paint); | |
1923 blue_recording->RerecordPile(); | |
1924 | |
1925 scoped_refptr<FakePicturePileImpl> blue_pile = | |
1926 FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr); | |
1927 | |
1928 gfx::Transform blue_content_to_target_transform; | |
1929 gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right()); | |
1930 blue_content_to_target_transform.Translate(offset.x(), offset.y()); | |
1931 gfx::RectF blue_scissor_rect = blue_clip_rect; | |
1932 blue_content_to_target_transform.TransformRect(&blue_scissor_rect); | |
1933 SharedQuadState* blue_shared_state = | |
1934 CreateTestSharedQuadStateClipped(blue_content_to_target_transform, | |
1935 blue_rect, | |
1936 gfx::ToEnclosingRect(blue_scissor_rect), | |
1937 pass.get()); | |
1938 | |
1939 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | |
1940 | |
1941 blue_quad->SetNew(blue_shared_state, | |
1942 viewport, // Intentionally bigger than clip. | |
1943 gfx::Rect(), viewport, gfx::RectF(viewport), | |
1944 viewport.size(), nearest_neighbor, texture_format, viewport, | |
1945 1.f, blue_pile.get()); | |
1946 | |
1947 // One viewport-filling green quad. | |
1948 scoped_ptr<FakePicturePile> green_recording = | |
1949 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size()); | |
1950 SkPaint green_paint; | |
1951 green_paint.setColor(SK_ColorGREEN); | |
1952 green_recording->add_draw_rect_with_paint(viewport, green_paint); | |
1953 green_recording->RerecordPile(); | |
1954 scoped_refptr<FakePicturePileImpl> green_pile = | |
1955 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr); | |
1956 | |
1957 gfx::Transform green_content_to_target_transform; | |
1958 SharedQuadState* green_shared_state = CreateTestSharedQuadState( | |
1959 green_content_to_target_transform, viewport, pass.get()); | |
1960 | |
1961 PictureDrawQuad* green_quad = | |
1962 pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | |
1963 green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport, | |
1964 gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(), | |
1965 nearest_neighbor, texture_format, viewport, 1.f, | |
1966 green_pile.get()); | |
1967 | |
1968 RenderPassList pass_list; | |
1969 pass_list.push_back(pass.Pass()); | |
1970 | |
1971 EXPECT_TRUE(this->RunPixelTest( | |
1972 &pass_list, | |
1973 base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")), | |
1974 ExactPixelComparator(true))); | |
1975 } | |
1976 | |
1977 // Not WithSkiaGPUBackend since that path currently requires tiles for opacity. | |
1978 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadOpacity) { | |
1979 gfx::Size pile_tile_size(1000, 1000); | |
1980 gfx::Rect viewport(this->device_viewport_size_); | |
1981 ResourceFormat texture_format = RGBA_8888; | |
1982 bool nearest_neighbor = false; | |
1983 | |
1984 RenderPassId id(1, 1); | |
1985 gfx::Transform transform_to_root; | |
1986 scoped_ptr<RenderPass> pass = | |
1987 CreateTestRenderPass(id, viewport, transform_to_root); | |
1988 | |
1989 // One viewport-filling 0.5-opacity green quad. | |
1990 scoped_ptr<FakePicturePile> green_recording = | |
1991 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size()); | |
1992 SkPaint green_paint; | |
1993 green_paint.setColor(SK_ColorGREEN); | |
1994 green_recording->add_draw_rect_with_paint(viewport, green_paint); | |
1995 green_recording->RerecordPile(); | |
1996 scoped_refptr<FakePicturePileImpl> green_pile = | |
1997 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr); | |
1998 | |
1999 gfx::Transform green_content_to_target_transform; | |
2000 SharedQuadState* green_shared_state = CreateTestSharedQuadState( | |
2001 green_content_to_target_transform, viewport, pass.get()); | |
2002 green_shared_state->opacity = 0.5f; | |
2003 | |
2004 PictureDrawQuad* green_quad = | |
2005 pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | |
2006 green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport, | |
2007 gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor, | |
2008 texture_format, viewport, 1.f, green_pile.get()); | |
2009 | |
2010 // One viewport-filling white quad. | |
2011 scoped_ptr<FakePicturePile> white_recording = | |
2012 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size()); | |
2013 SkPaint white_paint; | |
2014 white_paint.setColor(SK_ColorWHITE); | |
2015 white_recording->add_draw_rect_with_paint(viewport, white_paint); | |
2016 white_recording->RerecordPile(); | |
2017 scoped_refptr<FakePicturePileImpl> white_pile = | |
2018 FakePicturePileImpl::CreateFromPile(white_recording.get(), nullptr); | |
2019 | |
2020 gfx::Transform white_content_to_target_transform; | |
2021 SharedQuadState* white_shared_state = CreateTestSharedQuadState( | |
2022 white_content_to_target_transform, viewport, pass.get()); | |
2023 | |
2024 PictureDrawQuad* white_quad = | |
2025 pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | |
2026 white_quad->SetNew(white_shared_state, viewport, gfx::Rect(), viewport, | |
2027 gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor, | |
2028 texture_format, viewport, 1.f, white_pile.get()); | |
2029 | |
2030 RenderPassList pass_list; | |
2031 pass_list.push_back(pass.Pass()); | |
2032 | |
2033 EXPECT_TRUE(this->RunPixelTest( | |
2034 &pass_list, | |
2035 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), | |
2036 FuzzyPixelOffByOneComparator(true))); | |
2037 } | |
2038 | |
2039 template<typename TypeParam> bool IsSoftwareRenderer() { | |
2040 return false; | |
2041 } | |
2042 | |
2043 template<> | |
2044 bool IsSoftwareRenderer<SoftwareRenderer>() { | |
2045 return true; | |
2046 } | |
2047 | |
2048 template<> | |
2049 bool IsSoftwareRenderer<SoftwareRendererWithExpandedViewport>() { | |
2050 return true; | |
2051 } | |
2052 | |
2053 // If we disable image filtering, then a 2x2 bitmap should appear as four | |
2054 // huge sharp squares. | |
2055 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadDisableImageFiltering) { | |
2056 // We only care about this in software mode since bilinear filtering is | |
2057 // cheap in hardware. | |
2058 if (!IsSoftwareRenderer<TypeParam>()) | |
2059 return; | |
2060 | |
2061 gfx::Size pile_tile_size(1000, 1000); | |
2062 gfx::Rect viewport(this->device_viewport_size_); | |
2063 ResourceFormat texture_format = RGBA_8888; | |
2064 bool nearest_neighbor = false; | |
2065 | |
2066 RenderPassId id(1, 1); | |
2067 gfx::Transform transform_to_root; | |
2068 scoped_ptr<RenderPass> pass = | |
2069 CreateTestRenderPass(id, viewport, transform_to_root); | |
2070 | |
2071 SkBitmap bitmap; | |
2072 bitmap.allocN32Pixels(2, 2); | |
2073 { | |
2074 SkAutoLockPixels lock(bitmap); | |
2075 SkCanvas canvas(bitmap); | |
2076 canvas.drawPoint(0, 0, SK_ColorGREEN); | |
2077 canvas.drawPoint(0, 1, SK_ColorBLUE); | |
2078 canvas.drawPoint(1, 0, SK_ColorBLUE); | |
2079 canvas.drawPoint(1, 1, SK_ColorGREEN); | |
2080 } | |
2081 | |
2082 scoped_ptr<FakePicturePile> recording = | |
2083 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size()); | |
2084 SkPaint paint; | |
2085 paint.setFilterQuality(kLow_SkFilterQuality); | |
2086 recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint); | |
2087 recording->RerecordPile(); | |
2088 scoped_refptr<FakePicturePileImpl> pile = | |
2089 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr); | |
2090 | |
2091 gfx::Transform content_to_target_transform; | |
2092 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
2093 content_to_target_transform, viewport, pass.get()); | |
2094 | |
2095 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | |
2096 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, | |
2097 gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor, | |
2098 texture_format, viewport, 1.f, pile.get()); | |
2099 | |
2100 RenderPassList pass_list; | |
2101 pass_list.push_back(pass.Pass()); | |
2102 | |
2103 this->disable_picture_quad_image_filtering_ = true; | |
2104 | |
2105 EXPECT_TRUE(this->RunPixelTest( | |
2106 &pass_list, | |
2107 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), | |
2108 ExactPixelComparator(true))); | |
2109 } | |
2110 | |
2111 // This disables filtering by setting |nearest_neighbor| on the PictureDrawQuad. | |
2112 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNearestNeighbor) { | |
2113 gfx::Size pile_tile_size(1000, 1000); | |
2114 gfx::Rect viewport(this->device_viewport_size_); | |
2115 ResourceFormat texture_format = RGBA_8888; | |
2116 bool nearest_neighbor = true; | |
2117 | |
2118 RenderPassId id(1, 1); | |
2119 gfx::Transform transform_to_root; | |
2120 scoped_ptr<RenderPass> pass = | |
2121 CreateTestRenderPass(id, viewport, transform_to_root); | |
2122 | |
2123 SkBitmap bitmap; | |
2124 bitmap.allocN32Pixels(2, 2); | |
2125 { | |
2126 SkAutoLockPixels lock(bitmap); | |
2127 SkCanvas canvas(bitmap); | |
2128 canvas.drawPoint(0, 0, SK_ColorGREEN); | |
2129 canvas.drawPoint(0, 1, SK_ColorBLUE); | |
2130 canvas.drawPoint(1, 0, SK_ColorBLUE); | |
2131 canvas.drawPoint(1, 1, SK_ColorGREEN); | |
2132 } | |
2133 | |
2134 scoped_ptr<FakePicturePile> recording = | |
2135 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size()); | |
2136 SkPaint paint; | |
2137 paint.setFilterQuality(kLow_SkFilterQuality); | |
2138 recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint); | |
2139 recording->RerecordPile(); | |
2140 scoped_refptr<FakePicturePileImpl> pile = | |
2141 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr); | |
2142 | |
2143 gfx::Transform content_to_target_transform; | |
2144 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
2145 content_to_target_transform, viewport, pass.get()); | |
2146 | |
2147 PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | |
2148 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, | |
2149 gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor, | |
2150 texture_format, viewport, 1.f, pile.get()); | |
2151 | |
2152 RenderPassList pass_list; | |
2153 pass_list.push_back(pass.Pass()); | |
2154 | |
2155 EXPECT_TRUE(this->RunPixelTest( | |
2156 &pass_list, | |
2157 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), | |
2158 ExactPixelComparator(true))); | |
2159 } | |
2160 | |
2161 // This disables filtering by setting |nearest_neighbor| on the TileDrawQuad. | |
2162 TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) { | |
2163 gfx::Rect viewport(this->device_viewport_size_); | |
2164 bool swizzle_contents = true; | |
2165 bool nearest_neighbor = true; | |
2166 | |
2167 SkBitmap bitmap; | |
2168 bitmap.allocN32Pixels(2, 2); | |
2169 { | |
2170 SkAutoLockPixels lock(bitmap); | |
2171 SkCanvas canvas(bitmap); | |
2172 canvas.drawPoint(0, 0, SK_ColorGREEN); | |
2173 canvas.drawPoint(0, 1, SK_ColorBLUE); | |
2174 canvas.drawPoint(1, 0, SK_ColorBLUE); | |
2175 canvas.drawPoint(1, 1, SK_ColorGREEN); | |
2176 } | |
2177 | |
2178 gfx::Size tile_size(2, 2); | |
2179 ResourceProvider::ResourceId resource = | |
2180 this->resource_provider_->CreateResource( | |
2181 tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, | |
2182 RGBA_8888); | |
2183 | |
2184 { | |
2185 SkAutoLockPixels lock(bitmap); | |
2186 this->resource_provider_->CopyToResource( | |
2187 resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size); | |
2188 } | |
2189 | |
2190 RenderPassId id(1, 1); | |
2191 gfx::Transform transform_to_root; | |
2192 scoped_ptr<RenderPass> pass = | |
2193 CreateTestRenderPass(id, viewport, transform_to_root); | |
2194 | |
2195 gfx::Transform content_to_target_transform; | |
2196 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
2197 content_to_target_transform, viewport, pass.get()); | |
2198 | |
2199 TileDrawQuad* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>(); | |
2200 quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource, | |
2201 gfx::Rect(tile_size), tile_size, swizzle_contents, | |
2202 nearest_neighbor); | |
2203 | |
2204 RenderPassList pass_list; | |
2205 pass_list.push_back(pass.Pass()); | |
2206 | |
2207 EXPECT_TRUE(this->RunPixelTest( | |
2208 &pass_list, | |
2209 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), | |
2210 ExactPixelComparator(true))); | |
2211 } | |
2212 | |
2213 TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) { | |
2214 gfx::Size pile_tile_size(1000, 1000); | |
2215 gfx::Rect viewport(this->device_viewport_size_); | |
2216 // TODO(enne): the renderer should figure this out on its own. | |
2217 ResourceFormat texture_format = RGBA_8888; | |
2218 bool nearest_neighbor = false; | |
2219 | |
2220 RenderPassId id(1, 1); | |
2221 gfx::Transform transform_to_root; | |
2222 scoped_ptr<RenderPass> pass = | |
2223 CreateTestRenderPass(id, viewport, transform_to_root); | |
2224 | |
2225 // As scaling up the blue checkerboards will cause sampling on the GPU, | |
2226 // a few extra "cleanup rects" need to be added to clobber the blending | |
2227 // to make the output image more clean. This will also test subrects | |
2228 // of the layer. | |
2229 gfx::Transform green_content_to_target_transform; | |
2230 gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100)); | |
2231 gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20)); | |
2232 | |
2233 scoped_ptr<FakePicturePile> green_recording = | |
2234 FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size()); | |
2235 | |
2236 SkPaint red_paint; | |
2237 red_paint.setColor(SK_ColorRED); | |
2238 green_recording->add_draw_rect_with_paint(viewport, red_paint); | |
2239 SkPaint green_paint; | |
2240 green_paint.setColor(SK_ColorGREEN); | |
2241 green_recording->add_draw_rect_with_paint(green_rect1, green_paint); | |
2242 green_recording->add_draw_rect_with_paint(green_rect2, green_paint); | |
2243 green_recording->RerecordPile(); | |
2244 scoped_refptr<FakePicturePileImpl> green_pile = | |
2245 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr); | |
2246 | |
2247 SharedQuadState* top_right_green_shared_quad_state = | |
2248 CreateTestSharedQuadState( | |
2249 green_content_to_target_transform, viewport, pass.get()); | |
2250 | |
2251 PictureDrawQuad* green_quad1 = | |
2252 pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | |
2253 green_quad1->SetNew(top_right_green_shared_quad_state, green_rect1, | |
2254 gfx::Rect(), green_rect1, gfx::RectF(green_rect1.size()), | |
2255 green_rect1.size(), nearest_neighbor, texture_format, | |
2256 green_rect1, 1.f, green_pile.get()); | |
2257 | |
2258 PictureDrawQuad* green_quad2 = | |
2259 pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | |
2260 green_quad2->SetNew(top_right_green_shared_quad_state, green_rect2, | |
2261 gfx::Rect(), green_rect2, gfx::RectF(green_rect2.size()), | |
2262 green_rect2.size(), nearest_neighbor, texture_format, | |
2263 green_rect2, 1.f, green_pile.get()); | |
2264 | |
2265 // Add a green clipped checkerboard in the bottom right to help test | |
2266 // interleaving picture quad content and solid color content. | |
2267 gfx::Rect bottom_right_rect( | |
2268 gfx::Point(viewport.width() / 2, viewport.height() / 2), | |
2269 gfx::Size(viewport.width() / 2, viewport.height() / 2)); | |
2270 SharedQuadState* bottom_right_green_shared_state = | |
2271 CreateTestSharedQuadStateClipped(green_content_to_target_transform, | |
2272 viewport, | |
2273 bottom_right_rect, | |
2274 pass.get()); | |
2275 SolidColorDrawQuad* bottom_right_color_quad = | |
2276 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
2277 bottom_right_color_quad->SetNew(bottom_right_green_shared_state, | |
2278 viewport, | |
2279 viewport, | |
2280 SK_ColorGREEN, | |
2281 false); | |
2282 | |
2283 // Add two blue checkerboards taking up the bottom left and top right, | |
2284 // but use content scales as content rects to make this happen. | |
2285 // The content is at a 4x content scale. | |
2286 gfx::Rect layer_rect(gfx::Size(20, 30)); | |
2287 float contents_scale = 4.f; | |
2288 // Two rects that touch at their corners, arbitrarily placed in the layer. | |
2289 gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f)); | |
2290 gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f)); | |
2291 gfx::RectF union_layer_rect = blue_layer_rect1; | |
2292 union_layer_rect.Union(blue_layer_rect2); | |
2293 | |
2294 // Because scaling up will cause sampling outside the rects, add one extra | |
2295 // pixel of buffer at the final content scale. | |
2296 float inset = -1.f / contents_scale; | |
2297 blue_layer_rect1.Inset(inset, inset, inset, inset); | |
2298 blue_layer_rect2.Inset(inset, inset, inset, inset); | |
2299 | |
2300 scoped_ptr<FakePicturePile> recording = | |
2301 FakePicturePile::CreateFilledPile(pile_tile_size, layer_rect.size()); | |
2302 | |
2303 Region outside(layer_rect); | |
2304 outside.Subtract(gfx::ToEnclosingRect(union_layer_rect)); | |
2305 for (Region::Iterator iter(outside); iter.has_rect(); iter.next()) { | |
2306 recording->add_draw_rect_with_paint(iter.rect(), red_paint); | |
2307 } | |
2308 | |
2309 SkPaint blue_paint; | |
2310 blue_paint.setColor(SK_ColorBLUE); | |
2311 recording->add_draw_rect_with_paint(blue_layer_rect1, blue_paint); | |
2312 recording->add_draw_rect_with_paint(blue_layer_rect2, blue_paint); | |
2313 recording->RerecordPile(); | |
2314 scoped_refptr<FakePicturePileImpl> pile = | |
2315 FakePicturePileImpl::CreateFromPile(recording.get(), nullptr); | |
2316 | |
2317 gfx::Rect content_rect( | |
2318 gfx::ScaleToEnclosingRect(layer_rect, contents_scale)); | |
2319 gfx::Rect content_union_rect( | |
2320 gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale))); | |
2321 | |
2322 // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels, | |
2323 // so scale an additional 10x to make them 100x100. | |
2324 gfx::Transform content_to_target_transform; | |
2325 content_to_target_transform.Scale(10.0, 10.0); | |
2326 gfx::Rect quad_content_rect(gfx::Size(20, 20)); | |
2327 SharedQuadState* blue_shared_state = CreateTestSharedQuadState( | |
2328 content_to_target_transform, quad_content_rect, pass.get()); | |
2329 | |
2330 PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>(); | |
2331 blue_quad->SetNew(blue_shared_state, quad_content_rect, gfx::Rect(), | |
2332 quad_content_rect, gfx::RectF(quad_content_rect), | |
2333 content_union_rect.size(), nearest_neighbor, texture_format, | |
2334 content_union_rect, contents_scale, pile.get()); | |
2335 | |
2336 // Fill left half of viewport with green. | |
2337 gfx::Transform half_green_content_to_target_transform; | |
2338 gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height())); | |
2339 SharedQuadState* half_green_shared_state = CreateTestSharedQuadState( | |
2340 half_green_content_to_target_transform, half_green_rect, pass.get()); | |
2341 SolidColorDrawQuad* half_color_quad = | |
2342 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
2343 half_color_quad->SetNew(half_green_shared_state, | |
2344 half_green_rect, | |
2345 half_green_rect, | |
2346 SK_ColorGREEN, | |
2347 false); | |
2348 | |
2349 RenderPassList pass_list; | |
2350 pass_list.push_back(pass.Pass()); | |
2351 | |
2352 EXPECT_TRUE(this->RunPixelTest( | |
2353 &pass_list, | |
2354 base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")), | |
2355 ExactPixelComparator(true))); | |
2356 } | |
2357 | |
2358 typedef RendererPixelTest<GLRendererWithFlippedSurface> | |
2359 GLRendererPixelTestWithFlippedOutputSurface; | |
2360 | |
2361 TEST_F(GLRendererPixelTestWithFlippedOutputSurface, ExplicitFlipTest) { | |
2362 // This draws a blue rect above a yellow rect with an inverted output surface. | |
2363 gfx::Rect viewport_rect(this->device_viewport_size_); | |
2364 | |
2365 RenderPassId root_pass_id(1, 1); | |
2366 scoped_ptr<RenderPass> root_pass = | |
2367 CreateTestRootRenderPass(root_pass_id, viewport_rect); | |
2368 | |
2369 RenderPassId child_pass_id(2, 2); | |
2370 gfx::Rect pass_rect(this->device_viewport_size_); | |
2371 gfx::Transform transform_to_root; | |
2372 scoped_ptr<RenderPass> child_pass = | |
2373 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | |
2374 | |
2375 gfx::Transform content_to_target_transform; | |
2376 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
2377 content_to_target_transform, viewport_rect, child_pass.get()); | |
2378 | |
2379 gfx::Rect blue_rect(0, | |
2380 0, | |
2381 this->device_viewport_size_.width(), | |
2382 this->device_viewport_size_.height() / 2); | |
2383 SolidColorDrawQuad* blue = | |
2384 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
2385 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | |
2386 gfx::Rect yellow_rect(0, | |
2387 this->device_viewport_size_.height() / 2, | |
2388 this->device_viewport_size_.width(), | |
2389 this->device_viewport_size_.height() / 2); | |
2390 SolidColorDrawQuad* yellow = | |
2391 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
2392 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | |
2393 | |
2394 SharedQuadState* pass_shared_state = | |
2395 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | |
2396 CreateTestRenderPassDrawQuad( | |
2397 pass_shared_state, pass_rect, child_pass_id, root_pass.get()); | |
2398 | |
2399 RenderPassList pass_list; | |
2400 pass_list.push_back(child_pass.Pass()); | |
2401 pass_list.push_back(root_pass.Pass()); | |
2402 | |
2403 EXPECT_TRUE(this->RunPixelTest( | |
2404 &pass_list, | |
2405 base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")), | |
2406 ExactPixelComparator(true))); | |
2407 } | |
2408 | |
2409 TEST_F(GLRendererPixelTestWithFlippedOutputSurface, CheckChildPassUnflipped) { | |
2410 // This draws a blue rect above a yellow rect with an inverted output surface. | |
2411 gfx::Rect viewport_rect(this->device_viewport_size_); | |
2412 | |
2413 RenderPassId root_pass_id(1, 1); | |
2414 scoped_ptr<RenderPass> root_pass = | |
2415 CreateTestRootRenderPass(root_pass_id, viewport_rect); | |
2416 | |
2417 RenderPassId child_pass_id(2, 2); | |
2418 gfx::Rect pass_rect(this->device_viewport_size_); | |
2419 gfx::Transform transform_to_root; | |
2420 scoped_ptr<RenderPass> child_pass = | |
2421 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | |
2422 | |
2423 gfx::Transform content_to_target_transform; | |
2424 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
2425 content_to_target_transform, viewport_rect, child_pass.get()); | |
2426 | |
2427 gfx::Rect blue_rect(0, | |
2428 0, | |
2429 this->device_viewport_size_.width(), | |
2430 this->device_viewport_size_.height() / 2); | |
2431 SolidColorDrawQuad* blue = | |
2432 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
2433 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | |
2434 gfx::Rect yellow_rect(0, | |
2435 this->device_viewport_size_.height() / 2, | |
2436 this->device_viewport_size_.width(), | |
2437 this->device_viewport_size_.height() / 2); | |
2438 SolidColorDrawQuad* yellow = | |
2439 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
2440 yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false); | |
2441 | |
2442 SharedQuadState* pass_shared_state = | |
2443 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | |
2444 CreateTestRenderPassDrawQuad( | |
2445 pass_shared_state, pass_rect, child_pass_id, root_pass.get()); | |
2446 | |
2447 RenderPassList pass_list; | |
2448 pass_list.push_back(child_pass.Pass()); | |
2449 pass_list.push_back(root_pass.Pass()); | |
2450 | |
2451 // Check that the child pass remains unflipped. | |
2452 EXPECT_TRUE(this->RunPixelTestWithReadbackTarget( | |
2453 &pass_list, | |
2454 pass_list.front(), | |
2455 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")), | |
2456 ExactPixelComparator(true))); | |
2457 } | |
2458 | |
2459 TEST_F(GLRendererPixelTest, CheckReadbackSubset) { | |
2460 gfx::Rect viewport_rect(this->device_viewport_size_); | |
2461 | |
2462 RenderPassId root_pass_id(1, 1); | |
2463 scoped_ptr<RenderPass> root_pass = | |
2464 CreateTestRootRenderPass(root_pass_id, viewport_rect); | |
2465 | |
2466 RenderPassId child_pass_id(2, 2); | |
2467 gfx::Rect pass_rect(this->device_viewport_size_); | |
2468 gfx::Transform transform_to_root; | |
2469 scoped_ptr<RenderPass> child_pass = | |
2470 CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root); | |
2471 | |
2472 gfx::Transform content_to_target_transform; | |
2473 SharedQuadState* shared_state = CreateTestSharedQuadState( | |
2474 content_to_target_transform, viewport_rect, child_pass.get()); | |
2475 | |
2476 // Draw a green quad full-size with a blue quad in the lower-right corner. | |
2477 gfx::Rect blue_rect(this->device_viewport_size_.width() * 3 / 4, | |
2478 this->device_viewport_size_.height() * 3 / 4, | |
2479 this->device_viewport_size_.width() * 3 / 4, | |
2480 this->device_viewport_size_.height() * 3 / 4); | |
2481 SolidColorDrawQuad* blue = | |
2482 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
2483 blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false); | |
2484 gfx::Rect green_rect(0, | |
2485 0, | |
2486 this->device_viewport_size_.width(), | |
2487 this->device_viewport_size_.height()); | |
2488 SolidColorDrawQuad* green = | |
2489 child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
2490 green->SetNew(shared_state, green_rect, green_rect, SK_ColorGREEN, false); | |
2491 | |
2492 SharedQuadState* pass_shared_state = | |
2493 CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get()); | |
2494 CreateTestRenderPassDrawQuad( | |
2495 pass_shared_state, pass_rect, child_pass_id, root_pass.get()); | |
2496 | |
2497 RenderPassList pass_list; | |
2498 pass_list.push_back(child_pass.Pass()); | |
2499 pass_list.push_back(root_pass.Pass()); | |
2500 | |
2501 // Check that the child pass remains unflipped. | |
2502 gfx::Rect capture_rect(this->device_viewport_size_.width() / 2, | |
2503 this->device_viewport_size_.height() / 2, | |
2504 this->device_viewport_size_.width() / 2, | |
2505 this->device_viewport_size_.height() / 2); | |
2506 EXPECT_TRUE(this->RunPixelTestWithReadbackTargetAndArea( | |
2507 &pass_list, | |
2508 pass_list.front(), | |
2509 base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")), | |
2510 ExactPixelComparator(true), | |
2511 &capture_rect)); | |
2512 } | |
2513 | |
2514 TYPED_TEST(RendererPixelTest, WrapModeRepeat) { | |
2515 gfx::Rect rect(this->device_viewport_size_); | |
2516 | |
2517 RenderPassId id(1, 1); | |
2518 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | |
2519 | |
2520 SharedQuadState* shared_state = | |
2521 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | |
2522 | |
2523 gfx::Size texture_size(4, 4); | |
2524 SkPMColor colors[4] = { | |
2525 SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)), | |
2526 SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)), | |
2527 SkPreMultiplyColor(SkColorSetARGB(255, 0, 64, 0)), | |
2528 SkPreMultiplyColor(SkColorSetARGB(255, 0, 0, 0)), | |
2529 }; | |
2530 uint32_t pixels[16] = { | |
2531 colors[0], colors[0], colors[1], colors[1], | |
2532 colors[0], colors[0], colors[1], colors[1], | |
2533 colors[2], colors[2], colors[3], colors[3], | |
2534 colors[2], colors[2], colors[3], colors[3], | |
2535 }; | |
2536 ResourceProvider::ResourceId resource = | |
2537 this->resource_provider_->CreateResource( | |
2538 texture_size, GL_REPEAT, ResourceProvider::TEXTURE_HINT_IMMUTABLE, | |
2539 RGBA_8888); | |
2540 this->resource_provider_->CopyToResource( | |
2541 resource, reinterpret_cast<uint8_t*>(pixels), texture_size); | |
2542 | |
2543 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; | |
2544 TextureDrawQuad* texture_quad = | |
2545 pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); | |
2546 texture_quad->SetNew( | |
2547 shared_state, gfx::Rect(this->device_viewport_size_), gfx::Rect(), | |
2548 gfx::Rect(this->device_viewport_size_), resource, | |
2549 true, // premultiplied_alpha | |
2550 gfx::PointF(0.0f, 0.0f), // uv_top_left | |
2551 gfx::PointF( // uv_bottom_right | |
2552 this->device_viewport_size_.width() / texture_size.width(), | |
2553 this->device_viewport_size_.height() / texture_size.height()), | |
2554 SK_ColorWHITE, vertex_opacity, | |
2555 false, // flipped | |
2556 false); // nearest_neighbor | |
2557 | |
2558 RenderPassList pass_list; | |
2559 pass_list.push_back(pass.Pass()); | |
2560 | |
2561 EXPECT_TRUE(this->RunPixelTest( | |
2562 &pass_list, | |
2563 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")), | |
2564 FuzzyPixelOffByOneComparator(true))); | |
2565 } | |
2566 | |
2567 TYPED_TEST(RendererPixelTest, Checkerboards) { | |
2568 gfx::Rect rect(this->device_viewport_size_); | |
2569 | |
2570 RenderPassId id(1, 1); | |
2571 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | |
2572 | |
2573 SharedQuadState* shared_state = | |
2574 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | |
2575 | |
2576 // The color's alpha value is not used. | |
2577 SkColor color1 = SK_ColorGREEN; | |
2578 color1 = SkColorSetA(color1, 0); | |
2579 SkColor color2 = SK_ColorBLUE; | |
2580 color2 = SkColorSetA(color2, 0); | |
2581 | |
2582 gfx::Rect content_rect(rect); | |
2583 | |
2584 gfx::Rect top_left(content_rect); | |
2585 gfx::Rect top_right(content_rect); | |
2586 gfx::Rect bottom_left(content_rect); | |
2587 gfx::Rect bottom_right(content_rect); | |
2588 // The format is Inset(left, top, right, bottom). | |
2589 top_left.Inset(0, 0, content_rect.width() / 2, content_rect.height() / 2); | |
2590 top_right.Inset(content_rect.width() / 2, 0, 0, content_rect.height() / 2); | |
2591 bottom_left.Inset(0, content_rect.height() / 2, content_rect.width() / 2, 0); | |
2592 bottom_right.Inset(content_rect.width() / 2, content_rect.height() / 2, 0, 0); | |
2593 | |
2594 // Appends checkerboard quads with a scale of 1. | |
2595 CheckerboardDrawQuad* quad = | |
2596 pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>(); | |
2597 quad->SetNew(shared_state, top_left, top_left, color1, 1.f); | |
2598 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>(); | |
2599 quad->SetNew(shared_state, top_right, top_right, color2, 1.f); | |
2600 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>(); | |
2601 quad->SetNew(shared_state, bottom_left, bottom_left, color2, 1.f); | |
2602 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>(); | |
2603 quad->SetNew(shared_state, bottom_right, bottom_right, color1, 1.f); | |
2604 | |
2605 RenderPassList pass_list; | |
2606 pass_list.push_back(pass.Pass()); | |
2607 | |
2608 base::FilePath::StringType path = | |
2609 IsSoftwareRenderer<TypeParam>() | |
2610 ? FILE_PATH_LITERAL("four_blue_green_checkers.png") | |
2611 : FILE_PATH_LITERAL("checkers.png"); | |
2612 EXPECT_TRUE(this->RunPixelTest(&pass_list, base::FilePath(path), | |
2613 ExactPixelComparator(true))); | |
2614 } | |
2615 | |
2616 TYPED_TEST(RendererPixelTest, CheckerboardsScaled) { | |
2617 gfx::Rect rect(this->device_viewport_size_); | |
2618 | |
2619 RenderPassId id(1, 1); | |
2620 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | |
2621 | |
2622 gfx::Transform scale; | |
2623 scale.Scale(2.f, 2.f); | |
2624 | |
2625 SharedQuadState* shared_state = | |
2626 CreateTestSharedQuadState(scale, rect, pass.get()); | |
2627 | |
2628 // The color's alpha value is not used. | |
2629 SkColor color1 = SK_ColorGREEN; | |
2630 color1 = SkColorSetA(color1, 0); | |
2631 SkColor color2 = SK_ColorBLUE; | |
2632 color2 = SkColorSetA(color2, 0); | |
2633 | |
2634 gfx::Rect content_rect(rect); | |
2635 content_rect.Inset(0, 0, rect.width() / 2, rect.height() / 2); | |
2636 | |
2637 gfx::Rect top_left(content_rect); | |
2638 gfx::Rect top_right(content_rect); | |
2639 gfx::Rect bottom_left(content_rect); | |
2640 gfx::Rect bottom_right(content_rect); | |
2641 // The format is Inset(left, top, right, bottom). | |
2642 top_left.Inset(0, 0, content_rect.width() / 2, content_rect.height() / 2); | |
2643 top_right.Inset(content_rect.width() / 2, 0, 0, content_rect.height() / 2); | |
2644 bottom_left.Inset(0, content_rect.height() / 2, content_rect.width() / 2, 0); | |
2645 bottom_right.Inset(content_rect.width() / 2, content_rect.height() / 2, 0, 0); | |
2646 | |
2647 // Appends checkerboard quads with a scale of 2, and a shared quad state | |
2648 // with a scale of 2. The checkers should be scaled by 2 * 2 = 4. | |
2649 CheckerboardDrawQuad* quad = | |
2650 pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>(); | |
2651 quad->SetNew(shared_state, top_left, top_left, color1, 2.f); | |
2652 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>(); | |
2653 quad->SetNew(shared_state, top_right, top_right, color2, 2.f); | |
2654 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>(); | |
2655 quad->SetNew(shared_state, bottom_left, bottom_left, color2, 2.f); | |
2656 quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>(); | |
2657 quad->SetNew(shared_state, bottom_right, bottom_right, color1, 2.f); | |
2658 | |
2659 RenderPassList pass_list; | |
2660 pass_list.push_back(pass.Pass()); | |
2661 | |
2662 base::FilePath::StringType path = | |
2663 IsSoftwareRenderer<TypeParam>() | |
2664 ? FILE_PATH_LITERAL("four_blue_green_checkers.png") | |
2665 : FILE_PATH_LITERAL("checkers_big.png"); | |
2666 EXPECT_TRUE(this->RunPixelTest(&pass_list, base::FilePath(path), | |
2667 ExactPixelComparator(true))); | |
2668 } | |
2669 | |
2670 #endif // !defined(OS_ANDROID) | |
2671 | |
2672 } // namespace | |
2673 } // namespace cc | |
OLD | NEW |