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

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

Issue 1426903002: gpu: Make glTexSubImage2D work with GL_SRGB_ALPHA on OpenGL (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove an unneeded hunk now that workarounds are used Created 5 years, 1 month 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_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, &current_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,
« no previous file with comments | « gpu/command_buffer/service/feature_info.cc ('k') | gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698