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