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

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: Comments from zmo. 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);
Zhenyao Mo 2016/01/05 00:52:16 Can we also pass in dest_target and DCHECK it's TE
erikchen 2016/01/05 01:46:39 Done.
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,
315 GLuint dest_id, 291 GLuint dest_id,
Zhenyao Mo 2016/01/05 00:52:16 Same here, can we also pass in dest_target and DCH
erikchen 2016/01/05 01:46:39 Done.
316 GLint xoffset, 292 GLint xoffset,
317 GLint yoffset, 293 GLint yoffset,
318 GLint source_x, 294 GLint source_x,
319 GLint source_y, 295 GLint source_y,
320 GLsizei source_width, 296 GLsizei source_width,
321 GLsizei source_height, 297 GLsizei source_height,
322 GLuint framebuffer) { 298 GLuint framebuffer) {
323 DCHECK(source_target == GL_TEXTURE_2D || 299 DCHECK(source_target == GL_TEXTURE_2D ||
324 source_target == GL_TEXTURE_RECTANGLE_ARB); 300 source_target == GL_TEXTURE_RECTANGLE_ARB);
325 if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) { 301 if (BindFramebufferTexture2D(source_target, source_id, framebuffer)) {
(...skipping 12 matching lines...) Expand all
338 decoder->RestoreActiveTexture(); 314 decoder->RestoreActiveTexture();
339 decoder->RestoreFramebufferBindings(); 315 decoder->RestoreFramebufferBindings();
340 } 316 }
341 317
342 } // namespace 318 } // namespace
343 319
344 namespace gpu { 320 namespace gpu {
345 321
346 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() 322 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager()
347 : initialized_(false), 323 : initialized_(false),
348 vertex_shaders_(NUM_VERTEX_SHADERS, 0u), 324 vertex_shader_(0u),
349 fragment_shaders_(NUM_FRAGMENT_SHADERS, 0u), 325 fragment_shaders_(NUM_FRAGMENT_SHADERS, 0u),
350 buffer_id_(0u), 326 buffer_id_(0u),
351 framebuffer_(0u) {} 327 framebuffer_(0u) {}
352 328
353 CopyTextureCHROMIUMResourceManager::~CopyTextureCHROMIUMResourceManager() { 329 CopyTextureCHROMIUMResourceManager::~CopyTextureCHROMIUMResourceManager() {
354 // |buffer_id_| and |framebuffer_| can be not-null because when GPU context is 330 // |buffer_id_| and |framebuffer_| can be not-null because when GPU context is
355 // lost, this class can be deleted without releasing resources like 331 // lost, this class can be deleted without releasing resources like
356 // GLES2DecoderImpl. 332 // GLES2DecoderImpl.
357 } 333 }
358 334
(...skipping 23 matching lines...) Expand all
382 initialized_ = true; 358 initialized_ = true;
383 } 359 }
384 360
385 void CopyTextureCHROMIUMResourceManager::Destroy() { 361 void CopyTextureCHROMIUMResourceManager::Destroy() {
386 if (!initialized_) 362 if (!initialized_)
387 return; 363 return;
388 364
389 glDeleteFramebuffersEXT(1, &framebuffer_); 365 glDeleteFramebuffersEXT(1, &framebuffer_);
390 framebuffer_ = 0; 366 framebuffer_ = 0;
391 367
392 std::for_each(vertex_shaders_.begin(), vertex_shaders_.end(), DeleteShader); 368 DeleteShader(vertex_shader_);
393 std::for_each( 369 std::for_each(
394 fragment_shaders_.begin(), fragment_shaders_.end(), DeleteShader); 370 fragment_shaders_.begin(), fragment_shaders_.end(), DeleteShader);
395 371
396 for (ProgramMap::const_iterator it = programs_.begin(); it != programs_.end(); 372 for (ProgramMap::const_iterator it = programs_.begin(); it != programs_.end();
397 ++it) { 373 ++it) {
398 const ProgramInfo& info = it->second; 374 const ProgramInfo& info = it->second;
399 glDeleteProgram(info.program); 375 glDeleteProgram(info.program);
400 } 376 }
401 377
402 glDeleteBuffersARB(1, &buffer_id_); 378 glDeleteBuffersARB(1, &buffer_id_);
403 buffer_id_ = 0; 379 buffer_id_ = 0;
404 } 380 }
405 381
406 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( 382 void CopyTextureCHROMIUMResourceManager::DoCopyTexture(
407 const gles2::GLES2Decoder* decoder, 383 const gles2::GLES2Decoder* decoder,
408 GLenum source_target, 384 GLenum source_target,
409 GLuint source_id, 385 GLuint source_id,
410 GLenum source_internal_format, 386 GLenum source_internal_format,
387 GLenum dest_target,
411 GLuint dest_id, 388 GLuint dest_id,
412 GLenum dest_internal_format, 389 GLenum dest_internal_format,
413 GLsizei width, 390 GLsizei width,
414 GLsizei height, 391 GLsizei height,
415 bool flip_y, 392 bool flip_y,
416 bool premultiply_alpha, 393 bool premultiply_alpha,
417 bool unpremultiply_alpha) { 394 bool unpremultiply_alpha) {
418 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; 395 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha;
419 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's 396 // 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 397 // format does not contain a superset of the components required by the base
421 // format of internalformat. 398 // format of internalformat.
422 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml 399 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml
423 bool source_format_contain_superset_of_dest_format = 400 bool source_format_contain_superset_of_dest_format =
424 (source_internal_format == dest_internal_format && 401 (source_internal_format == dest_internal_format &&
425 source_internal_format != GL_BGRA_EXT) || 402 source_internal_format != GL_BGRA_EXT) ||
426 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); 403 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB);
427 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, 404 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2,
428 // so restrict this to GL_TEXTURE_2D. 405 // so restrict this to GL_TEXTURE_2D.
429 if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && 406 if (source_target == GL_TEXTURE_2D && dest_target == GL_TEXTURE_2D &&
407 !flip_y && !premultiply_alpha_change &&
430 source_format_contain_superset_of_dest_format) { 408 source_format_contain_superset_of_dest_format) {
431 DoCopyTexImage2D(decoder, 409 DoCopyTexImage2D(decoder,
432 source_target, 410 source_target,
433 source_id, 411 source_id,
434 dest_id, 412 dest_id,
435 dest_internal_format, 413 dest_internal_format,
436 width, 414 width,
437 height, 415 height,
438 framebuffer_); 416 framebuffer_);
439 return; 417 return;
440 } 418 }
441 419
442 // Use kIdentityMatrix if no transform passed in. 420 // Use kIdentityMatrix if no transform passed in.
443 DoCopyTextureWithTransform(decoder, source_target, source_id, dest_id, width, 421 DoCopyTextureWithTransform(decoder, source_target, source_id, dest_target,
444 height, flip_y, premultiply_alpha, 422 dest_id, width, height, flip_y, premultiply_alpha,
445 unpremultiply_alpha, kIdentityMatrix); 423 unpremultiply_alpha, kIdentityMatrix);
446 } 424 }
447 425
448 void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( 426 void CopyTextureCHROMIUMResourceManager::DoCopySubTexture(
449 const gles2::GLES2Decoder* decoder, 427 const gles2::GLES2Decoder* decoder,
450 GLenum source_target, 428 GLenum source_target,
451 GLuint source_id, 429 GLuint source_id,
452 GLenum source_internal_format, 430 GLenum source_internal_format,
431 GLenum dest_target,
453 GLuint dest_id, 432 GLuint dest_id,
454 GLenum dest_internal_format, 433 GLenum dest_internal_format,
455 GLint xoffset, 434 GLint xoffset,
456 GLint yoffset, 435 GLint yoffset,
457 GLint x, 436 GLint x,
458 GLint y, 437 GLint y,
459 GLsizei width, 438 GLsizei width,
460 GLsizei height, 439 GLsizei height,
461 GLsizei dest_width, 440 GLsizei dest_width,
462 GLsizei dest_height, 441 GLsizei dest_height,
463 GLsizei source_width, 442 GLsizei source_width,
464 GLsizei source_height, 443 GLsizei source_height,
465 bool flip_y, 444 bool flip_y,
466 bool premultiply_alpha, 445 bool premultiply_alpha,
467 bool unpremultiply_alpha) { 446 bool unpremultiply_alpha) {
468 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; 447 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha;
469 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's 448 // 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 449 // format does not contain a superset of the components required by the base
471 // format of internalformat. 450 // format of internalformat.
472 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml 451 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml
473 bool source_format_contain_superset_of_dest_format = 452 bool source_format_contain_superset_of_dest_format =
474 (source_internal_format == dest_internal_format && 453 (source_internal_format == dest_internal_format &&
475 source_internal_format != GL_BGRA_EXT) || 454 source_internal_format != GL_BGRA_EXT) ||
476 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); 455 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB);
477 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, 456 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2,
478 // so restrict this to GL_TEXTURE_2D. 457 // so restrict this to GL_TEXTURE_2D.
479 if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && 458 if (source_target == GL_TEXTURE_2D && dest_target == GL_TEXTURE_2D &&
459 !flip_y && !premultiply_alpha_change &&
480 source_format_contain_superset_of_dest_format) { 460 source_format_contain_superset_of_dest_format) {
481 DoCopyTexSubImage2D(decoder, source_target, source_id, dest_id, xoffset, 461 DoCopyTexSubImage2D(decoder, source_target, source_id, dest_id, xoffset,
482 yoffset, x, y, width, height, framebuffer_); 462 yoffset, x, y, width, height, framebuffer_);
483 return; 463 return;
484 } 464 }
485 465
486 DoCopyTextureInternal(decoder, source_target, source_id, dest_id, xoffset, 466 DoCopyTextureInternal(decoder, source_target, source_id, dest_target, dest_id,
487 yoffset, x, y, width, height, dest_width, dest_height, 467 xoffset, yoffset, x, y, width, height, dest_width, dest_height,
488 source_width, source_height, flip_y, premultiply_alpha, 468 source_width, source_height, flip_y, premultiply_alpha,
489 unpremultiply_alpha, kIdentityMatrix); 469 unpremultiply_alpha, kIdentityMatrix);
490 } 470 }
491 471
492 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( 472 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
493 const gles2::GLES2Decoder* decoder, 473 const gles2::GLES2Decoder* decoder,
494 GLenum source_target, 474 GLenum source_target,
495 GLuint source_id, 475 GLuint source_id,
476 GLenum dest_target,
496 GLuint dest_id, 477 GLuint dest_id,
497 GLsizei width, 478 GLsizei width,
498 GLsizei height, 479 GLsizei height,
499 bool flip_y, 480 bool flip_y,
500 bool premultiply_alpha, 481 bool premultiply_alpha,
501 bool unpremultiply_alpha, 482 bool unpremultiply_alpha,
502 const GLfloat transform_matrix[16]) { 483 const GLfloat transform_matrix[16]) {
503 GLsizei dest_width = width; 484 GLsizei dest_width = width;
504 GLsizei dest_height = height; 485 GLsizei dest_height = height;
505 DoCopyTextureInternal(decoder, source_target, source_id, dest_id, 0, 0, 0, 0, 486 DoCopyTextureInternal(decoder, source_target, source_id, dest_target, dest_id,
506 width, height, dest_width, dest_height, width, height, 487 0, 0, 0, 0, width, height, dest_width, dest_height,
507 flip_y, premultiply_alpha, unpremultiply_alpha, 488 width, height, flip_y, premultiply_alpha,
508 transform_matrix); 489 unpremultiply_alpha, transform_matrix);
509 } 490 }
510 491
511 void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal( 492 void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal(
512 const gles2::GLES2Decoder* decoder, 493 const gles2::GLES2Decoder* decoder,
513 GLenum source_target, 494 GLenum source_target,
514 GLuint source_id, 495 GLuint source_id,
496 GLenum dest_target,
515 GLuint dest_id, 497 GLuint dest_id,
516 GLint xoffset, 498 GLint xoffset,
517 GLint yoffset, 499 GLint yoffset,
518 GLint x, 500 GLint x,
519 GLint y, 501 GLint y,
520 GLsizei width, 502 GLsizei width,
521 GLsizei height, 503 GLsizei height,
522 GLsizei dest_width, 504 GLsizei dest_width,
523 GLsizei dest_height, 505 GLsizei dest_height,
524 GLsizei source_width, 506 GLsizei source_width,
525 GLsizei source_height, 507 GLsizei source_height,
526 bool flip_y, 508 bool flip_y,
527 bool premultiply_alpha, 509 bool premultiply_alpha,
528 bool unpremultiply_alpha, 510 bool unpremultiply_alpha,
529 const GLfloat transform_matrix[16]) { 511 const GLfloat transform_matrix[16]) {
530 DCHECK(source_target == GL_TEXTURE_2D || 512 DCHECK(source_target == GL_TEXTURE_2D ||
531 source_target == GL_TEXTURE_RECTANGLE_ARB || 513 source_target == GL_TEXTURE_RECTANGLE_ARB ||
532 source_target == GL_TEXTURE_EXTERNAL_OES); 514 source_target == GL_TEXTURE_EXTERNAL_OES);
515 DCHECK(dest_target == GL_TEXTURE_2D ||
516 dest_target == GL_TEXTURE_RECTANGLE_ARB);
533 DCHECK_GE(xoffset, 0); 517 DCHECK_GE(xoffset, 0);
534 DCHECK_LE(xoffset + width, dest_width); 518 DCHECK_LE(xoffset + width, dest_width);
535 DCHECK_GE(yoffset, 0); 519 DCHECK_GE(yoffset, 0);
536 DCHECK_LE(yoffset + height, dest_height); 520 DCHECK_LE(yoffset + height, dest_height);
521 if (dest_width == 0 || dest_height == 0 || source_width == 0 ||
522 source_height == 0) {
523 return;
524 }
525
537 if (!initialized_) { 526 if (!initialized_) {
538 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; 527 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager.";
539 return; 528 return;
540 } 529 }
541 530
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( 531 FragmentShaderId fragment_shader_id = GetFragmentShaderId(
545 premultiply_alpha, unpremultiply_alpha, source_target); 532 premultiply_alpha, unpremultiply_alpha, source_target);
546 DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size()); 533 DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size());
547 534
548 ProgramMapKey key(vertex_shader_id, fragment_shader_id); 535 ProgramMapKey key(fragment_shader_id);
549 ProgramInfo* info = &programs_[key]; 536 ProgramInfo* info = &programs_[key];
550 // Create program if necessary. 537 // Create program if necessary.
551 if (!info->program) { 538 if (!info->program) {
552 info->program = glCreateProgram(); 539 info->program = glCreateProgram();
553 GLuint* vertex_shader = &vertex_shaders_[vertex_shader_id]; 540 if (!vertex_shader_) {
554 if (!*vertex_shader) { 541 vertex_shader_ = glCreateShader(GL_VERTEX_SHADER);
555 *vertex_shader = glCreateShader(GL_VERTEX_SHADER); 542 std::string source = GetVertexShaderSource();
556 std::string source = GetVertexShaderSource(flip_y); 543 CompileShader(vertex_shader_, source.c_str());
557 CompileShader(*vertex_shader, source.c_str());
558 } 544 }
559 glAttachShader(info->program, *vertex_shader); 545 glAttachShader(info->program, vertex_shader_);
560 GLuint* fragment_shader = &fragment_shaders_[fragment_shader_id]; 546 GLuint* fragment_shader = &fragment_shaders_[fragment_shader_id];
561 if (!*fragment_shader) { 547 if (!*fragment_shader) {
562 *fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); 548 *fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
563 std::string source = GetFragmentShaderSource( 549 std::string source = GetFragmentShaderSource(
564 premultiply_alpha, unpremultiply_alpha, source_target); 550 premultiply_alpha, unpremultiply_alpha, source_target);
565 CompileShader(*fragment_shader, source.c_str()); 551 CompileShader(*fragment_shader, source.c_str());
566 } 552 }
567 glAttachShader(info->program, *fragment_shader); 553 glAttachShader(info->program, *fragment_shader);
568 glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position"); 554 glBindAttribLocation(info->program, kVertexPositionAttrib, "a_position");
569 glLinkProgram(info->program); 555 glLinkProgram(info->program);
570 #ifndef NDEBUG 556 #ifndef NDEBUG
571 GLint linked; 557 GLint linked;
572 glGetProgramiv(info->program, GL_LINK_STATUS, &linked); 558 glGetProgramiv(info->program, GL_LINK_STATUS, &linked);
573 if (!linked) 559 if (!linked)
574 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; 560 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure.";
575 #endif 561 #endif
576 info->vertex_translate_handle = glGetUniformLocation(info->program, 562 info->vertex_dest_mult_handle =
577 "u_vertex_translate"); 563 glGetUniformLocation(info->program, "u_vertex_dest_mult");
564 info->vertex_dest_add_handle =
565 glGetUniformLocation(info->program, "u_vertex_dest_add");
566 info->vertex_source_mult_handle =
567 glGetUniformLocation(info->program, "u_vertex_source_mult");
568 info->vertex_source_add_handle =
569 glGetUniformLocation(info->program, "u_vertex_source_add");
570
578 info->tex_coord_transform_handle = 571 info->tex_coord_transform_handle =
579 glGetUniformLocation(info->program, "u_tex_coord_transform"); 572 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"); 573 info->sampler_handle = glGetUniformLocation(info->program, "u_sampler");
582 } 574 }
583 glUseProgram(info->program); 575 glUseProgram(info->program);
584 576
585 glUniformMatrix4fv(info->tex_coord_transform_handle, 1, GL_FALSE, 577 glUniformMatrix4fv(info->tex_coord_transform_handle, 1, GL_FALSE,
586 transform_matrix); 578 transform_matrix);
587 579
588 GLint x_translate = xoffset - x; 580 // Note: For simplicity, the calculations in this comment block use a single
589 GLint y_translate = yoffset - y; 581 // dimension. All calculations trivially extend to the x-y plane.
590 if (!x_translate && !y_translate) { 582 // The target subrange in the destination texture has coordinates
591 glUniform2f(info->vertex_translate_handle, 0.0f, 0.0f); 583 // [xoffset, xoffset + width]. The full destination texture has range
592 } else { 584 // [0, dest_width].
593 // transform offsets from ([0, dest_width], [0, dest_height]) coord. 585 //
594 // to ([-1, 1], [-1, 1]) coord. 586 // We want to find A and B such that:
595 GLfloat x_translate_on_vertex = ((2.f * x_translate) / dest_width); 587 // A * X + B = Y
596 GLfloat y_translate_on_vertex = ((2.f * y_translate) / dest_height); 588 // C * Y + D = Z
589 //
590 // where X = [-1, 1], Z = [xoffset, xoffset + width]
591 // and C, D satisfy the relationship C * [-1, 1] + D = [0, dest_width].
592 //
593 // Math shows:
594 // C = D = dest_width / 2
595 // Y = [(xoffset * 2 / dest_width) - 1,
596 // (xoffset + width) * 2 / dest_width) - 1]
597 // A = width / dest_width
598 // B = (xoffset * 2 + width - dest_width) / dest_width
599 glUniform2f(info->vertex_dest_mult_handle, width * 1.f / dest_width,
600 height * 1.f / dest_height);
601 glUniform2f(info->vertex_dest_add_handle,
602 (xoffset * 2.f + width - dest_width) / dest_width,
603 (yoffset * 2.f + height - dest_height) / dest_height);
597 604
598 // Pass translation to the shader program. 605 // Note: For simplicity, the calculations in this comment block use a single
599 glUniform2f(info->vertex_translate_handle, x_translate_on_vertex, 606 // dimension. All calculations trivially extend to the x-y plane.
600 y_translate_on_vertex); 607 // The target subrange in the source texture has coordinates [x, x + width].
601 } 608 // The full source texture has range [0, source_width]. We need to transform
602 if (source_target == GL_TEXTURE_RECTANGLE_ARB) 609 // the subrange into texture space ([0, M]), assuming that [0, source_width]
603 glUniform2f(info->half_size_handle, source_width / 2.0f, 610 // gets mapped to [0, M]. If source_target == GL_TEXTURE_RECTANGLE_ARB, M =
604 source_height / 2.0f); 611 // source_width. Otherwise, M = 1.
605 else 612 //
606 glUniform2f(info->half_size_handle, 0.5f, 0.5f); 613 // We want to find A and B such that:
614 // A * X + B = Y
615 // C * Y + D = Z
616 //
617 // where X = [-1, 1], Z = [x, x + width]
618 // and C, D satisfy the relationship C * [0, M] + D = [0, source_width].
619 //
620 // Math shows:
621 // D = 0
622 // C = source_width / M
623 // Y = [x * M / source_width, (x + width) * M / source_width]
624 // B = (x + w/2) * M / source_width
625 // A = (w/2) * M / source_width
626 //
627 // When flip_y is true, we run the same calcluation, but with Z = [x + width,
628 // x]. (I'm intentionally keeping the x-plane notation, although the
629 // calculation only gets applied to the y-plane).
630 //
631 // Math shows:
632 // D = 0
633 // C = source_width / M
634 // Y = [(x + width) * M / source_width, x * M / source_width]
635 // B = (x + w/2) * M / source_width
636 // A = (-w/2) * M / source_width
637 //
638 // So everything is the same but the sign of A is flipped.
639 GLfloat m_x = source_target == GL_TEXTURE_RECTANGLE_ARB ? source_width : 1;
640 GLfloat m_y = source_target == GL_TEXTURE_RECTANGLE_ARB ? source_height : 1;
641 GLfloat sign_a = flip_y ? -1 : 1;
642 glUniform2f(info->vertex_source_mult_handle, width / 2.f * m_x / source_width,
643 height / 2.f * m_y / source_height * sign_a);
644 glUniform2f(info->vertex_source_add_handle,
645 (x + width / 2.f) * m_x / source_width,
646 (y + height / 2.f) * m_y / source_height);
607 647
608 if (BindFramebufferTexture2D(GL_TEXTURE_2D, dest_id, framebuffer_)) { 648 if (BindFramebufferTexture2D(dest_target, dest_id, framebuffer_)) {
609 #ifndef NDEBUG 649 #ifndef NDEBUG
610 // glValidateProgram of MACOSX validates FBO unlike other platforms, so 650 // glValidateProgram of MACOSX validates FBO unlike other platforms, so
611 // glValidateProgram must be called after FBO binding. crbug.com/463439 651 // glValidateProgram must be called after FBO binding. crbug.com/463439
612 glValidateProgram(info->program); 652 glValidateProgram(info->program);
613 GLint validation_status; 653 GLint validation_status;
614 glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status); 654 glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status);
615 if (GL_TRUE != validation_status) { 655 if (GL_TRUE != validation_status) {
616 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; 656 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader.";
617 return; 657 return;
618 } 658 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 decoder->RestoreTextureState(dest_id); 699 decoder->RestoreTextureState(dest_id);
660 decoder->RestoreTextureUnitBindings(0); 700 decoder->RestoreTextureUnitBindings(0);
661 decoder->RestoreActiveTexture(); 701 decoder->RestoreActiveTexture();
662 decoder->RestoreProgramBindings(); 702 decoder->RestoreProgramBindings();
663 decoder->RestoreBufferBindings(); 703 decoder->RestoreBufferBindings();
664 decoder->RestoreFramebufferBindings(); 704 decoder->RestoreFramebufferBindings();
665 decoder->RestoreGlobalState(); 705 decoder->RestoreGlobalState();
666 } 706 }
667 707
668 } // namespace gpu 708 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698