Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// System-core includes
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "tstopwatch.h"
Toshihiro Shimizu 890ddd
#include "tfiletype.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Images includes
Toshihiro Shimizu 890ddd
#include "trasterimage.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "tiio.h"
Toshihiro Shimizu 890ddd
#include "tpixelutils.h"
Toshihiro Shimizu 890ddd
#include "tlevel_io.h"
Toshihiro Shimizu 890ddd
#include "tcodec.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Fx-related includes
Toshihiro Shimizu 890ddd
#include "tfxutil.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Cache management includes
Toshihiro Shimizu 890ddd
#include "tpassivecachemanager.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Toonz app (currents)
Toshihiro Shimizu 890ddd
#include "tapp.h"
Toshihiro Shimizu 890ddd
#include "toutputproperties.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Toonz stage structures
Toshihiro Shimizu 890ddd
#include "toonz/tobjecthandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tscenehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tframehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tfxhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tpalettehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/sceneproperties.h"
Toshihiro Shimizu 890ddd
#include "toonz/scenefx.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcamera.h"
Toshihiro Shimizu 890ddd
#include "toonz/palettecontroller.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Toonz-qt stuff
Toshihiro Shimizu 890ddd
#include "toonzqt/gutil.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/menubarcommand.h"
Toshihiro Shimizu 890ddd
#include "menubarcommandids.h"
Toshihiro Shimizu 890ddd
#include "filebrowserpopup.h"
Toshihiro Shimizu 890ddd
#include "filebrowsermodel.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Toonz 6 FlipConsole's slider
Toshihiro Shimizu 890ddd
#include "toonzqt/flipconsole.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Qt stuff
Toshihiro Shimizu 890ddd
#include <qtimer></qtimer>
Toshihiro Shimizu 890ddd
#include <qregion></qregion>
Toshihiro Shimizu 890ddd
#include <qmetatype></qmetatype>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "previewer.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! \class Previewer
Shinya Kitaoka 120a6e
The Previewer class is a singleton which deals with Preview renders of isolated
Shinya Kitaoka 120a6e
frames.
Shinya Kitaoka 120a6e
The main purpose of this class, as of Toonz 6.x, is that of managing preview
Shinya Kitaoka 120a6e
requests coming
Shinya Kitaoka 120a6e
from Toonz's Scene Viewers; however, it is designed to support requests from a
Shinya Kitaoka 120a6e
generic
Toshihiro Shimizu 890ddd
\b Previewer::Listener class.
Shinya Kitaoka 120a6e
The Previewer is a singleton, meaning that it centralizes requests from many
Shinya Kitaoka 120a6e
possible listeners
Toshihiro Shimizu 890ddd
in a single collection of previewed frames.
Toshihiro Shimizu 890ddd
\n \n
Shinya Kitaoka 120a6e
The most important method of the class is \b getRaster(), which attempts
Shinya Kitaoka 120a6e
retrieval of a certain
Toshihiro Shimizu 890ddd
frame and, if the frame was not calculated yet, makes the Previewer build it.
Toshihiro Shimizu 890ddd
\n
luz paz 6454c4
The update() slot is provided to refresh the cached information about the
Shinya Kitaoka 120a6e
entire collection
Shinya Kitaoka 120a6e
of currently stored frames. Updated frames are recalculated only upon a new
Shinya Kitaoka 120a6e
getRaster(), in case the previously
luz paz 6454c4
stored information no more match the current frame description.
Toshihiro Shimizu 890ddd
\n
luz paz 6454c4
The clear() methods make the Previewer erase all stored information about one
Shinya Kitaoka 120a6e
or all frames,
Toshihiro Shimizu 890ddd
so that the following getRaster() will forcibly recalculate the requested frame.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//======================================================================================
Toshihiro Shimizu 890ddd
//    Preliminary stuff
Toshihiro Shimizu 890ddd
//======================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define CACHEID "RenderCache"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
bool suspendedRendering        = false;
Shinya Kitaoka 120a6e
Previewer *previewerInstance   = 0;
Toshihiro Shimizu 890ddd
Previewer *previewerInstanceSC = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QTimer levelChangedTimer, fxChangedTimer, xsheetChangedTimer,
Shinya Kitaoka 120a6e
    objectChangedTimer;
Toshihiro Shimizu 890ddd
const int notificationDelay = 300;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void buildNodeTreeDescription(std::string &desc, const TFxP &root);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Qt's contains actually returns QRegion::intersected... I wonder why...
Shinya Kitaoka 120a6e
inline bool contains(const QRegion ®ion, const TRect &rect) {
Shinya Kitaoka 120a6e
  return QRegion(toQRect(rect)).subtracted(region).isEmpty();
Toshihiro Shimizu 890ddd
}
shun-iwasawa 199e29
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//======================================================================================
Toshihiro Shimizu 890ddd
//    Internal classes declaration
Toshihiro Shimizu 890ddd
//======================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=======================
Toshihiro Shimizu 890ddd
//    Previewer::Imp
Toshihiro Shimizu 890ddd
//-----------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class Previewer::Imp final : public TRenderPort {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  // All useful infos about a frame under Previewer's management
Shinya Kitaoka 120a6e
  struct FrameInfo {
Shinya Kitaoka 120a6e
  public:
Shinya Kitaoka 120a6e
    std::string m_alias;       // The alias of m_fx
Shinya Kitaoka 120a6e
    unsigned long m_renderId;  // The render process Id - passed by TRenderer
Shinya Kitaoka 120a6e
    QRegion m_renderedRegion;  // The plane region already rendered for m_fx
Shinya Kitaoka 120a6e
    TRect m_rectUnderRender;   // Plane region currently under render
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    FrameInfo() : m_renderId((unsigned long)-1) {}
Shinya Kitaoka 120a6e
  };
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Previewer *m_owner;
Shinya Kitaoka 120a6e
  TThread::Mutex m_mutex;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::set<previewer::listener *=""> m_listeners;</previewer::listener>
Shinya Kitaoka 120a6e
  std::map<int, frameinfo=""> m_frames;</int,>
Shinya Kitaoka 120a6e
  std::vector<uchar> m_pbStatus;</uchar>
Shinya Kitaoka 120a6e
  int m_computingFrameCount;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRenderSettings m_renderSettings;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::string m_cachePrefix;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TDimension m_cameraRes;
Shinya Kitaoka 120a6e
  TRectD m_renderArea;
Shinya Kitaoka 120a6e
  TPointD m_cameraPos;
Shinya Kitaoka 120a6e
  bool m_subcamera;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRect m_previewRect;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRenderer m_renderer;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Save command stuff
Shinya Kitaoka 120a6e
  TLevelWriterP m_lw;
Shinya Kitaoka 120a6e
  int m_currentFrameToSave;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Imp(Previewer *owner);
Shinya Kitaoka 120a6e
  ~Imp();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void notifyStarted(int frame);
Shinya Kitaoka 120a6e
  void notifyCompleted(int frame);
Shinya Kitaoka 120a6e
  void notifyFailed(int frame);
Shinya Kitaoka 120a6e
  void notifyUpdate();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFxPair buildSceneFx(int frame);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Updater methods. These refresh the manager's status, but do not launch new
Shinya Kitaoka 120a6e
  // renders
Shinya Kitaoka 120a6e
  // on their own. The refreshFrame() method must be manually invoked if
Shinya Kitaoka 120a6e
  // necessary.
Shinya Kitaoka 120a6e
  void updateRenderSettings();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void updateAliases();
Shinya Kitaoka 120a6e
  void updateAliasKeyword(const std::string &keyword);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // There are dependencies among the following updaters. Invoke them in the
Shinya Kitaoka 120a6e
  // specified order.
Shinya Kitaoka 120a6e
  void updateFrameRange();
Shinya Kitaoka 120a6e
  void updateProgressBarStatus();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void updateCamera();
Shinya Kitaoka 120a6e
  void updatePreviewRect();  // This is automatically invoked by refreshFrame()
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Use this method to re-render the passed frame. Infos specified with the
Shinya Kitaoka 120a6e
  // update* methods
Shinya Kitaoka 120a6e
  // are assumed correct.
Shinya Kitaoka 120a6e
  void refreshFrame(int frame);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // TRenderPort methods
Shinya Kitaoka 473e70
  void onRenderRasterStarted(const RenderData &renderData) override;
Shinya Kitaoka 473e70
  void onRenderRasterCompleted(const RenderData &renderData) override;
Shinya Kitaoka 473e70
  void onRenderFailure(const RenderData &renderData, TException &e) override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Main-thread executed code related to TRenderPort. Used to update
Shinya Kitaoka 120a6e
  // thread-vulnerable infos.
Shinya Kitaoka 120a6e
  void doOnRenderRasterStarted(const RenderData &renderData);
Shinya Kitaoka 120a6e
  void doOnRenderRasterCompleted(const RenderData &renderData);
Shinya Kitaoka 120a6e
  void doOnRenderRasterFailed(const RenderData &renderData);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void remove(int frame);
Shinya Kitaoka 120a6e
  void remove();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  void saveFrame();
Shinya Kitaoka 120a6e
  bool doSaveRenderedFrames(const TFilePath fp);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//======================================================================================
Toshihiro Shimizu 890ddd
//    Code implementation
Toshihiro Shimizu 890ddd
//======================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//============================
Toshihiro Shimizu 890ddd
//    Previewer::Listener
Toshihiro Shimizu 890ddd
//----------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Previewer::Listener::Listener() { m_refreshTimer.setSingleShot(true); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::Listener::requestTimedRefresh() { m_refreshTimer.start(1000); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=======================
Toshihiro Shimizu 890ddd
//    Previewer::Imp
Toshihiro Shimizu 890ddd
//-----------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Previewer::Imp::Imp(Previewer *owner)
Shinya Kitaoka 120a6e
    : m_owner(owner)
Shinya Kitaoka 120a6e
    , m_cameraRes(0, 0)
Shinya Kitaoka 120a6e
    , m_renderer(TSystem::getProcessorCount())
Shinya Kitaoka 120a6e
    , m_computingFrameCount(0)
Shinya Kitaoka 120a6e
    , m_currentFrameToSave(0)
Campbell Barton 9b2bfd
    , m_subcamera(false)
Shinya Kitaoka 120a6e
    , m_lw() {
Shinya Kitaoka 120a6e
  // Precomputing (ie predictive cache) is disabled in this case. This is due to
Shinya Kitaoka 120a6e
  // current TFxCacheManager's
Shinya Kitaoka 120a6e
  // implementation, which can't still handle multiple render processes from the
Shinya Kitaoka 120a6e
  // same TRenderer. This should
Shinya Kitaoka 120a6e
  // change in the near future...
Shinya Kitaoka 120a6e
  m_renderer.enablePrecomputing(false);
Shinya Kitaoka 120a6e
  m_renderer.addPort(this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  updateRenderSettings();
Shinya Kitaoka 120a6e
  updateCamera();
Shinya Kitaoka 120a6e
  updateFrameRange();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Previewer::Imp::~Imp() {
Shinya Kitaoka 120a6e
  m_renderer.removePort(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // for(std::map<int, frameinfo*="">::iterator it=m_frames.begin();</int,>
Shinya Kitaoka 120a6e
  // it!=m_frames.end(); ++it)
Shinya Kitaoka 120a6e
  //  delete it->second; //crash on exit! not a serious leak, Previewer is a
Shinya Kitaoka 120a6e
  //  singleton
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFxPair Previewer::Imp::buildSceneFx(int frame) {
Shinya Kitaoka 120a6e
  TFxPair fxPair;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TApp *app         = TApp::instance();
Shinya Kitaoka 120a6e
  ToonzScene *scene = app->getCurrentScene()->getScene();
Shinya Kitaoka 120a6e
  TXsheet *xsh      = scene->getXsheet();
Shinya Kitaoka 120a6e
  if (m_renderSettings.m_stereoscopic) {
Shinya Kitaoka 120a6e
    scene->shiftCameraX(-m_renderSettings.m_stereoscopicShift / 2.0);
Shinya Kitaoka 120a6e
    fxPair.m_frameA = ::buildSceneFx(
Shinya Kitaoka 120a6e
        scene, xsh, frame, TOutputProperties::AllLevels,
Shinya Kitaoka 120a6e
        m_renderSettings.m_applyShrinkToViewer ? m_renderSettings.m_shrinkX : 1,
Shinya Kitaoka 120a6e
        false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    scene->shiftCameraX(m_renderSettings.m_stereoscopicShift);
Shinya Kitaoka 120a6e
    fxPair.m_frameB = ::buildSceneFx(
Shinya Kitaoka 120a6e
        scene, xsh, frame, TOutputProperties::AllLevels,
Shinya Kitaoka 120a6e
        m_renderSettings.m_applyShrinkToViewer ? m_renderSettings.m_shrinkX : 1,
Shinya Kitaoka 120a6e
        false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    scene->shiftCameraX(-m_renderSettings.m_stereoscopicShift / 2.0);
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    fxPair.m_frameA = ::buildSceneFx(
Shinya Kitaoka 120a6e
        scene, xsh, frame, TOutputProperties::AllLevels,
Shinya Kitaoka 120a6e
        m_renderSettings.m_applyShrinkToViewer ? m_renderSettings.m_shrinkX : 1,
Shinya Kitaoka 120a6e
        false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return fxPair;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::Imp::updateCamera() {
Shinya Kitaoka 120a6e
  // Retrieve current camera
Shinya Kitaoka 120a6e
  TCamera *currCamera =
Shinya Kitaoka 120a6e
      TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera();
Shinya Kitaoka 120a6e
  TRect subCameraRect = currCamera->getInterestRect();
Shinya Kitaoka 120a6e
  TPointD cameraPos(-0.5 * currCamera->getRes().lx,
Shinya Kitaoka 120a6e
                    -0.5 * currCamera->getRes().ly);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Update the camera region and camera stage area
Shinya Kitaoka 120a6e
  TDimension cameraRes(0, 0);
Shinya Kitaoka 120a6e
  TRectD renderArea;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_subcamera && subCameraRect.getLx() > 0 && subCameraRect.getLy() > 0) {
Shinya Kitaoka 120a6e
    cameraRes  = TDimension(subCameraRect.getLx(), subCameraRect.getLy());
Shinya Kitaoka 120a6e
    renderArea = TRectD(subCameraRect.x0, subCameraRect.y0,
Shinya Kitaoka 120a6e
                        subCameraRect.x1 + 1, subCameraRect.y1 + 1) +
Shinya Kitaoka 120a6e
                 cameraPos;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    cameraRes  = currCamera->getRes();
Shinya Kitaoka 120a6e
    renderArea = TRectD(cameraPos, TDimensionD(cameraRes.lx, cameraRes.ly));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Add the shrink to camera res
Shinya Kitaoka 120a6e
  cameraRes.lx /= m_renderSettings.m_shrinkX;
Shinya Kitaoka 120a6e
  cameraRes.ly /= m_renderSettings.m_shrinkY;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Invalidate the old camera size
Shinya Kitaoka 120a6e
  if (m_cameraRes != cameraRes || m_renderArea != renderArea) {
Shinya Kitaoka 120a6e
    m_cameraRes  = cameraRes;
Shinya Kitaoka 120a6e
    m_renderArea = renderArea;
Shinya Kitaoka 120a6e
    m_cameraPos  = cameraPos;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // All previously rendered frames must be erased
Shinya Kitaoka 120a6e
    std::map<int, frameinfo="">::iterator it;</int,>
Shinya Kitaoka 120a6e
    for (it = m_frames.begin(); it != m_frames.end(); ++it)
Shinya Kitaoka 120a6e
      TImageCache::instance()->remove(m_cachePrefix +
Shinya Kitaoka 120a6e
                                      std::to_string(it->first));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_frames.clear();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::Imp::updateRenderSettings() {
Shinya Kitaoka 120a6e
  ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
Shinya Kitaoka 120a6e
  TRenderSettings renderSettings =
Shinya Kitaoka 120a6e
      scene->getProperties()->getPreviewProperties()->getRenderSettings();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (renderSettings.m_applyShrinkToViewer)
Shinya Kitaoka 120a6e
    renderSettings.m_shrinkY = renderSettings.m_shrinkX;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    renderSettings.m_shrinkY = renderSettings.m_shrinkX = 1;
Toshihiro Shimizu 890ddd
luz paz 5d417b
  // In case the settings changed, erase all previously cached images
Shinya Kitaoka 120a6e
  if (renderSettings != m_renderSettings) {
Shinya Kitaoka 120a6e
    m_renderSettings = renderSettings;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    std::map<int, frameinfo="">::iterator it;</int,>
Shinya Kitaoka 120a6e
    for (it = m_frames.begin(); it != m_frames.end(); ++it)
Shinya Kitaoka 120a6e
      TImageCache::instance()->remove(m_cachePrefix +
Shinya Kitaoka 120a6e
                                      std::to_string(it->first));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_frames.clear();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::Imp::updateFrameRange() {
Shinya Kitaoka 120a6e
  // Erase all rendered frames outside the new frame range
Shinya Kitaoka 120a6e
  int newFrameCount =
Shinya Kitaoka 120a6e
      TApp::instance()->getCurrentScene()->getScene()->getFrameCount();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<int, frameinfo="">::iterator it,</int,>
Shinya Kitaoka 120a6e
      jt = m_frames.lower_bound(newFrameCount);
Shinya Kitaoka 120a6e
  for (it = jt; it != m_frames.end(); ++it)
Shinya Kitaoka 120a6e
    // Release all associated cached images
Shinya Kitaoka 120a6e
    TImageCache::instance()->remove(m_cachePrefix + std::to_string(it->first));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_frames.erase(jt, m_frames.end());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Resize the progress bar status
Shinya Kitaoka 120a6e
  int i, oldSize = m_pbStatus.size();
Shinya Kitaoka 120a6e
  m_pbStatus.resize(newFrameCount);
shun-iwasawa 199e29
  for (i = oldSize; i < newFrameCount; ++i)
Shinya Kitaoka 120a6e
    m_pbStatus[i] = FlipSlider::PBFrameNotStarted;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::Imp::updateProgressBarStatus() {
Shinya Kitaoka 120a6e
  unsigned int i, pbSize = m_pbStatus.size();
Shinya Kitaoka 120a6e
  std::map<int, frameinfo="">::iterator it;</int,>
Shinya Kitaoka 120a6e
  for (i = 0; i < pbSize; ++i) {
shun-iwasawa 481b59
    it            = m_frames.find(i);
shun-iwasawa 481b59
    m_pbStatus[i] = (it == m_frames.end()) ? FlipSlider::PBFrameNotStarted
shun-iwasawa 481b59
                    : ::contains(it->second.m_renderedRegion, m_previewRect)
shun-iwasawa 481b59
                        ? FlipSlider::PBFrameFinished
shun-iwasawa 481b59
                    : it->second.m_rectUnderRender.contains(m_previewRect)
Shinya Kitaoka 120a6e
                        ? FlipSlider::PBFrameStarted
Shinya Kitaoka 120a6e
                        : FlipSlider::PBFrameNotStarted;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::Imp::updatePreviewRect() {
Shinya Kitaoka 120a6e
  TRectD previewRectD;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*--
Shinya Kitaoka 120a6e
   * SubCameraPreviewではない場合、Viewerの表示エリアに関係なく全画面で計算を行う
Shinya Kitaoka 120a6e
   * --*/
Shinya Kitaoka 120a6e
  if (!m_subcamera)
Shinya Kitaoka 120a6e
    previewRectD = m_renderArea;
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    // Retrieve the view rects from each listener. Their union will form the
Shinya Kitaoka 120a6e
    // rect to be rendered.
Shinya Kitaoka 120a6e
    std::set<previewer::listener *="">::iterator it;</previewer::listener>
Shinya Kitaoka 120a6e
    for (it = m_listeners.begin(); it != m_listeners.end(); ++it) {
Shinya Kitaoka 120a6e
      // Retrieve the listener's viewRect and add it to the preview rect
Shinya Kitaoka 120a6e
      previewRectD += (*it)->getPreviewRect();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  previewRectD *= m_renderArea;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int shrinkX = m_renderSettings.m_shrinkX;
Shinya Kitaoka 120a6e
  int shrinkY = m_renderSettings.m_shrinkY;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Ensure that rect has the same pixel geometry as the preview camera
Shinya Kitaoka 120a6e
  previewRectD -= m_cameraPos;
Shinya Kitaoka 120a6e
  previewRectD.x0 = previewRectD.x0 / shrinkX;
Shinya Kitaoka 120a6e
  previewRectD.y0 = previewRectD.y0 / shrinkY;
Shinya Kitaoka 120a6e
  previewRectD.x1 = previewRectD.x1 / shrinkX;
Shinya Kitaoka 120a6e
  previewRectD.y1 = previewRectD.y1 / shrinkY;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Now, pass to m_cameraRes-relative coordinates
Shinya Kitaoka 120a6e
  TPointD shrinkedRelPos((m_renderArea.x0 - m_cameraPos.x) / shrinkX,
Shinya Kitaoka 120a6e
                         (m_renderArea.y0 - m_cameraPos.y) / shrinkY);
Shinya Kitaoka 120a6e
  previewRectD -= shrinkedRelPos;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  previewRectD.x0 = tfloor(previewRectD.x0);
Shinya Kitaoka 120a6e
  previewRectD.y0 = tfloor(previewRectD.y0);
Shinya Kitaoka 120a6e
  previewRectD.x1 = tceil(previewRectD.x1);
Shinya Kitaoka 120a6e
  previewRectD.y1 = tceil(previewRectD.y1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_previewRect = TRect(previewRectD.x0, previewRectD.y0, previewRectD.x1 - 1,
Shinya Kitaoka 120a6e
                        previewRectD.y1 - 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  previewRectD += m_cameraPos + shrinkedRelPos;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  setRenderArea(previewRectD);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::Imp::updateAliases() {
Shinya Kitaoka 120a6e
  std::map<int, frameinfo="">::iterator it;</int,>
Shinya Kitaoka 120a6e
  for (it = m_frames.begin(); it != m_frames.end(); ++it) {
Shinya Kitaoka 120a6e
    TFxPair fxPair = buildSceneFx(it->first);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::string newAlias =
Shinya Kitaoka 120a6e
        fxPair.m_frameA ? fxPair.m_frameA->getAlias(it->first, m_renderSettings)
Shinya Kitaoka 120a6e
                        : "";
shun-iwasawa 199e29
    newAlias = newAlias + (fxPair.m_frameB ? fxPair.m_frameB->getAlias(
shun-iwasawa 199e29
                                                 it->first, m_renderSettings)
shun-iwasawa 199e29
                                           : "");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (newAlias != it->second.m_alias) {
Shinya Kitaoka 120a6e
      // Clear the remaining frame infos
Shinya Kitaoka 120a6e
      it->second.m_renderedRegion = QRegion();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::Imp::updateAliasKeyword(const std::string &keyword) {
Shinya Kitaoka 120a6e
  std::map<int, frameinfo="">::iterator it;</int,>
Shinya Kitaoka 120a6e
  for (it = m_frames.begin(); it != m_frames.end(); ++it) {
Shinya Kitaoka 120a6e
    if (it->second.m_alias.find(keyword) != std::string::npos) {
shun-iwasawa 199e29
      TFxPair fxPair     = buildSceneFx(it->first);
shun-iwasawa 199e29
      it->second.m_alias = fxPair.m_frameA ? fxPair.m_frameA->getAlias(
shun-iwasawa 199e29
                                                 it->first, m_renderSettings)
shun-iwasawa 199e29
                                           : "";
shun-iwasawa 199e29
      it->second.m_alias = it->second.m_alias +
shun-iwasawa 199e29
                           (fxPair.m_frameB ? fxPair.m_frameB->getAlias(
shun-iwasawa 199e29
                                                  it->first, m_renderSettings)
shun-iwasawa 199e29
                                            : "");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Clear the remaining frame infos
Shinya Kitaoka 120a6e
      it->second.m_renderedRegion = QRegion();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // No need to release the cached image... eventually, clear it
Shinya Kitaoka 120a6e
      TRasterImageP ri = TImageCache::instance()->get(
Shinya Kitaoka 120a6e
          m_cachePrefix + std::to_string(it->first), true);
Shinya Kitaoka 120a6e
      if (ri) ri->getRaster()->clear();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Starts rendering the passed frame.
Shinya Kitaoka 120a6e
void Previewer::Imp::refreshFrame(int frame) {
Shinya Kitaoka 120a6e
  if (suspendedRendering) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Build the region to render
Shinya Kitaoka 120a6e
  updatePreviewRect();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_previewRect.getLx() <= 0 || m_previewRect.getLy() <= 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Retrieve the FrameInfo for passed frame
Shinya Kitaoka 120a6e
  std::map<int, frameinfo="">::iterator it = m_frames.find(frame);</int,>
Shinya Kitaoka 120a6e
  if (it != m_frames.end()) {
Shinya Kitaoka 120a6e
    // In case the rect we would render is contained in the frame's rendered
Shinya Kitaoka 120a6e
    // region, quit
Shinya Kitaoka 120a6e
    if (::contains(it->second.m_renderedRegion, m_previewRect)) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Then, check the m_previewRect against the frame's m_rectUnderRendering.
Shinya Kitaoka 120a6e
    // Ensure that we're not re-launching the very same render.
Shinya Kitaoka 120a6e
    if (it->second.m_rectUnderRender == m_previewRect) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Stop any frame's previously running render process
Shinya Kitaoka 120a6e
    m_renderer.abortRendering(it->second.m_renderId);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    it = m_frames.insert(std::make_pair(frame, FrameInfo())).first;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // In case the frame is not in the frame range, we add a temporary
Shinya Kitaoka 120a6e
    // supplement
Shinya Kitaoka 120a6e
    // to the progress bar.
Shinya Kitaoka 120a6e
    if (frame >= (int)m_pbStatus.size()) m_pbStatus.resize(frame + 1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Build the TFxPair to be passed to TRenderer
Shinya Kitaoka 120a6e
  TFxPair fxPair = buildSceneFx(frame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Update the RenderInfos associated with frame
Shinya Kitaoka 120a6e
  it->second.m_rectUnderRender = m_previewRect;
Shinya Kitaoka 120a6e
  it->second.m_alias = fxPair.m_frameA->getAlias(frame, m_renderSettings);
Shinya Kitaoka 120a6e
  if (fxPair.m_frameB)
Shinya Kitaoka 120a6e
    it->second.m_alias =
Shinya Kitaoka 120a6e
        it->second.m_alias + fxPair.m_frameB->getAlias(frame, m_renderSettings);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Retrieve the renderId of the rendering instance
Shinya Kitaoka 120a6e
  it->second.m_renderId = m_renderer.nextRenderId();
Shinya Kitaoka 120a6e
  std::string contextName("P");
Shinya Kitaoka 120a6e
  contextName += m_subcamera ? "SC" : "FU";
Shinya Kitaoka 120a6e
  contextName += std::to_string(frame);
Shinya Kitaoka 120a6e
  TPassiveCacheManager::instance()->setContextName(it->second.m_renderId,
Shinya Kitaoka 120a6e
                                                   contextName);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Start the render
Shinya Kitaoka 120a6e
  m_renderer.startRendering(frame, m_renderSettings, fxPair);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::Imp::remove(int frame) {
Shinya Kitaoka 120a6e
  // Search the frame among rendered ones
Shinya Kitaoka 120a6e
  std::map<int, frameinfo="">::iterator it = m_frames.find(frame);</int,>
Shinya Kitaoka 120a6e
  if (it != m_frames.end()) {
Shinya Kitaoka 120a6e
    m_renderer.abortRendering(it->second.m_renderId);
Shinya Kitaoka 120a6e
    m_frames.erase(frame);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Remove the associated image from cache
Shinya Kitaoka 120a6e
  TImageCache::instance()->remove(m_cachePrefix + std::to_string(frame));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::Imp::remove() {
Shinya Kitaoka 120a6e
  m_renderer.stopRendering(false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Remove all cached images
Shinya Kitaoka 120a6e
  std::map<int, frameinfo="">::iterator it;</int,>
Shinya Kitaoka 120a6e
  for (it = m_frames.begin(); it != m_frames.end(); ++it)
Shinya Kitaoka 120a6e
    TImageCache::instance()->remove(m_cachePrefix + std::to_string(it->first));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_frames.clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline void Previewer::Imp::notifyStarted(int frame) {
Shinya Kitaoka 120a6e
  std::set<previewer::listener *="">::iterator it;</previewer::listener>
Shinya Kitaoka 120a6e
  for (it = m_listeners.begin(); it != m_listeners.end(); ++it)
Shinya Kitaoka 120a6e
    (*it)->onRenderStarted(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline void Previewer::Imp::notifyCompleted(int frame) {
Shinya Kitaoka 120a6e
  std::set<previewer::listener *="">::iterator it;</previewer::listener>
Shinya Kitaoka 120a6e
  for (it = m_listeners.begin(); it != m_listeners.end(); ++it)
Shinya Kitaoka 120a6e
    (*it)->onRenderCompleted(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline void Previewer::Imp::notifyFailed(int frame) {
Shinya Kitaoka 120a6e
  std::set<previewer::listener *="">::iterator it;</previewer::listener>
Shinya Kitaoka 120a6e
  for (it = m_listeners.begin(); it != m_listeners.end(); ++it)
Shinya Kitaoka 120a6e
    (*it)->onRenderFailed(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline void Previewer::Imp::notifyUpdate() {
Shinya Kitaoka 120a6e
  std::set<previewer::listener *="">::iterator it;</previewer::listener>
Shinya Kitaoka 120a6e
  for (it = m_listeners.begin(); it != m_listeners.end(); ++it)
Shinya Kitaoka 120a6e
    (*it)->onPreviewUpdate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
luz paz 6454c4
//! Adds the renderized image to TImageCache; listeners are advised too.
Shinya Kitaoka 120a6e
void Previewer::Imp::onRenderRasterStarted(const RenderData &renderData) {
Shinya Kitaoka 120a6e
  // Emit the started signal to execute code in the main thread
Shinya Kitaoka 120a6e
  m_owner->emitStartedFrame(renderData);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::Imp::doOnRenderRasterStarted(const RenderData &renderData) {
Shinya Kitaoka 120a6e
  int frame = renderData.m_frames[0];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_computingFrameCount++;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Update the progress bar status
Shinya Kitaoka 120a6e
  if (frame < m_pbStatus.size()) m_pbStatus[frame] = FlipSlider::PBFrameStarted;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Notify listeners
Shinya Kitaoka 120a6e
  notifyStarted(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
luz paz 6454c4
//! Adds the renderized image to TImageCache; listeners are advised too.
Shinya Kitaoka 120a6e
void Previewer::Imp::onRenderRasterCompleted(const RenderData &renderData) {
Shinya Kitaoka 120a6e
  if (renderData.m_rasB) {
Shinya Kitaoka 120a6e
    RenderData _renderData = renderData;
Shinya Kitaoka 120a6e
    assert(m_renderSettings.m_stereoscopic);
Shinya Kitaoka 120a6e
    TRop::makeStereoRaster(_renderData.m_rasA, _renderData.m_rasB);
Shinya Kitaoka 120a6e
    if (_renderData.m_info.m_gamma != 1.0)
Shinya Kitaoka 120a6e
      TRop::gammaCorrect(_renderData.m_rasA, _renderData.m_info.m_gamma);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    _renderData.m_rasB = TRasterP();
Shinya Kitaoka 120a6e
    m_owner->emitRenderedFrame(_renderData);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // If required, correct gamma
Shinya Kitaoka 120a6e
  if (renderData.m_info.m_gamma != 1.0)
Shinya Kitaoka 120a6e
    TRop::gammaCorrect(renderData.m_rasA, renderData.m_info.m_gamma);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Emit the started signal to execute code in the main thread
Shinya Kitaoka 120a6e
  m_owner->emitRenderedFrame(renderData);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::Imp::doOnRenderRasterCompleted(const RenderData &renderData) {
Shinya Kitaoka 120a6e
  int renderId = renderData.m_renderId;
Shinya Kitaoka 120a6e
  int frame    = renderData.m_frames[0];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (renderData.m_rasB) {
Shinya Kitaoka 120a6e
    assert(m_renderSettings.m_stereoscopic);
Shinya Kitaoka 120a6e
    TRop::makeStereoRaster(renderData.m_rasA, renderData.m_rasB);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterP ras(renderData.m_rasA);
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
  // Linear Color Space -> sRGB
shun-iwasawa 481b59
  if (ras->isLinear()) {
shun-iwasawa 481b59
    TRop::tosRGB(ras, m_renderSettings.m_colorSpaceGamma);
shun-iwasawa 481b59
  }
shun-iwasawa 481b59
Shinya Kitaoka 120a6e
  m_computingFrameCount--;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Find the render infos in the Previewer
Shinya Kitaoka 120a6e
  std::map<int, frameinfo="">::iterator it = m_frames.find(frame);</int,>
Shinya Kitaoka 120a6e
  if (it == m_frames.end()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Ensure that the render process id is the same
Shinya Kitaoka 120a6e
  if (renderId != it->second.m_renderId) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Store the rendered image in the cache - this is done in the MAIN thread due
Shinya Kitaoka 120a6e
  // to the necessity of accessing it->second.m_rectUnderRender for raster
Shinya Kitaoka 120a6e
  // extraction.
Shinya Kitaoka 120a6e
  std::string str = m_cachePrefix + std::to_string(frame);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRasterImageP ri(TImageCache::instance()->get(str, true));
Shinya Kitaoka 120a6e
  TRasterP cachedRas(ri ? ri->getRaster() : TRasterP());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!cachedRas || (cachedRas->getSize() != m_cameraRes)) {
Shinya Kitaoka 120a6e
    TImageCache::instance()->remove(str);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // Create the raster at camera resolution
Shinya Kitaoka 120a6e
    cachedRas = ras->create(m_cameraRes.lx, m_cameraRes.ly);
Shinya Kitaoka 120a6e
    cachedRas->clear();
Shinya Kitaoka 120a6e
    ri = TRasterImageP(cachedRas);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Finally, copy the rendered raster over the cached one
Shinya Kitaoka 120a6e
  TRect rectUnderRender(
Shinya Kitaoka 120a6e
      it->second
Shinya Kitaoka 120a6e
          .m_rectUnderRender);  // Extract may MODIFY IT! E.g. with shrinks..!
Shinya Kitaoka 120a6e
  cachedRas = cachedRas->extract(rectUnderRender);
Shinya Kitaoka 120a6e
  if (cachedRas) {
Shinya Kitaoka 120a6e
    cachedRas->copy(ras);
Shinya Kitaoka 120a6e
    TImageCache::instance()->add(str, ri);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Update the FrameInfo
Shinya Kitaoka 120a6e
  it->second.m_renderedRegion += toQRect(it->second.m_rectUnderRender);
Shinya Kitaoka 120a6e
  it->second.m_rectUnderRender = TRect();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Update the progress bar status
Shinya Kitaoka 120a6e
  if (frame < m_pbStatus.size())
Shinya Kitaoka 120a6e
    m_pbStatus[frame] = FlipSlider::PBFrameFinished;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Notify listeners
Shinya Kitaoka 120a6e
  notifyCompleted(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Removes the associated raster from TImageCache, and listeners are made
Shinya Kitaoka 120a6e
//! aware.
Shinya Kitaoka 120a6e
void Previewer::Imp::onRenderFailure(const RenderData &renderData,
Shinya Kitaoka 120a6e
                                     TException &e) {
Shinya Kitaoka 120a6e
  m_owner->emitFailedFrame(renderData);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
luz paz 6454c4
//! Adds the renderized image to TImageCache; listeners are advised too.
Shinya Kitaoka 120a6e
void Previewer::Imp::doOnRenderRasterFailed(const RenderData &renderData) {
Shinya Kitaoka 120a6e
  m_computingFrameCount--;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int frame = (int)renderData.m_frames[0];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<int, frameinfo="">::iterator it = m_frames.find(frame);</int,>
Shinya Kitaoka 120a6e
  if (it == m_frames.end()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (renderData.m_renderId != it->second.m_renderId) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  it->second.m_renderedRegion  = QRegion();
Shinya Kitaoka 120a6e
  it->second.m_rectUnderRender = TRect();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Update the progress bar status
Shinya Kitaoka 120a6e
  if (frame < m_pbStatus.size())
Shinya Kitaoka 120a6e
    m_pbStatus[frame] = FlipSlider::PBFrameNotStarted;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  notifyCompleted(frame);  // Completed!?
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
enum { eBegin, eIncrement, eEnd };
Toshihiro Shimizu 890ddd
Shinya Kitaoka bb1d04
static DVGui::ProgressDialog *Pd = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class ProgressBarMessager final : public TThread::Message {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  int m_choice;
Shinya Kitaoka 120a6e
  int m_val;
Shinya Kitaoka 120a6e
  QString m_str;
Shinya Kitaoka 120a6e
  ProgressBarMessager(int choice, int val, const QString &str = "")
Shinya Kitaoka 120a6e
      : m_choice(choice), m_val(val), m_str(str) {}
Shinya Kitaoka 473e70
  void onDeliver() override {
Shinya Kitaoka 120a6e
    switch (m_choice) {
Shinya Kitaoka 120a6e
    case eBegin:
Shinya Kitaoka 120a6e
      if (!Pd)
Shinya Kitaoka 120a6e
        Pd = new DVGui::ProgressDialog(
Shinya Kitaoka 120a6e
            QObject::tr("Saving previewed frames...."), QObject::tr("Cancel"),
Shinya Kitaoka 120a6e
            0, m_val);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        Pd->setMaximum(m_val);
Shinya Kitaoka 120a6e
      Pd->show();
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case eIncrement:
Shinya Kitaoka 120a6e
      if (Pd->wasCanceled()) {
Shinya Kitaoka 120a6e
        delete Pd;
Shinya Kitaoka 120a6e
        Pd = 0;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        // if (m_val==Pd->maximum()) Pd->hide();
Shinya Kitaoka 120a6e
        Pd->setValue(m_val);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case eEnd: {
Shinya Kitaoka 120a6e
      DVGui::info(m_str);
Shinya Kitaoka 120a6e
      delete Pd;
Shinya Kitaoka 120a6e
      Pd = 0;
Shinya Kitaoka 120a6e
    } break;
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      assert(false);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 38fd86
  TThread::Message *clone() const override {
Shinya Kitaoka 38fd86
    return new ProgressBarMessager(*this);
Shinya Kitaoka 38fd86
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class SavePreviewedPopup final : public FileBrowserPopup {
Shinya Kitaoka 120a6e
  Previewer *m_p;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
shun-iwasawa 199e29
  SavePreviewedPopup()
shun-iwasawa 199e29
      : FileBrowserPopup(QObject::tr("Save Previewed Images")) {
shun-iwasawa 199e29
    setOkText(QObject::tr("Save"));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void setPreview(Previewer *p) { m_p = p; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  bool execute() override {
Shinya Kitaoka 120a6e
    if (m_selectedPaths.empty()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    return m_p->doSaveRenderedFrames(*m_selectedPaths.begin());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Previewer::doSaveRenderedFrames(TFilePath fp) {
Shinya Kitaoka 120a6e
  return m_imp->doSaveRenderedFrames(fp);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace DVGui;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Previewer::Imp::doSaveRenderedFrames(TFilePath fp) {
Shinya Kitaoka 120a6e
  ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
Shinya Kitaoka 120a6e
  TOutputProperties *outputSettings =
Shinya Kitaoka 120a6e
      scene->getProperties()->getOutputProperties();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QStringList formats;
Shinya Kitaoka 120a6e
  TLevelWriter::getSupportedFormats(formats, true);
Shinya Kitaoka 120a6e
  Tiio::Writer::getSupportedFormats(formats, true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string ext = fp.getType();
Shinya Kitaoka 120a6e
  if (ext == "") {
Shinya Kitaoka 120a6e
    ext = outputSettings->getPath().getType();
Shinya Kitaoka 120a6e
    fp  = fp.withType(ext);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (fp.getName() == "") {
shun-iwasawa 199e29
    DVGui::warning(QObject::tr(
shun-iwasawa 199e29
        "The file name cannot be empty or contain any of the following "
shun-iwasawa 199e29
        "characters:(new line)  \\ / : * ? \"  |"));
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!formats.contains(QString::fromStdString(ext))) {
shun-iwasawa 199e29
    DVGui::warning(QObject::tr("Unsopporter raster format, cannot save"));
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (fp.getWideName() == L"") fp = fp.withName(scene->getSceneName());
Shinya Kitaoka 120a6e
  if (TFileType::getInfo(fp) == TFileType::RASTER_IMAGE || ext == "pct" ||
Shinya Kitaoka 120a6e
      fp.getType() == "pic" || ext == "pict")  // pct e' un formato"livello" (ha
Shinya Kitaoka 120a6e
                                               // i settings di quicktime) ma
Shinya Kitaoka 120a6e
                                               // fatto di diversi frames
Shinya Kitaoka 120a6e
    fp = fp.withFrame(TFrameId::EMPTY_FRAME);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  fp          = scene->decodeFilePath(fp);
Shinya Kitaoka 120a6e
  bool exists = TFileStatus(fp.getParentDir()).doesExist();
Shinya Kitaoka 120a6e
  if (!exists) {
Shinya Kitaoka 120a6e
    try {
Shinya Kitaoka 120a6e
      TFilePath parent = fp.getParentDir();
Shinya Kitaoka 120a6e
      TSystem::mkDir(parent);
Shinya Kitaoka 120a6e
      DvDirModel::instance()->refreshFolder(parent.getParentDir());
Shinya Kitaoka 120a6e
    } catch (TException &e) {
shun-iwasawa 199e29
      error(QObject::tr("Cannot create %1 : %2",
shun-iwasawa 199e29
                        "Previewer warning %1:path %2:message")
shun-iwasawa 199e29
                .arg(toQString(fp.getParentDir()))
shun-iwasawa 199e29
                .arg(QString(::to_string(e.getMessage()).c_str())));
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    } catch (...) {
shun-iwasawa 199e29
      error(QObject::tr("Cannot create %1", "Previewer warning %1:path")
shun-iwasawa 199e29
                .arg(toQString(fp.getParentDir())));
Shinya Kitaoka 120a6e
      return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (TSystem::doesExistFileOrLevel(fp)) {
shun-iwasawa 199e29
    QString question(
shun-iwasawa 199e29
        QObject::tr("File %1 already exists.\nDo you want to overwrite it?")
shun-iwasawa 199e29
            .arg(toQString(fp)));
Shinya Kitaoka 120a6e
    int ret = DVGui::MsgBox(question, QObject::tr("Overwrite"),
Shinya Kitaoka 120a6e
                            QObject::tr("Cancel"), 0);
Shinya Kitaoka 120a6e
    if (ret == 2) return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    m_lw = TLevelWriterP(fp,
Shinya Kitaoka 120a6e
                         outputSettings->getFileFormatProperties(fp.getType()));
Shinya Kitaoka 120a6e
  } catch (TImageException &e) {
Shinya Kitaoka 120a6e
    error(QString::fromStdString(::to_string(e.getMessage())));
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_lw->setFrameRate(outputSettings->getFrameRate());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_currentFrameToSave = 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ProgressBarMessager(
Shinya Kitaoka 120a6e
      eBegin,
Shinya Kitaoka 120a6e
      TApp::instance()->getCurrentXsheet()->getXsheet()->getFrameCount())
Shinya Kitaoka 120a6e
      .sendBlocking();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QTimer::singleShot(50, m_owner, SLOT(saveFrame()));
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::Imp::saveFrame() {
Shinya Kitaoka 120a6e
  static int savedFrames = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int frameCount =
Shinya Kitaoka 120a6e
      TApp::instance()->getCurrentXsheet()->getXsheet()->getFrameCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(Pd);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (; m_currentFrameToSave <= frameCount; m_currentFrameToSave++) {
Shinya Kitaoka 120a6e
    ProgressBarMessager(eIncrement, m_currentFrameToSave).sendBlocking();
Shinya Kitaoka 120a6e
    if (!Pd) break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Ensure that current frame actually have to be saved
shun-iwasawa 199e29
    int currFrameToSave                   = m_currentFrameToSave - 1;
Shinya Kitaoka 120a6e
    std::map<int, frameinfo="">::iterator it = m_frames.find(currFrameToSave);</int,>
Shinya Kitaoka 120a6e
    if (it == m_frames.end()) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_pbStatus.size() < currFrameToSave ||
Shinya Kitaoka 120a6e
        m_pbStatus[currFrameToSave] != FlipSlider::PBFrameFinished)
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TImageP img = TImageCache::instance()->get(
Shinya Kitaoka 120a6e
        m_cachePrefix + std::to_string(currFrameToSave), false);
Shinya Kitaoka 120a6e
    if (!img) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Save the frame
Shinya Kitaoka 120a6e
    TImageWriterP writer = m_lw->getFrameWriter(TFrameId(m_currentFrameToSave));
Shinya Kitaoka 120a6e
    bool failureOnSaving = false;
Shinya Kitaoka 120a6e
    if (!writer) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    writer->save(img);
Shinya Kitaoka 120a6e
    savedFrames++;
Shinya Kitaoka 120a6e
    m_currentFrameToSave++;
Shinya Kitaoka 120a6e
    QTimer::singleShot(50, m_owner, SLOT(saveFrame()));
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Output the save result
shun-iwasawa 199e29
  QString str =
shun-iwasawa 199e29
      QObject::tr("Saved %1 frames out of %2 in %3",
shun-iwasawa 199e29
                  "Previewer %1:savedframes %2:framecount %3:filepath")
shun-iwasawa 199e29
          .arg(QString(std::to_string(savedFrames).c_str()))
shun-iwasawa 199e29
          .arg(QString(std::to_string(frameCount).c_str()))
shun-iwasawa 199e29
          .arg(QString(::to_string(m_lw->getFilePath()).c_str()));
Shinya Kitaoka 120a6e
shun-iwasawa 199e29
  if (!Pd) str = QObject::tr("Canceled! ", "Previewer") + str;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ProgressBarMessager(eEnd, 0, str).send();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_currentFrameToSave = 0;
Shinya Kitaoka 120a6e
  m_lw                 = TLevelWriterP();
Shinya Kitaoka 120a6e
  savedFrames          = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Previewer
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Previewer::Previewer(bool subcamera) : m_imp(new Imp(this)) {
Shinya Kitaoka 120a6e
  m_imp->m_subcamera   = subcamera;
Shinya Kitaoka 120a6e
  m_imp->m_cachePrefix = CACHEID + std::string(subcamera ? "SC" : "");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TApp *app = TApp::instance();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool ret = true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // ret = ret && connect(app->getPaletteController()->getCurrentPalette(),
Shinya Kitaoka 120a6e
  // SIGNAL(colorStyleChangedOnMouseRelease()),SLOT(onLevelChanged()));
Shinya Kitaoka 120a6e
  // ret = ret && connect(app->getPaletteController()->getCurrentPalette(),
Shinya Kitaoka 120a6e
  // SIGNAL(paletteChanged()),   SLOT(onLevelChanged()));
Shinya Kitaoka 120a6e
  ret = ret && connect(app->getPaletteController()->getCurrentLevelPalette(),
Shinya Kitaoka 120a6e
                       SIGNAL(colorStyleChangedOnMouseRelease()),
Shinya Kitaoka 120a6e
                       SLOT(onLevelChanged()));
Shinya Kitaoka 120a6e
  ret = ret && connect(app->getPaletteController()->getCurrentLevelPalette(),
Shinya Kitaoka 120a6e
                       SIGNAL(paletteChanged()), SLOT(onLevelChanged()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  levelChangedTimer.setInterval(notificationDelay);
Shinya Kitaoka 120a6e
  fxChangedTimer.setInterval(notificationDelay);
Shinya Kitaoka 120a6e
  xsheetChangedTimer.setInterval(notificationDelay);
Shinya Kitaoka 120a6e
  objectChangedTimer.setInterval(notificationDelay);
Shinya Kitaoka 120a6e
  levelChangedTimer.setSingleShot(true);
Shinya Kitaoka 120a6e
  fxChangedTimer.setSingleShot(true);
Shinya Kitaoka 120a6e
  xsheetChangedTimer.setSingleShot(true);
Shinya Kitaoka 120a6e
  objectChangedTimer.setSingleShot(true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ret = ret && connect(app->getCurrentLevel(), SIGNAL(xshLevelChanged()),
Shinya Kitaoka 120a6e
                       &levelChangedTimer, SLOT(start()));
Shinya Kitaoka 120a6e
  ret = ret && connect(app->getCurrentFx(), SIGNAL(fxChanged()),
Shinya Kitaoka 120a6e
                       &fxChangedTimer, SLOT(start()));
Shinya Kitaoka 120a6e
  ret = ret && connect(app->getCurrentXsheet(), SIGNAL(xsheetChanged()),
Shinya Kitaoka 120a6e
                       &xsheetChangedTimer, SLOT(start()));
Shinya Kitaoka 120a6e
  ret = ret && connect(app->getCurrentObject(), SIGNAL(objectChanged(bool)),
Shinya Kitaoka 120a6e
                       &objectChangedTimer, SLOT(start()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ret = ret && connect(&levelChangedTimer, SIGNAL(timeout()), this,
Shinya Kitaoka 120a6e
                       SLOT(onLevelChanged()));
Shinya Kitaoka 120a6e
  ret = ret &&
Shinya Kitaoka 120a6e
        connect(&fxChangedTimer, SIGNAL(timeout()), this, SLOT(onFxChanged()));
Shinya Kitaoka 120a6e
  ret = ret && connect(&xsheetChangedTimer, SIGNAL(timeout()), this,
Shinya Kitaoka 120a6e
                       SLOT(onXsheetChanged()));
Shinya Kitaoka 120a6e
  ret = ret && connect(&objectChangedTimer, SIGNAL(timeout()), this,
Shinya Kitaoka 120a6e
                       SLOT(onObjectChanged()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  qRegisterMetaType<trenderport::renderdata>("TRenderPort::RenderData");</trenderport::renderdata>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ret = ret && connect(this, SIGNAL(startedFrame(TRenderPort::RenderData)),
Shinya Kitaoka 120a6e
                       this, SLOT(onStartedFrame(TRenderPort::RenderData)));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ret = ret && connect(this, SIGNAL(renderedFrame(TRenderPort::RenderData)),
Shinya Kitaoka 120a6e
                       this, SLOT(onRenderedFrame(TRenderPort::RenderData)));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ret = ret && connect(this, SIGNAL(failedFrame(TRenderPort::RenderData)), this,
Shinya Kitaoka 120a6e
                       SLOT(onFailedFrame(TRenderPort::RenderData)));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // As a result of performing the connections above in the Previewer
Shinya Kitaoka 120a6e
  // constructor, no instance()
Shinya Kitaoka 120a6e
  // of it can be requested before a first scene has been completely
Shinya Kitaoka 120a6e
  // initialized.
Shinya Kitaoka 120a6e
  // Inform a global variable of the fact that a first instantiation was made.
Shinya Kitaoka 120a6e
  if (subcamera)
Shinya Kitaoka 120a6e
    previewerInstanceSC = this;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    previewerInstance = this;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(ret);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Previewer::~Previewer() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Ritorna l'istanza del \b Previewer
Shinya Kitaoka 120a6e
Previewer *Previewer::instance(bool subcameraPreview) {
Shinya Kitaoka 120a6e
  static Previewer _instance(false);
Shinya Kitaoka 120a6e
  static Previewer _instanceSC(true);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return subcameraPreview ? &_instanceSC : &_instance;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::vector<uchar> &Previewer::getProgressBarStatus() const {</uchar>
Shinya Kitaoka 120a6e
  return m_imp->m_pbStatus;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::addListener(Listener *listener) {
Shinya Kitaoka 120a6e
  m_imp->m_listeners.insert(listener);
Shinya Kitaoka 120a6e
  connect(&listener->m_refreshTimer, SIGNAL(timeout()), this,
Shinya Kitaoka 120a6e
          SLOT(updateView()));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::removeListener(Listener *listener) {
Shinya Kitaoka 120a6e
  m_imp->m_listeners.erase(listener);
Shinya Kitaoka 120a6e
  disconnect(&listener->m_refreshTimer, SIGNAL(timeout()), this,
Shinya Kitaoka 120a6e
             SLOT(updateView()));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_imp->m_listeners.empty()) {
Shinya Kitaoka 120a6e
    m_imp->m_renderer.stopRendering(false);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // Release all used context names
Shinya Kitaoka 120a6e
    std::string prefix("P");
Shinya Kitaoka 120a6e
    TPassiveCacheManager::instance()->releaseContextNamesWithPrefix(
Shinya Kitaoka 120a6e
        prefix + (m_imp->m_subcamera ? "SC" : "FU"));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::saveFrame() { m_imp->saveFrame(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::saveRenderedFrames() {
Shinya Kitaoka 120a6e
  if (TApp::instance()->getCurrentXsheet()->getXsheet()->getFrameCount() == 0) {
shun-iwasawa 199e29
    info(QObject::tr("No frame to save!"));
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_imp->m_currentFrameToSave != 0) {
shun-iwasawa 199e29
    info(QObject::tr("Already saving!"));
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  static SavePreviewedPopup *savePopup = 0;
shun-iwasawa 199e29
  if (!savePopup) savePopup = new SavePreviewedPopup;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  savePopup->setPreview(this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFilePath outpath = TApp::instance()
Shinya Kitaoka 120a6e
                          ->getCurrentScene()
Shinya Kitaoka 120a6e
                          ->getScene()
Shinya Kitaoka 120a6e
                          ->getProperties()
Shinya Kitaoka 120a6e
                          ->getOutputProperties()
Shinya Kitaoka 120a6e
                          ->getPath();
Shinya Kitaoka 120a6e
  savePopup->setFolder(outpath.getParentDir());
Shinya Kitaoka 120a6e
  TFilePath name = outpath.withoutParentDir();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  savePopup->setFilename(
Shinya Kitaoka 120a6e
      name.getName() == ""
Shinya Kitaoka 120a6e
          ? name.withName(
Shinya Kitaoka 120a6e
                TApp::instance()->getCurrentScene()->getScene()->getSceneName())
Shinya Kitaoka 120a6e
          : name);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  savePopup->show();
Shinya Kitaoka 120a6e
  savePopup->raise();
Shinya Kitaoka 120a6e
  savePopup->activateWindow();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! Restituisce un puntatore al raster randerizzato se il frame e' disponibile,
Toshihiro Shimizu 890ddd
    altrimenti comincia a calcolarlo*/
Shinya Kitaoka 120a6e
TRasterP Previewer::getRaster(int frame, bool renderIfNeeded) const {
shun_iwasawa f507ce
  if (frame < 0) return TRasterP();
Shinya Kitaoka 120a6e
  std::map<int, imp::frameinfo="">::iterator it = m_imp->m_frames.find(frame);</int,>
Shinya Kitaoka 120a6e
  if (it != m_imp->m_frames.end()) {
Shinya Kitaoka 120a6e
    if (frame < m_imp->m_pbStatus.size()) {
Shinya Kitaoka 120a6e
      if (m_imp->m_pbStatus[frame] == FlipSlider::PBFrameFinished ||
Shinya Kitaoka 120a6e
          !renderIfNeeded) {
Shinya Kitaoka 120a6e
        std::string str = m_imp->m_cachePrefix + std::to_string(frame);
Shinya Kitaoka 120a6e
        TRasterImageP rimg =
Shinya Kitaoka 120a6e
            (TRasterImageP)TImageCache::instance()->get(str, false);
Shinya Kitaoka 120a6e
        if (rimg) {
Shinya Kitaoka 120a6e
          TRasterP ras = rimg->getRaster();
shun-iwasawa 481b59
          assert((TRaster32P)ras || (TRaster64P)ras || (TRasterFP)ras);
Shinya Kitaoka 120a6e
          return ras;
Shinya Kitaoka 120a6e
        } else
Shinya Kitaoka 120a6e
          // Weird case - the frame was declared rendered, but no raster is
Shinya Kitaoka 120a6e
          // available...
Shinya Kitaoka 120a6e
          return TRasterP();
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        // Calculate the frame if it was not yet started
Shinya Kitaoka 120a6e
        if (m_imp->m_pbStatus[frame] == FlipSlider::PBFrameNotStarted)
Shinya Kitaoka 120a6e
          m_imp->refreshFrame(frame);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Retrieve the cached image, if any
Shinya Kitaoka 120a6e
    std::string str = m_imp->m_cachePrefix + std::to_string(frame);
Shinya Kitaoka 120a6e
    TRasterImageP rimg =
Shinya Kitaoka 120a6e
        (TRasterImageP)TImageCache::instance()->get(str, false);
Shinya Kitaoka 120a6e
    if (rimg) {
Shinya Kitaoka 120a6e
      TRasterP ras = rimg->getRaster();
shun-iwasawa 481b59
      assert((TRaster32P)ras || (TRaster64P)ras || (TRasterFP)ras);
Shinya Kitaoka 120a6e
      return ras;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      return TRasterP();
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    // Just schedule the frame for calculation, and return a void raster ptr
Shinya Kitaoka 120a6e
    if (renderIfNeeded) m_imp->refreshFrame(frame);
Shinya Kitaoka 120a6e
    return TRasterP();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Verifica se \b frame e' nella cache, cioe' se il frame e' disponibile
Shinya Kitaoka 120a6e
bool Previewer::isFrameReady(int frame) const {
shun_iwasawa f507ce
  if (frame < 0 || frame >= (int)m_imp->m_pbStatus.size()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return m_imp->m_pbStatus[frame] == FlipSlider::PBFrameFinished;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Previewer::isActive() const { return !m_imp->m_listeners.empty(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool Previewer::isBusy() const {
Shinya Kitaoka 120a6e
  return !m_imp->m_listeners.empty() && m_imp->m_computingFrameCount > 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Richiama IMP::invalidateFrames(string aliasKeyframe) per aggiornare il frame
Shinya Kitaoka 120a6e
//! \b fid.
Shinya Kitaoka 120a6e
void Previewer::onImageChange(TXshLevel *xl, const TFrameId &fid) {
Shinya Kitaoka 120a6e
  TFilePath fp             = xl->getPath().withFrame(fid);
Shinya Kitaoka 120a6e
  std::string levelKeyword = ::to_string(fp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Inform the cache managers of level invalidation
Shinya Kitaoka 120a6e
  if (!m_imp->m_subcamera)
Shinya Kitaoka 120a6e
    TPassiveCacheManager::instance()->invalidateLevel(levelKeyword);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->updateAliasKeyword(levelKeyword);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::clear(int frame) {
Shinya Kitaoka 120a6e
  m_imp->remove(frame);
Shinya Kitaoka 120a6e
  m_imp->updateProgressBarStatus();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::clear() {
Shinya Kitaoka 120a6e
  m_imp->remove();
Shinya Kitaoka 120a6e
  m_imp->updateAliases();
Shinya Kitaoka 120a6e
  m_imp->updateFrameRange();
Shinya Kitaoka 120a6e
  m_imp->updateRenderSettings();
Shinya Kitaoka 120a6e
  m_imp->updateCamera();
Shinya Kitaoka 120a6e
  m_imp->updatePreviewRect();
Shinya Kitaoka 120a6e
  m_imp->updateProgressBarStatus();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::clearAll() {
Shinya Kitaoka 120a6e
  Previewer::instance(false)->clear();
Shinya Kitaoka 120a6e
  Previewer::instance(true)->clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Refreshes all scene frames
Shinya Kitaoka 120a6e
void Previewer::update() {
Shinya Kitaoka 120a6e
  if (m_imp->m_listeners.empty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_imp->updateAliases();
Shinya Kitaoka 120a6e
  m_imp->updateFrameRange();
Shinya Kitaoka 120a6e
  m_imp->updateRenderSettings();
Shinya Kitaoka 120a6e
  m_imp->updateCamera();
Shinya Kitaoka 120a6e
  m_imp->updatePreviewRect();
Shinya Kitaoka 120a6e
  m_imp->updateProgressBarStatus();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_imp->notifyUpdate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Limited version of update(), just refreshes the view area.
Shinya Kitaoka 120a6e
void Previewer::updateView() {
Shinya Kitaoka 120a6e
  if (m_imp->m_listeners.empty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_imp->updateFrameRange();
Shinya Kitaoka 120a6e
  m_imp->updateRenderSettings();
Shinya Kitaoka 120a6e
  m_imp->updateCamera();
Shinya Kitaoka 120a6e
  m_imp->updatePreviewRect();
Shinya Kitaoka 120a6e
  m_imp->updateProgressBarStatus();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_imp->notifyUpdate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::onLevelChange(TXshLevel *xl) {
Shinya Kitaoka 120a6e
  TFilePath fp             = xl->getPath();
Shinya Kitaoka 120a6e
  std::string levelKeyword = ::to_string(fp);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Inform the cache managers of level invalidation
Shinya Kitaoka 120a6e
  if (!m_imp->m_subcamera)
Shinya Kitaoka 120a6e
    TPassiveCacheManager::instance()->invalidateLevel(levelKeyword);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->updateAliasKeyword(levelKeyword);
Shinya Kitaoka 120a6e
  m_imp->updateProgressBarStatus();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->notifyUpdate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::onLevelChanged() {
Shinya Kitaoka 120a6e
  TXshLevel *xl = TApp::instance()->getCurrentLevel()->getLevel();
Shinya Kitaoka 120a6e
  if (!xl) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::string levelKeyword;
Shinya Kitaoka 120a6e
  TFilePath fp = xl->getPath();
Shinya Kitaoka 120a6e
  levelKeyword = ::to_string(fp.withType(""));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Inform the cache managers of level invalidation
Shinya Kitaoka 120a6e
  if (!m_imp->m_subcamera)
Shinya Kitaoka 120a6e
    TPassiveCacheManager::instance()->invalidateLevel(levelKeyword);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->updateAliasKeyword(levelKeyword);
Shinya Kitaoka 120a6e
  m_imp->updateProgressBarStatus();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Seems that the scene viewer does not update in this case...
Shinya Kitaoka 120a6e
  m_imp->notifyUpdate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::onFxChanged() {
Shinya Kitaoka 120a6e
  m_imp->updateAliases();
Shinya Kitaoka 120a6e
  m_imp->updateProgressBarStatus();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->notifyUpdate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::onXsheetChanged() {
Shinya Kitaoka 120a6e
  m_imp->updateRenderSettings();
Shinya Kitaoka 120a6e
  m_imp->updateCamera();
Shinya Kitaoka 120a6e
  m_imp->updateFrameRange();
Shinya Kitaoka 120a6e
  m_imp->updateAliases();
Shinya Kitaoka 120a6e
  m_imp->updateProgressBarStatus();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->notifyUpdate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::onObjectChanged() {
Shinya Kitaoka 120a6e
  m_imp->updateAliases();
Shinya Kitaoka 120a6e
  m_imp->updateProgressBarStatus();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->notifyUpdate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::onChange(const TFxChange &change) { onObjectChanged(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::emitStartedFrame(const TRenderPort::RenderData &renderData) {
Shinya Kitaoka 120a6e
  emit startedFrame(renderData);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::emitRenderedFrame(const TRenderPort::RenderData &renderData) {
Shinya Kitaoka 120a6e
  emit renderedFrame(renderData);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::emitFailedFrame(const TRenderPort::RenderData &renderData) {
Shinya Kitaoka 120a6e
  emit failedFrame(renderData);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::onStartedFrame(TRenderPort::RenderData renderData) {
Shinya Kitaoka 120a6e
  // Invoke the corresponding function. This happens in the MAIN THREAD
Shinya Kitaoka 120a6e
  m_imp->doOnRenderRasterStarted(renderData);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::onRenderedFrame(TRenderPort::RenderData renderData) {
Shinya Kitaoka 120a6e
  m_imp->doOnRenderRasterCompleted(renderData);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void Previewer::onFailedFrame(TRenderPort::RenderData renderData) {
Shinya Kitaoka 120a6e
  m_imp->doOnRenderRasterFailed(renderData);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! The suspendRendering method allows suspension of the previewer's rendering
Shinya Kitaoka 120a6e
//! activity for safety purposes, typically related to the fact that no
Shinya Kitaoka 120a6e
//! rendering
Shinya Kitaoka 120a6e
//! process should actually be performed as the underlying scene is about to
Shinya Kitaoka 120a6e
//! change
Shinya Kitaoka 120a6e
//! or being destroyed. Upon suspension, further rendering requests are silently
Shinya Kitaoka 120a6e
//! rejected - and currently active ones are canceled and waited until they are
Shinya Kitaoka 120a6e
//! no
Shinya Kitaoka 120a6e
//! longer active.
Shinya Kitaoka 120a6e
//! NOTE: This method is currently static declared, since the Previewer must be
Shinya Kitaoka 120a6e
//! be instanced only after a consistent scene has been initialized. This method
Shinya Kitaoka 120a6e
//! is allowed to bypass such limitation.
Shinya Kitaoka 120a6e
void Previewer::suspendRendering(bool suspend) {
Shinya Kitaoka 120a6e
  suspendedRendering = suspend;
Shinya Kitaoka 120a6e
  if (suspend && previewerInstance)
Shinya Kitaoka 120a6e
    previewerInstance->m_imp->m_renderer.stopRendering(true);
Shinya Kitaoka 120a6e
  if (suspend && previewerInstanceSC)
Shinya Kitaoka 120a6e
    previewerInstanceSC->m_imp->m_renderer.stopRendering(true);
Toshihiro Shimizu 890ddd
}