First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
21 #include <imageconversion.h>
22 #include "surfaceutility.h"
24 CSurfaceUtility::CSurfaceUtility(CSurfaceUtility* aClone/*=NULL*/)
25 : iSurfaces(aClone?&(aClone->iSurfaces):NULL)
29 CSurfaceUtility* CSurfaceUtility::NewL(CSurfaceUtility* aClone/*=NULL*/)
31 CSurfaceUtility* utility = new (ELeave)CSurfaceUtility(aClone);
32 CleanupStack::PushL(utility);
33 utility->ConstructL();
34 CleanupStack::Pop(utility);
38 void CSurfaceUtility::ConstructL()
40 TInt r = iManager.Open();
43 LOG(("Surface manager failed to open: %d", r));
47 r = iSurfaceUpdateSession.Connect();
50 LOG(("Failed to connect to update server: %d", r));
55 CSurfaceUtility::~CSurfaceUtility()
63 iSurfaceUpdateSession.Close();
66 TBool CSurfaceUtility::DestroyAll()
69 TInt jj = iSurfaces.Count() - 1;
74 err = iManager.CloseSurface(iSurfaces[jj]);
77 LOG(("Error closing surface: 0x%X\n", err));
84 /***************************************
85 * The aim of the THeapSurfaceArray is to locally switch in the specified heap for any array operation
86 ***************************************/
88 CSurfaceUtility::RHeapSurfaceArray::RHeapSurfaceArray(RHeapSurfaceArray* aUseExternalArray)
89 : iUseArray(aUseExternalArray?aUseExternalArray->iUseArray:&this->iLocalArray),
90 iExternalHeapRef(aUseExternalArray?aUseExternalArray->iExternalHeapRef:User::Heap())
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 ************************************/
102 // PopAndDestroy method to restore the heap
103 /*static*/ void CSurfaceUtility::RHeapSurfaceArray::PopHeap(void* aHeapPtr)
105 RHeap* heapPtr=(RHeap*)aHeapPtr;
106 User::SwitchHeap(heapPtr);
109 // Switches and pushes the previous heap so it can be restored with PopAndDestroy
110 /*static*/ void CSurfaceUtility::RHeapSurfaceArray::SwitchHeapLC(RHeap* aNewHeap)
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);
118 CleanupStack::PushL(TCleanupItem(PopHeap,oldHeap));
122 TSurfaceId& CSurfaceUtility::RHeapSurfaceArray::operator[](TUint aIndex)
124 return iUseArray->operator[](aIndex);
126 // Close only closes the local array, while Reset resets the active array (may be external)
127 void CSurfaceUtility::RHeapSurfaceArray::Close()
129 RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef);
131 User::SwitchHeap(oldHeap);
133 TInt CSurfaceUtility::RHeapSurfaceArray::Count() const
135 return iUseArray->Count();
137 // Close only closes the local array, while Reset resets the active array (may be external)
138 inline void CSurfaceUtility::RHeapSurfaceArray::Reset()
140 RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef);
142 User::SwitchHeap(oldHeap);
144 void CSurfaceUtility::RHeapSurfaceArray::AppendL(const TSurfaceId &anEntry)
146 SwitchHeapLC(&iExternalHeapRef);
147 iUseArray->AppendL(anEntry);
148 CleanupStack::PopAndDestroy();
150 TInt CSurfaceUtility::RHeapSurfaceArray::Find(const TSurfaceId &anEntry) const
152 return iUseArray->Find(anEntry);
154 void CSurfaceUtility::RHeapSurfaceArray::Remove(TInt anIndex)
156 RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef);
157 iUseArray->Remove(anIndex);
158 User::SwitchHeap(oldHeap);
165 Cleanup stack helper object, holding references to both utility and surface, so
166 that the standard Close() semantics can be used.
168 class TSurfaceCleanup
171 TSurfaceCleanup(CSurfaceUtility& aUtility, TSurfaceId& aSurface)
172 : iUtility(aUtility), iSurface(aSurface)
176 // Removes the surface from the list of surfaces to clean up, and closes
177 // the surface reference.
178 iUtility.DestroySurface(iSurface);
181 CSurfaceUtility& iUtility;
182 TSurfaceId& iSurface;
186 Read the given image file into a new surface.
188 @param aFileName The name of the image file.
189 @param aSurface Filled with the surface ID for the surface containing the pixels.
191 void CSurfaceUtility::CreateSurfaceFromFileL(const TDesC& aFileName, TSurfaceId& aSurface)
195 User::LeaveIfError(fs.Connect());
196 CleanupClosePushL(fs);
197 CImageDecoder* decoder = CImageDecoder::FileNewL(fs, aFileName, CImageDecoder::EOptionAlwaysThread);
198 CleanupStack::PushL(decoder);
200 const TFrameInfo& info = decoder->FrameInfo();
202 TSize size = info.iOverallSizeInPixels;
203 TInt stride = size.iWidth << 2; // Default to four bytes per pixel
204 TDisplayMode bmpFormat = info.iFrameDisplayMode;
205 TUidPixelFormat pixelFormat = EUidPixelFormatUnknown;
218 bmpFormat = EColor16MU;
219 pixelFormat = EUidPixelFormatXRGB_8888;
224 stride = size.iWidth << 1;
225 pixelFormat = EUidPixelFormatXRGB_4444;
230 stride = size.iWidth << 1;
231 pixelFormat = EUidPixelFormatRGB_565;
236 pixelFormat = EUidPixelFormatARGB_8888;
241 pixelFormat = EUidPixelFormatARGB_8888_PRE;
246 LOG(("Unsupported display mode: %d", bmpFormat));
247 User::Leave(KErrNotSupported);
252 // Create an intermediary bitmap for decoding into
253 CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
254 CleanupStack::PushL(bitmap);
255 User::LeaveIfError(bitmap->Create(size, info.iFrameDisplayMode));
257 // Create the final surface.
258 aSurface = CreateSurfaceL(size, pixelFormat, stride);
259 TSurfaceCleanup surfaceCleanup(*this, aSurface);
260 CleanupClosePushL(surfaceCleanup);
263 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
264 CleanupClosePushL(chunk);
266 // Convert the image file into a Symbian bitmap
267 TRequestStatus status;
268 decoder->Convert(&status, *bitmap);
269 User::WaitForRequest(status);
270 User::LeaveIfError(status.Int());
272 TInt offsetToFirstBuffer;
273 User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
275 // Copy the data from the bitmap into the surface.
277 TUint8 *pSurfStart = chunk.Base() + offsetToFirstBuffer;
278 for (start.iY = 0; start.iY < size.iHeight; start.iY++)
280 // Set up a descriptor for the current line in the surface and get pixels.
281 TPtr8 ptr(pSurfStart + start.iY * stride, stride);
282 bitmap->GetScanLine(ptr, start, size.iWidth, bmpFormat);
285 CleanupStack::PopAndDestroy(/* chunk */);
286 CleanupStack::Pop(/* surfaceCleanup */);
287 CleanupStack::PopAndDestroy(bitmap);
288 CleanupStack::PopAndDestroy(decoder);
289 CleanupStack::PopAndDestroy(/* fs */);
292 void CSurfaceUtility::CopyBitmapSurfaceL(const CFbsBitmap* aBitmap, TSurfaceId& aSurface)
295 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
296 CleanupClosePushL(chunk);
297 TSize bitmapSize = aBitmap->SizeInPixels();
298 TSize size = SurfaceSize(aSurface);
299 TInt stride = size.iWidth*4; // Default to four bytes per pixel
301 TInt offsetToFirstBuffer;
302 User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
304 // Copy the data from the bitmap into the surface.
306 TUint8 *pSurfStart = chunk.Base() + offsetToFirstBuffer;
307 for (start.iY = 0; start.iY < bitmapSize.iHeight; start.iY++)
309 // Set up a descriptor for the current line in the surface and get pixels.
310 TPtr8 ptr(pSurfStart + start.iY * stride, stride);
311 aBitmap->GetScanLine(ptr, start, bitmapSize.iWidth, EColor16MU);
313 CleanupStack::PopAndDestroy(/* chunk */);
317 Copy the bitmap from a file to a surface.
319 @param aFileName The name of the image file.
320 @param aSurface Filled with the surface ID for the surface containing the pixels.
322 void CSurfaceUtility::CopyBitmapFromFileToSurfaceL(const TDesC& aFileName, TSurfaceId& aSurface)
326 User::LeaveIfError(fs.Connect());
327 CleanupClosePushL(fs);
328 CImageDecoder* decoder = CImageDecoder::FileNewL(fs, aFileName, CImageDecoder::EOptionAlwaysThread);
329 CleanupStack::PushL(decoder);
331 const TFrameInfo& info = decoder->FrameInfo();
333 RSurfaceManager::TInfoBuf infoBuf;
334 RSurfaceManager::TSurfaceInfoV01& infoSurf = infoBuf();
335 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
337 TSize size = infoSurf.iSize;
338 TDisplayMode bmpFormat = info.iFrameDisplayMode;
339 TInt stride = size.iWidth << 2; // Default to four bytes per pixel
341 // Create an intermediary bitmap for decoding into
342 CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
343 CleanupStack::PushL(bitmap);
344 User::LeaveIfError(bitmap->Create(size, info.iFrameDisplayMode));
347 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
348 CleanupClosePushL(chunk);
350 // Convert the image file into a Symbian bitmap
351 TRequestStatus status;
352 decoder->Convert(&status, *bitmap);
353 User::WaitForRequest(status);
354 User::LeaveIfError(status.Int());
356 TInt offsetToFirstBuffer;
357 User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
359 // Copy the data from the bitmap into the surface.
361 TUint8 *pSurfStart = chunk.Base() + offsetToFirstBuffer;
362 for (start.iY = 0; start.iY < size.iHeight; start.iY++)
364 // Set up a descriptor for the current line in the surface and get pixels.
365 TPtr8 ptr(pSurfStart + start.iY * stride, stride);
366 bitmap->GetScanLine(ptr, start, size.iWidth, bmpFormat);
369 CleanupStack::PopAndDestroy(/* chunk */);
370 CleanupStack::PopAndDestroy(bitmap);
371 CleanupStack::PopAndDestroy(decoder);
372 CleanupStack::PopAndDestroy(/* fs */);
375 Get the size of a surface.
377 @param aSurface The surface to get the size for.
378 @return The size in pixels, or empty on failure.
380 TSize CSurfaceUtility::SurfaceSize(const TSurfaceId& aSurface)
382 RSurfaceManager::TInfoBuf infoBuf;
383 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
385 if (iManager.SurfaceInfo(aSurface, infoBuf) == KErrNone)
395 Create a surface using the surface manager.
397 Stores the ID for tear down, as well as returning it.
399 @param aSize Dimensions of the surface.
400 @param aPixelFormat UID of the pixel format.
401 @param aStride Stride value for the surface (usually bytes per pixel * width)
402 @leave May leave due to lack of memory.
403 @return New surface's ID.
405 TSurfaceId CSurfaceUtility::CreateSurfaceL(const TSize& aSize, TUidPixelFormat aPixelFormat, TInt aStride, TInt aBuffers)
407 RSurfaceManager::TSurfaceCreationAttributesBuf bf;
408 RSurfaceManager::TSurfaceCreationAttributes& b = bf();
410 b.iSize.iWidth = aSize.iWidth;
411 b.iSize.iHeight = aSize.iHeight;
412 b.iBuffers = aBuffers; // number of buffers in the surface
413 b.iPixelFormat = aPixelFormat;
414 b.iStride = aStride; // Number of bytes between start of one line and start of next
415 b.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data
416 b.iAlignment = 4; // alignment, 1,2,4,8 byte aligned
417 b.iContiguous = EFalse;
420 TSurfaceId surface = TSurfaceId::CreateNullId();
422 User::LeaveIfError(iManager.CreateSurface(bf, surface));
423 iSurfaces.AppendL(surface);
428 A helper function that returns the bytes per pixel for a given pixel format uid
430 @param aPixelFormat Pixel format UID to convert
431 @return The bytes per pixel
433 TInt CSurfaceUtility::BytesPerPixelL(TUidPixelFormat aPixelFormat)
435 TInt bytesPerPixel = 0;
436 switch (aPixelFormat)
438 case EUidPixelFormatXRGB_8888:
439 case EUidPixelFormatARGB_8888:
440 case EUidPixelFormatARGB_8888_PRE:
445 case EUidPixelFormatXRGB_4444:
446 case EUidPixelFormatARGB_4444:
447 case EUidPixelFormatRGB_565:
454 User::Leave(KErrNotSupported);
458 return bytesPerPixel;
462 Fill the given surface with a color.
464 @param aSurface The surface to be filled.
465 @param aColor The color to fill it with.
467 void CSurfaceUtility::FillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor)
469 RSurfaceManager::TInfoBuf infoBuf;
470 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
472 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
474 TBool use16 = EFalse;
476 if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
478 User::Leave(KErrCorrupt);
480 if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
482 User::Leave(KErrNotReady);
485 switch (info.iPixelFormat)
487 case EUidPixelFormatXRGB_8888:
489 color = aColor.Color16MU();
490 #ifdef ALPHA_FIX_24BIT
491 color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
495 case EUidPixelFormatARGB_8888:
497 color = aColor.Color16MA();
500 case EUidPixelFormatARGB_8888_PRE:
502 color = aColor.Color16MAP();
505 case EUidPixelFormatXRGB_4444:
506 case EUidPixelFormatARGB_4444:
508 color = aColor.Color4K();
512 case EUidPixelFormatRGB_565:
514 color = aColor.Color64K();
520 User::Leave(KErrNotSupported);
526 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
527 CleanupClosePushL(chunk);
529 TInt offsetToFirstBuffer;
530 User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
531 TUint8* surfacePtr = chunk.Base() + offsetToFirstBuffer;
532 TUint8* linePtr = surfacePtr;
536 if ( info.iSize.iWidth*2>info.iStride)
538 User::Leave(KErrOverflow);
540 TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
543 for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
545 ptr[xx] = (TUint16)color;
550 if ( info.iSize.iWidth*4>info.iStride)
552 User::Leave(KErrOverflow);
554 TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
557 for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
563 // Now copy that to the other lines
564 for (TInt yy = 1; yy < info.iSize.iHeight; yy++)
566 linePtr += info.iStride;
567 Mem::Copy(linePtr, surfacePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat));
570 TInt err = iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
572 LOG(("Error submitting update: 0x%X\n", err));
574 CleanupStack::PopAndDestroy(/* chunk */);
578 Fill the given memory chunk with a color.
580 @param aSurface The surface to be filled.
581 @param aChunk The surface to be filled.
582 @param aColor The color to fill it with.
584 void CSurfaceUtility::FillChunkL(TSurfaceId& aSurface, RChunk& aChunk, const TRgb& aColor, TInt aBufferNumber)
586 RSurfaceManager::TInfoBuf infoBuf;
587 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
589 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
591 TBool use16 = EFalse;
593 if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
595 User::Leave(KErrCorrupt);
597 if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
599 User::Leave(KErrNotReady);
602 switch (info.iPixelFormat)
604 case EUidPixelFormatXRGB_8888:
606 color = aColor.Color16MU();
607 #ifdef ALPHA_FIX_24BIT
608 color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
612 case EUidPixelFormatARGB_8888:
614 color = aColor.Color16MA();
617 case EUidPixelFormatARGB_8888_PRE:
619 color = aColor.Color16MAP();
622 case EUidPixelFormatXRGB_4444:
623 case EUidPixelFormatARGB_4444:
625 color = aColor.Color4K();
629 case EUidPixelFormatRGB_565:
631 color = aColor.Color64K();
637 User::Leave(KErrNotSupported);
642 User::LeaveIfError(iManager.MapSurface(aSurface, aChunk));
644 TInt offsetToFirstBuffer;
645 User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
646 TInt offsetToBufferNumber;
647 User::LeaveIfError(iManager.GetBufferOffset(aSurface, aBufferNumber, offsetToBufferNumber));
649 TUint8* chunkPtr = aChunk.Base() + offsetToFirstBuffer;
650 TUint8* linePtr = aChunk.Base() + offsetToBufferNumber;
651 TUint8* surfPlanePtr = linePtr;
655 if ( info.iSize.iWidth*2>info.iStride)
658 User::Leave(KErrOverflow);
660 TUint16* ptr = reinterpret_cast<TUint16*>(surfPlanePtr);
663 for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
665 ptr[xx] = (TUint16)color;
670 if ( info.iSize.iWidth*4>info.iStride)
673 User::Leave(KErrOverflow);
675 TUint32* ptr = reinterpret_cast<TUint32*>(surfPlanePtr);
678 for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
684 // Now copy that to the other lines
685 for (TInt yy = 1; yy < info.iSize.iHeight; yy++)
687 linePtr += info.iStride;
688 Mem::Copy(linePtr, surfPlanePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat));
695 Fill a rectangle on the given surface.
697 @param aSurface The surface to be filled.
698 @param aStartPos Where to place the rectangle.
699 @param aSize Size of the rectangle.
700 @param aColor The colour to fill it with.
702 void CSurfaceUtility::FillRectangleL(TSurfaceId& aSurface, const TPoint& aStartPos, const TSize& aSize, const TRgb& aColor)
704 FillRectangleNoUpdateL(aSurface, aStartPos, aSize, aColor);
706 TInt err = iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
708 LOG(("Error submitting update: 0x%X\n", err));
712 Fill a rectangle on the given surface - does not submit update.
714 @param aSurface The surface to be filled.
715 @param aStartPos Where to place the rectangle.
716 @param aSize Size of the rectangle.
717 @param aColor The colour to fill it with.
719 void CSurfaceUtility::FillRectangleNoUpdateL(TSurfaceId& aSurface, const TPoint& aStartPos, const TSize& aSize, const TRgb& aColor)
721 RSurfaceManager::TInfoBuf infoBuf;
722 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
724 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
726 TBool use16 = EFalse;
728 if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
730 User::Leave(KErrCorrupt);
732 if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
734 User::Leave(KErrNotReady);
737 switch (info.iPixelFormat)
739 case EUidPixelFormatXRGB_8888:
741 color = aColor.Color16MU();
742 #ifdef ALPHA_FIX_24BIT
743 color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
747 case EUidPixelFormatARGB_8888:
749 color = aColor.Color16MA();
752 case EUidPixelFormatARGB_8888_PRE:
754 color = aColor.Color16MAP();
757 case EUidPixelFormatXRGB_4444:
758 case EUidPixelFormatARGB_4444:
760 color = aColor.Color4K();
764 case EUidPixelFormatRGB_565:
766 color = aColor.Color64K();
772 User::Leave(KErrNotSupported);
778 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
779 CleanupClosePushL(chunk);
781 TInt offsetToFirstBuffer;
782 User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
783 TUint8* surfacePtr = chunk.Base() + offsetToFirstBuffer;
785 // Check for out of bounds
786 TBool validRect = ETrue;
787 TInt surfaceWidth = info.iSize.iWidth;
788 TInt surfaceHeight = info.iSize.iHeight;
791 if ((aStartPos.iX + aSize.iWidth) > surfaceWidth)
794 if ((aStartPos.iY + aSize.iHeight) > surfaceHeight)
798 if ((aStartPos.iX < 0) || (aStartPos.iY < 0))
802 User::Leave(KErrOverflow);
806 if ( info.iSize.iWidth*2>info.iStride)
808 User::Leave(KErrOverflow);
811 TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
813 // Fill the rectangle
814 TInt yPos = aStartPos.iY;
815 TInt xPos = aStartPos.iX;
816 for (TInt yy = 0; yy < aSize.iHeight; ++yy)
818 ptr = reinterpret_cast<TUint16*>(surfacePtr+(yPos*info.iStride));
819 for (TInt xx = 0; xx < aSize.iWidth; ++xx)
830 if ( info.iSize.iWidth*4>info.iStride)
832 User::Leave(KErrOverflow);
835 TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
837 // Fill the rectangle
838 TInt yPos = aStartPos.iY;
839 TInt xPos = aStartPos.iX;
840 for (TInt yy = 0; yy < aSize.iHeight; ++yy)
842 ptr = reinterpret_cast<TUint32*>(surfacePtr+(yPos*info.iStride));
843 for (TInt xx = 0; xx < aSize.iWidth; ++xx)
853 CleanupStack::PopAndDestroy(/* chunk */);
857 Fill the given surface with a grid over a solid color.
859 Similar to FillSurfaceL(), but with a grid overlayed. The pitch of the grid is
862 @param aSurface The surface to be filled.
863 @param aColor The color to fill it with.
864 @param aLines The color of the grid lines.
866 void CSurfaceUtility::GridFillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor, const TRgb& aLines)
868 RSurfaceManager::TInfoBuf infoBuf;
869 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
871 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
874 TBool use16 = EFalse;
876 if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
878 User::Leave(KErrCorrupt);
880 if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
882 User::Leave(KErrNotReady);
885 switch (info.iPixelFormat)
887 case EUidPixelFormatXRGB_8888:
889 color = aColor.Color16MU();
890 lines = aLines.Color16MU();
891 #ifdef ALPHA_FIX_24BIT
892 color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
893 lines |= ((ALPHA_FIX_24BIT)&0xff)<<24;
897 case EUidPixelFormatARGB_8888:
899 color = aColor.Color16MA();
900 lines = aLines.Color16MA();
903 case EUidPixelFormatARGB_8888_PRE:
905 color = aColor.Color16MAP();
906 lines = aLines.Color16MAP();
909 case EUidPixelFormatXRGB_4444:
910 case EUidPixelFormatARGB_4444:
912 color = aColor.Color4K();
913 lines = aLines.Color4K();
917 case EUidPixelFormatRGB_565:
919 color = aColor.Color64K();
920 lines = aLines.Color64K();
926 User::Leave(KErrNotSupported);
932 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
933 CleanupClosePushL(chunk);
935 TInt offsetToFirstBuffer;
936 User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
937 TUint8* surfacePtr = chunk.Base() + offsetToFirstBuffer;
938 TUint8* linePtr = surfacePtr;
942 if ( info.iSize.iWidth*2>info.iStride)
944 User::Leave(KErrOverflow);
946 TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
949 for (TInt xx1 = 0; xx1 < info.iSize.iWidth; xx1++)
951 ptr[xx1] = (TUint16)lines;
955 ptr = reinterpret_cast<TUint16*>(surfacePtr + info.iStride);
956 for (TInt xx2 = 0; xx2 < info.iSize.iWidth; xx2++)
958 // Vertical line every 8 pixels across
959 ptr[xx2] = (TUint16)((xx2 & 7) ? color : lines);
964 if ( info.iSize.iWidth*4>info.iStride)
966 User::Leave(KErrOverflow);
968 TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
971 for (TInt xx3 = 0; xx3 < info.iSize.iWidth; xx3++)
977 ptr = reinterpret_cast<TUint32*>(surfacePtr + info.iStride);
978 for (TInt xx4 = 0; xx4 < info.iSize.iWidth; xx4++)
980 // Vertical line every 8 pixels across
981 ptr[xx4] = (xx4 & 7) ? color : lines;
984 linePtr += info.iStride;
986 // Now copy that to the other lines
987 for (TInt yy = 2; yy < info.iSize.iHeight; yy++)
989 linePtr += info.iStride;
993 Mem::Copy(linePtr, surfacePtr + info.iStride, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat));
998 Mem::Copy(linePtr, surfacePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat));
1002 TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1004 LOG(("Error submitting update: 0x%X\n", err));
1006 CleanupStack::PopAndDestroy(/* chunk */);
1011 Fill the given surface with a pattern suitable for automated testing.
1013 @param aSurface The surface to be filled.
1015 void CSurfaceUtility::PatternFillSurfaceL(TSurfaceId& aSurface)
1017 RSurfaceManager::TInfoBuf infoBuf;
1018 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1020 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1022 // Fill the background
1023 FillSurfaceL(aSurface, TRgb(0x00000000));
1025 TInt surfaceWidth = info.iSize.iWidth;
1026 TInt surfaceHeight = info.iSize.iHeight;
1028 // Create the 4 rectangles in the corners
1029 TPoint startPos(0,0);
1031 TInt rectWidth = size.iWidth;
1032 TInt rectHeight = size.iHeight;
1034 FillRectangleL(aSurface, startPos, size, TRgb(0x0000ff));
1037 startPos.iX = surfaceWidth - rectWidth;
1039 FillRectangleL(aSurface, startPos, size, TRgb(0x00ff00));
1043 startPos.iY = surfaceHeight - rectHeight;
1044 FillRectangleL(aSurface, startPos, size, TRgb(0x00ffff));
1047 startPos.iX = surfaceWidth - rectWidth;
1048 startPos.iY = surfaceHeight - rectHeight;
1049 FillRectangleL(aSurface, startPos, size, TRgb(0xffffff));
1051 // Create the 4 side bars
1055 size.iHeight = surfaceHeight - 12;
1057 FillRectangleL(aSurface, startPos, size, TRgb(0x808000));
1059 startPos.iX = surfaceWidth - size.iWidth;
1062 FillRectangleL(aSurface, startPos, size, TRgb(0xff00ff));
1065 startPos.iY = surfaceHeight - size.iWidth;
1066 size.iWidth = surfaceWidth - 12;
1069 FillRectangleL(aSurface, startPos, size, TRgb(0xaaaaaa));
1074 FillRectangleL(aSurface, startPos, size, TRgb(0x000080));
1078 template <class TIntType> void
1079 DdaLine(TUint aX1, TUint aY1,TUint aX2,TUint aY2, TUint aPixPerScan, TIntType* aBuffer, TIntType aColor)
1085 { adx=-adx; sdx=-1; }
1086 TInt ady=dy,sdy=aPixPerScan;
1088 { ady=-ady; sdy=-aPixPerScan; }
1089 //This is simplistic integert DDA.
1090 //The vertical cases are handled by this 1/2 accumulator:
1091 // If adx is zero then we step in sdy indefinitely
1092 // If ady is zero then we step in sdx indefinitely
1095 TIntType* bufferend=aBuffer+aX2+aY2*aPixPerScan;
1096 aBuffer+=aX1+aY1*aPixPerScan;
1098 while (aBuffer!=bufferend)
1115 template <class TIntType> void
1116 FanFill(const TPoint& aInnerXY,TUint aPixPerScan, TIntType* aSurfacePtr, TIntType aLinesTL,
1117 TIntType aLinesBR, TIntType aLinesTR, TIntType aLinesBL)
1120 DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*180/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR);
1121 DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*372/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR);
1122 DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*591/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR);
1123 DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*859/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR);
1125 DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesTR);
1126 DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesTR);
1127 DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesTR);
1128 DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesTR);
1130 DdaLine(0,aInnerXY.iY,aInnerXY.iX*180/1024,0,aPixPerScan,aSurfacePtr,aLinesBL);
1131 DdaLine(0,aInnerXY.iY,aInnerXY.iX*372/1024,0,aPixPerScan,aSurfacePtr,aLinesBL);
1132 DdaLine(0,aInnerXY.iY,aInnerXY.iX*591/1024,0,aPixPerScan,aSurfacePtr,aLinesBL);
1133 DdaLine(0,aInnerXY.iY,aInnerXY.iX*859/1024,0,aPixPerScan,aSurfacePtr,aLinesBL);
1135 DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesBL);
1136 DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesBL);
1137 DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesBL);
1138 DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesBL);
1140 DdaLine(0,0,aInnerXY.iX*180/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL);
1141 DdaLine(0,0,aInnerXY.iX*372/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL);
1142 DdaLine(0,0,aInnerXY.iX*591/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL);
1143 DdaLine(0,0,aInnerXY.iX*859/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL);
1145 DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesTL);
1146 DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesTL);
1147 DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesTL);
1148 DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesTL);
1150 DdaLine(0,aInnerXY.iY-aInnerXY.iY*180/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1151 DdaLine(0,aInnerXY.iY-aInnerXY.iY*372/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1152 DdaLine(0,aInnerXY.iY-aInnerXY.iY*591/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1153 DdaLine(0,aInnerXY.iY-aInnerXY.iY*859/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1155 DdaLine(aInnerXY.iX-aInnerXY.iX*180/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1156 DdaLine(aInnerXY.iX-aInnerXY.iX*372/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1157 DdaLine(aInnerXY.iX-aInnerXY.iX*591/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1158 DdaLine(aInnerXY.iX-aInnerXY.iX*859/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1162 Fill the given surface with a fan of lines over a solid color.
1164 Similar to FillSurfaceL(), but with a fan of lines overlayed.
1165 One fan is drawn about the top-left, and second fan at bottom-right.
1166 The fan contains 8 segments.
1168 @param aSurface The surface to be filled.
1169 @param aColor The color to fill it with.
1170 @param aLines The color of the grid lines.
1172 void CSurfaceUtility::FanFillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor, const TRgb& aLinesTL, const TRgb& aLinesBR)
1174 FillSurfaceL(aSurface,aColor);
1175 RSurfaceManager::TInfoBuf infoBuf;
1176 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1178 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1179 TUint32 linesTL = 0;
1180 TUint32 linesBR = 0;
1181 TUint32 linesTR = 0;
1182 TUint32 linesBL = 0;
1183 TBool use16 = EFalse;
1184 TRgb rgbLinesTR(0,0,0);
1185 TRgb rgbLinesBL(255,255,255);
1187 switch (info.iPixelFormat)
1189 case EUidPixelFormatXRGB_8888:
1191 linesBR = aLinesBR.Color16MU();
1192 linesTL = aLinesTL.Color16MU();
1193 linesTR = rgbLinesTR.Color16MU();
1194 linesBL = rgbLinesBL.Color16MU();
1195 #ifdef ALPHA_FIX_24BIT
1196 linesBR |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1197 linesTL |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1198 linesTR |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1199 linesBL |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1203 case EUidPixelFormatARGB_8888:
1205 linesBR = aLinesBR.Color16MA();
1206 linesTL = aLinesTL.Color16MA();
1207 linesTR = rgbLinesTR.Color16MA();
1208 linesBL = rgbLinesBL.Color16MA();
1211 case EUidPixelFormatARGB_8888_PRE:
1213 linesBR = aLinesBR.Color16MAP();
1214 linesTL = aLinesTL.Color16MAP();
1215 linesTR = rgbLinesTR.Color16MAP();
1216 linesBL = rgbLinesBL.Color16MAP();
1219 case EUidPixelFormatXRGB_4444:
1220 case EUidPixelFormatARGB_4444:
1222 linesBR = aLinesBR.Color4K();
1223 linesTL = aLinesTL.Color4K();
1224 linesTR = rgbLinesTR.Color4K();
1225 linesBL = rgbLinesBL.Color4K();
1229 case EUidPixelFormatRGB_565:
1231 linesBR = aLinesBR.Color64K();
1232 linesTL = aLinesTL.Color64K();
1233 linesTR = rgbLinesTR.Color64K();
1234 linesBL = rgbLinesBL.Color64K();
1240 User::Leave(KErrNotSupported);
1244 if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
1246 User::Leave(KErrCorrupt);
1248 if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
1250 User::Leave(KErrNotReady);
1253 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1254 CleanupClosePushL(chunk);
1256 TInt offsetToFirstBuffer;
1257 User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
1258 TUint8* surfacePtr = chunk.Base() + offsetToFirstBuffer;
1259 TPoint innerXY(info.iSize.iWidth-1,info.iSize.iHeight-1);
1262 if ( info.iSize.iWidth*2>info.iStride)
1264 User::Leave(KErrOverflow);
1266 FanFill<TUint16>(innerXY,info.iStride/2,(TUint16*)surfacePtr,linesTL,linesBR,linesBL,linesTR);
1270 if ( info.iSize.iWidth*4>info.iStride)
1272 User::Leave(KErrOverflow);
1274 FanFill<TUint>(innerXY,info.iStride/4,(TUint*)surfacePtr,linesTL,linesBR,linesBL,linesTR);
1277 iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1279 CleanupStack::PopAndDestroy(/* chunk */);
1282 Fill the given surface with vertical line at the given position
1284 Similar to FillSurfaceL(), but with a vertical line overlayed.
1285 The position along the surface is given as a percentage from the left
1287 @param aSurface The surface to be filled.
1288 @param aColor The color to fill it with.
1289 @param aLine The color of the line.
1290 @param aPosition Position of the vertical line given as a percentage across the surface from the left edge
1292 void CSurfaceUtility::LineFillSurfaceL(TSurfaceId& aSurface, const TRgb& aBackColor, const TRgb& aLineColor, TInt aPosition)
1294 if (aPosition<0 || aPosition>100)
1298 FillSurfaceL(aSurface,aBackColor);
1299 RSurfaceManager::TInfoBuf infoBuf;
1300 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1302 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1303 TUint32 lineColor = 0;
1304 TBool use16 = EFalse;
1306 switch (info.iPixelFormat)
1308 case EUidPixelFormatXRGB_8888:
1310 lineColor = aLineColor.Color16MU();
1311 #ifdef ALPHA_FIX_24BIT
1312 lineColor |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1316 case EUidPixelFormatARGB_8888:
1318 lineColor = aLineColor.Color16MA();
1321 case EUidPixelFormatARGB_8888_PRE:
1323 lineColor = aLineColor.Color16MAP();
1326 case EUidPixelFormatXRGB_4444:
1327 case EUidPixelFormatARGB_4444:
1329 lineColor = aLineColor.Color4K();
1333 case EUidPixelFormatRGB_565:
1335 lineColor = aLineColor.Color64K();
1341 User::Leave(KErrNotSupported);
1346 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1348 TInt offsetToFirstBuffer;
1349 User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
1350 TUint8* surfacePtr = chunk.Base() + offsetToFirstBuffer;
1353 DdaLine<TUint16>((info.iSize.iWidth*aPosition)/100,0,(info.iSize.iWidth*aPosition)/100,
1354 info.iSize.iHeight-1,info.iStride/2,(TUint16*)surfacePtr,lineColor);
1358 DdaLine<TUint>((info.iSize.iWidth*aPosition)/100,0,(info.iSize.iWidth*aPosition)/100,
1359 info.iSize.iHeight-1,info.iStride/4,(TUint*)surfacePtr,lineColor);
1364 iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1367 * Generates a bitmap equivalent to the surface.
1368 * Can reuse an existing bitmap or create a new bitmap.
1369 * The existing bitmap must be an exact match (eg previously generated by this method)
1371 CFbsBitmap* CSurfaceUtility::EquivalentBitmapL(TSurfaceId& aSurface,CFbsBitmap* aCopyToMayBeNull)
1373 RSurfaceManager::TInfoBuf infoBuf;
1374 RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1376 User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1377 TInt bytesPerPixel=0;
1378 TDisplayMode bitmapMode = ENone;
1379 switch (info.iPixelFormat)
1381 case EUidPixelFormatXRGB_8888:
1383 bitmapMode = EColor16MU;
1387 case EUidPixelFormatARGB_8888:
1389 bitmapMode=EColor16MA;
1393 case EUidPixelFormatARGB_8888_PRE:
1395 bitmapMode=EColor16MAP;
1399 case EUidPixelFormatXRGB_4444:
1400 case EUidPixelFormatARGB_4444:
1402 bitmapMode=EColor4K;
1406 case EUidPixelFormatRGB_565:
1408 bitmapMode=EColor64K;
1414 User::Leave(KErrNotSupported);
1418 CFbsBitmap* retVal=NULL;
1419 if (aCopyToMayBeNull)
1421 retVal=aCopyToMayBeNull;
1422 if (retVal->SizeInPixels()!=info.iSize)
1423 User::Leave(KErrCorrupt);
1424 if (retVal->DisplayMode()!=bitmapMode)
1425 User::Leave(KErrCorrupt);
1429 retVal=new CFbsBitmap;
1430 CleanupStack::PushL(retVal);
1431 User::LeaveIfError(retVal->Create(info.iSize,bitmapMode));
1434 CleanupClosePushL(chunk);
1435 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1436 TInt offsetToFirstBuffer;
1437 User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
1438 TUint8* surfacePtr = chunk.Base() + offsetToFirstBuffer;
1439 TUint8* bitmapPtr = (TUint8*)retVal->DataAddress();
1440 TInt copyBytes=info.iSize.iWidth*bytesPerPixel;
1441 for (TInt y=0;y<info.iSize.iHeight;y++)
1443 Mem::Copy(bitmapPtr,surfacePtr,copyBytes);
1444 surfacePtr+=info.iStride;
1445 bitmapPtr+=retVal->DataStride();
1447 CleanupStack::PopAndDestroy(&chunk);
1448 if (!aCopyToMayBeNull)
1449 CleanupStack::Pop(retVal);
1456 As well as destroying the surface, it is removed from the set held for
1457 destruction during tear down.
1459 @param aSurface The surface to be destroyed.
1461 void CSurfaceUtility::DestroySurface(TSurfaceId& aSurface)
1463 TInt index = iSurfaces.Find(aSurface);
1465 if (index != KErrNotFound)
1467 iSurfaces.Remove(index);
1470 TInt err = iManager.CloseSurface(aSurface);
1472 LOG(("Error closing surfaces: 0x%X\n", err));
1477 Submit an update to a surface to the update server.
1479 @param aScreenNumber The screen to be updated where the surface is shown.
1480 @param aSurface The surface which has been updated.
1481 @param aRegion The area of the surface affected, or NULL for all of it.*/
1482 void CSurfaceUtility::SubmitUpdate(TInt /* aScreenNumber */, const TSurfaceId& aSurface, const TRegion* aRegion,TInt aBufferNumber)
1484 TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, aBufferNumber, aRegion);
1486 LOG(("Error submitting update: 0x%X\n", err));
1490 Map and submit an update to a surface to the update server.
1492 @param aChunk The chunk of memory to be mapped
1493 @param aScreenNumber The screen to be updated where the surface is shown.
1494 @param aSurface The surface which has been updated.
1495 @param aRegion The area of the surface affected, or NULL for all of it.*/
1496 void CSurfaceUtility::MapAndSubmitUpdateL(RChunk& aChunk,
1497 TInt /* aScreenNumber */,
1498 const TSurfaceId& aSurface,
1499 const TRegion* aRegion)
1501 User::LeaveIfError(iManager.MapSurface(aSurface, aChunk));
1503 TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, aRegion);
1505 LOG(("Error submitting update: 0x%X\n", err));
1508 void CSurfaceUtility::MapSurfaceL(const TSurfaceId& aSurface, RChunk& aChunk)
1510 User::LeaveIfError(iManager.MapSurface(aSurface, aChunk));
1513 void CSurfaceUtility::CopyBitmapToSurfaceL(TSurfaceId& aSurface, const CFbsBitmap& aBitmap)
1515 TSize size = SurfaceSize(aSurface);
1517 TDisplayMode bmpFormat = aBitmap.DisplayMode();
1518 TInt stride = size.iWidth * 4; // Default to four bytes per pixel
1521 User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1522 CleanupClosePushL(chunk);
1524 TInt offsetToFirstBuffer;
1525 User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
1527 // Copy the data from the bitmap into the surface.
1529 TUint8 *pSurfStart = chunk.Base() + offsetToFirstBuffer;
1530 for (start.iY = 0; start.iY < size.iHeight; start.iY++)
1532 // Set up a descriptor for the current line in the surface and get pixels.
1533 TPtr8 ptr(pSurfStart + start.iY * stride, stride);
1534 aBitmap.GetScanLine(ptr, start, size.iWidth, bmpFormat);
1537 TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1540 LOG(("Error submitting update: 0x%X\n", err));
1543 CleanupStack::PopAndDestroy(/* chunk */);