diff options
Diffstat (limited to 'drawinglayer/source/primitive2d/sceneprimitive2d.cxx')
-rw-r--r-- | drawinglayer/source/primitive2d/sceneprimitive2d.cxx | 115 |
1 files changed, 87 insertions, 28 deletions
diff --git a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx index d371cdedcd5c..11807e459b7f 100644 --- a/drawinglayer/source/primitive2d/sceneprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/sceneprimitive2d.cxx @@ -24,6 +24,7 @@ #include <drawinglayer/attribute/sdrlightattribute3d.hxx> #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> #include <drawinglayer/primitive2d/PolygonHairlinePrimitive2D.hxx> +#include <drawinglayer/primitive2d/groupprimitive2d.hxx> #include <processor3d/zbufferprocessor3d.hxx> #include <processor3d/shadow3dextractor.hxx> #include <drawinglayer/geometry/viewinformation2d.hxx> @@ -31,9 +32,12 @@ #include <svtools/optionsdrawinglayer.hxx> #include <processor3d/geometry2dextractor.hxx> #include <basegfx/raster/bzpixelraster.hxx> +#include <utility> #include <vcl/BitmapTools.hxx> #include <comphelper/threadpool.hxx> +#include <comphelper/lok.hxx> #include <toolkit/helper/vclunohelper.hxx> +#include <officecfg/Office/Common.hxx> using namespace com::sun::star; @@ -209,8 +213,9 @@ namespace drawinglayer::primitive2d } } - void ScenePrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& rViewInformation) const + Primitive2DReference ScenePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const { + Primitive2DContainer aContainer; // create 2D shadows from contained 3D primitives. This creates the shadow primitives on demand and tells if // there are some or not. Do this at start, the shadow might still be visible even when the scene is not if(impGetShadow3D()) @@ -223,7 +228,7 @@ namespace drawinglayer::primitive2d if(aViewRange.isEmpty() || aShadow2DRange.overlaps(aViewRange)) { // add extracted 2d shadows (before 3d scene creations itself) - rContainer.insert(rContainer.end(), maShadowPrimitives.begin(), maShadowPrimitives.end()); + aContainer.append(maShadowPrimitives); } } @@ -235,13 +240,13 @@ namespace drawinglayer::primitive2d calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange); if(aVisibleDiscreteRange.isEmpty()) - return; + return new GroupPrimitive2D(std::move(aContainer)); // test if discrete view size (pixel) maybe too big and limit it double fViewSizeX(aVisibleDiscreteRange.getWidth()); double fViewSizeY(aVisibleDiscreteRange.getHeight()); const double fViewVisibleArea(fViewSizeX * fViewSizeY); - const double fMaximumVisibleArea(SvtOptionsDrawinglayer::GetQuadratic3DRenderLimit()); + const double fMaximumVisibleArea(officecfg::Office::Common::Drawinglayer::Quadratic3DRenderLimit::get()); double fReduceFactor(1.0); if(fViewVisibleArea > fMaximumVisibleArea) @@ -279,7 +284,7 @@ namespace drawinglayer::primitive2d // determine the oversample value static const sal_uInt16 nDefaultOversampleValue(3); - const sal_uInt16 nOversampleValue(SvtOptionsDrawinglayer::IsAntiAliasing() ? nDefaultOversampleValue : 0); + sal_uInt16 nOversampleValue(SvtOptionsDrawinglayer::IsAntiAliasing() ? nDefaultOversampleValue : 0); geometry::ViewInformation3D aViewInformation3D(getViewInformation3D()); { @@ -351,15 +356,65 @@ namespace drawinglayer::primitive2d const double fLogicY((aInverseOToV * basegfx::B2DVector(0.0, aDiscreteRange.getHeight() * fReduceFactor)).getLength()); // generate ViewSizes - const double fFullViewSizeX((rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(fLogicX, 0.0)).getLength()); - const double fFullViewSizeY((rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(0.0, fLogicY)).getLength()); + double fFullViewSizeX((rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(fLogicX, 0.0)).getLength()); + double fFullViewSizeY((rViewInformation.getObjectToViewTransformation() * basegfx::B2DVector(0.0, fLogicY)).getLength()); // generate RasterWidth and RasterHeight for visible part - const sal_Int32 nRasterWidth(basegfx::fround(fFullViewSizeX * aUnitVisibleRange.getWidth()) + 1); - const sal_Int32 nRasterHeight(basegfx::fround(fFullViewSizeY * aUnitVisibleRange.getHeight()) + 1); + sal_Int32 nRasterWidth(basegfx::fround(fFullViewSizeX * aUnitVisibleRange.getWidth()) + 1); + sal_Int32 nRasterHeight(basegfx::fround(fFullViewSizeY * aUnitVisibleRange.getHeight()) + 1); + + if(!rViewInformation.getReducedDisplayQuality() && comphelper::LibreOfficeKit::isActive()) + { + // for this purpose allow reduced 3D quality and make a compromise + // between quality and speed. This is balanced between those two + // targets, fine-tuning/experimenting can be done with the values + // below. + + // define some values which allow fine-tuning this feature + static const double fMin(80.0); + static const double fSqareMin(fMin * fMin); + static const double fMax(800.0); + static const double fSqareMax(fMax * fMax); + static const double fMaxReduction(0.65); + + // get the square pixels (work on pixel numbers to get same + // behaviour independent of width/height relations) + const double fSquarePixels(nRasterWidth * nRasterHeight); + + if (fSquarePixels > fSqareMin) + { + // only reduce at all when more than fSqareMin pixels needed + double fReduction(fMaxReduction); + + if (fSquarePixels < fSqareMax) + { + // range between fSqareMin and fSqareMax, calculate a + // linear interpolated reduction based on square root + fReduction = sqrt(fSquarePixels); // [fMin .. fMax] + fReduction = fReduction - fMin; // [0 .. (fMax - fMin)] + fReduction = fReduction / (fMax - fMin); // [0 .. 1] + fReduction = 1.0 - (fReduction * (1.0 - fMaxReduction)); // [1 .. fMaxReduction] + + // reduce oversampling for this range + if(nOversampleValue > 2) + nOversampleValue--; + } + else + { + // more than fSqareMax pixels, disable oversampling + nOversampleValue = 0; + } + + // adapt needed values to reduction + nRasterWidth = basegfx::fround(fReduction * nRasterWidth); + nRasterHeight = basegfx::fround(fReduction * nRasterHeight); + fFullViewSizeX *= fReduction; + fFullViewSizeY *= fReduction; + } + } if(!(nRasterWidth && nRasterHeight)) - return; + return new GroupPrimitive2D(std::move(aContainer)); // create view unit buffer basegfx::BZPixelRaster aBZPixelRaster( @@ -367,7 +422,7 @@ namespace drawinglayer::primitive2d nOversampleValue ? nRasterHeight * nOversampleValue : nRasterHeight); // check for parallel execution possibilities - static bool bMultithreadAllowed = false; // loplugin:constvars:ignore + static bool bMultithreadAllowed = true; // loplugin:constvars:ignore sal_Int32 nThreadCount(0); comphelper::ThreadPool& rThreadPool(comphelper::ThreadPool::getSharedOptimalPool()); @@ -455,7 +510,7 @@ namespace drawinglayer::primitive2d const Size aBitmapSizePixel(maOldRenderedBitmap.GetSizePixel()); if(!(aBitmapSizePixel.getWidth() && aBitmapSizePixel.getHeight())) - return; + return new GroupPrimitive2D(std::move(aContainer)); // create transform for the created bitmap in discrete coordinates first. basegfx::B2DHomMatrix aNew2DTransform; @@ -469,9 +524,9 @@ namespace drawinglayer::primitive2d aNew2DTransform *= aInverseOToV; // create bitmap primitive and add - rContainer.push_back( + aContainer.push_back( new BitmapPrimitive2D( - VCLUnoHelper::CreateVCLXBitmap(maOldRenderedBitmap), + maOldRenderedBitmap, aNew2DTransform)); // test: Allow to add an outline in the debugger when tests are needed @@ -481,8 +536,9 @@ namespace drawinglayer::primitive2d { basegfx::B2DPolygon aOutline(basegfx::utils::createUnitPolygon()); aOutline.transform(aNew2DTransform); - rContainer.push_back(new PolygonHairlinePrimitive2D(aOutline, basegfx::BColor(1.0, 0.0, 0.0))); + aContainer.push_back(new PolygonHairlinePrimitive2D(std::move(aOutline), basegfx::BColor(1.0, 0.0, 0.0))); } + return new GroupPrimitive2D(std::move(aContainer)); } Primitive2DContainer ScenePrimitive2D::getGeometry2D() const @@ -561,20 +617,23 @@ namespace drawinglayer::primitive2d } ScenePrimitive2D::ScenePrimitive2D( - const primitive3d::Primitive3DContainer& rxChildren3D, - const attribute::SdrSceneAttribute& rSdrSceneAttribute, - const attribute::SdrLightingAttribute& rSdrLightingAttribute, - const basegfx::B2DHomMatrix& rObjectTransformation, - const geometry::ViewInformation3D& rViewInformation3D) - : mxChildren3D(rxChildren3D), - maSdrSceneAttribute(rSdrSceneAttribute), - maSdrLightingAttribute(rSdrLightingAttribute), - maObjectTransformation(rObjectTransformation), - maViewInformation3D(rViewInformation3D), + primitive3d::Primitive3DContainer aChildren3D, + attribute::SdrSceneAttribute aSdrSceneAttribute, + attribute::SdrLightingAttribute aSdrLightingAttribute, + basegfx::B2DHomMatrix aObjectTransformation, + geometry::ViewInformation3D aViewInformation3D) + : BufferedDecompositionPrimitive2D(), + mxChildren3D(std::move(aChildren3D)), + maSdrSceneAttribute(std::move(aSdrSceneAttribute)), + maSdrLightingAttribute(std::move(aSdrLightingAttribute)), + maObjectTransformation(std::move(aObjectTransformation)), + maViewInformation3D(std::move(aViewInformation3D)), mbShadow3DChecked(false), mfOldDiscreteSizeX(0.0), mfOldDiscreteSizeY(0.0) { + // activate callback to flush buffered decomposition content + setCallbackSeconds(45); } bool ScenePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const @@ -628,7 +687,7 @@ namespace drawinglayer::primitive2d bool bNeedNewDecomposition(false); bool bDiscreteSizesAreCalculated(false); - if(!getBuffered2DDecomposition().empty()) + if(getBuffered2DDecomposition()) { basegfx::B2DRange aVisibleDiscreteRange; calculateDiscreteSizes(rViewInformation, aDiscreteRange, aVisibleDiscreteRange, aUnitVisibleRange); @@ -656,10 +715,10 @@ namespace drawinglayer::primitive2d if(bNeedNewDecomposition) { // conditions of last local decomposition have changed, delete - const_cast< ScenePrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DContainer()); + const_cast< ScenePrimitive2D* >(this)->setBuffered2DDecomposition(nullptr); } - if(getBuffered2DDecomposition().empty()) + if(!getBuffered2DDecomposition()) { if(!bDiscreteSizesAreCalculated) { |