OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/message_loop/message_loop.h" | 5 #include "base/message_loop/message_loop.h" |
6 #include "cc/layers/append_quads_data.h" | 6 #include "cc/layers/append_quads_data.h" |
7 #include "cc/output/gl_renderer.h" | 7 #include "cc/output/gl_renderer.h" |
8 #include "cc/quads/draw_quad.h" | 8 #include "cc/quads/draw_quad.h" |
9 #include "cc/quads/picture_draw_quad.h" | 9 #include "cc/quads/picture_draw_quad.h" |
10 #include "cc/quads/texture_draw_quad.h" | 10 #include "cc/quads/texture_draw_quad.h" |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 rect, | 104 rect, |
105 pass_id, | 105 pass_id, |
106 0, // mask_resource_id | 106 0, // mask_resource_id |
107 gfx::Vector2dF(), // mask_uv_scale | 107 gfx::Vector2dF(), // mask_uv_scale |
108 gfx::Size(), // mask_texture_size | 108 gfx::Size(), // mask_texture_size |
109 FilterOperations(), // foreground filters | 109 FilterOperations(), // foreground filters |
110 gfx::Vector2dF(), // filters scale | 110 gfx::Vector2dF(), // filters scale |
111 FilterOperations()); // background filters | 111 FilterOperations()); // background filters |
112 } | 112 } |
113 | 113 |
114 void CreateTestTwoColoredTextureDrawQuad(const gfx::Rect& rect, | |
115 SkColor texel_color, | |
116 SkColor texel_stripe_color, | |
117 SkColor background_color, | |
118 bool premultiplied_alpha, | |
119 const SharedQuadState* shared_state, | |
120 ResourceProvider* resource_provider, | |
121 RenderPass* render_pass) { | |
122 SkPMColor pixel_color = premultiplied_alpha | |
123 ? SkPreMultiplyColor(texel_color) | |
124 : SkPackARGB32NoCheck(SkColorGetA(texel_color), | |
125 SkColorGetR(texel_color), | |
126 SkColorGetG(texel_color), | |
127 SkColorGetB(texel_color)); | |
128 SkPMColor pixel_stripe_color = | |
129 premultiplied_alpha | |
130 ? SkPreMultiplyColor(texel_stripe_color) | |
131 : SkPackARGB32NoCheck(SkColorGetA(texel_stripe_color), | |
132 SkColorGetR(texel_stripe_color), | |
133 SkColorGetG(texel_stripe_color), | |
134 SkColorGetB(texel_stripe_color)); | |
135 std::vector<uint32_t> pixels(rect.size().GetArea(), pixel_color); | |
136 for (int i = rect.height() / 4; i < (rect.height() * 3 / 4); ++i) { | |
137 for (int k = rect.width() / 4; k < (rect.width() * 3 / 4); ++k) { | |
138 pixels[i * rect.width() + k] = pixel_stripe_color; | |
139 } | |
140 } | |
141 ResourceProvider::ResourceId resource = resource_provider->CreateResource( | |
142 rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, | |
143 RGBA_8888); | |
144 resource_provider->SetPixels(resource, | |
145 reinterpret_cast<uint8_t*>(&pixels.front()), | |
146 rect, rect, gfx::Vector2d()); | |
147 | |
148 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; | |
149 const gfx::PointF uv_top_left(0.0f, 0.0f); | |
150 const gfx::PointF uv_bottom_right(1.0f, 1.0f); | |
151 const bool flipped = false; | |
152 const bool nearest_neighbor = false; | |
153 TextureDrawQuad* quad = | |
154 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); | |
155 quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource, | |
156 premultiplied_alpha, uv_top_left, uv_bottom_right, | |
157 background_color, vertex_opacity, flipped, nearest_neighbor); | |
158 } | |
159 | |
160 void CreateTestTextureDrawQuad(const gfx::Rect& rect, | 114 void CreateTestTextureDrawQuad(const gfx::Rect& rect, |
161 SkColor texel_color, | 115 SkColor texel_color, |
162 SkColor background_color, | 116 SkColor background_color, |
163 bool premultiplied_alpha, | 117 bool premultiplied_alpha, |
164 const SharedQuadState* shared_state, | 118 const SharedQuadState* shared_state, |
165 ResourceProvider* resource_provider, | 119 ResourceProvider* resource_provider, |
166 RenderPass* render_pass) { | 120 RenderPass* render_pass) { |
167 SkPMColor pixel_color = premultiplied_alpha ? | 121 SkPMColor pixel_color = premultiplied_alpha ? |
168 SkPreMultiplyColor(texel_color) : | 122 SkPreMultiplyColor(texel_color) : |
169 SkPackARGB32NoCheck(SkColorGetA(texel_color), | 123 SkPackARGB32NoCheck(SkColorGetA(texel_color), |
170 SkColorGetR(texel_color), | 124 SkColorGetR(texel_color), |
171 SkColorGetG(texel_color), | 125 SkColorGetG(texel_color), |
172 SkColorGetB(texel_color)); | 126 SkColorGetB(texel_color)); |
173 size_t num_pixels = static_cast<size_t>(rect.width()) * rect.height(); | 127 size_t num_pixels = static_cast<size_t>(rect.width()) * rect.height(); |
174 std::vector<uint32_t> pixels(num_pixels, pixel_color); | 128 std::vector<uint32_t> pixels(num_pixels, pixel_color); |
175 | 129 |
176 ResourceProvider::ResourceId resource = resource_provider->CreateResource( | 130 ResourceProvider::ResourceId resource = resource_provider->CreateResource( |
177 rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, | 131 rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, |
178 RGBA_8888); | 132 RGBA_8888); |
179 resource_provider->CopyToResource( | 133 resource_provider->CopyToResource( |
180 resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size()); | 134 resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size()); |
181 | 135 |
182 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; | 136 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; |
183 | 137 |
184 const gfx::PointF uv_top_left(0.0f, 0.0f); | |
185 const gfx::PointF uv_bottom_right(1.0f, 1.0f); | |
186 const bool flipped = false; | |
187 const bool nearest_neighbor = false; | |
188 TextureDrawQuad* quad = | 138 TextureDrawQuad* quad = |
189 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); | 139 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); |
190 quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource, | 140 quad->SetNew(shared_state, |
191 premultiplied_alpha, uv_top_left, uv_bottom_right, | 141 rect, |
192 background_color, vertex_opacity, flipped, nearest_neighbor); | 142 gfx::Rect(), |
193 } | 143 rect, |
194 | 144 resource, |
195 void CreateTestYUVVideoDrawQuad_FromVideoFrame( | 145 premultiplied_alpha, |
196 const SharedQuadState* shared_state, | 146 gfx::PointF(0.0f, 0.0f), // uv_top_left |
197 scoped_refptr<media::VideoFrame> video_frame, | 147 gfx::PointF(1.0f, 1.0f), // uv_bottom_right |
198 uint8 alpha_value, | 148 background_color, |
199 const gfx::RectF& tex_coord_rect, | 149 vertex_opacity, |
200 RenderPass* render_pass, | 150 false, // flipped |
201 VideoResourceUpdater* video_resource_updater, | 151 false); // nearest_neighbor |
202 const gfx::Rect& rect, | |
203 ResourceProvider* resource_provider) { | |
204 const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A); | |
205 const YUVVideoDrawQuad::ColorSpace color_space = | |
206 (video_frame->format() == media::VideoFrame::YV12J | |
207 ? YUVVideoDrawQuad::JPEG | |
208 : YUVVideoDrawQuad::REC_601); | |
209 const gfx::Rect opaque_rect(0, 0, 0, 0); | |
210 | |
211 if (with_alpha) { | |
212 memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value, | |
213 video_frame->stride(media::VideoFrame::kAPlane) * | |
214 video_frame->rows(media::VideoFrame::kAPlane)); | |
215 } | |
216 | |
217 VideoFrameExternalResources resources = | |
218 video_resource_updater->CreateExternalResourcesFromVideoFrame( | |
219 video_frame); | |
220 | |
221 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type); | |
222 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()), | |
223 resources.mailboxes.size()); | |
224 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()), | |
225 resources.release_callbacks.size()); | |
226 | |
227 ResourceProvider::ResourceId y_resource = | |
228 resource_provider->CreateResourceFromTextureMailbox( | |
229 resources.mailboxes[media::VideoFrame::kYPlane], | |
230 SingleReleaseCallbackImpl::Create( | |
231 resources.release_callbacks[media::VideoFrame::kYPlane])); | |
232 ResourceProvider::ResourceId u_resource = | |
233 resource_provider->CreateResourceFromTextureMailbox( | |
234 resources.mailboxes[media::VideoFrame::kUPlane], | |
235 SingleReleaseCallbackImpl::Create( | |
236 resources.release_callbacks[media::VideoFrame::kUPlane])); | |
237 ResourceProvider::ResourceId v_resource = | |
238 resource_provider->CreateResourceFromTextureMailbox( | |
239 resources.mailboxes[media::VideoFrame::kVPlane], | |
240 SingleReleaseCallbackImpl::Create( | |
241 resources.release_callbacks[media::VideoFrame::kVPlane])); | |
242 ResourceProvider::ResourceId a_resource = 0; | |
243 if (with_alpha) { | |
244 a_resource = resource_provider->CreateResourceFromTextureMailbox( | |
245 resources.mailboxes[media::VideoFrame::kAPlane], | |
246 SingleReleaseCallbackImpl::Create( | |
247 resources.release_callbacks[media::VideoFrame::kAPlane])); | |
248 } | |
249 | |
250 YUVVideoDrawQuad* yuv_quad = | |
251 render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>(); | |
252 yuv_quad->SetNew(shared_state, rect, opaque_rect, rect, tex_coord_rect, | |
253 video_frame->coded_size(), y_resource, u_resource, | |
254 v_resource, a_resource, color_space); | |
255 } | |
256 | |
257 void CreateTestYUVVideoDrawQuad_Striped( | |
258 const SharedQuadState* shared_state, | |
259 media::VideoFrame::Format format, | |
260 bool is_transparent, | |
261 const gfx::RectF& tex_coord_rect, | |
262 RenderPass* render_pass, | |
263 VideoResourceUpdater* video_resource_updater, | |
264 const gfx::Rect& 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, 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 uint8 y_background, | |
310 uint8 u_background, | |
311 uint8 v_background, | |
312 const gfx::Rect& foreground_rect, | |
313 uint8 y_foreground, | |
314 uint8 u_foreground, | |
315 uint8 v_foreground, | |
316 RenderPass* render_pass, | |
317 VideoResourceUpdater* video_resource_updater, | |
318 ResourceProvider* resource_provider) { | |
319 const gfx::Rect rect(background_size); | |
320 | |
321 scoped_refptr<media::VideoFrame> video_frame = | |
322 media::VideoFrame::CreateFrame(format, background_size, foreground_rect, | |
323 foreground_rect.size(), base::TimeDelta()); | |
324 | |
325 int planes[] = {media::VideoFrame::kYPlane, | |
326 media::VideoFrame::kUPlane, | |
327 media::VideoFrame::kVPlane}; | |
328 uint8 yuv_background[] = {y_background, u_background, v_background}; | |
329 uint8 yuv_foreground[] = {y_foreground, u_foreground, v_foreground}; | |
330 int sample_size[] = {1, 2, 2}; | |
331 | |
332 for (int i = 0; i < 3; ++i) { | |
333 memset(video_frame->data(planes[i]), yuv_background[i], | |
334 video_frame->stride(planes[i]) * video_frame->rows(planes[i])); | |
335 } | |
336 | |
337 for (int i = 0; i < 3; ++i) { | |
338 // Since yuv encoding uses block encoding, widths have to be divisible | |
339 // by the sample size in order for this function to behave properly. | |
340 DCHECK_EQ(foreground_rect.x() % sample_size[i], 0); | |
341 DCHECK_EQ(foreground_rect.y() % sample_size[i], 0); | |
342 DCHECK_EQ(foreground_rect.width() % sample_size[i], 0); | |
343 DCHECK_EQ(foreground_rect.height() % sample_size[i], 0); | |
344 | |
345 gfx::Rect sample_rect(foreground_rect.x() / sample_size[i], | |
346 foreground_rect.y() / sample_size[i], | |
347 foreground_rect.width() / sample_size[i], | |
348 foreground_rect.height() / sample_size[i]); | |
349 for (int y = sample_rect.y(); y < sample_rect.bottom(); ++y) { | |
350 for (int x = sample_rect.x(); x < sample_rect.right(); ++x) { | |
351 size_t offset = y * video_frame->stride(planes[i]) + x; | |
352 video_frame->data(planes[i])[offset] = yuv_foreground[i]; | |
353 } | |
354 } | |
355 } | |
356 | |
357 uint8 alpha_value = 255; | |
358 CreateTestYUVVideoDrawQuad_FromVideoFrame( | |
359 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass, | |
360 video_resource_updater, rect, resource_provider); | |
361 } | |
362 | |
363 void CreateTestYUVVideoDrawQuad_Solid( | |
364 const SharedQuadState* shared_state, | |
365 media::VideoFrame::Format format, | |
366 bool is_transparent, | |
367 const gfx::RectF& tex_coord_rect, | |
368 uint8 y, | |
369 uint8 u, | |
370 uint8 v, | |
371 RenderPass* render_pass, | |
372 VideoResourceUpdater* video_resource_updater, | |
373 const gfx::Rect& rect, | |
374 ResourceProvider* resource_provider) { | |
375 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame( | |
376 format, rect.size(), rect, rect.size(), base::TimeDelta()); | |
377 | |
378 // YUV values of a solid, constant, color. Useful for testing that color | |
379 // space/color range are being handled properly. | |
380 memset(video_frame->data(media::VideoFrame::kYPlane), y, | |
381 video_frame->stride(media::VideoFrame::kYPlane) * | |
382 video_frame->rows(media::VideoFrame::kYPlane)); | |
383 memset(video_frame->data(media::VideoFrame::kUPlane), u, | |
384 video_frame->stride(media::VideoFrame::kUPlane) * | |
385 video_frame->rows(media::VideoFrame::kUPlane)); | |
386 memset(video_frame->data(media::VideoFrame::kVPlane), v, | |
387 video_frame->stride(media::VideoFrame::kVPlane) * | |
388 video_frame->rows(media::VideoFrame::kVPlane)); | |
389 | |
390 uint8 alpha_value = is_transparent ? 0 : 128; | |
391 CreateTestYUVVideoDrawQuad_FromVideoFrame( | |
392 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass, | |
393 video_resource_updater, rect, resource_provider); | |
394 } | 152 } |
395 | 153 |
396 typedef ::testing::Types<GLRenderer, | 154 typedef ::testing::Types<GLRenderer, |
397 SoftwareRenderer, | 155 SoftwareRenderer, |
398 GLRendererWithExpandedViewport, | 156 GLRendererWithExpandedViewport, |
399 SoftwareRendererWithExpandedViewport> RendererTypes; | 157 SoftwareRendererWithExpandedViewport> RendererTypes; |
400 TYPED_TEST_CASE(RendererPixelTest, RendererTypes); | 158 TYPED_TEST_CASE(RendererPixelTest, RendererTypes); |
401 | 159 |
402 template <typename RendererType> | 160 template <typename RendererType> |
403 class SoftwareRendererPixelTest : public RendererPixelTest<RendererType> {}; | 161 class SoftwareRendererPixelTest : public RendererPixelTest<RendererType> {}; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 | 316 |
559 RenderPassList pass_list; | 317 RenderPassList pass_list; |
560 pass_list.push_back(pass.Pass()); | 318 pass_list.push_back(pass.Pass()); |
561 | 319 |
562 EXPECT_TRUE(this->RunPixelTest( | 320 EXPECT_TRUE(this->RunPixelTest( |
563 &pass_list, | 321 &pass_list, |
564 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), | 322 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), |
565 FuzzyPixelOffByOneComparator(true))); | 323 FuzzyPixelOffByOneComparator(true))); |
566 } | 324 } |
567 | 325 |
568 template <typename QuadType> | |
569 static const base::FilePath::CharType* IntersectingQuadImage() { | |
570 return FILE_PATH_LITERAL("intersecting_blue_green_squares.png"); | |
571 } | |
572 template <> | |
573 const base::FilePath::CharType* IntersectingQuadImage<SolidColorDrawQuad>() { | |
574 return FILE_PATH_LITERAL("intersecting_blue_green.png"); | |
575 } | |
576 template <> | |
577 const base::FilePath::CharType* IntersectingQuadImage<YUVVideoDrawQuad>() { | |
578 return FILE_PATH_LITERAL("intersecting_blue_green_squares_video.png"); | |
579 } | |
580 | |
581 template <typename TypeParam> | |
582 class IntersectingQuadPixelTest : public RendererPixelTest<TypeParam> { | |
583 protected: | |
584 void SetupQuadStateAndRenderPass() { | |
585 // This sets up a pair of draw quads. They are both rotated | |
586 // relative to the root plane, they are also rotated relative to each other. | |
587 // The intersect in the middle at a non-perpendicular angle so that any | |
588 // errors are hopefully magnified. | |
589 // The quads should intersect correctly, as in the front quad should only | |
590 // be partially in front of the back quad, and partially behind. | |
591 | |
592 viewport_rect_ = gfx::Rect(this->device_viewport_size_); | |
593 quad_rect_ = gfx::Rect(0, 0, this->device_viewport_size_.width(), | |
594 this->device_viewport_size_.height() / 2.0); | |
595 | |
596 RenderPassId id(1, 1); | |
597 render_pass_ = CreateTestRootRenderPass(id, viewport_rect_); | |
598 | |
599 // Create the front quad rotated on the Z and Y axis. | |
600 gfx::Transform trans; | |
601 trans.Translate3d(0, 0, 0.707 * this->device_viewport_size_.width() / 2.0); | |
602 trans.RotateAboutZAxis(45.0); | |
603 trans.RotateAboutYAxis(45.0); | |
604 front_quad_state_ = | |
605 CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get()); | |
606 front_quad_state_->clip_rect = quad_rect_; | |
607 // Make sure they end up in a 3d sorting context. | |
608 front_quad_state_->sorting_context_id = 1; | |
609 | |
610 // Create the back quad, and rotate on just the y axis. This will intersect | |
611 // the first quad partially. | |
612 trans = gfx::Transform(); | |
613 trans.Translate3d(0, 0, -0.707 * this->device_viewport_size_.width() / 2.0); | |
614 trans.RotateAboutYAxis(-45.0); | |
615 back_quad_state_ = | |
616 CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get()); | |
617 back_quad_state_->sorting_context_id = 1; | |
618 back_quad_state_->clip_rect = quad_rect_; | |
619 } | |
620 template <typename T> | |
621 void AppendBackgroundAndRunTest(const PixelComparator& comparator) { | |
622 SharedQuadState* background_quad_state = CreateTestSharedQuadState( | |
623 gfx::Transform(), viewport_rect_, render_pass_.get()); | |
624 SolidColorDrawQuad* background_quad = | |
625 render_pass_->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
626 background_quad->SetNew(background_quad_state, viewport_rect_, | |
627 viewport_rect_, SK_ColorWHITE, false); | |
628 pass_list_.push_back(render_pass_.Pass()); | |
629 const base::FilePath::CharType* fileName = IntersectingQuadImage<T>(); | |
630 EXPECT_TRUE( | |
631 this->RunPixelTest(&pass_list_, base::FilePath(fileName), comparator)); | |
632 } | |
633 template <typename T> | |
634 T* CreateAndAppendDrawQuad() { | |
635 return render_pass_->CreateAndAppendDrawQuad<T>(); | |
636 } | |
637 | |
638 scoped_ptr<RenderPass> render_pass_; | |
639 gfx::Rect viewport_rect_; | |
640 SharedQuadState* front_quad_state_; | |
641 SharedQuadState* back_quad_state_; | |
642 gfx::Rect quad_rect_; | |
643 RenderPassList pass_list_; | |
644 }; | |
645 | |
646 template <typename TypeParam> | |
647 class IntersectingQuadGLPixelTest | |
648 : public IntersectingQuadPixelTest<TypeParam> { | |
649 public: | |
650 void SetUp() override { | |
651 IntersectingQuadPixelTest<TypeParam>::SetUp(); | |
652 video_resource_updater_.reset( | |
653 new VideoResourceUpdater(this->output_surface_->context_provider(), | |
654 this->resource_provider_.get())); | |
655 video_resource_updater2_.reset( | |
656 new VideoResourceUpdater(this->output_surface_->context_provider(), | |
657 this->resource_provider_.get())); | |
658 } | |
659 | |
660 protected: | |
661 scoped_ptr<VideoResourceUpdater> video_resource_updater_; | |
662 scoped_ptr<VideoResourceUpdater> video_resource_updater2_; | |
663 }; | |
664 | |
665 template <typename TypeParam> | |
666 class IntersectingQuadSoftwareTest | |
667 : public IntersectingQuadPixelTest<TypeParam> {}; | |
668 | |
669 typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport> | |
670 SoftwareRendererTypes; | |
671 typedef ::testing::Types<GLRenderer, GLRendererWithExpandedViewport> | |
672 GLRendererTypes; | |
673 | |
674 TYPED_TEST_CASE(IntersectingQuadPixelTest, RendererTypes); | |
675 TYPED_TEST_CASE(IntersectingQuadGLPixelTest, GLRendererTypes); | |
676 TYPED_TEST_CASE(IntersectingQuadSoftwareTest, SoftwareRendererTypes); | |
677 | |
678 TYPED_TEST(IntersectingQuadPixelTest, SolidColorQuads) { | |
679 this->SetupQuadStateAndRenderPass(); | |
680 | |
681 SolidColorDrawQuad* quad = | |
682 this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
683 SolidColorDrawQuad* quad2 = | |
684 this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | |
685 | |
686 quad->SetNew(this->front_quad_state_, this->quad_rect_, this->quad_rect_, | |
687 SK_ColorBLUE, false); | |
688 quad2->SetNew(this->back_quad_state_, this->quad_rect_, this->quad_rect_, | |
689 SK_ColorGREEN, false); | |
690 SCOPED_TRACE("IntersectingSolidColorQuads"); | |
691 this->template AppendBackgroundAndRunTest<SolidColorDrawQuad>( | |
692 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)); | |
693 } | |
694 | |
695 template <typename TypeParam> | |
696 SkColor GetColor(const SkColor& color) { | |
697 return color; | |
698 } | |
699 | |
700 template <> | |
701 SkColor GetColor<GLRenderer>(const SkColor& color) { | |
702 return SkColorSetARGB(SkColorGetA(color), SkColorGetB(color), | |
703 SkColorGetG(color), SkColorGetR(color)); | |
704 } | |
705 template <> | |
706 SkColor GetColor<GLRendererWithExpandedViewport>(const SkColor& color) { | |
707 return GetColor<GLRenderer>(color); | |
708 } | |
709 | |
710 TYPED_TEST(IntersectingQuadPixelTest, TexturedQuads) { | |
711 this->SetupQuadStateAndRenderPass(); | |
712 CreateTestTwoColoredTextureDrawQuad( | |
713 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), | |
714 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT, | |
715 true, this->front_quad_state_, this->resource_provider_.get(), | |
716 this->render_pass_.get()); | |
717 CreateTestTwoColoredTextureDrawQuad( | |
718 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)), | |
719 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT, | |
720 true, this->back_quad_state_, this->resource_provider_.get(), | |
721 this->render_pass_.get()); | |
722 | |
723 SCOPED_TRACE("IntersectingTexturedQuads"); | |
724 this->template AppendBackgroundAndRunTest<TextureDrawQuad>( | |
725 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)); | |
726 } | |
727 | |
728 TYPED_TEST(IntersectingQuadSoftwareTest, PictureQuads) { | |
729 this->SetupQuadStateAndRenderPass(); | |
730 gfx::RectF outer_rect(this->quad_rect_); | |
731 gfx::RectF inner_rect(this->quad_rect_.x() + (this->quad_rect_.width() / 4), | |
732 this->quad_rect_.y() + (this->quad_rect_.height() / 4), | |
733 this->quad_rect_.width() / 2, | |
734 this->quad_rect_.height() / 2); | |
735 | |
736 SkPaint black_paint; | |
737 black_paint.setColor(SK_ColorBLACK); | |
738 SkPaint blue_paint; | |
739 blue_paint.setColor(SK_ColorBLUE); | |
740 SkPaint green_paint; | |
741 green_paint.setColor(SK_ColorGREEN); | |
742 | |
743 scoped_ptr<FakePicturePile> blue_recording = | |
744 FakePicturePile::CreateFilledPile(gfx::Size(1000, 1000), | |
745 this->quad_rect_.size()); | |
746 blue_recording->add_draw_rect_with_paint(outer_rect, black_paint); | |
747 blue_recording->add_draw_rect_with_paint(inner_rect, blue_paint); | |
748 blue_recording->RerecordPile(); | |
749 scoped_refptr<FakePicturePileImpl> blue_pile = | |
750 FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr); | |
751 | |
752 PictureDrawQuad* blue_quad = | |
753 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>(); | |
754 | |
755 blue_quad->SetNew(this->front_quad_state_, this->quad_rect_, gfx::Rect(), | |
756 this->quad_rect_, this->quad_rect_, this->quad_rect_.size(), | |
757 false, RGBA_8888, this->quad_rect_, 1.f, blue_pile); | |
758 | |
759 scoped_ptr<FakePicturePile> green_recording = | |
760 FakePicturePile::CreateFilledPile(this->quad_rect_.size(), | |
761 this->quad_rect_.size()); | |
762 green_recording->add_draw_rect_with_paint(outer_rect, green_paint); | |
763 green_recording->add_draw_rect_with_paint(inner_rect, black_paint); | |
764 green_recording->RerecordPile(); | |
765 scoped_refptr<FakePicturePileImpl> green_pile = | |
766 FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr); | |
767 | |
768 PictureDrawQuad* green_quad = | |
769 this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>(); | |
770 green_quad->SetNew(this->back_quad_state_, this->quad_rect_, gfx::Rect(), | |
771 this->quad_rect_, this->quad_rect_, | |
772 this->quad_rect_.size(), false, RGBA_8888, | |
773 this->quad_rect_, 1.f, green_pile); | |
774 SCOPED_TRACE("IntersectingPictureQuadsPass"); | |
775 this->template AppendBackgroundAndRunTest<PictureDrawQuad>( | |
776 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)); | |
777 } | |
778 | |
779 TYPED_TEST(IntersectingQuadPixelTest, RenderPassQuads) { | |
780 this->SetupQuadStateAndRenderPass(); | |
781 RenderPassId child_pass_id1(2, 2); | |
782 RenderPassId child_pass_id2(2, 3); | |
783 scoped_ptr<RenderPass> child_pass1 = | |
784 CreateTestRenderPass(child_pass_id1, this->quad_rect_, gfx::Transform()); | |
785 SharedQuadState* child1_quad_state = CreateTestSharedQuadState( | |
786 gfx::Transform(), this->quad_rect_, child_pass1.get()); | |
787 scoped_ptr<RenderPass> child_pass2 = | |
788 CreateTestRenderPass(child_pass_id2, this->quad_rect_, gfx::Transform()); | |
789 SharedQuadState* child2_quad_state = CreateTestSharedQuadState( | |
790 gfx::Transform(), this->quad_rect_, child_pass2.get()); | |
791 | |
792 CreateTestTwoColoredTextureDrawQuad( | |
793 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), | |
794 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT, | |
795 true, child1_quad_state, this->resource_provider_.get(), | |
796 child_pass1.get()); | |
797 CreateTestTwoColoredTextureDrawQuad( | |
798 this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)), | |
799 GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT, | |
800 true, child2_quad_state, this->resource_provider_.get(), | |
801 child_pass2.get()); | |
802 | |
803 CreateTestRenderPassDrawQuad(this->front_quad_state_, this->quad_rect_, | |
804 child_pass_id1, this->render_pass_.get()); | |
805 CreateTestRenderPassDrawQuad(this->back_quad_state_, this->quad_rect_, | |
806 child_pass_id2, this->render_pass_.get()); | |
807 | |
808 this->pass_list_.push_back(child_pass1.Pass()); | |
809 this->pass_list_.push_back(child_pass2.Pass()); | |
810 SCOPED_TRACE("IntersectingRenderQuadsPass"); | |
811 this->template AppendBackgroundAndRunTest<RenderPassDrawQuad>( | |
812 FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)); | |
813 } | |
814 | |
815 TYPED_TEST(IntersectingQuadGLPixelTest, YUVVideoQuads) { | |
816 this->SetupQuadStateAndRenderPass(); | |
817 gfx::Rect inner_rect( | |
818 ((this->quad_rect_.x() + (this->quad_rect_.width() / 4)) & ~0xF), | |
819 ((this->quad_rect_.y() + (this->quad_rect_.height() / 4)) & ~0xF), | |
820 (this->quad_rect_.width() / 2) & ~0xF, | |
821 (this->quad_rect_.height() / 2) & ~0xF); | |
822 | |
823 CreateTestYUVVideoDrawQuad_TwoColor( | |
824 this->front_quad_state_, media::VideoFrame::YV12J, false, | |
825 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(), 0, 128, 128, | |
826 inner_rect, 29, 255, 107, this->render_pass_.get(), | |
827 this->video_resource_updater_.get(), this->resource_provider_.get()); | |
828 | |
829 CreateTestYUVVideoDrawQuad_TwoColor( | |
830 this->back_quad_state_, media::VideoFrame::YV12J, false, | |
831 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(), 149, 43, 21, | |
832 inner_rect, 0, 128, 128, this->render_pass_.get(), | |
833 this->video_resource_updater2_.get(), this->resource_provider_.get()); | |
834 | |
835 SCOPED_TRACE("IntersectingVideoQuads"); | |
836 this->template AppendBackgroundAndRunTest<YUVVideoDrawQuad>( | |
837 FuzzyPixelOffByOneComparator(false)); | |
838 } | |
839 | |
840 // TODO(skaslev): The software renderer does not support non-premultplied alpha. | 326 // TODO(skaslev): The software renderer does not support non-premultplied alpha. |
841 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) { | 327 TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) { |
842 gfx::Rect rect(this->device_viewport_size_); | 328 gfx::Rect rect(this->device_viewport_size_); |
843 | 329 |
844 RenderPassId id(1, 1); | 330 RenderPassId id(1, 1); |
845 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 331 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
846 | 332 |
847 SharedQuadState* shared_state = | 333 SharedQuadState* shared_state = |
848 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 334 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
849 | 335 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 pass_list.push_back(pass.Pass()); | 383 pass_list.push_back(pass.Pass()); |
898 | 384 |
899 EXPECT_TRUE(this->RunPixelTest( | 385 EXPECT_TRUE(this->RunPixelTest( |
900 &pass_list, | 386 &pass_list, |
901 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), | 387 base::FilePath(FILE_PATH_LITERAL("green_alpha.png")), |
902 FuzzyPixelOffByOneComparator(true))); | 388 FuzzyPixelOffByOneComparator(true))); |
903 } | 389 } |
904 | 390 |
905 class VideoGLRendererPixelTest : public GLRendererPixelTest { | 391 class VideoGLRendererPixelTest : public GLRendererPixelTest { |
906 protected: | 392 protected: |
| 393 void CreateTestYUVVideoDrawQuad_Striped(const SharedQuadState* shared_state, |
| 394 media::VideoFrame::Format format, |
| 395 bool is_transparent, |
| 396 const gfx::RectF& tex_coord_rect, |
| 397 RenderPass* render_pass) { |
| 398 const gfx::Rect rect(this->device_viewport_size_); |
| 399 |
| 400 scoped_refptr<media::VideoFrame> video_frame = |
| 401 media::VideoFrame::CreateFrame( |
| 402 format, rect.size(), rect, rect.size(), base::TimeDelta()); |
| 403 |
| 404 // YUV values representing a striped pattern, for validating texture |
| 405 // coordinates for sampling. |
| 406 uint8_t y_value = 0; |
| 407 uint8_t u_value = 0; |
| 408 uint8_t v_value = 0; |
| 409 for (int i = 0; i < video_frame->rows(media::VideoFrame::kYPlane); ++i) { |
| 410 uint8_t* y_row = video_frame->data(media::VideoFrame::kYPlane) + |
| 411 video_frame->stride(media::VideoFrame::kYPlane) * i; |
| 412 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kYPlane); |
| 413 ++j) { |
| 414 y_row[j] = (y_value += 1); |
| 415 } |
| 416 } |
| 417 for (int i = 0; i < video_frame->rows(media::VideoFrame::kUPlane); ++i) { |
| 418 uint8_t* u_row = video_frame->data(media::VideoFrame::kUPlane) + |
| 419 video_frame->stride(media::VideoFrame::kUPlane) * i; |
| 420 uint8_t* v_row = video_frame->data(media::VideoFrame::kVPlane) + |
| 421 video_frame->stride(media::VideoFrame::kVPlane) * i; |
| 422 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kUPlane); |
| 423 ++j) { |
| 424 u_row[j] = (u_value += 3); |
| 425 v_row[j] = (v_value += 5); |
| 426 } |
| 427 } |
| 428 uint8 alpha_value = is_transparent ? 0 : 128; |
| 429 CreateTestYUVVideoDrawQuad_FromVideoFrame( |
| 430 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass); |
| 431 } |
| 432 |
| 433 void CreateTestYUVVideoDrawQuad_Solid(const SharedQuadState* shared_state, |
| 434 media::VideoFrame::Format format, |
| 435 bool is_transparent, |
| 436 const gfx::RectF& tex_coord_rect, |
| 437 uint8 y, |
| 438 uint8 u, |
| 439 uint8 v, |
| 440 RenderPass* render_pass) { |
| 441 const gfx::Rect rect(this->device_viewport_size_); |
| 442 |
| 443 scoped_refptr<media::VideoFrame> video_frame = |
| 444 media::VideoFrame::CreateFrame( |
| 445 format, rect.size(), rect, rect.size(), base::TimeDelta()); |
| 446 |
| 447 // YUV values of a solid, constant, color. Useful for testing that color |
| 448 // space/color range are being handled properly. |
| 449 memset(video_frame->data(media::VideoFrame::kYPlane), |
| 450 y, |
| 451 video_frame->stride(media::VideoFrame::kYPlane) * |
| 452 video_frame->rows(media::VideoFrame::kYPlane)); |
| 453 memset(video_frame->data(media::VideoFrame::kUPlane), |
| 454 u, |
| 455 video_frame->stride(media::VideoFrame::kUPlane) * |
| 456 video_frame->rows(media::VideoFrame::kUPlane)); |
| 457 memset(video_frame->data(media::VideoFrame::kVPlane), |
| 458 v, |
| 459 video_frame->stride(media::VideoFrame::kVPlane) * |
| 460 video_frame->rows(media::VideoFrame::kVPlane)); |
| 461 |
| 462 uint8 alpha_value = is_transparent ? 0 : 128; |
| 463 CreateTestYUVVideoDrawQuad_FromVideoFrame( |
| 464 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass); |
| 465 } |
| 466 |
907 void CreateEdgeBleedPass(media::VideoFrame::Format format, | 467 void CreateEdgeBleedPass(media::VideoFrame::Format format, |
908 RenderPassList* pass_list) { | 468 RenderPassList* pass_list) { |
909 gfx::Rect rect(200, 200); | 469 gfx::Rect rect(200, 200); |
910 | 470 |
911 RenderPassId id(1, 1); | 471 RenderPassId id(1, 1); |
912 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 472 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
913 | 473 |
914 // Scale the video up so that bilinear filtering kicks in to sample more | 474 // Scale the video up so that bilinear filtering kicks in to sample more |
915 // than just nearest neighbor would. | 475 // than just nearest neighbor would. |
916 gfx::Transform scale_by_2; | 476 gfx::Transform scale_by_2; |
917 scale_by_2.Scale(2.f, 2.f); | 477 scale_by_2.Scale(2.f, 2.f); |
918 gfx::Rect half_rect(100, 100); | 478 gfx::Rect half_rect(100, 100); |
919 SharedQuadState* shared_state = | 479 SharedQuadState* shared_state = |
920 CreateTestSharedQuadState(scale_by_2, half_rect, pass.get()); | 480 CreateTestSharedQuadState(scale_by_2, half_rect, pass.get()); |
921 | 481 |
922 gfx::Size background_size(200, 200); | 482 gfx::Size background_size(200, 200); |
923 gfx::Rect green_rect(16, 20, 100, 100); | 483 gfx::Rect green_rect(16, 20, 100, 100); |
924 gfx::RectF tex_coord_rect( | 484 gfx::RectF tex_coord_rect( |
925 static_cast<float>(green_rect.x()) / background_size.width(), | 485 static_cast<float>(green_rect.x()) / background_size.width(), |
926 static_cast<float>(green_rect.y()) / background_size.height(), | 486 static_cast<float>(green_rect.y()) / background_size.height(), |
927 static_cast<float>(green_rect.width()) / background_size.width(), | 487 static_cast<float>(green_rect.width()) / background_size.width(), |
928 static_cast<float>(green_rect.height()) / background_size.height()); | 488 static_cast<float>(green_rect.height()) / background_size.height()); |
929 | 489 |
930 // YUV of (149,43,21) should be green (0,255,0) in RGB. | 490 // YUV of (149,43,21) should be green (0,255,0) in RGB. |
931 // Create a video frame that has a non-green background rect, with a | 491 // Create a video frame that has a non-green background rect, with a |
932 // green sub-rectangle that should be the only thing displayed in | 492 // green sub-rectangle that should be the only thing displayed in |
933 // the final image. Bleeding will appear on all four sides of the video | 493 // the final image. Bleeding will appear on all four sides of the video |
934 // if the tex coords are not clamped. | 494 // if the tex coords are not clamped. |
935 CreateTestYUVVideoDrawQuad_TwoColor( | 495 CreateTestYUVVideoDrawQuad_TwoColor(shared_state, format, false, |
936 shared_state, format, false, tex_coord_rect, background_size, 0, 0, 0, | 496 tex_coord_rect, background_size, 0, 0, |
937 green_rect, 149, 43, 21, pass.get(), video_resource_updater_.get(), | 497 0, green_rect, 149, 43, 21, pass.get()); |
938 resource_provider_.get()); | |
939 pass_list->push_back(pass.Pass()); | 498 pass_list->push_back(pass.Pass()); |
940 } | 499 } |
941 | 500 |
| 501 // Creates a video frame of size background_size filled with yuv_background, |
| 502 // and then draws a foreground rectangle in a different color on top of |
| 503 // that. The foreground rectangle must have coordinates that are divisible |
| 504 // by 2 because YUV is a block format. |
| 505 void CreateTestYUVVideoDrawQuad_TwoColor(const SharedQuadState* shared_state, |
| 506 media::VideoFrame::Format format, |
| 507 bool is_transparent, |
| 508 const gfx::RectF& tex_coord_rect, |
| 509 const gfx::Size& background_size, |
| 510 uint8 y_background, |
| 511 uint8 u_background, |
| 512 uint8 v_background, |
| 513 const gfx::Rect& foreground_rect, |
| 514 uint8 y_foreground, |
| 515 uint8 u_foreground, |
| 516 uint8 v_foreground, |
| 517 RenderPass* render_pass) { |
| 518 const gfx::Rect rect(background_size); |
| 519 |
| 520 scoped_refptr<media::VideoFrame> video_frame = |
| 521 media::VideoFrame::CreateFrame(format, background_size, foreground_rect, |
| 522 foreground_rect.size(), |
| 523 base::TimeDelta()); |
| 524 |
| 525 int planes[] = {media::VideoFrame::kYPlane, |
| 526 media::VideoFrame::kUPlane, |
| 527 media::VideoFrame::kVPlane}; |
| 528 uint8 yuv_background[] = {y_background, u_background, v_background}; |
| 529 uint8 yuv_foreground[] = {y_foreground, u_foreground, v_foreground}; |
| 530 int sample_size[] = {1, 2, 2}; |
| 531 |
| 532 for (int i = 0; i < 3; ++i) { |
| 533 memset(video_frame->data(planes[i]), yuv_background[i], |
| 534 video_frame->stride(planes[i]) * video_frame->rows(planes[i])); |
| 535 } |
| 536 |
| 537 for (int i = 0; i < 3; ++i) { |
| 538 // Since yuv encoding uses block encoding, widths have to be divisible |
| 539 // by the sample size in order for this function to behave properly. |
| 540 DCHECK_EQ(foreground_rect.x() % sample_size[i], 0); |
| 541 DCHECK_EQ(foreground_rect.y() % sample_size[i], 0); |
| 542 DCHECK_EQ(foreground_rect.width() % sample_size[i], 0); |
| 543 DCHECK_EQ(foreground_rect.height() % sample_size[i], 0); |
| 544 |
| 545 gfx::Rect sample_rect(foreground_rect.x() / sample_size[i], |
| 546 foreground_rect.y() / sample_size[i], |
| 547 foreground_rect.width() / sample_size[i], |
| 548 foreground_rect.height() / sample_size[i]); |
| 549 for (int y = sample_rect.y(); y < sample_rect.bottom(); ++y) { |
| 550 for (int x = sample_rect.x(); x < sample_rect.right(); ++x) { |
| 551 size_t offset = y * video_frame->stride(planes[i]) + x; |
| 552 video_frame->data(planes[i])[offset] = yuv_foreground[i]; |
| 553 } |
| 554 } |
| 555 } |
| 556 |
| 557 uint8 alpha_value = 255; |
| 558 CreateTestYUVVideoDrawQuad_FromVideoFrame( |
| 559 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass); |
| 560 } |
| 561 |
| 562 void CreateTestYUVVideoDrawQuad_FromVideoFrame( |
| 563 const SharedQuadState* shared_state, |
| 564 scoped_refptr<media::VideoFrame> video_frame, |
| 565 uint8 alpha_value, |
| 566 const gfx::RectF& tex_coord_rect, |
| 567 RenderPass* render_pass) { |
| 568 const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A); |
| 569 const YUVVideoDrawQuad::ColorSpace color_space = |
| 570 (video_frame->format() == media::VideoFrame::YV12J |
| 571 ? YUVVideoDrawQuad::JPEG |
| 572 : YUVVideoDrawQuad::REC_601); |
| 573 const gfx::Rect rect(shared_state->content_bounds); |
| 574 const gfx::Rect opaque_rect(0, 0, 0, 0); |
| 575 |
| 576 if (with_alpha) |
| 577 memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value, |
| 578 video_frame->stride(media::VideoFrame::kAPlane) * |
| 579 video_frame->rows(media::VideoFrame::kAPlane)); |
| 580 |
| 581 VideoFrameExternalResources resources = |
| 582 video_resource_updater_->CreateExternalResourcesFromVideoFrame( |
| 583 video_frame); |
| 584 |
| 585 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type); |
| 586 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()), |
| 587 resources.mailboxes.size()); |
| 588 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()), |
| 589 resources.release_callbacks.size()); |
| 590 |
| 591 ResourceProvider::ResourceId y_resource = |
| 592 resource_provider_->CreateResourceFromTextureMailbox( |
| 593 resources.mailboxes[media::VideoFrame::kYPlane], |
| 594 SingleReleaseCallbackImpl::Create( |
| 595 resources.release_callbacks[media::VideoFrame::kYPlane])); |
| 596 ResourceProvider::ResourceId u_resource = |
| 597 resource_provider_->CreateResourceFromTextureMailbox( |
| 598 resources.mailboxes[media::VideoFrame::kUPlane], |
| 599 SingleReleaseCallbackImpl::Create( |
| 600 resources.release_callbacks[media::VideoFrame::kUPlane])); |
| 601 ResourceProvider::ResourceId v_resource = |
| 602 resource_provider_->CreateResourceFromTextureMailbox( |
| 603 resources.mailboxes[media::VideoFrame::kVPlane], |
| 604 SingleReleaseCallbackImpl::Create( |
| 605 resources.release_callbacks[media::VideoFrame::kVPlane])); |
| 606 ResourceProvider::ResourceId a_resource = 0; |
| 607 if (with_alpha) { |
| 608 a_resource = resource_provider_->CreateResourceFromTextureMailbox( |
| 609 resources.mailboxes[media::VideoFrame::kAPlane], |
| 610 SingleReleaseCallbackImpl::Create( |
| 611 resources.release_callbacks[media::VideoFrame::kAPlane])); |
| 612 } |
| 613 |
| 614 YUVVideoDrawQuad* yuv_quad = |
| 615 render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>(); |
| 616 yuv_quad->SetNew(shared_state, rect, opaque_rect, rect, tex_coord_rect, |
| 617 video_frame->coded_size(), y_resource, u_resource, |
| 618 v_resource, a_resource, color_space); |
| 619 } |
| 620 |
942 void SetUp() override { | 621 void SetUp() override { |
943 GLRendererPixelTest::SetUp(); | 622 GLRendererPixelTest::SetUp(); |
944 video_resource_updater_.reset(new VideoResourceUpdater( | 623 video_resource_updater_.reset(new VideoResourceUpdater( |
945 output_surface_->context_provider(), resource_provider_.get())); | 624 output_surface_->context_provider(), resource_provider_.get())); |
946 } | 625 } |
947 | 626 |
| 627 private: |
948 scoped_ptr<VideoResourceUpdater> video_resource_updater_; | 628 scoped_ptr<VideoResourceUpdater> video_resource_updater_; |
949 }; | 629 }; |
950 | 630 |
951 TEST_F(VideoGLRendererPixelTest, SimpleYUVRect) { | 631 TEST_F(VideoGLRendererPixelTest, SimpleYUVRect) { |
952 gfx::Rect rect(this->device_viewport_size_); | 632 gfx::Rect rect(this->device_viewport_size_); |
953 | 633 |
954 RenderPassId id(1, 1); | 634 RenderPassId id(1, 1); |
955 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 635 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
956 | 636 |
957 SharedQuadState* shared_state = | 637 SharedQuadState* shared_state = |
958 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 638 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
959 | 639 |
960 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::VideoFrame::YV12, | 640 CreateTestYUVVideoDrawQuad_Striped(shared_state, |
961 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), | 641 media::VideoFrame::YV12, |
962 pass.get(), video_resource_updater_.get(), | 642 false, |
963 rect, resource_provider_.get()); | 643 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), |
| 644 pass.get()); |
964 | 645 |
965 RenderPassList pass_list; | 646 RenderPassList pass_list; |
966 pass_list.push_back(pass.Pass()); | 647 pass_list.push_back(pass.Pass()); |
967 | 648 |
968 EXPECT_TRUE( | 649 EXPECT_TRUE( |
969 this->RunPixelTest(&pass_list, | 650 this->RunPixelTest(&pass_list, |
970 base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")), | 651 base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")), |
971 FuzzyPixelOffByOneComparator(true))); | 652 FuzzyPixelOffByOneComparator(true))); |
972 } | 653 } |
973 | 654 |
974 TEST_F(VideoGLRendererPixelTest, OffsetYUVRect) { | 655 TEST_F(VideoGLRendererPixelTest, OffsetYUVRect) { |
975 gfx::Rect rect(this->device_viewport_size_); | 656 gfx::Rect rect(this->device_viewport_size_); |
976 | 657 |
977 RenderPassId id(1, 1); | 658 RenderPassId id(1, 1); |
978 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 659 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
979 | 660 |
980 SharedQuadState* shared_state = | 661 SharedQuadState* shared_state = |
981 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 662 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
982 | 663 |
983 // Intentionally sets frame format to I420 for testing coverage. | 664 // Intentionally sets frame format to I420 for testing coverage. |
984 CreateTestYUVVideoDrawQuad_Striped( | 665 CreateTestYUVVideoDrawQuad_Striped(shared_state, |
985 shared_state, media::VideoFrame::I420, false, | 666 media::VideoFrame::I420, |
986 gfx::RectF(0.125f, 0.25f, 0.75f, 0.5f), pass.get(), | 667 false, |
987 video_resource_updater_.get(), rect, resource_provider_.get()); | 668 gfx::RectF(0.125f, 0.25f, 0.75f, 0.5f), |
| 669 pass.get()); |
988 | 670 |
989 RenderPassList pass_list; | 671 RenderPassList pass_list; |
990 pass_list.push_back(pass.Pass()); | 672 pass_list.push_back(pass.Pass()); |
991 | 673 |
992 EXPECT_TRUE(this->RunPixelTest( | 674 EXPECT_TRUE(this->RunPixelTest( |
993 &pass_list, | 675 &pass_list, |
994 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_offset.png")), | 676 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_offset.png")), |
995 FuzzyPixelOffByOneComparator(true))); | 677 FuzzyPixelOffByOneComparator(true))); |
996 } | 678 } |
997 | 679 |
998 TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) { | 680 TEST_F(VideoGLRendererPixelTest, SimpleYUVRectBlack) { |
999 gfx::Rect rect(this->device_viewport_size_); | 681 gfx::Rect rect(this->device_viewport_size_); |
1000 | 682 |
1001 RenderPassId id(1, 1); | 683 RenderPassId id(1, 1); |
1002 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 684 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
1003 | 685 |
1004 SharedQuadState* shared_state = | 686 SharedQuadState* shared_state = |
1005 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 687 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
1006 | 688 |
1007 // In MPEG color range YUV values of (15,128,128) should produce black. | 689 // In MPEG color range YUV values of (15,128,128) should produce black. |
1008 CreateTestYUVVideoDrawQuad_Solid( | 690 CreateTestYUVVideoDrawQuad_Solid(shared_state, |
1009 shared_state, media::VideoFrame::YV12, false, | 691 media::VideoFrame::YV12, |
1010 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(), | 692 false, |
1011 video_resource_updater_.get(), rect, resource_provider_.get()); | 693 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), |
| 694 15, |
| 695 128, |
| 696 128, |
| 697 pass.get()); |
1012 | 698 |
1013 RenderPassList pass_list; | 699 RenderPassList pass_list; |
1014 pass_list.push_back(pass.Pass()); | 700 pass_list.push_back(pass.Pass()); |
1015 | 701 |
1016 // If we didn't get black out of the YUV values above, then we probably have a | 702 // If we didn't get black out of the YUV values above, then we probably have a |
1017 // color range issue. | 703 // color range issue. |
1018 EXPECT_TRUE(this->RunPixelTest(&pass_list, | 704 EXPECT_TRUE(this->RunPixelTest(&pass_list, |
1019 base::FilePath(FILE_PATH_LITERAL("black.png")), | 705 base::FilePath(FILE_PATH_LITERAL("black.png")), |
1020 FuzzyPixelOffByOneComparator(true))); | 706 FuzzyPixelOffByOneComparator(true))); |
1021 } | 707 } |
1022 | 708 |
1023 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) { | 709 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) { |
1024 gfx::Rect rect(this->device_viewport_size_); | 710 gfx::Rect rect(this->device_viewport_size_); |
1025 | 711 |
1026 RenderPassId id(1, 1); | 712 RenderPassId id(1, 1); |
1027 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 713 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
1028 | 714 |
1029 SharedQuadState* shared_state = | 715 SharedQuadState* shared_state = |
1030 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 716 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
1031 | 717 |
1032 // YUV of (149,43,21) should be green (0,255,0) in RGB. | 718 // YUV of (149,43,21) should be green (0,255,0) in RGB. |
1033 CreateTestYUVVideoDrawQuad_Solid( | 719 CreateTestYUVVideoDrawQuad_Solid(shared_state, |
1034 shared_state, media::VideoFrame::YV12J, false, | 720 media::VideoFrame::YV12J, |
1035 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(), | 721 false, |
1036 video_resource_updater_.get(), rect, resource_provider_.get()); | 722 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), |
| 723 149, |
| 724 43, |
| 725 21, |
| 726 pass.get()); |
1037 | 727 |
1038 RenderPassList pass_list; | 728 RenderPassList pass_list; |
1039 pass_list.push_back(pass.Pass()); | 729 pass_list.push_back(pass.Pass()); |
1040 | 730 |
1041 EXPECT_TRUE(this->RunPixelTest(&pass_list, | 731 EXPECT_TRUE(this->RunPixelTest(&pass_list, |
1042 base::FilePath(FILE_PATH_LITERAL("green.png")), | 732 base::FilePath(FILE_PATH_LITERAL("green.png")), |
1043 FuzzyPixelOffByOneComparator(true))); | 733 FuzzyPixelOffByOneComparator(true))); |
1044 } | 734 } |
1045 | 735 |
1046 // Test that a YUV video doesn't bleed outside of its tex coords when the | 736 // Test that a YUV video doesn't bleed outside of its tex coords when the |
(...skipping 17 matching lines...) Expand all Loading... |
1064 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) { | 754 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) { |
1065 gfx::Rect rect(this->device_viewport_size_); | 755 gfx::Rect rect(this->device_viewport_size_); |
1066 | 756 |
1067 RenderPassId id(1, 1); | 757 RenderPassId id(1, 1); |
1068 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 758 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
1069 | 759 |
1070 SharedQuadState* shared_state = | 760 SharedQuadState* shared_state = |
1071 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 761 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
1072 | 762 |
1073 // Dark grey in JPEG color range (in MPEG, this is black). | 763 // Dark grey in JPEG color range (in MPEG, this is black). |
1074 CreateTestYUVVideoDrawQuad_Solid( | 764 CreateTestYUVVideoDrawQuad_Solid(shared_state, |
1075 shared_state, media::VideoFrame::YV12J, false, | 765 media::VideoFrame::YV12J, |
1076 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 15, 128, 128, pass.get(), | 766 false, |
1077 video_resource_updater_.get(), rect, resource_provider_.get()); | 767 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), |
| 768 15, |
| 769 128, |
| 770 128, |
| 771 pass.get()); |
1078 | 772 |
1079 RenderPassList pass_list; | 773 RenderPassList pass_list; |
1080 pass_list.push_back(pass.Pass()); | 774 pass_list.push_back(pass.Pass()); |
1081 | 775 |
1082 EXPECT_TRUE( | 776 EXPECT_TRUE( |
1083 this->RunPixelTest(&pass_list, | 777 this->RunPixelTest(&pass_list, |
1084 base::FilePath(FILE_PATH_LITERAL("dark_grey.png")), | 778 base::FilePath(FILE_PATH_LITERAL("dark_grey.png")), |
1085 FuzzyPixelOffByOneComparator(true))); | 779 FuzzyPixelOffByOneComparator(true))); |
1086 } | 780 } |
1087 | 781 |
1088 TEST_F(VideoGLRendererPixelTest, SimpleYUVARect) { | 782 TEST_F(VideoGLRendererPixelTest, SimpleYUVARect) { |
1089 gfx::Rect rect(this->device_viewport_size_); | 783 gfx::Rect rect(this->device_viewport_size_); |
1090 | 784 |
1091 RenderPassId id(1, 1); | 785 RenderPassId id(1, 1); |
1092 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 786 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
1093 | 787 |
1094 SharedQuadState* shared_state = | 788 SharedQuadState* shared_state = |
1095 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 789 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
1096 | 790 |
1097 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::VideoFrame::YV12A, | 791 CreateTestYUVVideoDrawQuad_Striped(shared_state, |
1098 false, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), | 792 media::VideoFrame::YV12A, |
1099 pass.get(), video_resource_updater_.get(), | 793 false, |
1100 rect, resource_provider_.get()); | 794 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), |
| 795 pass.get()); |
1101 | 796 |
1102 SolidColorDrawQuad* color_quad = | 797 SolidColorDrawQuad* color_quad = |
1103 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 798 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); |
1104 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false); | 799 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false); |
1105 | 800 |
1106 RenderPassList pass_list; | 801 RenderPassList pass_list; |
1107 pass_list.push_back(pass.Pass()); | 802 pass_list.push_back(pass.Pass()); |
1108 | 803 |
1109 EXPECT_TRUE(this->RunPixelTest( | 804 EXPECT_TRUE(this->RunPixelTest( |
1110 &pass_list, | 805 &pass_list, |
1111 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_alpha.png")), | 806 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_alpha.png")), |
1112 FuzzyPixelOffByOneComparator(true))); | 807 FuzzyPixelOffByOneComparator(true))); |
1113 } | 808 } |
1114 | 809 |
1115 TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) { | 810 TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) { |
1116 gfx::Rect rect(this->device_viewport_size_); | 811 gfx::Rect rect(this->device_viewport_size_); |
1117 | 812 |
1118 RenderPassId id(1, 1); | 813 RenderPassId id(1, 1); |
1119 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 814 scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
1120 | 815 |
1121 SharedQuadState* shared_state = | 816 SharedQuadState* shared_state = |
1122 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 817 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
1123 | 818 |
1124 CreateTestYUVVideoDrawQuad_Striped(shared_state, media::VideoFrame::YV12A, | 819 CreateTestYUVVideoDrawQuad_Striped(shared_state, |
1125 true, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), | 820 media::VideoFrame::YV12A, |
1126 pass.get(), video_resource_updater_.get(), | 821 true, |
1127 rect, resource_provider_.get()); | 822 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), |
| 823 pass.get()); |
1128 | 824 |
1129 SolidColorDrawQuad* color_quad = | 825 SolidColorDrawQuad* color_quad = |
1130 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); | 826 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); |
1131 color_quad->SetNew(shared_state, rect, rect, SK_ColorBLACK, false); | 827 color_quad->SetNew(shared_state, rect, rect, SK_ColorBLACK, false); |
1132 | 828 |
1133 RenderPassList pass_list; | 829 RenderPassList pass_list; |
1134 pass_list.push_back(pass.Pass()); | 830 pass_list.push_back(pass.Pass()); |
1135 | 831 |
1136 EXPECT_TRUE(this->RunPixelTest( | 832 EXPECT_TRUE(this->RunPixelTest( |
1137 &pass_list, | 833 &pass_list, |
(...skipping 1656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2794 EXPECT_TRUE(this->RunPixelTest( | 2490 EXPECT_TRUE(this->RunPixelTest( |
2795 &pass_list, | 2491 &pass_list, |
2796 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")), | 2492 base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")), |
2797 FuzzyPixelOffByOneComparator(true))); | 2493 FuzzyPixelOffByOneComparator(true))); |
2798 } | 2494 } |
2799 | 2495 |
2800 #endif // !defined(OS_ANDROID) | 2496 #endif // !defined(OS_ANDROID) |
2801 | 2497 |
2802 } // namespace | 2498 } // namespace |
2803 } // namespace cc | 2499 } // namespace cc |
OLD | NEW |