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:
Diffstat (limited to 'source/blender/blenkernel/intern/image_gpu.c')
-rw-r--r--source/blender/blenkernel/intern/image_gpu.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/source/blender/blenkernel/intern/image_gpu.c b/source/blender/blenkernel/intern/image_gpu.c
index f37e038e69e..4d4013e5d1d 100644
--- a/source/blender/blenkernel/intern/image_gpu.c
+++ b/source/blender/blenkernel/intern/image_gpu.c
@@ -49,6 +49,21 @@
static void gpu_free_unused_buffers(void);
static void image_free_gpu(Image *ima, const bool immediate);
+/* Is the alpha of the `GPUTexture` for a given image/ibuf premultiplied. */
+bool BKE_image_has_gpu_texture_premultiplied_alpha(Image *image, ImBuf *ibuf)
+{
+ const bool type_is_premultiplied = (image == NULL) || ELEM(image->type,
+ IMA_TYPE_R_RESULT,
+ IMA_TYPE_COMPOSITE,
+ IMA_TYPE_UV_TEST);
+ const bool store_premultiplied =
+ type_is_premultiplied ||
+ ((ibuf != NULL) &&
+ (ibuf->rect_float ? (image ? (image->alpha_mode != IMA_ALPHA_STRAIGHT) : false) :
+ (image ? (image->alpha_mode == IMA_ALPHA_PREMUL) : true)));
+ return store_premultiplied;
+}
+
/* -------------------------------------------------------------------- */
/** \name UDIM gpu texture
* \{ */
@@ -198,8 +213,7 @@ static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
if (ibuf) {
- const bool store_premultiplied = ibuf->rect_float ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) :
- (ima->alpha_mode == IMA_ALPHA_PREMUL);
+ const bool store_premultiplied = BKE_image_has_gpu_texture_premultiplied_alpha(ima, ibuf);
IMB_update_gpu_texture_sub(tex,
ibuf,
UNPACK2(tileoffset),
@@ -272,10 +286,17 @@ static GPUTexture *image_get_gpu_texture(Image *ima,
* context and might as well ensure we have as much space free as possible. */
gpu_free_unused_buffers();
- /* Free GPU textures when requesting a different render pass/layer. */
- if (ima->gpu_pass != iuser->pass || ima->gpu_layer != iuser->layer) {
- ima->gpu_pass = iuser->pass;
- ima->gpu_layer = iuser->layer;
+ /* Free GPU textures when requesting a different render pass/layer.
+ * When `iuser` isn't set (texture painting single image mode) we assume that
+ * the current `pass` and `layer` should be 0. */
+ short requested_pass = iuser ? iuser->pass : 0;
+ short requested_layer = iuser ? iuser->layer : 0;
+ short requested_slot = ima->render_slot;
+ if (ima->gpu_pass != requested_pass || ima->gpu_layer != requested_layer ||
+ ima->gpu_slot != requested_slot) {
+ ima->gpu_pass = requested_pass;
+ ima->gpu_layer = requested_layer;
+ ima->gpu_slot = requested_slot;
ima->gpuflag |= IMA_GPU_REFRESH;
}
@@ -323,9 +344,8 @@ static GPUTexture *image_get_gpu_texture(Image *ima,
}
else {
const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH);
- const bool store_premultiplied = ibuf_intern->rect_float ?
- (ima ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : false) :
- (ima ? (ima->alpha_mode == IMA_ALPHA_PREMUL) : true);
+ const bool store_premultiplied = BKE_image_has_gpu_texture_premultiplied_alpha(ima,
+ ibuf_intern);
*tex = IMB_create_gpu_texture(
ima->id.name + 2, ibuf_intern, use_high_bitdepth, store_premultiplied);
@@ -635,6 +655,7 @@ static void gpu_texture_update_from_ibuf(
int tex_stride = ibuf->x;
int tex_offset = ibuf->channels * (y * ibuf->x + x);
+ const bool store_premultiplied = BKE_image_has_gpu_texture_premultiplied_alpha(ima, ibuf);
if (rect_float == NULL) {
/* Byte pixels. */
if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) {
@@ -651,15 +672,12 @@ static void gpu_texture_update_from_ibuf(
/* Convert to scene linear with sRGB compression, and premultiplied for
* correct texture interpolation. */
- const bool store_premultiplied = (ima->alpha_mode == IMA_ALPHA_PREMUL);
IMB_colormanagement_imbuf_to_byte_texture(
rect, x, y, w, h, ibuf, compress_as_srgb, store_premultiplied);
}
}
else {
/* Float pixels. */
- const bool store_premultiplied = (ima->alpha_mode != IMA_ALPHA_STRAIGHT);
-
if (ibuf->channels != 4 || scaled || !store_premultiplied) {
rect_float = (float *)MEM_mallocN(sizeof(float[4]) * w * h, __func__);
if (rect_float == NULL) {