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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gl/gl_image_surface_texture.h" 5 #include "ui/gl/gl_image_surface_texture.h"
6 6
7 #include "base/strings/stringize_macros.h"
8 #include "base/strings/stringprintf.h"
7 #include "base/trace_event/trace_event.h" 9 #include "base/trace_event/trace_event.h"
8 #include "ui/gl/android/surface_texture.h" 10 #include "ui/gl/android/surface_texture.h"
11 #include "ui/gl/gl_helper.h"
12 #include "ui/gl/scoped_binders.h"
9 13
10 namespace gl { 14 namespace gl {
11 15
12 GLImageSurfaceTexture::GLImageSurfaceTexture(const gfx::Size& size) 16 GLImageSurfaceTexture::GLImageSurfaceTexture(const gfx::Size& size)
13 : size_(size), texture_id_(0) {} 17 : size_(size) {}
14 18
15 GLImageSurfaceTexture::~GLImageSurfaceTexture() { 19 GLImageSurfaceTexture::~GLImageSurfaceTexture() {
16 DCHECK(thread_checker_.CalledOnValidThread()); 20 DCHECK(thread_checker_.CalledOnValidThread());
17 DCHECK(!surface_texture_.get()); 21 DCHECK(!surface_texture_.get());
18 DCHECK_EQ(0, texture_id_);
19 } 22 }
20 23
21 bool GLImageSurfaceTexture::Initialize(gfx::SurfaceTexture* surface_texture) { 24 bool GLImageSurfaceTexture::Initialize(gfx::SurfaceTexture* surface_texture) {
22 DCHECK(thread_checker_.CalledOnValidThread()); 25 DCHECK(thread_checker_.CalledOnValidThread());
23 DCHECK(!surface_texture_.get()); 26 DCHECK(!surface_texture_.get());
24 surface_texture_ = surface_texture; 27 surface_texture_ = surface_texture;
25 return true; 28 return true;
26 } 29 }
27 30
28 void GLImageSurfaceTexture::Destroy(bool have_context) { 31 void GLImageSurfaceTexture::Destroy(bool have_context) {
29 DCHECK(thread_checker_.CalledOnValidThread()); 32 DCHECK(thread_checker_.CalledOnValidThread());
30 surface_texture_ = NULL; 33 if (have_context && framebuffer_) {
31 texture_id_ = 0; 34 glDeleteProgram(program_);
35 glDeleteShader(vertex_shader_);
36 glDeleteShader(fragment_shader_);
37 glDeleteBuffersARB(1, &vertex_buffer_);
38 glDeleteFramebuffersEXT(1, &framebuffer_);
39 }
40 surface_texture_ = nullptr;
32 } 41 }
33 42
34 gfx::Size GLImageSurfaceTexture::GetSize() { 43 gfx::Size GLImageSurfaceTexture::GetSize() {
35 return size_; 44 return size_;
36 } 45 }
37 46
38 unsigned GLImageSurfaceTexture::GetInternalFormat() { return GL_RGBA; } 47 unsigned GLImageSurfaceTexture::GetInternalFormat() { return GL_RGBA; }
39 48
40 bool GLImageSurfaceTexture::BindTexImage(unsigned target) { 49 bool GLImageSurfaceTexture::BindTexImage(unsigned target) {
41 TRACE_EVENT0("gpu", "GLImageSurfaceTexture::BindTexImage"); 50 // Binding of surface textures directly to a target is not supported as
51 // an explicit release call is required before the buffer can be reused.
52 return false;
53 }
54
55 bool GLImageSurfaceTexture::CopyTexImage(unsigned target) {
56 TRACE_EVENT0("gpu", "GLImageSurfaceTexture::CopyTexImage");
42 DCHECK(thread_checker_.CalledOnValidThread()); 57 DCHECK(thread_checker_.CalledOnValidThread());
43 58
44 if (target != GL_TEXTURE_EXTERNAL_OES) { 59 if (target != GL_TEXTURE_2D) {
45 LOG(ERROR) 60 LOG(ERROR) << "CopyTexImage requires TEXTURE_2D target";
46 << "Surface texture can only be bound to TEXTURE_EXTERNAL_OES target";
47 return false; 61 return false;
48 } 62 }
49 63
50 GLint texture_id; 64 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.width(), size_.height(), 0,
51 glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texture_id); 65 GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
52 DCHECK(texture_id);
53 66
54 if (texture_id_ && texture_id_ != texture_id) { 67 return CopyTexSubImage(target, gfx::Point(), gfx::Rect(size_));
55 LOG(ERROR) << "Surface texture can only be bound to one texture ID";
56 return false;
57 }
58
59 DCHECK(surface_texture_.get());
60 if (texture_id != texture_id_) {
61 // Note: Surface textures used as gpu memory buffers are created with an
62 // initial dummy texture id of 0. We need to call DetachFromGLContext() here
63 // to detach from the dummy texture before we can attach to a real texture
64 // id. DetachFromGLContext() will delete the texture for the current
65 // attachment point so it's important that this is never called when
66 // attached to a real texture id. Detaching from the dummy texture id should
67 // not cause any problems as the GL should silently ignore 0 when passed to
68 // glDeleteTextures.
69 DCHECK_EQ(0, texture_id_);
70 surface_texture_->DetachFromGLContext();
71
72 // This will attach the surface texture to the texture currently bound to
73 // GL_TEXTURE_EXTERNAL_OES target.
74 surface_texture_->AttachToGLContext();
75 texture_id_ = texture_id;
76 }
77
78 surface_texture_->UpdateTexImage();
79 return true;
80 }
81
82 bool GLImageSurfaceTexture::CopyTexImage(unsigned target) {
83 return false;
84 } 68 }
85 69
86 bool GLImageSurfaceTexture::CopyTexSubImage(unsigned target, 70 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.
87 const gfx::Point& offset, 71 const gfx::Point& offset,
88 const gfx::Rect& rect) { 72 const gfx::Rect& rect) {
89 return false; 73 TRACE_EVENT0("gpu", "GLImageSurfaceTexture::CopyTexSubImage");
74
75 if (!offset.IsOrigin()) {
76 LOG(ERROR) << "Non-origin offset is not supported";
77 return false;
78 }
79
80 if (rect != gfx::Rect(size_)) {
81 LOG(ERROR) << "Sub-rectangle is not supported";
82 return false;
83 }
84
85 if (!framebuffer_) {
86 // Framebuffer.
87 glGenFramebuffersEXT(1, &framebuffer_);
88
89 // clang-format off
90 const char kVertexShader[] = STRINGIZE(
91 attribute vec2 a_position;
92 varying vec2 v_texCoord;
93 void main() {
94 gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0);
95 v_texCoord = (a_position + vec2(1.0, 1.0)) * 0.5;
96 }
97 );
98 const char kFragmentShader[] = STRINGIZE(
99 precision mediump float;
100 uniform samplerExternalOES a_texture;
101 varying vec2 v_texCoord;
102 void main() {
103 gl_FragColor = texture2D(a_texture, v_texCoord);
104 }
105 );
106 // clang-format on
107
108 // Shaders.
109 vertex_shader_ = gfx::GLHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader);
110 fragment_shader_ = gfx::GLHelper::LoadShader(
111 GL_FRAGMENT_SHADER,
112 base::StringPrintf("#extension GL_OES_EGL_image_external : require\n%s",
113 kFragmentShader)
114 .c_str());
115 program_ = gfx::GLHelper::SetupProgram(vertex_shader_, fragment_shader_);
116 gfx::ScopedUseProgram use_program(program_);
117 int sampler_location = glGetUniformLocation(program_, "a_texture");
118 DCHECK_NE(-1, sampler_location);
119 glUniform1i(sampler_location, 0);
120
121 // Vertex buffer.
122 glGenBuffersARB(1, &vertex_buffer_);
123 gfx::ScopedBufferBinder buffer_binder(GL_ARRAY_BUFFER, vertex_buffer_);
124 GLfloat data[] = {-1.f, -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f};
125 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
126 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.
127 }
128
129 GLint target_texture = 0;
130 glGetIntegerv(GL_TEXTURE_BINDING_2D, &target_texture);
131 DCHECK(target_texture);
132
133 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
134 // UpdateTexImage() call below will bind the surface texture to
135 // TEXTURE_EXTERNAL_OES. This scoped texture binder will restore the current
136 // binding before this function returns.
137 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_EXTERNAL_OES, 0);
138
139 DCHECK(surface_texture_.get());
140 surface_texture_->UpdateTexImage();
141
142 {
143 gfx::ScopedFrameBufferBinder framebuffer_binder(framebuffer_);
144 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
145 GL_TEXTURE_2D, target_texture, 0);
146 DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
147 glCheckFramebufferStatusEXT(GL_FRAMEBUFFER));
148
149 gfx::ScopedViewport viewport(0, 0, size_.width(), size_.height());
150 glViewport(0, 0, size_.width(), size_.height());
151
152 gfx::ScopedUseProgram use_program(program_);
153 gfx::ScopedEnableVertexAttribArray enable_vertex_attrib_array(0);
154 gfx::ScopedBufferBinder buffer_binder(GL_ARRAY_BUFFER, vertex_buffer_);
155
156 // Draw surface texture to target texture.
157 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
158
159 // Detach the output texture from the fbo.
160 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
161 GL_TEXTURE_2D, 0, 0);
162 }
163
164 surface_texture_->ReleaseTexImage();
165 return true;
90 } 166 }
91 167
92 bool GLImageSurfaceTexture::ScheduleOverlayPlane( 168 bool GLImageSurfaceTexture::ScheduleOverlayPlane(
93 gfx::AcceleratedWidget widget, 169 gfx::AcceleratedWidget widget,
94 int z_order, 170 int z_order,
95 gfx::OverlayTransform transform, 171 gfx::OverlayTransform transform,
96 const gfx::Rect& bounds_rect, 172 const gfx::Rect& bounds_rect,
97 const gfx::RectF& crop_rect) { 173 const gfx::RectF& crop_rect) {
98 return false; 174 return false;
99 } 175 }
100 176
101 void GLImageSurfaceTexture::OnMemoryDump( 177 void GLImageSurfaceTexture::OnMemoryDump(
102 base::trace_event::ProcessMemoryDump* pmd, 178 base::trace_event::ProcessMemoryDump* pmd,
103 uint64_t process_tracing_id, 179 uint64_t process_tracing_id,
104 const std::string& dump_name) { 180 const std::string& dump_name) {
105 // TODO(ericrk): Add OnMemoryDump for GLImages. crbug.com/514914 181 // TODO(ericrk): Add OnMemoryDump for GLImages. crbug.com/514914
106 } 182 }
107 183
108 } // namespace gl 184 } // namespace gl
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698