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

Side by Side Diff: content/common/gpu/media/gles2_external_texture_copier.cc

Issue 11973010: AndroidVDA by using Android's MediaCodec API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: adding save/restore status in copier. Created 7 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/common/gpu/media/gles2_external_texture_copier.h"
6
7 #include "base/logging.h"
8
9 namespace content {
10
11 static void CheckGlError(const char* op) {
12 for (GLint error = glGetError(); error; error = glGetError()) {
13 LOG(ERROR) << "after " << op <<" glError (0x" << std::hex << error << ")";
14 NOTREACHED();
15 }
16 }
17
18 static const char g_vertex_shader[] =
19 "uniform mat4 uMVPMatrix;\n"
20 "uniform mat4 uSTMatrix;\n"
21 "attribute vec4 aPosition;\n"
22 "attribute vec4 aTextureCoord;\n"
23 "varying vec2 vTextureCoord;\n"
24 "void main() {\n"
25 " gl_Position = uMVPMatrix * aPosition;\n"
26 " vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n"
27 "}\n";
28
29 static const char g_fragment_shader[] =
30 "#extension GL_OES_EGL_image_external : require\n"
31 "precision mediump float;\n"
32 "varying vec2 vTextureCoord;\n"
33 "uniform samplerExternalOES sTexture;\n"
34 "void main() {\n"
35 " gl_FragColor = texture2D(sTexture, vTextureCoord);\n"
36 "}\n";
37
38 static const int kVerticeStride = 5 * sizeof(float);
Ami GONE FROM CHROMIUM 2013/02/17 00:12:44 English: The singular of "vertices" is "vertex" ;)
39
40 static const GLfloat g_vertices[] = {
41 -1.0f, -1.0f, 0, 0.f, 0.f,
42 1.0f, -1.0f, 0, 1.f, 0.f,
43 -1.0f, 1.0f, 0, 0.f, 1.f,
44 1.0f, 1.0f, 0, 1.f, 1.f,
45 };
46
47 // Due to the absence of matrix functions in NDK, a pre-calculated matrix
48 // is used. g_mvp_matrix = P * L * I
49 // Matrix.setLookAtM(L, 0, 0, 0, 2, 0, 0, 0, 0, -1, 0);
50 // Matrix.orthoM(P, 0, -1, 1, -1, 1, 1, 3);
51 // Matrix.setIdentityM(I, 0);
52 // Up vector(0, -1, 0) is used instead of (0, 1, 0) to prevent flipped screen.
53 static const GLfloat g_mvp_matrix[] = {
Ami GONE FROM CHROMIUM 2013/02/17 00:12:44 My glFoo is super-weak, but I believe what you hav
54 1.f, 0.f, 0.f, 0.f,
55 0.f, -1.f, 0.f, 0.f,
56 0.f, 0.f, -1.f, 0.f,
57 0.f, 0.f, 0.f, 1.f,
58 };
59
60 static GLuint LoadShader(GLenum shaderType, const char* pSource) {
Ami GONE FROM CHROMIUM 2013/02/17 00:12:44 here and elsewhere, unix_style, not camelCase for
61 GLuint shader = glCreateShader(shaderType);
62 if (shader) {
Ami GONE FROM CHROMIUM 2013/02/17 00:12:44 nit: if you reversed the test you could early-retu
63 glShaderSource(shader, 1, &pSource, NULL);
64 glCompileShader(shader);
65 GLint compiled = 0;
66 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
67 if (!compiled) {
68 GLint infoLen = 0;
69 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
70 if (infoLen) {
71 char* buf = (char*) malloc(infoLen);
Ami GONE FROM CHROMIUM 2013/02/17 00:12:44 scoped_ptr
72 if (buf) {
Ami GONE FROM CHROMIUM 2013/02/17 00:12:44 unnecessary; malloc/new never fail in chromium oth
73 glGetShaderInfoLog(shader, infoLen, NULL, buf);
74 LOG(ERROR) << "Could not compile shader : " << buf;
75 free(buf);
76 }
77 glDeleteShader(shader);
78 shader = 0;
79 }
80 }
81 }
82 return shader;
83 }
84
85 static GLuint CreateProgram(
86 const char* pVertexSource, const char* pFragmentSource) {
87 GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, pVertexSource);
88 if (!vertexShader)
89 return 0;
90
91 GLuint pixelShader = LoadShader(GL_FRAGMENT_SHADER, pFragmentSource);
Ami GONE FROM CHROMIUM 2013/02/17 00:12:44 s/pixel/fragment/ ? (here and below)
92 if (!pixelShader)
93 return 0;
94
95 GLuint program = glCreateProgram();
96 if (program) {
97 glAttachShader(program, vertexShader);
Ami GONE FROM CHROMIUM 2013/02/17 00:12:44 delete the shaders after attaching them (so progra
98 CheckGlError("glAttachShader");
99 glAttachShader(program, pixelShader);
100 CheckGlError("glAttachShader");
101 glLinkProgram(program);
102 GLint linkStatus = GL_FALSE;
103 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
104 if (linkStatus != GL_TRUE) {
105 GLint bufLength = 0;
106 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
107 if (bufLength) {
108 char* buf = (char*) malloc(bufLength);
109 if (buf) {
110 glGetProgramInfoLog(program, bufLength, NULL, buf);
111 LOG(ERROR) << "Could not link program: "<< buf;
112 free(buf);
113 }
114 }
115 glDeleteProgram(program);
116 program = 0;
117 }
118 }
119 return program;
120 }
121
122 Gles2ExternalTextureCopier::Gles2ExternalTextureCopier()
123 : initialized_(false),
124 width_(0),
125 height_(0),
126 framebuffer_id_(0),
127 renderbuffer_id_(0),
128 program_(0),
129 position_handle_(0),
130 st_matrix_handle_(0),
131 mvp_matrix_handle_(0),
132 texture_handle_(0),
133 previous_framebuffer_id_(0),
134 previous_renderbuffer_id_(0),
135 previous_texture_id_(0) {
136 }
137
138 Gles2ExternalTextureCopier::~Gles2ExternalTextureCopier() {
139 if (initialized_) {
140 glDeleteFramebuffersEXT(1, &framebuffer_id_);
141 glDeleteRenderbuffersEXT(1, &renderbuffer_id_);
142 }
143 }
144
145 bool Gles2ExternalTextureCopier::SetupGraphics() {
146 program_ = CreateProgram(g_vertex_shader, g_fragment_shader);
147 if (!program_) {
148 LOG(ERROR) << "Could not create program.";
149 return false;
150 }
151 position_handle_ = glGetAttribLocation(program_, "aPosition");
152 CheckGlError("glGetAttribLocation");
153
154 texture_handle_ = glGetAttribLocation(program_, "aTextureCoord");
155 CheckGlError("glGetAttribLocation aTextureCoord");
156
157 mvp_matrix_handle_ = glGetUniformLocation(program_, "uMVPMatrix");
158 CheckGlError("glGetUniformLocation uMVPMatrix");
159
160 st_matrix_handle_ = glGetUniformLocation(program_, "uSTMatrix");
161 CheckGlError("glGetUniformLocation uSTMatrix");
162
163 return true;
164 }
165
166 void Gles2ExternalTextureCopier::RenderFrame(
167 int w, int h, GLuint texture_id, const float transfrom_matrix[16]) {
168 glViewport(0, 0, w, h);
Ami GONE FROM CHROMIUM 2013/02/17 00:12:44 I suspect this can go in a Setup method
169 CheckGlError("glViewport");
170
171 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
Ami GONE FROM CHROMIUM 2013/02/17 00:12:44 why DEPTH? (IOW, why allocate a depthbuffer later?
172 CheckGlError("glClear");
173
174 glUseProgram(program_);
175 CheckGlError("glUseProgram");
176
177 glActiveTexture(GL_TEXTURE0);
178 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
179 CheckGlError("glBindTexture");
180
181 glVertexAttribPointer(
Ami GONE FROM CHROMIUM 2013/02/17 00:12:44 l.181-195 can probably be done only once, right?
182 position_handle_, 3, GL_FLOAT, GL_FALSE, kVerticeStride, g_vertices);
183 CheckGlError("glVertexAttribPointer vPositionHandle");
184 glEnableVertexAttribArray(position_handle_);
185 CheckGlError("glEnableVertexAttribArray vPositionHandle");
186
187 glVertexAttribPointer(
188 texture_handle_, 2, GL_FLOAT, GL_FALSE, kVerticeStride, g_vertices + 3);
189 CheckGlError("glVertexAttribPointer aTextureHandle");
190 glEnableVertexAttribArray(texture_handle_);
191 CheckGlError("glEnableVertexAttribArray aTextureHandle");
192
193 glUniformMatrix4fv(mvp_matrix_handle_, 1, GL_FALSE, g_mvp_matrix);
194 CheckGlError("glUniformMatrix4fv uMVPMatrixHandle");
195
196 glUniformMatrix4fv(st_matrix_handle_, 1, GL_FALSE, transfrom_matrix);
Ami GONE FROM CHROMIUM 2013/02/17 00:12:44 Part of me wants to just ignore transform_matrix a
197 CheckGlError("glUniformMatrix4fv uSTMatrixHandle");
198
199 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
200 CheckGlError("glDrawArrays");
201 }
202
203 bool Gles2ExternalTextureCopier::Init(int32 width, int32 height) {
204 if (initialized_) {
205 LOG(ERROR) << "Init should not be called twice.";
Ami GONE FROM CHROMIUM 2013/02/17 00:12:44 Since this is the only failure mode of Init(), I t
206 return false;
207 }
208
209 width_ = width;
210 height_ = height;
211
212 SaveState();
213 SetupGraphics();
214 SetupFrameBuffer();
215 RestoreState();
216
217 initialized_ = true;
218 return initialized_;
219 }
220
221 bool Gles2ExternalTextureCopier::Copy(
222 GLuint source_texture_id, GLuint destination_texture_id,
223 const float transfrom_matrix[16]) {
224 if (!initialized_)
225 return false;
226
227 SaveState();
228 glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_id_);
229 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
230 destination_texture_id, 0);
231 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
232 if (status != GL_FRAMEBUFFER_COMPLETE) {
233 LOG(ERROR) << "Framebuffer is not complete: " << status;
234 RestoreState();
235 return false;
236 }
237 CheckGlError("glBindFramebuffer framebuffer_id_");
238 RenderFrame(width_, height_, source_texture_id, transfrom_matrix);
239 RestoreState();
240
241 return true;
242 }
243
244
245 bool Gles2ExternalTextureCopier::SetupFrameBuffer() {
246 GLuint framebuffer;
247 glGenFramebuffersEXT(1, &framebuffer);
248 glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer);
249
250 GLuint depthbuffer;
251 glGenRenderbuffersEXT(1, &depthbuffer);
252
253 glBindRenderbufferEXT(GL_RENDERBUFFER, depthbuffer);
254 glRenderbufferStorageEXT(
255 GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width_, height_);
256 glFramebufferRenderbufferEXT(
257 GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer);
258 CheckGlError("glFramebufferRenderbuffer");
259
260 framebuffer_id_ = framebuffer;
261 renderbuffer_id_ = depthbuffer;
262 return true;
263 }
264
265 void Gles2ExternalTextureCopier::SaveState() {
266 glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *)&previous_framebuffer_id_);
267 CheckGlError("glGetIntegerv previous_framebuffer_id");
268 glGetIntegerv(GL_RENDERBUFFER_BINDING, (GLint *)&previous_renderbuffer_id_);
269 CheckGlError("glGetIntegerv previous_renderbuffer_id_");
270 glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *)&previous_texture_id_);
271 CheckGlError("glGetIntegerv previous_texture_id_");
272 }
273
274 void Gles2ExternalTextureCopier::RestoreState() {
275 glBindFramebufferEXT(GL_FRAMEBUFFER, previous_framebuffer_id_);
276 CheckGlError("glBindFramebuffer previous_framebuffer_id");
277 glBindRenderbufferEXT(GL_RENDERBUFFER, previous_renderbuffer_id_);
278 CheckGlError("glBindFramebuffer previous_renderbuffer_id_");
279 glBindTexture(GL_TEXTURE_2D, previous_texture_id_);
280 CheckGlError("glBindTexture previous_texture_id_");
281 }
282
283 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698