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

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

Issue 1872663002: Enable TexStorage on Desktop GL lower than 4.2 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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_decoder.cc
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index f28cc4387e7832e07bdf8335f303ff646fd0293c..affed33b0e82a8399fc076eb5e414d73e347da4a 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -983,6 +983,12 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
void DoCompressedCopyTextureCHROMIUM(GLuint source_id, GLuint dest_id);
+ // Helper for DoTexStorage2DEXT and DoTexStorage3D.
+ void TexStorageImpl(
+ GLenum target, GLint levels, GLenum internal_format,
+ GLsizei width, GLsizei height, GLsizei depth,
+ ContextState::Dimension dimension, const char* function_name);
+
// Wrapper for TexStorage2DEXT.
void DoTexStorage2DEXT(
GLenum target,
@@ -14298,143 +14304,65 @@ void GLES2DecoderImpl::DoCompressedCopyTextureCHROMIUM(GLuint source_id,
false, false);
}
-void GLES2DecoderImpl::DoTexStorage2DEXT(
- GLenum target,
- GLint levels,
- GLenum internal_format,
- GLsizei width,
- GLsizei height) {
- TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
- "width", width, "height", height);
- if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
- TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
- LOCAL_SET_GL_ERROR(
- GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
- return;
- }
- TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
- &state_, target);
- if (!texture_ref) {
- LOCAL_SET_GL_ERROR(
- GL_INVALID_OPERATION,
- "glTexStorage2DEXT", "unknown texture for target");
- return;
- }
- Texture* texture = texture_ref->texture();
- if (texture->IsAttachedToFramebuffer()) {
- framebuffer_state_.clear_state_dirty = true;
- }
- if (texture->IsImmutable()) {
- LOCAL_SET_GL_ERROR(
- GL_INVALID_OPERATION,
- "glTexStorage2DEXT", "texture is immutable");
- return;
- }
-
- GLenum format = TextureManager::ExtractFormatFromStorageFormat(
- internal_format);
- GLenum type = TextureManager::ExtractTypeFromStorageFormat(internal_format);
-
- {
- GLsizei level_width = width;
- GLsizei level_height = height;
- uint32_t estimated_size = 0;
- for (int ii = 0; ii < levels; ++ii) {
- uint32_t level_size = 0;
- if (!GLES2Util::ComputeImageDataSizes(
- level_width, level_height, 1, format, type, state_.unpack_alignment,
- &estimated_size, NULL, NULL) ||
- !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
- LOCAL_SET_GL_ERROR(
- GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
- return;
- }
- level_width = std::max(1, level_width >> 1);
- level_height = std::max(1, level_height >> 1);
- }
- if (!EnsureGPUMemoryAvailable(estimated_size)) {
- LOCAL_SET_GL_ERROR(
- GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
+void GLES2DecoderImpl::TexStorageImpl(
+ GLenum target, GLint levels, GLenum internal_format,
+ GLsizei width, GLsizei height, GLsizei depth,
+ ContextState::Dimension dimension, const char* function_name) {
+ if (dimension == ContextState::k2D) {
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
return;
}
- }
-
- LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
- glTexStorage2DEXT(target, levels, internal_format, width, height);
- GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
- if (error == GL_NO_ERROR) {
- GLsizei level_width = width;
- GLsizei level_height = height;
-
- GLenum cur_format = feature_info_->IsES3Enabled() ?
- internal_format : format;
- for (int ii = 0; ii < levels; ++ii) {
- if (target == GL_TEXTURE_CUBE_MAP) {
- for (int jj = 0; jj < 6; ++jj) {
- GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + jj;
- texture_manager()->SetLevelInfo(texture_ref, face, ii, cur_format,
- level_width, level_height, 1, 0,
- format, type, gfx::Rect());
- }
- } else {
- texture_manager()->SetLevelInfo(texture_ref, target, ii, cur_format,
- level_width, level_height, 1, 0,
- format, type, gfx::Rect());
- }
- level_width = std::max(1, level_width >> 1);
- level_height = std::max(1, level_height >> 1);
+ } else {
+ if (!validators_->texture_3_d_target.IsValid(target)) {
+ LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
+ return;
}
- texture->SetImmutable(true);
- }
-}
-
-void GLES2DecoderImpl::DoTexStorage3D(
- GLenum target,
- GLint levels,
- GLenum internal_format,
- GLsizei width,
- GLsizei height,
- GLsizei depth) {
- TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage3D",
- "widthXheight", width * height, "depth", depth);
- if (!validators_->texture_3_d_target.IsValid(target)) {
- LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexStorage3D", target, "target");
- return;
}
if (levels <= 0) {
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage3D", "levels <= 0");
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "levels <= 0");
return;
}
if (!validators_->texture_internal_format_storage.IsValid(internal_format)) {
- LOCAL_SET_GL_ERROR_INVALID_ENUM("glTexStorage3D", internal_format,
- "internal_format");
- return;
- }
- if (width <= 0) {
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage3D", "width <= 0");
- return;
- }
- if (height <= 0) {
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage3D", "height <= 0");
+ LOCAL_SET_GL_ERROR_INVALID_ENUM(
+ function_name, internal_format, "internal_format");
return;
}
- if (depth <= 0) {
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage3D", "depth <= 0");
- return;
+ bool is_compressed_format;
+ switch (internal_format) {
+ case GL_COMPRESSED_R11_EAC:
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ case GL_COMPRESSED_RG11_EAC:
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ case GL_COMPRESSED_RGB8_ETC2:
+ case GL_COMPRESSED_SRGB8_ETC2:
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ is_compressed_format = true;
+ if (target == GL_TEXTURE_3D) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_OPERATION, function_name, "target invalid for format");
+ return;
+ }
+ break;
+ default:
+ is_compressed_format = false;
+ break;
}
if (!texture_manager()->ValidForTarget(target, 0, width, height, depth) ||
TextureManager::ComputeMipMapCount(
target, width, height, depth) < levels) {
LOCAL_SET_GL_ERROR(
- GL_INVALID_VALUE, "glTexStorage3D", "dimensions out of range");
+ GL_INVALID_VALUE, function_name, "dimensions out of range");
return;
}
TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
&state_, target);
if (!texture_ref) {
LOCAL_SET_GL_ERROR(
- GL_INVALID_OPERATION,
- "glTexStorage3D", "unknown texture for target");
+ GL_INVALID_OPERATION, function_name, "unknown texture for target");
return;
}
Texture* texture = texture_ref->texture();
@@ -14443,7 +14371,7 @@ void GLES2DecoderImpl::DoTexStorage3D(
}
if (texture->IsImmutable()) {
LOCAL_SET_GL_ERROR(
- GL_INVALID_OPERATION, "glTexStorage3D", "texture is immutable");
+ GL_INVALID_OPERATION, function_name, "texture is immutable");
return;
}
@@ -14451,48 +14379,81 @@ void GLES2DecoderImpl::DoTexStorage3D(
internal_format);
GLenum type = TextureManager::ExtractTypeFromStorageFormat(internal_format);
+ std::vector<int32_t> level_size(levels);
{
GLsizei level_width = width;
GLsizei level_height = height;
GLsizei level_depth = depth;
- uint32_t estimated_size = 0;
+ base::CheckedNumeric<uint32_t> estimated_size(0);
+ PixelStoreParams params;
+ params.alignment = 1;
for (int ii = 0; ii < levels; ++ii) {
- uint32_t level_size = 0;
- if (!GLES2Util::ComputeImageDataSizes(
- level_width, level_height, level_depth, format, type,
- state_.unpack_alignment,
- &estimated_size, NULL, NULL) ||
- !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
- LOCAL_SET_GL_ERROR(
- GL_OUT_OF_MEMORY, "glTexStorage3D", "dimensions too large");
- return;
+ uint32_t size;
+ if (is_compressed_format) {
+ if (!GetCompressedTexSizeInBytes(function_name,
+ level_width, level_height, level_depth,
+ internal_format, &level_size[ii])) {
+ // GetCompressedTexSizeInBytes() already generates a GL error.
+ return;
+ }
+ size = static_cast<uint32_t>(level_size[ii]);
+ } else {
+ if (!GLES2Util::ComputeImageDataSizesES3(level_width,
+ level_height,
+ level_depth,
+ format, type,
+ params,
+ &size,
+ nullptr, nullptr,
+ nullptr, nullptr)) {
+ LOCAL_SET_GL_ERROR(
+ GL_OUT_OF_MEMORY, function_name, "dimensions too large");
+ return;
+ }
}
+ estimated_size += size;
level_width = std::max(1, level_width >> 1);
level_height = std::max(1, level_height >> 1);
if (target == GL_TEXTURE_3D)
level_depth = std::max(1, level_depth >> 1);
}
- if (!EnsureGPUMemoryAvailable(estimated_size)) {
- LOCAL_SET_GL_ERROR(
- GL_OUT_OF_MEMORY, "glTexStorage3D", "out of memory");
+ if (!estimated_size.IsValid() ||
+ !EnsureGPUMemoryAvailable(estimated_size.ValueOrDefault(0))) {
+ LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "out of memory");
return;
}
}
- LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage3D");
- glTexStorage3D(target, levels, internal_format, width, height, depth);
- GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage3D");
- if (error == GL_NO_ERROR) {
+ // TODO(zmo): We might need to emulate TexStorage using TexImage or
+ // CompressedTexImage on Mac OSX where we expose ES3 APIs when the underlying
+ // driver is lower than 4.2 and ARB_texture_storage extension doesn't exist.
+ if (dimension == ContextState::k2D) {
+ glTexStorage2DEXT(target, levels, internal_format, width, height);
+ } else {
+ glTexStorage3D(target, levels, internal_format, width, height, depth);
+ }
+
+ {
GLsizei level_width = width;
GLsizei level_height = height;
GLsizei level_depth = depth;
-
- GLenum cur_format = feature_info_->IsES3Enabled() ?
- internal_format : format;
+ GLenum adjusted_format =
+ feature_info_->IsES3Enabled() ? internal_format : format;
for (int ii = 0; ii < levels; ++ii) {
- texture_manager()->SetLevelInfo(texture_ref, target, ii, cur_format,
- level_width, level_height, level_depth, 0,
- format, type, gfx::Rect());
+ if (target == GL_TEXTURE_CUBE_MAP) {
+ for (int jj = 0; jj < 6; ++jj) {
+ GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + jj;
+ texture_manager()->SetLevelInfo(texture_ref, face, ii,
+ adjusted_format,
+ level_width, level_height, 1,
+ 0, format, type, gfx::Rect());
+ }
+ } else {
+ texture_manager()->SetLevelInfo(texture_ref, target, ii,
+ adjusted_format,
+ level_width, level_height, level_depth,
+ 0, format, type, gfx::Rect());
+ }
level_width = std::max(1, level_width >> 1);
level_height = std::max(1, level_height >> 1);
if (target == GL_TEXTURE_3D)
@@ -14502,6 +14463,31 @@ void GLES2DecoderImpl::DoTexStorage3D(
}
}
+void GLES2DecoderImpl::DoTexStorage2DEXT(
+ GLenum target,
+ GLint levels,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height) {
+ TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2D",
+ "width", width, "height", height);
+ TexStorageImpl(target, levels, internal_format, width, height, 1,
+ ContextState::k2D, "glTexStorage2D");
+}
+
+void GLES2DecoderImpl::DoTexStorage3D(
+ GLenum target,
+ GLint levels,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth) {
+ TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage3D",
+ "widthXheight", width * height, "depth", depth);
+ TexStorageImpl(target, levels, internal_format, width, height, depth,
+ ContextState::k3D, "glTexStorage3D");
+}
+
error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
uint32_t immediate_data_size,
const void* cmd_data) {
« no previous file with comments | « gpu/command_buffer/service/feature_info.cc ('k') | gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698