Cache wxDisplayImpl object for faster access

Avoid a heap allocation on every wxDisplay creation by caching the
wxDisplayImpl objects once they're created.

Currently we never invalidate the cache, but we should add a way to do
it in the future.

This speeds up wxDisplay::GetGeometry() benchmark by a factor of 4.
This commit is contained in:
Vadim Zeitlin 2018-09-30 00:53:59 +02:00
parent d6793893c0
commit 990c8bfd73
3 changed files with 36 additions and 12 deletions

View File

@ -50,7 +50,6 @@ public:
// dtor is not virtual as this is a concrete class not meant to be derived
// from
~wxDisplay();
// return the number of available displays, valid parameters to

View File

@ -11,6 +11,7 @@
#define _WX_PRIVATE_DISPLAY_H_
#include "wx/gdicmn.h" // for wxRect
#include "wx/vector.h"
// ----------------------------------------------------------------------------
// wxDisplayFactory: allows to create wxDisplay objects
@ -20,12 +21,20 @@ class WXDLLIMPEXP_CORE wxDisplayFactory
{
public:
wxDisplayFactory() { }
virtual ~wxDisplayFactory() { }
virtual ~wxDisplayFactory();
// create a new display object
//
// it can return a NULL pointer if the display creation failed
virtual wxDisplayImpl *CreateDisplay(unsigned n) = 0;
// Create the display if necessary using CreateDisplay(), otherwise just
// get it from cache.
wxDisplayImpl* GetDisplay(unsigned n)
{
if ( m_impls.empty() )
m_impls.resize(GetCount());
else if ( m_impls[n] )
return m_impls[n];
m_impls[n] = CreateDisplay(n);
return m_impls[n];
}
// get the total number of displays
virtual unsigned GetCount() = 0;
@ -37,6 +46,18 @@ public:
//
// the window pointer must not be NULL (i.e. caller should check it)
virtual int GetFromWindow(const wxWindow *window);
protected:
// create a new display object
//
// it can return a NULL pointer if the display creation failed
virtual wxDisplayImpl *CreateDisplay(unsigned n) = 0;
private:
// On-demand populated vector of wxDisplayImpl objects.
wxVector<wxDisplayImpl*> m_impls;
wxDECLARE_NO_COPY_CLASS(wxDisplayFactory);
};
// ----------------------------------------------------------------------------

View File

@ -118,12 +118,7 @@ wxDisplay::wxDisplay(unsigned n)
wxASSERT_MSG( n == 0 || n < GetCount(),
wxT("An invalid index was passed to wxDisplay") );
m_impl = Factory().CreateDisplay(n);
}
wxDisplay::~wxDisplay()
{
delete m_impl;
m_impl = Factory().GetDisplay(n);
}
// ----------------------------------------------------------------------------
@ -230,6 +225,15 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode)
// wxDisplayFactory implementation
// ============================================================================
wxDisplayFactory::~wxDisplayFactory()
{
for ( size_t n = 0; n < m_impls.size(); ++n )
{
// It can be null, that's ok.
delete m_impls[n];
}
}
int wxDisplayFactory::GetFromWindow(const wxWindow *window)
{
// consider that the window belongs to the display containing its centre