/src/opengl/qpixmapdata_symbiangl.cpp
https://bitbucket.org/ultra_iter/qt-vtl · C++ · 836 lines · 654 code · 124 blank · 58 comment · 143 complexity · 0e563717aecc24b3a70f70ea5c6c5d1c MD5 · raw file
- /****************************************************************************
- **
- ** Copyright (C) 2012 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 <fbs.h>
- #include "qgltexturepool_p.h"
- QT_BEGIN_NAMESPACE
- Q_OPENGL_EXPORT extern QGLWidget* qt_gl_share_widget();
- class QGLSgImageTextureCleanup
- {
- public:
- QGLSgImageTextureCleanup(const QGLContext *context = 0) {}
- ~QGLSgImageTextureCleanup()
- {
- QList<qint64> keys = m_cache.keys();
- while(keys.size() > 0) {
- QGLPixmapData *data = m_cache.take(keys.takeAt(0));
- if (data)
- data->destroyTexture();
- }
- }
- static QGLSgImageTextureCleanup *cleanupForContext(const QGLContext *context);
- void insert(quint64 key, QGLPixmapData *data)
- {
- m_cache.insert(key, data);
- }
- void remove(quint64 key)
- {
- m_cache.take(key);
- }
- private:
- QCache<qint64, QGLPixmapData> m_cache;
- };
- #if QT_VERSION >= 0x040800
- Q_GLOBAL_STATIC(QGLContextGroupResource<QGLSgImageTextureCleanup>, qt_sgimage_texture_cleanup)
- #else
- static void qt_sgimage_texture_cleanup_free(void *data)
- {
- delete reinterpret_cast<QGLSgImageTextureCleanup *>(data);
- }
- Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_sgimage_texture_cleanup, (qt_sgimage_texture_cleanup_free))
- #endif
- QGLSgImageTextureCleanup *QGLSgImageTextureCleanup::cleanupForContext(const QGLContext *context)
- {
- QGLSgImageTextureCleanup *p = reinterpret_cast<QGLSgImageTextureCleanup *>(qt_sgimage_texture_cleanup()->value(context));
- #if QT_VERSION < 0x040800
- if (!p) {
- QGLShareContextScope scope(context);
- qt_sgimage_texture_cleanup()->insert(context, p = new QGLSgImageTextureCleanup);
- }
- #endif
- return p;
- }
- 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)
- #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
- , m_sgImage(0)
- #endif
- , m_dirty(false)
- , m_hasFillColor(false)
- , m_hasAlpha(false)
- {
- setSerialNumber(++qt_gl_pixmap_serial);
- }
- QGLPixmapData::~QGLPixmapData()
- {
- #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
- if (m_sgImage) {
- if (m_texture.id) {
- QGLSgImageTextureCleanup::cleanupForContext(m_ctx)->remove(m_texture.id);
- destroyTexture();
- }
- m_sgImage->Close();
- delete m_sgImage;
- m_sgImage = 0;
- }
- #endif
- delete m_engine;
- }
- QPixmapData *QGLPixmapData::createCompatiblePixmapData() const
- {
- return new QGLPixmapData(pixelType());
- }
- bool QGLPixmapData::isValid() const
- {
- return w > 0 && h > 0;
- }
- bool QGLPixmapData::isValidContext(const QGLContext *ctx) const
- {
- // On Symbian, we usually want to treat QGLPixmapData as
- // raster pixmap data because that's well known and tested
- // execution path which is used on other platforms as well.
- // That's why if source pixels are valid we return false
- // to simulate raster pixmaps. Only QPixmaps created from
- // SgImage will enable usage of QGLPixmapData.
- #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
- if (m_sgImage) {
- // SgImage texture
- if (ctx == m_ctx)
- return true;
- const QGLContext *share_ctx = qt_gl_share_widget()->context();
- return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx);
- }
- #endif
- return false;
- }
- 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;
- #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
- if (m_sgImage) {
- qt_resolve_eglimage_gl_extensions(ctx); // ensure initialized
- bool textureIsBound = false;
- GLuint newTextureId;
- EGLint imgAttr[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
- EGLImageKHR image = QEgl::eglCreateImageKHR(QEgl::display()
- , EGL_NO_CONTEXT
- , EGL_NATIVE_PIXMAP_KHR
- , (EGLClientBuffer)m_sgImage
- , imgAttr);
- glGenTextures(1, &newTextureId);
- glBindTexture( GL_TEXTURE_2D, newTextureId);
- if (image != EGL_NO_IMAGE_KHR) {
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
- GLint err = glGetError();
- if (err == GL_NO_ERROR)
- textureIsBound = true;
- QEgl::eglDestroyImageKHR(QEgl::display(), image);
- }
- if (textureIsBound) {
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- m_texture.id = newTextureId;
- m_texture.boundPixmap = const_cast<QGLPixmapData*>(this);
- QGLSgImageTextureCleanup::cleanupForContext(m_ctx)->insert(m_texture.id, const_cast<QGLPixmapData*>(this));
- } else {
- qWarning("QGLPixmapData: Failed to create texture from a SgImage image of size %dx%d", w, h);
- glDeleteTextures(1, &newTextureId);
- }
- }
- #endif
- }
- 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)
- {
- 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;
- }
- 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_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);
- }
- void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const
- {
- // We don't use FBOs on Symbian
- }
- bool QGLPixmapData::useFramebufferObjects() const
- {
- // We don't use FBOs on Symbian for now
- return false;
- }
- QPaintEngine* QGLPixmapData::paintEngine() const
- {
- if (!isValid())
- return 0;
- // 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);
- GLuint QGLPixmapData::bind(bool copyBack) const
- {
- ensureCreated();
- GLuint id = m_texture.id;
- glBindTexture(GL_TEXTURE_2D, id);
- if (m_hasFillColor) {
- 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;
- }
- Q_GUI_EXPORT int qt_defaultDpiX();
- Q_GUI_EXPORT int qt_defaultDpiY();
- 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;
- }
- void QGLPixmapData::destroyTexture()
- {
- if (m_texture.id) {
- QGLWidget *shareWidget = qt_gl_share_widget();
- if (shareWidget) {
- m_texture.options |= QGLContext::MemoryManagedBindOption;
- m_texture.freeTexture();
- m_texture.options &= ~QGLContext::MemoryManagedBindOption;
- } else if(QGLContext::currentContext()) {
- glDeleteTextures(1, &m_texture.id);
- m_texture.id = 0;
- m_texture.boundPixmap = 0;
- m_texture.boundKey = 0;
- }
- m_ctx = 0;
- m_dirty = true;
- }
- }
- void QGLPixmapData::detachTextureFromPool()
- {
- QGLTexturePool::instance()->detachTexture(&m_texture);
- }
- void QGLPixmapData::hibernate()
- {
- destroyTexture();
- }
- void QGLPixmapData::reclaimTexture()
- {
- if (!m_texture.inTexturePool)
- return;
- forceToImage();
- destroyTexture();
- }
- QGLPaintDevice *QGLPixmapData::glDevice() const
- {
- return 0;
- }
- 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;
- }
- }
- #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
- static inline int symbianPixeFormatBitsPerPixel(TUidPixelFormat pixelFormat)
- {
- switch (pixelFormat) {
- case EUidPixelFormatP_1:
- case EUidPixelFormatL_1:
- return 1;
- case EUidPixelFormatP_2:
- case EUidPixelFormatL_2:
- return 2;
- case EUidPixelFormatP_4:
- case EUidPixelFormatL_4:
- return 4;
- case EUidPixelFormatRGB_332:
- case EUidPixelFormatA_8:
- case EUidPixelFormatBGR_332:
- case EUidPixelFormatP_8:
- case EUidPixelFormatL_8:
- return 8;
- case EUidPixelFormatRGB_565:
- case EUidPixelFormatBGR_565:
- case EUidPixelFormatARGB_1555:
- case EUidPixelFormatXRGB_1555:
- case EUidPixelFormatARGB_4444:
- case EUidPixelFormatARGB_8332:
- case EUidPixelFormatBGRX_5551:
- case EUidPixelFormatBGRA_5551:
- case EUidPixelFormatBGRA_4444:
- case EUidPixelFormatBGRX_4444:
- case EUidPixelFormatAP_88:
- case EUidPixelFormatXRGB_4444:
- case EUidPixelFormatXBGR_4444:
- return 16;
- case EUidPixelFormatBGR_888:
- case EUidPixelFormatRGB_888:
- return 24;
- case EUidPixelFormatXRGB_8888:
- case EUidPixelFormatBGRX_8888:
- case EUidPixelFormatXBGR_8888:
- case EUidPixelFormatBGRA_8888:
- case EUidPixelFormatARGB_8888:
- case EUidPixelFormatABGR_8888:
- case EUidPixelFormatARGB_8888_PRE:
- case EUidPixelFormatABGR_8888_PRE:
- case EUidPixelFormatBGRA_8888_PRE:
- case EUidPixelFormatARGB_2101010:
- case EUidPixelFormatABGR_2101010:
- return 32;
- default:
- return 32;
- };
- }
- #endif
- void QGLPixmapData::fromNativeType(void* pixmap, NativeType type)
- {
- if (type == QPixmapData::SgImage && pixmap) {
- #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
- RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmap);
- m_sgImage = new RSgImage;
- m_sgImage->Open(sgImage->Id());
- TSgImageInfo info;
- sgImage->GetInfo(info);
- w = info.iSizeInPixels.iWidth;
- h = info.iSizeInPixels.iHeight;
- d = symbianPixeFormatBitsPerPixel((TUidPixelFormat)info.iPixelFormat);
- m_source = QVolatileImage();
- m_hasAlpha = true;
- m_hasFillColor = false;
- m_dirty = true;
- is_null = (w <= 0 || h <= 0);
- #endif
- } else if (type == QPixmapData::FbsBitmap && pixmap) {
- 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;
- d = m_source.depth();
- } 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;
- d = m_source.depth();
- } 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