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

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

Issue 1547873002: Allow GL_TEXTURE_RECTANGLE_ARB to be the destination target for copyTextureCHROMIUM. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase against https://codereview.chromium.org/1551143002/. Created 4 years, 11 months 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 "ui/gl/gl_implementation.h" 13 #include "ui/gl/gl_implementation.h"
14 14
15 namespace { 15 namespace {
16 16
17 const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 17 const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
18 0.0f, 1.0f, 0.0f, 0.0f, 18 0.0f, 1.0f, 0.0f, 0.0f,
19 0.0f, 0.0f, 1.0f, 0.0f, 19 0.0f, 0.0f, 1.0f, 0.0f,
20 0.0f, 0.0f, 0.0f, 1.0f}; 20 0.0f, 0.0f, 0.0f, 1.0f};
21 21
22 enum VertexShaderId {
23 VERTEX_SHADER_COPY_TEXTURE,
24 VERTEX_SHADER_COPY_TEXTURE_FLIP_Y,
25 NUM_VERTEX_SHADERS,
26 };
27
28 enum FragmentShaderId { 22 enum FragmentShaderId {
29 FRAGMENT_SHADER_COPY_TEXTURE_2D, 23 FRAGMENT_SHADER_COPY_TEXTURE_2D,
30 FRAGMENT_SHADER_COPY_TEXTURE_RECTANGLE_ARB, 24 FRAGMENT_SHADER_COPY_TEXTURE_RECTANGLE_ARB,
31 FRAGMENT_SHADER_COPY_TEXTURE_EXTERNAL_OES, 25 FRAGMENT_SHADER_COPY_TEXTURE_EXTERNAL_OES,
32 FRAGMENT_SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_2D, 26 FRAGMENT_SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_2D,
33 FRAGMENT_SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_RECTANGLE_ARB, 27 FRAGMENT_SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_RECTANGLE_ARB,
34 FRAGMENT_SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_EXTERNAL_OES, 28 FRAGMENT_SHADER_COPY_TEXTURE_PREMULTIPLY_ALPHA_EXTERNAL_OES,
35 FRAGMENT_SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_2D, 29 FRAGMENT_SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_2D,
36 FRAGMENT_SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_RECTANGLE_ARB, 30 FRAGMENT_SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_RECTANGLE_ARB,
37 FRAGMENT_SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_EXTERNAL_OES, 31 FRAGMENT_SHADER_COPY_TEXTURE_UNPREMULTIPLY_ALPHA_EXTERNAL_OES,
38 NUM_FRAGMENT_SHADERS, 32 NUM_FRAGMENT_SHADERS,
39 }; 33 };
40 34
41 // Returns the correct vertex shader id to evaluate the copy operation for
42 // the CHROMIUM_flipy setting.
43 VertexShaderId GetVertexShaderId(bool flip_y) {
44 // bit 0: flip y
45 static VertexShaderId shader_ids[] = {
46 VERTEX_SHADER_COPY_TEXTURE,
47 VERTEX_SHADER_COPY_TEXTURE_FLIP_Y,
48 };
49
50 unsigned index = flip_y ? 1 : 0;
51 return shader_ids[index];
52 }
53
54 // Returns the correct fragment shader id to evaluate the copy operation for 35 // Returns the correct fragment shader id to evaluate the copy operation for
55 // the premultiply alpha pixel store settings and target. 36 // the premultiply alpha pixel store settings and target.
56 FragmentShaderId GetFragmentShaderId(bool premultiply_alpha, 37 FragmentShaderId GetFragmentShaderId(bool premultiply_alpha,
57 bool unpremultiply_alpha, 38 bool unpremultiply_alpha,
58 GLenum target) { 39 GLenum target) {
59 // Only one alpha mode at a time makes sense. 40 // Only one alpha mode at a time makes sense.
60 DCHECK(!premultiply_alpha || !unpremultiply_alpha); 41 DCHECK(!premultiply_alpha || !unpremultiply_alpha);
61 42
62 enum { 43 enum {
63 SAMPLER_2D, 44 SAMPLER_2D,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 90 }
110 91
111 const char* kShaderPrecisionPreamble = "\ 92 const char* kShaderPrecisionPreamble = "\
112 #ifdef GL_ES\n\ 93 #ifdef GL_ES\n\
113 precision mediump float;\n\ 94 precision mediump float;\n\
114 #define TexCoordPrecision mediump\n\ 95 #define TexCoordPrecision mediump\n\
115 #else\n\ 96 #else\n\
116 #define TexCoordPrecision\n\ 97 #define TexCoordPrecision\n\
117 #endif\n"; 98 #endif\n";
118 99
119 std::string GetVertexShaderSource(bool flip_y) { 100 std::string GetVertexShaderSource() {
120 std::string source; 101 std::string source;
121 102
122 // Preamble for core and compatibility mode. 103 // Preamble for core and compatibility mode.
123 if (gfx::GetGLImplementation() == 104 if (gfx::GetGLImplementation() ==
124 gfx::kGLImplementationDesktopGLCoreProfile) { 105 gfx::kGLImplementationDesktopGLCoreProfile) {
125 source += std::string("\ 106 source += std::string("\
126 #version 150\n\ 107 #version 150\n\
127 #define ATTRIBUTE in\n\ 108 #define ATTRIBUTE in\n\
128 #define VARYING out\n"); 109 #define VARYING out\n");
129 } else { 110 } else {
130 source += std::string("\ 111 source += std::string("\
131 #define ATTRIBUTE attribute\n\ 112 #define ATTRIBUTE attribute\n\
132 #define VARYING varying\n"); 113 #define VARYING varying\n");
133 } 114 }
134 115
135 // Preamble for texture precision. 116 // Preamble for texture precision.
136 source += std::string(kShaderPrecisionPreamble); 117 source += std::string(kShaderPrecisionPreamble);
137 118
138 // Preamble to differentiate based on |flip_y|.
139 if (flip_y) {
140 source += std::string("#define SIGN -\n");
141 } else {
142 source += std::string("#define SIGN\n");
143 }
144
145 // Main shader source. 119 // Main shader source.
146 source += std::string("\ 120 source += std::string("\
147 uniform vec2 u_vertex_translate;\n\ 121 uniform vec2 u_vertex_dest_mult;\n\
148 uniform vec2 u_half_size;\n\ 122 uniform vec2 u_vertex_dest_add;\n\
123 uniform vec2 u_vertex_source_mult;\n\
124 uniform vec2 u_vertex_source_add;\n\
149 ATTRIBUTE vec4 a_position;\n\ 125 ATTRIBUTE vec4 a_position;\n\
150 VARYING TexCoordPrecision vec2 v_uv;\n\ 126 VARYING TexCoordPrecision vec2 v_uv;\n\
151 void main(void) {\n\ 127 void main(void) {\n\
152 gl_Position = a_position + vec4(u_vertex_translate, 0.0, 0.0);\n\ 128 gl_Position = a_position;\n\
153 v_uv = a_position.xy * vec2(u_half_size.s, SIGN u_half_size.t) +\n\ 129 gl_Position.xy = a_position.xy * u_vertex_dest_mult + \
154 vec2(u_half_size.s, u_half_size.t);\n\ 130 u_vertex_dest_add;\n\
131 v_uv = a_position.xy * u_vertex_source_mult + u_vertex_source_add;\n\
155 }\n"); 132 }\n");
156 133
157 return source; 134 return source;
158 } 135 }
159 136
160 std::string GetFragmentShaderSource(bool premultiply_alpha, 137 std::string GetFragmentShaderSource(bool premultiply_alpha,
161 bool unpremultiply_alpha, 138 bool unpremultiply_alpha,
162 GLenum target) { 139 GLenum target) {
163 // Only one alpha mode at a time makes sense. 140 // Only one alpha mode at a time makes sense.
164 DCHECK(!premultiply_alpha || !unpremultiply_alpha); 141 DCHECK(!premultiply_alpha || !unpremultiply_alpha);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 } 260 }
284 261
285 void DoCopyTexImage2D(const gpu::gles2::GLES2Decoder* decoder, 262 void DoCopyTexImage2D(const gpu::gles2::GLES2Decoder* decoder,
286 GLenum source_target, 263 GLenum source_target,
287 GLuint source_id, 264 GLuint source_id,
288 GLuint dest_id, 265 GLuint dest_id,
289 GLenum dest_internal_format, 266 GLenum dest_internal_format,
290 GLsizei width, 267 GLsizei width,
291 GLsizei height, 268 GLsizei height,
292 GLuint framebuffer) { 269 GLuint framebuffer) {
293 DCHECK(source_target == GL_TEXTURE_2D || 270 DCHECK(source_target == GL_TEXTURE_2D);
294 source_target == GL_TEXTURE_RECTANGLE_ARB);
295 if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) { 271 if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) {
296 glBindTexture(GL_TEXTURE_2D, dest_id); 272 glBindTexture(GL_TEXTURE_2D, dest_id);
297 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 273 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
298 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 274 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
299 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 275 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
300 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 276 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
301 glCopyTexImage2D(GL_TEXTURE_2D, 0 /* level */, dest_internal_format, 277 glCopyTexImage2D(GL_TEXTURE_2D, 0 /* level */, dest_internal_format,
302 0 /* x */, 0 /* y */, width, height, 0 /* border */); 278 0 /* x */, 0 /* y */, width, height, 0 /* border */);
303 } 279 }
304 280
305 decoder->RestoreTextureState(source_id); 281 decoder->RestoreTextureState(source_id);
306 decoder->RestoreTextureState(dest_id); 282 decoder->RestoreTextureState(dest_id);
307 decoder->RestoreTextureUnitBindings(0); 283 decoder->RestoreTextureUnitBindings(0);
308 decoder->RestoreActiveTexture(); 284 decoder->RestoreActiveTexture();
309 decoder->RestoreFramebufferBindings(); 285 decoder->RestoreFramebufferBindings();
310 } 286 }
311 287
312 void DoCopyTexSubImage2D(const gpu::gles2::GLES2Decoder* decoder, 288 void DoCopyTexSubImage2D(const gpu::gles2::GLES2Decoder* decoder,
313 GLenum source_target, 289 GLenum source_target,
314 GLuint source_id, 290 GLuint source_id,
291 GLenum dest_target,
315 GLuint dest_id, 292 GLuint dest_id,
316 GLint xoffset, 293 GLint xoffset,
317 GLint yoffset, 294 GLint yoffset,
318 GLint source_x, 295 GLint source_x,
319 GLint source_y, 296 GLint source_y,
320 GLsizei source_width, 297 GLsizei source_width,
321 GLsizei source_height, 298 GLsizei source_height,
322 GLuint framebuffer) { 299 GLuint framebuffer) {
323 DCHECK(source_target == GL_TEXTURE_2D || 300 DCHECK(source_target == GL_TEXTURE_2D ||
324 source_target == GL_TEXTURE_RECTANGLE_ARB); 301 source_target == GL_TEXTURE_RECTANGLE_ARB);
325 if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) { 302 if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) {
326 glBindTexture(GL_TEXTURE_2D, dest_id); 303 glBindTexture(GL_TEXTURE_2D, dest_id);
Zhenyao Mo 2016/01/04 22:43:54 Should you use dest_target here and in the followi
erikchen 2016/01/04 23:28:52 This function assumes that dest_target is GL_TEXTU
327 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 304 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
328 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 305 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
329 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 306 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
330 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 307 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
331 glCopyTexSubImage2D(GL_TEXTURE_2D, 0 /* level */, xoffset, yoffset, 308 glCopyTexSubImage2D(GL_TEXTURE_2D, 0 /* level */, xoffset, yoffset,
332 source_x, source_y, source_width, source_height); 309 source_x, source_y, source_width, source_height);
333 } 310 }
334 311
335 decoder->RestoreTextureState(source_id); 312 decoder->RestoreTextureState(source_id);
336 decoder->RestoreTextureState(dest_id); 313 decoder->RestoreTextureState(dest_id);
337 decoder->RestoreTextureUnitBindings(0); 314 decoder->RestoreTextureUnitBindings(0);
338 decoder->RestoreActiveTexture(); 315 decoder->RestoreActiveTexture();
339 decoder->RestoreFramebufferBindings(); 316 decoder->RestoreFramebufferBindings();
340 } 317 }
341 318
342 } // namespace 319 } // namespace
343 320
344 namespace gpu { 321 namespace gpu {
345 322
346 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() 323 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager()
347 : initialized_(false), 324 : initialized_(false),
348 vertex_shaders_(NUM_VERTEX_SHADERS, 0u), 325 vertex_shader_(0u),
349 fragment_shaders_(NUM_FRAGMENT_SHADERS, 0u), 326 fragment_shaders_(NUM_FRAGMENT_SHADERS, 0u),
350 buffer_id_(0u), 327 buffer_id_(0u),
351 framebuffer_(0u) {} 328 framebuffer_(0u) {}
352 329
353 CopyTextureCHROMIUMResourceManager::~CopyTextureCHROMIUMResourceManager() { 330 CopyTextureCHROMIUMResourceManager::~CopyTextureCHROMIUMResourceManager() {
354 // |buffer_id_| and |framebuffer_| can be not-null because when GPU context is 331 // |buffer_id_| and |framebuffer_| can be not-null because when GPU context is
355 // lost, this class can be deleted without releasing resources like 332 // lost, this class can be deleted without releasing resources like
356 // GLES2DecoderImpl. 333 // GLES2DecoderImpl.
357 } 334 }
358 335
(...skipping 23 matching lines...) Expand all
382 initialized_ = true; 359 initialized_ = true;
383 } 360 }
384 361
385 void CopyTextureCHROMIUMResourceManager::Destroy() { 362 void CopyTextureCHROMIUMResourceManager::Destroy() {
386 if (!initialized_) 363 if (!initialized_)
387 return; 364 return;
388 365
389 glDeleteFramebuffersEXT(1, &framebuffer_); 366 glDeleteFramebuffersEXT(1, &framebuffer_);
390 framebuffer_ = 0; 367 framebuffer_ = 0;
391 368
392 std::for_each(vertex_shaders_.begin(), vertex_shaders_.end(), DeleteShader); 369 DeleteShader(vertex_shader_);
393 std::for_each( 370 std::for_each(
394 fragment_shaders_.begin(), fragment_shaders_.end(), DeleteShader); 371 fragment_shaders_.begin(), fragment_shaders_.end(), DeleteShader);
395 372
396 for (ProgramMap::const_iterator it = programs_.begin(); it != programs_.end(); 373 for (ProgramMap::const_iterator it = programs_.begin(); it != programs_.end();
397 ++it) { 374 ++it) {
398 const ProgramInfo& info = it->second; 375 const ProgramInfo& info = it->second;
399 glDeleteProgram(info.program); 376 glDeleteProgram(info.program);
400 } 377 }
401 378
402 glDeleteBuffersARB(1, &buffer_id_); 379 glDeleteBuffersARB(1, &buffer_id_);
403 buffer_id_ = 0; 380 buffer_id_ = 0;
404 } 381 }
405 382
406 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( 383 void CopyTextureCHROMIUMResourceManager::DoCopyTexture(
407 const gles2::GLES2Decoder* decoder, 384 const gles2::GLES2Decoder* decoder,
408 GLenum source_target, 385 GLenum source_target,
409 GLuint source_id, 386 GLuint source_id,
410 GLenum source_internal_format, 387 GLenum source_internal_format,
388 GLenum dest_target,
411 GLuint dest_id, 389 GLuint dest_id,
412 GLenum dest_internal_format, 390 GLenum dest_internal_format,
413 GLsizei width, 391 GLsizei width,
414 GLsizei height, 392 GLsizei height,
415 bool flip_y, 393 bool flip_y,
416 bool premultiply_alpha, 394 bool premultiply_alpha,
417 bool unpremultiply_alpha) { 395 bool unpremultiply_alpha) {
418 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; 396 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha;
419 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's 397 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's
420 // format does not contain a superset of the components required by the base 398 // format does not contain a superset of the components required by the base
421 // format of internalformat. 399 // format of internalformat.
422 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml 400 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml
423 bool source_format_contain_superset_of_dest_format = 401 bool source_format_contain_superset_of_dest_format =
424 (source_internal_format == dest_internal_format && 402 (source_internal_format == dest_internal_format &&
425 source_internal_format != GL_BGRA_EXT) || 403 source_internal_format != GL_BGRA_EXT) ||
426 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); 404 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB);
427 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, 405 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2,
428 // so restrict this to GL_TEXTURE_2D. 406 // so restrict this to GL_TEXTURE_2D.
429 if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && 407 if (source_target == GL_TEXTURE_2D && dest_target == GL_TEXTURE_2D &&
408 !flip_y && !premultiply_alpha_change &&
430 source_format_contain_superset_of_dest_format) { 409 source_format_contain_superset_of_dest_format) {
431 DoCopyTexImage2D(decoder, 410 DoCopyTexImage2D(decoder,
432 source_target, 411 source_target,
433 source_id, 412 source_id,
434 dest_id, 413 dest_id,
435 dest_internal_format, 414 dest_internal_format,
436 width, 415 width,
437 height, 416 height,
438 framebuffer_); 417 framebuffer_);
439 return; 418 return;
440 } 419 }
441 420
442 // Use kIdentityMatrix if no transform passed in. 421 // Use kIdentityMatrix if no transform passed in.
443 DoCopyTextureWithTransform(decoder, source_target, source_id, dest_id, width, 422 DoCopyTextureWithTransform(decoder, source_target, source_id, dest_target,
444 height, flip_y, premultiply_alpha, 423 dest_id, width, height, flip_y, premultiply_alpha,
445 unpremultiply_alpha, kIdentityMatrix); 424 unpremultiply_alpha, kIdentityMatrix);
446 } 425 }
447 426
448 void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( 427 void CopyTextureCHROMIUMResourceManager::DoCopySubTexture(
449 const gles2::GLES2Decoder* decoder, 428 const gles2::GLES2Decoder* decoder,
450 GLenum source_target, 429 GLenum source_target,
451 GLuint source_id, 430 GLuint source_id,
452 GLenum source_internal_format, 431 GLenum source_internal_format,
432 GLenum dest_target,
453 GLuint dest_id, 433 GLuint dest_id,
454 GLenum dest_internal_format, 434 GLenum dest_internal_format,
455 GLint xoffset, 435 GLint xoffset,
456 GLint yoffset, 436 GLint yoffset,
457 GLint x, 437 GLint x,
458 GLint y, 438 GLint y,
459 GLsizei width, 439 GLsizei width,
460 GLsizei height, 440 GLsizei height,
461 GLsizei dest_width, 441 GLsizei dest_width,
462 GLsizei dest_height, 442 GLsizei dest_height,
463 GLsizei source_width, 443 GLsizei source_width,
464 GLsizei source_height, 444 GLsizei source_height,
465 bool flip_y, 445 bool flip_y,
466 bool premultiply_alpha, 446 bool premultiply_alpha,
467 bool unpremultiply_alpha) { 447 bool unpremultiply_alpha) {
468 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; 448 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha;
469 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's 449 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's
470 // format does not contain a superset of the components required by the base 450 // format does not contain a superset of the components required by the base
471 // format of internalformat. 451 // format of internalformat.
472 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml 452 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml
473 bool source_format_contain_superset_of_dest_format = 453 bool source_format_contain_superset_of_dest_format =
474 (source_internal_format == dest_internal_format && 454 (source_internal_format == dest_internal_format &&
475 source_internal_format != GL_BGRA_EXT) || 455 source_internal_format != GL_BGRA_EXT) ||
476 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); 456 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB);
477 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, 457 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2,
478 // so restrict this to GL_TEXTURE_2D. 458 // so restrict this to GL_TEXTURE_2D.
479 if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && 459 if (source_target == GL_TEXTURE_2D && dest_target == GL_TEXTURE_2D &&
460 !flip_y && !premultiply_alpha_change &&
480 source_format_contain_superset_of_dest_format) { 461 source_format_contain_superset_of_dest_format) {
481 DoCopyTexSubImage2D(decoder, source_target, source_id, dest_id, xoffset, 462 DoCopyTexSubImage2D(decoder, source_target, source_id, dest_target, dest_id,
482 yoffset, x, y, width, height, framebuffer_); 463 xoffset, yoffset, x, y, width, height, framebuffer_);
483 return; 464 return;
484 } 465 }
485 466
486 DoCopyTextureInternal(decoder, source_target, source_id, dest_id, xoffset, 467 DoCopyTextureInternal(decoder, source_target, source_id, dest_target, dest_id,
487 yoffset, x, y, width, height, dest_width, dest_height, 468 xoffset, yoffset, x, y, width, height, dest_width, dest_height,
488 source_width, source_height, flip_y, premultiply_alpha, 469 source_width, source_height, flip_y, premultiply_alpha,
489 unpremultiply_alpha, kIdentityMatrix); 470 unpremultiply_alpha, kIdentityMatrix);
490 } 471 }
491 472
492 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( 473 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
493 const gles2::GLES2Decoder* decoder, 474 const gles2::GLES2Decoder* decoder,
494 GLenum source_target, 475 GLenum source_target,
495 GLuint source_id, 476 GLuint source_id,
477 GLenum dest_target,
496 GLuint dest_id, 478 GLuint dest_id,
497 GLsizei width, 479 GLsizei width,
498 GLsizei height, 480 GLsizei height,
499 bool flip_y, 481 bool flip_y,
500 bool premultiply_alpha, 482 bool premultiply_alpha,
501 bool unpremultiply_alpha, 483 bool unpremultiply_alpha,
502 const GLfloat transform_matrix[16]) { 484 const GLfloat transform_matrix[16]) {
503 GLsizei dest_width = width; 485 GLsizei dest_width = width;
504 GLsizei dest_height = height; 486 GLsizei dest_height = height;
505 DoCopyTextureInternal(decoder, source_target, source_id, dest_id, 0, 0, 0, 0, 487 DoCopyTextureInternal(decoder, source_target, source_id, dest_target, dest_id,
506 width, height, dest_width, dest_height, width, height, 488 0, 0, 0, 0, width, height, dest_width, dest_height,
507 flip_y, premultiply_alpha, unpremultiply_alpha, 489 width, height, flip_y, premultiply_alpha,
508 transform_matrix); 490 unpremultiply_alpha, transform_matrix);
509 } 491 }
510 492
511 void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal( 493 void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal(
512 const gles2::GLES2Decoder* decoder, 494 const gles2::GLES2Decoder* decoder,
513 GLenum source_target, 495 GLenum source_target,
514 GLuint source_id, 496 GLuint source_id,
497 GLenum dest_target,
515 GLuint dest_id, 498 GLuint dest_id,
516 GLint xoffset, 499 GLint xoffset,
517 GLint yoffset, 500 GLint yoffset,
518 GLint x, 501 GLint x,
519 GLint y, 502 GLint y,
520 GLsizei width, 503 GLsizei width,
521 GLsizei height, 504 GLsizei height,
522 GLsizei dest_width, 505 GLsizei dest_width,
523 GLsizei dest_height, 506 GLsizei dest_height,
524 GLsizei source_width, 507 GLsizei source_width,
525 GLsizei source_height, 508 GLsizei source_height,
526 bool flip_y, 509 bool flip_y,
527 bool premultiply_alpha, 510 bool premultiply_alpha,
528 bool unpremultiply_alpha, 511 bool unpremultiply_alpha,
529 const GLfloat transform_matrix[16]) { 512 const GLfloat transform_matrix[16]) {
530 DCHECK(source_target == GL_TEXTURE_2D || 513 DCHECK(source_target == GL_TEXTURE_2D ||
531 source_target == GL_TEXTURE_RECTANGLE_ARB || 514 source_target == GL_TEXTURE_RECTANGLE_ARB ||
532 source_target == GL_TEXTURE_EXTERNAL_OES); 515 source_target == GL_TEXTURE_EXTERNAL_OES);
516 DCHECK(dest_target == GL_TEXTURE_2D ||
517 dest_target == GL_TEXTURE_RECTANGLE_ARB);
533 DCHECK_GE(xoffset, 0); 518 DCHECK_GE(xoffset, 0);
534 DCHECK_LE(xoffset + width, dest_width); 519 DCHECK_LE(xoffset + width, dest_width);
535 DCHECK_GE(yoffset, 0); 520 DCHECK_GE(yoffset, 0);
536 DCHECK_LE(yoffset + height, dest_height); 521 DCHECK_LE(yoffset + height, dest_height);
522 if (dest_width == 0 || dest_height == 0 || source_width == 0 ||
523 source_height == 0) {
524 return;
525 }
526
537 if (!initialized_) { 527 if (!initialized_) {
538 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; 528 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager.";
539 return; 529 return;
540 } 530 }
541 531
542 VertexShaderId vertex_shader_id = GetVertexShaderId(flip_y);
543 DCHECK_LT(static_cast<size_t>(vertex_shader_id), vertex_shaders_.size());
544 FragmentShaderId fragment_shader_id = GetFragmentShaderId( 532 FragmentShaderId fragment_shader_id = GetFragmentShaderId(
545 premultiply_alpha, unpremultiply_alpha, source_target); 533 premultiply_alpha, unpremultiply_alpha, source_target);
546 DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size()); 534 DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size());
547 535
548 ProgramMapKey key(vertex_shader_id, fragment_shader_id); 536 ProgramMapKey key(fragment_shader_id);
549 ProgramInfo* info = &programs_[key]; 537 ProgramInfo* info = &programs_[key];
550 // Create program if necessary. 538 // Create program if necessary.
551 if (!info->program) { 539 if (!info->program) {
552 info->program = glCreateProgram(); 540 info->program = glCreateProgram();
553 GLuint* vertex_shader = &vertex_shaders_[vertex_shader_id]; 541 if (!vertex_shader_) {
554 if (!*vertex_shader) { 542 vertex_shader_ = glCreateShader(GL_VERTEX_SHADER);
555 *vertex_shader = glCreateShader(GL_VERTEX_SHADER); 543 std::string source = GetVertexShaderSource();
556 std::string source = GetVertexShaderSource(flip_y); 544 CompileShader(vertex_shader_, source.c_str());
557 CompileShader(*vertex_shader, source.c_str());
558 } 545 }
559 glAttachShader(info->program, *vertex_shader); 546 glAttachShader(info->program, vertex_shader_);
560 GLuint* fragment_shader = &fragment_shaders_[fragment_shader_id]; 547 GLuint* fragment_shader = &fragment_shaders_[fragment_shader_id];
561 if (!*fragment_shader) { 548 if (!*fragment_shader) {
562 *fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); 549 *fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
563 std::string source = GetFragmentShaderSource( 550 std::string source = GetFragmentShaderSource(
564 premultiply_alpha, unpremultiply_alpha, source_target); 551 premultiply_alpha, unpremultiply_alpha, source_target);
565 CompileShader(*fragment_shader, source.c_str()); 552 CompileShader(*fragment_shader, source.c_str());
566 } 553 }
567 glAttachShader(info->program, *fragment_shader); 554 glAttachShader(info->program, *fragment_shader);
568 glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position"); 555 glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position");
569 glLinkProgram(info->program); 556 glLinkProgram(info->program);
570 #ifndef NDEBUG 557 #ifndef NDEBUG
571 GLint linked; 558 GLint linked;
572 glGetProgramiv(info->program, GL_LINK_STATUS, &linked); 559 glGetProgramiv(info->program, GL_LINK_STATUS, &linked);
573 if (!linked) 560 if (!linked)
574 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; 561 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure.";
575 #endif 562 #endif
576 info->vertex_translate_handle = glGetUniformLocation(info->program, 563 info->vertex_dest_mult_handle =
577 "u_vertex_translate"); 564 glGetUniformLocation(info->program, "u_vertex_dest_mult");
565 info->vertex_dest_add_handle =
566 glGetUniformLocation(info->program, "u_vertex_dest_add");
567 info->vertex_source_mult_handle =
568 glGetUniformLocation(info->program, "u_vertex_source_mult");
569 info->vertex_source_add_handle =
570 glGetUniformLocation(info->program, "u_vertex_source_add");
571
578 info->tex_coord_transform_handle = 572 info->tex_coord_transform_handle =
579 glGetUniformLocation(info->program, "u_tex_coord_transform"); 573 glGetUniformLocation(info->program, "u_tex_coord_transform");
580 info->half_size_handle = glGetUniformLocation(info->program, "u_half_size");
581 info->sampler_handle = glGetUniformLocation(info->program, "u_sampler"); 574 info->sampler_handle = glGetUniformLocation(info->program, "u_sampler");
582 } 575 }
583 glUseProgram(info->program); 576 glUseProgram(info->program);
584 577
585 glUniformMatrix4fv(info->tex_coord_transform_handle, 1, GL_FALSE, 578 glUniformMatrix4fv(info->tex_coord_transform_handle, 1, GL_FALSE,
586 transform_matrix); 579 transform_matrix);
587 580
588 GLint x_translate = xoffset - x; 581 // Note: For simplicity, the calculations in this comment block use a single
589 GLint y_translate = yoffset - y; 582 // dimension. All calculations trivially extend to the x-y plane.
590 if (!x_translate && !y_translate) { 583 // The target subrange in the destination texture has coordinates
591 glUniform2f(info->vertex_translate_handle, 0.0f, 0.0f); 584 // [xoffset, xoffset + width]. The full destination texture has range
592 } else { 585 // [0, dest_width].
593 // transform offsets from ([0, dest_width], [0, dest_height]) coord. 586 //
594 // to ([-1, 1], [-1, 1]) coord. 587 // We want to find A and B such that:
595 GLfloat x_translate_on_vertex = ((2.f * x_translate) / dest_width); 588 // A * X + B = Y
596 GLfloat y_translate_on_vertex = ((2.f * y_translate) / dest_height); 589 // C * Y + D = Z
590 //
591 // where X = [-1, 1], Z = [xoffset, xoffset + width]
592 // and C, D satisfy the relationship C * [-1, 1] + D = [0, dest_width].
593 //
594 // Math shows:
595 // C = D = dest_width / 2
596 // Y = [(xoffset * 2 / dest_width) - 1,
597 // (xoffset + width) * 2 / dest_width) - 1]
598 // A = width / dest_width
599 // B = (xoffset * 2 + width - dest_width) / dest_width
600 glUniform2f(info->vertex_dest_mult_handle, width * 1.f / dest_width,
601 height * 1.f / dest_height);
602 glUniform2f(info->vertex_dest_add_handle,
603 (xoffset * 2.f + width - dest_width) / dest_width,
604 (yoffset * 2.f + height - dest_height) / dest_height);
597 605
598 // Pass translation to the shader program. 606 // Note: For simplicity, the calculations in this comment block use a single
599 glUniform2f(info->vertex_translate_handle, x_translate_on_vertex, 607 // dimension. All calculations trivially extend to the x-y plane.
600 y_translate_on_vertex); 608 // The target subrange in the source texture has coordinates [x, x + width].
601 } 609 // The full source texture has range [0, source_width]. We need to transform
602 if (source_target == GL_TEXTURE_RECTANGLE_ARB) 610 // the subrange into texture space ([0, M]), assuming that [0, source_width]
603 glUniform2f(info->half_size_handle, source_width / 2.0f, 611 // gets mapped to [0, M]. If source_target == GL_TEXTURE_RECTANGLE_ARB, M =
604 source_height / 2.0f); 612 // source_width. Otherwise, M = 1.
605 else 613 //
606 glUniform2f(info->half_size_handle, 0.5f, 0.5f); 614 // We want to find A and B such that:
615 // A * X + B = Y
616 // C * Y + D = Z
617 //
618 // where X = [-1, 1], Z = [x, x + width]
619 // and C, D satisfy the relationship C * [0, M] + D = [0, source_width].
620 //
621 // Math shows:
622 // D = 0
623 // C = source_width / M
624 // Y = [x * M / source_width, (x + width) * M / source_width]
625 // B = (x + w/2) * M / source_width
626 // A = (w/2) * M / source_width
627 //
628 // When flip_y is true, we run the same calcluation, but with Z = [x + width,
629 // x]. (I'm intentionally keeping the x-plane notation, although the
630 // calculation only gets applied to the y-plane).
631 //
632 // Math shows:
633 // D = 0
634 // C = source_width / M
635 // Y = [(x + width) * M / source_width, x * M / source_width]
636 // B = (x + w/2) * M / source_width
637 // A = (-w/2) * M / source_width
638 //
639 // So everything is the same but the sign of A is flipped.
640 GLfloat m_x = source_target == GL_TEXTURE_RECTANGLE_ARB ? source_width : 1;
641 GLfloat m_y = source_target == GL_TEXTURE_RECTANGLE_ARB ? source_height : 1;
642 GLfloat sign_a = flip_y ? -1 : 1;
643 glUniform2f(info->vertex_source_mult_handle, width / 2.f * m_x / source_width,
644 height / 2.f * m_y / source_height * sign_a);
645 glUniform2f(info->vertex_source_add_handle,
646 (x + width / 2.f) * m_x / source_width,
647 (y + height / 2.f) * m_y / source_height);
607 648
608 if (BindFramebufferTexture2D(GL_TEXTURE_2D, dest_id, framebuffer_)) { 649 if (BindFramebufferTexture2D(dest_target, dest_id, framebuffer_)) {
609 #ifndef NDEBUG 650 #ifndef NDEBUG
610 // glValidateProgram of MACOSX validates FBO unlike other platforms, so 651 // glValidateProgram of MACOSX validates FBO unlike other platforms, so
611 // glValidateProgram must be called after FBO binding. crbug.com/463439 652 // glValidateProgram must be called after FBO binding. crbug.com/463439
612 glValidateProgram(info->program); 653 glValidateProgram(info->program);
613 GLint validation_status; 654 GLint validation_status;
614 glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status); 655 glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status);
615 if (GL_TRUE != validation_status) { 656 if (GL_TRUE != validation_status) {
616 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; 657 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader.";
617 return; 658 return;
618 } 659 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 decoder->RestoreTextureState(dest_id); 700 decoder->RestoreTextureState(dest_id);
660 decoder->RestoreTextureUnitBindings(0); 701 decoder->RestoreTextureUnitBindings(0);
661 decoder->RestoreActiveTexture(); 702 decoder->RestoreActiveTexture();
662 decoder->RestoreProgramBindings(); 703 decoder->RestoreProgramBindings();
663 decoder->RestoreBufferBindings(); 704 decoder->RestoreBufferBindings();
664 decoder->RestoreFramebufferBindings(); 705 decoder->RestoreFramebufferBindings();
665 decoder->RestoreGlobalState(); 706 decoder->RestoreGlobalState();
666 } 707 }
667 708
668 } // namespace gpu 709 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698