1 /***************************************************************************
2 * Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com) *
3 * This file is part of kdenlive. See www.kdenlive.org. *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 ***************************************************************************/
12 This abstract widget is a proof that abstract things sometimes *are* useful.
14 The widget expects three layers which
15 * Will be painted on top of each other on each update
16 * Are rendered in a separate thread so that the UI is not blocked
17 * Are rendered only if necessary (e.g., if a layer does not depend
18 on input images, it will not be re-rendered for incoming frames)
20 The layer order is as follows:
25 ---------------------------
30 ---------------------------
35 ---------------------------
37 Colors of Scope Widgets are defined in here (and thus don't need to be
38 re-defined in the implementation of the widget's .ui file).
40 The custom context menu already contains entries, like for enabling auto-
41 refresh. It can certainly be extended in the implementation of the widget.
43 Note: Widgets deriving from this class should connect slotActiveMonitorChanged
44 to the appropriate signal.
46 If you intend to write an own widget inheriting from this one, please read
47 the comments on the unimplemented methods carefully. They are not only here
48 for optical amusement, but also contain important information.
51 #ifndef ABSTRACTSCOPEWIDGET_H
52 #define ABSTRACTSCOPEWIDGET_H
62 class AbstractScopeWidget : public QWidget
67 AbstractScopeWidget(Monitor *projMonitor, Monitor *clipMonitor, QWidget *parent = 0);
68 virtual ~AbstractScopeWidget(); // Must be virtual because of inheritance, to avoid memory leaks
69 QPalette m_scopePalette;
71 virtual QString widgetName() const = 0;
76 Monitor *m_projMonitor;
77 Monitor *m_clipMonitor;
78 Render *m_activeRender;
81 /** The context menu. Feel free to add new entries in your implementation. */
84 /** Enables auto refreshing of the scope.
85 This is when a new frame is shown on the active monitor.
86 Resize events always force a recalculation. */
87 QAction *m_aAutoRefresh;
89 /** Realtime rendering. Should be disabled if it is not supported.
90 Use the accelerationFactor variable passed to the render functions as a hint of
91 how many times faster the scope should be calculated. */
95 /** Offset from the widget's borders */
98 /** The rect on the widget we're painting in. */
101 /** Images storing the calculated layers. Will be used on repaint events. */
104 QImage m_imgBackground;
107 ///// Unimplemented Methods /////
109 /** Where on the widget we can paint in */
110 virtual QRect scopeRect() = 0;
112 /** @brief HUD renderer. Must emit signalHUDRenderingFinished(). @see renderScope */
113 virtual QImage renderHUD(uint accelerationFactor) = 0;
114 /** @brief Scope renderer. Must emit signalScopeRenderingFinished()
115 when calculation has finished, to allow multi-threading.
116 accelerationFactor hints how much faster than usual the calculation should be accomplished, if possible. */
117 virtual QImage renderScope(uint accelerationFactor) = 0;
118 /** @brief Background renderer. Must emit signalBackgroundRenderingFinished(). @see renderScope */
119 virtual QImage renderBackground(uint accelerationFactor) = 0;
121 /** Must return true if the HUD layer depends on the input monitor.
122 If it does not, then it does not need to be re-calculated when
123 a new frame from the monitor is incoming. */
124 virtual bool isHUDDependingOnInput() const = 0;
125 /** @see isHUDDependingOnInput() */
126 virtual bool isScopeDependingOnInput() const = 0;
127 /** @see isHUDDependingOnInput() */
128 virtual bool isBackgroundDependingOnInput() const = 0;
132 void mouseReleaseEvent(QMouseEvent *);
133 void paintEvent(QPaintEvent *);
134 void resizeEvent(QResizeEvent *);
137 /** mseconds represent the time taken for the calculation,
138 accelerationFactor the acceleration factor that has been used. */
139 void signalHUDRenderingFinished(uint mseconds, uint accelerationFactor);
140 void signalScopeRenderingFinished(uint mseconds, uint accelerationFactor);
141 void signalBackgroundRenderingFinished(uint mseconds, uint accelerationFactor);
145 /** Counts the number of frames that have been rendered in the active monitor.
146 The frame number will be reset when the calculation starts for the current frame. */
147 QAtomicInt m_newHUDFrames;
148 QAtomicInt m_newScopeFrames;
149 QAtomicInt m_newBackgroundFrames;
151 /** Counts the number of updates that, unlike new frames, force a recalculation
152 of the scope, like for example a resize event. */
153 QAtomicInt m_newHUDUpdates;
154 QAtomicInt m_newScopeUpdates;
155 QAtomicInt m_newBackgroundUpdates;
157 /** The semaphores ensure that the QFutures for the HUD/Scope/Background threads cannot
158 be assigned a new thread while it is still running. (Could cause deadlocks and other
159 nasty things known from parallelism. */
160 QSemaphore m_semaphoreHUD;
161 QSemaphore m_semaphoreScope;
162 QSemaphore m_semaphoreBackground;
164 QFuture<QImage> m_threadHUD;
165 QFuture<QImage> m_threadScope;
166 QFuture<QImage> m_threadBackground;
168 int m_accelFactorHUD;
169 int m_accelFactorScope;
170 int m_accelFactorBackground;
172 bool initialDimensionUpdateDone;
173 void prodHUDThread();
174 void prodScopeThread();
175 void prodBackgroundThread();
179 /** @brief Must be called when the active monitor has shown a new frame.
180 This slot must be connected in the implementing class, it is *not*
181 done in this abstract class. */
182 void slotActiveMonitorChanged(bool isClipMonitor);
183 void customContextMenuRequested(const QPoint &pos);
184 void slotRenderZoneUpdated();
185 void slotHUDRenderingFinished(uint mseconds, uint accelerationFactor);
186 void slotScopeRenderingFinished(uint mseconds, uint accelerationFactor);
187 void slotBackgroundRenderingFinished(uint mseconds, uint accelerationFactor);
189 /** Resets the acceleration factors to 1 when realtime rendering is disabled. */
190 void slotResetRealtimeFactor(bool realtimeChecked);
194 #endif // ABSTRACTSCOPEWIDGET_H