aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-02-26 21:46:32 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-02-26 21:46:32 +0000
commit1744f97ea73384b9f75b0ccee0a36a213c681d3a (patch)
tree984f3a6988234c1a797049b2a43705cf970c1866 /src/gpu
parent8d33a24cfe4540126ae00618cc691c610d398d8d (diff)
Use glGetStringi to get extensions when available.
Review URL: https://codereview.chromium.org/12328111 git-svn-id: http://skia.googlecode.com/svn/trunk@7872 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/gl/GrGLContextInfo.cpp12
-rw-r--r--src/gpu/gl/GrGLContextInfo.h5
-rw-r--r--src/gpu/gl/GrGLCreateNullInterface.cpp1
-rw-r--r--src/gpu/gl/GrGLDefines.h8
-rw-r--r--src/gpu/gl/GrGLExtensions.cpp79
-rw-r--r--src/gpu/gl/GrGLInterface.cpp57
-rw-r--r--src/gpu/gl/GrGLNoOpInterface.cpp82
-rw-r--r--src/gpu/gl/GrGLNoOpInterface.h2
-rw-r--r--src/gpu/gl/GrGLUtil.cpp24
-rw-r--r--src/gpu/gl/GrGLUtil.h2
-rw-r--r--src/gpu/gl/SkGLContext.cpp24
-rw-r--r--src/gpu/gl/debug/GrGLCreateDebugInterface.cpp1
-rw-r--r--src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp40
-rw-r--r--src/gpu/gl/mac/SkNativeGLContext_mac.cpp2
-rw-r--r--src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp40
-rw-r--r--src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp43
-rw-r--r--src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp52
17 files changed, 305 insertions, 169 deletions
diff --git a/src/gpu/gl/GrGLContextInfo.cpp b/src/gpu/gl/GrGLContextInfo.cpp
index 7a33ac7fee..1522618d03 100644
--- a/src/gpu/gl/GrGLContextInfo.cpp
+++ b/src/gpu/gl/GrGLContextInfo.cpp
@@ -31,7 +31,7 @@ GrGLContextInfo& GrGLContextInfo::operator = (const GrGLContextInfo& ctx) {
fGLVersion = ctx.fGLVersion;
fGLSLGeneration = ctx.fGLSLGeneration;
fVendor = ctx.fVendor;
- fExtensionString = ctx.fExtensionString;
+ fExtensions = ctx.fExtensions;
fGLCaps = ctx.fGLCaps;
return *this;
}
@@ -42,7 +42,7 @@ void GrGLContextInfo::reset() {
fGLVersion = GR_GL_VER(0, 0);
fGLSLGeneration = static_cast<GrGLSLGeneration>(0);
fVendor = kOther_GrGLVendor;
- fExtensionString = "";
+ fExtensions.reset();
fGLCaps.reset();
}
@@ -50,14 +50,13 @@ bool GrGLContextInfo::initialize(const GrGLInterface* interface) {
this->reset();
// We haven't validated the GrGLInterface yet, so check for GetString
// function pointer
- if (NULL != interface->fGetString) {
-
+ if (interface->fGetString) {
const GrGLubyte* verUByte;
GR_GL_CALL_RET(interface, verUByte, GetString(GR_GL_VERSION));
const char* ver = reinterpret_cast<const char*>(verUByte);
GrGLBinding binding = GrGLGetBindingInUseFromString(ver);
- if (interface->validate(binding)) {
+ if (0 != binding && interface->validate(binding) && fExtensions.init(binding, interface)) {
fInterface = interface;
interface->ref();
@@ -69,9 +68,6 @@ bool GrGLContextInfo::initialize(const GrGLInterface* interface) {
fGLSLGeneration = GrGetGLSLGeneration(fBindingInUse,
this->interface());
- const GrGLubyte* ext;
- GR_GL_CALL_RET(interface, ext, GetString(GR_GL_EXTENSIONS));
- fExtensionString = reinterpret_cast<const char*>(ext);
fVendor = GrGLGetVendor(interface);
fGLCaps.init(*this);
return true;
diff --git a/src/gpu/gl/GrGLContextInfo.h b/src/gpu/gl/GrGLContextInfo.h
index a6c997f5a2..bfadabe87f 100644
--- a/src/gpu/gl/GrGLContextInfo.h
+++ b/src/gpu/gl/GrGLContextInfo.h
@@ -9,6 +9,7 @@
#ifndef GrGLContextInfo_DEFINED
#define GrGLContextInfo_DEFINED
+#include "gl/GrGLExtensions.h"
#include "gl/GrGLInterface.h"
#include "GrGLCaps.h"
#include "GrGLSL.h"
@@ -70,7 +71,7 @@ public:
if (!this->isInitialized()) {
return false;
}
- return GrGLHasExtensionFromString(ext, fExtensionString.c_str());
+ return fExtensions.has(ext);
}
private:
@@ -81,7 +82,7 @@ private:
GrGLVersion fGLVersion;
GrGLSLGeneration fGLSLGeneration;
GrGLVendor fVendor;
- SkString fExtensionString;
+ GrGLExtensions fExtensions;
GrGLCaps fGLCaps;
};
diff --git a/src/gpu/gl/GrGLCreateNullInterface.cpp b/src/gpu/gl/GrGLCreateNullInterface.cpp
index d221218b8a..da6491a6d5 100644
--- a/src/gpu/gl/GrGLCreateNullInterface.cpp
+++ b/src/gpu/gl/GrGLCreateNullInterface.cpp
@@ -215,6 +215,7 @@ const GrGLInterface* GrGLCreateNullInterface() {
interface->fGetShaderInfoLog = noOpGLGetInfoLog;
interface->fGetShaderiv = noOpGLGetShaderOrProgramiv;
interface->fGetString = noOpGLGetString;
+ interface->fGetStringi = noOpGLGetStringi;
interface->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv;
interface->fGetUniformLocation = noOpGLGetUniformLocation;
interface->fLineWidth = noOpGLLineWidth;
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index 852c0254c7..e0e8398795 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -10,6 +10,11 @@
#ifndef GrGLDefines_DEFINED
#define GrGLDefines_DEFINED
+/* Profiles */
+#define GR_GL_CONTEXT_PROFILE_MASK 0x9126
+#define GR_GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+
// The following constants consist of the intersection of GL constants
// exported by GLES 1.0, GLES 2.0, and desktop GL required by the system.
@@ -356,6 +361,9 @@
#define GR_GL_VERSION 0x1F02
#define GR_GL_EXTENSIONS 0x1F03
+/* StringCounts */
+#define GR_GL_NUM_EXTENSIONS 0x821D
+
/* Pixel Mode / Transfer */
#define GR_GL_UNPACK_ROW_LENGTH 0x0CF2
#define GR_GL_PACK_ROW_LENGTH 0x0D02
diff --git a/src/gpu/gl/GrGLExtensions.cpp b/src/gpu/gl/GrGLExtensions.cpp
new file mode 100644
index 0000000000..b5df2cc959
--- /dev/null
+++ b/src/gpu/gl/GrGLExtensions.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gl/GrGLExtensions.h"
+#include "gl/GrGLDefines.h"
+#include "gl/GrGLUtil.h"
+
+bool GrGLExtensions::init(GrGLBinding binding,
+ GrGLGetStringProc getString,
+ GrGLGetStringiProc getStringi,
+ GrGLGetIntegervProc getIntegerv) {
+ fStrings.reset();
+ if (NULL == getString) {
+ return false;
+ }
+ bool indexed = false;
+ if (kDesktop_GrGLBinding == binding) {
+ const GrGLubyte* verString = getString(GR_GL_VERSION);
+ if (NULL == verString) {
+ return false;
+ }
+ GrGLVersion version = GrGLGetVersionFromString((const char*) verString);
+ indexed = version >= GR_GL_VER(3, 0);
+ }
+ if (indexed) {
+ if (NULL == getStringi || NULL == getIntegerv) {
+ return false;
+ }
+ GrGLint extensionCnt = 0;
+ getIntegerv(GR_GL_NUM_EXTENSIONS, &extensionCnt);
+ fStrings.push_back_n(extensionCnt);
+ for (int i = 0; i < extensionCnt; ++i) {
+ const char* ext = (const char*) getStringi(GR_GL_EXTENSIONS, i);
+ fStrings[i] = ext;
+ }
+ } else {
+ const char* extensions = (const char*) getString(GR_GL_EXTENSIONS);
+ if (NULL == extensions) {
+ return false;
+ }
+ // First count the extensions so that we don't cause the array to malloc multiple times.
+ int extensionCnt = 1;
+ const char* e = (const char*) extensions;
+ while (NULL != (e = strchr(e+1, ' '))) {
+ e += 1;
+ ++extensionCnt;
+ }
+ fStrings.push_back_n(extensionCnt);
+
+ int i = 0;
+ while (true) {
+ size_t length = strcspn(extensions, " ");
+ GrAssert(i < extensionCnt);
+ fStrings[i].set(extensions, length);
+ ++i;
+ if ('\0' == extensions[length]) {
+ break;
+ }
+ extensions += length + 1;
+ }
+ GrAssert(i == extensionCnt);
+ }
+ return true;
+}
+
+bool GrGLExtensions::has(const char* ext) const {
+ // TODO: Sort the extensions and binary search.
+ int count = fStrings.count();
+ for (int i = 0; i < count; ++i) {
+ if (fStrings[i].equals(ext)) {
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp
index 61020bc2e3..f1be64fc34 100644
--- a/src/gpu/gl/GrGLInterface.cpp
+++ b/src/gpu/gl/GrGLInterface.cpp
@@ -7,7 +7,8 @@
#include "gl/GrGLInterface.h"
-#include "GrGLUtil.h"
+#include "gl/GrGLExtensions.h"
+#include "gl/GrGLUtil.h"
#include <stdio.h>
@@ -37,6 +38,11 @@ bool GrGLInterface::validate(GrGLBinding binding) const {
if (0 == (binding & fBindingsExported)) {
return false;
}
+
+ GrGLExtensions extensions;
+ if (!extensions.init(binding, this)) {
+ return false;
+ }
// functions that are always required
if (NULL == fActiveTexture ||
@@ -131,9 +137,7 @@ bool GrGLInterface::validate(GrGLBinding binding) const {
return false;
}
- const char* ext;
GrGLVersion glVer = GrGLGetVersion(this);
- ext = (const char*)fGetString(GR_GL_EXTENSIONS);
// Now check that baseline ES/Desktop fns not covered above are present
// and that we have fn pointers for any advertised extensions that we will
@@ -160,15 +164,13 @@ bool GrGLInterface::validate(GrGLBinding binding) const {
if (glVer >= GR_GL_VER(3,0) && NULL == fBindFragDataLocation) {
return false;
}
- if (glVer >= GR_GL_VER(2,0) ||
- GrGLHasExtensionFromString("GL_ARB_draw_buffers", ext)) {
+ if (glVer >= GR_GL_VER(2,0) || extensions.has("GL_ARB_draw_buffers")) {
if (NULL == fDrawBuffers) {
return false;
}
}
- if (glVer >= GR_GL_VER(1,5) ||
- GrGLHasExtensionFromString("GL_ARB_occlusion_query", ext)) {
+ if (glVer >= GR_GL_VER(1,5) || extensions.has("GL_ARB_occlusion_query")) {
if (NULL == fGenQueries ||
NULL == fDeleteQueries ||
NULL == fBeginQuery ||
@@ -180,15 +182,14 @@ bool GrGLInterface::validate(GrGLBinding binding) const {
}
}
if (glVer >= GR_GL_VER(3,3) ||
- GrGLHasExtensionFromString("GL_ARB_timer_query", ext) ||
- GrGLHasExtensionFromString("GL_EXT_timer_query", ext)) {
+ extensions.has("GL_ARB_timer_query") ||
+ extensions.has("GL_EXT_timer_query")) {
if (NULL == fGetQueryObjecti64v ||
NULL == fGetQueryObjectui64v) {
return false;
}
}
- if (glVer >= GR_GL_VER(3,3) ||
- GrGLHasExtensionFromString("GL_ARB_timer_query", ext)) {
+ if (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) {
if (NULL == fQueryCounter) {
return false;
}
@@ -202,7 +203,7 @@ bool GrGLInterface::validate(GrGLBinding binding) const {
NULL == fLoadMatrixf)) {
return false;
}
- if (false && GrGLHasExtensionFromString("GL_NV_path_rendering", ext)) {
+ if (false && extensions.has("GL_NV_path_rendering")) {
if (NULL == fPathCommands ||
NULL == fPathCoords ||
NULL == fPathSubCommands ||
@@ -259,8 +260,8 @@ bool GrGLInterface::validate(GrGLBinding binding) const {
// optional function on desktop before 1.3
if (kDesktop_GrGLBinding != binding ||
- (glVer >= GR_GL_VER(1,3) ||
- GrGLHasExtensionFromString("GL_ARB_texture_compression", ext))) {
+ (glVer >= GR_GL_VER(1,3)) ||
+ extensions.has("GL_ARB_texture_compression")) {
if (NULL == fCompressedTexImage2D) {
return false;
}
@@ -279,13 +280,13 @@ bool GrGLInterface::validate(GrGLBinding binding) const {
// There is a desktop ARB extension and an ES+desktop EXT extension
if (kDesktop_GrGLBinding == binding) {
if (glVer >= GR_GL_VER(4,2) ||
- GrGLHasExtensionFromString("GL_ARB_texture_storage", ext) ||
- GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) {
+ extensions.has("GL_ARB_texture_storage") ||
+ extensions.has("GL_EXT_texture_storage")) {
if (NULL == fTexStorage2D) {
return false;
}
}
- } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) {
+ } else if (extensions.has("GL_EXT_texture_storage")) {
if (NULL == fTexStorage2D) {
return false;
}
@@ -294,29 +295,29 @@ bool GrGLInterface::validate(GrGLBinding binding) const {
// FBO MSAA
if (kDesktop_GrGLBinding == binding) {
// GL 3.0 and the ARB extension have multisample + blit
- if (glVer >= GR_GL_VER(3,0) || GrGLHasExtensionFromString("GL_ARB_framebuffer_object", ext)) {
+ if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) {
if (NULL == fRenderbufferStorageMultisample ||
NULL == fBlitFramebuffer) {
return false;
}
} else {
- if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", ext) &&
+ if (extensions.has("GL_EXT_framebuffer_blit") &&
NULL == fBlitFramebuffer) {
return false;
}
- if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", ext) &&
+ if (extensions.has("GL_EXT_framebuffer_multisample") &&
NULL == fRenderbufferStorageMultisample) {
return false;
}
}
} else {
- if (GrGLHasExtensionFromString("GL_CHROMIUM_framebuffer_multisample", ext)) {
+ if (extensions.has("GL_CHROMIUM_framebuffer_multisample")) {
if (NULL == fRenderbufferStorageMultisample ||
NULL == fBlitFramebuffer) {
return false;
}
}
- if (GrGLHasExtensionFromString("GL_APPLE_framebuffer_multisample", ext)) {
+ if (extensions.has("GL_APPLE_framebuffer_multisample")) {
if (NULL == fRenderbufferStorageMultisample ||
NULL == fResolveMultisampleFramebuffer) {
return false;
@@ -327,8 +328,7 @@ bool GrGLInterface::validate(GrGLBinding binding) const {
// On ES buffer mapping is an extension. On Desktop
// buffer mapping was part of original VBO extension
// which we require.
- if (kDesktop_GrGLBinding == binding ||
- GrGLHasExtensionFromString("GL_OES_mapbuffer", ext)) {
+ if (kDesktop_GrGLBinding == binding || extensions.has("GL_OES_mapbuffer")) {
if (NULL == fMapBuffer ||
NULL == fUnmapBuffer) {
return false;
@@ -337,12 +337,17 @@ bool GrGLInterface::validate(GrGLBinding binding) const {
// Dual source blending
if (kDesktop_GrGLBinding == binding &&
- (glVer >= GR_GL_VER(3,3) ||
- GrGLHasExtensionFromString("GL_ARB_blend_func_extended", ext))) {
+ (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_blend_func_extended"))) {
if (NULL == fBindFragDataLocationIndexed) {
return false;
}
}
+
+ if (kDesktop_GrGLBinding == binding && glVer >= GR_GL_VER(3, 0)) {
+ if (NULL == fGetStringi) {
+ return false;
+ }
+ }
return true;
}
diff --git a/src/gpu/gl/GrGLNoOpInterface.cpp b/src/gpu/gl/GrGLNoOpInterface.cpp
index 5dd6e66820..e830ee18f9 100644
--- a/src/gpu/gl/GrGLNoOpInterface.cpp
+++ b/src/gpu/gl/GrGLNoOpInterface.cpp
@@ -6,6 +6,8 @@
*/
#include "GrGLNoOpInterface.h"
+#include "SkString.h"
+#include "SkThread.h"
// the OpenGLES 2.0 spec says this must be >= 128
static const GrGLint kDefaultMaxVertexUniformVectors = 128;
@@ -19,6 +21,33 @@ static const GrGLint kDefaultMaxVertexAttribs = 8;
// the OpenGLES 2.0 spec says this must be >= 8
static const GrGLint kDefaultMaxVaryingVectors = 8;
+static const char* kExtensions[] = {
+ "GL_ARB_framebuffer_object",
+ "GL_ARB_blend_func_extended",
+ "GL_ARB_timer_query",
+ "GL_ARB_draw_buffers",
+ "GL_ARB_occlusion_query",
+ "GL_EXT_blend_color",
+ "GL_EXT_stencil_wrap"
+};
+
+namespace {
+const GrGLubyte* combined_extensions_string() {
+ static SkString gExtString;
+ static SkMutex gMutex;
+ gMutex.acquire();
+ if (0 == gExtString.size()) {
+ for (size_t i = 0; i < GR_ARRAY_COUNT(kExtensions) - 1; ++i) {
+ gExtString.append(kExtensions[i]);
+ gExtString.append(" ");
+ }
+ gExtString.append(kExtensions[GR_ARRAY_COUNT(kExtensions) - 1]);
+ }
+ gMutex.release();
+ return (const GrGLubyte*) gExtString.c_str();
+}
+}
+
GrGLvoid GR_GL_FUNCTION_TYPE noOpGLBlendColor(GrGLclampf red,
GrGLclampf green,
GrGLclampf blue,
@@ -53,9 +82,9 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLClearStencil(GrGLint s) {
}
GrGLvoid GR_GL_FUNCTION_TYPE noOpGLColorMask(GrGLboolean red,
- GrGLboolean green,
- GrGLboolean blue,
- GrGLboolean alpha) {
+ GrGLboolean green,
+ GrGLboolean blue,
+ GrGLboolean alpha) {
}
GrGLvoid GR_GL_FUNCTION_TYPE noOpGLCompileShader(GrGLuint shader) {
@@ -132,9 +161,9 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLReadBuffer(GrGLenum src) {
}
GrGLvoid GR_GL_FUNCTION_TYPE noOpGLScissor(GrGLint x,
- GrGLint y,
- GrGLsizei width,
- GrGLsizei height) {
+ GrGLint y,
+ GrGLsizei width,
+ GrGLsizei height) {
}
GrGLvoid GR_GL_FUNCTION_TYPE noOpGLShaderSource(GrGLuint shader,
@@ -318,15 +347,15 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLVertexAttribPointer(GrGLuint indx,
}
GrGLvoid GR_GL_FUNCTION_TYPE noOpGLViewport(GrGLint x,
- GrGLint y,
- GrGLsizei width,
- GrGLsizei height) {
+ GrGLint y,
+ GrGLsizei width,
+ GrGLsizei height) {
}
GrGLvoid GR_GL_FUNCTION_TYPE noOpGLGetFramebufferAttachmentParameteriv(GrGLenum target,
- GrGLenum attachment,
- GrGLenum pname,
- GrGLint* params) {
+ GrGLenum attachment,
+ GrGLenum pname,
+ GrGLint* params) {
}
GrGLvoid GR_GL_FUNCTION_TYPE noOpGLGetRenderbufferParameteriv(GrGLenum target,
@@ -393,6 +422,9 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLGetIntegerv(GrGLenum pname, GrGLint* params)
// TODO: remove from Ganesh the #defines for gets we don't use.
// We would like to minimize gets overall due to performance issues
switch (pname) {
+ case GR_GL_CONTEXT_PROFILE_MASK:
+ *params = GR_GL_CONTEXT_COMPATIBILITY_PROFILE_BIT;
+ break;
case GR_GL_STENCIL_BITS:
*params = 8;
break;
@@ -440,6 +472,9 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLGetIntegerv(GrGLenum pname, GrGLint* params)
case GR_GL_MAX_VARYING_VECTORS:
*params = kDefaultMaxVaryingVectors;
break;
+ case GR_GL_NUM_EXTENSIONS:
+ *params = GR_ARRAY_COUNT(kExtensions);
+ break;
default:
GrCrash("Unexpected pname to GetIntegerv");
}
@@ -448,7 +483,7 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLGetIntegerv(GrGLenum pname, GrGLint* params)
GrGLvoid GR_GL_FUNCTION_TYPE noOpGLGetInfoLog(GrGLuint program,
GrGLsizei bufsize,
GrGLsizei* length,
- char* infolog) {
+ char* infolog) {
if (length) {
*length = 0;
}
@@ -534,7 +569,7 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLGetQueryObjectuiv(GrGLuint id,
const GrGLubyte* GR_GL_FUNCTION_TYPE noOpGLGetString(GrGLenum name) {
switch (name) {
case GR_GL_EXTENSIONS:
- return (const GrGLubyte*)"GL_ARB_framebuffer_object GL_ARB_blend_func_extended GL_ARB_timer_query GL_ARB_draw_buffers GL_ARB_occlusion_query GL_EXT_blend_color GL_EXT_stencil_wrap";
+ return combined_extensions_string();
case GR_GL_VERSION:
return (const GrGLubyte*)"4.0 Debug GL";
case GR_GL_SHADING_LANGUAGE_VERSION:
@@ -544,11 +579,25 @@ const GrGLubyte* GR_GL_FUNCTION_TYPE noOpGLGetString(GrGLenum name) {
case GR_GL_RENDERER:
return (const GrGLubyte*)"The Debug (Non-)Renderer";
default:
- GrCrash("Unexpected name to GetString");
+ GrCrash("Unexpected name passed to GetString");
return NULL;
}
}
+const GrGLubyte* GR_GL_FUNCTION_TYPE noOpGLGetStringi(GrGLenum name, GrGLuint i) {
+ switch (name) {
+ case GR_GL_EXTENSIONS:
+ if (static_cast<size_t>(i) <= GR_ARRAY_COUNT(kExtensions)) {
+ return (const GrGLubyte*) kExtensions[i];
+ } else {
+ return NULL;
+ }
+ default:
+ GrCrash("Unexpected name passed to GetStringi");
+ return NULL;
+ }
+}
+
GrGLvoid GR_GL_FUNCTION_TYPE noOpGLGetTexLevelParameteriv(GrGLenum target,
GrGLint level,
GrGLenum pname,
@@ -558,8 +607,7 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLGetTexLevelParameteriv(GrGLenum target,
GrCrash("Should never query texture parameters.");
}
-GrGLint GR_GL_FUNCTION_TYPE noOpGLGetUniformLocation(GrGLuint program,
- const char* name) {
+GrGLint GR_GL_FUNCTION_TYPE noOpGLGetUniformLocation(GrGLuint program, const char* name) {
static int gUniLocation = 0;
return ++gUniLocation;
}
diff --git a/src/gpu/gl/GrGLNoOpInterface.h b/src/gpu/gl/GrGLNoOpInterface.h
index 0b3865d687..79695e5637 100644
--- a/src/gpu/gl/GrGLNoOpInterface.h
+++ b/src/gpu/gl/GrGLNoOpInterface.h
@@ -335,6 +335,8 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLGetQueryObjectuiv(GrGLuint id,
const GrGLubyte* GR_GL_FUNCTION_TYPE noOpGLGetString(GrGLenum name);
+const GrGLubyte* GR_GL_FUNCTION_TYPE noOpGLGetStringi(GrGLenum name, GrGLuint i);
+
GrGLvoid GR_GL_FUNCTION_TYPE noOpGLGetTexLevelParameteriv(GrGLenum target,
GrGLint level,
GrGLenum pname,
diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp
index 88c81b7d4e..f4c5da67d5 100644
--- a/src/gpu/gl/GrGLUtil.cpp
+++ b/src/gpu/gl/GrGLUtil.cpp
@@ -8,7 +8,6 @@
#include "GrGLUtil.h"
-
void GrGLClearErr(const GrGLInterface* gl) {
while (GR_GL_NO_ERROR != gl->fGetError()) {}
}
@@ -149,23 +148,6 @@ GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
return 0;
}
-bool GrGLHasExtensionFromString(const char* ext, const char* extensionString) {
- int extLength = strlen(ext);
-
- while (true) {
- int n = strcspn(extensionString, " ");
- if (n == extLength && 0 == strncmp(ext, extensionString, n)) {
- return true;
- }
- if (0 == extensionString[n]) {
- return false;
- }
- extensionString += n+1;
- }
-
- return false;
-}
-
GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
if (NULL != vendorString) {
if (0 == strcmp(vendorString, "ARM")) {
@@ -181,12 +163,6 @@ GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
return kOther_GrGLVendor;
}
-bool GrGLHasExtension(const GrGLInterface* gl, const char* ext) {
- const GrGLubyte* glstr;
- GR_GL_CALL_RET(gl, glstr, GetString(GR_GL_EXTENSIONS));
- return GrGLHasExtensionFromString(ext, (const char*) glstr);
-}
-
GrGLBinding GrGLGetBindingInUse(const GrGLInterface* gl) {
const GrGLubyte* v;
GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index 30995a9fe1..ea84480f66 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -71,11 +71,9 @@ enum GrGLVendor {
GrGLVersion GrGLGetVersionFromString(const char* versionString);
GrGLBinding GrGLGetBindingInUseFromString(const char* versionString);
GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString);
-bool GrGLHasExtensionFromString(const char* ext, const char* extensionString);
GrGLVendor GrGLGetVendorFromString(const char* vendorString);
// these variants call glGetString()
-bool GrGLHasExtension(const GrGLInterface*, const char* ext);
GrGLBinding GrGLGetBindingInUse(const GrGLInterface*);
GrGLVersion GrGLGetVersion(const GrGLInterface*);
GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface*);
diff --git a/src/gpu/gl/SkGLContext.cpp b/src/gpu/gl/SkGLContext.cpp
index c1b9505698..6076845082 100644
--- a/src/gpu/gl/SkGLContext.cpp
+++ b/src/gpu/gl/SkGLContext.cpp
@@ -6,7 +6,7 @@
* found in the LICENSE file.
*/
#include "gl/SkGLContext.h"
-#include "gl/GrGLUtil.h"
+#include "GrGLUtil.h"
SK_DEFINE_INST_COUNT(SkGLContext)
@@ -29,10 +29,6 @@ SkGLContext::~SkGLContext() {
SkSafeUnref(fGL);
}
-bool SkGLContext::hasExtension(const char* extensionName) const {
- return GrGLHasExtensionFromString(extensionName, fExtensionString.c_str());
-}
-
bool SkGLContext::init(int width, int height) {
if (fGL) {
fGL->unref();
@@ -43,8 +39,13 @@ bool SkGLContext::init(int width, int height) {
if (fGL) {
const GrGLubyte* temp;
- SK_GL_RET(*this, temp, GetString(GR_GL_EXTENSIONS));
- fExtensionString = reinterpret_cast<const char*>(temp);
+ GrGLBinding bindingInUse = GrGLGetBindingInUse(this->gl());
+
+ if (!fGL->validate(bindingInUse) || !fExtensions.init(bindingInUse, fGL)) {
+ fGL = NULL;
+ this->destroyGLContext();
+ return false;
+ }
SK_GL_RET(*this, temp, GetString(GR_GL_VERSION));
const char* versionStr = reinterpret_cast<const char*>(temp);
@@ -56,8 +57,6 @@ bool SkGLContext::init(int width, int height) {
SK_GL_RET(*this, error, GetError());
} while (GR_GL_NO_ERROR != error);
- GrGLBinding bindingInUse = GrGLGetBindingInUse(this->gl());
-
SK_GL(*this, GenFramebuffers(1, &fFBO));
SK_GL(*this, BindFramebuffer(GR_GL_FRAMEBUFFER, fFBO));
SK_GL(*this, GenRenderbuffers(1, &fColorBufferID));
@@ -83,12 +82,11 @@ bool SkGLContext::init(int width, int height) {
// depth stencil being available.
bool supportsPackedDepthStencil;
if (kES2_GrGLBinding == bindingInUse) {
- supportsPackedDepthStencil =
- this->hasExtension("GL_OES_packed_depth_stencil");
+ supportsPackedDepthStencil = this->hasExtension("GL_OES_packed_depth_stencil");
} else {
supportsPackedDepthStencil = version >= GR_GL_VER(3,0) ||
- this->hasExtension("GL_EXT_packed_depth_stencil") ||
- this->hasExtension("GL_ARB_framebuffer_object");
+ this->hasExtension("GL_EXT_packed_depth_stencil") ||
+ this->hasExtension("GL_ARB_framebuffer_object");
}
if (supportsPackedDepthStencil) {
diff --git a/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp b/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp
index ef7658613c..ab3501c14b 100644
--- a/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp
+++ b/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp
@@ -814,6 +814,7 @@ const GrGLInterface* GrGLCreateDebugInterface() {
interface->fGetShaderInfoLog = noOpGLGetInfoLog;
interface->fGetShaderiv = noOpGLGetShaderOrProgramiv;
interface->fGetString = noOpGLGetString;
+ interface->fGetStringi = noOpGLGetStringi;
interface->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv;
interface->fGetUniformLocation = noOpGLGetUniformLocation;
interface->fLineWidth = noOpGLLineWidth;
diff --git a/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp b/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp
index fce96f4cc5..7307540849 100644
--- a/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp
+++ b/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp
@@ -8,7 +8,8 @@
#include "gl/GrGLInterface.h"
-#include "../GrGLUtil.h"
+#include "gl/GrGLExtensions.h"
+#include "GrGLUtil.h"
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
@@ -31,8 +32,12 @@ const GrGLInterface* GrGLCreateNativeInterface() {
glInterface.reset(interface);
const char* verStr = (const char*) glGetString(GL_VERSION);
GrGLVersion ver = GrGLGetVersionFromString(verStr);
- const char* extStr = (const char*) glGetString(GL_EXTENSIONS);
-
+ GrGLExtensions extensions;
+ GrGLGetStringiProc glGetStringi = (GrGLGetStringiProc) GetProcAddress("glGetStringi");
+ if (!extensions.init(kDesktop_GrGLBinding, glGetString, glGetStringi, glGetIntegerv)) {
+ glInterface.reset(NULL);
+ return NULL;
+ }
interface->fBindingsExported = kDesktop_GrGLBinding;
interface->fActiveTexture = glActiveTexture;
interface->fAttachShader = glAttachShader;
@@ -51,8 +56,8 @@ const GrGLInterface* GrGLCreateNativeInterface() {
if (ver >= GR_GL_VER(1,4)) {
interface->fBlendColor = glBlendColor;
- } else if (GrGLHasExtensionFromString("GL_ARB_imaging", extStr) ||
- GrGLHasExtensionFromString("GL_EXT_blend_color", extStr)) {
+ } else if (extensions.has("GL_ARB_imaging") ||
+ extensions.has("GL_EXT_blend_color")) {
GET_PROC(BlendColor);
}
@@ -74,8 +79,7 @@ const GrGLInterface* GrGLCreateNativeInterface() {
interface->fDeleteTextures = glDeleteTextures;
interface->fDepthMask = glDepthMask;
interface->fDisable = glDisable;
- interface->fDisableVertexAttribArray =
- glDisableVertexAttribArray;
+ interface->fDisableVertexAttribArray = glDisableVertexAttribArray;
interface->fDrawArrays = glDrawArrays;
interface->fDrawBuffer = glDrawBuffer;
interface->fDrawBuffers = glDrawBuffers;
@@ -99,6 +103,7 @@ const GrGLInterface* GrGLCreateNativeInterface() {
interface->fGetShaderInfoLog = glGetShaderInfoLog;
interface->fGetShaderiv = glGetShaderiv;
interface->fGetString = glGetString;
+ interface->fGetStringi = glGetStringi;
interface->fGetTexLevelParameteriv = glGetTexLevelParameteriv;
interface->fGenTextures = glGenTextures;
interface->fGetUniformLocation = glGetUniformLocation;
@@ -131,10 +136,9 @@ const GrGLInterface* GrGLCreateNativeInterface() {
#elif GL_EXT_texture_storage
interface->fTexStorage2D = glTexStorage2DEXT;
#else
- if (ver >= GR_GL_VER(4,2) ||
- GrGLHasExtensionFromString("GL_ARB_texture_storage", extStr)) {
+ if (ver >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage")) {
GET_PROC(TexStorage2D);
- } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", extStr)) {
+ } else if (extensions.has("GL_EXT_texture_storage")) {
GET_PROC_SUFFIX(TexStorage2D, EXT);
}
#endif
@@ -165,7 +169,7 @@ const GrGLInterface* GrGLCreateNativeInterface() {
interface->fVertexAttribPointer = glVertexAttribPointer;
interface->fViewport = glViewport;
- if (ver >= GR_GL_VER(3,3) || GrGLHasExtensionFromString("GL_ARB_timer_query", extStr)) {
+ if (ver >= GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) {
// ARB extension doesn't use the ARB suffix on the function name
#if GL_ARB_timer_query || GL_VERSION_3_3
interface->fQueryCounter = glQueryCounter;
@@ -176,7 +180,7 @@ const GrGLInterface* GrGLCreateNativeInterface() {
interface->fGetQueryObjecti64v = GET_PROC(GetQueryObjecti64v);
interface->fGetQueryObjectui64v = GET_PROC(GetQueryObjectui64v);
#endif
- } else if (GrGLHasExtensionFromString("GL_EXT_timer_query", extStr)) {
+ } else if (extensions.has("GL_EXT_timer_query")) {
#if GL_EXT_timer_query
interface->fGetQueryObjecti64v = glGetQueryObjecti64vEXT;
interface->fGetQueryObjectui64v = glGetQueryObjectui64vEXT;
@@ -186,7 +190,7 @@ const GrGLInterface* GrGLCreateNativeInterface() {
#endif
}
- if (ver >= GR_GL_VER(3,0) || GrGLHasExtensionFromString("GL_ARB_framebuffer_object", extStr)) {
+ if (ver >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) {
// ARB extension doesn't use the ARB suffix on the function names
#if GL_VERSION_3_0 || GL_ARB_framebuffer_object
interface->fGenFramebuffers = glGenFramebuffers;
@@ -220,7 +224,7 @@ const GrGLInterface* GrGLCreateNativeInterface() {
interface->fBlitFramebuffer = GET_PROC(BlitFramebuffer);
#endif
} else {
- if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object", extStr)) {
+ if (extensions.has("GL_EXT_framebuffer_object")) {
#if GL_EXT_framebuffer_object
interface->fGenFramebuffers = glGenFramebuffersEXT;
interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameterivEXT;
@@ -249,14 +253,14 @@ const GrGLInterface* GrGLCreateNativeInterface() {
interface->fBindRenderbuffer = GET_PROC_SUFFIX(BindRenderbuffer, EXT);
#endif
}
- if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", extStr)) {
+ if (extensions.has("GL_EXT_framebuffer_multisample")) {
#if GL_EXT_framebuffer_multisample
interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisampleEXT;
#else
interface->fRenderbufferStorageMultisample = GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
#endif
}
- if (GrGLHasExtensionFromString("", extStr)) {
+ if (extensions.has("GL_EXT_framebuffer_blit")) {
#if GL_EXT_framebuffer_blit
interface->fBlitFramebuffer = glBlitFramebufferEXT;
#else
@@ -264,7 +268,7 @@ const GrGLInterface* GrGLCreateNativeInterface() {
#endif
}
}
- if (ver >= GR_GL_VER(3,3) || GrGLHasExtensionFromString("GL_ARB_blend_func_extended", extStr)) {
+ if (ver >= GR_GL_VER(3,3) || extensions.has("GL_ARB_blend_func_extended")) {
// ARB extension doesn't use the ARB suffix on the function name
#if GL_VERSION_3_3 || GL_ARB_blend_func_extended
interface->fBindFragDataLocationIndexed = glBindFragDataLocationIndexed;
@@ -272,8 +276,6 @@ const GrGLInterface* GrGLCreateNativeInterface() {
interface->fBindFragDataLocationIndexed = GET_PROC(BindFragDataLocationIndexed);
#endif
}
-
- interface->fBindingsExported = kDesktop_GrGLBinding;
}
glInterface.get()->ref();
return glInterface.get();
diff --git a/src/gpu/gl/mac/SkNativeGLContext_mac.cpp b/src/gpu/gl/mac/SkNativeGLContext_mac.cpp
index 460fad7e26..b821f3dc11 100644
--- a/src/gpu/gl/mac/SkNativeGLContext_mac.cpp
+++ b/src/gpu/gl/mac/SkNativeGLContext_mac.cpp
@@ -36,7 +36,7 @@ const GrGLInterface* SkNativeGLContext::createGLContext() {
CGLPixelFormatAttribute attributes[] = {
#if 0
- kCGLPFAOpenGLProfile, kCGLOGLPVersion_3_2_Core,
+ kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core,
#endif
(CGLPixelFormatAttribute)0
};
diff --git a/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp b/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp
index 1b4b7f6a37..74f6a51d9e 100644
--- a/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp
+++ b/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp
@@ -6,7 +6,7 @@
* found in the LICENSE file.
*/
-
+#include "gl/GrGLExtensions.h"
#include "gl/GrGLInterface.h"
#include "../GrGLUtil.h"
@@ -23,9 +23,20 @@
const GrGLInterface* GrGLCreateMesaInterface() {
if (NULL != OSMesaGetCurrentContext()) {
- GrGLGetStringProc getString = (GrGLGetStringProc) OSMesaGetProcAddress("glGetString");
+
+ GrGLGetStringProc getString =
+ (GrGLGetStringProc) OSMesaGetProcAddress("glGetString");
+ GrGLGetStringiProc glGetStringi =
+ (GrGLGetStringiProc) OSMesaGetProcAddress("glGetStringi");
+ GrGLGetIntegervProc glGetIntegerv =
+ (GrGLGetIntegervProc) OSMesaGetProcAddress("glGetIntegerv");
+
+ GrGLExtensions extensions;
+ if (!extensions.init(kDesktop_GrGLBinding, glGetString, glGetStringi, glGetIntegerv)) {
+ return NULL;
+ }
+
const char* versionString = (const char*) getString(GL_VERSION);
- const char* extString = (const char*) getString(GL_EXTENSIONS);
GrGLVersion glVer = GrGLGetVersionFromString(versionString);
if (glVer < GR_GL_VER(1,5)) {
@@ -44,8 +55,8 @@ const GrGLInterface* GrGLCreateMesaInterface() {
GR_GL_GET_PROC(BlendFunc);
if (glVer >= GR_GL_VER(1,4) ||
- GrGLHasExtensionFromString("GL_ARB_imaging", extString) ||
- GrGLHasExtensionFromString("GL_EXT_blend_color", extString)) {
+ extensions.has("GL_ARB_imaging") ||
+ extensions.has("GL_EXT_blend_color")) {
GR_GL_GET_PROC(BlendColor);
}
@@ -85,12 +96,11 @@ const GrGLInterface* GrGLCreateMesaInterface() {
GR_GL_GET_PROC(GetIntegerv);
GR_GL_GET_PROC(GetProgramInfoLog);
GR_GL_GET_PROC(GetProgramiv);
- if (glVer >= GR_GL_VER(3,3) ||
- GrGLHasExtensionFromString("GL_ARB_timer_query", extString)) {
+ if (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) {
GR_GL_GET_PROC(GetQueryObjecti64v);
GR_GL_GET_PROC(GetQueryObjectui64v)
GR_GL_GET_PROC(QueryCounter);
- } else if (GrGLHasExtensionFromString("GL_EXT_timer_query", extString)) {
+ } else if (extensions.has("GL_EXT_timer_query")) {
GR_GL_GET_PROC_SUFFIX(GetQueryObjecti64v, EXT);
GR_GL_GET_PROC_SUFFIX(GetQueryObjectui64v, EXT);
}
@@ -100,6 +110,7 @@ const GrGLInterface* GrGLCreateMesaInterface() {
GR_GL_GET_PROC(GetShaderInfoLog);
GR_GL_GET_PROC(GetShaderiv);
GR_GL_GET_PROC(GetString);
+ GR_GL_GET_PROC(GetStringi);
GR_GL_GET_PROC(GetTexLevelParameteriv);
GR_GL_GET_PROC(GenTextures);
GR_GL_GET_PROC(GetUniformLocation);
@@ -152,9 +163,7 @@ const GrGLInterface* GrGLCreateMesaInterface() {
// First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since
// GL_ARB_framebuffer_object doesn't use ARB suffix.)
- if (glVer >= GR_GL_VER(3,0) ||
- GrGLHasExtensionFromString("GL_ARB_framebuffer_object",
- extString)) {
+ if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) {
GR_GL_GET_PROC(GenFramebuffers);
GR_GL_GET_PROC(GetFramebufferAttachmentParameteriv);
GR_GL_GET_PROC(GetRenderbufferParameteriv);
@@ -169,8 +178,7 @@ const GrGLInterface* GrGLCreateMesaInterface() {
GR_GL_GET_PROC(BindRenderbuffer);
GR_GL_GET_PROC(RenderbufferStorageMultisample);
GR_GL_GET_PROC(BlitFramebuffer);
- } else if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object",
- extString)) {
+ } else if (extensions.has("GL_EXT_framebuffer_object")) {
GR_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT);
GR_GL_GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT);
GR_GL_GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT);
@@ -183,12 +191,10 @@ const GrGLInterface* GrGLCreateMesaInterface() {
GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT);
- if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample",
- extString)) {
+ if (extensions.has("GL_EXT_framebuffer_multisample")) {
GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
}
- if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit",
- extString)) {
+ if (extensions.has("GL_EXT_framebuffer_blit")) {
GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT);
}
} else {
diff --git a/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp b/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp
index 04d35d1836..2965e7f19a 100644
--- a/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp
+++ b/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp
@@ -7,6 +7,7 @@
*/
+#include "gl/GrGLExtensions.h"
#include "gl/GrGLInterface.h"
#include "../GrGLUtil.h"
@@ -22,10 +23,19 @@
const GrGLInterface* GrGLCreateNativeInterface() {
if (NULL != glXGetCurrentContext()) {
+
const char* versionString = (const char*) glGetString(GL_VERSION);
- const char* extString = (const char*) glGetString(GL_EXTENSIONS);
GrGLVersion glVer = GrGLGetVersionFromString(versionString);
+ // This may or may not succeed depending on the gl version.
+ GrGLGetStringiProc glGetStringi =
+ (GrGLGetStringiProc) glXGetProcAddress(reinterpret_cast<const GLubyte*>("glGetStringi"));
+
+ GrGLExtensions extensions;
+ if (!extensions.init(kDesktop_GrGLBinding, glGetString, glGetStringi, glGetIntegerv)) {
+ return NULL;
+ }
+
if (glVer < GR_GL_VER(1,5)) {
// We must have array and element_array buffer objects.
return NULL;
@@ -43,8 +53,8 @@ const GrGLInterface* GrGLCreateNativeInterface() {
interface->fBlendFunc = glBlendFunc;
if (glVer >= GR_GL_VER(1,4) ||
- GrGLHasExtensionFromString("GL_ARB_imaging", extString) ||
- GrGLHasExtensionFromString("GL_EXT_blend_color", extString)) {
+ extensions.has("GL_ARB_imaging") ||
+ extensions.has("GL_EXT_blend_color")) {
GR_GL_GET_PROC(BlendColor);
}
@@ -83,12 +93,11 @@ const GrGLInterface* GrGLCreateNativeInterface() {
interface->fGetIntegerv = glGetIntegerv;
GR_GL_GET_PROC(GetQueryObjectiv);
GR_GL_GET_PROC(GetQueryObjectuiv);
- if (glVer >= GR_GL_VER(3,3) ||
- GrGLHasExtensionFromString("GL_ARB_timer_query", extString)) {
+ if (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) {
GR_GL_GET_PROC(GetQueryObjecti64v);
GR_GL_GET_PROC(GetQueryObjectui64v);
GR_GL_GET_PROC(QueryCounter);
- } else if (GrGLHasExtensionFromString("GL_EXT_timer_query", extString)) {
+ } else if (extensions.has("GL_EXT_timer_query")) {
GR_GL_GET_PROC_SUFFIX(GetQueryObjecti64v, EXT);
GR_GL_GET_PROC_SUFFIX(GetQueryObjectui64v, EXT);
}
@@ -98,6 +107,7 @@ const GrGLInterface* GrGLCreateNativeInterface() {
GR_GL_GET_PROC(GetShaderInfoLog);
GR_GL_GET_PROC(GetShaderiv);
interface->fGetString = glGetString;
+ GR_GL_GET_PROC(GetStringi);
interface->fGetTexLevelParameteriv = glGetTexLevelParameteriv;
GR_GL_GET_PROC(GenQueries);
interface->fGenTextures = glGenTextures;
@@ -108,8 +118,7 @@ const GrGLInterface* GrGLCreateNativeInterface() {
interface->fPixelStorei = glPixelStorei;
interface->fReadBuffer = glReadBuffer;
interface->fReadPixels = glReadPixels;
- if (GrGLHasExtensionFromString("GL_NV_framebuffer_multisample_coverage",
- extString)) {
+ if (extensions.has("GL_NV_framebuffer_multisample_coverage")) {
GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisampleCoverage, NV);
}
interface->fScissor = glScissor;
@@ -123,10 +132,9 @@ const GrGLInterface* GrGLCreateNativeInterface() {
interface->fTexImage2D = glTexImage2D;
interface->fTexParameteri = glTexParameteri;
interface->fTexParameteriv = glTexParameteriv;
- if (glVer >= GR_GL_VER(4,2) ||
- GrGLHasExtensionFromString("GL_ARB_texture_storage", extString)) {
+ if (glVer >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage")) {
GR_GL_GET_PROC(TexStorage2D);
- } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", extString)) {
+ } else if (extensions.has("GL_EXT_texture_storage")) {
GR_GL_GET_PROC_SUFFIX(TexStorage2D, EXT);
}
interface->fTexSubImage2D = glTexSubImage2D;
@@ -158,9 +166,7 @@ const GrGLInterface* GrGLCreateNativeInterface() {
// First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since
// GL_ARB_framebuffer_object doesn't use ARB suffix.)
- if (glVer >= GR_GL_VER(3,0) ||
- GrGLHasExtensionFromString("GL_ARB_framebuffer_object",
- extString)) {
+ if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) {
GR_GL_GET_PROC(GenFramebuffers);
GR_GL_GET_PROC(GetFramebufferAttachmentParameteriv);
GR_GL_GET_PROC(GetRenderbufferParameteriv);
@@ -175,8 +181,7 @@ const GrGLInterface* GrGLCreateNativeInterface() {
GR_GL_GET_PROC(BindRenderbuffer);
GR_GL_GET_PROC(RenderbufferStorageMultisample);
GR_GL_GET_PROC(BlitFramebuffer);
- } else if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object",
- extString)) {
+ } else if (extensions.has("GL_EXT_framebuffer_object")) {
GR_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT);
GR_GL_GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT);
GR_GL_GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT);
@@ -189,12 +194,10 @@ const GrGLInterface* GrGLCreateNativeInterface() {
GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT);
- if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample",
- extString)) {
+ if (extensions.has("GL_EXT_framebuffer_multisample")) {
GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
}
- if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit",
- extString)) {
+ if (extensions.has("GL_EXT_framebuffer_blit")) {
GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT);
}
} else {
diff --git a/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp b/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp
index 64f073a75f..e08d8d4faf 100644
--- a/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp
+++ b/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp
@@ -7,8 +7,9 @@
*/
+#include "gl/GrGLExtensions.h"
#include "gl/GrGLInterface.h"
-#include "../GrGLUtil.h"
+#include "gl/GrGLUtil.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
@@ -48,12 +49,26 @@ const GrGLInterface* GrGLCreateNativeInterface() {
if (NULL == alu.get()) {
return NULL;
}
- GrGLGetStringProc glGetString =
- (GrGLGetStringProc) GetProcAddress(alu.get(), "glGetString");
if (NULL != wglGetCurrentContext()) {
+
+ // These should always be present and don't require wglGetProcAddress
+ GrGLGetStringProc glGetString =
+ (GrGLGetStringProc) GetProcAddress(alu.get(), "glGetString");
+ GrGLGetIntegervProc glGetIntegerv =
+ (GrGLGetIntegervProc) GetProcAddress(alu.get(), "glGetIntegerv");
+ if (NULL == glGetString || NULL == glGetIntegerv) {
+ return NULL;
+ }
+
+ // This may or may not succeed depending on the gl version.
+ GrGLGetStringiProc glGetStringi = (GrGLGetStringiProc) wglGetProcAddress("glGetStringi");
+
+ GrGLExtensions extensions;
+ if (!extensions.init(kDesktop_GrGLBinding, glGetString, glGetStringi, glGetIntegerv)) {
+ return NULL;
+ }
const char* versionString = (const char*) glGetString(GR_GL_VERSION);
- const char* extString = (const char*) glGetString(GR_GL_EXTENSIONS);
GrGLVersion glVer = GrGLGetVersionFromString(versionString);
if (glVer < GR_GL_VER(1,5)) {
@@ -68,8 +83,8 @@ const GrGLInterface* GrGLCreateNativeInterface() {
SET_PROC(BlendFunc)
if (glVer >= GR_GL_VER(1,4) ||
- GrGLHasExtensionFromString("GL_ARB_imaging", extString) ||
- GrGLHasExtensionFromString("GL_EXT_blend_color", extString)) {
+ extensions.has("GL_ARB_imaging") ||
+ extensions.has("GL_EXT_blend_color")) {
WGL_SET_PROC(BlendColor);
}
@@ -107,10 +122,9 @@ const GrGLInterface* GrGLCreateNativeInterface() {
SET_PROC(TexImage2D)
SET_PROC(TexParameteri)
SET_PROC(TexParameteriv)
- if (glVer >= GR_GL_VER(4,2) ||
- GrGLHasExtensionFromString("GL_ARB_texture_storage", extString)) {
+ if (glVer >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage")) {
WGL_SET_PROC(TexStorage2D);
- } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", extString)) {
+ } else if (extensions.has("GL_EXT_texture_storage")) {
WGL_SET_PROC_SUFFIX(TexStorage2D, EXT);
}
SET_PROC(TexSubImage2D)
@@ -142,12 +156,11 @@ const GrGLInterface* GrGLCreateNativeInterface() {
WGL_SET_PROC(GetQueryiv);
WGL_SET_PROC(GetQueryObjectiv);
WGL_SET_PROC(GetQueryObjectuiv);
- if (glVer > GR_GL_VER(3,3) ||
- GrGLHasExtensionFromString("GL_ARB_timer_query", extString)) {
+ if (glVer > GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) {
WGL_SET_PROC(GetQueryObjecti64v);
WGL_SET_PROC(GetQueryObjectui64v);
WGL_SET_PROC(QueryCounter);
- } else if (GrGLHasExtensionFromString("GL_EXT_timer_query", extString)) {
+ } else if (extensions.has("GL_EXT_timer_query")) {
WGL_SET_PROC_SUFFIX(GetQueryObjecti64v, EXT);
WGL_SET_PROC_SUFFIX(GetQueryObjectui64v, EXT);
}
@@ -155,9 +168,10 @@ const GrGLInterface* GrGLCreateNativeInterface() {
WGL_SET_PROC(GetProgramiv);
WGL_SET_PROC(GetShaderInfoLog);
WGL_SET_PROC(GetShaderiv);
+ WGL_SET_PROC(GetStringi)
WGL_SET_PROC(GetUniformLocation);
WGL_SET_PROC(LinkProgram);
- if (GrGLHasExtensionFromString("GL_NV_framebuffer_multisample_coverage", extString)) {
+ if (extensions.has("GL_NV_framebuffer_multisample_coverage")) {
WGL_SET_PROC_SUFFIX(RenderbufferStorageMultisampleCoverage, NV);
}
WGL_SET_PROC(ShaderSource);
@@ -190,8 +204,7 @@ const GrGLInterface* GrGLCreateNativeInterface() {
// First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since
// GL_ARB_framebuffer_object doesn't use ARB suffix.)
- if (glVer > GR_GL_VER(3,0) ||
- GrGLHasExtensionFromString("GL_ARB_framebuffer_object", extString)) {
+ if (glVer > GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) {
WGL_SET_PROC(GenFramebuffers);
WGL_SET_PROC(GetFramebufferAttachmentParameteriv);
WGL_SET_PROC(GetRenderbufferParameteriv);
@@ -206,8 +219,7 @@ const GrGLInterface* GrGLCreateNativeInterface() {
WGL_SET_PROC(BindRenderbuffer);
WGL_SET_PROC(RenderbufferStorageMultisample);
WGL_SET_PROC(BlitFramebuffer);
- } else if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object",
- extString)) {
+ } else if (extensions.has("GL_EXT_framebuffer_object")) {
WGL_SET_PROC_SUFFIX(GenFramebuffers, EXT);
WGL_SET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT);
WGL_SET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT);
@@ -220,10 +232,10 @@ const GrGLInterface* GrGLCreateNativeInterface() {
WGL_SET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
WGL_SET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
WGL_SET_PROC_SUFFIX(BindRenderbuffer, EXT);
- if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", extString)) {
+ if (extensions.has("GL_EXT_framebuffer_multisample")) {
WGL_SET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
}
- if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", extString)) {
+ if (extensions.has("GL_EXT_framebuffer_blit")) {
WGL_SET_PROC_SUFFIX(BlitFramebuffer, EXT);
}
} else {
@@ -234,7 +246,7 @@ const GrGLInterface* GrGLCreateNativeInterface() {
WGL_SET_PROC(MapBuffer);
WGL_SET_PROC(UnmapBuffer);
- if (GrGLHasExtensionFromString("GL_NV_path_rendering", extString)) {
+ if (extensions.has("GL_NV_path_rendering")) {
WGL_SET_PROC_SUFFIX(PathCommands, NV);
WGL_SET_PROC_SUFFIX(PathCoords, NV);
WGL_SET_PROC_SUFFIX(PathSubCommands, NV);