summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
authorGareth Stockwell <gareth.stockwell@sosco.com>2009-09-29 16:09:17 (GMT)
committerGareth Stockwell <gareth.stockwell@sosco.com>2009-09-29 16:09:17 (GMT)
commit1cbe6b2126a10ad846167d147b4cfbf3c6d9b402 (patch)
tree84b9ac33707f194cb34c753f91f9c948e2593510 /src/opengl
parentd34bbd852241fcd9ddf50c961b5e234f9de0b5ac (diff)
parent17c17adbd706d32723ecedeb207c7e467f9fa8eb (diff)
downloadQt-1cbe6b2126a10ad846167d147b4cfbf3c6d9b402.zip
Qt-1cbe6b2126a10ad846167d147b4cfbf3c6d9b402.tar.gz
Qt-1cbe6b2126a10ad846167d147b4cfbf3c6d9b402.tar.bz2
Merge branch 'mmfphonon' of git@scm.dev.nokia.troll.no:qt/qt-s60-public into mmfphonon
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp48
-rw-r--r--src/opengl/qgl.cpp20
-rw-r--r--src/opengl/qgl_egl.cpp89
-rw-r--r--src/opengl/qgl_p.h1
-rw-r--r--src/opengl/qgl_qws.cpp107
-rw-r--r--src/opengl/qgl_win.cpp6
-rw-r--r--src/opengl/qgl_wince.cpp96
-rw-r--r--src/opengl/qgl_x11.cpp92
-rw-r--r--src/opengl/qgl_x11egl.cpp106
-rw-r--r--src/opengl/qglframebufferobject.cpp17
-rw-r--r--src/opengl/qglpixelbuffer.cpp1
-rw-r--r--src/opengl/qglpixelbuffer_egl.cpp5
-rw-r--r--src/opengl/qglpixelbuffer_x11.cpp33
-rw-r--r--src/opengl/qglpixmapfilter.cpp16
-rw-r--r--src/opengl/qpixmapdata_gl.cpp26
-rw-r--r--src/opengl/qwindowsurface_gl.cpp75
16 files changed, 351 insertions, 387 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 9db1de8..7e45fd9 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -85,6 +85,8 @@
QT_BEGIN_NAMESPACE
+//#define QT_GL_NO_SCISSOR_TEST
+
static const GLuint QT_BRUSH_TEXTURE_UNIT = 0;
static const GLuint QT_IMAGE_TEXTURE_UNIT = 0; //Can be the same as brush texture unit
static const GLuint QT_MASK_TEXTURE_UNIT = 1;
@@ -127,7 +129,7 @@ public Q_SLOTS:
// since the context holding the texture is shared, and
// about to be destroyed, we have to transfer ownership
// of the texture to one of the share contexts
- ctx = const_cast<QGLContext *>(shares.at(0));
+ ctx = const_cast<QGLContext *>((ctx == shares.at(0)) ? shares.at(1) : shares.at(0));
}
}
}
@@ -756,6 +758,8 @@ void QGL2PaintEngineEx::beginNativePainting()
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&mv_matrix[0][0]);
+#else
+ Q_UNUSED(ctx);
#endif
d->lastTexture = GLuint(-1);
@@ -1205,7 +1209,9 @@ void QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const
ensureActive();
d->transferMode(ImageDrawingMode);
+#ifndef QT_OPENGL_ES_2
QGLContext *ctx = d->ctx;
+#endif
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
glBindTexture(GL_TEXTURE_2D, textureId);
@@ -1533,6 +1539,7 @@ void QGL2PaintEngineExPrivate::updateDepthScissorTest()
else
glDisable(GL_DEPTH_TEST);
+#ifndef QT_GL_NO_SCISSOR_TEST
QRect bounds = q->state()->rectangleClip;
if (!q->state()->clipEnabled) {
if (use_system_clip)
@@ -1554,6 +1561,7 @@ void QGL2PaintEngineExPrivate::updateDepthScissorTest()
glEnable(GL_SCISSOR_TEST);
setScissor(bounds);
}
+#endif
}
void QGL2PaintEngineExPrivate::setScissor(const QRect &rect)
@@ -1650,6 +1658,7 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op)
}
}
+#ifndef QT_GL_NO_SCISSOR_TEST
if (!path.isEmpty() && op == Qt::IntersectClip && (path.shape() == QVectorPath::RectangleHint)) {
const QPointF* const points = reinterpret_cast<const QPointF*>(path.points());
QRectF rect(points[0], points[2]);
@@ -1660,6 +1669,7 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op)
return;
}
}
+#endif
const QRect pathRect = state()->matrix.mapRect(path.controlPointRect()).toAlignedRect();
@@ -1684,6 +1694,7 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op)
state()->depthTestEnabled = true;
break;
case Qt::UniteClip: {
+#ifndef QT_GL_NO_SCISSOR_TEST
if (state()->rectangleClip.isValid()) {
++state()->maxDepth;
@@ -1709,7 +1720,8 @@ void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op)
// first clear the depth buffer in the extended region
d->writeClip(qtVectorPathForPath(state()->matrix.inverted().map(extendPath)), 0);
}
-
+#endif
+ glDepthFunc(GL_ALWAYS);
// now write the clip path
d->writeClip(path, state()->maxDepth);
state()->canRestoreClip = false;
@@ -1760,29 +1772,33 @@ void QGL2PaintEngineExPrivate::systemStateChanged()
updateDepthScissorTest();
if (use_system_clip) {
+#ifndef QT_GL_NO_SCISSOR_TEST
if (systemClip.numRects() == 1) {
if (q->state()->rectangleClip == QRect(0, 0, width, height)) {
use_system_clip = false;
- return;
+ } else {
+ simpleShaderDepthUniformDirty = true;
+ depthUniformDirty = true;
}
- } else {
- q->state()->needsDepthBufferClear = false;
+ return;
+ }
+#endif
+ q->state()->needsDepthBufferClear = false;
- glDepthMask(true);
+ glDepthMask(true);
- glClearDepth(0);
- glClear(GL_DEPTH_BUFFER_BIT);
+ glClearDepth(0);
+ glClear(GL_DEPTH_BUFFER_BIT);
- QPainterPath path;
- path.addRegion(systemClip);
+ QPainterPath path;
+ path.addRegion(systemClip);
- glDepthFunc(GL_ALWAYS);
- writeClip(qtVectorPathForPath(q->state()->matrix.inverted().map(path)), 2);
- glDepthFunc(GL_LESS);
+ glDepthFunc(GL_ALWAYS);
+ writeClip(qtVectorPathForPath(q->state()->matrix.inverted().map(path)), 2);
+ glDepthFunc(GL_LESS);
- glEnable(GL_DEPTH_TEST);
- q->state()->depthTestEnabled = true;
- }
+ glEnable(GL_DEPTH_TEST);
+ q->state()->depthTestEnabled = true;
simpleShaderDepthUniformDirty = true;
depthUniformDirty = true;
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index fe676ea..0ad6772 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1245,11 +1245,11 @@ QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags()
if (cachedDefault) {
return defaultVersionFlags;
} else {
- cachedDefault = true;
if (!hasOpenGL())
return defaultVersionFlags;
dummy = new QGLWidget;
dummy->makeCurrent(); // glGetString() needs a current context
+ cachedDefault = true;
}
}
@@ -1430,6 +1430,7 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
#endif
#if defined(QT_OPENGL_ES)
eglContext = 0;
+ eglSurface = EGL_NO_SURFACE;
#endif
fbo = 0;
crWin = false;
@@ -2513,6 +2514,8 @@ void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexT
array[7] = f2vt(y2);
}
+#if !defined(QT_OPENGL_ES_2)
+
static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint textureHeight, GLenum textureTarget)
{
q_vertexType tx = f2vt(1);
@@ -2541,7 +2544,6 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex
q_vertexType vertexArray[4*2];
qt_add_rect_to_array(target, vertexArray);
-#if !defined(QT_OPENGL_ES_2)
glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);
glTexCoordPointer(2, q_vertexTypeEnum, 0, texCoordArray);
@@ -2551,18 +2553,22 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-#endif
}
+#endif // !QT_OPENGL_ES_2
+
/*!
\since 4.4
Draws the given texture, \a textureId, to the given target rectangle,
\a target, in OpenGL model space. The \a textureTarget should be a 2D
texture target.
+
+ \note This function is not supported under OpenGL/ES 2.0.
*/
void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget)
{
+#ifndef QT_OPENGL_ES_2
#ifdef QT_OPENGL_ES
if (textureTarget != GL_TEXTURE_2D) {
qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES");
@@ -2586,6 +2592,12 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
glDisable(textureTarget);
glBindTexture(textureTarget, oldTexture);
#endif
+#else
+ Q_UNUSED(target);
+ Q_UNUSED(textureId);
+ Q_UNUSED(textureTarget);
+ qWarning("drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES/2.0");
+#endif
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
@@ -2601,6 +2613,8 @@ void QGLContext::drawTexture(const QRectF &target, QMacCompatGLuint textureId, Q
Draws the given texture at the given \a point in OpenGL model
space. The \a textureTarget should be a 2D texture target.
+
+ \note This function is not supported under OpenGL/ES.
*/
void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget)
{
diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp
index 60155b6..5ce1a45 100644
--- a/src/opengl/qgl_egl.cpp
+++ b/src/opengl/qgl_egl.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include <QtOpenGL/qgl.h>
+#include "qgl_p.h"
#include "qgl_egl_p.h"
QT_BEGIN_NAMESPACE
@@ -128,4 +129,92 @@ void qt_egl_update_format(const QEglContext& context, QGLFormat& format)
context.clearError();
}
+bool QGLFormat::hasOpenGL()
+{
+ return true;
+}
+
+void QGLContext::reset()
+{
+ Q_D(QGLContext);
+ if (!d->valid)
+ return;
+ d->cleanup();
+ doneCurrent();
+ if (d->eglContext) {
+ delete d->eglContext;
+ d->eglContext = 0;
+ }
+ d->eglSurface = EGL_NO_SURFACE; // XXX - probably need to destroy surface
+ d->crWin = false;
+ d->sharing = false;
+ d->valid = false;
+ d->transpColor = QColor();
+ d->initDone = false;
+ qgl_share_reg()->removeShare(this);
+}
+
+void QGLContext::makeCurrent()
+{
+ Q_D(QGLContext);
+ if (!d->valid || !d->eglContext || d->eglSurface == EGL_NO_SURFACE) {
+ qWarning("QGLContext::makeCurrent(): Cannot make invalid context current");
+ return;
+ }
+
+ if (d->eglContext->makeCurrent(d->eglSurface))
+ QGLContextPrivate::setCurrentContext(this);
+}
+
+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->eglSurface);
+}
+
+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_p.h b/src/opengl/qgl_p.h
index 7269195..2e8ac88 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -295,6 +295,7 @@ public:
#endif
#if defined(QT_OPENGL_ES)
QEglContext *eglContext;
+ EGLSurface eglSurface;
#elif defined(Q_WS_X11) || defined(Q_WS_MAC)
void* cx;
#endif
diff --git a/src/opengl/qgl_qws.cpp b/src/opengl/qgl_qws.cpp
index 7197776..bb23ace 100644
--- a/src/opengl/qgl_qws.cpp
+++ b/src/opengl/qgl_qws.cpp
@@ -87,12 +87,6 @@ static QGLScreen *glScreenForDevice(QPaintDevice *device)
*****************************************************************************/
//#define DEBUG_OPENGL_REGION_UPDATE
-bool QGLFormat::hasOpenGL()
-{
- return true;
-}
-
-
bool QGLFormat::hasOpenGLOverlays()
{
QGLScreen *glScreen = glScreenForDevice(0);
@@ -117,17 +111,17 @@ void qt_egl_add_platform_config(QEglProperties& props, QPaintDevice *device)
props.setPixelFormat(glScreen->pixelFormat());
}
-static bool qt_egl_create_surface
+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 false;
+ return EGL_NO_SURFACE;
QGLScreenSurfaceFunctions *funcs = glScreen->surfaceFunctions();
if (!funcs)
- return false;
+ return EGL_NO_SURFACE;
// Create the native drawable for the paint device.
int devType = device->devType();
@@ -143,7 +137,7 @@ static bool qt_egl_create_surface
}
if (!ok) {
qWarning("QEglContext::createSurface(): Cannot create the native EGL drawable");
- return false;
+ return EGL_NO_SURFACE;
}
// Create the EGL surface to draw into, based on the native drawable.
@@ -160,12 +154,9 @@ static bool qt_egl_create_surface
surf = eglCreatePixmapSurface
(context->display(), context->config(), pixmapDrawable, props);
}
- if (surf == EGL_NO_SURFACE) {
+ if (surf == EGL_NO_SURFACE)
qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError());
- return false;
- }
- context->setSurface(surf);
- return true;
+ return surf;
}
bool QGLContext::chooseContext(const QGLContext* shareContext)
@@ -223,7 +214,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
// Create the EGL surface to draw into. We cannot use
// QEglContext::createSurface() because it does not have
// access to the QGLScreen.
- if (!qt_egl_create_surface(d->eglContext, device())) {
+ d->eglSurface = qt_egl_create_surface(d->eglContext, device());
+ if (d->eglSurface == EGL_NO_SURFACE) {
delete d->eglContext;
d->eglContext = 0;
return false;
@@ -233,89 +225,11 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
}
-void QGLContext::reset()
-{
- Q_D(QGLContext);
- if (!d->valid)
- return;
- d->cleanup();
- doneCurrent();
- if (d->eglContext) {
- delete d->eglContext;
- d->eglContext = 0;
- }
- d->crWin = false;
- d->sharing = false;
- d->valid = false;
- d->transpColor = QColor();
- d->initDone = false;
- qgl_share_reg()->removeShare(this);
-}
-
-void QGLContext::makeCurrent()
-{
- Q_D(QGLContext);
- if(!d->valid || !d->eglContext) {
- qWarning("QGLContext::makeCurrent(): Cannot make invalid context current");
- return;
- }
-
- if (d->eglContext->makeCurrent())
- QGLContextPrivate::setCurrentContext(this);
-}
-
-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();
-}
-
-QColor QGLContext::overlayTransparentColor() const
-{
- return QColor(0, 0, 0); // Invalid color
-}
-
-uint QGLContext::colorIndex(const QColor &c) const
-{
- //### color index doesn't work on egl
- 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 QGLWidget::event(QEvent *e)
{
return QWidget::event(e);
}
-void QGLWidget::setMouseTracking(bool enable)
-{
- QWidget::setMouseTracking(enable);
-}
-
void QGLWidget::resizeEvent(QResizeEvent *)
{
@@ -380,11 +294,6 @@ void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget)
}
}
-bool QGLWidgetPrivate::renderCxPm(QPixmap*)
-{
- return false;
-}
-
void QGLWidgetPrivate::cleanupColormaps()
{
}
diff --git a/src/opengl/qgl_win.cpp b/src/opengl/qgl_win.cpp
index 2f9e225..5b5820a 100644
--- a/src/opengl/qgl_win.cpp
+++ b/src/opengl/qgl_win.cpp
@@ -660,6 +660,8 @@ public:
int dmy_pf = ChoosePixelFormat(dmy_pdc, &dmy_pfd);
SetPixelFormat(dmy_pdc, dmy_pf, &dmy_pfd);
dmy_rc = wglCreateContext(dmy_pdc);
+ old_dc = wglGetCurrentDC();
+ old_context = wglGetCurrentContext();
wglMakeCurrent(dmy_pdc, dmy_rc);
}
@@ -668,10 +670,14 @@ public:
wglDeleteContext(dmy_rc);
ReleaseDC(dmy_id, dmy_pdc);
DestroyWindow(dmy_id);
+ if (old_dc && old_context)
+ wglMakeCurrent(old_dc, old_context);
}
HDC dmy_pdc;
HGLRC dmy_rc;
+ HDC old_dc;
+ HGLRC old_context;
WId dmy_id;
};
diff --git a/src/opengl/qgl_wince.cpp b/src/opengl/qgl_wince.cpp
index 4e655f1..53b9e27 100644
--- a/src/opengl/qgl_wince.cpp
+++ b/src/opengl/qgl_wince.cpp
@@ -112,11 +112,6 @@ void qt_egl_add_platform_config(QEglProperties& props, QPaintDevice *device)
}
-bool QGLFormat::hasOpenGL()
-{
- return true;
-}
-
static bool opengl32dll = false;
bool QGLFormat::hasOpenGLOverlays()
@@ -178,7 +173,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
#endif
// Create the EGL surface to draw into.
- if (!d->eglContext->createSurface(device())) {
+ d->eglSurface = d->eglContext->createSurface(device());
+ if (d->eglSurface == EGL_NO_SURFACE) {
delete d->eglContext;
d->eglContext = 0;
return false;
@@ -415,83 +411,6 @@ const QRgb* QGLCmap::colors() const
}
-void QGLContext::reset()
-{
- Q_D(QGLContext);
- if (!d->valid)
- return;
- d->cleanup();
- doneCurrent();
- if (d->eglContext) {
- delete d->eglContext;
- d->eglContext = 0;
- }
- d->crWin = false;
- d->sharing = false;
- d->valid = false;
- d->transpColor = QColor();
- d->initDone = false;
- qgl_share_reg()->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->valid || !d->eglContext) {
- qWarning("QGLContext::makeCurrent(): Cannot make invalid context current");
- return;
- }
-
- if (d->eglContext->makeCurrent())
- QGLContextPrivate::setCurrentContext(this);
-}
-
-
-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();
-}
-
-
-QColor QGLContext::overlayTransparentColor() const
-{
- return d_func()->transpColor;
-}
-
-
-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()));
-}
-
/*****************************************************************************
QGLWidget Win32/WGL-specific code
*****************************************************************************/
@@ -570,12 +489,6 @@ bool QGLWidget::event(QEvent *e)
}
-void QGLWidget::setMouseTracking(bool enable)
-{
- QWidget::setMouseTracking(enable);
-}
-
-
void QGLWidget::resizeEvent(QResizeEvent *)
{
Q_D(QGLWidget);
@@ -675,11 +588,6 @@ void QGLWidget::setContext(QGLContext *context,
}
-bool QGLWidgetPrivate::renderCxPm(QPixmap*)
-{
- return false;
-}
-
void QGLWidgetPrivate::cleanupColormaps()
{
Q_Q(QGLWidget);
diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp
index da7972d..86e593d 100644
--- a/src/opengl/qgl_x11.cpp
+++ b/src/opengl/qgl_x11.cpp
@@ -331,6 +331,62 @@ static void find_trans_colors()
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;
+ QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
+ if (glxExt.contains(QLatin1String("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 = 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;
@@ -819,23 +875,8 @@ void QGLContext::swapBuffers() const
if (!resolved) {
QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) {
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
- void *handle = dlopen(NULL, RTLD_LAZY);
- if (handle) {
- glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) dlsym(handle, "glXGetVideoSyncSGI");
- glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) dlsym(handle, "glXWaitVideoSyncSGI");
- dlclose(handle);
- }
- if (!glXGetVideoSyncSGI)
-#endif
- {
-#if !defined(QT_NO_LIBRARY)
- extern const QString qt_gl_library_name();
- QLibrary lib(qt_gl_library_name());
- glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) lib.resolve("glXGetVideoSyncSGI");
- glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) lib.resolve("glXWaitVideoSyncSGI");
-#endif
- }
+ glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI)qglx_getProcAddress("glXGetVideoSyncSGI");
+ glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI)qglx_getProcAddress("glXWaitVideoSyncSGI");
}
resolved = true;
}
@@ -1568,21 +1609,8 @@ bool qt_resolveTextureFromPixmap()
QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
if (glxExt.contains(QLatin1String("GLX_EXT_texture_from_pixmap"))) {
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
- void *handle = dlopen(NULL, RTLD_LAZY);
- if (handle) {
- glXBindTexImageEXT = (qt_glXBindTexImageEXT) dlsym(handle, "glXBindTexImageEXT");
- glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) dlsym(handle, "glXReleaseTexImageEXT");
- dlclose(handle);
- }
- if (!glXBindTexImageEXT)
-#endif
- {
- extern const QString qt_gl_library_name();
- QLibrary lib(qt_gl_library_name());
- glXBindTexImageEXT = (qt_glXBindTexImageEXT) lib.resolve("glXBindTexImageEXT");
- glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) lib.resolve("glXReleaseTexImageEXT");
- }
+ glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT");
+ glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT");
}
}
diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp
index 32d8cc2..67f391b 100644
--- a/src/opengl/qgl_x11egl.cpp
+++ b/src/opengl/qgl_x11egl.cpp
@@ -51,11 +51,6 @@
QT_BEGIN_NAMESPACE
-bool QGLFormat::hasOpenGL()
-{
- return true;
-}
-
bool QGLFormat::hasOpenGLOverlays()
{
return false;
@@ -118,86 +113,6 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
return true;
}
-
-void QGLContext::reset()
-{
- Q_D(QGLContext);
- if (!d->valid)
- return;
- d->cleanup();
- doneCurrent();
- if (d->eglContext) {
- delete d->eglContext;
- d->eglContext = 0;
- }
- d->crWin = false;
- d->sharing = false;
- d->valid = false;
- d->transpColor = QColor();
- d->initDone = false;
- qgl_share_reg()->removeShare(this);
-}
-
-void QGLContext::makeCurrent()
-{
- Q_D(QGLContext);
- if(!d->valid || !d->eglContext) {
- qWarning("QGLContext::makeCurrent(): Cannot make invalid context current");
- return;
- }
-
- if (d->eglContext->makeCurrent())
- QGLContextPrivate::setCurrentContext(this);
-}
-
-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();
-}
-
-QColor QGLContext::overlayTransparentColor() const
-{
- return QColor(0, 0, 0); // Invalid color
-}
-
-uint QGLContext::colorIndex(const QColor &c) const
-{
- //### color index doesn't work on egl
- 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()));
-}
-
-void QGLWidget::setMouseTracking(bool enable)
-{
- QWidget::setMouseTracking(enable);
-}
-
-
void QGLWidget::resizeEvent(QResizeEvent *)
{
Q_D(QGLWidget);
@@ -412,9 +327,11 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext,
// Create the EGL surface to draw into.
- if (!d->glcx->d_func()->eglContext->createSurface(this)) {
- delete d->glcx->d_func()->eglContext;
- d->glcx->d_func()->eglContext = 0;
+ QGLContextPrivate *ctxpriv = d->glcx->d_func();
+ ctxpriv->eglSurface = ctxpriv->eglContext->createSurface(this);
+ if (ctxpriv->eglSurface == EGL_NO_SURFACE) {
+ delete ctxpriv->eglContext;
+ ctxpriv->eglContext = 0;
return;
}
@@ -439,11 +356,6 @@ void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget)
}
}
-bool QGLWidgetPrivate::renderCxPm(QPixmap*)
-{
- return false;
-}
-
void QGLWidgetPrivate::cleanupColormaps()
{
}
@@ -483,8 +395,14 @@ void QGLWidgetPrivate::recreateEglSurface(bool force)
if ( force || (currentId != eglSurfaceWindowId) ) {
// The window id has changed so we need to re-create the EGL surface
- if (!glcx->d_func()->eglContext->recreateSurface(q))
+ QEglContext *ctx = glcx->d_func()->eglContext;
+ EGLSurface surface = glcx->d_func()->eglSurface;
+ if (surface != EGL_NO_SURFACE)
+ ctx->destroySurface(surface); // Will force doneCurrent() if nec.
+ surface = ctx->createSurface(q);
+ if (surface == EGL_NO_SURFACE)
qWarning("Error creating EGL window surface: 0x%x", eglGetError());
+ glcx->d_func()->eglSurface = surface;
eglSurfaceWindowId = currentId;
}
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index e4cef5f..c728902 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -1185,6 +1185,8 @@ bool QGLFramebufferObject::isBound() const
Returns true if the OpenGL \c{GL_EXT_framebuffer_blit} extension
is present on this system; otherwise returns false.
+
+ \sa blitFramebuffer()
*/
bool QGLFramebufferObject::hasOpenGLFramebufferBlit()
{
@@ -1202,14 +1204,15 @@ bool QGLFramebufferObject::hasOpenGLFramebufferBlit()
instead of a framebuffer object as source or target respectively.
The \a buffers parameter should be a mask consisting of any combination of
- COLOR_BUFFER_BIT, DEPTH_BUFFER_BIT, and STENCIL_BUFFER_BIT. Any buffer type
- that is not present both in the source and target buffers is ignored.
+ \c GL_COLOR_BUFFER_BIT, \c GL_DEPTH_BUFFER_BIT, and
+ \c GL_STENCIL_BUFFER_BIT. Any buffer type that is not present both
+ in the source and target buffers is ignored.
The \a sourceRect and \a targetRect rectangles may have different sizes;
- in this case \a buffers should not contain DEPTH_BUFFER_BIT or
- STENCIL_BUFFER_BIT. The \a filter parameter should be set to GL_LINEAR or
- GL_NEAREST, and specifies whether linear or nearest interpolation should
- be used when scaling is performed.
+ in this case \a buffers should not contain \c GL_DEPTH_BUFFER_BIT or
+ \c GL_STENCIL_BUFFER_BIT. The \a filter parameter should be set to
+ \c GL_LINEAR or \c GL_NEAREST, and specifies whether linear or nearest
+ interpolation should be used when scaling is performed.
If \a source equals \a target a copy is performed within the same buffer.
Results are undefined if the source and target rectangles overlap and
@@ -1220,6 +1223,8 @@ bool QGLFramebufferObject::hasOpenGLFramebufferBlit()
This function will have no effect unless hasOpenGLFramebufferBlit() returns
true.
+
+ \sa hasOpenGLFramebufferBlit()
*/
void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const QRect &targetRect,
QGLFramebufferObject *source, const QRect &sourceRect,
diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp
index 07bc711..7c97ebb 100644
--- a/src/opengl/qglpixelbuffer.cpp
+++ b/src/opengl/qglpixelbuffer.cpp
@@ -146,6 +146,7 @@ void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &form
qctx->d_func()->vi = 0;
#elif defined(QT_OPENGL_ES)
qctx->d_func()->eglContext = ctx;
+ qctx->d_func()->eglSurface = pbuf;
#endif
}
}
diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp
index e331de5..4cba1bb 100644
--- a/src/opengl/qglpixelbuffer_egl.cpp
+++ b/src/opengl/qglpixelbuffer_egl.cpp
@@ -135,7 +135,6 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge
qWarning() << "QGLPixelBufferPrivate::init(): Unable to create EGL pbuffer surface:" << QEglContext::errorString(eglGetError());
return false;
}
- ctx->setSurface(pbuf);
// Create a new context for the configuration.
QEglContext *shareContext = 0;
@@ -163,7 +162,7 @@ bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id)
if (d->invalid || d->textureFormat == EGL_NONE || !d->ctx)
return false;
glBindTexture(GL_TEXTURE_2D, texture_id);
- return eglBindTexImage(d->ctx->display(), d->ctx->surface(), EGL_BACK_BUFFER);
+ return eglBindTexImage(d->ctx->display(), d->pbuf, EGL_BACK_BUFFER);
#else
Q_UNUSED(texture_id);
return false;
@@ -176,7 +175,7 @@ void QGLPixelBuffer::releaseFromDynamicTexture()
Q_D(QGLPixelBuffer);
if (d->invalid || d->textureFormat == EGL_NONE || !d->ctx)
return;
- eglReleaseTexImage(d->ctx->display(), d->ctx->surface(), EGL_BACK_BUFFER);
+ eglReleaseTexImage(d->ctx->display(), d->pbuf, EGL_BACK_BUFFER);
#endif
}
diff --git a/src/opengl/qglpixelbuffer_x11.cpp b/src/opengl/qglpixelbuffer_x11.cpp
index 793471d..6971133 100644
--- a/src/opengl/qglpixelbuffer_x11.cpp
+++ b/src/opengl/qglpixelbuffer_x11.cpp
@@ -93,6 +93,8 @@ static _glXMakeContextCurrent qt_glXMakeContextCurrent = 0;
#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;
@@ -101,31 +103,12 @@ static bool qt_resolve_pbuffer_extensions()
else if (resolved)
return false;
-#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
- void *handle = dlopen(NULL, RTLD_LAZY);
- if (handle) {
- qt_glXChooseFBConfig = (_glXChooseFBConfig) dlsym(handle, "glXChooseFBConfig");
- qt_glXCreateNewContext = (_glXCreateNewContext) dlsym(handle, "glXCreateNewContext");
- qt_glXCreatePbuffer = (_glXCreatePbuffer) dlsym(handle, "glXCreatePbuffer");
- qt_glXDestroyPbuffer = (_glXDestroyPbuffer) dlsym(handle, "glXDestroyPbuffer");
- qt_glXGetFBConfigAttrib = (_glXGetFBConfigAttrib) dlsym(handle, "glXGetFBConfigAttrib");
- qt_glXMakeContextCurrent = (_glXMakeContextCurrent) dlsym(handle, "glXMakeContextCurrent");
- dlclose(handle);
- }
- if (!qt_glXChooseFBConfig)
-#endif
- {
-#if !defined(QT_NO_LIBRARY)
- extern const QString qt_gl_library_name();
- QLibrary gl(qt_gl_library_name());
- qt_glXChooseFBConfig = (_glXChooseFBConfig) gl.resolve("glXChooseFBConfig");
- qt_glXCreateNewContext = (_glXCreateNewContext) gl.resolve("glXCreateNewContext");
- qt_glXCreatePbuffer = (_glXCreatePbuffer) gl.resolve("glXCreatePbuffer");
- qt_glXDestroyPbuffer = (_glXDestroyPbuffer) gl.resolve("glXDestroyPbuffer");
- qt_glXGetFBConfigAttrib = (_glXGetFBConfigAttrib) gl.resolve("glXGetFBConfigAttrib");
- qt_glXMakeContextCurrent = (_glXMakeContextCurrent) gl.resolve("glXMakeContextCurrent");
-#endif
- }
+ 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;
diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp
index bb0306c..bb3cb5d 100644
--- a/src/opengl/qglpixmapfilter.cpp
+++ b/src/opengl/qglpixmapfilter.cpp
@@ -79,6 +79,8 @@ protected:
bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &pixmap, const QRectF &srcRect) const;
};
+#ifndef QT_OPENGL_ES_2
+
class QGLPixmapConvolutionFilter: public QGLPixmapFilter<QPixmapConvolutionFilter>
{
public:
@@ -99,6 +101,8 @@ private:
mutable int m_kernelHeight;
};
+#endif
+
class QGLPixmapBlurFilter : public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapBlurFilter>
{
public:
@@ -143,22 +147,25 @@ QPixmapFilter *QGL2PaintEngineEx::pixmapFilter(int type, const QPixmapFilter *pr
return d->blurFilter.data();
}
+#ifndef QT_OPENGL_ES_2
case QPixmapFilter::ConvolutionFilter:
if (!d->convolutionFilter)
d->convolutionFilter.reset(new QGLPixmapConvolutionFilter);
return d->convolutionFilter.data();
+#endif
default: break;
}
return QPaintEngineEx::pixmapFilter(type, prototype);
}
+#ifndef QT_OPENGL_ES_2 // XXX: needs to be ported
+
extern void qt_add_rect_to_array(const QRectF &r, q_vertexType *array);
extern void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, q_vertexType *array);
static void qgl_drawTexture(const QRectF &rect, int tx_width, int tx_height, const QRectF & src)
{
-#ifndef QT_OPENGL_ES_2 // XXX: needs to be ported
#ifndef QT_OPENGL_ES
glPushAttrib(GL_CURRENT_BIT);
#endif
@@ -187,9 +194,10 @@ static void qgl_drawTexture(const QRectF &rect, int tx_width, int tx_height, con
#ifndef QT_OPENGL_ES
glPopAttrib();
#endif
-#endif
}
+#endif // !QT_OPENGL_ES_2
+
static const char *qt_gl_colorize_filter =
"uniform lowp vec4 colorizeColor;"
"uniform lowp float colorizeStrength;"
@@ -223,6 +231,8 @@ void QGLPixmapColorizeFilter::setUniforms(QGLShaderProgram *program)
program->setUniformValue("colorizeStrength", float(strength()));
}
+#ifndef QT_OPENGL_ES_2
+
// generates convolution filter code for arbitrary sized kernel
QByteArray QGLPixmapConvolutionFilter::generateConvolutionShader() const {
QByteArray code;
@@ -315,6 +325,8 @@ bool QGLPixmapConvolutionFilter::processGL(QPainter *, const QPointF &pos, const
return true;
}
+#endif // !QT_OPENGL_ES_2
+
static const char *qt_gl_blur_filter_fast =
"const int samples = 9;"
"uniform mediump vec2 delta;"
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index 8cb6c8d..2331c6d 100644
--- a/src/opengl/qpixmapdata_gl.cpp
+++ b/src/opengl/qpixmapdata_gl.cpp
@@ -384,8 +384,20 @@ void QGLPixmapData::fill(const QColor &color)
m_hasFillColor = true;
m_fillColor = color;
} else {
- QImage image = fillImage(color);
- fromImage(image, 0);
+
+ 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);
+ }
}
}
@@ -399,15 +411,11 @@ QImage QGLPixmapData::fillImage(const QColor &color) const
QImage img;
if (pixelType() == BitmapType) {
img = QImage(w, h, QImage::Format_MonoLSB);
- img.setNumColors(2);
- img.setColor(0, QColor(Qt::color0).rgba());
- img.setColor(1, QColor(Qt::color1).rgba());
- int gray = qGray(color.rgba());
- if (qAbs(255 - gray) < gray)
- img.fill(0);
- else
+ if (color == Qt::color1)
img.fill(1);
+ else
+ img.fill(0);
} else {
img = QImage(w, h,
m_hasAlpha
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index cddc53f..3a348bc 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -86,6 +86,10 @@
#include "qgl_cl_p.h"
#endif
+#ifdef QT_OPENGL_ES
+#include <private/qegl_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
//
@@ -326,6 +330,10 @@ QGLWindowSurface::~QGLWindowSurface()
void QGLWindowSurface::deleted(QObject *object)
{
+ // Make sure that the fbo is destroyed before destroying its context.
+ delete d_ptr->fbo;
+ d_ptr->fbo = 0;
+
QWidget *widget = qobject_cast<QWidget *>(object);
if (widget) {
QWidgetPrivate *widgetPrivate = widget->d_func();
@@ -352,6 +360,17 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
QGLContext *ctx = new QGLContext(surfaceFormat, widget);
ctx->create(qt_gl_share_widget()->context());
+#if defined(Q_WS_X11) && defined(QT_OPENGL_ES)
+ // Create the EGL surface to draw into. QGLContext::chooseContext()
+ // does not do this for X11/EGL, but does do it for other platforms.
+ // This probably belongs in qgl_x11egl.cpp.
+ QGLContextPrivate *ctxpriv = ctx->d_func();
+ ctxpriv->eglSurface = ctxpriv->eglContext->createSurface(widget);
+ if (ctxpriv->eglSurface == EGL_NO_SURFACE) {
+ qWarning() << "hijackWindow() could not create EGL surface";
+ }
+#endif
+
widgetPrivate->extraData()->glContext = ctx;
union { QGLContext **ctxPtr; void **voidPtr; };
@@ -584,6 +603,44 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &
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);
+
+ GLuint texture = d_ptr->fbo->texture();
+
+ glDisable(GL_DEPTH_TEST);
+
+ if (d_ptr->fbo->isBound())
+ d_ptr->fbo->release();
+
+ glViewport(0, 0, size.width(), size.height());
+
+ QGLShaderProgram *blitProgram =
+ QGLEngineSharedShaders::shadersForContext(ctx)->blitProgram();
+ blitProgram->enable();
+ 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 = size.width() ? size.width() : 1.0f;
+ qreal h = size.height() ? size.height() : 1.0f;
+ r.setLeft((rect.left() / w) * 2.0f - 1.0f);
+ if (rect.right() == (size.width() - 1))
+ r.setRight(1.0f);
+ else
+ r.setRight((rect.right() / w) * 2.0f - 1.0f);
+ r.setBottom((rect.top() / h) * 2.0f - 1.0f);
+ if (rect.bottom() == (size.height() - 1))
+ r.setTop(1.0f);
+ else
+ r.setTop((rect.bottom() / w) * 2.0f - 1.0f);
+
+ drawTexture(r, texture, window()->size(), br);
+ }
#endif
if (ctx->format().doubleBuffer())
@@ -635,9 +692,6 @@ void QGLWindowSurface::updateGeometry() {
if (d_ptr->destructive_swap_buffers
&& (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject)
-#ifdef QT_OPENGL_ES_2
- && (QGLExtensions::glExtensions & QGLExtensions::FramebufferBlit)
-#endif
&& (d_ptr->fbo || !d_ptr->tried_fbo)
&& qt_gl_preferGL2Engine())
{
@@ -805,10 +859,23 @@ static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize,
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-#endif
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)