summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp4
-rw-r--r--src/opengl/opengl.pro2
-rw-r--r--src/opengl/qgl_symbian.cpp65
-rw-r--r--src/opengl/qgltexturepool.cpp7
-rw-r--r--src/opengl/qpixmapdata_gl_p.h10
-rw-r--r--src/opengl/qpixmapdata_poolgl.cpp21
-rw-r--r--src/opengl/qwindowsurface_gl.cpp40
7 files changed, 123 insertions, 26 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index c8786fb..5c8d2b6 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -90,10 +90,6 @@
QT_BEGIN_NAMESPACE
-#if defined(Q_OS_SYMBIAN)
-#define QT_GL_NO_SCISSOR_TEST
-#endif
-
#if defined(Q_WS_WIN)
extern Q_GUI_EXPORT bool qt_cleartype_enabled;
#endif
diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro
index 6bbf99b..6d79584 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -148,7 +148,7 @@ embedded {
}
symbian {
- DEFINES += QGL_USE_TEXTURE_POOL
+ DEFINES += QGL_USE_TEXTURE_POOL QGL_NO_PRESERVED_SWAP
SOURCES -= qpixmapdata_gl.cpp
SOURCES += qgl_symbian.cpp \
qpixmapdata_poolgl.cpp \
diff --git a/src/opengl/qgl_symbian.cpp b/src/opengl/qgl_symbian.cpp
index 78624a2..1b41db4 100644
--- a/src/opengl/qgl_symbian.cpp
+++ b/src/opengl/qgl_symbian.cpp
@@ -48,6 +48,7 @@
#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"
@@ -228,13 +229,20 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // almost same as
d->eglSurface = QEgl::createSurface(device(), d->eglContext->config());
-#if !defined(QGL_NO_PRESERVED_SWAP)
- eglGetError(); // Clear error state first.
- eglSurfaceAttrib(QEgl::display(), d->eglSurface,
- EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
- if (eglGetError() != EGL_SUCCESS) {
- qWarning("QGLContext: could not enable preserved swap");
- }
+ 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);
@@ -404,6 +412,11 @@ void QGLPixmapData::fromNativeType(void* pixmap, NativeType type)
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();
}
}
@@ -418,4 +431,42 @@ void* QGLPixmapData::toNativeType(NativeType type)
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/qgltexturepool.cpp b/src/opengl/qgltexturepool.cpp
index 61a88c3..a5472ec 100644
--- a/src/opengl/qgltexturepool.cpp
+++ b/src/opengl/qgltexturepool.cpp
@@ -135,8 +135,11 @@ void QGLTexturePool::releaseTexture(QGLPixmapData *data, GLuint texture)
if (data)
removeFromLRU(data);
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- glDeleteTextures(1, &texture);
+ QGLWidget *shareWidget = qt_gl_share_widget();
+ if (shareWidget) {
+ QGLShareContextScope ctx(shareWidget->context());
+ glDeleteTextures(1, &texture);
+ }
}
void QGLTexturePool::useTexture(QGLPixmapData *data)
diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h
index 41740dd..8855c20 100644
--- a/src/opengl/qpixmapdata_gl_p.h
+++ b/src/opengl/qpixmapdata_gl_p.h
@@ -76,6 +76,10 @@ void qt_gl_unregister_pixmap(QGLPixmapData *pd);
void qt_gl_hibernate_pixmaps();
#endif
+#ifdef Q_OS_SYMBIAN
+class QNativeImageHandleProvider;
+#endif
+
class QGLFramebufferObjectPool
{
public:
@@ -160,6 +164,9 @@ public:
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:
@@ -191,6 +198,9 @@ private:
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
diff --git a/src/opengl/qpixmapdata_poolgl.cpp b/src/opengl/qpixmapdata_poolgl.cpp
index 64de29e..44d9c84 100644
--- a/src/opengl/qpixmapdata_poolgl.cpp
+++ b/src/opengl/qpixmapdata_poolgl.cpp
@@ -49,6 +49,7 @@
#include <private/qgl_p.h>
#include <private/qdrawhelper_p.h>
#include <private/qimage_p.h>
+#include <private/qnativeimagehandleprovider_p.h>
#include <private/qpaintengineex_opengl2_p.h>
@@ -254,6 +255,8 @@ QGLPixmapData::QGLPixmapData(PixelType type)
, m_renderFbo(0)
, m_engine(0)
, m_ctx(0)
+ , nativeImageHandleProvider(0)
+ , nativeImageHandle(0)
, m_dirty(false)
, m_hasFillColor(false)
, m_hasAlpha(false)
@@ -292,6 +295,8 @@ void QGLPixmapData::destroyTexture()
}
m_texture.id = 0;
inTexturePool = false;
+
+ releaseNativeImageHandle();
}
QPixmapData *QGLPixmapData::createCompatiblePixmapData() const
@@ -342,6 +347,9 @@ void QGLPixmapData::ensureCreated() const
m_dirty = false;
+ if (nativeImageHandleProvider && !nativeImageHandle)
+ const_cast<QGLPixmapData *>(this)->createFromNativeImageHandleProvider();
+
QGLShareContextScope ctx(qt_gl_share_widget()->context());
m_ctx = ctx;
@@ -860,9 +868,16 @@ void QGLPixmapData::detachTextureFromPool()
void QGLPixmapData::hibernate()
{
- // If the texture was imported (e.g, from an SgImage under Symbian),
- // then we cannot copy it back to main memory for storage.
- if (m_texture.id && m_source.isNull())
+ // 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();
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index 11a9eb0..ed541ce 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -371,6 +371,10 @@ QGLWindowSurface::QGLWindowSurface(QWidget *window)
d_ptr->q_ptr = this;
d_ptr->geometry_updated = false;
d_ptr->did_paint = false;
+
+#ifdef QGL_NO_PRESERVED_SWAP
+ setPartialUpdateSupport(false);
+#endif
}
QGLWindowSurface::~QGLWindowSurface()
@@ -467,8 +471,16 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
if (haveNOKSwapRegion)
qDebug() << "Found EGL_NOK_swap_region2 extension. Using partial updates.";
}
- bool swapBehaviourPreserved = (ctx->d_func()->eglContext->configAttrib(EGL_SWAP_BEHAVIOR)
- || (ctx->d_func()->eglContext->configAttrib(EGL_SURFACE_TYPE)&EGL_SWAP_BEHAVIOR_PRESERVED_BIT));
+
+ bool swapBehaviourPreserved = ctx->d_func()->eglContext->configAttrib(EGL_SWAP_BEHAVIOR);
+ 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)) {
+ swapBehaviourPreserved = (swapBehavior == EGL_BUFFER_PRESERVED);
+ }
+ }
+
if (!swapBehaviourPreserved && !haveNOKSwapRegion)
setPartialUpdateSupport(false); // Force full-screen updates
else
@@ -514,6 +526,8 @@ static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize,
void QGLWindowSurface::beginPaint(const QRegion &)
{
+ updateGeometry();
+
if (!context())
return;
@@ -874,14 +888,22 @@ void QGLWindowSurface::updateGeometry() {
ctx->d_func()->eglSurface = QEgl::createSurface(ctx->device(),
ctx->d_func()->eglContext->config());
-#if !defined(QGL_NO_PRESERVED_SWAP)
- eglGetError(); // Clear error state first.
- eglSurfaceAttrib(QEgl::display(), ctx->d_func()->eglSurface,
- EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
- if (eglGetError() != EGL_SUCCESS) {
- qWarning("QGLWindowSurface: could not restore preserved swap behaviour");
+ eglGetError(); // Clear error state.
+ if (hasPartialUpdateSupport()) {
+ eglSurfaceAttrib(ctx->d_func()->eglContext->display(),
+ ctx->d_func()->eglSurface,
+ EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
+
+ if (eglGetError() != EGL_SUCCESS)
+ qWarning("QGLWindowSurface: could not enable preserved swap behaviour");
+ } else {
+ eglSurfaceAttrib(ctx->d_func()->eglContext->display(),
+ ctx->d_func()->eglSurface,
+ EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
+
+ if (eglGetError() != EGL_SUCCESS)
+ qWarning("QGLWindowSurface: could not enable destroyed swap behaviour");
}
-#endif
}
#endif