Fix off-by-one error with the number of storage mip levels.

This caused there to be too few mip levels in the TextureStorage and it
would be discarded if there was a modification to a lower mip.

Also modified Texture::mipLevels to return the number of mip levels rather
than the index of the smallest mip to avoid confusion.

Fixes WebGL D3D9 conformance failures in:
    mipmap-fbo

BUG=angleproject:550

Change-Id: Idf3f543487232edceb520337331b39dab2bd26ba
Reviewed-on: https://chromium-review.googlesource.com/192341
Reviewed-by: Nicolas Capens <nicolascapens@chromium.org>
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index a1a447c..f143994 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -400,7 +400,7 @@
     if ((isPow2(width) && isPow2(height) && isPow2(depth)) || mRenderer->getNonPower2TextureSupport())
     {
         // Maximum number of levels
-        return static_cast<GLint>(log2(std::max(std::max(width, height), depth)));
+        return log2(std::max(std::max(width, height), depth)) + 1;
     }
     else
     {
@@ -411,7 +411,7 @@
 
 int Texture::mipLevels() const
 {
-    return static_cast<int>(log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())));
+    return log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
 }
 
 Texture2D::Texture2D(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_2D)
@@ -800,9 +800,9 @@
 // Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
 bool Texture2D::isMipmapComplete() const
 {
-    int q = mipLevels();
+    int levelCount = mipLevels();
 
-    for (int level = 0; level <= q; level++)
+    for (int level = 0; level < levelCount; level++)
     {
         if (!isLevelComplete(level))
         {
@@ -953,8 +953,8 @@
 void Texture2D::generateMipmaps()
 {
     // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
-    int q = mipLevels();
-    for (int level = 1; level <= q; level++)
+    int levelCount = mipLevels();
+    for (int level = 1; level < levelCount; level++)
     {
         redefineImage(level, getBaseLevelInternalFormat(),
                       std::max(getBaseLevelWidth() >> level, 1),
@@ -963,7 +963,7 @@
 
     if (mTexStorage && mTexStorage->isRenderTarget())
     {
-        for (int level = 1; level <= q; level++)
+        for (int level = 1; level < levelCount; level++)
         {
             mTexStorage->generateMipmap(level);
 
@@ -972,7 +972,7 @@
     }
     else
     {
-        for (int level = 1; level <= q; level++)
+        for (int level = 1; level < levelCount; level++)
         {
             mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
         }
@@ -1255,11 +1255,11 @@
         return false;
     }
 
-    int q = mipLevels();
+    int levelCount = mipLevels();
 
     for (int face = 0; face < 6; face++)
     {
-        for (int level = 1; level <= q; level++)
+        for (int level = 1; level < levelCount; level++)
         {
             if (!isFaceLevelComplete(face, level))
             {
@@ -1585,10 +1585,10 @@
 void TextureCubeMap::generateMipmaps()
 {
     // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
-    int q = mipLevels();
+    int levelCount = mipLevels();
     for (int faceIndex = 0; faceIndex < 6; faceIndex++)
     {
-        for (int level = 1; level <= q; level++)
+        for (int level = 1; level < levelCount; level++)
         {
             int faceLevelSize = (std::max(mImageArray[faceIndex][0]->getWidth() >> level, 1));
             redefineImage(faceIndex, level, mImageArray[faceIndex][0]->getInternalFormat(), faceLevelSize, faceLevelSize);
@@ -1599,7 +1599,7 @@
     {
         for (int faceIndex = 0; faceIndex < 6; faceIndex++)
         {
-            for (int level = 1; level <= q; level++)
+            for (int level = 1; level < levelCount; level++)
             {
                 mTexStorage->generateMipmap(faceIndex, level);
 
@@ -1611,7 +1611,7 @@
     {
         for (int faceIndex = 0; faceIndex < 6; faceIndex++)
         {
-            for (int level = 1; level <= q; level++)
+            for (int level = 1; level < levelCount; level++)
             {
                 mRenderer->generateMipmap(mImageArray[faceIndex][level], mImageArray[faceIndex][level - 1]);
             }
@@ -1853,8 +1853,8 @@
 void Texture3D::generateMipmaps()
 {
     // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
-    int q = mipLevels();
-    for (int level = 1; level <= q; level++)
+    int levelCount = mipLevels();
+    for (int level = 1; level < levelCount; level++)
     {
         redefineImage(level, getBaseLevelInternalFormat(),
                       std::max(getBaseLevelWidth() >> level, 1),
@@ -1864,7 +1864,7 @@
 
     if (mTexStorage && mTexStorage->isRenderTarget())
     {
-        for (int level = 1; level <= q; level++)
+        for (int level = 1; level < levelCount; level++)
         {
             mTexStorage->generateMipmap(level);
 
@@ -1873,7 +1873,7 @@
     }
     else
     {
-        for (int level = 1; level <= q; level++)
+        for (int level = 1; level < levelCount; level++)
         {
             mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
         }
@@ -1959,9 +1959,9 @@
 
 bool Texture3D::isMipmapComplete() const
 {
-    int q = mipLevels();
+    int levelCount = mipLevels();
 
-    for (int level = 0; level <= q; level++)
+    for (int level = 0; level < levelCount; level++)
     {
         if (!isLevelComplete(level))
         {
@@ -2407,15 +2407,15 @@
     GLenum baseFormat = getBaseLevelInternalFormat();
 
     // Purge array levels 1 through q and reset them to represent the generated mipmap levels.
-    int q = mipLevels();
-    for (int level = 1; level <= q; level++)
+    int levelCount = mipLevels();
+    for (int level = 1; level < levelCount; level++)
     {
         redefineImage(level, baseFormat, std::max(baseWidth >> level, 1), std::max(baseHeight >> level, 1), baseDepth);
     }
 
     if (mTexStorage && mTexStorage->isRenderTarget())
     {
-        for (int level = 1; level <= q; level++)
+        for (int level = 1; level < levelCount; level++)
         {
             mTexStorage->generateMipmap(level);
 
@@ -2427,7 +2427,7 @@
     }
     else
     {
-        for (int level = 1; level <= q; level++)
+        for (int level = 1; level < levelCount; level++)
         {
             for (int layer = 0; layer < mLayerCounts[level]; layer++)
             {
@@ -2515,9 +2515,9 @@
 
 bool Texture2DArray::isMipmapComplete() const
 {
-    int q = mipLevels();
+    int levelCount = mipLevels();
 
-    for (int level = 1; level <= q; level++)
+    for (int level = 1; level < levelCount; level++)
     {
         if (!isLevelComplete(level))
         {