os/graphics/graphicscomposition/openwfsupport/test/tstreamoperation/surfaceutility.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicscomposition/openwfsupport/test/tstreamoperation/surfaceutility.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,821 @@
1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +/**
1.20 + @file
1.21 +*/
1.22 +
1.23 +#include <e32std.h>
1.24 +#include <imageconversion.h>
1.25 +#include "surfaceutility.h"
1.26 +
1.27 +CSurfaceUtility::CSurfaceUtility(CSurfaceUtility* aClone)
1.28 + : iSurfaces(aClone?&(aClone->iSurfaces):NULL)
1.29 + {
1.30 + }
1.31 +
1.32 +CSurfaceUtility* CSurfaceUtility::NewL(CSurfaceUtility* aClone/*=NULL*/)
1.33 + {
1.34 + CSurfaceUtility* utility = new (ELeave)CSurfaceUtility(aClone);
1.35 + CleanupStack::PushL(utility);
1.36 + utility->ConstructL();
1.37 + CleanupStack::Pop(utility);
1.38 + return utility;
1.39 + }
1.40 +
1.41 +void CSurfaceUtility::ConstructL()
1.42 + {
1.43 + TInt r = iManager.Open();
1.44 + if (r != KErrNone)
1.45 + {
1.46 + LOG(("Surface manager failed to open: %d", r));
1.47 + User::Leave(r);
1.48 + }
1.49 +
1.50 + r = iSurfaceUpdateSession.Connect();
1.51 + if (r != KErrNone)
1.52 + {
1.53 + LOG(("Failed to connect to update server: %d", r));
1.54 + User::Leave(r);
1.55 + }
1.56 + }
1.57 +
1.58 +CSurfaceUtility::~CSurfaceUtility()
1.59 + {
1.60 + DestroyAll();
1.61 +
1.62 + iSurfaces.Close();
1.63 +
1.64 + iManager.Close();
1.65 +
1.66 + iSurfaceUpdateSession.Close();
1.67 + }
1.68 +
1.69 +TBool CSurfaceUtility::DestroyAll()
1.70 + {
1.71 + TInt err = KErrNone;
1.72 + TInt jj = iSurfaces.Count() - 1;
1.73 + if (jj<0)
1.74 + return EFalse;
1.75 + for (; jj >= 0; jj--)
1.76 + {
1.77 + err = iManager.CloseSurface(iSurfaces[jj]);
1.78 + if (err!=KErrNone)
1.79 + {
1.80 + LOG(("Error closing surface: 0x%X\n", err));
1.81 + }
1.82 + }
1.83 + iSurfaces.Reset();
1.84 + return ETrue;
1.85 + }
1.86 +
1.87 +/***************************************
1.88 + * The aim of the THeapSurfaceArray is to locally switch in the specified heap for any array operation
1.89 + ***************************************/
1.90 +
1.91 +CSurfaceUtility::RHeapSurfaceArray::RHeapSurfaceArray(RHeapSurfaceArray* aUseExternalArray)
1.92 + : iUseArray(aUseExternalArray?aUseExternalArray->iUseArray:&this->iLocalArray),
1.93 + iExternalHeapRef(aUseExternalArray?aUseExternalArray->iExternalHeapRef:User::Heap())
1.94 + {
1.95 +
1.96 + }
1.97 +/************************************
1.98 + * The following methods have been used by the surfaceutility... some require the heap wrapping, and some don't
1.99 + * I actually need three different startegies (count em) for 7 methods...
1.100 + * Some methods only read the existing objects, so don't need a heap swap at all
1.101 + * Leaving methods have to use PopAndDestroy strategy to restore the heap on leaving or success
1.102 + * Non-leaving methods must not call PushL, so directly make SwitchHeap calls!
1.103 + ************************************/
1.104 +
1.105 +// PopAndDestroy method to restore the heap
1.106 +/*static*/ void CSurfaceUtility::RHeapSurfaceArray::PopHeap(void* aHeapPtr)
1.107 + {
1.108 + RHeap* heapPtr=(RHeap*)aHeapPtr;
1.109 + User::SwitchHeap(heapPtr);
1.110 + }
1.111 +
1.112 +// Switches and pushes the previous heap so it can be restored with PopAndDestroy
1.113 +/*static*/ void CSurfaceUtility::RHeapSurfaceArray::SwitchHeapLC(RHeap* aNewHeap)
1.114 + {
1.115 + CleanupStack::PushL(TCleanupItem(PopHeap,NULL));
1.116 + CleanupStack::PushL(TCleanupItem(PopHeap,NULL));
1.117 + CleanupStack::PushL(TCleanupItem(PopHeap,NULL));
1.118 + CleanupStack::Pop(3);
1.119 + RHeap* oldHeap=User::SwitchHeap(aNewHeap);
1.120 + delete new char;
1.121 + CleanupStack::PushL(TCleanupItem(PopHeap,oldHeap));
1.122 + }
1.123 +
1.124 +
1.125 +TSurfaceId& CSurfaceUtility::RHeapSurfaceArray::operator[](TUint aIndex)
1.126 + {
1.127 + return iUseArray->operator[](aIndex);
1.128 + }
1.129 +
1.130 +// Close only closes the local array, while Reset resets the active array (may be external)
1.131 +void CSurfaceUtility::RHeapSurfaceArray::Close()
1.132 + {
1.133 + iLocalArray.Close();
1.134 + }
1.135 +
1.136 +TInt CSurfaceUtility::RHeapSurfaceArray::Count() const
1.137 + {
1.138 + return iUseArray->Count();
1.139 + }
1.140 +
1.141 +// Close only closes the local array, while Reset resets the active array (may be external)
1.142 +inline void CSurfaceUtility::RHeapSurfaceArray::Reset()
1.143 + {
1.144 + iUseArray->Reset();
1.145 + }
1.146 +
1.147 +void CSurfaceUtility::RHeapSurfaceArray::AppendL(const TSurfaceId &anEntry)
1.148 + {
1.149 + iUseArray->AppendL(anEntry);
1.150 + }
1.151 +
1.152 +TInt CSurfaceUtility::RHeapSurfaceArray::Find(const TSurfaceId &anEntry) const
1.153 + {
1.154 + return iUseArray->Find(anEntry);
1.155 + }
1.156 +
1.157 +void CSurfaceUtility::RHeapSurfaceArray::Remove(TInt anIndex)
1.158 + {
1.159 + iUseArray->Remove(anIndex);
1.160 + }
1.161 +
1.162 +/**
1.163 +Cleanup stack helper object, holding references to both utility and surface, so
1.164 +that the standard Close() semantics can be used.
1.165 +*/
1.166 +class TSurfaceCleanup
1.167 + {
1.168 +public:
1.169 + TSurfaceCleanup(CSurfaceUtility& aUtility, TSurfaceId& aSurface)
1.170 + : iUtility(aUtility), iSurface(aSurface)
1.171 + {}
1.172 + void Close()
1.173 + {
1.174 + // Removes the surface from the list of surfaces to clean up, and closes
1.175 + // the surface reference.
1.176 + iUtility.DestroySurface(iSurface);
1.177 + }
1.178 +private:
1.179 + CSurfaceUtility& iUtility;
1.180 + TSurfaceId& iSurface;
1.181 + };
1.182 +
1.183 +/**
1.184 +Get the size of a surface.
1.185 +
1.186 +@param aSurface The surface to get the size for.
1.187 +@return The size in pixels, or empty on failure.
1.188 +*/
1.189 +TSize CSurfaceUtility::SurfaceSize(const TSurfaceId& aSurface)
1.190 + {
1.191 + RSurfaceManager::TInfoBuf infoBuf;
1.192 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.193 +
1.194 + if (iManager.SurfaceInfo(aSurface, infoBuf) == KErrNone)
1.195 + {
1.196 + return info.iSize;
1.197 + }
1.198 +
1.199 + return TSize();
1.200 + }
1.201 +
1.202 +/**
1.203 +Create a surface using the surface manager.
1.204 +
1.205 +Stores the ID for tear down, as well as returning it.
1.206 +
1.207 +@param aSize Dimensions of the surface.
1.208 +@param aPixelFormat UID of the pixel format.
1.209 +@param aStride Stride value for the surface (usually bytes per pixel * width)
1.210 +@leave May leave due to lack of memory.
1.211 +@return New surface's ID.
1.212 +*/
1.213 +TSurfaceId CSurfaceUtility::CreateSurfaceL(const TSize& aSize, TUidPixelFormat aPixelFormat, TInt aStride, TInt aBuffers)
1.214 + {
1.215 + RSurfaceManager::TSurfaceCreationAttributesBuf bf;
1.216 + RSurfaceManager::TSurfaceCreationAttributes& b = bf();
1.217 + if (aStride<aSize.iWidth*BytesPerPixelL(aPixelFormat))
1.218 + {
1.219 + User::Leave(KErrOverflow);
1.220 + }
1.221 + b.iSize.iWidth = aSize.iWidth;
1.222 + b.iSize.iHeight = aSize.iHeight;
1.223 + b.iBuffers = aBuffers; // number of buffers in the surface
1.224 + b.iPixelFormat = aPixelFormat;
1.225 + b.iStride = aStride; // Number of bytes between start of one line and start of next
1.226 + b.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data
1.227 + b.iAlignment = 4; // alignment, 1,2,4,8 byte aligned
1.228 + b.iContiguous = EFalse;
1.229 + b.iMappable = ETrue;
1.230 +
1.231 + TSurfaceId surface = TSurfaceId::CreateNullId();
1.232 +
1.233 + User::LeaveIfError(iManager.CreateSurface(bf, surface));
1.234 + iSurfaces.AppendL(surface);
1.235 + return surface;
1.236 + }
1.237 +
1.238 +/**
1.239 +A helper function that returns the bytes per pixel for a given pixel format uid
1.240 +
1.241 +@param aPixelFormat Pixel format UID to convert
1.242 +@return The bytes per pixel
1.243 +*/
1.244 +TInt CSurfaceUtility::BytesPerPixelL(TUidPixelFormat aPixelFormat)
1.245 + {
1.246 + TInt bytesPerPixel = 0;
1.247 + switch (aPixelFormat)
1.248 + {
1.249 + case EUidPixelFormatXRGB_8888:
1.250 + case EUidPixelFormatARGB_8888:
1.251 + case EUidPixelFormatARGB_8888_PRE:
1.252 + {
1.253 + bytesPerPixel = 4;
1.254 + break;
1.255 + }
1.256 + case EUidPixelFormatXRGB_4444:
1.257 + case EUidPixelFormatARGB_4444:
1.258 + case EUidPixelFormatRGB_565:
1.259 + {
1.260 + bytesPerPixel = 2;
1.261 + break;
1.262 + }
1.263 + default:
1.264 + {
1.265 + User::Leave(KErrNotSupported);
1.266 + break;
1.267 + }
1.268 + }
1.269 + return bytesPerPixel;
1.270 + }
1.271 +
1.272 +/**
1.273 +Fill the given surface with a color.
1.274 +
1.275 +@param aSurface The surface to be filled.
1.276 +@param aColor The color to fill it with.
1.277 +*/
1.278 +void CSurfaceUtility::FillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor)
1.279 + {
1.280 + RSurfaceManager::TInfoBuf infoBuf;
1.281 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.282 +
1.283 + User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1.284 + TUint32 color = 0;
1.285 + TBool use16 = EFalse;
1.286 +
1.287 + if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
1.288 + {
1.289 + User::Leave(KErrCorrupt);
1.290 + }
1.291 + if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
1.292 + {
1.293 + User::Leave(KErrNotReady);
1.294 + }
1.295 +
1.296 + switch (info.iPixelFormat)
1.297 + {
1.298 + case EUidPixelFormatXRGB_8888:
1.299 + {
1.300 + color = aColor.Color16MU();
1.301 +#ifdef ALPHA_FIX_24BIT
1.302 + color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1.303 +#endif
1.304 + break;
1.305 + }
1.306 + case EUidPixelFormatARGB_8888:
1.307 + {
1.308 + color = aColor.Color16MA();
1.309 + break;
1.310 + }
1.311 + case EUidPixelFormatARGB_8888_PRE:
1.312 + {
1.313 + color = aColor.Color16MAP();
1.314 + break;
1.315 + }
1.316 + case EUidPixelFormatXRGB_4444:
1.317 + case EUidPixelFormatARGB_4444:
1.318 + {
1.319 + color = aColor.Color4K();
1.320 + use16 = ETrue;
1.321 + break;
1.322 + }
1.323 + case EUidPixelFormatRGB_565:
1.324 + {
1.325 + color = aColor.Color64K();
1.326 + use16 = ETrue;
1.327 + break;
1.328 + }
1.329 + default:
1.330 + {
1.331 + User::Leave(KErrNotSupported);
1.332 + break;
1.333 + }
1.334 + }
1.335 +
1.336 + RChunk chunk;
1.337 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.338 + CleanupClosePushL(chunk);
1.339 +
1.340 + TInt offsetToFirstBuffer;
1.341 + User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
1.342 + TUint8* surfacePtr = chunk.Base() + offsetToFirstBuffer;
1.343 + TUint8* linePtr = surfacePtr;
1.344 +
1.345 + if (use16)
1.346 + {
1.347 + if ( info.iSize.iWidth*2>info.iStride)
1.348 + {
1.349 + User::Leave(KErrOverflow);
1.350 + }
1.351 + TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
1.352 +
1.353 + // Fill first line
1.354 + for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
1.355 + {
1.356 + ptr[xx] = (TUint16)color;
1.357 + }
1.358 + }
1.359 + else
1.360 + {
1.361 + if ( info.iSize.iWidth*4>info.iStride)
1.362 + {
1.363 + User::Leave(KErrOverflow);
1.364 + }
1.365 + TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
1.366 +
1.367 + // Fill first line
1.368 + for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
1.369 + {
1.370 + ptr[xx] = color;
1.371 + }
1.372 + }
1.373 +
1.374 + // Now copy that to the other lines
1.375 + for (TInt yy = 1; yy < info.iSize.iHeight; yy++)
1.376 + {
1.377 + linePtr += info.iStride;
1.378 + Mem::Copy(linePtr, surfacePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat));
1.379 + }
1.380 +
1.381 + TInt err = SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1.382 + if (err!=KErrNone)
1.383 + LOG(("Error submitting update: 0x%X\n", err));
1.384 +
1.385 + CleanupStack::PopAndDestroy(/* chunk */);
1.386 + }
1.387 +
1.388 +/**
1.389 +Fill the given surface with a color.
1.390 +
1.391 +@param aSurface The surface to be filled.
1.392 +@param aBuffer The buffer to fill.
1.393 +@param aColor The color to fill it with.
1.394 +*/
1.395 +void CSurfaceUtility::FillSurfaceL(TSurfaceId& aSurface, TInt aBuffer, const TRgb& aColor)
1.396 + {
1.397 + RSurfaceManager::TInfoBuf infoBuf;
1.398 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.399 +
1.400 + User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1.401 + TUint32 color = 0;
1.402 + TBool use16 = EFalse;
1.403 + TInt numBuffers = info.iBuffers;
1.404 + if (aBuffer < 0 || aBuffer >= numBuffers)
1.405 + {
1.406 + User::Leave(KErrArgument);
1.407 + }
1.408 +
1.409 + if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
1.410 + {
1.411 + User::Leave(KErrCorrupt);
1.412 + }
1.413 + if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
1.414 + {
1.415 + User::Leave(KErrNotReady);
1.416 + }
1.417 +
1.418 + switch (info.iPixelFormat)
1.419 + {
1.420 + case EUidPixelFormatXRGB_8888:
1.421 + {
1.422 + color = aColor.Color16MU();
1.423 +#ifdef ALPHA_FIX_24BIT
1.424 + color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1.425 +#endif
1.426 + break;
1.427 + }
1.428 + case EUidPixelFormatARGB_8888:
1.429 + {
1.430 + color = aColor.Color16MA();
1.431 + break;
1.432 + }
1.433 + case EUidPixelFormatARGB_8888_PRE:
1.434 + {
1.435 + color = aColor.Color16MAP();
1.436 + break;
1.437 + }
1.438 + case EUidPixelFormatXRGB_4444:
1.439 + case EUidPixelFormatARGB_4444:
1.440 + {
1.441 + color = aColor.Color4K();
1.442 + use16 = ETrue;
1.443 + break;
1.444 + }
1.445 + case EUidPixelFormatRGB_565:
1.446 + {
1.447 + color = aColor.Color64K();
1.448 + use16 = ETrue;
1.449 + break;
1.450 + }
1.451 + default:
1.452 + {
1.453 + User::Leave(KErrNotSupported);
1.454 + break;
1.455 + }
1.456 + }
1.457 +
1.458 + RChunk chunk;
1.459 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.460 + CleanupClosePushL(chunk);
1.461 +
1.462 + TInt offsetToBuffer;
1.463 + User::LeaveIfError(iManager.GetBufferOffset(aSurface, aBuffer, offsetToBuffer));
1.464 + TUint8* surfacePtr = chunk.Base() + offsetToBuffer;
1.465 + TUint8* linePtr = surfacePtr;
1.466 +
1.467 + if (use16)
1.468 + {
1.469 + if ( info.iSize.iWidth*2>info.iStride)
1.470 + {
1.471 + User::Leave(KErrOverflow);
1.472 + }
1.473 + TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
1.474 +
1.475 + // Fill first line
1.476 + for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
1.477 + {
1.478 + ptr[xx] = (TUint16)color;
1.479 + }
1.480 + }
1.481 + else
1.482 + {
1.483 + if ( info.iSize.iWidth*4>info.iStride)
1.484 + {
1.485 + User::Leave(KErrOverflow);
1.486 + }
1.487 + TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
1.488 +
1.489 + // Fill first line
1.490 + for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
1.491 + {
1.492 + ptr[xx] = color;
1.493 + }
1.494 + }
1.495 +
1.496 + // Now copy that to the other lines
1.497 + for (TInt yy = 1; yy < info.iSize.iHeight; yy++)
1.498 + {
1.499 + linePtr += info.iStride;
1.500 + Mem::Copy(linePtr, surfacePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat));
1.501 + }
1.502 +
1.503 + TInt err = SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1.504 + if (err!=KErrNone)
1.505 + LOG(("Error submitting update: 0x%X\n", err));
1.506 +
1.507 + CleanupStack::PopAndDestroy(/* chunk */);
1.508 + }
1.509 +
1.510 +
1.511 +/**
1.512 +Destroy a surface.
1.513 +
1.514 +As well as destroying the surface, it is removed from the set held for
1.515 +destruction during tear down.
1.516 +
1.517 +@param aSurface The surface to be destroyed.
1.518 +*/
1.519 +void CSurfaceUtility::DestroySurface(TSurfaceId& aSurface)
1.520 + {
1.521 + TInt index = iSurfaces.Find(aSurface);
1.522 +
1.523 + if (index != KErrNotFound)
1.524 + {
1.525 + iSurfaces.Remove(index);
1.526 + }
1.527 +
1.528 + TInt err = iManager.CloseSurface(aSurface);
1.529 + if (err!=KErrNone)
1.530 + LOG(("Error closing surfaces: 0x%X\n", err));
1.531 + }
1.532 +
1.533 +
1.534 +/**
1.535 +Submit an update to a surface to the update server.
1.536 +
1.537 +@param aScreenNumber The screen to be updated where the surface is shown.
1.538 +@param aSurface The surface which has been updated.
1.539 +@param aRegion The area of the surface affected, or NULL for all of it.
1.540 +*/
1.541 +TInt CSurfaceUtility::SubmitUpdate(TInt /* aScreenNumber */, const TSurfaceId& aSurface,TInt aBufferNumber, TInt aNullRegion)
1.542 + {
1.543 + if (aNullRegion==0)
1.544 + {
1.545 + return SubmitUpdate(KAllScreens, aSurface, aBufferNumber);
1.546 + }
1.547 + else
1.548 + if (aBufferNumber==0)
1.549 + {
1.550 + return SubmitUpdate(KAllScreens, aSurface, aNullRegion);
1.551 + }
1.552 + else
1.553 + {
1.554 + return KErrNotSupported;
1.555 + }
1.556 + }
1.557 +
1.558 +TInt CSurfaceUtility::SubmitUpdate(TInt /* aScreenNumber */, const TSurfaceId& aSurface, const TRegion* aRegion,TInt aBufferNumber)
1.559 + {
1.560 + return SubmitUpdate(KAllScreens, aSurface, aBufferNumber, aRegion);
1.561 + }
1.562 +
1.563 +TInt CSurfaceUtility::SubmitUpdate(TInt /* aScreenNumber */, const TSurfaceId& aSurface,TInt aBufferNumber, const TRegion* aRegion)
1.564 + {
1.565 + if (!iSurfaceUpdateSession.Handle())
1.566 + {
1.567 + iSurfaceUpdateSession.Connect();
1.568 + }
1.569 + if (!iSurfaceUpdateSession.Handle())
1.570 + {
1.571 + LOG(("Error - SUS client not started!"));
1.572 + return KErrNotReady;
1.573 + }
1.574 + else
1.575 + {
1.576 + TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, aBufferNumber, aRegion);
1.577 + if (err!=KErrNone)
1.578 + LOG(("Error submitting update: 0x%X\n", err));
1.579 + return err;
1.580 + }
1.581 + }
1.582 +
1.583 +void CSurfaceUtility::FillNativeStreamSurfaceL(TSurfaceId& aSurface, TUint8* aBufferPtr, const TRgb& aColor)
1.584 + {
1.585 + RSurfaceManager::TInfoBuf infoBuf;
1.586 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.587 +
1.588 + User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1.589 + TUint32 color = 0;
1.590 + TBool use16 = EFalse;
1.591 +
1.592 + if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
1.593 + {
1.594 + User::Leave(KErrCorrupt);
1.595 + }
1.596 + if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
1.597 + {
1.598 + User::Leave(KErrNotReady);
1.599 + }
1.600 +
1.601 + switch (info.iPixelFormat)
1.602 + {
1.603 + case EUidPixelFormatXRGB_8888:
1.604 + {
1.605 + color = aColor.Color16MU();
1.606 +#ifdef ALPHA_FIX_24BIT
1.607 + color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1.608 +#endif
1.609 + break;
1.610 + }
1.611 + case EUidPixelFormatARGB_8888:
1.612 + {
1.613 + color = aColor.Color16MA();
1.614 + break;
1.615 + }
1.616 + case EUidPixelFormatARGB_8888_PRE:
1.617 + {
1.618 + color = aColor.Color16MAP();
1.619 + break;
1.620 + }
1.621 + case EUidPixelFormatXRGB_4444:
1.622 + case EUidPixelFormatARGB_4444:
1.623 + {
1.624 + color = aColor.Color4K();
1.625 + use16 = ETrue;
1.626 + break;
1.627 + }
1.628 + case EUidPixelFormatRGB_565:
1.629 + {
1.630 + color = aColor.Color64K();
1.631 + use16 = ETrue;
1.632 + break;
1.633 + }
1.634 + default:
1.635 + {
1.636 + User::Leave(KErrNotSupported);
1.637 + break;
1.638 + }
1.639 + }
1.640 +
1.641 + TUint8* surfacePtr = aBufferPtr;
1.642 + TUint8* linePtr = surfacePtr;
1.643 +
1.644 + if (use16)
1.645 + {
1.646 + if ( info.iSize.iWidth*2>info.iStride)
1.647 + {
1.648 + User::Leave(KErrOverflow);
1.649 + }
1.650 + TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
1.651 +
1.652 + // Fill first line
1.653 + for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
1.654 + {
1.655 + ptr[xx] = (TUint16)color;
1.656 + }
1.657 + }
1.658 + else
1.659 + {
1.660 + if ( info.iSize.iWidth*4>info.iStride)
1.661 + {
1.662 + User::Leave(KErrOverflow);
1.663 + }
1.664 + TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
1.665 +
1.666 + // Fill first line
1.667 + for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
1.668 + {
1.669 + ptr[xx] = color;
1.670 + }
1.671 + }
1.672 +
1.673 + // Now copy that to the other lines
1.674 + for (TInt yy = 1; yy < info.iSize.iHeight; yy++)
1.675 + {
1.676 + linePtr += info.iStride;
1.677 + Mem::Copy(linePtr, surfacePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat));
1.678 + }
1.679 + }
1.680 +
1.681 +TBool CSurfaceUtility::CompareSurfacesL(TSurfaceId& aSurface, TInt aBuffer, TSurfaceId& aStreamSurface, TUint8* aBufferPtr)
1.682 + {
1.683 + RSurfaceManager::TInfoBuf infoBuf1;
1.684 + RSurfaceManager::TSurfaceInfoV01& info1 = infoBuf1();
1.685 +
1.686 + RSurfaceManager::TInfoBuf infoBuf2;
1.687 + RSurfaceManager::TSurfaceInfoV01& info2 = infoBuf2();
1.688 +
1.689 + User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf1));
1.690 + User::LeaveIfError(iManager.SurfaceInfo(aStreamSurface, infoBuf2));
1.691 + TBool use16 = EFalse;
1.692 +
1.693 + if (aBuffer < 0 || aBuffer >= info1.iBuffers)
1.694 + {
1.695 + User::Leave(KErrArgument);
1.696 + }
1.697 +
1.698 + if (info1.iPixelFormat != info2.iPixelFormat)
1.699 + {
1.700 + User::Leave(KErrArgument);
1.701 + }
1.702 +
1.703 + if ((info1.iSize.iHeight<0 || info1.iSize.iWidth<0 || info1.iStride<0) ||
1.704 + (info2.iSize.iHeight<0 || info2.iSize.iWidth<0 || info2.iStride<0))
1.705 + {
1.706 + User::Leave(KErrCorrupt);
1.707 + }
1.708 + if ((info1.iSize.iHeight==0 || info1.iSize.iWidth==0 || info1.iStride==0) ||
1.709 + (info2.iSize.iHeight==0 || info2.iSize.iWidth==0 || info2.iStride==0))
1.710 + {
1.711 + User::Leave(KErrNotReady);
1.712 + }
1.713 + if (info1.iSize != info2.iSize)
1.714 + {
1.715 + User::Leave(KErrArgument);
1.716 + }
1.717 +
1.718 + switch (info1.iPixelFormat)
1.719 + {
1.720 + case EUidPixelFormatXRGB_8888:
1.721 + case EUidPixelFormatARGB_8888:
1.722 + case EUidPixelFormatARGB_8888_PRE:
1.723 + {
1.724 + break;
1.725 + }
1.726 + case EUidPixelFormatXRGB_4444:
1.727 + case EUidPixelFormatARGB_4444:
1.728 + case EUidPixelFormatRGB_565:
1.729 + {
1.730 + use16 = ETrue;
1.731 + break;
1.732 + }
1.733 + default:
1.734 + {
1.735 + User::Leave(KErrNotSupported);
1.736 + break;
1.737 + }
1.738 + }
1.739 +
1.740 + // Surface
1.741 + RChunk chunk;
1.742 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.743 + CleanupClosePushL(chunk);
1.744 +
1.745 + TInt offsetToBuffer;
1.746 + User::LeaveIfError(iManager.GetBufferOffset(aSurface, aBuffer, offsetToBuffer));
1.747 + TUint8* surfacePtr1 = chunk.Base() + offsetToBuffer;
1.748 +
1.749 + // Native stream
1.750 + TUint8* surfacePtr2 = aBufferPtr;
1.751 +
1.752 + TUint32 color1 = 0;
1.753 + TUint32 color2 = 0;
1.754 +
1.755 + if (use16)
1.756 + {
1.757 + if ((info1.iSize.iWidth*2>info1.iStride) ||
1.758 + (info2.iSize.iWidth*2>info2.iStride))
1.759 + {
1.760 + User::Leave(KErrOverflow);
1.761 + }
1.762 +
1.763 + TUint16* ptr1 = reinterpret_cast<TUint16*>(surfacePtr1);
1.764 + TUint16* ptr2 = reinterpret_cast<TUint16*>(surfacePtr2);
1.765 +
1.766 + // Fill first line
1.767 + for (TInt xx = 0; xx < info1.iSize.iWidth; xx++)
1.768 + {
1.769 + for (TInt yy = 0; yy < info1.iSize.iHeight; yy++)
1.770 + {
1.771 + color1 = (TUint16)ptr1[xx];
1.772 + color2 = (TUint16)ptr2[xx];
1.773 + if (color1 != color2)
1.774 + {
1.775 + return EFalse;
1.776 + }
1.777 + }
1.778 + }
1.779 + }
1.780 + else
1.781 + {
1.782 + if ((info1.iSize.iWidth*4>info1.iStride) ||
1.783 + (info2.iSize.iWidth*4>info2.iStride))
1.784 + {
1.785 + User::Leave(KErrOverflow);
1.786 + }
1.787 +
1.788 + TUint32* ptr1 = reinterpret_cast<TUint32*>(surfacePtr1);
1.789 + TUint32* ptr2 = reinterpret_cast<TUint32*>(surfacePtr2);
1.790 +
1.791 + // Fill first line
1.792 + for (TInt xx = 0; xx < info1.iSize.iWidth; xx++)
1.793 + {
1.794 + for (TInt yy = 0; yy < info1.iSize.iHeight; yy++)
1.795 + {
1.796 + color1 = ptr1[xx];
1.797 + color2 = ptr2[xx];
1.798 + if (color1 != color2)
1.799 + {
1.800 + CleanupStack::PopAndDestroy(/* chunk */);
1.801 + return EFalse;
1.802 + }
1.803 + }
1.804 + }
1.805 + }
1.806 +
1.807 + CleanupStack::PopAndDestroy(/* chunk */);
1.808 + return ETrue;
1.809 + }
1.810 +
1.811 +void CSurfaceUtility::NotifyWhenDisplayed(TRequestStatus& aStatusDisplayed, TTimeStamp& aTimeStamp)
1.812 + {
1.813 + iSurfaceUpdateSession.NotifyWhenDisplayed(aStatusDisplayed, aTimeStamp);
1.814 + }
1.815 +
1.816 +void CSurfaceUtility::NotifyWhenDisplayedXTimes(TInt aCount, TRequestStatus& aStatusDisplayedX)
1.817 + {
1.818 + iSurfaceUpdateSession.NotifyWhenDisplayedXTimes(aCount, aStatusDisplayedX);
1.819 + }
1.820 +
1.821 +void CSurfaceUtility::NotifyWhenAvailable(TRequestStatus& aStatusAvailable)
1.822 + {
1.823 + iSurfaceUpdateSession.NotifyWhenAvailable(aStatusAvailable);
1.824 + }