Brief description of class still missing. More...
#include <LayerPainter.h>
Public Member Functions | |
void | clear (GraphContent *gc) |
LayerPainter () | |
void | paint (LayerPainterRequest *r) |
int | terminate (GraphContent *gc) |
~LayerPainter () | |
Friends | |
class | LayerPainterThread |
Brief description of class still missing.
Full description of class still missing
Description of constructor still missing
References LayerPainterThread, QGpCoreTools::Thread::start(), and TRACE.
{ TRACE; // We ignore user specification for parallel jobs in this case // Forced to hardware maximum. int maximumThreads=QThread::idealThreadCount(); //int maximumThreads=1; if(maximumThreads<1) maximumThreads=1; // _threads is never modified in thread, only in main thread, hence no need for mutex for(int i=0; i<maximumThreads; i++) { LayerPainterThread * t=new LayerPainterThread(this); t->setObjectName(QString("layerPainter%1").arg(i+1)); _threads.append(t); t->start(QThread::LowestPriority); } }
Description of destructor still missing
References TRACE.
{ TRACE; _queueMutex.lock(); qDeleteAll(_queue); _queue.clear(); _queueMutex.unlock(); for(QList<LayerPainterThread *>::iterator it=_threads.begin(); it!=_threads.end(); it++) { (*it)->terminate(); } _paintEvent.wakeAll(); for(QList<LayerPainterThread *>::iterator it=_threads.begin(); it!=_threads.end(); it++) { (*it)->wait(); } }
void SciFigs::LayerPainter::clear | ( | GraphContent * | gc | ) |
Remove all requests corresponding to gc. This function blocks until effective termination of all paint requests attached to gc.
References SciFigs::LayerPainterRequest::graphContent(), and SciFigs::LayerPainterRequest::terminate().
Referenced by SciFigs::GraphContent::~GraphContent().
{ _queueMutex.lock(); // Clear the queue for any request corresponding to r for(int i=0; i<_queue.count(); i++) { LayerPainterRequest * oldRequest=_queue.at(i); if(gc==oldRequest->graphContent()) { delete oldRequest; _queue.removeAt(i); i--; } } // Terminate running request for(QList<LayerPainterThread *>::const_iterator it=_threads.begin(); it!=_threads.end(); it++) { LayerPainterRequest * request=(*it)->currentRequest(); if(request && request->graphContent()==gc) { request->terminate(); } } _queueMutex.unlock(); // Wait for proper termination QList<LayerPainterThread *>::const_iterator it; do { _queueMutex.lock(); for(it=_threads.begin(); it!=_threads.end(); it++) { LayerPainterRequest * request=(*it)->currentRequest(); if(request && request->graphContent()==gc) { break; } } _queueMutex.unlock(); App::sleep(10); //QWaitCondition } while(it!=_threads.end()); }
void SciFigs::LayerPainter::paint | ( | LayerPainterRequest * | r | ) |
Send a paint request. r must have the graphContent, layers, size, options, intermediate images and depth set up.
LayerPainterRequest * request=new LayerPainterRequest; request->setGraphContent(this); request->setLayers(_layers); request->setSize(size()); request->setOptions(_d); request->setLayerImages(_layerImages); request->setDepth(_paintDepth);
References SciFigs::LayerPainterRequest::depth(), SciFigs::LayerPainterRequest::graphContent(), SciFigs::LayerPainterRequest::paintText(), SciFigs::LayerPainterRequest::setDepth(), SciFigs::LayerPainterRequest::size(), SciFigs::LayerPainterRequest::terminate(), and TRACE.
{ TRACE; _queueMutex.lock(); // Check running requests, stop them asynchroneously for(QList<LayerPainterThread *>::iterator it=_threads.begin(); it!=_threads.end(); it++) { LayerPainterRequest * oldRequest=(*it)->currentRequest(); if(oldRequest && oldRequest->graphContent()==r->graphContent()) { if(oldRequest->depth()==r->depth() || oldRequest->size()!=r->size()) { oldRequest->terminate(); } } } // All requests found in the queue are not running, start from the request to be handled first for(int i=0; i<_queue.count(); i++) { LayerPainterRequest * oldRequest=_queue.at(i); if(r->graphContent()==oldRequest->graphContent()) { if(oldRequest->size()==r->size()) { if(oldRequest->depth()<r->depth()) { /* Old request has to repaint more layers. Because old request is still not running we inverse the priorities to accelerate rendering for the latest user request that requires less layers to be repainted. */ _queue[i]=r; r=oldRequest; } else if(oldRequest->depth()==r->depth()) { /* The old request and the new one will repaint the same layers. The old one will do useless job */ delete oldRequest; _queue.removeAt(i); i--; } /* Else leave the old request as it is. */ } else { /* Old request has not the correct size or options, remove it but keep its depth if less than new one */ if(oldRequest->depth()<r->depth()) { r->setDepth(oldRequest->depth()); } delete oldRequest; _queue.removeAt(i); i--; } } } _queue.enqueue(r); // Draw text for layers that contain text (text depends upon QFont which cannot be used in thread) // paintText is run from the main thread. // After unlock, the main paint request may start at any time and paintText must be finished. // textPaths created by paintText must be protected by specific mutex r->paintText(); //printf("--- painting request %p (%i)\n",r->graphContent(), _queue.count()); // Wake at least one thread. After timing measurements, this is the longest operation ??? _paintEvent.wakeOne(); // Unlock after wake up to avoid block of this thread _queueMutex.unlock(); }
int SciFigs::LayerPainter::terminate | ( | GraphContent * | gc | ) |
Terminate asynchroneously all paint requests attached to gc. Return the maximum depth of terminated requests or -1 if no request to terminate. This is designed so to be able to requeue the terminated request (with the latest parameters).
References SciFigs::LayerPainterRequest::depth(), SciFigs::LayerPainterRequest::graphContent(), SciFigs::LayerPainterRequest::terminate(), and TRACE.
Referenced by SciFigs::GraphContent::delayPainting(), and SciFigs::GraphContent::~GraphContent().
{ TRACE; int depth=-1; _queueMutex.lock(); for(QList<LayerPainterThread *>::iterator it=_threads.begin(); it!=_threads.end(); it++) { LayerPainterRequest * request=(*it)->currentRequest(); if(request && request->graphContent()==gc) { if(depth==-1 || depth>request->depth()) depth=request->depth(); request->terminate(); } } _queueMutex.unlock(); return depth; }
friend class LayerPainterThread [friend] |
Referenced by LayerPainter().