40 ****************************************************************************/ |
40 ****************************************************************************/ |
41 |
41 |
42 #include "qpixmapdata_vg_p.h" |
42 #include "qpixmapdata_vg_p.h" |
43 #include "qpaintengine_vg_p.h" |
43 #include "qpaintengine_vg_p.h" |
44 #include <QtGui/private/qdrawhelper_p.h> |
44 #include <QtGui/private/qdrawhelper_p.h> |
|
45 #if !defined(QT_NO_EGL) |
|
46 #include <QtGui/private/qegl_p.h> |
|
47 #endif |
45 #include "qvg_p.h" |
48 #include "qvg_p.h" |
46 #include "qvgimagepool_p.h" |
49 #include "qvgimagepool_p.h" |
47 |
50 |
48 #if defined(Q_OS_SYMBIAN) |
51 #if defined(Q_OS_SYMBIAN) |
49 #include <private/qt_s60_p.h> |
52 #include <private/qt_s60_p.h> |
50 #include <fbs.h> |
53 #include <fbs.h> |
51 #endif |
54 #endif |
52 #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE |
55 #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE |
53 #include <sgresource/sgimage.h> |
56 #include <sgresource/sgimage.h> |
54 typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*); |
|
55 typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR); |
|
56 typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR); |
57 typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR); |
57 #endif // QT_SYMBIAN_SUPPORTS_SGIMAGE |
58 #endif // QT_SYMBIAN_SUPPORTS_SGIMAGE |
58 |
59 |
59 QT_BEGIN_NAMESPACE |
60 QT_BEGIN_NAMESPACE |
60 |
61 |
231 // This is simpler than juggling multiple VG contexts. |
232 // This is simpler than juggling multiple VG contexts. |
232 const_cast<QVGPixmapData *>(this)->forceToImage(); |
233 const_cast<QVGPixmapData *>(this)->forceToImage(); |
233 return source.paintEngine(); |
234 return source.paintEngine(); |
234 } |
235 } |
235 |
236 |
236 // This function works around QImage::bits() making a deep copy if the |
|
237 // QImage is not const. We force it to be const and then get the bits. |
|
238 // XXX: Should add a QImage::constBits() in the future to replace this. |
|
239 const uchar *qt_vg_imageBits(const QImage& image) |
|
240 { |
|
241 return image.bits(); |
|
242 } |
|
243 |
|
244 VGImage QVGPixmapData::toVGImage() |
237 VGImage QVGPixmapData::toVGImage() |
245 { |
238 { |
246 if (!isValid()) |
239 if (!isValid()) |
247 return VG_INVALID_HANDLE; |
240 return VG_INVALID_HANDLE; |
248 |
241 |
271 } |
264 } |
272 |
265 |
273 if (!source.isNull() && recreate) { |
266 if (!source.isNull() && recreate) { |
274 vgImageSubData |
267 vgImageSubData |
275 (vgImage, |
268 (vgImage, |
276 qt_vg_imageBits(source), source.bytesPerLine(), |
269 source.constBits(), source.bytesPerLine(), |
277 VG_sARGB_8888_PRE, 0, 0, w, h); |
270 VG_sARGB_8888_PRE, 0, 0, w, h); |
278 } |
271 } |
279 |
272 |
280 recreate = false; |
273 recreate = false; |
281 prevSize = QSize(w, h); |
274 prevSize = QSize(w, h); |
494 cleanup(); |
487 cleanup(); |
495 driver.Close(); |
488 driver.Close(); |
496 return; |
489 return; |
497 } |
490 } |
498 |
491 |
499 pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); |
|
500 pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); |
|
501 pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); |
492 pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); |
502 |
493 |
503 if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { |
494 if (eglGetError() != EGL_SUCCESS || !(QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) || !vgCreateEGLImageTargetKHR) { |
504 cleanup(); |
495 cleanup(); |
505 driver.Close(); |
496 driver.Close(); |
506 return; |
497 return; |
507 } |
498 } |
508 |
499 |
509 const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; |
500 const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; |
510 EGLImageKHR eglImage = eglCreateImageKHR(QEglContext::display(), |
501 EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(), |
511 EGL_NO_CONTEXT, |
502 EGL_NO_CONTEXT, |
512 EGL_NATIVE_PIXMAP_KHR, |
503 EGL_NATIVE_PIXMAP_KHR, |
513 (EGLClientBuffer)sgImage, |
504 (EGLClientBuffer)sgImage, |
514 (EGLint*)KEglImageAttribs); |
505 (EGLint*)KEglImageAttribs); |
515 |
506 |
534 source = QImage(); |
525 source = QImage(); |
535 recreate = false; |
526 recreate = false; |
536 prevSize = QSize(w, h); |
527 prevSize = QSize(w, h); |
537 setSerialNumber(++qt_vg_pixmap_serial); |
528 setSerialNumber(++qt_vg_pixmap_serial); |
538 // release stuff |
529 // release stuff |
539 eglDestroyImageKHR(QEglContext::display(), eglImage); |
530 QEgl::eglDestroyImageKHR(QEgl::display(), eglImage); |
540 driver.Close(); |
531 driver.Close(); |
541 #endif |
532 #endif |
542 } else if (type == QPixmapData::FbsBitmap) { |
533 } else if (type == QPixmapData::FbsBitmap) { |
543 CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap); |
534 CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap); |
544 |
535 |
612 if (err != KErrNone) { |
603 if (err != KErrNone) { |
613 driver.Close(); |
604 driver.Close(); |
614 return 0; |
605 return 0; |
615 } |
606 } |
616 |
607 |
617 pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); |
|
618 pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); |
|
619 pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); |
608 pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); |
620 |
609 |
621 if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { |
610 if (eglGetError() != EGL_SUCCESS || !(QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) || !vgCreateEGLImageTargetKHR) { |
622 driver.Close(); |
611 driver.Close(); |
623 return 0; |
612 return 0; |
624 } |
613 } |
625 |
614 |
626 const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; |
615 const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; |
627 EGLImageKHR eglImage = eglCreateImageKHR(QEglContext::display(), |
616 EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(), |
628 EGL_NO_CONTEXT, |
617 EGL_NO_CONTEXT, |
629 EGL_NATIVE_PIXMAP_KHR, |
618 EGL_NATIVE_PIXMAP_KHR, |
630 (EGLClientBuffer)sgImage, |
619 (EGLClientBuffer)sgImage, |
631 (EGLint*)KEglImageAttribs); |
620 (EGLint*)KEglImageAttribs); |
632 if (eglGetError() != EGL_SUCCESS) { |
621 if (eglGetError() != EGL_SUCCESS) { |
651 sgImage->Close(); |
640 sgImage->Close(); |
652 sgImage = 0; |
641 sgImage = 0; |
653 } |
642 } |
654 // release stuff |
643 // release stuff |
655 vgDestroyImage(dstVgImage); |
644 vgDestroyImage(dstVgImage); |
656 eglDestroyImageKHR(QEglContext::display(), eglImage); |
645 QEgl::eglDestroyImageKHR(QEgl::display(), eglImage); |
657 driver.Close(); |
646 driver.Close(); |
658 return reinterpret_cast<void*>(sgImage); |
647 return reinterpret_cast<void*>(sgImage); |
659 #endif |
648 #endif |
660 } else if (type == QPixmapData::FbsBitmap) { |
649 } else if (type == QPixmapData::FbsBitmap) { |
661 CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); |
650 CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); |
662 |
651 |
663 if (bitmap) { |
652 if (bitmap) { |
664 if (bitmap->Create(TSize(source.width(), source.height()), |
653 if (bitmap->Create(TSize(source.width(), source.height()), |
665 EColor16MAP) == KErrNone) { |
654 EColor16MAP) == KErrNone) { |
666 const uchar *sptr = qt_vg_imageBits(source); |
655 const uchar *sptr = source.constBits(); |
667 bitmap->BeginDataAccess(); |
656 bitmap->BeginDataAccess(); |
668 |
657 |
669 uchar *dptr = (uchar*)bitmap->DataAddress(); |
658 uchar *dptr = (uchar*)bitmap->DataAddress(); |
670 Mem::Copy(dptr, sptr, source.byteCount()); |
659 Mem::Copy(dptr, sptr, source.byteCount()); |
671 |
660 |