HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
task.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef HD_TASK_H
25 #define HD_TASK_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/imaging/hd/api.h"
29 #include "pxr/imaging/hd/version.h"
30 
32 
33 #include "pxr/usd/sdf/path.h"
34 #include "pxr/base/tf/hashmap.h"
35 #include "pxr/base/vt/value.h"
36 #include "pxr/base/vt/dictionary.h"
37 
38 #include <vector>
39 #include <unordered_map>
40 #include <hboost/shared_ptr.hpp>
41 
43 
44 
45 typedef hboost::shared_ptr<class HdTask> HdTaskSharedPtr;
46 typedef std::vector<HdTaskSharedPtr> HdTaskSharedPtrVector;
47 
48 typedef hboost::shared_ptr<class HdSceneTask> HdSceneTaskSharedPtr;
49 typedef std::vector<HdSceneTaskSharedPtr> HdSceneTaskSharedPtrVector;
50 
51 // We want to use token as a key not std::string, so use an unordered_map over
52 // VtDictionary
53 typedef std::unordered_map<TfToken, VtValue, TfToken::HashFunctor>
55 
56 class HdTask {
57 public:
58  /// Construct a new task.
59  /// If the task is going to be added to the render index, id
60  /// should be an absolute scene path.
61  /// If the task isn't going to be added to the render index
62  /// an empty path should be used for id.
63  HD_API
64  HdTask(SdfPath const& id);
65 
66  HD_API
67  virtual ~HdTask();
68 
69  /// Sync Phase: Obtain task state from Scene delegate based on
70  /// change processing.
71  ///
72  /// This function might only be called if dirtyBits is not 0,
73  /// so isn't guaranteed to be called every time HdEngine::Execute() is run
74  /// with this task.
75  ///
76  /// However, this is the only time when the task should communicate with
77  /// with the scene delegate responsible for the task and should be
78  /// used to pull all changed data. As outside the Sync phase, the scene
79  /// delegate may not have the data available.
80  ///
81  /// Tasks maybe synced in parallel and out of order.
82  ///
83  /// The ctx parameter is present for legacy reason and shouldn't be used
84  /// once the task has moved to using the 3-phase mechanism.
85  ///
86  /// After a task has been synced, it is expected that it produces a
87  /// collection identifying the prims that are important to the task. This
88  /// collection is used to filter the prims in the scene so only the
89  /// Relevant prims get synced.
90  ///
91  /// Note about inter-prim dependencies:
92  /// Quite often tasks need to access other prims, such as a camera prim
93  /// for example. These other prims have not been synced yet when sync is
94  /// called. Therefore, it is not recommended to access these prims during
95  /// the sync phase. Instead a task should store the path to the prim
96  /// to be resolved to an actual prim during the "prepare" phase.
97 
98  virtual void Sync(HdSceneDelegate* delegate,
99  HdTaskContext* ctx,
100  HdDirtyBits* dirtyBits) = 0;
101 
102  /// Prepare Phase: Resolve bindings and manage resources.
103  ///
104  /// The Prepare phase happens before the Data Commit phase.
105  /// All tasks in the task list get called for every execute.
106  /// At this time all Tasks and other prims have completed the phase synced.
107  ///
108  /// This is an opportunity for the task to pull data from other prims
109  /// (such as a camera prim), but accessing the render index.
110  ///
111  /// The task can also use the phase to create, register and update temporary
112  /// resources with the resource registry or other render delegate
113  /// specific mechanism.
114  ///
115  /// Tasks are always "Prepared" in execution order.
116  ///
117  /// Inter-task communication is achievable via the task context.
118  /// The same task context is used for the prepare and execution phases.
119  /// Data in the task context isn't guaranteed to persist across calls
120  /// to HdEngine::Execute().
121  virtual void Prepare(HdTaskContext* ctx,
122  HdRenderIndex* renderIndex) = 0;
123 
124  /// Execute Phase: Runs the task.
125  ///
126  /// The execution phase should trigger render delegate processing,
127  /// such as issuing draw commands.
128  ///
129  /// Task execution is non-parallel and ordered.
130  ///
131  /// The task context is the same as used by the prepare step and is used
132  /// for inter-task communication.
133  virtual void Execute(HdTaskContext* ctx) = 0;
134 
135  /// Render Tag Gather.
136  ///
137  /// Is called during the Sync phase after the task has been sync'ed.
138  ///
139  /// The task should return the render tags it wants to be appended to the
140  /// active set.
141  ///
142  /// Hydra prims are marked up with a render tag and only prims
143  /// marked with the render tags in the current active set are Sync'ed.
144  ///
145  /// Hydra's core will combine the sets from each task and deduplicated the
146  /// result. So tasks don't need to co-ordinate with each other to
147  /// Optimize the set.
148  ///
149  /// For those tasks that use HdRenderPass, is the typically the set passed
150  /// to HdRenderPass's Execute method.
151  ///
152  /// The default implementation returns an empty set
153  HD_API
154  virtual const TfTokenVector &GetRenderTags() const;
155 
156  SdfPath const& GetId() const { return _id; }
157 
158  /// Returns the minimal set of dirty bits to place in the
159  /// change tracker for use in the first sync of this prim.
160  /// Typically this would be all dirty bits.
161  HD_API
162  virtual HdDirtyBits GetInitialDirtyBitsMask() const;
163 
164 
165 protected:
166  /// Extracts a typed value out of the task context at the given id.
167  /// If the id is missing or of the wrong type, the code will
168  /// throw a verify error, return false and outValue will be unmodified.
169  /// in case of success, the return value is true and the value is
170  /// copied into outValue.
171  ///
172  /// outValue must not be null.
173  template <class T>
174  static bool _GetTaskContextData(HdTaskContext const* ctx,
175  TfToken const& id,
176  T* outValue);
177 
178  /// Extracts a typed value out of the task context at the given id.
179  /// If the id is missing or of the wrong type, the code will
180  /// throw a verify error, return false and outValue will be unmodified.
181  /// in case of success, the return value is true and the value is
182  /// copied into outValue.
183  ///
184  /// outValue must not be null.
185  template <class T>
186  bool _GetTaskParams(HdSceneDelegate* delegate,
187  T* outValue);
188 
189  HD_API
191 
192 private:
193  SdfPath _id;
194 
195  HdTask() = delete;
196  HdTask(const HdTask &) = delete;
197  HdTask &operator =(const HdTask &) = delete;
198 };
199 
200 // Inline template body
201 template <class T>
202 bool
204  TfToken const& id,
205  T* outValue)
206 {
207  TF_DEV_AXIOM(outValue != nullptr);
208 
209  if (!ctx) {
210  return false;
211  }
212 
213  HdTaskContext::const_iterator valueIt = ctx->find(id);
214  if (valueIt == ctx->cend()) {
215  TF_CODING_ERROR("Token %s missing from task context", id.GetText());
216  return false;
217  }
218 
219  const VtValue &valueVt = (valueIt->second);
220  if (!valueVt.IsHolding<T>()) {
221  TF_CODING_ERROR("Token %s in task context is of mismatched type",
222  id.GetText());
223  return false;
224  }
225 
226  *outValue = valueVt.UncheckedGet<T>();
227 
228  return true;
229 }
230 
231 template <class T>
232 bool
234  T* outValue)
235 {
236  TF_DEV_AXIOM(outValue != nullptr);
237 
238  SdfPath const& taskId = GetId();
239 
240  VtValue valueVt = delegate->Get(taskId, HdTokens->params);
241  if (!valueVt.IsHolding<T>()) {
242  TF_CODING_ERROR("Task params for %s is of unexpected type",
243  taskId.GetText());
244  return false;
245  }
246 
247  *outValue = valueVt.UncheckedGet<T>();
248 
249  return true;
250 }
251 
253 
254 #endif // HD_TASK_H
SDF_API const char * GetText() const
Returns the string representation of this path as a c string.
SdfPath const & GetId() const
Definition: task.h:156
T const & UncheckedGet() const
Definition: value.h:836
PXR_NAMESPACE_OPEN_SCOPE typedef hboost::shared_ptr< class HdTask > HdTaskSharedPtr
Definition: task.h:45
#define TF_CODING_ERROR
#define HD_API
Definition: api.h:40
std::unordered_map< TfToken, VtValue, TfToken::HashFunctor > HdTaskContext
Definition: renderIndex.h:76
std::unordered_map< TfToken, VtValue, TfToken::HashFunctor > HdTaskContext
Definition: task.h:54
virtual HD_API ~HdTask()
#define TF_DEV_AXIOM(cond)
Definition: token.h:89
hboost::shared_ptr< class HdSceneTask > HdSceneTaskSharedPtr
Definition: task.h:48
virtual HD_API HdDirtyBits GetInitialDirtyBitsMask() const
std::vector< HdTaskSharedPtr > HdTaskSharedPtrVector
Definition: task.h:46
PXR_NAMESPACE_OPEN_SCOPE typedef uint32_t HdDirtyBits
Definition: types.h:41
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:438
virtual void Prepare(HdTaskContext *ctx, HdRenderIndex *renderIndex)=0
virtual void Sync(HdSceneDelegate *delegate, HdTaskContext *ctx, HdDirtyBits *dirtyBits)=0
Definition: task.h:56
Definition: path.h:287
HD_API TfTokenVector _GetTaskRenderTags(HdSceneDelegate *delegate)
virtual HD_API const TfTokenVector & GetRenderTags() const
virtual void Execute(HdTaskContext *ctx)=0
virtual HD_API VtValue Get(SdfPath const &id, TfToken const &key)
Returns a named value.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1245
bool IsHolding() const
Definition: value.h:808
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:83
bool _GetTaskParams(HdSceneDelegate *delegate, T *outValue)
Definition: task.h:233
std::vector< HdSceneTaskSharedPtr > HdSceneTaskSharedPtrVector
Definition: task.h:49
Definition: value.h:182
static bool _GetTaskContextData(HdTaskContext const *ctx, TfToken const &id, T *outValue)
Definition: task.h:203