From fe68a04ed15038a9e22b66c567bcd44ee93e33d1 Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Mon, 7 Feb 2011 13:41:46 +0200 Subject: Recreate GL surface when native window is resized on Symbian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Symbian doesn't automatically resize EGL surface when native window is resized. Task-number: QTBUG-15249 Reviewed-by: Jørgen Lind --- src/opengl/qwindowsurface_gl.cpp | 44 ++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 5a783ca..cdd3eb9 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -363,7 +363,6 @@ QGLWindowSurface::~QGLWindowSurface() *ctx = 0; } #endif - delete d_ptr->pb; delete d_ptr->fbo; delete d_ptr; @@ -812,20 +811,25 @@ void QGLWindowSurface::updateGeometry() { return; d_ptr->geometry_updated = false; -#ifdef Q_WS_QPA - QSize surfSize = size(); -#else - QSize surfSize = geometry().size(); -#endif + bool hijack(true); + QWidgetPrivate *wd = window()->d_func(); + if (wd->extraData() && wd->extraData()->glContext) + hijack = false; // we already have gl context for widget - hijackWindow(window()); - QGLContext *ctx = reinterpret_cast(window()->d_func()->extraData()->glContext); + if (hijack) + hijackWindow(window()); + + QGLContext *ctx = reinterpret_cast(wd->extraData()->glContext); #ifdef Q_WS_MAC ctx->updatePaintDevice(); #endif - const GLenum target = GL_TEXTURE_2D; +#ifdef Q_WS_QPA + QSize surfSize = size(); +#else + QSize surfSize = geometry().size(); +#endif if (surfSize.width() <= 0 || surfSize.height() <= 0) return; @@ -835,6 +839,27 @@ void QGLWindowSurface::updateGeometry() { d_ptr->size = surfSize; +#ifdef Q_OS_SYMBIAN + if (!hijack) { // Symbian needs to recreate EGL surface when native window size changes + if (ctx->d_func()->eglSurface != EGL_NO_SURFACE) { + eglDestroySurface(ctx->d_func()->eglContext->display(), + ctx->d_func()->eglSurface); + } + + 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"); + } +#endif + } +#endif + if (d_ptr->ctx) { #ifndef QT_OPENGL_ES_2 if (d_ptr->destructive_swap_buffers) @@ -843,6 +868,7 @@ void QGLWindowSurface::updateGeometry() { return; } + const GLenum target = GL_TEXTURE_2D; if (d_ptr->destructive_swap_buffers && (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject) && (d_ptr->fbo || !d_ptr->tried_fbo) -- cgit v0.12 From 7dc4c8dc1dd4fba8072fd688014f74c98aeb3a23 Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Mon, 7 Feb 2011 13:38:51 +0200 Subject: Use the 'convertInPlace' versions of QImage in QGLPixmapData load. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change QGLPixmapData load functions to use 'convertInPlace' versions of QImage to save memory. Task-number: QTBUG-17256 Reviewed-by: Samuel Rødal --- src/opengl/qpixmapdata_gl.cpp | 113 +++++++++++++++++++++++++++++------------- src/opengl/qpixmapdata_gl_p.h | 4 ++ 2 files changed, 83 insertions(+), 34 deletions(-) diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index d12704d..249c71e 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -55,6 +55,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -369,40 +370,18 @@ void QGLPixmapData::ensureCreated() const void QGLPixmapData::fromImage(const QImage &image, Qt::ImageConversionFlags flags) { - 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(image).data_ptr()->checkForAlphaPixels())) - format = QImage::Format_ARGB32_Premultiplied;; - - m_source = image.convertToFormat(format); - } - - m_dirty = true; - m_hasFillColor = false; + QImage img = image; + createPixmapForImage(img, flags, false); +} - m_hasAlpha = m_source.hasAlphaChannel(); - w = image.width(); - h = image.height(); - is_null = (w <= 0 || h <= 0); - d = m_source.depth(); +void QGLPixmapData::fromImageReader(QImageReader *imageReader, + Qt::ImageConversionFlags flags) +{ + QImage image = imageReader->read(); + if (image.isNull()) + return; - if (m_texture.id) { - QGLShareContextScope ctx(qt_gl_share_context()); - glDeleteTextures(1, &m_texture.id); - m_texture.id = 0; - } + createPixmapForImage(image, flags, true); } bool QGLPixmapData::fromFile(const QString &filename, const char *format, @@ -435,7 +414,13 @@ bool QGLPixmapData::fromFile(const QString &filename, const char *format, } return false; } - fromImage(QImageReader(&file, format).read(), flags); + + QImage image = QImageReader(filename, format).read(); + if (image.isNull()) + return false; + + createPixmapForImage(image, flags, true); + return !isNull(); } @@ -459,7 +444,67 @@ bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format, return true; } } - return QPixmapData::fromData(buffer, len, format, flags); + + QByteArray a = QByteArray::fromRawData(reinterpret_cast(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(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) diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index 5545d3c..96631e6 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -107,6 +107,8 @@ public: // 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, @@ -149,6 +151,8 @@ private: 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; -- cgit v0.12 From 35cbf6b191fdf7c86ff8c4e9d41a152e04302797 Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Wed, 9 Feb 2011 10:11:45 +0200 Subject: QPixmap::to/fromSymbianCFbsBitmap() in OpenGL graphics system. Implementation of Symbian specific conversion functions for converting Symbian native bitmap to QPixmap and QPixmap to Symbian native bitmap. Task-number: QTBUG-16977 Reviewed-by: Jason Barron --- mkspecs/common/symbian/symbian.conf | 11 ++-- src/opengl/qgl_symbian.cpp | 114 ++++++++++++++++++++++++++++++++++++ src/opengl/qpixmapdata_gl_p.h | 5 ++ 3 files changed, 125 insertions(+), 5 deletions(-) diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 37bbb82..4ba6f2e 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -70,16 +70,17 @@ QMAKE_LINK_OBJECT_SCRIPT= QMAKE_LIBS = -llibc -llibm -leuser -llibdl QMAKE_LIBS_CORE = $$QMAKE_LIBS -lefsrv -lhal -lbafl -lapparc -QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE -lfbscli -lbitgdi -lgdi -lws32 -lapgrfx -lcone -leikcore -lmediaclientaudio -lcentralrepository +QMAKE_LIBS_CFBSBITMAP = -lfbscli -lbitgdi -lgdi +QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE $$QMAKE_LIBS_CFBSBITMAP -lws32 -lapgrfx -lcone -leikcore -lmediaclientaudio -lcentralrepository QMAKE_LIBS_NETWORK = QMAKE_LIBS_EGL = -llibEGL QMAKE_LIBS_OPENGL = -llibGLESv2 QMAKE_LIBS_OPENGL_ES1 = -llibGLESv1_CM QMAKE_LIBS_OPENGL_ES2 = -llibGLESv2 -QMAKE_LIBS_OPENGL_QT = -llibGLESv2 -lcone -lws32 -QMAKE_LIBS_OPENGL_ES1_QT = -llibGLESv1_CM -lcone -lws32 -QMAKE_LIBS_OPENGL_ES2_QT = -llibGLESv2 -lcone -lws32 -QMAKE_LIBS_OPENVG = -llibOpenVG -lfbscli -lbitgdi -lgdi +QMAKE_LIBS_OPENGL_QT = $$QMAKE_LIBS_OPENGL $$QMAKE_LIBS_CFBSBITMAP -lcone -lws32 +QMAKE_LIBS_OPENGL_ES1_QT = $$QMAKE_LIBS_OPENGL_ES1 $$QMAKE_LIBS_CFBSBITMAP -lcone -lws32 +QMAKE_LIBS_OPENGL_ES2_QT = $$QMAKE_LIBS_OPENGL_ES2 $$QMAKE_LIBS_CFBSBITMAP -lcone -lws32 +QMAKE_LIBS_OPENVG = $$QMAKE_LIBS_CFBSBITMAP -llibOpenVG QMAKE_LIBS_THREAD = -llibpthread QMAKE_LIBS_COMPAT = QMAKE_LIBS_S60 = -lavkon -leikcoctl diff --git a/src/opengl/qgl_symbian.cpp b/src/opengl/qgl_symbian.cpp index 82b66f5..3426a4c 100644 --- a/src/opengl/qgl_symbian.cpp +++ b/src/opengl/qgl_symbian.cpp @@ -44,12 +44,14 @@ #include #include #include +#include #include #include #include #include #include // to access QWExtra #include "qgl_egl_p.h" +#include "qpixmapdata_gl_p.h" #include "qcolormap.h" #include @@ -358,5 +360,117 @@ void QGLWidgetPrivate::recreateEglSurface() eglSurfaceWindowId = currentId; } +/* + * Symbian specific QGLPixmapData functions + */ + +static CFbsBitmap* createBlitCopy(CFbsBitmap* bitmap) +{ + CFbsBitmap *copy = q_check_ptr(new CFbsBitmap); + if(!copy) + return 0; + + if (copy->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) { + delete copy; + copy = 0; + + return 0; + } + + CFbsBitmapDevice* bitmapDevice = 0; + CFbsBitGc *bitmapGc = 0; + QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(copy)); + QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL()); + bitmapGc->Activate(bitmapDevice); + + bitmapGc->BitBlt(TPoint(), bitmap); + + delete bitmapGc; + delete bitmapDevice; + + return copy; +} + +void QGLPixmapData::fromNativeType(void* pixmap, NativeType type) +{ + if (type == QPixmapData::FbsBitmap) { + CFbsBitmap *bitmap = reinterpret_cast(pixmap); + + bool deleteSourceBitmap = false; +#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE + + // Rasterize extended bitmaps + + TUid extendedBitmapType = bitmap->ExtendedBitmapType(); + if (extendedBitmapType != KNullUid) { + bitmap = createBlitCopy(bitmap); + deleteSourceBitmap = true; + } +#endif + + if (bitmap->IsCompressedInRAM()) { + bitmap = createBlitCopy(bitmap); + deleteSourceBitmap = true; + } + + TDisplayMode displayMode = bitmap->DisplayMode(); + QImage::Format format = qt_TDisplayMode2Format(displayMode); + + TSize size = bitmap->SizeInPixels(); + int bytesPerLine = bitmap->ScanLineLength(size.iWidth, displayMode); + + bitmap->BeginDataAccess(); + uchar *bytes = (uchar*)bitmap->DataAddress(); + QImage img = QImage(bytes, size.iWidth, size.iHeight, bytesPerLine, format); + img = img.copy(); + bitmap->EndDataAccess(); + + if(displayMode == EGray2) { + //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid + //So invert mono bitmaps so that masks work correctly. + img.invertPixels(); + } else if(displayMode == EColor16M) { + img = img.rgbSwapped(); // EColor16M is BGR + } + + fromImage(img, Qt::AutoColor); + + if(deleteSourceBitmap) + delete bitmap; + } +} + +void* QGLPixmapData::toNativeType(NativeType type) +{ + if (type == QPixmapData::FbsBitmap) { + CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); + + if (bitmap) { + QImage image = toImage(); + + TDisplayMode displayMode(EColor16MU); + if (image.format()==QImage::Format_ARGB32_Premultiplied) + displayMode = EColor16MAP; + + if (bitmap->Create(TSize(image.width(), image.height()), + displayMode) == KErrNone) { + const uchar *sptr = const_cast(image).bits(); + bitmap->BeginDataAccess(); + + uchar *dptr = (uchar*)bitmap->DataAddress(); + Mem::Copy(dptr, sptr, image.byteCount()); + + bitmap->EndDataAccess(); + } else { + delete bitmap; + bitmap = 0; + } + } + + return reinterpret_cast(bitmap); + } + return 0; +} + QT_END_NAMESPACE diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index 96631e6..a4066fd 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -129,6 +129,11 @@ public: GLuint bind(bool copyBack = true) const; QGLTexture *texture() const; +#if defined(Q_OS_SYMBIAN) + void* toNativeType(NativeType type); + void fromNativeType(void* pixmap, NativeType type); +#endif + private: bool isValid() const; -- cgit v0.12 From bf1cb011f23f1779fccd8c911afbdc5765fb316d Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Wed, 9 Feb 2011 12:06:04 +0200 Subject: Fix code style in qgl_symbian.cpp Reviewed-by: TRUSTME --- src/opengl/qgl_symbian.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/opengl/qgl_symbian.cpp b/src/opengl/qgl_symbian.cpp index 3426a4c..a9e2248 100644 --- a/src/opengl/qgl_symbian.cpp +++ b/src/opengl/qgl_symbian.cpp @@ -367,7 +367,7 @@ void QGLWidgetPrivate::recreateEglSurface() static CFbsBitmap* createBlitCopy(CFbsBitmap* bitmap) { CFbsBitmap *copy = q_check_ptr(new CFbsBitmap); - if(!copy) + if (!copy) return 0; if (copy->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) { @@ -425,17 +425,17 @@ void QGLPixmapData::fromNativeType(void* pixmap, NativeType type) img = img.copy(); bitmap->EndDataAccess(); - if(displayMode == EGray2) { + if (displayMode == EGray2) { //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid //So invert mono bitmaps so that masks work correctly. img.invertPixels(); - } else if(displayMode == EColor16M) { + } else if (displayMode == EColor16M) { img = img.rgbSwapped(); // EColor16M is BGR } fromImage(img, Qt::AutoColor); - if(deleteSourceBitmap) + if (deleteSourceBitmap) delete bitmap; } } -- cgit v0.12 From ea770c9aa3099facd7adccf5d4a159bc163e7356 Mon Sep 17 00:00:00 2001 From: Jani Hautakangas Date: Wed, 9 Feb 2011 12:49:13 +0200 Subject: Fix for loading QPixmaps from file in GL graphics system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QPixmap::load fails if extension (.png) is left out from given filename when loading a pixmap. QPixmap should try loading with all supported formats. Task-number: QTBUG-17328 Reviewed-by: Samuel Rødal --- src/opengl/qpixmapdata_gl.cpp | 44 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 249c71e..72035bd 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -390,29 +390,29 @@ bool QGLPixmapData::fromFile(const QString &filename, const char *format, if (pixelType() == QPixmapData::BitmapType) return QPixmapData::fromFile(filename, format, flags); QFile file(filename); - if (!file.open(QIODevice::ReadOnly)) - return false; - 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; + 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; } - return false; } QImage image = QImageReader(filename, format).read(); -- cgit v0.12