blob: 5ebab14b65a24622093434a13a5935a86e483572 [file] [log] [blame]
bsalomon@google.com1744f972013-02-26 21:46:32 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "gl/GrGLExtensions.h"
9#include "gl/GrGLDefines.h"
10#include "gl/GrGLUtil.h"
11
bsalomon@google.comff436612013-02-27 19:07:32 +000012#include "SkTSearch.h"
13#include "SkTSort.h"
14
15namespace {
bsalomon@google.com20f7f172013-05-17 19:05:03 +000016inline bool extension_compare(const SkString& a, const SkString& b) {
17 return strcmp(a.c_str(), b.c_str()) < 0;
bsalomon@google.comff436612013-02-27 19:07:32 +000018}
19}
20
bsalomon@google.com1744f972013-02-26 21:46:32 +000021bool GrGLExtensions::init(GrGLBinding binding,
22 GrGLGetStringProc getString,
23 GrGLGetStringiProc getStringi,
24 GrGLGetIntegervProc getIntegerv) {
25 fStrings.reset();
26 if (NULL == getString) {
27 return false;
28 }
commit-bot@chromium.org726e6212013-08-23 20:55:46 +000029
30 // glGetStringi and indexed extensions were added in version 3.0 of desktop GL and ES.
31 const GrGLubyte* verString = getString(GR_GL_VERSION);
32 if (NULL == verString) {
33 return false;
bsalomon@google.com1744f972013-02-26 21:46:32 +000034 }
commit-bot@chromium.org726e6212013-08-23 20:55:46 +000035 GrGLVersion version = GrGLGetVersionFromString((const char*) verString);
36 bool indexed = version >= GR_GL_VER(3, 0);
37
bsalomon@google.com1744f972013-02-26 21:46:32 +000038 if (indexed) {
39 if (NULL == getStringi || NULL == getIntegerv) {
40 return false;
41 }
42 GrGLint extensionCnt = 0;
43 getIntegerv(GR_GL_NUM_EXTENSIONS, &extensionCnt);
44 fStrings.push_back_n(extensionCnt);
45 for (int i = 0; i < extensionCnt; ++i) {
46 const char* ext = (const char*) getStringi(GR_GL_EXTENSIONS, i);
47 fStrings[i] = ext;
48 }
49 } else {
50 const char* extensions = (const char*) getString(GR_GL_EXTENSIONS);
skia.committer@gmail.comeed625d2013-03-09 07:01:15 +000051 if (NULL == extensions) {
bsalomon@google.com1744f972013-02-26 21:46:32 +000052 return false;
53 }
bsalomon@google.com1744f972013-02-26 21:46:32 +000054 while (true) {
bsalomon@google.coma2240722013-03-08 16:06:28 +000055 // skip over multiple spaces between extensions
56 while (' ' == *extensions) {
57 ++extensions;
58 }
59 // quit once we reach the end of the string.
60 if ('\0' == *extensions) {
bsalomon@google.com1744f972013-02-26 21:46:32 +000061 break;
62 }
bsalomon@google.coma2240722013-03-08 16:06:28 +000063 // we found an extension
64 size_t length = strcspn(extensions, " ");
65 fStrings.push_back().set(extensions, length);
66 extensions += length;
bsalomon@google.com1744f972013-02-26 21:46:32 +000067 }
bsalomon@google.com1744f972013-02-26 21:46:32 +000068 }
bsalomon@google.com42db2e42013-06-11 19:22:44 +000069 if (!fStrings.empty()) {
bsalomon@google.com20f7f172013-05-17 19:05:03 +000070 SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
bsalomon@google.coma1d27cd2013-03-08 19:01:01 +000071 SkTQSort(&fStrings.front(), &fStrings.back(), cmp);
72 }
bsalomon@google.com1744f972013-02-26 21:46:32 +000073 return true;
74}
75
76bool GrGLExtensions::has(const char* ext) const {
bsalomon@google.com42db2e42013-06-11 19:22:44 +000077 if (fStrings.empty()) {
78 return false;
79 }
bsalomon@google.comff436612013-02-27 19:07:32 +000080 SkString extensionStr(ext);
81 int idx = SkTSearch<SkString, extension_compare>(&fStrings.front(),
82 fStrings.count(),
83 extensionStr,
84 sizeof(SkString));
85 return idx >= 0;
bsalomon@google.com1744f972013-02-26 21:46:32 +000086}
bsalomon@google.com00142c42013-05-02 19:42:54 +000087
88void GrGLExtensions::print(const char* sep) const {
89 if (NULL == sep) {
90 sep = " ";
91 }
92 int cnt = fStrings.count();
93 for (int i = 0; i < cnt; ++i) {
94 GrPrintf("%s%s", fStrings[i].c_str(), (i < cnt - 1) ? sep : "");
95 }
96}