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