[Bf-blender-cvs] [ea768ff2108] temp-gpu-image-engine: ImageEngine: Added skeleton for screen space drawing mode.

Jeroen Bakker noreply at git.blender.org
Wed Nov 24 15:52:16 CET 2021


Commit: ea768ff2108439a0a43b07359cb0c6e62b4a9749
Author: Jeroen Bakker
Date:   Wed Nov 24 15:51:35 2021 +0100
Branches: temp-gpu-image-engine
https://developer.blender.org/rBea768ff2108439a0a43b07359cb0c6e62b4a9749

ImageEngine: Added skeleton for screen space drawing mode.

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

M	source/blender/blenkernel/BKE_image.h
A	source/blender/blenkernel/BKE_image_partial_update.hh
M	source/blender/blenkernel/intern/image_partial_update.cc
A	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/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index bfe42549af3..7b03aeb208e 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -446,7 +446,7 @@ typedef enum ePartialUpdateIterResult {
 /**
  * \brief Create a new PartialUpdateUser. An Object that contains data to use partial updates.
  */
-struct PartialUpdateUser *BKE_image_partial_update_create(struct Image *image);
+struct PartialUpdateUser *BKE_image_partial_update_create(const struct Image *image);
 
 /**
  * \brief free a partial update user.
diff --git a/source/blender/blenkernel/BKE_image_partial_update.hh b/source/blender/blenkernel/BKE_image_partial_update.hh
new file mode 100644
index 00000000000..b16913e6f23
--- /dev/null
+++ b/source/blender/blenkernel/BKE_image_partial_update.hh
@@ -0,0 +1,93 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+#pragma once
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "DNA_image_types.h"
+
+#include "BKE_image.h"
+
+namespace blender::bke::image {
+
+class PartialUpdateIterator {
+  Image *image;
+  PartialUpdateUser *user;
+
+ public:
+  int tile_number;
+  ImageTile *tile = nullptr;
+  ImBuf *tile_buffer = nullptr;
+  PartialUpdateRegion change;
+
+ public:
+  PartialUpdateIterator(Image *image, PartialUpdateUser *user)
+      : image(image), user(user), tile_number(-1)
+  {
+  }
+
+  ePartialUpdateCollectResult collect_changes()
+  {
+    return BKE_image_partial_update_collect_changes(image, user);
+  }
+
+  ePartialUpdateIterResult get_next_change()
+  {
+    ePartialUpdateIterResult result = BKE_image_partial_update_get_next_change(user, &change);
+    switch (result) {
+      case PARTIAL_UPDATE_ITER_FINISHED:
+        free_tile_buffer();
+        return result;
+
+      case PARTIAL_UPDATE_ITER_CHANGE_AVAILABLE:
+        if (tile_number == change.tile_number) {
+          return result;
+        }
+        free_tile_buffer();
+        acquire_tile_buffer(change.tile_number);
+        return result;
+
+      default:
+        BLI_assert_unreachable();
+        return result;
+    }
+  }
+
+ private:
+  void free_tile_buffer()
+  {
+    BKE_image_release_ibuf(image, tile_buffer, nullptr);
+    tile = nullptr;
+    tile_buffer = nullptr;
+  }
+
+  void acquire_tile_buffer(int new_tile_number)
+  {
+    ImageUser tile_user = {0};
+    tile_user.tile = new_tile_number;
+
+    tile = BKE_image_get_tile(image, tile_number);
+    tile_buffer = BKE_image_acquire_ibuf(image, &tile_user, NULL);
+    tile_number = new_tile_number;
+  }
+};
+
+}  // namespace blender::bke::image
diff --git a/source/blender/blenkernel/intern/image_partial_update.cc b/source/blender/blenkernel/intern/image_partial_update.cc
index 0348afba215..f159482cc3c 100644
--- a/source/blender/blenkernel/intern/image_partial_update.cc
+++ b/source/blender/blenkernel/intern/image_partial_update.cc
@@ -134,7 +134,7 @@ struct PartialUpdateUserImpl {
 
 #ifdef NDEBUG
   /** \brief reference to image to validate correct API usage. */
-  void *debug_image_;
+  const void *debug_image_;
 #endif
 
   /**
@@ -460,7 +460,7 @@ static struct PartialUpdateRegister *image_partial_update_register_ensure(Image
 }
 
 // TODO(jbakker): cleanup parameter.
-struct PartialUpdateUser *BKE_image_partial_update_create(struct Image *image)
+struct PartialUpdateUser *BKE_image_partial_update_create(const struct Image *image)
 {
   PartialUpdateUserImpl *user_impl = OBJECT_GUARDED_NEW(PartialUpdateUserImpl);
 
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
new file mode 100644
index 00000000000..2138b83e495
--- /dev/null
+++ b/source/blender/draw/engines/image/image_drawing_mode_screen_space.hh
@@ -0,0 +1,276 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2021, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup draw_engine
+ */
+
+#pragma once
+
+#include "image_private.hh"
+
+#include "BKE_image_partial_update.hh"
+
+namespace blender::draw::image_engine {
+
+using namespace blender::bke::image;
+
+/* TODO: Should we use static class functions in stead of a namespace. */
+namespace clipping {
+static void update_texture_slots_bounds(const AbstractSpaceAccessor *space, IMAGE_PrivateData *pd)
+{
+  // each texture
+}
+
+static void update_texture_slots_visibility(const AbstractSpaceAccessor *space,
+                                            IMAGE_PrivateData *pd)
+{
+}
+
+}  // namespace clipping
+
+class ScreenSpaceDrawingMode : public AbstractDrawingMode {
+ private:
+  DRWPass *create_image_pass() const
+  {
+    /* 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 add_to_shgroup(AbstractSpaceAccessor *space,
+                      DRWShadingGroup *grp,
+                      const Image *image,
+                      const ImBuf *image_buffer) const
+  {
+    float image_mat[4][4];
+
+    const DRWContextState *draw_ctx = DRW_context_state_get();
+    const ARegion *region = draw_ctx->region;
+    space->get_image_mat(image_buffer, region, image_mat);
+
+    GPUBatch *geom = DRW_cache_quad_get();
+
+    const float translate_x = image_mat[3][0];
+    const float translate_y = image_mat[3][1];
+    LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) {
+      const int tile_x = ((tile->tile_number - 1001) % 10);
+      const int tile_y = ((tile->tile_number - 1001) / 10);
+      image_mat[3][0] = (float)tile_x + translate_x;
+      image_mat[3][1] = (float)tile_y + translate_y;
+      DRW_shgroup_call_obmat(grp, geom, image_mat);
+    }
+  }
+
+  /**
+   * \brief check if the partial update user in the private data can still be used.
+   *
+   * When switching to a different image the partial update user should be recreated.
+   */
+  bool partial_update_is_valid(const IMAGE_PrivateData *pd, const Image *image) const
+  {
+    if (pd->screen_space.partial_update_image != image) {
+      return false;
+    }
+
+    return pd->screen_space.partial_update_user != nullptr;
+  }
+
+  void partial_update_allocate(IMAGE_PrivateData *pd, const Image *image) const
+  {
+    BLI_assert(pd->screen_space.partial_update_user == nullptr);
+    pd->screen_space.partial_update_user = BKE_image_partial_update_create(image);
+    pd->screen_space.partial_update_image = image;
+  }
+
+  void partial_update_free(IMAGE_PrivateData *pd) const
+  {
+    if (pd->screen_space.partial_update_user != nullptr) {
+      BKE_image_partial_update_free(pd->screen_space.partial_update_user);
+      pd->screen_space.partial_update_user = nullptr;
+    }
+  }
+
+  void update_texture_slot_allocation(IMAGE_TextureList *txl, IMAGE_PrivateData *pd) const
+  {
+    for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
+      const bool is_allocated = txl->screen_space.textures[i] != nullptr;
+      const bool is_visible = pd->screen_space.texture_infos[i].visible;
+      const bool should_be_freed = !is_visible && is_allocated;
+      const bool should_be_created = is_visible && !is_allocated;
+
+      if (should_be_freed) {
+        GPU_texture_free(txl->screen_space.textures[i]);
+        txl->screen_space.textures[i] = nullptr;
+      }
+
+      if (should_be_created) {
+        DRW_texture_ensure_fullscreen_2d(
+            &txl->screen_space.textures[i], GPU_RGBA16F, static_cast<DRWTextureFlag>(0));
+      }
+      pd->screen_space.texture_infos[i].dirty = should_be_created;
+    }
+  }
+
+  void mark_all_texture_slots_dirty(IMAGE_PrivateData *pd) const
+  {
+    for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) {
+      pd->screen_space.texture_infos[i].dirty = true;
+    }
+  }
+
+  void update_textures(IMAGE_TextureList *txl, IMAGE_PrivateData *pd, Image *image) const
+  {
+    PartialUpdateIterator iterator(image, pd->screen_space.partial_update_user);
+
+    switch (iterator.collect_changes()) {
+      case PARTIAL_UPDATE_NEED_FULL_UPDATE:
+        mark_all_texture_slots_dirty(pd);
+        break;
+      case PARTIAL_UPDATE_NO_CHANGES:
+        break;
+      case PARTIAL_UPDATE_CHANGES_AVAILABLE:
+        do_partial_update(iterator, txl, pd, image);
+        break;
+    }
+    update_dirty_textures();
+  }
+
+  void do_partial_update(PartialUpdateIterator &iterator,
+                         IMAGE_TextureList *txl,
+                         IMAGE_PrivateData *pd,
+                     

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list