gpu: Extend CopyTextureCHROMIUM with support for copying part of source texture.
This makes it possible to specify the area of the source texture
that is copied to the destination texture.
BUG=490889
TEST=gl_tests
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Review URL: https://codereview.chromium.org/1143373004
Cr-Commit-Position: refs/heads/master@{#331326}
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 d41ee9db..974cbd7 100644
--- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
+++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.cc
@@ -250,6 +250,8 @@
GLuint dest_id,
GLint xoffset,
GLint yoffset,
+ GLint source_x,
+ GLint source_y,
GLsizei source_width,
GLsizei source_height,
GLuint framebuffer) {
@@ -262,7 +264,7 @@
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0 /* level */, xoffset, yoffset,
- 0 /* x */, 0 /* y */, source_width, source_height);
+ source_x, source_y, source_width, source_height);
}
decoder->RestoreTextureState(source_id);
@@ -398,6 +400,10 @@
GLenum dest_internal_format,
GLint xoffset,
GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
GLsizei dest_width,
GLsizei dest_height,
GLsizei source_width,
@@ -419,15 +425,15 @@
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, xoffset,
- yoffset, source_width, source_height, framebuffer_);
+ yoffset, x, y, width, height, framebuffer_);
return;
}
- // Use kIdentityMatrix if no transform passed in.
- DoCopySubTextureWithTransform(
- decoder, source_target, source_id, dest_id, xoffset, yoffset, dest_width,
- dest_height, source_width, source_height, flip_y, premultiply_alpha,
- unpremultiply_alpha, kIdentityMatrix);
+ DoCopyTextureInternal(decoder, source_target, source_id, dest_id, xoffset - x,
+ yoffset - y, dest_width, dest_height, source_width,
+ source_height, flip_y, premultiply_alpha,
+ unpremultiply_alpha, kIdentityMatrix, xoffset, yoffset,
+ width, height);
}
void CopyTextureCHROMIUMResourceManager::DoCopyTextureWithTransform(
@@ -446,28 +452,7 @@
DoCopyTextureInternal(decoder, source_target, source_id, dest_id, 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 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, xoffset,
- yoffset, dest_width, dest_height, source_width,
- source_height, flip_y, premultiply_alpha,
- unpremultiply_alpha, transform_matrix);
+ transform_matrix, 0, 0, dest_width, dest_height);
}
void CopyTextureCHROMIUMResourceManager::DoCopyTextureInternal(
@@ -484,7 +469,11 @@
bool flip_y,
bool premultiply_alpha,
bool unpremultiply_alpha,
- const GLfloat transform_matrix[16]) {
+ const GLfloat transform_matrix[16],
+ GLint scissor_x,
+ GLint scissor_y,
+ GLsizei scissor_width,
+ GLsizei scissor_height) {
DCHECK(source_target == GL_TEXTURE_2D ||
source_target == GL_TEXTURE_RECTANGLE_ARB ||
source_target == GL_TEXTURE_EXTERNAL_OES);
@@ -580,13 +569,14 @@
glTexParameteri(source_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
glDisable(GL_STENCIL_TEST);
glDisable(GL_CULL_FACE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_FALSE);
glDisable(GL_BLEND);
+ glEnable(GL_SCISSOR_TEST);
+ glScissor(scissor_x, scissor_y, scissor_width, scissor_height);
glViewport(0, 0, dest_width, dest_height);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
diff --git a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h
index 5c62141..8cba517 100644
--- a/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h
+++ b/gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h
@@ -50,6 +50,10 @@
GLenum dest_internal_format,
GLint xoffset,
GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
GLsizei dest_width,
GLsizei dest_height,
GLsizei source_width,
@@ -71,21 +75,6 @@
bool unpremultiply_alpha,
const GLfloat transform_matrix[16]);
- void DoCopySubTextureWithTransform(const gles2::GLES2Decoder* decoder,
- GLenum source_target,
- GLuint source_id,
- GLuint dest_id,
- 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]);
-
// The attributes used during invocation of the extension.
static const GLuint kVertexPositionAttrib = 0;
@@ -116,7 +105,11 @@
bool flip_y,
bool premultiply_alpha,
bool unpremultiply_alpha,
- const GLfloat transform_matrix[16]);
+ const GLfloat transform_matrix[16],
+ GLint scissor_x,
+ GLint scissor_y,
+ GLsizei scissor_width,
+ GLsizei scissor_height);
bool initialized_;
typedef std::vector<GLuint> ShaderVector;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 9c4af2e7..f1880d1c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1013,7 +1013,11 @@
GLuint source_id,
GLuint dest_id,
GLint xoffset,
- GLint yoffset);
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
// Wrapper for TexStorage2DEXT.
void DoTexStorage2DEXT(
@@ -11969,7 +11973,7 @@
ScopedModifyPixels modify(dest_texture_ref);
- // Try using GLImage::CopyTexImage when possible.
+ // Try using GLImage::CopyTexSubImage when possible.
bool unpack_premultiply_alpha_change =
unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change) {
@@ -12007,7 +12011,11 @@
GLuint source_id,
GLuint dest_id,
GLint xoffset,
- GLint yoffset) {
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height) {
TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopySubTextureCHROMIUM");
TextureRef* source_texture_ref = GetTexture(source_id);
@@ -12048,6 +12056,13 @@
GLenum source_internal_format = 0;
source_texture->GetLevelType(source_texture->target(), 0, &source_type,
&source_internal_format);
+ if (!source_texture->ValidForTexture(source_texture->target(), 0, x, y, 0,
+ width, height, 1, source_type)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
+ "source texture bad dimensions.");
+ return;
+ }
+
GLenum dest_type = 0;
GLenum dest_internal_format = 0;
bool dest_level_defined = dest_texture->GetLevelType(
@@ -12058,8 +12073,7 @@
return;
}
if (!dest_texture->ValidForTexture(dest_texture->target(), 0, xoffset,
- yoffset, 0, source_width, source_height,
- 1, dest_type)) {
+ yoffset, 0, width, height, 1, dest_type)) {
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
"destination texture bad dimensions.");
return;
@@ -12095,8 +12109,8 @@
bool ok = dest_texture->GetLevelSize(
GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr);
DCHECK(ok);
- if (xoffset != 0 || yoffset != 0 || source_width != dest_width ||
- source_height != dest_height) {
+ if (xoffset != 0 || yoffset != 0 || width != dest_width ||
+ height != dest_height) {
if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target,
0)) {
LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopySubTextureCHROMIUM",
@@ -12116,31 +12130,21 @@
if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change) {
glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
if (image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(xoffset, yoffset),
- gfx::Rect(0, 0, source_width, source_height))) {
+ gfx::Rect(x, y, source_width, source_height))) {
return;
}
}
DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
- // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
- // before presenting.
- if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
- // TODO(hkuang): get the StreamTexture transform matrix in GPU process
- // instead of using kIdentityMatrix crbug.com/226218.
- copy_texture_CHROMIUM_->DoCopySubTextureWithTransform(
- this, source_texture->target(), source_texture->service_id(),
- dest_texture->service_id(), xoffset, yoffset, dest_width, dest_height,
- source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
- unpack_unpremultiply_alpha_, kIdentityMatrix);
- } else {
- copy_texture_CHROMIUM_->DoCopySubTexture(
- this, source_texture->target(), source_texture->service_id(),
- source_internal_format, dest_texture->service_id(),
- dest_internal_format, xoffset, yoffset, dest_width, dest_height,
- source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
- unpack_unpremultiply_alpha_);
- }
+ // TODO(hkuang): get the StreamTexture transform matrix in GPU process.
+ // crbug.com/226218.
+ copy_texture_CHROMIUM_->DoCopySubTexture(
+ this, source_texture->target(), source_texture->service_id(),
+ source_internal_format, dest_texture->service_id(), dest_internal_format,
+ xoffset, yoffset, x, y, width, height, dest_width, dest_height,
+ source_width, source_height, unpack_flip_y_, unpack_premultiply_alpha_,
+ unpack_unpremultiply_alpha_);
DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 26c4782..09d07c0b 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -4553,7 +4553,22 @@
GLenum dest_id = static_cast<GLenum>(c.dest_id);
GLint xoffset = static_cast<GLint>(c.xoffset);
GLint yoffset = static_cast<GLint>(c.yoffset);
- DoCopySubTextureCHROMIUM(target, source_id, dest_id, xoffset, yoffset);
+ GLint x = static_cast<GLint>(c.x);
+ GLint y = static_cast<GLint>(c.y);
+ GLsizei width = static_cast<GLsizei>(c.width);
+ GLsizei height = static_cast<GLsizei>(c.height);
+ if (width < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
+ "width < 0");
+ return error::kNoError;
+ }
+ if (height < 0) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopySubTextureCHROMIUM",
+ "height < 0");
+ return error::kNoError;
+ }
+ DoCopySubTextureCHROMIUM(target, source_id, dest_id, xoffset, yoffset, x, y,
+ width, height);
return error::kNoError;
}