Home | History | Annotate | Download | only in gl
      1 /*
      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 
     12 #include "SkTSearch.h"
     13 #include "SkTSort.h"
     14 
     15 namespace {
     16 inline bool extension_compare(const SkString& a, const SkString& b) {
     17     return strcmp(a.c_str(), b.c_str()) < 0;
     18 }
     19 }
     20 
     21 bool 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 
     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;
     34     }
     35     GrGLVersion version = GrGLGetVersionFromString((const char*) verString);
     36     bool 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);
     51         if (NULL == extensions) {
     52             return false;
     53         }
     54         while (true) {
     55             // 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) {
     61                 break;
     62             }
     63             // we found an extension
     64             size_t length = strcspn(extensions, " ");
     65             fStrings.push_back().set(extensions, length);
     66             extensions += length;
     67         }
     68     }
     69     if (!fStrings.empty()) {
     70         SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
     71         SkTQSort(&fStrings.front(), &fStrings.back(), cmp);
     72     }
     73     return true;
     74 }
     75 
     76 bool GrGLExtensions::has(const char* ext) const {
     77     if (fStrings.empty()) {
     78         return false;
     79     }
     80     SkString extensionStr(ext);
     81     int idx = SkTSearch<SkString, extension_compare>(&fStrings.front(),
     82                                                      fStrings.count(),
     83                                                      extensionStr,
     84                                                      sizeof(SkString));
     85     return idx >= 0;
     86 }
     87 
     88 void 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 }
     97