All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Public Member Functions | Friends
SciFigs::LayerPainter Class Reference

Brief description of class still missing. More...

#include <LayerPainter.h>

List of all members.

Public Member Functions

void clear (GraphContent *gc)
 LayerPainter ()
void paint (LayerPainterRequest *r)
int terminate (GraphContent *gc)
 ~LayerPainter ()

Friends

class LayerPainterThread

Detailed Description

Brief description of class still missing.

Full description of class still missing


Constructor & Destructor Documentation

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();
  }
}

Member Function Documentation

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());
}

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();
}

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;
}

Friends And Related Function Documentation

friend class LayerPainterThread [friend]

Referenced by LayerPainter().


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines