| 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 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 PlaneResource(resource_id, plane_size, format, mailbox)); | 202 PlaneResource(resource_id, plane_size, format, mailbox)); |
| 203 return all_resources_.begin(); | 203 return all_resources_.begin(); |
| 204 } | 204 } |
| 205 | 205 |
| 206 void VideoResourceUpdater::DeleteResource(ResourceList::iterator resource_it) { | 206 void VideoResourceUpdater::DeleteResource(ResourceList::iterator resource_it) { |
| 207 DCHECK_EQ(resource_it->ref_count, 0); | 207 DCHECK_EQ(resource_it->ref_count, 0); |
| 208 resource_provider_->DeleteResource(resource_it->resource_id); | 208 resource_provider_->DeleteResource(resource_it->resource_id); |
| 209 all_resources_.erase(resource_it); | 209 all_resources_.erase(resource_it); |
| 210 } | 210 } |
| 211 | 211 |
| 212 VideoFrameExternalResources VideoResourceUpdater:: | 212 VideoFrameExternalResources |
| 213 CreateExternalResourcesFromVideoFrame( | 213 VideoResourceUpdater::CreateExternalResourcesFromVideoFrame( |
| 214 const scoped_refptr<media::VideoFrame>& video_frame) { | 214 scoped_refptr<media::VideoFrame> video_frame) { |
| 215 #if defined(VIDEO_HOLE) | 215 #if defined(VIDEO_HOLE) |
| 216 if (video_frame->storage_type() == media::VideoFrame::STORAGE_HOLE) { | 216 if (video_frame->storage_type() == media::VideoFrame::STORAGE_HOLE) { |
| 217 VideoFrameExternalResources external_resources; | 217 VideoFrameExternalResources external_resources; |
| 218 external_resources.type = VideoFrameExternalResources::HOLE; | 218 external_resources.type = VideoFrameExternalResources::HOLE; |
| 219 return external_resources; | 219 return external_resources; |
| 220 } | 220 } |
| 221 #endif // defined(VIDEO_HOLE) | 221 #endif // defined(VIDEO_HOLE) |
| 222 if (video_frame->format() == media::PIXEL_FORMAT_UNKNOWN) | 222 if (video_frame->format() == media::PIXEL_FORMAT_UNKNOWN) |
| 223 return VideoFrameExternalResources(); | 223 return VideoFrameExternalResources(); |
| 224 DCHECK(video_frame->HasTextures() || video_frame->IsMappable()); | 224 DCHECK(video_frame->HasTextures() || video_frame->IsMappable()); |
| 225 if (video_frame->HasTextures()) | 225 if (video_frame->HasTextures()) |
| 226 return CreateForHardwarePlanes(video_frame); | 226 return CreateForHardwarePlanes(std::move(video_frame)); |
| 227 else | 227 else |
| 228 return CreateForSoftwarePlanes(video_frame); | 228 return CreateForSoftwarePlanes(std::move(video_frame)); |
| 229 } | 229 } |
| 230 | 230 |
| 231 // For frames that we receive in software format, determine the dimensions of | 231 // For frames that we receive in software format, determine the dimensions of |
| 232 // each plane in the frame. | 232 // each plane in the frame. |
| 233 static gfx::Size SoftwarePlaneDimension( | 233 static gfx::Size SoftwarePlaneDimension(media::VideoFrame* input_frame, |
| 234 const scoped_refptr<media::VideoFrame>& input_frame, | 234 bool software_compositor, |
| 235 bool software_compositor, | 235 size_t plane_index) { |
| 236 size_t plane_index) { | |
| 237 gfx::Size coded_size = input_frame->coded_size(); | 236 gfx::Size coded_size = input_frame->coded_size(); |
| 238 if (software_compositor) | 237 if (software_compositor) |
| 239 return coded_size; | 238 return coded_size; |
| 240 | 239 |
| 241 int plane_width = media::VideoFrame::Columns( | 240 int plane_width = media::VideoFrame::Columns( |
| 242 plane_index, input_frame->format(), coded_size.width()); | 241 plane_index, input_frame->format(), coded_size.width()); |
| 243 int plane_height = media::VideoFrame::Rows(plane_index, input_frame->format(), | 242 int plane_height = media::VideoFrame::Rows(plane_index, input_frame->format(), |
| 244 coded_size.height()); | 243 coded_size.height()); |
| 245 return gfx::Size(plane_width, plane_height); | 244 return gfx::Size(plane_width, plane_height); |
| 246 } | 245 } |
| 247 | 246 |
| 248 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( | 247 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
| 249 const scoped_refptr<media::VideoFrame>& video_frame) { | 248 scoped_refptr<media::VideoFrame> video_frame) { |
| 250 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); | 249 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); |
| 251 const media::VideoPixelFormat input_frame_format = video_frame->format(); | 250 const media::VideoPixelFormat input_frame_format = video_frame->format(); |
| 252 | 251 |
| 253 // TODO(hubbe): Make this a video frame method. | 252 // TODO(hubbe): Make this a video frame method. |
| 254 int bits_per_channel = 0; | 253 int bits_per_channel = 0; |
| 255 switch (input_frame_format) { | 254 switch (input_frame_format) { |
| 256 case media::PIXEL_FORMAT_UNKNOWN: | 255 case media::PIXEL_FORMAT_UNKNOWN: |
| 257 NOTREACHED(); | 256 NOTREACHED(); |
| 258 // Fall through! | 257 // Fall through! |
| 259 case media::PIXEL_FORMAT_I420: | 258 case media::PIXEL_FORMAT_I420: |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 if (it->ref_count == 0 && it->resource_format != output_resource_format) | 311 if (it->ref_count == 0 && it->resource_format != output_resource_format) |
| 313 DeleteResource(it++); | 312 DeleteResource(it++); |
| 314 else | 313 else |
| 315 ++it; | 314 ++it; |
| 316 } | 315 } |
| 317 | 316 |
| 318 const int max_resource_size = resource_provider_->max_texture_size(); | 317 const int max_resource_size = resource_provider_->max_texture_size(); |
| 319 std::vector<ResourceList::iterator> plane_resources; | 318 std::vector<ResourceList::iterator> plane_resources; |
| 320 for (size_t i = 0; i < output_plane_count; ++i) { | 319 for (size_t i = 0; i < output_plane_count; ++i) { |
| 321 gfx::Size output_plane_resource_size = | 320 gfx::Size output_plane_resource_size = |
| 322 SoftwarePlaneDimension(video_frame, software_compositor, i); | 321 SoftwarePlaneDimension(video_frame.get(), software_compositor, i); |
| 323 if (output_plane_resource_size.IsEmpty() || | 322 if (output_plane_resource_size.IsEmpty() || |
| 324 output_plane_resource_size.width() > max_resource_size || | 323 output_plane_resource_size.width() > max_resource_size || |
| 325 output_plane_resource_size.height() > max_resource_size) { | 324 output_plane_resource_size.height() > max_resource_size) { |
| 326 break; | 325 break; |
| 327 } | 326 } |
| 328 | 327 |
| 329 // Try recycle a previously-allocated resource. | 328 // Try recycle a previously-allocated resource. |
| 330 ResourceList::iterator resource_it = all_resources_.end(); | 329 ResourceList::iterator resource_it = all_resources_.end(); |
| 331 for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) { | 330 for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) { |
| 332 if (it->resource_size == output_plane_resource_size && | 331 if (it->resource_size == output_plane_resource_size && |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 // returned by the compositor and emit a WaitSyncTokenCHROMIUM on | 540 // returned by the compositor and emit a WaitSyncTokenCHROMIUM on |
| 542 // |video_frame|'s previous sync point using the current GL context. | 541 // |video_frame|'s previous sync point using the current GL context. |
| 543 SyncTokenClientImpl client(updater->context_provider_->ContextGL(), | 542 SyncTokenClientImpl client(updater->context_provider_->ContextGL(), |
| 544 sync_token); | 543 sync_token); |
| 545 video_frame->UpdateReleaseSyncToken(&client); | 544 video_frame->UpdateReleaseSyncToken(&client); |
| 546 } | 545 } |
| 547 | 546 |
| 548 // Create a copy of a texture-backed source video frame in a new GL_TEXTURE_2D | 547 // Create a copy of a texture-backed source video frame in a new GL_TEXTURE_2D |
| 549 // texture. | 548 // texture. |
| 550 void VideoResourceUpdater::CopyPlaneTexture( | 549 void VideoResourceUpdater::CopyPlaneTexture( |
| 551 const scoped_refptr<media::VideoFrame>& video_frame, | 550 media::VideoFrame* video_frame, |
| 552 const gpu::MailboxHolder& mailbox_holder, | 551 const gpu::MailboxHolder& mailbox_holder, |
| 553 VideoFrameExternalResources* external_resources) { | 552 VideoFrameExternalResources* external_resources) { |
| 554 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); | 553 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); |
| 555 SyncTokenClientImpl client(gl, mailbox_holder.sync_token); | 554 SyncTokenClientImpl client(gl, mailbox_holder.sync_token); |
| 556 | 555 |
| 557 const gfx::Size output_plane_resource_size = video_frame->coded_size(); | 556 const gfx::Size output_plane_resource_size = video_frame->coded_size(); |
| 558 // The copy needs to be a direct transfer of pixel data, so we use an RGBA8 | 557 // The copy needs to be a direct transfer of pixel data, so we use an RGBA8 |
| 559 // target to avoid loss of precision or dropping any alpha component. | 558 // target to avoid loss of precision or dropping any alpha component. |
| 560 const ResourceFormat copy_target_format = ResourceFormat::RGBA_8888; | 559 const ResourceFormat copy_target_format = ResourceFormat::RGBA_8888; |
| 561 | 560 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 | 610 |
| 612 external_resources->mailboxes.push_back( | 611 external_resources->mailboxes.push_back( |
| 613 TextureMailbox(resource->mailbox, sync_token, GL_TEXTURE_2D, | 612 TextureMailbox(resource->mailbox, sync_token, GL_TEXTURE_2D, |
| 614 video_frame->coded_size(), false, false)); | 613 video_frame->coded_size(), false, false)); |
| 615 | 614 |
| 616 external_resources->release_callbacks.push_back( | 615 external_resources->release_callbacks.push_back( |
| 617 base::Bind(&RecycleResource, AsWeakPtr(), resource->resource_id)); | 616 base::Bind(&RecycleResource, AsWeakPtr(), resource->resource_id)); |
| 618 } | 617 } |
| 619 | 618 |
| 620 VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes( | 619 VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes( |
| 621 const scoped_refptr<media::VideoFrame>& video_frame) { | 620 scoped_refptr<media::VideoFrame> video_frame) { |
| 622 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForHardwarePlanes"); | 621 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForHardwarePlanes"); |
| 623 DCHECK(video_frame->HasTextures()); | 622 DCHECK(video_frame->HasTextures()); |
| 624 if (!context_provider_) | 623 if (!context_provider_) |
| 625 return VideoFrameExternalResources(); | 624 return VideoFrameExternalResources(); |
| 626 | 625 |
| 627 VideoFrameExternalResources external_resources; | 626 VideoFrameExternalResources external_resources; |
| 628 if (video_frame->metadata()->IsTrue( | 627 if (video_frame->metadata()->IsTrue( |
| 629 media::VideoFrameMetadata::READ_LOCK_FENCES_ENABLED)) { | 628 media::VideoFrameMetadata::READ_LOCK_FENCES_ENABLED)) { |
| 630 external_resources.read_lock_fences_enabled = true; | 629 external_resources.read_lock_fences_enabled = true; |
| 631 } | 630 } |
| 632 | 631 |
| 633 external_resources.type = ResourceTypeForVideoFrame(video_frame.get()); | 632 external_resources.type = ResourceTypeForVideoFrame(video_frame.get()); |
| 634 if (external_resources.type == VideoFrameExternalResources::NONE) { | 633 if (external_resources.type == VideoFrameExternalResources::NONE) { |
| 635 DLOG(ERROR) << "Unsupported Texture format" | 634 DLOG(ERROR) << "Unsupported Texture format" |
| 636 << media::VideoPixelFormatToString(video_frame->format()); | 635 << media::VideoPixelFormatToString(video_frame->format()); |
| 637 return external_resources; | 636 return external_resources; |
| 638 } | 637 } |
| 639 | 638 |
| 640 const size_t num_planes = media::VideoFrame::NumPlanes(video_frame->format()); | 639 const size_t num_planes = media::VideoFrame::NumPlanes(video_frame->format()); |
| 641 for (size_t i = 0; i < num_planes; ++i) { | 640 for (size_t i = 0; i < num_planes; ++i) { |
| 642 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(i); | 641 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(i); |
| 643 if (mailbox_holder.mailbox.IsZero()) | 642 if (mailbox_holder.mailbox.IsZero()) |
| 644 break; | 643 break; |
| 645 | 644 |
| 646 if (video_frame->metadata()->IsTrue( | 645 if (video_frame->metadata()->IsTrue( |
| 647 media::VideoFrameMetadata::COPY_REQUIRED)) { | 646 media::VideoFrameMetadata::COPY_REQUIRED)) { |
| 648 CopyPlaneTexture(video_frame, mailbox_holder, &external_resources); | 647 CopyPlaneTexture(video_frame.get(), mailbox_holder, &external_resources); |
| 649 } else { | 648 } else { |
| 650 external_resources.mailboxes.push_back(TextureMailbox( | 649 external_resources.mailboxes.push_back(TextureMailbox( |
| 651 mailbox_holder.mailbox, mailbox_holder.sync_token, | 650 mailbox_holder.mailbox, mailbox_holder.sync_token, |
| 652 mailbox_holder.texture_target, video_frame->coded_size(), | 651 mailbox_holder.texture_target, video_frame->coded_size(), |
| 653 video_frame->metadata()->IsTrue( | 652 video_frame->metadata()->IsTrue( |
| 654 media::VideoFrameMetadata::ALLOW_OVERLAY), | 653 media::VideoFrameMetadata::ALLOW_OVERLAY), |
| 655 false)); | 654 false)); |
| 656 | 655 |
| 657 external_resources.release_callbacks.push_back( | 656 external_resources.release_callbacks.push_back( |
| 658 base::Bind(&ReturnTexture, AsWeakPtr(), video_frame)); | 657 base::Bind(&ReturnTexture, AsWeakPtr(), video_frame)); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 691 resource_it->ref_count = 0; | 690 resource_it->ref_count = 0; |
| 692 updater->DeleteResource(resource_it); | 691 updater->DeleteResource(resource_it); |
| 693 return; | 692 return; |
| 694 } | 693 } |
| 695 | 694 |
| 696 --resource_it->ref_count; | 695 --resource_it->ref_count; |
| 697 DCHECK_GE(resource_it->ref_count, 0); | 696 DCHECK_GE(resource_it->ref_count, 0); |
| 698 } | 697 } |
| 699 | 698 |
| 700 } // namespace cc | 699 } // namespace cc |
| OLD | NEW |