| Index: media/gpu/avda_picture_buffer_manager.cc
|
| diff --git a/media/gpu/avda_picture_buffer_manager.cc b/media/gpu/avda_picture_buffer_manager.cc
|
| index d0f13136ffdcf6ad3ca788f5592bbcc5551bb60b..4fe59e2df372d18632176cac163cca8cb23aece8 100644
|
| --- a/media/gpu/avda_picture_buffer_manager.cc
|
| +++ b/media/gpu/avda_picture_buffer_manager.cc
|
| @@ -84,8 +84,13 @@ gl::ScopedJavaSurface AVDAPictureBufferManager::Initialize(int surface_id) {
|
| shared_state_ = new AVDASharedState();
|
|
|
| // Acquire the SurfaceView surface if given a valid id.
|
| - if (surface_id != SurfaceManager::kNoSurfaceID)
|
| + if (surface_id != SurfaceManager::kNoSurfaceID) {
|
| + if (surface_texture_) {
|
| + surface_texture_->ReleaseSurfaceTexture();
|
| + surface_texture_ = nullptr;
|
| + }
|
| return gpu::GpuSurfaceLookup::GetInstance()->AcquireJavaSurface(surface_id);
|
| + }
|
|
|
| // Otherwise create a SurfaceTexture.
|
| GLuint service_id;
|
| @@ -109,34 +114,14 @@ void AVDAPictureBufferManager::Destroy(const PictureBufferMap& buffers) {
|
| surface_texture_->ReleaseSurfaceTexture();
|
| }
|
|
|
| -uint32_t AVDAPictureBufferManager::GetTextureTarget() const {
|
| - // If we're using a surface texture, then we need an external texture target
|
| - // to sample from it. If not, then we'll use 2D transparent textures to draw
|
| - // a transparent hole through which to see the SurfaceView. This is normally
|
| - // needed only for the devtools inspector, since the overlay mechanism handles
|
| - // it otherwise.
|
| - return surface_texture_ ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D;
|
| -}
|
| -
|
| -gfx::Size AVDAPictureBufferManager::GetPictureBufferSize() const {
|
| - // For SurfaceView, request a 1x1 2D texture to reduce memory during
|
| - // initialization. For SurfaceTexture, allocate a picture buffer that is the
|
| - // actual frame size. Note that it will be an external texture anyway, so it
|
| - // doesn't allocate an image of that size. However, it's still important to
|
| - // get the coded size right, so that VideoLayerImpl doesn't try to scale the
|
| - // texture when building the quad for it.
|
| - return surface_texture_ ? state_provider_->GetSize() : gfx::Size(1, 1);
|
| -}
|
| -
|
| void AVDAPictureBufferManager::SetImageForPicture(
|
| const PictureBuffer& picture_buffer,
|
| gpu::gles2::GLStreamTextureImage* image) {
|
| auto gles_decoder = state_provider_->GetGlDecoder();
|
| RETURN_IF_NULL(gles_decoder);
|
| - RETURN_IF_NULL(gles_decoder->GetContextGroup());
|
| -
|
| - gpu::gles2::TextureManager* texture_manager =
|
| - gles_decoder->GetContextGroup()->texture_manager();
|
| + auto* context_group = gles_decoder->GetContextGroup();
|
| + RETURN_IF_NULL(context_group);
|
| + auto* texture_manager = context_group->texture_manager();
|
| RETURN_IF_NULL(texture_manager);
|
|
|
| DCHECK_LE(1u, picture_buffer.client_texture_ids().size());
|
| @@ -154,7 +139,7 @@ void AVDAPictureBufferManager::SetImageForPicture(
|
|
|
| // Also set the parameters for the level if we're not clearing the image.
|
| const gfx::Size size = state_provider_->GetSize();
|
| - texture_manager->SetLevelInfo(texture_ref, GetTextureTarget(), 0, GL_RGBA,
|
| + texture_manager->SetLevelInfo(texture_ref, kTextureTarget, 0, GL_RGBA,
|
| size.width(), size.height(), 1, 0, GL_RGBA,
|
| GL_UNSIGNED_BYTE, gfx::Rect());
|
|
|
| @@ -172,34 +157,35 @@ void AVDAPictureBufferManager::SetImageForPicture(
|
| // matter.
|
| if (image && !surface_texture_)
|
| image_state = gpu::gles2::Texture::BOUND;
|
| - texture_manager->SetLevelStreamTextureImage(texture_ref, GetTextureTarget(),
|
| - 0, image, image_state,
|
| + texture_manager->SetLevelStreamTextureImage(texture_ref, kTextureTarget, 0,
|
| + image, image_state,
|
| stream_texture_service_id);
|
| - texture_manager->SetLevelCleared(texture_ref, GetTextureTarget(), 0, true);
|
| + texture_manager->SetLevelCleared(texture_ref, kTextureTarget, 0, true);
|
| }
|
|
|
| AVDACodecImage* AVDAPictureBufferManager::GetImageForPicture(
|
| int picture_buffer_id) const {
|
| auto it = codec_images_.find(picture_buffer_id);
|
| - return it == codec_images_.end() ? nullptr : it->second.get();
|
| + DCHECK(it != codec_images_.end());
|
| + return it->second.get();
|
| }
|
|
|
| void AVDAPictureBufferManager::UseCodecBufferForPictureBuffer(
|
| int32_t codec_buf_index,
|
| const PictureBuffer& picture_buffer) {
|
| - // Make sure that the decoder is available.
|
| - RETURN_IF_NULL(state_provider_->GetGlDecoder());
|
| -
|
| // Notify the AVDACodecImage for picture_buffer that it should use the
|
| // decoded buffer codec_buf_index to render this frame.
|
| AVDACodecImage* avda_image = GetImageForPicture(picture_buffer.id());
|
| - RETURN_IF_NULL(avda_image);
|
|
|
| // Note that this is not a race, since we do not re-use a PictureBuffer
|
| // until after the CC is done drawing it.
|
| pictures_out_for_display_.push_back(picture_buffer.id());
|
| - avda_image->set_media_codec_buffer_index(codec_buf_index);
|
| - avda_image->set_size(state_provider_->GetSize());
|
| + avda_image->SetBufferMetadata(codec_buf_index, !!surface_texture_,
|
| + state_provider_->GetSize());
|
| +
|
| + // If the shared state has changed for this image, retarget its texture.
|
| + if (avda_image->SetSharedState(shared_state_))
|
| + SetImageForPicture(picture_buffer, avda_image);
|
|
|
| MaybeRenderEarly();
|
| }
|
| @@ -212,29 +198,12 @@ void AVDAPictureBufferManager::AssignOnePictureBuffer(
|
| codec_images_[picture_buffer.id()] = new AVDACodecImage(
|
| shared_state_, media_codec_, state_provider_->GetGlDecoder());
|
| SetImageForPicture(picture_buffer, gl_image.get());
|
| -
|
| - if (!surface_texture_ && have_context) {
|
| - // To make devtools work, we're using a 2D texture. Make it transparent,
|
| - // so that it draws a hole for the SV to show through. This is only
|
| - // because devtools draws and reads back, which skips overlay processing.
|
| - // It's unclear why devtools renders twice -- once normally, and once
|
| - // including a readback layer. The result is that the device screen
|
| - // flashes as we alternately draw the overlay hole and this texture,
|
| - // unless we make the texture transparent.
|
| - static const uint8_t rgba[] = {0, 0, 0, 0};
|
| - const gfx::Size size(1, 1);
|
| - DCHECK_LE(1u, picture_buffer.service_texture_ids().size());
|
| - glBindTexture(GL_TEXTURE_2D, picture_buffer.service_texture_ids()[0]);
|
| - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0,
|
| - GL_RGBA, GL_UNSIGNED_BYTE, rgba);
|
| - }
|
| }
|
|
|
| void AVDAPictureBufferManager::ReleaseCodecBufferForPicture(
|
| const PictureBuffer& picture_buffer) {
|
| - AVDACodecImage* avda_image = GetImageForPicture(picture_buffer.id());
|
| - RETURN_IF_NULL(avda_image);
|
| - avda_image->UpdateSurface(AVDACodecImage::UpdateMode::DISCARD_CODEC_BUFFER);
|
| + GetImageForPicture(picture_buffer.id())
|
| + ->UpdateSurface(AVDACodecImage::UpdateMode::DISCARD_CODEC_BUFFER);
|
| }
|
|
|
| void AVDAPictureBufferManager::ReuseOnePictureBuffer(
|
| @@ -270,8 +239,6 @@ void AVDAPictureBufferManager::MaybeRenderEarly() {
|
| for (int i = front_index; i >= 0; --i) {
|
| const int id = pictures_out_for_display_[i];
|
| AVDACodecImage* avda_image = GetImageForPicture(id);
|
| - if (!avda_image)
|
| - continue;
|
|
|
| // Update the front buffer index as we move along to shorten the number of
|
| // candidate images we look at for back buffer rendering.
|
| @@ -302,10 +269,8 @@ void AVDAPictureBufferManager::MaybeRenderEarly() {
|
| // first unrendered frame if there is back buffer space.
|
| first_renderable_image =
|
| GetImageForPicture(pictures_out_for_display_[backbuffer_index]);
|
| - if (!first_renderable_image ||
|
| - first_renderable_image->was_rendered_to_back_buffer()) {
|
| + if (first_renderable_image->was_rendered_to_back_buffer())
|
| return;
|
| - }
|
|
|
| // Due to the loop in the beginning this should never be true.
|
| DCHECK(!first_renderable_image->was_rendered_to_front_buffer());
|
| @@ -326,4 +291,12 @@ bool AVDAPictureBufferManager::ArePicturesOverlayable() {
|
| return !surface_texture_;
|
| }
|
|
|
| +bool AVDAPictureBufferManager::HasUnrenderedPictures() const {
|
| + for (int id : pictures_out_for_display_) {
|
| + if (GetImageForPicture(id)->is_unrendered())
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| } // namespace media
|
|
|