Panda3D
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  */
45 template<class CycleDataType>
47 public:
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
71 private:
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.