Attempt to simplify NPOT texture caps. Also fixes case where textures would unnecessarily be bloated to POT. Adds setting of sampler's filter setting in paint conversion.
git-svn-id: http://skia.googlecode.com/svn/trunk@751 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
f7c157610f
commit
0748f217ba
@ -54,28 +54,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
static GrGpu* Create(Engine, Platform3DContext context3D);
|
static GrGpu* Create(Engine, Platform3DContext context3D);
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes levels of support for non-power-of-two textures.
|
|
||||||
*/
|
|
||||||
enum NPOTTextureTypes {
|
|
||||||
/**
|
|
||||||
* no support for NPOT textures
|
|
||||||
*/
|
|
||||||
kNone_NPOTTextureType,
|
|
||||||
/**
|
|
||||||
* only clamp is supported for textures
|
|
||||||
*/
|
|
||||||
kNoRepeat_NPOTTextureType,
|
|
||||||
/**
|
|
||||||
* no texture restrictions at all, but rendertargets must be POW2
|
|
||||||
*/
|
|
||||||
kNonRendertarget_NPOTTextureType,
|
|
||||||
/**
|
|
||||||
* no POW2 restrictions at all
|
|
||||||
*/
|
|
||||||
kFull_NPOTTextureType
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to control the level of antialiasing available for a rendertarget.
|
* Used to control the level of antialiasing available for a rendertarget.
|
||||||
* Anti-alias quality levels depend on the underlying API/GPU capabilities.
|
* Anti-alias quality levels depend on the underlying API/GPU capabilities.
|
||||||
@ -173,7 +151,10 @@ public:
|
|||||||
void unimpl(const char[]);
|
void unimpl(const char[]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a texture object
|
* Creates a texture object. If desc width or height is not a power of
|
||||||
|
* two but underlying API requires a power of two texture then srcData
|
||||||
|
* will be embedded in a power of two texture. The extra width and height
|
||||||
|
* is filled as though srcData were rendered clamped into the texture.
|
||||||
*
|
*
|
||||||
* @param desc describes the texture to be created.
|
* @param desc describes the texture to be created.
|
||||||
* @param srcData texel data to load texture. Begins with full-size
|
* @param srcData texel data to load texture. Begins with full-size
|
||||||
@ -278,14 +259,25 @@ public:
|
|||||||
int minRenderTargetHeight() const { return fMinRenderTargetHeight; }
|
int minRenderTargetHeight() const { return fMinRenderTargetHeight; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the level of NPOT texture support. Regardless of support level
|
* Returns true if NPOT textures can be created
|
||||||
* NPOT textures can always be created, but internally they may be imbedded
|
|
||||||
* in a POT texture. An exception is paletted textures which must be
|
|
||||||
* specified as a POT when npotTextureSupport() is not Full.
|
|
||||||
*
|
*
|
||||||
* @return the level of NPOT texture support.
|
* @return true if NPOT textures can be created
|
||||||
*/
|
*/
|
||||||
NPOTTextureTypes npotTextureSupport() const { return fNPOTTextureSupport; }
|
bool npotTextureSupport() const { return fNPOTTextureSupport; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if NPOT textures can be repeat/mirror tiled.
|
||||||
|
*
|
||||||
|
* @return true if NPOT textures can be tiled
|
||||||
|
*/
|
||||||
|
bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if a NPOT texture can be a rendertarget
|
||||||
|
*
|
||||||
|
* @return the true if NPOT texture/rendertarget can be created.
|
||||||
|
*/
|
||||||
|
bool npotRenderTargetSupport() const { return fNPOTRenderTargetSupport; }
|
||||||
|
|
||||||
int maxTextureDimension() const { return fMaxTextureDimension; }
|
int maxTextureDimension() const { return fMaxTextureDimension; }
|
||||||
|
|
||||||
@ -374,8 +366,10 @@ protected:
|
|||||||
// defaults to false, subclass can set true to support palleted textures
|
// defaults to false, subclass can set true to support palleted textures
|
||||||
bool f8bitPaletteSupport;
|
bool f8bitPaletteSupport;
|
||||||
|
|
||||||
// defaults to false, subclass can set higher support level
|
// set by subclass
|
||||||
NPOTTextureTypes fNPOTTextureSupport;
|
bool fNPOTTextureSupport;
|
||||||
|
bool fNPOTTextureTileSupport;
|
||||||
|
bool fNPOTRenderTargetSupport;
|
||||||
|
|
||||||
// True if only one stencil pass is required to implement the winding path
|
// True if only one stencil pass is required to implement the winding path
|
||||||
// fill rule. Subclass responsible for setting this value.
|
// fill rule. Subclass responsible for setting this value.
|
||||||
|
@ -260,22 +260,21 @@ bool GrContext::supportsIndex8PixelConfig(const GrSamplerState& sampler,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool needsRepeat = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||
|
|
||||||
sampler.getWrapY() != GrSamplerState::kClamp_WrapMode;
|
|
||||||
bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
|
bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
|
||||||
|
|
||||||
switch (fGpu->npotTextureSupport()) {
|
if (!isPow2) {
|
||||||
case GrGpu::kNone_NPOTTextureType:
|
if (!fGpu->npotTextureSupport()) {
|
||||||
return isPow2;
|
return false;
|
||||||
case GrGpu::kNoRepeat_NPOTTextureType:
|
}
|
||||||
return isPow2 || !needsRepeat;
|
|
||||||
case GrGpu::kNonRendertarget_NPOTTextureType:
|
bool tiled = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||
|
||||||
case GrGpu::kFull_NPOTTextureType:
|
sampler.getWrapY() != GrSamplerState::kClamp_WrapMode;
|
||||||
return true;
|
if (tiled && !fGpu->npotTextureTileSupport()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// should never get here
|
return true;
|
||||||
GrAssert(!"Bad enum from fGpu->npotTextureSupport");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1141,10 +1140,15 @@ bool GrContext::finalizeTextureKey(GrTextureKey* key,
|
|||||||
uint32_t bits = 0;
|
uint32_t bits = 0;
|
||||||
uint16_t width = key->width();
|
uint16_t width = key->width();
|
||||||
uint16_t height = key->height();
|
uint16_t height = key->height();
|
||||||
if (fGpu->npotTextureSupport() < GrGpu::kNonRendertarget_NPOTTextureType) {
|
|
||||||
if ((sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||
|
|
||||||
sampler.getWrapY() != GrSamplerState::kClamp_WrapMode) &&
|
if (!fGpu->npotTextureTileSupport()) {
|
||||||
(!GrIsPow2(width) || !GrIsPow2(height))) {
|
bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
|
||||||
|
|
||||||
|
bool tiled = (sampler.getWrapX() != GrSamplerState::kClamp_WrapMode) ||
|
||||||
|
(sampler.getWrapY() != GrSamplerState::kClamp_WrapMode);
|
||||||
|
|
||||||
|
if (tiled && !isPow2) {
|
||||||
bits |= 1;
|
bits |= 1;
|
||||||
bits |= sampler.isFilter() ? 2 : 0;
|
bits |= sampler.isFilter() ? 2 : 0;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,6 @@ bool GrTexture::PixelConfigIsOpaque(PixelConfig config) {
|
|||||||
extern void gr_run_unittests();
|
extern void gr_run_unittests();
|
||||||
|
|
||||||
GrGpu::GrGpu() : f8bitPaletteSupport(false),
|
GrGpu::GrGpu() : f8bitPaletteSupport(false),
|
||||||
fNPOTTextureSupport(kNone_NPOTTextureType),
|
|
||||||
fQuadIndexBuffer(NULL),
|
fQuadIndexBuffer(NULL),
|
||||||
fUnitSquareVertexBuffer(NULL) {
|
fUnitSquareVertexBuffer(NULL) {
|
||||||
#if GR_DEBUG
|
#if GR_DEBUG
|
||||||
|
@ -250,18 +250,20 @@ GrGpuGL::GrGpuGL() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if GR_SUPPORT_GLDESKTOP
|
#if GR_SUPPORT_GLDESKTOP
|
||||||
fNPOTTextureSupport =
|
if (major >= 2 || has_gl_extension("GL_ARB_texture_non_power_of_two")) {
|
||||||
(major >= 2 || has_gl_extension("GL_ARB_texture_non_power_of_two")) ?
|
fNPOTTextureTileSupport = true;
|
||||||
kFull_NPOTTextureType :
|
fNPOTTextureSupport = true;
|
||||||
kNone_NPOTTextureType;
|
|
||||||
#else
|
|
||||||
if (has_gl_extension("GL_OES_texture_npot")) {
|
|
||||||
fNPOTTextureSupport = kFull_NPOTTextureType;
|
|
||||||
} else if (major >= 2 ||
|
|
||||||
has_gl_extension("GL_APPLE_texture_2D_limited_npot")) {
|
|
||||||
fNPOTTextureSupport = kNoRepeat_NPOTTextureType;
|
|
||||||
} else {
|
} else {
|
||||||
fNPOTTextureSupport = kNone_NPOTTextureType;
|
fNPOTTextureTileSupport = false;
|
||||||
|
fNPOTTextureSupport = false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (major >= 2) {
|
||||||
|
fNPOTTextureSupport = true;
|
||||||
|
fNPOTTextureTileSupport = has_gl_extension("GL_OES_texture_npot");
|
||||||
|
} else {
|
||||||
|
fNPOTTextureSupport = has_gl_extension("GL_APPLE_texture_2D_limited_npot");
|
||||||
|
fNPOTTextureTileSupport = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
@ -269,16 +271,16 @@ GrGpuGL::GrGpuGL() {
|
|||||||
// these a preprocess that generate some compile time constants.
|
// these a preprocess that generate some compile time constants.
|
||||||
|
|
||||||
// sanity check to make sure we can at least create an FBO from a POT texture
|
// sanity check to make sure we can at least create an FBO from a POT texture
|
||||||
if (fNPOTTextureSupport < kFull_NPOTTextureType) {
|
|
||||||
bool npotFBOSuccess = fbo_test(fExts, 128, 128);
|
bool simpleFBOSuccess = fbo_test(fExts, 128, 128);
|
||||||
if (gPrintStartupSpew) {
|
if (gPrintStartupSpew) {
|
||||||
if (!npotFBOSuccess) {
|
if (!simpleFBOSuccess) {
|
||||||
GrPrintf("FBO Sanity Test: FAILED\n");
|
GrPrintf("FBO Sanity Test: FAILED\n");
|
||||||
} else {
|
} else {
|
||||||
GrPrintf("FBO Sanity Test: PASSED\n");
|
GrPrintf("FBO Sanity Test: PASSED\n");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GrAssert(simpleFBOSuccess);
|
||||||
|
|
||||||
/* Experimentation has found that some GLs that support NPOT textures
|
/* Experimentation has found that some GLs that support NPOT textures
|
||||||
do not support FBOs with a NPOT texture. They report "unsupported" FBO
|
do not support FBOs with a NPOT texture. They report "unsupported" FBO
|
||||||
@ -287,34 +289,26 @@ GrGpuGL::GrGpuGL() {
|
|||||||
texture. Presumably, the implementation bloats the renderbuffer
|
texture. Presumably, the implementation bloats the renderbuffer
|
||||||
internally to the next POT.
|
internally to the next POT.
|
||||||
*/
|
*/
|
||||||
if (fNPOTTextureSupport == kFull_NPOTTextureType) {
|
bool fNPOTRenderTargetSupport = false;
|
||||||
bool npotFBOSuccess = fbo_test(fExts, 200, 200);
|
if (fNPOTTextureSupport) {
|
||||||
if (!npotFBOSuccess) {
|
fNPOTRenderTargetSupport = fbo_test(fExts, 200, 200);
|
||||||
fNPOTTextureSupport = kNonRendertarget_NPOTTextureType;
|
}
|
||||||
if (gPrintStartupSpew) {
|
|
||||||
GrPrintf("NPOT Renderbuffer Test: FAILED\n");
|
if (gPrintStartupSpew) {
|
||||||
|
if (fNPOTTextureSupport) {
|
||||||
|
GrPrintf("NPOT textures supported\n");
|
||||||
|
if (fNPOTTextureTileSupport) {
|
||||||
|
GrPrintf("NPOT texture tiling supported\n");
|
||||||
|
} else {
|
||||||
|
GrPrintf("NPOT texture tiling NOT supported\n");
|
||||||
|
}
|
||||||
|
if (fNPOTRenderTargetSupport) {
|
||||||
|
GrPrintf("NPOT render targets supported\n");
|
||||||
|
} else {
|
||||||
|
GrPrintf("NPOT render targets NOT supported\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (gPrintStartupSpew) {
|
GrPrintf("NPOT textures NOT supported\n");
|
||||||
GrPrintf("NPOT Renderbuffer Test: PASSED\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gPrintStartupSpew) {
|
|
||||||
switch (fNPOTTextureSupport) {
|
|
||||||
case kNone_NPOTTextureType:
|
|
||||||
GrPrintf("NPOT Support: NONE\n");
|
|
||||||
break;
|
|
||||||
case kNoRepeat_NPOTTextureType:
|
|
||||||
GrPrintf("NPOT Support: NO REPEAT\n");
|
|
||||||
break;
|
|
||||||
case kNonRendertarget_NPOTTextureType:
|
|
||||||
GrPrintf("NPOT Support: NO FBOTEX\n");
|
|
||||||
break;
|
|
||||||
case kFull_NPOTTextureType:
|
|
||||||
GrPrintf("NPOT Support: FULL\n");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,8 +323,8 @@ GrGpuGL::GrGpuGL() {
|
|||||||
if (gPrintStartupSpew) {
|
if (gPrintStartupSpew) {
|
||||||
GrPrintf("Small height FBO texture experiments\n");
|
GrPrintf("Small height FBO texture experiments\n");
|
||||||
}
|
}
|
||||||
for (GLuint i = 1; i <= 256;
|
|
||||||
(kFull_NPOTTextureType != fNPOTTextureSupport) ? i *= 2 : ++i) {
|
for (GLuint i = 1; i <= 256; fNPOTRenderTargetSupport ? ++i : i *= 2) {
|
||||||
GLuint w = maxRenderSize;
|
GLuint w = maxRenderSize;
|
||||||
GLuint h = i;
|
GLuint h = i;
|
||||||
if (fbo_test(fExts, w, h)) {
|
if (fbo_test(fExts, w, h)) {
|
||||||
@ -351,8 +345,7 @@ GrGpuGL::GrGpuGL() {
|
|||||||
GrPrintf("Small width FBO texture experiments\n");
|
GrPrintf("Small width FBO texture experiments\n");
|
||||||
}
|
}
|
||||||
fMinRenderTargetWidth = GR_MAX_GLUINT;
|
fMinRenderTargetWidth = GR_MAX_GLUINT;
|
||||||
for (GLuint i = 1; i <= 256;
|
for (GLuint i = 1; i <= 256; fNPOTRenderTargetSupport ? i *= 2 : ++i) {
|
||||||
(kFull_NPOTTextureType != fNPOTTextureSupport) ? i *= 2 : ++i) {
|
|
||||||
GLuint w = i;
|
GLuint w = i;
|
||||||
GLuint h = maxRenderSize;
|
GLuint h = maxRenderSize;
|
||||||
if (fbo_test(fExts, w, h)) {
|
if (fbo_test(fExts, w, h)) {
|
||||||
@ -369,22 +362,7 @@ GrGpuGL::GrGpuGL() {
|
|||||||
}
|
}
|
||||||
GrAssert(GR_INVAL_GLINT != fMinRenderTargetWidth);
|
GrAssert(GR_INVAL_GLINT != fMinRenderTargetWidth);
|
||||||
|
|
||||||
#if GR_IOS_BUILD
|
|
||||||
/*
|
|
||||||
The iPad seems to fail, at least sometimes, if the height is < 16,
|
|
||||||
so we pin the values here for now. A better fix might be to
|
|
||||||
conditionalize this based on known that its an iPad (or some other
|
|
||||||
check).
|
|
||||||
*/
|
|
||||||
fMinRenderTargetWidth = GrMax<GLuint>(fMinRenderTargetWidth, 16);
|
|
||||||
fMinRenderTargetHeight = GrMax<GLuint>(fMinRenderTargetHeight, 16);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GR_GL_GetIntegerv(GL_MAX_TEXTURE_SIZE, &fMaxTextureDimension);
|
GR_GL_GetIntegerv(GL_MAX_TEXTURE_SIZE, &fMaxTextureDimension);
|
||||||
|
|
||||||
#if GR_COLLECT_STATS
|
|
||||||
++fStats.fRenderTargetChngCnt;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GrGpuGL::~GrGpuGL() {
|
GrGpuGL::~GrGpuGL() {
|
||||||
@ -607,18 +585,19 @@ GrTexture* GrGpuGL::createTexture(const TextureDesc& desc,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fNPOTTextureSupport < kNonRendertarget_NPOTTextureType ||
|
|
||||||
(fNPOTTextureSupport == kNonRendertarget_NPOTTextureType &&
|
|
||||||
renderTarget)) {
|
|
||||||
glDesc.fAllocWidth = GrNextPow2(desc.fWidth);
|
|
||||||
glDesc.fAllocHeight = GrNextPow2(desc.fHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (renderTarget) {
|
if (renderTarget) {
|
||||||
|
if (!this->npotRenderTargetSupport()) {
|
||||||
|
glDesc.fAllocWidth = GrNextPow2(desc.fWidth);
|
||||||
|
glDesc.fAllocHeight = GrNextPow2(desc.fHeight);
|
||||||
|
}
|
||||||
|
|
||||||
glDesc.fAllocWidth = GrMax<int>(fMinRenderTargetWidth,
|
glDesc.fAllocWidth = GrMax<int>(fMinRenderTargetWidth,
|
||||||
glDesc.fAllocWidth);
|
glDesc.fAllocWidth);
|
||||||
glDesc.fAllocHeight = GrMax<int>(fMinRenderTargetHeight,
|
glDesc.fAllocHeight = GrMax<int>(fMinRenderTargetHeight,
|
||||||
glDesc.fAllocHeight);
|
glDesc.fAllocHeight);
|
||||||
|
} else if (!this->npotTextureSupport()) {
|
||||||
|
glDesc.fAllocWidth = GrNextPow2(desc.fWidth);
|
||||||
|
glDesc.fAllocHeight = GrNextPow2(desc.fHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
GR_GL(BindTexture(GL_TEXTURE_2D, glDesc.fTextureID));
|
GR_GL(BindTexture(GL_TEXTURE_2D, glDesc.fTextureID));
|
||||||
|
@ -405,7 +405,7 @@ bool SkGpuDevice::skPaint2GrPaintShader(const SkPaint& skPaint,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
grPaint->fSampler.setSampleMode(sampleMode);
|
grPaint->fSampler.setSampleMode(sampleMode);
|
||||||
|
grPaint->fSampler.setFilter(skPaint.isFilterBitmap());
|
||||||
grPaint->fSampler.setWrapX(sk_tile_mode_to_grwrap(tileModes[0]));
|
grPaint->fSampler.setWrapX(sk_tile_mode_to_grwrap(tileModes[0]));
|
||||||
grPaint->fSampler.setWrapY(sk_tile_mode_to_grwrap(tileModes[1]));
|
grPaint->fSampler.setWrapY(sk_tile_mode_to_grwrap(tileModes[1]));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user