sl@0: // Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #ifndef __SURFACEUPDATESERVER_H__ sl@0: #define __SURFACEUPDATESERVER_H__ sl@0: sl@0: /** sl@0: @file sl@0: @internalTechnology sl@0: */ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: enum TSurfaceUpdateServPanic sl@0: { sl@0: EUpdateServPanicBadRequest = 1, sl@0: EUpdateServPanicNoMemory, sl@0: EUpdateServPanicStartUp, sl@0: EUpdateServPanicDataIntegrity, sl@0: EUpdateServPanicRegister, sl@0: EUpdateServPanicGlobalFastLock, sl@0: }; sl@0: sl@0: enum TSurfaceUpdateEvent sl@0: { sl@0: EUpdateServEventRegister = 1, sl@0: EUpdateServEventTerminate //this event will only be used for test purpose sl@0: }; sl@0: sl@0: class CSurfaceUpdateServer; sl@0: sl@0: /** sl@0: The class implements interface(s) required for content update sl@0: Intended to be used by Surface-update control flow sl@0: @see MSurfaceUpdateServerProvider sl@0: */ sl@0: class CSurfaceUpdateServerProvider : public CActive, public MSurfaceUpdateServerProvider sl@0: { sl@0: public: sl@0: static CSurfaceUpdateServerProvider* NewL(CActive::TPriority aPriority, CSurfaceUpdateServer* aServer); sl@0: ~CSurfaceUpdateServerProvider(); sl@0: //from MSurfaceUpdateServerProvider sl@0: IMPORT_C TInt Register(TInt aScreen, CBase* aUpdateReceiver, TInt aPriority); sl@0: //the following function is intended to be used for test purpose only, sl@0: //will have no effect in the release build sl@0: IMPORT_C void Terminate(); sl@0: protected: sl@0: CSurfaceUpdateServerProvider(CActive::TPriority aPriority, CSurfaceUpdateServer* aServer); sl@0: void ConstructL(); sl@0: void RunL(); sl@0: void DoCancel(); sl@0: protected: sl@0: CSurfaceUpdateServer* iServer; sl@0: TThreadId iThreadId; sl@0: TInt iRegisterErr; sl@0: CBase* iUpdateReceiver; sl@0: TInt iScreen; sl@0: TInt iPriority; sl@0: RSemaphore iSemaphore; sl@0: }; sl@0: /** sl@0: Priority is used to identify the master screen for the surface. sl@0: */ sl@0: class TUpdateReceiverPriorityEntry sl@0: { sl@0: public: sl@0: TInt iPriority; //Highest number signifies highest priority of the screen. sl@0: MCompositionSurfaceUpdate* iUpdateReceiver; //doesn't own sl@0: }; sl@0: sl@0: sl@0: /** sl@0: The server maintains session with the clients. sl@0: It starts during the initialization of the Compositor thread. sl@0: */ sl@0: class CSurfaceUpdateServer : public CServer2 sl@0: { sl@0: friend class CSurfaceUpdateSession; sl@0: public: sl@0: static CSurfaceUpdateServer* NewL(); sl@0: sl@0: ~CSurfaceUpdateServer(); sl@0: sl@0: TInt Register(TInt aScreen, CBase* aUpdateReceiver, TInt aPriority); sl@0: virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const; sl@0: static void PanicServer(TSurfaceUpdateServPanic aPanic); sl@0: sl@0: /** sl@0: Provide surface update provider for usage by the content update receiver. sl@0: sl@0: @return surface update provider sl@0: */ sl@0: MSurfaceUpdateServerProvider* SurfaceUpdateProvider() const sl@0: { sl@0: return static_cast (iServerProvider); sl@0: } sl@0: static TInt ThreadFunction(TAny* aAny); sl@0: // for DEF118736: [v9.5] turfaceupdatetestserver unexecuted sl@0: // For test purposes, only if iNumberPendingNotification reaches zero, the surface update server can be shut. sl@0: // The counter is incremented by one when the CUpdateReceiverNotification AO is set to self-destroyed in surface update session's destructor() sl@0: // The counter is decremented by one before its self-destruction in CUpdateReceiverNotification AO's RunL() sl@0: #ifdef TEST_SURFACE_UPDATE sl@0: TInt iNumberPendingNotification; sl@0: #endif sl@0: protected: sl@0: void ConstructL(); sl@0: CSurfaceUpdateServer(CActive::TPriority aPriority); sl@0: MCompositionSurfaceUpdate* UpdateReceiver(TInt aScreen) const; sl@0: /** sl@0: @return content update receiver priority list sl@0: */ sl@0: inline const RPointerArray& UpdateReceiverPriority() const; sl@0: sl@0: inline TInt NumUpdateReceivers() const; sl@0: static TInt CompareUpdateReceiverPriority(const TUpdateReceiverPriorityEntry& aEntry1, const TUpdateReceiverPriorityEntry& aEntry2); sl@0: protected: sl@0: RPointerArray iUpdateReceiver; //Screen number is the index for the access of the receiver entry in the array sl@0: RPointerArray iUpdateReceiverPriorityOrder; //stored in priority order, the higher the priority of the receiver the closer to the beginning of the array sl@0: CSurfaceUpdateServerProvider* iServerProvider; sl@0: }; sl@0: sl@0: sl@0: enum TNotificationType sl@0: { sl@0: EUpdateSrvReusable = 1, /**< When a notification batch doesn’t contain any active notifiers, i.e. they have been processed by the content update receiver, the batch will not be deleted but becomes available for the following reuse.*/ sl@0: EUpdateSrvAvailable, sl@0: EUpdateSrvDisplayed, sl@0: EUpdateSrvDisplayedXTimes, sl@0: }; sl@0: sl@0: class CSurfaceUpdateSession; sl@0: class CUpdateReceiverNotificationBatch; sl@0: sl@0: /** sl@0: Notification object. Content update receiver signals the server via this object of composition events. sl@0: */ sl@0: class CUpdateReceiverNotification : public CActive sl@0: { sl@0: public: sl@0: CUpdateReceiverNotification(CActive::TPriority aPriority, TInt aReceiverPriority, CUpdateReceiverNotificationBatch *aParentNotificationBatch); sl@0: ~CUpdateReceiverNotification(); sl@0: TRequestStatus& Status(); sl@0: void Activate(); sl@0: protected: sl@0: void DoCancel(); sl@0: virtual void RunL(); sl@0: public: sl@0: TUint32 iTimeStamp; sl@0: TInt iUpdateReceiverPriority; sl@0: TBool iSelfDestructWhenRun; sl@0: protected: sl@0: #ifdef TEST_SURFACE_UPDATE sl@0: void DecNumberPendingNotifications(); sl@0: #endif sl@0: protected: sl@0: CUpdateReceiverNotificationBatch *iParentNotificationBatch; //doesn't own sl@0: #ifdef TEST_SURFACE_UPDATE sl@0: CSurfaceUpdateServer* iServer; sl@0: #endif sl@0: }; sl@0: sl@0: /** sl@0: The class manages the batch of notification objects with the same type and sl@0: initiated by the particular SubmitUpdate request. sl@0: */ sl@0: class CUpdateReceiverNotificationBatch : public CBase sl@0: { sl@0: public: sl@0: CUpdateReceiverNotificationBatch(CSurfaceUpdateSession *aSession, TInt aNumReceivers); sl@0: ~CUpdateReceiverNotificationBatch(); sl@0: void ProcessNotificationEvent(CUpdateReceiverNotification* aReceiverNotification); sl@0: TBool IsActive() const; sl@0: CUpdateReceiverNotification* UpdateReceiverNotification(TInt aReceiverPriority = 0); sl@0: void CheckForReuse(); sl@0: void SetNumUpdateReceivers(TInt aNumUpdateReceivers); sl@0: #ifdef TEST_SURFACE_UPDATE sl@0: CSurfaceUpdateServer* Server(); sl@0: void IncNumberPendingNotifications(); sl@0: #endif sl@0: public: sl@0: RMessage2 iMsg; sl@0: TNotificationType iType; sl@0: RPointerArray iUpdateReceiverNotifications; //for multiple entries stored in priority order, the higher the priority of the receiver the closer to the beginning of the array sl@0: protected: sl@0: CSurfaceUpdateSession *iSession; //doesn't own sl@0: TInt iNumUpdateReceivers; sl@0: TBool iCompleteWithSuccess; sl@0: TInt iHighestPriority; //attributed to successful notification sl@0: TUint32 iTimeStamp; //attributed to successful notification sl@0: }; sl@0: sl@0: /** sl@0: Maintain the channel between clients and the server. sl@0: Functions are provided will respond appropriately to client messages. sl@0: */ sl@0: class CSurfaceUpdateSession : public CSession2 sl@0: { sl@0: public: sl@0: CSurfaceUpdateSession(const RPointerArray& aReceiverEntryList); sl@0: ~CSurfaceUpdateSession(); sl@0: void SubmitUpdate(const RMessage2& aMessage); sl@0: void NotifyWhenAvailable(const RMessage2& aMessage); sl@0: void NotifyWhenDisplayed(const RMessage2& aMessage); sl@0: void NotifyWhenDisplayedXTimes(const RMessage2& aMessage); sl@0: void CancelAllUpdateNotifications(); sl@0: protected: sl@0: void DoSubmitUpdateL(const RMessage2& aMessage); sl@0: void StoreNotification(CUpdateReceiverNotificationBatch*& aNotifier, const RMessage2& aMessage, TNotificationType aType); sl@0: virtual void ServiceL(const RMessage2& aMessage); sl@0: void PanicClient(const RMessage2& aMessage, TInt aPanic) const; sl@0: CUpdateReceiverNotificationBatch* UpdateReceiverNotificationBatchL(); sl@0: void IssueRequestComplete(TInt aErr); sl@0: void DispatchUpdate(const TSurfaceId& aSurfaceId, TInt aBuffer, RRegion* aRegion, TInt* aDisplayedXTimes, MCompositionSurfaceUpdate* aReceiver = NULL ); sl@0: #ifdef TEST_SURFACE_UPDATE sl@0: void SetHeapFailure(const RMessage2& aMessage); sl@0: #endif sl@0: private: sl@0: RPointerArray iUpdateReceiverNotificationBatches; sl@0: CUpdateReceiverNotificationBatch* iAvailable; sl@0: CUpdateReceiverNotificationBatch* iDisplayed; sl@0: CUpdateReceiverNotificationBatch* iDisplayedXTimes; sl@0: const RPointerArray& iUpdateReceiverEntryList; //doesn't own sl@0: enum sl@0: { sl@0: EUpdateMethodNone, sl@0: EUpdateMethodPerScreen, sl@0: EUpdateMethodGlobal, sl@0: } iUpdateMethod; sl@0: }; sl@0: sl@0: inline const RPointerArray& CSurfaceUpdateServer::UpdateReceiverPriority() const sl@0: { sl@0: return iUpdateReceiverPriorityOrder; sl@0: } sl@0: sl@0: #endif