Chromium Code Reviews| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
| =================================================================== |
| --- gpu/command_buffer/service/gles2_cmd_decoder.cc (revision 113223) |
| +++ gpu/command_buffer/service/gles2_cmd_decoder.cc (working copy) |
| @@ -911,7 +911,8 @@ |
| unsigned format, |
| unsigned type, |
| int width, |
| - int height); |
| + int height, |
| + bool is_texture_immutable); |
| // Restore all GL state that affects clearing. |
| void RestoreClearState(); |
| @@ -3238,7 +3239,7 @@ |
| void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { |
| TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
| if (!info || |
| - !texture_manager()->MarkMipmapsGenerated(feature_info_, info, true)) { |
| + !texture_manager()->MarkMipmapsGenerated(feature_info_, info)) { |
| SetGLError(GL_INVALID_OPERATION, |
| "glGenerateMipmaps: Can not generate mips for npot textures"); |
| return; |
| @@ -6143,7 +6144,8 @@ |
| unsigned format, |
| unsigned type, |
| int width, |
| - int height) { |
| + int height, |
| + bool is_texture_immutable) { |
| // Assumes the size has already been checked. |
| uint32 pixels_size = 0; |
| if (!GLES2Util::ComputeImageDataSize( |
| @@ -6153,8 +6155,13 @@ |
| scoped_array<char> zero(new char[pixels_size]); |
| memset(zero.get(), 0, pixels_size); |
| glBindTexture(bind_target, service_id); |
| - WrappedTexImage2D( |
| - target, level, format, width, height, 0, format, type, zero.get()); |
| + if (is_texture_immutable) { |
| + glTexSubImage2D( |
| + target, level, 0, 0, width, height, format, type, zero.get()); |
| + } else { |
| + WrappedTexImage2D( |
| + target, level, format, width, height, 0, format, type, zero.get()); |
| + } |
| TextureManager::TextureInfo* info = GetTextureInfoForTarget(bind_target); |
| glBindTexture(bind_target, info ? info->service_id() : 0); |
| return true; |
| @@ -6499,19 +6506,19 @@ |
| if (!info->GetLevelType(target, level, &type, &internal_format)) { |
| SetGLError( |
| GL_INVALID_OPERATION, |
| - "glCompressdTexSubImage2D: level does not exist."); |
| + "glCompressedTexSubImage2D: level does not exist."); |
| return; |
| } |
| if (internal_format != format) { |
| SetGLError( |
| GL_INVALID_OPERATION, |
| - "glCompressdTexSubImage2D: format does not match internal format."); |
| + "glCompressedTexSubImage2D: format does not match internal format."); |
| return; |
| } |
| if (!info->ValidForTexture( |
| target, level, xoffset, yoffset, width, height, format, type)) { |
| SetGLError(GL_INVALID_VALUE, |
| - "glCompressdTexSubImage2D: bad dimensions."); |
| + "glCompressedTexSubImage2D: bad dimensions."); |
| return; |
| } |
| // Note: There is no need to deal with texture cleared tracking here |
| @@ -6602,7 +6609,8 @@ |
| // some part was clipped so clear the texture. |
| if (!ClearLevel( |
| info->service_id(), info->target(), |
| - target, level, internal_format, GL_UNSIGNED_BYTE, width, height)) { |
| + target, level, internal_format, GL_UNSIGNED_BYTE, width, height, |
| + info->IsImmutable())) { |
| SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D: dimensions too big"); |
| return; |
| } |
| @@ -6752,28 +6760,31 @@ |
| return; |
| } |
| - // See if we can call glTexImage2D instead since it appears to be faster. |
| - 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); |
| - DCHECK(ok); |
| - if (width == tex_width && height == tex_height) { |
| - // NOTE: In OpenGL ES 2.0 border is always zero and format is always the |
| - // same as internal_foramt. If that changes we'll need to look them up. |
| - WrappedTexImage2D( |
| - target, level, format, width, height, 0, format, type, data); |
| - texture_manager()->SetLevelCleared(info, target, level); |
| + GLsizei tex_width = 0; |
| + GLsizei tex_height = 0; |
| + bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); |
| + DCHECK(ok); |
| + if (xoffset != 0 || yoffset != 0 || |
| + width != tex_width || height != tex_height) { |
| + if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { |
| + SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D: dimensions too big"); |
| return; |
| } |
| - } |
| - if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { |
| - SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D: dimensions too big"); |
| + glTexSubImage2D( |
| + target, level, xoffset, yoffset, width, height, format, type, data); |
| return; |
| } |
| - glTexSubImage2D( |
| - target, level, xoffset, yoffset, width, height, format, type, data); |
| + |
| + if (teximage2d_faster_than_texsubimage2d_ && !info->IsImmutable()) { |
| + // NOTE: In OpenGL ES 2.0 border is always zero and format is always the |
| + // same as internal_foramt. If that changes we'll need to look them up. |
| + WrappedTexImage2D( |
| + target, level, format, width, height, 0, format, type, data); |
| + } else { |
| + glTexSubImage2D( |
| + target, level, xoffset, yoffset, width, height, format, type, data); |
| + } |
| + texture_manager()->SetLevelCleared(info, target, level); |
|
greggman
2011/12/09 20:22:58
this SetLevelCleared line should move to line 6775
vangelis
2011/12/09 22:53:04
Oops, sorry I missed that. But I probably also nee
vangelis
2011/12/12 18:55:40
Looking at this again, wouldn't calling ClearTextu
|
| } |
| error::Error GLES2DecoderImpl::HandleTexSubImage2D( |
| @@ -7831,11 +7842,16 @@ |
| 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); |
| + GLsizei level_width = width; |
| + GLsizei level_height = height; |
| + for (int ii = 0; ii < levels; ++ii) { |
| + texture_manager()->SetLevelInfo( |
| + feature_info_, info, |
| + target, 0, format, level_width, level_height, 1, 0, format, type, |
| + false); |
| + level_width = level_width >> 1; |
|
greggman
2011/12/09 20:22:58
these need to be level_width = std::max(1, level_w
vangelis
2011/12/12 18:55:40
Done.
|
| + level_height = level_height >> 1; |
| + } |
| info->SetImmutable(true); |
| } |