diff -r 000000000000 -r 5d03bc08d59c graphicsdeviceinterface/directgdi/test/tvgimagecache.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicsdeviceinterface/directgdi/test/tvgimagecache.cpp Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,591 @@ +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include "tvgimagecache.h" +#include + +_LIT(KRomBitmap, "z:\\system\\data\\dgdi32bit.mbm"); + +CTVgImageCache::CTVgImageCache() + { + SetTestStepName(KTDirectGdiVgImageCacheStep); + } + +CTVgImageCache::~CTVgImageCache() + { + } + +/** +@SYMTestCaseID + GRAPHICS-DIRECTGDI-VGIMAGECACHE-0001 + +@SYMPREQ + PREQ39 + +@SYMREQ + REQ9195 + REQ9201 + REQ9202 + REQ9222 + REQ9223 + REQ9236 + REQ9237 + +@SYMTestCaseDesc + Test entries are added to the cache. + +@SYMTestStatus + Implemented + +@SYMTestPriority + High + +@SYMTestActions + 1. Create bitmaps and bitmap masks. Blit them so that they are stored in the cache. + Check the VGImages created from the bitmaps are stored in the cache. + 2. Blit the bitmaps again in a different order. + Check the order that the bitmaps are stored in the cache. + +@SYMTestExpectedResults + 1. There are entries for each bitmap and bitmap mask. + 2. The bitmaps are stored in the cache in order of most-recently used to least-recently used. + */ +void CTVgImageCache::TestAddEntriesL() + { + _LIT(KTestName, "Test Bitmaps Are Added To Cache"); + if(!iRunningOomTests) + { + INFO_PRINTF1(KTestName); + } + CFbsBitmap* romBitmap = new(ELeave) CFbsBitmap; + TInt err = romBitmap->Load(KRomBitmap); + TESTNOERRORL(err); + CleanupStack::PushL(romBitmap); + + TSize bitmapSize(48,48); + TRect bitmapRect(TPoint(0,0), bitmapSize); + CFbsBitmap* bitmap1 = CreateCheckedBoardBitmapL(iTestParams.iSourcePixelFormat, bitmapSize, TSize (20, 20)); + TESTL(bitmap1 != NULL); + CleanupStack::PushL(bitmap1); + CFbsBitmap* bitmap2 = CreateCheckedBoardBitmapL(iTestParams.iSourcePixelFormat, bitmapSize, TSize (10, 10)); + TESTL(bitmap2 != NULL); + CleanupStack::PushL(bitmap2); + CFbsBitmap* bitmap3 = CreateCheckedBoardBitmapL(iTestParams.iSourcePixelFormat, bitmapSize, TSize (8, 8)); + TESTL(bitmap3 != NULL); + CleanupStack::PushL(bitmap3); + CFbsBitmap* mask1 = CreateCheckedBoardBitmapL(iTestParams.iSourcePixelFormat, bitmapSize, TSize (4, 4)); + TESTL(mask1 != NULL); + CleanupStack::PushL(mask1); + CFbsBitmap* mask2 = CreateCheckedBoardBitmapL(iTestParams.iSourcePixelFormat, bitmapSize, TSize (2, 2)); + TESTL(mask2 != NULL); + CleanupStack::PushL(mask2); + + ResetGc(); + CleanupStack::PushL(TCleanupItem(ResetCache, iVgImageCache)); + + iGc->BitBlt(TPoint(0,0), *romBitmap); + iGc->DrawBitmap(bitmapRect, *bitmap1); + iGc->BitBltMasked(TPoint(0,0), *bitmap2, bitmapRect, *mask1, EFalse); + iGc->DrawBitmapMasked(bitmapRect, *bitmap3, bitmapRect, *mask2, EFalse); + + // Check bitmaps added + TInt numEntries = iVgImageCache->NumEntries(); + TEST(numEntries == 6); + // The following tests must leave if they fail, + // otherwise a panic will occur in the ordered cache entry test + TESTL(iVgImageCache->IsInCache(romBitmap->SerialNumber())); + TESTL(iVgImageCache->IsInCache(bitmap1->SerialNumber())); + TESTL(iVgImageCache->IsInCache(bitmap2->SerialNumber())); + TESTL(iVgImageCache->IsInCache(bitmap3->SerialNumber())); + TESTL(iVgImageCache->IsInCache(mask1->SerialNumber())); + TESTL(iVgImageCache->IsInCache(mask2->SerialNumber())); + + //Blit a few more times and check order of items in cache + iGc->BitBlt(TPoint(0,0), *bitmap3); + iGc->BitBlt(TPoint(0,0), *bitmap1); + iGc->BitBlt(TPoint(0,0), *romBitmap); + iGc->BitBlt(TPoint(0,0), *mask2); + iGc->BitBlt(TPoint(0,0), *bitmap2); + + // Expect the most recently used to be at the head of the list + // i.e. bitmap2, mask2, romBitmap, bitmap1, bitmap3, mask1 + TInt64* serialNumList = new TInt64[numEntries]; + TESTL(serialNumList != NULL); + iVgImageCache->GetOrderedCacheEntries(*serialNumList,numEntries); + TEST(serialNumList[0] == bitmap2->SerialNumber()); + TEST(serialNumList[1] == mask2->SerialNumber()); + TEST(serialNumList[2] == romBitmap->SerialNumber()); + TEST(serialNumList[3] == bitmap1->SerialNumber()); + TEST(serialNumList[4] == bitmap3->SerialNumber()); + TEST(serialNumList[5] == mask1->SerialNumber()); + delete[] serialNumList; + + CleanupStack::PopAndDestroy(7, romBitmap); + } + +/** +@SYMTestCaseID + GRAPHICS-DIRECTGDI-VGIMAGECACHE-0002 + +@SYMPREQ + PREQ39 + +@SYMREQ + REQ9195 + REQ9201 + REQ9202 + REQ9222 + REQ9223 + REQ9236 + REQ9237 + +@SYMTestCaseDesc + Test entries are added to the cache. + +@SYMTestStatus + Implemented + +@SYMTestPriority + High + +@SYMTestActions + Create a bitmap. Blit it so that it is stored in the cache. + Check there is an entry for that bitmap in the cache. + Resize the bitmap (so that the bitmap's touch count is increased). + Blit the bitmap again. + Check the value of the touch count stored in the cache. + +@SYMTestExpectedResults + Entry exists for bitmap and touch count value stored in cache + is same as the bitmap after it was resized. + + */ +void CTVgImageCache::TestBitmapResizedL() + { + _LIT(KTestName, "Test That Images In Cache Are Updated When Associated Bitmap Is Resized"); + if(!iRunningOomTests) + { + INFO_PRINTF1(KTestName); + } + TSize bitmapSize(48,48); + CFbsBitmap* bitmap = CreateCheckedBoardBitmapL(iTestParams.iSourcePixelFormat, bitmapSize, TSize (8, 8)); + TESTL(bitmap != NULL); + + ResetGc(); + + iGc->BitBlt(TPoint(0,0), *bitmap); + TInt64 serialNumber = bitmap->SerialNumber(); + // Check bitmaps added + TEST(iVgImageCache->IsInCache(serialNumber)); + TInt oldTouchCount = iVgImageCache->TouchCount(serialNumber); + TEST(oldTouchCount == bitmap->TouchCount()); + + //Resize bitmap + TESTNOERROR(bitmap->Resize(TSize(80,24))); + iGc->BitBlt(TPoint(0,0), *bitmap); + TEST(iVgImageCache->TouchCount(serialNumber) != oldTouchCount); + TEST(iVgImageCache->TouchCount(serialNumber) == bitmap->TouchCount()); + + delete bitmap; + iVgImageCache->ResetCache(); + } + + +/** +@SYMTestCaseID + GRAPHICS-DIRECTGDI-VGIMAGECACHE-0003 + +@SYMPREQ + PREQ39 + +@SYMREQ + REQ9195 + REQ9201 + REQ9202 + REQ9222 + REQ9223 + REQ9236 + REQ9237 + +@SYMTestCaseDesc + Test entries are added to the cache. + +@SYMTestStatus + Implemented + +@SYMTestPriority + High + +@SYMTestActions + Create a bitmap. Blit it so that it is stored in the cache. + Check there is an entry for that bitmap in the cache. + Swap the width and height of the bitmap (so that the bitmap's touch count is increased). + Blit the bitmap again. + Check the value of the touch count stored in the cache. + +@SYMTestExpectedResults + Entry exists for bitmap and touch count value stored in cache + is same as the bitmap after its width and height were swapped. + + */ +void CTVgImageCache::TestBitmapSwapWidthAndHeightL() + { + _LIT(KTestName, "Test That Images In Cache Are Updated When Associated Bitmap Swaps Height and Width"); + if(!iRunningOomTests) + { + INFO_PRINTF1(KTestName); + } + TSize bitmapSize(40,60); + CFbsBitmap* bitmap = CreateCheckedBoardBitmapL(iTestParams.iSourcePixelFormat, bitmapSize, TSize (8, 8)); + TESTL(bitmap != NULL); + + ResetGc(); + iVgImageCache->ResetCache(); + + iGc->BitBlt(TPoint(0,0), *bitmap); + // Check bitmap is added to cache + TEST(iVgImageCache->IsInCache(bitmap->SerialNumber())); + TInt oldTouchCount = bitmap->TouchCount(); + TEST(oldTouchCount == iVgImageCache->TouchCount(bitmap->SerialNumber())); + + // Swap width & height of bitmap within a Begin/End bounds + // so that touch count increases + TESTNOERROR(bitmap->SwapWidthAndHeight()); + TInt newTouchCount = bitmap->TouchCount(); + iGc->BitBlt(TPoint(0,0), *bitmap); + // Check touch count is now different + TEST(newTouchCount != oldTouchCount); + // Expect cache to update entry for bitmap + TEST(iVgImageCache->TouchCount(bitmap->SerialNumber()) == newTouchCount); + + delete bitmap; + iVgImageCache->ResetCache(); + } + +/** +@SYMTestCaseID + GRAPHICS-DIRECTGDI-VGIMAGECACHE-0004 + +@SYMPREQ + PREQ39 + +@SYMREQ + REQ9195 + REQ9201 + REQ9202 + REQ9222 + REQ9223 + REQ9236 + REQ9237 + +@SYMTestCaseDesc + Test entries are not added to the cache for volatile bitmaps. + +@SYMTestStatus + Implemented + +@SYMTestPriority + High + +@SYMTestActions + Create Font Image Storage. In the cycle request Glyph Image entry for particular Glyph + code and font ID. + Delete Glyph Storage. + +@SYMTestExpectedResults + No entry exists for the bitmap in the cache. + + */ +void CTVgImageCache::TestVolatileBitmapL() + { + _LIT(KTestName, "Test That Volatile Bitmaps Are not Stored In Cache"); + if(!iRunningOomTests) + { + INFO_PRINTF1(KTestName); + } + TSize bitmapSize(40,60); + CFbsBitmap* bitmap = CreateCheckedBoardBitmapL(iTestParams.iSourcePixelFormat, bitmapSize, TSize (8, 8)); + TESTL(bitmap != NULL); + + ResetGc(); + iVgImageCache->ResetCache(); + + // Make bitmap volatile + bitmap->DataAddress(); + iGc->BitBlt(TPoint(0,0), *bitmap); + // Check bitmap is added to cache + TEST(!iVgImageCache->IsInCache(bitmap->SerialNumber())); + + delete bitmap; + iVgImageCache->ResetCache(); + } + +/** +@SYMTestCaseID + GRAPHICS-DIRECTGDI-VGIMAGECACHE-0005 + +@SYMPREQ + PREQ39 + +@SYMREQ + REQ9195 + REQ9201 + REQ9202 + REQ9222 + REQ9223 + REQ9236 + REQ9237 + +@SYMTestCaseDesc + Test least recently used entries are deleted when the cache is full and a new entry is added to the cache. + +@SYMTestStatus + Implemented + +@SYMTestPriority + High + +@SYMTestActions + Fill the cache up (by blitting many different bitmaps). + Blit one more bitmap so that the cache has to delete an entry. + Get the driver's MDirectGdiDriverCacheSize extension interface. + Check that a new maximum cache size cannot be set that is smaller + than the existing cache size. + +@SYMTestExpectedResults + An entry was deleted and that entry was the least recently used. + A cache size cannot be set that is smaller than the existing cache size. + */ +void CTVgImageCache::TestFullCacheL() + { + _LIT(KTestName, "Test Adding Image to Cache when Cache is Full"); + if(!iRunningOomTests) + { + INFO_PRINTF1(KTestName); + } + + ResetGc(); + iVgImageCache->ResetCache(); + CleanupStack::PushL(TCleanupItem(ResetCache, iVgImageCache)); + TInt maxCacheSize = iVgImageCache->MaxCacheSize(); + + TSize bitmapSize(200,200); + TInt dataStride = CFbsBitmap::ScanLineLength(bitmapSize.iWidth, TDisplayModeMapping::MapPixelFormatToDisplayMode(iTestParams.iSourcePixelFormat)); + TInt imageSizeInBytes = bitmapSize.iHeight * dataStride; + TSize checksPerAxis(1,1); + // Create the first bitmap to be added to the cache. + // This is also be the bitmap to be removed from the cache when full. + CFbsBitmap* firstBitmap = CreateCheckedBoardBitmapL(iTestParams.iSourcePixelFormat, bitmapSize, checksPerAxis); + TESTL(firstBitmap != NULL); + CleanupStack::PushL(firstBitmap); + iGc->BitBlt(TPoint(0,0), *firstBitmap); + TEST(iVgImageCache->IsInCache(firstBitmap->SerialNumber())); + + // Fill the cache up. + while(imageSizeInBytes + iVgImageCache->CacheSizeInBytes() < maxCacheSize) + { + CFbsBitmap* bitmap = CreateCheckedBoardBitmapL(iTestParams.iSourcePixelFormat, bitmapSize, checksPerAxis); + TESTL(bitmap != NULL); + iGc->BitBlt(TPoint(0,0), *bitmap); + delete bitmap; + } + + // Add one more entry to the cache + CFbsBitmap* bitmap = CreateCheckedBoardBitmapL(iTestParams.iSourcePixelFormat, bitmapSize, checksPerAxis); + TESTL(bitmap != NULL); + TEST(!iVgImageCache->IsInCache(bitmap->SerialNumber())); + TEST(iVgImageCache->IsInCache(firstBitmap->SerialNumber())); + iGc->BitBlt(TPoint(0,0), *bitmap); + + // firstBitmap should now have been removed from the cache as it was the least recently used. + TEST(!iVgImageCache->IsInCache(firstBitmap->SerialNumber())); + // last bitmap should be in cache + TEST(iVgImageCache->IsInCache(bitmap->SerialNumber())); + + // get the driver's MDirectGdiDriverCacheSize extension interface and attempt + // to set the maximum cache size to be smaller than the existing cache size + CDirectGdiDriver* driver = CDirectGdiDriver::Static(); + TESTL(driver != NULL); + MDirectGdiDriverCacheSize* driverCacheSize = NULL; + TInt res = driver->GetInterface(TUid::Uid(KDirectGdiDriverCacheSizeUid), (TAny*&)driverCacheSize); + TESTNOERRORL(res); + // save the original cache size + TInt originalCacheSize = driverCacheSize->MaxImageCacheSize(); + // setting the cache size to a size smaller than the existing cache should fail + res = driverCacheSize->SetMaxImageCacheSize(iVgImageCache->CacheSizeInBytes()-1); + TEST(res == KErrArgument); + // setting the cache size to the same size as the existing cache should pass + res = driverCacheSize->SetMaxImageCacheSize(iVgImageCache->CacheSizeInBytes()); + TESTNOERROR(res); + TEST(iVgImageCache->CacheSizeInBytes() == driverCacheSize->MaxImageCacheSize()); + // reset the original driver cache size + res = driverCacheSize->SetMaxImageCacheSize(originalCacheSize); + TESTNOERROR(res); + + delete bitmap; + CleanupStack::PopAndDestroy(firstBitmap); + CleanupStack::PopAndDestroy(iVgImageCache); + } + +/** +@SYMTestCaseID + GRAPHICS-DIRECTGDI-VGIMAGECACHE-0006 + +@SYMPREQ + PREQ39 + +@SYMREQ + REQ9195 + REQ9201 + REQ9202 + REQ9222 + REQ9223 + REQ9236 + REQ9237 + +@SYMTestCaseDesc + Test adding a bitmap larger than maximum size of cache. + +@SYMTestStatus + Implemented + +@SYMTestPriority + High + +@SYMTestActions. + Blit a small bitmap which is added to the cache. + Blit a bitmap whose size in pixels is more than the maximum size of the cache. + +@SYMTestExpectedResults + An entry for the large bitmap should not appear in the cache. + An entry for the small bitmap should appear in the cache. + + */ +void CTVgImageCache::TestImageLargerThanCacheL() + { + _LIT(KTestName, "Test Adding Image Larger Than Cache"); + if(!iRunningOomTests) + { + INFO_PRINTF1(KTestName); + } + + ResetGc(); + iVgImageCache->ResetCache(); + TInt maxCacheSize = iVgImageCache->MaxCacheSize(); + + // Calculate height of bitmap whose width is 512 pixels so that the total size in bytes of the bitmap + // is the same as the maximum cache size. + TInt dataStride = CFbsBitmap::ScanLineLength(512, TDisplayModeMapping::MapPixelFormatToDisplayMode(iTestParams.iSourcePixelFormat)); + TInt largeBitmapHeight = maxCacheSize / dataStride; + // Want bitmap with a larger size in bytes than cache, + // so create a bitmap with width of 550 pixels and largeBitmapHeight + TSize largeBitmapSize(550,largeBitmapHeight); + + TSize smallBitmapSize(200,200); + + TSize checksPerAxis(1,1); + + // Create a small bitmap to be added to the cache. + CFbsBitmap* smallBitmap = CreateCheckedBoardBitmapL(iTestParams.iSourcePixelFormat, smallBitmapSize, checksPerAxis); + TESTL(smallBitmap != NULL); + CleanupStack::PushL(smallBitmap); + // Create large bitmap which is too large to fit in cache + CFbsBitmap* largeBitmap = CreateCheckedBoardBitmapL(iTestParams.iSourcePixelFormat, largeBitmapSize, checksPerAxis); + TESTL(largeBitmap != NULL); + + // Add small bitmap to cache + iGc->BitBlt(TPoint(0,0), *smallBitmap); + TEST(iVgImageCache->IsInCache(smallBitmap->SerialNumber())); + + // Blit large bitmap + iGc->BitBlt(TPoint(0,0), *largeBitmap); + TEST(!iVgImageCache->IsInCache(largeBitmap->SerialNumber())); + TEST(iVgImageCache->IsInCache(smallBitmap->SerialNumber())); + + delete largeBitmap; + CleanupStack::PopAndDestroy(smallBitmap); + iVgImageCache->ResetCache(); + } + +/** +Override of base class virtual +@leave Gets system wide error code +@return - TVerdict code +*/ +TVerdict CTVgImageCache::doTestStepPreambleL() + { + CTDirectGdiStepBase::doTestStepPreambleL(); + return TestStepResult(); + } + +/** +Override of base class pure virtual +Our implementation only gets called if the base class doTestStepPreambleL() did +not leave. That being the case, the current test result value will be EPass. +@leave Gets system wide error code +@return TVerdict code +*/ +TVerdict CTVgImageCache::doTestStepL() + { + if (iUseDirectGdi) + { + // Test independent of target pixel formats, so just use first. + iTestParams.iTargetPixelFormat = iTargetPixelFormatArray[0]; + // Test needs a VG compatible source pixel format. + iTestParams.iSourcePixelFormat = EUidPixelFormatRGB_565; + SetTargetL(iTestParams.iTargetPixelFormat); + if (!iUseSwDirectGdi) + { + RunTestsL(); + RunOomTestsL(); + } + else + { + INFO_PRINTF1(_L("SW DirectGDI has no image cache to test!")); + } + + } + else + { + INFO_PRINTF1(_L("BitGDI has no image cache to test!")); + } + return TestStepResult(); + } + +/** +Override of base class pure virtual +Lists the tests to be run +*/ +void CTVgImageCache::RunTestsL() + { + SetTestStepID(_L("GRAPHICS-DIRECTGDI-VGIMAGECACHE-0001")); + TestAddEntriesL(); + RecordTestResultL(); + SetTestStepID(_L("GRAPHICS-DIRECTGDI-VGIMAGECACHE-0005")); + TestFullCacheL(); + RecordTestResultL(); + SetTestStepID(_L("GRAPHICS-DIRECTGDI-VGIMAGECACHE-0006")); + TestImageLargerThanCacheL(); + RecordTestResultL(); + SetTestStepID(_L("GRAPHICS-DIRECTGDI-VGIMAGECACHE-0002")); + TestBitmapResizedL(); + RecordTestResultL(); + SetTestStepID(_L("GRAPHICS-DIRECTGDI-VGIMAGECACHE-0003")); + TestBitmapSwapWidthAndHeightL(); + RecordTestResultL(); + SetTestStepID(_L("GRAPHICS-DIRECTGDI-VGIMAGECACHE-0004")); + TestVolatileBitmapL(); + RecordTestResultL(); + }