Commit da6b03e7 authored by Dmitry Kazakov's avatar Dmitry Kazakov

Merge remote-tracking branch 'origin/kazakov/animation-cache-swapping'

# Conflicts:
#	libs/ui/canvas/kis_canvas2.cpp
parents fd6c490d 3f2d2b0e
......@@ -226,7 +226,7 @@ void KisImageConfig::setMemoryPoolLimitPercent(qreal value)
m_config.writeEntry("memoryPoolLimitPercent", value);
}
QString KisImageConfig::swapDir(bool requestDefault)
QString KisImageConfig::safelyGetWritableTempLocation(const QString &suffix, const QString &configKey, bool requestDefault) const
{
#ifdef Q_OS_OSX
// On OSX, QDir::tempPath() gives us a folder we cannot reply upon (usually
......@@ -243,20 +243,27 @@ QString KisImageConfig::swapDir(bool requestDefault)
// furthermore, this is just a default and swapDir can always be configured
// to another location.
QString swap = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/swap";
QString swap = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + QDir::separator() + suffix;
#else
Q_UNUSED(suffix);
QString swap = QDir::tempPath();
#endif
if (requestDefault) {
return swap;
}
QString configuredSwap = m_config.readEntry("swaplocation", swap);
const QString configuredSwap = m_config.readEntry(configKey, swap);
if (!configuredSwap.isEmpty()) {
swap = configuredSwap;
}
return swap;
}
QString KisImageConfig::swapDir(bool requestDefault)
{
return safelyGetWritableTempLocation("swap", "swaplocation", requestDefault);
}
void KisImageConfig::setSwapDir(const QString &swapDir)
{
m_config.writeEntry("swaplocation", swapDir);
......@@ -519,3 +526,63 @@ void KisImageConfig::setFpsLimit(int value)
{
m_config.writeEntry("fpsLimit", value);
}
bool KisImageConfig::useOnDiskAnimationCacheSwapping(bool defaultValue) const
{
return defaultValue ? true : m_config.readEntry("useOnDiskAnimationCacheSwapping", true);
}
void KisImageConfig::setUseOnDiskAnimationCacheSwapping(bool value)
{
m_config.writeEntry("useOnDiskAnimationCacheSwapping", value);
}
QString KisImageConfig::animationCacheDir(bool defaultValue) const
{
return safelyGetWritableTempLocation("animation_cache", "animationCacheDir", defaultValue);
}
void KisImageConfig::setAnimationCacheDir(const QString &value)
{
m_config.writeEntry("animationCacheDir", value);
}
bool KisImageConfig::useAnimationCacheFrameSizeLimit(bool defaultValue) const
{
return defaultValue ? true : m_config.readEntry("useAnimationCacheFrameSizeLimit", true);
}
void KisImageConfig::setUseAnimationCacheFrameSizeLimit(bool value)
{
m_config.writeEntry("useAnimationCacheFrameSizeLimit", value);
}
int KisImageConfig::animationCacheFrameSizeLimit(bool defaultValue) const
{
return defaultValue ? 2500 : m_config.readEntry("animationCacheFrameSizeLimit", 2500);
}
void KisImageConfig::setAnimationCacheFrameSizeLimit(int value)
{
m_config.writeEntry("animationCacheFrameSizeLimit", value);
}
bool KisImageConfig::useAnimationCacheRegionOfInterest(bool defaultValue) const
{
return defaultValue ? true : m_config.readEntry("useAnimationCacheRegionOfInterest", true);
}
void KisImageConfig::setUseAnimationCacheRegionOfInterest(bool value)
{
m_config.writeEntry("useAnimationCacheRegionOfInterest", value);
}
qreal KisImageConfig::animationCacheRegionOfInterestMargin(bool defaultValue) const
{
return defaultValue ? 0.25 : m_config.readEntry("animationCacheRegionOfInterestMargin", 0.25);
}
void KisImageConfig::setAnimationCacheRegionOfInterestMargin(qreal value)
{
m_config.writeEntry("animationCacheRegionOfInterestMargin", value);
}
......@@ -120,9 +120,29 @@ public:
int fpsLimit(bool defaultValue = false) const;
void setFpsLimit(int value);
bool useOnDiskAnimationCacheSwapping(bool defaultValue = false) const;
void setUseOnDiskAnimationCacheSwapping(bool value);
QString animationCacheDir(bool defaultValue = false) const;
void setAnimationCacheDir(const QString &value);
bool useAnimationCacheFrameSizeLimit(bool defaultValue = false) const;
void setUseAnimationCacheFrameSizeLimit(bool value);
int animationCacheFrameSizeLimit(bool defaultValue = false) const;
void setAnimationCacheFrameSizeLimit(int value);
bool useAnimationCacheRegionOfInterest(bool defaultValue = false) const;
void setUseAnimationCacheRegionOfInterest(bool value);
qreal animationCacheRegionOfInterestMargin(bool defaultValue = false) const;
void setAnimationCacheRegionOfInterestMargin(qreal value);
private:
Q_DISABLE_COPY(KisImageConfig)
QString safelyGetWritableTempLocation(const QString &suffix, const QString &configKey, bool requestDefault) const;
private:
KConfigGroup m_config;
bool m_readOnly;
......
......@@ -407,6 +407,12 @@ public:
void uploadLodDataStruct(LodDataStruct *dst);
QRegion regionForLodSyncing() const;
void updateLodDataManager(KisDataManager *srcDataManager,
KisDataManager *dstDataManager, const QPoint &srcOffset, const QPoint &dstOffset,
const QRect &originalRect, int lod);
void generateLodCloneDevice(KisPaintDeviceSP dst, const QRect &originalRect, int lod);
void tesingFetchLodDevice(KisPaintDeviceSP targetDevice);
......@@ -685,15 +691,13 @@ KisPaintDevice::LodDataStruct* KisPaintDevice::Private::createLodDataStruct(int
return lodStruct;
}
void KisPaintDevice::Private::updateLodDataStruct(LodDataStruct *_dst, const QRect &originalRect)
void KisPaintDevice::Private::updateLodDataManager(KisDataManager *srcDataManager,
KisDataManager *dstDataManager,
const QPoint &srcOffset,
const QPoint &dstOffset,
const QRect &originalRect,
int lod)
{
LodDataStructImpl *dst = dynamic_cast<LodDataStructImpl*>(_dst);
KIS_SAFE_ASSERT_RECOVER_RETURN(dst);
Data *lodData = dst->lodData.data();
Data *srcData = currentNonLodData();
const int lod = lodData->levelOfDetail();
const int srcStepSize = 1 << lod;
KIS_ASSERT_RECOVER_RETURN(lod > 0);
......@@ -704,7 +708,7 @@ void KisPaintDevice::Private::updateLodDataStruct(LodDataStruct *_dst, const QRe
KIS_ASSERT_RECOVER_NOOP(srcRect.width() / srcStepSize == dstRect.width());
const int pixelSize = srcData->dataManager()->pixelSize();
const int pixelSize = srcDataManager->pixelSize();
int rowsAccumulated = 0;
int columnsAccumulated = 0;
......@@ -733,8 +737,8 @@ void KisPaintDevice::Private::updateLodDataStruct(LodDataStruct *_dst, const QRe
weights[srcCellSize - 1] = averageWeight - extraWeight;
}
InternalSequentialConstIterator srcIntIt(StrategyPolicy(currentStrategy(), srcData->dataManager().data(), srcData->x(), srcData->y()), srcRect);
InternalSequentialIterator dstIntIt(StrategyPolicy(currentStrategy(), lodData->dataManager().data(), lodData->x(), lodData->y()), dstRect);
InternalSequentialConstIterator srcIntIt(StrategyPolicy(currentStrategy(), srcDataManager, srcOffset.x(), srcOffset.y()), srcRect);
InternalSequentialIterator dstIntIt(StrategyPolicy(currentStrategy(), dstDataManager, dstOffset.x(), dstOffset.y()), dstRect);
int rowsRemaining = srcRect.height();
while (rowsRemaining > 0) {
......@@ -782,6 +786,33 @@ void KisPaintDevice::Private::updateLodDataStruct(LodDataStruct *_dst, const QRe
}
}
void KisPaintDevice::Private::updateLodDataStruct(LodDataStruct *_dst, const QRect &originalRect)
{
LodDataStructImpl *dst = dynamic_cast<LodDataStructImpl*>(_dst);
KIS_SAFE_ASSERT_RECOVER_RETURN(dst);
Data *lodData = dst->lodData.data();
Data *srcData = currentNonLodData();
const int lod = lodData->levelOfDetail();
updateLodDataManager(srcData->dataManager().data(), lodData->dataManager().data(),
QPoint(srcData->x(), srcData->y()),
QPoint(lodData->x(), lodData->y()),
originalRect, lod);
}
void KisPaintDevice::Private::generateLodCloneDevice(KisPaintDeviceSP dst, const QRect &originalRect, int lod)
{
KIS_SAFE_ASSERT_RECOVER_RETURN(fastBitBltPossible(dst));
Data *srcData = currentNonLodData();
updateLodDataManager(srcData->dataManager().data(), dst->dataManager().data(),
QPoint(srcData->x(), srcData->y()),
QPoint(dst->x(), dst->y()),
originalRect, lod);
}
void KisPaintDevice::Private::uploadLodDataStruct(LodDataStruct *_dst)
{
LodDataStructImpl *dst = dynamic_cast<LodDataStructImpl*>(_dst);
......@@ -2027,6 +2058,11 @@ void KisPaintDevice::uploadLodDataStruct(LodDataStruct *dst)
m_d->uploadLodDataStruct(dst);
}
void KisPaintDevice::generateLodCloneDevice(KisPaintDeviceSP dst, const QRect &originalRect, int lod)
{
m_d->generateLodCloneDevice(dst, originalRect, lod);
}
KisPaintDeviceFramesInterface* KisPaintDevice::framesInterface()
{
......
......@@ -842,6 +842,8 @@ public:
void updateLodDataStruct(LodDataStruct *dst, const QRect &srcRect);
void uploadLodDataStruct(LodDataStruct *dst);
void generateLodCloneDevice(KisPaintDeviceSP dst, const QRect &originalRect, int lod);
void setProjectionDevice(bool value);
void tesingFetchLodDevice(KisPaintDeviceSP targetDevice);
......
......@@ -163,6 +163,7 @@ set(kritaui_LIB_SRCS
opengl/kis_texture_tile.cpp
opengl/kis_opengl_shader_loader.cpp
opengl/kis_texture_tile_info_pool.cpp
opengl/KisOpenGLUpdateInfoBuilder.cpp
kis_fps_decoration.cpp
recorder/kis_node_query_path_editor.cc
recorder/kis_recorded_action_creator.cc
......@@ -422,6 +423,12 @@ endif()
canvas/kis_animation_player.cpp
kis_animation_importer.cpp
KisSyncedAudioPlayback.cpp
KisFrameDataSerializer.cpp
KisFrameCacheStore.cpp
KisFrameCacheSwapper.cpp
KisAbstractFrameCacheSwapper.cpp
KisInMemoryFrameCacheSwapper.cpp
input/wintab/drawpile_tablettester/tablettester.cpp
input/wintab/drawpile_tablettester/tablettest.cpp
)
......
/*
* Copyright (c) 2018 Dmitry Kazakov <dimula73@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "KisAbstractFrameCacheSwapper.h"
KisAbstractFrameCacheSwapper::~KisAbstractFrameCacheSwapper()
{
}
/*
* Copyright (c) 2018 Dmitry Kazakov <dimula73@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KISABSTRACTFRAMECACHESWAPPER_H
#define KISABSTRACTFRAMECACHESWAPPER_H
#include "kritaui_export.h"
class QRect;
template<class T>
class KisSharedPtr;
class KisOpenGLUpdateInfo;
typedef KisSharedPtr<KisOpenGLUpdateInfo> KisOpenGLUpdateInfoSP;
class KRITAUI_EXPORT KisAbstractFrameCacheSwapper
{
public:
virtual ~KisAbstractFrameCacheSwapper();
// WARNING: after transferring \p info to saveFrame() the object becomes invalid
virtual void saveFrame(int frameId, KisOpenGLUpdateInfoSP info, const QRect &imageBounds) = 0;
virtual KisOpenGLUpdateInfoSP loadFrame(int frameId) = 0;
virtual void moveFrame(int srcFrameId, int dstFrameId) = 0;
virtual void forgetFrame(int frameId) = 0;
virtual bool hasFrame(int frameId) const = 0;
virtual int frameLevelOfDetail(int frameId) const = 0;
virtual QRect frameDirtyRect(int frameId) const = 0;
};
#endif // KISABSTRACTFRAMECACHESWAPPER_H
......@@ -43,13 +43,13 @@ void KisAsyncAnimationCacheRenderer::setFrameCache(KisAnimationFrameCacheSP cach
m_d->requestedCache = cache;
}
void KisAsyncAnimationCacheRenderer::frameCompletedCallback(int frame)
void KisAsyncAnimationCacheRenderer::frameCompletedCallback(int frame, const QRegion &requestedRegion)
{
KisAnimationFrameCacheSP cache = m_d->requestedCache;
KisImageSP image = requestedImage();
if (!cache || !image) return;
m_d->requestInfo = cache->fetchFrameData(frame, image);
m_d->requestInfo = cache->fetchFrameData(frame, image, requestedRegion);
emit sigCompleteRegenerationInternal(frame);
}
......
......@@ -31,7 +31,7 @@ public:
void setFrameCache(KisAnimationFrameCacheSP cache);
protected:
void frameCompletedCallback(int frame) override;
void frameCompletedCallback(int frame, const QRegion &requestedRegion) override;
void frameCancelledCallback(int frame) override;
void clearFrameRegenerationState(bool isCancelled) override;
......
......@@ -92,11 +92,16 @@ KisAsyncAnimationFramesSavingRenderer::~KisAsyncAnimationFramesSavingRenderer()
{
}
void KisAsyncAnimationFramesSavingRenderer::frameCompletedCallback(int frame)
void KisAsyncAnimationFramesSavingRenderer::frameCompletedCallback(int frame, const QRegion &requestedRegion)
{
KisImageSP image = requestedImage();
if (!image) return;
KIS_SAFE_ASSERT_RECOVER (requestedRegion == image->bounds()) {
emit sigCancelRegenerationInternal(frame);
return;
}
m_d->savingDevice->makeCloneFromRough(image->projection(), image->bounds());
KisTimeRange range(frame, 1);
......
......@@ -38,7 +38,7 @@ public:
~KisAsyncAnimationFramesSavingRenderer();
protected:
void frameCompletedCallback(int frame) override;
void frameCompletedCallback(int frame, const QRegion &requestedRegion) override;
void frameCancelledCallback(int frame) override;
Q_SIGNALS:
......
......@@ -25,7 +25,7 @@
#include "kis_image_animation_interface.h"
#include "kis_signal_auto_connection.h"
struct KisAsyncAnimationRendererBase::Private
struct KRITAUI_NO_EXPORT KisAsyncAnimationRendererBase::Private
{
KisSignalAutoConnectionsStore imageRequestConnections;
......@@ -34,6 +34,7 @@ struct KisAsyncAnimationRendererBase::Private
KisImageSP requestedImage;
int requestedFrame = -1;
bool isCancelled = false;
QRegion requestedRegion;
static const int WAITING_FOR_FRAME_TIMEOUT = 10000;
};
......@@ -52,13 +53,14 @@ KisAsyncAnimationRendererBase::~KisAsyncAnimationRendererBase()
}
void KisAsyncAnimationRendererBase::startFrameRegeneration(KisImageSP image, int frame)
void KisAsyncAnimationRendererBase::startFrameRegeneration(KisImageSP image, int frame, const QRegion &regionOfInterest)
{
KIS_SAFE_ASSERT_RECOVER_NOOP(QThread::currentThread() == this->thread());
m_d->requestedImage = image;
m_d->requestedFrame = frame;
m_d->isCancelled = false;
m_d->requestedRegion = !regionOfInterest.isEmpty() ? regionOfInterest : image->bounds();
KisImageAnimationInterface *animation = m_d->requestedImage->animationInterface();
......@@ -74,7 +76,12 @@ void KisAsyncAnimationRendererBase::startFrameRegeneration(KisImageSP image, int
Qt::AutoConnection);
m_d->regenerationTimeout.start();
animation->requestFrameRegeneration(m_d->requestedFrame, image->bounds());
animation->requestFrameRegeneration(m_d->requestedFrame, m_d->requestedRegion);
}
void KisAsyncAnimationRendererBase::startFrameRegeneration(KisImageSP image, int frame)
{
startFrameRegeneration(image, frame, QRegion());
}
bool KisAsyncAnimationRendererBase::isActive() const
......@@ -106,7 +113,7 @@ void KisAsyncAnimationRendererBase::slotFrameRegenerationFinished(int frame)
// probably a bit too strict...
KIS_SAFE_ASSERT_RECOVER_NOOP(QThread::currentThread() != this->thread());
frameCompletedCallback(frame);
frameCompletedCallback(frame, m_d->requestedRegion);
}
void KisAsyncAnimationRendererBase::notifyFrameCompleted(int frame)
......@@ -150,6 +157,7 @@ void KisAsyncAnimationRendererBase::clearFrameRegenerationState(bool isCancelled
m_d->requestedFrame = -1;
m_d->regenerationTimeout.stop();
m_d->isCancelled = true;
m_d->requestedRegion = QRegion();
}
KisImageSP KisAsyncAnimationRendererBase::requestedImage() const
......
......@@ -22,6 +22,8 @@
#include <QObject>
#include "kis_types.h"
#include "kritaui_export.h"
/**
* KisAsyncAnimationRendererBase is a special class represinting a
* single worker thread inside KisAsyncAnimationRenderDialogBase. It connects
......@@ -32,7 +34,7 @@
* should override these two methods to do the actual work.
*/
class KisAsyncAnimationRendererBase : public QObject
class KRITAUI_EXPORT KisAsyncAnimationRendererBase : public QObject
{
Q_OBJECT
public:
......@@ -40,9 +42,16 @@ public:
virtual ~KisAsyncAnimationRendererBase();
/**
* Initiates the rendering of the frame \p frame on an image \p image
* Initiates the rendering of the frame \p frame on an image \p image.
* Only \p regionOfInterest is regenerated. If \p regionOfInterest is
* empty, then entire bounds of the image is regenerated.
*/
void startFrameRegeneration(KisImageSP image, int frame, const QRegion &regionOfInterest);
/**
* Convenience overload that regenerates the full image
*/
virtual void startFrameRegeneration(KisImageSP image, int frame);
void startFrameRegeneration(KisImageSP image, int frame);
/**
* @return true if the regeneration process is in progress
......@@ -93,7 +102,7 @@ protected:
* NOTE3: In case of failure, notifyFrameCancelled(). The same threading
* rules apply.
*/
virtual void frameCompletedCallback(int frame) = 0;
virtual void frameCompletedCallback(int frame, const QRegion &requestedRegion) = 0;
/**
* @brief frameCancelledCallback is called when the rendering of
......
......@@ -20,6 +20,9 @@
#include "KisDocument.h"
#include "kis_layer_utils.h"
#include <QApplication>
struct KRITAIMAGE_NO_EXPORT KisCloneDocumentStroke::Private
{
Private(KisDocument *_document)
......@@ -35,7 +38,7 @@ KisCloneDocumentStroke::KisCloneDocumentStroke(KisDocument *document)
m_d(new Private(document))
{
setClearsRedoOnStart(false);
setRequestsOtherStrokesToEnd(false); // TODO: ???
setRequestsOtherStrokesToEnd(false);
enableJob(JOB_INIT, true, KisStrokeJobData::BARRIER, KisStrokeJobData::EXCLUSIVE);
enableJob(JOB_FINISH, true, KisStrokeJobData::BARRIER, KisStrokeJobData::EXCLUSIVE);
}
......@@ -49,8 +52,6 @@ void KisCloneDocumentStroke::initStrokeCallback()
KisLayerUtils::forceAllDelayedNodesUpdate(m_d->document->image()->root());
}
#include <QApplication>
void KisCloneDocumentStroke::finishStrokeCallback()
{
KisDocument *doc = m_d->document->clone();
......
......@@ -1702,7 +1702,7 @@ void KisDocument::setAssistants(const QList<KisPaintingAssistantSP> &value)
d->assistants = value;
}
KisSharedPtr<KisReferenceImagesLayer> KisDocument::createReferenceImagesLayer(KisImageSP targetImage)
KisSharedPtr<KisReferenceImagesLayer> KisDocument::getOrCreateReferenceImagesLayer(KisImageSP targetImage)
{
if (!d->referenceImagesLayer) {
if (targetImage.isNull()) targetImage = d->image;
......@@ -1714,11 +1714,17 @@ KisSharedPtr<KisReferenceImagesLayer> KisDocument::createReferenceImagesLayer(Ki
return d->referenceImagesLayer;
}
// TODO: change signature to return a shared pointer
KisReferenceImagesLayer *KisDocument::referenceImagesLayer() const
{
return d->referenceImagesLayer.data();
}
void KisDocument::setReferenceImagesLayer(KisSharedPtr<KisReferenceImagesLayer> layer)
{
d->referenceImagesLayer = layer;
}
void KisDocument::setPreActivatedNode(KisNodeSP activatedNode)
{
d->preActivatedNode = activatedNode;
......
......@@ -592,14 +592,18 @@ public:
/**
* Get existing reference images layer or create new if none exists.
*
* TODO: use setReferenceImagesLayer() combined with undo commands instead
*/
KisSharedPtr<KisReferenceImagesLayer> createReferenceImagesLayer(KisImageSP targetImage = KisImageSP());
KRITAUI_DEPRECATED KisSharedPtr<KisReferenceImagesLayer> getOrCreateReferenceImagesLayer(KisImageSP targetImage = KisImageSP());
/**
* Get existing reference images layer or null if none exists.
*/
KisReferenceImagesLayer *referenceImagesLayer() const;
void setReferenceImagesLayer(KisSharedPtr<KisReferenceImagesLayer> layer);
bool save(bool showWarnings, KisPropertiesConfigurationSP exportConfiguration);
Q_SIGNALS:
......
This diff is collapsed.
/*
* Copyright (c) 2018 Dmitry Kazakov <dimula73@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KISFRAMECACHESTORE_H
#define KISFRAMECACHESTORE_H
#include "kritaui_export.h"
#include <QScopedPointer>
#include "kis_types.h"
#include "opengl/kis_texture_tile_info_pool.h"
class KisOpenGLUpdateInfoBuilder;
class KisOpenGLUpdateInfo;
typedef KisSharedPtr<KisOpenGLUpdateInfo> KisOpenGLUpdateInfoSP;
/**
* KisFrameCacheStore is a middle-level class for reading/writing
* animation frames on disk. Its main responsibilities:
*
* 1) Convert frames from KisOpenGLUpdateInfo format into a serializable
* KisFrameDataSerializer::Frame format.
*
* 2) Calculate differences between the frames and decide which
* frame will be a keyframe for other frames.
*
* 3) The keyframes will be used as a base for difference
* calculation and stored in a short in-memory cache to avoid
* fetching them from disk too often.
*
* 4) The in-memory cache of the keyframes is stored in serializable
* KisFrameDataSerializer::Frame format.
*/
class KRITAUI_EXPORT KisFrameCacheStore
{
public:
KisFrameCacheStore();
KisFrameCacheStore(const QString &frameCachePath);
~KisFrameCacheStore();
// WARNING: after transferring \p info to saveFrame() the object becomes invalid
void saveFrame(int frameId, KisOpenGLUpdateInfoSP info, const QRect &imageBounds);
KisOpenGLUpdateInfoSP loadFrame(int frameId, const KisOpenGLUpdateInfoBuilder &builder);
void moveFrame(int srcFrameId, int dstFrameId);
void forgetFrame(int frameId);
bool hasFrame(int frameId) const;
int frameLevelOfDetail(int frameId) const;
QRect frameDirtyRect(int frameId) const;
private:
struct Private;
const QScopedPointer<Private> m_d;
};
#endif // KISFRAMECACHESTORE_H
/*
* Copyright (c) 2018 Dmitry Kazakov <dimula73@gmail.com>
*
* This program is free software; you can redistribute it and/or modify