forked from NatronGitHub/Natron
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AbortableRenderInfo.h
159 lines (126 loc) · 5.97 KB
/
AbortableRenderInfo.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/* ***** BEGIN LICENSE BLOCK *****
* This file is part of Natron <https://natrongithub.github.io/>,
* (C) 2018-2021 The Natron developers
* (C) 2013-2018 INRIA and Alexandre Gauthier-Foichat
*
* Natron 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.
*
* Natron 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 Natron. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>
* ***** END LICENSE BLOCK ***** */
#ifndef ABORTABLERENDERINFO_H
#define ABORTABLERENDERINFO_H
// ***** BEGIN PYTHON BLOCK *****
// from <https://docs.python.org/3/c-api/intro.html#include-files>:
// "Since Python may define some pre-processor definitions which affect the standard headers on some systems, you must include Python.h before any standard headers are included."
#include <Python.h>
// ***** END PYTHON BLOCK *****
#include "Global/Macros.h"
#include "Global/GlobalDefines.h"
#if !defined(Q_MOC_RUN) && !defined(SBK_RUN)
#include <boost/scoped_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#endif
#include <QtCore/QObject>
#include "Engine/EngineFwd.h"
NATRON_NAMESPACE_ENTER
/**
* @brief Holds infos necessary to identify one render request and whether it was aborted or not.
*
* Typical usage is to start a render on a thread deriving the AbortableThread class, then make a new
* AbortableRenderInfo object and set the info on the thread with the AbortableThread::setAbortInfo function.
*
* Whenever the GenericSchedulerThread::abortThreadedTask() function is called, this will set the aborted flag on this info
* and the thread will be notified. The thread should then periodically call AbortableThread::getAbortInfo and call the AbortableRenderInfo::isAborted()
* function to find out whether the render was aborted or not. Some renders relying on a 3rd party library might not peek the isAborted() function.
* In this case, if this thread does not return from its task after some time that the user called setAborted(), then the user will be notified about a potentially
* stalled render.
**/
struct AbortableRenderInfoPrivate;
class AbortableRenderInfo
: public QObject
, public boost::enable_shared_from_this<AbortableRenderInfo>
{
GCC_DIAG_SUGGEST_OVERRIDE_OFF
Q_OBJECT
GCC_DIAG_SUGGEST_OVERRIDE_ON
private:
// constructors should be privatized in any class that derives from boost::enable_shared_from_this<>
/**
* @brief Create new infos for a specific render that can be aborted with the given age.
* The render age identifies one single frame render in the Viewer. The older a render is, the smaller its render age is.
* This is used in the Viewer keep and order on the render requests, even though each request runs concurrently of another.
* This is not used by playback since in playback the ordering is controlled by the frame number.
**/
AbortableRenderInfo(bool canAbort,
U64 age);
/**
* @brief Same as AbortableRenderInfo(true, 0)
**/
AbortableRenderInfo();
public:
// public constructors
// Note: when switching to C++11, we can add variadic templates:
//template<typename ... T>
//static AbortableRenderInfoPtr create( T&& ... all ) {
// return AbortableRenderInfoPtr( new AbortableRenderInfo( std::forward<T>(all)... ) );
//}
static AbortableRenderInfoPtr create(bool canAbort,
U64 age)
{
return AbortableRenderInfoPtr( new AbortableRenderInfo(canAbort, age) );
}
static AbortableRenderInfoPtr create()
{
return AbortableRenderInfoPtr( new AbortableRenderInfo() );
}
~AbortableRenderInfo();
// Is this render abortable ?
bool canAbort() const;
// Is this render aborted ? This is extremely fast as it just dereferences an atomic integer
bool isAborted() const;
/**
* @brief Set this render as aborted, cannot be reversed. This is call when the function GenericSchedulerThread::abortThreadedTask() is called
**/
void setAborted();
/**
* @brief Get the render age. The render age identifies one single frame render in the Viewer. The older a render is, the smaller its render age is.
* This is used in the Viewer keep and order on the render requests, even though each request runs concurrently of another.
* This is not used by playback since in playback the ordering is controlled by the frame number.
**/
U64 getRenderAge() const;
/**
* @brief Registers the thread as part of this render request. Whenever AbortableThread::setAbortInfo is called, the thread is automatically registered
* in this class as to be part of this render. This is used to monitor running threads for a specific render and to know if a thread has stalled when
* the user called setAborted()
**/
void registerThreadForRender(AbortableThread* thread);
/**
* @brief Unregister the thread as part of this render, returns true
* if it was registered and found.
* This is called whenever a thread calls cleanupTLSForThread(), i.e:
* when its processing is finished.
**/
bool unregisterThreadForRender(AbortableThread* thread);
public Q_SLOTS:
/**
* @brief Triggered by a timer after some time that a thread called setAborted(). This is used to detect stalled threads that do not seem
* to want to abort.
**/
void onAbortTimerTimeout();
void onStartTimerInOriginalThreadTriggered();
Q_SIGNALS:
void startTimerInOriginalThread();
private:
boost::scoped_ptr<AbortableRenderInfoPrivate> _imp;
};
NATRON_NAMESPACE_EXIT
#endif // ABORTABLERENDERINFO_H