From: bsalomon@google.com Date: Sat, 5 Nov 2011 21:21:13 +0000 (+0000) Subject: Use timestamp to detect when client GL calls could cause Gr's cache of glTexParam... X-Git-Tag: submit/tizen/20180928.044319~17363 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=80d09b9f7eb653103ca5fa10471e582c44f5b9de;p=platform%2Fupstream%2FlibSkiaSharp.git Use timestamp to detect when client GL calls could cause Gr's cache of glTexParam values to be invalid. git-svn-id: http://skia.googlecode.com/svn/trunk@2609 2bbb7eff-a529-9590-31e7-b0007b416f81 --- diff --git a/src/gpu/GrGLTexture.cpp b/src/gpu/GrGLTexture.cpp index 7ff6588084..34ddb851a7 100644 --- a/src/gpu/GrGLTexture.cpp +++ b/src/gpu/GrGLTexture.cpp @@ -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() { diff --git a/src/gpu/GrGLTexture.h b/src/gpu/GrGLTexture.h index 49002af62a..1f9636a181 100644 --- a/src/gpu/GrGLTexture.h +++ b/src/gpu/GrGLTexture.h @@ -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; }; diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index abcd8ac4b5..5d9cf4fd48 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -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; diff --git a/src/gpu/GrGpuGL.cpp b/src/gpu/GrGpuGL.cpp index 1b06a4d588..10c0fa6157 100644 --- a/src/gpu/GrGpuGL.cpp +++ b/src/gpu/GrGpuGL.cpp @@ -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(×tamp); + 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()); } }