*/
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.
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
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 true if NPOT textures can be created
+ */
+ bool npotTextureSupport() const { return fNPOTTextureSupport; }
+
+ /**
+ * Returns true if NPOT textures can be repeat/mirror tiled.
*
- * @return the level of NPOT texture support.
+ * @return true if NPOT textures can be tiled
*/
- NPOTTextureTypes npotTextureSupport() const { return fNPOTTextureSupport; }
+ 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; }
// 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.
return false;\r
}\r
\r
- bool needsRepeat = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||\r
- sampler.getWrapY() != GrSamplerState::kClamp_WrapMode;\r
+\r
bool isPow2 = GrIsPow2(width) && GrIsPow2(height);\r
\r
- switch (fGpu->npotTextureSupport()) {\r
- case GrGpu::kNone_NPOTTextureType:\r
- return isPow2;\r
- case GrGpu::kNoRepeat_NPOTTextureType:\r
- return isPow2 || !needsRepeat;\r
- case GrGpu::kNonRendertarget_NPOTTextureType:\r
- case GrGpu::kFull_NPOTTextureType:\r
- return true;\r
+ if (!isPow2) {\r
+ if (!fGpu->npotTextureSupport()) {\r
+ return false;\r
+ }\r
+\r
+ bool tiled = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||\r
+ sampler.getWrapY() != GrSamplerState::kClamp_WrapMode;\r
+ if (tiled && !fGpu->npotTextureTileSupport()) {\r
+ return false;\r
+ }\r
}\r
- // should never get here\r
- GrAssert(!"Bad enum from fGpu->npotTextureSupport");\r
- return false;\r
+ return true;\r
}\r
\r
////////////////////////////////////////////////////////////////////////////////\r
uint32_t bits = 0;\r
uint16_t width = key->width();\r
uint16_t height = key->height();\r
- if (fGpu->npotTextureSupport() < GrGpu::kNonRendertarget_NPOTTextureType) {\r
- if ((sampler.getWrapX() != GrSamplerState::kClamp_WrapMode ||\r
- sampler.getWrapY() != GrSamplerState::kClamp_WrapMode) &&\r
- (!GrIsPow2(width) || !GrIsPow2(height))) {\r
+ \r
+\r
+ if (!fGpu->npotTextureTileSupport()) {\r
+ bool isPow2 = GrIsPow2(width) && GrIsPow2(height);\r
+\r
+ bool tiled = (sampler.getWrapX() != GrSamplerState::kClamp_WrapMode) ||\r
+ (sampler.getWrapY() != GrSamplerState::kClamp_WrapMode);\r
+\r
+ if (tiled && !isPow2) {\r
bits |= 1;\r
bits |= sampler.isFilter() ? 2 : 0;\r
}\r
}
#if GR_SUPPORT_GLDESKTOP
- fNPOTTextureSupport =
- (major >= 2 || has_gl_extension("GL_ARB_texture_non_power_of_two")) ?
- kFull_NPOTTextureType :
- kNone_NPOTTextureType;
+ if (major >= 2 || has_gl_extension("GL_ARB_texture_non_power_of_two")) {
+ fNPOTTextureTileSupport = true;
+ fNPOTTextureSupport = true;
+ } else {
+ fNPOTTextureTileSupport = false;
+ fNPOTTextureSupport = false;
+ }
#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) {
+ fNPOTTextureSupport = true;
+ fNPOTTextureTileSupport = has_gl_extension("GL_OES_texture_npot");
} else {
- fNPOTTextureSupport = kNone_NPOTTextureType;
+ fNPOTTextureSupport = has_gl_extension("GL_APPLE_texture_2D_limited_npot");
+ fNPOTTextureTileSupport = false;
}
#endif
////////////////////////////////////////////////////////////////////////////
// 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
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");
- }
- } else {
- if (gPrintStartupSpew) {
- GrPrintf("NPOT Renderbuffer Test: PASSED\n");
- }
- }
+ bool fNPOTRenderTargetSupport = false;
+ if (fNPOTTextureSupport) {
+ fNPOTRenderTargetSupport = fbo_test(fExts, 200, 200);
}
-
+
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;
+ 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 {
+ GrPrintf("NPOT textures NOT supported\n");
}
}
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)) {
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)) {
}
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() {
}
#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));