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

Side by Side Diff: gpu/tools/compositor_model_bench/shaders.cc

Issue 7718020: Initial checkin of the compositor_model_bench tool, which simulates the GPU demands of Chromium's... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 9 years, 3 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "gpu/tools/compositor_model_bench/shaders.h"
6
7 #include <algorithm>
8
9 #include "gpu/tools/compositor_model_bench/render_model_utils.h"
10 #include "gpu/tools/compositor_model_bench/render_tree.h"
11
12 using std::min;
13
14 static unsigned g_quad_vertices_vbo;
15 static unsigned g_quad_elements_vbo;
16
17 // Store a pointer to the transform matrix of the active layer (the complete
18 // transform isn't build until we draw the quad; then we can apply
19 // translation/scaling/projection)
20 static float* g_current_layer_transform;
21
22 // In addition to the transform, store other useful information about tiled
23 // layers that we'll need to render each tile's quad
24 static float g_current_tile_layer_width;
25 static float g_current_tile_layer_height;
26 static float g_current_tile_width;
27 static float g_current_tile_height;
28
29 static const float yuv2RGB[9] = {
30 1.164f, 1.164f, 1.164f,
31 0.f, -.391f, 2.018f,
32 1.596f, -.813f, 0.f
33 };
34
35 // Store shader programs in a sparse array so that they can be addressed easily.
36 static int g_program_objects[SHADER_ID_MAX*SHADER_ID_MAX];
37 static int g_active_index = -1;
38
39 ///////////////////////////////////////////////////////////////////////////////
40 // L R B T N F
41 // glOrtho(0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, -1, 1); // column major
42
43 static float ProjMat[] = {
piman 2011/08/26 02:24:16 ProjMat -> g_projection_matrix
44 2.0 / WINDOW_WIDTH, 0.0, 0.0, 0.0,
45 0.0, 2.0 / -WINDOW_HEIGHT, 0.0, 0.0,
46 0.0, 0.0, -1.0, 0.0,
47 -1.0, 1.0, 0.0, 1.0 };
piman 2011/08/26 02:24:16 '};' should be on a separate line
48
49 #define ADDR(i, j) (i*4 + j) /* column major */
50 static void Project(const float* v, float* p) {
51 for (int i = 0; i < 4; ++i) {
52 for (int j = 0; j < 4; ++j) {
53 p[ADDR(i, j)] = 0;
54 for (int k = 0; k < 4; ++k) {
55 p[ADDR(i, j)] += ProjMat[ADDR(k, i)] * v[ADDR(j, k)];
56 }
57 }
58 }
59 }
60
61 static void Scale(const float* in, float* out, float sx, float sy, float sz) {
62 for (int i = 0; i < 4; ++i)
63 out[i] = in[i] * sx;
64 for (int j = 4; j < 8; ++j)
65 out[j] = in[j] * sy;
66 for (int k = 8; k < 12; ++k)
67 out[k] = in[k] * sz;
68 for (int l = 12; l < 16; ++l)
69 out[l] = in[l];
70 }
71
72 static void Translate_InPlace(float* m, float tx, float ty, float tz) {
piman 2011/08/26 02:24:16 Translate_InPlace -> TranslateInPlace
73 m[12] += tx;
74 m[13] += ty;
75 m[14] += tz;
76 }
77
78 ///////////////////////////////////////////////////////////////////////////////
79
80 ShaderID ShaderIDFromString(std::string name) {
81 if (name == "VertexShaderPosTexYUVStretch")
82 return VERTEX_SHADER_POS_TEX_YUV_STRETCH;
83 if (name == "VertexShaderPosTex")
84 return VERTEX_SHADER_POS_TEX;
85 if (name == "VertexShaderPosTexTransform")
86 return VERTEX_SHADER_POS_TEX_TRANSFORM;
87 if (name == "FragmentShaderYUVVideo")
88 return FRAGMENT_SHADER_YUV_VIDEO;
89 if (name == "FragmentShaderRGBATexFlipAlpha")
90 return FRAGMENT_SHADER_RGBA_TEX_FLIP_ALPHA;
91 if (name == "FragmentShaderRGBATexAlpha")
92 return FRAGMENT_SHADER_RGBA_TEX_ALPHA;
93 return SHADER_UNRECOGNIZED;
94 }
95
96 std::string ShaderNameFromID(ShaderID id) {
97 switch (id) {
98 case VERTEX_SHADER_POS_TEX_YUV_STRETCH:
99 return "VertexShaderPosTexYUVStretch";
100 case VERTEX_SHADER_POS_TEX:
101 return "VertexShaderPosTex";
102 case VERTEX_SHADER_POS_TEX_TRANSFORM:
103 return "VertexShaderPosTexTransform";
104 case FRAGMENT_SHADER_YUV_VIDEO:
105 return "FragmentShaderYUVVideo";
106 case FRAGMENT_SHADER_RGBA_TEX_FLIP_ALPHA:
107 return "FragmentShaderRGBATexFlipAlpha";
108 case FRAGMENT_SHADER_RGBA_TEX_ALPHA:
109 return "FragmentShaderRGBATexAlpha";
110 default:
111 return "(unknown shader)";
112 }
113 }
114
115 #define SHADER0(Src) #Src
116 #define SHADER(Src) SHADER0(Src)
117
118 const char* GetShaderSource(ShaderID shader) {
119 switch (shader) {
120 case VERTEX_SHADER_POS_TEX_YUV_STRETCH:
121 return SHADER(
122 #ifdef GL_ES
123 precision mediump float;
124 #endif
125 attribute vec4 a_position;
126 attribute vec2 a_texCoord;
127 uniform mat4 matrix;
128 varying vec2 y_texCoord;
129 varying vec2 uv_texCoord;
130 uniform float y_widthScaleFactor;
131 uniform float uv_widthScaleFactor;
132 void main() {
133 gl_Position = matrix * a_position;
134 y_texCoord = vec2(y_widthScaleFactor * a_texCoord.x,
135 a_texCoord.y);
136 uv_texCoord = vec2(uv_widthScaleFactor * a_texCoord.x,
137 a_texCoord.y);
138 });
139 break;
140 case VERTEX_SHADER_POS_TEX:
141 return SHADER(
142 attribute vec4 a_position;
143 attribute vec2 a_texCoord;
144 uniform mat4 matrix;
145 varying vec2 v_texCoord;
146 void main() {
147 gl_Position = matrix * a_position;
148 v_texCoord = a_texCoord;
149 });
150 break;
151 case VERTEX_SHADER_POS_TEX_TRANSFORM:
152 return SHADER(
153 attribute vec4 a_position;
154 attribute vec2 a_texCoord;
155 uniform mat4 matrix;
156 uniform vec4 texTransform;
157 varying vec2 v_texCoord;
158 void main() {
159 gl_Position = matrix * a_position;
160 v_texCoord = a_texCoord*texTransform.zw + texTransform.xy;
161 });
162 break;
163 case FRAGMENT_SHADER_YUV_VIDEO:
164 return SHADER(
165 #ifdef GL_ES
166 precision mediump float;
167 precision mediump int;
168 #endif
169 varying vec2 y_texCoord;
170 varying vec2 uv_texCoord;
171 uniform sampler2D y_texture;
172 uniform sampler2D u_texture;
173 uniform sampler2D v_texture;
174 uniform float alpha;
175 uniform vec3 yuv_adj;
176 uniform mat3 cc_matrix;
177 void main() {
178 float y_raw = texture2D(y_texture, y_texCoord).x;
179 float u_unsigned = texture2D(u_texture, uv_texCoord).x;
180 float v_unsigned = texture2D(v_texture, uv_texCoord).x;
181 vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
182 vec3 rgb = cc_matrix * yuv;
183 gl_FragColor = vec4(rgb, 1.0) * alpha;
184 });
185 break;
186 case FRAGMENT_SHADER_RGBA_TEX_FLIP_ALPHA:
187 return SHADER(
188 #ifdef GL_ES
189 precision mediump float;
190 #endif
191 varying vec2 v_texCoord;
192 uniform sampler2D s_texture;
193 uniform float alpha;
194 void main() {
195 vec4 texColor = texture2D(s_texture,
196 vec2(v_texCoord.x, 1.0 - v_texCoord.y));
197 gl_FragColor = vec4(texColor.x,
198 texColor.y,
199 texColor.z,
200 texColor.w) * alpha;
201 });
202 break;
203 case FRAGMENT_SHADER_RGBA_TEX_ALPHA:
204 return SHADER(
205 #ifdef GL_ES
206 precision mediump float;
207 #endif
208 varying vec2 v_texCoord;
209 uniform sampler2D s_texture;
210 uniform float alpha;
211 void main() {
212 vec4 texColor = texture2D(s_texture, v_texCoord);
213 gl_FragColor = texColor * alpha;
214 });
215 break;
216 default:
217 printf("Shader source requested for unknown shader\n");
218 return "";
219 }
220 }
221
222 int GetProgramIdx(ShaderID v, ShaderID f) {
223 return v * SHADER_ID_MAX + f;
224 }
225
226 static void ReportAnyShaderCompilationErrors(GLuint shader, ShaderID id) {
227 GLint status;
228 glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
229 if (status)
230 return;
231 // Get the length of the log string
232 GLsizei length;
233 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
234 GLchar* log = new GLchar[length+1];
piman 2011/08/26 02:24:16 you can make this a scoped_array and skip the dele
235 glGetShaderInfoLog(shader, length, NULL, log);
236 LOG(ERROR) << log << " in shader " << ShaderNameFromID(id);
237 delete[] log;
238 }
239
240 static int ActivateShader(ShaderID v, ShaderID f, float* layer_transform) {
241 int program_index = GetProgramIdx(v, f);
242 if (!g_program_objects[program_index]) {
243 g_program_objects[program_index] = glCreateProgramObjectARB();
244 GLenum vs = glCreateShaderObjectARB(GL_VERTEX_SHADER);
245 GLenum fs = glCreateShaderObjectARB(GL_FRAGMENT_SHADER);
246 const char* vs_source = GetShaderSource(v);
247 const char* fs_source = GetShaderSource(f);
248 glShaderSourceARB(vs, 1, &vs_source, 0);
249 glShaderSourceARB(fs, 1, &fs_source, 0);
250 glCompileShaderARB(vs);
251 ReportAnyShaderCompilationErrors(vs, v);
252 glCompileShaderARB(fs);
253 ReportAnyShaderCompilationErrors(fs, f);
254 glAttachObjectARB(g_program_objects[program_index], vs);
255 glAttachObjectARB(g_program_objects[program_index], fs);
256 glBindAttribLocationARB(g_program_objects[program_index], 10, "a_position");
257 glBindAttribLocationARB(g_program_objects[program_index], 11, "a_texCoord");
piman 2011/08/26 02:24:16 Why 10 and 11, instead of say, 0 and 1 ? You prob
258 glLinkProgramARB(g_program_objects[program_index]);
259 }
260 if (g_active_index != program_index)
261 glUseProgramObjectARB(g_program_objects[program_index]);
262 g_active_index = program_index;
263
264 g_current_layer_transform = layer_transform;
265
266 return g_program_objects[program_index];
267 }
268
269 void ConfigAndActivateShaderForNode(CCNode* n) {
270 int program = ActivateShader(n->vertex_shader,
271 n->fragment_shader,
piman 2011/08/26 02:24:16 nit: indentation (align arguments)
272 n->transform);
273 if (n->vertex_shader == VERTEX_SHADER_POS_TEX_YUV_STRETCH) {
274 GLint y_scale = glGetUniformLocationARB(program, "y_widthScaleFactor");
275 GLint uv_scale = glGetUniformLocationARB(program, "uv_widthScaleFactor");
276 glUniform1fARB(y_scale, 1.0);
277 glUniform1fARB(uv_scale, 1.0);
278 }
279 if (n->vertex_shader == VERTEX_SHADER_POS_TEX_TRANSFORM) {
280 GLint texTrans = glGetUniformLocationARB(program, "texTransform");
281 glUniform4fARB(texTrans, 0.0, 0.0, 0.0, 0.0);
282 }
283 if (n->fragment_shader == FRAGMENT_SHADER_RGBA_TEX_FLIP_ALPHA) {
284 DCHECK_EQ(n->textures.size(), 1u);
285 DCHECK_NE(n->textures[0].texID, -1);
286 glActiveTexture(GL_TEXTURE0);
287 glBindTexture(GL_TEXTURE_2D, n->textures[0].texID);
288 int sTexLoc = glGetUniformLocationARB(program, "s_texture");
289 glUniform1iARB(sTexLoc, 0);
290 }
291 if (n->fragment_shader == FRAGMENT_SHADER_YUV_VIDEO) {
292 DCHECK_EQ(n->textures.size(), 3u);
293 DCHECK_NE(n->textures[0].texID, -1);
294 DCHECK_NE(n->textures[1].texID, -1);
295 DCHECK_NE(n->textures[2].texID, -1);
296 // Bind Y tex.
297 glActiveTexture(GL_TEXTURE0);
298 glBindTexture(GL_TEXTURE_2D, n->textures[0].texID);
299 int yTexLoc = glGetUniformLocationARB(program, "y_texture");
300 glUniform1iARB(yTexLoc, 0);
301 // Bind U tex.
302 glActiveTexture(GL_TEXTURE0 + 1);
303 glBindTexture(GL_TEXTURE_2D, n->textures[1].texID);
304 int uTexLoc = glGetUniformLocationARB(program, "u_texture");
305 glUniform1iARB(uTexLoc, 1);
306 // Bind V tex.
307 glActiveTexture(GL_TEXTURE0 + 2);
308 glBindTexture(GL_TEXTURE_2D, n->textures[2].texID);
309 int vTexLoc = glGetUniformLocationARB(program, "v_texture");
310 glUniform1iARB(vTexLoc, 2);
311 // Set YUV offset.
312 int yuvAdjLoc = glGetUniformLocationARB(program, "yuv_adj");
313 glUniform3fARB(yuvAdjLoc, -0.0625f, -0.5f, -0.5f);
314 // Set YUV matrix.
315 int ccMatLoc = glGetUniformLocationARB(program, "cc_matrix");
316 glUniformMatrix3fvARB(ccMatLoc, 1, false, yuv2RGB);
317 }
318 GLint alpha = glGetUniformLocationARB(program, "alpha");
319 glUniform1fARB(alpha, 0.9);
320 }
321
322 void ConfigAndActivateShaderForTiling(ContentLayerNode* n) {
323 int program = ActivateShader(VERTEX_SHADER_POS_TEX_TRANSFORM,
324 FRAGMENT_SHADER_RGBA_TEX_ALPHA,
piman 2011/08/26 02:24:16 nit: indentation
325 n->transform);
326 GLint texTrans = glGetUniformLocationARB(program, "texTransform");
327 glUniform4fARB(texTrans, 0.0, 0.0, 1.0, 1.0);
328 GLint alpha = glGetUniformLocationARB(program, "alpha");
329 glUniform1fARB(alpha, 0.9);
330
331 g_current_tile_layer_width = n->width;
332 g_current_tile_layer_height = n->height;
333 g_current_tile_width = n->tile_width;
334 g_current_tile_height = n->tile_height;
335 }
336
337 void DeleteShaders() {
338 g_active_index = -1;
339 glUseProgramObjectARB(0);
340 for (int i = 0; i < SHADER_ID_MAX*SHADER_ID_MAX; ++i) {
341 if (g_program_objects[i]) {
342 glDeleteObjectARB(g_program_objects[i]);
343 }
344 g_program_objects[i] = 0;
345 }
346 }
347
348 void InitBuffers() {
349 // Vertex positions and texture coordinates for the 4 corners of a 1x1 quad.
350 float vertices[] = { -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
351 -0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
352 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
353 0.5f, 0.5f, 0.0f, 1.0f, 1.0f };
354 uint16_t indices[] = { 0, 1, 2, 0, 2, 3};
355
356 glGenBuffers(1, &g_quad_vertices_vbo);
357 glGenBuffers(1, &g_quad_elements_vbo);
358 glBindBuffer(GL_ARRAY_BUFFER, g_quad_vertices_vbo);
359 glBufferData(GL_ARRAY_BUFFER,
360 sizeof(vertices),
piman 2011/08/26 02:24:16 nit: indentation
361 vertices,
362 GL_STATIC_DRAW);
363 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_quad_elements_vbo);
364 glBufferData(GL_ELEMENT_ARRAY_BUFFER,
365 sizeof(indices),
piman 2011/08/26 02:24:16 nit: indentation
366 indices,
367 GL_STATIC_DRAW);
368 }
369
370 void BeginFrame(GLuint position_attrib_index, GLuint texcoord_attrib_index) {
371 glBindBuffer(GL_ARRAY_BUFFER, g_quad_vertices_vbo);
372 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_quad_elements_vbo);
373 unsigned offset = 0;
374 glVertexAttribPointer(position_attrib_index,
375 3,
376 GL_FLOAT,
377 false,
378 5 * sizeof(float),
379 reinterpret_cast<void*>(offset));
380 offset += 3 * sizeof(float);
381 glVertexAttribPointer(texcoord_attrib_index,
382 2,
383 GL_FLOAT,
384 false,
385 5 * sizeof(float),
386 reinterpret_cast<void*>(offset));
387 glEnableVertexAttribArray(position_attrib_index);
388 glEnableVertexAttribArray(texcoord_attrib_index);
389 }
390
391 void DrawQuad(float width, float height) {
392 float mv_transform[16];
393 float proj_transform[16];
394 Scale(g_current_layer_transform, mv_transform, width, height, 1.0);
395 Project(mv_transform, proj_transform);
396 GLint mat = glGetUniformLocationARB(g_program_objects[g_active_index],
397 "matrix");
piman 2011/08/26 02:24:16 nit: indentation (or fold on previous line if it f
398 glUniformMatrix4fvARB(mat, 1, true, proj_transform);
piman 2011/08/26 02:24:16 true->GL_TRUE
399
400 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
401 }
402
403 void DrawTileQuad(GLuint texID, int x, int y) {
404 float left = g_current_tile_width*x;
405 float top = g_current_tile_height*y;
406 if (left > g_current_tile_layer_width || top > g_current_tile_layer_height)
407 return;
408
409 float right = min(left+g_current_tile_width, g_current_tile_layer_width);
410 float bottom = min(top+g_current_tile_height, g_current_tile_layer_height);
411 float width = right-left;
412 float height = bottom-top;
413
414 int prog = g_program_objects[g_active_index];
415
416 // Scale the texture if the full tile rectangle doesn't get drawn.
417 float u_scale = width / g_current_tile_width;
418 float v_scale = height / g_current_tile_height;
419 GLint texTrans = glGetUniformLocationARB(prog, "texTransform");
420 glUniform4fARB(texTrans, 0.0, 0.0, u_scale, v_scale);
421
422 glActiveTexture(GL_TEXTURE0);
423 glBindTexture(GL_TEXTURE_2D, texID);
424 int texLoc = glGetUniformLocationARB(prog, "s_texture");
425 glUniform1iARB(texLoc, 0);
426
427 float mv_transform[16];
428 float proj_transform[16];
429 Scale(g_current_layer_transform, mv_transform, width, height, 1.0);
430
431 // We have to position the tile by its center.
432 float center_x = (left+right)/2 - g_current_tile_layer_width/2;
433 float center_y = (top+bottom)/2 - g_current_tile_layer_height/2;
434 Translate_InPlace(mv_transform, center_x, center_y, 0.0);
435
436 Project(mv_transform, proj_transform);
437 GLint mat = glGetUniformLocationARB(prog, "matrix");
438 glUniformMatrix4fvARB(mat, 1, true, proj_transform);
piman 2011/08/26 02:24:16 true -> GL_TRUE
439
440 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
441 }
442
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698