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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
11 #include "gpu/command_buffer/service/gl_utils.h" | 11 #include "gpu/command_buffer/service/gl_utils.h" |
12 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 12 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
13 #include "gpu/command_buffer/service/texture_manager.h" | |
13 #include "ui/gl/gl_version_info.h" | 14 #include "ui/gl/gl_version_info.h" |
14 | 15 |
15 namespace { | 16 namespace { |
16 | 17 |
17 const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, | 18 const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, |
18 0.0f, 1.0f, 0.0f, 0.0f, | 19 0.0f, 1.0f, 0.0f, 0.0f, |
19 0.0f, 0.0f, 1.0f, 0.0f, | 20 0.0f, 0.0f, 1.0f, 0.0f, |
20 0.0f, 0.0f, 0.0f, 1.0f}; | 21 0.0f, 0.0f, 0.0f, 1.0f}; |
21 | 22 |
22 enum FragmentShaderId { | 23 enum FragmentShaderId { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
79 case GL_TEXTURE_EXTERNAL_OES: | 80 case GL_TEXTURE_EXTERNAL_OES: |
80 return shader_ids[index][SAMPLER_EXTERNAL_OES]; | 81 return shader_ids[index][SAMPLER_EXTERNAL_OES]; |
81 default: | 82 default: |
82 break; | 83 break; |
83 } | 84 } |
84 | 85 |
85 NOTREACHED(); | 86 NOTREACHED(); |
86 return shader_ids[0][SAMPLER_2D]; | 87 return shader_ids[0][SAMPLER_2D]; |
87 } | 88 } |
88 | 89 |
89 const char* kShaderPrecisionPreamble = "\ | 90 const char* kShaderPrecisionPreamble = |
90 #ifdef GL_ES\n\ | 91 "#ifdef GL_ES\n" |
Zhenyao Mo
2016/11/19 00:42:32
You can use LONG_STRING_CONST so the shader source
qiankun
2016/11/21 16:01:50
ifdef and define will be treated as C++ directives
| |
91 precision mediump float;\n\ | 92 "precision mediump float;\n" |
92 #define TexCoordPrecision mediump\n\ | 93 "#define TexCoordPrecision mediump\n" |
93 #else\n\ | 94 "#else\n" |
94 #define TexCoordPrecision\n\ | 95 "#define TexCoordPrecision\n" |
95 #endif\n"; | 96 "#endif\n"; |
96 | 97 |
97 std::string GetVertexShaderSource(const gl::GLVersionInfo& gl_version_info) { | 98 std::string GetVertexShaderSource(const gl::GLVersionInfo& gl_version_info) { |
98 std::string source; | 99 std::string source; |
99 | 100 |
100 // Preamble for core and compatibility mode. | 101 if (gl_version_info.is_es) { |
101 if (gl_version_info.is_desktop_core_profile) { | 102 if (gl_version_info.is_es3) { |
102 source += std::string("\ | 103 source += std::string("#version 300 es\n"); |
103 #version 150\n\ | 104 source += std::string( |
104 #define ATTRIBUTE in\n\ | 105 "#define ATTRIBUTE in\n" |
105 #define VARYING out\n"); | 106 "#define VARYING out\n"); |
107 } else { | |
108 source += std::string( | |
109 "#define ATTRIBUTE attribute\n" | |
110 "#define VARYING varying\n"); | |
111 } | |
106 } else { | 112 } else { |
107 source += std::string("\ | 113 source += std::string("#version 150\n"); |
108 #define ATTRIBUTE attribute\n\ | 114 source += std::string( |
109 #define VARYING varying\n"); | 115 "#define ATTRIBUTE in\n" |
116 "#define VARYING out\n"); | |
110 } | 117 } |
111 | 118 |
112 // Preamble for texture precision. | 119 // Preamble for texture precision. |
113 source += std::string(kShaderPrecisionPreamble); | 120 source += std::string(kShaderPrecisionPreamble); |
114 | 121 |
115 // Main shader source. | 122 // Main shader source. |
116 source += std::string("\ | 123 source += std::string( |
117 uniform vec2 u_vertex_dest_mult;\n\ | 124 "uniform vec2 u_vertex_dest_mult;\n" |
118 uniform vec2 u_vertex_dest_add;\n\ | 125 "uniform vec2 u_vertex_dest_add;\n" |
119 uniform vec2 u_vertex_source_mult;\n\ | 126 "uniform vec2 u_vertex_source_mult;\n" |
120 uniform vec2 u_vertex_source_add;\n\ | 127 "uniform vec2 u_vertex_source_add;\n" |
121 ATTRIBUTE vec2 a_position;\n\ | 128 "ATTRIBUTE vec2 a_position;\n" |
122 VARYING TexCoordPrecision vec2 v_uv;\n\ | 129 "VARYING TexCoordPrecision vec2 v_uv;\n" |
123 void main(void) {\n\ | 130 "void main(void) {\n" |
124 gl_Position = vec4(0, 0, 0, 1);\n\ | 131 " gl_Position = vec4(0, 0, 0, 1);\n" |
125 gl_Position.xy = a_position.xy * u_vertex_dest_mult + \ | 132 " gl_Position.xy = a_position.xy * u_vertex_dest_mult + " |
126 u_vertex_dest_add;\n\ | 133 "u_vertex_dest_add;\n" |
127 v_uv = a_position.xy * u_vertex_source_mult + u_vertex_source_add;\n\ | 134 " v_uv = a_position.xy * u_vertex_source_mult + u_vertex_source_add;\n" |
128 }\n"); | 135 "}\n"); |
129 | 136 |
130 return source; | 137 return source; |
131 } | 138 } |
132 | 139 |
133 std::string GetFragmentShaderSource(const gl::GLVersionInfo& gl_version_info, | 140 std::string GetFragmentShaderSource(const gl::GLVersionInfo& gl_version_info, |
134 bool premultiply_alpha, | 141 bool premultiply_alpha, |
135 bool unpremultiply_alpha, | 142 bool unpremultiply_alpha, |
136 bool nv_egl_stream_consumer_external, | 143 bool nv_egl_stream_consumer_external, |
137 GLenum target) { | 144 GLenum target, |
145 GLenum source_format, | |
146 GLenum dest_format) { | |
138 std::string source; | 147 std::string source; |
139 | 148 |
140 // Preamble for core and compatibility mode. | 149 // Preamble for core and compatibility mode. |
141 if (gl_version_info.is_desktop_core_profile) { | 150 if (gl_version_info.is_es) { |
142 source += std::string("\ | 151 if (gl_version_info.is_es3) { |
143 #version 150\n\ | 152 source += std::string("#version 300 es\n"); |
144 out vec4 frag_color;\n\ | 153 } |
145 #define VARYING in\n\ | 154 if (target == GL_TEXTURE_EXTERNAL_OES) { |
146 #define FRAGCOLOR frag_color\n\ | 155 source += std::string("#extension GL_OES_EGL_image_external : enable\n"); |
147 #define TextureLookup texture\n"); | 156 |
157 if (nv_egl_stream_consumer_external) { | |
158 source += std::string( | |
159 "#extension GL_NV_EGL_stream_consumer_external : enable\n"); | |
160 } | |
161 } | |
148 } else { | 162 } else { |
163 source += std::string("#version 150\n"); | |
164 } | |
165 | |
166 // Preamble for texture precision. | |
167 source += std::string(kShaderPrecisionPreamble); | |
168 | |
169 if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(dest_format)) { | |
170 source += std::string("#define TextureType ivec4\n"); | |
171 source += std::string("#define ZERO 0\n"); | |
172 source += std::string("#define MAX_COLOR 255\n"); | |
173 if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(source_format)) | |
174 source += std::string("#define InnerScaleValue 1\n"); | |
175 else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(source_format)) | |
176 source += std::string("#define InnerScaleValue 1u\n"); | |
177 else | |
178 source += std::string("#define InnerScaleValue 255.0\n"); | |
179 source += std::string("#define OuterScaleValue 1\n"); | |
180 } else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(dest_format)) { | |
181 source += std::string("#define TextureType uvec4\n"); | |
182 source += std::string("#define ZERO 0u\n"); | |
183 source += std::string("#define MAX_COLOR 255u\n"); | |
184 if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(source_format)) | |
185 source += std::string("#define InnerScaleValue 1\n"); | |
186 else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(source_format)) | |
187 source += std::string("#define InnerScaleValue 1u\n"); | |
188 else | |
189 source += std::string("#define InnerScaleValue 255.0\n"); | |
190 source += std::string("#define OuterScaleValue 1u\n"); | |
191 } else { | |
192 source += std::string("#define TextureType vec4\n"); | |
193 source += std::string("#define ZERO 0.0\n"); | |
194 source += std::string("#define MAX_COLOR 1.0\n"); | |
195 if (gpu::gles2::GLES2Util::IsSignedIntegerFormat(source_format)) { | |
196 source += std::string("#define InnerScaleValue 1\n"); | |
197 source += std::string("#define OuterScaleValue (1.0 / 255.0)\n"); | |
198 } else if (gpu::gles2::GLES2Util::IsUnsignedIntegerFormat(source_format)) { | |
199 source += std::string("#define InnerScaleValue 1u\n"); | |
200 source += std::string("#define OuterScaleValue (1.0 / 255.0)\n"); | |
201 } else { | |
202 source += std::string("#define InnerScaleValue 1.0\n"); | |
203 source += std::string("#define OuterScaleValue 1.0\n"); | |
204 } | |
205 } | |
206 if (gl_version_info.is_es2) { | |
149 switch (target) { | 207 switch (target) { |
150 case GL_TEXTURE_2D: | 208 case GL_TEXTURE_2D: |
209 case GL_TEXTURE_EXTERNAL_OES: | |
151 source += std::string("#define TextureLookup texture2D\n"); | 210 source += std::string("#define TextureLookup texture2D\n"); |
152 break; | 211 break; |
153 case GL_TEXTURE_RECTANGLE_ARB: | 212 case GL_TEXTURE_RECTANGLE_ARB: |
Zhenyao Mo
2016/11/19 00:42:32
This is not needed (and it's not es2 thing, it's n
qiankun
2016/11/21 16:01:50
So, it's not available now since Mac uses core pro
| |
154 source += std::string("#define TextureLookup texture2DRect\n"); | 213 source += std::string("#define TextureLookup texture2DRect\n"); |
155 break; | 214 break; |
156 case GL_TEXTURE_EXTERNAL_OES: | |
157 source += | |
158 std::string("#extension GL_OES_EGL_image_external : enable\n"); | |
159 | |
160 if (nv_egl_stream_consumer_external) { | |
161 source += std::string( | |
162 "#extension GL_NV_EGL_stream_consumer_external : enable\n"); | |
163 } | |
164 | |
165 source += std::string("#define TextureLookup texture2D\n"); | |
166 break; | |
167 default: | 215 default: |
168 NOTREACHED(); | 216 NOTREACHED(); |
169 break; | 217 break; |
170 } | 218 } |
171 source += std::string("\ | 219 |
172 #define VARYING varying\n\ | 220 source += std::string( |
173 #define FRAGCOLOR gl_FragColor\n"); | 221 "#define VARYING varying\n" |
222 "#define FRAGCOLOR gl_FragColor\n"); | |
223 } else { | |
224 source += std::string( | |
225 "#define VARYING in\n" | |
226 "out TextureType frag_color;\n" | |
227 "#define FRAGCOLOR frag_color\n" | |
228 "#define TextureLookup texture\n"); | |
174 } | 229 } |
175 | 230 |
176 // Preamble for sampler type. | 231 // Preamble for sampler type. |
177 switch (target) { | 232 switch (target) { |
178 case GL_TEXTURE_2D: | 233 case GL_TEXTURE_2D: |
179 source += std::string("#define SamplerType sampler2D\n"); | 234 source += std::string("#define SamplerType sampler2D\n"); |
180 break; | 235 break; |
181 case GL_TEXTURE_RECTANGLE_ARB: | 236 case GL_TEXTURE_RECTANGLE_ARB: |
182 source += std::string("#define SamplerType sampler2DRect\n"); | 237 source += std::string("#define SamplerType sampler2DRect\n"); |
183 break; | 238 break; |
184 case GL_TEXTURE_EXTERNAL_OES: | 239 case GL_TEXTURE_EXTERNAL_OES: |
185 source += std::string("#define SamplerType samplerExternalOES\n"); | 240 source += std::string("#define SamplerType samplerExternalOES\n"); |
186 break; | 241 break; |
187 default: | 242 default: |
188 NOTREACHED(); | 243 NOTREACHED(); |
189 break; | 244 break; |
190 } | 245 } |
191 | 246 |
192 // Preamble for texture precision. | |
193 source += std::string(kShaderPrecisionPreamble); | |
194 | |
195 // Main shader source. | 247 // Main shader source. |
196 source += std::string("\ | 248 source += std::string( |
197 uniform SamplerType u_sampler;\n\ | 249 "uniform mediump SamplerType u_sampler;\n" |
198 uniform mat4 u_tex_coord_transform;\n\ | 250 "uniform mat4 u_tex_coord_transform;\n" |
199 VARYING TexCoordPrecision vec2 v_uv;\n\ | 251 "VARYING TexCoordPrecision vec2 v_uv;\n" |
200 void main(void) {\n\ | 252 "void main(void) {\n" |
201 TexCoordPrecision vec4 uv = u_tex_coord_transform * vec4(v_uv, 0, 1);\n\ | 253 " TexCoordPrecision vec4 uv = u_tex_coord_transform * vec4(v_uv, 0, " |
202 FRAGCOLOR = TextureLookup(u_sampler, uv.st);\n"); | 254 "1);\n" |
255 " vec4 color = TextureLookup(u_sampler, uv.st);\n" | |
256 " FRAGCOLOR = TextureType(color * InnerScaleValue) * " | |
257 "OuterScaleValue;\n"); | |
203 | 258 |
204 // Post-processing to premultiply or un-premultiply alpha. | 259 // Post-processing to premultiply or un-premultiply alpha. |
205 if (premultiply_alpha) { | 260 // Check dest format has alpha channel first. |
206 source += std::string(" FRAGCOLOR.rgb *= FRAGCOLOR.a;\n"); | 261 if ((gpu::gles2::GLES2Util::GetChannelsForFormat(dest_format) & 0x0008) != |
207 } | 262 0) { |
208 if (unpremultiply_alpha) { | 263 if (premultiply_alpha) { |
209 source += std::string("\ | 264 source += std::string(" FRAGCOLOR.rgb *= FRAGCOLOR.a;\n"); |
210 if (FRAGCOLOR.a > 0.0)\n\ | 265 source += std::string(" FRAGCOLOR.rgb /= MAX_COLOR;\n"); |
211 FRAGCOLOR.rgb /= FRAGCOLOR.a;\n"); | 266 } |
267 if (unpremultiply_alpha) { | |
268 source += std::string( | |
269 " if (FRAGCOLOR.a > ZERO) {\n" | |
270 " FRAGCOLOR.rgb /= FRAGCOLOR.a;\n" | |
271 " FRAGCOLOR.rgb *= MAX_COLOR;\n" | |
272 " }\n"); | |
273 } | |
212 } | 274 } |
213 | 275 |
214 // Main function end. | 276 // Main function end. |
215 source += std::string(" }\n"); | 277 source += std::string("}\n"); |
216 | 278 |
217 return source; | 279 return source; |
218 } | 280 } |
219 | 281 |
282 GLenum getIntermediateFormat(GLenum format) { | |
283 // TODO(qiankun.miao@intel.com): which intermediate format should be used for | |
284 // RGB9_E5? | |
Zhenyao Mo
2016/11/19 00:42:32
Definite a float format, say GL_RGBA16F or RGBA32F
qiankun
2016/11/21 16:01:50
Use RGBA32F now.
| |
285 switch (format) { | |
286 case GL_LUMINANCE_ALPHA: | |
287 case GL_LUMINANCE: | |
288 case GL_ALPHA: | |
289 case GL_RGB9_E5: | |
290 return GL_RGBA; | |
291 case GL_SRGB_EXT: | |
292 return GL_SRGB_ALPHA_EXT; | |
293 case GL_RGB16F: | |
294 return GL_RGBA16F; | |
295 case GL_RGB32F: | |
296 return GL_RGBA32F; | |
297 case GL_SRGB8: | |
298 return GL_SRGB8_ALPHA8; | |
299 case GL_RGB8UI: | |
300 return GL_RGBA8UI; | |
301 default: | |
302 return format; | |
303 } | |
304 } | |
305 | |
220 void CompileShader(GLuint shader, const char* shader_source) { | 306 void CompileShader(GLuint shader, const char* shader_source) { |
221 glShaderSource(shader, 1, &shader_source, 0); | 307 glShaderSource(shader, 1, &shader_source, 0); |
222 glCompileShader(shader); | 308 glCompileShader(shader); |
223 #ifndef NDEBUG | 309 #ifndef NDEBUG |
224 GLint compile_status; | 310 GLint compile_status; |
225 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); | 311 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); |
226 if (GL_TRUE != compile_status) | 312 if (GL_TRUE != compile_status) { |
227 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; | 313 char buffer[1024]; |
314 GLsizei length = 0; | |
315 glGetShaderInfoLog(shader, sizeof(buffer), &length, buffer); | |
316 std::string log(buffer, length); | |
317 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure." << log; | |
318 } | |
228 #endif | 319 #endif |
229 } | 320 } |
230 | 321 |
231 void DeleteShader(GLuint shader) { | 322 void DeleteShader(GLuint shader) { |
232 if (shader) | 323 if (shader) |
233 glDeleteShader(shader); | 324 glDeleteShader(shader); |
234 } | 325 } |
235 | 326 |
236 bool BindFramebufferTexture2D(GLenum target, | 327 bool BindFramebufferTexture2D(GLenum target, |
237 GLuint texture_id, | 328 GLuint texture_id, |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
412 GLenum source_target, | 503 GLenum source_target, |
413 GLuint source_id, | 504 GLuint source_id, |
414 GLenum source_internal_format, | 505 GLenum source_internal_format, |
415 GLenum dest_target, | 506 GLenum dest_target, |
416 GLuint dest_id, | 507 GLuint dest_id, |
417 GLenum dest_internal_format, | 508 GLenum dest_internal_format, |
418 GLsizei width, | 509 GLsizei width, |
419 GLsizei height, | 510 GLsizei height, |
420 bool flip_y, | 511 bool flip_y, |
421 bool premultiply_alpha, | 512 bool premultiply_alpha, |
422 bool unpremultiply_alpha) { | 513 bool unpremultiply_alpha, |
514 SupportedCopyMethodByFormat method) { | |
423 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; | 515 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; |
424 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's | 516 |
425 // format does not contain a superset of the components required by the base | |
426 // format of internalformat. | |
427 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml | |
428 bool source_format_contain_superset_of_dest_format = | |
429 (source_internal_format == dest_internal_format && | |
430 source_internal_format != GL_BGRA_EXT) || | |
431 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); | |
432 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, | 517 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, |
433 // so restrict this to GL_TEXTURE_2D. | 518 // so restrict this to GL_TEXTURE_2D. |
434 if (source_target == GL_TEXTURE_2D && dest_target == GL_TEXTURE_2D && | 519 if (source_target == GL_TEXTURE_2D && dest_target == GL_TEXTURE_2D && |
435 !flip_y && !premultiply_alpha_change && | 520 !flip_y && !premultiply_alpha_change && method == DIRECT_COPY) { |
436 source_format_contain_superset_of_dest_format) { | |
437 DoCopyTexImage2D(decoder, | 521 DoCopyTexImage2D(decoder, |
438 source_target, | 522 source_target, |
439 source_id, | 523 source_id, |
440 dest_target, | 524 dest_target, |
441 dest_id, | 525 dest_id, |
442 dest_internal_format, | 526 dest_internal_format, |
443 width, | 527 width, |
444 height, | 528 height, |
445 framebuffer_); | 529 framebuffer_); |
446 return; | 530 return; |
447 } | 531 } |
448 | 532 |
533 GLenum adjusted_internal_format = getIntermediateFormat(dest_internal_format); | |
534 GLuint adjusted_texture = dest_id; | |
535 if (method == DRAW_AND_COPY) { | |
536 glGenTextures(1, &adjusted_texture); | |
Zhenyao Mo
2016/11/19 00:42:33
Where is this texture deleted?
qiankun
2016/11/21 16:01:50
Delete it now.
| |
537 glBindTexture(dest_target, adjusted_texture); | |
Zhenyao Mo
2016/11/19 00:42:32
I assume we already have the code to recover any c
qiankun
2016/11/21 16:01:50
Both DoCopyTexImage2D and DoCopyTextureWithTransfo
| |
538 GLenum format = TextureManager::ExtractFormatFromStorageFormat( | |
539 adjusted_internal_format); | |
540 GLenum type = | |
541 TextureManager::ExtractTypeFromStorageFormat(adjusted_internal_format); | |
542 | |
543 glTexImage2D(dest_target, 0, adjusted_internal_format, width, height, 0, | |
544 format, type, nullptr); | |
545 } | |
449 // Use kIdentityMatrix if no transform passed in. | 546 // Use kIdentityMatrix if no transform passed in. |
450 DoCopyTextureWithTransform(decoder, source_target, source_id, dest_target, | 547 DoCopyTextureWithTransform( |
451 dest_id, width, height, flip_y, premultiply_alpha, | 548 decoder, source_target, source_id, source_internal_format, dest_target, |
452 unpremultiply_alpha, kIdentityMatrix); | 549 adjusted_texture, adjusted_internal_format, width, height, flip_y, |
550 premultiply_alpha, unpremultiply_alpha, kIdentityMatrix); | |
551 | |
552 if (method == DRAW_AND_COPY) { | |
553 DoCopyTexImage2D(decoder, dest_target, adjusted_texture, dest_target, | |
554 dest_id, dest_internal_format, width, height, | |
555 framebuffer_); | |
556 } | |
453 } | 557 } |
454 | 558 |
455 void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( | 559 void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( |
456 const gles2::GLES2Decoder* decoder, | 560 const gles2::GLES2Decoder* decoder, |
457 GLenum source_target, | 561 GLenum source_target, |
458 GLuint source_id, | 562 GLuint source_id, |
459 GLenum source_internal_format, | 563 GLenum source_internal_format, |
460 GLenum dest_target, | 564 GLenum dest_target, |
461 GLuint dest_id, | 565 GLuint dest_id, |
462 GLenum dest_internal_format, | 566 GLenum dest_internal_format, |
463 GLint xoffset, | 567 GLint xoffset, |
464 GLint yoffset, | 568 GLint yoffset, |
465 GLint x, | 569 GLint x, |
466 GLint y, | 570 GLint y, |
467 GLsizei width, | 571 GLsizei width, |
468 GLsizei height, | 572 GLsizei height, |
469 GLsizei dest_width, | 573 GLsizei dest_width, |
470 GLsizei dest_height, | 574 GLsizei dest_height, |
471 GLsizei source_width, | 575 GLsizei source_width, |
472 GLsizei source_height, | 576 GLsizei source_height, |
473 bool flip_y, | 577 bool flip_y, |
474 bool premultiply_alpha, | 578 bool premultiply_alpha, |
475 bool unpremultiply_alpha) { | 579 bool unpremultiply_alpha, |
580 SupportedCopyMethodByFormat method) { | |
476 bool use_gl_copy_tex_sub_image_2d = true; | 581 bool use_gl_copy_tex_sub_image_2d = true; |
477 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) | 582 #if defined(OS_CHROMEOS) && defined(ARCH_CPU_X86_FAMILY) |
478 // glDrawArrays is faster than glCopyTexSubImage2D on IA Mesa driver, | 583 // glDrawArrays is faster than glCopyTexSubImage2D on IA Mesa driver, |
479 // although opposite in Android. | 584 // although opposite in Android. |
480 // TODO(dshwang): After Mesa fixes this issue, remove this hack. | 585 // TODO(dshwang): After Mesa fixes this issue, remove this hack. |
481 // https://bugs.freedesktop.org/show_bug.cgi?id=98478 crbug.com/535198 | 586 // https://bugs.freedesktop.org/show_bug.cgi?id=98478 crbug.com/535198 |
482 use_gl_copy_tex_sub_image_2d = false; | 587 use_gl_copy_tex_sub_image_2d = false; |
483 #endif | 588 #endif |
484 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; | 589 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; |
485 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's | 590 |
486 // format does not contain a superset of the components required by the base | |
487 // format of internalformat. | |
488 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml | |
489 bool source_format_contain_superset_of_dest_format = | |
490 (source_internal_format == dest_internal_format && | |
491 source_internal_format != GL_BGRA_EXT) || | |
492 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); | |
493 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, | 591 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, |
494 // so restrict this to GL_TEXTURE_2D. | 592 // so restrict this to GL_TEXTURE_2D. |
495 if (use_gl_copy_tex_sub_image_2d && source_target == GL_TEXTURE_2D && | 593 if (use_gl_copy_tex_sub_image_2d && source_target == GL_TEXTURE_2D && |
496 dest_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && | 594 dest_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && |
497 source_format_contain_superset_of_dest_format) { | 595 method == DIRECT_COPY) { |
498 DoCopyTexSubImage2D(decoder, source_target, source_id, dest_target, dest_id, | 596 DoCopyTexSubImage2D(decoder, source_target, source_id, dest_target, dest_id, |
499 xoffset, yoffset, x, y, width, height, framebuffer_); | 597 xoffset, yoffset, x, y, width, height, framebuffer_); |
500 return; | 598 return; |
501 } | 599 } |
502 | 600 |
601 if (method == DRAW_AND_COPY) { | |
602 GLenum adjusted_internal_format = | |
603 getIntermediateFormat(dest_internal_format); | |
604 GLuint adjusted_texture = dest_id; | |
Zhenyao Mo
2016/11/19 00:42:33
= 0. = dest_id is really confusing.
I think it's
qiankun
2016/11/21 16:01:50
Done.
| |
605 glGenTextures(1, &adjusted_texture); | |
Zhenyao Mo
2016/11/19 00:42:33
Where is this texture deleted?
qiankun
2016/11/21 16:01:50
Done.
| |
606 glBindTexture(dest_target, adjusted_texture); | |
607 GLenum format = TextureManager::ExtractFormatFromStorageFormat( | |
608 adjusted_internal_format); | |
609 GLenum type = | |
610 TextureManager::ExtractTypeFromStorageFormat(adjusted_internal_format); | |
611 | |
612 glTexImage2D(dest_target, 0, adjusted_internal_format, width, height, 0, | |
613 format, type, nullptr); | |
614 DoCopySubTextureWithTransform( | |
615 decoder, source_target, source_id, source_internal_format, dest_target, | |
616 adjusted_texture, dest_internal_format, 0, 0, x, y, width, height, | |
617 width, height, source_width, source_height, flip_y, premultiply_alpha, | |
618 unpremultiply_alpha, kIdentityMatrix); | |
619 DoCopyTexSubImage2D(decoder, dest_target, adjusted_texture, dest_target, | |
620 dest_id, xoffset, yoffset, 0, 0, width, height, | |
621 framebuffer_); | |
622 return; | |
623 } | |
624 | |
503 DoCopySubTextureWithTransform( | 625 DoCopySubTextureWithTransform( |
504 decoder, source_target, source_id, source_internal_format, dest_target, | 626 decoder, source_target, source_id, source_internal_format, dest_target, |
505 dest_id, dest_internal_format, xoffset, yoffset, x, y, width, height, | 627 dest_id, dest_internal_format, xoffset, yoffset, x, y, width, height, |
506 dest_width, dest_height, source_width, source_height, flip_y, | 628 dest_width, dest_height, source_width, source_height, flip_y, |
507 premultiply_alpha, unpremultiply_alpha, kIdentityMatrix); | 629 premultiply_alpha, unpremultiply_alpha, kIdentityMatrix); |
508 } | 630 } |
509 | 631 |
510 void CopyTextureCHROMIUMResourceManager::DoCopySubTextureWithTransform( | 632 void CopyTextureCHROMIUMResourceManager::DoCopySubTextureWithTransform( |
511 const gles2::GLES2Decoder* decoder, | 633 const gles2::GLES2Decoder* decoder, |
512 GLenum source_target, | 634 GLenum source_target, |
513 GLuint source_id, | 635 GLuint source_id, |
514 GLenum source_internal_format, | 636 GLenum source_internal_format, |
515 GLenum dest_target, | 637 GLenum dest_target, |
516 GLuint dest_id, | 638 GLuint dest_id, |
517 GLenum dest_internal_format, | 639 GLenum dest_internal_format, |
518 GLint xoffset, | 640 GLint xoffset, |
519 GLint yoffset, | 641 GLint yoffset, |
520 GLint x, | 642 GLint x, |
521 GLint y, | 643 GLint y, |
522 GLsizei width, | 644 GLsizei width, |
523 GLsizei height, | 645 GLsizei height, |
524 GLsizei dest_width, | 646 GLsizei dest_width, |
525 GLsizei dest_height, | 647 GLsizei dest_height, |
526 GLsizei source_width, | 648 GLsizei source_width, |
527 GLsizei source_height, | 649 GLsizei source_height, |
528 bool flip_y, | 650 bool flip_y, |
529 bool premultiply_alpha, | 651 bool premultiply_alpha, |
530 bool unpremultiply_alpha, | 652 bool unpremultiply_alpha, |
531 const GLfloat transform_matrix[16]) { | 653 const GLfloat transform_matrix[16]) { |
532 DoCopyTextureInternal(decoder, source_target, source_id, dest_target, dest_id, | 654 DoCopyTextureInternal( |
533 xoffset, yoffset, x, y, width, height, dest_width, dest_height, | 655 decoder, source_target, source_id, source_internal_format, dest_target, |
534 source_width, source_height, flip_y, premultiply_alpha, | 656 dest_id, dest_internal_format, xoffset, yoffset, x, y, width, height, |
535 unpremultiply_alpha, transform_matrix); | 657 dest_width, dest_height, source_width, source_height, flip_y, |
658 premultiply_alpha, unpremultiply_alpha, transform_matrix); | |
536 } | 659 } |
537 | 660 |
538 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( | 661 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( |
539 const gles2::GLES2Decoder* decoder, | 662 const gles2::GLES2Decoder* decoder, |
540 GLenum source_target, | 663 GLenum source_target, |
541 GLuint source_id, | 664 GLuint source_id, |
665 GLenum source_format, | |
542 GLenum dest_target, | 666 GLenum dest_target, |
543 GLuint dest_id, | 667 GLuint dest_id, |
668 GLenum dest_format, | |
544 GLsizei width, | 669 GLsizei width, |
545 GLsizei height, | 670 GLsizei height, |
546 bool flip_y, | 671 bool flip_y, |
547 bool premultiply_alpha, | 672 bool premultiply_alpha, |
548 bool unpremultiply_alpha, | 673 bool unpremultiply_alpha, |
549 const GLfloat transform_matrix[16]) { | 674 const GLfloat transform_matrix[16]) { |
550 GLsizei dest_width = width; | 675 GLsizei dest_width = width; |
551 GLsizei dest_height = height; | 676 GLsizei dest_height = height; |
552 DoCopyTextureInternal(decoder, source_target, source_id, dest_target, dest_id, | 677 DoCopyTextureInternal( |
553 0, 0, 0, 0, width, height, dest_width, dest_height, | 678 decoder, source_target, source_id, source_format, dest_target, dest_id, |
554 width, height, flip_y, premultiply_alpha, | 679 dest_format, 0, 0, 0, 0, width, height, dest_width, dest_height, width, |
555 unpremultiply_alpha, transform_matrix); | 680 height, flip_y, premultiply_alpha, unpremultiply_alpha, transform_matrix); |
556 } | 681 } |
557 | 682 |
558 void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal( | 683 void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal( |
559 const gles2::GLES2Decoder* decoder, | 684 const gles2::GLES2Decoder* decoder, |
560 GLenum source_target, | 685 GLenum source_target, |
561 GLuint source_id, | 686 GLuint source_id, |
687 GLenum source_format, | |
562 GLenum dest_target, | 688 GLenum dest_target, |
563 GLuint dest_id, | 689 GLuint dest_id, |
690 GLenum dest_format, | |
564 GLint xoffset, | 691 GLint xoffset, |
565 GLint yoffset, | 692 GLint yoffset, |
566 GLint x, | 693 GLint x, |
567 GLint y, | 694 GLint y, |
568 GLsizei width, | 695 GLsizei width, |
569 GLsizei height, | 696 GLsizei height, |
570 GLsizei dest_width, | 697 GLsizei dest_width, |
571 GLsizei dest_height, | 698 GLsizei dest_height, |
572 GLsizei source_width, | 699 GLsizei source_width, |
573 GLsizei source_height, | 700 GLsizei source_height, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
607 glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); | 734 glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); |
608 } | 735 } |
609 | 736 |
610 FragmentShaderId fragment_shader_id = GetFragmentShaderId( | 737 FragmentShaderId fragment_shader_id = GetFragmentShaderId( |
611 premultiply_alpha, unpremultiply_alpha, source_target); | 738 premultiply_alpha, unpremultiply_alpha, source_target); |
612 DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size()); | 739 DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size()); |
613 | 740 |
614 ProgramMapKey key(fragment_shader_id); | 741 ProgramMapKey key(fragment_shader_id); |
615 ProgramInfo* info = &programs_[key]; | 742 ProgramInfo* info = &programs_[key]; |
616 // Create program if necessary. | 743 // Create program if necessary. |
617 if (!info->program) { | 744 if (!info->program || |
745 decoder->GetFeatureInfo()->context_type() == CONTEXT_TYPE_OPENGLES3) { | |
Zhenyao Mo
2016/11/19 00:42:32
1) Why this is needed?
2) We definitely use this i
qiankun
2016/11/21 16:01:50
This is used to avoid caching program and fragment
| |
618 info->program = glCreateProgram(); | 746 info->program = glCreateProgram(); |
619 if (!vertex_shader_) { | 747 if (!vertex_shader_) { |
620 vertex_shader_ = glCreateShader(GL_VERTEX_SHADER); | 748 vertex_shader_ = glCreateShader(GL_VERTEX_SHADER); |
621 std::string source = GetVertexShaderSource(gl_version_info); | 749 std::string source = GetVertexShaderSource(gl_version_info); |
622 CompileShader(vertex_shader_, source.c_str()); | 750 CompileShader(vertex_shader_, source.c_str()); |
623 } | 751 } |
624 glAttachShader(info->program, vertex_shader_); | 752 glAttachShader(info->program, vertex_shader_); |
625 GLuint* fragment_shader = &fragment_shaders_[fragment_shader_id]; | 753 GLuint* fragment_shader = &fragment_shaders_[fragment_shader_id]; |
626 if (!*fragment_shader) { | 754 if (!*fragment_shader || |
755 decoder->GetFeatureInfo()->context_type() == CONTEXT_TYPE_OPENGLES3) { | |
627 *fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); | 756 *fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); |
628 std::string source = GetFragmentShaderSource( | 757 std::string source = GetFragmentShaderSource( |
629 gl_version_info, premultiply_alpha, unpremultiply_alpha, | 758 gl_version_info, premultiply_alpha, unpremultiply_alpha, |
630 nv_egl_stream_consumer_external_, source_target); | 759 nv_egl_stream_consumer_external_, source_target, source_format, |
760 dest_format); | |
631 CompileShader(*fragment_shader, source.c_str()); | 761 CompileShader(*fragment_shader, source.c_str()); |
632 } | 762 } |
633 glAttachShader(info->program, *fragment_shader); | 763 glAttachShader(info->program, *fragment_shader); |
634 glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position"); | 764 glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position"); |
635 glLinkProgram(info->program); | 765 glLinkProgram(info->program); |
636 #ifndef NDEBUG | 766 #ifndef NDEBUG |
637 GLint linked; | 767 GLint linked; |
638 glGetProgramiv(info->program, GL_LINK_STATUS, &linked); | 768 glGetProgramiv(info->program, GL_LINK_STATUS, &linked); |
639 if (!linked) | 769 if (!linked) |
640 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; | 770 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
771 decoder->RestoreTextureUnitBindings(0); | 901 decoder->RestoreTextureUnitBindings(0); |
772 decoder->RestoreActiveTexture(); | 902 decoder->RestoreActiveTexture(); |
773 decoder->RestoreProgramBindings(); | 903 decoder->RestoreProgramBindings(); |
774 decoder->RestoreBufferBindings(); | 904 decoder->RestoreBufferBindings(); |
775 decoder->RestoreFramebufferBindings(); | 905 decoder->RestoreFramebufferBindings(); |
776 decoder->RestoreGlobalState(); | 906 decoder->RestoreGlobalState(); |
777 } | 907 } |
778 | 908 |
779 } // namespace gles2 | 909 } // namespace gles2 |
780 } // namespace gpu | 910 } // namespace gpu |
OLD | NEW |