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

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