summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drawinglayer/source/attribute/fillgraphicattribute.cxx6
-rw-r--r--drawinglayer/source/primitive2d/sceneprimitive2d.cxx251
-rw-r--r--drawinglayer/source/primitive3d/sdrextrudeprimitive3d.cxx4
-rw-r--r--drawinglayer/source/primitive3d/sdrlatheprimitive3d.cxx4
-rw-r--r--drawinglayer/source/processor3d/zbufferprocessor3d.cxx394
-rw-r--r--include/basegfx/matrix/b3dhommatrix.hxx2
-rw-r--r--include/basegfx/polygon/b3dpolygon.hxx2
-rw-r--r--include/basegfx/polygon/b3dpolypolygon.hxx2
-rw-r--r--include/drawinglayer/processor3d/zbufferprocessor3d.hxx18
9 files changed, 376 insertions, 307 deletions
diff --git a/drawinglayer/source/attribute/fillgraphicattribute.cxx b/drawinglayer/source/attribute/fillgraphicattribute.cxx
index 6d70e46de699..9465af23b054 100644
--- a/drawinglayer/source/attribute/fillgraphicattribute.cxx
+++ b/drawinglayer/source/attribute/fillgraphicattribute.cxx
@@ -51,6 +51,12 @@ namespace drawinglayer
mfOffsetX(fOffsetX),
mfOffsetY(fOffsetY)
{
+ // access once to ensure that the buffered bitmap exists, else
+ // the SolarMutex may be needed to create it. This may not be
+ // available when a renderer works with multi-treading.
+ // When changing this, please check if it is still possible to
+ // use a metafile as texture for a 3D object
+ maGraphic.GetBitmapEx();
}
ImpFillGraphicAttribute()
diff --git a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
index 27a4e0dc3943..68acb57ff5d6 100644
--- a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx
@@ -32,10 +32,105 @@
#include <svtools/optionsdrawinglayer.hxx>
#include <drawinglayer/processor3d/geometry2dextractor.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
-
+#include <basegfx/raster/bzpixelraster.hxx>
+#include <vcl/bitmapaccess.hxx>
+#include <comphelper/threadpool.hxx>
using namespace com::sun::star;
+namespace
+{
+ BitmapEx BPixelRasterToBitmapEx(const basegfx::BPixelRaster& rRaster, sal_uInt16 mnAntiAlialize)
+ {
+ BitmapEx aRetval;
+ const sal_uInt32 nWidth(mnAntiAlialize ? rRaster.getWidth()/mnAntiAlialize : rRaster.getWidth());
+ const sal_uInt32 nHeight(mnAntiAlialize ? rRaster.getHeight()/mnAntiAlialize : rRaster.getHeight());
+
+ if(nWidth && nHeight)
+ {
+ const Size aDestSize(nWidth, nHeight);
+ sal_uInt8 nInitAlpha(255);
+ Bitmap aContent(aDestSize, 24);
+ AlphaMask aAlpha(aDestSize, &nInitAlpha);
+ BitmapWriteAccess* pContent = aContent.AcquireWriteAccess();
+ BitmapWriteAccess* pAlpha = aAlpha.AcquireWriteAccess();
+
+ if (pContent && pAlpha)
+ {
+ if(mnAntiAlialize)
+ {
+ const sal_uInt16 nDivisor(mnAntiAlialize * mnAntiAlialize);
+
+ for(sal_uInt32 y(0L); y < nHeight; y++)
+ {
+ for(sal_uInt32 x(0L); x < nWidth; x++)
+ {
+ sal_uInt16 nRed(0);
+ sal_uInt16 nGreen(0);
+ sal_uInt16 nBlue(0);
+ sal_uInt16 nOpacity(0);
+ sal_uInt32 nIndex(rRaster.getIndexFromXY(x * mnAntiAlialize, y * mnAntiAlialize));
+
+ for(sal_uInt32 c(0); c < mnAntiAlialize; c++)
+ {
+ for(sal_uInt32 d(0); d < mnAntiAlialize; d++)
+ {
+ const basegfx::BPixel& rPixel(rRaster.getBPixel(nIndex++));
+ nRed = nRed + rPixel.getRed();
+ nGreen = nGreen + rPixel.getGreen();
+ nBlue = nBlue + rPixel.getBlue();
+ nOpacity = nOpacity + rPixel.getOpacity();
+ }
+
+ nIndex += rRaster.getWidth() - mnAntiAlialize;
+ }
+
+ nOpacity = nOpacity / nDivisor;
+
+ if(nOpacity)
+ {
+ pContent->SetPixel(y, x, BitmapColor(
+ (sal_uInt8)(nRed / nDivisor),
+ (sal_uInt8)(nGreen / nDivisor),
+ (sal_uInt8)(nBlue / nDivisor)));
+ pAlpha->SetPixel(y, x, BitmapColor(255 - (sal_uInt8)nOpacity));
+ }
+ }
+ }
+ }
+ else
+ {
+ sal_uInt32 nIndex(0L);
+
+ for(sal_uInt32 y(0L); y < nHeight; y++)
+ {
+ for(sal_uInt32 x(0L); x < nWidth; x++)
+ {
+ const basegfx::BPixel& rPixel(rRaster.getBPixel(nIndex++));
+
+ if(rPixel.getOpacity())
+ {
+ pContent->SetPixel(y, x, BitmapColor(rPixel.getRed(), rPixel.getGreen(), rPixel.getBlue()));
+ pAlpha->SetPixel(y, x, BitmapColor(255 - rPixel.getOpacity()));
+ }
+ }
+ }
+ }
+ }
+
+ aAlpha.ReleaseAccess(pAlpha);
+ Bitmap::ReleaseAccess(pContent);
+
+ aRetval = BitmapEx(aContent, aAlpha);
+
+ // #i101811# set PrefMapMode and PrefSize at newly created Bitmap
+ aRetval.SetPrefMapMode(MAP_PIXEL);
+ aRetval.SetPrefSize(Size(nWidth, nHeight));
+ }
+
+ return aRetval;
+ }
+} // end of anonymous namespace
namespace drawinglayer
{
@@ -263,49 +358,135 @@ namespace drawinglayer
const double fLogicX((aInverseOToV * basegfx::B2DVector(aDiscreteRange.getWidth() * fReduceFactor, 0.0)).getLength());
const double fLogicY((aInverseOToV * basegfx::B2DVector(0.0, aDiscreteRange.getHeight() * fReduceFactor)).getLength());
- // use default 3D primitive processor to create BitmapEx for aUnitVisiblePart and process
- processor3d::ZBufferProcessor3D aZBufferProcessor3D(
- aViewInformation3D,
- rViewInformation,
- getSdrSceneAttribute(),
- getSdrLightingAttribute(),
- fLogicX,
- fLogicY,
- aUnitVisibleRange,
- nOversampleValue);
-
- aZBufferProcessor3D.process(getChildren3D());
- aZBufferProcessor3D.finish();
+ // generate ViewSizes
+ const double fFullViewSizeX((rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(fLogicX, 0.0)).getLength());
+ const double fFullViewSizeY((rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(0.0, fLogicY)).getLength());
- const_cast< ScenePrimitive2D* >(this)->maOldRenderedBitmap = aZBufferProcessor3D.getBitmapEx();
- const Size aBitmapSizePixel(maOldRenderedBitmap.GetSizePixel());
+ // generate RasterWidth and RasterHeight for visible part
+ const sal_Int32 nRasterWidth((sal_Int32)basegfx::fround(fFullViewSizeX * aUnitVisibleRange.getWidth()) + 1);
+ const sal_Int32 nRasterHeight((sal_Int32)basegfx::fround(fFullViewSizeY * aUnitVisibleRange.getHeight()) + 1);
- if(aBitmapSizePixel.getWidth() && aBitmapSizePixel.getHeight())
+ if(nRasterWidth && nRasterHeight)
{
- // create transform for the created bitmap in discrete coordinates first.
- basegfx::B2DHomMatrix aNew2DTransform;
+ // create view unit buffer
+ basegfx::BZPixelRaster aBZPixelRaster(
+ nOversampleValue ? nRasterWidth * nOversampleValue : nRasterWidth,
+ nOversampleValue ? nRasterHeight * nOversampleValue : nRasterHeight);
- aNew2DTransform.set(0, 0, aVisibleDiscreteRange.getWidth());
- aNew2DTransform.set(1, 1, aVisibleDiscreteRange.getHeight());
- aNew2DTransform.set(0, 2, aVisibleDiscreteRange.getMinX());
- aNew2DTransform.set(1, 2, aVisibleDiscreteRange.getMinY());
+ // check for parallel execution possibilities
+ static bool bMultithreadAllowed = true;
+ sal_Int32 nThreadCount(0);
+ comphelper::ThreadPool& rThreadPool(comphelper::ThreadPool::getSharedOptimalPool());
- // transform back to world coordinates for usage in primitive creation
- aNew2DTransform *= aInverseOToV;
+ if(bMultithreadAllowed)
+ {
+ nThreadCount = rThreadPool.getWorkerCount();
+
+ if(nThreadCount > 1)
+ {
+ // at least use 10px per processor, so limit number of processors to
+ // target pixel size divided by 10 (which might be zero what is okay)
+ nThreadCount = std::min(nThreadCount, nRasterHeight / 10);
+ }
+ }
- // create bitmap primitive and add
- const Primitive2DReference xRef(new BitmapPrimitive2D(maOldRenderedBitmap, aNew2DTransform));
- aRetval.push_back(xRef);
+ if(nThreadCount > 1)
+ {
+ class Executor : public comphelper::ThreadTask
+ {
+ private:
+ processor3d::ZBufferProcessor3D* mpZBufferProcessor3D;
+ const primitive3d::Primitive3DContainer& mrChildren3D;
+
+ public:
+ explicit Executor(
+ processor3d::ZBufferProcessor3D* pZBufferProcessor3D,
+ const primitive3d::Primitive3DContainer& rChildren3D)
+ : mpZBufferProcessor3D(pZBufferProcessor3D),
+ mrChildren3D(rChildren3D)
+ {
+ }
+
+ virtual void doWork() override
+ {
+ mpZBufferProcessor3D->process(mrChildren3D);
+ mpZBufferProcessor3D->finish();
+ delete mpZBufferProcessor3D;
+ }
+ };
+
+ std::vector< processor3d::ZBufferProcessor3D* > aProcessors;
+ const sal_uInt32 nLinesPerThread(aBZPixelRaster.getHeight() / nThreadCount);
+
+ for(sal_Int32 a(0); a < nThreadCount; a++)
+ {
+ processor3d::ZBufferProcessor3D* pNewZBufferProcessor3D = new processor3d::ZBufferProcessor3D(
+ aViewInformation3D,
+ getSdrSceneAttribute(),
+ getSdrLightingAttribute(),
+ aUnitVisibleRange,
+ nOversampleValue,
+ fFullViewSizeX,
+ fFullViewSizeY,
+ aBZPixelRaster,
+ nLinesPerThread * a,
+ a + 1 == nThreadCount ? aBZPixelRaster.getHeight() : nLinesPerThread * (a + 1));
+ aProcessors.push_back(pNewZBufferProcessor3D);
+ Executor* pExecutor = new Executor(pNewZBufferProcessor3D, getChildren3D());
+ rThreadPool.pushTask(pExecutor);
+ }
+
+ rThreadPool.waitUntilEmpty();
+ }
+ else
+ {
+ // use default 3D primitive processor to create BitmapEx for aUnitVisiblePart and process
+ processor3d::ZBufferProcessor3D aZBufferProcessor3D(
+ aViewInformation3D,
+ getSdrSceneAttribute(),
+ getSdrLightingAttribute(),
+ aUnitVisibleRange,
+ nOversampleValue,
+ fFullViewSizeX,
+ fFullViewSizeY,
+ aBZPixelRaster,
+ 0,
+ aBZPixelRaster.getHeight());
+
+ aZBufferProcessor3D.process(getChildren3D());
+ aZBufferProcessor3D.finish();
+ }
- // test: Allow to add an outline in the debugger when tests are needed
- static bool bAddOutlineToCreated3DSceneRepresentation(false);
+ const_cast< ScenePrimitive2D* >(this)->maOldRenderedBitmap = BPixelRasterToBitmapEx(aBZPixelRaster, nOversampleValue);
+ const Size aBitmapSizePixel(maOldRenderedBitmap.GetSizePixel());
- if(bAddOutlineToCreated3DSceneRepresentation)
+ if(aBitmapSizePixel.getWidth() && aBitmapSizePixel.getHeight())
{
- basegfx::B2DPolygon aOutline(basegfx::tools::createUnitPolygon());
- aOutline.transform(aNew2DTransform);
- const Primitive2DReference xRef2(new PolygonHairlinePrimitive2D(aOutline, basegfx::BColor(1.0, 0.0, 0.0)));
- aRetval.push_back(xRef2);
+ // create transform for the created bitmap in discrete coordinates first.
+ basegfx::B2DHomMatrix aNew2DTransform;
+
+ aNew2DTransform.set(0, 0, aVisibleDiscreteRange.getWidth());
+ aNew2DTransform.set(1, 1, aVisibleDiscreteRange.getHeight());
+ aNew2DTransform.set(0, 2, aVisibleDiscreteRange.getMinX());
+ aNew2DTransform.set(1, 2, aVisibleDiscreteRange.getMinY());
+
+ // transform back to world coordinates for usage in primitive creation
+ aNew2DTransform *= aInverseOToV;
+
+ // create bitmap primitive and add
+ const Primitive2DReference xRef(new BitmapPrimitive2D(maOldRenderedBitmap, aNew2DTransform));
+ aRetval.push_back(xRef);
+
+ // test: Allow to add an outline in the debugger when tests are needed
+ static bool bAddOutlineToCreated3DSceneRepresentation(false);
+
+ if(bAddOutlineToCreated3DSceneRepresentation)
+ {
+ basegfx::B2DPolygon aOutline(basegfx::tools::createUnitPolygon());
+ aOutline.transform(aNew2DTransform);
+ const Primitive2DReference xRef2(new PolygonHairlinePrimitive2D(aOutline, basegfx::BColor(1.0, 0.0, 0.0)));
+ aRetval.push_back(xRef2);
+ }
}
}
}
diff --git a/drawinglayer/source/primitive3d/sdrextrudeprimitive3d.cxx b/drawinglayer/source/primitive3d/sdrextrudeprimitive3d.cxx
index a5fe0ddb0348..be15838fd8b7 100644
--- a/drawinglayer/source/primitive3d/sdrextrudeprimitive3d.cxx
+++ b/drawinglayer/source/primitive3d/sdrextrudeprimitive3d.cxx
@@ -375,6 +375,8 @@ namespace drawinglayer
// again when no longer geometry is needed for non-visible 3D objects as it is now for chart
if(getPolyPolygon().count() && !maSlices.size())
{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
const_cast< SdrExtrudePrimitive3D& >(*this).impCreateSlices();
}
@@ -488,6 +490,8 @@ namespace drawinglayer
(!getBuffered3DDecomposition().empty()
&& *mpLastRLGViewInformation != rViewInformation))
{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
// conditions of last local decomposition with reduced lines have changed. Remember
// new one and clear current decompositiopn
SdrExtrudePrimitive3D* pThat = const_cast< SdrExtrudePrimitive3D* >(this);
diff --git a/drawinglayer/source/primitive3d/sdrlatheprimitive3d.cxx b/drawinglayer/source/primitive3d/sdrlatheprimitive3d.cxx
index be66c16d7a8b..f831aba427bd 100644
--- a/drawinglayer/source/primitive3d/sdrlatheprimitive3d.cxx
+++ b/drawinglayer/source/primitive3d/sdrlatheprimitive3d.cxx
@@ -231,6 +231,8 @@ namespace drawinglayer
// again when no longer geometry is needed for non-visible 3D objects as it is now for chart
if(getPolyPolygon().count() && !maSlices.size())
{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
const_cast< SdrLathePrimitive3D& >(*this).impCreateSlices();
}
@@ -350,6 +352,8 @@ namespace drawinglayer
(!getBuffered3DDecomposition().empty()
&& *mpLastRLGViewInformation != rViewInformation))
{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
// conditions of last local decomposition with reduced lines have changed. Remember
// new one and clear current decompositiopn
SdrLathePrimitive3D* pThat = const_cast< SdrLathePrimitive3D* >(this);
diff --git a/drawinglayer/source/processor3d/zbufferprocessor3d.cxx b/drawinglayer/source/processor3d/zbufferprocessor3d.cxx
index 0334c911ba76..3944f83705e0 100644
--- a/drawinglayer/source/processor3d/zbufferprocessor3d.cxx
+++ b/drawinglayer/source/processor3d/zbufferprocessor3d.cxx
@@ -19,7 +19,6 @@
#include <drawinglayer/processor3d/zbufferprocessor3d.hxx>
#include <basegfx/raster/bpixelraster.hxx>
-#include <vcl/bitmapaccess.hxx>
#include <basegfx/raster/rasterconvert3d.hxx>
#include <basegfx/raster/bzpixelraster.hxx>
#include <drawinglayer/attribute/materialattribute3d.hxx>
@@ -35,100 +34,6 @@
using namespace com::sun::star;
-namespace
-{
- BitmapEx BPixelRasterToBitmapEx(const basegfx::BPixelRaster& rRaster, sal_uInt16 mnAntiAlialize)
- {
- BitmapEx aRetval;
- const sal_uInt32 nWidth(mnAntiAlialize ? rRaster.getWidth()/mnAntiAlialize : rRaster.getWidth());
- const sal_uInt32 nHeight(mnAntiAlialize ? rRaster.getHeight()/mnAntiAlialize : rRaster.getHeight());
-
- if(nWidth && nHeight)
- {
- const Size aDestSize(nWidth, nHeight);
- sal_uInt8 nInitAlpha(255);
- Bitmap aContent(aDestSize, 24);
- AlphaMask aAlpha(aDestSize, &nInitAlpha);
- BitmapWriteAccess* pContent = aContent.AcquireWriteAccess();
- BitmapWriteAccess* pAlpha = aAlpha.AcquireWriteAccess();
-
- if (pContent && pAlpha)
- {
- if(mnAntiAlialize)
- {
- const sal_uInt16 nDivisor(mnAntiAlialize * mnAntiAlialize);
-
- for(sal_uInt32 y(0L); y < nHeight; y++)
- {
- for(sal_uInt32 x(0L); x < nWidth; x++)
- {
- sal_uInt16 nRed(0);
- sal_uInt16 nGreen(0);
- sal_uInt16 nBlue(0);
- sal_uInt16 nOpacity(0);
- sal_uInt32 nIndex(rRaster.getIndexFromXY(x * mnAntiAlialize, y * mnAntiAlialize));
-
- for(sal_uInt32 c(0); c < mnAntiAlialize; c++)
- {
- for(sal_uInt32 d(0); d < mnAntiAlialize; d++)
- {
- const basegfx::BPixel& rPixel(rRaster.getBPixel(nIndex++));
- nRed = nRed + rPixel.getRed();
- nGreen = nGreen + rPixel.getGreen();
- nBlue = nBlue + rPixel.getBlue();
- nOpacity = nOpacity + rPixel.getOpacity();
- }
-
- nIndex += rRaster.getWidth() - mnAntiAlialize;
- }
-
- nOpacity = nOpacity / nDivisor;
-
- if(nOpacity)
- {
- pContent->SetPixel(y, x, BitmapColor(
- (sal_uInt8)(nRed / nDivisor),
- (sal_uInt8)(nGreen / nDivisor),
- (sal_uInt8)(nBlue / nDivisor)));
- pAlpha->SetPixel(y, x, BitmapColor(255 - (sal_uInt8)nOpacity));
- }
- }
- }
- }
- else
- {
- sal_uInt32 nIndex(0L);
-
- for(sal_uInt32 y(0L); y < nHeight; y++)
- {
- for(sal_uInt32 x(0L); x < nWidth; x++)
- {
- const basegfx::BPixel& rPixel(rRaster.getBPixel(nIndex++));
-
- if(rPixel.getOpacity())
- {
- pContent->SetPixel(y, x, BitmapColor(rPixel.getRed(), rPixel.getGreen(), rPixel.getBlue()));
- pAlpha->SetPixel(y, x, BitmapColor(255 - rPixel.getOpacity()));
- }
- }
- }
- }
- }
-
- aAlpha.ReleaseAccess(pAlpha);
- Bitmap::ReleaseAccess(pContent);
-
- aRetval = BitmapEx(aContent, aAlpha);
-
- // #i101811# set PrefMapMode and PrefSize at newly created Bitmap
- aRetval.SetPrefMapMode(MAP_PIXEL);
- aRetval.SetPrefSize(Size(nWidth, nHeight));
- }
-
- return aRetval;
- }
-} // end of anonymous namespace
-
class ZBufferRasterConverter3D : public basegfx::RasterConverter3D
{
private:
@@ -536,211 +441,188 @@ namespace drawinglayer
{
void ZBufferProcessor3D::rasterconvertB3DPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolygon& rHairline) const
{
- if(mpBZPixelRaster)
+ if(getTransparenceCounter())
{
- if(getTransparenceCounter())
+ // transparent output; record for later sorting and painting from
+ // back to front
+ if(!mpRasterPrimitive3Ds)
{
- // transparent output; record for later sorting and painting from
- // back to front
- if(!mpRasterPrimitive3Ds)
- {
- const_cast< ZBufferProcessor3D* >(this)->mpRasterPrimitive3Ds = new std::vector< RasterPrimitive3D >;
- }
-
- mpRasterPrimitive3Ds->push_back(RasterPrimitive3D(
- getGeoTexSvx(),
- getTransparenceGeoTexSvx(),
- rMaterial,
- basegfx::B3DPolyPolygon(rHairline),
- getModulate(),
- getFilter(),
- getSimpleTextureActive(),
- true));
+ const_cast< ZBufferProcessor3D* >(this)->mpRasterPrimitive3Ds = new std::vector< RasterPrimitive3D >;
}
- else
+
+ mpRasterPrimitive3Ds->push_back(RasterPrimitive3D(
+ getGeoTexSvx(),
+ getTransparenceGeoTexSvx(),
+ rMaterial,
+ basegfx::B3DPolyPolygon(rHairline),
+ getModulate(),
+ getFilter(),
+ getSimpleTextureActive(),
+ true));
+ }
+ else
+ {
+ // do rasterconversion
+ mpZBufferRasterConverter3D->setCurrentMaterial(rMaterial);
+
+ if(mnAntiAlialize > 1)
{
- // do rasterconversion
- mpZBufferRasterConverter3D->setCurrentMaterial(rMaterial);
+ const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete());
- if(mnAntiAlialize > 1)
+ if(bForceLineSnap)
{
- const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete());
+ basegfx::B3DHomMatrix aTransform;
+ basegfx::B3DPolygon aSnappedHairline(rHairline);
+ const double fScaleDown(1.0 / mnAntiAlialize);
+ const double fScaleUp(mnAntiAlialize);
- if(bForceLineSnap)
- {
- basegfx::B3DHomMatrix aTransform;
- basegfx::B3DPolygon aSnappedHairline(rHairline);
- const double fScaleDown(1.0 / mnAntiAlialize);
- const double fScaleUp(mnAntiAlialize);
-
- // take oversampling out
- aTransform.scale(fScaleDown, fScaleDown, 1.0);
- aSnappedHairline.transform(aTransform);
+ // take oversampling out
+ aTransform.scale(fScaleDown, fScaleDown, 1.0);
+ aSnappedHairline.transform(aTransform);
- // snap to integer
- aSnappedHairline = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aSnappedHairline);
+ // snap to integer
+ aSnappedHairline = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aSnappedHairline);
- // add oversampling again
- aTransform.identity();
- aTransform.scale(fScaleUp, fScaleUp, 1.0);
+ // add oversampling again
+ aTransform.identity();
+ aTransform.scale(fScaleUp, fScaleUp, 1.0);
- aSnappedHairline.transform(aTransform);
+ aSnappedHairline.transform(aTransform);
- mpZBufferRasterConverter3D->rasterconvertB3DPolygon(aSnappedHairline, 0, mpBZPixelRaster->getHeight(), mnAntiAlialize);
- }
- else
- {
- mpZBufferRasterConverter3D->rasterconvertB3DPolygon(rHairline, 0, mpBZPixelRaster->getHeight(), mnAntiAlialize);
- }
+ mpZBufferRasterConverter3D->rasterconvertB3DPolygon(aSnappedHairline, mnStartLine, mnStopLine, mnAntiAlialize);
}
else
{
- mpZBufferRasterConverter3D->rasterconvertB3DPolygon(rHairline, 0, mpBZPixelRaster->getHeight(), 1);
+ mpZBufferRasterConverter3D->rasterconvertB3DPolygon(rHairline, mnStartLine, mnStopLine, mnAntiAlialize);
}
}
+ else
+ {
+ mpZBufferRasterConverter3D->rasterconvertB3DPolygon(rHairline, mnStartLine, mnStopLine, 1);
+ }
}
}
void ZBufferProcessor3D::rasterconvertB3DPolyPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolyPolygon& rFill) const
{
- if(mpBZPixelRaster)
+ if(getTransparenceCounter())
{
- if(getTransparenceCounter())
+ // transparent output; record for later sorting and painting from
+ // back to front
+ if(!mpRasterPrimitive3Ds)
{
- // transparent output; record for later sorting and painting from
- // back to front
- if(!mpRasterPrimitive3Ds)
- {
- const_cast< ZBufferProcessor3D* >(this)->mpRasterPrimitive3Ds = new std::vector< RasterPrimitive3D >;
- }
-
- mpRasterPrimitive3Ds->push_back(RasterPrimitive3D(
- getGeoTexSvx(),
- getTransparenceGeoTexSvx(),
- rMaterial,
- rFill,
- getModulate(),
- getFilter(),
- getSimpleTextureActive(),
- false));
- }
- else
- {
- mpZBufferRasterConverter3D->setCurrentMaterial(rMaterial);
- mpZBufferRasterConverter3D->rasterconvertB3DPolyPolygon(rFill, &maInvEyeToView, 0, mpBZPixelRaster->getHeight());
+ const_cast< ZBufferProcessor3D* >(this)->mpRasterPrimitive3Ds = new std::vector< RasterPrimitive3D >;
}
+
+ mpRasterPrimitive3Ds->push_back(RasterPrimitive3D(
+ getGeoTexSvx(),
+ getTransparenceGeoTexSvx(),
+ rMaterial,
+ rFill,
+ getModulate(),
+ getFilter(),
+ getSimpleTextureActive(),
+ false));
+ }
+ else
+ {
+ mpZBufferRasterConverter3D->setCurrentMaterial(rMaterial);
+ mpZBufferRasterConverter3D->rasterconvertB3DPolyPolygon(rFill, &maInvEyeToView, mnStartLine, mnStopLine);
}
}
ZBufferProcessor3D::ZBufferProcessor3D(
const geometry::ViewInformation3D& rViewInformation3D,
- const geometry::ViewInformation2D& rViewInformation2D,
const attribute::SdrSceneAttribute& rSdrSceneAttribute,
const attribute::SdrLightingAttribute& rSdrLightingAttribute,
- double fSizeX,
- double fSizeY,
const basegfx::B2DRange& rVisiblePart,
- sal_uInt16 nAntiAlialize)
+ sal_uInt16 nAntiAlialize,
+ double fFullViewSizeX,
+ double fFullViewSizeY,
+ basegfx::BZPixelRaster& rBZPixelRaster,
+ sal_uInt32 nStartLine,
+ sal_uInt32 nStopLine)
: DefaultProcessor3D(rViewInformation3D, rSdrSceneAttribute, rSdrLightingAttribute),
- mpBZPixelRaster(nullptr),
+ mrBZPixelRaster(rBZPixelRaster),
maInvEyeToView(),
mpZBufferRasterConverter3D(nullptr),
mnAntiAlialize(nAntiAlialize),
- mpRasterPrimitive3Ds(nullptr)
+ mpRasterPrimitive3Ds(nullptr),
+ mnStartLine(nStartLine),
+ mnStopLine(nStopLine)
{
- // generate ViewSizes
- const double fFullViewSizeX((rViewInformation2D.getObjectToViewTransformation() * basegfx::B2DVector(fSizeX, 0.0)).getLength());
- const double fFullViewSizeY((rViewInformation2D.getObjectToViewTransformation() * basegfx::B2DVector(0.0, fSizeY)).getLength());
- const double fViewSizeX(fFullViewSizeX * rVisiblePart.getWidth());
- const double fViewSizeY(fFullViewSizeY * rVisiblePart.getHeight());
-
- // generate RasterWidth and RasterHeight
- const sal_uInt32 nRasterWidth((sal_uInt32)basegfx::fround(fViewSizeX) + 1);
- const sal_uInt32 nRasterHeight((sal_uInt32)basegfx::fround(fViewSizeY) + 1);
+ // create DeviceToView for Z-Buffer renderer since Z is handled
+ // different from standard 3D transformations (Z is mirrored). Also
+ // the transformation includes the step from unit device coordinates
+ // to discrete units ([-1.0 .. 1.0] -> [minDiscrete .. maxDiscrete]
+ basegfx::B3DHomMatrix aDeviceToView;
- if(nRasterWidth && nRasterHeight)
{
- // create view unit buffer
- mpBZPixelRaster = new basegfx::BZPixelRaster(
- mnAntiAlialize ? nRasterWidth * mnAntiAlialize : nRasterWidth,
- mnAntiAlialize ? nRasterHeight * mnAntiAlialize : nRasterHeight);
- OSL_ENSURE(mpBZPixelRaster, "ZBufferProcessor3D: Could not allocate basegfx::BZPixelRaster (!)");
-
- // create DeviceToView for Z-Buffer renderer since Z is handled
- // different from standard 3D transformations (Z is mirrored). Also
- // the transformation includes the step from unit device coordinates
- // to discrete units ([-1.0 .. 1.0] -> [minDiscrete .. maxDiscrete]
-
- basegfx::B3DHomMatrix aDeviceToView;
-
- {
- // step one:
- //
- // bring from [-1.0 .. 1.0] in X,Y and Z to [0.0 .. 1.0]. Also
- // necessary to
- // - flip Y due to screen orientation
- // - flip Z due to Z-Buffer orientation from back to front
-
- aDeviceToView.scale(0.5, -0.5, -0.5);
- aDeviceToView.translate(0.5, 0.5, 0.5);
- }
+ // step one:
+ //
+ // bring from [-1.0 .. 1.0] in X,Y and Z to [0.0 .. 1.0]. Also
+ // necessary to
+ // - flip Y due to screen orientation
+ // - flip Z due to Z-Buffer orientation from back to front
+
+ aDeviceToView.scale(0.5, -0.5, -0.5);
+ aDeviceToView.translate(0.5, 0.5, 0.5);
+ }
- {
- // step two:
- //
- // bring from [0.0 .. 1.0] in X,Y and Z to view coordinates
- //
- // #i102611#
- // also: scale Z to [1.5 .. 65534.5]. Normally, a range of [0.0 .. 65535.0]
- // could be used, but a 'unused' value is needed, so '0' is used what reduces
- // the range to [1.0 .. 65535.0]. It has also shown that small numerical errors
- // (smaller as basegfx::fTools::mfSmallValue, which is 0.000000001) happen.
- // Instead of checking those by basegfx::fTools methods which would cost
- // runtime, just add another 0.5 tolerance to the start and end of the Z-Buffer
- // range, thus resulting in [1.5 .. 65534.5]
- const double fMaxZDepth(65533.0);
- aDeviceToView.translate(-rVisiblePart.getMinX(), -rVisiblePart.getMinY(), 0.0);
-
- if(mnAntiAlialize)
- aDeviceToView.scale(fFullViewSizeX * mnAntiAlialize, fFullViewSizeY * mnAntiAlialize, fMaxZDepth);
- else
- aDeviceToView.scale(fFullViewSizeX, fFullViewSizeY, fMaxZDepth);
+ {
+ // step two:
+ //
+ // bring from [0.0 .. 1.0] in X,Y and Z to view coordinates
+ //
+ // #i102611#
+ // also: scale Z to [1.5 .. 65534.5]. Normally, a range of [0.0 .. 65535.0]
+ // could be used, but a 'unused' value is needed, so '0' is used what reduces
+ // the range to [1.0 .. 65535.0]. It has also shown that small numerical errors
+ // (smaller as basegfx::fTools::mfSmallValue, which is 0.000000001) happen.
+ // Instead of checking those by basegfx::fTools methods which would cost
+ // runtime, just add another 0.5 tolerance to the start and end of the Z-Buffer
+ // range, thus resulting in [1.5 .. 65534.5]
+ const double fMaxZDepth(65533.0);
+ aDeviceToView.translate(-rVisiblePart.getMinX(), -rVisiblePart.getMinY(), 0.0);
- aDeviceToView.translate(0.0, 0.0, 1.5);
- }
+ if(mnAntiAlialize)
+ aDeviceToView.scale(fFullViewSizeX * mnAntiAlialize, fFullViewSizeY * mnAntiAlialize, fMaxZDepth);
+ else
+ aDeviceToView.scale(fFullViewSizeX, fFullViewSizeY, fMaxZDepth);
- // update local ViewInformation3D with own DeviceToView
- const geometry::ViewInformation3D aNewViewInformation3D(
- getViewInformation3D().getObjectTransformation(),
- getViewInformation3D().getOrientation(),
- getViewInformation3D().getProjection(),
- aDeviceToView,
- getViewInformation3D().getViewTime(),
- getViewInformation3D().getExtendedInformationSequence());
- updateViewInformation(aNewViewInformation3D);
-
- // prepare inverse EyeToView transformation. This can be done in constructor
- // since changes in object transformations when processing TransformPrimitive3Ds
- // do not influence this prepared partial transformation
- maInvEyeToView = getViewInformation3D().getDeviceToView() * getViewInformation3D().getProjection();
- maInvEyeToView.invert();
-
- // prepare maRasterRange
- maRasterRange.reset();
- maRasterRange.expand(basegfx::B2DPoint(0.0, 0.0));
- maRasterRange.expand(basegfx::B2DPoint(mpBZPixelRaster->getWidth(), mpBZPixelRaster->getHeight()));
-
- // create the raster converter
- mpZBufferRasterConverter3D = new ZBufferRasterConverter3D(*mpBZPixelRaster, *this);
+ aDeviceToView.translate(0.0, 0.0, 1.5);
}
+
+ // update local ViewInformation3D with own DeviceToView
+ const geometry::ViewInformation3D aNewViewInformation3D(
+ getViewInformation3D().getObjectTransformation(),
+ getViewInformation3D().getOrientation(),
+ getViewInformation3D().getProjection(),
+ aDeviceToView,
+ getViewInformation3D().getViewTime(),
+ getViewInformation3D().getExtendedInformationSequence());
+ updateViewInformation(aNewViewInformation3D);
+
+ // prepare inverse EyeToView transformation. This can be done in constructor
+ // since changes in object transformations when processing TransformPrimitive3Ds
+ // do not influence this prepared partial transformation
+ maInvEyeToView = getViewInformation3D().getDeviceToView() * getViewInformation3D().getProjection();
+ maInvEyeToView.invert();
+
+ // prepare maRasterRange
+ maRasterRange.reset();
+ maRasterRange.expand(basegfx::B2DPoint(0.0, nStartLine));
+ maRasterRange.expand(basegfx::B2DPoint(mrBZPixelRaster.getWidth(), nStopLine));
+
+ // create the raster converter
+ mpZBufferRasterConverter3D = new ZBufferRasterConverter3D(mrBZPixelRaster, *this);
}
ZBufferProcessor3D::~ZBufferProcessor3D()
{
- if(mpBZPixelRaster)
+ if(mpZBufferRasterConverter3D)
{
delete mpZBufferRasterConverter3D;
- delete mpBZPixelRaster;
}
if(mpRasterPrimitive3Ds)
@@ -795,16 +677,6 @@ namespace drawinglayer
mpRasterPrimitive3Ds = nullptr;
}
}
-
- BitmapEx ZBufferProcessor3D::getBitmapEx() const
- {
- if(mpBZPixelRaster)
- {
- return BPixelRasterToBitmapEx(*mpBZPixelRaster, mnAntiAlialize);
- }
-
- return BitmapEx();
- }
} // end of namespace processor3d
} // end of namespace drawinglayer
diff --git a/include/basegfx/matrix/b3dhommatrix.hxx b/include/basegfx/matrix/b3dhommatrix.hxx
index b8e1c5b26c9c..ec8ee34f51d5 100644
--- a/include/basegfx/matrix/b3dhommatrix.hxx
+++ b/include/basegfx/matrix/b3dhommatrix.hxx
@@ -34,7 +34,7 @@ namespace basegfx
class BASEGFX_DLLPUBLIC B3DHomMatrix
{
public:
- typedef o3tl::cow_wrapper< Impl3DHomMatrix > ImplType;
+ typedef o3tl::cow_wrapper< Impl3DHomMatrix, o3tl::ThreadSafeRefCountingPolicy > ImplType;
private:
ImplType mpImpl;
diff --git a/include/basegfx/polygon/b3dpolygon.hxx b/include/basegfx/polygon/b3dpolygon.hxx
index 6c9c9b9c0808..d32968b47ac0 100644
--- a/include/basegfx/polygon/b3dpolygon.hxx
+++ b/include/basegfx/polygon/b3dpolygon.hxx
@@ -42,7 +42,7 @@ namespace basegfx
class BASEGFX_DLLPUBLIC B3DPolygon
{
public:
- typedef o3tl::cow_wrapper< ImplB3DPolygon > ImplType;
+ typedef o3tl::cow_wrapper< ImplB3DPolygon, o3tl::ThreadSafeRefCountingPolicy > ImplType;
private:
// internal data.
diff --git a/include/basegfx/polygon/b3dpolypolygon.hxx b/include/basegfx/polygon/b3dpolypolygon.hxx
index ea47e332f63b..9e3472dbb74c 100644
--- a/include/basegfx/polygon/b3dpolypolygon.hxx
+++ b/include/basegfx/polygon/b3dpolypolygon.hxx
@@ -38,7 +38,7 @@ namespace basegfx
class BASEGFX_DLLPUBLIC B3DPolyPolygon
{
public:
- typedef o3tl::cow_wrapper< ImplB3DPolyPolygon > ImplType;
+ typedef o3tl::cow_wrapper< ImplB3DPolyPolygon, o3tl::ThreadSafeRefCountingPolicy > ImplType;
private:
ImplType mpPolyPolygon;
diff --git a/include/drawinglayer/processor3d/zbufferprocessor3d.hxx b/include/drawinglayer/processor3d/zbufferprocessor3d.hxx
index 8e3f6d4f3ac1..0f58a7f1f0ab 100644
--- a/include/drawinglayer/processor3d/zbufferprocessor3d.hxx
+++ b/include/drawinglayer/processor3d/zbufferprocessor3d.hxx
@@ -56,7 +56,7 @@ namespace drawinglayer
{
private:
/// the raster target, a Z-Buffer
- basegfx::BZPixelRaster* mpBZPixelRaster;
+ basegfx::BZPixelRaster& mrBZPixelRaster;
/// inverse of EyeToView for rasterconversion with evtl. Phong shading
basegfx::B3DHomMatrix maInvEyeToView;
@@ -74,6 +74,9 @@ namespace drawinglayer
*/
std::vector< RasterPrimitive3D >* mpRasterPrimitive3Ds;
+ sal_uInt32 mnStartLine;
+ sal_uInt32 mnStopLine;
+
// rasterconversions for filled and non-filled polygons
virtual void rasterconvertB3DPolygon(const attribute::MaterialAttribute3D& rMaterial, const basegfx::B3DPolygon& rHairline) const override;
@@ -82,19 +85,18 @@ namespace drawinglayer
public:
ZBufferProcessor3D(
const geometry::ViewInformation3D& rViewInformation3D,
- const geometry::ViewInformation2D& rViewInformation2D,
const attribute::SdrSceneAttribute& rSdrSceneAttribute,
const attribute::SdrLightingAttribute& rSdrLightingAttribute,
- double fSizeX,
- double fSizeY,
const basegfx::B2DRange& rVisiblePart,
- sal_uInt16 nAntiAlialize);
+ sal_uInt16 nAntiAlialize,
+ double fFullViewSizeX,
+ double fFullViewSizeY,
+ basegfx::BZPixelRaster& rBZPixelRaster,
+ sal_uInt32 nStartLine,
+ sal_uInt32 nStopLine);
virtual ~ZBufferProcessor3D();
void finish();
-
- /// get the result as bitmapEx
- BitmapEx getBitmapEx() const;
};
}
}