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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Anti-alias quality levels depend on the underlying API/GPU capabilities.
|
||||
@ -173,7 +151,10 @@ public:
|
||||
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 srcData texel data to load texture. Begins with full-size
|
||||
@ -278,14 +259,25 @@ public:
|
||||
int minRenderTargetHeight() const { return fMinRenderTargetHeight; }
|
||||
|
||||
/**
|
||||
* Retrieves the level of NPOT texture support. Regardless of support level
|
||||
* 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.
|
||||
* Returns true if NPOT textures can be created
|
||||
*
|
||||
* @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; }
|
||||
|
||||
@ -374,8 +366,10 @@ protected:
|
||||
// defaults to false, subclass can set true to support palleted textures
|
||||
bool f8bitPaletteSupport;
|
||||
|
||||
// defaults to false, subclass can set higher support level
|
||||
NPOTTextureTypes fNPOTTextureSupport;
|
||||
// set by subclass
|
||||
bool fNPOTTextureSupport;
|
||||
bool fNPOTTextureTileSupport;
|
||||
bool fNPOTRenderTargetSupport;
|
||||
|
||||
// True if only one stencil pass is required to implement the winding path
|
||||
// fill rule. Subclass responsible for setting this value.
|
||||
|
@ -260,22 +260,21 @@ bool GrContext::supportsIndex8PixelConfig(const GrSamplerState& sampler,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool needsRepeat = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||
|
||||
sampler.getWrapY() != GrSamplerState::kClamp_WrapMode;
|
||||
|
||||
bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
|
||||
|
||||
switch (fGpu->npotTextureSupport()) {
|
||||
case GrGpu::kNone_NPOTTextureType:
|
||||
return isPow2;
|
||||
case GrGpu::kNoRepeat_NPOTTextureType:
|
||||
return isPow2 || !needsRepeat;
|
||||
case GrGpu::kNonRendertarget_NPOTTextureType:
|
||||
case GrGpu::kFull_NPOTTextureType:
|
||||
return true;
|
||||
if (!isPow2) {
|
||||
if (!fGpu->npotTextureSupport()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool tiled = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||
|
||||
sampler.getWrapY() != GrSamplerState::kClamp_WrapMode;
|
||||
if (tiled && !fGpu->npotTextureTileSupport()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// should never get here
|
||||
GrAssert(!"Bad enum from fGpu->npotTextureSupport");
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1141,10 +1140,15 @@ bool GrContext::finalizeTextureKey(GrTextureKey* key,
|
||||
uint32_t bits = 0;
|
||||
uint16_t width = key->width();
|
||||
uint16_t height = key->height();
|
||||
if (fGpu->npotTextureSupport() < GrGpu::kNonRendertarget_NPOTTextureType) {
|
||||
if ((sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||
|
||||
sampler.getWrapY() != GrSamplerState::kClamp_WrapMode) &&
|
||||
(!GrIsPow2(width) || !GrIsPow2(height))) {
|
||||
|
||||
|
||||
if (!fGpu->npotTextureTileSupport()) {
|
||||
bool isPow2 = GrIsPow2(width) && GrIsPow2(height);
|
||||
|
||||
bool tiled = (sampler.getWrapX() != GrSamplerState::kClamp_WrapMode) ||
|
||||
(sampler.getWrapY() != GrSamplerState::kClamp_WrapMode);
|
||||
|
||||
if (tiled && !isPow2) {
|
||||
bits |= 1;
|
||||
bits |= sampler.isFilter() ? 2 : 0;
|
||||
}
|
||||
|
@ -57,7 +57,6 @@ bool GrTexture::PixelConfigIsOpaque(PixelConfig config) {
|
||||
extern void gr_run_unittests();
|
||||
|
||||
GrGpu::GrGpu() : f8bitPaletteSupport(false),
|
||||
fNPOTTextureSupport(kNone_NPOTTextureType),
|
||||
fQuadIndexBuffer(NULL),
|
||||
fUnitSquareVertexBuffer(NULL) {
|
||||
#if GR_DEBUG
|
||||
|
@ -250,18 +250,20 @@ GrGpuGL::GrGpuGL() {
|
||||
}
|
||||
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
fNPOTTextureSupport =
|
||||
(major >= 2 || has_gl_extension("GL_ARB_texture_non_power_of_two")) ?
|
||||
kFull_NPOTTextureType :
|
||||
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;
|
||||
if (major >= 2 || has_gl_extension("GL_ARB_texture_non_power_of_two")) {
|
||||
fNPOTTextureTileSupport = true;
|
||||
fNPOTTextureSupport = true;
|
||||
} 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
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@ -269,16 +271,16 @@ GrGpuGL::GrGpuGL() {
|
||||
// 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
|
||||
if (fNPOTTextureSupport < kFull_NPOTTextureType) {
|
||||
bool npotFBOSuccess = fbo_test(fExts, 128, 128);
|
||||
if (gPrintStartupSpew) {
|
||||
if (!npotFBOSuccess) {
|
||||
GrPrintf("FBO Sanity Test: FAILED\n");
|
||||
} else {
|
||||
GrPrintf("FBO Sanity Test: PASSED\n");
|
||||
}
|
||||
|
||||
bool simpleFBOSuccess = fbo_test(fExts, 128, 128);
|
||||
if (gPrintStartupSpew) {
|
||||
if (!simpleFBOSuccess) {
|
||||
GrPrintf("FBO Sanity Test: FAILED\n");
|
||||
} else {
|
||||
GrPrintf("FBO Sanity Test: PASSED\n");
|
||||
}
|
||||
}
|
||||
GrAssert(simpleFBOSuccess);
|
||||
|
||||
/* Experimentation has found that some GLs that support NPOT textures
|
||||
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
|
||||
internally to the next POT.
|
||||
*/
|
||||
if (fNPOTTextureSupport == kFull_NPOTTextureType) {
|
||||
bool npotFBOSuccess = fbo_test(fExts, 200, 200);
|
||||
if (!npotFBOSuccess) {
|
||||
fNPOTTextureSupport = kNonRendertarget_NPOTTextureType;
|
||||
if (gPrintStartupSpew) {
|
||||
GrPrintf("NPOT Renderbuffer Test: FAILED\n");
|
||||
bool fNPOTRenderTargetSupport = false;
|
||||
if (fNPOTTextureSupport) {
|
||||
fNPOTRenderTargetSupport = fbo_test(fExts, 200, 200);
|
||||
}
|
||||
|
||||
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 {
|
||||
if (gPrintStartupSpew) {
|
||||
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;
|
||||
GrPrintf("NPOT textures NOT supported\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,8 +323,8 @@ GrGpuGL::GrGpuGL() {
|
||||
if (gPrintStartupSpew) {
|
||||
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 h = i;
|
||||
if (fbo_test(fExts, w, h)) {
|
||||
@ -351,8 +345,7 @@ GrGpuGL::GrGpuGL() {
|
||||
GrPrintf("Small width FBO texture experiments\n");
|
||||
}
|
||||
fMinRenderTargetWidth = GR_MAX_GLUINT;
|
||||
for (GLuint i = 1; i <= 256;
|
||||
(kFull_NPOTTextureType != fNPOTTextureSupport) ? i *= 2 : ++i) {
|
||||
for (GLuint i = 1; i <= 256; fNPOTRenderTargetSupport ? i *= 2 : ++i) {
|
||||
GLuint w = i;
|
||||
GLuint h = maxRenderSize;
|
||||
if (fbo_test(fExts, w, h)) {
|
||||
@ -369,22 +362,7 @@ GrGpuGL::GrGpuGL() {
|
||||
}
|
||||
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);
|
||||
|
||||
#if GR_COLLECT_STATS
|
||||
++fStats.fRenderTargetChngCnt;
|
||||
#endif
|
||||
}
|
||||
|
||||
GrGpuGL::~GrGpuGL() {
|
||||
@ -607,18 +585,19 @@ GrTexture* GrGpuGL::createTexture(const TextureDesc& desc,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fNPOTTextureSupport < kNonRendertarget_NPOTTextureType ||
|
||||
(fNPOTTextureSupport == kNonRendertarget_NPOTTextureType &&
|
||||
renderTarget)) {
|
||||
glDesc.fAllocWidth = GrNextPow2(desc.fWidth);
|
||||
glDesc.fAllocHeight = GrNextPow2(desc.fHeight);
|
||||
}
|
||||
|
||||
if (renderTarget) {
|
||||
if (!this->npotRenderTargetSupport()) {
|
||||
glDesc.fAllocWidth = GrNextPow2(desc.fWidth);
|
||||
glDesc.fAllocHeight = GrNextPow2(desc.fHeight);
|
||||
}
|
||||
|
||||
glDesc.fAllocWidth = GrMax<int>(fMinRenderTargetWidth,
|
||||
glDesc.fAllocWidth);
|
||||
glDesc.fAllocHeight = GrMax<int>(fMinRenderTargetHeight,
|
||||
glDesc.fAllocHeight);
|
||||
} else if (!this->npotTextureSupport()) {
|
||||
glDesc.fAllocWidth = GrNextPow2(desc.fWidth);
|
||||
glDesc.fAllocHeight = GrNextPow2(desc.fHeight);
|
||||
}
|
||||
|
||||
GR_GL(BindTexture(GL_TEXTURE_2D, glDesc.fTextureID));
|
||||
|
@ -405,7 +405,7 @@ bool SkGpuDevice::skPaint2GrPaintShader(const SkPaint& skPaint,
|
||||
return false;
|
||||
}
|
||||
grPaint->fSampler.setSampleMode(sampleMode);
|
||||
|
||||
grPaint->fSampler.setFilter(skPaint.isFilterBitmap());
|
||||
grPaint->fSampler.setWrapX(sk_tile_mode_to_grwrap(tileModes[0]));
|
||||
grPaint->fSampler.setWrapY(sk_tile_mode_to_grwrap(tileModes[1]));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user