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