GrGLExtensions.cpp revision eed625df23ee83a94f1814c43744b1961b79adf1
11744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com/*
21744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com * Copyright 2013 Google Inc.
31744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com *
41744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com * Use of this source code is governed by a BSD-style license that can be
51744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com * found in the LICENSE file.
61744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com */
71744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com
81744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com#include "gl/GrGLExtensions.h"
91744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com#include "gl/GrGLDefines.h"
101744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com#include "gl/GrGLUtil.h"
111744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com
12ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com#include "SkTSearch.h"
13ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com#include "SkTSort.h"
14ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com
15ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.comnamespace {
16ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.cominline int extension_compare(const SkString* a, const SkString* b) {
17ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com    return strcmp(a->c_str(), b->c_str());
18ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com}
19ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com}
20ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com
211744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.combool GrGLExtensions::init(GrGLBinding binding,
221744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com                          GrGLGetStringProc getString,
231744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com                          GrGLGetStringiProc getStringi,
241744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com                          GrGLGetIntegervProc getIntegerv) {
251744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com    fStrings.reset();
261744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com    if (NULL == getString) {
271744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        return false;
281744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com    }
291744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com    bool indexed = false;
301744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com    if (kDesktop_GrGLBinding == binding) {
311744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        const GrGLubyte* verString = getString(GR_GL_VERSION);
321744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        if (NULL == verString) {
331744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com            return false;
341744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        }
351744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        GrGLVersion version = GrGLGetVersionFromString((const char*) verString);
361744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        indexed = version >= GR_GL_VER(3, 0);
371744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com    }
381744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com    if (indexed) {
391744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        if (NULL == getStringi || NULL == getIntegerv) {
401744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com            return false;
411744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        }
421744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        GrGLint extensionCnt = 0;
431744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        getIntegerv(GR_GL_NUM_EXTENSIONS, &extensionCnt);
441744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        fStrings.push_back_n(extensionCnt);
451744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        for (int i = 0; i < extensionCnt; ++i) {
461744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com            const char* ext = (const char*) getStringi(GR_GL_EXTENSIONS, i);
471744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com            fStrings[i] = ext;
481744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        }
491744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com    } else {
501744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        const char* extensions = (const char*) getString(GR_GL_EXTENSIONS);
51eed625df23ee83a94f1814c43744b1961b79adf1skia.committer@gmail.com        if (NULL == extensions) {
521744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com            return false;
531744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        }
541744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        while (true) {
55a22407283650ae570d8f93db0f4f6df266812716bsalomon@google.com            // skip over multiple spaces between extensions
56a22407283650ae570d8f93db0f4f6df266812716bsalomon@google.com            while (' ' == *extensions) {
57a22407283650ae570d8f93db0f4f6df266812716bsalomon@google.com                ++extensions;
58a22407283650ae570d8f93db0f4f6df266812716bsalomon@google.com            }
59a22407283650ae570d8f93db0f4f6df266812716bsalomon@google.com            // quit once we reach the end of the string.
60a22407283650ae570d8f93db0f4f6df266812716bsalomon@google.com            if ('\0' == *extensions) {
611744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com                break;
621744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com            }
63a22407283650ae570d8f93db0f4f6df266812716bsalomon@google.com            // we found an extension
64a22407283650ae570d8f93db0f4f6df266812716bsalomon@google.com            size_t length = strcspn(extensions, " ");
65a22407283650ae570d8f93db0f4f6df266812716bsalomon@google.com            fStrings.push_back().set(extensions, length);
66a22407283650ae570d8f93db0f4f6df266812716bsalomon@google.com            extensions += length;
671744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        }
681744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com    }
69a1d27cd07af36436a3c9c4495055fea5bbd219afbsalomon@google.com    if (0 != fStrings.count()) {
70a1d27cd07af36436a3c9c4495055fea5bbd219afbsalomon@google.com        SkTSearchCompareLTFunctor<SkString, extension_compare> cmp;
71a1d27cd07af36436a3c9c4495055fea5bbd219afbsalomon@google.com        SkTQSort(&fStrings.front(), &fStrings.back(), cmp);
72a1d27cd07af36436a3c9c4495055fea5bbd219afbsalomon@google.com    }
731744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com    return true;
741744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com}
751744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com
761744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.combool GrGLExtensions::has(const char* ext) const {
77ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com    SkString extensionStr(ext);
78ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com    int idx = SkTSearch<SkString, extension_compare>(&fStrings.front(),
79ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com                                                     fStrings.count(),
80ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com                                                     extensionStr,
81ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com                                                     sizeof(SkString));
82ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com    return idx >= 0;
831744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com}
84