diff -r 000000000000 -r 5d03bc08d59c graphicscomposition/surfaceupdate/tsrc/tsurfacehelper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicscomposition/surfaceupdate/tsrc/tsurfacehelper.cpp Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,229 @@ +// Copyright (c) 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 "tsurfacehelper.h" +#include + +CSurfaceHelper* CSurfaceHelper::NewL() + { + CSurfaceHelper* helper = new(ELeave)CSurfaceHelper; + CleanupStack::PushL(helper); + helper->ConstructL(); + CleanupStack::Pop(helper); + return helper; + } + +CSurfaceHelper::~CSurfaceHelper() + { + DestroySurfaces(); + iSurfaces.Close(); + iManager.Close(); + } + +/** + * Load logical device and open a surface manager + */ +void CSurfaceHelper::ConstructL() + { + TInt res = iManager.Open(); + if (res != KErrNone) + { + User::Leave(res); + } + } + +/** + * Create the surface with the given parameters. + * The surface will be owned by the instance of this class + */ +TSurfaceId CSurfaceHelper::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; + } + +/** + * Destroy all surfaces wich have been created by the instance of this class + */ +void CSurfaceHelper::DestroySurfaces() + { + TInt numSurfaces = iSurfaces.Count(); + for (TInt index = 0; index < numSurfaces; index++) + { + TSurfaceId surfaceId = iSurfaces[index]; + TInt err = iManager.CloseSurface(surfaceId); + __ASSERT_DEBUG(err ==KErrNone, User::Panic(_L("CSurfaceHelper::DestroySurfaces"), err)); + } + iSurfaces.Reset(); + } + +/** +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 CSurfaceHelper::FillRectangleL(const 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; + + 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 EUidPixelFormatRGB_565: + { + color = aColor.Color64K(); + break; + } + default: + { + User::Leave(KErrNotSupported); + break; + } + } + + RChunk chunk; + User::LeaveIfError(iManager.MapSurface(aSurface, chunk)); + CleanupClosePushL(chunk); + TUint8* surfacePtr = chunk.Base(); + + // 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 (info.iPixelFormat == EUidPixelFormatRGB_565) + {//2 bytes per pixel + if ( info.iSize.iWidth*2>info.iStride) + { + User::Leave(KErrOverflow); + } + + TInt offset; + User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offset)); + TUint16* ptr = reinterpret_cast(surfacePtr + offset); + + // 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); + } + + TInt offset; + User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offset)); + TUint32* ptr = reinterpret_cast(surfacePtr + offset); + + // 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); + }