Line data Source code
1 :
2 : /* Copyright (c) 2005-2014, Stefan Eilemann <eile@equalizergraphics.com>
3 : * 2010, Cedric Stalder <cedric.stalder@gmail.com>
4 : * 2011, Daniel Nachbaur <danielnachbaur@gmail.com>
5 : *
6 : * This library is free software; you can redistribute it and/or modify it under
7 : * the terms of the GNU Lesser General Public License version 2.1 as published
8 : * by the Free Software Foundation.
9 : *
10 : * This library is distributed in the hope that it will be useful, but WITHOUT
11 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 : * details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public License
16 : * along with this library; if not, write to the Free Software Foundation, Inc.,
17 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #ifndef EQ_CHANNEL_H
21 : #define EQ_CHANNEL_H
22 :
23 : #include <eq/client/api.h>
24 : #include <eq/client/types.h>
25 :
26 : #include <eq/fabric/channel.h> // base class
27 :
28 : namespace eq
29 : {
30 : namespace detail { class Channel; struct RBStat; }
31 :
32 : /**
33 : * A channel represents a two-dimensional viewport within a Window.
34 : *
35 : * The channel is the basic rendering entity. It represents a 2D rendering area
36 : * within a Window. It executes all rendering-relevant tasks, such as clear,
37 : * draw, assemble and readback. Each rendering task is using its own
38 : * RenderContext, which is computed by the server based on the rendering
39 : * description of the current configuration.
40 : *
41 : * @sa fabric::Channel
42 : */
43 : class Channel : public fabric::Channel< Window, Channel >
44 : {
45 : public:
46 : /** Construct a new channel. @version 1.0 */
47 : EQ_API Channel( Window* parent );
48 :
49 : /** Destruct the channel. @version 1.0 */
50 : EQ_API virtual ~Channel();
51 :
52 : /** @name Data Access */
53 : //@{
54 : EQ_API co::CommandQueue* getPipeThreadQueue(); //!< @internal
55 : EQ_API co::CommandQueue* getCommandThreadQueue(); //!< @internal
56 : EQ_API uint32_t getCurrentFrame() const; //!< @internal render thr only
57 : void waitFrameFinished( const uint32_t frame ) const; //!< @internal
58 :
59 : /**
60 : * @return true if this channel is stopped, false otherwise.
61 : * @version 1.0
62 : */
63 : EQ_API bool isStopped() const;
64 :
65 : /** @return the parent pipe. @version 1.0 */
66 : EQ_API Pipe* getPipe();
67 :
68 : /** @return the parent pipe. @version 1.0 */
69 : EQ_API const Pipe* getPipe() const;
70 :
71 : /** @return the parent node. @version 1.0 */
72 : EQ_API Node* getNode();
73 :
74 : /** @return the parent node. @version 1.0 */
75 : EQ_API const Node* getNode() const;
76 :
77 : /** @return the parent config. @version 1.0 */
78 : EQ_API Config* getConfig();
79 :
80 : /** @return the parent config. @version 1.0 */
81 : EQ_API const Config* getConfig() const;
82 :
83 : /** @return the parent server. @version 1.0 */
84 : EQ_API ServerPtr getServer();
85 :
86 : /**
87 : * Get the GLEW context for this channel.
88 : *
89 : * The GLEW context is initialized during window initialization, and
90 : * provides access to OpenGL extensions. This function does not follow the
91 : * Equalizer naming conventions, since GLEW uses a function of this name to
92 : * automatically resolve OpenGL function entry points. Therefore, any
93 : * supported GL function can be called directly from an initialized Channel.
94 : *
95 : * @return the extended OpenGL function table for the channel's OpenGL
96 : * context.
97 : * @version 1.0
98 : */
99 : EQ_API const GLEWContext* glewGetContext() const;
100 :
101 : /** @return the window's object manager instance. @version 1.0 */
102 : EQ_API util::ObjectManager& getObjectManager();
103 :
104 : /** @return the channel's drawable config. @version 1.0 */
105 : EQ_API const DrawableConfig& getDrawableConfig() const;
106 :
107 : /**
108 : * Get the channel's native view.
109 : *
110 : * This function always returns the channel's native view, no matter in
111 : * which context it is called. Only destination channels have a native view.
112 : *
113 : * @return the channel's native view, or 0 if it does not have one.
114 : * @sa getView()
115 : * @version 1.0
116 : */
117 : EQ_API View* getNativeView();
118 :
119 : /** const-version of getNativeView() @version 1.0 */
120 : EQ_API const View* getNativeView() const;
121 :
122 : /** @return the FBO used as an alternate frame buffer. @version 1.0*/
123 : EQ_API util::FrameBufferObject* getFrameBufferObject();
124 :
125 : /** @return a fixed unique color for this channel. @version 1.0 */
126 : EQ_API const Vector3ub& getUniqueColor() const;
127 :
128 : /** @internal Add a new statistics event for the current frame. */
129 : EQ_API void addStatistic( Event& event );
130 : //@}
131 :
132 : /**
133 : * @name Context-specific data access.
134 : *
135 : * The data returned by these methods depends on the context (callback) they
136 : * are called from, typically the data for the current rendering task. If
137 : * they are called outside of a frame task method, they return the channel's
138 : * native parameter or a placeholder value for the task decomposition
139 : * parameters.
140 : */
141 : //@{
142 : /**
143 : * @return the jitter vector for the current subpixel decomposition.
144 : * @version 1.0
145 : */
146 : EQ_API virtual Vector2f getJitter() const;
147 :
148 : /**
149 : * Get the channel's current View.
150 : *
151 : * During a frame task method, i.e., in one of the frameFoo functions, the
152 : * view is set to the view of the destination channel, that is, the channel
153 : * for which this channel is executing the rendering task. Outside of a
154 : * frame task method the native view of the channel, or 0, is returned.
155 : *
156 : * @return the channel's view, or 0 if it does not have a view.
157 : * @sa getNativeView()
158 : * @version 1.0
159 : */
160 : EQ_API View* getView();
161 :
162 : /** Const version of getView(). @version 1.0 */
163 : EQ_API const View* getView() const;
164 :
165 : /**
166 : * Returns an orthographic frustum for 2D operations on the view.
167 : *
168 : * One unit of the frustum covers one pixel on screen. The frustum is
169 : * positioned relative to the view.
170 : *
171 : * @return the 2D orthographic frustum.
172 : * @version 1.0
173 : */
174 : EQ_API Frustumf getScreenFrustum() const;
175 : //@}
176 :
177 : /**
178 : * @name Operations
179 : *
180 : * Operations are only meaningful from within certain callbacks. They are
181 : * just convenience wrappers applying context-specific data to the OpenGL
182 : * state using the context-specific data access above.
183 : */
184 : //@{
185 : /**
186 : * Apply the current rendering buffer, including the color mask.
187 : * @sa getReadBuffer() , getDrawBuffer(), getDrawBufferMask()
188 : * @version 1.0
189 : */
190 : EQ_API virtual void applyBuffer();
191 :
192 : /**
193 : * Apply the current color mask.
194 : * @sa applyBuffer(), getDrawBufferMask()
195 : * @version 1.0
196 : */
197 : EQ_API virtual void applyColorMask() const;
198 :
199 : /**
200 : * Apply the OpenGL viewport for the current rendering task.
201 : * @sa getViewport()
202 : * @version 1.0
203 : */
204 : EQ_API virtual void applyViewport() const;
205 :
206 : /**
207 : * Apply the frustum matrix for the current rendering task.
208 : *
209 : * If a sub-pixel decomposition is defined, the frustum is jittered by the
210 : * amount given by getJitter() to implement software
211 : * anti-aliasing. Applications which want to implement a different
212 : * multi-sampling algorithm, e.g., depth-of-field, have to re-implement
213 : * getJitter() or applyFrustum() accordingly.
214 : *
215 : * @sa useOrtho(), getJitter(), getSubPixel()
216 : * @version 1.0
217 : */
218 : EQ_API virtual void applyFrustum() const;
219 :
220 : /**
221 : * Apply the perspective frustum matrix for the current rendering task.
222 : * @version 1.0
223 : */
224 : EQ_API virtual void applyPerspective() const;
225 :
226 : /**
227 : * Apply the orthographic frustum matrix for the current rendering task.
228 : * @version 1.0
229 : */
230 : EQ_API virtual void applyOrtho() const;
231 :
232 : /**
233 : * Apply an orthographic frustum for pixel-based 2D operations.
234 : *
235 : * One unit of the frustum covers one pixel on screen. The frustum is
236 : * positioned relative to the view.
237 : * @version 1.0
238 : */
239 : EQ_API void applyScreenFrustum() const;
240 :
241 : /**
242 : * Apply the transformation to position the view frustum.
243 : * @version 1.0
244 : * @sa useOrtho()
245 : */
246 : EQ_API virtual void applyHeadTransform() const;
247 :
248 : /**
249 : * Apply the transformation to position the perspective view frustum.
250 : * @version 1.0
251 : */
252 : EQ_API virtual void applyPerspectiveTransform() const;
253 :
254 : /**
255 : * Apply the transformation to position the orthographic view frustum.
256 : * @version 1.0
257 : */
258 : EQ_API virtual void applyOrthoTransform() const;
259 :
260 : /**
261 : * Apply the current alternate frame buffer.
262 : * @version 1.0
263 : */
264 : EQ_API virtual void applyFrameBufferObject();
265 :
266 : /**
267 : * Rebind the current alternate FBO of the channel or window.
268 : * @version 1.0
269 : */
270 : EQ_API void bindFrameBuffer();
271 : //@}
272 :
273 : /** @name Region of Interest. */
274 : //@{
275 : /**
276 : * Reset the declared regions of interest.
277 : *
278 : * Called from frameStart and frameClear to reset the area to be used to
279 : * optimize compositing and load balancing for each frame.
280 : * @version 1.3
281 : */
282 : EQ_API virtual void resetRegions();
283 :
284 : /**
285 : * Declare a region covered by the current draw or assemble operation.
286 : *
287 : * The region is relative to the current pixel viewport. It is clipped
288 : * against the current pixel viewport of the channel. Called with the full
289 : * pixel viewport after frameDraw if no region has been declared.
290 : *
291 : * Declaring a single, empty region causes this channel to not read back any
292 : * pixel data, i.e., if it did not draw anything.
293 : *
294 : * The implementation might merge or split the declared regions.
295 : *
296 : * @version 1.3
297 : */
298 : EQ_API virtual void declareRegion( const eq::PixelViewport& region );
299 :
300 : /**
301 : * Convenience method to declare a region in relative coordinates.
302 : *
303 : * The given viewport is relative to the current pixel viewport.
304 : * @version 1.3
305 : */
306 : EQ_API void declareRegion( const eq::Viewport& vp );
307 :
308 : /** @return a region covering all declared regions. @version 1.3 */
309 : EQ_API PixelViewport getRegion() const;
310 :
311 : /**
312 : * Get the current regions of interest.
313 : *
314 : * The returned regions are guaranteed not to overlap with each
315 : * other. Therefore they may differ in number and size from the declared
316 : * regions. The actual algorithm to create the non-overlapping regions is
317 : * unspecified and may change in the future.
318 : *
319 : * @return current regions of interest.
320 : * @version 1.3
321 : */
322 : EQ_API const PixelViewports& getRegions() const;
323 : //@}
324 :
325 : /** @name Events */
326 : //@{
327 : /**
328 : * Send a channel error event to the application node.
329 : *
330 : * @param error the error code.
331 : * @version 1.7.1
332 : */
333 : EQ_API EventOCommand sendError( const uint32_t error );
334 :
335 : /**
336 : * Process a received event.
337 : *
338 : * The task of this method is to update the channel as necessary, and
339 : * transform the event into a config event to be send to the application
340 : * using Config::sendEvent().
341 : *
342 : * @param event the received event.
343 : * @return true when the event was handled, false if not.
344 : * @version 1.0
345 : */
346 : EQ_API virtual bool processEvent( const Event& event );
347 : //@}
348 :
349 : /** Draw a statistics overlay. @version 1.0 */
350 : EQ_API virtual void drawStatistics();
351 :
352 : /** Outline the current pixel viewport. @version 1.0 */
353 : EQ_API virtual void outlineViewport();
354 :
355 : /**
356 : * @internal
357 : * Change the latency.
358 : *
359 : * @param latency the new latency.
360 : */
361 : void changeLatency( const uint32_t latency );
362 :
363 : protected:
364 : /** @internal */
365 : EQ_API void attach( const uint128_t& id, const uint32_t instanceID );
366 :
367 : /** @name Actions */
368 : //@{
369 : /**
370 : * Start a frame by unlocking all child resources.
371 : *
372 : * @param frameNumber the frame to start.
373 : * @version 1.0
374 : */
375 : EQ_API void startFrame( const uint32_t frameNumber );
376 :
377 : /**
378 : * Signal the completion of a frame to the parent.
379 : *
380 : * @param frameNumber the frame to end.
381 : * @version 1.0
382 : */
383 : EQ_API void releaseFrame( const uint32_t frameNumber );
384 :
385 : /**
386 : * Release the local synchronization of the parent for a frame.
387 : *
388 : * @param frameNumber the frame to release.
389 : * @version 1.0
390 : */
391 : EQ_API void releaseFrameLocal( const uint32_t frameNumber );
392 :
393 : /**
394 : * Setup the OpenGL state for a readback or assemble operation.
395 : *
396 : * The default implementation is very conservative and saves any state
397 : * which is potentially changed by the assembly routines. Applications
398 : * may overwrite this and resetAssemblyState() to optimize performance
399 : * in accordance with their rendering code.
400 : *
401 : * @version 1.0
402 : */
403 : EQ_API virtual void setupAssemblyState();
404 :
405 : /** Reset the OpenGL state after an assembly operation. @version 1.0 */
406 : EQ_API virtual void resetAssemblyState();
407 : //@}
408 :
409 : /**
410 : * @name Task Methods
411 : *
412 : * The task methods (callbacks) are called by Equalizer during rendering
413 : * to execute various rendering tasks. Each task method has a useful
414 : * default implementation, but at least frameDraw() is implemented by an
415 : * application.
416 : */
417 : //@{
418 : /**
419 : * Initialize this channel.
420 : *
421 : * @param initID the init identifier.
422 : * @version 1.0
423 : */
424 : EQ_API virtual bool configInit( const uint128_t& initID );
425 :
426 : /** Exit this channel. @version 1.0 */
427 : EQ_API virtual bool configExit();
428 :
429 : /**
430 : * Start rendering a frame.
431 : *
432 : * Called once at the beginning of each frame, to do per-frame updates
433 : * of channel-specific data. This method has to call startFrame().
434 : *
435 : * @param frameID the per-frame identifier.
436 : * @param frameNumber the frame to start.
437 : * @sa Config::startFrame()
438 : * @version 1.0
439 : */
440 : EQ_API virtual void frameStart( const uint128_t& frameID,
441 : const uint32_t frameNumber );
442 :
443 : /**
444 : * Finish rendering a frame.
445 : *
446 : * Called once at the end of each frame, to do per-frame updates of
447 : * channel-specific data. This method has to call releaseFrame().
448 : *
449 : * @param frameID the per-frame identifier.
450 : * @param frameNumber the frame to finish.
451 : * @version 1.0
452 : */
453 : EQ_API virtual void frameFinish( const uint128_t& frameID,
454 : const uint32_t frameNumber );
455 :
456 : /**
457 : * Finish drawing.
458 : *
459 : * Called once per frame after the last draw operation. Typically
460 : * releases the local node thread synchronization for this frame.
461 : *
462 : * @param frameID the per-frame identifier.
463 : * @param frameNumber the frame to finished with draw.
464 : * @version 1.0
465 : */
466 : EQ_API virtual void frameDrawFinish( const uint128_t& frameID,
467 : const uint32_t frameNumber );
468 :
469 : /**
470 : * Clear the frame buffer.
471 : *
472 : * Called 0 to n times during one frame.
473 : *
474 : * @param frameID the per-frame identifier.
475 : * @version 1.0
476 : */
477 : EQ_API virtual void frameClear( const uint128_t& frameID );
478 :
479 : /**
480 : * Draw the scene.
481 : *
482 : * Called 0 to n times during one frame.
483 : *
484 : * @param frameID the per-frame identifier.
485 : * @version 1.0
486 : */
487 : EQ_API virtual void frameDraw( const uint128_t& frameID );
488 :
489 : /**
490 : * Assemble all input frames.
491 : *
492 : * Called 0 to n times during one frame.
493 : *
494 : * @param frameID the per-frame identifier.
495 : * @param frames the input frames.
496 : * @version 1.7.3
497 : */
498 : EQ_API virtual void frameAssemble( const uint128_t& frameID,
499 : const Frames& frames );
500 :
501 : /**
502 : * Read back the rendered frame buffer into the output frames.
503 : *
504 : * Called 0 to n times during one frame.
505 : *
506 : * @param frameID the per-frame identifier.
507 : * @param frames the output frames.
508 : * @version 1.7.3
509 : * @version 1.0
510 : */
511 : EQ_API virtual void frameReadback( const uint128_t& frameID,
512 : const Frames& frames );
513 :
514 : /**
515 : * Start updating a destination channel.
516 : *
517 : * Called once on each destination channel, e.g., channels which are
518 : * defined by a view/segment intersection, after frameStart to update a
519 : * part of a display.
520 : *
521 : * @param frameID the per-frame identifier.
522 : * @version 1.0
523 : */
524 : EQ_API virtual void frameViewStart( const uint128_t& frameID );
525 :
526 : /**
527 : * Finish updating a destination channel.
528 : *
529 : * Called once on each destination channel, e.g., channels which are
530 : * defined by a view/segment intersection, before frameFinish to update
531 : * a part of a view.
532 : *
533 : * This is typically used to do operations on the output channel after
534 : * it has been fully updated, e.g., to draw a 2D overlay.
535 : *
536 : * @param frameID the per-frame identifier.
537 : * @version 1.0
538 : */
539 : EQ_API virtual void frameViewFinish( const uint128_t& frameID );
540 : //@}
541 :
542 : /** Start a batch of tile rendering operations. @version 1.1.6 */
543 0 : virtual void frameTilesStart( const uint128_t& /*frameID*/ ) {}
544 :
545 : /** Finish a batch of tile rendering operations. @version 1.1.6 */
546 0 : virtual void frameTilesFinish( const uint128_t& /*frameID*/ ) {}
547 :
548 : /** Notification that parameters influencing the vp/pvp have changed.*/
549 : EQ_API virtual void notifyViewportChanged();
550 :
551 : /**
552 : * Notify interruption of the rendering.
553 : *
554 : * This method is called from the Client command thread, as opposed to the
555 : * rendering thread. Its purpose is to cause the rendering thread to stop
556 : * its operations as soon as possible. Normal rendering shall recommence
557 : * after the given frame.
558 : *
559 : * @param lastFrameNumber stop rendering until this frame has been
560 : * processed.
561 : * @version 1.0
562 : */
563 : EQ_API virtual void notifyStopFrame( const uint32_t lastFrameNumber );
564 :
565 : private:
566 : detail::Channel* const _impl;
567 : friend class fabric::Window< Pipe, Window, Channel, WindowSettings >;
568 :
569 : //-------------------- Methods --------------------
570 : /** Setup the current rendering context. */
571 : void _overrideContext( RenderContext& context );
572 :
573 : /** Initialize the FBO */
574 : bool _configInitFBO();
575 :
576 : /** Initialize the channel's drawable config. */
577 : void _initDrawableConfig();
578 :
579 : /** Tile render loop. */
580 : void _frameTiles( RenderContext& context, const bool isLocal,
581 : const uint128_t& queueID, const uint32_t tasks,
582 : const co::ObjectVersions& frames );
583 :
584 : /** Reference the frame for an async operation. */
585 : void _refFrame( const uint32_t frameNumber );
586 :
587 : /** Check for and send frame finish reply. */
588 : void _unrefFrame( const uint32_t frameNumber );
589 :
590 : /** Transmit one image of a frame to one node. */
591 : void _transmitImage( const co::ObjectVersion& frameDataVersion,
592 : const uint128_t& nodeID,
593 : const co::NodeID& netNodeID,
594 : const uint64_t imageIndex,
595 : const uint32_t frameNumber,
596 : const uint32_t taskID );
597 :
598 : void _frameReadback( const uint128_t& frameID,
599 : const co::ObjectVersions& frames );
600 : void _finishReadback( const co::ObjectVersion& frameDataVersion,
601 : const uint64_t imageIndex,
602 : const uint32_t frameNumber,
603 : const uint32_t taskID,
604 : const std::vector< uint128_t >& nodes,
605 : const co::NodeIDs& netNodes );
606 :
607 : bool _asyncFinishReadback( const std::vector< size_t >& imagePos,
608 : const Frames& frames );
609 :
610 : void _asyncTransmit( FrameDataPtr frame, const uint32_t frameNumber,
611 : const uint64_t image,
612 : const std::vector< uint128_t >& nodes,
613 : const co::NodeIDs& netNodes,
614 : const uint32_t taskID );
615 :
616 : void _setReady( const bool async, detail::RBStat* stat,
617 : const Frames& frames );
618 : void _asyncSetReady( const FrameDataPtr frame, detail::RBStat* stat,
619 : const std::vector< uint128_t >& nodes,
620 : const co::NodeIDs& netNodes );
621 :
622 : void _setReady( FrameDataPtr frame, detail::RBStat* stat,
623 : const std::vector< uint128_t >& nodes,
624 : const co::NodeIDs& netNodes );
625 :
626 : /** Get the channel's current input queue. */
627 : co::QueueSlave* _getQueue( const uint128_t& queueID );
628 :
629 : Frames _getFrames( const co::ObjectVersions& frameIDs,
630 : const bool isOutput );
631 :
632 : void _deleteTransferContext();
633 :
634 : /* The command handler functions. */
635 : bool _cmdConfigInit( co::ICommand& command );
636 : bool _cmdConfigExit( co::ICommand& command );
637 : bool _cmdFrameStart( co::ICommand& command );
638 : bool _cmdFrameFinish( co::ICommand& command );
639 : bool _cmdFrameClear( co::ICommand& command );
640 : bool _cmdFrameDraw( co::ICommand& command );
641 : bool _cmdFrameDrawFinish( co::ICommand& command );
642 : bool _cmdFrameAssemble( co::ICommand& command );
643 : bool _cmdFrameReadback( co::ICommand& command );
644 : bool _cmdFinishReadback( co::ICommand& command );
645 : bool _cmdFrameSetReady( co::ICommand& command );
646 : bool _cmdFrameTransmitImage( co::ICommand& command );
647 : bool _cmdFrameSetReadyNode( co::ICommand& command );
648 : bool _cmdFrameViewStart( co::ICommand& command );
649 : bool _cmdFrameViewFinish( co::ICommand& command );
650 : bool _cmdStopFrame( co::ICommand& command );
651 : bool _cmdFrameTiles( co::ICommand& command );
652 : bool _cmdDeleteTransferContext( co::ICommand& command );
653 :
654 840 : LB_TS_VAR( _pipeThread );
655 : };
656 : }
657 :
658 : #endif // EQ_CHANNEL_H
|