[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