Improve the QOpenGLExtensionMatcher class

Using a QSet<QByteArray> internally means that checking for the
presence of an extension no longer uses an O(N) search.

This patch also allows users of this class to easily get a list
of the supported extensions.

Change-Id: I02194e5345573c47be0876f3ea6eb6b69a2ead81
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
This commit is contained in:
Sean Harmer 2012-07-20 16:21:47 +01:00 committed by Qt by Nokia
parent e81d7fd1e5
commit 46212d657e
2 changed files with 11 additions and 50 deletions

View File

@ -46,11 +46,6 @@
QT_BEGIN_NAMESPACE
QOpenGLExtensionMatcher::QOpenGLExtensionMatcher(const char *str)
{
init(str);
}
typedef const GLubyte * (QOPENGLF_APIENTRYP qt_glGetStringi)(GLenum, GLuint);
#ifndef GL_NUM_EXTENSIONS
@ -62,7 +57,9 @@ QOpenGLExtensionMatcher::QOpenGLExtensionMatcher()
const char *extensionStr = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
if (extensionStr) {
init(extensionStr);
QByteArray ba(extensionStr);
QList<QByteArray> extensions = ba.split(' ');
m_extensions = extensions.toSet();
} else {
// clear error state
while (glGetError()) {}
@ -79,32 +76,10 @@ QOpenGLExtensionMatcher::QOpenGLExtensionMatcher()
for (int i = 0; i < numExtensions; ++i) {
const char *str = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i));
m_offsets << m_extensions.size();
while (*str != 0)
m_extensions.append(*str++);
m_extensions.append(' ');
m_extensions.insert(str);
}
}
}
}
void QOpenGLExtensionMatcher::init(const char *str)
{
m_extensions = str;
// make sure extension string ends with a space
if (!m_extensions.endsWith(' '))
m_extensions.append(' ');
int index = 0;
int next = 0;
while ((next = m_extensions.indexOf(' ', index)) >= 0) {
m_offsets << index;
index = next + 1;
}
}
QT_END_NAMESPACE

View File

@ -44,9 +44,7 @@
#include <qopengl.h>
#include <private/qopenglcontext_p.h>
#include <qthreadstorage.h>
#include <qcache.h>
#include <QtCore/qset.h>
QT_BEGIN_HEADER
@ -55,29 +53,17 @@ QT_BEGIN_NAMESPACE
class QOpenGLExtensionMatcher
{
public:
QOpenGLExtensionMatcher(const char *str);
QOpenGLExtensionMatcher();
bool match(const char *str) const {
int str_length = qstrlen(str);
Q_ASSERT(str);
Q_ASSERT(str_length > 0);
Q_ASSERT(str[str_length-1] != ' ');
for (int i = 0; i < m_offsets.size(); ++i) {
const char *extension = m_extensions.constData() + m_offsets.at(i);
if (qstrncmp(extension, str, str_length) == 0 && extension[str_length] == ' ')
return true;
}
return false;
bool match(const QByteArray &extension) const
{
return m_extensions.contains(extension);
}
private:
void init(const char *str);
QSet<QByteArray> extensions() const { return m_extensions; }
QByteArray m_extensions;
QVector<int> m_offsets;
private:
QSet<QByteArray> m_extensions;
};
QT_END_NAMESPACE