graphicscomposition/openwfsupport/src/surfacestream.cpp
changeset 0 5d03bc08d59c
child 36 01a6848ebfd7
child 163 bbf46f59e123
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // SurfaceStream.cpp
       
    15 // CSurfaceStream implementation
       
    16 
       
    17 #include <e32base.h>
       
    18 #include <graphics/suerror.h>
       
    19 #include <graphics/surfacetypes.h>
       
    20 #include <hal.h>
       
    21 #include "surfacestream.h"
       
    22 #include "openwfcpanic.h"
       
    23 #include "streammap.h"
       
    24 #include "symbianstream.h"
       
    25 #define WFC_INVALID_HANDLE NULL
       
    26 
       
    27 const TInt KInvalidIndex = KNoAssociatedScreenNumber;
       
    28 
       
    29 struct CSurfaceStream::TCallBackEntry
       
    30 	{
       
    31 	typedef SymbianStreamCallback	TSimpleCallback;
       
    32 	TCallBackEntry();
       
    33 	void Reset();
       
    34 	TSimpleCallback iCallBackFunction;
       
    35 	TAny*			iCallBackClientParam;
       
    36 	TInt32			iEventMask;
       
    37 	TInt32          iScreenNumber;
       
    38 	};
       
    39 
       
    40 CSurfaceStream::TCallBackEntry::TCallBackEntry():
       
    41 iCallBackFunction(NULL),
       
    42 iCallBackClientParam(NULL),
       
    43 iEventMask(ESOWF_NoEvent),
       
    44 iScreenNumber(KNoAssociatedScreenNumber)
       
    45     {
       
    46     }
       
    47 
       
    48 void CSurfaceStream::TCallBackEntry::Reset()
       
    49     {
       
    50     iCallBackFunction = NULL;
       
    51     iCallBackClientParam = NULL;
       
    52     iEventMask = ESOWF_NoEvent;
       
    53     iScreenNumber = KNoAssociatedScreenNumber;
       
    54     }
       
    55 
       
    56 struct CSurfaceStream::TGlobalNotification
       
    57     {
       
    58     TGlobalNotification();
       
    59     void Reset();
       
    60     TRequestStatus* iStatus;
       
    61     TThreadId       iThreadId;
       
    62     TInt            iPendingNotifications;
       
    63     TInt            iCompletedOkNotifications;
       
    64     TInt            iCanceledNotifications;
       
    65     TInt            iOverflowedNotifications;
       
    66     TInt            iNotVisibleNotifications;
       
    67     TInt            iOtherNotifications;
       
    68     };
       
    69 
       
    70 
       
    71 CSurfaceStream::TGlobalNotification::TGlobalNotification():
       
    72 iStatus(NULL),
       
    73 iThreadId(0),
       
    74 iPendingNotifications(0),
       
    75 iCompletedOkNotifications(0),
       
    76 iCanceledNotifications(0),
       
    77 iOverflowedNotifications(0),
       
    78 iNotVisibleNotifications(0),
       
    79 iOtherNotifications(0)
       
    80     {
       
    81     
       
    82     }
       
    83 
       
    84 void CSurfaceStream::TGlobalNotification::Reset()
       
    85     {
       
    86     iStatus = NULL;
       
    87     iThreadId = 0;
       
    88     iPendingNotifications = 0;
       
    89     iCompletedOkNotifications = 0;
       
    90     iCanceledNotifications = 0;
       
    91     iOverflowedNotifications = 0;
       
    92     iNotVisibleNotifications = 0;
       
    93     iOtherNotifications = 0;
       
    94     }
       
    95 
       
    96 struct CSurfaceStream::TNewGlobalNotifications
       
    97     {
       
    98     TNewGlobalNotifications();
       
    99     TInt iNewAvailableIdx;
       
   100     TInt iNewDisplayedIdx;
       
   101     TInt iNewDisplayedXIdx;
       
   102     };
       
   103 
       
   104 CSurfaceStream::TNewGlobalNotifications::TNewGlobalNotifications():
       
   105 iNewAvailableIdx(KInvalidIndex),
       
   106 iNewDisplayedIdx(KInvalidIndex),
       
   107 iNewDisplayedXIdx(KInvalidIndex)
       
   108     {
       
   109     }
       
   110 
       
   111 CSurfaceStream::Guard::Guard(RFastLock& aLock):
       
   112 iLock(aLock)
       
   113     {
       
   114     iLock.Wait();
       
   115     }
       
   116 
       
   117 CSurfaceStream::Guard::~Guard()
       
   118     {
       
   119     iLock.Signal();
       
   120     }
       
   121 
       
   122 CSurfaceStream::CSurfaceStream():
       
   123 	iSurfaceId(TSurfaceId::CreateNullId()),
       
   124 	iBufferInfo(NULL),
       
   125 	iProtected(EFalse),
       
   126 	iNumberOfScreenAttachedAvailableNotif(0),
       
   127 	iNumberOfScreenAttachedDisplayedNotif(0),
       
   128 	iNumberOfScreenAttachedDisplayedXNotif(),
       
   129 	iFlipState(EFlippedTargetNormal),
       
   130     iNewFlip(EFlipNotSet)
       
   131 	{
       
   132 	iStreamProxySurfaceId.iInternal[TSurfaceId::TSurfaceUsage::EObjectRefField]=
       
   133 			reinterpret_cast<TInt>(this);
       
   134 	iStreamProxySurfaceId.iInternal[TSurfaceId::TSurfaceUsage::ETypeClassField]=
       
   135 			TSurfaceId::EStreamHandle<<TSurfaceId::TSurfaceUsage::ETypeClassShift;
       
   136 	}
       
   137 
       
   138 CSurfaceStream::ContentUpdatedParams::ContentUpdatedParams(TInt aBuffer,
       
   139                                                            TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp,
       
   140                                                            TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes,
       
   141                                                            TRequestStatus* aStatusConsumed, const TRegion* aRegion,
       
   142                                                            TBool aImmediateAvailable, TInt32 aImmediateVisibility,
       
   143                                                            const TNewGlobalNotifications& aGlobalNotifications):
       
   144 iBuffer(aBuffer),
       
   145 iStatusDisplayed(aStatusDisplayed),
       
   146 iTimeStamp(aTimeStamp),
       
   147 iStatusDispXTimes(aStatusDispXTimes),
       
   148 iDisplayedXTimes(aDisplayedXTimes),
       
   149 iStatusConsumed(aStatusConsumed),
       
   150 iRegion(aRegion),
       
   151 iImmediateAvailable(aImmediateAvailable),
       
   152 iImmediateVisibility(aImmediateVisibility),
       
   153 iGlobalNotifications(aGlobalNotifications)
       
   154     {
       
   155     
       
   156     }
       
   157 
       
   158 CSurfaceStream::~CSurfaceStream()
       
   159 	{
       
   160 	// Cancel any outstanding notifications
       
   161 	CancelNotifications();
       
   162     iCallBacks.Close();
       
   163     iGlobalNotifications.Close();
       
   164     iBufferChunk.Close();
       
   165 	
       
   166     if (!iSurfaceId.IsNull() && iSurfaceId.Type() == TSurfaceTypes::ESurfaceManagerSurface)
       
   167         {
       
   168         TRAP_IGNORE(GetSingletonL().SurfaceManager().CloseSurface(iSurfaceId));
       
   169         }
       
   170 	
       
   171 	iRefCountMutex.Close();
       
   172 	iCallBacksMutex.Close();
       
   173 	delete [] iBufferInfo;
       
   174 	}
       
   175 
       
   176 CSurfaceStream* CSurfaceStream::NewLC(const TSurfaceId& aId)
       
   177 	{
       
   178 	CSurfaceStream* self = new (ELeave)CSurfaceStream();
       
   179 	CleanupStack::PushL(self);
       
   180 	self->ConstructL(aId);
       
   181 	return self;
       
   182 	}
       
   183 
       
   184 void CSurfaceStream::ConstructL(const TSurfaceId& aId)
       
   185 	{
       
   186 	User::LeaveIfError(iRefCountMutex.CreateLocal());
       
   187     User::LeaveIfError(iCallBacksMutex.CreateLocal());
       
   188    
       
   189     RSurfaceManager::TInfoBuf infoBuf;  
       
   190     SurfaceInfoL(aId, infoBuf);
       
   191 	iInfo = infoBuf();
       
   192 
       
   193     COpenWfcStreamMap& stream = GetSingletonL();
       
   194 	//Create array for TBufferInfo
       
   195 	iBufferInfo = new(ELeave) TBufferInfo[iInfo.iBuffers];
       
   196 	for(TInt i = 0; i < iInfo.iBuffers; i++)
       
   197 		{
       
   198 		TInt offset = 0;
       
   199 	    switch(aId.Type())
       
   200 	        {
       
   201 	        case TSurfaceTypes::ESurfaceManagerSurface:
       
   202 	            {
       
   203 	            User::LeaveIfError(stream.SurfaceManager().GetBufferOffset(iSurfaceId,
       
   204 	                     i, offset));
       
   205 	            break;
       
   206 	            }
       
   207 	        case TSurfaceId::EScreenSurface:
       
   208 	            {
       
   209 	            TInt screenId = SurfaceId().iInternal[TSurfaceId::TScreenSurfaceUsage::EScreenField];
       
   210 	            User::LeaveIfError(HAL::Get(screenId, HALData::EDisplayOffsetToFirstPixel, offset));
       
   211 	            break;
       
   212 	            }
       
   213 	        default:
       
   214 	            User::Leave(KErrNotSupported);
       
   215 	        }
       
   216 
       
   217 		iBufferInfo[i].iRefCount = 0;
       
   218 		iBufferInfo[i].iOffset = offset;
       
   219 		}
       
   220 	}
       
   221 
       
   222 void CSurfaceStream::SurfaceInfoL(const TSurfaceId& aId, RSurfaceManager::TInfoBuf& aInfoBuf)
       
   223     {
       
   224     COpenWfcStreamMap& stream = GetSingletonL();    
       
   225     switch(aId.Type())
       
   226         {
       
   227         case TSurfaceTypes::ESurfaceManagerSurface:
       
   228             {
       
   229             iStreamProxySurfaceId.iInternal[TSurfaceId::TSurfaceUsage::EObjectRefField]=
       
   230                     reinterpret_cast<TInt>(this);
       
   231             iStreamProxySurfaceId.iInternal[TSurfaceId::TSurfaceUsage::ETypeClassField]=
       
   232                     TSurfaceId::EStreamHandle<<TSurfaceId::TSurfaceUsage::ETypeClassShift;        
       
   233             
       
   234             User::LeaveIfError(stream.SurfaceManager().OpenSurface(aId));            
       
   235             iSurfaceId = aId;
       
   236             User::LeaveIfError(stream.SurfaceManager().SurfaceInfo(iSurfaceId, aInfoBuf));
       
   237             break;
       
   238             }
       
   239         case TSurfaceId::EScreenSurface:
       
   240             {
       
   241             // DSA surface only has one buffer
       
   242             aInfoBuf().iBuffers = 1;
       
   243             
       
   244             TInt screenId = aId.iInternal[TSurfaceId::TScreenSurfaceUsage::EScreenField];
       
   245             TInt width;
       
   246             User::LeaveIfError(HAL::Get(screenId, HALData::EDisplayXPixels, width));
       
   247                         
       
   248             TInt height;
       
   249             User::LeaveIfError(HAL::Get(screenId, HALData::EDisplayYPixels, height));
       
   250             
       
   251             aInfoBuf().iSize = TSize(width, height);
       
   252             
       
   253             TInt bpp = 0;
       
   254             User::LeaveIfError(HAL::Get(screenId, HALData::EDisplayBitsPerPixel, bpp));
       
   255 
       
   256             TUidPixelFormat pixelFormat = static_cast<TUidPixelFormat> (aId.iInternal[TSurfaceId::TScreenSurfaceUsage::ETypeGuidField]);
       
   257             if (!pixelFormat)
       
   258                 {
       
   259                 //if (bpp==12 || bpp==4))   //This allows low-color indices to be semi-functionally tested
       
   260                 if (bpp==12)
       
   261                     {
       
   262                     pixelFormat = EUidPixelFormatXRGB_4444;
       
   263                     }
       
   264                 else if (bpp == 16)
       
   265                     {
       
   266                     pixelFormat = EUidPixelFormatRGB_565;
       
   267                     }
       
   268                 else if (bpp== 24 || bpp==32)
       
   269                     {
       
   270                     pixelFormat = EUidPixelFormatARGB_8888;
       
   271                     }
       
   272                 else
       
   273                     {
       
   274                     User::Leave(KErrNotSupported);
       
   275                     }
       
   276 
       
   277                 }
       
   278             aInfoBuf().iPixelFormat = pixelFormat;
       
   279             
       
   280 #ifdef  SYMBIAN_ROTATION_MODE_CHANGES
       
   281             TInt displayMode = aId.iInternal[TSurfaceId::TScreenSurfaceUsage::EHalField];
       
   282 #else
       
   283             TInt displayMode = 0;
       
   284             User::LeaveIfError(HAL::Get(screenId, HALData::EDisplayMode, displayMode));
       
   285 #endif            
       
   286             
       
   287 #if defined(SYMBIAN_ROTATION_MODE_CHANGES)
       
   288             if (displayMode & TSurfaceId::TScreenSurfaceUsage::EHalFlippedFlag) // 90 | 270 degree rotation
       
   289                 {
       
   290                 // Swap dimensions and recalculate stride. Assume no padding for now.
       
   291                 aInfoBuf().iSize.iWidth = height;
       
   292                 aInfoBuf().iSize.iHeight = width;
       
   293                 //"vertical" stride has already been fetched
       
   294                 }
       
   295 #elif defined(SYMBIAN_ROTATION_CHANGES)
       
   296             if (aSurface.iInternal[1] & (2 | 8))    // 90 | 270 degree rotation
       
   297                 {
       
   298                 // Swap dimensions and recalculate stride. Assume no padding for now.
       
   299                 aInfoBuf().iSize.iWidth = height;
       
   300                 aInfoBuf().iSize.iHeight = width;
       
   301                 aInfoBuf().iStride = infoBuf().iSize.width * bpp;
       
   302                 }
       
   303 #endif            
       
   304             
       
   305             TInt stride = displayMode;
       
   306             User::LeaveIfError(HAL::Get(screenId, HALData::EDisplayOffsetBetweenLines, stride));
       
   307 
       
   308             aInfoBuf().iStride = stride;             
       
   309             
       
   310             iSurfaceId = aId;
       
   311             break;
       
   312             }
       
   313         default:
       
   314             User::Leave(KErrNotSupported);
       
   315         } 
       
   316     }
       
   317 
       
   318 COpenWfcStreamMap& CSurfaceStream::GetSingletonL()
       
   319 	{
       
   320 	return COpenWfcStreamMap::InstanceL();
       
   321 	}
       
   322 
       
   323 /**
       
   324 	Helper to resolve handle to stream object
       
   325 **/
       
   326 /*static*/
       
   327 CSurfaceStream* CSurfaceStream::FromHandle(SymbianStreamType aNativeStreamHandle)
       
   328 	{
       
   329 	if (aNativeStreamHandle)
       
   330 		{
       
   331 		if (aNativeStreamHandle->Type()==TSurfaceId::EStreamHandle)
       
   332 			{
       
   333 			return reinterpret_cast<CSurfaceStream*>(aNativeStreamHandle->iInternal[TSurfaceId::TSurfaceUsage::EObjectRefField]);
       
   334 			}
       
   335 		}
       
   336 	return NULL;
       
   337 	}
       
   338 
       
   339 /**
       
   340 	Helper to resolve handle to stream object
       
   341 **/
       
   342 SymbianStreamType CSurfaceStream::ToHandle()
       
   343 	{
       
   344 	if (this)
       
   345 		{
       
   346 		return &iStreamProxySurfaceId;
       
   347 		}
       
   348 	else
       
   349 		{
       
   350 		return NULL;
       
   351 		}
       
   352 	}
       
   353 
       
   354 
       
   355 /**	Returns internal surface ID.
       
   356  *
       
   357  * @return surface id asociated with this stream
       
   358  **/
       
   359 const TSurfaceId& CSurfaceStream::SurfaceId()const
       
   360 	{
       
   361 	return iSurfaceId;
       
   362 	}
       
   363 
       
   364 /*!
       
   365  * \brief Increase stream's reference count by one.
       
   366  *
       
   367  */
       
   368  void CSurfaceStream::AddReference()
       
   369 	 {
       
   370 	 iRefCountMutex.Wait();
       
   371 	 iRefCount++;
       
   372 	 iRefCountMutex.Signal();
       
   373 
       
   374 	 }
       
   375 
       
   376 /*!
       
   377  * \internal
       
   378  *
       
   379  * \brief Returns flag if reference count is now zero.
       
   380  *
       
   381  */
       
   382 TBool	CSurfaceStream::RemainingReference()
       
   383 	{
       
   384 	 iRefCountMutex.Wait();
       
   385 	 TBool countZero=iRefCount==0;
       
   386 	 iRefCountMutex.Signal();
       
   387 	 return countZero;
       
   388 	}
       
   389 
       
   390 
       
   391 /*!
       
   392  * \brief Decrease stream's reference count by one and destroy
       
   393  * the stream, if the reference count goes to zero.
       
   394  *
       
   395  * All acquired read & write buffers must be released
       
   396  * before calling WFC_Native_Destroy.
       
   397  *
       
   398  */
       
   399 void CSurfaceStream::ReleaseReference()
       
   400 	{
       
   401 	iRefCountMutex.Wait();
       
   402 	--iRefCount;
       
   403 	if (iRefCount < 1)
       
   404 		{
       
   405 		// it is required to signal the mutex before calling LockDestroy()
       
   406 		iRefCountMutex.Signal();
       
   407 		TRAP_IGNORE(GetSingletonL().LockDestroy(this));
       
   408 		}
       
   409 	else
       
   410 		{
       
   411 		iRefCountMutex.Signal();
       
   412 		}
       
   413 	 }
       
   414 
       
   415 /*!
       
   416  * \brief Get stream "frame header". Can be used to query
       
   417  * all or some of the frame properties.
       
   418  *
       
   419  * \param width Pointer to location where width parameter should be saved
       
   420  * \param height Pointer to location where height parameter should be saved
       
   421  * \param stride Pointer to location where stride (row size in bytes)
       
   422  * parameter should be saved
       
   423  * \param pixelSize Pointer to location where pizelSize (pixel size in bytes) if the format has more than 8 bits.
       
   424  *                  For the formats with fewer than 8 bits per pixel, or ones that do not use packed pixel 
       
   425  *                  the parameter is a negative number            
       
   426  * parameter should be saved
       
   427 
       
   428  * Passing a NULL pointer implies that particular
       
   429  * value is of no interest to caller. E.g.
       
   430  *   owfNativeStreamGetHeader(stream, &w, &h, NULL, NULL, NULL);
       
   431  * would only fetch width & height parameters.
       
   432  */
       
   433 void CSurfaceStream::GetHeader(  khronos_int32_t* aWidth,
       
   434                            khronos_int32_t* aHeight,
       
   435                            khronos_int32_t* aStride,
       
   436                            SymOwfPixelFormat* aFormat,
       
   437                            khronos_int32_t* aPixelSize)
       
   438 	 {
       
   439 	 Guard g1(iRefCountMutex);
       
   440 	 if (aWidth)
       
   441 		 {
       
   442 		 if (iFlipState == EFlippedTargetFlipped)
       
   443 		     {
       
   444 	         *aWidth = static_cast<khronos_int32_t>(iInfo.iSize.iHeight);
       
   445 		     }
       
   446 		 else
       
   447 		     {
       
   448              *aWidth = static_cast<khronos_int32_t>(iInfo.iSize.iWidth);
       
   449 		     }
       
   450 		 }
       
   451 	 
       
   452 	 if (aHeight)
       
   453 		 {
       
   454          if (iFlipState == EFlippedTargetFlipped)
       
   455              {
       
   456              *aHeight = static_cast<khronos_int32_t>(iInfo.iSize.iWidth);
       
   457              }
       
   458          else
       
   459              {
       
   460              *aHeight = static_cast<khronos_int32_t>(iInfo.iSize.iHeight);
       
   461              }
       
   462 		 }
       
   463 	 if (aStride)
       
   464 		 {
       
   465          if (iFlipState == EFlippedTargetFlipped)
       
   466              {
       
   467              *aStride = Stride(iInfo.iSize.iHeight, iInfo.iPixelFormat);
       
   468              }
       
   469          else
       
   470              {
       
   471              *aStride = static_cast<khronos_int32_t>(iInfo.iStride);
       
   472              }
       
   473 		 }
       
   474 	 if (aFormat)
       
   475 		 {
       
   476 		 *aFormat=iInfo.iPixelFormat;
       
   477 		 }
       
   478 	 if (aPixelSize)
       
   479 		 {
       
   480 		*aPixelSize = static_cast<khronos_int32_t>(BytesPerPixel(iInfo.iPixelFormat));
       
   481 		 }
       
   482 	 }
       
   483 
       
   484 /*!
       
   485  * \brief Acquires read buffer for stream. For > 1 buffer
       
   486  * streams this function doesn't block, but simply returns
       
   487  * WFC_INVALID_HANDLE if no buffer is available for reading.
       
   488  * For 1 buffer stream the caller is blocked until the buffer
       
   489  * is ready for reading (the reader has committed the buffer,
       
   490  * that is.)
       
   491  *
       
   492  *
       
   493  * \return WFC_INVALID_HANDLE if no buffer is available or
       
   494  * handle to last committed buffer.
       
   495  *
       
   496  * An example sequence for 3 buffer stream where
       
   497  * producer produces frames approx. after every ~5th time unit.
       
   498  * Consumer consumes buffers at constant rate of 1buf/time unit.
       
   499  * Pframe is the number/handle of buffer that is being written by
       
   500  * the producer (let's assume that it takes 2 time units
       
   501  * for producer to produce a frame/buffer.) Cframe is the number/
       
   502  * handle of the buffer the consumer receives from AcquireReadBuffer().
       
   503  * "i" stands for WFC_INVALID_HANDLE:
       
   504  *
       
   505  * \code
       
   506  * Time:   0    5    10   15   20   25
       
   507  * Pframe: 0    1    2    0    1    ...
       
   508  * Cframe: ii00000111112222200000111...
       
   509  * \endcode
       
   510  */
       
   511 SymbianStreamBuffer CSurfaceStream::AcquireReadBuffer()
       
   512 	 {
       
   513 	 SymbianStreamBuffer buffer = WFC_INVALID_HANDLE;
       
   514 
       
   515 	 iRefCountMutex.Wait();
       
   516 	 TInt index = GetReadBufferIndex();
       
   517      buffer = IndexToReadHandle(index);
       
   518      ++(iBufferInfo[index].iRefCount);
       
   519 	 iRefCountMutex.Signal();
       
   520 	 AddReference();
       
   521 	 return buffer;
       
   522 	 }
       
   523 
       
   524 /*!
       
   525  * \brief Releases read buffer.
       
   526  *
       
   527  * When read buffer is released, it is marked as clean to
       
   528  * be written again, unless it is the only committed buffer
       
   529  * in which case it is recycled so that the same buffer
       
   530  * can be read again (as long as no new buffers are committed
       
   531  * by the producer)
       
   532  *
       
   533  * \param buf Buffer handle. Must be valid read buffer handle for
       
   534  * given stream.
       
   535  */
       
   536 TInt CSurfaceStream::ReleaseReadBuffer(SymbianStreamBuffer aBuf)
       
   537 	 {
       
   538 	 TInt index = BufferHandleToIndex(aBuf);
       
   539 	 if(index < 0 || index >= iInfo.iBuffers)
       
   540 		 {
       
   541 		 return KErrBadHandle;
       
   542 		 }
       
   543 
       
   544      iRefCountMutex.Wait();
       
   545 
       
   546       __ASSERT_DEBUG(iBufferInfo[index].iRefCount > 0, 
       
   547 			 (iRefCountMutex.Signal(),Panic(EOwfPanicSurfaceStreamBufferNotLocked)));
       
   548 
       
   549       --(iBufferInfo[index].iRefCount);
       
   550      
       
   551      iRefCountMutex.Signal();
       
   552      ReleaseReference();
       
   553      return KErrNone;
       
   554 	 }
       
   555 
       
   556 /*!
       
   557  * \brief Acquires write buffer for stream.
       
   558  *
       
   559  * Returns handle to a buffer that can be used to write
       
   560  * data into stream. If no clean buffer is available,
       
   561  * invalid handle is returned.
       
   562  *
       
   563  *
       
   564  * \return Handle to a writable buffer
       
   565  */
       
   566 SymbianStreamBuffer CSurfaceStream::AcquireWriteBuffer()
       
   567 	 {
       
   568 	 SymbianStreamBuffer   buffer = WFC_INVALID_HANDLE;
       
   569 
       
   570      iRefCountMutex.Wait();
       
   571      TInt index = GetWriteBufferIndex();
       
   572      //Writers are currently not blocked in single buffered,
       
   573      //but if proper signalling was implemented then they could be blocked
       
   574      //Ideally, make signalling/blocking a parameter flag of AcquireWriteBuffer
       
   575      if (iInfo.iBuffers>1 && iBufferInfo[index].iRefCount > 0)
       
   576        	{
       
   577         buffer = WFC_INVALID_HANDLE;
       
   578       	}
       
   579      else
       
   580        	{
       
   581         buffer = IndexToWriteHandle(index);
       
   582         ++(iBufferInfo[index].iRefCount);
       
   583         iAcquiredWriteBuffer = buffer;
       
   584        	}
       
   585     iRefCountMutex.Signal();
       
   586     if (buffer)
       
   587     	{
       
   588     	AddReference();
       
   589     	}
       
   590     return buffer;
       
   591 	}
       
   592 
       
   593 /*!
       
   594  * \brief Releases write buffer to stream.
       
   595  * Released buffer is made new front buffer, i.e., producer is expected
       
   596  * to release buffer is the same order they were acquired.
       
   597  *
       
   598  * \param buf Buffer handle. Must be valid write buffer handle
       
   599  * for given stream.
       
   600  */
       
   601 void CSurfaceStream::ReleaseWriteBuffer(SymbianStreamBuffer aBuf)
       
   602 	 {
       
   603 	 TInt index = BufferHandleToIndex(aBuf);
       
   604 	 if(index < 0 || index >= iInfo.iBuffers)
       
   605 		 {
       
   606 		 return;
       
   607 		 }
       
   608 
       
   609 	 iRefCountMutex.Wait();
       
   610 
       
   611      __ASSERT_DEBUG(iBufferInfo[index].iRefCount > 0,
       
   612 			(iRefCountMutex.Signal(),Panic(EOwfPanicSurfaceStreamBufferNotLocked)));
       
   613 
       
   614      __ASSERT_DEBUG((iAcquiredWriteBuffer == aBuf) || (iAcquiredWriteBuffer == BUFFER_WRITE_UPDATE_OVERWRITE),
       
   615 			(iRefCountMutex.Signal(),Panic(EOwfPanicSurfaceStreamBufferNotLocked)));
       
   616 
       
   617 	 if (iAcquiredWriteBuffer != BUFFER_WRITE_UPDATE_OVERWRITE)
       
   618 		 {
       
   619 		 // Update read buffer to point to buffer just finished writing
       
   620 		 SetReadBufferIndex(index);
       
   621 		 }
       
   622 	 iAcquiredWriteBuffer = WFC_INVALID_HANDLE;
       
   623 
       
   624      --(iBufferInfo[index].iRefCount);
       
   625 	 
       
   626      if (iNewFlip != EFlipNotSet)
       
   627          {
       
   628          iFlipState = iNewFlip;
       
   629          iNewFlip = EFlipNotSet;
       
   630          }
       
   631      
       
   632 	 iRefCountMutex.Signal();
       
   633 
       
   634 	 NotifyObservers(ESOWF_EventComposed);
       
   635 	 ReleaseReference();	//Note this means this NotifyObservers can never get the rug pulled out
       
   636 	 }
       
   637 
       
   638 
       
   639 void CSurfaceStream::SetReadBufferIndex(TInt aIndex)
       
   640 	{
       
   641 	__ASSERT_DEBUG(aIndex >= 0 && aIndex < iInfo.iBuffers,
       
   642 			(iRefCountMutex.Signal(),Panic(EOwfPanicSurfaceStreamBufferIndexOutOfBounds)));
       
   643 	iReadBuffer = aIndex;
       
   644 	}
       
   645 
       
   646 TInt CSurfaceStream::GetReadBufferIndex()
       
   647 	{
       
   648 	return iReadBuffer;
       
   649 	}
       
   650 TInt CSurfaceStream::GetWriteBufferIndex()
       
   651 	{
       
   652 	return (iReadBuffer+1)%iInfo.iBuffers;
       
   653 	}
       
   654 
       
   655 /*! \brief Returns pointer to pixel buffer.
       
   656  *
       
   657  * \param buffer Handle of buffer
       
   658  */
       
   659 void* CSurfaceStream::GetBufferPtrL(SymbianStreamBuffer aBuffer)
       
   660 	 {
       
   661      TInt bufferIndex = BufferHandleToIndex(aBuffer);  
       
   662      Guard g1(iRefCountMutex);
       
   663      __ASSERT_DEBUG(iBufferInfo[bufferIndex].iRefCount > 0,
       
   664              (iRefCountMutex.Signal(),Panic(EOwfPanicSurfaceStreamBufferNotLocked)));
       
   665              
       
   666      switch (SurfaceId().Type())
       
   667          {
       
   668          case TSurfaceTypes::ESurfaceManagerSurface:
       
   669              {                         
       
   670              if (iBufferChunk.Handle() == 0)
       
   671                  {
       
   672                  RChunk threadChunk;
       
   673                  User::LeaveIfError(GetSingletonL().SurfaceManager().MapSurface(iSurfaceId, threadChunk));
       
   674 				 CleanupClosePushL(threadChunk);
       
   675 
       
   676 				 RChunk duplicateChunk;
       
   677 				 duplicateChunk.SetHandle(threadChunk.Handle());
       
   678 				 User::LeaveIfError(duplicateChunk.Duplicate(RThread(), EOwnerProcess));
       
   679 
       
   680                  iBufferChunk.SetHandle(duplicateChunk.Handle());
       
   681 				 CleanupStack::PopAndDestroy(&threadChunk);
       
   682                  }
       
   683              break;
       
   684              }
       
   685 	     case TSurfaceId::EScreenSurface:
       
   686 	         {
       
   687 	         if (iBufferChunk.Handle() == 0)
       
   688 	             {
       
   689 	             TInt val = 0;
       
   690 	             TInt screenId = SurfaceId().iInternal[TSurfaceId::TScreenSurfaceUsage::EScreenField];
       
   691 	             User::LeaveIfError(HAL::Get(screenId, HALData::EDisplayMemoryHandle, val));
       
   692                 
       
   693 	             RChunk threadChunk;
       
   694 				 CleanupClosePushL(threadChunk);
       
   695 	             User::LeaveIfError(threadChunk.SetReturnedHandle(val));
       
   696 
       
   697 				 RChunk duplicateChunk;
       
   698 				 duplicateChunk.SetHandle(threadChunk.Handle());
       
   699 				 User::LeaveIfError(duplicateChunk.Duplicate(RThread(), EOwnerProcess));
       
   700 
       
   701 	             iBufferChunk.SetHandle(duplicateChunk.Handle());
       
   702 	             CleanupStack::PopAndDestroy(&threadChunk);
       
   703 	             }
       
   704 	         break;
       
   705 	         }
       
   706 	     default:
       
   707 	         User::Leave(KErrNotSupported);
       
   708 	     }
       
   709 	 
       
   710      TUint8 *pBufferStart = iBufferChunk.Base() + iBufferInfo[bufferIndex].iOffset;
       
   711      return static_cast<void*>(pBufferStart);	 
       
   712 	 }
       
   713 
       
   714 void CSurfaceStream::SetProtectionFlag(TBool aFlag)
       
   715 	{
       
   716 	iRefCountMutex.Wait();
       
   717 	if (aFlag!=iProtected)
       
   718 		{
       
   719 		iProtected=aFlag;
       
   720 		iRefCountMutex.Signal();
       
   721 		if (aFlag)
       
   722 			{
       
   723 			AddReference();
       
   724 			}
       
   725 		else
       
   726 			{
       
   727 			ReleaseReference();
       
   728 			}
       
   729 		}
       
   730 	else
       
   731 		{
       
   732 		iRefCountMutex.Signal();
       
   733 		}
       
   734 	}
       
   735 
       
   736 TInt CSurfaceStream::BytesPerPixel(TUidPixelFormat aPixelFormat)
       
   737 	{
       
   738 	switch (aPixelFormat)
       
   739 		{
       
   740 		case EUidPixelFormatXRGB_8888:
       
   741 		case EUidPixelFormatARGB_8888:
       
   742 		case EUidPixelFormatBGRX_8888:
       
   743 		case EUidPixelFormatXBGR_8888:
       
   744 		case EUidPixelFormatBGRA_8888:
       
   745 		case EUidPixelFormatABGR_8888:	
       
   746 		case EUidPixelFormatABGR_8888_PRE:
       
   747 		case EUidPixelFormatARGB_8888_PRE:
       
   748 		case EUidPixelFormatBGRA_8888_PRE:
       
   749 		case EUidPixelFormatARGB_2101010:
       
   750 		case EUidPixelFormatABGR_2101010:
       
   751 			return 4;
       
   752 		case EUidPixelFormatBGR_888:
       
   753 		case EUidPixelFormatRGB_888:
       
   754 			return 3;
       
   755 		case EUidPixelFormatXRGB_4444:
       
   756 		case EUidPixelFormatARGB_4444:
       
   757 		case EUidPixelFormatXBGR_4444:
       
   758 		case EUidPixelFormatRGB_565:
       
   759 		case EUidPixelFormatBGR_565:
       
   760 		case EUidPixelFormatARGB_1555:
       
   761 		case EUidPixelFormatXRGB_1555:
       
   762 		case EUidPixelFormatARGB_8332:
       
   763 		case EUidPixelFormatBGRX_5551:
       
   764 		case EUidPixelFormatBGRA_5551:
       
   765 		case EUidPixelFormatBGRA_4444:
       
   766 		case EUidPixelFormatBGRX_4444:
       
   767 		case EUidPixelFormatAP_88:
       
   768 			return  2;
       
   769 		case EUidPixelFormatRGB_332:
       
   770 		case EUidPixelFormatBGR_332:
       
   771 	    case EUidPixelFormatA_8:
       
   772 	    case EUidPixelFormatL_8:
       
   773 	        return  1;
       
   774 		case EUidPixelFormatP_8:
       
   775 			return -1;
       
   776 	    case EUidPixelFormatP_4:
       
   777 	    case EUidPixelFormatL_4:
       
   778 	    	return -2;
       
   779 	    case EUidPixelFormatL_2:
       
   780 	    case EUidPixelFormatP_2:
       
   781 	    	return -4;
       
   782 	    case EUidPixelFormatL_1 :
       
   783             return -8;
       
   784 		default:
       
   785 			{
       
   786 			return 0;
       
   787 			}
       
   788 		}
       
   789 	}
       
   790 
       
   791 SymbianStreamBuffer CSurfaceStream::IndexToReadHandle(TInt aIndex)
       
   792 	{
       
   793 	return static_cast<SymbianStreamBuffer>(aIndex + BUFFER_READ_HANDLE_BASE);
       
   794 	}
       
   795 
       
   796 SymbianStreamBuffer CSurfaceStream::IndexToWriteHandle(TInt aIndex)
       
   797 	{
       
   798 	return static_cast<SymbianStreamBuffer>(aIndex + BUFFER_WRITE_HANDLE_BASE);
       
   799 	}
       
   800 
       
   801 TInt CSurfaceStream::BufferHandleToIndex(SymbianStreamBuffer aBuff)
       
   802 	{
       
   803 	TInt retVal= (aBuff > 0) ? (aBuff&0xFF) : (aBuff - BUFFER_READ_HANDLE_BASE);
       
   804 	__ASSERT_DEBUG(retVal>=0,User::Invariant());
       
   805 	__ASSERT_DEBUG(retVal<iInfo.iBuffers,User::Invariant());
       
   806 	return retVal;
       
   807 	}
       
   808 
       
   809 
       
   810 
       
   811 
       
   812 void CSurfaceStream::RequestComplete(TThreadId& aThreadId, TRequestStatus*& aRequestStatus, TInt& aGlobalIndexArray, TInt aStatus)
       
   813     {
       
   814     if (aRequestStatus)
       
   815         {
       
   816         if (aGlobalIndexArray != KInvalidIndex)
       
   817             {
       
   818             TGlobalNotification& globalNotification = iGlobalNotifications[aGlobalIndexArray];
       
   819             --globalNotification.iPendingNotifications;
       
   820             switch (aStatus)
       
   821                 {
       
   822                 case KErrNone:
       
   823                     globalNotification.iCompletedOkNotifications++;
       
   824                     break;
       
   825                 case KErrOverflow:
       
   826                     globalNotification.iOverflowedNotifications++;
       
   827                     break;
       
   828                 case KErrCancel:
       
   829                     globalNotification.iCanceledNotifications++;
       
   830                     break;
       
   831                 case KErrNotVisible:
       
   832                     globalNotification.iNotVisibleNotifications++;
       
   833                     break;
       
   834                 default:
       
   835                     globalNotification.iOtherNotifications++;
       
   836                 }
       
   837             NFLOG(("### CSurfaceStream::RequestComplete globalRequestStatus[%d] iPendingNotifications(%d) "
       
   838                     "iCompletedOkNotifications(%d)"
       
   839                     "iOverflowedNotifications(%d)"
       
   840                     "iCanceledNotifications(%d)"
       
   841                     "iNotVisibleNotifications(%d)"
       
   842                     "iOtherNotifications(%d)"
       
   843                     "requestStatus(%p)",
       
   844                     aGlobalIndexArray, 
       
   845                     globalNotification.iPendingNotifications, 
       
   846                     globalNotification.iCompletedOkNotifications, 
       
   847                     globalNotification.iOverflowedNotifications,
       
   848                     globalNotification.iCanceledNotifications,
       
   849                     globalNotification.iNotVisibleNotifications,
       
   850                     globalNotification.iOtherNotifications,
       
   851                     aStatus));
       
   852             
       
   853             if (globalNotification.iStatus && globalNotification.iPendingNotifications == 0)
       
   854                 {
       
   855                 TInt status;
       
   856                 if (globalNotification.iCompletedOkNotifications > 0)
       
   857                     {
       
   858                     status = KErrNone;
       
   859                     }
       
   860                 else if (globalNotification.iOverflowedNotifications > 0)
       
   861                     {
       
   862                     status = KErrOverflow;
       
   863                     }
       
   864                 else if (globalNotification.iNotVisibleNotifications > 0)
       
   865                     {
       
   866                     status = KErrNotVisible;
       
   867                     }
       
   868                 else if (globalNotification.iCanceledNotifications > 0)
       
   869                     {
       
   870                     status = KErrCancel;
       
   871                     }
       
   872                 else
       
   873                     {
       
   874                     status = KErrGeneral;
       
   875                     }
       
   876                     
       
   877                 RThread thread;
       
   878                 if (thread.Open(globalNotification.iThreadId) == KErrNone)
       
   879                     {
       
   880                     NFLOG(("### CSurfaceStream::RequestComplete globalIndex[%d] aRequestComplete(0x%x) status(%d)",
       
   881                             aGlobalIndexArray, iGlobalNotifications[aGlobalIndexArray].iStatus, status));
       
   882                     thread.RequestComplete(globalNotification.iStatus, status);
       
   883                     thread.Close();
       
   884                     iGlobalNotifications[aGlobalIndexArray].Reset();
       
   885                     }
       
   886                 }
       
   887             }
       
   888         else
       
   889             {
       
   890             RThread thread;
       
   891             if (thread.Open(aThreadId) == KErrNone)
       
   892                 {
       
   893                 NFLOG(("### CSurfaceStream::RequestComplete aRequestStatus(0x%x) aThreadId(0x%x) aStatus(%d)",
       
   894                         aRequestStatus, aThreadId, aStatus));
       
   895                 thread.RequestComplete(aRequestStatus, aStatus);
       
   896                 thread.Close();
       
   897                 }
       
   898             }
       
   899         aRequestStatus = NULL;
       
   900         aThreadId = 0;
       
   901         }
       
   902     aGlobalIndexArray = KInvalidIndex;
       
   903     }
       
   904 
       
   905 int  CSurfaceStream::AddObserver(SymbianStreamCallback aObserver, 
       
   906                                  TInt32 aEvent,
       
   907                                  TInt32 aScreenNumber,
       
   908                                  void* aData)
       
   909      {
       
   910      if (!(aEvent & ESOWF_AllEventsMask) || !aData)
       
   911          {
       
   912          // early exit if the parameters are invalid
       
   913          return KErrArgument;
       
   914          }
       
   915      
       
   916      TInt  errRet = KErrNone;
       
   917      TCallBackEntry newEntry;
       
   918      
       
   919      Guard g2(iCallBacksMutex);
       
   920      Guard g1(iRefCountMutex);
       
   921      
       
   922      // Let's do the check that we dont have an other similar observer already inserted
       
   923      // traverse the whole aobservers list to see if there is already an observer in place
       
   924      TInt  idx = iCallBacks.Count();
       
   925      while(idx--)
       
   926          {
       
   927          if (iCallBacks[idx].iEventMask == aEvent)
       
   928              {
       
   929              switch (aEvent)
       
   930                  {
       
   931                  case ESOWF_EventAvailable:
       
   932                  case ESOWF_EventDisplayed:
       
   933                  case ESOWF_EventDisplayedX:
       
   934                      // these are events related to a context and identified by a screen number
       
   935                      if (iCallBacks[idx].iScreenNumber == aScreenNumber)
       
   936                          {
       
   937                          // nothing else to do, the entry is already created
       
   938                          return KErrOverflow;
       
   939                          }
       
   940                      break;
       
   941                      
       
   942                  case ESOWF_EventComposed:
       
   943                  case ESOWF_EventUpdated:
       
   944                      if (iCallBacks[idx].iCallBackClientParam == aData)
       
   945                          {
       
   946                          // nothing else to do, the entry is already created
       
   947                          return KErrOverflow;
       
   948                          }
       
   949                      break;
       
   950                      
       
   951                  default:
       
   952                      // something really unexpected, let's invalidate the entry
       
   953                      // possible memomry leaks but we are, still, alive and running.
       
   954                      iCallBacks[idx].Reset();
       
   955                      break;
       
   956                  }
       
   957              }
       
   958          }
       
   959      
       
   960      // we need to add a new observer to the list
       
   961     newEntry.iCallBackFunction = aObserver;
       
   962     newEntry.iEventMask = aEvent;
       
   963     newEntry.iScreenNumber = aScreenNumber;
       
   964     TInt trapErr;
       
   965     switch (aEvent)
       
   966         {
       
   967         case ESOWF_EventUpdated:
       
   968         case ESOWF_EventComposed:
       
   969             newEntry.iCallBackClientParam = aData;
       
   970             break;
       
   971         
       
   972         case ESOWF_EventAvailable:
       
   973             {
       
   974             TNotificationAvailable* available = NULL;
       
   975             TRAP(trapErr,available = new(ELeave) TNotificationAvailable());
       
   976             if (trapErr != KErrNone)
       
   977                 {
       
   978                 return trapErr;
       
   979                 }
       
   980             ResetCallBackData(available, aEvent);
       
   981             available->iSerialNumber = KInitialContextSerialNumber;
       
   982             newEntry.iCallBackClientParam = available;
       
   983             }
       
   984             break;
       
   985         
       
   986         case ESOWF_EventDisplayed:
       
   987             {
       
   988             TNotificationDisplayed* displayed = NULL;
       
   989             TRAP(trapErr,displayed = new(ELeave) TNotificationDisplayed());
       
   990             if (trapErr != KErrNone)
       
   991                 {
       
   992                 return trapErr;
       
   993                 }
       
   994             ResetCallBackData(displayed, aEvent);
       
   995             displayed->iSerialNumber = KInitialContextSerialNumber;
       
   996             newEntry.iCallBackClientParam = displayed;
       
   997             }
       
   998             break;
       
   999         
       
  1000         case ESOWF_EventDisplayedX:
       
  1001             {
       
  1002             TNotificationDisplayedX* displayedX = NULL;
       
  1003             TRAP(trapErr,displayedX = new(ELeave) TNotificationDisplayedX()); 
       
  1004             if (trapErr != KErrNone)
       
  1005                 {
       
  1006                 return trapErr;
       
  1007                 }
       
  1008             ResetCallBackData(displayedX, aEvent);
       
  1009             displayedX->iSerialNumber = KInitialContextSerialNumber;
       
  1010             newEntry.iCallBackClientParam = displayedX;
       
  1011             }
       
  1012             break;
       
  1013         
       
  1014         default:
       
  1015             return KErrArgument;
       
  1016         }
       
  1017      
       
  1018      // look for an entry that already exists
       
  1019      idx = iCallBacks.Count();
       
  1020      
       
  1021      while(idx--)
       
  1022          {
       
  1023          // the free entry positions are identified using event mask
       
  1024          if (iCallBacks[idx].iEventMask == ESOWF_NoEvent) break;
       
  1025          }
       
  1026      
       
  1027      if (idx > -1)
       
  1028          {
       
  1029          // ok, we got an existing, free entry
       
  1030          iCallBacks[idx] = newEntry;
       
  1031          }
       
  1032      else
       
  1033          {
       
  1034          errRet = iCallBacks.Append(newEntry);
       
  1035          if (errRet != KErrNone)
       
  1036              {
       
  1037              return errRet;
       
  1038              }
       
  1039          }
       
  1040 
       
  1041      switch (aEvent)
       
  1042          {
       
  1043          case ESOWF_EventAvailable:
       
  1044              iNumberOfScreenAttachedAvailableNotif++;
       
  1045              break;
       
  1046              
       
  1047          case ESOWF_EventDisplayed:
       
  1048              iNumberOfScreenAttachedDisplayedNotif++;
       
  1049              break;
       
  1050              
       
  1051          case ESOWF_EventDisplayedX:
       
  1052              iNumberOfScreenAttachedDisplayedXNotif++;
       
  1053              break;
       
  1054              
       
  1055          default:
       
  1056              break;
       
  1057          
       
  1058          }
       
  1059      
       
  1060      return errRet;
       
  1061      }
       
  1062 
       
  1063 
       
  1064 int CSurfaceStream::RemoveObserver(TInt32 aEvents, void* aData)
       
  1065     {
       
  1066     NFLOG(("ENTER ###CSurfaceStream::RemoveObserver() events(%d) data(0x%x)", aEvents, aData));
       
  1067     if (!(aEvents & ESOWF_AllEventsMask))
       
  1068     {
       
  1069         NFLOG(("EXIT ###CSurfaceStream::RemoveObserver() ERROR: KErrArgument"));
       
  1070         return KErrArgument;
       
  1071     }
       
  1072      
       
  1073     Guard g2(iCallBacksMutex);
       
  1074     Guard g1(iRefCountMutex);
       
  1075     
       
  1076     TInt32 notFoundEvent = aEvents;
       
  1077     TInt count = iCallBacks.Count();
       
  1078     TInt32 susScreenNumber = KNoAssociatedScreenNumber;
       
  1079     
       
  1080     if (aData)
       
  1081         {
       
  1082         susScreenNumber = *(((TInt32*)aData));
       
  1083         }
       
  1084         
       
  1085     while (count-- && notFoundEvent)
       
  1086         {
       
  1087         TInt32 currentEvent = iCallBacks[count].iEventMask;
       
  1088         if (currentEvent & aEvents)
       
  1089             {
       
  1090             void* callBackData = iCallBacks[count].iCallBackClientParam;
       
  1091             switch (currentEvent)
       
  1092                 {
       
  1093                 case ESOWF_EventDisplayed:
       
  1094                     if (callBackData && (!aData || (iCallBacks[count].iScreenNumber == susScreenNumber)))
       
  1095                         {
       
  1096                         Displayed(ESOWF_ObserverCancel, iCallBacks[count].iScreenNumber, NULL, callBackData, NULL);
       
  1097                         delete callBackData;
       
  1098                         iCallBacks[count].Reset();
       
  1099                         if (iNumberOfScreenAttachedDisplayedNotif > 0)
       
  1100                             {
       
  1101                             iNumberOfScreenAttachedDisplayedNotif--;
       
  1102                             }
       
  1103                         notFoundEvent &= ~currentEvent;
       
  1104                         }
       
  1105                     break;
       
  1106              
       
  1107                 case ESOWF_EventAvailable:
       
  1108                     if (callBackData && (!aData || (iCallBacks[count].iScreenNumber == susScreenNumber)))
       
  1109                         {
       
  1110                         Available(ESOWF_ObserverCancel, iCallBacks[count].iScreenNumber, NULL, callBackData, NULL);
       
  1111                         delete callBackData;
       
  1112                         iCallBacks[count].Reset();
       
  1113                         if (iNumberOfScreenAttachedAvailableNotif > 0)
       
  1114                             {
       
  1115                             iNumberOfScreenAttachedAvailableNotif--;
       
  1116                             }
       
  1117                         notFoundEvent &= ~currentEvent;
       
  1118                         }                       
       
  1119                     break;
       
  1120              
       
  1121                 case ESOWF_EventDisplayedX:
       
  1122                     if (callBackData && (!aData || (iCallBacks[count].iScreenNumber == susScreenNumber)))
       
  1123                         {
       
  1124                         DisplayedXTimes(ESOWF_ObserverCancel, iCallBacks[count].iScreenNumber, NULL, callBackData, NULL);
       
  1125                         delete callBackData;
       
  1126                         iCallBacks[count].Reset();
       
  1127                         if (iNumberOfScreenAttachedDisplayedXNotif)
       
  1128                             {
       
  1129                             iNumberOfScreenAttachedDisplayedXNotif--;
       
  1130                             }
       
  1131                         notFoundEvent &= ~currentEvent;
       
  1132                         }                   
       
  1133                     break;
       
  1134              
       
  1135                 case ESOWF_EventComposed:
       
  1136                     if (!aData || (aData == iCallBacks[count].iCallBackClientParam))
       
  1137                         {
       
  1138                         // just in case that we have to delete the call back, we try, first to execute it
       
  1139                         // avoiding in this way some deadlocks in CT code
       
  1140                         if (iCallBacks[count].iCallBackFunction && iCallBacks[count].iCallBackClientParam)
       
  1141                             {
       
  1142                             iCallBacks[count].iCallBackFunction(ToHandle(), 
       
  1143                                                                 ESOWF_EventComposed, 
       
  1144                                                                 iCallBacks[count].iCallBackClientParam, 
       
  1145                                                                 NULL);
       
  1146                             }
       
  1147                         iCallBacks[count].Reset();
       
  1148                         notFoundEvent &= ~currentEvent;
       
  1149                         }
       
  1150                     break;
       
  1151                 
       
  1152                 case ESOWF_EventUpdated:
       
  1153                     if (!aData || (aData == iCallBacks[count].iCallBackClientParam))
       
  1154                         {
       
  1155                         if (iCallBacks[count].iScreenNumber != KNoAssociatedScreenNumber)
       
  1156                             {
       
  1157                             susScreenNumber = iCallBacks[count].iScreenNumber;
       
  1158                             iCallBacks[count].Reset();
       
  1159                             notFoundEvent &= ~currentEvent;
       
  1160                             
       
  1161                             // Reseting variables to loop back and remove SUS events.
       
  1162                             notFoundEvent |= ESOWF_SUSEventsMask;
       
  1163                             aEvents = ESOWF_SUSEventsMask;
       
  1164                             count = iCallBacks.Count();
       
  1165                             }
       
  1166                         else
       
  1167                             {
       
  1168                             iCallBacks[count].Reset();
       
  1169                             notFoundEvent &= ~currentEvent;
       
  1170                             }
       
  1171                         }
       
  1172                     break;
       
  1173                 
       
  1174                 default:
       
  1175                     break;
       
  1176                 }
       
  1177             }
       
  1178         }
       
  1179     
       
  1180     NFLOG(("EXIT ###CSurfaceStream::CancelNotifications() err(%d)", notFoundEvent ? KErrNotFound : KErrNone));
       
  1181     return (notFoundEvent ? KErrNotFound : KErrNone);
       
  1182     }
       
  1183 
       
  1184 TInt CSurfaceStream::NotifyObservers(TInt32 aEvent)
       
  1185     {
       
  1186     NFLOG(("### ENTER CSurfaceStream::NotifyObservers()"));
       
  1187     TInt err = KErrNotFound;
       
  1188     
       
  1189     Guard g2(iCallBacksMutex);
       
  1190     TCallBackEntry localCallBackEntry;
       
  1191     
       
  1192     for (TInt i = 0; i < iCallBacks.Count(); ++i)
       
  1193         {
       
  1194         localCallBackEntry = iCallBacks[i];
       
  1195         if (iCallBacks[i].iEventMask & aEvent && 
       
  1196             iCallBacks[i].iCallBackFunction) 
       
  1197             {
       
  1198             err = KErrNone;
       
  1199             NFLOG(("### EXIT CSurfaceStream::NotifyObservers() callback(%d)", iCallBacks[i].iEventMask));
       
  1200             localCallBackEntry.iCallBackFunction(ToHandle(), 
       
  1201                                                  iCallBacks[i].iEventMask, 
       
  1202                                                  localCallBackEntry.iCallBackClientParam, 
       
  1203                                                  NULL);
       
  1204             }
       
  1205         }
       
  1206     NFLOG(("### EXIT CSurfaceStream::NotifyObservers() err(%d)", err));
       
  1207     return err;
       
  1208     }
       
  1209 
       
  1210 TBool CSurfaceStream::NotifyComposerContext(TInt32 aScreenNumber, TInt aOp, SYMOWF_CONTENT_UPDATED_PARAM* aParam)
       
  1211     {
       
  1212     NFLOG(("### ENTER CSurfaceStream::NotifyComposerContext()"));
       
  1213     TCallBackEntry entry;
       
  1214     TBool ret = EFalse;
       
  1215     for(TInt i = 0; i < iCallBacks.Count(); i++)
       
  1216         {
       
  1217         if (iCallBacks[i].iEventMask == ESOWF_EventUpdated && 
       
  1218             iCallBacks[i].iCallBackFunction && 
       
  1219             (((iCallBacks[i].iScreenNumber == KNoAssociatedScreenNumber) && (aOp != SYM_CONTENT_UPDATE_BEGIN)) ||
       
  1220              ((aScreenNumber == KNoAssociatedScreenNumber) && (aOp != SYM_CONTENT_UPDATE_BEGIN)) ||
       
  1221              iCallBacks[i].iScreenNumber == aScreenNumber))
       
  1222             {
       
  1223             entry = iCallBacks[i];
       
  1224             iRefCountMutex.Signal();
       
  1225             NFLOG(("###CSurfaceStream::NotifyComposerContext() ESOWF_EventUpdated aParam(%d)", aParam? aParam->id: -1));
       
  1226             entry.iCallBackFunction(ToHandle(), ESOWF_EventUpdated, entry.iCallBackClientParam, aParam);
       
  1227             ret = ETrue;
       
  1228             iRefCountMutex.Wait();
       
  1229             }
       
  1230         }
       
  1231     NFLOG(("### EXIT CSurfaceStream::NotifyComposerContext() ret(%d)", ret));
       
  1232     return ret;
       
  1233     }
       
  1234 
       
  1235 TBool CSurfaceStream::StartUpdateNotifications(TInt aScreenNumber, SYMOWF_CONTENT_UPDATED_PARAM& param)
       
  1236     {
       
  1237     NFLOG(("### CSurfaceStream::StartUpdateNotifications()"));
       
  1238     param.id = SYM_CONTENT_UPDATE_BEGIN;
       
  1239     param.length = sizeof (param);
       
  1240     param.par = 0;
       
  1241     param.serialNumber = KNoAssociatedScreenNumber;
       
  1242     param.immediateAvailable = 0;
       
  1243     return NotifyComposerContext(aScreenNumber, SYM_CONTENT_UPDATE_BEGIN, &param);
       
  1244     }
       
  1245 
       
  1246 TBool CSurfaceStream::EndUpdateNotifications(TInt aScreenNum, TInt aBufferNum, TInt32 aUpdatedFlags, const TRegion* aRegion)
       
  1247     {
       
  1248     (void)aScreenNum;
       
  1249     (void)aRegion;
       
  1250     NFLOG(("### CSurfaceStream::EndUpdateNotifications()"));
       
  1251     if (aBufferNum < 0 || aBufferNum >= iInfo.iBuffers)
       
  1252         {
       
  1253         return EFalse;
       
  1254         }
       
  1255     
       
  1256     if (iAcquiredWriteBuffer != WFC_INVALID_HANDLE)
       
  1257         {
       
  1258         iAcquiredWriteBuffer = BUFFER_WRITE_UPDATE_OVERWRITE;
       
  1259         }
       
  1260     
       
  1261     SetReadBufferIndex(aBufferNum);
       
  1262     
       
  1263     SYMOWF_CONTENT_UPDATED_PARAM param;
       
  1264     param.length = sizeof (param);
       
  1265     param.id = SYM_CONTENT_UPDATE_END;
       
  1266     param.par = aUpdatedFlags;
       
  1267     return NotifyComposerContext(aScreenNum, SYM_CONTENT_UPDATE_END, &param);
       
  1268     }
       
  1269 
       
  1270 TBool CSurfaceStream::UpdateNotifications(TInt aScreenNum, 
       
  1271                                          TInt aBufferNum, 
       
  1272                                          TInt32 aUpdatedFlags, 
       
  1273                                          const TRegion* aRegion)
       
  1274     {
       
  1275     (void)aScreenNum;
       
  1276     (void)aRegion;
       
  1277     NFLOG(("### CSurfaceStream::UpdateNotifications()"));
       
  1278     if (aBufferNum < 0 || aBufferNum >= iInfo.iBuffers)
       
  1279         {
       
  1280         return EFalse;
       
  1281         }
       
  1282     
       
  1283     if (iAcquiredWriteBuffer != WFC_INVALID_HANDLE)
       
  1284         {
       
  1285         iAcquiredWriteBuffer = BUFFER_WRITE_UPDATE_OVERWRITE;
       
  1286         }
       
  1287     
       
  1288     SetReadBufferIndex(aBufferNum);
       
  1289     
       
  1290     SYMOWF_CONTENT_UPDATED_PARAM param;
       
  1291     param.length = sizeof (param);
       
  1292     param.id = SYM_CONTENT_UPDATE;
       
  1293     param.par = aUpdatedFlags;
       
  1294     return NotifyComposerContext(aScreenNum, SYM_CONTENT_UPDATE, &param);
       
  1295     }
       
  1296 
       
  1297 void CSurfaceStream::SetNewNotifications(TInt            aBuffer,
       
  1298                                          TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp,
       
  1299                                          TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes,
       
  1300                                          TRequestStatus* aStatusConsumed, const TRegion* aRegion, 
       
  1301                                          TInt32          aScreenNumber)
       
  1302     {
       
  1303     NFLOG(("### ENTER * CSurfaceStream::SetNewNotifications()"));
       
  1304     Guard g2(iCallBacksMutex);
       
  1305     Guard g1(iRefCountMutex);
       
  1306     if (aScreenNumber == KAllScreens)
       
  1307         {
       
  1308         SetAllNotifications(aBuffer, 
       
  1309                             aStatusDisplayed, aTimeStamp, 
       
  1310                             aStatusDispXTimes, aDisplayedXTimes, 
       
  1311                             aStatusConsumed, aRegion);
       
  1312         }
       
  1313     else
       
  1314         {
       
  1315         TNewGlobalNotifications noGlobalNotifications;
       
  1316         SetNotifications(aBuffer, 
       
  1317                          aStatusDisplayed, aTimeStamp, 
       
  1318                          aStatusDispXTimes, aDisplayedXTimes, 
       
  1319                          aStatusConsumed, aRegion, 
       
  1320                          aScreenNumber, noGlobalNotifications);
       
  1321         }
       
  1322     NFLOG(("### EXIT * CSurfaceStream::SetNewNotifications()"));
       
  1323     }
       
  1324 
       
  1325 
       
  1326 void CSurfaceStream::SetNotifications(TInt            aBuffer,
       
  1327                                       TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp,
       
  1328                                       TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes,
       
  1329                                       TRequestStatus* aStatusConsumed, const TRegion* aRegion, 
       
  1330                                       TInt32          aScreenNumber, const TNewGlobalNotifications& aGlobalNotifications)
       
  1331     {
       
  1332     NFLOG(("### ENTER * CSurfaceStream::SetNotifications()"));
       
  1333     TInt32 eventsFound = 0;
       
  1334     TInt32 eventsReceived = 0;
       
  1335     TInt32 eventsToProcess = 0;
       
  1336     TInt32 contextUpdate = 0;
       
  1337     // let's take in evidence the events we have to process
       
  1338     if (aStatusConsumed)
       
  1339         {
       
  1340         eventsReceived |= ESOWF_EventAvailable;
       
  1341         }
       
  1342     if (aStatusDisplayed)
       
  1343         {
       
  1344         eventsReceived |= ESOWF_EventDisplayed;
       
  1345         }
       
  1346     if (aStatusDispXTimes)
       
  1347         {
       
  1348         eventsReceived |= ESOWF_EventDisplayedX;
       
  1349         }
       
  1350     
       
  1351     TInt availableIndex = -1;
       
  1352     TInt displayedIndex = -1;
       
  1353     TInt displayedXIndex = -1;
       
  1354     
       
  1355     TInt32 serialNumber = KNoAssociatedScreenNumber;
       
  1356     TBool immediateAvailable = EFalse;
       
  1357     TInt32 immediateVisibility = SYM_CONTENT_VISIBLE_NOT_SET;
       
  1358     
       
  1359     // guard acquiring/release of the update lock of the composer
       
  1360     // acquire the update lock of the composer and retrive the composer state info
       
  1361     SYMOWF_CONTENT_UPDATED_PARAM param;
       
  1362     TBool startUpdateNotification = StartUpdateNotifications(aScreenNumber, param);
       
  1363     immediateAvailable = param.immediateAvailable && ETrue;
       
  1364     immediateVisibility = param.immediateVisibility;
       
  1365     serialNumber = param.serialNumber;
       
  1366     
       
  1367     
       
  1368     // we take, initially in consideration "availble" even if we might not have received a consumed request status
       
  1369     eventsToProcess = 0;
       
  1370     
       
  1371     // we try to figure out which are the vents we have to process and to get hold of their position
       
  1372     // in the observers array, in order to avoid traversing it again
       
  1373     TInt idx = iCallBacks.Count();
       
  1374     //we will intend to mark the visited events, as an optimisation
       
  1375     TInt32 eventsToCheck = eventsReceived | ESOWF_EventAvailable;
       
  1376     TInt32 currentEvent = 0;
       
  1377     while(--idx > -1 && eventsToCheck)
       
  1378         {
       
  1379         currentEvent = iCallBacks[idx].iEventMask;
       
  1380         if ((currentEvent & eventsToCheck) && (iCallBacks[idx].iScreenNumber == aScreenNumber))
       
  1381             {
       
  1382             switch (currentEvent)
       
  1383                 {
       
  1384                 case ESOWF_EventAvailable:
       
  1385                     // mark observer visited
       
  1386                     eventsToCheck &= ~currentEvent;
       
  1387                     // mark the events found only if the corresponding status request has been recived
       
  1388                     eventsFound |= (currentEvent & eventsReceived);
       
  1389                     // reset the events to process mask
       
  1390                     eventsToProcess &= ~currentEvent;
       
  1391                     {
       
  1392                     TNotificationAvailable* available = (TNotificationAvailable*) iCallBacks[idx].iCallBackClientParam;
       
  1393                     if (available && (aStatusConsumed || available->iStatus || available->iNewStatus))
       
  1394                         {
       
  1395                         // set the mask of the events to be processed because we have either to overflow some available request
       
  1396                         // statuses, or to process them further
       
  1397                         eventsToProcess |= ESOWF_EventAvailable;
       
  1398                         availableIndex = idx;
       
  1399                         }
       
  1400                     }
       
  1401                     break;
       
  1402                     
       
  1403                 case ESOWF_EventDisplayed:
       
  1404                     // mark observer visited
       
  1405                     eventsFound |= currentEvent;
       
  1406                     eventsToProcess |= currentEvent;
       
  1407                     eventsToCheck &= ~currentEvent;
       
  1408                     displayedIndex = idx;
       
  1409                     break;
       
  1410                     
       
  1411                 case ESOWF_EventDisplayedX:
       
  1412                     // mark observer visited
       
  1413                     eventsFound |= currentEvent;
       
  1414                     eventsToProcess |= currentEvent;
       
  1415                     eventsToCheck &= ~currentEvent;
       
  1416                     displayedXIndex = idx;
       
  1417                     break;
       
  1418                     
       
  1419                 default:
       
  1420                     Panic(EOwfSymbianUnexpectedObserverId);
       
  1421                     break;
       
  1422                 }
       
  1423             }
       
  1424         }
       
  1425     
       
  1426     NFLOG(("### CSurfaceStream::SetNotifications eventsToProcess(0x%x)", eventsToProcess));
       
  1427     if (eventsToProcess)
       
  1428         {
       
  1429         
       
  1430         // from this momment on, the composer cannot process any notifications related to this stream
       
  1431         
       
  1432         ContentUpdatedParams updateParameters(aBuffer, aStatusDisplayed, aTimeStamp,
       
  1433                                               aStatusDispXTimes, aDisplayedXTimes,
       
  1434                                               aStatusConsumed, aRegion, 
       
  1435                                               immediateAvailable, immediateVisibility,
       
  1436                                               aGlobalNotifications);
       
  1437         
       
  1438         // process the observer corresponding to aStatusConsumed request status
       
  1439         if ((ESOWF_EventAvailable & eventsToProcess) && (availableIndex > -1))
       
  1440             {
       
  1441             Available(ESOWF_ObserverProcessing, 
       
  1442                       serialNumber, 
       
  1443                       &updateParameters, 
       
  1444                       iCallBacks[availableIndex].iCallBackClientParam, 
       
  1445                       &contextUpdate);
       
  1446             }
       
  1447         
       
  1448         // process the observer corresponding to aStatusDisplayed request status
       
  1449         if ((ESOWF_EventDisplayed & eventsToProcess) && (displayedIndex > -1))
       
  1450             {
       
  1451             Displayed(ESOWF_ObserverProcessing, 
       
  1452                       serialNumber, 
       
  1453                       &updateParameters, 
       
  1454                       iCallBacks[displayedIndex].iCallBackClientParam, 
       
  1455                       &contextUpdate);
       
  1456             }
       
  1457         
       
  1458         // process the observer corresponding to aStatusDispXTimes request status
       
  1459         if ((ESOWF_EventDisplayedX & eventsToProcess) && (displayedXIndex > -1))
       
  1460             {
       
  1461             DisplayedXTimes(ESOWF_ObserverProcessing, 
       
  1462                             serialNumber, 
       
  1463                             &updateParameters, 
       
  1464                             iCallBacks[displayedXIndex].iCallBackClientParam, 
       
  1465                             &contextUpdate);
       
  1466             }
       
  1467         
       
  1468         }
       
  1469     
       
  1470     if (startUpdateNotification)
       
  1471         {
       
  1472         EndUpdateNotifications(aScreenNumber, aBuffer, contextUpdate, aRegion);
       
  1473         }
       
  1474     else
       
  1475         {
       
  1476         UpdateNotifications(aScreenNumber, aBuffer, contextUpdate, aRegion);
       
  1477         }
       
  1478     
       
  1479     if (eventsReceived != eventsFound)
       
  1480         {
       
  1481         if (aStatusConsumed && !(eventsFound & ESOWF_EventAvailable))
       
  1482             {
       
  1483             User::RequestComplete(aStatusConsumed, KErrCancel);
       
  1484             }
       
  1485         
       
  1486         if (aStatusDisplayed && !(eventsFound & ESOWF_EventDisplayed))
       
  1487             {
       
  1488             *aTimeStamp = 0;
       
  1489             User::RequestComplete(aStatusDisplayed, KErrCancel);
       
  1490             }
       
  1491         
       
  1492         if (aStatusDispXTimes && !(eventsFound & ESOWF_EventDisplayedX))
       
  1493             {
       
  1494             User::RequestComplete(aStatusDispXTimes, KErrCancel);
       
  1495             }
       
  1496         }
       
  1497     NFLOG(("### EXIT * CSurfaceStream::SetNotifications()"));
       
  1498     }
       
  1499 
       
  1500 TInt CSurfaceStream::AddNewGlobalNotification(TRequestStatus* aStatusDisplayed, TInt aAssociatedScreens)
       
  1501     {
       
  1502     TInt maxIdx = iGlobalNotifications.Count();
       
  1503     TInt retIdx = KInvalidIndex;
       
  1504     for (TInt i = 0; i < maxIdx; i++)
       
  1505         {
       
  1506         if (iGlobalNotifications[i].iStatus == NULL)
       
  1507             {
       
  1508             NFLOG(("### ENTER * CSurfaceStream::AddNewGlobalNotification found free idx(%d)", i));
       
  1509             retIdx = i;
       
  1510             break;
       
  1511             }
       
  1512         }
       
  1513     
       
  1514     if (retIdx == KInvalidIndex)
       
  1515         {
       
  1516         TGlobalNotification newNotification;
       
  1517         if (iGlobalNotifications.Append(newNotification) == KErrNone)
       
  1518             {
       
  1519             retIdx = iGlobalNotifications.Count() - 1;
       
  1520             }
       
  1521         }
       
  1522     
       
  1523     if (retIdx != KInvalidIndex)
       
  1524         {
       
  1525         NFLOG(("### ENTER * CSurfaceStream::AddNewGlobalNotification populating idx(%d, status(%p) associated screens=0x%x)", retIdx, aStatusDisplayed, aAssociatedScreens));
       
  1526         iGlobalNotifications[retIdx].Reset();
       
  1527         iGlobalNotifications[retIdx].iStatus = aStatusDisplayed;
       
  1528         iGlobalNotifications[retIdx].iThreadId = RThread().Id();
       
  1529         iGlobalNotifications[retIdx].iPendingNotifications = aAssociatedScreens;
       
  1530         }
       
  1531     
       
  1532     return retIdx;
       
  1533     }
       
  1534 
       
  1535 void CSurfaceStream::SetAllNotifications(TInt            aBuffer,
       
  1536                                          TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp,
       
  1537                                          TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes,
       
  1538                                          TRequestStatus* aStatusConsumed, const TRegion* aRegion)
       
  1539     {
       
  1540     NFLOG(("### ENTER * CSurfaceStream::SetAllNotifications()"));
       
  1541     TInt32 eventsToProcess = 0;
       
  1542     // let's take in evidence the events we have to process
       
  1543     
       
  1544     TNewGlobalNotifications newGlobalNotifications;
       
  1545     TInt idx = 0;
       
  1546     
       
  1547     if (aStatusConsumed && iNumberOfScreenAttachedAvailableNotif > 0)
       
  1548         {
       
  1549         if ((idx = AddNewGlobalNotification(aStatusConsumed, iNumberOfScreenAttachedAvailableNotif)) != KInvalidIndex)
       
  1550             {
       
  1551             newGlobalNotifications.iNewAvailableIdx = idx;
       
  1552             eventsToProcess |= ESOWF_EventAvailable;
       
  1553             }
       
  1554         }
       
  1555     
       
  1556     if (aStatusDisplayed && iNumberOfScreenAttachedDisplayedNotif > 0)
       
  1557         {
       
  1558         if ((idx = AddNewGlobalNotification(aStatusDisplayed, iNumberOfScreenAttachedDisplayedNotif)) != KInvalidIndex)
       
  1559             {
       
  1560             newGlobalNotifications.iNewDisplayedIdx = idx;
       
  1561             eventsToProcess |= ESOWF_EventDisplayed;
       
  1562             }
       
  1563         }
       
  1564     
       
  1565     if (aStatusDispXTimes && iNumberOfScreenAttachedDisplayedXNotif > 0)
       
  1566         {
       
  1567         if ((idx = AddNewGlobalNotification(aStatusDispXTimes, iNumberOfScreenAttachedDisplayedXNotif)) != KInvalidIndex)
       
  1568             {
       
  1569             newGlobalNotifications.iNewDisplayedXIdx = idx;
       
  1570             eventsToProcess |= ESOWF_EventDisplayedX;
       
  1571             }
       
  1572         }
       
  1573     
       
  1574     NFLOG(("### CSurfaceStream::SetAllNotifications eventsToProcess(0x%x)", eventsToProcess));
       
  1575     
       
  1576     idx = iCallBacks.Count();
       
  1577     TInt prevScreenNumber = KNoAssociatedScreenNumber;
       
  1578     TInt screenNumber = KNoAssociatedScreenNumber;
       
  1579     idx = iCallBacks.Count();
       
  1580     while (idx--)
       
  1581         {
       
  1582         if (iCallBacks[idx].iCallBackClientParam &&
       
  1583             (iCallBacks[idx].iEventMask == ESOWF_EventUpdated) &&
       
  1584             ((screenNumber = iCallBacks[idx].iScreenNumber) != KNoAssociatedScreenNumber) 
       
  1585             && prevScreenNumber != screenNumber)
       
  1586             {
       
  1587             NFLOG(("### CSurfaceStream::SetAllNotifications update composer %d", screenNumber));
       
  1588             SetNotifications(aBuffer,
       
  1589                              aStatusDisplayed, aTimeStamp,
       
  1590                              aStatusDispXTimes, aDisplayedXTimes,
       
  1591                              aStatusConsumed, aRegion, screenNumber, newGlobalNotifications);
       
  1592             
       
  1593             prevScreenNumber = screenNumber;
       
  1594             }
       
  1595         
       
  1596         }
       
  1597     
       
  1598     if (aStatusConsumed && !(eventsToProcess & ESOWF_EventAvailable))
       
  1599         {
       
  1600         User::RequestComplete(aStatusConsumed, KErrCancel);
       
  1601         }
       
  1602     
       
  1603     if (aStatusDisplayed && !(eventsToProcess & ESOWF_EventDisplayed))
       
  1604         {
       
  1605         *aTimeStamp = 0;
       
  1606         User::RequestComplete(aStatusDisplayed, KErrCancel);
       
  1607         }
       
  1608     
       
  1609     if (aStatusDispXTimes && !(eventsToProcess & ESOWF_EventDisplayedX))
       
  1610         {
       
  1611         User::RequestComplete(aStatusDispXTimes, KErrCancel);
       
  1612         }
       
  1613     NFLOG(("### EXIT * CSurfaceStream::SetAllNotifications()"));
       
  1614         
       
  1615     }
       
  1616 
       
  1617 void CSurfaceStream::ProcessNotifications(TInt32 aEvent, 
       
  1618                                           TInt32 aScreenNumber, 
       
  1619                                           TInt32 aOperation, 
       
  1620                                           TInt32 aSerialNumber, 
       
  1621                                           TInt32* aReturnMask)
       
  1622     {
       
  1623     Guard g(iRefCountMutex);
       
  1624     NFLOG(("### ENTER CSurfaceStream::ProcessNotifications()"));
       
  1625     
       
  1626     TInt32 eventsToFind = aEvent & ESOWF_SUSEventsMask;
       
  1627     TInt idx = iCallBacks.Count();
       
  1628     while(idx-- && eventsToFind)
       
  1629         {
       
  1630         TInt32 currentEvent = iCallBacks[idx].iEventMask;
       
  1631         if (currentEvent & aEvent)
       
  1632             {
       
  1633             TNotificationBase* notifBase = (TNotificationBase*) iCallBacks[idx].iCallBackClientParam;
       
  1634             if (notifBase && notifBase->iStatus && iCallBacks[idx].iScreenNumber == aScreenNumber)
       
  1635                 {
       
  1636                 TInt callBackOperation = (aOperation == EDefaultOperation) ? currentEvent : ESOWF_ObserverCheckVisible;
       
  1637                 eventsToFind &= ~currentEvent;
       
  1638                 switch (currentEvent)
       
  1639                     {
       
  1640                     case ESOWF_EventAvailable:
       
  1641                         Available(callBackOperation, aSerialNumber, NULL, iCallBacks[idx].iCallBackClientParam, aReturnMask);
       
  1642                         break;
       
  1643                         
       
  1644                     case ESOWF_EventDisplayed:
       
  1645                         Displayed(callBackOperation, aSerialNumber, NULL, iCallBacks[idx].iCallBackClientParam, aReturnMask);
       
  1646                         break;
       
  1647                         
       
  1648                     case ESOWF_EventDisplayedX:
       
  1649                         DisplayedXTimes(callBackOperation, aSerialNumber, NULL, iCallBacks[idx].iCallBackClientParam, aReturnMask);
       
  1650                         break;
       
  1651                         
       
  1652                     default:
       
  1653                         break;
       
  1654                     }
       
  1655                 }
       
  1656             }
       
  1657         }
       
  1658     NFLOG(("### EXIT CSurfaceStream::ProcessNotifications()"));
       
  1659     }
       
  1660 
       
  1661 TInt CSurfaceStream::CheckBufferNumber(TInt aBuffer,
       
  1662                                        TRequestStatus* aStatusDisplayed,
       
  1663                                        TRequestStatus* aStatusDispXTimes,
       
  1664                                        TRequestStatus* aStatusConsumed)
       
  1665     {
       
  1666     if (aBuffer < 0 || aBuffer >= iInfo.iBuffers)
       
  1667         {
       
  1668             if (aStatusConsumed)
       
  1669                 {
       
  1670                 User::RequestComplete(aStatusConsumed, KErrArgument);
       
  1671                 }
       
  1672             if (aStatusDisplayed)
       
  1673                 {
       
  1674                 User::RequestComplete(aStatusDisplayed, KErrArgument);
       
  1675                 }
       
  1676             if (aStatusDispXTimes)
       
  1677                 {
       
  1678                 User::RequestComplete(aStatusDispXTimes, KErrArgument);
       
  1679                 }
       
  1680             return KErrArgument;
       
  1681         }
       
  1682     else
       
  1683         {
       
  1684         return KErrNone;
       
  1685         }
       
  1686     }
       
  1687 
       
  1688 void CSurfaceStream::Available(TInt32 aEvent, 
       
  1689                                TInt32 aSerialNumber, 
       
  1690                                ContentUpdatedParams* aParams, 
       
  1691                                void* aCallBackData, 
       
  1692                                TInt32* aReturnMask)
       
  1693     {
       
  1694     (void) aReturnMask;
       
  1695     NFLOG(("### ENTER CSurfaceStream::Available aEvent(0x%x) aSerialNumber(0x%x) "
       
  1696             "aParams(0x%x) aCallBackData(0x%x) aReturnMask(0x%x)", 
       
  1697             aEvent, aSerialNumber, aParams, aCallBackData, aReturnMask));
       
  1698     
       
  1699     TNotificationAvailable* callBackData = (TNotificationAvailable*) aCallBackData;
       
  1700     if (!callBackData)
       
  1701         {
       
  1702         return;
       
  1703         }
       
  1704     
       
  1705     switch(aEvent)
       
  1706         {
       
  1707         case ESOWF_ObserverProcessing:
       
  1708             NFLOG(("###CSurfaceStream::Available ESOWF_ObserverProcessing"));
       
  1709             // when a new available notification request is issued by SUS, we have to:
       
  1710             // 1. Overflow the old request status (GCE behaviour)
       
  1711             // 2. Update the observer
       
  1712             // 3. If immediate availabilty chec if the old request status can be completed
       
  1713             // 4. Inform the composer about any active available notifications requests
       
  1714             {
       
  1715             if (aParams)
       
  1716                 {
       
  1717                 // let's check first for overflow conditions
       
  1718                 // and overflow the oldest if exists (GCE behaviour)
       
  1719                 if (callBackData->iStatus)
       
  1720                     {
       
  1721                     NFLOG(("###CSurfaceStream::Available ESOWF_ObserverProcessing Overflow"));
       
  1722                     // oldest notifications is overflowed (like GCE behaviour)
       
  1723                     RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrOverflow);
       
  1724                     callBackData->iStatus = NULL;
       
  1725                     callBackData->iThreadId = 0;
       
  1726                     callBackData->iBufferNumber = -1;
       
  1727                     }
       
  1728                 
       
  1729                 // propagate the new data
       
  1730                 callBackData->iSerialNumber = aSerialNumber;
       
  1731                 TBool multibuffered = iInfo.iBuffers > 1;
       
  1732                 if (multibuffered)
       
  1733                     {
       
  1734                     callBackData->iStatus = callBackData->iNewStatus;
       
  1735                     callBackData->iThreadId = callBackData->iNewThreadId;
       
  1736                     callBackData->iBufferNumber = callBackData->iNewBufferNumber;
       
  1737                     callBackData->iGlobalIndex = callBackData->iNewGlobalIndex;
       
  1738                     }
       
  1739                 else
       
  1740                     {
       
  1741                     callBackData->iStatus = aParams->iStatusConsumed;
       
  1742                     callBackData->iThreadId = RThread().Id();
       
  1743                     callBackData->iBufferNumber = aParams->iBuffer;
       
  1744                     callBackData->iGlobalIndex = aParams->iGlobalNotifications.iNewAvailableIdx;
       
  1745                     }
       
  1746                  
       
  1747                 // the availability can be immediately completed if the
       
  1748                 // visibility status is known and the composer is not composing at that momment
       
  1749                 if (callBackData->iStatus && aParams->iImmediateAvailable)
       
  1750                     {
       
  1751                     NFLOG(("###CSurfaceStream::Available ESOWF_ObserverProcessing Immediate Available"));
       
  1752                     if (iAcquiredWriteBuffer != WFC_INVALID_HANDLE)
       
  1753                         {
       
  1754                         iAcquiredWriteBuffer = BUFFER_WRITE_UPDATE_OVERWRITE;
       
  1755                         }
       
  1756                     
       
  1757                     SetReadBufferIndex(aParams->iBuffer);
       
  1758                     // immediate notification is possible because the context
       
  1759                     // is not composing at this momment
       
  1760                     if (aParams->iImmediateVisibility == SYM_CONTENT_NOT_VISIBLE)
       
  1761                         {
       
  1762                         RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrNotVisible);
       
  1763                         }
       
  1764                     else
       
  1765                         {
       
  1766                         RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrNone);
       
  1767                         }
       
  1768                     ResetCallBackData(callBackData, aEvent);
       
  1769                     }
       
  1770                     
       
  1771                 if (multibuffered)
       
  1772                     {
       
  1773                     callBackData->iNewStatus = aParams->iStatusConsumed;
       
  1774                     callBackData->iNewThreadId = RThread().Id();
       
  1775                     callBackData->iNewBufferNumber = aParams->iBuffer;
       
  1776                     callBackData->iGlobalIndex = aParams->iGlobalNotifications.iNewAvailableIdx;
       
  1777                     }
       
  1778                 
       
  1779                 // let the composer know that the Availability has to be analysed further
       
  1780                 if (aReturnMask && callBackData->iStatus)
       
  1781                     {
       
  1782                     NFLOG(("###CSurfaceStream::Available ESOWF_ObserverProcessing *aReturnMask |= ESOWF_EventAvailable"));
       
  1783                     *aReturnMask |= ESOWF_EventAvailable;
       
  1784                     }
       
  1785                 }
       
  1786             }
       
  1787             break;
       
  1788 
       
  1789         case ESOWF_EventAvailable:
       
  1790             NFLOG(("###CSurfaceStream::Available ESOWF_EventAvailable"));
       
  1791             if (callBackData->iStatus)
       
  1792                 {
       
  1793                 // if it is an event just added during composition, we wxpect the same serial number
       
  1794                 RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrNone);
       
  1795                 // clean the old reques notification related info
       
  1796                 callBackData->iSerialNumber = aSerialNumber;
       
  1797                 callBackData->iStatus = NULL;
       
  1798                 callBackData->iThreadId = 0;
       
  1799                 callBackData->iBufferNumber = -1;
       
  1800                 }
       
  1801             break;
       
  1802             
       
  1803         case ESOWF_ObserverCheckVisible:
       
  1804             NFLOG(("###CSurfaceStream::Available ESOWF_ObserverCheckVisible"));
       
  1805             if (callBackData->iStatus)
       
  1806                 {
       
  1807                 // complete the old request status (standard GCE behaviour)
       
  1808                 RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrNotVisible);
       
  1809                 // clean the old reques notification related info
       
  1810                 callBackData->iSerialNumber = aSerialNumber;
       
  1811                 callBackData->iStatus = NULL;
       
  1812                 callBackData->iThreadId = 0;
       
  1813                 callBackData->iBufferNumber = -1;
       
  1814                 }
       
  1815             break;
       
  1816             
       
  1817         case ESOWF_ObserverCancel:
       
  1818             {
       
  1819             NFLOG(("###CSurfaceStream::Available ESOWF_ObserverCancel"));
       
  1820             // cancel both requests if they are valid
       
  1821             RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrCancel);
       
  1822             RequestComplete(callBackData->iNewThreadId, callBackData->iNewStatus, callBackData->iGlobalIndex, KErrCancel);
       
  1823             ResetCallBackData(callBackData, aEvent);
       
  1824             }
       
  1825             break;
       
  1826             
       
  1827         default:
       
  1828             return;
       
  1829         }
       
  1830     NFLOG(("EXIT ###CSurfaceStream::Available()"));
       
  1831     }
       
  1832 
       
  1833 
       
  1834 void CSurfaceStream::Displayed(TInt32 aEvent, TInt32 aSerialNumber, ContentUpdatedParams* aParams, void* aCallBackData, TInt32* aReturnMask)
       
  1835     {
       
  1836     TInt notification = KErrNone;
       
  1837     (void) aReturnMask;
       
  1838     NFLOG(("### ENTER CSurfaceStream::Displayed aEvent(0x%x) aSerialNumber(0x%x) "
       
  1839             "aParams(0x%x) aCallBackData(0x%x) aReturnMask(0x%x)", 
       
  1840             aEvent, aSerialNumber, aParams, aCallBackData, aReturnMask));
       
  1841     TNotificationDisplayed* callBackData = (TNotificationDisplayed*) aCallBackData;
       
  1842     if (!callBackData)
       
  1843         {
       
  1844         return;
       
  1845         }
       
  1846     
       
  1847     switch(aEvent)
       
  1848         {
       
  1849         case ESOWF_ObserverProcessing:
       
  1850             NFLOG(("###CSurfaceStream::Displayed ESOWF_ObserverProcessing"));
       
  1851             // When a new available notification request is issued by SUS, we have to:
       
  1852             // 1. Overflow the previous request status
       
  1853             // 2. Update the observer
       
  1854             // 3. Inform the composer about any active available notifications requests
       
  1855             
       
  1856             if (callBackData->iStatus)
       
  1857                 {
       
  1858                 NFLOG(("###CSurfaceStream::Displayed ESOWF_ObserverProcessing Overflowing"));
       
  1859                 RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrOverflow);
       
  1860                 ResetCallBackData(callBackData, aEvent);
       
  1861                 }
       
  1862             if (aParams && aParams->iStatusDisplayed)
       
  1863                 {
       
  1864                 __ASSERT_DEBUG(aParams->iTimeStamp,
       
  1865                        (iRefCountMutex.Signal(),Panic(EOwfInvalidSUSDisplayedParameter)));
       
  1866                 callBackData->iStatus = aParams->iStatusDisplayed;
       
  1867                 callBackData->iThreadId = RThread().Id();
       
  1868                 callBackData->iBufferNumber = aParams->iBuffer;
       
  1869                 callBackData->iSerialNumber = aSerialNumber;
       
  1870                 callBackData->iTimeStamp = aParams->iTimeStamp;
       
  1871                 callBackData->iGlobalIndex = aParams->iGlobalNotifications.iNewDisplayedIdx;
       
  1872                 NFLOG(("###CSurfaceStream::Displayed iGlobalIndex(%d)", callBackData->iGlobalIndex));
       
  1873                 }
       
  1874             if (aReturnMask && callBackData->iStatus)
       
  1875                 {
       
  1876                 NFLOG(("###CSurfaceStream::Displayed ESOWF_ObserverProcessing *aReturnMask |= ESOWF_EventDisplayed"));
       
  1877                 *aReturnMask |= ESOWF_EventDisplayed;
       
  1878                 }
       
  1879             return;
       
  1880             
       
  1881         case ESOWF_EventDisplayed:
       
  1882             // this invoked by composer
       
  1883             NFLOG(("###CSurfaceStream::Displayed ESOWF_EventDisplayed"));
       
  1884             if (!callBackData->iStatus)
       
  1885                 {
       
  1886                 // no active notification, nothing to do
       
  1887                 NFLOG(("###CSurfaceStream::Displayed ESOWF_EventDisplayed no active notifications"));
       
  1888                 return;
       
  1889                 }
       
  1890             // deffer for next composition the processing if the updated happended during a composition
       
  1891             if (callBackData->iSerialNumber == aSerialNumber && aReturnMask)
       
  1892                 {
       
  1893                 NFLOG(("###CSurfaceStream::Displayed ESOWF_EventDisplayed *aReturnMask |= ESOWF_EventDisplayed"));
       
  1894                 *aReturnMask |= ESOWF_EventDisplayed;
       
  1895                 return;
       
  1896                 }
       
  1897             // complete the active request status
       
  1898             callBackData->iSerialNumber = aSerialNumber;
       
  1899             *callBackData->iTimeStamp = User::FastCounter();
       
  1900             notification = KErrNone;
       
  1901             break;
       
  1902 
       
  1903         case ESOWF_ObserverCheckVisible:
       
  1904             // visibility check comming from composer
       
  1905             NFLOG(("###CSurfaceStream::Displayed ESOWF_ObserverCheckVisible"));
       
  1906             if (!callBackData->iStatus)
       
  1907                 {
       
  1908                 // deffer for next composition the processing if the updated happended during a composition
       
  1909                 // or if no active notification, nothing to do
       
  1910                 NFLOG(("###CSurfaceStream::Displayed ESOWF_ObserverCheckVisible = Not Visible"));
       
  1911                 return;
       
  1912                 }
       
  1913             notification = KErrNotVisible;
       
  1914             callBackData->iSerialNumber = aSerialNumber;
       
  1915             break;
       
  1916             
       
  1917         case ESOWF_ObserverCancel:
       
  1918             // cancel the active notification
       
  1919             NFLOG(("###CSurfaceStream::Displayed ESOWF_ObserverCancel"));
       
  1920             if (!callBackData->iStatus)
       
  1921                 {
       
  1922                 return;
       
  1923                 }
       
  1924             notification = KErrCancel;
       
  1925             break;
       
  1926             
       
  1927         default:
       
  1928             return;
       
  1929         }
       
  1930     
       
  1931     RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, notification);
       
  1932     ResetCallBackData(callBackData, aEvent);
       
  1933     NFLOG(("EXIT ###CSurfaceStream::Displayed()"));
       
  1934     }
       
  1935 
       
  1936 void CSurfaceStream::DisplayedXTimes(TInt32 aEvent, TInt32 aSerialNumber, ContentUpdatedParams* aParams, void* aCallBackData, TInt32* aReturnMask)
       
  1937     {
       
  1938     TInt notification = KErrNone;
       
  1939     
       
  1940     NFLOG(("### ENTER CSurfaceStream::DisplayedXTimes aEvent(0x%x) aSerialNumber(0x%x) "
       
  1941             "aParams(0x%x) aCallBackData(0x%x) aReturnMask(0x%x)", 
       
  1942             aEvent, aSerialNumber, aParams, aCallBackData, aReturnMask));
       
  1943     
       
  1944     TNotificationDisplayedX* callBackData = (TNotificationDisplayedX*) aCallBackData;
       
  1945     if (!callBackData)
       
  1946         {
       
  1947         return;
       
  1948         }
       
  1949 
       
  1950     switch(aEvent)
       
  1951         {
       
  1952         case ESOWF_ObserverProcessing:
       
  1953             // When a new available notification request is issued by SUS, we have to:
       
  1954             // 1. Overflow the previous request status
       
  1955             // 2. Update the observer
       
  1956             // 3. Inform the composer about any active available notifications requests
       
  1957             NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_ObserverProcessing"));
       
  1958             if (callBackData->iStatus)
       
  1959                 {
       
  1960                 NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_ObserverProcessing Overflowing"));
       
  1961                 RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, KErrOverflow);
       
  1962                 ResetCallBackData(callBackData, aEvent);
       
  1963                 }
       
  1964             if (aParams && aParams->iStatusDispXTimes)
       
  1965                 {
       
  1966                 __ASSERT_DEBUG(aParams->iDisplayedXTimes && *aParams->iDisplayedXTimes >= 1,
       
  1967                        (iRefCountMutex.Signal(),Panic(EOwfInvalidSUSDisplayedXTimesParameter)));
       
  1968                 callBackData->iStatus = aParams->iStatusDispXTimes;
       
  1969                 callBackData->iThreadId = RThread().Id();
       
  1970                 callBackData->iBufferNumber = aParams->iBuffer;
       
  1971                 callBackData->iSerialNumber = aSerialNumber;
       
  1972                 callBackData->iCount = *aParams->iDisplayedXTimes;
       
  1973                 callBackData->iGlobalIndex = aParams->iGlobalNotifications.iNewDisplayedXIdx;
       
  1974                 }
       
  1975             
       
  1976             if (aReturnMask && callBackData->iStatus)
       
  1977                 {
       
  1978                 NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_ObserverProcessing *aReturnMask |= ESOWF_EventDisplayedX"));
       
  1979                 *aReturnMask |= ESOWF_EventDisplayedX;
       
  1980                 }
       
  1981             return;
       
  1982             
       
  1983         case ESOWF_EventDisplayedX:
       
  1984             NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_EventDisplayedX"));
       
  1985             if (!callBackData->iStatus)
       
  1986                 {
       
  1987                 // no active notification, nothing to do
       
  1988                 return;
       
  1989                 }
       
  1990             
       
  1991             // deffer for next composition the processing if the updated happended during a composition
       
  1992             if (callBackData->iSerialNumber == aSerialNumber)
       
  1993                 {
       
  1994                 if (aReturnMask)
       
  1995                     {
       
  1996                     NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_EventDisplayedX *aReturnMask |= ESOWF_EventDisplayedX"));
       
  1997                     *aReturnMask |= ESOWF_EventDisplayedX;
       
  1998                     }
       
  1999                 return;
       
  2000                 }
       
  2001             
       
  2002             callBackData->iSerialNumber = aSerialNumber;
       
  2003             
       
  2004             // complete the active request status
       
  2005             if (callBackData->iCount > 1)
       
  2006                 {
       
  2007                 // inform the composer a new notification is needed
       
  2008                 callBackData->iCount--;
       
  2009                 if (aReturnMask)
       
  2010                     {
       
  2011                     NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_EventDisplayedX *aReturnMask |= ESOWF_EventDisplayedX iCount(%d)", callBackData->iCount));
       
  2012                     *aReturnMask |= ESOWF_EventDisplayedX;
       
  2013                     }
       
  2014                 return;
       
  2015                 }
       
  2016             
       
  2017             NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_EventDisplayedX iCount(%d)", callBackData->iCount));
       
  2018             notification = KErrNone;
       
  2019             break;
       
  2020 
       
  2021         case ESOWF_ObserverCheckVisible:
       
  2022             NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_ObserverCheckVisible"));
       
  2023             // visibility check comming from composer
       
  2024             if (!callBackData->iStatus || 
       
  2025                 callBackData->iSerialNumber == aSerialNumber)
       
  2026                 {
       
  2027                 // deffer for next composition the processing if the updated happended during a composition
       
  2028                 // or if no active notification, nothing to do
       
  2029                 return;
       
  2030                 }
       
  2031             callBackData->iSerialNumber = aSerialNumber;
       
  2032             notification = KErrNotVisible;
       
  2033             break;
       
  2034             
       
  2035         case ESOWF_ObserverCancel:
       
  2036             // cancel the active notification
       
  2037             NFLOG(("###CSurfaceStream::DisplayedXTimes ESOWF_ObserverCancel"));
       
  2038             if (!callBackData->iStatus)
       
  2039                 {
       
  2040                 return;
       
  2041                 }
       
  2042             notification = KErrCancel;
       
  2043             break;
       
  2044             
       
  2045         default:
       
  2046             return;
       
  2047         }
       
  2048     
       
  2049     RequestComplete(callBackData->iThreadId, callBackData->iStatus, callBackData->iGlobalIndex, notification);
       
  2050     ResetCallBackData(callBackData, aEvent);
       
  2051     NFLOG(("EXIT ###CSurfaceStream::DisplayedXTimes()"));
       
  2052     }
       
  2053 
       
  2054 void CSurfaceStream::ResetCallBackData(void* aCallBackData,
       
  2055                                        TInt32 aEvent)
       
  2056     {
       
  2057     switch (aEvent)
       
  2058         {
       
  2059         case ESOWF_EventAvailable:
       
  2060             {
       
  2061             TNotificationAvailable* available = (TNotificationAvailable*) aCallBackData;
       
  2062             available->iStatus = NULL;
       
  2063             available->iThreadId = 0;
       
  2064             available->iBufferNumber = -1;
       
  2065             available->iGlobalIndex = KInvalidIndex;
       
  2066             available->iNewBufferNumber = -1;
       
  2067             available->iNewStatus = NULL;
       
  2068             available->iNewThreadId = 0;
       
  2069             available->iNewGlobalIndex = KInvalidIndex;
       
  2070             }
       
  2071             break;
       
  2072             
       
  2073         case ESOWF_EventDisplayed:
       
  2074             {
       
  2075             TNotificationDisplayed* displayed = (TNotificationDisplayed*) aCallBackData; 
       
  2076             displayed->iStatus = NULL;
       
  2077             displayed->iThreadId = 0;
       
  2078             displayed->iBufferNumber = -1;
       
  2079             displayed->iTimeStamp = NULL;
       
  2080             displayed->iGlobalIndex = KInvalidIndex;
       
  2081             }
       
  2082             break;
       
  2083             
       
  2084         case ESOWF_EventDisplayedX:
       
  2085             {
       
  2086             TNotificationDisplayedX* displayed = (TNotificationDisplayedX*) aCallBackData; 
       
  2087             displayed->iStatus = NULL;
       
  2088             displayed->iThreadId = 0;
       
  2089             displayed->iBufferNumber = -1;
       
  2090             displayed->iCount = 0;
       
  2091             displayed->iGlobalIndex = KInvalidIndex;
       
  2092             }
       
  2093             break;
       
  2094             
       
  2095         default:
       
  2096             break;
       
  2097         }
       
  2098     }
       
  2099 
       
  2100 void CSurfaceStream::CancelNotifications()
       
  2101     {
       
  2102     NFLOG(("ENTER ###CSurfaceStream::CancelNotifications()"));
       
  2103     TInt cancelEvents = ESOWF_AllEventsMask;
       
  2104     RemoveObserver(cancelEvents, NULL);
       
  2105     NFLOG(("EXIT ###CSurfaceStream::CancelNotifications()"));
       
  2106     }
       
  2107 
       
  2108 TInt CSurfaceStream::Stride(TInt aWidth, TUidPixelFormat aPixelFormat)
       
  2109     {
       
  2110     
       
  2111     TInt bytesPerPixel = BytesPerPixel(aPixelFormat);
       
  2112     
       
  2113     if (bytesPerPixel >= 0)
       
  2114         {
       
  2115          return bytesPerPixel * aWidth;  // number of bytes between start of one line and start of next  
       
  2116         }
       
  2117     else
       
  2118         {
       
  2119         return (aWidth-(bytesPerPixel+1)) / (-bytesPerPixel);
       
  2120         }
       
  2121     }
       
  2122 
       
  2123 void CSurfaceStream::SetFlipState(TBool aFlip)
       
  2124     {
       
  2125     Guard g1(iRefCountMutex);
       
  2126     if (aFlip)
       
  2127         {
       
  2128         iNewFlip = EFlippedTargetFlipped;
       
  2129         }
       
  2130     else
       
  2131         {
       
  2132         iNewFlip = EFlippedTargetNormal;
       
  2133         }
       
  2134     }