WIP on canvas pixel shading

This commit is contained in:
Michaël Lemaire 2014-08-18 12:17:16 +02:00
parent fb3d32baf4
commit 2aeecdec62
24 changed files with 317 additions and 83 deletions

View file

@ -99,3 +99,8 @@ void CanvasPixel::updateComposite()
} }
composite = result; composite = result;
} }
void CanvasPixel::setComposite(const Color &color)
{
composite = color;
}

View file

@ -22,11 +22,13 @@ public:
inline int getFragmentCount() const {return count;} inline int getFragmentCount() const {return count;}
inline const Color &getComposite() const {return composite;} inline const Color &getComposite() const {return composite;}
inline const CanvasFragment &getFragment(int position) const {return fragments[position];}
const CanvasFragment *getFrontFragment() const; const CanvasFragment *getFrontFragment() const;
void reset(); void reset();
void pushFragment(const CanvasFragment &fragment); void pushFragment(const CanvasFragment &fragment);
void updateComposite(); void updateComposite();
void setComposite(const Color &color);
private: private:
int count; int count;

View file

@ -0,0 +1,36 @@
#include "CanvasPixelShader.h"
#include "Color.h"
#include "SoftwareCanvasRenderer.h"
#include "CanvasPortion.h"
#include "CanvasPixel.h"
#include "CanvasFragment.h"
#include "Rasterizer.h"
CanvasPixelShader::CanvasPixelShader(const SoftwareCanvasRenderer &renderer, CanvasPortion *portion, int chunk_size, int chunks_x, int chunks_y):
renderer(renderer), portion(portion), chunk_size(chunk_size), chunks_x(chunks_x), chunks_y(chunks_y)
{
}
int CanvasPixelShader::processParallelUnit(int unit)
{
// Locate the chunk we work on
int chunk_x = unit % chunks_x;
int chunk_y = unit / chunks_x;
// Resolve the pixel color
int x = chunk_x * chunk_size;
int y = chunk_y * chunk_size;
const CanvasPixel &pixel = portion->at(x, y);
int n = pixel.getFragmentCount();
Color composite = COLOR_BLACK;
for (int i = 0; i < n; i++)
{
const CanvasFragment &fragment = pixel.getFragment(i);
const Rasterizer &rasterizer = renderer.getRasterizer(fragment.getClient());
composite.mask(rasterizer.shadeFragment(fragment));
}
portion->setColor(x, y, composite);
return 0;
}

View file

@ -0,0 +1,36 @@
#ifndef CANVASPIXELSHADER_H
#define CANVASPIXELSHADER_H
#include "software_global.h"
#include "ParallelWorker.h"
namespace paysages {
namespace software {
/**
* @brief Parallel worker that can work on canvas portion to resolve pixel colors.
*
* This is used after the rasterization phase to compute pixel colors from the fragments stored in them.
*
* This worker will be set to work on a given chunk of a canvas portion.
*/
class CanvasPixelShader: public ParallelWorker
{
public:
CanvasPixelShader(const SoftwareCanvasRenderer &renderer, CanvasPortion *portion, int chunk_size, int chunks_x, int chunks_y);
virtual int processParallelUnit(int unit);
private:
const SoftwareCanvasRenderer &renderer;
CanvasPortion *portion;
int chunk_size;
int chunks_x;
int chunks_y;
};
}
}
#endif // CANVASPIXELSHADER_H

View file

@ -69,3 +69,25 @@ void CanvasPortion::pushFragment(int x, int y, const CanvasFragment &fragment)
preview->pushPixel(x, y, old_color, pixel.getComposite()); preview->pushPixel(x, y, old_color, pixel.getComposite());
} }
} }
const CanvasPixel &CanvasPortion::at(int x, int y)
{
CHECK_COORDINATES();
return pixels[y * width + x];
}
void CanvasPortion::setColor(int x, int y, const Color &color)
{
CHECK_COORDINATES();
CanvasPixel &pixel = pixels[y * width + x];
Color old_color = pixel.getComposite();
pixel.setComposite(color);
if (preview)
{
preview->pushPixel(x, y, old_color, pixel.getComposite());
}
}

View file

@ -7,7 +7,7 @@ namespace paysages {
namespace software { namespace software {
/** /**
* @brief Rectangular portion of a Canvas. * Rectangular portion of a Canvas.
* *
* Contains the pixels of a canvas region (CanvasPixel). * Contains the pixels of a canvas region (CanvasPixel).
*/ */
@ -26,12 +26,26 @@ public:
void setSize(int width, int height); void setSize(int width, int height);
/** /**
* @brief Add a fragment to the pixel located at (x, y). * Add a fragment to the pixel located at (x, y).
* *
* Checking x and y coordinates to be in the canvas portion should be done before this call. * Checking x and y coordinates to be in the canvas portion should be done before this call.
*/ */
void pushFragment(int x, int y, const CanvasFragment &fragment); void pushFragment(int x, int y, const CanvasFragment &fragment);
/**
* Get the CanvasPixel at a given coordinates.
*
* Checking x and y coordinates to be in the canvas portion should be done before this call.
*/
const CanvasPixel &at(int x, int y);
/**
* Change the final color of the pixel.
*
* Checking x and y coordinates to be in the canvas portion should be done before this call.
*/
void setColor(int x, int y, const Color &color);
private: private:
int width; int width;
int height; int height;

View file

@ -136,10 +136,6 @@ void Rasterizer::pushDisplacedQuad(CanvasPortion *canvas, const Vector3 &v1, con
pushDisplacedTriangle(canvas, v4, v1, v3, ov4, ov1, ov3); pushDisplacedTriangle(canvas, v4, v1, v3, ov4, ov1, ov3);
} }
void Rasterizer::rasterizeToCanvas(CanvasPortion *)
{
}
void Rasterizer::scanGetDiff(ScanPoint* v1, ScanPoint* v2, ScanPoint* result) void Rasterizer::scanGetDiff(ScanPoint* v1, ScanPoint* v2, ScanPoint* result)
{ {
result->pixel.x = v2->pixel.x - v1->pixel.x; result->pixel.x = v2->pixel.x - v1->pixel.x;
@ -316,25 +312,35 @@ void Rasterizer::renderScanLines(CanvasPortion *canvas, RenderScanlines* scanlin
current.x = x; current.x = x;
for (cury = starty; cury <= endy; cury++) for (cury = starty; cury <= endy; cury++)
{ {
fy = (double)cury + 0.5; if (dy == 0)
if (fy < down.pixel.y)
{ {
fy = down.pixel.y; // Down and up are the same
current = down;
} }
else if (fy > up.pixel.y) else
{ {
fy = up.pixel.y; fy = (double)cury + 0.5;
} if (fy < down.pixel.y)
fy = fy - down.pixel.y; {
fy = down.pixel.y;
}
else if (fy > up.pixel.y)
{
fy = up.pixel.y;
}
fy = fy - down.pixel.y;
current.y = cury; current.y = cury;
scanInterpolate(renderer->render_camera, &down, &diff, fy / dy, &current); scanInterpolate(renderer->render_camera, &down, &diff, fy / dy, &current);
}
CanvasFragment fragment(current.pixel.z, Vector3(current.location.x, current.location.y, current.location.z), current.client); CanvasFragment fragment(current.pixel.z, Vector3(current.location.x, current.location.y, current.location.z), current.client);
Color frag_color = *color; Color frag_color = *color;
if (cury == starty || cury == endy) if (cury == starty || cury == endy)
{
frag_color.mask(Color(0.0, 0.0, 0.0, 0.3)); frag_color.mask(Color(0.0, 0.0, 0.0, 0.3));
}
fragment.setColor(frag_color); fragment.setColor(frag_color);
canvas->pushFragment(current.x, current.y, fragment); canvas->pushFragment(current.x, current.y, fragment);

View file

@ -20,7 +20,8 @@ public:
inline SoftwareRenderer *getRenderer() const {return renderer;} inline SoftwareRenderer *getRenderer() const {return renderer;}
virtual void rasterizeToCanvas(CanvasPortion* canvas); virtual void rasterizeToCanvas(CanvasPortion* canvas) = 0;
virtual Color shadeFragment(const CanvasFragment &fragment) const = 0;
protected: protected:
void pushProjectedTriangle(CanvasPortion *canvas, const Vector3 &pixel1, const Vector3 &pixel2, const Vector3 &pixel3, const Vector3 &location1, const Vector3 &location2, const Vector3 &location3); void pushProjectedTriangle(CanvasPortion *canvas, const Vector3 &pixel1, const Vector3 &pixel2, const Vector3 &pixel3, const Vector3 &location1, const Vector3 &location2, const Vector3 &location3);

View file

@ -7,6 +7,7 @@
#include "AtmosphereResult.h" #include "AtmosphereResult.h"
#include "CloudsRenderer.h" #include "CloudsRenderer.h"
#include "Rasterizer.h" #include "Rasterizer.h"
#include "CanvasFragment.h"
#define SPHERE_SIZE 20000.0 #define SPHERE_SIZE 20000.0
@ -15,21 +16,6 @@ SkyRasterizer::SkyRasterizer(SoftwareRenderer* renderer, int client_id):
{ {
} }
static Color _postProcessFragment(SoftwareRenderer* renderer, const Vector3 &location, void*)
{
Vector3 camera_location, direction;
Color result;
camera_location = renderer->getCameraLocation(location);
direction = location.sub(camera_location);
/* TODO Don't compute result->color if it's fully covered by clouds */
result = renderer->getAtmosphereRenderer()->getSkyColor(direction.normalize()).final;
result = renderer->getCloudsRenderer()->getColor(camera_location, camera_location.add(direction.scale(10.0)), result);
return result;
}
void SkyRasterizer::rasterizeToCanvas(CanvasPortion* canvas) void SkyRasterizer::rasterizeToCanvas(CanvasPortion* canvas)
{ {
int res_i, res_j; int res_i, res_j;
@ -84,3 +70,19 @@ void SkyRasterizer::rasterizeToCanvas(CanvasPortion* canvas)
} }
} }
} }
Color SkyRasterizer::shadeFragment(const CanvasFragment &fragment) const
{
Vector3 location = fragment.getLocation();
Vector3 camera_location, direction;
Color result;
camera_location = renderer->getCameraLocation(location);
direction = location.sub(camera_location);
/* TODO Don't compute result->color if it's fully covered by clouds */
result = renderer->getAtmosphereRenderer()->getSkyColor(direction.normalize()).final;
result = renderer->getCloudsRenderer()->getColor(camera_location, camera_location.add(direction.scale(10.0)), result);
return result;
}

View file

@ -14,6 +14,7 @@ public:
SkyRasterizer(SoftwareRenderer* renderer, int client_id); SkyRasterizer(SoftwareRenderer* renderer, int client_id);
virtual void rasterizeToCanvas(CanvasPortion* canvas); virtual void rasterizeToCanvas(CanvasPortion* canvas);
virtual Color shadeFragment(const CanvasFragment &fragment) const;
}; };
} }

View file

@ -7,6 +7,9 @@
#include "WaterRasterizer.h" #include "WaterRasterizer.h"
#include "SkyRasterizer.h" #include "SkyRasterizer.h"
#include "CameraDefinition.h" #include "CameraDefinition.h"
#include "ParallelWork.h"
#include "CanvasPortion.h"
#include "CanvasPixelShader.h"
SoftwareCanvasRenderer::SoftwareCanvasRenderer() SoftwareCanvasRenderer::SoftwareCanvasRenderer()
{ {
@ -58,6 +61,11 @@ const std::vector<Rasterizer *> &SoftwareCanvasRenderer::getRasterizers() const
return rasterizers; return rasterizers;
} }
const Rasterizer &SoftwareCanvasRenderer::getRasterizer(int client_id) const
{
return *(getRasterizers()[client_id]);
}
void SoftwareCanvasRenderer::rasterize(CanvasPortion *portion, bool threaded) void SoftwareCanvasRenderer::rasterize(CanvasPortion *portion, bool threaded)
{ {
for (auto &rasterizer:getRasterizers()) for (auto &rasterizer:getRasterizers())
@ -68,5 +76,14 @@ void SoftwareCanvasRenderer::rasterize(CanvasPortion *portion, bool threaded)
void SoftwareCanvasRenderer::postProcess(CanvasPortion *portion, bool threaded) void SoftwareCanvasRenderer::postProcess(CanvasPortion *portion, bool threaded)
{ {
// TODO // Subdivide in chunks
int chunk_size = 32;
int chunks_x = portion->getWidth() / chunk_size + 1;
int chunks_y = portion->getHeight() / chunk_size + 1;
int units = chunks_x * chunks_y;
// Render chunks in parallel
CanvasPixelShader shader(*this, portion, chunk_size, chunks_x, chunks_y);
ParallelWork work(&shader, units);
work.perform();
} }

View file

@ -36,11 +36,16 @@ public:
*/ */
void render(); void render();
/*! /**
* \brief Get the list of objects that can be rasterized to polygons on a canvas. * @brief Get the list of objects that can be rasterized to polygons on a canvas.
*/ */
virtual const std::vector<Rasterizer*> &getRasterizers() const; virtual const std::vector<Rasterizer*> &getRasterizers() const;
/**
* Get a rasterizer by its client id.
*/
const Rasterizer &getRasterizer(int client_id) const;
protected: protected:
/** /**
* @brief Rasterize the scenery into a canvas portion. * @brief Rasterize the scenery into a canvas portion.

View file

@ -9,6 +9,7 @@
#include "Scenery.h" #include "Scenery.h"
#include "ParallelQueue.h" #include "ParallelQueue.h"
#include "CanvasPortion.h" #include "CanvasPortion.h"
#include "CanvasFragment.h"
TerrainRasterizer::TerrainRasterizer(SoftwareRenderer* renderer, int client_id): TerrainRasterizer::TerrainRasterizer(SoftwareRenderer* renderer, int client_id):
Rasterizer(renderer, client_id, Color(0.5, 0.3, 0.3)) Rasterizer(renderer, client_id, Color(0.5, 0.3, 0.3))
@ -20,12 +21,6 @@ static inline Vector3 _getPoint(SoftwareRenderer* renderer, double x, double z)
return Vector3(x, renderer->getTerrainRenderer()->getHeight(x, z, 1), z); return Vector3(x, renderer->getTerrainRenderer()->getHeight(x, z, 1), z);
} }
static Color _postProcessFragment(SoftwareRenderer* renderer, const Vector3 &point, void*)
{
double precision = renderer->getPrecision(_getPoint(renderer, point.x, point.z));
return renderer->getTerrainRenderer()->getFinalColor(point, precision);
}
void TerrainRasterizer::tessellateChunk(CanvasPortion* canvas, TerrainChunkInfo* chunk, int detail) void TerrainRasterizer::tessellateChunk(CanvasPortion* canvas, TerrainChunkInfo* chunk, int detail)
{ {
if (detail < 1) if (detail < 1)
@ -245,3 +240,10 @@ void TerrainRasterizer::rasterizeToCanvas(CanvasPortion *canvas)
queue->wait(); queue->wait();
} }
Color TerrainRasterizer::shadeFragment(const CanvasFragment &fragment) const
{
Vector3 point = fragment.getLocation();
double precision = renderer->getPrecision(_getPoint(renderer, point.x, point.z));
return renderer->getTerrainRenderer()->getFinalColor(point, precision);
}

View file

@ -51,6 +51,7 @@ public:
virtual void rasterize(); virtual void rasterize();
virtual void rasterizeToCanvas(CanvasPortion* canvas); virtual void rasterizeToCanvas(CanvasPortion* canvas);
virtual Color shadeFragment(const CanvasFragment &fragment) const;
private: private:
ParallelQueue* queue; ParallelQueue* queue;

View file

@ -3,17 +3,13 @@
#include "SoftwareRenderer.h" #include "SoftwareRenderer.h"
#include "WaterRenderer.h" #include "WaterRenderer.h"
#include "ParallelQueue.h" #include "ParallelQueue.h"
#include "CanvasFragment.h"
WaterRasterizer::WaterRasterizer(SoftwareRenderer* renderer, int client_id): WaterRasterizer::WaterRasterizer(SoftwareRenderer* renderer, int client_id):
Rasterizer(renderer, client_id, Color(0.1, 0.3, 0.6)) Rasterizer(renderer, client_id, Color(0.1, 0.3, 0.6))
{ {
} }
static Color _postProcessFragment(SoftwareRenderer* renderer, const Vector3 &location, void*)
{
return renderer->getWaterRenderer()->getResult(location.x, location.z).final;
}
static inline Vector3 _getFirstPassVertex(SoftwareRenderer* renderer, double x, double z) static inline Vector3 _getFirstPassVertex(SoftwareRenderer* renderer, double x, double z)
{ {
Vector3 result; Vector3 result;
@ -84,3 +80,9 @@ void WaterRasterizer::rasterizeToCanvas(CanvasPortion *canvas)
radius_ext += chunk_size; radius_ext += chunk_size;
} }
} }
Color WaterRasterizer::shadeFragment(const CanvasFragment &fragment) const
{
Vector3 location = fragment.getLocation();
return renderer->getWaterRenderer()->getResult(location.x, location.z).final;
}

View file

@ -16,6 +16,7 @@ public:
void rasterizeQuad(CanvasPortion* canvas, double x, double z, double size); void rasterizeQuad(CanvasPortion* canvas, double x, double z, double size);
virtual void rasterizeToCanvas(CanvasPortion* canvas); virtual void rasterizeToCanvas(CanvasPortion* canvas);
virtual Color shadeFragment(const CanvasFragment &fragment) const;
}; };
} }

View file

@ -45,7 +45,8 @@ SOURCES += SoftwareRenderer.cpp \
Rasterizer.cpp \ Rasterizer.cpp \
CanvasLiveClient.cpp \ CanvasLiveClient.cpp \
CanvasPreview.cpp \ CanvasPreview.cpp \
RenderConfig.cpp RenderConfig.cpp \
CanvasPixelShader.cpp
HEADERS += SoftwareRenderer.h\ HEADERS += SoftwareRenderer.h\
software_global.h \ software_global.h \
@ -80,7 +81,8 @@ HEADERS += SoftwareRenderer.h\
Rasterizer.h \ Rasterizer.h \
CanvasLiveClient.h \ CanvasLiveClient.h \
CanvasPreview.h \ CanvasPreview.h \
RenderConfig.h RenderConfig.h \
CanvasPixelShader.h
unix:!symbian { unix:!symbian {
maemo5 { maemo5 {

View file

@ -53,6 +53,7 @@ namespace software {
class CanvasFragment; class CanvasFragment;
class CanvasLiveClient; class CanvasLiveClient;
class CanvasPreview; class CanvasPreview;
class CanvasPixelShader;
} }
} }

View file

@ -2,37 +2,72 @@
#include "Thread.h" #include "Thread.h"
#include "System.h" #include "System.h"
#include "ParallelWorker.h"
#include <cassert> #include <cassert>
/**
* Compatibility class for code that uses ParallelUnitFunction.
*/
class ParallelWorkerCompat:public ParallelWorker
{
public:
ParallelWorkerCompat(ParallelWork *work, ParallelWork::ParallelUnitFunction func, void* data):
ParallelWorker(), work(work), func(func), data(data)
{
}
virtual int processParallelUnit(int unit)
{
return func(work, unit, data);
}
private:
ParallelWork* work;
ParallelWork::ParallelUnitFunction func;
void* data;
};
ParallelWork::ParallelWork(ParallelWorker *worker, int units)
{
this->units = units;
this->running = 0;
this->worker = worker;
this->worker_compat = false;
}
ParallelWork::ParallelWork(ParallelUnitFunction func, int units, void* data) ParallelWork::ParallelWork(ParallelUnitFunction func, int units, void* data)
{ {
this->units = units; this->units = units;
this->running = 0; this->running = 0;
this->unit_function = func; this->worker = new ParallelWorkerCompat(this, func, data);
this->data = data; this->worker_compat = true;
} }
ParallelWork::~ParallelWork() ParallelWork::~ParallelWork()
{ {
assert(not running); assert(not running);
if (worker_compat)
{
delete worker;
}
} }
static void* _workerThreadCallback(ParallelWork::ParallelWorker* worker) static void* _workerThreadCallback(ParallelWork::ParallelWorkerThread* thread)
{ {
worker->result = worker->work->unit_function(worker->work, worker->unit, worker->work->data); thread->result = thread->worker->processParallelUnit(thread->unit);
worker->status = ParallelWork::PARALLEL_WORKER_STATUS_DONE; thread->status = ParallelWork::PARALLEL_WORKER_STATUS_DONE;
return NULL; return NULL;
} }
static int _runNextWorker(ParallelWork::ParallelWorker workers[], int worker_count, int unit) static int _runNextWorker(ParallelWork::ParallelWorkerThread threads[], int thread_count, int unit)
{ {
int i; int i;
while (1) while (1)
{ {
for (i = 0; i < worker_count; i++) for (i = 0; i < thread_count; i++)
{ {
ParallelWork::ParallelWorker* worker = workers + i; ParallelWork::ParallelWorkerThread* worker = threads + i;
if (worker->status == ParallelWork::PARALLEL_WORKER_STATUS_VOID) if (worker->status == ParallelWork::PARALLEL_WORKER_STATUS_VOID)
{ {
worker->status = ParallelWork::PARALLEL_WORKER_STATUS_RUNNING; worker->status = ParallelWork::PARALLEL_WORKER_STATUS_RUNNING;
@ -62,47 +97,47 @@ static int _runNextWorker(ParallelWork::ParallelWorker workers[], int worker_cou
} }
} }
int ParallelWork::perform(int nbworkers) int ParallelWork::perform(int thread_count)
{ {
int i, done, result; int i, done, result;
assert(not running); assert(not running);
result = 0; result = 0;
if (nbworkers <= 0) if (thread_count <= 0)
{ {
nbworkers = System::getCoreCount(); thread_count = System::getCoreCount();
} }
if (nbworkers > PARALLEL_MAX_THREADS) if (thread_count > PARALLEL_MAX_THREADS)
{ {
nbworkers = PARALLEL_MAX_THREADS; thread_count = PARALLEL_MAX_THREADS;
} }
running = 1; running = 1;
/* Init workers */ /* Init workers */
for (i = 0; i < nbworkers; i++) for (i = 0; i < thread_count; i++)
{ {
workers[i].status = PARALLEL_WORKER_STATUS_VOID; threads[i].status = PARALLEL_WORKER_STATUS_VOID;
workers[i].work = this; threads[i].worker = worker;
} }
/* Perform run */ /* Perform run */
for (done = 0; done < units; done++) for (done = 0; done < units; done++)
{ {
if (_runNextWorker(workers, nbworkers, done)) if (_runNextWorker(threads, thread_count, done))
{ {
result++; result++;
} }
} }
/* Wait and clean up workers */ /* Wait and clean up workers */
for (i = 0; i < nbworkers; i++) for (i = 0; i < thread_count; i++)
{ {
if (workers[i].status != PARALLEL_WORKER_STATUS_VOID) if (threads[i].status != PARALLEL_WORKER_STATUS_VOID)
{ {
workers[i].thread->join(); threads[i].thread->join();
delete workers[i].thread; delete threads[i].thread;
if (workers[i].result) if (threads[i].result)
{ {
result++; result++;
} }

View file

@ -23,22 +23,24 @@ public:
typedef struct typedef struct
{ {
Thread* thread; Thread* thread;
ParallelWork* work; ParallelWorker* worker;
ParallelWorkerStatus status; ParallelWorkerStatus status;
int unit; int unit;
int result; int result;
} ParallelWorker; } ParallelWorkerThread;
public: public:
/** /**
* Create a parallel work handler. * Create a parallel work handler.
* *
* This will spawn an optimal number of threads to process a given number of work units. * This will spawn a number of threads.
*/
ParallelWork(ParallelWorker *worker, int units);
/**
* Create a parallel work handler.
* *
* @param func The callback that will be called from threads to process one unit. * This is a compatibility constructor for older code, use the constructor with ParallelWorker instead.
* @param units Number of units to handle.
* @param data Custom data that will be passed to the callback.
* @return The newly allocated handler.
*/ */
ParallelWork(ParallelUnitFunction func, int units, void* data); ParallelWork(ParallelUnitFunction func, int units, void* data);
@ -52,15 +54,15 @@ public:
/** /**
* Start working on the units. * Start working on the units.
* *
* @param workers Number of threads to spaws, -1 for an optimal number. * @param threads Number of threads to spaws, -1 for an optimal number.
*/ */
int perform(int workers=-1); int perform(int thread_count=-1);
int units; int units;
int running; int running;
ParallelUnitFunction unit_function; ParallelWorker *worker;
ParallelWorker workers[PARALLEL_MAX_THREADS]; bool worker_compat;
void* data; ParallelWorkerThread threads[PARALLEL_MAX_THREADS];
}; };
} }

View file

@ -0,0 +1,9 @@
#include "ParallelWorker.h"
ParallelWorker::ParallelWorker()
{
}
ParallelWorker::~ParallelWorker()
{
}

View file

@ -0,0 +1,29 @@
#ifndef PARALLELWORKER_H
#define PARALLELWORKER_H
#include "system_global.h"
namespace paysages {
namespace system {
/**
* @brief Worker that can be used by the ParallelWork object to perform tasks in several threads.
*/
class SYSTEMSHARED_EXPORT ParallelWorker
{
public:
ParallelWorker();
virtual ~ParallelWorker();
/**
* Abstract method to reimplement to process a work unit.
*
* This method will be called from any thread in the thread pool used by the ParallelWork.
*/
virtual int processParallelUnit(int unit) = 0;
};
}
}
#endif // PARALLELWORKER_H

View file

@ -25,7 +25,8 @@ SOURCES += \
CacheFile.cpp \ CacheFile.cpp \
PictureWriter.cpp \ PictureWriter.cpp \
Logs.cpp \ Logs.cpp \
ParallelPool.cpp ParallelPool.cpp \
ParallelWorker.cpp
HEADERS += \ HEADERS += \
system_global.h \ system_global.h \
@ -40,7 +41,8 @@ HEADERS += \
CacheFile.h \ CacheFile.h \
PictureWriter.h \ PictureWriter.h \
Logs.h \ Logs.h \
ParallelPool.h ParallelPool.h \
ParallelWorker.h
unix:!symbian { unix:!symbian {
maemo5 { maemo5 {

View file

@ -18,6 +18,7 @@ namespace system {
class ParallelQueue; class ParallelQueue;
class ParallelWork; class ParallelWork;
class ParallelPool; class ParallelPool;
class ParallelWorker;
class Thread; class Thread;
class Mutex; class Mutex;
} }