Line data Source code
1 :
2 : /* Copyright (c) 2007-2012, Stefan Eilemann <eile@equalizergraphics.com>
3 : *
4 : * This library is free software; you can redistribute it and/or modify it under
5 : * the terms of the GNU Lesser General Public License version 2.1 as published
6 : * by the Free Software Foundation.
7 : *
8 : * This library is distributed in the hope that it will be useful, but WITHOUT
9 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11 : * details.
12 : *
13 : * You should have received a copy of the GNU Lesser General Public License
14 : * along with this library; if not, write to the Free Software Foundation, Inc.,
15 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 : */
17 :
18 : #ifndef EQ_COMPOSITOR_H
19 : #define EQ_COMPOSITOR_H
20 :
21 : #include <eq/client/frame.h> // nested type Frame::Buffer
22 : #include <eq/client/types.h> // type definitions
23 :
24 : #include <eq/fabric/pixel.h> // member
25 : #include <eq/fabric/zoom.h> // member
26 :
27 : #include <vector>
28 :
29 : namespace eq
30 : {
31 : /**
32 : * A set of functions performing compositing for a set of input frames.
33 : *
34 : * The following diagram depicts the call flow within the
35 : * compositor. Typically, an application uses one of the entry functions
36 : * assembleFrames() or assembleFramesUnsorted(), but the various lower-level
37 : * functions are still useful for advanced tasks, e.g., mergeFramesCPU() to
38 : * perform compositing on the CPU into a main memory buffer.
39 : *
40 : * <img src="http://www.equalizergraphics.com/documents/design/images/compositor.png">
41 : */
42 : class EQ_API Compositor
43 : {
44 : public:
45 : /** A structure describing an image assembly task. */
46 : struct ImageOp
47 : {
48 2 : ImageOp() : channel( 0 ), buffers( 0 )
49 : , offset( Vector2i::ZERO )
50 2 : , zoomFilter( FILTER_LINEAR ) {}
51 :
52 : Channel* channel; //!< The destination channel
53 : uint32_t buffers; //!< The Frame buffer attachments to use
54 : Vector2i offset; //!< The offset wrt destination window
55 : ZoomFilter zoomFilter; //!< The zoom Filter from Frame
56 : Pixel pixel; //!< The pixel decomposition parameters
57 : Zoom zoom; //!< The zoom factor
58 : };
59 :
60 : /** @name Frame-based operations. */
61 : //@{
62 : /**
63 : * Assemble all frames in an arbitrary order using the fastest
64 : * implemented algorithm on the given channel.
65 : *
66 : * @param frames the frames to assemble.
67 : * @param channel the destination channel.
68 : * @param accum the accumulation buffer.
69 : * @return the number of different subpixel steps assembled.
70 : * @version 1.0
71 : */
72 : static uint32_t assembleFrames( const Frames& frames,
73 : Channel* channel, util::Accum* accum );
74 :
75 : /**
76 : * Assemble all frames in the given order using the fastest implemented
77 : * algorithm on the given channel.
78 : *
79 : * For alpha-blending see comment for assembleFramesCPU().
80 : *
81 : * @param frames the frames to assemble.
82 : * @param channel the destination channel.
83 : * @param accum the accumulation buffer.
84 : * @param blendAlpha blend color-only images if they have an alpha
85 : * channel
86 : * @return the number of different subpixel steps assembled.
87 : * @version 1.0
88 : */
89 : static uint32_t assembleFramesSorted( const Frames& frames,
90 : Channel* channel,
91 : util::Accum* accum,
92 : const bool blendAlpha = false );
93 :
94 : /**
95 : * Assemble all frames in the order they become available directly on
96 : * the given channel.
97 : *
98 : * @param frames the frames to assemble.
99 : * @param channel the destination channel.
100 : * @param accum the accumulation buffer.
101 : * @return the number of different subpixel steps assembled.
102 : * @version 1.0
103 : */
104 : static uint32_t assembleFramesUnsorted( const Frames& frames,
105 : Channel* channel,
106 : util::Accum* accum );
107 :
108 : /**
109 : * Assemble all frames in the given order in a memory buffer using the
110 : * CPU before assembling the result on the given channel.
111 : *
112 : * If alpha-blending is enabled, the images are blended into the
113 : * intermediate image in main memory as if using:
114 : * glBlendFuncSeparate( GL_ONE, GL_SRC_ALPHA, GL_ZERO, GL_SRC_ALPHA )
115 : * The resulting image is composited using
116 : * glBlendFunc( GL_ONE, GL_SRC_ALPHA )
117 : * into the current framebuffer.
118 : *
119 : * @param frames the frames to assemble.
120 : * @param channel the destination channel.
121 : * @param blendAlpha blend color-only images if they have an alpha
122 : * channel
123 : * @return the number of different subpixel steps assembled (0 or 1).
124 : * @version 1.0
125 : */
126 : static uint32_t assembleFramesCPU( const Frames& frames,
127 : Channel* channel,
128 : const bool blendAlpha = false );
129 :
130 : /**
131 : * Merge the provided frames in the given order into one image in main
132 : * memory.
133 : *
134 : * The returned image does not have to be freed. The compositor
135 : * maintains one image per thread, that is, the returned image is valid
136 : * until the next usage of the compositor in the current thread.
137 : *
138 : * @version 1.0
139 : */
140 : static const Image* mergeFramesCPU( const Frames& frames,
141 : const bool blendAlpha = false,
142 : const uint32_t timeout = LB_TIMEOUT_INDEFINITE );
143 :
144 : /**
145 : * Merge the provided frames into one main memory buffer.
146 : *
147 : * The callee has to allocate and clear (if needed) the output buffers
148 : * to hold the necessary data. All input images have to use the same
149 : * format and type, which will also be the output format. The depth
150 : * buffer and depth buffer size may be 0, if the images contain no depth
151 : * information.
152 : *
153 : * The output pixel viewport receives the image size and offset wrt the
154 : * destination channel.
155 : *
156 : * @return true if the compositing was successful, false otherwise,
157 : * e.g., a buffer is too small.
158 : * @version 1.0
159 : */
160 : static bool mergeFramesCPU( const Frames& frames,
161 : const bool blendAlpha,
162 : void* colorBuffer,
163 : const uint32_t colorBufferSize,
164 : void* depthBuffer,
165 : const uint32_t depthBufferSize,
166 : PixelViewport& outPVP,
167 : const uint32_t timeout = LB_TIMEOUT_INDEFINITE );
168 :
169 : /**
170 : * Assemble a frame into the frame buffer using the default algorithm.
171 : * @version 1.0
172 : */
173 : static void assembleFrame( const Frame* frame, Channel* channel );
174 : //@}
175 :
176 :
177 : /** @name Image-based operations. */
178 : //@{
179 : /**
180 : * Assemble an image into the frame buffer.
181 : *
182 : * @param image the input image.
183 : * @param operation an ImageOp struct describing the operation.
184 : */
185 : static void assembleImage( const Image* image,
186 : const ImageOp& operation );
187 :
188 : /**
189 : * Setup the stencil buffer for a pixel compound recomposition.
190 : *
191 : * @param image the image to be assembled.
192 : * @param operation the assembly parameters.
193 : */
194 : static void setupStencilBuffer( const Image* image,
195 : const ImageOp& operation );
196 :
197 : /**
198 : * Clear the stencil buffer after a pixel compound recomposition.
199 : *
200 : * @param operation the assembly parameters.
201 : */
202 : static void clearStencilBuffer( const ImageOp& operation );
203 :
204 : /**
205 : * Setup the OpenGL state.
206 : * @param pvp the current pixel viewport.
207 : * @param gl the OpenGL function table
208 : */
209 : static void setupAssemblyState( const PixelViewport& pvp,
210 : const GLEWContext* gl );
211 :
212 : /**
213 : * Reset the OpenGL state.
214 : */
215 : static void resetAssemblyState();
216 :
217 : /** Start a tile-based assembly of the image color attachment. */
218 : static void assembleImage2D( const Image* image, const ImageOp& op );
219 : /** Start a Z-based assembly of the image color and depth attachment. */
220 : static void assembleImageDB( const Image* image, const ImageOp& op );
221 :
222 : /**
223 : * Start a Z-based assembly of the image color and depth attachment,
224 : * based on OpenGL 1.1 functionality.
225 : */
226 : static void assembleImageDB_FF( const Image* image, const ImageOp& op );
227 :
228 : /**
229 : * Start a Z-based assembly of the image color and depth attachment,
230 : * using GLSL.
231 : */
232 : static void assembleImageDB_GLSL( const Image* image,
233 : const ImageOp& op );
234 : //@}
235 :
236 : /** @name Region of Interest. */
237 : //@{
238 : /**
239 : * Declare the region covered by the image on the operation's channel.
240 : *
241 : * Called from all assembleImage methods.
242 : * @version 1.3
243 : */
244 : static void declareRegion( const Image* image, const ImageOp& op );
245 : //@}
246 :
247 : /** @name Early assembly. */
248 : //@{
249 : /** A handle for one unordered assembly. @version 1.3.1 */
250 : class WaitHandle;
251 :
252 : /** Start waiting on a set of input frames. @version 1.3.1 */
253 : static WaitHandle* startWaitFrames( const Frames& frames,
254 : Channel* channel );
255 :
256 : /**
257 : * Wait for one input frame from a set of pending frames.
258 : *
259 : * Before the first call, a wait handle is acquired using
260 : * startWaitFrames(). When all frames have been processed, 0 is returned
261 : * and the wait handle is invalidated. If the wait times out, an
262 : * exception is thrown and the wait handle in invalidated.
263 : *
264 : * @param handle the wait handle acquires using startWaitFrames().
265 : * @return One ready frame, or 0 if all frames have been processed.
266 : * @version 1.3.1
267 : */
268 : static Frame* waitFrame( WaitHandle* handle );
269 : //@}
270 :
271 : private:
272 : typedef std::pair< const Frame*, const Image* > FrameImage;
273 :
274 : static bool _isSubPixelDecomposition( const Frames& frames );
275 : static const Frames _extractOneSubPixel( Frames& frames );
276 :
277 : static bool _collectOutputData(
278 : const Frames& frames,
279 : PixelViewport& destPVP,
280 : uint32_t& colorInternalFormat,
281 : uint32_t& colorPixelSize,
282 : uint32_t& colorExternalFormat,
283 : uint32_t& depthInternalFormat,
284 : uint32_t& depthPixelSize,
285 : uint32_t& depthExternalFormat,
286 : const uint32_t timeout );
287 :
288 : static void _collectOutputData( const PixelData& pixelData,
289 : uint32_t& internalFormat,
290 : uint32_t& pixelSize,
291 : uint32_t& externalFormat );
292 :
293 : static void _mergeFrames( const Frames& frames,
294 : const bool blendAlpha,
295 : void* colorBuffer, void* depthBuffer,
296 : const PixelViewport& destPVP );
297 :
298 : static void _mergeDBImage( void* destColor, void* destDepth,
299 : const PixelViewport& destPVP,
300 : const Image* image,
301 : const Vector2i& offset );
302 :
303 : static void _merge2DImage( void* destColor, void* destDepth,
304 : const PixelViewport& destPVP,
305 : const Image* input,
306 : const Vector2i& offset );
307 :
308 : static void _mergeBlendImage( void* dest,
309 : const PixelViewport& destPVP,
310 : const Image* input,
311 : const Vector2i& offset );
312 : static bool _mergeImage_PC( int operation, void* destColor,
313 : void* destDepth, const Image* source );
314 : /**
315 : * draw an image to the frame buffer using a texture quad or drawPixels.
316 : */
317 : static void _drawPixels( const Image* image, const ImageOp& op,
318 : const Frame::Buffer which );
319 :
320 : /** @return the accumulation buffer used for subpixel compositing. */
321 : static util::Accum* _obtainAccum( Channel* channel );
322 : };
323 : }
324 :
325 : #endif // EQ_COMPOSITOR_H
326 :
|