summaryrefslogtreecommitdiff
path: root/vcl/win/gdi/salbmp.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/win/gdi/salbmp.cxx')
-rw-r--r--vcl/win/gdi/salbmp.cxx233
1 files changed, 72 insertions, 161 deletions
diff --git a/vcl/win/gdi/salbmp.cxx b/vcl/win/gdi/salbmp.cxx
index cc3a051c0dd5..8f378e23c15c 100644
--- a/vcl/win/gdi/salbmp.cxx
+++ b/vcl/win/gdi/salbmp.cxx
@@ -59,136 +59,12 @@ inline void ImplSetPixel4( sal_uInt8* pScanline, long nX, const BYTE cIndex )
}
}
-// Helper class to manage Gdiplus::Bitmap instances inside of
-// WinSalBitmap
-
-struct Comparator
-{
- bool operator()(WinSalBitmap* pA, WinSalBitmap* pB) const
- {
- return pA < pB;
- }
-};
-
-typedef ::std::map< WinSalBitmap*, sal_uInt32, Comparator > EntryMap;
-static const sal_uInt32 nDefaultCycles(60);
-
-class GdiPlusBuffer : protected comphelper::OBaseMutex, public Timer
-{
-private:
- EntryMap maEntries;
-
-public:
- GdiPlusBuffer( const sal_Char *pDebugName )
- : Timer( pDebugName ),
- maEntries()
- {
- SetTimeout(1000);
- Stop();
- }
-
- ~GdiPlusBuffer()
- {
- Stop();
- }
-
- void addEntry(WinSalBitmap& rEntry)
- {
- ::osl::MutexGuard aGuard(m_aMutex);
- EntryMap::iterator aFound = maEntries.find(&rEntry);
-
- if(aFound == maEntries.end())
- {
- if(maEntries.empty())
- {
- Start();
- }
-
- maEntries[&rEntry] = nDefaultCycles;
- }
- }
-
- void remEntry(WinSalBitmap& rEntry)
- {
- ::osl::MutexGuard aGuard(m_aMutex);
- EntryMap::iterator aFound = maEntries.find(&rEntry);
-
- if(aFound != maEntries.end())
- {
- maEntries.erase(aFound);
-
- if(maEntries.empty())
- {
- Stop();
- }
- }
- }
-
- void touchEntry(WinSalBitmap& rEntry)
- {
- ::osl::MutexGuard aGuard(m_aMutex);
- EntryMap::iterator aFound = maEntries.find(&rEntry);
-
- if(aFound != maEntries.end())
- {
- aFound->second = nDefaultCycles;
- }
- }
-
- // from parent Timer
- virtual void Invoke()
- {
- ::osl::MutexGuard aGuard(m_aMutex);
- EntryMap::iterator aIter(maEntries.begin());
-
- while(aIter != maEntries.end())
- {
- if(aIter->second)
- {
- aIter->second--;
- ++aIter;
- }
- else
- {
- EntryMap::iterator aDelete(aIter);
- WinSalBitmap* pSource = aDelete->first;
- ++aIter;
- maEntries.erase(aDelete);
-
- if(maEntries.empty())
- {
- Stop();
- }
-
- // delete at WinSalBitmap after entry is removed; this
- // way it would not hurt to call remEntry from there, too
- if(pSource->maGdiPlusBitmap.get())
- {
- pSource->maGdiPlusBitmap.reset();
- pSource->mpAssociatedAlpha = 0;
- }
- }
- }
-
- if(!maEntries.empty())
- {
- Start();
- }
- }
-};
-
-// Global instance of GdiPlusBuffer which manages Gdiplus::Bitmap
-// instances
-
-static GdiPlusBuffer aGdiPlusBuffer( "vcl::win GdiPlusBuffer aGdiPlusBuffer" );
-
-
WinSalBitmap::WinSalBitmap()
-: maSize(),
- mhDIB(0),
- mhDDB(0),
- maGdiPlusBitmap(),
- mpAssociatedAlpha(0),
+: SalBitmap(),
+ basegfx::SystemDependentDataHolder(),
+ maSize(),
+ mhDIB(nullptr),
+ mhDDB(nullptr),
mnBitCount(0)
{
}
@@ -200,11 +76,6 @@ WinSalBitmap::~WinSalBitmap()
void WinSalBitmap::Destroy()
{
- if(maGdiPlusBitmap.get())
- {
- aGdiPlusBuffer.remEntry(*this);
- }
-
if( mhDIB )
GlobalFree( mhDIB );
else if( mhDDB )
@@ -214,45 +85,85 @@ void WinSalBitmap::Destroy()
mnBitCount = 0;
}
-GdiPlusBmpPtr WinSalBitmap::ImplGetGdiPlusBitmap(const WinSalBitmap* pAlphaSource) const
+class SystemDependentData_GdiPlusBitmap : public basegfx::SystemDependentData
{
- WinSalBitmap* pThat = const_cast< WinSalBitmap* >(this);
+private:
+ std::shared_ptr<Gdiplus::Bitmap> mpGdiPlusBitmap;
+ const WinSalBitmap* mpAssociatedAlpha;
+
+public:
+ SystemDependentData_GdiPlusBitmap(
+ basegfx::SystemDependentDataManager& rSystemDependentDataManager);
+ virtual ~SystemDependentData_GdiPlusBitmap() override;
+
+ const WinSalBitmap* getAssociatedAlpha() const { return mpAssociatedAlpha; }
+ void setAssociatedAlpha(const WinSalBitmap* pNew) { mpAssociatedAlpha = pNew; }
+
+ const std::shared_ptr<Gdiplus::Bitmap>& getGdiPlusBitmap() const { return mpGdiPlusBitmap; }
+ void setGdiPlusBitmap(const std::shared_ptr<Gdiplus::Bitmap>& rNew) { mpGdiPlusBitmap = rNew; }
+};
- if(maGdiPlusBitmap.get() && pAlphaSource != mpAssociatedAlpha)
+SystemDependentData_GdiPlusBitmap::SystemDependentData_GdiPlusBitmap(
+ basegfx::SystemDependentDataManager& rSystemDependentDataManager)
+: basegfx::SystemDependentData(rSystemDependentDataManager),
+ mpGdiPlusBitmap(),
+ mpAssociatedAlpha(nullptr)
+{
+}
+
+SystemDependentData_GdiPlusBitmap::~SystemDependentData_GdiPlusBitmap()
+{
+}
+
+std::shared_ptr< Gdiplus::Bitmap > WinSalBitmap::ImplGetGdiPlusBitmap(const WinSalBitmap* pAlphaSource) const
+{
+ std::shared_ptr< Gdiplus::Bitmap > aRetval;
+
+ // try to access buffered data
+ std::shared_ptr<SystemDependentData_GdiPlusBitmap> pSystemDependentData_GdiPlusBitmap(
+ getSystemDependentData<SystemDependentData_GdiPlusBitmap>());
+
+ if(pSystemDependentData_GdiPlusBitmap)
{
- // #122350# if associated alpha with which the GDIPlus was constructed has changed
- // it is necessary to remove it from buffer, reset reference to it and reconstruct
- pThat->maGdiPlusBitmap.reset();
- aGdiPlusBuffer.remEntry(const_cast< WinSalBitmap& >(*this));
+ // check data validity
+ if(pSystemDependentData_GdiPlusBitmap->getAssociatedAlpha() != pAlphaSource
+ || 0 == maSize.Width()
+ || 0 == maSize.Height())
+ {
+ // #122350# if associated alpha with which the GDIPlus was constructed has changed
+ // it is necessary to remove it from buffer, reset reference to it and reconstruct
+ // data invalid, forget
+ pSystemDependentData_GdiPlusBitmap.reset();
+ }
}
- if(maGdiPlusBitmap.get())
+ if(pSystemDependentData_GdiPlusBitmap)
{
- aGdiPlusBuffer.touchEntry(const_cast< WinSalBitmap& >(*this));
+ // use from buffer
+ aRetval = pSystemDependentData_GdiPlusBitmap->getGdiPlusBitmap();
}
- else
+ else if(maSize.Width() > 0 && maSize.Height() > 0)
{
- if(maSize.Width() > 0 && maSize.Height() > 0)
- {
- if(pAlphaSource)
- {
- pThat->maGdiPlusBitmap.reset(pThat->ImplCreateGdiPlusBitmap(*pAlphaSource));
- pThat->mpAssociatedAlpha = pAlphaSource;
- }
- else
- {
- pThat->maGdiPlusBitmap.reset(pThat->ImplCreateGdiPlusBitmap());
- pThat->mpAssociatedAlpha = 0;
- }
+ // add to buffering mechanism
+ pSystemDependentData_GdiPlusBitmap = addOrReplaceSystemDependentData<SystemDependentData_GdiPlusBitmap>(
+ SalGraphics::getSystemDependentDataManager());
- if(maGdiPlusBitmap.get())
- {
- aGdiPlusBuffer.addEntry(*pThat);
- }
+ // create and set data
+ if(pAlphaSource)
+ {
+ aRetval.reset(const_cast< WinSalBitmap* >(this)->ImplCreateGdiPlusBitmap(*pAlphaSource));
+ pSystemDependentData_GdiPlusBitmap->setGdiPlusBitmap(aRetval);
+ pSystemDependentData_GdiPlusBitmap->setAssociatedAlpha(pAlphaSource);
+ }
+ else
+ {
+ aRetval.reset(const_cast< WinSalBitmap* >(this)->ImplCreateGdiPlusBitmap());
+ pSystemDependentData_GdiPlusBitmap->setGdiPlusBitmap(aRetval);
+ pSystemDependentData_GdiPlusBitmap->setAssociatedAlpha(nullptr);
}
}
- return maGdiPlusBitmap;
+ return aRetval;
}
Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap()