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 |