Use timestamp to detect when client GL calls could cause Gr's cache of glTexParam...
authorbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Sat, 5 Nov 2011 21:21:13 +0000 (21:21 +0000)
committerbsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Sat, 5 Nov 2011 21:21:13 +0000 (21:21 +0000)
git-svn-id: http://skia.googlecode.com/svn/trunk@2609 2bbb7eff-a529-9590-31e7-b0007b416f81

src/gpu/GrGLTexture.cpp
src/gpu/GrGLTexture.h
src/gpu/GrGpu.h
src/gpu/GrGpuGL.cpp

index 7ff6588084f435b1e2f76f66d05ec3d41343cbd4..34ddb851a777537f6bd20874c843edbd125531a1 100644 (file)
@@ -37,12 +37,12 @@ const GrGLenum* GrGLTexture::WrapMode2GLWrap(GrGLBinding binding) {
 
 void GrGLTexture::init(GrGpuGL* gpu,
                        const Desc& textureDesc,
-                       const GrGLRenderTarget::Desc* rtDesc,
-                       const TexParams& initialTexParams) {
+                       const GrGLRenderTarget::Desc* rtDesc) {
 
     GrAssert(0 != textureDesc.fTextureID);
 
-    fTexParams          = initialTexParams;
+    fTexParams.invalidate();
+    fTexParamsTimestamp = GrGpu::kExpiredTimestamp;
     fTexIDObj           = new GrGLTexID(GPUGL->glInterface(),
                                         textureDesc.fTextureID,
                                         textureDesc.fOwnsID);
@@ -67,28 +67,26 @@ void GrGLTexture::init(GrGpuGL* gpu,
 }
 
 GrGLTexture::GrGLTexture(GrGpuGL* gpu,
-                         const Desc& textureDesc,
-                         const TexParams& initialTexParams) 
+                         const Desc& textureDesc) 
     : INHERITED(gpu,
                 textureDesc.fContentWidth,
                 textureDesc.fContentHeight,
                 textureDesc.fAllocWidth,
                 textureDesc.fAllocHeight,
                 textureDesc.fConfig) {
-    this->init(gpu, textureDesc, NULL, initialTexParams);
+    this->init(gpu, textureDesc, NULL);
 }
 
 GrGLTexture::GrGLTexture(GrGpuGL* gpu,
                          const Desc& textureDesc,
-                         const GrGLRenderTarget::Desc& rtDesc,
-                         const TexParams& initialTexParams)
+                         const GrGLRenderTarget::Desc& rtDesc)
     : INHERITED(gpu,
                 textureDesc.fContentWidth,
                 textureDesc.fContentHeight,
                 textureDesc.fAllocWidth,
                 textureDesc.fAllocHeight,
                 textureDesc.fConfig) {
-    this->init(gpu, textureDesc, &rtDesc, initialTexParams);
+    this->init(gpu, textureDesc, &rtDesc);
 }
 
 void GrGLTexture::onRelease() {
index 49002af62a514bacf73c8d095478d5ed6fe4eaaf..1f9636a181c1bb3a73d1ab9128afc5ecd2f7ec59 100644 (file)
@@ -10,9 +10,8 @@
 #ifndef GrGLTexture_DEFINED
 #define GrGLTexture_DEFINED
 
+#include "GrGpu.h"
 #include "GrGLRenderTarget.h"
-#include "GrScalar.h"
-#include "GrTexture.h"
 
 /**
  * A ref counted tex id that deletes the texture in its destructor.
@@ -75,13 +74,11 @@ public:
     // creates a texture that is also an RT
     GrGLTexture(GrGpuGL* gpu,
                 const Desc& textureDesc,
-                const GrGLRenderTarget::Desc& rtDesc,
-                const TexParams& initialTexParams);
+                const GrGLRenderTarget::Desc& rtDesc);
 
     // creates a non-RT texture
     GrGLTexture(GrGpuGL* gpu,
-                const Desc& textureDesc,
-                const TexParams& initialTexParams);
+                const Desc& textureDesc);
 
 
     virtual ~GrGLTexture() { this->release(); }
@@ -95,8 +92,16 @@ public:
                                    size_t rowBytes);
     virtual intptr_t getTextureHandle() const;
 
-    const TexParams& getTexParams() const { return fTexParams; }
-    void setTexParams(const TexParams& texParams) { fTexParams = texParams; }
+    // these functions 
+    const TexParams& getCachedTexParams(GrGpu::ResetTimestamp* timestamp) const {
+        *timestamp = fTexParamsTimestamp;
+        return fTexParams;
+    }
+    void setCachedTexParams(const TexParams& texParams,
+                            GrGpu::ResetTimestamp timestamp) {
+        fTexParams = texParams;
+        fTexParamsTimestamp = timestamp;
+    }
     GrGLuint textureID() const { return fTexIDObj->id(); }
 
     GrGLenum uploadFormat() const { return fUploadFormat; }
@@ -116,7 +121,7 @@ public:
     // in the top-left corner of the image. OpenGL, however,
     // has the origin in the lower-left corner. For content that
     // is loaded by Ganesh we just push the content "upside down"
-    // (by GL's understanding of the world ) in glTex*Image and the
+    // (by GL's understanding of the world) in glTex*Image and the
     // addressing just works out. However, content generated by GL
     // (FBO or externally imported texture) will be updside down
     // and it is up to the GrGpuGL derivative to handle y-mirroing.
@@ -131,19 +136,19 @@ protected:
     virtual void onRelease();
 
 private:
-    TexParams           fTexParams;
-    GrGLTexID*          fTexIDObj;
-    GrGLenum            fUploadFormat;
-    GrGLenum            fUploadType;
+    TexParams                       fTexParams;
+    GrGpu::ResetTimestamp           fTexParamsTimestamp;
+    GrGLTexID*                      fTexIDObj;
+    GrGLenum                        fUploadFormat;
+    GrGLenum                        fUploadType;
     // precomputed content / alloc ratios
-    GrScalar            fScaleX;
-    GrScalar            fScaleY;
-    Orientation         fOrientation;
+    GrScalar                        fScaleX;
+    GrScalar                        fScaleY;
+    Orientation                     fOrientation;
 
     void init(GrGpuGL* gpu,
               const Desc& textureDesc,
-              const GrGLRenderTarget::Desc* rtDesc,
-              const TexParams& initialTexParams);
+              const GrGLRenderTarget::Desc* rtDesc);
 
     typedef GrTexture INHERITED;
 };
index abcd8ac4b5245c9b22fd72f1023d605e41c0ac66..5d9cf4fd482f96747cbcd8177fc0ff57f03328ab 100644 (file)
@@ -223,6 +223,23 @@ public:
     // GrDrawTarget overrides
     virtual void clear(const GrIRect* rect, GrColor color);
 
+    // After the client interacts directly with the 3D context state the GrGpu
+    // must resync its internal state and assumptions about 3D context state.
+    // Each time this occurs the GrGpu bumps a timestamp.
+    // state of the 3D context
+    // At 10 resets / frame and 60fps a 64bit timestamp will overflow in about
+    // a billion years.
+    typedef uint64_t ResetTimestamp;
+
+    // This timestamp is always older than the current timestamp
+    static const ResetTimestamp kExpiredTimestamp = 0;
+    // Returns a timestamp based on the number of times the context was reset.
+    // This timestamp can be used to lazily detect when cached 3D context state
+    // is dirty.
+    ResetTimestamp getResetTimestamp() const {
+        return fResetTimestamp;
+    }
+
 protected:
     enum PrivateStateBits {
         kFirstBit = (kLastPublicStateBit << 1),
@@ -288,19 +305,10 @@ protected:
     void finalizeReservedVertices();
     void finalizeReservedIndices();
 
-    // at 10 resets / frame and 60fps a 64bit timestamp will overflow in about
-    // a billion years.
-    typedef uint64_t ResetContextTimestamp;
-    
     // called when the 3D context state is unknown. Subclass should emit any
     // assumed 3D context state and dirty any state cache
     virtual void onResetContext() = 0;
 
-    // returns the number of times the context was reset. This timestamp can be
-    // used to lazily detect when cached 3D context state is dirty.
-    ResetContextTimestamp resetContextTimestamp() const {
-        return fResetTimestamp;
-    }
     
     // overridden by API-specific derived class to create objects.
     virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
@@ -374,7 +382,7 @@ protected:
 private:
     GrContext*                  fContext; // not reffed (context refs gpu)
     
-    ResetContextTimestamp       fResetTimestamp;
+    ResetTimestamp              fResetTimestamp;
 
     GrVertexBufferAllocPool*    fVertexPool;
 
index 1b06a4d5882d33c0bb96f82481f956c1bd294257..10c0fa61578c89754baafac42f2cc14ebcf14078 100644 (file)
@@ -681,9 +681,6 @@ GrResource* GrGpuGL::onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc)
                          &texDesc.fUploadType)) {
             return NULL;
         }
-
-        GrGLTexture::TexParams params;
-
         texDesc.fAllocWidth  = texDesc.fContentWidth  = desc.fWidth;
         texDesc.fAllocHeight = texDesc.fContentHeight = desc.fHeight;
 
@@ -691,14 +688,13 @@ GrResource* GrGpuGL::onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc)
         texDesc.fOrientation        = GrGLTexture::kBottomUp_Orientation;
         texDesc.fTextureID          = desc.fPlatformTexture;
         texDesc.fOwnsID             = false;
-
-        params.invalidate(); // rather than do glGets.
+        
         if (isRenderTarget) {
-            GrTexture* tex = new GrGLTexture(this, texDesc, rtDesc, params);
+            GrTexture* tex = new GrGLTexture(this, texDesc, rtDesc);
             tex->asRenderTarget()->setStencilBuffer(sb.get());
             return tex;
         } else {
-            return new GrGLTexture(this, texDesc, params);
+            return new GrGLTexture(this, texDesc);
         }
     } else {
         GrGLIRect viewport;
@@ -1057,10 +1053,11 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
             GL_CALL(DeleteTextures(1, &glTexDesc.fTextureID));
             return return_null_texture();
         }
-        tex = new GrGLTexture(this, glTexDesc, glRTDesc, DEFAULT_PARAMS);
+        tex = new GrGLTexture(this, glTexDesc, glRTDesc);
     } else {
-        tex = new GrGLTexture(this, glTexDesc, DEFAULT_PARAMS);
+        tex = new GrGLTexture(this, glTexDesc);
     }
+    tex->setCachedTexParams(DEFAULT_PARAMS, this->getResetTimestamp());
 #ifdef TRACE_TEXTURE_CREATION
     GrPrintf("--- new texture [%d] size=(%d %d) config=%d\n",
              glTexDesc.fTextureID, desc.fWidth, desc.fHeight, desc.fConfig);
@@ -1952,8 +1949,10 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
             }
 
             const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
+            ResetTimestamp timestamp;
             const GrGLTexture::TexParams& oldTexParams =
-                                                nextTexture->getTexParams();
+                                    nextTexture->getCachedTexParams(&timestamp);
+            bool setAll = timestamp < this->getResetTimestamp();
             GrGLTexture::TexParams newTexParams;
 
             newTexParams.fFilter = grToGLFilter(sampler.getFilter());
@@ -1962,8 +1961,7 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
                                 GrGLTexture::WrapMode2GLWrap(this->glBinding());
             newTexParams.fWrapS = wraps[sampler.getWrapX()];
             newTexParams.fWrapT = wraps[sampler.getWrapY()];
-
-            if (newTexParams.fFilter != oldTexParams.fFilter) {
+            if (setAll) {
                 setTextureUnit(s);
                 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
                                       GR_GL_TEXTURE_MAG_FILTER,
@@ -1971,20 +1969,37 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
                 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
                                       GR_GL_TEXTURE_MIN_FILTER,
                                       newTexParams.fFilter));
-            }
-            if (newTexParams.fWrapS != oldTexParams.fWrapS) {
-                setTextureUnit(s);
                 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
                                       GR_GL_TEXTURE_WRAP_S,
                                       newTexParams.fWrapS));
-            }
-            if (newTexParams.fWrapT != oldTexParams.fWrapT) {
-                setTextureUnit(s);
                 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
                                       GR_GL_TEXTURE_WRAP_T,
                                       newTexParams.fWrapT));
+            } else {
+                if (newTexParams.fFilter != oldTexParams.fFilter) {
+                    setTextureUnit(s);
+                    GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+                                          GR_GL_TEXTURE_MAG_FILTER,
+                                          newTexParams.fFilter));
+                    GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+                                          GR_GL_TEXTURE_MIN_FILTER,
+                                          newTexParams.fFilter));
+                }
+                if (newTexParams.fWrapS != oldTexParams.fWrapS) {
+                    setTextureUnit(s);
+                    GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+                                          GR_GL_TEXTURE_WRAP_S,
+                                          newTexParams.fWrapS));
+                }
+                if (newTexParams.fWrapT != oldTexParams.fWrapT) {
+                    setTextureUnit(s);
+                    GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
+                                          GR_GL_TEXTURE_WRAP_T,
+                                          newTexParams.fWrapT));
+                }
             }
-            nextTexture->setTexParams(newTexParams);
+            nextTexture->setCachedTexParams(newTexParams,
+                                            this->getResetTimestamp());
         }
     }