| |
| |
| #include "toonzqt/swatchviewer.h" |
| #include "toonzqt/gutil.h" |
| |
| #include <QPainter> |
| #include <QMouseEvent> |
| #include <QResizeEvent> |
| |
| #include "trasterfx.h" |
| #include "toonz/tcolumnfx.h" |
| #include "tparamcontainer.h" |
| #include "tfxutil.h" |
| |
| |
| #include "tfxcachemanager.h" |
| #include "tcacheresourcepool.h" |
| #include "tpassivecachemanager.h" |
| |
| #include <QEventLoop> |
| #include <QCoreApplication> |
| |
| using namespace TFxUtil; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| class SwatchCacheManager final : public TFxCacheManagerDelegate { |
| T_RENDER_RESOURCE_MANAGER |
| |
| unsigned long m_setFxId; |
| std::set<unsigned long> m_childrenFxIds; |
| |
| std::set<TCacheResourceP> m_genericCacheContainer; |
| std::set<TCacheResourceP> m_swatchCacheContainer; |
| TCacheResourceP m_currEditedFxResult; |
| |
| QMutex m_mutex; |
| |
| public: |
| SwatchCacheManager() {} |
| ~SwatchCacheManager() {} |
| |
| static SwatchCacheManager *instance(); |
| |
| void setFx(const TFxP &actualFx); |
| |
| void clearSwatchResults(); |
| |
| void getResource(TCacheResourceP &resource, const std::string &alias, |
| const TFxP &fx, double frame, const TRenderSettings &rs, |
| ResourceDeclaration *resData) override; |
| |
| |
| |
| |
| bool renderHasOwnership() override { return false; } |
| }; |
| |
| |
| |
| |
| |
| class SwatchCacheManagerGenerator final |
| : public TRenderResourceManagerGenerator { |
| TRenderResourceManager *operator()(void) override { |
| |
| return SwatchCacheManager::instance(); |
| } |
| }; |
| |
| MANAGER_FILESCOPE_DECLARATION_DEP(SwatchCacheManager, |
| SwatchCacheManagerGenerator, |
| TFxCacheManager::deps()) |
| |
| |
| namespace { |
| |
| |
| |
| |
| void setFxForCaching(TFx *fx) { |
| SwatchCacheManager::instance()->setFx(fx); |
| TPassiveCacheManager::instance()->releaseContextNamesWithPrefix("S"); |
| } |
| |
| |
| |
| |
| std::string matchSuffix(std::string name, std::string suffix) { |
| if (name.length() <= suffix.length()) return ""; |
| int i = name.length() - suffix.length(); |
| if (name.substr(i) == suffix) |
| return name.substr(0, i); |
| else |
| return ""; |
| } |
| |
| |
| |
| TRaster32P createCrossIcon() { |
| TRaster32P crossIcon = TRaster32P(7, 7); |
| |
| |
| crossIcon->fill(TPixel32(0, 0, 0, 0)); |
| TPixel32 *c = crossIcon->pixels(3) + 3; |
| for (int i = 1; i <= 3; i++) |
| c[i] = c[-i] = c[7 * i] = c[-7 * i] = |
| (i & 1) == 0 ? TPixel32::White : TPixel32::Red; |
| return crossIcon; |
| } |
| |
| |
| |
| |
| |
| |
| TRaster32P createArrowShape(int len) { |
| int d = 5; |
| if (len < d) len = d; |
| TPixel32 c0(210, 210, 210); |
| TPixel32 c1(10, 10, 10); |
| |
| TRaster32P ras(len, d * 2 + 1); |
| ras->clear(); |
| ras->lock(); |
| TPixel32 *pix = ras->pixels(d); |
| int x = 0; |
| for (x = 0; x < len; x++) pix[x] = (x & 8) == 0 ? c0 : c1; |
| for (x = 1; x < d; x++) |
| for (int y = -x; y < x; y++) { |
| assert(ras->getBounds().contains(TPoint(x, y + d))); |
| pix[len * y + x] = c0; |
| } |
| ras->unlock(); |
| return ras; |
| } |
| |
| |
| |
| |
| |
| |
| #define ZOOMLEVELS 30 |
| #define NOZOOMINDEX 20 |
| double ZoomFactors[ZOOMLEVELS] = { |
| 0.001, 0.002, 0.003, 0.004, 0.005, 0.007, 0.01, 0.015, 0.02, 0.03, |
| 0.04, 0.05, 0.0625, 0.0833, 0.125, 0.167, 0.25, 0.333, 0.5, 0.667, |
| 1, 2, 3, 4, 5, 6, 7, 8, 12, 16}; |
| |
| double getQuantizedZoomFactor(double zf, bool forward) { |
| if (forward && zf > ZoomFactors[ZOOMLEVELS - 1] || |
| areAlmostEqual(zf, ZoomFactors[ZOOMLEVELS - 1], 1e-5)) |
| return zf; |
| else if (!forward && zf < ZoomFactors[0] || |
| areAlmostEqual(zf, ZoomFactors[0], 1e-5)) |
| return zf; |
| |
| assert((!forward && zf > ZoomFactors[0]) || |
| (forward && zf < ZoomFactors[ZOOMLEVELS - 1])); |
| int i = 0; |
| for (i = 0; i <= ZOOMLEVELS - 1; i++) |
| if (areAlmostEqual(zf, ZoomFactors[i], 1e-5)) zf = ZoomFactors[i]; |
| |
| if (forward && zf < ZoomFactors[0]) |
| return ZoomFactors[0]; |
| else if (!forward && zf > ZoomFactors[ZOOMLEVELS - 1]) |
| return ZoomFactors[ZOOMLEVELS - 1]; |
| |
| for (i = 0; i < ZOOMLEVELS - 1; i++) |
| if (ZoomFactors[i + 1] - zf >= 0 && zf - ZoomFactors[i] >= 0) { |
| if (forward && ZoomFactors[i + 1] == zf) |
| return ZoomFactors[i + 2]; |
| else if (!forward && ZoomFactors[i] == zf) |
| return ZoomFactors[i - 1]; |
| else |
| return forward ? ZoomFactors[i + 1] : ZoomFactors[i]; |
| } |
| return ZoomFactors[NOZOOMINDEX]; |
| } |
| |
| |
| |
| bool suspendedRendering = false; |
| QEventLoop *waitingLoop = 0; |
| int submittedTasks = 0; |
| |
| |
| } |
| |
| |
| |
| |
| |
| |
| #if QT_VERSION >= 0x050500 |
| SwatchViewer::SwatchViewer(QWidget *parent, Qt::WindowFlags flags) |
| #else |
| SwatchViewer::SwatchViewer(QWidget *parent, Qt::WFlags flags) |
| #endif |
| : QWidget(parent, flags) |
| , m_fx(0) |
| , m_actualFxClone(0) |
| , m_mouseButton(Qt::NoButton) |
| , m_selectedPoint(0) |
| , m_pointPosDelta(TPointD()) |
| , m_enabled(false) |
| , m_content() |
| , m_aff(TAffine()) |
| , m_fxAff(TAffine()) |
| , m_cameraRect() |
| , m_bgPainter(0) |
| , m_pos(TPoint()) |
| , m_firstPos(TPoint()) |
| , m_oldContent() |
| , m_curContent() |
| , m_executor() { |
| |
| setMinimumHeight(150); |
| setFixedWidth(150); |
| setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); |
| |
| m_raster = TRaster32P(width(), height()); |
| m_crossIcon = createCrossIcon(); |
| setFocusPolicy(Qt::StrongFocus); |
| m_executor.setDedicatedThreads(true); |
| m_executor.setMaxActiveTasks(1); |
| |
| m_renderer.enablePrecomputing(false); |
| } |
| |
| |
| |
| SwatchViewer::~SwatchViewer() {} |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| void SwatchViewer::suspendRendering(bool suspend, bool blocking) { |
| suspendedRendering = suspend; |
| |
| if (suspend && submittedTasks > 0 && blocking) { |
| QEventLoop loop; |
| |
| waitingLoop = &loop; |
| loop.exec(); |
| waitingLoop = 0; |
| } |
| } |
| |
| |
| |
| void SwatchViewer::setCameraSize(const TDimension &cameraSize) { |
| TRect cameraRect(cameraSize); |
| if (cameraRect != m_cameraRect) { |
| m_cameraRect = cameraRect; |
| updateSize(size()); |
| |
| } |
| } |
| |
| |
| |
| void SwatchViewer::setFx(const TFxP &fx, const TFxP &actualFx, int frame) { |
| m_fx = m_actualFxClone = fx; |
| m_frame = frame; |
| m_points.clear(); |
| m_pointPairs.clear(); |
| |
| if (!fx) { |
| ::setFxForCaching(0); |
| computeContent(); |
| return; |
| } |
| |
| |
| ::setFxForCaching(actualFx.getPointer()); |
| |
| if (NaAffineFx *affFx = dynamic_cast<NaAffineFx *>(m_fx.getPointer())) |
| m_fxAff = affFx->getPlacement(m_frame); |
| else |
| m_fxAff = TAffine(); |
| int i; |
| for (i = 0; i < actualFx->getParams()->getParamCount(); i++) { |
| TPointParam *pointParam = |
| dynamic_cast<TPointParam *>(actualFx->getParams()->getParam(i)); |
| if (pointParam) m_points.push_back(Point(i, pointParam)); |
| } |
| |
| int n = m_points.size(); |
| for (i = 0; i < n; i++) { |
| std::string name = m_points[i].m_param->getName(); |
| std::string prefix = matchSuffix(name, "_a"); |
| if (prefix == "") continue; |
| std::string otherName = prefix + "_b"; |
| int j; |
| for (j = 0; j < n; j++) |
| if (i != j && m_points[j].m_param->getName() == otherName) break; |
| if (j < n) { |
| m_pointPairs.push_back(std::make_pair(i, j)); |
| m_points[i].m_pairFlag = m_points[j].m_pairFlag = true; |
| } |
| } |
| computeContent(); |
| } |
| |
| |
| |
| void SwatchViewer::updateFrame(int frame) { |
| m_frame = frame; |
| computeContent(); |
| update(); |
| } |
| |
| |
| |
| void SwatchViewer::setEnable(bool enabled) { |
| if (m_enabled == enabled) return; |
| m_enabled = enabled; |
| if (m_enabled) |
| computeContent(); |
| else |
| update(); |
| } |
| |
| |
| |
| void SwatchViewer::updateSize(const QSize &size) { |
| int h = size.height(); |
| double ratio = m_cameraRect.getLy() > 0 |
| ? m_cameraRect.getLx() / (double)m_cameraRect.getLy() |
| : 1.0; |
| int w = std::min((int)(h * ratio), parentWidget()->width()); |
| setFixedWidth(w); |
| if (w > 2 && h > 2) |
| m_raster = TRaster32P(TDimension(w, h)); |
| else |
| m_raster = TRaster32P(); |
| } |
| |
| |
| |
| void SwatchViewer::setBgPainter(TPixel32 color1, TPixel32 color2) { |
| if (color2 == TPixel32()) |
| m_bgPainter = new SolidColorBgPainter("", color1); |
| else |
| m_bgPainter = new CheckboardBgPainter("", color1, color2); |
| updateRaster(); |
| } |
| |
| |
| |
| TPoint SwatchViewer::world2win(const TPointD &p) const { |
| TPointD center(width() * 0.5, height() * 0.5); |
| return convert(m_aff * m_fxAff * p + center); |
| } |
| |
| |
| |
| TPointD SwatchViewer::win2world(const TPoint &p) const { |
| TPointD center(width() * 0.5, height() * 0.5); |
| TPointD point = TPointD(convert(p) - center); |
| return m_fxAff.inv() * m_aff.inv() * TPointD(point.x, -point.y); |
| } |
| |
| |
| |
| void SwatchViewer::zoom(const TPoint &pos, double factor) { |
| if (!m_content || factor == 1.0) return; |
| |
| TPointD delta = convert(pos); |
| double scale = m_aff.det(); |
| TAffine aff; |
| if ((scale < 2000 || factor < 1) && (scale > 0.004 || factor > 1)) { |
| aff = TTranslation(delta) * TScale(factor) * TTranslation(-delta); |
| setAff(aff * m_aff); |
| } |
| } |
| |
| |
| |
| void SwatchViewer::zoom(bool forward, bool reset) { |
| double scale2 = m_aff.det(); |
| if (reset || ((scale2 < 2000 || !forward) && (scale2 > 0.004 || forward))) { |
| double oldZoomScale = sqrt(scale2); |
| double zoomScale = |
| reset ? 1 : getQuantizedZoomFactor(oldZoomScale, forward); |
| TAffine aff = TScale(zoomScale / oldZoomScale); |
| |
| setAff(aff * m_aff); |
| } |
| } |
| |
| |
| |
| void SwatchViewer::computeContent() { |
| if (suspendedRendering) return; |
| if (!m_enabled) return; |
| if (!m_raster) return; |
| |
| |
| |
| |
| if (m_aff.a11 != m_contentAff.a11) |
| SwatchCacheManager::instance()->clearSwatchResults(); |
| |
| TRect rect(0, 0, width() - 1, height() - 1); |
| TDimension size = rect.getSize(); |
| assert(m_raster->getSize() == size); |
| if (m_fx) { |
| |
| |
| TRasterFxP rasterFx = m_fx; |
| if (rasterFx) { |
| m_executor.cancelAll(); |
| m_executor.addTask( |
| new ContentRender(rasterFx.getPointer(), m_frame, size, this)); |
| |
| submittedTasks++; |
| return; |
| } else { |
| m_content = TRaster32P(size); |
| m_content->fill(TPixel32::Red); |
| } |
| } else { |
| m_content = TRaster32P(size); |
| m_content->fill(TPixel32::Transparent); |
| } |
| updateRaster(); |
| } |
| |
| |
| |
| void SwatchViewer::updateRaster() { |
| QMutexLocker sl(&m_mutex); |
| |
| if (!m_enabled) return; |
| if (!m_raster) return; |
| if (m_bgPainter) |
| m_bgPainter->paint(m_raster); |
| else |
| m_raster->fill(TPixel32(127, 127, 127)); |
| |
| if (m_cameraMode && !m_cameraRect.isEmpty()) { |
| TPointD p0(m_cameraRect.x0, m_cameraRect.y0); |
| TPointD p1(m_cameraRect.x1, m_cameraRect.y1); |
| TPointD center(width() * 0.5, height() * 0.5); |
| TPoint transP0 = convert(m_aff * p0 + center); |
| TPoint transP1 = convert(m_aff * p1 + center); |
| TPoint p = convert( |
| (TPointD(transP1.x, transP1.y) - TPointD(transP0.x, transP0.y)) * 0.5); |
| TRect rect(transP0 - p, transP1 - p); |
| m_content->fillOutside(rect, TPixel32(255, 0, 0, 255)); |
| m_content->fillOutside(rect.enlarge(TDimension(1, 1)), |
| TPixel32(0, 0, 0, 0)); |
| } |
| |
| if (m_content) TRop::over(m_raster, m_content); |
| |
| int i; |
| for (i = 0; i < (int)m_points.size(); i++) { |
| if (m_points[i].m_pairFlag) continue; |
| TPoint p = world2win(m_points[i].m_param->getValue(m_frame)); |
| TRop::over(m_raster, m_crossIcon, p - TPoint(4, 4)); |
| } |
| for (i = 0; i < (int)m_pointPairs.size(); i++) { |
| int i0 = m_pointPairs[i].first; |
| int i1 = m_pointPairs[i].second; |
| assert(i0 != i1); |
| assert(0 <= i0 && i0 < (int)m_points.size()); |
| assert(0 <= i1 && i1 < (int)m_points.size()); |
| TPoint p0 = world2win(m_points[i0].m_param->getValue(m_frame)); |
| TPoint p1 = world2win(m_points[i1].m_param->getValue(m_frame)); |
| TPoint delta = p1 - p0; |
| int len = tround(sqrt((double)(delta * delta))); |
| double phi = 0; |
| if (len > 0) phi = atan2((double)delta.y, (double)delta.x) * M_180_PI; |
| |
| if (len > 500) { |
| |
| |
| |
| } else { |
| TRaster32P arrowShape = createArrowShape(len); |
| TAffine aff = |
| TRotation(phi).place(0, arrowShape->getLy() / 2, p0.x, p0.y); |
| TRop::over(m_raster, arrowShape, aff); |
| |
| |
| } |
| } |
| |
| update(); |
| } |
| |
| |
| |
| void SwatchViewer::setContent(const TRaster32P &content, |
| const TAffine &contentAff) { |
| m_content = content; |
| m_contentAff = contentAff; |
| |
| updateRaster(); |
| update(); |
| } |
| |
| |
| |
| void SwatchViewer::setAff(const TAffine &aff) { |
| m_aff = aff; |
| computeContent(); |
| } |
| |
| |
| |
| void SwatchViewer::paintEvent(QPaintEvent *event) { |
| QPainter p(this); |
| QRect rectBox = rect(); |
| |
| if (!m_enabled) |
| p.fillRect(rectBox, QBrush(QColor(120, 120, 120))); |
| else { |
| if (!m_raster) return; |
| QImage image = rasterToQImage(m_raster); |
| p.drawImage(rectBox, image); |
| if (m_computing) { |
| QPen pen; |
| pen.setColor(Qt::red); |
| pen.setWidth(3); |
| p.setPen(pen); |
| p.drawRect(rectBox.adjusted(0, 0, -1, -1)); |
| } |
| } |
| } |
| |
| |
| |
| void SwatchViewer::resizeEvent(QResizeEvent *re) { |
| int oldHeight = re->oldSize().height(); |
| int newHeight = re->size().height(); |
| if (oldHeight != newHeight) { |
| updateSize(QSize(newHeight, newHeight)); |
| computeContent(); |
| } |
| } |
| |
| |
| |
| void SwatchViewer::mousePressEvent(QMouseEvent *event) { |
| TPoint pos = TPoint(event->pos().x(), event->pos().y()); |
| m_mouseButton = event->button(); |
| if (m_mouseButton == Qt::LeftButton) { |
| m_selectedPoint = -1; |
| if (m_points.empty()) return; |
| TPointD p = win2world(pos); |
| TPointD q; |
| double minDist2 = 1e6; |
| int i; |
| for (i = 0; i < (int)m_points.size(); i++) { |
| TPointD paramPoint = m_points[i].m_param->getValue(m_frame); |
| double d2 = tdistance2(p, paramPoint); |
| if (m_selectedPoint < 0 || d2 < minDist2) { |
| m_selectedPoint = i; |
| minDist2 = d2; |
| q = paramPoint; |
| } |
| } |
| if (m_selectedPoint >= 0) { |
| m_pointPosDelta = q - p; |
| TPoint d = world2win(p) - world2win(q); |
| int dd2 = d.x * d.x + d.y * d.y; |
| if (dd2 > 400) |
| m_selectedPoint = -1; |
| else { |
| std::string name = m_points[m_selectedPoint].m_param->getName(); |
| std::string prefix = matchSuffix(name, "_b"); |
| if (prefix != "") { |
| std::string otherName = prefix + "_a"; |
| int n = (int)m_points.size(); |
| int j; |
| for (j = 0; j < n; j++) |
| if (i != j && m_points[j].m_param->getName() == otherName) break; |
| if (j < n) { |
| TPoint dist = world2win(m_points[m_selectedPoint].m_param->getValue( |
| m_frame)) - |
| world2win(m_points[j].m_param->getValue(m_frame)); |
| int ddist2 = dist.x * dist.x + dist.y * dist.y; |
| if (ddist2 < 100) m_selectedPoint = j; |
| } |
| } |
| } |
| } |
| update(); |
| } else if (m_mouseButton == Qt::MidButton) { |
| m_pos = pos; |
| m_firstPos = pos; |
| m_oldContent = getContent(); |
| if (m_oldContent) |
| m_curContent = TRaster32P(m_oldContent->getSize()); |
| else |
| m_curContent = TRaster32P(); |
| } |
| } |
| |
| |
| |
| void SwatchViewer::mouseMoveEvent(QMouseEvent *event) { |
| TPoint pos = TPoint(event->pos().x(), event->pos().y()); |
| if (m_mouseButton == Qt::LeftButton) { |
| if (m_selectedPoint < 0 || m_selectedPoint >= (int)m_points.size()) return; |
| TPointD p = win2world(pos) + m_pointPosDelta; |
| int index = m_points[m_selectedPoint].m_index; |
| emit pointPositionChanged(index, p); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); |
| } else if (m_mouseButton == Qt::MidButton) { |
| if (!m_oldContent || !m_curContent) return; |
| m_curContent->fill(TPixel32::Transparent); |
| TPointD step = convert(pos - m_pos); |
| |
| m_aff = TTranslation(step.x, -step.y) * m_aff; |
| m_pos = pos; |
| TPoint p = pos - m_firstPos; |
| m_curContent->copy(m_oldContent, TPoint(p.x, -p.y)); |
| setContent(m_curContent, TTranslation(step.x, -step.y) * m_contentAff); |
| } |
| } |
| |
| |
| |
| void SwatchViewer::mouseReleaseEvent(QMouseEvent *event) { |
| m_mouseButton = Qt::NoButton; |
| m_selectedPoint = -1; |
| TPoint pos = TPoint(event->pos().x(), event->pos().y()); |
| if (event->button() == Qt::MidButton) { |
| if (!m_oldContent || !m_curContent) return; |
| TPointD p = convert(pos - m_pos); |
| setAff(TTranslation(p.x, -p.y) * m_aff); |
| update(); |
| } |
| } |
| |
| |
| |
| void SwatchViewer::wheelEvent(QWheelEvent *event) { |
| TPoint center(event->pos().x() - width() / 2, |
| -event->pos().y() + height() / 2); |
| zoom(center, exp(0.001 * event->delta())); |
| } |
| |
| |
| |
| void SwatchViewer::keyPressEvent(QKeyEvent *event) { |
| int key = event->key(); |
| if (key == '+' || key == '-' || key == '0') { |
| zoom(key == '+', key == '0'); |
| } |
| } |
| |
| |
| |
| void SwatchViewer::hideEvent(QHideEvent *event) { |
| |
| ::setFxForCaching(0); |
| } |
| |
| |
| |
| |
| |
| SwatchViewer::ContentRender::ContentRender(TRasterFx *fx, int frame, |
| const TDimension &size, |
| SwatchViewer *viewer) |
| : m_fx(fx) |
| , m_raster(0) |
| , m_frame(frame) |
| , m_size(size) |
| , m_aff(viewer->m_aff) |
| , m_viewer(viewer) |
| , m_started(false) { |
| |
| connect(this, SIGNAL(started(TThread::RunnableP)), this, |
| SLOT(onStarted(TThread::RunnableP))); |
| connect(this, SIGNAL(finished(TThread::RunnableP)), this, |
| SLOT(onFinished(TThread::RunnableP))); |
| connect(this, SIGNAL(exception(TThread::RunnableP)), this, |
| SLOT(onFinished(TThread::RunnableP))); |
| connect(this, SIGNAL(canceled(TThread::RunnableP)), this, |
| SLOT(onCanceled(TThread::RunnableP)), |
| Qt::QueuedConnection); |
| |
| } |
| |
| |
| |
| SwatchViewer::ContentRender::~ContentRender() {} |
| |
| |
| |
| void SwatchViewer::ContentRender::run() { |
| if (suspendedRendering) return; |
| |
| unsigned long renderId = TRenderer::buildRenderId(); |
| |
| TPassiveCacheManager::instance()->setContextName(renderId, "S"); |
| |
| m_viewer->m_renderer.install(renderId); |
| m_viewer->m_renderer.declareRenderStart(renderId); |
| m_viewer->m_renderer.declareFrameStart(m_frame); |
| |
| TRenderSettings info; |
| info.m_isSwatch = true; |
| info.m_affine = m_aff; |
| |
| TTile tile; |
| m_fx->allocateAndCompute(tile, -0.5 * TPointD(m_size.lx, m_size.ly), m_size, |
| 0, (double)m_frame, info); |
| m_raster = tile.getRaster(); |
| |
| m_viewer->m_renderer.declareFrameEnd(m_frame); |
| m_viewer->m_renderer.declareRenderEnd(renderId); |
| m_viewer->m_renderer.uninstall(); |
| } |
| |
| |
| |
| int SwatchViewer::ContentRender::taskLoad() { return 100; } |
| |
| |
| |
| void SwatchViewer::ContentRender::onStarted(TThread::RunnableP task) { |
| m_started = true; |
| m_viewer->m_computing = true; |
| m_viewer->update(); |
| } |
| |
| |
| |
| void SwatchViewer::ContentRender::onFinished(TThread::RunnableP task) { |
| m_viewer->m_computing = false; |
| |
| m_viewer->setContent(m_raster, m_aff); |
| if ((--submittedTasks == 0) && waitingLoop) waitingLoop->quit(); |
| } |
| |
| |
| |
| void SwatchViewer::ContentRender::onCanceled(TThread::RunnableP task) { |
| if (m_started) return; |
| |
| if ((--submittedTasks == 0) && waitingLoop) waitingLoop->quit(); |
| } |
| |
| |
| |
| |
| |
| SwatchCacheManager *SwatchCacheManager::instance() { |
| static SwatchCacheManager theInstance; |
| return &theInstance; |
| } |
| |
| |
| |
| void SwatchCacheManager::setFx(const TFxP &fx) { |
| QMutexLocker locker(&m_mutex); |
| |
| |
| if (fx == TFxP()) { |
| |
| m_setFxId = 0; |
| m_childrenFxIds.clear(); |
| } else { |
| m_setFxId = fx->getIdentifier(); |
| m_childrenFxIds.clear(); |
| assert(m_setFxId != 0); |
| |
| TRasterFx *rfx = dynamic_cast<TRasterFx *>(fx.getPointer()); |
| assert(rfx); |
| |
| for (int i = 0; i < fx->getInputPortCount(); ++i) { |
| |
| if (!rfx->allowUserCacheOnPort(i)) continue; |
| |
| TFxPort *iport = fx->getInputPort(i); |
| if (iport && iport->isConnected()) { |
| TFx *child = iport->getFx(); |
| |
| |
| TZeraryColumnFx *zcfx = dynamic_cast<TZeraryColumnFx *>(child); |
| if (zcfx) child = zcfx->getZeraryFx(); |
| |
| assert(child && child->getIdentifier() != 0); |
| m_childrenFxIds.insert(child->getIdentifier()); |
| } |
| } |
| } |
| |
| |
| |
| |
| if (m_currEditedFxResult) m_currEditedFxResult->releaseLock(); |
| m_currEditedFxResult = TCacheResourceP(); |
| |
| std::set<TCacheResourceP>::iterator it; |
| for (it = m_swatchCacheContainer.begin(); it != m_swatchCacheContainer.end(); |
| ++it) |
| (*it)->releaseLock(); |
| m_swatchCacheContainer.clear(); |
| |
| #ifdef USE_SQLITE_HDPOOL |
| TCacheResourcePool::instance()->releaseReferences("S"); |
| #else |
| for (it = m_genericCacheContainer.begin(); |
| it != m_genericCacheContainer.end(); ++it) |
| (*it)->releaseLock(); |
| m_genericCacheContainer.clear(); |
| #endif |
| } |
| |
| |
| |
| |
| |
| void SwatchCacheManager::clearSwatchResults() { |
| QMutexLocker locker(&m_mutex); |
| |
| if (m_currEditedFxResult) m_currEditedFxResult->releaseLock(); |
| m_currEditedFxResult = TCacheResourceP(); |
| |
| std::set<TCacheResourceP>::iterator it; |
| for (it = m_swatchCacheContainer.begin(); it != m_swatchCacheContainer.end(); |
| ++it) |
| (*it)->releaseLock(); |
| m_swatchCacheContainer.clear(); |
| } |
| |
| |
| |
| void SwatchCacheManager::getResource(TCacheResourceP &resource, |
| const std::string &alias, const TFxP &fx, |
| double frame, const TRenderSettings &rs, |
| ResourceDeclaration *resData) { |
| |
| |
| if (!(fx && m_setFxId > 0)) return; |
| |
| QMutexLocker locker(&m_mutex); |
| |
| |
| unsigned long fxId = fx->getIdentifier(); |
| |
| if (fxId == m_setFxId && rs.m_isSwatch) { |
| if (!resource) resource = TCacheResourceP(alias, true); |
| |
| resource->addLock(); |
| if (m_currEditedFxResult) m_currEditedFxResult->releaseLock(); |
| |
| m_currEditedFxResult = resource; |
| return; |
| } |
| |
| if (m_childrenFxIds.find(fxId) != m_childrenFxIds.end()) { |
| if (!resource) resource = TCacheResourceP(alias, true); |
| |
| if (rs.m_isSwatch) { |
| std::set<TCacheResourceP>::iterator it = |
| m_swatchCacheContainer.find(resource); |
| |
| if (it == m_swatchCacheContainer.end()) { |
| resource->addLock(); |
| m_swatchCacheContainer.insert(resource); |
| } |
| } else { |
| #ifdef USE_SQLITE_HDPOOL |
| resource->enableBackup(); |
| TCacheResourcePool::instance()->addReference(resource, "S"); |
| #else |
| std::set<TCacheResourceP>::iterator it = |
| m_genericCacheContainer.find(resource); |
| |
| if (it == m_genericCacheContainer.end()) { |
| resource->addLock(); |
| m_genericCacheContainer.insert(resource); |
| } |
| #endif |
| } |
| } |
| } |
| |