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

Unified Diff: ui/gl/gl_image_surface_texture.cc

Issue 1419623008: ui: Use single buffer SurfaceTexture mode for native GpuMemoryBuffers on Android. Base URL: https://chromium.googlesource.com/chromium/src.git@1419733005
Patch Set: Created 5 years, 1 month 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: 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
index e47392d8be0fc49ace841192670075475747c54b..b2e708a7faf4dc26f3f18b674c20cdee1b1c1678 100644
--- a/ui/gl/gl_image_surface_texture.cc
+++ b/ui/gl/gl_image_surface_texture.cc
@@ -4,18 +4,21 @@
#include "ui/gl/gl_image_surface_texture.h"
+#include "base/strings/stringize_macros.h"
+#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "ui/gl/android/surface_texture.h"
+#include "ui/gl/gl_helper.h"
+#include "ui/gl/scoped_binders.h"
namespace gl {
GLImageSurfaceTexture::GLImageSurfaceTexture(const gfx::Size& size)
- : size_(size), texture_id_(0) {}
+ : size_(size) {}
GLImageSurfaceTexture::~GLImageSurfaceTexture() {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!surface_texture_.get());
- DCHECK_EQ(0, texture_id_);
}
bool GLImageSurfaceTexture::Initialize(gfx::SurfaceTexture* surface_texture) {
@@ -27,8 +30,14 @@ bool GLImageSurfaceTexture::Initialize(gfx::SurfaceTexture* surface_texture) {
void GLImageSurfaceTexture::Destroy(bool have_context) {
DCHECK(thread_checker_.CalledOnValidThread());
- surface_texture_ = NULL;
- texture_id_ = 0;
+ if (have_context && framebuffer_) {
+ glDeleteProgram(program_);
+ glDeleteShader(vertex_shader_);
+ glDeleteShader(fragment_shader_);
+ glDeleteBuffersARB(1, &vertex_buffer_);
+ glDeleteFramebuffersEXT(1, &framebuffer_);
+ }
+ surface_texture_ = nullptr;
}
gfx::Size GLImageSurfaceTexture::GetSize() {
@@ -38,55 +47,122 @@ gfx::Size GLImageSurfaceTexture::GetSize() {
unsigned GLImageSurfaceTexture::GetInternalFormat() { return GL_RGBA; }
bool GLImageSurfaceTexture::BindTexImage(unsigned target) {
- TRACE_EVENT0("gpu", "GLImageSurfaceTexture::BindTexImage");
+ // Binding of surface textures directly to a target is not supported as
+ // an explicit release call is required before the buffer can be reused.
+ return false;
+}
+
+bool GLImageSurfaceTexture::CopyTexImage(unsigned target) {
+ TRACE_EVENT0("gpu", "GLImageSurfaceTexture::CopyTexImage");
DCHECK(thread_checker_.CalledOnValidThread());
- if (target != GL_TEXTURE_EXTERNAL_OES) {
- LOG(ERROR)
- << "Surface texture can only be bound to TEXTURE_EXTERNAL_OES target";
+ if (target != GL_TEXTURE_2D) {
+ LOG(ERROR) << "CopyTexImage requires TEXTURE_2D target";
return false;
}
- GLint texture_id;
- glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texture_id);
- DCHECK(texture_id);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.width(), size_.height(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
- if (texture_id_ && texture_id_ != texture_id) {
- LOG(ERROR) << "Surface texture can only be bound to one texture ID";
+ return CopyTexSubImage(target, gfx::Point(), gfx::Rect(size_));
+}
+
+bool GLImageSurfaceTexture::CopyTexSubImage(unsigned target,
Daniele Castagna 2015/11/03 19:57:34 Why implement CopyTexSubImage that supports only f
reveman 2015/12/05 23:09:08 This is what the compositor use for one-copy.
+ const gfx::Point& offset,
+ const gfx::Rect& rect) {
+ TRACE_EVENT0("gpu", "GLImageSurfaceTexture::CopyTexSubImage");
+
+ if (!offset.IsOrigin()) {
+ LOG(ERROR) << "Non-origin offset is not supported";
return false;
}
- DCHECK(surface_texture_.get());
- if (texture_id != texture_id_) {
- // Note: Surface textures used as gpu memory buffers are created with an
- // initial dummy texture id of 0. We need to call DetachFromGLContext() here
- // to detach from the dummy texture before we can attach to a real texture
- // id. DetachFromGLContext() will delete the texture for the current
- // attachment point so it's important that this is never called when
- // attached to a real texture id. Detaching from the dummy texture id should
- // not cause any problems as the GL should silently ignore 0 when passed to
- // glDeleteTextures.
- DCHECK_EQ(0, texture_id_);
- surface_texture_->DetachFromGLContext();
-
- // This will attach the surface texture to the texture currently bound to
- // GL_TEXTURE_EXTERNAL_OES target.
- surface_texture_->AttachToGLContext();
- texture_id_ = texture_id;
+ if (rect != gfx::Rect(size_)) {
+ LOG(ERROR) << "Sub-rectangle is not supported";
+ return false;
}
+ if (!framebuffer_) {
+ // Framebuffer.
+ glGenFramebuffersEXT(1, &framebuffer_);
+
+ // clang-format off
+ const char kVertexShader[] = STRINGIZE(
+ attribute vec2 a_position;
+ varying vec2 v_texCoord;
+ void main() {
+ gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0);
+ v_texCoord = (a_position + vec2(1.0, 1.0)) * 0.5;
+ }
+ );
+ const char kFragmentShader[] = STRINGIZE(
+ precision mediump float;
+ uniform samplerExternalOES a_texture;
+ varying vec2 v_texCoord;
+ void main() {
+ gl_FragColor = texture2D(a_texture, v_texCoord);
+ }
+ );
+ // clang-format on
+
+ // Shaders.
+ vertex_shader_ = gfx::GLHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader);
+ fragment_shader_ = gfx::GLHelper::LoadShader(
+ GL_FRAGMENT_SHADER,
+ base::StringPrintf("#extension GL_OES_EGL_image_external : require\n%s",
+ kFragmentShader)
+ .c_str());
+ program_ = gfx::GLHelper::SetupProgram(vertex_shader_, fragment_shader_);
+ gfx::ScopedUseProgram use_program(program_);
+ int sampler_location = glGetUniformLocation(program_, "a_texture");
+ DCHECK_NE(-1, sampler_location);
+ glUniform1i(sampler_location, 0);
+
+ // Vertex buffer.
+ glGenBuffersARB(1, &vertex_buffer_);
+ gfx::ScopedBufferBinder buffer_binder(GL_ARRAY_BUFFER, vertex_buffer_);
+ GLfloat data[] = {-1.f, -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f};
+ glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, 0);
Daniele Castagna 2015/11/03 19:57:34 As pointed out by piman@, this needs to be set and
reveman 2015/12/05 23:09:08 Fixed by rebase.
+ }
+
+ GLint target_texture = 0;
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &target_texture);
+ DCHECK(target_texture);
+
+ gfx::ScopedActiveTexture active_texture(GL_TEXTURE0);
Daniele Castagna 2015/11/03 19:57:34 As mentioned by piman in the previous CL, we need
reveman 2015/12/05 23:09:08 Latest patch should be consistent with what we do
+ // UpdateTexImage() call below will bind the surface texture to
+ // TEXTURE_EXTERNAL_OES. This scoped texture binder will restore the current
+ // binding before this function returns.
+ gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_EXTERNAL_OES, 0);
+
+ DCHECK(surface_texture_.get());
surface_texture_->UpdateTexImage();
- return true;
-}
-bool GLImageSurfaceTexture::CopyTexImage(unsigned target) {
- return false;
-}
+ {
+ gfx::ScopedFrameBufferBinder framebuffer_binder(framebuffer_);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, target_texture, 0);
+ DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
+ glCheckFramebufferStatusEXT(GL_FRAMEBUFFER));
-bool GLImageSurfaceTexture::CopyTexSubImage(unsigned target,
- const gfx::Point& offset,
- const gfx::Rect& rect) {
- return false;
+ gfx::ScopedViewport viewport(0, 0, size_.width(), size_.height());
+ glViewport(0, 0, size_.width(), size_.height());
+
+ gfx::ScopedUseProgram use_program(program_);
+ gfx::ScopedEnableVertexAttribArray enable_vertex_attrib_array(0);
+ gfx::ScopedBufferBinder buffer_binder(GL_ARRAY_BUFFER, vertex_buffer_);
+
+ // Draw surface texture to target texture.
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ // Detach the output texture from the fbo.
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, 0, 0);
+ }
+
+ surface_texture_->ReleaseTexImage();
+ return true;
}
bool GLImageSurfaceTexture::ScheduleOverlayPlane(

Powered by Google App Engine
This is Rietveld 408576698