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

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc

Issue 2479513002: Reland of Extend CopyTextureCHROMIUM to more ES 3.0 texture formats. (Closed)
Patch Set: rebase and minor fix for premultiply and un-premultiply alpha Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698