예제 #1
0
void* QVGPixmapData::toNativeType(NativeType type)
{
    if (type == QPixmapData::SgImage) {
#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
        toVGImage();

        if (!isValid() || vgImage == VG_INVALID_HANDLE)
            return 0;

        TInt err = 0;

        RSgDriver driver;
        err = driver.Open();
        if (err != KErrNone)
            return 0;

        TSgImageInfo sgInfo;
        sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE;
        sgInfo.iSizeInPixels.SetSize(w, h);
        sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;

        QScopedPointer<RSgImage> sgImage(new RSgImage());
        err = sgImage->Create(sgInfo, NULL, NULL);
        if (err != KErrNone) {
            driver.Close();
            return 0;
        }

        const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
        EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(),
                EGL_NO_CONTEXT,
                EGL_NATIVE_PIXMAP_KHR,
                (EGLClientBuffer)sgImage.data(),
                (EGLint*)KEglImageAttribs);
        if (!eglImage || eglGetError() != EGL_SUCCESS) {
            sgImage->Close();
            driver.Close();
            return 0;
        }

        VGImage dstVgImage = QVG::vgCreateEGLImageTargetKHR(eglImage);
        if (!dstVgImage || vgGetError() != VG_NO_ERROR) {
            QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
            sgImage->Close();
            driver.Close();
            return 0;
        }

        vgCopyImage(dstVgImage, 0, 0,
                vgImage, 0, 0,
                w, h, VG_FALSE);

        if (vgGetError() != VG_NO_ERROR) {
            sgImage->Close();
            sgImage.reset();
        }

        // release stuff
        vgDestroyImage(dstVgImage);
        QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
        driver.Close();
        return reinterpret_cast<void*>(sgImage.take());
#endif
    } else if (type == QPixmapData::FbsBitmap && isValid()) {
        ensureReadback(true);
        if (source.isNull()) {
            source = QVolatileImage(w, h, sourceFormat());
        }
        // Just duplicate the bitmap handle, no data copying happens.
        return source.duplicateNativeImage();
    }
    return 0;
}
예제 #2
0
void QVGPixmapData::fromNativeType(void* pixmap, NativeType type)
{
    if (type == QPixmapData::SgImage && pixmap) {
#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
        RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmap);

        destroyImages();
        prevSize = QSize();

        TInt err = 0;

        RSgDriver driver;
        err = driver.Open();
        if (err != KErrNone) {
            cleanup();
            return;
        }

        if (sgImage->IsNull()) {
            cleanup();
            driver.Close();
            return;
        }

        TSgImageInfo sgImageInfo;
        err = sgImage->GetInfo(sgImageInfo);
        if (err != KErrNone) {
            cleanup();
            driver.Close();
            return;
        }

        pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");

        if (eglGetError() != EGL_SUCCESS || !(QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) || !vgCreateEGLImageTargetKHR) {
            cleanup();
            driver.Close();
            return;
        }

        const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
        EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(),
                EGL_NO_CONTEXT,
                EGL_NATIVE_PIXMAP_KHR,
                (EGLClientBuffer)sgImage,
                (EGLint*)KEglImageAttribs);

        if (eglGetError() != EGL_SUCCESS) {
            cleanup();
            driver.Close();
            return;
        }

        vgImage = vgCreateEGLImageTargetKHR(eglImage);
        if (vgGetError() != VG_NO_ERROR) {
            cleanup();
            QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
            driver.Close();
            return;
        }

        w = sgImageInfo.iSizeInPixels.iWidth;
        h = sgImageInfo.iSizeInPixels.iHeight;
        d = 32; // We always use ARGB_Premultiplied for VG pixmaps.
        is_null = (w <= 0 || h <= 0);
        source = QImage();
        recreate = false;
        prevSize = QSize(w, h);
        setSerialNumber(++qt_vg_pixmap_serial);
        // release stuff
        QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
        driver.Close();
#endif
    } else if (type == QPixmapData::FbsBitmap) {
        CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);

        bool deleteSourceBitmap = false;

#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE

        // Rasterize extended bitmaps

        TUid extendedBitmapType = bitmap->ExtendedBitmapType();
        if (extendedBitmapType != KNullUid) {
            bitmap = createBlitCopy(bitmap);
            deleteSourceBitmap = true;
        }
#endif

        if (bitmap->IsCompressedInRAM()) {
            bitmap = createBlitCopy(bitmap);
            deleteSourceBitmap = true;
        }

        TDisplayMode displayMode = bitmap->DisplayMode();
        QImage::Format format = qt_TDisplayMode2Format(displayMode);

        TSize size = bitmap->SizeInPixels();

        bitmap->BeginDataAccess();
        uchar *bytes = (uchar*)bitmap->DataAddress();
        QImage img = QImage(bytes, size.iWidth, size.iHeight, format);
        img = img.copy();
        bitmap->EndDataAccess();

        if(displayMode == EGray2) {
            //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
            //So invert mono bitmaps so that masks work correctly.
            img.invertPixels();
        } else if(displayMode == EColor16M) {
            img = img.rgbSwapped(); // EColor16M is BGR
        }

        fromImage(img, Qt::AutoColor);

        if(deleteSourceBitmap)
            delete bitmap;
    }
}
예제 #3
0
void* QVGPixmapData::toNativeType(NativeType type)
{
    if (type == QPixmapData::SgImage) {
#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
        toVGImage();

        if (!isValid() || vgImage == VG_INVALID_HANDLE)
            return 0;

        TInt err = 0;

        RSgDriver driver;
        err = driver.Open();
        if (err != KErrNone)
            return 0;

        TSgImageInfo sgInfo;
        sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE;
        sgInfo.iSizeInPixels.SetSize(w, h);
        sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;

        RSgImage *sgImage = q_check_ptr(new RSgImage());
        err = sgImage->Create(sgInfo, NULL, NULL);
        if (err != KErrNone) {
            driver.Close();
            return 0;
        }

        pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");

        if (eglGetError() != EGL_SUCCESS || !(QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) || !vgCreateEGLImageTargetKHR) {
            driver.Close();
            return 0;
        }

        const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
        EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(),
                EGL_NO_CONTEXT,
                EGL_NATIVE_PIXMAP_KHR,
                (EGLClientBuffer)sgImage,
                (EGLint*)KEglImageAttribs);
        if (eglGetError() != EGL_SUCCESS) {
            sgImage->Close();
            driver.Close();
            return 0;
        }

        VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage);
        if (vgGetError() != VG_NO_ERROR) {
            QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
            sgImage->Close();
            driver.Close();
            return 0;
        }

        vgCopyImage(dstVgImage, 0, 0,
                vgImage, 0, 0,
                w, h, VG_FALSE);

        if (vgGetError() != VG_NO_ERROR) {
            sgImage->Close();
            sgImage = 0;
        }
        // release stuff
        vgDestroyImage(dstVgImage);
        QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
        driver.Close();
        return reinterpret_cast<void*>(sgImage);
#endif
    } else if (type == QPixmapData::FbsBitmap) {
        CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);

        if (bitmap) {
            if (bitmap->Create(TSize(source.width(), source.height()),
                              EColor16MAP) == KErrNone) {
                const uchar *sptr = source.constBits();
                bitmap->BeginDataAccess();

                uchar *dptr = (uchar*)bitmap->DataAddress();
                Mem::Copy(dptr, sptr, source.byteCount());

                bitmap->EndDataAccess();
            } else {
                delete bitmap;
                bitmap = 0;
            }
        }

        return reinterpret_cast<void*>(bitmap);
    }
    return 0;
}
/*
@SYMTestCaseID			GRAPHICS-RESOURCE-0111
@SYMTestCaseDesc		Test MSgDriver_Profiling extension.
@SYMPREQ				PREQ2637
@SYMFssID				RSgImage
						RSgDriver
						MSgDriver_Profiling
@SYMTestPriority		Medium
@SYMTestType			UT
@SYMTestPurpose			To test that the extension MSgDriver_Profiling correctly reports
						the correct global and local resource count and memory usage when
						resources are created in separate processes.
@SYMTestActions			Get the MSgDriver_Profiling extension, query memory/resource usage.
						Create an image and check  the memory usage and count.
						Launch a separate process that checks the same memory usage/count.
						Create an image in this separate process and check the global resource 
						count and memory. Close the image nad check the memory usage and resource
						count. Terminate the second process. Check the local and global count 
						in the first process. Close the image in this process and check the global 
						and local resource count.
@SYMTestExpectedResults When creating the first image, the local resource count should equal one,
						the global count should increment. The local memory usage should increase
						by at least the size of the image in pixels * byte-depth. The global memory
						usage should increase by the same amount.
						Second process should report the same global resouce count and memory as
						the first process. 
						Second process image creation to cause same usage/count increase as did 
						first image.
						Closing the image in the second process should set count and memory usage 
						back to initial values, and local count/usage to zero. 
						Closing the image in the first process should set the count and memory usage
						back to their pre-test values, and local count/usage to zero.
 */	
void CTGraphicsResourceInternal::TestResourceProfilingL()
	{
	__UHEAP_MARK;
	
	RSgDriver sgDriver;
	TInt err = sgDriver.Open();
	TESTE(err == KErrNone, err);

	if (KErrNone == err)
		{
		MSgDriver_Profiling* profiling = NULL;
		err = sgDriver.GetInterface(profiling);
		if (!profiling || err != KErrNone)
			{
			ERR_PRINTF2(_L("Failed to get MSgDriver_Profiling extension [%d]"), err);
			SetTestStepResult(EFail);
			return;
			}
		
		const TInt originalGlobalResourceCount = profiling->GlobalResourceCount();
		const TInt originalGlobalGraphicsMemory = profiling->GlobalGraphicsMemoryUsed();

		TEST(profiling->LocalGraphicsMemoryUsed() == 0);
		
		RSgImage image;
		const TSize KImageSize(8, 8);
		err = image.Create(TSgImageInfo(KImageSize, EUidPixelFormatARGB_8888, ESgUsageBitOpenVgImage));
		TESTE(err == KErrNone, err);

		// Check that having created an image, the global resource count and memory usage has
		// increased.
		TInt localGraphicsMemory = profiling->LocalGraphicsMemoryUsed();
		TEST(localGraphicsMemory >= (KImageSize.iWidth * KImageSize.iHeight * 4));
		TEST(profiling->GlobalResourceCount() == (originalGlobalResourceCount + 1));
		TEST(profiling->GlobalGraphicsMemoryUsed() == (localGraphicsMemory + originalGlobalResourceCount));
		
		TSgResIntTestInfo testInfo = { ESgResIntResourceProfiling };
		testInfo.iGlobalGraphicsMemory = profiling->GlobalGraphicsMemoryUsed();
		testInfo.iGlobalResourceCount = profiling->GlobalResourceCount();
		TInt result = CreateSecondProcessAndDoTestL(KInternalTestsSecondProcess, testInfo);
		TEST(result & EFirstTestPassed);
		TEST(result & ESecondTestPassed);
		TEST(result & EThirdTestPassed);
		TEST(result & EFourthTestPassed);
		TEST(result & EFifthTestPassed);
		TEST(result & ESixthTestPassed);
		TEST(result & ESeventhTestPassed);
		TEST(result & EEighthTestPassed);
		TEST(result & ENinthTestPassed);
		TEST(result & ETenthTestPassed);
		TEST(result & EEleventhTestPassed);
		
		// Check that the global and local counts are unchanged.
		TEST(profiling->LocalGraphicsMemoryUsed() == localGraphicsMemory);
		TEST(profiling->GlobalResourceCount() == (originalGlobalResourceCount + 1));
		TEST(profiling->GlobalGraphicsMemoryUsed() == (localGraphicsMemory + originalGlobalResourceCount));
				
		// Check that closing the image shows the image memory is back to zero.
		image.Close();		
		TEST(profiling->LocalGraphicsMemoryUsed() == 0);
		TEST(profiling->GlobalGraphicsMemoryUsed() == originalGlobalGraphicsMemory);
		TEST(profiling->GlobalResourceCount() == originalGlobalResourceCount);
		
		// Cleanup
		sgDriver.Close();
		profiling = NULL;
		}
	__UHEAP_MARKEND;
	}