Revert 114133 - Revert 114059 - Fixed service side implementation of glTexStorage2DEXT to only initialize the number of
levels requirested. Also ClearLevel now uses glTexSubImage2D to clear the level if the
texture is immutable.  Finally, rearranged the code in doTexSubImage2D to correctly
bypass clearing a level if the bitmaps supplied matches the dimensions of the texture level.
BUG=106894
Review URL: http://codereview.chromium.org/8872061

Reverting as it may be causing a failure in the XP perf bots:
http://build.chromium.org/p/chromium.perf/builders/XP%20Perf%20%28dbg%29/builds/6854

Un-reverting original change.  It doesn't seem to have been the cause for the regression.


[email protected]
Review URL: http://codereview.chromium.org/8905027

[email protected]
Review URL: http://codereview.chromium.org/8913011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114476 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 9824bdf70..b110751b 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -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);
   }