[Bf-blender-cvs] [86ca5f5e94c] temp-gpu-image-engine: ImBuf transform: Added Sampler.

Jeroen Bakker noreply at git.blender.org
Mon Dec 13 12:47:44 CET 2021


Commit: 86ca5f5e94c3aae5ff3acbb48548ca8fab346cd0
Author: Jeroen Bakker
Date:   Mon Dec 13 09:19:12 2021 +0100
Branches: temp-gpu-image-engine
https://developer.blender.org/rB86ca5f5e94c3aae5ff3acbb48548ca8fab346cd0

ImBuf transform: Added Sampler.

The sampler will hide the interpolation functions and would allow us
to add interpolation functions for none 4 channel buffers.

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

M	source/blender/imbuf/intern/transform.cc

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

diff --git a/source/blender/imbuf/intern/transform.cc b/source/blender/imbuf/intern/transform.cc
index 814e21e730c..8bfca373aee 100644
--- a/source/blender/imbuf/intern/transform.cc
+++ b/source/blender/imbuf/intern/transform.cc
@@ -144,24 +144,24 @@ template<
      * \brief Kind of buffer.
      * Possible options: float, unsigned char.
      */
-    typename ImBufStorageType = float,
+    typename StorageType = float,
 
     /**
      * \brief Number of channels of a single pixel.
      */
     int NumChannels = 4>
 class TexelPointer {
-  ImBufStorageType *pointer;
+  StorageType *pointer;
 
  public:
   void init_pixel_pointer(const ImBuf *image_buffer, int x, int y)
   {
     const size_t offset = (y * (size_t)image_buffer->x + x) * NumChannels;
 
-    if constexpr (std::is_same_v<ImBufStorageType, float>) {
+    if constexpr (std::is_same_v<StorageType, float>) {
       pointer = image_buffer->rect_float + offset;
     }
-    else if constexpr (std::is_same_v<ImBufStorageType, unsigned char>) {
+    else if constexpr (std::is_same_v<StorageType, unsigned char>) {
       pointer = const_cast<unsigned char *>(
           static_cast<const unsigned char *>(static_cast<const void *>(image_buffer->rect)) +
           offset);
@@ -170,24 +170,33 @@ class TexelPointer {
       pointer = nullptr;
     }
   }
-
-  float *get_float_pointer()
-  {
-    if constexpr (std::is_same_v<ImBufStorageType, float>) {
-      return pointer;
+  /*
+    float *get_float_pointer()
+    {
+      if constexpr (std::is_same_v<StorageType, float>) {
+        return pointer;
+      }
+      else {
+        return nullptr;
+      }
     }
-    else {
-      return nullptr;
+    unsigned char *get_uchar_pointer()
+    {
+      if constexpr (std::is_same_v<StorageType, unsigned char>) {
+        return pointer;
+      }
+      else {
+        return nullptr;
+      }
     }
-  }
-  unsigned char *get_uchar_pointer()
+    */
+
+  /**
+   * \brief Get pointer to the current texel to write to.
+   */
+  StorageType *get_pointer()
   {
-    if constexpr (std::is_same_v<ImBufStorageType, unsigned char>) {
-      return pointer;
-    }
-    else {
-      return nullptr;
-    }
+    return pointer;
   }
 
   void increase_pixel_pointer()
@@ -196,6 +205,36 @@ class TexelPointer {
   }
 };
 
+template<eIMBInterpolationFilterMode Filter, typename StorageType, int NumChannels> class Sampler {
+ public:
+  virtual void sample(const ImBuf *source,
+                      const float u,
+                      const float v,
+                      StorageType r_sample[NumChannels])
+  {
+    if constexpr (Filter == IMB_FILTER_NEAREST && std::is_same_v<StorageType, float> &&
+                  NumChannels == 4) {
+      nearest_interpolation_color_fl(source, nullptr, r_sample, u, v);
+    }
+    else if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v<StorageType, float> &&
+                       NumChannels == 4) {
+      bilinear_interpolation_color_fl(source, nullptr, r_sample, u, v);
+    }
+    else if constexpr (Filter == IMB_FILTER_NEAREST &&
+                       std::is_same_v<StorageType, unsigned char> && NumChannels == 4) {
+      nearest_interpolation_color_char(source, r_sample, nullptr, u, v);
+    }
+    else if constexpr (Filter == IMB_FILTER_BILINEAR &&
+                       std::is_same_v<StorageType, unsigned char> && NumChannels == 4) {
+      bilinear_interpolation_color_char(source, r_sample, nullptr, u, v);
+    }
+    else {
+      /* Unsupported sampler. */
+      BLI_assert_unreachable();
+    }
+  }
+};
+
 /**
  * \brief Wrapping mode for the uv coordinates.
  *
@@ -269,7 +308,7 @@ template<
     /**
      * \brief Color interpolation function to read from the source buffer.
      */
-    InterpolationColorFunction ColorInterpolation,
+    typename Sampler,
 
     /**
      * \brief Kernel to store to the destination buffer.
@@ -286,6 +325,7 @@ class ScanlineProcessor {
   Discard discarder;
   UVWrapping uv_wrapping;
   OutputTexelPointer output;
+  Sampler sampler;
 
  public:
   void process(const TransformUserData *user_data, int scanline)
@@ -298,11 +338,11 @@ class ScanlineProcessor {
     output.init_pixel_pointer(user_data->dst, 0, scanline);
     for (int xi = 0; xi < width; xi++) {
       if (!discarder.should_discard(*user_data, uv)) {
-        ColorInterpolation(user_data->src,
-                           output.get_uchar_pointer(),
-                           output.get_float_pointer(),
-                           uv_wrapping.modify_u(*user_data, uv[0]),
-                           uv_wrapping.modify_v(*user_data, uv[1]));
+
+        sampler.sample(user_data->src,
+                       uv_wrapping.modify_u(*user_data, uv[0]),
+                       uv_wrapping.modify_v(*user_data, uv[1]),
+                       output.get_pointer());
       }
 
       add_v2_v2(uv, user_data->add_x);
@@ -318,26 +358,29 @@ template<typename Processor> void transform_scanline_function(void *custom_data,
   processor.process(user_data, scanline);
 }
 
-template<InterpolationColorFunction InterpolationFunction, typename StorageType>
+template<eIMBInterpolationFilterMode Filter, typename StorageType, int NumChannels>
 ScanlineThreadFunc get_scanline_function(const eIMBTransformMode mode)
 
 {
   switch (mode) {
     case IMB_TRANSFORM_MODE_REGULAR:
-      return transform_scanline_function<ScanlineProcessor<NoDiscard,
-                                                           InterpolationFunction,
-                                                           TexelPointer<StorageType, 4>,
-                                                           PassThroughUV>>;
+      return transform_scanline_function<
+          ScanlineProcessor<NoDiscard,
+                            Sampler<Filter, StorageType, NumChannels>,
+                            TexelPointer<StorageType, NumChannels>,
+                            PassThroughUV>>;
     case IMB_TRANSFORM_MODE_CROP_SRC:
-      return transform_scanline_function<ScanlineProcessor<CropSource,
-                                                           InterpolationFunction,
-                                                           TexelPointer<StorageType, 4>,
-                                                           PassThroughUV>>;
+      return transform_scanline_function<
+          ScanlineProcessor<CropSource,
+                            Sampler<Filter, StorageType, NumChannels>,
+                            TexelPointer<StorageType, NumChannels>,
+                            PassThroughUV>>;
     case IMB_TRANSFORM_MODE_WRAP_REPEAT:
-      return transform_scanline_function<ScanlineProcessor<NoDiscard,
-                                                           InterpolationFunction,
-                                                           TexelPointer<StorageType, 4>,
-                                                           WrapRepeatUV>>;
+      return transform_scanline_function<
+          ScanlineProcessor<NoDiscard,
+                            Sampler<Filter, StorageType, NumChannels>,
+                            TexelPointer<StorageType, NumChannels>,
+                            WrapRepeatUV>>;
   }
 
   BLI_assert_unreachable();
@@ -350,16 +393,10 @@ static void transform(TransformUserData *user_data, const eIMBTransformMode mode
   ScanlineThreadFunc scanline_func = nullptr;
 
   if (user_data->dst->rect_float) {
-    constexpr InterpolationColorFunction interpolation_function =
-        Filter == IMB_FILTER_NEAREST ? nearest_interpolation_color_fl :
-                                       bilinear_interpolation_color_fl;
-    scanline_func = get_scanline_function<interpolation_function, float>(mode);
+    scanline_func = get_scanline_function<Filter, float, 4>(mode);
   }
   else if (user_data->dst->rect) {
-    constexpr InterpolationColorFunction interpolation_function =
-        Filter == IMB_FILTER_NEAREST ? nearest_interpolation_color_char :
-                                       bilinear_interpolation_color_char;
-    scanline_func = get_scanline_function<interpolation_function, unsigned char>(mode);
+    scanline_func = get_scanline_function<Filter, unsigned char, 4>(mode);
   }
 
   if (scanline_func != nullptr) {



More information about the Bf-blender-cvs mailing list