OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "gpu/command_buffer/service/gl_utils.h" | 10 #include "gpu/command_buffer/service/gl_utils.h" |
(...skipping 14 matching lines...) Expand all Loading... | |
25 "#define TextureLookup texture2DRect\n" SHADER(src) | 25 "#define TextureLookup texture2DRect\n" SHADER(src) |
26 #define SHADER_EXTERNAL_OES(src) \ | 26 #define SHADER_EXTERNAL_OES(src) \ |
27 "#extension GL_OES_EGL_image_external : require\n" \ | 27 "#extension GL_OES_EGL_image_external : require\n" \ |
28 "#define SamplerType samplerExternalOES\n" \ | 28 "#define SamplerType samplerExternalOES\n" \ |
29 "#define TextureLookup texture2D\n" SHADER(src) | 29 "#define TextureLookup texture2D\n" SHADER(src) |
30 #define FRAGMENT_SHADERS(src) \ | 30 #define FRAGMENT_SHADERS(src) \ |
31 SHADER_2D(src), SHADER_RECTANGLE_ARB(src), SHADER_EXTERNAL_OES(src) | 31 SHADER_2D(src), SHADER_RECTANGLE_ARB(src), SHADER_EXTERNAL_OES(src) |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
35 GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, | |
Ken Russell (switch to Gerrit)
2015/01/24 01:33:24
This should be const.
dshwang
2015/02/10 18:11:55
Done.
| |
36 0.0f, 1.0f, 0.0f, 0.0f, | |
37 0.0f, 0.0f, 1.0f, 0.0f, | |
38 0.0f, 0.0f, 0.0f, 1.0f}; | |
39 | |
35 enum VertexShaderId { | 40 enum VertexShaderId { |
36 VERTEX_SHADER_COPY_TEXTURE, | 41 VERTEX_SHADER_COPY_TEXTURE, |
37 VERTEX_SHADER_COPY_TEXTURE_FLIP_Y, | 42 VERTEX_SHADER_COPY_TEXTURE_FLIP_Y, |
38 NUM_VERTEX_SHADERS, | 43 NUM_VERTEX_SHADERS, |
39 }; | 44 }; |
40 | 45 |
41 enum FragmentShaderId { | 46 enum FragmentShaderId { |
42 FRAGMENT_SHADER_COPY_TEXTURE_2D, | 47 FRAGMENT_SHADER_COPY_TEXTURE_2D, |
43 FRAGMENT_SHADER_COPY_TEXTURE_RECTANGLE_ARB, | 48 FRAGMENT_SHADER_COPY_TEXTURE_RECTANGLE_ARB, |
44 FRAGMENT_SHADER_COPY_TEXTURE_EXTERNAL_OES, | 49 FRAGMENT_SHADER_COPY_TEXTURE_EXTERNAL_OES, |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
241 0 /* border */); | 246 0 /* border */); |
242 } | 247 } |
243 | 248 |
244 decoder->RestoreTextureState(source_id); | 249 decoder->RestoreTextureState(source_id); |
245 decoder->RestoreTextureState(dest_id); | 250 decoder->RestoreTextureState(dest_id); |
246 decoder->RestoreTextureUnitBindings(0); | 251 decoder->RestoreTextureUnitBindings(0); |
247 decoder->RestoreActiveTexture(); | 252 decoder->RestoreActiveTexture(); |
248 decoder->RestoreFramebufferBindings(); | 253 decoder->RestoreFramebufferBindings(); |
249 } | 254 } |
250 | 255 |
256 void DoCopyTexSubImage2D(const gpu::gles2::GLES2Decoder* decoder, | |
257 GLenum source_target, | |
258 GLuint source_id, | |
259 GLuint dest_id, | |
260 GLint dest_level, | |
261 GLint xoffset, | |
262 GLint yoffset, | |
263 GLsizei source_width, | |
264 GLsizei source_height, | |
265 GLuint framebuffer) { | |
266 DCHECK(source_target == GL_TEXTURE_2D || | |
267 source_target == GL_TEXTURE_RECTANGLE_ARB); | |
268 if (BindFramebufferTexture2D(source_target, source_id, 0 /* level */, | |
269 framebuffer)) { | |
270 glBindTexture(GL_TEXTURE_2D, dest_id); | |
271 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
272 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
273 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
274 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
275 glCopyTexSubImage2D(GL_TEXTURE_2D, dest_level, xoffset, yoffset, 0 /* x */, | |
276 0 /* y */, source_width, source_height); | |
277 } | |
278 | |
279 decoder->RestoreTextureState(source_id); | |
280 decoder->RestoreTextureState(dest_id); | |
281 decoder->RestoreTextureUnitBindings(0); | |
282 decoder->RestoreActiveTexture(); | |
283 decoder->RestoreFramebufferBindings(); | |
284 } | |
285 | |
286 // Copy from SkMatrix44::preTranslate | |
287 void PreTranslate(GLfloat* matrix, GLfloat dx, GLfloat dy, GLfloat dz) { | |
288 if (!dx && !dy && !dz) | |
289 return; | |
290 | |
291 for (int i = 0; i < 4; ++i) { | |
292 matrix[(3 * 4) + i] = matrix[(0 * 4) + i] * dx + matrix[(1 * 4) + i] * dy + | |
293 matrix[(2 * 4) + i] * dz + matrix[(3 * 4) + i]; | |
294 } | |
295 } | |
296 | |
251 } // namespace | 297 } // namespace |
252 | 298 |
253 namespace gpu { | 299 namespace gpu { |
254 | 300 |
255 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() | 301 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() |
256 : initialized_(false), | 302 : initialized_(false), |
257 vertex_shaders_(NUM_VERTEX_SHADERS, 0u), | 303 vertex_shaders_(NUM_VERTEX_SHADERS, 0u), |
258 fragment_shaders_(NUM_FRAGMENT_SHADERS, 0u), | 304 fragment_shaders_(NUM_FRAGMENT_SHADERS, 0u), |
259 buffer_id_(0u), | 305 buffer_id_(0u), |
260 framebuffer_(0u) {} | 306 framebuffer_(0u) {} |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
343 source_id, | 389 source_id, |
344 dest_id, | 390 dest_id, |
345 dest_level, | 391 dest_level, |
346 dest_internal_format, | 392 dest_internal_format, |
347 width, | 393 width, |
348 height, | 394 height, |
349 framebuffer_); | 395 framebuffer_); |
350 return; | 396 return; |
351 } | 397 } |
352 | 398 |
353 // Use default transform matrix if no transform passed in. | 399 // Use kIdentityMatrix if no transform passed in. |
354 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, | 400 DoCopyTextureWithTransform( |
355 0.0f, 1.0f, 0.0f, 0.0f, | 401 decoder, source_target, source_id, dest_id, dest_level, width, height, |
356 0.0f, 0.0f, 1.0f, 0.0f, | 402 flip_y, premultiply_alpha, unpremultiply_alpha, kIdentityMatrix); |
357 0.0f, 0.0f, 0.0f, 1.0f}; | 403 } |
358 DoCopyTextureWithTransform(decoder, | 404 |
359 source_target, | 405 void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( |
360 source_id, | 406 const gles2::GLES2Decoder* decoder, |
361 dest_id, | 407 GLenum source_target, |
362 dest_level, | 408 GLuint source_id, |
363 width, | 409 GLenum source_internal_format, |
364 height, | 410 GLuint dest_id, |
365 flip_y, | 411 GLint dest_level, |
366 premultiply_alpha, | 412 GLenum dest_internal_format, |
367 unpremultiply_alpha, | 413 GLint xoffset, |
368 default_matrix); | 414 GLint yoffset, |
415 GLsizei dest_width, | |
416 GLsizei dest_height, | |
417 GLsizei source_width, | |
418 GLsizei source_height, | |
419 bool flip_y, | |
420 bool premultiply_alpha, | |
421 bool unpremultiply_alpha) { | |
422 bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha; | |
423 // GL_INVALID_OPERATION is generated if the currently bound framebuffer's | |
424 // format does not contain a superset of the components required by the base | |
425 // format of internalformat. | |
426 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml | |
427 bool source_format_contain_superset_of_dest_format = | |
428 (source_internal_format == dest_internal_format && | |
429 source_internal_format != GL_BGRA_EXT) || | |
430 (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB); | |
431 // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2, | |
432 // so restrict this to GL_TEXTURE_2D. | |
433 if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change && | |
434 source_format_contain_superset_of_dest_format) { | |
435 DoCopyTexSubImage2D(decoder, source_target, source_id, dest_id, dest_level, | |
436 xoffset, yoffset, source_width, source_height, | |
437 framebuffer_); | |
438 return; | |
439 } | |
440 | |
441 // Use kIdentityMatrix if no transform passed in. | |
442 DoCopySubTextureWithTransform( | |
443 decoder, source_target, source_id, dest_id, dest_level, xoffset, yoffset, | |
444 dest_width, dest_height, source_width, source_height, flip_y, | |
445 premultiply_alpha, unpremultiply_alpha, kIdentityMatrix); | |
369 } | 446 } |
370 | 447 |
371 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( | 448 void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform( |
372 const gles2::GLES2Decoder* decoder, | 449 const gles2::GLES2Decoder* decoder, |
373 GLenum source_target, | 450 GLenum source_target, |
374 GLuint source_id, | 451 GLuint source_id, |
375 GLuint dest_id, | 452 GLuint dest_id, |
376 GLint dest_level, | 453 GLint dest_level, |
377 GLsizei width, | 454 GLsizei width, |
378 GLsizei height, | 455 GLsizei height, |
379 bool flip_y, | 456 bool flip_y, |
380 bool premultiply_alpha, | 457 bool premultiply_alpha, |
381 bool unpremultiply_alpha, | 458 bool unpremultiply_alpha, |
382 const GLfloat transform_matrix[16]) { | 459 const GLfloat transform_matrix[16]) { |
460 GLsizei dest_width = width; | |
461 GLsizei dest_height = height; | |
462 DoCopyTextureInternal(decoder, source_target, source_id, dest_id, dest_level, | |
463 0, 0, dest_width, dest_height, width, height, flip_y, | |
464 premultiply_alpha, unpremultiply_alpha, | |
465 transform_matrix); | |
466 } | |
467 | |
468 void CopyTextureCHROMIUMResourceManager::DoCopySubTextureWithTransform( | |
469 const gles2::GLES2Decoder* decoder, | |
470 GLenum source_target, | |
471 GLuint source_id, | |
472 GLuint dest_id, | |
473 GLint dest_level, | |
474 GLint xoffset, | |
475 GLint yoffset, | |
476 GLsizei dest_width, | |
477 GLsizei dest_height, | |
478 GLsizei source_width, | |
479 GLsizei source_height, | |
480 bool flip_y, | |
481 bool premultiply_alpha, | |
482 bool unpremultiply_alpha, | |
483 const GLfloat transform_matrix[16]) { | |
484 DoCopyTextureInternal(decoder, source_target, source_id, dest_id, dest_level, | |
485 xoffset, yoffset, dest_width, dest_height, source_width, | |
486 source_height, flip_y, premultiply_alpha, | |
487 unpremultiply_alpha, transform_matrix); | |
488 } | |
489 | |
490 void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal( | |
491 const gles2::GLES2Decoder* decoder, | |
492 GLenum source_target, | |
493 GLuint source_id, | |
494 GLuint dest_id, | |
495 GLint dest_level, | |
496 GLint xoffset, | |
497 GLint yoffset, | |
498 GLsizei dest_width, | |
499 GLsizei dest_height, | |
500 GLsizei source_width, | |
501 GLsizei source_height, | |
502 bool flip_y, | |
503 bool premultiply_alpha, | |
504 bool unpremultiply_alpha, | |
505 const GLfloat transform_matrix[16]) { | |
383 DCHECK(source_target == GL_TEXTURE_2D || | 506 DCHECK(source_target == GL_TEXTURE_2D || |
384 source_target == GL_TEXTURE_RECTANGLE_ARB || | 507 source_target == GL_TEXTURE_RECTANGLE_ARB || |
385 source_target == GL_TEXTURE_EXTERNAL_OES); | 508 source_target == GL_TEXTURE_EXTERNAL_OES); |
509 DCHECK(xoffset >= 0 && xoffset + source_width <= dest_width); | |
510 DCHECK(yoffset >= 0 && yoffset + source_height <= dest_height); | |
386 if (!initialized_) { | 511 if (!initialized_) { |
387 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; | 512 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; |
388 return; | 513 return; |
389 } | 514 } |
390 | 515 |
391 VertexShaderId vertex_shader_id = GetVertexShaderId(flip_y); | 516 VertexShaderId vertex_shader_id = GetVertexShaderId(flip_y); |
392 DCHECK_LT(static_cast<size_t>(vertex_shader_id), vertex_shaders_.size()); | 517 DCHECK_LT(static_cast<size_t>(vertex_shader_id), vertex_shaders_.size()); |
393 FragmentShaderId fragment_shader_id = GetFragmentShaderId( | 518 FragmentShaderId fragment_shader_id = GetFragmentShaderId( |
394 premultiply_alpha, unpremultiply_alpha, source_target); | 519 premultiply_alpha, unpremultiply_alpha, source_target); |
395 DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size()); | 520 DCHECK_LT(static_cast<size_t>(fragment_shader_id), fragment_shaders_.size()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
429 #ifndef NDEBUG | 554 #ifndef NDEBUG |
430 glValidateProgram(info->program); | 555 glValidateProgram(info->program); |
431 GLint validation_status; | 556 GLint validation_status; |
432 glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status); | 557 glGetProgramiv(info->program, GL_VALIDATE_STATUS, &validation_status); |
433 if (GL_TRUE != validation_status) { | 558 if (GL_TRUE != validation_status) { |
434 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; | 559 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; |
435 return; | 560 return; |
436 } | 561 } |
437 #endif | 562 #endif |
438 | 563 |
439 glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix); | 564 if (!xoffset && !yoffset) { |
565 glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix); | |
566 } else { | |
567 // transform offsets from ([0, dest_width], [0, dest_height]) coord. | |
568 // to ([-1, 1], [-1, 1]) coord. | |
569 GLfloat xoffset_on_vertex = ((2.f * xoffset) / dest_width); | |
570 GLfloat yoffset_on_vertex = ((2.f * yoffset) / dest_height); | |
571 | |
572 // Pass view_matrix * offset_matrix to the program. | |
573 GLfloat view_transform[16]; | |
574 memcpy(view_transform, transform_matrix, 16 * sizeof(GLfloat)); | |
575 PreTranslate(view_transform, xoffset_on_vertex, yoffset_on_vertex, 0); | |
576 glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, view_transform); | |
577 } | |
440 if (source_target == GL_TEXTURE_RECTANGLE_ARB) | 578 if (source_target == GL_TEXTURE_RECTANGLE_ARB) |
441 glUniform2f(info->half_size_handle, width / 2.0f, height / 2.0f); | 579 glUniform2f(info->half_size_handle, source_width / 2.0f, |
580 source_height / 2.0f); | |
442 else | 581 else |
443 glUniform2f(info->half_size_handle, 0.5f, 0.5f); | 582 glUniform2f(info->half_size_handle, 0.5f, 0.5f); |
444 | 583 |
445 if (BindFramebufferTexture2D( | 584 if (BindFramebufferTexture2D( |
446 GL_TEXTURE_2D, dest_id, dest_level, framebuffer_)) { | 585 GL_TEXTURE_2D, dest_id, dest_level, framebuffer_)) { |
447 decoder->ClearAllAttributes(); | 586 decoder->ClearAllAttributes(); |
448 glEnableVertexAttribArray(kVertexPositionAttrib); | 587 glEnableVertexAttribArray(kVertexPositionAttrib); |
449 | 588 |
450 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); | 589 glBindBuffer(GL_ARRAY_BUFFER, buffer_id_); |
451 glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); | 590 glVertexAttribPointer(kVertexPositionAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0); |
452 | 591 |
453 glUniform1i(info->sampler_handle, 0); | 592 glUniform1i(info->sampler_handle, 0); |
454 | 593 |
455 glBindTexture(source_target, source_id); | 594 glBindTexture(source_target, source_id); |
456 glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 595 glTexParameterf(source_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
457 glTexParameterf(source_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 596 glTexParameterf(source_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
458 glTexParameteri(source_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 597 glTexParameteri(source_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
459 glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 598 glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
460 | 599 |
461 glDisable(GL_DEPTH_TEST); | 600 glDisable(GL_DEPTH_TEST); |
462 glDisable(GL_SCISSOR_TEST); | 601 glDisable(GL_SCISSOR_TEST); |
463 glDisable(GL_STENCIL_TEST); | 602 glDisable(GL_STENCIL_TEST); |
464 glDisable(GL_CULL_FACE); | 603 glDisable(GL_CULL_FACE); |
465 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | 604 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
466 glDepthMask(GL_FALSE); | 605 glDepthMask(GL_FALSE); |
467 glDisable(GL_BLEND); | 606 glDisable(GL_BLEND); |
468 | 607 |
469 glViewport(0, 0, width, height); | 608 glViewport(0, 0, dest_width, dest_height); |
470 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | 609 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
471 } | 610 } |
472 | 611 |
473 decoder->RestoreAllAttributes(); | 612 decoder->RestoreAllAttributes(); |
474 decoder->RestoreTextureState(source_id); | 613 decoder->RestoreTextureState(source_id); |
475 decoder->RestoreTextureState(dest_id); | 614 decoder->RestoreTextureState(dest_id); |
476 decoder->RestoreTextureUnitBindings(0); | 615 decoder->RestoreTextureUnitBindings(0); |
477 decoder->RestoreActiveTexture(); | 616 decoder->RestoreActiveTexture(); |
478 decoder->RestoreProgramBindings(); | 617 decoder->RestoreProgramBindings(); |
479 decoder->RestoreBufferBindings(); | 618 decoder->RestoreBufferBindings(); |
480 decoder->RestoreFramebufferBindings(); | 619 decoder->RestoreFramebufferBindings(); |
481 decoder->RestoreGlobalState(); | 620 decoder->RestoreGlobalState(); |
482 } | 621 } |
483 | 622 |
484 } // namespace gpu | 623 } // namespace gpu |
OLD | NEW |