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 }; |
piman
2014/04/25 03:30:40
This should be 2 components per vertex instead of
reveman
2014/04/25 20:27:10
I'll fix this in a follow up.
| |
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, |
piman
2014/04/25 03:30:40
nit: it'd be nice to be consistent between FLIP_Y
reveman
2014/04/25 20:27:10
Done.
| |
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_FLIPY, |
40 PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY, | 40 SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY, |
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 | 51 // VERTEX_SHADER_POS_TEX |
56 SHADER( | 52 SHADER( |
57 uniform mat4 u_matrix; | 53 uniform mat4 u_matrix; |
58 attribute vec4 a_position; | 54 attribute vec4 a_position; |
59 varying vec2 v_uv; | 55 varying vec2 v_uv; |
60 void main(void) { | 56 void main(void) { |
61 gl_Position = u_matrix * a_position; | 57 gl_Position = u_matrix * a_position; |
62 v_uv = a_position.xy * 0.5 + vec2(0.5, 0.5); | 58 v_uv = a_position.xy * 0.5 + vec2(0.5, 0.5); |
63 }), | 59 }); |
60 | |
61 const char* fragment_shader_source[NUM_SHADERS][NUM_SAMPLERS] = { | |
64 // FRAGMENT_SHADER_TEX | 62 // FRAGMENT_SHADER_TEX |
65 SHADER( | 63 SHADERS( |
66 uniform sampler2D u_texSampler; | 64 uniform SamplerType u_texSampler; |
67 varying vec2 v_uv; | 65 varying vec2 v_uv; |
68 void main(void) { | 66 void main(void) { |
69 gl_FragColor = texture2D(u_texSampler, v_uv.st); | 67 gl_FragColor = TextureLookup(u_texSampler, v_uv.st); |
70 }), | 68 }), |
71 // FRAGMENT_SHADER_TEX_FLIP_Y | 69 // FRAGMENT_SHADER_TEX_FLIP_Y |
72 SHADER( | 70 SHADERS( |
73 uniform sampler2D u_texSampler; | 71 uniform SamplerType u_texSampler; |
74 varying vec2 v_uv; | 72 varying vec2 v_uv; |
75 void main(void) { | 73 void main(void) { |
76 gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | 74 gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); |
piman
2014/04/25 03:30:40
Maybe for later... those shaders would be more eff
reveman
2014/04/25 20:27:10
I'll do this in a follow up. I need to change this
| |
77 }), | 75 }), |
78 // FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA | 76 // FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA |
79 SHADER( | 77 SHADERS( |
80 uniform sampler2D u_texSampler; | 78 uniform SamplerType u_texSampler; |
81 varying vec2 v_uv; | 79 varying vec2 v_uv; |
82 void main(void) { | 80 void main(void) { |
83 gl_FragColor = texture2D(u_texSampler, v_uv.st); | 81 gl_FragColor = TextureLookup(u_texSampler, v_uv.st); |
84 gl_FragColor.rgb *= gl_FragColor.a; | 82 gl_FragColor.rgb *= gl_FragColor.a; |
85 }), | 83 }), |
86 // FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA | 84 // FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA |
87 SHADER( | 85 SHADERS( |
88 uniform sampler2D u_texSampler; | 86 uniform SamplerType u_texSampler; |
89 varying vec2 v_uv; | 87 varying vec2 v_uv; |
90 void main(void) { | 88 void main(void) { |
91 gl_FragColor = texture2D(u_texSampler, v_uv.st); | 89 gl_FragColor = TextureLookup(u_texSampler, v_uv.st); |
92 if (gl_FragColor.a > 0.0) | 90 if (gl_FragColor.a > 0.0) |
93 gl_FragColor.rgb /= gl_FragColor.a; | 91 gl_FragColor.rgb /= gl_FragColor.a; |
94 }), | 92 }), |
95 // FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y | 93 // FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y |
96 SHADER( | 94 SHADERS( |
97 uniform sampler2D u_texSampler; | 95 uniform SamplerType u_texSampler; |
98 varying vec2 v_uv; | 96 varying vec2 v_uv; |
99 void main(void) { | 97 void main(void) { |
100 gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | 98 gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); |
101 gl_FragColor.rgb *= gl_FragColor.a; | 99 gl_FragColor.rgb *= gl_FragColor.a; |
102 }), | 100 }), |
103 // FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA_FLIP_Y | 101 // FRAGMENT_SHADER_TEX_UNPREMULTIPLY_ALPHA_FLIP_Y |
104 SHADER( | 102 SHADERS( |
105 uniform sampler2D u_texSampler; | 103 uniform SamplerType u_texSampler; |
106 varying vec2 v_uv; | 104 varying vec2 v_uv; |
107 void main(void) { | 105 void main(void) { |
108 gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | 106 gl_FragColor = TextureLookup(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); |
109 if (gl_FragColor.a > 0.0) | 107 if (gl_FragColor.a > 0.0) |
110 gl_FragColor.rgb /= gl_FragColor.a; | 108 gl_FragColor.rgb /= gl_FragColor.a; |
111 }), | 109 }), |
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 }; | 110 }; |
170 | 111 |
171 const int kNumShaders = arraysize(shader_infos); | 112 // 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. | 113 // the CHROMIUM_flipy and premultiply alpha pixel store settings. |
175 ProgramId GetProgram( | 114 ShaderId GetShaderId(bool flip_y, |
176 bool flip_y, | 115 bool premultiply_alpha, |
177 bool premultiply_alpha, | 116 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 | 117 // If both pre-multiply and unpremultiply are requested, then perform no |
181 // alpha manipulation. | 118 // alpha manipulation. |
182 if (premultiply_alpha && unpremultiply_alpha) { | 119 if (premultiply_alpha && unpremultiply_alpha) { |
183 premultiply_alpha = false; | 120 premultiply_alpha = false; |
184 unpremultiply_alpha = false; | 121 unpremultiply_alpha = false; |
185 } | 122 } |
186 | 123 |
187 // bit 0: Flip_y | 124 // bit 0: Flip_y |
188 // bit 1: Premult | 125 // bit 1: Premult |
189 // bit 2: Unpremult | 126 // bit 2: Unpremult |
190 // bit 3: External_oes | 127 static ShaderId shader_ids[] = { |
191 static ProgramId program_ids[] = { | 128 SHADER_COPY_TEXTURE, |
192 PROGRAM_COPY_TEXTURE, | 129 SHADER_COPY_TEXTURE_FLIP_Y, // F |
193 PROGRAM_COPY_TEXTURE_FLIP_Y, // F | 130 SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA, // P |
194 PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA, // P | 131 SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY, // F P |
195 PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY, // F P | 132 SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA, // U |
196 PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA, // U | 133 SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY, // F U |
197 PROGRAM_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_FLIPY, // F U | 134 SHADER_COPY_TEXTURE, // P U |
198 PROGRAM_COPY_TEXTURE, // P U | 135 SHADER_COPY_TEXTURE, // F P U |
piman
2014/04/25 03:30:40
Shouldn't this last one be SHADER_COPY_TEXTURE_FLI
reveman
2014/04/25 20:27:10
Sure, I assume these last two are invalid configur
| |
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 }; | 136 }; |
209 | 137 |
210 unsigned index = (flip_y ? (1 << 0) : 0) | | 138 unsigned index = (flip_y ? (1 << 0) : 0) | |
211 (premultiply_alpha ? (1 << 1) : 0) | | 139 (premultiply_alpha ? (1 << 1) : 0) | |
212 (unpremultiply_alpha ? (1 << 2) : 0) | | 140 (unpremultiply_alpha ? (1 << 2) : 0); |
213 (is_source_external_oes ? (1 << 3) : 0); | 141 return shader_ids[index]; |
214 return program_ids[index]; | 142 } |
143 | |
144 SamplerId GetSamplerId(GLenum source_target) { | |
145 switch (source_target) { | |
146 case GL_TEXTURE_2D: | |
147 return SAMPLER_TEXTURE_2D; | |
148 case GL_TEXTURE_EXTERNAL_OES: | |
149 return SAMPLER_TEXTURE_EXTERNAL_OES; | |
150 } | |
151 | |
152 NOTREACHED(); | |
153 return SAMPLER_TEXTURE_2D; | |
154 } | |
155 | |
156 void CompileShader(GLuint shader, const char* shader_source) { | |
157 glShaderSource(shader, 1, &shader_source, 0); | |
158 glCompileShader(shader); | |
159 #ifndef NDEBUG | |
160 GLint compile_status; | |
161 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); | |
162 if (GL_TRUE != compile_status) | |
163 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; | |
164 #endif | |
215 } | 165 } |
216 | 166 |
217 } // namespace | 167 } // namespace |
218 | 168 |
219 namespace gpu { | 169 namespace gpu { |
220 | 170 |
221 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() | 171 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() |
222 : initialized_(false), | 172 : 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 } | 173 } |
231 | 174 |
175 CopyTextureCHROMIUMResourceManager::~CopyTextureCHROMIUMResourceManager() {} | |
176 | |
232 void CopyTextureCHROMIUMResourceManager::Initialize( | 177 void CopyTextureCHROMIUMResourceManager::Initialize( |
233 const gles2::GLES2Decoder* decoder) { | 178 const gles2::GLES2Decoder* decoder) { |
234 COMPILE_ASSERT( | 179 COMPILE_ASSERT( |
235 kVertexPositionAttrib == 0u, | 180 kVertexPositionAttrib == 0u, |
236 Position_attribs_must_be_0); | 181 Position_attribs_must_be_0); |
237 | 182 |
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. | 183 // Initialize all of the GPU resources required to perform the copy. |
244 glGenBuffersARB(1, &buffer_id_); | 184 glGenBuffersARB(1, &buffer_id_); |
245 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); | 185 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); |
246 glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, | 186 glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, |
247 GL_STATIC_DRAW); | 187 GL_STATIC_DRAW); |
248 | 188 |
249 glGenFramebuffersEXT(1, &framebuffer_); | 189 glGenFramebuffersEXT(1, &framebuffer_); |
250 | 190 |
251 // TODO(gman): Init these on demand. | 191 vertex_shader_ = glCreateShader(GL_VERTEX_SHADER); |
252 GLuint shaders[kNumShaders]; | 192 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 | 193 |
302 decoder->RestoreBufferBindings(); | 194 decoder->RestoreBufferBindings(); |
303 | 195 |
304 initialized_ = true; | 196 initialized_ = true; |
305 } | 197 } |
306 | 198 |
307 void CopyTextureCHROMIUMResourceManager::Destroy() { | 199 void CopyTextureCHROMIUMResourceManager::Destroy() { |
308 if (!initialized_) | 200 if (!initialized_) |
309 return; | 201 return; |
310 | 202 |
311 glDeleteFramebuffersEXT(1, &framebuffer_); | 203 glDeleteFramebuffersEXT(1, &framebuffer_); |
312 | 204 |
313 for (int program = 0; program < kNumPrograms; ++program) { | 205 glDeleteShader(vertex_shader_); |
314 if (programs_[program]) | 206 for (ProgramMap::const_iterator it = programs_.begin(); it != programs_.end(); |
315 glDeleteProgram(programs_[program]); | 207 ++it) { |
208 const ProgramInfo& info = it->second; | |
209 glDeleteProgram(info.program); | |
316 } | 210 } |
317 | 211 |
318 glDeleteBuffersARB(1, &buffer_id_); | 212 glDeleteBuffersARB(1, &buffer_id_); |
319 } | 213 } |
320 | 214 |
321 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( | 215 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( |
322 const gles2::GLES2Decoder* decoder, | 216 const gles2::GLES2Decoder* decoder, |
323 GLenum source_target, | 217 GLenum source_target, |
324 GLenum dest_target, | 218 GLenum dest_target, |
325 GLuint source_id, | 219 GLuint source_id, |
(...skipping 27 matching lines...) Expand all Loading... | |
353 bool premultiply_alpha, | 247 bool premultiply_alpha, |
354 bool unpremultiply_alpha, | 248 bool unpremultiply_alpha, |
355 const GLfloat transform_matrix[16]) { | 249 const GLfloat transform_matrix[16]) { |
356 DCHECK(source_target == GL_TEXTURE_2D || | 250 DCHECK(source_target == GL_TEXTURE_2D || |
357 source_target == GL_TEXTURE_EXTERNAL_OES); | 251 source_target == GL_TEXTURE_EXTERNAL_OES); |
358 if (!initialized_) { | 252 if (!initialized_) { |
359 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; | 253 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; |
360 return; | 254 return; |
361 } | 255 } |
362 | 256 |
363 GLuint program = GetProgram( | 257 ShaderId shader_id = |
364 flip_y, premultiply_alpha, unpremultiply_alpha, | 258 GetShaderId(flip_y, premultiply_alpha, unpremultiply_alpha); |
365 source_target == GL_TEXTURE_EXTERNAL_OES); | 259 SamplerId sampler_id = GetSamplerId(source_target); |
366 glUseProgram(programs_[program]); | 260 |
261 ProgramMapKey key(shader_id, sampler_id); | |
262 ProgramInfo* info = &programs_[key]; | |
263 // Create program if necessary. | |
264 if (!info->program) { | |
265 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER); | |
266 CompileShader(shader, fragment_shader_source[shader_id][sampler_id]); | |
267 info->program = glCreateProgram(); | |
268 glAttachShader(info->program, vertex_shader_); | |
269 glAttachShader(info->program, shader); | |
270 glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position"); | |
271 glLinkProgram(info->program); | |
272 #ifndef NDEBUG | |
273 GLint linked; | |
274 glGetProgramiv(info->program, GL_LINK_STATUS, &linked); | |
275 if (!linked) | |
276 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; | |
277 #endif | |
278 info->sampler_locations = | |
279 glGetUniformLocation(info->program, "u_texSampler"); | |
280 info->matrix_handle = glGetUniformLocation(info->program, "u_matrix"); | |
281 glDeleteShader(shader); | |
282 } | |
283 glUseProgram(info->program); | |
367 | 284 |
368 #ifndef NDEBUG | 285 #ifndef NDEBUG |
369 glValidateProgram(programs_[program]); | 286 glValidateProgram(info->program); |
370 GLint validation_status; | 287 GLint validation_status; |
371 glGetProgramiv(programs_[program], GL_VALIDATE_STATUS, &validation_status); | 288 glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status); |
372 if (GL_TRUE != validation_status) { | 289 if (GL_TRUE != validation_status) { |
373 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; | 290 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; |
374 return; | 291 return; |
375 } | 292 } |
376 #endif | 293 #endif |
377 | 294 |
378 glUniformMatrix4fv(matrix_handle_[program], 1, GL_FALSE, transform_matrix); | 295 glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix); |
379 glActiveTexture(GL_TEXTURE0); | 296 glActiveTexture(GL_TEXTURE0); |
380 glBindTexture(GL_TEXTURE_2D, dest_id); | 297 glBindTexture(GL_TEXTURE_2D, dest_id); |
381 // NVidia drivers require texture settings to be a certain way | 298 // NVidia drivers require texture settings to be a certain way |
382 // or they won't report FRAMEBUFFER_COMPLETE. | 299 // or they won't report FRAMEBUFFER_COMPLETE. |
383 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 300 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); | 301 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
385 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 302 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
386 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 303 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
387 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_); | 304 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_); |
388 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dest_target, | 305 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dest_target, |
389 dest_id, level); | 306 dest_id, level); |
390 | 307 |
391 #ifndef NDEBUG | 308 #ifndef NDEBUG |
392 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | 309 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
393 if (GL_FRAMEBUFFER_COMPLETE != fb_status) { | 310 if (GL_FRAMEBUFFER_COMPLETE != fb_status) { |
394 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; | 311 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; |
395 } else | 312 } else |
396 #endif | 313 #endif |
397 { | 314 { |
398 decoder->ClearAllAttributes(); | 315 decoder->ClearAllAttributes(); |
399 glEnableVertexAttribArray(kVertexPositionAttrib); | 316 glEnableVertexAttribArray(kVertexPositionAttrib); |
400 | 317 |
401 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); | 318 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); |
402 glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE, | 319 glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE, |
403 4 * sizeof(GLfloat), 0); | 320 4 * sizeof(GLfloat), 0); |
404 | 321 |
405 glUniform1i(sampler_locations_[program], 0); | 322 glUniform1i(info->sampler_locations, 0); |
406 | 323 |
407 glBindTexture(source_target, source_id); | 324 glBindTexture(source_target, source_id); |
408 glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 325 glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
409 glTexParameterf(source_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 326 glTexParameterf(source_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
410 glTexParameteri(source_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 327 glTexParameteri(source_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
411 glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 328 glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
412 | 329 |
413 glDisable(GL_DEPTH_TEST); | 330 glDisable(GL_DEPTH_TEST); |
414 glDisable(GL_SCISSOR_TEST); | 331 glDisable(GL_SCISSOR_TEST); |
415 glDisable(GL_STENCIL_TEST); | 332 glDisable(GL_STENCIL_TEST); |
(...skipping 12 matching lines...) Expand all Loading... | |
428 decoder->RestoreTextureUnitBindings(0); | 345 decoder->RestoreTextureUnitBindings(0); |
429 decoder->RestoreActiveTexture(); | 346 decoder->RestoreActiveTexture(); |
430 decoder->RestoreProgramBindings(); | 347 decoder->RestoreProgramBindings(); |
431 decoder->RestoreBufferBindings(); | 348 decoder->RestoreBufferBindings(); |
432 decoder->RestoreFramebufferBindings(); | 349 decoder->RestoreFramebufferBindings(); |
433 decoder->RestoreGlobalState(); | 350 decoder->RestoreGlobalState(); |
434 } | 351 } |
435 | 352 |
436 } // namespace | 353 } // namespace |
437 | 354 |
OLD | NEW |