Kaydet (Commit) 664fb35a authored tarafından Markus Mohrhard's avatar Markus Mohrhard

first part for threaded chart rendering, fdo#81110

It is nor working correctly yet.

Change-Id: Ic592eb2f50265886ad6d97539d2c52d7c45179e6
üst b75f6baa
......@@ -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;
}
......
......@@ -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;
};
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment