Chromium Code Reviews| 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..0eda5cb1b42565c9ec1354eb9d7fa9c05326a70c 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,23 +114,12 @@ 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 { |
|
watk
2016/11/09 01:20:48
Just realized the only caller of this is AVDA and
DaleCurtis
2016/11/09 21:58:17
Good catch, removed, fixed up code to use DCHECK i
|
| - // 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); |
| + // 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. It's important to get the coded size right, so that VideoLayerImpl |
| + // doesn't try to scale the texture when building the quad for it. |
| + return state_provider_->GetSize(); |
| } |
| void AVDAPictureBufferManager::SetImageForPicture( |
| @@ -133,10 +127,9 @@ void AVDAPictureBufferManager::SetImageForPicture( |
| 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 +147,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 +165,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 +206,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 +247,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 +277,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 +299,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 |