emulator/emulatorbsp/inc/display_chan.h
changeset 0 cec860690d41
child 14 2b9ddd958b2b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emulator/emulatorbsp/inc/display_chan.h	Tue Feb 02 01:39:10 2010 +0200
@@ -0,0 +1,242 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @publishedPartner
+ @prototype
+*/
+
+#ifndef __DISPLAY_CHAN_H__
+#define __DISPLAY_CHAN_H__
+
+#include "nk_priv.h"
+#include <dispchannel.h>
+#include <videodriver.h>
+#include "displayhandler.h"
+
+struct TBufferAddressA;
+class TScreenBuffer;
+/**
+Logical Channel kernel side class for Display
+*/
+
+
+class DDisplayChannel : public DLogicalChannel
+	{
+public:
+	// constants
+	enum { KDisplayChMajorVersionNumber = 1 };
+	enum { KDisplayChMinorVersionNumber = 2 };
+	enum { KDisplayChBuildVersionNumber = 1 };
+public:
+	// Duplicate of RDisplayChannel structure, as the header file cannot be used.
+	class TCaps
+    {
+      public:
+          TVersion iVersion;
+    };
+
+	class TRequest
+		{
+	public:
+		inline TRequest(void) : iThread(0), iStatus(0) {}
+		TBool SetStatus(TThreadMessage& aMsg);
+		void Complete(TInt aResult);
+	public:
+		DThread* iThread;
+		TRequestStatus* iStatus;
+		};
+
+	class TBufferInfo
+		{
+	public:
+		TAny* iAddress;
+		DChunk* iChunk;
+		TRequest iRequest;
+		};
+
+	enum TDisplayPanic
+		{
+		EDisplayPanicNullThreadOnSet = 1,
+		EDisplayPanicInUse = 2,
+		EDisplayPanicThreadAlreadySet = 3,
+		EDisplayPanicNullThreadOnComplete = 4,
+		EDisplayPanicThreadOpenFailed = 5,
+		EDisplayPanicWaitForPostMissed = 6,
+		EDisplayPanicNullArgument = 7,
+		EDisplayPanicNotYetImplemented = 8,
+		EDisplayPanicInvalidDimensions = 9,
+		EDisplayPanicInvalidRotation = 10,
+		EDisplayPanicInvalidBitDepth = 11,
+		EDisplayPanicInvalidStride = 12,
+		EDisplayPanicInvalidWindowHandle = 13,
+		EDisplayPanicInvalidFrameBuffers = 14,
+		EDisplayPanicInvalidRefreshRate = 15,
+		EDisplayPanicInvalidOffset = 16,
+		EDisplayPanicNoLegacyBuffer = 17
+		};
+
+public:
+	DDisplayChannel(void);
+	~DDisplayChannel(void);
+
+	// DLogicalChannel implementation
+	virtual TInt DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer);
+	virtual void HandleMsg(TMessageBase* aMsg);
+
+	// Function used by the UI code to set up the buffers.
+	virtual TInt Initialize(RDisplayChannel::TDisplayInfo& aInfo, 
+							RDisplayChannel::TDisplayRotation aRotation,
+							HWND aHwnd, RPointerArray<TAny>& aFrameBuffers, 
+							RPointerArray<TBufferAddressA>& aChunks,
+							TScreenBuffer& aDsaBuffer,
+							TSize aResolution, 
+							TSize aTwips,
+							const RDisplayChannel::TPixelFormat aPixelFormatArray[],
+							const TInt aPixelFormatArraySize,
+							const RDisplayChannel::TBufferFormat& aBufferFormat);
+	virtual void SetLegacyBuffer(void *aAddress);
+
+private:
+	DDisplayChannel(const DDisplayChannel&);
+
+	// Handlers for the three classes of channel message sent
+	TInt DoControl(TInt aFunction);
+	void DoRequest(TInt aFunction);
+	TInt DoCancel(TInt aRequestMask);
+	TInt NumberOfResolutions();
+	TInt SafePut(TAny* aDst, TAny* aSrc, TInt aBytes);
+
+	void ValidateSpecificInfo(TInt aBytesPerPixel, RDisplayChannel::TOrientationSpecificInfo& aInfo);
+	static void Panic(TDisplayPanic aPanic);
+	void ClientPanic(RDisplayChannel::TPanic aPanic);
+
+	inline TBool IsCompositionBuffer(RDisplayChannel::TBufferId aId);
+	static inline TBool IsLegacyBuffer(RDisplayChannel::TBufferId aId);
+	static inline TBool IsUserBuffer(RDisplayChannel::TBufferId aId);
+	inline TBool IsValidBuffer(RDisplayChannel::TBufferId aId);
+    inline RDisplayChannel::TBufferId NextCompositionBuffer(RDisplayChannel::TBufferId aId);
+
+	static inline TBool IsFlipped(RDisplayChannel::TDisplayRotation aRotation);
+
+	static void VSyncTimerFn(TAny* aDisplayChannel);
+	void DoVSyncTimer(void);
+	static void VSyncDfcFn(TAny* aDisplayChannel);
+	void DoVSync(void);
+
+	TInt PostCompositionBuffer(TAny* aRegion, RDisplayChannel::TPostCount* aPostCount);
+	TInt PostLegacyBuffer(TAny* aRegion, RDisplayChannel::TPostCount* aPostCount);
+	TInt GetCompositionBuffer(TAny** aAddress);
+	TInt PostUserBuffer(RDisplayChannel::TBufferId* aBufferId, TAny* aRegion, RDisplayChannel::TPostCount* aPostCount);
+	TInt WaitForPost(RDisplayChannel::TPostCount* aPostCount);
+	TInt WaitForDisplayConnect();
+	TInt SetRotation(RDisplayChannel::TDisplayRotation* aNewRotation, TBool* aIsBufferPreserved);
+	TInt RegisterUserBuffer(TInt aChunkHandle, TInt aOffset, RDisplayChannel::TBufferId* aBufferId);
+	TInt DeregisterUserBuffer(RDisplayChannel::TBufferId* aBufferId);
+	TInt GetResolutions();
+	TInt SetResolution(TSize* aSize);
+	TInt GetResolution(TSize* aSize);
+	TInt GetTwips(TSize* aSize);
+	TInt GetIndexForSize(const TSize& aSize,TInt& aSpinnerOut);
+	TInt GetPixelFormats();
+	TInt SetBufferFormat(RDisplayChannel::TBufferFormat* aBufferFormat);
+	TInt NextPlaneOffset(RDisplayChannel::TBufferFormat* aBufferFormat, 
+			            RDisplayChannel::TBufferFormatContext* aContext);
+	TInt NextLineOffset(RDisplayChannel::TBufferFormat* aBufferFormat, 
+			            RDisplayChannel::TBufferFormatContext* aContext);
+	TInt ValidateBufferFormat(const RDisplayChannel::TBufferFormat& aBufferFormat,
+						 	  const RDisplayChannel::TResolution& aResolution);
+private:
+	// Constants
+	enum {KDfcPriority = 6};
+
+	enum {KBufferNotSet = -1};
+
+	// Buffer index points. The legacy buffer is first, followed by the user
+	// buffers, followed by a variable number of composition buffers.
+	enum { KLegacyBuffer = 0};
+	enum { KFirstUserBuffer = KLegacyBuffer + 1};
+	enum { KFirstCompositionBuffer = KFirstUserBuffer + RDisplayChannel::TDisplayInfo::KMaxUserBuffers};
+	enum { KMaxBufferSizeHeightAndWidth = KMaxTInt16 };
+
+private:
+	TInt iScreenNumber;
+	TThreadMessage* iMsg;
+	TInt iVSyncTicks;					// Number of nanokernel ticks between frames
+	TUint iNumCompositionBuffers;		// Number of composition buffers
+	TUint iTotalBuffers;				// KFirstCompositionBuffer + iNumCompositionBuffers
+	RDisplayChannel::TDisplayInfo iChannelInfo;
+	RDisplayChannel::TPostCount iPostCount;				// Count of Post... calls
+	RDisplayChannel::TPostCount iLastPostCount;			// Value of iPostCount when last buffer was actually posted
+	TBufferInfo* iBuffer;				// Allocated to contain iTotalBuffers
+	TBufferAddressA* iChunks;
+	DThread* iClient;
+
+	// Posting support
+	NTimer iVSync;						// Emulated VSync signal using a timer
+	TDfc iVSyncDfc;						// DFC queued on DfcQue0 when iVSync triggers
+	RDisplayChannel::TBufferId iPostedBuffer;			// Index of buffer to be posted on next frame
+	RDisplayChannel::TDisplayRotation iCurrentRotation;	// Rotation of buffer being posted
+	RDisplayChannel::TDisplayRotation iNewRotation;	// Rotation of buffer being posted
+	TSize iCurrentResolution;			// Display resolution (normal rotation) to be posted
+	TSize iNewResolution;			    // Display resolution (normal rotation) for buffer being posted
+	TSize iCurrentTwips;
+	TInt iPostedRectCount;				// Number of rectangles defined in region
+	RECT iPostedRect[RDisplayChannel::TDisplayInfo::KMaxRectangles];	//
+
+	// Paint support
+	HWND iHwnd;							// Window to be painted
+	RDisplayChannel::TBufferId iDisplayBuffer;			// Index of buffer to be painted
+	RDisplayChannel::TDisplayRotation iDisplayRotation;	// Rotation of buffer to be painted
+	TSize iDisplayResolution;			// Display resolution (normal rotation) on screen
+
+	// GetCompositionBuffer support
+	TUint iGetBuffer;					// Index of next composition buffer
+
+	// WaitForPost support
+	RDisplayChannel::TPostCount iWaitForPost;			// Post count being awaited
+	TRequest iWaitForPostRequest;		// Request to complete when post count reached
+	
+	// WaitForDisplayConnect support 
+	TRequest iWaitForDisplayConnect;		// Request to complete when display connection state changes
+	
+	TInt iDisplayStateSpinner;
+	
+	TVersion iVersion;
+	const RDisplayChannel::TPixelFormat* iPixelFormatArray;
+	TInt iPixelFormatArraySize;
+	RDisplayChannel::TBufferFormat iInitialBufferFormat;
+	RDisplayChannel::TBufferFormat iCurrentBufferFormat;
+	RDisplayChannel::TBufferFormat iDisplayBufferFormat;
+	RDisplayChannel::TBufferFormat iNewBufferFormat;
+	};
+
+inline TBool DDisplayChannel::IsCompositionBuffer(RDisplayChannel::TBufferId aId)
+	{ return (aId >= KFirstCompositionBuffer && aId < iTotalBuffers); }
+inline TBool DDisplayChannel::IsLegacyBuffer(RDisplayChannel::TBufferId aId)
+	{ return (aId == KLegacyBuffer); }
+inline TBool DDisplayChannel::IsUserBuffer(RDisplayChannel::TBufferId aId)
+	{ return (aId >= KFirstUserBuffer && aId < (KFirstUserBuffer + RDisplayChannel::TDisplayInfo::KMaxUserBuffers)); }
+inline TBool DDisplayChannel::IsValidBuffer(RDisplayChannel::TBufferId aId)
+	{ return (aId >= 0 && aId < iTotalBuffers); }
+inline RDisplayChannel::TBufferId DDisplayChannel::NextCompositionBuffer(RDisplayChannel::TBufferId aId)
+	{ TUint r = (aId + 1); return (r >= iTotalBuffers) ? KFirstCompositionBuffer : r; }
+
+inline TBool DDisplayChannel::IsFlipped(RDisplayChannel::TDisplayRotation aRotation)
+	{ return !(aRotation & (RDisplayChannel::ERotationNormal | RDisplayChannel::ERotation180)); }
+
+#endif
+