Attempt to simplify NPOT texture caps. Also fixes case where textures would unnecessa...
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 1 Feb 2011 22:56:16 +0000 (22:56 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 1 Feb 2011 22:56:16 +0000 (22:56 +0000)
git-svn-id: http://skia.googlecode.com/svn/trunk@751 2bbb7eff-a529-9590-31e7-b0007b416f81

gpu/include/GrGpu.h
gpu/src/GrContext.cpp
gpu/src/GrGpu.cpp
gpu/src/GrGpuGL.cpp
src/gpu/SkGpuDevice.cpp

index 5a9281e..2bbb419 100644 (file)
@@ -55,28 +55,6 @@ public:
     static GrGpu* Create(Engine, Platform3DContext context3D);
 
     /**
-     * Describes levels of support for non-power-of-two textures.
-     */
-    enum NPOTTextureTypes {
-        /**
-         *  no support for NPOT textures
-         */
-        kNone_NPOTTextureType,
-        /**
-         *  only clamp is supported for textures
-         */
-        kNoRepeat_NPOTTextureType,
-        /**
-         *  no texture restrictions at all, but rendertargets must be POW2
-         */
-        kNonRendertarget_NPOTTextureType,
-        /**
-         * no POW2 restrictions at all
-         */
-        kFull_NPOTTextureType
-    };
-
-    /**
      * Used to control the level of antialiasing available for a rendertarget.
      * Anti-alias quality levels depend on the underlying API/GPU capabilities.
      */
@@ -173,7 +151,10 @@ public:
     void unimpl(const char[]);
 
     /**
-     * Creates a texture object
+     * Creates a texture object. If desc width or height is not a power of
+     * two but underlying API requires a power of two texture then srcData
+     * will be embedded in a power of two texture. The extra width and height
+     * is filled as though srcData were rendered clamped into the texture.
      *
      * @param desc        describes the texture to be created.
      * @param srcData     texel data to load texture. Begins with full-size
@@ -278,14 +259,25 @@ public:
     int minRenderTargetHeight() const  { return fMinRenderTargetHeight; }
 
     /**
-     * Retrieves the level of NPOT texture support. Regardless of support level
-     * NPOT textures can always be created, but internally they may be imbedded
-     * in a POT texture. An exception is paletted textures which must be
-     * specified as a POT when npotTextureSupport() is not Full.
+     * Returns true if NPOT textures can be created
+     *
+     * @return    true if NPOT textures can be created
+     */
+    bool npotTextureSupport() const { return fNPOTTextureSupport; }
+
+    /**
+     * Returns true if NPOT textures can be repeat/mirror tiled.
      *
-     * @return    the level of NPOT texture support.
+     * @return    true if NPOT textures can be tiled
      */
-    NPOTTextureTypes npotTextureSupport() const { return fNPOTTextureSupport; }
+    bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
+
+    /**
+     * Returns true if a NPOT texture can be a rendertarget
+     *
+     * @return    the true if NPOT texture/rendertarget can be created.
+     */
+    bool npotRenderTargetSupport() const { return fNPOTRenderTargetSupport; } 
 
     int maxTextureDimension() const { return fMaxTextureDimension; }
 
@@ -374,8 +366,10 @@ protected:
     // defaults to false, subclass can set true to support palleted textures
     bool f8bitPaletteSupport;
 
-    // defaults to false, subclass can set higher support level
-    NPOTTextureTypes fNPOTTextureSupport;
+    // set by subclass
+    bool fNPOTTextureSupport;
+    bool fNPOTTextureTileSupport;
+    bool fNPOTRenderTargetSupport;
 
     // True if only one stencil pass is required to implement the winding path
     // fill rule. Subclass responsible for setting this value.
index bcccc4e..f966c2c 100644 (file)
@@ -260,22 +260,21 @@ bool GrContext::supportsIndex8PixelConfig(const GrSamplerState& sampler,
         return false;\r
     }\r
 \r
-    bool needsRepeat = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||\r
-                       sampler.getWrapY() != GrSamplerState::kClamp_WrapMode;\r
+\r
     bool isPow2 = GrIsPow2(width) && GrIsPow2(height);\r
 \r
-    switch (fGpu->npotTextureSupport()) {\r
-        case GrGpu::kNone_NPOTTextureType:\r
-            return isPow2;\r
-        case GrGpu::kNoRepeat_NPOTTextureType:\r
-            return isPow2 || !needsRepeat;\r
-        case GrGpu::kNonRendertarget_NPOTTextureType:\r
-        case GrGpu::kFull_NPOTTextureType:\r
-            return true;\r
+    if (!isPow2) {\r
+        if (!fGpu->npotTextureSupport()) {\r
+            return false;\r
+        }\r
+\r
+        bool tiled = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||\r
+                     sampler.getWrapY() != GrSamplerState::kClamp_WrapMode;\r
+        if (tiled && !fGpu->npotTextureTileSupport()) {\r
+            return false;\r
+        }\r
     }\r
-    // should never get here\r
-    GrAssert(!"Bad enum from fGpu->npotTextureSupport");\r
-    return false;\r
+    return true;\r
 }\r
 \r
 ////////////////////////////////////////////////////////////////////////////////\r
@@ -1141,10 +1140,15 @@ bool GrContext::finalizeTextureKey(GrTextureKey* key,
     uint32_t bits = 0;\r
     uint16_t width = key->width();\r
     uint16_t height = key->height();\r
-    if (fGpu->npotTextureSupport() < GrGpu::kNonRendertarget_NPOTTextureType) {\r
-        if ((sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||\r
-             sampler.getWrapY() != GrSamplerState::kClamp_WrapMode) &&\r
-            (!GrIsPow2(width) || !GrIsPow2(height))) {\r
+    \r
+\r
+    if (!fGpu->npotTextureTileSupport()) {\r
+        bool isPow2 = GrIsPow2(width) && GrIsPow2(height);\r
+\r
+        bool tiled = (sampler.getWrapX() != GrSamplerState::kClamp_WrapMode) ||\r
+                     (sampler.getWrapY() != GrSamplerState::kClamp_WrapMode);\r
+\r
+        if (tiled && !isPow2) {\r
             bits |= 1;\r
             bits |= sampler.isFilter() ? 2 : 0;\r
         }\r
index 3624747..057a8c9 100644 (file)
@@ -57,7 +57,6 @@ bool GrTexture::PixelConfigIsOpaque(PixelConfig config) {
 extern void gr_run_unittests();
 
 GrGpu::GrGpu() : f8bitPaletteSupport(false),
-                 fNPOTTextureSupport(kNone_NPOTTextureType),
                  fQuadIndexBuffer(NULL),
                  fUnitSquareVertexBuffer(NULL) {
 #if GR_DEBUG
index fb23152..3d86d1b 100644 (file)
@@ -250,18 +250,20 @@ GrGpuGL::GrGpuGL() {
     }
 
 #if GR_SUPPORT_GLDESKTOP
-    fNPOTTextureSupport =
-        (major >= 2 || has_gl_extension("GL_ARB_texture_non_power_of_two")) ?
-            kFull_NPOTTextureType :
-            kNone_NPOTTextureType;
+    if (major >= 2 || has_gl_extension("GL_ARB_texture_non_power_of_two")) {
+        fNPOTTextureTileSupport = true;
+        fNPOTTextureSupport = true;
+    } else {
+        fNPOTTextureTileSupport = false;
+        fNPOTTextureSupport = false;
+    }
 #else
-    if (has_gl_extension("GL_OES_texture_npot")) {
-        fNPOTTextureSupport = kFull_NPOTTextureType;
-    } else if (major >= 2 ||
-               has_gl_extension("GL_APPLE_texture_2D_limited_npot")) {
-        fNPOTTextureSupport = kNoRepeat_NPOTTextureType;
+    if (major >= 2) {
+        fNPOTTextureSupport = true;
+        fNPOTTextureTileSupport = has_gl_extension("GL_OES_texture_npot");
     } else {
-        fNPOTTextureSupport = kNone_NPOTTextureType;
+        fNPOTTextureSupport = has_gl_extension("GL_APPLE_texture_2D_limited_npot");
+        fNPOTTextureTileSupport = false;
     }
 #endif
     ////////////////////////////////////////////////////////////////////////////
@@ -269,16 +271,16 @@ GrGpuGL::GrGpuGL() {
     // these a preprocess that generate some compile time constants.
 
     // sanity check to make sure we can at least create an FBO from a POT texture
-    if (fNPOTTextureSupport < kFull_NPOTTextureType) {
-        bool npotFBOSuccess = fbo_test(fExts, 128, 128);
-        if (gPrintStartupSpew) {
-            if (!npotFBOSuccess) {
-                GrPrintf("FBO Sanity Test: FAILED\n");
-            } else {
-                GrPrintf("FBO Sanity Test: PASSED\n");
-            }
+    
+    bool simpleFBOSuccess = fbo_test(fExts, 128, 128);
+    if (gPrintStartupSpew) {
+        if (!simpleFBOSuccess) {
+            GrPrintf("FBO Sanity Test: FAILED\n");
+        } else {
+            GrPrintf("FBO Sanity Test: PASSED\n");
         }
     }
+    GrAssert(simpleFBOSuccess);
 
     /* Experimentation has found that some GLs that support NPOT textures
        do not support FBOs with a NPOT texture. They report "unsupported" FBO
@@ -287,34 +289,26 @@ GrGpuGL::GrGpuGL() {
        texture. Presumably, the implementation bloats the renderbuffer
        internally to the next POT.
      */
-    if (fNPOTTextureSupport == kFull_NPOTTextureType) {
-        bool npotFBOSuccess = fbo_test(fExts, 200, 200);
-        if (!npotFBOSuccess) {
-            fNPOTTextureSupport = kNonRendertarget_NPOTTextureType;
-            if (gPrintStartupSpew) {
-                GrPrintf("NPOT Renderbuffer Test: FAILED\n");
-            }
-        } else {
-            if (gPrintStartupSpew) {
-                GrPrintf("NPOT Renderbuffer Test: PASSED\n");
-            }
-        }
+    bool fNPOTRenderTargetSupport = false;
+    if (fNPOTTextureSupport) {
+        fNPOTRenderTargetSupport = fbo_test(fExts, 200, 200);
     }
-
+    
     if (gPrintStartupSpew) {
-        switch (fNPOTTextureSupport) {
-        case kNone_NPOTTextureType:
-            GrPrintf("NPOT Support: NONE\n");
-            break;
-        case kNoRepeat_NPOTTextureType:
-            GrPrintf("NPOT Support: NO REPEAT\n");
-            break;
-        case kNonRendertarget_NPOTTextureType:
-            GrPrintf("NPOT Support: NO FBOTEX\n");
-            break;
-        case kFull_NPOTTextureType:
-            GrPrintf("NPOT Support: FULL\n");
-            break;
+        if (fNPOTTextureSupport) {
+            GrPrintf("NPOT textures supported\n");
+            if (fNPOTTextureTileSupport) {
+                GrPrintf("NPOT texture tiling supported\n");
+            } else {
+                GrPrintf("NPOT texture tiling NOT supported\n");
+            }
+            if (fNPOTRenderTargetSupport) {
+                GrPrintf("NPOT render targets supported\n");
+            } else {
+                GrPrintf("NPOT render targets NOT supported\n");
+            }
+        } else {
+            GrPrintf("NPOT textures NOT supported\n");
         }
     }
 
@@ -329,8 +323,8 @@ GrGpuGL::GrGpuGL() {
     if (gPrintStartupSpew) {
         GrPrintf("Small height FBO texture experiments\n");
     }
-    for (GLuint i = 1; i <= 256;
-         (kFull_NPOTTextureType != fNPOTTextureSupport) ? i *= 2 : ++i) {
+
+    for (GLuint i = 1; i <= 256; fNPOTRenderTargetSupport ? ++i : i *= 2) {
         GLuint w = maxRenderSize;
         GLuint h = i;
         if (fbo_test(fExts, w, h)) {
@@ -351,8 +345,7 @@ GrGpuGL::GrGpuGL() {
         GrPrintf("Small width FBO texture experiments\n");
     }
     fMinRenderTargetWidth = GR_MAX_GLUINT;
-    for (GLuint i = 1; i <= 256;
-         (kFull_NPOTTextureType != fNPOTTextureSupport) ? i *= 2 : ++i) {
+    for (GLuint i = 1; i <= 256; fNPOTRenderTargetSupport ? i *= 2 : ++i) {
         GLuint w = i;
         GLuint h = maxRenderSize;
         if (fbo_test(fExts, w, h)) {
@@ -369,22 +362,7 @@ GrGpuGL::GrGpuGL() {
     }
     GrAssert(GR_INVAL_GLINT != fMinRenderTargetWidth);
 
-#if GR_IOS_BUILD
-    /*
-        The iPad seems to fail, at least sometimes, if the height is < 16,
-        so we pin the values here for now. A better fix might be to
-        conditionalize this based on known that its an iPad (or some other
-        check).
-     */
-    fMinRenderTargetWidth = GrMax<GLuint>(fMinRenderTargetWidth, 16);
-    fMinRenderTargetHeight = GrMax<GLuint>(fMinRenderTargetHeight, 16);
-#endif
-
     GR_GL_GetIntegerv(GL_MAX_TEXTURE_SIZE, &fMaxTextureDimension);
-
-#if GR_COLLECT_STATS
-    ++fStats.fRenderTargetChngCnt;
-#endif
 }
 
 GrGpuGL::~GrGpuGL() {
@@ -607,18 +585,19 @@ GrTexture* GrGpuGL::createTexture(const TextureDesc& desc,
     }
 #endif
 
-    if (fNPOTTextureSupport < kNonRendertarget_NPOTTextureType ||
-        (fNPOTTextureSupport == kNonRendertarget_NPOTTextureType &&
-         renderTarget)) {
-        glDesc.fAllocWidth  = GrNextPow2(desc.fWidth);
-        glDesc.fAllocHeight = GrNextPow2(desc.fHeight);
-    }
-
     if (renderTarget) {
+        if (!this->npotRenderTargetSupport()) {
+            glDesc.fAllocWidth  = GrNextPow2(desc.fWidth);
+            glDesc.fAllocHeight = GrNextPow2(desc.fHeight);
+        }
+
         glDesc.fAllocWidth = GrMax<int>(fMinRenderTargetWidth,
                                         glDesc.fAllocWidth);
         glDesc.fAllocHeight = GrMax<int>(fMinRenderTargetHeight,
                                          glDesc.fAllocHeight);
+    } else if (!this->npotTextureSupport()) {
+        glDesc.fAllocWidth  = GrNextPow2(desc.fWidth);
+        glDesc.fAllocHeight = GrNextPow2(desc.fHeight);
     }
 
     GR_GL(BindTexture(GL_TEXTURE_2D, glDesc.fTextureID));
index 3afd46c..5059569 100644 (file)
@@ -405,7 +405,7 @@ bool SkGpuDevice::skPaint2GrPaintShader(const SkPaint& skPaint,
         return false;
     }
     grPaint->fSampler.setSampleMode(sampleMode);
-
+    grPaint->fSampler.setFilter(skPaint.isFilterBitmap());
     grPaint->fSampler.setWrapX(sk_tile_mode_to_grwrap(tileModes[0]));
     grPaint->fSampler.setWrapY(sk_tile_mode_to_grwrap(tileModes[1]));