| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| index 39e0a2954c987119b03744e8848c02faffce1ff9..f25c65f0e1b42467433f4cc6e909577d710b9334 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| @@ -190,33 +190,6 @@ struct Vec4f {
|
| GLfloat v[4];
|
| };
|
|
|
| -// Returns the union of |rect1| and |rect2| if one of the rectangles is empty,
|
| -// contains the other rectangle or shares an edge with the other rectangle.
|
| -bool CombineAdjacentRects(const gfx::Rect& rect1,
|
| - const gfx::Rect& rect2,
|
| - gfx::Rect* result) {
|
| - // Return |rect2| if |rect1| is empty or |rect2| contains |rect1|.
|
| - if (rect1.IsEmpty() || rect2.Contains(rect1)) {
|
| - *result = rect2;
|
| - return true;
|
| - }
|
| -
|
| - // Return |rect1| if |rect2| is empty or |rect1| contains |rect2|.
|
| - if (rect2.IsEmpty() || rect1.Contains(rect2)) {
|
| - *result = rect1;
|
| - return true;
|
| - }
|
| -
|
| - // Return the union of |rect1| and |rect2| if they share an edge.
|
| - if (rect1.SharesEdgeWith(rect2)) {
|
| - *result = gfx::UnionRects(rect1, rect2);
|
| - return true;
|
| - }
|
| -
|
| - // Return false if it's not possible to combine |rect1| and |rect2|.
|
| - return false;
|
| -}
|
| -
|
| GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
|
| switch (internalformat) {
|
| case GL_R8:
|
| @@ -11109,9 +11082,9 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D(
|
| if (xoffset != 0 || yoffset != 0 || width != size.width() ||
|
| height != size.height()) {
|
| gfx::Rect cleared_rect;
|
| - if (CombineAdjacentRects(texture->GetLevelClearedRect(target, level),
|
| - gfx::Rect(xoffset, yoffset, width, height),
|
| - &cleared_rect)) {
|
| + if (TextureManager::CombineAdjacentRects(
|
| + texture->GetLevelClearedRect(target, level),
|
| + gfx::Rect(xoffset, yoffset, width, height), &cleared_rect)) {
|
| DCHECK_GE(cleared_rect.size().GetArea(),
|
| texture->GetLevelClearedRect(target, level).size().GetArea());
|
| texture_manager()->SetLevelClearedRect(texture_ref, target, level,
|
| @@ -11165,149 +11138,6 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D(
|
| ExitCommandProcessingEarly();
|
| }
|
|
|
| -bool GLES2DecoderImpl::ValidateTexSubImage2D(
|
| - error::Error* error,
|
| - const char* function_name,
|
| - GLenum target,
|
| - GLint level,
|
| - GLint xoffset,
|
| - GLint yoffset,
|
| - GLsizei width,
|
| - GLsizei height,
|
| - GLenum format,
|
| - GLenum type,
|
| - const void * data) {
|
| - (*error) = error::kNoError;
|
| - if (!validators_->texture_target.IsValid(target)) {
|
| - LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
|
| - return false;
|
| - }
|
| - if (width < 0) {
|
| - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
|
| - return false;
|
| - }
|
| - if (height < 0) {
|
| - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
|
| - return false;
|
| - }
|
| - TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
|
| - &state_, target);
|
| - if (!texture_ref) {
|
| - LOCAL_SET_GL_ERROR(
|
| - GL_INVALID_OPERATION,
|
| - function_name, "unknown texture for target");
|
| - return false;
|
| - }
|
| - Texture* texture = texture_ref->texture();
|
| - GLenum current_type = 0;
|
| - GLenum internal_format = 0;
|
| - if (!texture->GetLevelType(target, level, ¤t_type, &internal_format)) {
|
| - LOCAL_SET_GL_ERROR(
|
| - GL_INVALID_OPERATION, function_name, "level does not exist.");
|
| - return false;
|
| - }
|
| - if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
|
| - function_name, format, type, internal_format, level)) {
|
| - return false;
|
| - }
|
| - if (type != current_type && !feature_info_->IsES3Enabled()) {
|
| - LOCAL_SET_GL_ERROR(
|
| - GL_INVALID_OPERATION,
|
| - function_name, "type does not match type of texture.");
|
| - return false;
|
| - }
|
| - if (!texture->ValidForTexture(
|
| - target, level, xoffset, yoffset, 0, width, height, 1)) {
|
| - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
|
| - return false;
|
| - }
|
| - if ((GLES2Util::GetChannelsForFormat(format) &
|
| - (GLES2Util::kDepth | GLES2Util::kStencil)) != 0
|
| - && !feature_info_->IsES3Enabled()) {
|
| - LOCAL_SET_GL_ERROR(
|
| - GL_INVALID_OPERATION,
|
| - function_name, "can not supply data for depth or stencil textures");
|
| - return false;
|
| - }
|
| - if (data == NULL) {
|
| - (*error) = error::kOutOfBounds;
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -error::Error GLES2DecoderImpl::DoTexSubImage2D(
|
| - GLenum target,
|
| - GLint level,
|
| - GLint xoffset,
|
| - GLint yoffset,
|
| - GLsizei width,
|
| - GLsizei height,
|
| - GLenum format,
|
| - GLenum type,
|
| - const void * data) {
|
| - error::Error error = error::kNoError;
|
| - if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
|
| - xoffset, yoffset, width, height, format, type, data)) {
|
| - return error;
|
| - }
|
| - TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
|
| - &state_, target);
|
| - Texture* texture = texture_ref->texture();
|
| - GLsizei tex_width = 0;
|
| - GLsizei tex_height = 0;
|
| - bool ok = texture->GetLevelSize(
|
| - target, level, &tex_width, &tex_height, nullptr);
|
| - DCHECK(ok);
|
| - if (xoffset != 0 || yoffset != 0 ||
|
| - width != tex_width || height != tex_height) {
|
| - gfx::Rect cleared_rect;
|
| - if (CombineAdjacentRects(texture->GetLevelClearedRect(target, level),
|
| - gfx::Rect(xoffset, yoffset, width, height),
|
| - &cleared_rect)) {
|
| - DCHECK_GE(cleared_rect.size().GetArea(),
|
| - texture->GetLevelClearedRect(target, level).size().GetArea());
|
| - texture_manager()->SetLevelClearedRect(texture_ref, target, level,
|
| - cleared_rect);
|
| - } else {
|
| - // Otherwise clear part of texture level that is not already cleared.
|
| - if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
|
| - level)) {
|
| - LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glTexSubImage2D",
|
| - "dimensions too big");
|
| - return error::kNoError;
|
| - }
|
| - }
|
| - ScopedTextureUploadTimer timer(&texture_state_);
|
| - glTexSubImage2D(
|
| - target, level, xoffset, yoffset, width, height, format, type, data);
|
| - return error::kNoError;
|
| - }
|
| -
|
| - if (!texture_state_.texsubimage_faster_than_teximage &&
|
| - !texture->IsImmutable() &&
|
| - !texture->HasImages()) {
|
| - ScopedTextureUploadTimer timer(&texture_state_);
|
| - GLenum internal_format;
|
| - GLenum tex_type;
|
| - texture->GetLevelType(target, level, &tex_type, &internal_format);
|
| - // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
|
| - // to look it up.
|
| - glTexImage2D(
|
| - target, level, internal_format, width, height, 0, format, type, data);
|
| - } else {
|
| - ScopedTextureUploadTimer timer(&texture_state_);
|
| - glTexSubImage2D(
|
| - target, level, xoffset, yoffset, width, height, format, type, data);
|
| - }
|
| - texture_manager()->SetLevelCleared(texture_ref, target, level, true);
|
| -
|
| - // This may be a slow command. Exit command processing to allow for
|
| - // context preemption and GPU watchdog checks.
|
| - ExitCommandProcessingEarly();
|
| - return error::kNoError;
|
| -}
|
| -
|
| error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
|
| const void* cmd_data) {
|
| const gles2::cmds::TexSubImage2D& c =
|
| @@ -11332,10 +11162,23 @@ error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
|
| NULL, NULL)) {
|
| return error::kOutOfBounds;
|
| }
|
| +
|
| const void* pixels = GetSharedMemoryAs<const void*>(
|
| c.pixels_shm_id, c.pixels_shm_offset, data_size);
|
| - return DoTexSubImage2D(
|
| - target, level, xoffset, yoffset, width, height, format, type, pixels);
|
| + if (!pixels)
|
| + return error::kOutOfBounds;
|
| +
|
| + TextureManager::DoTexSubImageArguments args = {
|
| + target, level, xoffset, yoffset, width,
|
| + height, format, type, pixels, data_size};
|
| + texture_manager()->ValidateAndDoTexSubImage(this, &texture_state_, &state_,
|
| + &framebuffer_state_,
|
| + "glTexSubImage2D", args);
|
| +
|
| + // This may be a slow command. Exit command processing to allow for
|
| + // context preemption and GPU watchdog checks.
|
| + ExitCommandProcessingEarly();
|
| + return error::kNoError;
|
| }
|
|
|
| error::Error GLES2DecoderImpl::DoTexSubImage3D(
|
| @@ -13273,9 +13116,9 @@ void GLES2DecoderImpl::DoCopySubTextureCHROMIUM(
|
| if (xoffset != 0 || yoffset != 0 || width != dest_width ||
|
| height != dest_height) {
|
| gfx::Rect cleared_rect;
|
| - if (CombineAdjacentRects(dest_texture->GetLevelClearedRect(target, 0),
|
| - gfx::Rect(xoffset, yoffset, width, height),
|
| - &cleared_rect)) {
|
| + if (TextureManager::CombineAdjacentRects(
|
| + dest_texture->GetLevelClearedRect(target, 0),
|
| + gfx::Rect(xoffset, yoffset, width, height), &cleared_rect)) {
|
| DCHECK_GE(cleared_rect.size().GetArea(),
|
| dest_texture->GetLevelClearedRect(target, 0).size().GetArea());
|
| texture_manager()->SetLevelClearedRect(dest_texture_ref, target, 0,
|
| @@ -13611,9 +13454,9 @@ void GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM(GLenum target,
|
| if (xoffset != 0 || yoffset != 0 || width != dest_width ||
|
| height != dest_height) {
|
| gfx::Rect cleared_rect;
|
| - if (CombineAdjacentRects(dest_texture->GetLevelClearedRect(target, 0),
|
| - gfx::Rect(xoffset, yoffset, width, height),
|
| - &cleared_rect)) {
|
| + if (TextureManager::CombineAdjacentRects(
|
| + dest_texture->GetLevelClearedRect(target, 0),
|
| + gfx::Rect(xoffset, yoffset, width, height), &cleared_rect)) {
|
| DCHECK_GE(cleared_rect.size().GetArea(),
|
| dest_texture->GetLevelClearedRect(target, 0).size().GetArea());
|
| texture_manager()->SetLevelClearedRect(dest_texture_ref, target, 0,
|
|
|