Add caching of clipping box values for Direct2D graphics context

Since retrieving actual clipping box is an expensive operation so to improve performance of wxD2DContext::GetClipBox() we need to store just retrieved clipping box data in the cache. These stored data will be then used in the forthcoming requests for clipping box values. Cached clipping box data are invalidated whenever clipping region is explicitly set using Clip()/ResetClip() or whenever transformation matrix is changed (to take into account new coordinates). If there is a call for clipping box (with GetClipBox) and cached data are marked as invalid then clipping box is retrieved/recalculated and stored in the cache.
This commit is contained in:
Artur Wieczorek
2016-09-01 21:23:08 +02:00
parent ba4b8d5670
commit 588425a9d4

View File

@@ -54,6 +54,8 @@
#pragma hdrstop #pragma hdrstop
#endif #endif
#include <float.h> // for FLT_MAX, FLT_MIN
#ifndef WX_PRECOMP #ifndef WX_PRECOMP
#include "wx/dc.h" #include "wx/dc.h"
#include "wx/dcclient.h" #include "wx/dcclient.h"
@@ -62,7 +64,6 @@
#include "wx/module.h" #include "wx/module.h"
#include "wx/window.h" #include "wx/window.h"
#include "wx/msw/private.h" #include "wx/msw/private.h"
#include <float.h> // for FLT_MAX
#endif // !WX_PRECOMP #endif // !WX_PRECOMP
#include "wx/graphics.h" #include "wx/graphics.h"
@@ -3442,16 +3443,15 @@ private:
private: private:
ID2D1Factory* m_direct2dFactory; ID2D1Factory* m_direct2dFactory;
wxSharedPtr<wxD2DRenderTargetResourceHolder> m_renderTargetHolder; wxSharedPtr<wxD2DRenderTargetResourceHolder> m_renderTargetHolder;
wxStack<StateData> m_stateStack; wxStack<StateData> m_stateStack;
wxStack<LayerData> m_layers; wxStack<LayerData> m_layers;
ID2D1RenderTarget* m_cachedRenderTarget; ID2D1RenderTarget* m_cachedRenderTarget;
D2D1::Matrix3x2F m_initTransform; D2D1::Matrix3x2F m_initTransform;
// Clipping box
bool m_isClipBoxValid;
double m_clipX1, m_clipY1, m_clipX2, m_clipY2;
private: private:
wxDECLARE_NO_COPY_CLASS(wxD2DContext); wxDECLARE_NO_COPY_CLASS(wxD2DContext);
}; };
@@ -3510,6 +3510,8 @@ void wxD2DContext::Init()
m_composition = wxCOMPOSITION_OVER; m_composition = wxCOMPOSITION_OVER;
m_renderTargetHolder->Bind(this); m_renderTargetHolder->Bind(this);
m_enableOffset = true; m_enableOffset = true;
m_isClipBoxValid = false;
m_clipX1 = m_clipY1 = m_clipX2 = m_clipY2 = 0.0;
EnsureInitialized(); EnsureInitialized();
} }
@@ -3575,6 +3577,8 @@ void wxD2DContext::SetClipLayer(ID2D1Geometry* clipGeometry)
GetRenderTarget()->PushLayer(ld.params, clipLayer); GetRenderTarget()->PushLayer(ld.params, clipLayer);
// Store layer parameters. // Store layer parameters.
m_layers.push(ld); m_layers.push(ld);
m_isClipBoxValid = false;
} }
void wxD2DContext::ResetClip() void wxD2DContext::ResetClip()
@@ -3619,10 +3623,14 @@ void wxD2DContext::ResetClip()
} }
// Restore current transformation matrix. // Restore current transformation matrix.
GetRenderTarget()->SetTransform(&currTransform); GetRenderTarget()->SetTransform(&currTransform);
m_isClipBoxValid = false;
} }
void wxD2DContext::GetClipBox(wxDouble* x, wxDouble* y, wxDouble* w, wxDouble* h) void wxD2DContext::GetClipBox(wxDouble* x, wxDouble* y, wxDouble* w, wxDouble* h)
{ {
if ( !m_isClipBoxValid )
{
// To obtain actual clipping box we have to start with rectangle // To obtain actual clipping box we have to start with rectangle
// covering the entire render target and interesect with this rectangle // covering the entire render target and interesect with this rectangle
// all clipping layers. Bounding box of the final geometry // all clipping layers. Bounding box of the final geometry
@@ -3707,14 +3715,21 @@ void wxD2DContext::GetClipBox(wxDouble* x, wxDouble* y, wxDouble* w, wxDouble* h
wxCHECK_HRESULT_RET(hr); wxCHECK_HRESULT_RET(hr);
} }
m_clipX1 = bounds.left;
m_clipY1 = bounds.top;
m_clipX2 = bounds.right;
m_clipY2 = bounds.bottom;
m_isClipBoxValid = true;
}
if ( x ) if ( x )
*x = bounds.left; *x = m_clipX1;
if ( y ) if ( y )
*y = bounds.top; *y = m_clipY1;
if ( w ) if ( w )
*w = (double)bounds.right - bounds.left; *w = m_clipX2 - m_clipX1;
if ( h ) if ( h )
*h = (double)bounds.bottom - bounds.top; *h = m_clipY2 - m_clipY1;
} }
void* wxD2DContext::GetNativeContext() void* wxD2DContext::GetNativeContext()
@@ -3924,6 +3939,8 @@ void wxD2DContext::SetTransform(const wxGraphicsMatrix& matrix)
D2D1::Matrix3x2F m; D2D1::Matrix3x2F m;
m.SetProduct(wxGetD2DMatrixData(matrix)->GetMatrix3x2F(), m_initTransform); m.SetProduct(wxGetD2DMatrixData(matrix)->GetMatrix3x2F(), m_initTransform);
GetRenderTarget()->SetTransform(&m); GetRenderTarget()->SetTransform(&m);
m_isClipBoxValid = false;
} }
wxGraphicsMatrix wxD2DContext::GetTransform() const wxGraphicsMatrix wxD2DContext::GetTransform() const
@@ -4043,6 +4060,8 @@ void wxD2DContext::PopState()
// Restore drawing state. // Restore drawing state.
GetRenderTarget()->RestoreDrawingState(state.drawingState); GetRenderTarget()->RestoreDrawingState(state.drawingState);
m_isClipBoxValid = false;
} }
void wxD2DContext::GetTextExtent( void wxD2DContext::GetTextExtent(