Chromium Code Reviews| Index: ui/gl/gl_image_surface_texture.cc |
| diff --git a/ui/gl/gl_image_surface_texture.cc b/ui/gl/gl_image_surface_texture.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d80eebb7133c2bd009f63aa1d9da8bf86877be58 |
| --- /dev/null |
| +++ b/ui/gl/gl_image_surface_texture.cc |
| @@ -0,0 +1,99 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "ui/gl/gl_image_surface_texture.h" |
| + |
| +#include "base/debug/trace_event.h" |
| +#include "ui/gl/android/surface_texture.h" |
| +#include "ui/gl/android/surface_texture_tracker.h" |
| +#include "ui/gl/gl_bindings.h" |
| + |
| +namespace gfx { |
| +namespace { |
| + |
| +// This is admittedly a bit ugly. SurfaceTexture API takes ownership of texture |
| +// ids when AttachToGLContext() is called and will delete the texture unless |
| +// DetachFromGLContext() is called with no context current. This helper class |
| +// can be used to temporarily make no context current for the purpose of |
| +// stealing the texture id of a given surface texture. |
| +class ScopedNoContextCurrent { |
| + public: |
| + ScopedNoContextCurrent() |
| + : display_(eglGetCurrentDisplay()), |
| + context_(eglGetCurrentContext()), |
| + draw_surface_(eglGetCurrentSurface(EGL_DRAW)), |
| + read_surface_(eglGetCurrentSurface(EGL_READ)) { |
| + eglMakeCurrent(display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); |
| + } |
| + |
| + ~ScopedNoContextCurrent() { |
| + eglMakeCurrent(display_, draw_surface_, read_surface_, context_); |
| + } |
| + |
| + private: |
| + EGLDisplay display_; |
| + EGLContext context_; |
| + EGLSurface draw_surface_; |
| + EGLSurface read_surface_; |
| +}; |
| + |
| +void DetachFromGLContext(SurfaceTexture* surface_texture) { |
| + // Detach with no context current to prevent SurfaceTexture from deleting |
| + // currently attached texture id. |
| + ScopedNoContextCurrent no_context_current; |
| + surface_texture->DetachFromGLContext(); |
| +} |
| + |
| +} // namespace |
| + |
| +GLImageSurfaceTexture::GLImageSurfaceTexture(gfx::Size size) |
| + : size_(size), texture_id_(0) {} |
| + |
| +GLImageSurfaceTexture::~GLImageSurfaceTexture() { Destroy(); } |
| + |
| +bool GLImageSurfaceTexture::Initialize(gfx::GpuMemoryBufferHandle buffer) { |
| + DCHECK(!surface_texture_); |
| + surface_texture_ = |
| + SurfaceTextureTracker::GetInstance()->AcquireSurfaceTexture( |
|
no sievers
2014/03/18 20:58:13
This handle comes from the client, so we also need
reveman
2014/03/24 18:35:07
Gpu memory buffers are global on other platforms.
|
| + buffer.surface_texture_id); |
| + return !!surface_texture_; |
| +} |
| + |
| +void GLImageSurfaceTexture::Destroy() { |
| + surface_texture_ = NULL; |
| + texture_id_ = 0; |
| +} |
| + |
| +gfx::Size GLImageSurfaceTexture::GetSize() { return size_; } |
| + |
| +bool GLImageSurfaceTexture::BindTexImage(unsigned target) { |
| + TRACE_EVENT0("gpu", "GLImageSurfaceTexture::BindTexImage"); |
| + |
| + if (target != GL_TEXTURE_EXTERNAL_OES) { |
| + LOG(ERROR) |
| + << "Surface texture can only be bound to TEXTURE_EXTERNAL_OES target"; |
| + return false; |
| + } |
| + |
| + int texture_id; |
| + glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texture_id); |
| + DCHECK(texture_id); |
| + |
| + if (texture_id_ && texture_id_ != texture_id) { |
| + LOG(ERROR) << "Surface texture can only be bound to one texture ID"; |
| + return false; |
| + } |
| + |
| + DCHECK(surface_texture_); |
| + if (texture_id != texture_id_) { |
| + DetachFromGLContext(surface_texture_.get()); |
| + surface_texture_->AttachToGLContext(); |
| + texture_id_ = texture_id; |
| + } |
| + |
| + surface_texture_->UpdateTexImage(); |
|
no sievers
2014/03/18 20:58:13
So whenever we updated the contents from the clien
reveman
2014/03/24 18:35:07
Yes, no guarantee that updated contents will be us
|
| + return true; |
| +} |
| + |
| +} // namespace gfx |