OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "gpu/command_buffer/common/types.h" | 9 #include "gpu/command_buffer/common/types.h" |
10 #include "gpu/command_buffer/service/gl_utils.h" | 10 #include "gpu/command_buffer/service/gl_utils.h" |
11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
12 | 12 |
13 #define SHADER0(src) \ | 13 #define SHADER(src) \ |
14 "#ifdef GL_ES\n"\ | 14 "#ifdef GL_ES\n" \ |
15 "precision mediump float;\n"\ | 15 "precision mediump float;\n" \ |
16 "#endif\n"\ | 16 "#endif\n" #src |
17 #src | 17 #define SHADER_2D(src) \ |
18 #define SHADER(src) { false, SHADER0(src), } | 18 "#define SamplerType sampler2D\n" \ |
19 #define SHADER_EXTERNAL_OES0(src) \ | 19 "#define TextureLookup texture2D\n" SHADER(src) |
20 "#extension GL_OES_EGL_image_external : require\n"\ | 20 #define SHADER_EXTERNAL_OES(src) \ |
21 "#ifdef GL_ES\n"\ | 21 "#extension GL_OES_EGL_image_external : require\n" \ |
22 "precision mediump float;\n"\ | 22 "#define SamplerType samplerExternalOES\n" \ |
23 "#endif\n"\ | 23 "#define TextureLookup texture2D\n" SHADER(src) |
24 #src | 24 #define SHADERS(src) \ |
25 #define SHADER_EXTERNAL_OES(src) { true, SHADER_EXTERNAL_OES0(src), } | 25 { SHADER_2D(src), SHADER_EXTERNAL_OES(src) } |
26 | 26 |
27 namespace { | 27 namespace { |
28 | 28 |
29 const GLfloat kQuadVertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, | 29 const GLfloat kQuadVertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, |
30 1.0f, -1.0f, 0.0f, 1.0f, | 30 1.0f, -1.0f, 0.0f, 1.0f, |
31 1.0f, 1.0f, 0.0f, 1.0f, | 31 1.0f, 1.0f, 0.0f, 1.0f, |
32 -1.0f, 1.0f, 0.0f, 1.0f }; | 32 -1.0f, 1.0f, 0.0f, 1.0f }; |
33 | 33 |
34 enum ProgramId { | 34 enum ShaderId { |
35 PROGRAM_COPY_TEXTURE, | 35 SHADER_COPY_TEXTURE, |
36 PROGRAM_COPY_TEXTURE_FLIP_Y, | 36 SHADER_COPY_TEXTURE_FLIP_Y, |
37 PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA, | 37 SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA, |
38 PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA, | 38 SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA, |
39 PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY, | 39 SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIP_Y, |
40 PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY, | 40 SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIP_Y, |
41 PROGRAM_COPY_TEXTURE_OES, | 41 NUM_SHADERS, |
42 PROGRAM_COPY_TEXTURE_OES_FLIP_Y, | |
43 PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA, | |
44 PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA, | |
45 PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA_FLIPY, | |
46 PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA_FLIPY, | |
47 }; | 42 }; |
48 | 43 |
49 struct ShaderInfo { | 44 enum SamplerId { |
50 bool needs_egl_image_external; | 45 SAMPLER_TEXTURE_2D, |
51 const char* source; | 46 SAMPLER_TEXTURE_EXTERNAL_OES, |
| 47 NUM_SAMPLERS, |
52 }; | 48 }; |
53 | 49 |
54 const ShaderInfo shader_infos[] = { | 50 const char* vertex_shader_source = |
55 // VERTEX_SHADER_POS_TEX | |
56 SHADER( | 51 SHADER( |
57 uniform mat4 u_matrix; | 52 uniform mat4 u_matrix; |
58 attribute vec4 a_position; | 53 attribute vec4 a_position; |
59 varying vec2 v_uv; | 54 varying vec2 v_uv; |
60 void main(void) { | 55 void main(void) { |
61 gl_Position = u_matrix * a_position; | 56 gl_Position = u_matrix * a_position; |
62 v_uv = a_position.xy * 0.5 + vec2(0.5, 0.5); | 57 v_uv = a_position.xy * 0.5 + vec2(0.5, 0.5); |
63 }), | 58 }); |
64 // FRAGMENT_SHADER_TEX | 59 |
65 SHADER( | 60 const char* fragment_shader_source[NUM_SHADERS][NUM_SAMPLERS] = { |
66 uniform sampler2D u_texSampler; | 61 // SHADER_COPY_TEXTURE |
| 62 SHADERS( |
| 63 uniform SamplerType u_texSampler; |
67 varying vec2 v_uv; | 64 varying vec2 v_uv; |
68 void main(void) { | 65 void main(void) { |
69 gl_FragColor = texture2D(u_texSampler, v_uv.st); | 66 gl_FragColor = TextureLookup(u_texSampler, v_uv.st); |
70 }), | 67 }), |
71 // FRAGMENT_SHADER_TEX_FLIP_Y | 68 // SHADER_COPY_TEXTURE_FLIP_Y |
72 SHADER( | 69 SHADERS( |
73 uniform sampler2D u_texSampler; | 70 uniform SamplerType u_texSampler; |
74 varying vec2 v_uv; | 71 varying vec2 v_uv; |
75 void main(void) { | 72 void main(void) { |
76 gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | 73 gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); |
77 }), | 74 }), |
78 // FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA | 75 // SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA |
79 SHADER( | 76 SHADERS( |
80 uniform sampler2D u_texSampler; | 77 uniform SamplerType u_texSampler; |
81 varying vec2 v_uv; | 78 varying vec2 v_uv; |
82 void main(void) { | 79 void main(void) { |
83 gl_FragColor = texture2D(u_texSampler, v_uv.st); | 80 gl_FragColor = TextureLookup(u_texSampler, v_uv.st); |
84 gl_FragColor.rgb *= gl_FragColor.a; | 81 gl_FragColor.rgb *= gl_FragColor.a; |
85 }), | 82 }), |
86 // FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA | 83 // SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA |
87 SHADER( | 84 SHADERS( |
88 uniform sampler2D u_texSampler; | 85 uniform SamplerType u_texSampler; |
89 varying vec2 v_uv; | 86 varying vec2 v_uv; |
90 void main(void) { | 87 void main(void) { |
91 gl_FragColor = texture2D(u_texSampler, v_uv.st); | 88 gl_FragColor = TextureLookup(u_texSampler, v_uv.st); |
92 if (gl_FragColor.a > 0.0) | 89 if (gl_FragColor.a > 0.0) |
93 gl_FragColor.rgb /= gl_FragColor.a; | 90 gl_FragColor.rgb /= gl_FragColor.a; |
94 }), | 91 }), |
95 // FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y | 92 // SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIP_Y |
96 SHADER( | 93 SHADERS( |
97 uniform sampler2D u_texSampler; | 94 uniform SamplerType u_texSampler; |
98 varying vec2 v_uv; | 95 varying vec2 v_uv; |
99 void main(void) { | 96 void main(void) { |
100 gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | 97 gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); |
101 gl_FragColor.rgb *= gl_FragColor.a; | 98 gl_FragColor.rgb *= gl_FragColor.a; |
102 }), | 99 }), |
103 // FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA_FLIP_Y | 100 // SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIP_Y |
104 SHADER( | 101 SHADERS( |
105 uniform sampler2D u_texSampler; | 102 uniform SamplerType u_texSampler; |
106 varying vec2 v_uv; | 103 varying vec2 v_uv; |
107 void main(void) { | 104 void main(void) { |
108 gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | 105 gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); |
109 if (gl_FragColor.a > 0.0) | 106 if (gl_FragColor.a > 0.0) |
110 gl_FragColor.rgb /= gl_FragColor.a; | 107 gl_FragColor.rgb /= gl_FragColor.a; |
111 }), | 108 }), |
112 // FRAGMENT_SHADER_TEX_OES | |
113 SHADER_EXTERNAL_OES( | |
114 precision mediump float; | |
115 uniform samplerExternalOES u_texSampler; | |
116 varying vec2 v_uv; | |
117 void main(void) { | |
118 gl_FragColor = texture2D(u_texSampler, v_uv.st); | |
119 }), | |
120 // FRAGMENT_SHADER_TEX_OES_FLIP_Y | |
121 SHADER_EXTERNAL_OES( | |
122 precision mediump float; | |
123 uniform samplerExternalOES u_texSampler; | |
124 varying vec2 v_uv; | |
125 void main(void) { | |
126 gl_FragColor = | |
127 texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | |
128 }), | |
129 // FRAGMENT_SHADER_TEX_OES_PREMULTIPLY_ALPHA | |
130 SHADER_EXTERNAL_OES( | |
131 precision mediump float; | |
132 uniform samplerExternalOES u_texSampler; | |
133 varying vec2 v_uv; | |
134 void main(void) { | |
135 gl_FragColor = texture2D(u_texSampler, v_uv.st); | |
136 gl_FragColor.rgb *= gl_FragColor.a; | |
137 }), | |
138 // FRAGMENT_SHADER_TEX_OES_UNPREMULTIPLY_ALPHA | |
139 SHADER_EXTERNAL_OES( | |
140 precision mediump float; | |
141 uniform samplerExternalOES u_texSampler; | |
142 varying vec2 v_uv; | |
143 void main(void) { | |
144 gl_FragColor = texture2D(u_texSampler, v_uv.st); | |
145 if (gl_FragColor.a > 0.0) | |
146 gl_FragColor.rgb /= gl_FragColor.a; | |
147 }), | |
148 // FRAGMENT_SHADER_TEX_OES_PREMULTIPLY_ALPHA_FLIP_Y | |
149 SHADER_EXTERNAL_OES( | |
150 precision mediump float; | |
151 uniform samplerExternalOES u_texSampler; | |
152 varying vec2 v_uv; | |
153 void main(void) { | |
154 gl_FragColor = | |
155 texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | |
156 gl_FragColor.rgb *= gl_FragColor.a; | |
157 }), | |
158 // FRAGMENT_SHADER_TEX_OES_UNPREMULTIPLY_ALPHA_FLIP_Y | |
159 SHADER_EXTERNAL_OES( | |
160 precision mediump float; | |
161 uniform samplerExternalOES u_texSampler; | |
162 varying vec2 v_uv; | |
163 void main(void) { | |
164 gl_FragColor = | |
165 texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | |
166 if (gl_FragColor.a > 0.0) | |
167 gl_FragColor.rgb /= gl_FragColor.a; | |
168 }), | |
169 }; | 109 }; |
170 | 110 |
171 const int kNumShaders = arraysize(shader_infos); | 111 // Returns the correct shader id to evaluate the copy operation for |
172 | |
173 // Returns the correct program to evaluate the copy operation for | |
174 // the CHROMIUM_flipy and premultiply alpha pixel store settings. | 112 // the CHROMIUM_flipy and premultiply alpha pixel store settings. |
175 ProgramId GetProgram( | 113 ShaderId GetShaderId(bool flip_y, |
176 bool flip_y, | 114 bool premultiply_alpha, |
177 bool premultiply_alpha, | 115 bool unpremultiply_alpha) { |
178 bool unpremultiply_alpha, | |
179 bool is_source_external_oes) { | |
180 // If both pre-multiply and unpremultiply are requested, then perform no | 116 // If both pre-multiply and unpremultiply are requested, then perform no |
181 // alpha manipulation. | 117 // alpha manipulation. |
182 if (premultiply_alpha && unpremultiply_alpha) { | 118 if (premultiply_alpha && unpremultiply_alpha) { |
183 premultiply_alpha = false; | 119 premultiply_alpha = false; |
184 unpremultiply_alpha = false; | 120 unpremultiply_alpha = false; |
185 } | 121 } |
186 | 122 |
187 // bit 0: Flip_y | 123 // bit 0: Flip_y |
188 // bit 1: Premult | 124 // bit 1: Premult |
189 // bit 2: Unpremult | 125 // bit 2: Unpremult |
190 // bit 3: External_oes | 126 static ShaderId shader_ids[] = { |
191 static ProgramId program_ids[] = { | 127 SHADER_COPY_TEXTURE, |
192 PROGRAM_COPY_TEXTURE, | 128 SHADER_COPY_TEXTURE_FLIP_Y, // F |
193 PROGRAM_COPY_TEXTURE_FLIP_Y, // F | 129 SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA, // P |
194 PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA, // P | 130 SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIP_Y, // F P |
195 PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY, // F P | 131 SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA, // U |
196 PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA, // U | 132 SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIP_Y, // F U |
197 PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY, // F U | 133 SHADER_COPY_TEXTURE, // P U |
198 PROGRAM_COPY_TEXTURE, // P U | 134 SHADER_COPY_TEXTURE_FLIP_Y, // F P U |
199 PROGRAM_COPY_TEXTURE, // F P U | |
200 PROGRAM_COPY_TEXTURE_OES, // E | |
201 PROGRAM_COPY_TEXTURE_OES_FLIP_Y, // F E | |
202 PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA, // P E | |
203 PROGRAM_COPY_TEXTURE_OES_PREMULTIPLY_ALPHA_FLIPY, // F P E | |
204 PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA, // U E | |
205 PROGRAM_COPY_TEXTURE_OES_UNPREMULTIPLY_ALPHA_FLIPY, // F U E | |
206 PROGRAM_COPY_TEXTURE_OES, // P U E | |
207 PROGRAM_COPY_TEXTURE_OES, // F P U E | |
208 }; | 135 }; |
209 | 136 |
210 unsigned index = (flip_y ? (1 << 0) : 0) | | 137 unsigned index = (flip_y ? (1 << 0) : 0) | |
211 (premultiply_alpha ? (1 << 1) : 0) | | 138 (premultiply_alpha ? (1 << 1) : 0) | |
212 (unpremultiply_alpha ? (1 << 2) : 0) | | 139 (unpremultiply_alpha ? (1 << 2) : 0); |
213 (is_source_external_oes ? (1 << 3) : 0); | 140 return shader_ids[index]; |
214 return program_ids[index]; | 141 } |
| 142 |
| 143 SamplerId GetSamplerId(GLenum source_target) { |
| 144 switch (source_target) { |
| 145 case GL_TEXTURE_2D: |
| 146 return SAMPLER_TEXTURE_2D; |
| 147 case GL_TEXTURE_EXTERNAL_OES: |
| 148 return SAMPLER_TEXTURE_EXTERNAL_OES; |
| 149 } |
| 150 |
| 151 NOTREACHED(); |
| 152 return SAMPLER_TEXTURE_2D; |
| 153 } |
| 154 |
| 155 void CompileShader(GLuint shader, const char* shader_source) { |
| 156 glShaderSource(shader, 1, &shader_source, 0); |
| 157 glCompileShader(shader); |
| 158 #ifndef NDEBUG |
| 159 GLint compile_status; |
| 160 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); |
| 161 if (GL_TRUE != compile_status) |
| 162 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; |
| 163 #endif |
215 } | 164 } |
216 | 165 |
217 } // namespace | 166 } // namespace |
218 | 167 |
219 namespace gpu { | 168 namespace gpu { |
220 | 169 |
221 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() | 170 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() |
222 : initialized_(false), | 171 : initialized_(false), buffer_id_(0), framebuffer_(0), vertex_shader_(0) { |
223 buffer_id_(0), | |
224 framebuffer_(0) { | |
225 for (int i = 0; i < kNumPrograms; ++i) { | |
226 programs_[i] = 0; | |
227 matrix_handle_[i] = 0; | |
228 sampler_locations_[i] = 0; | |
229 } | |
230 } | 172 } |
231 | 173 |
| 174 CopyTextureCHROMIUMResourceManager::~CopyTextureCHROMIUMResourceManager() {} |
| 175 |
232 void CopyTextureCHROMIUMResourceManager::Initialize( | 176 void CopyTextureCHROMIUMResourceManager::Initialize( |
233 const gles2::GLES2Decoder* decoder) { | 177 const gles2::GLES2Decoder* decoder) { |
234 COMPILE_ASSERT( | 178 COMPILE_ASSERT( |
235 kVertexPositionAttrib == 0u, | 179 kVertexPositionAttrib == 0u, |
236 Position_attribs_must_be_0); | 180 Position_attribs_must_be_0); |
237 | 181 |
238 const char* extensions = | |
239 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); | |
240 bool have_egl_image_external = extensions && | |
241 strstr(extensions, "GL_OES_EGL_image_external"); | |
242 | |
243 // Initialize all of the GPU resources required to perform the copy. | 182 // Initialize all of the GPU resources required to perform the copy. |
244 glGenBuffersARB(1, &buffer_id_); | 183 glGenBuffersARB(1, &buffer_id_); |
245 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); | 184 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); |
246 glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, | 185 glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, |
247 GL_STATIC_DRAW); | 186 GL_STATIC_DRAW); |
248 | 187 |
249 glGenFramebuffersEXT(1, &framebuffer_); | 188 glGenFramebuffersEXT(1, &framebuffer_); |
250 | 189 |
251 // TODO(gman): Init these on demand. | 190 vertex_shader_ = glCreateShader(GL_VERTEX_SHADER); |
252 GLuint shaders[kNumShaders]; | 191 CompileShader(vertex_shader_, vertex_shader_source); |
253 for (int shader = 0; shader < kNumShaders; ++shader) { | |
254 shaders[shader] = glCreateShader( | |
255 shader == 0 ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER); | |
256 const ShaderInfo& info = shader_infos[shader]; | |
257 if (info.needs_egl_image_external && !have_egl_image_external) { | |
258 continue; | |
259 } | |
260 const char* shader_source = shader_infos[shader].source; | |
261 glShaderSource(shaders[shader], 1, &shader_source, 0); | |
262 glCompileShader(shaders[shader]); | |
263 #ifndef NDEBUG | |
264 GLint compile_status; | |
265 glGetShaderiv(shaders[shader], GL_COMPILE_STATUS, &compile_status); | |
266 if (GL_TRUE != compile_status) | |
267 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; | |
268 #endif | |
269 } | |
270 | |
271 // TODO(gman): Init these on demand. | |
272 for (int program = 0; program < kNumPrograms; ++program) { | |
273 const ShaderInfo& info = shader_infos[program + 1]; | |
274 if (info.needs_egl_image_external && !have_egl_image_external) { | |
275 continue; | |
276 } | |
277 programs_[program] = glCreateProgram(); | |
278 glAttachShader(programs_[program], shaders[0]); | |
279 glAttachShader(programs_[program], shaders[program + 1]); | |
280 | |
281 glBindAttribLocation(programs_[program], kVertexPositionAttrib, | |
282 "a_position"); | |
283 | |
284 glLinkProgram(programs_[program]); | |
285 #ifndef NDEBUG | |
286 GLint linked; | |
287 glGetProgramiv(programs_[program], GL_LINK_STATUS, &linked); | |
288 if (!linked) | |
289 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; | |
290 #endif | |
291 | |
292 sampler_locations_[program] = glGetUniformLocation(programs_[program], | |
293 "u_texSampler"); | |
294 | |
295 matrix_handle_[program] = glGetUniformLocation(programs_[program], | |
296 "u_matrix"); | |
297 } | |
298 | |
299 for (int shader = 0; shader < kNumShaders; ++shader) | |
300 glDeleteShader(shaders[shader]); | |
301 | 192 |
302 decoder->RestoreBufferBindings(); | 193 decoder->RestoreBufferBindings(); |
303 | 194 |
304 initialized_ = true; | 195 initialized_ = true; |
305 } | 196 } |
306 | 197 |
307 void CopyTextureCHROMIUMResourceManager::Destroy() { | 198 void CopyTextureCHROMIUMResourceManager::Destroy() { |
308 if (!initialized_) | 199 if (!initialized_) |
309 return; | 200 return; |
310 | 201 |
311 glDeleteFramebuffersEXT(1, &framebuffer_); | 202 glDeleteFramebuffersEXT(1, &framebuffer_); |
312 | 203 |
313 for (int program = 0; program < kNumPrograms; ++program) { | 204 glDeleteShader(vertex_shader_); |
314 if (programs_[program]) | 205 for (ProgramMap::const_iterator it = programs_.begin(); it != programs_.end(); |
315 glDeleteProgram(programs_[program]); | 206 ++it) { |
| 207 const ProgramInfo& info = it->second; |
| 208 glDeleteProgram(info.program); |
316 } | 209 } |
317 | 210 |
318 glDeleteBuffersARB(1, &buffer_id_); | 211 glDeleteBuffersARB(1, &buffer_id_); |
319 } | 212 } |
320 | 213 |
321 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( | 214 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( |
322 const gles2::GLES2Decoder* decoder, | 215 const gles2::GLES2Decoder* decoder, |
323 GLenum source_target, | 216 GLenum source_target, |
324 GLenum dest_target, | 217 GLenum dest_target, |
325 GLuint source_id, | 218 GLuint source_id, |
(...skipping 27 matching lines...) Expand all Loading... |
353 bool premultiply_alpha, | 246 bool premultiply_alpha, |
354 bool unpremultiply_alpha, | 247 bool unpremultiply_alpha, |
355 const GLfloat transform_matrix[16]) { | 248 const GLfloat transform_matrix[16]) { |
356 DCHECK(source_target == GL_TEXTURE_2D || | 249 DCHECK(source_target == GL_TEXTURE_2D || |
357 source_target == GL_TEXTURE_EXTERNAL_OES); | 250 source_target == GL_TEXTURE_EXTERNAL_OES); |
358 if (!initialized_) { | 251 if (!initialized_) { |
359 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; | 252 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; |
360 return; | 253 return; |
361 } | 254 } |
362 | 255 |
363 GLuint program = GetProgram( | 256 ShaderId shader_id = |
364 flip_y, premultiply_alpha, unpremultiply_alpha, | 257 GetShaderId(flip_y, premultiply_alpha, unpremultiply_alpha); |
365 source_target == GL_TEXTURE_EXTERNAL_OES); | 258 SamplerId sampler_id = GetSamplerId(source_target); |
366 glUseProgram(programs_[program]); | 259 |
| 260 ProgramMapKey key(shader_id, sampler_id); |
| 261 ProgramInfo* info = &programs_[key]; |
| 262 // Create program if necessary. |
| 263 if (!info->program) { |
| 264 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER); |
| 265 CompileShader(shader, fragment_shader_source[shader_id][sampler_id]); |
| 266 info->program = glCreateProgram(); |
| 267 glAttachShader(info->program, vertex_shader_); |
| 268 glAttachShader(info->program, shader); |
| 269 glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position"); |
| 270 glLinkProgram(info->program); |
| 271 #ifndef NDEBUG |
| 272 GLint linked; |
| 273 glGetProgramiv(info->program, GL_LINK_STATUS, &linked); |
| 274 if (!linked) |
| 275 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; |
| 276 #endif |
| 277 info->sampler_locations = |
| 278 glGetUniformLocation(info->program, "u_texSampler"); |
| 279 info->matrix_handle = glGetUniformLocation(info->program, "u_matrix"); |
| 280 glDeleteShader(shader); |
| 281 } |
| 282 glUseProgram(info->program); |
367 | 283 |
368 #ifndef NDEBUG | 284 #ifndef NDEBUG |
369 glValidateProgram(programs_[program]); | 285 glValidateProgram(info->program); |
370 GLint validation_status; | 286 GLint validation_status; |
371 glGetProgramiv(programs_[program], GL_VALIDATE_STATUS, &validation_status); | 287 glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status); |
372 if (GL_TRUE != validation_status) { | 288 if (GL_TRUE != validation_status) { |
373 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; | 289 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; |
374 return; | 290 return; |
375 } | 291 } |
376 #endif | 292 #endif |
377 | 293 |
378 glUniformMatrix4fv(matrix_handle_[program], 1, GL_FALSE, transform_matrix); | 294 glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix); |
379 glActiveTexture(GL_TEXTURE0); | 295 glActiveTexture(GL_TEXTURE0); |
380 glBindTexture(GL_TEXTURE_2D, dest_id); | 296 glBindTexture(GL_TEXTURE_2D, dest_id); |
381 // NVidia drivers require texture settings to be a certain way | 297 // NVidia drivers require texture settings to be a certain way |
382 // or they won't report FRAMEBUFFER_COMPLETE. | 298 // or they won't report FRAMEBUFFER_COMPLETE. |
383 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 299 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
384 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 300 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
385 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 301 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
386 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 302 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
387 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_); | 303 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_); |
388 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dest_target, | 304 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dest_target, |
389 dest_id, level); | 305 dest_id, level); |
390 | 306 |
391 #ifndef NDEBUG | 307 #ifndef NDEBUG |
392 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | 308 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
393 if (GL_FRAMEBUFFER_COMPLETE != fb_status) { | 309 if (GL_FRAMEBUFFER_COMPLETE != fb_status) { |
394 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; | 310 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; |
395 } else | 311 } else |
396 #endif | 312 #endif |
397 { | 313 { |
398 decoder->ClearAllAttributes(); | 314 decoder->ClearAllAttributes(); |
399 glEnableVertexAttribArray(kVertexPositionAttrib); | 315 glEnableVertexAttribArray(kVertexPositionAttrib); |
400 | 316 |
401 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); | 317 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); |
402 glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE, | 318 glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE, |
403 4 * sizeof(GLfloat), 0); | 319 4 * sizeof(GLfloat), 0); |
404 | 320 |
405 glUniform1i(sampler_locations_[program], 0); | 321 glUniform1i(info->sampler_locations, 0); |
406 | 322 |
407 glBindTexture(source_target, source_id); | 323 glBindTexture(source_target, source_id); |
408 glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 324 glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
409 glTexParameterf(source_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 325 glTexParameterf(source_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
410 glTexParameteri(source_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 326 glTexParameteri(source_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
411 glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 327 glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
412 | 328 |
413 glDisable(GL_DEPTH_TEST); | 329 glDisable(GL_DEPTH_TEST); |
414 glDisable(GL_SCISSOR_TEST); | 330 glDisable(GL_SCISSOR_TEST); |
415 glDisable(GL_STENCIL_TEST); | 331 glDisable(GL_STENCIL_TEST); |
(...skipping 12 matching lines...) Expand all Loading... |
428 decoder->RestoreTextureUnitBindings(0); | 344 decoder->RestoreTextureUnitBindings(0); |
429 decoder->RestoreActiveTexture(); | 345 decoder->RestoreActiveTexture(); |
430 decoder->RestoreProgramBindings(); | 346 decoder->RestoreProgramBindings(); |
431 decoder->RestoreBufferBindings(); | 347 decoder->RestoreBufferBindings(); |
432 decoder->RestoreFramebufferBindings(); | 348 decoder->RestoreFramebufferBindings(); |
433 decoder->RestoreGlobalState(); | 349 decoder->RestoreGlobalState(); |
434 } | 350 } |
435 | 351 |
436 } // namespace | 352 } // namespace |
437 | 353 |
OLD | NEW |