sd/qa/unit/tiledrendering/data/anim.odp |binary sd/qa/unit/tiledrendering/tiledrendering.cxx | 174 +++++++++++++++++++++++++- sd/source/ui/inc/SlideshowLayerRenderer.hxx | 35 +---- sd/source/ui/tools/SlideshowLayerRenderer.cxx | 26 ++- 4 files changed, 203 insertions(+), 32 deletions(-)
New commits: commit dfb779ff7689fc31b7e6bd27ea87a2074c2bdfd3 Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Mon Sep 9 18:14:16 2024 +0200 Commit: Szymon Kłos <szymon.k...@collabora.com> CommitDate: Mon Nov 25 09:21:54 2024 +0100 lok: slideshow: render animated objects as separate layers don't merge animated and non-animated objects on single layer Signed-off-by: Szymon Kłos <szymon.k...@collabora.com> Change-Id: I259507e08c95c3662e60f7691646395d1a840465 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173084 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177228 Tested-by: Jenkins diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx index 8289d539c639..72fc3894dd2d 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -3011,9 +3011,9 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"group\": \"MasterPage\"") >= 0); CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"index\": 1") >= 0); - CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"hash\"") >= 0); - CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"initVisible\": true") >= 0); - CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"type\": \"animated\"") >= 0); + CPPUNIT_ASSERT_EQUAL(-1, rJsonMsg.indexOf(u"\"hash\"")); + CPPUNIT_ASSERT_EQUAL(-1, rJsonMsg.indexOf(u"\"initVisible\"")); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"type\": \"bitmap\"") >= 0); CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"content\": { \"type\": \"%IMAGETYPE%\", \"checksum\": \"%IMAGECHECKSUM%\"}") >= 0); debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, rJsonMsg.toUtf8().getStr()); @@ -3030,6 +3030,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"index\": 0") >= 0); CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"hash\"") >= 0); CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"type\": \"animated\"") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"initVisible\": true") >= 0); CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"content\": { \"type\": \"%IMAGETYPE%\", \"checksum\": \"%IMAGECHECKSUM%\"}") >= 0); debugWriteImageToFile(3, pBuffer, nViewWidth, nViewHeight, rJsonMsg.toUtf8().getStr()); @@ -3062,6 +3063,138 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati pXImpressDocument->postSlideshowCleanup(); } +CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animations2) +{ + SdXImpressDocument* pXImpressDocument = createDoc("anim.odp"); + pXImpressDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>()); + sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell(); + CPPUNIT_ASSERT(pViewShell); + SdPage* pPage = pViewShell->GetActualPage(); + CPPUNIT_ASSERT(pPage); + sal_Int32 nViewWidth = 2000; + sal_Int32 nViewHeight = 2000; + CPPUNIT_ASSERT(pXImpressDocument->createSlideRenderer(0, nViewWidth, nViewHeight, true, true)); + CPPUNIT_ASSERT_EQUAL(2000, nViewWidth); + CPPUNIT_ASSERT_EQUAL(1125, nViewHeight); + + { + std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); + bool bIsBitmapLayer = false; + OUString rJsonMsg; + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg)); + CPPUNIT_ASSERT(bIsBitmapLayer); + + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"group\": \"Background\"") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"index\": 0") >= 0); + CPPUNIT_ASSERT_EQUAL(-1, rJsonMsg.indexOf(u"\"hash\"")); + CPPUNIT_ASSERT_EQUAL(-1, rJsonMsg.indexOf(u"\"initVisible\"")); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"type\": \"bitmap\"") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"content\": { \"type\": \"%IMAGETYPE%\", \"checksum\": \"%IMAGECHECKSUM%\"}") >= 0); + + debugWriteImageToFile(0, pBuffer, nViewWidth, nViewHeight, rJsonMsg.toUtf8().getStr()); + } + + { + std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); + bool bIsBitmapLayer = false; + OUString rJsonMsg; + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg)); + CPPUNIT_ASSERT(bIsBitmapLayer); + + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"group\": \"MasterPage\"") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"index\": 0") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"type\": \"bitmap\"") >= 0); + + debugWriteImageToFile(1, pBuffer, nViewWidth, nViewHeight, rJsonMsg.toUtf8().getStr()); + } + + { + std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); + bool bIsBitmapLayer = false; + OUString rJsonMsg; + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg)); + CPPUNIT_ASSERT(bIsBitmapLayer); + + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"group\": \"MasterPage\"") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"index\": 1") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"type\": \"bitmap\"") >= 0); + + debugWriteImageToFile(2, pBuffer, nViewWidth, nViewHeight, rJsonMsg.toUtf8().getStr()); + } + + { + std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); + bool bIsBitmapLayer = false; + OUString rJsonMsg; + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg)); + CPPUNIT_ASSERT(bIsBitmapLayer); + + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"group\": \"DrawPage\"") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"index\": 0") >= 0); + CPPUNIT_ASSERT_EQUAL(-1, rJsonMsg.indexOf(u"\"initVisible\"")); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"type\": \"bitmap\"") >= 0); + + debugWriteImageToFile(3, pBuffer, nViewWidth, nViewHeight, rJsonMsg.toUtf8().getStr()); + } + + { + std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); + bool bIsBitmapLayer = false; + OUString rJsonMsg; + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg)); + CPPUNIT_ASSERT(bIsBitmapLayer); + + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"group\": \"DrawPage\"") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"index\": 1") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"initVisible\": true") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"type\": \"animated\"") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"type\": \"bitmap\"") >= 0); + + debugWriteImageToFile(4, pBuffer, nViewWidth, nViewHeight, rJsonMsg.toUtf8().getStr()); + } + + { + std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); + bool bIsBitmapLayer = false; + OUString rJsonMsg; + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg)); + CPPUNIT_ASSERT(bIsBitmapLayer); + + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"group\": \"DrawPage\"") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"index\": 2") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"initVisible\": true") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"type\": \"animated\"") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"type\": \"bitmap\"") >= 0); + + debugWriteImageToFile(5, pBuffer, nViewWidth, nViewHeight, rJsonMsg.toUtf8().getStr()); + } + + { + std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); + bool bIsBitmapLayer = false; + OUString rJsonMsg; + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg)); + CPPUNIT_ASSERT(bIsBitmapLayer); + + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"group\": \"DrawPage\"") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"index\": 3") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"initVisible\": true") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"type\": \"animated\"") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"type\": \"bitmap\"") >= 0); + + debugWriteImageToFile(6, pBuffer, nViewWidth, nViewHeight, rJsonMsg.toUtf8().getStr()); + } + + { + std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); + bool bIsBitmapLayer = false; + OUString rJsonMsg; + CPPUNIT_ASSERT(pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg)); + } + + pXImpressDocument->postSlideshowCleanup(); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx b/sd/source/ui/tools/SlideshowLayerRenderer.cxx index d9bb1ce41045..54ad8d0a98e6 100644 --- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx +++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx @@ -117,6 +117,7 @@ public: { if (mrRenderState.meStage == RenderStage::Background) { + mrRenderState.mbPassHasOutput = true; mrRenderState.mbSkipAllInThisPass = true; return; } @@ -134,8 +135,6 @@ public: if (pPage == nullptr) return; - mrRenderState.mpCurrentTarget = pObject; - // is the object visible and not hidden by any option const bool bVisible = pObject->getSdrPageFromSdrObject()->checkVisibility(rOriginal, rDisplayInfo, true); @@ -166,6 +165,9 @@ public: if (mrRenderState.isObjectInAnimation(pObject)) { + if (!mrRenderState.mbFirstObjectInPass) + return; + mrRenderState.mbSkipAllInThisPass = true; } @@ -177,6 +179,8 @@ public: return; } + mrRenderState.mpCurrentTarget = pObject; + // render the object sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence( rOriginal, rDisplayInfo, rVisitor); commit 505775873fb715ef4e60a88927fd73b5e96b0b6d Author: Szymon Kłos <szymon.k...@collabora.com> AuthorDate: Mon Sep 9 17:34:03 2024 +0200 Commit: Szymon Kłos <szymon.k...@collabora.com> CommitDate: Mon Nov 25 09:21:47 2024 +0100 lok: slideshow: render background as separate layer we still take color from the JSON Change-Id: I6b83cc8aaaa3e9127d85ec06589bac7ed4472f71 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173083 Reviewed-by: Marco Cecchetti <marco.cecche...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177227 Tested-by: Jenkins Reviewed-by: Szymon Kłos <szymon.k...@collabora.com> diff --git a/sd/qa/unit/tiledrendering/data/anim.odp b/sd/qa/unit/tiledrendering/data/anim.odp new file mode 100644 index 000000000000..b508d48f8a43 Binary files /dev/null and b/sd/qa/unit/tiledrendering/data/anim.odp differ diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx index f3a21c08eb06..8289d539c639 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -2793,6 +2793,15 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering) CPPUNIT_ASSERT_EQUAL(1125, nViewHeight); const Color aTransparentColor(ColorAlpha, 0x00000000); + + // Background Layer - TODO + { + std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); + bool bIsBitmapLayer = false; + OUString rJsonMsg; + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg)); + } + { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; @@ -2863,6 +2872,15 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_WithFie CPPUNIT_ASSERT_EQUAL(1125, nViewHeight); const Color aTransparentColor(ColorAlpha, 0x00000000); + + // Background Layer - TODO + { + std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); + bool bIsBitmapLayer = false; + OUString rJsonMsg; + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg)); + } + { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; @@ -2950,6 +2968,23 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testSlideshowLayeredRendering_Animati CPPUNIT_ASSERT_EQUAL(2000, nViewWidth); CPPUNIT_ASSERT_EQUAL(1125, nViewHeight); + { + std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); + bool bIsBitmapLayer = false; + OUString rJsonMsg; + CPPUNIT_ASSERT(!pXImpressDocument->renderNextSlideLayer(pBuffer.data(), bIsBitmapLayer, rJsonMsg)); + CPPUNIT_ASSERT(bIsBitmapLayer); + + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"group\": \"Background\"") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"index\": 0") >= 0); + CPPUNIT_ASSERT_EQUAL(-1, rJsonMsg.indexOf(u"\"hash\"")); + CPPUNIT_ASSERT_EQUAL(-1, rJsonMsg.indexOf(u"\"initVisible\"")); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"type\": \"bitmap\"") >= 0); + CPPUNIT_ASSERT(rJsonMsg.indexOf(u"\"content\": { \"type\": \"%IMAGETYPE%\", \"checksum\": \"%IMAGECHECKSUM%\"}") >= 0); + + debugWriteImageToFile(0, pBuffer, nViewWidth, nViewHeight, rJsonMsg.toUtf8().getStr()); + } + { std::vector<sal_uInt8> pBuffer(nViewWidth * nViewHeight * 4); bool bIsBitmapLayer = false; diff --git a/sd/source/ui/inc/SlideshowLayerRenderer.hxx b/sd/source/ui/inc/SlideshowLayerRenderer.hxx index 760d771470ba..5555ea8300e4 100644 --- a/sd/source/ui/inc/SlideshowLayerRenderer.hxx +++ b/sd/source/ui/inc/SlideshowLayerRenderer.hxx @@ -28,22 +28,24 @@ struct RenderContext; enum class RenderStage { + Background, Master, - Slide + Slide, + TextFields, + Count }; /** Holds rendering state, properties and switches through all rendering passes */ struct RenderState { - RenderStage meStage = RenderStage::Master; + RenderStage meStage = RenderStage::Background; - sal_Int32 mnMasterIndex = 0; bool mbStopRenderingWhenField = true; std::unordered_set<SdrObject*> maObjectsDone; std::unordered_set<SdrObject*> maInAnimation; std::map<SdrObject*, bool> maInitiallyVisible; - sal_Int32 mnIndex = 0; + sal_Int32 mnIndex[static_cast<unsigned>(RenderStage::Count)] = { 0, 0, 0, 0 }; SdrObject* mpCurrentTarget = nullptr; bool mbFirstObjectInPass = true; @@ -53,29 +55,22 @@ struct RenderState sal_Int32 mnCurrentPass = 0; /// increments index depending on the current render stage - void incrementIndex() - { - if (meStage == RenderStage::Master) - mnMasterIndex++; - else - mnIndex++; - } + void incrementIndex() { mnIndex[static_cast<unsigned>(meStage)]++; } /// returns the current stage as string OString stageString() const { if (meStage == RenderStage::Master) return "MasterPage"_ostr; + else if (meStage == RenderStage::Background) + return "Background"_ostr; + else if (meStage == RenderStage::TextFields) + return "TextFields"_ostr; return "DrawPage"_ostr; } /// returns the current index depending on the current render stage - sal_Int32 currentIndex() const - { - if (meStage == RenderStage::Master) - return mnMasterIndex; - return mnIndex; - } + sal_Int32 currentIndex() const { return mnIndex[static_cast<unsigned>(meStage)]; } /// returns the current target element for which layer is created if any SdrObject* currentTarget() const { return mpCurrentTarget; } @@ -97,11 +92,7 @@ struct RenderState } /// should include background in rendering - bool includeBackground() const - { - // include background only if we are rendering the first pass - return mnCurrentPass == 0; - } + bool includeBackground() const { return meStage == RenderStage::Background; } bool isObjectAlreadyRendered(SdrObject* pObject) const { diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx b/sd/source/ui/tools/SlideshowLayerRenderer.cxx index 1b09c8cccd24..d9bb1ce41045 100644 --- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx +++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx @@ -115,6 +115,12 @@ public: const sdr::contact::DisplayInfo& rDisplayInfo, drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) override { + if (mrRenderState.meStage == RenderStage::Background) + { + mrRenderState.mbSkipAllInThisPass = true; + return; + } + if (mrRenderState.mbSkipAllInThisPass) return; @@ -202,11 +208,7 @@ SlideshowLayerRenderer::SlideshowLayerRenderer(SdrPage& rPage) : mrPage(rPage) , mrModel(rPage.getSdrModelFromSdrPage()) { - if (!hasEmptyMaster(rPage)) - maRenderState.meStage = RenderStage::Master; - else - maRenderState.meStage = RenderStage::Slide; - + maRenderState.meStage = RenderStage::Background; setupAnimations(); } @@ -399,6 +401,12 @@ bool SlideshowLayerRenderer::render(unsigned char* pBuffer, OString& rJsonMsg) maRenderState.mnCurrentPass++; + if (maRenderState.meStage == RenderStage::Background) + maRenderState.meStage = RenderStage::Master; + + if (hasEmptyMaster(mrPage)) + maRenderState.meStage = RenderStage::Slide; + return true; }