[Bf-blender-cvs] [ae68c53b159] temp-T98375-share-gpu-textures: Base implementation to share textures between mutliple image data-blocks.
Jeroen Bakker
noreply at git.blender.org
Fri May 27 15:09:13 CEST 2022
Commit: ae68c53b15912669f432b93bfd6edbe4d043a897
Author: Jeroen Bakker
Date: Fri May 27 14:46:05 2022 +0200
Branches: temp-T98375-share-gpu-textures
https://developer.blender.org/rBae68c53b15912669f432b93bfd6edbe4d043a897
Base implementation to share textures between mutliple image data-blocks.
===================================================================
M source/blender/blenkernel/BKE_image.h
M source/blender/blenkernel/intern/image.cc
M source/blender/blenkernel/intern/image_gpu.cc
M source/blender/editors/sculpt_paint/paint_image.cc
M source/blender/makesdna/DNA_image_types.h
M source/blender/makesrna/intern/rna_image.c
M source/blender/makesrna/intern/rna_image_api.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index b6607a92c14..8f617cce7f7 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -325,11 +325,6 @@ bool BKE_image_scale(struct Image *image, int width, int height);
*/
bool BKE_image_has_alpha(struct Image *image);
-/**
- * Check if texture has GPU texture code.
- */
-bool BKE_image_has_opengl_texture(struct Image *ima);
-
/**
* Get tile index for tiled images.
*/
@@ -525,7 +520,7 @@ void BKE_image_update_gputexture_delayed(struct Image *ima,
* temporary disabling/enabling mipmapping on all images for quick texture
* updates with glTexSubImage2D. images that didn't change don't have to be re-uploaded to OpenGL.
*/
-void BKE_image_paint_set_mipmap(struct Main *bmain, bool mipmap);
+void BKE_image_paint_set_mipmap(bool mipmap);
/**
* Delayed free of OpenGL buffers by main thread.
diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc
index bc21e706d1e..bf00eb7ab7a 100644
--- a/source/blender/blenkernel/intern/image.cc
+++ b/source/blender/blenkernel/intern/image.cc
@@ -180,12 +180,6 @@ static void image_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
BLI_duplicatelist(&image_dst->tiles, &image_src->tiles);
- for (int eye = 0; eye < 2; eye++) {
- for (int i = 0; i < TEXTARGET_COUNT; i++) {
- image_dst->gputexture[i][eye] = nullptr;
- }
- }
-
if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
BKE_previewimg_id_copy(&image_dst->id, &image_src->id);
}
@@ -234,6 +228,7 @@ static void image_foreach_cache(ID *id,
key.offset_in_ID = offsetof(Image, cache);
function_callback(id, &key, (void **)&image->cache, 0, user_data);
+#if 0
auto gputexture_offset = [image](int target, int eye) {
constexpr size_t base_offset = offsetof(Image, gputexture);
struct GPUTexture **first = &image->gputexture[0][0];
@@ -241,6 +236,7 @@ static void image_foreach_cache(ID *id,
return base_offset + array_offset;
};
+// TODO(jbakker): need to check how this is actually used not the GPU textures are shared we might need to reinvalidate this.
for (int eye = 0; eye < 2; eye++) {
for (int a = 0; a < TEXTARGET_COUNT; a++) {
GPUTexture *texture = image->gputexture[a][eye];
@@ -251,6 +247,7 @@ static void image_foreach_cache(ID *id,
function_callback(id, &key, (void **)&image->gputexture[a][eye], 0, user_data);
}
}
+#endif
key.offset_in_ID = offsetof(Image, rr);
function_callback(id, &key, (void **)&image->rr, 0, user_data);
@@ -328,11 +325,6 @@ static void image_blend_write(BlendWriter *writer, ID *id, const void *id_addres
BLI_listbase_clear(&ima->anims);
ima->runtime.partial_update_register = nullptr;
ima->runtime.partial_update_user = nullptr;
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 2; j++) {
- ima->gputexture[i][j] = nullptr;
- }
- }
ImagePackedFile *imapf;
@@ -773,18 +765,6 @@ bool BKE_image_scale(Image *image, int width, int height)
return (ibuf != nullptr);
}
-bool BKE_image_has_opengl_texture(Image *ima)
-{
- for (int eye = 0; eye < 2; eye++) {
- for (int i = 0; i < TEXTARGET_COUNT; i++) {
- if (ima->gputexture[i][eye] != nullptr) {
- return true;
- }
- }
- }
- return false;
-}
-
static int image_get_tile_number_from_iuser(Image *ima, const ImageUser *iuser)
{
BLI_assert(ima != nullptr && ima->tiles.first);
@@ -2847,20 +2827,6 @@ void BKE_image_init_imageuser(Image *ima, ImageUser *iuser)
static void image_free_tile(Image *ima, ImageTile *tile)
{
- for (int i = 0; i < TEXTARGET_COUNT; i++) {
- /* Only two textures depends on all tiles, so if this is a secondary tile we can keep the other
- * two. */
- if (tile != ima->tiles.first && !(ELEM(i, TEXTARGET_2D_ARRAY, TEXTARGET_TILE_MAPPING))) {
- continue;
- }
-
- for (int eye = 0; eye < 2; eye++) {
- if (ima->gputexture[i][eye] != nullptr) {
- GPU_texture_free(ima->gputexture[i][eye]);
- ima->gputexture[i][eye] = nullptr;
- }
- }
- }
BKE_image_partial_update_mark_full_update(ima);
if (BKE_image_is_multiview(ima)) {
@@ -3196,17 +3162,6 @@ ImageTile *BKE_image_add_tile(struct Image *ima, int tile_number, const char *la
BLI_strncpy(tile->label, label, sizeof(tile->label));
}
- for (int eye = 0; eye < 2; eye++) {
- /* Reallocate GPU tile array. */
- if (ima->gputexture[TEXTARGET_2D_ARRAY][eye] != nullptr) {
- GPU_texture_free(ima->gputexture[TEXTARGET_2D_ARRAY][eye]);
- ima->gputexture[TEXTARGET_2D_ARRAY][eye] = nullptr;
- }
- if (ima->gputexture[TEXTARGET_TILE_MAPPING][eye] != nullptr) {
- GPU_texture_free(ima->gputexture[TEXTARGET_TILE_MAPPING][eye]);
- ima->gputexture[TEXTARGET_TILE_MAPPING][eye] = nullptr;
- }
- }
BKE_image_partial_update_mark_full_update(ima);
return tile;
@@ -3259,17 +3214,6 @@ void BKE_image_reassign_tile(struct Image *ima, ImageTile *tile, int new_tile_nu
IMB_freeImBuf(ibuf);
}
- for (int eye = 0; eye < 2; eye++) {
- /* Reallocate GPU tile array. */
- if (ima->gputexture[TEXTARGET_2D_ARRAY][eye] != nullptr) {
- GPU_texture_free(ima->gputexture[TEXTARGET_2D_ARRAY][eye]);
- ima->gputexture[TEXTARGET_2D_ARRAY][eye] = nullptr;
- }
- if (ima->gputexture[TEXTARGET_TILE_MAPPING][eye] != nullptr) {
- GPU_texture_free(ima->gputexture[TEXTARGET_TILE_MAPPING][eye]);
- ima->gputexture[TEXTARGET_TILE_MAPPING][eye] = nullptr;
- }
- }
BKE_image_partial_update_mark_full_update(ima);
}
diff --git a/source/blender/blenkernel/intern/image_gpu.cc b/source/blender/blenkernel/intern/image_gpu.cc
index bed79a318e8..3e0e0414afa 100644
--- a/source/blender/blenkernel/intern/image_gpu.cc
+++ b/source/blender/blenkernel/intern/image_gpu.cc
@@ -11,7 +11,9 @@
#include "BLI_boxpack_2d.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
+#include "BLI_map.hh"
#include "BLI_threads.h"
+#include "BLI_utility_mixins.hh"
#include "DNA_image_types.h"
#include "DNA_userdef_types.h"
@@ -33,13 +35,133 @@
using namespace blender::bke::image::partial_update;
+namespace blender::bke::image::gpu {
+struct ImageGPUTextureStore {
+ class Entry : NonCopyable {
+ public:
+ GPUTexture *gputextures[TEXTARGET_COUNT][2];
+ struct {
+ bool in_use : 1;
+ } flags;
+
+ Entry()
+ {
+ for (int target = 0; target < TEXTARGET_COUNT; target++) {
+ for (int eye = 0; eye < 2; eye++) {
+ gputextures[target][eye] = nullptr;
+ }
+ }
+ }
+
+ Entry(Entry &&other)
+ {
+ for (int target = 0; target < TEXTARGET_COUNT; target++) {
+ for (int eye = 0; eye < 2; eye++) {
+ gputextures[target][eye] = other.gputextures[target][eye];
+ other.gputextures[target][eye] = nullptr;
+ }
+ }
+ flags.in_use = other.flags.in_use;
+ };
+
+ virtual ~Entry()
+ {
+ clear();
+ }
+
+ void set_mipmap(const bool mipmap)
+ {
+ for (int eye = 0; eye < 2; eye++) {
+ if (gputextures[TEXTARGET_2D][eye]) {
+ GPU_texture_mipmap_mode(gputextures[TEXTARGET_2D][eye], mipmap, true);
+ }
+ if (gputextures[TEXTARGET_2D_ARRAY][eye]) {
+ GPU_texture_mipmap_mode(gputextures[TEXTARGET_2D_ARRAY][eye], mipmap, true);
+ }
+ }
+ }
+
+ void tag_used()
+ {
+ flags.in_use = true;
+ }
+
+ void clear()
+ {
+ for (int target = 0; target < TEXTARGET_COUNT; target++) {
+ for (int eye = 0; eye < 2; eye++) {
+ GPU_TEXTURE_FREE_SAFE(gputextures[target][eye]);
+ }
+ }
+ }
+ };
+
+ using Entries = Map<std::string, Entry>;
+
+ Entries entries;
+
+ void reset_usage()
+ {
+ for (Entry &entry : entries.values()) {
+ entry.flags.in_use = false;
+ }
+ }
+
+ void remove_unused()
+ {
+ for (auto it : entries.items()) {
+ if (it.value.flags.in_use) {
+ continue;
+ }
+ entries.remove(it.key);
+ }
+ }
+
+ void set_mipmap(const bool mipmap)
+ {
+ for (Entry &entry : entries.values()) {
+ entry.set_mipmap(mipmap);
+ }
+ }
+
+ void clear()
+ {
+ entries.clear();
+ }
+
+ std::string create_key(const Image &image) const
+ {
+ std::stringstream result;
+ result << "ID:" << image.id.name;
+ return result.str();
+ }
+
+ Entry &operator[](Image &image)
+ {
+ std::string key = create_key(image);
+ return entries.lookup_or_add_default(key);
+ }
+};
+
+static ImageGPUTextureStore g_texture_store;
+
+} // namespace blender::bke::image::gpu
+
extern "C" {
+using namespace blender::bke::image::gpu;
+
/* Prototypes. */
static void gpu_free_unused_buffers();
static void image_free_gpu(Image *ima, const bool immediate);
-static void image_update_gputexture_ex(
- Image *ima, ImageTile *tile, ImBuf *ibuf, int x, int y, int w, int h);
+static void image_update_gputexture_ex(Image *ima,
+ ImageGPUTextureStore::Entry &entry,
+ ImageTile *tile,
+ ImBuf *ibuf,
+ int x,
+ int y,
+ int w,
+ int h);
bool BKE_image_has_gpu_texture_premultiplied_alpha(Image *image, ImBuf *ibuf)
{
@@ -77,9 +199,11 @@ static int smaller_power_of_2_limit(int num)
return power_of_2_min_i(GPU_texture_size_with_limit(num));
}
-static GPUTexture *gpu_texture_create_tile_mapping(Image *ima, const int multiview_eye)
+static GPUTexture *gpu_texture_create_tile_mapping(Image *ima,
+ ImageGPUTextureStore::Entry &entry,
+ const int multiview_eye)
{
- GPUTexture *tilearray = ima->gputexture[TEXTARGET_2D_ARRAY][multiview_eye];
+ GPUTexture *tilearray = entry.gputextures[TEXTARGET_2D_ARRAY][multiview_eye];
if (tilearray == nullptr) {
return nullptr;
@@ -249,7 +373,7 @@ static GPUTexture *gpu_texture_create_tile_array(
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list