summaryrefslogtreecommitdiffstats
path: root/src/opengl/qpixmapdata_symbiangl.cpp
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2011-07-01 15:38:45 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2011-07-01 15:38:45 (GMT)
commit296f64a839a6af458a98d36da4836cab1d5cbb8e (patch)
treecaca4423ef4e938d5b06944eeb0752b06bba6b10 /src/opengl/qpixmapdata_symbiangl.cpp
parent84f4a8590471928fcd5e98fb424a9b6b89603ef1 (diff)
parent20d1bf0db865c93424c55838833b7d4d2551b758 (diff)
downloadQt-296f64a839a6af458a98d36da4836cab1d5cbb8e.zip
Qt-296f64a839a6af458a98d36da4836cab1d5cbb8e.tar.gz
Qt-296f64a839a6af458a98d36da4836cab1d5cbb8e.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-s60-public into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/qt-s60-public: QS60Style: provide more standard icons Update QtOpenGL section in Symbian platform notes. The qmlshadersplugin deployment must be scoped same as its building Do not try to open VKB if it is already open in Symbian Introduce QPixmap::fromSymbianRSgImage(RSgImage*) to GL engine
Diffstat (limited to 'src/opengl/qpixmapdata_symbiangl.cpp')
-rw-r--r--src/opengl/qpixmapdata_symbiangl.cpp627
1 files changed, 281 insertions, 346 deletions
diff --git a/src/opengl/qpixmapdata_symbiangl.cpp b/src/opengl/qpixmapdata_symbiangl.cpp
index 8c3d61a..372b5ca 100644
--- a/src/opengl/qpixmapdata_symbiangl.cpp
+++ b/src/opengl/qpixmapdata_symbiangl.cpp
@@ -58,181 +58,61 @@
#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();
-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)
+class QGLSgImageTextureCleanup
{
- QGLFramebufferObject *chosen = 0;
- QGLFramebufferObject *candidate = 0;
- for (int i = 0; !chosen && i < m_fbos.size(); ++i) {
- QGLFramebufferObject *fbo = m_fbos.at(i);
+public:
+ QGLSgImageTextureCleanup() {}
- 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;
+ ~QGLSgImageTextureCleanup()
+ {
+ QList<qint64> keys = m_cache.keys();
+ while(keys.size() > 0) {
+ QGLPixmapData *data = m_cache.take(keys.takeAt(0));
+ if (data)
+ data->destroyTexture();
}
}
- if (!chosen) {
- if (strictSize)
- chosen = new QGLFramebufferObject(requestSize, requestFormat);
- else
- chosen = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(requestSize), requestFormat);
- }
+ static QGLSgImageTextureCleanup *cleanupForContext(const QGLContext *context);
- if (!chosen->isValid()) {
- delete chosen;
- chosen = 0;
+ void insert(quint64 key, QGLPixmapData *data)
+ {
+ m_cache.insert(key, data);
}
- 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);
+ void remove(quint64 key)
+ {
+ m_cache.take(key);
}
- 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);
+private:
- // Base's endPaint will restore the previous FBO binding
- QGLPaintDevice::endPaint();
-
- qgl_fbo_pool()->release(data->m_renderFbo);
- data->m_renderFbo = 0;
-}
+ QCache<qint64, QGLPixmapData> m_cache;
+};
-QGLContext* QGLPixmapGLPaintDevice::context() const
+static void qt_sgimage_texture_cleanup_free(void *data)
{
- data->ensureCreated();
- return data->m_ctx;
+ delete reinterpret_cast<QGLSgImageTextureCleanup *>(data);
}
-QSize QGLPixmapGLPaintDevice::size() const
-{
- return data->size();
-}
+Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_sgimage_texture_cleanup, (qt_sgimage_texture_cleanup_free))
-bool QGLPixmapGLPaintDevice::alphaRequested() const
+QGLSgImageTextureCleanup *QGLSgImageTextureCleanup::cleanupForContext(const QGLContext *context)
{
- return data->m_hasAlpha;
-}
-
-void QGLPixmapGLPaintDevice::setPixmapData(QGLPixmapData* d)
-{
- data = d;
+ QGLSgImageTextureCleanup *p = reinterpret_cast<QGLSgImageTextureCleanup *>(qt_sgimage_texture_cleanup()->value(context));
+ if (!p) {
+ QGLShareContextScope scope(context);
+ qt_sgimage_texture_cleanup()->insert(context, p = new QGLSgImageTextureCleanup);
+ }
+ return p;
}
int qt_gl_pixmap_serial = 0;
@@ -244,16 +124,28 @@ QGLPixmapData::QGLPixmapData(PixelType type)
, 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);
- m_glDevice.setPixmapData(this);
}
QGLPixmapData::~QGLPixmapData()
{
+ 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;
+ }
delete m_engine;
}
@@ -275,6 +167,16 @@ bool QGLPixmapData::isValidContext(const QGLContext *ctx) const
// 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;
}
@@ -313,72 +215,45 @@ void QGLPixmapData::ensureCreated() const
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;
-
- if (!m_texture.id) {
- m_texture.id = QGLTexturePool::instance()->createTexture(
- target,
- 0, internal_format,
- w, h,
- external_format,
- type,
- &m_texture);
- if (!m_texture.id) {
- m_texture.failedToAlloc = true;
- return;
- }
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
+ if (m_sgImage) {
+ qt_resolve_eglimage_gl_extensions(ctx); // ensure initialized
- m_texture.inTexturePool = true;
- } else if (m_texture.inTexturePool) {
- glBindTexture(target, m_texture.id);
- QGLTexturePool::instance()->useTexture(&m_texture);
- }
+ bool textureIsBound = false;
+ GLuint newTextureId;
- 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);
+ 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);
- 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);
+ 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 (useFramebufferObjects())
- m_source = QVolatileImage();
+ 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
}
@@ -538,42 +413,7 @@ bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect)
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);
- }
+ QPixmapData::copy(data, rect);
}
void QGLPixmapData::fill(const QColor &color)
@@ -590,11 +430,6 @@ void QGLPixmapData::fill(const QColor &color)
m_hasAlpha = color.alpha() != 255;
}
- if (useFramebufferObjects()) {
- m_source = QVolatileImage();
- m_hasFillColor = true;
- m_fillColor = color;
- } else {
forceToImage();
if (m_source.depth() == 32) {
@@ -605,7 +440,6 @@ void QGLPixmapData::fill(const QColor &color)
m_source.fill(1);
else
m_source.fill(0);
- }
}
}
@@ -645,9 +479,7 @@ QImage QGLPixmapData::toImage() const
if (!isValid())
return QImage();
- if (m_renderFbo) {
- copyBackFromRenderFbo(true);
- } else if (!m_source.isNull()) {
+ if (!m_source.isNull()) {
// QVolatileImage::toImage() will make a copy always so no check
// for active painting is needed.
QImage img = m_source.toImage();
@@ -668,58 +500,9 @@ QImage QGLPixmapData::toImage() const
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();
- }
+ // We don't use FBOs on Symbian
}
bool QGLPixmapData::useFramebufferObjects() const
@@ -733,32 +516,6 @@ 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.
@@ -773,25 +530,16 @@ QPaintEngine* QGLPixmapData::paintEngine() const
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();
- }
+ 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;
@@ -860,7 +608,21 @@ void QGLPixmapData::forceToImage()
void QGLPixmapData::destroyTexture()
{
- // Destroy SgImage texture
+ 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()
@@ -885,7 +647,180 @@ void QGLPixmapData::reclaimTexture()
QGLPaintDevice *QGLPixmapData::glDevice() const
{
- return &m_glDevice;
+ 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;
+ }
+}
+
+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;
+ };
+}
+
+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