[Date Prev][Date Next][Thread Prev][Thread Next][Thread Index]

[XaraXtreme-commits] Commit Complete



Commit by  : alex
Repository : xara
Revision   : 1323
Date       : Wed Jun 14 19:52:46 BST 2006

Changed paths:
   M /Trunk/XaraLX/Kernel/docview.cpp
   M /Trunk/XaraLX/Kernel/rndrgn.cpp
   M /Trunk/XaraLX/Kernel/view.cpp
   M /Trunk/XaraLX/Kernel/view.h
   M /Trunk/XaraLX/wxOil/camview.cpp
   M /Trunk/XaraLX/wxOil/camview.h
   M /Trunk/XaraLX/wxOil/rendwnd.cpp
   M /Trunk/XaraLX/wxOil/rendwnd.h

Implement lazy DC deletion with locking


Diff:
Index: Trunk/XaraLX/Kernel/docview.cpp
===================================================================
--- Trunk/XaraLX/Kernel/docview.cpp	(revision 1322)
+++ Trunk/XaraLX/Kernel/docview.cpp	(revision 1323)
@@ -2527,6 +2527,9 @@
 	// find type of rendering device
 	CCamView *pCamView = GetConnectionToOilView();
 	ERROR2IF(pCamView == NULL, (void)0, "DocView::ForceRedraw: DocView has no CamView");
+
+	pCamView->AllocateDC(); // allocate a DC
+
 	CNativeDC* pDevContext = pCamView->GetRenderDC();
 	const RenderType rType = CCDC::GetType(pDevContext, TRUE);
 
@@ -2596,6 +2599,8 @@
 			}
 		}
 	}
+
+	pCamView->DoneWithDC(); // deallocate a DC
 }
 
 
@@ -3869,6 +3874,8 @@
 		}
 
 		CNativeDC* pDC = pViewWindow->GetRenderDC();
+		ERROR3IF(!pDC, "No allocated DC");
+
 		RenderRegion *NewRegion =	View::NewRenderRegion(SpreadClipRect, RenderMatrix, 
 									pDC, pSpread, rType);
 
Index: Trunk/XaraLX/Kernel/view.h
===================================================================
--- Trunk/XaraLX/Kernel/view.h	(revision 1322)
+++ Trunk/XaraLX/Kernel/view.h	(revision 1323)
@@ -276,6 +276,7 @@
 									BOOL fDeleteRegionAfter = TRUE,
 									BOOL bForceImmediate = FALSE) = 0;
 	virtual wxDC* GetRenderDC() = 0;
+	virtual void AllocateDC();
 	virtual void DoneWithDC();
 	virtual BOOL RenderTreeCallback(Node* pNode, RenderRegion* pRender) {return TRUE;}
 
Index: Trunk/XaraLX/Kernel/rndrgn.cpp
===================================================================
--- Trunk/XaraLX/Kernel/rndrgn.cpp	(revision 1322)
+++ Trunk/XaraLX/Kernel/rndrgn.cpp	(revision 1323)
@@ -659,11 +659,7 @@
 		pCapture = GetTopCapture();
 	}
 
-	if (RenderView)
-	{
-		RenderView->DoneWithDC(); // hint that we might like to drop this DC so a fresh one will be created
-	}
-	
+
 	if( m_fOwned )
 	{
 		delete RenderDC;
@@ -1127,12 +1123,17 @@
 
 	if (RenderView)
 	{
+		RenderView->AllocateDC();
 		RenderDC = RenderView->GetRenderDC();
 		if (RenderDC)
 		{
+			View * pView = RenderView; // as ContinueRenderView can delete the RenderRegion (i.e. "this").
    			RenderView->SetCurrent();
 			(RenderView->GetDoc())->SetCurrent();
 			RenderView->ContinueRenderView(this, RenderSpread, TRUE, TRUE, bForceImmediate);
+
+			// This MUST pair with AllocateDC
+			pView->DoneWithDC(); // hint that we might like to drop this DC so a fresh one will be created
 		}
 		else
 		{
@@ -1140,9 +1141,7 @@
 //			Error::SetError(_R(IDT_INTERNAL_ERROR), 0);
 //			InformError();
 			TRACE(_T("Failed to get a DC for rendering in RenderRegion::DefaultRender
"));
-			return;
 		}
-
 	}
 }
 
Index: Trunk/XaraLX/Kernel/view.cpp
===================================================================
--- Trunk/XaraLX/Kernel/view.cpp	(revision 1322)
+++ Trunk/XaraLX/Kernel/view.cpp	(revision 1323)
@@ -249,6 +249,25 @@
 
 /********************************************************************************************
 
+>	void View::AllocateDC()
+
+	Author:		Alex Bligh <alex@xxxxxxxxxxx>
+	Created:	12/06/2006
+	Purpose:	Hints that we've done with our DC
+	SeeAlso:	View; PaperRenderRegion.
+
+Note this is merely a hint. This routine is not guaranteed to eb called
+
+********************************************************************************************/
+
+void View::AllocateDC()
+{
+	if (pViewWindow)
+		pViewWindow->AllocateDC();
+}
+
+/********************************************************************************************
+
 >	void View::DoneWithDC()
 
 	Author:		Alex Bligh <alex@xxxxxxxxxxx>
Index: Trunk/XaraLX/wxOil/rendwnd.cpp
===================================================================
--- Trunk/XaraLX/wxOil/rendwnd.cpp	(revision 1322)
+++ Trunk/XaraLX/wxOil/rendwnd.cpp	(revision 1323)
@@ -144,6 +144,7 @@
 	EVT_KEY_DOWN(			CRenderWnd::OnKey)
 	EVT_KEY_UP(				CRenderWnd::OnKey)
 	EVT_CHAR(				CRenderWnd::OnChar)
+	EVT_IDLE(				CRenderWnd::OnIdle)
 	
 #if defined(__WXGTK__)
 	EVT_ENTER_WINDOW(		CRenderWnd::OnEnter )
@@ -156,20 +157,54 @@
 CRenderWnd::CRenderWnd(CCamView* pView) :
 	m_pView(pView), m_pCCClientDC(NULL)
 {
+	m_DCUsers=0;
 	// Nothing else to do for now...
 }
 
 CRenderWnd::~CRenderWnd()
 {
 	TRACEUSER("Gerry", _T("Deleting CRenderWnd at 0x%08x
"), this);
-	if (m_pCCClientDC)
+	if (m_DCUsers)
 	{
-		delete(m_pCCClientDC);
-		m_pCCClientDC = NULL;
+		ERROR3("CRenderWnd::~CRenderWnd non-zero DC user count - leaking a DC");
 	}
+	else
+	{
+		if (m_pCCClientDC)
+		{
+			delete(m_pCCClientDC);
+			m_pCCClientDC = NULL;
+		}
+	}
 }
 
 /*********************************************************************************************
+>	virtual void CRenderWnd::AllocateDC(BOOL KeepIt=TRUE)
+
+	Author:		Alex Bligh <alex@xxxxxxxxxxx>
+	Created:	12/06/2006
+	Inputs:		None
+	Outputs:	None
+	Returns:	Pointer to the CCClientDC
+	Purpose:	Returns a pointer to the appropriate client DC, allocating it if necessary
+	Errors:		-
+	Scope:	    Public
+	SeeAlso:    CCamView::OnCreate()
+
+**********************************************************************************************/ 
+
+void CRenderWnd::AllocateDC(BOOL KeepIt/*=TRUE*/)
+{
+	ERROR3IF((m_DCUsers && !m_pCCClientDC), "We have users, but no client DC");
+	if (!m_pCCClientDC)
+		m_pCCClientDC = new CCClientDC(this); // OK if it fails
+	
+	if (KeepIt)
+		m_DCUsers++;
+	return;
+}
+
+/*********************************************************************************************
 >	virtual wxClientDC * CRenderWnd::GetClientDC()
 
 	Author:		Alex Bligh <alex@xxxxxxxxxxx>
@@ -187,15 +222,13 @@
 wxClientDC * CRenderWnd::GetClientDC()
 {
 	if (!m_pCCClientDC)
-		m_pCCClientDC = new CCClientDC(this); // OK if it fails
+		AllocateDC(FALSE);
 	return (wxClientDC*)(m_pCCClientDC?m_pCCClientDC->GetDC():NULL);
 }
 
 /*********************************************************************************************
->	virtual wxClientDC * CRenderWnd::GetClientDC()
+>	void CRenderWnd::DoneWithDC()
 
->	void CCamView::DoneWithDC()
-
 	Author:		Alex Bligh <alex@xxxxxxxxxxx>
 	Created:	12/06/2006
 	Purpose:	Hints that we've done with our DC
@@ -207,7 +240,30 @@
 
 void CRenderWnd::DoneWithDC()
 {
-	if (m_pCCClientDC)
+	ERROR3IF((m_DCUsers<=0), "We have no users, but I'm being told I'm done with");
+
+	if (m_DCUsers>0)
+		m_DCUsers--;
+
+	// Note we use a lazy-destroy from our idle handler
+}
+
+/*********************************************************************************************
+>	void CRenderWnd::OnIdle()
+
+	Author:		Alex Bligh <alex@xxxxxxxxxxx>
+	Created:	12/06/2006
+	Purpose:	Laze deletion of our client DC on idle
+	SeeAlso:	View; PaperRenderRegion.
+
+We appear to need to create and delete DCs or rendering into the first RenderWindow doesn't
+work. Who knows why.
+
+**********************************************************************************************/ 
+
+void CRenderWnd::OnIdle(wxIdleEvent &event)
+{
+	if ((m_DCUsers<=0) && m_pCCClientDC)
 	{
 		delete m_pCCClientDC;
 		m_pCCClientDC=NULL;
@@ -236,6 +292,7 @@
 						wxWindow *pParent, UINT32 id)
 {
 	BOOL ok=wxWindow::Create(pParent, id, rect.GetTopLeft(), rect.GetSize(), wxNO_FULL_REPAINT_ON_RESIZE);
+	SetExtraStyle(wxWS_EX_PROCESS_IDLE);
 #if defined(__WXGTK__)
 	::SetDoubleBuffer(this, m_DoubleBuffer);
 #endif
Index: Trunk/XaraLX/wxOil/rendwnd.h
===================================================================
--- Trunk/XaraLX/wxOil/rendwnd.h	(revision 1322)
+++ Trunk/XaraLX/wxOil/rendwnd.h	(revision 1323)
@@ -145,6 +145,7 @@
 	static BOOL GetDoubleBuffer () {return m_DoubleBuffer;}
 
 	virtual wxClientDC * GetClientDC();
+	virtual void AllocateDC(BOOL KeepIt=TRUE);
 	virtual void DoneWithDC();
 
 /////////////////////////////////////////////////////////////////////////////
@@ -176,6 +177,7 @@
 
 	void OnKey ( wxKeyEvent & event);
 	void OnChar( wxKeyEvent& event );
+	void OnIdle( wxIdleEvent& event );
 
 protected:
 	CCamView* m_pView;
@@ -183,6 +185,8 @@
 	static BOOL m_DoubleBuffer;
 	static void ReflectDoubleBufferingInChildren(wxWindow * pWindow);
 
+	INT32 m_DCUsers;
+
 	DECLARE_EVENT_TABLE()
 
 	CCClientDC * m_pCCClientDC;
Index: Trunk/XaraLX/wxOil/camview.h
===================================================================
--- Trunk/XaraLX/wxOil/camview.h	(revision 1322)
+++ Trunk/XaraLX/wxOil/camview.h	(revision 1323)
@@ -199,6 +199,7 @@
 
 public:
 	virtual CNativeDC *GetRenderDC() const;
+	virtual void AllocateDC() const;
 	virtual void DoneWithDC() const;
 	void GetClientSize(/* TYPENOTE: Correct */ int * width, /*TYPENOTE: Correct */ int * height) const;
 	
Index: Trunk/XaraLX/wxOil/camview.cpp
===================================================================
--- Trunk/XaraLX/wxOil/camview.cpp	(revision 1322)
+++ Trunk/XaraLX/wxOil/camview.cpp	(revision 1323)
@@ -651,6 +651,26 @@
 		RenderWindow->DoneWithDC();
 }
 
+/********************************************************************************************
+
+>	void CCamView::AllocateDC()
+
+	Author:		Alex Bligh <alex@xxxxxxxxxxx>
+	Created:	12/06/2006
+	Purpose:	Hints that we've done with our DC
+	SeeAlso:	View; PaperRenderRegion.
+
+Note this is merely a hint. This routine is not guaranteed to eb called
+
+********************************************************************************************/
+
+void CCamView::AllocateDC() const
+{
+	if (RenderWindow)
+		RenderWindow->AllocateDC();
+}
+
+
 /*********************************************************************************************
 >	void CCamView::GetClientSize(int * pWidth, int * pHeight) const    TYPENOTE: Correct
 


Xara