blob: 633796ded8373417e82b975725a27fb152220f1b [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 }
29 bool indexed = false;
30 if (kDesktop_GrGLBinding == binding) {
31 const GrGLubyte* verString = getString(GR_GL_VERSION);
32 if (NULL == verString) {
33 return false;
34 }
35 GrGLVersion version = GrGLGetVersionFromString((const char*) verString);
36 indexed = version >= GR_GL_VER(3, 0);
37 }
38 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.coma1d27cd2013-03-08 19:01:01 +000069 if (0 != fStrings.count()) {
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.comff436612013-02-27 19:07:32 +000077 SkString extensionStr(ext);
78 int idx = SkTSearch<SkString, extension_compare>(&fStrings.front(),
79 fStrings.count(),
80 extensionStr,
81 sizeof(SkString));
82 return idx >= 0;
bsalomon@google.com1744f972013-02-26 21:46:32 +000083}
bsalomon@google.com00142c42013-05-02 19:42:54 +000084
85void GrGLExtensions::print(const char* sep) const {
86 if (NULL == sep) {
87 sep = " ";
88 }
89 int cnt = fStrings.count();
90 for (int i = 0; i < cnt; ++i) {
91 GrPrintf("%s%s", fStrings[i].c_str(), (i < cnt - 1) ? sep : "");
92 }
93}