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 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 VideoResourceUpdater::NewHalfFloatMaker(int bits_per_channel) { | 372 VideoResourceUpdater::NewHalfFloatMaker(int bits_per_channel) { |
373 if (bits_per_channel < 11) { | 373 if (bits_per_channel < 11) { |
374 return std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>( | 374 return std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>( |
375 new HalfFloatMaker_xor(bits_per_channel)); | 375 new HalfFloatMaker_xor(bits_per_channel)); |
376 } else { | 376 } else { |
377 return std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>( | 377 return std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>( |
378 new HalfFloatMaker_libyuv(bits_per_channel)); | 378 new HalfFloatMaker_libyuv(bits_per_channel)); |
379 } | 379 } |
380 } | 380 } |
381 | 381 |
| 382 ResourceFormat VideoResourceUpdater::YuvResourceFormat(int bits) const { |
| 383 if (!context_provider_) |
| 384 return LUMINANCE_8; |
| 385 |
| 386 const auto caps = context_provider_->ContextCapabilities(); |
| 387 if (caps.disable_one_component_textures) |
| 388 return RGBA_8888; |
| 389 |
| 390 ResourceFormat yuv_resource_format = caps.texture_rg ? RED_8 : LUMINANCE_8; |
| 391 if (bits <= 8) |
| 392 return yuv_resource_format; |
| 393 |
| 394 if (caps.texture_half_float_linear) |
| 395 return LUMINANCE_F16; |
| 396 |
| 397 return yuv_resource_format; |
| 398 } |
| 399 |
382 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( | 400 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
383 scoped_refptr<media::VideoFrame> video_frame) { | 401 scoped_refptr<media::VideoFrame> video_frame) { |
384 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); | 402 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); |
385 const media::VideoPixelFormat input_frame_format = video_frame->format(); | 403 const media::VideoPixelFormat input_frame_format = video_frame->format(); |
386 | 404 |
387 // TODO(hubbe): Make this a video frame method. | 405 // TODO(hubbe): Make this a video frame method. |
388 int bits_per_channel = 0; | 406 int bits_per_channel = 0; |
389 switch (input_frame_format) { | 407 switch (input_frame_format) { |
390 case media::PIXEL_FORMAT_UNKNOWN: | 408 case media::PIXEL_FORMAT_UNKNOWN: |
391 NOTREACHED(); | 409 NOTREACHED(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 | 448 |
431 // TODO(dshwang): support PIXEL_FORMAT_Y16. crbug.com/624436 | 449 // TODO(dshwang): support PIXEL_FORMAT_Y16. crbug.com/624436 |
432 DCHECK_NE(bits_per_channel, 16); | 450 DCHECK_NE(bits_per_channel, 16); |
433 | 451 |
434 // Only YUV software video frames are supported. | 452 // Only YUV software video frames are supported. |
435 if (!media::IsYuvPlanar(input_frame_format)) { | 453 if (!media::IsYuvPlanar(input_frame_format)) { |
436 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format); | 454 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format); |
437 return VideoFrameExternalResources(); | 455 return VideoFrameExternalResources(); |
438 } | 456 } |
439 | 457 |
440 const bool software_compositor = context_provider_ == NULL; | 458 const bool software_compositor = context_provider_ == nullptr; |
| 459 bool disable_one_component_textures = true; |
| 460 if (!software_compositor) { |
| 461 const auto caps = context_provider_->ContextCapabilities(); |
| 462 disable_one_component_textures = caps.disable_one_component_textures; |
| 463 } |
441 | 464 |
442 ResourceFormat output_resource_format = | 465 ResourceFormat output_resource_format = YuvResourceFormat(bits_per_channel); |
443 resource_provider_->YuvResourceFormat(bits_per_channel); | |
444 | 466 |
445 // If GPU compositing is enabled, but the output resource format | 467 // If GPU compositing is enabled, but the output resource format |
446 // returned by the resource provider is RGBA_8888, then a GPU driver | 468 // returned by the resource provider is RGBA_8888, then a GPU driver |
447 // bug workaround requires that YUV frames must be converted to RGB | 469 // bug workaround requires that YUV frames must be converted to RGB |
448 // before texture upload. | 470 // before texture upload. |
449 bool texture_needs_rgb_conversion = | 471 bool texture_needs_rgb_conversion = |
450 !software_compositor && | 472 !software_compositor && disable_one_component_textures; |
451 output_resource_format == ResourceFormat::RGBA_8888; | |
452 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); | 473 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); |
453 | 474 |
454 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB | 475 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB |
455 // conversion here. That involves an extra copy of each frame to a bitmap. | 476 // conversion here. That involves an extra copy of each frame to a bitmap. |
456 // Obviously, this is suboptimal and should be addressed once ubercompositor | 477 // Obviously, this is suboptimal and should be addressed once ubercompositor |
457 // starts shaping up. | 478 // starts shaping up. |
458 if (software_compositor || texture_needs_rgb_conversion) { | 479 if (software_compositor || texture_needs_rgb_conversion) { |
459 output_resource_format = kRGBResourceFormat; | 480 output_resource_format = kRGBResourceFormat; |
460 output_plane_count = 1; | 481 output_plane_count = 1; |
461 bits_per_channel = 8; | 482 bits_per_channel = 8; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 // by software. | 538 // by software. |
518 video_renderer_->Copy(video_frame, &canvas, media::Context3D()); | 539 video_renderer_->Copy(video_frame, &canvas, media::Context3D()); |
519 } else { | 540 } else { |
520 size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>( | 541 size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>( |
521 video_frame->coded_size().width(), ResourceFormat::RGBA_8888); | 542 video_frame->coded_size().width(), ResourceFormat::RGBA_8888); |
522 size_t needed_size = bytes_per_row * video_frame->coded_size().height(); | 543 size_t needed_size = bytes_per_row * video_frame->coded_size().height(); |
523 if (upload_pixels_.size() < needed_size) | 544 if (upload_pixels_.size() < needed_size) |
524 upload_pixels_.resize(needed_size); | 545 upload_pixels_.resize(needed_size); |
525 | 546 |
526 media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( | 547 media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( |
527 video_frame.get(), &upload_pixels_[0], bytes_per_row); | 548 video_frame.get(), |
| 549 media::SkCanvasVideoRenderer::ConvertingSize::CODED, |
| 550 &upload_pixels_[0], bytes_per_row); |
528 | 551 |
529 resource_provider_->CopyToResource(plane_resource.resource_id(), | 552 resource_provider_->CopyToResource(plane_resource.resource_id(), |
530 &upload_pixels_[0], | 553 &upload_pixels_[0], |
531 plane_resource.resource_size()); | 554 plane_resource.resource_size()); |
532 } | 555 } |
533 plane_resource.SetUniqueId(video_frame->unique_id(), 0); | 556 plane_resource.SetUniqueId(video_frame->unique_id(), 0); |
534 } | 557 } |
535 | 558 |
536 if (software_compositor) { | 559 if (software_compositor) { |
537 external_resources.software_resources.push_back( | 560 external_resources.software_resources.push_back( |
538 plane_resource.resource_id()); | 561 plane_resource.resource_id()); |
539 external_resources.software_release_callback = base::Bind( | 562 external_resources.software_release_callback = base::Bind( |
540 &RecycleResource, AsWeakPtr(), plane_resource.resource_id()); | 563 &RecycleResource, AsWeakPtr(), plane_resource.resource_id()); |
541 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; | 564 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; |
542 } else { | 565 } else { |
543 // VideoResourceUpdater shares a context with the compositor so | 566 // VideoResourceUpdater shares a context with the compositor so |
544 // a sync token is not required. | 567 // a sync token is not required. |
545 TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(), | 568 TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(), |
546 resource_provider_->GetResourceTextureTarget( | 569 resource_provider_->GetResourceTextureTarget( |
547 plane_resource.resource_id())); | 570 plane_resource.resource_id()), |
| 571 plane_resource.resource_size(), false, false); |
548 mailbox.set_color_space(video_frame->ColorSpace()); | 572 mailbox.set_color_space(video_frame->ColorSpace()); |
549 external_resources.mailboxes.push_back(mailbox); | 573 external_resources.mailboxes.push_back(mailbox); |
550 external_resources.release_callbacks.push_back(base::Bind( | 574 external_resources.release_callbacks.push_back(base::Bind( |
551 &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); | 575 &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); |
552 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE; | 576 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE; |
553 } | 577 } |
554 return external_resources; | 578 return external_resources; |
555 } | 579 } |
556 | 580 |
557 std::unique_ptr<HalfFloatMaker> half_float_maker; | 581 std::unique_ptr<HalfFloatMaker> half_float_maker; |
558 if (resource_provider_->YuvResourceFormat(bits_per_channel) == | 582 if (YuvResourceFormat(bits_per_channel) == LUMINANCE_F16) { |
559 LUMINANCE_F16) { | |
560 half_float_maker = NewHalfFloatMaker(bits_per_channel); | 583 half_float_maker = NewHalfFloatMaker(bits_per_channel); |
561 external_resources.offset = half_float_maker->Offset(); | 584 external_resources.offset = half_float_maker->Offset(); |
562 external_resources.multiplier = half_float_maker->Multiplier(); | 585 external_resources.multiplier = half_float_maker->Multiplier(); |
563 } | 586 } |
564 | 587 |
565 for (size_t i = 0; i < plane_resources.size(); ++i) { | 588 for (size_t i = 0; i < plane_resources.size(); ++i) { |
566 PlaneResource& plane_resource = *plane_resources[i]; | 589 PlaneResource& plane_resource = *plane_resources[i]; |
567 // Update each plane's resource id with its content. | 590 // Update each plane's resource id with its content. |
568 DCHECK_EQ(plane_resource.resource_format(), | 591 DCHECK_EQ(plane_resource.resource_format(), |
569 resource_provider_->YuvResourceFormat(bits_per_channel)); | 592 YuvResourceFormat(bits_per_channel)); |
570 | 593 |
571 if (!plane_resource.Matches(video_frame->unique_id(), i)) { | 594 if (!plane_resource.Matches(video_frame->unique_id(), i)) { |
572 // TODO(hubbe): Move all conversion (and upload?) code to media/. | 595 // TODO(hubbe): Move all conversion (and upload?) code to media/. |
573 // We need to transfer data from |video_frame| to the plane resource. | 596 // We need to transfer data from |video_frame| to the plane resource. |
574 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance. | 597 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance. |
575 | 598 |
576 // The |resource_size_pixels| is the size of the resource we want to | 599 // The |resource_size_pixels| is the size of the resource we want to |
577 // upload to. | 600 // upload to. |
578 gfx::Size resource_size_pixels = plane_resource.resource_size(); | 601 gfx::Size resource_size_pixels = plane_resource.resource_size(); |
579 // The |video_stride_bytes| is the width of the video frame we are | 602 // The |video_stride_bytes| is the width of the video frame we are |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 if (lost_resource) { | 824 if (lost_resource) { |
802 resource_it->clear_refs(); | 825 resource_it->clear_refs(); |
803 updater->DeleteResource(resource_it); | 826 updater->DeleteResource(resource_it); |
804 return; | 827 return; |
805 } | 828 } |
806 | 829 |
807 resource_it->remove_ref(); | 830 resource_it->remove_ref(); |
808 } | 831 } |
809 | 832 |
810 } // namespace cc | 833 } // namespace cc |
OLD | NEW |