Reland "Add clamp to border wrap mode to gpu"
This reverts commit8137f3c862
. Reason for revert: update GrCaps clampToBorder for iOS and Mac 10.11 Original change's description: > Revert "Add clamp to border wrap mode to gpu" > > This reverts commitf49a5785f3
. > > Reason for revert: clamp-to-border in metal not available on iOS > > Original change's description: > > Add clamp to border wrap mode to gpu > > > > Bug: skia: > > Change-Id: I286163cdea4fa8f7e6a876baaa11aa3dacd4f2ff > > Reviewed-on: https://skia-review.googlesource.com/c/175244 > > Reviewed-by: Brian Salomon <bsalomon@google.com> > > Reviewed-by: Greg Daniel <egdaniel@google.com> > > Commit-Queue: Michael Ludwig <michaelludwig@google.com> > > TBR=egdaniel@google.com,bsalomon@google.com,ethannicholas@google.com,michaelludwig@google.com > > Change-Id: I01ef28d9c2fbf6c6dcd82d9aac193ff102d60151 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: skia: > Reviewed-on: https://skia-review.googlesource.com/c/175988 > Reviewed-by: Michael Ludwig <michaelludwig@google.com> > Commit-Queue: Michael Ludwig <michaelludwig@google.com> TBR=egdaniel@google.com,bsalomon@google.com,ethannicholas@google.com,michaelludwig@google.com Change-Id: I37467eb096fec28131587aefe340f0485fca59d4 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: skia: Reviewed-on: https://skia-review.googlesource.com/c/175989 Reviewed-by: Michael Ludwig <michaelludwig@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
parent
be5a09332e
commit
f23a152715
@ -16,7 +16,7 @@
|
|||||||
class GrSamplerState {
|
class GrSamplerState {
|
||||||
public:
|
public:
|
||||||
enum class Filter : uint8_t { kNearest, kBilerp, kMipMap };
|
enum class Filter : uint8_t { kNearest, kBilerp, kMipMap };
|
||||||
enum class WrapMode : uint8_t { kClamp, kRepeat, kMirrorRepeat };
|
enum class WrapMode : uint8_t { kClamp, kRepeat, kMirrorRepeat, kClampToBorder };
|
||||||
|
|
||||||
static constexpr GrSamplerState ClampNearest() { return GrSamplerState(); }
|
static constexpr GrSamplerState ClampNearest() { return GrSamplerState(); }
|
||||||
static constexpr GrSamplerState ClampBilerp() {
|
static constexpr GrSamplerState ClampBilerp() {
|
||||||
@ -51,7 +51,8 @@ public:
|
|||||||
WrapMode wrapModeY() const { return fWrapModes[1]; }
|
WrapMode wrapModeY() const { return fWrapModes[1]; }
|
||||||
|
|
||||||
bool isRepeated() const {
|
bool isRepeated() const {
|
||||||
return WrapMode::kClamp != fWrapModes[0] || WrapMode::kClamp != fWrapModes[1];
|
return (WrapMode::kClamp != fWrapModes[0] && WrapMode::kClampToBorder != fWrapModes[0]) ||
|
||||||
|
(WrapMode::kClamp != fWrapModes[1] && WrapMode::kClampToBorder != fWrapModes[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const GrSamplerState& that) const {
|
bool operator==(const GrSamplerState& that) const {
|
||||||
|
@ -72,6 +72,9 @@ GrCaps::GrCaps(const GrContextOptions& options) {
|
|||||||
|
|
||||||
fPreferVRAMUseOverFlushes = true;
|
fPreferVRAMUseOverFlushes = true;
|
||||||
|
|
||||||
|
// Default to true, allow older versions of OpenGL to disable explicitly
|
||||||
|
fClampToBorderSupport = true;
|
||||||
|
|
||||||
fDriverBugWorkarounds = options.fDriverBugWorkarounds;
|
fDriverBugWorkarounds = options.fDriverBugWorkarounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,6 +311,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
GrBackendFormat createFormatFromBackendTexture(const GrBackendTexture&) const;
|
GrBackendFormat createFormatFromBackendTexture(const GrBackendTexture&) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The CLAMP_TO_BORDER wrap mode for texture coordinates was added to desktop GL in 1.3, and
|
||||||
|
* GLES 3.2, but is also available in extensions. Vulkan and Metal always have support.
|
||||||
|
*/
|
||||||
|
bool clampToBorderSupport() const { return fClampToBorderSupport; }
|
||||||
|
|
||||||
const GrDriverBugWorkarounds& workarounds() const { return fDriverBugWorkarounds; }
|
const GrDriverBugWorkarounds& workarounds() const { return fDriverBugWorkarounds; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -347,6 +353,7 @@ protected:
|
|||||||
bool fMustClearUploadedBufferData : 1;
|
bool fMustClearUploadedBufferData : 1;
|
||||||
bool fSupportsAHardwareBufferImages : 1;
|
bool fSupportsAHardwareBufferImages : 1;
|
||||||
bool fHalfFloatVertexAttributeSupport : 1;
|
bool fHalfFloatVertexAttributeSupport : 1;
|
||||||
|
bool fClampToBorderSupport : 1;
|
||||||
|
|
||||||
// Driver workaround
|
// Driver workaround
|
||||||
bool fBlacklistCoverageCounting : 1;
|
bool fBlacklistCoverageCounting : 1;
|
||||||
|
@ -235,6 +235,21 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
|
|||||||
// lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
|
// lacks TexImage2D support and ANGLE lacks GL ES 3.0 support.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GrCaps defaults fClampToBorderSupport to true, so disable when unsupported
|
||||||
|
if (kGL_GrGLStandard == standard) {
|
||||||
|
// Clamp to border added in 1.3
|
||||||
|
if (version < GR_GL_VER(1, 3) && !ctxInfo.hasExtension("GL_ARB_texture_border_clamp")) {
|
||||||
|
fClampToBorderSupport = false;
|
||||||
|
}
|
||||||
|
} else if (kGLES_GrGLStandard == standard) {
|
||||||
|
// GLES didn't have clamp to border until 3.2, but provides several alternative extensions
|
||||||
|
if (version < GR_GL_VER(3, 2) && !ctxInfo.hasExtension("GL_EXT_texture_border_clamp") &&
|
||||||
|
!ctxInfo.hasExtension("GL_NV_texture_border_clamp") &&
|
||||||
|
!ctxInfo.hasExtension("GL_OES_texture_border_clamp")) {
|
||||||
|
fClampToBorderSupport = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (kGL_GrGLStandard == standard) {
|
if (kGL_GrGLStandard == standard) {
|
||||||
if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
|
if (version >= GR_GL_VER(3,3) || ctxInfo.hasExtension("GL_ARB_texture_swizzle")) {
|
||||||
fTextureSwizzleSupport = true;
|
fTextureSwizzleSupport = true;
|
||||||
|
@ -670,6 +670,7 @@
|
|||||||
#define GR_GL_REPEAT 0x2901
|
#define GR_GL_REPEAT 0x2901
|
||||||
#define GR_GL_CLAMP_TO_EDGE 0x812F
|
#define GR_GL_CLAMP_TO_EDGE 0x812F
|
||||||
#define GR_GL_MIRRORED_REPEAT 0x8370
|
#define GR_GL_MIRRORED_REPEAT 0x8370
|
||||||
|
#define GR_GL_CLAMP_TO_BORDER 0x812D
|
||||||
|
|
||||||
/* Texture Swizzle */
|
/* Texture Swizzle */
|
||||||
#define GR_GL_TEXTURE_SWIZZLE_R 0x8E42
|
#define GR_GL_TEXTURE_SWIZZLE_R 0x8E42
|
||||||
|
@ -202,11 +202,16 @@ static GrGLenum filter_to_gl_min_filter(GrSamplerState::Filter filter) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline GrGLenum wrap_mode_to_gl_wrap(GrSamplerState::WrapMode wrapMode) {
|
static inline GrGLenum wrap_mode_to_gl_wrap(GrSamplerState::WrapMode wrapMode,
|
||||||
|
const GrCaps& caps) {
|
||||||
switch (wrapMode) {
|
switch (wrapMode) {
|
||||||
case GrSamplerState::WrapMode::kClamp: return GR_GL_CLAMP_TO_EDGE;
|
case GrSamplerState::WrapMode::kClamp: return GR_GL_CLAMP_TO_EDGE;
|
||||||
case GrSamplerState::WrapMode::kRepeat: return GR_GL_REPEAT;
|
case GrSamplerState::WrapMode::kRepeat: return GR_GL_REPEAT;
|
||||||
case GrSamplerState::WrapMode::kMirrorRepeat: return GR_GL_MIRRORED_REPEAT;
|
case GrSamplerState::WrapMode::kMirrorRepeat: return GR_GL_MIRRORED_REPEAT;
|
||||||
|
case GrSamplerState::WrapMode::kClampToBorder:
|
||||||
|
// May not be supported but should have been caught earlier
|
||||||
|
SkASSERT(caps.clampToBorderSupport());
|
||||||
|
return GR_GL_CLAMP_TO_BORDER;
|
||||||
}
|
}
|
||||||
SK_ABORT("Unknown wrap mode");
|
SK_ABORT("Unknown wrap mode");
|
||||||
return 0;
|
return 0;
|
||||||
@ -242,8 +247,8 @@ public:
|
|||||||
fSamplers[index] = s;
|
fSamplers[index] = s;
|
||||||
auto minFilter = filter_to_gl_min_filter(state.filter());
|
auto minFilter = filter_to_gl_min_filter(state.filter());
|
||||||
auto magFilter = filter_to_gl_mag_filter(state.filter());
|
auto magFilter = filter_to_gl_mag_filter(state.filter());
|
||||||
auto wrapX = wrap_mode_to_gl_wrap(state.wrapModeX());
|
auto wrapX = wrap_mode_to_gl_wrap(state.wrapModeX(), fGpu->glCaps());
|
||||||
auto wrapY = wrap_mode_to_gl_wrap(state.wrapModeY());
|
auto wrapY = wrap_mode_to_gl_wrap(state.wrapModeY(), fGpu->glCaps());
|
||||||
GR_GL_CALL(fGpu->glInterface(),
|
GR_GL_CALL(fGpu->glInterface(),
|
||||||
SamplerParameteri(s, GR_GL_TEXTURE_MIN_FILTER, minFilter));
|
SamplerParameteri(s, GR_GL_TEXTURE_MIN_FILTER, minFilter));
|
||||||
GR_GL_CALL(fGpu->glInterface(),
|
GR_GL_CALL(fGpu->glInterface(),
|
||||||
@ -284,16 +289,16 @@ private:
|
|||||||
int filter = static_cast<int>(state.filter());
|
int filter = static_cast<int>(state.filter());
|
||||||
SkASSERT(filter >= 0 && filter < 3);
|
SkASSERT(filter >= 0 && filter < 3);
|
||||||
int wrapX = static_cast<int>(state.wrapModeX());
|
int wrapX = static_cast<int>(state.wrapModeX());
|
||||||
SkASSERT(wrapX >= 0 && wrapX < 3);
|
SkASSERT(wrapX >= 0 && wrapX < 4);
|
||||||
int wrapY = static_cast<int>(state.wrapModeY());
|
int wrapY = static_cast<int>(state.wrapModeY());
|
||||||
SkASSERT(wrapY >= 0 && wrapY < 3);
|
SkASSERT(wrapY >= 0 && wrapY < 4);
|
||||||
int idx = 9 * filter + 3 * wrapX + wrapY;
|
int idx = 16 * filter + 4 * wrapX + wrapY;
|
||||||
SkASSERT(idx < kNumSamplers);
|
SkASSERT(idx < kNumSamplers);
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrGLGpu* fGpu;
|
GrGLGpu* fGpu;
|
||||||
static constexpr int kNumSamplers = 27;
|
static constexpr int kNumSamplers = 48;
|
||||||
std::unique_ptr<GrGLuint[]> fHWBoundSamplers;
|
std::unique_ptr<GrGLuint[]> fHWBoundSamplers;
|
||||||
GrGLuint fSamplers[kNumSamplers];
|
GrGLuint fSamplers[kNumSamplers];
|
||||||
int fNumTextureUnits;
|
int fNumTextureUnits;
|
||||||
@ -2854,8 +2859,8 @@ void GrGLGpu::bindTexture(int unitIdx, GrSamplerState samplerState, GrGLTexture*
|
|||||||
newSamplerParams.fMinFilter = filter_to_gl_min_filter(samplerState.filter());
|
newSamplerParams.fMinFilter = filter_to_gl_min_filter(samplerState.filter());
|
||||||
newSamplerParams.fMagFilter = filter_to_gl_mag_filter(samplerState.filter());
|
newSamplerParams.fMagFilter = filter_to_gl_mag_filter(samplerState.filter());
|
||||||
|
|
||||||
newSamplerParams.fWrapS = wrap_mode_to_gl_wrap(samplerState.wrapModeX());
|
newSamplerParams.fWrapS = wrap_mode_to_gl_wrap(samplerState.wrapModeX(), this->glCaps());
|
||||||
newSamplerParams.fWrapT = wrap_mode_to_gl_wrap(samplerState.wrapModeY());
|
newSamplerParams.fWrapT = wrap_mode_to_gl_wrap(samplerState.wrapModeY(), this->glCaps());
|
||||||
|
|
||||||
// These are the OpenGL default values.
|
// These are the OpenGL default values.
|
||||||
newSamplerParams.fMinLOD = -1000;
|
newSamplerParams.fMinLOD = -1000;
|
||||||
@ -2889,6 +2894,17 @@ void GrGLGpu::bindTexture(int unitIdx, GrSamplerState samplerState, GrGLTexture*
|
|||||||
this->setTextureUnit(unitIdx);
|
this->setTextureUnit(unitIdx);
|
||||||
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newSamplerParams.fWrapT));
|
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_WRAP_T, newSamplerParams.fWrapT));
|
||||||
}
|
}
|
||||||
|
if (this->glCaps().clampToBorderSupport()) {
|
||||||
|
// Make sure the border color is transparent black (the default)
|
||||||
|
if (setAll || oldSamplerParams.fBorderColorInvalid) {
|
||||||
|
this->setTextureUnit(unitIdx);
|
||||||
|
// Specify the transparent black as normalized signed integers. The conversion is
|
||||||
|
// defined as (2c+1)/(2^32-1), which makes it impossible to map a signed in to
|
||||||
|
// exactly 0.f. But 1/(2^32-1) is close enough.
|
||||||
|
static const GrGLint kTransparentBlack[4] = {0, 0, 0, 0};
|
||||||
|
GL_CALL(TexParameteriv(target, GR_GL_TEXTURE_BORDER_COLOR, kTransparentBlack));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
GrGLTexture::NonSamplerParams newNonSamplerParams;
|
GrGLTexture::NonSamplerParams newNonSamplerParams;
|
||||||
newNonSamplerParams.fBaseMipMapLevel = 0;
|
newNonSamplerParams.fBaseMipMapLevel = 0;
|
||||||
|
@ -27,6 +27,10 @@ public:
|
|||||||
GrGLenum fWrapT = GR_GL_REPEAT;
|
GrGLenum fWrapT = GR_GL_REPEAT;
|
||||||
GrGLfloat fMinLOD = -1000.f;
|
GrGLfloat fMinLOD = -1000.f;
|
||||||
GrGLfloat fMaxLOD = 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() {
|
void invalidate() {
|
||||||
fMinFilter = ~0U;
|
fMinFilter = ~0U;
|
||||||
fMagFilter = ~0U;
|
fMagFilter = ~0U;
|
||||||
@ -34,6 +38,7 @@ public:
|
|||||||
fWrapT = ~0U;
|
fWrapT = ~0U;
|
||||||
fMinLOD = SK_ScalarNaN;
|
fMinLOD = SK_ScalarNaN;
|
||||||
fMaxLOD = SK_ScalarNaN;
|
fMaxLOD = SK_ScalarNaN;
|
||||||
|
fBorderColorInvalid = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -221,6 +221,16 @@ void GrMtlCaps::initGrCaps(const id<MTLDevice> device) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clamp to border is supported on Mac 10.12 and higher (gpu family.version >= 1.2). It is not
|
||||||
|
// supported on iOS.
|
||||||
|
if (this->isMac()) {
|
||||||
|
if (fFamilyGroup == 1 && fVersion < 2) {
|
||||||
|
fClampToBorderSupport = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fClampToBorderSupport = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Starting with the assumption that there isn't a reason to not map small buffers.
|
// Starting with the assumption that there isn't a reason to not map small buffers.
|
||||||
fBufferMapThreshold = 0;
|
fBufferMapThreshold = 0;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include "GrMtlGpu.h"
|
#include "GrMtlGpu.h"
|
||||||
|
|
||||||
static inline MTLSamplerAddressMode wrap_mode_to_mtl_sampler_address(
|
static inline MTLSamplerAddressMode wrap_mode_to_mtl_sampler_address(
|
||||||
GrSamplerState::WrapMode wrapMode) {
|
GrSamplerState::WrapMode wrapMode, const GrCaps& caps) {
|
||||||
switch (wrapMode) {
|
switch (wrapMode) {
|
||||||
case GrSamplerState::WrapMode::kClamp:
|
case GrSamplerState::WrapMode::kClamp:
|
||||||
return MTLSamplerAddressModeClampToEdge;
|
return MTLSamplerAddressModeClampToEdge;
|
||||||
@ -18,6 +18,16 @@ static inline MTLSamplerAddressMode wrap_mode_to_mtl_sampler_address(
|
|||||||
return MTLSamplerAddressModeRepeat;
|
return MTLSamplerAddressModeRepeat;
|
||||||
case GrSamplerState::WrapMode::kMirrorRepeat:
|
case GrSamplerState::WrapMode::kMirrorRepeat:
|
||||||
return MTLSamplerAddressModeMirrorRepeat;
|
return MTLSamplerAddressModeMirrorRepeat;
|
||||||
|
case GrSamplerState::WrapMode::kClampToBorder:
|
||||||
|
// Must guard the reference to the clamp to border address mode by macro since iOS
|
||||||
|
// builds will fail if it's referenced, even if other code makes sure it's never used.
|
||||||
|
#ifdef SK_BUILD_FOR_IOS
|
||||||
|
SkASSERT(false);
|
||||||
|
return MTLSamplerAddressModeClampToEdge;
|
||||||
|
#else
|
||||||
|
SkASSERT(caps.clampToBorderSupport());
|
||||||
|
return MTLSamplerAddressModeClampToBorderColor;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
SK_ABORT("Unknown wrap mode.");
|
SK_ABORT("Unknown wrap mode.");
|
||||||
return MTLSamplerAddressModeClampToEdge;
|
return MTLSamplerAddressModeClampToEdge;
|
||||||
@ -37,8 +47,10 @@ GrMtlSampler* GrMtlSampler::Create(const GrMtlGpu* gpu, const GrSamplerState& sa
|
|||||||
|
|
||||||
auto samplerDesc = [[MTLSamplerDescriptor alloc] init];
|
auto samplerDesc = [[MTLSamplerDescriptor alloc] init];
|
||||||
samplerDesc.rAddressMode = MTLSamplerAddressModeClampToEdge;
|
samplerDesc.rAddressMode = MTLSamplerAddressModeClampToEdge;
|
||||||
samplerDesc.sAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeX());
|
samplerDesc.sAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeX(),
|
||||||
samplerDesc.tAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeY());
|
gpu->mtlCaps());
|
||||||
|
samplerDesc.tAddressMode = wrap_mode_to_mtl_sampler_address(samplerState.wrapModeY(),
|
||||||
|
gpu->mtlCaps());
|
||||||
samplerDesc.magFilter = mtlMinMagFilterModes[static_cast<int>(samplerState.filter())];
|
samplerDesc.magFilter = mtlMinMagFilterModes[static_cast<int>(samplerState.filter())];
|
||||||
samplerDesc.minFilter = mtlMinMagFilterModes[static_cast<int>(samplerState.filter())];
|
samplerDesc.minFilter = mtlMinMagFilterModes[static_cast<int>(samplerState.filter())];
|
||||||
samplerDesc.mipFilter = MTLSamplerMipFilterLinear;
|
samplerDesc.mipFilter = MTLSamplerMipFilterLinear;
|
||||||
|
@ -19,6 +19,8 @@ static inline VkSamplerAddressMode wrap_mode_to_vk_sampler_address(
|
|||||||
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
case GrSamplerState::WrapMode::kMirrorRepeat:
|
case GrSamplerState::WrapMode::kMirrorRepeat:
|
||||||
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
|
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
|
||||||
|
case GrSamplerState::WrapMode::kClampToBorder:
|
||||||
|
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||||
}
|
}
|
||||||
SK_ABORT("Unknown wrap mode.");
|
SK_ABORT("Unknown wrap mode.");
|
||||||
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
|
@ -171,8 +171,7 @@ static GrSamplerState::WrapMode tile_mode_to_wrap_mode(const SkShader::TileMode
|
|||||||
case SkShader::TileMode::kMirror_TileMode:
|
case SkShader::TileMode::kMirror_TileMode:
|
||||||
return GrSamplerState::WrapMode::kMirrorRepeat;
|
return GrSamplerState::WrapMode::kMirrorRepeat;
|
||||||
case SkShader::kDecal_TileMode:
|
case SkShader::kDecal_TileMode:
|
||||||
// TODO: depending on caps, we should extend WrapMode for decal...
|
return GrSamplerState::WrapMode::kClampToBorder;
|
||||||
return GrSamplerState::WrapMode::kClamp;
|
|
||||||
}
|
}
|
||||||
SK_ABORT("Unknown tile mode.");
|
SK_ABORT("Unknown tile mode.");
|
||||||
return GrSamplerState::WrapMode::kClamp;
|
return GrSamplerState::WrapMode::kClamp;
|
||||||
@ -188,6 +187,19 @@ std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor(
|
|||||||
|
|
||||||
GrSamplerState::WrapMode wrapModes[] = {tile_mode_to_wrap_mode(fTileModeX),
|
GrSamplerState::WrapMode wrapModes[] = {tile_mode_to_wrap_mode(fTileModeX),
|
||||||
tile_mode_to_wrap_mode(fTileModeY)};
|
tile_mode_to_wrap_mode(fTileModeY)};
|
||||||
|
if ((wrapModes[0] == GrSamplerState::WrapMode::kClampToBorder ||
|
||||||
|
wrapModes[1] == GrSamplerState::WrapMode::kClampToBorder) &&
|
||||||
|
!args.fContext->contextPriv().caps()->clampToBorderSupport()) {
|
||||||
|
// HW clamp to border is unavailable, so fall back to clamp for now
|
||||||
|
// TODO(michaelludwig): If clamp-to-border is selected but is unsupported, the texture
|
||||||
|
// domain effect could be used to emulate the decal effect.
|
||||||
|
if (wrapModes[0] == GrSamplerState::WrapMode::kClampToBorder) {
|
||||||
|
wrapModes[0] = GrSamplerState::WrapMode::kClamp;
|
||||||
|
}
|
||||||
|
if (wrapModes[1] == GrSamplerState::WrapMode::kClampToBorder) {
|
||||||
|
wrapModes[1] = GrSamplerState::WrapMode::kClamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Must set wrap and filter on the sampler before requesting a texture. In two places below
|
// Must set wrap and filter on the sampler before requesting a texture. In two places below
|
||||||
// we check the matrix scale factors to determine how to interpret the filter quality setting.
|
// we check the matrix scale factors to determine how to interpret the filter quality setting.
|
||||||
|
Loading…
Reference in New Issue
Block a user