windowing/windowserver/nga/SERVER/openwfc/redrawmsgwindow.h
author William Roberts <williamr@symbian.org>
Thu, 03 Jun 2010 17:39:46 +0100
branchNewGraphicsArchitecture
changeset 87 0709f76d91e5
parent 0 5d03bc08d59c
permissions -rw-r--r--
Add MMP files to build libOpenVG_sw.lib which uses LINKAS to redirect to libOpenVG.dll (and the same for libEGL_sw.lib and libOpenVGU_sw.lib). Only the libEGL_sw.lib redirection isn't activated - this can't happen until there is a merged libEGL.dll which supports the OpenWF synchronisation and also implements the graphical support functions. The overall aim is to eliminate the *_sw.dll implementations, at least as a compile-time way of choosing a software-only implementation.The correct way to choose is to put the right set of libraries into a ROM with suitable renaming, and in the emulator to use the "switching DLL" technique to pick the right set. As the Symbian Foundation doesn't have any alternative implementations, we don't need the switching DLLs and we can build directly to the correct name.

// Copyright (c) 2006-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:
// CWsRedrawMsgWindow and associated classes definitions
// 
//

#ifndef __REDRAWMSGWINDOW_H__
#define __REDRAWMSGWINDOW_H__

#include "wnredraw.h"
#include "redrawmsgwindow.h"

class CWsFbsFont;
class CWsDrawableSource;

// This class is intended to be used in cases, where it's needed to track how many times a CFbsBitmap
// is referenced, e.g. in redraws, where already drawn bitmaps need to be re-drawn in different position.
class CFbsBitmapRef : public CFbsBitmap
    {
public:
    CFbsBitmapRef();
    ~CFbsBitmapRef();
    inline TInt RefCount() const;
    inline void IncRefCount();
    inline void DecRefCount();
private:
    TInt iRefCount;
    };

class CWsRedrawMsgWindow : public CWsWindowRedraw
	{
	class CRedrawSegment;
	enum TFlags
		{
		EBackgroundClear=0x0001,		//Clear background when starting redraw
		EBeginEndRedraw=0x0002,			//This window is currently in the middle of a redraw, that is between client calls to BeginRedraw and EndRedraw.
		EPendingScheduledDraw=0x0004,   //We have scheduled a redraw but it hasn't happened yet
		EStoringEntireWindow=0x0008,    //If store commands for the entire window or only the viewport
		ECurrentRedrawFailedStorage=0x0010,		//The current redraw failed to store a command (is reset for each redraw). Is used to make sure we only request a redraw from the client once per failing redraw
		EPreviousRedrawFailedStorage=0x0020,	//The previous redraw failed to store a command. Is used to avoid infinite loops -- if two consecutive redraws fail (i.e. current and previous) then there is no use requesting yet another redraw from the client
		};
	enum TScope
		{
		EStoreEntireWindow,             //We try to obtain draw commands for the entire window
		EStoreViewport                  //We only try to obtain commands for the on screen viewport
		};
public:
	enum TRedrawSegmentType
		{
		ESegmentTypePendingRedraw,      // A redraw segment still being received
		ESegmentTypeRedraw              // A segment received between a begin and end redraw
		};
public:
	static void StaticInitL();
	CWsRedrawMsgWindow(CWsWindow *aWin);
	~CWsRedrawMsgWindow();
	void AddFbsBitmapsL(TInt aHandle, TInt aMaskHandle);
	void AddFbsBitmapRefL(TInt aHandle);
	void AddWsBitmapsL(TInt aHandle, TInt aMaskHandle);
	void AddWsFontL(TInt aHandle);
	void AddWsDrawableSourceL(TInt aHandle);
	void SetScope(TScope aStore);
	void CleanupBitmapRefArray(const RArray<TInt>& aHandleArray);
	
public:	//from CWsWindowRedraw		
	void ConstructL();
	TBool CommandL(TInt aOpcode, TWsWinCmdUnion &aCmd);
	void ClipInvalidRegion(const TRect &aRect);
	TBool NeedsRedraw() const;
	TBool GetRedrawRect(TRect &aRect) const;
	const TRegion& BaseDrawRegion() const;
	const TRegion& InvalidArea() const;
	void ClearRedrawStore(TBool aClearPendingRedraw=EFalse);
	TBool DrawCommand(CWsGc* aGc,const TAny *aCmdData);
	void GcAttributeChange(CWsGc* aGc,const TAny *aCmdData);
	void GcDeactivate(CWsGc* aGc);
	void ClientExposing();
	void DrawWindow();
	void PrepareForResizeL(const TSize &aSize, TSize &aOldSize);
	void Moved();
	TBool Contains(const TArray<TGraphicDrawerId>& aDrawers,const TRegion& aRegion) const;
	TBool ReleaseMemory(MWsMemoryRelease::TMemoryReleaseLevel aLevel);
	void VisibleRegionChange();
	TBool ReadyToDraw() const;
	TInt SizeInBytes() const;
	TBool RedrawingInProgress() const;
	void WindowClosing();
	TBool IsRedrawStoreEmpty() const;
	TBool IsBackgroundClearEnabled() const;
	CFbsBitmap* BitmapFromHandle(TInt aHandle) const;

private: //from CWsWindowRedraw	
	void Invalidate(const TRect * aRect = 0);
	TRgb BackColor() const;
	void Scroll(const TRect &aClipRect, const TPoint &aOffset,const TRect &aRect);
	
private:
	void RemoveFromRedrawQueueIfEmpty();
	const TRegion * ReadRegion(const TInt aRegionNum);
	void BeginRedraw(const TRect* aRect);
	void DoBeginRedrawL(const TRect* aRect);
	void SubtractRectFromSegmentArray(const TRect& aRect);
	void EndRedraw();
	void ValidateRect(const TRect *aRect);
	void StoreDrawCommandL(CWsGc* aGc,const TAny *aCmdData);
	void AppendCommandL(const TAny* aCmdData, const TUint16 aOpcodeFlags = 0);
	void StoreAllGcAttributesL(CWsGc* aGc);
	void DrawCommandsL();
	void DiscardStoredCommands();
	TBool DiscardSegmentsOutsideViewport();
	inline TBool NoBuffer() const;
	void DiscardStoredCommandsIfError(TInt aError);
	inline TBool IsFbsBitmapOperation(TInt aOpCode) const;
	inline TBool IsWsBitmapOperation(TInt aOpCode) const;
	inline TBool IsRemoteReadRequired(TInt aOpCode) const;
	inline TBool IsWsFontOperation(TInt aOpCode) const;
	inline TBool IsDrawWsGraphicOperation(TInt aOpCode) const;
	inline TBool IsWsDrawableSourceOperation(TInt aOpCode) const;
	void ReplaceAndAppendCommandL(TInt aOpcode,const TAny* aCmdData);
	// CRedrawSegment related methods
	inline TInt CurrentCommandBufferWritePos() const;
	inline CBufSeg* CurrentDrawCommandBuffer() const;
	void ExpandCommandBufferL(TInt aLength);
	void CommandBufferWrite(const TDesC8& aDes, TInt aLength);
	void CommandBufferWrite(const TAny* aPtr,TInt aLength);
	void CreateNewSegmentL(const TRect& aRect, TRedrawSegmentType aRegionType);
	inline TBool InRedraw() const;
	void PromotePendingSegment();
	void Lock();
	void Unlock();
	void ReleaseRedrawSegments();
private:
	static TBool iAtomic;
	RPointerArray<CFbsBitmapRef> iFbsBitmapRefArray;
private:
	class CRedrawSegment : public CBase
		{
	public:
		static CRedrawSegment* NewLC(const TRect& aRect, TRedrawSegmentType aNewRegionType, CWsRedrawMsgWindow& aRedraw);
		~CRedrawSegment();
		void AddWsBitmapL(DWsBitmap* bitmap);
		void AddWsDrawableSourceL(CWsDrawableSource* aDrawableSource);
		void AddDrawerL(TGraphicDrawerId aDrawerId);
		TBool ContainsDrawers(const TArray<TGraphicDrawerId>& aDrawers,const TRegion& aRegion) const;
		TInt SizeInBytes() const;
		TBool AppendNonDuplicateBitmapHandleL(TInt aHandle);
	private:
		CRedrawSegment(CWsRedrawMsgWindow& aRedraw);
		void ConstructL(const TRect& aRect, TRedrawSegmentType aNewRegionType);
		void ReleaseFontsBitmapsDrawableSources();
	public:
		TRedrawSegmentType iRedrawSegmentType;
		CBufSeg* iDrawCommands;
		TInt iCurrentCommandBufferWritePos;
		RWsRegion iRegion;
		RPointerArray<DWsBitmap> iWsBitmapArray;
		RPointerArray<CWsFbsFont> iWsFontArray;
		RArray<TGraphicDrawerId> iDrawerArray;
		RPointerArray<CWsDrawableSource> iWsDrawableSourceArray;
		TTime iCreationTime;
	private:
	    CWsRedrawMsgWindow& iRedraw;
	    RArray<TInt> iBitmapHandleArray;
		};
	RWsRegion iInvalid; // Region we haven't been sent a begin redraw for.
	TRect iRedrawRect;
	TRgb iBackColor;
	TInt iFlags;
	// Regions currently in use for drawing this window:
	RPointerArray<CRedrawSegment> iRedrawSegments;
	// The segment we are currently storing to.  This is allowed to be null!
	CRedrawSegment * iCurrentSegment;
	// The last GC we drew with so we can detect changes
	CWsGc* iLastDrawGc;
	// During a scheduled draw, this is the area being drawn to (see comments on ReadRegion)
	RWsRegion iLocalRedrawRegion;
	TInt iMemoryLock;
	TBool iOSBStatus;
	};

inline TBool CWsRedrawMsgWindow::IsRemoteReadRequired(TInt aOpCode) const
	{
	return (aOpCode==EWsGcOpDrawTextPtr || aOpCode==EWsGcOpDrawTextVerticalPtr || 
		aOpCode==EWsGcOpDrawBoxTextPtr || aOpCode==EWsGcOpDrawBoxTextVerticalPtr);
	}

inline TInt CWsRedrawMsgWindow::CurrentCommandBufferWritePos() const
	{
	WS_ASSERT_DEBUG(iCurrentSegment, EWsPanicDrawCommandsInvalidState);
	return iCurrentSegment->iCurrentCommandBufferWritePos;
	}

inline CBufSeg* CWsRedrawMsgWindow::CurrentDrawCommandBuffer() const
	{
	WS_ASSERT_DEBUG(iCurrentSegment, EWsPanicDrawCommandsInvalidState);
	return iCurrentSegment->iDrawCommands;
	}

inline TBool CWsRedrawMsgWindow::InRedraw() const
	{
	return iFlags&EBeginEndRedraw;
	}
	
inline TInt CFbsBitmapRef::RefCount() const
    {
    return iRefCount;
    }

inline void CFbsBitmapRef::IncRefCount()
    {
    ++iRefCount;
    }

inline void CFbsBitmapRef::DecRefCount()
    {
    WS_ASSERT_DEBUG(iRefCount>0,EWsPanicCounterValue);
    --iRefCount;
    }
	
#endif