OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "cc/resources/video_resource_updater.h" | 5 #include "cc/resources/video_resource_updater.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
302 uint16_t* dst) { | 302 uint16_t* dst) { |
303 // Source and dest stride can be zero since we're only copying | 303 // Source and dest stride can be zero since we're only copying |
304 // one row at a time. | 304 // one row at a time. |
305 int stride = 0; | 305 int stride = 0; |
306 // Maximum value used in |src|. | 306 // Maximum value used in |src|. |
307 int max_value = (1 << bits_per_channel) - 1; | 307 int max_value = (1 << bits_per_channel) - 1; |
308 int rows = 1; | 308 int rows = 1; |
309 libyuv::HalfFloatPlane(src, stride, dst, stride, 1.0f / max_value, num, rows); | 309 libyuv::HalfFloatPlane(src, stride, dst, stride, 1.0f / max_value, num, rows); |
310 } | 310 } |
311 | 311 |
312 ResourceFormat VideoResourceUpdater::YuvResourceFormat(int bits) const { | |
dshwang
2016/10/18 19:14:36
Move this logic from ResourceProvider because
1. t
| |
313 if (!context_provider_) | |
314 return LUMINANCE_8; | |
315 | |
316 const auto caps = context_provider_->ContextCapabilities(); | |
317 if (caps.disable_one_component_textures) | |
318 return RGBA_8888; | |
319 | |
320 ResourceFormat yuv_resource_format = caps.texture_rg ? RED_8 : LUMINANCE_8; | |
321 if (bits <= 8) | |
322 return yuv_resource_format; | |
323 | |
324 if (caps.texture_half_float_linear) | |
325 return LUMINANCE_F16; | |
326 | |
327 return yuv_resource_format; | |
328 } | |
329 | |
312 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( | 330 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
313 scoped_refptr<media::VideoFrame> video_frame) { | 331 scoped_refptr<media::VideoFrame> video_frame) { |
314 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); | 332 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); |
315 const media::VideoPixelFormat input_frame_format = video_frame->format(); | 333 const media::VideoPixelFormat input_frame_format = video_frame->format(); |
316 | 334 |
317 // TODO(hubbe): Make this a video frame method. | 335 // TODO(hubbe): Make this a video frame method. |
318 int bits_per_channel = 0; | 336 int bits_per_channel = 0; |
319 switch (input_frame_format) { | 337 switch (input_frame_format) { |
320 case media::PIXEL_FORMAT_UNKNOWN: | 338 case media::PIXEL_FORMAT_UNKNOWN: |
321 NOTREACHED(); | 339 NOTREACHED(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
360 | 378 |
361 // TODO(dshwang): support PIXEL_FORMAT_Y16. crbug.com/624436 | 379 // TODO(dshwang): support PIXEL_FORMAT_Y16. crbug.com/624436 |
362 DCHECK_NE(bits_per_channel, 16); | 380 DCHECK_NE(bits_per_channel, 16); |
363 | 381 |
364 // Only YUV software video frames are supported. | 382 // Only YUV software video frames are supported. |
365 if (!media::IsYuvPlanar(input_frame_format)) { | 383 if (!media::IsYuvPlanar(input_frame_format)) { |
366 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format); | 384 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format); |
367 return VideoFrameExternalResources(); | 385 return VideoFrameExternalResources(); |
368 } | 386 } |
369 | 387 |
370 const bool software_compositor = context_provider_ == NULL; | 388 const bool software_compositor = context_provider_ == nullptr; |
389 bool disable_one_component_textures = true; | |
390 if (!software_compositor) { | |
391 const auto caps = context_provider_->ContextCapabilities(); | |
392 disable_one_component_textures = caps.disable_one_component_textures; | |
393 } | |
371 | 394 |
372 ResourceFormat output_resource_format = | 395 ResourceFormat output_resource_format = YuvResourceFormat(bits_per_channel); |
373 resource_provider_->YuvResourceFormat(bits_per_channel); | |
374 | 396 |
375 // If GPU compositing is enabled, but the output resource format | 397 // If GPU compositing is enabled, but the output resource format |
376 // returned by the resource provider is RGBA_8888, then a GPU driver | 398 // returned by the resource provider is RGBA_8888, then a GPU driver |
377 // bug workaround requires that YUV frames must be converted to RGB | 399 // bug workaround requires that YUV frames must be converted to RGB |
378 // before texture upload. | 400 // before texture upload. |
379 bool texture_needs_rgb_conversion = | 401 bool texture_needs_rgb_conversion = |
380 !software_compositor && | 402 !software_compositor && disable_one_component_textures; |
381 output_resource_format == ResourceFormat::RGBA_8888; | |
382 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); | 403 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); |
383 | 404 |
384 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB | 405 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB |
385 // conversion here. That involves an extra copy of each frame to a bitmap. | 406 // conversion here. That involves an extra copy of each frame to a bitmap. |
386 // Obviously, this is suboptimal and should be addressed once ubercompositor | 407 // Obviously, this is suboptimal and should be addressed once ubercompositor |
387 // starts shaping up. | 408 // starts shaping up. |
388 if (software_compositor || texture_needs_rgb_conversion) { | 409 if (software_compositor || texture_needs_rgb_conversion) { |
389 output_resource_format = kRGBResourceFormat; | 410 output_resource_format = kRGBResourceFormat; |
390 output_plane_count = 1; | 411 output_plane_count = 1; |
391 bits_per_channel = 8; | 412 bits_per_channel = 8; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
447 // by software. | 468 // by software. |
448 video_renderer_->Copy(video_frame, &canvas, media::Context3D()); | 469 video_renderer_->Copy(video_frame, &canvas, media::Context3D()); |
449 } else { | 470 } else { |
450 size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>( | 471 size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>( |
451 video_frame->coded_size().width(), ResourceFormat::RGBA_8888); | 472 video_frame->coded_size().width(), ResourceFormat::RGBA_8888); |
452 size_t needed_size = bytes_per_row * video_frame->coded_size().height(); | 473 size_t needed_size = bytes_per_row * video_frame->coded_size().height(); |
453 if (upload_pixels_.size() < needed_size) | 474 if (upload_pixels_.size() < needed_size) |
454 upload_pixels_.resize(needed_size); | 475 upload_pixels_.resize(needed_size); |
455 | 476 |
456 media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( | 477 media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( |
457 video_frame.get(), &upload_pixels_[0], bytes_per_row); | 478 video_frame.get(), |
479 media::SkCanvasVideoRenderer::ConvertingSize::CODED, | |
480 &upload_pixels_[0], bytes_per_row); | |
458 | 481 |
459 resource_provider_->CopyToResource(plane_resource.resource_id(), | 482 resource_provider_->CopyToResource(plane_resource.resource_id(), |
460 &upload_pixels_[0], | 483 &upload_pixels_[0], |
461 plane_resource.resource_size()); | 484 plane_resource.resource_size()); |
462 } | 485 } |
463 plane_resource.SetUniqueId(video_frame->unique_id(), 0); | 486 plane_resource.SetUniqueId(video_frame->unique_id(), 0); |
464 } | 487 } |
465 | 488 |
466 if (software_compositor) { | 489 if (software_compositor) { |
467 external_resources.software_resources.push_back( | 490 external_resources.software_resources.push_back( |
468 plane_resource.resource_id()); | 491 plane_resource.resource_id()); |
469 external_resources.software_release_callback = base::Bind( | 492 external_resources.software_release_callback = base::Bind( |
470 &RecycleResource, AsWeakPtr(), plane_resource.resource_id()); | 493 &RecycleResource, AsWeakPtr(), plane_resource.resource_id()); |
471 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; | 494 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; |
472 } else { | 495 } else { |
473 // VideoResourceUpdater shares a context with the compositor so | 496 // VideoResourceUpdater shares a context with the compositor so |
474 // a sync token is not required. | 497 // a sync token is not required. |
475 TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(), | 498 TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(), |
476 resource_provider_->GetResourceTextureTarget( | 499 resource_provider_->GetResourceTextureTarget( |
477 plane_resource.resource_id())); | 500 plane_resource.resource_id()), |
501 plane_resource.resource_size(), false, false); | |
dshwang
2016/10/18 19:14:36
This hidden bug is covered by VideoGLRendererPixel
| |
478 mailbox.set_color_space(video_frame->ColorSpace()); | 502 mailbox.set_color_space(video_frame->ColorSpace()); |
479 external_resources.mailboxes.push_back(mailbox); | 503 external_resources.mailboxes.push_back(mailbox); |
480 external_resources.release_callbacks.push_back(base::Bind( | 504 external_resources.release_callbacks.push_back(base::Bind( |
481 &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); | 505 &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); |
482 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE; | 506 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE; |
483 } | 507 } |
484 return external_resources; | 508 return external_resources; |
485 } | 509 } |
486 | 510 |
487 for (size_t i = 0; i < plane_resources.size(); ++i) { | 511 for (size_t i = 0; i < plane_resources.size(); ++i) { |
488 PlaneResource& plane_resource = *plane_resources[i]; | 512 PlaneResource& plane_resource = *plane_resources[i]; |
489 // Update each plane's resource id with its content. | 513 // Update each plane's resource id with its content. |
490 DCHECK_EQ(plane_resource.resource_format(), | 514 DCHECK_EQ(plane_resource.resource_format(), |
491 resource_provider_->YuvResourceFormat(bits_per_channel)); | 515 YuvResourceFormat(bits_per_channel)); |
492 | 516 |
493 if (!plane_resource.Matches(video_frame->unique_id(), i)) { | 517 if (!plane_resource.Matches(video_frame->unique_id(), i)) { |
494 // TODO(hubbe): Move all conversion (and upload?) code to media/. | 518 // TODO(hubbe): Move all conversion (and upload?) code to media/. |
495 // We need to transfer data from |video_frame| to the plane resource. | 519 // We need to transfer data from |video_frame| to the plane resource. |
496 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance. | 520 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance. |
497 | 521 |
498 // The |resource_size_pixels| is the size of the resource we want to | 522 // The |resource_size_pixels| is the size of the resource we want to |
499 // upload to. | 523 // upload to. |
500 gfx::Size resource_size_pixels = plane_resource.resource_size(); | 524 gfx::Size resource_size_pixels = plane_resource.resource_size(); |
501 // The |video_stride_bytes| is the width of the video frame we are | 525 // The |video_stride_bytes| is the width of the video frame we are |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
763 if (lost_resource) { | 787 if (lost_resource) { |
764 resource_it->clear_refs(); | 788 resource_it->clear_refs(); |
765 updater->DeleteResource(resource_it); | 789 updater->DeleteResource(resource_it); |
766 return; | 790 return; |
767 } | 791 } |
768 | 792 |
769 resource_it->remove_ref(); | 793 resource_it->remove_ref(); |
770 } | 794 } |
771 | 795 |
772 } // namespace cc | 796 } // namespace cc |
OLD | NEW |