1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicstest/uibench/s60/src/surfaceutility.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1784 @@
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 +#include <BitmapTransforms.h>
1.27 +
1.28 +//_LIT(KFileName,"surfacemanager");
1.29 +
1.30 +CSurfaceUtility::CSurfaceUtility(CSurfaceUtility* aClone/*=NULL*/)
1.31 + : iSurfaces(aClone?&(aClone->iSurfaces):NULL)
1.32 + {
1.33 + }
1.34 +
1.35 +CSurfaceUtility* CSurfaceUtility::NewL(CSurfaceUtility* aClone/*=NULL*/)
1.36 + {
1.37 + CSurfaceUtility* utility = new (ELeave)CSurfaceUtility(aClone);
1.38 + CleanupStack::PushL(utility);
1.39 + utility->ConstructL();
1.40 + CleanupStack::Pop(utility);
1.41 + return utility;
1.42 + }
1.43 +
1.44 +void CSurfaceUtility::ConstructL()
1.45 + {
1.46 + TInt r = iManager.Open();
1.47 + if (r != KErrNone)
1.48 + {
1.49 + LOG(("Surface manager failed to open: %d", r));
1.50 + User::Leave(r);
1.51 + }
1.52 +
1.53 + r = iSurfaceUpdateSession.Connect();
1.54 + if (r != KErrNone)
1.55 + {
1.56 + LOG(("Failed to connect to update server: %d", r));
1.57 + User::Leave(r);
1.58 + }
1.59 + }
1.60 +
1.61 +CSurfaceUtility::~CSurfaceUtility()
1.62 + {
1.63 + DestroyAll();
1.64 +
1.65 + iSurfaces.Close();
1.66 +
1.67 + iManager.Close();
1.68 +
1.69 + iSurfaceUpdateSession.Close();
1.70 +
1.71 + // the following call is needed because of a bug in CImageDecoder that
1.72 + // leaks heap memory
1.73 + REComSession::FinalClose();
1.74 + }
1.75 +
1.76 +TBool CSurfaceUtility::DestroyAll()
1.77 + {
1.78 + TInt err = KErrNone;
1.79 + TInt jj = iSurfaces.Count() - 1;
1.80 + if (jj<0)
1.81 + return EFalse;
1.82 + for (; jj >= 0; jj--)
1.83 + {
1.84 + err = iManager.CloseSurface(iSurfaces[jj]);
1.85 + if (err!=KErrNone)
1.86 + {
1.87 + LOG(("Error closing surface: 0x%X\n", err));
1.88 + }
1.89 + }
1.90 + iSurfaces.Reset();
1.91 + return ETrue;
1.92 + }
1.93 +
1.94 +/***************************************
1.95 + * The aim of the THeapSurfaceArray is to locally switch in the specified heap for any array operation
1.96 + ***************************************/
1.97 +
1.98 +CSurfaceUtility::RHeapSurfaceArray::RHeapSurfaceArray(RHeapSurfaceArray* aUseExternalArray)
1.99 + : iUseArray(aUseExternalArray?aUseExternalArray->iUseArray:&this->iLocalArray),
1.100 + iExternalHeapRef(aUseExternalArray?aUseExternalArray->iExternalHeapRef:User::Heap())
1.101 + {
1.102 +
1.103 + }
1.104 +/************************************
1.105 + * The following methods have been used by the surfaceutility... some require the heap wrapping, and some don't
1.106 + * I actually need three different startegies (count em) for 7 methods...
1.107 + * Some methods only read the existing objects, so don't need a heap swap at all
1.108 + * Leaving methods have to use PopAndDestroy strategy to restore the heap on leaving or success
1.109 + * Non-leaving methods must not call PushL, so directly make SwitchHeap calls!
1.110 + ************************************/
1.111 +
1.112 +// PopAndDestroy method to restore the heap
1.113 +/*static*/ void CSurfaceUtility::RHeapSurfaceArray::PopHeap(void* aHeapPtr)
1.114 + {
1.115 + RHeap* heapPtr=(RHeap*)aHeapPtr;
1.116 + User::SwitchHeap(heapPtr);
1.117 + }
1.118 +
1.119 +// Switches and pushes the previous heap so it can be restored with PopAndDestroy
1.120 +/*static*/ void CSurfaceUtility::RHeapSurfaceArray::SwitchHeapLC(RHeap* aNewHeap)
1.121 + {
1.122 + CleanupStack::PushL(TCleanupItem(PopHeap,NULL));
1.123 + CleanupStack::PushL(TCleanupItem(PopHeap,NULL));
1.124 + CleanupStack::PushL(TCleanupItem(PopHeap,NULL));
1.125 + CleanupStack::Pop(3);
1.126 + RHeap* oldHeap=User::SwitchHeap(aNewHeap);
1.127 + delete new char;
1.128 + CleanupStack::PushL(TCleanupItem(PopHeap,oldHeap));
1.129 + }
1.130 +
1.131 +
1.132 +TSurfaceId& CSurfaceUtility::RHeapSurfaceArray::operator[](TUint aIndex)
1.133 + {
1.134 + return iUseArray->operator[](aIndex);
1.135 + }
1.136 +// Close only closes the local array, while Reset resets the active array (may be external)
1.137 +void CSurfaceUtility::RHeapSurfaceArray::Close()
1.138 + {
1.139 + RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef);
1.140 + iLocalArray.Close();
1.141 + User::SwitchHeap(oldHeap);
1.142 + }
1.143 +TInt CSurfaceUtility::RHeapSurfaceArray::Count() const
1.144 + {
1.145 + return iUseArray->Count();
1.146 + }
1.147 +// Close only closes the local array, while Reset resets the active array (may be external)
1.148 +inline void CSurfaceUtility::RHeapSurfaceArray::Reset()
1.149 + {
1.150 + RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef);
1.151 + iUseArray->Reset();
1.152 + User::SwitchHeap(oldHeap);
1.153 + }
1.154 +void CSurfaceUtility::RHeapSurfaceArray::AppendL(const TSurfaceId &anEntry)
1.155 + {
1.156 + SwitchHeapLC(&iExternalHeapRef);
1.157 + iUseArray->AppendL(anEntry);
1.158 + CleanupStack::PopAndDestroy();
1.159 + }
1.160 +TInt CSurfaceUtility::RHeapSurfaceArray::Find(const TSurfaceId &anEntry) const
1.161 + {
1.162 + return iUseArray->Find(anEntry);
1.163 + }
1.164 +void CSurfaceUtility::RHeapSurfaceArray::Remove(TInt anIndex)
1.165 + {
1.166 + RHeap* oldHeap=User::SwitchHeap(&iExternalHeapRef);
1.167 + iUseArray->Remove(anIndex);
1.168 + User::SwitchHeap(oldHeap);
1.169 + }
1.170 +
1.171 +
1.172 +
1.173 +
1.174 +/**
1.175 +Cleanup stack helper object, holding references to both utility and surface, so
1.176 +that the standard Close() semantics can be used.
1.177 +*/
1.178 +class TSurfaceCleanup
1.179 + {
1.180 +public:
1.181 + TSurfaceCleanup(CSurfaceUtility& aUtility, TSurfaceId& aSurface)
1.182 + : iUtility(aUtility), iSurface(aSurface)
1.183 + {}
1.184 + void Close()
1.185 + {
1.186 + // Removes the surface from the list of surfaces to clean up, and closes
1.187 + // the surface reference.
1.188 + iUtility.DestroySurface(iSurface);
1.189 + }
1.190 +private:
1.191 + CSurfaceUtility& iUtility;
1.192 + TSurfaceId& iSurface;
1.193 + };
1.194 +
1.195 +/**
1.196 +Read the given image file into a new surface.
1.197 +
1.198 +@param aFileName The name of the image file.
1.199 +@param aSurface Filled with the surface ID for the surface containing the pixels.
1.200 +*/
1.201 +void CSurfaceUtility::CreateSurfaceFromFileL(const TDesC& aFileName, TSurfaceId& aSurface)
1.202 + {
1.203 + RFs fs;
1.204 +
1.205 + User::LeaveIfError(fs.Connect());
1.206 + CleanupClosePushL(fs);
1.207 + CImageDecoder* decoder = CImageDecoder::FileNewL(fs, aFileName, CImageDecoder::EOptionAlwaysThread);
1.208 + CleanupStack::PushL(decoder);
1.209 +
1.210 + const TFrameInfo& info = decoder->FrameInfo();
1.211 +
1.212 + TSize size = info.iOverallSizeInPixels;
1.213 + TInt stride = size.iWidth << 2; // Default to four bytes per pixel
1.214 + TDisplayMode bmpFormat = info.iFrameDisplayMode;
1.215 + TUidPixelFormat pixelFormat = EUidPixelFormatUnknown;
1.216 +
1.217 + switch (bmpFormat)
1.218 + {
1.219 + case EGray2:
1.220 + case EGray4:
1.221 + case EGray16:
1.222 + case EGray256:
1.223 + case EColor16:
1.224 + case EColor256:
1.225 + case EColor16M:
1.226 + case EColor16MU:
1.227 + {
1.228 + bmpFormat = EColor16MU;
1.229 + pixelFormat = EUidPixelFormatXRGB_8888;
1.230 + break;
1.231 + }
1.232 + case EColor4K:
1.233 + {
1.234 + stride = size.iWidth << 1;
1.235 + pixelFormat = EUidPixelFormatXRGB_4444;
1.236 + break;
1.237 + }
1.238 + case EColor64K:
1.239 + {
1.240 + stride = size.iWidth << 1;
1.241 + pixelFormat = EUidPixelFormatRGB_565;
1.242 + break;
1.243 + }
1.244 + case EColor16MA:
1.245 + {
1.246 + pixelFormat = EUidPixelFormatARGB_8888;
1.247 + break;
1.248 + }
1.249 + case EColor16MAP:
1.250 + {
1.251 + pixelFormat = EUidPixelFormatARGB_8888_PRE;
1.252 + break;
1.253 + }
1.254 + default:
1.255 + {
1.256 + LOG(("Unsupported display mode: %d", bmpFormat));
1.257 + User::Leave(KErrNotSupported);
1.258 + break;
1.259 + }
1.260 + }
1.261 +
1.262 + // Create an intermediary bitmap for decoding into
1.263 + CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
1.264 + CleanupStack::PushL(bitmap);
1.265 + User::LeaveIfError(bitmap->Create(size, info.iFrameDisplayMode));
1.266 +
1.267 + // Create the final surface.
1.268 + aSurface = CreateSurfaceL(size, pixelFormat, stride);
1.269 + TSurfaceCleanup surfaceCleanup(*this, aSurface);
1.270 + CleanupClosePushL(surfaceCleanup);
1.271 +
1.272 + RChunk chunk;
1.273 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.274 + CleanupClosePushL(chunk);
1.275 +
1.276 + // Convert the image file into a Symbian bitmap
1.277 + TRequestStatus status;
1.278 + decoder->Convert(&status, *bitmap);
1.279 + User::WaitForRequest(status);
1.280 + User::LeaveIfError(status.Int());
1.281 +
1.282 + // Copy the data from the bitmap into the surface.
1.283 + TPoint start;
1.284 + for (start.iY = 0; start.iY < size.iHeight; start.iY++)
1.285 + {
1.286 + // Set up a descriptor for the current line in the surface and get pixels.
1.287 + TPtr8 ptr(chunk.Base() + start.iY * stride, stride);
1.288 + bitmap->GetScanLine(ptr, start, size.iWidth, bmpFormat);
1.289 + }
1.290 +
1.291 + CleanupStack::PopAndDestroy(/* chunk */);
1.292 + CleanupStack::Pop(/* surfaceCleanup */);
1.293 + CleanupStack::PopAndDestroy(bitmap);
1.294 + CleanupStack::PopAndDestroy(decoder);
1.295 + CleanupStack::PopAndDestroy(/* fs */);
1.296 + }
1.297 +
1.298 +void CSurfaceUtility::CopyBitmapSurfaceL(const CFbsBitmap* aBitmap, TSurfaceId& aSurface)
1.299 + {
1.300 + RChunk chunk;
1.301 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.302 + CleanupClosePushL(chunk);
1.303 + TSize bitmapSize = aBitmap->SizeInPixels();
1.304 + TSize size = SurfaceSize(aSurface);
1.305 + TInt stride = size.iWidth*4; // Default to four bytes per pixel
1.306 +
1.307 + // Copy the data from the bitmap into the surface.
1.308 + TPoint start;
1.309 + for (start.iY = 0; start.iY < bitmapSize.iHeight; start.iY++)
1.310 + {
1.311 + // Set up a descriptor for the current line in the surface and get pixels.
1.312 + TPtr8 ptr(chunk.Base() + start.iY * stride, stride);
1.313 + aBitmap->GetScanLine(ptr, start, bitmapSize.iWidth, EColor16MU);
1.314 + }
1.315 + CleanupStack::PopAndDestroy(/* chunk */);
1.316 +
1.317 + }
1.318 +/**
1.319 +Copy the bitmap from a file to a surface.
1.320 +
1.321 +@param aFileName The name of the image file.
1.322 +@param aSurface Filled with the surface ID for the surface containing the pixels.
1.323 +*/
1.324 +void CSurfaceUtility::CopyBitmapFromFileToSurfaceL(const TDesC& aFileName, const TSurfaceId& aSurface)
1.325 + {
1.326 + RFs fs;
1.327 +
1.328 + User::LeaveIfError(fs.Connect());
1.329 + CleanupClosePushL(fs);
1.330 + CImageDecoder* decoder = CImageDecoder::FileNewL(fs, aFileName, CImageDecoder::EOptionAlwaysThread);
1.331 + CleanupStack::PushL(decoder);
1.332 +
1.333 + const TFrameInfo& info = decoder->FrameInfo();
1.334 +
1.335 + TSize size = SurfaceSize(aSurface);
1.336 + TDisplayMode bmpFormat = info.iFrameDisplayMode;
1.337 + TInt stride = size.iWidth << 2; // Default to four bytes per pixel
1.338 +
1.339 + // Create an intermediary bitmap for decoding into
1.340 + CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
1.341 + CleanupStack::PushL(bitmap);
1.342 + User::LeaveIfError(bitmap->Create(size, info.iFrameDisplayMode));
1.343 +
1.344 + RChunk chunk;
1.345 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.346 + CleanupClosePushL(chunk);
1.347 +
1.348 + // Convert the image file into a Symbian bitmap
1.349 + TRequestStatus status;
1.350 + decoder->Convert(&status, *bitmap);
1.351 + User::WaitForRequest(status);
1.352 + User::LeaveIfError(status.Int());
1.353 +
1.354 + // Copy the data from the bitmap into the surface.
1.355 + TPoint start;
1.356 + for (start.iY = 0; start.iY < size.iHeight; start.iY++)
1.357 + {
1.358 + // Set up a descriptor for the current line in the surface and get pixels.
1.359 + TPtr8 ptr(chunk.Base() + start.iY * stride, stride);
1.360 + bitmap->GetScanLine(ptr, start, size.iWidth, bmpFormat);
1.361 + }
1.362 +
1.363 + CleanupStack::PopAndDestroy(/* chunk */);
1.364 + CleanupStack::PopAndDestroy(bitmap);
1.365 + CleanupStack::PopAndDestroy(decoder);
1.366 + CleanupStack::PopAndDestroy(/* fs */);
1.367 + }
1.368 +
1.369 +/**
1.370 +Copy the bitmap from a file to a surface scaling the original image to cover the entire surface.
1.371 +
1.372 +@param aFileName The name of the image file.
1.373 +@param aSurface Filled with the surface ID for the surface containing the pixels.
1.374 +*/
1.375 +void CSurfaceUtility::ScaleBitmapFromFileToSurfaceL(const TDesC& aFileName, const TSurfaceId& aSurface)
1.376 + {
1.377 +
1.378 + RFs fs;
1.379 + User::LeaveIfError(fs.Connect());
1.380 + CleanupClosePushL(fs);
1.381 + CImageDecoder* decoder = CImageDecoder::FileNewL(fs, aFileName, CImageDecoder::EOptionAlwaysThread);
1.382 + CleanupStack::PushL(decoder);
1.383 +
1.384 + const TFrameInfo& info = decoder->FrameInfo();
1.385 +
1.386 + TSize size = SurfaceSize(aSurface);
1.387 + TInt stride = size.iWidth << 2; // Default to four bytes per pixel
1.388 +
1.389 + // Create an intermediary bitmap for decoding into
1.390 + CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
1.391 + CleanupStack::PushL(bitmap);
1.392 + User::LeaveIfError(bitmap->Create(info.iOverallSizeInPixels, info.iFrameDisplayMode));
1.393 +
1.394 + RChunk chunk;
1.395 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.396 + CleanupClosePushL(chunk);
1.397 + TUint8* surfacePixelData = chunk.Base() + PixelDataOffet(aSurface);
1.398 +
1.399 + // Convert the image file into a Symbian bitmap
1.400 + // CImageDecoder::EOptionAlwaysThread setting above avoids need for Active Object
1.401 + TRequestStatus status;
1.402 + decoder->Convert(&status, *bitmap);
1.403 + User::WaitForRequest(status);
1.404 + User::LeaveIfError(status.Int());
1.405 +
1.406 + // scale to fit surface
1.407 + CBitmapScaler* scaler = CBitmapScaler::NewL();
1.408 + CleanupStack::PushL(scaler);
1.409 + scaler->SetQualityAlgorithm(CBitmapScaler::EMaximumQuality);
1.410 +
1.411 + CActiveListener* activeListener = CActiveListener::NewLC();
1.412 + activeListener->Initialize();
1.413 + scaler->Scale(&activeListener->iStatus, *bitmap, size, EFalse);
1.414 + CActiveScheduler::Start();
1.415 +
1.416 + User::LeaveIfError(activeListener->iStatus.Int());
1.417 +
1.418 + // Copy the data from the bitmap into the surface.
1.419 + TPoint start;
1.420 + for (start.iY = 0; start.iY < size.iHeight; start.iY++)
1.421 + {
1.422 + // Set up a descriptor for the current line in the surface and get pixels.
1.423 + TPtr8 ptr(surfacePixelData + start.iY * stride, stride);
1.424 + bitmap->GetScanLine(ptr, start, size.iWidth, EColor16MA);
1.425 + }
1.426 + CleanupStack::PopAndDestroy(activeListener);
1.427 + CleanupStack::PopAndDestroy(scaler);
1.428 + CleanupStack::PopAndDestroy(/* chunk */);
1.429 + CleanupStack::PopAndDestroy(bitmap);
1.430 + CleanupStack::PopAndDestroy(decoder);
1.431 + CleanupStack::PopAndDestroy(/* fs */);
1.432 + }
1.433 +
1.434 +/**
1.435 +Get the size of a surface.
1.436 +
1.437 +@param aSurface The surface to get the size for.
1.438 +@return The size in pixels, or empty on failure.
1.439 +*/
1.440 +TSize CSurfaceUtility::SurfaceSize(const TSurfaceId& aSurface)
1.441 + {
1.442 + RSurfaceManager::TInfoBuf infoBuf;
1.443 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.444 +
1.445 + if (iManager.SurfaceInfo(aSurface, infoBuf) == KErrNone)
1.446 + {
1.447 + return info.iSize;
1.448 + }
1.449 +
1.450 + return TSize();
1.451 + }
1.452 +
1.453 +/**
1.454 +Get the offset into the chunk of the start of pixel data.
1.455 +
1.456 +@param aSurface The surface to get the size for.
1.457 +@return The offset bytes, or empty on failure.
1.458 +*/
1.459 +TInt CSurfaceUtility::PixelDataOffet(const TSurfaceId& aSurface)
1.460 + {
1.461 + TInt offsetToFirstBuffer = 0;
1.462 + iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer);
1.463 +
1.464 + return offsetToFirstBuffer;
1.465 + }
1.466 +
1.467 +
1.468 +/**
1.469 +Create a surface using the surface manager.
1.470 +
1.471 +Stores the ID for tear down, as well as returning it.
1.472 +
1.473 +@param aSize Dimensions of the surface.
1.474 +@param aPixelFormat UID of the pixel format.
1.475 +@param aStride Stride value for the surface (usually bytes per pixel * width)
1.476 +@leave May leave due to lack of memory.
1.477 +@return New surface's ID.
1.478 +*/
1.479 +TSurfaceId CSurfaceUtility::CreateSurfaceL(const TSize& aSize, TUidPixelFormat aPixelFormat, TInt aStride, TInt aBuffers)
1.480 + {
1.481 + RSurfaceManager::TSurfaceCreationAttributesBuf bf;
1.482 + RSurfaceManager::TSurfaceCreationAttributes& b = bf();
1.483 +
1.484 + b.iSize.iWidth = aSize.iWidth;
1.485 + b.iSize.iHeight = aSize.iHeight;
1.486 + b.iBuffers = aBuffers; // number of buffers in the surface
1.487 + b.iPixelFormat = aPixelFormat;
1.488 + b.iStride = aStride; // Number of bytes between start of one line and start of next
1.489 + b.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data
1.490 + b.iAlignment = 4; // alignment, 1,2,4,8 byte aligned
1.491 + b.iContiguous=EFalse;
1.492 +
1.493 + TSurfaceId surface = TSurfaceId::CreateNullId();
1.494 +
1.495 + User::LeaveIfError(iManager.CreateSurface(bf, surface));
1.496 + iSurfaces.AppendL(surface);
1.497 + return surface;
1.498 + }
1.499 +
1.500 +
1.501 +/**
1.502 +Fill the given surface with a color.
1.503 +
1.504 +@param aSurface The surface to be filled.
1.505 +@param aColor The color to fill it with.
1.506 +*/
1.507 +void CSurfaceUtility::FillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor)
1.508 + {
1.509 + RSurfaceManager::TInfoBuf infoBuf;
1.510 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.511 +
1.512 + User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1.513 + TUint32 color = 0;
1.514 + TBool use16 = EFalse;
1.515 +
1.516 + if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
1.517 + {
1.518 + User::Leave(KErrCorrupt);
1.519 + }
1.520 + if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
1.521 + {
1.522 + User::Leave(KErrNotReady);
1.523 + }
1.524 +
1.525 + switch (info.iPixelFormat)
1.526 + {
1.527 + case EUidPixelFormatXRGB_8888:
1.528 + {
1.529 + color = aColor.Color16MU();
1.530 +#ifdef ALPHA_FIX_24BIT
1.531 + color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1.532 +#endif
1.533 + break;
1.534 + }
1.535 + case EUidPixelFormatARGB_8888:
1.536 + {
1.537 + color = aColor.Color16MA();
1.538 + break;
1.539 + }
1.540 + case EUidPixelFormatARGB_8888_PRE:
1.541 + {
1.542 + color = aColor.Color16MAP();
1.543 + break;
1.544 + }
1.545 + case EUidPixelFormatXRGB_4444:
1.546 + case EUidPixelFormatARGB_4444:
1.547 + {
1.548 + color = aColor.Color4K();
1.549 + use16 = ETrue;
1.550 + break;
1.551 + }
1.552 + case EUidPixelFormatRGB_565:
1.553 + {
1.554 + color = aColor.Color64K();
1.555 + use16 = ETrue;
1.556 + break;
1.557 + }
1.558 + default:
1.559 + {
1.560 + User::Leave(KErrNotSupported);
1.561 + break;
1.562 + }
1.563 + }
1.564 +
1.565 + RChunk chunk;
1.566 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.567 +
1.568 + TUint8* surfacePtr = chunk.Base();
1.569 + TUint8* linePtr = surfacePtr;
1.570 +
1.571 + if (use16)
1.572 + {
1.573 + if ( info.iSize.iWidth*2>info.iStride)
1.574 + {
1.575 + User::Leave(KErrOverflow);
1.576 + }
1.577 + TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
1.578 +
1.579 + // Fill first line
1.580 + for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
1.581 + {
1.582 + ptr[xx] = (TUint16)color;
1.583 + }
1.584 + }
1.585 + else
1.586 + {
1.587 + if ( info.iSize.iWidth*4>info.iStride)
1.588 + {
1.589 + User::Leave(KErrOverflow);
1.590 + }
1.591 + TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
1.592 +
1.593 + // Fill first line
1.594 + for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
1.595 + {
1.596 + ptr[xx] = color;
1.597 + }
1.598 + }
1.599 +
1.600 + // Now copy that to the other lines
1.601 + for (TInt yy = 1; yy < info.iSize.iHeight; yy++)
1.602 + {
1.603 + linePtr += info.iStride;
1.604 + Mem::Move(linePtr, surfacePtr, info.iStride);
1.605 + }
1.606 +
1.607 + chunk.Close();
1.608 +
1.609 + TInt err = iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1.610 + if (err!=KErrNone)
1.611 + LOG(("Error submitting update: 0x%X\n", err));
1.612 + }
1.613 +
1.614 +/**
1.615 +Fill the given memory chunk with a color.
1.616 +
1.617 +@param aSurface The surface to be filled.
1.618 +@param aChunk The surface to be filled.
1.619 +@param aColor The color to fill it with.
1.620 +*/
1.621 +void CSurfaceUtility::FillChunkL(TSurfaceId& aSurface, RChunk& aChunk, const TRgb& aColor, TInt aBufferNumber)
1.622 + {
1.623 + RSurfaceManager::TInfoBuf infoBuf;
1.624 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.625 +
1.626 + User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1.627 + TUint32 color = 0;
1.628 + TBool use16 = EFalse;
1.629 +
1.630 + if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
1.631 + {
1.632 + User::Leave(KErrCorrupt);
1.633 + }
1.634 + if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
1.635 + {
1.636 + User::Leave(KErrNotReady);
1.637 + }
1.638 +
1.639 + switch (info.iPixelFormat)
1.640 + {
1.641 + case EUidPixelFormatXRGB_8888:
1.642 + {
1.643 + color = aColor.Color16MU();
1.644 +#ifdef ALPHA_FIX_24BIT
1.645 + color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1.646 +#endif
1.647 + break;
1.648 + }
1.649 + case EUidPixelFormatARGB_8888:
1.650 + {
1.651 + color = aColor.Color16MA();
1.652 + break;
1.653 + }
1.654 + case EUidPixelFormatARGB_8888_PRE:
1.655 + {
1.656 + color = aColor.Color16MAP();
1.657 + break;
1.658 + }
1.659 + case EUidPixelFormatXRGB_4444:
1.660 + case EUidPixelFormatARGB_4444:
1.661 + {
1.662 + color = aColor.Color4K();
1.663 + use16 = ETrue;
1.664 + break;
1.665 + }
1.666 + case EUidPixelFormatRGB_565:
1.667 + {
1.668 + color = aColor.Color64K();
1.669 + use16 = ETrue;
1.670 + break;
1.671 + }
1.672 + default:
1.673 + {
1.674 + User::Leave(KErrNotSupported);
1.675 + break;
1.676 + }
1.677 + }
1.678 +
1.679 + User::LeaveIfError(iManager.MapSurface(aSurface, aChunk));
1.680 +
1.681 + TInt offsetToFirstBuffer;
1.682 + User::LeaveIfError(iManager.GetBufferOffset(aSurface, 0, offsetToFirstBuffer));
1.683 + TInt offsetToBufferNumber;
1.684 + User::LeaveIfError(iManager.GetBufferOffset(aSurface, aBufferNumber, offsetToBufferNumber));
1.685 +
1.686 + TUint8* chunkPtr = aChunk.Base() + offsetToFirstBuffer;
1.687 + TUint8* linePtr = aChunk.Base() + offsetToBufferNumber;
1.688 + TUint8* surfPlanePtr = linePtr;
1.689 +
1.690 + if (use16)
1.691 + {
1.692 + if ( info.iSize.iWidth*2>info.iStride)
1.693 + {
1.694 + aChunk.Close();
1.695 + User::Leave(KErrOverflow);
1.696 + }
1.697 + TUint16* ptr = reinterpret_cast<TUint16*>(surfPlanePtr);
1.698 +
1.699 + // Fill first line
1.700 + for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
1.701 + {
1.702 + ptr[xx] = (TUint16)color;
1.703 + }
1.704 + }
1.705 + else
1.706 + {
1.707 + if ( info.iSize.iWidth*4>info.iStride)
1.708 + {
1.709 + aChunk.Close();
1.710 + User::Leave(KErrOverflow);
1.711 + }
1.712 + TUint32* ptr = reinterpret_cast<TUint32*>(surfPlanePtr);
1.713 +
1.714 + // Fill first line
1.715 + for (TInt xx = 0; xx < info.iSize.iWidth; xx++)
1.716 + {
1.717 + ptr[xx] = color;
1.718 + }
1.719 + }
1.720 +
1.721 + // Now copy that to the other lines
1.722 + for (TInt yy = 1; yy < info.iSize.iHeight; yy++)
1.723 + {
1.724 + linePtr += info.iStride;
1.725 + Mem::Copy(linePtr, surfPlanePtr, info.iSize.iWidth * BytesPerPixelL(info.iPixelFormat));
1.726 + }
1.727 +
1.728 + aChunk.Close();
1.729 + }
1.730 +
1.731 +/**
1.732 +Fill a rectangle on the given surface.
1.733 +
1.734 +@param aSurface The surface to be filled.
1.735 +@param aStartPos Where to place the rectangle.
1.736 +@param aSize Size of the rectangle.
1.737 +@param aColor The colour to fill it with.
1.738 +*/
1.739 +void CSurfaceUtility::FillRectangleL(TSurfaceId& aSurface, TPoint& aStartPos, TSize& aSize, const TRgb& aColor)
1.740 + {
1.741 + RSurfaceManager::TInfoBuf infoBuf;
1.742 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.743 +
1.744 + User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1.745 + TUint32 color = 0;
1.746 + TBool use16 = EFalse;
1.747 +
1.748 + if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
1.749 + {
1.750 + User::Leave(KErrCorrupt);
1.751 + }
1.752 + if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
1.753 + {
1.754 + User::Leave(KErrNotReady);
1.755 + }
1.756 +
1.757 + switch (info.iPixelFormat)
1.758 + {
1.759 + case EUidPixelFormatXRGB_8888:
1.760 + {
1.761 + color = aColor.Color16MU();
1.762 +#ifdef ALPHA_FIX_24BIT
1.763 + color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1.764 +#endif
1.765 + break;
1.766 + }
1.767 + case EUidPixelFormatARGB_8888:
1.768 + {
1.769 + color = aColor.Color16MA();
1.770 + break;
1.771 + }
1.772 + case EUidPixelFormatARGB_8888_PRE:
1.773 + {
1.774 + color = aColor.Color16MAP();
1.775 + break;
1.776 + }
1.777 + case EUidPixelFormatXRGB_4444:
1.778 + case EUidPixelFormatARGB_4444:
1.779 + {
1.780 + color = aColor.Color4K();
1.781 + use16 = ETrue;
1.782 + break;
1.783 + }
1.784 + case EUidPixelFormatRGB_565:
1.785 + {
1.786 + color = aColor.Color64K();
1.787 + use16 = ETrue;
1.788 + break;
1.789 + }
1.790 + default:
1.791 + {
1.792 + User::Leave(KErrNotSupported);
1.793 + break;
1.794 + }
1.795 + }
1.796 +
1.797 + RChunk chunk;
1.798 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.799 +
1.800 + TUint8* surfacePtr = chunk.Base();
1.801 +
1.802 + // Check for out of bounds
1.803 + TBool validRect = ETrue;
1.804 + TInt surfaceWidth = info.iSize.iWidth;
1.805 + TInt surfaceHeight = info.iSize.iHeight;
1.806 +
1.807 + // Width and Height
1.808 + if ((aStartPos.iX + aSize.iWidth) > surfaceWidth)
1.809 + validRect = EFalse;
1.810 +
1.811 + if ((aStartPos.iY + aSize.iHeight) > surfaceHeight)
1.812 + validRect = EFalse;
1.813 +
1.814 + // Starting position
1.815 + if ((aStartPos.iX < 0) || (aStartPos.iY < 0))
1.816 + validRect = EFalse;
1.817 +
1.818 + if (!validRect)
1.819 + User::Leave(KErrOverflow);
1.820 +
1.821 + if (use16)
1.822 + {
1.823 + if ( info.iSize.iWidth*2>info.iStride)
1.824 + {
1.825 + User::Leave(KErrOverflow);
1.826 + }
1.827 +
1.828 + TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
1.829 +
1.830 + // Fill the rectangle
1.831 + TInt yPos = aStartPos.iY;
1.832 + TInt xPos = aStartPos.iX;
1.833 + for (TInt yy = 0; yy < aSize.iHeight; ++yy)
1.834 + {
1.835 + ptr = reinterpret_cast<TUint16*>(surfacePtr+(yPos*info.iStride));
1.836 + for (TInt xx = 0; xx < aSize.iWidth; ++xx)
1.837 + {
1.838 + ptr[xPos] = color;
1.839 + xPos++;
1.840 + }
1.841 + xPos = aStartPos.iX;
1.842 + yPos++;
1.843 + }
1.844 + }
1.845 + else
1.846 + {
1.847 + if ( info.iSize.iWidth*4>info.iStride)
1.848 + {
1.849 + User::Leave(KErrOverflow);
1.850 + }
1.851 +
1.852 + TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
1.853 +
1.854 + // Fill the rectangle
1.855 + TInt yPos = aStartPos.iY;
1.856 + TInt xPos = aStartPos.iX;
1.857 + for (TInt yy = 0; yy < aSize.iHeight; ++yy)
1.858 + {
1.859 + ptr = reinterpret_cast<TUint32*>(surfacePtr+(yPos*info.iStride));
1.860 + for (TInt xx = 0; xx < aSize.iWidth; ++xx)
1.861 + {
1.862 + ptr[xPos] = color;
1.863 + xPos++;
1.864 + }
1.865 + xPos = aStartPos.iX;
1.866 + yPos++;
1.867 + }
1.868 + }
1.869 +
1.870 + chunk.Close();
1.871 +
1.872 + TInt err = iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1.873 + if (err!=KErrNone)
1.874 + LOG(("Error submitting update: 0x%X\n", err));
1.875 + }
1.876 +
1.877 +/**
1.878 +Fill a rectangle on the given surface - does not submit update.
1.879 +
1.880 +@param aSurface The surface to be filled.
1.881 +@param aStartPos Where to place the rectangle.
1.882 +@param aSize Size of the rectangle.
1.883 +@param aColor The colour to fill it with.
1.884 +*/
1.885 +void CSurfaceUtility::FillRectangleNoUpdateL(TSurfaceId& aSurface, TPoint& aStartPos, TSize& aSize, const TRgb& aColor)
1.886 + {
1.887 + RSurfaceManager::TInfoBuf infoBuf;
1.888 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.889 +
1.890 + User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1.891 + TUint32 color = 0;
1.892 + TBool use16 = EFalse;
1.893 +
1.894 + if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
1.895 + {
1.896 + User::Leave(KErrCorrupt);
1.897 + }
1.898 + if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
1.899 + {
1.900 + User::Leave(KErrNotReady);
1.901 + }
1.902 +
1.903 + switch (info.iPixelFormat)
1.904 + {
1.905 + case EUidPixelFormatXRGB_8888:
1.906 + {
1.907 + color = aColor.Color16MU();
1.908 +#ifdef ALPHA_FIX_24BIT
1.909 + color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1.910 +#endif
1.911 + break;
1.912 + }
1.913 + case EUidPixelFormatARGB_8888:
1.914 + {
1.915 + color = aColor.Color16MA();
1.916 + break;
1.917 + }
1.918 + case EUidPixelFormatARGB_8888_PRE:
1.919 + {
1.920 + color = aColor.Color16MAP();
1.921 + break;
1.922 + }
1.923 + case EUidPixelFormatXRGB_4444:
1.924 + case EUidPixelFormatARGB_4444:
1.925 + {
1.926 + color = aColor.Color4K();
1.927 + use16 = ETrue;
1.928 + break;
1.929 + }
1.930 + case EUidPixelFormatRGB_565:
1.931 + {
1.932 + color = aColor.Color64K();
1.933 + use16 = ETrue;
1.934 + break;
1.935 + }
1.936 + default:
1.937 + {
1.938 + User::Leave(KErrNotSupported);
1.939 + break;
1.940 + }
1.941 + }
1.942 +
1.943 + RChunk chunk;
1.944 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.945 +
1.946 + TUint8* surfacePtr = chunk.Base();
1.947 +
1.948 + // Check for out of bounds
1.949 + TBool validRect = ETrue;
1.950 + TInt surfaceWidth = info.iSize.iWidth;
1.951 + TInt surfaceHeight = info.iSize.iHeight;
1.952 +
1.953 + // Width and Height
1.954 + if ((aStartPos.iX + aSize.iWidth) > surfaceWidth)
1.955 + validRect = EFalse;
1.956 +
1.957 + if ((aStartPos.iY + aSize.iHeight) > surfaceHeight)
1.958 + validRect = EFalse;
1.959 +
1.960 + // Starting position
1.961 + if ((aStartPos.iX < 0) || (aStartPos.iY < 0))
1.962 + validRect = EFalse;
1.963 +
1.964 + if (!validRect)
1.965 + User::Leave(KErrOverflow);
1.966 +
1.967 + if (use16)
1.968 + {
1.969 + if ( info.iSize.iWidth*2>info.iStride)
1.970 + {
1.971 + User::Leave(KErrOverflow);
1.972 + }
1.973 +
1.974 + TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
1.975 +
1.976 + // Fill the rectangle
1.977 + TInt yPos = aStartPos.iY;
1.978 + TInt xPos = aStartPos.iX;
1.979 + for (TInt yy = 0; yy < aSize.iHeight; ++yy)
1.980 + {
1.981 + ptr = reinterpret_cast<TUint16*>(surfacePtr+(yPos*info.iStride));
1.982 + for (TInt xx = 0; xx < aSize.iWidth; ++xx)
1.983 + {
1.984 + ptr[xPos] = color;
1.985 + xPos++;
1.986 + }
1.987 + xPos = aStartPos.iX;
1.988 + yPos++;
1.989 + }
1.990 + }
1.991 + else
1.992 + {
1.993 + if ( info.iSize.iWidth*4>info.iStride)
1.994 + {
1.995 + User::Leave(KErrOverflow);
1.996 + }
1.997 +
1.998 + TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
1.999 +
1.1000 + // Fill the rectangle
1.1001 + TInt yPos = aStartPos.iY;
1.1002 + TInt xPos = aStartPos.iX;
1.1003 + for (TInt yy = 0; yy < aSize.iHeight; ++yy)
1.1004 + {
1.1005 + ptr = reinterpret_cast<TUint32*>(surfacePtr+(yPos*info.iStride));
1.1006 + for (TInt xx = 0; xx < aSize.iWidth; ++xx)
1.1007 + {
1.1008 + ptr[xPos] = color;
1.1009 + xPos++;
1.1010 + }
1.1011 + xPos = aStartPos.iX;
1.1012 + yPos++;
1.1013 + }
1.1014 + }
1.1015 +
1.1016 + chunk.Close();
1.1017 +
1.1018 + }
1.1019 +
1.1020 +/**
1.1021 +Fill the given surface with a grid over a solid color.
1.1022 +
1.1023 +Similar to FillSurfaceL(), but with a grid overlayed. The pitch of the grid is
1.1024 +eight pixels.
1.1025 +
1.1026 +@param aSurface The surface to be filled.
1.1027 +@param aColor The color to fill it with.
1.1028 +@param aLines The color of the grid lines.
1.1029 +*/
1.1030 +void CSurfaceUtility::GridFillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor, const TRgb& aLines)
1.1031 + {
1.1032 + RSurfaceManager::TInfoBuf infoBuf;
1.1033 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.1034 +
1.1035 + User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1.1036 + TUint32 color = 0;
1.1037 + TUint32 lines = 0;
1.1038 + TBool use16 = EFalse;
1.1039 +
1.1040 + if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
1.1041 + {
1.1042 + User::Leave(KErrCorrupt);
1.1043 + }
1.1044 + if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
1.1045 + {
1.1046 + User::Leave(KErrNotReady);
1.1047 + }
1.1048 +
1.1049 + switch (info.iPixelFormat)
1.1050 + {
1.1051 + case EUidPixelFormatXRGB_8888:
1.1052 + {
1.1053 + color = aColor.Color16MU();
1.1054 + lines = aLines.Color16MU();
1.1055 +#ifdef ALPHA_FIX_24BIT
1.1056 + color |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1.1057 + lines |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1.1058 +#endif
1.1059 + break;
1.1060 + }
1.1061 + case EUidPixelFormatARGB_8888:
1.1062 + {
1.1063 + color = aColor.Color16MA();
1.1064 + lines = aLines.Color16MA();
1.1065 + break;
1.1066 + }
1.1067 + case EUidPixelFormatARGB_8888_PRE:
1.1068 + {
1.1069 + color = aColor.Color16MAP();
1.1070 + lines = aLines.Color16MAP();
1.1071 + break;
1.1072 + }
1.1073 + case EUidPixelFormatXRGB_4444:
1.1074 + case EUidPixelFormatARGB_4444:
1.1075 + {
1.1076 + color = aColor.Color4K();
1.1077 + lines = aLines.Color4K();
1.1078 + use16 = ETrue;
1.1079 + break;
1.1080 + }
1.1081 + case EUidPixelFormatRGB_565:
1.1082 + {
1.1083 + color = aColor.Color64K();
1.1084 + lines = aLines.Color64K();
1.1085 + use16 = ETrue;
1.1086 + break;
1.1087 + }
1.1088 + default:
1.1089 + {
1.1090 + User::Leave(KErrNotSupported);
1.1091 + break;
1.1092 + }
1.1093 + }
1.1094 +
1.1095 + RChunk chunk;
1.1096 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.1097 +
1.1098 + TUint8* surfacePtr = chunk.Base();
1.1099 + TUint8* linePtr = surfacePtr;
1.1100 +
1.1101 + if (use16)
1.1102 + {
1.1103 + if ( info.iSize.iWidth*2>info.iStride)
1.1104 + {
1.1105 + User::Leave(KErrOverflow);
1.1106 + }
1.1107 + TUint16* ptr = reinterpret_cast<TUint16*>(surfacePtr);
1.1108 +
1.1109 + // Fill first line
1.1110 + for (TInt xx1 = 0; xx1 < info.iSize.iWidth; xx1++)
1.1111 + {
1.1112 + ptr[xx1] = (TUint16)lines;
1.1113 + }
1.1114 +
1.1115 + // Fill second line
1.1116 + ptr = reinterpret_cast<TUint16*>(surfacePtr + info.iStride);
1.1117 + for (TInt xx2 = 0; xx2 < info.iSize.iWidth; xx2++)
1.1118 + {
1.1119 + // Vertical line every 8 pixels across
1.1120 + ptr[xx2] = (TUint16)((xx2 & 7) ? color : lines);
1.1121 + }
1.1122 + }
1.1123 + else
1.1124 + {
1.1125 + if ( info.iSize.iWidth*4>info.iStride)
1.1126 + {
1.1127 + User::Leave(KErrOverflow);
1.1128 + }
1.1129 + TUint32* ptr = reinterpret_cast<TUint32*>(surfacePtr);
1.1130 +
1.1131 + // Fill first line
1.1132 + for (TInt xx3 = 0; xx3 < info.iSize.iWidth; xx3++)
1.1133 + {
1.1134 + ptr[xx3] = lines;
1.1135 + }
1.1136 +
1.1137 + // Fill second line
1.1138 + ptr = reinterpret_cast<TUint32*>(surfacePtr + info.iStride);
1.1139 + for (TInt xx4 = 0; xx4 < info.iSize.iWidth; xx4++)
1.1140 + {
1.1141 + // Vertical line every 8 pixels across
1.1142 + ptr[xx4] = (xx4 & 7) ? color : lines;
1.1143 + }
1.1144 + }
1.1145 + linePtr += info.iStride;
1.1146 +
1.1147 + // Now copy that to the other lines
1.1148 + for (TInt yy = 2; yy < info.iSize.iHeight; yy++)
1.1149 + {
1.1150 + linePtr += info.iStride;
1.1151 + if (yy & 7)
1.1152 + {
1.1153 + // Copy second line
1.1154 + Mem::Move(linePtr, surfacePtr + info.iStride, info.iStride);
1.1155 + }
1.1156 + else
1.1157 + {
1.1158 + // Copy first line
1.1159 + Mem::Move(linePtr, surfacePtr, info.iStride);
1.1160 + }
1.1161 + }
1.1162 + chunk.Close();
1.1163 +
1.1164 + TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1.1165 + if (err!=KErrNone)
1.1166 + LOG(("Error submitting update: 0x%X\n", err));
1.1167 +
1.1168 + }
1.1169 +
1.1170 +
1.1171 +/**
1.1172 +Fill the given surface with a pattern suitable for automated testing.
1.1173 +
1.1174 +@param aSurface The surface to be filled.
1.1175 +*/
1.1176 +void CSurfaceUtility::PatternFillSurfaceL(TSurfaceId& aSurface)
1.1177 + {
1.1178 + RSurfaceManager::TInfoBuf infoBuf;
1.1179 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.1180 +
1.1181 + User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1.1182 +
1.1183 + // Fill the background
1.1184 + FillSurfaceL(aSurface, TRgb(0x00000000));
1.1185 +
1.1186 + TInt surfaceWidth = info.iSize.iWidth;
1.1187 + TInt surfaceHeight = info.iSize.iHeight;
1.1188 +
1.1189 + // Create the 4 rectangles in the corners
1.1190 + TPoint startPos(0,0);
1.1191 + TSize size(15,15);
1.1192 + TInt rectWidth = size.iWidth;
1.1193 + TInt rectHeight = size.iHeight;
1.1194 + // Top left
1.1195 + FillRectangleL(aSurface, startPos, size, TRgb(0x0000ff));
1.1196 +
1.1197 + // Top right
1.1198 + startPos.iX = surfaceWidth - rectWidth;
1.1199 + startPos.iY = 0;
1.1200 + FillRectangleL(aSurface, startPos, size, TRgb(0x00ff00));
1.1201 +
1.1202 + // Bottom left
1.1203 + startPos.iX = 0;
1.1204 + startPos.iY = surfaceHeight - rectHeight;
1.1205 + FillRectangleL(aSurface, startPos, size, TRgb(0x00ffff));
1.1206 +
1.1207 + // Bottom right
1.1208 + startPos.iX = surfaceWidth - rectWidth;
1.1209 + startPos.iY = surfaceHeight - rectHeight;
1.1210 + FillRectangleL(aSurface, startPos, size, TRgb(0xffffff));
1.1211 +
1.1212 + // Create the 4 side bars
1.1213 + startPos.iX = 0;
1.1214 + startPos.iY = 6;
1.1215 + size.iWidth = 5;
1.1216 + size.iHeight = surfaceHeight - 12;
1.1217 + // Left
1.1218 + FillRectangleL(aSurface, startPos, size, TRgb(0x808000));
1.1219 +
1.1220 + startPos.iX = surfaceWidth - size.iWidth;
1.1221 + startPos.iY = 6;
1.1222 + // Right
1.1223 + FillRectangleL(aSurface, startPos, size, TRgb(0xff00ff));
1.1224 +
1.1225 + startPos.iX = 6;
1.1226 + startPos.iY = surfaceHeight - size.iWidth;
1.1227 + size.iWidth = surfaceWidth - 12;
1.1228 + size.iHeight = 5;
1.1229 + // Top
1.1230 + FillRectangleL(aSurface, startPos, size, TRgb(0xaaaaaa));
1.1231 +
1.1232 + startPos.iX = 6;
1.1233 + startPos.iY = 0;
1.1234 + // Bottom
1.1235 + FillRectangleL(aSurface, startPos, size, TRgb(0x000080));
1.1236 + }
1.1237 +
1.1238 +
1.1239 +template <class TIntType> void
1.1240 +DdaLine(TUint aX1, TUint aY1,TUint aX2,TUint aY2, TUint aPixPerScan, TIntType* aBuffer, TIntType aColor)
1.1241 + {
1.1242 + TInt dx=aX2-aX1;
1.1243 + TInt dy=aY2-aY1;
1.1244 + TInt adx=dx,sdx=1;
1.1245 + if (adx<0)
1.1246 + { adx=-adx; sdx=-1; }
1.1247 + TInt ady=dy,sdy=aPixPerScan;
1.1248 + if (ady<0)
1.1249 + { ady=-ady; sdy=-aPixPerScan; }
1.1250 + //This is simplistic integert DDA.
1.1251 + //The vertical cases are handled by this 1/2 accumulator:
1.1252 + // If adx is zero then we step in sdy indefinitely
1.1253 + // If ady is zero then we step in sdx indefinitely
1.1254 + TInt accum=adx/2;
1.1255 +
1.1256 + TIntType* bufferend=aBuffer+aX2+aY2*aPixPerScan;
1.1257 + aBuffer+=aX1+aY1*aPixPerScan;
1.1258 + *aBuffer=aColor;
1.1259 + while (aBuffer!=bufferend)
1.1260 + {
1.1261 + if (accum>0)
1.1262 + {
1.1263 + accum-=ady;
1.1264 + aBuffer+=sdx;
1.1265 + }
1.1266 + else
1.1267 + {
1.1268 + accum+=adx;
1.1269 + aBuffer+=sdy;
1.1270 + }
1.1271 + *aBuffer=aColor;
1.1272 + }
1.1273 +
1.1274 +
1.1275 + }
1.1276 +template <class TIntType> void
1.1277 +FanFill(const TPoint& aInnerXY,TUint aPixPerScan, TIntType* aSurfacePtr, TIntType aLinesTL,
1.1278 + TIntType aLinesBR, TIntType aLinesTR, TIntType aLinesBL)
1.1279 + {
1.1280 +
1.1281 + DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*180/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR);
1.1282 + DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*372/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR);
1.1283 + DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*591/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR);
1.1284 + DdaLine(aInnerXY.iX,0,aInnerXY.iX-aInnerXY.iX*859/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTR);
1.1285 +
1.1286 + DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesTR);
1.1287 + DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesTR);
1.1288 + DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesTR);
1.1289 + DdaLine(aInnerXY.iX,0,0,aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesTR);
1.1290 +
1.1291 + DdaLine(0,aInnerXY.iY,aInnerXY.iX*180/1024,0,aPixPerScan,aSurfacePtr,aLinesBL);
1.1292 + DdaLine(0,aInnerXY.iY,aInnerXY.iX*372/1024,0,aPixPerScan,aSurfacePtr,aLinesBL);
1.1293 + DdaLine(0,aInnerXY.iY,aInnerXY.iX*591/1024,0,aPixPerScan,aSurfacePtr,aLinesBL);
1.1294 + DdaLine(0,aInnerXY.iY,aInnerXY.iX*859/1024,0,aPixPerScan,aSurfacePtr,aLinesBL);
1.1295 +
1.1296 + DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesBL);
1.1297 + DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesBL);
1.1298 + DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesBL);
1.1299 + DdaLine(0,aInnerXY.iY,aInnerXY.iX,aInnerXY.iY-aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesBL);
1.1300 +
1.1301 + DdaLine(0,0,aInnerXY.iX*180/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL);
1.1302 + DdaLine(0,0,aInnerXY.iX*372/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL);
1.1303 + DdaLine(0,0,aInnerXY.iX*591/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL);
1.1304 + DdaLine(0,0,aInnerXY.iX*859/1024,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesTL);
1.1305 +
1.1306 + DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*180/1024,aPixPerScan,aSurfacePtr,aLinesTL);
1.1307 + DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*372/1024,aPixPerScan,aSurfacePtr,aLinesTL);
1.1308 + DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*591/1024,aPixPerScan,aSurfacePtr,aLinesTL);
1.1309 + DdaLine(0,0,aInnerXY.iX,aInnerXY.iY*859/1024,aPixPerScan,aSurfacePtr,aLinesTL);
1.1310 +
1.1311 + DdaLine(0,aInnerXY.iY-aInnerXY.iY*180/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1.1312 + DdaLine(0,aInnerXY.iY-aInnerXY.iY*372/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1.1313 + DdaLine(0,aInnerXY.iY-aInnerXY.iY*591/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1.1314 + DdaLine(0,aInnerXY.iY-aInnerXY.iY*859/1024,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1.1315 +
1.1316 + DdaLine(aInnerXY.iX-aInnerXY.iX*180/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1.1317 + DdaLine(aInnerXY.iX-aInnerXY.iX*372/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1.1318 + DdaLine(aInnerXY.iX-aInnerXY.iX*591/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1.1319 + DdaLine(aInnerXY.iX-aInnerXY.iX*859/1024,0,aInnerXY.iX,aInnerXY.iY,aPixPerScan,aSurfacePtr,aLinesBR);
1.1320 +
1.1321 + }
1.1322 +/**
1.1323 +Fill the given surface with a fan of lines over a solid color.
1.1324 +
1.1325 +Similar to FillSurfaceL(), but with a fan of lines overlayed.
1.1326 +One fan is drawn about the top-left, and second fan at bottom-right.
1.1327 +The fan contains 8 segments.
1.1328 +
1.1329 +@param aSurface The surface to be filled.
1.1330 +@param aColor The color to fill it with.
1.1331 +@param aLines The color of the grid lines.
1.1332 +*/
1.1333 +void CSurfaceUtility::FanFillSurfaceL(TSurfaceId& aSurface, const TRgb& aColor, const TRgb& aLinesTL, const TRgb& aLinesBR)
1.1334 + {
1.1335 + FillSurfaceL(aSurface,aColor);
1.1336 + RSurfaceManager::TInfoBuf infoBuf;
1.1337 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.1338 +
1.1339 + User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1.1340 + TUint32 linesTL = 0;
1.1341 + TUint32 linesBR = 0;
1.1342 + TUint32 linesTR = 0;
1.1343 + TUint32 linesBL = 0;
1.1344 + TBool use16 = EFalse;
1.1345 + TRgb rgbLinesTR(0,0,0);
1.1346 + TRgb rgbLinesBL(255,255,255);
1.1347 +
1.1348 + switch (info.iPixelFormat)
1.1349 + {
1.1350 + case EUidPixelFormatXRGB_8888:
1.1351 + {
1.1352 + linesBR = aLinesBR.Color16MU();
1.1353 + linesTL = aLinesTL.Color16MU();
1.1354 + linesTR = rgbLinesTR.Color16MU();
1.1355 + linesBL = rgbLinesBL.Color16MU();
1.1356 +#ifdef ALPHA_FIX_24BIT
1.1357 + linesBR |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1.1358 + linesTL |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1.1359 + linesTR |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1.1360 + linesBL |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1.1361 +#endif
1.1362 + break;
1.1363 + }
1.1364 + case EUidPixelFormatARGB_8888:
1.1365 + {
1.1366 + linesBR = aLinesBR.Color16MA();
1.1367 + linesTL = aLinesTL.Color16MA();
1.1368 + linesTR = rgbLinesTR.Color16MA();
1.1369 + linesBL = rgbLinesBL.Color16MA();
1.1370 + break;
1.1371 + }
1.1372 + case EUidPixelFormatARGB_8888_PRE:
1.1373 + {
1.1374 + linesBR = aLinesBR.Color16MAP();
1.1375 + linesTL = aLinesTL.Color16MAP();
1.1376 + linesTR = rgbLinesTR.Color16MAP();
1.1377 + linesBL = rgbLinesBL.Color16MAP();
1.1378 + break;
1.1379 + }
1.1380 + case EUidPixelFormatXRGB_4444:
1.1381 + case EUidPixelFormatARGB_4444:
1.1382 + {
1.1383 + linesBR = aLinesBR.Color4K();
1.1384 + linesTL = aLinesTL.Color4K();
1.1385 + linesTR = rgbLinesTR.Color4K();
1.1386 + linesBL = rgbLinesBL.Color4K();
1.1387 + use16 = ETrue;
1.1388 + break;
1.1389 + }
1.1390 + case EUidPixelFormatRGB_565:
1.1391 + {
1.1392 + linesBR = aLinesBR.Color64K();
1.1393 + linesTL = aLinesTL.Color64K();
1.1394 + linesTR = rgbLinesTR.Color64K();
1.1395 + linesBL = rgbLinesBL.Color64K();
1.1396 + use16 = ETrue;
1.1397 + break;
1.1398 + }
1.1399 + default:
1.1400 + {
1.1401 + User::Leave(KErrNotSupported);
1.1402 + break;
1.1403 + }
1.1404 + }
1.1405 + if (info.iSize.iHeight<0 || info.iSize.iWidth<0 || info.iStride<0)
1.1406 + {
1.1407 + User::Leave(KErrCorrupt);
1.1408 + }
1.1409 + if (info.iSize.iHeight==0 || info.iSize.iWidth==0 || info.iStride==0)
1.1410 + {
1.1411 + User::Leave(KErrNotReady);
1.1412 + }
1.1413 + RChunk chunk;
1.1414 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.1415 + TUint8* surfacePtr = chunk.Base();
1.1416 + TPoint innerXY(info.iSize.iWidth-1,info.iSize.iHeight-1);
1.1417 + if (use16)
1.1418 + {
1.1419 + if ( info.iSize.iWidth*2>info.iStride)
1.1420 + {
1.1421 + User::Leave(KErrOverflow);
1.1422 + }
1.1423 + FanFill<TUint16>(innerXY,info.iStride/2,(TUint16*)surfacePtr,linesTL,linesBR,linesBL,linesTR);
1.1424 + }
1.1425 + else
1.1426 + {
1.1427 + if ( info.iSize.iWidth*4>info.iStride)
1.1428 + {
1.1429 + User::Leave(KErrOverflow);
1.1430 + }
1.1431 + FanFill<TUint>(innerXY,info.iStride/4,(TUint*)surfacePtr,linesTL,linesBR,linesBL,linesTR);
1.1432 + }
1.1433 +
1.1434 + chunk.Close();
1.1435 +
1.1436 + iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1.1437 + }
1.1438 +/**
1.1439 +Fill the given surface with vertical line at the given position
1.1440 +
1.1441 +Similar to FillSurfaceL(), but with a vertical line overlayed.
1.1442 +The position along the surface is given as a percentage from the left
1.1443 +
1.1444 +@param aSurface The surface to be filled.
1.1445 +@param aColor The color to fill it with.
1.1446 +@param aLine The color of the line.
1.1447 +@param aPosition Position of the vertical line given as a percentage across the surface from the left edge
1.1448 +*/
1.1449 +void CSurfaceUtility::LineFillSurfaceL(TSurfaceId& aSurface, const TRgb& aBackColor, const TRgb& aLineColor, TInt aPosition)
1.1450 + {
1.1451 + if (aPosition<0 || aPosition>100)
1.1452 + {
1.1453 + aPosition=0;
1.1454 + }
1.1455 + FillSurfaceL(aSurface,aBackColor);
1.1456 + RSurfaceManager::TInfoBuf infoBuf;
1.1457 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.1458 +
1.1459 + User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1.1460 + TUint32 lineColor = 0;
1.1461 + TBool use16 = EFalse;
1.1462 +
1.1463 + switch (info.iPixelFormat)
1.1464 + {
1.1465 + case EUidPixelFormatXRGB_8888:
1.1466 + {
1.1467 + lineColor = aLineColor.Color16MU();
1.1468 +#ifdef ALPHA_FIX_24BIT
1.1469 + lineColor |= ((ALPHA_FIX_24BIT)&0xff)<<24;
1.1470 +#endif
1.1471 + break;
1.1472 + }
1.1473 + case EUidPixelFormatARGB_8888:
1.1474 + {
1.1475 + lineColor = aLineColor.Color16MA();
1.1476 + break;
1.1477 + }
1.1478 + case EUidPixelFormatARGB_8888_PRE:
1.1479 + {
1.1480 + lineColor = aLineColor.Color16MAP();
1.1481 + break;
1.1482 + }
1.1483 + case EUidPixelFormatXRGB_4444:
1.1484 + case EUidPixelFormatARGB_4444:
1.1485 + {
1.1486 + lineColor = aLineColor.Color4K();
1.1487 + use16 = ETrue;
1.1488 + break;
1.1489 + }
1.1490 + case EUidPixelFormatRGB_565:
1.1491 + {
1.1492 + lineColor = aLineColor.Color64K();
1.1493 + use16 = ETrue;
1.1494 + break;
1.1495 + }
1.1496 + default:
1.1497 + {
1.1498 + User::Leave(KErrNotSupported);
1.1499 + break;
1.1500 + }
1.1501 + }
1.1502 + RChunk chunk;
1.1503 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.1504 +
1.1505 + TUint8* surfacePtr = chunk.Base();
1.1506 + if (use16)
1.1507 + {
1.1508 + DdaLine<TUint16>((info.iSize.iWidth*aPosition)/100,0,(info.iSize.iWidth*aPosition)/100,
1.1509 + info.iSize.iHeight-1,info.iStride/2,(TUint16*)surfacePtr,lineColor);
1.1510 + }
1.1511 + else
1.1512 + {
1.1513 + DdaLine<TUint>((info.iSize.iWidth*aPosition)/100,0,(info.iSize.iWidth*aPosition)/100,
1.1514 + info.iSize.iHeight-1,info.iStride/4,(TUint*)surfacePtr,lineColor);
1.1515 + }
1.1516 + chunk.Close();
1.1517 + iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1.1518 + }
1.1519 +/**
1.1520 + * Generates a bitmap equivalent to the surface.
1.1521 + * Can reuse an existing bitmap or create a new bitmap.
1.1522 + * The existing bitmap must be an exact match (eg previously generated by this method)
1.1523 + **/
1.1524 +CFbsBitmap* CSurfaceUtility::EquivalentBitmapL(TSurfaceId& aSurface,CFbsBitmap* aCopyToMayBeNull)
1.1525 + {
1.1526 + RSurfaceManager::TInfoBuf infoBuf;
1.1527 + RSurfaceManager::TSurfaceInfoV01& info = infoBuf();
1.1528 +
1.1529 + User::LeaveIfError(iManager.SurfaceInfo(aSurface, infoBuf));
1.1530 + TInt bytesPerPixel=0;
1.1531 + TDisplayMode bitmapMode = ENone;
1.1532 + switch (info.iPixelFormat)
1.1533 + {
1.1534 + case EUidPixelFormatXRGB_8888:
1.1535 + {
1.1536 + bitmapMode = EColor16MU;
1.1537 + bytesPerPixel = 4;
1.1538 + break;
1.1539 + }
1.1540 + case EUidPixelFormatARGB_8888:
1.1541 + {
1.1542 + bitmapMode=EColor16MA;
1.1543 + bytesPerPixel = 4;
1.1544 + break;
1.1545 + }
1.1546 + case EUidPixelFormatARGB_8888_PRE:
1.1547 + {
1.1548 + bitmapMode=EColor16MAP;
1.1549 + bytesPerPixel = 4;
1.1550 + break;
1.1551 + }
1.1552 + case EUidPixelFormatXRGB_4444:
1.1553 + case EUidPixelFormatARGB_4444:
1.1554 + {
1.1555 + bitmapMode=EColor4K;
1.1556 + bytesPerPixel = 2;
1.1557 + break;
1.1558 + }
1.1559 + case EUidPixelFormatRGB_565:
1.1560 + {
1.1561 + bitmapMode=EColor64K;
1.1562 + bytesPerPixel = 2;
1.1563 + break;
1.1564 + }
1.1565 + default:
1.1566 + {
1.1567 + User::Leave(KErrNotSupported);
1.1568 + break;
1.1569 + }
1.1570 + }
1.1571 + CFbsBitmap* retVal=NULL;
1.1572 + if (aCopyToMayBeNull)
1.1573 + {
1.1574 + retVal=aCopyToMayBeNull;
1.1575 + if (retVal->SizeInPixels()!=info.iSize)
1.1576 + User::Leave(KErrCorrupt);
1.1577 + if (retVal->DisplayMode()!=bitmapMode)
1.1578 + User::Leave(KErrCorrupt);
1.1579 + }
1.1580 + else
1.1581 + {
1.1582 + retVal=new CFbsBitmap;
1.1583 + CleanupStack::PushL(retVal);
1.1584 + User::LeaveIfError(retVal->Create(info.iSize,bitmapMode));
1.1585 + }
1.1586 + RChunk chunk;
1.1587 + CleanupClosePushL(chunk);
1.1588 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.1589 + TUint8* surfacePtr = chunk.Base();
1.1590 + TUint8* bitmapPtr = (TUint8*)retVal->DataAddress();
1.1591 + TInt copyBytes=info.iSize.iWidth*bytesPerPixel;
1.1592 + for (TInt y=0;y<info.iSize.iHeight;y++)
1.1593 + {
1.1594 + Mem::Copy(bitmapPtr,surfacePtr,copyBytes);
1.1595 + surfacePtr+=info.iStride;
1.1596 + bitmapPtr+=retVal->DataStride();
1.1597 + }
1.1598 + CleanupStack::PopAndDestroy(&chunk);
1.1599 + if (!aCopyToMayBeNull)
1.1600 + CleanupStack::Pop(retVal);
1.1601 + return retVal;
1.1602 + }
1.1603 +
1.1604 +/**
1.1605 +Destroy a surface.
1.1606 +
1.1607 +As well as destroying the surface, it is removed from the set held for
1.1608 +destruction during tear down.
1.1609 +
1.1610 +@param aSurface The surface to be destroyed.
1.1611 +*/
1.1612 +void CSurfaceUtility::DestroySurface(TSurfaceId& aSurface)
1.1613 + {
1.1614 + TInt index = iSurfaces.Find(aSurface);
1.1615 +
1.1616 + if (index != KErrNotFound)
1.1617 + {
1.1618 + iSurfaces.Remove(index);
1.1619 + }
1.1620 +
1.1621 + TInt err = iManager.CloseSurface(aSurface);
1.1622 + if (err!=KErrNone)
1.1623 + LOG(("Error closing surfaces: 0x%X\n", err));
1.1624 + }
1.1625 +
1.1626 +
1.1627 +/**
1.1628 +Submit an update to a surface to the update server.
1.1629 +
1.1630 +@param aScreenNumber The screen to be updated where the surface is shown.
1.1631 +@param aSurface The surface which has been updated.
1.1632 +@param aRegion The area of the surface affected, or NULL for all of it.*/
1.1633 +void CSurfaceUtility::SubmitUpdate(TInt /* aScreenNumber */, const TSurfaceId& aSurface, const TRegion* aRegion,TInt aBufferNumber)
1.1634 + {
1.1635 + TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, aBufferNumber, aRegion);
1.1636 + if (err!=KErrNone)
1.1637 + LOG(("Error submitting update: 0x%X\n", err));
1.1638 + }
1.1639 +
1.1640 +/**
1.1641 +Map and submit an update to a surface to the update server.
1.1642 +
1.1643 +@param aChunk The chunk of memory to be mapped
1.1644 +@param aScreenNumber The screen to be updated where the surface is shown.
1.1645 +@param aSurface The surface which has been updated.
1.1646 +@param aRegion The area of the surface affected, or NULL for all of it.*/
1.1647 +void CSurfaceUtility::MapAndSubmitUpdateL(RChunk& aChunk,
1.1648 + TInt /* aScreenNumber */,
1.1649 + const TSurfaceId& aSurface,
1.1650 + const TRegion* aRegion)
1.1651 + {
1.1652 + User::LeaveIfError(iManager.MapSurface(aSurface, aChunk));
1.1653 + aChunk.Close();
1.1654 + TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, aRegion);
1.1655 + if (err!=KErrNone)
1.1656 + LOG(("Error submitting update: 0x%X\n", err));
1.1657 + }
1.1658 +
1.1659 +void CSurfaceUtility::MapSurfaceL(const TSurfaceId& aSurface, RChunk& aChunk)
1.1660 + {
1.1661 + User::LeaveIfError(iManager.MapSurface(aSurface, aChunk));
1.1662 + }
1.1663 +
1.1664 +void CSurfaceUtility::CopyBitmapToSurfaceL(TSurfaceId& aSurface, const CFbsBitmap& aBitmap)
1.1665 + {
1.1666 + TSize size = SurfaceSize(aSurface);
1.1667 +
1.1668 + TDisplayMode bmpFormat = aBitmap.DisplayMode();
1.1669 + TInt stride = size.iWidth * 4; // Default to four bytes per pixel
1.1670 +
1.1671 + RChunk chunk;
1.1672 + User::LeaveIfError(iManager.MapSurface(aSurface, chunk));
1.1673 + CleanupClosePushL(chunk);
1.1674 +
1.1675 + // Copy the data from the bitmap into the surface.
1.1676 + TPoint start;
1.1677 + for (start.iY = 0; start.iY < size.iHeight; start.iY++)
1.1678 + {
1.1679 + // Set up a descriptor for the current line in the surface and get pixels.
1.1680 + TPtr8 ptr(chunk.Base() + start.iY * stride, stride);
1.1681 + aBitmap.GetScanLine(ptr, start, size.iWidth, bmpFormat);
1.1682 + }
1.1683 +
1.1684 + TInt err =iSurfaceUpdateSession.SubmitUpdate(KAllScreens, aSurface, 0, NULL);
1.1685 + if (err!=KErrNone)
1.1686 + {
1.1687 + LOG(("Error submitting update: 0x%X\n", err));
1.1688 + }
1.1689 +
1.1690 + CleanupStack::PopAndDestroy(/* chunk */);
1.1691 + }
1.1692 +
1.1693 +/**
1.1694 +CActiveListener factory function
1.1695 +@return A CActiveListener object
1.1696 +*/
1.1697 +CActiveListener* CActiveListener::NewLC()
1.1698 + {
1.1699 + CActiveListener* self = new(ELeave) CActiveListener();
1.1700 + CleanupStack::PushL(self);
1.1701 + return self;
1.1702 + }
1.1703 +
1.1704 +/**
1.1705 +Constructor for class CActiveListener
1.1706 +*/
1.1707 +CActiveListener::CActiveListener() : CActive(EPriorityLow)
1.1708 + {
1.1709 + CActiveScheduler::Add(this);
1.1710 + }
1.1711 +
1.1712 +/**
1.1713 +Destructor
1.1714 +*/
1.1715 +CActiveListener::~CActiveListener()
1.1716 + {
1.1717 + }
1.1718 +
1.1719 +/**
1.1720 +Handles the request.
1.1721 +This function is derived from CActive
1.1722 +*/
1.1723 +void CActiveListener::RunL()
1.1724 + {
1.1725 + CActiveScheduler::Stop();
1.1726 + }
1.1727 +
1.1728 +/**
1.1729 +Cancels the outstanding request.
1.1730 +This function is derived from CActive
1.1731 +*/
1.1732 +void CActiveListener::DoCancel()
1.1733 + {
1.1734 + }
1.1735 +
1.1736 +/**
1.1737 +Initializes the CActiveListener
1.1738 +*/
1.1739 +void CActiveListener::Initialize()
1.1740 + {
1.1741 + iStatus = KRequestPending;
1.1742 + SetActive();
1.1743 + }
1.1744 +
1.1745 +/**
1.1746 +Check that the request has been cancelled.
1.1747 +@return A boolean indicating whether the request has been cancelled or not
1.1748 +*/
1.1749 +TBool CActiveListener::IsRequestCancelled()
1.1750 + {
1.1751 + return (iStatus == KErrCancel);
1.1752 + }
1.1753 +
1.1754 +/**
1.1755 +A helper function that returns the bytes per pixel for a given pixel format uid
1.1756 +
1.1757 +@param aPixelFormat Pixel format UID to convert
1.1758 +@return The bytes per pixel
1.1759 +*/
1.1760 +TInt CSurfaceUtility::BytesPerPixelL(TUidPixelFormat aPixelFormat)
1.1761 + {
1.1762 + TInt bytesPerPixel = 0;
1.1763 + switch (aPixelFormat)
1.1764 + {
1.1765 + case EUidPixelFormatXRGB_8888:
1.1766 + case EUidPixelFormatARGB_8888:
1.1767 + case EUidPixelFormatARGB_8888_PRE:
1.1768 + {
1.1769 + bytesPerPixel = 4;
1.1770 + break;
1.1771 + }
1.1772 + case EUidPixelFormatXRGB_4444:
1.1773 + case EUidPixelFormatARGB_4444:
1.1774 + case EUidPixelFormatRGB_565:
1.1775 + {
1.1776 + bytesPerPixel = 2;
1.1777 + break;
1.1778 + }
1.1779 + default:
1.1780 + {
1.1781 + User::Leave(KErrNotSupported);
1.1782 + break;
1.1783 + }
1.1784 + }
1.1785 + return bytesPerPixel;
1.1786 + }
1.1787 +