| 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 <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/strings/string_split.h" |
| 10 #include "cc/base/math_util.h" | 11 #include "cc/base/math_util.h" |
| 11 #include "cc/output/gl_renderer.h" | 12 #include "cc/output/gl_renderer.h" |
| 12 #include "cc/quads/draw_quad.h" | 13 #include "cc/quads/draw_quad.h" |
| 13 #include "cc/quads/picture_draw_quad.h" | 14 #include "cc/quads/picture_draw_quad.h" |
| 14 #include "cc/quads/texture_draw_quad.h" | 15 #include "cc/quads/texture_draw_quad.h" |
| 15 #include "cc/resources/video_resource_updater.h" | 16 #include "cc/resources/video_resource_updater.h" |
| 16 #include "cc/test/fake_raster_source.h" | 17 #include "cc/test/fake_raster_source.h" |
| 17 #include "cc/test/fake_recording_source.h" | 18 #include "cc/test/fake_recording_source.h" |
| 18 #include "cc/test/pixel_test.h" | 19 #include "cc/test/pixel_test.h" |
| 20 #include "cc/test/test_in_process_context_provider.h" |
| 19 #include "gpu/command_buffer/client/gles2_interface.h" | 21 #include "gpu/command_buffer/client/gles2_interface.h" |
| 20 #include "media/base/video_frame.h" | 22 #include "media/base/video_frame.h" |
| 21 #include "third_party/skia/include/core/SkColorPriv.h" | 23 #include "third_party/skia/include/core/SkColorPriv.h" |
| 22 #include "third_party/skia/include/core/SkImageFilter.h" | 24 #include "third_party/skia/include/core/SkImageFilter.h" |
| 23 #include "third_party/skia/include/core/SkMatrix.h" | 25 #include "third_party/skia/include/core/SkMatrix.h" |
| 24 #include "third_party/skia/include/core/SkRefCnt.h" | 26 #include "third_party/skia/include/core/SkRefCnt.h" |
| 25 #include "third_party/skia/include/core/SkSurface.h" | 27 #include "third_party/skia/include/core/SkSurface.h" |
| 26 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" | 28 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" |
| 27 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" | 29 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" |
| 28 #include "ui/gfx/geometry/rect_conversions.h" | 30 #include "ui/gfx/geometry/rect_conversions.h" |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 gfx::ColorSpace video_color_space = video_frame->ColorSpace(); | 212 gfx::ColorSpace video_color_space = video_frame->ColorSpace(); |
| 211 | 213 |
| 212 const gfx::Rect opaque_rect(0, 0, 0, 0); | 214 const gfx::Rect opaque_rect(0, 0, 0, 0); |
| 213 | 215 |
| 214 if (with_alpha) { | 216 if (with_alpha) { |
| 215 memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value, | 217 memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value, |
| 216 video_frame->stride(media::VideoFrame::kAPlane) * | 218 video_frame->stride(media::VideoFrame::kAPlane) * |
| 217 video_frame->rows(media::VideoFrame::kAPlane)); | 219 video_frame->rows(media::VideoFrame::kAPlane)); |
| 218 } | 220 } |
| 219 | 221 |
| 220 VideoFrameExternalResources resources = | 222 VideoFrameExternalResources external_resources = |
| 221 video_resource_updater->CreateExternalResourcesFromVideoFrame( | 223 video_resource_updater->CreateExternalResourcesFromVideoFrame( |
| 222 video_frame); | 224 video_frame); |
| 223 | 225 |
| 224 EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type); | 226 ResourceProvider::ResourceIdArray resource_ids; |
| 225 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()), | 227 resource_ids.reserve(external_resources.mailboxes.size()); |
| 226 resources.mailboxes.size()); | 228 for (size_t i = 0; i < external_resources.mailboxes.size(); ++i) { |
| 227 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()), | 229 ResourceId resource_id = |
| 228 resources.release_callbacks.size()); | 230 resource_provider->CreateResourceFromTextureMailbox( |
| 229 | 231 external_resources.mailboxes[i], |
| 230 ResourceId y_resource = resource_provider->CreateResourceFromTextureMailbox( | 232 SingleReleaseCallbackImpl::Create( |
| 231 resources.mailboxes[media::VideoFrame::kYPlane], | 233 external_resources.release_callbacks[i]), |
| 232 SingleReleaseCallbackImpl::Create( | 234 external_resources.read_lock_fences_enabled); |
| 233 resources.release_callbacks[media::VideoFrame::kYPlane])); | 235 resource_ids.push_back(resource_id); |
| 234 ResourceId u_resource = resource_provider->CreateResourceFromTextureMailbox( | |
| 235 resources.mailboxes[media::VideoFrame::kUPlane], | |
| 236 SingleReleaseCallbackImpl::Create( | |
| 237 resources.release_callbacks[media::VideoFrame::kUPlane])); | |
| 238 ResourceId v_resource = resource_provider->CreateResourceFromTextureMailbox( | |
| 239 resources.mailboxes[media::VideoFrame::kVPlane], | |
| 240 SingleReleaseCallbackImpl::Create( | |
| 241 resources.release_callbacks[media::VideoFrame::kVPlane])); | |
| 242 ResourceId a_resource = 0; | |
| 243 if (with_alpha) { | |
| 244 a_resource = resource_provider->CreateResourceFromTextureMailbox( | |
| 245 resources.mailboxes[media::VideoFrame::kAPlane], | |
| 246 SingleReleaseCallbackImpl::Create( | |
| 247 resources.release_callbacks[media::VideoFrame::kAPlane])); | |
| 248 } | 236 } |
| 249 | 237 |
| 250 const gfx::Size ya_tex_size = video_frame->coded_size(); | 238 switch (external_resources.type) { |
| 251 const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize( | 239 case VideoFrameExternalResources::YUV_RESOURCE: { |
| 252 video_frame->format(), media::VideoFrame::kUPlane, | 240 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()), |
| 253 video_frame->coded_size()); | 241 external_resources.mailboxes.size()); |
| 254 DCHECK(uv_tex_size == media::VideoFrame::PlaneSize( | 242 EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()), |
| 255 video_frame->format(), media::VideoFrame::kVPlane, | 243 external_resources.release_callbacks.size()); |
| 256 video_frame->coded_size())); | 244 const gfx::Size ya_tex_size = video_frame->coded_size(); |
| 257 if (with_alpha) { | 245 const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize( |
| 258 DCHECK(ya_tex_size == media::VideoFrame::PlaneSize( | 246 video_frame->format(), media::VideoFrame::kUPlane, |
| 259 video_frame->format(), media::VideoFrame::kAPlane, | 247 video_frame->coded_size()); |
| 260 video_frame->coded_size())); | 248 DCHECK(uv_tex_size == |
| 249 media::VideoFrame::PlaneSize(video_frame->format(), |
| 250 media::VideoFrame::kVPlane, |
| 251 video_frame->coded_size())); |
| 252 if (with_alpha) { |
| 253 DCHECK(ya_tex_size == |
| 254 media::VideoFrame::PlaneSize(video_frame->format(), |
| 255 media::VideoFrame::kAPlane, |
| 256 video_frame->coded_size())); |
| 257 } |
| 258 gfx::RectF ya_tex_coord_rect( |
| 259 tex_coord_rect.x() * ya_tex_size.width(), |
| 260 tex_coord_rect.y() * ya_tex_size.height(), |
| 261 tex_coord_rect.width() * ya_tex_size.width(), |
| 262 tex_coord_rect.height() * ya_tex_size.height()); |
| 263 gfx::RectF uv_tex_coord_rect( |
| 264 tex_coord_rect.x() * uv_tex_size.width(), |
| 265 tex_coord_rect.y() * uv_tex_size.height(), |
| 266 tex_coord_rect.width() * uv_tex_size.width(), |
| 267 tex_coord_rect.height() * uv_tex_size.height()); |
| 268 |
| 269 YUVVideoDrawQuad* yuv_quad = |
| 270 render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>(); |
| 271 yuv_quad->SetNew( |
| 272 shared_state, rect, opaque_rect, visible_rect, ya_tex_coord_rect, |
| 273 uv_tex_coord_rect, ya_tex_size, uv_tex_size, resource_ids[0], |
| 274 resource_ids[1], |
| 275 resource_ids.size() > 2 ? resource_ids[2] : resource_ids[1], |
| 276 resource_ids.size() > 3 ? resource_ids[3] : 0, color_space, |
| 277 video_color_space, external_resources.offset, |
| 278 external_resources.multiplier, external_resources.bits_per_channel); |
| 279 break; |
| 280 } |
| 281 case VideoFrameExternalResources::RGBA_RESOURCE: { |
| 282 EXPECT_EQ(1u, external_resources.mailboxes.size()); |
| 283 EXPECT_EQ(1u, external_resources.release_callbacks.size()); |
| 284 float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; |
| 285 TextureDrawQuad* texture_quad = |
| 286 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); |
| 287 texture_quad->SetNew(shared_state, rect, opaque_rect, visible_rect, |
| 288 resource_ids[0], false, tex_coord_rect.origin(), |
| 289 tex_coord_rect.bottom_right(), SK_ColorTRANSPARENT, |
| 290 opacity, false, false, false); |
| 291 break; |
| 292 } |
| 293 case VideoFrameExternalResources::NONE: |
| 294 case VideoFrameExternalResources::RGB_RESOURCE: |
| 295 case VideoFrameExternalResources::RGBA_PREMULTIPLIED_RESOURCE: |
| 296 case VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE: |
| 297 case VideoFrameExternalResources::SOFTWARE_RESOURCE: |
| 298 NOTREACHED(); |
| 299 break; |
| 261 } | 300 } |
| 262 | |
| 263 gfx::RectF ya_tex_coord_rect(tex_coord_rect.x() * ya_tex_size.width(), | |
| 264 tex_coord_rect.y() * ya_tex_size.height(), | |
| 265 tex_coord_rect.width() * ya_tex_size.width(), | |
| 266 tex_coord_rect.height() * ya_tex_size.height()); | |
| 267 gfx::RectF uv_tex_coord_rect(tex_coord_rect.x() * uv_tex_size.width(), | |
| 268 tex_coord_rect.y() * uv_tex_size.height(), | |
| 269 tex_coord_rect.width() * uv_tex_size.width(), | |
| 270 tex_coord_rect.height() * uv_tex_size.height()); | |
| 271 | |
| 272 YUVVideoDrawQuad* yuv_quad = | |
| 273 render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>(); | |
| 274 uint32_t bits_per_channel = 8; | |
| 275 if (video_frame->format() == media::PIXEL_FORMAT_YUV420P10 || | |
| 276 video_frame->format() == media::PIXEL_FORMAT_YUV422P10 || | |
| 277 video_frame->format() == media::PIXEL_FORMAT_YUV444P10) { | |
| 278 bits_per_channel = 10; | |
| 279 } | |
| 280 | |
| 281 yuv_quad->SetNew(shared_state, rect, opaque_rect, visible_rect, | |
| 282 ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size, | |
| 283 uv_tex_size, y_resource, u_resource, v_resource, a_resource, | |
| 284 color_space, video_color_space, 0.0f, 1.0f, | |
| 285 bits_per_channel); | |
| 286 } | 301 } |
| 287 | 302 |
| 288 void CreateTestY16TextureDrawQuad_FromVideoFrame( | 303 void CreateTestY16TextureDrawQuad_FromVideoFrame( |
| 289 const SharedQuadState* shared_state, | 304 const SharedQuadState* shared_state, |
| 290 scoped_refptr<media::VideoFrame> video_frame, | 305 scoped_refptr<media::VideoFrame> video_frame, |
| 291 const gfx::RectF& tex_coord_rect, | 306 const gfx::RectF& tex_coord_rect, |
| 292 RenderPass* render_pass, | 307 RenderPass* render_pass, |
| 293 VideoResourceUpdater* video_resource_updater, | 308 VideoResourceUpdater* video_resource_updater, |
| 294 const gfx::Rect& rect, | 309 const gfx::Rect& rect, |
| 295 const gfx::Rect& visible_rect, | 310 const gfx::Rect& visible_rect, |
| 296 ResourceProvider* resource_provider) { | 311 ResourceProvider* resource_provider) { |
| 297 VideoFrameExternalResources resources = | 312 VideoFrameExternalResources resources = |
| 298 video_resource_updater->CreateExternalResourcesFromVideoFrame( | 313 video_resource_updater->CreateExternalResourcesFromVideoFrame( |
| 299 video_frame); | 314 video_frame); |
| 300 | 315 |
| 301 EXPECT_EQ(VideoFrameExternalResources::RGBA_RESOURCE, resources.type); | 316 EXPECT_EQ(VideoFrameExternalResources::RGBA_RESOURCE, resources.type); |
| 302 EXPECT_EQ(1u, resources.mailboxes.size()); | 317 EXPECT_EQ(1u, resources.mailboxes.size()); |
| 303 EXPECT_EQ(1u, resources.release_callbacks.size()); | 318 EXPECT_EQ(1u, resources.release_callbacks.size()); |
| 304 | 319 |
| 305 ResourceId y_resource = resource_provider->CreateResourceFromTextureMailbox( | 320 ResourceId y_resource = resource_provider->CreateResourceFromTextureMailbox( |
| 306 resources.mailboxes[0], | 321 resources.mailboxes[0], |
| 307 SingleReleaseCallbackImpl::Create(resources.release_callbacks[0])); | 322 SingleReleaseCallbackImpl::Create(resources.release_callbacks[0])); |
| 308 | 323 |
| 309 TextureDrawQuad* quad = | 324 TextureDrawQuad* quad = |
| 310 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); | 325 render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); |
| 311 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; | 326 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; |
| 312 quad->SetNew(shared_state, rect, gfx::Rect(), rect, y_resource, false, | 327 quad->SetNew(shared_state, rect, gfx::Rect(), visible_rect, y_resource, false, |
| 313 tex_coord_rect.origin(), tex_coord_rect.bottom_right(), | 328 tex_coord_rect.origin(), tex_coord_rect.bottom_right(), |
| 314 SK_ColorBLACK, vertex_opacity, false, false, false); | 329 SK_ColorBLACK, vertex_opacity, false, false, false); |
| 315 } | 330 } |
| 316 | 331 |
| 317 // Upshift video frame to 10 bit. | 332 // Upshift video frame to 10 bit. |
| 318 scoped_refptr<media::VideoFrame> CreateHighbitVideoFrame( | 333 scoped_refptr<media::VideoFrame> CreateHighbitVideoFrame( |
| 319 media::VideoFrame* video_frame) { | 334 media::VideoFrame* video_frame) { |
| 320 media::VideoPixelFormat format; | 335 media::VideoPixelFormat format; |
| 321 switch (video_frame->format()) { | 336 switch (video_frame->format()) { |
| 322 case media::PIXEL_FORMAT_I420: | 337 case media::PIXEL_FORMAT_I420: |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 bool is_transparent, | 380 bool is_transparent, |
| 366 bool highbit, | 381 bool highbit, |
| 367 const gfx::RectF& tex_coord_rect, | 382 const gfx::RectF& tex_coord_rect, |
| 368 RenderPass* render_pass, | 383 RenderPass* render_pass, |
| 369 VideoResourceUpdater* video_resource_updater, | 384 VideoResourceUpdater* video_resource_updater, |
| 370 const gfx::Rect& rect, | 385 const gfx::Rect& rect, |
| 371 const gfx::Rect& visible_rect, | 386 const gfx::Rect& visible_rect, |
| 372 ResourceProvider* resource_provider) { | 387 ResourceProvider* resource_provider) { |
| 373 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame( | 388 scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame( |
| 374 format, rect.size(), rect, rect.size(), base::TimeDelta()); | 389 format, rect.size(), rect, rect.size(), base::TimeDelta()); |
| 390 video_frame->metadata()->SetInteger(media::VideoFrameMetadata::COLOR_SPACE, |
| 391 media::COLOR_SPACE_JPEG); |
| 375 | 392 |
| 376 // YUV values representing a striped pattern, for validating texture | 393 // YUV values representing a striped pattern, for validating texture |
| 377 // coordinates for sampling. | 394 // coordinates for sampling. |
| 378 uint8_t y_value = 0; | 395 uint8_t y_value = 0; |
| 379 uint8_t u_value = 0; | 396 uint8_t u_value = 0; |
| 380 uint8_t v_value = 0; | 397 uint8_t v_value = 0; |
| 381 for (int i = 0; i < video_frame->rows(media::VideoFrame::kYPlane); ++i) { | 398 for (int i = 0; i < video_frame->rows(media::VideoFrame::kYPlane); ++i) { |
| 382 uint8_t* y_row = video_frame->data(media::VideoFrame::kYPlane) + | 399 uint8_t* y_row = video_frame->data(media::VideoFrame::kYPlane) + |
| 383 video_frame->stride(media::VideoFrame::kYPlane) * i; | 400 video_frame->stride(media::VideoFrame::kYPlane) * i; |
| 384 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kYPlane); | 401 for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kYPlane); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 | 525 |
| 509 uint8_t alpha_value = is_transparent ? 0 : 128; | 526 uint8_t alpha_value = is_transparent ? 0 : 128; |
| 510 CreateTestYUVVideoDrawQuad_FromVideoFrame( | 527 CreateTestYUVVideoDrawQuad_FromVideoFrame( |
| 511 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass, | 528 shared_state, video_frame, alpha_value, tex_coord_rect, render_pass, |
| 512 video_resource_updater, rect, visible_rect, resource_provider); | 529 video_resource_updater, rect, visible_rect, resource_provider); |
| 513 } | 530 } |
| 514 | 531 |
| 515 void CreateTestYUVVideoDrawQuad_NV12(const SharedQuadState* shared_state, | 532 void CreateTestYUVVideoDrawQuad_NV12(const SharedQuadState* shared_state, |
| 516 media::ColorSpace video_frame_color_space, | 533 media::ColorSpace video_frame_color_space, |
| 517 const gfx::ColorSpace& video_color_space, | 534 const gfx::ColorSpace& video_color_space, |
| 535 ResourceFormat y_format, |
| 518 const gfx::RectF& tex_coord_rect, | 536 const gfx::RectF& tex_coord_rect, |
| 519 uint8_t y, | 537 uint8_t y, |
| 520 uint8_t u, | 538 uint8_t u, |
| 521 uint8_t v, | 539 uint8_t v, |
| 522 RenderPass* render_pass, | 540 RenderPass* render_pass, |
| 523 const gfx::Rect& rect, | 541 const gfx::Rect& rect, |
| 524 const gfx::Rect& visible_rect, | 542 const gfx::Rect& visible_rect, |
| 525 ResourceProvider* resource_provider) { | 543 ResourceProvider* resource_provider) { |
| 526 YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::REC_601; | 544 YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::REC_601; |
| 527 if (video_frame_color_space == media::COLOR_SPACE_JPEG) { | 545 if (video_frame_color_space == media::COLOR_SPACE_JPEG) { |
| 528 color_space = YUVVideoDrawQuad::JPEG; | 546 color_space = YUVVideoDrawQuad::JPEG; |
| 529 } | 547 } |
| 530 | 548 |
| 531 const gfx::Rect opaque_rect(0, 0, 0, 0); | 549 const gfx::Rect opaque_rect(0, 0, 0, 0); |
| 532 const gfx::Size ya_tex_size = rect.size(); | 550 const gfx::Size ya_tex_size = rect.size(); |
| 533 const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize( | 551 const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize( |
| 534 media::PIXEL_FORMAT_NV12, media::VideoFrame::kUVPlane, rect.size()); | 552 media::PIXEL_FORMAT_NV12, media::VideoFrame::kUVPlane, rect.size()); |
| 535 | 553 |
| 536 ResourceId y_resource = resource_provider->CreateResource( | 554 ResourceId y_resource = resource_provider->CreateResource( |
| 537 rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT, | 555 rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT, y_format, |
| 538 resource_provider->YuvResourceFormat(8), gfx::ColorSpace()); | 556 gfx::ColorSpace()); |
| 539 ResourceId u_resource = resource_provider->CreateResource( | 557 ResourceId u_resource = resource_provider->CreateResource( |
| 540 uv_tex_size, ResourceProvider::TEXTURE_HINT_DEFAULT, RGBA_8888, | 558 uv_tex_size, ResourceProvider::TEXTURE_HINT_DEFAULT, RGBA_8888, |
| 541 gfx::ColorSpace()); | 559 gfx::ColorSpace()); |
| 542 ResourceId v_resource = u_resource; | 560 ResourceId v_resource = u_resource; |
| 543 ResourceId a_resource = 0; | 561 ResourceId a_resource = 0; |
| 544 | 562 |
| 545 std::vector<uint8_t> y_pixels(ya_tex_size.GetArea(), y); | 563 std::vector<uint8_t> y_pixels(ya_tex_size.GetArea(), y); |
| 546 resource_provider->CopyToResource(y_resource, y_pixels.data(), ya_tex_size); | 564 resource_provider->CopyToResource(y_resource, y_pixels.data(), ya_tex_size); |
| 547 | 565 |
| 548 // U goes in the R component and V goes in the G component. | 566 // U goes in the R component and V goes in the G component. |
| (...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1188 resource_provider_.get()); | 1206 resource_provider_.get()); |
| 1189 pass_list->push_back(std::move(pass)); | 1207 pass_list->push_back(std::move(pass)); |
| 1190 } | 1208 } |
| 1191 | 1209 |
| 1192 void SetUp() override { | 1210 void SetUp() override { |
| 1193 GLRendererPixelTest::SetUp(); | 1211 GLRendererPixelTest::SetUp(); |
| 1194 video_resource_updater_.reset(new VideoResourceUpdater( | 1212 video_resource_updater_.reset(new VideoResourceUpdater( |
| 1195 output_surface_->context_provider(), resource_provider_.get())); | 1213 output_surface_->context_provider(), resource_provider_.get())); |
| 1196 } | 1214 } |
| 1197 | 1215 |
| 1216 void DisableOneComponentTextures() { |
| 1217 TestInProcessContextProvider* context_provider = |
| 1218 GetTestInProcessContextProvider(); |
| 1219 context_provider->SetDisableOneComponentTextures(true); |
| 1220 } |
| 1221 |
| 1198 std::unique_ptr<VideoResourceUpdater> video_resource_updater_; | 1222 std::unique_ptr<VideoResourceUpdater> video_resource_updater_; |
| 1223 |
| 1224 protected: |
| 1225 TestInProcessContextProvider* GetTestInProcessContextProvider() { |
| 1226 return static_cast<TestInProcessContextProvider*>( |
| 1227 output_surface_->context_provider()); |
| 1228 } |
| 1229 }; |
| 1230 |
| 1231 enum class HighbitTexture { |
| 1232 Y8, |
| 1233 RGBA_8888, |
| 1234 LUMINANCE_F16, // need --use-gpu-in-tests |
| 1199 }; | 1235 }; |
| 1200 | 1236 |
| 1201 class VideoGLRendererPixelHiLoTest | 1237 class VideoGLRendererPixelHiLoTest |
| 1202 : public VideoGLRendererPixelTest, | 1238 : public VideoGLRendererPixelTest, |
| 1203 public ::testing::WithParamInterface<bool> {}; | 1239 public ::testing::WithParamInterface< |
| 1240 ::testing::tuple<bool, HighbitTexture>> { |
| 1241 public: |
| 1242 void SetSupportHighbitTexture(HighbitTexture texture) { |
| 1243 TestInProcessContextProvider* context_provider = |
| 1244 GetTestInProcessContextProvider(); |
| 1245 switch (texture) { |
| 1246 case HighbitTexture::Y8: |
| 1247 context_provider->SetDisableOneComponentTextures(false); |
| 1248 context_provider->SetSupportTextureHalfFloatLinear(false); |
| 1249 break; |
| 1250 case HighbitTexture::RGBA_8888: |
| 1251 context_provider->SetDisableOneComponentTextures(true); |
| 1252 context_provider->SetSupportTextureHalfFloatLinear(false); |
| 1253 break; |
| 1254 case HighbitTexture::LUMINANCE_F16: |
| 1255 context_provider->SetDisableOneComponentTextures(false); |
| 1256 context_provider->SetSupportTextureHalfFloatLinear(true); |
| 1257 break; |
| 1258 } |
| 1259 } |
| 1260 |
| 1261 bool IsHalfFloatLinearSupported() { |
| 1262 if (extensions_.empty()) |
| 1263 InitializeExtensions(); |
| 1264 |
| 1265 return extensions_.find("GL_OES_texture_half_float_linear") != |
| 1266 extensions_.end(); |
| 1267 } |
| 1268 |
| 1269 private: |
| 1270 void InitializeExtensions() { |
| 1271 std::string extensions = GetTestInProcessContextProvider() |
| 1272 ->ContextGL() |
| 1273 ->GetRequestableExtensionsCHROMIUM(); |
| 1274 std::vector<std::string> tokens = base::SplitString( |
| 1275 extensions, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
| 1276 extensions_.insert(tokens.begin(), tokens.end()); |
| 1277 } |
| 1278 |
| 1279 std::set<std::string> extensions_; |
| 1280 }; |
| 1204 | 1281 |
| 1205 TEST_P(VideoGLRendererPixelHiLoTest, SimpleYUVRect) { | 1282 TEST_P(VideoGLRendererPixelHiLoTest, SimpleYUVRect) { |
| 1206 gfx::Rect rect(this->device_viewport_size_); | 1283 gfx::Rect rect(this->device_viewport_size_); |
| 1207 | 1284 |
| 1208 RenderPassId id(1, 1); | 1285 RenderPassId id(1, 1); |
| 1209 std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 1286 std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
| 1210 | 1287 |
| 1211 SharedQuadState* shared_state = | 1288 SharedQuadState* shared_state = |
| 1212 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 1289 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
| 1213 | 1290 |
| 1214 bool highbit = GetParam(); | 1291 const bool highbit = testing::get<0>(GetParam()); |
| 1292 const HighbitTexture format = testing::get<1>(GetParam()); |
| 1293 if (format == HighbitTexture::LUMINANCE_F16 && !IsHalfFloatLinearSupported()) |
| 1294 return; |
| 1295 |
| 1296 SetSupportHighbitTexture(format); |
| 1215 CreateTestYUVVideoDrawQuad_Striped( | 1297 CreateTestYUVVideoDrawQuad_Striped( |
| 1216 shared_state, media::PIXEL_FORMAT_YV12, false, highbit, | 1298 shared_state, media::PIXEL_FORMAT_YV12, false, highbit, |
| 1217 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(), | 1299 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(), |
| 1218 video_resource_updater_.get(), rect, rect, resource_provider_.get()); | 1300 video_resource_updater_.get(), rect, rect, resource_provider_.get()); |
| 1219 | 1301 |
| 1220 RenderPassList pass_list; | 1302 RenderPassList pass_list; |
| 1221 pass_list.push_back(std::move(pass)); | 1303 pass_list.push_back(std::move(pass)); |
| 1222 | 1304 |
| 1223 EXPECT_TRUE( | 1305 base::FilePath file_path = |
| 1224 this->RunPixelTest(&pass_list, | 1306 base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")); |
| 1225 base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")), | 1307 // TODO(dshwang): investigate why results per configuraion are so different. |
| 1226 FuzzyPixelOffByOneComparator(true))); | 1308 // crbug.com/622133 |
| 1309 if (format == HighbitTexture::RGBA_8888) { |
| 1310 // Color space is so different, because this path doesn't respect video |
| 1311 // color profile. |
| 1312 file_path = base::FilePath(FILE_PATH_LITERAL("yuv_stripes_rgba.png")); |
| 1313 } |
| 1314 EXPECT_TRUE(this->RunPixelTest( |
| 1315 &pass_list, file_path, |
| 1316 // All pixels can be off by two, but any more than that is an error. |
| 1317 FuzzyPixelComparator(true, 100.f, 0.f, 2.f, 2, 0))); |
| 1227 } | 1318 } |
| 1228 | 1319 |
| 1229 TEST_P(VideoGLRendererPixelHiLoTest, ClippedYUVRect) { | 1320 TEST_P(VideoGLRendererPixelHiLoTest, ClippedYUVRect) { |
| 1230 gfx::Rect viewport(this->device_viewport_size_); | 1321 gfx::Rect viewport(this->device_viewport_size_); |
| 1231 gfx::Rect draw_rect(this->device_viewport_size_.width() * 1.5, | 1322 gfx::Rect draw_rect(this->device_viewport_size_.width() * 1.5, |
| 1232 this->device_viewport_size_.height() * 1.5); | 1323 this->device_viewport_size_.height() * 1.5); |
| 1233 | 1324 |
| 1234 RenderPassId id(1, 1); | 1325 RenderPassId id(1, 1); |
| 1235 std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, viewport); | 1326 std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, viewport); |
| 1236 | 1327 |
| 1237 SharedQuadState* shared_state = | 1328 SharedQuadState* shared_state = |
| 1238 CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get()); | 1329 CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get()); |
| 1239 | 1330 |
| 1240 bool highbit = GetParam(); | 1331 const bool highbit = testing::get<0>(GetParam()); |
| 1332 const HighbitTexture format = testing::get<1>(GetParam()); |
| 1333 if (format == HighbitTexture::LUMINANCE_F16 && !IsHalfFloatLinearSupported()) |
| 1334 return; |
| 1335 |
| 1336 SetSupportHighbitTexture(format); |
| 1241 CreateTestYUVVideoDrawQuad_Striped( | 1337 CreateTestYUVVideoDrawQuad_Striped( |
| 1242 shared_state, media::PIXEL_FORMAT_YV12, false, highbit, | 1338 shared_state, media::PIXEL_FORMAT_YV12, false, highbit, |
| 1243 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(), | 1339 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(), |
| 1244 video_resource_updater_.get(), draw_rect, viewport, | 1340 video_resource_updater_.get(), draw_rect, viewport, |
| 1245 resource_provider_.get()); | 1341 resource_provider_.get()); |
| 1246 RenderPassList pass_list; | 1342 RenderPassList pass_list; |
| 1247 pass_list.push_back(std::move(pass)); | 1343 pass_list.push_back(std::move(pass)); |
| 1248 | 1344 |
| 1345 base::FilePath file_path = |
| 1346 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png")); |
| 1347 if (format == HighbitTexture::RGBA_8888) { |
| 1348 file_path = |
| 1349 base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped_rgba.png")); |
| 1350 } |
| 1249 EXPECT_TRUE(this->RunPixelTest( | 1351 EXPECT_TRUE(this->RunPixelTest( |
| 1250 &pass_list, base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png")), | 1352 &pass_list, file_path, |
| 1251 FuzzyPixelOffByOneComparator(true))); | 1353 // All pixels can be off by two, but any more than that is an error. |
| 1354 FuzzyPixelComparator(true, 100.f, 0.f, 2.f, 2, 0))); |
| 1252 } | 1355 } |
| 1253 | 1356 |
| 1254 TEST_F(VideoGLRendererPixelHiLoTest, OffsetYUVRect) { | 1357 TEST_F(VideoGLRendererPixelHiLoTest, OffsetYUVRect) { |
| 1255 gfx::Rect rect(this->device_viewport_size_); | 1358 gfx::Rect rect(this->device_viewport_size_); |
| 1256 | 1359 |
| 1257 RenderPassId id(1, 1); | 1360 RenderPassId id(1, 1); |
| 1258 std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 1361 std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
| 1259 | 1362 |
| 1260 SharedQuadState* shared_state = | 1363 SharedQuadState* shared_state = |
| 1261 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 1364 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1293 pass_list.push_back(std::move(pass)); | 1396 pass_list.push_back(std::move(pass)); |
| 1294 | 1397 |
| 1295 // If we didn't get black out of the YUV values above, then we probably have a | 1398 // If we didn't get black out of the YUV values above, then we probably have a |
| 1296 // color range issue. | 1399 // color range issue. |
| 1297 EXPECT_TRUE(this->RunPixelTest(&pass_list, | 1400 EXPECT_TRUE(this->RunPixelTest(&pass_list, |
| 1298 base::FilePath(FILE_PATH_LITERAL("black.png")), | 1401 base::FilePath(FILE_PATH_LITERAL("black.png")), |
| 1299 FuzzyPixelOffByOneComparator(true))); | 1402 FuzzyPixelOffByOneComparator(true))); |
| 1300 } | 1403 } |
| 1301 | 1404 |
| 1302 // First argument (test case prefix) is intentionally left empty. | 1405 // First argument (test case prefix) is intentionally left empty. |
| 1303 INSTANTIATE_TEST_CASE_P(, VideoGLRendererPixelHiLoTest, ::testing::Bool()); | 1406 INSTANTIATE_TEST_CASE_P( |
| 1407 , |
| 1408 VideoGLRendererPixelHiLoTest, |
| 1409 ::testing::Combine(::testing::Bool(), |
| 1410 ::testing::Values(HighbitTexture::Y8, |
| 1411 HighbitTexture::LUMINANCE_F16, |
| 1412 HighbitTexture::RGBA_8888))); |
| 1304 | 1413 |
| 1305 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) { | 1414 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) { |
| 1306 gfx::Rect rect(this->device_viewport_size_); | 1415 gfx::Rect rect(this->device_viewport_size_); |
| 1307 | 1416 |
| 1308 RenderPassId id(1, 1); | 1417 RenderPassId id(1, 1); |
| 1309 std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 1418 std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
| 1310 | 1419 |
| 1311 SharedQuadState* shared_state = | 1420 SharedQuadState* shared_state = |
| 1312 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 1421 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
| 1313 | 1422 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1327 | 1436 |
| 1328 TEST_F(VideoGLRendererPixelTest, SimpleNV12JRect) { | 1437 TEST_F(VideoGLRendererPixelTest, SimpleNV12JRect) { |
| 1329 gfx::Rect rect(this->device_viewport_size_); | 1438 gfx::Rect rect(this->device_viewport_size_); |
| 1330 | 1439 |
| 1331 RenderPassId id(1, 1); | 1440 RenderPassId id(1, 1); |
| 1332 std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 1441 std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
| 1333 | 1442 |
| 1334 SharedQuadState* shared_state = | 1443 SharedQuadState* shared_state = |
| 1335 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 1444 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
| 1336 | 1445 |
| 1446 ResourceFormat y_format = |
| 1447 video_resource_updater_->YuvResourceFormat(8, media::PIXEL_FORMAT_NV12); |
| 1448 |
| 1337 // YUV of (149,43,21) should be green (0,255,0) in RGB. | 1449 // YUV of (149,43,21) should be green (0,255,0) in RGB. |
| 1338 CreateTestYUVVideoDrawQuad_NV12( | 1450 CreateTestYUVVideoDrawQuad_NV12( |
| 1339 shared_state, media::COLOR_SPACE_JPEG, gfx::ColorSpace::CreateJpeg(), | 1451 shared_state, media::COLOR_SPACE_JPEG, gfx::ColorSpace::CreateJpeg(), |
| 1340 gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(), rect, rect, | 1452 y_format, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(), |
| 1341 resource_provider_.get()); | 1453 rect, rect, resource_provider_.get()); |
| 1342 | 1454 |
| 1343 RenderPassList pass_list; | 1455 RenderPassList pass_list; |
| 1344 pass_list.push_back(std::move(pass)); | 1456 pass_list.push_back(std::move(pass)); |
| 1345 | 1457 |
| 1346 EXPECT_TRUE(this->RunPixelTest(&pass_list, | 1458 EXPECT_TRUE(this->RunPixelTest(&pass_list, |
| 1347 base::FilePath(FILE_PATH_LITERAL("green.png")), | 1459 base::FilePath(FILE_PATH_LITERAL("green.png")), |
| 1348 FuzzyPixelOffByOneComparator(true))); | 1460 FuzzyPixelOffByOneComparator(true))); |
| 1349 } | 1461 } |
| 1350 | 1462 |
| 1351 // Test that a YUV video doesn't bleed outside of its tex coords when the | 1463 // Test that a YUV video doesn't bleed outside of its tex coords when the |
| 1352 // tex coord rect is only a partial subrectangle of the coded contents. | 1464 // tex coord rect is only a partial subrectangle of the coded contents. |
| 1353 TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) { | 1465 TEST_F(VideoGLRendererPixelTest, YUVEdgeBleed) { |
| 1354 RenderPassList pass_list; | 1466 RenderPassList pass_list; |
| 1355 CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG, | 1467 CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG, |
| 1356 &pass_list); | 1468 &pass_list); |
| 1357 EXPECT_TRUE(this->RunPixelTest(&pass_list, | 1469 EXPECT_TRUE(this->RunPixelTest(&pass_list, |
| 1358 base::FilePath(FILE_PATH_LITERAL("green.png")), | 1470 base::FilePath(FILE_PATH_LITERAL("green.png")), |
| 1359 FuzzyPixelOffByOneComparator(true))); | 1471 FuzzyPixelOffByOneComparator(true))); |
| 1360 } | 1472 } |
| 1361 | 1473 |
| 1362 TEST_F(VideoGLRendererPixelTest, YUVAEdgeBleed) { | 1474 TEST_F(VideoGLRendererPixelTest, YUVAEdgeBleed) { |
| 1363 RenderPassList pass_list; | 1475 RenderPassList pass_list; |
| 1364 CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12A, media::COLOR_SPACE_UNSPECIFIED, | 1476 CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12A, media::COLOR_SPACE_UNSPECIFIED, |
| 1365 &pass_list); | 1477 &pass_list); |
| 1366 EXPECT_TRUE(this->RunPixelTest(&pass_list, | 1478 EXPECT_TRUE(this->RunPixelTest(&pass_list, |
| 1367 base::FilePath(FILE_PATH_LITERAL("green.png")), | 1479 base::FilePath(FILE_PATH_LITERAL("green.png")), |
| 1368 FuzzyPixelOffByOneComparator(true))); | 1480 FuzzyPixelOffByOneComparator(true))); |
| 1369 } | 1481 } |
| 1370 | 1482 |
| 1483 TEST_F(VideoGLRendererPixelTest, TextureQuadEdgeBleed) { |
| 1484 // VideoResourceUpdater::CreateForSoftwarePlanes() converts YUV frame to RGBA |
| 1485 // texture. |
| 1486 DisableOneComponentTextures(); |
| 1487 RenderPassList pass_list; |
| 1488 CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG, |
| 1489 &pass_list); |
| 1490 EXPECT_TRUE(this->RunPixelTest(&pass_list, |
| 1491 base::FilePath(FILE_PATH_LITERAL("green.png")), |
| 1492 FuzzyPixelOffByOneComparator(true))); |
| 1493 } |
| 1494 |
| 1371 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) { | 1495 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) { |
| 1372 gfx::Rect rect(this->device_viewport_size_); | 1496 gfx::Rect rect(this->device_viewport_size_); |
| 1373 | 1497 |
| 1374 RenderPassId id(1, 1); | 1498 RenderPassId id(1, 1); |
| 1375 std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); | 1499 std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
| 1376 | 1500 |
| 1377 SharedQuadState* shared_state = | 1501 SharedQuadState* shared_state = |
| 1378 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); | 1502 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
| 1379 | 1503 |
| 1380 // Dark grey in JPEG color range (in MPEG, this is black). | 1504 // Dark grey in JPEG color range (in MPEG, this is black). |
| (...skipping 1891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3272 | 3396 |
| 3273 EXPECT_TRUE(this->RunPixelTest( | 3397 EXPECT_TRUE(this->RunPixelTest( |
| 3274 &pass_list, base::FilePath(FILE_PATH_LITERAL("spiral.png")), | 3398 &pass_list, base::FilePath(FILE_PATH_LITERAL("spiral.png")), |
| 3275 FuzzyPixelOffByOneComparator(true))); | 3399 FuzzyPixelOffByOneComparator(true))); |
| 3276 } | 3400 } |
| 3277 | 3401 |
| 3278 #endif // !defined(OS_ANDROID) | 3402 #endif // !defined(OS_ANDROID) |
| 3279 | 3403 |
| 3280 } // namespace | 3404 } // namespace |
| 3281 } // namespace cc | 3405 } // namespace cc |
| OLD | NEW |