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

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: rebase Created 4 years, 3 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 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 : context_provider_(context_provider), 166 : context_provider_(context_provider),
167 resource_provider_(resource_provider) { 167 resource_provider_(resource_provider) {
168 } 168 }
169 169
170 VideoResourceUpdater::~VideoResourceUpdater() { 170 VideoResourceUpdater::~VideoResourceUpdater() {
171 for (const PlaneResource& plane_resource : all_resources_) 171 for (const PlaneResource& plane_resource : all_resources_)
172 resource_provider_->DeleteResource(plane_resource.resource_id()); 172 resource_provider_->DeleteResource(plane_resource.resource_id());
173 } 173 }
174 174
175 VideoResourceUpdater::ResourceList::iterator 175 VideoResourceUpdater::ResourceList::iterator
176 VideoResourceUpdater::RecycleOrAllocateResource(
177 const gfx::Size& resource_size,
178 ResourceFormat resource_format,
179 const gfx::ColorSpace& color_space,
180 bool software_resource,
181 bool immutable_hint,
182 int unique_id,
183 int plane_index) {
184 for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) {
185 if (it->Matches(unique_id, plane_index)) {
186 DCHECK(it->resource_size() == resource_size);
187 DCHECK(it->resource_format() == resource_format);
188 DCHECK(it->mailbox().IsZero() == software_resource);
189 return it;
190 }
191 }
192 for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) {
193 if (it->resource_size() == resource_size &&
194 it->resource_format() == resource_format &&
195 it->mailbox().IsZero() == software_resource && !it->has_refs()) {
196 if (software_resource) {
197 // This extra check is needed because resources backed by SharedMemory
198 // are not ref-counted, unlike mailboxes. Full discussion in
199 // codereview.chromium.org/145273021.
200 if (!resource_provider_->InUseByConsumer(it->resource_id()))
201 return it;
202 } else {
203 if (immutable_hint ==
204 (resource_provider_->GetTextureHint(it->resource_id()) ==
danakj 2016/08/26 18:24:23 doesn't this need to match the immutable hint? In
Tobias Sargeant 2016/08/30 11:31:06 This should only return resources if they have sim
205 ResourceProvider::TEXTURE_HINT_IMMUTABLE))
206 return it;
207 }
208 }
209 }
210
211 // Otherwise allocate a new resource.
212 return AllocateResource(resource_size, resource_format, color_space,
213 !software_resource, immutable_hint);
214 }
215
216 VideoResourceUpdater::ResourceList::iterator
176 VideoResourceUpdater::AllocateResource(const gfx::Size& plane_size, 217 VideoResourceUpdater::AllocateResource(const gfx::Size& plane_size,
177 ResourceFormat format, 218 ResourceFormat format,
178 const gfx::ColorSpace& color_space, 219 const gfx::ColorSpace& color_space,
179 bool has_mailbox, 220 bool has_mailbox,
180 bool immutable_hint) { 221 bool immutable_hint) {
181 // TODO(danakj): Abstract out hw/sw resource create/delete from 222 // TODO(danakj): Abstract out hw/sw resource create/delete from
182 // ResourceProvider and stop using ResourceProvider in this class. 223 // ResourceProvider and stop using ResourceProvider in this class.
183 const ResourceId resource_id = resource_provider_->CreateResource( 224 const ResourceId resource_id = resource_provider_->CreateResource(
184 plane_size, immutable_hint ? ResourceProvider::TEXTURE_HINT_IMMUTABLE 225 plane_size, immutable_hint ? ResourceProvider::TEXTURE_HINT_IMMUTABLE
185 : ResourceProvider::TEXTURE_HINT_DEFAULT, 226 : ResourceProvider::TEXTURE_HINT_DEFAULT,
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 if (!media::IsYuvPlanar(input_frame_format)) { 332 if (!media::IsYuvPlanar(input_frame_format)) {
292 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format); 333 NOTREACHED() << media::VideoPixelFormatToString(input_frame_format);
293 return VideoFrameExternalResources(); 334 return VideoFrameExternalResources();
294 } 335 }
295 336
296 const bool software_compositor = context_provider_ == NULL; 337 const bool software_compositor = context_provider_ == NULL;
297 338
298 ResourceFormat output_resource_format = 339 ResourceFormat output_resource_format =
299 resource_provider_->YuvResourceFormat(bits_per_channel); 340 resource_provider_->YuvResourceFormat(bits_per_channel);
300 341
342 // If GPU compositing is enabled, but the output resource format
343 // returned by the resource provider is RGBA_8888, then a GPU driver
344 // bug workaround requires that YUV frames must be converted to RGB
345 // before texture upload.
346 bool texture_needs_rgb_conversion =
347 !software_compositor &&
348 output_resource_format == ResourceFormat::RGBA_8888;
301 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format); 349 size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format);
302 350
303 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB 351 // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB
304 // conversion here. That involves an extra copy of each frame to a bitmap. 352 // conversion here. That involves an extra copy of each frame to a bitmap.
305 // Obviously, this is suboptimal and should be addressed once ubercompositor 353 // Obviously, this is suboptimal and should be addressed once ubercompositor
306 // starts shaping up. 354 // starts shaping up.
307 if (software_compositor) { 355 if (software_compositor || texture_needs_rgb_conversion) {
308 output_resource_format = kRGBResourceFormat; 356 output_resource_format = kRGBResourceFormat;
309 output_plane_count = 1; 357 output_plane_count = 1;
358 bits_per_channel = 8;
310 } 359 }
311 360
312 // Drop recycled resources that are the wrong format. 361 // Drop recycled resources that are the wrong format.
313 for (auto it = all_resources_.begin(); it != all_resources_.end();) { 362 for (auto it = all_resources_.begin(); it != all_resources_.end();) {
314 if (!it->has_refs() && it->resource_format() != output_resource_format) 363 if (!it->has_refs() && it->resource_format() != output_resource_format)
315 DeleteResource(it++); 364 DeleteResource(it++);
316 else 365 else
317 ++it; 366 ++it;
318 } 367 }
319 368
320 const int max_resource_size = resource_provider_->max_texture_size(); 369 const int max_resource_size = resource_provider_->max_texture_size();
321 std::vector<ResourceList::iterator> plane_resources; 370 std::vector<ResourceList::iterator> plane_resources;
322 for (size_t i = 0; i < output_plane_count; ++i) { 371 for (size_t i = 0; i < output_plane_count; ++i) {
323 gfx::Size output_plane_resource_size = 372 gfx::Size output_plane_resource_size =
324 SoftwarePlaneDimension(video_frame.get(), software_compositor, i); 373 SoftwarePlaneDimension(video_frame.get(), software_compositor, i);
325 if (output_plane_resource_size.IsEmpty() || 374 if (output_plane_resource_size.IsEmpty() ||
326 output_plane_resource_size.width() > max_resource_size || 375 output_plane_resource_size.width() > max_resource_size ||
327 output_plane_resource_size.height() > max_resource_size) { 376 output_plane_resource_size.height() > max_resource_size) {
328 break; 377 break;
329 } 378 }
330 379
331 // Try recycle a previously-allocated resource. 380 const bool is_immutable = true;
332 ResourceList::iterator resource_it = all_resources_.end(); 381 ResourceList::iterator resource_it = RecycleOrAllocateResource(
333 for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) { 382 output_plane_resource_size, output_resource_format,
334 if (it->resource_size() == output_plane_resource_size && 383 video_frame->ColorSpace(), software_compositor, is_immutable,
335 it->resource_format() == output_resource_format) { 384 video_frame->unique_id(), i);
336 if (it->Matches(video_frame->unique_id(), i)) {
337 // Bingo, we found a resource that already contains the data we are
338 // planning to put in it. It's safe to reuse it even if
339 // resource_provider_ holds some references to it, because those
340 // references are read-only.
341 resource_it = it;
342 break;
343 }
344 385
345 // This extra check is needed because resources backed by SharedMemory
346 // are not ref-counted, unlike mailboxes. Full discussion in
347 // codereview.chromium.org/145273021.
348 const bool in_use =
349 software_compositor &&
350 resource_provider_->InUseByConsumer(it->resource_id());
351 if (!it->has_refs() && !in_use) {
352 // We found a resource with the correct size that we can overwrite.
353 resource_it = it;
354 }
355 }
356 }
357
358 // Check if we need to allocate a new resource.
359 if (resource_it == all_resources_.end()) {
360 const bool is_immutable = true;
361 resource_it = AllocateResource(
362 output_plane_resource_size, output_resource_format,
363 video_frame->ColorSpace(), !software_compositor, is_immutable);
364 }
365 if (resource_it == all_resources_.end()) 386 if (resource_it == all_resources_.end())
366 break; 387 break;
367 388
368 resource_it->add_ref(); 389 resource_it->add_ref();
369 plane_resources.push_back(resource_it); 390 plane_resources.push_back(resource_it);
370 } 391 }
371 392
372 if (plane_resources.size() != output_plane_count) { 393 if (plane_resources.size() != output_plane_count) {
373 // Allocation failed, nothing will be returned so restore reference counts. 394 // Allocation failed, nothing will be returned so restore reference counts.
374 for (ResourceList::iterator resource_it : plane_resources) 395 for (ResourceList::iterator resource_it : plane_resources)
375 resource_it->remove_ref(); 396 resource_it->remove_ref();
376 return VideoFrameExternalResources(); 397 return VideoFrameExternalResources();
377 } 398 }
378 399
379 VideoFrameExternalResources external_resources; 400 VideoFrameExternalResources external_resources;
380 401
381 external_resources.bits_per_channel = bits_per_channel; 402 external_resources.bits_per_channel = bits_per_channel;
382 403
383 if (software_compositor) { 404 if (software_compositor || texture_needs_rgb_conversion) {
384 DCHECK_EQ(plane_resources.size(), 1u); 405 DCHECK_EQ(plane_resources.size(), 1u);
385 PlaneResource& plane_resource = *plane_resources[0]; 406 PlaneResource& plane_resource = *plane_resources[0];
386 DCHECK_EQ(plane_resource.resource_format(), kRGBResourceFormat); 407 DCHECK_EQ(plane_resource.resource_format(), kRGBResourceFormat);
387 DCHECK(plane_resource.mailbox().IsZero()); 408 DCHECK(software_compositor == plane_resource.mailbox().IsZero());
danakj 2016/08/26 18:24:23 DCHECK_EQ
Tobias Sargeant 2016/08/30 11:31:06 Done.
388 409
389 if (!plane_resource.Matches(video_frame->unique_id(), 0)) { 410 if (!plane_resource.Matches(video_frame->unique_id(), 0)) {
390 // We need to transfer data from |video_frame| to the plane resource. 411 // We need to transfer data from |video_frame| to the plane resource.
391 if (!video_renderer_) 412 if (software_compositor) {
392 video_renderer_.reset(new media::SkCanvasVideoRenderer); 413 if (!video_renderer_)
414 video_renderer_.reset(new media::SkCanvasVideoRenderer);
393 415
394 ResourceProvider::ScopedWriteLockSoftware lock( 416 ResourceProvider::ScopedWriteLockSoftware lock(
395 resource_provider_, plane_resource.resource_id()); 417 resource_provider_, plane_resource.resource_id());
396 SkCanvas canvas(lock.sk_bitmap()); 418 SkCanvas canvas(lock.sk_bitmap());
397 // This is software path, so canvas and video_frame are always backed 419 // This is software path, so canvas and video_frame are always backed
398 // by software. 420 // by software.
399 video_renderer_->Copy(video_frame, &canvas, media::Context3D()); 421 video_renderer_->Copy(video_frame, &canvas, media::Context3D());
422 } else {
423 size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>(
424 video_frame->coded_size().width(), ResourceFormat::RGBA_8888);
425 size_t needed_size = bytes_per_row * video_frame->coded_size().height();
426 if (upload_pixels_.size() < needed_size)
427 upload_pixels_.resize(needed_size);
428
429 media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
430 video_frame.get(), &upload_pixels_[0], bytes_per_row);
431
432 resource_provider_->CopyToResource(plane_resource.resource_id(),
433 &upload_pixels_[0],
434 plane_resource.resource_size());
435 }
400 plane_resource.SetUniqueId(video_frame->unique_id(), 0); 436 plane_resource.SetUniqueId(video_frame->unique_id(), 0);
401 } 437 }
402 438
403 external_resources.software_resources.push_back( 439 if (software_compositor) {
404 plane_resource.resource_id()); 440 external_resources.software_resources.push_back(
405 external_resources.software_release_callback = 441 plane_resource.resource_id());
406 base::Bind(&RecycleResource, AsWeakPtr(), plane_resource.resource_id()); 442 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE;
407 external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; 443 } else {
444 TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(),
danakj 2016/08/26 18:24:23 why no SyncToken?
Tobias Sargeant 2016/08/30 11:31:05 This is identical to the mailbox construction on l
danakj 2016/09/02 22:58:15 Oh, I guess this class is relying on it sharing th
Tobias Sargeant 2016/09/12 14:25:25 I've added the comment. Given our discussion, it l
445 resource_provider_->GetResourceTextureTarget(
446 plane_resource.resource_id()));
447 mailbox.set_color_space(video_frame->ColorSpace());
448 external_resources.mailboxes.push_back(mailbox);
449 external_resources.type = VideoFrameExternalResources::RGBA_RESOURCE;
450 }
451 external_resources.release_callbacks.push_back(base::Bind(
452 &RecycleResource, AsWeakPtr(), plane_resource.resource_id()));
408 return external_resources; 453 return external_resources;
409 } 454 }
410 455
411 for (size_t i = 0; i < plane_resources.size(); ++i) { 456 for (size_t i = 0; i < plane_resources.size(); ++i) {
412 PlaneResource& plane_resource = *plane_resources[i]; 457 PlaneResource& plane_resource = *plane_resources[i];
413 // Update each plane's resource id with its content. 458 // Update each plane's resource id with its content.
414 DCHECK_EQ(plane_resource.resource_format(), 459 DCHECK_EQ(plane_resource.resource_format(),
415 resource_provider_->YuvResourceFormat(bits_per_channel)); 460 resource_provider_->YuvResourceFormat(bits_per_channel));
416 461
417 if (!plane_resource.Matches(video_frame->unique_id(), i)) { 462 if (!plane_resource.Matches(video_frame->unique_id(), i)) {
418 // We need to transfer data from |video_frame| to the plane resource. 463 // We need to transfer data from |video_frame| to the plane resource.
419 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance. 464 // TODO(reveman): Can use GpuMemoryBuffers here to improve performance.
420 465
421 // The |resource_size_pixels| is the size of the resource we want to 466 // The |resource_size_pixels| is the size of the resource we want to
422 // upload to. 467 // upload to.
423 gfx::Size resource_size_pixels = plane_resource.resource_size(); 468 gfx::Size resource_size_pixels = plane_resource.resource_size();
424 // The |video_stride_bytes| is the width of the video frame we are 469 // The |video_stride_bytes| is the width of the video frame we are
425 // uploading (including non-frame data to fill in the stride). 470 // uploading (including non-frame data to fill in the stride).
426 int video_stride_bytes = video_frame->stride(i); 471 int video_stride_bytes = video_frame->stride(i);
427 472
428 size_t bytes_per_row = ResourceUtil::UncheckedWidthInBytes<size_t>( 473 size_t bytes_per_row = ResourceUtil::CheckedWidthInBytes<size_t>(
429 resource_size_pixels.width(), plane_resource.resource_format()); 474 resource_size_pixels.width(), plane_resource.resource_format());
430 // Use 4-byte row alignment (OpenGL default) for upload performance. 475 // Use 4-byte row alignment (OpenGL default) for upload performance.
431 // Assuming that GL_UNPACK_ALIGNMENT has not changed from default. 476 // Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
432 size_t upload_image_stride = 477 size_t upload_image_stride =
433 MathUtil::UncheckedRoundUp<size_t>(bytes_per_row, 4u); 478 MathUtil::CheckedRoundUp<size_t>(bytes_per_row, 4u);
434 479
435 bool needs_conversion = false; 480 bool needs_conversion = false;
436 int shift = 0; 481 int shift = 0;
437 482
438 // LUMINANCE_F16 uses half-floats, so we always need a conversion step. 483 // LUMINANCE_F16 uses half-floats, so we always need a conversion step.
439 if (plane_resource.resource_format() == LUMINANCE_F16) { 484 if (plane_resource.resource_format() == LUMINANCE_F16) {
440 needs_conversion = true; 485 needs_conversion = true;
441 // Note that the current method of converting integers to half-floats 486 // Note that the current method of converting integers to half-floats
442 // stops working if you have more than 10 bits of data. 487 // stops working if you have more than 10 bits of data.
443 DCHECK_LE(bits_per_channel, 10); 488 DCHECK_LE(bits_per_channel, 10);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 // Update the release sync point in |video_frame| with |sync_token| 591 // Update the release sync point in |video_frame| with |sync_token|
547 // returned by the compositor and emit a WaitSyncTokenCHROMIUM on 592 // returned by the compositor and emit a WaitSyncTokenCHROMIUM on
548 // |video_frame|'s previous sync point using the current GL context. 593 // |video_frame|'s previous sync point using the current GL context.
549 SyncTokenClientImpl client(updater->context_provider_->ContextGL(), 594 SyncTokenClientImpl client(updater->context_provider_->ContextGL(),
550 sync_token); 595 sync_token);
551 video_frame->UpdateReleaseSyncToken(&client); 596 video_frame->UpdateReleaseSyncToken(&client);
552 } 597 }
553 598
554 // Create a copy of a texture-backed source video frame in a new GL_TEXTURE_2D 599 // Create a copy of a texture-backed source video frame in a new GL_TEXTURE_2D
555 // texture. 600 // texture.
556 void VideoResourceUpdater::CopyPlaneTexture( 601 bool VideoResourceUpdater::CopyPlaneTexture(
557 media::VideoFrame* video_frame, 602 media::VideoFrame* video_frame,
558 const gpu::MailboxHolder& mailbox_holder, 603 const gpu::MailboxHolder& mailbox_holder,
559 VideoFrameExternalResources* external_resources) { 604 VideoFrameExternalResources* external_resources) {
560 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL(); 605 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
561 SyncTokenClientImpl client(gl, mailbox_holder.sync_token); 606 SyncTokenClientImpl client(gl, mailbox_holder.sync_token);
562 607
563 const gfx::Size output_plane_resource_size = video_frame->coded_size(); 608 const gfx::Size output_plane_resource_size = video_frame->coded_size();
564 // The copy needs to be a direct transfer of pixel data, so we use an RGBA8 609 // The copy needs to be a direct transfer of pixel data, so we use an RGBA8
565 // target to avoid loss of precision or dropping any alpha component. 610 // target to avoid loss of precision or dropping any alpha component.
566 const ResourceFormat copy_target_format = ResourceFormat::RGBA_8888; 611 const ResourceFormat copy_target_format = ResourceFormat::RGBA_8888;
567 612
568 // Search for an existing resource to reuse. 613 const bool is_immutable = false;
569 VideoResourceUpdater::ResourceList::iterator resource = all_resources_.end(); 614 VideoResourceUpdater::ResourceList::iterator resource =
570 615 RecycleOrAllocateResource(output_plane_resource_size, copy_target_format,
danakj 2016/08/26 18:24:23 Hm, but if it uses a resource with references on i
Tobias Sargeant 2016/08/30 11:31:06 Passing -1 for the unique_id and plane_number prev
571 for (auto it = all_resources_.begin(); it != all_resources_.end(); ++it) { 616 video_frame->ColorSpace(), false, is_immutable,
572 // Reuse resource if attributes match and the resource is a currently 617 -1, -1);
573 // unreferenced texture.
574 if (it->resource_size() == output_plane_resource_size &&
575 it->resource_format() == copy_target_format &&
576 !it->mailbox().IsZero() && !it->has_refs() &&
577 resource_provider_->GetTextureHint(it->resource_id()) !=
578 ResourceProvider::TEXTURE_HINT_IMMUTABLE) {
579 resource = it;
580 break;
581 }
582 }
583
584 // Otherwise allocate a new resource.
585 if (resource == all_resources_.end()) { 618 if (resource == all_resources_.end()) {
586 const bool is_immutable = false; 619 return false;
587 resource = AllocateResource(output_plane_resource_size, copy_target_format,
588 video_frame->ColorSpace(), true, is_immutable);
589 } 620 }
590 621
591 resource->add_ref(); 622 resource->add_ref();
592 623
593 ResourceProvider::ScopedWriteLockGL lock(resource_provider_, 624 ResourceProvider::ScopedWriteLockGL lock(resource_provider_,
594 resource->resource_id(), false); 625 resource->resource_id(), false);
595 DCHECK_EQ( 626 DCHECK_EQ(
596 resource_provider_->GetResourceTextureTarget(resource->resource_id()), 627 resource_provider_->GetResourceTextureTarget(resource->resource_id()),
597 (GLenum)GL_TEXTURE_2D); 628 (GLenum)GL_TEXTURE_2D);
598 629
(...skipping 15 matching lines...) Expand all
614 // Done with the source video frame texture at this point. 645 // Done with the source video frame texture at this point.
615 video_frame->UpdateReleaseSyncToken(&client); 646 video_frame->UpdateReleaseSyncToken(&client);
616 647
617 TextureMailbox mailbox(resource->mailbox(), sync_token, GL_TEXTURE_2D, 648 TextureMailbox mailbox(resource->mailbox(), sync_token, GL_TEXTURE_2D,
618 video_frame->coded_size(), false, false); 649 video_frame->coded_size(), false, false);
619 mailbox.set_color_space(video_frame->ColorSpace()); 650 mailbox.set_color_space(video_frame->ColorSpace());
620 external_resources->mailboxes.push_back(mailbox); 651 external_resources->mailboxes.push_back(mailbox);
621 652
622 external_resources->release_callbacks.push_back( 653 external_resources->release_callbacks.push_back(
623 base::Bind(&RecycleResource, AsWeakPtr(), resource->resource_id())); 654 base::Bind(&RecycleResource, AsWeakPtr(), resource->resource_id()));
655
656 return true;
624 } 657 }
625 658
626 VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes( 659 VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes(
627 scoped_refptr<media::VideoFrame> video_frame) { 660 scoped_refptr<media::VideoFrame> video_frame) {
628 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForHardwarePlanes"); 661 TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForHardwarePlanes");
629 DCHECK(video_frame->HasTextures()); 662 DCHECK(video_frame->HasTextures());
630 if (!context_provider_) 663 if (!context_provider_)
631 return VideoFrameExternalResources(); 664 return VideoFrameExternalResources();
632 665
633 VideoFrameExternalResources external_resources; 666 VideoFrameExternalResources external_resources;
(...skipping 10 matching lines...) Expand all
644 } 677 }
645 678
646 const size_t num_planes = media::VideoFrame::NumPlanes(video_frame->format()); 679 const size_t num_planes = media::VideoFrame::NumPlanes(video_frame->format());
647 for (size_t i = 0; i < num_planes; ++i) { 680 for (size_t i = 0; i < num_planes; ++i) {
648 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(i); 681 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(i);
649 if (mailbox_holder.mailbox.IsZero()) 682 if (mailbox_holder.mailbox.IsZero())
650 break; 683 break;
651 684
652 if (video_frame->metadata()->IsTrue( 685 if (video_frame->metadata()->IsTrue(
653 media::VideoFrameMetadata::COPY_REQUIRED)) { 686 media::VideoFrameMetadata::COPY_REQUIRED)) {
654 CopyPlaneTexture(video_frame.get(), mailbox_holder, &external_resources); 687 if (!CopyPlaneTexture(video_frame.get(), mailbox_holder,
688 &external_resources)) {
689 return VideoFrameExternalResources();
690 }
655 } else { 691 } else {
656 TextureMailbox mailbox(mailbox_holder.mailbox, mailbox_holder.sync_token, 692 TextureMailbox mailbox(mailbox_holder.mailbox, mailbox_holder.sync_token,
657 mailbox_holder.texture_target, 693 mailbox_holder.texture_target,
658 video_frame->coded_size(), 694 video_frame->coded_size(),
659 video_frame->metadata()->IsTrue( 695 video_frame->metadata()->IsTrue(
660 media::VideoFrameMetadata::ALLOW_OVERLAY), 696 media::VideoFrameMetadata::ALLOW_OVERLAY),
661 false); 697 false);
662 mailbox.set_color_space(video_frame->ColorSpace()); 698 mailbox.set_color_space(video_frame->ColorSpace());
663 external_resources.mailboxes.push_back(mailbox); 699 external_resources.mailboxes.push_back(mailbox);
664 external_resources.release_callbacks.push_back( 700 external_resources.release_callbacks.push_back(
665 base::Bind(&ReturnTexture, AsWeakPtr(), video_frame)); 701 base::Bind(&ReturnTexture, AsWeakPtr(), video_frame));
666 } 702 }
667 } 703 }
668 return external_resources; 704 return external_resources;
669 } 705 }
670 706
671 // static 707 // static
672 void VideoResourceUpdater::RecycleResource( 708 void VideoResourceUpdater::RecycleResource(
673 base::WeakPtr<VideoResourceUpdater> updater, 709 base::WeakPtr<VideoResourceUpdater> updater,
674 ResourceId resource_id, 710 ResourceId resource_id,
675 const gpu::SyncToken& sync_token, 711 const gpu::SyncToken& sync_token,
676 bool lost_resource, 712 bool lost_resource,
677 BlockingTaskRunner* main_thread_task_runner) { 713 BlockingTaskRunner* main_thread_task_runner) {
678 if (!updater.get()) { 714 if (!updater.get()) {
679 // Resource was already deleted. 715 // Resource was already deleted.
680 return; 716 return;
681 } 717 }
682
683 const ResourceList::iterator resource_it = std::find_if( 718 const ResourceList::iterator resource_it = std::find_if(
684 updater->all_resources_.begin(), updater->all_resources_.end(), 719 updater->all_resources_.begin(), updater->all_resources_.end(),
685 [resource_id](const PlaneResource& plane_resource) { 720 [resource_id](const PlaneResource& plane_resource) {
686 return plane_resource.resource_id() == resource_id; 721 return plane_resource.resource_id() == resource_id;
687 }); 722 });
688 if (resource_it == updater->all_resources_.end()) 723 if (resource_it == updater->all_resources_.end())
689 return; 724 return;
690 725
691 ContextProvider* context_provider = updater->context_provider_; 726 ContextProvider* context_provider = updater->context_provider_;
692 if (context_provider && sync_token.HasData()) { 727 if (context_provider && sync_token.HasData()) {
693 context_provider->ContextGL()->WaitSyncTokenCHROMIUM( 728 context_provider->ContextGL()->WaitSyncTokenCHROMIUM(
694 sync_token.GetConstData()); 729 sync_token.GetConstData());
695 } 730 }
696 731
697 if (lost_resource) { 732 if (lost_resource) {
698 resource_it->clear_refs(); 733 resource_it->clear_refs();
699 updater->DeleteResource(resource_it); 734 updater->DeleteResource(resource_it);
700 return; 735 return;
701 } 736 }
702 737
703 resource_it->remove_ref(); 738 resource_it->remove_ref();
704 } 739 }
705 740
706 } // namespace cc 741 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698