sl@0: // Copyright (c) 2006-2009 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 __SURFACEUPDATECLIENT_H__ sl@0: #define __SURFACEUPDATECLIENT_H__ sl@0: sl@0: #include sl@0: #include sl@0: #ifdef TEST_SURFACE_UPDATE sl@0: #include "surfaceupdate.h" sl@0: #include "surfaceupdatetest.h" sl@0: #endif sl@0: sl@0: class TSurfaceId; sl@0: sl@0: const TInt KDefaultMessageSlot = 6; sl@0: sl@0: typedef TPckgBuf TTimeStamp; sl@0: sl@0: /** sl@0: The RSurfaceUpdateSession class is intended to be used by surface update control flow. sl@0: The class implements an interface between the Compositor and clients. It allows a client to sl@0: inform the Compositor when a surface has been modified and to receive notification when sl@0: its buffer becomes available and/or displayed. sl@0: */ sl@0: class RSurfaceUpdateSession : public RSessionBase sl@0: { sl@0: public: sl@0: IMPORT_C RSurfaceUpdateSession(); sl@0: /** sl@0: Connect to the server using given number of message slots. sl@0: sl@0: @param aMessageSlots The number of message slots available to this session. sl@0: This parameter is defined in RSessionBase specification; it signifies the maximum number sl@0: of asynchronous outstanding requests to the server. sl@0: SubmitUpdate commands could contain up to three asynchronous requests to the server, sl@0: each corresponds to a different type of notification. sl@0: sl@0: @see RSessionBase sl@0: sl@0: @pre The surface update server is started up sl@0: @post Connection to the server has been established. sl@0: sl@0: @return KErrNone if successful. sl@0: @return KErrAlreadyExists if the session has already been established. sl@0: @return KErrArgument if arguments don’t lie within expected range. sl@0: @return KErrNotFound if the server is not in operation, otherwise one of the sl@0: system-wide error codes. sl@0: */ sl@0: IMPORT_C TInt Connect(TInt aMessageSlots = KDefaultMessageSlot); sl@0: sl@0: /** sl@0: Close the session to the server. sl@0: sl@0: @pre Outstanding notification requests (if any) are cancelled. sl@0: @post The session is disconnected. sl@0: */ sl@0: IMPORT_C void Close(); sl@0: sl@0: /** sl@0: Send update message to the server. All notification requests will also be submitted at sl@0: this stage. sl@0: This is referring to when notifications are requested before the update request. sl@0:

The GCE may collapse a few requests into one. sl@0: If a few requests with different buffer numbers specified for the same surface have sl@0: been submitted at specific composition cycle, only last such request will have effect. sl@0:

Clients can send a global submit update which will be broadcast by the SUS to all sl@0: backends presented in the system. For a global update, to all screens, sl@0: the pre-defined constant KAllScreens needs to be passed as the screen parameter sl@0: to SubmitUpdate. sl@0: Note that once a Client has begun issuing SubmitUpdate with either KAllScreens or a sl@0: specific screen, then only that type of screen can be used thereafter for that sl@0: Surface Update Session, i.e. the client cannot have a mix of SubmitUpdate with sl@0: KAllScreens and specific screens. sl@0: sl@0: @see RSurfaceUpdateSession::NotifyWhenAvailable sl@0: @see RSurfaceUpdateSession::NotifyWhenDisplayed sl@0: @see RSurfaceUpdateSession::NotifyWhenDisplayedXTimes sl@0: sl@0: @param aScreen Screen number. KAllScreens is the only allowed parameter. sl@0: @param aSurfaceId Secure 128-bit surface unique identifier, which fully specified the sl@0: surface. Surface ID must be assigned and registered with the GCE. sl@0: @param aBuffer Current buffer for composition. Varies from 0 to N-1, where N is the sl@0: total number of buffers in the surface. sl@0: @param aRegion The region requiring update, if this is NULL or empty, the whole sl@0: surface will be used for composition. The function doesn’t take ownership of sl@0: this parameter. sl@0: sl@0: @pre The surface session must be established to the server. sl@0: @post The GCE will trigger composition to use this region at the next composition cycle. sl@0: sl@0: @return KErrNone if a message has been transferred to the server successfully. sl@0: @return KErrArgument if arguments don’t lie within expected range. sl@0: @return KErrBackendNotAvailable if backend for specified screen hasn’t been registered sl@0: with the server. sl@0: @return KErrNotSupported if global and per-screen update are mixed within the same session. sl@0: @return KErrNoMemory if the memory is not enough to fulfill the request, sl@0: otherwise one of the system-wide error codes. sl@0: Will panic if applied on disconnected session. sl@0: */ sl@0: IMPORT_C TInt SubmitUpdate(TInt aScreen, const TSurfaceId& aSurfaceId, TInt aBuffer, sl@0: const TRegion* aDirtyRegion = NULL); sl@0: sl@0: /** sl@0: The message signals the client that the buffer associated with the notifier is available sl@0: for further updates. sl@0:

For performance reasons, the GCE uses the buffer sent by the client for composition sl@0: directly rather than composing with a copy of the buffer. sl@0: This means that, potentially, a client could be rendering to a buffer which is currently sl@0: being used for composition, leading to artefacts and possible tearing. sl@0: Depending on whether the surface is single or multi-buffered, there is some difference sl@0: in behaviour: sl@0:

  • In the case of single-buffered surfaces, the GCE will not wait for the next sl@0: submit update and will complete the request after the composition.
  • sl@0:
  • In case of multi-buffered surfaces, the GCE can postpone with the issuing the notification sl@0: to the client even after the composition with the specified surface buffer has already happened, sl@0: and issues the request when the client changes the active buffer, i.e. submits another sl@0: request for update with different buffer. This will help the GCE to keep the active buffer in a sl@0: valid state should another composition required.
  • sl@0:

    This notification enables a client to, if desired, be able to perform artefact free sl@0: rendering using this notification in conjunction with a multi-buffered surface. sl@0:

    Note that since the compositor can delay to issue request complete for multi-buffered sl@0: surface until the change of the active buffer occurs, the completion of a particular sl@0: notifier may not relate to the buffer to which it is intuitively associated. sl@0:

    Only the last call of this function before SubmitUpdate command takes place will have sl@0: effect, i.e. the following call will override the previous one. sl@0: This request will only be associated with the following single call of the SubmitUpdate. sl@0:

    When a SubmitUpdate has been broadcast to all available screen, i.e. KAllScreens was sl@0: supplied as a screen number, for multi-buffered surfaces, the notification will be completed sl@0: when the surface buffer has been released by all displays it is being shown on. sl@0: For single-buffered surfaces, notification will be completed when all displays have read sl@0: the buffer once. sl@0: sl@0: @param aStatus Reference to the request status object. sl@0: sl@0: @see RSurfaceUpdateSession::SubmitUpdate sl@0: sl@0: @pre The surface session must be established to the server. sl@0: @post This request for the consumption notification event will be transferred to the GCE sl@0: at next SubmitUpdate command. sl@0: sl@0: @return KErrNone if consumption has succeeded, the request completed aStatus will sl@0: contain this code. sl@0: @return KErrOverflow if the GCE drops the frame for composition. That could happen sl@0: if the GCE can’t cope with the current composition rate or the new request arrives sl@0: while the current is still in a progress. sl@0: The buffer overflow error can only happen with double buffering: sl@0:

  • If notification is not being used
  • sl@0:
  • If notification is not being used correctly as the client is not waiting for sl@0: notification to complete before sending a further buffer.
  • sl@0: sl@0: If an application such as video is using three (or more) buffers, this error can occur. sl@0: For instance, the video may be producing frames at a fixed rate which is faster than sl@0: the GCE can cope with, and in this case frames will be “lost”, but the notification sl@0: mechanism will still operate correctly. sl@0: sl@0: @return KErrBackendNotAvailable if backend for specified screen hasn’t been registered sl@0: with the server. sl@0: @return KErrArgument if arguments in SubmitUpdate command don’t lie within expected range. sl@0: @return KErrCancel if notification has been cancelled. It could happen, for instance, sl@0: if CancelUpdateNotification is called before the request is completed. sl@0: @return KErrServerBusy if the number of outstanding requests has exceeded specified sl@0: value (see RSurfaceUpdateSession::Connect for details). sl@0: @return KErrNotReady if the environment is in invalid state (for instance, the Surface sl@0: Update Server has not been launched or the session is disconnected). sl@0: @return KErrSurfaceNotRegistered if the surface is not registered with the specific backend. sl@0: @return KErrNotVisible if the surface specified in SubmitUpdate is not visible. sl@0: This could happen if there is no layer associated with the surface or no active sl@0: composition scene. sl@0: Note, the absence of this error code does not guarantee that the surface sl@0: is visible. For example, if the surface is behind another surface that has alpha blending sl@0: enabled the compositor will not do a pixel level comparison to determine surface visibility. sl@0: @return KErrSurfaceNotRegistered if the surface is not registered with the specific backend. sl@0: @return KErrNotSupported if global and per-screen update are mixed within the same session. sl@0: @return KErrNoMemory if the memory is not enough to fulfil the request, any other sl@0: system error codes. sl@0: Will panic if applied on disconnected session. sl@0: */ sl@0: IMPORT_C void NotifyWhenAvailable(TRequestStatus& aStatus); sl@0: sl@0: /** sl@0: Ask the server to notify when the surface buffer which will be specified in the next sl@0: update request has been displayed for the first time. sl@0: The notification will also include exact time of the event as it is supplied by the sl@0: User::FastCounter(). sl@0: Only the last call of this function before SubmitUpdate command takes place will sl@0: have effect, i.e. the following call will override the previous one. sl@0: sl@0: @param aStatus Reference to the request status object. sl@0: @param aTimeStamp Reference to the timestamp of the display notification event, sl@0: packed into the modified buffer descriptor. sl@0: Will only be valid if aStatus is equal to KErrNone. sl@0: sl@0: @see RSurfaceUpdateSession::SubmitUpdate sl@0: sl@0: @pre The surface session must be established to the server. sl@0: @post This request for the display notification event will be transferred to the GCE sl@0: at next SubmitUpdate command. sl@0: sl@0: @return KErrNone if the surface has been displayed successfully, when request sl@0: completed aStatus will contain this error code. sl@0: @return KErrOverflow if the updated buffer was not displayed because it was sl@0: superseded by a further update on the same surface. sl@0: @return KErrBackendNotAvailable if backend for specified screen hasn’t been sl@0: registered with the server. sl@0: @return KErrArgument if arguments in SubmitUpdate command don’t lie within expected range. sl@0: @return KErrCancel if notification has been cancelled. It could happen, for instance, sl@0: if CancelUpdateNotification is called before the request is completed. sl@0: @return KErrServerBusy if the number of outstanding requests has exceeded specified sl@0: value (@see RSurfaceUpdateSession::Connect for details). sl@0: @return KErrNotReady if the environment is in invalid state (for instance, the sl@0: Surface Update Server has not been launched or session is disconnected). sl@0: @return KErrNotVisible if the surface specified in SubmitUpdate is not visible. sl@0: This could happen if there is no layer associated with the surface or no active sl@0: composition scene. sl@0: For global update it signifies that the surface is not visible for any screen. sl@0: Note, the absence of this error code does not guarantee that the surface is visible. sl@0: For example, if the surface is behind another surface that has alpha blending sl@0: enabled the compositor will not do a pixel level comparison to determine surface visibility. sl@0: @return KErrSurfaceNotRegistered if the surface is not registered with the specific backend. sl@0: @return KErrNotSupported if global and per-screen update are mixed within the same session. sl@0: @return ErrNoMemory if the memory is not enough to fulfill the request, otherwise any sl@0: other system error codes. sl@0: Will panic if applied on disconnected session. sl@0: */ sl@0: IMPORT_C void NotifyWhenDisplayed(TRequestStatus& aStatus, TTimeStamp& aTimeStamp); sl@0: sl@0: /** sl@0: Ask the server to notify when the surface buffer which will sl@0: be specified in the next update request has been displayed for the X times. sl@0:

    Only the last call of this function before SubmitUpdate command takes place sl@0: will have effect, i.e. the following call will override the previous one. sl@0:

    In case of the global update the notification will always be aligned with the master sl@0: display. The SUS will send notification to client when the surface has been displayed on a sl@0: master display for the X times or if there is no master display for that surface. sl@0: If the master becomes invisible while the request is still in a progress it will be sl@0: reassigned to the next visible display with highest priority. sl@0:

    This request will only be associated with the following single call of the SubmitUpdate. sl@0: sl@0: @param aCount Number of times the surface is displayed before the request is completed. sl@0: Varies from 1 and greater. sl@0: @param aStatus Reference to the request status object. sl@0: sl@0: @pre The surface session must be established to the server. sl@0: @post This request for the display notification event will be transferred to the GCE at sl@0: next SubmitUpdate command. sl@0: sl@0: @return KErrNone if the surface has been displayed successfully for specified numbers sl@0: of times, when request completed aStatus will contain this error code. sl@0: @return KErrOverflow if the updated buffer did not remain on-screen for the specified sl@0: number of display refreshes because it was superseded by a further update on the sl@0: same surface. sl@0: @return KErrArgument if arguments in SubmitUpdate command don’t lie within expected range. sl@0: @return KErrBackendNotAvailable if backend for specified screen hasn’t been registered sl@0: with the server. sl@0: @return KErrCancel if notification has been cancelled. It could happen, for instance, sl@0: if CancelUpdateNotification is called before the request is completed. sl@0: @return KErrServerBusy if the number of outstanding requests has exceeded sl@0: specified value (@see RSurfaceUpdateSession::Connect for details). sl@0: @return KErrNotReady if the environment is in invalid state (for instance, the sl@0: Surface Update Server has not been launched or session is disconnected). sl@0: @return KErrNotVisible if the surface specified in SubmitUpdate is not visible. sl@0: This could happen if there is no layer associated with the surface or no active sl@0: composition scene. sl@0: For global update it signifies that the surface is not visible for any screen. sl@0: Note, the absence of this error code does not guarantee that the surface is visible. sl@0: For example, if the surface is behind another surface that has alpha blending sl@0: enabled the compositor will not do a pixel level comparison to determine surface visibility. sl@0: @return KErrSurfaceNotRegistered if the surface is not registered with the specific backend. sl@0: @return KErrNotSupported if global and per-screen update are mixed within the same session. sl@0: @return KErrNoMemory if the memory is not enough to fulfill the request, otherwise sl@0: any other system error codes. sl@0: Will panic if applied on disconnected session. sl@0: */ sl@0: IMPORT_C void NotifyWhenDisplayedXTimes(TInt aCount, TRequestStatus& aStatus); sl@0: sl@0: /** sl@0: Cancel all outstanding requests for notification. sl@0: The function doesn't cancel the submit update requests themselves. sl@0: sl@0: @pre The surface session must be established to the server. sl@0: @post The server will issue request complete immediately for all outstanding requests sl@0: related to particular session. sl@0: Will panic if applied on disconnected session. sl@0: */ sl@0: IMPORT_C void CancelAllUpdateNotifications(); sl@0: sl@0: protected: sl@0: /** sl@0: Allow to retrieve the version number. sl@0: sl@0: @return client version number sl@0: */ sl@0: TVersion Version() const; sl@0: sl@0: private: sl@0: void IssueRequestComplete(TInt aErr); sl@0: sl@0: private: sl@0: TRequestStatus *iStatusAvailable; sl@0: TRequestStatus *iStatusDisplayed; sl@0: TRequestStatus *iStatusDisplayedXTimes; sl@0: TTimeStamp* iTimeStamp; sl@0: TInt iCount; sl@0: }; sl@0: sl@0: #endif