| Index: content/common/gpu/media/android_deferred_rendering_backing_strategy.cc
|
| diff --git a/content/common/gpu/media/android_deferred_rendering_backing_strategy.cc b/content/common/gpu/media/android_deferred_rendering_backing_strategy.cc
|
| index aa66ed7ec62bb30f3a7db4c3c5fb110b083747b2..7e7e8cfc8f1406c70bcfa2447f0bb45fd5733ff4 100644
|
| --- a/content/common/gpu/media/android_deferred_rendering_backing_strategy.cc
|
| +++ b/content/common/gpu/media/android_deferred_rendering_backing_strategy.cc
|
| @@ -168,7 +168,8 @@ void AndroidDeferredRenderingBackingStrategy::SetImageForPicture(
|
|
|
| void AndroidDeferredRenderingBackingStrategy::UseCodecBufferForPictureBuffer(
|
| int32_t codec_buf_index,
|
| - const media::PictureBuffer& picture_buffer) {
|
| + const media::PictureBuffer& picture_buffer,
|
| + const std::vector<int32_t>& pictures_out_for_display) {
|
| // Make sure that the decoder is available.
|
| RETURN_IF_NULL(state_provider_->GetGlDecoder());
|
|
|
| @@ -177,11 +178,13 @@ void AndroidDeferredRenderingBackingStrategy::UseCodecBufferForPictureBuffer(
|
| AVDACodecImage* avda_image =
|
| shared_state_->GetImageForPicture(picture_buffer.id());
|
| RETURN_IF_NULL(avda_image);
|
| - DCHECK_EQ(avda_image->GetMediaCodecBufferIndex(), -1);
|
| +
|
| // Note that this is not a race, since we do not re-use a PictureBuffer
|
| // until after the CC is done drawing it.
|
| avda_image->SetMediaCodecBufferIndex(codec_buf_index);
|
| avda_image->SetSize(state_provider_->GetSize());
|
| +
|
| + MaybeRenderEarly(pictures_out_for_display);
|
| }
|
|
|
| void AndroidDeferredRenderingBackingStrategy::AssignOnePictureBuffer(
|
| @@ -218,24 +221,62 @@ void AndroidDeferredRenderingBackingStrategy::ReleaseCodecBufferForPicture(
|
| AVDACodecImage* avda_image =
|
| shared_state_->GetImageForPicture(picture_buffer.id());
|
| RETURN_IF_NULL(avda_image);
|
| -
|
| - // See if there is a media codec buffer still attached to this image.
|
| - const int32_t codec_buffer = avda_image->GetMediaCodecBufferIndex();
|
| -
|
| - if (codec_buffer >= 0) {
|
| - // PictureBuffer wasn't displayed, so release the buffer.
|
| - media_codec_->ReleaseOutputBuffer(codec_buffer, false);
|
| - avda_image->SetMediaCodecBufferIndex(-1);
|
| - }
|
| + avda_image->ReleaseOutputBuffer(AVDACodecImage::ReleaseMode::SKIP_RENDER);
|
| }
|
|
|
| void AndroidDeferredRenderingBackingStrategy::ReuseOnePictureBuffer(
|
| - const media::PictureBuffer& picture_buffer) {
|
| + const media::PictureBuffer& picture_buffer,
|
| + const std::vector<int32_t>& pictures_out_for_display) {
|
| // At this point, the CC must be done with the picture. We can't really
|
| // check for that here directly. it's guaranteed in gpu_video_decoder.cc,
|
| // when it waits on the sync point before releasing the mailbox. That sync
|
| // point is inserted by destroying the resource in VideoLayerImpl::DidDraw.
|
| ReleaseCodecBufferForPicture(picture_buffer);
|
| + MaybeRenderEarly(pictures_out_for_display);
|
| +}
|
| +
|
| +void AndroidDeferredRenderingBackingStrategy::MaybeRenderEarly(
|
| + const std::vector<int32_t>& pictures_out_for_display) {
|
| + // See if we can consume the front buffer / render to the SurfaceView.
|
| + if (pictures_out_for_display.size() == 1u) {
|
| + AVDACodecImage* avda_image =
|
| + shared_state_->GetImageForPicture(*pictures_out_for_display.begin());
|
| + RETURN_IF_NULL(avda_image);
|
| + avda_image->ReleaseOutputBuffer(
|
| + AVDACodecImage::ReleaseMode::RENDER_AND_UPDATE);
|
| + return;
|
| + }
|
| +
|
| + // Back buffer rendering is only available for surface textures.
|
| + if (!surface_texture_)
|
| + return;
|
| +
|
| + // See if the back buffer is free. If so, then render the earliest frame. The
|
| + // listing is in render order, so we can just use the first unrendered frame
|
| + // if there is back buffer space.
|
| + AVDACodecImage* first_renderable_image = nullptr;
|
| + for (int id : pictures_out_for_display) {
|
| + AVDACodecImage* avda_image = shared_state_->GetImageForPicture(id);
|
| + if (!avda_image)
|
| + continue;
|
| +
|
| + // If the back buffer is unavailable, there's nothing left to do.
|
| + if (avda_image->is_rendered_to_back_buffer())
|
| + return;
|
| +
|
| + // If the image is rendered to the front buffer or has been dropped, it is
|
| + // not valid for rendering.
|
| + if (avda_image->is_rendered())
|
| + continue;
|
| +
|
| + if (!first_renderable_image)
|
| + first_renderable_image = avda_image;
|
| + }
|
| +
|
| + if (first_renderable_image) {
|
| + first_renderable_image->ReleaseOutputBuffer(
|
| + AVDACodecImage::ReleaseMode::RENDER_ONLY);
|
| + }
|
| }
|
|
|
| void AndroidDeferredRenderingBackingStrategy::CodecChanged(
|
|
|