Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(707)

Side by Side Diff: cc/resources/video_resource_updater.cc

Issue 1761893003: Avoid planar YUV resources when one component EGL images are not supported (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 if (software_compositor) 238 if (software_compositor)
239 return coded_size; 239 return coded_size;
240 240
241 int plane_width = media::VideoFrame::Columns( 241 int plane_width = media::VideoFrame::Columns(
242 plane_index, input_frame->format(), coded_size.width()); 242 plane_index, input_frame->format(), coded_size.width());
243 int plane_height = media::VideoFrame::Rows(plane_index, input_frame->format(), 243 int plane_height = media::VideoFrame::Rows(plane_index, input_frame->format(),
244 coded_size.height()); 244 coded_size.height());
245 return gfx::Size(plane_width, plane_height); 245 return gfx::Size(plane_width, plane_height);
246 } 246 }
247 247
248 VideoResourceUpdater::ResourceList::iterator
249 VideoResourceUpdater::RecycleOrAllocateTexture(const gfx::Size& resource_size,
250 ResourceFormat resource_format,
251 bool immutable_hint) {
252 for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) {
253 // Reuse resource if attributes match and the resource is a currently
254 // unreferenced texture.
255 if (it->ref_count == 0 && !it->mailbox.IsZero() &&
256 it->resource_format == resource_format &&
257 it->resource_size == resource_size &&
258 immutable_hint ==
259 (resource_provider_->GetTextureHint(it->resource_id) ==
260 ResourceProvider::TEXTURE_HINT_IMMUTABLE)) {
261 return it;
262 }
263 }
264
265 return AllocateResource(resource_size, resource_format, true, immutable_hint);
266 }
267
268 // Create an RGB texture by software converting YUV planar data, for the case
269 // where YUV planar textures are not renderable by the GPU.
270 VideoFrameExternalResources
271 VideoResourceUpdater::CreateRGBTextureForSoftwarePlanes(
272 const scoped_refptr<media::VideoFrame>& video_frame) {
273 DCHECK(media::IsYuvPlanar(video_frame->format()));
274
275 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
276 const ResourceFormat resource_format = ResourceFormat::RGBA_8888;
277 const gfx::Size output_plane_resource_size = video_frame->coded_size();
278 const bool is_immutable = false;
279
280 VideoResourceUpdater::ResourceList::iterator resource =
281 RecycleOrAllocateTexture(output_plane_resource_size, resource_format,
282 is_immutable);
283
284 ++resource->ref_count;
285
286 size_t bytes_per_row = ResourceUtil::UncheckedWidthInBytes<size_t>(
287 output_plane_resource_size.width(), ResourceFormat::RGBA_8888);
288 size_t upload_image_stride =
289 MathUtil::UncheckedRoundUp<size_t>(bytes_per_row, 4u);
290 size_t needed_size =
291 upload_image_stride * output_plane_resource_size.height();
292 if (upload_pixels_.size() < needed_size)
293 upload_pixels_.resize(needed_size);
294
295 ResourceProvider::ScopedWriteLockGL lock(resource_provider_,
296 resource->resource_id);
297 media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
298 video_frame.get(), &upload_pixels_[0], upload_image_stride);
299
300 resource_provider_->CopyToResource(resource->resource_id, &upload_pixels_[0],
301 resource->resource_size);
302
303 gpu::SyncToken sync_token;
304 const uint64_t fence_sync = gl->InsertFenceSyncCHROMIUM();
305 gl->ShallowFlushCHROMIUM();
306 gl->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
307
308 VideoFrameExternalResources external_resources;
309
310 external_resources.mailboxes.push_back(
311 TextureMailbox(resource->mailbox, sync_token, GL_TEXTURE_2D,
312 video_frame->coded_size(), false));
313 external_resources.release_callbacks.push_back(
314 base::Bind(&RecycleResource, AsWeakPtr(), resource->resource_id));
315 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE;
316 return external_resources;
317 }
318
248 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( 319 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
249 const scoped_refptr<media::VideoFrame>& video_frame) { 320 const scoped_refptr<media::VideoFrame>& video_frame) {
250 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); 321 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes");
251 const media::VideoPixelFormat input_frame_format = video_frame->format(); 322 const media::VideoPixelFormat input_frame_format = video_frame->format();
252 323
253 // TODO(hubbe): Make this a video frame method. 324 // TODO(hubbe): Make this a video frame method.
254 int bits_per_channel = 0; 325 int bits_per_channel = 0;
255 switch (input_frame_format) { 326 switch (input_frame_format) {
256 case media::PIXEL_FORMAT_UNKNOWN: 327 case media::PIXEL_FORMAT_UNKNOWN:
257 NOTREACHED(); 328 NOTREACHED();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 if (!media::IsYuvPlanar(input_frame_format)) { 360 if (!media::IsYuvPlanar(input_frame_format)) {
290 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format); 361 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format);
291 return VideoFrameExternalResources(); 362 return VideoFrameExternalResources();
292 } 363 }
293 364
294 const bool software_compositor = context_provider_ == NULL; 365 const bool software_compositor = context_provider_ == NULL;
295 366
296 ResourceFormat output_resource_format = 367 ResourceFormat output_resource_format =
297 resource_provider_->YuvResourceFormat(bits_per_channel); 368 resource_provider_->YuvResourceFormat(bits_per_channel);
298 369
370 if (output_resource_format == ResourceFormat::RGBA_8888) {
371 // YUV frames must be converted to RGB before texture upload.
372 return CreateRGBTextureForSoftwarePlanes(video_frame);
373 }
374
299 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); 375 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format);
300 376
301 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB 377 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB
302 // conversion here. That involves an extra copy of each frame to a bitmap. 378 // conversion here. That involves an extra copy of each frame to a bitmap.
303 // Obviously, this is suboptimal and should be addressed once ubercompositor 379 // Obviously, this is suboptimal and should be addressed once ubercompositor
304 // starts shaping up. 380 // starts shaping up.
305 if (software_compositor) { 381 if (software_compositor) {
306 output_resource_format = kRGBResourceFormat; 382 output_resource_format = kRGBResourceFormat;
307 output_plane_count = 1; 383 output_plane_count = 1;
308 } 384 }
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 const scoped_refptr<media::VideoFrame>& video_frame, 627 const scoped_refptr<media::VideoFrame>& video_frame,
552 const gpu::MailboxHolder& mailbox_holder, 628 const gpu::MailboxHolder& mailbox_holder,
553 VideoFrameExternalResources* external_resources) { 629 VideoFrameExternalResources* external_resources) {
554 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); 630 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
555 SyncTokenClientImpl client(gl, mailbox_holder.sync_token); 631 SyncTokenClientImpl client(gl, mailbox_holder.sync_token);
556 632
557 const gfx::Size output_plane_resource_size = video_frame->coded_size(); 633 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 634 // 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. 635 // target to avoid loss of precision or dropping any alpha component.
560 const ResourceFormat copy_target_format = ResourceFormat::RGBA_8888; 636 const ResourceFormat copy_target_format = ResourceFormat::RGBA_8888;
637 const bool is_immutable = false;
561 638
562 // Search for an existing resource to reuse. 639 // Search for an existing resource to reuse.
563 VideoResourceUpdater::ResourceList::iterator resource = all_resources_.end(); 640 ResourceList::iterator resource = RecycleOrAllocateTexture(
564 641 output_plane_resource_size, copy_target_format, is_immutable);
565 for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) {
566 // Reuse resource if attributes match and the resource is a currently
567 // unreferenced texture.
568 if (it->resource_size == output_plane_resource_size &&
569 it->resource_format == copy_target_format && !it->mailbox.IsZero() &&
570 it->ref_count == 0 &&
571 resource_provider_->GetTextureHint(it->resource_id) !=
572 ResourceProvider::TEXTURE_HINT_IMMUTABLE) {
573 resource = it;
574 break;
575 }
576 }
577
578 // Otherwise allocate a new resource.
579 if (resource == all_resources_.end()) {
580 const bool is_immutable = false;
581 resource = AllocateResource(output_plane_resource_size, copy_target_format,
582 true, is_immutable);
583 }
584 642
585 ++resource->ref_count; 643 ++resource->ref_count;
586 644
587 ResourceProvider::ScopedWriteLockGL lock(resource_provider_, 645 ResourceProvider::ScopedWriteLockGL lock(resource_provider_,
588 resource->resource_id); 646 resource->resource_id);
589 uint32_t texture_id = lock.texture_id(); 647 uint32_t texture_id = lock.texture_id();
590 648
591 DCHECK_EQ(resource_provider_->GetResourceTextureTarget(resource->resource_id), 649 DCHECK_EQ(resource_provider_->GetResourceTextureTarget(resource->resource_id),
592 (GLenum)GL_TEXTURE_2D); 650 (GLenum)GL_TEXTURE_2D);
593 651
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 resource_it->ref_count = 0; 745 resource_it->ref_count = 0;
688 updater->DeleteResource(resource_it); 746 updater->DeleteResource(resource_it);
689 return; 747 return;
690 } 748 }
691 749
692 --resource_it->ref_count; 750 --resource_it->ref_count;
693 DCHECK_GE(resource_it->ref_count, 0); 751 DCHECK_GE(resource_it->ref_count, 0);
694 } 752 }
695 753
696 } // namespace cc 754 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698