[Bf-blender-cvs] [96396272d49] temp-image-engine-refactor: Reorganizing image engine code.

Jeroen Bakker noreply at git.blender.org
Fri Nov 5 12:44:28 CET 2021


Commit: 96396272d4985d12cc660bd0f2e0238b3bdd83c9
Author: Jeroen Bakker
Date:   Wed Nov 3 15:53:07 2021 +0100
Branches: temp-image-engine-refactor
https://developer.blender.org/rB96396272d4985d12cc660bd0f2e0238b3bdd83c9

Reorganizing image engine code.

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

M	source/blender/draw/engines/image/image_engine.cc

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

diff --git a/source/blender/draw/engines/image/image_engine.cc b/source/blender/draw/engines/image/image_engine.cc
index 776639f5224..11fe7e55d10 100644
--- a/source/blender/draw/engines/image/image_engine.cc
+++ b/source/blender/draw/engines/image/image_engine.cc
@@ -24,6 +24,9 @@
 
 #include "DRW_render.h"
 
+#include <memory>
+#include <optional>
+
 #include "BKE_image.h"
 #include "BKE_main.h"
 #include "BKE_object.h"
@@ -43,6 +46,11 @@
 
 namespace blender::draw::image_engine {
 
+/* Forward declarations. */
+class AbstractSpaceAccessor;
+static void image_cache_image(
+    AbstractSpaceAccessor &space, IMAGE_Data *vedata, Image *image, ImageUser *iuser, ImBuf *ibuf);
+
 #define IMAGE_DRAW_FLAG_SHOW_ALPHA (1 << 0)
 #define IMAGE_DRAW_FLAG_APPLY_ALPHA (1 << 1)
 #define IMAGE_DRAW_FLAG_SHUFFLING (1 << 2)
@@ -50,6 +58,292 @@ namespace blender::draw::image_engine {
 #define IMAGE_DRAW_FLAG_DO_REPEAT (1 << 4)
 #define IMAGE_DRAW_FLAG_USE_WORLD_POS (1 << 5)
 
+struct ShaderParameters {
+  constexpr static float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+
+  int flags = 0;
+  float shuffle[4];
+  float far_near[2];
+  bool use_premul_alpha = false;
+
+  ShaderParameters()
+  {
+    copy_v4_fl(shuffle, 1.0f);
+    copy_v2_fl2(far_near, 100.0f, 0.0f);
+  }
+
+  void set_far_near(Camera *camera)
+  {
+    far_near[1] = camera->clip_start;
+    far_near[0] = camera->clip_end;
+  }
+};
+
+class AbstractSpaceAccessor {
+ public:
+  virtual void release_buffer(Image *image, ImBuf *ibuf, void *lock) = 0;
+  virtual Image *get_image(Main *bmain) = 0;
+  virtual ImageUser *get_image_user() = 0;
+  virtual ImBuf *acquire_image_buffer(Image *image, void **lock) = 0;
+  virtual void get_shader_parameters(ShaderParameters &r_shader_parameters,
+                                     ImBuf *ibuf,
+                                     bool is_tiled) = 0;
+
+  virtual std::optional<DRWView *> create_view(const ARegion *UNUSED(region))
+  {
+    return std::nullopt;
+  }
+};
+
+class SpaceImageAccessor : public AbstractSpaceAccessor {
+  SpaceImage *sima;
+
+ public:
+  SpaceImageAccessor(SpaceImage *sima) : sima(sima)
+  {
+  }
+
+  Image *get_image(Main *UNUSED(bmain)) override
+  {
+    return ED_space_image(sima);
+  }
+
+  ImageUser *get_image_user() override
+  {
+    return &sima->iuser;
+  }
+
+  ImBuf *acquire_image_buffer(Image *UNUSED(image), void **lock) override
+  {
+    return ED_space_image_acquire_buffer(sima, lock, 0);
+  }
+
+  void release_buffer(Image *UNUSED(image), ImBuf *ibuf, void *lock) override
+  {
+    ED_space_image_release_buffer(sima, ibuf, lock);
+  }
+
+  void get_shader_parameters(ShaderParameters &r_shader_parameters,
+                             ImBuf *ibuf,
+                             bool is_tiled) override
+  {
+    const int sima_flag = sima->flag & ED_space_image_get_display_channel_mask(ibuf);
+    const bool do_repeat = (!is_tiled) && ((sima->flag & SI_DRAW_TILE) != 0);
+    SET_FLAG_FROM_TEST(r_shader_parameters.flags, do_repeat, IMAGE_DRAW_FLAG_DO_REPEAT);
+    SET_FLAG_FROM_TEST(r_shader_parameters.flags, is_tiled, IMAGE_DRAW_FLAG_USE_WORLD_POS);
+    if ((sima_flag & SI_USE_ALPHA) != 0) {
+      /* Show RGBA */
+      r_shader_parameters.flags |= IMAGE_DRAW_FLAG_SHOW_ALPHA | IMAGE_DRAW_FLAG_APPLY_ALPHA;
+    }
+    else if ((sima_flag & SI_SHOW_ALPHA) != 0) {
+      r_shader_parameters.flags |= IMAGE_DRAW_FLAG_SHUFFLING;
+      copy_v4_fl4(r_shader_parameters.shuffle, 0.0f, 0.0f, 0.0f, 1.0f);
+    }
+    else if ((sima_flag & SI_SHOW_ZBUF) != 0) {
+      r_shader_parameters.flags |= IMAGE_DRAW_FLAG_DEPTH | IMAGE_DRAW_FLAG_SHUFFLING;
+      copy_v4_fl4(r_shader_parameters.shuffle, 1.0f, 0.0f, 0.0f, 0.0f);
+    }
+    else if ((sima_flag & SI_SHOW_R) != 0) {
+      r_shader_parameters.flags |= IMAGE_DRAW_FLAG_SHUFFLING;
+      if (IMB_alpha_affects_rgb(ibuf)) {
+        r_shader_parameters.flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA;
+      }
+      copy_v4_fl4(r_shader_parameters.shuffle, 1.0f, 0.0f, 0.0f, 0.0f);
+    }
+    else if ((sima_flag & SI_SHOW_G) != 0) {
+      r_shader_parameters.flags |= IMAGE_DRAW_FLAG_SHUFFLING;
+      if (IMB_alpha_affects_rgb(ibuf)) {
+        r_shader_parameters.flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA;
+      }
+      copy_v4_fl4(r_shader_parameters.shuffle, 0.0f, 1.0f, 0.0f, 0.0f);
+    }
+    else if ((sima_flag & SI_SHOW_B) != 0) {
+      r_shader_parameters.flags |= IMAGE_DRAW_FLAG_SHUFFLING;
+      if (IMB_alpha_affects_rgb(ibuf)) {
+        r_shader_parameters.flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA;
+      }
+      copy_v4_fl4(r_shader_parameters.shuffle, 0.0f, 0.0f, 1.0f, 0.0f);
+    }
+    else /* RGB */ {
+      if (IMB_alpha_affects_rgb(ibuf)) {
+        r_shader_parameters.flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA;
+      }
+    }
+  }
+};
+
+class SpaceNodeAccessor : public AbstractSpaceAccessor {
+  SpaceNode *snode;
+
+ public:
+  SpaceNodeAccessor(SpaceNode *snode) : snode(snode)
+  {
+  }
+
+  Image *get_image(Main *bmain) override
+  {
+    return BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
+  }
+
+  ImageUser *get_image_user() override
+  {
+    return nullptr;
+  }
+
+  ImBuf *acquire_image_buffer(Image *image, void **lock) override
+  {
+    return BKE_image_acquire_ibuf(image, nullptr, lock);
+  }
+
+  void release_buffer(Image *image, ImBuf *ibuf, void *lock) override
+  {
+    BKE_image_release_ibuf(image, ibuf, lock);
+  }
+
+  std::optional<DRWView *> create_view(const ARegion *region) override
+  {
+    /* Setup a screen pixel view. The backdrop of the node editor doesn't follow the region. */
+    float winmat[4][4], viewmat[4][4];
+    orthographic_m4(viewmat, 0.0, region->winx, 0.0, region->winy, 0.0, 1.0);
+    unit_m4(winmat);
+    return std::make_optional(DRW_view_create(viewmat, winmat, nullptr, nullptr, nullptr));
+  }
+
+  void get_shader_parameters(ShaderParameters &r_shader_parameters,
+                             ImBuf *ibuf,
+                             bool UNUSED(is_tiled)) override
+  {
+    if ((snode->flag & SNODE_USE_ALPHA) != 0) {
+      /* Show RGBA */
+      r_shader_parameters.flags |= IMAGE_DRAW_FLAG_SHOW_ALPHA | IMAGE_DRAW_FLAG_APPLY_ALPHA;
+    }
+    else if ((snode->flag & SNODE_SHOW_ALPHA) != 0) {
+      r_shader_parameters.flags |= IMAGE_DRAW_FLAG_SHUFFLING;
+      copy_v4_fl4(r_shader_parameters.shuffle, 0.0f, 0.0f, 0.0f, 1.0f);
+    }
+    else if ((snode->flag & SNODE_SHOW_R) != 0) {
+      r_shader_parameters.flags |= IMAGE_DRAW_FLAG_SHUFFLING;
+      if (IMB_alpha_affects_rgb(ibuf)) {
+        r_shader_parameters.flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA;
+      }
+      copy_v4_fl4(r_shader_parameters.shuffle, 1.0f, 0.0f, 0.0f, 0.0f);
+    }
+    else if ((snode->flag & SNODE_SHOW_G) != 0) {
+      r_shader_parameters.flags |= IMAGE_DRAW_FLAG_SHUFFLING;
+      if (IMB_alpha_affects_rgb(ibuf)) {
+        r_shader_parameters.flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA;
+      }
+      copy_v4_fl4(r_shader_parameters.shuffle, 0.0f, 1.0f, 0.0f, 0.0f);
+    }
+    else if ((snode->flag & SNODE_SHOW_B) != 0) {
+      r_shader_parameters.flags |= IMAGE_DRAW_FLAG_SHUFFLING;
+      if (IMB_alpha_affects_rgb(ibuf)) {
+        r_shader_parameters.flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA;
+      }
+      copy_v4_fl4(r_shader_parameters.shuffle, 0.0f, 0.0f, 1.0f, 0.0f);
+    }
+    else /* RGB */ {
+      if (IMB_alpha_affects_rgb(ibuf)) {
+        r_shader_parameters.flags |= IMAGE_DRAW_FLAG_APPLY_ALPHA;
+      }
+    }
+  }
+};
+
+static std::unique_ptr<AbstractSpaceAccessor> space_accessor_from_context(
+    const DRWContextState *draw_ctx)
+{
+  const char space_type = draw_ctx->space_data->spacetype;
+  if (space_type == SPACE_IMAGE) {
+    return std::make_unique<SpaceImageAccessor>((SpaceImage *)draw_ctx->space_data);
+  }
+  if (space_type == SPACE_NODE) {
+    return std::make_unique<SpaceNodeAccessor>((SpaceNode *)draw_ctx->space_data);
+  }
+  BLI_assert_unreachable();
+  return nullptr;
+}
+
+class ImageEngine {
+ private:
+  const DRWContextState *draw_ctx;
+  IMAGE_Data *vedata;
+  std::unique_ptr<AbstractSpaceAccessor> space;
+
+ public:
+  ImageEngine(const DRWContextState *draw_ctx, IMAGE_Data *vedata)
+      : draw_ctx(draw_ctx), vedata(vedata), space(space_accessor_from_context(draw_ctx))
+  {
+  }
+
+  virtual ~ImageEngine() = default;
+
+  static DRWPass *create_image_pass()
+  {
+    /* Write depth is needed for background overlay rendering. Near depth is used for
+     * transparency checker and Far depth is used for indicating the image size. */
+    DRWState state = static_cast<DRWState>(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
+                                           DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA_PREMUL);
+    return DRW_pass_create("Image", state);
+  }
+
+  void cache_init()
+  {
+    IMAGE_StorageList *stl = vedata->stl;
+    IMAGE_PrivateData *pd = stl->pd;
+    IMAGE_PassList *psl = vedata->psl;
+
+    psl->image_pass = create_image_pass();
+
+    Main *bmain = CTX_data_main(draw_ctx->evil_C);
+    const ARegion *region = draw_ctx->region;
+    pd->image = space->get_image(bmain);
+    pd->ibuf = space->acquire_image_buffer(pd->image, &pd->lock);
+    ImageUser *iuser = space->get_image_user();
+    image_cache_image(*space, vedata, pd->image, iuser, pd->ibuf);
+
+    pd->view = nullptr;
+    std::optional<DRWView *> view_override = space->create_view(region);
+    if (view_override.has_value()) {
+      pd->view = view_override.value();
+    }
+  }
+
+  void draw_finish()
+  {
+    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;
+
+    if (pd->texture && pd->owns_texture) {
+      GPU_texture_free(pd->texture);
+      pd->owns_texture = false;
+    }
+    pd->texture = nullptr;
+  }
+
+  void draw_scene()
+  {
+    IMAGE_PassList *psl = vedata->psl;
+    IMAGE_PrivateData *pd = vedata->stl->pd;
+
+    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);
+
+   

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list