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

Unified Diff: gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc

Issue 864513004: gpu: introduce glCopySubTextureCHROMIUM (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address concerns of owners Created 5 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
diff --git a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
index 9098aba839010a9950684fa87b95108e4109582d..29e756cf65810938042faacb3b540fc225cced5e 100644
--- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
+++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
@@ -32,6 +32,11 @@
namespace {
+const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f};
+
enum VertexShaderId {
VERTEX_SHADER_COPY_TEXTURE,
VERTEX_SHADER_COPY_TEXTURE_FLIP_Y,
@@ -248,6 +253,47 @@ void DoCopyTexImage2D(const gpu::gles2::GLES2Decoder* decoder,
decoder->RestoreFramebufferBindings();
}
+void DoCopyTexSubImage2D(const gpu::gles2::GLES2Decoder* decoder,
+ GLenum source_target,
+ GLuint source_id,
+ GLuint dest_id,
+ GLint dest_level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei source_width,
+ GLsizei source_height,
+ GLuint framebuffer) {
+ DCHECK(source_target == GL_TEXTURE_2D ||
+ source_target == GL_TEXTURE_RECTANGLE_ARB);
+ if (BindFramebufferTexture2D(source_target, source_id, 0 /* level */,
+ framebuffer)) {
+ glBindTexture(GL_TEXTURE_2D, dest_id);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, dest_level, xoffset, yoffset, 0 /* x */,
+ 0 /* y */, source_width, source_height);
+ }
+
+ decoder->RestoreTextureState(source_id);
+ decoder->RestoreTextureState(dest_id);
+ decoder->RestoreTextureUnitBindings(0);
+ decoder->RestoreActiveTexture();
+ decoder->RestoreFramebufferBindings();
+}
+
+// Copy from SkMatrix44::preTranslate
+void PreTranslate(GLfloat* matrix, GLfloat dx, GLfloat dy, GLfloat dz) {
+ if (!dx && !dy && !dz)
+ return;
+
+ for (int i = 0; i < 4; ++i) {
+ matrix[(3 * 4) + i] = matrix[(0 * 4) + i] * dx + matrix[(1 * 4) + i] * dy +
+ matrix[(2 * 4) + i] * dz + matrix[(3 * 4) + i];
+ }
+}
+
} // namespace
namespace gpu {
@@ -350,22 +396,53 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTexture(
return;
}
- // Use default transform matrix if no transform passed in.
- const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f};
- DoCopyTextureWithTransform(decoder,
- source_target,
- source_id,
- dest_id,
- dest_level,
- width,
- height,
- flip_y,
- premultiply_alpha,
- unpremultiply_alpha,
- default_matrix);
+ // Use kIdentityMatrix if no transform passed in.
+ DoCopyTextureWithTransform(
+ decoder, source_target, source_id, dest_id, dest_level, width, height,
+ flip_y, premultiply_alpha, unpremultiply_alpha, kIdentityMatrix);
+}
+
+void CopyTextureCHROMIUMResourceManager::DoCopySubTexture(
+ const gles2::GLES2Decoder* decoder,
+ GLenum source_target,
+ GLuint source_id,
+ GLenum source_internal_format,
+ GLuint dest_id,
+ GLint dest_level,
+ GLenum dest_internal_format,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei dest_width,
+ GLsizei dest_height,
+ GLsizei source_width,
+ GLsizei source_height,
+ bool flip_y,
+ bool premultiply_alpha,
+ bool unpremultiply_alpha) {
+ bool premultiply_alpha_change = premultiply_alpha ^ unpremultiply_alpha;
+ // GL_INVALID_OPERATION is generated if the currently bound framebuffer's
+ // format does not contain a superset of the components required by the base
+ // format of internalformat.
+ // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glCopyTexImage2D.xml
+ bool source_format_contain_superset_of_dest_format =
+ (source_internal_format == dest_internal_format &&
+ source_internal_format != GL_BGRA_EXT) ||
+ (source_internal_format == GL_RGBA && dest_internal_format == GL_RGB);
+ // GL_TEXTURE_RECTANGLE_ARB on FBO is supported by OpenGL, not GLES2,
+ // so restrict this to GL_TEXTURE_2D.
+ if (source_target == GL_TEXTURE_2D && !flip_y && !premultiply_alpha_change &&
+ source_format_contain_superset_of_dest_format) {
+ DoCopyTexSubImage2D(decoder, source_target, source_id, dest_id, dest_level,
+ xoffset, yoffset, source_width, source_height,
+ framebuffer_);
+ return;
+ }
+
+ // Use kIdentityMatrix if no transform passed in.
+ DoCopySubTextureWithTransform(
+ decoder, source_target, source_id, dest_id, dest_level, xoffset, yoffset,
+ dest_width, dest_height, source_width, source_height, flip_y,
+ premultiply_alpha, unpremultiply_alpha, kIdentityMatrix);
}
void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
@@ -380,9 +457,57 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
bool premultiply_alpha,
bool unpremultiply_alpha,
const GLfloat transform_matrix[16]) {
+ GLsizei dest_width = width;
+ GLsizei dest_height = height;
+ DoCopyTextureInternal(decoder, source_target, source_id, dest_id, dest_level,
+ 0, 0, dest_width, dest_height, width, height, flip_y,
+ premultiply_alpha, unpremultiply_alpha,
+ transform_matrix);
+}
+
+void CopyTextureCHROMIUMResourceManager::DoCopySubTextureWithTransform(
+ const gles2::GLES2Decoder* decoder,
+ GLenum source_target,
+ GLuint source_id,
+ GLuint dest_id,
+ GLint dest_level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei dest_width,
+ GLsizei dest_height,
+ GLsizei source_width,
+ GLsizei source_height,
+ bool flip_y,
+ bool premultiply_alpha,
+ bool unpremultiply_alpha,
+ const GLfloat transform_matrix[16]) {
+ DoCopyTextureInternal(decoder, source_target, source_id, dest_id, dest_level,
+ xoffset, yoffset, dest_width, dest_height, source_width,
+ source_height, flip_y, premultiply_alpha,
+ unpremultiply_alpha, transform_matrix);
+}
+
+void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal(
+ const gles2::GLES2Decoder* decoder,
+ GLenum source_target,
+ GLuint source_id,
+ GLuint dest_id,
+ GLint dest_level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei dest_width,
+ GLsizei dest_height,
+ GLsizei source_width,
+ GLsizei source_height,
+ bool flip_y,
+ bool premultiply_alpha,
+ bool unpremultiply_alpha,
+ const GLfloat transform_matrix[16]) {
DCHECK(source_target == GL_TEXTURE_2D ||
source_target == GL_TEXTURE_RECTANGLE_ARB ||
source_target == GL_TEXTURE_EXTERNAL_OES);
+ DCHECK(xoffset >= 0 && xoffset + source_width <= dest_width);
+ DCHECK(yoffset >= 0 && yoffset + source_height <= dest_height);
if (!initialized_) {
DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager.";
return;
@@ -436,9 +561,23 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
}
#endif
- glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix);
+ if (!xoffset && !yoffset) {
+ glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, transform_matrix);
+ } else {
+ // transform offsets from ([0, dest_width], [0, dest_height]) coord.
+ // to ([-1, 1], [-1, 1]) coord.
+ GLfloat xoffset_on_vertex = ((2.f * xoffset) / dest_width);
+ GLfloat yoffset_on_vertex = ((2.f * yoffset) / dest_height);
+
+ // Pass view_matrix * offset_matrix to the program.
+ GLfloat view_transform[16];
+ memcpy(view_transform, transform_matrix, 16 * sizeof(GLfloat));
+ PreTranslate(view_transform, xoffset_on_vertex, yoffset_on_vertex, 0);
+ glUniformMatrix4fv(info->matrix_handle, 1, GL_FALSE, view_transform);
+ }
if (source_target == GL_TEXTURE_RECTANGLE_ARB)
- glUniform2f(info->half_size_handle, width / 2.0f, height / 2.0f);
+ glUniform2f(info->half_size_handle, source_width / 2.0f,
+ source_height / 2.0f);
else
glUniform2f(info->half_size_handle, 0.5f, 0.5f);
@@ -466,7 +605,7 @@ void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
glDepthMask(GL_FALSE);
glDisable(GL_BLEND);
- glViewport(0, 0, width, height);
+ glViewport(0, 0, dest_width, dest_height);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}

Powered by Google App Engine
This is Rietveld 408576698