aboutsummaryrefslogtreecommitdiffhomepage
path: root/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-07-06 17:47:02 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-07-06 17:47:02 +0000
commit2c17fcdc45f9fa9a2dc785786347040fbe30928b (patch)
treed6676cf0d78f21fab28476c685aa182fb567a79e /gpu
parent25fd36c7efc0287b6a2a82463eacaeaf91ca07b9 (diff)
Reduce gets of ext string and check validity of stencil format enums
Review URL: http://codereview.appspot.com/4678043/ git-svn-id: http://skia.googlecode.com/svn/trunk@1801 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gpu')
-rw-r--r--gpu/include/GrGLInterface.h5
-rw-r--r--gpu/src/GrGLInterface.cpp26
-rw-r--r--gpu/src/GrGpuGL.cpp144
-rw-r--r--gpu/src/GrGpuGL.h23
-rw-r--r--gpu/src/GrGpuGLShaders.cpp8
5 files changed, 138 insertions, 68 deletions
diff --git a/gpu/include/GrGLInterface.h b/gpu/include/GrGLInterface.h
index e3942cd203..42ff0c8a2c 100644
--- a/gpu/include/GrGLInterface.h
+++ b/gpu/include/GrGLInterface.h
@@ -31,14 +31,17 @@
* Helpers for glGetString()
*/
+// these variants assume caller already has a string from glGetString()
void gl_version_from_string(int* major, int* minor,
const char* versionString);
+float gl_version_as_float_from_string(const char* versionString);
bool has_gl_extension_from_string(const char* ext,
const char* extensionString);
+// these variants call glGetString()
bool has_gl_extension(const char* ext);
void gl_version(int* major, int* minor);
-
+float gl_version_as_float();
////////////////////////////////////////////////////////////////////////////////
diff --git a/gpu/src/GrGLInterface.cpp b/gpu/src/GrGLInterface.cpp
index 5ecf8eb591..2237474f97 100644
--- a/gpu/src/GrGLInterface.cpp
+++ b/gpu/src/GrGLInterface.cpp
@@ -54,6 +54,25 @@ void gl_version_from_string(int* major, int* minor,
}
}
+float gl_version_as_float_from_string(const char* versionString) {
+ int major, minor;
+ gl_version_from_string(&major, &minor, versionString);
+ GrAssert(minor >= 0);
+ // AFAIK there are only single digit minor numbers
+ if (minor < 10) {
+ return major + minor / 10.f;
+ } else if (minor < 100) {
+ return major + minor / 100.f;
+ } else if (minor < 1000) {
+ return major + minor / 1000.f;
+ } else {
+ GrAssert(!"Why so many digits in minor revision number?");
+ char temp[32];
+ sprintf(temp, "%d.%d", major, minor);
+ return (float) atof(temp);
+ }
+}
+
bool has_gl_extension_from_string(const char* ext,
const char* extensionString) {
int extLength = strlen(ext);
@@ -72,7 +91,6 @@ bool has_gl_extension_from_string(const char* ext,
return false;
}
-
GR_API void GrGLSetGLInterface(GrGLInterface* gl_interface) {
gGLInterface = gl_interface;
}
@@ -94,6 +112,12 @@ void gl_version(int* major, int* minor) {
gl_version_from_string(major, minor, v);
}
+float gl_version_as_float() {
+ const char* v = reinterpret_cast<const char*>(
+ GrGLGetGLInterface()->fGetString(GR_GL_VERSION));
+ return gl_version_as_float_from_string(v);
+}
+
bool GrGLInterface::validateShaderFunctions() const {
// required for GrGpuGLShaders
if (NULL == fAttachShader ||
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index fe51875bb9..1f9afdcb5d 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -262,7 +262,10 @@ static int probe_for_min_render_target_width(bool hasNPOTRenderTargetSupport,
}
-GrGpuGL::GrGpuGL() {
+GrGpuGL::GrGpuGL()
+ : fStencilFormats(8) {
+
+ GrGLClearErr();
if (gPrintStartupSpew) {
GrPrintf("------------------------- create GrGpuGL %p --------------\n",
@@ -277,9 +280,10 @@ GrGpuGL::GrGpuGL() {
GrGLGetGLInterface()->fGetString(GR_GL_EXTENSIONS));
}
- GrGLClearErr();
+ fGLVersion = gl_version_as_float();
+ fExtensionString = (const char*) GR_GL(GetString(GR_GL_EXTENSIONS));
- resetDirtyFlags();
+ this->resetDirtyFlags();
GrGLint maxTextureUnits;
// check FS and fixed-function texture unit limits
@@ -307,8 +311,7 @@ GrGpuGL::GrGpuGL() {
////////////////////////////////////////////////////////////////////////////
// Check for supported features.
- int major, minor;
- gl_version(&major, &minor);
+ this->setupStencilFormats();
GrGLint numFormats;
GR_GL_GetIntegerv(GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats);
@@ -333,19 +336,19 @@ GrGpuGL::GrGpuGL() {
memset(fAASamples, 0, sizeof(fAASamples));
fMSFBOType = kNone_MSFBO;
if (GR_GL_SUPPORT_ES) {
- if (has_gl_extension("GL_CHROMIUM_framebuffer_multisample")) {
+ if (this->hasExtension("GL_CHROMIUM_framebuffer_multisample")) {
// chrome's extension is equivalent to the EXT msaa
// and fbo_blit extensions.
fMSFBOType = kDesktopEXT_MSFBO;
- } else if (has_gl_extension("GL_APPLE_framebuffer_multisample")) {
+ } else if (this->hasExtension("GL_APPLE_framebuffer_multisample")) {
fMSFBOType = kAppleES_MSFBO;
}
} else {
GrAssert(GR_GL_SUPPORT_DESKTOP);
- if ((major >= 3) || has_gl_extension("GL_ARB_framebuffer_object")) {
+ if ((fGLVersion >= 3.f) || this->hasExtension("GL_ARB_framebuffer_object")) {
fMSFBOType = kDesktopARB_MSFBO;
- } else if (has_gl_extension("GL_EXT_framebuffer_multisample") &&
- has_gl_extension("GL_EXT_framebuffer_blit")) {
+ } else if (this->hasExtension("GL_EXT_framebuffer_multisample") &&
+ this->hasExtension("GL_EXT_framebuffer_blit")) {
fMSFBOType = kDesktopEXT_MSFBO;
}
}
@@ -386,10 +389,10 @@ GrGpuGL::GrGpuGL() {
fFSAASupport = fAASamples[kHigh_GrAALevel] > 0;
if (GR_GL_SUPPORT_DESKTOP) {
- fHasStencilWrap = (major >= 2 || (major == 1 && minor >= 4)) ||
- has_gl_extension("GL_EXT_stencil_wrap");
+ fHasStencilWrap = (fGLVersion >= 1.4f) ||
+ this->hasExtension("GL_EXT_stencil_wrap");
} else {
- fHasStencilWrap = (major >= 2) || has_gl_extension("GL_OES_stencil_wrap");
+ fHasStencilWrap = (fGLVersion >= 2.0f) || this->hasExtension("GL_OES_stencil_wrap");
}
if (gPrintStartupSpew) {
GrPrintf("Stencil Wrap: %s\n", (fHasStencilWrap ? "YES" : "NO"));
@@ -399,18 +402,17 @@ GrGpuGL::GrGpuGL() {
// we could also look for GL_ATI_separate_stencil extension or
// GL_EXT_stencil_two_side but they use different function signatures
// than GL2.0+ (and than each other).
- fTwoSidedStencilSupport = (major >= 2);
+ fTwoSidedStencilSupport = (fGLVersion >= 2.f);
// supported on GL 1.4 and higher or by extension
- fStencilWrapOpsSupport = (major > 1) ||
- ((1 == major) && (minor >= 4)) ||
- has_gl_extension("GL_EXT_stencil_wrap");
+ fStencilWrapOpsSupport = (fGLVersion >= 1.4f) ||
+ this->hasExtension("GL_EXT_stencil_wrap");
} else {
// ES 2 has two sided stencil but 1.1 doesn't. There doesn't seem to be
// an ES1 extension.
- fTwoSidedStencilSupport = (major >= 2);
+ fTwoSidedStencilSupport = (fGLVersion >= 2.f);
// stencil wrap support is in ES2, ES1 requires extension.
- fStencilWrapOpsSupport = (major > 1) ||
- has_gl_extension("GL_OES_stencil_wrap");
+ fStencilWrapOpsSupport = (fGLVersion >= 2.f) ||
+ this->hasExtension("GL_OES_stencil_wrap");
}
if (gPrintStartupSpew) {
GrPrintf("Stencil Caps: TwoSide: %s, Wrap: %s\n",
@@ -421,7 +423,7 @@ GrGpuGL::GrGpuGL() {
if (GR_GL_SUPPORT_DESKTOP) {
fRGBA8Renderbuffer = true;
} else {
- fRGBA8Renderbuffer = has_gl_extension("GL_OES_rgb8_rgba8");
+ fRGBA8Renderbuffer = this->hasExtension("GL_OES_rgb8_rgba8");
}
if (gPrintStartupSpew) {
GrPrintf("RGBA Renderbuffer: %s\n", (fRGBA8Renderbuffer ? "YES" : "NO"));
@@ -430,7 +432,7 @@ GrGpuGL::GrGpuGL() {
if (GR_GL_SUPPORT_ES) {
if (GR_GL_32BPP_COLOR_FORMAT == GR_GL_BGRA) {
- GrAssert(has_gl_extension("GL_EXT_texture_format_BGRA8888"));
+ GrAssert(this->hasExtension("GL_EXT_texture_format_BGRA8888"));
}
}
@@ -438,7 +440,7 @@ GrGpuGL::GrGpuGL() {
fBufferLockSupport = true; // we require VBO support and the desktop VBO
// extension includes glMapBuffer.
} else {
- fBufferLockSupport = has_gl_extension("GL_OES_mapbuffer");
+ fBufferLockSupport = this->hasExtension("GL_OES_mapbuffer");
}
if (gPrintStartupSpew) {
@@ -446,7 +448,8 @@ GrGpuGL::GrGpuGL() {
}
if (GR_GL_SUPPORT_DESKTOP) {
- if (major >= 2 || has_gl_extension("GL_ARB_texture_non_power_of_two")) {
+ if (fGLVersion >= 2.f ||
+ this->hasExtension("GL_ARB_texture_non_power_of_two")) {
fNPOTTextureTileSupport = true;
fNPOTTextureSupport = true;
} else {
@@ -454,12 +457,12 @@ GrGpuGL::GrGpuGL() {
fNPOTTextureSupport = false;
}
} else {
- if (major >= 2) {
+ if (fGLVersion >= 2.f) {
fNPOTTextureSupport = true;
- fNPOTTextureTileSupport = has_gl_extension("GL_OES_texture_npot");
+ fNPOTTextureTileSupport = this->hasExtension("GL_OES_texture_npot");
} else {
fNPOTTextureSupport =
- has_gl_extension("GL_APPLE_texture_2D_limited_npot");
+ this->hasExtension("GL_APPLE_texture_2D_limited_npot");
fNPOTTextureTileSupport = false;
}
}
@@ -685,37 +688,57 @@ GrRenderTarget* GrGpuGL::onCreateRenderTargetFrom3DApiState() {
///////////////////////////////////////////////////////////////////////////////
-static const GrGLuint UNKNOWN_BITS = ~0;
+void GrGpuGL::setupStencilFormats() {
-struct StencilFormat {
- GrGLenum fEnum;
- GrGLuint fBits;
- bool fPacked;
-};
-
-const StencilFormat* GrGLStencilFormats(int* count) {
- // defines stencil formats from more to less preferred
- static const StencilFormat desktopStencilFormats[] = {
- {GR_GL_STENCIL_INDEX8, 8, false},
- {GR_GL_STENCIL_INDEX16, 16, false},
- {GR_GL_DEPTH24_STENCIL8, 8, true },
- {GR_GL_STENCIL_INDEX4, 4, false},
- {GR_GL_STENCIL_INDEX, UNKNOWN_BITS, false},
- {GR_GL_DEPTH_STENCIL, UNKNOWN_BITS, true },
- };
+ // Build up list of legal stencil formats (though perhaps not supported on
+ // the particular gpu/driver) from most preferred to least.
- static const StencilFormat esStencilFormats[] = {
- {GR_GL_STENCIL_INDEX8, 8, false},
- {GR_GL_DEPTH24_STENCIL8, 8, true },
- {GR_GL_STENCIL_INDEX4, 4, false},
- };
+ // these consts are in order of most preferred to least preferred
+ // we don't bother with GL_STENCIL_INDEX1 or GL_DEPTH32F_STENCIL8
+ static const StencilFormat gS8 = {GR_GL_STENCIL_INDEX8, 8, false};
+ static const StencilFormat gS16 = {GR_GL_STENCIL_INDEX16, 16, false};
+ static const StencilFormat gD24S8 = {GR_GL_DEPTH24_STENCIL8, 8, true };
+ static const StencilFormat gS4 = {GR_GL_STENCIL_INDEX4, 4, false};
+ static const StencilFormat gS = {GR_GL_STENCIL_INDEX, gUNKNOWN_BITCOUNT, false};
+ static const StencilFormat gDS = {GR_GL_DEPTH_STENCIL, gUNKNOWN_BITCOUNT, true };
if (GR_GL_SUPPORT_DESKTOP) {
- *count = GR_ARRAY_COUNT(desktopStencilFormats);
- return desktopStencilFormats;
+ bool supportsPackedDS = fGLVersion >= 3.0f ||
+ this->hasExtension("GL_EXT_packed_depth_stencil") ||
+ this->hasExtension("GL_ARB_framebuffer_object");
+
+ // S1 thru S16 formats are in GL 3.0+, EXT_FBO, and ARB_FBO since we
+ // require FBO support we can expect these are legal formats and don't
+ // check. These also all support the unsized GL_STENCIL_INDEX.
+ fStencilFormats.push_back() = gS8;
+ fStencilFormats.push_back() = gS16;
+ if (supportsPackedDS) {
+ fStencilFormats.push_back() = gD24S8;
+ }
+ fStencilFormats.push_back() = gS4;
+ if (supportsPackedDS) {
+ fStencilFormats.push_back() = gDS;
+ }
} else {
- *count = GR_ARRAY_COUNT(esStencilFormats);
- return esStencilFormats;
+ // ES2 has STENCIL_INDEX8 without extensions.
+ // ES1 with GL_OES_framebuffer_object (which we require for ES1)
+ // introduces tokens for S1 thu S8 but there are separate extensions
+ // that make them legal (GL_OES_stencil1, ...).
+ // GL_OES_packed_depth_stencil adds DEPTH24_STENCIL8
+ // ES doesn't support using the unsized formats.
+
+ if (fGLVersion >= 2.f || this->hasExtension("GL_OES_stencil8")) {
+ fStencilFormats.push_back() = gS8;
+ }
+ //fStencilFormats.push_back() = gS16;
+ if (this->hasExtension("GL_OES_packed_depth_stencil")) {
+ fStencilFormats.push_back() = gD24S8;
+ }
+ if (this->hasExtension("GL_OES_stencil4")) {
+ fStencilFormats.push_back() = gS4;
+ }
+ // we require some stencil format.
+ GrAssert(fStencilFormats.count() > 0);
}
}
@@ -983,9 +1006,8 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
err = ~GR_GL_NO_ERROR;
int stencilFmtCnt;
- const StencilFormat* stencilFormats = NULL;
if (rtIDs.fStencilRenderbufferID) {
- stencilFormats = GrGLStencilFormats(&stencilFmtCnt);
+ stencilFmtCnt = fStencilFormats.count();
} else {
stencilFmtCnt = 1; // only 1 attempt when we don't need a stencil
}
@@ -1003,12 +1025,12 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
GR_GL_NO_ERR(RenderbufferStorageMultisample(
GR_GL_RENDERBUFFER,
samples,
- stencilFormats[sIdx].fEnum,
+ fStencilFormats[sIdx].fEnum,
glDesc.fAllocWidth,
glDesc.fAllocHeight));
} else {
GR_GL_NO_ERR(RenderbufferStorage(GR_GL_RENDERBUFFER,
- stencilFormats[sIdx].fEnum,
+ fStencilFormats[sIdx].fEnum,
glDesc.fAllocWidth,
glDesc.fAllocHeight));
}
@@ -1064,7 +1086,7 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
rtIDs.fStencilRenderbufferID));
// if it is a packed format bind to depth also, otherwise
// we may get an unsupported fbo completeness result
- if (stencilFormats[sIdx].fPacked) {
+ if (fStencilFormats[sIdx].fPacked) {
GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
GR_GL_DEPTH_ATTACHMENT,
GR_GL_RENDERBUFFER,
@@ -1076,7 +1098,7 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
if (status != GR_GL_FRAMEBUFFER_COMPLETE) {
// undo the depth bind
if (rtIDs.fStencilRenderbufferID &&
- stencilFormats[sIdx].fPacked) {
+ fStencilFormats[sIdx].fPacked) {
GR_GL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
GR_GL_DEPTH_ATTACHMENT,
GR_GL_RENDERBUFFER,
@@ -1088,10 +1110,10 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
failed = false;
if (rtIDs.fStencilRenderbufferID) {
fLastSuccessfulStencilFmtIdx = sIdx;
- if (UNKNOWN_BITS == stencilFormats[sIdx].fBits) {
+ if (gUNKNOWN_BITCOUNT == fStencilFormats[sIdx].fBits) {
GR_GL_GetIntegerv(GR_GL_STENCIL_BITS, (GrGLint*)&glDesc.fStencilBits);
} else {
- glDesc.fStencilBits = stencilFormats[sIdx].fBits;
+ glDesc.fStencilBits = fStencilFormats[sIdx].fBits;
}
}
break;
diff --git a/gpu/src/GrGpuGL.h b/gpu/src/GrGpuGL.h
index aec55d8b7b..7f13ea11a4 100644
--- a/gpu/src/GrGpuGL.h
+++ b/gpu/src/GrGpuGL.h
@@ -25,6 +25,8 @@
#include "GrGLVertexBuffer.h"
#include "GrGLIndexBuffer.h"
+#include "SkString.h"
+
class GrGpuGL : public GrGpu {
public:
virtual ~GrGpuGL();
@@ -48,6 +50,10 @@ protected:
DrState fHWDrawState;
bool fHWStencilClip;
+ // read these once at begining and then never again
+ SkString fExtensionString;
+ float fGLVersion;
+
// As flush of GL state proceeds it updates fHDrawState
// to reflect the new state. Later parts of the state flush
// may perform cascaded changes but cannot refer to fHWDrawState.
@@ -127,6 +133,10 @@ protected:
GrBlendCoeff srcCoeff,
GrBlendCoeff dstCoeff);
+ bool hasExtension(const char* ext) {
+ return has_gl_extension_from_string(ext, fExtensionString.c_str());
+ }
+
// adjusts texture matrix to account for orientation, size, and npotness
static void AdjustTextureMatrix(const GrGLTexture* texture,
GrSamplerState::SampleMode mode,
@@ -142,6 +152,9 @@ protected:
private:
+ // determines valid stencil formats
+ void setupStencilFormats();
+
// notify callbacks to update state tracking when related
// objects are bound to GL or deleted outside of the class
void notifyVertexBufferBind(const GrGLVertexBuffer* buffer);
@@ -175,6 +188,16 @@ private:
friend class GrGLTexture;
friend class GrGLRenderTarget;
+ static const GrGLuint gUNKNOWN_BITCOUNT = ~0;
+
+ struct StencilFormat {
+ GrGLenum fEnum;
+ GrGLuint fBits;
+ bool fPacked;
+ };
+
+ GrTArray<StencilFormat, true> fStencilFormats;
+
bool fHWBlendDisabled;
GrGLuint fAASamples[4];
diff --git a/gpu/src/GrGpuGLShaders.cpp b/gpu/src/GrGpuGLShaders.cpp
index b474be240e..13f7543ae5 100644
--- a/gpu/src/GrGpuGLShaders.cpp
+++ b/gpu/src/GrGpuGLShaders.cpp
@@ -248,14 +248,12 @@ void GrGpuGLShaders::ProgramUnitTest() {
GrGpuGLShaders::GrGpuGLShaders() {
resetContext();
- int major, minor;
- gl_version(&major, &minor);
f4X4DownsampleFilterSupport = true;
if (GR_GL_SUPPORT_DESKTOP) {
- fDualSourceBlendingSupport =
- major > 3 ||(3 == major && 3 <= minor) ||
- has_gl_extension("GL_ARB_blend_func_extended");
+ fDualSourceBlendingSupport =
+ fGLVersion >= 3.3f ||
+ this->hasExtension("GL_ARB_blend_func_extended");
} else {
fDualSourceBlendingSupport = false;
}