| 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> | 
| 11 | 11 | 
| 12 #include "base/bind.h" | 12 #include "base/bind.h" | 
| 13 #include "base/bit_cast.h" | 13 #include "base/bit_cast.h" | 
| 14 #include "base/trace_event/trace_event.h" | 14 #include "base/trace_event/trace_event.h" | 
| 15 #include "cc/base/math_util.h" | 15 #include "cc/base/math_util.h" | 
| 16 #include "cc/output/gl_renderer.h" | 16 #include "cc/output/gl_renderer.h" | 
| 17 #include "cc/resources/resource_provider.h" | 17 #include "cc/resources/resource_provider.h" | 
| 18 #include "cc/resources/resource_util.h" | 18 #include "cc/resources/resource_util.h" | 
| 19 #include "gpu/GLES2/gl2extchromium.h" | 19 #include "gpu/GLES2/gl2extchromium.h" | 
| 20 #include "gpu/command_buffer/client/gles2_interface.h" | 20 #include "gpu/command_buffer/client/gles2_interface.h" | 
|  | 21 #include "media/base/media_switches.h" | 
| 21 #include "media/base/video_frame.h" | 22 #include "media/base/video_frame.h" | 
| 22 #include "media/renderers/skcanvas_video_renderer.h" | 23 #include "media/renderers/skcanvas_video_renderer.h" | 
| 23 #include "third_party/khronos/GLES2/gl2.h" | 24 #include "third_party/khronos/GLES2/gl2.h" | 
| 24 #include "third_party/khronos/GLES2/gl2ext.h" | 25 #include "third_party/khronos/GLES2/gl2ext.h" | 
| 25 #include "third_party/libyuv/include/libyuv.h" | 26 #include "third_party/libyuv/include/libyuv.h" | 
| 26 #include "third_party/skia/include/core/SkCanvas.h" | 27 #include "third_party/skia/include/core/SkCanvas.h" | 
| 27 #include "ui/gfx/geometry/size_conversions.h" | 28 #include "ui/gfx/geometry/size_conversions.h" | 
| 28 | 29 | 
| 29 namespace cc { | 30 namespace cc { | 
| 30 | 31 | 
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 150 void VideoResourceUpdater::PlaneResource::SetUniqueId(int unique_frame_id, | 151 void VideoResourceUpdater::PlaneResource::SetUniqueId(int unique_frame_id, | 
| 151                                                       size_t plane_index) { | 152                                                       size_t plane_index) { | 
| 152   DCHECK_EQ(ref_count_, 1); | 153   DCHECK_EQ(ref_count_, 1); | 
| 153   plane_index_ = plane_index; | 154   plane_index_ = plane_index; | 
| 154   unique_frame_id_ = unique_frame_id; | 155   unique_frame_id_ = unique_frame_id; | 
| 155   has_unique_frame_id_and_plane_index_ = true; | 156   has_unique_frame_id_and_plane_index_ = true; | 
| 156 } | 157 } | 
| 157 | 158 | 
| 158 VideoFrameExternalResources::VideoFrameExternalResources() | 159 VideoFrameExternalResources::VideoFrameExternalResources() | 
| 159     : type(NONE), | 160     : type(NONE), | 
|  | 161       format(RGBA_8888), | 
| 160       read_lock_fences_enabled(false), | 162       read_lock_fences_enabled(false), | 
| 161       offset(0.0f), | 163       offset(0.0f), | 
| 162       multiplier(1.0f), | 164       multiplier(1.0f), | 
| 163       bits_per_channel(8) {} | 165       bits_per_channel(8) {} | 
| 164 | 166 | 
| 165 VideoFrameExternalResources::VideoFrameExternalResources( | 167 VideoFrameExternalResources::VideoFrameExternalResources( | 
| 166     const VideoFrameExternalResources& other) = default; | 168     const VideoFrameExternalResources& other) = default; | 
| 167 | 169 | 
| 168 VideoFrameExternalResources::~VideoFrameExternalResources() {} | 170 VideoFrameExternalResources::~VideoFrameExternalResources() {} | 
| 169 | 171 | 
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 301                                           uint16_t* dst) { | 303                                           uint16_t* dst) { | 
| 302   // Source and dest stride can be zero since we're only copying | 304   // Source and dest stride can be zero since we're only copying | 
| 303   // one row at a time. | 305   // one row at a time. | 
| 304   int stride = 0; | 306   int stride = 0; | 
| 305   // Maximum value used in |src|. | 307   // Maximum value used in |src|. | 
| 306   int max_value = (1 << bits_per_channel) - 1; | 308   int max_value = (1 << bits_per_channel) - 1; | 
| 307   int rows = 1; | 309   int rows = 1; | 
| 308   libyuv::HalfFloatPlane(src, stride, dst, stride, 1.0f / max_value, num, rows); | 310   libyuv::HalfFloatPlane(src, stride, dst, stride, 1.0f / max_value, num, rows); | 
| 309 } | 311 } | 
| 310 | 312 | 
|  | 313 ResourceFormat VideoResourceUpdater::YuvResourceFormat(int bits) const { | 
|  | 314   if (!context_provider_) | 
|  | 315     return LUMINANCE_8; | 
|  | 316 | 
|  | 317   const auto caps = context_provider_->ContextCapabilities(); | 
|  | 318   if (caps.disable_one_component_textures) | 
|  | 319     return RGBA_8888; | 
|  | 320 | 
|  | 321   ResourceFormat yuv_resource_format = caps.texture_rg ? RED_8 : LUMINANCE_8; | 
|  | 322   if (bits <= 8) | 
|  | 323     return yuv_resource_format; | 
|  | 324 | 
|  | 325   if (caps.texture_half_float_linear) | 
|  | 326     return LUMINANCE_F16; | 
|  | 327 | 
|  | 328   if (base::FeatureList::IsEnabled(media::kUseRGTexture) || use_rg_for_testing_) | 
|  | 329     return caps.texture_rg ? RG_88 : RGBA_8888; | 
|  | 330 | 
|  | 331   return yuv_resource_format; | 
|  | 332 } | 
|  | 333 | 
| 311 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( | 334 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( | 
| 312     scoped_refptr<media::VideoFrame> video_frame) { | 335     scoped_refptr<media::VideoFrame> video_frame) { | 
| 313   TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); | 336   TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); | 
| 314   const media::VideoPixelFormat input_frame_format = video_frame->format(); | 337   const media::VideoPixelFormat input_frame_format = video_frame->format(); | 
| 315 | 338 | 
| 316   // TODO(hubbe): Make this a video frame method. | 339   // TODO(hubbe): Make this a video frame method. | 
|  | 340   // TODO(dshwang): handle YUV4XXPX by GMBs pool code. crbug.com/445071 | 
| 317   int bits_per_channel = 0; | 341   int bits_per_channel = 0; | 
| 318   switch (input_frame_format) { | 342   switch (input_frame_format) { | 
| 319     case media::PIXEL_FORMAT_UNKNOWN: | 343     case media::PIXEL_FORMAT_UNKNOWN: | 
| 320       NOTREACHED(); | 344       NOTREACHED(); | 
| 321     // Fall through! | 345     // Fall through! | 
| 322     case media::PIXEL_FORMAT_I420: | 346     case media::PIXEL_FORMAT_I420: | 
| 323     case media::PIXEL_FORMAT_YV12: | 347     case media::PIXEL_FORMAT_YV12: | 
| 324     case media::PIXEL_FORMAT_YV16: | 348     case media::PIXEL_FORMAT_YV16: | 
| 325     case media::PIXEL_FORMAT_YV12A: | 349     case media::PIXEL_FORMAT_YV12A: | 
| 326     case media::PIXEL_FORMAT_YV24: | 350     case media::PIXEL_FORMAT_YV24: | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 350     case media::PIXEL_FORMAT_YUV420P12: | 374     case media::PIXEL_FORMAT_YUV420P12: | 
| 351     case media::PIXEL_FORMAT_YUV422P12: | 375     case media::PIXEL_FORMAT_YUV422P12: | 
| 352     case media::PIXEL_FORMAT_YUV444P12: | 376     case media::PIXEL_FORMAT_YUV444P12: | 
| 353       bits_per_channel = 12; | 377       bits_per_channel = 12; | 
| 354       break; | 378       break; | 
| 355     case media::PIXEL_FORMAT_Y16: | 379     case media::PIXEL_FORMAT_Y16: | 
| 356       bits_per_channel = 16; | 380       bits_per_channel = 16; | 
| 357       break; | 381       break; | 
| 358   } | 382   } | 
| 359 | 383 | 
| 360   // TODO(dshwang): support PIXEL_FORMAT_Y16. crbug.com/624436 |  | 
| 361   DCHECK_NE(bits_per_channel, 16); |  | 
| 362 |  | 
| 363   // Only YUV software video frames are supported. | 384   // Only YUV software video frames are supported. | 
| 364   if (!media::IsYuvPlanar(input_frame_format)) { | 385   if (!media::IsYuvPlanar(input_frame_format)) { | 
| 365     NOTREACHED() << media::VideoPixelFormatToString(input_frame_format); | 386     NOTREACHED() << media::VideoPixelFormatToString(input_frame_format); | 
| 366     return VideoFrameExternalResources(); | 387     return VideoFrameExternalResources(); | 
| 367   } | 388   } | 
| 368 | 389 | 
| 369   const bool software_compositor = context_provider_ == NULL; | 390   const bool software_compositor = context_provider_ == nullptr; | 
|  | 391   bool disable_one_component_textures = true; | 
|  | 392   if (!software_compositor) { | 
|  | 393     const auto caps = context_provider_->ContextCapabilities(); | 
|  | 394     disable_one_component_textures = caps.disable_one_component_textures; | 
|  | 395   } | 
| 370 | 396 | 
| 371   ResourceFormat output_resource_format = | 397   ResourceFormat output_resource_format = YuvResourceFormat(bits_per_channel); | 
| 372       resource_provider_->YuvResourceFormat(bits_per_channel); |  | 
| 373 | 398 | 
| 374   // If GPU compositing is enabled, but the output resource format | 399   // If GPU compositing is enabled, but the output resource format | 
| 375   // returned by the resource provider is RGBA_8888, then a GPU driver | 400   // returned by the resource provider is RGBA_8888, then a GPU driver | 
| 376   // bug workaround requires that YUV frames must be converted to RGB | 401   // bug workaround requires that YUV frames must be converted to RGB | 
| 377   // before texture upload. | 402   // before texture upload. | 
| 378   bool texture_needs_rgb_conversion = | 403   bool texture_needs_rgb_conversion = | 
| 379       !software_compositor && | 404       !software_compositor && disable_one_component_textures; | 
| 380       output_resource_format == ResourceFormat::RGBA_8888; |  | 
| 381   size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); | 405   size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); | 
| 382 | 406 | 
| 383   // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB | 407   // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB | 
| 384   // conversion here. That involves an extra copy of each frame to a bitmap. | 408   // conversion here. That involves an extra copy of each frame to a bitmap. | 
| 385   // Obviously, this is suboptimal and should be addressed once ubercompositor | 409   // Obviously, this is suboptimal and should be addressed once ubercompositor | 
| 386   // starts shaping up. | 410   // starts shaping up. | 
| 387   if (software_compositor || texture_needs_rgb_conversion) { | 411   if (software_compositor || texture_needs_rgb_conversion) { | 
| 388     output_resource_format = kRGBResourceFormat; | 412     output_resource_format = kRGBResourceFormat; | 
| 389     output_plane_count = 1; | 413     output_plane_count = 1; | 
| 390     bits_per_channel = 8; | 414     bits_per_channel = 8; | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 417     ResourceList::iterator resource_it = RecycleOrAllocateResource( | 441     ResourceList::iterator resource_it = RecycleOrAllocateResource( | 
| 418         output_plane_resource_size, output_resource_format, | 442         output_plane_resource_size, output_resource_format, | 
| 419         video_frame->ColorSpace(), software_compositor, is_immutable, | 443         video_frame->ColorSpace(), software_compositor, is_immutable, | 
| 420         video_frame->unique_id(), i); | 444         video_frame->unique_id(), i); | 
| 421 | 445 | 
| 422     resource_it->add_ref(); | 446     resource_it->add_ref(); | 
| 423     plane_resources.push_back(resource_it); | 447     plane_resources.push_back(resource_it); | 
| 424   } | 448   } | 
| 425 | 449 | 
| 426   VideoFrameExternalResources external_resources; | 450   VideoFrameExternalResources external_resources; | 
| 427 |  | 
| 428   external_resources.bits_per_channel = bits_per_channel; | 451   external_resources.bits_per_channel = bits_per_channel; | 
|  | 452   external_resources.format = output_resource_format; | 
| 429 | 453 | 
| 430   if (software_compositor || texture_needs_rgb_conversion) { | 454   if (software_compositor || texture_needs_rgb_conversion) { | 
| 431     DCHECK_EQ(plane_resources.size(), 1u); | 455     DCHECK_EQ(plane_resources.size(), 1u); | 
| 432     PlaneResource& plane_resource = *plane_resources[0]; | 456     PlaneResource& plane_resource = *plane_resources[0]; | 
| 433     DCHECK_EQ(plane_resource.resource_format(), kRGBResourceFormat); | 457     DCHECK_EQ(plane_resource.resource_format(), kRGBResourceFormat); | 
| 434     DCHECK_EQ(software_compositor, plane_resource.mailbox().IsZero()); | 458     DCHECK_EQ(software_compositor, plane_resource.mailbox().IsZero()); | 
| 435 | 459 | 
| 436     if (!plane_resource.Matches(video_frame->unique_id(), 0)) { | 460     if (!plane_resource.Matches(video_frame->unique_id(), 0)) { | 
| 437       // We need to transfer data from |video_frame| to the plane resource. | 461       // We need to transfer data from |video_frame| to the plane resource. | 
| 438       if (software_compositor) { | 462       if (software_compositor) { | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 476                                  plane_resource.resource_id())); | 500                                  plane_resource.resource_id())); | 
| 477       mailbox.set_color_space(video_frame->ColorSpace()); | 501       mailbox.set_color_space(video_frame->ColorSpace()); | 
| 478       external_resources.mailboxes.push_back(mailbox); | 502       external_resources.mailboxes.push_back(mailbox); | 
| 479       external_resources.release_callbacks.push_back(base::Bind( | 503       external_resources.release_callbacks.push_back(base::Bind( | 
| 480           &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); | 504           &RecycleResource, AsWeakPtr(), plane_resource.resource_id())); | 
| 481       external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE; | 505       external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE; | 
| 482     } | 506     } | 
| 483     return external_resources; | 507     return external_resources; | 
| 484   } | 508   } | 
| 485 | 509 | 
| 486   for (size_t i = 0; i < plane_resources.size(); ++i) { | 510   const bool highbit_rg_rgba_fallback = | 
| 487     PlaneResource& plane_resource = *plane_resources[i]; | 511       bits_per_channel > 8 && output_resource_format == RGBA_8888; | 
|  | 512   bool needs_conversion = false; | 
|  | 513   int shift = 0; | 
|  | 514   if (output_resource_format == LUMINANCE_F16) { | 
|  | 515     // LUMINANCE_F16 uses half-floats, so we always need a conversion step. | 
|  | 516     needs_conversion = true; | 
|  | 517   } else if (output_resource_format == RG_88) { | 
|  | 518     // RG_88 can represent 16bit int, so we don't need a conversion step. | 
|  | 519     needs_conversion = false; | 
|  | 520   } else if (highbit_rg_rgba_fallback) { | 
|  | 521     // RG channels is used to represent 16bit int. | 
|  | 522     needs_conversion = true; | 
|  | 523   } else if (bits_per_channel > 8) { | 
|  | 524     // If bits_per_channel > 8 and we can't use RG_88, we need to | 
|  | 525     // shift the data down and create an 8-bit texture. | 
|  | 526     needs_conversion = true; | 
|  | 527     shift = bits_per_channel - 8; | 
|  | 528     external_resources.bits_per_channel = 8; | 
|  | 529   } | 
|  | 530 | 
|  | 531   for (size_t plane = 0; plane < plane_resources.size(); ++plane) { | 
|  | 532     PlaneResource& plane_resource = *plane_resources[plane]; | 
| 488     // Update each plane's resource id with its content. | 533     // Update each plane's resource id with its content. | 
| 489     DCHECK_EQ(plane_resource.resource_format(), | 534     DCHECK_EQ(plane_resource.resource_format(), output_resource_format); | 
| 490               resource_provider_->YuvResourceFormat(bits_per_channel)); |  | 
| 491 | 535 | 
| 492     if (!plane_resource.Matches(video_frame->unique_id(), i)) { | 536     if (!plane_resource.Matches(video_frame->unique_id(), plane)) { | 
| 493       // TODO(hubbe): Move all conversion (and upload?) code to media/. | 537       // TODO(hubbe): Move all conversion (and upload?) code to media/. | 
| 494       // We need to transfer data from |video_frame| to the plane resource. | 538       // We need to transfer data from |video_frame| to the plane resource. | 
| 495       // TODO(reveman): Can use GpuMemoryBuffers here to improve performance. | 539       // TODO(reveman): Can use GpuMemoryBuffers here to improve performance. | 
| 496 | 540 | 
| 497       // The |resource_size_pixels| is the size of the resource we want to | 541       // The |resource_size_pixels| is the size of the resource we want to | 
| 498       // upload to. | 542       // upload to. | 
| 499       gfx::Size resource_size_pixels = plane_resource.resource_size(); | 543       gfx::Size resource_size_pixels = plane_resource.resource_size(); | 
| 500       // The |video_stride_bytes| is the width of the video frame we are | 544       // The |video_stride_bytes| is the width of the video frame we are | 
| 501       // uploading (including non-frame data to fill in the stride). | 545       // uploading (including non-frame data to fill in the stride). | 
| 502       int video_stride_bytes = video_frame->stride(i); | 546       int video_stride_bytes = video_frame->stride(plane); | 
| 503 | 547 | 
| 504       size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>( | 548       size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>( | 
| 505           resource_size_pixels.width(), plane_resource.resource_format()); | 549           resource_size_pixels.width(), output_resource_format); | 
| 506       // Use 4-byte row alignment (OpenGL default) for upload performance. | 550       // Use 4-byte row alignment (OpenGL default) for upload performance. | 
| 507       // Assuming that GL_UNPACK_ALIGNMENT has not changed from default. | 551       // Assuming that GL_UNPACK_ALIGNMENT has not changed from default. | 
| 508       size_t upload_image_stride = | 552       size_t upload_image_stride = | 
| 509           MathUtil::CheckedRoundUp<size_t>(bytes_per_row, 4u); | 553           MathUtil::CheckedRoundUp<size_t>(bytes_per_row, 4u); | 
| 510 | 554 | 
| 511       bool needs_conversion = false; |  | 
| 512       int shift = 0; |  | 
| 513 |  | 
| 514       // LUMINANCE_F16 uses half-floats, so we always need a conversion step. |  | 
| 515       if (plane_resource.resource_format() == LUMINANCE_F16) { |  | 
| 516         needs_conversion = true; |  | 
| 517       } else if (bits_per_channel > 8) { |  | 
| 518         // If bits_per_channel > 8 and we can't use LUMINANCE_F16, we need to |  | 
| 519         // shift the data down and create an 8-bit texture. |  | 
| 520         needs_conversion = true; |  | 
| 521         shift = bits_per_channel - 8; |  | 
| 522       } |  | 
| 523       const uint8_t* pixels; | 555       const uint8_t* pixels; | 
| 524       if (static_cast<int>(upload_image_stride) == video_stride_bytes && | 556       if (static_cast<int>(upload_image_stride) == video_stride_bytes && | 
| 525           !needs_conversion) { | 557           !needs_conversion) { | 
| 526         pixels = video_frame->data(i); | 558         pixels = video_frame->data(plane); | 
| 527       } else { | 559       } else { | 
| 528         // Avoid malloc for each frame/plane if possible. | 560         // Avoid malloc for each frame/plane if possible. | 
| 529         size_t needed_size = | 561         size_t needed_size = | 
| 530             upload_image_stride * resource_size_pixels.height(); | 562             upload_image_stride * resource_size_pixels.height(); | 
| 531         if (upload_pixels_.size() < needed_size) | 563         if (upload_pixels_.size() < needed_size) | 
| 532           upload_pixels_.resize(needed_size); | 564           upload_pixels_.resize(needed_size); | 
| 533 | 565 | 
| 534         for (int row = 0; row < resource_size_pixels.height(); ++row) { | 566         for (int row = 0; row < resource_size_pixels.height(); ++row) { | 
| 535           if (plane_resource.resource_format() == LUMINANCE_F16) { | 567           if (output_resource_format == LUMINANCE_F16) { | 
| 536             uint16_t* dst = reinterpret_cast<uint16_t*>( | 568             uint16_t* dst = reinterpret_cast<uint16_t*>( | 
| 537                 &upload_pixels_[upload_image_stride * row]); | 569                 &upload_pixels_[upload_image_stride * row]); | 
| 538             const uint16_t* src = reinterpret_cast<uint16_t*>( | 570             const uint16_t* src = reinterpret_cast<uint16_t*>( | 
| 539                 video_frame->data(i) + (video_stride_bytes * row)); | 571                 video_frame->data(plane) + (video_stride_bytes * row)); | 
| 540             if (bits_per_channel <= 10) { | 572             if (bits_per_channel <= 10) { | 
| 541               // Micro-benchmarking indicates that the compiler does | 573               // Micro-benchmarking indicates that the compiler does | 
| 542               // a good enough job of optimizing this loop that trying | 574               // a good enough job of optimizing this loop that trying | 
| 543               // to manually operate on one uint64 at a time is not | 575               // to manually operate on one uint64 at a time is not | 
| 544               // actually helpful. | 576               // actually helpful. | 
| 545               // Note to future optimizers: Benchmark your optimizations! | 577               // Note to future optimizers: Benchmark your optimizations! | 
| 546               for (size_t i = 0; i < bytes_per_row / 2; i++) | 578               for (size_t i = 0; i < bytes_per_row / 2; i++) | 
| 547                 dst[i] = src[i] | 0x3800; | 579                 dst[i] = src[i] | 0x3800; | 
| 548             } else { | 580             } else { | 
| 549               MakeHalfFloats(src, bits_per_channel, bytes_per_row / 2, dst); | 581               MakeHalfFloats(src, bits_per_channel, bytes_per_row / 2, dst); | 
| 550             } | 582             } | 
|  | 583           } else if (highbit_rg_rgba_fallback) { | 
|  | 584             uint32_t* dst = reinterpret_cast<uint32_t*>( | 
|  | 585                 &upload_pixels_[upload_image_stride * row]); | 
|  | 586             const uint16_t* src = reinterpret_cast<uint16_t*>( | 
|  | 587                 video_frame->data(plane) + (video_stride_bytes * row)); | 
|  | 588             for (int i = 0; i < resource_size_pixels.width(); i++) | 
|  | 589               dst[i] = src[i]; | 
| 551           } else if (shift != 0) { | 590           } else if (shift != 0) { | 
| 552             // We have more-than-8-bit input which we need to shift | 591             // We have more-than-8-bit input which we need to shift | 
| 553             // down to fit it into an 8-bit texture. | 592             // down to fit it into an 8-bit texture. | 
| 554             uint8_t* dst = &upload_pixels_[upload_image_stride * row]; | 593             uint8_t* dst = &upload_pixels_[upload_image_stride * row]; | 
| 555             const uint16_t* src = reinterpret_cast<uint16_t*>( | 594             const uint16_t* src = reinterpret_cast<uint16_t*>( | 
| 556                 video_frame->data(i) + (video_stride_bytes * row)); | 595                 video_frame->data(plane) + (video_stride_bytes * row)); | 
| 557             for (size_t i = 0; i < bytes_per_row; i++) | 596             for (size_t i = 0; i < bytes_per_row; i++) | 
| 558               dst[i] = src[i] >> shift; | 597               dst[i] = src[i] >> shift; | 
| 559           } else { | 598           } else { | 
| 560             // Input and output are the same size and format, but | 599             // Input and output are the same size and format, but | 
| 561             // differ in stride, copy one row at a time. | 600             // differ in stride, copy one row at a time. | 
| 562             uint8_t* dst = &upload_pixels_[upload_image_stride * row]; | 601             uint8_t* dst = &upload_pixels_[upload_image_stride * row]; | 
| 563             const uint8_t* src = | 602             const uint8_t* src = | 
| 564                 video_frame->data(i) + (video_stride_bytes * row); | 603                 video_frame->data(plane) + (video_stride_bytes * row); | 
| 565             memcpy(dst, src, bytes_per_row); | 604             memcpy(dst, src, bytes_per_row); | 
| 566           } | 605           } | 
| 567         } | 606         } | 
| 568         pixels = &upload_pixels_[0]; | 607         pixels = &upload_pixels_[0]; | 
| 569       } | 608       } | 
| 570 | 609 | 
| 571       resource_provider_->CopyToResource(plane_resource.resource_id(), pixels, | 610       resource_provider_->CopyToResource(plane_resource.resource_id(), pixels, | 
| 572                                          resource_size_pixels); | 611                                          resource_size_pixels); | 
| 573       plane_resource.SetUniqueId(video_frame->unique_id(), i); | 612       plane_resource.SetUniqueId(video_frame->unique_id(), plane); | 
| 574     } | 613     } | 
| 575 | 614 | 
| 576     if (plane_resource.resource_format() == LUMINANCE_F16) { | 615     if (plane_resource.resource_format() == LUMINANCE_F16) { | 
| 577       // If the input data was 9 or 10 bit, and we output to half-floats, | 616       // If the input data was 9 or 10 bit, and we output to half-floats, | 
| 578       // then we used the OR path above, which means that we need to | 617       // then we used the OR path above, which means that we need to | 
| 579       // adjust the resource offset and multiplier accordingly. If the | 618       // adjust the resource offset and multiplier accordingly. If the | 
| 580       // input data uses more than 10 bits, it will already be normalized | 619       // input data uses more than 10 bits, it will already be normalized | 
| 581       // to 0.0..1.0, so there is no need to do anything. | 620       // to 0.0..1.0, so there is no need to do anything. | 
| 582       if (bits_per_channel <= 10) { | 621       if (bits_per_channel <= 10) { | 
| 583         // By OR-ing with 0x3800, 10-bit numbers become half-floats in the | 622         // By OR-ing with 0x3800, 10-bit numbers become half-floats in the | 
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 762   if (lost_resource) { | 801   if (lost_resource) { | 
| 763     resource_it->clear_refs(); | 802     resource_it->clear_refs(); | 
| 764     updater->DeleteResource(resource_it); | 803     updater->DeleteResource(resource_it); | 
| 765     return; | 804     return; | 
| 766   } | 805   } | 
| 767 | 806 | 
| 768   resource_it->remove_ref(); | 807   resource_it->remove_ref(); | 
| 769 } | 808 } | 
| 770 | 809 | 
| 771 }  // namespace cc | 810 }  // namespace cc | 
| OLD | NEW | 
|---|