Blender V4.3
cached_texture.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include <cstdint>
6#include <memory>
7
8#include "BLI_array.hh"
9#include "BLI_hash.hh"
10#include "BLI_index_range.hh"
11#include "BLI_math_vector.h"
13#include "BLI_task.hh"
14
15#include "GPU_texture.hh"
16
17#include "BKE_image.hh"
18#include "BKE_texture.h"
19
20#include "DNA_ID.h"
21#include "DNA_scene_types.h"
22#include "DNA_texture_types.h"
23
24#include "RE_texture.h"
25
26#include "COM_cached_texture.hh"
27#include "COM_context.hh"
28#include "COM_result.hh"
29
31
32/* --------------------------------------------------------------------
33 * Cached Texture Key.
34 */
35
37 : size(size), offset(offset), scale(scale)
38{
39}
40
42{
43 return get_default_hash(size, offset, scale);
44}
45
47{
48 return a.size == b.size && a.offset == b.offset && a.scale == b.scale;
49}
50
51/* --------------------------------------------------------------------
52 * Cached Texture.
53 */
54
56 Tex *texture,
57 bool use_color_management,
58 int2 size,
59 float3 offset,
60 float3 scale)
61{
62 ImagePool *image_pool = BKE_image_pool_new();
63 BKE_texture_fetch_images_for_pool(texture, image_pool);
64
65 Array<float4> color_pixels(size.x * size.y);
66 Array<float> value_pixels(size.x * size.y);
67 threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) {
68 for (const int64_t y : sub_y_range) {
69 for (const int64_t x : IndexRange(size.x)) {
70 /* Compute the coordinates in the [-1, 1] range and add 0.5 to evaluate the texture at the
71 * center of pixels in case it was interpolated. */
72 const float2 pixel_coordinates = ((float2(x, y) + 0.5f) / float2(size)) * 2.0f - 1.0f;
73 /* Note that it is expected that the offset is scaled by the scale. */
74 const float3 coordinates = (float3(pixel_coordinates, 0.0f) + offset) * scale;
75
76 TexResult texture_result;
77 const int result_type = multitex_ext_safe(
78 texture, coordinates, &texture_result, image_pool, use_color_management, false);
79
80 float4 color = float4(texture_result.trgba);
81 color.w = texture_result.talpha ? color.w : texture_result.tin;
82 if (!(result_type & TEX_RGB)) {
83 copy_v3_fl(color, color.w);
84 }
85
86 color_pixels[y * size.x + x] = color;
87 value_pixels[y * size.x + x] = color.w;
88 }
89 }
90 });
91
92 BKE_image_pool_free(image_pool);
93
94 color_texture_ = GPU_texture_create_2d(
95 "Cached Color Texture",
96 size.x,
97 size.y,
98 1,
99 Result::gpu_texture_format(ResultType::Color, context.get_precision()),
101 *color_pixels.data());
102
103 value_texture_ = GPU_texture_create_2d(
104 "Cached Value Texture",
105 size.x,
106 size.y,
107 1,
108 Result::gpu_texture_format(ResultType::Float, context.get_precision()),
110 value_pixels.data());
111}
112
113CachedTexture::~CachedTexture()
114{
115 GPU_texture_free(color_texture_);
116 GPU_texture_free(value_texture_);
117}
118
119GPUTexture *CachedTexture::color_texture()
120{
121 return color_texture_;
122}
123
124GPUTexture *CachedTexture::value_texture()
125{
126 return value_texture_;
127}
128
129/* --------------------------------------------------------------------
130 * Cached Texture Container.
131 */
132
133void CachedTextureContainer::reset()
134{
135 /* First, delete all cached textures that are no longer needed. */
136 for (auto &cached_textures_for_id : map_.values()) {
137 cached_textures_for_id.remove_if([](auto item) { return !item.value->needed; });
138 }
139 map_.remove_if([](auto item) { return item.value.is_empty(); });
140
141 /* Second, reset the needed status of the remaining cached textures to false to ready them to
142 * track their needed status for the next evaluation. */
143 for (auto &cached_textures_for_id : map_.values()) {
144 for (auto &value : cached_textures_for_id.values()) {
145 value->needed = false;
146 }
147 }
148}
149
150CachedTexture &CachedTextureContainer::get(Context &context,
151 Tex *texture,
152 bool use_color_management,
153 int2 size,
154 float3 offset,
155 float3 scale)
156{
157 const CachedTextureKey key(size, offset, scale);
158
159 const std::string library_key = texture->id.lib ? texture->id.lib->id.name : "";
160 const std::string id_key = std::string(texture->id.name) + library_key;
161 auto &cached_textures_for_id = map_.lookup_or_add_default(id_key);
162
163 /* Invalidate the cache for that texture ID if it was changed and reset the recalculate flag. */
164 if (context.query_id_recalc_flag(reinterpret_cast<ID *>(texture)) & ID_RECALC_ALL) {
165 cached_textures_for_id.clear();
166 }
167
168 auto &cached_texture = *cached_textures_for_id.lookup_or_add_cb(key, [&]() {
169 return std::make_unique<CachedTexture>(
170 context, texture, use_color_management, size, offset, scale);
171 });
172
173 cached_texture.needed = true;
174 return cached_texture;
175}
176
177} // namespace blender::realtime_compositor
void BKE_image_pool_free(ImagePool *pool)
ImagePool * BKE_image_pool_new(void)
void BKE_texture_fetch_images_for_pool(struct Tex *texture, struct ImagePool *pool)
Definition texture.cc:745
ID and Library types, which are fundamental for SDNA.
@ ID_RECALC_ALL
Definition DNA_ID.h:1155
GPUTexture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_free(GPUTexture *texture)
@ GPU_TEXTURE_USAGE_SHADER_READ
CachedTextureKey(int2 size, float3 offset, float3 scale)
CachedTexture(Context &context, Tex *texture, bool use_color_management, int2 size, float3 offset, float3 scale)
static eGPUTextureFormat gpu_texture_format(ResultType type, ResultPrecision precision)
Definition result.cc:29
local_group_size(16, 16) .push_constant(Type b
bool operator==(const BokehKernelKey &a, const BokehKernelKey &b)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:95
uint64_t get_default_hash(const T &v)
Definition BLI_hash.hh:219
unsigned __int64 uint64_t
Definition stdint.h:90
Definition DNA_ID.h:413