Warning: That file was not part of the compilation database. It may have many parsing errors.

1/****************************************************************************
2**
3** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the QtOpenGL module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Digia. For licensing terms and
14** conditions see http://qt.digia.com/licensing. For further information
15** use the contact form at http://qt.digia.com/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Digia gives you certain additional
26** rights. These rights are described in the Digia Qt LGPL Exception
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28**
29** GNU General Public License Usage
30** Alternatively, this file may be used under the terms of the GNU
31** General Public License version 3.0 as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL included in the
33** packaging of this file. Please review the following information to
34** ensure the GNU General Public License version 3.0 requirements will be
35** met: http://www.gnu.org/copyleft/gpl.html.
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qpixmap.h"
43#include "qglframebufferobject.h"
44
45#include <private/qpaintengine_raster_p.h>
46
47#include "qpixmapdata_gl_p.h"
48
49#include <private/qgl_p.h>
50#include <private/qdrawhelper_p.h>
51#include <private/qimage_p.h>
52#include <private/qnativeimagehandleprovider_p.h>
53#include <private/qfont_p.h>
54
55#include <private/qpaintengineex_opengl2_p.h>
56
57#include <qdesktopwidget.h>
58#include <qfile.h>
59#include <qimagereader.h>
60#include <qbuffer.h>
61
62#include <fbs.h>
63
64#include "qgltexturepool_p.h"
65
66QT_BEGIN_NAMESPACE
67
68Q_OPENGL_EXPORT extern QGLWidget* qt_gl_share_widget();
69
70class QGLSgImageTextureCleanup
71{
72public:
73 QGLSgImageTextureCleanup(const QGLContext *context = 0) {}
74
75 ~QGLSgImageTextureCleanup()
76 {
77 QList<qint64> keys = m_cache.keys();
78 while(keys.size() > 0) {
79 QGLPixmapData *data = m_cache.take(keys.takeAt(0));
80 if (data)
81 data->destroyTexture();
82 }
83 }
84
85 static QGLSgImageTextureCleanup *cleanupForContext(const QGLContext *context);
86
87 void insert(quint64 key, QGLPixmapData *data)
88 {
89 m_cache.insert(key, data);
90 }
91
92 void remove(quint64 key)
93 {
94 m_cache.take(key);
95 }
96
97private:
98
99 QCache<qint64, QGLPixmapData> m_cache;
100};
101
102#if QT_VERSION >= 0x040800
103Q_GLOBAL_STATIC(QGLContextGroupResource<QGLSgImageTextureCleanup>, qt_sgimage_texture_cleanup)
104#else
105static void qt_sgimage_texture_cleanup_free(void *data)
106{
107 delete reinterpret_cast<QGLSgImageTextureCleanup *>(data);
108}
109Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_sgimage_texture_cleanup, (qt_sgimage_texture_cleanup_free))
110#endif
111
112QGLSgImageTextureCleanup *QGLSgImageTextureCleanup::cleanupForContext(const QGLContext *context)
113{
114 QGLSgImageTextureCleanup *p = reinterpret_cast<QGLSgImageTextureCleanup *>(qt_sgimage_texture_cleanup()->value(context));
115#if QT_VERSION < 0x040800
116 if (!p) {
117 QGLShareContextScope scope(context);
118 qt_sgimage_texture_cleanup()->insert(context, p = new QGLSgImageTextureCleanup);
119 }
120#endif
121 return p;
122}
123
124int qt_gl_pixmap_serial = 0;
125
126QGLPixmapData::QGLPixmapData(PixelType type)
127 : QPixmapData(type, OpenGLClass)
128 , m_renderFbo(0)
129 , m_engine(0)
130 , m_ctx(0)
131 , nativeImageHandleProvider(0)
132 , nativeImageHandle(0)
133#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
134 , m_sgImage(0)
135#endif
136 , m_dirty(false)
137 , m_hasFillColor(false)
138 , m_hasAlpha(false)
139{
140 setSerialNumber(++qt_gl_pixmap_serial);
141}
142
143QGLPixmapData::~QGLPixmapData()
144{
145#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
146 if (m_sgImage) {
147 if (m_texture.id) {
148 QGLSgImageTextureCleanup::cleanupForContext(m_ctx)->remove(m_texture.id);
149 destroyTexture();
150 }
151
152 m_sgImage->Close();
153 delete m_sgImage;
154 m_sgImage = 0;
155 }
156#endif
157 delete m_engine;
158}
159
160QPixmapData *QGLPixmapData::createCompatiblePixmapData() const
161{
162 return new QGLPixmapData(pixelType());
163}
164
165bool QGLPixmapData::isValid() const
166{
167 return w > 0 && h > 0;
168}
169
170bool QGLPixmapData::isValidContext(const QGLContext *ctx) const
171{
172 // On Symbian, we usually want to treat QGLPixmapData as
173 // raster pixmap data because that's well known and tested
174 // execution path which is used on other platforms as well.
175 // That's why if source pixels are valid we return false
176 // to simulate raster pixmaps. Only QPixmaps created from
177 // SgImage will enable usage of QGLPixmapData.
178#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
179 if (m_sgImage) {
180 // SgImage texture
181 if (ctx == m_ctx)
182 return true;
183
184 const QGLContext *share_ctx = qt_gl_share_widget()->context();
185 return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx);
186 }
187#endif
188 return false;
189}
190
191void QGLPixmapData::resize(int width, int height)
192{
193 if (width == w && height == h)
194 return;
195
196 if (width <= 0 || height <= 0) {
197 width = 0;
198 height = 0;
199 }
200
201 w = width;
202 h = height;
203 is_null = (w <= 0 || h <= 0);
204 d = pixelType() == QPixmapData::PixmapType ? 32 : 1;
205
206 destroyTexture();
207
208 m_source = QVolatileImage();
209 m_dirty = isValid();
210 setSerialNumber(++qt_gl_pixmap_serial);
211}
212
213void QGLPixmapData::ensureCreated() const
214{
215 if (!m_dirty)
216 return;
217
218 m_dirty = false;
219
220 if (nativeImageHandleProvider && !nativeImageHandle)
221 const_cast<QGLPixmapData *>(this)->createFromNativeImageHandleProvider();
222
223 QGLShareContextScope ctx(qt_gl_share_widget()->context());
224 m_ctx = ctx;
225
226#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
227 if (m_sgImage) {
228 qt_resolve_eglimage_gl_extensions(ctx); // ensure initialized
229
230 bool textureIsBound = false;
231 GLuint newTextureId;
232
233 EGLint imgAttr[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
234 EGLImageKHR image = QEgl::eglCreateImageKHR(QEgl::display()
235 , EGL_NO_CONTEXT
236 , EGL_NATIVE_PIXMAP_KHR
237 , (EGLClientBuffer)m_sgImage
238 , imgAttr);
239
240 glGenTextures(1, &newTextureId);
241 glBindTexture( GL_TEXTURE_2D, newTextureId);
242
243 if (image != EGL_NO_IMAGE_KHR) {
244 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
245 GLint err = glGetError();
246 if (err == GL_NO_ERROR)
247 textureIsBound = true;
248
249 QEgl::eglDestroyImageKHR(QEgl::display(), image);
250 }
251
252 if (textureIsBound) {
253 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
254 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
255
256 m_texture.id = newTextureId;
257 m_texture.boundPixmap = const_cast<QGLPixmapData*>(this);
258 QGLSgImageTextureCleanup::cleanupForContext(m_ctx)->insert(m_texture.id, const_cast<QGLPixmapData*>(this));
259 } else {
260 qWarning("QGLPixmapData: Failed to create texture from a SgImage image of size %dx%d", w, h);
261 glDeleteTextures(1, &newTextureId);
262 }
263 }
264#endif
265}
266
267
268void QGLPixmapData::fromImage(const QImage &image,
269 Qt::ImageConversionFlags flags)
270{
271 QImage img = image;
272 createPixmapForImage(img, flags, false);
273}
274
275void QGLPixmapData::fromImageReader(QImageReader *imageReader,
276 Qt::ImageConversionFlags flags)
277{
278 QImage image = imageReader->read();
279 if (image.isNull())
280 return;
281
282 createPixmapForImage(image, flags, true);
283}
284
285bool QGLPixmapData::fromFile(const QString &filename, const char *format,
286 Qt::ImageConversionFlags flags)
287{
288 if (pixelType() == QPixmapData::BitmapType)
289 return QPixmapData::fromFile(filename, format, flags);
290 QFile file(filename);
291 if (file.open(QIODevice::ReadOnly)) {
292 QByteArray data = file.peek(64);
293 bool alpha;
294 if (m_texture.canBindCompressedTexture
295 (data.constData(), data.size(), format, &alpha)) {
296 resize(0, 0);
297 data = file.readAll();
298 file.close();
299 QGLShareContextScope ctx(qt_gl_share_widget()->context());
300 QSize size = m_texture.bindCompressedTexture
301 (data.constData(), data.size(), format);
302 if (!size.isEmpty()) {
303 w = size.width();
304 h = size.height();
305 is_null = false;
306 d = 32;
307 m_hasAlpha = alpha;
308 m_source = QVolatileImage();
309 m_dirty = isValid();
310 return true;
311 }
312 return false;
313 }
314 }
315
316 QImage image = QImageReader(filename, format).read();
317 if (image.isNull())
318 return false;
319
320 createPixmapForImage(image, flags, true);
321
322 return !isNull();
323}
324
325bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format,
326 Qt::ImageConversionFlags flags)
327{
328 bool alpha;
329 const char *buf = reinterpret_cast<const char *>(buffer);
330 if (m_texture.canBindCompressedTexture(buf, int(len), format, &alpha)) {
331 resize(0, 0);
332 QGLShareContextScope ctx(qt_gl_share_widget()->context());
333 QSize size = m_texture.bindCompressedTexture(buf, int(len), format);
334 if (!size.isEmpty()) {
335 w = size.width();
336 h = size.height();
337 is_null = false;
338 d = 32;
339 m_hasAlpha = alpha;
340 m_source = QVolatileImage();
341 m_dirty = isValid();
342 return true;
343 }
344 }
345
346 QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len);
347 QBuffer b(&a);
348 b.open(QIODevice::ReadOnly);
349 QImage image = QImageReader(&b, format).read();
350 if (image.isNull())
351 return false;
352
353 createPixmapForImage(image, flags, true);
354
355 return !isNull();
356}
357
358QImage::Format QGLPixmapData::idealFormat(QImage &image, Qt::ImageConversionFlags flags)
359{
360 QImage::Format format = QImage::Format_RGB32;
361 if (qApp->desktop()->depth() == 16)
362 format = QImage::Format_RGB16;
363
364 if (image.hasAlphaChannel()
365 && ((flags & Qt::NoOpaqueDetection)
366 || const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()))
367 format = QImage::Format_ARGB32_Premultiplied;
368
369 return format;
370}
371
372void QGLPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
373{
374 if (image.size() == QSize(w, h))
375 setSerialNumber(++qt_gl_pixmap_serial);
376
377 resize(image.width(), image.height());
378
379 if (pixelType() == BitmapType) {
380 QImage convertedImage = image.convertToFormat(QImage::Format_MonoLSB);
381 if (image.format() == QImage::Format_MonoLSB)
382 convertedImage.detach();
383
384 m_source = QVolatileImage(convertedImage);
385
386 } else {
387 QImage::Format format = idealFormat(image, flags);
388
389 if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
390 m_source = QVolatileImage(image);
391 } else {
392 QImage convertedImage = image.convertToFormat(format);
393
394 // convertToFormat won't detach the image if format stays the same.
395 if (image.format() == format)
396 convertedImage.detach();
397
398 m_source = QVolatileImage(convertedImage);
399 }
400 }
401
402 m_dirty = true;
403 m_hasFillColor = false;
404
405 m_hasAlpha = m_source.hasAlphaChannel();
406 w = image.width();
407 h = image.height();
408 is_null = (w <= 0 || h <= 0);
409 d = m_source.depth();
410
411 destroyTexture();
412}
413
414bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect)
415{
416 Q_UNUSED(dx);
417 Q_UNUSED(dy);
418 Q_UNUSED(rect);
419 return false;
420}
421
422void QGLPixmapData::copy(const QPixmapData *data, const QRect &rect)
423{
424 QPixmapData::copy(data, rect);
425}
426
427void QGLPixmapData::fill(const QColor &color)
428{
429 if (!isValid())
430 return;
431
432 bool hasAlpha = color.alpha() != 255;
433 if (hasAlpha && !m_hasAlpha) {
434 if (m_texture.id) {
435 destroyTexture();
436 m_dirty = true;
437 }
438 m_hasAlpha = color.alpha() != 255;
439 }
440
441 forceToImage();
442
443 if (m_source.depth() == 32) {
444 m_source.fill(PREMUL(color.rgba()));
445
446 } else if (m_source.depth() == 1) {
447 if (color == Qt::color1)
448 m_source.fill(1);
449 else
450 m_source.fill(0);
451 }
452}
453
454bool QGLPixmapData::hasAlphaChannel() const
455{
456 return m_hasAlpha;
457}
458
459QImage QGLPixmapData::fillImage(const QColor &color) const
460{
461 QImage img;
462 if (pixelType() == BitmapType) {
463 img = QImage(w, h, QImage::Format_MonoLSB);
464
465 img.setColorCount(2);
466 img.setColor(0, QColor(Qt::color0).rgba());
467 img.setColor(1, QColor(Qt::color1).rgba());
468
469 if (color == Qt::color1)
470 img.fill(1);
471 else
472 img.fill(0);
473 } else {
474 img = QImage(w, h,
475 m_hasAlpha
476 ? QImage::Format_ARGB32_Premultiplied
477 : QImage::Format_RGB32);
478 img.fill(PREMUL(color.rgba()));
479 }
480 return img;
481}
482
483extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha);
484
485QImage QGLPixmapData::toImage() const
486{
487 if (!isValid())
488 return QImage();
489
490 if (!m_source.isNull()) {
491 // QVolatileImage::toImage() will make a copy always so no check
492 // for active painting is needed.
493 QImage img = m_source.toImage();
494 if (img.format() == QImage::Format_MonoLSB) {
495 img.setColorCount(2);
496 img.setColor(0, QColor(Qt::color0).rgba());
497 img.setColor(1, QColor(Qt::color1).rgba());
498 }
499 return img;
500 } else if (m_dirty || m_hasFillColor) {
501 return fillImage(m_fillColor);
502 } else {
503 ensureCreated();
504 }
505
506 QGLShareContextScope ctx(qt_gl_share_widget()->context());
507 glBindTexture(GL_TEXTURE_2D, m_texture.id);
508 return qt_gl_read_texture(QSize(w, h), true, true);
509}
510
511void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const
512{
513 // We don't use FBOs on Symbian
514}
515
516bool QGLPixmapData::useFramebufferObjects() const
517{
518 // We don't use FBOs on Symbian for now
519 return false;
520}
521
522QPaintEngine* QGLPixmapData::paintEngine() const
523{
524 if (!isValid())
525 return 0;
526
527 // If the application wants to paint into the QPixmap, we first
528 // force it to QImage format and then paint into that.
529 // This is simpler than juggling multiple GL contexts.
530 const_cast<QGLPixmapData *>(this)->forceToImage();
531
532 if (m_hasFillColor) {
533 m_source.fill(PREMUL(m_fillColor.rgba()));
534 m_hasFillColor = false;
535 }
536 return m_source.paintEngine();
537}
538
539extern QRgb qt_gl_convertToGLFormat(QRgb src_pixel, GLenum texture_format);
540
541GLuint QGLPixmapData::bind(bool copyBack) const
542{
543 ensureCreated();
544
545 GLuint id = m_texture.id;
546 glBindTexture(GL_TEXTURE_2D, id);
547
548 if (m_hasFillColor) {
549 m_source = QVolatileImage(w, h, QImage::Format_ARGB32_Premultiplied);
550 m_source.fill(PREMUL(m_fillColor.rgba()));
551
552 m_hasFillColor = false;
553
554 GLenum format = qt_gl_preferredTextureFormat();
555 QImage tx(w, h, QImage::Format_ARGB32_Premultiplied);
556 tx.fill(qt_gl_convertToGLFormat(m_fillColor.rgba(), format));
557 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.constBits());
558 }
559
560 return id;
561}
562
563QGLTexture* QGLPixmapData::texture() const
564{
565 return &m_texture;
566}
567
568Q_GUI_EXPORT int qt_defaultDpiX();
569Q_GUI_EXPORT int qt_defaultDpiY();
570
571int QGLPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
572{
573 if (w == 0)
574 return 0;
575
576 switch (metric) {
577 case QPaintDevice::PdmWidth:
578 return w;
579 case QPaintDevice::PdmHeight:
580 return h;
581 case QPaintDevice::PdmNumColors:
582 return 0;
583 case QPaintDevice::PdmDepth:
584 return d;
585 case QPaintDevice::PdmWidthMM:
586 return qRound(w * 25.4 / qt_defaultDpiX());
587 case QPaintDevice::PdmHeightMM:
588 return qRound(h * 25.4 / qt_defaultDpiY());
589 case QPaintDevice::PdmDpiX:
590 case QPaintDevice::PdmPhysicalDpiX:
591 return qt_defaultDpiX();
592 case QPaintDevice::PdmDpiY:
593 case QPaintDevice::PdmPhysicalDpiY:
594 return qt_defaultDpiY();
595 default:
596 qWarning("QGLPixmapData::metric(): Invalid metric");
597 return 0;
598 }
599}
600
601// Force the pixmap data to be backed by some valid data.
602void QGLPixmapData::forceToImage()
603{
604 if (!isValid())
605 return;
606
607 if (m_source.isNull()) {
608 QImage::Format format = QImage::Format_ARGB32_Premultiplied;
609 if (pixelType() == BitmapType)
610 format = QImage::Format_MonoLSB;
611 m_source = QVolatileImage(w, h, format);
612 }
613
614 m_dirty = true;
615}
616
617void QGLPixmapData::destroyTexture()
618{
619 if (m_texture.id) {
620 QGLWidget *shareWidget = qt_gl_share_widget();
621 if (shareWidget) {
622 m_texture.options |= QGLContext::MemoryManagedBindOption;
623 m_texture.freeTexture();
624 m_texture.options &= ~QGLContext::MemoryManagedBindOption;
625 } else if(QGLContext::currentContext()) {
626 glDeleteTextures(1, &m_texture.id);
627 m_texture.id = 0;
628 m_texture.boundPixmap = 0;
629 m_texture.boundKey = 0;
630 }
631 m_ctx = 0;
632 m_dirty = true;
633 }
634}
635
636void QGLPixmapData::detachTextureFromPool()
637{
638 QGLTexturePool::instance()->detachTexture(&m_texture);
639}
640
641void QGLPixmapData::hibernate()
642{
643 destroyTexture();
644}
645
646void QGLPixmapData::reclaimTexture()
647{
648 if (!m_texture.inTexturePool)
649 return;
650
651 forceToImage();
652
653 destroyTexture();
654}
655
656QGLPaintDevice *QGLPixmapData::glDevice() const
657{
658 return 0;
659}
660
661static inline bool knownGoodFormat(QImage::Format format)
662{
663 switch (format) {
664 case QImage::Format_RGB16: // EColor64K
665 case QImage::Format_RGB32: // EColor16MU
666 case QImage::Format_ARGB32_Premultiplied: // EColor16MAP
667 return true;
668 default:
669 return false;
670 }
671}
672
673#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
674static inline int symbianPixeFormatBitsPerPixel(TUidPixelFormat pixelFormat)
675{
676 switch (pixelFormat) {
677 case EUidPixelFormatP_1:
678 case EUidPixelFormatL_1:
679 return 1;
680 case EUidPixelFormatP_2:
681 case EUidPixelFormatL_2:
682 return 2;
683 case EUidPixelFormatP_4:
684 case EUidPixelFormatL_4:
685 return 4;
686 case EUidPixelFormatRGB_332:
687 case EUidPixelFormatA_8:
688 case EUidPixelFormatBGR_332:
689 case EUidPixelFormatP_8:
690 case EUidPixelFormatL_8:
691 return 8;
692 case EUidPixelFormatRGB_565:
693 case EUidPixelFormatBGR_565:
694 case EUidPixelFormatARGB_1555:
695 case EUidPixelFormatXRGB_1555:
696 case EUidPixelFormatARGB_4444:
697 case EUidPixelFormatARGB_8332:
698 case EUidPixelFormatBGRX_5551:
699 case EUidPixelFormatBGRA_5551:
700 case EUidPixelFormatBGRA_4444:
701 case EUidPixelFormatBGRX_4444:
702 case EUidPixelFormatAP_88:
703 case EUidPixelFormatXRGB_4444:
704 case EUidPixelFormatXBGR_4444:
705 return 16;
706 case EUidPixelFormatBGR_888:
707 case EUidPixelFormatRGB_888:
708 return 24;
709 case EUidPixelFormatXRGB_8888:
710 case EUidPixelFormatBGRX_8888:
711 case EUidPixelFormatXBGR_8888:
712 case EUidPixelFormatBGRA_8888:
713 case EUidPixelFormatARGB_8888:
714 case EUidPixelFormatABGR_8888:
715 case EUidPixelFormatARGB_8888_PRE:
716 case EUidPixelFormatABGR_8888_PRE:
717 case EUidPixelFormatBGRA_8888_PRE:
718 case EUidPixelFormatARGB_2101010:
719 case EUidPixelFormatABGR_2101010:
720 return 32;
721 default:
722 return 32;
723 };
724}
725#endif
726
727void QGLPixmapData::fromNativeType(void* pixmap, NativeType type)
728{
729 if (type == QPixmapData::SgImage && pixmap) {
730#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
731 RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmap);
732
733 m_sgImage = new RSgImage;
734 m_sgImage->Open(sgImage->Id());
735
736 TSgImageInfo info;
737 sgImage->GetInfo(info);
738
739 w = info.iSizeInPixels.iWidth;
740 h = info.iSizeInPixels.iHeight;
741 d = symbianPixeFormatBitsPerPixel((TUidPixelFormat)info.iPixelFormat);
742
743 m_source = QVolatileImage();
744 m_hasAlpha = true;
745 m_hasFillColor = false;
746 m_dirty = true;
747 is_null = (w <= 0 || h <= 0);
748#endif
749 } else if (type == QPixmapData::FbsBitmap && pixmap) {
750 CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap *>(pixmap);
751 QSize size(bitmap->SizeInPixels().iWidth, bitmap->SizeInPixels().iHeight);
752 if (size.width() == w && size.height() == h)
753 setSerialNumber(++qt_gl_pixmap_serial);
754 resize(size.width(), size.height());
755 m_source = QVolatileImage(bitmap);
756 if (pixelType() == BitmapType) {
757 m_source.ensureFormat(QImage::Format_MonoLSB);
758 } else if (!knownGoodFormat(m_source.format())) {
759 m_source.beginDataAccess();
760 QImage::Format format = idealFormat(m_source.imageRef(), Qt::AutoColor);
761 m_source.endDataAccess(true);
762 m_source.ensureFormat(format);
763 }
764 m_hasAlpha = m_source.hasAlphaChannel();
765 m_hasFillColor = false;
766 m_dirty = true;
767 d = m_source.depth();
768 } else if (type == QPixmapData::VolatileImage && pixmap) {
769 // Support QS60Style in more efficient skin graphics retrieval.
770 QVolatileImage *img = static_cast<QVolatileImage *>(pixmap);
771 if (img->width() == w && img->height() == h)
772 setSerialNumber(++qt_gl_pixmap_serial);
773 resize(img->width(), img->height());
774 m_source = *img;
775 m_hasAlpha = m_source.hasAlphaChannel();
776 m_hasFillColor = false;
777 m_dirty = true;
778 d = m_source.depth();
779 } else if (type == QPixmapData::NativeImageHandleProvider && pixmap) {
780 destroyTexture();
781 nativeImageHandleProvider = static_cast<QNativeImageHandleProvider *>(pixmap);
782 // Cannot defer the retrieval, we need at least the size right away.
783 createFromNativeImageHandleProvider();
784 }
785}
786
787void* QGLPixmapData::toNativeType(NativeType type)
788{
789 if (type == QPixmapData::FbsBitmap) {
790 if (m_source.isNull())
791 m_source = QVolatileImage(w, h, QImage::Format_ARGB32_Premultiplied);
792 return m_source.duplicateNativeImage();
793 }
794
795 return 0;
796}
797
798bool QGLPixmapData::initFromNativeImageHandle(void *handle, const QString &type)
799{
800 if (type == QLatin1String("RSgImage")) {
801 fromNativeType(handle, QPixmapData::SgImage);
802 return true;
803 } else if (type == QLatin1String("CFbsBitmap")) {
804 fromNativeType(handle, QPixmapData::FbsBitmap);
805 return true;
806 }
807 return false;
808}
809
810void QGLPixmapData::createFromNativeImageHandleProvider()
811{
812 void *handle = 0;
813 QString type;
814 nativeImageHandleProvider->get(&handle, &type);
815 if (handle) {
816 if (initFromNativeImageHandle(handle, type)) {
817 nativeImageHandle = handle;
818 nativeImageType = type;
819 } else {
820 qWarning("QGLPixmapData: Unknown native image type '%s'", qPrintable(type));
821 }
822 } else {
823 qWarning("QGLPixmapData: Native handle is null");
824 }
825}
826
827void QGLPixmapData::releaseNativeImageHandle()
828{
829 if (nativeImageHandleProvider && nativeImageHandle) {
830 nativeImageHandleProvider->release(nativeImageHandle, nativeImageType);
831 nativeImageHandle = 0;
832 nativeImageType = QString();
833 }
834}
835
836QT_END_NAMESPACE
837

Warning: That file was not part of the compilation database. It may have many parsing errors.