зеркало из https://github.com/mozilla/moz-skia.git
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
This commit is contained in:
Родитель
25fd36c7ef
Коммит
2c17fcdc45
|
@ -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();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
// Build up list of legal stencil formats (though perhaps not supported on
|
||||
// the particular gpu/driver) from most preferred to least.
|
||||
|
||||
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 },
|
||||
};
|
||||
|
||||
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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче