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