Changeset 846 for trunk/src/openvg/qpixmapdata_vg.cpp
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/openvg/qpixmapdata_vg.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 43 43 #include "qpaintengine_vg_p.h" 44 44 #include <QtGui/private/qdrawhelper_p.h> 45 #if !defined(QT_NO_EGL) 46 #include <QtGui/private/qegl_p.h> 47 #endif 45 48 #include "qvg_p.h" 46 49 #include "qvgimagepool_p.h" 47 48 #if defined(Q_OS_SYMBIAN) 49 #include <private/qt_s60_p.h> 50 #include <fbs.h> 51 #endif 52 #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE 53 #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 #endif // QT_SYMBIAN_SUPPORTS_SGIMAGE 50 #include <QBuffer> 51 #include <QImageReader> 52 #include <QtGui/private/qimage_p.h> 58 53 59 54 QT_BEGIN_NAMESPACE … … 71 66 inImagePool = false; 72 67 inLRU = false; 68 failedToAlloc = false; 73 69 #if !defined(QT_NO_EGL) 74 70 context = 0; … … 161 157 (const QImage &image, Qt::ImageConversionFlags flags) 162 158 { 159 if(image.isNull()) 160 return; 161 162 QImage img = image; 163 createPixmapForImage(img, flags, false); 164 } 165 166 void QVGPixmapData::fromImageReader(QImageReader *imageReader, 167 Qt::ImageConversionFlags flags) 168 { 169 QImage image = imageReader->read(); 170 if (image.isNull()) 171 return; 172 173 createPixmapForImage(image, flags, true); 174 } 175 176 bool QVGPixmapData::fromFile(const QString &filename, const char *format, 177 Qt::ImageConversionFlags flags) 178 { 179 QImage image = QImageReader(filename, format).read(); 180 if (image.isNull()) 181 return false; 182 183 createPixmapForImage(image, flags, true); 184 185 return !isNull(); 186 } 187 188 bool QVGPixmapData::fromData(const uchar *buffer, uint len, const char *format, 189 Qt::ImageConversionFlags flags) 190 { 191 QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len); 192 QBuffer b(&a); 193 b.open(QIODevice::ReadOnly); 194 QImage image = QImageReader(&b, format).read(); 195 if (image.isNull()) 196 return false; 197 198 createPixmapForImage(image, flags, true); 199 200 return !isNull(); 201 } 202 203 /*! 204 out-of-place conversion (inPlace == false) will always detach() 205 */ 206 void QVGPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace) 207 { 163 208 if (image.size() == QSize(w, h)) 164 209 setSerialNumber(++qt_vg_pixmap_serial); 165 210 else 166 211 resize(image.width(), image.height()); 167 source = image.convertToFormat(sourceFormat(), flags); 212 213 QImage::Format format = sourceFormat(); 214 int d = image.depth(); 215 if (d == 1 || d == 16 || d == 24 || (d == 32 && !image.hasAlphaChannel())) 216 format = QImage::Format_RGB32; 217 else if (!(flags & Qt::NoOpaqueDetection) && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()) 218 format = sourceFormat(); 219 else 220 format = image.hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32; 221 222 if (inPlace && image.data_ptr()->convertInPlace(format, flags)) { 223 source = image; 224 } else { 225 source = image.convertToFormat(format); 226 227 // convertToFormat won't detach the image if format stays the same. 228 if (image.format() == format) 229 source.detach(); 230 } 231 168 232 recreate = true; 169 233 } … … 234 298 } 235 299 236 // This function works around QImage::bits() making a deep copy if the237 // 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 300 VGImage QVGPixmapData::toVGImage() 245 301 { 246 if (!isValid() )302 if (!isValid() || failedToAlloc) 247 303 return VG_INVALID_HANDLE; 248 304 … … 260 316 if (vgImage == VG_INVALID_HANDLE) { 261 317 vgImage = QVGImagePool::instance()->createImageForPixmap 262 ( VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER, this);318 (qt_vg_image_to_vg_format(source.format()), w, h, VG_IMAGE_QUALITY_FASTER, this); 263 319 264 320 // Bail out if we run out of GPU memory - try again next time. 265 if (vgImage == VG_INVALID_HANDLE) 321 if (vgImage == VG_INVALID_HANDLE) { 322 failedToAlloc = true; 266 323 return VG_INVALID_HANDLE; 324 } 267 325 268 326 inImagePool = true; … … 274 332 vgImageSubData 275 333 (vgImage, 276 qt_vg_imageBits(source), source.bytesPerLine(),277 VG_sARGB_8888_PRE, 0, 0, w, h);334 source.constBits(), source.bytesPerLine(), 335 qt_vg_image_to_vg_format(source.format()), 0, 0, w, h); 278 336 } 279 337 … … 429 487 } 430 488 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 460 void QVGPixmapData::cleanup()461 {462 is_null = w = h = 0;463 recreate = false;464 source = QImage();465 }466 467 void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)468 {469 if (type == QPixmapData::SgImage && pixmap) {470 #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)471 RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmap);472 473 destroyImages();474 prevSize = QSize();475 476 TInt err = 0;477 478 RSgDriver driver;479 err = driver.Open();480 if (err != KErrNone) {481 cleanup();482 return;483 }484 485 if (sgImage->IsNull()) {486 cleanup();487 driver.Close();488 return;489 }490 491 TSgImageInfo sgImageInfo;492 err = sgImage->GetInfo(sgImageInfo);493 if (err != KErrNone) {494 cleanup();495 driver.Close();496 return;497 }498 499 pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");500 pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");501 pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");502 503 if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {504 cleanup();505 driver.Close();506 return;507 }508 509 const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};510 EGLImageKHR eglImage = eglCreateImageKHR(QEglContext::display(),511 EGL_NO_CONTEXT,512 EGL_NATIVE_PIXMAP_KHR,513 (EGLClientBuffer)sgImage,514 (EGLint*)KEglImageAttribs);515 516 if (eglGetError() != EGL_SUCCESS) {517 cleanup();518 driver.Close();519 return;520 }521 522 vgImage = vgCreateEGLImageTargetKHR(eglImage);523 if (vgGetError() != VG_NO_ERROR) {524 cleanup();525 eglDestroyImageKHR(QEglContext::display(), eglImage);526 driver.Close();527 return;528 }529 530 w = sgImageInfo.iSizeInPixels.iWidth;531 h = sgImageInfo.iSizeInPixels.iHeight;532 d = 32; // We always use ARGB_Premultiplied for VG pixmaps.533 is_null = (w <= 0 || h <= 0);534 source = QImage();535 recreate = false;536 prevSize = QSize(w, h);537 setSerialNumber(++qt_vg_pixmap_serial);538 // release stuff539 eglDestroyImageKHR(QEglContext::display(), eglImage);540 driver.Close();541 #endif542 } else if (type == QPixmapData::FbsBitmap) {543 CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);544 545 bool deleteSourceBitmap = false;546 547 #ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE548 549 // Rasterize extended bitmaps550 551 TUid extendedBitmapType = bitmap->ExtendedBitmapType();552 if (extendedBitmapType != KNullUid) {553 bitmap = createBlitCopy(bitmap);554 deleteSourceBitmap = true;555 }556 #endif557 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/solid576 //So invert mono bitmaps so that masks work correctly.577 img.invertPixels();578 } else if(displayMode == EColor16M) {579 img = img.rgbSwapped(); // EColor16M is BGR580 }581 582 fromImage(img, Qt::AutoColor);583 584 if(deleteSourceBitmap)585 delete bitmap;586 }587 }588 589 void* QVGPixmapData::toNativeType(NativeType type)590 {591 if (type == QPixmapData::SgImage) {592 #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)593 toVGImage();594 595 if (!isValid() || vgImage == VG_INVALID_HANDLE)596 return 0;597 598 TInt err = 0;599 600 RSgDriver driver;601 err = driver.Open();602 if (err != KErrNone)603 return 0;604 605 TSgImageInfo sgInfo;606 sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE;607 sgInfo.iSizeInPixels.SetSize(w, h);608 sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;609 610 RSgImage *sgImage = q_check_ptr(new RSgImage());611 err = sgImage->Create(sgInfo, NULL, NULL);612 if (err != KErrNone) {613 driver.Close();614 return 0;615 }616 617 pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");618 pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");619 pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");620 621 if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {622 driver.Close();623 return 0;624 }625 626 const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};627 EGLImageKHR eglImage = eglCreateImageKHR(QEglContext::display(),628 EGL_NO_CONTEXT,629 EGL_NATIVE_PIXMAP_KHR,630 (EGLClientBuffer)sgImage,631 (EGLint*)KEglImageAttribs);632 if (eglGetError() != EGL_SUCCESS) {633 sgImage->Close();634 driver.Close();635 return 0;636 }637 638 VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage);639 if (vgGetError() != VG_NO_ERROR) {640 eglDestroyImageKHR(QEglContext::display(), eglImage);641 sgImage->Close();642 driver.Close();643 return 0;644 }645 646 vgCopyImage(dstVgImage, 0, 0,647 vgImage, 0, 0,648 w, h, VG_FALSE);649 650 if (vgGetError() != VG_NO_ERROR) {651 sgImage->Close();652 sgImage = 0;653 }654 // release stuff655 vgDestroyImage(dstVgImage);656 eglDestroyImageKHR(QEglContext::display(), eglImage);657 driver.Close();658 return reinterpret_cast<void*>(sgImage);659 #endif660 } else if (type == QPixmapData::FbsBitmap) {661 CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);662 663 if (bitmap) {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 }681 return 0;682 }683 #endif //Q_OS_SYMBIAN684 685 489 QT_END_NAMESPACE
Note:
See TracChangeset
for help on using the changeset viewer.