/**
@SYMTestCaseID			GRAPHICS-RESOURCE-0201
@SYMTestCaseDesc		Test Graphics Resource with low memory conditions.
@SYMPREQ				PREQ2637
@SYMFssID				RSgImage
						RSgDrawable
						RSgDriver
@SYMTestPriority		High
@SYMTestType			UT
@SYMTestPurpose			To ensure the correct errors or KErrNoMemory are returned by graphics resource apis under low
						memory conditions.
@SYMTestActions			Force allocations to fail on the RSgDrivers heap, try running each of the conformance tests and
						stress tests to ensure no RSgDriver allocated memory or heap memory is leaked. It also creates
						an image in this process which is used in another process for OOM testing. 
@SYMTestExpectedResults	Return codes of the functions tested should be either the expected value or KErrNoMemory
						This is handled by CTSgTestStepBase::CheckErrorL. No ALLOC or SGALLOC panics should occur.
 */	
void CTGraphicsResourceInternal::TestOOML()
	{
	// drawable OOM test
	TSgResIntTestInfo testInfo = { ESgResIntDrawableOOM };
	TInt result = CreateSecondProcessAndDoTestL(KInternalTestsSecondProcess, testInfo);
	TEST(result & EFirstTestPassed);
	
	// image OOM test
    testInfo.iTestCase = ESgResIntImageOOM;
    
    RSgDriver sgDriver;
    TInt err = sgDriver.Open();
    TESTEL(err == KErrNone, err);
    CleanupClosePushL(sgDriver);
    
    RSgImage image1;
    TSgImageInfo info1(TSize(8, 8), EUidPixelFormatRGB_565, ESgUsageBitOpenVgImage);
    err = image1.Create(info1);
    TESTEL(err == KErrNone, err);
    CleanupClosePushL(image1);
    testInfo.iDrawableId = image1.Id();
            
    result = CreateSecondProcessAndDoTestL(KInternalTestsSecondProcess, testInfo);
    TEST(result & EFirstTestPassed);
        
    CleanupStack::PopAndDestroy(2, &sgDriver); 
	}
/**
@SYMTestCaseID			GRAPHICS-RESOURCE-0022
@SYMTestCaseDesc		Shuts down an uninitialised driver.
@SYMPREQ				PREQ2637
@SYMFssID				RSgDriver::Close()
@SYMTestPriority		Low
@SYMTestType			UT
@SYMTestPurpose			To ensure invalid Close() calls on the driver will cause no errors.
@SYMTestActions			Call RSgDriver::Close() several times without calling RSgDriver::Open().
@SYMTestExpectedResults	No errors should be returned.
 */	
void CTSgDriver::TestShutdownUninitialized()
	{
	__UHEAP_MARK;	
	
	RSgDriver sgDriver;
	
	sgDriver.Close();
	sgDriver.Close();
	sgDriver.Close();
	
	__UHEAP_MARKEND;
	}
/**
@SYMTestCaseID			GRAPHICS-RESOURCE-0096
@SYMTestCaseDesc		Test the version number returned by RSgDriver is correct.
@SYMPREQ				PREQ2637
@SYMFssID				RSgDriver::Version()
@SYMTestPriority		Medium
@SYMTestType			UT
@SYMTestPurpose			To check the correct version of the driver is being used in the
						conformance tests.
@SYMTestActions			Call RSgDriver::Version().
@SYMTestExpectedResults	The correct version should be returned.
 */	
void CTSgDriver::TestVersion()
	{
	__UHEAP_MARK;	
	
	RSgDriver sgDriver;
	
	TVersion vers = sgDriver.Version();
	TEST(vers.iMajor == 1);
	TEST(vers.iMinor == 1);
	
	__UHEAP_MARKEND;
	}
/*
@SYMTestCaseID          GRAPHICS-RESOURCE-0204
@SYMTestCaseDesc        Test usage bit
@SYMPREQ                PREQ2637
@SYMFssID               RSgImage
                        RSgDrawable
                        RSgDriver
@SYMTestPriority        High
@SYMTestType            UT
@SYMTestPurpose         To ensure that an image can be created using various usage bit, and the usage bit of created image
                        is correct.
@SYMTestActions         Create an image with selection of usage bit. Check if the return code of SgImage::Create
                        is correct. If creation succeeds, open the image and check if the usage bit is the same 
                        to the one expected. 
                        NOTE: The usage bit may not be the same as the one that is used to create an image - it 
                        depends on the implementation.
@SYMTestExpectedResults The usage bit should match the expected usage bit.
 */ 
void CTGraphicsResourceInternal::TestUsageBitsL()
    {
 
    RSgDriver driver;
    User::LeaveIfError(driver.Open());
    CleanupClosePushL(driver);
    
    for(TInt i=0; i < KUsageBitTestCount; ++i)
        {
        TSgImageInfo info(TSize(8, 8), KUsageBitTestCases[i].iPixelFormat,  KUsageBitTestCases[i].iUsageBit);
            
        RSgImage image;
        TInt err = image.Create(info);
        CleanupClosePushL(image);
        
        if(err != KUsageBitTestCases[i].iExpectedReturnCode)
            {
            ERR_PRINTF3(_L("Test case index: %d, Test failed with error: %d"), i, err);
            SetTestStepResult(EFail);
            }
        
        if(err == KErrNone)
            {    
            TSgImageInfo info1;
            User::LeaveIfError(image.GetInfo(info1));   
            if(info1.iUsage != KUsageBitTestCases[i].iExpectedUsageBit)
                {
                ERR_PRINTF3(_L("Test case index: %d, info1 usage bit 0x%04X"), i, info1.iUsage);
                SetTestStepResult(EFail);
                }
            }
            
        CleanupStack::PopAndDestroy(&image);
        }
    
    CleanupStack::PopAndDestroy(&driver);
    }
/**
@SYMTestCaseID			GRAPHICS-RESOURCE-0099
@SYMTestCaseDesc		Test SgDriver Handles Multiple Calls to Open Correctly
@SYMPREQ				PREQ2637
@SYMFssID				RSgDriver::Open()
@SYMTestPriority		High
@SYMTestType			UT
@SYMTestPurpose			To ensure the correct error code is returned when an open
						driver is opened
@SYMTestActions			Call RSgDriver::Open().
@SYMTestExpectedResults	KErrInUse should be returned when the driver is opened for
						the second time and all subsequent times.
 */	
void CTSgDriver::TestMultipleOpens()
	{
	__UHEAP_MARK;	
	
	TInt err = KErrNone;
	RSgDriver sgDriver;
	
	err = sgDriver.Open();
	TESTE(KErrNone == err, err);
	err = sgDriver.Open();
	TESTE(KErrInUse == err, err);
	err = sgDriver.Open();
	TESTE(KErrInUse == err, err);
	err = sgDriver.Open();
	TESTE(KErrInUse == err, err);	
	sgDriver.Close();	
	
	__UHEAP_MARKEND;
	}
void CTSgDriver::TestGetInterface()
	{
	__UHEAP_MARK;
	
	RSgDriver sgDriver;
	TInt err = sgDriver.Open();
	TESTE(err == KErrNone, err);
	
	MFakeInterface* fakeInterface = NULL;
	err = sgDriver.GetInterface(fakeInterface);
	TESTE(err == KErrExtensionNotSupported, err);	
	
	MNullInterface* nullInterface = NULL;
	err = sgDriver.GetInterface(nullInterface);
	TESTE(err == KErrArgument, err);
	
	sgDriver.Close();	
	err = sgDriver.GetInterface(fakeInterface);
	TESTE(err == KErrBadHandle, err);
	err = sgDriver.GetInterface(nullInterface);
	TESTE(err == KErrBadHandle, err);
	
	__UHEAP_MARKEND;
	}
Exemple #7
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;
}
Exemple #8
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;
}
Exemple #9
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;
    }
}
LOCAL_C void LaunchClientProcessL()
	{
	__UHEAP_MARK;
	RProcess::Rendezvous(KErrNone);

    RSemaphore sem;
    User::LeaveIfError(sem.OpenGlobal(KEglStressTest));
    CleanupClosePushL(sem);

    //Access data passed from the main process
    TStressProcessInfo info;
    TPckg<TStressProcessInfo> pckgInfo(info);
    User::LeaveIfError(User::GetDesParameter(KMultiProcessSlot, pckgInfo));

    //Create RSgDriver and open the image
    RSgDriver driver;
    User::LeaveIfError(driver.Open());
    CleanupClosePushL(driver);

    RSgImage image;
    User::LeaveIfError(image.Open(info.iSgId));
    CleanupClosePushL(image);

    EGLDisplay display;
    EGL_LEAVE_NULL(display, eglGetDisplay(EGL_DEFAULT_DISPLAY));
    EGL_LEAVE_ERROR(eglInitialize(display, NULL, NULL));
    EGL_LEAVE_ERROR(eglBindAPI(EGL_OPENVG_API));

    //Initialise to remove arm compiler warnings
    EGLConfig config = 0;
    EGLContext context = EGL_NO_CONTEXT;
    EGLSurface surface = EGL_NO_SURFACE;

    if(info.iTestType == EStressRead)
        {
        TSgImageInfo sginfo;
        User::LeaveIfError(image.GetInfo(sginfo));

        //Create an independant pixmap surface on which to copy the vgimage 
        RSgImage image2;
        User::LeaveIfError(image2.Create(sginfo, NULL, NULL));
        CleanupClosePushL(image2);
        ChooseConfigAndCreateContextL(display, context, config, image2, KStressTestChildAppPanic, info.iAlphaPre);
        EGL_LEAVE_NULL(surface, CreatePixmapSurfaceL(display, config, image2, info.iAlphaPre)); 
        CleanupStack::PopAndDestroy(&image2);
        }
    else
        {
        ChooseConfigAndCreateContextL(display, context, config, image, KStressTestChildAppPanic, info.iAlphaPre);
        EGL_LEAVE_NULL(surface, CreatePixmapSurfaceL(display, config, image, info.iAlphaPre));       
        }

    EGL_LEAVE_ERROR(eglMakeCurrent(display, surface, surface, context));

    VGImage vgImage;
    GenerateVgImageL(display, &image, vgImage);

    /* Create and install the active scheduler */
    CActiveScheduler* sched = new(ELeave) CActiveScheduler;
    CActiveScheduler::Install(sched);
    CleanupStack::PushL(sched);

    TInt width = vgGetParameteri(vgImage, VG_IMAGE_WIDTH);
    VgLeaveIfErrorL();

    TInt height = vgGetParameteri(vgImage, VG_IMAGE_HEIGHT);
    VgLeaveIfErrorL();

    VGImageFormat format = static_cast<VGImageFormat>(vgGetParameteri(vgImage, VG_IMAGE_FORMAT));
    VgLeaveIfErrorL();

    TBool testPass = ETrue;

    CTReadWriteChild* painter = CTReadWriteChild::NewL(vgImage, width, height, info.iByteSize, format, info.iTestType, testPass);
    CleanupStack::PushL(painter);
    painter->After(TTimeIntervalMicroSeconds32(0));

    //Data access is synchronised from the main process
    sem.Wait();
    sched->Start();

    if(testPass == EFalse)
        {
		// Leave with a 'known' test error so that we can catch this particular failure 
        User::Leave(KTestStressUnexpectedPixelError);
        }
    
    CleanupStack::PopAndDestroy(5, &sem); //painter, sched, image, driver, sem
      
    __UHEAP_MARKEND;
    }
/*
@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;
	}