summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp32
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h8
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadersource_p.h9
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp198
-rw-r--r--src/opengl/qgl.cpp8
-rw-r--r--src/opengl/qgl.h1
-rw-r--r--src/opengl/qgl_x11.cpp2
-rw-r--r--src/opengl/qglshaderprogram.cpp186
-rw-r--r--src/opengl/qglshaderprogram.h20
-rw-r--r--src/opengl/util/fragmentprograms_p.h8
-rw-r--r--src/opengl/util/generator.cpp1
11 files changed, 323 insertions, 150 deletions
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index f64af85..ea57fdf 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -64,6 +64,7 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context)
maskType(NoMask),
useTextureCoords(false),
compositionMode(QPainter::CompositionMode_SourceOver),
+ blitShaderProg(0),
simpleShaderProg(0),
currentShaderProg(0)
{
@@ -83,6 +84,7 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context)
code[MainVertexShader] = qglslMainVertexShader;
code[MainWithTexCoordsVertexShader] = qglslMainWithTexCoordsVertexShader;
+ code[UntransformedPositionVertexShader] = qglslUntransformedPositionVertexShader;
code[PositionOnlyVertexShader] = qglslPositionOnlyVertexShader;
code[PositionWithPatternBrushVertexShader] = qglslPositionWithPatternBrushVertexShader;
code[PositionWithLinearGradientBrushVertexShader] = qglslPositionWithLinearGradientBrushVertexShader;
@@ -160,6 +162,24 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context)
qCritical() << "Errors linking simple shader:"
<< simpleShaderProg->log();
}
+
+ // Compile the blit shader:
+ blitShaderProg = new QGLShaderProgram(ctx, this);
+ compileNamedShader(MainWithTexCoordsVertexShader, QGLShader::PartialVertexShader);
+ compileNamedShader(UntransformedPositionVertexShader, QGLShader::PartialVertexShader);
+ compileNamedShader(MainFragmentShader, QGLShader::PartialFragmentShader);
+ compileNamedShader(ImageSrcFragmentShader, QGLShader::PartialFragmentShader);
+ blitShaderProg->addShader(compiledShaders[MainWithTexCoordsVertexShader]);
+ blitShaderProg->addShader(compiledShaders[UntransformedPositionVertexShader]);
+ blitShaderProg->addShader(compiledShaders[MainFragmentShader]);
+ blitShaderProg->addShader(compiledShaders[ImageSrcFragmentShader]);
+ blitShaderProg->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
+ blitShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
+ blitShaderProg->link();
+ if (!blitShaderProg->isLinked()) {
+ qCritical() << "Errors linking blit shader:"
+ << blitShaderProg->log();
+ }
}
QGLEngineShaderManager::~QGLEngineShaderManager()
@@ -176,6 +196,11 @@ void QGLEngineShaderManager::optimiseForBrushTransform(const QTransform &transfo
Q_UNUSED(transform); // Currently ignored
}
+void QGLEngineShaderManager::setDirty()
+{
+ shaderProgNeedsChanging = true;
+}
+
void QGLEngineShaderManager::setSrcPixelType(Qt::BrushStyle style)
{
srcPixelType = style;
@@ -222,6 +247,10 @@ QGLShaderProgram* QGLEngineShaderManager::simpleProgram()
return simpleShaderProg;
}
+QGLShaderProgram* QGLEngineShaderManager::blitProgram()
+{
+ return blitShaderProg;
+}
@@ -452,8 +481,7 @@ void QGLEngineShaderManager::compileNamedShader(QGLEngineShaderManager::ShaderNa
return;
QGLShader *newShader = new QGLShader(type, ctx, this);
- newShader->setSourceCode(qglEngineShaderSourceCode[name]);
- // newShader->compile(); ### does not exist?
+ newShader->compile(qglEngineShaderSourceCode[name]);
#if defined(QT_DEBUG)
// Name the shader for easier debugging
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
index b8b2745..afbc918 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
@@ -257,7 +257,7 @@ static const GLuint QT_TEXTURE_COORDS_ATTR = 1;
class QGLEngineShaderManager : public QObject
{
- Q_OBJECT;
+ Q_OBJECT
public:
QGLEngineShaderManager(QGLContext* context);
~QGLEngineShaderManager();
@@ -279,15 +279,18 @@ public:
void setMaskType(MaskType);
void setCompositionMode(QPainter::CompositionMode);
+ void setDirty(); // someone has manually changed the current shader program
bool useCorrectShaderProg(); // returns true if the shader program needed to be changed
QGLShaderProgram* currentProgram(); // Returns pointer to the shader the manager has chosen
QGLShaderProgram* simpleProgram(); // Used to draw into e.g. stencil buffers
+ QGLShaderProgram* blitProgram(); // Used to blit a texture into the framebuffer
enum ShaderName {
MainVertexShader,
MainWithTexCoordsVertexShader,
+ UntransformedPositionVertexShader,
PositionOnlyVertexShader,
PositionWithPatternBrushVertexShader,
PositionWithLinearGradientBrushVertexShader,
@@ -349,7 +352,7 @@ public:
*/
#if defined (QT_DEBUG)
- Q_ENUMS(ShaderName);
+ Q_ENUMS(ShaderName)
#endif
@@ -365,6 +368,7 @@ private:
bool useTextureCoords;
QPainter::CompositionMode compositionMode;
+ QGLShaderProgram* blitShaderProg;
QGLShaderProgram* simpleShaderProg;
QGLShaderProgram* currentShaderProg;
diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
index fdbba72..920d0bc 100644
--- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
@@ -89,6 +89,12 @@ static const char* const qglslPositionOnlyVertexShader = "\
gl_Position = pmvMatrix * vertexCoordsArray;\
}";
+static const char* const qglslUntransformedPositionVertexShader = "\
+ attribute highp vec4 vertexCoordsArray;\
+ void setPosition(void)\
+ {\
+ gl_Position = vertexCoordsArray;\
+ }";
// Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125
static const char* const qglslPositionWithPatternBrushVertexShader = "\
@@ -354,7 +360,7 @@ static const char* const qglslMaskFragmentShader = "\
lowp vec4 applyMask(lowp vec4 src) \
{\
lowp vec4 mask = texture2D(maskTexture, textureCoords); \
- return src * mask.r; \
+ return src * mask.a; \
}";
/*
@@ -375,7 +381,6 @@ static const char* const qglslMaskFragmentShader = "\
ExclusionCompositionModeFragmentShader,
*/
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 40f3a8d..868adcf 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -79,18 +79,165 @@
#include "qglengineshadermanager_p.h"
#include "qgl2pexvertexarray_p.h"
-
#include <QDebug>
QT_BEGIN_NAMESPACE
-extern QImage qt_imageForBrush(int brushStyle, bool invert);
-
static const GLuint QT_BRUSH_TEXTURE_UNIT = 0;
static const GLuint QT_IMAGE_TEXTURE_UNIT = 0; //Can be the same as brush texture unit
static const GLuint QT_MASK_TEXTURE_UNIT = 1;
static const GLuint QT_BACKGROUND_TEXTURE_UNIT = 2;
+class QGLTextureGlyphCache : public QTextureGlyphCache
+{
+public:
+ QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix);
+ ~QGLTextureGlyphCache();
+
+ virtual void createTextureData(int width, int height);
+ virtual void resizeTextureData(int width, int height);
+ virtual void fillTexture(const Coord &c, glyph_t glyph);
+
+ inline GLuint texture() const { return m_texture; }
+
+ inline int width() const { return m_width; }
+ inline int height() const { return m_height; }
+
+ inline void setPaintEnginePrivate(QGL2PaintEngineExPrivate *p) { pex = p; }
+
+private:
+ QGLContext *ctx;
+
+ QGL2PaintEngineExPrivate *pex;
+
+ GLuint m_texture;
+ GLuint m_fbo;
+
+ int m_width;
+ int m_height;
+
+ QGLShaderProgram *m_program;
+};
+
+QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix)
+ : QTextureGlyphCache(type, matrix)
+ , ctx(context)
+ , m_width(0)
+ , m_height(0)
+{
+ glGenFramebuffers(1, &m_fbo);
+}
+
+QGLTextureGlyphCache::~QGLTextureGlyphCache()
+{
+ glDeleteFramebuffers(1, &m_fbo);
+
+ if (m_width || m_height)
+ glDeleteTextures(1, &m_texture);
+}
+
+void QGLTextureGlyphCache::createTextureData(int width, int height)
+{
+ glGenTextures(1, &m_texture);
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+
+ m_width = width;
+ m_height = height;
+
+ QVarLengthArray<uchar> data(width * height);
+ for (int i = 0; i < width * height; ++i)
+ data[i] = 0;
+
+ if (m_type == QFontEngineGlyphCache::Raster_RGBMask)
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]);
+ else
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+}
+
+void QGLTextureGlyphCache::resizeTextureData(int width, int height)
+{
+ // ### the QTextureGlyphCache API needs to be reworked to allow
+ // ### resizeTextureData to fail
+
+ int oldWidth = m_width;
+ int oldHeight = m_height;
+
+ GLuint oldTexture = m_texture;
+ createTextureData(width, height);
+
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);
+
+ GLuint colorBuffer;
+ glGenRenderbuffers(1, &colorBuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER_EXT, colorBuffer);
+ glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_RGBA, oldWidth, oldHeight);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ GL_RENDERBUFFER_EXT, colorBuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
+
+ glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
+ glBindTexture(GL_TEXTURE_2D, oldTexture);
+
+ pex->transferMode(BrushDrawingMode);
+
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_DEPTH_TEST);
+
+ glViewport(0, 0, oldWidth, oldHeight);
+
+ float vertexCoordinateArray[] = { -1, -1, 1, -1, 1, 1, -1, 1 };
+ float textureCoordinateArray[] = { 0, 0, 1, 0, 1, 1, 0, 1 };
+
+ glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
+ glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
+
+ glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray);
+ glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray);
+
+ pex->shaderManager->blitProgram()->enable();
+ pex->shaderManager->blitProgram()->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT);
+ pex->shaderManager->setDirty();
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
+ glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
+
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ GL_RENDERBUFFER_EXT, 0);
+ glDeleteRenderbuffers(1, &colorBuffer);
+ glDeleteTextures(1, &oldTexture);
+
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
+
+ glViewport(0, 0, pex->width, pex->height);
+ pex->updateDepthClip();
+}
+
+void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph)
+{
+ QImage mask = textureMapForGlyph(glyph);
+
+ const uint maskWidth = mask.width();
+ const uint maskHeight = mask.height();
+
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ if (mask.format() == QImage::Format_RGB32) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, m_height - c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
+ } else {
+ mask = mask.convertToFormat(QImage::Format_Indexed8);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_ALPHA, GL_UNSIGNED_BYTE, mask.bits());
+ }
+}
+
+extern QImage qt_imageForBrush(int brushStyle, bool invert);
+
////////////////////////////////// Private Methods //////////////////////////////////////////
QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate()
@@ -141,6 +288,7 @@ void QGL2PaintEngineExPrivate::setBrush(const QBrush* brush)
void QGL2PaintEngineExPrivate::useSimpleShader()
{
shaderManager->simpleProgram()->enable();
+ shaderManager->setDirty();
if (matrixDirty)
updateMatrix();
@@ -905,8 +1053,6 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem
void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti)
{
- transferMode(TextDrawingMode);
-
Q_Q(QGL2PaintEngineEx);
QOpenGL2PaintEngineState *s = q->state();
@@ -921,34 +1067,32 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte
? QFontEngineGlyphCache::Type(ti.fontEngine->glyphFormat)
: QFontEngineGlyphCache::Raster_A8;
- GLenum maskFormat = GL_RGBA;
- if (glyphType == QFontEngineGlyphCache::Raster_A8) {
- shaderManager->setMaskType(QGLEngineShaderManager::PixelMask);
-// maskFormat = GL_ALPHA;
+ QGLTextureGlyphCache *cache =
+ (QGLTextureGlyphCache *) ti.fontEngine->glyphCache(ctx, s->matrix);
+ if (!cache) {
+ cache = new QGLTextureGlyphCache(ctx, glyphType, s->matrix);
+ ti.fontEngine->setGlyphCache(ctx, cache);
}
+
+ cache->setPaintEnginePrivate(this);
+ cache->populate(ti, glyphs, positions);
+
+ if (cache->width() == 0 || cache->height() == 0)
+ return;
+
+ transferMode(TextDrawingMode);
+
+ if (glyphType == QFontEngineGlyphCache::Raster_A8)
+ shaderManager->setMaskType(QGLEngineShaderManager::PixelMask);
else if (glyphType == QFontEngineGlyphCache::Raster_RGBMask)
shaderManager->setMaskType(QGLEngineShaderManager::SubPixelMask);
//### TODO: Gamma correction
shaderManager->setTextureCoordsEnabled(true);
-
- QImageTextureGlyphCache *cache =
- (QImageTextureGlyphCache *) ti.fontEngine->glyphCache(glyphType, s->matrix);
- if (!cache) {
- cache = new QImageTextureGlyphCache(glyphType, s->matrix);
- ti.fontEngine->setGlyphCache(glyphType, cache);
- }
-
- cache->populate(ti, glyphs, positions);
-
- const QImage &image = cache->image();
int margin = cache->glyphMargin();
- if (image.isNull())
- return;
-
- GLfloat dx = 1.0 / image.width();
- GLfloat dy = 1.0 / image.height();
+ GLfloat dx = 1.0 / cache->width();
+ GLfloat dy = 1.0 / cache->height();
QGLPoint *oldVertexCoordinateDataPtr = vertexCoordinateArray.data();
QGLPoint *oldTextureCoordinateDataPtr = textureCoordinateArray.data();
@@ -962,11 +1106,11 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte
int y = positions[i].y.toInt() - c.baseLineY - margin;
vertexCoordinateArray.addRect(QRectF(x, y, c.w, c.h));
- textureCoordinateArray.addRect(QRectF(c.x*dx, 1 - c.y*dy, c.w * dx, -c.h * dy));
+ textureCoordinateArray.addRect(QRectF(c.x*dx, c.y*dy, c.w * dx, c.h * dy));
}
glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
- ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true);
+ glBindTexture(GL_TEXTURE_2D, cache->texture());
updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
QBrush pensBrush = q->state()->pen.brush();
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 60039eb..2e72851 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1456,7 +1456,7 @@ struct DDSFormat {
#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
#endif
-Q_GLOBAL_STATIC(QGLShareRegister, _qgl_share_reg);
+Q_GLOBAL_STATIC(QGLShareRegister, _qgl_share_reg)
Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg()
{
return _qgl_share_reg();
@@ -2609,7 +2609,7 @@ const QGLContext* QGLContext::currentContext()
*/
/*! \fn int QGLContext::choosePixelFormat(void* dummyPfd, HDC pdc)
-
+
\bold{Win32 only:} This virtual function chooses a pixel format
that matches the OpenGL \link setFormat() format\endlink.
Reimplement this function in a subclass if you need a custom
@@ -2623,7 +2623,7 @@ const QGLContext* QGLContext::currentContext()
*/
/*! \fn void *QGLContext::chooseVisual()
-
+
\bold{X11 only:} This virtual function tries to find a visual that
matches the format, reducing the demands if the original request
cannot be met.
@@ -4354,7 +4354,7 @@ void QGLWidgetPrivate::initContext(QGLContext *context, const QGLWidget* shareWi
}
#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
-Q_GLOBAL_STATIC(QString, qt_gl_lib_name);
+Q_GLOBAL_STATIC(QString, qt_gl_lib_name)
Q_OPENGL_EXPORT void qt_set_gl_library_name(const QString& name)
{
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index 19d779a..6b511e2 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -363,6 +363,7 @@ private:
friend class QGLWindowSurface;
friend class QGLPixmapData;
friend class QGLPixmapFilterBase;
+ friend class QGLTextureGlyphCache;
friend QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags();
#ifdef Q_WS_MAC
public:
diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp
index 28a50bd..da61634 100644
--- a/src/opengl/qgl_x11.cpp
+++ b/src/opengl/qgl_x11.cpp
@@ -129,7 +129,7 @@ struct QGLCMapCleanupHandler {
CMapEntryHash *cmap_hash;
GLCMapHash *qglcmap_hash;
};
-Q_GLOBAL_STATIC(QGLCMapCleanupHandler, cmap_handler);
+Q_GLOBAL_STATIC(QGLCMapCleanupHandler, cmap_handler)
static void cleanup_cmaps()
{
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index d74b930..37732dd 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE
\code
QGLShader shader(QGLShader::VertexShader);
- shader.setSourceCode(code);
+ shader.compile(code);
QGLShaderProgram program(context);
program.addShader(shader);
@@ -245,14 +245,14 @@ class QGLShaderPrivate
{
public:
QGLShaderPrivate(QGLShader::ShaderType type, const QGLContext *ctx)
+ : context(ctx)
+ , shader(0)
+ , shaderType(type)
+ , compiled(false)
+ , isPartial(type == QGLShader::PartialVertexShader ||
+ type == QGLShader::PartialFragmentShader)
+ , hasPartialSource(false)
{
- context = ctx;
- shader = 0;
- shaderType = type;
- compiled = false;
- isPartial = (type == QGLShader::PartialVertexShader ||
- type == QGLShader::PartialFragmentShader);
- hasPartialSource = false;
}
const QGLContext *context;
@@ -265,7 +265,7 @@ public:
QByteArray partialSource;
bool create();
- bool compile();
+ bool compile(QGLShader *q);
};
#define ctx context
@@ -293,7 +293,7 @@ bool QGLShaderPrivate::create()
}
}
-bool QGLShaderPrivate::compile()
+bool QGLShaderPrivate::compile(QGLShader *q)
{
// Partial shaders are compiled during QGLShaderProgram::link().
if (isPartial && hasPartialSource) {
@@ -313,7 +313,11 @@ bool QGLShaderPrivate::compile()
GLint len;
glGetShaderInfoLog(shader, value, &len, logbuf);
log = QString::fromLatin1(logbuf);
- qWarning() << "QGLShader::compile:" << log;
+ QString name = q->objectName();
+ if (name.isEmpty())
+ qWarning() << "QGLShader::compile:" << log;
+ else
+ qWarning() << "QGLShader::compile[" << name << "]:" << log;
delete [] logbuf;
}
return compiled;
@@ -325,14 +329,14 @@ bool QGLShaderPrivate::compile()
/*!
Constructs a new QGLShader object of the specified \a type
and attaches it to \a parent. If shader programs are not supported,
- then isValid() will return false.
+ QGLShaderProgram::hasShaderPrograms() will return false.
- This constructor is normally followed by a call to setSourceCode()
- or setSourceCodeFile().
+ This constructor is normally followed by a call to compile()
+ or compileFile().
The shader will be associated with the current QGLContext.
- \sa setSourceCode(), setSourceCodeFile(), isValid()
+ \sa compile(), compileFile()
*/
QGLShader::QGLShader(QGLShader::ShaderType type, QObject *parent)
: QObject(parent)
@@ -346,11 +350,11 @@ QGLShader::QGLShader(QGLShader::ShaderType type, QObject *parent)
and attaches it to \a parent. If the filename ends in \c{.fsh},
it is assumed to be a fragment shader, otherwise it is assumed to
be a vertex shader (normally the extension is \c{.vsh} for vertex shaders).
- If the shader could not be loaded, then isValid() will return false.
+ If the shader could not be loaded, then isCompiled() will return false.
The shader will be associated with the current QGLContext.
- \sa isValid()
+ \sa isCompiled()
*/
QGLShader::QGLShader(const QString& fileName, QObject *parent)
: QObject(parent)
@@ -359,7 +363,7 @@ QGLShader::QGLShader(const QString& fileName, QObject *parent)
d = new QGLShaderPrivate(QGLShader::FragmentShader, QGLContext::currentContext());
else
d = new QGLShaderPrivate(QGLShader::VertexShader, QGLContext::currentContext());
- if (d->create() && !setSourceCodeFile(fileName)) {
+ if (d->create() && !compileFile(fileName)) {
if (d->shader)
glDeleteShader(d->shader);
d->shader = 0;
@@ -369,18 +373,18 @@ QGLShader::QGLShader(const QString& fileName, QObject *parent)
/*!
Constructs a new QGLShader object of the specified \a type from the
source code in \a fileName and attaches it to \a parent.
- If the shader could not be loaded, then isValid() will return false.
+ If the shader could not be loaded, then isCompiled() will return false.
The shader will be associated with the current QGLContext.
- \sa isValid()
+ \sa isCompiled()
*/
QGLShader::QGLShader
(const QString& fileName, QGLShader::ShaderType type, QObject *parent)
: QObject(parent)
{
d = new QGLShaderPrivate(type, QGLContext::currentContext());
- if (d->create() && !setSourceCodeFile(fileName)) {
+ if (d->create() && !compileFile(fileName)) {
if (d->shader)
glDeleteShader(d->shader);
d->shader = 0;
@@ -390,14 +394,14 @@ QGLShader::QGLShader
/*!
Constructs a new QGLShader object of the specified \a type
and attaches it to \a parent. If shader programs are not supported,
- then isValid() will return false.
+ then QGLShaderProgram::hasShaderPrograms() will return false.
- This constructor is normally followed by a call to setSourceCode()
- or setSourceCodeFile().
+ This constructor is normally followed by a call to compile()
+ or compileFile().
The shader will be associated with \a context.
- \sa setSourceCode(), setSourceCodeFile(), isValid()
+ \sa compile(), compileFile()
*/
QGLShader::QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObject *parent)
: QObject(parent)
@@ -411,11 +415,11 @@ QGLShader::QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObj
and attaches it to \a parent. If the filename ends in \c{.fsh},
it is assumed to be a fragment shader, otherwise it is assumed to
be a vertex shader (normally the extension is \c{.vsh} for vertex shaders).
- If the shader could not be loaded, then isValid() will return false.
+ If the shader could not be loaded, then isCompiled() will return false.
The shader will be associated with \a context.
- \sa isValid()
+ \sa isCompiled()
*/
QGLShader::QGLShader(const QString& fileName, const QGLContext *context, QObject *parent)
: QObject(parent)
@@ -424,7 +428,7 @@ QGLShader::QGLShader(const QString& fileName, const QGLContext *context, QObject
d = new QGLShaderPrivate(QGLShader::FragmentShader, context);
else
d = new QGLShaderPrivate(QGLShader::VertexShader, context);
- if (d->create() && !setSourceCodeFile(fileName)) {
+ if (d->create() && !compileFile(fileName)) {
if (d->shader)
glDeleteShader(d->shader);
d->shader = 0;
@@ -434,18 +438,18 @@ QGLShader::QGLShader(const QString& fileName, const QGLContext *context, QObject
/*!
Constructs a new QGLShader object of the specified \a type from the
source code in \a fileName and attaches it to \a parent.
- If the shader could not be loaded, then isValid() will return false.
+ If the shader could not be loaded, then isCompiled() will return false.
The shader will be associated with \a context.
- \sa isValid()
+ \sa isCompiled()
*/
QGLShader::QGLShader
(const QString& fileName, QGLShader::ShaderType type, const QGLContext *context, QObject *parent)
: QObject(parent)
{
d = new QGLShaderPrivate(type, context);
- if (d->create() && !setSourceCodeFile(fileName)) {
+ if (d->create() && !compileFile(fileName)) {
if (d->shader)
glDeleteShader(d->shader);
d->shader = 0;
@@ -465,24 +469,6 @@ QGLShader::~QGLShader()
}
/*!
- Returns true if this shader is valid. Shaders become invalid
- when they are destroyed and no longer attached to a QGLShaderProgram.
-*/
-bool QGLShader::isValid() const
-{
- if (d->isPartial && d->hasPartialSource)
- return true;
- if (!d->shader)
- return false;
-#if defined(QT_OPENGL_ES_2)
- return glIsShader(d->shader);
-#else
- // glIsShader() may not exist on some systems.
- return (!glIsShader || glIsShader(d->shader));
-#endif
-}
-
-/*!
Returns the type of this shader.
*/
QGLShader::ShaderType QGLShader::shaderType() const
@@ -509,13 +495,15 @@ static const char qualifierDefines[] =
then this function will always return true, even if the source code
is invalid. Partial shaders are compiled when QGLShaderProgram::link()
is called.
+
+ \sa compileFile()
*/
-bool QGLShader::setSourceCode(const char *source)
+bool QGLShader::compile(const char *source)
{
if (d->isPartial) {
d->partialSource = QByteArray(source);
d->hasPartialSource = true;
- return d->compile();
+ return d->compile(this);
} else if (d->shader) {
QVarLengthArray<const char *> src;
#ifdef QGL_DEFINE_QUALIFIERS
@@ -523,7 +511,7 @@ bool QGLShader::setSourceCode(const char *source)
#endif
src.append(source);
glShaderSource(d->shader, src.size(), src.data(), 0);
- return d->compile();
+ return d->compile(this);
} else {
return false;
}
@@ -539,10 +527,12 @@ bool QGLShader::setSourceCode(const char *source)
then this function will always return true, even if the source code
is invalid. Partial shaders are compiled when QGLShaderProgram::link()
is called.
+
+ \sa compileFile()
*/
-bool QGLShader::setSourceCode(const QByteArray& source)
+bool QGLShader::compile(const QByteArray& source)
{
- return setSourceCode(source.constData());
+ return compile(source.constData());
}
/*!
@@ -555,10 +545,12 @@ bool QGLShader::setSourceCode(const QByteArray& source)
then this function will always return true, even if the source code
is invalid. Partial shaders are compiled when QGLShaderProgram::link()
is called.
+
+ \sa compileFile()
*/
-bool QGLShader::setSourceCode(const QString& source)
+bool QGLShader::compile(const QString& source)
{
- return setSourceCode(source.toLatin1().constData());
+ return compile(source.toLatin1().constData());
}
/*!
@@ -570,8 +562,10 @@ bool QGLShader::setSourceCode(const QString& source)
then this function will always return true, even if the source code
is invalid. Partial shaders are compiled when QGLShaderProgram::link()
is called.
+
+ \sa compile()
*/
-bool QGLShader::setSourceCodeFile(const QString& fileName)
+bool QGLShader::compileFile(const QString& fileName)
{
QFile file(fileName);
if (!file.open(QFile::ReadOnly)) {
@@ -580,7 +574,7 @@ bool QGLShader::setSourceCodeFile(const QString& fileName)
}
QByteArray contents = file.readAll();
- return setSourceCode(contents.constData());
+ return compile(contents.constData());
}
/*!
@@ -592,9 +586,11 @@ bool QGLShader::setSourceCodeFile(const QString& fileName)
This function cannot be used with PartialVertexShader or
PartialFragmentShader.
+ If this function succeeds, then the shader will be considered compiled.
+
\sa shaderBinaryFormats()
*/
-bool QGLShader::setBinaryCode(GLenum format, const void *binary, int length)
+bool QGLShader::setShaderBinary(GLenum format, const void *binary, int length)
{
#if !defined(QT_OPENGL_ES_2)
if (!glShaderBinary)
@@ -604,7 +600,8 @@ bool QGLShader::setBinaryCode(GLenum format, const void *binary, int length)
return false;
glGetError(); // Clear error state.
glShaderBinary(1, &(d->shader), format, binary, length);
- return (glGetError() == GL_NO_ERROR);
+ d->compiled = (glGetError() == GL_NO_ERROR);
+ return d->compiled;
}
/*!
@@ -620,9 +617,11 @@ bool QGLShader::setBinaryCode(GLenum format, const void *binary, int length)
This function cannot be used with PartialVertexShader or
PartialFragmentShader.
+ If this function succeeds, then the shader will be considered compiled.
+
\sa shaderBinaryFormats()
*/
-bool QGLShader::setBinaryCode
+bool QGLShader::setShaderBinary
(QGLShader& otherShader, GLenum format, const void *binary, int length)
{
#if !defined(QT_OPENGL_ES_2)
@@ -638,14 +637,16 @@ bool QGLShader::setBinaryCode
shaders[0] = d->shader;
shaders[1] = otherShader.d->shader;
glShaderBinary(2, shaders, format, binary, length);
- return (glGetError() == GL_NO_ERROR);
+ d->compiled = (glGetError() == GL_NO_ERROR);
+ otherShader.d->compiled = d->compiled;
+ return d->compiled;
}
/*!
Returns a list of all binary formats that are supported by
- setBinaryCode() on this system.
+ setShaderBinary() on this system.
- \sa setBinaryCode()
+ \sa setShaderBinary()
*/
QList<GLenum> QGLShader::shaderBinaryFormats()
{
@@ -665,7 +666,7 @@ QList<GLenum> QGLShader::shaderBinaryFormats()
/*!
Returns the source code for this shader.
- \sa setSourceCode()
+ \sa compile()
*/
QByteArray QGLShader::sourceCode() const
{
@@ -688,7 +689,7 @@ QByteArray QGLShader::sourceCode() const
/*!
Returns true if this shader has been compiled; false otherwise.
- \sa setSourceCode()
+ \sa compile()
*/
bool QGLShader::isCompiled() const
{
@@ -698,7 +699,7 @@ bool QGLShader::isCompiled() const
/*!
Returns the errors and warnings that occurred during the last compile.
- \sa setSourceCode()
+ \sa compile()
*/
QString QGLShader::log() const
{
@@ -726,14 +727,14 @@ class QGLShaderProgramPrivate
{
public:
QGLShaderProgramPrivate(const QGLContext *ctx)
+ : context(ctx)
+ , program(0)
+ , linked(false)
+ , inited(false)
+ , hasPartialShaders(false)
+ , vertexShader(0)
+ , fragmentShader(0)
{
- context = ctx;
- program = 0;
- linked = false;
- inited = false;
- hasPartialShaders = false;
- vertexShader = 0;
- fragmentShader = 0;
}
~QGLShaderProgramPrivate()
{
@@ -762,7 +763,7 @@ public:
The shader program will be associated with the current QGLContext.
- \sa isValid(), addShader()
+ \sa addShader()
*/
QGLShaderProgram::QGLShaderProgram(QObject *parent)
: QObject(parent)
@@ -776,7 +777,7 @@ QGLShaderProgram::QGLShaderProgram(QObject *parent)
The shader program will be associated with \a context.
- \sa isValid(), addShader()
+ \sa addShader()
*/
QGLShaderProgram::QGLShaderProgram(const QGLContext *context, QObject *parent)
: QObject(parent)
@@ -815,21 +816,6 @@ bool QGLShaderProgram::init()
}
/*!
- Returns true if this shader program object is valid, false otherwise.
-*/
-bool QGLShaderProgram::isValid() const
-{
- if (!d->program)
- return false;
-#if defined(QT_OPENGL_ES_2)
- return glIsProgram(d->program);
-#else
- // glIsProgram() may not exist on some systems.
- return (!glIsProgram || glIsProgram(d->program));
-#endif
-}
-
-/*!
Adds a compiled \a shader to this shader program. Returns true
if the shader could be added, or false otherwise.
@@ -881,7 +867,7 @@ bool QGLShaderProgram::addShader(QGLShader::ShaderType type, const char *source)
if (!init())
return false;
QGLShader *shader = new QGLShader(type, this);
- if (!shader->setSourceCode(source)) {
+ if (!shader->compile(source)) {
d->log = shader->log();
delete shader;
return false;
@@ -1058,7 +1044,11 @@ bool QGLShaderProgram::setProgramBinary(int format, const QByteArray& binary)
GLint len;
glGetProgramInfoLog(d->program, value, &len, logbuf);
d->log = QString::fromLatin1(logbuf);
- qWarning() << "QGLShaderProgram::setProgramBinary:" << d->log;
+ QString name = objectName();
+ if (name.isEmpty())
+ qWarning() << "QGLShader::setProgramBinary:" << d->log;
+ else
+ qWarning() << "QGLShader::setProgramBinary[" << name << "]:" << d->log;
delete [] logbuf;
}
return d->linked;
@@ -1130,7 +1120,7 @@ bool QGLShaderProgram::link()
d->vertexShader =
new QGLShader(QGLShader::VertexShader, this);
}
- if (!d->vertexShader->setSourceCode(vertexSource)) {
+ if (!d->vertexShader->compile(vertexSource)) {
d->log = d->vertexShader->log();
return false;
}
@@ -1147,7 +1137,7 @@ bool QGLShaderProgram::link()
d->fragmentShader =
new QGLShader(QGLShader::FragmentShader, this);
}
- if (!d->fragmentShader->setSourceCode(fragmentSource)) {
+ if (!d->fragmentShader->compile(fragmentSource)) {
d->log = d->fragmentShader->log();
return false;
}
@@ -1166,7 +1156,11 @@ bool QGLShaderProgram::link()
GLint len;
glGetProgramInfoLog(d->program, value, &len, logbuf);
d->log = QString::fromLatin1(logbuf);
- qWarning() << "QGLShaderProgram::link:" << d->log;
+ QString name = objectName();
+ if (name.isEmpty())
+ qWarning() << "QGLShader::link:" << d->log;
+ else
+ qWarning() << "QGLShader::link[" << name << "]:" << d->log;
delete [] logbuf;
}
return d->linked;
diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h
index b69d28e..06bff42 100644
--- a/src/opengl/qglshaderprogram.h
+++ b/src/opengl/qglshaderprogram.h
@@ -79,17 +79,15 @@ public:
QGLShader(const QString& fileName, QGLShader::ShaderType type, const QGLContext *context, QObject *parent = 0);
virtual ~QGLShader();
- bool isValid() const;
-
QGLShader::ShaderType shaderType() const;
- bool setSourceCode(const char *source);
- bool setSourceCode(const QByteArray& source);
- bool setSourceCode(const QString& source);
- bool setSourceCodeFile(const QString& fileName);
+ bool compile(const char *source);
+ bool compile(const QByteArray& source);
+ bool compile(const QString& source);
+ bool compileFile(const QString& fileName);
- bool setBinaryCode(GLenum format, const void *binary, int length);
- bool setBinaryCode(QGLShader& otherShader, GLenum format, const void *binary, int length);
+ bool setShaderBinary(GLenum format, const void *binary, int length);
+ bool setShaderBinary(QGLShader& otherShader, GLenum format, const void *binary, int length);
static QList<GLenum> shaderBinaryFormats();
@@ -105,7 +103,7 @@ private:
friend class QGLShaderProgram;
- Q_DISABLE_COPY(QGLShader);
+ Q_DISABLE_COPY(QGLShader)
};
class QGLShaderProgramPrivate;
@@ -118,8 +116,6 @@ public:
explicit QGLShaderProgram(const QGLContext *context, QObject *parent = 0);
virtual ~QGLShaderProgram();
- bool isValid() const;
-
bool addShader(QGLShader *shader);
void removeShader(QGLShader *shader);
QList<QGLShader *> shaders() const;
@@ -283,7 +279,7 @@ public:
private:
QGLShaderProgramPrivate *d;
- Q_DISABLE_COPY(QGLShaderProgram);
+ Q_DISABLE_COPY(QGLShaderProgram)
bool init();
};
diff --git a/src/opengl/util/fragmentprograms_p.h b/src/opengl/util/fragmentprograms_p.h
index ecf0bf8..d4b54d4 100644
--- a/src/opengl/util/fragmentprograms_p.h
+++ b/src/opengl/util/fragmentprograms_p.h
@@ -71,7 +71,7 @@ enum FragmentVariable {
VAR_FMP2_M_RADIUS2,
VAR_FMP,
VAR_INV_MATRIX_M0,
- VAR_ANGLE,
+ VAR_ANGLE
};
enum FragmentBrushType {
@@ -80,7 +80,7 @@ enum FragmentBrushType {
FRAGMENT_PROGRAM_BRUSH_CONICAL,
FRAGMENT_PROGRAM_BRUSH_LINEAR,
FRAGMENT_PROGRAM_BRUSH_TEXTURE,
- FRAGMENT_PROGRAM_BRUSH_PATTERN,
+ FRAGMENT_PROGRAM_BRUSH_PATTERN
};
enum FragmentCompositionModeType {
@@ -109,12 +109,12 @@ enum FragmentCompositionModeType {
COMPOSITION_MODES_DIFFERENCE_NOMASK,
COMPOSITION_MODES_EXCLUSION_NOMASK,
COMPOSITION_MODE_BLEND_MODE_MASK,
- COMPOSITION_MODE_BLEND_MODE_NOMASK,
+ COMPOSITION_MODE_BLEND_MODE_NOMASK
};
enum FragmentMaskType {
FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA,
- FRAGMENT_PROGRAM_MASK_ELLIPSE_AA,
+ FRAGMENT_PROGRAM_MASK_ELLIPSE_AA
};
static const unsigned int num_fragment_variables = 19;
diff --git a/src/opengl/util/generator.cpp b/src/opengl/util/generator.cpp
index dac5a2d..430ced1 100644
--- a/src/opengl/util/generator.cpp
+++ b/src/opengl/util/generator.cpp
@@ -48,6 +48,7 @@
#include <QTextStream>
#include <QtDebug>
+#include <cstdlib>
QT_BEGIN_NAMESPACE