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

Unified Diff: content/common/gpu/media/avda_codec_image.cc

Issue 1892013002: ReleaseOutputBuffer to surface back and front buffers where possible. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleanup. Created 4 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: content/common/gpu/media/avda_codec_image.cc
diff --git a/content/common/gpu/media/avda_codec_image.cc b/content/common/gpu/media/avda_codec_image.cc
index 7efc0c690bb45c20784fe60ad559271c27a8b162..71bf4eba1771555c2704dd6d52b84a5c77ae00cd 100644
--- a/content/common/gpu/media/avda_codec_image.cc
+++ b/content/common/gpu/media/avda_codec_image.cc
@@ -84,7 +84,8 @@ bool AVDACodecImage::CopyTexImage(unsigned target) {
// Make sure that we have the right image in the front buffer. Note that the
// bound_service_id is guaranteed to be equal to the surface texture's client
// texture id, so we can skip preserving it if the right context is current.
- UpdateSurfaceTexture(kDontRestoreBindings);
+ UpdateSurfaceInternal(UpdateMode::RENDER_TO_FRONT_BUFFER,
+ kDontRestoreBindings);
// By setting image state to UNBOUND instead of COPIED we ensure that
// CopyTexImage() is called each time the surface texture is used for drawing.
@@ -114,10 +115,7 @@ bool AVDACodecImage::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
return false;
}
- if (codec_buffer_index_ != kInvalidCodecBufferIndex) {
- media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true);
- codec_buffer_index_ = kInvalidCodecBufferIndex;
- }
+ UpdateSurface(UpdateMode::RENDER_TO_FRONT_BUFFER);
return true;
}
@@ -127,20 +125,7 @@ void AVDACodecImage::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
void AVDACodecImage::UpdateSurfaceTexture(RestoreBindingsMode mode) {
DCHECK(surface_texture_);
-
- // Render via the media codec if needed.
- if (!IsCodecBufferOutstanding())
- return;
-
- // The decoder buffer is still pending.
- // This must be synchronous, so wait for OnFrameAvailable.
- media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true);
- {
- SCOPED_UMA_HISTOGRAM_TIMER("Media.AvdaCodecImage.WaitTimeForFrame");
- shared_state_->WaitForFrameAvailable();
- }
-
- // Don't bother to check if we're rendered again.
+ DCHECK_EQ(codec_buffer_index_, kUpdateOnly);
codec_buffer_index_ = kInvalidCodecBufferIndex;
// Swap the rendered image to the front.
@@ -169,14 +154,14 @@ void AVDACodecImage::SetMediaCodecBufferIndex(int buffer_index) {
codec_buffer_index_ = buffer_index;
}
-int AVDACodecImage::GetMediaCodecBufferIndex() const {
- return codec_buffer_index_;
-}
-
void AVDACodecImage::SetSize(const gfx::Size& size) {
size_ = size;
}
+void AVDACodecImage::UpdateSurface(UpdateMode update_mode) {
+ UpdateSurfaceInternal(update_mode, kDoRestoreBindings);
+}
+
void AVDACodecImage::CodecChanged(media::MediaCodecBridge* codec) {
media_codec_ = codec;
codec_buffer_index_ = kInvalidCodecBufferIndex;
@@ -186,6 +171,76 @@ void AVDACodecImage::SetTexture(gpu::gles2::Texture* texture) {
texture_ = texture;
}
+void AVDACodecImage::UpdateSurfaceInternal(
+ UpdateMode update_mode,
+ RestoreBindingsMode attached_bindings_mode) {
+ if (!IsCodecBufferOutstanding())
+ return;
+
+ ReleaseOutputBuffer(update_mode);
+
+ // SurfaceViews are updated implicitly, so no further steps are necessary.
+ if (!surface_texture_) {
liberato (no reviews please) 2016/04/22 20:25:08 DCHECK_NE(...BACK_BUFFER)?
DaleCurtis 2016/04/22 20:58:02 Done, though can't use DCHECK_NE with enum class f
+ codec_buffer_index_ = kInvalidCodecBufferIndex;
liberato (no reviews please) 2016/04/22 20:25:08 this might be better in ReleaseOutputBuffer.
DaleCurtis 2016/04/22 20:58:02 Good point, done.
+ return;
+ }
+
+ // If front buffer rendering hasn't been requested, exit early.
+ if (update_mode != UpdateMode::RENDER_TO_FRONT_BUFFER)
+ return;
+
+ // Surface texture is already attached, so just update it.
+ if (shared_state_->surface_texture_is_attached()) {
+ UpdateSurfaceTexture(attached_bindings_mode);
+ return;
+ }
+
+ // Don't attach the surface texture permanently. Perhaps we should just
+ // attach the surface texture in avda and be done with it.
+ GLuint service_id = 0;
+ glGenTextures(1, &service_id);
+ GLint bound_service_id = 0;
+ glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, service_id);
+ AttachSurfaceTextureToContext();
+ UpdateSurfaceTexture(kDontRestoreBindings);
+
+ // Detach the surface texture, which deletes the generated texture.
+ surface_texture_->DetachFromGLContext();
+ shared_state_->DidDetachSurfaceTexture();
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, bound_service_id);
+}
+
+void AVDACodecImage::ReleaseOutputBuffer(UpdateMode update_mode) {
+ DCHECK(IsCodecBufferOutstanding());
+
+ // In case of discard, simply discard and clear our codec buffer index.
+ if (update_mode == UpdateMode::DISCARD_CODEC_BUFFER) {
+ if (codec_buffer_index_ != kUpdateOnly)
+ media_codec_->ReleaseOutputBuffer(codec_buffer_index_, false);
+ codec_buffer_index_ = kInvalidCodecBufferIndex;
+ return;
+ }
+
+ DCHECK(update_mode == UpdateMode::RENDER_TO_BACK_BUFFER ||
+ update_mode == UpdateMode::RENDER_TO_FRONT_BUFFER);
+
+ // If we've already released to the back buffer, there's nothing left to do.
+ if (codec_buffer_index_ == kUpdateOnly)
+ return;
+
+ media_codec_->ReleaseOutputBuffer(codec_buffer_index_, true);
+ codec_buffer_index_ = kUpdateOnly;
+
+ // If we're using a SurfaceView we're done!
+ if (!surface_texture_)
+ return;
+
+ // This must be synchronous, so wait for OnFrameAvailable.
+ SCOPED_UMA_HISTOGRAM_TIMER("Media.AvdaCodecImage.WaitTimeForFrame");
+ shared_state_->WaitForFrameAvailable();
+}
+
void AVDACodecImage::AttachSurfaceTextureToContext() {
DCHECK(surface_texture_);
@@ -217,28 +272,9 @@ std::unique_ptr<ui::ScopedMakeCurrent> AVDACodecImage::MakeCurrentIfNeeded() {
}
void AVDACodecImage::GetTextureMatrix(float matrix[16]) {
- if (IsCodecBufferOutstanding() && shared_state_ && surface_texture_) {
- // Our current matrix may be stale. Update it if possible.
- if (!shared_state_->surface_texture_is_attached()) {
- // Don't attach the surface texture permanently. Perhaps we should
- // just attach the surface texture in avda and be done with it.
- GLuint service_id = 0;
- glGenTextures(1, &service_id);
- GLint bound_service_id = 0;
- glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
- glBindTexture(GL_TEXTURE_EXTERNAL_OES, service_id);
- AttachSurfaceTextureToContext();
- UpdateSurfaceTexture(kDontRestoreBindings);
- // Detach the surface texture, which deletes the generated texture.
- surface_texture_->DetachFromGLContext();
- shared_state_->DidDetachSurfaceTexture();
- glBindTexture(GL_TEXTURE_EXTERNAL_OES, bound_service_id);
- } else {
- // Surface texture is already attached, so just update it.
- UpdateSurfaceTexture(kDoRestoreBindings);
- }
- }
-
+ // Our current matrix may be stale. Update it if possible.
+ if (surface_texture_)
+ UpdateSurface(UpdateMode::RENDER_TO_FRONT_BUFFER);
memcpy(matrix, gl_matrix_, sizeof(gl_matrix_));
}
« content/common/gpu/media/avda_codec_image.h ('K') | « content/common/gpu/media/avda_codec_image.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698