Commit ad32d9a2d2c3b1202867f8563a69afb93effecd0

Adding support for symbian graphics resources.

This enables us to convert from and to new Symbian type of
graphics resource, namely SgImage. This only supported with
the OpenVG graphics system.
On other graphics systems this will return null QPixmap.

Conflicts:
	src/corelib/global/qglobal.h
	src/gui/image/qpixmap.h
	src/gui/image/qpixmap_s60.cpp

Reviewed-by: Jason Barron
  
6868QMAKE_LIBS_NETWORK =
6969QMAKE_LIBS_EGL = -llibEGL
7070QMAKE_LIBS_OPENGL =
71QMAKE_LIBS_OPENVG = -llibOpenVG
71QMAKE_LIBS_OPENVG = -llibOpenVG -lgraphicsresource
7272QMAKE_LIBS_COMPAT =
7373QMAKE_LIBS_QT_ENTRY = -llibcrt0.lib
7474QMAKE_LIBS_S60 = -lavkon
  
820820# define Q_WS_WIN
821821#endif
822822
823
824823QT_BEGIN_HEADER
825824QT_BEGIN_NAMESPACE
826825
23892389//RWsPointerCursor is fixed, so don't use low performance sprites
23902390#define Q_SYMBIAN_FIXED_POINTER_CURSORS
23912391#define Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
2392//enabling new graphics resources
2393#define QT_SYMBIAN_SUPPORTS_SGIMAGE
23922394#endif
2395
23932396
23942397//Symbian does not support data imports from a DLL
23952398#define Q_NO_DATA_RELOCATION
  
9898// Set pixel format and other properties based on a paint device.
9999void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev)
100100{
101 if(!dev)
102 return;
103
101104 int devType = dev->devType();
102105 if (devType == QInternal::Image)
103106 setPixelFormat(static_cast<QImage *>(dev)->format());
  
2424 image/qpixmap.h \
2525 image/qpixmap_raster_p.h \
2626 image/qpixmapcache.h \
27 image/qpixmapcache_p.h \
27 image/qpixmapcache_p.h \
2828 image/qpixmapdata_p.h \
2929 image/qpixmapdatafactory_p.h \
3030 image/qpixmapfilter_p.h \
  
5454
5555#if defined(Q_OS_SYMBIAN)
5656class CFbsBitmap;
57class RSgImage;
5758#endif
5859
5960QT_BEGIN_NAMESPACE
159159
160160#if defined(Q_OS_SYMBIAN)
161161 enum ConversionMode { CopyData, DuplicateHandle };
162
162
163163 CFbsBitmap *toSymbianCFbsBitmap(ConversionMode mode = DuplicateHandle) const;
164164 static QPixmap fromSymbianCFbsBitmap(CFbsBitmap *bitmap, ConversionMode mode = DuplicateHandle);
165 RSgImage* toSymbianRSgImage() const;
166 static QPixmap fromSymbianRSgImage(RSgImage *sgImage);
165167#endif
166168
167169 inline QPixmap copy(int x, int y, int width, int height) const;
  
4242#include <w32std.h>
4343#include <fbs.h>
4444
45#include <private/qapplication_p.h>
46#include <private/qgraphicssystem_p.h>
4547#include <private/qt_s60_p.h>
4648#include <private/qpaintengine_s60_p.h>
4749
897897 symbianBitmapDataAccess->endDataAccess(cfbsBitmap);
898898}
899899
900/*!
901 \since 4.6
902
903 Returns a QPixmap that wraps given \c RSgImage \a graphics resource.
904 The data should be valid even when original RSgImage handle has been
905 closed.
906
907 \warning This function is only available on Symbian OS.
908
909 \sa toSymbianRSgImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
910*/
911
912QPixmap QPixmap::fromSymbianRSgImage(RSgImage *sgImage)
913{
914 // It is expected that RSgImage will
915 // CURRENTLY be used in conjuction with
916 // OpenVG graphics system
917 //
918 // Surely things might change in future
919
920 if (!sgImage)
921 return QPixmap();
922
923 QPixmap pixmap;
924 pixmap.pixmapData()->fromRSgImage(sgImage);
925
926 return pixmap;
927}
928
929/*!
930\since 4.6
931
932Returns a \c RSgImage that is equivalent to the QPixmap by copying the data.
933
934It is the caller's responsibility to close/delete the \c RSgImage after use.
935
936\warning This function is only available on Symbian OS.
937
938\sa fromSymbianRSgImage()
939*/
940
941RSgImage *QPixmap::toSymbianRSgImage() const
942{
943 // It is expected that RSgImage will
944 // CURRENTLY be used in conjuction with
945 // OpenVG graphics system
946 //
947 // Surely things might change in future
948
949 if (isNull())
950 return 0;
951
952 RSgImage *sgImage = pixmapData()->toRSgImage();
953
954 return sgImage;
955}
900956
901957QT_END_NAMESPACE
  
223223 return 0;
224224}
225225
226#if defined(Q_OS_SYMBIAN)
227RSgImage* QPixmapData::toRSgImage()
228{
229 return 0;
230}
231
232void QPixmapData::fromRSgImage(RSgImage* rsgImage)
233{
234 return;
235}
236#endif
226237QT_END_NAMESPACE
  
5656#include <QtGui/qpixmap.h>
5757#include <QtCore/qatomic.h>
5858
59#if defined(Q_OS_SYMBIAN)
60class RSgImage;
61#endif
62
5963QT_BEGIN_NAMESPACE
6064
6165class Q_GUI_EXPORT QPixmapData
112112 inline int numColors() const { return metric(QPaintDevice::PdmNumColors); }
113113 inline int depth() const { return d; }
114114 inline bool isNull() const { return is_null; }
115
116#if defined(Q_OS_SYMBIAN)
117 virtual RSgImage* toRSgImage();
118 virtual void fromRSgImage(RSgImage* rsgImage);
119#endif
115120
116121protected:
117122 void setSerialNumber(int serNo);
  
4444#include <QtGui/private/qdrawhelper_p.h>
4545#include "qvg_p.h"
4646
47#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
48#include <graphics/sgimage.h>
49typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*);
50typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR);
51typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR);
52#endif
53
4754QT_BEGIN_NAMESPACE
4855
4956static int qt_vg_pixmap_serial = 0;
373373 return VG_INVALID_HANDLE;
374374}
375375
376#if defined(Q_OS_SYMBIAN)
377void QVGPixmapData::cleanup()
378{
379 is_null = w = h = 0;
380 recreate = false;
381 source = QImage();
382}
383
384void QVGPixmapData::fromRSgImage(RSgImage* sgImage)
385{
386 Q_UNUSED(sgImage);
387#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
388 // when "0" used as argument then
389 // default display, context are used
390 if (!context)
391 context = qt_vg_create_context(0);
392
393 if (vgImage != VG_INVALID_HANDLE) {
394 vgDestroyImage(vgImage);
395 vgImage = VG_INVALID_HANDLE;
396 }
397 if (vgImageOpacity != VG_INVALID_HANDLE) {
398 vgDestroyImage(vgImageOpacity);
399 vgImageOpacity = VG_INVALID_HANDLE;
400 }
401
402 TInt err = 0;
403
404 err = SgDriver::Open();
405 if(err != KErrNone) {
406 cleanup();
407 return;
408 }
409
410 if(sgImage->IsNull()) {
411 cleanup();
412 SgDriver::Close();
413 return;
414 }
415
416 TSgImageInfo sgImageInfo;
417 err = sgImage->GetInfo(sgImageInfo);
418 if(err != KErrNone) {
419 cleanup();
420 SgDriver::Close();
421 return;
422 }
423
424 pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");
425 pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");
426 pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
427
428 if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {
429 cleanup();
430 SgDriver::Close();
431 return;
432 }
433
434 const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
435 EGLImageKHR eglImage = eglCreateImageKHR(context->display(),
436 EGL_NO_CONTEXT,
437 EGL_NATIVE_PIXMAP_KHR,
438 (EGLClientBuffer)sgImage,
439 (EGLint*)KEglImageAttribs);
440
441 if(eglGetError() != EGL_SUCCESS) {
442 cleanup();
443 SgDriver::Close();
444 return;
445 }
446
447 vgImage = vgCreateEGLImageTargetKHR(eglImage);
448 if(vgGetError() != VG_NO_ERROR) {
449 cleanup();
450 eglDestroyImageKHR(context->display(), eglImage);
451 SgDriver::Close();
452 return;
453 }
454
455 w = sgImageInfo.iSizeInPixels.iWidth;
456 h = sgImageInfo.iSizeInPixels.iHeight;
457 d = 32; // We always use ARGB_Premultiplied for VG pixmaps.
458 is_null = (w <= 0 || h <= 0);
459 source = QImage();
460 recreate = false;
461 setSerialNumber(++qt_vg_pixmap_serial);
462 // release stuff
463 eglDestroyImageKHR(context->display(), eglImage);
464 SgDriver::Close();
465#else
466#endif
467}
468
469RSgImage* QVGPixmapData::toRSgImage()
470{
471#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
472 toVGImage();
473
474 if(!isValid() || vgImage == VG_INVALID_HANDLE)
475 return 0;
476
477 TInt err = 0;
478
479 err = SgDriver::Open();
480 if(err != KErrNone)
481 return 0;
482
483 TSgImageInfo sgInfo;
484 sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE;
485 sgInfo.iSizeInPixels.SetSize(w, h);
486 sgInfo.iUsage = ESgUsageOpenVgImage | ESgUsageOpenVgTarget;
487 sgInfo.iShareable = ETrue;
488 sgInfo.iCpuAccess = ESgCpuAccessNone;
489 sgInfo.iScreenId = KSgScreenIdMain; //KSgScreenIdAny;
490 sgInfo.iUserAttributes = NULL;
491 sgInfo.iUserAttributeCount = 0;
492
493 RSgImage *sgImage = q_check_ptr(new RSgImage());
494 err = sgImage->Create(sgInfo, NULL, NULL);
495 if(err != KErrNone) {
496 SgDriver::Close();
497 return 0;
498 }
499
500 pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");
501 pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");
502 pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
503
504 if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {
505 SgDriver::Close();
506 return 0;
507 }
508
509 const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
510 EGLImageKHR eglImage = eglCreateImageKHR(context->display(),
511 EGL_NO_CONTEXT,
512 EGL_NATIVE_PIXMAP_KHR,
513 (EGLClientBuffer)sgImage,
514 (EGLint*)KEglImageAttribs);
515 if(eglGetError() != EGL_SUCCESS) {
516 sgImage->Close();
517 SgDriver::Close();
518 return 0;
519 }
520
521 VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage);
522 if(vgGetError() != VG_NO_ERROR) {
523 eglDestroyImageKHR(context->display(), eglImage);
524 sgImage->Close();
525 SgDriver::Close();
526 return 0;
527 }
528
529 vgCopyImage(dstVgImage, 0, 0,
530 vgImage, 0, 0,
531 w, h, VG_FALSE);
532
533 if(vgGetError() != VG_NO_ERROR) {
534 sgImage->Close();
535 sgImage = 0;
536 }
537 // release stuff
538 vgDestroyImage(dstVgImage);
539 eglDestroyImageKHR(context->display(), eglImage);
540 SgDriver::Close();
541 return sgImage;
542#else
543 return 0;
544#endif
545}
546#endif //Q_OS_SYMBIAN
376547QT_END_NAMESPACE
  
5656#include <QtGui/private/qpixmap_raster_p.h>
5757#include <private/qvg_p.h>
5858#if !defined(QT_NO_EGL)
59#include <QtGui/private/qegl_p.h>
6059#endif
6160
61#if defined(Q_OS_SYMBIAN)
62class RSGImage;
63#endif
64
6265QT_BEGIN_NAMESPACE
6366
6467class QEglContext;
9494
9595 QSize size() const { return QSize(w, h); }
9696
97#if defined(Q_OS_SYMBIAN)
98 RSgImage* toRSgImage();
99 void fromRSgImage(RSgImage* sgImage);
100#endif
101
97102protected:
98103 int metric(QPaintDevice::PaintDeviceMetric metric) const;
104
105#if defined(Q_OS_SYMBIAN)
106 void cleanup();
107#endif
99108
100109private:
101110 VGImage vgImage;
  
1414} symbian*: {
1515 DEPLOYMENT_PLUGIN += qmng
1616 LIBS += -lfbscli.dll -lbitgdi.dll -lgdi.dll
17 contains(QT_CONFIG, openvg) {
18 LIBS += $$QMAKE_LIBS_OPENVG
19 }
1720} else {
1821 DEFINES += SRCDIR=\\\"$$PWD\\\"
1922 win32:LIBS += -lgdi32 -luser32