summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp55
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h1
-rw-r--r--src/opengl/gl2paintengineex/qglgradientcache.cpp25
-rw-r--r--src/opengl/gl2paintengineex/qglgradientcache_p.h9
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp36
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h8
-rw-r--r--src/opengl/gl2paintengineex/qrbtree_p.h573
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp74
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h48
-rw-r--r--src/opengl/gl2paintengineex/qtriangulator.cpp2612
-rw-r--r--src/opengl/gl2paintengineex/qtriangulator_p.h148
-rw-r--r--src/opengl/opengl.pro170
-rw-r--r--src/opengl/qgl.cpp825
-rw-r--r--src/opengl/qgl.h119
-rw-r--r--src/opengl/qgl_egl.cpp351
-rw-r--r--src/opengl/qgl_egl_p.h69
-rw-r--r--src/opengl/qgl_mac.mm996
-rw-r--r--src/opengl/qgl_p.h363
-rw-r--r--src/opengl/qgl_qpa.cpp224
-rw-r--r--src/opengl/qgl_qws.cpp318
-rw-r--r--src/opengl/qgl_symbian.cpp472
-rw-r--r--src/opengl/qgl_win.cpp1601
-rw-r--r--src/opengl/qgl_wince.cpp636
-rw-r--r--src/opengl/qgl_x11.cpp1904
-rw-r--r--src/opengl/qgl_x11egl.cpp562
-rw-r--r--src/opengl/qglbuffer.cpp71
-rw-r--r--src/opengl/qglextensions.cpp11
-rw-r--r--src/opengl/qglextensions_p.h40
-rw-r--r--src/opengl/qglframebufferobject.cpp208
-rw-r--r--src/opengl/qglframebufferobject.h19
-rw-r--r--src/opengl/qglframebufferobject_p.h17
-rw-r--r--src/opengl/qglfunctions.cpp36
-rw-r--r--src/opengl/qglfunctions.h20
-rw-r--r--src/opengl/qglpaintdevice.cpp22
-rw-r--r--src/opengl/qglpaintdevice_p.h2
-rw-r--r--src/opengl/qglpixelbuffer.cpp117
-rw-r--r--src/opengl/qglpixelbuffer.h13
-rw-r--r--src/opengl/qglpixelbuffer_egl.cpp224
-rw-r--r--src/opengl/qglpixelbuffer_mac.mm331
-rw-r--r--src/opengl/qglpixelbuffer_p.h103
-rw-r--r--src/opengl/qglpixelbuffer_win.cpp403
-rw-r--r--src/opengl/qglpixelbuffer_x11.cpp290
-rw-r--r--src/opengl/qglpixmapfilter.cpp621
-rw-r--r--src/opengl/qglpixmapfilter_p.h94
-rw-r--r--src/opengl/qglscreen_qws.cpp242
-rw-r--r--src/opengl/qglscreen_qws.h127
-rw-r--r--src/opengl/qglshaderprogram.cpp229
-rw-r--r--src/opengl/qglshaderprogram.h26
-rw-r--r--src/opengl/qgltexturepool.cpp244
-rw-r--r--src/opengl/qgltexturepool_p.h147
-rw-r--r--src/opengl/qglwindowsurface_qws.cpp133
-rw-r--r--src/opengl/qglwindowsurface_qws_p.h90
-rw-r--r--src/opengl/qgraphicsshadereffect.cpp6
-rw-r--r--src/opengl/qgraphicsshadereffect_p.h2
-rw-r--r--src/opengl/qgraphicssystem_gl.cpp114
-rw-r--r--src/opengl/qgraphicssystem_gl_p.h80
-rw-r--r--src/opengl/qpaintengine_opengl.cpp5635
-rw-r--r--src/opengl/qpaintengine_opengl_p.h158
-rw-r--r--src/opengl/qpixmapdata_gl.cpp829
-rw-r--r--src/opengl/qpixmapdata_gl_p.h247
-rw-r--r--src/opengl/qpixmapdata_poolgl.cpp934
-rw-r--r--src/opengl/qpixmapdata_x11gl_egl.cpp403
-rw-r--r--src/opengl/qpixmapdata_x11gl_p.h98
-rw-r--r--src/opengl/qwindowsurface_gl.cpp1174
-rw-r--r--src/opengl/qwindowsurface_gl_p.h129
-rw-r--r--src/opengl/qwindowsurface_x11gl.cpp213
-rw-r--r--src/opengl/qwindowsurface_x11gl_p.h83
-rw-r--r--src/opengl/util/README-GLSL18
-rw-r--r--src/opengl/util/brush_painter.glsl7
-rw-r--r--src/opengl/util/brushes.conf6
-rw-r--r--src/opengl/util/composition_mode_colorburn.glsl13
-rw-r--r--src/opengl/util/composition_mode_colordodge.glsl15
-rw-r--r--src/opengl/util/composition_mode_darken.glsl9
-rw-r--r--src/opengl/util/composition_mode_difference.glsl9
-rw-r--r--src/opengl/util/composition_mode_exclusion.glsl9
-rw-r--r--src/opengl/util/composition_mode_hardlight.glsl14
-rw-r--r--src/opengl/util/composition_mode_lighten.glsl9
-rw-r--r--src/opengl/util/composition_mode_multiply.glsl9
-rw-r--r--src/opengl/util/composition_mode_overlay.glsl13
-rw-r--r--src/opengl/util/composition_mode_screen.glsl6
-rw-r--r--src/opengl/util/composition_mode_softlight.glsl22
-rw-r--r--src/opengl/util/composition_modes.conf12
-rw-r--r--src/opengl/util/conical_brush.glsl27
-rw-r--r--src/opengl/util/ellipse_aa.glsl58
-rw-r--r--src/opengl/util/fast_painter.glsl19
-rw-r--r--src/opengl/util/fragmentprograms_p.h7287
-rw-r--r--src/opengl/util/generator.cpp500
-rw-r--r--src/opengl/util/generator.pro13
-rwxr-xr-xsrc/opengl/util/glsl_to_include.sh73
-rw-r--r--src/opengl/util/linear_brush.glsl22
-rw-r--r--src/opengl/util/masks.conf2
-rw-r--r--src/opengl/util/meego/main.cpp89
-rw-r--r--src/opengl/util/meego/shader-cache-introspector.pro7
-rw-r--r--src/opengl/util/painter.glsl21
-rw-r--r--src/opengl/util/painter_nomask.glsl9
-rw-r--r--src/opengl/util/pattern_brush.glsl23
-rw-r--r--src/opengl/util/radial_brush.glsl28
-rw-r--r--src/opengl/util/simple_porter_duff.glsl16
-rw-r--r--src/opengl/util/solid_brush.glsl4
-rw-r--r--src/opengl/util/texture_brush.glsl21
-rw-r--r--src/opengl/util/trap_exact_aa.glsl58
101 files changed, 611 insertions, 34021 deletions
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index 4c50089f6d..aebdce6e01 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -44,6 +44,8 @@
#include "qpaintengineex_opengl2_p.h"
#include "qglshadercache_p.h"
+#include <QtGui/private/qopenglcontext_p.h>
+
#if defined(QT_DEBUG)
#include <QMetaEnum>
#endif
@@ -52,18 +54,50 @@
QT_BEGIN_NAMESPACE
+class QGLEngineSharedShadersResource : public QOpenGLSharedResource
+{
+public:
+ QGLEngineSharedShadersResource(QOpenGLContext *ctx)
+ : QOpenGLSharedResource(ctx->shareGroup())
+ , m_shaders(new QGLEngineSharedShaders(QGLContext::fromOpenGLContext(ctx)))
+ {
+ }
+
+ ~QGLEngineSharedShadersResource()
+ {
+ delete m_shaders;
+ }
+
+ void invalidateResource()
+ {
+ delete m_shaders;
+ m_shaders = 0;
+ }
+
+ void freeResource(QOpenGLContext *)
+ {
+ }
+
+ QGLEngineSharedShaders *shaders() const { return m_shaders; }
+
+private:
+ QGLEngineSharedShaders *m_shaders;
+};
+
class QGLShaderStorage
{
public:
QGLEngineSharedShaders *shadersForThread(const QGLContext *context) {
- QGLContextGroupResource<QGLEngineSharedShaders> *&shaders = m_storage.localData();
+ QOpenGLMultiGroupSharedResource *&shaders = m_storage.localData();
if (!shaders)
- shaders = new QGLContextGroupResource<QGLEngineSharedShaders>();
- return shaders->value(context);
+ shaders = new QOpenGLMultiGroupSharedResource;
+ QGLEngineSharedShadersResource *resource =
+ shaders->value<QGLEngineSharedShadersResource>(context->contextHandle());
+ return resource ? resource->shaders() : 0;
}
private:
- QThreadStorage<QGLContextGroupResource<QGLEngineSharedShaders> *> m_storage;
+ QThreadStorage<QOpenGLMultiGroupSharedResource *> m_storage;
};
Q_GLOBAL_STATIC(QGLShaderStorage, qt_shader_storage);
@@ -81,8 +115,7 @@ const char* QGLEngineSharedShaders::qShaderSnippets[] = {
};
QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
- : ctxGuard(context)
- , blitShaderProg(0)
+ : blitShaderProg(0)
, simpleShaderProg(0)
{
@@ -327,14 +360,14 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS
vertexSource.append(qShaderSnippets[prog.mainVertexShader]);
vertexSource.append(qShaderSnippets[prog.positionVertexShader]);
- QScopedPointer<QGLShaderProgram> shaderProgram(new QGLShaderProgram(ctxGuard.context(), 0));
+ QScopedPointer<QGLShaderProgram> shaderProgram(new QGLShaderProgram);
CachedShader shaderCache(fragSource, vertexSource);
- bool inCache = shaderCache.load(shaderProgram.data(), ctxGuard.context());
+ bool inCache = shaderCache.load(shaderProgram.data(), QGLContext::currentContext());
if (!inCache) {
- QScopedPointer<QGLShader> fragShader(new QGLShader(QGLShader::Fragment, ctxGuard.context(), 0));
+ QScopedPointer<QGLShader> fragShader(new QGLShader(QGLShader::Fragment));
QByteArray description;
#if defined(QT_DEBUG)
// Name the shader for easier debugging
@@ -357,7 +390,7 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS
break;
}
- QScopedPointer<QGLShader> vertexShader(new QGLShader(QGLShader::Vertex, ctxGuard.context(), 0));
+ QScopedPointer<QGLShader> vertexShader(new QGLShader(QGLShader::Vertex));
#if defined(QT_DEBUG)
// Name the shader for easier debugging
description.clear();
@@ -396,7 +429,7 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS
newProg->program->link();
if (newProg->program->isLinked()) {
if (!inCache)
- shaderCache.store(newProg->program, ctxGuard.context());
+ shaderCache.store(newProg->program, QGLContext::currentContext());
} else {
QLatin1String none("none");
QLatin1String br("\n");
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
index 921df369f4..58c761df43 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
@@ -365,7 +365,6 @@ public:
void cleanupCustomStage(QGLCustomShaderStage* stage);
private:
- QGLSharedResourceGuard ctxGuard;
QGLShaderProgram *blitShaderProg;
QGLShaderProgram *simpleShaderProg;
QList<QGLEngineShaderProg*> cachedPrograms;
diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp
index 9e6b801c40..6ca09ba140 100644
--- a/src/opengl/gl2paintengineex/qglgradientcache.cpp
+++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp
@@ -51,21 +51,42 @@ class QGL2GradientCacheWrapper
public:
QGL2GradientCache *cacheForContext(const QGLContext *context) {
QMutexLocker lock(&m_mutex);
- return m_resource.value(context);
+ return m_resource.value<QGL2GradientCache>(context->contextHandle());
}
private:
- QGLContextGroupResource<QGL2GradientCache> m_resource;
+ QOpenGLMultiGroupSharedResource m_resource;
QMutex m_mutex;
};
Q_GLOBAL_STATIC(QGL2GradientCacheWrapper, qt_gradient_caches)
+QGL2GradientCache::QGL2GradientCache(QOpenGLContext *ctx)
+ : QOpenGLSharedResource(ctx->shareGroup())
+{
+}
+
+QGL2GradientCache::~QGL2GradientCache()
+{
+ cache.clear();
+}
+
QGL2GradientCache *QGL2GradientCache::cacheForContext(const QGLContext *context)
{
return qt_gradient_caches()->cacheForContext(context);
}
+void QGL2GradientCache::invalidateResource()
+{
+ QMutexLocker lock(&m_mutex);
+ cache.clear();
+}
+
+void QGL2GradientCache::freeResource(QOpenGLContext *)
+{
+ cleanCache();
+}
+
void QGL2GradientCache::cleanCache()
{
QMutexLocker lock(&m_mutex);
diff --git a/src/opengl/gl2paintengineex/qglgradientcache_p.h b/src/opengl/gl2paintengineex/qglgradientcache_p.h
index 1c2d0a029a..600085a75f 100644
--- a/src/opengl/gl2paintengineex/qglgradientcache_p.h
+++ b/src/opengl/gl2paintengineex/qglgradientcache_p.h
@@ -58,7 +58,7 @@
QT_BEGIN_NAMESPACE
-class QGL2GradientCache
+class QGL2GradientCache : public QOpenGLSharedResource
{
struct CacheInfo
{
@@ -76,12 +76,15 @@ class QGL2GradientCache
public:
static QGL2GradientCache *cacheForContext(const QGLContext *context);
- QGL2GradientCache(const QGLContext *) {}
- ~QGL2GradientCache() { cleanCache(); }
+ QGL2GradientCache(QOpenGLContext *);
+ ~QGL2GradientCache();
GLuint getBuffer(const QGradient &gradient, qreal opacity);
inline int paletteSize() const { return 1024; }
+ void invalidateResource();
+ void freeResource(QOpenGLContext *ctx);
+
private:
inline int maxCacheSize() const { return 60; }
inline void generateGradientColorTable(const QGradient& gradient,
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index d2c63ddc10..e6a12cd40c 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -76,10 +76,9 @@
#include <QPaintEngine>
#include <private/qpainter_p.h>
#include <private/qfontengine_p.h>
-#include <private/qpixmapdata_gl_p.h>
#include <private/qdatabuffer_p.h>
#include <private/qstatictext_p.h>
-#include <private/qtriangulator_p.h>
+#include <QtGui/private/qtriangulator_p.h>
#include "qglengineshadermanager_p.h"
#include "qgl2pexvertexarray_p.h"
@@ -668,6 +667,7 @@ struct QGL2PEVectorPathCache
int indexCount;
GLenum primitiveType;
qreal iscale;
+ QVertexIndexVector::Type indexType;
};
void QGL2PaintEngineExPrivate::cleanupVectorPath(QPaintEngineEx *engine, void *data)
@@ -825,13 +825,14 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
cache->indexCount = polys.indices.size();
cache->primitiveType = GL_TRIANGLES;
cache->iscale = inverseScale;
+ cache->indexType = polys.indices.type();
#ifdef QT_OPENGL_CACHE_AS_VBOS
glGenBuffers(1, &cache->vbo);
glGenBuffers(1, &cache->ibo);
glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo);
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint)
+ if (polys.indices.type() == QVertexIndexVector::UnsignedInt)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint32) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW);
else
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint16) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW);
@@ -842,7 +843,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), vertices.data(), GL_STATIC_DRAW);
#else
cache->vertices = (float *) qMalloc(sizeof(float) * polys.vertices.size());
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
+ if (polys.indices.type() == QVertexIndexVector::UnsignedInt) {
cache->indices = (quint32 *) qMalloc(sizeof(quint32) * polys.indices.size());
memcpy(cache->indices, polys.indices.data(), sizeof(quint32) * polys.indices.size());
} else {
@@ -859,7 +860,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
glBindBuffer(GL_ARRAY_BUFFER, cache->vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo);
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0);
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint)
+ if (cache->indexType == QVertexIndexVector::UnsignedInt)
glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, 0);
else
glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, 0);
@@ -867,7 +868,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
glBindBuffer(GL_ARRAY_BUFFER, 0);
#else
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices);
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint)
+ if (cache->indexType == QVertexIndexVector::UnsignedInt)
glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, (qint32 *)cache->indices);
else
glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, (qint16 *)cache->indices);
@@ -896,7 +897,7 @@ void QGL2PaintEngineExPrivate::fill(const QVectorPath& path)
prepareForDraw(currentBrush.isOpaque());
setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertices.constData());
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint)
+ if (polys.indices.type() == QVertexIndexVector::UnsignedInt)
glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_INT, polys.indices.data());
else
glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_SHORT, polys.indices.data());
@@ -1581,10 +1582,9 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
QGLTextureGlyphCache *cache =
(QGLTextureGlyphCache *) staticTextItem->fontEngine()->glyphCache(cacheKey, glyphType, QTransform());
- if (!cache || cache->cacheType() != glyphType || cache->context() == 0) {
- cache = new QGLTextureGlyphCache(ctx, glyphType, QTransform());
+ if (!cache || cache->cacheType() != glyphType || cache->contextGroup() == 0) {
+ cache = new QGLTextureGlyphCache(glyphType, QTransform());
staticTextItem->fontEngine()->setGlyphCache(cacheKey, cache);
- cache->insert(ctx, cache);
recreateVertexArrays = true;
}
@@ -2048,21 +2048,13 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
bool QGL2PaintEngineEx::end()
{
Q_D(QGL2PaintEngineEx);
- QGLContext *ctx = d->ctx;
+ QGLContext *ctx = d->ctx;
glUseProgram(0);
d->transferMode(BrushDrawingMode);
d->device->endPaint();
-#if defined(Q_WS_X11)
- // On some (probably all) drivers, deleting an X pixmap which has been bound to a texture
- // before calling glFinish/swapBuffers renders garbage. Presumably this is because X deletes
- // the pixmap behind the driver's back before it's had a chance to use it. To fix this, we
- // reference all QPixmaps which have been bound to stop them being deleted and only deref
- // them here, after swapBuffers, where they can be safely deleted.
- ctx->d_func()->boundPixmaps.clear();
-#endif
- d->ctx->d_ptr->active_engine = 0;
+ ctx->d_ptr->active_engine = 0;
d->resetGLState();
@@ -2335,8 +2327,8 @@ void QGL2PaintEngineExPrivate::systemStateChanged()
if (systemClip.isEmpty()) {
useSystemClip = false;
} else {
- if (q->paintDevice()->devType() == QInternal::Widget && currentClipWidget) {
- QWidgetPrivate *widgetPrivate = qt_widget_private(currentClipWidget->window());
+ if (q->paintDevice()->devType() == QInternal::Widget && currentClipDevice) {
+ QWidgetPrivate *widgetPrivate = qt_widget_private(static_cast<QWidget *>(currentClipDevice)->window());
useSystemClip = widgetPrivate->extra && widgetPrivate->extra->inRenderWithPainter;
} else {
useSystemClip = true;
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index 2895d5a9b0..dbf760929c 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -59,7 +59,6 @@
#include <private/qglengineshadermanager_p.h>
#include <private/qgl2pexvertexarray_p.h>
#include <private/qglpaintdevice_p.h>
-#include <private/qglpixmapfilter_p.h>
#include <private/qfontengine_p.h>
#include <private/qdatabuffer_p.h>
#include <private/qtriangulatingstroker_p.h>
@@ -153,8 +152,6 @@ public:
void invalidateState();
- QPixmapFilter *pixmapFilter(int type, const QPixmapFilter *prototype);
-
void setRenderTextActive(bool);
bool isNativePaintingActive() const;
@@ -302,11 +299,6 @@ public:
QTriangulatingStroker stroker;
QDashedStrokeProcessor dasher;
- QScopedPointer<QPixmapFilter> convolutionFilter;
- QScopedPointer<QPixmapFilter> colorizeFilter;
- QScopedPointer<QPixmapFilter> blurFilter;
- QScopedPointer<QPixmapFilter> dropShadowFilter;
-
QSet<QVectorPath::CacheEntry *> pathCaches;
QVector<GLuint> unusedVBOSToClean;
QVector<GLuint> unusedIBOSToClean;
diff --git a/src/opengl/gl2paintengineex/qrbtree_p.h b/src/opengl/gl2paintengineex/qrbtree_p.h
deleted file mode 100644
index 09ef81cdbb..0000000000
--- a/src/opengl/gl2paintengineex/qrbtree_p.h
+++ /dev/null
@@ -1,573 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QRBTREE_P_H
-#define QRBTREE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-template <class T>
-struct QRBTree
-{
- struct Node
- {
- inline Node() : parent(0), left(0), right(0), red(true) { }
- inline ~Node() {if (left) delete left; if (right) delete right;}
- T data;
- Node *parent;
- Node *left;
- Node *right;
- bool red;
- };
-
- inline QRBTree() : root(0), freeList(0) { }
- inline ~QRBTree();
-
- inline void clear();
-
- void attachBefore(Node *parent, Node *child);
- void attachAfter(Node *parent, Node *child);
-
- inline Node *front(Node *node) const;
- inline Node *back(Node *node) const;
- Node *next(Node *node) const;
- Node *previous(Node *node) const;
-
- inline void deleteNode(Node *&node);
- inline Node *newNode();
-
- // Return 1 if 'left' comes after 'right', 0 if equal, and -1 otherwise.
- // 'left' and 'right' cannot be null.
- int order(Node *left, Node *right);
- inline bool validate() const;
-
-private:
- void rotateLeft(Node *node);
- void rotateRight(Node *node);
- void update(Node *node);
-
- inline void attachLeft(Node *parent, Node *child);
- inline void attachRight(Node *parent, Node *child);
-
- int blackDepth(Node *top) const;
- bool checkRedBlackProperty(Node *top) const;
-
- void swapNodes(Node *n1, Node *n2);
- void detach(Node *node);
-
- // 'node' must be black. rebalance will reduce the depth of black nodes by one in the sibling tree.
- void rebalance(Node *node);
-
-public:
- Node *root;
-private:
- Node *freeList;
-};
-
-template <class T>
-inline QRBTree<T>::~QRBTree()
-{
- clear();
- while (freeList) {
- // Avoid recursively calling the destructor, as this list may become large.
- Node *next = freeList->right;
- freeList->right = 0;
- delete freeList;
- freeList = next;
- }
-}
-
-template <class T>
-inline void QRBTree<T>::clear()
-{
- if (root)
- delete root;
- root = 0;
-}
-
-template <class T>
-void QRBTree<T>::rotateLeft(Node *node)
-{
- // | | //
- // N B //
- // / \ / \ //
- // A B ---> N D //
- // / \ / \ //
- // C D A C //
-
- Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
- ref = node->right;
- node->right->parent = node->parent;
-
- // : //
- // N //
- // / :| //
- // A B //
- // / \ //
- // C D //
-
- node->right = ref->left;
- if (ref->left)
- ref->left->parent = node;
-
- // : | //
- // N B //
- // / \ : \ //
- // A C D //
-
- ref->left = node;
- node->parent = ref;
-
- // | //
- // B //
- // / \ //
- // N D //
- // / \ //
- // A C //
-}
-
-template <class T>
-void QRBTree<T>::rotateRight(Node *node)
-{
- // | | //
- // N A //
- // / \ / \ //
- // A B ---> C N //
- // / \ / \ //
- // C D D B //
-
- Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
- ref = node->left;
- node->left->parent = node->parent;
-
- node->left = ref->right;
- if (ref->right)
- ref->right->parent = node;
-
- ref->right = node;
- node->parent = ref;
-}
-
-template <class T>
-void QRBTree<T>::update(Node *node) // call this after inserting a node
-{
- for (;;) {
- Node *parent = node->parent;
-
- // if the node is the root, color it black
- if (!parent) {
- node->red = false;
- return;
- }
-
- // if the parent is black, the node can be left red
- if (!parent->red)
- return;
-
- // at this point, the parent is red and cannot be the root
- Node *grandpa = parent->parent;
- Q_ASSERT(grandpa);
-
- Node *uncle = (parent == grandpa->left ? grandpa->right : grandpa->left);
- if (uncle && uncle->red) {
- // grandpa's black, parent and uncle are red.
- // let parent and uncle be black, grandpa red and recursively update grandpa.
- Q_ASSERT(!grandpa->red);
- parent->red = false;
- uncle->red = false;
- grandpa->red = true;
- node = grandpa;
- continue;
- }
-
- // at this point, uncle is black
- if (node == parent->right && parent == grandpa->left)
- rotateLeft(node = parent);
- else if (node == parent->left && parent == grandpa->right)
- rotateRight(node = parent);
- parent = node->parent;
-
- if (parent == grandpa->left) {
- rotateRight(grandpa);
- parent->red = false;
- grandpa->red = true;
- } else {
- rotateLeft(grandpa);
- parent->red = false;
- grandpa->red = true;
- }
- return;
- }
-}
-
-template <class T>
-inline void QRBTree<T>::attachLeft(Node *parent, Node *child)
-{
- Q_ASSERT(!parent->left);
- parent->left = child;
- child->parent = parent;
- update(child);
-}
-
-template <class T>
-inline void QRBTree<T>::attachRight(Node *parent, Node *child)
-{
- Q_ASSERT(!parent->right);
- parent->right = child;
- child->parent = parent;
- update(child);
-}
-
-template <class T>
-void QRBTree<T>::attachBefore(Node *parent, Node *child)
-{
- if (!root)
- update(root = child);
- else if (!parent)
- attachRight(back(root), child);
- else if (parent->left)
- attachRight(back(parent->left), child);
- else
- attachLeft(parent, child);
-}
-
-template <class T>
-void QRBTree<T>::attachAfter(Node *parent, Node *child)
-{
- if (!root)
- update(root = child);
- else if (!parent)
- attachLeft(front(root), child);
- else if (parent->right)
- attachLeft(front(parent->right), child);
- else
- attachRight(parent, child);
-}
-
-template <class T>
-void QRBTree<T>::swapNodes(Node *n1, Node *n2)
-{
- // Since iterators must not be invalidated, it is not sufficient to only swap the data.
- if (n1->parent == n2) {
- n1->parent = n2->parent;
- n2->parent = n1;
- } else if (n2->parent == n1) {
- n2->parent = n1->parent;
- n1->parent = n2;
- } else {
- qSwap(n1->parent, n2->parent);
- }
-
- qSwap(n1->left, n2->left);
- qSwap(n1->right, n2->right);
- qSwap(n1->red, n2->red);
-
- if (n1->parent) {
- if (n1->parent->left == n2)
- n1->parent->left = n1;
- else
- n1->parent->right = n1;
- } else {
- root = n1;
- }
-
- if (n2->parent) {
- if (n2->parent->left == n1)
- n2->parent->left = n2;
- else
- n2->parent->right = n2;
- } else {
- root = n2;
- }
-
- if (n1->left)
- n1->left->parent = n1;
- if (n1->right)
- n1->right->parent = n1;
-
- if (n2->left)
- n2->left->parent = n2;
- if (n2->right)
- n2->right->parent = n2;
-}
-
-template <class T>
-void QRBTree<T>::detach(Node *node) // call this before removing a node.
-{
- if (node->right)
- swapNodes(node, front(node->right));
-
- Node *child = (node->left ? node->left : node->right);
-
- if (!node->red) {
- if (child && child->red)
- child->red = false;
- else
- rebalance(node);
- }
-
- Node *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : root);
- ref = child;
- if (child)
- child->parent = node->parent;
- node->left = node->right = node->parent = 0;
-}
-
-// 'node' must be black. rebalance will reduce the depth of black nodes by one in the sibling tree.
-template <class T>
-void QRBTree<T>::rebalance(Node *node)
-{
- Q_ASSERT(!node->red);
- for (;;) {
- if (!node->parent)
- return;
-
- // at this point, node is not a parent, it is black, thus it must have a sibling.
- Node *sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
- Q_ASSERT(sibling);
-
- if (sibling->red) {
- sibling->red = false;
- node->parent->red = true;
- if (node == node->parent->left)
- rotateLeft(node->parent);
- else
- rotateRight(node->parent);
- sibling = (node == node->parent->left ? node->parent->right : node->parent->left);
- Q_ASSERT(sibling);
- }
-
- // at this point, the sibling is black.
- Q_ASSERT(!sibling->red);
-
- if ((!sibling->left || !sibling->left->red) && (!sibling->right || !sibling->right->red)) {
- bool parentWasRed = node->parent->red;
- sibling->red = true;
- node->parent->red = false;
- if (parentWasRed)
- return;
- node = node->parent;
- continue;
- }
-
- // at this point, at least one of the sibling's children is red.
-
- if (node == node->parent->left) {
- if (!sibling->right || !sibling->right->red) {
- Q_ASSERT(sibling->left);
- sibling->red = true;
- sibling->left->red = false;
- rotateRight(sibling);
-
- sibling = sibling->parent;
- Q_ASSERT(sibling);
- }
- sibling->red = node->parent->red;
- node->parent->red = false;
-
- Q_ASSERT(sibling->right->red);
- sibling->right->red = false;
- rotateLeft(node->parent);
- } else {
- if (!sibling->left || !sibling->left->red) {
- Q_ASSERT(sibling->right);
- sibling->red = true;
- sibling->right->red = false;
- rotateLeft(sibling);
-
- sibling = sibling->parent;
- Q_ASSERT(sibling);
- }
- sibling->red = node->parent->red;
- node->parent->red = false;
-
- Q_ASSERT(sibling->left->red);
- sibling->left->red = false;
- rotateRight(node->parent);
- }
- return;
- }
-}
-
-template <class T>
-inline typename QRBTree<T>::Node *QRBTree<T>::front(Node *node) const
-{
- while (node->left)
- node = node->left;
- return node;
-}
-
-template <class T>
-inline typename QRBTree<T>::Node *QRBTree<T>::back(Node *node) const
-{
- while (node->right)
- node = node->right;
- return node;
-}
-
-template <class T>
-typename QRBTree<T>::Node *QRBTree<T>::next(Node *node) const
-{
- if (node->right)
- return front(node->right);
- while (node->parent && node == node->parent->right)
- node = node->parent;
- return node->parent;
-}
-
-template <class T>
-typename QRBTree<T>::Node *QRBTree<T>::previous(Node *node) const
-{
- if (node->left)
- return back(node->left);
- while (node->parent && node == node->parent->left)
- node = node->parent;
- return node->parent;
-}
-
-template <class T>
-int QRBTree<T>::blackDepth(Node *top) const
-{
- if (!top)
- return 0;
- int leftDepth = blackDepth(top->left);
- int rightDepth = blackDepth(top->right);
- if (leftDepth != rightDepth)
- return -1;
- if (!top->red)
- ++leftDepth;
- return leftDepth;
-}
-
-template <class T>
-bool QRBTree<T>::checkRedBlackProperty(Node *top) const
-{
- if (!top)
- return true;
- if (top->left && !checkRedBlackProperty(top->left))
- return false;
- if (top->right && !checkRedBlackProperty(top->right))
- return false;
- return !(top->red && ((top->left && top->left->red) || (top->right && top->right->red)));
-}
-
-template <class T>
-inline bool QRBTree<T>::validate() const
-{
- return checkRedBlackProperty(root) && blackDepth(root) != -1;
-}
-
-template <class T>
-inline void QRBTree<T>::deleteNode(Node *&node)
-{
- Q_ASSERT(node);
- detach(node);
- node->right = freeList;
- freeList = node;
- node = 0;
-}
-
-template <class T>
-inline typename QRBTree<T>::Node *QRBTree<T>::newNode()
-{
- if (freeList) {
- Node *node = freeList;
- freeList = freeList->right;
- node->parent = node->left = node->right = 0;
- node->red = true;
- return node;
- }
- return new Node;
-}
-
-// Return 1 if 'left' comes after 'right', 0 if equal, and -1 otherwise.
-// 'left' and 'right' cannot be null.
-template <class T>
-int QRBTree<T>::order(Node *left, Node *right)
-{
- Q_ASSERT(left && right);
- if (left == right)
- return 0;
-
- QVector<Node *> leftAncestors;
- QVector<Node *> rightAncestors;
- while (left) {
- leftAncestors.push_back(left);
- left = left->parent;
- }
- while (right) {
- rightAncestors.push_back(right);
- right = right->parent;
- }
- Q_ASSERT(leftAncestors.back() == root && rightAncestors.back() == root);
-
- while (!leftAncestors.empty() && !rightAncestors.empty() && leftAncestors.back() == rightAncestors.back()) {
- leftAncestors.pop_back();
- rightAncestors.pop_back();
- }
-
- if (!leftAncestors.empty())
- return (leftAncestors.back() == leftAncestors.back()->parent->left ? -1 : 1);
-
- if (!rightAncestors.empty())
- return (rightAncestors.back() == rightAncestors.back()->parent->right ? -1 : 1);
-
- // The code should never reach this point.
- Q_ASSERT(!leftAncestors.empty() || !rightAncestors.empty());
- return 0;
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
index dbed354dfb..af6cb53a3a 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
@@ -43,10 +43,6 @@
#include "qpaintengineex_opengl2_p.h"
#include "private/qglengineshadersource_p.h"
-#if defined QT_OPENGL_ES_2 && !defined(QT_NO_EGL)
-#include "private/qeglcontext_p.h"
-#endif
-
QT_BEGIN_NAMESPACE
#ifdef Q_WS_WIN
@@ -55,19 +51,16 @@ extern Q_GUI_EXPORT bool qt_cleartype_enabled;
QBasicAtomicInt qgltextureglyphcache_serial_number = Q_BASIC_ATOMIC_INITIALIZER(1);
-QGLTextureGlyphCache::QGLTextureGlyphCache(const QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix)
- : QImageTextureGlyphCache(type, matrix), QGLContextGroupResourceBase()
- , ctx(0)
+QGLTextureGlyphCache::QGLTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix)
+ : QImageTextureGlyphCache(type, matrix)
, pex(0)
, m_blitProgram(0)
, m_filterMode(Nearest)
, m_serialNumber(qgltextureglyphcache_serial_number.fetchAndAddRelaxed(1))
{
#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
- qDebug(" -> QGLTextureGlyphCache() %p for context %p.", this, ctx);
+ qDebug(" -> QGLTextureGlyphCache() %p for context %p.", this, QOpenGLContext::currentContext());
#endif
- setContext(context);
-
m_vertexCoordinateArray[0] = -1.0f;
m_vertexCoordinateArray[1] = -1.0f;
m_vertexCoordinateArray[2] = 1.0f;
@@ -95,14 +88,9 @@ QGLTextureGlyphCache::~QGLTextureGlyphCache()
delete m_blitProgram;
}
-void QGLTextureGlyphCache::setContext(const QGLContext *context)
-{
- ctx = context;
- m_h = 0;
-}
-
void QGLTextureGlyphCache::createTextureData(int width, int height)
{
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
if (ctx == 0) {
qWarning("QGLTextureGlyphCache::createTextureData: Called with no context");
return;
@@ -120,12 +108,17 @@ void QGLTextureGlyphCache::createTextureData(int width, int height)
if (height < 16)
height = 16;
- QGLGlyphTexture *glyphTexture = m_textureResource.value(ctx);
- glGenTextures(1, &glyphTexture->m_texture);
- glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture);
+ if (m_textureResource && !m_textureResource->m_texture)
+ delete m_textureResource;
+
+ if (!m_textureResource)
+ m_textureResource = new QGLGlyphTexture(ctx);
+
+ glGenTextures(1, &m_textureResource->m_texture);
+ glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
- glyphTexture->m_width = width;
- glyphTexture->m_height = height;
+ m_textureResource->m_width = width;
+ m_textureResource->m_height = height;
if (m_type == QFontEngineGlyphCache::Raster_RGBMask) {
QVarLengthArray<uchar> data(width * height * 4);
@@ -148,14 +141,14 @@ void QGLTextureGlyphCache::createTextureData(int width, int height)
void QGLTextureGlyphCache::resizeTextureData(int width, int height)
{
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
if (ctx == 0) {
qWarning("QGLTextureGlyphCache::resizeTextureData: Called with no context");
return;
}
- QGLGlyphTexture *glyphTexture = m_textureResource.value(ctx);
- int oldWidth = glyphTexture->m_width;
- int oldHeight = glyphTexture->m_height;
+ int oldWidth = m_textureResource->m_width;
+ int oldHeight = m_textureResource->m_height;
// Make the lower glyph texture size 16 x 16.
if (width < 16)
@@ -163,7 +156,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
if (height < 16)
height = 16;
- GLuint oldTexture = glyphTexture->m_texture;
+ GLuint oldTexture = m_textureResource->m_texture;
createTextureData(width, height);
if (ctx->d_ptr->workaround_brokenFBOReadBack) {
@@ -177,7 +170,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
// ### the QTextureGlyphCache API needs to be reworked to allow
// ### resizeTextureData to fail
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, glyphTexture->m_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_textureResource->m_fbo);
GLuint tmp_texture;
glGenTextures(1, &tmp_texture);
@@ -261,7 +254,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture);
+ glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
@@ -280,16 +273,16 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height)
void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition)
{
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
if (ctx == 0) {
qWarning("QGLTextureGlyphCache::fillTexture: Called with no context");
return;
}
- QGLGlyphTexture *glyphTexture = m_textureResource.value(ctx);
if (ctx->d_ptr->workaround_brokenFBOReadBack) {
QImageTextureGlyphCache::fillTexture(c, glyph, subPixelPosition);
- glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture);
+ glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
const QImage &texture = image();
const uchar *bits = texture.constBits();
bits += c.y * texture.bytesPerLine() + c.x;
@@ -326,7 +319,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub
}
}
- glBindTexture(GL_TEXTURE_2D, glyphTexture->m_texture);
+ glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
if (mask.format() == QImage::Format_RGB32) {
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
} else {
@@ -362,6 +355,7 @@ int QGLTextureGlyphCache::glyphPadding() const
int QGLTextureGlyphCache::maxTextureWidth() const
{
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
if (ctx == 0)
return QImageTextureGlyphCache::maxTextureWidth();
else
@@ -370,6 +364,7 @@ int QGLTextureGlyphCache::maxTextureWidth() const
int QGLTextureGlyphCache::maxTextureHeight() const
{
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
if (ctx == 0)
return QImageTextureGlyphCache::maxTextureHeight();
@@ -381,16 +376,15 @@ int QGLTextureGlyphCache::maxTextureHeight() const
void QGLTextureGlyphCache::clear()
{
- if (ctx != 0) {
- m_textureResource.cleanup(ctx);
-
- m_w = 0;
- m_h = 0;
- m_cx = 0;
- m_cy = 0;
- m_currentRowHeight = 0;
- coords.clear();
- }
+ m_textureResource->free();
+ m_textureResource = 0;
+
+ m_w = 0;
+ m_h = 0;
+ m_cx = 0;
+ m_cy = 0;
+ m_currentRowHeight = 0;
+ coords.clear();
}
QT_END_NAMESPACE
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
index 83ca06d040..7b7da9d8e8 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h
@@ -63,10 +63,11 @@ QT_BEGIN_NAMESPACE
class QGL2PaintEngineExPrivate;
-struct QGLGlyphTexture
+struct QGLGlyphTexture : public QOpenGLSharedResource
{
QGLGlyphTexture(const QGLContext *ctx)
- : m_width(0)
+ : QOpenGLSharedResource(ctx->contextHandle()->shareGroup())
+ , m_width(0)
, m_height(0)
{
if (ctx && !ctx->d_ptr->workaround_brokenFBOReadBack)
@@ -77,19 +78,24 @@ struct QGLGlyphTexture
#endif
}
- ~QGLGlyphTexture() {
- const QGLContext *ctx = QGLContext::currentContext();
+ void freeResource(QOpenGLContext *context)
+ {
+ const QGLContext *ctx = QGLContext::fromOpenGLContext(context);
#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
qDebug("~QGLGlyphTexture() %p for context %p.", this, ctx);
#endif
- // At this point, the context group is made current, so it's safe to
- // release resources without a makeCurrent() call
- if (ctx) {
- if (!ctx->d_ptr->workaround_brokenFBOReadBack)
- glDeleteFramebuffers(1, &m_fbo);
- if (m_width || m_height)
- glDeleteTextures(1, &m_texture);
- }
+ if (!ctx->d_ptr->workaround_brokenFBOReadBack)
+ glDeleteFramebuffers(1, &m_fbo);
+ if (m_width || m_height)
+ glDeleteTextures(1, &m_texture);
+ }
+
+ void invalidateResource()
+ {
+ m_texture = 0;
+ m_fbo = 0;
+ m_width = 0;
+ m_height = 0;
}
GLuint m_texture;
@@ -98,10 +104,10 @@ struct QGLGlyphTexture
int m_height;
};
-class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QImageTextureGlyphCache, public QGLContextGroupResourceBase
+class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QImageTextureGlyphCache
{
public:
- QGLTextureGlyphCache(const QGLContext *context, QFontEngineGlyphCache::Type type, const QTransform &matrix);
+ QGLTextureGlyphCache(QFontEngineGlyphCache::Type type, const QTransform &matrix);
~QGLTextureGlyphCache();
virtual void createTextureData(int width, int height);
@@ -113,25 +119,24 @@ public:
inline GLuint texture() const {
QGLTextureGlyphCache *that = const_cast<QGLTextureGlyphCache *>(this);
- QGLGlyphTexture *glyphTexture = that->m_textureResource.value(ctx);
+ QGLGlyphTexture *glyphTexture = that->m_textureResource;
return glyphTexture ? glyphTexture->m_texture : 0;
}
inline int width() const {
QGLTextureGlyphCache *that = const_cast<QGLTextureGlyphCache *>(this);
- QGLGlyphTexture *glyphTexture = that->m_textureResource.value(ctx);
+ QGLGlyphTexture *glyphTexture = that->m_textureResource;
return glyphTexture ? glyphTexture->m_width : 0;
}
inline int height() const {
QGLTextureGlyphCache *that = const_cast<QGLTextureGlyphCache *>(this);
- QGLGlyphTexture *glyphTexture = that->m_textureResource.value(ctx);
+ QGLGlyphTexture *glyphTexture = that->m_textureResource;
return glyphTexture ? glyphTexture->m_height : 0;
}
inline void setPaintEnginePrivate(QGL2PaintEngineExPrivate *p) { pex = p; }
- void setContext(const QGLContext *context);
- inline const QGLContext *context() const { return ctx; }
+ inline const QOpenGLContextGroup *contextGroup() const { return m_textureResource ? m_textureResource->group() : 0; }
inline int serialNumber() const { return m_serialNumber; }
@@ -144,12 +149,9 @@ public:
void clear();
- void freeResource(void *) { ctx = 0; }
-
private:
- QGLContextGroupResource<QGLGlyphTexture> m_textureResource;
+ QGLGlyphTexture *m_textureResource;
- const QGLContext *ctx;
QGL2PaintEngineExPrivate *pex;
QGLShaderProgram *m_blitProgram;
FilterMode m_filterMode;
diff --git a/src/opengl/gl2paintengineex/qtriangulator.cpp b/src/opengl/gl2paintengineex/qtriangulator.cpp
deleted file mode 100644
index d4b7131794..0000000000
--- a/src/opengl/gl2paintengineex/qtriangulator.cpp
+++ /dev/null
@@ -1,2612 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qtriangulator_p.h"
-
-#include <QtGui/qdialog.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qpainter.h>
-#include <QtGui/qpainterpath.h>
-#include <QtGui/private/qbezier_p.h>
-#include <QtGui/private/qdatabuffer_p.h>
-#include <QtCore/qbitarray.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qqueue.h>
-#include <QtCore/qglobal.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qalgorithms.h>
-
-#include <private/qgl_p.h>
-#include <private/qrbtree_p.h>
-
-#include <math.h>
-
-QT_BEGIN_NAMESPACE
-
-//#define Q_TRIANGULATOR_DEBUG
-
-#define Q_FIXED_POINT_SCALE 32
-
-// Quick sort.
-template <class T, class LessThan>
-#ifdef Q_CC_RVCT // RVCT 2.2 doesn't see recursive _static_ template function
-void sort(T *array, int count, LessThan lessThan)
-#else
-static void sort(T *array, int count, LessThan lessThan)
-#endif
-{
- // If the number of elements fall below some threshold, use insertion sort.
- const int INSERTION_SORT_LIMIT = 7; // About 7 is fastest on my computer...
- if (count <= INSERTION_SORT_LIMIT) {
- for (int i = 1; i < count; ++i) {
- T temp = array[i];
- int j = i;
- while (j > 0 && lessThan(temp, array[j - 1])) {
- array[j] = array[j - 1];
- --j;
- }
- array[j] = temp;
- }
- return;
- }
-
- int high = count - 1;
- int low = 0;
- int mid = high / 2;
- if (lessThan(array[mid], array[low]))
- qSwap(array[mid], array[low]);
- if (lessThan(array[high], array[mid]))
- qSwap(array[high], array[mid]);
- if (lessThan(array[mid], array[low]))
- qSwap(array[mid], array[low]);
-
- --high;
- ++low;
- qSwap(array[mid], array[high]);
- int pivot = high;
- --high;
-
- while (low <= high) {
- while (!lessThan(array[pivot], array[low])) {
- ++low;
- if (low > high)
- goto sort_loop_end;
- }
- while (!lessThan(array[high], array[pivot])) {
- --high;
- if (low > high)
- goto sort_loop_end;
- }
- qSwap(array[low], array[high]);
- ++low;
- --high;
- }
-sort_loop_end:
- if (low != pivot)
- qSwap(array[pivot], array[low]);
- sort(array, low, lessThan);
- sort(array + low + 1, count - low - 1, lessThan);
-}
-
-// Quick sort.
-template <class T>
-#ifdef Q_CC_RVCT
-void sort(T *array, int count) // RVCT 2.2 doesn't see recursive _static_ template function
-#else
-static void sort(T *array, int count)
-#endif
-{
- // If the number of elements fall below some threshold, use insertion sort.
- const int INSERTION_SORT_LIMIT = 25; // About 25 is fastest on my computer...
- if (count <= INSERTION_SORT_LIMIT) {
- for (int i = 1; i < count; ++i) {
- T temp = array[i];
- int j = i;
- while (j > 0 && (temp < array[j - 1])) {
- array[j] = array[j - 1];
- --j;
- }
- array[j] = temp;
- }
- return;
- }
-
- int high = count - 1;
- int low = 0;
- int mid = high / 2;
- if ((array[mid] < array[low]))
- qSwap(array[mid], array[low]);
- if ((array[high] < array[mid]))
- qSwap(array[high], array[mid]);
- if ((array[mid] < array[low]))
- qSwap(array[mid], array[low]);
-
- --high;
- ++low;
- qSwap(array[mid], array[high]);
- int pivot = high;
- --high;
-
- while (low <= high) {
- while (!(array[pivot] < array[low])) {
- ++low;
- if (low > high)
- goto sort_loop_end;
- }
- while (!(array[high] < array[pivot])) {
- --high;
- if (low > high)
- goto sort_loop_end;
- }
- qSwap(array[low], array[high]);
- ++low;
- --high;
- }
-sort_loop_end:
- if (low != pivot)
- qSwap(array[pivot], array[low]);
- sort(array, low);
- sort(array + low + 1, count - low - 1);
-}
-
-template<typename T>
-struct QVertexSet
-{
- inline QVertexSet() { }
- inline QVertexSet(const QVertexSet<T> &other) : vertices(other.vertices), indices(other.indices) { }
- QVertexSet<T> &operator = (const QVertexSet<T> &other) {vertices = other.vertices; indices = other.indices; return *this;}
-
- // The vertices of a triangle are given by: (x[i[n]], y[i[n]]), (x[j[n]], y[j[n]]), (x[k[n]], y[k[n]]), n = 0, 1, ...
- QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
- QVector<T> indices; // [i[0], j[0], k[0], i[1], j[1], k[1], i[2], ...]
-};
-
-//============================================================================//
-// QFraction //
-//============================================================================//
-
-// Fraction must be in the range [0, 1)
-struct QFraction
-{
- // Comparison operators must not be called on invalid fractions.
- inline bool operator < (const QFraction &other) const;
- inline bool operator == (const QFraction &other) const;
- inline bool operator != (const QFraction &other) const {return !(*this == other);}
- inline bool operator > (const QFraction &other) const {return other < *this;}
- inline bool operator >= (const QFraction &other) const {return !(*this < other);}
- inline bool operator <= (const QFraction &other) const {return !(*this > other);}
-
- inline bool isValid() const {return denominator != 0;}
-
- // numerator and denominator must not have common denominators.
- quint64 numerator, denominator;
-};
-
-static inline quint64 gcd(quint64 x, quint64 y)
-{
- while (y != 0) {
- quint64 z = y;
- y = x % y;
- x = z;
- }
- return x;
-}
-
-static inline int compare(quint64 a, quint64 b)
-{
- return (a > b) - (a < b);
-}
-
-// Compare a/b with c/d.
-// Return negative if less, 0 if equal, positive if greater.
-// a < b, c < d
-static int qCompareFractions(quint64 a, quint64 b, quint64 c, quint64 d)
-{
- const quint64 LIMIT = Q_UINT64_C(0x100000000);
- for (;;) {
- // If the products 'ad' and 'bc' fit into 64 bits, they can be directly compared.
- if (b < LIMIT && d < LIMIT)
- return compare(a * d, b * c);
-
- if (a == 0 || c == 0)
- return compare(a, c);
-
- // a/b < c/d <=> d/c < b/a
- quint64 b_div_a = b / a;
- quint64 d_div_c = d / c;
- if (b_div_a != d_div_c)
- return compare(d_div_c, b_div_a);
-
- // floor(d/c) == floor(b/a)
- // frac(d/c) < frac(b/a) ?
- // frac(x/y) = (x%y)/y
- d -= d_div_c * c; //d %= c;
- b -= b_div_a * a; //b %= a;
- qSwap(a, d);
- qSwap(b, c);
- }
-}
-
-// Fraction must be in the range [0, 1)
-// Assume input is valid.
-static QFraction qFraction(quint64 n, quint64 d) {
- QFraction result;
- if (n == 0) {
- result.numerator = 0;
- result.denominator = 1;
- } else {
- quint64 g = gcd(n, d);
- result.numerator = n / g;
- result.denominator = d / g;
- }
- return result;
-}
-
-inline bool QFraction::operator < (const QFraction &other) const
-{
- return qCompareFractions(numerator, denominator, other.numerator, other.denominator) < 0;
-}
-
-inline bool QFraction::operator == (const QFraction &other) const
-{
- return numerator == other.numerator && denominator == other.denominator;
-}
-
-//============================================================================//
-// QPodPoint //
-//============================================================================//
-
-struct QPodPoint
-{
- inline bool operator < (const QPodPoint &other) const
- {
- if (y != other.y)
- return y < other.y;
- return x < other.x;
- }
-
- inline bool operator > (const QPodPoint &other) const {return other < *this;}
- inline bool operator <= (const QPodPoint &other) const {return !(*this > other);}
- inline bool operator >= (const QPodPoint &other) const {return !(*this < other);}
- inline bool operator == (const QPodPoint &other) const {return x == other.x && y == other.y;}
- inline bool operator != (const QPodPoint &other) const {return x != other.x || y != other.y;}
-
- inline QPodPoint &operator += (const QPodPoint &other) {x += other.x; y += other.y; return *this;}
- inline QPodPoint &operator -= (const QPodPoint &other) {x -= other.x; y -= other.y; return *this;}
- inline QPodPoint operator + (const QPodPoint &other) const {QPodPoint result = {x + other.x, y + other.y}; return result;}
- inline QPodPoint operator - (const QPodPoint &other) const {QPodPoint result = {x - other.x, y - other.y}; return result;}
-
- int x;
- int y;
-};
-
-static inline qint64 qCross(const QPodPoint &u, const QPodPoint &v)
-{
- return qint64(u.x) * qint64(v.y) - qint64(u.y) * qint64(v.x);
-}
-
-static inline qint64 qDot(const QPodPoint &u, const QPodPoint &v)
-{
- return qint64(u.x) * qint64(v.x) + qint64(u.y) * qint64(v.y);
-}
-
-// Return positive value if 'p' is to the right of the line 'v1'->'v2', negative if left of the
-// line and zero if exactly on the line.
-// The returned value is the z-component of the qCross product between 'v2-v1' and 'p-v1',
-// which is twice the signed area of the triangle 'p'->'v1'->'v2' (positive for CW order).
-static inline qint64 qPointDistanceFromLine(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2)
-{
- return qCross(v2 - v1, p - v1);
-}
-
-static inline bool qPointIsLeftOfLine(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2)
-{
- return QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(p, v1, v2) < 0;
-}
-
-// Return:
-// -1 if u < v
-// 0 if u == v
-// 1 if u > v
-static int comparePoints(const QPodPoint &u, const QPodPoint &v)
-{
- if (u.y < v.y)
- return -1;
- if (u.y > v.y)
- return 1;
- if (u.x < v.x)
- return -1;
- if (u.x > v.x)
- return 1;
- return 0;
-}
-
-//============================================================================//
-// QIntersectionPoint //
-//============================================================================//
-
-struct QIntersectionPoint
-{
- inline bool isValid() const {return xOffset.isValid() && yOffset.isValid();}
- QPodPoint round() const;
- inline bool isAccurate() const {return xOffset.numerator == 0 && yOffset.numerator == 0;}
- bool operator < (const QIntersectionPoint &other) const;
- bool operator == (const QIntersectionPoint &other) const;
- inline bool operator != (const QIntersectionPoint &other) const {return !(*this == other);}
- inline bool operator > (const QIntersectionPoint &other) const {return other < *this;}
- inline bool operator >= (const QIntersectionPoint &other) const {return !(*this < other);}
- inline bool operator <= (const QIntersectionPoint &other) const {return !(*this > other);}
- bool isOnLine(const QPodPoint &u, const QPodPoint &v) const;
-
- QPodPoint upperLeft;
- QFraction xOffset;
- QFraction yOffset;
-};
-
-static inline QIntersectionPoint qIntersectionPoint(const QPodPoint &point)
-{
- // upperLeft = point, xOffset = 0/1, yOffset = 0/1.
- QIntersectionPoint p = {{point.x, point.y}, {0, 1}, {0, 1}};
- return p;
-}
-
-static inline QIntersectionPoint qIntersectionPoint(int x, int y)
-{
- // upperLeft = (x, y), xOffset = 0/1, yOffset = 0/1.
- QIntersectionPoint p = {{x, y}, {0, 1}, {0, 1}};
- return p;
-}
-
-static QIntersectionPoint qIntersectionPoint(const QPodPoint &u1, const QPodPoint &u2, const QPodPoint &v1, const QPodPoint &v2)
-{
- QIntersectionPoint result = {{0, 0}, {0, 0}, {0, 0}};
-
- QPodPoint u = u2 - u1;
- QPodPoint v = v2 - v1;
- qint64 d1 = qCross(u, v1 - u1);
- qint64 d2 = qCross(u, v2 - u1);
- qint64 det = d2 - d1;
- qint64 d3 = qCross(v, u1 - v1);
- qint64 d4 = d3 - det; //qCross(v, u2 - v1);
-
- // Check that the math is correct.
- Q_ASSERT(d4 == qCross(v, u2 - v1));
-
- // The intersection point can be expressed as:
- // v1 - v * d1/det
- // v2 - v * d2/det
- // u1 + u * d3/det
- // u2 + u * d4/det
-
- // I'm only interested in lines that are crossing, so ignore parallel lines even if they overlap.
- if (det == 0)
- return result;
-
- if (det < 0) {
- det = -det;
- d1 = -d1;
- d2 = -d2;
- d3 = -d3;
- d4 = -d4;
- }
-
- // I'm only interested in lines intersecting at their interior, not at their end points.
- // The lines intersect at their interior if and only if 'd1 < 0', 'd2 > 0', 'd3 < 0' and 'd4 > 0'.
- if (d1 >= 0 || d2 <= 0 || d3 <= 0 || d4 >= 0)
- return result;
-
- // Calculate the intersection point as follows:
- // v1 - v * d1/det | v1 <= v2 (component-wise)
- // v2 - v * d2/det | v2 < v1 (component-wise)
-
- // Assuming 21 bits per vector component.
- // TODO: Make code path for 31 bits per vector component.
- if (v.x >= 0) {
- result.upperLeft.x = v1.x + (-v.x * d1) / det;
- result.xOffset = qFraction(quint64(-v.x * d1) % quint64(det), quint64(det));
- } else {
- result.upperLeft.x = v2.x + (-v.x * d2) / det;
- result.xOffset = qFraction(quint64(-v.x * d2) % quint64(det), quint64(det));
- }
-
- if (v.y >= 0) {
- result.upperLeft.y = v1.y + (-v.y * d1) / det;
- result.yOffset = qFraction(quint64(-v.y * d1) % quint64(det), quint64(det));
- } else {
- result.upperLeft.y = v2.y + (-v.y * d2) / det;
- result.yOffset = qFraction(quint64(-v.y * d2) % quint64(det), quint64(det));
- }
-
- Q_ASSERT(result.xOffset.isValid());
- Q_ASSERT(result.yOffset.isValid());
- return result;
-}
-
-QPodPoint QIntersectionPoint::round() const
-{
- QPodPoint result = upperLeft;
- if (2 * xOffset.numerator >= xOffset.denominator)
- ++result.x;
- if (2 * yOffset.numerator >= yOffset.denominator)
- ++result.y;
- return result;
-}
-
-bool QIntersectionPoint::operator < (const QIntersectionPoint &other) const
-{
- if (upperLeft.y != other.upperLeft.y)
- return upperLeft.y < other.upperLeft.y;
- if (yOffset != other.yOffset)
- return yOffset < other.yOffset;
- if (upperLeft.x != other.upperLeft.x)
- return upperLeft.x < other.upperLeft.x;
- return xOffset < other.xOffset;
-}
-
-bool QIntersectionPoint::operator == (const QIntersectionPoint &other) const
-{
- return upperLeft == other.upperLeft && xOffset == other.xOffset && yOffset == other.yOffset;
-}
-
-// Returns true if this point is on the infinite line passing through 'u' and 'v'.
-bool QIntersectionPoint::isOnLine(const QPodPoint &u, const QPodPoint &v) const
-{
- // TODO: Make code path for coordinates with more than 21 bits.
- const QPodPoint p = upperLeft - u;
- const QPodPoint q = v - u;
- bool isHorizontal = p.y == 0 && yOffset.numerator == 0;
- bool isVertical = p.x == 0 && xOffset.numerator == 0;
- if (isHorizontal && isVertical)
- return true;
- if (isHorizontal)
- return q.y == 0;
- if (q.y == 0)
- return false;
- if (isVertical)
- return q.x == 0;
- if (q.x == 0)
- return false;
-
- // At this point, 'p+offset' and 'q' cannot lie on the x or y axis.
-
- if (((q.x < 0) == (q.y < 0)) != ((p.x < 0) == (p.y < 0)))
- return false; // 'p + offset' and 'q' pass through different quadrants.
-
- // Move all coordinates into the first quadrant.
- quint64 nx, ny;
- if (p.x < 0)
- nx = quint64(-p.x) * xOffset.denominator - xOffset.numerator;
- else
- nx = quint64(p.x) * xOffset.denominator + xOffset.numerator;
- if (p.y < 0)
- ny = quint64(-p.y) * yOffset.denominator - yOffset.numerator;
- else
- ny = quint64(p.y) * yOffset.denominator + yOffset.numerator;
-
- return qFraction(quint64(qAbs(q.x)) * xOffset.denominator, quint64(qAbs(q.y)) * yOffset.denominator) == qFraction(nx, ny);
-}
-
-//============================================================================//
-// QMaxHeap //
-//============================================================================//
-
-template <class T>
-class QMaxHeap
-{
-public:
- QMaxHeap() : m_data(0) {}
- inline int size() const {return m_data.size();}
- inline bool empty() const {return m_data.isEmpty();}
- inline bool isEmpty() const {return m_data.isEmpty();}
- void push(const T &x);
- T pop();
- inline const T &top() const {return m_data.first();}
-private:
- static inline int parent(int i) {return (i - 1) / 2;}
- static inline int left(int i) {return 2 * i + 1;}
- static inline int right(int i) {return 2 * i + 2;}
-
- QDataBuffer<T> m_data;
-};
-
-template <class T>
-void QMaxHeap<T>::push(const T &x)
-{
- int current = m_data.size();
- int parent = QMaxHeap::parent(current);
- m_data.add(x);
- while (current != 0 && m_data.at(parent) < x) {
- m_data.at(current) = m_data.at(parent);
- current = parent;
- parent = QMaxHeap::parent(current);
- }
- m_data.at(current) = x;
-}
-
-template <class T>
-T QMaxHeap<T>::pop()
-{
- T result = m_data.first();
- T back = m_data.last();
- m_data.pop_back();
- if (!m_data.isEmpty()) {
- int current = 0;
- for (;;) {
- int left = QMaxHeap::left(current);
- int right = QMaxHeap::right(current);
- if (left >= m_data.size())
- break;
- int greater = left;
- if (right < m_data.size() && m_data.at(left) < m_data.at(right))
- greater = right;
- if (m_data.at(greater) < back)
- break;
- m_data.at(current) = m_data.at(greater);
- current = greater;
- }
- m_data.at(current) = back;
- }
- return result;
-}
-
-//============================================================================//
-// QInt64Hash //
-//============================================================================//
-
-// Copied from qhash.cpp
-static const uchar prime_deltas[] = {
- 0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3,
- 1, 21, 3, 21, 7, 15, 9, 5, 3, 29, 15, 0, 0, 0, 0, 0
-};
-
-// Copied from qhash.cpp
-static inline int primeForNumBits(int numBits)
-{
- return (1 << numBits) + prime_deltas[numBits];
-}
-
-static inline int primeForCount(int count)
-{
- int low = 0;
- int high = 32;
- for (int i = 0; i < 5; ++i) {
- int mid = (high + low) / 2;
- if (count >= 1 << mid)
- low = mid;
- else
- high = mid;
- }
- return primeForNumBits(high);
-}
-
-// Hash set of quint64s. Elements cannot be removed without clearing the
-// entire set. A value of -1 is used to mark unused entries.
-class QInt64Set
-{
-public:
- inline QInt64Set(int capacity = 64);
- inline ~QInt64Set() {if (m_array) delete[] m_array;}
- inline bool isValid() const {return m_array;}
- void insert(quint64 key);
- bool contains(quint64 key) const;
- inline void clear();
-private:
- bool rehash(int capacity);
-
- static const quint64 UNUSED;
-
- quint64 *m_array;
- int m_capacity;
- int m_count;
-};
-
-const quint64 QInt64Set::UNUSED = quint64(-1);
-
-inline QInt64Set::QInt64Set(int capacity)
-{
- m_capacity = primeForCount(capacity);
- m_array = new quint64[m_capacity];
- if (m_array)
- clear();
- else
- m_capacity = 0;
-}
-
-bool QInt64Set::rehash(int capacity)
-{
- quint64 *oldArray = m_array;
- int oldCapacity = m_capacity;
-
- m_capacity = capacity;
- m_array = new quint64[m_capacity];
- if (m_array) {
- clear();
- if (oldArray) {
- for (int i = 0; i < oldCapacity; ++i) {
- if (oldArray[i] != UNUSED)
- insert(oldArray[i]);
- }
- delete[] oldArray;
- }
- return true;
- } else {
- m_capacity = oldCapacity;
- m_array = oldArray;
- return false;
- }
-}
-
-void QInt64Set::insert(quint64 key)
-{
- if (m_count > 3 * m_capacity / 4)
- rehash(primeForCount(2 * m_capacity));
- Q_ASSERT_X(m_array, "QInt64Hash<T>::insert", "Hash set not allocated.");
- int index = int(key % m_capacity);
- for (int i = 0; i < m_capacity; ++i) {
- index += i;
- if (index >= m_capacity)
- index -= m_capacity;
- if (m_array[index] == key)
- return;
- if (m_array[index] == UNUSED) {
- ++m_count;
- m_array[index] = key;
- return;
- }
- }
- Q_ASSERT_X(0, "QInt64Hash<T>::insert", "Hash set full.");
-}
-
-bool QInt64Set::contains(quint64 key) const
-{
- Q_ASSERT_X(m_array, "QInt64Hash<T>::contains", "Hash set not allocated.");
- int index = int(key % m_capacity);
- for (int i = 0; i < m_capacity; ++i) {
- index += i;
- if (index >= m_capacity)
- index -= m_capacity;
- if (m_array[index] == key)
- return true;
- if (m_array[index] == UNUSED)
- return false;
- }
- return false;
-}
-
-inline void QInt64Set::clear()
-{
- Q_ASSERT_X(m_array, "QInt64Hash<T>::clear", "Hash set not allocated.");
- for (int i = 0; i < m_capacity; ++i)
- m_array[i] = UNUSED;
- m_count = 0;
-}
-
-//============================================================================//
-// QRingBuffer //
-//============================================================================//
-
-// T must be POD.
-template <class T>
-class QRingBuffer
-{
-public:
- inline QRingBuffer() : m_array(0), m_head(0), m_size(0), m_capacity(0) { }
- inline ~QRingBuffer() {if (m_array) delete[] m_array;}
- bool reallocate(int capacity);
- inline const T &head() const {Q_ASSERT(m_size > 0); return m_array[m_head];}
- inline const T &dequeue();
- inline void enqueue(const T &x);
- inline bool isEmpty() const {return m_size == 0;}
-private:
- T *m_array;
- int m_head;
- int m_size;
- int m_capacity;
-};
-
-template <class T>
-bool QRingBuffer<T>::reallocate(int capacity)
-{
- T *oldArray = m_array;
- m_array = new T[capacity];
- if (m_array) {
- if (oldArray) {
- if (m_head + m_size > m_capacity) {
- memcpy(m_array, oldArray + m_head, (m_capacity - m_head) * sizeof(T));
- memcpy(m_array + (m_capacity - m_head), oldArray, (m_head + m_size - m_capacity) * sizeof(T));
- } else {
- memcpy(m_array, oldArray + m_head, m_size * sizeof(T));
- }
- delete[] oldArray;
- }
- m_capacity = capacity;
- m_head = 0;
- return true;
- } else {
- m_array = oldArray;
- return false;
- }
-}
-
-template <class T>
-inline const T &QRingBuffer<T>::dequeue()
-{
- Q_ASSERT(m_size > 0);
- Q_ASSERT(m_array);
- Q_ASSERT(m_capacity >= m_size);
- int index = m_head;
- if (++m_head >= m_capacity)
- m_head -= m_capacity;
- --m_size;
- return m_array[index];
-}
-
-template <class T>
-inline void QRingBuffer<T>::enqueue(const T &x)
-{
- if (m_size == m_capacity)
- reallocate(qMax(2 * m_capacity, 64));
- int index = m_head + m_size;
- if (index >= m_capacity)
- index -= m_capacity;
- m_array[index] = x;
- ++m_size;
-}
-
-//============================================================================//
-// QTriangulator //
-//============================================================================//
-template<typename T>
-class QTriangulator
-{
-public:
- typedef QVarLengthArray<int, 6> ShortArray;
-
- //================================//
- // QTriangulator::ComplexToSimple //
- //================================//
- friend class ComplexToSimple;
- class ComplexToSimple
- {
- public:
- inline ComplexToSimple(QTriangulator<T> *parent) : m_parent(parent),
- m_edges(0), m_events(0), m_splits(0) { }
- void decompose();
- private:
- struct Edge
- {
- inline int &upper() {return pointingUp ? to : from;}
- inline int &lower() {return pointingUp ? from : to;}
- inline int upper() const {return pointingUp ? to : from;}
- inline int lower() const {return pointingUp ? from : to;}
-
- QRBTree<int>::Node *node;
- int from, to; // vertex
- int next, previous; // edge
- int winding;
- bool mayIntersect;
- bool pointingUp, originallyPointingUp;
- };
-
- friend class CompareEdges;
- class CompareEdges
- {
- public:
- inline CompareEdges(ComplexToSimple *parent) : m_parent(parent) { }
- bool operator () (int i, int j) const;
- private:
- ComplexToSimple *m_parent;
- };
-
- struct Intersection
- {
- bool operator < (const Intersection &other) const {return other.intersectionPoint < intersectionPoint;}
-
- QIntersectionPoint intersectionPoint;
- int vertex;
- int leftEdge;
- int rightEdge;
- };
-
- struct Split
- {
- int vertex;
- int edge;
- bool accurate;
- };
-
- struct Event
- {
- enum Type {Upper, Lower};
- inline bool operator < (const Event &other) const;
-
- QPodPoint point;
- Type type;
- int edge;
- };
-
-#ifdef Q_TRIANGULATOR_DEBUG
- friend class DebugDialog;
- friend class QTriangulator;
- class DebugDialog : public QDialog
- {
- public:
- DebugDialog(ComplexToSimple *parent, int currentVertex);
- protected:
- void paintEvent(QPaintEvent *);
- void wheelEvent(QWheelEvent *);
- void mouseMoveEvent(QMouseEvent *);
- void mousePressEvent(QMouseEvent *);
- private:
- ComplexToSimple *m_parent;
- QRectF m_window;
- QPoint m_lastMousePos;
- int m_vertex;
- };
-#endif
-
- void initEdges();
- bool calculateIntersection(int left, int right);
- bool edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const;
- QRBTree<int>::Node *searchEdgeLeftOf(int edgeIndex) const;
- QRBTree<int>::Node *searchEdgeLeftOf(int edgeIndex, QRBTree<int>::Node *after) const;
- QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> bounds(const QPodPoint &point) const;
- QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> outerBounds(const QPodPoint &point) const;
- void splitEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost, int vertex, const QIntersectionPoint &intersectionPoint);
- void reorderEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost);
- void sortEdgeList(const QPodPoint eventPoint);
- void fillPriorityQueue();
- void calculateIntersections();
- int splitEdge(int splitIndex);
- bool splitEdgesAtIntersections();
- void insertEdgeIntoVectorIfWanted(ShortArray &orderedEdges, int i);
- void removeUnwantedEdgesAndConnect();
- void removeUnusedPoints();
-
- QTriangulator *m_parent;
- QDataBuffer<Edge> m_edges;
- QRBTree<int> m_edgeList;
- QDataBuffer<Event> m_events;
- QDataBuffer<Split> m_splits;
- QMaxHeap<Intersection> m_topIntersection;
- QInt64Set m_processedEdgePairs;
- int m_initialPointCount;
- };
-#ifdef Q_TRIANGULATOR_DEBUG
- friend class ComplexToSimple::DebugDialog;
-#endif
-
- //=================================//
- // QTriangulator::SimpleToMonotone //
- //=================================//
- friend class SimpleToMonotone;
- class SimpleToMonotone
- {
- public:
- inline SimpleToMonotone(QTriangulator<T> *parent) : m_parent(parent), m_edges(0), m_upperVertex(0) { }
- void decompose();
- private:
- enum VertexType {MergeVertex, EndVertex, RegularVertex, StartVertex, SplitVertex};
-
- struct Edge
- {
- QRBTree<int>::Node *node;
- int helper, twin, next, previous;
- T from, to;
- VertexType type;
- bool pointingUp;
- int upper() const {return (pointingUp ? to : from);}
- int lower() const {return (pointingUp ? from : to);}
- };
-
- friend class CompareVertices;
- class CompareVertices
- {
- public:
- CompareVertices(SimpleToMonotone *parent) : m_parent(parent) { }
- bool operator () (int i, int j) const;
- private:
- SimpleToMonotone *m_parent;
- };
-
- void setupDataStructures();
- void removeZeroLengthEdges();
- void fillPriorityQueue();
- bool edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const;
- // Returns the rightmost edge not to the right of the given edge.
- QRBTree<int>::Node *searchEdgeLeftOfEdge(int edgeIndex) const;
- // Returns the rightmost edge left of the given point.
- QRBTree<int>::Node *searchEdgeLeftOfPoint(int pointIndex) const;
- void classifyVertex(int i);
- void classifyVertices();
- bool pointIsInSector(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2, const QPodPoint &v3);
- bool pointIsInSector(int vertex, int sector);
- int findSector(int edge, int vertex);
- void createDiagonal(int lower, int upper);
- void monotoneDecomposition();
-
- QTriangulator *m_parent;
- QRBTree<int> m_edgeList;
- QDataBuffer<Edge> m_edges;
- QDataBuffer<int> m_upperVertex;
- bool m_clockwiseOrder;
- };
-
- //====================================//
- // QTriangulator::MonotoneToTriangles //
- //====================================//
- friend class MonotoneToTriangles;
- class MonotoneToTriangles
- {
- public:
- inline MonotoneToTriangles(QTriangulator<T> *parent) : m_parent(parent) { }
- void decompose();
- private:
- inline T indices(int index) const {return m_parent->m_indices.at(index + m_first);}
- inline int next(int index) const {return (index + 1) % m_length;}
- inline int previous(int index) const {return (index + m_length - 1) % m_length;}
- inline bool less(int i, int j) const {return m_parent->m_vertices.at((qint32)indices(i)) < m_parent->m_vertices.at(indices(j));}
- inline bool leftOfEdge(int i, int j, int k) const
- {
- return qPointIsLeftOfLine(m_parent->m_vertices.at((qint32)indices(i)),
- m_parent->m_vertices.at((qint32)indices(j)), m_parent->m_vertices.at((qint32)indices(k)));
- }
-
- QTriangulator<T> *m_parent;
- int m_first;
- int m_length;
- };
-
- inline QTriangulator() : m_vertices(0) { }
-
- // Call this only once.
- void initialize(const qreal *polygon, int count, uint hint, const QTransform &matrix);
- // Call this only once.
- void initialize(const QVectorPath &path, const QTransform &matrix, qreal lod);
- // Call this only once.
- void initialize(const QPainterPath &path, const QTransform &matrix, qreal lod);
- // Call either triangulate() or polyline() only once.
- QVertexSet<T> triangulate();
- QVertexSet<T> polyline();
-private:
- QDataBuffer<QPodPoint> m_vertices;
- QVector<T> m_indices;
- uint m_hint;
-};
-
-//============================================================================//
-// QTriangulator //
-//============================================================================//
-
-template <typename T>
-QVertexSet<T> QTriangulator<T>::triangulate()
-{
- for (int i = 0; i < m_vertices.size(); ++i) {
- Q_ASSERT(qAbs(m_vertices.at(i).x) < (1 << 21));
- Q_ASSERT(qAbs(m_vertices.at(i).y) < (1 << 21));
- }
-
- if (!(m_hint & (QVectorPath::OddEvenFill | QVectorPath::WindingFill)))
- m_hint |= QVectorPath::OddEvenFill;
-
- if (m_hint & QVectorPath::NonConvexShapeMask) {
- ComplexToSimple c2s(this);
- c2s.decompose();
- SimpleToMonotone s2m(this);
- s2m.decompose();
- }
- MonotoneToTriangles m2t(this);
- m2t.decompose();
-
- QVertexSet<T> result;
- result.indices = m_indices;
- result.vertices.resize(2 * m_vertices.size());
- for (int i = 0; i < m_vertices.size(); ++i) {
- result.vertices[2 * i + 0] = qreal(m_vertices.at(i).x) / Q_FIXED_POINT_SCALE;
- result.vertices[2 * i + 1] = qreal(m_vertices.at(i).y) / Q_FIXED_POINT_SCALE;
- }
- return result;
-}
-
-template <typename T>
-QVertexSet<T> QTriangulator<T>::polyline()
-{
- for (int i = 0; i < m_vertices.size(); ++i) {
- Q_ASSERT(qAbs(m_vertices.at(i).x) < (1 << 21));
- Q_ASSERT(qAbs(m_vertices.at(i).y) < (1 << 21));
- }
-
- if (!(m_hint & (QVectorPath::OddEvenFill | QVectorPath::WindingFill)))
- m_hint |= QVectorPath::OddEvenFill;
-
- if (m_hint & QVectorPath::NonConvexShapeMask) {
- ComplexToSimple c2s(this);
- c2s.decompose();
- }
-
- QVertexSet<T> result;
- result.indices = m_indices;
- result.vertices.resize(2 * m_vertices.size());
- for (int i = 0; i < m_vertices.size(); ++i) {
- result.vertices[2 * i + 0] = qreal(m_vertices.at(i).x) / Q_FIXED_POINT_SCALE;
- result.vertices[2 * i + 1] = qreal(m_vertices.at(i).y) / Q_FIXED_POINT_SCALE;
- }
- return result;
-}
-
-template <typename T>
-void QTriangulator<T>::initialize(const qreal *polygon, int count, uint hint, const QTransform &matrix)
-{
- m_hint = hint;
- m_vertices.resize(count);
- m_indices.resize(count + 1);
- for (int i = 0; i < count; ++i) {
- qreal x, y;
- matrix.map(polygon[2 * i + 0], polygon[2 * i + 1], &x, &y);
- m_vertices.at(i).x = qRound(x * Q_FIXED_POINT_SCALE);
- m_vertices.at(i).y = qRound(y * Q_FIXED_POINT_SCALE);
- m_indices[i] = i;
- }
- m_indices[count] = T(-1); //Q_TRIANGULATE_END_OF_POLYGON
-}
-
-template <typename T>
-void QTriangulator<T>::initialize(const QVectorPath &path, const QTransform &matrix, qreal lod)
-{
- m_hint = path.hints();
- // Curved paths will be converted to complex polygons.
- m_hint &= ~QVectorPath::CurvedShapeMask;
-
- const qreal *p = path.points();
- const QPainterPath::ElementType *e = path.elements();
- if (e) {
- for (int i = 0; i < path.elementCount(); ++i, ++e, p += 2) {
- switch (*e) {
- case QPainterPath::MoveToElement:
- if (!m_indices.isEmpty())
- m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
- // Fall through.
- case QPainterPath::LineToElement:
- m_indices.push_back(T(m_vertices.size()));
- m_vertices.resize(m_vertices.size() + 1);
- qreal x, y;
- matrix.map(p[0], p[1], &x, &y);
- m_vertices.last().x = qRound(x * Q_FIXED_POINT_SCALE);
- m_vertices.last().y = qRound(y * Q_FIXED_POINT_SCALE);
- break;
- case QPainterPath::CurveToElement:
- {
- qreal pts[8];
- for (int i = 0; i < 4; ++i)
- matrix.map(p[2 * i - 2], p[2 * i - 1], &pts[2 * i + 0], &pts[2 * i + 1]);
- for (int i = 0; i < 8; ++i)
- pts[i] *= lod;
- QBezier bezier = QBezier::fromPoints(QPointF(pts[0], pts[1]), QPointF(pts[2], pts[3]), QPointF(pts[4], pts[5]), QPointF(pts[6], pts[7]));
- QPolygonF poly = bezier.toPolygon();
- // Skip first point, it already exists in 'm_vertices'.
- for (int j = 1; j < poly.size(); ++j) {
- m_indices.push_back(T(m_vertices.size()));
- m_vertices.resize(m_vertices.size() + 1);
- m_vertices.last().x = qRound(poly.at(j).x() * Q_FIXED_POINT_SCALE / lod);
- m_vertices.last().y = qRound(poly.at(j).y() * Q_FIXED_POINT_SCALE / lod);
- }
- }
- i += 2;
- e += 2;
- p += 4;
- break;
- default:
- Q_ASSERT_X(0, "QTriangulator::triangulate", "Unexpected element type.");
- break;
- }
- }
- } else {
- for (int i = 0; i < path.elementCount(); ++i, p += 2) {
- m_indices.push_back(T(m_vertices.size()));
- m_vertices.resize(m_vertices.size() + 1);
- qreal x, y;
- matrix.map(p[0], p[1], &x, &y);
- m_vertices.last().x = qRound(x * Q_FIXED_POINT_SCALE);
- m_vertices.last().y = qRound(y * Q_FIXED_POINT_SCALE);
- }
- }
- m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
-}
-
-template <typename T>
-void QTriangulator<T>::initialize(const QPainterPath &path, const QTransform &matrix, qreal lod)
-{
- initialize(qtVectorPathForPath(path), matrix, lod);
-}
-
-//============================================================================//
-// QTriangulator::ComplexToSimple //
-//============================================================================//
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::decompose()
-{
- m_initialPointCount = m_parent->m_vertices.size();
- initEdges();
- do {
- calculateIntersections();
- } while (splitEdgesAtIntersections());
-
- removeUnwantedEdgesAndConnect();
- removeUnusedPoints();
-
- m_parent->m_indices.clear();
- QBitArray processed(m_edges.size(), false);
- for (int first = 0; first < m_edges.size(); ++first) {
- // If already processed, or if unused path, skip.
- if (processed.at(first) || m_edges.at(first).next == -1)
- continue;
-
- int i = first;
- do {
- Q_ASSERT(!processed.at(i));
- Q_ASSERT(m_edges.at(m_edges.at(i).next).previous == i);
- m_parent->m_indices.push_back(m_edges.at(i).from);
- processed.setBit(i);
- i = m_edges.at(i).next; // CCW order
- } while (i != first);
- m_parent->m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
- }
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::initEdges()
-{
- // Initialize edge structure.
- // 'next' and 'previous' are not being initialized at this point.
- int first = 0;
- for (int i = 0; i < m_parent->m_indices.size(); ++i) {
- if (m_parent->m_indices.at(i) == T(-1)) { // Q_TRIANGULATE_END_OF_POLYGON
- if (m_edges.size() != first)
- m_edges.last().to = m_edges.at(first).from;
- first = m_edges.size();
- } else {
- Q_ASSERT(i + 1 < m_parent->m_indices.size());
- // {node, from, to, next, previous, winding, mayIntersect, pointingUp, originallyPointingUp}
- Edge edge = {0, m_parent->m_indices.at(i), m_parent->m_indices.at(i + 1), -1, -1, 0, true, false, false};
- m_edges.add(edge);
- }
- }
- if (first != m_edges.size())
- m_edges.last().to = m_edges.at(first).from;
- for (int i = 0; i < m_edges.size(); ++i) {
- m_edges.at(i).originallyPointingUp = m_edges.at(i).pointingUp =
- m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
- }
-}
-
-// Return true if new intersection was found
-template <typename T>
-bool QTriangulator<T>::ComplexToSimple::calculateIntersection(int left, int right)
-{
- const Edge &e1 = m_edges.at(left);
- const Edge &e2 = m_edges.at(right);
-
- const QPodPoint &u1 = m_parent->m_vertices.at((qint32)e1.from);
- const QPodPoint &u2 = m_parent->m_vertices.at((qint32)e1.to);
- const QPodPoint &v1 = m_parent->m_vertices.at((qint32)e2.from);
- const QPodPoint &v2 = m_parent->m_vertices.at((qint32)e2.to);
- if (qMax(u1.x, u2.x) <= qMin(v1.x, v2.x))
- return false;
-
- quint64 key = (left > right ? (quint64(right) << 32) | quint64(left) : (quint64(left) << 32) | quint64(right));
- if (m_processedEdgePairs.contains(key))
- return false;
- m_processedEdgePairs.insert(key);
-
- Intersection intersection;
- intersection.leftEdge = left;
- intersection.rightEdge = right;
- intersection.intersectionPoint = QT_PREPEND_NAMESPACE(qIntersectionPoint)(u1, u2, v1, v2);
-
- if (!intersection.intersectionPoint.isValid())
- return false;
-
- Q_ASSERT(intersection.intersectionPoint.isOnLine(u1, u2));
- Q_ASSERT(intersection.intersectionPoint.isOnLine(v1, v2));
-
- intersection.vertex = m_parent->m_vertices.size();
- m_topIntersection.push(intersection);
- m_parent->m_vertices.add(intersection.intersectionPoint.round());
- return true;
-}
-
-template <typename T>
-bool QTriangulator<T>::ComplexToSimple::edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const
-{
- const Edge &leftEdge = m_edges.at(leftEdgeIndex);
- const Edge &rightEdge = m_edges.at(rightEdgeIndex);
- const QPodPoint &u = m_parent->m_vertices.at(rightEdge.upper());
- const QPodPoint &l = m_parent->m_vertices.at(rightEdge.lower());
- const QPodPoint &upper = m_parent->m_vertices.at(leftEdge.upper());
- if (upper.x < qMin(l.x, u.x))
- return true;
- if (upper.x > qMax(l.x, u.x))
- return false;
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(upper, l, u);
- // d < 0: left, d > 0: right, d == 0: on top
- if (d == 0)
- d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.lower()), l, u);
- return d < 0;
-}
-
-template <typename T>
-QRBTree<int>::Node *QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edgeIndex) const
-{
- QRBTree<int>::Node *current = m_edgeList.root;
- QRBTree<int>::Node *result = 0;
- while (current) {
- if (edgeIsLeftOfEdge(edgeIndex, current->data)) {
- current = current->left;
- } else {
- result = current;
- current = current->right;
- }
- }
- return result;
-}
-
-template <typename T>
-QRBTree<int>::Node *QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edgeIndex, QRBTree<int>::Node *after) const
-{
- if (!m_edgeList.root)
- return after;
- QRBTree<int>::Node *result = after;
- QRBTree<int>::Node *current = (after ? m_edgeList.next(after) : m_edgeList.front(m_edgeList.root));
- while (current) {
- if (edgeIsLeftOfEdge(edgeIndex, current->data))
- return result;
- result = current;
- current = m_edgeList.next(current);
- }
- return result;
-}
-
-template <typename T>
-QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSimple::bounds(const QPodPoint &point) const
-{
- QRBTree<int>::Node *current = m_edgeList.root;
- QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> result(0, 0);
- while (current) {
- const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
- const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
- if (d == 0) {
- result.first = result.second = current;
- break;
- }
- current = (d < 0 ? current->left : current->right);
- }
- if (current == 0)
- return result;
-
- current = result.first->left;
- while (current) {
- const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
- const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
- Q_ASSERT(d >= 0);
- if (d == 0) {
- result.first = current;
- current = current->left;
- } else {
- current = current->right;
- }
- }
-
- current = result.second->right;
- while (current) {
- const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
- const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
- Q_ASSERT(d <= 0);
- if (d == 0) {
- result.second = current;
- current = current->right;
- } else {
- current = current->left;
- }
- }
-
- return result;
-}
-
-template <typename T>
-QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> QTriangulator<T>::ComplexToSimple::outerBounds(const QPodPoint &point) const
-{
- QRBTree<int>::Node *current = m_edgeList.root;
- QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> result(0, 0);
-
- while (current) {
- const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
- const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
- if (d == 0)
- break;
- if (d < 0) {
- result.second = current;
- current = current->left;
- } else {
- result.first = current;
- current = current->right;
- }
- }
-
- if (!current)
- return result;
-
- QRBTree<int>::Node *mid = current;
-
- current = mid->left;
- while (current) {
- const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
- const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
- Q_ASSERT(d >= 0);
- if (d == 0) {
- current = current->left;
- } else {
- result.first = current;
- current = current->right;
- }
- }
-
- current = mid->right;
- while (current) {
- const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
- const QPodPoint &v2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(point, v1, v2);
- Q_ASSERT(d <= 0);
- if (d == 0) {
- current = current->right;
- } else {
- result.second = current;
- current = current->left;
- }
- }
-
- return result;
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::splitEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost, int vertex, const QIntersectionPoint &intersectionPoint)
-{
- Q_ASSERT(leftmost && rightmost);
-
- // Split.
- for (;;) {
- const QPodPoint &u = m_parent->m_vertices.at(m_edges.at(leftmost->data).from);
- const QPodPoint &v = m_parent->m_vertices.at(m_edges.at(leftmost->data).to);
- Q_ASSERT(intersectionPoint.isOnLine(u, v));
- const Split split = {vertex, leftmost->data, intersectionPoint.isAccurate()};
- if (intersectionPoint.xOffset.numerator != 0 || intersectionPoint.yOffset.numerator != 0 || (intersectionPoint.upperLeft != u && intersectionPoint.upperLeft != v))
- m_splits.add(split);
- if (leftmost == rightmost)
- break;
- leftmost = m_edgeList.next(leftmost);
- }
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::reorderEdgeListRange(QRBTree<int>::Node *leftmost, QRBTree<int>::Node *rightmost)
-{
- Q_ASSERT(leftmost && rightmost);
-
- QRBTree<int>::Node *storeLeftmost = leftmost;
- QRBTree<int>::Node *storeRightmost = rightmost;
-
- // Reorder.
- while (leftmost != rightmost) {
- Edge &left = m_edges.at(leftmost->data);
- Edge &right = m_edges.at(rightmost->data);
- qSwap(left.node, right.node);
- qSwap(leftmost->data, rightmost->data);
- leftmost = m_edgeList.next(leftmost);
- if (leftmost == rightmost)
- break;
- rightmost = m_edgeList.previous(rightmost);
- }
-
- rightmost = m_edgeList.next(storeRightmost);
- leftmost = m_edgeList.previous(storeLeftmost);
- if (leftmost)
- calculateIntersection(leftmost->data, storeLeftmost->data);
- if (rightmost)
- calculateIntersection(storeRightmost->data, rightmost->data);
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::sortEdgeList(const QPodPoint eventPoint)
-{
- QIntersectionPoint eventPoint2 = QT_PREPEND_NAMESPACE(qIntersectionPoint)(eventPoint);
- while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint < eventPoint2) {
- Intersection intersection = m_topIntersection.pop();
-
- QIntersectionPoint currentIntersectionPoint = intersection.intersectionPoint;
- int currentVertex = intersection.vertex;
-
- QRBTree<int>::Node *leftmost = m_edges.at(intersection.leftEdge).node;
- QRBTree<int>::Node *rightmost = m_edges.at(intersection.rightEdge).node;
-
- for (;;) {
- QRBTree<int>::Node *previous = m_edgeList.previous(leftmost);
- if (!previous)
- break;
- const Edge &edge = m_edges.at(previous->data);
- const QPodPoint &u = m_parent->m_vertices.at((qint32)edge.from);
- const QPodPoint &v = m_parent->m_vertices.at((qint32)edge.to);
- if (!currentIntersectionPoint.isOnLine(u, v)) {
- Q_ASSERT(!currentIntersectionPoint.isAccurate() || qCross(currentIntersectionPoint.upperLeft - u, v - u) != 0);
- break;
- }
- leftmost = previous;
- }
-
- for (;;) {
- QRBTree<int>::Node *next = m_edgeList.next(rightmost);
- if (!next)
- break;
- const Edge &edge = m_edges.at(next->data);
- const QPodPoint &u = m_parent->m_vertices.at((qint32)edge.from);
- const QPodPoint &v = m_parent->m_vertices.at((qint32)edge.to);
- if (!currentIntersectionPoint.isOnLine(u, v)) {
- Q_ASSERT(!currentIntersectionPoint.isAccurate() || qCross(currentIntersectionPoint.upperLeft - u, v - u) != 0);
- break;
- }
- rightmost = next;
- }
-
- Q_ASSERT(leftmost && rightmost);
- splitEdgeListRange(leftmost, rightmost, currentVertex, currentIntersectionPoint);
- reorderEdgeListRange(leftmost, rightmost);
-
- while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint <= currentIntersectionPoint)
- m_topIntersection.pop();
-
-#ifdef Q_TRIANGULATOR_DEBUG
- DebugDialog dialog(this, intersection.vertex);
- dialog.exec();
-#endif
-
- }
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::fillPriorityQueue()
-{
- m_events.reset();
- m_events.reserve(m_edges.size() * 2);
- for (int i = 0; i < m_edges.size(); ++i) {
- Q_ASSERT(m_edges.at(i).previous == -1 && m_edges.at(i).next == -1);
- Q_ASSERT(m_edges.at(i).node == 0);
- Q_ASSERT(m_edges.at(i).pointingUp == m_edges.at(i).originallyPointingUp);
- Q_ASSERT(m_edges.at(i).pointingUp == (m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from)));
- // Ignore zero-length edges.
- if (m_parent->m_vertices.at(m_edges.at(i).to) != m_parent->m_vertices.at(m_edges.at(i).from)) {
- QPodPoint upper = m_parent->m_vertices.at(m_edges.at(i).upper());
- QPodPoint lower = m_parent->m_vertices.at(m_edges.at(i).lower());
- Event upperEvent = {{upper.x, upper.y}, Event::Upper, i};
- Event lowerEvent = {{lower.x, lower.y}, Event::Lower, i};
- m_events.add(upperEvent);
- m_events.add(lowerEvent);
- }
- }
- //qSort(m_events.data(), m_events.data() + m_events.size());
- sort(m_events.data(), m_events.size());
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::calculateIntersections()
-{
- fillPriorityQueue();
-
- Q_ASSERT(m_topIntersection.empty());
- Q_ASSERT(m_edgeList.root == 0);
-
- // Find all intersection points.
- while (!m_events.isEmpty()) {
- Event event = m_events.last();
- sortEdgeList(event.point);
-
- // Find all edges in the edge list that contain the current vertex and mark them to be split later.
- QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> range = bounds(event.point);
- QRBTree<int>::Node *leftNode = range.first ? m_edgeList.previous(range.first) : 0;
- int vertex = (event.type == Event::Upper ? m_edges.at(event.edge).upper() : m_edges.at(event.edge).lower());
- QIntersectionPoint eventPoint = QT_PREPEND_NAMESPACE(qIntersectionPoint)(event.point);
-
- if (range.first != 0) {
- splitEdgeListRange(range.first, range.second, vertex, eventPoint);
- reorderEdgeListRange(range.first, range.second);
- }
-
- // Handle the edges with start or end point in the current vertex.
- while (!m_events.isEmpty() && m_events.last().point == event.point) {
- event = m_events.last();
- m_events.pop_back();
- int i = event.edge;
-
- if (m_edges.at(i).node) {
- // Remove edge from edge list.
- Q_ASSERT(event.type == Event::Lower);
- QRBTree<int>::Node *left = m_edgeList.previous(m_edges.at(i).node);
- QRBTree<int>::Node *right = m_edgeList.next(m_edges.at(i).node);
- m_edgeList.deleteNode(m_edges.at(i).node);
- if (!left || !right)
- continue;
- calculateIntersection(left->data, right->data);
- } else {
- // Insert edge into edge list.
- Q_ASSERT(event.type == Event::Upper);
- QRBTree<int>::Node *left = searchEdgeLeftOf(i, leftNode);
- m_edgeList.attachAfter(left, m_edges.at(i).node = m_edgeList.newNode());
- m_edges.at(i).node->data = i;
- QRBTree<int>::Node *right = m_edgeList.next(m_edges.at(i).node);
- if (left)
- calculateIntersection(left->data, i);
- if (right)
- calculateIntersection(i, right->data);
- }
- }
- while (!m_topIntersection.isEmpty() && m_topIntersection.top().intersectionPoint <= eventPoint)
- m_topIntersection.pop();
-#ifdef Q_TRIANGULATOR_DEBUG
- DebugDialog dialog(this, vertex);
- dialog.exec();
-#endif
- }
- m_processedEdgePairs.clear();
-}
-
-// Split an edge into two pieces at the given point.
-// The upper piece is pushed to the end of the 'm_edges' vector.
-// The lower piece replaces the old edge.
-// Return the edge whose 'from' is 'pointIndex'.
-template <typename T>
-int QTriangulator<T>::ComplexToSimple::splitEdge(int splitIndex)
-{
- const Split &split = m_splits.at(splitIndex);
- Edge &lowerEdge = m_edges.at(split.edge);
- Q_ASSERT(lowerEdge.node == 0);
- Q_ASSERT(lowerEdge.previous == -1 && lowerEdge.next == -1);
-
- if (lowerEdge.from == split.vertex)
- return split.edge;
- if (lowerEdge.to == split.vertex)
- return lowerEdge.next;
-
- // Check that angle >= 90 degrees.
- //Q_ASSERT(qDot(m_points.at(m_edges.at(edgeIndex).from) - m_points.at(pointIndex),
- // m_points.at(m_edges.at(edgeIndex).to) - m_points.at(pointIndex)) <= 0);
-
- Edge upperEdge = lowerEdge;
- upperEdge.mayIntersect |= !split.accurate; // The edge may have been split before at an inaccurate split point.
- lowerEdge.mayIntersect = !split.accurate;
- if (lowerEdge.pointingUp) {
- lowerEdge.to = upperEdge.from = split.vertex;
- m_edges.add(upperEdge);
- return m_edges.size() - 1;
- } else {
- lowerEdge.from = upperEdge.to = split.vertex;
- m_edges.add(upperEdge);
- return split.edge;
- }
-}
-
-template <typename T>
-bool QTriangulator<T>::ComplexToSimple::splitEdgesAtIntersections()
-{
- for (int i = 0; i < m_edges.size(); ++i)
- m_edges.at(i).mayIntersect = false;
- bool checkForNewIntersections = false;
- for (int i = 0; i < m_splits.size(); ++i) {
- splitEdge(i);
- checkForNewIntersections |= !m_splits.at(i).accurate;
- }
- for (int i = 0; i < m_edges.size(); ++i) {
- m_edges.at(i).originallyPointingUp = m_edges.at(i).pointingUp =
- m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
- }
- m_splits.reset();
- return checkForNewIntersections;
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::insertEdgeIntoVectorIfWanted(ShortArray &orderedEdges, int i)
-{
- // Edges with zero length should not reach this part.
- Q_ASSERT(m_parent->m_vertices.at(m_edges.at(i).from) != m_parent->m_vertices.at(m_edges.at(i).to));
-
- // Skip edges with unwanted winding number.
- int windingNumber = m_edges.at(i).winding;
- if (m_edges.at(i).originallyPointingUp)
- ++windingNumber;
-
- // Make sure exactly one fill rule is specified.
- Q_ASSERT(((m_parent->m_hint & QVectorPath::WindingFill) != 0) != ((m_parent->m_hint & QVectorPath::OddEvenFill) != 0));
-
- if ((m_parent->m_hint & QVectorPath::WindingFill) && windingNumber != 0 && windingNumber != 1)
- return;
-
- // Skip cancelling edges.
- if (!orderedEdges.isEmpty()) {
- int j = orderedEdges[orderedEdges.size() - 1];
- // If the last edge is already connected in one end, it should not be cancelled.
- if (m_edges.at(j).next == -1 && m_edges.at(j).previous == -1
- && (m_parent->m_vertices.at(m_edges.at(i).from) == m_parent->m_vertices.at(m_edges.at(j).to))
- && (m_parent->m_vertices.at(m_edges.at(i).to) == m_parent->m_vertices.at(m_edges.at(j).from))) {
- orderedEdges.removeLast();
- return;
- }
- }
- orderedEdges.append(i);
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::removeUnwantedEdgesAndConnect()
-{
- Q_ASSERT(m_edgeList.root == 0);
- // Initialize priority queue.
- fillPriorityQueue();
-
- ShortArray orderedEdges;
-
- while (!m_events.isEmpty()) {
- Event event = m_events.last();
- int edgeIndex = event.edge;
-
- // Check that all the edges in the list crosses the current scanline
- //if (m_edgeList.root) {
- // for (QRBTree<int>::Node *node = m_edgeList.front(m_edgeList.root); node; node = m_edgeList.next(node)) {
- // Q_ASSERT(event.point <= m_points.at(m_edges.at(node->data).lower()));
- // }
- //}
-
- orderedEdges.clear();
- QPair<QRBTree<int>::Node *, QRBTree<int>::Node *> b = outerBounds(event.point);
- if (m_edgeList.root) {
- QRBTree<int>::Node *current = (b.first ? m_edgeList.next(b.first) : m_edgeList.front(m_edgeList.root));
- // Process edges that are going to be removed from the edge list at the current event point.
- while (current != b.second) {
- Q_ASSERT(current);
- Q_ASSERT(m_edges.at(current->data).node == current);
- Q_ASSERT(QT_PREPEND_NAMESPACE(qIntersectionPoint)(event.point).isOnLine(m_parent->m_vertices.at(m_edges.at(current->data).from), m_parent->m_vertices.at(m_edges.at(current->data).to)));
- Q_ASSERT(m_parent->m_vertices.at(m_edges.at(current->data).from) == event.point || m_parent->m_vertices.at(m_edges.at(current->data).to) == event.point);
- insertEdgeIntoVectorIfWanted(orderedEdges, current->data);
- current = m_edgeList.next(current);
- }
- }
-
- // Remove edges above the event point, insert edges below the event point.
- do {
- event = m_events.last();
- m_events.pop_back();
- edgeIndex = event.edge;
-
- // Edges with zero length should not reach this part.
- Q_ASSERT(m_parent->m_vertices.at(m_edges.at(edgeIndex).from) != m_parent->m_vertices.at(m_edges.at(edgeIndex).to));
-
- if (m_edges.at(edgeIndex).node) {
- Q_ASSERT(event.type == Event::Lower);
- Q_ASSERT(event.point == m_parent->m_vertices.at(m_edges.at(event.edge).lower()));
- m_edgeList.deleteNode(m_edges.at(edgeIndex).node);
- } else {
- Q_ASSERT(event.type == Event::Upper);
- Q_ASSERT(event.point == m_parent->m_vertices.at(m_edges.at(event.edge).upper()));
- QRBTree<int>::Node *left = searchEdgeLeftOf(edgeIndex, b.first);
- m_edgeList.attachAfter(left, m_edges.at(edgeIndex).node = m_edgeList.newNode());
- m_edges.at(edgeIndex).node->data = edgeIndex;
- }
- } while (!m_events.isEmpty() && m_events.last().point == event.point);
-
- if (m_edgeList.root) {
- QRBTree<int>::Node *current = (b.first ? m_edgeList.next(b.first) : m_edgeList.front(m_edgeList.root));
-
- // Calculate winding number and turn counter-clockwise.
- int currentWindingNumber = (b.first ? m_edges.at(b.first->data).winding : 0);
- while (current != b.second) {
- Q_ASSERT(current);
- //Q_ASSERT(b.second == 0 || m_edgeList.order(current, b.second) < 0);
- int i = current->data;
- Q_ASSERT(m_edges.at(i).node == current);
-
- // Winding number.
- int ccwWindingNumber = m_edges.at(i).winding = currentWindingNumber;
- if (m_edges.at(i).originallyPointingUp) {
- --m_edges.at(i).winding;
- } else {
- ++m_edges.at(i).winding;
- ++ccwWindingNumber;
- }
- currentWindingNumber = m_edges.at(i).winding;
-
- // Turn counter-clockwise.
- if ((ccwWindingNumber & 1) == 0) {
- Q_ASSERT(m_edges.at(i).previous == -1 && m_edges.at(i).next == -1);
- qSwap(m_edges.at(i).from, m_edges.at(i).to);
- m_edges.at(i).pointingUp = !m_edges.at(i).pointingUp;
- }
-
- current = m_edgeList.next(current);
- }
-
- // Process edges that were inserted into the edge list at the current event point.
- current = (b.second ? m_edgeList.previous(b.second) : m_edgeList.back(m_edgeList.root));
- while (current != b.first) {
- Q_ASSERT(current);
- Q_ASSERT(m_edges.at(current->data).node == current);
- insertEdgeIntoVectorIfWanted(orderedEdges, current->data);
- current = m_edgeList.previous(current);
- }
- }
- if (orderedEdges.isEmpty())
- continue;
-
- Q_ASSERT((orderedEdges.size() & 1) == 0);
-
- // Connect edges.
- // First make sure the first edge point towards the current point.
- int i;
- if (m_parent->m_vertices.at(m_edges.at(orderedEdges[0]).from) == event.point) {
- i = 1;
- int copy = orderedEdges[0]; // Make copy in case the append() will cause a reallocation.
- orderedEdges.append(copy);
- } else {
- Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[0]).to) == event.point);
- i = 0;
- }
-
- // Remove references to duplicate points. First find the point with lowest index.
- int pointIndex = INT_MAX;
- for (int j = i; j < orderedEdges.size(); j += 2) {
- Q_ASSERT(j + 1 < orderedEdges.size());
- Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[j]).to) == event.point);
- Q_ASSERT(m_parent->m_vertices.at(m_edges.at(orderedEdges[j + 1]).from) == event.point);
- if (m_edges.at(orderedEdges[j]).to < pointIndex)
- pointIndex = m_edges.at(orderedEdges[j]).to;
- if (m_edges.at(orderedEdges[j + 1]).from < pointIndex)
- pointIndex = m_edges.at(orderedEdges[j + 1]).from;
- }
-
- for (; i < orderedEdges.size(); i += 2) {
- // Remove references to duplicate points by making all edges reference one common point.
- m_edges.at(orderedEdges[i]).to = m_edges.at(orderedEdges[i + 1]).from = pointIndex;
-
- Q_ASSERT(m_edges.at(orderedEdges[i]).pointingUp || m_edges.at(orderedEdges[i]).previous != -1);
- Q_ASSERT(!m_edges.at(orderedEdges[i + 1]).pointingUp || m_edges.at(orderedEdges[i + 1]).next != -1);
-
- m_edges.at(orderedEdges[i]).next = orderedEdges[i + 1];
- m_edges.at(orderedEdges[i + 1]).previous = orderedEdges[i];
- }
- } // end while
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::removeUnusedPoints() {
- QBitArray used(m_parent->m_vertices.size(), false);
- for (int i = 0; i < m_edges.size(); ++i) {
- Q_ASSERT((m_edges.at(i).previous == -1) == (m_edges.at(i).next == -1));
- if (m_edges.at(i).next != -1)
- used.setBit(m_edges.at(i).from);
- }
- QDataBuffer<quint32> newMapping(m_parent->m_vertices.size());
- newMapping.resize(m_parent->m_vertices.size());
- int count = 0;
- for (int i = 0; i < m_parent->m_vertices.size(); ++i) {
- if (used.at(i)) {
- m_parent->m_vertices.at(count) = m_parent->m_vertices.at(i);
- newMapping.at(i) = count;
- ++count;
- }
- }
- m_parent->m_vertices.resize(count);
- for (int i = 0; i < m_edges.size(); ++i) {
- m_edges.at(i).from = newMapping.at(m_edges.at(i).from);
- m_edges.at(i).to = newMapping.at(m_edges.at(i).to);
- }
-}
-
-template <typename T>
-bool QTriangulator<T>::ComplexToSimple::CompareEdges::operator () (int i, int j) const
-{
- int cmp = comparePoints(m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).from),
- m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).from));
- if (cmp == 0) {
- cmp = comparePoints(m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).to),
- m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).to));
- }
- return cmp > 0;
-}
-
-template <typename T>
-inline bool QTriangulator<T>::ComplexToSimple::Event::operator < (const Event &other) const
-{
- if (point == other.point)
- return type < other.type; // 'Lower' has higher priority than 'Upper'.
- return other.point < point;
-}
-
-//============================================================================//
-// QTriangulator::ComplexToSimple::DebugDialog //
-//============================================================================//
-
-#ifdef Q_TRIANGULATOR_DEBUG
-template <typename T>
-QTriangulator<T>::ComplexToSimple::DebugDialog::DebugDialog(ComplexToSimple *parent, int currentVertex)
- : m_parent(parent), m_vertex(currentVertex)
-{
- QDataBuffer<QPodPoint> &vertices = m_parent->m_parent->m_vertices;
- if (vertices.isEmpty())
- return;
-
- int minX, maxX, minY, maxY;
- minX = maxX = vertices.at(0).x;
- minY = maxY = vertices.at(0).y;
- for (int i = 1; i < vertices.size(); ++i) {
- minX = qMin(minX, vertices.at(i).x);
- maxX = qMax(maxX, vertices.at(i).x);
- minY = qMin(minY, vertices.at(i).y);
- maxY = qMax(maxY, vertices.at(i).y);
- }
- int w = maxX - minX;
- int h = maxY - minY;
- qreal border = qMin(w, h) / 10.0;
- m_window = QRectF(minX - border, minY - border, (maxX - minX + 2 * border), (maxY - minY + 2 * border));
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::DebugDialog::paintEvent(QPaintEvent *)
-{
- QPainter p(this);
- p.setRenderHint(QPainter::Antialiasing, true);
- p.fillRect(rect(), Qt::black);
- QDataBuffer<QPodPoint> &vertices = m_parent->m_parent->m_vertices;
- if (vertices.isEmpty())
- return;
-
- qreal halfPointSize = qMin(m_window.width(), m_window.height()) / 300.0;
- p.setWindow(m_window.toRect());
-
- p.setPen(Qt::white);
-
- QDataBuffer<Edge> &edges = m_parent->m_edges;
- for (int i = 0; i < edges.size(); ++i) {
- QPodPoint u = vertices.at(edges.at(i).from);
- QPodPoint v = vertices.at(edges.at(i).to);
- p.drawLine(u.x, u.y, v.x, v.y);
- }
-
- for (int i = 0; i < vertices.size(); ++i) {
- QPodPoint q = vertices.at(i);
- p.fillRect(QRectF(q.x - halfPointSize, q.y - halfPointSize, 2 * halfPointSize, 2 * halfPointSize), Qt::red);
- }
-
- Qt::GlobalColor colors[6] = {Qt::red, Qt::green, Qt::blue, Qt::cyan, Qt::magenta, Qt::yellow};
- p.setOpacity(0.5);
- int count = 0;
- if (m_parent->m_edgeList.root) {
- QRBTree<int>::Node *current = m_parent->m_edgeList.front(m_parent->m_edgeList.root);
- while (current) {
- p.setPen(colors[count++ % 6]);
- QPodPoint u = vertices.at(edges.at(current->data).from);
- QPodPoint v = vertices.at(edges.at(current->data).to);
- p.drawLine(u.x, u.y, v.x, v.y);
- current = m_parent->m_edgeList.next(current);
- }
- }
-
- p.setOpacity(1.0);
- QPodPoint q = vertices.at(m_vertex);
- p.fillRect(QRectF(q.x - halfPointSize, q.y - halfPointSize, 2 * halfPointSize, 2 * halfPointSize), Qt::green);
-
- p.setPen(Qt::gray);
- QDataBuffer<Split> &splits = m_parent->m_splits;
- for (int i = 0; i < splits.size(); ++i) {
- QPodPoint q = vertices.at(splits.at(i).vertex);
- QPodPoint u = vertices.at(edges.at(splits.at(i).edge).from) - q;
- QPodPoint v = vertices.at(edges.at(splits.at(i).edge).to) - q;
- qreal uLen = sqrt(qreal(qDot(u, u)));
- qreal vLen = sqrt(qreal(qDot(v, v)));
- if (uLen) {
- u.x *= 2 * halfPointSize / uLen;
- u.y *= 2 * halfPointSize / uLen;
- }
- if (vLen) {
- v.x *= 2 * halfPointSize / vLen;
- v.y *= 2 * halfPointSize / vLen;
- }
- u += q;
- v += q;
- p.drawLine(u.x, u.y, v.x, v.y);
- }
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::DebugDialog::wheelEvent(QWheelEvent *event)
-{
- qreal scale = exp(-0.001 * event->delta());
- QPointF center = m_window.center();
- QPointF delta = scale * (m_window.bottomRight() - center);
- m_window = QRectF(center - delta, center + delta);
- event->accept();
- update();
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::DebugDialog::mouseMoveEvent(QMouseEvent *event)
-{
- if (event->buttons() & Qt::LeftButton) {
- QPointF delta = event->pos() - m_lastMousePos;
- delta.setX(delta.x() * m_window.width() / width());
- delta.setY(delta.y() * m_window.height() / height());
- m_window.translate(-delta.x(), -delta.y());
- m_lastMousePos = event->pos();
- event->accept();
- update();
- }
-}
-
-template <typename T>
-void QTriangulator<T>::ComplexToSimple::DebugDialog::mousePressEvent(QMouseEvent *event)
-{
- if (event->button() == Qt::LeftButton)
- m_lastMousePos = event->pos();
- event->accept();
-}
-
-
-#endif
-
-//============================================================================//
-// QTriangulator::SimpleToMonotone //
-//============================================================================//
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::decompose()
-{
- setupDataStructures();
- removeZeroLengthEdges();
- monotoneDecomposition();
-
- m_parent->m_indices.clear();
- QBitArray processed(m_edges.size(), false);
- for (int first = 0; first < m_edges.size(); ++first) {
- if (processed.at(first))
- continue;
- int i = first;
- do {
- Q_ASSERT(!processed.at(i));
- Q_ASSERT(m_edges.at(m_edges.at(i).next).previous == i);
- m_parent->m_indices.push_back(m_edges.at(i).from);
- processed.setBit(i);
- i = m_edges.at(i).next;
- } while (i != first);
- if (m_parent->m_indices.size() > 0 && m_parent->m_indices.back() != T(-1)) // Q_TRIANGULATE_END_OF_POLYGON
- m_parent->m_indices.push_back(T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
- }
-}
-
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::setupDataStructures()
-{
- int i = 0;
- Edge e;
- e.node = 0;
- e.twin = -1;
-
- while (i + 3 <= m_parent->m_indices.size()) {
- int start = m_edges.size();
-
- do {
- e.from = m_parent->m_indices.at(i);
- e.type = RegularVertex;
- e.next = m_edges.size() + 1;
- e.previous = m_edges.size() - 1;
- m_edges.add(e);
- ++i;
- Q_ASSERT(i < m_parent->m_indices.size());
- } while (m_parent->m_indices.at(i) != T(-1)); // Q_TRIANGULATE_END_OF_POLYGON
-
- m_edges.last().next = start;
- m_edges.at(start).previous = m_edges.size() - 1;
- ++i; // Skip Q_TRIANGULATE_END_OF_POLYGON.
- }
-
- for (i = 0; i < m_edges.size(); ++i) {
- m_edges.at(i).to = m_edges.at(m_edges.at(i).next).from;
- m_edges.at(i).pointingUp = m_parent->m_vertices.at(m_edges.at(i).to) < m_parent->m_vertices.at(m_edges.at(i).from);
- m_edges.at(i).helper = -1; // Not initialized here.
- }
-}
-
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::removeZeroLengthEdges()
-{
- for (int i = 0; i < m_edges.size(); ++i) {
- if (m_parent->m_vertices.at(m_edges.at(i).from) == m_parent->m_vertices.at(m_edges.at(i).to)) {
- m_edges.at(m_edges.at(i).previous).next = m_edges.at(i).next;
- m_edges.at(m_edges.at(i).next).previous = m_edges.at(i).previous;
- m_edges.at(m_edges.at(i).next).from = m_edges.at(i).from;
- m_edges.at(i).next = -1; // Mark as removed.
- }
- }
-
- QDataBuffer<int> newMapping(m_edges.size());
- newMapping.resize(m_edges.size());
- int count = 0;
- for (int i = 0; i < m_edges.size(); ++i) {
- if (m_edges.at(i).next != -1) {
- m_edges.at(count) = m_edges.at(i);
- newMapping.at(i) = count;
- ++count;
- }
- }
- m_edges.resize(count);
- for (int i = 0; i < m_edges.size(); ++i) {
- m_edges.at(i).next = newMapping.at(m_edges.at(i).next);
- m_edges.at(i).previous = newMapping.at(m_edges.at(i).previous);
- }
-}
-
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::fillPriorityQueue()
-{
- m_upperVertex.reset();
- m_upperVertex.reserve(m_edges.size());
- for (int i = 0; i < m_edges.size(); ++i)
- m_upperVertex.add(i);
- CompareVertices cmp(this);
- //qSort(m_upperVertex.data(), m_upperVertex.data() + m_upperVertex.size(), cmp);
- sort(m_upperVertex.data(), m_upperVertex.size(), cmp);
- //for (int i = 1; i < m_upperVertex.size(); ++i) {
- // Q_ASSERT(!cmp(m_upperVertex.at(i), m_upperVertex.at(i - 1)));
- //}
-}
-
-template <typename T>
-bool QTriangulator<T>::SimpleToMonotone::edgeIsLeftOfEdge(int leftEdgeIndex, int rightEdgeIndex) const
-{
- const Edge &leftEdge = m_edges.at(leftEdgeIndex);
- const Edge &rightEdge = m_edges.at(rightEdgeIndex);
- const QPodPoint &u = m_parent->m_vertices.at(rightEdge.upper());
- const QPodPoint &l = m_parent->m_vertices.at(rightEdge.lower());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.upper()), l, u);
- // d < 0: left, d > 0: right, d == 0: on top
- if (d == 0)
- d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(leftEdge.lower()), l, u);
- return d < 0;
-}
-
-// Returns the rightmost edge not to the right of the given edge.
-template <typename T>
-QRBTree<int>::Node *QTriangulator<T>::SimpleToMonotone::searchEdgeLeftOfEdge(int edgeIndex) const
-{
- QRBTree<int>::Node *current = m_edgeList.root;
- QRBTree<int>::Node *result = 0;
- while (current) {
- if (edgeIsLeftOfEdge(edgeIndex, current->data)) {
- current = current->left;
- } else {
- result = current;
- current = current->right;
- }
- }
- return result;
-}
-
-// Returns the rightmost edge left of the given point.
-template <typename T>
-QRBTree<int>::Node *QTriangulator<T>::SimpleToMonotone::searchEdgeLeftOfPoint(int pointIndex) const
-{
- QRBTree<int>::Node *current = m_edgeList.root;
- QRBTree<int>::Node *result = 0;
- while (current) {
- const QPodPoint &p1 = m_parent->m_vertices.at(m_edges.at(current->data).lower());
- const QPodPoint &p2 = m_parent->m_vertices.at(m_edges.at(current->data).upper());
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(m_parent->m_vertices.at(pointIndex), p1, p2);
- if (d <= 0) {
- current = current->left;
- } else {
- result = current;
- current = current->right;
- }
- }
- return result;
-}
-
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::classifyVertex(int i)
-{
- Edge &e2 = m_edges.at(i);
- const Edge &e1 = m_edges.at(e2.previous);
-
- bool startOrSplit = (e1.pointingUp && !e2.pointingUp);
- bool endOrMerge = (!e1.pointingUp && e2.pointingUp);
-
- const QPodPoint &p1 = m_parent->m_vertices.at(e1.from);
- const QPodPoint &p2 = m_parent->m_vertices.at(e2.from);
- const QPodPoint &p3 = m_parent->m_vertices.at(e2.to);
- qint64 d = QT_PREPEND_NAMESPACE(qPointDistanceFromLine)(p1, p2, p3);
- Q_ASSERT(d != 0 || (!startOrSplit && !endOrMerge));
-
- e2.type = RegularVertex;
-
- if (m_clockwiseOrder) {
- if (startOrSplit)
- e2.type = (d < 0 ? SplitVertex : StartVertex);
- else if (endOrMerge)
- e2.type = (d < 0 ? MergeVertex : EndVertex);
- } else {
- if (startOrSplit)
- e2.type = (d > 0 ? SplitVertex : StartVertex);
- else if (endOrMerge)
- e2.type = (d > 0 ? MergeVertex : EndVertex);
- }
-}
-
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::classifyVertices()
-{
- for (int i = 0; i < m_edges.size(); ++i)
- classifyVertex(i);
-}
-
-template <typename T>
-bool QTriangulator<T>::SimpleToMonotone::pointIsInSector(const QPodPoint &p, const QPodPoint &v1, const QPodPoint &v2, const QPodPoint &v3)
-{
- bool leftOfPreviousEdge = !qPointIsLeftOfLine(p, v2, v1);
- bool leftOfNextEdge = !qPointIsLeftOfLine(p, v3, v2);
-
- if (qPointIsLeftOfLine(v1, v2, v3))
- return leftOfPreviousEdge && leftOfNextEdge;
- else
- return leftOfPreviousEdge || leftOfNextEdge;
-}
-
-template <typename T>
-bool QTriangulator<T>::SimpleToMonotone::pointIsInSector(int vertex, int sector)
-{
- const QPodPoint &center = m_parent->m_vertices.at(m_edges.at(sector).from);
- // Handle degenerate edges.
- while (m_parent->m_vertices.at(m_edges.at(vertex).from) == center)
- vertex = m_edges.at(vertex).next;
- int next = m_edges.at(sector).next;
- while (m_parent->m_vertices.at(m_edges.at(next).from) == center)
- next = m_edges.at(next).next;
- int previous = m_edges.at(sector).previous;
- while (m_parent->m_vertices.at(m_edges.at(previous).from) == center)
- previous = m_edges.at(previous).previous;
-
- const QPodPoint &p = m_parent->m_vertices.at(m_edges.at(vertex).from);
- const QPodPoint &v1 = m_parent->m_vertices.at(m_edges.at(previous).from);
- const QPodPoint &v3 = m_parent->m_vertices.at(m_edges.at(next).from);
- if (m_clockwiseOrder)
- return pointIsInSector(p, v3, center, v1);
- else
- return pointIsInSector(p, v1, center, v3);
-}
-
-template <typename T>
-int QTriangulator<T>::SimpleToMonotone::findSector(int edge, int vertex)
-{
- while (!pointIsInSector(vertex, edge)) {
- edge = m_edges.at(m_edges.at(edge).previous).twin;
- Q_ASSERT(edge != -1);
- }
- return edge;
-}
-
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::createDiagonal(int lower, int upper)
-{
- lower = findSector(lower, upper);
- upper = findSector(upper, lower);
-
- int prevLower = m_edges.at(lower).previous;
- int prevUpper = m_edges.at(upper).previous;
-
- Edge e;
-
- e.twin = m_edges.size() + 1;
- e.next = upper;
- e.previous = prevLower;
- e.from = m_edges.at(lower).from;
- e.to = m_edges.at(upper).from;
- m_edges.at(upper).previous = m_edges.at(prevLower).next = int(m_edges.size());
- m_edges.add(e);
-
- e.twin = m_edges.size() - 1;
- e.next = lower;
- e.previous = prevUpper;
- e.from = m_edges.at(upper).from;
- e.to = m_edges.at(lower).from;
- m_edges.at(lower).previous = m_edges.at(prevUpper).next = int(m_edges.size());
- m_edges.add(e);
-}
-
-template <typename T>
-void QTriangulator<T>::SimpleToMonotone::monotoneDecomposition()
-{
- if (m_edges.isEmpty())
- return;
-
- Q_ASSERT(!m_edgeList.root);
- QDataBuffer<QPair<int, int> > diagonals(m_upperVertex.size());
-
- int i = 0;
- for (int index = 1; index < m_edges.size(); ++index) {
- if (m_parent->m_vertices.at(m_edges.at(index).from) < m_parent->m_vertices.at(m_edges.at(i).from))
- i = index;
- }
- Q_ASSERT(i < m_edges.size());
- int j = m_edges.at(i).previous;
- Q_ASSERT(j < m_edges.size());
- m_clockwiseOrder = qPointIsLeftOfLine(m_parent->m_vertices.at((quint32)m_edges.at(i).from),
- m_parent->m_vertices.at((quint32)m_edges.at(j).from), m_parent->m_vertices.at((quint32)m_edges.at(i).to));
-
- classifyVertices();
- fillPriorityQueue();
-
- // debug: set helpers explicitly (shouldn't be necessary)
- //for (int i = 0; i < m_edges.size(); ++i)
- // m_edges.at(i).helper = m_edges.at(i).upper();
-
- while (!m_upperVertex.isEmpty()) {
- i = m_upperVertex.last();
- Q_ASSERT(i < m_edges.size());
- m_upperVertex.pop_back();
- j = m_edges.at(i).previous;
- Q_ASSERT(j < m_edges.size());
-
- QRBTree<int>::Node *leftEdgeNode = 0;
-
- switch (m_edges.at(i).type) {
- case RegularVertex:
- // If polygon interior is to the right of the vertex...
- if (m_edges.at(i).pointingUp == m_clockwiseOrder) {
- if (m_edges.at(i).node) {
- Q_ASSERT(!m_edges.at(j).node);
- if (m_edges.at(m_edges.at(i).helper).type == MergeVertex)
- diagonals.add(QPair<int, int>(i, m_edges.at(i).helper));
- m_edges.at(j).node = m_edges.at(i).node;
- m_edges.at(i).node = 0;
- m_edges.at(j).node->data = j;
- m_edges.at(j).helper = i;
- } else if (m_edges.at(j).node) {
- Q_ASSERT(!m_edges.at(i).node);
- if (m_edges.at(m_edges.at(j).helper).type == MergeVertex)
- diagonals.add(QPair<int, int>(i, m_edges.at(j).helper));
- m_edges.at(i).node = m_edges.at(j).node;
- m_edges.at(j).node = 0;
- m_edges.at(i).node->data = i;
- m_edges.at(i).helper = i;
- } else {
- qWarning("Inconsistent polygon. (#1)");
- }
- } else {
- leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
- if (leftEdgeNode) {
- if (m_edges.at(m_edges.at(leftEdgeNode->data).helper).type == MergeVertex)
- diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
- m_edges.at(leftEdgeNode->data).helper = i;
- } else {
- qWarning("Inconsistent polygon. (#2)");
- }
- }
- break;
- case SplitVertex:
- leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
- if (leftEdgeNode) {
- diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
- m_edges.at(leftEdgeNode->data).helper = i;
- } else {
- qWarning("Inconsistent polygon. (#3)");
- }
- // Fall through.
- case StartVertex:
- if (m_clockwiseOrder) {
- leftEdgeNode = searchEdgeLeftOfEdge(j);
- QRBTree<int>::Node *node = m_edgeList.newNode();
- node->data = j;
- m_edges.at(j).node = node;
- m_edges.at(j).helper = i;
- m_edgeList.attachAfter(leftEdgeNode, node);
- Q_ASSERT(m_edgeList.validate());
- } else {
- leftEdgeNode = searchEdgeLeftOfEdge(i);
- QRBTree<int>::Node *node = m_edgeList.newNode();
- node->data = i;
- m_edges.at(i).node = node;
- m_edges.at(i).helper = i;
- m_edgeList.attachAfter(leftEdgeNode, node);
- Q_ASSERT(m_edgeList.validate());
- }
- break;
- case MergeVertex:
- leftEdgeNode = searchEdgeLeftOfPoint(m_edges.at(i).from);
- if (leftEdgeNode) {
- if (m_edges.at(m_edges.at(leftEdgeNode->data).helper).type == MergeVertex)
- diagonals.add(QPair<int, int>(i, m_edges.at(leftEdgeNode->data).helper));
- m_edges.at(leftEdgeNode->data).helper = i;
- } else {
- qWarning("Inconsistent polygon. (#4)");
- }
- // Fall through.
- case EndVertex:
- if (m_clockwiseOrder) {
- if (m_edges.at(m_edges.at(i).helper).type == MergeVertex)
- diagonals.add(QPair<int, int>(i, m_edges.at(i).helper));
- if (m_edges.at(i).node) {
- m_edgeList.deleteNode(m_edges.at(i).node);
- Q_ASSERT(m_edgeList.validate());
- } else {
- qWarning("Inconsistent polygon. (#5)");
- }
- } else {
- if (m_edges.at(m_edges.at(j).helper).type == MergeVertex)
- diagonals.add(QPair<int, int>(i, m_edges.at(j).helper));
- if (m_edges.at(j).node) {
- m_edgeList.deleteNode(m_edges.at(j).node);
- Q_ASSERT(m_edgeList.validate());
- } else {
- qWarning("Inconsistent polygon. (#6)");
- }
- }
- break;
- }
- }
-
- for (int i = 0; i < diagonals.size(); ++i)
- createDiagonal(diagonals.at(i).first, diagonals.at(i).second);
-}
-
-template <typename T>
-bool QTriangulator<T>::SimpleToMonotone::CompareVertices::operator () (int i, int j) const
-{
- if (m_parent->m_edges.at(i).from == m_parent->m_edges.at(j).from)
- return m_parent->m_edges.at(i).type > m_parent->m_edges.at(j).type;
- return m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(i).from) >
- m_parent->m_parent->m_vertices.at(m_parent->m_edges.at(j).from);
-}
-
-//============================================================================//
-// QTriangulator::MonotoneToTriangles //
-//============================================================================//
-template <typename T>
-void QTriangulator<T>::MonotoneToTriangles::decompose()
-{
- QVector<T> result;
- QDataBuffer<int> stack(m_parent->m_indices.size());
- m_first = 0;
- // Require at least three more indices.
- while (m_first + 3 <= m_parent->m_indices.size()) {
- m_length = 0;
- while (m_parent->m_indices.at(m_first + m_length) != T(-1)) { // Q_TRIANGULATE_END_OF_POLYGON
- ++m_length;
- Q_ASSERT(m_first + m_length < m_parent->m_indices.size());
- }
- if (m_length < 3) {
- m_first += m_length + 1;
- continue;
- }
-
- int minimum = 0;
- while (less(next(minimum), minimum))
- minimum = next(minimum);
- while (less(previous(minimum), minimum))
- minimum = previous(minimum);
-
- stack.reset();
- stack.add(minimum);
- int left = previous(minimum);
- int right = next(minimum);
- bool stackIsOnLeftSide;
- bool clockwiseOrder = leftOfEdge(minimum, left, right);
-
- if (less(left, right)) {
- stack.add(left);
- left = previous(left);
- stackIsOnLeftSide = true;
- } else {
- stack.add(right);
- right = next(right);
- stackIsOnLeftSide = false;
- }
-
- for (int count = 0; count + 2 < m_length; ++count)
- {
- Q_ASSERT(stack.size() >= 2);
- if (less(left, right)) {
- if (stackIsOnLeftSide == false) {
- for (int i = 0; i + 1 < stack.size(); ++i) {
- result.push_back(indices(stack.at(i + 1)));
- result.push_back(indices(left));
- result.push_back(indices(stack.at(i)));
- }
- stack.first() = stack.last();
- stack.resize(1);
- } else {
- while (stack.size() >= 2 && (clockwiseOrder ^ !leftOfEdge(left, stack.at(stack.size() - 2), stack.last()))) {
- result.push_back(indices(stack.at(stack.size() - 2)));
- result.push_back(indices(left));
- result.push_back(indices(stack.last()));
- stack.pop_back();
- }
- }
- stack.add(left);
- left = previous(left);
- stackIsOnLeftSide = true;
- } else {
- if (stackIsOnLeftSide == true) {
- for (int i = 0; i + 1 < stack.size(); ++i) {
- result.push_back(indices(stack.at(i)));
- result.push_back(indices(right));
- result.push_back(indices(stack.at(i + 1)));
- }
- stack.first() = stack.last();
- stack.resize(1);
- } else {
- while (stack.size() >= 2 && (clockwiseOrder ^ !leftOfEdge(right, stack.last(), stack.at(stack.size() - 2)))) {
- result.push_back(indices(stack.last()));
- result.push_back(indices(right));
- result.push_back(indices(stack.at(stack.size() - 2)));
- stack.pop_back();
- }
- }
- stack.add(right);
- right = next(right);
- stackIsOnLeftSide = false;
- }
- }
-
- m_first += m_length + 1;
- }
- m_parent->m_indices = result;
-}
-
-//============================================================================//
-// qTriangulate //
-//============================================================================//
-
-QTriangleSet qTriangulate(const qreal *polygon,
- int count, uint hint, const QTransform &matrix)
-{
- QTriangleSet triangleSet;
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
- QTriangulator<quint32> triangulator;
- triangulator.initialize(polygon, count, hint, matrix);
- QVertexSet<quint32> vertexSet = triangulator.triangulate();
- triangleSet.vertices = vertexSet.vertices;
- triangleSet.indices.setDataUint(vertexSet.indices);
-
- } else {
- QTriangulator<quint16> triangulator;
- triangulator.initialize(polygon, count, hint, matrix);
- QVertexSet<quint16> vertexSet = triangulator.triangulate();
- triangleSet.vertices = vertexSet.vertices;
- triangleSet.indices.setDataUshort(vertexSet.indices);
- }
- return triangleSet;
-}
-
-QTriangleSet qTriangulate(const QVectorPath &path,
- const QTransform &matrix, qreal lod)
-{
- QTriangleSet triangleSet;
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
- QTriangulator<quint32> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint32> vertexSet = triangulator.triangulate();
- triangleSet.vertices = vertexSet.vertices;
- triangleSet.indices.setDataUint(vertexSet.indices);
- } else {
- QTriangulator<quint16> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint16> vertexSet = triangulator.triangulate();
- triangleSet.vertices = vertexSet.vertices;
- triangleSet.indices.setDataUshort(vertexSet.indices);
- }
- return triangleSet;
-}
-
-QTriangleSet qTriangulate(const QPainterPath &path,
- const QTransform &matrix, qreal lod)
-{
- QTriangleSet triangleSet;
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
- QTriangulator<quint32> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint32> vertexSet = triangulator.triangulate();
- triangleSet.vertices = vertexSet.vertices;
- triangleSet.indices.setDataUint(vertexSet.indices);
- } else {
- QTriangulator<quint16> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint16> vertexSet = triangulator.triangulate();
- triangleSet.vertices = vertexSet.vertices;
- triangleSet.indices.setDataUshort(vertexSet.indices);
- }
- return triangleSet;
-}
-
-QPolylineSet qPolyline(const QVectorPath &path,
- const QTransform &matrix, qreal lod)
-{
- QPolylineSet polyLineSet;
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
- QTriangulator<quint32> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint32> vertexSet = triangulator.polyline();
- polyLineSet.vertices = vertexSet.vertices;
- polyLineSet.indices.setDataUint(vertexSet.indices);
- } else {
- QTriangulator<quint16> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint16> vertexSet = triangulator.polyline();
- polyLineSet.vertices = vertexSet.vertices;
- polyLineSet.indices.setDataUshort(vertexSet.indices);
- }
- return polyLineSet;
-}
-
-QPolylineSet qPolyline(const QPainterPath &path,
- const QTransform &matrix, qreal lod)
-{
- QPolylineSet polyLineSet;
- if (QGLExtensions::glExtensions() & QGLExtensions::ElementIndexUint) {
- QTriangulator<quint32> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint32> vertexSet = triangulator.polyline();
- polyLineSet.vertices = vertexSet.vertices;
- polyLineSet.indices.setDataUint(vertexSet.indices);
- } else {
- QTriangulator<quint16> triangulator;
- triangulator.initialize(path, matrix, lod);
- QVertexSet<quint16> vertexSet = triangulator.polyline();
- polyLineSet.vertices = vertexSet.vertices;
- polyLineSet.indices.setDataUshort(vertexSet.indices);
- }
- return polyLineSet;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/gl2paintengineex/qtriangulator_p.h b/src/opengl/gl2paintengineex/qtriangulator_p.h
deleted file mode 100644
index 04a219c255..0000000000
--- a/src/opengl/gl2paintengineex/qtriangulator_p.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QTRIANGULATOR_P_H
-#define QTRIANGULATOR_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qvector.h>
-#include <QtGui/private/qvectorpath_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_OPENGL_EXPORT QVertexIndexVector
-{
-public:
- enum Type {
- UnsignedInt,
- UnsignedShort
- };
-
- inline Type type() const { return t; }
-
- inline void setDataUint(const QVector<quint32> &data)
- {
- t = UnsignedInt;
- indices32 = data;
- }
-
- inline void setDataUshort(const QVector<quint16> &data)
- {
- t = UnsignedShort;
- indices16 = data;
- }
-
- inline const void* data() const
- {
- if (t == UnsignedInt)
- return indices32.data();
- return indices16.data();
- }
-
- inline int size() const
- {
- if (t == UnsignedInt)
- return indices32.size();
- return indices16.size();
- }
-
- inline QVertexIndexVector &operator = (const QVertexIndexVector &other)
- {
- if (t == UnsignedInt)
- indices32 = other.indices32;
- else
- indices16 = other.indices16;
-
- return *this;
- }
-
-private:
-
- Type t;
- QVector<quint32> indices32;
- QVector<quint16> indices16;
-};
-
-struct Q_OPENGL_EXPORT QTriangleSet
-{
- inline QTriangleSet() { }
- inline QTriangleSet(const QTriangleSet &other) : vertices(other.vertices), indices(other.indices) { }
- QTriangleSet &operator = (const QTriangleSet &other) {vertices = other.vertices; indices = other.indices; return *this;}
-
- // The vertices of a triangle are given by: (x[i[n]], y[i[n]]), (x[j[n]], y[j[n]]), (x[k[n]], y[k[n]]), n = 0, 1, ...
- QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
- QVertexIndexVector indices; // [i[0], j[0], k[0], i[1], j[1], k[1], i[2], ...]
-};
-
-struct Q_OPENGL_EXPORT QPolylineSet
-{
- inline QPolylineSet() { }
- inline QPolylineSet(const QPolylineSet &other) : vertices(other.vertices), indices(other.indices) { }
- QPolylineSet &operator = (const QPolylineSet &other) {vertices = other.vertices; indices = other.indices; return *this;}
-
- QVector<qreal> vertices; // [x[0], y[0], x[1], y[1], x[2], ...]
- QVertexIndexVector indices; // End of polyline is marked with -1.
-};
-
-// The vertex coordinates of the returned triangle set will be rounded to a grid with a mesh size
-// of 1/32. The polygon is first transformed, then scaled by 32, the coordinates are rounded to
-// integers, the polygon is triangulated, and then scaled back by 1/32.
-// 'hint' should be a combination of QVectorPath::Hints.
-// 'lod' is the level of detail. Default is 1. Curves are split into more lines when 'lod' is higher.
-QTriangleSet qTriangulate(const qreal *polygon, int count, uint hint = QVectorPath::PolygonHint | QVectorPath::OddEvenFill, const QTransform &matrix = QTransform());
-QTriangleSet qTriangulate(const QVectorPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
-QTriangleSet Q_OPENGL_EXPORT qTriangulate(const QPainterPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
-QPolylineSet qPolyline(const QVectorPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
-QPolylineSet Q_OPENGL_EXPORT qPolyline(const QPainterPath &path, const QTransform &matrix = QTransform(), qreal lod = 1);
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro
index e2dc011532..658cdd5eb4 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -2,7 +2,7 @@ load(qt_module)
TARGET = QtOpenGL
QPRO_PWD = $$PWD
-QT = core-private gui-private
+QT = core-private gui-private widgets-private
CONFIG += module
MODULE_PRI = ../modules/qt_opengl.pri
@@ -19,7 +19,7 @@ load(qt_module_config)
HEADERS += $$QT_SOURCE_TREE/src/opengl/qtopenglversion.h
-!win32:!embedded:!mac:!symbian:!qpa:CONFIG += x11
+!win32:!embedded:!mac:!qpa:CONFIG += x11
contains(QT_CONFIG, opengl):CONFIG += opengl
contains(QT_CONFIG, opengles1):CONFIG += opengles1
contains(QT_CONFIG, opengles2):CONFIG += opengles2
@@ -47,144 +47,32 @@ SOURCES += qgl.cpp \
qglpaintdevice.cpp \
qglbuffer.cpp \
-
-!contains(QT_CONFIG, opengles2) {
- HEADERS += qpaintengine_opengl_p.h
- SOURCES += qpaintengine_opengl.cpp
-}
-
-!contains(QT_CONFIG, opengles1) {
- HEADERS += qglshaderprogram.h \
- qglpixmapfilter_p.h \
- qgraphicsshadereffect_p.h \
- qgraphicssystem_gl_p.h \
- qwindowsurface_gl_p.h \
- qpixmapdata_gl_p.h \
- gl2paintengineex/qglgradientcache_p.h \
- gl2paintengineex/qglengineshadermanager_p.h \
- gl2paintengineex/qgl2pexvertexarray_p.h \
- gl2paintengineex/qpaintengineex_opengl2_p.h \
- gl2paintengineex/qglengineshadersource_p.h \
- gl2paintengineex/qglcustomshaderstage_p.h \
- gl2paintengineex/qtriangulatingstroker_p.h \
- gl2paintengineex/qtriangulator_p.h \
- gl2paintengineex/qrbtree_p.h \
- gl2paintengineex/qtextureglyphcache_gl_p.h \
- gl2paintengineex/qglshadercache_p.h \
- gl2paintengineex/qglshadercache_meego_p.h
-
- SOURCES += qglshaderprogram.cpp \
- qglpixmapfilter.cpp \
- qgraphicsshadereffect.cpp \
- qgraphicssystem_gl.cpp \
- qwindowsurface_gl.cpp \
- qpixmapdata_gl.cpp \
- gl2paintengineex/qglgradientcache.cpp \
- gl2paintengineex/qglengineshadermanager.cpp \
- gl2paintengineex/qgl2pexvertexarray.cpp \
- gl2paintengineex/qpaintengineex_opengl2.cpp \
- gl2paintengineex/qglcustomshaderstage.cpp \
- gl2paintengineex/qtriangulatingstroker.cpp \
- gl2paintengineex/qtriangulator.cpp \
- gl2paintengineex/qtextureglyphcache_gl.cpp
-
-}
-
-qpa {
- SOURCES += qgl_qpa.cpp \
- qglpixelbuffer_stub.cpp
-}
-
-x11 {
- contains(QT_CONFIG, egl) {
- SOURCES += qgl_x11egl.cpp \
- qglpixelbuffer_egl.cpp \
- qgl_egl.cpp \
- qpixmapdata_x11gl_egl.cpp \
- qwindowsurface_x11gl.cpp
-
- HEADERS += qgl_egl_p.h \
- qpixmapdata_x11gl_p.h \
- qwindowsurface_x11gl_p.h
-
- } else {
- SOURCES += qgl_x11.cpp \
- qglpixelbuffer_x11.cpp
- }
-
- contains(QT_CONFIG, fontconfig) {
- contains(QT_CONFIG, system-freetype) {
- embedded:CONFIG += opentype
- # pull in the proper freetype2 include directory
- include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri)
- LIBS_PRIVATE += -lfreetype
- } else {
- ### Note: how does this compile with a non-system freetype?
- # This probably does not compile
- }
- } else {
- DEFINES *= QT_NO_FREETYPE
- }
-
- LIBS_PRIVATE += $$QMAKE_LIBS_DYNLOAD
-}
-
-mac:!qpa {
- OBJECTIVE_SOURCES += qgl_mac.mm \
- qglpixelbuffer_mac.mm
- LIBS_PRIVATE += -framework AppKit -framework Carbon
-}
-win32:!wince*: {
- DEFINES += QT_NO_EGL
- SOURCES += qgl_win.cpp \
- qglpixelbuffer_win.cpp
-}
-wince*: {
- SOURCES += qgl_wince.cpp \
- qglpixelbuffer_egl.cpp \
- qgl_egl.cpp
-
- HEADERS += qgl_egl_p.h
-}
-
-embedded {
- SOURCES += qgl_qws.cpp \
- qglpixelbuffer_egl.cpp \
- qglscreen_qws.cpp \
- qglwindowsurface_qws.cpp \
- qgl_egl.cpp
-
- HEADERS += qglscreen_qws.h \
- qglwindowsurface_qws_p.h \
- qgl_egl_p.h
-
- contains(QT_CONFIG, fontconfig) {
- include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri)
- } else {
- DEFINES *= QT_NO_FREETYPE
- }
-}
-
-symbian {
- DEFINES += QGL_USE_TEXTURE_POOL QGL_NO_PRESERVED_SWAP
- SOURCES -= qpixmapdata_gl.cpp
- SOURCES += qgl_symbian.cpp \
- qpixmapdata_poolgl.cpp \
- qglpixelbuffer_egl.cpp \
- qgl_egl.cpp \
- qgltexturepool.cpp
-
- HEADERS += qgl_egl_p.h \
- qgltexturepool_p.h
-
- contains(QT_CONFIG, freetype) {
- DEFINES += QT_NO_FONTCONFIG
- INCLUDEPATH += \
- ../3rdparty/freetype/src \
- ../3rdparty/freetype/include
- }
-
- symbian:TARGET.UID3 = 0x2002131A
-}
+HEADERS += qglshaderprogram.h \
+ qgraphicsshadereffect_p.h \
+ gl2paintengineex/qglgradientcache_p.h \
+ gl2paintengineex/qglengineshadermanager_p.h \
+ gl2paintengineex/qgl2pexvertexarray_p.h \
+ gl2paintengineex/qpaintengineex_opengl2_p.h \
+ gl2paintengineex/qglengineshadersource_p.h \
+ gl2paintengineex/qglcustomshaderstage_p.h \
+ gl2paintengineex/qtriangulatingstroker_p.h \
+ gl2paintengineex/qtextureglyphcache_gl_p.h \
+ gl2paintengineex/qglshadercache_p.h \
+ gl2paintengineex/qglshadercache_meego_p.h
+
+SOURCES += qglshaderprogram.cpp \
+ qgraphicsshadereffect.cpp \
+ gl2paintengineex/qglgradientcache.cpp \
+ gl2paintengineex/qglengineshadermanager.cpp \
+ gl2paintengineex/qgl2pexvertexarray.cpp \
+ gl2paintengineex/qpaintengineex_opengl2.cpp \
+ gl2paintengineex/qglcustomshaderstage.cpp \
+ gl2paintengineex/qtriangulatingstroker.cpp \
+ gl2paintengineex/qtextureglyphcache_gl.cpp
+
+SOURCES += qgl_qpa.cpp \
+ qglpixelbuffer_stub.cpp
+
+DEFINES += QT_NO_EGL
INCLUDEPATH += ../3rdparty/harfbuzz/src
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index f1fb2b4e7f..ad53b20098 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -45,21 +45,6 @@
#include <qdebug.h>
#include <qglfunctions.h>
-#if defined(Q_WS_X11)
-#include "private/qt_x11_p.h"
-#include "private/qpixmap_x11_p.h"
-#define INT32 dummy_INT32
-#define INT8 dummy_INT8
-#ifdef QT_NO_EGL
-# include <GL/glx.h>
-#endif
-#undef INT32
-#undef INT8
-#include "qx11info_x11.h"
-#elif defined(Q_WS_MAC)
-# include <private/qt_mac_p.h>
-#endif
-
#include <qdatetime.h>
#include <stdlib.h> // malloc
@@ -68,29 +53,15 @@
#include "qimage.h"
#include "qgl_p.h"
-#if !defined(QT_OPENGL_ES_1)
#include "gl2paintengineex/qpaintengineex_opengl2_p.h"
-#include <private/qwindowsurface_gl_p.h>
-#endif
-
-#ifndef QT_OPENGL_ES_2
-#include <private/qpaintengine_opengl_p.h>
-#endif
-#ifdef Q_WS_QWS
-#include <private/qglwindowsurface_qws_p.h>
-#endif
-
-#ifdef Q_WS_QPA
-#include <QtGui/QPlatformGLContext>
-#endif
+#include <QtGui/QPlatformOpenGLContext>
#include <qglpixelbuffer.h>
#include <qglframebufferobject.h>
#include <private/qimage_p.h>
-#include <private/qpixmapdata_p.h>
-#include <private/qpixmapdata_gl_p.h>
+#include <qplatformpixmap_qpa.h>
#include <private/qglpixelbuffer_p.h>
#include <private/qimagepixmapcleanuphooks_p.h>
#include "qcolormap.h"
@@ -98,24 +69,11 @@
#include "qlibrary.h"
#include <qmutex.h>
-#if defined(QT_OPENGL_ES) && !defined(QT_NO_EGL)
-#include <EGL/egl.h>
-#endif
-#ifdef QGL_USE_TEXTURE_POOL
-#include <private/qgltexturepool_p.h>
-#endif
-
// #define QT_GL_CONTEXT_RESOURCE_DEBUG
QT_BEGIN_NAMESPACE
-#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs;
-#endif
-
-#ifdef Q_WS_X11
-extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
-#endif
struct QGLThreadContext {
~QGLThreadContext() {
@@ -125,10 +83,6 @@ struct QGLThreadContext {
QGLContext *context;
};
-#ifndef Q_WS_QPA
-static QThreadStorage<QGLThreadContext *> qgl_context_storage;
-#endif
-
Q_GLOBAL_STATIC(QGLFormat, qgl_default_format)
class QGLDefaultOverlayFormat: public QGLFormat
@@ -155,71 +109,6 @@ QGLSignalProxy *QGLSignalProxy::instance()
}
-class QGLEngineSelector
-{
-public:
- QGLEngineSelector() : engineType(QPaintEngine::MaxUser)
- {
- }
-
- void setPreferredPaintEngine(QPaintEngine::Type type) {
- if (type == QPaintEngine::OpenGL || type == QPaintEngine::OpenGL2)
- engineType = type;
- }
-
- QPaintEngine::Type preferredPaintEngine() {
-#ifdef Q_WS_MAC
- // The ATI X1600 driver for Mac OS X does not support return
- // values from functions in GLSL. Since working around this in
- // the GL2 engine would require a big, ugly rewrite, we're
- // falling back to the GL 1 engine..
- static bool mac_x1600_check_done = false;
- if (!mac_x1600_check_done) {
- QGLTemporaryContext *tmp = 0;
- if (!QGLContext::currentContext())
- tmp = new QGLTemporaryContext();
- if (strstr((char *) glGetString(GL_RENDERER), "X1600"))
- engineType = QPaintEngine::OpenGL;
- if (tmp)
- delete tmp;
- mac_x1600_check_done = true;
- }
-#endif
- if (engineType == QPaintEngine::MaxUser) {
- // No user-set engine - use the defaults
-#if defined(QT_OPENGL_ES_2)
- engineType = QPaintEngine::OpenGL2;
-#else
- // We can't do this in the constructor for this object because it
- // needs to be called *before* the QApplication constructor.
- // Also check for the FragmentShader extension in conjunction with
- // the 2.0 version flag, to cover the case where we export the display
- // from an old GL 1.1 server to a GL 2.x client. In that case we can't
- // use GL 2.0.
- if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)
- && (QGLExtensions::glExtensions() & QGLExtensions::FragmentShader)
- && qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty())
- engineType = QPaintEngine::OpenGL2;
- else
- engineType = QPaintEngine::OpenGL;
-#endif
- }
- return engineType;
- }
-
-private:
- QPaintEngine::Type engineType;
-};
-
-Q_GLOBAL_STATIC(QGLEngineSelector, qgl_engine_selector)
-
-
-bool qt_gl_preferGL2Engine()
-{
- return qgl_engine_selector()->preferredPaintEngine() == QPaintEngine::OpenGL2;
-}
-
-
/*!
\namespace QGL
\inmodule QtOpenGL
@@ -266,32 +155,6 @@ bool qt_gl_preferGL2Engine()
\sa {Sample Buffers Example}
*/
-/*!
- \fn void QGL::setPreferredPaintEngine(QPaintEngine::Type engineType)
-
- \since 4.6
-
- Sets the preferred OpenGL paint engine that is used to draw onto
- QGLWidget, QGLPixelBuffer and QGLFramebufferObject targets with QPainter
- in Qt.
-
- The \a engineType parameter specifies which of the GL engines to
- use. Only \c QPaintEngine::OpenGL and \c QPaintEngine::OpenGL2 are
- valid parameters to this function. All other values are ignored.
-
- By default, the \c QPaintEngine::OpenGL2 engine is used if GL/GLES
- version 2.0 is available, otherwise \c QPaintEngine::OpenGL is
- used.
-
- \warning This function must be called before the QApplication
- constructor is called.
-*/
-void QGL::setPreferredPaintEngine(QPaintEngine::Type engineType)
-{
- qgl_engine_selector()->setPreferredPaintEngine(engineType);
-}
-
-
/*****************************************************************************
QGLFormat implementation
*****************************************************************************/
@@ -1613,42 +1476,16 @@ Q_GLOBAL_STATIC(QGLContextGroupList, qt_context_groups)
*****************************************************************************/
QGLContextGroup::QGLContextGroup(const QGLContext *context)
- : m_context(context), m_guards(0), m_refs(1)
+ : m_context(context), m_refs(1)
{
qt_context_groups()->append(this);
}
QGLContextGroup::~QGLContextGroup()
{
- // Clear any remaining QGLSharedResourceGuard objects on the group.
- QGLSharedResourceGuard *guard = m_guards;
- while (guard != 0) {
- guard->m_group = 0;
- guard->m_id = 0;
- guard = guard->m_next;
- }
qt_context_groups()->remove(this);
}
-void QGLContextGroup::addGuard(QGLSharedResourceGuard *guard)
-{
- if (m_guards)
- m_guards->m_prev = guard;
- guard->m_next = m_guards;
- guard->m_prev = 0;
- m_guards = guard;
-}
-
-void QGLContextGroup::removeGuard(QGLSharedResourceGuard *guard)
-{
- if (guard->m_next)
- guard->m_next->m_prev = guard->m_prev;
- if (guard->m_prev)
- guard->m_prev->m_next = guard->m_next;
- else
- m_guards = guard->m_next;
-}
-
const QGLContext *qt_gl_transfer_context(const QGLContext *ctx)
{
if (!ctx)
@@ -1664,11 +1501,15 @@ const QGLContext *qt_gl_transfer_context(const QGLContext *ctx)
QGLContextPrivate::QGLContextPrivate(QGLContext *context)
: internal_context(false)
, q_ptr(context)
+ , texture_destroyer(0)
, functions(0)
{
group = new QGLContextGroup(context);
- texture_destroyer = new QGLTextureDestroyer;
- texture_destroyer->moveToThread(qApp->thread());
+
+ if (qApp) {
+ texture_destroyer = new QGLTextureDestroyer;
+ texture_destroyer->moveToThread(qApp->thread());
+ }
}
QGLContextPrivate::~QGLContextPrivate()
@@ -1689,35 +1530,9 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
glFormat = reqFormat = format;
valid = false;
q->setDevice(dev);
-#if defined(Q_WS_X11)
- pbuf = 0;
- gpm = 0;
- vi = 0;
- screen = QX11Info::appScreen();
-#endif
-#if defined(Q_WS_WIN)
- dc = 0;
- win = 0;
- threadId = 0;
- pixelFormatId = 0;
- cmap = 0;
- hbitmap = 0;
- hbitmap_hdc = 0;
-#endif
-#if defined(Q_WS_MAC)
-# ifndef QT_MAC_USE_COCOA
- update = false;
-# endif
- vi = 0;
-#endif
-#if defined(Q_WS_QPA)
- platformContext = 0;
-#endif
-#if !defined(QT_NO_EGL)
- ownsEglContext = false;
- eglContext = 0;
- eglSurface = EGL_NO_SURFACE;
-#endif
+
+ guiGlContext = 0;
+ ownContext = false;
fbo = 0;
crWin = false;
initDone = false;
@@ -1795,7 +1610,7 @@ static void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, boo
img = img.mirrored();
}
-Q_OPENGL_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
+QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha)
{
QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied
: QImage::Format_RGB32);
@@ -1811,7 +1626,7 @@ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alp
QImage img(size, alpha_format ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32);
int w = size.width();
int h = size.height();
-#if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_ES_1)
+#if !defined(QT_OPENGL_ES_2)
//### glGetTexImage not in GL ES 2.0, need to do something else here!
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
#endif
@@ -1845,15 +1660,15 @@ Q_GLOBAL_STATIC(QGLTextureCache, qt_gl_texture_cache)
QGLTextureCache::QGLTextureCache()
: m_cache(64*1024) // cache ~64 MB worth of textures - this is not accurate though
{
- QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTexturesForPixampData);
- QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(cleanupBeforePixmapDestruction);
+ QImagePixmapCleanupHooks::instance()->addPlatformPixmapModificationHook(cleanupTexturesForPixampData);
+ QImagePixmapCleanupHooks::instance()->addPlatformPixmapDestructionHook(cleanupBeforePixmapDestruction);
QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey);
}
QGLTextureCache::~QGLTextureCache()
{
- QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTexturesForPixampData);
- QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction);
+ QImagePixmapCleanupHooks::instance()->removePlatformPixmapModificationHook(cleanupTexturesForPixampData);
+ QImagePixmapCleanupHooks::instance()->removePlatformPixmapDestructionHook(cleanupBeforePixmapDestruction);
QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey);
}
@@ -1912,22 +1727,15 @@ void QGLTextureCache::cleanupTexturesForCacheKey(qint64 cacheKey)
}
-void QGLTextureCache::cleanupTexturesForPixampData(QPixmapData* pmd)
+void QGLTextureCache::cleanupTexturesForPixampData(QPlatformPixmap* pmd)
{
cleanupTexturesForCacheKey(pmd->cacheKey());
}
-void QGLTextureCache::cleanupBeforePixmapDestruction(QPixmapData* pmd)
+void QGLTextureCache::cleanupBeforePixmapDestruction(QPlatformPixmap* pmd)
{
// Remove any bound textures first:
cleanupTexturesForPixampData(pmd);
-
-#if defined(Q_WS_X11)
- if (pmd->classId() == QPixmapData::X11Class) {
- Q_ASSERT(pmd->ref == 0); // Make sure reference counting isn't broken
- QGLContextPrivate::destroyGlSurfaceForPixmap(pmd);
- }
-#endif
}
QGLTextureCache *QGLTextureCache::instance()
@@ -2105,8 +1913,6 @@ QGLContext::~QGLContext()
// clean up resources specific to this context
d_ptr->cleanup();
- // clean up resources belonging to this context's group
- d_ptr->group->cleanupResources(this);
QGLSignalProxy::instance()->emitAboutToDestroyContext(this);
reset();
@@ -2114,10 +1920,6 @@ QGLContext::~QGLContext()
void QGLContextPrivate::cleanup()
{
- QHash<QGLContextResourceBase *, void *>::ConstIterator it;
- for (it = m_resources.begin(); it != m_resources.end(); ++it)
- it.key()->freeResource(it.value());
- m_resources.clear();
}
#define ctx q_ptr
@@ -2152,13 +1954,11 @@ void QGLContextPrivate::syncGlState()
}
#undef ctx
-#ifdef QT_NO_EGL
void QGLContextPrivate::swapRegion(const QRegion &)
{
Q_Q(QGLContext);
q->swapBuffers();
}
-#endif
/*!
\overload
@@ -2303,12 +2103,10 @@ static void convertToGLFormatHelper(QImage &dst, const QImage &img, GLenum textu
}
}
-#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
QGLExtensionFuncs& QGLContextPrivate::extensionFuncs(const QGLContext *)
{
return qt_extensionFuncs;
}
-#endif
QImage QGLContextPrivate::convertToGLFormat(const QImage &image, bool force_premul,
GLenum texture_format)
@@ -2547,18 +2345,8 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
#endif
const QImage &constRef = img; // to avoid detach in bits()...
-#ifdef QGL_USE_TEXTURE_POOL
- QGLTexturePool::instance()->createPermanentTexture(tx_id,
- target,
- 0, internalFormat,
- img.width(), img.height(),
- externalFormat,
- pixel_type,
- constRef.bits());
-#else
glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat,
pixel_type, constRef.bits());
-#endif
#if defined(QT_OPENGL_ES_2)
if (genMipmap)
glGenerateMipmap(target);
@@ -2601,19 +2389,8 @@ QGLTexture *QGLContextPrivate::textureCacheLookup(const qint64 key, GLenum targe
QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, QGLContext::BindOptions options)
{
Q_Q(QGLContext);
- QPixmapData *pd = pixmap.pixmapData();
-#if !defined(QT_OPENGL_ES_1)
- if (target == GL_TEXTURE_2D && pd->classId() == QPixmapData::OpenGLClass) {
- const QGLPixmapData *data = static_cast<const QGLPixmapData *>(pd);
-
- if (data->isValidContext(q)) {
- data->bind();
- return data->texture();
- }
- }
-#else
+ QPlatformPixmap *pd = pixmap.handle();
Q_UNUSED(pd);
-#endif
const qint64 key = pixmap.cacheKey();
QGLTexture *texture = textureCacheLookup(key, target);
@@ -2628,39 +2405,6 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target,
}
}
-#if defined(Q_WS_X11)
- // Try to use texture_from_pixmap
- const QX11Info *xinfo = qt_x11Info(paintDevice);
- if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType
- && xinfo && xinfo->screen() == pixmap.x11Info().screen()
- && target == GL_TEXTURE_2D
- && QApplication::instance()->thread() == QThread::currentThread())
- {
- if (!workaround_brokenTextureFromPixmap_init) {
- workaround_brokenTextureFromPixmap_init = true;
-
- const QByteArray versionString(reinterpret_cast<const char*>(glGetString(GL_VERSION)));
- const int pos = versionString.indexOf("NVIDIA ");
-
- if (pos >= 0) {
- const QByteArray nvidiaVersionString = versionString.mid(pos + strlen("NVIDIA "));
-
- if (nvidiaVersionString.startsWith("195") || nvidiaVersionString.startsWith("256"))
- workaround_brokenTextureFromPixmap = true;
- }
- }
-
- if (!workaround_brokenTextureFromPixmap) {
- texture = bindTextureFromNativePixmap(const_cast<QPixmap*>(&pixmap), key, options);
- if (texture) {
- texture->options |= QGLContext::MemoryManagedBindOption;
- texture->boundPixmap = pd;
- boundPixmaps.insert(pd, QPixmap(pixmap));
- }
- }
- }
-#endif
-
if (!texture) {
QImage image = pixmap.toImage();
// If the system depth is 16 and the pixmap doesn't have an alpha channel
@@ -2779,31 +2523,6 @@ GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format,
return texture->id;
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format)
-{
- if (image.isNull())
- return 0;
-
- Q_D(QGLContext);
- QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), DefaultBindOption);
- return texture->id;
-}
-
-/*! \internal */
-GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format,
- BindOptions options)
-{
- if (image.isNull())
- return 0;
-
- Q_D(QGLContext);
- QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), options);
- return texture->id;
-}
-#endif
-
/*! \overload
Generates and binds a 2D GL texture based on \a pixmap.
@@ -2835,30 +2554,6 @@ GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint forma
return texture->id;
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format)
-{
- if (pixmap.isNull())
- return 0;
-
- Q_D(QGLContext);
- QGLTexture *texture = d->bindTexture(pixmap, GLenum(target), GLint(format), DefaultBindOption);
- return texture->id;
-}
-/*! \internal */
-GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format,
- BindOptions options)
-{
- if (pixmap.isNull())
- return 0;
-
- Q_D(QGLContext);
- QGLTexture *texture = d->bindTexture(pixmap, GLenum(target), GLint(format), options);
- return texture->id;
-}
-#endif
-
/*!
Removes the texture identified by \a id from the texture cache,
and calls glDeleteTextures() to delete the texture from the
@@ -2873,14 +2568,6 @@ void QGLContext::deleteTexture(GLuint id)
glDeleteTextures(1, &id);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLContext::deleteTexture(QMacCompatGLuint id)
-{
- return deleteTexture(GLuint(id));
-}
-#endif
-
void qt_add_rect_to_array(const QRectF &r, GLfloat *array)
{
qreal left = r.left();
@@ -3020,14 +2707,6 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
#endif
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLContext::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- drawTexture(target, GLuint(textureId), GLenum(textureTarget));
-}
-#endif
-
/*!
\since 4.4
@@ -3091,15 +2770,6 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text
#endif
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLContext::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- drawTexture(point, GLuint(textureId), GLenum(textureTarget));
-}
-#endif
-
-
/*!
This function sets the limit for the texture cache to \a size,
expressed in kilobytes.
@@ -3329,11 +2999,7 @@ bool QGLContext::areSharing(const QGLContext *context1, const QGLContext *contex
bool QGLContext::create(const QGLContext* shareContext)
{
Q_D(QGLContext);
-#ifdef Q_WS_QPA
- if (!d->paintDevice && !d->platformContext)
-#else
- if (!d->paintDevice)
-#endif
+ if (!d->paintDevice && !d->guiGlContext)
return false;
reset();
@@ -3342,10 +3008,6 @@ bool QGLContext::create(const QGLContext* shareContext)
QWidgetPrivate *wd = qt_widget_private(static_cast<QWidget *>(d->paintDevice));
wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer();
}
-#ifndef Q_WS_QPA //We do this in choose context->setupSharing()
- if (d->sharing) // ok, we managed to share
- QGLContextGroup::addShare(this, shareContext);
-#endif
return d->valid;
}
@@ -3419,37 +3081,15 @@ void QGLContext::setInitialized(bool on)
const QGLContext* QGLContext::currentContext()
{
-#ifdef Q_WS_QPA
- if (const QPlatformGLContext *threadContext = QPlatformGLContext::currentContext()) {
- return QGLContext::fromPlatformGLContext(const_cast<QPlatformGLContext *>(threadContext));
+ if (const QOpenGLContext *threadContext = QOpenGLContext::currentContext()) {
+ return QGLContext::fromOpenGLContext(const_cast<QOpenGLContext *>(threadContext));
}
return 0;
-#else
- QGLThreadContext *threadContext = qgl_context_storage.localData();
- if (threadContext)
- return threadContext->context;
- return 0;
-#endif //Q_WS_QPA
}
void QGLContextPrivate::setCurrentContext(QGLContext *context)
{
-#ifdef Q_WS_QPA
Q_UNUSED(context);
-#else
- QGLThreadContext *threadContext = qgl_context_storage.localData();
- if (!threadContext) {
- if (!QThread::currentThread()) {
- // We don't have a current QThread, so just set the static.
- QGLContext::currentCtx = context;
- return;
- }
- threadContext = new QGLThreadContext;
- qgl_context_storage.setLocalData(threadContext);
- }
- threadContext->context = context;
- QGLContext::currentCtx = context; // XXX: backwards-compat, not thread-safe
-#endif
}
/*!
@@ -3761,11 +3401,6 @@ void QGLContextPrivate::setCurrentContext(QGLContext *context)
on a QGLWidget and the widget's rendering context is current in
another thread, it will fail.
- Note that under X11 it is necessary to set the
- Qt::AA_X11InitThreads application attribute to make the X11
- library and GLX calls thread safe, otherwise the above scenarios
- will fail.
-
In addition to this, rendering using raw GL calls in a separate
thread is supported.
@@ -3906,30 +3541,9 @@ QGLWidget::QGLWidget(QGLContext *context, QWidget *parent, const QGLWidget *shar
QGLWidget::~QGLWidget()
{
Q_D(QGLWidget);
-#if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
- bool doRelease = (glcx && glcx->windowCreated());
-#endif
delete d->glcx;
d->glcx = 0;
-#if defined(Q_WS_WIN)
- delete d->olcx;
- d->olcx = 0;
-#endif
-#if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
- if (doRelease)
- glXReleaseBuffersMESA(x11Display(), winId());
-#endif
d->cleanupColormaps();
-
-#ifdef Q_WS_MAC
- QWidget *current = parentWidget();
- while (current) {
- qt_widget_private(current)->glWidgets.removeAll(QWidgetPrivate::GlWidgetInfo(this));
- if (current->isWindow())
- break;
- current = current->parentWidget();
- };
-#endif
}
/*!
@@ -4275,125 +3889,6 @@ void QGLWidget::resizeOverlayGL(int, int)
{
}
-/*! \fn bool QGLWidget::event(QEvent *e)
- \reimp
-*/
-#if !defined(Q_OS_WINCE) && !defined(Q_WS_QWS) && !defined(Q_WS_QPA)
-bool QGLWidget::event(QEvent *e)
-{
- Q_D(QGLWidget);
-
- if (e->type() == QEvent::Paint) {
- QPoint offset;
- QPaintDevice *redirectedDevice = d->redirected(&offset);
- if (redirectedDevice && redirectedDevice->devType() == QInternal::Pixmap) {
- d->restoreRedirected();
- QPixmap pixmap = renderPixmap();
- d->setRedirected(redirectedDevice, offset);
- QPainter p(redirectedDevice);
- p.drawPixmap(-offset, pixmap);
- return true;
- }
- }
-
-#if defined(Q_WS_X11)
- if (e->type() == QEvent::ParentChange) {
- // if we've reparented a window that has the current context
- // bound, we need to rebind that context to the new window id
- if (d->glcx == QGLContext::currentContext())
- makeCurrent();
-
- if (d->glcx->d_func()->screen != d->xinfo.screen() || testAttribute(Qt::WA_TranslucentBackground)) {
- setContext(new QGLContext(d->glcx->requestedFormat(), this));
- // ### recreating the overlay isn't supported atm
- }
- }
-
-#ifndef QT_NO_EGL
- // A re-parent is likely to destroy the X11 window and re-create it. It is important
- // that we free the EGL surface _before_ the winID changes - otherwise we can leak.
- if (e->type() == QEvent::ParentAboutToChange)
- d->glcx->d_func()->destroyEglSurfaceForDevice();
-
- if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) {
- // The window may have been re-created during re-parent or state change - if so, the EGL
- // surface will need to be re-created.
- d->recreateEglSurface();
- }
-#endif
-#elif defined(Q_WS_WIN)
- if (e->type() == QEvent::ParentChange) {
- QGLContext *newContext = new QGLContext(d->glcx->requestedFormat(), this);
- setContext(newContext, d->glcx);
-
- // the overlay needs to be recreated as well
- delete d->olcx;
- if (isValid() && context()->format().hasOverlay()) {
- d->olcx = new QGLContext(QGLFormat::defaultOverlayFormat(), this);
- if (!d->olcx->create(isSharing() ? d->glcx : 0)) {
- delete d->olcx;
- d->olcx = 0;
- d->glcx->d_func()->glFormat.setOverlay(false);
- }
- } else {
- d->olcx = 0;
- }
- } else if (e->type() == QEvent::Show) {
- if (!format().rgba())
- d->updateColormap();
- }
-#elif defined(Q_WS_MAC)
- if (e->type() == QEvent::MacGLWindowChange
-#if 0 //(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
- && ((QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 && isWindow())
- || QSysInfo::MacintoshVersion <= QSysInfo::MV_10_4)
-#endif
- ) {
- if (d->needWindowChange) {
- d->needWindowChange = false;
- d->glcx->updatePaintDevice();
- update();
- }
- return true;
-# if defined(QT_MAC_USE_COCOA)
- } else if (e->type() == QEvent::MacGLClearDrawable) {
- d->glcx->d_ptr->clearDrawable();
-# endif
- }
-#elif defined(Q_OS_SYMBIAN)
- // prevents errors on some systems, where we get a flush to a
- // hidden widget
- if (e->type() == QEvent::Hide) {
- makeCurrent();
- glFinish();
- doneCurrent();
- } else if (e->type() == QEvent::ParentChange) {
- // if we've reparented a window that has the current context
- // bound, we need to rebind that context to the new window id
- if (d->glcx == QGLContext::currentContext())
- makeCurrent();
-
- if (testAttribute(Qt::WA_TranslucentBackground))
- setContext(new QGLContext(d->glcx->requestedFormat(), this));
- }
-
- // A re-parent is likely to destroy the Symbian window and re-create it. It is important
- // that we free the EGL surface _before_ the winID changes - otherwise we can leak.
- if (e->type() == QEvent::ParentAboutToChange)
- d->glcx->d_func()->destroyEglSurfaceForDevice();
-
- if ((e->type() == QEvent::ParentChange) || (e->type() == QEvent::WindowStateChange)) {
- // The window may have been re-created during re-parent or state change - if so, the EGL
- // surface will need to be re-created.
- d->recreateEglSurface();
- }
-
-#endif
-
- return QWidget::event(e);
-}
-#endif
-
/*!
\fn void QGLWidget::paintEvent(QPaintEvent *event)
@@ -4467,28 +3962,7 @@ QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext)
if ((w > 0) && (h > 0))
sz = QSize(w, h);
-#if defined(Q_WS_X11)
- extern int qt_x11_preferred_pixmap_depth;
- int old_depth = qt_x11_preferred_pixmap_depth;
- qt_x11_preferred_pixmap_depth = x11Info().depth();
-
- QPixmapData *data = new QX11PixmapData(QPixmapData::PixmapType);
- data->resize(sz.width(), sz.height());
- QPixmap pm(data);
- qt_x11_preferred_pixmap_depth = old_depth;
- QX11Info xinfo = x11Info();
-
- // make sure we use a pixmap with the same depth/visual as the widget
- if (xinfo.visual() != QX11Info::appVisual()) {
- QX11InfoData* xd = pm.x11Info().getX11Data(true);
- xd->depth = xinfo.depth();
- xd->visual = static_cast<Visual *>(xinfo.visual());
- const_cast<QX11Info &>(pm.x11Info()).setX11Data(xd);
- }
-
-#else
QPixmap pm(sz);
-#endif
d->glcx->doneCurrent();
@@ -4500,9 +3974,6 @@ QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext)
QGLFormat fmt = d->glcx->requestedFormat();
fmt.setDirectRendering(false); // Direct is unlikely to work
fmt.setDoubleBuffer(false); // We don't need dbl buf
-#ifdef Q_WS_MAC // crash prevention on the Mac - it's unlikely to work anyway
- fmt.setSampleBuffers(false);
-#endif
QGLContext* ocx = d->glcx;
ocx->doneCurrent();
@@ -4520,13 +3991,6 @@ QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext)
ocx->makeCurrent();
if (success) {
-#if defined(Q_WS_X11)
- if (xinfo.visual() != QX11Info::appVisual()) {
- QImage image = pm.toImage();
- QPixmap p = QPixmap::fromImage(image);
- return p;
- }
-#endif
return pm;
}
return QPixmap();
@@ -4546,21 +4010,8 @@ QImage QGLWidget::grabFrameBuffer(bool withAlpha)
QImage res;
int w = width();
int h = height();
- if (format().rgba()) {
+ if (format().rgba())
res = qt_gl_read_framebuffer(QSize(w, h), format().alpha(), withAlpha);
- } else {
-#if defined (Q_WS_WIN) && !defined(QT_OPENGL_ES)
- res = QImage(w, h, QImage::Format_Indexed8);
- glReadPixels(0, 0, w, h, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, res.bits());
- const QVector<QColor> pal = QColormap::instance().colormap();
- if (pal.size()) {
- res.setColorCount(pal.size());
- for (int i = 0; i < pal.size(); i++)
- res.setColor(i, pal.at(i).rgb());
- }
- res = res.mirrored();
-#endif
- }
return res;
}
@@ -4595,11 +4046,6 @@ void QGLWidget::glDraw()
Q_D(QGLWidget);
if (!isValid())
return;
-#ifdef Q_OS_SYMBIAN
- // Crashes on Symbian if trying to render to invisible surfaces
- if (!isVisible() && d->glcx->device()->devType() == QInternal::Widget)
- return;
-#endif
makeCurrent();
#ifndef QT_OPENGL_ES
if (d->glcx->deviceIsPixmap())
@@ -4918,18 +4364,13 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font,
int height = d->glcx->device()->height();
bool auto_swap = autoBufferSwap();
- QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
-
QPaintEngine *engine = paintEngine();
- if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) {
+ if (engine && engine->isActive()) {
qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is"
" active on the same device is not allowed.");
return;
}
- // this changes what paintEngine() returns
- qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL);
- engine = paintEngine();
QPainter *p;
bool reuse_painter = false;
if (engine->isActive()) {
@@ -4973,7 +4414,6 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font,
setAutoBufferSwap(auto_swap);
d->disable_clear_on_painter_begin = false;
}
- qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
#else // QT_OPENGL_ES
Q_UNUSED(x);
Q_UNUSED(y);
@@ -5021,18 +4461,14 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
&win_x, &win_y, &win_z);
win_y = height - win_y; // y is inverted
- QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine();
QPaintEngine *engine = paintEngine();
- if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) {
+ if (engine && engine->isActive()) {
qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is"
" active on the same device is not allowed.");
return;
}
- // this changes what paintEngine() returns
- qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL);
- engine = paintEngine();
QPainter *p;
bool reuse_painter = false;
bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
@@ -5077,7 +4513,6 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
setAutoBufferSwap(auto_swap);
d->disable_clear_on_painter_begin = false;
}
- qgl_engine_selector()->setPreferredPaintEngine(oldEngineType);
#else // QT_OPENGL_ES
Q_UNUSED(x);
Q_UNUSED(y);
@@ -5150,28 +4585,6 @@ GLuint QGLWidget::bindTexture(const QImage &image, GLenum target, GLint format,
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-GLuint QGLWidget::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format)
-{
- if (image.isNull())
- return 0;
-
- Q_D(QGLWidget);
- return d->glcx->bindTexture(image, GLenum(target), GLint(format), QGLContext::DefaultBindOption);
-}
-
-GLuint QGLWidget::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format,
- QGLContext::BindOptions options)
-{
- if (image.isNull())
- return 0;
-
- Q_D(QGLWidget);
- return d->glcx->bindTexture(image, GLenum(target), GLint(format), options);
-}
-#endif
-
/*!
Calls QGLContext:::bindTexture(\a pixmap, \a target, \a format) on the currently
set context.
@@ -5204,23 +4617,6 @@ GLuint QGLWidget::bindTexture(const QPixmap &pixmap, GLenum target, GLint format
return d->glcx->bindTexture(pixmap, target, format, options);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-GLuint QGLWidget::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format)
-{
- Q_D(QGLWidget);
- return d->glcx->bindTexture(pixmap, target, format, QGLContext::DefaultBindOption);
-}
-
-GLuint QGLWidget::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format,
- QGLContext::BindOptions options)
-{
- Q_D(QGLWidget);
- return d->glcx->bindTexture(pixmap, target, format, options);
-}
-#endif
-
-
/*! \overload
Calls QGLContext::bindTexture(\a fileName) on the currently set context.
@@ -5245,15 +4641,6 @@ void QGLWidget::deleteTexture(GLuint id)
d->glcx->deleteTexture(id);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLWidget::deleteTexture(QMacCompatGLuint id)
-{
- Q_D(QGLWidget);
- d->glcx->deleteTexture(GLuint(id));
-}
-#endif
-
/*!
\since 4.4
@@ -5267,15 +4654,6 @@ void QGLWidget::drawTexture(const QRectF &target, GLuint textureId, GLenum textu
d->glcx->drawTexture(target, textureId, textureTarget);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLWidget::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- Q_D(QGLWidget);
- d->glcx->drawTexture(target, GLint(textureId), GLenum(textureTarget));
-}
-#endif
-
/*!
\since 4.4
@@ -5289,42 +4667,17 @@ void QGLWidget::drawTexture(const QPointF &point, GLuint textureId, GLenum textu
d->glcx->drawTexture(point, textureId, textureTarget);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLWidget::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- Q_D(QGLWidget);
- d->glcx->drawTexture(point, GLuint(textureId), GLenum(textureTarget));
-}
-#endif
-
-#ifndef QT_OPENGL_ES_1
Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_gl_2_engine)
-#endif
-
-#ifndef QT_OPENGL_ES_2
-Q_GLOBAL_STATIC(QGLEngineThreadStorage<QOpenGLPaintEngine>, qt_gl_engine)
-#endif
-Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine()
+QPaintEngine* qt_qgl_paint_engine()
{
-#if defined(QT_OPENGL_ES_1)
- return qt_gl_engine()->engine();
-#elif defined(QT_OPENGL_ES_2)
return qt_gl_2_engine()->engine();
-#else
- if (qt_gl_preferGL2Engine())
- return qt_gl_2_engine()->engine();
- else
- return qt_gl_engine()->engine();
-#endif
}
/*!
\internal
- Returns the GL widget's paint engine. This is normally a
- QOpenGLPaintEngine.
+ Returns the GL widget's paint engine.
*/
QPaintEngine *QGLWidget::paintEngine() const
{
@@ -5492,10 +4845,6 @@ QGLExtensions::Extensions QGLExtensions::currentContextExtensions()
glExtensions |= GenerateMipmap;
glExtensions |= FragmentShader;
#endif
-#if defined(QT_OPENGL_ES_1)
- if (extensions.match("GL_OES_framebuffer_object"))
- glExtensions |= FramebufferObject;
-#endif
#if defined(QT_OPENGL_ES)
if (extensions.match("GL_OES_packed_depth_stencil"))
glExtensions |= PackedDepthStencil;
@@ -5588,32 +4937,24 @@ void QGLWidgetPrivate::initContext(QGLContext *context, const QGLWidget* shareWi
glcx = new QGLContext(QGLFormat::defaultFormat(), q);
}
-#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_WS_QPA)
Q_GLOBAL_STATIC(QString, qt_gl_lib_name)
-Q_OPENGL_EXPORT void qt_set_gl_library_name(const QString& name)
+void qt_set_gl_library_name(const QString& name)
{
qt_gl_lib_name()->operator=(name);
}
-Q_OPENGL_EXPORT const QString qt_gl_library_name()
+const QString qt_gl_library_name()
{
if (qt_gl_lib_name()->isNull()) {
-#ifdef Q_WS_MAC
- return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib");
-#else
-# if defined(QT_OPENGL_ES_1)
- return QLatin1String("GLES_CM");
-# elif defined(QT_OPENGL_ES_2)
+# if defined(QT_OPENGL_ES_2)
return QLatin1String("GLESv2");
# else
return QLatin1String("GL");
# endif
-#endif // defined Q_WS_MAC
}
return *qt_gl_lib_name();
}
-#endif
void QGLContextGroup::addShare(const QGLContext *context, const QGLContext *share) {
Q_ASSERT(context && share);
@@ -5653,108 +4994,6 @@ void QGLContextGroup::removeShare(const QGLContext *context) {
group->m_shares.clear();
}
-QGLContextGroupResourceBase::QGLContextGroupResourceBase()
- : active(0)
-{
-#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
- qDebug("Creating context group resource object %p.", this);
-#endif
-}
-
-QGLContextGroupResourceBase::~QGLContextGroupResourceBase()
-{
-#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
- qDebug("Deleting context group resource %p. Group size: %d.", this, m_groups.size());
-#endif
- for (int i = 0; i < m_groups.size(); ++i) {
- m_groups.at(i)->m_resources.remove(this);
- active.deref();
- }
-#ifndef QT_NO_DEBUG
- if (active != 0) {
- qWarning("QtOpenGL: Resources are still available at program shutdown.\n"
- " This is possibly caused by a leaked QGLWidget, \n"
- " QGLFramebufferObject or QGLPixelBuffer.");
- }
-#endif
-}
-
-void QGLContextGroupResourceBase::insert(const QGLContext *context, void *value)
-{
-#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
- qDebug("Inserting context group resource %p for context %p, managed by %p.", value, context, this);
-#endif
- QGLContextGroup *group = QGLContextPrivate::contextGroup(context);
- Q_ASSERT(!group->m_resources.contains(this));
- group->m_resources.insert(this, value);
- m_groups.append(group);
- active.ref();
-}
-
-void *QGLContextGroupResourceBase::value(const QGLContext *context)
-{
- QGLContextGroup *group = QGLContextPrivate::contextGroup(context);
- return group->m_resources.value(this, 0);
-}
-
-void QGLContextGroupResourceBase::cleanup(const QGLContext *ctx)
-{
- void *resource = value(ctx);
-
- if (resource != 0) {
- QGLShareContextScope scope(ctx);
- freeResource(resource);
-
- QGLContextGroup *group = QGLContextPrivate::contextGroup(ctx);
- group->m_resources.remove(this);
- m_groups.removeOne(group);
- active.deref();
- }
-}
-
-void QGLContextGroupResourceBase::cleanup(const QGLContext *ctx, void *value)
-{
-#ifdef QT_GL_CONTEXT_RESOURCE_DEBUG
- qDebug("Cleaning up context group resource %p, for context %p in thread %p.", this, ctx, QThread::currentThread());
-#endif
- QGLShareContextScope scope(ctx);
- freeResource(value);
- active.deref();
-
- QGLContextGroup *group = QGLContextPrivate::contextGroup(ctx);
- m_groups.removeOne(group);
-}
-
-void QGLContextGroup::cleanupResources(const QGLContext *context)
-{
- // If there are still shares, then no cleanup to be done yet.
- if (m_shares.size() > 1)
- return;
-
- // Iterate over all resources and free each in turn.
- QHash<QGLContextGroupResourceBase *, void *>::ConstIterator it;
- for (it = m_resources.begin(); it != m_resources.end(); ++it)
- it.key()->cleanup(context, it.value());
-}
-
-QGLSharedResourceGuard::~QGLSharedResourceGuard()
-{
- if (m_group)
- m_group->removeGuard(this);
-}
-
-void QGLSharedResourceGuard::setContext(const QGLContext *context)
-{
- if (m_group)
- m_group->removeGuard(this);
- if (context) {
- m_group = QGLContextPrivate::contextGroup(context);
- m_group->addGuard(this);
- } else {
- m_group = 0;
- }
-}
-
QSize QGLTexture::bindCompressedTexture
(const QString& fileName, const char *format)
{
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index f7685ed8b4..665dcac412 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -42,34 +42,22 @@
#ifndef QGL_H
#define QGL_H
-#include <QtGui/qwidget.h>
+#include <QtWidgets/qwidget.h>
#include <QtGui/qpaintengine.h>
#include <QtOpenGL/qglcolormap.h>
#include <QtCore/qmap.h>
#include <QtCore/qscopedpointer.h>
-#ifdef Q_WS_QPA
-#include <QtGui/QPlatformWindowFormat>
-#endif
+#include <QtGui/QSurfaceFormat>
QT_BEGIN_HEADER
-#if defined(Q_WS_WIN)
+#if defined(Q_OS_WIN)
# include <QtCore/qt_windows.h>
#endif
-#if defined(QT_OPENGL_ES_1)
-# if defined(Q_OS_MAC)
-# include <OpenGLES/ES1/gl.h>
-# else
-# include <GLES/gl.h>
-# endif
-# ifndef GL_DOUBLE
-# define GL_DOUBLE GL_FLOAT
-# endif
-# ifndef GLdouble
-typedef GLfloat GLdouble;
-# endif
+#if defined(Q_OS_MAC)
+# include <OpenGL/gl.h>
#elif defined(QT_OPENGL_ES_2)
# if defined(Q_OS_MAC)
# include <OpenGLES/ES2/gl.h>
@@ -94,31 +82,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(OpenGL)
-#if defined(Q_WS_MAC) && defined (QT_BUILD_OPENGL_LIB) && !defined(QT_MAC_USE_COCOA) && !defined(QDOC)
-#define Q_MAC_COMPAT_GL_FUNCTIONS
-
-template <typename T>
-struct QMacGLCompatTypes
-{
- typedef long CompatGLint;
- typedef unsigned long CompatGLuint;
- typedef unsigned long CompatGLenum;
-};
-
-template <>
-struct QMacGLCompatTypes<long>
-{
- typedef int CompatGLint;
- typedef unsigned int CompatGLuint;
- typedef unsigned int CompatGLenum;
-};
-
-typedef QMacGLCompatTypes<GLint>::CompatGLint QMacCompatGLint;
-typedef QMacGLCompatTypes<GLint>::CompatGLuint QMacCompatGLuint;
-typedef QMacGLCompatTypes<GLint>::CompatGLenum QMacCompatGLenum;
-
-#endif
-
#ifdef QT3_SUPPORT
#define QGL_VERSION 460
#define QGL_VERSION_STR "4.6"
@@ -132,17 +95,12 @@ class QGLCmap;
#endif
class QPixmap;
-#if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)
-class QGLOverlayWidget;
-#endif
class QGLWidgetPrivate;
class QGLContextPrivate;
// Namespace class:
namespace QGL
{
- Q_OPENGL_EXPORT void setPreferredPaintEngine(QPaintEngine::Type engineType);
-
enum FormatOption {
DoubleBuffer = 0x0001,
DepthBuffer = 0x0002,
@@ -284,10 +242,8 @@ public:
static OpenGLVersionFlags openGLVersionFlags();
-#if defined(Q_WS_QPA)
- static QGLFormat fromPlatformWindowFormat(const QPlatformWindowFormat &format);
- static QPlatformWindowFormat toPlatformWindowFormat(const QGLFormat &format);
-#endif
+ static QGLFormat fromSurfaceFormat(const QSurfaceFormat &format);
+ static QSurfaceFormat toSurfaceFormat(const QGLFormat &format);
private:
QGLFormatPrivate *d;
@@ -373,22 +329,6 @@ public:
void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- GLuint bindTexture(const QImage &image, QMacCompatGLenum = GL_TEXTURE_2D,
- QMacCompatGLint format = GL_RGBA);
- GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum = GL_TEXTURE_2D,
- QMacCompatGLint format = GL_RGBA);
- GLuint bindTexture(const QImage &image, QMacCompatGLenum, QMacCompatGLint format,
- BindOptions);
- GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum, QMacCompatGLint format,
- BindOptions);
-
- void deleteTexture(QMacCompatGLuint tx_id);
-
- void drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
- void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
-#endif
-
static void setTextureCacheLimit(int size);
static int textureCacheLimit();
@@ -398,23 +338,12 @@ public:
static const QGLContext* currentContext();
-#ifdef Q_WS_QPA
- static QGLContext *fromPlatformGLContext(QPlatformGLContext *platformContext);
-#endif
+ static QGLContext *fromOpenGLContext(QOpenGLContext *platformContext);
+ QOpenGLContext *contextHandle() const;
+
protected:
virtual bool chooseContext(const QGLContext* shareContext = 0);
-#if defined(Q_WS_WIN)
- virtual int choosePixelFormat(void* pfd, HDC pdc);
-#endif
-#if defined(Q_WS_X11)
- virtual void* tryVisual(const QGLFormat& f, int bufDepth = 1);
- virtual void* chooseVisual();
-#endif
-#if defined(Q_WS_MAC)
- virtual void* chooseMacVisual(GDHandle);
-#endif
-
bool deviceIsPixmap() const;
bool windowCreated() const;
void setWindowCreated(bool on);
@@ -430,9 +359,7 @@ protected:
static QGLContext* currentCtx;
private:
-#ifdef Q_WS_QPA
- QGLContext(QPlatformGLContext *platformContext);
-#endif
+ QGLContext(QOpenGLContext *windowContext);
QScopedPointer<QGLContextPrivate> d_ptr;
@@ -441,18 +368,12 @@ private:
friend class QGLWidget;
friend class QGLWidgetPrivate;
friend class QGLGlyphCache;
- friend class QOpenGLPaintEngine;
- friend class QOpenGLPaintEnginePrivate;
friend class QGL2PaintEngineEx;
friend class QGL2PaintEngineExPrivate;
friend class QGLEngineShaderManager;
- friend class QGLWindowSurface;
- friend class QGLPixmapData;
- friend class QGLPixmapFilterBase;
friend class QGLTextureGlyphCache;
friend struct QGLGlyphTexture;
friend class QGLContextGroup;
- friend class QGLSharedResourceGuard;
friend class QGLPixmapBlurFilter;
friend class QGLExtensions;
friend class QGLTexture;
@@ -469,7 +390,6 @@ private:
friend class QGLFBOGLPaintDevice;
friend class QGLPaintDevice;
friend class QGLWidgetGLPaintDevice;
- friend class QX11GLPixmapData;
friend class QX11GLSharedContexts;
friend class QGLContextResourceBase;
friend class QSGDistanceFieldGlyphCache;
@@ -556,22 +476,6 @@ public:
void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- GLuint bindTexture(const QImage &image, QMacCompatGLenum = GL_TEXTURE_2D,
- QMacCompatGLint format = GL_RGBA);
- GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum = GL_TEXTURE_2D,
- QMacCompatGLint format = GL_RGBA);
- GLuint bindTexture(const QImage &image, QMacCompatGLenum, QMacCompatGLint format,
- QGLContext::BindOptions);
- GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum, QMacCompatGLint format,
- QGLContext::BindOptions);
-
- void deleteTexture(QMacCompatGLuint tx_id);
-
- void drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
- void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
-#endif
-
public Q_SLOTS:
virtual void updateGL();
virtual void updateOverlayGL();
@@ -613,7 +517,6 @@ private:
friend class QGLContext;
friend class QGLContextPrivate;
friend class QGLOverlayWidget;
- friend class QOpenGLPaintEngine;
friend class QGLPaintDevice;
friend class QGLWidgetGLPaintDevice;
};
diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp
deleted file mode 100644
index 4de5122a86..0000000000
--- a/src/opengl/qgl_egl.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qdebug.h>
-#include <QtOpenGL/qgl.h>
-#include <QtOpenGL/qglpixelbuffer.h>
-#include "qgl_p.h"
-#include "qgl_egl_p.h"
-#include "qglpixelbuffer_p.h"
-
-#ifdef Q_WS_X11
-#include <QtGui/private/qpixmap_x11_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-QEglProperties *QGLContextPrivate::extraWindowSurfaceCreationProps = NULL;
-
-void qt_eglproperties_set_glformat(QEglProperties& eglProperties, const QGLFormat& glFormat)
-{
- int redSize = glFormat.redBufferSize();
- int greenSize = glFormat.greenBufferSize();
- int blueSize = glFormat.blueBufferSize();
- int alphaSize = glFormat.alphaBufferSize();
- int depthSize = glFormat.depthBufferSize();
- int stencilSize = glFormat.stencilBufferSize();
- int sampleCount = glFormat.samples();
-
- // QGLFormat uses a magic value of -1 to indicate "don't care", even when a buffer of that
- // type has been requested. So we must check QGLFormat's booleans too if size is -1:
- if (glFormat.alpha() && alphaSize <= 0)
- alphaSize = 1;
- if (glFormat.depth() && depthSize <= 0)
- depthSize = 1;
- if (glFormat.stencil() && stencilSize <= 0)
- stencilSize = 1;
- if (glFormat.sampleBuffers() && sampleCount <= 0)
- sampleCount = 1;
-
- // We want to make sure 16-bit configs are chosen over 32-bit configs as they will provide
- // the best performance. The EGL config selection algorithm is a bit stange in this regard:
- // The selection criteria for EGL_BUFFER_SIZE is "AtLeast", so we can't use it to discard
- // 32-bit configs completely from the selection. So it then comes to the sorting algorithm.
- // The red/green/blue sizes have a sort priority of 3, so they are sorted by first. The sort
- // order is special and described as "by larger _total_ number of color bits.". So EGL will
- // put 32-bit configs in the list before the 16-bit configs. However, the spec also goes on
- // to say "If the requested number of bits in attrib_list for a particular component is 0,
- // then the number of bits for that component is not considered". This part of the spec also
- // seems to imply that setting the red/green/blue bits to zero means none of the components
- // are considered and EGL disregards the entire sorting rule. It then looks to the next
- // highest priority rule, which is EGL_BUFFER_SIZE. Despite the selection criteria being
- // "AtLeast" for EGL_BUFFER_SIZE, it's sort order is "smaller" meaning 16-bit configs are
- // put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit,
- // we must set the red/green/blue sizes to zero. This has an unfortunate consequence that
- // if the application sets the red/green/blue size to 5/6/5 on the QGLFormat, they will
- // probably get a 32-bit config, even when there's an RGB565 config available. Oh well.
-
- // Now normalize the values so -1 becomes 0
- redSize = redSize > 0 ? redSize : 0;
- greenSize = greenSize > 0 ? greenSize : 0;
- blueSize = blueSize > 0 ? blueSize : 0;
- alphaSize = alphaSize > 0 ? alphaSize : 0;
- depthSize = depthSize > 0 ? depthSize : 0;
- stencilSize = stencilSize > 0 ? stencilSize : 0;
- sampleCount = sampleCount > 0 ? sampleCount : 0;
-
- eglProperties.setValue(EGL_RED_SIZE, redSize);
- eglProperties.setValue(EGL_GREEN_SIZE, greenSize);
- eglProperties.setValue(EGL_BLUE_SIZE, blueSize);
- eglProperties.setValue(EGL_ALPHA_SIZE, alphaSize);
- eglProperties.setValue(EGL_DEPTH_SIZE, depthSize);
- eglProperties.setValue(EGL_STENCIL_SIZE, stencilSize);
- eglProperties.setValue(EGL_SAMPLES, sampleCount);
- eglProperties.setValue(EGL_SAMPLE_BUFFERS, sampleCount ? 1 : 0);
-}
-
-// Updates "format" with the parameters of the selected configuration.
-void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config)
-{
- EGLint redSize = 0;
- EGLint greenSize = 0;
- EGLint blueSize = 0;
- EGLint alphaSize = 0;
- EGLint depthSize = 0;
- EGLint stencilSize = 0;
- EGLint sampleCount = 0;
- EGLint level = 0;
-
- EGLDisplay display = QEgl::display();
- eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize);
- eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize);
- eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize);
- eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize);
- eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize);
- eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize);
- eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount);
- eglGetConfigAttrib(display, config, EGL_LEVEL, &level);
-
- format.setRedBufferSize(redSize);
- format.setGreenBufferSize(greenSize);
- format.setBlueBufferSize(blueSize);
- format.setAlphaBufferSize(alphaSize);
- format.setDepthBufferSize(depthSize);
- format.setStencilBufferSize(stencilSize);
- format.setSamples(sampleCount);
- format.setPlane(level);
- format.setDirectRendering(true); // All EGL contexts are direct-rendered
- format.setRgba(true); // EGL doesn't support colour index rendering
- format.setStereo(false); // EGL doesn't support stereo buffers
- format.setAccumBufferSize(0); // EGL doesn't support accululation buffers
- format.setDoubleBuffer(true); // We don't support single buffered EGL contexts
-
- // Clear the EGL error state because some of the above may
- // have errored out because the attribute is not applicable
- // to the surface type. Such errors don't matter.
- eglGetError();
-}
-
-bool QGLFormat::hasOpenGL()
-{
- return true;
-}
-
-void QGLContext::reset()
-{
- Q_D(QGLContext);
- if (!d->valid)
- return;
- d->cleanup();
- doneCurrent();
- if (d->eglContext && d->ownsEglContext) {
- d->destroyEglSurfaceForDevice();
- delete d->eglContext;
- }
- d->ownsEglContext = false;
- d->eglContext = 0;
- d->eglSurface = EGL_NO_SURFACE;
- d->crWin = false;
- d->sharing = false;
- d->valid = false;
- d->transpColor = QColor();
- d->initDone = false;
- QGLContextGroup::removeShare(this);
-}
-
-void QGLContext::makeCurrent()
-{
- Q_D(QGLContext);
- if (!d->valid || !d->eglContext || d->eglSurfaceForDevice() == EGL_NO_SURFACE) {
- qWarning("QGLContext::makeCurrent(): Cannot make invalid context current");
- return;
- }
-
- if (d->eglContext->makeCurrent(d->eglSurfaceForDevice())) {
- QGLContextPrivate::setCurrentContext(this);
- if (!d->workaroundsCached) {
- d->workaroundsCached = true;
- const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
- if (renderer && (strstr(renderer, "SGX") || strstr(renderer, "MBX"))) {
- // PowerVR MBX/SGX chips needs to clear all buffers when starting to render
- // a new frame, otherwise there will be a performance penalty to pay for
- // each frame.
- qDebug() << "Found SGX/MBX driver, enabling FullClearOnEveryFrame";
- d->workaround_needsFullClearOnEveryFrame = true;
-
- // Older PowerVR SGX drivers (like the one in the N900) have a
- // bug which prevents glCopyTexSubImage2D() to work with a POT
- // or GL_ALPHA texture bound to an FBO. The only way to
- // identify that driver is to check the EGL version number for it.
- const char *egl_version = eglQueryString(d->eglContext->display(), EGL_VERSION);
-
- if (egl_version && strstr(egl_version, "1.3")) {
- qDebug() << "Found v1.3 driver, enabling brokenFBOReadBack";
- d->workaround_brokenFBOReadBack = true;
- } else if (egl_version && strstr(egl_version, "1.4")) {
- qDebug() << "Found v1.4 driver, enabling brokenTexSubImage";
- d->workaround_brokenTexSubImage = true;
-
- // this is a bit complicated; 1.4 version SGX drivers from
- // Nokia have fixed the brokenFBOReadBack problem, but
- // official drivers from TI haven't, meaning that things
- // like the beagleboard are broken unless we hack around it
- // - but at the same time, we want to not reduce performance
- // by not enabling this elsewhere.
- //
- // so, let's check for a Nokia-specific addon, and only
- // enable if it isn't present.
- // (see MeeGo bug #5616)
- if (!QEgl::hasExtension("EGL_NOK_image_shared")) {
- // no Nokia extension, this is probably a standard SGX
- // driver, so enable the workaround
- qDebug() << "Found non-Nokia v1.4 driver, enabling brokenFBOReadBack";
- d->workaround_brokenFBOReadBack = true;
- }
- }
- }
- }
- }
-}
-
-void QGLContext::doneCurrent()
-{
- Q_D(QGLContext);
- if (d->eglContext)
- d->eglContext->doneCurrent();
-
- QGLContextPrivate::setCurrentContext(0);
-}
-
-
-void QGLContext::swapBuffers() const
-{
- Q_D(const QGLContext);
- if (!d->valid || !d->eglContext)
- return;
-
- d->eglContext->swapBuffers(d->eglSurfaceForDevice());
-}
-
-void QGLContextPrivate::destroyEglSurfaceForDevice()
-{
- if (eglSurface != EGL_NO_SURFACE) {
-#if defined(Q_WS_X11) || defined(Q_OS_SYMBIAN)
- // Make sure we don't call eglDestroySurface on a surface which
- // was created for a different winId. This applies only to QGLWidget
- // paint device, so make sure this is the one we're operating on
- // (as opposed to a QGLWindowSurface use case).
- if (paintDevice && paintDevice->devType() == QInternal::Widget) {
- QWidget *w = static_cast<QWidget *>(paintDevice);
- if (QGLWidget *wgl = qobject_cast<QGLWidget *>(w)) {
- if (wgl->d_func()->eglSurfaceWindowId != wgl->winId()) {
- qWarning("WARNING: Potential EGL surface leak! Not destroying surface.");
- eglSurface = EGL_NO_SURFACE;
- return;
- }
- }
- }
-#endif
- eglDestroySurface(eglContext->display(), eglSurface);
- eglSurface = EGL_NO_SURFACE;
- }
-}
-
-EGLSurface QGLContextPrivate::eglSurfaceForDevice() const
-{
- // If a QPixmapData had to create the QGLContext, we don't have a paintDevice
- if (!paintDevice)
- return eglSurface;
-
-#ifdef Q_WS_X11
- if (paintDevice->devType() == QInternal::Pixmap) {
- QPixmapData *pmd = static_cast<QPixmap*>(paintDevice)->data_ptr().data();
- if (pmd->classId() == QPixmapData::X11Class) {
- QX11PixmapData* x11PixmapData = static_cast<QX11PixmapData*>(pmd);
- return (EGLSurface)x11PixmapData->gl_surface;
- }
- }
-#endif
-
- if (paintDevice->devType() == QInternal::Pbuffer) {
- QGLPixelBuffer* pbuf = static_cast<QGLPixelBuffer*>(paintDevice);
- return pbuf->d_func()->pbuf;
- }
-
- return eglSurface;
-}
-
-void QGLContextPrivate::swapRegion(const QRegion &region)
-{
- if (!valid || !eglContext)
- return;
-
- eglContext->swapBuffersRegion2NOK(eglSurfaceForDevice(), &region);
-}
-
-void QGLContextPrivate::setExtraWindowSurfaceCreationProps(QEglProperties *props)
-{
- extraWindowSurfaceCreationProps = props;
-}
-
-void QGLWidget::setMouseTracking(bool enable)
-{
- QWidget::setMouseTracking(enable);
-}
-
-QColor QGLContext::overlayTransparentColor() const
-{
- return d_func()->transpColor;
-}
-
-uint QGLContext::colorIndex(const QColor &c) const
-{
- Q_UNUSED(c);
- return 0;
-}
-
-void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
-{
- Q_UNUSED(fnt);
- Q_UNUSED(listBase);
-}
-
-void *QGLContext::getProcAddress(const QString &proc) const
-{
- return (void*)eglGetProcAddress(reinterpret_cast<const char *>(proc.toLatin1().data()));
-}
-
-bool QGLWidgetPrivate::renderCxPm(QPixmap*)
-{
- return false;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgl_egl_p.h b/src/opengl/qgl_egl_p.h
deleted file mode 100644
index 2522fca822..0000000000
--- a/src/opengl/qgl_egl_p.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGL_EGL_P_H
-#define QGL_EGL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QGLWidget class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/private/qegl_p.h>
-#include <QtGui/private/qeglcontext_p.h>
-#include <QtGui/private/qeglproperties_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGLFormat;
-
-void qt_eglproperties_set_glformat(QEglProperties& props, const QGLFormat& format);
-void qt_glformat_from_eglconfig(QGLFormat& format, const EGLConfig config);
-
-QT_END_NAMESPACE
-
-#endif // QGL_EGL_P_H
diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm
deleted file mode 100644
index d4b2a40e93..0000000000
--- a/src/opengl/qgl_mac.mm
+++ /dev/null
@@ -1,996 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgl.h"
-
-// There are functions that are deprecated in 10.5, but really there's no way around them
-// for Carbon, so just undefine them.
-#undef DEPRECATED_ATTRIBUTE
-#define DEPRECATED_ATTRIBUTE
-#if defined(Q_WS_MAC)
-#ifndef QT_MAC_USE_COCOA
-#ifdef qDebug
-# undef qDebug
-# include <AGL/agl.h>
-# include <AGL/aglRenderers.h>
-# include <OpenGL/gl.h>
-# ifdef QT_NO_DEBUG
-# define qDebug qt_noop(),1?(void)0:qDebug
-# endif
-#else
-# include <AGL/agl.h>
-# include <AGL/aglRenderers.h>
-# include <OpenGL/gl.h>
-#endif
-#else
-#include <private/qcocoaview_mac_p.h>
-#endif
-
-
-#include <OpenGL/gl.h>
-#include <CoreServices/CoreServices.h>
-#include <private/qfont_p.h>
-#include <private/qfontengine_p.h>
-#include <private/qgl_p.h>
-#include <private/qpaintengine_opengl_p.h>
-#include <private/qt_mac_p.h>
-#include <qpixmap.h>
-#include <qtimer.h>
-#include <qapplication.h>
-#include <qstack.h>
-#include <qdesktopwidget.h>
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-#ifdef QT_MAC_USE_COCOA
-QT_END_NAMESPACE
-
-QT_FORWARD_DECLARE_CLASS(QWidget)
-QT_FORWARD_DECLARE_CLASS(QWidgetPrivate)
-QT_FORWARD_DECLARE_CLASS(QGLWidgetPrivate)
-
-QT_BEGIN_NAMESPACE
-
-void *qt_current_nsopengl_context()
-{
- return [NSOpenGLContext currentContext];
-}
-
-static GLint attribValue(NSOpenGLPixelFormat *fmt, NSOpenGLPixelFormatAttribute attrib)
-{
- GLint res;
- [fmt getValues:&res forAttribute:attrib forVirtualScreen:0];
- return res;
-}
-
-static int def(int val, int defVal)
-{
- return val != -1 ? val : defVal;
-}
-#else
-QRegion qt_mac_get_widget_rgn(const QWidget *widget);
-#endif
-
-extern quint32 *qt_mac_pixmap_get_base(const QPixmap *);
-extern int qt_mac_pixmap_get_bytes_per_line(const QPixmap *);
-extern RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp
-extern void qt_mac_dispose_rgn(RgnHandle); //qregion_mac.cpp
-extern QRegion qt_mac_convert_mac_region(RgnHandle); //qregion_mac.cpp
-extern void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding=0, int len=-1); //qglobal.cpp
-
-/*
- QGLTemporaryContext implementation
-*/
-
-class QGLTemporaryContextPrivate
-{
-public:
-#ifndef QT_MAC_USE_COCOA
- AGLContext ctx;
-#else
- NSOpenGLContext *ctx;
-#endif
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
- : d(new QGLTemporaryContextPrivate)
-{
- d->ctx = 0;
-#ifndef QT_MAC_USE_COCOA
- GLint attribs[] = {AGL_RGBA, AGL_NONE};
- AGLPixelFormat fmt = aglChoosePixelFormat(0, 0, attribs);
- if (!fmt) {
- qDebug("QGLTemporaryContext: Couldn't find any RGB visuals");
- return;
- }
- d->ctx = aglCreateContext(fmt, 0);
- if (!d->ctx)
- qDebug("QGLTemporaryContext: Unable to create context");
- else
- aglSetCurrentContext(d->ctx);
- aglDestroyPixelFormat(fmt);
-#else
- QMacCocoaAutoReleasePool pool;
- NSOpenGLPixelFormatAttribute attribs[] = { 0 };
- NSOpenGLPixelFormat *fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
- if (!fmt) {
- qWarning("QGLTemporaryContext: Cannot find any visuals");
- return;
- }
-
- d->ctx = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:0];
- if (!d->ctx)
- qWarning("QGLTemporaryContext: Cannot create context");
- else
- [d->ctx makeCurrentContext];
- [fmt release];
-#endif
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- if (d->ctx) {
-#ifndef QT_MAC_USE_COCOA
- aglSetCurrentContext(0);
- aglDestroyContext(d->ctx);
-#else
- [NSOpenGLContext clearCurrentContext];
- [d->ctx release];
-#endif
- }
-}
-
-bool QGLFormat::hasOpenGL()
-{
- return true;
-}
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- return false;
-}
-
-bool QGLContext::chooseContext(const QGLContext *shareContext)
-{
- QMacCocoaAutoReleasePool pool;
- Q_D(QGLContext);
- d->cx = 0;
- d->vi = chooseMacVisual(0);
- if (!d->vi)
- return false;
-
-#ifndef QT_MAC_USE_COCOA
- AGLPixelFormat fmt = (AGLPixelFormat)d->vi;
- GLint res;
- aglDescribePixelFormat(fmt, AGL_LEVEL, &res);
- d->glFormat.setPlane(res);
- if (deviceIsPixmap())
- res = 0;
- else
- aglDescribePixelFormat(fmt, AGL_DOUBLEBUFFER, &res);
- d->glFormat.setDoubleBuffer(res);
- aglDescribePixelFormat(fmt, AGL_DEPTH_SIZE, &res);
- d->glFormat.setDepth(res);
- if (d->glFormat.depth())
- d->glFormat.setDepthBufferSize(res);
- aglDescribePixelFormat(fmt, AGL_RGBA, &res);
- d->glFormat.setRgba(res);
- aglDescribePixelFormat(fmt, AGL_RED_SIZE, &res);
- d->glFormat.setRedBufferSize(res);
- aglDescribePixelFormat(fmt, AGL_GREEN_SIZE, &res);
- d->glFormat.setGreenBufferSize(res);
- aglDescribePixelFormat(fmt, AGL_BLUE_SIZE, &res);
- d->glFormat.setBlueBufferSize(res);
- aglDescribePixelFormat(fmt, AGL_ALPHA_SIZE, &res);
- d->glFormat.setAlpha(res);
- if (d->glFormat.alpha())
- d->glFormat.setAlphaBufferSize(res);
- aglDescribePixelFormat(fmt, AGL_ACCUM_RED_SIZE, &res);
- // Bug in Apple OpenGL (rdr://5015603), when we don't have an accumulation
- // buffer, it still claims that we have a 16-bit one (which is pretty rare).
- // So, we just assume we can never have a buffer that small.
- d->glFormat.setAccum(res > 5);
- if (d->glFormat.accum())
- d->glFormat.setAccumBufferSize(res);
- aglDescribePixelFormat(fmt, AGL_STENCIL_SIZE, &res);
- d->glFormat.setStencil(res);
- if (d->glFormat.stencil())
- d->glFormat.setStencilBufferSize(res);
- aglDescribePixelFormat(fmt, AGL_STEREO, &res);
- d->glFormat.setStereo(res);
- aglDescribePixelFormat(fmt, AGL_SAMPLE_BUFFERS_ARB, &res);
- d->glFormat.setSampleBuffers(res);
- if (d->glFormat.sampleBuffers()) {
- aglDescribePixelFormat(fmt, AGL_SAMPLES_ARB, &res);
- d->glFormat.setSamples(res);
- }
-#else
- NSOpenGLPixelFormat *fmt = static_cast<NSOpenGLPixelFormat *>(d->vi);
-
- d->glFormat = QGLFormat();
-
- // ### make sure to reset other options
- d->glFormat.setDoubleBuffer(attribValue(fmt, NSOpenGLPFADoubleBuffer));
-
- int depthSize = attribValue(fmt, NSOpenGLPFADepthSize);
- d->glFormat.setDepth(depthSize > 0);
- if (depthSize > 0)
- d->glFormat.setDepthBufferSize(depthSize);
-
- int alphaSize = attribValue(fmt, NSOpenGLPFAAlphaSize);
- d->glFormat.setAlpha(alphaSize > 0);
- if (alphaSize > 0)
- d->glFormat.setAlphaBufferSize(alphaSize);
-
- int accumSize = attribValue(fmt, NSOpenGLPFAAccumSize);
- d->glFormat.setAccum(accumSize > 0);
- if (accumSize > 0)
- d->glFormat.setAccumBufferSize(accumSize);
-
- int stencilSize = attribValue(fmt, NSOpenGLPFAStencilSize);
- d->glFormat.setStencil(stencilSize > 0);
- if (stencilSize > 0)
- d->glFormat.setStencilBufferSize(stencilSize);
-
- d->glFormat.setStereo(attribValue(fmt, NSOpenGLPFAStereo));
-
- int sampleBuffers = attribValue(fmt, NSOpenGLPFASampleBuffers);
- d->glFormat.setSampleBuffers(sampleBuffers);
- if (sampleBuffers > 0)
- d->glFormat.setSamples(attribValue(fmt, NSOpenGLPFASamples));
-#endif
- if (shareContext && (!shareContext->isValid() || !shareContext->d_func()->cx)) {
- qWarning("QGLContext::chooseContext: Cannot share with invalid context");
- shareContext = 0;
- }
-
- // sharing between rgba and color-index will give wrong colors
- if (shareContext && (format().rgba() != shareContext->format().rgba()))
- shareContext = 0;
-
-#ifndef QT_MAC_USE_COCOA
- AGLContext ctx = aglCreateContext(fmt, (AGLContext) (shareContext ? shareContext->d_func()->cx : 0));
-#else
- NSOpenGLContext *ctx = [[NSOpenGLContext alloc] initWithFormat:fmt
- shareContext:(shareContext ? static_cast<NSOpenGLContext *>(shareContext->d_func()->cx)
- : 0)];
-#endif
- if (!ctx) {
-#ifndef QT_MAC_USE_COCOA
- GLenum err = aglGetError();
- if (err == AGL_BAD_MATCH || err == AGL_BAD_CONTEXT) {
- if (shareContext && shareContext->d_func()->cx) {
- qWarning("QGLContext::chooseContext(): Context sharing mismatch!");
- if (!(ctx = aglCreateContext(fmt, 0)))
- return false;
- shareContext = 0;
- }
- }
-#else
- if (shareContext) {
- ctx = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:0];
- if (ctx) {
- qWarning("QGLContext::chooseContext: Context sharing mismatch");
- shareContext = 0;
- }
- }
-#endif
- if (!ctx) {
- qWarning("QGLContext::chooseContext: Unable to create QGLContext");
- return false;
- }
- }
- d->cx = ctx;
- if (shareContext && shareContext->d_func()->cx) {
- QGLContext *share = const_cast<QGLContext *>(shareContext);
- d->sharing = true;
- share->d_func()->sharing = true;
- }
- if (deviceIsPixmap())
- updatePaintDevice();
-
- // vblank syncing
- GLint interval = d->reqFormat.swapInterval();
- if (interval != -1) {
-#ifndef QT_MAC_USE_COCOA
- aglSetInteger((AGLContext)d->cx, AGL_SWAP_INTERVAL, &interval);
- if (interval != 0)
- aglEnable((AGLContext)d->cx, AGL_SWAP_INTERVAL);
- else
- aglDisable((AGLContext)d->cx, AGL_SWAP_INTERVAL);
-#else
- [ctx setValues:&interval forParameter:NSOpenGLCPSwapInterval];
-#endif
- }
-#ifndef QT_MAC_USE_COCOA
- aglGetInteger((AGLContext)d->cx, AGL_SWAP_INTERVAL, &interval);
-#else
- [ctx getValues:&interval forParameter:NSOpenGLCPSwapInterval];
-#endif
- d->glFormat.setSwapInterval(interval);
- return true;
-}
-
-void *QGLContextPrivate::tryFormat(const QGLFormat &format)
-{
- static const int Max = 40;
-#ifndef QT_MAC_USE_COCOA
- GLint attribs[Max], cnt = 0;
- bool device_is_pixmap = (paintDevice->devType() == QInternal::Pixmap);
-
- attribs[cnt++] = AGL_RGBA;
- attribs[cnt++] = AGL_BUFFER_SIZE;
- attribs[cnt++] = device_is_pixmap ? static_cast<QPixmap *>(paintDevice)->depth() : 32;
- attribs[cnt++] = AGL_LEVEL;
- attribs[cnt++] = format.plane();
-
- if (format.redBufferSize() != -1) {
- attribs[cnt++] = AGL_RED_SIZE;
- attribs[cnt++] = format.redBufferSize();
- }
- if (format.greenBufferSize() != -1) {
- attribs[cnt++] = AGL_GREEN_SIZE;
- attribs[cnt++] = format.greenBufferSize();
- }
- if (format.blueBufferSize() != -1) {
- attribs[cnt++] = AGL_BLUE_SIZE;
- attribs[cnt++] = format.blueBufferSize();
- }
- if (device_is_pixmap) {
- attribs[cnt++] = AGL_PIXEL_SIZE;
- attribs[cnt++] = static_cast<QPixmap *>(paintDevice)->depth();
- attribs[cnt++] = AGL_OFFSCREEN;
- if (!format.alpha()) {
- attribs[cnt++] = AGL_ALPHA_SIZE;
- attribs[cnt++] = 8;
- }
- } else {
- if (format.doubleBuffer())
- attribs[cnt++] = AGL_DOUBLEBUFFER;
- }
-
- if (format.stereo())
- attribs[cnt++] = AGL_STEREO;
- if (format.alpha()) {
- attribs[cnt++] = AGL_ALPHA_SIZE;
- attribs[cnt++] = format.alphaBufferSize() == -1 ? 8 : format.alphaBufferSize();
- }
- if (format.stencil()) {
- attribs[cnt++] = AGL_STENCIL_SIZE;
- attribs[cnt++] = format.stencilBufferSize() == -1 ? 8 : format.stencilBufferSize();
- }
- if (format.depth()) {
- attribs[cnt++] = AGL_DEPTH_SIZE;
- attribs[cnt++] = format.depthBufferSize() == -1 ? 32 : format.depthBufferSize();
- }
- if (format.accum()) {
- attribs[cnt++] = AGL_ACCUM_RED_SIZE;
- attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
- attribs[cnt++] = AGL_ACCUM_BLUE_SIZE;
- attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
- attribs[cnt++] = AGL_ACCUM_GREEN_SIZE;
- attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
- attribs[cnt++] = AGL_ACCUM_ALPHA_SIZE;
- attribs[cnt++] = format.accumBufferSize() == -1 ? 1 : format.accumBufferSize();
- }
- if (format.sampleBuffers()) {
- attribs[cnt++] = AGL_SAMPLE_BUFFERS_ARB;
- attribs[cnt++] = 1;
- attribs[cnt++] = AGL_SAMPLES_ARB;
- attribs[cnt++] = format.samples() == -1 ? 4 : format.samples();
- }
-
- attribs[cnt] = AGL_NONE;
- Q_ASSERT(cnt < Max);
- return aglChoosePixelFormat(0, 0, attribs);
-#else
- NSOpenGLPixelFormatAttribute attribs[Max];
- int cnt = 0;
- int devType = paintDevice->devType();
- bool device_is_pixmap = (devType == QInternal::Pixmap);
- int depth = device_is_pixmap ? static_cast<QPixmap *>(paintDevice)->depth() : 32;
-
- attribs[cnt++] = NSOpenGLPFAColorSize;
- attribs[cnt++] = depth;
-
- if (device_is_pixmap) {
- attribs[cnt++] = NSOpenGLPFAOffScreen;
- } else {
- if (format.doubleBuffer())
- attribs[cnt++] = NSOpenGLPFADoubleBuffer;
- }
- if (glFormat.stereo())
- attribs[cnt++] = NSOpenGLPFAStereo;
- if (device_is_pixmap || format.alpha()) {
- attribs[cnt++] = NSOpenGLPFAAlphaSize;
- attribs[cnt++] = def(format.alphaBufferSize(), 8);
- }
- if (format.stencil()) {
- attribs[cnt++] = NSOpenGLPFAStencilSize;
- attribs[cnt++] = def(format.stencilBufferSize(), 8);
- }
- if (format.depth()) {
- attribs[cnt++] = NSOpenGLPFADepthSize;
- attribs[cnt++] = def(format.depthBufferSize(), 32);
- }
- if (format.accum()) {
- attribs[cnt++] = NSOpenGLPFAAccumSize;
- attribs[cnt++] = def(format.accumBufferSize(), 1);
- }
- if (format.sampleBuffers()) {
- attribs[cnt++] = NSOpenGLPFASampleBuffers;
- attribs[cnt++] = 1;
- attribs[cnt++] = NSOpenGLPFASamples;
- attribs[cnt++] = def(format.samples(), 4);
- }
-
- if (format.directRendering())
- attribs[cnt++] = NSOpenGLPFAAccelerated;
-
- if (devType == QInternal::Pbuffer)
- attribs[cnt++] = NSOpenGLPFAPixelBuffer;
-
- attribs[cnt] = 0;
- Q_ASSERT(cnt < Max);
- return [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
-#endif
-}
-
-void QGLContextPrivate::clearDrawable()
-{
- [static_cast<NSOpenGLContext *>(cx) clearDrawable];
-}
-
-/*!
- \bold{Mac OS X only:} This virtual function tries to find a visual that
- matches the format, reducing the demands if the original request
- cannot be met.
-
- The algorithm for reducing the demands of the format is quite
- simple-minded, so override this method in your subclass if your
- application has spcific requirements on visual selection.
-
- The \a handle argument is always zero and is not used
-
- \sa chooseContext()
-*/
-
-void *QGLContext::chooseMacVisual(GDHandle /* handle */)
-{
- Q_D(QGLContext);
-
- void *fmt = d->tryFormat(d->glFormat);
- if (!fmt && d->glFormat.stereo()) {
- d->glFormat.setStereo(false);
- fmt = d->tryFormat(d->glFormat);
- }
- if (!fmt && d->glFormat.sampleBuffers()) {
- d->glFormat.setSampleBuffers(false);
- fmt = d->tryFormat(d->glFormat);
- }
- if (!fmt)
- qWarning("QGLContext::chooseMacVisual: Unable to choose a pixel format");
- return fmt;
-}
-
-void QGLContext::reset()
-{
- Q_D(QGLContext);
- if (!d->valid)
- return;
- d->cleanup();
- doneCurrent();
-#ifndef QT_MAC_USE_COCOA
- if (d->cx)
- aglDestroyContext((AGLContext)d->cx);
-#else
- QMacCocoaAutoReleasePool pool;
- [static_cast<NSOpenGLContext *>(d->cx) release];
-#endif
- d->cx = 0;
-#ifndef QT_MAC_USE_COCOA
- if (d->vi)
- aglDestroyPixelFormat((AGLPixelFormat)d->vi);
-#else
- [static_cast<NSOpenGLPixelFormat *>(d->vi) release];
-#endif
- d->vi = 0;
- d->crWin = false;
- d->sharing = false;
- d->valid = false;
- d->transpColor = QColor();
- d->initDone = false;
- QGLContextGroup::removeShare(this);
-}
-
-void QGLContext::makeCurrent()
-{
- Q_D(QGLContext);
-
- if (!d->valid) {
- qWarning("QGLContext::makeCurrent: Cannot make invalid context current");
- return;
- }
-#ifndef QT_MAC_USE_COCOA
- aglSetCurrentContext((AGLContext)d->cx);
- if (d->update)
- updatePaintDevice();
-#else
- [static_cast<NSOpenGLContext *>(d->cx) makeCurrentContext];
-#endif
- QGLContextPrivate::setCurrentContext(this);
-}
-
-#ifndef QT_MAC_USE_COCOA
-/*
- Returns the effective scale factor for a widget. For this value to be
- different than 1, the following must be true:
- - The system scale factor must be greater than 1.
- - The widget window must have WA_MacFrameworkScaled set.
-*/
-float qt_mac_get_scale_factor(QWidget *widget)
-{
- if (!widget | !widget->window())
- return 1;
-
- if (widget->window()->testAttribute(Qt::WA_MacFrameworkScaled) == false)
- return 1;
-
- float systemScale = QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4 ? HIGetScaleFactor() : 1;
- if (systemScale == float(1))
- return 1;
-
- return systemScale;
-}
-#endif
-
-/*! \internal
-*/
-void QGLContext::updatePaintDevice()
-{
- Q_D(QGLContext);
-#ifndef QT_MAC_USE_COCOA
- d->update = false;
- if (d->paintDevice->devType() == QInternal::Widget) {
- //get control information
- QWidget *w = (QWidget *)d->paintDevice;
- HIViewRef hiview = (HIViewRef)w->winId();
- WindowRef window = HIViewGetWindow(hiview);
-#ifdef DEBUG_OPENGL_REGION_UPDATE
- static int serial_no_gl = 0;
- qDebug("[%d] %p setting on %s::%s %p/%p [%s]", ++serial_no_gl, w,
- w->metaObject()->className(), w->objectName().toLatin1().constData(),
- hiview, window, w->handle() ? "Inside" : "Outside");
-#endif
-
- //update drawable
- if (0 && w->isWindow() && w->isFullScreen()) {
- aglSetDrawable((AGLContext)d->cx, 0);
- aglSetFullScreen((AGLContext)d->cx, w->width(), w->height(), 0, QApplication::desktop()->screenNumber(w));
- w->hide();
- } else {
- AGLDrawable old_draw = aglGetDrawable((AGLContext)d->cx), new_draw = GetWindowPort(window);
- if (old_draw != new_draw)
- aglSetDrawable((AGLContext)d->cx, new_draw);
- }
-
- float scale = qt_mac_get_scale_factor(w);
-
- if (!w->isWindow()) {
- QRegion clp = qt_mac_get_widget_rgn(w); //get drawable area
-
-#ifdef DEBUG_OPENGL_REGION_UPDATE
- if (clp.isEmpty()) {
- qDebug(" Empty area!");
- } else {
- QVector<QRect> rs = clp.rects();
- for(int i = 0; i < rs.count(); i++)
- qDebug(" %d %d %d %d", rs[i].x(), rs[i].y(), rs[i].width(), rs[i].height());
- }
-#endif
- //update the clip
- if (!aglIsEnabled((AGLContext)d->cx, AGL_BUFFER_RECT))
- aglEnable((AGLContext)d->cx, AGL_BUFFER_RECT);
- if (clp.isEmpty()) {
- GLint offs[4] = { 0, 0, 0, 0 };
- aglSetInteger((AGLContext)d->cx, AGL_BUFFER_RECT, offs);
- if (aglIsEnabled((AGLContext)d->cx, AGL_CLIP_REGION))
- aglDisable((AGLContext)d->cx, AGL_CLIP_REGION);
- } else {
- HIPoint origin = { 0., 0. };
- HIViewConvertPoint(&origin, HIViewRef(w->winId()), 0);
- const GLint offs[4] = { qRound(origin.x),
- w->window()->frameGeometry().height() * scale
- - (qRound(origin.y) + w->height() * scale),
- w->width() * scale, w->height() * scale};
-
- RgnHandle region = clp.handle(true);
-
- if (scale != float(1)) {
- // Sacle the clip region by the scale factor
- Rect regionBounds;
- GetRegionBounds(region, &regionBounds);
- Rect regionBoundsDest = regionBounds;
- regionBoundsDest.bottom *= scale;
- regionBoundsDest.right *= scale;
- MapRgn(region, &regionBounds, &regionBoundsDest);
- }
-
- aglSetInteger((AGLContext)d->cx, AGL_BUFFER_RECT, offs);
- aglSetInteger((AGLContext)d->cx, AGL_CLIP_REGION, (const GLint *)region);
- if (!aglIsEnabled((AGLContext)d->cx, AGL_CLIP_REGION))
- aglEnable((AGLContext)d->cx, AGL_CLIP_REGION);
- }
- } else {
- // Set the buffer rect for top-level gl contexts when scaled.
- if (scale != float(1)) {
- aglEnable((AGLContext)d->cx, AGL_BUFFER_RECT);
- const GLint offs[4] = { 0, 0, w->width() * scale , w->height() * scale};
- aglSetInteger((AGLContext)d->cx, AGL_BUFFER_RECT, offs);
- }
- }
- } else if (d->paintDevice->devType() == QInternal::Pixmap) {
- QPixmap *pm = reinterpret_cast<QPixmap *>(d->paintDevice);
-
- unsigned long qdformat = k32ARGBPixelFormat;
- if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
- qdformat = k32BGRAPixelFormat;
- Rect rect;
- SetRect(&rect, 0, 0, pm->width(), pm->height());
-
- GWorldPtr gworld;
- NewGWorldFromPtr(&gworld, qdformat, &rect, 0, 0, 0,
- reinterpret_cast<char *>(qt_mac_pixmap_get_base(pm)),
- qt_mac_pixmap_get_bytes_per_line(pm));
-
- PixMapHandle pixmapHandle = GetGWorldPixMap(gworld);
- aglSetOffScreen(reinterpret_cast<AGLContext>(d->cx), pm->width(), pm->height(),
- GetPixRowBytes(pixmapHandle), GetPixBaseAddr(pixmapHandle));
- } else {
- qWarning("QGLContext::updatePaintDevice(): Not sure how to render OpenGL on this device!");
- }
- aglUpdateContext((AGLContext)d->cx);
-
-#else
- QMacCocoaAutoReleasePool pool;
-
- if (d->paintDevice->devType() == QInternal::Widget) {
- //get control information
- QWidget *w = (QWidget *)d->paintDevice;
- NSView *view = qt_mac_nativeview_for(w);
-
- // Trying to attach the GL context to the NSView will fail with
- // "invalid drawable" if done too soon, but we have to make sure
- // the connection is made before the first paint event. Using
- // the NSView do to this check fails as the NSView is visible
- // before it's safe to connect, and using the NSWindow fails as
- // the NSWindow will become visible after the first paint event.
- // This leaves us with the QWidget, who's visible state seems
- // to match the point in time when it's safe to connect.
- if (!w || !w->isVisible())
- return; // Not safe to attach GL context to view yet
-
- if ([static_cast<NSOpenGLContext *>(d->cx) view] != view && ![view isHidden])
- [static_cast<NSOpenGLContext *>(d->cx) setView:view];
- } else if (d->paintDevice->devType() == QInternal::Pixmap) {
- const QPixmap *pm = static_cast<const QPixmap *>(d->paintDevice);
- [static_cast<NSOpenGLContext *>(d->cx) setOffScreen:qt_mac_pixmap_get_base(pm)
- width:pm->width()
- height:pm->height()
- rowbytes:qt_mac_pixmap_get_bytes_per_line(pm)];
- } else {
- qWarning("QGLContext::updatePaintDevice: Not sure how to render OpenGL on this device");
- }
- [static_cast<NSOpenGLContext *>(d->cx) update];
-#endif
-}
-
-void QGLContext::doneCurrent()
-{
-
- if (
-#ifndef QT_MAC_USE_COCOA
- aglGetCurrentContext() != (AGLContext) d_func()->cx
-#else
- [NSOpenGLContext currentContext] != d_func()->cx
-#endif
- )
- return;
-
- QGLContextPrivate::setCurrentContext(0);
-#ifndef QT_MAC_USE_COCOA
- aglSetCurrentContext(0);
-#else
- [NSOpenGLContext clearCurrentContext];
-#endif
-}
-
-void QGLContext::swapBuffers() const
-{
- Q_D(const QGLContext);
- if (!d->valid)
- return;
-#ifndef QT_MAC_USE_COCOA
- aglSwapBuffers((AGLContext)d->cx);
-#else
- [static_cast<NSOpenGLContext *>(d->cx) flushBuffer];
-#endif
-}
-
-QColor QGLContext::overlayTransparentColor() const
-{
- return QColor(0, 0, 0); // Invalid color
-}
-
-#ifndef QT_MAC_USE_COCOA
-static QColor cmap[256];
-static bool cmap_init = false;
-#endif
-uint QGLContext::colorIndex(const QColor &c) const
-{
-#ifndef QT_MAC_USE_COCOA
- int ret = -1;
- if(!cmap_init) {
- cmap_init = true;
- for(int i = 0; i < 256; i++)
- cmap[i] = QColor();
- } else {
- for(int i = 0; i < 256; i++) {
- if(cmap[i].isValid() && cmap[i] == c) {
- ret = i;
- break;
- }
- }
- }
- if(ret == -1) {
- for(ret = 0; ret < 256; ret++)
- if(!cmap[ret].isValid())
- break;
- if(ret == 256) {
- ret = -1;
- qWarning("QGLContext::colorIndex(): Internal error!");
- } else {
- cmap[ret] = c;
-
- GLint vals[4];
- vals[0] = ret;
- vals[1] = c.red();
- vals[2] = c.green();
- vals[3] = c.blue();
- aglSetInteger((AGLContext)d_func()->cx, AGL_COLORMAP_ENTRY, vals);
- }
- }
- return (uint)(ret == -1 ? 0 : ret);
-#else
- Q_UNUSED(c);
- return 0;
-#endif
-}
-
-void QGLContext::generateFontDisplayLists(const QFont & /* fnt */, int /* listBase */)
-{
-}
-
-static CFBundleRef qt_getOpenGLBundle()
-{
- CFBundleRef bundle = 0;
- CFStringRef urlString = QCFString::toCFStringRef(QLatin1String("/System/Library/Frameworks/OpenGL.framework"));
- QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
- urlString, kCFURLPOSIXPathStyle, false);
- if (url)
- bundle = CFBundleCreate(kCFAllocatorDefault, url);
- CFRelease(urlString);
- return bundle;
-}
-
-void *QGLContext::getProcAddress(const QString &proc) const
-{
- CFStringRef procName = QCFString(proc).toCFStringRef(proc);
- void *result = CFBundleGetFunctionPointerForName(QCFType<CFBundleRef>(qt_getOpenGLBundle()),
- procName);
- CFRelease(procName);
- return result;
-}
-#ifndef QT_MAC_USE_COCOA
-/*****************************************************************************
- QGLWidget AGL-specific code
- *****************************************************************************/
-
-/****************************************************************************
- Hacks to glue AGL to an HIView
- ***************************************************************************/
-QRegion qt_mac_get_widget_rgn(const QWidget *widget)
-{
- if(!widget->isVisible() || widget->isMinimized())
- return QRegion();
- const QRect wrect = QRect(qt_mac_posInWindow(widget), widget->size());
- if(!wrect.isValid())
- return QRegion();
-
- RgnHandle macr = qt_mac_get_rgn();
- GetControlRegion((HIViewRef)widget->winId(), kControlStructureMetaPart, macr);
- OffsetRgn(macr, wrect.x(), wrect.y());
- QRegion ret = qt_mac_convert_mac_region(macr);
-
- QPoint clip_pos = wrect.topLeft();
- for(const QWidget *last_clip = 0, *clip = widget; clip; last_clip = clip, clip = clip->parentWidget()) {
- if(clip != widget) {
- GetControlRegion((HIViewRef)clip->winId(), kControlStructureMetaPart, macr);
- OffsetRgn(macr, clip_pos.x(), clip_pos.y());
- ret &= qt_mac_convert_mac_region(macr);
- }
- const QObjectList &children = clip->children();
- for(int i = children.size()-1; i >= 0; --i) {
- if(QWidget *child = qobject_cast<QWidget*>(children.at(i))) {
- if(child == last_clip)
- break;
-
- // This check may seem weird, but when we are using a unified toolbar
- // The widget is actually being owned by that toolbar and not by Qt.
- // This means that the geometry it reports will be wrong
- // and will accidentally cause problems when calculating the region
- // So, it is better to skip these widgets since they aren't the hierarchy
- // anyway.
- if (HIViewGetSuperview(HIViewRef(child->winId())) != HIViewRef(clip->winId()))
- continue;
-
- if(child->isVisible() && !child->isMinimized() && !child->isTopLevel()) {
- const QRect childRect = QRect(clip_pos+child->pos(), child->size());
- if(childRect.isValid() && wrect.intersects(childRect)) {
- GetControlRegion((HIViewRef)child->winId(), kControlStructureMetaPart, macr);
- OffsetRgn(macr, childRect.x(), childRect.y());
- ret -= qt_mac_convert_mac_region(macr);
- }
- }
- }
- }
- if(clip->isWindow())
- break;
- clip_pos -= clip->pos();
- }
- qt_mac_dispose_rgn(macr);
- return ret;
-}
-
-#endif
-
-void QGLWidget::setMouseTracking(bool enable)
-{
- QWidget::setMouseTracking(enable);
-}
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
-#ifndef QT_MAC_USE_COCOA
- if (!isWindow())
- d->glcx->d_func()->update = true;
-#endif
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
-#ifdef QT_MAC_USE_COCOA
- d->glcx->updatePaintDevice();
-#endif
-#ifndef QT_MAC_USE_COCOA
- float scale = qt_mac_get_scale_factor(this);
- resizeGL(width() * scale, height() * scale);
-#else
- resizeGL(width(), height());
-#endif
-}
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- return 0;
-}
-
-void QGLWidget::makeOverlayCurrent()
-{
-}
-
-void QGLWidget::updateOverlayGL()
-{
-}
-
-void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
-
- if (d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
- if (!d->glcx->isValid())
- d->glcx->create(shareContext ? shareContext : oldcx);
- if (deleteOldContext && oldcx)
- delete oldcx;
-}
-
-void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget)
-{
- Q_Q(QGLWidget);
-
- initContext(context, shareWidget);
-
- QWidget *current = q;
- while (current) {
- qt_widget_private(current)->glWidgets.append(QWidgetPrivate::GlWidgetInfo(q));
- if (current->isWindow())
- break;
- current = current->parentWidget();
- }
-}
-
-bool QGLWidgetPrivate::renderCxPm(QPixmap*)
-{
- return false;
-}
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- return d_func()->cmap;
-}
-
-void QGLWidget::setColormap(const QGLColormap &)
-{
-}
-
-void QGLWidgetPrivate::updatePaintDevice()
-{
- Q_Q(QGLWidget);
- glcx->updatePaintDevice();
- q->update();
-}
-
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 4c22f0f3d7..668728be20 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -60,24 +60,18 @@
#include "QtCore/qthreadstorage.h"
#include "QtCore/qhash.h"
#include "QtCore/qatomic.h"
-#include "private/qwidget_p.h"
+#include "QtWidgets/private/qwidget_p.h"
+#include "QtGui/private/qopenglcontext_p.h"
#include "qcache.h"
#include "qglpaintdevice_p.h"
-#ifndef QT_NO_EGL
-#include <QtGui/private/qegl_p.h>
-#endif
-
-#if defined(Q_WS_QPA)
-#include <QtGui/QPlatformGLContext>
-#endif
+#include <QtGui/QOpenGLContext>
QT_BEGIN_NAMESPACE
class QGLContext;
class QGLOverlayWidget;
class QPixmap;
-class QPixmapFilter;
#ifdef Q_WS_MAC
# ifdef qDebug
# define old_qDebug qDebug
@@ -96,14 +90,6 @@ QT_END_INCLUDE_NAMESPACE
class QMacWindowChangeEvent;
#endif
-#ifdef Q_WS_QWS
-class QWSGLWindowSurface;
-#endif
-
-#ifndef QT_NO_EGL
-class QEglContext;
-#endif
-
QT_BEGIN_INCLUDE_NAMESPACE
#include <QtOpenGL/private/qglextensions_p.h>
QT_END_INCLUDE_NAMESPACE
@@ -165,15 +151,6 @@ class Q_OPENGL_EXPORT QGLWidgetPrivate : public QWidgetPrivate
public:
QGLWidgetPrivate() : QWidgetPrivate()
, disable_clear_on_painter_begin(false)
-#if defined(Q_WS_QWS)
- , wsurf(0)
-#endif
-#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
- , eglSurfaceWindowId(0)
-#endif
-#if defined(Q_OS_SYMBIAN)
- , eglSurfaceWindowId(0)
-#endif
{
isGLWidget = 1;
}
@@ -199,31 +176,8 @@ public:
#endif
bool disable_clear_on_painter_begin;
-
-#if defined(Q_WS_WIN)
- void updateColormap();
- QGLContext *olcx;
-#elif defined(Q_WS_X11)
- QGLOverlayWidget *olw;
-#ifndef QT_NO_EGL
- void recreateEglSurface();
- WId eglSurfaceWindowId;
-#endif
-#elif defined(Q_WS_MAC)
- QGLContext *olcx;
- void updatePaintDevice();
-#elif defined(Q_WS_QWS)
- QWSGLWindowSurface *wsurf;
-#endif
-#ifdef Q_OS_SYMBIAN
- void recreateEglSurface();
- WId eglSurfaceWindowId;
-#endif
};
-class QGLContextGroupResourceBase;
-class QGLSharedResourceGuard;
-
// QGLContextPrivate has the responsibility of creating context groups.
// QGLContextPrivate maintains the reference counter and destroys
// context groups when needed.
@@ -237,9 +191,6 @@ public:
bool isSharing() const { return m_shares.size() >= 2; }
QList<const QGLContext *> shares() const { return m_shares; }
- void addGuard(QGLSharedResourceGuard *guard);
- void removeGuard(QGLSharedResourceGuard *guard);
-
static void addShare(const QGLContext *context, const QGLContext *share);
static void removeShare(const QGLContext *context);
@@ -249,12 +200,8 @@ private:
QGLExtensionFuncs m_extensionFuncs;
const QGLContext *m_context; // context group's representative
QList<const QGLContext *> m_shares;
- QHash<QGLContextGroupResourceBase *, void *> m_resources;
- QGLSharedResourceGuard *m_guards; // double-linked list of active guards.
QAtomicInt m_refs;
- void cleanupResources(const QGLContext *ctx);
-
friend class QGLContext;
friend class QGLContextPrivate;
friend class QGLContextGroupResourceBase;
@@ -262,7 +209,7 @@ private:
// Get the context that resources for "ctx" will transfer to once
// "ctx" is destroyed. Returns null if nothing is sharing with ctx.
-Q_OPENGL_EXPORT const QGLContext *qt_gl_transfer_context(const QGLContext *);
+const QGLContext *qt_gl_transfer_context(const QGLContext *);
// GL extension definitions
class QGLExtensions {
@@ -351,54 +298,11 @@ public:
void syncGlState(); // Makes sure the GL context's state is what we think it is
void swapRegion(const QRegion &region);
-#if defined(Q_WS_WIN)
- void updateFormatVersion();
-#endif
+ QOpenGLContext *guiGlContext;
+ bool ownContext;
-#if defined(Q_WS_WIN)
- HGLRC rc;
- HDC dc;
- WId win;
- int pixelFormatId;
- QGLCmap* cmap;
- HBITMAP hbitmap;
- HDC hbitmap_hdc;
- Qt::HANDLE threadId;
-#endif
-#ifndef QT_NO_EGL
- QEglContext *eglContext;
- EGLSurface eglSurface;
- void destroyEglSurfaceForDevice();
- EGLSurface eglSurfaceForDevice() const;
- static QEglProperties *extraWindowSurfaceCreationProps;
- static void setExtraWindowSurfaceCreationProps(QEglProperties *props);
-#endif
-
-#if defined(Q_WS_QPA)
- QPlatformGLContext *platformContext;
void setupSharing();
-#elif defined(Q_WS_X11) || defined(Q_WS_MAC)
- void* cx;
-#endif
-#if defined(Q_WS_X11) || defined(Q_WS_MAC)
- void* vi;
-#endif
-#if defined(Q_WS_X11)
- void* pbuf;
- quint32 gpm;
- int screen;
- QHash<QPixmapData*, QPixmap> boundPixmaps;
- QGLTexture *bindTextureFromNativePixmap(QPixmap*, const qint64 key,
- QGLContext::BindOptions options);
- static void destroyGlSurfaceForPixmap(QPixmapData*);
- static void unbindPixmapFromTexture(QPixmapData*);
-#endif
-#if defined(Q_WS_MAC)
- bool update;
- void *tryFormat(const QGLFormat &format);
- void clearDrawable();
-#endif
QGLFormat glFormat;
QGLFormat reqFormat;
GLuint fbo;
@@ -423,10 +327,6 @@ public:
uint workaround_brokenAlphaTexSubImage : 1;
uint workaround_brokenAlphaTexSubImage_init : 1;
-#ifndef QT_NO_EGL
- uint ownsEglContext : 1;
-#endif
-
QPaintDevice *paintDevice;
QColor transpColor;
QGLContext *q_ptr;
@@ -439,7 +339,6 @@ public:
GLuint current_fbo;
GLuint default_fbo;
QPaintEngine *active_engine;
- QHash<QGLContextResourceBase *, void *> m_resources;
QGLTextureDestroyer *texture_destroyer;
QGLFunctions *functions;
@@ -448,14 +347,8 @@ public:
static inline QGLContextGroup *contextGroup(const QGLContext *ctx) { return ctx->d_ptr->group; }
-#ifdef Q_WS_WIN
- static inline QGLExtensionFuncs& extensionFuncs(const QGLContext *ctx) { return ctx->d_ptr->group->extensionFuncs(); }
-#endif
-
-#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN)
static Q_OPENGL_EXPORT QGLExtensionFuncs qt_extensionFuncs;
static Q_OPENGL_EXPORT QGLExtensionFuncs& extensionFuncs(const QGLContext *);
-#endif
static void setCurrentContext(QGLContext *context);
};
@@ -508,34 +401,19 @@ class Q_OPENGL_EXPORT QGLTextureDestroyer : public QObject
public:
QGLTextureDestroyer() : QObject() {
qRegisterMetaType<GLuint>("GLuint");
- connect(this, SIGNAL(freeTexture(QGLContext *, QPixmapData *, GLuint)),
- this, SLOT(freeTexture_slot(QGLContext *, QPixmapData *, GLuint)));
+ connect(this, SIGNAL(freeTexture(QGLContext *, QPlatformPixmap *, GLuint)),
+ this, SLOT(freeTexture_slot(QGLContext *, QPlatformPixmap *, GLuint)));
}
- void emitFreeTexture(QGLContext *context, QPixmapData *boundPixmap, GLuint id) {
+ void emitFreeTexture(QGLContext *context, QPlatformPixmap *boundPixmap, GLuint id) {
emit freeTexture(context, boundPixmap, id);
}
Q_SIGNALS:
- void freeTexture(QGLContext *context, QPixmapData *boundPixmap, GLuint id);
+ void freeTexture(QGLContext *context, QPlatformPixmap *boundPixmap, GLuint id);
private slots:
- void freeTexture_slot(QGLContext *context, QPixmapData *boundPixmap, GLuint id) {
+ void freeTexture_slot(QGLContext *context, QPlatformPixmap *boundPixmap, GLuint id) {
Q_UNUSED(boundPixmap);
-#if defined(Q_WS_X11)
- if (boundPixmap) {
- QGLContext *oldContext = const_cast<QGLContext *>(QGLContext::currentContext());
- context->makeCurrent();
- // Although glXReleaseTexImage is a glX call, it must be called while there
- // is a current context - the context the pixmap was bound to a texture in.
- // Otherwise the release doesn't do anything and you get BadDrawable errors
- // when you come to delete the context.
- QGLContextPrivate::unbindPixmapFromTexture(boundPixmap);
- glDeleteTextures(1, &id);
- if (oldContext)
- oldContext->makeCurrent();
- return;
- }
-#endif
QGLShareContextScope scope(context);
glDeleteTextures(1, &id);
}
@@ -562,17 +440,12 @@ public:
id(tx_id),
target(tx_target),
options(opt)
-#if defined(Q_WS_X11)
- , boundPixmap(0)
-#endif
{}
~QGLTexture() {
if (options & QGLContext::MemoryManagedBindOption) {
Q_ASSERT(context);
-#if !defined(Q_WS_X11)
- QPixmapData *boundPixmap = 0;
-#endif
+ QPlatformPixmap *boundPixmap = 0;
context->d_ptr->texture_destroyer->emitFreeTexture(context, boundPixmap, id);
}
}
@@ -583,10 +456,6 @@ public:
QGLContext::BindOptions options;
-#if defined(Q_WS_X11)
- QPixmapData* boundPixmap;
-#endif
-
bool canBindCompressedTexture
(const char *buf, int len, const char *format, bool *hasAlpha);
QSize bindCompressedTexture
@@ -629,8 +498,8 @@ public:
void removeContextTextures(QGLContext *ctx);
static QGLTextureCache *instance();
static void cleanupTexturesForCacheKey(qint64 cacheKey);
- static void cleanupTexturesForPixampData(QPixmapData* pixmap);
- static void cleanupBeforePixmapDestruction(QPixmapData* pixmap);
+ static void cleanupTexturesForPixampData(QPlatformPixmap* pixmap);
+ static void cleanupBeforePixmapDestruction(QPlatformPixmap* pixmap);
private:
QCache<QGLTextureCacheKey, QGLTexture> m_cache;
@@ -661,199 +530,71 @@ QGLTexture* QGLTextureCache::getTexture(QGLContext *ctx, qint64 key)
return m_cache.object(cacheKey);
}
-extern Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine();
-
-bool qt_gl_preferGL2Engine();
-
-inline GLenum qt_gl_preferredTextureFormat()
-{
- return (QGLExtensions::glExtensions() & QGLExtensions::BGRATextureFormat) && QSysInfo::ByteOrder == QSysInfo::LittleEndian
- ? GL_BGRA : GL_RGBA;
-}
-
-inline GLenum qt_gl_preferredTextureTarget()
-{
-#if defined(QT_OPENGL_ES_2)
- return GL_TEXTURE_2D;
-#else
- return (QGLExtensions::glExtensions() & QGLExtensions::TextureRectangle)
- && !qt_gl_preferGL2Engine()
- ? GL_TEXTURE_RECTANGLE_NV
- : GL_TEXTURE_2D;
-#endif
-}
+extern QPaintEngine* qt_qgl_paint_engine();
-/*
- Base for resources that are shared in a context group.
-*/
-class Q_OPENGL_EXPORT QGLContextGroupResourceBase
-{
-public:
- QGLContextGroupResourceBase();
- virtual ~QGLContextGroupResourceBase();
- void insert(const QGLContext *context, void *value);
- void *value(const QGLContext *context);
- void cleanup(const QGLContext *context);
- void cleanup(const QGLContext *context, void *value);
- virtual void freeResource(void *value) = 0;
-
-protected:
- QList<QGLContextGroup *> m_groups;
-
-private:
- QAtomicInt active;
-};
-
-/*
- The QGLContextGroupResource template is used to manage a resource
- for a group of sharing GL contexts. When the last context in the
- group is destroyed, or when the QGLContextGroupResource object
- itself is destroyed (implies potential context switches), the
- resource will be freed.
-
- The class used as the template class type needs to have a
- constructor with the following signature:
- T(const QGLContext *);
-*/
-template <class T>
-class QGLContextGroupResource : public QGLContextGroupResourceBase
+// Put a guard around a GL object identifier and its context.
+// When the context goes away, a shared context will be used
+// in its place. If there are no more shared contexts, then
+// the identifier is returned as zero - it is assumed that the
+// context destruction cleaned up the identifier in this case.
+class QGLSharedResourceGuardBase : public QOpenGLSharedResource
{
public:
- ~QGLContextGroupResource() {
- for (int i = 0; i < m_groups.size(); ++i) {
- const QGLContext *context = m_groups.at(i)->context();
- T *resource = reinterpret_cast<T *>(QGLContextGroupResourceBase::value(context));
- if (resource) {
- QGLShareContextScope scope(context);
- delete resource;
- }
- }
+ QGLSharedResourceGuardBase(QGLContext *context, GLuint id)
+ : QOpenGLSharedResource(context->contextHandle()->shareGroup())
+ , m_id(id)
+ {
}
- T *value(const QGLContext *context) {
- T *resource = reinterpret_cast<T *>(QGLContextGroupResourceBase::value(context));
- if (!resource) {
- resource = new T(context);
- insert(context, resource);
- }
- return resource;
+ GLuint id() const
+ {
+ return m_id;
}
protected:
- void freeResource(void *resource) {
- delete reinterpret_cast<T *>(resource);
- }
-};
-
-/*
- Base for resources that are context specific.
-*/
-class Q_OPENGL_EXPORT QGLContextResourceBase
-{
-public:
- virtual ~QGLContextResourceBase() {
- for (int i = 0; i < m_contexts.size(); ++i)
- m_contexts.at(i)->d_ptr->m_resources.remove(this);
- }
-
- void insert(const QGLContext *context, void *value) {
- context->d_ptr->m_resources.insert(this, value);
- }
-
- void *value(const QGLContext *context) {
- return context->d_ptr->m_resources.value(this, 0);
+ void invalidateResource()
+ {
+ m_id = 0;
}
- virtual void freeResource(void *value) = 0;
-protected:
- QList<const QGLContext *> m_contexts;
-};
-
-/*
- The QGLContextResource template is used to manage a resource for a
- single GL context. Just before the context is destroyed (while it's
- still the current context), or when the QGLContextResource object
- itself is destroyed (implies potential context switches), the
- resource will be freed. The class used as the template class type
- needs to have a constructor with the following signature: T(const
- QGLContext *);
-*/
-template <class T>
-class QGLContextResource : public QGLContextResourceBase
-{
-public:
- ~QGLContextResource() {
- for (int i = 0; i < m_contexts.size(); ++i) {
- const QGLContext *context = m_contexts.at(i);
- T *resource = reinterpret_cast<T *>(QGLContextResourceBase::value(context));
- if (resource) {
- QGLShareContextScope scope(context);
- delete resource;
- }
+ void freeResource(QOpenGLContext *context)
+ {
+ if (m_id) {
+ freeResource(QGLContext::fromOpenGLContext(context), m_id);
}
}
- T *value(const QGLContext *context) {
- T *resource = reinterpret_cast<T *>(QGLContextResourceBase::value(context));
- if (!resource) {
- resource = new T(context);
- insert(context, resource);
- }
- return resource;
- }
+ virtual void freeResource(QGLContext *ctx, GLuint id) = 0;
-protected:
- void freeResource(void *resource) {
- delete reinterpret_cast<T *>(resource);
- }
+private:
+ GLuint m_id;
};
-// Put a guard around a GL object identifier and its context.
-// When the context goes away, a shared context will be used
-// in its place. If there are no more shared contexts, then
-// the identifier is returned as zero - it is assumed that the
-// context destruction cleaned up the identifier in this case.
-class Q_OPENGL_EXPORT QGLSharedResourceGuard
+template <typename Func>
+class QGLSharedResourceGuard : public QGLSharedResourceGuardBase
{
public:
- QGLSharedResourceGuard(const QGLContext *context)
- : m_group(0), m_id(0), m_next(0), m_prev(0)
- {
- setContext(context);
- }
- QGLSharedResourceGuard(const QGLContext *context, GLuint id)
- : m_group(0), m_id(id), m_next(0), m_prev(0)
+ QGLSharedResourceGuard(QGLContext *context, GLuint id, Func func)
+ : QGLSharedResourceGuardBase(context, id)
+ , m_func(func)
{
- setContext(context);
}
- ~QGLSharedResourceGuard();
- const QGLContext *context() const
- {
- return m_group ? m_group->context() : 0;
- }
-
- void setContext(const QGLContext *context);
-
- GLuint id() const
- {
- return m_id;
- }
-
- void setId(GLuint id)
+protected:
+ void freeResource(QGLContext *ctx, GLuint id)
{
- m_id = id;
+ m_func(ctx, id);
}
private:
- QGLContextGroup *m_group;
- GLuint m_id;
- QGLSharedResourceGuard *m_next;
- QGLSharedResourceGuard *m_prev;
-
- friend class QGLContextGroup;
+ Func m_func;
};
+template <typename Func>
+QGLSharedResourceGuardBase *createSharedResourceGuard(QGLContext *context, GLuint id, Func cleanupFunc)
+{
+ return new QGLSharedResourceGuard<Func>(context, id, cleanupFunc);
+}
class QGLExtensionMatcher
{
diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp
index 9ba8b75362..afa2772a6f 100644
--- a/src/opengl/qgl_qpa.cpp
+++ b/src/opengl/qgl_qpa.cpp
@@ -40,12 +40,14 @@
****************************************************************************/
#include <QApplication>
-#include <QtGui/private/qapplication_p.h>
+#include <private/qapplication_p.h>
#include <QPixmap>
#include <QDebug>
-#include <QtGui/private/qapplication_p.h>
+#include <private/qapplication_p.h>
+#include <QtGui/QPlatformOpenGLContext>
#include <QtGui/QPlatformWindow>
+#include <QtGui/QSurfaceFormat>
#include "qgl.h"
#include "qgl_p.h"
@@ -53,81 +55,66 @@
QT_BEGIN_NAMESPACE
/*!
- Returns an OpenGL format for the platform window format specified by \a format.
+ Returns an OpenGL format for the window format specified by \a format.
*/
-QGLFormat QGLFormat::fromPlatformWindowFormat(const QPlatformWindowFormat &format)
+QGLFormat QGLFormat::fromSurfaceFormat(const QSurfaceFormat &format)
{
QGLFormat retFormat;
- retFormat.setAccum(format.accum());
- if (format.accumBufferSize() >= 0)
- retFormat.setAccumBufferSize(format.accumBufferSize());
- retFormat.setAlpha(format.alpha());
if (format.alphaBufferSize() >= 0)
retFormat.setAlphaBufferSize(format.alphaBufferSize());
if (format.blueBufferSize() >= 0)
retFormat.setBlueBufferSize(format.blueBufferSize());
- retFormat.setDepth(format.depth());
- if (format.depthBufferSize() >= 0)
- retFormat.setDepthBufferSize(format.depthBufferSize());
- retFormat.setDirectRendering(format.directRendering());
- retFormat.setDoubleBuffer(format.doubleBuffer());
if (format.greenBufferSize() >= 0)
retFormat.setGreenBufferSize(format.greenBufferSize());
if (format.redBufferSize() >= 0)
retFormat.setRedBufferSize(format.redBufferSize());
- retFormat.setRgba(format.rgba());
- retFormat.setSampleBuffers(format.sampleBuffers());
- retFormat.setSamples(format.sampleBuffers());
- retFormat.setStencil(format.stencil());
- if (format.stencilBufferSize() >= 0)
+ if (format.depthBufferSize() >= 0)
+ retFormat.setDepthBufferSize(format.depthBufferSize());
+ if (format.samples() > 1) {
+ retFormat.setSampleBuffers(format.samples());
+ retFormat.setSamples(true);
+ }
+ if (format.stencilBufferSize() > 0) {
+ retFormat.setStencil(true);
retFormat.setStencilBufferSize(format.stencilBufferSize());
+ }
+ retFormat.setDoubleBuffer(format.swapBehavior() != QSurfaceFormat::SingleBuffer);
retFormat.setStereo(format.stereo());
- retFormat.setSwapInterval(format.swapInterval());
return retFormat;
}
/*!
- Returns a platform window format for the OpenGL format specified by \a format.
+ Returns a window format for the OpenGL format specified by \a format.
*/
-QPlatformWindowFormat QGLFormat::toPlatformWindowFormat(const QGLFormat &format)
+QSurfaceFormat QGLFormat::toSurfaceFormat(const QGLFormat &format)
{
- QPlatformWindowFormat retFormat;
- retFormat.setAccum(format.accum());
- if (format.accumBufferSize() >= 0)
- retFormat.setAccumBufferSize(format.accumBufferSize());
- retFormat.setAlpha(format.alpha());
- if (format.alphaBufferSize() >= 0)
- retFormat.setAlphaBufferSize(format.alphaBufferSize());
+ QSurfaceFormat retFormat;
+ if (format.alpha())
+ retFormat.setAlphaBufferSize(format.alphaBufferSize() == -1 ? 1 : format.alphaBufferSize());
if (format.blueBufferSize() >= 0)
retFormat.setBlueBufferSize(format.blueBufferSize());
- retFormat.setDepth(format.depth());
- if (format.depthBufferSize() >= 0)
- retFormat.setDepthBufferSize(format.depthBufferSize());
- retFormat.setDirectRendering(format.directRendering());
- retFormat.setDoubleBuffer(format.doubleBuffer());
if (format.greenBufferSize() >= 0)
retFormat.setGreenBufferSize(format.greenBufferSize());
if (format.redBufferSize() >= 0)
retFormat.setRedBufferSize(format.redBufferSize());
- retFormat.setRgba(format.rgba());
- retFormat.setSampleBuffers(format.sampleBuffers());
- if (format.samples() >= 0)
- retFormat.setSamples(format.samples());
- retFormat.setStencil(format.stencil());
- if (format.stencilBufferSize() >= 0)
- retFormat.setStencilBufferSize(format.stencilBufferSize());
+ if (format.depth())
+ retFormat.setDepthBufferSize(format.depthBufferSize() == -1 ? 1 : format.depthBufferSize());
+ retFormat.setSwapBehavior(format.doubleBuffer() ? QSurfaceFormat::DoubleBuffer : QSurfaceFormat::DefaultSwapBehavior);
+ if (format.sampleBuffers())
+ retFormat.setSamples(format.samples() == -1 ? 4 : format.samples());
+ if (format.stencil())
+ retFormat.setStencilBufferSize(format.stencilBufferSize() == -1 ? 1 : format.stencilBufferSize());
retFormat.setStereo(format.stereo());
- retFormat.setSwapInterval(format.swapInterval());
return retFormat;
}
void QGLContextPrivate::setupSharing() {
Q_Q(QGLContext);
- QPlatformGLContext *sharedPlatformGLContext = platformContext->platformWindowFormat().sharedGLContext();
- if (sharedPlatformGLContext) {
- QGLContext *actualSharedContext = QGLContext::fromPlatformGLContext(sharedPlatformGLContext);
+ QOpenGLContext *sharedContext = guiGlContext->shareContext();
+ if (sharedContext) {
+ QGLContext *actualSharedContext = QGLContext::fromOpenGLContext(sharedContext);
sharing = true;
- QGLContextGroup::addShare(q,actualSharedContext);
+ QGLContextGroup::addShare(q, actualSharedContext);
}
}
@@ -150,26 +137,30 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
d->valid = false;
}else {
QWidget *widget = static_cast<QWidget *>(d->paintDevice);
- if (!widget->platformWindow()){
- QGLFormat glformat = format();
- QPlatformWindowFormat winFormat = QGLFormat::toPlatformWindowFormat(glformat);
- if (shareContext) {
- winFormat.setSharedContext(shareContext->d_func()->platformContext);
- }
- if (widget->testAttribute(Qt::WA_TranslucentBackground))
- winFormat.setAlpha(true);
- winFormat.setWindowApi(QPlatformWindowFormat::OpenGL);
- winFormat.setWindowSurface(false);
- widget->setPlatformWindowFormat(winFormat);
+ QGLFormat glformat = format();
+ QSurfaceFormat winFormat = QGLFormat::toSurfaceFormat(glformat);
+ if (widget->testAttribute(Qt::WA_TranslucentBackground))
+ winFormat.setAlphaBufferSize(qMax(winFormat.alphaBufferSize(), 8));
+
+ if (!widget->windowHandle()->handle()) {
+ widget->windowHandle()->setSurfaceType(QWindow::OpenGLSurface);
+ widget->windowHandle()->setFormat(winFormat);
widget->winId();//make window
}
- d->platformContext = widget->platformWindow()->glContext();
- Q_ASSERT(d->platformContext);
- d->glFormat = QGLFormat::fromPlatformWindowFormat(d->platformContext->platformWindowFormat());
- d->valid =(bool) d->platformContext;
- if (d->valid) {
- d->platformContext->setQGLContextHandle(this,qDeleteQGLContext);
- }
+
+ if (d->ownContext)
+ delete d->guiGlContext;
+ d->ownContext = true;
+ QOpenGLContext *shareGlContext = shareContext ? shareContext->d_func()->guiGlContext : 0;
+ d->guiGlContext = new QOpenGLContext;
+ d->guiGlContext->setFormat(winFormat);
+ d->guiGlContext->setShareContext(shareGlContext);
+ d->valid = d->guiGlContext->create();
+
+ if (d->valid)
+ d->guiGlContext->setQGLContextHandle(this,qDeleteQGLContext);
+
+ d->glFormat = QGLFormat::fromSurfaceFormat(d->guiGlContext->format());
d->setupSharing();
}
@@ -190,42 +181,60 @@ void QGLContext::reset()
d->transpColor = QColor();
d->initDone = false;
QGLContextGroup::removeShare(this);
- if (d->platformContext) {
- d->platformContext->setQGLContextHandle(0,0);
+ if (d->guiGlContext) {
+ if (d->ownContext)
+ delete d->guiGlContext;
+ else
+ d->guiGlContext->setQGLContextHandle(0,0);
+ d->guiGlContext = 0;
}
+ d->ownContext = false;
}
void QGLContext::makeCurrent()
{
Q_D(QGLContext);
- d->platformContext->makeCurrent();
+ if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget)
+ return;
+
+ QWidget *widget = static_cast<QWidget *>(d->paintDevice);
+ if (!widget->windowHandle())
+ return;
- if (!d->workaroundsCached) {
- d->workaroundsCached = true;
- const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
- if (renderer && strstr(renderer, "Mali")) {
- d->workaround_brokenFBOReadBack = true;
+ if (d->guiGlContext->makeCurrent(widget->windowHandle())) {
+ if (!d->workaroundsCached) {
+ d->workaroundsCached = true;
+ const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
+ if (renderer && strstr(renderer, "Mali")) {
+ d->workaround_brokenFBOReadBack = true;
+ }
}
}
-
}
void QGLContext::doneCurrent()
{
Q_D(QGLContext);
- d->platformContext->doneCurrent();
+ d->guiGlContext->doneCurrent();
}
void QGLContext::swapBuffers() const
{
Q_D(const QGLContext);
- d->platformContext->swapBuffers();
+ if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget)
+ return;
+
+ QWidget *widget = static_cast<QWidget *>(d->paintDevice);
+ if (!widget->windowHandle())
+ return;
+
+ d->guiGlContext->swapBuffers(widget->windowHandle());
}
void *QGLContext::getProcAddress(const QString &procName) const
{
Q_D(const QGLContext);
- return d->platformContext->getProcAddress(procName);
+ return (void *)d->guiGlContext->getProcAddress(procName.toAscii());
}
void QGLWidget::setContext(QGLContext *context,
@@ -283,33 +292,34 @@ void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
class QGLTemporaryContextPrivate
{
public:
- QWidget *widget;
- QPlatformGLContext *context;
+ QWindow *window;
+ QOpenGLContext *context;
+
+ QGLContext *oldContext;
};
QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
: d(new QGLTemporaryContextPrivate)
{
- d->context = const_cast<QPlatformGLContext *>(QPlatformGLContext::currentContext());
- if (d->context)
- d->context->doneCurrent();
- d->widget = new QWidget;
- d->widget->setGeometry(0,0,3,3);
- QPlatformWindowFormat format = d->widget->platformWindowFormat();
- format.setWindowApi(QPlatformWindowFormat::OpenGL);
- format.setWindowSurface(false);
- d->widget->setPlatformWindowFormat(format);
- d->widget->winId();
+ d->oldContext = const_cast<QGLContext *>(QGLContext::currentContext());
- d->widget->platformWindow()->glContext()->makeCurrent();
+ d->window = new QWindow;
+ d->window->setSurfaceType(QWindow::OpenGLSurface);
+ d->window->setGeometry(QRect(0, 0, 3, 3));
+ d->window->create();
+
+ d->context = new QOpenGLContext;
+ d->context->create();
+ d->context->makeCurrent(d->window);
}
QGLTemporaryContext::~QGLTemporaryContext()
{
- d->widget->platformWindow()->glContext()->doneCurrent();
- if (d->context)
- d->context->makeCurrent();
- delete d->widget;
+ if (d->oldContext)
+ d->oldContext->makeCurrent();
+
+ delete d->context;
+ delete d->window;
}
@@ -375,29 +385,35 @@ void QGLWidget::setColormap(const QGLColormap & c)
Q_UNUSED(c);
}
-QGLContext::QGLContext(QPlatformGLContext *platformContext)
+QGLContext::QGLContext(QOpenGLContext *context)
: d_ptr(new QGLContextPrivate(this))
{
Q_D(QGLContext);
- d->init(0,QGLFormat::fromPlatformWindowFormat(platformContext->platformWindowFormat()));
- d->platformContext = platformContext;
- d->platformContext->setQGLContextHandle(this,qDeleteQGLContext);
- d->valid = true;
+ d->init(0, QGLFormat::fromSurfaceFormat(context->format()));
+ d->guiGlContext = context;
+ d->guiGlContext->setQGLContextHandle(this,qDeleteQGLContext);
+ d->ownContext = false;
+ d->valid = context->isValid();
d->setupSharing();
}
+QOpenGLContext *QGLContext::contextHandle() const
+{
+ Q_D(const QGLContext);
+ return d->guiGlContext;
+}
+
/*!
- Returns a OpenGL context for the platform-specific OpenGL context given by
- \a platformContext.
+ Returns a OpenGL context for the window context specified by \a windowContext
*/
-QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContext)
+QGLContext *QGLContext::fromOpenGLContext(QOpenGLContext *context)
{
- if (!platformContext)
+ if (!context)
return 0;
- if (platformContext->qGLContextHandle()) {
- return reinterpret_cast<QGLContext *>(platformContext->qGLContextHandle());
+ if (context->qGLContextHandle()) {
+ return reinterpret_cast<QGLContext *>(context->qGLContextHandle());
}
- QGLContext *glContext = new QGLContext(platformContext);
+ QGLContext *glContext = new QGLContext(context);
//Dont call create on context. This can cause the platformFormat to be set on the widget, which
//will cause the platformWindow to be recreated.
return glContext;
diff --git a/src/opengl/qgl_qws.cpp b/src/opengl/qgl_qws.cpp
deleted file mode 100644
index c0844786e2..0000000000
--- a/src/opengl/qgl_qws.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgl.h"
-#include "qgl_egl_p.h"
-#include "qglpixelbuffer.h"
-
-#include <qglscreen_qws.h>
-#include <qscreenproxy_qws.h>
-#include <private/qglwindowsurface_qws_p.h>
-
-#include <private/qbackingstore_p.h>
-#include <private/qfont_p.h>
-#include <private/qfontengine_p.h>
-#include <private/qgl_p.h>
-#include <private/qpaintengine_opengl_p.h>
-#include <qpixmap.h>
-#include <qtimer.h>
-#include <qapplication.h>
-#include <qstack.h>
-#include <qdesktopwidget.h>
-#include <qdebug.h>
-#include <qvarlengtharray.h>
-
-QT_BEGIN_NAMESPACE
-
-static QGLScreen *glScreenForDevice(QPaintDevice *device)
-{
- QScreen *screen = qt_screen;
- if (screen->classId() == QScreen::MultiClass) {
- int screenNumber;
- if (device && device->devType() == QInternal::Widget)
- screenNumber = qApp->desktop()->screenNumber(static_cast<QWidget *>(device));
- else
- screenNumber = 0;
- screen = screen->subScreens()[screenNumber];
- }
- while (screen->classId() == QScreen::ProxyClass ||
- screen->classId() == QScreen::TransformedClass) {
- screen = static_cast<QProxyScreen *>(screen)->screen();
- }
- if (screen->classId() == QScreen::GLClass)
- return static_cast<QGLScreen *>(screen);
- else
- return 0;
-}
-
-/*
- QGLTemporaryContext implementation
-*/
-
-class QGLTemporaryContextPrivate
-{
-public:
- QGLWidget *widget;
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
- : d(new QGLTemporaryContextPrivate)
-{
- d->widget = new QGLWidget;
- d->widget->makeCurrent();
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- delete d->widget;
-}
-
-/*****************************************************************************
- QOpenGL debug facilities
- *****************************************************************************/
-//#define DEBUG_OPENGL_REGION_UPDATE
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- QGLScreen *glScreen = glScreenForDevice(0);
- if (glScreen)
- return (glScreen->options() & QGLScreen::Overlays);
- else
- return false;
-}
-
-static EGLSurface qt_egl_create_surface
- (QEglContext *context, QPaintDevice *device,
- const QEglProperties *properties = 0)
-{
- // Get the screen surface functions, which are used to create native ids.
- QGLScreen *glScreen = glScreenForDevice(device);
- if (!glScreen)
- return EGL_NO_SURFACE;
- QGLScreenSurfaceFunctions *funcs = glScreen->surfaceFunctions();
- if (!funcs)
- return EGL_NO_SURFACE;
-
- // Create the native drawable for the paint device.
- int devType = device->devType();
- EGLNativePixmapType pixmapDrawable = 0;
- EGLNativeWindowType windowDrawable = 0;
- bool ok;
- if (devType == QInternal::Pixmap) {
- ok = funcs->createNativePixmap(static_cast<QPixmap *>(device), &pixmapDrawable);
- } else if (devType == QInternal::Image) {
- ok = funcs->createNativeImage(static_cast<QImage *>(device), &pixmapDrawable);
- } else {
- ok = funcs->createNativeWindow(static_cast<QWidget *>(device), &windowDrawable);
- }
- if (!ok) {
- qWarning("QEglContext::createSurface(): Cannot create the native EGL drawable");
- return EGL_NO_SURFACE;
- }
-
- // Create the EGL surface to draw into, based on the native drawable.
- const int *props;
- if (properties)
- props = properties->properties();
- else
- props = 0;
- EGLSurface surf;
- if (devType == QInternal::Widget) {
- surf = eglCreateWindowSurface
- (context->display(), context->config(), windowDrawable, props);
- } else {
- surf = eglCreatePixmapSurface
- (context->display(), context->config(), pixmapDrawable, props);
- }
- if (surf == EGL_NO_SURFACE)
- qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError());
- return surf;
-}
-
-bool QGLContext::chooseContext(const QGLContext* shareContext)
-{
- Q_D(QGLContext);
-
- // Validate the device.
- if (!device())
- return false;
- int devType = device()->devType();
- if (devType != QInternal::Pixmap && devType != QInternal::Image && devType != QInternal::Widget) {
- qWarning("QGLContext::chooseContext(): Cannot create QGLContext's for paint device type %d", devType);
- return false;
- }
-
- // Get the display and initialize it.
- d->eglContext = new QEglContext();
- d->ownsEglContext = true;
- d->eglContext->setApi(QEgl::OpenGL);
-
- // Construct the configuration we need for this surface.
- QEglProperties configProps;
- qt_eglproperties_set_glformat(configProps, d->glFormat);
- configProps.setDeviceType(devType);
- configProps.setPaintDeviceFormat(device());
- configProps.setRenderableType(QEgl::OpenGL);
-
- // Search for a matching configuration, reducing the complexity
- // each time until we get something that matches.
- if (!d->eglContext->chooseConfig(configProps)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
-
- // Inform the higher layers about the actual format properties.
- qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config());
-
- // Create a new context for the configuration.
- if (!d->eglContext->createContext
- (shareContext ? shareContext->d_func()->eglContext : 0)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
- d->sharing = d->eglContext->isSharing();
- if (d->sharing && shareContext)
- const_cast<QGLContext *>(shareContext)->d_func()->sharing = true;
-
-#if defined(EGL_VERSION_1_1)
- if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget)
- eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval());
-#endif
-
- // Create the EGL surface to draw into. We cannot use
- // QEglContext::createSurface() because it does not have
- // access to the QGLScreen.
- d->eglSurface = qt_egl_create_surface(d->eglContext, device());
- if (d->eglSurface == EGL_NO_SURFACE) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
-
- return true;
-}
-
-
-bool QGLWidget::event(QEvent *e)
-{
- return QWidget::event(e);
-}
-
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
- resizeGL(width(), height());
- //handle overlay
-}
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- return 0;
-}
-
-void QGLWidget::makeOverlayCurrent()
-{
- //handle overlay
-}
-
-void QGLWidget::updateOverlayGL()
-{
- //handle overlay
-}
-
-void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if(context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
-
- if(d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
- if(!d->glcx->isValid())
- d->glcx->create(shareContext ? shareContext : oldcx);
- if(deleteOldContext)
- delete oldcx;
-}
-
-void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget)
-{
- Q_Q(QGLWidget);
-
- QGLScreen *glScreen = glScreenForDevice(q);
- if (glScreen) {
- wsurf = static_cast<QWSGLWindowSurface*>(glScreen->createSurface(q));
- q->setWindowSurface(wsurf);
- }
-
- initContext(context, shareWidget);
-
- if(q->isValid() && glcx->format().hasOverlay()) {
- //no overlay
- qWarning("QtOpenGL ES doesn't currently support overlays");
- }
-}
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- return d_func()->cmap;
-}
-
-void QGLWidget::setColormap(const QGLColormap &)
-{
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgl_symbian.cpp b/src/opengl/qgl_symbian.cpp
deleted file mode 100644
index bc65bcd44a..0000000000
--- a/src/opengl/qgl_symbian.cpp
+++ /dev/null
@@ -1,472 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qgl.h"
-#include <fbs.h>
-#include <private/qt_s60_p.h>
-#include <private/qpixmap_s60_p.h>
-#include <private/qimagepixmapcleanuphooks_p.h>
-#include <private/qgl_p.h>
-#include <private/qpaintengine_opengl_p.h>
-#include <private/qwidget_p.h> // to access QWExtra
-#include <private/qnativeimagehandleprovider_p.h>
-#include "qgl_egl_p.h"
-#include "qpixmapdata_gl_p.h"
-#include "qgltexturepool_p.h"
-#include "qcolormap.h"
-#include <QDebug>
-
-QT_BEGIN_NAMESPACE
-
-// Turn off "direct to window" rendering if EGL cannot support it.
-#if !defined(EGL_RENDER_BUFFER) || !defined(EGL_SINGLE_BUFFER)
-#if defined(QGL_DIRECT_TO_WINDOW)
-#undef QGL_DIRECT_TO_WINDOW
-#endif
-#endif
-
-// Determine if preserved window contents should be used.
-#if !defined(EGL_SWAP_BEHAVIOR) || !defined(EGL_BUFFER_PRESERVED)
-#if !defined(QGL_NO_PRESERVED_SWAP)
-#define QGL_NO_PRESERVED_SWAP 1
-#endif
-#endif
-
-extern int qt_gl_pixmap_serial;
-
-/*
- QGLTemporaryContext implementation
-*/
-
-
-class QGLTemporaryContextPrivate
-{
-public:
- bool initialized;
- RWindow *window;
- EGLContext context;
- EGLSurface surface;
- EGLDisplay display;
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
- : d(new QGLTemporaryContextPrivate)
-{
- d->initialized = false;
- d->window = 0;
- d->context = 0;
- d->surface = 0;
-
- d->display = d->display = QEgl::display();
-
- EGLConfig config;
- int numConfigs = 0;
- EGLint attribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
-#ifdef QT_OPENGL_ES_2
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-#endif
- EGL_NONE
- };
-
- eglChooseConfig(d->display, attribs, &config, 1, &numConfigs);
- if (!numConfigs) {
- qWarning("QGLTemporaryContext: No EGL configurations available.");
- return;
- }
-
- d->window = new RWindow(CCoeEnv::Static()->WsSession());
- d->window->Construct(CCoeEnv::Static()->RootWin(),(uint)this);
-
- d->surface = eglCreateWindowSurface(d->display, config, (EGLNativeWindowType) d->window, NULL);
-
- if (d->surface == EGL_NO_SURFACE) {
- qWarning("QGLTemporaryContext: Error creating EGL surface.");
- delete d->window;
- d->window = 0;
- return;
- }
-
- EGLint contextAttribs[] = {
-#ifdef QT_OPENGL_ES_2
- EGL_CONTEXT_CLIENT_VERSION, 2,
-#endif
- EGL_NONE
- };
- d->context = eglCreateContext(d->display, config, 0, contextAttribs);
- if (d->context != EGL_NO_CONTEXT
- && eglMakeCurrent(d->display, d->surface, d->surface, d->context))
- {
- d->initialized = true;
- } else {
- qWarning("QGLTemporaryContext: Error creating EGL context.");
- d->window = 0;
- return;
- }
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- if (d->initialized) {
- eglMakeCurrent(d->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglDestroyContext(d->display, d->context);
- eglDestroySurface(d->display, d->surface);
- delete d->window;
- }
-}
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- return false;
-}
-
-// Chooses the EGL config and creates the EGL context
-bool QGLContext::chooseContext(const QGLContext* shareContext) // almost same as in qgl_x11egl.cpp
-{
- Q_D(QGLContext);
-
- if (!device())
- return false;
-
- int devType = device()->devType();
-
- if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) {
- qWarning("WARNING: Creating a QGLContext not supported on device type %d", devType);
- return false;
- }
-
- // Get the display and initialize it.
- if (d->eglContext == 0) {
- d->eglContext = new QEglContext();
- d->ownsEglContext = true;
- d->eglContext->setApi(QEgl::OpenGL);
-
- // If the device is a widget with WA_TranslucentBackground set, make sure the glFormat
- // has the alpha channel option set:
- if (devType == QInternal::Widget) {
- QWidget* widget = static_cast<QWidget*>(device());
- if (widget->testAttribute(Qt::WA_TranslucentBackground))
- d->glFormat.setAlpha(true);
- }
-
- // Construct the configuration we need for this surface.
- QEglProperties configProps;
- configProps.setDeviceType(devType);
- configProps.setPaintDeviceFormat(device());
- configProps.setRenderableType(QEgl::OpenGL);
- configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_SWAP_BEHAVIOR_PRESERVED_BIT);
-
- qt_eglproperties_set_glformat(configProps, d->glFormat);
-
- if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
-
- // Create a new context for the configuration.
- QEglContext* eglSharedContext = shareContext ? shareContext->d_func()->eglContext : 0;
- if (!d->eglContext->createContext(eglSharedContext)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
- d->sharing = d->eglContext->isSharing();
- if (d->sharing && shareContext)
- const_cast<QGLContext *>(shareContext)->d_func()->sharing = true;
- }
-
- // Inform the higher layers about the actual format properties
- qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config());
-
- // Do don't create the EGLSurface for everything.
- // QWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface
- // QGLWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface
- // QGLPixelBuffer - no, it creates the surface itself and stores it in QGLPixelBufferPrivate::pbuf
-
- if (devType == QInternal::Widget) {
- if (d->eglSurface != EGL_NO_SURFACE)
- eglDestroySurface(d->eglContext->display(), d->eglSurface);
-
- d->eglSurface = QEgl::createSurface(device(), d->eglContext->config());
-
- eglGetError(); // Clear error state first.
-
-#ifdef QGL_NO_PRESERVED_SWAP
- eglSurfaceAttrib(QEgl::display(), d->eglSurface,
- EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
-
- if (eglGetError() != EGL_SUCCESS)
- qWarning("QGLContext: could not enable destroyed swap behaviour");
-#else
- eglSurfaceAttrib(QEgl::display(), d->eglSurface,
- EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
-
- if (eglGetError() != EGL_SUCCESS)
- qWarning("QGLContext: could not enable preserved swap behaviour");
-#endif
-
- setWindowCreated(true);
- }
-
- return true;
-}
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
-
- if (QGLContext::currentContext())
- doneCurrent();
-
- // Symbian needs to recreate the surface on resize.
- d->recreateEglSurface();
-
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
- resizeGL(width(), height());
- //handle overlay
-}
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- return 0;
-}
-
-void QGLWidget::makeOverlayCurrent()
-{
- //handle overlay
-}
-
-void QGLWidget::updateOverlayGL()
-{
- //handle overlay
-}
-
-void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
- if (!context->deviceIsPixmap() && context->device() != this) {
- qWarning("QGLWidget::setContext: Context must refer to this widget");
- return;
- }
-
- if (d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
-
- bool createFailed = false;
- if (!d->glcx->isValid()) {
- // Create the QGLContext here, which in turn chooses the EGL config
- // and creates the EGL context:
- if (!d->glcx->create(shareContext ? shareContext : oldcx))
- createFailed = true;
- }
- if (createFailed) {
- if (deleteOldContext)
- delete oldcx;
- return;
- }
-
- d->eglSurfaceWindowId = winId(); // Remember the window id we created the surface for
-}
-
-void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget)
-{
- Q_Q(QGLWidget);
-
- initContext(context, shareWidget);
-
- if(q->isValid() && glcx->format().hasOverlay()) {
- //no overlay
- qWarning("QtOpenGL ES doesn't currently support overlays");
- }
-}
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- return d_func()->cmap;
-}
-
-void QGLWidget::setColormap(const QGLColormap &)
-{
-}
-
-void QGLWidgetPrivate::recreateEglSurface()
-{
- Q_Q(QGLWidget);
-
- WId currentId = q->winId();
-
- if (glcx->d_func()->eglSurface != EGL_NO_SURFACE) {
- eglDestroySurface(glcx->d_func()->eglContext->display(),
- glcx->d_func()->eglSurface);
- }
-
- glcx->d_func()->eglSurface = QEgl::createSurface(glcx->device(),
- glcx->d_func()->eglContext->config());
-
-#if !defined(QGL_NO_PRESERVED_SWAP)
- eglGetError(); // Clear error state first.
- eglSurfaceAttrib(QEgl::display(), glcx->d_func()->eglSurface,
- EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
- if (eglGetError() != EGL_SUCCESS) {
- qWarning("QGLContext: could not enable preserved swap");
- }
-#endif
-
- eglSurfaceWindowId = currentId;
-}
-
-static inline bool knownGoodFormat(QImage::Format format)
-{
- switch (format) {
- case QImage::Format_RGB16: // EColor64K
- case QImage::Format_RGB32: // EColor16MU
- case QImage::Format_ARGB32_Premultiplied: // EColor16MAP
- return true;
- default:
- return false;
- }
-}
-
-void QGLPixmapData::fromNativeType(void* pixmap, NativeType type)
-{
- if (type == QPixmapData::FbsBitmap) {
- CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap *>(pixmap);
- QSize size(bitmap->SizeInPixels().iWidth, bitmap->SizeInPixels().iHeight);
- if (size.width() == w && size.height() == h)
- setSerialNumber(++qt_gl_pixmap_serial);
- resize(size.width(), size.height());
- m_source = QVolatileImage(bitmap);
- if (pixelType() == BitmapType) {
- m_source.ensureFormat(QImage::Format_MonoLSB);
- } else if (!knownGoodFormat(m_source.format())) {
- m_source.beginDataAccess();
- QImage::Format format = idealFormat(m_source.imageRef(), Qt::AutoColor);
- m_source.endDataAccess(true);
- m_source.ensureFormat(format);
- }
- m_hasAlpha = m_source.hasAlphaChannel();
- m_hasFillColor = false;
- m_dirty = true;
-
- } else if (type == QPixmapData::VolatileImage && pixmap) {
- // Support QS60Style in more efficient skin graphics retrieval.
- QVolatileImage *img = static_cast<QVolatileImage *>(pixmap);
- if (img->width() == w && img->height() == h)
- setSerialNumber(++qt_gl_pixmap_serial);
- resize(img->width(), img->height());
- m_source = *img;
- m_hasAlpha = m_source.hasAlphaChannel();
- m_hasFillColor = false;
- m_dirty = true;
- } else if (type == QPixmapData::NativeImageHandleProvider && pixmap) {
- destroyTexture();
- nativeImageHandleProvider = static_cast<QNativeImageHandleProvider *>(pixmap);
- // Cannot defer the retrieval, we need at least the size right away.
- createFromNativeImageHandleProvider();
- }
-}
-
-void* QGLPixmapData::toNativeType(NativeType type)
-{
- if (type == QPixmapData::FbsBitmap) {
- if (m_source.isNull())
- m_source = QVolatileImage(w, h, QImage::Format_ARGB32_Premultiplied);
- return m_source.duplicateNativeImage();
- }
-
- return 0;
-}
-
-bool QGLPixmapData::initFromNativeImageHandle(void *handle, const QString &type)
-{
- if (type == QLatin1String("RSgImage")) {
- fromNativeType(handle, QPixmapData::SgImage);
- return true;
- } else if (type == QLatin1String("CFbsBitmap")) {
- fromNativeType(handle, QPixmapData::FbsBitmap);
- return true;
- }
- return false;
-}
-
-void QGLPixmapData::createFromNativeImageHandleProvider()
-{
- void *handle = 0;
- QString type;
- nativeImageHandleProvider->get(&handle, &type);
- if (handle) {
- if (initFromNativeImageHandle(handle, type)) {
- nativeImageHandle = handle;
- nativeImageType = type;
- } else {
- qWarning("QGLPixmapData: Unknown native image type '%s'", qPrintable(type));
- }
- } else {
- qWarning("QGLPixmapData: Native handle is null");
- }
-}
-
-void QGLPixmapData::releaseNativeImageHandle()
-{
- if (nativeImageHandleProvider && nativeImageHandle) {
- nativeImageHandleProvider->release(nativeImageHandle, nativeImageType);
- nativeImageHandle = 0;
- nativeImageType = QString();
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgl_win.cpp b/src/opengl/qgl_win.cpp
deleted file mode 100644
index 3b1643f4c2..0000000000
--- a/src/opengl/qgl_win.cpp
+++ /dev/null
@@ -1,1601 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <qgl.h>
-#include <qlist.h>
-#include <qmap.h>
-#include <qpixmap.h>
-#include <qevent.h>
-#include <private/qgl_p.h>
-#include <qcolormap.h>
-#include <qvarlengtharray.h>
-#include <qdebug.h>
-#include <qcolor.h>
-
-#include <qt_windows.h>
-
-typedef bool (APIENTRY *PFNWGLGETPIXELFORMATATTRIBIVARB)(HDC hdc,
- int iPixelFormat,
- int iLayerPlane,
- uint nAttributes,
- const int *piAttributes,
- int *piValues);
-typedef bool (APIENTRY *PFNWGLCHOOSEPIXELFORMATARB)(HDC hdc,
- const int *piAttribList,
- const float *pfAttribFList,
- uint nMaxFormats,
- int *piFormats,
- UINT *nNumFormats);
-#ifndef WGL_ARB_multisample
-#define WGL_SAMPLE_BUFFERS_ARB 0x2041
-#define WGL_SAMPLES_ARB 0x2042
-#endif
-
-#ifndef WGL_ARB_pixel_format
-#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
-#define WGL_DRAW_TO_WINDOW_ARB 0x2001
-#define WGL_DRAW_TO_BITMAP_ARB 0x2002
-#define WGL_ACCELERATION_ARB 0x2003
-#define WGL_NEED_PALETTE_ARB 0x2004
-#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
-#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
-#define WGL_SWAP_METHOD_ARB 0x2007
-#define WGL_NUMBER_OVERLAYS_ARB 0x2008
-#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
-#define WGL_TRANSPARENT_ARB 0x200A
-#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
-#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
-#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
-#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
-#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
-#define WGL_SHARE_DEPTH_ARB 0x200C
-#define WGL_SHARE_STENCIL_ARB 0x200D
-#define WGL_SHARE_ACCUM_ARB 0x200E
-#define WGL_SUPPORT_GDI_ARB 0x200F
-#define WGL_SUPPORT_OPENGL_ARB 0x2010
-#define WGL_DOUBLE_BUFFER_ARB 0x2011
-#define WGL_STEREO_ARB 0x2012
-#define WGL_PIXEL_TYPE_ARB 0x2013
-#define WGL_COLOR_BITS_ARB 0x2014
-#define WGL_RED_BITS_ARB 0x2015
-#define WGL_RED_SHIFT_ARB 0x2016
-#define WGL_GREEN_BITS_ARB 0x2017
-#define WGL_GREEN_SHIFT_ARB 0x2018
-#define WGL_BLUE_BITS_ARB 0x2019
-#define WGL_BLUE_SHIFT_ARB 0x201A
-#define WGL_ALPHA_BITS_ARB 0x201B
-#define WGL_ALPHA_SHIFT_ARB 0x201C
-#define WGL_ACCUM_BITS_ARB 0x201D
-#define WGL_ACCUM_RED_BITS_ARB 0x201E
-#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
-#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
-#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
-#define WGL_DEPTH_BITS_ARB 0x2022
-#define WGL_STENCIL_BITS_ARB 0x2023
-#define WGL_AUX_BUFFERS_ARB 0x2024
-#define WGL_NO_ACCELERATION_ARB 0x2025
-#define WGL_GENERIC_ACCELERATION_ARB 0x2026
-#define WGL_FULL_ACCELERATION_ARB 0x2027
-#define WGL_SWAP_EXCHANGE_ARB 0x2028
-#define WGL_SWAP_COPY_ARB 0x2029
-#define WGL_SWAP_UNDEFINED_ARB 0x202A
-#define WGL_TYPE_RGBA_ARB 0x202B
-#define WGL_TYPE_COLORINDEX_ARB 0x202C
-#endif
-
-#ifndef WGL_ARB_create_context
-#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
-#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
-#define WGL_CONTEXT_FLAGS_ARB 0x2094
-#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
-#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
-#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
-#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x0001
-#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x0002
-// Error codes returned by GetLastError().
-#define ERROR_INVALID_VERSION_ARB 0x2095
-#define ERROR_INVALID_PROFILE_ARB 0x2096
-#endif
-
-#ifndef GL_VERSION_3_2
-#define GL_CONTEXT_PROFILE_MASK 0x9126
-#define GL_MAJOR_VERSION 0x821B
-#define GL_MINOR_VERSION 0x821C
-#define GL_NUM_EXTENSIONS 0x821D
-#define GL_CONTEXT_FLAGS 0x821E
-#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QGLCmapPrivate
-{
-public:
- QGLCmapPrivate() : count(1) { }
- void ref() { ++count; }
- bool deref() { return !--count; }
- uint count;
-
- enum AllocState{ UnAllocated = 0, Allocated = 0x01, Reserved = 0x02 };
-
- int maxSize;
- QVector<uint> colorArray;
- QVector<quint8> allocArray;
- QVector<quint8> contextArray;
- QMap<uint,int> colorMap;
-};
-
-/*****************************************************************************
- QColorMap class - temporarily here, until it is ready for prime time
- *****************************************************************************/
-
-/****************************************************************************
-**
-** Definition of QColorMap class
-**
-****************************************************************************/
-
-class QGLCmapPrivate;
-
-class /*Q_EXPORT*/ QGLCmap
-{
-public:
- enum Flags { Reserved = 0x01 };
-
- QGLCmap(int maxSize = 256);
- QGLCmap(const QGLCmap& map);
- ~QGLCmap();
-
- QGLCmap& operator=(const QGLCmap& map);
-
- // isEmpty and/or isNull ?
- int size() const;
- int maxSize() const;
-
- void resize(int newSize);
-
- int find(QRgb color) const;
- int findNearest(QRgb color) const;
- int allocate(QRgb color, uint flags = 0, quint8 context = 0);
-
- void setEntry(int idx, QRgb color, uint flags = 0, quint8 context = 0);
-
- const QRgb* colors() const;
-
-private:
- void detach();
- QGLCmapPrivate* d;
-};
-
-
-QGLCmap::QGLCmap(int maxSize) // add a bool prealloc?
-{
- d = new QGLCmapPrivate;
- d->maxSize = maxSize;
-}
-
-
-QGLCmap::QGLCmap(const QGLCmap& map)
-{
- d = map.d;
- d->ref();
-}
-
-
-QGLCmap::~QGLCmap()
-{
- if (d && d->deref())
- delete d;
- d = 0;
-}
-
-
-QGLCmap& QGLCmap::operator=(const QGLCmap& map)
-{
- map.d->ref();
- if (d->deref())
- delete d;
- d = map.d;
- return *this;
-}
-
-
-int QGLCmap::size() const
-{
- return d->colorArray.size();
-}
-
-
-int QGLCmap::maxSize() const
-{
- return d->maxSize;
-}
-
-
-void QGLCmap::detach()
-{
- if (d->count != 1) {
- d->deref();
- QGLCmapPrivate* newd = new QGLCmapPrivate;
- newd->maxSize = d->maxSize;
- newd->colorArray = d->colorArray;
- newd->allocArray = d->allocArray;
- newd->contextArray = d->contextArray;
- newd->colorArray.detach();
- newd->allocArray.detach();
- newd->contextArray.detach();
- newd->colorMap = d->colorMap;
- d = newd;
- }
-}
-
-
-void QGLCmap::resize(int newSize)
-{
- if (newSize < 0 || newSize > d->maxSize) {
- qWarning("QGLCmap::resize(): size out of range");
- return;
- }
- int oldSize = size();
- detach();
- //if shrinking; remove the lost elems from colorMap
- d->colorArray.resize(newSize);
- d->allocArray.resize(newSize);
- d->contextArray.resize(newSize);
- if (newSize > oldSize) {
- memset(d->allocArray.data() + oldSize, 0, newSize - oldSize);
- memset(d->contextArray.data() + oldSize, 0, newSize - oldSize);
- }
-}
-
-
-int QGLCmap::find(QRgb color) const
-{
- QMap<uint,int>::ConstIterator it = d->colorMap.find(color);
- if (it != d->colorMap.end())
- return *it;
- return -1;
-}
-
-
-int QGLCmap::findNearest(QRgb color) const
-{
- int idx = find(color);
- if (idx >= 0)
- return idx;
- int mapSize = size();
- int mindist = 200000;
- int r = qRed(color);
- int g = qGreen(color);
- int b = qBlue(color);
- int rx, gx, bx, dist;
- for (int i=0; i < mapSize; i++) {
- if (!(d->allocArray[i] & QGLCmapPrivate::Allocated))
- continue;
- QRgb ci = d->colorArray[i];
- rx = r - qRed(ci);
- gx = g - qGreen(ci);
- bx = b - qBlue(ci);
- dist = rx*rx + gx*gx + bx*bx; // calculate distance
- if (dist < mindist) { // minimal?
- mindist = dist;
- idx = i;
- }
- }
- return idx;
-}
-
-
-
-
-// Does not always allocate; returns existing c idx if found
-
-int QGLCmap::allocate(QRgb color, uint flags, quint8 context)
-{
- int idx = find(color);
- if (idx >= 0)
- return idx;
-
- int mapSize = d->colorArray.size();
- int newIdx = d->allocArray.indexOf(QGLCmapPrivate::UnAllocated);
-
- if (newIdx < 0) { // Must allocate more room
- if (mapSize < d->maxSize) {
- newIdx = mapSize;
- mapSize++;
- resize(mapSize);
- }
- else {
- //# add a bool param that says what to do in case no more room -
- // fail (-1) or return nearest?
- return -1;
- }
- }
-
- d->colorArray[newIdx] = color;
- if (flags & QGLCmap::Reserved) {
- d->allocArray[newIdx] = QGLCmapPrivate::Reserved;
- }
- else {
- d->allocArray[newIdx] = QGLCmapPrivate::Allocated;
- d->colorMap.insert(color, newIdx);
- }
- d->contextArray[newIdx] = context;
- return newIdx;
-}
-
-
-void QGLCmap::setEntry(int idx, QRgb color, uint flags, quint8 context)
-{
- if (idx < 0 || idx >= d->maxSize) {
- qWarning("QGLCmap::set(): Index out of range");
- return;
- }
- detach();
- int mapSize = size();
- if (idx >= mapSize) {
- mapSize = idx + 1;
- resize(mapSize);
- }
- d->colorArray[idx] = color;
- if (flags & QGLCmap::Reserved) {
- d->allocArray[idx] = QGLCmapPrivate::Reserved;
- }
- else {
- d->allocArray[idx] = QGLCmapPrivate::Allocated;
- d->colorMap.insert(color, idx);
- }
- d->contextArray[idx] = context;
-}
-
-
-const QRgb* QGLCmap::colors() const
-{
- return d->colorArray.data();
-}
-
-
-
-/*****************************************************************************
- QGLFormat Win32/WGL-specific code
- *****************************************************************************/
-
-
-void qwglError(const char* method, const char* func)
-{
-#ifndef QT_NO_DEBUG
- char* lpMsgBuf;
- FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- 0, GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (char*) &lpMsgBuf, 0, 0);
- qWarning("%s : %s failed: %s", method, func, lpMsgBuf);
- LocalFree(lpMsgBuf);
-#else
- Q_UNUSED(method);
- Q_UNUSED(func);
-#endif
-}
-
-
-
-bool QGLFormat::hasOpenGL()
-{
- return true;
-}
-
-static bool opengl32dll = false;
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- // workaround for matrox driver:
- // make a cheap call to opengl to force loading of DLL
- if (!opengl32dll) {
- GLint params;
- glGetIntegerv(GL_DEPTH_BITS, &params);
- opengl32dll = true;
- }
-
- static bool checkDone = false;
- static bool hasOl = false;
-
- if (!checkDone) {
- checkDone = true;
- HDC display_dc = GetDC(0);
- int pfiMax = DescribePixelFormat(display_dc, 0, 0, NULL);
- PIXELFORMATDESCRIPTOR pfd;
- for (int pfi = 1; pfi <= pfiMax; pfi++) {
- DescribePixelFormat(display_dc, pfi, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
- if ((pfd.bReserved & 0x0f) && (pfd.dwFlags & PFD_SUPPORT_OPENGL)) {
- // This format has overlays/underlays
- LAYERPLANEDESCRIPTOR lpd;
- wglDescribeLayerPlane(display_dc, pfi, 1,
- sizeof(LAYERPLANEDESCRIPTOR), &lpd);
- if (lpd.dwFlags & LPD_SUPPORT_OPENGL) {
- hasOl = true;
- break;
- }
- }
- }
- ReleaseDC(0, display_dc);
- }
- return hasOl;
-}
-
-
-/*****************************************************************************
- QGLContext Win32/WGL-specific code
- *****************************************************************************/
-
-static uchar qgl_rgb_palette_comp(int idx, uint nbits, uint shift)
-{
- const uchar map_3_to_8[8] = {
- 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
- };
- const uchar map_2_to_8[4] = {
- 0, 0x55, 0xaa, 0xff
- };
- const uchar map_1_to_8[2] = {
- 0, 255
- };
-
- uchar val = (uchar) (idx >> shift);
- uchar res = 0;
- switch (nbits) {
- case 1:
- val &= 0x1;
- res = map_1_to_8[val];
- break;
- case 2:
- val &= 0x3;
- res = map_2_to_8[val];
- break;
- case 3:
- val &= 0x7;
- res = map_3_to_8[val];
- break;
- default:
- res = 0;
- }
- return res;
-}
-
-
-static QRgb* qgl_create_rgb_palette(const PIXELFORMATDESCRIPTOR* pfd)
-{
- if ((pfd->iPixelType != PFD_TYPE_RGBA) ||
- !(pfd->dwFlags & PFD_NEED_PALETTE) ||
- (pfd->cColorBits != 8))
- return 0;
- int numEntries = 1 << pfd->cColorBits;
- QRgb* pal = new QRgb[numEntries];
- for (int i = 0; i < numEntries; i++) {
- int r = qgl_rgb_palette_comp(i, pfd->cRedBits, pfd->cRedShift);
- int g = qgl_rgb_palette_comp(i, pfd->cGreenBits, pfd->cGreenShift);
- int b = qgl_rgb_palette_comp(i, pfd->cBlueBits, pfd->cBlueShift);
- pal[i] = qRgb(r, g, b);
- }
-
- const int syscol_indices[12] = {
- 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91
- };
-
- const uint syscols[20] = {
- 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080,
- 0x008080, 0xc0c0c0, 0xc0dcc0, 0xa6caf0, 0xfffbf0, 0xa0a0a4,
- 0x808080, 0xff0000, 0x00ff00, 0xffff00, 0x0000ff, 0xff00ff,
- 0x00ffff, 0xffffff
- }; // colors #1 - #12 are not present in pal; gets added below
-
- if ((pfd->cColorBits == 8) &&
- (pfd->cRedBits == 3) && (pfd->cRedShift == 0) &&
- (pfd->cGreenBits == 3) && (pfd->cGreenShift == 3) &&
- (pfd->cBlueBits == 2) && (pfd->cBlueShift == 6)) {
- for (int j = 0 ; j < 12 ; j++)
- pal[syscol_indices[j]] = QRgb(syscols[j+1]);
- }
-
- return pal;
-}
-
-static QGLFormat pfdToQGLFormat(const PIXELFORMATDESCRIPTOR* pfd)
-{
- QGLFormat fmt;
- fmt.setDoubleBuffer(pfd->dwFlags & PFD_DOUBLEBUFFER);
- fmt.setDepth(pfd->cDepthBits);
- if (fmt.depth())
- fmt.setDepthBufferSize(pfd->cDepthBits);
- fmt.setRgba(pfd->iPixelType == PFD_TYPE_RGBA);
- fmt.setRedBufferSize(pfd->cRedBits);
- fmt.setGreenBufferSize(pfd->cGreenBits);
- fmt.setBlueBufferSize(pfd->cBlueBits);
- fmt.setAlpha(pfd->cAlphaBits);
- if (fmt.alpha())
- fmt.setAlphaBufferSize(pfd->cAlphaBits);
- fmt.setAccum(pfd->cAccumBits);
- if (fmt.accum())
- fmt.setAccumBufferSize(pfd->cAccumRedBits);
- fmt.setStencil(pfd->cStencilBits);
- if (fmt.stencil())
- fmt.setStencilBufferSize(pfd->cStencilBits);
- fmt.setStereo(pfd->dwFlags & PFD_STEREO);
- fmt.setDirectRendering((pfd->dwFlags & PFD_GENERIC_ACCELERATED) ||
- !(pfd->dwFlags & PFD_GENERIC_FORMAT));
- fmt.setOverlay((pfd->bReserved & 0x0f) != 0);
- return fmt;
-}
-
-/*
- NB! requires a current GL context to work
-*/
-QGLFormat pfiToQGLFormat(HDC hdc, int pfi)
-{
- QGLFormat fmt;
- QVarLengthArray<int> iAttributes(40);
- QVarLengthArray<int> iValues(40);
- int i = 0;
- bool has_sample_buffers = QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers;
-
- iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB; // 0
- iAttributes[i++] = WGL_DEPTH_BITS_ARB; // 1
- iAttributes[i++] = WGL_PIXEL_TYPE_ARB; // 2
- iAttributes[i++] = WGL_RED_BITS_ARB; // 3
- iAttributes[i++] = WGL_GREEN_BITS_ARB; // 4
- iAttributes[i++] = WGL_BLUE_BITS_ARB; // 5
- iAttributes[i++] = WGL_ALPHA_BITS_ARB; // 6
- iAttributes[i++] = WGL_ACCUM_BITS_ARB; // 7
- iAttributes[i++] = WGL_STENCIL_BITS_ARB; // 8
- iAttributes[i++] = WGL_STEREO_ARB; // 9
- iAttributes[i++] = WGL_ACCELERATION_ARB; // 10
- iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB; // 11
- if (has_sample_buffers) {
- iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; // 12
- iAttributes[i++] = WGL_SAMPLES_ARB; // 13
- }
- PFNWGLGETPIXELFORMATATTRIBIVARB wglGetPixelFormatAttribivARB =
- (PFNWGLGETPIXELFORMATATTRIBIVARB) wglGetProcAddress("wglGetPixelFormatAttribivARB");
-
- if (wglGetPixelFormatAttribivARB
- && wglGetPixelFormatAttribivARB(hdc, pfi, 0, i,
- iAttributes.constData(),
- iValues.data()))
- {
- fmt.setDoubleBuffer(iValues[0]);
- fmt.setDepth(iValues[1]);
- if (fmt.depth())
- fmt.setDepthBufferSize(iValues[1]);
- fmt.setRgba(iValues[2] == WGL_TYPE_RGBA_ARB);
- fmt.setRedBufferSize(iValues[3]);
- fmt.setGreenBufferSize(iValues[4]);
- fmt.setBlueBufferSize(iValues[5]);
- fmt.setAlpha(iValues[6]);
- if (fmt.alpha())
- fmt.setAlphaBufferSize(iValues[6]);
- fmt.setAccum(iValues[7]);
- if (fmt.accum())
- fmt.setAccumBufferSize(iValues[7]);
- fmt.setStencil(iValues[8]);
- if (fmt.stencil())
- fmt.setStencilBufferSize(iValues[8]);
- fmt.setStereo(iValues[9]);
- if (iValues[10] == WGL_FULL_ACCELERATION_ARB)
- fmt.setDirectRendering(true);
- else
- fmt.setDirectRendering(false);
- fmt.setOverlay(iValues[11]);
- if (has_sample_buffers) {
- fmt.setSampleBuffers(iValues[12]);
- if (fmt.sampleBuffers())
- fmt.setSamples(iValues[13]);
- }
- }
-#if 0
- qDebug() << "values for pfi:" << pfi;
- qDebug() << "doublebuffer 0:" << fmt.doubleBuffer();
- qDebug() << "depthbuffer 1:" << fmt.depthBufferSize();
- qDebug() << "rgba 2:" << fmt.rgba();
- qDebug() << "red size 3:" << fmt.redBufferSize();
- qDebug() << "green size 4:" << fmt.greenBufferSize();
- qDebug() << "blue size 5:" << fmt.blueBufferSize();
- qDebug() << "alpha size 6:" << fmt.alphaBufferSize();
- qDebug() << "accum size 7:" << fmt.accumBufferSize();
- qDebug() << "stencil size 8:" << fmt.stencilBufferSize();
- qDebug() << "stereo 9:" << fmt.stereo();
- qDebug() << "direct 10:" << fmt.directRendering();
- qDebug() << "has overlays 11:" << fmt.hasOverlay();
- qDebug() << "sample buff 12:" << fmt.sampleBuffers();
- qDebug() << "num samples 13:" << fmt.samples();
-#endif
- return fmt;
-}
-
-
-/*
- QGLTemporaryContext implementation
-*/
-
-Q_GUI_EXPORT const QString qt_getRegisteredWndClass();
-
-class QGLTemporaryContextPrivate
-{
-public:
- HDC dmy_pdc;
- HGLRC dmy_rc;
- HDC old_dc;
- HGLRC old_context;
- WId dmy_id;
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool directRendering, QWidget *parent)
- : d(new QGLTemporaryContextPrivate)
-{
- QString windowClassName = qt_getRegisteredWndClass();
- if (parent && !parent->internalWinId())
- parent = parent->nativeParentWidget();
-
- d->dmy_id = CreateWindow((const wchar_t *)windowClassName.utf16(),
- 0, 0, 0, 0, 1, 1,
- parent ? parent->winId() : 0, 0, qWinAppInst(), 0);
-
- d->dmy_pdc = GetDC(d->dmy_id);
- PIXELFORMATDESCRIPTOR dmy_pfd;
- memset(&dmy_pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
- dmy_pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
- dmy_pfd.nVersion = 1;
- dmy_pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
- dmy_pfd.iPixelType = PFD_TYPE_RGBA;
- if (!directRendering)
- dmy_pfd.dwFlags |= PFD_GENERIC_FORMAT;
-
- int dmy_pf = ChoosePixelFormat(d->dmy_pdc, &dmy_pfd);
- SetPixelFormat(d->dmy_pdc, dmy_pf, &dmy_pfd);
- d->dmy_rc = wglCreateContext(d->dmy_pdc);
- d->old_dc = wglGetCurrentDC();
- d->old_context = wglGetCurrentContext();
- wglMakeCurrent(d->dmy_pdc, d->dmy_rc);
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- wglMakeCurrent(d->dmy_pdc, 0);
- wglDeleteContext(d->dmy_rc);
- ReleaseDC(d->dmy_id, d->dmy_pdc);
- DestroyWindow(d->dmy_id);
- if (d->old_dc && d->old_context)
- wglMakeCurrent(d->old_dc, d->old_context);
-}
-
-static bool qgl_create_context(HDC hdc, QGLContextPrivate *d, QGLContextPrivate *shareContext)
-{
- d->rc = 0;
-
- typedef HGLRC (APIENTRYP PFNWGLCREATECONTEXTATTRIBSARB)(HDC, HGLRC, const int *);
- PFNWGLCREATECONTEXTATTRIBSARB wglCreateContextAttribsARB =
- (PFNWGLCREATECONTEXTATTRIBSARB) wglGetProcAddress("wglCreateContextAttribsARB");
- if (wglCreateContextAttribsARB) {
- int attributes[11];
- int attribIndex = 0;
- const int major = d->reqFormat.majorVersion();
- const int minor = d->reqFormat.minorVersion();
- attributes[attribIndex++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
- attributes[attribIndex++] = major;
- attributes[attribIndex++] = WGL_CONTEXT_MINOR_VERSION_ARB;
- attributes[attribIndex++] = minor;
-
- if (major >= 3 && !d->reqFormat.testOption(QGL::DeprecatedFunctions)) {
- attributes[attribIndex++] = WGL_CONTEXT_FLAGS_ARB;
- attributes[attribIndex++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
- }
-
- if ((major == 3 && minor >= 2) || major > 3) {
- switch (d->reqFormat.profile()) {
- case QGLFormat::NoProfile:
- break;
- case QGLFormat::CoreProfile:
- attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB;
- attributes[attribIndex++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
- break;
- case QGLFormat::CompatibilityProfile:
- attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB;
- attributes[attribIndex++] = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
- break;
- default:
- qWarning("QGLContext::chooseContext(): Context profile not supported.");
- return false;
- }
- }
-
- if (d->reqFormat.plane() != 0) {
- attributes[attribIndex++] = WGL_CONTEXT_LAYER_PLANE_ARB;
- attributes[attribIndex++] = d->reqFormat.plane();
- }
-
- attributes[attribIndex++] = 0; // Terminate list.
- d->rc = wglCreateContextAttribsARB(hdc, shareContext && shareContext->valid
- ? shareContext->rc : 0, attributes);
- if (d->rc) {
- if (shareContext)
- shareContext->sharing = d->sharing = true;
- return true;
- }
- }
-
- d->rc = wglCreateLayerContext(hdc, d->reqFormat.plane());
- if (d->rc && shareContext && shareContext->valid)
- shareContext->sharing = d->sharing = wglShareLists(shareContext->rc, d->rc);
- return d->rc != 0;
-}
-
-void QGLContextPrivate::updateFormatVersion()
-{
- const GLubyte *s = glGetString(GL_VERSION);
-
- if (!(s && s[0] >= '0' && s[0] <= '9' && s[1] == '.' && s[2] >= '0' && s[2] <= '9')) {
- if (!s)
- qWarning("QGLContext::chooseContext(): OpenGL version string is null.");
- else
- qWarning("QGLContext::chooseContext(): Unexpected OpenGL version string format.");
- glFormat.setVersion(0, 0);
- glFormat.setProfile(QGLFormat::NoProfile);
- glFormat.setOption(QGL::DeprecatedFunctions);
- return;
- }
-
- int major = s[0] - '0';
- int minor = s[2] - '0';
- glFormat.setVersion(major, minor);
-
- if (major < 3) {
- glFormat.setProfile(QGLFormat::NoProfile);
- glFormat.setOption(QGL::DeprecatedFunctions);
- } else {
- GLint value = 0;
- if (major > 3 || minor >= 2)
- glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value);
-
- switch (value) {
- case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
- glFormat.setProfile(QGLFormat::CoreProfile);
- break;
- case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
- glFormat.setProfile(QGLFormat::CompatibilityProfile);
- break;
- default:
- glFormat.setProfile(QGLFormat::NoProfile);
- break;
- }
-
- glGetIntegerv(GL_CONTEXT_FLAGS, &value);
- if (value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
- glFormat.setOption(QGL::NoDeprecatedFunctions);
- else
- glFormat.setOption(QGL::DeprecatedFunctions);
- }
-}
-
-bool QGLContext::chooseContext(const QGLContext* shareContext)
-{
- QGLContextPrivate *share = shareContext ? const_cast<QGLContext *>(shareContext)->d_func() : 0;
-
- Q_D(QGLContext);
- // workaround for matrox driver:
- // make a cheap call to opengl to force loading of DLL
- if (!opengl32dll) {
- GLint params;
- glGetIntegerv(GL_DEPTH_BITS, &params);
- opengl32dll = true;
- }
-
- bool result = true;
- HDC myDc;
- QWidget *widget = 0;
-
- if (deviceIsPixmap()) {
- if (d->glFormat.plane())
- return false; // Pixmaps can't have overlay
- d->win = 0;
- HDC display_dc = GetDC(0);
- myDc = d->hbitmap_hdc = CreateCompatibleDC(display_dc);
- QPixmap *px = static_cast<QPixmap *>(d->paintDevice);
-
- BITMAPINFO bmi;
- memset(&bmi, 0, sizeof(bmi));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = px->width();
- bmi.bmiHeader.biHeight = px->height();
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = BI_RGB;
- d->hbitmap = CreateDIBSection(display_dc, &bmi, DIB_RGB_COLORS, 0, 0, 0);
- SelectObject(myDc, d->hbitmap);
- ReleaseDC(0, display_dc);
- } else {
- widget = static_cast<QWidget *>(d->paintDevice);
- d->win = widget->winId();
- myDc = GetDC(d->win);
- }
-
- // NB! the QGLTemporaryContext object is needed for the
- // wglGetProcAddress() calls to succeed and are absolutely
- // necessary - don't remove!
- QGLTemporaryContext tmp_ctx(d->glFormat.directRendering(), widget);
-
- if (!myDc) {
- qWarning("QGLContext::chooseContext(): Paint device cannot be null");
- result = false;
- goto end;
- }
-
- if (d->glFormat.plane()) {
- d->pixelFormatId = ((QGLWidget*)d->paintDevice)->context()->d_func()->pixelFormatId;
- if (!d->pixelFormatId) { // I.e. the glwidget is invalid
- qWarning("QGLContext::chooseContext(): Cannot create overlay context for invalid widget");
- result = false;
- goto end;
- }
-
- if (!qgl_create_context(myDc, d, share)) {
- qwglError("QGLContext::chooseContext()", "CreateLayerContext");
- result = false;
- goto end;
- }
-
- LAYERPLANEDESCRIPTOR lpfd;
- wglDescribeLayerPlane(myDc, d->pixelFormatId, d->glFormat.plane(), sizeof(LAYERPLANEDESCRIPTOR), &lpfd);
- d->glFormat.setDoubleBuffer(lpfd.dwFlags & LPD_DOUBLEBUFFER);
- d->glFormat.setDepth(lpfd.cDepthBits);
- d->glFormat.setRgba(lpfd.iPixelType == PFD_TYPE_RGBA);
- if (d->glFormat.rgba()) {
- if (d->glFormat.redBufferSize() != -1)
- d->glFormat.setRedBufferSize(lpfd.cRedBits);
- if (d->glFormat.greenBufferSize() != -1)
- d->glFormat.setGreenBufferSize(lpfd.cGreenBits);
- if (d->glFormat.blueBufferSize() != -1)
- d->glFormat.setBlueBufferSize(lpfd.cBlueBits);
- }
- d->glFormat.setAlpha(lpfd.cAlphaBits);
- d->glFormat.setAccum(lpfd.cAccumBits);
- d->glFormat.setStencil(lpfd.cStencilBits);
- d->glFormat.setStereo(lpfd.dwFlags & LPD_STEREO);
- d->glFormat.setDirectRendering(false);
- if (d->glFormat.depth())
- d->glFormat.setDepthBufferSize(lpfd.cDepthBits);
- if (d->glFormat.alpha())
- d->glFormat.setAlphaBufferSize(lpfd.cAlphaBits);
- if (d->glFormat.accum())
- d->glFormat.setAccumBufferSize(lpfd.cAccumRedBits);
- if (d->glFormat.stencil())
- d->glFormat.setStencilBufferSize(lpfd.cStencilBits);
-
- if (d->glFormat.rgba()) {
- if (lpfd.dwFlags & LPD_TRANSPARENT)
- d->transpColor = QColor(lpfd.crTransparent & 0xff,
- (lpfd.crTransparent >> 8) & 0xff,
- (lpfd.crTransparent >> 16) & 0xff);
- else
- d->transpColor = QColor(0, 0, 0);
- }
- else {
- if (lpfd.dwFlags & LPD_TRANSPARENT)
- d->transpColor = QColor(qRgb(1, 2, 3));//, lpfd.crTransparent);
- else
- d->transpColor = QColor(qRgb(1, 2, 3));//, 0);
-
- d->cmap = new QGLCmap(1 << lpfd.cColorBits);
- d->cmap->setEntry(lpfd.crTransparent, qRgb(1, 2, 3));//, QGLCmap::Reserved);
- }
- } else {
- PIXELFORMATDESCRIPTOR pfd;
- PIXELFORMATDESCRIPTOR realPfd;
- d->pixelFormatId = choosePixelFormat(&pfd, myDc);
- if (d->pixelFormatId == 0) {
- qwglError("QGLContext::chooseContext()", "ChoosePixelFormat");
- result = false;
- goto end;
- }
-
- bool overlayRequested = d->glFormat.hasOverlay();
- DescribePixelFormat(myDc, d->pixelFormatId, sizeof(PIXELFORMATDESCRIPTOR), &realPfd);
-
- if (!deviceIsPixmap() && wglGetProcAddress("wglGetPixelFormatAttribivARB"))
- d->glFormat = pfiToQGLFormat(myDc, d->pixelFormatId);
- else
- d->glFormat = pfdToQGLFormat(&realPfd);
-
- d->glFormat.setOverlay(d->glFormat.hasOverlay() && overlayRequested);
-
- if (deviceIsPixmap() && !(realPfd.dwFlags & PFD_DRAW_TO_BITMAP)) {
- qWarning("QGLContext::chooseContext(): Failed to get pixmap rendering context.");
- result = false;
- goto end;
- }
-
- if (deviceIsPixmap() &&
- (((QPixmap*)d->paintDevice)->depth() != realPfd.cColorBits)) {
- qWarning("QGLContext::chooseContext(): Failed to get pixmap rendering context of suitable depth.");
- result = false;
- goto end;
- }
-
- if (!SetPixelFormat(myDc, d->pixelFormatId, &realPfd)) {
- qwglError("QGLContext::chooseContext()", "SetPixelFormat");
- result = false;
- goto end;
- }
-
- if (!qgl_create_context(myDc, d, share)) {
- qwglError("QGLContext::chooseContext()", "wglCreateContext");
- result = false;
- goto end;
- }
-
- if(!deviceIsPixmap()) {
- QRgb* pal = qgl_create_rgb_palette(&realPfd);
- if (pal) {
- QGLColormap cmap;
- cmap.setEntries(256, pal);
- ((QGLWidget*)d->paintDevice)->setColormap(cmap);
- delete[] pal;
- }
- }
- }
-
-end:
- // vblanking
- wglMakeCurrent(myDc, d->rc);
- if (d->rc)
- d->updateFormatVersion();
-
- typedef BOOL (APIENTRYP PFNWGLSWAPINTERVALEXT) (int interval);
- typedef int (APIENTRYP PFNWGLGETSWAPINTERVALEXT) (void);
- PFNWGLSWAPINTERVALEXT wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXT) wglGetProcAddress("wglSwapIntervalEXT");
- PFNWGLGETSWAPINTERVALEXT wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXT) wglGetProcAddress("wglGetSwapIntervalEXT");
- if (wglSwapIntervalEXT && wglGetSwapIntervalEXT) {
- if (d->reqFormat.swapInterval() != -1)
- wglSwapIntervalEXT(d->reqFormat.swapInterval());
- d->glFormat.setSwapInterval(wglGetSwapIntervalEXT());
- }
-
- if (d->win)
- ReleaseDC(d->win, myDc);
- return result;
-}
-
-
-
-static bool qLogEq(bool a, bool b)
-{
- return (((!a) && (!b)) || (a && b));
-}
-
-/*
- See qgl.cpp for qdoc comment.
- */
-int QGLContext::choosePixelFormat(void* dummyPfd, HDC pdc)
-{
- Q_D(QGLContext);
- // workaround for matrox driver:
- // make a cheap call to opengl to force loading of DLL
- if (!opengl32dll) {
- GLint params;
- glGetIntegerv(GL_DEPTH_BITS, &params);
- opengl32dll = true;
- }
-
- PFNWGLCHOOSEPIXELFORMATARB wglChoosePixelFormatARB =
- (PFNWGLCHOOSEPIXELFORMATARB) wglGetProcAddress("wglChoosePixelFormatARB");
- int chosenPfi = 0;
- if (!deviceIsPixmap() && wglChoosePixelFormatARB) {
- bool valid;
- int pixelFormat = 0;
- uint numFormats = 0;
- QVarLengthArray<int> iAttributes(40);
- int i = 0;
- iAttributes[i++] = WGL_ACCELERATION_ARB;
- if (d->glFormat.directRendering())
- iAttributes[i++] = WGL_FULL_ACCELERATION_ARB;
- else
- iAttributes[i++] = WGL_NO_ACCELERATION_ARB;
- iAttributes[i++] = WGL_SUPPORT_OPENGL_ARB;
- iAttributes[i++] = TRUE;
- iAttributes[i++] = WGL_DRAW_TO_WINDOW_ARB;
- iAttributes[i++] = TRUE;
- iAttributes[i++] = WGL_COLOR_BITS_ARB;
- iAttributes[i++] = 24;
- iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB;
- iAttributes[i++] = d->glFormat.doubleBuffer();
- if (d->glFormat.stereo()) {
- iAttributes[i++] = WGL_STEREO_ARB;
- iAttributes[i++] = TRUE;
- }
- if (d->glFormat.depth()) {
- iAttributes[i++] = WGL_DEPTH_BITS_ARB;
- iAttributes[i++] = d->glFormat.depthBufferSize() == -1 ? 24 : d->glFormat.depthBufferSize();
- }
- iAttributes[i++] = WGL_PIXEL_TYPE_ARB;
- if (d->glFormat.rgba()) {
- iAttributes[i++] = WGL_TYPE_RGBA_ARB;
- if (d->glFormat.redBufferSize() != -1) {
- iAttributes[i++] = WGL_RED_BITS_ARB;
- iAttributes[i++] = d->glFormat.redBufferSize();
- }
- if (d->glFormat.greenBufferSize() != -1) {
- iAttributes[i++] = WGL_GREEN_BITS_ARB;
- iAttributes[i++] = d->glFormat.greenBufferSize();
- }
- if (d->glFormat.blueBufferSize() != -1) {
- iAttributes[i++] = WGL_BLUE_BITS_ARB;
- iAttributes[i++] = d->glFormat.blueBufferSize();
- }
- } else {
- iAttributes[i++] = WGL_TYPE_COLORINDEX_ARB;
- }
- if (d->glFormat.alpha()) {
- iAttributes[i++] = WGL_ALPHA_BITS_ARB;
- iAttributes[i++] = d->glFormat.alphaBufferSize() == -1 ? 8 : d->glFormat.alphaBufferSize();
- }
- if (d->glFormat.accum()) {
- iAttributes[i++] = WGL_ACCUM_BITS_ARB;
- iAttributes[i++] = d->glFormat.accumBufferSize() == -1 ? 16 : d->glFormat.accumBufferSize();
- }
- if (d->glFormat.stencil()) {
- iAttributes[i++] = WGL_STENCIL_BITS_ARB;
- iAttributes[i++] = d->glFormat.stencilBufferSize() == -1 ? 8 : d->glFormat.stencilBufferSize();
- }
- if (d->glFormat.hasOverlay()) {
- iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB;
- iAttributes[i++] = 1;
- }
- int si = 0;
- bool trySampleBuffers = QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers;
- if (trySampleBuffers && d->glFormat.sampleBuffers()) {
- iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB;
- iAttributes[i++] = TRUE;
- iAttributes[i++] = WGL_SAMPLES_ARB;
- si = i;
- iAttributes[i++] = d->glFormat.samples() == -1 ? 4 : d->glFormat.samples();
- }
- iAttributes[i] = 0;
-
- do {
- valid = wglChoosePixelFormatARB(pdc, iAttributes.constData(), 0, 1,
- &pixelFormat, &numFormats);
- if (trySampleBuffers && (!valid || numFormats < 1) && d->glFormat.sampleBuffers())
- iAttributes[si] /= 2; // try different no. samples - we aim for the best one
- else
- break;
- } while ((!valid || numFormats < 1) && iAttributes[si] > 1);
- chosenPfi = pixelFormat;
- }
-
- if (!chosenPfi) { // fallback if wglChoosePixelFormatARB() failed
- int pmDepth = deviceIsPixmap() ? ((QPixmap*)d->paintDevice)->depth() : 0;
- PIXELFORMATDESCRIPTOR* p = (PIXELFORMATDESCRIPTOR*)dummyPfd;
- memset(p, 0, sizeof(PIXELFORMATDESCRIPTOR));
- p->nSize = sizeof(PIXELFORMATDESCRIPTOR);
- p->nVersion = 1;
- p->dwFlags = PFD_SUPPORT_OPENGL;
- if (deviceIsPixmap())
- p->dwFlags |= PFD_DRAW_TO_BITMAP;
- else
- p->dwFlags |= PFD_DRAW_TO_WINDOW;
- if (!d->glFormat.directRendering())
- p->dwFlags |= PFD_GENERIC_FORMAT;
- if (d->glFormat.doubleBuffer() && !deviceIsPixmap())
- p->dwFlags |= PFD_DOUBLEBUFFER;
- if (d->glFormat.stereo())
- p->dwFlags |= PFD_STEREO;
- if (d->glFormat.depth())
- p->cDepthBits = d->glFormat.depthBufferSize() == -1 ? 32 : d->glFormat.depthBufferSize();
- else
- p->dwFlags |= PFD_DEPTH_DONTCARE;
- if (d->glFormat.rgba()) {
- p->iPixelType = PFD_TYPE_RGBA;
- if (d->glFormat.redBufferSize() != -1)
- p->cRedBits = d->glFormat.redBufferSize();
- if (d->glFormat.greenBufferSize() != -1)
- p->cGreenBits = d->glFormat.greenBufferSize();
- if (d->glFormat.blueBufferSize() != -1)
- p->cBlueBits = d->glFormat.blueBufferSize();
- if (deviceIsPixmap())
- p->cColorBits = pmDepth;
- else
- p->cColorBits = 32;
- } else {
- p->iPixelType = PFD_TYPE_COLORINDEX;
- p->cColorBits = 8;
- }
- if (d->glFormat.alpha())
- p->cAlphaBits = d->glFormat.alphaBufferSize() == -1 ? 8 : d->glFormat.alphaBufferSize();
- if (d->glFormat.accum()) {
- p->cAccumRedBits = p->cAccumGreenBits = p->cAccumBlueBits = p->cAccumAlphaBits =
- d->glFormat.accumBufferSize() == -1 ? 16 : d->glFormat.accumBufferSize();
- }
- if (d->glFormat.stencil())
- p->cStencilBits = d->glFormat.stencilBufferSize() == -1 ? 8 : d->glFormat.stencilBufferSize();
- p->iLayerType = PFD_MAIN_PLANE;
- chosenPfi = ChoosePixelFormat(pdc, p);
-
- if (!chosenPfi)
- qErrnoWarning("QGLContext: ChoosePixelFormat failed");
-
- // Since the GDI function ChoosePixelFormat() does not handle
- // overlay and direct-rendering requests, we must roll our own here
-
- bool doSearch = chosenPfi <= 0;
- PIXELFORMATDESCRIPTOR pfd;
- QGLFormat fmt;
- if (!doSearch) {
- DescribePixelFormat(pdc, chosenPfi, sizeof(PIXELFORMATDESCRIPTOR),
- &pfd);
- fmt = pfdToQGLFormat(&pfd);
- if (d->glFormat.hasOverlay() && !fmt.hasOverlay())
- doSearch = true;
- else if (!qLogEq(d->glFormat.directRendering(), fmt.directRendering()))
- doSearch = true;
- else if (deviceIsPixmap() && (!(pfd.dwFlags & PFD_DRAW_TO_BITMAP) ||
- pfd.cColorBits != pmDepth))
- doSearch = true;
- else if (!deviceIsPixmap() && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))
- doSearch = true;
- else if (!qLogEq(d->glFormat.rgba(), fmt.rgba()))
- doSearch = true;
- }
-
- if (doSearch) {
- int pfiMax = DescribePixelFormat(pdc, 0, 0, NULL);
- int bestScore = -1;
- int bestPfi = -1;
- for (int pfi = 1; pfi <= pfiMax; pfi++) {
- DescribePixelFormat(pdc, pfi, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
- if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL))
- continue;
- if (deviceIsPixmap() && (!(pfd.dwFlags & PFD_DRAW_TO_BITMAP) ||
- pfd.cColorBits != pmDepth))
- continue;
- if (!deviceIsPixmap() && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW))
- continue;
-
- fmt = pfdToQGLFormat(&pfd);
- if (d->glFormat.hasOverlay() && !fmt.hasOverlay())
- continue;
-
- int score = pfd.cColorBits;
- if (qLogEq(d->glFormat.depth(), fmt.depth()))
- score += pfd.cDepthBits;
- if (qLogEq(d->glFormat.alpha(), fmt.alpha()))
- score += pfd.cAlphaBits;
- if (qLogEq(d->glFormat.accum(), fmt.accum()))
- score += pfd.cAccumBits;
- if (qLogEq(d->glFormat.stencil(), fmt.stencil()))
- score += pfd.cStencilBits;
- if (qLogEq(d->glFormat.doubleBuffer(), fmt.doubleBuffer()))
- score += 1000;
- if (qLogEq(d->glFormat.stereo(), fmt.stereo()))
- score += 2000;
- if (qLogEq(d->glFormat.directRendering(), fmt.directRendering()))
- score += 4000;
- if (qLogEq(d->glFormat.rgba(), fmt.rgba()))
- score += 8000;
- if (score > bestScore) {
- bestScore = score;
- bestPfi = pfi;
- }
- }
-
- if (bestPfi > 0)
- chosenPfi = bestPfi;
- }
- }
- return chosenPfi;
-}
-
-
-
-void QGLContext::reset()
-{
- Q_D(QGLContext);
- // workaround for matrox driver:
- // make a cheap call to opengl to force loading of DLL
- if (!opengl32dll) {
- GLint params;
- glGetIntegerv(GL_DEPTH_BITS, &params);
- opengl32dll = true;
- }
-
- if (!d->valid)
- return;
- d->cleanup();
- doneCurrent();
- if (d->rc)
- wglDeleteContext(d->rc);
- d->rc = 0;
- if (d->win && d->dc)
- ReleaseDC(d->win, d->dc);
- if (deviceIsPixmap()) {
- DeleteDC(d->hbitmap_hdc);
- DeleteObject(d->hbitmap);
- d->hbitmap_hdc = 0;
- d->hbitmap = 0;
- }
- d->dc = 0;
- d->win = 0;
- d->threadId = 0;
- d->pixelFormatId = 0;
- d->sharing = false;
- d->valid = false;
- d->transpColor = QColor();
- delete d->cmap;
- d->cmap = 0;
- d->initDone = false;
- QGLContextGroup::removeShare(this);
-}
-
-//
-// NOTE: In a multi-threaded environment, each thread has a current
-// context. If we want to make this code thread-safe, we probably
-// have to use TLS (thread local storage) for keeping current contexts.
-//
-
-void QGLContext::makeCurrent()
-{
- Q_D(QGLContext);
- if (d->rc == wglGetCurrentContext() || !d->valid) // already current
- return;
-
- if (d->win && (!d->dc || d->threadId != QThread::currentThreadId())) {
- d->dc = GetDC(d->win);
- d->threadId = QThread::currentThreadId();
- if (!d->dc) {
- qwglError("QGLContext::makeCurrent()", "GetDC()");
- return;
- }
- } else if (deviceIsPixmap()) {
- d->dc = d->hbitmap_hdc;
- }
-
- HPALETTE hpal = QColormap::hPal();
- if (hpal) {
- SelectPalette(d->dc, hpal, FALSE);
- RealizePalette(d->dc);
- }
- if (d->glFormat.plane()) {
- wglRealizeLayerPalette(d->dc, d->glFormat.plane(), TRUE);
- }
-
- if (wglMakeCurrent(d->dc, d->rc)) {
- QGLContextPrivate::setCurrentContext(this);
- } else {
- qwglError("QGLContext::makeCurrent()", "wglMakeCurrent");
- }
-}
-
-
-void QGLContext::doneCurrent()
-{
- Q_D(QGLContext);
- wglMakeCurrent(0, 0);
- QGLContextPrivate::setCurrentContext(0);
- if (deviceIsPixmap() && d->hbitmap) {
- QPixmap *pm = static_cast<QPixmap *>(d->paintDevice);
- *pm = QPixmap::fromWinHBITMAP(d->hbitmap);
- }
- if (d->win && d->dc) {
- ReleaseDC(d->win, d->dc);
- d->dc = 0;
- d->threadId = 0;
- }
-}
-
-void QGLContext::swapBuffers() const
-{
- Q_D(const QGLContext);
- if (d->dc && d->glFormat.doubleBuffer() && !deviceIsPixmap()) {
- if (d->glFormat.plane())
- wglSwapLayerBuffers(d->dc, WGL_SWAP_OVERLAY1);
- else {
- if (d->glFormat.hasOverlay())
- wglSwapLayerBuffers(d->dc, WGL_SWAP_MAIN_PLANE);
- else
- SwapBuffers(d->dc);
- }
- }
-}
-
-
-QColor QGLContext::overlayTransparentColor() const
-{
- return d_func()->transpColor;
-}
-
-
-uint QGLContext::colorIndex(const QColor& c) const
-{
- Q_D(const QGLContext);
- if (!isValid())
- return 0;
- if (d->cmap) {
- int idx = d->cmap->find(c.rgb());
- if (idx >= 0)
- return idx;
- if (d->dc && d->glFormat.plane()) {
- idx = d->cmap->allocate(c.rgb());
- if (idx >= 0) {
- COLORREF r = RGB(qRed(c.rgb()),qGreen(c.rgb()),qBlue(c.rgb()));
- wglSetLayerPaletteEntries(d->dc, d->glFormat.plane(), idx, 1, &r);
- wglRealizeLayerPalette(d->dc, d->glFormat.plane(), TRUE);
- return idx;
- }
- }
- return d->cmap->findNearest(c.rgb());
- }
- QColormap cmap = QColormap::instance();
- return cmap.pixel(c) & 0x00ffffff; // Assumes standard palette
-}
-
-void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
-{
- if (!isValid())
- return;
-
- HDC display_dc = GetDC(0);
- HDC tmp_dc = CreateCompatibleDC(display_dc);
- HGDIOBJ old_font = SelectObject(tmp_dc, fnt.handle());
-
- ReleaseDC(0, display_dc);
-
- if (!wglUseFontBitmaps(tmp_dc, 0, 256, listBase))
- qWarning("QGLContext::generateFontDisplayLists: Could not generate display lists for font '%s'", fnt.family().toLatin1().data());
-
- SelectObject(tmp_dc, old_font);
- DeleteDC(tmp_dc);
-}
-
-void *QGLContext::getProcAddress(const QString &proc) const
-{
- return (void *)wglGetProcAddress(proc.toLatin1());
-}
-
-/*****************************************************************************
- QGLWidget Win32/WGL-specific code
- *****************************************************************************/
-
-void QGLWidgetPrivate::init(QGLContext *ctx, const QGLWidget* shareWidget)
-{
- Q_Q(QGLWidget);
- olcx = 0;
- initContext(ctx, shareWidget);
-
- if (q->isValid() && q->context()->format().hasOverlay()) {
- olcx = new QGLContext(QGLFormat::defaultOverlayFormat(), q);
- if (!olcx->create(shareWidget ? shareWidget->overlayContext() : 0)) {
- delete olcx;
- olcx = 0;
- glcx->d_func()->glFormat.setOverlay(false);
- }
- } else {
- olcx = 0;
- }
-}
-
-/*\internal
- Store color values in the given colormap.
-*/
-static void qStoreColors(HPALETTE cmap, const QGLColormap & cols)
-{
- QRgb color;
- PALETTEENTRY pe;
-
- for (int i = 0; i < cols.size(); i++) {
- color = cols.entryRgb(i);
- pe.peRed = qRed(color);
- pe.peGreen = qGreen(color);
- pe.peBlue = qBlue(color);
- pe.peFlags = 0;
-
- SetPaletteEntries(cmap, i, 1, &pe);
- }
-}
-
-void QGLWidgetPrivate::updateColormap()
-{
- Q_Q(QGLWidget);
- if (!cmap.handle())
- return;
- HDC hdc = GetDC(q->winId());
- SelectPalette(hdc, (HPALETTE) cmap.handle(), TRUE);
- qStoreColors((HPALETTE) cmap.handle(), cmap);
- RealizePalette(hdc);
- ReleaseDC(q->winId(), hdc);
-}
-
-void QGLWidget::setMouseTracking(bool enable)
-{
- QWidget::setMouseTracking(enable);
-}
-
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
- resizeGL(width(), height());
- if (d->olcx) {
- makeOverlayCurrent();
- resizeOverlayGL(width(), height());
- }
-}
-
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- return d_func()->olcx;
-}
-
-
-void QGLWidget::makeOverlayCurrent()
-{
- Q_D(QGLWidget);
- if (d->olcx) {
- d->olcx->makeCurrent();
- if (!d->olcx->initialized()) {
- initializeOverlayGL();
- d->olcx->setInitialized(true);
- }
- }
-}
-
-
-void QGLWidget::updateOverlayGL()
-{
- Q_D(QGLWidget);
- if (d->olcx) {
- makeOverlayCurrent();
- paintOverlayGL();
- if (d->olcx->format().doubleBuffer()) {
- if (d->autoSwap)
- d->olcx->swapBuffers();
- }
- else {
- glFlush();
- }
- }
-}
-
-
-void QGLWidget::setContext(QGLContext *context,
- const QGLContext* shareContext,
- bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
- if (!context->deviceIsPixmap() && context->device() != this) {
- qWarning("QGLWidget::setContext: Context must refer to this widget");
- return;
- }
-
- if (d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
-
- bool doShow = false;
- if (oldcx && oldcx->d_func()->win == winId() && !d->glcx->deviceIsPixmap()) {
- // We already have a context and must therefore create a new
- // window since Windows does not permit setting a new OpenGL
- // context for a window that already has one set.
- doShow = isVisible();
- QWidget *pW = static_cast<QWidget *>(parent());
- QPoint pos = geometry().topLeft();
- setParent(pW, windowFlags());
- move(pos);
- }
-
- if (!d->glcx->isValid()) {
- bool wasSharing = shareContext || (oldcx && oldcx->isSharing());
- d->glcx->create(shareContext ? shareContext : oldcx);
- // the above is a trick to keep disp lists etc when a
- // QGLWidget has been reparented, so remove the sharing
- // flag if we don't actually have a sharing context.
- if (!wasSharing)
- d->glcx->d_ptr->sharing = false;
- }
-
- if (deleteOldContext)
- delete oldcx;
-
- if (doShow)
- show();
-}
-
-
-bool QGLWidgetPrivate::renderCxPm(QPixmap*)
-{
- return false;
-}
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
- Q_Q(QGLWidget);
- if (cmap.handle()) {
- HDC hdc = GetDC(q->winId());
- SelectPalette(hdc, (HPALETTE) GetStockObject(DEFAULT_PALETTE), FALSE);
- DeleteObject((HPALETTE) cmap.handle());
- ReleaseDC(q->winId(), hdc);
- cmap.setHandle(0);
- }
- return;
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- return d_func()->cmap;
-}
-
-void QGLWidget::setColormap(const QGLColormap & c)
-{
- Q_D(QGLWidget);
- d->cmap = c;
-
- if (d->cmap.handle()) { // already have an allocated cmap
- d->updateColormap();
- } else {
- LOGPALETTE *lpal = (LOGPALETTE *) malloc(sizeof(LOGPALETTE)
- +c.size()*sizeof(PALETTEENTRY));
- lpal->palVersion = 0x300;
- lpal->palNumEntries = c.size();
- d->cmap.setHandle(CreatePalette(lpal));
- free(lpal);
- d->updateColormap();
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgl_wince.cpp b/src/opengl/qgl_wince.cpp
deleted file mode 100644
index d6d8f24bfa..0000000000
--- a/src/opengl/qgl_wince.cpp
+++ /dev/null
@@ -1,636 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <qgl.h>
-#include <qlist.h>
-#include <qmap.h>
-#include <qpixmap.h>
-#include <qevent.h>
-#include <private/qgl_p.h>
-#include <qcolormap.h>
-#include <qvarlengtharray.h>
-#include <qdebug.h>
-#include <qapplication.h>
-#include <qdesktopwidget>
-
-#include <windows.h>
-
-#include <private/qeglproperties_p.h>
-#include <private/qeglcontext_p.h>
-#include <private/qgl_egl_p.h>
-
-
-QT_BEGIN_NAMESPACE
-
-
-
-class QGLCmapPrivate
-{
-public:
- QGLCmapPrivate() : count(1) { }
- void ref() { ++count; }
- bool deref() { return !--count; }
- uint count;
-
- enum AllocState{ UnAllocated = 0, Allocated = 0x01, Reserved = 0x02 };
-
- int maxSize;
- QVector<uint> colorArray;
- QVector<quint8> allocArray;
- QVector<quint8> contextArray;
- QMap<uint,int> colorMap;
-};
-
-/*****************************************************************************
- QColorMap class - temporarily here, until it is ready for prime time
- *****************************************************************************/
-
-/****************************************************************************
-**
-** Definition of QColorMap class
-**
-****************************************************************************/
-
-#ifndef QGLCMAP_H
-#define QGLCMAP_H
-
-#include <qcolor.h>
-
-/*
- QGLTemporaryContext implementation
-*/
-
-class QGLTemporaryContextPrivate
-{
-public:
- QGLWidget *widget;
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
- : d(new QGLTemporaryContextPrivate)
-{
- d->widget = new QGLWidget;
- d->widget->makeCurrent();
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- delete d->widget;
-}
-
-/*****************************************************************************
- QGLFormat Win32/WGL-specific code
- *****************************************************************************/
-
-static bool opengl32dll = false;
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- return false; // ###
-}
-
-
-bool QGLContext::chooseContext(const QGLContext* shareContext)
-{
- Q_D(QGLContext);
-
- // Validate the device.
- if (!device())
- return false;
- int devType = device()->devType();
- if (devType != QInternal::Pixmap && devType != QInternal::Image && devType != QInternal::Widget) {
- qWarning("QGLContext::chooseContext(): Cannot create QGLContext's for paint device type %d", devType);
- return false;
- }
-
- // Get the display and initialize it.
- d->eglContext = new QEglContext();
- d->ownsEglContext = true;
- d->eglContext->setApi(QEgl::OpenGL);
-
- // Construct the configuration we need for this surface.
- QEglProperties configProps;
- qt_eglproperties_set_glformat(configProps, d->glFormat);
- configProps.setDeviceType(devType);
- configProps.setPaintDeviceFormat(device());
- configProps.setRenderableType(QEgl::OpenGL);
-
- // Search for a matching configuration, reducing the complexity
- // each time until we get something that matches.
- if (!d->eglContext->chooseConfig(configProps)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
-
- // Inform the higher layers about the actual format properties.
- qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config());
-
- // Create a new context for the configuration.
- if (!d->eglContext->createContext
- (shareContext ? shareContext->d_func()->eglContext : 0)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
- d->sharing = d->eglContext->isSharing();
- if (d->sharing && shareContext)
- const_cast<QGLContext *>(shareContext)->d_func()->sharing = true;
-
-#if defined(EGL_VERSION_1_1)
- if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget)
- eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval());
-#endif
-
- // Create the EGL surface to draw into.
- d->eglSurface = d->eglContext->createSurface(device());
- if (d->eglSurface == EGL_NO_SURFACE) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
-
- return true;
-
-}
-
-
-
-static bool qLogEq(bool a, bool b)
-{
- return (((!a) && (!b)) || (a && b));
-}
-
-int QGLContext::choosePixelFormat(void* , HDC )
-{
-
- return 0;
-}
-
-class QGLCmapPrivate;
-
-class /*Q_EXPORT*/ QGLCmap
-{
-public:
- enum Flags { Reserved = 0x01 };
-
- QGLCmap(int maxSize = 256);
- QGLCmap(const QGLCmap& map);
- ~QGLCmap();
-
- QGLCmap& operator=(const QGLCmap& map);
-
- // isEmpty and/or isNull ?
- int size() const;
- int maxSize() const;
-
- void resize(int newSize);
-
- int find(QRgb color) const;
- int findNearest(QRgb color) const;
- int allocate(QRgb color, uint flags = 0, quint8 context = 0);
-
- void setEntry(int idx, QRgb color, uint flags = 0, quint8 context = 0);
-
- const QRgb* colors() const;
-
-private:
- void detach();
- QGLCmapPrivate* d;
-};
-
-#endif
-
-
-QGLCmap::QGLCmap(int maxSize) // add a bool prealloc?
-{
- d = new QGLCmapPrivate;
- d->maxSize = maxSize;
-}
-
-QGLCmap::QGLCmap(const QGLCmap& map)
-{
- d = map.d;
- d->ref();
-}
-
-QGLCmap::~QGLCmap()
-{
- if (d && d->deref())
- delete d;
- d = 0;
-}
-
-QGLCmap& QGLCmap::operator=(const QGLCmap& map)
-{
- map.d->ref();
- if (d->deref())
- delete d;
- d = map.d;
- return *this;
-}
-
-int QGLCmap::size() const
-{
- return d->colorArray.size();
-}
-
-int QGLCmap::maxSize() const
-{
- return d->maxSize;
-}
-
-void QGLCmap::detach()
-{
- if (d->count != 1) {
- d->deref();
- QGLCmapPrivate* newd = new QGLCmapPrivate;
- newd->maxSize = d->maxSize;
- newd->colorArray = d->colorArray;
- newd->allocArray = d->allocArray;
- newd->contextArray = d->contextArray;
- newd->colorArray.detach();
- newd->allocArray.detach();
- newd->contextArray.detach();
- newd->colorMap = d->colorMap;
- d = newd;
- }
-}
-
-
-void QGLCmap::resize(int newSize)
-{
- if (newSize < 0 || newSize > d->maxSize) {
- qWarning("QGLCmap::resize(): size out of range");
- return;
- }
- int oldSize = size();
- detach();
- //if shrinking; remove the lost elems from colorMap
- d->colorArray.resize(newSize);
- d->allocArray.resize(newSize);
- d->contextArray.resize(newSize);
- if (newSize > oldSize) {
- memset(d->allocArray.data() + oldSize, 0, newSize - oldSize);
- memset(d->contextArray.data() + oldSize, 0, newSize - oldSize);
- }
-}
-
-
-int QGLCmap::find(QRgb color) const
-{
- QMap<uint,int>::ConstIterator it = d->colorMap.find(color);
- if (it != d->colorMap.end())
- return *it;
- return -1;
-}
-
-
-int QGLCmap::findNearest(QRgb color) const
-{
- int idx = find(color);
- if (idx >= 0)
- return idx;
- int mapSize = size();
- int mindist = 200000;
- int r = qRed(color);
- int g = qGreen(color);
- int b = qBlue(color);
- int rx, gx, bx, dist;
- for (int i=0; i < mapSize; i++) {
- if (!(d->allocArray[i] & QGLCmapPrivate::Allocated))
- continue;
- QRgb ci = d->colorArray[i];
- rx = r - qRed(ci);
- gx = g - qGreen(ci);
- bx = b - qBlue(ci);
- dist = rx*rx + gx*gx + bx*bx; // calculate distance
- if (dist < mindist) { // minimal?
- mindist = dist;
- idx = i;
- }
- }
- return idx;
-}
-
-
-// Does not always allocate; returns existing c idx if found
-
-int QGLCmap::allocate(QRgb color, uint flags, quint8 context)
-{
- int idx = find(color);
- if (idx >= 0)
- return idx;
-
- int mapSize = d->colorArray.size();
- int newIdx = d->allocArray.indexOf(QGLCmapPrivate::UnAllocated);
-
- if (newIdx < 0) { // Must allocate more room
- if (mapSize < d->maxSize) {
- newIdx = mapSize;
- mapSize++;
- resize(mapSize);
- }
- else {
- //# add a bool param that says what to do in case no more room -
- // fail (-1) or return nearest?
- return -1;
- }
- }
-
- d->colorArray[newIdx] = color;
- if (flags & QGLCmap::Reserved) {
- d->allocArray[newIdx] = QGLCmapPrivate::Reserved;
- }
- else {
- d->allocArray[newIdx] = QGLCmapPrivate::Allocated;
- d->colorMap.insert(color, newIdx);
- }
- d->contextArray[newIdx] = context;
- return newIdx;
-}
-
-
-void QGLCmap::setEntry(int idx, QRgb color, uint flags, quint8 context)
-{
- if (idx < 0 || idx >= d->maxSize) {
- qWarning("QGLCmap::set(): Index out of range");
- return;
- }
- detach();
- int mapSize = size();
- if (idx >= mapSize) {
- mapSize = idx + 1;
- resize(mapSize);
- }
- d->colorArray[idx] = color;
- if (flags & QGLCmap::Reserved) {
- d->allocArray[idx] = QGLCmapPrivate::Reserved;
- }
- else {
- d->allocArray[idx] = QGLCmapPrivate::Allocated;
- d->colorMap.insert(color, idx);
- }
- d->contextArray[idx] = context;
-}
-
-
-const QRgb* QGLCmap::colors() const
-{
- return d->colorArray.data();
-}
-
-
-/*****************************************************************************
- QGLWidget Win32/WGL-specific code
- *****************************************************************************/
-
-void QGLWidgetPrivate::init(QGLContext *ctx, const QGLWidget* shareWidget)
-{
- Q_Q(QGLWidget);
- olcx = 0;
- initContext(ctx, shareWidget);
-
- if (q->isValid() && q->context()->format().hasOverlay()) {
- olcx = new QGLContext(QGLFormat::defaultOverlayFormat(), q);
- if (!olcx->create(shareWidget ? shareWidget->overlayContext() : 0)) {
- delete olcx;
- olcx = 0;
- glcx->d_func()->glFormat.setOverlay(false);
- }
- } else {
- olcx = 0;
- }
-}
-
-/*\internal
- Store color values in the given colormap.
-*/
-static void qStoreColors(HPALETTE cmap, const QGLColormap & cols)
-{
- QRgb color;
- PALETTEENTRY pe;
-
- for (int i = 0; i < cols.size(); i++) {
- color = cols.entryRgb(i);
- pe.peRed = qRed(color);
- pe.peGreen = qGreen(color);
- pe.peBlue = qBlue(color);
- pe.peFlags = 0;
-
- SetPaletteEntries(cmap, i, 1, &pe);
- }
-}
-
-void QGLWidgetPrivate::updateColormap()
-{
- Q_Q(QGLWidget);
- if (!cmap.handle())
- return;
- HDC hdc = GetDC(q->winId());
- SelectPalette(hdc, (HPALETTE) cmap.handle(), TRUE);
- qStoreColors((HPALETTE) cmap.handle(), cmap);
- RealizePalette(hdc);
- ReleaseDC(q->winId(), hdc);
-}
-
-bool QGLWidget::event(QEvent *e)
-{
- Q_D(QGLWidget);
- if (e->type() == QEvent::ParentChange) {
- setContext(new QGLContext(d->glcx->requestedFormat(), this));
- // the overlay needs to be recreated as well
- delete d->olcx;
- if (isValid() && context()->format().hasOverlay()) {
- d->olcx = new QGLContext(QGLFormat::defaultOverlayFormat(), this);
- if (!d->olcx->create(isSharing() ? d->glcx : 0)) {
- delete d->olcx;
- d->olcx = 0;
- d->glcx->d_func()->glFormat.setOverlay(false);
- }
- } else {
- d->olcx = 0;
- }
- } else if (e->type() == QEvent::Show && !format().rgba()) {
- d->updateColormap();
- }
-
- return QWidget::event(e);
-}
-
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
- resizeGL(width(), height());
- if (d->olcx) {
- makeOverlayCurrent();
- resizeOverlayGL(width(), height());
- }
-}
-
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- return d_func()->olcx;
-}
-
-
-void QGLWidget::makeOverlayCurrent()
-{
- Q_D(QGLWidget);
- if (d->olcx) {
- d->olcx->makeCurrent();
- if (!d->olcx->initialized()) {
- initializeOverlayGL();
- d->olcx->setInitialized(true);
- }
- }
-}
-
-
-void QGLWidget::updateOverlayGL()
-{
- Q_D(QGLWidget);
- if (d->olcx) {
- makeOverlayCurrent();
- paintOverlayGL();
- if (d->olcx->format().doubleBuffer()) {
- if (d->autoSwap)
- d->olcx->swapBuffers();
- }
- else {
- glFlush();
- }
- }
-}
-
-void QGLWidget::setContext(QGLContext *context,
- const QGLContext* shareContext,
- bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
- if (!context->deviceIsPixmap() && context->device() != this) {
- qWarning("QGLWidget::setContext: Context must refer to this widget");
- return;
- }
-
- if (d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
-
- bool doShow = false;
- if (oldcx && oldcx->d_func()->win == winId() && !d->glcx->deviceIsPixmap()) {
- // We already have a context and must therefore create a new
- // window since Windows does not permit setting a new OpenGL
- // context for a window that already has one set.
- doShow = isVisible();
- QWidget *pW = static_cast<QWidget *>(parent());
- QPoint pos = geometry().topLeft();
- setParent(pW, windowFlags());
- move(pos);
- }
-
- if (!d->glcx->isValid()) {
- d->glcx->create(shareContext ? shareContext : oldcx);
- // the above is a trick to keep disp lists etc when a
- // QGLWidget has been reparented, so remove the sharing
- // flag if we don't actually have a sharing context.
- if (!shareContext)
- d->glcx->d_ptr->sharing = false;
- }
-
- if (deleteOldContext)
- delete oldcx;
-
- if (doShow)
- show();
-}
-
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
- Q_Q(QGLWidget);
- if (cmap.handle()) {
- HDC hdc = GetDC(q->winId());
- SelectPalette(hdc, (HPALETTE) GetStockObject(DEFAULT_PALETTE), FALSE);
- DeleteObject((HPALETTE) cmap.handle());
- ReleaseDC(q->winId(), hdc);
- cmap.setHandle(0);
- }
- return;
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- return d_func()->cmap;
-}
-
-void QGLWidget::setColormap(const QGLColormap & c)
-{
- Q_D(QGLWidget);
- d->cmap = c;
-
- if (d->cmap.handle()) { // already have an allocated cmap
- d->updateColormap();
- } else {
- LOGPALETTE *lpal = (LOGPALETTE *) malloc(sizeof(LOGPALETTE)
- +c.size()*sizeof(PALETTEENTRY));
- lpal->palVersion = 0x300;
- lpal->palNumEntries = c.size();
- d->cmap.setHandle(CreatePalette(lpal));
- free(lpal);
- d->updateColormap();
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp
deleted file mode 100644
index 22a222eb1b..0000000000
--- a/src/opengl/qgl_x11.cpp
+++ /dev/null
@@ -1,1904 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgl.h"
-#include "qgl_p.h"
-
-#include "qmap.h"
-#include "qapplication.h"
-#include "qcolormap.h"
-#include "qdesktopwidget.h"
-#include "qpixmap.h"
-#include "qhash.h"
-#include "qlibrary.h"
-#include "qdebug.h"
-#include <private/qfontengine_ft_p.h>
-#include <private/qt_x11_p.h>
-#include <private/qpixmap_x11_p.h>
-#include <private/qimagepixmapcleanuphooks_p.h>
-#include <private/qunicodetables_p.h>
-#ifdef Q_OS_HPUX
-// for GLXPBuffer
-#include <private/qglpixelbuffer_p.h>
-#endif
-
-// We always define GLX_EXT_texture_from_pixmap ourselves because
-// we can't trust system headers to do it properly
-#define GLX_EXT_texture_from_pixmap 1
-
-#define INT8 dummy_INT8
-#define INT32 dummy_INT32
-#include <GL/glx.h>
-#undef INT8
-#undef INT32
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xos.h>
-#ifdef Q_OS_VXWORS
-# ifdef open
-# undef open
-# endif
-# ifdef getpid
-# undef getpid
-# endif
-#endif // Q_OS_VXWORKS
-#include <X11/Xatom.h>
-
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
-#include <dlfcn.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-extern Drawable qt_x11Handle(const QPaintDevice *pd);
-extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
-
-#ifndef GLX_ARB_multisample
-#define GLX_SAMPLE_BUFFERS_ARB 100000
-#define GLX_SAMPLES_ARB 100001
-#endif
-
-#ifndef GLX_TEXTURE_2D_BIT_EXT
-#define GLX_TEXTURE_2D_BIT_EXT 0x00000002
-#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004
-#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
-#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1
-#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2
-#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3
-#define GLX_Y_INVERTED_EXT 0x20D4
-#define GLX_TEXTURE_FORMAT_EXT 0x20D5
-#define GLX_TEXTURE_TARGET_EXT 0x20D6
-#define GLX_MIPMAP_TEXTURE_EXT 0x20D7
-#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8
-#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9
-#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA
-#define GLX_TEXTURE_2D_EXT 0x20DC
-#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD
-#define GLX_FRONT_LEFT_EXT 0x20DE
-#endif
-
-#ifndef GLX_ARB_create_context
-#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
-#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
-#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
-#define GLX_CONTEXT_FLAGS_ARB 0x2094
-#endif
-
-#ifndef GLX_ARB_create_context_profile
-#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
-#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
-#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
-#endif
-
-/*
- The qt_gl_choose_cmap function is internal and used by QGLWidget::setContext()
- and GLX (not Windows). If the application can't find any sharable
- colormaps, it must at least create as few colormaps as possible. The
- dictionary solution below ensures only one colormap is created per visual.
- Colormaps are also deleted when the application terminates.
-*/
-
-struct QCMapEntry {
- QCMapEntry();
- ~QCMapEntry();
-
- Colormap cmap;
- bool alloc;
- XStandardColormap scmap;
-};
-
-QCMapEntry::QCMapEntry()
-{
- cmap = 0;
- alloc = false;
- scmap.colormap = 0;
-}
-
-QCMapEntry::~QCMapEntry()
-{
- if (alloc)
- XFreeColormap(X11->display, cmap);
-}
-typedef QHash<int, QCMapEntry *> CMapEntryHash;
-typedef QHash<int, QMap<int, QRgb> > GLCMapHash;
-static bool mesa_gl = false;
-static bool first_time = true;
-
-static void cleanup_cmaps();
-
-struct QGLCMapCleanupHandler {
- QGLCMapCleanupHandler() {
- cmap_hash = new CMapEntryHash;
- qglcmap_hash = new GLCMapHash;
- }
- ~QGLCMapCleanupHandler() {
- delete cmap_hash;
- delete qglcmap_hash;
- }
- CMapEntryHash *cmap_hash;
- GLCMapHash *qglcmap_hash;
-};
-Q_GLOBAL_STATIC(QGLCMapCleanupHandler, cmap_handler)
-
-static void cleanup_cmaps()
-{
- CMapEntryHash *hash = cmap_handler()->cmap_hash;
- QHash<int, QCMapEntry *>::ConstIterator it = hash->constBegin();
- while (it != hash->constEnd()) {
- delete it.value();
- ++it;
- }
-
- hash->clear();
- cmap_handler()->qglcmap_hash->clear();
-}
-
-Colormap qt_gl_choose_cmap(Display *dpy, XVisualInfo *vi)
-{
- if (first_time) {
- const char *v = glXQueryServerString(dpy, vi->screen, GLX_VERSION);
- if (v)
- mesa_gl = (strstr(v, "Mesa") != 0);
- first_time = false;
- }
-
- CMapEntryHash *hash = cmap_handler()->cmap_hash;
- CMapEntryHash::ConstIterator it = hash->constFind((long) vi->visualid + (vi->screen * 256));
- if (it != hash->constEnd())
- return it.value()->cmap; // found colormap for visual
-
- if (vi->visualid ==
- XVisualIDFromVisual((Visual *) QX11Info::appVisual(vi->screen))) {
- // qDebug("Using x11AppColormap");
- return QX11Info::appColormap(vi->screen);
- }
-
- QCMapEntry *x = new QCMapEntry();
-
- XStandardColormap *c;
- int n, i;
-
- // qDebug("Choosing cmap for vID %0x", vi->visualid);
-
- if (mesa_gl) { // we're using MesaGL
- Atom hp_cmaps = XInternAtom(dpy, "_HP_RGB_SMOOTH_MAP_LIST", true);
- if (hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8) {
- if (XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n,
- hp_cmaps)) {
- i = 0;
- while (i < n && x->cmap == 0) {
- if (c[i].visualid == vi->visual->visualid) {
- x->cmap = c[i].colormap;
- x->scmap = c[i];
- //qDebug("Using HP_RGB scmap");
-
- }
- i++;
- }
- XFree((char *)c);
- }
- }
- }
- if (!x->cmap) {
- if (XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n,
- XA_RGB_DEFAULT_MAP)) {
- for (int i = 0; i < n && x->cmap == 0; ++i) {
- if (!c[i].red_max ||
- !c[i].green_max ||
- !c[i].blue_max ||
- !c[i].red_mult ||
- !c[i].green_mult ||
- !c[i].blue_mult)
- continue; // invalid stdcmap
- if (c[i].visualid == vi->visualid) {
- x->cmap = c[i].colormap;
- x->scmap = c[i];
- //qDebug("Using RGB_DEFAULT scmap");
- }
- }
- XFree((char *)c);
- }
- }
- if (!x->cmap) { // no shared cmap found
- x->cmap = XCreateColormap(dpy, RootWindow(dpy,vi->screen), vi->visual,
- AllocNone);
- x->alloc = true;
- // qDebug("Allocating cmap");
- }
-
- // colormap hash should be cleanup only when the QApplication dtor is called
- if (hash->isEmpty())
- qAddPostRoutine(cleanup_cmaps);
-
- // associate cmap with visualid
- hash->insert((long) vi->visualid + (vi->screen * 256), x);
- return x->cmap;
-}
-
-struct QTransColor
-{
- VisualID vis;
- int screen;
- long color;
-};
-
-static QVector<QTransColor> trans_colors;
-static int trans_colors_init = false;
-
-static void find_trans_colors()
-{
- struct OverlayProp {
- long visual;
- long type;
- long value;
- long layer;
- };
-
- trans_colors_init = true;
-
- Display* appDisplay = X11->display;
-
- int scr;
- int lastsize = 0;
- for (scr = 0; scr < ScreenCount(appDisplay); scr++) {
- QWidget* rootWin = QApplication::desktop()->screen(scr);
- if (!rootWin)
- return; // Should not happen
- Atom overlayVisualsAtom = XInternAtom(appDisplay,
- "SERVER_OVERLAY_VISUALS", True);
- if (overlayVisualsAtom == XNone)
- return; // Server has no overlays
-
- Atom actualType;
- int actualFormat;
- ulong nItems;
- ulong bytesAfter;
- unsigned char *retval = 0;
- int res = XGetWindowProperty(appDisplay, rootWin->winId(),
- overlayVisualsAtom, 0, 10000, False,
- overlayVisualsAtom, &actualType,
- &actualFormat, &nItems, &bytesAfter,
- &retval);
-
- if (res != Success || actualType != overlayVisualsAtom
- || actualFormat != 32 || nItems < 4 || !retval)
- return; // Error reading property
-
- OverlayProp *overlayProps = (OverlayProp *)retval;
-
- int numProps = nItems / 4;
- trans_colors.resize(lastsize + numProps);
- int j = lastsize;
- for (int i = 0; i < numProps; i++) {
- if (overlayProps[i].type == 1) {
- trans_colors[j].vis = (VisualID)overlayProps[i].visual;
- trans_colors[j].screen = scr;
- trans_colors[j].color = (int)overlayProps[i].value;
- j++;
- }
- }
- XFree(overlayProps);
- lastsize = j;
- trans_colors.resize(lastsize);
- }
-}
-
-/*****************************************************************************
- QGLFormat UNIX/GLX-specific code
- *****************************************************************************/
-
-void (*qglx_getProcAddress(const char* procName))()
-{
- // On systems where the GL driver is pluggable (like Mesa), we have to use
- // the glXGetProcAddressARB extension to resolve other function pointers as
- // the symbols wont be in the GL library, but rather in a plugin loaded by
- // the GL library.
- typedef void (*(*qt_glXGetProcAddressARB)(const char *))();
- static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
- static bool triedResolvingGlxGetProcAddress = false;
- if (!triedResolvingGlxGetProcAddress) {
- triedResolvingGlxGetProcAddress = true;
- QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
- if (extensions.match("GLX_ARB_get_proc_address")) {
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
- void *handle = dlopen(NULL, RTLD_LAZY);
- if (handle) {
- glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
- dlclose(handle);
- }
- if (!glXGetProcAddressARB)
-#endif
- {
-#if !defined(QT_NO_LIBRARY)
- extern const QString qt_gl_library_name();
- QLibrary lib(qt_gl_library_name());
- glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB");
-#endif
- }
- }
- }
-
- void (*procAddress)() = 0;
- if (glXGetProcAddressARB)
- procAddress = glXGetProcAddressARB(procName);
-
- // If glXGetProcAddress didn't work, try looking the symbol up in the GL library
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
- if (!procAddress) {
- void *handle = dlopen(NULL, RTLD_LAZY);
- if (handle) {
- procAddress = (void (*)())dlsym(handle, procName);
- dlclose(handle);
- }
- }
-#endif
-#if !defined(QT_NO_LIBRARY)
- if (!procAddress) {
- extern const QString qt_gl_library_name();
- QLibrary lib(qt_gl_library_name());
- procAddress = lib.resolve(procName);
- }
-#endif
-
- return procAddress;
-}
-
-bool QGLFormat::hasOpenGL()
-{
- return glXQueryExtension(X11->display, 0, 0) != 0;
-}
-
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- if (!trans_colors_init)
- find_trans_colors();
- return trans_colors.size() > 0;
-}
-
-static bool buildSpec(int* spec, const QGLFormat& f, QPaintDevice* paintDevice,
- int bufDepth, bool onlyFBConfig = false)
-{
- int i = 0;
- spec[i++] = GLX_LEVEL;
- spec[i++] = f.plane();
- const QX11Info *xinfo = qt_x11Info(paintDevice);
- bool useFBConfig = onlyFBConfig;
-
-#if defined(GLX_VERSION_1_3) && !defined(QT_NO_XRENDER) && !defined(Q_OS_HPUX)
- /*
- HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions.
- Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented.
- */
- QWidget* widget = 0;
- if (paintDevice->devType() == QInternal::Widget)
- widget = static_cast<QWidget*>(paintDevice);
-
- // Only use glXChooseFBConfig for widgets if we're trying to get an ARGB visual
- if (widget && widget->testAttribute(Qt::WA_TranslucentBackground) && X11->use_xrender)
- useFBConfig = true;
-#endif
-
-#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
- static bool useTranspExt = false;
- static bool useTranspExtChecked = false;
- if (f.plane() && !useTranspExtChecked && paintDevice) {
- QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
- useTranspExt = extensions.match("GLX_EXT_visual_info");
- //# (A bit simplistic; that could theoretically be a substring)
- if (useTranspExt) {
- QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR));
- useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround
- if (useTranspExt) {
- // bug workaround - some systems (eg. FireGL) refuses to return an overlay
- // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specified, even if
- // the implementation supports transparent overlays
- int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT,
- f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT,
- XNone };
- XVisualInfo * vinf = glXChooseVisual(xinfo->display(), xinfo->screen(), tmpSpec);
- if (!vinf) {
- useTranspExt = false;
- }
- }
- }
-
- useTranspExtChecked = true;
- }
- if (f.plane() && useTranspExt && !useFBConfig) {
- // Required to avoid non-transparent overlay visual(!) on some systems
- spec[i++] = GLX_TRANSPARENT_TYPE_EXT;
- spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT;
- }
-#endif
-
-#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
- // GLX_RENDER_TYPE is only in glx >=1.3
- if (useFBConfig) {
- spec[i++] = GLX_RENDER_TYPE;
- spec[i++] = f.rgba() ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
- }
-#endif
-
- if (f.doubleBuffer())
- spec[i++] = GLX_DOUBLEBUFFER;
- if (useFBConfig)
- spec[i++] = True;
- if (f.depth()) {
- spec[i++] = GLX_DEPTH_SIZE;
- spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize();
- }
- if (f.stereo()) {
- spec[i++] = GLX_STEREO;
- if (useFBConfig)
- spec[i++] = True;
- }
- if (f.stencil()) {
- spec[i++] = GLX_STENCIL_SIZE;
- spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize();
- }
- if (f.rgba()) {
- if (!useFBConfig)
- spec[i++] = GLX_RGBA;
- spec[i++] = GLX_RED_SIZE;
- spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize();
- spec[i++] = GLX_GREEN_SIZE;
- spec[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize();
- spec[i++] = GLX_BLUE_SIZE;
- spec[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize();
- if (f.alpha()) {
- spec[i++] = GLX_ALPHA_SIZE;
- spec[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize();
- }
- if (f.accum()) {
- spec[i++] = GLX_ACCUM_RED_SIZE;
- spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- spec[i++] = GLX_ACCUM_GREEN_SIZE;
- spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- spec[i++] = GLX_ACCUM_BLUE_SIZE;
- spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- if (f.alpha()) {
- spec[i++] = GLX_ACCUM_ALPHA_SIZE;
- spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- }
- }
- } else {
- spec[i++] = GLX_BUFFER_SIZE;
- spec[i++] = bufDepth;
- }
-
- if (f.sampleBuffers()) {
- spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
- spec[i++] = 1;
- spec[i++] = GLX_SAMPLES_ARB;
- spec[i++] = f.samples() == -1 ? 4 : f.samples();
- }
-
-#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
- if (useFBConfig) {
- spec[i++] = GLX_DRAWABLE_TYPE;
- switch(paintDevice->devType()) {
- case QInternal::Pixmap:
- spec[i++] = GLX_PIXMAP_BIT;
- break;
- case QInternal::Pbuffer:
- spec[i++] = GLX_PBUFFER_BIT;
- break;
- default:
- qWarning("QGLContext: Unknown paint device type %d", paintDevice->devType());
- // Fall-through & assume it's a window
- case QInternal::Widget:
- spec[i++] = GLX_WINDOW_BIT;
- break;
- };
- }
-#endif
-
- spec[i] = XNone;
- return useFBConfig;
-}
-
-/*****************************************************************************
- QGLContext UNIX/GLX-specific code
- *****************************************************************************/
-
-bool QGLContext::chooseContext(const QGLContext* shareContext)
-{
- Q_D(QGLContext);
- const QX11Info *xinfo = qt_x11Info(d->paintDevice);
-
- Display* disp = xinfo->display();
- d->vi = chooseVisual();
- if (!d->vi)
- return false;
-
- if (deviceIsPixmap() &&
- (((XVisualInfo*)d->vi)->depth != xinfo->depth() ||
- ((XVisualInfo*)d->vi)->screen != xinfo->screen()))
- {
- XFree(d->vi);
- XVisualInfo appVisInfo;
- memset(&appVisInfo, 0, sizeof(XVisualInfo));
- appVisInfo.visualid = XVisualIDFromVisual((Visual *) xinfo->visual());
- appVisInfo.screen = xinfo->screen();
- int nvis;
- d->vi = XGetVisualInfo(disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis);
- if (!d->vi)
- return false;
-
- int useGL;
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_USE_GL, &useGL);
- if (!useGL)
- return false; //# Chickening out already...
- }
- int res;
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_LEVEL, &res);
- d->glFormat.setPlane(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DOUBLEBUFFER, &res);
- d->glFormat.setDoubleBuffer(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_DEPTH_SIZE, &res);
- d->glFormat.setDepth(res);
- if (d->glFormat.depth())
- d->glFormat.setDepthBufferSize(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RGBA, &res);
- d->glFormat.setRgba(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_RED_SIZE, &res);
- d->glFormat.setRedBufferSize(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_GREEN_SIZE, &res);
- d->glFormat.setGreenBufferSize(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BLUE_SIZE, &res);
- d->glFormat.setBlueBufferSize(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ALPHA_SIZE, &res);
- d->glFormat.setAlpha(res);
- if (d->glFormat.alpha())
- d->glFormat.setAlphaBufferSize(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_ACCUM_RED_SIZE, &res);
- d->glFormat.setAccum(res);
- if (d->glFormat.accum())
- d->glFormat.setAccumBufferSize(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STENCIL_SIZE, &res);
- d->glFormat.setStencil(res);
- if (d->glFormat.stencil())
- d->glFormat.setStencilBufferSize(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_STEREO, &res);
- d->glFormat.setStereo(res);
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLE_BUFFERS_ARB, &res);
- d->glFormat.setSampleBuffers(res);
- if (d->glFormat.sampleBuffers()) {
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_SAMPLES_ARB, &res);
- d->glFormat.setSamples(res);
- }
-
- Bool direct = format().directRendering() ? True : False;
-
- if (shareContext &&
- (!shareContext->isValid() || !shareContext->d_func()->cx)) {
- qWarning("QGLContext::chooseContext(): Cannot share with invalid context");
- shareContext = 0;
- }
-
- // 1. Sharing between rgba and color-index will give wrong colors.
- // 2. Contexts cannot be shared btw. direct/non-direct renderers.
- // 3. Pixmaps cannot share contexts that are set up for direct rendering.
- // 4. If the contexts are not created on the same screen, they can't be shared
-
- if (shareContext
- && (format().rgba() != shareContext->format().rgba()
- || (deviceIsPixmap() && glXIsDirect(disp, (GLXContext)shareContext->d_func()->cx))
- || (shareContext->d_func()->screen != xinfo->screen())))
- {
- shareContext = 0;
- }
-
- const int major = d->reqFormat.majorVersion();
- const int minor = d->reqFormat.minorVersion();
- const int profile = d->reqFormat.profile() == QGLFormat::CompatibilityProfile
- ? GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
- : GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
-
- d->cx = 0;
-
-#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
- /*
- HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions.
- Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented.
- */
- if ((major == 3 && minor >= 2) || major > 3) {
- QGLTemporaryContext *tmpContext = 0;
- if (!QGLContext::currentContext())
- tmpContext = new QGLTemporaryContext;
-
- int attributes[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, major,
- GLX_CONTEXT_MINOR_VERSION_ARB, minor,
- GLX_CONTEXT_PROFILE_MASK_ARB, profile,
- 0 };
-
- typedef GLXContext ( * Q_PFNGLXCREATECONTEXTATTRIBSARBPROC)
- (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
-
-
- Q_PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs =
- (Q_PFNGLXCREATECONTEXTATTRIBSARBPROC) qglx_getProcAddress("glXCreateContextAttribsARB");
-
- if (glXCreateContextAttribs) {
- int spec[45];
- glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BUFFER_SIZE, &res);
- buildSpec(spec, format(), d->paintDevice, res, true);
-
- GLXFBConfig *configs;
- int configCount = 0;
- configs = glXChooseFBConfig(disp, xinfo->screen(), spec, &configCount);
-
- if (configs && configCount > 0) {
- d->cx = glXCreateContextAttribs(disp, configs[0],
- shareContext ? (GLXContext)shareContext->d_func()->cx : 0, direct, attributes);
- if (!d->cx && shareContext) {
- shareContext = 0;
- d->cx = glXCreateContextAttribs(disp, configs[0], 0, direct, attributes);
- }
- d->screen = ((XVisualInfo*)d->vi)->screen;
- }
- XFree(configs);
- } else {
- qWarning("QGLContext::chooseContext(): OpenGL %d.%d is not supported", major, minor);
- }
-
- if (tmpContext)
- delete tmpContext;
- }
-#else
- Q_UNUSED(major);
- Q_UNUSED(minor);
- Q_UNUSED(profile);
-#endif
-
- if (!d->cx && shareContext) {
- d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi,
- (GLXContext)shareContext->d_func()->cx, direct);
- d->screen = ((XVisualInfo*)d->vi)->screen;
- }
- if (!d->cx) {
- d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, NULL, direct);
- d->screen = ((XVisualInfo*)d->vi)->screen;
- shareContext = 0;
- }
-
- if (shareContext && d->cx) {
- QGLContext *share = const_cast<QGLContext *>(shareContext);
- d->sharing = true;
- share->d_func()->sharing = true;
- }
-
- if (!d->cx)
- return false;
- d->glFormat.setDirectRendering(glXIsDirect(disp, (GLXContext)d->cx));
- if (deviceIsPixmap()) {
-#if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT)
- d->gpm = glXCreateGLXPixmapMESA(disp, (XVisualInfo *)d->vi,
- qt_x11Handle(d->paintDevice),
- qt_gl_choose_cmap(disp, (XVisualInfo *)d->vi));
-#else
- d->gpm = (quint32)glXCreateGLXPixmap(disp, (XVisualInfo *)d->vi,
- qt_x11Handle(d->paintDevice));
-#endif
- if (!d->gpm)
- return false;
- }
- QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
- if (extensions.match("GLX_SGI_video_sync")) {
- if (d->glFormat.swapInterval() == -1)
- d->glFormat.setSwapInterval(0);
- } else {
- d->glFormat.setSwapInterval(-1);
- }
- return true;
-}
-
-/*
- See qgl.cpp for qdoc comment.
- */
-void *QGLContext::chooseVisual()
-{
- Q_D(QGLContext);
- static const int bufDepths[] = { 8, 4, 2, 1 }; // Try 16, 12 also?
- //todo: if pixmap, also make sure that vi->depth == pixmap->depth
- void* vis = 0;
- int i = 0;
- bool fail = false;
- QGLFormat fmt = format();
- bool tryDouble = !fmt.doubleBuffer(); // Some GL impl's only have double
- bool triedDouble = false;
- bool triedSample = false;
- if (fmt.sampleBuffers())
- fmt.setSampleBuffers(QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers);
- while(!fail && !(vis = tryVisual(fmt, bufDepths[i]))) {
- if (!fmt.rgba() && bufDepths[i] > 1) {
- i++;
- continue;
- }
- if (tryDouble) {
- fmt.setDoubleBuffer(true);
- tryDouble = false;
- triedDouble = true;
- continue;
- } else if (triedDouble) {
- fmt.setDoubleBuffer(false);
- triedDouble = false;
- }
- if (!triedSample && fmt.sampleBuffers()) {
- fmt.setSampleBuffers(false);
- triedSample = true;
- continue;
- }
- if (fmt.stereo()) {
- fmt.setStereo(false);
- continue;
- }
- if (fmt.accum()) {
- fmt.setAccum(false);
- continue;
- }
- if (fmt.stencil()) {
- fmt.setStencil(false);
- continue;
- }
- if (fmt.alpha()) {
- fmt.setAlpha(false);
- continue;
- }
- if (fmt.depth()) {
- fmt.setDepth(false);
- continue;
- }
- if (fmt.doubleBuffer()) {
- fmt.setDoubleBuffer(false);
- continue;
- }
- fail = true;
- }
- d->glFormat = fmt;
- return vis;
-}
-
-/*
- See qgl.cpp for qdoc comment.
- */
-void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth)
-{
- Q_D(QGLContext);
- int spec[45];
- const QX11Info *xinfo = qt_x11Info(d->paintDevice);
- bool useFBConfig = buildSpec(spec, f, d->paintDevice, bufDepth, false);
-
- XVisualInfo* chosenVisualInfo = 0;
-
-#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
- while (useFBConfig) {
- GLXFBConfig *configs;
- int configCount = 0;
- configs = glXChooseFBConfig(xinfo->display(), xinfo->screen(), spec, &configCount);
-
- if (!configs)
- break; // fallback to trying glXChooseVisual
-
- for (int i = 0; i < configCount; ++i) {
- XVisualInfo* vi;
- vi = glXGetVisualFromFBConfig(xinfo->display(), configs[i]);
- if (!vi)
- continue;
-
-#if !defined(QT_NO_XRENDER)
- QWidget* w = 0;
- if (d->paintDevice->devType() == QInternal::Widget)
- w = static_cast<QWidget*>(d->paintDevice);
-
- if (w && w->testAttribute(Qt::WA_TranslucentBackground) && f.alpha()) {
- // Attempt to find a config who's visual has a proper alpha channel
- XRenderPictFormat *pictFormat;
- pictFormat = XRenderFindVisualFormat(xinfo->display(), vi->visual);
-
- if (pictFormat && (pictFormat->type == PictTypeDirect) && pictFormat->direct.alphaMask) {
- // The pict format for the visual matching the FBConfig indicates ARGB
- if (chosenVisualInfo)
- XFree(chosenVisualInfo);
- chosenVisualInfo = vi;
- break;
- }
- } else
-#endif //QT_NO_XRENDER
- if (chosenVisualInfo) {
- // If we've got a visual we can use and we're not trying to find one with a
- // real alpha channel, we might as well just use the one we've got
- break;
- }
-
- if (!chosenVisualInfo)
- chosenVisualInfo = vi; // Have something to fall back to
- else
- XFree(vi);
- }
-
- XFree(configs);
- break;
- }
-#endif // defined(GLX_VERSION_1_3)
-
- if (!chosenVisualInfo)
- chosenVisualInfo = glXChooseVisual(xinfo->display(), xinfo->screen(), spec);
-
- return chosenVisualInfo;
-}
-
-
-void QGLContext::reset()
-{
- Q_D(QGLContext);
- if (!d->valid)
- return;
- d->cleanup();
- const QX11Info *xinfo = qt_x11Info(d->paintDevice);
- doneCurrent();
- if (d->gpm)
- glXDestroyGLXPixmap(xinfo->display(), (GLXPixmap)d->gpm);
- d->gpm = 0;
- glXDestroyContext(xinfo->display(), (GLXContext)d->cx);
- if (d->vi)
- XFree(d->vi);
- d->vi = 0;
- d->cx = 0;
- d->crWin = false;
- d->sharing = false;
- d->valid = false;
- d->transpColor = QColor();
- d->initDone = false;
- QGLContextGroup::removeShare(this);
-}
-
-
-void QGLContext::makeCurrent()
-{
- Q_D(QGLContext);
- if (!d->valid) {
- qWarning("QGLContext::makeCurrent(): Cannot make invalid context current.");
- return;
- }
- const QX11Info *xinfo = qt_x11Info(d->paintDevice);
- bool ok = true;
- if (d->paintDevice->devType() == QInternal::Pixmap) {
- ok = glXMakeCurrent(xinfo->display(), (GLXPixmap)d->gpm, (GLXContext)d->cx);
- } else if (d->paintDevice->devType() == QInternal::Pbuffer) {
- ok = glXMakeCurrent(xinfo->display(), (GLXPbuffer)d->pbuf, (GLXContext)d->cx);
- } else if (d->paintDevice->devType() == QInternal::Widget) {
- ok = glXMakeCurrent(xinfo->display(), ((QWidget *)d->paintDevice)->internalWinId(), (GLXContext)d->cx);
- }
- if (!ok)
- qWarning("QGLContext::makeCurrent(): Failed.");
-
- if (ok)
- QGLContextPrivate::setCurrentContext(this);
-}
-
-void QGLContext::doneCurrent()
-{
- Q_D(QGLContext);
- glXMakeCurrent(qt_x11Info(d->paintDevice)->display(), 0, 0);
- QGLContextPrivate::setCurrentContext(0);
-}
-
-
-void QGLContext::swapBuffers() const
-{
- Q_D(const QGLContext);
- if (!d->valid)
- return;
- if (!deviceIsPixmap()) {
- int interval = d->glFormat.swapInterval();
- if (interval > 0) {
- typedef int (*qt_glXGetVideoSyncSGI)(uint *);
- typedef int (*qt_glXWaitVideoSyncSGI)(int, int, uint *);
- static qt_glXGetVideoSyncSGI glXGetVideoSyncSGI = 0;
- static qt_glXWaitVideoSyncSGI glXWaitVideoSyncSGI = 0;
- static bool resolved = false;
- if (!resolved) {
- const QX11Info *xinfo = qt_x11Info(d->paintDevice);
- QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));
- if (extensions.match("GLX_SGI_video_sync")) {
- glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI)qglx_getProcAddress("glXGetVideoSyncSGI");
- glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI)qglx_getProcAddress("glXWaitVideoSyncSGI");
- }
- resolved = true;
- }
- if (glXGetVideoSyncSGI && glXWaitVideoSyncSGI) {
- uint counter;
- if (!glXGetVideoSyncSGI(&counter))
- glXWaitVideoSyncSGI(interval + 1, (counter + interval) % (interval + 1), &counter);
- }
- }
- glXSwapBuffers(qt_x11Info(d->paintDevice)->display(),
- static_cast<QWidget *>(d->paintDevice)->winId());
- }
-}
-
-QColor QGLContext::overlayTransparentColor() const
-{
- if (isValid())
- return Qt::transparent;
- return QColor(); // Invalid color
-}
-
-static uint qt_transparent_pixel(VisualID id, int screen)
-{
- for (int i = 0; i < trans_colors.size(); i++) {
- if (trans_colors[i].vis == id && trans_colors[i].screen == screen)
- return trans_colors[i].color;
- }
- return 0;
-}
-
-uint QGLContext::colorIndex(const QColor& c) const
-{
- Q_D(const QGLContext);
- int screen = ((XVisualInfo *)d->vi)->screen;
- QColormap colmap = QColormap::instance(screen);
- if (isValid()) {
- if (format().plane() && c == Qt::transparent) {
- return qt_transparent_pixel(((XVisualInfo *)d->vi)->visualid,
- ((XVisualInfo *)d->vi)->screen);
- }
- if (((XVisualInfo*)d->vi)->visualid ==
- XVisualIDFromVisual((Visual *) QX11Info::appVisual(screen)))
- return colmap.pixel(c); // We're using QColor's cmap
-
- XVisualInfo *info = (XVisualInfo *) d->vi;
- CMapEntryHash *hash = cmap_handler()->cmap_hash;
- CMapEntryHash::ConstIterator it = hash->constFind(long(info->visualid)
- + (info->screen * 256));
- QCMapEntry *x = 0;
- if (it != hash->constEnd())
- x = it.value();
- if (x && !x->alloc) { // It's a standard colormap
- int rf = (int)(((float)c.red() * (x->scmap.red_max+1))/256.0);
- int gf = (int)(((float)c.green() * (x->scmap.green_max+1))/256.0);
- int bf = (int)(((float)c.blue() * (x->scmap.blue_max+1))/256.0);
- uint p = x->scmap.base_pixel
- + (rf * x->scmap.red_mult)
- + (gf * x->scmap.green_mult)
- + (bf * x->scmap.blue_mult);
- return p;
- } else {
- QMap<int, QRgb> &cmap = (*cmap_handler()->qglcmap_hash)[(long)info->visualid];
-
- // already in the map?
- QRgb target = c.rgb();
- QMap<int, QRgb>::Iterator it = cmap.begin();
- for (; it != cmap.end(); ++it) {
- if ((*it) == target)
- return it.key();
- }
-
- // need to alloc color
- unsigned long plane_mask[2];
- unsigned long color_map_entry;
- if (!XAllocColorCells (QX11Info::display(), x->cmap, true, plane_mask, 0,
- &color_map_entry, 1))
- return colmap.pixel(c);
-
- XColor col;
- col.flags = DoRed | DoGreen | DoBlue;
- col.pixel = color_map_entry;
- col.red = (ushort)((qRed(c.rgb()) / 255.0) * 65535.0 + 0.5);
- col.green = (ushort)((qGreen(c.rgb()) / 255.0) * 65535.0 + 0.5);
- col.blue = (ushort)((qBlue(c.rgb()) / 255.0) * 65535.0 + 0.5);
- XStoreColor(QX11Info::display(), x->cmap, &col);
-
- cmap.insert(color_map_entry, target);
- return color_map_entry;
- }
- }
- return 0;
-}
-
-#ifndef QT_NO_FONTCONFIG
-/*! \internal
- This is basically a substitute for glxUseXFont() which can only
- handle XLFD fonts. This version relies on freetype to render the
- glyphs, but it works with all fonts that fontconfig provides - both
- antialiased and aliased bitmap and outline fonts.
-*/
-static void qgl_use_font(QFontEngineFT *engine, int first, int count, int listBase)
-{
- GLfloat color[4];
- glGetFloatv(GL_CURRENT_COLOR, color);
-
- // save the pixel unpack state
- GLint gl_swapbytes, gl_lsbfirst, gl_rowlength, gl_skiprows, gl_skippixels, gl_alignment;
- glGetIntegerv (GL_UNPACK_SWAP_BYTES, &gl_swapbytes);
- glGetIntegerv (GL_UNPACK_LSB_FIRST, &gl_lsbfirst);
- glGetIntegerv (GL_UNPACK_ROW_LENGTH, &gl_rowlength);
- glGetIntegerv (GL_UNPACK_SKIP_ROWS, &gl_skiprows);
- glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &gl_skippixels);
- glGetIntegerv (GL_UNPACK_ALIGNMENT, &gl_alignment);
-
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
- glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- const bool antialiased = engine->drawAntialiased();
- FT_Face face = engine->lockFace();
-
- // start generating font glyphs
- for (int i = first; i < count; ++i) {
- int list = listBase + i;
- GLfloat x0, y0, dx, dy;
-
- FT_Error err;
-
- err = FT_Load_Glyph(face, FT_Get_Char_Index(face, i), FT_LOAD_DEFAULT);
- if (err) {
- qDebug("failed loading glyph %d from font", i);
- Q_ASSERT(!err);
- }
- err = FT_Render_Glyph(face->glyph, (antialiased ? FT_RENDER_MODE_NORMAL
- : FT_RENDER_MODE_MONO));
- if (err) {
- qDebug("failed rendering glyph %d from font", i);
- Q_ASSERT(!err);
- }
-
- FT_Bitmap bm = face->glyph->bitmap;
- x0 = face->glyph->metrics.horiBearingX >> 6;
- y0 = (face->glyph->metrics.height - face->glyph->metrics.horiBearingY) >> 6;
- dx = face->glyph->metrics.horiAdvance >> 6;
- dy = 0;
- int sz = bm.pitch * bm.rows;
- uint *aa_glyph = 0;
- uchar *ua_glyph = 0;
-
- if (antialiased)
- aa_glyph = new uint[sz];
- else
- ua_glyph = new uchar[sz];
-
- // convert to GL format
- for (int y = 0; y < bm.rows; ++y) {
- for (int x = 0; x < bm.pitch; ++x) {
- int c1 = y*bm.pitch + x;
- int c2 = (bm.rows - y - 1) > 0 ? (bm.rows-y-1)*bm.pitch + x : x;
- if (antialiased) {
- aa_glyph[c1] = (int(color[0]*255) << 24)
- | (int(color[1]*255) << 16)
- | (int(color[2]*255) << 8) | bm.buffer[c2];
- } else {
- ua_glyph[c1] = bm.buffer[c2];
- }
- }
- }
-
- glNewList(list, GL_COMPILE);
- if (antialiased) {
- // calling glBitmap() is just a trick to move the current
- // raster pos, since glGet*() won't work in display lists
- glBitmap(0, 0, 0, 0, x0, -y0, 0);
- glDrawPixels(bm.pitch, bm.rows, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, aa_glyph);
- glBitmap(0, 0, 0, 0, dx-x0, y0, 0);
- } else {
- glBitmap(bm.pitch*8, bm.rows, -x0, y0, dx, dy, ua_glyph);
- }
- glEndList();
- antialiased ? delete[] aa_glyph : delete[] ua_glyph;
- }
-
- engine->unlockFace();
-
- // restore pixel unpack settings
- glPixelStorei(GL_UNPACK_SWAP_BYTES, gl_swapbytes);
- glPixelStorei(GL_UNPACK_LSB_FIRST, gl_lsbfirst);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, gl_rowlength);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, gl_skiprows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, gl_skippixels);
- glPixelStorei(GL_UNPACK_ALIGNMENT, gl_alignment);
-}
-#endif
-
-#undef d
-void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
-{
- QFont f(fnt);
- QFontEngine *engine = f.d->engineForScript(QUnicodeTables::Common);
-
- if (engine->type() == QFontEngine::Multi)
- engine = static_cast<QFontEngineMulti *>(engine)->engine(0);
-#ifndef QT_NO_FONTCONFIG
- if(engine->type() == QFontEngine::Freetype) {
- qgl_use_font(static_cast<QFontEngineFT *>(engine), 0, 256, listBase);
- return;
- }
-#endif
- // glXUseXFont() only works with XLFD font structures and a few GL
- // drivers crash if 0 is passed as the font handle
- f.setStyleStrategy(QFont::OpenGLCompatible);
- if (f.handle() && engine->type() == QFontEngine::XLFD)
- glXUseXFont(static_cast<Font>(f.handle()), 0, 256, listBase);
-}
-
-void *QGLContext::getProcAddress(const QString &proc) const
-{
- typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *);
- static qt_glXGetProcAddressARB glXGetProcAddressARB = 0;
- static bool resolved = false;
-
- if (resolved && !glXGetProcAddressARB)
- return 0;
- if (!glXGetProcAddressARB) {
- QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
- if (extensions.match("GLX_ARB_get_proc_address")) {
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
- void *handle = dlopen(NULL, RTLD_LAZY);
- if (handle) {
- glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB");
- dlclose(handle);
- }
- if (!glXGetProcAddressARB)
-#endif
- {
-#if !defined(QT_NO_LIBRARY)
- extern const QString qt_gl_library_name();
- QLibrary lib(qt_gl_library_name());
- glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB");
-#endif
- }
- }
- resolved = true;
- }
- if (!glXGetProcAddressARB)
- return 0;
- return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(proc.toLatin1().data()));
-}
-
-/*
- QGLTemporaryContext implementation
-*/
-
-class QGLTemporaryContextPrivate {
-public:
- bool initialized;
- Window drawable;
- GLXContext context;
- GLXDrawable oldDrawable;
- GLXContext oldContext;
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
- : d(new QGLTemporaryContextPrivate)
-{
- d->initialized = false;
- d->oldDrawable = 0;
- d->oldContext = 0;
- int screen = 0;
-
- int attribs[] = {GLX_RGBA, XNone};
- XVisualInfo *vi = glXChooseVisual(X11->display, screen, attribs);
- if (!vi) {
- qWarning("QGLTempContext: No GL capable X visuals available.");
- return;
- }
-
- int useGL;
- glXGetConfig(X11->display, vi, GLX_USE_GL, &useGL);
- if (!useGL) {
- XFree(vi);
- return;
- }
-
- d->oldDrawable = glXGetCurrentDrawable();
- d->oldContext = glXGetCurrentContext();
-
- XSetWindowAttributes a;
- a.colormap = qt_gl_choose_cmap(X11->display, vi);
- d->drawable = XCreateWindow(X11->display, RootWindow(X11->display, screen),
- 0, 0, 1, 1, 0,
- vi->depth, InputOutput, vi->visual,
- CWColormap, &a);
- d->context = glXCreateContext(X11->display, vi, 0, True);
- if (d->context && glXMakeCurrent(X11->display, d->drawable, d->context)) {
- d->initialized = true;
- } else {
- qWarning("QGLTempContext: Unable to create GL context.");
- XDestroyWindow(X11->display, d->drawable);
- }
- XFree(vi);
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- if (d->initialized) {
- glXMakeCurrent(X11->display, 0, 0);
- glXDestroyContext(X11->display, d->context);
- XDestroyWindow(X11->display, d->drawable);
- }
- if (d->oldDrawable && d->oldContext)
- glXMakeCurrent(X11->display, d->oldDrawable, d->oldContext);
-}
-
-/*****************************************************************************
- QGLOverlayWidget (Internal overlay class for X11)
- *****************************************************************************/
-
-class QGLOverlayWidget : public QGLWidget
-{
- Q_OBJECT
-public:
- QGLOverlayWidget(const QGLFormat& format, QGLWidget* parent, const QGLWidget* shareWidget=0);
-
-protected:
- void initializeGL();
- void paintGL();
- void resizeGL(int w, int h);
- bool x11Event(XEvent *e) { return realWidget->x11Event(e); }
-
-private:
- QGLWidget* realWidget;
-
-private:
- Q_DISABLE_COPY(QGLOverlayWidget)
-};
-
-
-QGLOverlayWidget::QGLOverlayWidget(const QGLFormat& format, QGLWidget* parent,
- const QGLWidget* shareWidget)
- : QGLWidget(format, parent, shareWidget ? shareWidget->d_func()->olw : 0)
-{
- setAttribute(Qt::WA_X11OpenGLOverlay);
- realWidget = parent;
-}
-
-
-
-void QGLOverlayWidget::initializeGL()
-{
- QColor transparentColor = context()->overlayTransparentColor();
- if (transparentColor.isValid())
- qglClearColor(transparentColor);
- else
- qWarning("QGLOverlayWidget::initializeGL(): Could not get transparent color");
- realWidget->initializeOverlayGL();
-}
-
-
-void QGLOverlayWidget::resizeGL(int w, int h)
-{
- glViewport(0, 0, w, h);
- realWidget->resizeOverlayGL(w, h);
-}
-
-
-void QGLOverlayWidget::paintGL()
-{
- realWidget->paintOverlayGL();
-}
-
-#undef Bool
-QT_BEGIN_INCLUDE_NAMESPACE
-#include "qgl_x11.moc"
-QT_END_INCLUDE_NAMESPACE
-
-/*****************************************************************************
- QGLWidget UNIX/GLX-specific code
- *****************************************************************************/
-void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget)
-{
- Q_Q(QGLWidget);
- initContext(context, shareWidget);
- olw = 0;
-
- if (q->isValid() && context->format().hasOverlay()) {
- QString olwName = q->objectName();
- olwName += QLatin1String("-QGL_internal_overlay_widget");
- olw = new QGLOverlayWidget(QGLFormat::defaultOverlayFormat(), q, shareWidget);
- olw->setObjectName(olwName);
- if (olw->isValid()) {
- olw->setAutoBufferSwap(false);
- olw->setFocusProxy(q);
- }
- else {
- delete olw;
- olw = 0;
- glcx->d_func()->glFormat.setOverlay(false);
- }
- }
-}
-
-bool QGLWidgetPrivate::renderCxPm(QPixmap* pm)
-{
- Q_Q(QGLWidget);
- if (((XVisualInfo*)glcx->d_func()->vi)->depth != pm->depth())
- return false;
-
- GLXPixmap glPm;
-#if defined(GLX_MESA_pixmap_colormap) && defined(QGL_USE_MESA_EXT)
- glPm = glXCreateGLXPixmapMESA(X11->display,
- (XVisualInfo*)glcx->vi,
- (Pixmap)pm->handle(),
- qt_gl_choose_cmap(pm->X11->display,
- (XVisualInfo*)glcx->vi));
-#else
- glPm = (quint32)glXCreateGLXPixmap(X11->display,
- (XVisualInfo*)glcx->d_func()->vi,
- (Pixmap)pm->handle());
-#endif
-
- if (!glXMakeCurrent(X11->display, glPm, (GLXContext)glcx->d_func()->cx)) {
- glXDestroyGLXPixmap(X11->display, glPm);
- return false;
- }
-
- glDrawBuffer(GL_FRONT);
- if (!glcx->initialized())
- q->glInit();
- q->resizeGL(pm->width(), pm->height());
- q->paintGL();
- glFlush();
- q->makeCurrent();
- glXDestroyGLXPixmap(X11->display, glPm);
- q->resizeGL(q->width(), q->height());
- return true;
-}
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
- if (!cmap.handle()) {
- return;
- } else {
- XFreeColormap(X11->display, (Colormap) cmap.handle());
- cmap.setHandle(0);
- }
-}
-
-void QGLWidget::setMouseTracking(bool enable)
-{
- Q_D(QGLWidget);
- if (d->olw)
- d->olw->setMouseTracking(enable);
- QWidget::setMouseTracking(enable);
-}
-
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
- glXWaitX();
- resizeGL(width(), height());
- if (d->olw)
- d->olw->setGeometry(rect());
-}
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- Q_D(const QGLWidget);
- if (d->olw)
- return d->olw->context();
- else
- return 0;
-}
-
-
-void QGLWidget::makeOverlayCurrent()
-{
- Q_D(QGLWidget);
- if (d->olw)
- d->olw->makeCurrent();
-}
-
-
-void QGLWidget::updateOverlayGL()
-{
- Q_D(QGLWidget);
- if (d->olw)
- d->olw->updateGL();
-}
-
-/*!
- \internal
-
- Sets a new QGLContext, \a context, for this QGLWidget, using the
- shared context, \a shareContext. If \a deleteOldContext is true,
- the original context is deleted; otherwise it is overridden.
-*/
-void QGLWidget::setContext(QGLContext *context,
- const QGLContext* shareContext,
- bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
- if (!context->deviceIsPixmap() && context->device() != this) {
- qWarning("QGLWidget::setContext: Context must refer to this widget");
- return;
- }
-
- if (d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
-
- if (parentWidget()) {
- // force creation of delay-created widgets
- parentWidget()->winId();
- if (parentWidget()->x11Info().screen() != x11Info().screen())
- d_func()->xinfo = parentWidget()->d_func()->xinfo;
- }
-
- // If the application has set WA_TranslucentBackground and not explicitly set
- // the alpha buffer size to zero, modify the format so it have an alpha channel
- QGLFormat& fmt = d->glcx->d_func()->glFormat;
- if (testAttribute(Qt::WA_TranslucentBackground) && fmt.alphaBufferSize() == -1)
- fmt.setAlphaBufferSize(1);
-
- bool createFailed = false;
- if (!d->glcx->isValid()) {
- if (!d->glcx->create(shareContext ? shareContext : oldcx))
- createFailed = true;
- }
- if (createFailed) {
- if (deleteOldContext)
- delete oldcx;
- return;
- }
-
- if (d->glcx->windowCreated() || d->glcx->deviceIsPixmap()) {
- if (deleteOldContext)
- delete oldcx;
- return;
- }
-
- bool visible = isVisible();
- if (visible)
- hide();
-
- XVisualInfo *vi = (XVisualInfo*)d->glcx->d_func()->vi;
- XSetWindowAttributes a;
-
- QColormap colmap = QColormap::instance(vi->screen);
- a.colormap = qt_gl_choose_cmap(QX11Info::display(), vi); // find best colormap
- a.background_pixel = colmap.pixel(palette().color(backgroundRole()));
- a.border_pixel = colmap.pixel(Qt::black);
- Window p = RootWindow(X11->display, vi->screen);
- if (parentWidget())
- p = parentWidget()->winId();
-
- Window w = XCreateWindow(X11->display, p, x(), y(), width(), height(),
- 0, vi->depth, InputOutput, vi->visual,
- CWBackPixel|CWBorderPixel|CWColormap, &a);
- Window *cmw;
- Window *cmwret;
- int count;
- if (XGetWMColormapWindows(X11->display, window()->winId(),
- &cmwret, &count)) {
- cmw = new Window[count+1];
- memcpy((char *)cmw, (char *)cmwret, sizeof(Window)*count);
- XFree((char *)cmwret);
- int i;
- for (i=0; i<count; i++) {
- if (cmw[i] == winId()) { // replace old window
- cmw[i] = w;
- break;
- }
- }
- if (i >= count) // append new window
- cmw[count++] = w;
- } else {
- count = 1;
- cmw = new Window[count];
- cmw[0] = w;
- }
-
-#if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT)
- if (oldcx && oldcx->windowCreated())
- glXReleaseBuffersMESA(X11->display, winId());
-#endif
- if (deleteOldContext)
- delete oldcx;
- oldcx = 0;
-
- if (testAttribute(Qt::WA_WState_Created))
- create(w);
- else
- d->createWinId(w);
- XSetWMColormapWindows(X11->display, window()->winId(), cmw, count);
- delete [] cmw;
-
- // calling QWidget::create() will always result in a new paint
- // engine being created - get rid of it and replace it with our
- // own
-
- if (visible)
- show();
- XFlush(X11->display);
- d->glcx->setWindowCreated(true);
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- Q_D(const QGLWidget);
- return d->cmap;
-}
-
-/*\internal
- Store color values in the given colormap.
-*/
-static void qStoreColors(QWidget * tlw, Colormap cmap,
- const QGLColormap & cols)
-{
- Q_UNUSED(tlw);
- XColor c;
- QRgb color;
-
- for (int i = 0; i < cols.size(); i++) {
- color = cols.entryRgb(i);
- c.pixel = i;
- c.red = (ushort)((qRed(color) / 255.0) * 65535.0 + 0.5);
- c.green = (ushort)((qGreen(color) / 255.0) * 65535.0 + 0.5);
- c.blue = (ushort)((qBlue(color) / 255.0) * 65535.0 + 0.5);
- c.flags = DoRed | DoGreen | DoBlue;
- XStoreColor(X11->display, cmap, &c);
- }
-}
-
-/*\internal
- Check whether the given visual supports dynamic colormaps or not.
-*/
-static bool qCanAllocColors(QWidget * w)
-{
- bool validVisual = false;
- int numVisuals;
- long mask;
- XVisualInfo templ;
- XVisualInfo * visuals;
- VisualID id = XVisualIDFromVisual((Visual *) w->window()->x11Info().visual());
-
- mask = VisualScreenMask;
- templ.screen = w->x11Info().screen();
- visuals = XGetVisualInfo(X11->display, mask, &templ, &numVisuals);
-
- for (int i = 0; i < numVisuals; i++) {
- if (visuals[i].visualid == id) {
- switch (visuals[i].c_class) {
- case TrueColor:
- case StaticColor:
- case StaticGray:
- case XGrayScale:
- validVisual = false;
- break;
- case DirectColor:
- case PseudoColor:
- validVisual = true;
- break;
- }
- break;
- }
- }
- XFree(visuals);
-
- if (!validVisual)
- return false;
- return true;
-}
-
-
-void QGLWidget::setColormap(const QGLColormap & c)
-{
- Q_D(QGLWidget);
- QWidget * tlw = window(); // must return a valid widget
-
- d->cmap = c;
- if (!d->cmap.handle())
- return;
-
- if (!qCanAllocColors(this)) {
- qWarning("QGLWidget::setColormap: Cannot create a read/write "
- "colormap for this visual");
- return;
- }
-
- // If the child GL widget is not of the same visual class as the
- // toplevel widget we will get in trouble..
- Window wid = tlw->winId();
- Visual * vis = (Visual *) tlw->x11Info().visual();;
- VisualID cvId = XVisualIDFromVisual((Visual *) x11Info().visual());
- VisualID tvId = XVisualIDFromVisual((Visual *) tlw->x11Info().visual());
- if (cvId != tvId) {
- wid = winId();
- vis = (Visual *) x11Info().visual();
- }
-
- if (!d->cmap.handle()) // allocate a cmap if necessary
- d->cmap.setHandle(XCreateColormap(X11->display, wid, vis, AllocAll));
-
- qStoreColors(this, (Colormap) d->cmap.handle(), c);
- XSetWindowColormap(X11->display, wid, (Colormap) d->cmap.handle());
-
- // tell the wm that this window has a special colormap
- Window * cmw;
- Window * cmwret;
- int count;
- if (XGetWMColormapWindows(X11->display, tlw->winId(), &cmwret, &count))
- {
- cmw = new Window[count+1];
- memcpy((char *) cmw, (char *) cmwret, sizeof(Window) * count);
- XFree((char *) cmwret);
- int i;
- for (i = 0; i < count; i++) {
- if (cmw[i] == winId()) {
- break;
- }
- }
- if (i >= count) // append new window only if not in the list
- cmw[count++] = winId();
- } else {
- count = 1;
- cmw = new Window[count];
- cmw[0] = winId();
- }
- XSetWMColormapWindows(X11->display, tlw->winId(), cmw, count);
- delete [] cmw;
-}
-
-// Solaris defines glXBindTexImageEXT as part of the GL library
-#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
-typedef void (*qt_glXBindTexImageEXT)(Display*, GLXDrawable, int, const int*);
-typedef void (*qt_glXReleaseTexImageEXT)(Display*, GLXDrawable, int);
-static qt_glXBindTexImageEXT glXBindTexImageEXT = 0;
-static qt_glXReleaseTexImageEXT glXReleaseTexImageEXT = 0;
-
-static bool qt_resolveTextureFromPixmap(QPaintDevice *paintDevice)
-{
- static bool resolvedTextureFromPixmap = false;
-
- if (!resolvedTextureFromPixmap) {
- resolvedTextureFromPixmap = true;
-
- // Check to see if we have NPOT texture support
- if ( !(QGLExtensions::glExtensions() & QGLExtensions::NPOTTextures) &&
- !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0))
- {
- return false; // Can't use TFP without NPOT
- }
-
- const QX11Info *xinfo = qt_x11Info(paintDevice);
- Display *display = xinfo ? xinfo->display() : X11->display;
- int screen = xinfo ? xinfo->screen() : X11->defaultScreen;
-
- QGLExtensionMatcher serverExtensions(glXQueryExtensionsString(display, screen));
- QGLExtensionMatcher clientExtensions(glXGetClientString(display, GLX_EXTENSIONS));
- if (serverExtensions.match("GLX_EXT_texture_from_pixmap")
- && clientExtensions.match("GLX_EXT_texture_from_pixmap"))
- {
- glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT");
- glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT");
- }
- }
-
- return glXBindTexImageEXT && glXReleaseTexImageEXT;
-}
-#endif //defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
-
-
-QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key,
- QGLContext::BindOptions options)
-{
-#if !defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX)
- return 0;
-#else
-
- // Check we have GLX 1.3, as it is needed for glXCreatePixmap & glXDestroyPixmap
- int majorVersion = 0;
- int minorVersion = 0;
- glXQueryVersion(X11->display, &majorVersion, &minorVersion);
- if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 3))
- return 0;
-
- Q_Q(QGLContext);
-
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data());
- Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class);
-
- // We can't use TFP if the pixmap has a separate X11 mask
- if (pixmapData->x11_mask)
- return 0;
-
- if (!qt_resolveTextureFromPixmap(paintDevice))
- return 0;
-
- const QX11Info &x11Info = pixmapData->xinfo;
-
- // Store the configs (Can be static because configs aren't dependent on current context)
- static GLXFBConfig glxRGBPixmapConfig = 0;
- static bool RGBConfigInverted = false;
- static GLXFBConfig glxRGBAPixmapConfig = 0;
- static bool RGBAConfigInverted = false;
-
- bool hasAlpha = pixmapData->hasAlphaChannel();
-
- // Check to see if we need a config
- if ( (hasAlpha && !glxRGBAPixmapConfig) || (!hasAlpha && !glxRGBPixmapConfig) ) {
- GLXFBConfig *configList = 0;
- int configCount = 0;
-
- int configAttribs[] = {
- hasAlpha ? GLX_BIND_TO_TEXTURE_RGBA_EXT : GLX_BIND_TO_TEXTURE_RGB_EXT, True,
- GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
- GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
- // QGLContext::bindTexture() can't return an inverted texture, but QPainter::drawPixmap() can:
- GLX_Y_INVERTED_EXT, options & QGLContext::CanFlipNativePixmapBindOption ? GLX_DONT_CARE : False,
- XNone
- };
- configList = glXChooseFBConfig(x11Info.display(), x11Info.screen(), configAttribs, &configCount);
- if (!configList)
- return 0;
-
- int yInv;
- glXGetFBConfigAttrib(x11Info.display(), configList[0], GLX_Y_INVERTED_EXT, &yInv);
-
- if (hasAlpha) {
- glxRGBAPixmapConfig = configList[0];
- RGBAConfigInverted = yInv;
- }
- else {
- glxRGBPixmapConfig = configList[0];
- RGBConfigInverted = yInv;
- }
-
- XFree(configList);
- }
-
- // Check to see if the surface is still valid
- if (pixmapData->gl_surface &&
- hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
- {
- // Surface is invalid!
- destroyGlSurfaceForPixmap(pixmapData);
- }
-
- // Check to see if we need a surface
- if (!pixmapData->gl_surface) {
- GLXPixmap glxPixmap;
- int pixmapAttribs[] = {
- GLX_TEXTURE_FORMAT_EXT, hasAlpha ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT,
- GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
- GLX_MIPMAP_TEXTURE_EXT, False, // Maybe needs to be don't care
- XNone
- };
-
- // Wrap the X Pixmap into a GLXPixmap:
- glxPixmap = glXCreatePixmap(x11Info.display(),
- hasAlpha ? glxRGBAPixmapConfig : glxRGBPixmapConfig,
- pixmapData->handle(), pixmapAttribs);
-
- if (!glxPixmap)
- return 0;
-
- pixmapData->gl_surface = (void*)glxPixmap;
-
- // Make sure the cleanup hook gets called so we can delete the glx pixmap
- QImagePixmapCleanupHooks::enableCleanupHooks(pixmapData);
- }
-
- GLuint textureId;
- glGenTextures(1, &textureId);
- glBindTexture(GL_TEXTURE_2D, textureId);
- glXBindTexImageEXT(x11Info.display(), (GLXPixmap)pixmapData->gl_surface, GLX_FRONT_LEFT_EXT, 0);
-
- glBindTexture(GL_TEXTURE_2D, textureId);
- GLuint filtering = (options & QGLContext::LinearFilteringBindOption) ? GL_LINEAR : GL_NEAREST;
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
-
- if (!((hasAlpha && RGBAConfigInverted) || (!hasAlpha && RGBConfigInverted)))
- options &= ~QGLContext::InvertedYBindOption;
-
- QGLTexture *texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options);
- if (texture->options & QGLContext::InvertedYBindOption)
- pixmapData->flags |= QX11PixmapData::InvertedWhenBoundToTexture;
-
- // We assume the cost of bound pixmaps is zero
- QGLTextureCache::instance()->insert(q, key, texture, 0);
-
- return texture;
-#endif //!defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX)
-}
-
-
-void QGLContextPrivate::destroyGlSurfaceForPixmap(QPixmapData* pmd)
-{
-#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
- Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
- if (pixmapData->gl_surface) {
- glXDestroyPixmap(QX11Info::display(), (GLXPixmap)pixmapData->gl_surface);
- pixmapData->gl_surface = 0;
- }
-#endif
-}
-
-void QGLContextPrivate::unbindPixmapFromTexture(QPixmapData* pmd)
-{
-#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX)
- Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
- Q_ASSERT(QGLContext::currentContext());
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
- if (pixmapData->gl_surface)
- glXReleaseTexImageEXT(QX11Info::display(), (GLXPixmap)pixmapData->gl_surface, GLX_FRONT_LEFT_EXT);
-#endif
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp
deleted file mode 100644
index 4dd7fc2f5d..0000000000
--- a/src/opengl/qgl_x11egl.cpp
+++ /dev/null
@@ -1,562 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgl.h"
-#include <private/qt_x11_p.h>
-#include <private/qpixmap_x11_p.h>
-#include <private/qgl_p.h>
-#include <private/qpaintengine_opengl_p.h>
-#include "qgl_egl_p.h"
-#include "qcolormap.h"
-#include <QDebug>
-#include <QPixmap>
-
-
-QT_BEGIN_NAMESPACE
-
-
-/*
- QGLTemporaryContext implementation
-*/
-
-class QGLTemporaryContextPrivate
-{
-public:
- bool initialized;
- Window window;
- EGLContext context;
- EGLSurface surface;
- EGLDisplay display;
-};
-
-QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
- : d(new QGLTemporaryContextPrivate)
-{
- d->initialized = false;
- d->window = 0;
- d->context = 0;
- d->surface = 0;
- int screen = 0;
-
- d->display = QEgl::display();
-
- EGLConfig config;
- int numConfigs = 0;
- EGLint attribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
-#ifdef QT_OPENGL_ES_2
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-#endif
- EGL_NONE
- };
-
- eglChooseConfig(d->display, attribs, &config, 1, &numConfigs);
- if (!numConfigs) {
- qWarning("QGLTemporaryContext: No EGL configurations available.");
- return;
- }
-
- XVisualInfo visualInfo;
- XVisualInfo *vi;
- int numVisuals;
-
- visualInfo.visualid = QEgl::getCompatibleVisualId(config);
- vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals);
- if (!vi || numVisuals < 1) {
- qWarning("QGLTemporaryContext: Unable to get X11 visual info id.");
- return;
- }
-
- XSetWindowAttributes attr;
- unsigned long mask;
- attr.background_pixel = 0;
- attr.border_pixel = 0;
- attr.colormap = XCreateColormap(X11->display, DefaultRootWindow(X11->display), vi->visual, AllocNone);
- attr.event_mask = StructureNotifyMask | ExposureMask;
- mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
-
- d->window = XCreateWindow(X11->display, RootWindow(X11->display, screen),
- 0, 0, 1, 1, 0,
- vi->depth, InputOutput, vi->visual,
- mask, &attr);
-
- d->surface = eglCreateWindowSurface(d->display, config, (EGLNativeWindowType) d->window, NULL);
-
- if (d->surface == EGL_NO_SURFACE) {
- qWarning("QGLTemporaryContext: Error creating EGL surface.");
- XFree(vi);
- XDestroyWindow(X11->display, d->window);
- return;
- }
-
- EGLint contextAttribs[] = {
-#ifdef QT_OPENGL_ES_2
- EGL_CONTEXT_CLIENT_VERSION, 2,
-#endif
- EGL_NONE
- };
- d->context = eglCreateContext(d->display, config, 0, contextAttribs);
- if (d->context != EGL_NO_CONTEXT
- && eglMakeCurrent(d->display, d->surface, d->surface, d->context))
- {
- d->initialized = true;
- } else {
- qWarning("QGLTemporaryContext: Error creating EGL context.");
- eglDestroySurface(d->display, d->surface);
- XDestroyWindow(X11->display, d->window);
- }
- XFree(vi);
-}
-
-QGLTemporaryContext::~QGLTemporaryContext()
-{
- if (d->initialized) {
- eglMakeCurrent(d->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglDestroyContext(d->display, d->context);
- eglDestroySurface(d->display, d->surface);
- XDestroyWindow(X11->display, d->window);
- }
-}
-
-bool QGLFormat::hasOpenGLOverlays()
-{
- return false;
-}
-
-// Chooses the EGL config and creates the EGL context
-bool QGLContext::chooseContext(const QGLContext* shareContext)
-{
- Q_D(QGLContext);
-
- if (!device())
- return false;
-
- int devType = device()->devType();
-
- QX11PixmapData *x11PixmapData = 0;
- if (devType == QInternal::Pixmap) {
- QPixmapData *pmd = static_cast<QPixmap*>(device())->data_ptr().data();
- if (pmd->classId() == QPixmapData::X11Class)
- x11PixmapData = static_cast<QX11PixmapData*>(pmd);
- else {
- // TODO: Replace the pixmap's data with a new QX11PixmapData
- qWarning("WARNING: Creating a QGLContext on a QPixmap is only supported for X11 pixmap backend");
- return false;
- }
- } else if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) {
- qWarning("WARNING: Creating a QGLContext not supported on device type %d", devType);
- return false;
- }
-
- // Only create the eglContext if we don't already have one:
- if (d->eglContext == 0) {
- d->eglContext = new QEglContext();
- d->ownsEglContext = true;
- d->eglContext->setApi(QEgl::OpenGL);
-
- // If the device is a widget with WA_TranslucentBackground set, make sure the glFormat
- // has the alpha channel option set:
- if (devType == QInternal::Widget) {
- QWidget* widget = static_cast<QWidget*>(device());
- if (widget->testAttribute(Qt::WA_TranslucentBackground))
- d->glFormat.setAlpha(true);
- }
-
- // Construct the configuration we need for this surface.
- QEglProperties configProps;
- configProps.setDeviceType(devType);
- configProps.setRenderableType(QEgl::OpenGL);
- qt_eglproperties_set_glformat(configProps, d->glFormat);
-
- // Set buffer preserved for regular QWidgets, QGLWidgets are ok with either preserved or destroyed:
- if ((devType == QInternal::Widget) && qobject_cast<QGLWidget*>(static_cast<QWidget*>(device())) == 0)
- configProps.setValue(EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
-
- if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
-
- // Create a new context for the configuration.
- QEglContext* eglSharedContext = shareContext ? shareContext->d_func()->eglContext : 0;
- if (!d->eglContext->createContext(eglSharedContext)) {
- delete d->eglContext;
- d->eglContext = 0;
- return false;
- }
- d->sharing = d->eglContext->isSharing();
- if (d->sharing && shareContext)
- const_cast<QGLContext *>(shareContext)->d_func()->sharing = true;
- }
-
- // Inform the higher layers about the actual format properties
- qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config());
-
- // Do don't create the EGLSurface for everything.
- // QWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface
- // QGLWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface
- // QPixmap - yes, create the EGLSurface but store it in QX11PixmapData::gl_surface
- // QGLPixelBuffer - no, it creates the surface itself and stores it in QGLPixelBufferPrivate::pbuf
-
- if (devType == QInternal::Widget) {
- if (d->eglSurface != EGL_NO_SURFACE)
- eglDestroySurface(d->eglContext->display(), d->eglSurface);
- // extraWindowSurfaceCreationProps default to NULL unless were specifically set before
- d->eglSurface = QEgl::createSurface(device(), d->eglContext->config(), d->extraWindowSurfaceCreationProps);
- XFlush(X11->display);
- setWindowCreated(true);
- }
-
- if (x11PixmapData) {
- // TODO: Actually check to see if the existing surface can be re-used
- if (x11PixmapData->gl_surface)
- eglDestroySurface(d->eglContext->display(), (EGLSurface)x11PixmapData->gl_surface);
-
- x11PixmapData->gl_surface = (void*)QEgl::createSurface(device(), d->eglContext->config());
- }
-
- return true;
-}
-
-void *QGLContext::chooseVisual()
-{
- qFatal("QGLContext::chooseVisual - this method must not be called as Qt is built with EGL support");
- return 0;
-}
-
-void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth)
-{
- Q_UNUSED(f);
- Q_UNUSED(bufDepth);
- qFatal("QGLContext::tryVisual - this method must not be called as Qt is built with EGL support");
- return 0;
-}
-
-void QGLWidget::resizeEvent(QResizeEvent *)
-{
- Q_D(QGLWidget);
- if (!isValid())
- return;
- makeCurrent();
- if (!d->glcx->initialized())
- glInit();
- resizeGL(width(), height());
- //handle overlay
-}
-
-const QGLContext* QGLWidget::overlayContext() const
-{
- return 0;
-}
-
-void QGLWidget::makeOverlayCurrent()
-{
- //handle overlay
-}
-
-void QGLWidget::updateOverlayGL()
-{
- //handle overlay
-}
-
-void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext)
-{
- Q_D(QGLWidget);
- if (context == 0) {
- qWarning("QGLWidget::setContext: Cannot set null context");
- return;
- }
- if (!context->deviceIsPixmap() && context->device() != this) {
- qWarning("QGLWidget::setContext: Context must refer to this widget");
- return;
- }
-
- if (d->glcx)
- d->glcx->doneCurrent();
- QGLContext* oldcx = d->glcx;
- d->glcx = context;
-
- bool createFailed = false;
- if (!d->glcx->isValid()) {
- // Create the QGLContext here, which in turn chooses the EGL config
- // and creates the EGL context:
- if (!d->glcx->create(shareContext ? shareContext : oldcx))
- createFailed = true;
- }
- if (createFailed) {
- if (deleteOldContext)
- delete oldcx;
- return;
- }
-
-
- d->eglSurfaceWindowId = winId(); // Remember the window id we created the surface for
-}
-
-void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget)
-{
- Q_Q(QGLWidget);
-
- initContext(context, shareWidget);
-
- if (q->isValid() && glcx->format().hasOverlay()) {
- //no overlay
- qWarning("QtOpenGL ES doesn't currently support overlays");
- }
-}
-
-void QGLWidgetPrivate::cleanupColormaps()
-{
-}
-
-const QGLColormap & QGLWidget::colormap() const
-{
- return d_func()->cmap;
-}
-
-void QGLWidget::setColormap(const QGLColormap &)
-{
-}
-
-// Re-creates the EGL surface if the window ID has changed or if there isn't a surface
-void QGLWidgetPrivate::recreateEglSurface()
-{
- Q_Q(QGLWidget);
-
- Window currentId = q->winId();
-
- // If the window ID has changed since the surface was created, we need to delete the
- // old surface before re-creating a new one. Note: This should not be the case as the
- // surface should be deleted before the old window id.
- if (glcx->d_func()->eglSurface != EGL_NO_SURFACE && (currentId != eglSurfaceWindowId)) {
- qWarning("EGL surface for deleted window %lx was not destroyed", uint(eglSurfaceWindowId));
- glcx->d_func()->destroyEglSurfaceForDevice();
- }
-
- if (glcx->d_func()->eglSurface == EGL_NO_SURFACE) {
- glcx->d_func()->eglSurface = glcx->d_func()->eglContext->createSurface(q);
- eglSurfaceWindowId = currentId;
- }
-}
-
-
-QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key,
- QGLContext::BindOptions options)
-{
- Q_Q(QGLContext);
-
- // The EGL texture_from_pixmap has no facility to invert the y coordinate
- if (!(options & QGLContext::CanFlipNativePixmapBindOption))
- return 0;
-
-
- static bool checkedForTFP = false;
- static bool haveTFP = false;
- static bool checkedForEglImageTFP = false;
- static bool haveEglImageTFP = false;
-
-
- if (!checkedForEglImageTFP) {
- checkedForEglImageTFP = true;
-
- // We need to be able to create an EGLImage from a native pixmap, which was split
- // into a separate EGL extension, EGL_KHR_image_pixmap. It is possible to have
- // eglCreateImageKHR & eglDestroyImageKHR without support for pixmaps, so we must
- // check we have the EGLImage from pixmap functionality.
- if (QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) {
-
- // Being able to create an EGLImage from a native pixmap is also pretty useless
- // without the ability to bind that EGLImage as a texture, which is provided by
- // the GL_OES_EGL_image extension, which we try to resolve here:
- haveEglImageTFP = qt_resolve_eglimage_gl_extensions(q);
-
- if (haveEglImageTFP)
- qDebug("Found EGL_KHR_image_pixmap & GL_OES_EGL_image extensions (preferred method)!");
- }
- }
-
- if (!checkedForTFP) {
- // Check for texture_from_pixmap egl extension
- checkedForTFP = true;
- if (QEgl::hasExtension("EGL_NOKIA_texture_from_pixmap") ||
- QEgl::hasExtension("EGL_EXT_texture_from_pixmap"))
- {
- qDebug("Found texture_from_pixmap EGL extension!");
- haveTFP = true;
- }
- }
-
- if (!haveTFP && !haveEglImageTFP)
- return 0;
-
-
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data());
- Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class);
- bool hasAlpha = pixmapData->hasAlphaChannel();
- bool pixmapHasValidSurface = false;
- bool textureIsBound = false;
- GLuint textureId;
- glGenTextures(1, &textureId);
- glBindTexture(GL_TEXTURE_2D, textureId);
-
- if (haveTFP && pixmapData->gl_surface &&
- hasAlpha == (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
- {
- pixmapHasValidSurface = true;
- }
-
- // If we already have a valid EGL surface for the pixmap, we should use it
- if (pixmapHasValidSurface) {
- EGLBoolean success;
- success = eglBindTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER);
- if (success == EGL_FALSE) {
- qWarning() << "eglBindTexImage() failed:" << QEgl::errorString();
- eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface);
- pixmapData->gl_surface = (void*)EGL_NO_SURFACE;
- } else
- textureIsBound = true;
- }
-
- // If the pixmap doesn't already have a valid surface, try binding it via EGLImage
- // first, as going through EGLImage should be faster and better supported:
- if (!textureIsBound && haveEglImageTFP) {
- EGLImageKHR eglImage;
-
- EGLint attribs[] = {
- EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
- EGL_NONE
- };
- eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
- (EGLClientBuffer)QEgl::nativePixmap(pixmap), attribs);
-
- QGLContext* ctx = q;
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage);
-
- GLint err = glGetError();
- if (err == GL_NO_ERROR)
- textureIsBound = true;
-
- // Once the egl image is bound, the texture becomes a new sibling image and we can safely
- // destroy the EGLImage we created for the pixmap:
- if (eglImage != EGL_NO_IMAGE_KHR)
- QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
- }
-
- if (!textureIsBound && haveTFP) {
- // Check to see if the surface is still valid
- if (pixmapData->gl_surface &&
- hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
- {
- // Surface is invalid!
- destroyGlSurfaceForPixmap(pixmapData);
- }
-
- if (pixmapData->gl_surface == 0) {
- EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap,
- QEgl::OpenGL,
- hasAlpha ? QEgl::Translucent : QEgl::NoOptions);
-
- pixmapData->gl_surface = (void*)QEgl::createSurface(pixmap, config);
- if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE)
- return false;
- }
-
- EGLBoolean success;
- success = eglBindTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER);
- if (success == EGL_FALSE) {
- qWarning() << "eglBindTexImage() failed:" << QEgl::errorString();
- eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface);
- pixmapData->gl_surface = (void*)EGL_NO_SURFACE;
- haveTFP = false; // If TFP isn't working, disable it's use
- } else
- textureIsBound = true;
- }
-
- QGLTexture *texture = 0;
-
- if (textureIsBound) {
- texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options);
- pixmapData->flags |= QX11PixmapData::InvertedWhenBoundToTexture;
-
- // We assume the cost of bound pixmaps is zero
- QGLTextureCache::instance()->insert(q, key, texture, 0);
-
- glBindTexture(GL_TEXTURE_2D, textureId);
- } else
- glDeleteTextures(1, &textureId);
-
- return texture;
-}
-
-
-void QGLContextPrivate::destroyGlSurfaceForPixmap(QPixmapData* pmd)
-{
- Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
- if (pixmapData->gl_surface) {
- EGLBoolean success;
- success = eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface);
- if (success == EGL_FALSE) {
- qWarning() << "destroyGlSurfaceForPixmap() - Error deleting surface: "
- << QEgl::errorString();
- }
- pixmapData->gl_surface = 0;
- }
-}
-
-void QGLContextPrivate::unbindPixmapFromTexture(QPixmapData* pmd)
-{
- Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
- if (pixmapData->gl_surface) {
- EGLBoolean success;
- success = eglReleaseTexImage(QEgl::display(),
- (EGLSurface)pixmapData->gl_surface,
- EGL_BACK_BUFFER);
- if (success == EGL_FALSE) {
- qWarning() << "unbindPixmapFromTexture() - Unable to release bound texture: "
- << QEgl::errorString();
- }
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp
index a1ec3ef8e0..c1128a0ebd 100644
--- a/src/opengl/qglbuffer.cpp
+++ b/src/opengl/qglbuffer.cpp
@@ -141,7 +141,7 @@ public:
QAtomicInt ref;
QGLBuffer::Type type;
- QGLSharedResourceGuard guard;
+ QGLSharedResourceGuardBase *guard;
QGLBuffer::UsagePattern usagePattern;
QGLBuffer::UsagePattern actualUsagePattern;
};
@@ -184,7 +184,7 @@ QGLBuffer::QGLBuffer(const QGLBuffer &other)
d_ptr->ref.ref();
}
-#define ctx d->guard.context()
+#define ctx QGLContext::currentContext();
/*!
Destroys this buffer object, including the storage being
@@ -245,21 +245,19 @@ QGLBuffer::UsagePattern QGLBuffer::usagePattern() const
void QGLBuffer::setUsagePattern(QGLBuffer::UsagePattern value)
{
Q_D(QGLBuffer);
-#if defined(QT_OPENGL_ES_1)
- // OpenGL/ES 1.1 does not support GL_STREAM_DRAW, so use GL_STATIC_DRAW.
- // OpenGL/ES 2.0 does support GL_STREAM_DRAW.
- d->usagePattern = value;
- if (value == StreamDraw)
- d->actualUsagePattern = StaticDraw;
- else
- d->actualUsagePattern = value;
-#else
d->usagePattern = d->actualUsagePattern = value;
-#endif
}
#undef ctx
+namespace {
+ void freeBufferFunc(QGLContext *ctx, GLuint id)
+ {
+ Q_UNUSED(ctx);
+ glDeleteBuffers(1, &id);
+ }
+}
+
/*!
Creates the buffer object in the GL server. Returns true if
the object was created; false otherwise.
@@ -276,24 +274,26 @@ void QGLBuffer::setUsagePattern(QGLBuffer::UsagePattern value)
bool QGLBuffer::create()
{
Q_D(QGLBuffer);
- if (d->guard.id())
+ if (d->guard && d->guard->id())
return true;
- const QGLContext *ctx = QGLContext::currentContext();
+ QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
if (ctx) {
- if (!qt_resolve_buffer_extensions(const_cast<QGLContext *>(ctx)))
+ if (!qt_resolve_buffer_extensions(ctx))
return false;
GLuint bufferId = 0;
glGenBuffers(1, &bufferId);
if (bufferId) {
- d->guard.setContext(ctx);
- d->guard.setId(bufferId);
+ if (d->guard)
+ d->guard->free();
+
+ d->guard = createSharedResourceGuard(ctx, bufferId, freeBufferFunc);
return true;
}
}
return false;
}
-#define ctx d->guard.context()
+#define ctx QGLContext::currentContext()
/*!
Returns true if this buffer has been created; false otherwise.
@@ -303,7 +303,7 @@ bool QGLBuffer::create()
bool QGLBuffer::isCreated() const
{
Q_D(const QGLBuffer);
- return d->guard.id() != 0;
+ return d->guard && d->guard->id();
}
/*!
@@ -314,14 +314,10 @@ bool QGLBuffer::isCreated() const
void QGLBuffer::destroy()
{
Q_D(QGLBuffer);
- GLuint bufferId = d->guard.id();
- if (bufferId) {
- // Switch to the original creating context to destroy it.
- QGLShareContextScope scope(d->guard.context());
- glDeleteBuffers(1, &bufferId);
+ if (d->guard) {
+ d->guard->free();
+ d->guard = 0;
}
- d->guard.setId(0);
- d->guard.setContext(0);
}
/*!
@@ -338,7 +334,7 @@ bool QGLBuffer::read(int offset, void *data, int count)
{
#if !defined(QT_OPENGL_ES)
Q_D(QGLBuffer);
- if (!glGetBufferSubData || !d->guard.id())
+ if (!glGetBufferSubData || !d->guard->id())
return false;
while (glGetError() != GL_NO_ERROR) ; // Clear error state.
glGetBufferSubData(d->type, offset, count, data);
@@ -368,7 +364,7 @@ void QGLBuffer::write(int offset, const void *data, int count)
qWarning("QGLBuffer::allocate(): buffer not created");
#endif
Q_D(QGLBuffer);
- if (d->guard.id())
+ if (d->guard && d->guard->id())
glBufferSubData(d->type, offset, count, data);
}
@@ -388,7 +384,7 @@ void QGLBuffer::allocate(const void *data, int count)
qWarning("QGLBuffer::allocate(): buffer not created");
#endif
Q_D(QGLBuffer);
- if (d->guard.id())
+ if (d->guard && d->guard->id())
glBufferData(d->type, count, data, d->actualUsagePattern);
}
@@ -423,10 +419,9 @@ bool QGLBuffer::bind()
qWarning("QGLBuffer::bind(): buffer not created");
#endif
Q_D(const QGLBuffer);
- GLuint bufferId = d->guard.id();
+ GLuint bufferId = d->guard ? d->guard->id() : 0;
if (bufferId) {
- if (!QGLContext::areSharing(QGLContext::currentContext(),
- d->guard.context())) {
+ if (d->guard->group() != QOpenGLContextGroup::currentContextGroup()) {
#ifndef QT_NO_DEBUG
qWarning("QGLBuffer::bind: buffer is not valid in the current context");
#endif
@@ -455,7 +450,7 @@ void QGLBuffer::release()
qWarning("QGLBuffer::release(): buffer not created");
#endif
Q_D(const QGLBuffer);
- if (d->guard.id())
+ if (d->guard && d->guard->id())
glBindBuffer(d->type, 0);
}
@@ -481,7 +476,7 @@ void QGLBuffer::release(QGLBuffer::Type type)
glBindBuffer(GLenum(type), 0);
}
-#define ctx d->guard.context()
+#define ctx QGLContext::currentContext()
/*!
Returns the GL identifier associated with this buffer; zero if
@@ -492,7 +487,7 @@ void QGLBuffer::release(QGLBuffer::Type type)
GLuint QGLBuffer::bufferId() const
{
Q_D(const QGLBuffer);
- return d->guard.id();
+ return d->guard ? d->guard->id() : 0;
}
#ifndef GL_BUFFER_SIZE
@@ -511,7 +506,7 @@ GLuint QGLBuffer::bufferId() const
int QGLBuffer::size() const
{
Q_D(const QGLBuffer);
- if (!d->guard.id())
+ if (!d->guard || !d->guard->id())
return -1;
GLint value = -1;
glGetBufferParameteriv(d->type, GL_BUFFER_SIZE, &value);
@@ -539,7 +534,7 @@ void *QGLBuffer::map(QGLBuffer::Access access)
if (!isCreated())
qWarning("QGLBuffer::map(): buffer not created");
#endif
- if (!d->guard.id())
+ if (!d->guard || !d->guard->id())
return 0;
if (!glMapBufferARB)
return 0;
@@ -566,7 +561,7 @@ bool QGLBuffer::unmap()
if (!isCreated())
qWarning("QGLBuffer::unmap(): buffer not created");
#endif
- if (!d->guard.id())
+ if (!d->guard || !d->guard->id())
return false;
if (!glUnmapBufferARB)
return false;
diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp
index 98d2960e1b..0734f713c6 100644
--- a/src/opengl/qglextensions.cpp
+++ b/src/opengl/qglextensions.cpp
@@ -222,17 +222,6 @@ bool qt_resolve_buffer_extensions(QGLContext *ctx)
#endif
}
-#ifndef QT_NO_EGL
-bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx)
-{
- if (glEGLImageTargetTexture2DOES || glEGLImageTargetRenderbufferStorageOES)
- return true;
- glEGLImageTargetTexture2DOES = (_glEGLImageTargetTexture2DOES) ctx->getProcAddress(QLatin1String("glEGLImageTargetTexture2DOES"));
- glEGLImageTargetRenderbufferStorageOES = (_glEGLImageTargetRenderbufferStorageOES) ctx->getProcAddress(QLatin1String("glEGLImageTargetRenderbufferStorageOES"));
- return glEGLImageTargetTexture2DOES && glEGLImageTargetRenderbufferStorageOES;
-}
-#endif
-
bool qt_resolve_glsl_extensions(QGLContext *ctx)
{
diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h
index 98433c366d..991fbba8c7 100644
--- a/src/opengl/qglextensions_p.h
+++ b/src/opengl/qglextensions_p.h
@@ -68,11 +68,6 @@
# define APIENTRYP *
#endif
-#ifndef QT_NO_EGL
-// Needed for EGLImageKHR definition:
-#include <QtGui/private/qegl_p.h>
-#endif
-
#include <QtCore/qglobal.h>
#ifndef GL_ARB_vertex_buffer_object
@@ -214,15 +209,6 @@ typedef void (APIENTRY *_glFramebufferTextureFaceEXT)(GLenum target, GLenum atta
// ARB_texture_compression
typedef void (APIENTRY *_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei,
GLsizei, GLint, GLsizei, const GLvoid *);
-
-#ifndef QT_NO_EGL
-// OES_EGL_image
-// Note: We define these to take EGLImage whereas spec says they take a new GLeglImageOES
-// type, which the EGL image should be cast to.
-typedef void (APIENTRY *_glEGLImageTargetTexture2DOES) (GLenum, EGLImageKHR);
-typedef void (APIENTRY *_glEGLImageTargetRenderbufferStorageOES) (GLenum, EGLImageKHR);
-#endif
-
QT_BEGIN_NAMESPACE
struct QGLExtensionFuncs
@@ -340,12 +326,6 @@ struct QGLExtensionFuncs
// Texture compression
qt_glCompressedTexImage2DARB = 0;
#endif
-
-#ifndef QT_NO_EGL
- // OES_EGL_image
- qt_glEGLImageTargetTexture2DOES = 0;
- qt_glEGLImageTargetRenderbufferStorageOES = 0;
-#endif
}
@@ -466,12 +446,6 @@ struct QGLExtensionFuncs
// Texture compression
_glCompressedTexImage2DARB qt_glCompressedTexImage2DARB;
#endif
-
-#ifndef QT_NO_EGL
- // OES_EGL_image
- _glEGLImageTargetTexture2DOES qt_glEGLImageTargetTexture2DOES;
- _glEGLImageTargetRenderbufferStorageOES qt_glEGLImageTargetRenderbufferStorageOES;
-#endif
};
@@ -880,26 +854,16 @@ struct QGLExtensionFuncs
#define glCompressedTexImage2D QGLContextPrivate::extensionFuncs(ctx).qt_glCompressedTexImage2DARB
#endif
-#ifndef QT_NO_EGL
-// OES_EGL_image
-#define glEGLImageTargetTexture2DOES QGLContextPrivate::extensionFuncs(ctx).qt_glEGLImageTargetTexture2DOES
-#define glEGLImageTargetRenderbufferStorageOES QGLContextPrivate::extensionFuncs(ctx).qt_glEGLImageTargetRenderbufferStorageOES
-#endif
-
extern bool qt_resolve_framebufferobject_extensions(QGLContext *ctx);
-bool Q_OPENGL_EXPORT qt_resolve_buffer_extensions(QGLContext *ctx);
+bool qt_resolve_buffer_extensions(QGLContext *ctx);
bool qt_resolve_version_1_3_functions(QGLContext *ctx);
-bool Q_OPENGL_EXPORT qt_resolve_version_2_0_functions(QGLContext *ctx);
+bool qt_resolve_version_2_0_functions(QGLContext *ctx);
bool qt_resolve_stencil_face_extension(QGLContext *ctx);
bool qt_resolve_frag_program_extensions(QGLContext *ctx);
bool qt_resolve_glsl_extensions(QGLContext *ctx);
-#ifndef QT_NO_EGL
-Q_OPENGL_EXPORT bool qt_resolve_eglimage_gl_extensions(QGLContext *ctx);
-#endif
-
QT_END_NAMESPACE
#endif // QGL_EXTENSIONS_P_H
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 682c26255d..5e140ab9da 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -45,24 +45,17 @@
#include <qdebug.h>
#include <private/qgl_p.h>
#include <private/qfont_p.h>
-#if !defined(QT_OPENGL_ES_1)
-#include <private/qpaintengineex_opengl2_p.h>
-#endif
-
-#ifndef QT_OPENGL_ES_2
-#include <private/qpaintengine_opengl_p.h>
-#endif
+#include "gl2paintengineex/qpaintengineex_opengl2_p.h"
-#include <qglframebufferobject.h>
#include <qlibrary.h>
#include <qimage.h>
QT_BEGIN_NAMESPACE
-extern Q_OPENGL_EXPORT QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
+extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
-#define QGL_FUNC_CONTEXT const QGLContext *ctx = d_ptr->fbo_guard.context();
-#define QGL_FUNCP_CONTEXT const QGLContext *ctx = fbo_guard.context();
+#define QGL_FUNC_CONTEXT const QGLContext *ctx = QGLContext::currentContext();
+#define QGL_FUNCP_CONTEXT const QGLContext *ctx = QGLContext::currentContext();
#ifndef QT_NO_DEBUG
#define QT_RESET_GLERROR() \
@@ -306,22 +299,6 @@ GLenum QGLFramebufferObjectFormat::internalTextureFormat() const
return d->internal_format;
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLFramebufferObjectFormat::setTextureTarget(QMacCompatGLenum target)
-{
- detach();
- d->target = target;
-}
-
-/*! \internal */
-void QGLFramebufferObjectFormat::setInternalTextureFormat(QMacCompatGLenum internalTextureFormat)
-{
- detach();
- d->internal_format = internalTextureFormat;
-}
-#endif
-
/*!
Returns true if all the options of this framebuffer object format
are the same as \a other; otherwise returns false.
@@ -373,13 +350,7 @@ void QGLFBOGLPaintDevice::setFBO(QGLFramebufferObject* f,
QGLContext *QGLFBOGLPaintDevice::context() const
{
- QGLContext *fboContext = const_cast<QGLContext *>(fbo->d_ptr->fbo_guard.context());
- QGLContext *currentContext = const_cast<QGLContext *>(QGLContext::currentContext());
-
- if (QGLContextPrivate::contextGroup(fboContext) == QGLContextPrivate::contextGroup(currentContext))
- return currentContext;
- else
- return fboContext;
+ return const_cast<QGLContext *>(QGLContext::currentContext());
}
bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const
@@ -429,13 +400,33 @@ bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const
return false;
}
+namespace
+{
+ void freeFramebufferFunc(QGLContext *ctx, GLuint id)
+ {
+ Q_UNUSED(ctx);
+ glDeleteFramebuffers(1, &id);
+ }
+
+ void freeRenderbufferFunc(QGLContext *ctx, GLuint id)
+ {
+ Q_UNUSED(ctx);
+ glDeleteRenderbuffers(1, &id);
+ }
+
+ void freeTextureFunc(QGLContext *ctx, GLuint id)
+ {
+ Q_UNUSED(ctx);
+ glDeleteTextures(1, &id);
+ }
+}
+
void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
QGLFramebufferObject::Attachment attachment,
GLenum texture_target, GLenum internal_format,
GLint samples, bool mipmap)
{
QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
- fbo_guard.setContext(ctx);
bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject);
if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
@@ -449,9 +440,11 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
GLuint fbo = 0;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
- fbo_guard.setId(fbo);
- glDevice.setFBO(q, attachment);
+ GLuint texture = 0;
+ GLuint color_buffer = 0;
+ GLuint depth_buffer = 0;
+ GLuint stencil_buffer = 0;
QT_CHECK_GLERROR();
// init texture
@@ -625,7 +618,21 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
}
glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
- if (!valid) {
+ if (valid) {
+ fbo_guard = createSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
+ if (color_buffer)
+ color_buffer_guard = createSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
+ else
+ texture_guard = createSharedResourceGuard(ctx, texture, freeTextureFunc);
+ if (depth_buffer)
+ depth_buffer_guard = createSharedResourceGuard(ctx, depth_buffer, freeRenderbufferFunc);
+ if (stencil_buffer) {
+ if (stencil_buffer == depth_buffer)
+ stencil_buffer_guard = depth_buffer_guard;
+ else
+ stencil_buffer_guard = createSharedResourceGuard(ctx, stencil_buffer, freeRenderbufferFunc);
+ }
+ } else {
if (color_buffer)
glDeleteRenderbuffers(1, &color_buffer);
else
@@ -635,7 +642,6 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
if (stencil_buffer && depth_buffer != stencil_buffer)
glDeleteRenderbuffers(1, &stencil_buffer);
glDeleteFramebuffers(1, &fbo);
- fbo_guard.setId(0);
}
QT_CHECK_GLERROR();
@@ -644,6 +650,8 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
format.setAttachment(fbo_attachment);
format.setInternalTextureFormat(internal_format);
format.setMipmap(mipmap);
+
+ glDevice.setFBO(q, attachment);
}
/*!
@@ -720,8 +728,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
As of Qt 4.8, it's possible to draw into a QGLFramebufferObject
using a QPainter in a separate thread. Note that OpenGL 2.0 or
- OpenGL ES 2.0 is required for this to work. Also, under X11, it's
- necessary to set the Qt::AA_X11InitThreads application attribute.
+ OpenGL ES 2.0 is required for this to work.
\sa {Framebuffer Object Example}
*/
@@ -780,16 +787,6 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target)
d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-QGLFramebufferObject::QGLFramebufferObject(const QSize &size, QMacCompatGLenum target)
- : d_ptr(new QGLFramebufferObjectPrivate)
-{
- Q_D(QGLFramebufferObject);
- d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
-}
-#endif
-
/*! \overload
Constructs an OpenGL framebuffer object and binds a 2D GL texture
@@ -832,16 +829,6 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, const QGLFrame
format.internalTextureFormat(), format.samples(), format.mipmap());
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-QGLFramebufferObject::QGLFramebufferObject(int width, int height, QMacCompatGLenum target)
- : d_ptr(new QGLFramebufferObjectPrivate)
-{
- Q_D(QGLFramebufferObject);
- d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
-}
-#endif
-
/*! \overload
Constructs an OpenGL framebuffer object and binds a texture to the
@@ -863,17 +850,6 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment att
d->init(this, QSize(width, height), attachment, target, internal_format);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment attachment,
- QMacCompatGLenum target, QMacCompatGLenum internal_format)
- : d_ptr(new QGLFramebufferObjectPrivate)
-{
- Q_D(QGLFramebufferObject);
- d->init(this, QSize(width, height), attachment, target, internal_format);
-}
-#endif
-
/*! \overload
Constructs an OpenGL framebuffer object and binds a texture to the
@@ -895,17 +871,6 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachm
d->init(this, size, attachment, target, internal_format);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachment,
- QMacCompatGLenum target, QMacCompatGLenum internal_format)
- : d_ptr(new QGLFramebufferObjectPrivate)
-{
- Q_D(QGLFramebufferObject);
- d->init(this, size, attachment, target, internal_format);
-}
-#endif
-
/*!
\fn QGLFramebufferObject::~QGLFramebufferObject()
@@ -914,23 +879,19 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachm
QGLFramebufferObject::~QGLFramebufferObject()
{
Q_D(QGLFramebufferObject);
- QGL_FUNC_CONTEXT;
delete d->engine;
- if (isValid() && ctx) {
- QGLShareContextScope scope(ctx);
- if (d->texture)
- glDeleteTextures(1, &d->texture);
- if (d->color_buffer)
- glDeleteRenderbuffers(1, &d->color_buffer);
- if (d->depth_buffer)
- glDeleteRenderbuffers(1, &d->depth_buffer);
- if (d->stencil_buffer && d->stencil_buffer != d->depth_buffer)
- glDeleteRenderbuffers(1, &d->stencil_buffer);
- GLuint fbo = d->fbo();
- glDeleteFramebuffers(1, &fbo);
- }
+ if (d->texture_guard)
+ d->texture_guard->free();
+ if (d->color_buffer_guard)
+ d->color_buffer_guard->free();
+ if (d->depth_buffer_guard)
+ d->depth_buffer_guard->free();
+ if (d->stencil_buffer_guard && d->stencil_buffer_guard != d->depth_buffer_guard)
+ d->stencil_buffer_guard->free();
+ if (d->fbo_guard)
+ d->fbo_guard->free();
}
/*!
@@ -954,7 +915,7 @@ QGLFramebufferObject::~QGLFramebufferObject()
bool QGLFramebufferObject::isValid() const
{
Q_D(const QGLFramebufferObject);
- return d->valid && d->fbo_guard.context();
+ return d->valid && d->fbo_guard && d->fbo_guard->id();
}
/*!
@@ -1037,7 +998,7 @@ bool QGLFramebufferObject::release()
GLuint QGLFramebufferObject::texture() const
{
Q_D(const QGLFramebufferObject);
- return d->texture;
+ return d->texture_guard ? d->texture_guard->id() : 0;
}
/*!
@@ -1092,13 +1053,7 @@ QImage QGLFramebufferObject::toImage() const
return image;
}
-#if !defined(QT_OPENGL_ES_1)
Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_buffer_2_engine)
-#endif
-
-#ifndef QT_OPENGL_ES_2
-Q_GLOBAL_STATIC(QGLEngineThreadStorage<QOpenGLPaintEngine>, qt_buffer_engine)
-#endif
/*! \reimp */
QPaintEngine *QGLFramebufferObject::paintEngine() const
@@ -1107,29 +1062,12 @@ QPaintEngine *QGLFramebufferObject::paintEngine() const
if (d->engine)
return d->engine;
-#if !defined(QT_OPENGL_ES_1)
-#if !defined (QT_OPENGL_ES_2)
- if (qt_gl_preferGL2Engine()) {
-#endif
- QPaintEngine *engine = qt_buffer_2_engine()->engine();
- if (engine->isActive() && engine->paintDevice() != this) {
- d->engine = new QGL2PaintEngineEx;
- return d->engine;
- }
- return engine;
-#if !defined (QT_OPENGL_ES_2)
- }
-#endif
-#endif
-
-#if !defined(QT_OPENGL_ES_2)
- QPaintEngine *engine = qt_buffer_engine()->engine();
+ QPaintEngine *engine = qt_buffer_2_engine()->engine();
if (engine->isActive() && engine->paintDevice() != this) {
- d->engine = new QOpenGLPaintEngine;
+ d->engine = new QGL2PaintEngineEx;
return d->engine;
}
return engine;
-#endif
}
/*!
@@ -1189,14 +1127,6 @@ void QGLFramebufferObject::drawTexture(const QRectF &target, GLuint textureId, G
const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(target, textureId, textureTarget);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLFramebufferObject::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(target, textureId, textureTarget);
-}
-#endif
-
/*!
\since 4.4
@@ -1212,14 +1142,6 @@ void QGLFramebufferObject::drawTexture(const QPointF &point, GLuint textureId, G
const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(point, textureId, textureTarget);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLFramebufferObject::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(point, textureId, textureTarget);
-}
-#endif
-
/*! \reimp */
int QGLFramebufferObject::metric(PaintDeviceMetric metric) const
{
@@ -1370,10 +1292,12 @@ void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const Q
return;
const QGLContext *ctx = QGLContext::currentContext();
- if (!ctx)
+ if (!ctx || !ctx->contextHandle())
return;
- const int height = ctx->device()->height();
+ QSurface *surface = ctx->contextHandle()->surface();
+
+ const int height = static_cast<QWindow *>(surface)->height();
const int sh = source ? source->height() : height;
const int th = target ? target->height() : height;
diff --git a/src/opengl/qglframebufferobject.h b/src/opengl/qglframebufferobject.h
index d5e5c482fb..817aecd9b7 100644
--- a/src/opengl/qglframebufferobject.h
+++ b/src/opengl/qglframebufferobject.h
@@ -81,16 +81,6 @@ public:
QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format);
QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format);
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- QGLFramebufferObject(const QSize &size, QMacCompatGLenum target = GL_TEXTURE_2D);
- QGLFramebufferObject(int width, int height, QMacCompatGLenum target = GL_TEXTURE_2D);
-
- QGLFramebufferObject(const QSize &size, Attachment attachment,
- QMacCompatGLenum target = GL_TEXTURE_2D, QMacCompatGLenum internal_format = GL_RGBA8);
- QGLFramebufferObject(int width, int height, Attachment attachment,
- QMacCompatGLenum target = GL_TEXTURE_2D, QMacCompatGLenum internal_format = GL_RGBA8);
-#endif
-
virtual ~QGLFramebufferObject();
QGLFramebufferObjectFormat format() const;
@@ -114,10 +104,6 @@ public:
void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- void drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
- void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
-#endif
static bool hasOpenGLFramebufferBlit();
static void blitFramebuffer(QGLFramebufferObject *target, const QRect &targetRect,
@@ -160,11 +146,6 @@ public:
void setInternalTextureFormat(GLenum internalTextureFormat);
GLenum internalTextureFormat() const;
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- void setTextureTarget(QMacCompatGLenum target);
- void setInternalTextureFormat(QMacCompatGLenum internalTextureFormat);
-#endif
-
bool operator==(const QGLFramebufferObjectFormat& other) const;
bool operator!=(const QGLFramebufferObjectFormat& other) const;
diff --git a/src/opengl/qglframebufferobject_p.h b/src/opengl/qglframebufferobject_p.h
index f82361279d..61d39c6a07 100644
--- a/src/opengl/qglframebufferobject_p.h
+++ b/src/opengl/qglframebufferobject_p.h
@@ -130,8 +130,9 @@ private:
class QGLFramebufferObjectPrivate
{
public:
- QGLFramebufferObjectPrivate() : fbo_guard(0), texture(0), depth_buffer(0), stencil_buffer(0)
- , color_buffer(0), valid(false), engine(0) {}
+ QGLFramebufferObjectPrivate() : fbo_guard(0), texture_guard(0), depth_buffer_guard(0)
+ , stencil_buffer_guard(0), color_buffer_guard(0)
+ , valid(false), engine(0) {}
~QGLFramebufferObjectPrivate() {}
void init(QGLFramebufferObject *q, const QSize& sz,
@@ -139,11 +140,11 @@ public:
GLenum internal_format, GLenum texture_target,
GLint samples = 0, bool mipmap = false);
bool checkFramebufferStatus() const;
- QGLSharedResourceGuard fbo_guard;
- GLuint texture;
- GLuint depth_buffer;
- GLuint stencil_buffer;
- GLuint color_buffer;
+ QGLSharedResourceGuardBase *fbo_guard;
+ QGLSharedResourceGuardBase *texture_guard;
+ QGLSharedResourceGuardBase *depth_buffer_guard;
+ QGLSharedResourceGuardBase *stencil_buffer_guard;
+ QGLSharedResourceGuardBase *color_buffer_guard;
GLenum target;
QSize size;
QGLFramebufferObjectFormat format;
@@ -152,7 +153,7 @@ public:
mutable QPaintEngine *engine;
QGLFBOGLPaintDevice glDevice;
- inline GLuint fbo() const { return fbo_guard.id(); }
+ inline GLuint fbo() const { return fbo_guard ? fbo_guard->id() : 0; }
};
diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp
index 02e7091c9e..227e6cc176 100644
--- a/src/opengl/qglfunctions.cpp
+++ b/src/opengl/qglfunctions.cpp
@@ -41,6 +41,7 @@
#include "qglfunctions.h"
#include "qgl_p.h"
+#include "QtGui/private/qopenglcontext_p.h"
QT_BEGIN_NAMESPACE
@@ -139,25 +140,28 @@ QT_BEGIN_NAMESPACE
*/
// Hidden private fields for additional extension data.
-struct QGLFunctionsPrivateEx : public QGLFunctionsPrivate
+struct QGLFunctionsPrivateEx : public QGLFunctionsPrivate, public QOpenGLSharedResource
{
- QGLFunctionsPrivateEx(const QGLContext *context = 0)
- : QGLFunctionsPrivate(context)
+ QGLFunctionsPrivateEx(QOpenGLContext *context)
+ : QGLFunctionsPrivate(QGLContext::fromOpenGLContext(context))
+ , QOpenGLSharedResource(context->shareGroup())
, m_features(-1) {}
+ void invalidateResource()
+ {
+ m_features = -1;
+ }
+
+ void freeResource(QOpenGLContext *)
+ {
+ // no gl resources to free
+ }
+
int m_features;
};
-#if QT_VERSION >= 0x040800
-Q_GLOBAL_STATIC(QGLContextGroupResource<QGLFunctionsPrivateEx>, qt_gl_functions_resource)
-#else
-static void qt_gl_functions_free(void *data)
-{
- delete reinterpret_cast<QGLFunctionsPrivateEx *>(data);
-}
+Q_GLOBAL_STATIC(QOpenGLMultiGroupSharedResource, qt_gl_functions_resource)
-Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_gl_functions_resource, (qt_gl_functions_free))
-#endif
static QGLFunctionsPrivateEx *qt_gl_functions(const QGLContext *context = 0)
{
if (!context)
@@ -165,13 +169,7 @@ static QGLFunctionsPrivateEx *qt_gl_functions(const QGLContext *context = 0)
Q_ASSERT(context);
QGLFunctionsPrivateEx *funcs =
reinterpret_cast<QGLFunctionsPrivateEx *>
- (qt_gl_functions_resource()->value(context));
-#if QT_VERSION < 0x040800
- if (!funcs) {
- funcs = new QGLFunctionsPrivateEx();
- qt_gl_functions_resource()->insert(context, funcs);
- }
-#endif
+ (qt_gl_functions_resource()->value<QGLFunctionsPrivateEx>(context->contextHandle()));
return funcs;
}
diff --git a/src/opengl/qglfunctions.h b/src/opengl/qglfunctions.h
index 2bb6119b29..e789d4020d 100644
--- a/src/opengl/qglfunctions.h
+++ b/src/opengl/qglfunctions.h
@@ -419,7 +419,7 @@ struct QGLFunctionsPrivate
inline void QGLFunctions::glActiveTexture(GLenum texture)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glActiveTexture(texture);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -449,7 +449,7 @@ inline void QGLFunctions::glBindAttribLocation(GLuint program, GLuint index, con
inline void QGLFunctions::glBindBuffer(GLenum target, GLuint buffer)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glBindBuffer(target, buffer);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -519,7 +519,7 @@ inline void QGLFunctions::glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLen
inline void QGLFunctions::glBufferData(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glBufferData(target, size, data, usage);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -529,7 +529,7 @@ inline void QGLFunctions::glBufferData(GLenum target, qgl_GLsizeiptr size, const
inline void QGLFunctions::glBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glBufferSubData(target, offset, size, data);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -568,7 +568,7 @@ inline void QGLFunctions::glCompileShader(GLuint shader)
inline void QGLFunctions::glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -578,7 +578,7 @@ inline void QGLFunctions::glCompressedTexImage2D(GLenum target, GLint level, GLe
inline void QGLFunctions::glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -608,7 +608,7 @@ inline GLuint QGLFunctions::glCreateShader(GLenum type)
inline void QGLFunctions::glDeleteBuffers(GLsizei n, const GLuint* buffers)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glDeleteBuffers(n, buffers);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -717,7 +717,7 @@ inline void QGLFunctions::glFramebufferTexture2D(GLenum target, GLenum attachmen
inline void QGLFunctions::glGenBuffers(GLsizei n, GLuint* buffers)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glGenBuffers(n, buffers);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -947,7 +947,7 @@ inline void QGLFunctions::glGetVertexAttribPointerv(GLuint index, GLenum pname,
inline GLboolean QGLFunctions::glIsBuffer(GLuint buffer)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
return ::glIsBuffer(buffer);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
@@ -1027,7 +1027,7 @@ inline void QGLFunctions::glRenderbufferStorage(GLenum target, GLenum internalfo
inline void QGLFunctions::glSampleCoverage(GLclampf value, GLboolean invert)
{
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2)
::glSampleCoverage(value, invert);
#else
Q_ASSERT(QGLFunctions::isInitialized(d_ptr));
diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp
index b4e12d8b7e..08807bdd49 100644
--- a/src/opengl/qglpaintdevice.cpp
+++ b/src/opengl/qglpaintdevice.cpp
@@ -43,14 +43,6 @@
#include <private/qgl_p.h>
#include <private/qglpixelbuffer_p.h>
#include <private/qglframebufferobject_p.h>
-#ifdef Q_WS_X11
-#include <private/qpixmapdata_x11gl_p.h>
-#endif
-
-#if !defined(QT_OPENGL_ES_1)
-#include <private/qpixmapdata_gl_p.h>
-#include <private/qwindowsurface_gl_p.h>
-#endif
QT_BEGIN_NAMESPACE
@@ -220,19 +212,7 @@ QGLPaintDevice* QGLPaintDevice::getDevice(QPaintDevice* pd)
glpd = &(static_cast<QGLFramebufferObject*>(pd)->d_func()->glDevice);
break;
case QInternal::Pixmap: {
-#if !defined(QT_OPENGL_ES_1)
- QPixmapData* pmd = static_cast<QPixmap*>(pd)->pixmapData();
- if (pmd->classId() == QPixmapData::OpenGLClass)
- glpd = static_cast<QGLPixmapData*>(pmd)->glDevice();
-#ifdef Q_WS_X11
- else if (pmd->classId() == QPixmapData::X11Class)
- glpd = static_cast<QX11GLPixmapData*>(pmd);
-#endif
- else
- qWarning("Pixmap type not supported for GL rendering");
-#else
- qWarning("Pixmap render targets not supported on OpenGL ES 1.x");
-#endif
+ qWarning("Pixmap type not supported for GL rendering");
break;
}
default:
diff --git a/src/opengl/qglpaintdevice_p.h b/src/opengl/qglpaintdevice_p.h
index c5390645e2..32ae85dc90 100644
--- a/src/opengl/qglpaintdevice_p.h
+++ b/src/opengl/qglpaintdevice_p.h
@@ -55,7 +55,7 @@
#include <qpaintdevice.h>
-#include <qgl.h>
+#include <QtOpenGL/qgl.h>
QT_BEGIN_NAMESPACE
diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp
index 45e7cdd875..ddabbef0b2 100644
--- a/src/opengl/qglpixelbuffer.cpp
+++ b/src/opengl/qglpixelbuffer.cpp
@@ -81,8 +81,7 @@
As of Qt 4.8, it's possible to render into a QGLPixelBuffer using
a QPainter in a separate thread. Note that OpenGL 2.0 or OpenGL ES
- 2.0 is required for this to work. Also, under X11, it's necessary
- to set the Qt::AA_X11InitThreads application attribute.
+ 2.0 is required for this to work.
Pbuffers are provided by the OpenGL \c pbuffer extension; call
hasOpenGLPbuffer() to find out if the system provides pbuffers.
@@ -92,28 +91,16 @@
#include <QtCore/qglobal.h>
-#if !defined(QT_OPENGL_ES_1)
-#include <private/qpaintengineex_opengl2_p.h>
-#endif
+#include "gl2paintengineex/qpaintengineex_opengl2_p.h"
#include <qglpixelbuffer.h>
#include <private/qglpixelbuffer_p.h>
#include <private/qfont_p.h>
#include <qimage.h>
-#ifndef QT_OPENGL_ES_2
-#include <private/qpaintengine_opengl_p.h>
-#endif
-
QT_BEGIN_NAMESPACE
-#if !defined(QT_OPENGL_ES_2)
-extern void qgl_cleanup_glyph_cache(QGLContext *);
-#else
-void qgl_cleanup_glyph_cache(QGLContext *) {}
-#endif
-
-extern Q_OPENGL_EXPORT QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
+extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
QGLContext* QGLPBufferGLPaintDevice::context() const
@@ -149,20 +136,6 @@ void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &form
glDevice.setPBuffer(q);
qctx->d_func()->paintDevice = q;
qctx->d_func()->valid = true;
-#if defined(Q_WS_WIN) && !defined(QT_OPENGL_ES)
- qctx->d_func()->dc = dc;
- qctx->d_func()->rc = ctx;
-#elif (defined(Q_WS_X11) && defined(QT_NO_EGL))
- qctx->d_func()->cx = ctx;
- qctx->d_func()->pbuf = (void *) pbuf;
- qctx->d_func()->vi = 0;
-#elif defined(Q_WS_MAC)
- qctx->d_func()->cx = ctx;
- qctx->d_func()->vi = 0;
-#elif !defined(QT_NO_EGL)
- qctx->d_func()->eglContext = ctx;
- qctx->d_func()->eglSurface = pbuf;
-#endif
}
}
@@ -221,7 +194,6 @@ QGLPixelBuffer::~QGLPixelBuffer()
QGLContext *current = const_cast<QGLContext *>(QGLContext::currentContext());
if (current != d->qctx)
makeCurrent();
- qgl_cleanup_glyph_cache(d->qctx);
d->cleanup();
delete d->qctx;
if (current && current != d->qctx)
@@ -261,6 +233,8 @@ bool QGLPixelBuffer::doneCurrent()
}
/*!
+ \fn GLuint QGLPixelBuffer::generateDynamicTexture() const
+
Generates and binds a 2D GL texture that is the same size as the
pbuffer, and returns the texture's ID. This can be used in
conjunction with bindToDynamicTexture() and
@@ -269,20 +243,6 @@ bool QGLPixelBuffer::doneCurrent()
\sa size()
*/
-#if (defined(Q_WS_X11) || defined(Q_WS_WIN)) && defined(QT_NO_EGL)
-GLuint QGLPixelBuffer::generateDynamicTexture() const
-{
- Q_D(const QGLPixelBuffer);
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, d->req_size.width(), d->req_size.height(), 0, GL_RGBA, GL_FLOAT, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- return texture;
-}
-#endif
-
/*! \fn bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
Binds the texture specified by \a texture_id to this pbuffer.
@@ -353,13 +313,6 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
#endif
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-void QGLPixelBuffer::updateDynamicTexture(QMacCompatGLuint texture_id) const
-{
- updateDynamicTexture(GLuint(texture_id));
-}
-#endif
-
/*!
Returns the size of the pbuffer.
*/
@@ -402,27 +355,12 @@ bool QGLPixelBuffer::isValid() const
return !d->invalid;
}
-#if !defined(QT_OPENGL_ES_1)
Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_buffer_2_engine)
-#endif
-
-#ifndef QT_OPENGL_ES_2
-Q_GLOBAL_STATIC(QGLEngineThreadStorage<QOpenGLPaintEngine>, qt_buffer_engine)
-#endif
/*! \reimp */
QPaintEngine *QGLPixelBuffer::paintEngine() const
{
-#if defined(QT_OPENGL_ES_1)
- return qt_buffer_engine()->engine();
-#elif defined(QT_OPENGL_ES_2)
return qt_buffer_2_engine()->engine();
-#else
- if (qt_gl_preferGL2Engine())
- return qt_buffer_2_engine()->engine();
- else
- return qt_buffer_engine()->engine();
-#endif
}
/*! \reimp */
@@ -493,15 +431,6 @@ GLuint QGLPixelBuffer::bindTexture(const QImage &image, GLenum target)
#endif
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-GLuint QGLPixelBuffer::bindTexture(const QImage &image, QMacCompatGLenum target)
-{
- Q_D(QGLPixelBuffer);
- return d->qctx->bindTexture(image, target, QMacCompatGLint(GL_RGBA8));
-}
-#endif
-
/*! \overload
Generates and binds a 2D GL texture based on \a pixmap.
@@ -520,15 +449,6 @@ GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, GLenum target)
#endif
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target)
-{
- Q_D(QGLPixelBuffer);
- return d->qctx->bindTexture(pixmap, target, QMacCompatGLint(GL_RGBA8));
-}
-#endif
-
/*! \overload
Reads the DirectDrawSurface (DDS) compressed file \a fileName and
@@ -555,15 +475,6 @@ void QGLPixelBuffer::deleteTexture(GLuint texture_id)
d->qctx->deleteTexture(texture_id);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLPixelBuffer::deleteTexture(QMacCompatGLuint texture_id)
-{
- Q_D(QGLPixelBuffer);
- d->qctx->deleteTexture(texture_id);
-}
-#endif
-
/*!
\since 4.4
@@ -579,15 +490,6 @@ void QGLPixelBuffer::drawTexture(const QRectF &target, GLuint textureId, GLenum
d->qctx->drawTexture(target, textureId, textureTarget);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLPixelBuffer::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- Q_D(QGLPixelBuffer);
- d->qctx->drawTexture(target, textureId, textureTarget);
-}
-#endif
-
/*!
\since 4.4
@@ -602,15 +504,6 @@ void QGLPixelBuffer::drawTexture(const QPointF &point, GLuint textureId, GLenum
d->qctx->drawTexture(point, textureId, textureTarget);
}
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLPixelBuffer::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
-{
- Q_D(QGLPixelBuffer);
- d->qctx->drawTexture(point, textureId, textureTarget);
-}
-#endif
-
/*!
Returns the format of the pbuffer. The format may be different
from the one that was requested.
diff --git a/src/opengl/qglpixelbuffer.h b/src/opengl/qglpixelbuffer.h
index dcd1a6ca71..0c7ad38237 100644
--- a/src/opengl/qglpixelbuffer.h
+++ b/src/opengl/qglpixelbuffer.h
@@ -80,18 +80,6 @@ public:
void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- bool bindToDynamicTexture(QMacCompatGLuint texture);
- void updateDynamicTexture(QMacCompatGLuint texture_id) const;
- GLuint bindTexture(const QImage &image, QMacCompatGLenum target = GL_TEXTURE_2D);
- GLuint bindTexture(const QPixmap &pixmap, QMacCompatGLenum target = GL_TEXTURE_2D);
-
- void drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
- void drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget = GL_TEXTURE_2D);
-
- void deleteTexture(QMacCompatGLuint texture_id);
-#endif
-
QSize size() const;
Qt::HANDLE handle() const;
QImage toImage() const;
@@ -109,7 +97,6 @@ private:
Q_DISABLE_COPY(QGLPixelBuffer)
QScopedPointer<QGLPixelBufferPrivate> d_ptr;
friend class QGLDrawable;
- friend class QGLWindowSurface;
friend class QGLPaintDevice;
friend class QGLPBufferGLPaintDevice;
friend class QGLContextPrivate;
diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp
deleted file mode 100644
index 64d032799a..0000000000
--- a/src/opengl/qglpixelbuffer_egl.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qdebug.h>
-#include "qglpixelbuffer.h"
-#include "qglpixelbuffer_p.h"
-#include "qgl_egl_p.h"
-
-#include <qimage.h>
-#include <private/qgl_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifdef EGL_BIND_TO_TEXTURE_RGBA
-#define QGL_RENDER_TEXTURE 1
-#else
-#define QGL_RENDER_TEXTURE 0
-#endif
-
-bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
-{
- // Create the EGL context.
- ctx = new QEglContext();
- ctx->setApi(QEgl::OpenGL);
-
- // Find the shared context.
- QEglContext *shareContext = 0;
- if (shareWidget && shareWidget->d_func()->glcx)
- shareContext = shareWidget->d_func()->glcx->d_func()->eglContext;
-
- // Choose an appropriate configuration. We use the best format
- // we can find, even if it is greater than the requested format.
- // We try for a pbuffer that is capable of texture rendering if possible.
- textureFormat = EGL_NONE;
- if (shareContext) {
- // Use the same configuration as the widget we are sharing with.
- ctx->setConfig(shareContext->config());
-#if QGL_RENDER_TEXTURE
- if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGBA) == EGL_TRUE)
- textureFormat = EGL_TEXTURE_RGBA;
- else if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGB) == EGL_TRUE)
- textureFormat = EGL_TEXTURE_RGB;
-#endif
- } else {
- QEglProperties configProps;
- qt_eglproperties_set_glformat(configProps, f);
- configProps.setDeviceType(QInternal::Pbuffer);
- configProps.setRenderableType(ctx->api());
- bool ok = false;
-#if QGL_RENDER_TEXTURE
- textureFormat = EGL_TEXTURE_RGBA;
- configProps.setValue(EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE);
- ok = ctx->chooseConfig(configProps, QEgl::BestPixelFormat);
- if (!ok) {
- // Try again with RGB texture rendering.
- textureFormat = EGL_TEXTURE_RGB;
- configProps.removeValue(EGL_BIND_TO_TEXTURE_RGBA);
- configProps.setValue(EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE);
- ok = ctx->chooseConfig(configProps, QEgl::BestPixelFormat);
- if (!ok) {
- // One last try for a pbuffer with no texture rendering.
- configProps.removeValue(EGL_BIND_TO_TEXTURE_RGB);
- textureFormat = EGL_NONE;
- }
- }
-#endif
- if (!ok) {
- if (!ctx->chooseConfig(configProps, QEgl::BestPixelFormat)) {
- delete ctx;
- ctx = 0;
- return false;
- }
- }
- }
-
- // Retrieve the actual format properties.
- qt_glformat_from_eglconfig(format, ctx->config());
-
- // Create the attributes needed for the pbuffer.
- QEglProperties attribs;
- attribs.setValue(EGL_WIDTH, size.width());
- attribs.setValue(EGL_HEIGHT, size.height());
-#if QGL_RENDER_TEXTURE
- if (textureFormat != EGL_NONE) {
- attribs.setValue(EGL_TEXTURE_FORMAT, textureFormat);
- attribs.setValue(EGL_TEXTURE_TARGET, EGL_TEXTURE_2D);
- }
-#endif
-
- // Create the pbuffer surface.
- pbuf = eglCreatePbufferSurface(ctx->display(), ctx->config(), attribs.properties());
-#if QGL_RENDER_TEXTURE
- if (pbuf == EGL_NO_SURFACE && textureFormat != EGL_NONE) {
- // Try again with texture rendering disabled.
- textureFormat = EGL_NONE;
- attribs.removeValue(EGL_TEXTURE_FORMAT);
- attribs.removeValue(EGL_TEXTURE_TARGET);
- pbuf = eglCreatePbufferSurface(ctx->display(), ctx->config(), attribs.properties());
- }
-#endif
- if (pbuf == EGL_NO_SURFACE) {
- qWarning() << "QGLPixelBufferPrivate::init(): Unable to create EGL pbuffer surface:" << QEgl::errorString();
- return false;
- }
-
- // Create a new context for the configuration.
- if (!ctx->createContext(shareContext)) {
- delete ctx;
- ctx = 0;
- return false;
- }
-
- return true;
-}
-
-bool QGLPixelBufferPrivate::cleanup()
-{
- // No need to destroy "pbuf" here - it is done in QGLContext::reset().
- return true;
-}
-
-bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
-{
-#if QGL_RENDER_TEXTURE
- Q_D(QGLPixelBuffer);
- if (d->invalid || d->textureFormat == EGL_NONE || !d->ctx)
- return false;
- glBindTexture(GL_TEXTURE_2D, texture_id);
- return eglBindTexImage(d->ctx->display(), d->pbuf, EGL_BACK_BUFFER);
-#else
- Q_UNUSED(texture_id);
- return false;
-#endif
-}
-
-void QGLPixelBuffer::releaseFromDynamicTexture()
-{
-#if QGL_RENDER_TEXTURE
- Q_D(QGLPixelBuffer);
- if (d->invalid || d->textureFormat == EGL_NONE || !d->ctx)
- return;
- eglReleaseTexImage(d->ctx->display(), d->pbuf, EGL_BACK_BUFFER);
-#endif
-}
-
-
-GLuint QGLPixelBuffer::generateDynamicTexture() const
-{
-#if QGL_RENDER_TEXTURE
- Q_D(const QGLPixelBuffer);
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- if (d->textureFormat == EGL_TEXTURE_RGB)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, d->req_size.width(), d->req_size.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
- else
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d->req_size.width(), d->req_size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- return texture;
-#else
- return 0;
-#endif
-}
-
-bool QGLPixelBuffer::hasOpenGLPbuffers()
-{
- // See if we have at least 1 configuration that matches the default format.
- EGLDisplay dpy = QEgl::display();
- if (dpy == EGL_NO_DISPLAY)
- return false;
- QEglProperties configProps;
- qt_eglproperties_set_glformat(configProps, QGLFormat::defaultFormat());
- configProps.setDeviceType(QInternal::Pbuffer);
- configProps.setRenderableType(QEgl::OpenGL);
- do {
- EGLConfig cfg = 0;
- EGLint matching = 0;
- if (eglChooseConfig(dpy, configProps.properties(),
- &cfg, 1, &matching) && matching > 0)
- return true;
- } while (configProps.reduceConfiguration());
- return false;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglpixelbuffer_mac.mm b/src/opengl/qglpixelbuffer_mac.mm
deleted file mode 100644
index b364209b95..0000000000
--- a/src/opengl/qglpixelbuffer_mac.mm
+++ /dev/null
@@ -1,331 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qglpixelbuffer.h"
-#include "qglpixelbuffer_p.h"
-
-#ifndef QT_MAC_USE_COCOA
-#include <AGL/agl.h>
-#endif
-
-#include <qimage.h>
-#include <private/qgl_p.h>
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-#ifndef GL_TEXTURE_RECTANGLE_EXT
-#define GL_TEXTURE_RECTANGLE_EXT 0x84F5
-#endif
-
-static int nearest_gl_texture_size(int v)
-{
- int n = 0, last = 0;
- for (int s = 0; s < 32; ++s) {
- if (((v>>s) & 1) == 1) {
- ++n;
- last = s;
- }
- }
- if (n > 1)
- return 1 << (last+1);
- return 1 << last;
-}
-
-bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
-{
-#ifdef QT_MAC_USE_COCOA
- Q_Q(QGLPixelBuffer);
- // create a dummy context
- QGLContext context(f, q);
- context.create(shareWidget ? shareWidget->context() : 0);
-
- if (context.isSharing())
- share_ctx = shareWidget->context()->d_func()->cx;
-
- // steal the NSOpenGLContext and update the format
- ctx = context.d_func()->cx;
- context.d_func()->cx = 0;
- // d->cx will be set to ctx later in
- // QGLPixelBufferPrivate::common_init, so we need to retain it:
- [static_cast<NSOpenGLContext *>(ctx) retain];
-
- format = context.format();
-
- GLenum target = GL_TEXTURE_2D;
-
- if ((QGLExtensions::glExtensions() & QGLExtensions::TextureRectangle)
- && (size.width() != nearest_gl_texture_size(size.width())
- || size.height() != nearest_gl_texture_size(size.height())))
- {
- target = GL_TEXTURE_RECTANGLE_EXT;
- }
-
- pbuf = [[NSOpenGLPixelBuffer alloc] initWithTextureTarget:target
- textureInternalFormat:GL_RGBA
- textureMaxMipMapLevel:0
- pixelsWide:size.width()
- pixelsHigh:size.height()];
- if (!pbuf) {
- qWarning("QGLPixelBuffer: Cannot create a pbuffer");
- return false;
- }
-
- [static_cast<NSOpenGLContext *>(ctx) setPixelBuffer:static_cast<NSOpenGLPixelBuffer *>(pbuf)
- cubeMapFace:0
- mipMapLevel:0
- currentVirtualScreen:0];
- return true;
-#else
- GLint attribs[40], i=0;
- attribs[i++] = AGL_RGBA;
- attribs[i++] = AGL_BUFFER_SIZE;
- attribs[i++] = 32;
- attribs[i++] = AGL_LEVEL;
- attribs[i++] = f.plane();
- if (f.redBufferSize() != -1) {
- attribs[i++] = AGL_RED_SIZE;
- attribs[i++] = f.redBufferSize();
- }
- if (f.greenBufferSize() != -1) {
- attribs[i++] = AGL_GREEN_SIZE;
- attribs[i++] = f.greenBufferSize();
- }
- if (f.blueBufferSize() != -1) {
- attribs[i++] = AGL_BLUE_SIZE;
- attribs[i++] = f.blueBufferSize();
- }
- if (f.stereo())
- attribs[i++] = AGL_STEREO;
- if (f.alpha()) {
- attribs[i++] = AGL_ALPHA_SIZE;
- attribs[i++] = f.alphaBufferSize() == -1 ? 8 : f.alphaBufferSize();
- }
- if (f.stencil()) {
- attribs[i++] = AGL_STENCIL_SIZE;
- attribs[i++] = f.stencilBufferSize() == -1 ? 8 : f.stencilBufferSize();
- }
- if (f.depth()) {
- attribs[i++] = AGL_DEPTH_SIZE;
- attribs[i++] = f.depthBufferSize() == -1 ? 32 : f.depthBufferSize();
- }
- if (f.accum()) {
- attribs[i++] = AGL_ACCUM_RED_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
- attribs[i++] = AGL_ACCUM_BLUE_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
- attribs[i++] = AGL_ACCUM_GREEN_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
- attribs[i++] = AGL_ACCUM_ALPHA_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
- }
-
- if (f.sampleBuffers()) {
- attribs[i++] = AGL_SAMPLE_BUFFERS_ARB;
- attribs[i++] = 1;
- attribs[i++] = AGL_SAMPLES_ARB;
- attribs[i++] = f.samples() == -1 ? 4 : f.samples();
- }
- attribs[i] = AGL_NONE;
-
- AGLPixelFormat format = aglChoosePixelFormat(0, 0, attribs);
- if (!format) {
- qWarning("QGLPixelBuffer: Unable to find a pixel format (AGL error %d).",
- (int) aglGetError());
- return false;
- }
-
- GLint res;
- aglDescribePixelFormat(format, AGL_LEVEL, &res);
- this->format.setPlane(res);
- aglDescribePixelFormat(format, AGL_DOUBLEBUFFER, &res);
- this->format.setDoubleBuffer(res);
- aglDescribePixelFormat(format, AGL_DEPTH_SIZE, &res);
- this->format.setDepth(res);
- if (this->format.depth())
- this->format.setDepthBufferSize(res);
- aglDescribePixelFormat(format, AGL_RGBA, &res);
- this->format.setRgba(res);
- aglDescribePixelFormat(format, AGL_RED_SIZE, &res);
- this->format.setRedBufferSize(res);
- aglDescribePixelFormat(format, AGL_GREEN_SIZE, &res);
- this->format.setGreenBufferSize(res);
- aglDescribePixelFormat(format, AGL_BLUE_SIZE, &res);
- this->format.setBlueBufferSize(res);
- aglDescribePixelFormat(format, AGL_ALPHA_SIZE, &res);
- this->format.setAlpha(res);
- if (this->format.alpha())
- this->format.setAlphaBufferSize(res);
- aglDescribePixelFormat(format, AGL_ACCUM_RED_SIZE, &res);
- this->format.setAccum(res);
- if (this->format.accum())
- this->format.setAccumBufferSize(res);
- aglDescribePixelFormat(format, AGL_STENCIL_SIZE, &res);
- this->format.setStencil(res);
- if (this->format.stencil())
- this->format.setStencilBufferSize(res);
- aglDescribePixelFormat(format, AGL_STEREO, &res);
- this->format.setStereo(res);
- aglDescribePixelFormat(format, AGL_SAMPLE_BUFFERS_ARB, &res);
- this->format.setSampleBuffers(res);
- if (this->format.sampleBuffers()) {
- aglDescribePixelFormat(format, AGL_SAMPLES_ARB, &res);
- this->format.setSamples(res);
- }
-
- AGLContext share = 0;
- if (shareWidget)
- share = share_ctx = static_cast<AGLContext>(shareWidget->d_func()->glcx->d_func()->cx);
- ctx = aglCreateContext(format, share);
- if (!ctx) {
- qWarning("QGLPixelBuffer: Unable to create a context (AGL error %d).",
- (int) aglGetError());
- return false;
- }
-
- GLenum target = GL_TEXTURE_2D;
-
- if ((QGLExtensions::glExtensions() & QGLExtensions::TextureRectangle)
- && (size.width() != nearest_gl_texture_size(size.width())
- || size.height() != nearest_gl_texture_size(size.height())))
- {
- target = GL_TEXTURE_RECTANGLE_EXT;
- }
-
- if (!aglCreatePBuffer(size.width(), size.height(), target, GL_RGBA, 0, &pbuf)) {
- qWarning("QGLPixelBuffer: Unable to create a pbuffer (AGL error %d).",
- (int) aglGetError());
- return false;
- }
-
- if (!aglSetPBuffer(ctx, pbuf, 0, 0, 0)) {
- qWarning("QGLPixelBuffer: Unable to set pbuffer (AGL error %d).",
- (int) aglGetError());
- return false;
- }
-
- aglDestroyPixelFormat(format);
- return true;
-
-#endif
-}
-
-bool QGLPixelBufferPrivate::cleanup()
-{
-#ifdef QT_MAC_USE_COCOA
- [static_cast<NSOpenGLPixelBuffer *>(pbuf) release];
- pbuf = 0;
- [static_cast<NSOpenGLContext *>(ctx) release];
- ctx = 0;
-#else
- aglDestroyPBuffer(pbuf);
-#endif
- return true;
-}
-
-bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
-{
- Q_D(QGLPixelBuffer);
- if (d->invalid || !d->share_ctx)
- return false;
-
-#ifdef QT_MAC_USE_COCOA
- NSOpenGLContext *oldContext = [NSOpenGLContext currentContext];
- if (d->share_ctx != oldContext)
- [static_cast<NSOpenGLContext *>(d->share_ctx) makeCurrentContext];
- glBindTexture(GL_TEXTURE_2D, texture_id);
- [static_cast<NSOpenGLContext *>(d->share_ctx)
- setTextureImageToPixelBuffer:static_cast<NSOpenGLPixelBuffer *>(d->pbuf)
- colorBuffer:GL_FRONT];
- if (oldContext && oldContext != d->share_ctx)
- [oldContext makeCurrentContext];
- return true;
-#else
- aglSetCurrentContext(d->share_ctx);
- glBindTexture(GL_TEXTURE_2D, texture_id);
- aglTexImagePBuffer(d->share_ctx, d->pbuf, GL_FRONT);
- return true;
-#endif
-}
-
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-bool QGLPixelBuffer::bindToDynamicTexture(QMacCompatGLuint texture_id)
-{
- return bindToDynamicTexture(GLuint(texture_id));
-}
-#endif
-
-void QGLPixelBuffer::releaseFromDynamicTexture()
-{
-}
-
-GLuint QGLPixelBuffer::generateDynamicTexture() const
-{
-#ifdef QT_MAC_USE_COCOA
- Q_D(const QGLPixelBuffer);
- NSOpenGLContext *oldContext = [NSOpenGLContext currentContext];
- if (d->share_ctx != oldContext)
- [static_cast<NSOpenGLContext *>(d->share_ctx) makeCurrentContext];
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-
- if (oldContext && oldContext != d->share_ctx)
- [oldContext makeCurrentContext];
- return texture;
-#else
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- return texture;
-#endif
-}
-
-bool QGLPixelBuffer::hasOpenGLPbuffers()
-{
- return true;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglpixelbuffer_p.h b/src/opengl/qglpixelbuffer_p.h
index eb761047e7..05e161b7ef 100644
--- a/src/opengl/qglpixelbuffer_p.h
+++ b/src/opengl/qglpixelbuffer_p.h
@@ -59,77 +59,6 @@ QT_BEGIN_INCLUDE_NAMESPACE
#include "QtOpenGL/qglpixelbuffer.h"
#include <private/qgl_p.h>
#include <private/qglpaintdevice_p.h>
-
-#if defined(Q_WS_X11) && defined(QT_NO_EGL)
-#include <GL/glx.h>
-
-// The below is needed to for compilation on HPUX, due to broken GLX
-// headers. Some of the systems define GLX_VERSION_1_3 without
-// defining the GLXFBConfig structure, which is wrong.
-#if defined (Q_OS_HPUX) && defined(QT_DEFINE_GLXFBCONFIG_STRUCT)
-typedef unsigned long GLXPbuffer;
-
-struct GLXFBConfig {
- int visualType;
- int transparentType;
- /* colors are floats scaled to ints */
- int transparentRed, transparentGreen, transparentBlue, transparentAlpha;
- int transparentIndex;
-
- int visualCaveat;
-
- int associatedVisualId;
- int screen;
-
- int drawableType;
- int renderType;
-
- int maxPbufferWidth, maxPbufferHeight, maxPbufferPixels;
- int optimalPbufferWidth, optimalPbufferHeight; /* for SGIX_pbuffer */
-
- int visualSelectGroup; /* visuals grouped by select priority */
-
- unsigned int id;
-
- GLboolean rgbMode;
- GLboolean colorIndexMode;
- GLboolean doubleBufferMode;
- GLboolean stereoMode;
- GLboolean haveAccumBuffer;
- GLboolean haveDepthBuffer;
- GLboolean haveStencilBuffer;
-
- /* The number of bits present in various buffers */
- GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits;
- GLint depthBits;
- GLint stencilBits;
- GLint indexBits;
- GLint redBits, greenBits, blueBits, alphaBits;
- GLuint redMask, greenMask, blueMask, alphaMask;
-
- GLuint multiSampleSize; /* Number of samples per pixel (0 if no ms) */
-
- GLuint nMultiSampleBuffers; /* Number of available ms buffers */
- GLint maxAuxBuffers;
-
- /* frame buffer level */
- GLint level;
-
- /* color ranges (for SGI_color_range) */
- GLboolean extendedRange;
- GLdouble minRed, maxRed;
- GLdouble minGreen, maxGreen;
- GLdouble minBlue, maxBlue;
- GLdouble minAlpha, maxAlpha;
-};
-
-#endif // Q_OS_HPUX
-
-#elif defined(Q_WS_WIN)
-DECLARE_HANDLE(HPBUFFERARB);
-#elif !defined(QT_NO_EGL)
-#include <QtGui/private/qegl_p.h>
-#endif
QT_END_INCLUDE_NAMESPACE
class QEglContext;
@@ -152,11 +81,6 @@ class QGLPixelBufferPrivate {
public:
QGLPixelBufferPrivate(QGLPixelBuffer *q) : q_ptr(q), invalid(true), qctx(0), pbuf(0), ctx(0)
{
-#ifdef Q_WS_WIN
- dc = 0;
-#elif defined(Q_WS_MACX)
- share_ctx = 0;
-#endif
}
bool init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget);
void common_init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget);
@@ -172,36 +96,9 @@ public:
QPointer<QGLWidget> req_shareWidget;
QSize req_size;
-#if defined(Q_WS_X11) && defined(QT_NO_EGL)
- GLXPbuffer pbuf;
- GLXContext ctx;
-#elif defined(Q_WS_WIN)
- HDC dc;
- bool has_render_texture :1;
-#if !defined(QT_OPENGL_ES)
- HPBUFFERARB pbuf;
- HGLRC ctx;
-#endif
-#elif defined(Q_WS_MACX)
-# ifdef QT_MAC_USE_COCOA
- void *pbuf;
- void *ctx;
- void *share_ctx;
-# else
- AGLPbuffer pbuf;
- AGLContext ctx;
- AGLContext share_ctx;
-# endif
-#endif
-#ifndef QT_NO_EGL
- EGLSurface pbuf;
- QEglContext *ctx;
- int textureFormat;
-#elif defined(Q_WS_QPA)
//stubs
void *pbuf;
void *ctx;
-#endif
};
QT_END_NAMESPACE
diff --git a/src/opengl/qglpixelbuffer_win.cpp b/src/opengl/qglpixelbuffer_win.cpp
deleted file mode 100644
index 80ce99219e..0000000000
--- a/src/opengl/qglpixelbuffer_win.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qglpixelbuffer.h>
-#include <qgl.h>
-#include <private/qgl_p.h>
-
-#include <private/qglpixelbuffer_p.h>
-
-#include <qimage.h>
-#include <qdebug.h>
-
-QT_BEGIN_NAMESPACE
-
-/* WGL_WGLEXT_PROTOTYPES */
-typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
-typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
-typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
-typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
-typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
-typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
-typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
-typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
-typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
-typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
-typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
-typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int * piAttribList);
-
-#ifndef WGL_ARB_pbuffer
-#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
-#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
-#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
-#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
-#define WGL_PBUFFER_LARGEST_ARB 0x2033
-#define WGL_PBUFFER_WIDTH_ARB 0x2034
-#define WGL_PBUFFER_HEIGHT_ARB 0x2035
-#define WGL_PBUFFER_LOST_ARB 0x2036
-#endif
-
-#ifndef WGL_ARB_pixel_format
-#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
-#define WGL_DRAW_TO_WINDOW_ARB 0x2001
-#define WGL_DRAW_TO_BITMAP_ARB 0x2002
-#define WGL_ACCELERATION_ARB 0x2003
-#define WGL_NEED_PALETTE_ARB 0x2004
-#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
-#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
-#define WGL_SWAP_METHOD_ARB 0x2007
-#define WGL_NUMBER_OVERLAYS_ARB 0x2008
-#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
-#define WGL_TRANSPARENT_ARB 0x200A
-#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
-#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
-#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
-#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
-#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
-#define WGL_SHARE_DEPTH_ARB 0x200C
-#define WGL_SHARE_STENCIL_ARB 0x200D
-#define WGL_SHARE_ACCUM_ARB 0x200E
-#define WGL_SUPPORT_GDI_ARB 0x200F
-#define WGL_SUPPORT_OPENGL_ARB 0x2010
-#define WGL_DOUBLE_BUFFER_ARB 0x2011
-#define WGL_STEREO_ARB 0x2012
-#define WGL_PIXEL_TYPE_ARB 0x2013
-#define WGL_COLOR_BITS_ARB 0x2014
-#define WGL_RED_BITS_ARB 0x2015
-#define WGL_RED_SHIFT_ARB 0x2016
-#define WGL_GREEN_BITS_ARB 0x2017
-#define WGL_GREEN_SHIFT_ARB 0x2018
-#define WGL_BLUE_BITS_ARB 0x2019
-#define WGL_BLUE_SHIFT_ARB 0x201A
-#define WGL_ALPHA_BITS_ARB 0x201B
-#define WGL_ALPHA_SHIFT_ARB 0x201C
-#define WGL_ACCUM_BITS_ARB 0x201D
-#define WGL_ACCUM_RED_BITS_ARB 0x201E
-#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
-#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
-#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
-#define WGL_DEPTH_BITS_ARB 0x2022
-#define WGL_STENCIL_BITS_ARB 0x2023
-#define WGL_AUX_BUFFERS_ARB 0x2024
-#define WGL_NO_ACCELERATION_ARB 0x2025
-#define WGL_GENERIC_ACCELERATION_ARB 0x2026
-#define WGL_FULL_ACCELERATION_ARB 0x2027
-#define WGL_SWAP_EXCHANGE_ARB 0x2028
-#define WGL_SWAP_COPY_ARB 0x2029
-#define WGL_SWAP_UNDEFINED_ARB 0x202A
-#define WGL_TYPE_RGBA_ARB 0x202B
-#define WGL_TYPE_COLORINDEX_ARB 0x202C
-#endif
-
-#ifndef WGL_ARB_render_texture
-#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
-#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
-#define WGL_TEXTURE_FORMAT_ARB 0x2072
-#define WGL_TEXTURE_TARGET_ARB 0x2073
-#define WGL_MIPMAP_TEXTURE_ARB 0x2074
-#define WGL_TEXTURE_RGB_ARB 0x2075
-#define WGL_TEXTURE_RGBA_ARB 0x2076
-#define WGL_NO_TEXTURE_ARB 0x2077
-#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
-#define WGL_TEXTURE_1D_ARB 0x2079
-#define WGL_TEXTURE_2D_ARB 0x207A
-#define WGL_MIPMAP_LEVEL_ARB 0x207B
-#define WGL_CUBE_MAP_FACE_ARB 0x207C
-#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
-#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
-#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
-#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
-#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
-#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
-#define WGL_FRONT_LEFT_ARB 0x2083
-#define WGL_FRONT_RIGHT_ARB 0x2084
-#define WGL_BACK_LEFT_ARB 0x2085
-#define WGL_BACK_RIGHT_ARB 0x2086
-#define WGL_AUX0_ARB 0x2087
-#define WGL_AUX1_ARB 0x2088
-#define WGL_AUX2_ARB 0x2089
-#define WGL_AUX3_ARB 0x208A
-#define WGL_AUX4_ARB 0x208B
-#define WGL_AUX5_ARB 0x208C
-#define WGL_AUX6_ARB 0x208D
-#define WGL_AUX7_ARB 0x208E
-#define WGL_AUX8_ARB 0x208F
-#define WGL_AUX9_ARB 0x2090
-#endif
-
-#ifndef WGL_FLOAT_COMPONENTS_NV
-#define WGL_FLOAT_COMPONENTS_NV 0x20B0
-#endif
-
-#ifndef WGL_ARB_multisample
-#define WGL_SAMPLE_BUFFERS_ARB 0x2041
-#define WGL_SAMPLES_ARB 0x2042
-#endif
-
-#ifndef GL_SAMPLES_ARB
-#define GL_SAMPLES_ARB 0x80A9
-#endif
-
-QGLFormat pfiToQGLFormat(HDC hdc, int pfi);
-
-static void qt_format_to_attrib_list(bool has_render_texture, const QGLFormat &f, int attribs[])
-{
- int i = 0;
- attribs[i++] = WGL_SUPPORT_OPENGL_ARB;
- attribs[i++] = TRUE;
- attribs[i++] = WGL_DRAW_TO_PBUFFER_ARB;
- attribs[i++] = TRUE;
-
- if (has_render_texture) {
- attribs[i++] = WGL_BIND_TO_TEXTURE_RGBA_ARB;
- attribs[i++] = TRUE;
- }
-
- attribs[i++] = WGL_COLOR_BITS_ARB;
- attribs[i++] = 32;
- attribs[i++] = WGL_DOUBLE_BUFFER_ARB;
- attribs[i++] = FALSE;
-
- if (f.stereo()) {
- attribs[i++] = WGL_STEREO_ARB;
- attribs[i++] = TRUE;
- }
- if (f.depth()) {
- attribs[i++] = WGL_DEPTH_BITS_ARB;
- attribs[i++] = f.depthBufferSize() == -1 ? 24 : f.depthBufferSize();
- }
- if (f.redBufferSize() != -1) {
- attribs[i++] = WGL_RED_BITS_ARB;
- attribs[i++] = f.redBufferSize();
- }
- if (f.greenBufferSize() != -1) {
- attribs[i++] = WGL_GREEN_BITS_ARB;
- attribs[i++] = f.greenBufferSize();
- }
- if (f.blueBufferSize() != -1) {
- attribs[i++] = WGL_BLUE_BITS_ARB;
- attribs[i++] = f.blueBufferSize();
- }
- if (f.alpha()) {
- attribs[i++] = WGL_ALPHA_BITS_ARB;
- attribs[i++] = f.alphaBufferSize() == -1 ? 8 : f.alphaBufferSize();
- }
- if (f.accum()) {
- attribs[i++] = WGL_ACCUM_BITS_ARB;
- attribs[i++] = f.accumBufferSize() == -1 ? 16 : f.accumBufferSize();
- }
- if (f.stencil()) {
- attribs[i++] = WGL_STENCIL_BITS_ARB;
- attribs[i++] = f.stencilBufferSize() == -1 ? 8 : f.stencilBufferSize();
- }
- if ((f.redBufferSize() > 8 || f.greenBufferSize() > 8
- || f.blueBufferSize() > 8 || f.alphaBufferSize() > 8)
- && (QGLExtensions::glExtensions() & QGLExtensions::NVFloatBuffer))
- {
- attribs[i++] = WGL_FLOAT_COMPONENTS_NV;
- attribs[i++] = TRUE;
- }
- if (f.sampleBuffers()) {
- attribs[i++] = WGL_SAMPLE_BUFFERS_ARB;
- attribs[i++] = 1;
- attribs[i++] = WGL_SAMPLES_ARB;
- attribs[i++] = f.samples() == -1 ? 16 : f.samples();
- }
- attribs[i] = 0;
-}
-
-bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
-{
- QGLTemporaryContext tempContext;
-
- PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB =
- (PFNWGLCREATEPBUFFERARBPROC) wglGetProcAddress("wglCreatePbufferARB");
- PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB =
- (PFNWGLGETPBUFFERDCARBPROC) wglGetProcAddress("wglGetPbufferDCARB");
- PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB =
- (PFNWGLQUERYPBUFFERARBPROC) wglGetProcAddress("wglQueryPbufferARB");
- PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB =
- (PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB");
-
- if (!wglCreatePbufferARB) // assumes that if one can be resolved, all of them can
- return false;
-
- dc = wglGetCurrentDC();
- Q_ASSERT(dc);
- has_render_texture = false;
-
- // sample buffers doesn't work in conjunction with the render_texture extension
- if (!f.sampleBuffers()) {
- PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB =
- (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
-
- if (wglGetExtensionsStringARB) {
- QString extensions(QLatin1String(wglGetExtensionsStringARB(dc)));
- has_render_texture = extensions.contains(QLatin1String("WGL_ARB_render_texture"));
- }
- }
-
- int attribs[40];
- qt_format_to_attrib_list(has_render_texture, f, attribs);
-
- // Find pbuffer capable pixel format.
- unsigned int num_formats = 0;
- int pixel_format;
- wglChoosePixelFormatARB(dc, attribs, 0, 1, &pixel_format, &num_formats);
-
- // some GL implementations don't support pbuffers with accum
- // buffers, so try that before we give up
- if (num_formats == 0 && f.accum()) {
- QGLFormat tmp = f;
- tmp.setAccum(false);
- qt_format_to_attrib_list(has_render_texture, tmp, attribs);
- wglChoosePixelFormatARB(dc, attribs, 0, 1, &pixel_format, &num_formats);
- }
-
- if (num_formats == 0) {
- qWarning("QGLPixelBuffer: Unable to find a pixel format with pbuffer - giving up.");
- return false;
- }
- format = pfiToQGLFormat(dc, pixel_format);
-
- // NB! The below ONLY works if the width/height are powers of 2.
- // Set some pBuffer attributes so that we can use this pBuffer as
- // a 2D RGBA texture target.
- int pb_attribs[] = {WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
- WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, 0};
-
- pbuf = wglCreatePbufferARB(dc, pixel_format, size.width(), size.height(),
- has_render_texture ? pb_attribs : 0);
- if (!pbuf) {
- // try again without the render_texture extension
- pbuf = wglCreatePbufferARB(dc, pixel_format, size.width(), size.height(), 0);
- has_render_texture = false;
- if (!pbuf) {
- qWarning("QGLPixelBuffer: Unable to create pbuffer [w=%d, h=%d] - giving up.", size.width(), size.height());
- return false;
- }
- }
-
- dc = wglGetPbufferDCARB(pbuf);
- ctx = wglCreateContext(dc);
- if (!dc || !ctx) {
- qWarning("QGLPixelBuffer: Unable to create pbuffer context - giving up.");
- return false;
- }
-
- // Explicitly disable the render_texture extension if we have a
- // multi-sampled pbuffer context. This seems to be a problem only with
- // ATI cards if multi-sampling is forced globally in the driver.
- wglMakeCurrent(dc, ctx);
- GLint samples = 0;
- glGetIntegerv(GL_SAMPLES_ARB, &samples);
- if (has_render_texture && samples != 0)
- has_render_texture = false;
-
- HGLRC share_ctx = shareWidget ? shareWidget->d_func()->glcx->d_func()->rc : 0;
- if (share_ctx && !wglShareLists(share_ctx, ctx))
- qWarning("QGLPixelBuffer: Unable to share display lists - with share widget.");
-
- int width, height;
- wglQueryPbufferARB(pbuf, WGL_PBUFFER_WIDTH_ARB, &width);
- wglQueryPbufferARB(pbuf, WGL_PBUFFER_HEIGHT_ARB, &height);
- return true;
-}
-
-bool QGLPixelBufferPrivate::cleanup()
-{
- PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB =
- (PFNWGLRELEASEPBUFFERDCARBPROC) wglGetProcAddress("wglReleasePbufferDCARB");
- PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB =
- (PFNWGLDESTROYPBUFFERARBPROC) wglGetProcAddress("wglDestroyPbufferARB");
- if (!invalid && wglReleasePbufferDCARB && wglDestroyPbufferARB) {
- wglReleasePbufferDCARB(pbuf, dc);
- wglDestroyPbufferARB(pbuf);
- }
- return true;
-}
-
-bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
-{
- Q_D(QGLPixelBuffer);
- if (d->invalid || !d->has_render_texture)
- return false;
- PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB =
- (PFNWGLBINDTEXIMAGEARBPROC) wglGetProcAddress("wglBindTexImageARB");
- if (wglBindTexImageARB) {
- glBindTexture(GL_TEXTURE_2D, texture_id);
- return wglBindTexImageARB(d->pbuf, WGL_FRONT_LEFT_ARB);
- }
- return false;
-}
-
-void QGLPixelBuffer::releaseFromDynamicTexture()
-{
- Q_D(QGLPixelBuffer);
- if (d->invalid || !d->has_render_texture)
- return;
- PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB =
- (PFNWGLRELEASETEXIMAGEARBPROC) wglGetProcAddress("wglReleaseTexImageARB");
- if (wglReleaseTexImageARB)
- wglReleaseTexImageARB(d->pbuf, WGL_FRONT_LEFT_ARB);
-}
-
-bool QGLPixelBuffer::hasOpenGLPbuffers()
-{
- bool ret = false;
- QGLTemporaryContext *tmpContext = 0;
- if (!QGLContext::currentContext())
- tmpContext = new QGLTemporaryContext;
- PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB =
- (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress("wglGetExtensionsStringARB");
- if (wglGetExtensionsStringARB) {
- QString extensions(QLatin1String(wglGetExtensionsStringARB(wglGetCurrentDC())));
- if (extensions.contains(QLatin1String("WGL_ARB_pbuffer"))
- && extensions.contains(QLatin1String("WGL_ARB_pixel_format"))) {
- ret = true;
- }
- }
- if (tmpContext)
- delete tmpContext;
- return ret;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglpixelbuffer_x11.cpp b/src/opengl/qglpixelbuffer_x11.cpp
deleted file mode 100644
index fcd7b521bb..0000000000
--- a/src/opengl/qglpixelbuffer_x11.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <qlibrary.h>
-#include <qdebug.h>
-#include <private/qgl_p.h>
-#include <private/qt_x11_p.h>
-#include <private/qpaintengine_opengl_p.h>
-
-#include <qx11info_x11.h>
-#include <GL/glx.h>
-#include <qimage.h>
-
-#include "qglpixelbuffer.h"
-#include "qglpixelbuffer_p.h"
-
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
-#include <dlfcn.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-#ifndef GLX_VERSION_1_3
-#define GLX_RGBA_BIT 0x00000002
-#define GLX_PBUFFER_BIT 0x00000004
-#define GLX_DRAWABLE_TYPE 0x8010
-#define GLX_RENDER_TYPE 0x8011
-#define GLX_RGBA_TYPE 0x8014
-#define GLX_PBUFFER_HEIGHT 0x8040
-#define GLX_PBUFFER_WIDTH 0x8041
-#endif
-
-#ifndef GLX_ARB_multisample
-#define GLX_SAMPLE_BUFFERS_ARB 100000
-#define GLX_SAMPLES_ARB 100001
-#endif
-
-typedef GLXFBConfig* (*_glXChooseFBConfig) (Display *dpy, int screen, const int *attrib_list, int *nelements);
-typedef int (*_glXGetFBConfigAttrib) (Display *dpy, GLXFBConfig config, int attribute, int *value);
-typedef GLXPbuffer (*_glXCreatePbuffer) (Display *dpy, GLXFBConfig config, const int *attrib_list);
-typedef void (*_glXDestroyPbuffer) (Display *dpy, GLXPbuffer pbuf);
-typedef GLXContext (*_glXCreateNewContext) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
-typedef Bool (*_glXMakeContextCurrent) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
-
-static _glXChooseFBConfig qt_glXChooseFBConfig = 0;
-static _glXCreateNewContext qt_glXCreateNewContext = 0;
-static _glXCreatePbuffer qt_glXCreatePbuffer = 0;
-static _glXDestroyPbuffer qt_glXDestroyPbuffer = 0;
-static _glXGetFBConfigAttrib qt_glXGetFBConfigAttrib = 0;
-static _glXMakeContextCurrent qt_glXMakeContextCurrent = 0;
-
-#define glXChooseFBConfig qt_glXChooseFBConfig
-#define glXCreateNewContext qt_glXCreateNewContext
-#define glXCreatePbuffer qt_glXCreatePbuffer
-#define glXDestroyPbuffer qt_glXDestroyPbuffer
-#define glXGetFBConfigAttrib qt_glXGetFBConfigAttrib
-#define glXMakeContextCurrent qt_glXMakeContextCurrent
-
-extern void (*qglx_getProcAddress(const char* procName))(); // in qgl_x11.cpp
-
-static bool qt_resolve_pbuffer_extensions()
-{
- static int resolved = false;
- if (resolved && qt_glXMakeContextCurrent)
- return true;
- else if (resolved)
- return false;
-
- qt_glXChooseFBConfig = (_glXChooseFBConfig) qglx_getProcAddress("glXChooseFBConfig");
- qt_glXCreateNewContext = (_glXCreateNewContext) qglx_getProcAddress("glXCreateNewContext");
- qt_glXCreatePbuffer = (_glXCreatePbuffer) qglx_getProcAddress("glXCreatePbuffer");
- qt_glXDestroyPbuffer = (_glXDestroyPbuffer) qglx_getProcAddress("glXDestroyPbuffer");
- qt_glXGetFBConfigAttrib = (_glXGetFBConfigAttrib) qglx_getProcAddress("glXGetFBConfigAttrib");
- qt_glXMakeContextCurrent = (_glXMakeContextCurrent) qglx_getProcAddress("glXMakeContextCurrent");
-
- resolved = qt_glXMakeContextCurrent ? true : false;
- return resolved;
-}
-
-static void qt_format_to_attrib_list(const QGLFormat &f, int attribs[])
-{
- int i = 0;
- attribs[i++] = GLX_RENDER_TYPE;
- attribs[i++] = GLX_RGBA_BIT;
- attribs[i++] = GLX_DRAWABLE_TYPE;
- attribs[i++] = GLX_PBUFFER_BIT;
- attribs[i++] = GLX_RED_SIZE;
- attribs[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize();
- attribs[i++] = GLX_GREEN_SIZE;
- attribs[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize();
- attribs[i++] = GLX_BLUE_SIZE;
- attribs[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize();
- if (f.doubleBuffer()) {
- attribs[i++] = GLX_DOUBLEBUFFER;
- attribs[i++] = true;
- }
- if (f.depth()) {
- attribs[i++] = GLX_DEPTH_SIZE;
- attribs[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize();
- }
- if (f.stereo()) {
- attribs[i++] = GLX_STEREO;
- attribs[i++] = true;
- }
- if (f.stencil()) {
- attribs[i++] = GLX_STENCIL_SIZE;
- attribs[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize();
- }
- if (f.alpha()) {
- attribs[i++] = GLX_ALPHA_SIZE;
- attribs[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize();
- }
- if (f.accum()) {
- attribs[i++] = GLX_ACCUM_RED_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- attribs[i++] = GLX_ACCUM_GREEN_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- attribs[i++] = GLX_ACCUM_BLUE_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- if (f.alpha()) {
- attribs[i++] = GLX_ACCUM_ALPHA_SIZE;
- attribs[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize();
- }
- }
- if (f.sampleBuffers()) {
- attribs[i++] = GLX_SAMPLE_BUFFERS_ARB;
- attribs[i++] = 1;
- attribs[i++] = GLX_SAMPLES_ARB;
- attribs[i++] = f.samples() == -1 ? 4 : f.samples();
- }
-
- attribs[i] = XNone;
-}
-
-bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget)
-{
- if (!qt_resolve_pbuffer_extensions()) {
- qWarning("QGLPixelBuffer: pbuffers are not supported on this system.");
- return false;
- }
-
- int attribs[40];
- int num_configs = 0;
-
- qt_format_to_attrib_list(f, attribs);
-
- int screen = X11->defaultScreen;
- if (shareWidget)
- screen = shareWidget->x11Info().screen();
-
- GLXFBConfig *configs = glXChooseFBConfig(X11->display, screen, attribs, &num_configs);
- if (configs && num_configs) {
- int res;
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_LEVEL, &res);
- format.setPlane(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_DOUBLEBUFFER, &res);
- format.setDoubleBuffer(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_DEPTH_SIZE, &res);
- format.setDepth(res);
- if (format.depth())
- format.setDepthBufferSize(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_RGBA, &res);
- format.setRgba(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_RED_SIZE, &res);
- format.setRedBufferSize(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_GREEN_SIZE, &res);
- format.setGreenBufferSize(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_BLUE_SIZE, &res);
- format.setBlueBufferSize(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_ALPHA_SIZE, &res);
- format.setAlpha(res);
- if (format.alpha())
- format.setAlphaBufferSize(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_ACCUM_RED_SIZE, &res);
- format.setAccum(res);
- if (format.accum())
- format.setAccumBufferSize(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_STENCIL_SIZE, &res);
- format.setStencil(res);
- if (format.stencil())
- format.setStencilBufferSize(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_STEREO, &res);
- format.setStereo(res);
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_SAMPLE_BUFFERS_ARB, &res);
- format.setSampleBuffers(res);
- if (format.sampleBuffers()) {
- glXGetFBConfigAttrib(X11->display, configs[0], GLX_SAMPLES_ARB, &res);
- format.setSamples(res);
- }
-
- int pb_attribs[] = {GLX_PBUFFER_WIDTH, size.width(), GLX_PBUFFER_HEIGHT, size.height(), XNone};
- GLXContext shareContext = 0;
- if (shareWidget && shareWidget->d_func()->glcx)
- shareContext = (GLXContext) shareWidget->d_func()->glcx->d_func()->cx;
-
- pbuf = glXCreatePbuffer(QX11Info::display(), configs[0], pb_attribs);
- ctx = glXCreateNewContext(QX11Info::display(), configs[0], GLX_RGBA_TYPE, shareContext, true);
-
- XFree(configs);
- if (!pbuf || !ctx) {
- qWarning("QGLPixelBuffer: Unable to create a pbuffer/context - giving up.");
- return false;
- }
- return true;
- } else {
- qWarning("QGLPixelBuffer: Unable to find a context/format match - giving up.");
- return false;
- }
-}
-
-bool QGLPixelBufferPrivate::cleanup()
-{
- glXDestroyPbuffer(QX11Info::display(), pbuf);
- return true;
-}
-
-bool QGLPixelBuffer::bindToDynamicTexture(GLuint)
-{
- return false;
-}
-
-void QGLPixelBuffer::releaseFromDynamicTexture()
-{
-}
-
-bool QGLPixelBuffer::hasOpenGLPbuffers()
-{
- bool ret = qt_resolve_pbuffer_extensions();
-
- if (!ret)
- return false;
-
- int attribs[40];
- int num_configs = 0;
-
- qt_format_to_attrib_list(QGLFormat::defaultFormat(), attribs);
-
- GLXFBConfig *configs = glXChooseFBConfig(X11->display, X11->defaultScreen, attribs, &num_configs);
- GLXPbuffer pbuf = 0;
- GLXContext ctx = 0;
-
- if (configs && num_configs) {
- int pb_attribs[] = {GLX_PBUFFER_WIDTH, 128, GLX_PBUFFER_HEIGHT, 128, XNone};
- pbuf = glXCreatePbuffer(X11->display, configs[0], pb_attribs);
- ctx = glXCreateNewContext(X11->display, configs[0], GLX_RGBA_TYPE, 0, true);
- XFree(configs);
- glXDestroyContext(X11->display, ctx);
- glXDestroyPbuffer(X11->display, pbuf);
- }
- return pbuf && ctx;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp
deleted file mode 100644
index 7546d84064..0000000000
--- a/src/opengl/qglpixmapfilter.cpp
+++ /dev/null
@@ -1,621 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "private/qpixmapfilter_p.h"
-#include "private/qpixmapdata_gl_p.h"
-#include "private/qpaintengineex_opengl2_p.h"
-#include "private/qglengineshadermanager_p.h"
-#include "private/qpixmapdata_p.h"
-#include "private/qimagepixmapcleanuphooks_p.h"
-#include "qglpixmapfilter_p.h"
-#include "qgraphicssystem_gl_p.h"
-#include "qpaintengine_opengl_p.h"
-#include "qcache.h"
-
-#include "qglframebufferobject.h"
-#include "qglshaderprogram.h"
-#include "qgl_p.h"
-
-#include "private/qapplication_p.h"
-#include "private/qdrawhelper_p.h"
-#include "private/qmemrotate_p.h"
-#include "private/qmath_p.h"
-#include "qmath.h"
-
-QT_BEGIN_NAMESPACE
-
-// qpixmapfilter.cpp
-Q_GUI_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0);
-Q_GUI_EXPORT QImage qt_halfScaled(const QImage &source);
-
-void QGLPixmapFilterBase::bindTexture(const QPixmap &src) const
-{
- const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(src, GL_TEXTURE_2D, GL_RGBA, QGLContext::BindOptions(QGLContext::DefaultBindOption | QGLContext::MemoryManagedBindOption));
-}
-
-void QGLPixmapFilterBase::drawImpl(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF& source) const
-{
- processGL(painter, pos, src, source);
-}
-
-class QGLPixmapColorizeFilter: public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapColorizeFilter>
-{
-public:
- QGLPixmapColorizeFilter();
-
- void setUniforms(QGLShaderProgram *program);
-
-protected:
- bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &pixmap, const QRectF &srcRect) const;
-};
-
-class QGLPixmapConvolutionFilter: public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapConvolutionFilter>
-{
-public:
- QGLPixmapConvolutionFilter();
- ~QGLPixmapConvolutionFilter();
-
- void setUniforms(QGLShaderProgram *program);
-
-protected:
- bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;
-
-private:
- QByteArray generateConvolutionShader() const;
-
- mutable QSize m_srcSize;
- mutable int m_prevKernelSize;
-};
-
-class QGLPixmapBlurFilter : public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapBlurFilter>
-{
-public:
- QGLPixmapBlurFilter();
-
-protected:
- bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;
-};
-
-class QGLPixmapDropShadowFilter : public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapDropShadowFilter>
-{
-public:
- QGLPixmapDropShadowFilter();
-
- void setUniforms(QGLShaderProgram *program);
-
-protected:
- bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;
-};
-
-extern const QGLContext *qt_gl_share_context();
-
-QPixmapFilter *QGL2PaintEngineEx::pixmapFilter(int type, const QPixmapFilter *prototype)
-{
- Q_D(QGL2PaintEngineEx);
- switch (type) {
- case QPixmapFilter::ColorizeFilter:
- if (!d->colorizeFilter)
- d->colorizeFilter.reset(new QGLPixmapColorizeFilter);
- return d->colorizeFilter.data();
-
- case QPixmapFilter::BlurFilter: {
- if (!d->blurFilter)
- d->blurFilter.reset(new QGLPixmapBlurFilter());
- return d->blurFilter.data();
- }
-
- case QPixmapFilter::DropShadowFilter: {
- if (!d->dropShadowFilter)
- d->dropShadowFilter.reset(new QGLPixmapDropShadowFilter());
- return d->dropShadowFilter.data();
- }
-
- case QPixmapFilter::ConvolutionFilter:
- if (!d->convolutionFilter)
- d->convolutionFilter.reset(new QGLPixmapConvolutionFilter);
- return d->convolutionFilter.data();
-
- default: break;
- }
- return QPaintEngineEx::pixmapFilter(type, prototype);
-}
-
-static const char *qt_gl_colorize_filter =
- "uniform lowp vec4 colorizeColor;"
- "uniform lowp float colorizeStrength;"
- "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords)"
- "{"
- " lowp vec4 srcPixel = texture2D(src, srcCoords);"
- " lowp float gray = dot(srcPixel.rgb, vec3(0.212671, 0.715160, 0.072169));"
- " lowp vec3 colorized = 1.0-((1.0-gray)*(1.0-colorizeColor.rgb));"
- " return vec4(mix(srcPixel.rgb, colorized * srcPixel.a, colorizeStrength), srcPixel.a);"
- "}";
-
-QGLPixmapColorizeFilter::QGLPixmapColorizeFilter()
-{
- setSource(qt_gl_colorize_filter);
-}
-
-bool QGLPixmapColorizeFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const
-{
- QGLPixmapColorizeFilter *filter = const_cast<QGLPixmapColorizeFilter *>(this);
-
- filter->setOnPainter(painter);
- painter->drawPixmap(pos, src);
- filter->removeFromPainter(painter);
-
- return true;
-}
-
-void QGLPixmapColorizeFilter::setUniforms(QGLShaderProgram *program)
-{
- program->setUniformValue("colorizeColor", color());
- program->setUniformValue("colorizeStrength", float(strength()));
-}
-
-void QGLPixmapConvolutionFilter::setUniforms(QGLShaderProgram *program)
-{
- const qreal *kernel = convolutionKernel();
- int kernelWidth = columns();
- int kernelHeight = rows();
- int kernelSize = kernelWidth * kernelHeight;
-
- QVarLengthArray<GLfloat> matrix(kernelSize);
- QVarLengthArray<GLfloat> offset(kernelSize * 2);
-
- for(int i = 0; i < kernelSize; ++i)
- matrix[i] = kernel[i];
-
- for(int y = 0; y < kernelHeight; ++y) {
- for(int x = 0; x < kernelWidth; ++x) {
- offset[(y * kernelWidth + x) * 2] = x - (kernelWidth / 2);
- offset[(y * kernelWidth + x) * 2 + 1] = (kernelHeight / 2) - y;
- }
- }
-
- const qreal iw = 1.0 / m_srcSize.width();
- const qreal ih = 1.0 / m_srcSize.height();
- program->setUniformValue("inv_texture_size", iw, ih);
- program->setUniformValueArray("matrix", matrix.constData(), kernelSize, 1);
- program->setUniformValueArray("offset", offset.constData(), kernelSize, 2);
-}
-
-// generates convolution filter code for arbitrary sized kernel
-QByteArray QGLPixmapConvolutionFilter::generateConvolutionShader() const {
- QByteArray code;
- int kernelWidth = columns();
- int kernelHeight = rows();
- int kernelSize = kernelWidth * kernelHeight;
- code.append("uniform highp vec2 inv_texture_size;\n"
- "uniform mediump float matrix[");
- code.append(QByteArray::number(kernelSize));
- code.append("];\n"
- "uniform highp vec2 offset[");
- code.append(QByteArray::number(kernelSize));
- code.append("];\n");
- code.append("lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords) {\n");
-
- code.append(" int i = 0;\n"
- " lowp vec4 sum = vec4(0.0);\n"
- " for (i = 0; i < ");
- code.append(QByteArray::number(kernelSize));
- code.append("; i++) {\n"
- " sum += matrix[i] * texture2D(src,srcCoords+inv_texture_size*offset[i]);\n"
- " }\n"
- " return sum;\n"
- "}");
- return code;
-}
-
-QGLPixmapConvolutionFilter::QGLPixmapConvolutionFilter()
- : m_prevKernelSize(-1)
-{
-}
-
-QGLPixmapConvolutionFilter::~QGLPixmapConvolutionFilter()
-{
-}
-
-bool QGLPixmapConvolutionFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const
-{
- QGLPixmapConvolutionFilter *filter = const_cast<QGLPixmapConvolutionFilter *>(this);
-
- m_srcSize = src.size();
-
- int kernelSize = rows() * columns();
- if (m_prevKernelSize == -1 || m_prevKernelSize != kernelSize) {
- filter->setSource(generateConvolutionShader());
- m_prevKernelSize = kernelSize;
- }
-
- filter->setOnPainter(painter);
- painter->drawPixmap(pos, src, srcRect);
- filter->removeFromPainter(painter);
-
- return true;
-}
-
-QGLPixmapBlurFilter::QGLPixmapBlurFilter()
-{
-}
-
-class QGLBlurTextureInfo
-{
-public:
- QGLBlurTextureInfo(const QImage &image, GLuint tex, qreal r)
- : m_texture(tex)
- , m_radius(r)
- {
- m_paddedImage << image;
- }
-
- ~QGLBlurTextureInfo()
- {
- glDeleteTextures(1, &m_texture);
- }
-
- QImage paddedImage(int scaleLevel = 0) const;
- GLuint texture() const { return m_texture; }
- qreal radius() const { return m_radius; }
-
-private:
- mutable QList<QImage> m_paddedImage;
- GLuint m_texture;
- qreal m_radius;
-};
-
-QImage QGLBlurTextureInfo::paddedImage(int scaleLevel) const
-{
- for (int i = m_paddedImage.size() - 1; i <= scaleLevel; ++i)
- m_paddedImage << qt_halfScaled(m_paddedImage.at(i));
-
- return m_paddedImage.at(scaleLevel);
-}
-
-class QGLBlurTextureCache : public QObject
-{
-public:
- static QGLBlurTextureCache *cacheForContext(const QGLContext *context);
-
- QGLBlurTextureCache(const QGLContext *);
- ~QGLBlurTextureCache();
-
- QGLBlurTextureInfo *takeBlurTextureInfo(const QPixmap &pixmap);
- bool hasBlurTextureInfo(quint64 cacheKey) const;
- void insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTextureInfo *info);
- void clearBlurTextureInfo(quint64 cacheKey);
-
- void timerEvent(QTimerEvent *event);
-
-private:
- static void pixmapDestroyed(QPixmapData *pixmap);
-
- QCache<quint64, QGLBlurTextureInfo > cache;
-
- static QList<QGLBlurTextureCache *> blurTextureCaches;
-
- int timerId;
-};
-
-QList<QGLBlurTextureCache *> QGLBlurTextureCache::blurTextureCaches;
-Q_GLOBAL_STATIC(QGLContextGroupResource<QGLBlurTextureCache>, qt_blur_texture_caches)
-
-QGLBlurTextureCache::QGLBlurTextureCache(const QGLContext *)
- : timerId(0)
-{
- cache.setMaxCost(4 * 1024 * 1024);
- blurTextureCaches.append(this);
-}
-
-QGLBlurTextureCache::~QGLBlurTextureCache()
-{
- blurTextureCaches.removeAt(blurTextureCaches.indexOf(this));
-}
-
-void QGLBlurTextureCache::timerEvent(QTimerEvent *)
-{
- killTimer(timerId);
- timerId = 0;
-
- cache.clear();
-}
-
-QGLBlurTextureCache *QGLBlurTextureCache::cacheForContext(const QGLContext *context)
-{
- return qt_blur_texture_caches()->value(context);
-}
-
-QGLBlurTextureInfo *QGLBlurTextureCache::takeBlurTextureInfo(const QPixmap &pixmap)
-{
- return cache.take(pixmap.cacheKey());
-}
-
-void QGLBlurTextureCache::clearBlurTextureInfo(quint64 cacheKey)
-{
- cache.remove(cacheKey);
-}
-
-bool QGLBlurTextureCache::hasBlurTextureInfo(quint64 cacheKey) const
-{
- return cache.contains(cacheKey);
-}
-
-void QGLBlurTextureCache::insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTextureInfo *info)
-{
- static bool hookAdded = false;
- if (!hookAdded) {
- QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(pixmapDestroyed);
- QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(pixmapDestroyed);
- hookAdded = true;
- }
-
- QImagePixmapCleanupHooks::enableCleanupHooks(pixmap);
- cache.insert(pixmap.cacheKey(), info, pixmap.width() * pixmap.height());
-
- if (timerId)
- killTimer(timerId);
-
- timerId = startTimer(8000);
-}
-
-void QGLBlurTextureCache::pixmapDestroyed(QPixmapData *pmd)
-{
- foreach (QGLBlurTextureCache *cache, blurTextureCaches) {
- if (cache->hasBlurTextureInfo(pmd->cacheKey()))
- cache->clearBlurTextureInfo(pmd->cacheKey());
- }
-}
-
-static const int qAnimatedBlurLevelIncrement = 16;
-static const int qMaxBlurHalfScaleLevel = 1;
-
-static GLuint generateBlurTexture(const QSize &size, GLenum format = GL_RGBA)
-{
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0, format,
- GL_UNSIGNED_BYTE, 0);
- return texture;
-}
-
-static inline uint nextMultiple(uint x, uint multiplier)
-{
- uint mod = x % multiplier;
- if (mod == 0)
- return x;
- return x + multiplier - mod;
-}
-
-Q_GUI_EXPORT void qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride,
- quint32 *dest, int dstStride);
-
-bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const
-{
- if (radius() < 1) {
- painter->drawPixmap(pos, src);
- return true;
- }
-
- qreal actualRadius = radius();
-
- QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
-
- QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx);
- QGLBlurTextureInfo *info = 0;
- int padding = nextMultiple(qCeil(actualRadius), qAnimatedBlurLevelIncrement);
- QRect targetRect = src.rect().adjusted(-padding, -padding, padding, padding);
-
- // pad so that we'll be able to half-scale qMaxBlurHalfScaleLevel times
- targetRect.setWidth((targetRect.width() + (qMaxBlurHalfScaleLevel-1)) & ~(qMaxBlurHalfScaleLevel-1));
- targetRect.setHeight((targetRect.height() + (qMaxBlurHalfScaleLevel-1)) & ~(qMaxBlurHalfScaleLevel-1));
-
- QSize textureSize;
-
- info = blurTextureCache->takeBlurTextureInfo(src);
- if (!info || info->radius() < actualRadius) {
- QSize paddedSize = targetRect.size() / 2;
-
- QImage padded(paddedSize.height(), paddedSize.width(), QImage::Format_ARGB32_Premultiplied);
- padded.fill(0);
-
- if (info) {
- int oldPadding = qRound(info->radius());
-
- QPainter p(&padded);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- p.drawImage((padding - oldPadding) / 2, (padding - oldPadding) / 2, info->paddedImage());
- p.end();
- } else {
- // TODO: combine byteswapping and memrotating into one by declaring
- // custom GL_RGBA pixel type and qt_colorConvert template for it
- QImage prepadded = qt_halfScaled(src.toImage()).convertToFormat(QImage::Format_ARGB32_Premultiplied);
-
- // byte-swap and memrotates in one go
- qt_memrotate90_gl(reinterpret_cast<const quint32*>(prepadded.bits()),
- prepadded.width(), prepadded.height(), prepadded.bytesPerLine(),
- reinterpret_cast<quint32*>(padded.scanLine(padding / 2)) + padding / 2,
- padded.bytesPerLine());
- }
-
- delete info;
- info = new QGLBlurTextureInfo(padded, generateBlurTexture(paddedSize), padding);
-
- textureSize = paddedSize;
- } else {
- textureSize = QSize(info->paddedImage().height(), info->paddedImage().width());
- }
-
- actualRadius *= qreal(0.5);
- int level = 1;
- for (; level < qMaxBlurHalfScaleLevel; ++level) {
- if (actualRadius <= 16)
- break;
- actualRadius *= qreal(0.5);
- }
-
- const int s = (1 << level);
-
- int prepadding = qRound(info->radius());
- padding = qMin(prepadding, qCeil(actualRadius) << level);
- targetRect = src.rect().adjusted(-padding, -padding, padding, padding);
-
- targetRect.setWidth(targetRect.width() & ~(s-1));
- targetRect.setHeight(targetRect.height() & ~(s-1));
-
- int paddingDelta = (prepadding - padding) >> level;
-
- QRect subRect(paddingDelta, paddingDelta, targetRect.width() >> level, targetRect.height() >> level);
- QImage sourceImage = info->paddedImage(level-1);
-
- QImage subImage(subRect.height(), subRect.width(), QImage::Format_ARGB32_Premultiplied);
- qt_rectcopy((QRgb *)subImage.bits(), ((QRgb *)sourceImage.scanLine(paddingDelta)) + paddingDelta,
- 0, 0, subRect.height(), subRect.width(), subImage.bytesPerLine(), sourceImage.bytesPerLine());
-
- GLuint texture = info->texture();
-
- qt_blurImage(subImage, actualRadius, blurHints() & QGraphicsBlurEffect::QualityHint, 1);
-
- // subtract one pixel off the end to prevent the bilinear sampling from sampling uninitialized data
- QRect textureSubRect = subImage.rect().adjusted(0, 0, -1, -1);
- QRectF targetRectF = QRectF(targetRect).adjusted(0, 0, -targetRect.width() / qreal(textureSize.width()), -targetRect.height() / qreal(textureSize.height()));
-
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subImage.width(), subImage.height(), GL_RGBA,
- GL_UNSIGNED_BYTE, const_cast<const QImage &>(subImage).bits());
-
- QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
- painter->setRenderHint(QPainter::SmoothPixmapTransform);
-
- // texture is flipped on the y-axis
- targetRectF = QRectF(targetRectF.x(), targetRectF.bottom(), targetRectF.width(), -targetRectF.height());
- engine->drawTexture(targetRectF.translated(pos), texture, textureSize, textureSubRect);
-
- blurTextureCache->insertBlurTextureInfo(src, info);
-
- return true;
-}
-
-static const char *qt_gl_drop_shadow_filter =
- "uniform lowp vec4 shadowColor;"
- "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords)"
- "{"
- " return shadowColor * texture2D(src, srcCoords.yx).a;"
- "}";
-
-
-QGLPixmapDropShadowFilter::QGLPixmapDropShadowFilter()
-{
- setSource(qt_gl_drop_shadow_filter);
-}
-
-bool QGLPixmapDropShadowFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const
-{
- QGLPixmapDropShadowFilter *filter = const_cast<QGLPixmapDropShadowFilter *>(this);
-
- qreal r = blurRadius();
- QRectF targetRectUnaligned = QRectF(src.rect()).translated(pos + offset()).adjusted(-r, -r, r, r);
- QRect targetRect = targetRectUnaligned.toAlignedRect();
-
- // ensure even dimensions (going to divide by two)
- targetRect.setWidth((targetRect.width() + 1) & ~1);
- targetRect.setHeight((targetRect.height() + 1) & ~1);
-
- QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
- QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx);
-
- QGLBlurTextureInfo *info = blurTextureCache->takeBlurTextureInfo(src);
- if (!info || info->radius() != r) {
- QImage half = qt_halfScaled(src.toImage().alphaChannel());
-
- qreal rx = r + targetRect.left() - targetRectUnaligned.left();
- qreal ry = r + targetRect.top() - targetRectUnaligned.top();
-
- QImage image = QImage(targetRect.size() / 2, QImage::Format_Indexed8);
- image.setColorTable(half.colorTable());
- image.fill(0);
- int dx = qRound(rx * qreal(0.5));
- int dy = qRound(ry * qreal(0.5));
- qt_rectcopy(image.bits(), half.bits(), dx, dy,
- half.width(), half.height(),
- image.bytesPerLine(), half.bytesPerLine());
-
- qt_blurImage(image, r * qreal(0.5), false, 1);
-
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, image.width(), image.height(),
- 0, GL_ALPHA, GL_UNSIGNED_BYTE, image.bits());
-
- info = new QGLBlurTextureInfo(image, texture, r);
- }
-
- GLuint texture = info->texture();
-
- filter->setOnPainter(painter);
-
- QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
- painter->setRenderHint(QPainter::SmoothPixmapTransform);
-
- engine->drawTexture(targetRect, texture, info->paddedImage().size(), info->paddedImage().rect());
-
- filter->removeFromPainter(painter);
-
- // Now draw the actual pixmap over the top.
- painter->drawPixmap(pos, src, srcRect);
-
- blurTextureCache->insertBlurTextureInfo(src, info);
-
- return true;
-}
-
-void QGLPixmapDropShadowFilter::setUniforms(QGLShaderProgram *program)
-{
- QColor col = color();
- qreal alpha = col.alphaF();
- program->setUniformValue("shadowColor", col.redF() * alpha,
- col.greenF() * alpha,
- col.blueF() * alpha,
- alpha);
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglpixmapfilter_p.h b/src/opengl/qglpixmapfilter_p.h
deleted file mode 100644
index 1aa234a25b..0000000000
--- a/src/opengl/qglpixmapfilter_p.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGLPIXMAPFILTER_P_H
-#define QGLPIXMAPFILTER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qpixmapfilter_p.h>
-
-#include <QtOpenGL/qgl.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-class QGLPixelBuffer;
-
-QT_MODULE(OpenGL)
-
-class QGLPixmapFilterBase
-{
-public:
- virtual ~QGLPixmapFilterBase() {}
-protected:
- void bindTexture(const QPixmap &src) const;
- void drawImpl(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect = QRectF()) const;
-
- virtual bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const = 0;
-};
-
-template <typename Filter>
-class QGLPixmapFilter : public Filter, public QGLPixmapFilterBase
-{
-public:
- void draw(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect = QRectF()) const {
- const QRectF source = srcRect.isNull() ? QRectF(src.rect()) : srcRect;
- if (painter)
- drawImpl(painter, pos, src, source);
- }
-};
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QGLPIXMAPFILTER_P_H
diff --git a/src/opengl/qglscreen_qws.cpp b/src/opengl/qglscreen_qws.cpp
deleted file mode 100644
index 517813e628..0000000000
--- a/src/opengl/qglscreen_qws.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QGLScreen>
-#include <QGLContext>
-#include <QGLWidget>
-#include "private/qglwindowsurface_qws_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QGLScreenPrivate
-{
-public:
- QGLScreen::Options options;
- QGLScreenSurfaceFunctions *functions;
-};
-
-/*!
- \internal
- \preliminary
- \class QGLScreen
-
- \brief This class encapsulates an OpenGL screen driver.
-*/
-
-QGLScreen::QGLScreen(int displayId)
- : QScreen(displayId, GLClass), d_ptr(new QGLScreenPrivate)
-{
- d_ptr->options = NoOptions;
- d_ptr->functions = new QGLScreenSurfaceFunctions();
-}
-
-QGLScreen::~QGLScreen()
-{
- delete d_ptr->functions;
- delete d_ptr;
-}
-
-/*!
- \since 4.3
- \obsolete
-
- Initializes the \a context and sets up the QGLWindowSurface of the
- QWidget of \a context based on the parameters of \a context and
- based on its own requirements. The format() of \a context needs
- to be updated with the actual parameters of the OpenGLES drawable
- that was set up.
-
- \a shareContext is used in the same way as for QGLContext. It is
- the context with which \a context shares display lists and texture
- ids etc. The window surface must be set up so that this sharing
- works.
-
- Returns true in case of success and false if it is not possible to
- create the necessary OpenGLES drawable/context.
-
- Since 4.4.2, this function will be not be called if options()
- indicates that a native window or pixmap drawable can be created
- via the functions in the surfaceFunctions() object.
-
- This function is obsolete in Qt 4.5 and higher. Use surfaceFunctions()
- instead.
-
- \sa options(), surfaceFunctions()
-*/
-bool
-QGLScreen::chooseContext(QGLContext *context, const QGLContext *shareContext)
-{
- Q_UNUSED(context);
- Q_UNUSED(shareContext);
- return false;
-}
-
-/*!
- \enum QGLScreen::Option
- This enum defines options that can be set on QGLScreen instances.
-
- \value NoOptions There are no special options on the screen. This is the default.
- \value NativeWindows Native windows can be created with QGLScreenSurfaceFunctions::createNativeWindow().
- \value NativePixmaps Native pixmaps can be created with QGLScreenSurfaceFunctions::createNativePixmap().
- \value NativeImages Native images can be created with QGLScreenSurfaceFunctions::createNativeImage().
- \value Overlays The screen supports GL overlays.
-*/
-
-/*!
- \since 4.4.2
-
- Returns the options associated with this QGLScreen.
-
- \sa setOptions()
-*/
-QGLScreen::Options QGLScreen::options() const
-{
- return d_ptr->options;
-}
-
-/*!
- \since 4.4.2
-
- Sets the options associated with this QGLScreen to \a value.
-
- \sa options()
-*/
-void QGLScreen::setOptions(QGLScreen::Options value)
-{
- d_ptr->options = value;
-}
-
-/*!
- \since 4.4.2
-
- Returns the surface functions object for this QGLScreen.
-
- \sa setSurfaceFunctions()
-*/
-QGLScreenSurfaceFunctions *QGLScreen::surfaceFunctions() const
-{
- return d_ptr->functions;
-}
-
-/*!
- \since 4.4.2
-
- Sets the surface functions object for this QGLScreen to \a functions.
- The QGLScreen will take over ownership of \a functions and delete
- it when the QGLScreen is deleted.
-
- \sa setSurfaceFunctions()
-*/
-void QGLScreen::setSurfaceFunctions(QGLScreenSurfaceFunctions *functions)
-{
- if (functions && functions != d_ptr->functions) {
- delete d_ptr->functions;
- d_ptr->functions = functions;
- }
-}
-
-/*!
- \internal
- \preliminary
- \class QGLScreenSurfaceFunctions
- \brief The QGLScreenSurfaceFunctions class encapsulates the functions for creating native windows and pixmaps for OpenGL ES.
-*/
-
-/*!
- \since 4.4.2
-
- Creates a native OpenGLES drawable for the surface of \a widget and
- returns it in \a native. Returns true if the OpenGLES drawable could
- be created, or false if windows are not supported.
-
- This function will be called if the NativeWindows option is set on
- the screen.
-
- \sa createNativePixmap(), createNativeImage(), QGLScreen::options()
-*/
-bool QGLScreenSurfaceFunctions::createNativeWindow(QWidget *widget, EGLNativeWindowType *native)
-{
- Q_UNUSED(widget);
- Q_UNUSED(native);
- return false;
-}
-
-/*!
- \since 4.4.2
-
- Creates a native OpenGLES drawable for directly rendering into
- \a pixmap and returns it in \a native. Returns true if the OpenGLES
- drawable could be created, or false if direct rendering into pixmaps
- is not supported.
-
- This function will be called if the NativePixmaps option is set on
- the screen.
-
- \sa createNativeWindow(), createNativeImage(), QGLScreen::options()
-*/
-bool QGLScreenSurfaceFunctions::createNativePixmap(QPixmap *pixmap, EGLNativePixmapType *native)
-{
- Q_UNUSED(pixmap);
- Q_UNUSED(native);
- return false;
-}
-
-/*!
- \since 4.4.2
-
- Creates a native OpenGLES drawable for directly rendering into
- \a image and returns it in \a native. Returns true if the OpenGLES
- drawable could be created, or false if direct rendering into images
- is not supported.
-
- This function will be called if the NativeImages option is set on
- the screen.
-
- \sa createNativeWindow(), createNativePixmap(), QGLScreen::options()
-*/
-bool QGLScreenSurfaceFunctions::createNativeImage(QImage *image, EGLNativePixmapType *native)
-{
- Q_UNUSED(image);
- Q_UNUSED(native);
- return false;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglscreen_qws.h b/src/opengl/qglscreen_qws.h
deleted file mode 100644
index a033b6badb..0000000000
--- a/src/opengl/qglscreen_qws.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCREENEGL_P_H
-#define QSCREENEGL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QScreenEGL class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/QScreen>
-#include <QtOpenGL/qgl.h>
-#if defined(QT_OPENGL_ES_2)
-#include <EGL/egl.h>
-#else
-#include <GLES/egl.h>
-#endif
-#if !defined(EGL_VERSION_1_3) && !defined(QEGL_NATIVE_TYPES_DEFINED)
-#undef EGLNativeWindowType
-#undef EGLNativePixmapType
-#undef EGLNativeDisplayType
-typedef NativeWindowType EGLNativeWindowType;
-typedef NativePixmapType EGLNativePixmapType;
-typedef NativeDisplayType EGLNativeDisplayType;
-#define QEGL_NATIVE_TYPES_DEFINED 1
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(OpenGL)
-
-class QGLScreenPrivate;
-
-class Q_OPENGL_EXPORT QGLScreenSurfaceFunctions
-{
-public:
- virtual bool createNativeWindow(QWidget *widget, EGLNativeWindowType *native);
- virtual bool createNativePixmap(QPixmap *pixmap, EGLNativePixmapType *native);
- virtual bool createNativeImage(QImage *image, EGLNativePixmapType *native);
-};
-
-class Q_OPENGL_EXPORT QGLScreen : public QScreen
-{
- Q_DECLARE_PRIVATE(QGLScreen)
-public:
- QGLScreen(int displayId);
- virtual ~QGLScreen();
-
- enum Option
- {
- NoOptions = 0,
- NativeWindows = 1,
- NativePixmaps = 2,
- NativeImages = 4,
- Overlays = 8
- };
- Q_DECLARE_FLAGS(Options, Option)
-
- QGLScreen::Options options() const;
-
- virtual bool chooseContext(QGLContext *context, const QGLContext *shareContext);
- virtual bool hasOpenGL() = 0;
-
- QGLScreenSurfaceFunctions *surfaceFunctions() const;
-
-protected:
- void setOptions(QGLScreen::Options value);
- void setSurfaceFunctions(QGLScreenSurfaceFunctions *functions);
-
-private:
- QGLScreenPrivate *d_ptr;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QGLScreen::Options)
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QSCREENEGL_P_H
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index e9cae44662..0163d60f0c 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -50,8 +50,6 @@
QT_BEGIN_NAMESPACE
-#if !defined(QT_OPENGL_ES_1)
-
/*!
\class QGLShaderProgram
\brief The QGLShaderProgram class allows OpenGL shader programs to be linked and used.
@@ -191,15 +189,15 @@ class QGLShaderPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QGLShader)
public:
- QGLShaderPrivate(const QGLContext *context, QGLShader::ShaderType type)
- : shaderGuard(context)
+ QGLShaderPrivate(const QGLContext *, QGLShader::ShaderType type)
+ : shaderGuard(0)
, shaderType(type)
, compiled(false)
{
}
~QGLShaderPrivate();
- QGLSharedResourceGuard shaderGuard;
+ QGLSharedResourceGuardBase *shaderGuard;
QGLShader::ShaderType shaderType;
bool compiled;
QString log;
@@ -209,22 +207,28 @@ public:
void deleteShader();
};
-#define ctx shaderGuard.context()
+namespace {
+ void freeShaderFunc(QGLContext *ctx, GLuint id)
+ {
+ Q_UNUSED(ctx);
+ glDeleteShader(id);
+ }
+}
+
+#define ctx QGLContext::currentContext()
QGLShaderPrivate::~QGLShaderPrivate()
{
- if (shaderGuard.id()) {
- QGLShareContextScope scope(shaderGuard.context());
- glDeleteShader(shaderGuard.id());
- }
+ if (shaderGuard)
+ shaderGuard->free();
}
bool QGLShaderPrivate::create()
{
- const QGLContext *context = shaderGuard.context();
+ QGLContext *context = const_cast<QGLContext *>(QGLContext::currentContext());
if (!context)
return false;
- if (qt_resolve_glsl_extensions(const_cast<QGLContext *>(context))) {
+ if (qt_resolve_glsl_extensions(context)) {
GLuint shader;
if (shaderType == QGLShader::Vertex)
shader = glCreateShader(GL_VERTEX_SHADER);
@@ -236,7 +240,7 @@ bool QGLShaderPrivate::create()
qWarning() << "QGLShader: could not create shader";
return false;
}
- shaderGuard.setId(shader);
+ shaderGuard = createSharedResourceGuard(context, shader, freeShaderFunc);
return true;
} else {
return false;
@@ -245,7 +249,7 @@ bool QGLShaderPrivate::create()
bool QGLShaderPrivate::compile(QGLShader *q)
{
- GLuint shader = shaderGuard.id();
+ GLuint shader = shaderGuard ? shaderGuard->id() : 0;
if (!shader)
return false;
glCompileShader(shader);
@@ -288,15 +292,12 @@ bool QGLShaderPrivate::compile(QGLShader *q)
void QGLShaderPrivate::deleteShader()
{
- if (shaderGuard.id()) {
- glDeleteShader(shaderGuard.id());
- shaderGuard.setId(0);
+ if (shaderGuard) {
+ shaderGuard->free();
+ shaderGuard = 0;
}
}
-#undef ctx
-#define ctx d->shaderGuard.context()
-
/*!
Constructs a new QGLShader object of the specified \a type
and attaches it to \a parent. If shader programs are not supported,
@@ -389,7 +390,7 @@ static const char redefineHighp[] =
bool QGLShader::compileSourceCode(const char *source)
{
Q_D(QGLShader);
- if (d->shaderGuard.id()) {
+ if (d->shaderGuard && d->shaderGuard->id()) {
QVarLengthArray<const char *, 4> src;
QVarLengthArray<GLint, 4> srclen;
int headerLen = 0;
@@ -422,7 +423,7 @@ bool QGLShader::compileSourceCode(const char *source)
#endif
src.append(source + headerLen);
srclen.append(GLint(qstrlen(source + headerLen)));
- glShaderSource(d->shaderGuard.id(), src.size(), src.data(), srclen.data());
+ glShaderSource(d->shaderGuard->id(), src.size(), src.data(), srclen.data());
return d->compile(this);
} else {
return false;
@@ -482,7 +483,7 @@ bool QGLShader::compileSourceFile(const QString& fileName)
QByteArray QGLShader::sourceCode() const
{
Q_D(const QGLShader);
- GLuint shader = d->shaderGuard.id();
+ GLuint shader = d->shaderGuard ? d->shaderGuard->id() : 0;
if (!shader)
return QByteArray();
GLint size = 0;
@@ -527,22 +528,17 @@ QString QGLShader::log() const
GLuint QGLShader::shaderId() const
{
Q_D(const QGLShader);
- return d->shaderGuard.id();
+ return d->shaderGuard ? d->shaderGuard->id() : 0;
}
-
-
-
-
#undef ctx
-#define ctx programGuard.context()
class QGLShaderProgramPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QGLShaderProgram)
public:
- QGLShaderProgramPrivate(const QGLContext *context)
- : programGuard(context)
+ QGLShaderProgramPrivate(const QGLContext *)
+ : programGuard(0)
, linked(false)
, inited(false)
, removingShaders(false)
@@ -553,7 +549,7 @@ public:
}
~QGLShaderProgramPrivate();
- QGLSharedResourceGuard programGuard;
+ QGLSharedResourceGuardBase *programGuard;
bool linked;
bool inited;
bool removingShaders;
@@ -569,12 +565,19 @@ public:
bool hasShader(QGLShader::ShaderType type) const;
};
+namespace {
+ void freeProgramFunc(QGLContext *ctx, GLuint id)
+ {
+ Q_UNUSED(ctx);
+ glDeleteProgram(id);
+ }
+}
+
+
QGLShaderProgramPrivate::~QGLShaderProgramPrivate()
{
- if (programGuard.id()) {
- QGLShareContextScope scope(programGuard.context());
- glDeleteProgram(programGuard.id());
- }
+ if (programGuard)
+ programGuard->free();
}
bool QGLShaderProgramPrivate::hasShader(QGLShader::ShaderType type) const
@@ -586,8 +589,7 @@ bool QGLShaderProgramPrivate::hasShader(QGLShader::ShaderType type) const
return false;
}
-#undef ctx
-#define ctx d->programGuard.context()
+#define ctx QGLContext::currentContext()
/*!
Constructs a new shader program and attaches it to \a parent.
@@ -625,24 +627,21 @@ QGLShaderProgram::~QGLShaderProgram()
bool QGLShaderProgram::init()
{
Q_D(QGLShaderProgram);
- if (d->programGuard.id() || d->inited)
+ if ((d->programGuard && d->programGuard->id()) || d->inited)
return true;
d->inited = true;
- const QGLContext *context = d->programGuard.context();
- if (!context) {
- context = QGLContext::currentContext();
- d->programGuard.setContext(context);
- }
-
+ QGLContext *context = const_cast<QGLContext *>(QGLContext::currentContext());
if (!context)
return false;
- if (qt_resolve_glsl_extensions(const_cast<QGLContext *>(context))) {
+ if (qt_resolve_glsl_extensions(context)) {
GLuint program = glCreateProgram();
if (!program) {
qWarning() << "QGLShaderProgram: could not create shader program";
return false;
}
- d->programGuard.setId(program);
+ if (d->programGuard)
+ delete d->programGuard;
+ d->programGuard = createSharedResourceGuard(context, program, freeProgramFunc);
return true;
} else {
qWarning() << "QGLShaderProgram: shader programs are not supported";
@@ -669,15 +668,14 @@ bool QGLShaderProgram::addShader(QGLShader *shader)
return false;
if (d->shaders.contains(shader))
return true; // Already added to this shader program.
- if (d->programGuard.id() && shader) {
- if (!QGLContext::areSharing(shader->d_func()->shaderGuard.context(),
- d->programGuard.context())) {
+ if (d->programGuard && d->programGuard->id() && shader) {
+ if (!shader->d_func()->shaderGuard || !shader->d_func()->shaderGuard->id())
+ return false;
+ if (d->programGuard->group() != shader->d_func()->shaderGuard->group()) {
qWarning("QGLShaderProgram::addShader: Program and shader are not associated with same context.");
return false;
}
- if (!shader->d_func()->shaderGuard.id())
- return false;
- glAttachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id());
+ glAttachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
d->linked = false; // Program needs to be relinked.
d->shaders.append(shader);
connect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed()));
@@ -786,14 +784,17 @@ bool QGLShaderProgram::addShaderFromSourceFile
/*!
Removes \a shader from this shader program. The object is not deleted.
+ The shader program must be valid in the current QGLContext.
+
\sa addShader(), link(), removeAllShaders()
*/
void QGLShaderProgram::removeShader(QGLShader *shader)
{
Q_D(QGLShaderProgram);
- if (d->programGuard.id() && shader && shader->d_func()->shaderGuard.id()) {
- QGLShareContextScope scope(d->programGuard.context());
- glDetachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id());
+ if (d->programGuard && d->programGuard->id()
+ && shader && shader->d_func()->shaderGuard)
+ {
+ glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
}
d->linked = false; // Program needs to be relinked.
if (shader) {
@@ -828,8 +829,11 @@ void QGLShaderProgram::removeAllShaders()
Q_D(QGLShaderProgram);
d->removingShaders = true;
foreach (QGLShader *shader, d->shaders) {
- if (d->programGuard.id() && shader && shader->d_func()->shaderGuard.id())
- glDetachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id());
+ if (d->programGuard && d->programGuard->id()
+ && shader && shader->d_func()->shaderGuard)
+ {
+ glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
+ }
}
foreach (QGLShader *shader, d->anonShaders) {
// Delete shader objects that were created anonymously.
@@ -858,7 +862,7 @@ void QGLShaderProgram::removeAllShaders()
bool QGLShaderProgram::link()
{
Q_D(QGLShaderProgram);
- GLuint program = d->programGuard.id();
+ GLuint program = d->programGuard ? d->programGuard->id() : 0;
if (!program)
return false;
@@ -948,13 +952,13 @@ QString QGLShaderProgram::log() const
bool QGLShaderProgram::bind()
{
Q_D(QGLShaderProgram);
- GLuint program = d->programGuard.id();
+ GLuint program = d->programGuard ? d->programGuard->id() : 0;
if (!program)
return false;
if (!d->linked && !link())
return false;
#ifndef QT_NO_DEBUG
- if (!QGLContext::areSharing(d->programGuard.context(), QGLContext::currentContext())) {
+ if (d->programGuard->group() != QOpenGLContextGroup::currentContextGroup()) {
qWarning("QGLShaderProgram::bind: program is not valid in the current context.");
return false;
}
@@ -976,7 +980,7 @@ void QGLShaderProgram::release()
{
#ifndef QT_NO_DEBUG
Q_D(QGLShaderProgram);
- if (!QGLContext::areSharing(d->programGuard.context(), QGLContext::currentContext()))
+ if (d->programGuard->group() != QOpenGLContextGroup::currentContextGroup())
qWarning("QGLShaderProgram::release: program is not valid in the current context.");
#endif
#if defined(QT_OPENGL_ES_2)
@@ -987,9 +991,6 @@ void QGLShaderProgram::release()
#endif
}
-#undef ctx
-#define ctx d->programGuard.context()
-
/*!
Returns the OpenGL identifier associated with this shader program.
@@ -998,7 +999,7 @@ void QGLShaderProgram::release()
GLuint QGLShaderProgram::programId() const
{
Q_D(const QGLShaderProgram);
- GLuint id = d->programGuard.id();
+ GLuint id = d->programGuard ? d->programGuard->id() : 0;
if (id)
return id;
@@ -1007,7 +1008,7 @@ GLuint QGLShaderProgram::programId() const
// themselves, particularly those using program binaries.
if (!const_cast<QGLShaderProgram *>(this)->init())
return 0;
- return d->programGuard.id();
+ return d->programGuard ? d->programGuard->id() : 0;
}
/*!
@@ -1024,9 +1025,9 @@ GLuint QGLShaderProgram::programId() const
void QGLShaderProgram::bindAttributeLocation(const char *name, int location)
{
Q_D(QGLShaderProgram);
- if (!init())
+ if (!init() || !d->programGuard || !d->programGuard->id())
return;
- glBindAttribLocation(d->programGuard.id(), location, name);
+ glBindAttribLocation(d->programGuard->id(), location, name);
d->linked = false; // Program needs to be relinked.
}
@@ -1076,8 +1077,8 @@ void QGLShaderProgram::bindAttributeLocation(const QString& name, int location)
int QGLShaderProgram::attributeLocation(const char *name) const
{
Q_D(const QGLShaderProgram);
- if (d->linked) {
- return glGetAttribLocation(d->programGuard.id(), name);
+ if (d->linked && d->programGuard && d->programGuard->id()) {
+ return glGetAttribLocation(d->programGuard->id(), name);
} else {
qWarning() << "QGLShaderProgram::attributeLocation(" << name
<< "): shader program is not linked";
@@ -1754,8 +1755,8 @@ int QGLShaderProgram::uniformLocation(const char *name) const
{
Q_D(const QGLShaderProgram);
Q_UNUSED(d);
- if (d->linked) {
- return glGetUniformLocation(d->programGuard.id(), name);
+ if (d->linked && d->programGuard && d->programGuard->id()) {
+ return glGetUniformLocation(d->programGuard->id(), name);
} else {
qWarning() << "QGLShaderProgram::uniformLocation(" << name
<< "): shader program is not linked";
@@ -3269,86 +3270,4 @@ bool QGLShader::hasOpenGLShaders(ShaderType type, const QGLContext *context)
return true;
}
-
-
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
-/*! \internal */
-void QGLShaderProgram::setAttributeArray
- (int location, QMacCompatGLenum type, const void *values, int tupleSize, int stride)
-{
- setAttributeArray(location, GLenum(type), values, tupleSize, stride);
-}
-
-/*! \internal */
-void QGLShaderProgram::setAttributeArray
- (const char *name, QMacCompatGLenum type, const void *values, int tupleSize, int stride)
-{
- setAttributeArray(name, GLenum(type), values, tupleSize, stride);
-}
-
-/*! \internal */
-void QGLShaderProgram::setAttributeBuffer
- (int location, QMacCompatGLenum type, int offset, int tupleSize, int stride)
-{
- setAttributeBuffer(location, GLenum(type), offset, tupleSize, stride);
-}
-
-/*! \internal */
-void QGLShaderProgram::setAttributeBuffer
- (const char *name, QMacCompatGLenum type, int offset, int tupleSize, int stride)
-{
- setAttributeBuffer(name, GLenum(type), offset, tupleSize, stride);
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValue(int location, QMacCompatGLint value)
-{
- setUniformValue(location, GLint(value));
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValue(int location, QMacCompatGLuint value)
-{
- setUniformValue(location, GLuint(value));
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLint value)
-{
- setUniformValue(name, GLint(value));
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValue(const char *name, QMacCompatGLuint value)
-{
- setUniformValue(name, GLuint(value));
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLint *values, int count)
-{
- setUniformValueArray(location, (const GLint *)values, count);
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValueArray(int location, const QMacCompatGLuint *values, int count)
-{
- setUniformValueArray(location, (const GLuint *)values, count);
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLint *values, int count)
-{
- setUniformValueArray(name, (const GLint *)values, count);
-}
-
-/*! \internal */
-void QGLShaderProgram::setUniformValueArray(const char *name, const QMacCompatGLuint *values, int count)
-{
- setUniformValueArray(name, (const GLuint *)values, count);
-}
-#endif
-
-#endif // !defined(QT_OPENGL_ES_1)
-
QT_END_NAMESPACE
diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h
index 09b6184bcb..591aab27cd 100644
--- a/src/opengl/qglshaderprogram.h
+++ b/src/opengl/qglshaderprogram.h
@@ -54,8 +54,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(OpenGL)
-#if !defined(QT_OPENGL_ES_1)
-
class QGLShaderProgram;
class QGLShaderPrivate;
@@ -204,17 +202,6 @@ public:
void setAttributeBuffer
(const char *name, GLenum type, int offset, int tupleSize, int stride = 0);
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- void setAttributeArray
- (int location, QMacCompatGLenum type, const void *values, int tupleSize, int stride = 0);
- void setAttributeArray
- (const char *name, QMacCompatGLenum type, const void *values, int tupleSize, int stride = 0);
- void setAttributeBuffer
- (int location, QMacCompatGLenum type, int offset, int tupleSize, int stride = 0);
- void setAttributeBuffer
- (const char *name, QMacCompatGLenum type, int offset, int tupleSize, int stride = 0);
-#endif
-
void enableAttributeArray(int location);
void enableAttributeArray(const char *name);
void disableAttributeArray(int location);
@@ -224,17 +211,6 @@ public:
int uniformLocation(const QByteArray& name) const;
int uniformLocation(const QString& name) const;
-#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
- void setUniformValue(int location, QMacCompatGLint value);
- void setUniformValue(int location, QMacCompatGLuint value);
- void setUniformValue(const char *name, QMacCompatGLint value);
- void setUniformValue(const char *name, QMacCompatGLuint value);
- void setUniformValueArray(int location, const QMacCompatGLint *values, int count);
- void setUniformValueArray(int location, const QMacCompatGLuint *values, int count);
- void setUniformValueArray(const char *name, const QMacCompatGLint *values, int count);
- void setUniformValueArray(const char *name, const QMacCompatGLuint *values, int count);
-#endif
-
void setUniformValue(int location, GLfloat value);
void setUniformValue(int location, GLint value);
void setUniformValue(int location, GLuint value);
@@ -335,8 +311,6 @@ private:
bool init();
};
-#endif
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/opengl/qgltexturepool.cpp b/src/opengl/qgltexturepool.cpp
deleted file mode 100644
index d809328725..0000000000
--- a/src/opengl/qgltexturepool.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgltexturepool_p.h"
-#include "qpixmapdata_gl_p.h"
-
-QT_BEGIN_NAMESPACE
-
-Q_OPENGL_EXPORT extern QGLWidget* qt_gl_share_widget();
-
-static QGLTexturePool *qt_gl_texture_pool = 0;
-
-class QGLTexturePoolPrivate
-{
-public:
- QGLTexturePoolPrivate() : lruFirst(0), lruLast(0) {}
-
- QGLPixmapData *lruFirst;
- QGLPixmapData *lruLast;
-};
-
-QGLTexturePool::QGLTexturePool()
- : d_ptr(new QGLTexturePoolPrivate())
-{
-}
-
-QGLTexturePool::~QGLTexturePool()
-{
-}
-
-QGLTexturePool *QGLTexturePool::instance()
-{
- if (!qt_gl_texture_pool)
- qt_gl_texture_pool = new QGLTexturePool();
- return qt_gl_texture_pool;
-}
-
-GLuint QGLTexturePool::createTextureForPixmap(GLenum target,
- GLint level,
- GLint internalformat,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- QGLPixmapData *data)
-{
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(target, texture);
- do {
- glTexImage2D(target, level, internalformat, width, height, 0, format, type, 0);
- GLenum error = glGetError();
- if (error == GL_NO_ERROR) {
- if (data)
- moveToHeadOfLRU(data);
- return texture;
- } else if (error != GL_OUT_OF_MEMORY) {
- qWarning("QGLTexturePool: cannot create temporary texture because of invalid params");
- return 0;
- }
- } while (reclaimSpace(internalformat, width, height, format, type, data));
- qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d pixmap",
- width, height);
- return 0;
-}
-
-bool QGLTexturePool::createPermanentTexture(GLuint texture,
- GLenum target,
- GLint level,
- GLint internalformat,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const GLvoid *data)
-{
- glBindTexture(target, texture);
- do {
- glTexImage2D(target, level, internalformat, width, height, 0, format, type, data);
-
- GLenum error = glGetError();
- if (error == GL_NO_ERROR) {
- return true;
- } else if (error != GL_OUT_OF_MEMORY) {
- qWarning("QGLTexturePool: cannot create permanent texture because of invalid params");
- return false;
- }
- } while (reclaimSpace(internalformat, width, height, format, type, 0));
- qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d pixmap",
- width, height);
- return 0;
-}
-
-void QGLTexturePool::releaseTexture(QGLPixmapData *data, GLuint texture)
-{
- // Very simple strategy at the moment: just destroy the texture.
- if (data)
- removeFromLRU(data);
-
- QGLWidget *shareWidget = qt_gl_share_widget();
- if (shareWidget) {
- QGLShareContextScope ctx(shareWidget->context());
- glDeleteTextures(1, &texture);
- }
-}
-
-void QGLTexturePool::useTexture(QGLPixmapData *data)
-{
- moveToHeadOfLRU(data);
-}
-
-void QGLTexturePool::detachTexture(QGLPixmapData *data)
-{
- removeFromLRU(data);
-}
-
-bool QGLTexturePool::reclaimSpace(GLint internalformat,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- QGLPixmapData *data)
-{
- Q_UNUSED(internalformat); // For future use in picking the best texture to eject.
- Q_UNUSED(width);
- Q_UNUSED(height);
- Q_UNUSED(format);
- Q_UNUSED(type);
-
- bool succeeded = false;
- bool wasInLRU = false;
- if (data) {
- wasInLRU = data->inLRU;
- moveToHeadOfLRU(data);
- }
-
- QGLPixmapData *lrudata = pixmapLRU();
- if (lrudata && lrudata != data) {
- lrudata->reclaimTexture();
- succeeded = true;
- }
-
- if (data && !wasInLRU)
- removeFromLRU(data);
-
- return succeeded;
-}
-
-void QGLTexturePool::hibernate()
-{
- Q_D(QGLTexturePool);
- QGLPixmapData *pd = d->lruLast;
- while (pd) {
- QGLPixmapData *prevLRU = pd->prevLRU;
- pd->inTexturePool = false;
- pd->inLRU = false;
- pd->nextLRU = 0;
- pd->prevLRU = 0;
- pd->hibernate();
- pd = prevLRU;
- }
- d->lruFirst = 0;
- d->lruLast = 0;
-}
-
-void QGLTexturePool::moveToHeadOfLRU(QGLPixmapData *data)
-{
- Q_D(QGLTexturePool);
- if (data->inLRU) {
- if (!data->prevLRU)
- return; // Already at the head of the list.
- removeFromLRU(data);
- }
- data->inLRU = true;
- data->nextLRU = d->lruFirst;
- data->prevLRU = 0;
- if (d->lruFirst)
- d->lruFirst->prevLRU = data;
- else
- d->lruLast = data;
- d->lruFirst = data;
-}
-
-void QGLTexturePool::removeFromLRU(QGLPixmapData *data)
-{
- Q_D(QGLTexturePool);
- if (!data->inLRU)
- return;
- if (data->nextLRU)
- data->nextLRU->prevLRU = data->prevLRU;
- else
- d->lruLast = data->prevLRU;
- if (data->prevLRU)
- data->prevLRU->nextLRU = data->nextLRU;
- else
- d->lruFirst = data->nextLRU;
- data->inLRU = false;
-}
-
-QGLPixmapData *QGLTexturePool::pixmapLRU()
-{
- Q_D(QGLTexturePool);
- return d->lruLast;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qgltexturepool_p.h b/src/opengl/qgltexturepool_p.h
deleted file mode 100644
index 27b730cbb9..0000000000
--- a/src/opengl/qgltexturepool_p.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenVG module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGLTEXTUREPOOL_P_H
-#define QGLTEXTUREPOOL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qgl.h"
-#include <QtCore/qscopedpointer.h>
-
-QT_BEGIN_NAMESPACE
-
-class QGLPixmapData;
-class QGLTexturePoolPrivate;
-
-class QGLTexturePool
-{
-public:
- QGLTexturePool();
- virtual ~QGLTexturePool();
-
- static QGLTexturePool *instance();
-
- // Create a new texture with the specified parameters and associate
- // it with "data". The QGLPixmapData will be notified when the
- // texture needs to be reclaimed by the pool.
- //
- // This function will call reclaimSpace() when texture creation fails.
- GLuint createTextureForPixmap(GLenum target,
- GLint level,
- GLint internalformat,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- QGLPixmapData *data);
-
- // Create a permanent texture with the specified parameters.
- // If there is insufficient space for the texture,
- // then this function will call reclaimSpace() and try again.
- //
- // The caller is responsible for calling glDeleteTextures()
- // when it no longer needs the texture, as the texture is not
- // recorded in the texture pool.
- bool createPermanentTexture(GLuint texture,
- GLenum target,
- GLint level,
- GLint internalformat,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const GLvoid *data);
-
- // Release a texture that is no longer required.
- void releaseTexture(QGLPixmapData *data, GLuint texture);
-
- // Notify the pool that a QGLPixmapData object is using
- // an texture again. This allows the pool to move the texture
- // within a least-recently-used list of QGLPixmapData objects.
- void useTexture(QGLPixmapData *data);
-
- // Notify the pool that the texture associated with a
- // QGLPixmapData is being detached from the pool. The caller
- // will become responsible for calling glDeleteTextures().
- void detachTexture(QGLPixmapData *data);
-
- // Reclaim space for an image allocation with the specified parameters.
- // Returns true if space was reclaimed, or false if there is no
- // further space that can be reclaimed. The "data" parameter
- // indicates the pixmap that is trying to obtain space which should
- // not itself be reclaimed.
- bool reclaimSpace(GLint internalformat,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- QGLPixmapData *data);
-
- // Hibernate the image pool because the context is about to be
- // destroyed. All textures left in the pool should be released.
- void hibernate();
-
-protected:
- // Helper functions for managing the LRU list of QGLPixmapData objects.
- void moveToHeadOfLRU(QGLPixmapData *data);
- void removeFromLRU(QGLPixmapData *data);
- QGLPixmapData *pixmapLRU();
-
-private:
- QScopedPointer<QGLTexturePoolPrivate> d_ptr;
-
- Q_DECLARE_PRIVATE(QGLTexturePool)
- Q_DISABLE_COPY(QGLTexturePool)
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/opengl/qglwindowsurface_qws.cpp b/src/opengl/qglwindowsurface_qws.cpp
deleted file mode 100644
index b3ad45185e..0000000000
--- a/src/opengl/qglwindowsurface_qws.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtGui/QPaintDevice>
-#include <QtGui/QWidget>
-#include <QtOpenGL/QGLWidget>
-#include "private/qglwindowsurface_qws_p.h"
-#include "private/qpaintengine_opengl_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QWSGLWindowSurface
- \since 4.3
- \ingroup qws
- \preliminary
-
- \brief The QWSGLWindowSurface class provides the drawing area for top-level
- windows with Qt for Embedded Linux on EGL/OpenGL ES. It also provides the
- drawing area for \l{QGLWidget}s whether they are top-level windows or
- children of another QWidget.
-
- Note that this class is only available in Qt for Embedded Linux and only
- available if Qt is configured with OpenGL support.
-*/
-
-class QWSGLWindowSurfacePrivate
-{
-public:
- QWSGLWindowSurfacePrivate() :
- qglContext(0), ownsContext(false) {}
-
- QGLContext *qglContext;
- bool ownsContext;
-};
-
-/*!
- Constructs an empty QWSGLWindowSurface for the given top-level \a window.
- The window surface is later initialized from chooseContext() and resources for it
- is typically allocated in setGeometry().
-*/
-QWSGLWindowSurface::QWSGLWindowSurface(QWidget *window)
- : QWSWindowSurface(window),
- d_ptr(new QWSGLWindowSurfacePrivate)
-{
-}
-
-/*!
- Constructs an empty QWSGLWindowSurface.
-*/
-QWSGLWindowSurface::QWSGLWindowSurface()
- : d_ptr(new QWSGLWindowSurfacePrivate)
-{
-}
-
-/*!
- Destroys the QWSGLWindowSurface object and frees any
- allocated resources.
- */
-QWSGLWindowSurface::~QWSGLWindowSurface()
-{
- Q_D(QWSGLWindowSurface);
- if (d->ownsContext)
- delete d->qglContext;
- delete d;
-}
-
-/*!
- Returns the QGLContext of the window surface.
-*/
-QGLContext *QWSGLWindowSurface::context() const
-{
- Q_D(const QWSGLWindowSurface);
- if (!d->qglContext) {
- QWSGLWindowSurface *that = const_cast<QWSGLWindowSurface*>(this);
- that->setContext(new QGLContext(QGLFormat::defaultFormat()));
- that->d_func()->ownsContext = true;
- }
- return d->qglContext;
-}
-
-/*!
- Sets the QGLContext for this window surface to \a context.
-*/
-void QWSGLWindowSurface::setContext(QGLContext *context)
-{
- Q_D(QWSGLWindowSurface);
- if (d->ownsContext) {
- delete d->qglContext;
- d->ownsContext = false;
- }
- d->qglContext = context;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qglwindowsurface_qws_p.h b/src/opengl/qglwindowsurface_qws_p.h
deleted file mode 100644
index 07362b1b88..0000000000
--- a/src/opengl/qglwindowsurface_qws_p.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGLWINDOWSURFACE_QWS_P_H
-#define QGLWINDOWSURFACE_QWS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QWSGLWindowSurface class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-#include <QPaintDevice>
-#include "private/qwindowsurface_qws_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QPaintDevice;
-class QPoint;
-class QRegion;
-class QSize;
-class QWidget;
-class QGLContext;
-
-class QWSGLWindowSurfacePrivate;
-
-class Q_OPENGL_EXPORT QWSGLWindowSurface : public QWSWindowSurface
-{
- Q_DECLARE_PRIVATE(QWSGLWindowSurface)
-
-public:
- QWSGLWindowSurface(QWidget *widget);
- QWSGLWindowSurface();
- ~QWSGLWindowSurface();
-
- QGLContext *context() const;
- void setContext(QGLContext *context);
-
-private:
- QWSGLWindowSurfacePrivate *d_ptr;
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QGLWINDOWSURFACE_QWS_P_H
diff --git a/src/opengl/qgraphicsshadereffect.cpp b/src/opengl/qgraphicsshadereffect.cpp
index c7a058e9ef..c785fb29ad 100644
--- a/src/opengl/qgraphicsshadereffect.cpp
+++ b/src/opengl/qgraphicsshadereffect.cpp
@@ -40,14 +40,12 @@
****************************************************************************/
#include "qgraphicsshadereffect_p.h"
-#if !defined(QT_OPENGL_ES_1)
#include "qglshaderprogram.h"
#include "gl2paintengineex/qglcustomshaderstage_p.h"
#define QGL_HAVE_CUSTOM_SHADERS 1
-#endif
#include <QtGui/qpainter.h>
-#include <QtGui/qgraphicsitem.h>
-#include <QtGui/private/qgraphicseffect_p.h>
+#include <QtWidgets/qgraphicsitem.h>
+#include <private/qgraphicseffect_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/opengl/qgraphicsshadereffect_p.h b/src/opengl/qgraphicsshadereffect_p.h
index 12d716524b..7ae5f53d7e 100644
--- a/src/opengl/qgraphicsshadereffect_p.h
+++ b/src/opengl/qgraphicsshadereffect_p.h
@@ -53,7 +53,7 @@
// We mean it.
//
-#include <QtGui/qgraphicseffect.h>
+#include <QtWidgets/qgraphicseffect.h>
QT_BEGIN_HEADER
diff --git a/src/opengl/qgraphicssystem_gl.cpp b/src/opengl/qgraphicssystem_gl.cpp
deleted file mode 100644
index 01a2864ecc..0000000000
--- a/src/opengl/qgraphicssystem_gl.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgraphicssystem_gl_p.h"
-#include <QGraphicsView>
-
-#include "private/qpixmap_raster_p.h"
-#include "private/qpixmapdata_gl_p.h"
-#include "private/qwindowsurface_gl_p.h"
-#include "private/qgl_p.h"
-#include <private/qwindowsurface_raster_p.h>
-
-#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
-#include "private/qpixmapdata_x11gl_p.h"
-#include "private/qwindowsurface_x11gl_p.h"
-#endif
-
-#if defined(Q_OS_SYMBIAN)
-#include <QtGui/private/qapplication_p.h>
-#endif
-
-#ifdef QGL_USE_TEXTURE_POOL
-#include "private/qgltexturepool_p.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-extern QGLWidget *qt_gl_getShareWidget();
-
-QPixmapData *QGLGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
-{
- return new QGLPixmapData(type);
-}
-
-QWindowSurface *QGLGraphicsSystem::createWindowSurface(QWidget *widget) const
-{
-#ifdef Q_WS_WIN
- // On Windows the QGLWindowSurface class can't handle
- // drop shadows and native effects, e.g. fading a menu in/out using
- // top level window opacity.
- if (widget->windowType() == Qt::Popup)
- return new QRasterWindowSurface(widget);
-#endif
-
-#if defined(Q_WS_X11) && !defined(QT_NO_EGL)
- if (m_useX11GL && QX11GLPixmapData::hasX11GLPixmaps()) {
- // If the widget is a QGraphicsView which will be re-drawing the entire
- // scene each frame anyway, we should use QGLWindowSurface as this may
- // provide proper buffer flipping, which should be faster than QX11GL's
- // blitting approach:
- QGraphicsView* qgv = qobject_cast<QGraphicsView*>(widget);
- if (qgv && qgv->viewportUpdateMode() == QGraphicsView::FullViewportUpdate)
- return new QGLWindowSurface(widget);
- else
- return new QX11GLWindowSurface(widget);
- }
-#endif
-
-#if defined(Q_OS_SYMBIAN)
- if (!QApplicationPrivate::instance()->useTranslucentEGLSurfaces) {
- QWidgetPrivate *d = qt_widget_private(widget);
- if (!d->isOpaque && widget->testAttribute(Qt::WA_TranslucentBackground))
- return d->createDefaultWindowSurface_sys();
- }
-#endif
-
- return new QGLWindowSurface(widget);
-}
-#ifdef QGL_USE_TEXTURE_POOL
-void QGLGraphicsSystem::releaseCachedResources()
-{
- QGLTexturePool::instance()->hibernate();
-}
-#endif
-QT_END_NAMESPACE
-
diff --git a/src/opengl/qgraphicssystem_gl_p.h b/src/opengl/qgraphicssystem_gl_p.h
deleted file mode 100644
index 6e8e9a8966..0000000000
--- a/src/opengl/qgraphicssystem_gl_p.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSYSTEM_RASTER_P_H
-#define QGRAPHICSSYSTEM_RASTER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qgraphicssystem_p.h"
-
-#include <QMap>
-
-QT_BEGIN_NAMESPACE
-
-class Q_OPENGL_EXPORT QGLGraphicsSystem : public QGraphicsSystem
-{
-public:
- QGLGraphicsSystem(bool useX11GL);
-
- QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
- QWindowSurface *createWindowSurface(QWidget *widget) const;
-
-#ifdef QGL_USE_TEXTURE_POOL
- void releaseCachedResources();
-#endif
-private:
- bool m_useX11GL;
-};
-
-QT_END_NAMESPACE
-
-#endif
-
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
deleted file mode 100644
index 56a6af1cfe..0000000000
--- a/src/opengl/qpaintengine_opengl.cpp
+++ /dev/null
@@ -1,5635 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qdebug.h>
-#include <private/qfontengine_p.h>
-#include <qmath.h>
-#include <private/qmath_p.h>
-#include <private/qdrawhelper_p.h>
-#include <private/qpaintengine_p.h>
-#include "qapplication.h"
-#include "qbrush.h"
-#include "qgl.h"
-#include <private/qgl_p.h>
-#include <private/qglpaintdevice_p.h>
-#include <private/qpainter_p.h>
-#include "qmap.h"
-#include <private/qpaintengine_opengl_p.h>
-#include <private/qdatabuffer_p.h>
-#include "qpen.h"
-#include "qvarlengtharray.h"
-#include <private/qpainter_p.h>
-#include <private/qglpixelbuffer_p.h>
-#include <private/qbezier_p.h>
-#include <qglframebufferobject.h>
-#include <private/qstatictext_p.h>
-
-#include "private/qtessellator_p.h"
-
-#include "util/fragmentprograms_p.h"
-
-#ifdef Q_WS_QWS
-#include "private/qglwindowsurface_qws_p.h"
-#include "qwsmanager_qws.h"
-#include "private/qwsmanager_p.h"
-#endif
-
-#define QGL_FUNC_CONTEXT QGLContext *ctx = const_cast<QGLContext *>(device->context());
-
-#include <stdlib.h>
-#include "qpaintengine_opengl_p.h"
-
-QT_BEGIN_NAMESPACE
-
-Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert); //in qbrush.cpp
-#ifdef QT_MAC_USE_COCOA
-extern void *qt_current_nsopengl_context(); // qgl_mac.mm
-#endif
-
-#define QREAL_MAX 9e100
-#define QREAL_MIN -9e100
-
-extern int qt_next_power_of_two(int v);
-
-#define DISABLE_DEBUG_ONCE
-
-//#define DEBUG_DISPLAY_MASK_TEXTURE
-
-#ifdef DISABLE_DEBUG_ONCE
-#define DEBUG_OVERRIDE(state) ;
-#define DEBUG_ONCE_STR(str) ;
-#define DEBUG_ONCE if (0)
-#else
-static int DEBUG_OVERRIDE_FLAG = 0;
-static bool DEBUG_TEMP_FLAG;
-#define DEBUG_OVERRIDE(state) { state ? ++DEBUG_OVERRIDE_FLAG : --DEBUG_OVERRIDE_FLAG; }
-#define DEBUG_ONCE if ((DEBUG_TEMP_FLAG = DEBUG_OVERRIDE_FLAG) && 0) ; else for (static int DEBUG_ONCE_FLAG = false; !DEBUG_ONCE_FLAG || DEBUG_TEMP_FLAG; DEBUG_ONCE_FLAG = true, DEBUG_TEMP_FLAG = false)
-#define DEBUG_ONCE_STR(str) DEBUG_ONCE qDebug() << (str);
-#endif
-
-#ifdef Q_WS_X11
-static bool qt_nvidiaFboNeedsFinish = false;
-#endif
-
-static inline void qt_glColor4ubv(unsigned char *col)
-{
- glColor4f(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, col[3]/255.0f);
-}
-
-struct QT_PointF {
- qreal x;
- qreal y;
-};
-
-struct QGLTrapezoid
-{
- QGLTrapezoid()
- {}
-
- QGLTrapezoid(qreal top_, qreal bottom_, qreal topLeftX_, qreal topRightX_, qreal bottomLeftX_, qreal bottomRightX_)
- : top(top_),
- bottom(bottom_),
- topLeftX(topLeftX_),
- topRightX(topRightX_),
- bottomLeftX(bottomLeftX_),
- bottomRightX(bottomRightX_)
- {}
-
- const QGLTrapezoid translated(const QPointF &delta) const;
-
- qreal top;
- qreal bottom;
- qreal topLeftX;
- qreal topRightX;
- qreal bottomLeftX;
- qreal bottomRightX;
-};
-
-const QGLTrapezoid QGLTrapezoid::translated(const QPointF &delta) const
-{
- QGLTrapezoid trap(*this);
- trap.top += delta.y();
- trap.bottom += delta.y();
- trap.topLeftX += delta.x();
- trap.topRightX += delta.x();
- trap.bottomLeftX += delta.x();
- trap.bottomRightX += delta.x();
- return trap;
-}
-
-
-class QOpenGLImmediateModeTessellator;
-class QGLMaskGenerator;
-class QGLOffscreen;
-
-class QGLMaskTextureCache
-{
-public:
- void setOffscreenSize(const QSize &offscreenSize);
- void setDrawableSize(const QSize &drawableSize);
-
- struct CacheLocation {
- QRect rect;
- int channel;
-
- QRect screen_rect;
- };
-
- struct CacheInfo {
- inline CacheInfo(const QPainterPath &p, const QTransform &m, qreal w = -1) :
- path(p), matrix(m), stroke_width(w), age(0) {}
-
- QPainterPath path;
- QTransform matrix;
- qreal stroke_width;
-
- CacheLocation loc;
-
- int age;
- };
-
- struct QuadTreeNode {
- quint64 key;
-
- int largest_available_block;
- int largest_used_block;
- };
-
- CacheLocation getMask(QGLMaskGenerator &maskGenerator, QOpenGLPaintEnginePrivate *engine);
-
- typedef QMultiHash<quint64, CacheInfo> QGLTextureCacheHash;
-
- enum {block_size = 64};
-
- // throw out keys that are too old
- void maintainCache();
- void clearCache();
-
-private:
- quint64 hash(const QPainterPath &p, const QTransform &m, qreal w);
-
- void createMask(quint64 key, CacheInfo &info, QGLMaskGenerator &maskGenerator);
-
- QSize offscreenSize;
- QSize drawableSize;
-
- QGLTextureCacheHash cache;
-
- QVector<QuadTreeNode> occupied_quadtree[4];
-
- void quadtreeUpdate(int channel, int node, int current_block_size);
- void quadtreeAllocate(quint64 key, const QSize &size, QRect *rect, int *channel);
-
- bool quadtreeFindAvailableLocation(const QSize &size, QRect *rect, int *channel);
- void quadtreeFindExistingLocation(const QSize &size, QRect *rect, int *channel);
-
- void quadtreeInsert(int channel, quint64 key, const QRect &rect, int node = 0);
- void quadtreeClear(int channel, const QRect &rect, int node = 0);
-
- int quadtreeBlocksize(int node);
- QPoint quadtreeLocation(int node);
-
- QOpenGLPaintEnginePrivate *engine;
-};
-
-Q_GLOBAL_STATIC(QGLMaskTextureCache, qt_mask_texture_cache)
-
-class QGLOffscreen : public QObject
-{
- Q_OBJECT
-public:
- QGLOffscreen()
- : QObject(),
- offscreen(0),
- ctx(0),
- mask_dim(0),
- activated(false),
- bound(false)
- {
- connect(QGLSignalProxy::instance(),
- SIGNAL(aboutToDestroyContext(const QGLContext*)),
- SLOT(cleanupGLContextRefs(const QGLContext*)));
- }
-
- inline void setDevice(QPaintDevice *pdev);
-
- void begin();
- void end();
-
- inline void bind();
- inline void release();
-
- inline bool isBound() const;
-
- inline QSize drawableSize() const;
- inline QSize offscreenSize() const;
-
- inline GLuint offscreenTexture() const;
-
- QGLContext *context() const;
-
- static bool isSupported();
-
- inline void initialize();
-
- inline bool isValid() const;
-
-public Q_SLOTS:
- void cleanupGLContextRefs(const QGLContext *context) {
- if (context == ctx) {
- delete offscreen;
- ctx = 0;
- offscreen = 0;
- mask_dim = 0;
- }
- }
-
-private:
- QGLPaintDevice* device;
-
- QGLFramebufferObject *offscreen;
- QGLContext *ctx;
-
- // dimensions of mask texture (square)
- int mask_dim;
- QSize last_failed_size;
-
- bool drawable_fbo;
-
- bool activated;
- bool initialized;
-
- bool bound;
-};
-
-inline void QGLOffscreen::setDevice(QPaintDevice *pdev)
-{
- if (pdev->devType() == QInternal::OpenGL)
- device = static_cast<QGLPaintDevice*>(pdev);
- else
- device = QGLPaintDevice::getDevice(pdev);
-
- if (!device)
- return;
-
- drawable_fbo = (pdev->devType() == QInternal::FramebufferObject);
-}
-
-void QGLOffscreen::begin()
-{
-#ifndef QT_OPENGL_ES
- initialized = false;
-
- if (activated)
- initialize();
-#endif
-}
-
-void QGLOffscreen::initialize()
-{
-#ifndef QT_OPENGL_ES
- if (initialized)
- return;
-
- activated = true;
- initialized = true;
-
- int dim = qMax(2048, static_cast<int>(qt_next_power_of_two(qMax(device->size().width(), device->size().height()))));
-
- bool shared_context = QGLContext::areSharing(device->context(), ctx);
- bool would_fail = last_failed_size.isValid() &&
- (device->size().width() >= last_failed_size.width() ||
- device->size().height() >= last_failed_size.height());
- bool needs_refresh = dim > mask_dim || !shared_context;
-
- if (needs_refresh && !would_fail) {
- DEBUG_ONCE qDebug() << "QGLOffscreen::initialize(): creating offscreen of size" << dim;
- delete offscreen;
- offscreen = new QGLFramebufferObject(dim, dim, GLenum(GL_TEXTURE_2D));
- mask_dim = dim;
-
- if (!offscreen->isValid()) {
- qWarning("QGLOffscreen: Invalid offscreen fbo (size %dx%d)", mask_dim, mask_dim);
- delete offscreen;
- offscreen = 0;
- mask_dim = 0;
- last_failed_size = device->size();
- }
- }
-
- qt_mask_texture_cache()->setOffscreenSize(offscreenSize());
- qt_mask_texture_cache()->setDrawableSize(device->size());
- ctx = device->context();
-#endif
-}
-
-inline bool QGLOffscreen::isValid() const
-{
- return offscreen;
-}
-
-void QGLOffscreen::end()
-{
- if (bound)
- release();
-#ifdef DEBUG_DISPLAY_MASK_TEXTURE
- glReadBuffer(GL_BACK);
- glDrawBuffer(GL_BACK);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glColor4f(1, 1, 1, 1);
- glDisable(GL_DEPTH_TEST);
- glBlendFunc(GL_ONE, GL_ZERO);
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, offscreen->texture());
-
- glBegin(GL_QUADS);
- glTexCoord2f(0.0, 1.0); glVertex2f(0.0, 0.0);
- glTexCoord2f(1.0, 1.0); glVertex2f(drawable.size().width(), 0.0);
- glTexCoord2f(1.0, 0.0); glVertex2f(drawable.size().width(), drawable.size().height());
- glTexCoord2f(0.0, 0.0); glVertex2f(0.0, drawable.size().height());
- glEnd();
-
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisable(GL_TEXTURE_2D);
-#endif
-}
-
-inline void QGLOffscreen::bind()
-{
-#ifndef QT_OPENGL_ES
- Q_ASSERT(initialized);
-
- if (!offscreen || bound)
- return;
-
- DEBUG_ONCE qDebug() << "QGLOffscreen: binding offscreen";
- offscreen->bind();
-
- bound = true;
-
- glViewport(0, 0, offscreenSize().width(), offscreenSize().height());
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, offscreenSize().width(), offscreenSize().height(), 0, -999999, 999999);
- glMatrixMode(GL_MODELVIEW);
-#endif
-}
-
-inline void QGLOffscreen::release()
-{
-#ifndef QT_OPENGL_ES
- if (!offscreen || !bound)
- return;
-
-#ifdef Q_WS_X11
- // workaround for bug in nvidia driver versions 9x.xx
- if (qt_nvidiaFboNeedsFinish)
- glFinish();
-#endif
-
- DEBUG_ONCE_STR("QGLOffscreen: releasing offscreen");
-
- if (drawable_fbo)
- device->ensureActiveTarget(); //###
- else
- offscreen->release();
-
- QSize sz(device->size());
- glViewport(0, 0, sz.width(), sz.height());
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-#ifndef QT_OPENGL_ES
- glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
-#else
- glOrthof(0, sz.width(), sz.height(), 0, -999999, 999999);
-#endif
- glMatrixMode(GL_MODELVIEW);
-
- bound = false;
-#endif
-}
-
-inline bool QGLOffscreen::isBound() const
-{
- return bound;
-}
-
-inline QSize QGLOffscreen::drawableSize() const
-{
- return device->size();
-}
-
-inline QSize QGLOffscreen::offscreenSize() const
-{
- return QSize(mask_dim, mask_dim);
-}
-
-inline GLuint QGLOffscreen::offscreenTexture() const
-{
- return offscreen ? offscreen->texture() : 0;
-}
-
-inline QGLContext *QGLOffscreen::context() const
-{
- return ctx;
-}
-
-bool QGLOffscreen::isSupported()
-{
- return (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject); // for fbo
-}
-
-struct QDrawQueueItem
-{
- QDrawQueueItem(qreal _opacity,
- QBrush _brush,
- const QPointF &_brush_origion,
- QPainter::CompositionMode _composition_mode,
- const QTransform &_matrix,
- QGLMaskTextureCache::CacheLocation _location)
- : opacity(_opacity),
- brush(_brush),
- brush_origin(_brush_origion),
- composition_mode(_composition_mode),
- matrix(_matrix),
- location(_location) {}
- qreal opacity;
- QBrush brush;
- QPointF brush_origin;
- QPainter::CompositionMode composition_mode;
-
- QTransform matrix;
- QGLMaskTextureCache::CacheLocation location;
-};
-
-////////// GL program cache: start
-
-struct GLProgram {
- int brush; // brush index or mask index
- int mode; // composition mode index
- bool mask;
- GLuint program;
-};
-
-typedef QMultiHash<const QGLContext *, GLProgram> QGLProgramHash;
-
-class QGLProgramCache : public QObject
-{
- Q_OBJECT
-public:
- QGLProgramCache() {
- // we have to know when a context is deleted so we can free
- // any program handles it holds
- connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext*)),
- SLOT(cleanupPrograms(const QGLContext*)));
-
- }
- ~QGLProgramCache() {
- // at this point the cache should contain 0 elements
- // Q_ASSERT(program.size() == 0);
- }
-
- GLuint getProgram(const QGLContext *ctx, int brush, int mode, bool mask_mode)
- {
- // 1. see if we have an entry for the ctx context
- QList<GLProgram> progs = programs.values(ctx);
- for (int i=0; i<progs.size(); ++i) {
- const GLProgram &prg = progs.at(i);
- if (mask_mode) {
- if (prg.mask && prg.brush == brush)
- return prg.program;
- } else {
- if (!prg.mask && prg.brush == brush && prg.mode == mode)
- return prg.program;
- }
- }
-
- // 2. try to find a match in a shared context, and update the
- // hash with the entry found
- QList<const QGLContext *> contexts = programs.uniqueKeys();
- for (int i=0; i<contexts.size(); ++i) {
- const QGLContext *cx = contexts.at(i);
- if (cx != ctx && QGLContext::areSharing(cx, ctx)) {
- QList<GLProgram> progs = programs.values(cx);
- for (int k=0; k<progs.size(); ++k) {
- const GLProgram &prg = progs.at(k);
- if (mask_mode) {
- if (prg.mask && prg.brush == brush) {
- programs.insert(ctx, prg);
- return prg.program;
- }
- } else {
- if (!prg.mask && prg.brush == brush && prg.mode == mode) {
- programs.insert(ctx, prg);
- return prg.program;
- }
- }
- }
- }
- }
-
- // 3. compile a new program and place it into the cache
- // NB! assumes ctx is the current GL context
- GLProgram prg;
- prg.brush = brush;
- prg.mode = mode;
- prg.mask = mask_mode;
- glGenProgramsARB(1, &prg.program);
- glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prg.program);
- const char *src = mask_mode
- ? mask_fragment_program_sources[brush]
- : painter_fragment_program_sources[brush][mode];
- // necessary for .NET 2002, apparently
- const GLbyte *gl_src = reinterpret_cast<const GLbyte *>(src);
-
- while (glGetError() != GL_NO_ERROR) {} // reset error state
- glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
- int(strlen(src)), gl_src);
- if (glGetError() != GL_NO_ERROR) {
-// qDebug() << "QGLProgramCache: Unable to compile fragment program.";
- glDeleteProgramsARB(1, &prg.program);
- return 0;
- }
-
-// qDebug() << "QGLProgramCache: Creating GL program:" << prg.program << hex << ctx;
- programs.insert(ctx, prg);
- return prg.program;
- }
-
-public Q_SLOTS:
- void cleanupPrograms(const QGLContext *context)
- {
- QGLProgramHash::iterator it = programs.begin();
- while (it != programs.end()) {
- if (it.key() == context) {
- if (!context->isSharing()) {
- // the ctx variable below is needed for the glDeleteProgramARB call
- // since it is resolved from our extension system
- // NB! assumes context is the current GL context
- const QGLContext *ctx = context;
- // qDebug() << "QGLProgramHash: Deleting GL program:" << it.value().program << hex << it.key();
- glDeleteProgramsARB(1, &it.value().program);
- }
- it = programs.erase(it);
- } else {
- ++it;
- }
- }
- }
-
-private:
- QGLProgramHash programs;
-};
-
-Q_GLOBAL_STATIC(QGLProgramCache, qt_gl_program_cache)
-
-////////// GL program cache: end
-
-class QOpenGLPaintEnginePrivate;
-class QGLPrivateCleanup : public QObject
-{
- Q_OBJECT
-public:
- QGLPrivateCleanup(QOpenGLPaintEnginePrivate *priv)
- : p(priv)
- {
- connect(QGLSignalProxy::instance(),
- SIGNAL(aboutToDestroyContext(const QGLContext*)),
- SLOT(cleanupGLContextRefs(const QGLContext*)));
- }
-
-public Q_SLOTS:
- void cleanupGLContextRefs(const QGLContext *context);
-
-private:
- QOpenGLPaintEnginePrivate *p;
-};
-
-class QOpenGLPaintEnginePrivate : public QPaintEngineExPrivate
-{
- Q_DECLARE_PUBLIC(QOpenGLPaintEngine)
-public:
- QOpenGLPaintEnginePrivate()
- : opacity(1)
- , composition_mode(QPainter::CompositionMode_SourceOver)
- , has_fast_pen(false)
- , use_stencil_method(false)
- , dirty_drawable_texture(false)
- , has_stencil_face_ext(false)
- , use_fragment_programs(false)
- , high_quality_antialiasing(false)
- , use_smooth_pixmap_transform(false)
- , use_emulation(false)
- , txop(QTransform::TxNone)
- , inverseScale(1)
- , moveToCount(0)
- , last_created_state(0)
- , shader_ctx(0)
- , grad_palette(0)
- , tess_points(0)
- , drawable_texture(0)
- , ref_cleaner(this)
- {}
-
- inline void setGLPen(const QColor &c) {
- uint alpha = qRound(c.alpha() * opacity);
- pen_color[0] = qt_div_255(c.red() * alpha);
- pen_color[1] = qt_div_255(c.green() * alpha);
- pen_color[2] = qt_div_255(c.blue() * alpha);
- pen_color[3] = alpha;
- }
-
- inline void setGLBrush(const QColor &c) {
- uint alpha = qRound(c.alpha() * opacity);
- brush_color[0] = qt_div_255(c.red() * alpha);
- brush_color[1] = qt_div_255(c.green() * alpha);
- brush_color[2] = qt_div_255(c.blue() * alpha);
- brush_color[3] = alpha;
- }
-
- inline void setGradientOps(const QBrush &brush, const QRectF &bounds);
- void createGradientPaletteTexture(const QGradient& g);
-
- void updateGradient(const QBrush &brush, const QRectF &bounds);
-
- inline void lineToStencil(qreal x, qreal y);
- inline void curveToStencil(const QPointF &cp1, const QPointF &cp2, const QPointF &ep);
- void pathToVertexArrays(const QPainterPath &path);
- void fillVertexArray(Qt::FillRule fillRule);
- void drawVertexArrays();
- void fillPath(const QPainterPath &path);
- void fillPolygon_dev(const QPointF *polygonPoints, int pointCount,
- Qt::FillRule fill);
-
- void drawFastRect(const QRectF &rect);
- void strokePath(const QPainterPath &path, bool use_cache);
- void strokePathFastPen(const QPainterPath &path, bool needsResolving);
- void strokeLines(const QPainterPath &path);
-
- void updateDepthClip();
- void systemStateChanged();
-
- void cleanupGLContextRefs(const QGLContext *context) {
- if (context == shader_ctx)
- shader_ctx = 0;
- }
-
- inline void updateFastPen() {
- qreal pen_width = cpen.widthF();
- has_fast_pen =
- ((pen_width == 0 || (pen_width <= 1 && matrix.type() <= QTransform::TxTranslate))
- || cpen.isCosmetic())
- && cpen.style() == Qt::SolidLine
- && cpen.isSolid();
-
- }
-
- void disableClipping();
- void enableClipping();
- void ensureDrawableTexture();
-
- QPen cpen;
- QBrush cbrush;
- Qt::BrushStyle brush_style;
- QPointF brush_origin;
- Qt::BrushStyle pen_brush_style;
- qreal opacity;
- QPainter::CompositionMode composition_mode;
-
- Qt::BrushStyle current_style;
-
- uint has_pen : 1;
- uint has_brush : 1;
- uint has_fast_pen : 1;
- uint use_stencil_method : 1;
- uint dirty_drawable_texture : 1;
- uint has_stencil_face_ext : 1;
- uint use_fragment_programs : 1;
- uint high_quality_antialiasing : 1;
- uint has_antialiasing : 1;
- uint has_fast_composition_mode : 1;
- uint use_smooth_pixmap_transform : 1;
- uint use_system_clip : 1;
- uint use_emulation : 1;
-
- QRegion dirty_stencil;
-
- void updateUseEmulation();
-
- QTransform matrix;
- GLubyte pen_color[4];
- GLubyte brush_color[4];
- QTransform::TransformationType txop;
- QGLPaintDevice* device;
- QGLOffscreen offscreen;
-
- qreal inverseScale;
-
- int moveToCount;
- QPointF path_start;
-
- bool isFastRect(const QRectF &r);
-
- void drawImageAsPath(const QRectF &r, const QImage &img, const QRectF &sr);
- void drawTiledImageAsPath(const QRectF &r, const QImage &img, qreal sx, qreal sy, const QPointF &offset);
-
- void drawOffscreenPath(const QPainterPath &path);
-
- void composite(const QRectF &rect, const QPoint &maskOffset = QPoint());
- void composite(GLuint primitive, const GLfloat *vertexArray, int vertexCount, const QPoint &maskOffset = QPoint());
-
- bool createFragmentPrograms();
- void deleteFragmentPrograms();
- void updateFragmentProgramData(int locations[]);
-
- void cacheItemErased(int channel, const QRect &rect);
-
- void addItem(const QGLMaskTextureCache::CacheLocation &location);
- void drawItem(const QDrawQueueItem &item);
- void flushDrawQueue();
-
- void copyDrawable(const QRectF &rect);
-
- void updateGLMatrix() const;
-
- mutable QPainterState *last_created_state;
-
- QGLContext *shader_ctx;
- GLuint grad_palette;
-
- GLuint painter_fragment_programs[num_fragment_brushes][num_fragment_composition_modes];
- GLuint mask_fragment_programs[num_fragment_masks];
-
- float inv_matrix_data[3][4];
- float fmp_data[4];
- float fmp2_m_radius2_data[4];
- float angle_data[4];
- float linear_data[4];
-
- float porterduff_ab_data[4];
- float porterduff_xyz_data[4];
-
- float mask_offset_data[4];
- float mask_channel_data[4];
-
- FragmentBrushType fragment_brush;
- FragmentCompositionModeType fragment_composition_mode;
-
- void setPorterDuffData(float a, float b, float x, float y, float z);
- void setInvMatrixData(const QTransform &inv_matrix);
-
- qreal max_x;
- qreal max_y;
- qreal min_x;
- qreal min_y;
-
- QDataBuffer<QPointF> tess_points;
- QVector<int> tess_points_stops;
-
- GLdouble projection_matrix[4][4];
-
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
- GLfloat mv_matrix[4][4];
-#else
- GLdouble mv_matrix[4][4];
-#endif
-
- QList<QDrawQueueItem> drawQueue;
-
- GLuint drawable_texture;
- QSize drawable_texture_size;
-
- int max_texture_size;
-
- QGLPrivateCleanup ref_cleaner;
- friend class QGLMaskTextureCache;
-};
-
-class QOpenGLCoordinateOffset
-{
-public:
- QOpenGLCoordinateOffset(QOpenGLPaintEnginePrivate *d);
- ~QOpenGLCoordinateOffset();
-
- static void enableOffset(QOpenGLPaintEnginePrivate *d);
- static void disableOffset(QOpenGLPaintEnginePrivate *d);
-
-private:
- QOpenGLPaintEnginePrivate *d;
-};
-
-QOpenGLCoordinateOffset::QOpenGLCoordinateOffset(QOpenGLPaintEnginePrivate *d_)
- : d(d_)
-{
- enableOffset(d);
-}
-
-void QOpenGLCoordinateOffset::enableOffset(QOpenGLPaintEnginePrivate *d)
-{
- if (!d->has_antialiasing) {
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- d->mv_matrix[3][0] += 0.5;
- d->mv_matrix[3][1] += 0.5;
- d->updateGLMatrix();
- }
-}
-
-QOpenGLCoordinateOffset::~QOpenGLCoordinateOffset()
-{
- disableOffset(d);
-}
-
-void QOpenGLCoordinateOffset::disableOffset(QOpenGLPaintEnginePrivate *d)
-{
- if (!d->has_antialiasing) {
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- d->mv_matrix[3][0] -= 0.5;
- d->mv_matrix[3][1] -= 0.5;
- }
-}
-
-void QGLPrivateCleanup::cleanupGLContextRefs(const QGLContext *context)
-{
- p->cleanupGLContextRefs(context);
-}
-
-
-static inline void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform)
-{
- if (smoothPixmapTransform) {
- glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- } else {
- glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
- glTexParameterf(target, GL_TEXTURE_WRAP_S, wrapMode);
- glTexParameterf(target, GL_TEXTURE_WRAP_T, wrapMode);
-}
-
-static inline QPainterPath strokeForPath(const QPainterPath &path, const QPen &cpen) {
- QPainterPathStroker stroker;
- if (cpen.style() == Qt::CustomDashLine)
- stroker.setDashPattern(cpen.dashPattern());
- else
- stroker.setDashPattern(cpen.style());
-
- stroker.setCapStyle(cpen.capStyle());
- stroker.setJoinStyle(cpen.joinStyle());
- stroker.setMiterLimit(cpen.miterLimit());
- stroker.setDashOffset(cpen.dashOffset());
-
- qreal width = cpen.widthF();
- if (width == 0)
- stroker.setWidth(1);
- else
- stroker.setWidth(width);
-
- QPainterPath stroke = stroker.createStroke(path);
- stroke.setFillRule(Qt::WindingFill);
- return stroke;
-}
-
-class QGLStrokeCache
-{
- struct CacheInfo
- {
- inline CacheInfo(QPainterPath p, QPainterPath sp, QPen stroke_pen) :
- path(p), stroked_path(sp), pen(stroke_pen) {}
- QPainterPath path;
- QPainterPath stroked_path;
- QPen pen;
- };
-
- typedef QMultiHash<quint64, CacheInfo> QGLStrokeTableHash;
-
-public:
- inline QPainterPath getStrokedPath(const QPainterPath &path, const QPen &pen) {
- quint64 hash_val = 0;
-
- for (int i = 0; i < path.elementCount() && i <= 2; i++) {
- hash_val += quint64(path.elementAt(i).x);
- hash_val += quint64(path.elementAt(i).y);
- }
-
- QGLStrokeTableHash::const_iterator it = cache.constFind(hash_val);
-
- if (it == cache.constEnd())
- return addCacheElement(hash_val, path, pen);
- else {
- do {
- const CacheInfo &cache_info = it.value();
- if (cache_info.path == path && cache_info.pen == pen)
- return cache_info.stroked_path;
- ++it;
- } while (it != cache.constEnd() && it.key() == hash_val);
- // an exact match for this path was not found, create new cache element
- return addCacheElement(hash_val, path, pen);
- }
- }
-
-protected:
- inline int maxCacheSize() const { return 500; }
- QPainterPath addCacheElement(quint64 hash_val, QPainterPath path, const QPen &pen) {
- if (cache.size() == maxCacheSize()) {
- int elem_to_remove = qrand() % maxCacheSize();
- cache.remove(cache.keys()[elem_to_remove]); // may remove more than 1, but OK
- }
- QPainterPath stroke = strokeForPath(path, pen);
- CacheInfo cache_entry(path, stroke, pen);
- return cache.insert(hash_val, cache_entry).value().stroked_path;
- }
-
- QGLStrokeTableHash cache;
-};
-
-Q_GLOBAL_STATIC(QGLStrokeCache, qt_opengl_stroke_cache)
-
-class QGLGradientCache : public QObject
-{
- Q_OBJECT
- struct CacheInfo
- {
- inline CacheInfo(QGradientStops s, qreal op, QGradient::InterpolationMode mode) :
- stops(s), opacity(op), interpolationMode(mode) {}
-
- GLuint texId;
- QGradientStops stops;
- qreal opacity;
- QGradient::InterpolationMode interpolationMode;
- };
-
- typedef QMultiHash<quint64, CacheInfo> QGLGradientColorTableHash;
-
-public:
- QGLGradientCache() : QObject(), buffer_ctx(0)
- {
- connect(QGLSignalProxy::instance(),
- SIGNAL(aboutToDestroyContext(const QGLContext*)),
- SLOT(cleanupGLContextRefs(const QGLContext*)));
- }
-
- inline GLuint getBuffer(const QGradient &gradient, qreal opacity, QGLContext *ctx) {
- if (buffer_ctx && !QGLContext::areSharing(buffer_ctx, ctx))
- cleanCache();
-
- buffer_ctx = ctx;
-
- quint64 hash_val = 0;
-
- QGradientStops stops = gradient.stops();
- for (int i = 0; i < stops.size() && i <= 2; i++)
- hash_val += stops[i].second.rgba();
-
- QGLGradientColorTableHash::const_iterator it = cache.constFind(hash_val);
-
- if (it == cache.constEnd())
- return addCacheElement(hash_val, gradient, opacity);
- else {
- do {
- const CacheInfo &cache_info = it.value();
- if (cache_info.stops == stops && cache_info.opacity == opacity && cache_info.interpolationMode == gradient.interpolationMode()) {
- return cache_info.texId;
- }
- ++it;
- } while (it != cache.constEnd() && it.key() == hash_val);
- // an exact match for these stops and opacity was not found, create new cache
- return addCacheElement(hash_val, gradient, opacity);
- }
- }
-
- inline int paletteSize() const { return 1024; }
-
-protected:
- inline int maxCacheSize() const { return 60; }
- inline void generateGradientColorTable(const QGradient& g,
- uint *colorTable,
- int size, qreal opacity) const;
- GLuint addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity) {
- if (cache.size() == maxCacheSize()) {
- int elem_to_remove = qrand() % maxCacheSize();
- quint64 key = cache.keys()[elem_to_remove];
-
- // need to call glDeleteTextures on each removed cache entry:
- QGLGradientColorTableHash::const_iterator it = cache.constFind(key);
- do {
- glDeleteTextures(1, &it.value().texId);
- } while (++it != cache.constEnd() && it.key() == key);
- cache.remove(key); // may remove more than 1, but OK
- }
- CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode());
- uint buffer[1024];
- generateGradientColorTable(gradient, buffer, paletteSize(), opacity);
- glGenTextures(1, &cache_entry.texId);
-#ifndef QT_OPENGL_ES
- glBindTexture(GL_TEXTURE_1D, cache_entry.texId);
- glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, paletteSize(),
- 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
-#else
- // create 2D one-line texture instead. This requires an impl of manual GL_TEXGEN for all primitives
-#endif
- return cache.insert(hash_val, cache_entry).value().texId;
- }
-
- void cleanCache() {
- QGLShareContextScope scope(buffer_ctx);
- QGLGradientColorTableHash::const_iterator it = cache.constBegin();
- for (; it != cache.constEnd(); ++it) {
- const CacheInfo &cache_info = it.value();
- glDeleteTextures(1, &cache_info.texId);
- }
- cache.clear();
- }
-
- QGLGradientColorTableHash cache;
-
- QGLContext *buffer_ctx;
-
-public Q_SLOTS:
- void cleanupGLContextRefs(const QGLContext *context) {
- if (context == buffer_ctx) {
- cleanCache();
- buffer_ctx = 0;
- }
- }
-};
-
-static inline uint endianColor(uint c)
-{
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- return c;
-#else
- return ( (c << 24) & 0xff000000)
- | ((c >> 24) & 0x000000ff)
- | ((c << 8) & 0x00ff0000)
- | ((c >> 8) & 0x0000ff00);
-#endif // Q_BYTE_ORDER
-}
-
-void QGLGradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const
-{
- int pos = 0;
- QGradientStops s = gradient.stops();
- QVector<uint> colors(s.size());
-
- for (int i = 0; i < s.size(); ++i)
- colors[i] = s[i].second.rgba();
-
- bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation);
-
- uint alpha = qRound(opacity * 256);
- uint current_color = ARGB_COMBINE_ALPHA(colors[0], alpha);
- qreal incr = 1.0 / qreal(size);
- qreal fpos = 1.5 * incr;
- colorTable[pos++] = endianColor(PREMUL(current_color));
-
- while (fpos <= s.first().first) {
- colorTable[pos] = colorTable[pos - 1];
- pos++;
- fpos += incr;
- }
-
- if (colorInterpolation)
- current_color = PREMUL(current_color);
-
- for (int i = 0; i < s.size() - 1; ++i) {
- qreal delta = 1/(s[i+1].first - s[i].first);
- uint next_color = ARGB_COMBINE_ALPHA(colors[i+1], alpha);
- if (colorInterpolation)
- next_color = PREMUL(next_color);
-
- while (fpos < s[i+1].first && pos < size) {
- int dist = int(256 * ((fpos - s[i].first) * delta));
- int idist = 256 - dist;
- if (colorInterpolation)
- colorTable[pos] = endianColor(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
- else
- colorTable[pos] = endianColor(PREMUL(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
- ++pos;
- fpos += incr;
- }
- current_color = next_color;
- }
-
- Q_ASSERT(s.size() > 0);
-
- uint last_color = endianColor(PREMUL(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha)));
- for (;pos < size; ++pos)
- colorTable[pos] = last_color;
-
- // Make sure the last color stop is represented at the end of the table
- colorTable[size-1] = last_color;
-}
-
-#ifndef Q_WS_QWS
-Q_GLOBAL_STATIC(QGLGradientCache, qt_opengl_gradient_cache)
-#endif
-
-void QOpenGLPaintEnginePrivate::createGradientPaletteTexture(const QGradient& g)
-{
-#ifdef QT_OPENGL_ES //###
- Q_UNUSED(g);
-#else
- GLuint texId = qt_opengl_gradient_cache()->getBuffer(g, opacity, device->context());
- glBindTexture(GL_TEXTURE_1D, texId);
- grad_palette = texId;
- if (g.spread() == QGradient::RepeatSpread || g.type() == QGradient::ConicalGradient)
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- else if (g.spread() == QGradient::ReflectSpread)
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT_IBM);
- else
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
-#endif
-}
-
-
-inline void QOpenGLPaintEnginePrivate::setGradientOps(const QBrush &brush, const QRectF &bounds)
-{
- current_style = brush.style();
-
- if (current_style < Qt::LinearGradientPattern || current_style > Qt::ConicalGradientPattern) {
- setGLBrush(brush.color());
- qt_glColor4ubv(brush_color);
- }
-
- updateGradient(brush, bounds);
-
-#ifndef QT_OPENGL_ES //### GLES does not have GL_TEXTURE_GEN_ so we are falling back for gradients
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_1D);
-
- if (current_style == Qt::LinearGradientPattern) {
- if (high_quality_antialiasing || !has_fast_composition_mode) {
- fragment_brush = FRAGMENT_PROGRAM_BRUSH_LINEAR;
- } else {
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_1D);
- }
- } else {
- if (use_fragment_programs) {
- if (current_style == Qt::RadialGradientPattern)
- fragment_brush = FRAGMENT_PROGRAM_BRUSH_RADIAL;
- else if (current_style == Qt::ConicalGradientPattern)
- fragment_brush = FRAGMENT_PROGRAM_BRUSH_CONICAL;
- else if (current_style == Qt::SolidPattern)
- fragment_brush = FRAGMENT_PROGRAM_BRUSH_SOLID;
- else if (current_style == Qt::TexturePattern && !brush.texture().isQBitmap())
- fragment_brush = FRAGMENT_PROGRAM_BRUSH_TEXTURE;
- else
- fragment_brush = FRAGMENT_PROGRAM_BRUSH_PATTERN;
- }
- }
-#endif
-}
-
-QOpenGLPaintEngine::QOpenGLPaintEngine()
- : QPaintEngineEx(*(new QOpenGLPaintEnginePrivate))
-{
-}
-
-QOpenGLPaintEngine::~QOpenGLPaintEngine()
-{
-}
-
-bool QOpenGLPaintEngine::begin(QPaintDevice *pdev)
-{
- Q_D(QOpenGLPaintEngine);
-
- if (pdev->devType() == QInternal::OpenGL)
- d->device = static_cast<QGLPaintDevice*>(pdev);
- else
- d->device = QGLPaintDevice::getDevice(pdev);
-
- if (!d->device)
- return false;
-
- d->offscreen.setDevice(pdev);
- d->has_fast_pen = false;
- d->inverseScale = 1;
- d->opacity = 1;
- d->device->beginPaint();
- d->matrix = QTransform();
- d->has_antialiasing = false;
- d->high_quality_antialiasing = false;
-
- QSize sz(d->device->size());
- d->dirty_stencil = QRect(0, 0, sz.width(), sz.height());
-
- d->use_emulation = false;
-
- for (int i = 0; i < 4; ++i)
- for (int j = 0; j < 4; ++j)
- d->mv_matrix[i][j] = (i == j ? qreal(1) : qreal(0));
-
- bool has_frag_program = (QGLExtensions::glExtensions() & QGLExtensions::FragmentProgram)
- && (pdev->devType() != QInternal::Pixmap);
-
- QGLContext *ctx = const_cast<QGLContext *>(d->device->context());
- if (!ctx) {
- qWarning() << "QOpenGLPaintEngine: paint device doesn't have a valid GL context.";
- return false;
- }
-
- if (has_frag_program)
- has_frag_program = qt_resolve_frag_program_extensions(ctx) && qt_resolve_version_1_3_functions(ctx);
-
- d->use_stencil_method = d->device->format().stencil()
- && (QGLExtensions::glExtensions() & QGLExtensions::StencilWrap);
- if (d->device->format().directRendering()
- && (d->use_stencil_method && QGLExtensions::glExtensions() & QGLExtensions::StencilTwoSide))
- d->has_stencil_face_ext = qt_resolve_stencil_face_extension(ctx);
-
-#ifdef Q_WS_X11
- static bool nvidia_workaround_needs_init = true;
- if (nvidia_workaround_needs_init) {
- // nvidia 9x.xx unix drivers contain a bug which requires us to
- // call glFinish before releasing an fbo to avoid painting
- // artifacts
- const QByteArray versionString(reinterpret_cast<const char*>(glGetString(GL_VERSION)));
- const int pos = versionString.indexOf("NVIDIA");
- if (pos >= 0) {
- const float nvidiaDriverVersion = versionString.mid(pos + strlen("NVIDIA")).toFloat();
- qt_nvidiaFboNeedsFinish = nvidiaDriverVersion >= 90.0 && nvidiaDriverVersion < 100.0;
- }
- nvidia_workaround_needs_init = false;
- }
-#endif
-
-#ifndef QT_OPENGL_ES
- if (!ctx->d_ptr->internal_context) {
- glGetDoublev(GL_PROJECTION_MATRIX, &d->projection_matrix[0][0]);
- glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
- glPushAttrib(GL_ALL_ATTRIB_BITS);
-
- glDisableClientState(GL_EDGE_FLAG_ARRAY);
- glDisableClientState(GL_INDEX_ARRAY);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glDisable(GL_TEXTURE_1D);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glPixelTransferi(GL_MAP_COLOR, false);
- glPixelTransferi(GL_MAP_STENCIL, false);
- glDisable(GL_TEXTURE_GEN_S);
-
- glPixelStorei(GL_PACK_SWAP_BYTES, false);
- glPixelStorei(GL_PACK_LSB_FIRST, false);
- glPixelStorei(GL_PACK_ROW_LENGTH, 0);
- glPixelStorei(GL_PACK_SKIP_ROWS, 0);
- glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_PACK_ALIGNMENT, 4);
-
- glPixelStorei(GL_UNPACK_SWAP_BYTES, false);
- glPixelStorei(GL_UNPACK_LSB_FIRST, false);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-
- if (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2) {
- glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
- glPixelStorei(GL_PACK_SKIP_IMAGES, 0);
- glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
- glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
- }
- }
-#endif
-
- if (!ctx->d_ptr->internal_context) {
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glMatrixMode(GL_TEXTURE);
- glPushMatrix();
- glLoadIdentity();
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- if (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers)
- glDisable(GL_MULTISAMPLE);
- glDisable(GL_TEXTURE_2D);
- if (QGLExtensions::glExtensions() & QGLExtensions::TextureRectangle)
- glDisable(GL_TEXTURE_RECTANGLE_NV);
- glDisable(GL_STENCIL_TEST);
- glDisable(GL_CULL_FACE);
- glDisable(GL_LIGHTING);
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- }
-
- d->offscreen.begin();
-
- glViewport(0, 0, sz.width(), sz.height()); // XXX (Embedded): We need a solution for GLWidgets that draw in a part or a bigger surface...
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-#ifdef QT_OPENGL_ES
- glOrthof(0, sz.width(), sz.height(), 0, -999999, 999999);
-#else
- glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
-#endif
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glEnable(GL_BLEND);
- d->composition_mode = QPainter::CompositionMode_SourceOver;
-
-#ifdef QT_OPENGL_ES
- d->max_texture_size = ctx->d_func()->maxTextureSize();
-#else
- bool shared_ctx = QGLContext::areSharing(d->device->context(), d->shader_ctx);
-
- if (shared_ctx) {
- d->max_texture_size = d->shader_ctx->d_func()->maxTextureSize();
- } else {
- d->max_texture_size = ctx->d_func()->maxTextureSize();
-
- if (d->shader_ctx) {
- d->shader_ctx->makeCurrent();
- glBindTexture(GL_TEXTURE_1D, 0);
- glDeleteTextures(1, &d->grad_palette);
-
- if (has_frag_program && d->use_fragment_programs)
- glDeleteTextures(1, &d->drawable_texture);
- ctx->makeCurrent();
- }
- d->shader_ctx = d->device->context();
- glGenTextures(1, &d->grad_palette);
-
- qt_mask_texture_cache()->clearCache();
- d->use_fragment_programs = has_frag_program;
- }
-
- if (d->use_fragment_programs && (!shared_ctx || sz.width() > d->drawable_texture_size.width()
- || sz.height() > d->drawable_texture_size.height()))
- {
- // delete old texture if size has increased, otherwise it was deleted earlier
- if (shared_ctx)
- glDeleteTextures(1, &d->drawable_texture);
-
- d->dirty_drawable_texture = true;
- d->drawable_texture_size = QSize(qt_next_power_of_two(sz.width()),
- qt_next_power_of_two(sz.height()));
- }
-#endif
-
- updateClipRegion(QRegion(), Qt::NoClip);
- penChanged();
- brushChanged();
- opacityChanged();
- compositionModeChanged();
- renderHintsChanged();
- transformChanged();
- return true;
-}
-
-bool QOpenGLPaintEngine::end()
-{
- Q_D(QOpenGLPaintEngine);
- d->flushDrawQueue();
- d->offscreen.end();
- QGLContext *ctx = const_cast<QGLContext *>(d->device->context());
- if (!ctx->d_ptr->internal_context) {
- glMatrixMode(GL_TEXTURE);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- }
-#ifndef QT_OPENGL_ES
- if (ctx->d_ptr->internal_context) {
- glDisable(GL_SCISSOR_TEST);
- } else {
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixd(&d->projection_matrix[0][0]);
- glPopAttrib();
- glPopClientAttrib();
- }
-#endif
- d->device->endPaint();
- qt_mask_texture_cache()->maintainCache();
-
-#if defined(Q_WS_X11)
- // clear out the references we hold for textures bound with the
- // texture_from_pixmap extension
- ctx->d_func()->boundPixmaps.clear();
-#endif
- return true;
-}
-
-void QOpenGLPaintEngine::updateState(const QPaintEngineState &state)
-{
- Q_D(QOpenGLPaintEngine);
- QPaintEngine::DirtyFlags flags = state.state();
-
- bool update_fast_pen = false;
-
- if (flags & DirtyOpacity) {
- update_fast_pen = true;
- d->opacity = state.opacity();
- if (d->opacity > 1.0f)
- d->opacity = 1.0f;
- if (d->opacity < 0.f)
- d->opacity = 0.f;
- // force update
- flags |= DirtyPen;
- flags |= DirtyBrush;
- }
-
- if (flags & DirtyTransform) {
- update_fast_pen = true;
- updateMatrix(state.transform());
- // brush setup depends on transform state
- if (state.brush().style() != Qt::NoBrush)
- flags |= DirtyBrush;
- }
-
- if (flags & DirtyPen) {
- update_fast_pen = true;
- updatePen(state.pen());
- }
-
- if (flags & (DirtyBrush | DirtyBrushOrigin)) {
- updateBrush(state.brush(), state.brushOrigin());
- }
-
- if (flags & DirtyFont) {
- updateFont(state.font());
- }
-
- if (state.state() & DirtyClipEnabled) {
- if (state.isClipEnabled())
- updateClipRegion(painter()->clipRegion(), Qt::ReplaceClip);
- else
- updateClipRegion(QRegion(), Qt::NoClip);
- }
-
- if (flags & DirtyClipPath) {
- updateClipRegion(QRegion(state.clipPath().toFillPolygon().toPolygon(),
- state.clipPath().fillRule()),
- state.clipOperation());
- }
-
- if (flags & DirtyClipRegion) {
- updateClipRegion(state.clipRegion(), state.clipOperation());
- }
-
- if (flags & DirtyHints) {
- updateRenderHints(state.renderHints());
- }
-
- if (flags & DirtyCompositionMode) {
- updateCompositionMode(state.compositionMode());
- }
-
- if (update_fast_pen) {
- Q_D(QOpenGLPaintEngine);
- qreal pen_width = d->cpen.widthF();
- d->has_fast_pen =
- ((pen_width == 0 || (pen_width <= 1 && d->txop <= QTransform::TxTranslate))
- || d->cpen.isCosmetic())
- && d->cpen.style() == Qt::SolidLine
- && d->cpen.isSolid();
- }
-}
-
-
-void QOpenGLPaintEnginePrivate::setInvMatrixData(const QTransform &inv_matrix)
-{
- inv_matrix_data[0][0] = inv_matrix.m11();
- inv_matrix_data[1][0] = inv_matrix.m21();
- inv_matrix_data[2][0] = inv_matrix.m31();
-
- inv_matrix_data[0][1] = inv_matrix.m12();
- inv_matrix_data[1][1] = inv_matrix.m22();
- inv_matrix_data[2][1] = inv_matrix.m32();
-
- inv_matrix_data[0][2] = inv_matrix.m13();
- inv_matrix_data[1][2] = inv_matrix.m23();
- inv_matrix_data[2][2] = inv_matrix.m33();
-}
-
-
-void QOpenGLPaintEnginePrivate::updateGradient(const QBrush &brush, const QRectF &)
-{
-#ifdef QT_OPENGL_ES
- Q_UNUSED(brush);
-#else
- bool has_mirrored_repeat = QGLExtensions::glExtensions() & QGLExtensions::MirroredRepeat;
- Qt::BrushStyle style = brush.style();
-
- QTransform m = brush.transform();
-
- if (has_mirrored_repeat && style == Qt::LinearGradientPattern) {
- const QLinearGradient *g = static_cast<const QLinearGradient *>(brush.gradient());
- QTransform m = brush.transform();
- QPointF realStart = g->start();
- QPointF realFinal = g->finalStop();
- QPointF start = m.map(realStart);
- QPointF stop;
-
- if (qFuzzyCompare(m.m11(), m.m22()) && m.m12() == 0.0 && m.m21() == 0.0) {
- // It is a simple uniform scale and/or translation
- stop = m.map(realFinal);
- } else {
- // It is not enough to just transform the endpoints.
- // We have to make sure the _pattern_ is transformed correctly.
-
- qreal odx = realFinal.x() - realStart.x();
- qreal ody = realFinal.y() - realStart.y();
-
- // nx, ny and dx, dy are normal and gradient direction after transform:
- qreal nx = m.m11()*ody - m.m21()*odx;
- qreal ny = m.m12()*ody - m.m22()*odx;
-
- qreal dx = m.m11()*odx + m.m21()*ody;
- qreal dy = m.m12()*odx + m.m22()*ody;
-
- qreal lx = 1 / (dx - dy*nx/ny);
- qreal ly = 1 / (dy - dx*ny/nx);
- qreal l = 1 / qSqrt(lx*lx+ly*ly);
-
- stop = start + QPointF(-ny, nx) * l/qSqrt(nx*nx+ny*ny);
- }
-
- float tr[4], f;
- tr[0] = stop.x() - start.x();
- tr[1] = stop.y() - start.y();
- f = 1.0 / (tr[0]*tr[0] + tr[1]*tr[1]);
- tr[0] *= f;
- tr[1] *= f;
- tr[2] = 0;
- tr[3] = -(start.x()*tr[0] + start.y()*tr[1]);
- brush_color[0] = brush_color[1] = brush_color[2] = brush_color[3] = 255;
- qt_glColor4ubv(brush_color);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tr);
- }
-
- if (use_fragment_programs) {
- if (style == Qt::RadialGradientPattern) {
- const QRadialGradient *g = static_cast<const QRadialGradient *>(brush.gradient());
- QPointF realCenter = g->center();
- QPointF realFocal = g->focalPoint();
- qreal realRadius = g->radius();
- QTransform translate(1, 0, 0, 1, -realFocal.x(), -realFocal.y());
- QTransform gl_to_qt(1, 0, 0, -1, 0, pdev->height());
- QTransform m = QTransform(matrix).translate(brush_origin.x(), brush_origin.y());
- QTransform inv_matrix = gl_to_qt * (brush.transform() * m).inverted() * translate;
-
- setInvMatrixData(inv_matrix);
-
- fmp_data[0] = realCenter.x() - realFocal.x();
- fmp_data[1] = realCenter.y() - realFocal.y();
-
- fmp2_m_radius2_data[0] = -fmp_data[0] * fmp_data[0] - fmp_data[1] * fmp_data[1] + realRadius * realRadius;
- } else if (style == Qt::ConicalGradientPattern) {
- const QConicalGradient *g = static_cast<const QConicalGradient *>(brush.gradient());
- QPointF realCenter = g->center();
- QTransform translate(1, 0, 0, 1, -realCenter.x(), -realCenter.y());
- QTransform gl_to_qt(1, 0, 0, -1, 0, pdev->height());
- QTransform m = QTransform(matrix).translate(brush_origin.x(), brush_origin.y());
- QTransform inv_matrix = gl_to_qt * (brush.transform() * m).inverted() * translate;
-
- setInvMatrixData(inv_matrix);
-
- angle_data[0] = -(g->angle() * 2 * Q_PI) / 360.0;
- } else if (style == Qt::LinearGradientPattern) {
- const QLinearGradient *g = static_cast<const QLinearGradient *>(brush.gradient());
-
- QPointF realStart = g->start();
- QPointF realFinal = g->finalStop();
- QTransform translate(1, 0, 0, 1, -realStart.x(), -realStart.y());
- QTransform gl_to_qt(1, 0, 0, -1, 0, pdev->height());
- QTransform m = QTransform(matrix).translate(brush_origin.x(), brush_origin.y());
- QTransform inv_matrix = gl_to_qt * (brush.transform() * m).inverted() * translate;
-
- setInvMatrixData(inv_matrix);
-
- QPointF l = realFinal - realStart;
-
- linear_data[0] = l.x();
- linear_data[1] = l.y();
-
- linear_data[2] = 1.0f / (l.x() * l.x() + l.y() * l.y());
- } else if (style != Qt::SolidPattern) {
- QTransform gl_to_qt(1, 0, 0, -1, 0, pdev->height());
- QTransform m = QTransform(matrix).translate(brush_origin.x(), brush_origin.y());
- QTransform inv_matrix = gl_to_qt * (brush.transform() * m).inverted();
-
- setInvMatrixData(inv_matrix);
- }
- }
-
- if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
- createGradientPaletteTexture(*brush.gradient());
- }
-#endif
-}
-
-
-class QOpenGLTessellator : public QTessellator
-{
-public:
- QOpenGLTessellator() {}
- ~QOpenGLTessellator() { }
- QGLTrapezoid toGLTrapezoid(const Trapezoid &trap);
-};
-
-QGLTrapezoid QOpenGLTessellator::toGLTrapezoid(const Trapezoid &trap)
-{
- QGLTrapezoid t;
-
- t.top = Q27Dot5ToDouble(trap.top);
- t.bottom = Q27Dot5ToDouble(trap.bottom);
-
- Q27Dot5 y = trap.topLeft->y - trap.bottomLeft->y;
-
- qreal topLeftY = Q27Dot5ToDouble(trap.topLeft->y);
-
- qreal tx = Q27Dot5ToDouble(trap.topLeft->x);
- qreal m = (-tx + Q27Dot5ToDouble(trap.bottomLeft->x)) / Q27Dot5ToDouble(y);
- t.topLeftX = tx + m * (topLeftY - t.top);
- t.bottomLeftX = tx + m * (topLeftY - t.bottom);
-
- y = trap.topRight->y - trap.bottomRight->y;
-
- qreal topRightY = Q27Dot5ToDouble(trap.topRight->y);
-
- tx = Q27Dot5ToDouble(trap.topRight->x);
- m = (-tx + Q27Dot5ToDouble(trap.bottomRight->x)) / Q27Dot5ToDouble(y);
-
- t.topRightX = tx + m * (topRightY - Q27Dot5ToDouble(trap.top));
- t.bottomRightX = tx + m * (topRightY - Q27Dot5ToDouble(trap.bottom));
-
- return t;
-}
-
-class QOpenGLImmediateModeTessellator : public QOpenGLTessellator
-{
-public:
- void addTrap(const Trapezoid &trap);
- void tessellate(const QPointF *points, int nPoints, bool winding) {
- trapezoids.reserve(trapezoids.size() + nPoints);
- setWinding(winding);
- QTessellator::tessellate(points, nPoints);
- }
-
- QVector<QGLTrapezoid> trapezoids;
-};
-
-void QOpenGLImmediateModeTessellator::addTrap(const Trapezoid &trap)
-{
- trapezoids.append(toGLTrapezoid(trap));
-}
-
-#ifndef QT_OPENGL_ES
-static void drawTrapezoid(const QGLTrapezoid &trap, const qreal offscreenHeight, QGLContext *ctx)
-{
- qreal minX = qMin(trap.topLeftX, trap.bottomLeftX);
- qreal maxX = qMax(trap.topRightX, trap.bottomRightX);
-
- if (qFuzzyCompare(trap.top, trap.bottom) || qFuzzyCompare(minX, maxX) ||
- (qFuzzyCompare(trap.topLeftX, trap.topRightX) && qFuzzyCompare(trap.bottomLeftX, trap.bottomRightX)))
- return;
-
- const qreal xpadding = 1.0;
- const qreal ypadding = 1.0;
-
- qreal topDist = offscreenHeight - trap.top;
- qreal bottomDist = offscreenHeight - trap.bottom;
-
- qreal reciprocal = bottomDist / (bottomDist - topDist);
-
- qreal leftB = trap.bottomLeftX + (trap.topLeftX - trap.bottomLeftX) * reciprocal;
- qreal rightB = trap.bottomRightX + (trap.topRightX - trap.bottomRightX) * reciprocal;
-
- const bool topZero = qFuzzyIsNull(topDist);
-
- reciprocal = topZero ? 1.0 / bottomDist : 1.0 / topDist;
-
- qreal leftA = topZero ? (trap.bottomLeftX - leftB) * reciprocal : (trap.topLeftX - leftB) * reciprocal;
- qreal rightA = topZero ? (trap.bottomRightX - rightB) * reciprocal : (trap.topRightX - rightB) * reciprocal;
-
- qreal invLeftA = qFuzzyIsNull(leftA) ? 0.0 : 1.0 / leftA;
- qreal invRightA = qFuzzyIsNull(rightA) ? 0.0 : 1.0 / rightA;
-
- // fragment program needs the negative of invRightA as it mirrors the line
- glTexCoord4f(topDist, bottomDist, invLeftA, -invRightA);
- glMultiTexCoord4f(GL_TEXTURE1, leftA, leftB, rightA, rightB);
-
- qreal topY = trap.top - ypadding;
- qreal bottomY = trap.bottom + ypadding;
-
- qreal bounds_bottomLeftX = leftA * (offscreenHeight - bottomY) + leftB;
- qreal bounds_bottomRightX = rightA * (offscreenHeight - bottomY) + rightB;
- qreal bounds_topLeftX = leftA * (offscreenHeight - topY) + leftB;
- qreal bounds_topRightX = rightA * (offscreenHeight - topY) + rightB;
-
- QPointF leftNormal(1, -leftA);
- leftNormal /= qSqrt(leftNormal.x() * leftNormal.x() + leftNormal.y() * leftNormal.y());
- QPointF rightNormal(1, -rightA);
- rightNormal /= qSqrt(rightNormal.x() * rightNormal.x() + rightNormal.y() * rightNormal.y());
-
- qreal left_padding = xpadding / qAbs(leftNormal.x());
- qreal right_padding = xpadding / qAbs(rightNormal.x());
-
- glVertex2d(bounds_topLeftX - left_padding, topY);
- glVertex2d(bounds_topRightX + right_padding, topY);
- glVertex2d(bounds_bottomRightX + right_padding, bottomY);
- glVertex2d(bounds_bottomLeftX - left_padding, bottomY);
-
- glTexCoord4f(0.0f, 0.0f, 0.0f, 1.0f);
-}
-#endif // !Q_WS_QWS
-
-class QOpenGLTrapezoidToArrayTessellator : public QOpenGLTessellator
-{
-public:
- QOpenGLTrapezoidToArrayTessellator() : vertices(0), allocated(0), size(0) {}
- ~QOpenGLTrapezoidToArrayTessellator() { free(vertices); }
- GLfloat *vertices;
- int allocated;
- int size;
- QRectF bounds;
- void addTrap(const Trapezoid &trap);
- void tessellate(const QPointF *points, int nPoints, bool winding) {
- size = 0;
- setWinding(winding);
- bounds = QTessellator::tessellate(points, nPoints);
- }
-};
-
-void QOpenGLTrapezoidToArrayTessellator::addTrap(const Trapezoid &trap)
-{
- // On OpenGL ES we convert the trap to 2 triangles
-#ifndef QT_OPENGL_ES
- if (size > allocated - 8) {
-#else
- if (size > allocated - 12) {
-#endif
- allocated = qMax(2*allocated, 512);
- vertices = (GLfloat *)realloc(vertices, allocated * sizeof(GLfloat));
- }
-
- QGLTrapezoid t = toGLTrapezoid(trap);
-
-#ifndef QT_OPENGL_ES
- vertices[size++] = t.topLeftX;
- vertices[size++] = t.top;
- vertices[size++] = t.topRightX;
- vertices[size++] = t.top;
- vertices[size++] = t.bottomRightX;
- vertices[size++] = t.bottom;
- vertices[size++] = t.bottomLeftX;
- vertices[size++] = t.bottom;
-#else
- // First triangle
- vertices[size++] = t.topLeftX;
- vertices[size++] = t.top;
- vertices[size++] = t.topRightX;
- vertices[size++] = t.top;
- vertices[size++] = t.bottomRightX;
- vertices[size++] = t.bottom;
-
- // Second triangle
- vertices[size++] = t.bottomLeftX;
- vertices[size++] = t.bottom;
- vertices[size++] = t.topLeftX;
- vertices[size++] = t.top;
- vertices[size++] = t.bottomRightX;
- vertices[size++] = t.bottom;
-#endif
-}
-
-
-void QOpenGLPaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int pointCount,
- Qt::FillRule fill)
-{
- QOpenGLTrapezoidToArrayTessellator tessellator;
- tessellator.tessellate(polygonPoints, pointCount, fill == Qt::WindingFill);
-
- DEBUG_ONCE qDebug() << "QOpenGLPaintEnginePrivate: Drawing polygon with" << pointCount << "points using fillPolygon_dev";
-
- setGradientOps(cbrush, tessellator.bounds);
-
- bool fast_style = current_style == Qt::LinearGradientPattern
- || current_style == Qt::SolidPattern;
-
-#ifndef QT_OPENGL_ES
- GLenum geometry_mode = GL_QUADS;
-#else
- GLenum geometry_mode = GL_TRIANGLES;
-#endif
-
- if (use_fragment_programs && !(fast_style && has_fast_composition_mode)) {
- composite(geometry_mode, tessellator.vertices, tessellator.size / 2);
- } else {
- glVertexPointer(2, GL_FLOAT, 0, tessellator.vertices);
- glEnableClientState(GL_VERTEX_ARRAY);
- glDrawArrays(geometry_mode, 0, tessellator.size/2);
- glDisableClientState(GL_VERTEX_ARRAY);
- }
-}
-
-
-inline void QOpenGLPaintEnginePrivate::lineToStencil(qreal x, qreal y)
-{
- tess_points.add(QPointF(x, y));
-
- if (x > max_x)
- max_x = x;
- else if (x < min_x)
- min_x = x;
- if (y > max_y)
- max_y = y;
- else if (y < min_y)
- min_y = y;
-}
-
-inline void QOpenGLPaintEnginePrivate::curveToStencil(const QPointF &cp1, const QPointF &cp2, const QPointF &ep)
-{
- qreal inverseScaleHalf = inverseScale / 2;
-
- QBezier beziers[32];
- beziers[0] = QBezier::fromPoints(tess_points.last(), cp1, cp2, ep);
- QBezier *b = beziers;
- while (b >= beziers) {
- // check if we can pop the top bezier curve from the stack
- qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1);
- qreal d;
- if (l > inverseScale) {
- d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2) - (b->y4 - b->y1)*(b->x1 - b->x2) )
- + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3) - (b->y4 - b->y1)*(b->x1 - b->x3) );
- d /= l;
- } else {
- d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) +
- qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);
- }
- if (d < inverseScaleHalf || b == beziers + 31) {
- // good enough, we pop it off and add the endpoint
- lineToStencil(b->x4, b->y4);
- --b;
- } else {
- // split, second half of the polygon goes lower into the stack
- b->split(b+1, b);
- ++b;
- }
- }
-}
-
-
-void QOpenGLPaintEnginePrivate::pathToVertexArrays(const QPainterPath &path)
-{
- const QPainterPath::Element &first = path.elementAt(0);
- min_x = max_x = first.x;
- min_y = max_y = first.y;
-
- tess_points.reset();
- tess_points_stops.clear();
- lineToStencil(first.x, first.y);
-
- for (int i=1; i<path.elementCount(); ++i) {
- const QPainterPath::Element &e = path.elementAt(i);
- switch (e.type) {
- case QPainterPath::MoveToElement:
- tess_points_stops.append(tess_points.size());
- lineToStencil(e.x, e.y);
- break;
- case QPainterPath::LineToElement:
- lineToStencil(e.x, e.y);
- break;
- case QPainterPath::CurveToElement:
- curveToStencil(e, path.elementAt(i+1), path.elementAt(i+2));
- i+=2;
- break;
- default:
- break;
- }
- }
- lineToStencil(first.x, first.y);
- tess_points_stops.append(tess_points.size());
-}
-
-
-void QOpenGLPaintEnginePrivate::drawVertexArrays()
-{
- if (tess_points_stops.count() == 0)
- return;
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_DOUBLE, 0, tess_points.data());
- int previous_stop = 0;
- foreach(int stop, tess_points_stops) {
- glDrawArrays(GL_TRIANGLE_FAN, previous_stop, stop-previous_stop);
- previous_stop = stop;
- }
- glDisableClientState(GL_VERTEX_ARRAY);
-}
-
-void QOpenGLPaintEnginePrivate::fillVertexArray(Qt::FillRule fillRule)
-{
- Q_Q(QOpenGLPaintEngine);
-
- QRect rect = dirty_stencil.boundingRect();
-
- if (use_system_clip)
- rect = q->systemClip().intersected(dirty_stencil).boundingRect();
-
- glStencilMask(~0);
-
- if (!rect.isEmpty()) {
- disableClipping();
-
- glEnable(GL_SCISSOR_TEST);
-
- const int left = rect.left();
- const int width = rect.width();
- const int bottom = device->size().height() - (rect.bottom() + 1);
- const int height = rect.height();
-
- glScissor(left, bottom, width, height);
-
- glClearStencil(0);
- glClear(GL_STENCIL_BUFFER_BIT);
- dirty_stencil -= rect;
-
- glDisable(GL_SCISSOR_TEST);
-
- enableClipping();
- }
-
- // Enable stencil.
- glEnable(GL_STENCIL_TEST);
-
- // Disable color writes.
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
- GLuint stencilMask = 0;
-
- if (fillRule == Qt::OddEvenFill) {
- stencilMask = 1;
-
- // Enable stencil writes.
- glStencilMask(stencilMask);
-
- // Set stencil xor mode.
- glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT);
-
- // Disable stencil func.
- glStencilFunc(GL_ALWAYS, 0, ~0);
-
- drawVertexArrays();
- } else if (fillRule == Qt::WindingFill) {
- stencilMask = ~0;
-
- if (has_stencil_face_ext) {
- QGL_FUNC_CONTEXT;
- glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
-
- glActiveStencilFaceEXT(GL_BACK);
- glStencilOp(GL_KEEP, GL_KEEP, GL_DECR_WRAP_EXT);
- glStencilFunc(GL_ALWAYS, 0, ~0);
-
- glActiveStencilFaceEXT(GL_FRONT);
- glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP_EXT);
- glStencilFunc(GL_ALWAYS, 0, ~0);
-
- drawVertexArrays();
-
- glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
- } else {
- glStencilFunc(GL_ALWAYS, 0, ~0);
- glEnable(GL_CULL_FACE);
-
- glCullFace(GL_BACK);
- glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP_EXT);
- drawVertexArrays();
-
- glCullFace(GL_FRONT);
- glStencilOp(GL_KEEP, GL_KEEP, GL_DECR_WRAP_EXT);
- drawVertexArrays();
-
- glDisable(GL_CULL_FACE);
- }
- }
-
- // Enable color writes.
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glStencilMask(stencilMask);
-
- setGradientOps(cbrush, QRectF(QPointF(min_x, min_y), QSizeF(max_x - min_x, max_y - min_y)));
-
- bool fast_fill = has_fast_composition_mode && (current_style == Qt::LinearGradientPattern || current_style == Qt::SolidPattern);
-
- if (use_fragment_programs && !fast_fill) {
- DEBUG_ONCE qDebug() << "QOpenGLPaintEnginePrivate: Drawing polygon using stencil method (fragment programs)";
- QRectF rect(QPointF(min_x, min_y), QSizeF(max_x - min_x, max_y - min_y));
-
- // Enable stencil func.
- glStencilFunc(GL_NOTEQUAL, 0, stencilMask);
- glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
- composite(rect);
- } else {
- DEBUG_ONCE qDebug() << "QOpenGLPaintEnginePrivate: Drawing polygon using stencil method (no fragment programs)";
-
- // Enable stencil func.
- glStencilFunc(GL_NOTEQUAL, 0, stencilMask);
- glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-#ifndef QT_OPENGL_ES
- glBegin(GL_QUADS);
- glVertex2f(min_x, min_y);
- glVertex2f(max_x, min_y);
- glVertex2f(max_x, max_y);
- glVertex2f(min_x, max_y);
- glEnd();
-#endif
- }
-
- // Disable stencil writes.
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- glStencilMask(0);
- glDisable(GL_STENCIL_TEST);
-}
-
-void QOpenGLPaintEnginePrivate::fillPath(const QPainterPath &path)
-{
- if (path.isEmpty())
- return;
-
- if (use_stencil_method && !high_quality_antialiasing) {
- pathToVertexArrays(path);
- fillVertexArray(path.fillRule());
- return;
- }
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- if (high_quality_antialiasing)
- drawOffscreenPath(path);
- else {
- QPolygonF poly = path.toFillPolygon(matrix);
- fillPolygon_dev(poly.data(), poly.count(),
- path.fillRule());
- }
-
- updateGLMatrix();
-}
-
-extern bool qt_isExtendedRadialGradient(const QBrush &brush);
-
-static inline bool needsEmulation(Qt::BrushStyle style)
-{
- return !(style == Qt::SolidPattern
- || (style == Qt::LinearGradientPattern
- && (QGLExtensions::glExtensions() & QGLExtensions::MirroredRepeat)));
-}
-
-void QOpenGLPaintEnginePrivate::updateUseEmulation()
-{
- use_emulation = (!use_fragment_programs
- && ((has_pen && needsEmulation(pen_brush_style))
- || (has_brush && needsEmulation(brush_style))))
- || (has_pen && qt_isExtendedRadialGradient(cpen.brush()))
- || (has_brush && qt_isExtendedRadialGradient(cbrush));
-}
-
-void QOpenGLPaintEngine::updatePen(const QPen &pen)
-{
- Q_D(QOpenGLPaintEngine);
- Qt::PenStyle pen_style = pen.style();
- d->pen_brush_style = pen.brush().style();
- d->cpen = pen;
- d->has_pen = (pen_style != Qt::NoPen) && (d->pen_brush_style != Qt::NoBrush);
- d->updateUseEmulation();
-
- if (pen.isCosmetic()) {
- GLfloat width = pen.widthF() == 0.0f ? 1.0f : pen.widthF();
- glLineWidth(width);
- glPointSize(width);
- }
-
- if (d->pen_brush_style >= Qt::LinearGradientPattern
- && d->pen_brush_style <= Qt::ConicalGradientPattern)
- {
- d->setGLPen(Qt::white);
- } else {
- d->setGLPen(pen.color());
- }
-
- d->updateFastPen();
-}
-
-void QOpenGLPaintEngine::updateBrush(const QBrush &brush, const QPointF &origin)
-{
- Q_D(QOpenGLPaintEngine);
- d->cbrush = brush;
- d->brush_style = brush.style();
- d->brush_origin = origin;
- d->has_brush = (d->brush_style != Qt::NoBrush);
- d->updateUseEmulation();
-}
-
-void QOpenGLPaintEngine::updateFont(const QFont &)
-{
-}
-
-void QOpenGLPaintEngine::updateMatrix(const QTransform &mtx)
-{
- Q_D(QOpenGLPaintEngine);
-
- d->matrix = mtx;
-
- d->mv_matrix[0][0] = mtx.m11();
- d->mv_matrix[0][1] = mtx.m12();
- d->mv_matrix[0][2] = 0;
- d->mv_matrix[0][3] = mtx.m13();
-
- d->mv_matrix[1][0] = mtx.m21();
- d->mv_matrix[1][1] = mtx.m22();
- d->mv_matrix[1][2] = 0;
- d->mv_matrix[1][3] = mtx.m23();
-
- d->mv_matrix[2][0] = 0;
- d->mv_matrix[2][1] = 0;
- d->mv_matrix[2][2] = 1;
- d->mv_matrix[2][3] = 0;
-
- d->mv_matrix[3][0] = mtx.dx();
- d->mv_matrix[3][1] = mtx.dy();
- d->mv_matrix[3][2] = 0;
- d->mv_matrix[3][3] = mtx.m33();
-
- d->txop = mtx.type();
-
- // 1/10000 == 0.0001, so we have good enough res to cover curves
- // that span the entire widget...
- d->inverseScale = qMax(1 / qMax( qMax(qAbs(mtx.m11()), qAbs(mtx.m22())),
- qMax(qAbs(mtx.m12()), qAbs(mtx.m21())) ),
- qreal(0.0001));
-
- d->updateGLMatrix();
- d->updateFastPen();
-}
-
-void QOpenGLPaintEnginePrivate::updateGLMatrix() const
-{
- glMatrixMode(GL_MODELVIEW);
-#ifndef QT_OPENGL_ES
- glLoadMatrixd(&mv_matrix[0][0]);
-#else
- glLoadMatrixf(&mv_matrix[0][0]);
-#endif
-}
-
-void QOpenGLPaintEnginePrivate::disableClipping()
-{
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
-}
-
-void QOpenGLPaintEnginePrivate::enableClipping()
-{
- Q_Q(QOpenGLPaintEngine);
- if (!q->state()->hasClipping)
- return;
-
- if (q->state()->fastClip.isEmpty())
- glEnable(GL_DEPTH_TEST);
- else
- updateDepthClip(); // this will enable the scissor test
-}
-
-void QOpenGLPaintEnginePrivate::updateDepthClip()
-{
- Q_Q(QOpenGLPaintEngine);
-
- ++q->state()->depthClipId;
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
-
- if (!q->state()->hasClipping)
- return;
-
- QRect fastClip;
- if (q->state()->clipEnabled) {
- fastClip = q->state()->fastClip;
- } else if (use_system_clip && q->systemClip().rects().count() == 1) {
- fastClip = q->systemClip().rects().at(0);
- }
-
- if (!fastClip.isEmpty()) {
- glEnable(GL_SCISSOR_TEST);
-
- const int left = fastClip.left();
- const int width = fastClip.width();
- const int bottom = device->size().height() - (fastClip.bottom() + 1);
- const int height = fastClip.height();
-
- glScissor(left, bottom, width, height);
- return;
- }
-
-#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_2)
- glClearDepthf(0.0f);
-#else
- glClearDepth(0.0f);
-#endif
-
- glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_TRUE);
- glClear(GL_DEPTH_BUFFER_BIT);
-
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- glDepthFunc(GL_ALWAYS);
-
- const QVector<QRect> rects = q->state()->clipEnabled ? q->state()->clipRegion.rects() : q->systemClip().rects();
-
- // rectangle count * 2 (triangles) * vertex count * component count (Z omitted)
- QDataBuffer<GLfloat> clipVertex(rects.size()*2*3*2);
- for (int i = 0; i < rects.size(); ++i) {
- GLfloat x = GLfloat(rects.at(i).left());
- GLfloat w = GLfloat(rects.at(i).width());
- GLfloat h = GLfloat(rects.at(i).height());
- GLfloat y = GLfloat(rects.at(i).top());
-
- // First triangle
- clipVertex.add(x);
- clipVertex.add(y);
-
- clipVertex.add(x);
- clipVertex.add(y + h);
-
- clipVertex.add(x + w);
- clipVertex.add(y);
-
- // Second triangle
- clipVertex.add(x);
- clipVertex.add(y + h);
-
- clipVertex.add(x + w);
- clipVertex.add(y + h);
-
- clipVertex.add (x + w);
- clipVertex.add(y);
- }
-
- if (rects.size()) {
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, clipVertex.data());
-
- glDrawArrays(GL_TRIANGLES, 0, rects.size()*2*3);
- glDisableClientState(GL_VERTEX_ARRAY);
- updateGLMatrix();
- }
-
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glDepthMask(GL_FALSE);
- glDepthFunc(GL_LEQUAL);
-}
-
-void QOpenGLPaintEnginePrivate::systemStateChanged()
-{
- Q_Q(QOpenGLPaintEngine);
- if (q->painter()->hasClipping())
- q->updateClipRegion(q->painter()->clipRegion(), Qt::ReplaceClip);
- else
- q->updateClipRegion(QRegion(), Qt::NoClip);
-}
-
-void QOpenGLPaintEngine::updateClipRegion(const QRegion &clipRegion, Qt::ClipOperation op)
-{
- Q_D(QOpenGLPaintEngine);
-
- // clipping is only supported when a stencil or depth buffer is
- // available
- if (!d->device->format().depth())
- return;
-
- d->use_system_clip = false;
- QRegion sysClip = systemClip();
- if (!sysClip.isEmpty()) {
- if (d->pdev->devType() != QInternal::Widget) {
- d->use_system_clip = true;
- } else {
-#ifndef Q_WS_QWS
- // Only use the system clip if we're currently rendering a widget with a GL painter.
- if (d->currentClipWidget) {
- QWidgetPrivate *widgetPrivate = qt_widget_private(d->currentClipWidget->window());
- d->use_system_clip = widgetPrivate->extra && widgetPrivate->extra->inRenderWithPainter;
- }
-#endif
- }
- }
-
- d->flushDrawQueue();
-
- if (op == Qt::NoClip && !d->use_system_clip) {
- state()->hasClipping = false;
- state()->clipRegion = QRegion();
- d->updateDepthClip();
- return;
- }
-
- bool isScreenClip = false;
- if (!d->use_system_clip) {
- QVector<QRect> untransformedRects = clipRegion.rects();
-
- if (untransformedRects.size() == 1) {
- QPainterPath path;
- path.addRect(untransformedRects[0]);
- path = d->matrix.map(path);
-
- if (path.contains(QRectF(QPointF(), d->device->size())))
- isScreenClip = true;
- }
- }
-
- QRegion region = isScreenClip ? QRegion() : clipRegion * d->matrix;
- switch (op) {
- case Qt::NoClip:
- if (!d->use_system_clip)
- break;
- state()->clipRegion = sysClip;
- break;
- case Qt::IntersectClip:
- if (isScreenClip)
- return;
- if (state()->hasClipping) {
- state()->clipRegion &= region;
- break;
- }
- // fall through
- case Qt::ReplaceClip:
- if (d->use_system_clip)
- state()->clipRegion = region & sysClip;
- else
- state()->clipRegion = region;
- break;
- default:
- break;
- }
-
- if (isScreenClip) {
- state()->hasClipping = false;
- state()->clipRegion = QRegion();
- } else {
- state()->hasClipping = op != Qt::NoClip || d->use_system_clip;
- }
-
- if (state()->hasClipping && state()->clipRegion.rects().size() == 1)
- state()->fastClip = state()->clipRegion.rects().at(0);
- else
- state()->fastClip = QRect();
-
- d->updateDepthClip();
-}
-
-void QOpenGLPaintEngine::updateRenderHints(QPainter::RenderHints hints)
-{
- Q_D(QOpenGLPaintEngine);
-
- d->flushDrawQueue();
- d->use_smooth_pixmap_transform = bool(hints & QPainter::SmoothPixmapTransform);
- if ((hints & QPainter::Antialiasing) || (hints & QPainter::HighQualityAntialiasing)) {
- if (d->use_fragment_programs && QGLOffscreen::isSupported()
- && (hints & QPainter::HighQualityAntialiasing)) {
- d->high_quality_antialiasing = true;
- } else {
- d->high_quality_antialiasing = false;
- if (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers)
- glEnable(GL_MULTISAMPLE);
- }
- } else {
- d->high_quality_antialiasing = false;
- if (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers)
- glDisable(GL_MULTISAMPLE);
- }
-
- if (d->high_quality_antialiasing) {
- d->offscreen.initialize();
-
- if (!d->offscreen.isValid()) {
- DEBUG_ONCE_STR("Unable to initialize offscreen, disabling high quality antialiasing");
- d->high_quality_antialiasing = false;
- if (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers)
- glEnable(GL_MULTISAMPLE);
- }
- }
-
- d->has_antialiasing = d->high_quality_antialiasing
- || ((hints & QPainter::Antialiasing)
- && (QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers));
-}
-
-
-void QOpenGLPaintEnginePrivate::setPorterDuffData(float a, float b, float x, float y, float z)
-{
- porterduff_ab_data[0] = a;
- porterduff_ab_data[1] = b;
-
- porterduff_xyz_data[0] = x;
- porterduff_xyz_data[1] = y;
- porterduff_xyz_data[2] = z;
-}
-
-
-void QOpenGLPaintEngine::updateCompositionMode(QPainter::CompositionMode composition_mode)
-{
- Q_D(QOpenGLPaintEngine);
-
- if (!d->use_fragment_programs && composition_mode > QPainter::CompositionMode_Plus)
- composition_mode = QPainter::CompositionMode_SourceOver;
-
- d->composition_mode = composition_mode;
-
- d->has_fast_composition_mode = (!d->high_quality_antialiasing && composition_mode <= QPainter::CompositionMode_Plus)
- || composition_mode == QPainter::CompositionMode_SourceOver
- || composition_mode == QPainter::CompositionMode_Destination
- || composition_mode == QPainter::CompositionMode_DestinationOver
- || composition_mode == QPainter::CompositionMode_DestinationOut
- || composition_mode == QPainter::CompositionMode_SourceAtop
- || composition_mode == QPainter::CompositionMode_Xor
- || composition_mode == QPainter::CompositionMode_Plus;
-
- if (d->has_fast_composition_mode)
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODE_BLEND_MODE_MASK : COMPOSITION_MODE_BLEND_MODE_NOMASK;
- else if (composition_mode <= QPainter::CompositionMode_Plus)
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_SIMPLE_PORTER_DUFF : COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK;
- else
- switch (composition_mode) {
- case QPainter::CompositionMode_Multiply:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_MULTIPLY : COMPOSITION_MODES_MULTIPLY_NOMASK;
- break;
- case QPainter::CompositionMode_Screen:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_SCREEN : COMPOSITION_MODES_SCREEN_NOMASK;
- break;
- case QPainter::CompositionMode_Overlay:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_OVERLAY : COMPOSITION_MODES_OVERLAY_NOMASK;
- break;
- case QPainter::CompositionMode_Darken:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_DARKEN : COMPOSITION_MODES_DARKEN_NOMASK;
- break;
- case QPainter::CompositionMode_Lighten:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_LIGHTEN : COMPOSITION_MODES_LIGHTEN_NOMASK;
- break;
- case QPainter::CompositionMode_ColorDodge:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_COLORDODGE : COMPOSITION_MODES_COLORDODGE_NOMASK;
- break;
- case QPainter::CompositionMode_ColorBurn:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_COLORBURN : COMPOSITION_MODES_COLORBURN_NOMASK;
- break;
- case QPainter::CompositionMode_HardLight:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_HARDLIGHT : COMPOSITION_MODES_HARDLIGHT_NOMASK;
- break;
- case QPainter::CompositionMode_SoftLight:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_SOFTLIGHT : COMPOSITION_MODES_SOFTLIGHT_NOMASK;
- break;
- case QPainter::CompositionMode_Difference:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_DIFFERENCE : COMPOSITION_MODES_DIFFERENCE_NOMASK;
- break;
- case QPainter::CompositionMode_Exclusion:
- d->fragment_composition_mode = d->high_quality_antialiasing ? COMPOSITION_MODES_EXCLUSION : COMPOSITION_MODES_EXCLUSION_NOMASK;
- break;
- default:
- Q_ASSERT(false);
- }
-
- switch(composition_mode) {
- case QPainter::CompositionMode_DestinationOver:
- glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);
- d->setPorterDuffData(0, 1, 1, 1, 1);
- break;
- case QPainter::CompositionMode_Clear:
- glBlendFunc(GL_ZERO, GL_ZERO);
- d->setPorterDuffData(0, 0, 0, 0, 0);
- break;
- case QPainter::CompositionMode_Source:
- glBlendFunc(GL_ONE, GL_ZERO);
- d->setPorterDuffData(1, 0, 1, 1, 0);
- break;
- case QPainter::CompositionMode_Destination:
- glBlendFunc(GL_ZERO, GL_ONE);
- d->setPorterDuffData(0, 1, 1, 0, 1);
- break;
- case QPainter::CompositionMode_SourceIn:
- glBlendFunc(GL_DST_ALPHA, GL_ZERO);
- d->setPorterDuffData(1, 0, 1, 0, 0);
- break;
- case QPainter::CompositionMode_DestinationIn:
- glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
- d->setPorterDuffData(0, 1, 1, 0, 0);
- break;
- case QPainter::CompositionMode_SourceOut:
- glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO);
- d->setPorterDuffData(0, 0, 0, 1, 0);
- break;
- case QPainter::CompositionMode_DestinationOut:
- glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
- d->setPorterDuffData(0, 0, 0, 0, 1);
- break;
- case QPainter::CompositionMode_SourceAtop:
- glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- d->setPorterDuffData(1, 0, 1, 0, 1);
- break;
- case QPainter::CompositionMode_DestinationAtop:
- glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA);
- d->setPorterDuffData(0, 1, 1, 1, 0);
- break;
- case QPainter::CompositionMode_Xor:
- glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- d->setPorterDuffData(0, 0, 0, 1, 1);
- break;
- case QPainter::CompositionMode_SourceOver:
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- d->setPorterDuffData(1, 0, 1, 1, 1);
- break;
- case QPainter::CompositionMode_Plus:
- glBlendFunc(GL_ONE, GL_ONE);
- d->setPorterDuffData(1, 1, 1, 1, 1);
- break;
- default:
- break;
- }
-}
-
-class QGLMaskGenerator
-{
-public:
- QGLMaskGenerator(const QPainterPath &path, const QTransform &matrix, qreal stroke_width = -1)
- : p(path),
- m(matrix),
- w(stroke_width)
- {
- }
-
- virtual QRect screenRect() = 0;
- virtual void drawMask(const QRect &rect) = 0;
-
- QPainterPath path() const { return p; }
- QTransform matrix() const { return m; }
- qreal strokeWidth() const { return w; }
-
- virtual ~QGLMaskGenerator() {}
-
-private:
- QPainterPath p;
- QTransform m;
- qreal w;
-};
-
-void QGLMaskTextureCache::setOffscreenSize(const QSize &sz)
-{
- Q_ASSERT(sz.width() == sz.height());
-
- if (offscreenSize != sz) {
- offscreenSize = sz;
- clearCache();
- }
-}
-
-void QGLMaskTextureCache::clearCache()
-{
- cache.clear();
-
- int quad_tree_size = 1;
-
- for (int i = block_size; i < offscreenSize.width(); i *= 2)
- quad_tree_size += quad_tree_size * 4;
-
- for (int i = 0; i < 4; ++i) {
- occupied_quadtree[i].resize(quad_tree_size);
-
- occupied_quadtree[i][0].key = 0;
- occupied_quadtree[i][0].largest_available_block = offscreenSize.width();
- occupied_quadtree[i][0].largest_used_block = 0;
-
- DEBUG_ONCE qDebug() << "QGLMaskTextureCache:: created quad tree of size" << quad_tree_size;
- }
-}
-
-void QGLMaskTextureCache::setDrawableSize(const QSize &sz)
-{
- drawableSize = sz;
-}
-
-void QGLMaskTextureCache::maintainCache()
-{
- QGLTextureCacheHash::iterator it = cache.begin();
- QGLTextureCacheHash::iterator end = cache.end();
-
- while (it != end) {
- CacheInfo &cache_info = it.value();
- ++cache_info.age;
-
- if (cache_info.age > 1) {
- quadtreeInsert(cache_info.loc.channel, 0, cache_info.loc.rect);
- it = cache.erase(it);
- } else {
- ++it;
- }
- }
-}
-
-//#define DISABLE_MASK_CACHE
-
-QGLMaskTextureCache::CacheLocation QGLMaskTextureCache::getMask(QGLMaskGenerator &maskGenerator, QOpenGLPaintEnginePrivate *e)
-{
-#ifndef DISABLE_MASK_CACHE
- engine = e;
-
- quint64 key = hash(maskGenerator.path(), maskGenerator.matrix(), maskGenerator.strokeWidth());
-
- if (key == 0)
- key = 1;
-
- CacheInfo info(maskGenerator.path(), maskGenerator.matrix(), maskGenerator.strokeWidth());
-
- QGLTextureCacheHash::iterator it = cache.find(key);
-
- while (it != cache.end() && it.key() == key) {
- CacheInfo &cache_info = it.value();
- if (info.stroke_width == cache_info.stroke_width && info.matrix == cache_info.matrix && info.path == cache_info.path) {
- DEBUG_ONCE_STR("QGLMaskTextureCache::getMask(): Using cached mask");
-
- cache_info.age = 0;
- return cache_info.loc;
- }
- ++it;
- }
-
- // mask was not found, create new mask
-
- DEBUG_ONCE_STR("QGLMaskTextureCache::getMask(): Creating new mask...");
-
- createMask(key, info, maskGenerator);
-
- cache.insert(key, info);
-
- return info.loc;
-#else
- CacheInfo info(maskGenerator.path(), maskGenerator.matrix());
- createMask(0, info, maskGenerator);
- return info.loc;
-#endif
-}
-
-#ifndef FloatToQuint64
-#define FloatToQuint64(i) (quint64)((i) * 32)
-#endif
-
-quint64 QGLMaskTextureCache::hash(const QPainterPath &p, const QTransform &m, qreal w)
-{
- Q_ASSERT(sizeof(quint64) == 8);
-
- quint64 h = 0;
-
- for (int i = 0; i < p.elementCount(); ++i) {
- h += FloatToQuint64(p.elementAt(i).x) << 32;
- h += FloatToQuint64(p.elementAt(i).y);
- h += p.elementAt(i).type;
- }
-
- h += FloatToQuint64(m.m11());
-#ifndef Q_OS_WINCE // ###
- //Compiler crashes for arm on WinCE
- h += FloatToQuint64(m.m12()) << 4;
- h += FloatToQuint64(m.m13()) << 8;
- h += FloatToQuint64(m.m21()) << 12;
- h += FloatToQuint64(m.m22()) << 16;
- h += FloatToQuint64(m.m23()) << 20;
- h += FloatToQuint64(m.m31()) << 24;
- h += FloatToQuint64(m.m32()) << 28;
-#endif
- h += FloatToQuint64(m.m33()) << 32;
-
- h += FloatToQuint64(w);
-
- return h;
-}
-
-void QGLMaskTextureCache::createMask(quint64 key, CacheInfo &info, QGLMaskGenerator &maskGenerator)
-{
- info.loc.screen_rect = maskGenerator.screenRect();
-
- if (info.loc.screen_rect.isEmpty()) {
- info.loc.channel = 0;
- info.loc.rect = QRect();
- return;
- }
-
- quadtreeAllocate(key, info.loc.screen_rect.size(), &info.loc.rect, &info.loc.channel);
-
- int ch = info.loc.channel;
- glColorMask(ch == 0, ch == 1, ch == 2, ch == 3);
-
- maskGenerator.drawMask(info.loc.rect);
-
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-}
-
-int QGLMaskTextureCache::quadtreeBlocksize(int node)
-{
- DEBUG_ONCE qDebug() << "Offscreen size:" << offscreenSize.width();
-
- int blocksize = offscreenSize.width();
-
- while (node) {
- node = (node - 1) / 4;
- blocksize /= 2;
- }
-
- return blocksize;
-}
-
-QPoint QGLMaskTextureCache::quadtreeLocation(int node)
-{
- QPoint location;
- int blocksize = quadtreeBlocksize(node);
-
- while (node) {
- --node;
-
- if (node & 1)
- location.setX(location.x() + blocksize);
-
- if (node & 2)
- location.setY(location.y() + blocksize);
-
- node /= 4;
- blocksize *= 2;
- }
-
- return location;
-}
-
-void QGLMaskTextureCache::quadtreeUpdate(int channel, int node, int current_block_size)
-{
- while (node) {
- node = (node - 1) / 4;
-
- int first_child = node * 4 + 1;
-
- int largest_available = 0;
- int largest_used = 0;
-
- bool all_empty = true;
-
- for (int i = 0; i < 4; ++i) {
- largest_available = qMax(largest_available, occupied_quadtree[channel][first_child + i].largest_available_block);
- largest_used = qMax(largest_used, occupied_quadtree[channel][first_child + i].largest_used_block);
-
- if (occupied_quadtree[channel][first_child + i].largest_available_block < current_block_size)
- all_empty = false;
- }
-
- current_block_size *= 2;
-
- if (all_empty) {
- occupied_quadtree[channel][node].largest_available_block = current_block_size;
- occupied_quadtree[channel][node].largest_used_block = 0;
- } else {
- occupied_quadtree[channel][node].largest_available_block = largest_available;
- occupied_quadtree[channel][node].largest_used_block = largest_used;
- }
- }
-}
-
-void QGLMaskTextureCache::quadtreeInsert(int channel, quint64 key, const QRect &rect, int node)
-{
- int current_block_size = quadtreeBlocksize(node);
- QPoint location = quadtreeLocation(node);
- QRect relative = rect.translated(-location);
-
- if (relative.left() >= current_block_size || relative.top() >= current_block_size
- || relative.right() < 0 || relative.bottom() < 0)
- return;
-
- if (current_block_size == block_size // no more refining possible
- || (relative.top() < block_size && relative.bottom() >= (current_block_size - block_size)
- && relative.left() < block_size && relative.right() >= (current_block_size - block_size)))
- {
- if (key != 0) {
- occupied_quadtree[channel][node].largest_available_block = 0;
- occupied_quadtree[channel][node].largest_used_block = rect.width() * rect.height();
- } else {
- occupied_quadtree[channel][node].largest_available_block = current_block_size;
- occupied_quadtree[channel][node].largest_used_block = 0;
- }
-
- occupied_quadtree[channel][node].key = key;
-
- quadtreeUpdate(channel, node, current_block_size);
- } else {
- if (key && occupied_quadtree[channel][node].largest_available_block == current_block_size) {
- // refining the quad tree, initialize child nodes
- int half_block_size = current_block_size / 2;
-
- int temp = node * 4 + 1;
- for (int sibling = 0; sibling < 4; ++sibling) {
- occupied_quadtree[channel][temp + sibling].largest_available_block = half_block_size;
- occupied_quadtree[channel][temp + sibling].largest_used_block = 0;
- occupied_quadtree[channel][temp + sibling].key = 0;
- }
- }
-
- node = node * 4 + 1;
-
- for (int sibling = 0; sibling < 4; ++sibling)
- quadtreeInsert(channel, key, rect, node + sibling);
- }
-}
-
-void QGLMaskTextureCache::quadtreeClear(int channel, const QRect &rect, int node)
-{
- const quint64 &key = occupied_quadtree[channel][node].key;
-
- int current_block_size = quadtreeBlocksize(node);
- QPoint location = quadtreeLocation(node);
-
- QRect relative = rect.translated(-location);
-
- if (relative.left() >= current_block_size || relative.top() >= current_block_size
- || relative.right() < 0 || relative.bottom() < 0)
- return;
-
- if (key != 0) {
- QGLTextureCacheHash::iterator it = cache.find(key);
-
- Q_ASSERT(it != cache.end());
-
- while (it != cache.end() && it.key() == key) {
- const CacheInfo &cache_info = it.value();
-
- if (cache_info.loc.channel == channel
- && cache_info.loc.rect.left() <= location.x()
- && cache_info.loc.rect.top() <= location.y()
- && cache_info.loc.rect.right() >= location.x()
- && cache_info.loc.rect.bottom() >= location.y())
- {
- quadtreeInsert(channel, 0, cache_info.loc.rect);
- engine->cacheItemErased(channel, cache_info.loc.rect);
- cache.erase(it);
- goto found;
- } else {
- ++it;
- }
- }
-
- // if we don't find the key there's an error in the quadtree
- Q_ASSERT(false);
-found:
- Q_ASSERT(occupied_quadtree[channel][node].key == 0);
- } else if (occupied_quadtree[channel][node].largest_available_block < current_block_size) {
- Q_ASSERT(current_block_size >= block_size);
-
- node = node * 4 + 1;
-
- for (int sibling = 0; sibling < 4; ++sibling)
- quadtreeClear(channel, rect, node + sibling);
- }
-}
-
-bool QGLMaskTextureCache::quadtreeFindAvailableLocation(const QSize &size, QRect *rect, int *channel)
-{
- int needed_block_size = qMax(1, qMax(size.width(), size.height()));
-
- for (int i = 0; i < 4; ++i) {
- int current_block_size = offscreenSize.width();
-
- if (occupied_quadtree[i][0].largest_available_block >= needed_block_size) {
- int node = 0;
-
- while (current_block_size != occupied_quadtree[i][node].largest_available_block) {
- Q_ASSERT(current_block_size > block_size);
- Q_ASSERT(current_block_size > occupied_quadtree[i][node].largest_available_block);
-
- node = node * 4 + 1;
- current_block_size /= 2;
-
- int sibling = 0;
-
- while (occupied_quadtree[i][node + sibling].largest_available_block < needed_block_size)
- ++sibling;
-
- Q_ASSERT(sibling < 4);
- node += sibling;
- }
-
- *channel = i;
- *rect = QRect(quadtreeLocation(node), size);
-
- return true;
- }
- }
-
- return false;
-}
-
-void QGLMaskTextureCache::quadtreeFindExistingLocation(const QSize &size, QRect *rect, int *channel)
-{
- // try to pick small masks to throw out, as large masks are more expensive to recompute
- *channel = qrand() % 4;
- for (int i = 0; i < 4; ++i)
- if (occupied_quadtree[i][0].largest_used_block < occupied_quadtree[*channel][0].largest_used_block)
- *channel = i;
-
- int needed_block_size = qt_next_power_of_two(qMax(1, qMax(size.width(), size.height())));
-
- int node = 0;
- int current_block_size = offscreenSize.width();
-
- while (current_block_size > block_size
- && current_block_size >= needed_block_size * 2
- && occupied_quadtree[*channel][node].key == 0)
- {
- node = node * 4 + 1;
-
- int sibling = 0;
-
- for (int i = 1; i < 4; ++i) {
- if (occupied_quadtree[*channel][node + i].largest_used_block
- <= occupied_quadtree[*channel][node + sibling].largest_used_block)
- {
- sibling = i;
- }
- }
-
- node += sibling;
- current_block_size /= 2;
- }
-
- *rect = QRect(quadtreeLocation(node), size);
-}
-
-void QGLMaskTextureCache::quadtreeAllocate(quint64 key, const QSize &size, QRect *rect, int *channel)
-{
-#ifndef DISABLE_MASK_CACHE
- if (!quadtreeFindAvailableLocation(size, rect, channel)) {
- quadtreeFindExistingLocation(size, rect, channel);
- quadtreeClear(*channel, *rect);
- }
-
- quadtreeInsert(*channel, key, *rect);
-#else
- *channel = 0;
- *rect = QRect(QPoint(), size);
-#endif
-}
-
-class QGLTrapezoidMaskGenerator : public QGLMaskGenerator
-{
-public:
- QGLTrapezoidMaskGenerator(const QPainterPath &path, const QTransform &matrix, QGLOffscreen &offscreen, GLuint maskFragmentProgram, qreal strokeWidth = -1.0);
-
- QRect screenRect();
- void drawMask(const QRect &rect);
-
-private:
- QRect screen_rect;
- bool has_screen_rect;
-
- QGLOffscreen *offscreen;
-
- GLuint maskFragmentProgram;
-
- virtual QVector<QGLTrapezoid> generateTrapezoids() = 0;
- virtual QRect computeScreenRect() = 0;
-};
-
-class QGLPathMaskGenerator : public QGLTrapezoidMaskGenerator
-{
-public:
- QGLPathMaskGenerator(const QPainterPath &path, const QTransform &matrix, QGLOffscreen &offscreen, GLuint maskFragmentProgram);
-
-private:
- QVector<QGLTrapezoid> generateTrapezoids();
- QRect computeScreenRect();
-
- QPolygonF poly;
-};
-
-class QGLLineMaskGenerator : public QGLTrapezoidMaskGenerator
-{
-public:
- QGLLineMaskGenerator(const QPainterPath &path, const QTransform &matrix, qreal width, QGLOffscreen &offscreen, GLuint maskFragmentProgram);
-
-private:
- QVector<QGLTrapezoid> generateTrapezoids();
- QRect computeScreenRect();
-
- QPainterPath transformedPath;
-};
-
-class QGLRectMaskGenerator : public QGLTrapezoidMaskGenerator
-{
-public:
- QGLRectMaskGenerator(const QPainterPath &path, const QTransform &matrix, QGLOffscreen &offscreen, GLuint maskFragmentProgram);
-
-private:
- QVector<QGLTrapezoid> generateTrapezoids();
- QRect computeScreenRect();
-
- QPainterPath transformedPath;
-};
-
-class QGLEllipseMaskGenerator : public QGLMaskGenerator
-{
-public:
- QGLEllipseMaskGenerator(const QRectF &rect, const QTransform &matrix, QGLOffscreen &offscreen, GLuint maskFragmentProgram, int *maskVariableLocations);
-
- QRect screenRect();
- void drawMask(const QRect &rect);
-
-private:
- QRect screen_rect;
-
- QRectF ellipseRect;
-
- QGLOffscreen *offscreen;
-
- GLuint maskFragmentProgram;
-
- int *maskVariableLocations;
-
- float vertexArray[4 * 2];
-};
-
-QGLTrapezoidMaskGenerator::QGLTrapezoidMaskGenerator(const QPainterPath &path, const QTransform &matrix, QGLOffscreen &offs, GLuint program, qreal stroke_width)
- : QGLMaskGenerator(path, matrix, stroke_width)
- , has_screen_rect(false)
- , offscreen(&offs)
- , maskFragmentProgram(program)
-{
-}
-
-extern void qt_add_rect_to_array(const QRectF &r, GLfloat *array);
-extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, GLfloat *array);
-
-void QGLTrapezoidMaskGenerator::drawMask(const QRect &rect)
-{
-#ifdef QT_OPENGL_ES
- Q_UNUSED(rect);
-#else
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- QGLContext *ctx = offscreen->context();
- offscreen->bind();
-
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_1D);
-
- GLfloat vertexArray[4 * 2];
- qt_add_rect_to_array(rect, vertexArray);
-
- bool needs_scissor = rect != screen_rect;
-
- if (needs_scissor) {
- glEnable(GL_SCISSOR_TEST);
- glScissor(rect.left(), offscreen->offscreenSize().height() - rect.bottom() - 1, rect.width(), rect.height());
- }
-
- QVector<QGLTrapezoid> trapezoids = generateTrapezoids();
-
- // clear mask
- glBlendFunc(GL_ZERO, GL_ZERO); // clear
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glEnableClientState(GL_VERTEX_ARRAY);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- glBlendFunc(GL_ONE, GL_ONE); // add mask
- glEnable(GL_FRAGMENT_PROGRAM_ARB);
- glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, maskFragmentProgram);
-
- QPoint delta = rect.topLeft() - screen_rect.topLeft();
- glBegin(GL_QUADS);
- for (int i = 0; i < trapezoids.size(); ++i)
- drawTrapezoid(trapezoids[i].translated(delta), offscreen->offscreenSize().height(), ctx);
- glEnd();
-
- if (needs_scissor)
- glDisable(GL_SCISSOR_TEST);
-
- glDisable(GL_FRAGMENT_PROGRAM_ARB);
-
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
-#endif
-}
-
-QRect QGLTrapezoidMaskGenerator::screenRect()
-{
- if (!has_screen_rect) {
- screen_rect = computeScreenRect();
- has_screen_rect = true;
- }
-
- screen_rect = screen_rect.intersected(QRect(QPoint(), offscreen->drawableSize()));
-
- return screen_rect;
-}
-
-QGLPathMaskGenerator::QGLPathMaskGenerator(const QPainterPath &path, const QTransform &matrix, QGLOffscreen &offs, GLuint program)
- : QGLTrapezoidMaskGenerator(path, matrix, offs, program)
-{
-}
-
-QRect QGLPathMaskGenerator::computeScreenRect()
-{
- poly = path().toFillPolygon(matrix());
- return poly.boundingRect().toAlignedRect();
-}
-
-QVector<QGLTrapezoid> QGLPathMaskGenerator::generateTrapezoids()
-{
- QOpenGLImmediateModeTessellator tessellator;
- tessellator.tessellate(poly.data(), poly.count(), path().fillRule() == Qt::WindingFill);
- return tessellator.trapezoids;
-}
-
-QGLRectMaskGenerator::QGLRectMaskGenerator(const QPainterPath &path, const QTransform &matrix, QGLOffscreen &offs, GLuint program)
- : QGLTrapezoidMaskGenerator(path, matrix, offs, program)
-{
-}
-
-QGLLineMaskGenerator::QGLLineMaskGenerator(const QPainterPath &path, const QTransform &matrix, qreal width, QGLOffscreen &offs, GLuint program)
- : QGLTrapezoidMaskGenerator(path, matrix, offs, program, width)
-{
-}
-
-QRect QGLRectMaskGenerator::computeScreenRect()
-{
- transformedPath = matrix().map(path());
-
- return transformedPath.controlPointRect().adjusted(-1, -1, 1, 1).toAlignedRect();
-}
-
-QRect QGLLineMaskGenerator::computeScreenRect()
-{
- transformedPath = matrix().map(path());
-
- return transformedPath.controlPointRect().adjusted(-1, -1, 1, 1).toAlignedRect();
-}
-
-QVector<QGLTrapezoid> QGLLineMaskGenerator::generateTrapezoids()
-{
- QOpenGLImmediateModeTessellator tessellator;
- QPointF last;
- for (int i = 0; i < transformedPath.elementCount(); ++i) {
- QPainterPath::Element element = transformedPath.elementAt(i);
-
- Q_ASSERT(!element.isCurveTo());
-
- if (element.isLineTo())
- tessellator.tessellateRect(last, element, strokeWidth());
-
- last = element;
- }
-
- return tessellator.trapezoids;
-}
-
-QVector<QGLTrapezoid> QGLRectMaskGenerator::generateTrapezoids()
-{
- Q_ASSERT(transformedPath.elementCount() == 5);
-
- QOpenGLImmediateModeTessellator tessellator;
- if (matrix().type() <= QTransform::TxScale) {
- QPointF a = transformedPath.elementAt(0);
- QPointF b = transformedPath.elementAt(1);
- QPointF c = transformedPath.elementAt(2);
- QPointF d = transformedPath.elementAt(3);
-
- QPointF first = (a + d) * 0.5;
- QPointF last = (b + c) * 0.5;
-
- QPointF delta = a - d;
-
- // manhattan distance (no rotation)
- qreal width = qAbs(delta.x()) + qAbs(delta.y());
-
- Q_ASSERT(qFuzzyIsNull(delta.x()) || qFuzzyIsNull(delta.y()));
-
- tessellator.tessellateRect(first, last, width);
- } else {
- QPointF points[5];
-
- for (int i = 0; i < 5; ++i)
- points[i] = transformedPath.elementAt(i);
-
- tessellator.tessellateConvex(points, 5);
- }
- return tessellator.trapezoids;
-}
-
-static QPainterPath ellipseRectToPath(const QRectF &rect)
-{
- QPainterPath path;
- path.addEllipse(rect);
- return path;
-}
-
-QGLEllipseMaskGenerator::QGLEllipseMaskGenerator(const QRectF &rect, const QTransform &matrix, QGLOffscreen &offs, GLuint program, int *locations)
- : QGLMaskGenerator(ellipseRectToPath(rect), matrix),
- ellipseRect(rect),
- offscreen(&offs),
- maskFragmentProgram(program),
- maskVariableLocations(locations)
-{
-}
-
-QRect QGLEllipseMaskGenerator::screenRect()
-{
- QPointF center = ellipseRect.center();
-
- QPointF points[] = {
- QPointF(ellipseRect.left(), center.y()),
- QPointF(ellipseRect.right(), center.y()),
- QPointF(center.x(), ellipseRect.top()),
- QPointF(center.x(), ellipseRect.bottom())
- };
-
- qreal min_screen_delta_len = QREAL_MAX;
-
- for (int i = 0; i < 4; ++i) {
- QPointF delta = points[i] - center;
-
- // normalize
- delta /= qSqrt(delta.x() * delta.x() + delta.y() * delta.y());
-
- QPointF screen_delta(matrix().m11() * delta.x() + matrix().m21() * delta.y(),
- matrix().m12() * delta.x() + matrix().m22() * delta.y());
-
- min_screen_delta_len = qMin(min_screen_delta_len,
- qreal(qSqrt(screen_delta.x() * screen_delta.x() + screen_delta.y() * screen_delta.y())));
- }
-
- const qreal padding = 2.0f;
-
- qreal grow = padding / min_screen_delta_len;
-
- QRectF boundingRect = ellipseRect.adjusted(-grow, -grow, grow, grow);
-
- boundingRect = matrix().mapRect(boundingRect);
-
- QPointF p(0.5, 0.5);
-
- screen_rect = QRect((boundingRect.topLeft() - p).toPoint(),
- (boundingRect.bottomRight() + p).toPoint());
-
- return screen_rect;
-}
-
-void QGLEllipseMaskGenerator::drawMask(const QRect &rect)
-{
-#ifdef QT_OPENGL_ES
- Q_UNUSED(rect);
-#else
- QGLContext *ctx = offscreen->context();
- offscreen->bind();
-
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_1D);
-
- // fragment program needs the inverse radii of the ellipse
- glTexCoord2f(1.0f / (ellipseRect.width() * 0.5f),
- 1.0f / (ellipseRect.height() * 0.5f));
-
- QTransform translate(1, 0, 0, 1, -ellipseRect.center().x(), -ellipseRect.center().y());
- QTransform gl_to_qt(1, 0, 0, -1, 0, offscreen->drawableSize().height());
- QTransform inv_matrix = gl_to_qt * matrix().inverted() * translate;
-
- float m[3][4] = { { float(inv_matrix.m11()), float(inv_matrix.m12()), float(inv_matrix.m13()) },
- { float(inv_matrix.m21()), float(inv_matrix.m22()), float(inv_matrix.m23()) },
- { float(inv_matrix.m31()), float(inv_matrix.m32()), float(inv_matrix.m33()) } };
-
- QPoint offs(screen_rect.left() - rect.left(), (offscreen->drawableSize().height() - screen_rect.top())
- - (offscreen->offscreenSize().height() - rect.top()));
-
- // last component needs to be 1.0f to avoid Nvidia bug on linux
- float ellipse_offset[4] = { float(offs.x()), float(offs.y()), 0.0f, 1.0f };
-
- GLfloat vertexArray[4 * 2];
- qt_add_rect_to_array(rect, vertexArray);
-
- glBlendFunc(GL_ONE, GL_ZERO); // set mask
- glEnable(GL_FRAGMENT_PROGRAM_ARB);
- glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, maskFragmentProgram);
-
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, maskVariableLocations[VAR_INV_MATRIX_M0], m[0]);
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, maskVariableLocations[VAR_INV_MATRIX_M1], m[1]);
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, maskVariableLocations[VAR_INV_MATRIX_M2], m[2]);
-
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, maskVariableLocations[VAR_ELLIPSE_OFFSET], ellipse_offset);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisable(GL_FRAGMENT_PROGRAM_ARB);
-#endif
-}
-
-void QOpenGLPaintEnginePrivate::drawOffscreenPath(const QPainterPath &path)
-{
-#ifdef Q_WS_QWS
- Q_UNUSED(path);
-#else
- DEBUG_ONCE_STR("QOpenGLPaintEnginePrivate::drawOffscreenPath()");
-
- disableClipping();
-
- GLuint program = qt_gl_program_cache()->getProgram(device->context(),
- FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA, 0, true);
- QGLPathMaskGenerator maskGenerator(path, matrix, offscreen, program);
- addItem(qt_mask_texture_cache()->getMask(maskGenerator, this));
-
- enableClipping();
-#endif
-}
-
-void QOpenGLPaintEnginePrivate::drawFastRect(const QRectF &r)
-{
- Q_Q(QOpenGLPaintEngine);
- DEBUG_ONCE_STR("QOpenGLPaintEngine::drawRects(): drawing fast rect");
-
- GLfloat vertexArray[10];
- qt_add_rect_to_array(r, vertexArray);
-
- if (has_pen)
- QOpenGLCoordinateOffset::enableOffset(this);
-
- if (has_brush) {
- flushDrawQueue();
-
- bool temp = high_quality_antialiasing;
- high_quality_antialiasing = false;
-
- q->updateCompositionMode(composition_mode);
-
- setGradientOps(cbrush, r);
-
- bool fast_style = current_style == Qt::LinearGradientPattern
- || current_style == Qt::SolidPattern;
-
- if (fast_style && has_fast_composition_mode) {
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_VERTEX_ARRAY);
- } else {
- composite(r);
- }
-
- high_quality_antialiasing = temp;
-
- q->updateCompositionMode(composition_mode);
- }
-
- if (has_pen) {
- if (has_fast_pen && !high_quality_antialiasing) {
- setGradientOps(cpen.brush(), r);
-
- vertexArray[8] = vertexArray[0];
- vertexArray[9] = vertexArray[1];
-
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glEnableClientState(GL_VERTEX_ARRAY);
- glDrawArrays(GL_LINE_STRIP, 0, 5);
- glDisableClientState(GL_VERTEX_ARRAY);
- } else {
- QPainterPath path;
- path.setFillRule(Qt::WindingFill);
-
- qreal left = r.left();
- qreal right = r.right();
- qreal top = r.top();
- qreal bottom = r.bottom();
-
- path.moveTo(left, top);
- path.lineTo(right, top);
- path.lineTo(right, bottom);
- path.lineTo(left, bottom);
- path.lineTo(left, top);
-
- strokePath(path, false);
- }
-
- QOpenGLCoordinateOffset::disableOffset(this);
- }
-}
-
-bool QOpenGLPaintEnginePrivate::isFastRect(const QRectF &rect)
-{
- if (matrix.type() < QTransform::TxRotate) {
- QRectF r = matrix.mapRect(rect);
- return r.topLeft().toPoint() == r.topLeft()
- && r.bottomRight().toPoint() == r.bottomRight();
- }
-
- return false;
-}
-
-void QOpenGLPaintEngine::drawRects(const QRect *rects, int rectCount)
-{
- struct RectF {
- qreal x;
- qreal y;
- qreal w;
- qreal h;
- };
- Q_ASSERT(sizeof(RectF) == sizeof(QRectF));
- RectF fr[256];
- while (rectCount) {
- int i = 0;
- while (i < rectCount && i < 256) {
- fr[i].x = rects[i].x();
- fr[i].y = rects[i].y();
- fr[i].w = rects[i].width();
- fr[i].h = rects[i].height();
- ++i;
- }
- drawRects((QRectF *)(void *)fr, i);
- rects += i;
- rectCount -= i;
- }
-}
-
-void QOpenGLPaintEngine::drawRects(const QRectF *rects, int rectCount)
-{
- Q_D(QOpenGLPaintEngine);
-
- if (d->use_emulation) {
- QPaintEngineEx::drawRects(rects, rectCount);
- return;
- }
-
- for (int i=0; i<rectCount; ++i) {
- const QRectF &r = rects[i];
-
- // optimization for rects which can be drawn aliased
- if (!d->high_quality_antialiasing || d->isFastRect(r)) {
- d->drawFastRect(r);
- } else {
- QPainterPath path;
- path.addRect(r);
-
- if (d->has_brush) {
- d->disableClipping();
- GLuint program = qt_gl_program_cache()->getProgram(d->device->context(),
- FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA, 0, true);
-
- if (d->matrix.type() >= QTransform::TxProject) {
- QGLPathMaskGenerator maskGenerator(path, d->matrix, d->offscreen, program);
- d->addItem(qt_mask_texture_cache()->getMask(maskGenerator, d));
- } else {
- QGLRectMaskGenerator maskGenerator(path, d->matrix, d->offscreen, program);
- d->addItem(qt_mask_texture_cache()->getMask(maskGenerator, d));
- }
-
- d->enableClipping();
- }
-
- if (d->has_pen) {
- if (d->has_fast_pen)
- d->strokeLines(path);
- else
- d->strokePath(path, false);
- }
- }
- }
-}
-
-static void addQuadAsTriangle(GLfloat *quad, GLfloat *triangle)
-{
- triangle[0] = quad[0];
- triangle[1] = quad[1];
-
- triangle[2] = quad[2];
- triangle[3] = quad[3];
-
- triangle[4] = quad[4];
- triangle[5] = quad[5];
-
- triangle[6] = quad[4];
- triangle[7] = quad[5];
-
- triangle[8] = quad[6];
- triangle[9] = quad[7];
-
- triangle[10] = quad[0];
- triangle[11] = quad[1];
-}
-
-void QOpenGLPaintEngine::drawPoints(const QPoint *points, int pointCount)
-{
- Q_ASSERT(sizeof(QT_PointF) == sizeof(QPointF));
- QT_PointF fp[256];
- while (pointCount) {
- int i = 0;
- while (i < pointCount && i < 256) {
- fp[i].x = points[i].x();
- fp[i].y = points[i].y();
- ++i;
- }
- drawPoints((QPointF *)(void *)fp, i);
- points += i;
- pointCount -= i;
- }
-}
-
-void QOpenGLPaintEngine::drawPoints(const QPointF *points, int pointCount)
-{
- Q_D(QOpenGLPaintEngine);
-
- if (d->use_emulation) {
- QPaintEngineEx::drawPoints(points, pointCount);
- return;
- }
-
- d->setGradientOps(d->cpen.brush(), QRectF());
-
- if (!d->cpen.isCosmetic() || d->high_quality_antialiasing) {
- Qt::PenCapStyle capStyle = d->cpen.capStyle();
- if (capStyle == Qt::FlatCap)
- d->cpen.setCapStyle(Qt::SquareCap);
- QPaintEngine::drawPoints(points, pointCount);
- d->cpen.setCapStyle(capStyle);
- return;
- }
-
- d->flushDrawQueue();
-
- if (d->has_fast_pen) {
- QVarLengthArray<GLfloat> vertexArray(6 * pointCount);
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- int j = 0;
- for (int i = 0; i < pointCount; ++i) {
- QPointF mapped = d->matrix.map(points[i]);
-
- GLfloat x = GLfloat(qRound(mapped.x()));
- GLfloat y = GLfloat(qRound(mapped.y()));
-
- vertexArray[j++] = x;
- vertexArray[j++] = y - 0.5f;
-
- vertexArray[j++] = x + 1.5f;
- vertexArray[j++] = y + 1.0f;
-
- vertexArray[j++] = x;
- vertexArray[j++] = y + 1.0f;
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
-
- glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData());
- glDrawArrays(GL_TRIANGLES, 0, pointCount*3);
-
- glDisableClientState(GL_VERTEX_ARRAY);
-
- glPopMatrix();
- return;
- }
-
- const qreal *vertexArray = reinterpret_cast<const qreal*>(&points[0]);
-
- if (sizeof(qreal) == sizeof(double)) {
- Q_ASSERT(sizeof(QPointF) == 16);
- glVertexPointer(2, GL_DOUBLE, 0, vertexArray);
- }
- else {
- Q_ASSERT(sizeof(QPointF) == 8);
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glDrawArrays(GL_POINTS, 0, pointCount);
- glDisableClientState(GL_VERTEX_ARRAY);
-}
-
-void QOpenGLPaintEngine::drawLines(const QLine *lines, int lineCount)
-{
- struct PointF {
- qreal x;
- qreal y;
- };
- struct LineF {
- PointF p1;
- PointF p2;
- };
- Q_ASSERT(sizeof(PointF) == sizeof(QPointF));
- Q_ASSERT(sizeof(LineF) == sizeof(QLineF));
- LineF fl[256];
- while (lineCount) {
- int i = 0;
- while (i < lineCount && i < 256) {
- fl[i].p1.x = lines[i].x1();
- fl[i].p1.y = lines[i].y1();
- fl[i].p2.x = lines[i].x2();
- fl[i].p2.y = lines[i].y2();
- ++i;
- }
- drawLines((QLineF *)(void *)fl, i);
- lines += i;
- lineCount -= i;
- }
-}
-
-void QOpenGLPaintEngine::drawLines(const QLineF *lines, int lineCount)
-{
- Q_D(QOpenGLPaintEngine);
-
- if (d->use_emulation) {
- QPaintEngineEx::drawLines(lines, lineCount);
- return;
- }
-
- if (d->has_pen) {
- QOpenGLCoordinateOffset offset(d);
- if (d->has_fast_pen && !d->high_quality_antialiasing) {
- //### gradient resolving on lines isn't correct
- d->setGradientOps(d->cpen.brush(), QRectF());
-
- bool useRects = false;
- // scale or 90 degree rotation?
- if (d->matrix.type() <= QTransform::TxTranslate
- || (!d->cpen.isCosmetic()
- && (d->matrix.type() <= QTransform::TxScale
- || (d->matrix.type() == QTransform::TxRotate
- && d->matrix.m11() == 0 && d->matrix.m22() == 0)))) {
- useRects = true;
- for (int i = 0; i < lineCount; ++i) {
- if (lines[i].p1().x() != lines[i].p2().x()
- && lines[i].p1().y() != lines[i].p2().y()) {
- useRects = false;
- break;
- }
- }
- }
-
- GLfloat endCap = d->cpen.capStyle() == Qt::FlatCap ? 0.0f : 0.5f;
- if (useRects) {
- QVarLengthArray<GLfloat> vertexArray(12 * lineCount);
-
- GLfloat quad[8];
- for (int i = 0; i < lineCount; ++i) {
- GLfloat x1 = lines[i].x1();
- GLfloat x2 = lines[i].x2();
- GLfloat y1 = lines[i].y1();
- GLfloat y2 = lines[i].y2();
-
- if (x1 == x2) {
- if (y1 > y2)
- qSwap(y1, y2);
-
- quad[0] = x1 - 0.5f;
- quad[1] = y1 - endCap;
-
- quad[2] = x1 + 0.5f;
- quad[3] = y1 - endCap;
-
- quad[4] = x1 + 0.5f;
- quad[5] = y2 + endCap;
-
- quad[6] = x1 - 0.5f;
- quad[7] = y2 + endCap;
- } else {
- if (x1 > x2)
- qSwap(x1, x2);
-
- quad[0] = x1 - endCap;
- quad[1] = y1 + 0.5f;
-
- quad[2] = x1 - endCap;
- quad[3] = y1 - 0.5f;
-
- quad[4] = x2 + endCap;
- quad[5] = y1 - 0.5f;
-
- quad[6] = x2 + endCap;
- quad[7] = y1 + 0.5f;
- }
-
- addQuadAsTriangle(quad, &vertexArray[12*i]);
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
-
- glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData());
- glDrawArrays(GL_TRIANGLES, 0, lineCount*6);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- } else {
- QVarLengthArray<GLfloat> vertexArray(4 * lineCount);
- for (int i = 0; i < lineCount; ++i) {
- const QPointF a = lines[i].p1();
- vertexArray[4*i] = lines[i].x1();
- vertexArray[4*i+1] = lines[i].y1();
- vertexArray[4*i+2] = lines[i].x2();
- vertexArray[4*i+3] = lines[i].y2();
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
-
- glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData());
- glDrawArrays(GL_LINES, 0, lineCount*2);
-
- glVertexPointer(2, GL_FLOAT, 4*sizeof(GLfloat), vertexArray.constData() + 2);
- glDrawArrays(GL_POINTS, 0, lineCount);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- }
- } else {
- QPainterPath path;
- path.setFillRule(Qt::WindingFill);
- for (int i=0; i<lineCount; ++i) {
- const QLineF &l = lines[i];
-
- if (l.p1() == l.p2()) {
- if (d->cpen.capStyle() != Qt::FlatCap) {
- QPointF p = l.p1();
- drawPoints(&p, 1);
- }
- continue;
- }
-
- path.moveTo(l.x1(), l.y1());
- path.lineTo(l.x2(), l.y2());
- }
-
- if (d->has_fast_pen && d->high_quality_antialiasing)
- d->strokeLines(path);
- else
- d->strokePath(path, false);
- }
- }
-}
-
-void QOpenGLPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
-{
- Q_ASSERT(sizeof(QT_PointF) == sizeof(QPointF));
- QVarLengthArray<QT_PointF> p(pointCount);
- for (int i=0; i<pointCount; ++i) {
- p[i].x = points[i].x();
- p[i].y = points[i].y();
- }
- drawPolygon((QPointF *)p.data(), pointCount, mode);
-}
-
-void QOpenGLPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
-{
- Q_D(QOpenGLPaintEngine);
- if(pointCount < 2)
- return;
-
- if (d->use_emulation) {
- QPaintEngineEx::drawPolygon(points, pointCount, mode);
- return;
- }
-
- QRectF bounds;
- if ((mode == ConvexMode && !d->high_quality_antialiasing && state()->brushNeedsResolving()) ||
- ((d->has_fast_pen && !d->high_quality_antialiasing) && state()->penNeedsResolving())) {
- qreal minx = points[0].x(), miny = points[0].y(),
- maxx = points[0].x(), maxy = points[0].y();
- for (int i = 1; i < pointCount; ++i) {
- const QPointF &pt = points[i];
- if (minx > pt.x())
- minx = pt.x();
- if (miny > pt.y())
- miny = pt.y();
- if (maxx < pt.x())
- maxx = pt.x();
- if (maxy < pt.y())
- maxy = pt.y();
- }
- bounds = QRectF(minx, maxx, maxx-minx, maxy-miny);
- }
-
- QOpenGLCoordinateOffset offset(d);
-
- if (d->has_brush && mode != PolylineMode) {
- if (mode == ConvexMode && !d->high_quality_antialiasing) {
- //### resolving on polygon from points isn't correct
- d->setGradientOps(d->cbrush, bounds);
-
- const qreal *vertexArray = reinterpret_cast<const qreal*>(&points[0]);
-
- if (sizeof(qreal) == sizeof(double)) {
- Q_ASSERT(sizeof(QPointF) == 16);
- glVertexPointer(2, GL_DOUBLE, 0, vertexArray);
- }
- else {
- Q_ASSERT(sizeof(QPointF) == 8);
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glDrawArrays(GL_TRIANGLE_FAN, 0, pointCount);
- glDisableClientState(GL_VERTEX_ARRAY);
- } else {
- QPainterPath path;
- path.setFillRule(mode == WindingMode ? Qt::WindingFill : Qt::OddEvenFill);
- path.moveTo(points[0]);
- for (int i=1; i<pointCount; ++i)
- path.lineTo(points[i]);
- d->fillPath(path);
- }
- }
-
- if (d->has_pen) {
- if (d->has_fast_pen && !d->high_quality_antialiasing) {
- d->setGradientOps(d->cpen.brush(), bounds);
- QVarLengthArray<GLfloat> vertexArray(pointCount*2 + 2);
- glVertexPointer(2, GL_FLOAT, 0, vertexArray.constData());
- int i;
- for (i=0; i<pointCount; ++i) {
- vertexArray[i*2] = points[i].x();
- vertexArray[i*2+1] = points[i].y();
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
- if (mode != PolylineMode) {
- vertexArray[i*2] = vertexArray[0];
- vertexArray[i*2+1] = vertexArray[1];
- glDrawArrays(GL_LINE_STRIP, 0, pointCount+1);
- } else {
- glDrawArrays(GL_LINE_STRIP, 0, pointCount);
- glDrawArrays(GL_POINTS, pointCount-1, 1);
- }
- glDisableClientState(GL_VERTEX_ARRAY);
- } else {
- QPainterPath path(points[0]);
- for (int i = 1; i < pointCount; ++i)
- path.lineTo(points[i]);
- if (mode != PolylineMode)
- path.lineTo(points[0]);
-
- if (d->has_fast_pen)
- d->strokeLines(path);
- else
- d->strokePath(path, true);
- }
- }
-}
-
-void QOpenGLPaintEnginePrivate::strokeLines(const QPainterPath &path)
-{
- DEBUG_ONCE_STR("QOpenGLPaintEnginePrivate::strokeLines()");
-
- qreal penWidth = cpen.widthF();
-
- GLuint program = qt_gl_program_cache()->getProgram(device->context(),
- FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA, 0, true);
- QGLLineMaskGenerator maskGenerator(path, matrix, penWidth == 0 ? 1.0 : penWidth,
- offscreen, program);
-
- disableClipping();
-
- QBrush temp = cbrush;
- QPointF origin = brush_origin;
-
- cbrush = cpen.brush();
- brush_origin = QPointF();
-
- addItem(qt_mask_texture_cache()->getMask(maskGenerator, this));
-
- cbrush = temp;
- brush_origin = origin;
-
- enableClipping();
-}
-
-Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
-
-void QOpenGLPaintEnginePrivate::strokePath(const QPainterPath &path, bool use_cache)
-{
- QBrush old_brush = cbrush;
- cbrush = cpen.brush();
-
- qreal txscale = 1;
- if (cpen.isCosmetic() || (qt_scaleForTransform(matrix, &txscale) && txscale != 1)) {
- QTransform temp = matrix;
- matrix = QTransform();
- glPushMatrix();
-
- if (has_antialiasing) {
- glLoadIdentity();
- } else {
- float offs_matrix[] =
- { 1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0.5, 0.5, 0, 1 };
- glLoadMatrixf(offs_matrix);
- }
-
- QPen pen = cpen;
- if (txscale != 1)
- pen.setWidthF(pen.widthF() * txscale);
- if (use_cache)
- fillPath(qt_opengl_stroke_cache()->getStrokedPath(temp.map(path), pen));
- else
- fillPath(strokeForPath(temp.map(path), pen));
-
- glPopMatrix();
- matrix = temp;
- } else if (use_cache) {
- fillPath(qt_opengl_stroke_cache()->getStrokedPath(path, cpen));
- } else {
- fillPath(strokeForPath(path, cpen));
- }
-
- cbrush = old_brush;
-}
-
-void QOpenGLPaintEnginePrivate::strokePathFastPen(const QPainterPath &path, bool needsResolving)
-{
-#ifndef QT_OPENGL_ES
- QRectF bounds;
- if (needsResolving)
- bounds = path.controlPointRect();
- setGradientOps(cpen.brush(), bounds);
-
- QBezier beziers[32];
- for (int i=0; i<path.elementCount(); ++i) {
- const QPainterPath::Element &e = path.elementAt(i);
- switch (e.type) {
- case QPainterPath::MoveToElement:
- if (i != 0)
- glEnd(); // GL_LINE_STRIP
- glBegin(GL_LINE_STRIP);
- glVertex2d(e.x, e.y);
-
- break;
- case QPainterPath::LineToElement:
- glVertex2d(e.x, e.y);
- break;
-
- case QPainterPath::CurveToElement:
- {
- QPointF sp = path.elementAt(i-1);
- QPointF cp2 = path.elementAt(i+1);
- QPointF ep = path.elementAt(i+2);
- i+=2;
-
- qreal inverseScaleHalf = inverseScale / 2;
- beziers[0] = QBezier::fromPoints(sp, e, cp2, ep);
- QBezier *b = beziers;
- while (b >= beziers) {
- // check if we can pop the top bezier curve from the stack
- qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1);
- qreal d;
- if (l > inverseScale) {
- d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2)
- - (b->y4 - b->y1)*(b->x1 - b->x2) )
- + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3)
- - (b->y4 - b->y1)*(b->x1 - b->x3) );
- d /= l;
- } else {
- d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) +
- qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);
- }
- if (d < inverseScaleHalf || b == beziers + 31) {
- // good enough, we pop it off and add the endpoint
- glVertex2d(b->x4, b->y4);
- --b;
- } else {
- // split, second half of the polygon goes lower into the stack
- b->split(b+1, b);
- ++b;
- }
- }
- } // case CurveToElement
- default:
- break;
- } // end of switch
- }
- glEnd(); // GL_LINE_STRIP
-#else
- // have to use vertex arrays on embedded
- QRectF bounds;
- if (needsResolving)
- bounds = path.controlPointRect();
- setGradientOps(cpen.brush(), bounds);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- tess_points.reset();
- QBezier beziers[32];
- for (int i=0; i<path.elementCount(); ++i) {
- const QPainterPath::Element &e = path.elementAt(i);
- switch (e.type) {
- case QPainterPath::MoveToElement:
- if (i != 0) {
- glVertexPointer(2, GL_FLOAT, 0, tess_points.data());
- glDrawArrays(GL_LINE_STRIP, 0, tess_points.size());
- tess_points.reset();
- }
- tess_points.add(QPointF(e.x, e.y));
-
- break;
- case QPainterPath::LineToElement:
- tess_points.add(QPointF(e.x, e.y));
- break;
-
- case QPainterPath::CurveToElement:
- {
- QPointF sp = path.elementAt(i-1);
- QPointF cp2 = path.elementAt(i+1);
- QPointF ep = path.elementAt(i+2);
- i+=2;
-
- qreal inverseScaleHalf = inverseScale / 2;
- beziers[0] = QBezier::fromPoints(sp, e, cp2, ep);
- QBezier *b = beziers;
- while (b >= beziers) {
- // check if we can pop the top bezier curve from the stack
- qreal l = qAbs(b->x4 - b->x1) + qAbs(b->y4 - b->y1);
- qreal d;
- if (l > inverseScale) {
- d = qAbs( (b->x4 - b->x1)*(b->y1 - b->y2)
- - (b->y4 - b->y1)*(b->x1 - b->x2) )
- + qAbs( (b->x4 - b->x1)*(b->y1 - b->y3)
- - (b->y4 - b->y1)*(b->x1 - b->x3) );
- d /= l;
- } else {
- d = qAbs(b->x1 - b->x2) + qAbs(b->y1 - b->y2) +
- qAbs(b->x1 - b->x3) + qAbs(b->y1 - b->y3);
- }
- if (d < inverseScaleHalf || b == beziers + 31) {
- // good enough, we pop it off and add the endpoint
- tess_points.add(QPointF(b->x4, b->y4));
- --b;
- } else {
- // split, second half of the polygon goes lower into the stack
- b->split(b+1, b);
- ++b;
- }
- }
- } // case CurveToElement
- default:
- break;
- } // end of switch
- }
- glVertexPointer(2, GL_FLOAT, 0, tess_points.data());
- glDrawArrays(GL_LINE_STRIP, 0, tess_points.size());
- glDisableClientState(GL_VERTEX_ARRAY);
-#endif
-}
-
-static bool pathClosed(const QPainterPath &path)
-{
- QPointF lastMoveTo = path.elementAt(0);
- QPointF lastPoint = lastMoveTo;
-
- for (int i = 1; i < path.elementCount(); ++i) {
- const QPainterPath::Element &e = path.elementAt(i);
- switch (e.type) {
- case QPainterPath::MoveToElement:
- if (lastMoveTo != lastPoint)
- return false;
- lastMoveTo = lastPoint = e;
- break;
- case QPainterPath::LineToElement:
- lastPoint = e;
- break;
- case QPainterPath::CurveToElement:
- lastPoint = path.elementAt(i + 2);
- i+=2;
- break;
- default:
- break;
- }
- }
-
- return lastMoveTo == lastPoint;
-}
-
-void QOpenGLPaintEngine::drawPath(const QPainterPath &path)
-{
- Q_D(QOpenGLPaintEngine);
-
- if (path.isEmpty())
- return;
-
- if (d->use_emulation) {
- QPaintEngineEx::drawPath(path);
- return;
- }
-
- QOpenGLCoordinateOffset offset(d);
-
- if (d->has_brush) {
- bool path_closed = pathClosed(path);
-
- bool has_thick_pen =
- path_closed
- && d->has_pen
- && d->cpen.style() == Qt::SolidLine
- && d->cpen.isSolid()
- && d->cpen.color().alpha() == 255
- && d->txop < QTransform::TxProject
- && d->cpen.widthF() >= 2 / qSqrt(qMin(d->matrix.m11() * d->matrix.m11()
- + d->matrix.m21() * d->matrix.m21(),
- d->matrix.m12() * d->matrix.m12()
- + d->matrix.m22() * d->matrix.m22()));
-
- if (has_thick_pen) {
- DEBUG_ONCE qDebug() << "QOpenGLPaintEngine::drawPath(): Using thick pen optimization, style:" << d->cbrush.style();
-
- d->flushDrawQueue();
-
- bool temp = d->high_quality_antialiasing;
- d->high_quality_antialiasing = false;
-
- updateCompositionMode(d->composition_mode);
-
- d->fillPath(path);
-
- d->high_quality_antialiasing = temp;
- updateCompositionMode(d->composition_mode);
- } else {
- d->fillPath(path);
- }
- }
-
- if (d->has_pen) {
- if (d->has_fast_pen && !d->high_quality_antialiasing)
- d->strokePathFastPen(path, state()->penNeedsResolving());
- else
- d->strokePath(path, true);
- }
-}
-
-void QOpenGLPaintEnginePrivate::drawImageAsPath(const QRectF &r, const QImage &img, const QRectF &sr)
-{
- QBrush old_brush = cbrush;
- QPointF old_brush_origin = brush_origin;
-
- qreal scaleX = r.width() / sr.width();
- qreal scaleY = r.height() / sr.height();
-
- QTransform brush_matrix = QTransform::fromTranslate(r.left(), r.top());
- brush_matrix.scale(scaleX, scaleY);
- brush_matrix.translate(-sr.left(), -sr.top());
-
- cbrush = QBrush(img);
- cbrush.setTransform(brush_matrix);
- brush_origin = QPointF();
-
- QPainterPath p;
- p.addRect(r);
- fillPath(p);
-
- cbrush = old_brush;
- brush_origin = old_brush_origin;
-}
-
-void QOpenGLPaintEnginePrivate::drawTiledImageAsPath(const QRectF &r, const QImage &img, qreal sx, qreal sy,
- const QPointF &offset)
-{
- QBrush old_brush = cbrush;
- QPointF old_brush_origin = brush_origin;
-
- QTransform brush_matrix = QTransform::fromTranslate(r.left(), r.top());
- brush_matrix.scale(sx, sy);
- brush_matrix.translate(-offset.x(), -offset.y());
-
- cbrush = QBrush(img);
- cbrush.setTransform(brush_matrix);
- brush_origin = QPointF();
-
- QPainterPath p;
- p.addRect(r);
- fillPath(p);
-
- cbrush = old_brush;
- brush_origin = old_brush_origin;
-}
-
-static const QRectF scaleRect(const QRectF &r, qreal sx, qreal sy)
-{
- return QRectF(r.x() * sx, r.y() * sy, r.width() * sx, r.height() * sy);
-}
-
-template <typename T>
-static const T qSubImage(const T &image, const QRectF &src, QRectF *srcNew)
-{
- const int sx1 = qMax(0, qFloor(src.left()));
- const int sy1 = qMax(0, qFloor(src.top()));
- const int sx2 = qMin(image.width(), qCeil(src.right()));
- const int sy2 = qMin(image.height(), qCeil(src.bottom()));
-
- const T sub = image.copy(sx1, sy1, sx2 - sx1, sy2 - sy1);
-
- if (srcNew)
- *srcNew = src.translated(-sx1, -sy1);
-
- return sub;
-}
-
-void QOpenGLPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
-{
- Q_D(QOpenGLPaintEngine);
- if (pm.depth() == 1) {
- QPixmap tpx(pm.size());
- tpx.fill(Qt::transparent);
- QPainter p(&tpx);
- p.setPen(d->cpen);
- p.drawPixmap(0, 0, pm);
- p.end();
- drawPixmap(r, tpx, sr);
- return;
- }
-
- const int sz = d->max_texture_size;
- if (pm.width() > sz || pm.height() > sz) {
- QRectF subsr;
- const QPixmap sub = qSubImage(pm, sr, &subsr);
-
- if (sub.width() <= sz && sub.height() <= sz) {
- drawPixmap(r, sub, subsr);
- } else {
- const QPixmap scaled = sub.scaled(sz, sz, Qt::KeepAspectRatio);
- const qreal sx = scaled.width() / qreal(sub.width());
- const qreal sy = scaled.height() / qreal(sub.height());
-
- drawPixmap(r, scaled, scaleRect(subsr, sx, sy));
- }
- return;
- }
-
-
- if (d->composition_mode > QPainter::CompositionMode_Plus || (d->high_quality_antialiasing && !d->isFastRect(r)))
- d->drawImageAsPath(r, pm.toImage(), sr);
- else {
- GLenum target = qt_gl_preferredTextureTarget();
- d->flushDrawQueue();
- QGLTexture *tex =
- d->device->context()->d_func()->bindTexture(pm, target, GL_RGBA,
- QGLContext::InternalBindOption);
- drawTextureRect(pm.width(), pm.height(), r, sr, target, tex);
- }
-}
-
-void QOpenGLPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &offset)
-{
- Q_D(QOpenGLPaintEngine);
- if (pm.depth() == 1) {
- QPixmap tpx(pm.size());
- tpx.fill(Qt::transparent);
- QPainter p(&tpx);
- p.setPen(d->cpen);
- p.drawPixmap(0, 0, pm);
- p.end();
- drawTiledPixmap(r, tpx, offset);
- return;
- }
-
- QImage scaled;
- const int sz = d->max_texture_size;
- if (pm.width() > sz || pm.height() > sz) {
- int rw = qCeil(r.width());
- int rh = qCeil(r.height());
- if (rw < pm.width() && rh < pm.height()) {
- drawTiledPixmap(r, pm.copy(0, 0, rw, rh), offset);
- return;
- }
-
- scaled = pm.toImage().scaled(sz, sz, Qt::KeepAspectRatio);
- }
-
- if (d->composition_mode > QPainter::CompositionMode_Plus || (d->high_quality_antialiasing && !d->isFastRect(r))) {
- if (scaled.isNull())
- d->drawTiledImageAsPath(r, pm.toImage(), 1, 1, offset);
- else {
- const qreal sx = pm.width() / qreal(scaled.width());
- const qreal sy = pm.height() / qreal(scaled.height());
- d->drawTiledImageAsPath(r, scaled, sx, sy, offset);
- }
- } else {
- d->flushDrawQueue();
-
- QGLTexture *tex;
- if (scaled.isNull())
- tex = d->device->context()->d_func()->bindTexture(pm, GL_TEXTURE_2D, GL_RGBA,
- QGLContext::InternalBindOption);
- else
- tex = d->device->context()->d_func()->bindTexture(scaled, GL_TEXTURE_2D, GL_RGBA,
- QGLContext::InternalBindOption);
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, d->use_smooth_pixmap_transform);
-
-#ifndef QT_OPENGL_ES
- glPushAttrib(GL_CURRENT_BIT);
- glDisable(GL_TEXTURE_GEN_S);
-#endif
- glColor4f(d->opacity, d->opacity, d->opacity, d->opacity);
- glEnable(GL_TEXTURE_2D);
-
- GLdouble tc_w = r.width()/pm.width();
- GLdouble tc_h = r.height()/pm.height();
-
- // Rotate the texture so that it is aligned correctly and the
- // wrapping is done correctly
- if (tex->options & QGLContext::InvertedYBindOption) {
- glMatrixMode(GL_TEXTURE);
- glPushMatrix();
- glRotatef(180.0, 0.0, 1.0, 0.0);
- glRotatef(180.0, 0.0, 0.0, 1.0);
- }
-
- GLfloat vertexArray[4*2];
- GLfloat texCoordArray[4*2];
-
- double offset_x = offset.x() / pm.width();
- double offset_y = offset.y() / pm.height();
-
- qt_add_rect_to_array(r, vertexArray);
- qt_add_texcoords_to_array(offset_x, offset_y,
- tc_w + offset_x, tc_h + offset_y, texCoordArray);
-
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
- if (tex->options & QGLContext::InvertedYBindOption)
- glPopMatrix();
-
- glDisable(GL_TEXTURE_2D);
-#ifndef QT_OPENGL_ES
- glPopAttrib();
-#endif
- }
-}
-
-void QOpenGLPaintEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr,
- Qt::ImageConversionFlags)
-{
- Q_D(QOpenGLPaintEngine);
-
- const int sz = d->max_texture_size;
- if (image.width() > sz || image.height() > sz) {
- QRectF subsr;
- const QImage sub = qSubImage(image, sr, &subsr);
-
- if (sub.width() <= sz && sub.height() <= sz) {
- drawImage(r, sub, subsr, 0);
- } else {
- const QImage scaled = sub.scaled(sz, sz, Qt::KeepAspectRatio);
- const qreal sx = scaled.width() / qreal(sub.width());
- const qreal sy = scaled.height() / qreal(sub.height());
-
- drawImage(r, scaled, scaleRect(subsr, sx, sy), 0);
- }
- return;
- }
-
- if (d->composition_mode > QPainter::CompositionMode_Plus || (d->high_quality_antialiasing && !d->isFastRect(r)))
- d->drawImageAsPath(r, image, sr);
- else {
- GLenum target = qt_gl_preferredTextureTarget();
- d->flushDrawQueue();
- QGLTexture *tex =
- d->device->context()->d_func()->bindTexture(image, target, GL_RGBA,
- QGLContext::InternalBindOption);
- drawTextureRect(image.width(), image.height(), r, sr, target, tex);
- }
-}
-
-void QOpenGLPaintEngine::drawTextureRect(int tx_width, int tx_height, const QRectF &r,
- const QRectF &sr, GLenum target, QGLTexture *tex)
-{
- Q_D(QOpenGLPaintEngine);
-#ifndef QT_OPENGL_ES
- glPushAttrib(GL_CURRENT_BIT);
- glDisable(GL_TEXTURE_GEN_S);
-#endif
- glColor4f(d->opacity, d->opacity, d->opacity, d->opacity);
- glEnable(target);
- updateTextureFilter(target, GL_CLAMP_TO_EDGE, d->use_smooth_pixmap_transform);
-
- qreal x1, x2, y1, y2;
- if (target == GL_TEXTURE_2D) {
- x1 = sr.x() / tx_width;
- x2 = x1 + sr.width() / tx_width;
- if (tex->options & QGLContext::InvertedYBindOption) {
- y1 = 1 - (sr.bottom() / tx_height);
- y2 = 1 - (sr.y() / tx_height);
- } else {
- y1 = sr.bottom() / tx_height;
- y2 = sr.y() / tx_height;
- }
- } else {
- x1 = sr.x();
- x2 = sr.right();
- y1 = sr.bottom();
- y2 = sr.y();
- }
-
- GLfloat vertexArray[4*2];
- GLfloat texCoordArray[4*2];
-
- qt_add_rect_to_array(r, vertexArray);
- qt_add_texcoords_to_array(x1, y2, x2, y1, texCoordArray);
-
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- glDisable(target);
-#ifndef QT_OPENGL_ES
- glPopAttrib();
-#endif
-}
-
-#ifdef Q_WS_WIN
-HDC
-#else
-Qt::HANDLE
-#endif
-QOpenGLPaintEngine::handle() const
-{
- return 0;
-}
-
-static const int x_margin = 1;
-static const int y_margin = 0;
-
-struct QGLGlyphCoord {
- // stores the offset and size of a glyph texture
- qreal x;
- qreal y;
- qreal width;
- qreal height;
- qreal log_width;
- qreal log_height;
- QFixed x_offset;
- QFixed y_offset;
-};
-
-struct QGLFontTexture {
- int x_offset; // glyph offset within the
- int y_offset;
- GLuint texture;
- int width;
- int height;
-};
-
-typedef QHash<glyph_t, QGLGlyphCoord*> QGLGlyphHash;
-typedef QHash<QFontEngine*, QGLGlyphHash*> QGLFontGlyphHash;
-typedef QHash<quint64, QGLFontTexture*> QGLFontTexHash;
-typedef QHash<const QGLContext*, QGLFontGlyphHash*> QGLContextHash;
-
-static inline void qt_delete_glyph_hash(QGLGlyphHash *hash)
-{
- qDeleteAll(*hash);
- delete hash;
-}
-
-class QGLGlyphCache : public QObject
-{
- Q_OBJECT
-public:
- QGLGlyphCache() : QObject(0) { current_cache = 0; }
- ~QGLGlyphCache();
- QGLGlyphCoord *lookup(QFontEngine *, glyph_t);
- void cacheGlyphs(QGLContext *, QFontEngine *, glyph_t *glyphs, int numGlyphs);
- void cleanCache();
- void allocTexture(int width, int height, GLuint texture);
-
-public slots:
- void cleanupContext(const QGLContext *);
- void fontEngineDestroyed(QObject *);
- void widgetDestroyed(QObject *);
-
-protected:
- QGLGlyphHash *current_cache;
- QGLFontTexHash qt_font_textures;
- QGLContextHash qt_context_cache;
-};
-
-QGLGlyphCache::~QGLGlyphCache()
-{
-// qDebug() << "cleaning out the QGLGlyphCache";
- cleanCache();
-}
-
-void QGLGlyphCache::fontEngineDestroyed(QObject *o)
-{
-// qDebug() << "fontEngineDestroyed()";
- QFontEngine *fe = static_cast<QFontEngine *>(o); // safe, since only the type is used
- QList<const QGLContext *> keys = qt_context_cache.keys();
- const QGLContext *ctx = 0;
-
- for (int i=0; i < keys.size(); ++i) {
- QGLFontGlyphHash *font_cache = qt_context_cache.value(keys.at(i));
- if (font_cache->find(fe) != font_cache->end()) {
- ctx = keys.at(i);
- QGLGlyphHash *cache = font_cache->take(fe);
- qt_delete_glyph_hash(cache);
- break;
- }
- }
-
- quint64 font_key = (reinterpret_cast<quint64>(ctx) << 32) | reinterpret_cast<quint64>(fe);
- QGLFontTexture *tex = qt_font_textures.take(font_key);
- if (tex) {
-#ifdef Q_WS_MAC
- if (
-# ifndef QT_MAC_USE_COCOA
- aglGetCurrentContext() != 0
-# else
- qt_current_nsopengl_context() != 0
-# endif
- )
-#endif
- glDeleteTextures(1, &tex->texture);
- delete tex;
- }
-}
-
-void QGLGlyphCache::widgetDestroyed(QObject *)
-{
-// qDebug() << "widget destroyed";
- cleanCache(); // ###
-}
-
-void QGLGlyphCache::cleanupContext(const QGLContext *ctx)
-{
-// qDebug() << "==> cleaning for: " << hex << ctx;
- QGLFontGlyphHash *font_cache = qt_context_cache.take(ctx);
-
- if (font_cache) {
- QList<QFontEngine *> keys = font_cache->keys();
- for (int i=0; i < keys.size(); ++i) {
- QFontEngine *fe = keys.at(i);
- qt_delete_glyph_hash(font_cache->take(fe));
- quint64 font_key = (reinterpret_cast<quint64>(ctx) << 32) | reinterpret_cast<quint64>(fe);
- QGLFontTexture *font_tex = qt_font_textures.take(font_key);
- if (font_tex) {
-#ifdef Q_WS_MAC
- if (
-# ifndef QT_MAC_USE_COCOA
- aglGetCurrentContext() == 0
-# else
- qt_current_nsopengl_context() != 0
-# endif
- )
-#endif
- glDeleteTextures(1, &font_tex->texture);
- delete font_tex;
- }
- }
- delete font_cache;
- }
-// qDebug() << "<=== done cleaning, num tex:" << qt_font_textures.size() << "num ctx:" << qt_context_cache.size();
-}
-
-void QGLGlyphCache::cleanCache()
-{
- QGLFontTexHash::const_iterator it = qt_font_textures.constBegin();
- if (QGLContext::currentContext()) {
- while (it != qt_font_textures.constEnd()) {
-#if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
- if (qt_current_nsopengl_context() == 0)
- break;
-#endif
- glDeleteTextures(1, &it.value()->texture);
- ++it;
- }
- }
- qDeleteAll(qt_font_textures);
- qt_font_textures.clear();
-
- QList<const QGLContext *> keys = qt_context_cache.keys();
- for (int i=0; i < keys.size(); ++i) {
- QGLFontGlyphHash *font_cache = qt_context_cache.value(keys.at(i));
- QGLFontGlyphHash::Iterator it = font_cache->begin();
- for (; it != font_cache->end(); ++it)
- qt_delete_glyph_hash(it.value());
- font_cache->clear();
- }
- qDeleteAll(qt_context_cache);
- qt_context_cache.clear();
-}
-
-void QGLGlyphCache::allocTexture(int width, int height, GLuint texture)
-{
- uchar *tex_data = (uchar *) malloc(width*height*2);
- memset(tex_data, 0, width*height*2);
- glBindTexture(GL_TEXTURE_2D, texture);
-#ifndef QT_OPENGL_ES
- glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE8_ALPHA8,
- width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, tex_data);
-#else
- glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA,
- width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, tex_data);
-#endif
- free(tex_data);
-}
-
-#if 0
-// useful for debugging the glyph cache
-static QImage getCurrentTexture(const QColor &color, QGLFontTexture *font_tex)
-{
- ushort *old_tex_data = (ushort *) malloc(font_tex->width*font_tex->height*2);
- glGetTexImage(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, old_tex_data);
- QImage im(font_tex->width, font_tex->height, QImage::Format_ARGB32);
- for (int y=0; y<font_tex->height; ++y) {
- for (int x=0; x<font_tex->width; ++x) {
- im.setPixel(x, y, ((*(old_tex_data+x+y*font_tex->width)) << 24) | (0x00ffffff & color.rgb()));
- }
- }
- delete old_tex_data;
- return im;
-}
-#endif
-
-void QGLGlyphCache::cacheGlyphs(QGLContext *context, QFontEngine *fontEngine,
- glyph_t *glyphs, int numGlyphs)
-{
- QGLContextHash::const_iterator dev_it = qt_context_cache.constFind(context);
- QGLFontGlyphHash *font_cache = 0;
- const QGLContext *context_key = 0;
-
- if (dev_it == qt_context_cache.constEnd()) {
- // check for shared contexts
- QList<const QGLContext *> contexts = qt_context_cache.keys();
- for (int i=0; i<contexts.size(); ++i) {
- const QGLContext *ctx = contexts.at(i);
- if (ctx != context && QGLContext::areSharing(context, ctx)) {
- context_key = ctx;
- dev_it = qt_context_cache.constFind(context_key);
- break;
- }
- }
- }
-
- if (dev_it == qt_context_cache.constEnd()) {
- // no shared contexts either - create a new entry
- font_cache = new QGLFontGlyphHash;
-// qDebug() << "new context" << context << font_cache;
- qt_context_cache.insert(context, font_cache);
- if (context->isValid()) {
- if (context->device() && context->device()->devType() == QInternal::Widget) {
- QWidget *widget = static_cast<QWidget *>(context->device());
- connect(widget, SIGNAL(destroyed(QObject*)), SLOT(widgetDestroyed(QObject*)));
- }
- connect(QGLSignalProxy::instance(),
- SIGNAL(aboutToDestroyContext(const QGLContext*)),
- SLOT(cleanupContext(const QGLContext*)));
- }
- } else {
- font_cache = dev_it.value();
- }
- Q_ASSERT(font_cache != 0);
-
- QGLFontGlyphHash::const_iterator cache_it = font_cache->constFind(fontEngine);
- QGLGlyphHash *cache = 0;
- if (cache_it == font_cache->constEnd()) {
- cache = new QGLGlyphHash;
- font_cache->insert(fontEngine, cache);
- connect(fontEngine, SIGNAL(destroyed(QObject*)), SLOT(fontEngineDestroyed(QObject*)));
- } else {
- cache = cache_it.value();
- }
- current_cache = cache;
-
- quint64 font_key = (reinterpret_cast<quint64>(context_key ? context_key : context) << 32)
- | reinterpret_cast<quint64>(fontEngine);
- QGLFontTexHash::const_iterator it = qt_font_textures.constFind(font_key);
- QGLFontTexture *font_tex;
- if (it == qt_font_textures.constEnd()) {
- GLuint font_texture;
- glGenTextures(1, &font_texture);
- GLint tex_height = qt_next_power_of_two(qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2);
- GLint tex_width = qt_next_power_of_two(tex_height*30); // ###
- GLint max_tex_size;
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
- Q_ASSERT(max_tex_size > 0);
- if (tex_width > max_tex_size)
- tex_width = max_tex_size;
- allocTexture(tex_width, tex_height, font_texture);
- font_tex = new QGLFontTexture;
- font_tex->texture = font_texture;
- font_tex->x_offset = x_margin;
- font_tex->y_offset = y_margin;
- font_tex->width = tex_width;
- font_tex->height = tex_height;
-// qDebug() << "new font tex - width:" << tex_width << "height:"<< tex_height
-// << hex << "tex id:" << font_tex->texture << "key:" << font_key << "num cached:" << qt_font_textures.size();
- qt_font_textures.insert(font_key, font_tex);
- } else {
- font_tex = it.value();
- glBindTexture(GL_TEXTURE_2D, font_tex->texture);
- }
-
- for (int i=0; i< numGlyphs; ++i) {
- QGLGlyphHash::const_iterator it = cache->constFind(glyphs[i]);
- if (it == cache->constEnd()) {
- // render new glyph and put it in the cache
- glyph_metrics_t metrics = fontEngine->boundingBox(glyphs[i]);
- int glyph_width = qRound(metrics.width.toReal())+2;
- int glyph_height = qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2;
-
- if (font_tex->x_offset + glyph_width + x_margin > font_tex->width) {
- int strip_height = qt_next_power_of_two(qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2);
- font_tex->x_offset = x_margin;
- font_tex->y_offset += strip_height;
- if (font_tex->y_offset >= font_tex->height) {
- // get hold of the old font texture
- uchar *old_tex_data = (uchar *) malloc(font_tex->width*font_tex->height*2);
- int old_tex_height = font_tex->height;
-#ifndef QT_OPENGL_ES
- glGetTexImage(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, old_tex_data);
-#endif
-
- // realloc a larger texture
- glDeleteTextures(1, &font_tex->texture);
- glGenTextures(1, &font_tex->texture);
- font_tex->height = qt_next_power_of_two(font_tex->height + strip_height);
- allocTexture(font_tex->width, font_tex->height, font_tex->texture);
-
- // write back the old texture data
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, font_tex->width, old_tex_height,
- GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, old_tex_data);
- free(old_tex_data);
-
- // update the texture coords and the y offset for the existing glyphs in
- // the cache, because of the texture size change
- QGLGlyphHash::iterator it = cache->begin();
- while (it != cache->end()) {
- it.value()->height = (it.value()->height * old_tex_height) / font_tex->height;
- it.value()->y = (it.value()->y * old_tex_height) / font_tex->height;
- ++it;
- }
- }
- }
-
- QImage glyph_im(fontEngine->alphaMapForGlyph(glyphs[i]));
- glyph_width = glyph_im.width();
- Q_ASSERT(glyph_width >= 0);
- // pad the glyph width to an even number
- if (glyph_width%2 != 0)
- ++glyph_width;
-
- QGLGlyphCoord *qgl_glyph = new QGLGlyphCoord;
- qgl_glyph->x = qreal(font_tex->x_offset) / font_tex->width;
- qgl_glyph->y = qreal(font_tex->y_offset) / font_tex->height;
- qgl_glyph->width = qreal(glyph_width) / font_tex->width;
- qgl_glyph->height = qreal(glyph_height) / font_tex->height;
- qgl_glyph->log_width = qreal(glyph_width);
- qgl_glyph->log_height = qgl_glyph->height * font_tex->height;
-#ifdef Q_WS_MAC
- qgl_glyph->x_offset = -metrics.x + 1;
- qgl_glyph->y_offset = metrics.y - 2;
-#else
- qgl_glyph->x_offset = -metrics.x;
- qgl_glyph->y_offset = metrics.y;
-#endif
-
- if (!glyph_im.isNull()) {
- int idx = 0;
- uchar *tex_data = (uchar *) malloc(glyph_width*glyph_im.height()*2);
- memset(tex_data, 0, glyph_width*glyph_im.height()*2);
-
- bool is8BitGray = false;
-#ifdef Q_WS_QPA
- if (glyph_im.format() == QImage::Format_Indexed8) {
- is8BitGray = true;
- }
-#endif
- glyph_im = glyph_im.convertToFormat(QImage::Format_Indexed8);
- for (int y=0; y<glyph_im.height(); ++y) {
- uchar *s = (uchar *) glyph_im.scanLine(y);
- for (int x=0; x<glyph_im.width(); ++x) {
- uchar alpha = is8BitGray ? *s : qAlpha(glyph_im.color(*s));
- tex_data[idx] = alpha;
- tex_data[idx+1] = alpha;
- ++s;
- idx += 2;
- }
- if (glyph_im.width()%2 != 0)
- idx += 2;
- }
- glTexSubImage2D(GL_TEXTURE_2D, 0, font_tex->x_offset, font_tex->y_offset,
- glyph_width, glyph_im.height(),
- GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, tex_data);
- free(tex_data);
- }
- if (font_tex->x_offset + glyph_width + x_margin > font_tex->width) {
- font_tex->x_offset = x_margin;
- font_tex->y_offset += glyph_height + y_margin;
- } else {
- font_tex->x_offset += glyph_width + x_margin;
- }
-
- cache->insert(glyphs[i], qgl_glyph);
- }
- }
-}
-
-QGLGlyphCoord *QGLGlyphCache::lookup(QFontEngine *, glyph_t g)
-{
- Q_ASSERT(current_cache != 0);
- // ### careful here
- QGLGlyphHash::const_iterator it = current_cache->constFind(g);
- if (it == current_cache->constEnd())
- return 0;
- else
- return it.value();
-}
-
-Q_GLOBAL_STATIC(QGLGlyphCache, qt_glyph_cache)
-
-//
-// assumption: the context that this is called for has to be the
-// current context
-//
-void qgl_cleanup_glyph_cache(QGLContext *ctx)
-{
- qt_glyph_cache()->cleanupContext(ctx);
-}
-
-void QOpenGLPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
-{
- Q_D(QOpenGLPaintEngine);
-
- d->flushDrawQueue();
-
- // make sure the glyphs we want to draw are in the cache
- qt_glyph_cache()->cacheGlyphs(d->device->context(), textItem->fontEngine(), textItem->glyphs,
- textItem->numGlyphs);
-
- d->setGradientOps(Qt::SolidPattern, QRectF()); // turns off gradient ops
- qt_glColor4ubv(d->pen_color);
- glEnable(GL_TEXTURE_2D);
-
-#ifdef Q_WS_QWS
- // XXX: it is necessary to disable alpha writes on GLES/embedded because we don't want
- // text rendering to update the alpha in the window surface.
- // XXX: This may not be needed as this behavior does seem to be caused by driver bug
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
-#endif
-
- // do the actual drawing
- GLfloat vertexArray[4*2];
- GLfloat texCoordArray[4*2];
-
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- bool antialias = !(textItem->fontEngine()->fontDef.styleStrategy & QFont::NoAntialias)
- && (d->matrix.type() > QTransform::TxTranslate);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, antialias ? GL_LINEAR : GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, antialias ? GL_LINEAR : GL_NEAREST);
-
- for (int i=0; i< textItem->numGlyphs; ++i) {
- QGLGlyphCoord *g = qt_glyph_cache()->lookup(textItem->fontEngine(), textItem->glyphs[i]);
-
- // we don't cache glyphs with no width/height
- if (!g)
- continue;
-
- qreal x1, x2, y1, y2;
- x1 = g->x;
- y1 = g->y;
- x2 = x1 + g->width;
- y2 = y1 + g->height;
-
- QPointF logical_pos((textItem->glyphPositions[i].x - g->x_offset).toReal(),
- (textItem->glyphPositions[i].y + g->y_offset).toReal());
-
- qt_add_rect_to_array(QRectF(logical_pos, QSizeF(g->log_width, g->log_height)), vertexArray);
- qt_add_texcoords_to_array(x1, y1, x2, y2, texCoordArray);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
-
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- glDisable(GL_TEXTURE_2D);
-
-#ifdef Q_WS_QWS
- // XXX: This may not be needed as this behavior does seem to be caused by driver bug
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-#endif
-
-}
-
-void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
-{
- Q_D(QOpenGLPaintEngine);
-
- const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
-
- // fall back to drawing a polygon if the scale factor is large, or
- // we use a gradient pen
- if ((d->matrix.det() > 1) || (d->pen_brush_style >= Qt::LinearGradientPattern
- && d->pen_brush_style <= Qt::ConicalGradientPattern)) {
- QPaintEngine::drawTextItem(p, textItem);
- return;
- }
-
- // add the glyphs used to the glyph texture cache
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- QTransform matrix = QTransform::fromTranslate(qRound(p.x()), qRound(p.y()));
- ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
-
- {
- QStaticTextItem staticTextItem;
- staticTextItem.chars = const_cast<QChar *>(ti.chars);
- staticTextItem.setFontEngine(ti.fontEngine);
- staticTextItem.glyphs = glyphs.data();
- staticTextItem.numChars = ti.num_chars;
- staticTextItem.numGlyphs = glyphs.size();
- staticTextItem.glyphPositions = positions.data();
- drawStaticTextItem(&staticTextItem);
- }
-
-}
-
-
-void QOpenGLPaintEngine::drawEllipse(const QRectF &rect)
-{
-#ifndef Q_WS_QWS
- Q_D(QOpenGLPaintEngine);
-
- if (d->use_emulation) {
- QPaintEngineEx::drawEllipse(rect);
- return;
- }
-
- if (d->high_quality_antialiasing) {
- if (d->has_brush) {
- d->disableClipping();
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- GLuint program = qt_gl_program_cache()->getProgram(d->device->context(),
- FRAGMENT_PROGRAM_MASK_ELLIPSE_AA, 0, true);
- QGLEllipseMaskGenerator maskGenerator(rect,
- d->matrix,
- d->offscreen,
- program,
- mask_variable_locations[FRAGMENT_PROGRAM_MASK_ELLIPSE_AA]);
-
- d->addItem(qt_mask_texture_cache()->getMask(maskGenerator, d));
-
- d->enableClipping();
-
- glMatrixMode(GL_MODELVIEW);
- glPopMatrix();
- }
-
- if (d->has_pen) {
- QPainterPath path;
- path.addEllipse(rect);
-
- d->strokePath(path, false);
- }
- } else {
- DEBUG_ONCE_STR("QOpenGLPaintEngine::drawEllipse(): falling back to drawPath()");
-
- QPainterPath path;
- path.addEllipse(rect);
- drawPath(path);
- }
-#else
- QPaintEngineEx::drawEllipse(rect);
-#endif
-}
-
-
-void QOpenGLPaintEnginePrivate::updateFragmentProgramData(int locations[])
-{
-#ifdef Q_WS_QWS
- Q_UNUSED(locations);
-#else
- QGL_FUNC_CONTEXT;
-
- QSize sz = offscreen.offscreenSize();
-
- float inv_mask_size_data[4] = { 1.0f / sz.width(), 1.0f / sz.height(), 0.0f, 0.0f };
-
- sz = drawable_texture_size;
-
- float inv_dst_size_data[4] = { 1.0f / sz.width(), 1.0f / sz.height(), 0.0f, 0.0f };
-
- // default inv size 0.125f == 1.0f / 8.0f for pattern brushes
- float inv_brush_texture_size_data[4] = { 0.125f, 0.125f };
-
- // texture patterns have their own size
- if (current_style == Qt::TexturePattern) {
- QSize sz = cbrush.texture().size();
-
- inv_brush_texture_size_data[0] = 1.0f / sz.width();
- inv_brush_texture_size_data[1] = 1.0f / sz.height();
- }
-
- for (unsigned int i = 0; i < num_fragment_variables; ++i) {
- int location = locations[i];
-
- if (location < 0)
- continue;
-
- switch (i) {
- case VAR_ANGLE:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, angle_data);
- break;
- case VAR_LINEAR:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, linear_data);
- break;
- case VAR_FMP:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, fmp_data);
- break;
- case VAR_FMP2_M_RADIUS2:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, fmp2_m_radius2_data);
- break;
- case VAR_INV_MASK_SIZE:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, inv_mask_size_data);
- break;
- case VAR_INV_DST_SIZE:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, inv_dst_size_data);
- break;
- case VAR_INV_MATRIX_M0:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, inv_matrix_data[0]);
- break;
- case VAR_INV_MATRIX_M1:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, inv_matrix_data[1]);
- break;
- case VAR_INV_MATRIX_M2:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, inv_matrix_data[2]);
- break;
- case VAR_PORTERDUFF_AB:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, porterduff_ab_data);
- break;
- case VAR_PORTERDUFF_XYZ:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, porterduff_xyz_data);
- break;
- case VAR_INV_BRUSH_TEXTURE_SIZE:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, inv_brush_texture_size_data);
- break;
- case VAR_MASK_OFFSET:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, mask_offset_data);
- break;
- case VAR_MASK_CHANNEL:
- glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, location, mask_channel_data);
- break;
- case VAR_DST_TEXTURE:
- case VAR_MASK_TEXTURE:
- case VAR_PALETTE:
- case VAR_BRUSH_TEXTURE:
- // texture variables, not handled here
- break;
- default:
- qDebug() << "QOpenGLPaintEnginePrivate: Unhandled fragment variable:" << i;
- }
- }
-#endif
-}
-
-
-void QOpenGLPaintEnginePrivate::copyDrawable(const QRectF &rect)
-{
-#ifdef Q_WS_QWS
- Q_UNUSED(rect);
-#else
- ensureDrawableTexture();
-
- DEBUG_ONCE qDebug() << "Refreshing drawable_texture for rectangle" << rect;
- QRectF screen_rect = rect.adjusted(-1, -1, 1, 1);
-
- int left = qMax(0, static_cast<int>(screen_rect.left()));
- int width = qMin(device->size().width() - left, static_cast<int>(screen_rect.width()) + 1);
-
- int bottom = qMax(0, static_cast<int>(device->size().height() - screen_rect.bottom()));
- int height = qMin(device->size().height() - bottom, static_cast<int>(screen_rect.height()) + 1);
-
- glBindTexture(GL_TEXTURE_2D, drawable_texture);
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, left, bottom, left, bottom, width, height);
-#endif
-}
-
-
-void QOpenGLPaintEnginePrivate::composite(const QRectF &rect, const QPoint &maskOffset)
-{
-#ifdef Q_WS_QWS
- Q_UNUSED(rect);
- Q_UNUSED(maskOffset);
-#else
- GLfloat vertexArray[8];
- qt_add_rect_to_array(rect, vertexArray);
-
- composite(GL_TRIANGLE_FAN, vertexArray, 4, maskOffset);
-#endif
-}
-
-
-void QOpenGLPaintEnginePrivate::composite(GLuint primitive, const GLfloat *vertexArray, int vertexCount, const QPoint &maskOffset)
-{
-#ifdef QT_OPENGL_ES
- Q_UNUSED(primitive);
- Q_UNUSED(vertexArray);
- Q_UNUSED(vertexCount);
- Q_UNUSED(maskOffset);
-#else
- Q_Q(QOpenGLPaintEngine);
- QGL_FUNC_CONTEXT;
-
- if (current_style == Qt::NoBrush)
- return;
-
- DEBUG_ONCE qDebug() << "QOpenGLPaintEnginePrivate: Using compositing program: fragment_brush ="
- << fragment_brush << ", fragment_composition_mode =" << fragment_composition_mode;
-
- if (has_fast_composition_mode)
- q->updateCompositionMode(composition_mode);
- else {
- qreal minX = 1e9, minY = 1e9, maxX = -1e9, maxY = -1e9;
-
- for (int i = 0; i < vertexCount; ++i) {
- qreal x = vertexArray[2 * i];
- qreal y = vertexArray[2 * i + 1];
-
- qreal tx, ty;
- matrix.map(x, y, &tx, &ty);
-
- minX = qMin(minX, tx);
- minY = qMin(minY, ty);
- maxX = qMax(maxX, tx);
- maxY = qMax(maxY, ty);
- }
-
- QRectF r(minX, minY, maxX - minX, maxY - minY);
- copyDrawable(r);
-
- glBlendFunc(GL_ONE, GL_ZERO);
- }
-
- int *locations = painter_variable_locations[fragment_brush][fragment_composition_mode];
-
- int texture_locations[] = { locations[VAR_DST_TEXTURE],
- locations[VAR_MASK_TEXTURE],
- locations[VAR_PALETTE] };
-
- int brush_texture_location = locations[VAR_BRUSH_TEXTURE];
-
- GLuint texture_targets[] = { GL_TEXTURE_2D,
- GL_TEXTURE_2D,
- GL_TEXTURE_1D };
-
- GLuint textures[] = { drawable_texture,
- offscreen.offscreenTexture(),
- grad_palette };
-
- const int num_textures = sizeof(textures) / sizeof(*textures);
-
- Q_ASSERT(num_textures == sizeof(texture_locations) / sizeof(*texture_locations));
- Q_ASSERT(num_textures == sizeof(texture_targets) / sizeof(*texture_targets));
-
- for (int i = 0; i < num_textures; ++i)
- if (texture_locations[i] >= 0) {
- glActiveTexture(GL_TEXTURE0 + texture_locations[i]);
- glBindTexture(texture_targets[i], textures[i]);
- }
-
- if (brush_texture_location >= 0) {
- glActiveTexture(GL_TEXTURE0 + brush_texture_location);
-
- if (current_style == Qt::TexturePattern)
- device->context()->d_func()->bindTexture(cbrush.textureImage(), GL_TEXTURE_2D, GL_RGBA,
- QGLContext::InternalBindOption);
- else
- device->context()->d_func()->bindTexture(qt_imageForBrush(current_style, false),
- GL_TEXTURE_2D, GL_RGBA,
- QGLContext::InternalBindOption);
-
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, use_smooth_pixmap_transform);
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glEnable(GL_FRAGMENT_PROGRAM_ARB);
- GLuint program = qt_gl_program_cache()->getProgram(device->context(),
- fragment_brush,
- fragment_composition_mode, false);
- glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program);
-
- mask_offset_data[0] = maskOffset.x();
- mask_offset_data[1] = -maskOffset.y();
-
- updateFragmentProgramData(locations);
-
- glDrawArrays(primitive, 0, vertexCount);
-
- glDisable(GL_FRAGMENT_PROGRAM_ARB);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- for (int i = 0; i < num_textures; ++i)
- if (texture_locations[i] >= 0) {
- glActiveTexture(GL_TEXTURE0 + texture_locations[i]);
- glBindTexture(texture_targets[i], 0);
- }
-
- if (brush_texture_location >= 0) {
- glActiveTexture(GL_TEXTURE0 + brush_texture_location);
- glBindTexture(GL_TEXTURE_2D, 0);
- }
-
- glActiveTexture(GL_TEXTURE0);
-
- if (!has_fast_composition_mode)
- q->updateCompositionMode(composition_mode);
-#endif
-}
-
-void QOpenGLPaintEnginePrivate::cacheItemErased(int channel, const QRect &rect)
-{
- bool isInDrawQueue = false;
-
- foreach (const QDrawQueueItem &item, drawQueue) {
- if (item.location.channel == channel && item.location.rect == rect) {
- isInDrawQueue = true;
- break;
- }
- }
-
- if (isInDrawQueue)
- flushDrawQueue();
-}
-
-void QOpenGLPaintEnginePrivate::addItem(const QGLMaskTextureCache::CacheLocation &location)
-{
- drawQueue << QDrawQueueItem(opacity, cbrush, brush_origin, composition_mode, matrix, location);
-}
-
-void QOpenGLPaintEnginePrivate::drawItem(const QDrawQueueItem &item)
-{
- Q_Q(QOpenGLPaintEngine);
-
- opacity = item.opacity;
- brush_origin = item.brush_origin;
- q->updateCompositionMode(item.composition_mode);
- matrix = item.matrix;
- cbrush = item.brush;
- brush_style = item.brush.style();
-
- mask_channel_data[0] = item.location.channel == 0;
- mask_channel_data[1] = item.location.channel == 1;
- mask_channel_data[2] = item.location.channel == 2;
- mask_channel_data[3] = item.location.channel == 3;
-
- setGradientOps(item.brush, item.location.screen_rect);
-
- composite(item.location.screen_rect, item.location.rect.topLeft() - item.location.screen_rect.topLeft()
- - QPoint(0, offscreen.offscreenSize().height() - device->size().height()));
-}
-
-void QOpenGLPaintEnginePrivate::flushDrawQueue()
-{
-#ifndef QT_OPENGL_ES
- Q_Q(QOpenGLPaintEngine);
-
- offscreen.release();
-
- if (!drawQueue.isEmpty()) {
- DEBUG_ONCE qDebug() << "QOpenGLPaintEngine::flushDrawQueue():" << drawQueue.size() << "items";
-
- glPushMatrix();
- glLoadIdentity();
- qreal old_opacity = opacity;
- QPointF old_brush_origin = brush_origin;
- QPainter::CompositionMode old_composition_mode = composition_mode;
- QTransform old_matrix = matrix;
- QBrush old_brush = cbrush;
-
- bool hqaa_old = high_quality_antialiasing;
-
- high_quality_antialiasing = true;
-
- foreach (const QDrawQueueItem &item, drawQueue)
- drawItem(item);
-
- opacity = old_opacity;
- brush_origin = old_brush_origin;
- q->updateCompositionMode(old_composition_mode);
- matrix = old_matrix;
- cbrush = old_brush;
- brush_style = old_brush.style();
-
- high_quality_antialiasing = hqaa_old;
-
- setGLBrush(old_brush.color());
- qt_glColor4ubv(brush_color);
-
- drawQueue.clear();
-
- glPopMatrix();
- }
-#endif
-}
-
-void QOpenGLPaintEngine::clipEnabledChanged()
-{
- Q_D(QOpenGLPaintEngine);
-
- d->updateDepthClip();
-}
-
-void QOpenGLPaintEngine::penChanged()
-{
- updatePen(state()->pen);
-}
-
-void QOpenGLPaintEngine::brushChanged()
-{
- updateBrush(state()->brush, state()->brushOrigin);
-}
-
-void QOpenGLPaintEngine::brushOriginChanged()
-{
- updateBrush(state()->brush, state()->brushOrigin);
-}
-
-void QOpenGLPaintEngine::opacityChanged()
-{
- Q_D(QOpenGLPaintEngine);
- QPainterState *s = state();
- d->opacity = s->opacity;
- updateBrush(s->brush, s->brushOrigin);
- updatePen(s->pen);
-}
-
-void QOpenGLPaintEngine::compositionModeChanged()
-{
- updateCompositionMode(state()->composition_mode);
-}
-
-void QOpenGLPaintEngine::renderHintsChanged()
-{
- updateRenderHints(state()->renderHints);
-}
-
-void QOpenGLPaintEngine::transformChanged()
-{
- updateMatrix(state()->matrix);
-}
-
-extern QPainterPath qt_painterPathFromVectorPath(const QVectorPath &path);
-
-void QOpenGLPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
-{
- Q_D(QOpenGLPaintEngine);
-
- if (brush.style() == Qt::NoBrush)
- return;
-
- if ((!d->use_fragment_programs && needsEmulation(brush.style())) || qt_isExtendedRadialGradient(brush)) {
- QPainter *p = painter();
- QBrush oldBrush = p->brush();
- p->setBrush(brush);
- qt_draw_helper(p->d_ptr.data(), qt_painterPathFromVectorPath(path), QPainterPrivate::FillDraw);
- p->setBrush(oldBrush);
- return;
- }
-
- QBrush old_brush = state()->brush;
- updateBrush(brush, state()->brushOrigin);
-
- const qreal *points = path.points();
- const QPainterPath::ElementType *types = path.elements();
- if (!types && path.shape() == QVectorPath::RectangleHint) {
- QRectF r(points[0], points[1], points[4]-points[0], points[5]-points[1]);
- QPen old_pen = state()->pen;
- updatePen(Qt::NoPen);
- drawRects(&r, 1);
- updatePen(old_pen);
- } else {
- d->fillPath(qt_painterPathFromVectorPath(path));
- }
-
- updateBrush(old_brush, state()->brushOrigin);
-}
-
-template <typename T> static inline bool isRect(const T *pts, int elementCount) {
- return (elementCount == 5 // 5-point polygon, check for closed rect
- && pts[0] == pts[8] && pts[1] == pts[9] // last point == first point
- && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
- && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
- ) ||
- (elementCount == 4 // 4-point polygon, check for unclosed rect
- && pts[0] == pts[6] && pts[2] == pts[4] // x values equal
- && pts[1] == pts[3] && pts[5] == pts[7] // y values equal...
- );
-}
-
-void QOpenGLPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
-{
- const qreal *points = path.points();
- const QPainterPath::ElementType *types = path.elements();
- if (!types && path.shape() == QVectorPath::RectangleHint) {
- QRectF r(points[0], points[1], points[4]-points[0], points[5]-points[1]);
- updateClipRegion(QRegion(r.toRect()), op);
- return;
- }
-
- QPainterPath p;
- if (types) {
- int id = 0;
- for (int i=0; i<path.elementCount(); ++i) {
- switch(types[i]) {
- case QPainterPath::MoveToElement:
- p.moveTo(QPointF(points[id], points[id+1]));
- id+=2;
- break;
- case QPainterPath::LineToElement:
- p.lineTo(QPointF(points[id], points[id+1]));
- id+=2;
- break;
- case QPainterPath::CurveToElement: {
- QPointF p1(points[id], points[id+1]);
- QPointF p2(points[id+2], points[id+3]);
- QPointF p3(points[id+4], points[id+5]);
- p.cubicTo(p1, p2, p3);
- id+=6;
- break;
- }
- case QPainterPath::CurveToDataElement:
- ;
- break;
- }
- }
- } else if (!path.isEmpty()) {
- p.moveTo(QPointF(points[0], points[1]));
- int id = 2;
- for (int i=1; i<path.elementCount(); ++i) {
- p.lineTo(QPointF(points[id], points[id+1]));
- id+=2;
- }
- }
- if (path.hints() & QVectorPath::WindingFill)
- p.setFillRule(Qt::WindingFill);
-
- updateClipRegion(QRegion(p.toFillPolygon().toPolygon(), p.fillRule()), op);
- return;
-}
-
-void QOpenGLPaintEngine::setState(QPainterState *s)
-{
- Q_D(QOpenGLPaintEngine);
- QOpenGLPaintEngineState *new_state = static_cast<QOpenGLPaintEngineState *>(s);
- QOpenGLPaintEngineState *old_state = state();
-
- QPaintEngineEx::setState(s);
-
- // are we in a save() ?
- if (s == d->last_created_state) {
- d->last_created_state = 0;
- return;
- }
-
- if (isActive()) {
- if (old_state->depthClipId != new_state->depthClipId)
- d->updateDepthClip();
- penChanged();
- brushChanged();
- opacityChanged();
- compositionModeChanged();
- renderHintsChanged();
- transformChanged();
- }
-}
-
-QPainterState *QOpenGLPaintEngine::createState(QPainterState *orig) const
-{
- const Q_D(QOpenGLPaintEngine);
-
- QOpenGLPaintEngineState *s;
- if (!orig)
- s = new QOpenGLPaintEngineState();
- else
- s = new QOpenGLPaintEngineState(*static_cast<QOpenGLPaintEngineState *>(orig));
-
- d->last_created_state = s;
- return s;
-}
-
-//
-// QOpenGLPaintEngineState
-//
-
-QOpenGLPaintEngineState::QOpenGLPaintEngineState(QOpenGLPaintEngineState &other)
- : QPainterState(other)
-{
- clipRegion = other.clipRegion;
- hasClipping = other.hasClipping;
- fastClip = other.fastClip;
- depthClipId = other.depthClipId;
-}
-
-QOpenGLPaintEngineState::QOpenGLPaintEngineState()
-{
- hasClipping = false;
- depthClipId = 0;
-}
-
-QOpenGLPaintEngineState::~QOpenGLPaintEngineState()
-{
-}
-
-void QOpenGLPaintEnginePrivate::ensureDrawableTexture()
-{
- if (!dirty_drawable_texture)
- return;
-
- dirty_drawable_texture = false;
-
-#ifndef QT_OPENGL_ES
- glGenTextures(1, &drawable_texture);
- glBindTexture(GL_TEXTURE_2D, drawable_texture);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
- drawable_texture_size.width(),
- drawable_texture_size.height(), 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-#endif
-}
-
-QT_END_NAMESPACE
-
-#include "qpaintengine_opengl.moc"
diff --git a/src/opengl/qpaintengine_opengl_p.h b/src/opengl/qpaintengine_opengl_p.h
deleted file mode 100644
index 8d0ea83a47..0000000000
--- a/src/opengl/qpaintengine_opengl_p.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPAINTENGINE_OPENGL_P_H
-#define QPAINTENGINE_OPENGL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qpaintengineex_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QOpenGLPaintEnginePrivate;
-class QGLTexture;
-
-class QOpenGLPaintEngineState : public QPainterState
-{
-public:
- QOpenGLPaintEngineState(QOpenGLPaintEngineState &other);
- QOpenGLPaintEngineState();
- ~QOpenGLPaintEngineState();
-
- QRegion clipRegion;
- bool hasClipping;
- QRect fastClip;
- uint depthClipId;
-};
-
-class QOpenGLPaintEngine : public QPaintEngineEx
-{
- Q_DECLARE_PRIVATE(QOpenGLPaintEngine)
-public:
- QOpenGLPaintEngine();
- ~QOpenGLPaintEngine();
-
- bool begin(QPaintDevice *pdev);
- bool end();
-
- // new stuff
- void clipEnabledChanged();
- void penChanged();
- void brushChanged();
- void brushOriginChanged();
- void opacityChanged();
- void compositionModeChanged();
- void renderHintsChanged();
- void transformChanged();
-
- void fill(const QVectorPath &path, const QBrush &brush);
- void clip(const QVectorPath &path, Qt::ClipOperation op);
-
- void setState(QPainterState *s);
- QPainterState *createState(QPainterState *orig) const;
- inline QOpenGLPaintEngineState *state() {
- return static_cast<QOpenGLPaintEngineState *>(QPaintEngineEx::state());
- }
- inline const QOpenGLPaintEngineState *state() const {
- return static_cast<const QOpenGLPaintEngineState *>(QPaintEngineEx::state());
- }
-
-
- // old stuff
- void updateState(const QPaintEngineState &state);
-
- void updatePen(const QPen &pen);
- void updateBrush(const QBrush &brush, const QPointF &pt);
- void updateFont(const QFont &font);
- void updateMatrix(const QTransform &matrix);
- void updateClipRegion(const QRegion &region, Qt::ClipOperation op);
- void updateRenderHints(QPainter::RenderHints hints);
- void updateCompositionMode(QPainter::CompositionMode composition_mode);
-
- void drawRects(const QRectF *r, int rectCount);
- void drawLines(const QLineF *lines, int lineCount);
- void drawPoints(const QPointF *p, int pointCount);
- void drawRects(const QRect *r, int rectCount);
- void drawLines(const QLine *lines, int lineCount);
- void drawPoints(const QPoint *p, int pointCount);
-
- void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
-
- void drawPath(const QPainterPath &path);
- void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
- void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
- void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
- void drawImage(const QRectF &r, const QImage &image, const QRectF &sr,
- Qt::ImageConversionFlags conversionFlags);
- void drawTextItem(const QPointF &p, const QTextItem &ti);
- void drawStaticTextItem(QStaticTextItem *staticTextItem);
-
- void drawEllipse(const QRectF &rect);
-
-#ifdef Q_WS_WIN
- HDC handle() const;
-#else
- Qt::HANDLE handle() const;
-#endif
- inline Type type() const { return QPaintEngine::OpenGL; }
- bool supportsTransformations(qreal, const QTransform &) const { return true; }
-
-private:
- void drawPolyInternal(const QPolygonF &pa, bool close = true);
- void drawTextureRect(int tx_width, int tx_height, const QRectF &r, const QRectF &sr,
- GLenum target, QGLTexture *tex);
- Q_DISABLE_COPY(QOpenGLPaintEngine)
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QPAINTENGINE_OPENGL_P_H
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
deleted file mode 100644
index e909ff30b9..0000000000
--- a/src/opengl/qpixmapdata_gl.cpp
+++ /dev/null
@@ -1,829 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpixmap.h"
-#include "qglframebufferobject.h"
-
-#include <private/qpaintengine_raster_p.h>
-
-#include "qpixmapdata_gl_p.h"
-
-#include <private/qgl_p.h>
-#include <private/qdrawhelper_p.h>
-#include <private/qimage_p.h>
-#include <private/qfont_p.h>
-
-#include <private/qpaintengineex_opengl2_p.h>
-
-#include <qdesktopwidget.h>
-#include <qfile.h>
-#include <qimagereader.h>
-#include <qbuffer.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_OPENGL_EXPORT extern const QGLContext* qt_gl_share_context();
-
-/*!
- \class QGLFramebufferObjectPool
- \since 4.6
-
- \brief The QGLFramebufferObject class provides a pool of framebuffer
- objects for offscreen rendering purposes.
-
- When requesting an FBO of a given size and format, an FBO of the same
- format and a size at least as big as the requested size will be returned.
-
- \internal
-*/
-
-static inline int areaDiff(const QSize &size, const QGLFramebufferObject *fbo)
-{
- return qAbs(size.width() * size.height() - fbo->width() * fbo->height());
-}
-
-extern int qt_next_power_of_two(int v);
-
-static inline QSize maybeRoundToNextPowerOfTwo(const QSize &sz)
-{
-#ifdef QT_OPENGL_ES_2
- QSize rounded(qt_next_power_of_two(sz.width()), qt_next_power_of_two(sz.height()));
- if (rounded.width() * rounded.height() < 1.20 * sz.width() * sz.height())
- return rounded;
-#endif
- return sz;
-}
-
-
-QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize, const QGLFramebufferObjectFormat &requestFormat, bool strictSize)
-{
- QGLFramebufferObject *chosen = 0;
- QGLFramebufferObject *candidate = 0;
- for (int i = 0; !chosen && i < m_fbos.size(); ++i) {
- QGLFramebufferObject *fbo = m_fbos.at(i);
-
- if (strictSize) {
- if (fbo->size() == requestSize && fbo->format() == requestFormat) {
- chosen = fbo;
- break;
- } else {
- continue;
- }
- }
-
- if (fbo->format() == requestFormat) {
- // choose the fbo with a matching format and the closest size
- if (!candidate || areaDiff(requestSize, candidate) > areaDiff(requestSize, fbo))
- candidate = fbo;
- }
-
- if (candidate) {
- m_fbos.removeOne(candidate);
-
- const QSize fboSize = candidate->size();
- QSize sz = fboSize;
-
- if (sz.width() < requestSize.width())
- sz.setWidth(qMax(requestSize.width(), qRound(sz.width() * 1.5)));
- if (sz.height() < requestSize.height())
- sz.setHeight(qMax(requestSize.height(), qRound(sz.height() * 1.5)));
-
- // wasting too much space?
- if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 4)
- sz = requestSize;
-
- if (sz != fboSize) {
- delete candidate;
- candidate = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(sz), requestFormat);
- }
-
- chosen = candidate;
- }
- }
-
- if (!chosen) {
- if (strictSize)
- chosen = new QGLFramebufferObject(requestSize, requestFormat);
- else
- chosen = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(requestSize), requestFormat);
- }
-
- if (!chosen->isValid()) {
- delete chosen;
- chosen = 0;
- }
-
- return chosen;
-}
-
-void QGLFramebufferObjectPool::release(QGLFramebufferObject *fbo)
-{
- if (fbo)
- m_fbos << fbo;
-}
-
-
-QPaintEngine* QGLPixmapGLPaintDevice::paintEngine() const
-{
- return data->paintEngine();
-}
-
-void QGLPixmapGLPaintDevice::beginPaint()
-{
- if (!data->isValid())
- return;
-
- // QGLPaintDevice::beginPaint will store the current binding and replace
- // it with m_thisFBO:
- m_thisFBO = data->m_renderFbo->handle();
- QGLPaintDevice::beginPaint();
-
- Q_ASSERT(data->paintEngine()->type() == QPaintEngine::OpenGL2);
-
- // QPixmap::fill() is deferred until now, where we actually need to do the fill:
- if (data->needsFill()) {
- const QColor &c = data->fillColor();
- float alpha = c.alphaF();
- glDisable(GL_SCISSOR_TEST);
- glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha);
- glClear(GL_COLOR_BUFFER_BIT);
- }
- else if (!data->isUninitialized()) {
- // If the pixmap (GL Texture) has valid content (it has been
- // uploaded from an image or rendered into before), we need to
- // copy it from the texture to the render FBO.
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
- glDisable(GL_BLEND);
-
-#if !defined(QT_OPENGL_ES_2)
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, data->width(), data->height(), 0, -999999, 999999);
-#endif
-
- glViewport(0, 0, data->width(), data->height());
-
- // Pass false to bind so it doesn't copy the FBO into the texture!
- context()->drawTexture(QRect(0, 0, data->width(), data->height()), data->bind(false));
- }
-}
-
-void QGLPixmapGLPaintDevice::endPaint()
-{
- if (!data->isValid())
- return;
-
- data->copyBackFromRenderFbo(false);
-
- // Base's endPaint will restore the previous FBO binding
- QGLPaintDevice::endPaint();
-
- qgl_fbo_pool()->release(data->m_renderFbo);
- data->m_renderFbo = 0;
-}
-
-QGLContext* QGLPixmapGLPaintDevice::context() const
-{
- data->ensureCreated();
- return data->m_ctx;
-}
-
-QSize QGLPixmapGLPaintDevice::size() const
-{
- return data->size();
-}
-
-bool QGLPixmapGLPaintDevice::alphaRequested() const
-{
- return data->m_hasAlpha;
-}
-
-void QGLPixmapGLPaintDevice::setPixmapData(QGLPixmapData* d)
-{
- data = d;
-}
-
-static int qt_gl_pixmap_serial = 0;
-
-QGLPixmapData::QGLPixmapData(PixelType type)
- : QPixmapData(type, OpenGLClass)
- , m_renderFbo(0)
- , m_engine(0)
- , m_ctx(0)
- , m_dirty(false)
- , m_hasFillColor(false)
- , m_hasAlpha(false)
-{
- setSerialNumber(++qt_gl_pixmap_serial);
- m_glDevice.setPixmapData(this);
-}
-
-QGLPixmapData::~QGLPixmapData()
-{
- const QGLContext *shareContext = qt_gl_share_context();
- if (!shareContext)
- return;
-
- delete m_engine;
-
- if (m_texture.id) {
- QGLShareContextScope ctx(shareContext);
- glDeleteTextures(1, &m_texture.id);
- }
-}
-
-QPixmapData *QGLPixmapData::createCompatiblePixmapData() const
-{
- return new QGLPixmapData(pixelType());
-}
-
-bool QGLPixmapData::isValid() const
-{
- return w > 0 && h > 0;
-}
-
-bool QGLPixmapData::isValidContext(const QGLContext *ctx) const
-{
- if (ctx == m_ctx)
- return true;
-
- const QGLContext *share_ctx = qt_gl_share_context();
- return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx);
-}
-
-void QGLPixmapData::resize(int width, int height)
-{
- if (width == w && height == h)
- return;
-
- if (width <= 0 || height <= 0) {
- width = 0;
- height = 0;
- }
-
- w = width;
- h = height;
- is_null = (w <= 0 || h <= 0);
- d = pixelType() == QPixmapData::PixmapType ? 32 : 1;
-
- if (m_texture.id) {
- QGLShareContextScope ctx(qt_gl_share_context());
- glDeleteTextures(1, &m_texture.id);
- m_texture.id = 0;
- }
-
- m_source = QImage();
- m_dirty = isValid();
- setSerialNumber(++qt_gl_pixmap_serial);
-}
-
-void QGLPixmapData::ensureCreated() const
-{
- if (!m_dirty)
- return;
-
- m_dirty = false;
-
- QGLShareContextScope ctx(qt_gl_share_context());
- m_ctx = ctx;
-
- const GLenum internal_format = m_hasAlpha ? GL_RGBA : GL_RGB;
-#ifdef QT_OPENGL_ES_2
- const GLenum external_format = internal_format;
-#else
- const GLenum external_format = qt_gl_preferredTextureFormat();
-#endif
- const GLenum target = GL_TEXTURE_2D;
-
- if (!m_texture.id) {
- glGenTextures(1, &m_texture.id);
- glBindTexture(target, m_texture.id);
- glTexImage2D(target, 0, internal_format, w, h, 0, external_format, GL_UNSIGNED_BYTE, 0);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
-
- if (!m_source.isNull()) {
- if (external_format == GL_RGB) {
- const QImage tx = m_source.convertToFormat(QImage::Format_RGB888).mirrored(false, true);
-
- glBindTexture(target, m_texture.id);
- glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
- GL_UNSIGNED_BYTE, tx.bits());
- } else {
- const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, external_format);
-
- glBindTexture(target, m_texture.id);
- glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
- GL_UNSIGNED_BYTE, tx.bits());
- }
-
- if (useFramebufferObjects())
- m_source = QImage();
- }
-
- m_texture.options &= ~QGLContext::MemoryManagedBindOption;
-}
-
-void QGLPixmapData::fromImage(const QImage &image,
- Qt::ImageConversionFlags flags)
-{
- QImage img = image;
- createPixmapForImage(img, flags, false);
-}
-
-void QGLPixmapData::fromImageReader(QImageReader *imageReader,
- Qt::ImageConversionFlags flags)
-{
- QImage image = imageReader->read();
- if (image.isNull())
- return;
-
- createPixmapForImage(image, flags, true);
-}
-
-bool QGLPixmapData::fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags)
-{
- if (pixelType() == QPixmapData::BitmapType)
- return QPixmapData::fromFile(filename, format, flags);
- QFile file(filename);
- if (file.open(QIODevice::ReadOnly)) {
- QByteArray data = file.peek(64);
- bool alpha;
- if (m_texture.canBindCompressedTexture
- (data.constData(), data.size(), format, &alpha)) {
- resize(0, 0);
- data = file.readAll();
- file.close();
- QGLShareContextScope ctx(qt_gl_share_context());
- QSize size = m_texture.bindCompressedTexture
- (data.constData(), data.size(), format);
- if (!size.isEmpty()) {
- w = size.width();
- h = size.height();
- is_null = false;
- d = 32;
- m_hasAlpha = alpha;
- m_source = QImage();
- m_dirty = isValid();
- return true;
- }
- return false;
- }
- }
-
- QImage image = QImageReader(filename, format).read();
- if (image.isNull())
- return false;
-
- createPixmapForImage(image, flags, true);
-
- return !isNull();
-}
-
-bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags)
-{
- bool alpha;
- const char *buf = reinterpret_cast<const char *>(buffer);
- if (m_texture.canBindCompressedTexture(buf, int(len), format, &alpha)) {
- resize(0, 0);
- QGLShareContextScope ctx(qt_gl_share_context());
- QSize size = m_texture.bindCompressedTexture(buf, int(len), format);
- if (!size.isEmpty()) {
- w = size.width();
- h = size.height();
- is_null = false;
- d = 32;
- m_hasAlpha = alpha;
- m_source = QImage();
- m_dirty = isValid();
- return true;
- }
- }
-
- QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len);
- QBuffer b(&a);
- b.open(QIODevice::ReadOnly);
- QImage image = QImageReader(&b, format).read();
- if (image.isNull())
- return false;
-
- createPixmapForImage(image, flags, true);
-
- return !isNull();
-}
-
-/*!
- out-of-place conversion (inPlace == false) will always detach()
- */
-void QGLPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
-{
- if (image.size() == QSize(w, h))
- setSerialNumber(++qt_gl_pixmap_serial);
-
- resize(image.width(), image.height());
-
- if (pixelType() == BitmapType) {
- m_source = image.convertToFormat(QImage::Format_MonoLSB);
-
- } else {
- QImage::Format format = QImage::Format_RGB32;
- if (qApp->desktop()->depth() == 16)
- format = QImage::Format_RGB16;
-
- if (image.hasAlphaChannel()
- && ((flags & Qt::NoOpaqueDetection)
- || const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()))
- format = QImage::Format_ARGB32_Premultiplied;;
-
- if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
- m_source = image;
- } else {
- m_source = image.convertToFormat(format);
-
- // convertToFormat won't detach the image if format stays the same.
- if (image.format() == format)
- m_source.detach();
- }
- }
-
- m_dirty = true;
- m_hasFillColor = false;
-
- m_hasAlpha = m_source.hasAlphaChannel();
- w = image.width();
- h = image.height();
- is_null = (w <= 0 || h <= 0);
- d = m_source.depth();
-
- if (m_texture.id) {
- QGLShareContextScope ctx(qt_gl_share_context());
- glDeleteTextures(1, &m_texture.id);
- m_texture.id = 0;
- }
-}
-
-bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- Q_UNUSED(dx);
- Q_UNUSED(dy);
- Q_UNUSED(rect);
- return false;
-}
-
-void QGLPixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- if (data->classId() != QPixmapData::OpenGLClass || !static_cast<const QGLPixmapData *>(data)->useFramebufferObjects()) {
- QPixmapData::copy(data, rect);
- return;
- }
-
- const QGLPixmapData *other = static_cast<const QGLPixmapData *>(data);
- if (other->m_renderFbo) {
- QGLShareContextScope ctx(qt_gl_share_context());
-
- resize(rect.width(), rect.height());
- m_hasAlpha = other->m_hasAlpha;
- ensureCreated();
-
- if (!ctx->d_ptr->fbo)
- glGenFramebuffers(1, &ctx->d_ptr->fbo);
-
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo);
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, m_texture.id, 0);
-
- if (!other->m_renderFbo->isBound())
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, other->m_renderFbo->handle());
-
- glDisable(GL_SCISSOR_TEST);
- if (ctx->d_ptr->active_engine && ctx->d_ptr->active_engine->type() == QPaintEngine::OpenGL2)
- static_cast<QGL2PaintEngineEx *>(ctx->d_ptr->active_engine)->invalidateState();
-
- glBlitFramebufferEXT(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height(),
- 0, 0, w, h,
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
- } else {
- QPixmapData::copy(data, rect);
- }
-}
-
-void QGLPixmapData::fill(const QColor &color)
-{
- if (!isValid())
- return;
-
- bool hasAlpha = color.alpha() != 255;
- if (hasAlpha && !m_hasAlpha) {
- if (m_texture.id) {
- glDeleteTextures(1, &m_texture.id);
- m_texture.id = 0;
- m_dirty = true;
- }
- m_hasAlpha = color.alpha() != 255;
- }
-
- if (useFramebufferObjects()) {
- m_source = QImage();
- m_hasFillColor = true;
- m_fillColor = color;
- } else {
-
- if (m_source.isNull()) {
- m_fillColor = color;
- m_hasFillColor = true;
-
- } else if (m_source.depth() == 32) {
- m_source.fill(PREMUL(color.rgba()));
-
- } else if (m_source.depth() == 1) {
- if (color == Qt::color1)
- m_source.fill(1);
- else
- m_source.fill(0);
- }
- }
-}
-
-bool QGLPixmapData::hasAlphaChannel() const
-{
- return m_hasAlpha;
-}
-
-QImage QGLPixmapData::fillImage(const QColor &color) const
-{
- QImage img;
- if (pixelType() == BitmapType) {
- img = QImage(w, h, QImage::Format_MonoLSB);
-
- img.setColorCount(2);
- img.setColor(0, QColor(Qt::color0).rgba());
- img.setColor(1, QColor(Qt::color1).rgba());
-
- if (color == Qt::color1)
- img.fill(1);
- else
- img.fill(0);
- } else {
- img = QImage(w, h,
- m_hasAlpha
- ? QImage::Format_ARGB32_Premultiplied
- : QImage::Format_RGB32);
- img.fill(PREMUL(color.rgba()));
- }
- return img;
-}
-
-extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha);
-
-QImage QGLPixmapData::toImage() const
-{
- if (!isValid())
- return QImage();
-
- if (m_renderFbo) {
- copyBackFromRenderFbo(true);
- } else if (!m_source.isNull()) {
- QImageData *data = const_cast<QImage &>(m_source).data_ptr();
- if (data->paintEngine && data->paintEngine->isActive()
- && data->paintEngine->paintDevice() == &m_source)
- {
- return m_source.copy();
- }
- return m_source;
- } else if (m_dirty || m_hasFillColor) {
- return fillImage(m_fillColor);
- } else {
- ensureCreated();
- }
-
- QGLShareContextScope ctx(qt_gl_share_context());
- glBindTexture(GL_TEXTURE_2D, m_texture.id);
- return qt_gl_read_texture(QSize(w, h), true, true);
-}
-
-struct TextureBuffer
-{
- QGLFramebufferObject *fbo;
- QGL2PaintEngineEx *engine;
-};
-
-Q_GLOBAL_STATIC(QGLFramebufferObjectPool, _qgl_fbo_pool)
-QGLFramebufferObjectPool* qgl_fbo_pool()
-{
- return _qgl_fbo_pool();
-}
-
-void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const
-{
- if (!isValid())
- return;
-
- m_hasFillColor = false;
-
- const QGLContext *share_ctx = qt_gl_share_context();
- QGLShareContextScope ctx(share_ctx);
-
- ensureCreated();
-
- if (!ctx->d_ptr->fbo)
- glGenFramebuffers(1, &ctx->d_ptr->fbo);
-
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo);
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, m_texture.id, 0);
-
- const int x0 = 0;
- const int x1 = w;
- const int y0 = 0;
- const int y1 = h;
-
- if (!m_renderFbo->isBound())
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle());
-
- glDisable(GL_SCISSOR_TEST);
-
- glBlitFramebufferEXT(x0, y0, x1, y1,
- x0, y0, x1, y1,
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
- if (keepCurrentFboBound) {
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
- } else {
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, m_renderFbo->handle());
- ctx->d_ptr->current_fbo = m_renderFbo->handle();
- }
-}
-
-bool QGLPixmapData::useFramebufferObjects() const
-{
- return QGLFramebufferObject::hasOpenGLFramebufferObjects()
- && QGLFramebufferObject::hasOpenGLFramebufferBlit()
- && qt_gl_preferGL2Engine()
- && (w * h > 32*32); // avoid overhead of FBOs for small pixmaps
-}
-
-QPaintEngine* QGLPixmapData::paintEngine() const
-{
- if (!isValid())
- return 0;
-
- if (m_renderFbo)
- return m_engine;
-
- if (useFramebufferObjects()) {
- extern QGLWidget* qt_gl_share_widget();
-
- if (!QGLContext::currentContext())
- const_cast<QGLContext *>(qt_gl_share_context())->makeCurrent();
- QGLShareContextScope ctx(qt_gl_share_context());
-
- QGLFramebufferObjectFormat format;
- format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
- format.setSamples(4);
- format.setInternalTextureFormat(GLenum(m_hasAlpha ? GL_RGBA : GL_RGB));
-
- m_renderFbo = qgl_fbo_pool()->acquire(size(), format);
-
- if (m_renderFbo) {
- if (!m_engine)
- m_engine = new QGL2PaintEngineEx;
- return m_engine;
- }
-
- qWarning() << "Failed to create pixmap texture buffer of size " << size() << ", falling back to raster paint engine";
- }
-
- m_dirty = true;
- if (m_source.size() != size())
- m_source = QImage(size(), QImage::Format_ARGB32_Premultiplied);
- if (m_hasFillColor) {
- m_source.fill(PREMUL(m_fillColor.rgba()));
- m_hasFillColor = false;
- }
- return m_source.paintEngine();
-}
-
-extern QRgb qt_gl_convertToGLFormat(QRgb src_pixel, GLenum texture_format);
-
-// If copyBack is true, bind will copy the contents of the render
-// FBO to the texture (which is not bound to the texture, as it's
-// a multisample FBO).
-GLuint QGLPixmapData::bind(bool copyBack) const
-{
- if (m_renderFbo && copyBack) {
- copyBackFromRenderFbo(true);
- } else {
- ensureCreated();
- }
-
- GLuint id = m_texture.id;
- glBindTexture(GL_TEXTURE_2D, id);
-
- if (m_hasFillColor) {
- if (!useFramebufferObjects()) {
- m_source = QImage(w, h, QImage::Format_ARGB32_Premultiplied);
- m_source.fill(PREMUL(m_fillColor.rgba()));
- }
-
- m_hasFillColor = false;
-
- GLenum format = qt_gl_preferredTextureFormat();
- QImage tx(w, h, QImage::Format_ARGB32_Premultiplied);
- tx.fill(qt_gl_convertToGLFormat(m_fillColor.rgba(), format));
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.bits());
- }
-
- return id;
-}
-
-QGLTexture* QGLPixmapData::texture() const
-{
- return &m_texture;
-}
-
-int QGLPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
-{
- if (w == 0)
- return 0;
-
- switch (metric) {
- case QPaintDevice::PdmWidth:
- return w;
- case QPaintDevice::PdmHeight:
- return h;
- case QPaintDevice::PdmNumColors:
- return 0;
- case QPaintDevice::PdmDepth:
- return d;
- case QPaintDevice::PdmWidthMM:
- return qRound(w * 25.4 / qt_defaultDpiX());
- case QPaintDevice::PdmHeightMM:
- return qRound(h * 25.4 / qt_defaultDpiY());
- case QPaintDevice::PdmDpiX:
- case QPaintDevice::PdmPhysicalDpiX:
- return qt_defaultDpiX();
- case QPaintDevice::PdmDpiY:
- case QPaintDevice::PdmPhysicalDpiY:
- return qt_defaultDpiY();
- default:
- qWarning("QGLPixmapData::metric(): Invalid metric");
- return 0;
- }
-}
-
-QGLPaintDevice *QGLPixmapData::glDevice() const
-{
- return &m_glDevice;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h
deleted file mode 100644
index 909f264d05..0000000000
--- a/src/opengl/qpixmapdata_gl_p.h
+++ /dev/null
@@ -1,247 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPIXMAPDATA_GL_P_H
-#define QPIXMAPDATA_GL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qgl_p.h"
-#include "qgl.h"
-
-#include "private/qpixmapdata_p.h"
-#include "private/qglpaintdevice_p.h"
-
-#ifdef Q_OS_SYMBIAN
-#include "private/qvolatileimage_p.h"
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QPaintEngine;
-class QGLFramebufferObject;
-class QGLFramebufferObjectFormat;
-class QGLPixmapData;
-
-#ifdef QGL_USE_TEXTURE_POOL
-void qt_gl_register_pixmap(QGLPixmapData *pd);
-void qt_gl_unregister_pixmap(QGLPixmapData *pd);
-void qt_gl_hibernate_pixmaps();
-#endif
-
-#ifdef Q_OS_SYMBIAN
-class QNativeImageHandleProvider;
-#endif
-
-class QGLFramebufferObjectPool
-{
-public:
- QGLFramebufferObject *acquire(const QSize &size, const QGLFramebufferObjectFormat &format, bool strictSize = false);
- void release(QGLFramebufferObject *fbo);
-
-private:
- QList<QGLFramebufferObject *> m_fbos;
-};
-
-QGLFramebufferObjectPool* qgl_fbo_pool();
-
-
-class QGLPixmapGLPaintDevice : public QGLPaintDevice
-{
-public:
- QPaintEngine* paintEngine() const;
-
- void beginPaint();
- void endPaint();
- QGLContext* context() const;
- QSize size() const;
- bool alphaRequested() const;
-
- void setPixmapData(QGLPixmapData*);
-private:
- QGLPixmapData *data;
-};
-
-
-class Q_OPENGL_EXPORT QGLPixmapData : public QPixmapData
-{
-public:
- QGLPixmapData(PixelType type);
- ~QGLPixmapData();
-
- QPixmapData *createCompatiblePixmapData() const;
-
- // Re-implemented from QPixmapData:
- void resize(int width, int height);
- void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
- void fromImageReader(QImageReader *imageReader,
- Qt::ImageConversionFlags flags);
- bool fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags);
- bool fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags);
- void copy(const QPixmapData *data, const QRect &rect);
- bool scroll(int dx, int dy, const QRect &rect);
- void fill(const QColor &color);
- bool hasAlphaChannel() const;
- QImage toImage() const;
- QPaintEngine *paintEngine() const;
- int metric(QPaintDevice::PaintDeviceMetric metric) const;
-
- // For accessing as a target:
- QGLPaintDevice *glDevice() const;
-
- // For accessing as a source:
- bool isValidContext(const QGLContext *ctx) const;
- GLuint bind(bool copyBack = true) const;
- QGLTexture *texture() const;
-
-#ifdef QGL_USE_TEXTURE_POOL
- void destroyTexture();
- // Detach this image from the image pool.
- void detachTextureFromPool();
- // Release the GL resources associated with this pixmap and copy
- // the pixmap's contents out of the GPU back into main memory.
- // The GL resource will be automatically recreated the next time
- // ensureCreated() is called. Does nothing if the pixmap cannot be
- // hibernated for some reason (e.g. texture is shared with another
- // process via a SgImage).
- void hibernate();
- // Called when the QGLTexturePool wants to reclaim this pixmap's
- // texture objects to reuse storage.
- void reclaimTexture();
- void forceToImage();
-#endif
-
-#ifdef Q_OS_SYMBIAN
- QImage::Format idealFormat(QImage &image, Qt::ImageConversionFlags flags);
- void* toNativeType(NativeType type);
- void fromNativeType(void* pixmap, NativeType type);
- bool initFromNativeImageHandle(void *handle, const QString &type);
- void createFromNativeImageHandleProvider();
- void releaseNativeImageHandle();
-#endif
-
-private:
- bool isValid() const;
-
- void ensureCreated() const;
-
- bool isUninitialized() const { return m_dirty && m_source.isNull(); }
-
- bool needsFill() const { return m_hasFillColor; }
- QColor fillColor() const { return m_fillColor; }
-
-
-
- QGLPixmapData(const QGLPixmapData &other);
- QGLPixmapData &operator=(const QGLPixmapData &other);
-
- void copyBackFromRenderFbo(bool keepCurrentFboBound) const;
- QSize size() const { return QSize(w, h); }
-
- bool useFramebufferObjects() const;
-
- QImage fillImage(const QColor &color) const;
-
- void createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace);
-
- mutable QGLFramebufferObject *m_renderFbo;
- mutable QPaintEngine *m_engine;
- mutable QGLContext *m_ctx;
-#ifdef Q_OS_SYMBIAN
- mutable QVolatileImage m_source;
- mutable QNativeImageHandleProvider *nativeImageHandleProvider;
- void *nativeImageHandle;
- QString nativeImageType;
-#else
- mutable QImage m_source;
-#endif
- mutable QGLTexture m_texture;
-
- // the texture is not in sync with the source image
- mutable bool m_dirty;
-
- // fill has been called and no painting has been done, so the pixmap is
- // represented by a single fill color
- mutable QColor m_fillColor;
- mutable bool m_hasFillColor;
-
- mutable bool m_hasAlpha;
-
- mutable QGLPixmapGLPaintDevice m_glDevice;
-
-#ifdef QGL_USE_TEXTURE_POOL
- QGLPixmapData *nextLRU;
- QGLPixmapData *prevLRU;
- mutable bool inLRU;
- mutable bool failedToAlloc;
- mutable bool inTexturePool;
-
- QGLPixmapData *next;
- QGLPixmapData *prev;
-
- friend class QGLTexturePool;
-
- friend void qt_gl_register_pixmap(QGLPixmapData *pd);
- friend void qt_gl_unregister_pixmap(QGLPixmapData *pd);
- friend void qt_gl_hibernate_pixmaps();
-#endif
-
- friend class QGLPixmapGLPaintDevice;
- friend class QMeeGoPixmapData;
- friend class QMeeGoLivePixmapData;
-};
-
-QT_END_NAMESPACE
-
-#endif // QPIXMAPDATA_GL_P_H
-
-
diff --git a/src/opengl/qpixmapdata_poolgl.cpp b/src/opengl/qpixmapdata_poolgl.cpp
deleted file mode 100644
index 5dd7b09c64..0000000000
--- a/src/opengl/qpixmapdata_poolgl.cpp
+++ /dev/null
@@ -1,934 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qpixmap.h"
-#include "qglframebufferobject.h"
-
-#include <private/qpaintengine_raster_p.h>
-
-#include "qpixmapdata_gl_p.h"
-
-#include <private/qgl_p.h>
-#include <private/qdrawhelper_p.h>
-#include <private/qimage_p.h>
-#include <private/qnativeimagehandleprovider_p.h>
-#include <private/qfont_p.h>
-
-#include <private/qpaintengineex_opengl2_p.h>
-
-#include <qdesktopwidget.h>
-#include <qfile.h>
-#include <qimagereader.h>
-#include <qbuffer.h>
-
-#include "qgltexturepool_p.h"
-
-QT_BEGIN_NAMESPACE
-
-Q_OPENGL_EXPORT extern QGLWidget* qt_gl_share_widget();
-
-static inline int areaDiff(const QSize &size, const QGLFramebufferObject *fbo)
-{
- return qAbs(size.width() * size.height() - fbo->width() * fbo->height());
-}
-
-extern int qt_next_power_of_two(int v);
-
-static inline QSize maybeRoundToNextPowerOfTwo(const QSize &sz)
-{
-#ifdef QT_OPENGL_ES_2
- QSize rounded(qt_next_power_of_two(sz.width()), qt_next_power_of_two(sz.height()));
- if (rounded.width() * rounded.height() < 1.20 * sz.width() * sz.height())
- return rounded;
-#endif
- return sz;
-}
-
-
-QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize, const QGLFramebufferObjectFormat &requestFormat, bool strictSize)
-{
- QGLFramebufferObject *chosen = 0;
- QGLFramebufferObject *candidate = 0;
- for (int i = 0; !chosen && i < m_fbos.size(); ++i) {
- QGLFramebufferObject *fbo = m_fbos.at(i);
-
- if (strictSize) {
- if (fbo->size() == requestSize && fbo->format() == requestFormat) {
- chosen = fbo;
- break;
- } else {
- continue;
- }
- }
-
- if (fbo->format() == requestFormat) {
- // choose the fbo with a matching format and the closest size
- if (!candidate || areaDiff(requestSize, candidate) > areaDiff(requestSize, fbo))
- candidate = fbo;
- }
-
- if (candidate) {
- m_fbos.removeOne(candidate);
-
- const QSize fboSize = candidate->size();
- QSize sz = fboSize;
-
- if (sz.width() < requestSize.width())
- sz.setWidth(qMax(requestSize.width(), qRound(sz.width() * 1.5)));
- if (sz.height() < requestSize.height())
- sz.setHeight(qMax(requestSize.height(), qRound(sz.height() * 1.5)));
-
- // wasting too much space?
- if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 4)
- sz = requestSize;
-
- if (sz != fboSize) {
- delete candidate;
- candidate = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(sz), requestFormat);
- }
-
- chosen = candidate;
- }
- }
-
- if (!chosen) {
- if (strictSize)
- chosen = new QGLFramebufferObject(requestSize, requestFormat);
- else
- chosen = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(requestSize), requestFormat);
- }
-
- if (!chosen->isValid()) {
- delete chosen;
- chosen = 0;
- }
-
- return chosen;
-}
-
-void QGLFramebufferObjectPool::release(QGLFramebufferObject *fbo)
-{
- if (fbo)
- m_fbos << fbo;
-}
-
-
-QPaintEngine* QGLPixmapGLPaintDevice::paintEngine() const
-{
- return data->paintEngine();
-}
-
-void QGLPixmapGLPaintDevice::beginPaint()
-{
- if (!data->isValid())
- return;
-
- // QGLPaintDevice::beginPaint will store the current binding and replace
- // it with m_thisFBO:
- m_thisFBO = data->m_renderFbo->handle();
- QGLPaintDevice::beginPaint();
-
- Q_ASSERT(data->paintEngine()->type() == QPaintEngine::OpenGL2);
-
- // QPixmap::fill() is deferred until now, where we actually need to do the fill:
- if (data->needsFill()) {
- const QColor &c = data->fillColor();
- float alpha = c.alphaF();
- glDisable(GL_SCISSOR_TEST);
- glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha);
- glClear(GL_COLOR_BUFFER_BIT);
- }
- else if (!data->isUninitialized()) {
- // If the pixmap (GL Texture) has valid content (it has been
- // uploaded from an image or rendered into before), we need to
- // copy it from the texture to the render FBO.
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
- glDisable(GL_BLEND);
-
-#if !defined(QT_OPENGL_ES_2)
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, data->width(), data->height(), 0, -999999, 999999);
-#endif
-
- glViewport(0, 0, data->width(), data->height());
-
- // Pass false to bind so it doesn't copy the FBO into the texture!
- context()->drawTexture(QRect(0, 0, data->width(), data->height()), data->bind(false));
- }
-}
-
-void QGLPixmapGLPaintDevice::endPaint()
-{
- if (!data->isValid())
- return;
-
- data->copyBackFromRenderFbo(false);
-
- // Base's endPaint will restore the previous FBO binding
- QGLPaintDevice::endPaint();
-
- qgl_fbo_pool()->release(data->m_renderFbo);
- data->m_renderFbo = 0;
-}
-
-QGLContext* QGLPixmapGLPaintDevice::context() const
-{
- data->ensureCreated();
- return data->m_ctx;
-}
-
-QSize QGLPixmapGLPaintDevice::size() const
-{
- return data->size();
-}
-
-bool QGLPixmapGLPaintDevice::alphaRequested() const
-{
- return data->m_hasAlpha;
-}
-
-void QGLPixmapGLPaintDevice::setPixmapData(QGLPixmapData* d)
-{
- data = d;
-}
-
-int qt_gl_pixmap_serial = 0;
-
-QGLPixmapData::QGLPixmapData(PixelType type)
- : QPixmapData(type, OpenGLClass)
- , m_renderFbo(0)
- , m_engine(0)
- , m_ctx(0)
- , nativeImageHandleProvider(0)
- , nativeImageHandle(0)
- , m_dirty(false)
- , m_hasFillColor(false)
- , m_hasAlpha(false)
- , inLRU(false)
- , failedToAlloc(false)
- , inTexturePool(false)
-{
- setSerialNumber(++qt_gl_pixmap_serial);
- m_glDevice.setPixmapData(this);
-
- qt_gl_register_pixmap(this);
-}
-
-QGLPixmapData::~QGLPixmapData()
-{
- delete m_engine;
-
- destroyTexture();
- qt_gl_unregister_pixmap(this);
-}
-
-void QGLPixmapData::destroyTexture()
-{
- if (inTexturePool) {
- QGLTexturePool *pool = QGLTexturePool::instance();
- if (m_texture.id)
- pool->releaseTexture(this, m_texture.id);
- } else {
- if (m_texture.id) {
- QGLWidget *shareWidget = qt_gl_share_widget();
- if (shareWidget) {
- QGLShareContextScope ctx(shareWidget->context());
- glDeleteTextures(1, &m_texture.id);
- }
- }
- }
- m_texture.id = 0;
- inTexturePool = false;
-
- releaseNativeImageHandle();
-}
-
-QPixmapData *QGLPixmapData::createCompatiblePixmapData() const
-{
- return new QGLPixmapData(pixelType());
-}
-
-bool QGLPixmapData::isValid() const
-{
- return w > 0 && h > 0;
-}
-
-bool QGLPixmapData::isValidContext(const QGLContext *ctx) const
-{
- if (ctx == m_ctx)
- return true;
-
- const QGLContext *share_ctx = qt_gl_share_widget()->context();
- return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx);
-}
-
-void QGLPixmapData::resize(int width, int height)
-{
- if (width == w && height == h)
- return;
-
- if (width <= 0 || height <= 0) {
- width = 0;
- height = 0;
- }
-
- w = width;
- h = height;
- is_null = (w <= 0 || h <= 0);
- d = pixelType() == QPixmapData::PixmapType ? 32 : 1;
-
- destroyTexture();
-
- m_source = QVolatileImage();
- m_dirty = isValid();
- setSerialNumber(++qt_gl_pixmap_serial);
-}
-
-void QGLPixmapData::ensureCreated() const
-{
- if (!m_dirty)
- return;
-
- m_dirty = false;
-
- if (nativeImageHandleProvider && !nativeImageHandle)
- const_cast<QGLPixmapData *>(this)->createFromNativeImageHandleProvider();
-
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- m_ctx = ctx;
-
- const GLenum internal_format = m_hasAlpha ? GL_RGBA : GL_RGB;
-#ifdef QT_OPENGL_ES_2
- const GLenum external_format = internal_format;
-#else
- const GLenum external_format = qt_gl_preferredTextureFormat();
-#endif
- const GLenum target = GL_TEXTURE_2D;
-
- GLenum type = GL_UNSIGNED_BYTE;
- // Avoid conversion when pixmap is created from CFbsBitmap of EColor64K.
- if (!m_source.isNull() && m_source.format() == QImage::Format_RGB16)
- type = GL_UNSIGNED_SHORT_5_6_5;
-
- m_texture.options &= ~QGLContext::MemoryManagedBindOption;
-
- if (!m_texture.id) {
- m_texture.id = QGLTexturePool::instance()->createTextureForPixmap(
- target,
- 0, internal_format,
- w, h,
- external_format,
- type,
- const_cast<QGLPixmapData*>(this));
- if (!m_texture.id) {
- failedToAlloc = true;
- return;
- }
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- inTexturePool = true;
- } else if (inTexturePool) {
- glBindTexture(target, m_texture.id);
- QGLTexturePool::instance()->useTexture(const_cast<QGLPixmapData*>(this));
- }
-
- if (!m_source.isNull() && m_texture.id) {
- if (external_format == GL_RGB) {
- m_source.beginDataAccess();
- QImage tx;
- if (type == GL_UNSIGNED_BYTE)
- tx = m_source.imageRef().convertToFormat(QImage::Format_RGB888).mirrored(false, true);
- else if (type == GL_UNSIGNED_SHORT_5_6_5)
- tx = m_source.imageRef().mirrored(false, true);
- m_source.endDataAccess(true);
-
- glBindTexture(target, m_texture.id);
- if (!tx.isNull())
- glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
- type, tx.constBits());
- else
- qWarning("QGLPixmapData: Failed to create GL_RGB image of size %dx%d", w, h);
- } else {
- // do byte swizzling ARGB -> RGBA
- m_source.beginDataAccess();
- const QImage tx = ctx->d_func()->convertToGLFormat(m_source.imageRef(), true, external_format);
- m_source.endDataAccess(true);
- glBindTexture(target, m_texture.id);
- if (!tx.isNull())
- glTexSubImage2D(target, 0, 0, 0, w, h, external_format,
- type, tx.constBits());
- else
- qWarning("QGLPixmapData: Failed to create GL_RGBA image of size %dx%d", w, h);
- }
-
- if (useFramebufferObjects())
- m_source = QVolatileImage();
- }
-}
-
-
-void QGLPixmapData::fromImage(const QImage &image,
- Qt::ImageConversionFlags flags)
-{
- QImage img = image;
- createPixmapForImage(img, flags, false);
-}
-
-void QGLPixmapData::fromImageReader(QImageReader *imageReader,
- Qt::ImageConversionFlags flags)
-{
- QImage image = imageReader->read();
- if (image.isNull())
- return;
-
- createPixmapForImage(image, flags, true);
-}
-
-bool QGLPixmapData::fromFile(const QString &filename, const char *format,
- Qt::ImageConversionFlags flags)
-{
- if (pixelType() == QPixmapData::BitmapType)
- return QPixmapData::fromFile(filename, format, flags);
- QFile file(filename);
- if (file.open(QIODevice::ReadOnly)) {
- QByteArray data = file.peek(64);
- bool alpha;
- if (m_texture.canBindCompressedTexture
- (data.constData(), data.size(), format, &alpha)) {
- resize(0, 0);
- data = file.readAll();
- file.close();
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QSize size = m_texture.bindCompressedTexture
- (data.constData(), data.size(), format);
- if (!size.isEmpty()) {
- w = size.width();
- h = size.height();
- is_null = false;
- d = 32;
- m_hasAlpha = alpha;
- m_source = QVolatileImage();
- m_dirty = isValid();
- return true;
- }
- return false;
- }
- }
-
- QImage image = QImageReader(filename, format).read();
- if (image.isNull())
- return false;
-
- createPixmapForImage(image, flags, true);
-
- return !isNull();
-}
-
-bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format,
- Qt::ImageConversionFlags flags)
-{
- bool alpha;
- const char *buf = reinterpret_cast<const char *>(buffer);
- if (m_texture.canBindCompressedTexture(buf, int(len), format, &alpha)) {
- resize(0, 0);
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QSize size = m_texture.bindCompressedTexture(buf, int(len), format);
- if (!size.isEmpty()) {
- w = size.width();
- h = size.height();
- is_null = false;
- d = 32;
- m_hasAlpha = alpha;
- m_source = QVolatileImage();
- m_dirty = isValid();
- return true;
- }
- }
-
- QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len);
- QBuffer b(&a);
- b.open(QIODevice::ReadOnly);
- QImage image = QImageReader(&b, format).read();
- if (image.isNull())
- return false;
-
- createPixmapForImage(image, flags, true);
-
- return !isNull();
-}
-
-QImage::Format QGLPixmapData::idealFormat(QImage &image, Qt::ImageConversionFlags flags)
-{
- QImage::Format format = QImage::Format_RGB32;
- if (qApp->desktop()->depth() == 16)
- format = QImage::Format_RGB16;
-
- if (image.hasAlphaChannel()
- && ((flags & Qt::NoOpaqueDetection)
- || const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()))
- format = QImage::Format_ARGB32_Premultiplied;
-
- return format;
-}
-
-void QGLPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
-{
- if (image.size() == QSize(w, h))
- setSerialNumber(++qt_gl_pixmap_serial);
-
- resize(image.width(), image.height());
-
- if (pixelType() == BitmapType) {
- QImage convertedImage = image.convertToFormat(QImage::Format_MonoLSB);
- if (image.format() == QImage::Format_MonoLSB)
- convertedImage.detach();
-
- m_source = QVolatileImage(convertedImage);
-
- } else {
- QImage::Format format = idealFormat(image, flags);
-
- if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
- m_source = QVolatileImage(image);
- } else {
- QImage convertedImage = image.convertToFormat(format);
-
- // convertToFormat won't detach the image if format stays the same.
- if (image.format() == format)
- convertedImage.detach();
-
- m_source = QVolatileImage(convertedImage);
- }
- }
-
- m_dirty = true;
- m_hasFillColor = false;
-
- m_hasAlpha = m_source.hasAlphaChannel();
- w = image.width();
- h = image.height();
- is_null = (w <= 0 || h <= 0);
- d = m_source.depth();
-
- destroyTexture();
-}
-
-bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- Q_UNUSED(dx);
- Q_UNUSED(dy);
- Q_UNUSED(rect);
- return false;
-}
-
-void QGLPixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- if (data->classId() != QPixmapData::OpenGLClass || !static_cast<const QGLPixmapData *>(data)->useFramebufferObjects()) {
- QPixmapData::copy(data, rect);
- return;
- }
-
- const QGLPixmapData *other = static_cast<const QGLPixmapData *>(data);
- if (other->m_renderFbo) {
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
-
- resize(rect.width(), rect.height());
- m_hasAlpha = other->m_hasAlpha;
- ensureCreated();
-
- if (!ctx->d_ptr->fbo)
- glGenFramebuffers(1, &ctx->d_ptr->fbo);
-
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo);
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, m_texture.id, 0);
-
- if (!other->m_renderFbo->isBound())
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, other->m_renderFbo->handle());
-
- glDisable(GL_SCISSOR_TEST);
- if (ctx->d_ptr->active_engine && ctx->d_ptr->active_engine->type() == QPaintEngine::OpenGL2)
- static_cast<QGL2PaintEngineEx *>(ctx->d_ptr->active_engine)->invalidateState();
-
- glBlitFramebufferEXT(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height(),
- 0, 0, w, h,
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
- } else {
- QPixmapData::copy(data, rect);
- }
-}
-
-void QGLPixmapData::fill(const QColor &color)
-{
- if (!isValid())
- return;
-
- bool hasAlpha = color.alpha() != 255;
- if (hasAlpha && !m_hasAlpha) {
- if (m_texture.id) {
- destroyTexture();
- m_dirty = true;
- }
- m_hasAlpha = color.alpha() != 255;
- }
-
- if (useFramebufferObjects()) {
- m_source = QVolatileImage();
- m_hasFillColor = true;
- m_fillColor = color;
- } else {
- forceToImage();
-
- if (m_source.depth() == 32) {
- m_source.fill(PREMUL(color.rgba()));
-
- } else if (m_source.depth() == 1) {
- if (color == Qt::color1)
- m_source.fill(1);
- else
- m_source.fill(0);
- }
- }
-}
-
-bool QGLPixmapData::hasAlphaChannel() const
-{
- return m_hasAlpha;
-}
-
-QImage QGLPixmapData::fillImage(const QColor &color) const
-{
- QImage img;
- if (pixelType() == BitmapType) {
- img = QImage(w, h, QImage::Format_MonoLSB);
-
- img.setColorCount(2);
- img.setColor(0, QColor(Qt::color0).rgba());
- img.setColor(1, QColor(Qt::color1).rgba());
-
- if (color == Qt::color1)
- img.fill(1);
- else
- img.fill(0);
- } else {
- img = QImage(w, h,
- m_hasAlpha
- ? QImage::Format_ARGB32_Premultiplied
- : QImage::Format_RGB32);
- img.fill(PREMUL(color.rgba()));
- }
- return img;
-}
-
-extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha);
-
-QImage QGLPixmapData::toImage() const
-{
- if (!isValid())
- return QImage();
-
- if (m_renderFbo) {
- copyBackFromRenderFbo(true);
- } else if (!m_source.isNull()) {
- // QVolatileImage::toImage() will make a copy always so no check
- // for active painting is needed.
- QImage img = m_source.toImage();
- if (img.format() == QImage::Format_MonoLSB) {
- img.setColorCount(2);
- img.setColor(0, QColor(Qt::color0).rgba());
- img.setColor(1, QColor(Qt::color1).rgba());
- }
- return img;
- } else if (m_dirty || m_hasFillColor) {
- return fillImage(m_fillColor);
- } else {
- ensureCreated();
- }
-
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- glBindTexture(GL_TEXTURE_2D, m_texture.id);
- return qt_gl_read_texture(QSize(w, h), true, true);
-}
-
-struct TextureBuffer
-{
- QGLFramebufferObject *fbo;
- QGL2PaintEngineEx *engine;
-};
-
-Q_GLOBAL_STATIC(QGLFramebufferObjectPool, _qgl_fbo_pool)
-QGLFramebufferObjectPool* qgl_fbo_pool()
-{
- return _qgl_fbo_pool();
-}
-
-void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const
-{
- if (!isValid())
- return;
-
- m_hasFillColor = false;
-
- const QGLContext *share_ctx = qt_gl_share_widget()->context();
- QGLShareContextScope ctx(share_ctx);
-
- ensureCreated();
-
- if (!ctx->d_ptr->fbo)
- glGenFramebuffers(1, &ctx->d_ptr->fbo);
-
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo);
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, m_texture.id, 0);
-
- const int x0 = 0;
- const int x1 = w;
- const int y0 = 0;
- const int y1 = h;
-
- if (!m_renderFbo->isBound())
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle());
-
- glDisable(GL_SCISSOR_TEST);
-
- glBlitFramebufferEXT(x0, y0, x1, y1,
- x0, y0, x1, y1,
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
- if (keepCurrentFboBound) {
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
- } else {
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, m_renderFbo->handle());
- ctx->d_ptr->current_fbo = m_renderFbo->handle();
- }
-}
-
-bool QGLPixmapData::useFramebufferObjects() const
-{
-#ifdef Q_OS_SYMBIAN
- // We don't want to use FBOs on Symbian
- return false;
-#else
- return QGLFramebufferObject::hasOpenGLFramebufferObjects()
- && QGLFramebufferObject::hasOpenGLFramebufferBlit()
- && qt_gl_preferGL2Engine()
- && (w * h > 32*32); // avoid overhead of FBOs for small pixmaps
-#endif
-}
-
-QPaintEngine* QGLPixmapData::paintEngine() const
-{
- if (!isValid())
- return 0;
-
- if (m_renderFbo)
- return m_engine;
-
- if (useFramebufferObjects()) {
- extern QGLWidget* qt_gl_share_widget();
-
- if (!QGLContext::currentContext())
- qt_gl_share_widget()->makeCurrent();
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
-
- QGLFramebufferObjectFormat format;
- format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
- format.setSamples(4);
- format.setInternalTextureFormat(GLenum(m_hasAlpha ? GL_RGBA : GL_RGB));
-
- m_renderFbo = qgl_fbo_pool()->acquire(size(), format);
-
- if (m_renderFbo) {
- if (!m_engine)
- m_engine = new QGL2PaintEngineEx;
- return m_engine;
- }
-
- qWarning() << "Failed to create pixmap texture buffer of size " << size() << ", falling back to raster paint engine";
- }
-
- // If the application wants to paint into the QPixmap, we first
- // force it to QImage format and then paint into that.
- // This is simpler than juggling multiple GL contexts.
- const_cast<QGLPixmapData *>(this)->forceToImage();
-
- if (m_hasFillColor) {
- m_source.fill(PREMUL(m_fillColor.rgba()));
- m_hasFillColor = false;
- }
- return m_source.paintEngine();
-}
-
-extern QRgb qt_gl_convertToGLFormat(QRgb src_pixel, GLenum texture_format);
-
-// If copyBack is true, bind will copy the contents of the render
-// FBO to the texture (which is not bound to the texture, as it's
-// a multisample FBO).
-GLuint QGLPixmapData::bind(bool copyBack) const
-{
- if (m_renderFbo && copyBack) {
- copyBackFromRenderFbo(true);
- } else {
- ensureCreated();
- }
-
- GLuint id = m_texture.id;
- glBindTexture(GL_TEXTURE_2D, id);
-
- if (m_hasFillColor) {
- if (!useFramebufferObjects()) {
- m_source = QVolatileImage(w, h, QImage::Format_ARGB32_Premultiplied);
- m_source.fill(PREMUL(m_fillColor.rgba()));
- }
-
- m_hasFillColor = false;
-
- GLenum format = qt_gl_preferredTextureFormat();
- QImage tx(w, h, QImage::Format_ARGB32_Premultiplied);
- tx.fill(qt_gl_convertToGLFormat(m_fillColor.rgba(), format));
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.constBits());
- }
-
- return id;
-}
-
-QGLTexture* QGLPixmapData::texture() const
-{
- return &m_texture;
-}
-
-void QGLPixmapData::detachTextureFromPool()
-{
- if (inTexturePool) {
- QGLTexturePool::instance()->detachTexture(this);
- inTexturePool = false;
- }
-}
-
-void QGLPixmapData::hibernate()
-{
- // If the image was imported (e.g, from an SgImage under Symbian), then
- // skip the hibernation, there is no sense in copying it back to main
- // memory because the data is most likely shared between several processes.
- bool skipHibernate = (m_texture.id && m_source.isNull());
-#if defined(Q_OS_SYMBIAN)
- // However we have to proceed normally if the image was retrieved via
- // a handle provider.
- skipHibernate &= !nativeImageHandleProvider;
-#endif
- if (skipHibernate)
- return;
-
- forceToImage();
- destroyTexture();
-}
-
-void QGLPixmapData::reclaimTexture()
-{
- if (!inTexturePool)
- return;
- forceToImage();
- destroyTexture();
-}
-
-int QGLPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
-{
- if (w == 0)
- return 0;
-
- switch (metric) {
- case QPaintDevice::PdmWidth:
- return w;
- case QPaintDevice::PdmHeight:
- return h;
- case QPaintDevice::PdmNumColors:
- return 0;
- case QPaintDevice::PdmDepth:
- return d;
- case QPaintDevice::PdmWidthMM:
- return qRound(w * 25.4 / qt_defaultDpiX());
- case QPaintDevice::PdmHeightMM:
- return qRound(h * 25.4 / qt_defaultDpiY());
- case QPaintDevice::PdmDpiX:
- case QPaintDevice::PdmPhysicalDpiX:
- return qt_defaultDpiX();
- case QPaintDevice::PdmDpiY:
- case QPaintDevice::PdmPhysicalDpiY:
- return qt_defaultDpiY();
- default:
- qWarning("QGLPixmapData::metric(): Invalid metric");
- return 0;
- }
-}
-
-// Force the pixmap data to be backed by some valid data.
-void QGLPixmapData::forceToImage()
-{
- if (!isValid())
- return;
-
- if (m_source.isNull()) {
- QImage::Format format = QImage::Format_ARGB32_Premultiplied;
- if (pixelType() == BitmapType)
- format = QImage::Format_MonoLSB;
- m_source = QVolatileImage(w, h, format);
- }
-
- m_dirty = true;
-}
-
-QGLPaintDevice *QGLPixmapData::glDevice() const
-{
- return &m_glDevice;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qpixmapdata_x11gl_egl.cpp b/src/opengl/qpixmapdata_x11gl_egl.cpp
deleted file mode 100644
index 8a8eb38b7c..0000000000
--- a/src/opengl/qpixmapdata_x11gl_egl.cpp
+++ /dev/null
@@ -1,403 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QDebug>
-
-#include <QtGui/private/qt_x11_p.h>
-#include <QtGui/private/qegl_p.h>
-#include <QtGui/private/qeglproperties_p.h>
-#include <QtGui/private/qeglcontext_p.h>
-
-#if !defined(QT_OPENGL_ES_1)
-#include <QtOpenGL/private/qpaintengineex_opengl2_p.h>
-#endif
-
-#ifndef QT_OPENGL_ES_2
-#include <QtOpenGL/private/qpaintengine_opengl_p.h>
-#endif
-
-#include <QtOpenGL/private/qgl_p.h>
-#include <QtOpenGL/private/qgl_egl_p.h>
-
-#include "qpixmapdata_x11gl_p.h"
-
-QT_BEGIN_NAMESPACE
-
-
-class QX11GLSharedContexts
-{
-public:
- QX11GLSharedContexts()
- : rgbContext(0)
- , argbContext(0)
- , sharedQGLContext(0)
- , sharePixmap(0)
- {
- EGLint rgbConfigId;
- EGLint argbConfigId;
-
- do {
- EGLConfig rgbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL, QEgl::Renderable);
- EGLConfig argbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL,
- QEgl::Renderable | QEgl::Translucent);
-
- eglGetConfigAttrib(QEgl::display(), rgbConfig, EGL_CONFIG_ID, &rgbConfigId);
- eglGetConfigAttrib(QEgl::display(), argbConfig, EGL_CONFIG_ID, &argbConfigId);
-
- rgbContext = new QEglContext;
- rgbContext->setConfig(rgbConfig);
- rgbContext->createContext();
-
- if (!rgbContext->isValid())
- break;
-
- // If the RGB & ARGB configs are the same, use the same egl context for both:
- if (rgbConfig == argbConfig)
- argbContext = rgbContext;
-
- // Otherwise, create a separate context to be used for ARGB pixmaps:
- if (!argbContext) {
- argbContext = new QEglContext;
- argbContext->setConfig(argbConfig);
- bool success = argbContext->createContext(rgbContext);
- if (!success) {
- qWarning("QX11GLPixmapData - RGB & ARGB contexts aren't shared");
- success = argbContext->createContext();
- if (!success)
- argbContext = rgbContext; // Might work, worth a shot at least.
- }
- }
-
- if (!argbContext->isValid())
- break;
-
- // Create the pixmap which will be used to create the egl surface for the share QGLContext
- QX11PixmapData *rgbPixmapData = new QX11PixmapData(QPixmapData::PixmapType);
- rgbPixmapData->resize(8, 8);
- rgbPixmapData->fill(Qt::red);
- sharePixmap = new QPixmap(rgbPixmapData);
- EGLSurface sharePixmapSurface = QEgl::createSurface(sharePixmap, rgbConfig);
- rgbPixmapData->gl_surface = (void*)sharePixmapSurface;
-
- // Create the actual QGLContext which will be used for sharing
- sharedQGLContext = new QGLContext(QX11GLPixmapData::glFormat());
- sharedQGLContext->d_func()->eglContext = rgbContext;
- sharedQGLContext->d_func()->eglSurface = sharePixmapSurface;
- sharedQGLContext->d_func()->valid = true;
- qt_glformat_from_eglconfig(sharedQGLContext->d_func()->glFormat, rgbConfig);
-
-
- valid = rgbContext->makeCurrent(sharePixmapSurface);
-
- // If the ARGB & RGB configs are different, check ARGB works too:
- if (argbConfig != rgbConfig) {
- QX11PixmapData *argbPixmapData = new QX11PixmapData(QPixmapData::PixmapType);
- argbPixmapData->resize(8, 8);
- argbPixmapData->fill(Qt::transparent); // Force ARGB
- QPixmap argbPixmap(argbPixmapData); // destroys pixmap data when goes out of scope
- EGLSurface argbPixmapSurface = QEgl::createSurface(&argbPixmap, argbConfig);
- valid = argbContext->makeCurrent(argbPixmapSurface);
- argbContext->doneCurrent();
- eglDestroySurface(QEgl::display(), argbPixmapSurface);
- argbPixmapData->gl_surface = 0;
- }
-
- if (!valid) {
- qWarning() << "Unable to make pixmap surface current:" << QEgl::errorString();
- break;
- }
-
- // The pixmap surface destruction hooks are installed by QGLTextureCache, so we
- // must make sure this is instanciated:
- QGLTextureCache::instance();
- } while(0);
-
- if (!valid)
- cleanup();
- else
- qDebug("Using QX11GLPixmapData with EGL config %d for ARGB and config %d for RGB", argbConfigId, rgbConfigId);
-
- }
-
- ~QX11GLSharedContexts() {
- cleanup();
- }
-
- void cleanup() {
- if (sharedQGLContext) {
- delete sharedQGLContext;
- sharedQGLContext = 0;
- }
- if (argbContext && argbContext != rgbContext)
- delete argbContext;
- argbContext = 0;
-
- if (rgbContext) {
- delete rgbContext;
- rgbContext = 0;
- }
-
- // Deleting the QPixmap will fire the pixmap destruction cleanup hooks which in turn
- // will destroy the egl surface:
- if (sharePixmap) {
- delete sharePixmap;
- sharePixmap = 0;
- }
- }
-
- bool isValid() { return valid;}
-
- // On 16bpp systems, RGB & ARGB pixmaps are different bit-depths and therefore need
- // different contexts:
- QEglContext *rgbContext;
- QEglContext *argbContext;
-
- // The share context wraps the rgbContext and is used as the master of the context share
- // group. As all other contexts will have the same egl context (or a shared one if rgb != argb)
- // all QGLContexts will actually be sharing and can be in the same context group.
- QGLContext *sharedQGLContext;
-private:
- QPixmap *sharePixmap;
- bool valid;
-};
-
-static void qt_cleanup_x11gl_share_contexts();
-
-Q_GLOBAL_STATIC_WITH_INITIALIZER(QX11GLSharedContexts, qt_x11gl_share_contexts,
- {
- qAddPostRoutine(qt_cleanup_x11gl_share_contexts);
- })
-
-static void qt_cleanup_x11gl_share_contexts()
-{
- qt_x11gl_share_contexts()->cleanup();
-}
-
-
-QX11GLSharedContexts* QX11GLPixmapData::sharedContexts()
-{
- return qt_x11gl_share_contexts();
-}
-
-bool QX11GLPixmapData::hasX11GLPixmaps()
-{
- static bool checkedForX11GLPixmaps = false;
- static bool haveX11GLPixmaps = false;
-
- if (checkedForX11GLPixmaps)
- return haveX11GLPixmaps;
-
- haveX11GLPixmaps = qt_x11gl_share_contexts()->isValid();
- checkedForX11GLPixmaps = true;
-
- return haveX11GLPixmaps;
-}
-
-QX11GLPixmapData::QX11GLPixmapData()
- : QX11PixmapData(QPixmapData::PixmapType),
- ctx(0)
-{
-}
-
-QX11GLPixmapData::~QX11GLPixmapData()
-{
- if (ctx)
- delete ctx;
-}
-
-
-void QX11GLPixmapData::fill(const QColor &color)
-{
- if (ctx) {
- ctx->makeCurrent();
- glFinish();
- eglWaitClient();
- }
-
- QX11PixmapData::fill(color);
- XSync(X11->display, False);
-
- if (ctx) {
- ctx->makeCurrent();
- eglWaitNative(EGL_CORE_NATIVE_ENGINE);
- }
-}
-
-void QX11GLPixmapData::copy(const QPixmapData *data, const QRect &rect)
-{
- if (ctx) {
- ctx->makeCurrent();
- glFinish();
- eglWaitClient();
- }
-
- QX11PixmapData::copy(data, rect);
- XSync(X11->display, False);
-
- if (ctx) {
- ctx->makeCurrent();
- eglWaitNative(EGL_CORE_NATIVE_ENGINE);
- }
-}
-
-bool QX11GLPixmapData::scroll(int dx, int dy, const QRect &rect)
-{
- if (ctx) {
- ctx->makeCurrent();
- glFinish();
- eglWaitClient();
- }
-
- bool success = QX11PixmapData::scroll(dx, dy, rect);
- XSync(X11->display, False);
-
- if (ctx) {
- ctx->makeCurrent();
- eglWaitNative(EGL_CORE_NATIVE_ENGINE);
- }
-
- return success;
-}
-
-#if !defined(QT_OPENGL_ES_1)
-Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_pixmap_2_engine)
-#endif
-
-#ifndef QT_OPENGL_ES_2
-Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_pixmap_engine)
-#endif
-
-
-QPaintEngine* QX11GLPixmapData::paintEngine() const
-{
- // We need to create the context before beginPaint - do it here:
- if (!ctx) {
- ctx = new QGLContext(glFormat());
- Q_ASSERT(ctx->d_func()->eglContext == 0);
- ctx->d_func()->eglContext = hasAlphaChannel() ? sharedContexts()->argbContext : sharedContexts()->rgbContext;
-
- // While we use a separate QGLContext for each pixmap, the underlying QEglContext is
- // the same. So we must use a "fake" QGLContext and fool the texture cache into thinking
- // each pixmap's QGLContext is sharing with this central one. The only place this is
- // going to fail is where we the underlying EGL RGB and ARGB contexts aren't sharing.
- ctx->d_func()->sharing = true;
- QGLContextGroup::addShare(ctx, sharedContexts()->sharedQGLContext);
-
- // Update the glFormat for the QGLContext:
- qt_glformat_from_eglconfig(ctx->d_func()->glFormat, ctx->d_func()->eglContext->config());
- }
-
- QPaintEngine* engine;
-
-#if defined(QT_OPENGL_ES_1)
- engine = qt_gl_pixmap_engine();
-#elif defined(QT_OPENGL_ES_2)
- engine = qt_gl_pixmap_2_engine();
-#else
- if (qt_gl_preferGL2Engine())
- engine = qt_gl_pixmap_2_engine();
- else
- engine = qt_gl_pixmap_engine();
-#endif
-
-
-
- // Support multiple painters on multiple pixmaps simultaniously
- if (engine->isActive()) {
- qWarning("Pixmap paint engine already active");
-
-#if defined(QT_OPENGL_ES_1)
- engine = new QOpenGLPaintEngine;
-#elif defined(QT_OPENGL_ES_2)
- engine = new QGL2PaintEngineEx;
-#else
- if (qt_gl_preferGL2Engine())
- engine = new QGL2PaintEngineEx;
- else
- engine = new QOpenGLPaintEngine;
-#endif
-
- engine->setAutoDestruct(true);
- return engine;
- }
-
- return engine;
-}
-
-void QX11GLPixmapData::beginPaint()
-{
-// qDebug("QX11GLPixmapData::beginPaint()");
- // TODO: Check to see if the surface is renderable
- if ((EGLSurface)gl_surface == EGL_NO_SURFACE) {
- QPixmap tmpPixmap(this);
- EGLConfig cfg = ctx->d_func()->eglContext->config();
- Q_ASSERT(cfg != QEGL_NO_CONFIG);
-
-// qDebug("QX11GLPixmapData - using EGL Config ID %d", ctx->d_func()->eglContext->configAttrib(EGL_CONFIG_ID));
- EGLSurface surface = QEgl::createSurface(&tmpPixmap, cfg);
- if (surface == EGL_NO_SURFACE) {
- qWarning() << "Error creating EGL surface for pixmap:" << QEgl::errorString();
- return;
- }
- gl_surface = (void*)surface;
- ctx->d_func()->eglSurface = surface;
- ctx->d_func()->valid = true;
- }
- QGLPaintDevice::beginPaint();
-}
-
-QGLContext* QX11GLPixmapData::context() const
-{
- return ctx;
-}
-
-QSize QX11GLPixmapData::size() const
-{
- return QSize(w, h);
-}
-
-
-QGLFormat QX11GLPixmapData::glFormat()
-{
- return QGLFormat::defaultFormat(); //###
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qpixmapdata_x11gl_p.h b/src/opengl/qpixmapdata_x11gl_p.h
deleted file mode 100644
index 0a6c4e8f2f..0000000000
--- a/src/opengl/qpixmapdata_x11gl_p.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QPIXMAPDATA_X11GL_P_H
-#define QPIXMAPDATA_X11GL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qpixmapdata_p.h>
-#include <private/qpixmap_x11_p.h>
-#include <private/qglpaintdevice_p.h>
-
-#include <qgl.h>
-
-#ifndef QT_NO_EGL
-#include <QtGui/private/qeglcontext_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QX11GLSharedContexts;
-
-class QX11GLPixmapData : public QX11PixmapData, public QGLPaintDevice
-{
-public:
- QX11GLPixmapData();
- virtual ~QX11GLPixmapData();
-
- // Re-implemented from QX11PixmapData:
- void fill(const QColor &color);
- void copy(const QPixmapData *data, const QRect &rect);
- bool scroll(int dx, int dy, const QRect &rect);
-
- // Re-implemented from QGLPaintDevice
- QPaintEngine* paintEngine() const; // Also re-implements QX11PixmapData::paintEngine
- void beginPaint();
- QGLContext* context() const;
- QSize size() const;
-
- static bool hasX11GLPixmaps();
- static QGLFormat glFormat();
- static QX11GLSharedContexts* sharedContexts();
-
-private:
- mutable QGLContext* ctx;
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QPIXMAPDATA_X11GL_P_H
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
deleted file mode 100644
index 4f00908b9d..0000000000
--- a/src/opengl/qwindowsurface_gl.cpp
+++ /dev/null
@@ -1,1174 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtGui/QApplication>
-#include <QtGui/QColormap>
-#include <QtGui/QDesktopWidget>
-#include <QtGui/QPaintDevice>
-#include <QtGui/QWidget>
-
-#include <qglframebufferobject.h>
-#include <qglpixelbuffer.h>
-#include <qcolormap.h>
-#include <qdesktopwidget.h>
-#include <private/qwidget_p.h>
-#include "qdebug.h"
-
-#ifdef Q_WS_X11
-#include <private/qt_x11_p.h>
-#include <qx11info_x11.h>
-
-#ifndef QT_OPENGL_ES
-#include <GL/glx.h>
-#include <X11/Xlib.h>
-#endif
-#endif //Q_WS_X11
-
-#include <private/qglextensions_p.h>
-#include <private/qwindowsurface_gl_p.h>
-
-#include <private/qgl_p.h>
-
-#include <private/qglpixelbuffer_p.h>
-#include <private/qgraphicssystem_gl_p.h>
-
-#include <private/qpaintengineex_opengl2_p.h>
-#include <private/qpixmapdata_gl_p.h>
-
-#ifndef QT_OPENGL_ES_2
-#include <private/qpaintengine_opengl_p.h>
-#endif
-
-#ifndef GLX_ARB_multisample
-#define GLX_SAMPLE_BUFFERS_ARB 100000
-#define GLX_SAMPLES_ARB 100001
-#endif
-
-#ifndef QT_NO_EGL
-#include <private/qeglcontext_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-//
-// QGLGraphicsSystem
-//
-#ifdef Q_WS_WIN
-extern Q_GUI_EXPORT bool qt_win_owndc_required;
-#endif
-QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL)
- : QGraphicsSystem(), m_useX11GL(useX11GL)
-{
-#if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)
- // only override the system defaults if the user hasn't already
- // picked a visual
- if (X11->visual == 0 && X11->visual_id == -1 && X11->visual_class == -1) {
- // find a double buffered, RGBA visual that supports OpenGL
- // and set that as the default visual for windows in Qt
- int i = 0;
- int spec[16];
- spec[i++] = GLX_RGBA;
- spec[i++] = GLX_DOUBLEBUFFER;
-
- if (!qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull()) {
- spec[i++] = GLX_DEPTH_SIZE;
- spec[i++] = 8;
- spec[i++] = GLX_STENCIL_SIZE;
- spec[i++] = 8;
- spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
- spec[i++] = 1;
- spec[i++] = GLX_SAMPLES_ARB;
- spec[i++] = 4;
- }
-
- spec[i++] = XNone;
-
- XVisualInfo *vi = glXChooseVisual(X11->display, X11->defaultScreen, spec);
- if (vi) {
- X11->visual_id = vi->visualid;
- X11->visual_class = vi->c_class;
-
- QGLFormat format;
- int res;
- glXGetConfig(X11->display, vi, GLX_LEVEL, &res);
- format.setPlane(res);
- glXGetConfig(X11->display, vi, GLX_DOUBLEBUFFER, &res);
- format.setDoubleBuffer(res);
- glXGetConfig(X11->display, vi, GLX_DEPTH_SIZE, &res);
- format.setDepth(res);
- if (format.depth())
- format.setDepthBufferSize(res);
- glXGetConfig(X11->display, vi, GLX_RGBA, &res);
- format.setRgba(res);
- glXGetConfig(X11->display, vi, GLX_RED_SIZE, &res);
- format.setRedBufferSize(res);
- glXGetConfig(X11->display, vi, GLX_GREEN_SIZE, &res);
- format.setGreenBufferSize(res);
- glXGetConfig(X11->display, vi, GLX_BLUE_SIZE, &res);
- format.setBlueBufferSize(res);
- glXGetConfig(X11->display, vi, GLX_ALPHA_SIZE, &res);
- format.setAlpha(res);
- if (format.alpha())
- format.setAlphaBufferSize(res);
- glXGetConfig(X11->display, vi, GLX_ACCUM_RED_SIZE, &res);
- format.setAccum(res);
- if (format.accum())
- format.setAccumBufferSize(res);
- glXGetConfig(X11->display, vi, GLX_STENCIL_SIZE, &res);
- format.setStencil(res);
- if (format.stencil())
- format.setStencilBufferSize(res);
- glXGetConfig(X11->display, vi, GLX_STEREO, &res);
- format.setStereo(res);
- glXGetConfig(X11->display, vi, GLX_SAMPLE_BUFFERS_ARB, &res);
- format.setSampleBuffers(res);
- if (format.sampleBuffers()) {
- glXGetConfig(X11->display, vi, GLX_SAMPLES_ARB, &res);
- format.setSamples(res);
- }
-
- QGLWindowSurface::surfaceFormat = format;
- XFree(vi);
-
- printf("using visual class %x, id %x\n", X11->visual_class, X11->visual_id);
- }
- }
-#elif defined(Q_WS_WIN)
- QGLWindowSurface::surfaceFormat.setDoubleBuffer(true);
-
- qt_win_owndc_required = true;
-#endif
-}
-
-static void qt_cleanup_gl_share_widget();
-
-//
-// QGLWindowSurface
-//
-class QGLGlobalShareWidget
-{
-public:
- QGLGlobalShareWidget() : firstPixmap(0), widgetRefCount(0), widget(0), initializing(false) {
- // ### FIXME - readd the post routine if the qApp is recreated
- qAddPostRoutine(qt_cleanup_gl_share_widget);
- created = true;
- }
-
- QGLWidget *shareWidget() {
- if (!initializing && !widget && !cleanedUp) {
- initializing = true;
- widget = new QGLWidget(QGLFormat(QGL::SingleBuffer | QGL::NoDepthBuffer | QGL::NoStencilBuffer));
- widget->resize(1, 1);
-
- // We don't need this internal widget to appear in QApplication::topLevelWidgets()
- if (QWidgetPrivate::allWidgets)
- QWidgetPrivate::allWidgets->remove(widget);
- initializing = false;
- }
- return widget;
- }
-
- // destroys the share widget and prevents recreation
- void cleanup() {
- QGLWidget *w = widget;
- cleanedUp = true;
- widget = 0;
- delete w;
- }
-
- // destroys the share widget, but allows it to be recreated later on
- void destroy() {
- if (cleanedUp)
- return;
-
- QGLWidget *w = widget;
-
- // prevent potential recursions
- cleanedUp = true;
- widget = 0;
- delete w;
- cleanedUp = false;
- }
-
- static bool cleanedUp;
- static bool created;
-
- QGLPixmapData *firstPixmap;
- int widgetRefCount;
-
-private:
- QGLWidget *widget;
- bool initializing;
-};
-
-bool QGLGlobalShareWidget::cleanedUp = false;
-bool QGLGlobalShareWidget::created = false;
-
-Q_GLOBAL_STATIC(QGLGlobalShareWidget, _qt_gl_share_widget)
-
-static void qt_cleanup_gl_share_widget()
-{
- if (QGLGlobalShareWidget::created)
- _qt_gl_share_widget()->cleanup();
-}
-
-QGLWidget* qt_gl_share_widget()
-{
- if (QGLGlobalShareWidget::cleanedUp)
- return 0;
- return _qt_gl_share_widget()->shareWidget();
-}
-
-void qt_destroy_gl_share_widget()
-{
- if (QGLGlobalShareWidget::created)
- _qt_gl_share_widget()->destroy();
-}
-
-const QGLContext *qt_gl_share_context()
-{
- QGLWidget *widget = qt_gl_share_widget();
- if (widget)
- return widget->context();
- return 0;
-}
-
-#ifdef QGL_USE_TEXTURE_POOL
-void qt_gl_register_pixmap(QGLPixmapData *pd)
-{
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
- pd->next = shared->firstPixmap;
- pd->prev = 0;
- if (shared->firstPixmap)
- shared->firstPixmap->prev = pd;
- shared->firstPixmap = pd;
-}
-
-void qt_gl_unregister_pixmap(QGLPixmapData *pd)
-{
- if (pd->next)
- pd->next->prev = pd->prev;
- if (pd->prev) {
- pd->prev->next = pd->next;
- } else {
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
- if (shared)
- shared->firstPixmap = pd->next;
- }
-}
-
-void qt_gl_hibernate_pixmaps()
-{
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
-
- // Scan all QGLPixmapData objects in the system and hibernate them.
- QGLPixmapData *pd = shared->firstPixmap;
- while (pd != 0) {
- pd->hibernate();
- pd = pd->next;
- }
-}
-#endif
-
-struct QGLWindowSurfacePrivate
-{
- QGLFramebufferObject *fbo;
- QGLPixelBuffer *pb;
- GLuint tex_id;
- GLuint pb_tex_id;
-
- int tried_fbo : 1;
- int tried_pb : 1;
- int destructive_swap_buffers : 1;
- int geometry_updated : 1;
- int did_paint : 1;
-
- QGLContext *ctx;
-
- QList<QGLContext **> contexts;
-
- QRegion paintedRegion;
- QSize size;
-
- QSize textureSize;
-
- QList<QImage> buffers;
- QGLWindowSurfaceGLPaintDevice glDevice;
- QGLWindowSurface* q_ptr;
-
- bool swap_region_support;
-};
-
-QGLFormat QGLWindowSurface::surfaceFormat;
-QGLWindowSurface::SwapMode QGLWindowSurface::swapBehavior = QGLWindowSurface::AutomaticSwap;
-
-void QGLWindowSurfaceGLPaintDevice::endPaint()
-{
- glFlush();
- QGLPaintDevice::endPaint();
-}
-
-QSize QGLWindowSurfaceGLPaintDevice::size() const
-{
- return d->size;
-}
-
-QGLContext* QGLWindowSurfaceGLPaintDevice::context() const
-{
- return d->ctx;
-}
-
-
-int QGLWindowSurfaceGLPaintDevice::metric(PaintDeviceMetric m) const
-{
- return qt_paint_device_metric(d->q_ptr->window(), m);
-}
-
-QPaintEngine *QGLWindowSurfaceGLPaintDevice::paintEngine() const
-{
- return qt_qgl_paint_engine();
-}
-
-QGLWindowSurface::QGLWindowSurface(QWidget *window)
- : QWindowSurface(window), d_ptr(new QGLWindowSurfacePrivate)
-{
-// Q_ASSERT(window->isTopLevel());
- d_ptr->pb = 0;
- d_ptr->fbo = 0;
- d_ptr->ctx = 0;
- d_ptr->tex_id = 0;
-#if defined (QT_OPENGL_ES_2)
- d_ptr->tried_fbo = true;
- d_ptr->tried_pb = true;
-#else
- d_ptr->tried_fbo = false;
- d_ptr->tried_pb = false;
-#endif
- d_ptr->destructive_swap_buffers = qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull();
- d_ptr->glDevice.d = d_ptr;
- d_ptr->q_ptr = this;
- d_ptr->geometry_updated = false;
- d_ptr->did_paint = false;
- d_ptr->swap_region_support = false;
-}
-
-QGLWindowSurface::~QGLWindowSurface()
-{
- if (d_ptr->ctx)
- glDeleteTextures(1, &d_ptr->tex_id);
-#ifndef Q_WS_QPA // Dont delete the contexts. Destroying the window does that for us
- foreach(QGLContext **ctx, d_ptr->contexts) {
- delete *ctx;
- *ctx = 0;
- }
-#endif
- delete d_ptr->pb;
- delete d_ptr->fbo;
- delete d_ptr;
-
- if (QGLGlobalShareWidget::cleanedUp)
- return;
-
- --(_qt_gl_share_widget()->widgetRefCount);
-
-#ifdef QGL_USE_TEXTURE_POOL
- if (_qt_gl_share_widget()->widgetRefCount <= 0) {
- // All of the widget window surfaces have been destroyed
- // but we still have GL pixmaps active. Ask them to hibernate
- // to free up GPU resources until a widget is shown again.
- // This may eventually cause the EGLContext to be destroyed
- // because nothing in the system needs a context, which will
- // free up even more GPU resources.
- qt_gl_hibernate_pixmaps();
-
- // Destroy the context if necessary.
- if (!qt_gl_share_widget()->context()->isSharing())
- qt_destroy_gl_share_widget();
- }
-#endif // QGL_USE_TEXTURE_POOL
-}
-
-void QGLWindowSurface::deleted(QObject *object)
-{
- QWidget *widget = qobject_cast<QWidget *>(object);
- if (widget) {
- if (widget == window()) {
- // Make sure that the fbo is destroyed before destroying its context.
- delete d_ptr->fbo;
- d_ptr->fbo = 0;
- }
-
-#ifndef Q_WS_QPA //no need to specifically delete the QGLContext as it will be deleted by QWidget
- QWidgetPrivate *widgetPrivate = widget->d_func();
- if (widgetPrivate->extraData()) {
- union { QGLContext **ctxPtrPtr; void **voidPtrPtr; };
- voidPtrPtr = &widgetPrivate->extraData()->glContext;
- int index = d_ptr->contexts.indexOf(ctxPtrPtr);
- if (index != -1) {
- delete *ctxPtrPtr;
- *ctxPtrPtr = 0;
- d_ptr->contexts.removeAt(index);
- }
- }
-#endif
- }
-}
-
-void QGLWindowSurface::hijackWindow(QWidget *widget)
-{
- QWidgetPrivate *widgetPrivate = widget->d_func();
- widgetPrivate->createExtra();
- if (widgetPrivate->extraData()->glContext)
- return;
-
- QGLContext *ctx = NULL;
-
- // For translucent top-level widgets we need alpha in the format.
- if (widget->testAttribute(Qt::WA_TranslucentBackground)) {
- QGLFormat modFormat(surfaceFormat);
- modFormat.setSampleBuffers(false);
- modFormat.setSamples(0);
- modFormat.setAlpha(true);
- ctx = new QGLContext(modFormat, widget);
- } else
- ctx = new QGLContext(surfaceFormat, widget);
-
- ctx->create(qt_gl_share_context());
-
- if (widget != qt_gl_share_widget())
- ++(_qt_gl_share_widget()->widgetRefCount);
-
-#ifndef QT_NO_EGL
- static bool checkedForNOKSwapRegion = false;
- static bool haveNOKSwapRegion = false;
-
- if (!checkedForNOKSwapRegion) {
- haveNOKSwapRegion = QEgl::hasExtension("EGL_NOK_swap_region2");
- checkedForNOKSwapRegion = true;
-
- if (haveNOKSwapRegion)
- qDebug() << "Found EGL_NOK_swap_region2 extension. Using partial updates.";
- }
-
- d_ptr->destructive_swap_buffers = true;
- if (ctx->d_func()->eglContext->configAttrib(EGL_SURFACE_TYPE)&EGL_SWAP_BEHAVIOR_PRESERVED_BIT) {
- EGLint swapBehavior;
- if (eglQuerySurface(ctx->d_func()->eglContext->display(), ctx->d_func()->eglSurface
- , EGL_SWAP_BEHAVIOR, &swapBehavior)) {
- d_ptr->destructive_swap_buffers = (swapBehavior != EGL_BUFFER_PRESERVED);
- }
- }
-
- d_ptr->swap_region_support = haveNOKSwapRegion;
-#endif
-
- widgetPrivate->extraData()->glContext = ctx;
-
- union { QGLContext **ctxPtrPtr; void **voidPtrPtr; };
-
- connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(deleted(QObject*)));
-
- voidPtrPtr = &widgetPrivate->extraData()->glContext;
- d_ptr->contexts << ctxPtrPtr;
-#ifndef Q_OS_SYMBIAN
- qDebug() << "hijackWindow() context created for" << widget << d_ptr->contexts.size();
-#endif
-}
-
-QGLContext *QGLWindowSurface::context() const
-{
- return d_ptr->ctx;
-}
-
-QPaintDevice *QGLWindowSurface::paintDevice()
-{
- updateGeometry();
-
- if (d_ptr->pb)
- return d_ptr->pb;
-
- if (d_ptr->ctx)
- return &d_ptr->glDevice;
-
- QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
- ctx->makeCurrent();
-
- Q_ASSERT(d_ptr->fbo);
- return d_ptr->fbo;
-}
-
-static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &src = QRectF());
-
-void QGLWindowSurface::beginPaint(const QRegion &)
-{
- d_ptr->did_paint = true;
- updateGeometry();
-
- int clearFlags = 0;
-
- QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
-
- if (!ctx)
- return;
-
- if (ctx->d_func()->workaround_needsFullClearOnEveryFrame)
- clearFlags = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
- else if (ctx->format().alpha())
- clearFlags = GL_COLOR_BUFFER_BIT;
-
- if (clearFlags) {
- if (d_ptr->fbo)
- d_ptr->fbo->bind();
-
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glClear(clearFlags);
-
- if (d_ptr->fbo)
- d_ptr->fbo->release();
- }
-}
-
-void QGLWindowSurface::endPaint(const QRegion &rgn)
-{
- if (context())
- d_ptr->paintedRegion |= rgn;
-
- d_ptr->buffers.clear();
-}
-
-static void blitTexture(QGLContext *ctx, GLuint texture, const QSize &viewport, const QSize &texSize, const QRect &targetRect, const QRect &sourceRect)
-{
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
- glDisable(GL_BLEND);
-
- glViewport(0, 0, viewport.width(), viewport.height());
-
- QGLShaderProgram *blitProgram =
- QGLEngineSharedShaders::shadersForContext(ctx)->blitProgram();
- blitProgram->bind();
- blitProgram->setUniformValue("imageTexture", 0 /*QT_IMAGE_TEXTURE_UNIT*/);
-
- // The shader manager's blit program does not multiply the
- // vertices by the pmv matrix, so we need to do the effect
- // of the orthographic projection here ourselves.
- QRectF r;
- qreal w = viewport.width();
- qreal h = viewport.height();
- r.setLeft((targetRect.left() / w) * 2.0f - 1.0f);
- if (targetRect.right() == (viewport.width() - 1))
- r.setRight(1.0f);
- else
- r.setRight((targetRect.right() / w) * 2.0f - 1.0f);
- r.setBottom((targetRect.top() / h) * 2.0f - 1.0f);
- if (targetRect.bottom() == (viewport.height() - 1))
- r.setTop(1.0f);
- else
- r.setTop((targetRect.bottom() / w) * 2.0f - 1.0f);
-
- drawTexture(r, texture, texSize, sourceRect);
-}
-
-
-void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset)
-{
- //### Find out why d_ptr->geometry_updated isn't always false.
- // flush() should not be called when d_ptr->geometry_updated is true. It assumes that either
- // d_ptr->fbo or d_ptr->pb is allocated and has the correct size.
- if (d_ptr->geometry_updated)
- return;
-
- // did_paint is set to true in ::beginPaint. ::beginPaint means that we
- // at least cleared the background (= painted something). In EGL API it's a
- // mistake to call swapBuffers if nothing was painted unless
- // EGL_BUFFER_PRESERVED is set. This check protects the flush func from
- // being executed if it's for nothing.
- if (!d_ptr->destructive_swap_buffers && !d_ptr->did_paint)
- return;
-
-#ifdef Q_OS_SYMBIAN
- if (window() != widget) {
- // For performance reasons we don't support
- // flushing native child widgets on Symbian.
- // It breaks overlapping native child widget
- // rendering in some cases but we prefer performance.
- return;
- }
-#endif
-
-
- QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget();
- Q_ASSERT(parent);
-
-#if !defined(Q_WS_QPA)
- if (!geometry().isValid())
- return;
-#else
- if (!size().isValid())
- return;
-#endif
-
- // Needed to support native child-widgets...
- hijackWindow(parent);
-
- QRect br = rgn.boundingRect().translated(offset);
- br = br.intersected(window()->rect());
- QPoint wOffset = qt_qwidget_data(parent)->wrect.topLeft();
- QRect rect = br.translated(-offset - wOffset);
-
- const GLenum target = GL_TEXTURE_2D;
- Q_UNUSED(target);
-
- if (QGLWindowSurface::swapBehavior == QGLWindowSurface::KillSwap)
- return;
-
- if (context()) {
- context()->makeCurrent();
-
- if (context()->format().doubleBuffer()) {
-#if !defined(QT_OPENGL_ES_2)
- if (d_ptr->destructive_swap_buffers) {
- glBindTexture(target, d_ptr->tex_id);
-
- QVector<QRect> rects = d_ptr->paintedRegion.rects();
- for (int i = 0; i < rects.size(); ++i) {
- QRect br = rects.at(i);
- if (br.isEmpty())
- continue;
-
- const uint bottom = window()->height() - (br.y() + br.height());
- glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height());
- }
-
- glBindTexture(target, 0);
-
- QRegion dirtyRegion = QRegion(window()->rect()) - d_ptr->paintedRegion;
-
- if (!dirtyRegion.isEmpty()) {
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-#ifndef QT_OPENGL_ES
- glOrtho(0, window()->width(), window()->height(), 0, -999999, 999999);
-#else
- glOrthof(0, window()->width(), window()->height(), 0, -999999, 999999);
-#endif
- glViewport(0, 0, window()->width(), window()->height());
-
- QVector<QRect> rects = dirtyRegion.rects();
- glColor4f(1, 1, 1, 1);
- for (int i = 0; i < rects.size(); ++i) {
- QRect rect = rects.at(i);
- if (rect.isEmpty())
- continue;
-
- drawTexture(rect, d_ptr->tex_id, window()->size(), rect);
- }
- }
- }
-#endif
- bool doingPartialUpdate = false;
- if (d_ptr->swap_region_support) {
- if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AutomaticSwap)
- doingPartialUpdate = br.width() * br.height() < parent->geometry().width() * parent->geometry().height() * 0.2;
- else if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AlwaysPartialSwap)
- doingPartialUpdate = true;
- }
-
- QGLContext *ctx = reinterpret_cast<QGLContext *>(parent->d_func()->extraData()->glContext);
- if (widget != window()) {
- if (initializeOffscreenTexture(window()->size()))
- qWarning() << "QGLWindowSurface: Flushing to native child widget, may lead to significant performance loss";
- glBindTexture(target, d_ptr->tex_id);
-
- const uint bottom = window()->height() - (br.y() + br.height());
- glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height());
-
- glBindTexture(target, 0);
-
- ctx->makeCurrent();
- if (doingPartialUpdate)
- blitTexture(ctx, d_ptr->tex_id, parent->size(), window()->size(), rect, br);
- else
- blitTexture(ctx, d_ptr->tex_id, parent->size(), window()->size(), parent->rect(), parent->rect().translated(offset + wOffset));
- }
-
- if (doingPartialUpdate)
- ctx->d_func()->swapRegion(br);
- else
- ctx->swapBuffers();
-
- d_ptr->paintedRegion = QRegion();
- } else {
- glFlush();
- }
- return;
- }
-
- QGLContext *previous_ctx = const_cast<QGLContext *>(QGLContext::currentContext());
- QGLContext *ctx = reinterpret_cast<QGLContext *>(parent->d_func()->extraData()->glContext);
-
- // QPainter::end() should have unbound the fbo, otherwise something is very wrong...
- Q_ASSERT(!d_ptr->fbo || !d_ptr->fbo->isBound());
-
- if (ctx != previous_ctx) {
- ctx->makeCurrent();
- }
-
- QSize size = widget->rect().size();
- if (d_ptr->destructive_swap_buffers && ctx->format().doubleBuffer()) {
- rect = parent->rect();
- br = rect.translated(wOffset + offset);
- size = parent->size();
- }
-
- glDisable(GL_SCISSOR_TEST);
-
- if (d_ptr->fbo && (QGLExtensions::glExtensions() & QGLExtensions::FramebufferBlit)) {
- const int h = d_ptr->fbo->height();
-
- const int sx0 = br.left();
- const int sx1 = br.left() + br.width();
- const int sy0 = h - (br.top() + br.height());
- const int sy1 = h - br.top();
-
- const int tx0 = rect.left();
- const int tx1 = rect.left() + rect.width();
- const int ty0 = parent->height() - (rect.top() + rect.height());
- const int ty1 = parent->height() - rect.top();
-
- if (window() == parent || d_ptr->fbo->format().samples() <= 1) {
- if (ctx->d_ptr->current_fbo != 0)
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, d_ptr->fbo->handle());
-
- glBlitFramebufferEXT(sx0, sy0, sx1, sy1,
- tx0, ty0, tx1, ty1,
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0);
- } else {
- // can't do sub-region blits with multisample FBOs
- QGLFramebufferObject *temp = qgl_fbo_pool()->acquire(d_ptr->fbo->size(), QGLFramebufferObjectFormat());
-
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, temp->handle());
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, d_ptr->fbo->handle());
-
- glBlitFramebufferEXT(0, 0, d_ptr->fbo->width(), d_ptr->fbo->height(),
- 0, 0, d_ptr->fbo->width(), d_ptr->fbo->height(),
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, temp->handle());
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0);
-
- glBlitFramebufferEXT(sx0, sy0, sx1, sy1,
- tx0, ty0, tx1, ty1,
- GL_COLOR_BUFFER_BIT,
- GL_NEAREST);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0);
-
- qgl_fbo_pool()->release(temp);
- }
-
- ctx->d_ptr->current_fbo = 0;
- }
-#if !defined(QT_OPENGL_ES_2)
- else {
- GLuint texture;
- if (d_ptr->fbo) {
- texture = d_ptr->fbo->texture();
- } else {
- d_ptr->pb->makeCurrent();
- glBindTexture(target, d_ptr->pb_tex_id);
- const uint bottom = window()->height() - (br.y() + br.height());
- glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height());
- texture = d_ptr->pb_tex_id;
- glBindTexture(target, 0);
- }
-
- glDisable(GL_DEPTH_TEST);
-
- if (d_ptr->fbo) {
- d_ptr->fbo->release();
- } else {
- ctx->makeCurrent();
- }
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-#ifndef QT_OPENGL_ES
- glOrtho(0, size.width(), size.height(), 0, -999999, 999999);
-#else
- glOrthof(0, size.width(), size.height(), 0, -999999, 999999);
-#endif
- glViewport(0, 0, size.width(), size.height());
-
- glColor4f(1, 1, 1, 1);
- drawTexture(rect, texture, window()->size(), br);
-
- if (d_ptr->fbo)
- d_ptr->fbo->bind();
- }
-#else
- // OpenGL/ES 2.0 version of the fbo blit.
- else if (d_ptr->fbo) {
- Q_UNUSED(target);
-
- if (d_ptr->fbo->isBound())
- d_ptr->fbo->release();
-
- blitTexture(ctx, d_ptr->fbo->texture(), size, window()->size(), rect, br);
- }
-#endif
-
- if (ctx->format().doubleBuffer())
- ctx->swapBuffers();
- else
- glFlush();
-
- d_ptr->did_paint = false;
-}
-
-
-#if !defined(Q_WS_QPA)
-void QGLWindowSurface::setGeometry(const QRect &rect)
-{
- QWindowSurface::setGeometry(rect);
- d_ptr->geometry_updated = true;
-}
-#else
-void QGLWindowSurface::resize(const QSize &size)
-{
- QWindowSurface::resize(size);
- d_ptr->geometry_updated = true;
-}
-#endif
-
-void QGLWindowSurface::updateGeometry() {
- if (!d_ptr->geometry_updated)
- return;
- d_ptr->geometry_updated = false;
-
- bool hijack(true);
- QWidgetPrivate *wd = window()->d_func();
- if (wd->extraData() && wd->extraData()->glContext) {
-#ifdef Q_OS_SYMBIAN // Symbian needs to recreate the context when native window size changes
- if (d_ptr->size != geometry().size()) {
- if (window() != qt_gl_share_widget())
- --(_qt_gl_share_widget()->widgetRefCount);
-
- delete wd->extraData()->glContext;
- wd->extraData()->glContext = 0;
- d_ptr->ctx = 0;
- }
- else
-#endif
- {
- hijack = false; // we already have gl context for widget
- }
- }
-
- if (hijack)
- hijackWindow(window());
-
- QGLContext *ctx = reinterpret_cast<QGLContext *>(wd->extraData()->glContext);
-
-#ifdef Q_WS_MAC
- ctx->updatePaintDevice();
-#endif
-
- QSize surfSize = geometry().size();
-
- if (surfSize.width() <= 0 || surfSize.height() <= 0)
- return;
-
- if (d_ptr->size == surfSize)
- return;
-
- d_ptr->size = surfSize;
-
- if (d_ptr->ctx) {
-#ifndef QT_OPENGL_ES_2
- if (d_ptr->destructive_swap_buffers)
- initializeOffscreenTexture(surfSize);
-#endif
- return;
- }
-
- const GLenum target = GL_TEXTURE_2D;
- if (d_ptr->destructive_swap_buffers
- && (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject)
- && (d_ptr->fbo || !d_ptr->tried_fbo)
- && qt_gl_preferGL2Engine())
- {
- d_ptr->tried_fbo = true;
- ctx->d_ptr->internal_context = true;
- ctx->makeCurrent();
- delete d_ptr->fbo;
-
- QGLFramebufferObjectFormat format;
- format.setAttachment(QGLFramebufferObject::CombinedDepthStencil);
- format.setInternalTextureFormat(GLenum(GL_RGBA));
- format.setTextureTarget(target);
-
- if (QGLExtensions::glExtensions() & QGLExtensions::FramebufferBlit)
- format.setSamples(8);
-
- d_ptr->fbo = new QGLFramebufferObject(surfSize, format);
-
- if (d_ptr->fbo->isValid()) {
- qDebug() << "Created Window Surface FBO" << surfSize
- << "with samples" << d_ptr->fbo->format().samples();
- return;
- } else {
- qDebug() << "QGLWindowSurface: Failed to create valid FBO, falling back";
- delete d_ptr->fbo;
- d_ptr->fbo = 0;
- }
- }
-
-#if !defined(QT_OPENGL_ES_2) && !defined(Q_WS_QPA) //QPA doesn't support pixelbuffers
- if (d_ptr->destructive_swap_buffers && (d_ptr->pb || !d_ptr->tried_pb)) {
- d_ptr->tried_pb = true;
-
- if (d_ptr->pb) {
- d_ptr->pb->makeCurrent();
- glDeleteTextures(1, &d_ptr->pb_tex_id);
- }
-
- delete d_ptr->pb;
-
- d_ptr->pb = new QGLPixelBuffer(surfSize.width(), surfSize.height(),
- QGLFormat(QGL::SampleBuffers | QGL::StencilBuffer | QGL::DepthBuffer),
- qt_gl_share_widget());
-
- if (d_ptr->pb->isValid()) {
- qDebug() << "Created Window Surface Pixelbuffer, Sample buffers:" << d_ptr->pb->format().sampleBuffers();
- d_ptr->pb->makeCurrent();
-
- glGenTextures(1, &d_ptr->pb_tex_id);
- glBindTexture(target, d_ptr->pb_tex_id);
- glTexImage2D(target, 0, GL_RGBA, surfSize.width(), surfSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-
- glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glBindTexture(target, 0);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999);
-
- d_ptr->pb->d_ptr->qctx->d_func()->internal_context = true;
- return;
- } else {
- qDebug() << "QGLWindowSurface: Failed to create valid pixelbuffer, falling back";
- delete d_ptr->pb;
- d_ptr->pb = 0;
- }
- }
-#endif // !defined(QT_OPENGL_ES_2) !defined(Q_WS_QPA)
-
- ctx->makeCurrent();
-
-#ifndef QT_OPENGL_ES_2
- if (d_ptr->destructive_swap_buffers)
- initializeOffscreenTexture(surfSize);
-#endif
-#ifndef Q_OS_SYMBIAN
- qDebug() << "QGLWindowSurface: Using plain widget as window surface" << this;
-#endif
- d_ptr->ctx = ctx;
- d_ptr->ctx->d_ptr->internal_context = true;
-}
-
-bool QGLWindowSurface::initializeOffscreenTexture(const QSize &size)
-{
- if (size == d_ptr->textureSize)
- return false;
-
- glGenTextures(1, &d_ptr->tex_id);
- glBindTexture(GL_TEXTURE_2D, d_ptr->tex_id);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.width(), size.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
-
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- d_ptr->textureSize = size;
- return true;
-}
-
-bool QGLWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- // this code randomly fails currently for unknown reasons
- return false;
-
- if (!d_ptr->pb)
- return false;
-
- d_ptr->pb->makeCurrent();
-
- QRect br = area.boundingRect();
-
-#if 0
- // ## workaround driver issue (scrolling by these deltas is unbearably slow for some reason)
- // ## maybe we should use glCopyTexSubImage insteadk
- if (dx == 1 || dx == -1 || dy == 1 || dy == -1 || dy == 2)
- return false;
-
- glRasterPos2i(br.x() + dx, br.y() + br.height() + dy);
- glCopyPixels(br.x(), d_ptr->pb->height() - (br.y() + br.height()), br.width(), br.height(), GL_COLOR);
- return true;
-#endif
-
- const GLenum target = GL_TEXTURE_2D;
-
- glBindTexture(target, d_ptr->tex_id);
- glCopyTexImage2D(target, 0, GL_RGBA, br.x(), d_ptr->pb->height() - (br.y() + br.height()), br.width(), br.height(), 0);
- glBindTexture(target, 0);
-
- drawTexture(br.translated(dx, dy), d_ptr->tex_id, window()->size());
-
- return true;
-}
-
-static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &br)
-{
- const GLenum target = GL_TEXTURE_2D;
- QRectF src = br.isEmpty()
- ? QRectF(QPointF(), texSize)
- : QRectF(QPointF(br.x(), texSize.height() - br.bottom()), br.size());
-
- if (target == GL_TEXTURE_2D) {
- qreal width = texSize.width();
- qreal height = texSize.height();
-
- src.setLeft(src.left() / width);
- src.setRight(src.right() / width);
- src.setTop(src.top() / height);
- src.setBottom(src.bottom() / height);
- }
-
- const GLfloat tx1 = src.left();
- const GLfloat tx2 = src.right();
- const GLfloat ty1 = src.top();
- const GLfloat ty2 = src.bottom();
-
- GLfloat texCoordArray[4*2] = {
- tx1, ty2, tx2, ty2, tx2, ty1, tx1, ty1
- };
-
- GLfloat vertexArray[4*2];
- extern void qt_add_rect_to_array(const QRectF &r, GLfloat *array); // qpaintengine_opengl.cpp
- qt_add_rect_to_array(rect, vertexArray);
-
-#if !defined(QT_OPENGL_ES_2)
- glVertexPointer(2, GL_FLOAT, 0, vertexArray);
- glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray);
-
- glBindTexture(target, tex_id);
- glEnable(target);
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glDisable(target);
- glBindTexture(target, 0);
-#else
- glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexArray);
- glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, texCoordArray);
-
- glBindTexture(target, tex_id);
-
- glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
- glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR);
- glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR);
-
- glBindTexture(target, 0);
-#endif
-}
-
-QImage *QGLWindowSurface::buffer(const QWidget *widget)
-{
- QImage image;
-
- if (d_ptr->pb)
- image = d_ptr->pb->toImage();
- else if (d_ptr->fbo)
- image = d_ptr->fbo->toImage();
-
- if (image.isNull())
- return 0;
-
- QRect rect = widget->rect();
- rect.translate(widget->mapTo(widget->window(), QPoint()));
-
- QImage subImage = image.copy(rect);
- d_ptr->buffers << subImage;
- return &d_ptr->buffers.last();
-}
-
-QWindowSurface::WindowSurfaceFeatures QGLWindowSurface::features() const
-{
- WindowSurfaceFeatures features = 0;
- if (!d_ptr->destructive_swap_buffers || d_ptr->swap_region_support)
- features |= PartialUpdates;
- if (!d_ptr->destructive_swap_buffers)
- features |= PreservedContents;
- return features;
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/opengl/qwindowsurface_gl_p.h b/src/opengl/qwindowsurface_gl_p.h
deleted file mode 100644
index 91d1f9e245..0000000000
--- a/src/opengl/qwindowsurface_gl_p.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_GL_P_H
-#define QWINDOWSURFACE_GL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qglobal.h>
-#include <qgl.h>
-#include <private/qwindowsurface_p.h>
-#include <private/qglpaintdevice_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPaintDevice;
-class QPoint;
-class QRegion;
-class QWidget;
-struct QGLWindowSurfacePrivate;
-
-Q_OPENGL_EXPORT QGLWidget* qt_gl_share_widget();
-Q_OPENGL_EXPORT void qt_destroy_gl_share_widget();
-
-class QGLWindowSurfaceGLPaintDevice : public QGLPaintDevice
-{
-public:
- QPaintEngine* paintEngine() const;
- void endPaint();
- QSize size() const;
- int metric(PaintDeviceMetric m) const;
- QGLContext* context() const;
- QGLWindowSurfacePrivate* d;
-};
-
-class Q_OPENGL_EXPORT QGLWindowSurface : public QObject, public QWindowSurface // , public QPaintDevice
-{
- Q_OBJECT
-public:
- QGLWindowSurface(QWidget *window);
- ~QGLWindowSurface();
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
-
-#if !defined(Q_WS_QPA)
- void setGeometry(const QRect &rect);
-#else
- virtual void resize(const QSize &size);
-#endif
-
- void updateGeometry();
- bool scroll(const QRegion &area, int dx, int dy);
-
- void beginPaint(const QRegion &region);
- void endPaint(const QRegion &region);
-
- QImage *buffer(const QWidget *widget);
-
- WindowSurfaceFeatures features() const;
-
- QGLContext *context() const;
-
- static QGLFormat surfaceFormat;
-
- enum SwapMode { AutomaticSwap, AlwaysFullSwap, AlwaysPartialSwap, KillSwap };
- static SwapMode swapBehavior;
-
-private slots:
- void deleted(QObject *object);
-
-private:
- void hijackWindow(QWidget *widget);
- bool initializeOffscreenTexture(const QSize &size);
-
- QGLWindowSurfacePrivate *d_ptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSURFACE_GL_P_H
-
diff --git a/src/opengl/qwindowsurface_x11gl.cpp b/src/opengl/qwindowsurface_x11gl.cpp
deleted file mode 100644
index bec0ea7587..0000000000
--- a/src/opengl/qwindowsurface_x11gl.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QTime>
-#include <QDebug>
-
-#include <private/qt_x11_p.h>
-#include <private/qimagepixmapcleanuphooks_p.h>
-
-#include "qwindowsurface_x11gl_p.h"
-#include "qpixmapdata_x11gl_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QX11GLWindowSurface::QX11GLWindowSurface(QWidget* window)
- : QWindowSurface(window), m_windowGC(0), m_pixmapGC(0), m_window(window)
-{
-}
-
-QX11GLWindowSurface::~QX11GLWindowSurface()
-{
- if (m_windowGC)
- XFree(m_windowGC);
- if (m_pixmapGC)
- XFree(m_pixmapGC);
-}
-
-QPaintDevice *QX11GLWindowSurface::paintDevice()
-{
- return &m_backBuffer;
-}
-
-extern void *qt_getClipRects(const QRegion &r, int &num); // in qpaintengine_x11.cpp
-
-void QX11GLWindowSurface::flush(QWidget *widget, const QRegion &widgetRegion, const QPoint &offset)
-{
- // We don't need to know the widget which initiated the flush. Instead we just use the offset
- // to translate the widgetRegion:
- Q_UNUSED(widget);
-
- if (m_backBuffer.isNull()) {
- qDebug("QX11GLWindowSurface::flush() - backBuffer is null, not flushing anything");
- return;
- }
-
- Q_ASSERT(window()->size() != m_backBuffer.size());
-
- // Wait for all GL rendering to the back buffer pixmap to complete before trying to
- // copy it to the window. We do this by making sure the pixmap's context is current
- // and then call eglWaitClient. The EGL 1.4 spec says eglWaitClient doesn't have to
- // block, just that "All rendering calls...are guaranteed to be executed before native
- // rendering calls". This makes it potentially less expensive than glFinish.
- QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data())->context();
- if (QGLContext::currentContext() != ctx && ctx && ctx->isValid())
- ctx->makeCurrent();
- eglWaitClient();
-
- if (m_windowGC == 0) {
- XGCValues attribs;
- attribs.graphics_exposures = False;
- m_windowGC = XCreateGC(X11->display, m_window->handle(), GCGraphicsExposures, &attribs);
- }
-
- int rectCount;
- XRectangle *rects = (XRectangle *)qt_getClipRects(widgetRegion, rectCount);
- if (rectCount <= 0)
- return;
-
- XSetClipRectangles(X11->display, m_windowGC, 0, 0, rects, rectCount, YXBanded);
-
- QRect dirtyRect = widgetRegion.boundingRect().translated(-offset);
- XCopyArea(X11->display, m_backBuffer.handle(), m_window->handle(), m_windowGC,
- dirtyRect.x(), dirtyRect.y(), dirtyRect.width(), dirtyRect.height(),
- dirtyRect.x(), dirtyRect.y());
-
- // Make sure the blit of the update from the back buffer to the window completes
- // before allowing rendering to start again to the back buffer. Otherwise the GPU
- // might start rendering to the back buffer again while the blit takes place.
- eglWaitNative(EGL_CORE_NATIVE_ENGINE);
-}
-
-void QX11GLWindowSurface::setGeometry(const QRect &rect)
-{
- if (rect.width() > m_backBuffer.size().width() || rect.height() > m_backBuffer.size().height()) {
- QX11GLPixmapData *pd = new QX11GLPixmapData;
- QSize newSize = rect.size();
- pd->resize(newSize.width(), newSize.height());
- m_backBuffer = QPixmap(pd);
- if (window()->testAttribute(Qt::WA_TranslucentBackground))
- m_backBuffer.fill(Qt::transparent);
- if (m_pixmapGC) {
- XFreeGC(X11->display, m_pixmapGC);
- m_pixmapGC = 0;
- }
- }
-
- QWindowSurface::setGeometry(rect);
-}
-
-bool QX11GLWindowSurface::scroll(const QRegion &area, int dx, int dy)
-{
- if (m_backBuffer.isNull())
- return false;
-
- Q_ASSERT(m_backBuffer.data_ptr()->classId() == QPixmapData::X11Class);
-
- // Make sure all GL rendering is complete before starting the scroll operation:
- QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.data_ptr().data())->context();
- if (QGLContext::currentContext() != ctx && ctx && ctx->isValid())
- ctx->makeCurrent();
- eglWaitClient();
-
- if (!m_pixmapGC)
- m_pixmapGC = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0);
-
- foreach (const QRect& rect, area.rects()) {
- XCopyArea(X11->display, m_backBuffer.handle(), m_backBuffer.handle(), m_pixmapGC,
- rect.x(), rect.y(), rect.width(), rect.height(),
- rect.x()+dx, rect.y()+dy);
- }
-
- // Make sure the scroll operation is complete before allowing GL rendering to resume
- eglWaitNative(EGL_CORE_NATIVE_ENGINE);
-
- return true;
-}
-
-
-QPixmap QX11GLWindowSurface::grabWidget(const QWidget *widget, const QRect& rect) const
-{
- if (!widget || m_backBuffer.isNull())
- return QPixmap();
-
- QRect srcRect;
-
- // make sure the rect is inside the widget & clip to widget's rect
- if (!rect.isEmpty())
- srcRect = rect & widget->rect();
- else
- srcRect = widget->rect();
-
- if (srcRect.isEmpty())
- return QPixmap();
-
- // If it's a child widget we have to translate the coordinates
- if (widget != window())
- srcRect.translate(widget->mapTo(window(), QPoint(0, 0)));
-
- QPixmap::x11SetDefaultScreen(widget->x11Info().screen());
-
- QX11PixmapData *pmd = new QX11PixmapData(QPixmapData::PixmapType);
- pmd->resize(srcRect.width(), srcRect.height());
- QPixmap px(pmd);
-
- GC tmpGc = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0);
-
- // Make sure all GL rendering is complete before copying the window
- QGLContext* ctx = static_cast<QX11GLPixmapData*>(m_backBuffer.pixmapData())->context();
- if (QGLContext::currentContext() != ctx && ctx && ctx->isValid())
- ctx->makeCurrent();
- eglWaitClient();
-
- // Copy srcRect from the backing store to the new pixmap
- XSetGraphicsExposures(X11->display, tmpGc, False);
- XCopyArea(X11->display, m_backBuffer.handle(), px.handle(), tmpGc,
- srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), 0, 0);
- XFreeGC(X11->display, tmpGc);
-
- // Wait until the copy has finised before allowing more rendering into the back buffer
- eglWaitNative(EGL_CORE_NATIVE_ENGINE);
-
- return px;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/qwindowsurface_x11gl_p.h b/src/opengl/qwindowsurface_x11gl_p.h
deleted file mode 100644
index 737997b879..0000000000
--- a/src/opengl/qwindowsurface_x11gl_p.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSURFACE_X11GL_P_H
-#define QWINDOWSURFACE_X11GL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qwindowsurface_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QX11GLWindowSurface : public QWindowSurface
-{
-public:
- QX11GLWindowSurface(QWidget* window);
- virtual ~QX11GLWindowSurface();
-
- // Inherreted from QWindowSurface
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- void setGeometry(const QRect &rect);
- bool scroll(const QRegion &area, int dx, int dy);
- QPixmap grabWidget(const QWidget *widget, const QRect& rectangle = QRect()) const;
-
-private:
- GC m_windowGC;
- GC m_pixmapGC;
- QPixmap m_backBuffer;
- QWidget *m_window;
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSURFACE_X11GL_P_H
diff --git a/src/opengl/util/README-GLSL b/src/opengl/util/README-GLSL
deleted file mode 100644
index ff20eb45b2..0000000000
--- a/src/opengl/util/README-GLSL
+++ /dev/null
@@ -1,18 +0,0 @@
-Use of GLSL for vertex and fragment programs in Qt
----------------------------------------------------
-
-We don't compile the *.glsl files because we don't want the build process of
-Qt to require cgc from nVidia to build the fragment programs.
-
-The script src/opengl/util/glsl_to_include.sh will compile a GLSL program to a file
-that can be included in a C(++) program. The file is the output from cgc
-quoted as a string.
-
-This can be done manually by:
-
-./glsl_to_include.sh radial.glsl
-./glsl_to_include.sh conical.glsl
-
-This will produce the files radial.frag and radial.glsl_quoted.
-(and also conical.frag and conical.glsl_quoted)
-These files are included by qpaintengine_opengl.cpp
diff --git a/src/opengl/util/brush_painter.glsl b/src/opengl/util/brush_painter.glsl
deleted file mode 100644
index 6c4acdf924..0000000000
--- a/src/opengl/util/brush_painter.glsl
+++ /dev/null
@@ -1,7 +0,0 @@
-// fast brush painter for composition modes which can be implemented with blendfuncs
-// no mask, used for fast filling of aliased primitives (or multisampled)
-
-void main()
-{
- gl_FragColor = brush();
-}
diff --git a/src/opengl/util/brushes.conf b/src/opengl/util/brushes.conf
deleted file mode 100644
index 93e2b3b295..0000000000
--- a/src/opengl/util/brushes.conf
+++ /dev/null
@@ -1,6 +0,0 @@
-FRAGMENT_PROGRAM_BRUSH_SOLID solid_brush.glsl
-FRAGMENT_PROGRAM_BRUSH_RADIAL radial_brush.glsl
-FRAGMENT_PROGRAM_BRUSH_CONICAL conical_brush.glsl
-FRAGMENT_PROGRAM_BRUSH_LINEAR linear_brush.glsl
-FRAGMENT_PROGRAM_BRUSH_TEXTURE texture_brush.glsl
-FRAGMENT_PROGRAM_BRUSH_PATTERN pattern_brush.glsl
diff --git a/src/opengl/util/composition_mode_colorburn.glsl b/src/opengl/util/composition_mode_colorburn.glsl
deleted file mode 100644
index c913b9737f..0000000000
--- a/src/opengl/util/composition_mode_colorburn.glsl
+++ /dev/null
@@ -1,13 +0,0 @@
-// Dca' = Sca.Da + Dca.Sa <= Sa.Da ?
-// Sca.(1 - Da) + Dca.(1 - Sa)
-// Sa.(Sca.Da + Dca.Sa - Sa.Da)/Sca + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = mix(src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a),
- src.a * (src.rgb * dst.a + dst.rgb * src.a - src.a * dst.a) / max(src.rgb, 0.00001) + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a),
- step(src.a * dst.a, src.rgb * dst.a + dst.rgb * src.a));
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_colordodge.glsl b/src/opengl/util/composition_mode_colordodge.glsl
deleted file mode 100644
index b75e83cf4e..0000000000
--- a/src/opengl/util/composition_mode_colordodge.glsl
+++ /dev/null
@@ -1,15 +0,0 @@
-// Dca' = Sca.Da + Dca.Sa <= Sa.Da ?
-// Dca.Sa/(1 - Sca/Sa) + Sca.(1 - Da) + Dca.(1 - Sa) :
-// Sa.Da + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- vec3 temp = src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
- result.rgb = mix(dst.rgb * src.a / max(1.0 - src.rgb / max(src.a, 0.000001), 0.000001) + temp,
- src.a * dst.a + temp,
- step(src.a * dst.a, src.rgb * dst.a + dst.rgb * src.a));
-
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_darken.glsl b/src/opengl/util/composition_mode_darken.glsl
deleted file mode 100644
index 8bbb82b3ce..0000000000
--- a/src/opengl/util/composition_mode_darken.glsl
+++ /dev/null
@@ -1,9 +0,0 @@
-// Dca' = min(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = min(src.rgb * dst.a, dst.rgb * src.a) + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_difference.glsl b/src/opengl/util/composition_mode_difference.glsl
deleted file mode 100644
index 3c46ec71f2..0000000000
--- a/src/opengl/util/composition_mode_difference.glsl
+++ /dev/null
@@ -1,9 +0,0 @@
-// Dca' = Sca + Dca - 2.min(Sca.Da, Dca.Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = src.rgb + dst.rgb - 2.0 * min(src.rgb * dst.a, dst.rgb * src.a);
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_exclusion.glsl b/src/opengl/util/composition_mode_exclusion.glsl
deleted file mode 100644
index 59c2da99ea..0000000000
--- a/src/opengl/util/composition_mode_exclusion.glsl
+++ /dev/null
@@ -1,9 +0,0 @@
-// Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = (src.rgb * dst.a + dst.rgb * src.a - 2.0 * src.rgb * dst.rgb) + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_hardlight.glsl b/src/opengl/util/composition_mode_hardlight.glsl
deleted file mode 100644
index 4ea355029d..0000000000
--- a/src/opengl/util/composition_mode_hardlight.glsl
+++ /dev/null
@@ -1,14 +0,0 @@
-// Dca' = 2.Sca < Sa ?
-// 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) :
-// Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = mix(2.0 * src.rgb * dst.rgb + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a),
- src.a * dst.a - 2.0 * (dst.a - dst.rgb) * (src.a - src.rgb) + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a),
- step(src.a, 2.0 * src.rgb));
- result.a = src.a + dst.a - src.a * dst.a;
-
- return result;
-}
diff --git a/src/opengl/util/composition_mode_lighten.glsl b/src/opengl/util/composition_mode_lighten.glsl
deleted file mode 100644
index 13ef507a4c..0000000000
--- a/src/opengl/util/composition_mode_lighten.glsl
+++ /dev/null
@@ -1,9 +0,0 @@
-// Dca' = max(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = max(src.rgb * dst.a, dst.rgb * src.a) + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_multiply.glsl b/src/opengl/util/composition_mode_multiply.glsl
deleted file mode 100644
index f90b7f00ad..0000000000
--- a/src/opengl/util/composition_mode_multiply.glsl
+++ /dev/null
@@ -1,9 +0,0 @@
-// Dca' = Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = src.rgb * dst.rgb + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_overlay.glsl b/src/opengl/util/composition_mode_overlay.glsl
deleted file mode 100644
index f621bdee96..0000000000
--- a/src/opengl/util/composition_mode_overlay.glsl
+++ /dev/null
@@ -1,13 +0,0 @@
-// Dca' = 2.Dca < Da ?
-// 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
-// Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- result.rgb = mix(2.0 * src.rgb * dst.rgb + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a),
- src.a * dst.a - 2.0 * (dst.a - dst.rgb) * (src.a - src.rgb) + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a),
- step(dst.a, 2.0 * dst.rgb));
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_mode_screen.glsl b/src/opengl/util/composition_mode_screen.glsl
deleted file mode 100644
index 8f4f010032..0000000000
--- a/src/opengl/util/composition_mode_screen.glsl
+++ /dev/null
@@ -1,6 +0,0 @@
-// Dca' = Sca + Dca - Sca.Dca
-// Da' = Sa + Da - Sa.Da
-vec4 composite(vec4 src, vec4 dst)
-{
- return src + dst - src * dst;
-}
diff --git a/src/opengl/util/composition_mode_softlight.glsl b/src/opengl/util/composition_mode_softlight.glsl
deleted file mode 100644
index e4c1f89156..0000000000
--- a/src/opengl/util/composition_mode_softlight.glsl
+++ /dev/null
@@ -1,22 +0,0 @@
-// if 2.Sca <= Sa
-// Dca' = Dca.(Sa + (2.Sca - Sa).(1 - Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa)
-// otherwise if 2.Sca > Sa and 4.Dca <= Da
-// Dca' = Dca.Sa + Da.(2.Sca - Sa).(4.Dca/Da.(4.Dca/Da + 1).(Dca/Da - 1) + 7.Dca/Da) + Sca.(1 - Da) + Dca.(1 - Sa)
-// otherwise if 2.Sca > Sa and 4.Dca > Da
-// Dca' = Dca.Sa + Da.(2.Sca - Sa).((Dca/Da)^0.5 - Dca/Da) + Sca.(1 - Da) + Dca.(1 - Sa)
-// Da' = Sa + Da - Sa.Da
-
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
- float da = max(dst.a, 0.00001);
- vec3 dst_np = dst.rgb / da;
- result.rgb = mix(dst.rgb * (src.a + (2.0 * src.rgb - src.a) * (1.0 - dst_np)),
- mix(dst.rgb * src.a + dst.a * (2.0 * src.rgb - src.a) * ((16.0 * dst_np - 12.0) * dst_np + 3.0) * dst_np,
- dst.rgb * src.a + dst.a * (2.0 * src.rgb - src.a) * (sqrt(dst_np) - dst_np),
- step(dst.a, 4.0 * dst.rgb)),
- step(src.a, 2.0 * src.rgb))
- + src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
- result.a = src.a + dst.a - src.a * dst.a;
- return result;
-}
diff --git a/src/opengl/util/composition_modes.conf b/src/opengl/util/composition_modes.conf
deleted file mode 100644
index df52830b99..0000000000
--- a/src/opengl/util/composition_modes.conf
+++ /dev/null
@@ -1,12 +0,0 @@
-COMPOSITION_MODES_SIMPLE_PORTER_DUFF simple_porter_duff.glsl
-COMPOSITION_MODES_MULTIPLY composition_mode_multiply.glsl
-COMPOSITION_MODES_SCREEN composition_mode_screen.glsl
-COMPOSITION_MODES_OVERLAY composition_mode_overlay.glsl
-COMPOSITION_MODES_DARKEN composition_mode_darken.glsl
-COMPOSITION_MODES_LIGHTEN composition_mode_lighten.glsl
-COMPOSITION_MODES_COLORDODGE composition_mode_colordodge.glsl
-COMPOSITION_MODES_COLORBURN composition_mode_colorburn.glsl
-COMPOSITION_MODES_HARDLIGHT composition_mode_hardlight.glsl
-COMPOSITION_MODES_SOFTLIGHT composition_mode_softlight.glsl
-COMPOSITION_MODES_DIFFERENCE composition_mode_difference.glsl
-COMPOSITION_MODES_EXCLUSION composition_mode_exclusion.glsl
diff --git a/src/opengl/util/conical_brush.glsl b/src/opengl/util/conical_brush.glsl
deleted file mode 100644
index b3ec1d7efe..0000000000
--- a/src/opengl/util/conical_brush.glsl
+++ /dev/null
@@ -1,27 +0,0 @@
-// conical gradient shader
-#define M_PI 3.14159265358979323846
-uniform sampler1D palette;
-uniform float angle;
-uniform vec3 inv_matrix_m0;
-uniform vec3 inv_matrix_m1;
-uniform vec3 inv_matrix_m2;
-
-vec4 brush()
-{
- mat3 mat;
-
- mat[0] = inv_matrix_m0;
- mat[1] = inv_matrix_m1;
- mat[2] = inv_matrix_m2;
-
- vec3 hcoords = mat * vec3(gl_FragCoord.xy, 1);
- vec2 A = hcoords.xy / hcoords.z;
-
-/* float val = fmod((atan2(-A.y, A.x) + angle) / (2.0 * M_PI), 1); */
- if (abs(A.y) == abs(A.x))
- A.y += 0.002;
- float t = (atan(-A.y, A.x) + angle) / (2.0 * M_PI);
- float val = t - floor(t);
- return texture1D(palette, val);
-}
-
diff --git a/src/opengl/util/ellipse_aa.glsl b/src/opengl/util/ellipse_aa.glsl
deleted file mode 100644
index 257e3bbd47..0000000000
--- a/src/opengl/util/ellipse_aa.glsl
+++ /dev/null
@@ -1,58 +0,0 @@
-uniform vec3 inv_matrix_m0;
-uniform vec3 inv_matrix_m1;
-uniform vec3 inv_matrix_m2;
-
-uniform vec2 ellipse_offset;
-
-// ellipse equation
-
-// s^2/a^2 + t^2/b^2 = 1
-//
-// implicit equation:
-// g(s,t) = 1 - s^2/r_s^2 - t^2/r_t^2
-
-// distance from ellipse:
-// grad = [dg/dx dg/dy]
-// d(s, t) ~= g(s, t) / |grad|
-
-// dg/dx = dg/ds * ds/dx + dg/dt * dt/dx
-// dg/dy = dg/ds * ds/dy + dg/dt * dt/dy
-
-float ellipse_aa()
-{
- mat3 mat;
-
- mat[0] = inv_matrix_m0;
- mat[1] = inv_matrix_m1;
- mat[2] = inv_matrix_m2;
-
- vec3 hcoords = mat * vec3(gl_FragCoord.xy + ellipse_offset, 1);
- float inv_w = 1.0 / hcoords.z;
- vec2 st = hcoords.xy * inv_w;
-
- vec4 xy = vec4(mat[0].xy, mat[1].xy);
- vec2 h = vec2(mat[0].z, mat[1].z);
-
- vec4 dstdxy = (xy.xzyw - h.xyxy * st.xxyy) * inv_w;
-
- //dstdxy.x = (mat[0].x - mat[0].z * st.x) * inv_w; // ds/dx
- //dstdxy.y = (mat[1].x - mat[1].z * st.x) * inv_w; // ds/dy
- //dstdxy.z = (mat[0].y - mat[0].z * st.y) * inv_w; // dt/dx
- //dstdxy.w = (mat[1].y - mat[1].z * st.y) * inv_w; // dt/dy
-
- vec2 inv_r = gl_TexCoord[0].xy;
- vec2 n = st * inv_r;
- float g = 1.0 - dot(n, n);
-
- vec2 dgdst = -2.0 * n * inv_r;
-
- vec2 grad = vec2(dot(dgdst, dstdxy.xz),
- dot(dgdst, dstdxy.yw));
-
- return smoothstep(-0.5, 0.5, g * inversesqrt(dot(grad, grad)));
-}
-
-void main()
-{
- gl_FragColor = ellipse_aa().xxxx;
-}
diff --git a/src/opengl/util/fast_painter.glsl b/src/opengl/util/fast_painter.glsl
deleted file mode 100644
index 63f5e5f3be..0000000000
--- a/src/opengl/util/fast_painter.glsl
+++ /dev/null
@@ -1,19 +0,0 @@
-// fast painter for composition modes which can be implemented with blendfuncs
-
-uniform sampler2D mask_texture;
-uniform vec2 inv_mask_size;
-uniform vec2 mask_offset;
-uniform vec4 mask_channel;
-
-float mask()
-{
- return dot(mask_channel, texture2D(mask_texture, (gl_FragCoord.xy + mask_offset) * inv_mask_size));
-}
-
-void main()
-{
- // combine clip and coverage channels
- float mask_alpha = mask();
-
- gl_FragColor = brush() * mask_alpha;
-}
diff --git a/src/opengl/util/fragmentprograms_p.h b/src/opengl/util/fragmentprograms_p.h
deleted file mode 100644
index b1a47e3d5f..0000000000
--- a/src/opengl/util/fragmentprograms_p.h
+++ /dev/null
@@ -1,7287 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef FRAGMENTPROGRAMS_P_H
-#define FRAGMENTPROGRAMS_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-enum FragmentVariable {
- VAR_BRUSH_TEXTURE,
- VAR_LINEAR,
- VAR_INV_MATRIX_M1,
- VAR_INV_MASK_SIZE,
- VAR_INV_MATRIX_M2,
- VAR_PORTERDUFF_AB,
- VAR_MASK_CHANNEL,
- VAR_ELLIPSE_OFFSET,
- VAR_PORTERDUFF_XYZ,
- VAR_INV_DST_SIZE,
- VAR_MASK_TEXTURE,
- VAR_DST_TEXTURE,
- VAR_PALETTE,
- VAR_MASK_OFFSET,
- VAR_INV_BRUSH_TEXTURE_SIZE,
- VAR_FMP2_M_RADIUS2,
- VAR_FMP,
- VAR_INV_MATRIX_M0,
- VAR_ANGLE
-};
-
-enum FragmentBrushType {
- FRAGMENT_PROGRAM_BRUSH_SOLID,
- FRAGMENT_PROGRAM_BRUSH_RADIAL,
- FRAGMENT_PROGRAM_BRUSH_CONICAL,
- FRAGMENT_PROGRAM_BRUSH_LINEAR,
- FRAGMENT_PROGRAM_BRUSH_TEXTURE,
- FRAGMENT_PROGRAM_BRUSH_PATTERN
-};
-
-enum FragmentCompositionModeType {
- COMPOSITION_MODES_SIMPLE_PORTER_DUFF,
- COMPOSITION_MODES_MULTIPLY,
- COMPOSITION_MODES_SCREEN,
- COMPOSITION_MODES_OVERLAY,
- COMPOSITION_MODES_DARKEN,
- COMPOSITION_MODES_LIGHTEN,
- COMPOSITION_MODES_COLORDODGE,
- COMPOSITION_MODES_COLORBURN,
- COMPOSITION_MODES_HARDLIGHT,
- COMPOSITION_MODES_SOFTLIGHT,
- COMPOSITION_MODES_DIFFERENCE,
- COMPOSITION_MODES_EXCLUSION,
- COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK,
- COMPOSITION_MODES_MULTIPLY_NOMASK,
- COMPOSITION_MODES_SCREEN_NOMASK,
- COMPOSITION_MODES_OVERLAY_NOMASK,
- COMPOSITION_MODES_DARKEN_NOMASK,
- COMPOSITION_MODES_LIGHTEN_NOMASK,
- COMPOSITION_MODES_COLORDODGE_NOMASK,
- COMPOSITION_MODES_COLORBURN_NOMASK,
- COMPOSITION_MODES_HARDLIGHT_NOMASK,
- COMPOSITION_MODES_SOFTLIGHT_NOMASK,
- COMPOSITION_MODES_DIFFERENCE_NOMASK,
- COMPOSITION_MODES_EXCLUSION_NOMASK,
- COMPOSITION_MODE_BLEND_MODE_MASK,
- COMPOSITION_MODE_BLEND_MODE_NOMASK
-};
-
-enum FragmentMaskType {
- FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA,
- FRAGMENT_PROGRAM_MASK_ELLIPSE_AA
-};
-
-static const unsigned int num_fragment_variables = 19;
-
-static const unsigned int num_fragment_brushes = 6;
-static const unsigned int num_fragment_composition_modes = 26;
-static const unsigned int num_fragment_masks = 2;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA =
- "!!ARBfp1.0\n"
- "PARAM c[1] = { { 0.5, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "ADD R3.z, fragment.position.x, c[0].x;\n"
- "ADD R0.y, fragment.position, -c[0].x;\n"
- "MAX R4.x, fragment.texcoord[0].y, R0.y;\n"
- "ADD R0.x, fragment.position.y, c[0];\n"
- "MIN R3.w, R0.x, fragment.texcoord[0].x;\n"
- "ADD R2.z, fragment.position.x, -c[0].x;\n"
- "MOV R2.w, R3.z;\n"
- "MOV R0.yw, R4.x;\n"
- "MOV R0.xz, R3.w;\n"
- "MAD R0, fragment.texcoord[1].xxzz, R0, fragment.texcoord[1].yyww;\n"
- "MAD R0.zw, fragment.position.x, c[0].y, -R0;\n"
- "MOV R2.x, R0;\n"
- "MOV R2.y, R0.z;\n"
- "MOV R1.w, R0;\n"
- "MOV R1.z, R0.y;\n"
- "MIN R1.xy, R2, R1.zwzw;\n"
- "SGE R0.xy, R1.zwzw, R2;\n"
- "ADD R0.zw, -fragment.texcoord[0], -fragment.texcoord[0];\n"
- "MAD R3.xy, R0, R0.zwzw, fragment.texcoord[0].zwzw;\n"
- "ADD R0, -R1.xxyy, R2.zwzw;\n"
- "MAD R0, R0, R3.xxyy, R4.x;\n"
- "ADD R3.xy, R0.ywzw, R0.xzzw;\n"
- "ADD R4.zw, R3.w, -R0.xyxz;\n"
- "ADD R0.zw, -R4.x, R0.xyyw;\n"
- "ADD R0.xy, R3.z, -R1;\n"
- "MAX R1.zw, R2.xyxy, R1;\n"
- "MUL R0.xy, R0, R0.zwzw;\n"
- "MAD R3.xy, -R3, c[0].x, R3.w;\n"
- "ADD R2.w, R3.z, -R2.z;\n"
- "MUL R2.xy, R3, R2.w;\n"
- "ADD R2.w, R3, -R4.x;\n"
- "ADD R3.xy, -R2.z, R1.zwzw;\n"
- "MUL R3.xy, R4.zwzw, R3;\n"
- "ADD R4.zw, R1.xyxy, R1;\n"
- "MAD R0.zw, R4, c[0].x, -R2.z;\n"
- "MAD R0.xy, -R0, c[0].x, R2.w;\n"
- "MAD R4.zw, R0, R2.w, -R0.xyxy;\n"
- "SGE R0.zw, R3.z, R1;\n"
- "MAD R0.xy, R0.zwzw, R4.zwzw, R0;\n"
- "MAD R3.xy, R3, c[0].x, -R2;\n"
- "MAD R0.zw, R0, R3.xyxy, R2.xyxy;\n"
- "ADD R2.xy, R0.zwzw, -R0;\n"
- "SGE R0.zw, R2.z, R1.xyxy;\n"
- "MAD R0.xy, R0.zwzw, R2, R0;\n"
- "SGE R0.zw, R1, R2.z;\n"
- "ADD R0.xy, R0, -R2.w;\n"
- "SGE R1.xy, R3.z, R1;\n"
- "MAD R0.xy, R1, R0, R2.w;\n"
- "MAD R0.x, -R0, R0.z, R2.w;\n"
- "SGE R0.z, R3.w, R4.x;\n"
- "MAD R0.x, -R0.y, R0.w, R0;\n"
- "MUL result.color, R0.x, R0.z;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_MASK_ELLIPSE_AA =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..3],\n"
- " { -2, 1, -0.5, 2 },\n"
- " { 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "ADD R0.xy, fragment.position, c[3];\n"
- "MUL R1.xyz, R0.y, c[1];\n"
- "MAD R0.xyz, R0.x, c[0], R1;\n"
- "ADD R0.xyz, R0, c[2];\n"
- "RCP R2.z, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R2.z;\n"
- "MUL R2.xy, R0.zwzw, fragment.texcoord[0];\n"
- "MOV R1.xy, c[0];\n"
- "MOV R1.zw, c[1].xyxy;\n"
- "MOV R0.x, c[0].z;\n"
- "MOV R0.y, c[1].z;\n"
- "MAD R0, R0.zzww, -R0.xyxy, R1.xzyw;\n"
- "MUL R1.xy, R2, fragment.texcoord[0];\n"
- "MUL R0, R2.z, R0;\n"
- "MUL R1.xy, R1, c[4].x;\n"
- "MUL R1.zw, R1.xyxy, R0.xyxz;\n"
- "MUL R0.zw, R1.xyxy, R0.xyyw;\n"
- "ADD R0.y, R0.z, R0.w;\n"
- "ADD R0.x, R1.z, R1.w;\n"
- "MUL R0.xy, R0, R0;\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, R2.xyxy, R2.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "ADD R0.y, -R0.z, c[4];\n"
- "RSQ R0.x, R0.x;\n"
- "MAD_SAT R0.x, R0, R0.y, -c[4].z;\n"
- "MUL R0.y, -R0.x, c[4].w;\n"
- "ADD R0.y, R0, c[5].x;\n"
- "MUL R0.x, R0, R0;\n"
- "MUL result.color, R0.x, R0.y;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SIMPLE_PORTER_DUFF =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xy, fragment.position, c[3];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.xyz, R0, c[0].y;\n"
- "MUL R2.xyz, fragment.color.primary.w, R1;\n"
- "MUL R1.xyz, fragment.color.primary, c[0].x;\n"
- "MAD R2.xyz, R0.w, R1, R2;\n"
- "ADD R3.xy, fragment.position, c[4];\n"
- "ADD R1.w, -R0, c[6].x;\n"
- "MUL R1.xyz, fragment.color.primary, c[1].y;\n"
- "MAD R2.xyz, R1.w, R1, R2;\n"
- "MUL R1.xyz, R0, c[1].z;\n"
- "ADD R2.w, -fragment.color.primary, c[6].x;\n"
- "MAD R2.xyz, R2.w, R1, R2;\n"
- "MUL R1.z, R0.w, R2.w;\n"
- "MUL R1.x, fragment.color.primary.w, R0.w;\n"
- "MUL R1.y, fragment.color.primary.w, R1.w;\n"
- "DP3 R2.w, R1, c[1];\n"
- "MUL R3.xy, R3, c[2];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[5];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_MULTIPLY =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -R0.w, c[4];\n"
- "MUL R1.xyz, fragment.color.primary, R1.x;\n"
- "MAD R1.xyz, fragment.color.primary, R0, R1;\n"
- "ADD R1.w, -fragment.color.primary, c[4].x;\n"
- "MAD R2.xyz, R0, R1.w, R1;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SCREEN =
- "!!ARBfp1.0\n"
- "PARAM c[4] = { program.local[0..3] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "ADD R2, fragment.color.primary, R0;\n"
- "MUL R1.xy, R1, c[0];\n"
- "MAD R2, -fragment.color.primary, R0, R2;\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_OVERLAY =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R1, R0, texture[0], 2D;\n"
- "ADD R0.w, -R1, c[4].y;\n"
- "MUL R3.xyz, fragment.color.primary, R0.w;\n"
- "ADD R2.xyz, fragment.color.primary.w, -fragment.color.primary;\n"
- "ADD R0.xyz, R1.w, -R1;\n"
- "MUL R0.xyz, R0, R2;\n"
- "MUL R0.xyz, R0, c[4].x;\n"
- "MAD R0.xyz, fragment.color.primary.w, R1.w, -R0;\n"
- "MAD R0.xyz, fragment.color.primary, R0.w, R0;\n"
- "MUL R2.xyz, fragment.color.primary, R1;\n"
- "MAD R2.xyz, R2, c[4].x, R3;\n"
- "ADD R0.w, -fragment.color.primary, c[4].y;\n"
- "MAD R3.xyz, R1, R0.w, R0;\n"
- "MAD R2.xyz, R1, R0.w, R2;\n"
- "MUL R0.xyz, R1, c[4].x;\n"
- "SGE R0.xyz, R0, R1.w;\n"
- "ADD R3.xyz, R3, -R2;\n"
- "MAD R2.xyz, R0, R3, R2;\n"
- "ADD R0.z, fragment.color.primary.w, R1.w;\n"
- "MAD R2.w, -fragment.color.primary, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[2];\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[3];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DARKEN =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R2.xyz, fragment.color.primary.w, R0;\n"
- "MUL R1.xyz, fragment.color.primary, R0.w;\n"
- "MIN R1.xyz, R1, R2;\n"
- "ADD R1.w, -R0, c[4].x;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "ADD R1.w, -fragment.color.primary, c[4].x;\n"
- "MAD R2.xyz, R0, R1.w, R1;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_LIGHTEN =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R2.xyz, fragment.color.primary.w, R0;\n"
- "MUL R1.xyz, fragment.color.primary, R0.w;\n"
- "MAX R1.xyz, R1, R2;\n"
- "ADD R1.w, -R0, c[4].x;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "ADD R1.w, -fragment.color.primary, c[4].x;\n"
- "MAD R2.xyz, R0, R1.w, R1;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORDODGE =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -fragment.color.primary.w, c[4];\n"
- "MAX R1.y, fragment.color.primary.w, c[4];\n"
- "MUL R2.xyz, R0, R1.x;\n"
- "ADD R1.w, -R0, c[4].x;\n"
- "MAD R3.xyz, fragment.color.primary, R1.w, R2;\n"
- "RCP R1.y, R1.y;\n"
- "MAD R1.xyz, -fragment.color.primary, R1.y, c[4].x;\n"
- "MAX R1.xyz, R1, c[4].y;\n"
- "MUL R2.xyz, fragment.color.primary.w, R0;\n"
- "MUL R1.w, fragment.color.primary, R0;\n"
- "RCP R1.x, R1.x;\n"
- "RCP R1.y, R1.y;\n"
- "RCP R1.z, R1.z;\n"
- "MAD R1.xyz, R2, R1, R3;\n"
- "MAD R3.xyz, fragment.color.primary.w, R0.w, R3;\n"
- "MAD R2.xyz, fragment.color.primary, R0.w, R2;\n"
- "ADD R3.xyz, R3, -R1;\n"
- "SGE R2.xyz, R2, R1.w;\n"
- "MAD R2.xyz, R2, R3, R1;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORBURN =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.w, -R0, c[4].x;\n"
- "MUL R1.xyz, fragment.color.primary.w, R0;\n"
- "MAD R2.xyz, fragment.color.primary, R0.w, R1;\n"
- "MAD R1.xyz, -fragment.color.primary.w, R0.w, R2;\n"
- "MUL R3.xyz, fragment.color.primary.w, R1;\n"
- "MAX R1.xyz, fragment.color.primary, c[4].y;\n"
- "ADD R2.w, -fragment.color.primary, c[4].x;\n"
- "MUL R4.xyz, fragment.color.primary, R1.w;\n"
- "RCP R1.x, R1.x;\n"
- "RCP R1.y, R1.y;\n"
- "RCP R1.z, R1.z;\n"
- "MAD R3.xyz, R3, R1, R4;\n"
- "MUL R1.xyz, R0, R2.w;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "MAD R3.xyz, R0, R2.w, R3;\n"
- "MUL R1.w, fragment.color.primary, R0;\n"
- "ADD R3.xyz, R3, -R1;\n"
- "SGE R2.xyz, R2, R1.w;\n"
- "MAD R2.xyz, R2, R3, R1;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_HARDLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R1, R0, texture[0], 2D;\n"
- "ADD R0.w, -R1, c[4].y;\n"
- "MUL R3.xyz, fragment.color.primary, R0.w;\n"
- "ADD R2.xyz, fragment.color.primary.w, -fragment.color.primary;\n"
- "ADD R0.xyz, R1.w, -R1;\n"
- "MUL R0.xyz, R0, R2;\n"
- "MUL R0.xyz, R0, c[4].x;\n"
- "MAD R0.xyz, fragment.color.primary.w, R1.w, -R0;\n"
- "MAD R0.xyz, fragment.color.primary, R0.w, R0;\n"
- "MUL R2.xyz, fragment.color.primary, R1;\n"
- "MAD R2.xyz, R2, c[4].x, R3;\n"
- "ADD R0.w, -fragment.color.primary, c[4].y;\n"
- "MAD R3.xyz, R1, R0.w, R0;\n"
- "MAD R2.xyz, R1, R0.w, R2;\n"
- "MUL R0.xyz, fragment.color.primary, c[4].x;\n"
- "SGE R0.xyz, R0, fragment.color.primary.w;\n"
- "ADD R3.xyz, R3, -R2;\n"
- "MAD R2.xyz, R0, R3, R2;\n"
- "ADD R0.z, fragment.color.primary.w, R1.w;\n"
- "MAD R2.w, -fragment.color.primary, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[2];\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[3];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SOFTLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..3],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MAX R1.x, R0.w, c[4].z;\n"
- "RCP R1.x, R1.x;\n"
- "MUL R2.xyz, R0, R1.x;\n"
- "MAD R1.xyz, R2, c[5].x, -c[5].y;\n"
- "MAD R3.xyz, R2, R1, c[5].z;\n"
- "MAD R1.xyz, fragment.color.primary, c[4].y, -fragment.color.primary.w;\n"
- "MUL R4.xyz, R0.w, R1;\n"
- "MUL R5.xyz, R4, R3;\n"
- "RSQ R1.w, R2.x;\n"
- "RSQ R2.w, R2.z;\n"
- "RCP R3.x, R1.w;\n"
- "RSQ R1.w, R2.y;\n"
- "MUL R5.xyz, R2, R5;\n"
- "RCP R3.z, R2.w;\n"
- "RCP R3.y, R1.w;\n"
- "ADD R3.xyz, -R2, R3;\n"
- "MUL R3.xyz, R4, R3;\n"
- "ADD R2.xyz, -R2, c[4].x;\n"
- "MAD R1.xyz, R1, R2, fragment.color.primary.w;\n"
- "MUL R2.xyz, fragment.color.primary, c[4].y;\n"
- "MAD R4.xyz, fragment.color.primary.w, R0, R5;\n"
- "MAD R3.xyz, fragment.color.primary.w, R0, R3;\n"
- "ADD R5.xyz, R3, -R4;\n"
- "MUL R3.xyz, R0, c[4].w;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MAD R3.xyz, R3, R5, R4;\n"
- "MAD R3.xyz, -R0, R1, R3;\n"
- "MUL R1.xyz, R0, R1;\n"
- "SGE R2.xyz, R2, fragment.color.primary.w;\n"
- "MAD R2.xyz, R2, R3, R1;\n"
- "ADD R1.x, -R0.w, c[4];\n"
- "MAD R2.xyz, fragment.color.primary, R1.x, R2;\n"
- "ADD R1.x, -fragment.color.primary.w, c[4];\n"
- "MAD R2.xyz, R0, R1.x, R2;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DIFFERENCE =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.xyz, fragment.color.primary, R0;\n"
- "MUL R3.xyz, fragment.color.primary.w, R0;\n"
- "MUL R2.xyz, fragment.color.primary, R0.w;\n"
- "MIN R2.xyz, R2, R3;\n"
- "MAD R2.xyz, -R2, c[4].x, R1;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_EXCLUSION =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[1];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.xyz, fragment.color.primary.w, R0;\n"
- "MAD R2.xyz, fragment.color.primary, R0.w, R1;\n"
- "MUL R1.xyz, fragment.color.primary, R0;\n"
- "MAD R1.xyz, -R1, c[4].x, R2;\n"
- "ADD R1.w, -R0, c[4].y;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "ADD R1.w, -fragment.color.primary, c[4].y;\n"
- "MAD R2.xyz, R0, R1.w, R1;\n"
- "ADD R1.z, fragment.color.primary.w, R0.w;\n"
- "MAD R2.w, -fragment.color.primary, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[2];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[3];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[4] = { program.local[0..2],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[2];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.xyz, R0, c[0].y;\n"
- "MUL R2.xyz, fragment.color.primary.w, R1;\n"
- "MUL R1.xyz, fragment.color.primary, c[0].x;\n"
- "MAD R2.xyz, R0.w, R1, R2;\n"
- "MUL R0.xyz, R0, c[1].z;\n"
- "ADD R1.w, -R0, c[3].x;\n"
- "MUL R1.xyz, fragment.color.primary, c[1].y;\n"
- "MAD R1.xyz, R1.w, R1, R2;\n"
- "ADD R2.x, -fragment.color.primary.w, c[3];\n"
- "MAD result.color.xyz, R2.x, R0, R1;\n"
- "MUL R0.x, fragment.color.primary.w, R0.w;\n"
- "MUL R0.z, R0.w, R2.x;\n"
- "MUL R0.y, fragment.color.primary.w, R1.w;\n"
- "DP3 result.color.w, R0, c[1];\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_MULTIPLY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -R0.w, c[1];\n"
- "MUL R1.xyz, fragment.color.primary, R1.x;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "MAD R1.xyz, fragment.color.primary, R0, R1;\n"
- "ADD R2.x, -fragment.color.primary.w, c[1];\n"
- "MAD result.color.xyz, R0, R2.x, R1;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SCREEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[1] = { program.local[0] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1, fragment.color.primary, R0;\n"
- "MAD result.color, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_OVERLAY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.w, -R0, c[1].y;\n"
- "ADD R2.xyz, fragment.color.primary.w, -fragment.color.primary;\n"
- "ADD R1.xyz, R0.w, -R0;\n"
- "MUL R1.xyz, R1, R2;\n"
- "MUL R1.xyz, R1, c[1].x;\n"
- "MAD R1.xyz, fragment.color.primary.w, R0.w, -R1;\n"
- "MUL R3.xyz, fragment.color.primary, R1.w;\n"
- "MUL R2.xyz, fragment.color.primary, R0;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "ADD R1.w, -fragment.color.primary, c[1].y;\n"
- "MAD R2.xyz, R2, c[1].x, R3;\n"
- "MAD R2.xyz, R0, R1.w, R2;\n"
- "MAD R1.xyz, R0, R1.w, R1;\n"
- "MUL R0.xyz, R0, c[1].x;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "ADD R1.xyz, R1, -R2;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD result.color.xyz, R0, R1, R2;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DARKEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R2.xyz, fragment.color.primary.w, R0;\n"
- "MUL R1.xyz, fragment.color.primary, R0.w;\n"
- "MIN R1.xyz, R1, R2;\n"
- "ADD R1.w, -R0, c[1].x;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "ADD R2.x, -fragment.color.primary.w, c[1];\n"
- "MAD result.color.xyz, R0, R2.x, R1;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_LIGHTEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R2.xyz, fragment.color.primary.w, R0;\n"
- "MUL R1.xyz, fragment.color.primary, R0.w;\n"
- "MAX R1.xyz, R1, R2;\n"
- "ADD R1.w, -R0, c[1].x;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "ADD R2.x, -fragment.color.primary.w, c[1];\n"
- "MAD result.color.xyz, R0, R2.x, R1;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORDODGE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MAX R1.y, fragment.color.primary.w, c[1];\n"
- "RCP R2.x, R1.y;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -fragment.color.primary.w, c[1];\n"
- "MUL R1.xyz, R0, R1.x;\n"
- "ADD R1.w, -R0, c[1].x;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "MAD R2.xyz, -fragment.color.primary, R2.x, c[1].x;\n"
- "MAX R2.xyz, R2, c[1].y;\n"
- "MUL R0.xyz, fragment.color.primary.w, R0;\n"
- "MUL R1.w, fragment.color.primary, R0;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R0, R2, R1;\n"
- "MAD R1.xyz, fragment.color.primary.w, R0.w, R1;\n"
- "MAD R0.xyz, fragment.color.primary, R0.w, R0;\n"
- "SGE R0.xyz, R0, R1.w;\n"
- "ADD R1.xyz, R1, -R2;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "MAD result.color.xyz, R0, R1, R2;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORBURN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.xyz, fragment.color.primary.w, R0;\n"
- "MAD R2.xyz, fragment.color.primary, R0.w, R1;\n"
- "MAD R1.xyz, -fragment.color.primary.w, R0.w, R2;\n"
- "MUL R3.xyz, fragment.color.primary.w, R1;\n"
- "MAX R1.xyz, fragment.color.primary, c[1].y;\n"
- "ADD R1.w, -R0, c[1].x;\n"
- "MUL R4.xyz, fragment.color.primary, R1.w;\n"
- "ADD R2.w, -fragment.color.primary, c[1].x;\n"
- "RCP R1.x, R1.x;\n"
- "RCP R1.y, R1.y;\n"
- "RCP R1.z, R1.z;\n"
- "MAD R1.xyz, R3, R1, R4;\n"
- "MUL R3.xyz, R0, R2.w;\n"
- "MAD R0.xyz, R0, R2.w, R1;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R3;\n"
- "MUL R1.w, fragment.color.primary, R0;\n"
- "SGE R2.xyz, R2, R1.w;\n"
- "ADD R0.xyz, R0, -R1;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "MAD result.color.xyz, R2, R0, R1;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_HARDLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.w, -R0, c[1].y;\n"
- "ADD R2.xyz, fragment.color.primary.w, -fragment.color.primary;\n"
- "ADD R1.xyz, R0.w, -R0;\n"
- "MUL R1.xyz, R1, R2;\n"
- "MUL R1.xyz, R1, c[1].x;\n"
- "MAD R1.xyz, fragment.color.primary.w, R0.w, -R1;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "MUL R3.xyz, fragment.color.primary, R1.w;\n"
- "MUL R2.xyz, fragment.color.primary, R0;\n"
- "ADD R1.w, -fragment.color.primary, c[1].y;\n"
- "MAD R2.xyz, R2, c[1].x, R3;\n"
- "MAD R2.xyz, R0, R1.w, R2;\n"
- "MAD R0.xyz, R0, R1.w, R1;\n"
- "ADD R1.xyz, R0, -R2;\n"
- "MUL R0.xyz, fragment.color.primary, c[1].x;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "SGE R0.xyz, R0, fragment.color.primary.w;\n"
- "MAD result.color.xyz, R0, R1, R2;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SOFTLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[3] = { program.local[0],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MAX R1.x, R0.w, c[1].z;\n"
- "RCP R1.x, R1.x;\n"
- "MUL R2.xyz, R0, R1.x;\n"
- "MAD R1.xyz, R2, c[2].x, -c[2].y;\n"
- "MAD R3.xyz, R2, R1, c[2].z;\n"
- "MAD R1.xyz, fragment.color.primary, c[1].y, -fragment.color.primary.w;\n"
- "MUL R4.xyz, R0.w, R1;\n"
- "MUL R5.xyz, R4, R3;\n"
- "RSQ R1.w, R2.x;\n"
- "RCP R3.x, R1.w;\n"
- "RSQ R2.w, R2.z;\n"
- "RSQ R1.w, R2.y;\n"
- "MUL R5.xyz, R2, R5;\n"
- "RCP R3.z, R2.w;\n"
- "RCP R3.y, R1.w;\n"
- "ADD R3.xyz, -R2, R3;\n"
- "MUL R3.xyz, R4, R3;\n"
- "ADD R2.xyz, -R2, c[1].x;\n"
- "MAD R1.xyz, R1, R2, fragment.color.primary.w;\n"
- "MUL R2.xyz, fragment.color.primary, c[1].y;\n"
- "MAD R4.xyz, fragment.color.primary.w, R0, R5;\n"
- "MAD R3.xyz, fragment.color.primary.w, R0, R3;\n"
- "ADD R5.xyz, R3, -R4;\n"
- "MUL R3.xyz, R0, c[1].w;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MAD R3.xyz, R3, R5, R4;\n"
- "MAD R3.xyz, -R0, R1, R3;\n"
- "MUL R1.xyz, R0, R1;\n"
- "SGE R2.xyz, R2, fragment.color.primary.w;\n"
- "MAD R2.xyz, R2, R3, R1;\n"
- "ADD R1.x, -R0.w, c[1];\n"
- "MAD R2.xyz, fragment.color.primary, R1.x, R2;\n"
- "ADD R1.x, fragment.color.primary.w, R0.w;\n"
- "ADD R1.y, -fragment.color.primary.w, c[1].x;\n"
- "MAD result.color.xyz, R0, R1.y, R2;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DIFFERENCE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R2.xyz, fragment.color.primary.w, R0;\n"
- "MUL R1.xyz, fragment.color.primary, R0.w;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "MIN R1.xyz, R1, R2;\n"
- "ADD R0.xyz, fragment.color.primary, R0;\n"
- "MAD result.color.xyz, -R1, c[1].x, R0;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_EXCLUSION_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[2] = { program.local[0],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xy, fragment.position, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.xyz, fragment.color.primary.w, R0;\n"
- "MAD R2.xyz, fragment.color.primary, R0.w, R1;\n"
- "MUL R1.xyz, fragment.color.primary, R0;\n"
- "MAD R1.xyz, -R1, c[1].x, R2;\n"
- "ADD R1.w, -R0, c[1].y;\n"
- "MAD R1.xyz, fragment.color.primary, R1.w, R1;\n"
- "ADD R1.w, fragment.color.primary, R0;\n"
- "ADD R2.x, -fragment.color.primary.w, c[1].y;\n"
- "MAD result.color.xyz, R0, R2.x, R1;\n"
- "MAD result.color.w, -fragment.color.primary, R0, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODE_BLEND_MODE_MASK =
- "!!ARBfp1.0\n"
- "PARAM c[3] = { program.local[0..2] };\n"
- "TEMP R0;\n"
- "ADD R0.xy, fragment.position, c[1];\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "DP4 R0.x, R0, c[2];\n"
- "MUL result.color, fragment.color.primary, R0.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODE_BLEND_MODE_NOMASK =
- "!!ARBfp1.0\n"
- "MOV result.color, fragment.color.primary;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF =
- "!!ARBfp1.0\n"
- "PARAM c[12] = { program.local[0..10],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[11].x;\n"
- "MUL R0.z, R0, c[11].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.x, R0.x;\n"
- "RCP R0.z, R0.x;\n"
- "ADD R1.x, -R0.y, R0.z;\n"
- "MOV R0.x, c[11];\n"
- "MUL R0.z, R0.x, c[1].x;\n"
- "RCP R1.y, R0.z;\n"
- "MUL R0.xy, fragment.position, c[8];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.x, R1, R1.y;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R2.xyz, R0, c[5].y;\n"
- "MUL R3.xyz, R1.w, R2;\n"
- "MUL R2.xyz, R1, c[5].x;\n"
- "MAD R2.xyz, R0.w, R2, R3;\n"
- "ADD R3.xy, fragment.position, c[9];\n"
- "ADD R2.w, -R0, c[11].z;\n"
- "MUL R1.xyz, R1, c[6].y;\n"
- "MAD R2.xyz, R2.w, R1, R2;\n"
- "MUL R1.xyz, R0, c[6].z;\n"
- "ADD R3.z, -R1.w, c[11];\n"
- "MAD R2.xyz, R3.z, R1, R2;\n"
- "MUL R1.y, R1.w, R2.w;\n"
- "MUL R1.x, R1.w, R0.w;\n"
- "MUL R1.z, R0.w, R3;\n"
- "DP3 R2.w, R1, c[6];\n"
- "MUL R3.xy, R3, c[7];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[10];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_MULTIPLY =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.x, R0.x;\n"
- "RCP R0.z, R0.x;\n"
- "ADD R1.x, -R0.y, R0.z;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.z, R0.x, c[1].x;\n"
- "RCP R1.y, R0.z;\n"
- "MUL R0.xy, fragment.position, c[6];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.x, R1, R1.y;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "ADD R2.x, -R0.w, c[9].z;\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "MAD R1.xyz, R1, R0, R2;\n"
- "ADD R2.x, -R1.w, c[9].z;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[7];\n"
- "MUL R1.xy, R1, c[5];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[8];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SCREEN =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.z, R0.y, R0.y, -R0;\n"
- "ADD R3.xy, fragment.position, c[7];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RSQ R0.z, R0.z;\n"
- "RCP R0.x, R0.z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0.y, R0;\n"
- "MUL R0.z, R0.x, R0;\n"
- "TEX R1, R0.z, texture[2], 1D;\n"
- "MUL R0.xy, fragment.position, c[6];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R2, R1, R0;\n"
- "MAD R2, -R1, R0, R2;\n"
- "MUL R3.xy, R3, c[5];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[8];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_OVERLAY =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.z, R0.y, R0.y, -R0;\n"
- "MUL R1.xy, fragment.position, c[6];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RSQ R0.z, R0.z;\n"
- "RCP R0.x, R0.z;\n"
- "ADD R2.w, -R1, c[9].z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0.y, R0;\n"
- "MUL R0.x, R0, R0.z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[9].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, -R0.w, c[9].z;\n"
- "MAD R3.xyz, R3, c[9].x, R4;\n"
- "MAD R3.xyz, R1, R2.x, R3;\n"
- "MAD R0.xyz, R1, R2.x, R0;\n"
- "MUL R2.xyz, R1, c[9].x;\n"
- "ADD R0.xyz, R0, -R3;\n"
- "SGE R2.xyz, R2, R1.w;\n"
- "MAD R2.xyz, R2, R0, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[7];\n"
- "MUL R0.xy, R0, c[5];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[8];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DARKEN =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.x, R0, c[1];\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.z, -R0.y, R0;\n"
- "RCP R0.w, R0.x;\n"
- "MUL R1.x, R0.z, R0.w;\n"
- "MUL R0.xy, fragment.position, c[6];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[9].z;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[9].z;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[7];\n"
- "MUL R1.xy, R1, c[5];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[8];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_LIGHTEN =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.x, R0, c[1];\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.z, -R0.y, R0;\n"
- "RCP R0.w, R0.x;\n"
- "MUL R1.x, R0.z, R0.w;\n"
- "MUL R0.xy, fragment.position, c[6];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[9].z;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[9].z;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[7];\n"
- "MUL R1.xy, R1, c[5];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[8];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORDODGE =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.z, R0.y, R0.y, -R0;\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RSQ R0.z, R0.z;\n"
- "RCP R0.x, R0.z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0.y, R0;\n"
- "MUL R0.x, R0, R0.z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MAX R1.x, R0.w, c[9].w;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R1.xyz, -R0, R1.x, c[9].z;\n"
- "MAX R2.xyz, R1, c[9].w;\n"
- "MUL R1.xy, fragment.position, c[6];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[9].z;\n"
- "MUL R3.xyz, R1, R2.w;\n"
- "ADD R2.w, -R1, c[9].z;\n"
- "MAD R4.xyz, R0, R2.w, R3;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R0.xyz, R0, R1.w, R3;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R3, R2, R4;\n"
- "MAD R4.xyz, R0.w, R1.w, R4;\n"
- "ADD R4.xyz, R4, -R2;\n"
- "MAD R2.xyz, R0, R4, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[7];\n"
- "MUL R0.xy, R0, c[5];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[8];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORBURN =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.x, -R0.y, R0.z;\n"
- "RCP R0.y, R0.w;\n"
- "MUL R0.zw, fragment.position.xyxy, c[6].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, R0.y;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[9].w;\n"
- "ADD R2.w, -R1, c[9].z;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "ADD R3.w, -R0, c[9].z;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R2.xyz, R1, R3.w, R2;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R3.xyz, R3, R2.w;\n"
- "MAD R2.xyz, R3, R2, R0;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[7];\n"
- "MUL R0.xy, R0, c[5];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[8];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_HARDLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.z, R0.y, R0.y, -R0;\n"
- "MUL R1.xy, fragment.position, c[6];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RSQ R0.z, R0.z;\n"
- "RCP R0.x, R0.z;\n"
- "ADD R2.w, -R1, c[9].z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0.y, R0;\n"
- "MUL R0.x, R0, R0.z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[9].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[9].z;\n"
- "MAD R3.xyz, R3, c[9].x, R4;\n"
- "MUL R0.xyz, R0, c[9].x;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD R3.xyz, R1, R2.w, R3;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "MAD R2.xyz, R0, R2, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[7];\n"
- "MUL R0.xy, R0, c[5];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[8];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SOFTLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..8],\n"
- " { 2, 4, 1, 9.9999997e-006 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.z, c[9];\n"
- "MUL R0.x, R0, c[9];\n"
- "MUL R0.zw, fragment.position.xyxy, c[6].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MAD R0.y, R0.x, R0.x, -R0;\n"
- "RSQ R0.y, R0.y;\n"
- "RCP R0.y, R0.y;\n"
- "ADD R0.y, -R0.x, R0;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.x, R0, c[1];\n"
- "MAX R0.z, R1.w, c[9].w;\n"
- "RCP R0.z, R0.z;\n"
- "MUL R3.xyz, R1, R0.z;\n"
- "MAD R4.xyz, R3, c[10].x, -c[10].y;\n"
- "RCP R0.x, R0.x;\n"
- "MUL R0.x, R0.y, R0;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MAD R2.xyz, R0, c[9].x, -R0.w;\n"
- "MAD R4.xyz, R3, R4, c[10].z;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[9].z;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[9].x;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[9].y;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MUL R2.xyz, R1, R2;\n"
- "ADD R2.w, -R1, c[9].z;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, -R0.w, c[9].z;\n"
- "MAD R2.xyz, R1, R0.x, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[7];\n"
- "MUL R0.xy, R0, c[5];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[8];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DIFFERENCE =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.x, R0, c[1];\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.z, -R0.y, R0;\n"
- "RCP R0.w, R0.x;\n"
- "MUL R1.x, R0.z, R0.w;\n"
- "MUL R0.xy, fragment.position, c[6];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "ADD R2.xyz, R1, R0;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R1.xyz, R1, R0.w;\n"
- "MIN R1.xyz, R1, R3;\n"
- "MAD R2.xyz, -R1, c[9].x, R2;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[7];\n"
- "MUL R1.xy, R1, c[5];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[8];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_EXCLUSION =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..8],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[9].x;\n"
- "MUL R0.z, R0, c[9].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[9];\n"
- "MUL R0.x, R0, c[1];\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.z, -R0.y, R0;\n"
- "RCP R0.w, R0.x;\n"
- "MUL R1.x, R0.z, R0.w;\n"
- "MUL R0.xy, fragment.position, c[6];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "MUL R2.xyz, R1, R0;\n"
- "MAD R2.xyz, -R2, c[9].x, R3;\n"
- "ADD R2.w, -R0, c[9].z;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[9].z;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[7];\n"
- "MUL R1.xy, R1, c[5];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[8];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[8].x;\n"
- "MUL R0.z, R0, c[8].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.x, R0.x;\n"
- "RCP R0.z, R0.x;\n"
- "ADD R0.y, -R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[7].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R2.xyz, R1, c[5].y;\n"
- "MOV R0.x, c[8];\n"
- "MUL R0.x, R0, c[1];\n"
- "RCP R0.x, R0.x;\n"
- "MUL R0.x, R0.y, R0;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R3.xyz, R0.w, R2;\n"
- "MUL R2.xyz, R0, c[5].x;\n"
- "MAD R2.xyz, R1.w, R2, R3;\n"
- "ADD R2.w, -R1, c[8].z;\n"
- "MUL R0.xyz, R0, c[6].y;\n"
- "MAD R0.xyz, R2.w, R0, R2;\n"
- "ADD R2.x, -R0.w, c[8].z;\n"
- "MUL R1.xyz, R1, c[6].z;\n"
- "MAD result.color.xyz, R2.x, R1, R0;\n"
- "MUL R0.x, R0.w, R1.w;\n"
- "MUL R0.z, R1.w, R2.x;\n"
- "MUL R0.y, R0.w, R2.w;\n"
- "DP3 result.color.w, R0, c[6];\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_MULTIPLY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.x, R0.x;\n"
- "RCP R0.z, R0.x;\n"
- "ADD R0.y, -R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.x, R0, c[1];\n"
- "RCP R0.x, R0.x;\n"
- "MUL R0.x, R0.y, R0;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R2.x, -R1.w, c[6].z;\n"
- "MUL R2.xyz, R0, R2.x;\n"
- "MAD R0.xyz, R0, R1, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[6].z;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SCREEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.x, -R0.y, R0.z;\n"
- "RCP R0.y, R0.w;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R2, R0, R1;\n"
- "MAD result.color, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_OVERLAY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.z, R0.y, R0.y, -R0;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RSQ R0.z, R0.z;\n"
- "RCP R0.x, R0.z;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0.y, R0;\n"
- "MUL R0.x, R0, R0.z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[6].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R2.w;\n"
- "MUL R0.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[6].z;\n"
- "MAD R0.xyz, R0, c[6].x, R3;\n"
- "MAD R0.xyz, R1, R2.w, R0;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R1.xyz, R1, c[6].x;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R1.xyz, R1, R1.w;\n"
- "MAD result.color.xyz, R1, R2, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DARKEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.x, -R0.y, R0.z;\n"
- "RCP R0.y, R0.w;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[6].z;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_LIGHTEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.x, -R0.y, R0.z;\n"
- "RCP R0.y, R0.w;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[6].z;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORDODGE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.z, R0.y, R0.y, -R0;\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RSQ R0.z, R0.z;\n"
- "RCP R0.x, R0.z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0.y, R0;\n"
- "MUL R0.x, R0, R0.z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MAX R1.x, R0.w, c[6].w;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R1.xyz, -R0, R1.x, c[6].z;\n"
- "MAX R2.xyz, R1, c[6].w;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[6].z;\n"
- "MUL R3.xyz, R1, R2.w;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "MAD R3.xyz, R0, R2.w, R3;\n"
- "MUL R1.xyz, R0.w, R1;\n"
- "MAD R0.xyz, R0, R1.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R1, R2, R3;\n"
- "MAD R3.xyz, R0.w, R1.w, R3;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "ADD R3.xyz, R3, -R2;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "MAD result.color.xyz, R0, R3, R2;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORBURN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.x, -R0.y, R0.z;\n"
- "RCP R0.y, R0.w;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[6].w;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "ADD R3.w, -R0, c[6].z;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R1.xyz, R1, R3.w, R2;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.x, R0.w, R1.w;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R1.xyz, R1, -R0;\n"
- "SGE R2.xyz, R3, R2.x;\n"
- "MAD result.color.xyz, R2, R1, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_HARDLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.z, R0.y, R0.y, -R0;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RSQ R0.z, R0.z;\n"
- "RCP R0.x, R0.z;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0.y, R0;\n"
- "MUL R0.x, R0, R0.z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[6].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R2.w, -R0, c[6].z;\n"
- "MUL R0.xyz, R0, c[6].x;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MAD R3.xyz, R3, c[6].x, R4;\n"
- "MAD R1.xyz, R1, R2.w, R3;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R2.xyz, R2, -R1;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD result.color.xyz, R0, R2, R1;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SOFTLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..5],\n"
- " { 2, 4, 1, 9.9999997e-006 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.z, c[6];\n"
- "MUL R0.x, R0, c[6];\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MAD R0.y, R0.x, R0.x, -R0;\n"
- "RSQ R0.y, R0.y;\n"
- "RCP R0.y, R0.y;\n"
- "ADD R0.y, -R0.x, R0;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.x, R0, c[1];\n"
- "MAX R0.z, R1.w, c[6].w;\n"
- "RCP R0.z, R0.z;\n"
- "MUL R3.xyz, R1, R0.z;\n"
- "MAD R4.xyz, R3, c[7].x, -c[7].y;\n"
- "RCP R0.x, R0.x;\n"
- "MUL R0.x, R0.y, R0;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MAD R2.xyz, R0, c[6].x, -R0.w;\n"
- "MAD R4.xyz, R3, R4, c[7].z;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[6].z;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[6].x;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[6].y;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "MUL R2.xyz, R1, R2;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, R0.w, R1.w;\n"
- "ADD R0.y, -R0.w, c[6].z;\n"
- "MAD result.color.xyz, R1, R0.y, R2;\n"
- "MAD result.color.w, -R0, R1, R0.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DIFFERENCE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.x, -R0.y, R0.z;\n"
- "RCP R0.y, R0.w;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "ADD R0.xyz, R0, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "MAD result.color.xyz, -R2, c[6].x, R0;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_EXCLUSION_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..5],\n"
- " { 2, 4, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.x, c[6].x;\n"
- "MUL R0.z, R0, c[6].y;\n"
- "MAD R0.x, R0.y, R0.y, -R0.z;\n"
- "RSQ R0.z, R0.x;\n"
- "MOV R0.x, c[6];\n"
- "MUL R0.w, R0.x, c[1].x;\n"
- "RCP R0.z, R0.z;\n"
- "ADD R0.x, -R0.y, R0.z;\n"
- "RCP R0.y, R0.w;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MUL R2.xyz, R0, R1;\n"
- "MAD R2.xyz, -R2, c[6].x, R3;\n"
- "ADD R2.w, -R1, c[6].z;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[6].z;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODE_BLEND_MODE_MASK =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 4 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "ADD R0.z, R0, R0.w;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.z, c[8];\n"
- "MUL R0.x, R0, c[8];\n"
- "MAD R0.y, R0.x, R0.x, -R0;\n"
- "RSQ R0.y, R0.y;\n"
- "RCP R0.y, R0.y;\n"
- "ADD R1.x, -R0, R0.y;\n"
- "MOV R0.x, c[8];\n"
- "MUL R0.x, R0, c[1];\n"
- "RCP R1.y, R0.x;\n"
- "ADD R0.zw, fragment.position.xyxy, c[6].xyxy;\n"
- "MUL R0.zw, R0, c[5].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R1.x, R1, R1.y;\n"
- "DP4 R1.y, R0, c[7];\n"
- "TEX R0, R1, texture[1], 1D;\n"
- "MUL result.color, R0, R1.y;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODE_BLEND_MODE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2, 4 } };\n"
- "TEMP R0;\n"
- "MUL R0.xyz, fragment.position.y, c[3];\n"
- "MAD R0.xyz, fragment.position.x, c[2], R0;\n"
- "ADD R0.xyz, R0, c[4];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.xyxy;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.z, R0, R0.w;\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, -R0, c[1].x;\n"
- "MUL R0.y, R0.z, c[5];\n"
- "MUL R0.x, R0, c[5];\n"
- "MAD R0.z, R0.x, R0.x, -R0.y;\n"
- "MOV R0.y, c[5].x;\n"
- "RSQ R0.z, R0.z;\n"
- "MUL R0.w, R0.y, c[1].x;\n"
- "RCP R0.y, R0.z;\n"
- "RCP R0.z, R0.w;\n"
- "ADD R0.x, -R0, R0.y;\n"
- "MUL R0.x, R0, R0.z;\n"
- "TEX result.color, R0, texture[0], 1D;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF =
- "!!ARBfp1.0\n"
- "PARAM c[13] = { program.local[0..9],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[10].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[11].x, c[11].y;\n"
- "MAD R1.z, R1, R1.y, -c[11];\n"
- "MAD R1.z, R1, R1.y, c[11].w;\n"
- "MAD R1.z, R1, R1.y, -c[12].x;\n"
- "MAD R1.y, R1.z, R1, c[12];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[10].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[10].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R1.x, R0, c[10];\n"
- "FLR R1.y, R1.x;\n"
- "MUL R0.xy, fragment.position, c[7];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, R1, -R1.y;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R2.xyz, R0, c[4].y;\n"
- "MUL R3.xyz, R1.w, R2;\n"
- "MUL R2.xyz, R1, c[4].x;\n"
- "MAD R2.xyz, R0.w, R2, R3;\n"
- "ADD R3.xy, fragment.position, c[8];\n"
- "ADD R2.w, -R0, c[12].z;\n"
- "MUL R1.xyz, R1, c[5].y;\n"
- "MAD R2.xyz, R2.w, R1, R2;\n"
- "MUL R1.xyz, R0, c[5].z;\n"
- "ADD R3.z, -R1.w, c[12];\n"
- "MAD R2.xyz, R3.z, R1, R2;\n"
- "MUL R1.y, R1.w, R2.w;\n"
- "MUL R1.x, R1.w, R0.w;\n"
- "MUL R1.z, R0.w, R3;\n"
- "DP3 R2.w, R1, c[5];\n"
- "MUL R3.xy, R3, c[6];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[9];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_MULTIPLY =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[9].x, c[9].y;\n"
- "MAD R1.z, R1, R1.y, -c[9];\n"
- "MAD R1.z, R1, R1.y, c[9].w;\n"
- "MAD R1.z, R1, R1.y, -c[10].x;\n"
- "MAD R1.y, R1.z, R1, c[10];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[8].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[8].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R1.x, R0, c[8];\n"
- "FLR R1.y, R1.x;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, R1, -R1.y;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "ADD R2.x, -R0.w, c[10].z;\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "MAD R1.xyz, R1, R0, R2;\n"
- "ADD R2.x, -R1.w, c[10].z;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SCREEN =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ADD R3.xy, fragment.position, c[6];\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[9].x, c[9].y;\n"
- "MAD R1.z, R1, R1.y, -c[9];\n"
- "MAD R1.z, R1, R1.y, c[9].w;\n"
- "MAD R1.z, R1, R1.y, -c[10].x;\n"
- "MAD R1.y, R1.z, R1, c[10];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[8].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[8].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[8];\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.z, R0.x, -R0.y;\n"
- "TEX R1, R0.z, texture[2], 1D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R2, R1, R0;\n"
- "MAD R2, -R1, R0, R2;\n"
- "MUL R3.xy, R3, c[4];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_OVERLAY =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8];\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[8].y, c[8];\n"
- "MAD R1.z, R1, R1.y, -c[8].w;\n"
- "MAD R1.z, R1, R1.y, c[9].x;\n"
- "MAD R1.z, R1, R1.y, -c[9].y;\n"
- "MAD R1.y, R1.z, R1, c[9].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[9].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[10].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[10].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[10];\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[10].z;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, -R0.w, c[10].w;\n"
- "MAD R3.xyz, R3, c[10].z, R4;\n"
- "MAD R3.xyz, R1, R2.x, R3;\n"
- "MAD R0.xyz, R1, R2.x, R0;\n"
- "MUL R2.xyz, R1, c[10].z;\n"
- "ADD R0.xyz, R0, -R3;\n"
- "SGE R2.xyz, R2, R1.w;\n"
- "MAD R2.xyz, R2, R0, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DARKEN =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[9].x, c[9].y;\n"
- "MAD R1.z, R1, R1.y, -c[9];\n"
- "MAD R1.z, R1, R1.y, c[9].w;\n"
- "MAD R1.z, R1, R1.y, -c[10].x;\n"
- "MAD R1.y, R1.z, R1, c[10];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[8].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[8].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.z, R0.x, c[8].x;\n"
- "FLR R0.w, R0.z;\n"
- "ADD R1.x, R0.z, -R0.w;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[10].z;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[10].z;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_LIGHTEN =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[9].x, c[9].y;\n"
- "MAD R1.z, R1, R1.y, -c[9];\n"
- "MAD R1.z, R1, R1.y, c[9].w;\n"
- "MAD R1.z, R1, R1.y, -c[10].x;\n"
- "MAD R1.y, R1.z, R1, c[10];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[8].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[8].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.z, R0.x, c[8].x;\n"
- "FLR R0.w, R0.z;\n"
- "ADD R1.x, R0.z, -R0.w;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[10].z;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[10].z;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORDODGE =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8];\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[8].y, c[8];\n"
- "MAD R1.z, R1, R1.y, -c[8].w;\n"
- "MAD R1.z, R1, R1.y, c[9].x;\n"
- "MAD R1.z, R1, R1.y, -c[9].y;\n"
- "MAD R1.y, R1.z, R1, c[9].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[9].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[10].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[10].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MAX R1.x, R0.w, c[10].w;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R1.xyz, -R0, R1.x, c[10].z;\n"
- "MAX R2.xyz, R1, c[10].w;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[10].z;\n"
- "MUL R3.xyz, R1, R2.w;\n"
- "ADD R2.w, -R1, c[10].z;\n"
- "MAD R4.xyz, R0, R2.w, R3;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R0.xyz, R0, R1.w, R3;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R3, R2, R4;\n"
- "MAD R4.xyz, R0.w, R1.w, R4;\n"
- "ADD R4.xyz, R4, -R2;\n"
- "MAD R2.xyz, R0, R4, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORBURN =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.w, R0.x;\n"
- "ABS R0.z, R0.y;\n"
- "ADD R0.z, R0, -R0.w;\n"
- "ADD R1.x, R0.y, c[8];\n"
- "ABS R0.z, R0;\n"
- "CMP R0.y, -R0.z, R0, R1.x;\n"
- "ABS R0.z, -R0.y;\n"
- "MAX R1.x, R0.w, R0.z;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.w, R0.z;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[8].y, c[8];\n"
- "MAD R1.z, R1, R1.y, -c[8].w;\n"
- "MAD R1.z, R1, R1.y, c[9].x;\n"
- "MAD R1.z, R1, R1.y, -c[9].y;\n"
- "MAD R1.y, R1.z, R1, c[9].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[9].w;\n"
- "ADD R0.z, -R0.w, R0;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[10].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[10].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[10].w;\n"
- "ADD R2.w, -R1, c[10].z;\n"
- "ADD R3.w, -R0, c[10].z;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R2.xyz, R1, R3.w, R2;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R3.xyz, R3, R2.w;\n"
- "MAD R2.xyz, R3, R2, R0;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_HARDLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8];\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[8].y, c[8];\n"
- "MAD R1.z, R1, R1.y, -c[8].w;\n"
- "MAD R1.z, R1, R1.y, c[9].x;\n"
- "MAD R1.z, R1, R1.y, -c[9].y;\n"
- "MAD R1.y, R1.z, R1, c[9].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[9].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[10].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[10].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[10];\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[10].z;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[10];\n"
- "MAD R3.xyz, R3, c[10].z, R4;\n"
- "MUL R0.xyz, R0, c[10].z;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD R3.xyz, R1, R2.w, R3;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "MAD R2.xyz, R0, R2, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SOFTLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[13] = { program.local[0..7],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 1, 2 },\n"
- " { 9.9999997e-006, 4, 16, 12 },\n"
- " { 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.w, R0.x;\n"
- "ABS R0.z, R0.y;\n"
- "ADD R0.z, R0, -R0.w;\n"
- "ADD R1.x, R0.y, c[8];\n"
- "ABS R0.z, R0;\n"
- "CMP R0.y, -R0.z, R0, R1.x;\n"
- "ABS R0.z, -R0.y;\n"
- "MAX R1.x, R0.w, R0.z;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.w, R0.z;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[8].y, c[8];\n"
- "MAD R1.z, R1, R1.y, -c[8].w;\n"
- "MAD R1.z, R1, R1.y, c[9].x;\n"
- "MAD R1.z, R1, R1.y, -c[9].y;\n"
- "MAD R1.y, R1.z, R1, c[9].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[9].w;\n"
- "ADD R0.z, -R0.w, R0;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[10].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MAX R0.z, R1.w, c[11].x;\n"
- "RCP R2.x, R0.z;\n"
- "MUL R3.xyz, R1, R2.x;\n"
- "MAD R4.xyz, R3, c[11].z, -c[11].w;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[10].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MAD R2.xyz, R0, c[10].w, -R0.w;\n"
- "MAD R4.xyz, R3, R4, c[12].x;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[10].z;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[10].w;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[11].y;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MUL R2.xyz, R1, R2;\n"
- "ADD R2.w, -R1, c[10].z;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, -R0.w, c[10].z;\n"
- "MAD R2.xyz, R1, R0.x, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DIFFERENCE =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[9].x, c[9].y;\n"
- "MAD R1.z, R1, R1.y, -c[9];\n"
- "MAD R1.z, R1, R1.y, c[9].w;\n"
- "MAD R1.z, R1, R1.y, -c[10].x;\n"
- "MAD R1.y, R1.z, R1, c[10];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[8].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[8].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.z, R0.x, c[8].x;\n"
- "FLR R0.w, R0.z;\n"
- "ADD R1.x, R0.z, -R0.w;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "ADD R2.xyz, R1, R0;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R1.xyz, R1, R0.w;\n"
- "MIN R1.xyz, R1, R3;\n"
- "MAD R2.xyz, -R1, c[10].z, R2;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_EXCLUSION =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..7],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[8].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[9].x, c[9].y;\n"
- "MAD R1.z, R1, R1.y, -c[9];\n"
- "MAD R1.z, R1, R1.y, c[9].w;\n"
- "MAD R1.z, R1, R1.y, -c[10].x;\n"
- "MAD R1.y, R1.z, R1, c[10];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[8].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[8].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.z, R0.x, c[8].x;\n"
- "FLR R0.w, R0.z;\n"
- "ADD R1.x, R0.z, -R0.w;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "MUL R2.xyz, R1, R0;\n"
- "MAD R2.xyz, -R2, c[10].z, R3;\n"
- "ADD R2.w, -R0, c[10];\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[10].w;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..6],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[7].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[8].x, c[8].y;\n"
- "MAD R1.z, R1, R1.y, -c[8];\n"
- "MAD R1.z, R1, R1.y, c[8].w;\n"
- "MAD R1.z, R1, R1.y, -c[9].x;\n"
- "MAD R1.y, R1.z, R1, c[9];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[7].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[7].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[6].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R2.xyz, R1, c[4].y;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[7];\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R3.xyz, R0.w, R2;\n"
- "MUL R2.xyz, R0, c[4].x;\n"
- "MAD R2.xyz, R1.w, R2, R3;\n"
- "ADD R2.w, -R1, c[9].z;\n"
- "MUL R0.xyz, R0, c[5].y;\n"
- "MAD R0.xyz, R2.w, R0, R2;\n"
- "ADD R2.x, -R0.w, c[9].z;\n"
- "MUL R1.xyz, R1, c[5].z;\n"
- "MAD result.color.xyz, R2.x, R1, R0;\n"
- "MUL R0.x, R0.w, R1.w;\n"
- "MUL R0.z, R1.w, R2.x;\n"
- "MUL R0.y, R0.w, R2.w;\n"
- "DP3 result.color.w, R0, c[5];\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_MULTIPLY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[6].x, c[6].y;\n"
- "MAD R1.z, R1, R1.y, -c[6];\n"
- "MAD R1.z, R1, R1.y, c[6].w;\n"
- "MAD R1.z, R1, R1.y, -c[7].x;\n"
- "MAD R1.y, R1.z, R1, c[7];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[5].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[5].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[5];\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R2.x, -R1.w, c[7].z;\n"
- "MUL R2.xyz, R0, R2.x;\n"
- "MAD R0.xyz, R0, R1, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[7].z;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SCREEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[6].x, c[6].y;\n"
- "MAD R1.z, R1, R1.y, -c[6];\n"
- "MAD R1.z, R1, R1.y, c[6].w;\n"
- "MAD R1.z, R1, R1.y, -c[7].x;\n"
- "MAD R1.y, R1.z, R1, c[7];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[5].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[5].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[5];\n"
- "FLR R0.y, R0.x;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R2, R0, R1;\n"
- "MAD result.color, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_OVERLAY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5];\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[5].y, c[5];\n"
- "MAD R1.z, R1, R1.y, -c[5].w;\n"
- "MAD R1.z, R1, R1.y, c[6].x;\n"
- "MAD R1.z, R1, R1.y, -c[6].y;\n"
- "MAD R1.y, R1.z, R1, c[6].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[6].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[7].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[7].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[7];\n"
- "MUL R2.xyz, R2, c[7].z;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R2.w;\n"
- "MUL R0.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[7];\n"
- "MAD R0.xyz, R0, c[7].z, R3;\n"
- "MAD R0.xyz, R1, R2.w, R0;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R1.xyz, R1, c[7].z;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R1.xyz, R1, R1.w;\n"
- "MAD result.color.xyz, R1, R2, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DARKEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[6].x, c[6].y;\n"
- "MAD R1.z, R1, R1.y, -c[6];\n"
- "MAD R1.z, R1, R1.y, c[6].w;\n"
- "MAD R1.z, R1, R1.y, -c[7].x;\n"
- "MAD R1.y, R1.z, R1, c[7];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[5].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[5].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[5];\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[7].z;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[7].z;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_LIGHTEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[6].x, c[6].y;\n"
- "MAD R1.z, R1, R1.y, -c[6];\n"
- "MAD R1.z, R1, R1.y, c[6].w;\n"
- "MAD R1.z, R1, R1.y, -c[7].x;\n"
- "MAD R1.y, R1.z, R1, c[7];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[5].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[5].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[5];\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[7].z;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[7].z;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORDODGE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5];\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[5].y, c[5];\n"
- "MAD R1.z, R1, R1.y, -c[5].w;\n"
- "MAD R1.z, R1, R1.y, c[6].x;\n"
- "MAD R1.z, R1, R1.y, -c[6].y;\n"
- "MAD R1.y, R1.z, R1, c[6].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[6].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[7].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[7].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MAX R1.x, R0.w, c[7].w;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R1.xyz, -R0, R1.x, c[7].z;\n"
- "MAX R2.xyz, R1, c[7].w;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[7].z;\n"
- "MUL R3.xyz, R1, R2.w;\n"
- "ADD R2.w, -R1, c[7].z;\n"
- "MAD R3.xyz, R0, R2.w, R3;\n"
- "MUL R1.xyz, R0.w, R1;\n"
- "MAD R0.xyz, R0, R1.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R1, R2, R3;\n"
- "MAD R3.xyz, R0.w, R1.w, R3;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "ADD R3.xyz, R3, -R2;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "MAD result.color.xyz, R0, R3, R2;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORBURN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.w, R0.x;\n"
- "ABS R0.z, R0.y;\n"
- "ADD R0.z, R0, -R0.w;\n"
- "ADD R1.x, R0.y, c[5];\n"
- "ABS R0.z, R0;\n"
- "CMP R0.y, -R0.z, R0, R1.x;\n"
- "ABS R0.z, -R0.y;\n"
- "MAX R1.x, R0.w, R0.z;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.w, R0.z;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[5].y, c[5];\n"
- "MAD R1.z, R1, R1.y, -c[5].w;\n"
- "MAD R1.z, R1, R1.y, c[6].x;\n"
- "MAD R1.z, R1, R1.y, -c[6].y;\n"
- "MAD R1.y, R1.z, R1, c[6].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[6].w;\n"
- "ADD R0.z, -R0.w, R0;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[7].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[7].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "ADD R2.w, -R1, c[7].z;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[7].w;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "ADD R3.w, -R0, c[7].z;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R1.xyz, R1, R3.w, R2;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.x, R0.w, R1.w;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R1.xyz, R1, -R0;\n"
- "SGE R2.xyz, R3, R2.x;\n"
- "MAD result.color.xyz, R2, R1, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_HARDLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5];\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[5].y, c[5];\n"
- "MAD R1.z, R1, R1.y, -c[5].w;\n"
- "MAD R1.z, R1, R1.y, c[6].x;\n"
- "MAD R1.z, R1, R1.y, -c[6].y;\n"
- "MAD R1.y, R1.z, R1, c[6].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[6].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[7].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[7].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[7];\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[7].z;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R2.w, -R0, c[7];\n"
- "MUL R0.xyz, R0, c[7].z;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MAD R3.xyz, R3, c[7].z, R4;\n"
- "MAD R1.xyz, R1, R2.w, R3;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R2.xyz, R2, -R1;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD result.color.xyz, R0, R2, R1;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SOFTLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..4],\n"
- " { 0.0020000001, -0.01348047, 0.05747731, 0.1212391 },\n"
- " { 0.1956359, 0.33299461, 0.99999559, 1.570796 },\n"
- " { 3.141593, 0.15915494, 1, 2 },\n"
- " { 9.9999997e-006, 4, 16, 12 },\n"
- " { 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.w, R0.x;\n"
- "ABS R0.z, R0.y;\n"
- "ADD R0.z, R0, -R0.w;\n"
- "ADD R1.x, R0.y, c[5];\n"
- "ABS R0.z, R0;\n"
- "CMP R0.y, -R0.z, R0, R1.x;\n"
- "ABS R0.z, -R0.y;\n"
- "MAX R1.x, R0.w, R0.z;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.w, R0.z;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[5].y, c[5];\n"
- "MAD R1.z, R1, R1.y, -c[5].w;\n"
- "MAD R1.z, R1, R1.y, c[6].x;\n"
- "MAD R1.z, R1, R1.y, -c[6].y;\n"
- "MAD R1.y, R1.z, R1, c[6].z;\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[6].w;\n"
- "ADD R0.z, -R0.w, R0;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[7].x;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MAX R0.z, R1.w, c[8].x;\n"
- "RCP R2.x, R0.z;\n"
- "MUL R3.xyz, R1, R2.x;\n"
- "MAD R4.xyz, R3, c[8].z, -c[8].w;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[7].y;\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MAD R2.xyz, R0, c[7].w, -R0.w;\n"
- "MAD R4.xyz, R3, R4, c[9].x;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[7].z;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[7].w;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[8].y;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "MUL R2.xyz, R1, R2;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "ADD R2.w, -R1, c[7].z;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, R0.w, R1.w;\n"
- "ADD R0.y, -R0.w, c[7].z;\n"
- "MAD result.color.xyz, R1, R0.y, R2;\n"
- "MAD result.color.w, -R0, R1, R0.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DIFFERENCE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[6].x, c[6].y;\n"
- "MAD R1.z, R1, R1.y, -c[6];\n"
- "MAD R1.z, R1, R1.y, c[6].w;\n"
- "MAD R1.z, R1, R1.y, -c[7].x;\n"
- "MAD R1.y, R1.z, R1, c[7];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[5].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[5].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[5];\n"
- "FLR R0.y, R0.x;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "ADD R0.xyz, R0, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "MAD result.color.xyz, -R2, c[7].z, R0;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_EXCLUSION_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..4],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559, 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[5].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[6].x, c[6].y;\n"
- "MAD R1.z, R1, R1.y, -c[6];\n"
- "MAD R1.z, R1, R1.y, c[6].w;\n"
- "MAD R1.z, R1, R1.y, -c[7].x;\n"
- "MAD R1.y, R1.z, R1, c[7];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[5].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[5].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[5];\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MUL R2.xyz, R0, R1;\n"
- "MAD R2.xyz, -R2, c[7].z, R3;\n"
- "ADD R2.w, -R1, c[7];\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[7].w;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODE_BLEND_MODE_MASK =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..6],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[7].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[8].x, c[8].y;\n"
- "MAD R1.z, R1, R1.y, -c[8];\n"
- "MAD R1.z, R1, R1.y, c[8].w;\n"
- "MAD R1.z, R1, R1.y, -c[9].x;\n"
- "MAD R1.y, R1.z, R1, c[9];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R1.y, -R1.x, c[7].w;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[7].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R1.x, R0, c[7];\n"
- "FLR R1.y, R1.x;\n"
- "ADD R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "MUL R0.xy, R0.zwzw, c[4];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, R1, -R1.y;\n"
- "DP4 R1.y, R0, c[6];\n"
- "TEX R0, R1, texture[1], 1D;\n"
- "MUL result.color, R0, R1.y;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODE_BLEND_MODE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..3],\n"
- " { 0.15915494, 0.0020000001, 3.141593, 1.570796 },\n"
- " { -0.01348047, 0.05747731, 0.1212391, 0.1956359 },\n"
- " { 0.33299461, 0.99999559 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "ABS R0.z, R0.x;\n"
- "ABS R0.w, R0.y;\n"
- "ADD R0.w, R0, -R0.z;\n"
- "ADD R1.x, R0.y, c[4].y;\n"
- "ABS R0.w, R0;\n"
- "CMP R0.y, -R0.w, R0, R1.x;\n"
- "ABS R0.w, -R0.y;\n"
- "MAX R1.x, R0.z, R0.w;\n"
- "RCP R1.y, R1.x;\n"
- "MIN R1.x, R0.z, R0.w;\n"
- "MUL R1.x, R1, R1.y;\n"
- "MUL R1.y, R1.x, R1.x;\n"
- "MAD R1.z, R1.y, c[5].x, c[5].y;\n"
- "MAD R1.z, R1, R1.y, -c[5];\n"
- "MAD R1.z, R1, R1.y, c[5].w;\n"
- "MAD R1.z, R1, R1.y, -c[6].x;\n"
- "MAD R1.y, R1.z, R1, c[6];\n"
- "MUL R1.x, R1.y, R1;\n"
- "ADD R0.z, -R0, R0.w;\n"
- "ADD R1.y, -R1.x, c[4].w;\n"
- "CMP R0.z, -R0, R1.y, R1.x;\n"
- "ADD R0.w, -R0.z, c[4].z;\n"
- "CMP R0.x, R0, R0.w, R0.z;\n"
- "CMP R0.x, -R0.y, -R0, R0;\n"
- "ADD R0.x, R0, c[0];\n"
- "MUL R0.x, R0, c[4];\n"
- "FLR R0.y, R0.x;\n"
- "ADD R0.x, R0, -R0.y;\n"
- "TEX result.color, R0, texture[0], 1D;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SIMPLE_PORTER_DUFF =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..9],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, c[0].xyxy;\n"
- "ADD R1.x, R0.z, R0.w;\n"
- "MUL R0.xy, fragment.position, c[7];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.x, R1, c[0].z;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R2.xyz, R0, c[4].y;\n"
- "MUL R3.xyz, R1.w, R2;\n"
- "MUL R2.xyz, R1, c[4].x;\n"
- "MAD R2.xyz, R0.w, R2, R3;\n"
- "ADD R3.xy, fragment.position, c[8];\n"
- "ADD R2.w, -R0, c[10].x;\n"
- "MUL R1.xyz, R1, c[5].y;\n"
- "MAD R2.xyz, R2.w, R1, R2;\n"
- "MUL R1.xyz, R0, c[5].z;\n"
- "ADD R3.z, -R1.w, c[10].x;\n"
- "MAD R2.xyz, R3.z, R1, R2;\n"
- "MUL R1.y, R1.w, R2.w;\n"
- "MUL R1.x, R1.w, R0.w;\n"
- "MUL R1.z, R0.w, R3;\n"
- "DP3 R2.w, R1, c[5];\n"
- "MUL R3.xy, R3, c[6];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[9];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_MULTIPLY =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, c[0].xyxy;\n"
- "ADD R1.x, R0.z, R0.w;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.x, R1, c[0].z;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "ADD R2.x, -R0.w, c[8];\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "MAD R1.xyz, R1, R0, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SCREEN =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..7] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.z, R0.x, c[0];\n"
- "ADD R3.xy, fragment.position, c[6];\n"
- "TEX R1, R0.z, texture[2], 1D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R2, R1, R0;\n"
- "MAD R2, -R1, R0, R2;\n"
- "MUL R3.xy, R3, c[4];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_OVERLAY =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[8].y;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[8].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, -R0.w, c[8].y;\n"
- "MAD R3.xyz, R3, c[8].x, R4;\n"
- "MAD R3.xyz, R1, R2.x, R3;\n"
- "MAD R0.xyz, R1, R2.x, R0;\n"
- "MUL R2.xyz, R1, c[8].x;\n"
- "ADD R0.xyz, R0, -R3;\n"
- "SGE R2.xyz, R2, R1.w;\n"
- "MAD R2.xyz, R2, R0, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DARKEN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.z, R0.x, R0.y;\n"
- "MUL R1.x, R0.z, c[0].z;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_LIGHTEN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.z, R0.x, R0.y;\n"
- "MUL R1.x, R0.z, c[0].z;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORDODGE =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MAX R1.x, R0.w, c[8].y;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R2.xyz, -R0, R1.x, c[8].x;\n"
- "MAX R2.xyz, R2, c[8].y;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MUL R3.xyz, R1, R2.w;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MAD R4.xyz, R0, R2.w, R3;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R0.xyz, R0, R1.w, R3;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R3, R2, R4;\n"
- "MAD R4.xyz, R0.w, R1.w, R4;\n"
- "ADD R4.xyz, R4, -R2;\n"
- "MAD R2.xyz, R0, R4, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORBURN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[8].y;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "ADD R3.w, -R0, c[8].x;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R2.xyz, R1, R3.w, R2;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R3.xyz, R3, R2.w;\n"
- "MAD R2.xyz, R3, R2, R0;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_HARDLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[8].y;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[8].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[8].y;\n"
- "MAD R3.xyz, R3, c[8].x, R4;\n"
- "MUL R0.xyz, R0, c[8].x;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD R3.xyz, R1, R2.w, R3;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "MAD R2.xyz, R0, R2, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SOFTLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..7],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MAX R0.z, R1.w, c[8];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R3.xyz, R1, R0.z;\n"
- "MAD R2.xyz, R3, c[9].x, -c[9].y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[2], 1D;\n"
- "MAD R4.xyz, R3, R2, c[9].z;\n"
- "MAD R2.xyz, R0, c[8].y, -R0.w;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[8].x;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[8].y;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[8].w;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MUL R2.xyz, R1, R2;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, -R0.w, c[8];\n"
- "MAD R2.xyz, R1, R0.x, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DIFFERENCE =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.z, R0.x, R0.y;\n"
- "MUL R1.x, R0.z, c[0].z;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "ADD R2.xyz, R1, R0;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R1.xyz, R1, R0.w;\n"
- "MIN R1.xyz, R1, R3;\n"
- "MAD R2.xyz, -R1, c[8].x, R2;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_EXCLUSION =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.z, R0.x, R0.y;\n"
- "MUL R1.x, R0.z, c[0].z;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 1D;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "MUL R2.xyz, R1, R0;\n"
- "MAD R2.xyz, -R2, c[8].x, R3;\n"
- "ADD R2.w, -R0, c[8].y;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8].y;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..6],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[6].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R2.xyz, R1, c[4].y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R3.xyz, R0.w, R2;\n"
- "MUL R2.xyz, R0, c[4].x;\n"
- "MAD R2.xyz, R1.w, R2, R3;\n"
- "ADD R2.w, -R1, c[7].x;\n"
- "MUL R0.xyz, R0, c[5].y;\n"
- "MAD R0.xyz, R2.w, R0, R2;\n"
- "ADD R2.x, -R0.w, c[7];\n"
- "MUL R1.xyz, R1, c[5].z;\n"
- "MAD result.color.xyz, R2.x, R1, R0;\n"
- "MUL R0.x, R0.w, R1.w;\n"
- "MUL R0.z, R1.w, R2.x;\n"
- "MUL R0.y, R0.w, R2.w;\n"
- "DP3 result.color.w, R0, c[5];\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_MULTIPLY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R2.x, -R1.w, c[5];\n"
- "MUL R2.xyz, R0, R2.x;\n"
- "MAD R0.xyz, R0, R1, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SCREEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..4] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "ADD R2, R0, R1;\n"
- "MAD result.color, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_OVERLAY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[5].y;\n"
- "MUL R2.xyz, R2, c[5].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R2.w;\n"
- "MUL R0.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[5].y;\n"
- "MAD R0.xyz, R0, c[5].x, R3;\n"
- "MAD R0.xyz, R1, R2.w, R0;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R1.xyz, R1, c[5].x;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R1.xyz, R1, R1.w;\n"
- "MAD result.color.xyz, R1, R2, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DARKEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_LIGHTEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORDODGE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MAX R1.x, R0.w, c[5].y;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R3.xyz, -R0, R1.x, c[5].x;\n"
- "MAX R3.xyz, R3, c[5].y;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.x, -R0.w, c[5];\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R1.xyz, R0.w, R1;\n"
- "MAD R0.xyz, R0, R1.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "RCP R3.x, R3.x;\n"
- "RCP R3.y, R3.y;\n"
- "RCP R3.z, R3.z;\n"
- "MAD R3.xyz, R1, R3, R2;\n"
- "MAD R2.xyz, R0.w, R1.w, R2;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "MAD result.color.xyz, R0, R2, R3;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORBURN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[5].y;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "ADD R3.w, -R0, c[5].x;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R1.xyz, R1, R3.w, R2;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.x, R0.w, R1.w;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R1.xyz, R1, -R0;\n"
- "SGE R2.xyz, R3, R2.x;\n"
- "MAD result.color.xyz, R2, R1, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_HARDLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[5].y;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[5].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MUL R0.xyz, R0, c[5].x;\n"
- "ADD R2.w, -R0, c[5].y;\n"
- "MAD R3.xyz, R3, c[5].x, R4;\n"
- "MAD R3.xyz, R1, R2.w, R3;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R1.xyz, R1, -R3;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD result.color.xyz, R0, R1, R3;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SOFTLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..4],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MAX R0.z, R1.w, c[5];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R3.xyz, R1, R0.z;\n"
- "MAD R2.xyz, R3, c[6].x, -c[6].y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MAD R4.xyz, R3, R2, c[6].z;\n"
- "MAD R2.xyz, R0, c[5].y, -R0.w;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[5].x;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[5].y;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[5].w;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "MUL R2.xyz, R1, R2;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, R0.w, R1.w;\n"
- "ADD R0.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R0.y, R2;\n"
- "MAD result.color.w, -R0, R1, R0.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DIFFERENCE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "ADD R0.xyz, R0, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "MAD result.color.xyz, -R2, c[5].x, R0;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_EXCLUSION_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX R0, R0, texture[1], 1D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MUL R2.xyz, R0, R1;\n"
- "MAD R2.xyz, -R2, c[5].x, R3;\n"
- "ADD R2.w, -R1, c[5].y;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5];\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODE_BLEND_MODE_MASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..6] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.z;\n"
- "MUL R0.zw, R0, c[0].xyxy;\n"
- "ADD R1.x, R0.z, R0.w;\n"
- "ADD R0.xy, fragment.position, c[5];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "DP4 R1.y, R0, c[6];\n"
- "MUL R1.x, R1, c[0].z;\n"
- "TEX R0, R1, texture[1], 1D;\n"
- "MUL result.color, R0, R1.y;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODE_BLEND_MODE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[4] = { program.local[0..3] };\n"
- "TEMP R0;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "ADD R0.x, R0, R0.y;\n"
- "MUL R0.x, R0, c[0].z;\n"
- "TEX result.color, R0, texture[0], 1D;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SIMPLE_PORTER_DUFF =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..9],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R1.xyz, R0, c[3];\n"
- "RCP R0.z, R1.z;\n"
- "MUL R1.xy, R1, R0.z;\n"
- "MUL R0.xy, fragment.position, c[7];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[2], 2D;\n"
- "MUL R2.xyz, R0, c[4].y;\n"
- "MUL R3.xyz, R1.w, R2;\n"
- "MUL R2.xyz, R1, c[4].x;\n"
- "MAD R2.xyz, R0.w, R2, R3;\n"
- "ADD R3.xy, fragment.position, c[8];\n"
- "ADD R2.w, -R0, c[10].x;\n"
- "MUL R1.xyz, R1, c[5].y;\n"
- "MAD R2.xyz, R2.w, R1, R2;\n"
- "MUL R1.xyz, R0, c[5].z;\n"
- "ADD R3.z, -R1.w, c[10].x;\n"
- "MAD R2.xyz, R3.z, R1, R2;\n"
- "MUL R1.y, R1.w, R2.w;\n"
- "MUL R1.x, R1.w, R0.w;\n"
- "MUL R1.z, R0.w, R3;\n"
- "DP3 R2.w, R1, c[5];\n"
- "MUL R3.xy, R3, c[6];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[9];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_MULTIPLY =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R1.xyz, R0, c[3];\n"
- "RCP R0.z, R1.z;\n"
- "MUL R1.xy, R1, R0.z;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1, R1, texture[2], 2D;\n"
- "ADD R2.x, -R0.w, c[8];\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "MAD R1.xyz, R1, R0, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SCREEN =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..7] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, c[0].xyxy;\n"
- "ADD R3.xy, fragment.position, c[6];\n"
- "TEX R1, R0.zwzw, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R2, R1, R0;\n"
- "MAD R2, -R1, R0, R2;\n"
- "MUL R3.xy, R3, c[4];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_OVERLAY =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[2], 2D;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[8].y;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[8].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, -R0.w, c[8].y;\n"
- "MAD R3.xyz, R3, c[8].x, R4;\n"
- "MAD R3.xyz, R1, R2.x, R3;\n"
- "MAD R0.xyz, R1, R2.x, R0;\n"
- "MUL R2.xyz, R1, c[8].x;\n"
- "ADD R0.xyz, R0, -R3;\n"
- "SGE R2.xyz, R2, R1.w;\n"
- "MAD R2.xyz, R2, R0, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DARKEN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.z;\n"
- "MUL R1.xy, R0.zwzw, c[0];\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 2D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_LIGHTEN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.z;\n"
- "MUL R1.xy, R0.zwzw, c[0];\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 2D;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORDODGE =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[2], 2D;\n"
- "MAX R1.x, R0.w, c[8].y;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R2.xyz, -R0, R1.x, c[8].x;\n"
- "MAX R2.xyz, R2, c[8].y;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MUL R3.xyz, R1, R2.w;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MAD R4.xyz, R0, R2.w, R3;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R0.xyz, R0, R1.w, R3;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R3, R2, R4;\n"
- "MAD R4.xyz, R0.w, R1.w, R4;\n"
- "ADD R4.xyz, R4, -R2;\n"
- "MAD R2.xyz, R0, R4, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORBURN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[2], 2D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[8].y;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "ADD R3.w, -R0, c[8].x;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.w, R0, R1;\n"
- "MAD R2.xyz, R1, R3.w, R2;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R3.xyz, R3, R2.w;\n"
- "MAD R2.xyz, R3, R2, R0;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_HARDLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[2], 2D;\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[8].y;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[8].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[8].y;\n"
- "MAD R3.xyz, R3, c[8].x, R4;\n"
- "MUL R0.xyz, R0, c[8].x;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD R3.xyz, R1, R2.w, R3;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "MAD R2.xyz, R0, R2, R3;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SOFTLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..7],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MUL R1.xy, fragment.position, c[5];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MAX R0.w, R1, c[8].z;\n"
- "RCP R0.w, R0.w;\n"
- "MUL R3.xyz, R1, R0.w;\n"
- "MAD R2.xyz, R3, c[9].x, -c[9].y;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[2], 2D;\n"
- "MAD R4.xyz, R3, R2, c[9].z;\n"
- "MAD R2.xyz, R0, c[8].y, -R0.w;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[8].x;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[8].y;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[8].w;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MUL R2.xyz, R1, R2;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, -R0.w, c[8];\n"
- "MAD R2.xyz, R1, R0.x, R2;\n"
- "ADD R0.z, R0.w, R1.w;\n"
- "MAD R2.w, -R0, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[6];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R2, -R1;\n"
- "DP4 R0.x, R0, c[7];\n"
- "MAD result.color, R0.x, R2, R1;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DIFFERENCE =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.z;\n"
- "MUL R1.xy, R0.zwzw, c[0];\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 2D;\n"
- "ADD R2.xyz, R1, R0;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R1.xyz, R1, R0.w;\n"
- "MIN R1.xyz, R1, R3;\n"
- "MAD R2.xyz, -R1, c[8].x, R2;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_EXCLUSION =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.z;\n"
- "MUL R1.xy, R0.zwzw, c[0];\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "TEX R1, R1, texture[2], 2D;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "MUL R2.xyz, R1, R0;\n"
- "MAD R2.xyz, -R2, c[8].x, R3;\n"
- "ADD R2.w, -R0, c[8].y;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8].y;\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..6],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R1.xy, fragment.position, c[6];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MUL R2.xyz, R1, c[4].y;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R3.xyz, R0.w, R2;\n"
- "MUL R2.xyz, R0, c[4].x;\n"
- "MAD R2.xyz, R1.w, R2, R3;\n"
- "ADD R2.w, -R1, c[7].x;\n"
- "MUL R0.xyz, R0, c[5].y;\n"
- "MAD R0.xyz, R2.w, R0, R2;\n"
- "ADD R2.x, -R0.w, c[7];\n"
- "MUL R1.xyz, R1, c[5].z;\n"
- "MAD result.color.xyz, R2.x, R1, R0;\n"
- "MUL R0.x, R0.w, R1.w;\n"
- "MUL R0.z, R1.w, R2.x;\n"
- "MUL R0.y, R0.w, R2.w;\n"
- "DP3 result.color.w, R0, c[5];\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_MULTIPLY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2.x, -R1.w, c[5];\n"
- "MUL R2.xyz, R0, R2.x;\n"
- "MAD R0.xyz, R0, R1, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SCREEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..4] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "ADD R2, R0, R1;\n"
- "MAD result.color, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_OVERLAY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[5].y;\n"
- "MUL R2.xyz, R2, c[5].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R3.xyz, R0, R2.w;\n"
- "MUL R0.xyz, R0, R1;\n"
- "ADD R2.w, -R0, c[5].y;\n"
- "MAD R0.xyz, R0, c[5].x, R3;\n"
- "MAD R0.xyz, R1, R2.w, R0;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R1.xyz, R1, c[5].x;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R2.xyz, R2, -R0;\n"
- "SGE R1.xyz, R1, R1.w;\n"
- "MAD result.color.xyz, R1, R2, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DARKEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_LIGHTEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORDODGE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MAX R1.x, R0.w, c[5].y;\n"
- "RCP R1.x, R1.x;\n"
- "MAD R3.xyz, -R0, R1.x, c[5].x;\n"
- "MAX R3.xyz, R3, c[5].y;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.x, -R0.w, c[5];\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R1.xyz, R0.w, R1;\n"
- "MAD R0.xyz, R0, R1.w, R1;\n"
- "MUL R2.w, R0, R1;\n"
- "RCP R3.x, R3.x;\n"
- "RCP R3.y, R3.y;\n"
- "RCP R3.z, R3.z;\n"
- "MAD R3.xyz, R1, R3, R2;\n"
- "MAD R2.xyz, R0.w, R1.w, R2;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "MAD result.color.xyz, R0, R2, R3;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORBURN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R2.xyz, -R0.w, R1.w, R3;\n"
- "MUL R4.xyz, R0.w, R2;\n"
- "MAX R2.xyz, R0, c[5].y;\n"
- "MUL R5.xyz, R0, R2.w;\n"
- "ADD R3.w, -R0, c[5].x;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R1, R3.w;\n"
- "MAD R1.xyz, R1, R3.w, R2;\n"
- "MAD R0.xyz, R0, R2.w, R4;\n"
- "MUL R2.x, R0.w, R1.w;\n"
- "ADD R2.w, R0, R1;\n"
- "ADD R1.xyz, R1, -R0;\n"
- "SGE R2.xyz, R3, R2.x;\n"
- "MAD result.color.xyz, R2, R1, R0;\n"
- "MAD result.color.w, -R0, R1, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_HARDLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[5].y;\n"
- "ADD R3.xyz, R0.w, -R0;\n"
- "ADD R2.xyz, R1.w, -R1;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[5].x;\n"
- "MAD R2.xyz, R0.w, R1.w, -R2;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R4.xyz, R0, R2.w;\n"
- "MUL R3.xyz, R0, R1;\n"
- "MUL R0.xyz, R0, c[5].x;\n"
- "ADD R2.w, -R0, c[5].y;\n"
- "MAD R3.xyz, R3, c[5].x, R4;\n"
- "MAD R3.xyz, R1, R2.w, R3;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R1.xyz, R1, -R3;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD result.color.xyz, R0, R1, R3;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SOFTLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..4],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MUL R1.xy, fragment.position, c[4];\n"
- "TEX R1, R1, texture[0], 2D;\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MAX R0.w, R1, c[5].z;\n"
- "RCP R0.w, R0.w;\n"
- "MUL R3.xyz, R1, R0.w;\n"
- "MAD R2.xyz, R3, c[6].x, -c[6].y;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MAD R4.xyz, R3, R2, c[6].z;\n"
- "MAD R2.xyz, R0, c[5].y, -R0.w;\n"
- "MUL R5.xyz, R1.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[5].x;\n"
- "MAD R2.xyz, R2, R3, R0.w;\n"
- "MUL R3.xyz, R0, c[5].y;\n"
- "MAD R5.xyz, R0.w, R1, R6;\n"
- "MAD R4.xyz, R0.w, R1, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R1, c[5].w;\n"
- "SGE R4.xyz, R4, R1.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R1, R2, R4;\n"
- "MUL R2.xyz, R1, R2;\n"
- "SGE R3.xyz, R3, R0.w;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R0.x, R0.w, R1.w;\n"
- "ADD R0.y, -R0.w, c[5].x;\n"
- "MAD result.color.xyz, R1, R0.y, R2;\n"
- "MAD result.color.w, -R0, R1, R0.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DIFFERENCE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R2.xyz, R0, R1.w;\n"
- "MUL R3.xyz, R0.w, R1;\n"
- "ADD R0.xyz, R0, R1;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R1.x, R0.w, R1.w;\n"
- "MAD result.color.xyz, -R2, c[5].x, R0;\n"
- "MAD result.color.w, -R0, R1, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_EXCLUSION_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 2, 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R1, R0.zwzw, texture[0], 2D;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0, R0, texture[1], 2D;\n"
- "MUL R2.xyz, R0.w, R1;\n"
- "MAD R3.xyz, R0, R1.w, R2;\n"
- "MUL R2.xyz, R0, R1;\n"
- "MAD R2.xyz, -R2, c[5].x, R3;\n"
- "ADD R2.w, -R1, c[5].y;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R0.w, R1.w;\n"
- "ADD R2.y, -R0.w, c[5];\n"
- "MAD result.color.xyz, R1, R2.y, R0;\n"
- "MAD result.color.w, -R0, R1, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODE_BLEND_MODE_MASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..6] };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R1.xyz, R0, c[3];\n"
- "RCP R0.z, R1.z;\n"
- "MUL R1.xy, R1, R0.z;\n"
- "ADD R0.xy, fragment.position, c[5];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "DP4 R1.z, R0, c[6];\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R0, R1, texture[1], 2D;\n"
- "MUL result.color, R0, R1.z;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODE_BLEND_MODE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[4] = { program.local[0..3] };\n"
- "TEMP R0;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX result.color, R0, texture[0], 2D;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SIMPLE_PORTER_DUFF =
- "!!ARBfp1.0\n"
- "PARAM c[11] = { program.local[0..9],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, c[0].xyxy;\n"
- "TEX R1.x, R0.zwzw, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[7];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -R1, c[10];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R2.xyz, R0, c[4].y;\n"
- "MUL R3.xyz, R1.w, R2;\n"
- "MUL R2.xyz, R1, c[4].x;\n"
- "MAD R2.xyz, R0.w, R2, R3;\n"
- "ADD R3.xy, fragment.position, c[8];\n"
- "ADD R2.w, -R0, c[10].x;\n"
- "MUL R1.xyz, R1, c[5].y;\n"
- "MAD R2.xyz, R2.w, R1, R2;\n"
- "MUL R1.xyz, R0, c[5].z;\n"
- "ADD R3.z, -R1.w, c[10].x;\n"
- "MAD R2.xyz, R3.z, R1, R2;\n"
- "MUL R1.y, R1.w, R2.w;\n"
- "MUL R1.x, R1.w, R0.w;\n"
- "MUL R1.z, R0.w, R3;\n"
- "DP3 R2.w, R1, c[5];\n"
- "MUL R3.xy, R3, c[6];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[9];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_MULTIPLY =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.zw, R0.xyxy, c[0].xyxy;\n"
- "TEX R1.x, R0.zwzw, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -R1, c[8];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "ADD R2.x, -R0.w, c[8];\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "MAD R1.xyz, R1, R0, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SCREEN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[2], 2D;\n"
- "ADD R0.z, -R0.x, c[8].x;\n"
- "ADD R3.xy, fragment.position, c[6];\n"
- "MUL R1, fragment.color.primary, R0.z;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R2, R1, R0;\n"
- "MAD R2, -R1, R0, R2;\n"
- "MUL R3.xy, R3, c[4];\n"
- "TEX R1, R3, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_OVERLAY =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[2], 2D;\n"
- "ADD R0.x, -R0, c[8];\n"
- "MUL R1, fragment.color.primary, R0.x;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "ADD R3.xyz, R1.w, -R1;\n"
- "ADD R2.xyz, R0.w, -R0;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[8].y;\n"
- "MAD R2.xyz, R1.w, R0.w, -R2;\n"
- "MUL R4.xyz, R1, R2.w;\n"
- "MUL R3.xyz, R1, R0;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R3.xyz, R3, c[8].y, R4;\n"
- "MAD R3.xyz, R0, R2.x, R3;\n"
- "MAD R1.xyz, R0, R2.x, R1;\n"
- "MUL R2.xyz, R0, c[8].y;\n"
- "ADD R1.xyz, R1, -R3;\n"
- "SGE R2.xyz, R2, R0.w;\n"
- "MAD R2.xyz, R2, R1, R3;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DARKEN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R1.x, R0, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -R1, c[8];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_LIGHTEN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R1.x, R0, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -R1, c[8];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORDODGE =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[2], 2D;\n"
- "ADD R0.x, -R0, c[8];\n"
- "MUL R1, fragment.color.primary, R0.x;\n"
- "MAX R0.x, R1.w, c[8].y;\n"
- "RCP R0.x, R0.x;\n"
- "MAD R2.xyz, -R1, R0.x, c[8].x;\n"
- "MAX R2.xyz, R2, c[8].y;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MUL R3.xyz, R0, R2.w;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R4.xyz, R1, R2.w, R3;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.w, R1, R0;\n"
- "MAD R1.xyz, R1, R0.w, R3;\n"
- "SGE R1.xyz, R1, R2.w;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R3, R2, R4;\n"
- "MAD R4.xyz, R1.w, R0.w, R4;\n"
- "ADD R4.xyz, R4, -R2;\n"
- "MAD R2.xyz, R1, R4, R2;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORBURN =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[2], 2D;\n"
- "ADD R1.x, -R0, c[8];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "MAD R2.xyz, -R1.w, R0.w, R3;\n"
- "MUL R4.xyz, R1.w, R2;\n"
- "MAX R2.xyz, R1, c[8].y;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MUL R5.xyz, R1, R2.w;\n"
- "ADD R3.w, -R1, c[8].x;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R0, R3.w;\n"
- "MAD R1.xyz, R1, R2.w, R4;\n"
- "MUL R2.w, R1, R0;\n"
- "MAD R2.xyz, R0, R3.w, R2;\n"
- "ADD R2.xyz, R2, -R1;\n"
- "SGE R3.xyz, R3, R2.w;\n"
- "MAD R2.xyz, R3, R2, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_HARDLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[2], 2D;\n"
- "ADD R0.x, -R0, c[8];\n"
- "MUL R1, fragment.color.primary, R0.x;\n"
- "MUL R0.zw, fragment.position.xyxy, c[5].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "ADD R3.xyz, R1.w, -R1;\n"
- "ADD R2.xyz, R0.w, -R0;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[8].y;\n"
- "MAD R2.xyz, R1.w, R0.w, -R2;\n"
- "MUL R4.xyz, R1, R2.w;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R3.xyz, R1, R0;\n"
- "ADD R2.w, -R1, c[8].x;\n"
- "MAD R3.xyz, R3, c[8].y, R4;\n"
- "MUL R1.xyz, R1, c[8].y;\n"
- "SGE R1.xyz, R1, R1.w;\n"
- "MAD R3.xyz, R0, R2.w, R3;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "MAD R2.xyz, R1, R2, R3;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SOFTLIGHT =
- "!!ARBfp1.0\n"
- "PARAM c[10] = { program.local[0..7],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R1.xyz, R0, c[3];\n"
- "RCP R1.z, R1.z;\n"
- "MUL R1.xy, R1, R1.z;\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1.x, R1, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MAX R1.z, R0.w, c[8];\n"
- "RCP R1.z, R1.z;\n"
- "MUL R3.xyz, R0, R1.z;\n"
- "MAD R2.xyz, R3, c[9].x, -c[9].y;\n"
- "ADD R1.x, -R1, c[8];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MAD R4.xyz, R3, R2, c[9].z;\n"
- "MAD R2.xyz, R1, c[8].y, -R1.w;\n"
- "MUL R5.xyz, R0.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[8].x;\n"
- "MAD R2.xyz, R2, R3, R1.w;\n"
- "MUL R3.xyz, R1, c[8].y;\n"
- "MAD R5.xyz, R1.w, R0, R6;\n"
- "MAD R4.xyz, R1.w, R0, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R0, c[8].w;\n"
- "SGE R4.xyz, R4, R0.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R0, R2, R4;\n"
- "SGE R3.xyz, R3, R1.w;\n"
- "MUL R2.xyz, R0, R2;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "ADD R1.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R1.x, R2;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DIFFERENCE =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R1.x, R0, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "ADD R1.x, -R1, c[8];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "ADD R2.xyz, R1, R0;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R1.xyz, R1, R0.w;\n"
- "MIN R1.xyz, R1, R3;\n"
- "MAD R2.xyz, -R1, c[8].y, R2;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_EXCLUSION =
- "!!ARBfp1.0\n"
- "PARAM c[9] = { program.local[0..7],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R1.x, R0, texture[2], 2D;\n"
- "MUL R0.xy, fragment.position, c[5];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R1.x, -R1, c[8];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "MUL R2.xyz, R1, R0;\n"
- "MAD R2.xyz, -R2, c[8].y, R3;\n"
- "ADD R2.w, -R0, c[8].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, -R1.w, c[8];\n"
- "MAD R2.xyz, R0, R2.x, R1;\n"
- "ADD R1.z, R1.w, R0.w;\n"
- "MAD R2.w, -R1, R0, R1.z;\n"
- "ADD R1.xy, fragment.position, c[6];\n"
- "MUL R1.xy, R1, c[4];\n"
- "TEX R1, R1, texture[1], 2D;\n"
- "ADD R2, R2, -R0;\n"
- "DP4 R1.x, R1, c[7];\n"
- "MAD result.color, R1.x, R2, R0;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..6],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R1.x, R0, texture[1], 2D;\n"
- "MUL R0.zw, fragment.position.xyxy, c[6].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R2.xyz, R0, c[4].y;\n"
- "ADD R1.x, -R1, c[7];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R3.xyz, R1.w, R2;\n"
- "MUL R2.xyz, R1, c[4].x;\n"
- "MUL R0.xyz, R0, c[5].z;\n"
- "MAD R2.xyz, R0.w, R2, R3;\n"
- "ADD R2.w, -R0, c[7].x;\n"
- "MUL R1.xyz, R1, c[5].y;\n"
- "MAD R1.xyz, R2.w, R1, R2;\n"
- "ADD R2.x, -R1.w, c[7];\n"
- "MAD result.color.xyz, R2.x, R0, R1;\n"
- "MUL R0.x, R1.w, R0.w;\n"
- "MUL R0.z, R0.w, R2.x;\n"
- "MUL R0.y, R1.w, R2.w;\n"
- "DP3 result.color.w, R0, c[5];\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_MULTIPLY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R1.x, R0, texture[1], 2D;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "ADD R1.x, -R1, c[5];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "ADD R2.x, -R0.w, c[5];\n"
- "MUL R2.xyz, R1, R2.x;\n"
- "MAD R1.xyz, R1, R0, R2;\n"
- "ADD R2.x, R1.w, R0.w;\n"
- "ADD R2.y, -R1.w, c[5].x;\n"
- "MAD result.color.xyz, R0, R2.y, R1;\n"
- "MAD result.color.w, -R1, R0, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SCREEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R1.x, -R0, c[5];\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "ADD R2, R1, R0;\n"
- "MAD result.color, -R1, R0, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_OVERLAY_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R0.x, -R0, c[5];\n"
- "MUL R1, fragment.color.primary, R0.x;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "ADD R3.xyz, R1.w, -R1;\n"
- "ADD R2.xyz, R0.w, -R0;\n"
- "MUL R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "MUL R2.xyz, R2, c[5].y;\n"
- "MAD R2.xyz, R1.w, R0.w, -R2;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R3.xyz, R1, R2.w;\n"
- "MUL R1.xyz, R1, R0;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R1.xyz, R1, c[5].y, R3;\n"
- "MAD R1.xyz, R0, R2.w, R1;\n"
- "MAD R2.xyz, R0, R2.w, R2;\n"
- "MUL R0.xyz, R0, c[5].y;\n"
- "ADD R2.w, R1, R0;\n"
- "ADD R2.xyz, R2, -R1;\n"
- "SGE R0.xyz, R0, R0.w;\n"
- "MAD result.color.xyz, R0, R2, R1;\n"
- "MAD result.color.w, -R1, R0, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DARKEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R1.x, -R0, c[5];\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, R1.w, R0.w;\n"
- "ADD R2.y, -R1.w, c[5].x;\n"
- "MAD result.color.xyz, R0, R2.y, R1;\n"
- "MAD result.color.w, -R1, R0, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_LIGHTEN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R1.x, -R0, c[5];\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MAX R2.xyz, R2, R3;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, R1.w, R0.w;\n"
- "ADD R2.y, -R1.w, c[5].x;\n"
- "MAD result.color.xyz, R0, R2.y, R1;\n"
- "MAD result.color.w, -R1, R0, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORDODGE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 1e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R0.x, -R0, c[5];\n"
- "MUL R1, fragment.color.primary, R0.x;\n"
- "MAX R0.x, R1.w, c[5].y;\n"
- "RCP R0.x, R0.x;\n"
- "MAD R3.xyz, -R1, R0.x, c[5].x;\n"
- "MAX R3.xyz, R3, c[5].y;\n"
- "MUL R0.xy, fragment.position, c[4];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "ADD R2.x, -R1.w, c[5];\n"
- "MUL R2.xyz, R0, R2.x;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R0.xyz, R1.w, R0;\n"
- "RCP R3.x, R3.x;\n"
- "RCP R3.y, R3.y;\n"
- "RCP R3.z, R3.z;\n"
- "MAD R3.xyz, R0, R3, R2;\n"
- "MAD R0.xyz, R1, R0.w, R0;\n"
- "MAD R2.xyz, R1.w, R0.w, R2;\n"
- "MUL R2.w, R1, R0;\n"
- "ADD R1.x, R1.w, R0.w;\n"
- "ADD R2.xyz, R2, -R3;\n"
- "SGE R0.xyz, R0, R2.w;\n"
- "MAD result.color.xyz, R0, R2, R3;\n"
- "MAD result.color.w, -R1, R0, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORBURN_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 9.9999997e-006 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R1.x, -R0, c[5];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "MAD R2.xyz, -R1.w, R0.w, R3;\n"
- "MUL R4.xyz, R1.w, R2;\n"
- "MAX R2.xyz, R1, c[5].y;\n"
- "MUL R5.xyz, R1, R2.w;\n"
- "ADD R3.w, -R1, c[5].x;\n"
- "RCP R2.x, R2.x;\n"
- "RCP R2.y, R2.y;\n"
- "RCP R2.z, R2.z;\n"
- "MAD R2.xyz, R4, R2, R5;\n"
- "MUL R4.xyz, R0, R3.w;\n"
- "MAD R0.xyz, R0, R3.w, R2;\n"
- "MAD R1.xyz, R1, R2.w, R4;\n"
- "MUL R2.x, R1.w, R0.w;\n"
- "ADD R2.w, R1, R0;\n"
- "ADD R0.xyz, R0, -R1;\n"
- "SGE R2.xyz, R3, R2.x;\n"
- "MAD result.color.xyz, R2, R0, R1;\n"
- "MAD result.color.w, -R1, R0, R2;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_HARDLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R0.x, -R0, c[5];\n"
- "MUL R1, fragment.color.primary, R0.x;\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "ADD R3.xyz, R1.w, -R1;\n"
- "ADD R2.xyz, R0.w, -R0;\n"
- "MUL R2.xyz, R2, R3;\n"
- "MUL R2.xyz, R2, c[5].y;\n"
- "MAD R2.xyz, R1.w, R0.w, -R2;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "MUL R4.xyz, R1, R2.w;\n"
- "MUL R3.xyz, R1, R0;\n"
- "MUL R1.xyz, R1, c[5].y;\n"
- "ADD R2.w, -R1, c[5].x;\n"
- "MAD R3.xyz, R3, c[5].y, R4;\n"
- "MAD R3.xyz, R0, R2.w, R3;\n"
- "MAD R0.xyz, R0, R2.w, R2;\n"
- "ADD R2.x, R1.w, R0.w;\n"
- "ADD R0.xyz, R0, -R3;\n"
- "SGE R1.xyz, R1, R1.w;\n"
- "MAD result.color.xyz, R1, R0, R3;\n"
- "MAD result.color.w, -R1, R0, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SOFTLIGHT_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[7] = { program.local[0..4],\n"
- " { 1, 2, 9.9999997e-006, 4 },\n"
- " { 16, 12, 3 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "TEMP R4;\n"
- "TEMP R5;\n"
- "TEMP R6;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R1.xyz, R0, c[3];\n"
- "RCP R1.z, R1.z;\n"
- "MUL R1.xy, R1, R1.z;\n"
- "MUL R1.xy, R1, c[0];\n"
- "TEX R1.x, R1, texture[1], 2D;\n"
- "MUL R0.xy, fragment.position, c[4];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "MAX R1.z, R0.w, c[5];\n"
- "RCP R1.z, R1.z;\n"
- "MUL R3.xyz, R0, R1.z;\n"
- "MAD R2.xyz, R3, c[6].x, -c[6].y;\n"
- "ADD R1.x, -R1, c[5];\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MAD R4.xyz, R3, R2, c[6].z;\n"
- "MAD R2.xyz, R1, c[5].y, -R1.w;\n"
- "MUL R5.xyz, R0.w, R2;\n"
- "MUL R6.xyz, R5, R4;\n"
- "RSQ R2.w, R3.x;\n"
- "RCP R4.x, R2.w;\n"
- "RSQ R2.w, R3.y;\n"
- "RSQ R3.w, R3.z;\n"
- "RCP R4.y, R2.w;\n"
- "RCP R4.z, R3.w;\n"
- "ADD R4.xyz, -R3, R4;\n"
- "MUL R6.xyz, R3, R6;\n"
- "MUL R4.xyz, R5, R4;\n"
- "ADD R3.xyz, -R3, c[5].x;\n"
- "MAD R2.xyz, R2, R3, R1.w;\n"
- "MUL R3.xyz, R1, c[5].y;\n"
- "MAD R5.xyz, R1.w, R0, R6;\n"
- "MAD R4.xyz, R1.w, R0, R4;\n"
- "ADD R6.xyz, R4, -R5;\n"
- "MUL R4.xyz, R0, c[5].w;\n"
- "SGE R4.xyz, R4, R0.w;\n"
- "MAD R4.xyz, R4, R6, R5;\n"
- "MAD R4.xyz, -R0, R2, R4;\n"
- "MUL R2.xyz, R0, R2;\n"
- "SGE R3.xyz, R3, R1.w;\n"
- "MAD R2.xyz, R3, R4, R2;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "MAD R2.xyz, R1, R2.w, R2;\n"
- "ADD R1.x, R1.w, R0.w;\n"
- "ADD R1.y, -R1.w, c[5].x;\n"
- "MAD result.color.xyz, R0, R1.y, R2;\n"
- "MAD result.color.w, -R1, R0, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DIFFERENCE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R1.x, -R0, c[5];\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R3.xyz, R1.w, R0;\n"
- "MUL R2.xyz, R1, R0.w;\n"
- "ADD R0.xyz, R1, R0;\n"
- "MIN R2.xyz, R2, R3;\n"
- "ADD R1.x, R1.w, R0.w;\n"
- "MAD result.color.xyz, -R2, c[5].y, R0;\n"
- "MAD result.color.w, -R1, R0, R1.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_EXCLUSION_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[6] = { program.local[0..4],\n"
- " { 1, 2 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "TEMP R2;\n"
- "TEMP R3;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[1], 2D;\n"
- "ADD R1.x, -R0, c[5];\n"
- "MUL R0.zw, fragment.position.xyxy, c[4].xyxy;\n"
- "TEX R0, R0.zwzw, texture[0], 2D;\n"
- "MUL R1, fragment.color.primary, R1.x;\n"
- "MUL R2.xyz, R1.w, R0;\n"
- "MAD R3.xyz, R1, R0.w, R2;\n"
- "MUL R2.xyz, R1, R0;\n"
- "MAD R2.xyz, -R2, c[5].y, R3;\n"
- "ADD R2.w, -R0, c[5].x;\n"
- "MAD R1.xyz, R1, R2.w, R2;\n"
- "ADD R2.x, R1.w, R0.w;\n"
- "ADD R2.y, -R1.w, c[5].x;\n"
- "MAD result.color.xyz, R0, R2.y, R1;\n"
- "MAD result.color.w, -R1, R0, R2.x;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODE_BLEND_MODE_MASK =
- "!!ARBfp1.0\n"
- "PARAM c[8] = { program.local[0..6],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "TEMP R1;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.zw, R0.xyxy, R0.z;\n"
- "MUL R0.zw, R0, c[0].xyxy;\n"
- "TEX R1.x, R0.zwzw, texture[1], 2D;\n"
- "ADD R0.xy, fragment.position, c[5];\n"
- "MUL R0.xy, R0, c[4];\n"
- "TEX R0, R0, texture[0], 2D;\n"
- "DP4 R1.y, R0, c[6];\n"
- "ADD R1.x, -R1, c[7];\n"
- "MUL R0, fragment.color.primary, R1.x;\n"
- "MUL result.color, R0, R1.y;\n"
- "END\n"
- ;
-
-static const char *FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODE_BLEND_MODE_NOMASK =
- "!!ARBfp1.0\n"
- "PARAM c[5] = { program.local[0..3],\n"
- " { 1 } };\n"
- "TEMP R0;\n"
- "MUL R0.xyz, fragment.position.y, c[2];\n"
- "MAD R0.xyz, fragment.position.x, c[1], R0;\n"
- "ADD R0.xyz, R0, c[3];\n"
- "RCP R0.z, R0.z;\n"
- "MUL R0.xy, R0, R0.z;\n"
- "MUL R0.xy, R0, c[0];\n"
- "TEX R0.x, R0, texture[0], 2D;\n"
- "ADD R0.x, -R0, c[4];\n"
- "MUL result.color, fragment.color.primary, R0.x;\n"
- "END\n"
- ;
-
-static const char *mask_fragment_program_sources[num_fragment_masks] = {
- FragmentProgram_FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA,
- FragmentProgram_FRAGMENT_PROGRAM_MASK_ELLIPSE_AA,
-};
-
-static const char *painter_fragment_program_sources[num_fragment_brushes][num_fragment_composition_modes] = {
- {
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SIMPLE_PORTER_DUFF,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_MULTIPLY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SCREEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_OVERLAY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DARKEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_LIGHTEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORDODGE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORBURN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_HARDLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SOFTLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DIFFERENCE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_EXCLUSION,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_MULTIPLY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SCREEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_OVERLAY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DARKEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_LIGHTEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORDODGE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_COLORBURN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_HARDLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_SOFTLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_DIFFERENCE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODES_EXCLUSION_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODE_BLEND_MODE_MASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_SOLID_COMPOSITION_MODE_BLEND_MODE_NOMASK,
- },
- {
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_MULTIPLY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SCREEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_OVERLAY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DARKEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_LIGHTEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORDODGE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORBURN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_HARDLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SOFTLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DIFFERENCE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_EXCLUSION,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_MULTIPLY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SCREEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_OVERLAY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DARKEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_LIGHTEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORDODGE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_COLORBURN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_HARDLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_SOFTLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_DIFFERENCE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODES_EXCLUSION_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODE_BLEND_MODE_MASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_RADIAL_COMPOSITION_MODE_BLEND_MODE_NOMASK,
- },
- {
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_MULTIPLY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SCREEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_OVERLAY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DARKEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_LIGHTEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORDODGE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORBURN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_HARDLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SOFTLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DIFFERENCE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_EXCLUSION,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_MULTIPLY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SCREEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_OVERLAY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DARKEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_LIGHTEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORDODGE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_COLORBURN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_HARDLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_SOFTLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_DIFFERENCE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODES_EXCLUSION_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODE_BLEND_MODE_MASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_CONICAL_COMPOSITION_MODE_BLEND_MODE_NOMASK,
- },
- {
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SIMPLE_PORTER_DUFF,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_MULTIPLY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SCREEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_OVERLAY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DARKEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_LIGHTEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORDODGE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORBURN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_HARDLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SOFTLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DIFFERENCE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_EXCLUSION,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_MULTIPLY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SCREEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_OVERLAY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DARKEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_LIGHTEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORDODGE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_COLORBURN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_HARDLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_SOFTLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_DIFFERENCE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODES_EXCLUSION_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODE_BLEND_MODE_MASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_LINEAR_COMPOSITION_MODE_BLEND_MODE_NOMASK,
- },
- {
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SIMPLE_PORTER_DUFF,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_MULTIPLY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SCREEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_OVERLAY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DARKEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_LIGHTEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORDODGE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORBURN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_HARDLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SOFTLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DIFFERENCE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_EXCLUSION,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_MULTIPLY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SCREEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_OVERLAY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DARKEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_LIGHTEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORDODGE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_COLORBURN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_HARDLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_SOFTLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_DIFFERENCE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODES_EXCLUSION_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODE_BLEND_MODE_MASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_TEXTURE_COMPOSITION_MODE_BLEND_MODE_NOMASK,
- },
- {
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SIMPLE_PORTER_DUFF,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_MULTIPLY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SCREEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_OVERLAY,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DARKEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_LIGHTEN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORDODGE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORBURN,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_HARDLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SOFTLIGHT,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DIFFERENCE,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_EXCLUSION,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SIMPLE_PORTER_DUFF_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_MULTIPLY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SCREEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_OVERLAY_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DARKEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_LIGHTEN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORDODGE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_COLORBURN_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_HARDLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_SOFTLIGHT_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_DIFFERENCE_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODES_EXCLUSION_NOMASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODE_BLEND_MODE_MASK,
- FragmentProgram_FRAGMENT_PROGRAM_BRUSH_PATTERN_COMPOSITION_MODE_BLEND_MODE_NOMASK,
- },
-};
-
-static int painter_variable_locations[num_fragment_brushes][num_fragment_composition_modes][num_fragment_variables] = {
- {
- { -1, -1, -1, 2, -1, 0, 5, -1, 1, 3, 1, 0, -1, 4, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 3, -1, -1, 1, 1, 0, -1, 2, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, 0, -1, -1, 1, 2, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, 0, -1, -1, 2, -1, -1, -1, 0, -1, -1, 1, -1, -1, -1, -1, -1, },
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
- },
- {
- { -1, -1, 3, 7, 4, 5, 10, -1, 6, 8, 1, 0, 2, 9, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 8, -1, -1, 6, 1, 0, 2, 7, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, 5, -1, -1, 6, 7, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, 5, -1, 0, 1, -1, -1, 1, 0, 2, -1, },
- { -1, -1, 3, 5, 4, -1, 7, -1, -1, -1, 0, -1, 1, 6, -1, 1, 0, 2, -1, },
- { -1, -1, 3, -1, 4, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, 0, 2, -1, },
- },
- {
- { -1, -1, 2, 6, 3, 4, 9, -1, 5, 7, 1, 0, 2, 8, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, 4, -1, -1, 5, 6, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, 0, },
- { -1, -1, 2, 4, 3, -1, 6, -1, -1, -1, 0, -1, 1, 5, -1, -1, -1, 1, 0, },
- { -1, -1, 2, -1, 3, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, 1, 0, },
- },
- {
- { -1, 0, 2, 6, 3, 4, 9, -1, 5, 7, 1, 0, 2, 8, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, 2, 6, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, 4, -1, -1, 5, 6, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, 1, -1, -1, -1, -1, 1, -1, },
- { -1, 0, 2, 4, 3, -1, 6, -1, -1, -1, 0, -1, 1, 5, -1, -1, -1, 1, -1, },
- { -1, 0, 2, -1, 3, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, 1, -1, },
- },
- {
- { 2, -1, 2, 6, 3, 4, 9, -1, 5, 7, 1, 0, -1, 8, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, 4, -1, -1, 5, 6, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, 4, 3, -1, 6, -1, -1, -1, 0, -1, -1, 5, 0, -1, -1, 1, -1, },
- { 0, -1, 2, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, },
- },
- {
- { 2, -1, 2, 6, 3, 4, 9, -1, 5, 7, 1, 0, -1, 8, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 2, -1, 2, 4, 3, -1, 7, -1, -1, 5, 1, 0, -1, 6, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, 4, -1, -1, 5, 6, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, -1, 3, -1, -1, -1, -1, 4, -1, 0, -1, -1, 0, -1, -1, 1, -1, },
- { 1, -1, 2, 4, 3, -1, 6, -1, -1, -1, 0, -1, -1, 5, 0, -1, -1, 1, -1, },
- { 0, -1, 2, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, },
- },
-};
-
-static int mask_variable_locations[num_fragment_masks][num_fragment_variables] = {
- { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, },
- { -1, -1, 1, -1, 2, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, },
-};
-
-#endif
diff --git a/src/opengl/util/generator.cpp b/src/opengl/util/generator.cpp
deleted file mode 100644
index 3d12446842..0000000000
--- a/src/opengl/util/generator.cpp
+++ /dev/null
@@ -1,500 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QFile>
-#include <QList>
-#include <QMap>
-#include <QPair>
-#include <QSet>
-#include <QString>
-#include <QTextStream>
-
-#include <QtDebug>
-#include <cstdlib>
-
-QT_BEGIN_NAMESPACE
-
-QT_USE_NAMESPACE
-
-#define TAB " "
-
-typedef QPair<QString, QString> QStringPair;
-
-QString readSourceFile(const QString &sourceFile, bool fragmentProgram = false)
-{
- QFile file(sourceFile);
-
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qDebug() << "Missing source file" << sourceFile;
- exit(0);
- }
-
- QString source;
-
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString line = in.readLine();
-
- if (fragmentProgram && line[0] == '#' && !line.startsWith("#var"))
- continue;
-
- if (fragmentProgram)
- source.append(" \"");
-
- source.append(line);
-
- if (fragmentProgram)
- source.append("\\n\"");
-
- source.append('\n');
- }
-
- if (fragmentProgram)
- source.append(" ;\n");
-
- return source;
-}
-
-QList<QStringPair> readConf(const QString &confFile)
-{
- QFile file(confFile);
-
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qDebug() << "Missing file" << confFile;
- exit(0);
- }
-
- QList<QStringPair> result;
-
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString line = in.readLine();
-
- if (line.startsWith('#'))
- continue;
-
- QTextStream lineStream(&line);
-
- QString enumerator;
- QString sourceFile;
-
- lineStream >> enumerator;
-
- if (lineStream.atEnd()) {
- qDebug() << "Error in file" << confFile << '(' << enumerator << ')';
- exit(0);
- }
-
- lineStream >> sourceFile;
-
- result << QStringPair(enumerator, readSourceFile(sourceFile));
- }
-
- return result;
-}
-
-QString compileSource(const QString &source)
-{
- {
- QFile tempSourceFile("__tmp__.glsl");
- if (!tempSourceFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
- qDebug() << "Failed opening __tmp__.glsl";
- exit(0);
- }
-
- QTextStream out(&tempSourceFile);
- out << source;
- }
-
- if (std::system("cgc -quiet -oglsl -profile arbfp1 __tmp__.glsl >__tmp__.frag") == -1) {
- qDebug() << "Failed running cgc";
- exit(0);
- }
-
- return readSourceFile("__tmp__.frag", true);
-}
-
-QString getWord(QString line, int word)
-{
- QTextStream in(&line);
-
- QString result;
-
- for (int i = 0; i < word; ++i)
- in >> result;
-
- return result;
-}
-
-static int toInt(const QByteArray &str)
-{
- int value = 0;
-
- for (int i = 0; i < str.size(); ++i) {
- if (str[i] < '0' || str[i] > '9')
- break;
-
- value *= 10;
- value += (str[i] - '0');
- }
-
- return value;
-}
-QList<int> getLocations(const QSet<QString> &variables, QString source)
-{
- QTextStream in(&source);
-
- QMap<QString, int> locations;
-
- foreach (QString variable, variables)
- locations[variable] = -1;
-
- while (!in.atEnd()) {
- QString line = in.readLine().trimmed();
-
- line = line.right(line.size() - 1);
-
- if (line.startsWith("#var")) {
- QByteArray temp;
- QByteArray name;
-
- QTextStream lineStream(&line);
-
- lineStream >> temp >> temp >> name;
-
- int location = -1;
-
- while (!lineStream.atEnd()) {
- lineStream >> temp;
-
- if (temp.startsWith("c[")) {
- location = toInt(temp.right(temp.size() - 2));
- break;
- }
-
- if (temp == "texunit") {
- lineStream >> temp;
- location = toInt(temp);
- break;
- }
- }
-
- locations[name] = location;
- }
- }
-
- QList<int> result;
-
- foreach (QString variable, variables)
- result << locations[variable];
-
- return result;
-}
-
-// remove #var statements
-QString trimmed(QString source)
-{
- QTextStream in(&source);
-
- QString result;
-
- while (!in.atEnd()) {
- QString line = in.readLine();
- if (!line.trimmed().startsWith("\"#"))
- result += line + '\n';
- }
-
- return result;
-}
-
-void writeVariablesEnum(QTextStream &out, const char *name, const QSet<QString> &s)
-{
- out << "enum " << name << " {";
- QSet<QString>::const_iterator it = s.begin();
- if (it != s.end()) {
- out << "\n" TAB "VAR_" << it->toUpper();
- for (++it; it != s.end(); ++it)
- out << ",\n" TAB "VAR_" << it->toUpper();
- }
- out << "\n};\n\n";
-}
-
-void writeTypesEnum(QTextStream &out, const char *name, const QList<QStringPair> &s)
-{
- out << "enum " << name << " {";
- QList<QStringPair>::const_iterator it = s.begin();
- if (it != s.end()) {
- out << "\n" TAB << it->first;
- for (++it; it != s.end(); ++it)
- out << ",\n" TAB << it->first;
- }
- out << "\n};\n\n";
-}
-
-void writeIncludeFile(const QSet<QString> &variables,
- const QList<QStringPair> &brushes,
- const QList<QStringPair> &compositionModes,
- const QList<QStringPair> &masks,
- const QMap<QString, QMap<QString, QString> > &compiled)
-{
- QFile includeFile("fragmentprograms_p.h");
- if (!includeFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
- qDebug() << "Failed opening fragmentprograms_p.h";
- exit(0);
- }
-
- QTextStream out(&includeFile);
-
- QLatin1String tab(TAB);
-
- out << "/****************************************************************************\n"
- "**\n"
- "** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).\n"
- "** All rights reserved.\n"
- "** Contact: Nokia Corporation (qt-info@nokia.com)\n"
- "**\n"
- "** This file is part of the QtOpenGL module of the Qt Toolkit.\n"
- "**\n"
- "** $QT_BEGIN_LICENSE:LGPL$\n"
- "** GNU Lesser General Public License Usage\n"
- "** This file may be used under the terms of the GNU Lesser General Public\n"
- "** License version 2.1 as published by the Free Software Foundation and\n"
- "** appearing in the file LICENSE.LGPL included in the packaging of this\n"
- "** file. Please review the following information to ensure the GNU Lesser\n"
- "** General Public License version 2.1 requirements will be met:\n"
- "** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.\n"
- "**\n"
- "** In addition, as a special exception, Nokia gives you certain additional\n"
- "** rights. These rights are described in the Nokia Qt LGPL Exception\n"
- "** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.\n"
- "**\n"
- "** GNU General Public License Usage\n"
- "** Alternatively, this file may be used under the terms of the GNU General\n"
- "** Public License version 3.0 as published by the Free Software Foundation\n"
- "** and appearing in the file LICENSE.GPL included in the packaging of this\n"
- "** file. Please review the following information to ensure the GNU General\n"
- "** Public License version 3.0 requirements will be met:\n"
- "** http://www.gnu.org/copyleft/gpl.html.\n"
- "**\n"
- "** Other Usage\n"
- "** Alternatively, this file may be used in accordance with the terms and\n"
- "** conditions contained in a signed written agreement between you and Nokia.\n"
- "**\n"
- "**\n"
- "**\n"
- "**\n"
- "**\n"
- "** $QT_END_LICENSE$\n"
- "**\n"
- "****************************************************************************/\n"
- "\n"
- "#ifndef FRAGMENTPROGRAMS_P_H\n"
- "#define FRAGMENTPROGRAMS_P_H\n"
- "\n"
- "//\n"
- "// W A R N I N G\n"
- "// -------------\n"
- "//\n"
- "// This file is not part of the Qt API. It exists purely as an\n"
- "// implementation detail. This header file may change from version to\n"
- "// version without notice, or even be removed.\n"
- "//\n"
- "// We mean it.\n"
- "//\n"
- "\n";
-
- writeVariablesEnum(out, "FragmentVariable", variables);
- writeTypesEnum(out, "FragmentBrushType", brushes);
- writeTypesEnum(out, "FragmentCompositionModeType", compositionModes);
- writeTypesEnum(out, "FragmentMaskType", masks);
-
- out << "static const unsigned int num_fragment_variables = " << variables.size() << ";\n\n";
- out << "static const unsigned int num_fragment_brushes = " << brushes.size() << ";\n";
- out << "static const unsigned int num_fragment_composition_modes = " << compositionModes.size() << ";\n";
- out << "static const unsigned int num_fragment_masks = " << masks.size() << ";\n\n";
-
- foreach (QStringPair mask, masks) {
- const QString compiledSource = compiled[mask.first]["MASK__"];
-
- out << "static const char *FragmentProgram_" << mask.first << " =\n"
- << trimmed(compiledSource)
- << '\n';
- }
-
- foreach (QStringPair brush, brushes) {
- foreach (QStringPair mode, compositionModes) {
- const QString compiledSource = compiled[brush.first][mode.first];
-
- out << "static const char *FragmentProgram_" << brush.first << '_' << mode.first << " =\n"
- << trimmed(compiledSource)
- << '\n';
- }
- }
-
- out << "static const char *mask_fragment_program_sources[num_fragment_masks] = {\n";
- foreach (QStringPair mask, masks)
- out << tab << "FragmentProgram_" << mask.first << ",\n";
- out << "};\n\n";
-
- out << "static const char *painter_fragment_program_sources[num_fragment_brushes][num_fragment_composition_modes] = {\n";
- foreach (QStringPair brush, brushes) {
- out << tab << "{\n";
-
- foreach (QStringPair mode, compositionModes)
- out << tab << tab << "FragmentProgram_" << brush.first << '_' << mode.first << ",\n";
-
- out << tab << "},\n";
- }
- out << "};\n\n";
-
- out << "static int painter_variable_locations[num_fragment_brushes][num_fragment_composition_modes][num_fragment_variables] = {\n";
- foreach (QStringPair brush, brushes) {
- out << tab << "{\n";
-
- foreach (QStringPair mode, compositionModes) {
- out << tab << tab << "{ ";
-
- QList<int> locations = getLocations(variables, compiled[brush.first][mode.first]);
-
- foreach (int location, locations)
- out << location << ", ";
-
- out << "},\n";
- }
-
- out << tab << "},\n";
- }
- out << "};\n\n";
-
- out << "static int mask_variable_locations[num_fragment_masks][num_fragment_variables] = {\n";
- foreach (QStringPair mask, masks) {
- out << tab << "{ ";
-
- QList<int> locations = getLocations(variables, compiled[mask.first]["MASK__"]);
-
- foreach (int location, locations)
- out << location << ", ";
-
- out << "},\n";
- }
- out << "};\n\n";
- out << "#endif\n";
-}
-
-QList<QString> getVariables(QString program)
-{
- QList<QString> result;
-
- QTextStream in(&program);
- while (!in.atEnd()) {
- QString line = in.readLine();
-
- if (line.startsWith("uniform")) {
- QString word = getWord(line, 3);
- result << word.left(word.size() - 1);
- } else if (line.startsWith("#include")) {
- QString file = getWord(line, 2);
- result << getVariables(readSourceFile(file.mid(1, file.size() - 2)));
- }
- }
-
- return result;
-}
-
-int main()
-{
- QList<QStringPair> brushes = readConf(QLatin1String("brushes.conf"));
- QList<QStringPair> compositionModes = readConf(QLatin1String("composition_modes.conf"));
- QList<QStringPair> masks = readConf(QLatin1String("masks.conf"));
-
- QString painterSource = readSourceFile("painter.glsl");
- QString painterNoMaskSource = readSourceFile("painter_nomask.glsl");
- QString fastPainterSource = readSourceFile("fast_painter.glsl");
- QString brushPainterSource = readSourceFile("brush_painter.glsl");
-
- QSet<QString> variables;
-
- QList<QStringPair> programs[3] = { brushes, compositionModes, masks };
-
- for (int i = 0; i < 3; ++i)
- foreach (QStringPair value, programs[i])
- variables += QSet<QString>::fromList(getVariables(value.second));
-
- variables += QSet<QString>::fromList(getVariables(painterSource));
- variables += QSet<QString>::fromList(getVariables(fastPainterSource));
-
- QMap<QString, QMap<QString, QString> > compiled;
-
- foreach (QStringPair brush, brushes) {
- foreach (QStringPair mode, compositionModes) {
- QString combinedSource = brush.second + mode.second + painterSource;
- compiled[brush.first][mode.first] = compileSource(combinedSource);
-
- combinedSource = brush.second + mode.second + painterNoMaskSource;
- compiled[brush.first][mode.first + "_NOMASK"] = compileSource(combinedSource);
- }
-
- QString fastSource = brush.second + fastPainterSource;
- QString brushSource = brush.second + brushPainterSource;
-
- compiled[brush.first]["COMPOSITION_MODE_BLEND_MODE_MASK"] = compileSource(fastSource);
- compiled[brush.first]["COMPOSITION_MODE_BLEND_MODE_NOMASK"] = compileSource(brushSource);
- }
-
- QList<QStringPair> temp;
-
- foreach (QStringPair mode, compositionModes)
- temp << QStringPair(mode.first + "_NOMASK", mode.second);
-
- compositionModes += temp;
-
- compositionModes << QStringPair("COMPOSITION_MODE_BLEND_MODE_MASK", "")
- << QStringPair("COMPOSITION_MODE_BLEND_MODE_NOMASK", "");
-
- foreach (QStringPair mask, masks)
- compiled[mask.first]["MASK__"] = compileSource(mask.second);
-
- writeIncludeFile(variables, brushes, compositionModes, masks, compiled);
-
- return 0;
-}
-
-QT_END_NAMESPACE
diff --git a/src/opengl/util/generator.pro b/src/opengl/util/generator.pro
deleted file mode 100644
index ac71934ecf..0000000000
--- a/src/opengl/util/generator.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-######################################################################
-# Automatically generated by qmake (2.01a) Thu Oct 19 11:03:24 2006
-######################################################################
-
-TEMPLATE = app
-TARGET = generator
-DEPENDPATH += .
-INCLUDEPATH += .
-
-# Input
-SOURCES += generator.cpp
-
-CONFIG += console
diff --git a/src/opengl/util/glsl_to_include.sh b/src/opengl/util/glsl_to_include.sh
deleted file mode 100755
index c97239bfdd..0000000000
--- a/src/opengl/util/glsl_to_include.sh
+++ /dev/null
@@ -1,73 +0,0 @@
-#! /bin/sh
-#############################################################################
-##
-## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-## All rights reserved.
-## Contact: Nokia Corporation (qt-info@nokia.com)
-##
-## This file is the build configuration utility of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## GNU Lesser General Public License Usage
-## This file may be used under the terms of the GNU Lesser General Public
-## License version 2.1 as published by the Free Software Foundation and
-## appearing in the file LICENSE.LGPL included in the packaging of this
-## file. Please review the following information to ensure the GNU Lesser
-## General Public License version 2.1 requirements will be met:
-## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-##
-## In addition, as a special exception, Nokia gives you certain additional
-## rights. These rights are described in the Nokia Qt LGPL Exception
-## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU General
-## Public License version 3.0 as published by the Free Software Foundation
-## and appearing in the file LICENSE.GPL included in the packaging of this
-## file. Please review the following information to ensure the GNU General
-## Public License version 3.0 requirements will be met:
-## http://www.gnu.org/copyleft/gpl.html.
-##
-## Other Usage
-## Alternatively, this file may be used in accordance with the terms and
-## conditions contained in a signed written agreement between you and Nokia.
-##
-##
-##
-##
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-# Compile a .glsl file to a file that can be included in a C++ program
-USAGE="Usage: $0 <file.glsl>"
-CGC=cgc
-CGC_PROFILE=arbfp1
-
-if test $# -ne 1
-then
- echo $USAGE
- exit 1
-fi
-
-GLSL_FILE=$1
-FRAG_FILE=`basename $1 .glsl`.frag
-#GLSL_INC_FILE=`basename $1 .glsl`.glsl_quoted
-
-echo "// Generated by src/opengl/util/$0 from $1" > $FRAG_FILE
-$CGC -quiet -oglsl -profile $CGC_PROFILE $GLSL_FILE | while read line
-do
- if test `echo $line | cut -c1` != "#"
- then
- echo -e \"$line\" >> $FRAG_FILE
- fi
-done
-echo "; // Generated by src/opengl/util/$0 from $1" >> $FRAG_FILE
-
-#echo "// Generated by src/opengl/util/$0 from $1" > $GLSL_INC_FILE
-#cat $GLSL_FILE | while read line
-#do
-# printf \"%s\\\\n\"\\n "$line" >> $GLSL_INC_FILE
-#done
-#echo "; // Generated by src/opengl/util/$0 from $1" >> $GLSL_INC_FILE
diff --git a/src/opengl/util/linear_brush.glsl b/src/opengl/util/linear_brush.glsl
deleted file mode 100644
index 90a4440a99..0000000000
--- a/src/opengl/util/linear_brush.glsl
+++ /dev/null
@@ -1,22 +0,0 @@
-uniform sampler1D palette;
-uniform vec3 linear;
-uniform vec3 inv_matrix_m0;
-uniform vec3 inv_matrix_m1;
-uniform vec3 inv_matrix_m2;
-
-vec4 brush()
-{
- mat3 mat;
-
- mat[0] = inv_matrix_m0;
- mat[1] = inv_matrix_m1;
- mat[2] = inv_matrix_m2;
-
- vec3 hcoords = mat * vec3(gl_FragCoord.xy, 1);
- vec2 A = hcoords.xy / hcoords.z;
-
- float val = dot(linear.xy, A) * linear.z;
-
- return texture1D(palette, val);
-}
-
diff --git a/src/opengl/util/masks.conf b/src/opengl/util/masks.conf
deleted file mode 100644
index d853d0b6e9..0000000000
--- a/src/opengl/util/masks.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA trap_exact_aa.glsl
-FRAGMENT_PROGRAM_MASK_ELLIPSE_AA ellipse_aa.glsl
diff --git a/src/opengl/util/meego/main.cpp b/src/opengl/util/meego/main.cpp
deleted file mode 100644
index 21ac5fd629..0000000000
--- a/src/opengl/util/meego/main.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtOpenGL module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/qdebug.h>
-
-#define QT_DEBUG_SHADER_CACHE
-#define QT_MEEGO_EXPERIMENTAL_SHADERCACHE
-#define QT_OPENGL_ES_2
-#define QT_BOOTSTRAPPED
-
-typedef int GLsizei;
-typedef unsigned int GLenum;
-
-#include "../../gl2paintengineex/qglshadercache_meego_p.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-
-int main()
-{
- ShaderCacheSharedMemory shm;
-
- if (!shm.isAttached()) {
- fprintf(stderr, "Unable to attach to shared memory\n");
- return EXIT_FAILURE;
- }
-
- ShaderCacheLocker locker(&shm);
- if (!locker.isLocked()) {
- fprintf(stderr, "Unable to lock shared memory\n");
- return EXIT_FAILURE;
- }
-
- void *data = shm.data();
- Q_ASSERT(data);
-
- CachedShaders *cache = reinterpret_cast<CachedShaders *>(data);
-
- for (int i = 0; i < cache->shaderCount; ++i) {
- printf("Shader %d: %d bytes\n", i, cache->headers[i].size);
- }
-
- printf("\nSummary:\n\n"
- " Amount of cached shaders: %d\n"
- " Bytes used: %d\n"
- " Bytes available: %d\n",
- cache->shaderCount, cache->dataSize, cache->availableSize());
-
- return EXIT_SUCCESS;
-}
-
diff --git a/src/opengl/util/meego/shader-cache-introspector.pro b/src/opengl/util/meego/shader-cache-introspector.pro
deleted file mode 100644
index 520e9a5108..0000000000
--- a/src/opengl/util/meego/shader-cache-introspector.pro
+++ /dev/null
@@ -1,7 +0,0 @@
-TEMPLATE = app
-
-SOURCES += main.cpp
-
-TARGET = shader-cache-introspector
-
-QT = core
diff --git a/src/opengl/util/painter.glsl b/src/opengl/util/painter.glsl
deleted file mode 100644
index b990234778..0000000000
--- a/src/opengl/util/painter.glsl
+++ /dev/null
@@ -1,21 +0,0 @@
-uniform sampler2D dst_texture;
-uniform sampler2D mask_texture;
-uniform vec2 inv_mask_size;
-uniform vec2 inv_dst_size;
-uniform vec2 mask_offset;
-uniform vec4 mask_channel;
-
-float mask()
-{
- return dot(mask_channel, texture2D(mask_texture, (gl_FragCoord.xy + mask_offset) * inv_mask_size));
-}
-
-void main()
-{
- vec4 dst = texture2D(dst_texture, gl_FragCoord.xy * inv_dst_size);
-
- // combine clip and coverage channels
- float mask_alpha = mask();
-
- gl_FragColor = mix(dst, composite(brush(), dst), mask_alpha);
-}
diff --git a/src/opengl/util/painter_nomask.glsl b/src/opengl/util/painter_nomask.glsl
deleted file mode 100644
index af5ad6505f..0000000000
--- a/src/opengl/util/painter_nomask.glsl
+++ /dev/null
@@ -1,9 +0,0 @@
-uniform sampler2D dst_texture;
-uniform vec2 inv_dst_size;
-
-void main()
-{
- vec4 dst = texture2D(dst_texture, gl_FragCoord.xy * inv_dst_size);
-
- gl_FragColor = composite(brush(), dst);
-}
diff --git a/src/opengl/util/pattern_brush.glsl b/src/opengl/util/pattern_brush.glsl
deleted file mode 100644
index 31702b887c..0000000000
--- a/src/opengl/util/pattern_brush.glsl
+++ /dev/null
@@ -1,23 +0,0 @@
-uniform sampler2D brush_texture;
-uniform vec2 inv_brush_texture_size;
-uniform vec3 inv_matrix_m0;
-uniform vec3 inv_matrix_m1;
-uniform vec3 inv_matrix_m2;
-
-vec4 brush()
-{
- mat3 mat;
-
- mat[0] = inv_matrix_m0;
- mat[1] = inv_matrix_m1;
- mat[2] = inv_matrix_m2;
-
- vec3 hcoords = mat * vec3(gl_FragCoord.xy, 1);
- vec2 coords = hcoords.xy / hcoords.z;
-
- coords *= inv_brush_texture_size;
-
- float alpha = 1.0 - texture2D(brush_texture, coords).r;
-
- return gl_Color * alpha;
-}
diff --git a/src/opengl/util/radial_brush.glsl b/src/opengl/util/radial_brush.glsl
deleted file mode 100644
index 84bec62e65..0000000000
--- a/src/opengl/util/radial_brush.glsl
+++ /dev/null
@@ -1,28 +0,0 @@
-uniform sampler1D palette;
-uniform vec2 fmp;
-uniform float fmp2_m_radius2;
-uniform vec3 inv_matrix_m0;
-uniform vec3 inv_matrix_m1;
-uniform vec3 inv_matrix_m2;
-
-vec4 brush()
-{
- mat3 mat;
-
- mat[0] = inv_matrix_m0;
- mat[1] = inv_matrix_m1;
- mat[2] = inv_matrix_m2;
-
- vec3 hcoords = mat * vec3(gl_FragCoord.xy, 1);
- vec2 A = hcoords.xy / hcoords.z;
- vec2 B = fmp;
-
- float a = fmp2_m_radius2;
- float b = 2.0*dot(A, B);
- float c = -dot(A, A);
-
- float val = (-b + sqrt(b*b - 4.0*a*c)) / (2.0*a);
-
- return texture1D(palette, val);
-}
-
diff --git a/src/opengl/util/simple_porter_duff.glsl b/src/opengl/util/simple_porter_duff.glsl
deleted file mode 100644
index 4cb0599ac5..0000000000
--- a/src/opengl/util/simple_porter_duff.glsl
+++ /dev/null
@@ -1,16 +0,0 @@
-uniform vec2 porterduff_ab;
-uniform vec3 porterduff_xyz;
-
-vec4 composite(vec4 src, vec4 dst)
-{
- vec4 result;
-
- result.xyz = porterduff_ab.x * src.xyz * dst.a
- + porterduff_ab.y * dst.xyz * src.a
- + porterduff_xyz.y * src.xyz * (1.0 - dst.a)
- + porterduff_xyz.z * dst.xyz * (1.0 - src.a);
-
- result.a = dot(porterduff_xyz, vec3(src.a * dst.a, src.a * (1.0 - dst.a), dst.a * (1.0 - src.a)));
-
- return result;
-}
diff --git a/src/opengl/util/solid_brush.glsl b/src/opengl/util/solid_brush.glsl
deleted file mode 100644
index 760afd1a72..0000000000
--- a/src/opengl/util/solid_brush.glsl
+++ /dev/null
@@ -1,4 +0,0 @@
-vec4 brush()
-{
- return gl_Color;
-}
diff --git a/src/opengl/util/texture_brush.glsl b/src/opengl/util/texture_brush.glsl
deleted file mode 100644
index 949825583f..0000000000
--- a/src/opengl/util/texture_brush.glsl
+++ /dev/null
@@ -1,21 +0,0 @@
-uniform sampler2D brush_texture;
-uniform vec2 inv_brush_texture_size;
-uniform vec3 inv_matrix_m0;
-uniform vec3 inv_matrix_m1;
-uniform vec3 inv_matrix_m2;
-
-vec4 brush()
-{
- mat3 mat;
-
- mat[0] = inv_matrix_m0;
- mat[1] = inv_matrix_m1;
- mat[2] = inv_matrix_m2;
-
- vec3 hcoords = mat * vec3(gl_FragCoord.xy, 1);
- vec2 coords = hcoords.xy / hcoords.z;
-
- coords *= inv_brush_texture_size;
-
- return texture2D(brush_texture, coords);
-}
diff --git a/src/opengl/util/trap_exact_aa.glsl b/src/opengl/util/trap_exact_aa.glsl
deleted file mode 100644
index 1637f430b5..0000000000
--- a/src/opengl/util/trap_exact_aa.glsl
+++ /dev/null
@@ -1,58 +0,0 @@
-float quad_aa()
-{
- float top = min(gl_FragCoord.y + 0.5, gl_TexCoord[0].x);
- float bottom = max(gl_FragCoord.y - 0.5, gl_TexCoord[0].y);
-
- float area = top - bottom;
-
- float left = gl_FragCoord.x - 0.5;
- float right = gl_FragCoord.x + 0.5;
-
- // use line equations to compute intersections of left/right edges with top/bottom of truncated pixel
- vec4 vecX = gl_TexCoord[1].xxzz * vec2(top, bottom).xyxy + gl_TexCoord[1].yyww;
-
- vec2 invA = gl_TexCoord[0].zw;
-
- // transform right line to left to be able to use same calculations for both
- vecX.zw = 2.0 * gl_FragCoord.x - vecX.zw;
-
- vec2 topX = vec2(vecX.x, vecX.z);
- vec2 bottomX = vec2(vecX.y, vecX.w);
-
- // transform lines such that top intersection is to the right of bottom intersection
- vec2 topXTemp = max(topX, bottomX);
- vec2 bottomXTemp = min(topX, bottomX);
-
- // make sure line slope reflects mirrored lines
- invA = mix(invA, -invA, step(topX, bottomX));
-
- vec2 vecLeftRight = vec2(left, right);
-
- // compute the intersections of the lines with the left and right edges of the pixel
- vec4 intersectY = bottom + (vecLeftRight.xyxy - bottomXTemp.xxyy) * invA.xxyy;
-
- vec2 temp = mix(area - 0.5 * (right - bottomXTemp) * (intersectY.yw - bottom), // left < bottom < right < top
- (0.5 * (topXTemp + bottomXTemp) - left) * area, // left < bottom < top < right
- step(topXTemp, right.xx));
-
- vec2 excluded = 0.5 * (top - intersectY.xz) * (topXTemp - left); // bottom < left < top < right
-
- excluded = mix((top - 0.5 * (intersectY.yw + intersectY.xz)) * (right - left), // bottom < left < right < top
- excluded, step(topXTemp, right.xx));
-
- excluded = mix(temp, // left < bottom < right (see calculation of temp)
- excluded, step(bottomXTemp, left.xx));
-
- excluded = mix(vec2(area, area), // right < bottom < top
- excluded, step(bottomXTemp, right.xx));
-
- excluded *= step(left, topXTemp);
-
- return (area - excluded.x - excluded.y) * step(bottom, top);
-}
-
-void main()
-{
- gl_FragColor = quad_aa().xxxx;
-}
-