// ============================ MEMBER FUNCTIONS =============================== // ----------------------------------------------------------------------------- // CMaskedBitmap::CopyBitmap // ----------------------------------------------------------------------------- TInt BitmapUtil::CopyBitmap( const CFbsBitmap& aSource, CFbsBitmap& aDestination ) { TSize size( aSource.SizeInPixels() ); TDisplayMode displayMode( aSource.DisplayMode() ); TInt err( aDestination.Create( size, displayMode ) ); if( !err ) { err = BitmapUtil::CopyBitmapData( aSource, aDestination, size, displayMode ); if( err ) { aDestination.Reset(); } } return err; }
/** @SYMTestCaseID GRAPHICS-FBSERV-0512 @SYMTestCaseDesc Creates bitmaps in different ways and checks if memory allocation succeeded @SYMTestActions Creates normal size bitmaps, large bitmaps, loads bitmaps, loads shared bitmaps, duplicated bitmaps, resizes bitmaps, compresses bitmaps, externalized bitmaps to write store, internalizes bitmaps back again from write store. All ways of creating bitmaps are tested against Out Of Memory error conditions @SYMTestExpectedResults Test should pass */ void CTAlloc::BitmapsL() { TInt heapMarkCheckFlag; if( !iStep->GetIntFromConfig(KDefaultSectionName, KFbsHeapMarkCheckFlag, heapMarkCheckFlag) ) { INFO_PRINTF1(_L("Error reading ini file")); User::Leave(KErrNotFound); } CFbsBitmap iBitmap; CFbsBitmap iBitmap2; iTestBitmapName = KTestBitmapOnZ; TInt ret = iBitmap.Load(iTestBitmapName,ETfbs,NULL); TEST2(ret, KErrNone); ret = iBitmap.Create(KLargeSize,EColor256); // Expand server caches TEST2(ret, KErrNone); iBitmap.Reset(); TInt count; // Create bitmap INFO_PRINTF1(_L("CFbsBitmap::Create()\r\n")); for (count = 1; ; count++) { iFbs->SendCommand(EFbsMessDefaultAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } ret = iBitmap.Create(KSmallSize,EColor256); if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } } else if (ret == KErrNone) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==0); for (count = 1; ; count++) { iFbs->SendCommand(EFbsMessUserAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } ret=iBitmap.Create(KSmallSize,EGray2); if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } } else if (ret == KErrNone) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==0); // Create (large) for (count = 1; ; count++) { iFbs->SendCommand(EFbsMessDefaultAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } ret = iBitmap.Create(KLargeSize,EColor256); if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } } else if (ret == KErrNone) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==0); for (count = 1; ; count++) { iFbs->SendCommand(EFbsMessUserAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } ret = iBitmap.Create(KLargeSize,EColor256); if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } } else if (ret == KErrNone) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==0); // Load INFO_PRINTF1(_L("CFbsBitmap::Load()\r\n")); ret = iBitmap.Load(iTestBitmapName,ETfbs,NULL); TEST2(ret, KErrNone); iBitmap.Reset(); for (count = 1; ; count++) { iFbs->SendCommand(EFbsMessDefaultAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } ret = iBitmap.Load(iTestBitmapName,ETfbs,NULL); if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } } else if (ret == KErrNone) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==0); for (count = 1; ; count++) { iFbs->SendCommand(EFbsMessUserAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } ret = iBitmap.Load(iTestBitmapName,ETfbs,NULL); if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } } else if (ret == KErrNone) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==0); // Load (shared) INFO_PRINTF1(_L("CFbsBitmap::Load() - shared \r\n")); // Do an initial load to ensure the StreamId cache does not get updated whilst OOM testing ret = iBitmap.Load(iTestBitmapName,ETfbs,ETrue); TEST2(ret, KErrNone); iBitmap.Reset(); for (count = 1; ; count++) { iFbs->SendCommand(EFbsMessDefaultAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } ret = iBitmap.Load(iTestBitmapName,ETfbs,ETrue); if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } continue; } else if (ret != KErrNone) TEST2(ret, KErrNone); ret = iBitmap2.Load(iTestBitmapName,ETfbs,ETrue); if (ret == KErrNoMemory) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } continue; } else if (ret == KErrNone) { iBitmap.Reset(); iBitmap2.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==0); for (count = 1; ; count++) { iFbs->SendCommand(EFbsMessUserAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } ret = iBitmap.Load(iTestBitmapName,ETfbs,ETrue); if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } continue; } else if (ret != KErrNone) TEST2(ret, KErrNone); ret = iBitmap2.Load(iTestBitmapName,ETfbs,ETrue); if (ret == KErrNoMemory) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } continue; } else if (ret == KErrNone) { iBitmap.Reset(); iBitmap2.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==0); // Duplicate CFbsBitmap bmpalt; ret = bmpalt.Create(KSmallSize,EColor256); TEST2(ret, KErrNone); INFO_PRINTF1(_L("CFbsBitmap::Duplicate()\r\n")); for (count = 1; ; count++) { iFbs->SendCommand(EFbsMessDefaultAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } ret = iBitmap.Duplicate(bmpalt.Handle()); if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } } else if (ret == KErrNone) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==1); ret = bmpalt.Create(KSmallSize,EColor256); TEST2(ret, KErrNone); for (count = 1; ; count++) { iFbs->SendCommand(EFbsMessUserAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } ret = iBitmap.Duplicate(bmpalt.Handle()); if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } } else if (ret == KErrNone) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); bmpalt.Reset(); TEST(iFbs->ResourceCount()==0); // Resize // force fbserv to do a resize. This makes the pile to insert an index in it's array // If the array is empty when the tests below are run then the insert will look like a mem leak ret=iBitmap.Create(KLargeSize,EColor256); iBitmap.Resize(KLargeSizeAlt); iBitmap.Reset(); ret=iBitmap.Create(KSmallSize,EColor256); TEST2(ret, KErrNone); INFO_PRINTF1(_L("CFbsBitmap::Resize()\r\n")); for (count = 1; ; count++) { iFbs->SendCommand(EFbsMessDefaultAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } ret = iBitmap.Resize(KSmallSizeAlt); if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } } else if (ret == KErrNone) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==0); // force fbserv to do a resize. This makes the pile to insert an index in it's array // If the array is empty when the tests below are run then the insert will look like a mem leak ret=iBitmap.Create(KLargeSize,EColor256); iBitmap.Resize(KLargeSizeAlt); iBitmap.Reset(); ret=iBitmap.Create(KLargeSize,EColor256); TEST2(ret, KErrNone); for (count = 1; ; count++) { iFbs->SendCommand(EFbsMessUserAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } ret = iBitmap.Resize(KLargeSizeAlt); if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } } else if (ret == KErrNone) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==0); // Compress ret=iBitmap.Create(KSmallSize,EColor256); TEST2(ret, KErrNone); INFO_PRINTF1(_L("CFbsBitmap::Compress()\r\n")); for (count = 1; ; count++) { iFbs->SendCommand(EFbsMessDefaultAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } ret = iBitmap.Compress(); if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } } else if (ret == KErrNone) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==0); ret=iBitmap.Create(KLargeSize,EColor256); TEST2(ret, KErrNone); INFO_PRINTF1(_L("CFbsBitmap::Compress()\r\n")); for (count = 1; ; count++) { iFbs->SendCommand(EFbsMessDefaultAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } ret = iBitmap.Compress(); if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } } else if (ret == KErrNone) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==0); // WriteStore creation RFs fs; ret=fs.Connect(); TEST2(ret, KErrNone); CDirectFileStore* writestore=NULL; //Construct filename using the thread id to enable concurrent test runs. _LIT(KSbmFileName,"c:\\tall_"); TBuf<36> buf(KSbmFileName); TThreadId threadId = RThread().Id(); TUint64 id = threadId.Id(); TBuf<20> threadIdBuf; threadIdBuf.Num(id); buf.Append(threadIdBuf); buf.Append(_L(".sbm")); TRAP(ret,writestore=CDirectFileStore::ReplaceL(fs,buf,EFileStream|EFileWrite)); TEST2(ret, KErrNone); TUidType uidtype(KDirectFileStoreLayoutUid,KMultiBitmapFileImageUid); TRAP(ret,writestore->SetTypeL(uidtype)); TEST2(ret, KErrNone); RStoreWriteStream writestrm; TStreamId headerid(0); TRAP(ret,headerid=writestrm.CreateL(*writestore)); TEST2(ret, KErrNone); TRAP(ret,writestore->SetRootL(headerid)); TEST2(ret, KErrNone); // Externalize ret=iBitmap.Create(KSmallSize,EColor256); TEST2(ret, KErrNone); INFO_PRINTF1(_L("CFbsBitmap::ExternalizeL()\r\n")); for (count = 1; ; count++) { __UHEAP_SETFAIL(RHeap::EDeterministic,count); __UHEAP_MARK; TRAP(ret,iBitmap.ExternalizeL(writestrm)); if (ret == KErrNoMemory) { __UHEAP_MARKEND; } else if (ret == KErrNone) { iBitmap.Reset(); __UHEAP_MARKEND; break; } else { __UHEAP_MARKEND; TEST2(ret, KErrNone); } } __UHEAP_RESET; TEST(iFbs->ResourceCount()==0); // ExternalizeRectangle ret=iBitmap.Create(KSmallSize,EColor256); TEST2(ret, KErrNone); INFO_PRINTF1(_L("CFbsBitmap::ExternalizeRectangleL()\r\n")); for (count = 1; ; count++) { __UHEAP_SETFAIL(RHeap::EDeterministic,count); __UHEAP_MARK; TRAP(ret,iBitmap.ExternalizeRectangleL(writestrm,TRect(3,3,7,7))); if (ret == KErrNoMemory) { __UHEAP_MARKEND; } else if (ret == KErrNone) { __UHEAP_MARKEND; break; } else { __UHEAP_MARKEND; TEST2(ret, KErrNone); } } __UHEAP_RESET; writestrm.Close(); delete writestore; iBitmap.Reset(); TEST(iFbs->ResourceCount()==0); // Internalize INFO_PRINTF1(_L("CFbsBitmap::InternalizeL()\r\n")); for (count = 1; ; count++) { // ReadStore creation CDirectFileStore* readstore=NULL; TRAP(ret,readstore=CDirectFileStore::OpenL(fs,buf,EFileStream|EFileRead|EFileShareAny)); TEST2(ret, KErrNone); RStoreReadStream readstrm; headerid=readstore->Root(); TRAP(ret,readstrm.OpenL(*readstore,headerid)); TEST2(ret, KErrNone); iFbs->SendCommand(EFbsMessDefaultAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } TRAP(ret,iBitmap.InternalizeL(readstrm)); readstrm.Close(); delete readstore; if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } } else if (ret == KErrNone) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==0); for (count = 1; ; count++) { // ReadStore re-creation CDirectFileStore* readstore=NULL; // TRAP(ret,readstore=CDirectFileStore::OpenL(fs,_L("c:\\tall.sbm"),EFileStream|EFileRead|EFileShareAny)); TRAP(ret,readstore=CDirectFileStore::OpenL(fs,buf,EFileStream|EFileRead|EFileShareAny)); TEST2(ret, KErrNone); headerid=readstore->Root(); RStoreReadStream readstrm; TRAP(ret,readstrm.OpenL(*readstore,headerid)); TEST2(ret, KErrNone); iFbs->SendCommand(EFbsMessUserAllocFail,count); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMark); iFbs->SendCommand(EFbsMessUserMark); } TRAP(ret,iBitmap.InternalizeL(readstrm)); readstrm.Close(); delete readstore; if (ret == KErrNoMemory) { if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } } else if (ret == KErrNone) { iBitmap.Reset(); if(heapMarkCheckFlag) { iFbs->SendCommand(EFbsMessDefaultMarkEnd); iFbs->SendCommand(EFbsMessUserMarkEnd); } break; } else TEST2(ret, KErrNone); } iFbs->SendCommand(EFbsMessDefaultAllocFail,0); iFbs->SendCommand(EFbsMessUserAllocFail,0); TEST(iFbs->ResourceCount()==0); fs.Delete(buf); fs.Close(); }