diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-03-16 11:23:51 (GMT) |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-03-16 12:35:15 (GMT) |
commit | c066afa4bc95ac92185e9fc691b9d9d27ca64387 (patch) | |
tree | 73ad6740f2033039da92b39e596f5159ab948da3 /src/opengl | |
parent | e0dd5b450e1b04feb6c72a3c635c586b244392da (diff) | |
download | Qt-c066afa4bc95ac92185e9fc691b9d9d27ca64387.zip Qt-c066afa4bc95ac92185e9fc691b9d9d27ca64387.tar.gz Qt-c066afa4bc95ac92185e9fc691b9d9d27ca64387.tar.bz2 |
Implement a special case, simplified vertex shader for complex geometry
When drawing text, the vertex count will most likely be so high that
using a uniform-based, simpler vertex shader is faster. We implement
the ability to inform the shader manager that the geometry is considered
complex, so that it can choose the simpler vertex shader in these cases.
Task-number: QT-2887
Reviewed-by: tom
Diffstat (limited to 'src/opengl')
5 files changed, 39 insertions, 2 deletions
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 8183f08..aa704b1 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -96,6 +96,7 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) code[UntransformedPositionVertexShader] = qglslUntransformedPositionVertexShader; code[PositionOnlyVertexShader] = qglslPositionOnlyVertexShader; + code[ComplexGeometryPositionOnlyVertexShader] = qglslComplexGeometryPositionOnlyVertexShader; code[PositionWithPatternBrushVertexShader] = qglslPositionWithPatternBrushVertexShader; code[PositionWithLinearGradientBrushVertexShader] = qglslPositionWithLinearGradientBrushVertexShader; code[PositionWithConicalGradientBrushVertexShader] = qglslPositionWithConicalGradientBrushVertexShader; @@ -401,6 +402,7 @@ void QGLEngineSharedShaders::cleanupCustomStage(QGLCustomShaderStage* stage) QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) : ctx(context), shaderProgNeedsChanging(true), + complexGeometry(false), srcPixelType(Qt::NoBrush), opacityMode(NoOpacity), maskType(NoMask), @@ -442,7 +444,8 @@ GLuint QGLEngineShaderManager::getUniformLocation(Uniform id) "inverse_2_fmp2_m_radius2", "invertedTextureSize", "brushTransform", - "brushTexture" + "brushTexture", + "matrix" }; if (uniformLocations.at(id) == GLuint(-1)) @@ -751,6 +754,8 @@ bool QGLEngineShaderManager::useCorrectShaderProg() requiredProgram.useTextureCoords = texCoords; requiredProgram.useOpacityAttribute = (opacityMode == AttributeOpacity); requiredProgram.usePmvMatrix = true; + if (complexGeometry) + requiredProgram.positionVertexShader = QGLEngineSharedShaders::ComplexGeometryPositionOnlyVertexShader; // At this point, requiredProgram is fully populated so try to find the program in the cache currentShaderProg = sharedShaders->findProgramInCache(requiredProgram); diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index 3ab4ebe..d8be4c9 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -272,6 +272,7 @@ public: // UntransformedPositionVertexShader must be first in the list: UntransformedPositionVertexShader, PositionOnlyVertexShader, + ComplexGeometryPositionOnlyVertexShader, PositionWithPatternBrushVertexShader, PositionWithLinearGradientBrushVertexShader, PositionWithConicalGradientBrushVertexShader, @@ -446,6 +447,7 @@ public: InvertedTextureSize, BrushTransform, BrushTexture, + Matrix, NumUniforms }; @@ -474,6 +476,15 @@ public: void useSimpleProgram(); void useBlitProgram(); + void setHasComplexGeometry(bool hasComplexGeometry) + { + complexGeometry = hasComplexGeometry; + shaderProgNeedsChanging = true; + } + bool hasComplexGeometry() const + { + return complexGeometry; + } QGLShaderProgram* currentProgram(); // Returns pointer to the shader the manager has chosen QGLShaderProgram* simpleProgram(); // Used to draw into e.g. stencil buffers @@ -487,6 +498,7 @@ private slots: private: QGLContext* ctx; bool shaderProgNeedsChanging; + bool complexGeometry; // Current state variables which influence the choice of shader: QTransform brushTransform; diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index c88c041..3379296 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -107,6 +107,14 @@ static const char* const qglslPositionOnlyVertexShader = "\n\ gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \n\ }\n"; +static const char* const qglslComplexGeometryPositionOnlyVertexShader = "\n\ + uniform highp mat3 matrix; \n\ + attribute highp vec2 vertexCoordsArray; \n\ + void setPosition(void) \n\ + { \n\ + gl_Position = vec4(matrix * vec3(vertexCoordsArray, 1), 1);\n\ + } \n"; + static const char* const qglslUntransformedPositionVertexShader = "\n\ attribute highp vec4 vertexCoordsArray; \n\ void setPosition(void) \n\ diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index d68a268..b90f0c2 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -395,6 +395,7 @@ void QGL2PaintEngineExPrivate::updateMatrix() qreal(0.0001)); matrixDirty = false; + matrixUniformDirty = true; // Set the PMV matrix attribute. As we use an attributes rather than uniforms, we only // need to do this once for every matrix change and persists across all shader programs. @@ -594,6 +595,9 @@ void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) if (newMode == TextDrawingMode) { setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinateArray.data()); setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinateArray.data()); + shaderManager->setHasComplexGeometry(true); + } else { + shaderManager->setHasComplexGeometry(false); } if (newMode == ImageDrawingMode) { @@ -1045,6 +1049,7 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) // The shader program has changed so mark all uniforms as dirty: brushUniformsDirty = true; opacityUniformDirty = true; + matrixUniformDirty = true; } if (brushUniformsDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode) @@ -1055,6 +1060,12 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) opacityUniformDirty = false; } + if (matrixUniformDirty && shaderManager->hasComplexGeometry()) { + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Matrix), + pmvMatrix); + matrixUniformDirty = false; + } + return changed; } @@ -1631,7 +1642,6 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp lastMaskTextureUsed = cache->texture(); } updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::MaskTexture), QT_MASK_TEXTURE_UNIT); #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) @@ -1776,6 +1786,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) d->mode = BrushDrawingMode; d->brushTextureDirty = true; d->brushUniformsDirty = true; + d->matrixUniformDirty = true; d->matrixDirty = true; d->compositionModeDirty = true; d->opacityUniformDirty = true; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index ed8fbbc..34d72d1 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -259,6 +259,7 @@ public: bool brushTextureDirty; bool brushUniformsDirty; bool opacityUniformDirty; + bool matrixUniformDirty; bool stencilClean; // Has the stencil not been used for clipping so far? bool useSystemClip; |