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

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

Issue 1559203003: Add GLStreamTextureImage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: s/GL_EXPORT/GPU_EXPORT for windows Created 4 years, 10 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
« no previous file with comments | « content/common/gpu/media/avda_codec_image.h ('k') | content/common/gpu/media/avda_shared_state.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 6b0fa8a62658424e3b74e0e61262afb817112a5c..e0a0cb59c55a39ae0d3e8b5aae13098469fd3190 100644
--- a/content/common/gpu/media/avda_codec_image.cc
+++ b/content/common/gpu/media/avda_codec_image.cc
@@ -29,11 +29,12 @@ AVDACodecImage::AVDACodecImage(
decoder_(decoder),
surface_texture_(surface_texture),
detach_surface_texture_on_destruction_(false),
- texture_(0),
- need_shader_info_(true),
- texmatrix_uniform_location_(-1) {
+ texture_(0) {
+ // Default to a sane guess of "flip Y", just in case we can't get
+ // the matrix on the first call.
memset(gl_matrix_, 0, sizeof(gl_matrix_));
- gl_matrix_[0] = gl_matrix_[5] = gl_matrix_[10] = gl_matrix_[15] = 1.0f;
+ gl_matrix_[0] = gl_matrix_[10] = gl_matrix_[15] = 1.0f;
+ gl_matrix_[5] = -1.0f;
}
AVDACodecImage::~AVDACodecImage() {}
@@ -61,35 +62,29 @@ bool AVDACodecImage::CopyTexImage(unsigned target) {
if (target != GL_TEXTURE_EXTERNAL_OES)
return false;
- // Verify that the currently bound texture is the right one. If we're not
- // copying to a Texture that shares our service_id, then we can't do much.
- // This will force a copy.
- // TODO(liberato): Fall back to a copy that uses the texture matrix.
GLint bound_service_id = 0;
glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
+ // We insist that the currently bound texture is the right one. We could
+ // make a new glimage from a 2D image.
if (bound_service_id != shared_state_->surface_texture_service_id())
return false;
- // Attach the surface texture to our GL context if needed.
+ // If the surface texture isn't attached yet, then attach it. Note that this
+ // will be to the texture in |shared_state_|, because of the checks above.
if (!shared_state_->surface_texture_is_attached())
AttachSurfaceTextureToContext();
- // Make sure that we have the right image in the front buffer.
- UpdateSurfaceTexture();
-
- InstallTextureMatrix();
-
- // TODO(liberato): Handle the texture matrix properly.
- // Either we can update the shader with it or we can move all of the logic
- // to updateTexImage() to the right place in the cc to send it to the shader.
- // For now, we just skip it. crbug.com/530681
+ // 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);
// By setting image state to UNBOUND instead of COPIED we ensure that
// CopyTexImage() is called each time the surface texture is used for drawing.
// It would be nice if we could do this via asking for the currently bound
// Texture, but the active unit never seems to change.
- texture_->SetLevelImage(GL_TEXTURE_EXTERNAL_OES, 0, this,
- gpu::gles2::Texture::UNBOUND);
+ texture_->SetLevelStreamTextureImage(GL_TEXTURE_EXTERNAL_OES, 0, this,
+ gpu::gles2::Texture::UNBOUND);
return true;
}
@@ -123,11 +118,11 @@ void AVDACodecImage::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
uint64_t process_tracing_id,
const std::string& dump_name) {}
-void AVDACodecImage::UpdateSurfaceTexture() {
+void AVDACodecImage::UpdateSurfaceTexture(RestoreBindingsMode mode) {
DCHECK(surface_texture_);
// Render via the media codec if needed.
- if (codec_buffer_index_ == kInvalidCodecBufferIndex || !media_codec_)
+ if (!IsCodecBufferOutstanding())
return;
// The decoder buffer is still pending.
@@ -142,12 +137,21 @@ void AVDACodecImage::UpdateSurfaceTexture() {
codec_buffer_index_ = kInvalidCodecBufferIndex;
// Swap the rendered image to the front.
- scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
- if (!shared_state_->context()->IsCurrent(NULL)) {
- scoped_make_current.reset(new ui::ScopedMakeCurrent(
- shared_state_->context(), shared_state_->surface()));
- }
+ scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current = MakeCurrentIfNeeded();
+
+ // If we changed contexts, then we always want to restore it, since the caller
+ // doesn't know that we're switching contexts.
+ if (scoped_make_current)
+ mode = kDoRestoreBindings;
+
+ // Save the current binding if requested.
+ GLint bound_service_id = 0;
+ if (mode == kDoRestoreBindings)
+ glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id);
+
surface_texture_->UpdateTexImage();
+ if (mode == kDoRestoreBindings)
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, bound_service_id);
// Helpfully, this is already column major.
surface_texture_->GetTransformMatrix(gl_matrix_);
@@ -176,6 +180,8 @@ void AVDACodecImage::SetTexture(gpu::gles2::Texture* texture) {
void AVDACodecImage::AttachSurfaceTextureToContext() {
DCHECK(surface_texture_);
+ // We assume that the currently bound texture is the intended one.
+
// Attach the surface texture to the first context we're bound on, so that
// no context switch is needed later.
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -187,38 +193,48 @@ void AVDACodecImage::AttachSurfaceTextureToContext() {
// We could do this earlier, but SurfaceTexture has context affinity, and we
// don't want to require a context switch.
surface_texture_->AttachToGLContext();
- shared_state_->did_attach_surface_texture();
+ shared_state_->DidAttachSurfaceTexture();
}
-void AVDACodecImage::InstallTextureMatrix() {
- DCHECK(surface_texture_);
+scoped_ptr<ui::ScopedMakeCurrent> AVDACodecImage::MakeCurrentIfNeeded() {
+ DCHECK(shared_state_->context());
+ scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
+ if (!shared_state_->context()->IsCurrent(NULL)) {
+ scoped_make_current.reset(new ui::ScopedMakeCurrent(
+ shared_state_->context(), shared_state_->surface()));
+ }
- // glUseProgram() has been run already -- just modify the uniform.
- // Updating this via VideoFrameProvider::Client::DidUpdateMatrix() would
- // be a better solution, except that we'd definitely miss a frame at this
- // point in drawing.
- // Our current method assumes that we'll end up being a stream resource,
- // and that the program has a texMatrix uniform that does what we want.
- if (need_shader_info_) {
- GLint program_id = -1;
- glGetIntegerv(GL_CURRENT_PROGRAM, &program_id);
-
- if (program_id >= 0) {
- // This is memorized from cc/output/shader.cc .
- const char* uniformName = "texMatrix";
-
- // Within unittests this value may be -1.
- texmatrix_uniform_location_ =
- glGetUniformLocation(program_id, uniformName);
- }
+ return scoped_make_current;
+}
- // Only try once.
- need_shader_info_ = false;
+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);
+ }
}
- if (texmatrix_uniform_location_ >= 0) {
- glUniformMatrix4fv(texmatrix_uniform_location_, 1, false, gl_matrix_);
- }
+ memcpy(matrix, gl_matrix_, sizeof(gl_matrix_));
+}
+
+bool AVDACodecImage::IsCodecBufferOutstanding() const {
+ return codec_buffer_index_ != kInvalidCodecBufferIndex && media_codec_;
}
} // namespace content
« no previous file with comments | « content/common/gpu/media/avda_codec_image.h ('k') | content/common/gpu/media/avda_shared_state.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698