| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| ===================================================================
|
| --- gpu/command_buffer/service/gles2_cmd_decoder.cc (revision 114475)
|
| +++ gpu/command_buffer/service/gles2_cmd_decoder.cc (working copy)
|
| @@ -912,7 +912,8 @@
|
| unsigned format,
|
| unsigned type,
|
| int width,
|
| - int height);
|
| + int height,
|
| + bool is_texture_immutable);
|
|
|
| // Restore all GL state that affects clearing.
|
| void RestoreClearState();
|
| @@ -3244,7 +3245,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;
|
| @@ -6155,7 +6156,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(
|
| @@ -6165,8 +6167,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;
|
| @@ -6511,19 +6518,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
|
| @@ -6614,7 +6621,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;
|
| }
|
| @@ -6764,28 +6772,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);
|
| }
|
|
|
| error::Error GLES2DecoderImpl::HandleTexSubImage2D(
|
| @@ -7843,11 +7854,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 = std::max(1, level_width >> 1);
|
| + level_height = std::max(1, level_height >> 1);
|
| + }
|
| info->SetImmutable(true);
|
| }
|
|
|
|
|