summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Mohrhard <markus.mohrhard@collabora.co.uk>2014-07-11 05:34:41 +0200
committerMarkus Mohrhard <markus.mohrhard@collabora.co.uk>2014-07-12 04:38:45 +0200
commit664fb35ab522c40d298012922f059f6d48006355 (patch)
tree106e10c8ba3f44762d5215fa12eb218ba25cfa3c
parentb75f6baa3ae3c9c505068c5e4fc50bf261a43253 (diff)
first part for threaded chart rendering, fdo#81110
It is nor working correctly yet. Change-Id: Ic592eb2f50265886ad6d97539d2c52d7c45179e6
-rw-r--r--chart2/source/view/charttypes/GL3DBarChart.cxx267
-rw-r--r--chart2/source/view/inc/GL3DBarChart.hxx20
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<opengl3D::Renderable3DObject>::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<css::chart2::XChartType>& 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<VDataSeries>& rDataSeriesContainer)
void GL3DBarChart::create3DShapes(const boost::ptr_vector<VDataSeries>& 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<VDataSeries>& 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<opengl3D::Renderable3DObject>::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<RenderThread>(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<RenderThread>(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<sal_uInt32, const BarInformation>::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<opengl3D::ScreenText*>(&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<RenderThread>(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<opengl3D::ScreenText*>(&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<RenderThread>(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 <vcl/timer.hxx>
#include <vcl/openglwin.hxx>
+#include <rtl/ref.hxx>
+#include <salhelper/thread.hxx>
+
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<css::chart2::XChartType>& 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<css::chart2::XChartType> mxChartType;
boost::ptr_vector<opengl3D::Renderable3DObject> 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<RenderThread> mpRenderThread;
};
}