Panda3D
Loading...
Searching...
No Matches
pipelineCycler.h
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file pipelineCycler.h
10 * @author drose
11 * @date 2002-02-21
12 */
13
14#ifndef PIPELINECYCLER_H
15#define PIPELINECYCLER_H
16
17#include "pandabase.h"
18#include "pipelineCyclerBase.h"
19#include "cyclerHolder.h"
20#include "thread.h"
21
22/**
23 * This class maintains different copies of a page of data between stages of
24 * the graphics pipeline (or any other pipelining context).
25 *
26 * The class object maintains up to n copies of a CycleData structure, one for
27 * each stage of the pipeline. The head of the pipeline is responsible for
28 * making changes to its copy, which are then cycled through the pipeline at
29 * each frame.
30 *
31 * To access the data, you must first ask for a readable pointer. In order to
32 * make changes to the data, you must ask for a writable pointer. Both kinds
33 * of pointers should be released when you are done, as a sanity check. The
34 * CycleDataReader and CycleDataWriter classes transparently handle this.
35 *
36 * If pipelining support is not enabled at compile time (that is,
37 * DO_PIPELINING is not defined), this object compiles to a minimum object
38 * that presents the same interface but with minimal runtime overhead.
39 *
40 * We define this as a struct instead of a class to guarantee byte placement
41 * within the object, so that (particularly for the trivial implementation)
42 * the inherited struct's data is likely to be placed by the compiler at the
43 * "this" pointer.
44 */
45template<class CycleDataType>
47public:
48 INLINE PipelineCycler(Pipeline *pipeline = nullptr);
49 INLINE PipelineCycler(CycleDataType &&initial_data, Pipeline *pipeline = nullptr);
50
52 INLINE void operator = (const PipelineCycler<CycleDataType> &copy);
53
54 INLINE const CycleDataType *read_unlocked(Thread *current_thread) const;
55 INLINE const CycleDataType *read(Thread *current_thread) const;
56 INLINE CycleDataType *write(Thread *current_thread);
57 INLINE CycleDataType *write_upstream(bool force_to_0, Thread *current_thread);
58 INLINE CycleDataType *elevate_read(const CycleDataType *pointer, Thread *current_thread);
59 INLINE CycleDataType *elevate_read_upstream(const CycleDataType *pointer, bool force_to_0, Thread *current_thread);
60
61 INLINE const CycleDataType *read_stage_unlocked(int pipeline_stage) const;
62 INLINE const CycleDataType *read_stage(int pipeline_stage, Thread *current_thread) const;
63 INLINE CycleDataType *elevate_read_stage(int pipeline_stage, const CycleDataType *pointer, Thread *current_thread);
64 INLINE CycleDataType *elevate_read_stage_upstream(int pipeline_stage, const CycleDataType *pointer, bool force_to_0, Thread *current_thread);
65 INLINE CycleDataType *write_stage_upstream(int pipeline_stage, bool force_to_0, Thread *current_thread);
66 INLINE CycleDataType *write_stage(int pipeline_stage, Thread *current_thread);
67
68 INLINE CycleDataType *cheat() const;
69
70#ifndef DO_PIPELINING
71private:
72 // If we are *not* compiling in support for pipelining, we just store the
73 // CycleData object right here. No pointers needed.
74 CycleDataType _typed_data;
75#endif // !DO_PIPELINING
76};
77
78// These macros are handy for iterating through the set of pipeline stages.
79// They're particularly useful for updating cache values upstream of the
80// current stage, or for removing bad pointers from all stages of the
81// pipeline. In each case, the variable pipeline_stage is defined within the
82// loop to be the current stage of the pipeline traversed by the loop.
83#ifdef DO_PIPELINING
84
85// Iterates through all of the pipeline stages upstream of the current stage,
86// but not including the current stage.
87#define OPEN_ITERATE_UPSTREAM_ONLY(cycler, current_thread) { \
88 CyclerHolder cholder(cycler); \
89 int pipeline_stage; \
90 for (pipeline_stage = current_thread->get_pipeline_stage() - 1; \
91 pipeline_stage >= 0; \
92 --pipeline_stage)
93
94#define CLOSE_ITERATE_UPSTREAM_ONLY(cycler) \
95 }
96
97// Iterates through all of the pipeline stages upstream of the current stage,
98// and including the current stage.
99#define OPEN_ITERATE_CURRENT_AND_UPSTREAM(cycler, current_thread) { \
100 CyclerHolder cholder(cycler); \
101 int pipeline_stage; \
102 for (pipeline_stage = current_thread->get_pipeline_stage(); \
103 pipeline_stage >= 0; \
104 --pipeline_stage)
105
106#define CLOSE_ITERATE_CURRENT_AND_UPSTREAM(cycler) \
107 }
108
109// As above, but without holding the cycler lock during the loop.
110#define OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(cycler, current_thread) { \
111 int pipeline_stage; \
112 for (pipeline_stage = current_thread->get_pipeline_stage(); \
113 pipeline_stage >= 0; \
114 --pipeline_stage)
115
116#define CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(cycler) \
117 }
118
119// Iterates through all of the pipeline stages.
120#define OPEN_ITERATE_ALL_STAGES(cycler) { \
121 int pipeline_stage; \
122 for (pipeline_stage = (cycler).get_num_stages() - 1; \
123 pipeline_stage >= 0; \
124 --pipeline_stage)
125
126#define CLOSE_ITERATE_ALL_STAGES(cycler) \
127 }
128
129#else // DO_PIPELINING
130
131// These are trivial implementations of the above macros, defined when
132// pipelining is not enabled, that simply operate on stage 0 without bothering
133// to create a for loop.
134#define OPEN_ITERATE_UPSTREAM_ONLY(cycler, current_thread) \
135 if (false) { \
136 const int pipeline_stage = -1;
137
138#define CLOSE_ITERATE_UPSTREAM_ONLY(cycler) \
139 }
140
141#define OPEN_ITERATE_CURRENT_AND_UPSTREAM(cycler, current_thread) { \
142 const int pipeline_stage = 0; \
143
144#define CLOSE_ITERATE_CURRENT_AND_UPSTREAM(cycler) \
145 }
146
147#define OPEN_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(cycler, current_thread) { \
148 const int pipeline_stage = 0; \
149
150#define CLOSE_ITERATE_CURRENT_AND_UPSTREAM_NOLOCK(cycler) \
151 }
152
153#define OPEN_ITERATE_ALL_STAGES(cycler) { \
154 const int pipeline_stage = 0; \
155
156#define CLOSE_ITERATE_ALL_STAGES(cycler) \
157 }
158
159#endif // DO_PIPELINING
160
161#include "pipelineCycler.I"
162
163#endif
This class manages a staged pipeline of data, for instance the render pipeline, so that each stage of...
Definition pipeline.h:38
A thread; that is, a lightweight process.
Definition thread.h:46
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the trivial, non-threaded implementation of PipelineCyclerBase.
This class maintains different copies of a page of data between stages of the graphics pipeline (or a...
const CycleDataType * read_stage(int pipeline_stage, Thread *current_thread) const
See PipelineCyclerBase::read_stage().
CycleDataType * cheat() const
Returns a pointer without counting it.
CycleDataType * elevate_read_stage_upstream(int pipeline_stage, const CycleDataType *pointer, bool force_to_0, Thread *current_thread)
See PipelineCyclerBase::elevate_read_stage_upstream().
const CycleDataType * read_stage_unlocked(int pipeline_stage) const
See PipelineCyclerBase::read_stage_unlocked().
CycleDataType * write_upstream(bool force_to_0, Thread *current_thread)
See PipelineCyclerBase::write_upstream().
CycleDataType * write_stage_upstream(int pipeline_stage, bool force_to_0, Thread *current_thread)
See PipelineCyclerBase::write_stage_upstream().
CycleDataType * write(Thread *current_thread)
See PipelineCyclerBase::write().
CycleDataType * elevate_read_upstream(const CycleDataType *pointer, bool force_to_0, Thread *current_thread)
See PipelineCyclerBase::elevate_read_upstream().
const CycleDataType * read(Thread *current_thread) const
See PipelineCyclerBase::read().
CycleDataType * write_stage(int pipeline_stage, Thread *current_thread)
See PipelineCyclerBase::write_stage().
const CycleDataType * read_unlocked(Thread *current_thread) const
See PipelineCyclerBase::read_unlocked().
CycleDataType * elevate_read(const CycleDataType *pointer, Thread *current_thread)
See PipelineCyclerBase::elevate_read().
CycleDataType * elevate_read_stage(int pipeline_stage, const CycleDataType *pointer, Thread *current_thread)
See PipelineCyclerBase::elevate_read_stage().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.