Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2022-06-03 15:13:10 +0300
committerBrecht Van Lommel <brecht@blender.org>2022-06-03 16:25:23 +0300
commit9d8fb80f218f05f743943a289e2aad579e709058 (patch)
treeb16d985f28ddb0fd3d396e9713e624b96dae2b4f /source/blender/imbuf/intern/colormanagement.c
parent4c4056579b4bcbae3af745692f3fe802e3b79fac (diff)
Eevee/Workbench: store 8 bit image textures as half float for some color spaces
Same as in Cycles, this is needed for some color space conversions that don't compress well to byte sRGB, like for example Filmic sRGB. Ref T68926
Diffstat (limited to 'source/blender/imbuf/intern/colormanagement.c')
-rw-r--r--source/blender/imbuf/intern/colormanagement.c133
1 files changed, 75 insertions, 58 deletions
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 0a85b31ef7b..33873b5daa7 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -2211,21 +2211,14 @@ void IMB_colormanagement_imbuf_to_byte_texture(unsigned char *out_buffer,
const int width,
const int height,
const struct ImBuf *ibuf,
- const bool compress_as_srgb,
const bool store_premultiplied)
{
- /* Convert byte buffer for texture storage on the GPU. These have builtin
- * support for converting sRGB to linear, which allows us to store textures
- * without precision or performance loss at minimal memory usage. */
+ /* Byte buffer storage, only for sRGB and data texture since other
+ * color space conversions can't be done on the GPU. */
BLI_assert(ibuf->rect && ibuf->rect_float == NULL);
+ BLI_assert(IMB_colormanagement_space_is_srgb(ibuf->rect_colorspace) ||
+ IMB_colormanagement_space_is_data(ibuf->rect_colorspace));
- OCIO_ConstCPUProcessorRcPtr *processor = NULL;
- if (compress_as_srgb && ibuf->rect_colorspace &&
- !IMB_colormanagement_space_is_srgb(ibuf->rect_colorspace)) {
- processor = colorspace_to_scene_linear_cpu_processor(ibuf->rect_colorspace);
- }
-
- /* TODO(brecht): make this multi-threaded, or at least process in batches. */
const unsigned char *in_buffer = (unsigned char *)ibuf->rect;
const bool use_premultiply = IMB_alpha_affects_rgb(ibuf) && store_premultiplied;
@@ -2235,20 +2228,7 @@ void IMB_colormanagement_imbuf_to_byte_texture(unsigned char *out_buffer,
const unsigned char *in = in_buffer + in_offset * 4;
unsigned char *out = out_buffer + out_offset * 4;
- if (processor != NULL) {
- /* Convert to scene linear, to sRGB and premultiply. */
- for (int x = 0; x < width; x++, in += 4, out += 4) {
- float pixel[4];
- rgba_uchar_to_float(pixel, in);
- OCIO_cpuProcessorApplyRGB(processor, pixel);
- linearrgb_to_srgb_v3_v3(pixel, pixel);
- if (use_premultiply) {
- mul_v3_fl(pixel, pixel[3]);
- }
- rgba_float_to_uchar(out, pixel);
- }
- }
- else if (use_premultiply) {
+ if (use_premultiply) {
/* Premultiply only. */
for (int x = 0; x < width; x++, in += 4, out += 4) {
out[0] = (in[0] * in[3]) >> 8;
@@ -2279,43 +2259,80 @@ void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer,
{
/* Float texture are stored in scene linear color space, with premultiplied
* alpha depending on the image alpha mode. */
- const float *in_buffer = ibuf->rect_float;
- const int in_channels = ibuf->channels;
- const bool use_unpremultiply = IMB_alpha_affects_rgb(ibuf) && !store_premultiplied;
-
- for (int y = 0; y < height; y++) {
- const size_t in_offset = (offset_y + y) * ibuf->x + offset_x;
- const size_t out_offset = y * width;
- const float *in = in_buffer + in_offset * in_channels;
- float *out = out_buffer + out_offset * 4;
-
- if (in_channels == 1) {
- /* Copy single channel. */
- for (int x = 0; x < width; x++, in += 1, out += 4) {
- out[0] = in[0];
- out[1] = in[0];
- out[2] = in[0];
- out[3] = in[0];
+ if (ibuf->rect_float) {
+ /* Float source buffer. */
+ const float *in_buffer = ibuf->rect_float;
+ const int in_channels = ibuf->channels;
+ const bool use_unpremultiply = IMB_alpha_affects_rgb(ibuf) && !store_premultiplied;
+
+ for (int y = 0; y < height; y++) {
+ const size_t in_offset = (offset_y + y) * ibuf->x + offset_x;
+ const size_t out_offset = y * width;
+ const float *in = in_buffer + in_offset * in_channels;
+ float *out = out_buffer + out_offset * 4;
+
+ if (in_channels == 1) {
+ /* Copy single channel. */
+ for (int x = 0; x < width; x++, in += 1, out += 4) {
+ out[0] = in[0];
+ out[1] = in[0];
+ out[2] = in[0];
+ out[3] = in[0];
+ }
}
- }
- else if (in_channels == 3) {
- /* Copy RGB. */
- for (int x = 0; x < width; x++, in += 3, out += 4) {
- out[0] = in[0];
- out[1] = in[1];
- out[2] = in[2];
- out[3] = 1.0f;
+ else if (in_channels == 3) {
+ /* Copy RGB. */
+ for (int x = 0; x < width; x++, in += 3, out += 4) {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = 1.0f;
+ }
}
- }
- else if (in_channels == 4) {
- /* Copy or convert RGBA. */
- if (use_unpremultiply) {
- for (int x = 0; x < width; x++, in += 4, out += 4) {
- premul_to_straight_v4_v4(out, in);
+ else if (in_channels == 4) {
+ /* Copy or convert RGBA. */
+ if (use_unpremultiply) {
+ for (int x = 0; x < width; x++, in += 4, out += 4) {
+ premul_to_straight_v4_v4(out, in);
+ }
+ }
+ else {
+ memcpy(out, in, sizeof(float[4]) * width);
}
}
- else {
- memcpy(out, in, sizeof(float[4]) * width);
+ }
+ }
+ else {
+ /* Byte source buffer. */
+ const unsigned char *in_buffer = (unsigned char *)ibuf->rect;
+ const bool use_premultiply = IMB_alpha_affects_rgb(ibuf) && store_premultiplied;
+
+ /* TODO(brecht): make this multi-threaded, or at least process in batches. */
+ OCIO_ConstCPUProcessorRcPtr *processor = (ibuf->rect_colorspace) ?
+ colorspace_to_scene_linear_cpu_processor(
+ ibuf->rect_colorspace) :
+ NULL;
+
+ for (int y = 0; y < height; y++) {
+ const size_t in_offset = (offset_y + y) * ibuf->x + offset_x;
+ const size_t out_offset = y * width;
+ const unsigned char *in = in_buffer + in_offset * 4;
+ float *out = out_buffer + out_offset * 4;
+
+ /* Convert to scene linear, to sRGB and premultiply. */
+ for (int x = 0; x < width; x++, in += 4, out += 4) {
+ float pixel[4];
+ rgba_uchar_to_float(pixel, in);
+ if (processor) {
+ OCIO_cpuProcessorApplyRGB(processor, pixel);
+ }
+ else {
+ srgb_to_linearrgb_v3_v3(pixel, pixel);
+ }
+ if (use_premultiply) {
+ mul_v3_fl(pixel, pixel[3]);
+ }
+ copy_v4_v4(out, pixel);
}
}
}