[Bf-blender-cvs] [115c746d0fd] temp-explicit-colors: Changed templates to concrete classes.

Jeroen Bakker noreply at git.blender.org
Tue Apr 20 14:31:01 CEST 2021


Commit: 115c746d0fd4d1f506002e859bb7d359d289ad62
Author: Jeroen Bakker
Date:   Tue Apr 20 14:25:22 2021 +0200
Branches: temp-explicit-colors
https://developer.blender.org/rB115c746d0fd4d1f506002e859bb7d359d289ad62

Changed templates to concrete classes.

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

M	source/blender/blenkernel/BKE_attribute_math.hh
M	source/blender/blenkernel/intern/attribute_math.cc
M	source/blender/blenkernel/intern/geometry_component_mesh.cc
M	source/blender/blenlib/BLI_color.hh
M	source/blender/blenlib/CMakeLists.txt
A	source/blender/blenlib/intern/BLI_color.cc
M	source/blender/blenlib/tests/BLI_color_test.cc
M	source/blender/nodes/geometry/nodes/node_geo_switch.cc

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

diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh
index c5272b04582..28ffe9fc974 100644
--- a/source/blender/blenkernel/BKE_attribute_math.hh
+++ b/source/blender/blenkernel/BKE_attribute_math.hh
@@ -209,7 +209,7 @@ class ColorGeometryMixer {
 
  public:
   ColorGeometryMixer(MutableSpan<ColorGeometry4f> buffer,
-                     ColorGeometry4f default_color = {0, 0, 0, 1});
+                     ColorGeometry4f default_color = ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f));
   void mix_in(const int64_t index, const ColorGeometry4f &color, const float weight = 1.0f);
   void finalize();
 };
diff --git a/source/blender/blenkernel/intern/attribute_math.cc b/source/blender/blenkernel/intern/attribute_math.cc
index 155b034b404..5cdf329effb 100644
--- a/source/blender/blenkernel/intern/attribute_math.cc
+++ b/source/blender/blenkernel/intern/attribute_math.cc
@@ -24,7 +24,7 @@ ColorGeometryMixer::ColorGeometryMixer(MutableSpan<ColorGeometry4f> output_buffe
       default_color_(default_color),
       total_weights_(output_buffer.size(), 0.0f)
 {
-  buffer_.fill(ColorGeometry4f(0, 0, 0, 0));
+  buffer_.fill(ColorGeometry4f(0.0f, 0.0f, 0.0f, 0.0f));
 }
 
 void ColorGeometryMixer::mix_in(const int64_t index,
diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc
index 7262429e5f0..3e3403acc46 100644
--- a/source/blender/blenkernel/intern/geometry_component_mesh.cc
+++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc
@@ -787,15 +787,14 @@ static void set_loop_uv(MLoopUV &uv, float2 co)
 
 static ColorGeometry4f get_loop_color(const MLoopCol &col)
 {
-  ColorGeometry4b encoded_color(col.r, col.g, col.b, col.a);
-  ColorGeometry4f linear_color;
-  linear_color.decode(encoded_color);
+  ColorGeometry4b encoded_color = ColorGeometry4b(col.r, col.g, col.b, col.a);
+  ColorGeometry4f linear_color = encoded_color.to_byte_decoded();
   return linear_color;
 }
 
 static void set_loop_color(MLoopCol &col, ColorGeometry4f linear_color)
 {
-  ColorGeometry4b encoded_color = linear_color.encode();
+  ColorGeometry4b encoded_color = linear_color.to_byte_encoded();
   col.r = encoded_color.r;
   col.g = encoded_color.g;
   col.b = encoded_color.b;
diff --git a/source/blender/blenlib/BLI_color.hh b/source/blender/blenlib/BLI_color.hh
index a133b79cbe7..852d2218422 100644
--- a/source/blender/blenlib/BLI_color.hh
+++ b/source/blender/blenlib/BLI_color.hh
@@ -29,293 +29,321 @@ namespace blender {
  * Will increase readability and visibility of typically mistakes when
  * working with colors.
  *
- * The storage structs can hold 4 bytes (Color4b) or 4 floats (Color4f).
+ * The storage structs can hold 4 channels (r, g, b and a).
  *
  * Usage:
  *
  * Convert an srgb byte color to a linearrgb premultiplied.
  * ```
- * Color4b<Srgb, eAlpha::Straight> srgb_color;
- * Color4f<SceneLinear, eAlpha::Premultiplied> linearrgb_color(srgb_color);
+ * ColorSrgb4b srgb_color;
+ * ColorSceneLinear4f<eAlpha::Premultiplied> linearrgb_color =
+ *     BLI_color_convert_to_linear(srgb_color).to_premultiplied_alpha();
  * ```
  *
- * Common mistakes are:
- * - Storing linear colors in 4 bytes. Reducing the bit depth leads to banding
- *   artifacts.
- * - Missing conversion between Srgb/linearrgb color spaces. Colors are to
- *   bright or dark.
- * - Ignoring premultiplied or straight alpha.
+ * The API is structured to make most use of inlining. Most notably is that space
+ * conversions must be done via `BLI_color_convert_to*` functions.
+ *
+ * - Conversions between spaces (srgb <=> scene linear) should always be done by
+ *   invoking the `BLI_color_convert_to*` methods.
+ * - Encoding colors (compressing to store colors inside a less precision storage)
+ *   should be done by invoking the `encode` and `decode` methods.
+ * - Changing alpha association should be done by invoking `to_multiplied_alpha` or
+ *   `to_straight_alpha` methods.
+ *
+ * # Encoding.
+ *
+ * Color encoding is used to store colors with less precision using uint8_t in
+ * stead of floats. This encoding is supported for the `eSpace::SceneLinear`.
+ * To make this clear to the developer the a `eSpace::SceneLinearByteEncoded`
+ * space is added.
+ *
+ * # sRGB precision
+ *
+ * The sRGB colors can be stored using `uint8_t` or `float` colors. The conversion
+ * between the two precisions are available as methods. (`to_srgb4b` and
+ * `to_srgb4f`).
+ *
+ * # Alpha conversion
+ *
+ * Alpha conversion is only supported in SceneLinear space.
  *
  * Extending this file:
- * - This file can be extended with `ColorHex/Hsl/Hsv` for other
- *   representation of rgb based colors.
+ * - This file can be extended with `ColorHex/Hsl/Hsv` for different representations
+ *   of rgb based colors.
  * - Add ColorXyz.
  */
 
 /* Enumeration containing the different alpha modes. */
-enum class eAlpha : uint8_t {
-  /* Alpha is unassociated (color is straight). */
+enum class eAlpha {
+  /* Color and alpha are unassociated. */
   Straight,
-  /* Alpha is associated (color is premultiplied with alpha). */
+  /* Color and alpha are associated. */
   Premultiplied,
 };
-
-template<typename Space, eAlpha Alpha> struct Color4f;
-template<typename Space, eAlpha Alpha> struct Color4b;
-
-/* Predefinition of Spaces. */
-class Srgb;
-class SceneLinear;
-
-/* Spaces are defined as classes to be extended with meta-data in the future.
- * The meta data could contain CIE 1931 coordinates of whitepoints and the
- * individual components.
- */
-
-class ByteEncodingNotSupported;
-
-class Srgb {
- public:
-  using ByteEncodedSpace = ByteEncodingNotSupported;
+std::ostream &operator<<(std::ostream &stream, const eAlpha &space);
+
+/* Enumeration containing internal spaces. */
+enum class eSpace {
+  /* sRGB color space. */
+  Srgb,
+  /* Blender internal scene linear color space (maps to SceneReference role in OCIO). */
+  SceneLinear,
+  /* Blender internal scene linear color space compressed to be stored in 4 uint8_t. */
+  SceneLinearByteEncoded,
 };
+std::ostream &operator<<(std::ostream &stream, const eSpace &space);
 
-BLI_INLINE void convert_space(const Color4f<Srgb, eAlpha::Straight> src,
-                              Color4f<SceneLinear, eAlpha::Straight> &dst);
-
-class SceneLinearByteEncoded {
-};
-/* Primary linear colorspace used in Blender.
- * Float precision color corresponding to the scene linear role in the OpenColorIO config.
- */
-class SceneLinear {
+/* Template class to store RGBA values with different precision, space and alpha association. */
+template<typename ChannelStorageType, eSpace Space, eAlpha Alpha> class ColorRGBA {
  public:
-  using ByteEncodedSpace = SceneLinearByteEncoded;
+  ChannelStorageType r, g, b, a;
+  constexpr ColorRGBA() = default;
 
-  BLI_INLINE void byte_encode(const float *decoded, uint8_t *r_byte_encoded)
+  constexpr ColorRGBA(const ChannelStorageType rgba[4])
+      : r(rgba[0]), g(rgba[1]), b(rgba[2]), a(rgba[3])
   {
-    float float_encoded[4];
-    linearrgb_to_srgb_v4(float_encoded, decoded);
-    rgba_float_to_uchar(r_byte_encoded, float_encoded);
   }
 
-  BLI_INLINE void byte_decode(const uint8_t *byte_encoded, float *r_decoded)
+  constexpr ColorRGBA(const ChannelStorageType r,
+                      const ChannelStorageType g,
+                      const ChannelStorageType b,
+                      const ChannelStorageType a)
+      : r(r), g(g), b(b), a(a)
   {
-    float float_encoded[4];
-    rgba_uchar_to_float(float_encoded, byte_encoded);
-    srgb_to_linearrgb_v4(r_decoded, float_encoded);
   }
-};
-BLI_INLINE void convert_space(const Color4f<SceneLinear, eAlpha::Straight> src,
-                              Color4b<Srgb, eAlpha::Straight> &dst);
-BLI_INLINE void convert_space(const Color4f<SceneLinear, eAlpha::Straight> src,
-                              Color4f<Srgb, eAlpha::Straight> &dst);
-BLI_INLINE void convert_space(const Color4f<SceneLinear, eAlpha::Premultiplied> src,
-                              Color4f<SceneLinear, eAlpha::Premultiplied> &dst);
 
-template<typename Space, eAlpha Alpha> struct Color4f {
-  float r, g, b, a;
-
-  Color4f() = default;
-
-  Color4f(const float *rgba) : r(rgba[0]), g(rgba[1]), b(rgba[2]), a(rgba[3])
+  operator ChannelStorageType *()
   {
+    return &r;
   }
 
-  Color4f(float r, float g, float b, float a) : r(r), g(g), b(b), a(a)
+  operator const ChannelStorageType *() const
   {
+    return &r;
   }
 
-  template<typename OtherSpace> explicit Color4f(Color4f<OtherSpace, Alpha> &src)
+  friend std::ostream &operator<<(std::ostream &stream,
+                                  const ColorRGBA<ChannelStorageType, Space, Alpha> &c)
   {
-    convert_space(src, *this);
-  }
 
-  /**
-   * Convert to another space.
-   *
-   * Doesn't allow altering of alpha mode. This needs to be done separately by calling
-   * premultiply/straight_alpha. Supported space conversions are implementing in the
-   *
-   * Usage:
-   */
-  // template<typename OtherSpace> Color4f<OtherSpace, Alpha> convert_space() const
-  // {
-  //   Color4f<OtherSpace, Alpha> result;
-  //   convert_space(*this, result);
-  //   return result;
-  // }
-
-  // template<typename OtherSpace> Color4b<OtherSpace, Alpha> convert_space() const
-  // {
-  //   Color4b<OtherSpace, Alpha> result;
-  //   convert_space(*this, result);
-  //   return result;
-  // }
-
-  Color4f<Space, eAlpha::Premultiplied> premultiply_alpha() const
-  {
-    BLI_assert(Alpha == eAlpha::Straight);
-    Color4f<Space, eAlpha::Premultiplied> premultiplied_alpha;
-    straight_to_premul_v4_v4(premultiplied_alpha, *this);
-    return premultiplied_alpha;
+    stream << Space << Alpha << "(" << c.r << ", " << c.g << ", " << c.b << ", " << c.a << ")";
+    return stream;
   }
 
-  Color4f<Space, eAlpha::Straight> straight_alpha() const
+  friend bool operator==(const ColorRGBA<ChannelStorageType, Space, Alpha> &a,
+                         const ColorRGBA<ChannelStorageType, Space, Alpha> &b)
   {
-    BLI_assert(Alpha == eAlpha::Premultiplied);
-    Color4f<Space, eAlpha::Straight> straight_alpha;
-    premul_to_straight_v4_v4(straight_alpha, *this);
-    

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list