blob: 470e9f225b4cd764e97fe03da9402217eab4e219 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2022 Blender Foundation. */
/** \file
* \ingroup draw_engine
*/
#pragma once
#include "BLI_vector.hh"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
struct FloatImageBuffer {
ImBuf *source_buffer = nullptr;
ImBuf *float_buffer = nullptr;
bool is_used = true;
FloatImageBuffer(ImBuf *source_buffer, ImBuf *float_buffer)
: source_buffer(source_buffer), float_buffer(float_buffer)
{
}
FloatImageBuffer(FloatImageBuffer &&other) noexcept
{
source_buffer = other.source_buffer;
float_buffer = other.float_buffer;
is_used = other.is_used;
other.source_buffer = nullptr;
other.float_buffer = nullptr;
}
virtual ~FloatImageBuffer()
{
IMB_freeImBuf(float_buffer);
float_buffer = nullptr;
source_buffer = nullptr;
}
FloatImageBuffer &operator=(FloatImageBuffer &&other) noexcept
{
this->source_buffer = other.source_buffer;
this->float_buffer = other.float_buffer;
is_used = other.is_used;
other.source_buffer = nullptr;
other.float_buffer = nullptr;
return *this;
}
};
struct FloatBufferCache {
private:
blender::Vector<FloatImageBuffer> cache_;
public:
ImBuf *ensure_float_buffer(ImBuf *image_buffer)
{
/* Check if we can use the float buffer of the given image_buffer. */
if (image_buffer->rect_float != nullptr) {
return image_buffer;
}
/* Do we have a cached float buffer. */
for (FloatImageBuffer &item : cache_) {
if (item.source_buffer == image_buffer) {
item.is_used = true;
return item.float_buffer;
}
}
/* Generate a new float buffer. */
IMB_float_from_rect(image_buffer);
ImBuf *new_imbuf = IMB_allocImBuf(image_buffer->x, image_buffer->y, image_buffer->planes, 0);
new_imbuf->rect_float = image_buffer->rect_float;
new_imbuf->flags |= IB_rectfloat;
new_imbuf->mall |= IB_rectfloat;
image_buffer->rect_float = nullptr;
image_buffer->flags &= ~IB_rectfloat;
image_buffer->mall &= ~IB_rectfloat;
cache_.append(FloatImageBuffer(image_buffer, new_imbuf));
return new_imbuf;
}
void reset_usage_flags()
{
for (FloatImageBuffer &buffer : cache_) {
buffer.is_used = false;
}
}
void mark_used(const ImBuf *image_buffer)
{
for (FloatImageBuffer &item : cache_) {
if (item.source_buffer == image_buffer) {
item.is_used = true;
return;
}
}
}
void remove_unused_buffers()
{
for (int64_t i = cache_.size() - 1; i >= 0; i--) {
if (!cache_[i].is_used) {
cache_.remove_and_reorder(i);
}
}
}
void clear()
{
cache_.clear();
}
};
|