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 +}