From 664fb35ab522c40d298012922f059f6d48006355 Mon Sep 17 00:00:00 2001 From: Markus Mohrhard Date: Fri, 11 Jul 2014 05:34:41 +0200 Subject: first part for threaded chart rendering, fdo#81110 It is nor working correctly yet. Change-Id: Ic592eb2f50265886ad6d97539d2c52d7c45179e6 --- chart2/source/view/charttypes/GL3DBarChart.cxx | 267 +++++++++++++++---------- chart2/source/view/inc/GL3DBarChart.hxx | 20 +- 2 files changed, 174 insertions(+), 113 deletions(-) diff --git a/chart2/source/view/charttypes/GL3DBarChart.cxx b/chart2/source/view/charttypes/GL3DBarChart.cxx index f80ea9976527..8ce235fb9dae 100644 --- a/chart2/source/view/charttypes/GL3DBarChart.cxx +++ b/chart2/source/view/charttypes/GL3DBarChart.cxx @@ -23,6 +23,108 @@ using namespace com::sun::star; namespace chart { +const size_t STEPS = 200; + +class RenderThread : public salhelper::Thread +{ +public: + RenderThread(GL3DBarChart* pChart); + +protected: + + void renderFrame(); + GL3DBarChart* mpChart; +}; + +RenderThread::RenderThread(GL3DBarChart* pChart): + salhelper::Thread("RenderThread"), + mpChart(pChart) +{ +} + +void RenderThread::renderFrame() +{ + if(!mpChart->mbValidContext) + return; + + mpChart->mrWindow.getContext().makeCurrent(); + Size aSize = mpChart->mrWindow.GetSizePixel(); + mpChart->mpRenderer->SetSize(aSize); + if(mpChart->mbNeedsNewRender) + { + for(boost::ptr_vector::iterator itr = mpChart->maShapes.begin(), + itrEnd = mpChart->maShapes.end(); itr != itrEnd; ++itr) + { + itr->render(); + } + } + else + { + mpChart->mpCamera->render(); + } + mpChart->mpRenderer->ProcessUnrenderedShape(mpChart->mbNeedsNewRender); + mpChart->mbNeedsNewRender = false; + mpChart->mrWindow.getContext().swapBuffers(); + +} + +class RenderOneFrameThread : public RenderThread +{ +public: + RenderOneFrameThread(GL3DBarChart* pChart): + RenderThread(pChart) + {} + +protected: + + virtual void execute() SAL_OVERRIDE; +}; + +void RenderOneFrameThread::execute() +{ + osl::MutexGuard aGuard(mpChart->maMutex); + renderFrame(); +} + +class RenderAnimationThread : public RenderThread +{ +public: + RenderAnimationThread(GL3DBarChart* pChart, const glm::vec3& rStartPos, const glm::vec3& rEndPos, + const sal_Int32 nSteps = STEPS): + RenderThread(pChart), + maStartPos(rStartPos), + maEndPos(rEndPos), + mnSteps(nSteps) + { + } + +protected: + + virtual void execute() SAL_OVERRIDE; + +private: + glm::vec3 maStartPos; + glm::vec3 maEndPos; + sal_Int32 mnSteps; + +}; + +void RenderAnimationThread::execute() +{ + osl::MutexGuard aGuard(mpChart->maMutex); + glm::vec3 aStep = (maEndPos - maStartPos)/(float)mnSteps; + for(sal_Int32 i = 0; i < mnSteps; ++i) + { + mpChart->maCameraPosition += aStep; + mpChart->mpCamera->setPosition(mpChart->maCameraPosition); + /* + mpChart->maCameraDirection += mpChart->maStepDirection; + mpChart->mpCamera->setDirection(mpChart->maCameraDirection); + */ + renderFrame(); + } +} + GL3DBarChart::GL3DBarChart( const css::uno::Reference& xChartType, OpenGLWindow& rWindow) : @@ -32,8 +134,6 @@ GL3DBarChart::GL3DBarChart( mpCamera(NULL), mbValidContext(true), mpTextCache(new opengl3D::TextCache()), - mnStep(0), - mnStepsTotal(0), mnMaxX(0), mnMaxY(0), mnDistance(0.0), @@ -59,6 +159,9 @@ GL3DBarChart::BarInformation::BarInformation(const glm::vec3& rPos, float nVal, GL3DBarChart::~GL3DBarChart() { + if(mpRenderThread.is()) + mpRenderThread->join(); + osl::MutexGuard aGuard(maMutex); if(mbValidContext) mrWindow.setRenderer(NULL); } @@ -67,7 +170,6 @@ namespace { const float TEXT_HEIGHT = 10.0f; float DEFAULT_CAMERA_HEIGHT = 500.0f; -const size_t STEPS = 200; const sal_uLong TIMEOUT = 5; const sal_uInt32 ID_STEP = 10; @@ -108,6 +210,7 @@ double findMaxValue(const boost::ptr_vector& rDataSeriesContainer) void GL3DBarChart::create3DShapes(const boost::ptr_vector& rDataSeriesContainer, ExplicitCategoriesProvider& rCatProvider) { + osl::MutexGuard aGuard(maMutex); mpRenderer->ReleaseShapes(); // Each series of data flows from left to right, and multiple series are // stacked vertically along y axis. @@ -297,35 +400,14 @@ void GL3DBarChart::create3DShapes(const boost::ptr_vector& rDataSer mbNeedsNewRender = true; } -void GL3DBarChart::render() +void GL3DBarChart::update() { - if(!mbValidContext) - return; - - mrWindow.getContext().makeCurrent(); + if(mpRenderThread.is()) + mpRenderThread->join(); Size aSize = mrWindow.GetSizePixel(); - mpRenderer->SetSize(aSize); mrWindow.getContext().setWinSize(aSize); - if(mbNeedsNewRender) - { - for(boost::ptr_vector::iterator itr = maShapes.begin(), - itrEnd = maShapes.end(); itr != itrEnd; ++itr) - { - itr->render(); - } - } - else - { - mpCamera->render(); - } - mpRenderer->ProcessUnrenderedShape(mbNeedsNewRender); - mbNeedsNewRender = false; - mrWindow.getContext().swapBuffers(); -} - -void GL3DBarChart::update() -{ - render(); + mpRenderThread = rtl::Reference(new RenderOneFrameThread(this)); + mpRenderThread->launch(); } namespace { @@ -352,26 +434,31 @@ public: void GL3DBarChart::moveToDefault() { - mnStepsTotal = STEPS; - mnStep = 0; - mbBlockUserInput = true; - glm::vec3 maTargetPosition = maDefaultCameraPosition; - maStep = (maTargetPosition - maCameraPosition)/((float)mnStepsTotal); + osl::MutexGuard aGuard(maMutex); + if(mpRenderThread.is()) + mpRenderThread->join(); + Size aSize = mrWindow.GetSizePixel(); + mrWindow.getContext().setWinSize(aSize); + mpRenderThread = rtl::Reference(new RenderAnimationThread(this, maCameraPosition, maDefaultCameraPosition, STEPS)); + mpRenderThread->launch(); + + /* + * TODO: moggi: add to thread glm::vec3 maTargetDirection = maDefaultCameraDirection; maStepDirection = (maTargetDirection - maCameraDirection)/((float)mnStepsTotal); - maTimer.SetTimeout(TIMEOUT); - maTimer.SetTimeoutHdl(LINK(this, GL3DBarChart, MoveToBar)); - maTimer.Start(); + */ } void GL3DBarChart::clickedAt(const Point& rPos, sal_uInt16 nButtons) { if(mbBlockUserInput) return; + if (nButtons == MOUSE_RIGHT) { moveToDefault(); + return; } if(nButtons != MOUSE_LEFT) @@ -380,10 +467,12 @@ void GL3DBarChart::clickedAt(const Point& rPos, sal_uInt16 nButtons) sal_uInt32 nId = 5; { PickingModeSetter aPickingModeSetter(mpRenderer.get()); - render(); + update(); + mpRenderThread->join(); nId = mpRenderer->GetPixelColorFromPoint(rPos.X(), rPos.Y()); } + osl::MutexGuard aGuard(maMutex); std::map::const_iterator itr = maBarMap.find(nId); @@ -393,30 +482,39 @@ void GL3DBarChart::clickedAt(const Point& rPos, sal_uInt16 nButtons) mbBlockUserInput = true; const BarInformation& rBarInfo = itr->second; - mnStepsTotal = STEPS; - mnStep = 0; - render(); + + if(mpRenderThread.is()) + mpRenderThread->join(); + + maShapes.push_back(new opengl3D::ScreenText(mpRenderer.get(), *mpTextCache, + OUString("Value: ") + OUString::number(rBarInfo.mnVal), 0)); + opengl3D::ScreenText* pScreenText = static_cast(&maShapes.back()); + pScreenText->setPosition(glm::vec2(-0.9f, 0.9f), glm::vec2(-0.6f, 0.8f)); + pScreenText->render(); glm::vec3 maTargetPosition = rBarInfo.maPos; maTargetPosition.z += 240; maTargetPosition.y += BAR_SIZE_Y / 2.0f; - maStep = (maTargetPosition - maCameraPosition)/((float)mnStepsTotal); + Size aSize = mrWindow.GetSizePixel(); + mrWindow.getContext().setWinSize(aSize); + mpRenderThread = rtl::Reference(new RenderAnimationThread(this, maCameraPosition, maTargetPosition, STEPS)); + mpRenderThread->launch(); + /* + * TODO: moggi: add to thread glm::vec3 maTargetDirection = rBarInfo.maPos; maTargetDirection.x += BAR_SIZE_X / 2.0f; maTargetDirection.y += BAR_SIZE_Y / 2.0f; maStepDirection = (maTargetDirection - maCameraDirection)/((float)mnStepsTotal); + */ - maTimer.SetTimeout(TIMEOUT); - maTimer.SetTimeoutHdl(LINK(this, GL3DBarChart, MoveToBar)); - maTimer.Start(); +} - maShapes.push_back(new opengl3D::ScreenText(mpRenderer.get(), *mpTextCache, - OUString("Value: ") + OUString::number(rBarInfo.mnVal), 0)); - opengl3D::ScreenText* pScreenText = static_cast(&maShapes.back()); - pScreenText->setPosition(glm::vec2(-0.9f, 0.9f), glm::vec2(-0.6f, 0.8f)); - pScreenText->render(); +void GL3DBarChart::render() +{ + osl::MutexGuard aGuard(maMutex); + update(); } void GL3DBarChart::mouseDragMove(const Point& rStartPos, const Point& rEndPos, sal_uInt16 ) @@ -473,76 +571,33 @@ glm::vec3 GL3DBarChart::getCornerPosition(sal_Int8 nId) void GL3DBarChart::moveToCorner() { - mnStepsTotal = STEPS; - maStep = (getCornerPosition(mnCornerId) - maCameraPosition) / float(mnStepsTotal); - - maStepDirection = (glm::vec3(mnMaxX/2.0f, mnMaxY/2.0f, 0) - maCameraDirection)/ float(mnStepsTotal); - maTimer.SetTimeout(TIMEOUT); - maTimer.SetTimeoutHdl(LINK(this, GL3DBarChart, MoveCamera)); - maTimer.Start(); -} - -IMPL_LINK_NOARG(GL3DBarChart, MoveCamera) -{ - maTimer.Stop(); - if(mnStep < mnStepsTotal) - { - ++mnStep; - maCameraPosition += maStep; - mpCamera->setPosition(maCameraPosition); - maCameraDirection += maStepDirection; - mpCamera->setDirection(maCameraDirection); - render(); - maTimer.SetTimeout(TIMEOUT); - maTimer.Start(); - } - else - { - mbBlockUserInput = false; - mnStep = 0; - } + osl::MutexGuard aGuard(maMutex); + if(mpRenderThread.is()) + mpRenderThread->join(); - return 0; -} - -IMPL_LINK_NOARG(GL3DBarChart, MoveToBar) -{ - maTimer.Stop(); - if(mnStep < mnStepsTotal) - { - ++mnStep; - maCameraPosition += maStep; - mpCamera->setPosition(maCameraPosition); - maCameraDirection += maStepDirection; - mpCamera->setDirection(maCameraDirection); - render(); - maTimer.SetTimeout(TIMEOUT); - maTimer.Start(); - } - else - { - maShapes.pop_back(); - mpRenderer->ReleaseScreenTextShapes(); - mbBlockUserInput = false; - mnStep = 0; - } + Size aSize = mrWindow.GetSizePixel(); + mrWindow.getContext().setWinSize(aSize); + mpRenderThread = rtl::Reference(new RenderAnimationThread(this, getCornerPosition(mnCornerId), + maCameraPosition, STEPS)); + mpRenderThread->launch(); - return 0; + // TODO: moggi: add to thread + // maStepDirection = (glm::vec3(mnMaxX/2.0f, mnMaxY/2.0f, 0) - maCameraDirection)/ float(mnStepsTotal); } void GL3DBarChart::scroll(long nDelta) { - if(mbBlockUserInput) - return; + osl::MutexGuard aGuard(maMutex); glm::vec3 maDir = glm::normalize(maCameraPosition - maCameraDirection); maCameraPosition -= (float((nDelta/10)) * maDir); mpCamera->setPosition(maCameraPosition); - render(); + update(); } void GL3DBarChart::contextDestroyed() { + osl::MutexGuard aGuard(maMutex); mbValidContext = false; } diff --git a/chart2/source/view/inc/GL3DBarChart.hxx b/chart2/source/view/inc/GL3DBarChart.hxx index b14de4622bb7..25176277f068 100644 --- a/chart2/source/view/inc/GL3DBarChart.hxx +++ b/chart2/source/view/inc/GL3DBarChart.hxx @@ -21,6 +21,9 @@ #include #include +#include +#include + namespace chart { class ExplicitCategoriesProvider; @@ -34,8 +37,15 @@ class Camera; } +class RenderThread; +class RenderOneFrameThread; +class RenderAnimationThread; + class GL3DBarChart : public GL3DPlotterBase, public IRenderer { + friend class RenderThread; + friend class RenderOneFrameThread; + friend class RenderAnimationThread; public: GL3DBarChart( const css::uno::Reference& xChartType, @@ -61,9 +71,6 @@ private: void moveToDefault(); glm::vec3 getCornerPosition(sal_Int8 nCornerId); - DECL_LINK(MoveCamera, void*); - DECL_LINK(MoveToBar, void*); - css::uno::Reference mxChartType; boost::ptr_vector maShapes; @@ -81,11 +88,7 @@ private: glm::vec3 maDefaultCameraPosition; glm::vec3 maDefaultCameraDirection; - Timer maTimer; - glm::vec3 maStep; glm::vec3 maStepDirection; - size_t mnStep; - size_t mnStepsTotal; float mnMaxX; float mnMaxY; float mnDistance; @@ -112,6 +115,9 @@ private: bool mbBlockUserInput; bool mbNeedsNewRender; bool mbCameraInit; + + osl::Mutex maMutex; + rtl::Reference mpRenderThread; }; } -- cgit