Add API to invalidate GL texture parameters from GrBackendTexture.
This is modeled on how we coordinate VkImage layout changes between
GrContext and clients.
A type GrGLTextureParameters is used to track the current parameter
state.
When a client creates a GrBackendTexture in order to wrap a resource
they created a new GrGLTextureParameters is created and the wrapped
GrGLTexture will share ownership.
When GrContext creates a non-wrapped GrGLTexture, the GrGLTexture
creates a new GrGLTextureParameters and any GrBackendTextures created
from that GrGLTexture will share ownership.
Clients indicate parameter changes by calling
GrBackendTexture::glTextureParametersModified().
We still assume all texture parameters may have changed after a call
to GrContext::resetContext() (for now). The "timestamp" that is used
to implement this has been moved from GrGpu to GrGLGpu as there were
no other use cases.
Change-Id: Ic24e00488fad254a29d5eec6890278b67df6efae
Bug: skia:7966
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/217385
Auto-Submit: Brian Salomon <bsalomon@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 2a9b0f4..8edb3fa 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -655,6 +655,7 @@
fHWProgramID = 0;
fHWProgram.reset();
}
+ ++fResetTimestampForTextureParameters;
}
static bool check_backend_texture(const GrBackendTexture& backendTex, const GrGLCaps& caps,
@@ -706,8 +707,8 @@
GrMipMapsStatus mipMapsStatus = backendTex.hasMipMaps() ? GrMipMapsStatus::kValid
: GrMipMapsStatus::kNotAllocated;
- auto texture =
- GrGLTexture::MakeWrapped(this, surfDesc, mipMapsStatus, idDesc, cacheable, ioType);
+ auto texture = GrGLTexture::MakeWrapped(this, surfDesc, mipMapsStatus, idDesc,
+ backendTex.getGLTextureParams(), cacheable, ioType);
// We don't know what parameters are already set on wrapped textures.
texture->textureParamsModified();
return std::move(texture);
@@ -755,7 +756,8 @@
: GrMipMapsStatus::kNotAllocated;
sk_sp<GrGLTextureRenderTarget> texRT(GrGLTextureRenderTarget::MakeWrapped(
- this, surfDesc, idDesc, rtIDDesc, cacheable, mipMapsStatus));
+ this, surfDesc, idDesc, backendTex.getGLTextureParams(), rtIDDesc, cacheable,
+ mipMapsStatus));
texRT->baseLevelWasBoundToFBO();
// We don't know what parameters are already set on wrapped textures.
texRT->textureParamsModified();
@@ -1564,21 +1566,21 @@
return nullptr;
}
-static GrGLTexture::SamplerParams set_initial_texture_params(const GrGLInterface* interface,
- const GrGLTextureInfo& info) {
+static GrGLTextureParameters::SamplerOverriddenState set_initial_texture_params(
+ const GrGLInterface* interface, const GrGLTextureInfo& info) {
// Some drivers like to know filter/wrap before seeing glTexImage2D. Some
// drivers have a bug where an FBO won't be complete if it includes a
// texture that is not mipmap complete (considering the filter in use).
- GrGLTexture::SamplerParams params;
- params.fMinFilter = GR_GL_NEAREST;
- params.fMagFilter = GR_GL_NEAREST;
- params.fWrapS = GR_GL_CLAMP_TO_EDGE;
- params.fWrapT = GR_GL_CLAMP_TO_EDGE;
- GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_MAG_FILTER, params.fMagFilter));
- GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_MIN_FILTER, params.fMinFilter));
- GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_WRAP_S, params.fWrapS));
- GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_WRAP_T, params.fWrapT));
- return params;
+ GrGLTextureParameters::SamplerOverriddenState state;
+ state.fMinFilter = GR_GL_NEAREST;
+ state.fMagFilter = GR_GL_NEAREST;
+ state.fWrapS = GR_GL_CLAMP_TO_EDGE;
+ state.fWrapT = GR_GL_CLAMP_TO_EDGE;
+ GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_MAG_FILTER, state.fMagFilter));
+ GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_MIN_FILTER, state.fMinFilter));
+ GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_WRAP_S, state.fWrapS));
+ GR_GL_CALL(interface, TexParameteri(info.fTarget, GR_GL_TEXTURE_WRAP_T, state.fWrapT));
+ return state;
}
size_t GLBytesPerPixel(GrGLenum glFormat) {
@@ -1654,10 +1656,10 @@
GrGLTexture::IDDesc idDesc;
idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
GrMipMapsStatus mipMapsStatus;
- GrGLTexture::SamplerParams initialTexParams;
+ GrGLTextureParameters::SamplerOverriddenState initialState;
if (!this->createTextureImpl(desc, &idDesc.fInfo,
isRenderTarget ? GrRenderable::kYes : GrRenderable::kNo,
- &initialTexParams, texels, mipLevelCount, &mipMapsStatus)) {
+ &initialState, texels, mipLevelCount, &mipMapsStatus)) {
return return_null_texture();
}
@@ -1677,9 +1679,9 @@
} else {
tex = sk_make_sp<GrGLTexture>(this, budgeted, desc, idDesc, mipMapsStatus);
}
-
- tex->setCachedParams(&initialTexParams, tex->getCachedNonSamplerParams(),
- this->getResetTimestamp());
+ // The non-sampler params are still at their default values.
+ tex->parameters()->set(&initialState, GrGLTextureParameters::NonsamplerState(),
+ fResetTimestampForTextureParameters);
#ifdef TRACE_TEXTURE_CREATION
SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n",
idDesc.fInfo.fID, desc.fWidth, desc.fHeight, desc.fConfig);
@@ -1842,7 +1844,7 @@
bool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
GrRenderable renderable,
- GrGLTexture::SamplerParams* initialTexParams,
+ GrGLTextureParameters::SamplerOverriddenState* initialState,
const GrMipLevel texels[], int mipLevelCount,
GrMipMapsStatus* mipMapsStatus) {
info->fID = 0;
@@ -1864,7 +1866,7 @@
GR_GL_FRAMEBUFFER_ATTACHMENT));
}
- *initialTexParams = set_initial_texture_params(this->glInterface(), *info);
+ *initialState = set_initial_texture_params(this->glInterface(), *info);
bool success = false;
if (GrGLFormatIsCompressed(info->fFormat)) {
@@ -3052,71 +3054,73 @@
}
#endif
- ResetTimestamp timestamp = texture->getCachedParamsTimestamp();
- bool setAll = timestamp < this->getResetTimestamp();
+ auto timestamp = texture->parameters()->resetTimestamp();
+ bool setAll = timestamp < fResetTimestampForTextureParameters;
- const GrGLTexture::SamplerParams* samplerParamsToRecord = nullptr;
- GrGLTexture::SamplerParams newSamplerParams;
+ const GrGLTextureParameters::SamplerOverriddenState* samplerStateToRecord = nullptr;
+ GrGLTextureParameters::SamplerOverriddenState newSamplerState;
if (fSamplerObjectCache) {
fSamplerObjectCache->bindSampler(unitIdx, samplerState);
} else {
- const GrGLTexture::SamplerParams& oldSamplerParams = texture->getCachedSamplerParams();
- samplerParamsToRecord = &newSamplerParams;
+ const GrGLTextureParameters::SamplerOverriddenState& oldSamplerState =
+ texture->parameters()->samplerOverriddenState();
+ samplerStateToRecord = &newSamplerState;
- newSamplerParams.fMinFilter = filter_to_gl_min_filter(samplerState.filter());
- newSamplerParams.fMagFilter = filter_to_gl_mag_filter(samplerState.filter());
+ newSamplerState.fMinFilter = filter_to_gl_min_filter(samplerState.filter());
+ newSamplerState.fMagFilter = filter_to_gl_mag_filter(samplerState.filter());
- newSamplerParams.fWrapS = wrap_mode_to_gl_wrap(samplerState.wrapModeX(), this->glCaps());
- newSamplerParams.fWrapT = wrap_mode_to_gl_wrap(samplerState.wrapModeY(), this->glCaps());
+ newSamplerState.fWrapS = wrap_mode_to_gl_wrap(samplerState.wrapModeX(), this->glCaps());
+ newSamplerState.fWrapT = wrap_mode_to_gl_wrap(samplerState.wrapModeY(), this->glCaps());
// These are the OpenGL default values.
- newSamplerParams.fMinLOD = -1000.f;
- newSamplerParams.fMaxLOD = 1000.f;
+ newSamplerState.fMinLOD = -1000.f;
+ newSamplerState.fMaxLOD = 1000.f;
- if (setAll || newSamplerParams.fMagFilter != oldSamplerParams.fMagFilter) {
+ if (setAll || newSamplerState.fMagFilter != oldSamplerState.fMagFilter) {
this->setTextureUnit(unitIdx);
- GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newSamplerParams.fMagFilter));
+ GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newSamplerState.fMagFilter));
}
- if (setAll || newSamplerParams.fMinFilter != oldSamplerParams.fMinFilter) {
+ if (setAll || newSamplerState.fMinFilter != oldSamplerState.fMinFilter) {
this->setTextureUnit(unitIdx);
- GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, newSamplerParams.fMinFilter));
+ GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, newSamplerState.fMinFilter));
}
if (this->glCaps().mipMapLevelAndLodControlSupport()) {
- if (setAll || newSamplerParams.fMinLOD != oldSamplerParams.fMinLOD) {
+ if (setAll || newSamplerState.fMinLOD != oldSamplerState.fMinLOD) {
this->setTextureUnit(unitIdx);
- GL_CALL(TexParameterf(target, GR_GL_TEXTURE_MIN_LOD, newSamplerParams.fMinLOD));
+ GL_CALL(TexParameterf(target, GR_GL_TEXTURE_MIN_LOD, newSamplerState.fMinLOD));
}
- if (setAll || newSamplerParams.fMaxLOD != oldSamplerParams.fMaxLOD) {
+ if (setAll || newSamplerState.fMaxLOD != oldSamplerState.fMaxLOD) {
this->setTextureUnit(unitIdx);
- GL_CALL(TexParameterf(target, GR_GL_TEXTURE_MAX_LOD, newSamplerParams.fMaxLOD));
+ GL_CALL(TexParameterf(target, GR_GL_TEXTURE_MAX_LOD, newSamplerState.fMaxLOD));
}
}
- if (setAll || newSamplerParams.fWrapS != oldSamplerParams.fWrapS) {
+ if (setAll || newSamplerState.fWrapS != oldSamplerState.fWrapS) {
this->setTextureUnit(unitIdx);
- GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_S, newSamplerParams.fWrapS));
+ GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_S, newSamplerState.fWrapS));
}
- if (setAll || newSamplerParams.fWrapT != oldSamplerParams.fWrapT) {
+ if (setAll || newSamplerState.fWrapT != oldSamplerState.fWrapT) {
this->setTextureUnit(unitIdx);
- GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newSamplerParams.fWrapT));
+ GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newSamplerState.fWrapT));
}
if (this->glCaps().clampToBorderSupport()) {
// Make sure the border color is transparent black (the default)
- if (setAll || oldSamplerParams.fBorderColorInvalid) {
+ if (setAll || oldSamplerState.fBorderColorInvalid) {
this->setTextureUnit(unitIdx);
static const GrGLfloat kTransparentBlack[4] = {0.f, 0.f, 0.f, 0.f};
GL_CALL(TexParameterfv(target, GR_GL_TEXTURE_BORDER_COLOR, kTransparentBlack));
}
}
}
- GrGLTexture::NonSamplerParams newNonSamplerParams;
- newNonSamplerParams.fBaseMipMapLevel = 0;
- newNonSamplerParams.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel();
+ GrGLTextureParameters::NonsamplerState newNonsamplerState;
+ newNonsamplerState.fBaseMipMapLevel = 0;
+ newNonsamplerState.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel();
- const GrGLTexture::NonSamplerParams& oldNonSamplerParams = texture->getCachedNonSamplerParams();
+ const GrGLTextureParameters::NonsamplerState& oldNonsamplerState =
+ texture->parameters()->nonsamplerState();
if (this->glCaps().textureSwizzleSupport()) {
auto swizzle = this->glCaps().configSwizzle(texture->config());
- newNonSamplerParams.fSwizzleKey = swizzle.asKey();
- if (setAll || swizzle.asKey() != oldNonSamplerParams.fSwizzleKey) {
+ newNonsamplerState.fSwizzleKey = swizzle.asKey();
+ if (setAll || swizzle.asKey() != oldNonsamplerState.fSwizzleKey) {
GrGLenum glValues[4];
get_gl_swizzle_values(swizzle, glValues);
this->setTextureUnit(unitIdx);
@@ -3137,18 +3141,19 @@
if (this->glCaps().mipMapLevelAndLodControlSupport() &&
(texture->texturePriv().textureType() != GrTextureType::kExternal ||
!this->glCaps().dontSetBaseOrMaxLevelForExternalTextures())) {
- if (newNonSamplerParams.fBaseMipMapLevel != oldNonSamplerParams.fBaseMipMapLevel) {
+ if (newNonsamplerState.fBaseMipMapLevel != oldNonsamplerState.fBaseMipMapLevel) {
this->setTextureUnit(unitIdx);
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_BASE_LEVEL,
- newNonSamplerParams.fBaseMipMapLevel));
+ newNonsamplerState.fBaseMipMapLevel));
}
- if (newNonSamplerParams.fMaxMipMapLevel != oldNonSamplerParams.fMaxMipMapLevel) {
+ if (newNonsamplerState.fMaxMipMapLevel != oldNonsamplerState.fMaxMipMapLevel) {
this->setTextureUnit(unitIdx);
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAX_LEVEL,
- newNonSamplerParams.fMaxMipMapLevel));
+ newNonsamplerState.fMaxMipMapLevel));
}
}
- texture->setCachedParams(samplerParamsToRecord, newNonSamplerParams, this->getResetTimestamp());
+ texture->parameters()->set(samplerStateToRecord, newNonsamplerState,
+ fResetTimestampForTextureParameters);
}
void GrGLGpu::onResetTextureBindings() {
@@ -3952,9 +3957,10 @@
GR_GL_TEXTURE_2D, 0, 0));
// We modified the base level param.
- GrGLTexture::NonSamplerParams params = glTex->getCachedNonSamplerParams();
- params.fBaseMipMapLevel = levelCount - 2; // we drew the 2nd to last level into the last level.
- glTex->setCachedParams(nullptr, params, this->getResetTimestamp());
+ GrGLTextureParameters::NonsamplerState nonsamplerState = glTex->parameters()->nonsamplerState();
+ // We drew the 2nd to last level into the last level.
+ nonsamplerState.fBaseMipMapLevel = levelCount - 2;
+ glTex->parameters()->set(nullptr, nonsamplerState, fResetTimestampForTextureParameters);
return true;
}
@@ -4146,17 +4152,20 @@
desc.fConfig = config;
GrGLTextureInfo info;
- GrGLTexture::SamplerParams initialTexParams;
+ GrGLTextureParameters::SamplerOverriddenState initialState;
- if (!this->createTextureImpl(desc, &info, renderable, &initialTexParams,
- texels.get(), mipLevelCount, nullptr)) {
+ if (!this->createTextureImpl(desc, &info, renderable, &initialState, texels.get(),
+ mipLevelCount, nullptr)) {
return GrBackendTexture(); // invalid
}
// unbind the texture from the texture unit to avoid asserts
GL_CALL(BindTexture(info.fTarget, 0));
- GrBackendTexture beTex = GrBackendTexture(w, h, mipMapped, info);
+ auto parameters = sk_make_sp<GrGLTextureParameters>();
+ parameters->set(&initialState, GrGLTextureParameters::NonsamplerState(),
+ fResetTimestampForTextureParameters);
+ GrBackendTexture beTex = GrBackendTexture(w, h, mipMapped, info, std::move(parameters));
#if GR_TEST_UTILS
// Lots of tests don't go through Skia's public interface, which will set the config, so for
// testing we make sure we set a config here.
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 869a3f2..5a6c6d8 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -216,8 +216,9 @@
// The texture is populated with |texels|, if it exists.
// The texture parameters are cached in |initialTexParams|.
bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, GrRenderable,
- GrGLTexture::SamplerParams* initialTexParams, const GrMipLevel texels[],
- int mipLevelCount, GrMipMapsStatus* mipMapsStatus);
+ GrGLTextureParameters::SamplerOverriddenState* initialState,
+ const GrMipLevel texels[], int mipLevelCount,
+ GrMipMapsStatus* mipMapsStatus);
// Checks whether glReadPixels can be called to get pixel values in readConfig from the
// render target.
@@ -665,6 +666,8 @@
GrPrimitiveType fLastPrimitiveType;
+ GrGLTextureParameters::ResetTimestamp fResetTimestampForTextureParameters = 0;
+
class SamplerObjectCache;
std::unique_ptr<SamplerObjectCache> fSamplerObjectCache;
diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp
index 942f125..899ff8c 100644
--- a/src/gpu/gl/GrGLTexture.cpp
+++ b/src/gpu/gl/GrGLTexture.cpp
@@ -45,7 +45,8 @@
GrGLTexture::GrGLTexture(GrGLGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
const IDDesc& idDesc, GrMipMapsStatus mipMapsStatus)
: GrSurface(gpu, desc)
- , INHERITED(gpu, desc, TextureTypeFromTarget(idDesc.fInfo.fTarget), mipMapsStatus) {
+ , INHERITED(gpu, desc, TextureTypeFromTarget(idDesc.fInfo.fTarget), mipMapsStatus)
+ , fParameters(sk_make_sp<GrGLTextureParameters>()) {
this->init(desc, idDesc);
this->registerWithCache(budgeted);
if (GrPixelConfigIsCompressed(desc.fConfig)) {
@@ -54,9 +55,12 @@
}
GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, GrMipMapsStatus mipMapsStatus,
- const IDDesc& idDesc, GrWrapCacheable cacheable, GrIOType ioType)
+ const IDDesc& idDesc, sk_sp<GrGLTextureParameters> parameters,
+ GrWrapCacheable cacheable, GrIOType ioType)
: GrSurface(gpu, desc)
- , INHERITED(gpu, desc, TextureTypeFromTarget(idDesc.fInfo.fTarget), mipMapsStatus) {
+ , INHERITED(gpu, desc, TextureTypeFromTarget(idDesc.fInfo.fTarget), mipMapsStatus)
+ , fParameters(std::move(parameters)) {
+ SkASSERT(fParameters);
this->init(desc, idDesc);
this->registerWithCacheWrapped(cacheable);
if (ioType == kRead_GrIOType) {
@@ -65,16 +69,17 @@
}
GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc,
- GrMipMapsStatus mipMapsStatus)
+ sk_sp<GrGLTextureParameters> parameters, GrMipMapsStatus mipMapsStatus)
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, TextureTypeFromTarget(idDesc.fInfo.fTarget), mipMapsStatus) {
+ SkASSERT(parameters || idDesc.fOwnership == GrBackendObjectOwnership::kOwned);
+ fParameters = parameters ? std::move(parameters) : sk_make_sp<GrGLTextureParameters>();
this->init(desc, idDesc);
}
void GrGLTexture::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
SkASSERT(0 != idDesc.fInfo.fID);
SkASSERT(0 != idDesc.fInfo.fFormat);
- fParamsTimestamp = GrGpu::kExpiredTimestamp;
fID = idDesc.fInfo.fID;
fFormat = idDesc.fInfo.fFormat;
fTextureIDOwnership = idDesc.fOwnership;
@@ -104,7 +109,8 @@
info.fTarget = target_from_texture_type(this->texturePriv().textureType());
info.fID = fID;
info.fFormat = fFormat;
- return GrBackendTexture(this->width(), this->height(), this->texturePriv().mipMapped(), info);
+ return GrBackendTexture(this->width(), this->height(), this->texturePriv().mipMapped(), info,
+ fParameters);
}
GrBackendFormat GrGLTexture::backendFormat() const {
@@ -114,8 +120,10 @@
sk_sp<GrGLTexture> GrGLTexture::MakeWrapped(GrGLGpu* gpu, const GrSurfaceDesc& desc,
GrMipMapsStatus mipMapsStatus, const IDDesc& idDesc,
+ sk_sp<GrGLTextureParameters> parameters,
GrWrapCacheable cacheable, GrIOType ioType) {
- return sk_sp<GrGLTexture>(new GrGLTexture(gpu, desc, mipMapsStatus, idDesc, cacheable, ioType));
+ return sk_sp<GrGLTexture>(new GrGLTexture(gpu, desc, mipMapsStatus, idDesc,
+ std::move(parameters), cacheable, ioType));
}
bool GrGLTexture::onStealBackendTexture(GrBackendTexture* backendTexture,
diff --git a/src/gpu/gl/GrGLTexture.h b/src/gpu/gl/GrGLTexture.h
index 54d419c..cb3f158 100644
--- a/src/gpu/gl/GrGLTexture.h
+++ b/src/gpu/gl/GrGLTexture.h
@@ -10,6 +10,7 @@
#define GrGLTexture_DEFINED
#include "include/gpu/GrTexture.h"
+#include "include/private/GrGLTypesPriv.h"
#include "src/gpu/GrGpu.h"
#include "src/gpu/gl/GrGLUtil.h"
@@ -17,44 +18,6 @@
class GrGLTexture : public GrTexture {
public:
- // Texture state that overlaps with sampler object state. We don't need to track this if we
- // are using sampler objects.
- struct SamplerParams {
- // These are the OpenGL defaults.
- GrGLenum fMinFilter = GR_GL_NEAREST_MIPMAP_LINEAR;
- GrGLenum fMagFilter = GR_GL_LINEAR;
- GrGLenum fWrapS = GR_GL_REPEAT;
- GrGLenum fWrapT = GR_GL_REPEAT;
- GrGLfloat fMinLOD = -1000.f;
- GrGLfloat fMaxLOD = 1000.f;
- // We always want the border color to be transparent black, so no need to store 4 floats.
- // Just track if it's been invalidated and no longer the default
- bool fBorderColorInvalid = false;
-
- void invalidate() {
- fMinFilter = ~0U;
- fMagFilter = ~0U;
- fWrapS = ~0U;
- fWrapT = ~0U;
- fMinLOD = SK_ScalarNaN;
- fMaxLOD = SK_ScalarNaN;
- fBorderColorInvalid = true;
- }
- };
-
- // Texture state that does not overlap with sampler object state.
- struct NonSamplerParams {
- // These are the OpenGL defaults.
- uint32_t fSwizzleKey = GrSwizzle::RGBA().asKey();
- GrGLint fBaseMipMapLevel = 0;
- GrGLint fMaxMipMapLevel = 1000;
- void invalidate() {
- fSwizzleKey = ~0U;
- fBaseMipMapLevel = ~0;
- fMaxMipMapLevel = ~0;
- }
- };
-
struct IDDesc {
GrGLTextureInfo fInfo;
GrBackendObjectOwnership fOwnership;
@@ -70,25 +33,10 @@
GrBackendFormat backendFormat() const override;
- void textureParamsModified() override {
- fSamplerParams.invalidate();
- fNonSamplerParams.invalidate();
- }
+ // TODO: Remove once clients are no longer calling this.
+ void textureParamsModified() override { fParameters->invalidate(); }
- // These functions are used to track the texture parameters associated with the texture.
- GrGpu::ResetTimestamp getCachedParamsTimestamp() const { return fParamsTimestamp; }
- const SamplerParams& getCachedSamplerParams() const { return fSamplerParams; }
- const NonSamplerParams& getCachedNonSamplerParams() const { return fNonSamplerParams; }
-
- void setCachedParams(const SamplerParams* samplerParams,
- const NonSamplerParams& nonSamplerParams,
- GrGpu::ResetTimestamp currTimestamp) {
- if (samplerParams) {
- fSamplerParams = *samplerParams;
- }
- fNonSamplerParams = nonSamplerParams;
- fParamsTimestamp = currTimestamp;
- }
+ GrGLTextureParameters* parameters() { return fParameters.get(); }
GrGLuint textureID() const { return fID; }
@@ -98,17 +46,19 @@
void baseLevelWasBoundToFBO() { fBaseLevelHasBeenBoundToFBO = true; }
static sk_sp<GrGLTexture> MakeWrapped(GrGLGpu*, const GrSurfaceDesc&, GrMipMapsStatus,
- const IDDesc&, GrWrapCacheable, GrIOType);
+ const IDDesc&, sk_sp<GrGLTextureParameters>,
+ GrWrapCacheable, GrIOType);
void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const override;
protected:
// Constructor for subclasses.
- GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, GrMipMapsStatus);
+ GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, sk_sp<GrGLTextureParameters>,
+ GrMipMapsStatus);
// Constructor for instances wrapping backend objects.
- GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, GrMipMapsStatus, const IDDesc&, GrWrapCacheable,
- GrIOType);
+ GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, GrMipMapsStatus, const IDDesc&,
+ sk_sp<GrGLTextureParameters>, GrWrapCacheable, GrIOType);
void init(const GrSurfaceDesc&, const IDDesc&);
@@ -118,9 +68,7 @@
bool onStealBackendTexture(GrBackendTexture*, SkImage::BackendTextureReleaseProc*) override;
private:
- SamplerParams fSamplerParams;
- NonSamplerParams fNonSamplerParams;
- GrGpu::ResetTimestamp fParamsTimestamp;
+ sk_sp<GrGLTextureParameters> fParameters;
GrGLuint fID;
GrGLenum fFormat;
GrBackendObjectOwnership fTextureIDOwnership;
diff --git a/src/gpu/gl/GrGLTextureRenderTarget.cpp b/src/gpu/gl/GrGLTextureRenderTarget.cpp
index ab86162..6739b79 100644
--- a/src/gpu/gl/GrGLTextureRenderTarget.cpp
+++ b/src/gpu/gl/GrGLTextureRenderTarget.cpp
@@ -19,7 +19,7 @@
const GrGLRenderTarget::IDDesc& rtIDDesc,
GrMipMapsStatus mipMapsStatus)
: GrSurface(gpu, desc)
- , GrGLTexture(gpu, desc, texIDDesc, mipMapsStatus)
+ , GrGLTexture(gpu, desc, texIDDesc, nullptr, mipMapsStatus)
, GrGLRenderTarget(gpu, desc, texIDDesc.fInfo.fFormat, rtIDDesc) {
this->registerWithCache(budgeted);
}
@@ -27,11 +27,12 @@
GrGLTextureRenderTarget::GrGLTextureRenderTarget(GrGLGpu* gpu,
const GrSurfaceDesc& desc,
const GrGLTexture::IDDesc& texIDDesc,
+ sk_sp<GrGLTextureParameters> parameters,
const GrGLRenderTarget::IDDesc& rtIDDesc,
GrWrapCacheable cacheable,
GrMipMapsStatus mipMapsStatus)
: GrSurface(gpu, desc)
- , GrGLTexture(gpu, desc, texIDDesc, mipMapsStatus)
+ , GrGLTexture(gpu, desc, texIDDesc, std::move(parameters), mipMapsStatus)
, GrGLRenderTarget(gpu, desc, texIDDesc.fInfo.fFormat, rtIDDesc) {
this->registerWithCacheWrapped(cacheable);
}
@@ -58,14 +59,13 @@
sk_sp<GrGLTextureRenderTarget> GrGLTextureRenderTarget::MakeWrapped(
GrGLGpu* gpu, const GrSurfaceDesc& desc, const GrGLTexture::IDDesc& texIDDesc,
- const GrGLRenderTarget::IDDesc& rtIDDesc, GrWrapCacheable cacheable,
- GrMipMapsStatus mipMapsStatus) {
- return sk_sp<GrGLTextureRenderTarget>(
- new GrGLTextureRenderTarget(gpu, desc, texIDDesc, rtIDDesc, cacheable, mipMapsStatus));
+ sk_sp<GrGLTextureParameters> parameters, const GrGLRenderTarget::IDDesc& rtIDDesc,
+ GrWrapCacheable cacheable, GrMipMapsStatus mipMapsStatus) {
+ return sk_sp<GrGLTextureRenderTarget>(new GrGLTextureRenderTarget(
+ gpu, desc, texIDDesc, std::move(parameters), rtIDDesc, cacheable, mipMapsStatus));
}
size_t GrGLTextureRenderTarget::onGpuMemorySize() const {
return GrSurface::ComputeSize(this->config(), this->width(), this->height(),
- this->numSamplesOwnedPerPixel(),
- this->texturePriv().mipMapped());
+ this->numSamplesOwnedPerPixel(), this->texturePriv().mipMapped());
}
diff --git a/src/gpu/gl/GrGLTextureRenderTarget.h b/src/gpu/gl/GrGLTextureRenderTarget.h
index 75cdf01..c386822 100644
--- a/src/gpu/gl/GrGLTextureRenderTarget.h
+++ b/src/gpu/gl/GrGLTextureRenderTarget.h
@@ -37,6 +37,7 @@
static sk_sp<GrGLTextureRenderTarget> MakeWrapped(GrGLGpu* gpu, const GrSurfaceDesc& desc,
const GrGLTexture::IDDesc& texIDDesc,
+ sk_sp<GrGLTextureParameters> parameters,
const GrGLRenderTarget::IDDesc& rtIDDesc,
GrWrapCacheable cacheble, GrMipMapsStatus);
@@ -61,6 +62,7 @@
GrGLTextureRenderTarget(GrGLGpu* gpu,
const GrSurfaceDesc& desc,
const GrGLTexture::IDDesc& texIDDesc,
+ sk_sp<GrGLTextureParameters> parameters,
const GrGLRenderTarget::IDDesc& rtIDDesc,
GrWrapCacheable,
GrMipMapsStatus);
diff --git a/src/gpu/gl/GrGLTypesPriv.cpp b/src/gpu/gl/GrGLTypesPriv.cpp
new file mode 100644
index 0000000..debb408
--- /dev/null
+++ b/src/gpu/gl/GrGLTypesPriv.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "include/private/GrGLTypesPriv.h"
+#include "include/core/SkScalar.h"
+#include "src/gpu/GrSwizzle.h"
+#include "src/gpu/gl/GrGLDefines.h"
+
+GrGLTextureParameters::SamplerOverriddenState::SamplerOverriddenState()
+ // These are the OpenGL defaults.
+ : fMinFilter(GR_GL_NEAREST_MIPMAP_LINEAR)
+ , fMagFilter(GR_GL_LINEAR)
+ , fWrapS(GR_GL_REPEAT)
+ , fWrapT(GR_GL_REPEAT)
+ , fMinLOD(-1000.f)
+ , fMaxLOD(1000.f)
+ , fBorderColorInvalid(false) {}
+
+void GrGLTextureParameters::SamplerOverriddenState::invalidate() {
+ fMinFilter = ~0U;
+ fMagFilter = ~0U;
+ fWrapS = ~0U;
+ fWrapT = ~0U;
+ fMinLOD = SK_ScalarNaN;
+ fMaxLOD = SK_ScalarNaN;
+ fBorderColorInvalid = true;
+}
+
+GrGLTextureParameters::NonsamplerState::NonsamplerState()
+ // These are the OpenGL defaults.
+ : fSwizzleKey(GrSwizzle::RGBA().asKey()), fBaseMipMapLevel(0), fMaxMipMapLevel(1000) {}
+
+void GrGLTextureParameters::NonsamplerState::invalidate() {
+ fSwizzleKey = ~0U;
+ fBaseMipMapLevel = ~0;
+ fMaxMipMapLevel = ~0;
+}
+
+void GrGLTextureParameters::invalidate() {
+ fSamplerOverriddenState.invalidate();
+ fNonsamplerState.invalidate();
+}
+
+void GrGLTextureParameters::set(const SamplerOverriddenState* samplerState,
+ const NonsamplerState& nonsamplerState,
+ ResetTimestamp currTimestamp) {
+ if (samplerState) {
+ fSamplerOverriddenState = *samplerState;
+ }
+ fNonsamplerState = nonsamplerState;
+ fResetTimestamp = currTimestamp;
+}
+
+void GrGLBackendTextureInfo::assign(const GrGLBackendTextureInfo& that, bool thisIsValid) {
+ fInfo = that.fInfo;
+ SkSafeRef(that.fParams);
+ if (thisIsValid) {
+ SkSafeUnref(fParams);
+ }
+ fParams = that.fParams;
+}
+
+void GrGLBackendTextureInfo::cleanup() { SkSafeUnref(fParams); }