| |
| |
| #include <string> |
| |
| #include "trenderer.h" |
| #include "tcacheresourcepool.h" |
| |
| #include "tfxcachemanager.h" |
| |
| |
| |
| #ifdef DIAGNOSTICS |
| |
| #include "diagnostics.h" |
| |
| |
| |
| |
| |
| namespace |
| { |
| QString traduce(const TRectD &rect) |
| { |
| return "[" + QString::number(rect.x0) + " " + QString::number(rect.y0) + " " + QString::number(rect.x1) + " " + QString::number(rect.y1) + "]"; |
| } |
| |
| QString traduce(const TTile &tile) |
| { |
| TDimension dim(tile.getRaster()->getSize()); |
| TRectD tileRect(tile.m_pos, TDimensionD(dim.lx, dim.ly)); |
| return traduce(tileRect); |
| } |
| |
| QString prefixInfo("#info.txt | "); |
| QString prefixWarn("#warning.txt | "); |
| QString prefixErr("#error.txt | "); |
| QString prefixTest("#TestRun.txt | "); |
| QString prefixComp("#Computing.txt | "); |
| QString prefixSubTiles("#SubTiles.txt | "); |
| } |
| |
| #endif //DIAGNOSTICS |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| namespace |
| { |
| |
| |
| |
| |
| |
| |
| inline QRect toQRect(const TRect &r) { return QRect(r.x0, r.y0, r.getLx(), r.getLy()); } |
| inline TRect toTRect(const QRect &r) { return TRect(r.left(), r.top(), r.right(), r.bottom()); } |
| inline QPoint toQPoint(const TPoint &p) { return QPoint(p.x, p.y); } |
| |
| inline bool isEmpty(const TRectD &rect) { return rect.x0 >= rect.x1 || rect.y0 >= rect.y1; } |
| inline void enlargeToI(TRectD &r) |
| { |
| TRectD temp(tfloor(r.x0), tfloor(r.y0), tceil(r.x1), tceil(r.y1)); |
| if (!isEmpty(temp)) |
| r = temp; |
| } |
| |
| |
| inline bool contains(const QRegion ®ion, const TRect &rect) |
| { |
| return QRegion(toQRect(rect)).subtracted(region).isEmpty(); |
| } |
| |
| bool getTilesToBuild(const ResourceData &data, const TRectD &rect, |
| std::vector<ResourceDeclaration::TileData *> &rectsToCalculate); |
| } |
| |
| |
| |
| |
| |
| class TFxCacheManagerGenerator : public TRenderResourceManagerGenerator |
| { |
| public: |
| TFxCacheManagerGenerator() : TRenderResourceManagerGenerator(true) {} |
| |
| TRenderResourceManager *operator()() { return new TFxCacheManager; } |
| }; |
| |
| MANAGER_FILESCOPE_DECLARATION(TFxCacheManager, TFxCacheManagerGenerator); |
| |
| |
| |
| |
| |
| class TFxCacheManager::Imp |
| { |
| public: |
| typedef std::map<std::string, ResourceDeclaration> ResourceInstanceDataMap; |
| |
| ResourceInstanceDataMap m_resourcesData; |
| std::map<ResourceDeclaration *, ResourceDeclaration::RawData> m_rawData; |
| int m_renderStatus; |
| |
| QMutex m_mutex; |
| |
| public: |
| void prepareTilesToCalculate(ResourceDeclaration &data); |
| inline void subdivideIntoSmallerTiles(const TRectD &rect, std::vector<TRectD> &tileSet); |
| void recursiveRectSubdivide( |
| std::vector<ResourceDeclaration::TileData> &results, TRasterFx *fx, |
| const TRectD &rect, double frame, const TRenderSettings &info, |
| int dropTol = (std::numeric_limits<int>::max)()); |
| }; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| TFxCacheManager::TFxCacheManager() |
| : m_imp(new Imp) |
| { |
| } |
| |
| |
| |
| TFxCacheManager::~TFxCacheManager() |
| { |
| |
| std::set<std::string>::iterator it; |
| for (it = m_staticCacheIds.begin(); it != m_staticCacheIds.end(); ++it) |
| TImageCache::instance()->remove(*it); |
| } |
| |
| |
| |
| TFxCacheManager *TFxCacheManager::instance() |
| { |
| return static_cast<TFxCacheManager *>( |
| TFxCacheManager::gen()->getManager(TRenderer::renderId())); |
| } |
| |
| |
| |
| void TFxCacheManager::add(const std::string &cacheId, TImageP img) |
| { |
| TImageCache::instance()->add(cacheId, img); |
| |
| QMutexLocker locker(&m_imp->m_mutex); |
| m_staticCacheIds.insert(cacheId); |
| } |
| |
| |
| |
| void TFxCacheManager::remove(const std::string &cacheId) |
| { |
| TImageCache::instance()->remove(cacheId); |
| |
| QMutexLocker locker(&m_imp->m_mutex); |
| m_staticCacheIds.erase(cacheId); |
| } |
| |
| |
| |
| void TFxCacheManager::install(TFxCacheManagerDelegate *managerDelegate) |
| { |
| m_delegates.insert(managerDelegate); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| void TFxCacheManager::declareResource( |
| const string &alias, const TFxP &fx, |
| const TRectD &rect, double frame, const TRenderSettings &rs, |
| bool subtileable) |
| { |
| Imp::ResourceInstanceDataMap::iterator it; |
| it = m_imp->m_resourcesData.insert(std::make_pair(alias, ResourceDeclaration())).first; |
| it->second.m_rawData = |
| &m_imp->m_rawData.insert(std::make_pair(&it->second, ResourceDeclaration::RawData())).first->second; |
| |
| ResourceDeclaration::RawData &rawData = *it->second.m_rawData; |
| |
| |
| rawData.m_fx = fx; |
| rawData.m_tiles.push_back(rect); |
| rawData.m_rs = rs; |
| rawData.m_frame = frame; |
| |
| rawData.m_subtileable = subtileable; |
| } |
| |
| |
| |
| ResourceData TFxCacheManager::getResource( |
| const string &alias, |
| const TFxP &fx, double frame, const TRenderSettings &rs) |
| { |
| TCacheResourceP result, temp; |
| |
| |
| Imp::ResourceInstanceDataMap::iterator jt = |
| m_imp->m_resourcesData.find(alias); |
| ResourceDeclaration *decl = (jt == m_imp->m_resourcesData.end()) ? 0 : &jt->second; |
| |
| |
| |
| |
| |
| |
| |
| std::set<TFxCacheManagerDelegate *>::iterator it; |
| for (it = m_delegates.begin(); it != m_delegates.end(); ++it) { |
| (*it)->getResource(temp, alias, fx, frame, rs, decl); |
| if (!result && temp) |
| result = temp; |
| } |
| |
| |
| |
| return ResourceData(decl, result); |
| } |
| |
| |
| |
| void TFxCacheManager::onRenderStatusStart(int renderStatus) |
| { |
| |
| m_imp->m_renderStatus = renderStatus; |
| |
| #ifdef WRITESTACK |
| if (renderStatus == TRenderer::TESTRUN) { |
| DIAGNOSTICS_GLOSTRSET("status", "test"); |
| DIAGNOSTICS_GLOSET("testInst", DIAGNOSTICS_GLOGET("compInst") + 1); |
| DIAGNOSTICS_GLOSTRSET("instVar", QString::number(DIAGNOSTICS_GLOGET("testInst"))); |
| DIAGNOSTICS_GLOSTRSET("testRenderStr", "Render #" + QString::number(DIAGNOSTICS_GLOGET("testInst")) + " | "); |
| } else if (renderStatus == TRenderer::COMPUTING) { |
| DIAGNOSTICS_GLOSTRSET("status", "comp"); |
| DIAGNOSTICS_GLOSTRSET("instVar", QString::number(DIAGNOSTICS_GLOGET("compInst"))); |
| DIAGNOSTICS_GLOSTRSET("compRenderStr", "Render #" + QString::number(DIAGNOSTICS_GLOGET("compInst")) + " | "); |
| DIAGNOSTICS_GLOSET(DIAGNOSTICS_THRSTRGET("stackVar"), 0); |
| } |
| #endif |
| } |
| |
| |
| |
| void TFxCacheManager::onRenderStatusEnd(int renderStatus) |
| { |
| if (renderStatus == TRenderer::FIRSTRUN) { |
| Imp::ResourceInstanceDataMap &resMap = m_imp->m_resourcesData; |
| |
| Imp::ResourceInstanceDataMap::iterator it; |
| for (it = resMap.begin(); it != resMap.end();) { |
| m_imp->prepareTilesToCalculate(it->second); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ++it; |
| } |
| } else if (renderStatus == TRenderer::TESTRUN) { |
| Imp::ResourceInstanceDataMap &resMap = m_imp->m_resourcesData; |
| Imp::ResourceInstanceDataMap::iterator it; |
| for (it = resMap.begin(); it != resMap.end();) { |
| |
| if (it->second.m_tiles.size() == 1 && it->second.m_tiles[0].m_refCount == 1) { |
| Imp::ResourceInstanceDataMap::iterator jt = it++; |
| resMap.erase(jt); |
| continue; |
| } |
| |
| |
| |
| |
| it->second.m_rawData = 0; |
| |
| ++it; |
| } |
| |
| #ifdef WRITEGENERAL |
| DIAGNOSTICS_SET("Declarations used more than once", resMap.size()); |
| #endif |
| |
| m_imp->m_rawData.clear(); |
| } |
| #ifdef WRITEGENERAL |
| else { |
| |
| Imp::ResourceInstanceDataMap &resMap = m_imp->m_resourcesData; |
| Imp::ResourceInstanceDataMap::iterator it; |
| |
| DIAGNOSTICS_ADD(prefixErr + "Computing | Declarations survived after Test Run", resMap.size()); |
| if (resMap.size() > 0) { |
| for (it = resMap.begin(); it != resMap.end(); ++it) { |
| DIAGNOSTICS_STR(prefixErr + "Survived Declarations | " + QString::fromStdString(it->first).left(40)); |
| } |
| } |
| } |
| #endif |
| } |
| |
| |
| |
| |
| |
| void TFxCacheManager::Imp::prepareTilesToCalculate(ResourceDeclaration &data) |
| { |
| |
| TRectD sum; |
| int tilesCount = data.m_rawData->m_tiles.size(); |
| |
| for (int i = 0; i < tilesCount; ++i) |
| sum += data.m_rawData->m_tiles[i]; |
| |
| |
| |
| enlargeToI(sum); |
| |
| if (!data.m_rawData->m_subtileable) { |
| data.m_tiles.push_back(sum); |
| return; |
| } |
| |
| TRasterFx *fx = dynamic_cast<TRasterFx *>(data.m_rawData->m_fx.getPointer()); |
| |
| |
| recursiveRectSubdivide(data.m_tiles, fx, sum, data.m_rawData->m_frame, data.m_rawData->m_rs); |
| } |
| |
| |
| |
| |
| |
| inline void TFxCacheManager::Imp::subdivideIntoSmallerTiles( |
| const TRectD &rect, std::vector<TRectD> &tileSet) |
| { |
| |
| TRectD subTile1, subTile2; |
| if (rect.getLx() > rect.getLy()) { |
| int sep = rect.x0 + tceil(0.5 * rect.getLx()); |
| subTile1 = TRectD(rect.x0, rect.y0, sep, rect.y1); |
| subTile2 = TRectD(sep, rect.y0, rect.x1, rect.y1); |
| } else { |
| int sep = rect.y0 + tceil(0.5 * rect.getLy()); |
| subTile1 = TRectD(rect.x0, rect.y0, rect.x1, sep); |
| subTile2 = TRectD(rect.x0, sep, rect.x1, rect.y1); |
| } |
| |
| tileSet.push_back(subTile1); |
| tileSet.push_back(subTile2); |
| } |
| |
| |
| |
| void TFxCacheManager::Imp::recursiveRectSubdivide( |
| std::vector<ResourceDeclaration::TileData> &results, |
| TRasterFx *fx, |
| const TRectD &rect, |
| double frame, |
| const TRenderSettings &info, |
| int dropTol) |
| { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| int memReq = fx ? fx->getMemoryRequirement(rect, frame, info) : 0; |
| |
| |
| |
| if (memReq < 0) { |
| results.push_back(rect); |
| return; |
| } |
| |
| if ((memReq > info.m_maxTileSize && memReq < dropTol) || |
| TRasterFx::memorySize(rect, info.m_bpp) > info.m_maxTileSize) { |
| std::vector<TRectD> subTileRects; |
| subdivideIntoSmallerTiles(rect, subTileRects); |
| |
| while (!subTileRects.empty()) { |
| TRectD subTileRect(subTileRects.back()); |
| subTileRects.pop_back(); |
| |
| |
| recursiveRectSubdivide(results, fx, subTileRect, frame, info, |
| memReq - (memReq >> 2)); |
| |
| |
| |
| } |
| |
| return; |
| } |
| |
| results.push_back(ResourceDeclaration::TileData(rect)); |
| } |
| |
| |
| |
| |
| |
| ResourceBuilder::ResourceBuilder( |
| const std::string &resourceName, |
| const TFxP &fx, double frame, const TRenderSettings &rs) |
| : m_cacheManager(TFxCacheManager::instance()), m_data(m_cacheManager->getResource(resourceName, fx, frame, rs)) |
| { |
| #ifdef WRITESTACK |
| DIAGNOSTICS_THRSET("frame", frame); |
| DIAGNOSTICS_THRSTRSET("frameStr", "Frame " + QString::number(frame).rightJustified(4, ' ') + " | "); |
| DIAGNOSTICS_THRSTRSET("stackVar", |
| DIAGNOSTICS_GLOSTRGET("status") + "sv" + DIAGNOSTICS_GLOSTRGET("instVar") + "fr" + QString::number(frame)); |
| DIAGNOSTICS_THRSTRSET("ResourceName", QString::fromStdString(resourceName).left(35)); |
| #endif |
| } |
| |
| |
| |
| void ResourceBuilder::declareResource( |
| const string &alias, const TFxP &fx, |
| const TRectD &rect, double frame, const TRenderSettings &rs, |
| bool subtileable) |
| { |
| TFxCacheManager::instance()->declareResource( |
| alias, fx, rect, frame, rs, subtileable); |
| } |
| |
| |
| |
| namespace |
| { |
| |
| |
| |
| |
| |
| |
| bool getTilesToBuild( |
| const ResourceData &data, const TRectD &rect, std::vector<ResourceDeclaration::TileData *> &rectsToCalculate) |
| { |
| assert(data.first); |
| assert(data.second); |
| |
| |
| |
| |
| std::vector<ResourceDeclaration::TileData> &preparedRects = |
| data.first->m_tiles; |
| std::vector<ResourceDeclaration::TileData>::iterator jt; |
| |
| TRectD sum; |
| for (jt = preparedRects.begin(); jt != preparedRects.end(); ++jt) { |
| sum += jt->m_rect; |
| |
| if (!(isEmpty(rect * jt->m_rect) || jt->m_calculated)) |
| rectsToCalculate.push_back(&(*jt)); |
| } |
| |
| return sum.contains(rect); |
| } |
| } |
| |
| |
| |
| void ResourceBuilder::simBuild(const TRectD &rect) |
| { |
| |
| int renderStatus = m_cacheManager->m_imp->m_renderStatus; |
| |
| |
| if (renderStatus == TRenderer::FIRSTRUN) { |
| simCompute(rect); |
| return; |
| } |
| |
| |
| if (renderStatus == TRenderer::TESTRUN) { |
| if (!(m_data.first && m_data.second)) |
| return; |
| |
| #ifdef WRITESTACK |
| QString resName(DIAGNOSTICS_THRSTRGET("ResourceName")); |
| |
| QString renderStr(DIAGNOSTICS_GLOSTRGET("testRenderStr")); |
| QString frameStr(DIAGNOSTICS_THRSTRGET("frameStr")); |
| DIAGNOSTICS_NUMBEREDSTRSET(prefixTest + renderStr + frameStr, |
| DIAGNOSTICS_THRSTRGET("stackVar"), DIAGNOSTICS_STACKGET("parentResource") + " " + resName, |
| ::traduce(rect), 4); |
| DIAGNOSTICS_PUSHAUTO("parentResource", |
| QString::number(DIAGNOSTICS_GLOGET(DIAGNOSTICS_THRSTRGET("stackVar"))), bla); |
| #endif |
| |
| |
| std::vector<ResourceDeclaration::TileData> &tiles = m_data.first->m_tiles; |
| |
| |
| std::vector<ResourceDeclaration::TileData>::iterator it; |
| for (it = tiles.begin(); it != tiles.end(); ++it) { |
| ResourceDeclaration::TileData &tileData = *it; |
| |
| if (!isEmpty(tileData.m_rect * rect)) { |
| |
| |
| if (tileData.m_refCount == 0) { |
| #ifdef WRITESUBRECTS |
| DIAGNOSTICS_NUMBEREDSTRSET(prefixTest + renderStr + frameStr, |
| DIAGNOSTICS_THRSTRGET("stackVar"), DIAGNOSTICS_STACKGET("parentResource") + " " + resName, |
| ::traduce(tileData.m_rect), 4); |
| DIAGNOSTICS_PUSHAUTO("parentResource", |
| QString::number(DIAGNOSTICS_GLOGET(DIAGNOSTICS_THRSTRGET("stackVar"))), bla2); |
| #endif |
| |
| simCompute(tileData.m_rect); |
| ++m_data.first->m_tilesCount; |
| } |
| |
| |
| ++tileData.m_refCount; |
| |
| if (m_data.second) { |
| QMutexLocker locker(m_data.second->getMutex()); |
| |
| TRect tileRectI( |
| tileData.m_rect.x0, tileData.m_rect.y0, |
| tileData.m_rect.x1 - 1, tileData.m_rect.y1 - 1); |
| |
| m_data.second->addRef2(tileRectI); |
| } |
| } |
| } |
| |
| return; |
| } |
| |
| |
| |
| |
| |
| |
| |
| if (renderStatus == TRenderer::COMPUTING) { |
| if (!(m_data.first && m_data.second)) |
| return; |
| |
| QMutexLocker locker(m_data.second->getMutex()); |
| |
| |
| std::vector<ResourceDeclaration::TileData> &tiles = m_data.first->m_tiles; |
| |
| |
| |
| |
| |
| std::vector<ResourceDeclaration::TileData>::iterator it; |
| for (it = tiles.begin(); it != tiles.end(); ++it) { |
| ResourceDeclaration::TileData &tileData = *it; |
| |
| if (!isEmpty(tileData.m_rect * rect)) { |
| if (tileData.m_refCount <= 0) |
| continue; |
| |
| if (--tileData.m_refCount == 0 && !tileData.m_calculated) { |
| --m_data.first->m_tilesCount; |
| simCompute(tileData.m_rect); |
| } |
| |
| if (m_data.second) { |
| TRect tileRectI( |
| tileData.m_rect.x0, tileData.m_rect.y0, |
| tileData.m_rect.x1 - 1, tileData.m_rect.y1 - 1); |
| |
| m_data.second->release2(tileRectI); |
| } |
| } |
| } |
| } |
| } |
| |
| |
| |
| void ResourceBuilder::build(const TRectD &tileRect) |
| { |
| #ifdef WRITESTACK |
| QString resName(DIAGNOSTICS_THRSTRGET("ResourceName")); |
| |
| QString renderStr(DIAGNOSTICS_GLOSTRGET("compRenderStr")); |
| QString frameStr(DIAGNOSTICS_THRSTRGET("frameStr")); |
| DIAGNOSTICS_NUMBEREDSTRSET(prefixComp + renderStr + frameStr, |
| DIAGNOSTICS_THRSTRGET("stackVar"), DIAGNOSTICS_STACKGET("parentResource") + " " + resName, |
| ::traduce(tileRect), 4); |
| DIAGNOSTICS_PUSHAUTO("parentResource", |
| QString::number(DIAGNOSTICS_GLOGET(DIAGNOSTICS_THRSTRGET("stackVar"))), bla); |
| #endif |
| |
| |
| if (!m_data.second) { |
| #ifdef WRITEGENERAL |
| if (m_data.first) |
| if (m_data.first->m_tilesCount > 0) |
| DIAGNOSTICS_ADD(prefixErr + "Computing | No-resource build, active decl, tilesCount > 0", 1); |
| else |
| DIAGNOSTICS_ADD(prefixErr + "Computing | No-resource build, active decl, tilesCount <= 0", 1); |
| #endif |
| |
| |
| compute(tileRect); |
| return; |
| } |
| |
| |
| QMutexLocker locker(m_data.second->getMutex()); |
| |
| |
| if (!(m_data.first && m_data.first->m_tilesCount > 0)) { |
| #ifdef WRITEGENERAL |
| if (!m_data.first) |
| DIAGNOSTICS_ADD("#error.txt | Resources without declaration", 1); |
| else |
| DIAGNOSTICS_ADD("#error.txt | Resources with declaration, tilesCount <=0", 1); |
| #endif |
| |
| if (download(m_data.second)) |
| return; |
| |
| compute(tileRect); |
| |
| |
| |
| upload(m_data.second); |
| |
| return; |
| } |
| |
| |
| |
| |
| TDimension dim(tileRect.getLx(), tileRect.getLy()); |
| |
| std::vector<ResourceDeclaration::TileData *> tiles; |
| bool fittingPrediction = getTilesToBuild(m_data, tileRect, tiles); |
| |
| if (!fittingPrediction) { |
| #ifdef WRITEGENERAL |
| DIAGNOSTICS_ADD(prefixErr + "Computing | Not fitting tiles", 1); |
| #endif |
| |
| |
| |
| |
| |
| |
| |
| locker.unlock(); |
| |
| compute(tileRect); |
| return; |
| } |
| |
| |
| if (tiles.size() > 0) { |
| |
| std::vector<ResourceDeclaration::TileData *>::iterator it; |
| for (it = tiles.begin(); it != tiles.end(); ++it) { |
| ResourceDeclaration::TileData &tileData = **it; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| TRect tileRectI( |
| tileData.m_rect.x0, tileData.m_rect.y0, |
| tileData.m_rect.x1 - 1, tileData.m_rect.y1 - 1); |
| |
| if (m_data.second->canDownloadAll(tileRectI)) { |
| if (!tileData.m_calculated && tileData.m_refCount > 0) { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| simCompute(tileData.m_rect); |
| } |
| } else { |
| #ifdef WRITESUBRECTS |
| DIAGNOSTICS_NUMBEREDSTRSET(prefixComp + renderStr + frameStr, |
| DIAGNOSTICS_THRSTRGET("stackVar"), DIAGNOSTICS_STACKGET("parentResource") + " " + resName, |
| ::traduce(tileData.m_rect), 4); |
| DIAGNOSTICS_PUSHAUTO("parentResource", |
| QString::number(DIAGNOSTICS_GLOGET(DIAGNOSTICS_THRSTRGET("stackVar"))), bla2); |
| #endif |
| |
| |
| compute(tileData.m_rect); |
| if (tileData.m_refCount > 0) |
| tileData.m_calculated = true; |
| |
| |
| |
| |
| upload(m_data.second); |
| } |
| } |
| } |
| |
| |
| bool ret = download(m_data.second); |
| assert(ret); |
| |
| #ifdef WRITESTACK |
| if (!ret) |
| DIAGNOSTICS_STRSET(prefixErr + "Download falliti | " + |
| DIAGNOSTICS_GLOSTRGET("compRenderStr") + DIAGNOSTICS_THRSTRGET("frameStr") + |
| QString::number(DIAGNOSTICS_GLOGET(DIAGNOSTICS_THRSTRGET("stackVar"))), |
| "CROP #" + QString::number(DIAGNOSTICS_GLOGET("crStack"))); |
| #endif |
| |
| |
| |
| std::vector<ResourceDeclaration::TileData> &resTiles = m_data.first->m_tiles; |
| std::vector<ResourceDeclaration::TileData>::iterator it; |
| for (it = resTiles.begin(); it != resTiles.end(); ++it) { |
| ResourceDeclaration::TileData &tileData = *it; |
| |
| if (!isEmpty(tileData.m_rect * tileRect)) { |
| if (tileData.m_refCount <= 0) { |
| #ifdef WRITEGENERAL |
| DIAGNOSTICS_ADD(prefixErr + "Computing | Over-used subtiles", 1); |
| #endif |
| |
| continue; |
| } |
| |
| if (--tileData.m_refCount == 0) { |
| tileData.m_calculated = false; |
| --m_data.first->m_tilesCount; |
| } |
| |
| TRect tileRectI( |
| tileData.m_rect.x0, tileData.m_rect.y0, |
| tileData.m_rect.x1 - 1, tileData.m_rect.y1 - 1); |
| |
| m_data.second->release2(tileRectI); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
| |