graphicscomposition/openwfsupport/test/tstreamoperation/surfaceutility.cpp
changeset 0 5d03bc08d59c
child 36 01a6848ebfd7
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18 */
       
    19 
       
    20 #include <e32std.h>
       
    21 #include <imageconversion.h>
       
    22 #include "surfaceutility.h"
       
    23 
       
    24 CSurfaceUtility::CSurfaceUtility(CSurfaceUtility* aClone)
       
    25 	:	iScreenNum(0), iSurfaces(aClone?&(aClone->iSurfaces):NULL)
       
    26 	{
       
    27 	}
       
    28 	
       
    29 CSurfaceUtility* CSurfaceUtility::NewL(CSurfaceUtility* aClone/*=NULL*/)
       
    30 	{
       
    31 	CSurfaceUtility* utility = new (ELeave)CSurfaceUtility(aClone);
       
    32 	CleanupStack::PushL(utility);
       
    33 	utility->ConstructL();
       
    34 	CleanupStack::Pop(utility);
       
    35 	return utility;
       
    36 	}
       
    37 	
       
    38 void CSurfaceUtility::ConstructL()
       
    39 	{
       
    40 	TInt r = iManager.Open();
       
    41 	if (r != KErrNone)
       
    42 		{
       
    43 		LOG(("Surface manager failed to open: %d", r));
       
    44 		User::Leave(r);
       
    45 		}
       
    46 	
       
    47 	r = iSurfaceUpdateSession.Connect();
       
    48 	if (r != KErrNone)
       
    49 		{
       
    50 		LOG(("Failed to connect to update server: %d", r));
       
    51 		User::Leave(r);
       
    52 		}
       
    53 	}
       
    54 	
       
    55 CSurfaceUtility::~CSurfaceUtility()
       
    56 	{
       
    57 	DestroyAll();
       
    58 
       
    59 	iSurfaces.Close();
       
    60 
       
    61 	iManager.Close();
       
    62 
       
    63 	iSurfaceUpdateSession.Close();
       
    64 	}
       
    65 
       
    66 TBool CSurfaceUtility::DestroyAll()
       
    67 	{
       
    68 	TInt err = 	KErrNone;
       
    69 	TInt jj = iSurfaces.Count() - 1;
       
    70 	if (jj<0)
       
    71 		return EFalse;
       
    72 	for (; jj >= 0; jj--)
       
    73 		{
       
    74 		err = iManager.CloseSurface(iSurfaces[jj]);
       
    75 		if (err!=KErrNone)
       
    76 			{
       
    77 			LOG(("Error closing surface: 0x%X\n", err));
       
    78 			}
       
    79 		}
       
    80 	iSurfaces.Reset();
       
    81 	return ETrue;
       
    82 	}
       
    83 
       
    84 /***************************************
       
    85  * The aim of the THeapSurfaceArray is to locally switch in the specified heap for any array operation
       
    86  ***************************************/
       
    87 
       
    88 CSurfaceUtility::RHeapSurfaceArray::RHeapSurfaceArray(RHeapSurfaceArray* aUseExternalArray)
       
    89 	:	iUseArray(aUseExternalArray?aUseExternalArray->iUseArray:&this->iLocalArray),
       
    90 	iExternalHeapRef(aUseExternalArray?aUseExternalArray->iExternalHeapRef:User::Heap())
       
    91 	{
       
    92 	
       
    93 	}
       
    94 /************************************
       
    95  * The following methods have been used by the surfaceutility... some require the heap wrapping, and some don't
       
    96  * I actually need three different startegies (count em) for 7 methods...
       
    97  * Some methods only read the existing objects, so don't need a heap swap at all
       
    98  * Leaving methods have to use PopAndDestroy strategy to restore the heap on leaving or success
       
    99  * Non-leaving methods must not call PushL, so directly make SwitchHeap calls!
       
   100  ************************************/
       
   101 
       
   102 // PopAndDestroy method to restore the heap
       
   103 /*static*/ void	CSurfaceUtility::RHeapSurfaceArray::PopHeap(void* aHeapPtr)
       
   104 	{
       
   105 	RHeap* heapPtr=(RHeap*)aHeapPtr;
       
   106 	User::SwitchHeap(heapPtr);
       
   107 	}
       
   108 
       
   109 // Switches and pushes the previous heap so it can be restored with PopAndDestroy
       
   110 /*static*/ void CSurfaceUtility::RHeapSurfaceArray::SwitchHeapLC(RHeap* aNewHeap)
       
   111 	{
       
   112 	CleanupStack::PushL(TCleanupItem(PopHeap,NULL));
       
   113 	CleanupStack::PushL(TCleanupItem(PopHeap,NULL));
       
   114 	CleanupStack::PushL(TCleanupItem(PopHeap,NULL));
       
   115 	CleanupStack::Pop(3);
       
   116 	RHeap* oldHeap=User::SwitchHeap(aNewHeap);
       
   117 	delete new char;
       
   118 	CleanupStack::PushL(TCleanupItem(PopHeap,oldHeap));
       
   119 	}
       
   120 
       
   121 
       
   122 TSurfaceId& CSurfaceUtility::RHeapSurfaceArray::operator[](TUint aIndex)
       
   123 	{
       
   124 	return iUseArray->operator[](aIndex);
       
   125 	}
       
   126 
       
   127 // Close only closes the local array, while Reset resets the active array (may be external)
       
   128 void CSurfaceUtility::RHeapSurfaceArray::Close()
       
   129 	{
       
   130 	iLocalArray.Close();
       
   131 	}
       
   132 
       
   133 TInt CSurfaceUtility::RHeapSurfaceArray::Count() const
       
   134 	{
       
   135 	return iUseArray->Count();
       
   136 	}
       
   137 
       
   138 // Close only closes the local array, while Reset resets the active array (may be external)
       
   139 inline void CSurfaceUtility::RHeapSurfaceArray::Reset()
       
   140 	{
       
   141 	iUseArray->Reset();
       
   142 	}
       
   143 
       
   144 void CSurfaceUtility::RHeapSurfaceArray::AppendL(const TSurfaceId &anEntry)
       
   145 	{
       
   146 	iUseArray->AppendL(anEntry);
       
   147 	}
       
   148 
       
   149 TInt CSurfaceUtility::RHeapSurfaceArray::Find(const TSurfaceId &anEntry) const
       
   150 	{
       
   151 	return iUseArray->Find(anEntry);
       
   152 	}
       
   153 
       
   154 void CSurfaceUtility::RHeapSurfaceArray::Remove(TInt anIndex)
       
   155 	{
       
   156 	iUseArray->Remove(anIndex);
       
   157 	}
       
   158 
       
   159 /**
       
   160 Cleanup stack helper object, holding references to both utility and surface, so
       
   161 that the standard Close() semantics can be used.
       
   162 */
       
   163 class TSurfaceCleanup
       
   164 	{
       
   165 public:
       
   166 	TSurfaceCleanup(CSurfaceUtility& aUtility, TSurfaceId& aSurface)
       
   167 		: iUtility(aUtility), iSurface(aSurface)
       
   168 		{}
       
   169 	void Close()
       
   170 		{
       
   171 		// Removes the surface from the list of surfaces to clean up, and closes
       
   172 		// the surface reference.
       
   173 		iUtility.DestroySurface(iSurface);
       
   174 		}
       
   175 private:
       
   176 	CSurfaceUtility& iUtility;
       
   177 	TSurfaceId& iSurface;
       
   178 	};
       
   179 
       
   180 /**
       
   181 Get the size of a surface.
       
   182 
       
   183 @param aSurface The surface to get the size for.
       
   184 @return The size in pixels, or empty on failure.
       
   185 */
       
   186 TSize CSurfaceUtility::SurfaceSize(const TSurfaceId& aSurface)
       
   187 	{
       
   188 	RSurfaceManager::TInfoBuf infoBuf;
       
   189 	RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
       
   190 
       
   191 	if (iManager.SurfaceInfo(aSurface, infoBuf) == KErrNone)
       
   192 		{
       
   193 		return info.iSize;
       
   194 		}
       
   195 
       
   196 	return TSize();
       
   197 	}
       
   198 
       
   199 /**
       
   200 Create a surface using the surface manager.
       
   201 
       
   202 Stores the ID for tear down, as well as returning it.
       
   203 
       
   204 @param aSize Dimensions of the surface.
       
   205 @param aPixelFormat	UID of the pixel format.
       
   206 @param aStride	Stride value for the surface (usually bytes per pixel * width)
       
   207 @leave May leave due to lack of memory.
       
   208 @return New surface's ID.
       
   209 */
       
   210 TSurfaceId CSurfaceUtility::CreateSurfaceL(const TSize& aSize, TUidPixelFormat aPixelFormat, TInt aStride, TInt aBuffers)
       
   211 	{
       
   212 	RSurfaceManager::TSurfaceCreationAttributesBuf bf;
       
   213 	RSurfaceManager::TSurfaceCreationAttributes& b = bf();
       
   214 	if (aStride<aSize.iWidth*BytesPerPixelL(aPixelFormat))
       
   215 	    {
       
   216 	    User::Leave(KErrOverflow);
       
   217 	    }
       
   218 	b.iSize.iWidth = aSize.iWidth;
       
   219 	b.iSize.iHeight = aSize.iHeight;
       
   220 	b.iBuffers = aBuffers;				// number of buffers in the surface
       
   221 	b.iPixelFormat = aPixelFormat;
       
   222 	b.iStride = aStride;		// Number of bytes between start of one line and start of next
       
   223 	b.iOffsetToFirstBuffer = 0;	// way of reserving space before the surface pixel data
       
   224 	b.iAlignment = 4;			// alignment, 1,2,4,8 byte aligned
       
   225 	b.iContiguous = EFalse;
       
   226 	b.iMappable = ETrue;
       
   227 
       
   228 	TSurfaceId surface = TSurfaceId::CreateNullId();
       
   229 
       
   230 	User::LeaveIfError(iManager.CreateSurface(bf, surface));
       
   231 	iSurfaces.AppendL(surface);
       
   232 	return surface;
       
   233 	}
       
   234 
       
   235 /**
       
   236 A helper function that returns the bytes per pixel for a given pixel format uid
       
   237 
       
   238 @param aPixelFormat Pixel format UID to convert
       
   239 @return The bytes per pixel
       
   240 */
       
   241 TInt CSurfaceUtility::BytesPerPixelL(TUidPixelFormat aPixelFormat)
       
   242 	{
       
   243 	TInt bytesPerPixel = 0;
       
   244 	switch (aPixelFormat)
       
   245 		{
       
   246 		case EUidPixelFormatXRGB_8888:
       
   247 		case EUidPixelFormatARGB_8888:
       
   248 		case EUidPixelFormatARGB_8888_PRE:
       
   249 			{
       
   250 			bytesPerPixel = 4;
       
   251 			break;
       
   252 			}
       
   253 		case EUidPixelFormatXRGB_4444:
       
   254 		case EUidPixelFormatARGB_4444:
       
   255 		case EUidPixelFormatRGB_565:
       
   256 			{
       
   257 			bytesPerPixel = 2;
       
   258 			break;
       
   259 			}
       
   260 		default:
       
   261 			{
       
   262 			User::Leave(KErrNotSupported);
       
   263 			break;
       
   264 			}
       
   265 		}
       
   266 	return bytesPerPixel;
       
   267 	}
       
   268 
       
   269 /**
       
   270 Fill the given surface with a color.
       
   271 
       
   272 @param aSurface	The surface to be filled.
       
   273 @param aColor	The color to fill it with.
       
   274 */
       
   275 void CSurfaceUtility::FillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor)
       
   276 	{
       
   277 	RSurfaceManager::TInfoBuf infoBuf;
       
   278 	RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
       
   279 
       
   280 	User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
       
   281 	TUint32 color = 0;
       
   282 	TBool use16 = EFalse;
       
   283 
       
   284 	if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
       
   285 		{
       
   286 		User::Leave(KErrCorrupt);
       
   287 		}
       
   288 	if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
       
   289 		{
       
   290 		User::Leave(KErrNotReady);
       
   291 		}
       
   292 
       
   293 	switch (info.iPixelFormat)
       
   294 		{
       
   295 		case EUidPixelFormatXRGB_8888:
       
   296 			{
       
   297 			color = aColor.Color16MU();
       
   298 #ifdef ALPHA_FIX_24BIT
       
   299 			color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
       
   300 #endif
       
   301 			break;
       
   302 			}
       
   303 		case EUidPixelFormatARGB_8888:
       
   304 			{
       
   305 			color = aColor.Color16MA();
       
   306 			break;
       
   307 			}
       
   308 		case EUidPixelFormatARGB_8888_PRE:
       
   309 			{
       
   310 			color = aColor.Color16MAP();
       
   311 			break;
       
   312 			}
       
   313 		case EUidPixelFormatXRGB_4444:
       
   314 		case EUidPixelFormatARGB_4444:
       
   315 			{
       
   316 			color = aColor.Color4K();
       
   317 			use16 = ETrue;
       
   318 			break;
       
   319 			}
       
   320 		case EUidPixelFormatRGB_565:
       
   321 			{
       
   322 			color = aColor.Color64K();
       
   323 			use16 = ETrue;
       
   324 			break;
       
   325 			}
       
   326 		default:
       
   327 			{
       
   328 			User::Leave(KErrNotSupported);
       
   329 			break;
       
   330 			}
       
   331 		}
       
   332 
       
   333 	RChunk chunk;
       
   334 	User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
       
   335 	CleanupClosePushL(chunk);
       
   336 
       
   337 	TInt offsetToFirstBuffer;
       
   338 	User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
       
   339 	TUint8* surfacePtr = chunk.Base() + offsetToFirstBuffer;
       
   340 	TUint8* linePtr = surfacePtr;
       
   341 
       
   342 	if (use16)
       
   343 		{
       
   344 		if ( info.iSize.iWidth*2>info.iStride)
       
   345 			{
       
   346 			User::Leave(KErrOverflow);
       
   347 			}
       
   348 		TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
       
   349 
       
   350 		// Fill first line
       
   351 		for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
       
   352 			{
       
   353 			ptr[xx] = (TUint16)color;
       
   354 			}
       
   355 		}
       
   356 	else
       
   357 		{
       
   358 		if ( info.iSize.iWidth*4>info.iStride)
       
   359 			{
       
   360 			User::Leave(KErrOverflow);
       
   361 			}
       
   362 		TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
       
   363 
       
   364 		// Fill first line
       
   365 		for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
       
   366 			{
       
   367 			ptr[xx] = color;
       
   368 			}
       
   369 		}
       
   370 
       
   371 	// Now copy that to the other lines
       
   372 	for (TInt yy = 1; yy < info.iSize.iHeight; yy++)
       
   373 		{
       
   374 		linePtr += info.iStride;
       
   375 		Mem::Copy(linePtr, surfacePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat));
       
   376 		}
       
   377 	
       
   378 	TInt err = SubmitUpdate(iScreenNum, aSurface, 0, NULL);
       
   379 	if (err!=KErrNone)
       
   380 		LOG(("Error submitting update: 0x%X\n", err));
       
   381 
       
   382 	CleanupStack::PopAndDestroy(/* chunk */);
       
   383 	}
       
   384 
       
   385 /**
       
   386 Fill the given surface with a color.
       
   387 
       
   388 @param aSurface	The surface to be filled.
       
   389 @param aBuffer 	The buffer to fill.
       
   390 @param aColor	The color to fill it with.
       
   391 */
       
   392 void CSurfaceUtility::FillSurfaceL(TSurfaceId& aSurface, TInt aBuffer, const TRgb& aColor)
       
   393 	{
       
   394 	RSurfaceManager::TInfoBuf infoBuf;
       
   395 	RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
       
   396 
       
   397 	User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
       
   398 	TUint32 color = 0;
       
   399 	TBool use16 = EFalse;
       
   400 	TInt numBuffers = info.iBuffers;
       
   401 	if (aBuffer < 0 || aBuffer >= numBuffers)
       
   402 		{
       
   403 		User::Leave(KErrArgument);
       
   404 		}
       
   405 
       
   406 	if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
       
   407 		{
       
   408 		User::Leave(KErrCorrupt);
       
   409 		}
       
   410 	if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
       
   411 		{
       
   412 		User::Leave(KErrNotReady);
       
   413 		}
       
   414 
       
   415 	switch (info.iPixelFormat)
       
   416 		{
       
   417 		case EUidPixelFormatXRGB_8888:
       
   418 			{
       
   419 			color = aColor.Color16MU();
       
   420 #ifdef ALPHA_FIX_24BIT
       
   421 			color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
       
   422 #endif
       
   423 			break;
       
   424 			}
       
   425 		case EUidPixelFormatARGB_8888:
       
   426 			{
       
   427 			color = aColor.Color16MA();
       
   428 			break;
       
   429 			}
       
   430 		case EUidPixelFormatARGB_8888_PRE:
       
   431 			{
       
   432 			color = aColor.Color16MAP();
       
   433 			break;
       
   434 			}
       
   435 		case EUidPixelFormatXRGB_4444:
       
   436 		case EUidPixelFormatARGB_4444:
       
   437 			{
       
   438 			color = aColor.Color4K();
       
   439 			use16 = ETrue;
       
   440 			break;
       
   441 			}
       
   442 		case EUidPixelFormatRGB_565:
       
   443 			{
       
   444 			color = aColor.Color64K();
       
   445 			use16 = ETrue;
       
   446 			break;
       
   447 			}
       
   448 		default:
       
   449 			{
       
   450 			User::Leave(KErrNotSupported);
       
   451 			break;
       
   452 			}
       
   453 		}
       
   454 
       
   455 	RChunk chunk;
       
   456 	User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
       
   457 	CleanupClosePushL(chunk);
       
   458 
       
   459 	TInt offsetToBuffer;
       
   460 	User::LeaveIfError(iManager.GetBufferOffset(aSurface, aBuffer, offsetToBuffer));
       
   461 	TUint8* surfacePtr = chunk.Base() + offsetToBuffer;
       
   462 	TUint8* linePtr = surfacePtr;
       
   463 
       
   464 	if (use16)
       
   465 		{
       
   466 		if ( info.iSize.iWidth*2>info.iStride)
       
   467 			{
       
   468 			User::Leave(KErrOverflow);
       
   469 			}
       
   470 		TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
       
   471 
       
   472 		// Fill first line
       
   473 		for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
       
   474 			{
       
   475 			ptr[xx] = (TUint16)color;
       
   476 			}
       
   477 		}
       
   478 	else
       
   479 		{
       
   480 		if ( info.iSize.iWidth*4>info.iStride)
       
   481 			{
       
   482 			User::Leave(KErrOverflow);
       
   483 			}
       
   484 		TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
       
   485 
       
   486 		// Fill first line
       
   487 		for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
       
   488 			{
       
   489 			ptr[xx] = color;
       
   490 			}
       
   491 		}
       
   492 
       
   493 	// Now copy that to the other lines
       
   494 	for (TInt yy = 1; yy < info.iSize.iHeight; yy++)
       
   495 		{
       
   496 		linePtr += info.iStride;
       
   497 		Mem::Copy(linePtr, surfacePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat));
       
   498 		}
       
   499 	
       
   500 	TInt err = SubmitUpdate(iScreenNum, aSurface, 0, NULL);
       
   501 	if (err!=KErrNone)
       
   502 		LOG(("Error submitting update: 0x%X\n", err));
       
   503 
       
   504 	CleanupStack::PopAndDestroy(/* chunk */);
       
   505 	}
       
   506 
       
   507 
       
   508 /**
       
   509 Destroy a surface.
       
   510 
       
   511 As well as destroying the surface, it is removed from the set held for
       
   512 destruction during tear down.
       
   513 
       
   514 @param aSurface	The surface to be destroyed.
       
   515 */
       
   516 void CSurfaceUtility::DestroySurface(TSurfaceId& aSurface)
       
   517 	{
       
   518 	TInt index = iSurfaces.Find(aSurface);
       
   519 	
       
   520 	if (index != KErrNotFound)
       
   521 		{
       
   522 		iSurfaces.Remove(index);
       
   523 		}
       
   524 
       
   525 	TInt err = iManager.CloseSurface(aSurface);
       
   526 	if (err!=KErrNone)
       
   527 		LOG(("Error closing surfaces: 0x%X\n", err));
       
   528 	}
       
   529 
       
   530 
       
   531 /**
       
   532 Submit an update to a surface to the update server.
       
   533 
       
   534 @param aScreenNumber	The screen to be updated where the surface is shown.
       
   535 @param aSurface	The surface which has been updated.
       
   536 @param aRegion	The area of the surface affected, or NULL for all of it.
       
   537 */
       
   538 TInt CSurfaceUtility::SubmitUpdate(TInt aScreenNumber, const TSurfaceId& aSurface,TInt aBufferNumber, TInt aNullRegion)
       
   539     {
       
   540     if (aNullRegion==0)
       
   541         {
       
   542         return SubmitUpdate(aScreenNumber, aSurface, aBufferNumber);
       
   543         }
       
   544     else
       
   545         if (aBufferNumber==0)
       
   546             {
       
   547             return SubmitUpdate(aScreenNumber, aSurface, aNullRegion);
       
   548             }
       
   549         else
       
   550             {
       
   551             return KErrNotSupported;
       
   552             }
       
   553     }
       
   554 
       
   555 TInt CSurfaceUtility::SubmitUpdate(TInt aScreenNumber, const TSurfaceId& aSurface, const TRegion* aRegion,TInt aBufferNumber)
       
   556     {
       
   557     return SubmitUpdate(aScreenNumber, aSurface, aBufferNumber, aRegion);
       
   558     }
       
   559 
       
   560 TInt CSurfaceUtility::SubmitUpdate(TInt aScreenNumber, const TSurfaceId& aSurface,TInt aBufferNumber, const TRegion* aRegion)
       
   561 	{
       
   562 	if (!iSurfaceUpdateSession.Handle())
       
   563 	    {
       
   564 	    iSurfaceUpdateSession.Connect();
       
   565 	    }
       
   566     if (!iSurfaceUpdateSession.Handle())
       
   567         {
       
   568         LOG(("Error - SUS client not started!"));
       
   569         return KErrNotReady;
       
   570         }
       
   571     else
       
   572         {
       
   573         TInt err =iSurfaceUpdateSession.SubmitUpdate(aScreenNumber, aSurface, aBufferNumber, aRegion); 
       
   574         if (err!=KErrNone)
       
   575             LOG(("Error submitting update: 0x%X\n", err));
       
   576         return err;
       
   577         }
       
   578 	}
       
   579 
       
   580 void CSurfaceUtility::SetAutoUpdateScreenNum(TInt aScreenNum)
       
   581     {
       
   582     iScreenNum=aScreenNum;
       
   583     }
       
   584 
       
   585 void CSurfaceUtility::FillNativeStreamSurfaceL(TSurfaceId& aSurface, TUint8* aBufferPtr, const TRgb& aColor)
       
   586 	{
       
   587 	RSurfaceManager::TInfoBuf infoBuf;
       
   588 	RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
       
   589 
       
   590 	User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
       
   591 	TUint32 color = 0;
       
   592 	TBool use16 = EFalse;
       
   593 
       
   594 	if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
       
   595 		{
       
   596 		User::Leave(KErrCorrupt);
       
   597 		}
       
   598 	if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
       
   599 		{
       
   600 		User::Leave(KErrNotReady);
       
   601 		}
       
   602 
       
   603 	switch (info.iPixelFormat)
       
   604 		{
       
   605 		case EUidPixelFormatXRGB_8888:
       
   606 			{
       
   607 			color = aColor.Color16MU();
       
   608 #ifdef ALPHA_FIX_24BIT
       
   609 			color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
       
   610 #endif
       
   611 			break;
       
   612 			}
       
   613 		case EUidPixelFormatARGB_8888:
       
   614 			{
       
   615 			color = aColor.Color16MA();
       
   616 			break;
       
   617 			}
       
   618 		case EUidPixelFormatARGB_8888_PRE:
       
   619 			{
       
   620 			color = aColor.Color16MAP();
       
   621 			break;
       
   622 			}
       
   623 		case EUidPixelFormatXRGB_4444:
       
   624 		case EUidPixelFormatARGB_4444:
       
   625 			{
       
   626 			color = aColor.Color4K();
       
   627 			use16 = ETrue;
       
   628 			break;
       
   629 			}
       
   630 		case EUidPixelFormatRGB_565:
       
   631 			{
       
   632 			color = aColor.Color64K();
       
   633 			use16 = ETrue;
       
   634 			break;
       
   635 			}
       
   636 		default:
       
   637 			{
       
   638 			User::Leave(KErrNotSupported);
       
   639 			break;
       
   640 			}
       
   641 		}
       
   642 
       
   643 	TUint8* surfacePtr = aBufferPtr;
       
   644 	TUint8* linePtr = surfacePtr;
       
   645 
       
   646 	if (use16)
       
   647 		{
       
   648 		if ( info.iSize.iWidth*2>info.iStride)
       
   649 			{
       
   650 			User::Leave(KErrOverflow);
       
   651 			}
       
   652 		TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
       
   653 
       
   654 		// Fill first line
       
   655 		for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
       
   656 			{
       
   657 			ptr[xx] = (TUint16)color;
       
   658 			}
       
   659 		}
       
   660 	else
       
   661 		{
       
   662 		if ( info.iSize.iWidth*4>info.iStride)
       
   663 			{
       
   664 			User::Leave(KErrOverflow);
       
   665 			}
       
   666 		TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
       
   667 
       
   668 		// Fill first line
       
   669 		for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
       
   670 			{
       
   671 			ptr[xx] = color;
       
   672 			}
       
   673 		}
       
   674 
       
   675 	// Now copy that to the other lines
       
   676 	for (TInt yy = 1; yy < info.iSize.iHeight; yy++)
       
   677 		{
       
   678 		linePtr += info.iStride;
       
   679 		Mem::Copy(linePtr, surfacePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat));
       
   680 		}	
       
   681 	}
       
   682 
       
   683 TBool CSurfaceUtility::CompareSurfacesL(TSurfaceId& aSurface, TInt aBuffer, TSurfaceId& aStreamSurface, TUint8* aBufferPtr)
       
   684 	{
       
   685 	RSurfaceManager::TInfoBuf infoBuf1;
       
   686 	RSurfaceManager::TSurfaceInfoV01& info1 = infoBuf1();
       
   687 	
       
   688 	RSurfaceManager::TInfoBuf infoBuf2;
       
   689 	RSurfaceManager::TSurfaceInfoV01& info2 = infoBuf2();	
       
   690 
       
   691 	User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf1));
       
   692 	User::LeaveIfError(iManager.SurfaceInfo(aStreamSurface, infoBuf2));
       
   693 	TBool use16 = EFalse;
       
   694 	
       
   695 	if (aBuffer < 0 || aBuffer >= info1.iBuffers)
       
   696 		{
       
   697 		User::Leave(KErrArgument);
       
   698 		}
       
   699 
       
   700 	if (info1.iPixelFormat != info2.iPixelFormat)
       
   701 		{
       
   702 		User::Leave(KErrArgument);
       
   703 		}	
       
   704 	
       
   705 	if ((info1.iSize.iHeight<0 || info1.iSize.iWidth<0 || info1.iStride<0) ||
       
   706 		(info2.iSize.iHeight<0 || info2.iSize.iWidth<0 || info2.iStride<0))
       
   707 		{
       
   708 		User::Leave(KErrCorrupt);
       
   709 		}
       
   710 	if ((info1.iSize.iHeight==0 || info1.iSize.iWidth==0 || info1.iStride==0) ||
       
   711 		(info2.iSize.iHeight==0 || info2.iSize.iWidth==0 || info2.iStride==0))
       
   712 		{
       
   713 		User::Leave(KErrNotReady);
       
   714 		}
       
   715 	if (info1.iSize != info2.iSize)
       
   716 		{
       
   717 		User::Leave(KErrArgument);
       
   718 		}
       
   719 
       
   720 	switch (info1.iPixelFormat)
       
   721 		{
       
   722 		case EUidPixelFormatXRGB_8888:
       
   723 		case EUidPixelFormatARGB_8888:
       
   724 		case EUidPixelFormatARGB_8888_PRE:
       
   725 			{
       
   726 			break;
       
   727 			}
       
   728 		case EUidPixelFormatXRGB_4444:
       
   729 		case EUidPixelFormatARGB_4444:
       
   730 		case EUidPixelFormatRGB_565:
       
   731 			{
       
   732 			use16 = ETrue;
       
   733 			break;
       
   734 			}
       
   735 		default:
       
   736 			{
       
   737 			User::Leave(KErrNotSupported);
       
   738 			break;
       
   739 			}
       
   740 		}
       
   741 
       
   742 	// Surface
       
   743 	RChunk chunk;
       
   744 	User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
       
   745 	CleanupClosePushL(chunk);
       
   746 	
       
   747 	TInt offsetToBuffer;
       
   748 	User::LeaveIfError(iManager.GetBufferOffset(aSurface, aBuffer, offsetToBuffer));
       
   749 	TUint8* surfacePtr1 = chunk.Base() + offsetToBuffer;
       
   750 
       
   751 	// Native stream
       
   752 	TUint8* surfacePtr2 = aBufferPtr;
       
   753 	
       
   754 	TUint32 color1 = 0;
       
   755 	TUint32 color2 = 0;
       
   756 	
       
   757 	if (use16)
       
   758 		{
       
   759 		if ((info1.iSize.iWidth*2>info1.iStride) ||
       
   760 			(info2.iSize.iWidth*2>info2.iStride))
       
   761 			{
       
   762 			User::Leave(KErrOverflow);
       
   763 			}
       
   764 		
       
   765 		TUint16* ptr1 = reinterpret_cast<TUint16*>(surfacePtr1);
       
   766 		TUint16* ptr2 = reinterpret_cast<TUint16*>(surfacePtr2);
       
   767 
       
   768 		// Fill first line
       
   769 		for (TInt xx = 0; xx < info1.iSize.iWidth; xx++)
       
   770 			{
       
   771 			for (TInt yy = 0; yy < info1.iSize.iHeight; yy++)
       
   772 				{
       
   773 				color1 = (TUint16)ptr1[xx];
       
   774 				color2 = (TUint16)ptr2[xx];
       
   775 				if (color1 != color2)
       
   776 					{
       
   777 					return EFalse;
       
   778 					}
       
   779 				}
       
   780 			}
       
   781 		}
       
   782 	else
       
   783 		{
       
   784 		if ((info1.iSize.iWidth*4>info1.iStride) ||
       
   785 			(info2.iSize.iWidth*4>info2.iStride))
       
   786 			{
       
   787 			User::Leave(KErrOverflow);
       
   788 			}
       
   789 
       
   790 		TUint32* ptr1 = reinterpret_cast<TUint32*>(surfacePtr1);
       
   791 		TUint32* ptr2 = reinterpret_cast<TUint32*>(surfacePtr2);		
       
   792 
       
   793 		// Fill first line
       
   794 		for (TInt xx = 0; xx < info1.iSize.iWidth; xx++)
       
   795 			{
       
   796 			for (TInt yy = 0; yy < info1.iSize.iHeight; yy++)
       
   797 				{
       
   798 				color1 = ptr1[xx];
       
   799 				color2 = ptr2[xx];
       
   800 				if (color1 != color2)
       
   801 					{
       
   802 					CleanupStack::PopAndDestroy(/* chunk */);
       
   803 					return EFalse;
       
   804 					}
       
   805 				}
       
   806 			}
       
   807 		}	
       
   808 		
       
   809 	CleanupStack::PopAndDestroy(/* chunk */);
       
   810 	return ETrue;
       
   811 	}
       
   812 
       
   813 void CSurfaceUtility::NotifyWhenDisplayed(TRequestStatus& aStatusDisplayed, TTimeStamp& aTimeStamp)
       
   814     {
       
   815     iSurfaceUpdateSession.NotifyWhenDisplayed(aStatusDisplayed, aTimeStamp);
       
   816     }
       
   817 
       
   818 void CSurfaceUtility::NotifyWhenDisplayedXTimes(TInt aCount, TRequestStatus& aStatusDisplayedX)
       
   819     {
       
   820     iSurfaceUpdateSession.NotifyWhenDisplayedXTimes(aCount, aStatusDisplayedX);
       
   821     }
       
   822 
       
   823 void CSurfaceUtility::NotifyWhenAvailable(TRequestStatus& aStatusAvailable)
       
   824     {
       
   825     iSurfaceUpdateSession.NotifyWhenAvailable(aStatusAvailable);
       
   826     }