Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "trenderer.h"
Toshihiro Shimizu 890ddd
#include "trasterfx.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <algorithm></algorithm>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tpredictivecachemanager.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
//    Preliminaries
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class TPredictiveCacheManagerGenerator final
Shinya Kitaoka 120a6e
    : public TRenderResourceManagerGenerator {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TPredictiveCacheManagerGenerator() : TRenderResourceManagerGenerator(true) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  TRenderResourceManager *operator()(void) override {
Shinya Kitaoka 120a6e
    return new TPredictiveCacheManager;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
MANAGER_FILESCOPE_DECLARATION_DEP(TPredictiveCacheManager,
Shinya Kitaoka 120a6e
                                  TPredictiveCacheManagerGenerator,
Shinya Kitaoka 120a6e
                                  TFxCacheManager::deps())
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPredictiveCacheManager *TPredictiveCacheManager::instance() {
Shinya Kitaoka 120a6e
  return static_cast<tpredictivecachemanager *="">(</tpredictivecachemanager>
Shinya Kitaoka 120a6e
      // TPredictiveCacheManager::gen()->getManager(TRenderer::instance())
Shinya Kitaoka 120a6e
      TPredictiveCacheManager::gen()->getManager(TRenderer::renderId()));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
//    TPredictiveCacheManager::Imp definition
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=======================
Toshihiro Shimizu 890ddd
//    PredictionData
Toshihiro Shimizu 890ddd
//-----------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct PredictionData {
Shinya Kitaoka 120a6e
  const ResourceDeclaration *m_decl;
Shinya Kitaoka 120a6e
  int m_usageCount;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  PredictionData(const ResourceDeclaration *declaration)
Shinya Kitaoka 120a6e
      : m_decl(declaration), m_usageCount(1) {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//============================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=====================================
Toshihiro Shimizu 890ddd
//    TPredictiveCacheManager::Imp
Toshihiro Shimizu 890ddd
//-------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TPredictiveCacheManager::Imp {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  int m_renderStatus;
Shinya Kitaoka 120a6e
  bool m_enabled;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<tcacheresourcep, predictiondata=""> m_resources;</tcacheresourcep,>
Shinya Kitaoka 120a6e
  QMutex m_mutex;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Imp()
Shinya Kitaoka 120a6e
      : m_renderStatus(TRenderer::IDLE)
Shinya Kitaoka 120a6e
      , m_enabled(TRenderer::instance().isPrecomputingEnabled()) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void run(TCacheResourceP &resource, const std::string &alias, const TFxP &fx,
Shinya Kitaoka 120a6e
           double frame, const TRenderSettings &rs,
Shinya Kitaoka 120a6e
           ResourceDeclaration *resData) {
Shinya Kitaoka 120a6e
    switch (m_renderStatus) {
Shinya Kitaoka 120a6e
    case TRenderer::IDLE:
Shinya Kitaoka 120a6e
    case TRenderer::COMPUTING:
Shinya Kitaoka 120a6e
      getResourceComputing(resource, alias, fx, frame, rs, resData);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case TRenderer::TESTRUN:
Shinya Kitaoka 120a6e
      getResourceTestRun(resource, alias, fx, frame, rs, resData);
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 262a92
Shinya Kitaoka 262a92
private:
Shinya Kitaoka 120a6e
  void getResourceTestRun(TCacheResourceP &resource, const std::string &alias,
Shinya Kitaoka 120a6e
                          const TFxP &fx, double frame,
Shinya Kitaoka 120a6e
                          const TRenderSettings &rs,
Shinya Kitaoka 120a6e
                          ResourceDeclaration *resData);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void getResourceComputing(TCacheResourceP &resource, const std::string &alias,
Shinya Kitaoka 120a6e
                            const TFxP &fx, double frame,
Shinya Kitaoka 120a6e
                            const TRenderSettings &rs,
Shinya Kitaoka 120a6e
                            ResourceDeclaration *resData);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
//    TPredictiveCacheManager methods
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPredictiveCacheManager::TPredictiveCacheManager()
Shinya Kitaoka 120a6e
    : m_imp(new TPredictiveCacheManager::Imp()) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPredictiveCacheManager::~TPredictiveCacheManager() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPredictiveCacheManager::setMaxTileSize(int maxTileSize) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPredictiveCacheManager::setBPP(int bpp) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPredictiveCacheManager::getResource(TCacheResourceP &resource,
Shinya Kitaoka 120a6e
                                          const std::string &alias,
Shinya Kitaoka 120a6e
                                          const TFxP &fx, double frame,
Shinya Kitaoka 120a6e
                                          const TRenderSettings &rs,
Shinya Kitaoka 120a6e
                                          ResourceDeclaration *resData) {
Shinya Kitaoka 120a6e
  if (!m_imp->m_enabled) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->run(resource, alias, fx, frame, rs, resData);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
//    Notification-related functions
Toshihiro Shimizu 890ddd
//************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPredictiveCacheManager::Imp::getResourceTestRun(
Shinya Kitaoka 120a6e
    TCacheResourceP &resource, const std::string &alias, const TFxP &fx,
Shinya Kitaoka 120a6e
    double frame, const TRenderSettings &rs, ResourceDeclaration *resData) {
Shinya Kitaoka 120a6e
  assert(resData && resData->m_rawData);
Shinya Kitaoka 120a6e
  if (!(resData && resData->m_rawData))
Shinya Kitaoka 120a6e
    // This is a very rare case. I've seen it happen once in a 'pathologic' case
Shinya Kitaoka 120a6e
    // which involved affines truncation while building aliases.
Shinya Kitaoka 120a6e
    // The rendering system didn't expect the truncated part 'resurface' in a
Shinya Kitaoka 120a6e
    // downstream fx with a slightly different affine alias.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // TODO: Affines should be coded completely in the aliases... in a compact
Shinya Kitaoka 120a6e
    // way though.
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!resource) resource = TCacheResourceP(alias, true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Lock against concurrent threads
Shinya Kitaoka 120a6e
  // QMutexLocker locker(&m_mutex);    //preComputing is currently
Shinya Kitaoka 120a6e
  // single-threaded
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::map<tcacheresourcep, predictiondata="">::iterator it =</tcacheresourcep,>
Shinya Kitaoka 120a6e
      m_resources.find(resource);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (it != m_resources.end())
Shinya Kitaoka 120a6e
    it->second.m_usageCount++;
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    // Already initializes usageCount at 1
Shinya Kitaoka 120a6e
    m_resources.insert(std::make_pair(resource, PredictionData(resData))).first;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TPredictiveCacheManager::Imp::getResourceComputing(
Shinya Kitaoka 120a6e
    TCacheResourceP &resource, const std::string &alias, const TFxP &fx,
Shinya Kitaoka 120a6e
    double frame, const TRenderSettings &rs, ResourceDeclaration *resData) {
Shinya Kitaoka 120a6e
  // If there is no declaration data, either the request can be resolved in one
Shinya Kitaoka 120a6e
  // computation code (therefore it is uninteresting for us), or it was never
Shinya Kitaoka 120a6e
  // declared.
Shinya Kitaoka 120a6e
  // Anyway, return.
Shinya Kitaoka 120a6e
  if (!resData) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // NO! The refCount is dynamically depleted - could become 0 from n...
Shinya Kitaoka 120a6e
  // assert(!(resData->m_tiles.size() == 1 && resData->m_tiles[0].m_refCount ==
Shinya Kitaoka 120a6e
  // 1));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!resource) resource = TCacheResourceP(alias);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!resource) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Lock against concurrent threads
Shinya Kitaoka 120a6e
  QMutexLocker locker(&m_mutex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<tcacheresourcep, predictiondata="">::iterator it =</tcacheresourcep,>
Shinya Kitaoka 120a6e
      m_resources.find(resource);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (it == m_resources.end()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (--it->second.m_usageCount <= 0) m_resources.erase(it);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPredictiveCacheManager::onRenderStatusStart(int renderStatus) {
Shinya Kitaoka 120a6e
  m_imp->m_renderStatus = renderStatus;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPredictiveCacheManager::onRenderStatusEnd(int renderStatus) {
Shinya Kitaoka 120a6e
  switch (renderStatus) {
Shinya Kitaoka 120a6e
  case TRenderer::TESTRUN:
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // All resources which have just 1 computation tile, which is also
Shinya Kitaoka 120a6e
    // referenced
Shinya Kitaoka 120a6e
    // only once, are released.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::map<tcacheresourcep, predictiondata="">::iterator it;</tcacheresourcep,>
Shinya Kitaoka 120a6e
    for (it = m_imp->m_resources.begin(); it != m_imp->m_resources.end();) {
Shinya Kitaoka 120a6e
      const ResourceDeclaration *decl = it->second.m_decl;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (decl->m_tiles.size() == 1 && decl->m_tiles[0].m_refCount == 1) {
Shinya Kitaoka 120a6e
        std::map<tcacheresourcep, predictiondata="">::iterator jt = it++;</tcacheresourcep,>
Shinya Kitaoka 120a6e
        m_imp->m_resources.erase(jt);
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        it++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}