summaryrefslogtreecommitdiffstats
path: root/src/opengl/gl2paintengineex
diff options
context:
space:
mode:
authorSamuel Rødal <sroedal@trolltech.com>2009-06-24 08:43:30 (GMT)
committerSamuel Rødal <sroedal@trolltech.com>2009-06-24 10:33:01 (GMT)
commitbd08e5dc4bd4c14511838717daa5dc1b7c748746 (patch)
treee8427a58091f5e842cbd40d465f4738f76670d4f /src/opengl/gl2paintengineex
parent2d0bcd161299db2b01fd9a6427058af1c0d3b407 (diff)
downloadQt-bd08e5dc4bd4c14511838717daa5dc1b7c748746.zip
Qt-bd08e5dc4bd4c14511838717daa5dc1b7c748746.tar.gz
Qt-bd08e5dc4bd4c14511838717daa5dc1b7c748746.tar.bz2
Reduced number of state changes/uniform location queries in GL2 engine.
Keep track of uniform locations for the current shader program in the shader manager. Also don't change texture parameters unless necessary. Reviewed-by: Kim
Diffstat (limited to 'src/opengl/gl2paintengineex')
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp55
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h13
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp115
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h34
4 files changed, 168 insertions, 49 deletions
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index ac89599..4b73ca9 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -191,7 +191,29 @@ QGLEngineShaderManager::~QGLEngineShaderManager()
}
+uint QGLEngineShaderManager::getUniformIdentifier(const char *uniformName)
+{
+ uniformIdentifiers << uniformName;
+ return uniformIdentifiers.size() - 1;
+}
+
+uint QGLEngineShaderManager::getUniformLocation(uint id)
+{
+ QVector<uint> &uniformLocations = currentShaderProg->uniformLocations;
+ uint oldSize = uniformLocations.size();
+ if (oldSize <= id) {
+ uint newSize = id + 1;
+ uniformLocations.resize(newSize);
+
+ for (uint i = oldSize; i < newSize; ++i)
+ uniformLocations[i] = GLuint(-1);
+ }
+ if (uniformLocations.at(id) == GLuint(-1))
+ uniformLocations[id] = currentShaderProg->program->uniformLocation(uniformIdentifiers.at(id));
+
+ return uniformLocations.at(id);
+}
void QGLEngineShaderManager::optimiseForBrushTransform(const QTransform &transform)
@@ -206,43 +228,61 @@ void QGLEngineShaderManager::setDirty()
void QGLEngineShaderManager::setSrcPixelType(Qt::BrushStyle style)
{
+ if (srcPixelType == PixelSrcType(style))
+ return;
+
srcPixelType = style;
shaderProgNeedsChanging = true; //###
}
void QGLEngineShaderManager::setSrcPixelType(PixelSrcType type)
{
+ if (srcPixelType == type)
+ return;
+
srcPixelType = type;
shaderProgNeedsChanging = true; //###
}
void QGLEngineShaderManager::setTextureCoordsEnabled(bool enabled)
{
+ if (useTextureCoords == enabled)
+ return;
+
useTextureCoords = enabled;
shaderProgNeedsChanging = true; //###
}
void QGLEngineShaderManager::setUseGlobalOpacity(bool useOpacity)
{
+ if (useGlobalOpacity == useOpacity)
+ return;
+
useGlobalOpacity = useOpacity;
shaderProgNeedsChanging = true; //###
}
void QGLEngineShaderManager::setMaskType(MaskType type)
{
+ if (maskType == type)
+ return;
+
maskType = type;
shaderProgNeedsChanging = true; //###
}
void QGLEngineShaderManager::setCompositionMode(QPainter::CompositionMode mode)
{
+ if (compositionMode == mode)
+ return;
+
compositionMode = mode;
shaderProgNeedsChanging = true; //###
}
QGLShaderProgram* QGLEngineShaderManager::currentProgram()
{
- return currentShaderProg;
+ return currentShaderProg->program;
}
QGLShaderProgram* QGLEngineShaderManager::simpleProgram()
@@ -432,15 +472,16 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
// At this point, requiredProgram is fully populated so try to find the program in the cache
- foreach (const QGLEngineShaderProg &prog, cachedPrograms) {
+ for (int i = 0; i < cachedPrograms.size(); ++i) {
+ QGLEngineShaderProg &prog = cachedPrograms[i];
if ( (prog.mainVertexShader == requiredProgram.mainVertexShader)
&& (prog.positionVertexShader == requiredProgram.positionVertexShader)
&& (prog.mainFragShader == requiredProgram.mainFragShader)
&& (prog.srcPixelFragShader == requiredProgram.srcPixelFragShader)
&& (prog.compositionFragShader == requiredProgram.compositionFragShader) )
{
- currentShaderProg = prog.program;
- currentShaderProg->enable();
+ currentShaderProg = &prog;
+ currentShaderProg->program->enable();
shaderProgNeedsChanging = false;
return true;
}
@@ -480,8 +521,10 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
}
else {
cachedPrograms.append(requiredProgram);
- currentShaderProg = requiredProgram.program;
- currentShaderProg->enable();
+ // taking the address here is safe since
+ // cachePrograms isn't resized anywhere else
+ currentShaderProg = &cachedPrograms.last();
+ currentShaderProg->program->enable();
}
shaderProgNeedsChanging = false;
return true;
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
index 9013884..34f0768 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
@@ -237,6 +237,8 @@ struct QGLEngineShaderProg
QGLShader* maskFragShader; // Can be null for no mask
QGLShader* compositionFragShader; // Can be null for GL-handled mode
QGLShaderProgram* program;
+
+ QVector<uint> uniformLocations;
};
/*
@@ -283,6 +285,9 @@ public:
void setMaskType(MaskType);
void setCompositionMode(QPainter::CompositionMode);
+ uint getUniformIdentifier(const char *uniformName);
+ uint getUniformLocation(uint id);
+
void setDirty(); // someone has manually changed the current shader program
bool useCorrectShaderProg(); // returns true if the shader program needed to be changed
@@ -374,9 +379,9 @@ private:
bool useTextureCoords;
QPainter::CompositionMode compositionMode;
- QGLShaderProgram* blitShaderProg;
- QGLShaderProgram* simpleShaderProg;
- QGLShaderProgram* currentShaderProg;
+ QGLShaderProgram* blitShaderProg;
+ QGLShaderProgram* simpleShaderProg;
+ QGLEngineShaderProg* currentShaderProg;
// TODO: Possibly convert to a LUT
QList<QGLEngineShaderProg> cachedPrograms;
@@ -386,6 +391,8 @@ private:
void compileNamedShader(QGLEngineShaderManager::ShaderName name, QGLShader::ShaderType type);
static const char* qglEngineShaderSourceCode[TotalShaderCount];
+
+ QVector<const char *> uniformIdentifiers;
};
QT_END_NAMESPACE
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 6ff0c53..91df197 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -248,9 +248,13 @@ QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate()
}
}
-void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform)
+void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id)
{
// glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); //### Is it always this texture unit?
+ if (id != -1 && id == lastTexture)
+ return;
+
+ lastTexture = id;
if (smoothPixmapTransform) {
glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -368,7 +372,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms()
if (style == Qt::SolidPattern) {
QColor col = premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity);
- shaderManager->currentProgram()->setUniformValue("fragmentColor", col);
+ shaderManager->currentProgram()->setUniformValue(location(FragmentColor), col);
}
else {
// All other brushes have a transform and thus need the translation point:
@@ -379,10 +383,10 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms()
QColor col = premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity);
- shaderManager->currentProgram()->setUniformValue("patternColor", col);
+ shaderManager->currentProgram()->setUniformValue(location(PatternColor), col);
QVector2D halfViewportSize(width*0.5, height*0.5);
- shaderManager->currentProgram()->setUniformValue("halfViewportSize", halfViewportSize);
+ shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize);
}
else if (style == Qt::LinearGradientPattern) {
const QLinearGradient *g = static_cast<const QLinearGradient *>(currentBrush->gradient());
@@ -399,10 +403,10 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms()
1.0f / (l.x() * l.x() + l.y() * l.y())
);
- shaderManager->currentProgram()->setUniformValue("linearData", linearData);
+ shaderManager->currentProgram()->setUniformValue(location(LinearData), linearData);
QVector2D halfViewportSize(width*0.5, height*0.5);
- shaderManager->currentProgram()->setUniformValue("halfViewportSize", halfViewportSize);
+ shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize);
}
else if (style == Qt::ConicalGradientPattern) {
const QConicalGradient *g = static_cast<const QConicalGradient *>(currentBrush->gradient());
@@ -410,10 +414,10 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms()
GLfloat angle = -(g->angle() * 2 * Q_PI) / 360.0;
- shaderManager->currentProgram()->setUniformValue("angle", angle);
+ shaderManager->currentProgram()->setUniformValue(location(Angle), angle);
QVector2D halfViewportSize(width*0.5, height*0.5);
- shaderManager->currentProgram()->setUniformValue("halfViewportSize", halfViewportSize);
+ shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize);
}
else if (style == Qt::RadialGradientPattern) {
const QRadialGradient *g = static_cast<const QRadialGradient *>(currentBrush->gradient());
@@ -423,15 +427,15 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms()
translationPoint = realFocal;
QPointF fmp = realCenter - realFocal;
- shaderManager->currentProgram()->setUniformValue("fmp", fmp);
+ shaderManager->currentProgram()->setUniformValue(location(Fmp), fmp);
GLfloat fmp2_m_radius2 = -fmp.x() * fmp.x() - fmp.y() * fmp.y() + realRadius*realRadius;
- shaderManager->currentProgram()->setUniformValue("fmp2_m_radius2", fmp2_m_radius2);
- shaderManager->currentProgram()->setUniformValue("inverse_2_fmp2_m_radius2",
+ shaderManager->currentProgram()->setUniformValue(location(Fmp2MRadius2), fmp2_m_radius2);
+ shaderManager->currentProgram()->setUniformValue(location(Inverse2Fmp2MRadius2),
GLfloat(1.0 / (2.0*fmp2_m_radius2)));
QVector2D halfViewportSize(width*0.5, height*0.5);
- shaderManager->currentProgram()->setUniformValue("halfViewportSize", halfViewportSize);
+ shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize);
}
else if (style == Qt::TexturePattern) {
translationPoint = q->state()->brushOrigin;
@@ -440,14 +444,14 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms()
if (qHasPixmapTexture(*currentBrush) && currentBrush->texture().isQBitmap()) {
QColor col = premultiplyColor(currentBrush->color(), (GLfloat)q->state()->opacity);
- shaderManager->currentProgram()->setUniformValue("patternColor", col);
+ shaderManager->currentProgram()->setUniformValue(location(PatternColor), col);
}
QSizeF invertedTextureSize( 1.0 / texPixmap.width(), 1.0 / texPixmap.height() );
- shaderManager->currentProgram()->setUniformValue("invertedTextureSize", invertedTextureSize);
+ shaderManager->currentProgram()->setUniformValue(location(InvertedTextureSize), invertedTextureSize);
QVector2D halfViewportSize(width*0.5, height*0.5);
- shaderManager->currentProgram()->setUniformValue("halfViewportSize", halfViewportSize);
+ shaderManager->currentProgram()->setUniformValue(location(HalfViewportSize), halfViewportSize);
}
else
qWarning("QGL2PaintEngineEx: Unimplemented fill style");
@@ -456,8 +460,8 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms()
QTransform gl_to_qt(1, 0, 0, -1, 0, height);
QTransform inv_matrix = gl_to_qt * (brushQTransform * q->state()->matrix).inverted() * translate;
- shaderManager->currentProgram()->setUniformValue("brushTransform", inv_matrix);
- shaderManager->currentProgram()->setUniformValue("brushTexture", QT_BRUSH_TEXTURE_UNIT);
+ shaderManager->currentProgram()->setUniformValue(location(BrushTransform), inv_matrix);
+ shaderManager->currentProgram()->setUniformValue(location(BrushTexture), QT_BRUSH_TEXTURE_UNIT);
}
brushUniformsDirty = false;
}
@@ -591,22 +595,17 @@ static inline void setCoords(GLfloat *coords, const QGLRect &rect)
void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern)
{
- transferMode(ImageDrawingMode);
-
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
-
// Setup for texture drawing
shaderManager->setSrcPixelType(pattern ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc);
shaderManager->setTextureCoordsEnabled(true);
- prepareForDraw(opaque);
+ if (prepareForDraw(opaque))
+ shaderManager->currentProgram()->setUniformValue(location(ImageTexture), QT_IMAGE_TEXTURE_UNIT);
if (pattern) {
QColor col = premultiplyColor(q->state()->pen.color(), (GLfloat)q->state()->opacity);
- shaderManager->currentProgram()->setUniformValue("patternColor", col);
+ shaderManager->currentProgram()->setUniformValue(location(PatternColor), col);
}
- shaderManager->currentProgram()->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT);
-
GLfloat dx = 1.0 / textureSize.width();
GLfloat dy = 1.0 / textureSize.height();
@@ -651,6 +650,8 @@ void QGL2PaintEngineEx::sync()
glLoadMatrixf(&mv_matrix[0][0]);
#endif
+ d->lastTexture = GLuint(-1);
+
glDisable(GL_BLEND);
glActiveTexture(GL_TEXTURE0);
}
@@ -663,6 +664,8 @@ void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode)
if (mode == TextDrawingMode || mode == ImageDrawingMode) {
glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
+
+ lastTexture = GLuint(-1);
}
if (mode == TextDrawingMode)
@@ -796,7 +799,7 @@ void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(QGL2PEXVertexArray& ve
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
-void QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque)
+bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque)
{
if (brushTextureDirty && mode != ImageDrawingMode)
updateBrushTexture();
@@ -808,12 +811,14 @@ void QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque)
updateMatrix();
const bool stateHasOpacity = q->state()->opacity < 0.99f;
- if (q->state()->compositionMode() == QPainter::CompositionMode_Source
- || (q->state()->compositionMode() == QPainter::CompositionMode_SourceOver
+ if (q->state()->composition_mode == QPainter::CompositionMode_Source
+ || (q->state()->composition_mode == QPainter::CompositionMode_SourceOver
&& srcPixelsAreOpaque && !stateHasOpacity))
+ {
glDisable(GL_BLEND);
- else
+ } else {
glEnable(GL_BLEND);
+ }
bool useGlobalOpacityUniform = stateHasOpacity;
if (stateHasOpacity && (mode != ImageDrawingMode)) {
@@ -827,29 +832,35 @@ void QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque)
shaderManager->setUseGlobalOpacity(useGlobalOpacityUniform);
+ bool changed = shaderManager->useCorrectShaderProg();
// If the shader program needs changing, we change it and mark all uniforms as dirty
- if (shaderManager->useCorrectShaderProg()) {
+ if (changed) {
// The shader program has changed so mark all uniforms as dirty:
brushUniformsDirty = true;
shaderMatrixUniformDirty = true;
depthUniformDirty = true;
+ opacityUniformDirty = true;
}
if (brushUniformsDirty && mode != ImageDrawingMode)
updateBrushUniforms();
if (shaderMatrixUniformDirty) {
- shaderManager->currentProgram()->setUniformValue("pmvMatrix", pmvMatrix);
+ shaderManager->currentProgram()->setUniformValue(location(PmvMatrix), pmvMatrix);
shaderMatrixUniformDirty = false;
}
if (depthUniformDirty) {
- shaderManager->currentProgram()->setUniformValue("depth", (GLfloat)q->state()->currentDepth);
+ shaderManager->currentProgram()->setUniformValue(location(Depth), (GLfloat)q->state()->currentDepth);
depthUniformDirty = false;
}
- if (useGlobalOpacityUniform)
- shaderManager->currentProgram()->setUniformValue("globalOpacity", (GLfloat)q->state()->opacity);
+ if (useGlobalOpacityUniform && opacityUniformDirty) {
+ shaderManager->currentProgram()->setUniformValue(location(GlobalOpacity), (GLfloat)q->state()->opacity);
+ opacityUniformDirty = false;
+ }
+
+ return changed;
}
void QGL2PaintEngineExPrivate::composite(const QGLRect& boundingRect)
@@ -971,6 +982,7 @@ void QGL2PaintEngineEx::opacityChanged()
Q_ASSERT(d->shaderManager);
d->brushUniformsDirty = true;
+ d->opacityUniformDirty = true;
}
void QGL2PaintEngineEx::compositionModeChanged()
@@ -990,6 +1002,8 @@ void QGL2PaintEngineEx::renderHintsChanged()
glDisable(GL_MULTISAMPLE);
#endif
+ Q_D(QGL2PaintEngineEx);
+ d->lastTexture = GLuint(-1);
// qDebug("QGL2PaintEngineEx::renderHintsChanged() not implemented!");
}
@@ -1008,11 +1022,13 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c
QGLContext *ctx = d->ctx;
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
- ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, true);
+ GLuint id = ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, true);
bool isBitmap = pixmap.isQBitmap();
bool isOpaque = !isBitmap && !pixmap.hasAlphaChannel();
+ d->updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT,
+ state()->renderHints & QPainter::SmoothPixmapTransform, id);
d->drawTexture(dest, src, pixmap.size(), isOpaque, isBitmap);
}
@@ -1025,8 +1041,10 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const
QGLContext *ctx = d->ctx;
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
- ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true);
+ GLuint id = ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true);
+ d->updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT,
+ state()->renderHints & QPainter::SmoothPixmapTransform, id);
d->drawTexture(dest, src, image.size(), !image.hasAlphaChannel());
}
@@ -1121,7 +1139,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte
prepareForDraw(false); // Text always causes src pixels to be transparent
- shaderManager->currentProgram()->setUniformValue("maskTexture", QT_MASK_TEXTURE_UNIT);
+ shaderManager->currentProgram()->setUniformValue(location(MaskTexture), QT_MASK_TEXTURE_UNIT);
if (vertexCoordinateArray.data() != oldVertexCoordinateDataPtr)
glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray.data());
@@ -1161,9 +1179,27 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
qt_resolve_version_2_0_functions(d->ctx);
#endif
- if (!d->shaderManager)
+ if (!d->shaderManager) {
d->shaderManager = new QGLEngineShaderManager(d->ctx);
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::ImageTexture] = d->shaderManager->getUniformIdentifier("imageTexture");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::PatternColor] = d->shaderManager->getUniformIdentifier("patternColor");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::GlobalOpacity] = d->shaderManager->getUniformIdentifier("globalOpacity");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::Depth] = d->shaderManager->getUniformIdentifier("depth");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::PmvMatrix] = d->shaderManager->getUniformIdentifier("pmvMatrix");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::MaskTexture] = d->shaderManager->getUniformIdentifier("maskTexture");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::FragmentColor] = d->shaderManager->getUniformIdentifier("fragmentColor");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::LinearData] = d->shaderManager->getUniformIdentifier("linearData");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::Angle] = d->shaderManager->getUniformIdentifier("angle");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::HalfViewportSize] = d->shaderManager->getUniformIdentifier("halfViewportSize");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::Fmp] = d->shaderManager->getUniformIdentifier("fmp");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::Fmp2MRadius2] = d->shaderManager->getUniformIdentifier("fmp2_m_radius2");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::Inverse2Fmp2MRadius2] = d->shaderManager->getUniformIdentifier("inverse_2_fmp2_m_radius2");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::InvertedTextureSize] = d->shaderManager->getUniformIdentifier("invertedTextureSize");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::BrushTransform] = d->shaderManager->getUniformIdentifier("brushTransform");
+ d->uniformIdentifiers[QGL2PaintEngineExPrivate::BrushTexture] = d->shaderManager->getUniformIdentifier("brushTexture");
+ }
+
glViewport(0, 0, d->width, d->height);
// glClearColor(0.0, 1.0, 0.0, 1.0);
@@ -1179,6 +1215,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
d->stencilBufferDirty = true;
d->simpleShaderDepthUniformDirty = true;
d->depthUniformDirty = true;
+ d->opacityUniformDirty = true;
d->use_system_clip = !systemClip().isEmpty();
@@ -1210,6 +1247,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
source->bind(false);
QRect rect(0, 0, source->width(), source->height());
+ d->updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
d->drawTexture(QRectF(rect), QRectF(rect), rect.size(), true);
}
@@ -1506,6 +1544,7 @@ void QGL2PaintEngineEx::setState(QPainterState *new_state)
d->depthUniformDirty = true;
d->simpleShaderMatrixUniformDirty = true;
d->shaderMatrixUniformDirty = true;
+ d->opacityUniformDirty = true;
if (old_state && old_state != s && old_state->canRestoreClip) {
d->updateDepthScissorTest();
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index a2a44c0..448964b 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -156,7 +156,7 @@ public:
void updateBrushUniforms();
void updateMatrix();
void updateCompositionMode();
- void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform);
+ void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id = -1);
void setBrush(const QBrush* brush);
@@ -175,7 +175,8 @@ public:
void fillStencilWithVertexArray(QGL2PEXVertexArray& vertexArray, bool useWindingFill);
// ^ Calls drawVertexArrays to render into stencil buffer
- void prepareForDraw(bool srcPixelsAreOpaque);
+ bool prepareForDraw(bool srcPixelsAreOpaque);
+ // ^ returns whether the current program changed or not
inline void useSimpleShader();
inline QColor premultiplyColor(QColor c, GLfloat opacity);
@@ -198,6 +199,7 @@ public:
bool stencilBufferDirty;
bool depthUniformDirty;
bool simpleShaderDepthUniformDirty;
+ bool opacityUniformDirty;
const QBrush* currentBrush; // May not be the state's brush!
@@ -218,6 +220,34 @@ public:
void regenerateDepthClip();
void systemStateChanged();
uint use_system_clip : 1;
+
+ enum Uniform {
+ ImageTexture,
+ PatternColor,
+ GlobalOpacity,
+ Depth,
+ PmvMatrix,
+ MaskTexture,
+ FragmentColor,
+ LinearData,
+ Angle,
+ HalfViewportSize,
+ Fmp,
+ Fmp2MRadius2,
+ Inverse2Fmp2MRadius2,
+ InvertedTextureSize,
+ BrushTransform,
+ BrushTexture,
+ NumUniforms
+ };
+
+ uint location(Uniform uniform)
+ {
+ return shaderManager->getUniformLocation(uniformIdentifiers[uniform]);
+ }
+
+ uint uniformIdentifiers[NumUniforms];
+ GLuint lastTexture;
};
QT_END_NAMESPACE