gfx/skia/trunk/src/gpu/gl/GrGLExtensions.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/gpu/gl/GrGLExtensions.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,142 @@
     1.4 +/*
     1.5 + * Copyright 2013 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +#include "gl/GrGLExtensions.h"
    1.12 +#include "gl/GrGLDefines.h"
    1.13 +#include "gl/GrGLUtil.h"
    1.14 +
    1.15 +#include "SkTSearch.h"
    1.16 +#include "SkTSort.h"
    1.17 +
    1.18 +namespace { // This cannot be static because it is used as a template parameter.
    1.19 +inline bool extension_compare(const SkString& a, const SkString& b) {
    1.20 +    return strcmp(a.c_str(), b.c_str()) < 0;
    1.21 +}
    1.22 +}
    1.23 +
    1.24 +// finds the index of ext in strings or a negative result if ext is not found.
    1.25 +static int find_string(const SkTArray<SkString>& strings, const char ext[]) {
    1.26 +    if (strings.empty()) {
    1.27 +        return -1;
    1.28 +    }
    1.29 +    SkString extensionStr(ext);
    1.30 +    int idx = SkTSearch<SkString, extension_compare>(&strings.front(),
    1.31 +                                                     strings.count(),
    1.32 +                                                     extensionStr,
    1.33 +                                                     sizeof(SkString));
    1.34 +    return idx;
    1.35 +}
    1.36 +
    1.37 +GrGLExtensions::GrGLExtensions(const GrGLExtensions& that) : fStrings(SkNEW(SkTArray<SkString>)) {
    1.38 +    *this = that;
    1.39 +}
    1.40 +
    1.41 +GrGLExtensions& GrGLExtensions::operator=(const GrGLExtensions& that) {
    1.42 +    *fStrings = *that.fStrings;
    1.43 +    fInitialized = that.fInitialized;
    1.44 +    return *this;
    1.45 +}
    1.46 +
    1.47 +bool GrGLExtensions::init(GrGLStandard standard,
    1.48 +                          GrGLGetStringProc getString,
    1.49 +                          GrGLGetStringiProc getStringi,
    1.50 +                          GrGLGetIntegervProc getIntegerv) {
    1.51 +    fInitialized = false;
    1.52 +    fStrings->reset();
    1.53 +
    1.54 +    if (NULL == getString) {
    1.55 +        return false;
    1.56 +    }
    1.57 +
    1.58 +    // glGetStringi and indexed extensions were added in version 3.0 of desktop GL and ES.
    1.59 +    const GrGLubyte* verString = getString(GR_GL_VERSION);
    1.60 +    if (NULL == verString) {
    1.61 +        return false;
    1.62 +    }
    1.63 +    GrGLVersion version = GrGLGetVersionFromString((const char*) verString);
    1.64 +    bool indexed = version >= GR_GL_VER(3, 0);
    1.65 +
    1.66 +    if (indexed) {
    1.67 +        if (NULL == getStringi || NULL == getIntegerv) {
    1.68 +            return false;
    1.69 +        }
    1.70 +        GrGLint extensionCnt = 0;
    1.71 +        getIntegerv(GR_GL_NUM_EXTENSIONS, &extensionCnt);
    1.72 +        fStrings->push_back_n(extensionCnt);
    1.73 +        for (int i = 0; i < extensionCnt; ++i) {
    1.74 +            const char* ext = (const char*) getStringi(GR_GL_EXTENSIONS, i);
    1.75 +            (*fStrings)[i] = ext;
    1.76 +        }
    1.77 +    } else {
    1.78 +        const char* extensions = (const char*) getString(GR_GL_EXTENSIONS);
    1.79 +        if (NULL == extensions) {
    1.80 +            return false;
    1.81 +        }
    1.82 +        while (true) {
    1.83 +            // skip over multiple spaces between extensions
    1.84 +            while (' ' == *extensions) {
    1.85 +                ++extensions;
    1.86 +            }
    1.87 +            // quit once we reach the end of the string.
    1.88 +            if ('\0' == *extensions) {
    1.89 +                break;
    1.90 +            }
    1.91 +            // we found an extension
    1.92 +            size_t length = strcspn(extensions, " ");
    1.93 +            fStrings->push_back().set(extensions, length);
    1.94 +            extensions += length;
    1.95 +        }
    1.96 +    }
    1.97 +    if (!fStrings->empty()) {
    1.98 +        SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
    1.99 +        SkTQSort(&fStrings->front(), &fStrings->back(), cmp);
   1.100 +    }
   1.101 +    fInitialized = true;
   1.102 +    return true;
   1.103 +}
   1.104 +
   1.105 +bool GrGLExtensions::has(const char ext[]) const {
   1.106 +    SkASSERT(fInitialized);
   1.107 +    return find_string(*fStrings, ext) >= 0;
   1.108 +}
   1.109 +
   1.110 +bool GrGLExtensions::remove(const char ext[]) {
   1.111 +    SkASSERT(fInitialized);
   1.112 +    int idx = find_string(*fStrings, ext);
   1.113 +    if (idx >= 0) {
   1.114 +        // This is not terribly effecient but we really only expect this function to be called at
   1.115 +        // most a handful of times when our test programs start.
   1.116 +        SkAutoTDelete< SkTArray<SkString> > oldStrings(fStrings.detach());
   1.117 +        fStrings.reset(SkNEW(SkTArray<SkString>(oldStrings->count() - 1)));
   1.118 +        fStrings->push_back_n(idx, &oldStrings->front());
   1.119 +        fStrings->push_back_n(oldStrings->count() - idx - 1, &(*oldStrings)[idx] + 1);
   1.120 +        return true;
   1.121 +    } else {
   1.122 +        return false;
   1.123 +    }
   1.124 +}
   1.125 +
   1.126 +void GrGLExtensions::add(const char ext[]) {
   1.127 +    int idx = find_string(*fStrings, ext);
   1.128 +    if (idx < 0) {
   1.129 +        // This is not the most effecient approach since we end up doing a full sort of the
   1.130 +        // extensions after the add
   1.131 +        fStrings->push_back().set(ext);
   1.132 +        SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;
   1.133 +        SkTQSort(&fStrings->front(), &fStrings->back(), cmp);
   1.134 +    }
   1.135 +}
   1.136 +
   1.137 +void GrGLExtensions::print(const char* sep) const {
   1.138 +    if (NULL == sep) {
   1.139 +        sep = " ";
   1.140 +    }
   1.141 +    int cnt = fStrings->count();
   1.142 +    for (int i = 0; i < cnt; ++i) {
   1.143 +        GrPrintf("%s%s", (*fStrings)[i].c_str(), (i < cnt - 1) ? sep : "");
   1.144 +    }
   1.145 +}

mercurial