Author: alg
Date: Tue Jan 10 12:44:03 2012
New Revision: 1229521
URL: http://svn.apache.org/viewvc?rev=1229521&view=rev
Log:
#16758# Added buffering to the VDev usages of the VclProcessor2D derivates
(VclMetafileProcessor2D and VclPixelProcessor2D)
Modified:
incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx
Modified:
incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
URL:
http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx?rev=1229521&r1=1229520&r2=1229521&view=diff
==============================================================================
---
incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
(original)
+++
incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
Tue Jan 10 12:44:03 2012
@@ -29,149 +29,328 @@
#include <vcl/bitmapex.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <tools/stream.hxx>
+#include <vcl/timer.hxx>
+#include <comphelper/broadcasthelper.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+// buffered VDev usage
+
+namespace
+{
+ typedef ::std::vector< VirtualDevice* > aBuffers;
+
+ class VDevBuffer : public Timer, protected comphelper::OBaseMutex
+ {
+ private:
+ aBuffers maBuffers;
+
+ public:
+ VDevBuffer();
+ virtual ~VDevBuffer();
+
+ VirtualDevice* alloc(OutputDevice& rOutDev, const Size& rSizePixel,
bool bClear, bool bMono);
+ void free(VirtualDevice& rDevice);
+
+ // Timer virtuals
+ virtual void Timeout();
+ };
+
+ VDevBuffer::VDevBuffer()
+ : Timer(),
+ maBuffers()
+ {
+ SetTimeout(10L * 1000L); // ten seconds
+ }
+
+ VDevBuffer::~VDevBuffer()
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ Stop();
+
+ while(!maBuffers.empty())
+ {
+ delete *(maBuffers.end() - 1);
+ maBuffers.pop_back();
+ }
+ }
+
+ VirtualDevice* VDevBuffer::alloc(OutputDevice& rOutDev, const Size&
rSizePixel, bool bClear, bool bMono)
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ VirtualDevice* pRetval = 0;
+
+ if(!maBuffers.empty())
+ {
+ bool bOkay(false);
+ aBuffers::iterator aFound(maBuffers.end());
+
+ for(aBuffers::iterator a(maBuffers.begin()); a != maBuffers.end();
a++)
+ {
+ OSL_ENSURE(*a, "Empty pointer in VDevBuffer (!)");
+
+ if((bMono && 1 == (*a)->GetBitCount()) || (!bMono &&
(*a)->GetBitCount() > 1))
+ {
+ // candidate is valid due to bit depth
+ if(aFound != maBuffers.end())
+ {
+ // already found
+ if(bOkay)
+ {
+ // found is valid
+ const bool
bCandidateOkay((*a)->GetOutputWidthPixel() >= rSizePixel.getWidth() &&
(*a)->GetOutputHeightPixel() >= rSizePixel.getHeight());
+
+ if(bCandidateOkay)
+ {
+ // found and candidate are valid
+ const sal_uLong
aSquare((*aFound)->GetOutputWidthPixel() * (*aFound)->GetOutputHeightPixel());
+ const sal_uLong
aCandidateSquare((*a)->GetOutputWidthPixel() * (*a)->GetOutputHeightPixel());
+
+ if(aCandidateSquare < aSquare)
+ {
+ // candidate is valid and smaller, use it
+ aFound = a;
+ }
+ }
+ else
+ {
+ // found is valid, candidate is not. Keep found
+ }
+ }
+ else
+ {
+ // found is invalid, use candidate
+ aFound = a;
+ bOkay = (*aFound)->GetOutputWidthPixel() >=
rSizePixel.getWidth() && (*aFound)->GetOutputHeightPixel() >=
rSizePixel.getHeight();
+ }
+ }
+ else
+ {
+ // none yet, use candidate
+ aFound = a;
+ bOkay = (*aFound)->GetOutputWidthPixel() >=
rSizePixel.getWidth() && (*aFound)->GetOutputHeightPixel() >=
rSizePixel.getHeight();
+ }
+ }
+ }
+
+ if(aFound != maBuffers.end())
+ {
+ pRetval = *aFound;
+ maBuffers.erase(aFound);
+
+ if(bOkay)
+ {
+ if(bClear)
+ {
+ pRetval->Erase(Rectangle(0, 0, rSizePixel.getWidth(),
rSizePixel.getHeight()));
+ }
+ }
+ else
+ {
+ pRetval->SetOutputSizePixel(rSizePixel, bClear);
+ }
+ }
+ }
+
+ // no success yet, create new buffer
+ if(!pRetval)
+ {
+ pRetval = (bMono) ? new VirtualDevice(rOutDev, 1) : new
VirtualDevice(rOutDev);
+ pRetval->SetOutputSizePixel(rSizePixel, bClear);
+ }
+ else
+ {
+ // reused, reset some values
+ pRetval->SetMapMode();
+ }
+
+ return pRetval;
+ }
+
+ void VDevBuffer::free(VirtualDevice& rDevice)
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+ maBuffers.push_back(&rDevice);
+ Start();
+ }
+
+ void VDevBuffer::Timeout()
+ {
+ ::osl::MutexGuard aGuard(m_aMutex);
+
+ while(!maBuffers.empty())
+ {
+ delete *(maBuffers.end() - 1);
+ maBuffers.pop_back();
+ }
+ }
+}
//////////////////////////////////////////////////////////////////////////////
// support for rendering Bitmap and BitmapEx contents
namespace drawinglayer
{
- impBufferDevice::impBufferDevice(
- OutputDevice& rOutDev,
- const basegfx::B2DRange& rRange,
- bool bAddOffsetToMapping)
- : mrOutDev(rOutDev),
- maContent(rOutDev),
- mpMask(0L),
- mpAlpha(0L)
- {
+ // static global VDev buffer for the VclProcessor2D's
(VclMetafileProcessor2D and VclPixelProcessor2D)
+ static VDevBuffer aVDevBuffer;
+
+ impBufferDevice::impBufferDevice(
+ OutputDevice& rOutDev,
+ const basegfx::B2DRange& rRange,
+ bool bAddOffsetToMapping)
+ : mrOutDev(rOutDev),
+ mpContent(0),
+ mpMask(0),
+ mpAlpha(0)
+ {
basegfx::B2DRange aRangePixel(rRange);
- aRangePixel.transform(rOutDev.GetViewTransformation());
+ aRangePixel.transform(mrOutDev.GetViewTransformation());
const Rectangle aRectPixel(
- (sal_Int32)floor(aRangePixel.getMinX()),
(sal_Int32)floor(aRangePixel.getMinY()),
- (sal_Int32)ceil(aRangePixel.getMaxX()),
(sal_Int32)ceil(aRangePixel.getMaxY()));
- const Point aEmptyPoint;
- maDestPixel = Rectangle(aEmptyPoint,
rOutDev.GetOutputSizePixel());
- maDestPixel.Intersection(aRectPixel);
-
- if(isVisible())
- {
- maContent.SetOutputSizePixel(maDestPixel.GetSize(),
false);
+ (sal_Int32)floor(aRangePixel.getMinX()),
(sal_Int32)floor(aRangePixel.getMinY()),
+ (sal_Int32)ceil(aRangePixel.getMaxX()),
(sal_Int32)ceil(aRangePixel.getMaxY()));
+ const Point aEmptyPoint;
+ maDestPixel = Rectangle(aEmptyPoint, mrOutDev.GetOutputSizePixel());
+ maDestPixel.Intersection(aRectPixel);
+
+ if(isVisible())
+ {
+ mpContent = aVDevBuffer.alloc(mrOutDev, maDestPixel.GetSize(),
false, false);
// #i93485# assert when copying from window to VDev is used
- OSL_ENSURE(rOutDev.GetOutDevType() != OUTDEV_WINDOW,
+ OSL_ENSURE(mrOutDev.GetOutDevType() != OUTDEV_WINDOW,
"impBufferDevice render helper: Copying from Window to VDev,
this should be avoided (!)");
- const bool bWasEnabledSrc(rOutDev.IsMapModeEnabled());
- rOutDev.EnableMapMode(false);
- maContent.DrawOutDev(aEmptyPoint,
maDestPixel.GetSize(), maDestPixel.TopLeft(), maDestPixel.GetSize(), rOutDev);
- rOutDev.EnableMapMode(bWasEnabledSrc);
-
- MapMode aNewMapMode(rOutDev.GetMapMode());
-
- if(bAddOffsetToMapping)
- {
- const Point
aLogicTopLeft(rOutDev.PixelToLogic(maDestPixel.TopLeft()));
- aNewMapMode.SetOrigin(Point(-aLogicTopLeft.X(),
-aLogicTopLeft.Y()));
- }
+ const bool bWasEnabledSrc(mrOutDev.IsMapModeEnabled());
+ mrOutDev.EnableMapMode(false);
+ mpContent->DrawOutDev(aEmptyPoint, maDestPixel.GetSize(),
maDestPixel.TopLeft(), maDestPixel.GetSize(), mrOutDev);
+ mrOutDev.EnableMapMode(bWasEnabledSrc);
+
+ MapMode aNewMapMode(mrOutDev.GetMapMode());
+
+ if(bAddOffsetToMapping)
+ {
+ const Point
aLogicTopLeft(mrOutDev.PixelToLogic(maDestPixel.TopLeft()));
+ aNewMapMode.SetOrigin(Point(-aLogicTopLeft.X(),
-aLogicTopLeft.Y()));
+ }
- maContent.SetMapMode(aNewMapMode);
+ mpContent->SetMapMode(aNewMapMode);
// copy AA flag for new target
- maContent.SetAntialiasing(mrOutDev.GetAntialiasing());
- }
- }
-
- impBufferDevice::~impBufferDevice()
- {
- delete mpMask;
- delete mpAlpha;
- }
-
- void impBufferDevice::paint(double fTrans)
- {
- const Point aEmptyPoint;
- const Size aSizePixel(maContent.GetOutputSizePixel());
- const bool bWasEnabledDst(mrOutDev.IsMapModeEnabled());
- static bool bDoSaveForVisualControl(false);
-
- mrOutDev.EnableMapMode(false);
- maContent.EnableMapMode(false);
- Bitmap aContent(maContent.GetBitmap(aEmptyPoint, aSizePixel));
-
- if(bDoSaveForVisualControl)
- {
- SvFileStream aNew((const String&)String(ByteString(
"c:\\content.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
- aNew << aContent;
- }
+ mpContent->SetAntialiasing(mrOutDev.GetAntialiasing());
+ }
+ }
+
+ impBufferDevice::~impBufferDevice()
+ {
+ if(mpContent)
+ {
+ aVDevBuffer.free(*mpContent);
+ }
+
+ if(mpMask)
+ {
+ aVDevBuffer.free(*mpMask);
+ }
if(mpAlpha)
- {
- mpAlpha->EnableMapMode(false);
- const AlphaMask
aAlphaMask(mpAlpha->GetBitmap(aEmptyPoint, aSizePixel));
-
+ {
+ aVDevBuffer.free(*mpAlpha);
+ }
+ }
+
+ void impBufferDevice::paint(double fTrans)
+ {
+ if(isVisible())
+ {
+ const Point aEmptyPoint;
+ const Size aSizePixel(maDestPixel.GetSize());
+ const bool bWasEnabledDst(mrOutDev.IsMapModeEnabled());
+ static bool bDoSaveForVisualControl(false);
+
+ mrOutDev.EnableMapMode(false);
+ mpContent->EnableMapMode(false);
+ Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));
+
if(bDoSaveForVisualControl)
- {
- SvFileStream aNew((const String&)String(ByteString(
"c:\\transparence.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
- aNew << aAlphaMask.GetBitmap();
- }
-
- mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent,
aAlphaMask));
- }
- else if(mpMask)
- {
- mpMask->EnableMapMode(false);
- const Bitmap aMask(mpMask->GetBitmap(aEmptyPoint,
aSizePixel));
-
- if(bDoSaveForVisualControl)
- {
- SvFileStream aNew((const String&)String(ByteString(
"c:\\mask.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
- aNew << aMask;
- }
-
- mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent,
aMask));
- }
- else if(0.0 != fTrans)
- {
- sal_uInt8 nMaskValue((sal_uInt8)basegfx::fround(fTrans
* 255.0));
- const AlphaMask aAlphaMask(aSizePixel, &nMaskValue);
- mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(),
BitmapEx(aContent, aAlphaMask));
- }
- else
- {
- mrOutDev.DrawBitmap(maDestPixel.TopLeft(), aContent);
- }
-
- mrOutDev.EnableMapMode(bWasEnabledDst);
- }
-
- VirtualDevice& impBufferDevice::getMask()
- {
- if(!mpMask)
- {
- mpMask = new VirtualDevice(mrOutDev, 1);
- mpMask->SetOutputSizePixel(maDestPixel.GetSize(), true);
- mpMask->SetMapMode(maContent.GetMapMode());
+ {
+ SvFileStream aNew((const String&)String(ByteString(
"c:\\content.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
+ aNew << aContent;
+ }
+
+ if(mpAlpha)
+ {
+ mpAlpha->EnableMapMode(false);
+ const AlphaMask aAlphaMask(mpAlpha->GetBitmap(aEmptyPoint,
aSizePixel));
+
+ if(bDoSaveForVisualControl)
+ {
+ SvFileStream aNew((const String&)String(ByteString(
"c:\\transparence.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
+ aNew << aAlphaMask.GetBitmap();
+ }
+
+ mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(),
BitmapEx(aContent, aAlphaMask));
+ }
+ else if(mpMask)
+ {
+ mpMask->EnableMapMode(false);
+ const Bitmap aMask(mpMask->GetBitmap(aEmptyPoint,
aSizePixel));
+
+ if(bDoSaveForVisualControl)
+ {
+ SvFileStream aNew((const String&)String(ByteString(
"c:\\mask.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC);
+ aNew << aMask;
+ }
+
+ mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(),
BitmapEx(aContent, aMask));
+ }
+ else if(0.0 != fTrans)
+ {
+ sal_uInt8 nMaskValue((sal_uInt8)basegfx::fround(fTrans *
255.0));
+ const AlphaMask aAlphaMask(aSizePixel, &nMaskValue);
+ mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(),
BitmapEx(aContent, aAlphaMask));
+ }
+ else
+ {
+ mrOutDev.DrawBitmap(maDestPixel.TopLeft(), aContent);
+ }
+
+ mrOutDev.EnableMapMode(bWasEnabledDst);
+ }
+ }
+
+ VirtualDevice& impBufferDevice::getContent()
+ {
+ OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible()
before accessing (!)");
+ return *mpContent;
+ }
+
+ VirtualDevice& impBufferDevice::getMask()
+ {
+ OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible()
before accessing (!)");
+ if(!mpMask)
+ {
+ mpMask = aVDevBuffer.alloc(mrOutDev, maDestPixel.GetSize(), true,
true);
+ mpMask->SetMapMode(mpContent->GetMapMode());
// do NOT copy AA flag for mask!
- }
-
- return *mpMask;
- }
-
- VirtualDevice& impBufferDevice::getTransparence()
- {
- if(!mpAlpha)
- {
- mpAlpha = new VirtualDevice();
- mpAlpha->SetOutputSizePixel(maDestPixel.GetSize(),
true);
- mpAlpha->SetMapMode(maContent.GetMapMode());
+ }
+
+ return *mpMask;
+ }
+
+ VirtualDevice& impBufferDevice::getTransparence()
+ {
+ OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible()
before accessing (!)");
+ if(!mpAlpha)
+ {
+ mpAlpha = aVDevBuffer.alloc(mrOutDev, maDestPixel.GetSize(), true,
false);
+ mpAlpha->SetMapMode(mpContent->GetMapMode());
// copy AA flag for new target; masking needs to be smooth
- mpAlpha->SetAntialiasing(maContent.GetAntialiasing());
- }
-
- return *mpAlpha;
- }
+ mpAlpha->SetAntialiasing(mpContent->GetAntialiasing());
+ }
+
+ return *mpAlpha;
+ }
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
Modified:
incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx
URL:
http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx?rev=1229521&r1=1229520&r2=1229521&view=diff
==============================================================================
---
incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx
(original)
+++
incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelperbufferdevice.hxx
Tue Jan 10 12:44:03 2012
@@ -38,11 +38,11 @@ namespace drawinglayer
{
class impBufferDevice
{
- OutputDevice&
mrOutDev;
- VirtualDevice
maContent;
- VirtualDevice* mpMask;
- VirtualDevice* mpAlpha;
- Rectangle
maDestPixel;
+ OutputDevice& mrOutDev;
+ VirtualDevice* mpContent;
+ VirtualDevice* mpMask;
+ VirtualDevice* mpAlpha;
+ Rectangle maDestPixel;
public:
impBufferDevice(
@@ -53,7 +53,7 @@ namespace drawinglayer
void paint(double fTrans = 0.0);
bool isVisible() const { return !maDestPixel.IsEmpty(); }
- VirtualDevice& getContent() { return maContent; }
+ VirtualDevice& getContent();
VirtualDevice& getMask();
VirtualDevice& getTransparence();
};