Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2022-03-19 00:32:12 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-03-20 00:05:34 +0300
commitd7ecd4a0f3ba87781edec45b03c99eb9e354608a (patch)
treead6bfa19da94cd3a83047699edc08b3d2d73c943 /source/blender/draw/intern
parentdbf1e7c07f0ffcc475a468e161991e882a999268 (diff)
DRW: Add new texture from pool acquire/release mechanism
This adds a simple and more manageable temp texture behavior. The texture is garanteed to be available only between the acquire/release pair. This makes the same engine able to reuse the textures and even overlap the acquire & release calls.
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r--source/blender/draw/intern/draw_texture_pool.cc73
-rw-r--r--source/blender/draw/intern/draw_texture_pool.h11
2 files changed, 84 insertions, 0 deletions
diff --git a/source/blender/draw/intern/draw_texture_pool.cc b/source/blender/draw/intern/draw_texture_pool.cc
index b54df928418..b36cb5c809e 100644
--- a/source/blender/draw/intern/draw_texture_pool.cc
+++ b/source/blender/draw/intern/draw_texture_pool.cc
@@ -23,6 +23,10 @@ struct DRWTexturePool {
Vector<DRWTexturePoolHandle> handles;
/* Cache last result to avoid linear search each time. */
int last_user_id = -1;
+
+ Vector<GPUTexture *> tmp_tex_pruned;
+ Vector<GPUTexture *> tmp_tex_released;
+ Vector<GPUTexture *> tmp_tex_acquired;
};
DRWTexturePool *DRW_texture_pool_create()
@@ -94,6 +98,68 @@ GPUTexture *DRW_texture_pool_query(
return handle.texture;
}
+GPUTexture *DRW_texture_pool_texture_acquire(DRWTexturePool *pool,
+ int width,
+ int height,
+ eGPUTextureFormat format)
+{
+ GPUTexture *tmp_tex = nullptr;
+ int64_t found_index = 0;
+
+ auto texture_match = [&](GPUTexture *tex) -> bool {
+ /* TODO(@fclem): We could reuse texture using texture views if the formats are compatible. */
+ return (GPU_texture_format(tex) == format) && (GPU_texture_width(tex) == width) &&
+ (GPU_texture_height(tex) == height);
+ };
+
+ /* Search released texture first. */
+ for (auto i : pool->tmp_tex_released.index_range()) {
+ if (texture_match(pool->tmp_tex_released[i])) {
+ tmp_tex = pool->tmp_tex_released[i];
+ found_index = i;
+ break;
+ }
+ }
+
+ if (tmp_tex) {
+ pool->tmp_tex_released.remove_and_reorder(found_index);
+ }
+ else {
+ /* Then search pruned texture. */
+ for (auto i : pool->tmp_tex_pruned.index_range()) {
+ if (texture_match(pool->tmp_tex_pruned[i])) {
+ tmp_tex = pool->tmp_tex_pruned[i];
+ found_index = i;
+ break;
+ }
+ }
+
+ if (tmp_tex) {
+ pool->tmp_tex_pruned.remove_and_reorder(found_index);
+ }
+ }
+
+ if (!tmp_tex) {
+ /* Create a new texture in last resort. */
+ char name[16] = "DRW_tex_pool";
+ if (G.debug & G_DEBUG_GPU) {
+ int texture_id = pool->handles.size();
+ SNPRINTF(name, "DRW_tex_pool_%d", texture_id);
+ }
+ tmp_tex = GPU_texture_create_2d(name, width, height, 1, format, nullptr);
+ }
+
+ pool->tmp_tex_acquired.append(tmp_tex);
+
+ return tmp_tex;
+}
+
+void DRW_texture_pool_texture_release(DRWTexturePool *pool, GPUTexture *tmp_tex)
+{
+ pool->tmp_tex_acquired.remove_first_occurrence_and_reorder(tmp_tex);
+ pool->tmp_tex_released.append(tmp_tex);
+}
+
void DRW_texture_pool_reset(DRWTexturePool *pool)
{
pool->last_user_id = -1;
@@ -117,4 +183,11 @@ void DRW_texture_pool_reset(DRWTexturePool *pool)
pool->handles.remove_and_reorder(i);
}
}
+
+ BLI_assert(pool->tmp_tex_acquired.is_empty());
+ for (GPUTexture *tmp_tex : pool->tmp_tex_pruned) {
+ GPU_texture_free(tmp_tex);
+ }
+ pool->tmp_tex_pruned = pool->tmp_tex_released;
+ pool->tmp_tex_released.clear();
}
diff --git a/source/blender/draw/intern/draw_texture_pool.h b/source/blender/draw/intern/draw_texture_pool.h
index 5a7915e15e7..1c30ea88552 100644
--- a/source/blender/draw/intern/draw_texture_pool.h
+++ b/source/blender/draw/intern/draw_texture_pool.h
@@ -30,6 +30,17 @@ void DRW_texture_pool_free(DRWTexturePool *pool);
GPUTexture *DRW_texture_pool_query(
DRWTexturePool *pool, int width, int height, eGPUTextureFormat format, void *user);
/**
+ * Returns a temporary texture that needs to be released after use. Texture content is undefined.
+ */
+GPUTexture *DRW_texture_pool_texture_acquire(DRWTexturePool *pool,
+ int width,
+ int height,
+ eGPUTextureFormat format);
+/**
+ * Releases a previously acquired texture.
+ */
+void DRW_texture_pool_texture_release(DRWTexturePool *pool, GPUTexture *tmp_tex);
+/**
* Resets the user bits for each texture in the pool and delete unused ones.
*/
void DRW_texture_pool_reset(DRWTexturePool *pool);