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);
}
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() {
#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.
// 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(); }
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; }
// 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.
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;
};
// 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),
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,
private:
GrContext* fContext; // not reffed (context refs gpu)
- ResetContextTimestamp fResetTimestamp;
+ ResetTimestamp fResetTimestamp;
GrVertexBufferAllocPool* fVertexPool;
&texDesc.fUploadType)) {
return NULL;
}
-
- GrGLTexture::TexParams params;
-
texDesc.fAllocWidth = texDesc.fContentWidth = desc.fWidth;
texDesc.fAllocHeight = texDesc.fContentHeight = desc.fHeight;
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;
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);
}
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());
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,
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());
}
}