Update contrib.
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
15 // CSurfaceStream declaration
17 #ifndef SURFACESTREAM_H
18 #define SURFACESTREAM_H
24 #include <graphics/surface.h>
25 #include <pixelformats.h>
26 #include <graphics/surfacemanager.h>
27 #include "symbianstream.h"
29 #if defined(ENABLE_NF_LOGGING)
30 #define NFLOG(X) RDebug::Printf X
37 // Each surface buffer has its corresponding TBufferInfo to hold reference count and memory offset
45 struct TNotificationBase
47 TRequestStatus* iStatus;
54 struct TNotificationDisplayed: public TNotificationBase
59 struct TNotificationDisplayedX: public TNotificationBase
64 struct TNotificationAvailable: public TNotificationBase
66 TRequestStatus* iNewStatus;
67 TThreadId iNewThreadId;
68 TInt iNewBufferNumber;
73 class COpenWfcStreamMap;
78 NONSHARABLE_CLASS( CSurfaceStream ) : public CBase
80 struct TNewGlobalNotifications;
86 Guard(RFastLock& aLock);
93 struct ContentUpdatedParams
95 ContentUpdatedParams(TInt aBuffer,
96 TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp,
97 TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes,
98 TRequestStatus* aStatusConsumed, const TRegion* aRegion,
99 TBool aImmediateAvailable,
100 TInt32 aImmediateVisibility, const TNewGlobalNotifications& aGlobalNotifications);
102 TRequestStatus* iStatusDisplayed;
104 TRequestStatus* iStatusDispXTimes;
105 TInt* iDisplayedXTimes;
106 TRequestStatus* iStatusConsumed;
107 const TRegion* iRegion;
108 TBool iImmediateAvailable;
109 TInt32 iImmediateVisibility;
110 const TNewGlobalNotifications& iGlobalNotifications;
114 enum CallBackOperations
117 ECheckVisibleOperation
120 // Constructors and destructor
128 * Two-phased constructor.
130 static CSurfaceStream* NewL(const TSurfaceId& aId);
133 * Two-phased constructor.
135 static CSurfaceStream* NewLC(const TSurfaceId& aId);
138 Helper to resolve handle to stream object
140 static CSurfaceStream* FromHandle(SymbianStreamType aNativeStreamHandle);
143 * A helper function that returns the bytes per pixel for a given pixel format UID
144 * @param aPixelFormat Pixel format UID to convert
145 * @return Positive: bytes per pixel; negative is pixels per byte; 0 is error
148 static TInt BytesPerPixel(TUidPixelFormat aPixelFormat);
150 Helper to resolve handle to stream object
152 SymbianStreamType ToHandle();
156 /** Returns internal surface ID.
158 * @return surface id asociated with this stream
160 const TSurfaceId& SurfaceId()const;
163 //OpenWF-C SI/CT/MIG API implementation
166 * Increase stream's reference count by one.
173 * Decrease stream's reference count by one and destroy
174 * the stream, if the reference count goes to zero.
176 * All acquired read & write buffers must be released
177 * before calling WFC_Native_Destroy.
186 * @return flag if reference count is now zero.
190 RemainingReference();
195 * Sets flipped state.
199 SetFlipState(TBool aFlip);
202 * Get stream "frame header". Can be used to query
203 * all or some of the frame properties.
205 * @param width Pointer to location where width parameter should be saved
206 * @param height Pointer to location where height parameter should be saved
207 * @param stride Pointer to location where stride (row size in bytes)
208 * parameter should be saved
209 * @param pixelSize Pointer to location where pizelSize (pixel size in bytes)
210 * parameter should be saved
212 * Passing a NULL pointer implies that particular
213 * value is of no interest to caller. E.g.
214 * GetHeader(stream, &w, &h, NULL, NULL, NULL);
215 * would only fetch width & height parameters.
218 GetHeader(khronos_int32_t* width,
219 khronos_int32_t* height,
220 khronos_int32_t* stride,
221 SymOwfPixelFormat* format,
222 khronos_int32_t* pixelSize);
225 * Acquires read buffer for stream. For > 1 buffer
226 * streams this function doesn't block, but simply returns
227 * WFC_INVALID_HANDLE if no buffer is available for reading.
228 * For 1 buffer stream the caller is blocked until the buffer
229 * is ready for reading (the reader has committed the buffer,
233 * @return WFC_INVALID_HANDLE if no buffer is available or
234 * handle to last committed buffer.
236 * An example sequence for 3 buffer stream where
237 * producer produces frames approx. after every ~5th time unit.
238 * Consumer consumes buffers at constant rate of 1buf/time unit.
239 * Pframe is the number/handle of buffer that is being written by
240 * the producer (let's assume that it takes 2 time units
241 * for producer to produce a frame/buffer.) Cframe is the number/
242 * handle of the buffer the consumer receives from AcquireReadBuffer().
243 * "i" stands for WFC_INVALID_HANDLE:
245 * Time: 0 5 10 15 20 25
246 * Pframe: 0 1 2 0 1 ...
247 * Cframe: ii00000111112222200000111...
253 * Releases read buffer.
255 * When read buffer is released, it is marked as clean to
256 * be written again, unless it is the only committed buffer
257 * in which case it is recycled so that the same buffer
258 * can be read again (as long as no new buffers are committed
261 * @param buf Buffer handle. Must be valid read buffer handle for
263 * @return KErrNone if succeessful or KErrBadHandle if buf is not a currently
264 * open write buffer on this stream;
267 ReleaseReadBuffer(SymbianStreamBuffer buf);
270 * Acquires write buffer for stream.
272 * Returns handle to a buffer that can be used to write
273 * data into stream. If no clean buffer is available,
274 * invalid handle is returned.
277 * @return Handle to a writable buffer
280 AcquireWriteBuffer();
283 * Releases write buffer to stream.
284 * Released buffer is made new front buffer, i.e., producer is expected
285 * to release buffer is the same order they were acquired.
287 * @param buf Buffer handle. Must be valid write buffer handle
291 ReleaseWriteBuffer(SymbianStreamBuffer buf);
294 * Add event observer for stream. Observers are served in
295 * first-come-first-serve fashion. That is, newest observer
296 * is always placed at the end of the chain. If the observer
297 * is already in the chain, it's popped out and moved to
298 * the end of the chain.
300 * @param observer Observer (callback function) who should
301 * be notified when something interesting happens in the stream.
302 * @param data Additional data to pass to callback function
304 * @return 0 if successful, -1 if stream handle is invalid, -2 if
305 * OOM situation occurs.
307 int AddObserver(SymOwfStreamCallback observer,
308 void* data,MultipleSymbianStreamEventBits aEvents);
311 * Remove stream event observer. Observer is removed from
312 * the stream's event nofitication chain and won't receive
313 * any events from the stream afterwards.
315 * @param observer Observer (callback function)
317 * @param 0 if successful, -1 otherwise
319 int RemoveObserver(SymOwfStreamCallback observer,
320 void* aData,MultipleSymbianStreamEventBits aEvents);
323 * Returns pointer to pixel buffer.
325 * @param buffer Handle of buffer
328 GetBufferPtrL(SymbianStreamBuffer buffer);
331 * Undocumented protection flag
333 * @param flag enable disable protection
336 SetProtectionFlag(TBool flag);
338 TInt BufferHandleToIndex(SymbianStreamBuffer aBuff);
341 * Add event observer for stream. Observers are served in
342 * first-come-first-serve fashion. That is, newest observer
343 * is always placed at the end of the chain.
345 * @param observer Observer (callback function) who should
346 * be notified when something interesting happens in the stream.
347 * @aEvent The event corresponding to the observer
348 * @aScreenNumber The context identifier (screen number)
349 * @param data Additional data to pass to callback function
351 * @return KErrNone if successful
352 * KErrArgument if un unknown event is registered
353 * KErrOverflow if the observer was already registered
354 * An other system wide error if container couldn't be appended
355 * OOM situation occurs.
357 int AddObserver(SymbianStreamCallback aObserver,
359 TInt32 aScreenNumber,
363 * Remove stream event observer. Observer is removed from
364 * the stream's event nofitication chain and won't receive
365 * any events from the stream afterwards.
367 * @param aObserver The callback function
368 * @param aEvent The event id corresponding to the observer
369 * @param aScreenNumber The screen number
370 * @param aData Data must uniquely identify the observer
372 * @param KErrNone if successful, -1 otherwise
373 * KErrArgument if un unknown event passed as parameter
374 * KErrNotFount if the event is not found
376 int RemoveObserver(TInt32 aEvents, void* aData);
379 * Notifies the observers not associated with a context.
380 * The aim is to support legacy SI behavior.
382 * @param aEvent Observer identifier
385 int NotifyObservers(TInt32 aEvent);
388 * Implements surface content notifications.
390 * When the contents of a surface change, this function gets called
391 * MCompositionSurfaceUpdate implementation.
393 * @param aSurface The surface that has been updated.
394 * @param aBuffer The buffer of the surface to be used in
395 * composition. Integer starting from 0.
396 * @param aRegion The sub-area that has the updates. If NULL, the
397 * whole surface is considered changed.
398 * @param aStatusConsumed A request status object or NULL. If not NULL, then the
399 * request status is completed once the backend
400 * does not anymore need the contents of the
401 * surface to render the update. This may happen
402 * before actually displaying the finished frame.
403 * @param aStatusDisplayed This is signaled after the composited frame
404 * is posted the to display for the first time after
405 * the update. After this the value in
406 * aTimeStamp is valid, if the value in the
407 * status object is KErrNone. Can be NULL, if
408 * no signal is desired.
409 * @param aTimeStamp Value of the User::FastCounter() right after the
410 * display refresh that signaled aStatusDisplayed.
411 * @param aStatusDispXTimes This is signaled when the surface has been on
412 * the screen for aDisplayedXTimes refreshes,
413 * including the update that signaled aStatusDisplayed.
414 * Can be NULL, if no signal is wanted.
415 * @param aDisplayedXTimes The number of refreshes after which aStatusDispXTimes
416 * is signaled or NULL. If values is provided, it must be
418 * @param aScreenNumber Uniquelly identifies the context (composer)
420 void SetNewNotifications(TInt aBuffer,
421 TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp,
422 TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes,
423 TRequestStatus* aStatusConsumed, const TRegion* aRegion,
424 TInt32 aScreenNumber);
427 * Implements surface content notifications.
429 * When the contents of a surface change, this function gets called
430 * MCompositionSurfaceUpdate implementation.
432 * @param aSurface The surface that has been updated.
433 * @param aBuffer The buffer of the surface to be used in
434 * composition. Integer starting from 0.
435 * @param aRegion The sub-area that has the updates. If NULL, the
436 * whole surface is considered changed.
437 * @param aStatusConsumed A request status object or NULL. If not NULL, then the
438 * request status is completed once the backend
439 * does not anymore need the contents of the
440 * surface to render the update. This may happen
441 * before actually displaying the finished frame.
442 * @param aStatusDisplayed This is signaled after the composited frame
443 * is posted the to display for the first time after
444 * the update. After this the value in
445 * aTimeStamp is valid, if the value in the
446 * status object is KErrNone. Can be NULL, if
447 * no signal is desired.
448 * @param aTimeStamp Value of the User::FastCounter() right after the
449 * display refresh that signaled aStatusDisplayed.
450 * @param aStatusDispXTimes This is signaled when the surface has been on
451 * the screen for aDisplayedXTimes refreshes,
452 * including the update that signaled aStatusDisplayed.
453 * Can be NULL, if no signal is wanted.
454 * @param aDisplayedXTimes The number of refreshes after which aStatusDispXTimes
455 * is signaled or NULL. If values is provided, it must be
457 * @param aScreenNumber Uniquelly identifies the context (composer)
459 void SetAllNotifications(TInt aBuffer,
460 TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp,
461 TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes,
462 TRequestStatus* aStatusConsumed, const TRegion* aRegion);
465 * Process the notifications by accessing the information stored in the observer container.
467 * This method is expected to be called from the observer context every time composer has finished processing
468 * a stream and the rigger condition is met.
470 * @param aEvent Events map to identify the observer to be processed.
471 * @param aScreenNumber Screen ID used to identify the target composer that invokes the method
472 * @param aOperation The Operation expected to be executed
473 * @param aSerialNumber A number used to identify the composition operation
474 * @param aReturnMask Parameter to be retrieved by composer, representing the event to be processed
475 * when composed next time. A new composition is automatically triggered.
478 void ProcessNotifications(TInt32 aEvent, TInt32 aScreenNumber, TInt32 aOperation, TInt32 aSerialNumber, TInt32* aReturnMask);
481 * A function that checks the validity of the new buffer provided by SUS
484 * When the contents of a surface change, this function gets called by the MCompositionSurfaceUpdate implementation.
485 * If the buffer is invalid all request statuses will be completed with KErrArgument
487 * @param aBuffer The buffer of the surface to be used in
488 * composition. Integer starting from 0.
489 * @param aStatusConsumed A request status object or NULL.
490 * @param aStatusDisplayed A request status object or NULL.
491 * @param aStatusDispXTimes A request status object or NULL.
493 * @return KErrNone if successful
494 * KErrArgument if aBuffer parameter is invalid
497 TInt CheckBufferNumber(TInt aBuffer,
498 TRequestStatus* aStatusDisplayed,
499 TRequestStatus* aStatusDispXTimes,
500 TRequestStatus* aStatusConsumed);
502 TInt GetChunkHandle();
506 * Notifies the composer that the content has been updated.
509 * @param aScreenNumber Screen ID used to identify the target composer
510 * @param aOp The Operation expected the callback to execute
511 * @param aParam Parameter containing aaditional information to push/pop from targetet composer
514 TBool NotifyComposerContext(TInt32 aScreenNumber, TInt aOp, SYMOWF_CONTENT_UPDATED_PARAM* aParam);
517 * Notifies the composer that the content is in process to be updated. The composer will have to not access
518 * observer related information
521 * Note that while calling the callback the context update mutex is acquired.
523 * @param aScreenNumber Screen ID used to identify the target composer
524 * @param aBufferNum The buffer number to be updated
525 * @param aUpdatedFlags The events that triggers this function call
526 * @param aRegion The sub-area that has the updates. If NULL, the whole surface is considered changed.
528 TBool StartUpdateNotifications(TInt aScreenNumber, SYMOWF_CONTENT_UPDATED_PARAM& param);
531 * Notifies the composer that process of updating the content has finisshed
533 * The composer releases the content mutex and triggers a new composition
535 * @param aScreenNumber Screen ID used to identify the target composer
536 * @param aBufferNum The buffer number to be updated
537 * @param aUpdatedFlags The events that triggers this function call
538 * @param aRegion The sub-area that has the updates. If NULL, the whole surface is considered changed.
540 TBool EndUpdateNotifications(TInt aScreenNum,
542 TInt32 aUpdatedFlags,
543 const TRegion* aRegion);
546 * Notifies the composer that content has been updated
548 * It is used to support old SI behaviour. The content update mutex is acuired
549 * and released while a new composition is triggered
551 * @param aScreenNumber Screen ID used to identify the target composer
552 * @param aBufferNum The buffer number to be updated
553 * @param aUpdatedFlags The events that triggers this function call
554 * @param aRegion The sub-area that has the updates. If NULL, the whole surface is considered changed.
556 TBool UpdateNotifications(TInt aScreenNum,
558 TInt32 aUpdatedFlags,
559 const TRegion* aRegion);
562 * Processes the available observer
564 * @param aEvent Events map to identify the operation to be executed.
565 * @param aSerialNumber A number used to identify the composition operation
566 * @param ContentUpdatedParams Packs the information used when a new request from SUS has to be processed
567 * @param aCallBackData The observer data stored in the container of observers
568 * @param aReturnMask Parameter to be retrieved by composer, representing the event to be processed
570 void Available(TInt32 aEvent, TInt32 aSerialNumber, ContentUpdatedParams* aParams, void* aCallBackData, TInt32* aReturnMask);
572 * Processes the available observer
574 * @param aEvent Events map to identify the operation to be executed.
575 * @param aSerialNumber A number used to identify the composition operation
576 * @param ContentUpdatedParams Packs the information used when a new request from SUS has to be processed
577 * @param aCallBackData The observer data stored in the container of observers
578 * @param aReturnMask Parameter to be retrieved by composer, representing the event to be processed
580 void Displayed(TInt32 aEvent, TInt32 aSerialNumber, ContentUpdatedParams* aParams, void* aCallBackData, TInt32* aReturnMask);
582 * Processes the available observer
584 * @param aEvent Events map to identify the operation to be executed.
585 * @param aSerialNumber A number used to identify the composition operation
586 * @param ContentUpdatedParams Packs the information used when a new request from SUS has to be processed
587 * @param aCallBackData The observer data stored in the container of observers
588 * @param aReturnMask Parameter to be retrieved by composer, representing the event to be processed
590 void DisplayedXTimes(TInt32 aEvent, TInt32 aSerialNumber, ContentUpdatedParams* aParams, void* aCallBackData, TInt32* aReturnMask);
592 * Function used to reset observer data fields
594 * @param aEvent Event identifier for whis the operation is to be executed.
595 * @param aCallBackData The observer data stored in the container of observers
597 void ResetCallBackData(void* aCallBackData, TInt32 aEvent);
599 * Cancels all active notifications by completeting the associated requests
601 void CancelNotifications();
603 void SetNotifications(TInt aBuffer,
604 TRequestStatus* aStatusDisplayed, TUint32* aTimeStamp,
605 TRequestStatus* aStatusDispXTimes, TInt* aDisplayedXTimes,
606 TRequestStatus* aStatusConsumed, const TRegion* aRegion,
607 TInt32 aScreenNumber, const TNewGlobalNotifications& aGlobalNotifications);
609 void RequestComplete(TThreadId& aThreadId, TRequestStatus*& aRequestStatus, TInt& aGlobalIndexArray, TInt aStatus);
611 * Constructor for performing 1st stage construction
616 * Symbian's default constructor for performing 2nd stage construction
618 void ConstructL(const TSurfaceId& aId);
620 TInt AddNewGlobalNotification(TRequestStatus* aStatusDisplayed, TInt aAssociatedScreens);
621 void SetReadBufferIndex(TInt aIndex);
622 TInt GetReadBufferIndex();
623 TInt GetWriteBufferIndex();
624 TInt Stride(TInt aWidth, TUidPixelFormat aPixelFormat);
625 static SymbianStreamBuffer IndexToReadHandle(TInt aIndex);
626 static SymbianStreamBuffer IndexToWriteHandle(TInt aIndex);
628 static COpenWfcStreamMap& GetSingletonL();
630 void SurfaceInfoL(const TSurfaceId& aSurface, RSurfaceManager::TInfoBuf& aInfo);
635 EFlippedTargetNormal,
636 EFlippedTargetFlipped
640 // Each surface buffer has its corresponding TBufferInfo to hold reference count and memory offset
648 struct TCallBackEntry;
649 struct TGlobalNotification;
650 TSurfaceId iSurfaceId; //< Surface ID associated with stream.
651 TSurfaceId iStreamProxySurfaceId; //< Surface ID generated to represent stream
653 RFastLock iRefCountMutex;
656 TBufferInfo* iBufferInfo; //< Array of buffer info
657 RSurfaceManager::TSurfaceInfoV01 iInfo;
658 static const TInt BUFFER_READ_HANDLE_BASE = 0x100;
659 static const TInt BUFFER_WRITE_HANDLE_BASE = 0x200;
660 static const TInt BUFFER_WRITE_UPDATE_OVERWRITE = -1;
661 TInt iAcquiredWriteBuffer;
662 TAny* iCallBackHighestPriority;
663 RArray<TCallBackEntry> iCallBacks;
664 RFastLock iCallBacksMutex;
666 RArray<TGlobalNotification> iGlobalNotifications;
667 TInt iNumberOfScreenAttachedAvailableNotif;
668 TInt iNumberOfScreenAttachedDisplayedNotif;
669 TInt iNumberOfScreenAttachedDisplayedXNotif;
670 FlippedTarget iFlipState;
671 FlippedTarget iNewFlip;
674 #endif // SURFACESTREAM_H