Skip to content

Commit 57c38cb

Browse files
authored
Merge pull request #3 from korarei/refactor/geo
Refactor: Update geometry data storage
2 parents 0515ef9 + a2213eb commit 57c38cb

File tree

4 files changed

+102
-84
lines changed

4 files changed

+102
-84
lines changed

dll_src/geo_utils.hpp

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,56 +15,87 @@ class GeoMap {
1515
GeoMap() noexcept = default;
1616
~GeoMap() noexcept = default;
1717

18-
void write(const std::array<std::uint32_t, 2> &key, const Geo &geo) noexcept {
19-
std::uint32_t id, offset;
20-
calc_block_pos(key[1], id, offset);
18+
void resize(std::size_t hash, std::size_t idx, std::size_t num, std::uint32_t mode) noexcept {
19+
if (mode == 0u) {
20+
clear(hash);
21+
return;
22+
}
23+
24+
auto &list = map[hash];
25+
std::size_t size = list.size();
26+
27+
if (num < size) {
28+
std::vector<BlockMap> temp(list.begin(), list.begin() + num);
29+
list.swap(temp);
30+
} else if (num > size) {
31+
list.resize(num);
32+
}
33+
34+
auto &block_map = list[idx];
35+
36+
if (auto it = block_map.find(0); mode == 2u && it != block_map.end() && block_map.size() != 1) {
37+
auto node = block_map.extract(it);
38+
BlockMap{}.swap(block_map);
39+
block_map.insert(std::move(node));
40+
}
41+
42+
return;
43+
}
44+
45+
void write(std::size_t hash, std::size_t idx, std::size_t pos, const Geo &geo) noexcept {
46+
const auto [id, offset] = calc_block_pos(pos);
2147

22-
map[key[0]][id][offset] = geo;
48+
auto it_hash = map.find(hash);
49+
if (it_hash == map.end())
50+
return;
51+
52+
auto &list = it_hash->second;
53+
if (idx >= list.size())
54+
return;
55+
56+
auto &block = list[idx][id];
57+
block[offset] = geo;
58+
return;
2359
}
2460

25-
[[nodiscard]] Geo *read(const std::array<std::uint32_t, 2> &key) noexcept {
26-
std::uint32_t id, offset;
27-
calc_block_pos(key[1], id, offset);
61+
[[nodiscard]] Geo *read(std::size_t hash, std::size_t idx, std::size_t pos) noexcept {
62+
const auto [id, offset] = calc_block_pos(pos);
2863

29-
if (auto block = get_block(key[0], id); block && (*block)[offset].get_flag())
64+
if (auto block = get_block(hash, idx, id); block && (*block)[offset].get_flag())
3065
return &(*block)[offset];
3166
else
3267
return nullptr;
3368
}
3469

3570
void clear() noexcept { MapData{}.swap(map); }
36-
void clear(std::uint32_t match_bits, std::uint32_t mask) noexcept {
37-
std::vector<std::uint32_t> keys_to_erase;
38-
39-
for (auto &[key1, block_map] : map) {
40-
if ((key1 & mask) != match_bits)
41-
continue;
42-
43-
BlockMap{}.swap(block_map);
44-
keys_to_erase.push_back(key1);
45-
}
46-
47-
for (std::uint32_t key1 : keys_to_erase) map.erase(key1);
71+
void clear(std::size_t hash) noexcept {
72+
auto it_hash = map.find(hash);
73+
if (it_hash == map.end())
74+
return;
75+
76+
auto &list = it_hash->second;
77+
std::vector<BlockMap>{}.swap(list);
78+
map.erase(hash);
79+
return;
4880
}
4981

50-
[[nodiscard]] bool has_key0(std::uint32_t key0) const noexcept { return map.find(key0) != map.end(); }
51-
5282
private:
53-
using BlockMap = std::map<std::uint32_t, std::array<Geo, N>>;
54-
using MapData = std::unordered_map<std::uint32_t, BlockMap>;
83+
using BlockMap = std::map<std::size_t, std::array<Geo, N>>;
84+
using MapData = std::unordered_map<std::size_t, std::vector<BlockMap>>;
5585
MapData map{};
5686

57-
void calc_block_pos(std::uint32_t v, std::uint32_t &id, std::uint32_t &offset) const {
58-
id = v / N;
59-
offset = v % N;
60-
}
87+
std::array<std::size_t, 2> calc_block_pos(std::size_t v) const { return {v / N, v % N}; }
88+
89+
std::array<Geo, N> *get_block(std::size_t hash, std::size_t idx, std::size_t id) {
90+
auto it_hash = map.find(hash);
91+
if (it_hash == map.end())
92+
return nullptr;
6193

62-
std::array<Geo, N> *get_block(std::uint32_t key, std::uint32_t id) {
63-
auto it_key = map.find(key);
64-
if (it_key == map.end())
94+
auto &list = it_hash->second;
95+
if (idx >= list.size())
6596
return nullptr;
6697

67-
auto &block_map = it_key->second;
98+
auto &block_map = list[idx];
6899
auto it_block = block_map.find(id);
69100
if (it_block == block_map.end())
70101
return nullptr;

dll_src/main.cpp

Lines changed: 29 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,13 @@
77

88
static auto geo_map = GeoMap<8>();
99

10-
inline static constexpr std::uint32_t
11-
make_key(std::uint32_t obj_id, std::uint32_t obj_idx) noexcept {
12-
std::uint32_t id_t = (obj_idx & 0x3FFFFu) << 14;
13-
std::uint32_t id_b = obj_id & 0x3FFFu;
14-
std::uint32_t id = id_t | id_b;
15-
return id;
16-
}
17-
1810
static void
19-
set_init_geo(std::uint32_t ext, std::uint32_t k) noexcept {
20-
const std::array<std::uint32_t, 2> key{k, 0u};
21-
11+
set_init_geo(std::uint32_t ext, const Input input) noexcept {
2212
int flag = 1;
2313
std::array<Geo, 3> geos{};
2414

25-
for (std::uint32_t i = 0u; i <= ext; ++i) {
26-
if (auto g = geo_map.read({k, i + 1u}))
15+
for (std::size_t i = 0; i <= ext; ++i) {
16+
if (auto g = geo_map.read(input.obj_id, input.obj_idx, i + 1))
2717
geos[i] = *g;
2818
else
2919
flag = 0;
@@ -34,21 +24,21 @@ set_init_geo(std::uint32_t ext, std::uint32_t k) noexcept {
3424

3525
switch (ext) {
3626
case 1u:
37-
geo_map.write(key, geos[0] * 2.0 - geos[1]);
27+
geo_map.write(input.obj_id, input.obj_idx, 0, geos[0] * 2.0 - geos[1]);
3828
return;
3929
case 2u:
40-
geo_map.write(key, geos[0] * 3.0 - geos[1] * 3.0 + geos[2]);
30+
geo_map.write(input.obj_id, input.obj_idx, 0, geos[0] * 3.0 - geos[1] * 3.0 + geos[2]);
4131
return;
4232
default:
4333
return;
4434
}
4535
}
4636

4737
static Delta
48-
calc_delta(const Param &param, Input &input, const std::array<std::uint32_t, 2> &key) noexcept {
38+
calc_delta(const Param &param, Input &input, std::size_t pos) noexcept {
4939
input.tf_curr.set_geo(input.geo_curr);
5040

51-
if (auto geo = param.geo_cache ? geo_map.read(key) : nullptr)
41+
if (auto geo = param.geo_cache ? geo_map.read(input.obj_id, input.obj_idx, pos) : nullptr)
5242
input.tf_prev.set_geo(*geo);
5343
else
5444
input.tf_prev.set_geo(input.geo_curr);
@@ -79,28 +69,22 @@ calc_size(Delta &delta, float amt, const Input &input) noexcept {
7969

8070
static void
8171
cleanup_geo(const Param &param, const Input &input) {
82-
constexpr std::uint32_t mask = 0x3FFFu;
83-
8472
if (!input.is_last[0])
8573
return;
8674

87-
if (param.geo_cache) {
88-
switch (param.geo_ctrl) {
89-
case 1:
90-
if (input.is_last[1])
91-
geo_map.clear(input.obj_id, mask);
92-
break;
93-
case 2:
94-
geo_map.clear();
95-
break;
96-
case 3:
97-
geo_map.clear(input.obj_id, mask);
98-
break;
99-
default:
100-
break;
101-
}
102-
} else if (geo_map.has_key0(input.obj_id)) {
103-
geo_map.clear(input.obj_id, mask);
75+
switch (param.geo_ctrl) {
76+
case 1:
77+
if (input.is_last[1])
78+
geo_map.clear(input.obj_id);
79+
break;
80+
case 2:
81+
geo_map.clear();
82+
break;
83+
case 3:
84+
geo_map.clear(input.obj_id);
85+
break;
86+
default:
87+
break;
10488
}
10589
}
10690

@@ -112,11 +96,12 @@ process_motion_blur(const CParam *c_param, const CInput *c_input, COutput *c_out
11296
const auto param = Param(*c_param);
11397
auto input = Input(*c_input);
11498

115-
std::uint32_t k = make_key(input.obj_id, input.obj_idx);
11699
bool flag = param.is_valid && (param.ext || input.frame);
117100

101+
geo_map.resize(input.obj_id, input.obj_idx, input.obj_num, param.geo_cache);
102+
118103
if (param.geo_cache == 1u || (param.geo_cache == 2u && param.ext && input.frame <= param.ext))
119-
geo_map.write({k, input.frame + 1u}, input.geo_curr);
104+
geo_map.write(input.obj_id, input.obj_idx, input.frame + 1, input.geo_curr);
120105

121106
if (flag) {
122107
const float amt = param.shutter_angle / 360.0f;
@@ -126,9 +111,9 @@ process_motion_blur(const CParam *c_param, const CInput *c_input, COutput *c_out
126111
std::uint32_t smp = 0u;
127112

128113
if (param.geo_cache && !input.frame)
129-
set_init_geo(param.ext, k);
114+
set_init_geo(param.ext, input);
130115

131-
auto delta = calc_delta(param, input, {k, (param.geo_cache == 2u && input.frame) ? 7u : input.frame});
116+
auto delta = calc_delta(param, input, (param.geo_cache == 2u && input.frame) ? 7 : input.frame);
132117

133118
if (delta.is_moved()) {
134119
margin = calc_size(delta, amt, input);
@@ -149,9 +134,10 @@ process_motion_blur(const CParam *c_param, const CInput *c_input, COutput *c_out
149134
*c_output = COutput();
150135
}
151136

152-
if (param.geo_cache == 2u)
153-
if (auto geo = geo_map.read({k, 7u}); !geo || !geo->is_cached(input.frame))
154-
geo_map.write({k, 7u}, input.geo_curr);
137+
if (param.geo_cache == 2u) {
138+
if (auto geo = geo_map.read(input.obj_id, input.obj_idx, 7); !geo || !geo->is_cached(input.frame))
139+
geo_map.write(input.obj_id, input.obj_idx, 7, input.geo_curr);
140+
}
155141

156142
cleanup_geo(param, input);
157143

dll_src/structs.hpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ struct Input {
6969
Vec2<float> res;
7070
Vec2<float> pivot;
7171

72-
std::uint32_t obj_id, obj_idx;
73-
std::uint32_t frame;
72+
std::size_t obj_id, obj_idx, obj_num;
73+
std::size_t frame;
7474
std::array<bool, 2> is_last;
7575

7676
Transform tf_curr, tf_prev;
@@ -79,9 +79,10 @@ struct Input {
7979
constexpr Input(const CInput &c_input) noexcept :
8080
res(c_input.w, c_input.h),
8181
pivot(c_input.px, c_input.py),
82-
obj_id(static_cast<std::uint32_t>(std::clamp(c_input.obj_id, 0, 15000))),
83-
obj_idx(static_cast<std::uint32_t>(c_input.obj_idx)),
84-
frame(static_cast<std::uint32_t>(c_input.frame)),
82+
obj_id(static_cast<std::size_t>(std::max(c_input.obj_id, 0))),
83+
obj_idx(static_cast<std::size_t>(c_input.obj_idx)),
84+
obj_num(static_cast<std::size_t>(c_input.obj_num)),
85+
frame(static_cast<std::size_t>(c_input.frame)),
8586
is_last(c_input.obj_idx == c_input.obj_num - 1, c_input.frame == c_input.total_frame - 1),
8687
tf_curr(std::to_array(c_input.curr)),
8788
tf_prev(std::to_array(c_input.prev)),

dll_src/transform_utils.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414

1515
class Geo {
1616
public:
17-
constexpr Geo() noexcept : flag(false), frame(0u), data{} {}
18-
constexpr Geo(bool flag_, std::uint32_t f, const std::array<float, 6> geo) noexcept :
17+
constexpr Geo() noexcept : flag(false), frame(0), data{} {}
18+
constexpr Geo(bool flag_, std::size_t f, const std::array<float, 6> geo) noexcept :
1919
flag(flag_), frame(f), data(geo) {}
2020

2121
[[nodiscard]] constexpr float &operator[](std::size_t i) noexcept { return data[i]; }
@@ -40,11 +40,11 @@ class Geo {
4040
}
4141

4242
[[nodiscard]] constexpr bool get_flag() const noexcept { return flag; }
43-
[[nodiscard]] constexpr bool is_cached(std::uint32_t f) const noexcept { return flag && f == frame; }
43+
[[nodiscard]] constexpr bool is_cached(std::size_t f) const noexcept { return flag && f == frame; }
4444

4545
private:
4646
bool flag;
47-
std::uint32_t frame;
47+
std::size_t frame;
4848
std::array<float, 6> data;
4949
};
5050

0 commit comments

Comments
 (0)