File indexing completed on 2025-02-02 04:18:31
0001 /* 0002 * SPDX-FileCopyrightText: 2017 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KISASYNCANIMATIONRENDERDIALOGBASE_H 0008 #define KISASYNCANIMATIONRENDERDIALOGBASE_H 0009 0010 #include <QObject> 0011 #include "kis_types.h" 0012 #include "kritaui_export.h" 0013 0014 #include <KisAsyncAnimationRendererBase.h> 0015 0016 class KisTimeSpan; 0017 class KisViewManager; 0018 class KisRegion; 0019 0020 /** 0021 * @brief KisAsyncAnimationRenderDialogBase is a special class for rendering multiple 0022 * frames of the image and putting them somewhere (saving into a file or just 0023 * pushing into an openGL cache) 0024 * 0025 * The class handles a lot of boilerplate code for you and optimizes regeneration of 0026 * the frames using multithreading, according to the user's settings. The responsibilities 0027 * of the class are the following: 0028 * 0029 * Rendering itself: 0030 * - fetch the list of dirty frames using calcDirtyFrames() 0031 * - create some clones of the image according to the user's settings 0032 * to facilitate multithreaded rendering and processing of the frames 0033 * - if the user doesn't have enough RAM, the clones will not be created 0034 * (the memory overhead is calculated using "projections" metric of the 0035 * statistics server). 0036 * - feed the images/threads with dirty frames until the all the frames 0037 * are done 0038 * 0039 * Progress reporting: 0040 * - if batchMode() is false, the user will see a progress dialog showing 0041 * the current progress with estimate about total processing timer 0042 * - the user can also cancel the regeneration by pressing Cancel button 0043 * 0044 * Usage Details: 0045 * - one should implement two methods to make the rendering work: 0046 * - calcDirtyFrames() 0047 * - createRenderer(KisImageSP image) 0048 * - these methods will be called on the start of the rendering 0049 */ 0050 class KRITAUI_EXPORT KisAsyncAnimationRenderDialogBase : public QObject 0051 { 0052 Q_OBJECT 0053 public: 0054 enum Result { 0055 RenderComplete, 0056 RenderCancelled, 0057 RenderFailed, 0058 RenderTimedOut 0059 }; 0060 0061 public: 0062 /** 0063 * @brief construct and initialize the dialog 0064 * @param actionTitle the first line of the status reports that the user sees in the dialog 0065 * @param image the image that will be as a source of frames. Make sure the image is *not* 0066 * locked by the time regenerateRange() is called 0067 * @param busyWait the dialog will not show for the specified time (in milliseconds) 0068 */ 0069 KisAsyncAnimationRenderDialogBase(const QString &actionTitle, KisImageSP image, int busyWait = 200); 0070 virtual ~KisAsyncAnimationRenderDialogBase(); 0071 0072 /** 0073 * @brief start generation of frames and (if not in batch mode) show the dialog 0074 * 0075 * The link to view manager is used to barrier lock with visual feedback in the 0076 * end of the operation 0077 */ 0078 virtual Result regenerateRange(KisViewManager *viewManager); 0079 0080 /** 0081 * Set area of image that will be regenerated. If \p roi is empty, 0082 * full area of the image is regenerated. 0083 */ 0084 void setRegionOfInterest(const KisRegion &roi); 0085 0086 /** 0087 * @see setRegionOfInterest() 0088 */ 0089 KisRegion regionOfInterest() const; 0090 0091 /** 0092 * @brief setting batch mode to true will prevent any dialogs or message boxes from 0093 * showing on screen. Please take it into account that using batch mode prevents 0094 * some potentially dangerous recovery execution paths (e.g. delete the existing 0095 * frames in the destination folder). In such case the rendering will be stopped with 0096 * RenderFailed result. 0097 */ 0098 void setBatchMode(bool value); 0099 0100 /** 0101 * @see setBatchMode 0102 */ 0103 bool batchMode() const; 0104 0105 private Q_SLOTS: 0106 void slotFrameCompleted(int frame); 0107 void slotFrameCancelled(int frame, KisAsyncAnimationRendererBase::CancelReason cancelReason); 0108 0109 void slotCancelRegeneration(); 0110 void slotUpdateCompressedProgressData(); 0111 0112 private: 0113 void tryInitiateFrameRegeneration(); 0114 void updateProgressLabel(); 0115 void cancelProcessingImpl(KisAsyncAnimationRendererBase::CancelReason cancelReason); 0116 0117 protected: 0118 /** 0119 * @brief returns a list of frames that should be regenerated by the dialog 0120 * 0121 * Called by the dialog in the very beginning of regenerateRange() 0122 */ 0123 virtual QList<int> calcDirtyFrames() const = 0; 0124 0125 /** 0126 * @brief create a renderer object linked to \p image 0127 * 0128 * Renderer are special objects that connect to the individual image signals, 0129 * react on them and fetch the final frames data 0130 * 0131 * @see KisAsyncAnimationRendererBase 0132 */ 0133 virtual KisAsyncAnimationRendererBase* createRenderer(KisImageSP image) = 0; 0134 0135 virtual void initializeRendererForFrame(KisAsyncAnimationRendererBase *renderer, 0136 KisImageSP image, int frame) = 0; 0137 0138 private: 0139 struct Private; 0140 const QScopedPointer<Private> m_d; 0141 }; 0142 0143 #endif // KISASYNCANIMATIONRENDERDIALOGBASE_H