Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
GridScheduler.h
Go to the documentation of this file.
1#pragma once
2
4#include "Math/math.h"
5#include "Math/constant.h"
6
7#include <Common/assertion.h>
8
9#include <algorithm>
10#include <cmath>
11
12namespace ph
13{
14
20{
21public:
22 enum class EOrigin
23 {
28 };
29
31
33 std::size_t numWorkers,
34 const WorkUnit& totalWorkUnit);
35
37 std::size_t numWorkers,
38 const WorkUnit& totalWorkUnit,
39 const math::Vector2S& numCells);
40
42 std::size_t numWorkers,
43 const WorkUnit& totalWorkUnit,
44 const math::Vector2S& numCells,
45 EOrigin origin,
46 std::size_t prioriAxis);
47
48private:
49 math::Vector2S m_numCells;
50 math::Vector2S m_currentCell;
51 EOrigin m_origin;
52 std::size_t m_prioriAxis;
53
54 void scheduleOne(WorkUnit* out_workUnit) override;
55};
56
57// In-header Implementations:
58
60
62
63 , m_numCells (0)
64 , m_currentCell(0, 0)
65 , m_origin (EOrigin::LowerLeft)
66 , m_prioriAxis (math::constant::X_AXIS)
67{}
68
70 const std::size_t numWorkers,
71 const WorkUnit& totalWorkUnit) :
72
74 numWorkers,
75 totalWorkUnit,
76 math::Vector2S(
77 static_cast<std::size_t>(
78 std::ceil(math::fast_sqrt(numWorkers * static_cast<float>(totalWorkUnit.getAspectRatio())))),
79 static_cast<std::size_t>(
80 std::ceil(math::fast_sqrt(numWorkers / static_cast<float>(totalWorkUnit.getAspectRatio()))))))
81{}
82
84 const std::size_t numWorkers,
85 const WorkUnit& totalWorkUnit,
86 const math::Vector2S& numCells) :
87
89 numWorkers,
90 totalWorkUnit,
91 numCells,
92 EOrigin::LowerLeft,
93 math::constant::X_AXIS)// default to X-first as it is likely more cache friendly
94{}
95
97 const std::size_t numWorkers,
98 const WorkUnit& totalWorkUnit,
99 const math::Vector2S& numCells,
100 const EOrigin origin,
101 const std::size_t prioriAxis)
102
103 : WorkScheduler(numWorkers, totalWorkUnit)
104
105 , m_numCells (numCells)
106 , m_currentCell(0, 0)
107 , m_origin (origin)
108 , m_prioriAxis (prioriAxis)
109{}
110
111inline void GridScheduler::scheduleOne(WorkUnit* const out_workUnit)
112{
113 PH_ASSERT(out_workUnit);
114
115 // Cell coordinates are always in the canonical Cartesian space. Mapping
116 // only performed on divided ranges.
117
118 if(m_currentCell.x() < m_numCells.x() && m_currentCell.y() < m_numCells.y())
119 {
120 const std::size_t totalWidth = m_totalWorkUnit.getRegion().getWidth();
121 const std::size_t totalHeight = m_totalWorkUnit.getRegion().getHeight();
122
123 auto sideRangeX = math::ith_evenly_divided_range(
124 m_currentCell.x(), totalWidth, m_numCells.x());
125 if(m_origin == EOrigin::LowerRight || m_origin == EOrigin::UpperRight)
126 {
127 const auto size = sideRangeX.second - sideRangeX.first;
128 sideRangeX.first = totalWidth - sideRangeX.second;
129 sideRangeX.second = sideRangeX.first + size;
130 }
131
132 auto sideRangeY = math::ith_evenly_divided_range(
133 m_currentCell.y(), totalHeight, m_numCells.y());
134 if(m_origin == EOrigin::UpperLeft || m_origin == EOrigin::UpperRight)
135 {
136 const auto size = sideRangeY.second - sideRangeY.first;
137 sideRangeY.first = totalHeight - sideRangeY.second;
138 sideRangeY.second = sideRangeY.first + size;
139 }
140
141 *out_workUnit = WorkUnit(
142 Region(
143 math::TVector2<int64>(math::Vector2S(sideRangeX.first, sideRangeY.first)) + m_totalWorkUnit.getRegion().getMinVertex(),
144 math::TVector2<int64>(math::Vector2S(sideRangeX.second, sideRangeY.second)) + m_totalWorkUnit.getRegion().getMinVertex()),
146
147 if(m_prioriAxis == math::constant::X_AXIS)
148 {
149 ++m_currentCell.x();
150 if(m_currentCell.x() == m_numCells.x())
151 {
152 m_currentCell.x() = 0;
153 ++m_currentCell.y();
154 }
155 }
156 else
157 {
158 ++m_currentCell.y();
159 if(m_currentCell.y() == m_numCells.y())
160 {
161 m_currentCell.y() = 0;
162 ++m_currentCell.x();
163 }
164 }
165 }
166 else
167 {
168 *out_workUnit = WorkUnit();
169 }
170}
171
172}// end namespace ph
Definition GridScheduler.h:20
EOrigin
Definition GridScheduler.h:23
GridScheduler()
Definition GridScheduler.h:59
A manager that distributes a fixed amount of work to workers.
Definition WorkScheduler.h:21
WorkUnit m_totalWorkUnit
Definition WorkScheduler.h:55
Represents some amount of work.
Definition WorkUnit.h:17
Region getRegion() const
Definition WorkUnit.h:72
std::size_t getDepth() const
Definition WorkUnit.h:77
T getHeight() const
Definition TAABB2D.ipp:144
T getWidth() const
Definition TAABB2D.ipp:138
const TVector2< T > & getMinVertex() const
Definition TAABB2D.ipp:120
T & x()
Definition TVector2.ipp:38
T & y()
Definition TVector2.ipp:44
Miscellaneous math utilities.
constexpr std::size_t X_AXIS
Definition constant.h:90
std::pair< std::size_t, std::size_t > ith_evenly_divided_range(const std::size_t rangeIndex, const std::size_t totalSize, const std::size_t numDivisions)
Gets the i-th evenly divided range.
Definition math.h:379
TVector2< std::size_t > Vector2S
Definition math_fwd.h:48
float fast_sqrt(const float x)
Computes sqrt(x) in a fast but approximative way.
Definition math.h:436
The root for all renderer implementations.
Definition EEngineProject.h:6
math::TAABB2D< int64 > Region
Definition Region.h:8
Definition TAABB2D.h:96