[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