Make RT & TEX base classes aware of NPOT/min-RT bloated size

Review URL: http://codereview.appspot.com/4849045/


git-svn-id: http://skia.googlecode.com/svn/trunk@2057 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrRenderTarget.h b/gpu/include/GrRenderTarget.h
index 06d62a4..13b1a3ac 100644
--- a/gpu/include/GrRenderTarget.h
+++ b/gpu/include/GrRenderTarget.h
@@ -44,6 +44,20 @@
     int height() const { return fHeight; }
 
     /**
+     * Retrieves the allocated width. It may differ from width for
+     * NPOT or min-RT size reasons.
+     * @return allocated width in pixels
+     */
+    int allocatedWidth() const { return fAllocatedWidth; }
+
+    /**
+     * Retrieves the allocated height. It may differ from height for
+     * NPOT or min-RT size reasons.
+     * @return allocated height in pixels
+     */
+    int allocatedHeight() const { return fAllocatedHeight; }
+
+    /**
      * @return the pixel config. Can be kUnknown_GrPixelConfig
      * if client asked us to render to a target that has a pixel
      * config that isn't equivalent with one of our configs.
@@ -151,6 +165,8 @@
                    GrTexture* texture,
                    int width,
                    int height,
+                   int allocatedWidth,
+                   int allocatedHeight,
                    GrPixelConfig config,
                    int sampleCnt)
         : INHERITED(gpu)
@@ -158,6 +174,8 @@
         , fTexture(texture)
         , fWidth(width)
         , fHeight(height)
+        , fAllocatedWidth(allocatedWidth)
+        , fAllocatedHeight(allocatedHeight)
         , fConfig(config)
         , fSampleCnt(sampleCnt)
     {
@@ -181,6 +199,8 @@
     GrTexture*      fTexture; // not ref'ed
     int             fWidth;
     int             fHeight;
+    int             fAllocatedWidth;
+    int             fAllocatedHeight;
     GrPixelConfig   fConfig;
     int             fSampleCnt;
     GrIRect         fResolveRect;
diff --git a/gpu/include/GrTexture.h b/gpu/include/GrTexture.h
index 9bdd340..77f88fa 100644
--- a/gpu/include/GrTexture.h
+++ b/gpu/include/GrTexture.h
@@ -33,6 +33,20 @@
     int height() const { return fHeight; }
 
     /**
+     * Retrieves the allocated width. It may differ from width for
+     * NPOT or min-RT size reasons.
+     * @return allocated width in texels
+     */
+    int allocatedWidth() const { return fAllocatedWidth; }
+
+    /**
+     * Retrieves the allocated height. It may differ from height for
+     * NPOT or min-RT size reasons.
+     * @return allocated height in texels
+     */
+    int allocatedHeight() const { return fAllocatedHeight; }
+
+    /**
      * Convert from texels to normalized texture coords for POT textures
      * only.
      */
@@ -50,7 +64,7 @@
      *  Approximate number of bytes used by the texture
      */
     virtual size_t sizeInBytes() const {
-        return fWidth * fHeight * GrBytesPerPixel(fConfig);
+        return fAllocatedWidth * fAllocatedHeight * GrBytesPerPixel(fConfig);
     }
 
     /**
@@ -125,11 +139,15 @@
     GrTexture(GrGpu* gpu,
               int width,
               int height,
+              int allocatedWidth,
+              int allocatedHeight,
               GrPixelConfig config)
     : INHERITED(gpu)
     , fRenderTarget(NULL)
     , fWidth(width)
     , fHeight(height)
+    , fAllocatedWidth(allocatedWidth)
+    , fAllocatedHeight(allocatedHeight)
     , fConfig(config) {
         // only make sense if alloc size is pow2
         fShiftFixedX = 31 - Gr_clz(fWidth);
@@ -146,6 +164,9 @@
 private:
     int fWidth;
     int fHeight;
+    int fAllocatedWidth;
+    int fAllocatedHeight;
+
     // these two shift a fixed-point value into normalized coordinates
     // for this texture if the texture is power of two sized.
     int      fShiftFixedX;
diff --git a/gpu/src/GrGLRenderTarget.cpp b/gpu/src/GrGLRenderTarget.cpp
index 38b9eb7..39aa332 100644
--- a/gpu/src/GrGLRenderTarget.cpp
+++ b/gpu/src/GrGLRenderTarget.cpp
@@ -30,8 +30,14 @@
                                    const GrGLIRect& viewport,
                                    GrGLTexID* texID,
                                    GrGLTexture* texture)
-    : INHERITED(gpu, texture, viewport.fWidth,
-                viewport.fHeight, desc.fConfig, desc.fSampleCnt) {
+    : INHERITED(gpu,
+                texture,
+                viewport.fWidth,
+                viewport.fHeight,
+                texture->allocatedWidth(),
+                texture->allocatedHeight(),
+                desc.fConfig,
+                desc.fSampleCnt) {
     GrAssert(NULL != texID);
     GrAssert(NULL != texture);
     // FBO 0 can't also be a texture, right?
@@ -43,8 +49,14 @@
 GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
                                    const Desc& desc,
                                    const GrGLIRect& viewport)
-    : INHERITED(gpu, NULL, viewport.fWidth,
-                viewport.fHeight, desc.fConfig, desc.fSampleCnt) {
+    : INHERITED(gpu,
+                NULL,
+                viewport.fWidth,
+                viewport.fHeight,
+                viewport.fWidth,   // don't really need separate alloc w/h for
+                viewport.fHeight,  // non-texture RTs, repeat viewport values
+                desc.fConfig,
+                desc.fSampleCnt) {
     this->init(desc, viewport, NULL);
 }
 
diff --git a/gpu/src/GrGLTexture.cpp b/gpu/src/GrGLTexture.cpp
index caf001a..1dc9c1c 100644
--- a/gpu/src/GrGLTexture.cpp
+++ b/gpu/src/GrGLTexture.cpp
@@ -47,8 +47,6 @@
     fUploadByteCount    = textureDesc.fUploadByteCount;
     fUploadType         = textureDesc.fUploadType;
     fOrientation        = textureDesc.fOrientation;
-    fAllocWidth         = textureDesc.fAllocWidth;
-    fAllocHeight        = textureDesc.fAllocHeight;
     fScaleX             = GrIntToScalar(textureDesc.fContentWidth) /
                             textureDesc.fAllocWidth;
     fScaleY             = GrIntToScalar(textureDesc.fContentHeight) /
@@ -72,6 +70,8 @@
     : INHERITED(gpu,
                 textureDesc.fContentWidth,
                 textureDesc.fContentHeight,
+                textureDesc.fAllocWidth,
+                textureDesc.fAllocHeight,
                 textureDesc.fFormat) {
     this->init(gpu, textureDesc, NULL, initialTexParams);
 }
@@ -83,6 +83,8 @@
     : INHERITED(gpu,
                 textureDesc.fContentWidth,
                 textureDesc.fContentHeight,
+                textureDesc.fAllocWidth,
+                textureDesc.fAllocHeight,
                 textureDesc.fFormat) {
     this->init(gpu, textureDesc, &rtDesc, initialTexParams);
 }
diff --git a/gpu/src/GrGLTexture.h b/gpu/src/GrGLTexture.h
index 61a3f75..6020928 100644
--- a/gpu/src/GrGLTexture.h
+++ b/gpu/src/GrGLTexture.h
@@ -100,20 +100,6 @@
     GrGLenum uploadType() const { return fUploadType; }
 
     /**
-     * Retrieves the texture width actually allocated in texels.
-     *
-     * @return the width in texels
-     */
-    int allocWidth() const { return fAllocWidth; }
-
-    /**
-     * Retrieves the texture height actually allocated in texels.
-     *
-     * @return the height in texels
-     */
-    int allocHeight() const { return fAllocHeight; }
-
-    /**
      * @return width() / allocWidth()
      */
     GrScalar contentScaleX() const { return fScaleX; }
@@ -147,8 +133,6 @@
     GrGLenum            fUploadFormat;
     GrGLenum            fUploadByteCount;
     GrGLenum            fUploadType;
-    int                 fAllocWidth;
-    int                 fAllocHeight;
     // precomputed content / alloc ratios
     GrScalar            fScaleX;
     GrScalar            fScaleY;
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index 4672cff..ad297f4 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -156,8 +156,8 @@
 
 bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
     // TODO: use a cache of stencil buffers rather than create per-rt.
-    bool ret = this->createStencilBufferForRenderTarget(rt, rt->width(),
-                                                        rt->height());
+    bool ret = this->createStencilBufferForRenderTarget(rt, rt->allocatedWidth(),
+                                                        rt->allocatedHeight());
     if (ret) {
         // Right now we're clearing the stencil buffer here after it is
         // attached to an RT for the first time. When we start matching
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index 4c6c60e..7162f35 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -1307,11 +1307,8 @@
     // All internally created RTs are also textures. We don't create
     // SBs for a client's standalone RT (that is RT that isnt also a texture).
     GrAssert(rt->asTexture());
-    // if this thing is bloated for NPOT reasons we'll have to bloat the SB 
-    // as well.
-    GrGLTexture* tex = (GrGLTexture*) rt->asTexture();
-    width = GrMax(width, tex->allocWidth());
-    height = GrMax(height, tex->allocHeight());
+    GrAssert(width >= rt->allocatedWidth());
+    GrAssert(height >= rt->allocatedHeight());
 
     int samples = rt->numSamples();
     GrGLuint sbID;
diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp
index 6d75de8..adac9b0 100644
--- a/gpu/src/GrGpuGLShaders.cpp
+++ b/gpu/src/GrGpuGLShaders.cpp
@@ -462,11 +462,11 @@
     const int& uni = fProgramData->fUniLocations.fStages[s].fNormalizedTexelSizeUni;
     if (GrGLProgram::kUnusedUniform != uni) {
         GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
-        if (texture->allocWidth() != fProgramData->fTextureWidth[s] ||
-            texture->allocHeight() != fProgramData->fTextureWidth[s]) {
+        if (texture->allocatedWidth() != fProgramData->fTextureWidth[s] ||
+            texture->allocatedHeight() != fProgramData->fTextureWidth[s]) {
 
-            float texelSize[] = {1.f / texture->allocWidth(),
-                                 1.f / texture->allocHeight()};
+            float texelSize[] = {1.f / texture->allocatedWidth(),
+                                 1.f / texture->allocatedHeight()};
             GR_GL(Uniform2fv(uni, 1, texelSize));
         }
     }
diff --git a/gpu/src/GrRenderTarget.cpp b/gpu/src/GrRenderTarget.cpp
index 042bc59..8a73a84 100644
--- a/gpu/src/GrRenderTarget.cpp
+++ b/gpu/src/GrRenderTarget.cpp
@@ -31,7 +31,7 @@
     } else {
         colorBits = GrBytesPerPixel(fConfig);
     }
-    return fWidth * fHeight * colorBits;
+    return fAllocatedWidth * fAllocatedHeight * colorBits * GrMax(1,fSampleCnt);
 }
 
 void GrRenderTarget::flagAsNeedingResolve(const GrIRect* rect) {