Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "trenderer.h"
Toshihiro Shimizu 890ddd
#include "trendererP.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
#include "tthread.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "tstopwatch.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "trenderresourcemanager.h"
Toshihiro Shimizu 890ddd
#include "tpredictivecachemanager.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qeventloop></qeventloop>
Toshihiro Shimizu 890ddd
#include <qcoreapplication></qcoreapplication>
Toshihiro Shimizu 890ddd
#include <qreadwritelock></qreadwritelock>
Toshihiro Shimizu 890ddd
#include <qreadlocker></qreadlocker>
Toshihiro Shimizu 890ddd
#include <qwritelocker></qwritelocker>
Toshihiro Shimizu 890ddd
#include <qthreadstorage></qthreadstorage>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "tcg/tcg_deleter_types.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Debug
Toshihiro Shimizu 890ddd
//#define DIAGNOSTICS
Toshihiro Shimizu 890ddd
//#include "diagnostics.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <queue></queue>
Toshihiro Shimizu 890ddd
#include <functional></functional>
Toshihiro Shimizu 890ddd
shun_iwasawa 7e52a2
#include <qoffscreensurface></qoffscreensurface>
shun_iwasawa 7e52a2
#include <qsurfaceformat></qsurfaceformat>
shun_iwasawa 7e52a2
#include <qopenglcontext></qopenglcontext>
shun_iwasawa 7e52a2
#include <qthread></qthread>
shun_iwasawa 7e52a2
#include <qguiapplication></qguiapplication>
shun_iwasawa 7e52a2
Toshihiro Shimizu 890ddd
using namespace TThread;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
std::vector<const *="" tfx=""> calculateSortedFxs(TRasterFxP rootFx);</const>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
//    Preliminaries - Anonymous namespace
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
// TRenderer-thread association storage. It provides TRenderers the per-thread
Shinya Kitaoka 120a6e
// singleton status from inside a rendering process.
Toshihiro Shimizu 890ddd
QThreadStorage<trendererimp **=""> rendererStorage;</trendererimp>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Same for render process ids.
Toshihiro Shimizu 890ddd
QThreadStorage<unsigned *="" long=""> renderIdsStorage;</unsigned>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Interlacing functions for field-based rendering
Shinya Kitaoka 120a6e
inline void interlace(TRasterP f0, const TRasterP &f1, int field) {
Shinya Kitaoka 120a6e
  if (f0->getPixelSize() != f1->getPixelSize())
Shinya Kitaoka 120a6e
    throw TException("interlace: invalid raster combination");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(f0->getBounds() == f1->getBounds());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int outWrapBytes  = f0->getWrap() * f0->getPixelSize();
Shinya Kitaoka 120a6e
  int inWrapBytes   = f1->getWrap() * f1->getPixelSize();
Shinya Kitaoka 120a6e
  int outWrapBytes2 = outWrapBytes * 2;
Shinya Kitaoka 120a6e
  int inWrapBytes2  = inWrapBytes * 2;
Shinya Kitaoka 120a6e
  int rowSize       = f0->getLx() * f0->getPixelSize();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  f1->lock();
Shinya Kitaoka 120a6e
  f0->lock();
Shinya Kitaoka 120a6e
  UCHAR *rowIn  = f1->getRawData();
Shinya Kitaoka 120a6e
  UCHAR *rowOut = f0->getRawData();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (field) rowIn += inWrapBytes;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int count = f0->getLy() / 2;
Shinya Kitaoka 120a6e
  while (--count) {
Shinya Kitaoka 120a6e
    memcpy(rowOut, rowIn, rowSize);
Shinya Kitaoka 120a6e
    rowIn += inWrapBytes2;
Shinya Kitaoka 120a6e
    rowOut += outWrapBytes2;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  f1->unlock();
Shinya Kitaoka 120a6e
  f0->unlock();
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
}  // anonymous namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
//    Preliminaries - output rasters management
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================
Toshihiro Shimizu 890ddd
//    RasterItem
Toshihiro Shimizu 890ddd
//-------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! The RasterItem class represents a reusable output raster for rendering
Shinya Kitaoka 120a6e
//! purposes.
Shinya Kitaoka 120a6e
//! RasterItems are used as TRenderer's output rasters in order to avoid the
Shinya Kitaoka 120a6e
//! overhead
Toshihiro Shimizu 890ddd
//! of allocating one raster for each rendered frame.
Shinya Kitaoka 120a6e
//! Each frame-rendering task will lock a RasterItem as preallocated output
Shinya Kitaoka 120a6e
//! before starting the
Toshihiro Shimizu 890ddd
//! render, therefore changing the \b RasterItem::m_busy attribute accordingly.
Shinya Kitaoka 120a6e
//! As each frame is rendered on a separate thread, the number of RasterItems
Shinya Kitaoka 120a6e
//! that
Shinya Kitaoka 120a6e
//! TRenderer will allocate depends on the number of rendering threads specified
Shinya Kitaoka 120a6e
//! to it.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! \sa RasterPool, TRenderer classes
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class RasterItem {
Shinya Kitaoka 120a6e
  std::string m_rasterId;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  int m_bpp;
Shinya Kitaoka 120a6e
  bool m_busy;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  //---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  RasterItem(const TDimension &size, int bpp, bool busyFlag)
Shinya Kitaoka 120a6e
      : m_rasterId(""), m_bpp(bpp), m_busy(busyFlag) {
Shinya Kitaoka 120a6e
    TRasterP raster;
Shinya Kitaoka 120a6e
    if (bpp == 32)
Shinya Kitaoka 120a6e
      raster = TRaster32P(size);
Shinya Kitaoka 120a6e
    else if (bpp == 64)
Shinya Kitaoka 120a6e
      raster = TRaster64P(size);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      assert(false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_rasterId = TImageCache::instance()->getUniqueId();
Shinya Kitaoka 120a6e
    TImageCache::instance()->add(m_rasterId, TRasterImageP(raster));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  //---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ~RasterItem() { TImageCache::instance()->remove(m_rasterId); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  //---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterP getRaster() const {
Shinya Kitaoka 120a6e
    TRasterImageP rimg =
Shinya Kitaoka 120a6e
        (TRasterImageP)TImageCache::instance()->get(m_rasterId, true);
Shinya Kitaoka 120a6e
    return rimg ? rimg->getRaster() : TRasterP();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  // not implemented
Shinya Kitaoka 120a6e
  RasterItem();
Shinya Kitaoka 120a6e
  RasterItem(const TRaster &RasterItem);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================
Toshihiro Shimizu 890ddd
//    RasterPool
Toshihiro Shimizu 890ddd
//-------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Stores a list of RasterItems under TRenderer's requests.
Shinya Kitaoka 120a6e
class RasterPool {
Shinya Kitaoka 120a6e
  TDimension m_size;
Shinya Kitaoka 120a6e
  int m_bpp;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  typedef std::list<rasteritem *=""> RasterRepository;</rasteritem>
Shinya Kitaoka 120a6e
  RasterRepository m_rasterRepository;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TThread::Mutex m_repositoryLock;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  RasterPool() : m_size(-1, -1) {}
Shinya Kitaoka 120a6e
  ~RasterPool();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void setRasterSpecs(const TDimension &size, int bpp);
Shinya Kitaoka 120a6e
  void getRasterSpecs(TDimension &size, int &bpp) {
Shinya Kitaoka 120a6e
    size = m_size;
Shinya Kitaoka 120a6e
    bpp  = m_bpp;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterP getRaster();
Shinya Kitaoka 120a6e
  TRasterP getRaster(const TDimension &size, int bpp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void releaseRaster(const TRasterP &r);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void clear();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RasterPool::clear() {
Shinya Kitaoka 120a6e
  QMutexLocker sl(&m_repositoryLock);
Shinya Kitaoka 120a6e
  clearPointerContainer(m_rasterRepository);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RasterPool::setRasterSpecs(const TDimension &size, int bpp) {
Shinya Kitaoka 120a6e
  if (size != m_size || bpp != m_bpp) {
Shinya Kitaoka 120a6e
    m_size = size;
Shinya Kitaoka 120a6e
    m_bpp  = bpp;
Shinya Kitaoka 120a6e
    clear();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRasterP RasterPool::getRaster(const TDimension &size, int bpp) {
Shinya Kitaoka 120a6e
  assert(size == m_size && bpp == m_bpp);
Shinya Kitaoka 120a6e
  return getRaster();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Returns for the first not-busy raster
Shinya Kitaoka 120a6e
TRasterP RasterPool::getRaster() {
Shinya Kitaoka 120a6e
  QMutexLocker sl(&m_repositoryLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  RasterRepository::iterator it = m_rasterRepository.begin();
Shinya Kitaoka 120a6e
  while (it != m_rasterRepository.end()) {
Shinya Kitaoka 120a6e
    RasterItem *rasItem = *it;
Shinya Kitaoka 120a6e
    if (rasItem->m_busy == false) {
Shinya Kitaoka 120a6e
      TRasterP raster = rasItem->getRaster();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (!raster) {
Shinya Kitaoka 120a6e
        delete rasItem;
Shinya Kitaoka 120a6e
        m_rasterRepository.erase(it++);
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      rasItem->m_busy = true;
Shinya Kitaoka 120a6e
      raster->clear();
Shinya Kitaoka 120a6e
      return raster;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ++it;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  RasterItem *rasItem = new RasterItem(m_size, m_bpp, true);
Shinya Kitaoka 120a6e
  m_rasterRepository.push_back(rasItem);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return rasItem->getRaster();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Cerca il raster \b r in m_rasterRepository; se lo trova setta a \b false il
Shinya Kitaoka 120a6e
//! campo \b m_busy.
Shinya Kitaoka 120a6e
void RasterPool::releaseRaster(const TRasterP &r) {
Shinya Kitaoka 120a6e
  if (!r) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QMutexLocker sl(&m_repositoryLock);
Shinya Kitaoka 120a6e
  for (RasterRepository::iterator it = m_rasterRepository.begin();
Shinya Kitaoka 120a6e
       it != m_rasterRepository.end(); ++it) {
Shinya Kitaoka 120a6e
    RasterItem *rasItem = *it;
Shinya Kitaoka 120a6e
    if (rasItem->getRaster()->getRawData() == r->getRawData()) {
Shinya Kitaoka 120a6e
      assert(rasItem->m_busy);
Shinya Kitaoka 120a6e
      rasItem->m_busy = false;
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
RasterPool::~RasterPool() {
Shinya Kitaoka 120a6e
  /*if (m_rasterRepository.size())
Shinya Kitaoka 120a6e
TSystem::outputDebug("~RasterPool: itemCount = " + toString
Shinya Kitaoka 120a6e
((int)m_rasterRepository.size())+" (should be 0)\n");*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Release all raster items
Shinya Kitaoka 120a6e
  clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
//    Internal rendering classes declaration
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=====================
Toshihiro Shimizu 890ddd
//    TRendererImp
Toshihiro Shimizu 890ddd
//---------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class TRendererImp final : public TSmartObject {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  struct RenderInstanceInfos {
Shinya Kitaoka 120a6e
    int m_canceled;
Shinya Kitaoka 120a6e
    int m_activeTasks;
Shinya Kitaoka 120a6e
    int m_status;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    RenderInstanceInfos()
Shinya Kitaoka 120a6e
        : m_canceled(false), m_activeTasks(0), m_status(TRenderer::IDLE) {}
Shinya Kitaoka 120a6e
  };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  typedef std::vector<trenderport *=""> PortContainer;</trenderport>
Shinya Kitaoka 120a6e
  typedef PortContainer::iterator PortContainerIterator;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QReadWriteLock m_portsLock;
Shinya Kitaoka 120a6e
  PortContainer m_ports;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QMutex m_renderInstancesMutex;
Shinya Kitaoka 120a6e
  std::map<unsigned long,="" renderinstanceinfos=""> m_activeInstances;</unsigned>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  //! The renderer Id is a number uniquely associated with a TRenderer instance.
Shinya Kitaoka 120a6e
  static unsigned long m_rendererIdCounter;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  //! The render Id is a number uniquely associated with a render process
Shinya Kitaoka 120a6e
  //! started
Shinya Kitaoka 120a6e
  //! with the startRendering() method.
Shinya Kitaoka 120a6e
  static unsigned long m_renderIdCounter;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  unsigned long m_rendererId;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Executor m_executor;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool m_precomputingEnabled;
Shinya Kitaoka 120a6e
  RasterPool m_rasterPool;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<trenderresourcemanager *=""> m_managers;</trenderresourcemanager>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TAtomicVar m_undoneTasks;
Shinya Kitaoka 120a6e
  // std::vector<qeventloop*> m_waitingLoops;</qeventloop*>
Shinya Kitaoka 120a6e
  std::vector<bool *=""> m_waitingLoops;</bool>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterFxP rootFx;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  //-------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRendererImp(int nThreads);
Shinya Kitaoka 120a6e
  ~TRendererImp();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void startRendering(unsigned long renderId,
Shinya Kitaoka 120a6e
                      const std::vector<trenderer::renderdata> &renderDatas);</trenderer::renderdata>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void notifyRasterStarted(const TRenderPort::RenderData &rd);
Shinya Kitaoka 120a6e
  void notifyRasterCompleted(const TRenderPort::RenderData &rd);
Shinya Kitaoka 120a6e
  void notifyRasterFailure(const TRenderPort::RenderData &rd, TException &e);
Shinya Kitaoka 120a6e
  void notifyRenderFinished(bool isCanceled = false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void addPort(TRenderPort *port);
Shinya Kitaoka 120a6e
  void removePort(TRenderPort *port);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void abortRendering(unsigned long renderId);
Shinya Kitaoka 120a6e
  void stopRendering(bool waitForCompleteStop);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool hasToDie(unsigned long renderId);
Shinya Kitaoka 120a6e
  int getRenderStatus(unsigned long renderId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void enablePrecomputing(bool on) { m_precomputingEnabled = on; }
Shinya Kitaoka 120a6e
  bool isPrecomputingEnabled() const { return m_precomputingEnabled; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void setThreadsCount(int nThreads) { m_executor.setMaxActiveTasks(nThreads); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  inline void declareRenderStart(unsigned long renderId);
Shinya Kitaoka 120a6e
  inline void declareRenderEnd(unsigned long renderId);
Shinya Kitaoka 120a6e
  inline void declareFrameStart(double frame);
Shinya Kitaoka 120a6e
  inline void declareFrameEnd(double frame);
Shinya Kitaoka 120a6e
  inline void declareStatusStart(int renderStatus);
Shinya Kitaoka 120a6e
  inline void declareStatusEnd(int renderStatus);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void quitWaitingLoops();
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
template class DVAPI TSmartPointerT<trendererimp>;</trendererimp>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef TSmartPointerT<trendererimp> TRendererImpP;</trendererimp>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
unsigned long TRendererImp::m_rendererIdCounter = 0;
Shinya Kitaoka 120a6e
unsigned long TRendererImp::m_renderIdCounter   = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================
Toshihiro Shimizu 890ddd
//    RenderTask
Toshihiro Shimizu 890ddd
//-------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class RenderTask final : public TThread::Runnable {
Shinya Kitaoka 120a6e
  std::vector<double> m_frames;</double>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  unsigned long m_taskId;
Shinya Kitaoka 120a6e
  unsigned long m_renderId;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRendererImpP m_rendererImp;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFxPair m_fx;
Shinya Kitaoka 120a6e
  TPointD m_framePos;
Shinya Kitaoka 120a6e
  TDimension m_frameSize;
Shinya Kitaoka 120a6e
  TRenderSettings m_info;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool m_fieldRender, m_stereoscopic;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Mutex m_rasterGuard;
Shinya Kitaoka 120a6e
  TTile m_tileA;  // in normal and field rendering, Rendered at given frame; in
Shinya Kitaoka 120a6e
                  // stereoscopic, rendered left frame
Shinya Kitaoka 120a6e
  TTile m_tileB;  // in  field rendering, rendered at frame + 0.5; in
Shinya Kitaoka 120a6e
                  // stereoscopic, rendered right frame
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  RenderTask(unsigned long renderId, unsigned long taskId, double frame,
Shinya Kitaoka 120a6e
             const TRenderSettings &ri, const TFxPair &fx,
Shinya Kitaoka 120a6e
             const TPointD &framePos, const TDimension &frameSize,
Shinya Kitaoka 120a6e
             const TRendererImpP &rendererImp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ~RenderTask() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void addFrame(double frame) { m_frames.push_back(frame); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void buildTile(TTile &tile);
Shinya Kitaoka 120a6e
  void releaseTiles();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void onFrameStarted();
Shinya Kitaoka 120a6e
  void onFrameCompleted();
Shinya Kitaoka 120a6e
  void onFrameFailed(TException &e);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void preRun();
Shinya Kitaoka 473e70
  void run() override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  int taskLoad() override { return 100; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void onFinished(TThread::RunnableP) override;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
//    Implementations
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================
Toshihiro Shimizu 890ddd
//    TRenderer
Toshihiro Shimizu 890ddd
//------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRenderer::TRenderer(int nThread) {
Shinya Kitaoka 120a6e
  m_imp = new TRendererImp(nThread);  // Already adds a ref
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRenderer::TRenderer(TRendererImp *imp) : m_imp(imp) {
Shinya Kitaoka 120a6e
  if (m_imp) m_imp->addRef();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRenderer::TRenderer(const TRenderer &r) : m_imp(r.m_imp) {
Shinya Kitaoka 120a6e
  if (m_imp) m_imp->addRef();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRenderer::operator=(const TRenderer &r) {
Shinya Kitaoka 120a6e
  m_imp = r.m_imp;
Shinya Kitaoka 120a6e
  if (m_imp) m_imp->addRef();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRenderer::~TRenderer() {
Shinya Kitaoka 120a6e
  if (m_imp) m_imp->release();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! The static method is intended for use inside a rendering thread only. It
Shinya Kitaoka 120a6e
//! returns
Toshihiro Shimizu 890ddd
//! a copy of the eventual TRenderer interface installed on the thread -
Toshihiro Shimizu 890ddd
//! or an empty TRenderer if none happened to be. It can be set using the
Toshihiro Shimizu 890ddd
//! install() and uninstall() methods.
Shinya Kitaoka 120a6e
TRenderer TRenderer::instance() {
Shinya Kitaoka 120a6e
  TRendererImp **lData = rendererStorage.localData();
Shinya Kitaoka 120a6e
  if (lData) return TRenderer(*lData);
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Returns the renderer id.
Shinya Kitaoka 120a6e
unsigned long TRenderer::rendererId() { return m_imp->m_rendererId; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Returns the rendering process id currently running on the invoking
Toshihiro Shimizu 890ddd
//! thread.
Shinya Kitaoka 120a6e
unsigned long TRenderer::renderId() {
Shinya Kitaoka 120a6e
  unsigned long *lData = renderIdsStorage.localData();
Shinya Kitaoka 120a6e
  return lData ? *lData : -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Builds and returns an id for starting a new rendering process.
Shinya Kitaoka 120a6e
unsigned long TRenderer::buildRenderId() {
Shinya Kitaoka 120a6e
  return TRendererImp::m_renderIdCounter++;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Returns the renderId that will be used by the next startRendering() call.
Toshihiro Shimizu 890ddd
//! This method can be used to retrieve the renderId of a rendering instance
Toshihiro Shimizu 890ddd
//! before it is actually started - provided that no other render instance
Toshihiro Shimizu 890ddd
//! is launched inbetween.
Shinya Kitaoka 120a6e
unsigned long TRenderer::nextRenderId() {
Shinya Kitaoka 120a6e
  return TRendererImp::m_renderIdCounter;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline void TRendererImp::declareRenderStart(unsigned long renderId) {
Shinya Kitaoka 120a6e
  // Inform the resource managers
Shinya Kitaoka 120a6e
  for (unsigned int i = 0; i < m_managers.size(); ++i)
Shinya Kitaoka 120a6e
    m_managers[i]->onRenderInstanceStart(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Declares that the render process of passed renderId is about to start.
Shinya Kitaoka 120a6e
void TRenderer::declareRenderStart(unsigned long renderId) {
Shinya Kitaoka 120a6e
  m_imp->declareRenderStart(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline void TRendererImp::declareRenderEnd(unsigned long renderId) {
Shinya Kitaoka 120a6e
  // Inform the resource managers
Shinya Kitaoka 120a6e
  for (int i = m_managers.size() - 1; i >= 0; --i)
Shinya Kitaoka 120a6e
    m_managers[i]->onRenderInstanceEnd(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Declares that the render process of passed renderId has ended.
Shinya Kitaoka 120a6e
void TRenderer::declareRenderEnd(unsigned long renderId) {
Shinya Kitaoka 120a6e
  m_imp->declareRenderEnd(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline void TRendererImp::declareFrameStart(double frame) {
Shinya Kitaoka 120a6e
  // Inform the resource managers
Shinya Kitaoka 120a6e
  for (unsigned int i = 0; i < m_managers.size(); ++i)
Shinya Kitaoka 120a6e
    m_managers[i]->onRenderFrameStart(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Declares that render of passed frame is about to start.
Shinya Kitaoka 120a6e
void TRenderer::declareFrameStart(double frame) {
Shinya Kitaoka 120a6e
  m_imp->declareFrameStart(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline void TRendererImp::declareFrameEnd(double frame) {
Shinya Kitaoka 120a6e
  // Inform the resource managers
Shinya Kitaoka 120a6e
  for (int i = m_managers.size() - 1; i >= 0; --i)
Shinya Kitaoka 120a6e
    m_managers[i]->onRenderFrameEnd(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Declares that render of passed has ended.
Shinya Kitaoka 120a6e
void TRenderer::declareFrameEnd(double frame) { m_imp->declareFrameEnd(frame); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline void TRendererImp::declareStatusStart(int renderStatus) {
Shinya Kitaoka 120a6e
  // Inform the resource managers
Shinya Kitaoka 120a6e
  for (unsigned int i = 0; i < m_managers.size(); ++i)
Shinya Kitaoka 120a6e
    m_managers[i]->onRenderStatusStart(renderStatus);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline void TRendererImp::declareStatusEnd(int renderStatus) {
Shinya Kitaoka 120a6e
  // Inform the resource managers
Shinya Kitaoka 120a6e
  for (int i = m_managers.size() - 1; i >= 0; --i)
Shinya Kitaoka 120a6e
    m_managers[i]->onRenderStatusEnd(renderStatus);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Installs the specified render process on the invoking thread.
Shinya Kitaoka 120a6e
void TRenderer::install(unsigned long renderId) {
Shinya Kitaoka 120a6e
  m_imp->addRef();
Shinya Kitaoka 120a6e
  rendererStorage.setLocalData(new (TRendererImp *)(m_imp));
Shinya Kitaoka 120a6e
  renderIdsStorage.setLocalData(new unsigned long(renderId));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Uninstalls any rendering process active on the invoking thread.
Shinya Kitaoka 120a6e
void TRenderer::uninstall() {
Shinya Kitaoka 120a6e
  rendererStorage.setLocalData(0);
Shinya Kitaoka 120a6e
  renderIdsStorage.setLocalData(0);
Shinya Kitaoka 120a6e
  m_imp->release();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRenderResourceManager *TRenderer::getManager(unsigned int id) const {
Shinya Kitaoka 120a6e
  return m_imp->m_managers[id];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRenderer::enablePrecomputing(bool on) { m_imp->enablePrecomputing(on); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRenderer::isPrecomputingEnabled() const {
Shinya Kitaoka 120a6e
  return m_imp->isPrecomputingEnabled();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRenderer::setThreadsCount(int nThreads) {
Shinya Kitaoka 120a6e
  m_imp->setThreadsCount(nThreads);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRenderer::addPort(TRenderPort *port) { m_imp->addPort(port); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRenderer::removePort(TRenderPort *port) { m_imp->removePort(port); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
unsigned long TRenderer::startRendering(double f, const TRenderSettings &info,
Shinya Kitaoka 120a6e
                                        const TFxPair &actualRoot) {
Shinya Kitaoka 120a6e
  assert(f >= 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<renderdata> *rds = new std::vector<renderdata>;</renderdata></renderdata>
Shinya Kitaoka 120a6e
  rds->push_back(RenderData(f, info, actualRoot));
Shinya Kitaoka 120a6e
  return startRendering(rds);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Queues a rendering event in the main event loop.
Shinya Kitaoka 120a6e
//! NOTE: The passed pointer is owned by the TRenderer after it is submitted for
Shinya Kitaoka 120a6e
//! rendering -
Toshihiro Shimizu 890ddd
//! do not delete it later.
Shinya Kitaoka 120a6e
unsigned long TRenderer::startRendering(
Shinya Kitaoka 120a6e
    const std::vector<renderdata> *renderDatas) {</renderdata>
Shinya Kitaoka 120a6e
  if (renderDatas->empty()) {
Shinya Kitaoka 120a6e
    delete renderDatas;
Shinya Kitaoka 120a6e
    return -1;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Build a new render Id
Shinya Kitaoka 120a6e
  unsigned long renderId = m_imp->m_renderIdCounter++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRendererStartInvoker::StartInvokerRenderData srd;
Shinya Kitaoka 120a6e
  srd.m_renderId         = renderId;
Shinya Kitaoka 120a6e
  srd.m_renderDataVector = renderDatas;
Shinya Kitaoka 120a6e
  TRendererStartInvoker::instance()->emitStartRender(m_imp, srd);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return renderId;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRenderer::abortRendering(unsigned long renderId) {
Shinya Kitaoka 120a6e
  m_imp->abortRendering(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRenderer::stopRendering(bool waitForCompleteStop) {
Shinya Kitaoka 120a6e
  m_imp->stopRendering(waitForCompleteStop);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRenderer::isAborted(unsigned long renderId) const {
Shinya Kitaoka 120a6e
  return m_imp->hasToDie(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TRenderer::getRenderStatus(unsigned long renderId) const {
Shinya Kitaoka 120a6e
  return m_imp->getRenderStatus(renderId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=====================
Toshihiro Shimizu 890ddd
//    TRendererImp
Toshihiro Shimizu 890ddd
//---------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRendererImp::TRendererImp(int nThreads)
Shinya Kitaoka 120a6e
    : m_executor()
Shinya Kitaoka 120a6e
    , m_undoneTasks()
Shinya Kitaoka 120a6e
    , m_rendererId(m_rendererIdCounter++)
Shinya Kitaoka 120a6e
    , m_precomputingEnabled(true) {
Shinya Kitaoka 120a6e
  m_executor.setMaxActiveTasks(nThreads);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<trenderresourcemanagergenerator *=""> &generators =</trenderresourcemanagergenerator>
Shinya Kitaoka 120a6e
      TRenderResourceManagerGenerator::generators(false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // May be adopted by other TRenderers from now on.
Shinya Kitaoka 120a6e
  addRef();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  rendererStorage.setLocalData(new (TRendererImp *)(this));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  unsigned int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < generators.size(); ++i) {
Shinya Kitaoka 120a6e
    TRenderResourceManager *manager = (*generators[i])();
Shinya Kitaoka 120a6e
    if (manager) m_managers.push_back(manager);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  rendererStorage.setLocalData(0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRendererImp::~TRendererImp() {
Shinya Kitaoka 120a6e
  rendererStorage.setLocalData(new (TRendererImp *)(this));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = m_managers.size() - 1; i >= 0; --i)
Shinya Kitaoka 120a6e
    if (m_managers[i]->renderHasOwnership()) delete m_managers[i];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  rendererStorage.setLocalData(0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRendererImp::addPort(TRenderPort *port) {
Shinya Kitaoka 120a6e
  QWriteLocker sl(&m_portsLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  PortContainerIterator it = std::find(m_ports.begin(), m_ports.end(), port);
Shinya Kitaoka 120a6e
  if (it == m_ports.end()) m_ports.push_back(port);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRendererImp::removePort(TRenderPort *port) {
Shinya Kitaoka 120a6e
  QWriteLocker sl(&m_portsLock);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  PortContainerIterator it = std::find(m_ports.begin(), m_ports.end(), port);
Shinya Kitaoka 120a6e
  if (it != m_ports.end()) m_ports.erase(it);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRendererImp::hasToDie(unsigned long renderId) {
Shinya Kitaoka 120a6e
  QMutexLocker sl(&m_renderInstancesMutex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<unsigned long,="" renderinstanceinfos="">::iterator it =</unsigned>
Shinya Kitaoka 120a6e
      m_activeInstances.find(renderId);
Shinya Kitaoka 120a6e
  assert(it != m_activeInstances.end());
Shinya Kitaoka 120a6e
  return it == m_activeInstances.end() ? true : it->second.m_canceled;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TRendererImp::getRenderStatus(unsigned long renderId) {
Shinya Kitaoka 120a6e
  QMutexLocker sl(&m_renderInstancesMutex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<unsigned long,="" renderinstanceinfos="">::iterator it =</unsigned>
Shinya Kitaoka 120a6e
      m_activeInstances.find(renderId);
Shinya Kitaoka 120a6e
  assert(it != m_activeInstances.end());
Shinya Kitaoka 120a6e
  return it == m_activeInstances.end() ? true : it->second.m_status;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRendererImp::abortRendering(unsigned long renderId) {
Shinya Kitaoka 120a6e
  QMutexLocker sl(&m_renderInstancesMutex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<unsigned long,="" renderinstanceinfos="">::iterator it =</unsigned>
Shinya Kitaoka 120a6e
      m_activeInstances.find(renderId);
Shinya Kitaoka 120a6e
  if (it != m_activeInstances.end()) it->second.m_canceled = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRendererImp::stopRendering(bool waitForCompleteStop) {
Shinya Kitaoka 120a6e
  QMutexLocker sl(&m_renderInstancesMutex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    // Tasks already stop rendering on their own when they don't find their
Shinya Kitaoka 120a6e
    // render ids here.
Shinya Kitaoka 120a6e
    std::map<unsigned long,="" renderinstanceinfos="">::iterator it;</unsigned>
Shinya Kitaoka 120a6e
    for (it = m_activeInstances.begin(); it != m_activeInstances.end(); ++it)
Shinya Kitaoka 120a6e
      it->second.m_canceled = true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (waitForCompleteStop && m_undoneTasks > 0) {
Shinya Kitaoka 120a6e
    // Sometimes, QEventLoop suddenly stops processing slots (especially those
Shinya Kitaoka 120a6e
    // notifications
Shinya Kitaoka 120a6e
    // from active rendering instances) - therefore resulting in a block of the
Shinya Kitaoka 120a6e
    // application.
Shinya Kitaoka 120a6e
    // I've not figured out why (#QTBUG-11649?) - but substituting with a plain
Shinya Kitaoka 120a6e
    // while
Shinya Kitaoka 120a6e
    // seems to do the trick...
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    /*QEventLoop eventLoop;
Shinya Kitaoka 120a6e
m_waitingLoops.push_back(&eventLoop);
Shinya Kitaoka 120a6e
eventLoop.exec();*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    bool loopQuit = false;
Shinya Kitaoka 120a6e
    m_waitingLoops.push_back(&loopQuit);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    sl.unlock();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    while (!loopQuit)
Shinya Kitaoka 120a6e
      QCoreApplication::processEvents(QEventLoop::AllEvents |
Shinya Kitaoka 120a6e
                                      QEventLoop::WaitForMoreEvents);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRendererImp::quitWaitingLoops() {
Shinya Kitaoka 120a6e
  // Make the stopRendering waiting loops quit
Shinya Kitaoka 120a6e
  while (!m_waitingLoops.empty()) {
Shinya Kitaoka 120a6e
    // rendererImp->m_waitingLoops.back()->quit();
Shinya Kitaoka 120a6e
    *m_waitingLoops.back() = true;
Shinya Kitaoka 120a6e
    m_waitingLoops.pop_back();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRendererImp::notifyRasterStarted(const TRenderPort::RenderData &rd) {
Shinya Kitaoka 120a6e
  // Since notifications may trigger port removals, we always work on a copy of
Shinya Kitaoka 120a6e
  // the ports
Shinya Kitaoka 120a6e
  // vector.
Shinya Kitaoka 120a6e
  TRendererImp::PortContainer portsCopy;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    QReadLocker sl(&m_portsLock);
Shinya Kitaoka 120a6e
    portsCopy = m_ports;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (PortContainerIterator it = portsCopy.begin(); it != portsCopy.end();
Shinya Kitaoka 120a6e
       ++it)
Shinya Kitaoka 120a6e
    (*it)->onRenderRasterStarted(rd);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRendererImp::notifyRasterCompleted(const TRenderPort::RenderData &rd) {
Shinya Kitaoka 120a6e
  TRendererImp::PortContainer portsCopy;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    QReadLocker sl(&m_portsLock);
Shinya Kitaoka 120a6e
    portsCopy = m_ports;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(rd.m_rasA);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (PortContainerIterator it = portsCopy.begin(); it != portsCopy.end();
Shinya Kitaoka 120a6e
       ++it)
Shinya Kitaoka 120a6e
    (*it)->onRenderRasterCompleted(rd);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRendererImp::notifyRasterFailure(const TRenderPort::RenderData &rd,
Shinya Kitaoka 120a6e
                                       TException &e) {
Shinya Kitaoka 120a6e
  TRendererImp::PortContainer portsCopy;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    QReadLocker sl(&m_portsLock);
Shinya Kitaoka 120a6e
    portsCopy = m_ports;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (PortContainerIterator it = portsCopy.begin(); it != portsCopy.end();
Shinya Kitaoka 120a6e
       ++it)
Shinya Kitaoka 120a6e
    (*it)->onRenderFailure(rd, e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRendererImp::notifyRenderFinished(bool isCanceled) {
Shinya Kitaoka 120a6e
  TRendererImp::PortContainer portsCopy;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    QReadLocker sl(&m_portsLock);
Shinya Kitaoka 120a6e
    portsCopy = m_ports;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  auto sortedFxs = calculateSortedFxs(rootFx);
Shinya Kitaoka 120a6e
  for (auto fx : sortedFxs) {
Shinya Kitaoka 120a6e
    if (fx) const_cast<tfx *="">(fx)->callEndRenderHandler();</tfx>
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (PortContainerIterator it = portsCopy.begin(); it != portsCopy.end();
Shinya Kitaoka 120a6e
       ++it)
Shinya Kitaoka 120a6e
    (*it)->onRenderFinished();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//====================
Toshihiro Shimizu 890ddd
//    TRenderPort
Toshihiro Shimizu 890ddd
//--------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRenderPort::TRenderPort() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRenderPort::~TRenderPort() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Setta \b m_renderArea a \b area e pulisce l'istanza corrente di \b
Shinya Kitaoka 120a6e
//! RasterPool.
Shinya Kitaoka 120a6e
void TRenderPort::setRenderArea(const TRectD &area) { m_renderArea = area; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Ritorna \b m_renderArea.
Shinya Kitaoka 120a6e
TRectD &TRenderPort::getRenderArea() { return m_renderArea; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================
Toshihiro Shimizu 890ddd
//    RenderTask
Toshihiro Shimizu 890ddd
//-------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
RenderTask::RenderTask(unsigned long renderId, unsigned long taskId,
Shinya Kitaoka 120a6e
                       double frame, const TRenderSettings &ri,
Shinya Kitaoka 120a6e
                       const TFxPair &fx, const TPointD &framePos,
Shinya Kitaoka 120a6e
                       const TDimension &frameSize,
Shinya Kitaoka 120a6e
                       const TRendererImpP &rendererImp)
Shinya Kitaoka 120a6e
    : m_renderId(renderId)
Shinya Kitaoka 120a6e
    , m_taskId(taskId)
Shinya Kitaoka 120a6e
    , m_info(ri)
Shinya Kitaoka 120a6e
    , m_fx(fx)
Shinya Kitaoka 120a6e
    , m_frameSize(frameSize)
Shinya Kitaoka 120a6e
    , m_framePos(framePos)
Shinya Kitaoka 120a6e
    , m_rendererImp(rendererImp)
Shinya Kitaoka 120a6e
    , m_fieldRender(ri.m_fieldPrevalence != TRenderSettings::NoField)
Shinya Kitaoka 120a6e
    , m_stereoscopic(ri.m_stereoscopic) {
Shinya Kitaoka 120a6e
  m_frames.push_back(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Connect the onFinished slot
Shinya Kitaoka 120a6e
  connect(this, SIGNAL(finished(TThread::RunnableP)), this,
Shinya Kitaoka 120a6e
          SLOT(onFinished(TThread::RunnableP)));
Shinya Kitaoka 120a6e
  connect(this, SIGNAL(exception(TThread::RunnableP)), this,
Shinya Kitaoka 120a6e
          SLOT(onFinished(TThread::RunnableP)));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // The shrink info is currently reversed to the settings'affine. Shrink info
Shinya Kitaoka 120a6e
  // in the TRenderSettings
Shinya Kitaoka 120a6e
  // is no longer supported.
Shinya Kitaoka 120a6e
  m_info.m_shrinkX = m_info.m_shrinkY = 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RenderTask::preRun() {
Shinya Kitaoka 120a6e
  TRectD geom(m_framePos, TDimensionD(m_frameSize.lx, m_frameSize.ly));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_fx.m_frameA) m_fx.m_frameA->dryCompute(geom, m_frames[0], m_info);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_fx.m_frameB)
Shinya Kitaoka 120a6e
    m_fx.m_frameB->dryCompute(
Shinya Kitaoka 120a6e
        geom, m_fieldRender ? m_frames[0] + 0.5 : m_frames[0], m_info);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RenderTask::run() {
Shinya Kitaoka 120a6e
  // Retrieve the task's frame
Shinya Kitaoka 120a6e
  assert(!m_frames.empty());
Shinya Kitaoka 120a6e
  double t = m_frames[0];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_rendererImp->hasToDie(m_renderId)) {
Shinya Kitaoka 120a6e
    TException e("Render task aborted");
Shinya Kitaoka 120a6e
    onFrameFailed(e);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Install the renderer in current thread
Shinya Kitaoka 120a6e
  rendererStorage.setLocalData(
Shinya Kitaoka 120a6e
      new (TRendererImp *)(m_rendererImp.getPointer()));
Shinya Kitaoka 120a6e
  renderIdsStorage.setLocalData(new unsigned long(m_renderId));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Inform the managers of frame start
Shinya Kitaoka 120a6e
  m_rendererImp->declareFrameStart(t);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  auto sortedFxs = calculateSortedFxs(m_fx.m_frameA);
Shinya Kitaoka 120a6e
  for (auto fx : sortedFxs) {
Shinya Kitaoka 120a6e
    if (fx) const_cast<tfx *="">(fx)->callStartRenderFrameHandler(&m_info, t);</tfx>
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    onFrameStarted();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TStopWatch::global(8).start();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!m_fieldRender && !m_stereoscopic) {
Shinya Kitaoka 120a6e
      // Common case - just build the first tile
Shinya Kitaoka 120a6e
      buildTile(m_tileA);
Shinya Kitaoka 120a6e
      /*-- 通常はここがFxのレンダリング処理 --*/
Shinya Kitaoka 120a6e
      m_fx.m_frameA->compute(m_tileA, t, m_info);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      assert(!(m_stereoscopic && m_fieldRender));
Shinya Kitaoka 120a6e
      // Field rendering  or stereoscopic case
Shinya Kitaoka 120a6e
      if (m_stereoscopic) {
Shinya Kitaoka 120a6e
        buildTile(m_tileA);
Shinya Kitaoka 120a6e
        m_fx.m_frameA->compute(m_tileA, t, m_info);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        buildTile(m_tileB);
Shinya Kitaoka 120a6e
        m_fx.m_frameB->compute(m_tileB, t, m_info);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      // if fieldPrevalence, Decide the rendering frames depending on field
Shinya Kitaoka 120a6e
      // prevalence
Shinya Kitaoka 120a6e
      else if (m_info.m_fieldPrevalence == TRenderSettings::EvenField) {
Shinya Kitaoka 120a6e
        buildTile(m_tileA);
Shinya Kitaoka 120a6e
        m_fx.m_frameA->compute(m_tileA, t, m_info);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        buildTile(m_tileB);
Shinya Kitaoka 120a6e
        m_fx.m_frameB->compute(m_tileB, t + 0.5, m_info);
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        buildTile(m_tileB);
Shinya Kitaoka 120a6e
        m_fx.m_frameA->compute(m_tileB, t, m_info);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        buildTile(m_tileA);
Shinya Kitaoka 120a6e
        m_fx.m_frameB->compute(m_tileA, t + 0.5, m_info);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TStopWatch::global(8).stop();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    onFrameCompleted();
Shinya Kitaoka 120a6e
  } catch (TException &e) {
Shinya Kitaoka 120a6e
    onFrameFailed(e);
Shinya Kitaoka 120a6e
  } catch (...) {
Shinya Kitaoka 120a6e
    TException ex("Unknown render exception");
Shinya Kitaoka 120a6e
    onFrameFailed(ex);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Inform the managers of frame end
Shinya Kitaoka 120a6e
  m_rendererImp->declareFrameEnd(t);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Uninstall the renderer from current thread
Shinya Kitaoka 120a6e
  rendererStorage.setLocalData(0);
Shinya Kitaoka 120a6e
  renderIdsStorage.setLocalData(0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (auto fx : sortedFxs) {
Shinya Kitaoka 120a6e
    if (fx) const_cast<tfx *="">(fx)->callEndRenderFrameHandler(&m_info, t);</tfx>
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RenderTask::buildTile(TTile &tile) {
Shinya Kitaoka 120a6e
  tile.m_pos = m_framePos;
Shinya Kitaoka 120a6e
  tile.setRaster(
Shinya Kitaoka 120a6e
      m_rendererImp->m_rasterPool.getRaster(m_frameSize, m_info.m_bpp));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RenderTask::releaseTiles() {
Shinya Kitaoka 120a6e
  m_rendererImp->m_rasterPool.releaseRaster(m_tileA.getRaster());
Shinya Kitaoka 120a6e
  m_tileA.setRaster(TRasterP());
Shinya Kitaoka 120a6e
  if (m_fieldRender || m_stereoscopic) {
Shinya Kitaoka 120a6e
    m_rendererImp->m_rasterPool.releaseRaster(m_tileB.getRaster());
Shinya Kitaoka 120a6e
    m_tileB.setRaster(TRasterP());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RenderTask::onFrameStarted() {
Shinya Kitaoka 120a6e
  TRenderPort::RenderData rd(m_frames, m_info, 0, 0, m_renderId, m_taskId);
Shinya Kitaoka 120a6e
  m_rendererImp->notifyRasterStarted(rd);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RenderTask::onFrameCompleted() {
Shinya Kitaoka 120a6e
  TRasterP rasA(m_tileA.getRaster());
Shinya Kitaoka 120a6e
  TRasterP rasB(m_tileB.getRaster());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_fieldRender) {
Shinya Kitaoka 120a6e
    assert(rasB);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    double t = m_frames[0];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int f = (m_info.m_fieldPrevalence == TRenderSettings::EvenField) ? 0 : 1;
Shinya Kitaoka 120a6e
    interlace(rasA, rasB, f);
Shinya Kitaoka 120a6e
    rasB = TRasterP();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRenderPort::RenderData rd(m_frames, m_info, rasA, rasB, m_renderId,
Shinya Kitaoka 120a6e
                             m_taskId);
Shinya Kitaoka 120a6e
  m_rendererImp->notifyRasterCompleted(rd);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RenderTask::onFrameFailed(TException &e) {
Shinya Kitaoka 120a6e
  // TRasterP evenRas(m_evenTile.getRaster());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRenderPort::RenderData rd(m_frames, m_info, m_tileA.getRaster(),
Shinya Kitaoka 120a6e
                             m_tileB.getRaster(), m_renderId, m_taskId);
Shinya Kitaoka 120a6e
  m_rendererImp->notifyRasterFailure(rd, e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RenderTask::onFinished(TThread::RunnableP) {
Shinya Kitaoka 120a6e
  TRendererImp *rendererImp = m_rendererImp.getPointer();
Shinya Kitaoka 120a6e
  --rendererImp->m_undoneTasks;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Tiles release back to the Raster Pool happens in the main thread, after all
Shinya Kitaoka 120a6e
  // possible
Shinya Kitaoka 120a6e
  // signals emitted in the onFrameCompleted/Failed notifications have been
Shinya Kitaoka 120a6e
  // resolved, thus
Shinya Kitaoka 120a6e
  // ensuring that no other rendering thread owns the rasters before them.
Shinya Kitaoka 120a6e
  releaseTiles();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Update the render instance status
Shinya Kitaoka 120a6e
  bool instanceExpires = false;
shun-iwasawa 27b0cf
  bool isCanceled      = false;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    QMutexLocker sl(&rendererImp->m_renderInstancesMutex);
Shinya Kitaoka 120a6e
    std::map<unsigned long,="" trendererimp::renderinstanceinfos="">::iterator it =</unsigned>
Shinya Kitaoka 120a6e
        rendererImp->m_activeInstances.find(m_renderId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (it != rendererImp->m_activeInstances.end() &&
Shinya Kitaoka 120a6e
        (--it->second.m_activeTasks) <= 0) {
Shinya Kitaoka 120a6e
      instanceExpires = true;
shun-iwasawa 27b0cf
      isCanceled      = (m_info.m_isCanceled && *m_info.m_isCanceled);
Shinya Kitaoka 120a6e
      rendererImp->m_activeInstances.erase(m_renderId);
Campbell Barton 197095
      // m_info is freed, don't access further!
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // If the render instance has just expired
Shinya Kitaoka 120a6e
  if (instanceExpires) {
Shinya Kitaoka 120a6e
    /*-- キャンセルされた場合はm_overallRenderedRegionの更新をしない --*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Inform the render ports
Shinya Kitaoka 120a6e
    rendererImp->notifyRenderFinished(isCanceled);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // NOTE: This slot is currently invoked on the main thread. It could
Shinya Kitaoka 120a6e
    // eventually be
Shinya Kitaoka 120a6e
    // invoked directly on rendering threads, specifying the
Shinya Kitaoka 120a6e
    // Qt::DirectConnection option -
Shinya Kitaoka 120a6e
    // but probably there would be no real advantage in doing so...
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Temporarily install the renderer in current thread
Shinya Kitaoka 120a6e
    rendererStorage.setLocalData(new (TRendererImp *)(rendererImp));
Shinya Kitaoka 120a6e
    renderIdsStorage.setLocalData(new unsigned long(m_renderId));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Inform the resource managers
Shinya Kitaoka 120a6e
    rendererImp->declareRenderEnd(m_renderId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Uninstall the temporary
Shinya Kitaoka 120a6e
    rendererStorage.setLocalData(0);
Shinya Kitaoka 120a6e
    renderIdsStorage.setLocalData(0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    rendererImp->m_rasterPool
Shinya Kitaoka 120a6e
        .clear();  // Isn't this misplaced? Should be in the block
Shinya Kitaoka 120a6e
  }                // below...
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // If no rendering task (of this or other render instances) is found...
Shinya Kitaoka 120a6e
  if (rendererImp->m_undoneTasks == 0) {
Shinya Kitaoka 120a6e
    QMutexLocker sl(&rendererImp->m_renderInstancesMutex);
Shinya Kitaoka 120a6e
    rendererImp->quitWaitingLoops();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
//    Tough Stuff
Toshihiro Shimizu 890ddd
//================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRendererStartInvoker::emitStartRender(TRendererImp *renderer,
Shinya Kitaoka 120a6e
                                            StartInvokerRenderData rd) {
Shinya Kitaoka 120a6e
  renderer->addRef();
Shinya Kitaoka 120a6e
  Q_EMIT startRender(renderer, rd);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRendererStartInvoker::doStartRender(TRendererImp *renderer,
Shinya Kitaoka 120a6e
                                          StartInvokerRenderData rd) {
Shinya Kitaoka 120a6e
  renderer->startRendering(rd.m_renderId, *rd.m_renderDataVector);
Shinya Kitaoka 120a6e
  renderer->release();
Shinya Kitaoka 120a6e
  delete rd.m_renderDataVector;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
std::vector<const *="" tfx=""> calculateSortedFxs(TRasterFxP rootFx) {</const>
Shinya Kitaoka 120a6e
  std::map<const *="" *,="" std::set<const="" tfx="">> E; /* 辺の情報 */</const>
Shinya Kitaoka 120a6e
  std::set<const *="" tfx=""> Sources; /* 入次数0のノード群 */</const>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::queue<const *="" tfx=""> Q;</const>
Shinya Kitaoka 120a6e
  Q.push(rootFx.getPointer());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  E[rootFx.getPointer()] = std::set<const *="" tfx="">();</const>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (!Q.empty()) {
Shinya Kitaoka 120a6e
    const TFx *vptr = Q.front();
Shinya Kitaoka 120a6e
    Q.pop();
Shinya Kitaoka 120a6e
    if (!vptr) {
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /* 繋がっている入力ポートの先の Fx を訪問する
Shinya Kitaoka 120a6e
入力ポートが無ければ終了 */
Shinya Kitaoka 120a6e
    int portCount = vptr->getInputPortCount();
Shinya Kitaoka 120a6e
    if (portCount < 1) {
Shinya Kitaoka 120a6e
      Sources.insert(vptr);
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (int i = 0; i < portCount; i++) {
Shinya Kitaoka 120a6e
      TFxPort *port = vptr->getInputPort(i);
Shinya Kitaoka 120a6e
      if (!port) {
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      TFxP u          = port->getFx();
Shinya Kitaoka 120a6e
      const TFx *uptr = u.getPointer();
Shinya Kitaoka 120a6e
      if (E.count(uptr) == 0) {
Shinya Kitaoka 120a6e
        E[uptr] = std::set<const *="" tfx="">();</const>
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (E[uptr].count(vptr) == 0) {
Shinya Kitaoka 120a6e
        E[uptr].insert(vptr);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      Q.push(uptr);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /* トポロジカルソート */
Shinya Kitaoka 120a6e
  std::set<const *="" tfx=""> visited;</const>
Shinya Kitaoka 120a6e
  std::vector<const *="" tfx=""> L;</const>
Shinya Kitaoka 120a6e
  std::function<void(const *)="" tfx=""> visit = [&visit, &visited, &E,</void(const>
Shinya Kitaoka 120a6e
                                            &L](const TFx *fx) {
Shinya Kitaoka 120a6e
    if (visited.count(fx)) return;
Shinya Kitaoka 120a6e
    visited.insert(fx);
Shinya Kitaoka 120a6e
    auto edge = E[fx];
Shinya Kitaoka 120a6e
    for (auto i = edge.cbegin(); i != edge.cend(); i++) {
Shinya Kitaoka 120a6e
      visit(*i);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    L.insert(L.begin(), fx);
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
  for (auto i = E.cbegin(); i != E.cend(); i++) {
Shinya Kitaoka 120a6e
    visit(i->first);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return L;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRendererImp::startRendering(
Shinya Kitaoka 120a6e
    unsigned long renderId,
Shinya Kitaoka 120a6e
    const std::vector<trenderer::renderdata> &renderDatas) {</trenderer::renderdata>
Shinya Kitaoka 120a6e
  rootFx = renderDatas.front().m_fxRoot.m_frameA;
Shinya Kitaoka 120a6e
  int T  = renderDatas.size();
Shinya Kitaoka 120a6e
  for (int z = 0; z < T; z++) {
Shinya Kitaoka 120a6e
    auto sortedFxs = calculateSortedFxs(renderDatas[z].m_fxRoot.m_frameA);
Shinya Kitaoka 120a6e
    if (z == 0) {
Shinya Kitaoka 120a6e
      for (auto fx : sortedFxs) {
Shinya Kitaoka 120a6e
        if (fx) const_cast<tfx *="">(fx)->callStartRenderHandler();</tfx>
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  struct locals {
Shinya Kitaoka 120a6e
    static inline void setStorage(TRendererImp *imp, unsigned long renderId) {
Shinya Kitaoka 120a6e
      rendererStorage.setLocalData(new (TRendererImp *)(imp));
Shinya Kitaoka 120a6e
      renderIdsStorage.setLocalData(new unsigned long(renderId));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    static inline void clearStorage() {
Shinya Kitaoka 120a6e
      rendererStorage.setLocalData(0);
Shinya Kitaoka 120a6e
      renderIdsStorage.setLocalData(0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    static inline void declareStatusStart(TRendererImp *imp,
Shinya Kitaoka 120a6e
                                          TRenderer::RenderStatus status,
Shinya Kitaoka 120a6e
                                          RenderInstanceInfos *renderInfos) {
Shinya Kitaoka 120a6e
      renderInfos->m_status = status;
Shinya Kitaoka 120a6e
      imp->declareStatusStart(status);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    //-----------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    struct InstanceDeclaration {
Shinya Kitaoka 120a6e
      TRendererImp *m_imp;
Shinya Kitaoka 120a6e
      unsigned long m_renderId;
Shinya Kitaoka 120a6e
      bool m_rollback;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      InstanceDeclaration(TRendererImp *imp, unsigned long renderId)
Shinya Kitaoka 120a6e
          : m_imp(imp), m_renderId(renderId), m_rollback(true) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      ~InstanceDeclaration() {
Shinya Kitaoka 120a6e
        if (m_rollback) {
Shinya Kitaoka 120a6e
          QMutexLocker locker(&m_imp->m_renderInstancesMutex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          m_imp->m_activeInstances.erase(m_renderId);
Shinya Kitaoka 120a6e
          if (m_imp->m_undoneTasks == 0) m_imp->quitWaitingLoops();
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      void commit() { m_rollback = false; }
Shinya Kitaoka 120a6e
    };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    struct StorageDeclaration {
Shinya Kitaoka 120a6e
      StorageDeclaration(TRendererImp *imp, unsigned long renderId) {
Shinya Kitaoka 120a6e
        setStorage(imp, renderId);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      ~StorageDeclaration() { clearStorage(); }
Shinya Kitaoka 120a6e
    };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    struct RenderDeclaration {
Shinya Kitaoka 120a6e
      TRendererImp *m_imp;
Shinya Kitaoka 120a6e
      unsigned long m_renderId;
Shinya Kitaoka 120a6e
      bool m_rollback;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      RenderDeclaration(TRendererImp *imp, unsigned long renderId)
Shinya Kitaoka 120a6e
          : m_imp(imp), m_renderId(renderId), m_rollback(true) {
Shinya Kitaoka 120a6e
        imp->declareRenderStart(renderId);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      ~RenderDeclaration() {
Shinya Kitaoka 120a6e
        if (m_rollback) m_imp->declareRenderEnd(m_renderId);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      void commit() { m_rollback = false; }
Shinya Kitaoka 120a6e
    };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    struct StatusDeclaration {
Shinya Kitaoka 120a6e
      TRendererImp *m_imp;
Shinya Kitaoka 120a6e
      TRenderer::RenderStatus m_status;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      StatusDeclaration(TRendererImp *imp, TRenderer::RenderStatus status,
Shinya Kitaoka 120a6e
                        RenderInstanceInfos *renderInfos)
Shinya Kitaoka 120a6e
          : m_imp(imp), m_status(status) {
Shinya Kitaoka 120a6e
        declareStatusStart(imp, status, renderInfos);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      ~StatusDeclaration() { m_imp->declareStatusEnd(m_status); }
Shinya Kitaoka 120a6e
    };
Shinya Kitaoka 120a6e
  };  // locals
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // DIAGNOSTICS_CLEAR;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //----------------------------------------------------------------------
Shinya Kitaoka 120a6e
  //    Preliminary initializations
Shinya Kitaoka 120a6e
  //----------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Calculate the overall render area - sum of all render ports' areas
Shinya Kitaoka 120a6e
  TRectD renderArea;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    QReadLocker sl(&m_portsLock);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (PortContainerIterator it = m_ports.begin(); it != m_ports.end(); ++it)
Shinya Kitaoka 120a6e
      renderArea += (*it)->getRenderArea();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const TRenderSettings &info(renderDatas[0].m_info);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Extract the render geometry
Shinya Kitaoka 120a6e
  TPointD pos(renderArea.getP00());
Shinya Kitaoka 120a6e
  TDimension frameSize(tceil(renderArea.getLx()), tceil(renderArea.getLy()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRectD camBox(TPointD(pos.x / info.m_shrinkX, pos.y / info.m_shrinkY),
Shinya Kitaoka 120a6e
                TDimensionD(frameSize.lx, frameSize.ly));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Refresh the raster pool specs
Shinya Kitaoka 120a6e
  m_rasterPool.setRasterSpecs(frameSize, info.m_bpp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Set a temporary active instance count - so that hasToDie(renderId) returns
Shinya Kitaoka 120a6e
  // false
Shinya Kitaoka 120a6e
  RenderInstanceInfos *renderInfos;
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    QMutexLocker locker(&m_renderInstancesMutex);
Shinya Kitaoka 120a6e
    renderInfos                = &m_activeInstances[renderId];
Shinya Kitaoka 120a6e
    renderInfos->m_activeTasks = 1;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  locals::InstanceDeclaration instanceDecl(this, renderId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  //----------------------------------------------------------------------
Shinya Kitaoka 120a6e
  //    Clustering - Render Tasks creation
Shinya Kitaoka 120a6e
  //----------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<rendertask *=""> tasksVector;</rendertask>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  struct TasksCleaner {
Shinya Kitaoka 120a6e
    std::vector<rendertask *=""> &m_tasksVector;</rendertask>
Shinya Kitaoka 120a6e
    ~TasksCleaner() {
Shinya Kitaoka 120a6e
      std::for_each(m_tasksVector.begin(), m_tasksVector.end(),
Shinya Kitaoka 120a6e
                    tcg::deleter<rendertask>());</rendertask>
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } tasksCleaner = {tasksVector};
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  unsigned long tasksIdCounter = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<std::string, *="" rendertask=""> clusters;</std::string,>
Shinya Kitaoka 120a6e
  std::vector<trenderer::renderdata>::const_iterator it;</trenderer::renderdata>
Shinya Kitaoka 120a6e
  std::map<std::string, *="" rendertask="">::iterator jt;</std::string,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (it = renderDatas.begin(); it != renderDatas.end(); ++it) {
Shinya Kitaoka 120a6e
    // Check for user cancels
Shinya Kitaoka 120a6e
    if (hasToDie(renderId)) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Build the frame's description alias
Shinya Kitaoka 120a6e
    const TRenderer::RenderData &renderData = *it;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*--- カメラサイズ (LevelAutoやノイズで使用する) ---*/
Shinya Kitaoka 120a6e
    TRenderSettings rs = renderData.m_info;
Shinya Kitaoka 120a6e
    rs.m_cameraBox     = camBox;
Shinya Kitaoka 120a6e
    /*--- 途中でPreview計算がキャンセルされたときのフラグ ---*/
Shinya Kitaoka 120a6e
    rs.m_isCanceled = &renderInfos->m_canceled;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRasterFxP fx = renderData.m_fxRoot.m_frameA;
Shinya Kitaoka 120a6e
    assert(fx);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    double frame = renderData.m_frame;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::string alias = fx->getAlias(frame, renderData.m_info);
Shinya Kitaoka 120a6e
    if (renderData.m_fxRoot.m_frameB)
Shinya Kitaoka 120a6e
      alias = alias +
Shinya Kitaoka 120a6e
              renderData.m_fxRoot.m_frameB->getAlias(frame, renderData.m_info);
Shinya Kitaoka 120a6e
shun_iwasawa 7e52a2
    // If the render contains offscreen render, then prepare the
shun_iwasawa 7e52a2
    // QOffscreenSurface
shun_iwasawa 7e52a2
    // in main (GUI) thread. For now it is used only in the plasticDeformerFx.
shun_iwasawa 7e52a2
    if (alias.find("plasticDeformerFx") != std::string::npos &&
shun_iwasawa 7e52a2
        QThread::currentThread() == qGuiApp->thread()) {
shun_iwasawa 7e52a2
      rs.m_offScreenSurface.reset(new QOffscreenSurface());
shun_iwasawa 7e52a2
      rs.m_offScreenSurface->setFormat(QSurfaceFormat::defaultFormat());
shun_iwasawa 7e52a2
      rs.m_offScreenSurface->setScreen(
shun_iwasawa 7e52a2
          QOpenGLContext::globalShareContext()->screen());
shun_iwasawa 7e52a2
      rs.m_offScreenSurface->create();
shun_iwasawa 7e52a2
    }
shun_iwasawa 7e52a2
Shinya Kitaoka 120a6e
    // Search the alias among stored clusters - and store the frame
Shinya Kitaoka 120a6e
    jt = clusters.find(alias);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (jt == clusters.end()) {
Shinya Kitaoka 120a6e
      RenderTask *newTask =
Shinya Kitaoka 120a6e
          new RenderTask(renderId, tasksIdCounter++, renderData.m_frame, rs,
Shinya Kitaoka 120a6e
                         renderData.m_fxRoot, pos, frameSize, this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      tasksVector.push_back(newTask);
Shinya Kitaoka 120a6e
      clusters.insert(std::make_pair(alias, newTask));
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      jt->second->addFrame(renderData.m_frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Call processEvents to make the GUI reactive.
Shinya Kitaoka 120a6e
    QCoreApplication::instance()->processEvents();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Release the clusters - we'll just need the tasks vector from now on
Shinya Kitaoka 120a6e
  clusters.clear();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<rendertask *="">::iterator kt, kEnd = tasksVector.end();</rendertask>
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    // Install TRenderer on current thread before proceeding
Shinya Kitaoka 120a6e
    locals::StorageDeclaration storageDecl(this, renderId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Inform the resource managers
Shinya Kitaoka 120a6e
    locals::RenderDeclaration renderDecl(this, renderId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    //----------------------------------------------------------------------
Shinya Kitaoka 120a6e
    //    Precomputing
Shinya Kitaoka 120a6e
    //----------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_precomputingEnabled) {
Shinya Kitaoka 120a6e
      // Set current maxTileSize for cache manager precomputation
Shinya Kitaoka 120a6e
      const TRenderSettings &rs = renderDatas[0].m_info;
Shinya Kitaoka 120a6e
      TPredictiveCacheManager::instance()->setMaxTileSize(rs.m_maxTileSize);
Shinya Kitaoka 120a6e
      TPredictiveCacheManager::instance()->setBPP(rs.m_bpp);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Perform the first precomputing run - fx usages declaration
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        locals::StatusDeclaration firstrunDecl(this, TRenderer::FIRSTRUN,
Shinya Kitaoka 120a6e
                                               renderInfos);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        for (kt = tasksVector.begin(); kt != kEnd; ++kt) {
Shinya Kitaoka 120a6e
          if (hasToDie(renderId)) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
          (*kt)->preRun();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          // NOTE: Thread-specific data must be temporarily uninstalled before
Shinya Kitaoka 120a6e
          // processing events (which may redefine the thread data).
Shinya Kitaoka 120a6e
          locals::clearStorage();
Shinya Kitaoka 120a6e
          QCoreApplication::instance()->processEvents();
Shinya Kitaoka 120a6e
          locals::setStorage(this, renderId);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Pass to the TESTRUN status - this one should faithfully reproduce
Shinya Kitaoka 120a6e
      // the actual COMPUTING status
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        locals::StatusDeclaration testrunDecl(this, TRenderer::TESTRUN,
Shinya Kitaoka 120a6e
                                              renderInfos);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        for (kt = tasksVector.begin(); kt != kEnd; ++kt) {
Shinya Kitaoka 120a6e
          if (hasToDie(renderId)) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          (*kt)->preRun();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          // NOTE: Thread-specific data must be temporarily uninstalled before
Shinya Kitaoka 120a6e
          // processing events (which may redefine the thread data).
Shinya Kitaoka 120a6e
          locals::clearStorage();
Shinya Kitaoka 120a6e
          QCoreApplication::instance()->processEvents();
Shinya Kitaoka 120a6e
          locals::setStorage(this, renderId);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    //----------------------------------------------------------------------
Shinya Kitaoka 120a6e
    //    Render
Shinya Kitaoka 120a6e
    //----------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    locals::declareStatusStart(this, TRenderer::COMPUTING, renderInfos);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Update the tasks counts
Shinya Kitaoka 120a6e
    m_undoneTasks += tasksVector.size();
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      QMutexLocker locker(&m_renderInstancesMutex);
Shinya Kitaoka 120a6e
      renderInfos->m_activeTasks = tasksVector.size();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    renderDecl.commit();  // Declarations are taken over by render tasks
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  instanceDecl.commit();  // Same here
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Launch the render
Shinya Kitaoka 120a6e
  for (kt = tasksVector.begin(); kt != tasksVector.end(); ++kt)
Shinya Kitaoka 120a6e
    m_executor.addTask(*kt);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  tasksVector.clear();  // Prevent tasks destruction by TasksCleaner
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TRenderer::initialize() { TRendererStartInvoker::instance(); }