Chromium Code Reviews| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
| =================================================================== |
| --- gpu/command_buffer/service/gles2_cmd_decoder.cc (revision 112643) |
| +++ gpu/command_buffer/service/gles2_cmd_decoder.cc (working copy) |
| @@ -751,6 +751,14 @@ |
| GLuint io_surface_id, |
| GLuint plane); |
| + // Wrapper for TexStorage2DEXT. |
| + void DoTexStorage2DEXT( |
| + GLenum target, |
| + GLint levels, |
| + GLenum internal_format, |
| + GLsizei width, |
| + GLsizei height); |
| + |
| // Creates a ProgramInfo for the given program. |
| ProgramManager::ProgramInfo* CreateProgramInfo( |
| GLuint client_id, GLuint service_id) { |
| @@ -3229,7 +3237,8 @@ |
| void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { |
| TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
| - if (!info || !texture_manager()->MarkMipmapsGenerated(feature_info_, info)) { |
| + if (!info || |
| + !texture_manager()->MarkMipmapsGenerated(feature_info_, info, true)) { |
| SetGLError(GL_INVALID_OPERATION, |
| "glGenerateMipmaps: Can not generate mips for npot textures"); |
| return; |
| @@ -6185,6 +6194,11 @@ |
| "glCompressedTexImage2D: unknown texture target"); |
| return error::kNoError; |
| } |
| + if (info->IsImmutable()) { |
| + SetGLError(GL_INVALID_OPERATION, |
| + "glCompressedTexImage2D: texture is immutable"); |
| + return error::kNoError; |
| + } |
| scoped_array<int8> zero; |
| if (!data) { |
| zero.reset(new int8[image_size]); |
| @@ -6360,6 +6374,12 @@ |
| return error::kNoError; |
| } |
| + if (info->IsImmutable()) { |
| + SetGLError(GL_INVALID_OPERATION, |
| + "glTexImage2D: texture is immutable"); |
| + return error::kNoError; |
| + } |
| + |
| GLsizei tex_width = 0; |
| GLsizei tex_height = 0; |
| GLenum tex_type = 0; |
| @@ -6534,6 +6554,10 @@ |
| "glCopyTexImage2D: unknown texture for target"); |
| return; |
| } |
| + if (info->IsImmutable()) { |
| + SetGLError(GL_INVALID_OPERATION, |
| + "glCopyTexImage2D: texture is immutable"); |
| + } |
| if (!texture_manager()->ValidForTarget( |
| feature_info_, target, level, width, height, 1) || |
| border != 0) { |
| @@ -6729,7 +6753,8 @@ |
| } |
| // See if we can call glTexImage2D instead since it appears to be faster. |
| - if (teximage2d_faster_than_texsubimage2d_ && xoffset == 0 && yoffset == 0) { |
| + if (teximage2d_faster_than_texsubimage2d_ && xoffset == 0 && yoffset == 0 && |
| + !info->IsImmutable()) { |
| GLsizei tex_width = 0; |
| GLsizei tex_height = 0; |
| bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); |
| @@ -7684,7 +7709,138 @@ |
| #endif |
| } |
| +static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) { |
| + switch (internalformat) { |
|
greggman
2011/12/03 01:41:01
this function and the next have too many spaces. d
|
| + case GL_RGB565: |
| + return GL_RGB; |
| + case GL_RGBA4: |
| + return GL_RGBA; |
| + case GL_RGB5_A1: |
| + return GL_RGBA; |
| + case GL_RGB8_OES: |
| + return GL_RGB; |
| + case GL_RGBA8_OES: |
| + return GL_RGBA; |
| + case GL_LUMINANCE8_ALPHA8_EXT: |
| + return GL_LUMINANCE_ALPHA; |
| + case GL_LUMINANCE8_EXT: |
| + return GL_LUMINANCE; |
| + case GL_ALPHA8_EXT: |
| + return GL_ALPHA; |
| + case GL_RGBA32F_EXT: |
| + return GL_RGBA; |
| + case GL_RGB32F_EXT: |
| + return GL_RGB; |
| + case GL_ALPHA32F_EXT: |
| + return GL_ALPHA; |
| + case GL_LUMINANCE32F_EXT: |
| + return GL_LUMINANCE; |
| + case GL_LUMINANCE_ALPHA32F_EXT: |
| + return GL_LUMINANCE_ALPHA; |
| + case GL_RGBA16F_EXT: |
| + return GL_RGBA; |
| + case GL_RGB16F_EXT: |
| + return GL_RGB; |
| + case GL_ALPHA16F_EXT: |
| + return GL_ALPHA; |
| + case GL_LUMINANCE16F_EXT: |
| + return GL_LUMINANCE; |
| + case GL_LUMINANCE_ALPHA16F_EXT: |
| + return GL_LUMINANCE_ALPHA; |
| + case GL_BGRA8_EXT: |
| + return GL_BGRA_EXT; |
| + default: |
| + return GL_NONE; |
| + } |
| +} |
| +static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) { |
| + switch (internalformat) { |
| + case GL_RGB565: |
| + return GL_UNSIGNED_SHORT_5_6_5; |
| + case GL_RGBA4: |
| + return GL_UNSIGNED_SHORT_4_4_4_4; |
| + case GL_RGB5_A1: |
| + return GL_UNSIGNED_SHORT_5_5_5_1; |
| + case GL_RGB8_OES: |
| + return GL_UNSIGNED_BYTE; |
| + case GL_RGBA8_OES: |
| + return GL_UNSIGNED_BYTE; |
| + case GL_LUMINANCE8_ALPHA8_EXT: |
| + return GL_UNSIGNED_BYTE; |
| + case GL_LUMINANCE8_EXT: |
| + return GL_UNSIGNED_BYTE; |
| + case GL_ALPHA8_EXT: |
| + return GL_UNSIGNED_BYTE; |
| + case GL_RGBA32F_EXT: |
| + return GL_FLOAT; |
| + case GL_RGB32F_EXT: |
| + return GL_FLOAT; |
| + case GL_ALPHA32F_EXT: |
| + return GL_FLOAT; |
| + case GL_LUMINANCE32F_EXT: |
| + return GL_FLOAT; |
| + case GL_LUMINANCE_ALPHA32F_EXT: |
| + return GL_FLOAT; |
| + case GL_RGBA16F_EXT: |
| + return GL_HALF_FLOAT_OES; |
| + case GL_RGB16F_EXT: |
| + return GL_HALF_FLOAT_OES; |
| + case GL_ALPHA16F_EXT: |
| + return GL_HALF_FLOAT_OES; |
| + case GL_LUMINANCE16F_EXT: |
| + return GL_HALF_FLOAT_OES; |
| + case GL_LUMINANCE_ALPHA16F_EXT: |
| + return GL_HALF_FLOAT_OES; |
| + case GL_BGRA8_EXT: |
| + return GL_UNSIGNED_BYTE; |
| + default: |
| + return GL_NONE; |
| + } |
| +} |
| + |
| +void GLES2DecoderImpl::DoTexStorage2DEXT( |
| + GLenum target, |
| + GLint levels, |
| + GLenum internal_format, |
| + GLsizei width, |
| + GLsizei height) { |
| + if (!texture_manager()->ValidForTarget( |
| + feature_info_, target, 0, width, height, 1) || |
| + TextureManager::ComputeMipMapCount(width, height, 1) < levels) { |
| + SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT: dimensions out of range"); |
| + return; |
| + } |
| + TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
| + if (!info) { |
| + SetGLError(GL_INVALID_OPERATION, |
| + "glTexStorage2DEXT: unknown texture for target"); |
| + return; |
| + } |
| + if (info->IsAttachedToFramebuffer()) { |
| + state_dirty_ = true; |
| + } |
| + if (info->IsImmutable()) { |
| + SetGLError(GL_INVALID_OPERATION, |
| + "glTexStorage2DEXT: texture is immutable"); |
| + return; |
| + } |
| + CopyRealGLErrorsToWrapper(); |
| + glTexStorage2DEXT(target, levels, internal_format, width, height); |
| + GLenum error = PeekGLError(); |
| + if (error == GL_NO_ERROR) { |
| + GLenum format = ExtractFormatFromStorageFormat(internal_format); |
| + GLenum type = ExtractTypeFromStorageFormat(internal_format); |
| + texture_manager()->SetLevelInfo( |
| + feature_info_, info, |
| + target, 0, format, width, height, 1, 0, format, type, |
| + false); |
| + texture_manager()->MarkMipmapsGenerated(feature_info_, info, false); |
| + info->SetImmutable(true); |
| + } |
| + |
| +} |
| + |
| // Include the auto-generated part of this file. We split this because it means |
| // we can easily edit the non-auto generated parts right here in this file |
| // instead of having to edit some template or the code generator. |