[Bf-blender-cvs] [fddaa022afa] temp-gpu-image-engine: Use instance data to solve memory leak.

Jeroen Bakker noreply at git.blender.org
Tue Dec 7 15:35:58 CET 2021


Commit: fddaa022afa2da60278d62c8a86e6d823b9f8815
Author: Jeroen Bakker
Date:   Tue Dec 7 15:35:44 2021 +0100
Branches: temp-gpu-image-engine
https://developer.blender.org/rBfddaa022afa2da60278d62c8a86e6d823b9f8815

Use instance data to solve memory leak.

===================================================================

M	source/blender/draw/engines/image/image_drawing_mode_screen_space.hh
M	source/blender/draw/engines/image/image_engine.cc
M	source/blender/draw/engines/image/image_private.hh

===================================================================

diff --git a/source/blender/draw/engines/image/image_drawing_mode_screen_space.hh b/source/blender/draw/engines/image/image_drawing_mode_screen_space.hh
index e62ccd9cc9c..040a141cac4 100644
--- a/source/blender/draw/engines/image/image_drawing_mode_screen_space.hh
+++ b/source/blender/draw/engines/image/image_drawing_mode_screen_space.hh
@@ -241,13 +241,12 @@ class ScreenSpaceDrawingMode : public AbstractDrawingMode {
     return DRW_pass_create("Image", state);
   }
 
-  void add_shgroups(IMAGE_PassList *psl,
-                    const IMAGE_InstanceData *instance_data,
+  void add_shgroups(const IMAGE_InstanceData *instance_data,
                     const ShaderParameters &sh_params) const
   {
     GPUShader *shader = IMAGE_shader_image_get(false);
 
-    DRWShadingGroup *shgrp = DRW_shgroup_create(shader, psl->image_pass);
+    DRWShadingGroup *shgrp = DRW_shgroup_create(shader, instance_data->passes.image_pass);
     DRW_shgroup_uniform_vec2_copy(shgrp, "farNearDistances", sh_params.far_near);
     DRW_shgroup_uniform_vec4_copy(shgrp, "color", ShaderParameters::color);
     DRW_shgroup_uniform_vec4_copy(shgrp, "shuffle", sh_params.shuffle);
@@ -583,9 +582,8 @@ class ScreenSpaceDrawingMode : public AbstractDrawingMode {
  public:
   void cache_init(IMAGE_Data *vedata) const override
   {
-    IMAGE_PassList *psl = vedata->psl;
-
-    psl->image_pass = create_image_pass();
+    IMAGE_InstanceData *instance_data = vedata->instance_data;
+    instance_data->passes.image_pass = create_image_pass();
   }
 
   void cache_image(AbstractSpaceAccessor *space,
@@ -595,7 +593,6 @@ class ScreenSpaceDrawingMode : public AbstractDrawingMode {
                    ImBuf *image_buffer) const override
   {
     const DRWContextState *draw_ctx = DRW_context_state_get();
-    IMAGE_PassList *psl = vedata->psl;
     IMAGE_InstanceData *instance_data = vedata->instance_data;
     InstanceDataAccessor pda(instance_data);
 
@@ -638,7 +635,7 @@ class ScreenSpaceDrawingMode : public AbstractDrawingMode {
     const bool is_tiled_image = (image->source == IMA_SRC_TILED);
     space->get_shader_parameters(sh_params, image_buffer, is_tiled_image);
 
-    add_shgroups(psl, instance_data, sh_params);
+    add_shgroups(instance_data, sh_params);
   }
 
   void draw_finish(IMAGE_Data *UNUSED(vedata)) const override
@@ -647,16 +644,15 @@ class ScreenSpaceDrawingMode : public AbstractDrawingMode {
 
   void draw_scene(IMAGE_Data *vedata) const override
   {
-    IMAGE_PassList *psl = vedata->psl;
-    IMAGE_PrivateData *pd = vedata->stl->pd;
+    IMAGE_InstanceData *instance_data = vedata->instance_data;
 
     DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
     GPU_framebuffer_bind(dfbl->default_fb);
     static float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
     GPU_framebuffer_clear_color_depth(dfbl->default_fb, clear_col, 1.0);
 
-    DRW_view_set_active(pd->view);
-    DRW_draw_pass(psl->image_pass);
+    DRW_view_set_active(instance_data->view);
+    DRW_draw_pass(instance_data->passes.image_pass);
     DRW_view_set_active(nullptr);
   }
 };  // namespace clipping
diff --git a/source/blender/draw/engines/image/image_engine.cc b/source/blender/draw/engines/image/image_engine.cc
index b3ca0b65d53..9193f0a3365 100644
--- a/source/blender/draw/engines/image/image_engine.cc
+++ b/source/blender/draw/engines/image/image_engine.cc
@@ -86,44 +86,40 @@ class ImageEngine {
 
   void cache_init()
   {
-    IMAGE_StorageList *stl = vedata->stl;
-    IMAGE_PrivateData *pd = stl->pd;
-
+    IMAGE_InstanceData *instance_data = vedata->instance_data;
     drawing_mode.cache_init(vedata);
-    pd->view = nullptr;
+    instance_data->view = nullptr;
     if (space->has_view_override()) {
       const ARegion *region = draw_ctx->region;
-      pd->view = space->create_view_override(region);
+      instance_data->view = space->create_view_override(region);
     }
   }
 
   void cache_populate()
   {
-    IMAGE_StorageList *stl = vedata->stl;
-    IMAGE_PrivateData *pd = stl->pd;
     IMAGE_InstanceData *instance_data = vedata->instance_data;
     Main *bmain = CTX_data_main(draw_ctx->evil_C);
-    pd->image = space->get_image(bmain);
-    if (pd->image == nullptr) {
+    instance_data->image = space->get_image(bmain);
+    if (instance_data->image == nullptr) {
       /* Early exit, nothing to draw. */
       return;
     }
-    instance_data->flags.do_tile_drawing = pd->image->source != IMA_SRC_TILED &&
+    instance_data->flags.do_tile_drawing = instance_data->image->source != IMA_SRC_TILED &&
                                            space->use_tile_drawing();
-    pd->ibuf = space->acquire_image_buffer(pd->image, &pd->lock);
+    instance_data->ibuf = space->acquire_image_buffer(instance_data->image, &instance_data->lock);
     ImageUser *iuser = space->get_image_user();
-    drawing_mode.cache_image(space.get(), vedata, pd->image, iuser, pd->ibuf);
+    drawing_mode.cache_image(
+        space.get(), vedata, instance_data->image, iuser, instance_data->ibuf);
   }
 
   void draw_finish()
   {
     drawing_mode.draw_finish(vedata);
 
-    IMAGE_StorageList *stl = vedata->stl;
-    IMAGE_PrivateData *pd = stl->pd;
-    space->release_buffer(pd->image, pd->ibuf, pd->lock);
-    pd->image = nullptr;
-    pd->ibuf = nullptr;
+    IMAGE_InstanceData *instance_data = vedata->instance_data;
+    space->release_buffer(instance_data->image, instance_data->ibuf, instance_data->lock);
+    instance_data->image = nullptr;
+    instance_data->ibuf = nullptr;
   }
 
   void draw_scene()
@@ -140,17 +136,9 @@ static void IMAGE_engine_init(void *ved)
 {
   IMAGE_shader_library_ensure();
   IMAGE_Data *vedata = (IMAGE_Data *)ved;
-  IMAGE_StorageList *stl = vedata->stl;
-  if (!stl->pd) {
-    stl->pd = static_cast<IMAGE_PrivateData *>(MEM_callocN(sizeof(IMAGE_PrivateData), __func__));
-  }
   if (vedata->instance_data == nullptr) {
     vedata->instance_data = OBJECT_GUARDED_NEW(IMAGE_InstanceData);
   }
-  IMAGE_PrivateData *pd = stl->pd;
-
-  pd->ibuf = nullptr;
-  pd->lock = nullptr;
 }
 
 static void IMAGE_cache_init(void *vedata)
diff --git a/source/blender/draw/engines/image/image_private.hh b/source/blender/draw/engines/image/image_private.hh
index f6e74258c40..f09e357333c 100644
--- a/source/blender/draw/engines/image/image_private.hh
+++ b/source/blender/draw/engines/image/image_private.hh
@@ -44,25 +44,6 @@ struct Image;
 
 namespace blender::draw::image_engine {
 
-/* GPUViewport.storage
- * Is freed every time the viewport engine changes. */
-struct IMAGE_PassList {
-  DRWPass *image_pass;
-};
-
-struct IMAGE_PrivateData {
-  void *lock;
-  struct ImBuf *ibuf;
-  struct Image *image;
-  struct DRWView *view;
-
-  /* Data used in screen space drawing mode. */
-};
-
-struct IMAGE_StorageList {
-  IMAGE_PrivateData *pd;
-};
-
 struct IMAGE_ScreenSpaceTextureInfo {
   /**
    * \brief Is the texture clipped.
@@ -84,6 +65,7 @@ struct IMAGE_ScreenSpaceTextureInfo {
   rctf uv_bounds;
   /** \brief Transform matrix to convert a normalized uv coordinate to texture space. */
   float uv_to_texture[4][4];
+
   /**
    * \brief Batch to draw the associated texton the screen.
    *
@@ -97,12 +79,34 @@ struct IMAGE_ScreenSpaceTextureInfo {
    * \brief GPU Texture for a partial region of the image editor.
    */
   GPUTexture *texture;
+
+  ~IMAGE_ScreenSpaceTextureInfo()
+  {
+    if (batch != nullptr) {
+      GPU_batch_discard(batch);
+      batch = nullptr;
+    }
+
+    if (texture != nullptr) {
+      GPU_texture_free(texture);
+      texture = nullptr;
+    }
+  }
 };
 
 struct IMAGE_InstanceData {
   struct PartialUpdateUser *partial_update_user;
   const struct Image *partial_update_image;
 
+  void *lock;
+  struct ImBuf *ibuf;
+  struct Image *image;
+  struct DRWView *view;
+
+  struct {
+    DRWPass *image_pass;
+  } passes;
+
   struct {
     /**
      * \brief should we perform tile drawing (wrap repeat).
@@ -120,14 +124,22 @@ struct IMAGE_InstanceData {
    *
    * Larger UV coordinates would be drawn as a border. */
   float max_uv[2];
+
+  ~IMAGE_InstanceData()
+  {
+    if (partial_update_user) {
+      BKE_image_partial_update_free(partial_update_user);
+      partial_update_user = nullptr;
+    }
+  }
 };
 
 struct IMAGE_Data {
   void *engine_type;
   DRWViewportEmptyList *fbl;
   DRWViewportEmptyList *txl;
-  IMAGE_PassList *psl;
-  IMAGE_StorageList *stl;
+  DRWViewportEmptyList *psl;
+  DRWViewportEmptyList *stl;
   IMAGE_InstanceData *instance_data;
 };



More information about the Bf-blender-cvs mailing list