37 ** |
37 ** |
38 ** $QT_END_LICENSE$ |
38 ** $QT_END_LICENSE$ |
39 ** |
39 ** |
40 ****************************************************************************/ |
40 ****************************************************************************/ |
41 |
41 |
|
42 #include "../src/gui/egl/qegl_p.h" |
42 #include "qpixmapdata_vg_p.h" |
43 #include "qpixmapdata_vg_p.h" |
43 #include "qpaintengine_vg_p.h" |
44 #include "qpaintengine_vg_p.h" |
44 #include <QtGui/private/qdrawhelper_p.h> |
45 #include <QtGui/private/qdrawhelper_p.h> |
45 #include "qvg_p.h" |
46 #include "qvg_p.h" |
46 #include "qvgimagepool_p.h" |
47 #include "qvgimagepool_p.h" |
47 |
48 |
|
49 #include <private/qt_s60_p.h> |
|
50 #include <fbs.h> |
48 #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE |
51 #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE |
49 #include <graphics/sgimage.h> |
52 #include <sgresource/sgimage.h> |
50 typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*); |
53 typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*); |
51 typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR); |
54 typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR); |
52 typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR); |
55 typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR); |
53 #endif |
56 #endif // QT_SYMBIAN_SUPPORTS_SGIMAGE |
54 |
57 |
55 QT_BEGIN_NAMESPACE |
58 QT_BEGIN_NAMESPACE |
56 |
59 |
57 static int qt_vg_pixmap_serial = 0; |
60 static int qt_vg_pixmap_serial = 0; |
58 |
61 |
445 destroyImages(); |
476 destroyImages(); |
446 prevSize = QSize(); |
477 prevSize = QSize(); |
447 |
478 |
448 TInt err = 0; |
479 TInt err = 0; |
449 |
480 |
450 err = SgDriver::Open(); |
481 RSgDriver driver; |
451 if(err != KErrNone) { |
482 err = driver.Open(); |
|
483 if (err != KErrNone) { |
452 cleanup(); |
484 cleanup(); |
453 return; |
485 return; |
454 } |
486 } |
455 |
487 |
456 if(sgImage->IsNull()) { |
488 if (sgImage->IsNull()) { |
457 cleanup(); |
489 cleanup(); |
458 SgDriver::Close(); |
490 driver.Close(); |
459 return; |
491 return; |
460 } |
492 } |
461 |
493 |
462 TSgImageInfo sgImageInfo; |
494 TSgImageInfo sgImageInfo; |
463 err = sgImage->GetInfo(sgImageInfo); |
495 err = sgImage->GetInfo(sgImageInfo); |
464 if(err != KErrNone) { |
496 if (err != KErrNone) { |
465 cleanup(); |
497 cleanup(); |
466 SgDriver::Close(); |
498 driver.Close(); |
467 return; |
499 return; |
468 } |
500 } |
469 |
501 |
470 pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); |
502 pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); |
471 pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); |
503 pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); |
472 pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); |
504 pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); |
473 |
505 |
474 if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { |
506 if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { |
475 cleanup(); |
507 cleanup(); |
476 SgDriver::Close(); |
508 driver.Close(); |
477 return; |
509 return; |
478 } |
510 } |
479 |
511 |
480 const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; |
512 const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; |
481 EGLImageKHR eglImage = eglCreateImageKHR(context->display(), |
513 EGLImageKHR eglImage = eglCreateImageKHR(context->display(), |
482 EGL_NO_CONTEXT, |
514 EGL_NO_CONTEXT, |
483 EGL_NATIVE_PIXMAP_KHR, |
515 EGL_NATIVE_PIXMAP_KHR, |
484 (EGLClientBuffer)sgImage, |
516 (EGLClientBuffer)sgImage, |
485 (EGLint*)KEglImageAttribs); |
517 (EGLint*)KEglImageAttribs); |
486 |
518 |
487 if(eglGetError() != EGL_SUCCESS) { |
519 if (eglGetError() != EGL_SUCCESS) { |
488 cleanup(); |
520 cleanup(); |
489 SgDriver::Close(); |
521 driver.Close(); |
490 return; |
522 return; |
491 } |
523 } |
492 |
524 |
493 vgImage = vgCreateEGLImageTargetKHR(eglImage); |
525 vgImage = vgCreateEGLImageTargetKHR(eglImage); |
494 if(vgGetError() != VG_NO_ERROR) { |
526 if (vgGetError() != VG_NO_ERROR) { |
495 cleanup(); |
527 cleanup(); |
496 eglDestroyImageKHR(context->display(), eglImage); |
528 eglDestroyImageKHR(QEglContext::display(), eglImage); |
497 SgDriver::Close(); |
529 driver.Close(); |
498 return; |
530 return; |
499 } |
531 } |
500 |
532 |
501 w = sgImageInfo.iSizeInPixels.iWidth; |
533 w = sgImageInfo.iSizeInPixels.iWidth; |
502 h = sgImageInfo.iSizeInPixels.iHeight; |
534 h = sgImageInfo.iSizeInPixels.iHeight; |
505 source = QImage(); |
537 source = QImage(); |
506 recreate = false; |
538 recreate = false; |
507 prevSize = QSize(w, h); |
539 prevSize = QSize(w, h); |
508 setSerialNumber(++qt_vg_pixmap_serial); |
540 setSerialNumber(++qt_vg_pixmap_serial); |
509 // release stuff |
541 // release stuff |
510 eglDestroyImageKHR(context->display(), eglImage); |
542 eglDestroyImageKHR(QEglContext::display(), eglImage); |
511 SgDriver::Close(); |
543 driver.Close(); |
512 } else if (type == QPixmapData::FbsBitmap) { |
544 } else if (type == QPixmapData::FbsBitmap) { |
513 |
545 CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap); |
|
546 |
|
547 bool deleteSourceBitmap = false; |
|
548 |
|
549 #ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE |
|
550 |
|
551 // Rasterize extended bitmaps |
|
552 |
|
553 TUid extendedBitmapType = bitmap->ExtendedBitmapType(); |
|
554 if (extendedBitmapType != KNullUid) { |
|
555 bitmap = createBlitCopy(bitmap); |
|
556 deleteSourceBitmap = true; |
|
557 } |
|
558 #endif |
|
559 |
|
560 if (bitmap->IsCompressedInRAM()) { |
|
561 bitmap = createBlitCopy(bitmap); |
|
562 deleteSourceBitmap = true; |
|
563 } |
|
564 |
|
565 TDisplayMode displayMode = bitmap->DisplayMode(); |
|
566 QImage::Format format = qt_TDisplayMode2Format(displayMode); |
|
567 |
|
568 TSize size = bitmap->SizeInPixels(); |
|
569 |
|
570 bitmap->BeginDataAccess(); |
|
571 uchar *bytes = (uchar*)bitmap->DataAddress(); |
|
572 QImage img = QImage(bytes, size.iWidth, size.iHeight, format); |
|
573 img = img.copy(); |
|
574 bitmap->EndDataAccess(); |
|
575 |
|
576 if(displayMode == EGray2) { |
|
577 //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid |
|
578 //So invert mono bitmaps so that masks work correctly. |
|
579 img.invertPixels(); |
|
580 } else if(displayMode == EColor16M) { |
|
581 img = img.rgbSwapped(); // EColor16M is BGR |
|
582 } |
|
583 |
|
584 fromImage(img, Qt::AutoColor); |
|
585 |
|
586 if(deleteSourceBitmap) |
|
587 delete bitmap; |
514 } |
588 } |
515 #else |
589 #else |
516 Q_UNUSED(pixmap); |
590 Q_UNUSED(pixmap); |
517 Q_UNUSED(type); |
591 Q_UNUSED(type); |
518 #endif |
592 #endif |
522 { |
596 { |
523 #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL) |
597 #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL) |
524 if (type == QPixmapData::SgImage) { |
598 if (type == QPixmapData::SgImage) { |
525 toVGImage(); |
599 toVGImage(); |
526 |
600 |
527 if(!isValid() || vgImage == VG_INVALID_HANDLE) |
601 if (!isValid() || vgImage == VG_INVALID_HANDLE) |
528 return 0; |
602 return 0; |
529 |
603 |
530 TInt err = 0; |
604 TInt err = 0; |
531 |
605 |
532 err = SgDriver::Open(); |
606 RSgDriver driver; |
533 if(err != KErrNone) |
607 err = driver.Open(); |
|
608 if (err != KErrNone) |
534 return 0; |
609 return 0; |
535 |
610 |
536 TSgImageInfo sgInfo; |
611 TSgImageInfo sgInfo; |
537 sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE; |
612 sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE; |
538 sgInfo.iSizeInPixels.SetSize(w, h); |
613 sgInfo.iSizeInPixels.SetSize(w, h); |
539 sgInfo.iUsage = ESgUsageOpenVgImage | ESgUsageOpenVgTarget; |
614 sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface; |
540 sgInfo.iShareable = ETrue; |
|
541 sgInfo.iCpuAccess = ESgCpuAccessNone; |
|
542 sgInfo.iScreenId = KSgScreenIdMain; //KSgScreenIdAny; |
|
543 sgInfo.iUserAttributes = NULL; |
|
544 sgInfo.iUserAttributeCount = 0; |
|
545 |
615 |
546 RSgImage *sgImage = q_check_ptr(new RSgImage()); |
616 RSgImage *sgImage = q_check_ptr(new RSgImage()); |
547 err = sgImage->Create(sgInfo, NULL, NULL); |
617 err = sgImage->Create(sgInfo, NULL, NULL); |
548 if(err != KErrNone) { |
618 if (err != KErrNone) { |
549 SgDriver::Close(); |
619 driver.Close(); |
550 return 0; |
620 return 0; |
551 } |
621 } |
552 |
622 |
553 pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); |
623 pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); |
554 pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); |
624 pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); |
555 pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); |
625 pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); |
556 |
626 |
557 if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { |
627 if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { |
558 SgDriver::Close(); |
628 driver.Close(); |
559 return 0; |
629 return 0; |
560 } |
630 } |
561 |
631 |
562 const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; |
632 const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; |
563 EGLImageKHR eglImage = eglCreateImageKHR(context->display(), |
633 EGLImageKHR eglImage = eglCreateImageKHR(context->display(), |
564 EGL_NO_CONTEXT, |
634 EGL_NO_CONTEXT, |
565 EGL_NATIVE_PIXMAP_KHR, |
635 EGL_NATIVE_PIXMAP_KHR, |
566 (EGLClientBuffer)sgImage, |
636 (EGLClientBuffer)sgImage, |
567 (EGLint*)KEglImageAttribs); |
637 (EGLint*)KEglImageAttribs); |
568 if(eglGetError() != EGL_SUCCESS) { |
638 if (eglGetError() != EGL_SUCCESS) { |
569 sgImage->Close(); |
639 sgImage->Close(); |
570 SgDriver::Close(); |
640 driver.Close(); |
571 return 0; |
641 return 0; |
572 } |
642 } |
573 |
643 |
574 VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage); |
644 VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage); |
575 if(vgGetError() != VG_NO_ERROR) { |
645 if (vgGetError() != VG_NO_ERROR) { |
576 eglDestroyImageKHR(context->display(), eglImage); |
646 eglDestroyImageKHR(QEglContext::display(), eglImage); |
577 sgImage->Close(); |
647 sgImage->Close(); |
578 SgDriver::Close(); |
648 driver.Close(); |
579 return 0; |
649 return 0; |
580 } |
650 } |
581 |
651 |
582 vgCopyImage(dstVgImage, 0, 0, |
652 vgCopyImage(dstVgImage, 0, 0, |
583 vgImage, 0, 0, |
653 vgImage, 0, 0, |
584 w, h, VG_FALSE); |
654 w, h, VG_FALSE); |
585 |
655 |
586 if(vgGetError() != VG_NO_ERROR) { |
656 if (vgGetError() != VG_NO_ERROR) { |
587 sgImage->Close(); |
657 sgImage->Close(); |
588 sgImage = 0; |
658 sgImage = 0; |
589 } |
659 } |
590 // release stuff |
660 // release stuff |
591 vgDestroyImage(dstVgImage); |
661 vgDestroyImage(dstVgImage); |
592 eglDestroyImageKHR(context->display(), eglImage); |
662 eglDestroyImageKHR(QEglContext::display(), eglImage); |
593 SgDriver::Close(); |
663 driver.Close(); |
594 return reinterpret_cast<void*>(sgImage); |
664 return reinterpret_cast<void*>(sgImage); |
595 } else if (type == QPixmapData::FbsBitmap) { |
665 } else if (type == QPixmapData::FbsBitmap) { |
596 return 0; |
666 CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); |
|
667 |
|
668 if (bitmap) { |
|
669 if (bitmap->Create(TSize(source.width(), source.height()), |
|
670 EColor16MAP) == KErrNone) { |
|
671 const uchar *sptr = qt_vg_imageBits(source); |
|
672 bitmap->BeginDataAccess(); |
|
673 |
|
674 uchar *dptr = (uchar*)bitmap->DataAddress(); |
|
675 Mem::Copy(dptr, sptr, source.byteCount()); |
|
676 |
|
677 bitmap->EndDataAccess(); |
|
678 } else { |
|
679 delete bitmap; |
|
680 bitmap = 0; |
|
681 } |
|
682 } |
|
683 |
|
684 return reinterpret_cast<void*>(bitmap); |
597 } |
685 } |
598 #else |
686 #else |
599 Q_UNUSED(type); |
687 Q_UNUSED(type); |
600 return 0; |
688 return 0; |
601 #endif |
689 #endif |