1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicscomposition/openwfsupport/src/surfacestream.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,2144 @@
1.4 +// Copyright (c) 2009-2010 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 +// SurfaceStream.cpp
1.18 +// CSurfaceStream implementation
1.19 +
1.20 +#include <e32base.h>
1.21 +#include <graphics/suerror.h>
1.22 +#include <graphics/surfacetypes.h>
1.23 +#include <hal.h>
1.24 +#include "surfacestream.h"
1.25 +#include "openwfcpanic.h"
1.26 +#include "streammap.h"
1.27 +#include "symbianstream.h"
1.28 +#define WFC_INVALID_HANDLE NULL
1.29 +
1.30 +const TInt KInvalidIndex = KNoAssociatedScreenNumber;
1.31 +
1.32 +struct CSurfaceStream::TCallBackEntry
1.33 + {
1.34 + typedef SymbianStreamCallback TSimpleCallback;
1.35 + TCallBackEntry();
1.36 + void Reset();
1.37 + TSimpleCallback iCallBackFunction;
1.38 + TAny* iCallBackClientParam;
1.39 + TInt32 iEventMask;
1.40 + TInt32 iScreenNumber;
1.41 + };
1.42 +
1.43 +CSurfaceStream::TCallBackEntry::TCallBackEntry():
1.44 +iCallBackFunction(NULL),
1.45 +iCallBackClientParam(NULL),
1.46 +iEventMask(ESOWF_NoEvent),
1.47 +iScreenNumber(KNoAssociatedScreenNumber)
1.48 + {
1.49 + }
1.50 +
1.51 +void CSurfaceStream::TCallBackEntry::Reset()
1.52 + {
1.53 + iCallBackFunction = NULL;
1.54 + iCallBackClientParam = NULL;
1.55 + iEventMask = ESOWF_NoEvent;
1.56 + iScreenNumber = KNoAssociatedScreenNumber;
1.57 + }
1.58 +
1.59 +struct CSurfaceStream::TGlobalNotification
1.60 + {
1.61 + TGlobalNotification();
1.62 + void Reset();
1.63 + TRequestStatus* iStatus;
1.64 + TThreadId iThreadId;
1.65 + TInt iPendingNotifications;
1.66 + TInt iCompletedOkNotifications;
1.67 + TInt iCanceledNotifications;
1.68 + TInt iOverflowedNotifications;
1.69 + TInt iNotVisibleNotifications;
1.70 + TInt iOtherNotifications;
1.71 + };
1.72 +
1.73 +
1.74 +CSurfaceStream::TGlobalNotification::TGlobalNotification():
1.75 +iStatus(NULL),
1.76 +iThreadId(0),
1.77 +iPendingNotifications(0),
1.78 +iCompletedOkNotifications(0),
1.79 +iCanceledNotifications(0),
1.80 +iOverflowedNotifications(0),
1.81 +iNotVisibleNotifications(0),
1.82 +iOtherNotifications(0)
1.83 + {
1.84 +
1.85 + }
1.86 +
1.87 +void CSurfaceStream::TGlobalNotification::Reset()
1.88 + {
1.89 + iStatus = NULL;
1.90 + iThreadId = 0;
1.91 + iPendingNotifications = 0;
1.92 + iCompletedOkNotifications = 0;
1.93 + iCanceledNotifications = 0;
1.94 + iOverflowedNotifications = 0;
1.95 + iNotVisibleNotifications = 0;
1.96 + iOtherNotifications = 0;
1.97 + }
1.98 +
1.99 +struct CSurfaceStream::TNewGlobalNotifications
1.100 + {
1.101 + TNewGlobalNotifications();
1.102 + TInt iNewAvailableIdx;
1.103 + TInt iNewDisplayedIdx;
1.104 + TInt iNewDisplayedXIdx;
1.105 + };
1.106 +
1.107 +CSurfaceStream::TNewGlobalNotifications::TNewGlobalNotifications():
1.108 +iNewAvailableIdx(KInvalidIndex),
1.109 +iNewDisplayedIdx(KInvalidIndex),
1.110 +iNewDisplayedXIdx(KInvalidIndex)
1.111 + {
1.112 + }
1.113 +
1.114 +CSurfaceStream::Guard::Guard(RFastLock& aLock):
1.115 +iLock(aLock)
1.116 + {
1.117 + iLock.Wait();
1.118 + }
1.119 +
1.120 +CSurfaceStream::Guard::~Guard()
1.121 + {
1.122 + iLock.Signal();
1.123 + }
1.124 +
1.125 +CSurfaceStream::CSurfaceStream():
1.126 + iSurfaceId(TSurfaceId::CreateNullId()),
1.127 + iBufferInfo(NULL),
1.128 + iProtected(EFalse),
1.129 + iNumberOfScreenAttachedAvailableNotif(0),
1.130 + iNumberOfScreenAttachedDisplayedNotif(0),
1.131 + iNumberOfScreenAttachedDisplayedXNotif(),
1.132 + iFlipState(EFlippedTargetNormal),
1.133 + iNewFlip(EFlipNotSet)
1.134 + {
1.135 + iStreamProxySurfaceId.iInternal[TSurfaceId::TSurfaceUsage::EObjectRefField]=
1.136 + reinterpret_cast<TInt>(this);
1.137 + iStreamProxySurfaceId.iInternal[TSurfaceId::TSurfaceUsage::ETypeClassField]=
1.138 + TSurfaceId::EStreamHandle<<TSurfaceId::TSurfaceUsage::ETypeClassShift;
1.139 + }
1.140 +
1.141 +CSurfaceStream::ContentUpdatedParams::ContentUpdatedParams(TInt aBuffer,
1.142 + TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp,
1.143 + TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes,
1.144 + TRequestStatus* aStatusConsumed, const TRegion* aRegion,
1.145 + TBool aImmediateAvailable, TInt32 aImmediateVisibility,
1.146 + const TNewGlobalNotifications& aGlobalNotifications):
1.147 +iBuffer(aBuffer),
1.148 +iStatusDisplayed(aStatusDisplayed),
1.149 +iTimeStamp(aTimeStamp),
1.150 +iStatusDispXTimes(aStatusDispXTimes),
1.151 +iDisplayedXTimes(aDisplayedXTimes),
1.152 +iStatusConsumed(aStatusConsumed),
1.153 +iRegion(aRegion),
1.154 +iImmediateAvailable(aImmediateAvailable),
1.155 +iImmediateVisibility(aImmediateVisibility),
1.156 +iGlobalNotifications(aGlobalNotifications)
1.157 + {
1.158 +
1.159 + }
1.160 +
1.161 +CSurfaceStream::~CSurfaceStream()
1.162 + {
1.163 + // Cancel any outstanding notifications
1.164 + CancelNotifications();
1.165 + iCallBacks.Close();
1.166 + iGlobalNotifications.Close();
1.167 + iBufferChunk.Close();
1.168 +
1.169 + if (!iSurfaceId.IsNull() && iSurfaceId.Type() == TSurfaceTypes::ESurfaceManagerSurface)
1.170 + {
1.171 + TRAP_IGNORE(GetSingletonL().SurfaceManager().CloseSurface(iSurfaceId));
1.172 + }
1.173 +
1.174 + iRefCountMutex.Close();
1.175 + iCallBacksMutex.Close();
1.176 + delete [] iBufferInfo;
1.177 + }
1.178 +
1.179 +CSurfaceStream* CSurfaceStream::NewLC(const TSurfaceId& aId)
1.180 + {
1.181 + CSurfaceStream* self = new (ELeave)CSurfaceStream();
1.182 + CleanupStack::PushL(self);
1.183 + self->ConstructL(aId);
1.184 + return self;
1.185 + }
1.186 +
1.187 +void CSurfaceStream::ConstructL(const TSurfaceId& aId)
1.188 + {
1.189 + User::LeaveIfError(iRefCountMutex.CreateLocal());
1.190 + User::LeaveIfError(iCallBacksMutex.CreateLocal());
1.191 +
1.192 + RSurfaceManager::TInfoBuf infoBuf;
1.193 + SurfaceInfoL(aId, infoBuf);
1.194 + iInfo = infoBuf();
1.195 +
1.196 + COpenWfcStreamMap& stream = GetSingletonL();
1.197 + //Create array for TBufferInfo
1.198 + iBufferInfo = new(ELeave) TBufferInfo[iInfo.iBuffers];
1.199 + for(TInt i = 0; i < iInfo.iBuffers; i++)
1.200 + {
1.201 + TInt offset = 0;
1.202 + switch(aId.Type())
1.203 + {
1.204 + case TSurfaceTypes::ESurfaceManagerSurface:
1.205 + {
1.206 + User::LeaveIfError(stream.SurfaceManager().GetBufferOffset(iSurfaceId,
1.207 + i, offset));
1.208 + break;
1.209 + }
1.210 + case TSurfaceId::EScreenSurface:
1.211 + {
1.212 + TInt screenId = SurfaceId().iInternal[TSurfaceId::TScreenSurfaceUsage::EScreenField];
1.213 + User::LeaveIfError(HAL::Get(screenId, HALData::EDisplayOffsetToFirstPixel, offset));
1.214 + break;
1.215 + }
1.216 + default:
1.217 + User::Leave(KErrNotSupported);
1.218 + }
1.219 +
1.220 + iBufferInfo[i].iRefCount = 0;
1.221 + iBufferInfo[i].iOffset = offset;
1.222 + }
1.223 + }
1.224 +
1.225 +void CSurfaceStream::SurfaceInfoL(const TSurfaceId& aId, RSurfaceManager::TInfoBuf& aInfoBuf)
1.226 + {
1.227 + COpenWfcStreamMap& stream = GetSingletonL();
1.228 + switch(aId.Type())
1.229 + {
1.230 + case TSurfaceTypes::ESurfaceManagerSurface:
1.231 + {
1.232 + iStreamProxySurfaceId.iInternal[TSurfaceId::TSurfaceUsage::EObjectRefField]=
1.233 + reinterpret_cast<TInt>(this);
1.234 + iStreamProxySurfaceId.iInternal[TSurfaceId::TSurfaceUsage::ETypeClassField]=
1.235 + TSurfaceId::EStreamHandle<<TSurfaceId::TSurfaceUsage::ETypeClassShift;
1.236 +
1.237 + User::LeaveIfError(stream.SurfaceManager().OpenSurface(aId));
1.238 + iSurfaceId = aId;
1.239 + User::LeaveIfError(stream.SurfaceManager().SurfaceInfo(iSurfaceId, aInfoBuf));
1.240 + break;
1.241 + }
1.242 + case TSurfaceId::EScreenSurface:
1.243 + {
1.244 + // DSA surface only has one buffer
1.245 + aInfoBuf().iBuffers = 1;
1.246 +
1.247 + TInt screenId = aId.iInternal[TSurfaceId::TScreenSurfaceUsage::EScreenField];
1.248 + TInt width;
1.249 + User::LeaveIfError(HAL::Get(screenId, HALData::EDisplayXPixels, width));
1.250 +
1.251 + TInt height;
1.252 + User::LeaveIfError(HAL::Get(screenId, HALData::EDisplayYPixels, height));
1.253 +
1.254 + aInfoBuf().iSize = TSize(width, height);
1.255 +
1.256 + TInt bpp = 0;
1.257 + User::LeaveIfError(HAL::Get(screenId, HALData::EDisplayBitsPerPixel, bpp));
1.258 +
1.259 + TUidPixelFormat pixelFormat = static_cast<TUidPixelFormat> (aId.iInternal[TSurfaceId::TScreenSurfaceUsage::ETypeGuidField]);
1.260 + if (!pixelFormat)
1.261 + {
1.262 + //if (bpp==12 || bpp==4)) //This allows low-color indices to be semi-functionally tested
1.263 + if (bpp==12)
1.264 + {
1.265 + pixelFormat = EUidPixelFormatXRGB_4444;
1.266 + }
1.267 + else if (bpp == 16)
1.268 + {
1.269 + pixelFormat = EUidPixelFormatRGB_565;
1.270 + }
1.271 + else if (bpp== 24 || bpp==32)
1.272 + {
1.273 + pixelFormat = EUidPixelFormatARGB_8888;
1.274 + }
1.275 + else
1.276 + {
1.277 + User::Leave(KErrNotSupported);
1.278 + }
1.279 +
1.280 + }
1.281 + aInfoBuf().iPixelFormat = pixelFormat;
1.282 +
1.283 +#ifdef SYMBIAN_ROTATION_MODE_CHANGES
1.284 + TInt displayMode = aId.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
1.285 +#else
1.286 + TInt displayMode = 0;
1.287 + User::LeaveIfError(HAL::Get(screenId, HALData::EDisplayMode, displayMode));
1.288 +#endif
1.289 +
1.290 +#if defined(SYMBIAN_ROTATION_MODE_CHANGES)
1.291 + if (displayMode & TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag) // 90 | 270 degree rotation
1.292 + {
1.293 + // Swap dimensions and recalculate stride. Assume no padding for now.
1.294 + aInfoBuf().iSize.iWidth = height;
1.295 + aInfoBuf().iSize.iHeight = width;
1.296 + //"vertical" stride has already been fetched
1.297 + }
1.298 +#elif defined(SYMBIAN_ROTATION_CHANGES)
1.299 + if (aSurface.iInternal[1] & (2 | 8)) // 90 | 270 degree rotation
1.300 + {
1.301 + // Swap dimensions and recalculate stride. Assume no padding for now.
1.302 + aInfoBuf().iSize.iWidth = height;
1.303 + aInfoBuf().iSize.iHeight = width;
1.304 + aInfoBuf().iStride = infoBuf().iSize.width * bpp;
1.305 + }
1.306 +#endif
1.307 +
1.308 + TInt stride = displayMode;
1.309 + User::LeaveIfError(HAL::Get(screenId, HALData::EDisplayOffsetBetweenLines, stride));
1.310 +
1.311 + aInfoBuf().iStride = stride;
1.312 +
1.313 + iSurfaceId = aId;
1.314 + break;
1.315 + }
1.316 + default:
1.317 + User::Leave(KErrNotSupported);
1.318 + }
1.319 + }
1.320 +
1.321 +COpenWfcStreamMap& CSurfaceStream::GetSingletonL()
1.322 + {
1.323 + return COpenWfcStreamMap::InstanceL();
1.324 + }
1.325 +
1.326 +/**
1.327 + Helper to resolve handle to stream object
1.328 +**/
1.329 +/*static*/
1.330 +CSurfaceStream* CSurfaceStream::FromHandle(SymbianStreamType aNativeStreamHandle)
1.331 + {
1.332 + if (aNativeStreamHandle)
1.333 + {
1.334 + if (aNativeStreamHandle->Type()==TSurfaceId::EStreamHandle)
1.335 + {
1.336 + return reinterpret_cast<CSurfaceStream*>(aNativeStreamHandle->iInternal[TSurfaceId::TSurfaceUsage::EObjectRefField]);
1.337 + }
1.338 + }
1.339 + return NULL;
1.340 + }
1.341 +
1.342 +/**
1.343 + Helper to resolve handle to stream object
1.344 +**/
1.345 +SymbianStreamType CSurfaceStream::ToHandle()
1.346 + {
1.347 + if (this)
1.348 + {
1.349 + return &iStreamProxySurfaceId;
1.350 + }
1.351 + else
1.352 + {
1.353 + return NULL;
1.354 + }
1.355 + }
1.356 +
1.357 +
1.358 +/** Returns internal surface ID.
1.359 + *
1.360 + * @return surface id asociated with this stream
1.361 + **/
1.362 +const TSurfaceId& CSurfaceStream::SurfaceId()const
1.363 + {
1.364 + return iSurfaceId;
1.365 + }
1.366 +
1.367 +/*!
1.368 + * \brief Increase stream's reference count by one.
1.369 + *
1.370 + */
1.371 + void CSurfaceStream::AddReference()
1.372 + {
1.373 + iRefCountMutex.Wait();
1.374 + iRefCount++;
1.375 + iRefCountMutex.Signal();
1.376 +
1.377 + }
1.378 +
1.379 +/*!
1.380 + * \internal
1.381 + *
1.382 + * \brief Returns flag if reference count is now zero.
1.383 + *
1.384 + */
1.385 +TBool CSurfaceStream::RemainingReference()
1.386 + {
1.387 + iRefCountMutex.Wait();
1.388 + TBool countZero=iRefCount==0;
1.389 + iRefCountMutex.Signal();
1.390 + return countZero;
1.391 + }
1.392 +
1.393 +
1.394 +/*!
1.395 + * \brief Decrease stream's reference count by one and destroy
1.396 + * the stream, if the reference count goes to zero.
1.397 + *
1.398 + * All acquired read & write buffers must be released
1.399 + * before calling WFC_Native_Destroy.
1.400 + *
1.401 + */
1.402 +void CSurfaceStream::ReleaseReference()
1.403 + {
1.404 + iRefCountMutex.Wait();
1.405 + --iRefCount;
1.406 + if (iRefCount < 1)
1.407 + {
1.408 + // it is required to signal the mutex before calling LockDestroy()
1.409 + iRefCountMutex.Signal();
1.410 + TRAP_IGNORE(GetSingletonL().LockDestroy(this));
1.411 + }
1.412 + else
1.413 + {
1.414 + iRefCountMutex.Signal();
1.415 + }
1.416 + }
1.417 +
1.418 +/*!
1.419 + * \brief Get stream "frame header". Can be used to query
1.420 + * all or some of the frame properties.
1.421 + *
1.422 + * \param width Pointer to location where width parameter should be saved
1.423 + * \param height Pointer to location where height parameter should be saved
1.424 + * \param stride Pointer to location where stride (row size in bytes)
1.425 + * parameter should be saved
1.426 + * \param pixelSize Pointer to location where pizelSize (pixel size in bytes) if the format has more than 8 bits.
1.427 + * For the formats with fewer than 8 bits per pixel, or ones that do not use packed pixel
1.428 + * the parameter is a negative number
1.429 + * parameter should be saved
1.430 +
1.431 + * Passing a NULL pointer implies that particular
1.432 + * value is of no interest to caller. E.g.
1.433 + * owfNativeStreamGetHeader(stream, &w, &h, NULL, NULL, NULL);
1.434 + * would only fetch width & height parameters.
1.435 + */
1.436 +void CSurfaceStream::GetHeader( khronos_int32_t* aWidth,
1.437 + khronos_int32_t* aHeight,
1.438 + khronos_int32_t* aStride,
1.439 + SymOwfPixelFormat* aFormat,
1.440 + khronos_int32_t* aPixelSize)
1.441 + {
1.442 + Guard g1(iRefCountMutex);
1.443 + if (aWidth)
1.444 + {
1.445 + if (iFlipState == EFlippedTargetFlipped)
1.446 + {
1.447 + *aWidth = static_cast<khronos_int32_t>(iInfo.iSize.iHeight);
1.448 + }
1.449 + else
1.450 + {
1.451 + *aWidth = static_cast<khronos_int32_t>(iInfo.iSize.iWidth);
1.452 + }
1.453 + }
1.454 +
1.455 + if (aHeight)
1.456 + {
1.457 + if (iFlipState == EFlippedTargetFlipped)
1.458 + {
1.459 + *aHeight = static_cast<khronos_int32_t>(iInfo.iSize.iWidth);
1.460 + }
1.461 + else
1.462 + {
1.463 + *aHeight = static_cast<khronos_int32_t>(iInfo.iSize.iHeight);
1.464 + }
1.465 + }
1.466 + if (aStride)
1.467 + {
1.468 + if (iFlipState == EFlippedTargetFlipped)
1.469 + {
1.470 + *aStride = Stride(iInfo.iSize.iHeight, iInfo.iPixelFormat);
1.471 + }
1.472 + else
1.473 + {
1.474 + *aStride = static_cast<khronos_int32_t>(iInfo.iStride);
1.475 + }
1.476 + }
1.477 + if (aFormat)
1.478 + {
1.479 + *aFormat=iInfo.iPixelFormat;
1.480 + }
1.481 + if (aPixelSize)
1.482 + {
1.483 + *aPixelSize = static_cast<khronos_int32_t>(BytesPerPixel(iInfo.iPixelFormat));
1.484 + }
1.485 + }
1.486 +
1.487 +/*!
1.488 + * \brief Acquires read buffer for stream. For > 1 buffer
1.489 + * streams this function doesn't block, but simply returns
1.490 + * WFC_INVALID_HANDLE if no buffer is available for reading.
1.491 + * For 1 buffer stream the caller is blocked until the buffer
1.492 + * is ready for reading (the reader has committed the buffer,
1.493 + * that is.)
1.494 + *
1.495 + *
1.496 + * \return WFC_INVALID_HANDLE if no buffer is available or
1.497 + * handle to last committed buffer.
1.498 + *
1.499 + * An example sequence for 3 buffer stream where
1.500 + * producer produces frames approx. after every ~5th time unit.
1.501 + * Consumer consumes buffers at constant rate of 1buf/time unit.
1.502 + * Pframe is the number/handle of buffer that is being written by
1.503 + * the producer (let's assume that it takes 2 time units
1.504 + * for producer to produce a frame/buffer.) Cframe is the number/
1.505 + * handle of the buffer the consumer receives from AcquireReadBuffer().
1.506 + * "i" stands for WFC_INVALID_HANDLE:
1.507 + *
1.508 + * \code
1.509 + * Time: 0 5 10 15 20 25
1.510 + * Pframe: 0 1 2 0 1 ...
1.511 + * Cframe: ii00000111112222200000111...
1.512 + * \endcode
1.513 + */
1.514 +SymbianStreamBuffer CSurfaceStream::AcquireReadBuffer()
1.515 + {
1.516 + SymbianStreamBuffer buffer = WFC_INVALID_HANDLE;
1.517 +
1.518 + iRefCountMutex.Wait();
1.519 + TInt index = GetReadBufferIndex();
1.520 + buffer = IndexToReadHandle(index);
1.521 + ++(iBufferInfo[index].iRefCount);
1.522 + iRefCountMutex.Signal();
1.523 + AddReference();
1.524 + return buffer;
1.525 + }
1.526 +
1.527 +/*!
1.528 + * \brief Releases read buffer.
1.529 + *
1.530 + * When read buffer is released, it is marked as clean to
1.531 + * be written again, unless it is the only committed buffer
1.532 + * in which case it is recycled so that the same buffer
1.533 + * can be read again (as long as no new buffers are committed
1.534 + * by the producer)
1.535 + *
1.536 + * \param buf Buffer handle. Must be valid read buffer handle for
1.537 + * given stream.
1.538 + */
1.539 +TInt CSurfaceStream::ReleaseReadBuffer(SymbianStreamBuffer aBuf)
1.540 + {
1.541 + TInt index = BufferHandleToIndex(aBuf);
1.542 + if(index < 0 || index >= iInfo.iBuffers)
1.543 + {
1.544 + return KErrBadHandle;
1.545 + }
1.546 +
1.547 + iRefCountMutex.Wait();
1.548 +
1.549 + __ASSERT_DEBUG(iBufferInfo[index].iRefCount > 0,
1.550 + (iRefCountMutex.Signal(),Panic(EOwfPanicSurfaceStreamBufferNotLocked)));
1.551 +
1.552 + --(iBufferInfo[index].iRefCount);
1.553 +
1.554 + iRefCountMutex.Signal();
1.555 + ReleaseReference();
1.556 + return KErrNone;
1.557 + }
1.558 +
1.559 +/*!
1.560 + * \brief Acquires write buffer for stream.
1.561 + *
1.562 + * Returns handle to a buffer that can be used to write
1.563 + * data into stream. If no clean buffer is available,
1.564 + * invalid handle is returned.
1.565 + *
1.566 + *
1.567 + * \return Handle to a writable buffer
1.568 + */
1.569 +SymbianStreamBuffer CSurfaceStream::AcquireWriteBuffer()
1.570 + {
1.571 + SymbianStreamBuffer buffer = WFC_INVALID_HANDLE;
1.572 +
1.573 + iRefCountMutex.Wait();
1.574 + TInt index = GetWriteBufferIndex();
1.575 + //Writers are currently not blocked in single buffered,
1.576 + //but if proper signalling was implemented then they could be blocked
1.577 + //Ideally, make signalling/blocking a parameter flag of AcquireWriteBuffer
1.578 + if (iInfo.iBuffers>1 && iBufferInfo[index].iRefCount > 0)
1.579 + {
1.580 + buffer = WFC_INVALID_HANDLE;
1.581 + }
1.582 + else
1.583 + {
1.584 + buffer = IndexToWriteHandle(index);
1.585 + ++(iBufferInfo[index].iRefCount);
1.586 + iAcquiredWriteBuffer = buffer;
1.587 + }
1.588 + iRefCountMutex.Signal();
1.589 + if (buffer)
1.590 + {
1.591 + AddReference();
1.592 + }
1.593 + return buffer;
1.594 + }
1.595 +
1.596 +/*!
1.597 + * \brief Releases write buffer to stream.
1.598 + * Released buffer is made new front buffer, i.e., producer is expected
1.599 + * to release buffer is the same order they were acquired.
1.600 + *
1.601 + * \param buf Buffer handle. Must be valid write buffer handle
1.602 + * for given stream.
1.603 + */
1.604 +void CSurfaceStream::ReleaseWriteBuffer(SymbianStreamBuffer aBuf)
1.605 + {
1.606 + TInt index = BufferHandleToIndex(aBuf);
1.607 + if(index < 0 || index >= iInfo.iBuffers)
1.608 + {
1.609 + return;
1.610 + }
1.611 +
1.612 + iRefCountMutex.Wait();
1.613 +
1.614 + __ASSERT_DEBUG(iBufferInfo[index].iRefCount > 0,
1.615 + (iRefCountMutex.Signal(),Panic(EOwfPanicSurfaceStreamBufferNotLocked)));
1.616 +
1.617 + __ASSERT_DEBUG((iAcquiredWriteBuffer == aBuf) || (iAcquiredWriteBuffer == BUFFER_WRITE_UPDATE_OVERWRITE),
1.618 + (iRefCountMutex.Signal(),Panic(EOwfPanicSurfaceStreamBufferNotLocked)));
1.619 +
1.620 + if (iAcquiredWriteBuffer != BUFFER_WRITE_UPDATE_OVERWRITE)
1.621 + {
1.622 + // Update read buffer to point to buffer just finished writing
1.623 + SetReadBufferIndex(index);
1.624 + }
1.625 + iAcquiredWriteBuffer = WFC_INVALID_HANDLE;
1.626 +
1.627 + --(iBufferInfo[index].iRefCount);
1.628 +
1.629 + if (iNewFlip != EFlipNotSet)
1.630 + {
1.631 + iFlipState = iNewFlip;
1.632 + iNewFlip = EFlipNotSet;
1.633 + }
1.634 +
1.635 + iRefCountMutex.Signal();
1.636 +
1.637 + NotifyObservers(ESOWF_EventComposed);
1.638 + ReleaseReference(); //Note this means this NotifyObservers can never get the rug pulled out
1.639 + }
1.640 +
1.641 +
1.642 +void CSurfaceStream::SetReadBufferIndex(TInt aIndex)
1.643 + {
1.644 + __ASSERT_DEBUG(aIndex >= 0 && aIndex < iInfo.iBuffers,
1.645 + (iRefCountMutex.Signal(),Panic(EOwfPanicSurfaceStreamBufferIndexOutOfBounds)));
1.646 + iReadBuffer = aIndex;
1.647 + }
1.648 +
1.649 +TInt CSurfaceStream::GetReadBufferIndex()
1.650 + {
1.651 + return iReadBuffer;
1.652 + }
1.653 +TInt CSurfaceStream::GetWriteBufferIndex()
1.654 + {
1.655 + return (iReadBuffer+1)%iInfo.iBuffers;
1.656 + }
1.657 +
1.658 +/*! \brief Returns pointer to pixel buffer.
1.659 + *
1.660 + * \param buffer Handle of buffer
1.661 + */
1.662 +void* CSurfaceStream::GetBufferPtrL(SymbianStreamBuffer aBuffer)
1.663 + {
1.664 + TInt bufferIndex = BufferHandleToIndex(aBuffer);
1.665 + Guard g1(iRefCountMutex);
1.666 + __ASSERT_DEBUG(iBufferInfo[bufferIndex].iRefCount > 0,
1.667 + (iRefCountMutex.Signal(),Panic(EOwfPanicSurfaceStreamBufferNotLocked)));
1.668 +
1.669 + switch (SurfaceId().Type())
1.670 + {
1.671 + case TSurfaceTypes::ESurfaceManagerSurface:
1.672 + {
1.673 + if (iBufferChunk.Handle() == 0)
1.674 + {
1.675 + RChunk threadChunk;
1.676 + RSurfaceManager sm;
1.677 + sm.Open();
1.678 + TInt err = sm.MapSurface(iSurfaceId, threadChunk);
1.679 + sm.Close();
1.680 + CleanupClosePushL(threadChunk);
1.681 +
1.682 + RChunk duplicateChunk;
1.683 + duplicateChunk.SetHandle(threadChunk.Handle());
1.684 + User::LeaveIfError(duplicateChunk.Duplicate(RThread(), EOwnerProcess));
1.685 +
1.686 + iBufferChunk.SetHandle(duplicateChunk.Handle());
1.687 + CleanupStack::PopAndDestroy(&threadChunk);
1.688 + }
1.689 + break;
1.690 + }
1.691 + case TSurfaceId::EScreenSurface:
1.692 + {
1.693 + if (iBufferChunk.Handle() == 0)
1.694 + {
1.695 + TInt val = 0;
1.696 + TInt screenId = SurfaceId().iInternal[TSurfaceId::TScreenSurfaceUsage::EScreenField];
1.697 + User::LeaveIfError(HAL::Get(screenId, HALData::EDisplayMemoryHandle, val));
1.698 +
1.699 + RChunk threadChunk;
1.700 + CleanupClosePushL(threadChunk);
1.701 + User::LeaveIfError(threadChunk.SetReturnedHandle(val));
1.702 +
1.703 + RChunk duplicateChunk;
1.704 + duplicateChunk.SetHandle(threadChunk.Handle());
1.705 + User::LeaveIfError(duplicateChunk.Duplicate(RThread(), EOwnerProcess));
1.706 +
1.707 + iBufferChunk.SetHandle(duplicateChunk.Handle());
1.708 + CleanupStack::PopAndDestroy(&threadChunk);
1.709 + }
1.710 + break;
1.711 + }
1.712 + default:
1.713 + User::Leave(KErrNotSupported);
1.714 + }
1.715 +
1.716 + TUint8 *pBufferStart = iBufferChunk.Base() + iBufferInfo[bufferIndex].iOffset;
1.717 + return static_cast<void*>(pBufferStart);
1.718 + }
1.719 +
1.720 +void CSurfaceStream::SetProtectionFlag(TBool aFlag)
1.721 + {
1.722 + iRefCountMutex.Wait();
1.723 + if (aFlag!=iProtected)
1.724 + {
1.725 + iProtected=aFlag;
1.726 + iRefCountMutex.Signal();
1.727 + if (aFlag)
1.728 + {
1.729 + AddReference();
1.730 + }
1.731 + else
1.732 + {
1.733 + ReleaseReference();
1.734 + }
1.735 + }
1.736 + else
1.737 + {
1.738 + iRefCountMutex.Signal();
1.739 + }
1.740 + }
1.741 +
1.742 +TInt CSurfaceStream::BytesPerPixel(TUidPixelFormat aPixelFormat)
1.743 + {
1.744 + switch (aPixelFormat)
1.745 + {
1.746 + case EUidPixelFormatXRGB_8888:
1.747 + case EUidPixelFormatARGB_8888:
1.748 + case EUidPixelFormatBGRX_8888:
1.749 + case EUidPixelFormatXBGR_8888:
1.750 + case EUidPixelFormatBGRA_8888:
1.751 + case EUidPixelFormatABGR_8888:
1.752 + case EUidPixelFormatABGR_8888_PRE:
1.753 + case EUidPixelFormatARGB_8888_PRE:
1.754 + case EUidPixelFormatBGRA_8888_PRE:
1.755 + case EUidPixelFormatARGB_2101010:
1.756 + case EUidPixelFormatABGR_2101010:
1.757 + return 4;
1.758 + case EUidPixelFormatBGR_888:
1.759 + case EUidPixelFormatRGB_888:
1.760 + return 3;
1.761 + case EUidPixelFormatXRGB_4444:
1.762 + case EUidPixelFormatARGB_4444:
1.763 + case EUidPixelFormatXBGR_4444:
1.764 + case EUidPixelFormatRGB_565:
1.765 + case EUidPixelFormatBGR_565:
1.766 + case EUidPixelFormatARGB_1555:
1.767 + case EUidPixelFormatXRGB_1555:
1.768 + case EUidPixelFormatARGB_8332:
1.769 + case EUidPixelFormatBGRX_5551:
1.770 + case EUidPixelFormatBGRA_5551:
1.771 + case EUidPixelFormatBGRA_4444:
1.772 + case EUidPixelFormatBGRX_4444:
1.773 + case EUidPixelFormatAP_88:
1.774 + return 2;
1.775 + case EUidPixelFormatRGB_332:
1.776 + case EUidPixelFormatBGR_332:
1.777 + case EUidPixelFormatA_8:
1.778 + case EUidPixelFormatL_8:
1.779 + return 1;
1.780 + case EUidPixelFormatP_8:
1.781 + return -1;
1.782 + case EUidPixelFormatP_4:
1.783 + case EUidPixelFormatL_4:
1.784 + return -2;
1.785 + case EUidPixelFormatL_2:
1.786 + case EUidPixelFormatP_2:
1.787 + return -4;
1.788 + case EUidPixelFormatL_1 :
1.789 + return -8;
1.790 + default:
1.791 + {
1.792 + return 0;
1.793 + }
1.794 + }
1.795 + }
1.796 +
1.797 +SymbianStreamBuffer CSurfaceStream::IndexToReadHandle(TInt aIndex)
1.798 + {
1.799 + return static_cast<SymbianStreamBuffer>(aIndex + BUFFER_READ_HANDLE_BASE);
1.800 + }
1.801 +
1.802 +SymbianStreamBuffer CSurfaceStream::IndexToWriteHandle(TInt aIndex)
1.803 + {
1.804 + return static_cast<SymbianStreamBuffer>(aIndex + BUFFER_WRITE_HANDLE_BASE);
1.805 + }
1.806 +
1.807 +TInt CSurfaceStream::BufferHandleToIndex(SymbianStreamBuffer aBuff)
1.808 + {
1.809 + TInt retVal= (aBuff > 0) ? (aBuff&0xFF) : (aBuff - BUFFER_READ_HANDLE_BASE);
1.810 + __ASSERT_DEBUG(retVal>=0,User::Invariant());
1.811 + __ASSERT_DEBUG(retVal<iInfo.iBuffers,User::Invariant());
1.812 + return retVal;
1.813 + }
1.814 +
1.815 +
1.816 +
1.817 +
1.818 +void CSurfaceStream::RequestComplete(TThreadId& aThreadId, TRequestStatus*& aRequestStatus, TInt& aGlobalIndexArray, TInt aStatus)
1.819 + {
1.820 + if (aRequestStatus)
1.821 + {
1.822 + if (aGlobalIndexArray != KInvalidIndex)
1.823 + {
1.824 + TGlobalNotification& globalNotification = iGlobalNotifications[aGlobalIndexArray];
1.825 + --globalNotification.iPendingNotifications;
1.826 + switch (aStatus)
1.827 + {
1.828 + case KErrNone:
1.829 + globalNotification.iCompletedOkNotifications++;
1.830 + break;
1.831 + case KErrOverflow:
1.832 + globalNotification.iOverflowedNotifications++;
1.833 + break;
1.834 + case KErrCancel:
1.835 + globalNotification.iCanceledNotifications++;
1.836 + break;
1.837 + case KErrNotVisible:
1.838 + globalNotification.iNotVisibleNotifications++;
1.839 + break;
1.840 + default:
1.841 + globalNotification.iOtherNotifications++;
1.842 + }
1.843 + NFLOG(("### CSurfaceStream::RequestComplete globalRequestStatus[%d] iPendingNotifications(%d) "
1.844 + "iCompletedOkNotifications(%d)"
1.845 + "iOverflowedNotifications(%d)"
1.846 + "iCanceledNotifications(%d)"
1.847 + "iNotVisibleNotifications(%d)"
1.848 + "iOtherNotifications(%d)"
1.849 + "requestStatus(%p)",
1.850 + aGlobalIndexArray,
1.851 + globalNotification.iPendingNotifications,
1.852 + globalNotification.iCompletedOkNotifications,
1.853 + globalNotification.iOverflowedNotifications,
1.854 + globalNotification.iCanceledNotifications,
1.855 + globalNotification.iNotVisibleNotifications,
1.856 + globalNotification.iOtherNotifications,
1.857 + aStatus));
1.858 +
1.859 + if (globalNotification.iStatus && globalNotification.iPendingNotifications == 0)
1.860 + {
1.861 + TInt status;
1.862 + if (globalNotification.iCompletedOkNotifications > 0)
1.863 + {
1.864 + status = KErrNone;
1.865 + }
1.866 + else if (globalNotification.iOverflowedNotifications > 0)
1.867 + {
1.868 + status = KErrOverflow;
1.869 + }
1.870 + else if (globalNotification.iNotVisibleNotifications > 0)
1.871 + {
1.872 + status = KErrNotVisible;
1.873 + }
1.874 + else if (globalNotification.iCanceledNotifications > 0)
1.875 + {
1.876 + status = KErrCancel;
1.877 + }
1.878 + else
1.879 + {
1.880 + status = KErrGeneral;
1.881 + }
1.882 +
1.883 + RThread thread;
1.884 + if (thread.Open(globalNotification.iThreadId) == KErrNone)
1.885 + {
1.886 + NFLOG(("### CSurfaceStream::RequestComplete globalIndex[%d] aRequestComplete(0x%x) status(%d)",
1.887 + aGlobalIndexArray, iGlobalNotifications[aGlobalIndexArray].iStatus, status));
1.888 + thread.RequestComplete(globalNotification.iStatus, status);
1.889 + thread.Close();
1.890 + iGlobalNotifications[aGlobalIndexArray].Reset();
1.891 + }
1.892 + }
1.893 + }
1.894 + else
1.895 + {
1.896 + RThread thread;
1.897 + if (thread.Open(aThreadId) == KErrNone)
1.898 + {
1.899 + NFLOG(("### CSurfaceStream::RequestComplete aRequestStatus(0x%x) aThreadId(0x%x) aStatus(%d)",
1.900 + aRequestStatus, aThreadId, aStatus));
1.901 + thread.RequestComplete(aRequestStatus, aStatus);
1.902 + thread.Close();
1.903 + }
1.904 + }
1.905 + aRequestStatus = NULL;
1.906 + aThreadId = 0;
1.907 + }
1.908 + aGlobalIndexArray = KInvalidIndex;
1.909 + }
1.910 +
1.911 +int CSurfaceStream::AddObserver(SymbianStreamCallback aObserver,
1.912 + TInt32 aEvent,
1.913 + TInt32 aScreenNumber,
1.914 + void* aData)
1.915 + {
1.916 + if (!(aEvent & ESOWF_AllEventsMask) || !aData)
1.917 + {
1.918 + // early exit if the parameters are invalid
1.919 + return KErrArgument;
1.920 + }
1.921 +
1.922 + TInt errRet = KErrNone;
1.923 + TCallBackEntry newEntry;
1.924 +
1.925 + Guard g2(iCallBacksMutex);
1.926 + Guard g1(iRefCountMutex);
1.927 +
1.928 + // Let's do the check that we dont have an other similar observer already inserted
1.929 + // traverse the whole aobservers list to see if there is already an observer in place
1.930 + TInt idx = iCallBacks.Count();
1.931 + while(idx--)
1.932 + {
1.933 + if (iCallBacks[idx].iEventMask == aEvent)
1.934 + {
1.935 + switch (aEvent)
1.936 + {
1.937 + case ESOWF_EventAvailable:
1.938 + case ESOWF_EventDisplayed:
1.939 + case ESOWF_EventDisplayedX:
1.940 + // these are events related to a context and identified by a screen number
1.941 + if (iCallBacks[idx].iScreenNumber == aScreenNumber)
1.942 + {
1.943 + // nothing else to do, the entry is already created
1.944 + return KErrOverflow;
1.945 + }
1.946 + break;
1.947 +
1.948 + case ESOWF_EventComposed:
1.949 + case ESOWF_EventUpdated:
1.950 + if (iCallBacks[idx].iCallBackClientParam == aData)
1.951 + {
1.952 + // nothing else to do, the entry is already created
1.953 + return KErrOverflow;
1.954 + }
1.955 + break;
1.956 +
1.957 + default:
1.958 + // something really unexpected, let's invalidate the entry
1.959 + // possible memomry leaks but we are, still, alive and running.
1.960 + iCallBacks[idx].Reset();
1.961 + break;
1.962 + }
1.963 + }
1.964 + }
1.965 +
1.966 + // we need to add a new observer to the list
1.967 + newEntry.iCallBackFunction = aObserver;
1.968 + newEntry.iEventMask = aEvent;
1.969 + newEntry.iScreenNumber = aScreenNumber;
1.970 + TInt trapErr;
1.971 + switch (aEvent)
1.972 + {
1.973 + case ESOWF_EventUpdated:
1.974 + case ESOWF_EventComposed:
1.975 + newEntry.iCallBackClientParam = aData;
1.976 + break;
1.977 +
1.978 + case ESOWF_EventAvailable:
1.979 + {
1.980 + TNotificationAvailable* available = NULL;
1.981 + TRAP(trapErr,available = new(ELeave) TNotificationAvailable());
1.982 + if (trapErr != KErrNone)
1.983 + {
1.984 + return trapErr;
1.985 + }
1.986 + ResetCallBackData(available, aEvent);
1.987 + available->iSerialNumber = KInitialContextSerialNumber;
1.988 + newEntry.iCallBackClientParam = available;
1.989 + }
1.990 + break;
1.991 +
1.992 + case ESOWF_EventDisplayed:
1.993 + {
1.994 + TNotificationDisplayed* displayed = NULL;
1.995 + TRAP(trapErr,displayed = new(ELeave) TNotificationDisplayed());
1.996 + if (trapErr != KErrNone)
1.997 + {
1.998 + return trapErr;
1.999 + }
1.1000 + ResetCallBackData(displayed, aEvent);
1.1001 + displayed->iSerialNumber = KInitialContextSerialNumber;
1.1002 + newEntry.iCallBackClientParam = displayed;
1.1003 + }
1.1004 + break;
1.1005 +
1.1006 + case ESOWF_EventDisplayedX:
1.1007 + {
1.1008 + TNotificationDisplayedX* displayedX = NULL;
1.1009 + TRAP(trapErr,displayedX = new(ELeave) TNotificationDisplayedX());
1.1010 + if (trapErr != KErrNone)
1.1011 + {
1.1012 + return trapErr;
1.1013 + }
1.1014 + ResetCallBackData(displayedX, aEvent);
1.1015 + displayedX->iSerialNumber = KInitialContextSerialNumber;
1.1016 + newEntry.iCallBackClientParam = displayedX;
1.1017 + }
1.1018 + break;
1.1019 +
1.1020 + default:
1.1021 + return KErrArgument;
1.1022 + }
1.1023 +
1.1024 + // look for an entry that already exists
1.1025 + idx = iCallBacks.Count();
1.1026 +
1.1027 + while(idx--)
1.1028 + {
1.1029 + // the free entry positions are identified using event mask
1.1030 + if (iCallBacks[idx].iEventMask == ESOWF_NoEvent) break;
1.1031 + }
1.1032 +
1.1033 + if (idx > -1)
1.1034 + {
1.1035 + // ok, we got an existing, free entry
1.1036 + iCallBacks[idx] = newEntry;
1.1037 + }
1.1038 + else
1.1039 + {
1.1040 + errRet = iCallBacks.Append(newEntry);
1.1041 + if (errRet != KErrNone)
1.1042 + {
1.1043 + return errRet;
1.1044 + }
1.1045 + }
1.1046 +
1.1047 + switch (aEvent)
1.1048 + {
1.1049 + case ESOWF_EventAvailable:
1.1050 + iNumberOfScreenAttachedAvailableNotif++;
1.1051 + break;
1.1052 +
1.1053 + case ESOWF_EventDisplayed:
1.1054 + iNumberOfScreenAttachedDisplayedNotif++;
1.1055 + break;
1.1056 +
1.1057 + case ESOWF_EventDisplayedX:
1.1058 + iNumberOfScreenAttachedDisplayedXNotif++;
1.1059 + break;
1.1060 +
1.1061 + default:
1.1062 + break;
1.1063 +
1.1064 + }
1.1065 +
1.1066 + return errRet;
1.1067 + }
1.1068 +
1.1069 +
1.1070 +int CSurfaceStream::RemoveObserver(TInt32 aEvents, void* aData)
1.1071 + {
1.1072 + NFLOG(("ENTER ###CSurfaceStream::RemoveObserver() events(%d) data(0x%x)", aEvents, aData));
1.1073 + if (!(aEvents & ESOWF_AllEventsMask))
1.1074 + {
1.1075 + NFLOG(("EXIT ###CSurfaceStream::RemoveObserver() ERROR: KErrArgument"));
1.1076 + return KErrArgument;
1.1077 + }
1.1078 +
1.1079 + Guard g2(iCallBacksMutex);
1.1080 + Guard g1(iRefCountMutex);
1.1081 +
1.1082 + TInt32 notFoundEvent = aEvents;
1.1083 + TInt count = iCallBacks.Count();
1.1084 + TInt32 susScreenNumber = KNoAssociatedScreenNumber;
1.1085 +
1.1086 + if (aData)
1.1087 + {
1.1088 + susScreenNumber = *(((TInt32*)aData));
1.1089 + }
1.1090 +
1.1091 + while (count-- && notFoundEvent)
1.1092 + {
1.1093 + TInt32 currentEvent = iCallBacks[count].iEventMask;
1.1094 + if (currentEvent & aEvents)
1.1095 + {
1.1096 + void* callBackData = iCallBacks[count].iCallBackClientParam;
1.1097 + switch (currentEvent)
1.1098 + {
1.1099 + case ESOWF_EventDisplayed:
1.1100 + if (callBackData && (!aData || (iCallBacks[count].iScreenNumber == susScreenNumber)))
1.1101 + {
1.1102 + Displayed(ESOWF_ObserverCancel, iCallBacks[count].iScreenNumber, NULL, callBackData, NULL);
1.1103 + delete (TNotificationDisplayed*) callBackData;
1.1104 + iCallBacks[count].Reset();
1.1105 + if (iNumberOfScreenAttachedDisplayedNotif > 0)
1.1106 + {
1.1107 + iNumberOfScreenAttachedDisplayedNotif--;
1.1108 + }
1.1109 + notFoundEvent &= ~currentEvent;
1.1110 + }
1.1111 + break;
1.1112 +
1.1113 + case ESOWF_EventAvailable:
1.1114 + if (callBackData && (!aData || (iCallBacks[count].iScreenNumber == susScreenNumber)))
1.1115 + {
1.1116 + Available(ESOWF_ObserverCancel, iCallBacks[count].iScreenNumber, NULL, callBackData, NULL);
1.1117 + delete (TNotificationAvailable*) callBackData;
1.1118 + iCallBacks[count].Reset();
1.1119 + if (iNumberOfScreenAttachedAvailableNotif > 0)
1.1120 + {
1.1121 + iNumberOfScreenAttachedAvailableNotif--;
1.1122 + }
1.1123 + notFoundEvent &= ~currentEvent;
1.1124 + }
1.1125 + break;
1.1126 +
1.1127 + case ESOWF_EventDisplayedX:
1.1128 + if (callBackData && (!aData || (iCallBacks[count].iScreenNumber == susScreenNumber)))
1.1129 + {
1.1130 + DisplayedXTimes(ESOWF_ObserverCancel, iCallBacks[count].iScreenNumber, NULL, callBackData, NULL);
1.1131 + delete (TNotificationDisplayedX*) callBackData;
1.1132 + iCallBacks[count].Reset();
1.1133 + if (iNumberOfScreenAttachedDisplayedXNotif)
1.1134 + {
1.1135 + iNumberOfScreenAttachedDisplayedXNotif--;
1.1136 + }
1.1137 + notFoundEvent &= ~currentEvent;
1.1138 + }
1.1139 + break;
1.1140 +
1.1141 + case ESOWF_EventComposed:
1.1142 + if (!aData || (aData == iCallBacks[count].iCallBackClientParam))
1.1143 + {
1.1144 + // just in case that we have to delete the call back, we try, first to execute it
1.1145 + // avoiding in this way some deadlocks in CT code
1.1146 + if (iCallBacks[count].iCallBackFunction && iCallBacks[count].iCallBackClientParam)
1.1147 + {
1.1148 + iCallBacks[count].iCallBackFunction(ToHandle(),
1.1149 + ESOWF_EventComposed,
1.1150 + iCallBacks[count].iCallBackClientParam,
1.1151 + NULL);
1.1152 + }
1.1153 + iCallBacks[count].Reset();
1.1154 + notFoundEvent &= ~currentEvent;
1.1155 + }
1.1156 + break;
1.1157 +
1.1158 + case ESOWF_EventUpdated:
1.1159 + if (!aData || (aData == iCallBacks[count].iCallBackClientParam))
1.1160 + {
1.1161 + if (iCallBacks[count].iScreenNumber != KNoAssociatedScreenNumber)
1.1162 + {
1.1163 + susScreenNumber = iCallBacks[count].iScreenNumber;
1.1164 + iCallBacks[count].Reset();
1.1165 + notFoundEvent &= ~currentEvent;
1.1166 +
1.1167 + // Reseting variables to loop back and remove SUS events.
1.1168 + notFoundEvent |= ESOWF_SUSEventsMask;
1.1169 + aEvents = ESOWF_SUSEventsMask;
1.1170 + count = iCallBacks.Count();
1.1171 + }
1.1172 + else
1.1173 + {
1.1174 + iCallBacks[count].Reset();
1.1175 + notFoundEvent &= ~currentEvent;
1.1176 + }
1.1177 + }
1.1178 + break;
1.1179 +
1.1180 + default:
1.1181 + break;
1.1182 + }
1.1183 + }
1.1184 + }
1.1185 +
1.1186 + NFLOG(("EXIT ###CSurfaceStream::CancelNotifications() err(%d)", notFoundEvent ? KErrNotFound : KErrNone));
1.1187 + return (notFoundEvent ? KErrNotFound : KErrNone);
1.1188 + }
1.1189 +
1.1190 +TInt CSurfaceStream::NotifyObservers(TInt32 aEvent)
1.1191 + {
1.1192 + NFLOG(("### ENTER CSurfaceStream::NotifyObservers()"));
1.1193 + TInt err = KErrNotFound;
1.1194 +
1.1195 + Guard g2(iCallBacksMutex);
1.1196 + TCallBackEntry localCallBackEntry;
1.1197 +
1.1198 + for (TInt i = 0; i < iCallBacks.Count(); ++i)
1.1199 + {
1.1200 + localCallBackEntry = iCallBacks[i];
1.1201 + if (iCallBacks[i].iEventMask & aEvent &&
1.1202 + iCallBacks[i].iCallBackFunction)
1.1203 + {
1.1204 + err = KErrNone;
1.1205 + NFLOG(("### EXIT CSurfaceStream::NotifyObservers() callback(%d)", iCallBacks[i].iEventMask));
1.1206 + localCallBackEntry.iCallBackFunction(ToHandle(),
1.1207 + iCallBacks[i].iEventMask,
1.1208 + localCallBackEntry.iCallBackClientParam,
1.1209 + NULL);
1.1210 + }
1.1211 + }
1.1212 + NFLOG(("### EXIT CSurfaceStream::NotifyObservers() err(%d)", err));
1.1213 + return err;
1.1214 + }
1.1215 +
1.1216 +TBool CSurfaceStream::NotifyComposerContext(TInt32 aScreenNumber, TInt aOp, SYMOWF_CONTENT_UPDATED_PARAM* aParam)
1.1217 + {
1.1218 + NFLOG(("### ENTER CSurfaceStream::NotifyComposerContext()"));
1.1219 + TCallBackEntry entry;
1.1220 + TBool ret = EFalse;
1.1221 + for(TInt i = 0; i < iCallBacks.Count(); i++)
1.1222 + {
1.1223 + if (iCallBacks[i].iEventMask == ESOWF_EventUpdated &&
1.1224 + iCallBacks[i].iCallBackFunction &&
1.1225 + (((iCallBacks[i].iScreenNumber == KNoAssociatedScreenNumber) && (aOp != SYM_CONTENT_UPDATE_BEGIN)) ||
1.1226 + ((aScreenNumber == KNoAssociatedScreenNumber) && (aOp != SYM_CONTENT_UPDATE_BEGIN)) ||
1.1227 + iCallBacks[i].iScreenNumber == aScreenNumber))
1.1228 + {
1.1229 + entry = iCallBacks[i];
1.1230 + iRefCountMutex.Signal();
1.1231 + NFLOG(("###CSurfaceStream::NotifyComposerContext() ESOWF_EventUpdated aParam(%d)", aParam? aParam->id: -1));
1.1232 + entry.iCallBackFunction(ToHandle(), ESOWF_EventUpdated, entry.iCallBackClientParam, aParam);
1.1233 + ret = ETrue;
1.1234 + // We are meant to hold this lock when we leave this function so coverity warning is false
1.1235 + //coverity[lock]
1.1236 + iRefCountMutex.Wait();
1.1237 + }
1.1238 + }
1.1239 + NFLOG(("### EXIT CSurfaceStream::NotifyComposerContext() ret(%d)", ret));
1.1240 + return ret;
1.1241 + }
1.1242 +
1.1243 +TBool CSurfaceStream::StartUpdateNotifications(TInt aScreenNumber, SYMOWF_CONTENT_UPDATED_PARAM& param)
1.1244 + {
1.1245 + NFLOG(("### CSurfaceStream::StartUpdateNotifications()"));
1.1246 + param.id = SYM_CONTENT_UPDATE_BEGIN;
1.1247 + param.length = sizeof (param);
1.1248 + param.par = 0;
1.1249 + param.serialNumber = KNoAssociatedScreenNumber;
1.1250 + param.immediateAvailable = 0;
1.1251 + return NotifyComposerContext(aScreenNumber, SYM_CONTENT_UPDATE_BEGIN, ¶m);
1.1252 + }
1.1253 +
1.1254 +TBool CSurfaceStream::EndUpdateNotifications(TInt aScreenNum, TInt aBufferNum, TInt32 aUpdatedFlags, const TRegion* aRegion)
1.1255 + {
1.1256 + (void)aScreenNum;
1.1257 + (void)aRegion;
1.1258 + NFLOG(("### CSurfaceStream::EndUpdateNotifications()"));
1.1259 + if (aBufferNum < 0 || aBufferNum >= iInfo.iBuffers)
1.1260 + {
1.1261 + return EFalse;
1.1262 + }
1.1263 +
1.1264 + if (iAcquiredWriteBuffer != WFC_INVALID_HANDLE)
1.1265 + {
1.1266 + iAcquiredWriteBuffer = BUFFER_WRITE_UPDATE_OVERWRITE;
1.1267 + }
1.1268 +
1.1269 + SetReadBufferIndex(aBufferNum);
1.1270 +
1.1271 + SYMOWF_CONTENT_UPDATED_PARAM param;
1.1272 + param.length = sizeof (param);
1.1273 + param.id = SYM_CONTENT_UPDATE_END;
1.1274 + param.par = aUpdatedFlags;
1.1275 + return NotifyComposerContext(aScreenNum, SYM_CONTENT_UPDATE_END, ¶m);
1.1276 + }
1.1277 +
1.1278 +TBool CSurfaceStream::UpdateNotifications(TInt aScreenNum,
1.1279 + TInt aBufferNum,
1.1280 + TInt32 aUpdatedFlags,
1.1281 + const TRegion* aRegion)
1.1282 + {
1.1283 + (void)aScreenNum;
1.1284 + (void)aRegion;
1.1285 + NFLOG(("### CSurfaceStream::UpdateNotifications()"));
1.1286 + if (aBufferNum < 0 || aBufferNum >= iInfo.iBuffers)
1.1287 + {
1.1288 + return EFalse;
1.1289 + }
1.1290 +
1.1291 + if (iAcquiredWriteBuffer != WFC_INVALID_HANDLE)
1.1292 + {
1.1293 + iAcquiredWriteBuffer = BUFFER_WRITE_UPDATE_OVERWRITE;
1.1294 + }
1.1295 +
1.1296 + SetReadBufferIndex(aBufferNum);
1.1297 +
1.1298 + SYMOWF_CONTENT_UPDATED_PARAM param;
1.1299 + param.length = sizeof (param);
1.1300 + param.id = SYM_CONTENT_UPDATE;
1.1301 + param.par = aUpdatedFlags;
1.1302 + return NotifyComposerContext(aScreenNum, SYM_CONTENT_UPDATE, ¶m);
1.1303 + }
1.1304 +
1.1305 +void CSurfaceStream::SetNewNotifications(TInt aBuffer,
1.1306 + TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp,
1.1307 + TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes,
1.1308 + TRequestStatus* aStatusConsumed, const TRegion* aRegion,
1.1309 + TInt32 aScreenNumber)
1.1310 + {
1.1311 + NFLOG(("### ENTER * CSurfaceStream::SetNewNotifications()"));
1.1312 + Guard g2(iCallBacksMutex);
1.1313 + Guard g1(iRefCountMutex);
1.1314 + if (aScreenNumber == KAllScreens)
1.1315 + {
1.1316 + SetAllNotifications(aBuffer,
1.1317 + aStatusDisplayed, aTimeStamp,
1.1318 + aStatusDispXTimes, aDisplayedXTimes,
1.1319 + aStatusConsumed, aRegion);
1.1320 + }
1.1321 + else
1.1322 + {
1.1323 + TNewGlobalNotifications noGlobalNotifications;
1.1324 + SetNotifications(aBuffer,
1.1325 + aStatusDisplayed, aTimeStamp,
1.1326 + aStatusDispXTimes, aDisplayedXTimes,
1.1327 + aStatusConsumed, aRegion,
1.1328 + aScreenNumber, noGlobalNotifications);
1.1329 + }
1.1330 + NFLOG(("### EXIT * CSurfaceStream::SetNewNotifications()"));
1.1331 + }
1.1332 +
1.1333 +
1.1334 +void CSurfaceStream::SetNotifications(TInt aBuffer,
1.1335 + TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp,
1.1336 + TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes,
1.1337 + TRequestStatus* aStatusConsumed, const TRegion* aRegion,
1.1338 + TInt32 aScreenNumber, const TNewGlobalNotifications& aGlobalNotifications)
1.1339 + {
1.1340 + NFLOG(("### ENTER * CSurfaceStream::SetNotifications()"));
1.1341 + TInt32 eventsFound = 0;
1.1342 + TInt32 eventsReceived = 0;
1.1343 + TInt32 eventsToProcess = 0;
1.1344 + TInt32 contextUpdate = 0;
1.1345 + // let's take in evidence the events we have to process
1.1346 + if (aStatusConsumed)
1.1347 + {
1.1348 + eventsReceived |= ESOWF_EventAvailable;
1.1349 + }
1.1350 + if (aStatusDisplayed)
1.1351 + {
1.1352 + eventsReceived |= ESOWF_EventDisplayed;
1.1353 + }
1.1354 + if (aStatusDispXTimes)
1.1355 + {
1.1356 + eventsReceived |= ESOWF_EventDisplayedX;
1.1357 + }
1.1358 +
1.1359 + TInt availableIndex = -1;
1.1360 + TInt displayedIndex = -1;
1.1361 + TInt displayedXIndex = -1;
1.1362 +
1.1363 + TInt32 serialNumber = KNoAssociatedScreenNumber;
1.1364 + TBool immediateAvailable = EFalse;
1.1365 + TInt32 immediateVisibility = SYM_CONTENT_VISIBLE_NOT_SET;
1.1366 +
1.1367 + // guard acquiring/release of the update lock of the composer
1.1368 + // acquire the update lock of the composer and retrive the composer state info
1.1369 + SYMOWF_CONTENT_UPDATED_PARAM param;
1.1370 + TBool startUpdateNotification = StartUpdateNotifications(aScreenNumber, param);
1.1371 + immediateAvailable = param.immediateAvailable && ETrue;
1.1372 + immediateVisibility = param.immediateVisibility;
1.1373 + serialNumber = param.serialNumber;
1.1374 +
1.1375 +
1.1376 + // we take, initially in consideration "available" even if we might not have received a consumed request status
1.1377 + eventsToProcess = 0;
1.1378 +
1.1379 + // we try to figure out which are the events we have to process and to get hold of their position
1.1380 + // in the observers array, in order to avoid traversing it again
1.1381 + TInt idx = iCallBacks.Count();
1.1382 + //we will intend to mark the visited events, as an optimisation
1.1383 + TInt32 eventsToCheck = eventsReceived | ESOWF_EventAvailable;
1.1384 + TInt32 currentEvent = 0;
1.1385 + while(--idx > -1 && eventsToCheck)
1.1386 + {
1.1387 + currentEvent = iCallBacks[idx].iEventMask;
1.1388 + if ((currentEvent & eventsToCheck) && (iCallBacks[idx].iScreenNumber == aScreenNumber))
1.1389 + {
1.1390 + switch (currentEvent)
1.1391 + {
1.1392 + case ESOWF_EventAvailable:
1.1393 + // mark observer visited
1.1394 + eventsToCheck &= ~currentEvent;
1.1395 + // mark the events found only if the corresponding status request has been recived
1.1396 + eventsFound |= (currentEvent & eventsReceived);
1.1397 + // reset the events to process mask
1.1398 + eventsToProcess &= ~currentEvent;
1.1399 + {
1.1400 + TNotificationAvailable* available = (TNotificationAvailable*) iCallBacks[idx].iCallBackClientParam;
1.1401 + if (available && (aStatusConsumed || available->iStatus || available->iNewStatus))
1.1402 + {
1.1403 + // set the mask of the events to be processed because we have either to overflow some available request
1.1404 + // statuses, or to process them further
1.1405 + eventsToProcess |= ESOWF_EventAvailable;
1.1406 + availableIndex = idx;
1.1407 + }
1.1408 + }
1.1409 + break;
1.1410 +
1.1411 + case ESOWF_EventDisplayed:
1.1412 + // mark observer visited
1.1413 + eventsFound |= currentEvent;
1.1414 + eventsToProcess |= currentEvent;
1.1415 + eventsToCheck &= ~currentEvent;
1.1416 + displayedIndex = idx;
1.1417 + break;
1.1418 +
1.1419 + case ESOWF_EventDisplayedX:
1.1420 + // mark observer visited
1.1421 + eventsFound |= currentEvent;
1.1422 + eventsToProcess |= currentEvent;
1.1423 + eventsToCheck &= ~currentEvent;
1.1424 + displayedXIndex = idx;
1.1425 + break;
1.1426 +
1.1427 + default:
1.1428 + Panic(EOwfSymbianUnexpectedObserverId);
1.1429 + break;
1.1430 + }
1.1431 + }
1.1432 + }
1.1433 +
1.1434 + NFLOG(("### CSurfaceStream::SetNotifications eventsToProcess(0x%x)", eventsToProcess));
1.1435 + if (eventsToProcess)
1.1436 + {
1.1437 +
1.1438 + // from this momment on, the composer cannot process any notifications related to this stream
1.1439 +
1.1440 + ContentUpdatedParams updateParameters(aBuffer, aStatusDisplayed, aTimeStamp,
1.1441 + aStatusDispXTimes, aDisplayedXTimes,
1.1442 + aStatusConsumed, aRegion,
1.1443 + immediateAvailable, immediateVisibility,
1.1444 + aGlobalNotifications);
1.1445 +
1.1446 + // process the observer corresponding to aStatusConsumed request status
1.1447 + if ((ESOWF_EventAvailable & eventsToProcess) && (availableIndex > -1))
1.1448 + {
1.1449 + Available(ESOWF_ObserverProcessing,
1.1450 + serialNumber,
1.1451 + &updateParameters,
1.1452 + iCallBacks[availableIndex].iCallBackClientParam,
1.1453 + &contextUpdate);
1.1454 + }
1.1455 +
1.1456 + // process the observer corresponding to aStatusDisplayed request status
1.1457 + if ((ESOWF_EventDisplayed & eventsToProcess) && (displayedIndex > -1))
1.1458 + {
1.1459 + Displayed(ESOWF_ObserverProcessing,
1.1460 + serialNumber,
1.1461 + &updateParameters,
1.1462 + iCallBacks[displayedIndex].iCallBackClientParam,
1.1463 + &contextUpdate);
1.1464 + }
1.1465 +
1.1466 + // process the observer corresponding to aStatusDispXTimes request status
1.1467 + if ((ESOWF_EventDisplayedX & eventsToProcess) && (displayedXIndex > -1))
1.1468 + {
1.1469 + DisplayedXTimes(ESOWF_ObserverProcessing,
1.1470 + serialNumber,
1.1471 + &updateParameters,
1.1472 + iCallBacks[displayedXIndex].iCallBackClientParam,
1.1473 + &contextUpdate);
1.1474 + }
1.1475 +
1.1476 + }
1.1477 +
1.1478 + if (startUpdateNotification)
1.1479 + {
1.1480 + EndUpdateNotifications(aScreenNumber, aBuffer, contextUpdate, aRegion);
1.1481 + }
1.1482 + else
1.1483 + {
1.1484 + UpdateNotifications(aScreenNumber, aBuffer, contextUpdate, aRegion);
1.1485 + }
1.1486 +
1.1487 + if (eventsReceived != eventsFound)
1.1488 + {
1.1489 + if (aStatusConsumed && !(eventsFound & ESOWF_EventAvailable))
1.1490 + {
1.1491 + User::RequestComplete(aStatusConsumed, KErrCancel);
1.1492 + }
1.1493 +
1.1494 + if (aStatusDisplayed && !(eventsFound & ESOWF_EventDisplayed))
1.1495 + {
1.1496 + *aTimeStamp = 0;
1.1497 + User::RequestComplete(aStatusDisplayed, KErrCancel);
1.1498 + }
1.1499 +
1.1500 + if (aStatusDispXTimes && !(eventsFound & ESOWF_EventDisplayedX))
1.1501 + {
1.1502 + User::RequestComplete(aStatusDispXTimes, KErrCancel);
1.1503 + }
1.1504 + }
1.1505 + NFLOG(("### EXIT * CSurfaceStream::SetNotifications()"));
1.1506 + }
1.1507 +
1.1508 +TInt CSurfaceStream::AddNewGlobalNotification(TRequestStatus* aStatusDisplayed, TInt aAssociatedScreens)
1.1509 + {
1.1510 + TInt maxIdx = iGlobalNotifications.Count();
1.1511 + TInt retIdx = KInvalidIndex;
1.1512 + for (TInt i = 0; i < maxIdx; i++)
1.1513 + {
1.1514 + if (iGlobalNotifications[i].iStatus == NULL)
1.1515 + {
1.1516 + NFLOG(("### ENTER * CSurfaceStream::AddNewGlobalNotification found free idx(%d)", i));
1.1517 + retIdx = i;
1.1518 + break;
1.1519 + }
1.1520 + }
1.1521 +
1.1522 + if (retIdx == KInvalidIndex)
1.1523 + {
1.1524 + TGlobalNotification newNotification;
1.1525 + if (iGlobalNotifications.Append(newNotification) == KErrNone)
1.1526 + {
1.1527 + retIdx = iGlobalNotifications.Count() - 1;
1.1528 + }
1.1529 + }
1.1530 +
1.1531 + if (retIdx != KInvalidIndex)
1.1532 + {
1.1533 + NFLOG(("### ENTER * CSurfaceStream::AddNewGlobalNotification populating idx(%d, status(%p) associated screens=0x%x)", retIdx, aStatusDisplayed, aAssociatedScreens));
1.1534 + iGlobalNotifications[retIdx].Reset();
1.1535 + iGlobalNotifications[retIdx].iStatus = aStatusDisplayed;
1.1536 + iGlobalNotifications[retIdx].iThreadId = RThread().Id();
1.1537 + iGlobalNotifications[retIdx].iPendingNotifications = aAssociatedScreens;
1.1538 + }
1.1539 +
1.1540 + return retIdx;
1.1541 + }
1.1542 +
1.1543 +void CSurfaceStream::SetAllNotifications(TInt aBuffer,
1.1544 + TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp,
1.1545 + TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes,
1.1546 + TRequestStatus* aStatusConsumed, const TRegion* aRegion)
1.1547 + {
1.1548 + NFLOG(("### ENTER * CSurfaceStream::SetAllNotifications()"));
1.1549 + TInt32 eventsToProcess = 0;
1.1550 + // let's take in evidence the events we have to process
1.1551 +
1.1552 + TNewGlobalNotifications newGlobalNotifications;
1.1553 + TInt idx = 0;
1.1554 +
1.1555 + if (aStatusConsumed && iNumberOfScreenAttachedAvailableNotif > 0)
1.1556 + {
1.1557 + if ((idx = AddNewGlobalNotification(aStatusConsumed, iNumberOfScreenAttachedAvailableNotif)) != KInvalidIndex)
1.1558 + {
1.1559 + newGlobalNotifications.iNewAvailableIdx = idx;
1.1560 + eventsToProcess |= ESOWF_EventAvailable;
1.1561 + }
1.1562 + }
1.1563 +
1.1564 + if (aStatusDisplayed && iNumberOfScreenAttachedDisplayedNotif > 0)
1.1565 + {
1.1566 + if ((idx = AddNewGlobalNotification(aStatusDisplayed, iNumberOfScreenAttachedDisplayedNotif)) != KInvalidIndex)
1.1567 + {
1.1568 + newGlobalNotifications.iNewDisplayedIdx = idx;
1.1569 + eventsToProcess |= ESOWF_EventDisplayed;
1.1570 + }
1.1571 + }
1.1572 +
1.1573 + if (aStatusDispXTimes && iNumberOfScreenAttachedDisplayedXNotif > 0)
1.1574 + {
1.1575 + if ((idx = AddNewGlobalNotification(aStatusDispXTimes, iNumberOfScreenAttachedDisplayedXNotif)) != KInvalidIndex)
1.1576 + {
1.1577 + newGlobalNotifications.iNewDisplayedXIdx = idx;
1.1578 + eventsToProcess |= ESOWF_EventDisplayedX;
1.1579 + }
1.1580 + }
1.1581 +
1.1582 + NFLOG(("### CSurfaceStream::SetAllNotifications eventsToProcess(0x%x)", eventsToProcess));
1.1583 +
1.1584 + idx = iCallBacks.Count();
1.1585 + TInt prevScreenNumber = KNoAssociatedScreenNumber;
1.1586 + TInt screenNumber = KNoAssociatedScreenNumber;
1.1587 + idx = iCallBacks.Count();
1.1588 + while (idx--)
1.1589 + {
1.1590 + if (iCallBacks[idx].iCallBackClientParam &&
1.1591 + (iCallBacks[idx].iEventMask == ESOWF_EventUpdated) &&
1.1592 + ((screenNumber = iCallBacks[idx].iScreenNumber) != KNoAssociatedScreenNumber)
1.1593 + && prevScreenNumber != screenNumber)
1.1594 + {
1.1595 + NFLOG(("### CSurfaceStream::SetAllNotifications update composer %d", screenNumber));
1.1596 + SetNotifications(aBuffer,
1.1597 + aStatusDisplayed, aTimeStamp,
1.1598 + aStatusDispXTimes, aDisplayedXTimes,
1.1599 + aStatusConsumed, aRegion, screenNumber, newGlobalNotifications);
1.1600 +
1.1601 + prevScreenNumber = screenNumber;
1.1602 + }
1.1603 +
1.1604 + }
1.1605 +
1.1606 + if (aStatusConsumed && !(eventsToProcess & ESOWF_EventAvailable))
1.1607 + {
1.1608 + User::RequestComplete(aStatusConsumed, KErrCancel);
1.1609 + }
1.1610 +
1.1611 + if (aStatusDisplayed && !(eventsToProcess & ESOWF_EventDisplayed))
1.1612 + {
1.1613 + *aTimeStamp = 0;
1.1614 + User::RequestComplete(aStatusDisplayed, KErrCancel);
1.1615 + }
1.1616 +
1.1617 + if (aStatusDispXTimes && !(eventsToProcess & ESOWF_EventDisplayedX))
1.1618 + {
1.1619 + User::RequestComplete(aStatusDispXTimes, KErrCancel);
1.1620 + }
1.1621 + NFLOG(("### EXIT * CSurfaceStream::SetAllNotifications()"));
1.1622 +
1.1623 + }
1.1624 +
1.1625 +void CSurfaceStream::ProcessNotifications(TInt32 aEvent,
1.1626 + TInt32 aScreenNumber,
1.1627 + TInt32 aOperation,
1.1628 + TInt32 aSerialNumber,
1.1629 + TInt32* aReturnMask)
1.1630 + {
1.1631 + Guard g(iRefCountMutex);
1.1632 + NFLOG(("### ENTER CSurfaceStream::ProcessNotifications()"));
1.1633 +
1.1634 + TInt32 eventsToFind = aEvent & ESOWF_SUSEventsMask;
1.1635 + TInt idx = iCallBacks.Count();
1.1636 + while(idx-- && eventsToFind)
1.1637 + {
1.1638 + TInt32 currentEvent = iCallBacks[idx].iEventMask;
1.1639 + if (currentEvent & aEvent)
1.1640 + {
1.1641 + TNotificationBase* notifBase = (TNotificationBase*) iCallBacks[idx].iCallBackClientParam;
1.1642 + if (notifBase && notifBase->iStatus && iCallBacks[idx].iScreenNumber == aScreenNumber)
1.1643 + {
1.1644 + TInt callBackOperation = (aOperation == EDefaultOperation) ? currentEvent : ESOWF_ObserverCheckVisible;
1.1645 + eventsToFind &= ~currentEvent;
1.1646 + switch (currentEvent)
1.1647 + {
1.1648 + case ESOWF_EventAvailable:
1.1649 + Available(callBackOperation, aSerialNumber, NULL, iCallBacks[idx].iCallBackClientParam, aReturnMask);
1.1650 + break;
1.1651 +
1.1652 + case ESOWF_EventDisplayed:
1.1653 + Displayed(callBackOperation, aSerialNumber, NULL, iCallBacks[idx].iCallBackClientParam, aReturnMask);
1.1654 + break;
1.1655 +
1.1656 + case ESOWF_EventDisplayedX:
1.1657 + DisplayedXTimes(callBackOperation, aSerialNumber, NULL, iCallBacks[idx].iCallBackClientParam, aReturnMask);
1.1658 + break;
1.1659 +
1.1660 + default:
1.1661 + break;
1.1662 + }
1.1663 + }
1.1664 + }
1.1665 + }
1.1666 + NFLOG(("### EXIT CSurfaceStream::ProcessNotifications()"));
1.1667 + }
1.1668 +
1.1669 +TInt CSurfaceStream::CheckBufferNumber(TInt aBuffer,
1.1670 + TRequestStatus* aStatusDisplayed,
1.1671 + TRequestStatus* aStatusDispXTimes,
1.1672 + TRequestStatus* aStatusConsumed)
1.1673 + {
1.1674 + if (aBuffer < 0 || aBuffer >= iInfo.iBuffers)
1.1675 + {
1.1676 + if (aStatusConsumed)
1.1677 + {
1.1678 + User::RequestComplete(aStatusConsumed, KErrArgument);
1.1679 + }
1.1680 + if (aStatusDisplayed)
1.1681 + {
1.1682 + User::RequestComplete(aStatusDisplayed, KErrArgument);
1.1683 + }
1.1684 + if (aStatusDispXTimes)
1.1685 + {
1.1686 + User::RequestComplete(aStatusDispXTimes, KErrArgument);
1.1687 + }
1.1688 + return KErrArgument;
1.1689 + }
1.1690 + else
1.1691 + {
1.1692 + return KErrNone;
1.1693 + }
1.1694 + }
1.1695 +
1.1696 +void CSurfaceStream::Available(TInt32 aEvent,
1.1697 + TInt32 aSerialNumber,
1.1698 + ContentUpdatedParams* aParams,
1.1699 + void* aCallBackData,
1.1700 + TInt32* aReturnMask)
1.1701 + {
1.1702 + (void) aReturnMask;
1.1703 + NFLOG(("### ENTER CSurfaceStream::Available aEvent(0x%x) aSerialNumber(0x%x) "
1.1704 + "aParams(0x%x) aCallBackData(0x%x) aReturnMask(0x%x)",
1.1705 + aEvent, aSerialNumber, aParams, aCallBackData, aReturnMask));
1.1706 +
1.1707 + TNotificationAvailable* callBackData = (TNotificationAvailable*) aCallBackData;
1.1708 + if (!callBackData)
1.1709 + {
1.1710 + return;
1.1711 + }
1.1712 +
1.1713 + switch(aEvent)
1.1714 + {
1.1715 + case ESOWF_ObserverProcessing:
1.1716 + NFLOG(("###CSurfaceStream::Available ESOWF_ObserverProcessing"));
1.1717 + // when a new available notification request is issued by SUS, we have to:
1.1718 + // 1. Overflow the old request status (GCE behaviour)
1.1719 + // 2. Update the observer
1.1720 + // 3. If immediate availabilty chec if the old request status can be completed
1.1721 + // 4. Inform the composer about any active available notifications requests
1.1722 + {
1.1723 + if (aParams)
1.1724 + {
1.1725 + // let's check first for overflow conditions
1.1726 + // and overflow the oldest if exists (GCE behaviour)
1.1727 + if (callBackData->iStatus)
1.1728 + {
1.1729 + NFLOG(("###CSurfaceStream::Available ESOWF_ObserverProcessing Overflow"));
1.1730 + // oldest notifications is overflowed (like GCE behaviour)
1.1731 + RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrOverflow);
1.1732 + callBackData->iStatus = NULL;
1.1733 + callBackData->iThreadId = 0;
1.1734 + callBackData->iBufferNumber = -1;
1.1735 + }
1.1736 +
1.1737 + // propagate the new data
1.1738 + callBackData->iSerialNumber = aSerialNumber;
1.1739 + TBool multibuffered = iInfo.iBuffers > 1;
1.1740 + if (multibuffered)
1.1741 + {
1.1742 + callBackData->iStatus = callBackData->iNewStatus;
1.1743 + callBackData->iThreadId = callBackData->iNewThreadId;
1.1744 + callBackData->iBufferNumber = callBackData->iNewBufferNumber;
1.1745 + callBackData->iGlobalIndex = callBackData->iNewGlobalIndex;
1.1746 + }
1.1747 + else
1.1748 + {
1.1749 + callBackData->iStatus = aParams->iStatusConsumed;
1.1750 + callBackData->iThreadId = RThread().Id();
1.1751 + callBackData->iBufferNumber = aParams->iBuffer;
1.1752 + callBackData->iGlobalIndex = aParams->iGlobalNotifications.iNewAvailableIdx;
1.1753 + }
1.1754 +
1.1755 + // the availability can be immediately completed if the
1.1756 + // visibility status is known and the composer is not composing at that momment
1.1757 + if (callBackData->iStatus && aParams->iImmediateAvailable)
1.1758 + {
1.1759 + NFLOG(("###CSurfaceStream::Available ESOWF_ObserverProcessing Immediate Available"));
1.1760 + if (iAcquiredWriteBuffer != WFC_INVALID_HANDLE)
1.1761 + {
1.1762 + iAcquiredWriteBuffer = BUFFER_WRITE_UPDATE_OVERWRITE;
1.1763 + }
1.1764 +
1.1765 + SetReadBufferIndex(aParams->iBuffer);
1.1766 + // immediate notification is possible because the context
1.1767 + // is not composing at this momment
1.1768 + if (aParams->iImmediateVisibility == SYM_CONTENT_NOT_VISIBLE)
1.1769 + {
1.1770 + RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrNotVisible);
1.1771 + }
1.1772 + else
1.1773 + {
1.1774 + RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrNone);
1.1775 + }
1.1776 + ResetCallBackData(callBackData, aEvent);
1.1777 + }
1.1778 +
1.1779 + if (multibuffered)
1.1780 + {
1.1781 + callBackData->iNewStatus = aParams->iStatusConsumed;
1.1782 + callBackData->iNewThreadId = RThread().Id();
1.1783 + callBackData->iNewBufferNumber = aParams->iBuffer;
1.1784 + callBackData->iGlobalIndex = aParams->iGlobalNotifications.iNewAvailableIdx;
1.1785 + }
1.1786 +
1.1787 + // let the composer know that the Availability has to be analysed further
1.1788 + if (aReturnMask && callBackData->iStatus)
1.1789 + {
1.1790 + NFLOG(("###CSurfaceStream::Available ESOWF_ObserverProcessing *aReturnMask |= ESOWF_EventAvailable"));
1.1791 + *aReturnMask |= ESOWF_EventAvailable;
1.1792 + }
1.1793 + }
1.1794 + }
1.1795 + break;
1.1796 +
1.1797 + case ESOWF_EventAvailable:
1.1798 + NFLOG(("###CSurfaceStream::Available ESOWF_EventAvailable"));
1.1799 + if (callBackData->iStatus)
1.1800 + {
1.1801 + // if it is an event just added during composition, we wxpect the same serial number
1.1802 + RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrNone);
1.1803 + // clean the old reques notification related info
1.1804 + callBackData->iSerialNumber = aSerialNumber;
1.1805 + callBackData->iStatus = NULL;
1.1806 + callBackData->iThreadId = 0;
1.1807 + callBackData->iBufferNumber = -1;
1.1808 + }
1.1809 + break;
1.1810 +
1.1811 + case ESOWF_ObserverCheckVisible:
1.1812 + NFLOG(("###CSurfaceStream::Available ESOWF_ObserverCheckVisible"));
1.1813 + if (callBackData->iStatus)
1.1814 + {
1.1815 + // complete the old request status (standard GCE behaviour)
1.1816 + RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrNotVisible);
1.1817 + // clean the old reques notification related info
1.1818 + callBackData->iSerialNumber = aSerialNumber;
1.1819 + callBackData->iStatus = NULL;
1.1820 + callBackData->iThreadId = 0;
1.1821 + callBackData->iBufferNumber = -1;
1.1822 + }
1.1823 + break;
1.1824 +
1.1825 + case ESOWF_ObserverCancel:
1.1826 + {
1.1827 + NFLOG(("###CSurfaceStream::Available ESOWF_ObserverCancel"));
1.1828 + // cancel both requests if they are valid
1.1829 + RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrCancel);
1.1830 + RequestComplete(callBackData->iNewThreadId, callBackData->iNewStatus, callBackData->iGlobalIndex, KErrCancel);
1.1831 + ResetCallBackData(callBackData, aEvent);
1.1832 + }
1.1833 + break;
1.1834 +
1.1835 + default:
1.1836 + return;
1.1837 + }
1.1838 + NFLOG(("EXIT ###CSurfaceStream::Available()"));
1.1839 + }
1.1840 +
1.1841 +
1.1842 +void CSurfaceStream::Displayed(TInt32 aEvent, TInt32 aSerialNumber, ContentUpdatedParams* aParams, void* aCallBackData, TInt32* aReturnMask)
1.1843 + {
1.1844 + TInt notification = KErrNone;
1.1845 + (void) aReturnMask;
1.1846 + NFLOG(("### ENTER CSurfaceStream::Displayed aEvent(0x%x) aSerialNumber(0x%x) "
1.1847 + "aParams(0x%x) aCallBackData(0x%x) aReturnMask(0x%x)",
1.1848 + aEvent, aSerialNumber, aParams, aCallBackData, aReturnMask));
1.1849 + TNotificationDisplayed* callBackData = (TNotificationDisplayed*) aCallBackData;
1.1850 + if (!callBackData)
1.1851 + {
1.1852 + return;
1.1853 + }
1.1854 +
1.1855 + switch(aEvent)
1.1856 + {
1.1857 + case ESOWF_ObserverProcessing:
1.1858 + NFLOG(("###CSurfaceStream::Displayed ESOWF_ObserverProcessing"));
1.1859 + // When a new available notification request is issued by SUS, we have to:
1.1860 + // 1. Overflow the previous request status
1.1861 + // 2. Update the observer
1.1862 + // 3. Inform the composer about any active available notifications requests
1.1863 +
1.1864 + if (callBackData->iStatus)
1.1865 + {
1.1866 + NFLOG(("###CSurfaceStream::Displayed ESOWF_ObserverProcessing Overflowing"));
1.1867 + RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrOverflow);
1.1868 + ResetCallBackData(callBackData, aEvent);
1.1869 + }
1.1870 + if (aParams && aParams->iStatusDisplayed)
1.1871 + {
1.1872 + __ASSERT_DEBUG(aParams->iTimeStamp,
1.1873 + (iRefCountMutex.Signal(),Panic(EOwfInvalidSUSDisplayedParameter)));
1.1874 + callBackData->iStatus = aParams->iStatusDisplayed;
1.1875 + callBackData->iThreadId = RThread().Id();
1.1876 + callBackData->iBufferNumber = aParams->iBuffer;
1.1877 + callBackData->iSerialNumber = aSerialNumber;
1.1878 + callBackData->iTimeStamp = aParams->iTimeStamp;
1.1879 + callBackData->iGlobalIndex = aParams->iGlobalNotifications.iNewDisplayedIdx;
1.1880 + NFLOG(("###CSurfaceStream::Displayed iGlobalIndex(%d)", callBackData->iGlobalIndex));
1.1881 + }
1.1882 + if (aReturnMask && callBackData->iStatus)
1.1883 + {
1.1884 + NFLOG(("###CSurfaceStream::Displayed ESOWF_ObserverProcessing *aReturnMask |= ESOWF_EventDisplayed"));
1.1885 + *aReturnMask |= ESOWF_EventDisplayed;
1.1886 + }
1.1887 + return;
1.1888 +
1.1889 + case ESOWF_EventDisplayed:
1.1890 + // this invoked by composer
1.1891 + NFLOG(("###CSurfaceStream::Displayed ESOWF_EventDisplayed"));
1.1892 + if (!callBackData->iStatus)
1.1893 + {
1.1894 + // no active notification, nothing to do
1.1895 + NFLOG(("###CSurfaceStream::Displayed ESOWF_EventDisplayed no active notifications"));
1.1896 + return;
1.1897 + }
1.1898 + // deffer for next composition the processing if the updated happended during a composition
1.1899 + if (callBackData->iSerialNumber == aSerialNumber && aReturnMask)
1.1900 + {
1.1901 + NFLOG(("###CSurfaceStream::Displayed ESOWF_EventDisplayed *aReturnMask |= ESOWF_EventDisplayed"));
1.1902 + *aReturnMask |= ESOWF_EventDisplayed;
1.1903 + return;
1.1904 + }
1.1905 + // complete the active request status
1.1906 + callBackData->iSerialNumber = aSerialNumber;
1.1907 + *callBackData->iTimeStamp = User::FastCounter();
1.1908 + notification = KErrNone;
1.1909 + break;
1.1910 +
1.1911 + case ESOWF_ObserverCheckVisible:
1.1912 + // visibility check comming from composer
1.1913 + NFLOG(("###CSurfaceStream::Displayed ESOWF_ObserverCheckVisible"));
1.1914 + if (!callBackData->iStatus)
1.1915 + {
1.1916 + // deffer for next composition the processing if the updated happended during a composition
1.1917 + // or if no active notification, nothing to do
1.1918 + NFLOG(("###CSurfaceStream::Displayed ESOWF_ObserverCheckVisible = Not Visible"));
1.1919 + return;
1.1920 + }
1.1921 + notification = KErrNotVisible;
1.1922 + callBackData->iSerialNumber = aSerialNumber;
1.1923 + break;
1.1924 +
1.1925 + case ESOWF_ObserverCancel:
1.1926 + // cancel the active notification
1.1927 + NFLOG(("###CSurfaceStream::Displayed ESOWF_ObserverCancel"));
1.1928 + if (!callBackData->iStatus)
1.1929 + {
1.1930 + return;
1.1931 + }
1.1932 + notification = KErrCancel;
1.1933 + break;
1.1934 +
1.1935 + default:
1.1936 + return;
1.1937 + }
1.1938 +
1.1939 + RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, notification);
1.1940 + ResetCallBackData(callBackData, aEvent);
1.1941 + NFLOG(("EXIT ###CSurfaceStream::Displayed()"));
1.1942 + }
1.1943 +
1.1944 +void CSurfaceStream::DisplayedXTimes(TInt32 aEvent, TInt32 aSerialNumber, ContentUpdatedParams* aParams, void* aCallBackData, TInt32* aReturnMask)
1.1945 + {
1.1946 + TInt notification = KErrNone;
1.1947 +
1.1948 + NFLOG(("### ENTER CSurfaceStream::DisplayedXTimes aEvent(0x%x) aSerialNumber(0x%x) "
1.1949 + "aParams(0x%x) aCallBackData(0x%x) aReturnMask(0x%x)",
1.1950 + aEvent, aSerialNumber, aParams, aCallBackData, aReturnMask));
1.1951 +
1.1952 + TNotificationDisplayedX* callBackData = (TNotificationDisplayedX*) aCallBackData;
1.1953 + if (!callBackData)
1.1954 + {
1.1955 + return;
1.1956 + }
1.1957 +
1.1958 + switch(aEvent)
1.1959 + {
1.1960 + case ESOWF_ObserverProcessing:
1.1961 + // When a new available notification request is issued by SUS, we have to:
1.1962 + // 1. Overflow the previous request status
1.1963 + // 2. Update the observer
1.1964 + // 3. Inform the composer about any active available notifications requests
1.1965 + NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_ObserverProcessing"));
1.1966 + if (callBackData->iStatus)
1.1967 + {
1.1968 + NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_ObserverProcessing Overflowing"));
1.1969 + RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrOverflow);
1.1970 + ResetCallBackData(callBackData, aEvent);
1.1971 + }
1.1972 + if (aParams && aParams->iStatusDispXTimes)
1.1973 + {
1.1974 + __ASSERT_DEBUG(aParams->iDisplayedXTimes && *aParams->iDisplayedXTimes >= 1,
1.1975 + (iRefCountMutex.Signal(),Panic(EOwfInvalidSUSDisplayedXTimesParameter)));
1.1976 + callBackData->iStatus = aParams->iStatusDispXTimes;
1.1977 + callBackData->iThreadId = RThread().Id();
1.1978 + callBackData->iBufferNumber = aParams->iBuffer;
1.1979 + callBackData->iSerialNumber = aSerialNumber;
1.1980 + callBackData->iCount = *aParams->iDisplayedXTimes;
1.1981 + callBackData->iGlobalIndex = aParams->iGlobalNotifications.iNewDisplayedXIdx;
1.1982 + }
1.1983 +
1.1984 + if (aReturnMask && callBackData->iStatus)
1.1985 + {
1.1986 + NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_ObserverProcessing *aReturnMask |= ESOWF_EventDisplayedX"));
1.1987 + *aReturnMask |= ESOWF_EventDisplayedX;
1.1988 + }
1.1989 + return;
1.1990 +
1.1991 + case ESOWF_EventDisplayedX:
1.1992 + NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_EventDisplayedX"));
1.1993 + if (!callBackData->iStatus)
1.1994 + {
1.1995 + // no active notification, nothing to do
1.1996 + return;
1.1997 + }
1.1998 +
1.1999 + // deffer for next composition the processing if the updated happended during a composition
1.2000 + if (callBackData->iSerialNumber == aSerialNumber)
1.2001 + {
1.2002 + if (aReturnMask)
1.2003 + {
1.2004 + NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_EventDisplayedX *aReturnMask |= ESOWF_EventDisplayedX"));
1.2005 + *aReturnMask |= ESOWF_EventDisplayedX;
1.2006 + }
1.2007 + return;
1.2008 + }
1.2009 +
1.2010 + callBackData->iSerialNumber = aSerialNumber;
1.2011 +
1.2012 + // complete the active request status
1.2013 + if (callBackData->iCount > 1)
1.2014 + {
1.2015 + // inform the composer a new notification is needed
1.2016 + callBackData->iCount--;
1.2017 + if (aReturnMask)
1.2018 + {
1.2019 + NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_EventDisplayedX *aReturnMask |= ESOWF_EventDisplayedX iCount(%d)", callBackData->iCount));
1.2020 + *aReturnMask |= ESOWF_EventDisplayedX;
1.2021 + }
1.2022 + return;
1.2023 + }
1.2024 +
1.2025 + NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_EventDisplayedX iCount(%d)", callBackData->iCount));
1.2026 + notification = KErrNone;
1.2027 + break;
1.2028 +
1.2029 + case ESOWF_ObserverCheckVisible:
1.2030 + NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_ObserverCheckVisible"));
1.2031 + // visibility check comming from composer
1.2032 + if (!callBackData->iStatus ||
1.2033 + callBackData->iSerialNumber == aSerialNumber)
1.2034 + {
1.2035 + // deffer for next composition the processing if the updated happended during a composition
1.2036 + // or if no active notification, nothing to do
1.2037 + return;
1.2038 + }
1.2039 + callBackData->iSerialNumber = aSerialNumber;
1.2040 + notification = KErrNotVisible;
1.2041 + break;
1.2042 +
1.2043 + case ESOWF_ObserverCancel:
1.2044 + // cancel the active notification
1.2045 + NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_ObserverCancel"));
1.2046 + if (!callBackData->iStatus)
1.2047 + {
1.2048 + return;
1.2049 + }
1.2050 + notification = KErrCancel;
1.2051 + break;
1.2052 +
1.2053 + default:
1.2054 + return;
1.2055 + }
1.2056 +
1.2057 + RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, notification);
1.2058 + ResetCallBackData(callBackData, aEvent);
1.2059 + NFLOG(("EXIT ###CSurfaceStream::DisplayedXTimes()"));
1.2060 + }
1.2061 +
1.2062 +void CSurfaceStream::ResetCallBackData(void* aCallBackData,
1.2063 + TInt32 aEvent)
1.2064 + {
1.2065 + switch (aEvent)
1.2066 + {
1.2067 + case ESOWF_EventAvailable:
1.2068 + {
1.2069 + TNotificationAvailable* available = (TNotificationAvailable*) aCallBackData;
1.2070 + available->iStatus = NULL;
1.2071 + available->iThreadId = 0;
1.2072 + available->iBufferNumber = -1;
1.2073 + available->iGlobalIndex = KInvalidIndex;
1.2074 + available->iNewBufferNumber = -1;
1.2075 + available->iNewStatus = NULL;
1.2076 + available->iNewThreadId = 0;
1.2077 + available->iNewGlobalIndex = KInvalidIndex;
1.2078 + }
1.2079 + break;
1.2080 +
1.2081 + case ESOWF_EventDisplayed:
1.2082 + {
1.2083 + TNotificationDisplayed* displayed = (TNotificationDisplayed*) aCallBackData;
1.2084 + displayed->iStatus = NULL;
1.2085 + displayed->iThreadId = 0;
1.2086 + displayed->iBufferNumber = -1;
1.2087 + displayed->iTimeStamp = NULL;
1.2088 + displayed->iGlobalIndex = KInvalidIndex;
1.2089 + }
1.2090 + break;
1.2091 +
1.2092 + case ESOWF_EventDisplayedX:
1.2093 + {
1.2094 + TNotificationDisplayedX* displayed = (TNotificationDisplayedX*) aCallBackData;
1.2095 + displayed->iStatus = NULL;
1.2096 + displayed->iThreadId = 0;
1.2097 + displayed->iBufferNumber = -1;
1.2098 + displayed->iCount = 0;
1.2099 + displayed->iGlobalIndex = KInvalidIndex;
1.2100 + }
1.2101 + break;
1.2102 +
1.2103 + default:
1.2104 + break;
1.2105 + }
1.2106 + }
1.2107 +
1.2108 +void CSurfaceStream::CancelNotifications()
1.2109 + {
1.2110 + NFLOG(("ENTER ###CSurfaceStream::CancelNotifications()"));
1.2111 + TInt cancelEvents = ESOWF_AllEventsMask;
1.2112 + RemoveObserver(cancelEvents, NULL);
1.2113 + NFLOG(("EXIT ###CSurfaceStream::CancelNotifications()"));
1.2114 + }
1.2115 +
1.2116 +TInt CSurfaceStream::Stride(TInt aWidth, TUidPixelFormat aPixelFormat)
1.2117 + {
1.2118 +
1.2119 + TInt bytesPerPixel = BytesPerPixel(aPixelFormat);
1.2120 +
1.2121 + if (bytesPerPixel >= 0)
1.2122 + {
1.2123 + return bytesPerPixel * aWidth; // number of bytes between start of one line and start of next
1.2124 + }
1.2125 + else
1.2126 + {
1.2127 + return (aWidth-(bytesPerPixel+1)) / (-bytesPerPixel);
1.2128 + }
1.2129 + }
1.2130 +
1.2131 +void CSurfaceStream::SetFlipState(TBool aFlip)
1.2132 + {
1.2133 + Guard g1(iRefCountMutex);
1.2134 + if (aFlip)
1.2135 + {
1.2136 + iNewFlip = EFlippedTargetFlipped;
1.2137 + }
1.2138 + else
1.2139 + {
1.2140 + iNewFlip = EFlippedTargetNormal;
1.2141 + }
1.2142 + }
1.2143 +
1.2144 +TInt CSurfaceStream::GetChunkHandle()
1.2145 + {
1.2146 + return iBufferChunk.Handle();
1.2147 + }