OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 The Chromium OS 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 <stdio.h> | |
6 #include <sys/mman.h> | |
7 | |
8 #include "base/logging.h" | |
9 | |
10 #include "main.h" | |
11 #include "shaders.h" | |
12 #include "utils.h" | |
13 #include "yuv2rgb.h" | |
14 | |
15 | |
16 const char *simple_vertex_shader = | |
17 "attribute vec4 c1;" | |
18 "void main() {" | |
19 " gl_Position = c1;" | |
20 "}"; | |
21 | |
22 const char *simple_vertex_shader_2_attr = | |
23 "attribute vec4 c1;" | |
24 "attribute vec4 c2;" | |
25 "void main() {" | |
26 " gl_Position = c1+c2;" | |
27 "}"; | |
28 | |
29 const char *simple_vertex_shader_4_attr = | |
30 "attribute vec4 c1;" | |
31 "attribute vec4 c2;" | |
32 "attribute vec4 c3;" | |
33 "attribute vec4 c4;" | |
34 "void main() {" | |
35 " gl_Position = c1+c2+c3+c4;" | |
36 "}"; | |
37 | |
38 const char *simple_vertex_shader_8_attr = | |
39 "attribute vec4 c1;" | |
40 "attribute vec4 c2;" | |
41 "attribute vec4 c3;" | |
42 "attribute vec4 c4;" | |
43 "attribute vec4 c5;" | |
44 "attribute vec4 c6;" | |
45 "attribute vec4 c7;" | |
46 "attribute vec4 c8;" | |
47 "void main() {" | |
48 " gl_Position = c1+c2+c3+c4+c5+c6+c7+c8;" | |
49 "}"; | |
50 | |
51 | |
52 const char *simple_fragment_shader = | |
53 "void main() {" | |
54 " gl_FragColor = vec4(0.5);" | |
55 "}"; | |
56 | |
57 | |
58 ShaderProgram AttributeFetchShaderProgram(int attribute_count, | |
59 GLuint vertex_buffers[]) { | |
60 const char *vertex_shader = NULL; | |
61 switch (attribute_count) { | |
62 case 1: vertex_shader = simple_vertex_shader; break; | |
63 case 2: vertex_shader = simple_vertex_shader_2_attr; break; | |
64 case 4: vertex_shader = simple_vertex_shader_4_attr; break; | |
65 case 8: vertex_shader = simple_vertex_shader_8_attr; break; | |
66 default: return 0; | |
67 } | |
68 ShaderProgram program = | |
69 InitShaderProgram(vertex_shader, simple_fragment_shader); | |
70 | |
71 for (int i = 0; i < attribute_count; i++) { | |
72 char attribute[] = "c_"; | |
73 attribute[1] = '1' + i; | |
74 int attribute_index = glGetAttribLocation(program, attribute); | |
75 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers[i]); | |
76 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL); | |
77 glEnableVertexAttribArray(attribute_index); | |
78 } | |
79 | |
80 return program; | |
81 } | |
82 | |
83 #define I915_WORKAROUND 1 | |
84 | |
85 #if I915_WORKAROUND | |
86 #define V1 "gl_TexCoord[0]" | |
87 #define V2 "gl_TexCoord[1]" | |
88 #define V3 "gl_TexCoord[2]" | |
89 #define V4 "gl_TexCoord[3]" | |
90 #define V5 "gl_TexCoord[4]" | |
91 #define V6 "gl_TexCoord[5]" | |
92 #define V7 "gl_TexCoord[6]" | |
93 #define V8 "gl_TexCoord[7]" | |
94 #define DDX "dFdx" | |
95 #define DDY "dFdy" | |
96 #else | |
97 #define V1 "v1" | |
98 #define V2 "v2" | |
99 #define V3 "v3" | |
100 #define V4 "v4" | |
101 #define V5 "v5" | |
102 #define V6 "v6" | |
103 #define V7 "v7" | |
104 #define V8 "v8" | |
105 #define DDX "ddx" | |
106 #define DDY "ddy" | |
107 #endif | |
108 | |
109 const char *basic_texture_vertex_shader = | |
110 "attribute vec4 c1;" | |
111 "attribute vec4 c2;" | |
112 "varying vec2 v1;" | |
113 "void main() {" | |
114 " gl_Position = c1;" | |
115 " " V1 " = c2;" | |
116 "}"; | |
117 | |
118 const char *basic_texture_fragment_shader = | |
119 "uniform sampler2D texture_sampler;" | |
120 "varying vec2 v1;" | |
121 "void main() {" | |
122 " gl_FragColor = texture2D(texture_sampler, " V1 ".xy);" | |
123 "}"; | |
124 | |
125 ShaderProgram BasicTextureShaderProgram(GLuint vertex_buffer, | |
126 GLuint texture_buffer) { | |
127 ShaderProgram program = | |
128 InitShaderProgram(basic_texture_vertex_shader, | |
129 basic_texture_fragment_shader); | |
130 | |
131 // Set up the texture sampler | |
132 int textureSampler = glGetUniformLocation(program, "texture_sampler"); | |
133 glUniform1i(textureSampler, 0); | |
134 | |
135 // Set up vertex attribute | |
136 int attribute_index = glGetAttribLocation(program, "c1"); | |
137 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); | |
138 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL); | |
139 glEnableVertexAttribArray(attribute_index); | |
140 | |
141 // Set up texture attribute | |
142 attribute_index = glGetAttribLocation(program, "c2"); | |
143 glBindBuffer(GL_ARRAY_BUFFER, texture_buffer); | |
144 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL); | |
145 glEnableVertexAttribArray(attribute_index); | |
146 | |
147 return program; | |
148 } | |
149 | |
150 const char *double_texture_blend_vertex_shader = | |
151 "attribute vec4 c1;" | |
152 "attribute vec4 c2;" | |
153 "attribute vec4 c3;" | |
154 "varying vec2 v1;" | |
155 "varying vec2 v2;" | |
156 "void main() {" | |
157 " gl_Position = c1;" | |
158 " " V1 " = c2;" | |
159 " " V2 " = c3;" | |
160 "}"; | |
161 | |
162 const char *double_texture_blend_fragment_shader = | |
163 "uniform sampler2D texture_sampler_0;" | |
164 "uniform sampler2D texture_sampler_1;" | |
165 "varying vec2 v1;" | |
166 "varying vec2 v2;" | |
167 "void main() {" | |
168 " vec4 one = texture2D(texture_sampler_0, " V1 ".xy);" | |
169 " vec4 two = texture2D(texture_sampler_1, " V2 ".xy);" | |
170 " gl_FragColor = mix(one, two, 0.5);" | |
171 "}"; | |
172 | |
173 // This shader blends the three textures | |
174 ShaderProgram DoubleTextureBlendShaderProgram(GLuint vertex_buffer, | |
175 GLuint texture_buffer_0, | |
176 GLuint texture_buffer_1) { | |
177 ShaderProgram program = | |
178 InitShaderProgram(double_texture_blend_vertex_shader, | |
179 double_texture_blend_fragment_shader); | |
180 | |
181 // Set up the texture sampler | |
182 int textureSampler0 = glGetUniformLocation(program, "texture_sampler_0"); | |
183 glUniform1i(textureSampler0, 0); | |
184 int textureSampler1 = glGetUniformLocation(program, "texture_sampler_1"); | |
185 glUniform1i(textureSampler1, 1); | |
186 | |
187 // Set up vertex attribute | |
188 int attribute_index = glGetAttribLocation(program, "c1"); | |
189 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); | |
190 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL); | |
191 glEnableVertexAttribArray(attribute_index); | |
192 | |
193 // Set up texture attributes | |
194 attribute_index = glGetAttribLocation(program, "c2"); | |
195 glBindBuffer(GL_ARRAY_BUFFER, texture_buffer_0); | |
196 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL); | |
197 glEnableVertexAttribArray(attribute_index); | |
198 | |
199 attribute_index = glGetAttribLocation(program, "c3"); | |
200 glBindBuffer(GL_ARRAY_BUFFER, texture_buffer_1); | |
201 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL); | |
202 glEnableVertexAttribArray(attribute_index); | |
203 | |
204 return program; | |
205 } | |
206 | |
207 const char *triple_texture_blend_vertex_shader = | |
208 "attribute vec4 c1;" | |
209 "attribute vec4 c2;" | |
210 "attribute vec4 c3;" | |
211 "attribute vec4 c4;" | |
212 "varying vec2 v1;" | |
213 "varying vec2 v2;" | |
214 "varying vec2 v3;" | |
215 "void main() {" | |
216 " gl_Position = c1;" | |
217 " " V1 " = c2;" | |
218 " " V2 " = c3;" | |
219 " " V3 " = c4;" | |
220 "}"; | |
221 | |
222 const char *triple_texture_blend_fragment_shader = | |
223 "uniform sampler2D texture_sampler_0;" | |
224 "uniform sampler2D texture_sampler_1;" | |
225 "uniform sampler2D texture_sampler_2;" | |
226 "varying vec2 v1;" | |
227 "varying vec2 v2;" | |
228 "varying vec2 v3;" | |
229 "void main() {" | |
230 " vec4 one = texture2D(texture_sampler_0, " V1 ".xy);" | |
231 " vec4 two = texture2D(texture_sampler_1, " V2 ".xy);" | |
232 " vec4 three = texture2D(texture_sampler_2, " V3 ".xy);" | |
233 " gl_FragColor = mix(mix(one, two, 0.5), three, 0.5);" | |
234 "}"; | |
235 | |
236 // This shader blends the three textures | |
237 ShaderProgram TripleTextureBlendShaderProgram(GLuint vertex_buffer, | |
238 GLuint texture_buffer_0, | |
239 GLuint texture_buffer_1, | |
240 GLuint texture_buffer_2) { | |
241 ShaderProgram program = | |
242 InitShaderProgram(triple_texture_blend_vertex_shader, | |
243 triple_texture_blend_fragment_shader); | |
244 | |
245 // Set up the texture sampler | |
246 int textureSampler0 = glGetUniformLocation(program, "texture_sampler_0"); | |
247 glUniform1i(textureSampler0, 0); | |
248 int textureSampler1 = glGetUniformLocation(program, "texture_sampler_1"); | |
249 glUniform1i(textureSampler1, 1); | |
250 int textureSampler2 = glGetUniformLocation(program, "texture_sampler_2"); | |
251 glUniform1i(textureSampler2, 2); | |
252 | |
253 // Set up vertex attribute | |
254 int attribute_index = glGetAttribLocation(program, "c1"); | |
255 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); | |
256 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL); | |
257 glEnableVertexAttribArray(attribute_index); | |
258 | |
259 // Set up texture attributes | |
260 attribute_index = glGetAttribLocation(program, "c2"); | |
261 glBindBuffer(GL_ARRAY_BUFFER, texture_buffer_0); | |
262 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL); | |
263 glEnableVertexAttribArray(attribute_index); | |
264 | |
265 attribute_index = glGetAttribLocation(program, "c3"); | |
266 glBindBuffer(GL_ARRAY_BUFFER, texture_buffer_1); | |
267 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL); | |
268 glEnableVertexAttribArray(attribute_index); | |
269 | |
270 attribute_index = glGetAttribLocation(program, "c4"); | |
271 glBindBuffer(GL_ARRAY_BUFFER, texture_buffer_2); | |
272 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL); | |
273 glEnableVertexAttribArray(attribute_index); | |
274 | |
275 return program; | |
276 } | |
277 | |
278 const char *vertex_shader_1_varying = | |
279 "attribute vec4 c;" | |
280 "varying vec4 v1;" | |
281 "void main() {" | |
282 " gl_Position = c;" | |
283 V1 "= c;" | |
284 "}"; | |
285 | |
286 const char *vertex_shader_2_varying = | |
287 "attribute vec4 c;" | |
288 "varying vec4 v1;" | |
289 "varying vec4 v2;" | |
290 "void main() {" | |
291 " gl_Position = c;" | |
292 V1 "=" V2 "= c/2.;" | |
293 "}"; | |
294 | |
295 const char *vertex_shader_4_varying = | |
296 "attribute vec4 c;" | |
297 "varying vec4 v1;" | |
298 "varying vec4 v2;" | |
299 "varying vec4 v3;" | |
300 "varying vec4 v4;" | |
301 "void main() {" | |
302 " gl_Position = c;" | |
303 V1 "=" V2 "=" V3 "=" V4 "= c/4.;" | |
304 "}"; | |
305 | |
306 const char *vertex_shader_8_varying = | |
307 "attribute vec4 c;" | |
308 "varying vec4 v1;" | |
309 "varying vec4 v2;" | |
310 "varying vec4 v3;" | |
311 "varying vec4 v4;" | |
312 "varying vec4 v5;" | |
313 "varying vec4 v6;" | |
314 "varying vec4 v7;" | |
315 "varying vec4 v8;" | |
316 "void main() {" | |
317 " gl_Position = c;" | |
318 V1 "=" V2 "=" V3 "=" V4 "=" V5 "=" V6 "=" V7 "=" V8 "= c/8.;" | |
319 "}"; | |
320 | |
321 const char *fragment_shader_1_varying = | |
322 "varying vec4 v1;" | |
323 "void main() {" | |
324 " gl_FragColor =" V1 ";" | |
325 "}"; | |
326 | |
327 const char *fragment_shader_2_varying = | |
328 "varying vec4 v1;" | |
329 "varying vec4 v2;" | |
330 "void main() {" | |
331 " gl_FragColor =" V1 "+" V2 ";" | |
332 "}"; | |
333 | |
334 const char *fragment_shader_4_varying = | |
335 "varying vec4 v1;" | |
336 "varying vec4 v2;" | |
337 "varying vec4 v3;" | |
338 "varying vec4 v4;" | |
339 "void main() {" | |
340 " gl_FragColor =" V1 "+" V2 "+" V3 "+" V4 ";" | |
341 "}"; | |
342 | |
343 const char *fragment_shader_8_varying = | |
344 "varying vec4 v1;" | |
345 "varying vec4 v2;" | |
346 "varying vec4 v3;" | |
347 "varying vec4 v4;" | |
348 "varying vec4 v5;" | |
349 "varying vec4 v6;" | |
350 "varying vec4 v7;" | |
351 "varying vec4 v8;" | |
352 "void main() {" | |
353 " gl_FragColor =" V1 "+" V2 "+" V3 "+" V4 "+" V5 "+" V6 "+" V7 "+" V8 ";" | |
354 "}"; | |
355 | |
356 const char *fragment_shader_ddx = | |
357 "varying vec4 v1;" | |
358 "void main() {" | |
359 " gl_FragColor = vec4(" DDX "(" V1 ".x), 0., 0., 1.);" | |
360 "}"; | |
361 | |
362 const char *fragment_shader_ddy = | |
363 "varying vec4 v1;" | |
364 "void main() {" | |
365 " gl_FragColor = vec4(" DDY "(" V1 ".y), 0., 0., 1.);" | |
366 "}"; | |
367 | |
368 #undef V1 | |
369 #undef V2 | |
370 #undef V3 | |
371 #undef V4 | |
372 #undef V5 | |
373 #undef V6 | |
374 #undef V7 | |
375 #undef V8 | |
376 #undef DDX | |
377 #undef DDY | |
378 | |
379 | |
380 ShaderProgram VaryingsShaderProgram(int varyings_count, GLuint vertex_buffer) { | |
381 const char *vertex_shader = NULL; | |
382 const char *fragment_shader = NULL; | |
383 switch (varyings_count) { | |
384 case 1: | |
385 vertex_shader = vertex_shader_1_varying; | |
386 fragment_shader = fragment_shader_1_varying; | |
387 break; | |
388 case 2: | |
389 vertex_shader = vertex_shader_2_varying; | |
390 fragment_shader = fragment_shader_2_varying; | |
391 break; | |
392 case 4: | |
393 vertex_shader = vertex_shader_4_varying; | |
394 fragment_shader = fragment_shader_4_varying; | |
395 break; | |
396 case 8: | |
397 vertex_shader = vertex_shader_8_varying; | |
398 fragment_shader = fragment_shader_8_varying; | |
399 break; | |
400 default: return 0; | |
401 } | |
402 ShaderProgram program = | |
403 InitShaderProgram(vertex_shader, fragment_shader); | |
404 | |
405 int attribute_index = glGetAttribLocation(program, "c"); | |
406 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); | |
407 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL); | |
408 glEnableVertexAttribArray(attribute_index); | |
409 | |
410 return program; | |
411 } | |
412 | |
413 | |
414 ShaderProgram DdxDdyShaderProgram(bool ddx, GLuint vertex_buffer) { | |
415 ShaderProgram program = | |
416 InitShaderProgram(vertex_shader_1_varying, | |
417 ddx ? fragment_shader_ddx : fragment_shader_ddy); | |
418 | |
419 int attribute_index = glGetAttribLocation(program, "c"); | |
420 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); | |
421 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL); | |
422 glEnableVertexAttribArray(attribute_index); | |
423 | |
424 return program; | |
425 } | |
426 | |
427 ShaderProgram YuvToRgbShaderProgram(int type, GLuint vertex_buffer, | |
428 int width, int height) { | |
429 const char *vertex = type == 1 ? YUV2RGB_VERTEX_1 : YUV2RGB_VERTEX_2; | |
430 const char *fragment = type == 1 ? YUV2RGB_FRAGMENT_1 : YUV2RGB_FRAGMENT_2; | |
431 size_t size_vertex = 0; | |
432 size_t size_fragment = 0; | |
433 char *yuv_to_rgb_vertex = static_cast<char *>( | |
434 MmapFile(vertex, &size_vertex)); | |
435 char *yuv_to_rgb_fragment = static_cast<char *>( | |
436 MmapFile(fragment, &size_fragment)); | |
437 ShaderProgram program = 0; | |
438 | |
439 if (!yuv_to_rgb_fragment || !yuv_to_rgb_vertex) | |
440 goto done; | |
441 | |
442 { | |
443 program = InitShaderProgram(yuv_to_rgb_vertex, | |
444 yuv_to_rgb_fragment); | |
445 | |
446 int imageWidthUniform = glGetUniformLocation(program, "imageWidth"); | |
447 int imageHeightUniform = glGetUniformLocation(program, "imageHeight"); | |
448 int textureSampler = glGetUniformLocation(program, "textureSampler"); | |
449 int evenLinesSampler = glGetUniformLocation(program, "paritySampler"); | |
450 | |
451 glUniform1f(imageWidthUniform, width); | |
452 glUniform1f(imageHeightUniform, height); | |
453 glUniform1i(textureSampler, 0); | |
454 glUniform1i(evenLinesSampler, 1); | |
455 | |
456 int attribute_index = glGetAttribLocation(program, "c"); | |
457 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); | |
458 glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL); | |
459 glEnableVertexAttribArray(attribute_index); | |
460 return program; | |
461 } | |
462 | |
463 | |
464 done: | |
465 munmap(yuv_to_rgb_fragment, size_fragment); | |
466 munmap(yuv_to_rgb_fragment, size_vertex); | |
467 return program; | |
468 } | |
OLD | NEW |