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

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

Issue 2242453002: 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, 4 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
« no previous file with comments | « cc/resources/video_resource_updater.h ('k') | gpu/command_buffer/common/capabilities.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 : context_provider_(context_provider), 165 : context_provider_(context_provider),
166 resource_provider_(resource_provider) { 166 resource_provider_(resource_provider) {
167 } 167 }
168 168
169 VideoResourceUpdater::~VideoResourceUpdater() { 169 VideoResourceUpdater::~VideoResourceUpdater() {
170 for (const PlaneResource& plane_resource : all_resources_) 170 for (const PlaneResource& plane_resource : all_resources_)
171 resource_provider_->DeleteResource(plane_resource.resource_id()); 171 resource_provider_->DeleteResource(plane_resource.resource_id());
172 } 172 }
173 173
174 VideoResourceUpdater::ResourceList::iterator 174 VideoResourceUpdater::ResourceList::iterator
175 VideoResourceUpdater::RecycleOrAllocateTexture(const gfx::Size& resource_size,
176 ResourceFormat resource_format,
177 bool immutable_hint) {
178 for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) {
179 // Reuse resource if attributes match and the resource is a currently
180 // unreferenced texture.
181 if (it->resource_size() == resource_size &&
182 it->resource_format() == resource_format && !it->mailbox().IsZero() &&
183 !it->has_refs() &&
184 resource_provider_->GetTextureHint(it->resource_id()) !=
185 ResourceProvider::TEXTURE_HINT_IMMUTABLE) {
186 return it;
187 }
188 }
189
190 // Otherwise allocate a new resource.
191 return AllocateResource(resource_size, resource_format, true, immutable_hint);
192 }
193
194 VideoResourceUpdater::ResourceList::iterator
175 VideoResourceUpdater::AllocateResource(const gfx::Size& plane_size, 195 VideoResourceUpdater::AllocateResource(const gfx::Size& plane_size,
176 ResourceFormat format, 196 ResourceFormat format,
177 bool has_mailbox, 197 bool has_mailbox,
178 bool immutable_hint) { 198 bool immutable_hint) {
179 // TODO(danakj): Abstract out hw/sw resource create/delete from 199 // TODO(danakj): Abstract out hw/sw resource create/delete from
180 // ResourceProvider and stop using ResourceProvider in this class. 200 // ResourceProvider and stop using ResourceProvider in this class.
181 const ResourceId resource_id = resource_provider_->CreateResource( 201 const ResourceId resource_id = resource_provider_->CreateResource(
182 plane_size, immutable_hint ? ResourceProvider::TEXTURE_HINT_IMMUTABLE 202 plane_size, immutable_hint ? ResourceProvider::TEXTURE_HINT_IMMUTABLE
183 : ResourceProvider::TEXTURE_HINT_DEFAULT, 203 : ResourceProvider::TEXTURE_HINT_DEFAULT,
184 format); 204 format);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 if (software_compositor) 258 if (software_compositor)
239 return coded_size; 259 return coded_size;
240 260
241 int plane_width = media::VideoFrame::Columns( 261 int plane_width = media::VideoFrame::Columns(
242 plane_index, input_frame->format(), coded_size.width()); 262 plane_index, input_frame->format(), coded_size.width());
243 int plane_height = media::VideoFrame::Rows(plane_index, input_frame->format(), 263 int plane_height = media::VideoFrame::Rows(plane_index, input_frame->format(),
244 coded_size.height()); 264 coded_size.height());
245 return gfx::Size(plane_width, plane_height); 265 return gfx::Size(plane_width, plane_height);
246 } 266 }
247 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 media::VideoFrame* video_frame) {
273 DCHECK(media::IsYuvPlanar(video_frame->format()));
274 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
275 const ResourceFormat resource_format = ResourceFormat::RGBA_8888;
276 const gfx::Size output_plane_resource_size = video_frame->coded_size();
277 const bool is_immutable = false;
278
279 VideoResourceUpdater::ResourceList::iterator resource =
280 RecycleOrAllocateTexture(output_plane_resource_size, resource_format,
281 is_immutable);
282
283 resource->add_ref();
284
285 size_t bytes_per_row = ResourceUtil::UncheckedWidthInBytes<size_t>(
286 output_plane_resource_size.width(), ResourceFormat::RGBA_8888);
287 size_t upload_image_stride =
288 MathUtil::UncheckedRoundUp<size_t>(bytes_per_row, 4u);
dcheng 2016/08/12 22:50:47 Sorry, I think I've asked this before, but can the
Tobias Sargeant 2016/08/15 09:33:04 Ack. Commented in reply.
289 size_t needed_size =
290 upload_image_stride * output_plane_resource_size.height();
291 if (upload_pixels_.size() < needed_size)
292 upload_pixels_.resize(needed_size);
293
294 media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
295 video_frame, &upload_pixels_[0], upload_image_stride);
296
297 resource_provider_->CopyToResource(
298 resource->resource_id(), &upload_pixels_[0], resource->resource_size());
299
300 gpu::SyncToken sync_token;
301 const uint64_t fence_sync = gl->InsertFenceSyncCHROMIUM();
302 gl->ShallowFlushCHROMIUM();
303 gl->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
304
305 VideoFrameExternalResources external_resources;
306
307 external_resources.mailboxes.push_back(
308 TextureMailbox(resource->mailbox(), sync_token, GL_TEXTURE_2D,
309 video_frame->coded_size(), false, false));
310 external_resources.release_callbacks.push_back(
311 base::Bind(&RecycleResource, AsWeakPtr(), resource->resource_id()));
312 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE;
313 return external_resources;
314 }
315
248 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( 316 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
249 scoped_refptr<media::VideoFrame> video_frame) { 317 scoped_refptr<media::VideoFrame> video_frame) {
250 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes"); 318 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes");
251 const media::VideoPixelFormat input_frame_format = video_frame->format(); 319 const media::VideoPixelFormat input_frame_format = video_frame->format();
252 320
253 // TODO(hubbe): Make this a video frame method. 321 // TODO(hubbe): Make this a video frame method.
254 int bits_per_channel = 0; 322 int bits_per_channel = 0;
255 switch (input_frame_format) { 323 switch (input_frame_format) {
256 case media::PIXEL_FORMAT_UNKNOWN: 324 case media::PIXEL_FORMAT_UNKNOWN:
257 NOTREACHED(); 325 NOTREACHED();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 if (!media::IsYuvPlanar(input_frame_format)) { 357 if (!media::IsYuvPlanar(input_frame_format)) {
290 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format); 358 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format);
291 return VideoFrameExternalResources(); 359 return VideoFrameExternalResources();
292 } 360 }
293 361
294 const bool software_compositor = context_provider_ == NULL; 362 const bool software_compositor = context_provider_ == NULL;
295 363
296 ResourceFormat output_resource_format = 364 ResourceFormat output_resource_format =
297 resource_provider_->YuvResourceFormat(bits_per_channel); 365 resource_provider_->YuvResourceFormat(bits_per_channel);
298 366
367 if (!software_compositor &&
liberato (no reviews please) 2016/08/12 22:09:23 is it possible to avoid switching the resource for
Tobias Sargeant 2016/08/15 09:33:04 It will only be set to 8888 for GPU resources, so
liberato (no reviews please) 2016/08/16 14:55:46 makes sense. probably deserves a comment to that
Tobias Sargeant 2016/08/16 15:19:10 I updated the comment to make the intent clearer.
368 output_resource_format == ResourceFormat::RGBA_8888) {
369 // If the output resource format is RGB, then YUV frames must be converted
370 // to RGB before texture upload.
371 return CreateRGBTextureForSoftwarePlanes(video_frame.get());
372 }
373
299 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); 374 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format);
300 375
301 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB 376 // 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. 377 // conversion here. That involves an extra copy of each frame to a bitmap.
303 // Obviously, this is suboptimal and should be addressed once ubercompositor 378 // Obviously, this is suboptimal and should be addressed once ubercompositor
304 // starts shaping up. 379 // starts shaping up.
305 if (software_compositor) { 380 if (software_compositor) {
306 output_resource_format = kRGBResourceFormat; 381 output_resource_format = kRGBResourceFormat;
307 output_plane_count = 1; 382 output_plane_count = 1;
308 } 383 }
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 const gpu::MailboxHolder& mailbox_holder, 631 const gpu::MailboxHolder& mailbox_holder,
557 VideoFrameExternalResources* external_resources) { 632 VideoFrameExternalResources* external_resources) {
558 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); 633 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
559 SyncTokenClientImpl client(gl, mailbox_holder.sync_token); 634 SyncTokenClientImpl client(gl, mailbox_holder.sync_token);
560 635
561 const gfx::Size output_plane_resource_size = video_frame->coded_size(); 636 const gfx::Size output_plane_resource_size = video_frame->coded_size();
562 // The copy needs to be a direct transfer of pixel data, so we use an RGBA8 637 // The copy needs to be a direct transfer of pixel data, so we use an RGBA8
563 // target to avoid loss of precision or dropping any alpha component. 638 // target to avoid loss of precision or dropping any alpha component.
564 const ResourceFormat copy_target_format = ResourceFormat::RGBA_8888; 639 const ResourceFormat copy_target_format = ResourceFormat::RGBA_8888;
565 640
566 // Search for an existing resource to reuse. 641 const bool is_immutable = false;
567 VideoResourceUpdater::ResourceList::iterator resource = all_resources_.end(); 642 VideoResourceUpdater::ResourceList::iterator resource =
568 643 RecycleOrAllocateTexture(output_plane_resource_size, copy_target_format,
569 for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) { 644 is_immutable);
570 // Reuse resource if attributes match and the resource is a currently
571 // unreferenced texture.
572 if (it->resource_size() == output_plane_resource_size &&
573 it->resource_format() == copy_target_format &&
574 !it->mailbox().IsZero() && !it->has_refs() &&
575 resource_provider_->GetTextureHint(it->resource_id()) !=
576 ResourceProvider::TEXTURE_HINT_IMMUTABLE) {
577 resource = it;
578 break;
579 }
580 }
581
582 // Otherwise allocate a new resource.
583 if (resource == all_resources_.end()) {
584 const bool is_immutable = false;
585 resource = AllocateResource(output_plane_resource_size, copy_target_format,
586 true, is_immutable);
587 }
588 645
589 resource->add_ref(); 646 resource->add_ref();
590 647
591 ResourceProvider::ScopedWriteLockGL lock(resource_provider_, 648 ResourceProvider::ScopedWriteLockGL lock(resource_provider_,
592 resource->resource_id(), false); 649 resource->resource_id(), false);
593 DCHECK_EQ( 650 DCHECK_EQ(
594 resource_provider_->GetResourceTextureTarget(resource->resource_id()), 651 resource_provider_->GetResourceTextureTarget(resource->resource_id()),
595 (GLenum)GL_TEXTURE_2D); 652 (GLenum)GL_TEXTURE_2D);
596 653
597 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); 654 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData());
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 if (lost_resource) { 752 if (lost_resource) {
696 resource_it->clear_refs(); 753 resource_it->clear_refs();
697 updater->DeleteResource(resource_it); 754 updater->DeleteResource(resource_it);
698 return; 755 return;
699 } 756 }
700 757
701 resource_it->remove_ref(); 758 resource_it->remove_ref();
702 } 759 }
703 760
704 } // namespace cc 761 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/video_resource_updater.h ('k') | gpu/command_buffer/common/capabilities.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698