| 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 |