diff -r 57c618273d5c -r bbf46f59e123 graphicscomposition/openwfcompositionengine/test/tscreeninterface/streamutility.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicscomposition/openwfcompositionengine/test/tscreeninterface/streamutility.cpp Tue Aug 31 16:31:06 2010 +0300 @@ -0,0 +1,446 @@ +// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and/or associated documentation files (the +// "Materials"), to deal in the Materials without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Materials, and to +// permit persons to whom the Materials are furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Materials. +// +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +// +// Description: +// + +/** + @file +*/ + +#include +#include +#include +#include "streamutility.h" + +#define WFC_INVALID_HANDLE NULL + +CStreamUtility::CStreamUtility() + { + } + +CStreamUtility* CStreamUtility::NewL() + { + CStreamUtility* utility = new (ELeave)CStreamUtility(); + CleanupStack::PushL(utility); + utility->ConstructL(); + CleanupStack::Pop(utility); + return utility; + } + +void CStreamUtility::ConstructL() + { + TInt r = iManager.Open(); + if (r != KErrNone) + { + LOG(("Surface manager failed to open: %d", r)); + User::Leave(r); + } + } + +CStreamUtility::~CStreamUtility() + { + DestroyAll(); + + iStreams.Close(); + + iManager.Close(); + } + +TBool CStreamUtility::DestroyAll() + { + TInt err = KErrNone; + TInt jj = iStreams.Count() - 1; + if (jj<0) + return EFalse; + for (; jj >= 0; jj--) + { + //The following lines are just to get the surface ID for verification + SymbianStreamBuffer bufferHandle; + User::LeaveIfError(SymbianStreamAcquireReadBuffer(iStreams[jj], &bufferHandle)); + long bufferIndex; + const TSurfaceId* pSurfaceId = NULL; + + User::LeaveIfError(SymbianStreamGetBufferId(iStreams[jj],bufferHandle,&bufferIndex,&pSurfaceId)); + User::LeaveIfError(SymbianStreamReleaseReadBuffer(iStreams[jj], bufferHandle)); + + const TSurfaceId surfaceId = *pSurfaceId; //Need to copy my reference to the ID. + //Actually release the stream + SymbianStreamRemoveReference(iStreams[jj]); + + //Verify the stream is now not accessible + TInt offset; + err = iManager.GetBufferOffset(surfaceId,0,offset); + if (err==KErrNone) + { + LOG(("Closing stream via DestoryAll did not destroy surface!")); + } + } + iStreams.Reset(); + return ETrue; + } + +/*************************************** + * The aim of the RHeapStreamArray is to locally switch in the specified heap for any array operation + ***************************************/ + +CStreamUtility::RHeapStreamArray::RHeapStreamArray(RHeapStreamArray* aUseExternalArray) + : iUseArray(aUseExternalArray?aUseExternalArray->iUseArray:&this->iLocalArray), + iExternalHeapRef(aUseExternalArray?aUseExternalArray->iExternalHeapRef:User::Heap()) + { + + } +/************************************ + * The following methods have been used by the streamutility... some require the heap wrapping, and some don't + * I actually need three different strategies (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 CStreamUtility::RHeapStreamArray::PopHeap(void* aHeapPtr) + { + RHeap* heapPtr=(RHeap*)aHeapPtr; + User::SwitchHeap(heapPtr); + } + +SymbianStreamType& CStreamUtility::RHeapStreamArray::operator[](TUint aIndex) + { + return iUseArray->operator[](aIndex); + } + +/// Close only closes the local array, while Reset resets the active array (may be external) +void CStreamUtility::RHeapStreamArray::Close() + { + iLocalArray.Close(); + } + +TInt CStreamUtility::RHeapStreamArray::Count() const + { + return iUseArray->Count(); + } + +/// Close only closes the local array, while Reset resets the active array (may be external) +inline void CStreamUtility::RHeapStreamArray::Reset() + { + iUseArray->Reset(); + } + +void CStreamUtility::RHeapStreamArray::AppendL(const SymbianStreamType &anEntry) + { + iUseArray->AppendL(anEntry); + } + +TInt CStreamUtility::RHeapStreamArray::Find(const SymbianStreamType &anEntry) const + { + return iUseArray->Find(anEntry); + } + +void CStreamUtility::RHeapStreamArray::Remove(TInt anIndex) + { + iUseArray->Remove(anIndex); + } + +/** +Cleanup stack helper object, holding references to both utility and stream, so +that the standard Close() semantics can be used. +*/ +class TStreamCleanup + { +public: + TStreamCleanup(CStreamUtility& aUtility, SymbianStreamType& aStream) + : iUtility(aUtility), iStream(aStream) + {} + void Close() + { + // Removes the stream from the list of streams to clean up, and closes + // the stream reference. + iUtility.DestroyStream(iStream); + } +private: + CStreamUtility& iUtility; + SymbianStreamType& iStream; + }; + +/** +Get the size of a stream. + +@param aStream The stream to get the size for. +@return The size in pixels, or empty on failure. +*/ +TSize CStreamUtility::StreamSize(const SymbianStreamType aStream) + { + khronos_int32_t width; + khronos_int32_t height; + khronos_int32_t stride; + khronos_int32_t format; + khronos_int32_t pixelSize; + + SymbianStreamGetHeader(aStream, &width, &height, &stride, &format, &pixelSize); + + TSize size = TSize(static_cast(width), static_cast(height)); + + return size; + } + +/** +Create a stream using the surface manager. + +Stores the ID for tear down, as well as returning it. + +@param aSize Dimensions of the stream. +@param aPixelFormat UID of the pixel format. +@param aStride Stride value for the stream (usually bytes per pixel * width) +@param aReturnSurface Returns TSurfaceId wrapped by the stream +@param aContiguous Contiguous flag for creating surfaces +@param aBuffers Number of buffers +@leave May leave due to lack of memory. +@return New stream's ID. +*/ +SymbianStreamType CStreamUtility::CreateStreamL(const TSize& aSize, TUidPixelFormat aPixelFormat, + TInt aStride, TSurfaceId& aReturnSurface, + TBool aContiguous, TInt aBuffers) + { + RSurfaceManager::TSurfaceCreationAttributesBuf bf; + RSurfaceManager::TSurfaceCreationAttributes& b = bf(); + if (aStridestride) + { + User::Leave(KErrOverflow); + } + TUint16* ptr = reinterpret_cast(streamPtr); + + // Fill first line + for (TInt xx = 0; xx < width; xx++) + { + ptr[xx] = (TUint16)color; + } + } + else + { + if ( width*4>stride) + { + User::Leave(KErrOverflow); + } + TUint32* ptr = reinterpret_cast(streamPtr); + + // Fill first line + for (TInt xx = 0; xx < width; xx++) + { + ptr[xx] = color; + } + } + + // Now copy that to the other lines + for (TInt yy = 1; yy < height; yy++) + { + linePtr += stride; + Mem::Copy(linePtr, streamPtr, width * BytesPerPixelL(aStream)); + } + User::LeaveIfError(SymbianStreamReleaseWriteBuffer(aStream, bufferHandle)); + CleanupStack::PopAndDestroy(/* chunk */); + } + +/** +Destroy a stream. + +As well as destroying the stream, it is removed from the set held for +destruction during tear down. + +@param aStream The stream to be destroyed. +*/ +void CStreamUtility::DestroyStream(SymbianStreamType aStream) + { + TInt index = iStreams.Find(aStream); + + if (index != KErrNotFound) + { + iStreams.Remove(index); + } + + SymbianStreamRemoveReference(aStream); + } + +/** +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 CStreamUtility::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; + } + +/** +A helper function that returns the bytes per pixel for a given stream + +@param aStream The stream which is checked +@return The bytes per pixel +*/ +TInt CStreamUtility::BytesPerPixelL(const SymbianStreamType aStream) + { + khronos_int32_t width; + khronos_int32_t height; + khronos_int32_t stride; + khronos_int32_t format; + khronos_int32_t pixelSize; + + SymbianStreamGetHeader(aStream, &width, &height, &stride, &format, &pixelSize); + + return static_cast(pixelSize); + } +