diff -r 2717213c588a -r 171fae344dd4 windowing/windowserver/tdynamicres/src/surfaceutility.cpp --- a/windowing/windowserver/tdynamicres/src/surfaceutility.cpp Tue Jun 22 15:21:29 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1544 +0,0 @@ -// 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: -// - -/** - @file -*/ - -#include -#include -#include "surfaceutility.h" - -CSurfaceUtility::CSurfaceUtility(CSurfaceUtility* aClone/*=NULL*/) - : iSurfaces(aClone?&(aClone->iSurfaces):NULL) - { - } - -CSurfaceUtility* CSurfaceUtility::NewL(CSurfaceUtility* aClone/*=NULL*/) - { - CSurfaceUtility* utility = new (ELeave)CSurfaceUtility(aClone); - CleanupStack::PushL(utility); - utility->ConstructL(); - CleanupStack::Pop(utility); - return utility; - } - -void CSurfaceUtility::ConstructL() - { - TInt r = iManager.Open(); - if (r != KErrNone) - { - LOG(("Surface manager failed to open: %d", r)); - User::Leave(r); - } - - r = iSurfaceUpdateSession.Connect(); - if (r != KErrNone) - { - LOG(("Failed to connect to update server: %d", r)); - User::Leave(r); - } - } - -CSurfaceUtility::~CSurfaceUtility() - { - DestroyAll(); - - iSurfaces.Close(); - - iManager.Close(); - - iSurfaceUpdateSession.Close(); - } - -TBool CSurfaceUtility::DestroyAll() - { - TInt err = KErrNone; - TInt jj = iSurfaces.Count() - 1; - if (jj<0) - return EFalse; - for (; jj >= 0; jj--) - { - err = iManager.CloseSurface(iSurfaces[jj]); - if (err!=KErrNone) - { - LOG(("Error closing surface: 0x%X\n", err)); - } - } - iSurfaces.Reset(); - return ETrue; - } - -/*************************************** - * The aim of the THeapSurfaceArray is to locally switch in the specified heap for any array operation - ***************************************/ - -CSurfaceUtility::RHeapSurfaceArray::RHeapSurfaceArray(RHeapSurfaceArray* aUseExternalArray) - : iUseArray(aUseExternalArray?aUseExternalArray->iUseArray:&this->iLocalArray), - iExternalHeapRef(aUseExternalArray?aUseExternalArray->iExternalHeapRef:User::Heap()) - { - - } -/************************************ - * The following methods have been used by the surfaceutility... some require the heap wrapping, and some don't - * I actually need three different startegies (count em) for 7 methods... - * Some methods only read the existing objects, so don't need a heap swap at all - * Leaving methods have to use PopAndDestroy strategy to restore the heap on leaving or success - * Non-leaving methods must not call PushL, so directly make SwitchHeap calls! - ************************************/ - -// PopAndDestroy method to restore the heap -/*static*/ void CSurfaceUtility::RHeapSurfaceArray::PopHeap(void* aHeapPtr) - { - RHeap* heapPtr=(RHeap*)aHeapPtr; - User::SwitchHeap(heapPtr); - } - -// Switches and pushes the previous heap so it can be restored with PopAndDestroy -/*static*/ void CSurfaceUtility::RHeapSurfaceArray::SwitchHeapLC(RHeap* aNewHeap) - { - CleanupStack::PushL(TCleanupItem(PopHeap,NULL)); - CleanupStack::PushL(TCleanupItem(PopHeap,NULL)); - CleanupStack::PushL(TCleanupItem(PopHeap,NULL)); - CleanupStack::Pop(3); - RHeap* oldHeap=User::SwitchHeap(aNewHeap); - delete new char; - CleanupStack::PushL(TCleanupItem(PopHeap,oldHeap)); - } - - -TSurfaceId& CSurfaceUtility::RHeapSurfaceArray::operator[](TUint aIndex) - { - return iUseArray->operator[](aIndex); - } -// Close only closes the local array, while Reset resets the active array (may be external) -void CSurfaceUtility::RHeapSurfaceArray::Close() - { - RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef); - iLocalArray.Close(); - User::SwitchHeap(oldHeap); - } -TInt CSurfaceUtility::RHeapSurfaceArray::Count() const - { - return iUseArray->Count(); - } -// Close only closes the local array, while Reset resets the active array (may be external) -inline void CSurfaceUtility::RHeapSurfaceArray::Reset() - { - RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef); - iUseArray->Reset(); - User::SwitchHeap(oldHeap); - } -void CSurfaceUtility::RHeapSurfaceArray::AppendL(const TSurfaceId &anEntry) - { - SwitchHeapLC(&iExternalHeapRef); - iUseArray->AppendL(anEntry); - CleanupStack::PopAndDestroy(); - } -TInt CSurfaceUtility::RHeapSurfaceArray::Find(const TSurfaceId &anEntry) const - { - return iUseArray->Find(anEntry); - } -void CSurfaceUtility::RHeapSurfaceArray::Remove(TInt anIndex) - { - RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef); - iUseArray->Remove(anIndex); - User::SwitchHeap(oldHeap); - } - - - - -/** -Cleanup stack helper object, holding references to both utility and surface, so -that the standard Close() semantics can be used. -*/ -class TSurfaceCleanup - { -public: - TSurfaceCleanup(CSurfaceUtility& aUtility, TSurfaceId& aSurface) - : iUtility(aUtility), iSurface(aSurface) - {} - void Close() - { - // Removes the surface from the list of surfaces to clean up, and closes - // the surface reference. - iUtility.DestroySurface(iSurface); - } -private: - CSurfaceUtility& iUtility; - TSurfaceId& iSurface; - }; - -/** -Read the given image file into a new surface. - -@param aFileName The name of the image file. -@param aSurface Filled with the surface ID for the surface containing the pixels. -*/ -void CSurfaceUtility::CreateSurfaceFromFileL(const TDesC& aFileName, TSurfaceId& aSurface) - { - RFs fs; - - User::LeaveIfError(fs.Connect()); - CleanupClosePushL(fs); - CImageDecoder* decoder = CImageDecoder::FileNewL(fs, aFileName, CImageDecoder::EOptionAlwaysThread); - CleanupStack::PushL(decoder); - - const TFrameInfo& info = decoder->FrameInfo(); - - TSize size = info.iOverallSizeInPixels; - TInt stride = size.iWidth << 2; // Default to four bytes per pixel - TDisplayMode bmpFormat = info.iFrameDisplayMode; - TUidPixelFormat pixelFormat = EUidPixelFormatUnknown; - - switch (bmpFormat) - { - case EGray2: - case EGray4: - case EGray16: - case EGray256: - case EColor16: - case EColor256: - case EColor16M: - case EColor16MU: - { - bmpFormat = EColor16MU; - pixelFormat = EUidPixelFormatXRGB_8888; - break; - } - case EColor4K: - { - stride = size.iWidth << 1; - pixelFormat = EUidPixelFormatXRGB_4444; - break; - } - case EColor64K: - { - stride = size.iWidth << 1; - pixelFormat = EUidPixelFormatRGB_565; - break; - } - case EColor16MA: - { - pixelFormat = EUidPixelFormatARGB_8888; - break; - } - case EColor16MAP: - { - pixelFormat = EUidPixelFormatARGB_8888_PRE; - break; - } - default: - { - LOG(("Unsupported display mode: %d", bmpFormat)); - User::Leave(KErrNotSupported); - break; - } - } - - // Create an intermediary bitmap for decoding into - CFbsBitmap* bitmap = new (ELeave) CFbsBitmap(); - CleanupStack::PushL(bitmap); - User::LeaveIfError(bitmap->Create(size, info.iFrameDisplayMode)); - - // Create the final surface. - aSurface = CreateSurfaceL(size, pixelFormat, stride); - TSurfaceCleanup surfaceCleanup(*this, aSurface); - CleanupClosePushL(surfaceCleanup); - - RChunk chunk; - User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); - CleanupClosePushL(chunk); - - // Convert the image file into a Symbian bitmap - TRequestStatus status; - decoder->Convert(&status, *bitmap); - User::WaitForRequest(status); - User::LeaveIfError(status.Int()); - - TInt offsetToFirstBuffer; - User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer)); - - // Copy the data from the bitmap into the surface. - TPoint start; - TUint8 *pSurfStart = chunk.Base() + offsetToFirstBuffer; - for (start.iY = 0; start.iY < size.iHeight; start.iY++) - { - // Set up a descriptor for the current line in the surface and get pixels. - TPtr8 ptr(pSurfStart + start.iY * stride, stride); - bitmap->GetScanLine(ptr, start, size.iWidth, bmpFormat); - } - - CleanupStack::PopAndDestroy(/* chunk */); - CleanupStack::Pop(/* surfaceCleanup */); - CleanupStack::PopAndDestroy(bitmap); - CleanupStack::PopAndDestroy(decoder); - CleanupStack::PopAndDestroy(/* fs */); - } - -void CSurfaceUtility::CopyBitmapSurfaceL(const CFbsBitmap* aBitmap, TSurfaceId& aSurface) - { - RChunk chunk; - User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); - CleanupClosePushL(chunk); - TSize bitmapSize = aBitmap->SizeInPixels(); - TSize size = SurfaceSize(aSurface); - TInt stride = size.iWidth*4; // Default to four bytes per pixel - - TInt offsetToFirstBuffer; - User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer)); - - // Copy the data from the bitmap into the surface. - TPoint start; - TUint8 *pSurfStart = chunk.Base() + offsetToFirstBuffer; - for (start.iY = 0; start.iY < bitmapSize.iHeight; start.iY++) - { - // Set up a descriptor for the current line in the surface and get pixels. - TPtr8 ptr(pSurfStart + start.iY * stride, stride); - aBitmap->GetScanLine(ptr, start, bitmapSize.iWidth, EColor16MU); - } - CleanupStack::PopAndDestroy(/* chunk */); - - } -/** -Copy the bitmap from a file to a surface. - -@param aFileName The name of the image file. -@param aSurface Filled with the surface ID for the surface containing the pixels. -*/ -void CSurfaceUtility::CopyBitmapFromFileToSurfaceL(const TDesC& aFileName, TSurfaceId& aSurface) - { - RFs fs; - - User::LeaveIfError(fs.Connect()); - CleanupClosePushL(fs); - CImageDecoder* decoder = CImageDecoder::FileNewL(fs, aFileName, CImageDecoder::EOptionAlwaysThread); - CleanupStack::PushL(decoder); - - const TFrameInfo& info = decoder->FrameInfo(); - - RSurfaceManager::TInfoBuf infoBuf; - RSurfaceManager::TSurfaceInfoV01& infoSurf = infoBuf(); - User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); - - TSize size = infoSurf.iSize; - TDisplayMode bmpFormat = info.iFrameDisplayMode; - TInt stride = size.iWidth << 2; // Default to four bytes per pixel - - // Create an intermediary bitmap for decoding into - CFbsBitmap* bitmap = new (ELeave) CFbsBitmap(); - CleanupStack::PushL(bitmap); - User::LeaveIfError(bitmap->Create(size, info.iFrameDisplayMode)); - - RChunk chunk; - User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); - CleanupClosePushL(chunk); - - // Convert the image file into a Symbian bitmap - TRequestStatus status; - decoder->Convert(&status, *bitmap); - User::WaitForRequest(status); - User::LeaveIfError(status.Int()); - - TInt offsetToFirstBuffer; - User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer)); - - // Copy the data from the bitmap into the surface. - TPoint start; - TUint8 *pSurfStart = chunk.Base() + offsetToFirstBuffer; - for (start.iY = 0; start.iY < size.iHeight; start.iY++) - { - // Set up a descriptor for the current line in the surface and get pixels. - TPtr8 ptr(pSurfStart + start.iY * stride, stride); - bitmap->GetScanLine(ptr, start, size.iWidth, bmpFormat); - } - - CleanupStack::PopAndDestroy(/* chunk */); - CleanupStack::PopAndDestroy(bitmap); - CleanupStack::PopAndDestroy(decoder); - CleanupStack::PopAndDestroy(/* fs */); - } -/** -Get the size of a surface. - -@param aSurface The surface to get the size for. -@return The size in pixels, or empty on failure. -*/ -TSize CSurfaceUtility::SurfaceSize(const TSurfaceId& aSurface) - { - RSurfaceManager::TInfoBuf infoBuf; - RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); - - if (iManager.SurfaceInfo(aSurface, infoBuf) == KErrNone) - { - return info.iSize; - } - - return TSize(); - } - - -/** -Create a surface using the surface manager. - -Stores the ID for tear down, as well as returning it. - -@param aSize Dimensions of the surface. -@param aPixelFormat UID of the pixel format. -@param aStride Stride value for the surface (usually bytes per pixel * width) -@leave May leave due to lack of memory. -@return New surface's ID. -*/ -TSurfaceId CSurfaceUtility::CreateSurfaceL(const TSize& aSize, TUidPixelFormat aPixelFormat, TInt aStride, TInt aBuffers) - { - RSurfaceManager::TSurfaceCreationAttributesBuf bf; - RSurfaceManager::TSurfaceCreationAttributes& b = bf(); - - b.iSize.iWidth = aSize.iWidth; - b.iSize.iHeight = aSize.iHeight; - b.iBuffers = aBuffers; // number of buffers in the surface - b.iPixelFormat = aPixelFormat; - b.iStride = aStride; // Number of bytes between start of one line and start of next - b.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data - b.iAlignment = 4; // alignment, 1,2,4,8 byte aligned - b.iContiguous = EFalse; - b.iMappable = ETrue; - - TSurfaceId surface = TSurfaceId::CreateNullId(); - - User::LeaveIfError(iManager.CreateSurface(bf, surface)); - iSurfaces.AppendL(surface); - return surface; - } - -/** -A helper function that returns the bytes per pixel for a given pixel format uid - -@param aPixelFormat Pixel format UID to convert -@return The bytes per pixel -*/ -TInt CSurfaceUtility::BytesPerPixelL(TUidPixelFormat aPixelFormat) - { - TInt bytesPerPixel = 0; - switch (aPixelFormat) - { - case EUidPixelFormatXRGB_8888: - case EUidPixelFormatARGB_8888: - case EUidPixelFormatARGB_8888_PRE: - { - bytesPerPixel = 4; - break; - } - case EUidPixelFormatXRGB_4444: - case EUidPixelFormatARGB_4444: - case EUidPixelFormatRGB_565: - { - bytesPerPixel = 2; - break; - } - default: - { - User::Leave(KErrNotSupported); - break; - } - } - return bytesPerPixel; - } - -/** -Fill the given surface with a color. - -@param aSurface The surface to be filled. -@param aColor The color to fill it with. -*/ -void CSurfaceUtility::FillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor) - { - RSurfaceManager::TInfoBuf infoBuf; - RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); - - User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); - TUint32 color = 0; - TBool use16 = EFalse; - - if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0) - { - User::Leave(KErrCorrupt); - } - if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0) - { - User::Leave(KErrNotReady); - } - - switch (info.iPixelFormat) - { - case EUidPixelFormatXRGB_8888: - { - color = aColor.Color16MU(); -#ifdef ALPHA_FIX_24BIT - color |= ((ALPHA_FIX_24BIT)&0xff)<<24; -#endif - break; - } - case EUidPixelFormatARGB_8888: - { - color = aColor.Color16MA(); - break; - } - case EUidPixelFormatARGB_8888_PRE: - { - color = aColor.Color16MAP(); - break; - } - case EUidPixelFormatXRGB_4444: - case EUidPixelFormatARGB_4444: - { - color = aColor.Color4K(); - use16 = ETrue; - break; - } - case EUidPixelFormatRGB_565: - { - color = aColor.Color64K(); - use16 = ETrue; - break; - } - default: - { - User::Leave(KErrNotSupported); - break; - } - } - - RChunk chunk; - User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); - CleanupClosePushL(chunk); - - TInt offsetToFirstBuffer; - User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer)); - TUint8* surfacePtr = chunk.Base() + offsetToFirstBuffer; - TUint8* linePtr = surfacePtr; - - if (use16) - { - if ( info.iSize.iWidth*2>info.iStride) - { - User::Leave(KErrOverflow); - } - TUint16* ptr = reinterpret_cast(surfacePtr); - - // Fill first line - for (TInt xx = 0; xx < info.iSize.iWidth; xx++) - { - ptr[xx] = (TUint16)color; - } - } - else - { - if ( info.iSize.iWidth*4>info.iStride) - { - User::Leave(KErrOverflow); - } - TUint32* ptr = reinterpret_cast(surfacePtr); - - // Fill first line - for (TInt xx = 0; xx < info.iSize.iWidth; xx++) - { - ptr[xx] = color; - } - } - - // Now copy that to the other lines - for (TInt yy = 1; yy < info.iSize.iHeight; yy++) - { - linePtr += info.iStride; - Mem::Copy(linePtr, surfacePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat)); - } - - TInt err = iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL); - if (err!=KErrNone) - LOG(("Error submitting update: 0x%X\n", err)); - - CleanupStack::PopAndDestroy(/* chunk */); - } - -/** -Fill the given memory chunk with a color. - -@param aSurface The surface to be filled. -@param aChunk The surface to be filled. -@param aColor The color to fill it with. -*/ -void CSurfaceUtility::FillChunkL(TSurfaceId& aSurface, RChunk& aChunk, const TRgb& aColor, TInt aBufferNumber) - { - RSurfaceManager::TInfoBuf infoBuf; - RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); - - User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); - TUint32 color = 0; - TBool use16 = EFalse; - - if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0) - { - User::Leave(KErrCorrupt); - } - if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0) - { - User::Leave(KErrNotReady); - } - - switch (info.iPixelFormat) - { - case EUidPixelFormatXRGB_8888: - { - color = aColor.Color16MU(); -#ifdef ALPHA_FIX_24BIT - color |= ((ALPHA_FIX_24BIT)&0xff)<<24; -#endif - break; - } - case EUidPixelFormatARGB_8888: - { - color = aColor.Color16MA(); - break; - } - case EUidPixelFormatARGB_8888_PRE: - { - color = aColor.Color16MAP(); - break; - } - case EUidPixelFormatXRGB_4444: - case EUidPixelFormatARGB_4444: - { - color = aColor.Color4K(); - use16 = ETrue; - break; - } - case EUidPixelFormatRGB_565: - { - color = aColor.Color64K(); - use16 = ETrue; - break; - } - default: - { - User::Leave(KErrNotSupported); - break; - } - } - - User::LeaveIfError(iManager.MapSurface(aSurface, aChunk)); - - TInt offsetToFirstBuffer; - User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer)); - TInt offsetToBufferNumber; - User::LeaveIfError(iManager.GetBufferOffset(aSurface, aBufferNumber, offsetToBufferNumber)); - - TUint8* chunkPtr = aChunk.Base() + offsetToFirstBuffer; - TUint8* linePtr = aChunk.Base() + offsetToBufferNumber; - TUint8* surfPlanePtr = linePtr; - - if (use16) - { - if ( info.iSize.iWidth*2>info.iStride) - { - aChunk.Close(); - User::Leave(KErrOverflow); - } - TUint16* ptr = reinterpret_cast(surfPlanePtr); - - // Fill first line - for (TInt xx = 0; xx < info.iSize.iWidth; xx++) - { - ptr[xx] = (TUint16)color; - } - } - else - { - if ( info.iSize.iWidth*4>info.iStride) - { - aChunk.Close(); - User::Leave(KErrOverflow); - } - TUint32* ptr = reinterpret_cast(surfPlanePtr); - - // Fill first line - for (TInt xx = 0; xx < info.iSize.iWidth; xx++) - { - ptr[xx] = color; - } - } - - // Now copy that to the other lines - for (TInt yy = 1; yy < info.iSize.iHeight; yy++) - { - linePtr += info.iStride; - Mem::Copy(linePtr, surfPlanePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat)); - } - - aChunk.Close(); - } - -/** -Fill a rectangle on the given surface. - -@param aSurface The surface to be filled. -@param aStartPos Where to place the rectangle. -@param aSize Size of the rectangle. -@param aColor The colour to fill it with. -*/ -void CSurfaceUtility::FillRectangleL(TSurfaceId& aSurface, const TPoint& aStartPos, const TSize& aSize, const TRgb& aColor) - { - FillRectangleNoUpdateL(aSurface, aStartPos, aSize, aColor); - - TInt err = iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL); - if (err!=KErrNone) - LOG(("Error submitting update: 0x%X\n", err)); - } - -/** -Fill a rectangle on the given surface - does not submit update. - -@param aSurface The surface to be filled. -@param aStartPos Where to place the rectangle. -@param aSize Size of the rectangle. -@param aColor The colour to fill it with. -*/ -void CSurfaceUtility::FillRectangleNoUpdateL(TSurfaceId& aSurface, const TPoint& aStartPos, const TSize& aSize, const TRgb& aColor) - { - RSurfaceManager::TInfoBuf infoBuf; - RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); - - User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); - TUint32 color = 0; - TBool use16 = EFalse; - - if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0) - { - User::Leave(KErrCorrupt); - } - if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0) - { - User::Leave(KErrNotReady); - } - - switch (info.iPixelFormat) - { - case EUidPixelFormatXRGB_8888: - { - color = aColor.Color16MU(); -#ifdef ALPHA_FIX_24BIT - color |= ((ALPHA_FIX_24BIT)&0xff)<<24; -#endif - break; - } - case EUidPixelFormatARGB_8888: - { - color = aColor.Color16MA(); - break; - } - case EUidPixelFormatARGB_8888_PRE: - { - color = aColor.Color16MAP(); - break; - } - case EUidPixelFormatXRGB_4444: - case EUidPixelFormatARGB_4444: - { - color = aColor.Color4K(); - use16 = ETrue; - break; - } - case EUidPixelFormatRGB_565: - { - color = aColor.Color64K(); - use16 = ETrue; - break; - } - default: - { - User::Leave(KErrNotSupported); - break; - } - } - - RChunk chunk; - User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); - CleanupClosePushL(chunk); - - TInt offsetToFirstBuffer; - User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer)); - TUint8* surfacePtr = chunk.Base() + offsetToFirstBuffer; - - // Check for out of bounds - TBool validRect = ETrue; - TInt surfaceWidth = info.iSize.iWidth; - TInt surfaceHeight = info.iSize.iHeight; - - // Width and Height - if ((aStartPos.iX + aSize.iWidth) > surfaceWidth) - validRect = EFalse; - - if ((aStartPos.iY + aSize.iHeight) > surfaceHeight) - validRect = EFalse; - - // Starting position - if ((aStartPos.iX < 0) || (aStartPos.iY < 0)) - validRect = EFalse; - - if (!validRect) - User::Leave(KErrOverflow); - - if (use16) - { - if ( info.iSize.iWidth*2>info.iStride) - { - User::Leave(KErrOverflow); - } - - TUint16* ptr = reinterpret_cast(surfacePtr); - - // Fill the rectangle - TInt yPos = aStartPos.iY; - TInt xPos = aStartPos.iX; - for (TInt yy = 0; yy < aSize.iHeight; ++yy) - { - ptr = reinterpret_cast(surfacePtr+(yPos*info.iStride)); - for (TInt xx = 0; xx < aSize.iWidth; ++xx) - { - ptr[xPos] = color; - xPos++; - } - xPos = aStartPos.iX; - yPos++; - } - } - else - { - if ( info.iSize.iWidth*4>info.iStride) - { - User::Leave(KErrOverflow); - } - - TUint32* ptr = reinterpret_cast(surfacePtr); - - // Fill the rectangle - TInt yPos = aStartPos.iY; - TInt xPos = aStartPos.iX; - for (TInt yy = 0; yy < aSize.iHeight; ++yy) - { - ptr = reinterpret_cast(surfacePtr+(yPos*info.iStride)); - for (TInt xx = 0; xx < aSize.iWidth; ++xx) - { - ptr[xPos] = color; - xPos++; - } - xPos = aStartPos.iX; - yPos++; - } - } - - CleanupStack::PopAndDestroy(/* chunk */); - } - -/** -Fill the given surface with a grid over a solid color. - -Similar to FillSurfaceL(), but with a grid overlayed. The pitch of the grid is -eight pixels. - -@param aSurface The surface to be filled. -@param aColor The color to fill it with. -@param aLines The color of the grid lines. -*/ -void CSurfaceUtility::GridFillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor, const TRgb& aLines) - { - RSurfaceManager::TInfoBuf infoBuf; - RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); - - User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); - TUint32 color = 0; - TUint32 lines = 0; - TBool use16 = EFalse; - - if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0) - { - User::Leave(KErrCorrupt); - } - if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0) - { - User::Leave(KErrNotReady); - } - - switch (info.iPixelFormat) - { - case EUidPixelFormatXRGB_8888: - { - color = aColor.Color16MU(); - lines = aLines.Color16MU(); -#ifdef ALPHA_FIX_24BIT - color |= ((ALPHA_FIX_24BIT)&0xff)<<24; - lines |= ((ALPHA_FIX_24BIT)&0xff)<<24; -#endif - break; - } - case EUidPixelFormatARGB_8888: - { - color = aColor.Color16MA(); - lines = aLines.Color16MA(); - break; - } - case EUidPixelFormatARGB_8888_PRE: - { - color = aColor.Color16MAP(); - lines = aLines.Color16MAP(); - break; - } - case EUidPixelFormatXRGB_4444: - case EUidPixelFormatARGB_4444: - { - color = aColor.Color4K(); - lines = aLines.Color4K(); - use16 = ETrue; - break; - } - case EUidPixelFormatRGB_565: - { - color = aColor.Color64K(); - lines = aLines.Color64K(); - use16 = ETrue; - break; - } - default: - { - User::Leave(KErrNotSupported); - break; - } - } - - RChunk chunk; - User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); - CleanupClosePushL(chunk); - - TInt offsetToFirstBuffer; - User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer)); - TUint8* surfacePtr = chunk.Base() + offsetToFirstBuffer; - TUint8* linePtr = surfacePtr; - - if (use16) - { - if ( info.iSize.iWidth*2>info.iStride) - { - User::Leave(KErrOverflow); - } - TUint16* ptr = reinterpret_cast(surfacePtr); - - // Fill first line - for (TInt xx1 = 0; xx1 < info.iSize.iWidth; xx1++) - { - ptr[xx1] = (TUint16)lines; - } - - // Fill second line - ptr = reinterpret_cast(surfacePtr + info.iStride); - for (TInt xx2 = 0; xx2 < info.iSize.iWidth; xx2++) - { - // Vertical line every 8 pixels across - ptr[xx2] = (TUint16)((xx2 & 7) ? color : lines); - } - } - else - { - if ( info.iSize.iWidth*4>info.iStride) - { - User::Leave(KErrOverflow); - } - TUint32* ptr = reinterpret_cast(surfacePtr); - - // Fill first line - for (TInt xx3 = 0; xx3 < info.iSize.iWidth; xx3++) - { - ptr[xx3] = lines; - } - - // Fill second line - ptr = reinterpret_cast(surfacePtr + info.iStride); - for (TInt xx4 = 0; xx4 < info.iSize.iWidth; xx4++) - { - // Vertical line every 8 pixels across - ptr[xx4] = (xx4 & 7) ? color : lines; - } - } - linePtr += info.iStride; - - // Now copy that to the other lines - for (TInt yy = 2; yy < info.iSize.iHeight; yy++) - { - linePtr += info.iStride; - if (yy & 7) - { - // Copy second line - Mem::Copy(linePtr, surfacePtr + info.iStride, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat)); - } - else - { - // Copy first line - Mem::Copy(linePtr, surfacePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat)); - } - } - - TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL); - if (err!=KErrNone) - LOG(("Error submitting update: 0x%X\n", err)); - - CleanupStack::PopAndDestroy(/* chunk */); - } - - -/** -Fill the given surface with a pattern suitable for automated testing. - -@param aSurface The surface to be filled. -*/ -void CSurfaceUtility::PatternFillSurfaceL(TSurfaceId& aSurface) - { - RSurfaceManager::TInfoBuf infoBuf; - RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); - - User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); - - // Fill the background - FillSurfaceL(aSurface, TRgb(0x00000000)); - - TInt surfaceWidth = info.iSize.iWidth; - TInt surfaceHeight = info.iSize.iHeight; - - // Create the 4 rectangles in the corners - TPoint startPos(0,0); - TSize size(15,15); - TInt rectWidth = size.iWidth; - TInt rectHeight = size.iHeight; - // Top left - FillRectangleL(aSurface, startPos, size, TRgb(0x0000ff)); - - // Top right - startPos.iX = surfaceWidth - rectWidth; - startPos.iY = 0; - FillRectangleL(aSurface, startPos, size, TRgb(0x00ff00)); - - // Bottom left - startPos.iX = 0; - startPos.iY = surfaceHeight - rectHeight; - FillRectangleL(aSurface, startPos, size, TRgb(0x00ffff)); - - // Bottom right - startPos.iX = surfaceWidth - rectWidth; - startPos.iY = surfaceHeight - rectHeight; - FillRectangleL(aSurface, startPos, size, TRgb(0xffffff)); - - // Create the 4 side bars - startPos.iX = 0; - startPos.iY = 6; - size.iWidth = 5; - size.iHeight = surfaceHeight - 12; - // Left - FillRectangleL(aSurface, startPos, size, TRgb(0x808000)); - - startPos.iX = surfaceWidth - size.iWidth; - startPos.iY = 6; - // Right - FillRectangleL(aSurface, startPos, size, TRgb(0xff00ff)); - - startPos.iX = 6; - startPos.iY = surfaceHeight - size.iWidth; - size.iWidth = surfaceWidth - 12; - size.iHeight = 5; - // Top - FillRectangleL(aSurface, startPos, size, TRgb(0xaaaaaa)); - - startPos.iX = 6; - startPos.iY = 0; - // Bottom - FillRectangleL(aSurface, startPos, size, TRgb(0x000080)); - } - - -template void -DdaLine(TUint aX1, TUint aY1,TUint aX2,TUint aY2, TUint aPixPerScan, TIntType* aBuffer, TIntType aColor) - { - TInt dx=aX2-aX1; - TInt dy=aY2-aY1; - TInt adx=dx,sdx=1; - if (adx<0) - { adx=-adx; sdx=-1; } - TInt ady=dy,sdy=aPixPerScan; - if (ady<0) - { ady=-ady; sdy=-aPixPerScan; } - //This is simplistic integert DDA. - //The vertical cases are handled by this 1/2 accumulator: - // If adx is zero then we step in sdy indefinitely - // If ady is zero then we step in sdx indefinitely - TInt accum=adx/2; - - TIntType* bufferend=aBuffer+aX2+aY2*aPixPerScan; - aBuffer+=aX1+aY1*aPixPerScan; - *aBuffer=aColor; - while (aBuffer!=bufferend) - { - if (accum>0) - { - accum-=ady; - aBuffer+=sdx; - } - else - { - accum+=adx; - aBuffer+=sdy; - } - *aBuffer=aColor; - } - - - } -template void -FanFill(const TPoint& aInnerXY,TUint aPixPerScan, TIntType* aSurfacePtr, TIntType aLinesTL, - TIntType aLinesBR, TIntType aLinesTR, TIntType aLinesBL) - { - - DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*180/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR); - DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*372/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR); - DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*591/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR); - DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*859/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR); - - DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesTR); - DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesTR); - DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesTR); - DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesTR); - - DdaLine(0,aInnerXY.iY,aInnerXY.iX*180/1024,0,aPixPerScan,aSurfacePtr,aLinesBL); - DdaLine(0,aInnerXY.iY,aInnerXY.iX*372/1024,0,aPixPerScan,aSurfacePtr,aLinesBL); - DdaLine(0,aInnerXY.iY,aInnerXY.iX*591/1024,0,aPixPerScan,aSurfacePtr,aLinesBL); - DdaLine(0,aInnerXY.iY,aInnerXY.iX*859/1024,0,aPixPerScan,aSurfacePtr,aLinesBL); - - DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesBL); - DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesBL); - DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesBL); - DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesBL); - - DdaLine(0,0,aInnerXY.iX*180/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL); - DdaLine(0,0,aInnerXY.iX*372/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL); - DdaLine(0,0,aInnerXY.iX*591/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL); - DdaLine(0,0,aInnerXY.iX*859/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL); - - DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesTL); - DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesTL); - DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesTL); - DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesTL); - - DdaLine(0,aInnerXY.iY-aInnerXY.iY*180/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); - DdaLine(0,aInnerXY.iY-aInnerXY.iY*372/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); - DdaLine(0,aInnerXY.iY-aInnerXY.iY*591/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); - DdaLine(0,aInnerXY.iY-aInnerXY.iY*859/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); - - DdaLine(aInnerXY.iX-aInnerXY.iX*180/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); - DdaLine(aInnerXY.iX-aInnerXY.iX*372/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); - DdaLine(aInnerXY.iX-aInnerXY.iX*591/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); - DdaLine(aInnerXY.iX-aInnerXY.iX*859/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR); - - } -/** -Fill the given surface with a fan of lines over a solid color. - -Similar to FillSurfaceL(), but with a fan of lines overlayed. -One fan is drawn about the top-left, and second fan at bottom-right. -The fan contains 8 segments. - -@param aSurface The surface to be filled. -@param aColor The color to fill it with. -@param aLines The color of the grid lines. -*/ -void CSurfaceUtility::FanFillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor, const TRgb& aLinesTL, const TRgb& aLinesBR) - { - FillSurfaceL(aSurface,aColor); - RSurfaceManager::TInfoBuf infoBuf; - RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); - - User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); - TUint32 linesTL = 0; - TUint32 linesBR = 0; - TUint32 linesTR = 0; - TUint32 linesBL = 0; - TBool use16 = EFalse; - TRgb rgbLinesTR(0,0,0); - TRgb rgbLinesBL(255,255,255); - - switch (info.iPixelFormat) - { - case EUidPixelFormatXRGB_8888: - { - linesBR = aLinesBR.Color16MU(); - linesTL = aLinesTL.Color16MU(); - linesTR = rgbLinesTR.Color16MU(); - linesBL = rgbLinesBL.Color16MU(); -#ifdef ALPHA_FIX_24BIT - linesBR |= ((ALPHA_FIX_24BIT)&0xff)<<24; - linesTL |= ((ALPHA_FIX_24BIT)&0xff)<<24; - linesTR |= ((ALPHA_FIX_24BIT)&0xff)<<24; - linesBL |= ((ALPHA_FIX_24BIT)&0xff)<<24; -#endif - break; - } - case EUidPixelFormatARGB_8888: - { - linesBR = aLinesBR.Color16MA(); - linesTL = aLinesTL.Color16MA(); - linesTR = rgbLinesTR.Color16MA(); - linesBL = rgbLinesBL.Color16MA(); - break; - } - case EUidPixelFormatARGB_8888_PRE: - { - linesBR = aLinesBR.Color16MAP(); - linesTL = aLinesTL.Color16MAP(); - linesTR = rgbLinesTR.Color16MAP(); - linesBL = rgbLinesBL.Color16MAP(); - break; - } - case EUidPixelFormatXRGB_4444: - case EUidPixelFormatARGB_4444: - { - linesBR = aLinesBR.Color4K(); - linesTL = aLinesTL.Color4K(); - linesTR = rgbLinesTR.Color4K(); - linesBL = rgbLinesBL.Color4K(); - use16 = ETrue; - break; - } - case EUidPixelFormatRGB_565: - { - linesBR = aLinesBR.Color64K(); - linesTL = aLinesTL.Color64K(); - linesTR = rgbLinesTR.Color64K(); - linesBL = rgbLinesBL.Color64K(); - use16 = ETrue; - break; - } - default: - { - User::Leave(KErrNotSupported); - break; - } - } - if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0) - { - User::Leave(KErrCorrupt); - } - if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0) - { - User::Leave(KErrNotReady); - } - RChunk chunk; - User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); - CleanupClosePushL(chunk); - - TInt offsetToFirstBuffer; - User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer)); - TUint8* surfacePtr = chunk.Base() + offsetToFirstBuffer; - TPoint innerXY(info.iSize.iWidth-1,info.iSize.iHeight-1); - if (use16) - { - if ( info.iSize.iWidth*2>info.iStride) - { - User::Leave(KErrOverflow); - } - FanFill(innerXY,info.iStride/2,(TUint16*)surfacePtr,linesTL,linesBR,linesBL,linesTR); - } - else - { - if ( info.iSize.iWidth*4>info.iStride) - { - User::Leave(KErrOverflow); - } - FanFill(innerXY,info.iStride/4,(TUint*)surfacePtr,linesTL,linesBR,linesBL,linesTR); - } - - iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL); - - CleanupStack::PopAndDestroy(/* chunk */); - } -/** -Fill the given surface with vertical line at the given position - -Similar to FillSurfaceL(), but with a vertical line overlayed. -The position along the surface is given as a percentage from the left - -@param aSurface The surface to be filled. -@param aColor The color to fill it with. -@param aLine The color of the line. -@param aPosition Position of the vertical line given as a percentage across the surface from the left edge -*/ -void CSurfaceUtility::LineFillSurfaceL(TSurfaceId& aSurface, const TRgb& aBackColor, const TRgb& aLineColor, TInt aPosition) - { - if (aPosition<0 || aPosition>100) - { - aPosition=0; - } - FillSurfaceL(aSurface,aBackColor); - RSurfaceManager::TInfoBuf infoBuf; - RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); - - User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); - TUint32 lineColor = 0; - TBool use16 = EFalse; - - switch (info.iPixelFormat) - { - case EUidPixelFormatXRGB_8888: - { - lineColor = aLineColor.Color16MU(); -#ifdef ALPHA_FIX_24BIT - lineColor |= ((ALPHA_FIX_24BIT)&0xff)<<24; -#endif - break; - } - case EUidPixelFormatARGB_8888: - { - lineColor = aLineColor.Color16MA(); - break; - } - case EUidPixelFormatARGB_8888_PRE: - { - lineColor = aLineColor.Color16MAP(); - break; - } - case EUidPixelFormatXRGB_4444: - case EUidPixelFormatARGB_4444: - { - lineColor = aLineColor.Color4K(); - use16 = ETrue; - break; - } - case EUidPixelFormatRGB_565: - { - lineColor = aLineColor.Color64K(); - use16 = ETrue; - break; - } - default: - { - User::Leave(KErrNotSupported); - break; - } - } - RChunk chunk; - User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); - - TInt offsetToFirstBuffer; - User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer)); - TUint8* surfacePtr = chunk.Base() + offsetToFirstBuffer; - if (use16) - { - DdaLine((info.iSize.iWidth*aPosition)/100,0,(info.iSize.iWidth*aPosition)/100, - info.iSize.iHeight-1,info.iStride/2,(TUint16*)surfacePtr,lineColor); - } - else - { - DdaLine((info.iSize.iWidth*aPosition)/100,0,(info.iSize.iWidth*aPosition)/100, - info.iSize.iHeight-1,info.iStride/4,(TUint*)surfacePtr,lineColor); - } - - chunk.Close(); - - iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL); - } -/** - * Generates a bitmap equivalent to the surface. - * Can reuse an existing bitmap or create a new bitmap. - * The existing bitmap must be an exact match (eg previously generated by this method) - **/ -CFbsBitmap* CSurfaceUtility::EquivalentBitmapL(TSurfaceId& aSurface,CFbsBitmap* aCopyToMayBeNull) - { - RSurfaceManager::TInfoBuf infoBuf; - RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); - - User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf)); - TInt bytesPerPixel=0; - TDisplayMode bitmapMode = ENone; - switch (info.iPixelFormat) - { - case EUidPixelFormatXRGB_8888: - { - bitmapMode = EColor16MU; - bytesPerPixel = 4; - break; - } - case EUidPixelFormatARGB_8888: - { - bitmapMode=EColor16MA; - bytesPerPixel = 4; - break; - } - case EUidPixelFormatARGB_8888_PRE: - { - bitmapMode=EColor16MAP; - bytesPerPixel = 4; - break; - } - case EUidPixelFormatXRGB_4444: - case EUidPixelFormatARGB_4444: - { - bitmapMode=EColor4K; - bytesPerPixel = 2; - break; - } - case EUidPixelFormatRGB_565: - { - bitmapMode=EColor64K; - bytesPerPixel = 2; - break; - } - default: - { - User::Leave(KErrNotSupported); - break; - } - } - CFbsBitmap* retVal=NULL; - if (aCopyToMayBeNull) - { - retVal=aCopyToMayBeNull; - if (retVal->SizeInPixels()!=info.iSize) - User::Leave(KErrCorrupt); - if (retVal->DisplayMode()!=bitmapMode) - User::Leave(KErrCorrupt); - } - else - { - retVal=new CFbsBitmap; - CleanupStack::PushL(retVal); - User::LeaveIfError(retVal->Create(info.iSize,bitmapMode)); - } - RChunk chunk; - CleanupClosePushL(chunk); - User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); - TInt offsetToFirstBuffer; - User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer)); - TUint8* surfacePtr = chunk.Base() + offsetToFirstBuffer; - TUint8* bitmapPtr = (TUint8*)retVal->DataAddress(); - TInt copyBytes=info.iSize.iWidth*bytesPerPixel; - for (TInt y=0;yDataStride(); - } - CleanupStack::PopAndDestroy(&chunk); - if (!aCopyToMayBeNull) - CleanupStack::Pop(retVal); - return retVal; - } - -/** -Destroy a surface. - -As well as destroying the surface, it is removed from the set held for -destruction during tear down. - -@param aSurface The surface to be destroyed. -*/ -void CSurfaceUtility::DestroySurface(TSurfaceId& aSurface) - { - TInt index = iSurfaces.Find(aSurface); - - if (index != KErrNotFound) - { - iSurfaces.Remove(index); - } - - TInt err = iManager.CloseSurface(aSurface); - if (err!=KErrNone) - LOG(("Error closing surfaces: 0x%X\n", err)); - } - - -/** -Submit an update to a surface to the update server. - -@param aScreenNumber The screen to be updated where the surface is shown. -@param aSurface The surface which has been updated. -@param aRegion The area of the surface affected, or NULL for all of it.*/ -void CSurfaceUtility::SubmitUpdate(TInt /* aScreenNumber */, const TSurfaceId& aSurface, const TRegion* aRegion,TInt aBufferNumber) - { - TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, aBufferNumber, aRegion); - if (err!=KErrNone) - LOG(("Error submitting update: 0x%X\n", err)); - } - -/** -Map and submit an update to a surface to the update server. - -@param aChunk The chunk of memory to be mapped -@param aScreenNumber The screen to be updated where the surface is shown. -@param aSurface The surface which has been updated. -@param aRegion The area of the surface affected, or NULL for all of it.*/ -void CSurfaceUtility::MapAndSubmitUpdateL(RChunk& aChunk, - TInt /* aScreenNumber */, - const TSurfaceId& aSurface, - const TRegion* aRegion) - { - User::LeaveIfError(iManager.MapSurface(aSurface, aChunk)); - aChunk.Close(); - TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, aRegion); - if (err!=KErrNone) - LOG(("Error submitting update: 0x%X\n", err)); - } - -void CSurfaceUtility::MapSurfaceL(const TSurfaceId& aSurface, RChunk& aChunk) - { - User::LeaveIfError(iManager.MapSurface(aSurface, aChunk)); - } - -void CSurfaceUtility::CopyBitmapToSurfaceL(TSurfaceId& aSurface, const CFbsBitmap& aBitmap) - { - TSize size = SurfaceSize(aSurface); - - TDisplayMode bmpFormat = aBitmap.DisplayMode(); - TInt stride = size.iWidth * 4; // Default to four bytes per pixel - - RChunk chunk; - User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); - CleanupClosePushL(chunk); - - TInt offsetToFirstBuffer; - User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer)); - - // Copy the data from the bitmap into the surface. - TPoint start; - TUint8 *pSurfStart = chunk.Base() + offsetToFirstBuffer; - for (start.iY = 0; start.iY < size.iHeight; start.iY++) - { - // Set up a descriptor for the current line in the surface and get pixels. - TPtr8 ptr(pSurfStart + start.iY * stride, stride); - aBitmap.GetScanLine(ptr, start, size.iWidth, bmpFormat); - } - - TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL); - if (err!=KErrNone) - { - LOG(("Error submitting update: 0x%X\n", err)); - } - - CleanupStack::PopAndDestroy(/* chunk */); - }