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:
authorJacques Lucke <jacques@blender.org>2022-03-01 13:36:46 +0300
committerJacques Lucke <jacques@blender.org>2022-03-01 13:36:46 +0300
commit4b9c77a19aa359b5ab4b86e05cff1c8627d05a1e (patch)
tree8a5b74ef6f782e269883a1a38896cea51d4e953c
parentf0bfceb96d86062245c673938a8272276c1fcacf (diff)
parent9216cf9cb589f4d8ec0e79f0f0a160ce2c1dfb07 (diff)
Merge branch 'blender-v3.1-release'
-rw-r--r--source/blender/blenkernel/intern/image.c1
-rw-r--r--source/blender/blenkernel/intern/image_gpu.cc26
-rw-r--r--source/blender/blenkernel/intern/image_partial_update.cc4
-rw-r--r--source/blender/blenkernel/intern/node.cc2
-rw-r--r--source/blender/draw/engines/image/image_buffer_cache.hh131
-rw-r--r--source/blender/draw/engines/image/image_drawing_mode.hh65
-rw-r--r--source/blender/draw/engines/image/image_instance_data.hh9
-rw-r--r--source/blender/draw/engines/image/image_usage.hh3
-rw-r--r--source/blender/editors/object/object_bake_api.c1
-rw-r--r--source/blender/imbuf/IMB_imbuf.h3
-rw-r--r--source/blender/imbuf/intern/divers.c83
-rw-r--r--source/blender/makesrna/intern/rna_image.c2
12 files changed, 275 insertions, 55 deletions
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index fa63f99d3f1..817e7bb9685 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -3569,6 +3569,7 @@ static void image_tag_reload(Image *ima, ID *iuser_id, ImageUser *iuser, void *c
/* Must copy image user changes to CoW data-block. */
DEG_id_tag_update(iuser_id, ID_RECALC_COPY_ON_WRITE);
}
+ BKE_image_partial_update_mark_full_update(ima);
}
}
diff --git a/source/blender/blenkernel/intern/image_gpu.cc b/source/blender/blenkernel/intern/image_gpu.cc
index 444cbbe4bf9..c4a43d8b023 100644
--- a/source/blender/blenkernel/intern/image_gpu.cc
+++ b/source/blender/blenkernel/intern/image_gpu.cc
@@ -322,19 +322,25 @@ static void image_gpu_texture_partial_update_changes_available(
Image *image, PartialUpdateChecker<ImageTileData>::CollectResult &changes)
{
while (changes.get_next_change() == ePartialUpdateIterResult::ChangeAvailable) {
- const int tile_offset_x = changes.changed_region.region.xmin;
- const int tile_offset_y = changes.changed_region.region.ymin;
- const int tile_width = min_ii(changes.tile_data.tile_buffer->x,
- BLI_rcti_size_x(&changes.changed_region.region));
- const int tile_height = min_ii(changes.tile_data.tile_buffer->y,
- BLI_rcti_size_y(&changes.changed_region.region));
+ /* Calculate the clipping region with the tile buffer.
+ * TODO(jbakker): should become part of ImageTileData to deduplicate with image engine. */
+ rcti buffer_rect;
+ BLI_rcti_init(
+ &buffer_rect, 0, changes.tile_data.tile_buffer->x, 0, changes.tile_data.tile_buffer->y);
+ rcti clipped_update_region;
+ const bool has_overlap = BLI_rcti_isect(
+ &buffer_rect, &changes.changed_region.region, &clipped_update_region);
+ if (!has_overlap) {
+ continue;
+ }
+
image_update_gputexture_ex(image,
changes.tile_data.tile,
changes.tile_data.tile_buffer,
- tile_offset_x,
- tile_offset_y,
- tile_width,
- tile_height);
+ clipped_update_region.xmin,
+ clipped_update_region.ymin,
+ BLI_rcti_size_x(&clipped_update_region),
+ BLI_rcti_size_y(&clipped_update_region));
}
}
diff --git a/source/blender/blenkernel/intern/image_partial_update.cc b/source/blender/blenkernel/intern/image_partial_update.cc
index 9d5635f49ab..4606a14ab69 100644
--- a/source/blender/blenkernel/intern/image_partial_update.cc
+++ b/source/blender/blenkernel/intern/image_partial_update.cc
@@ -198,8 +198,8 @@ struct TileChangeset {
tile_width = image_buffer->x;
tile_height = image_buffer->y;
- int chunk_x_len = tile_width / CHUNK_SIZE;
- int chunk_y_len = tile_height / CHUNK_SIZE;
+ int chunk_x_len = (tile_width + CHUNK_SIZE - 1) / CHUNK_SIZE;
+ int chunk_y_len = (tile_height + CHUNK_SIZE - 1) / CHUNK_SIZE;
init_chunks(chunk_x_len, chunk_y_len);
return true;
}
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 876ccc5351c..96bfcb0311b 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -1952,6 +1952,8 @@ void nodeRemoveAllSockets(bNodeTree *ntree, bNode *node)
}
}
+ BLI_freelistN(&node->internal_links);
+
LISTBASE_FOREACH_MUTABLE (bNodeSocket *, sock, &node->inputs) {
node_socket_free(sock, true);
MEM_freeN(sock);
diff --git a/source/blender/draw/engines/image/image_buffer_cache.hh b/source/blender/draw/engines/image/image_buffer_cache.hh
new file mode 100644
index 00000000000..ef11551c879
--- /dev/null
+++ b/source/blender/draw/engines/image/image_buffer_cache.hh
@@ -0,0 +1,131 @@
+/*
+ * 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 2022, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup draw_engine
+ */
+
+#pragma once
+
+#include "BLI_vector.hh"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+struct FloatImageBuffer {
+ ImBuf *source_buffer = nullptr;
+ ImBuf *float_buffer = nullptr;
+ bool is_used = true;
+
+ FloatImageBuffer(ImBuf *source_buffer, ImBuf *float_buffer)
+ : source_buffer(source_buffer), float_buffer(float_buffer)
+ {
+ }
+
+ FloatImageBuffer(FloatImageBuffer &&other) noexcept
+ {
+ source_buffer = other.source_buffer;
+ float_buffer = other.float_buffer;
+ is_used = other.is_used;
+ other.source_buffer = nullptr;
+ other.float_buffer = nullptr;
+ }
+
+ virtual ~FloatImageBuffer()
+ {
+ IMB_freeImBuf(float_buffer);
+ float_buffer = nullptr;
+ source_buffer = nullptr;
+ }
+
+ FloatImageBuffer &operator=(FloatImageBuffer &&other) noexcept
+ {
+ this->source_buffer = other.source_buffer;
+ this->float_buffer = other.float_buffer;
+ is_used = other.is_used;
+ other.source_buffer = nullptr;
+ other.float_buffer = nullptr;
+ return *this;
+ }
+};
+
+struct FloatBufferCache {
+ private:
+ blender::Vector<FloatImageBuffer> cache_;
+
+ public:
+ ImBuf *ensure_float_buffer(ImBuf *image_buffer)
+ {
+ /* Check if we can use the float buffer of the given image_buffer. */
+ if (image_buffer->rect_float != nullptr) {
+ return image_buffer;
+ }
+
+ /* Do we have a cached float buffer. */
+ for (FloatImageBuffer &item : cache_) {
+ if (item.source_buffer == image_buffer) {
+ item.is_used = true;
+ return item.float_buffer;
+ }
+ }
+
+ /* Generate a new float buffer. */
+ IMB_float_from_rect(image_buffer);
+ ImBuf *new_imbuf = IMB_allocImBuf(image_buffer->x, image_buffer->y, image_buffer->planes, 0);
+ new_imbuf->rect_float = image_buffer->rect_float;
+ new_imbuf->flags |= IB_rectfloat;
+ new_imbuf->mall |= IB_rectfloat;
+ image_buffer->rect_float = nullptr;
+ image_buffer->flags &= ~IB_rectfloat;
+ image_buffer->mall &= ~IB_rectfloat;
+
+ cache_.append(FloatImageBuffer(image_buffer, new_imbuf));
+ return new_imbuf;
+ }
+
+ void reset_usage_flags()
+ {
+ for (FloatImageBuffer &buffer : cache_) {
+ buffer.is_used = false;
+ }
+ }
+
+ void mark_used(const ImBuf *image_buffer)
+ {
+ for (FloatImageBuffer &item : cache_) {
+ if (item.source_buffer == image_buffer) {
+ item.is_used = true;
+ return;
+ }
+ }
+ }
+
+ void remove_unused_buffers()
+ {
+ for (int64_t i = cache_.size() - 1; i >= 0; i--) {
+ if (!cache_[i].is_used) {
+ cache_.remove_and_reorder(i);
+ }
+ }
+ }
+
+ void clear()
+ {
+ cache_.clear();
+ }
+};
diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh
index b9de0838fef..c727fbcd98f 100644
--- a/source/blender/draw/engines/image/image_drawing_mode.hh
+++ b/source/blender/draw/engines/image/image_drawing_mode.hh
@@ -157,6 +157,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
if (tile_buffer == nullptr) {
continue;
}
+ instance_data.float_buffers.mark_used(tile_buffer);
BKE_image_release_ibuf(image, tile_buffer, lock);
DRWShadingGroup *shsub = DRW_shgroup_create_sub(shgrp);
@@ -184,12 +185,14 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
switch (changes.get_result_code()) {
case ePartialUpdateCollectResult::FullUpdateNeeded:
instance_data.mark_all_texture_slots_dirty();
+ instance_data.float_buffers.clear();
break;
case ePartialUpdateCollectResult::NoChangesDetected:
break;
case ePartialUpdateCollectResult::PartialChangesDetected:
/* Partial update when wrap repeat is enabled is not supported. */
if (instance_data.flags.do_tile_drawing) {
+ instance_data.float_buffers.clear();
instance_data.mark_all_texture_slots_dirty();
}
else {
@@ -200,6 +203,34 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
do_full_update_for_dirty_textures(instance_data, image_user);
}
+ /**
+ * Update the float buffer in the region given by the partial update checker.
+ */
+ void do_partial_update_float_buffer(
+ ImBuf *float_buffer, PartialUpdateChecker<ImageTileData>::CollectResult &iterator) const
+ {
+ ImBuf *src = iterator.tile_data.tile_buffer;
+ BLI_assert(float_buffer->rect_float != nullptr);
+ BLI_assert(float_buffer->rect == nullptr);
+ BLI_assert(src->rect_float == nullptr);
+ BLI_assert(src->rect != nullptr);
+
+ /* Calculate the overlap between the updated region and the buffer size. Partial Update Checker
+ * always returns a tile (256x256). Which could lay partially outside the buffer when using
+ * different resolutions.
+ */
+ rcti buffer_rect;
+ BLI_rcti_init(&buffer_rect, 0, float_buffer->x, 0, float_buffer->y);
+ rcti clipped_update_region;
+ const bool has_overlap = BLI_rcti_isect(
+ &buffer_rect, &iterator.changed_region.region, &clipped_update_region);
+ if (!has_overlap) {
+ return;
+ }
+
+ IMB_float_from_rect_ex(float_buffer, src, &clipped_update_region);
+ }
+
void do_partial_update(PartialUpdateChecker<ImageTileData>::CollectResult &iterator,
IMAGE_InstanceData &instance_data) const
{
@@ -208,7 +239,11 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
if (iterator.tile_data.tile_buffer == nullptr) {
continue;
}
- const bool do_free_float_buffer = ensure_float_buffer(*iterator.tile_data.tile_buffer);
+ ImBuf *tile_buffer = ensure_float_buffer(instance_data, iterator.tile_data.tile_buffer);
+ if (tile_buffer != iterator.tile_data.tile_buffer) {
+ do_partial_update_float_buffer(tile_buffer, iterator);
+ }
+
const float tile_width = static_cast<float>(iterator.tile_data.tile_buffer->x);
const float tile_height = static_cast<float>(iterator.tile_data.tile_buffer->y);
@@ -283,7 +318,6 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
&extracted_buffer, texture_region_width, texture_region_height, 32, IB_rectfloat);
int offset = 0;
- ImBuf *tile_buffer = iterator.tile_data.tile_buffer;
for (int y = gpu_texture_region_to_update.ymin; y < gpu_texture_region_to_update.ymax;
y++) {
float yf = y / (float)texture_height;
@@ -314,10 +348,6 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
0);
imb_freerectImbuf_all(&extracted_buffer);
}
-
- if (do_free_float_buffer) {
- imb_freerectfloatImBuf(iterator.tile_data.tile_buffer);
- }
}
}
@@ -376,16 +406,12 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
* rect_float as the reference-counter isn't 0. To work around this we destruct any created local
* buffers ourself.
*/
- bool ensure_float_buffer(ImBuf &image_buffer) const
+ ImBuf *ensure_float_buffer(IMAGE_InstanceData &instance_data, ImBuf *image_buffer) const
{
- if (image_buffer.rect_float == nullptr) {
- IMB_float_from_rect(&image_buffer);
- return true;
- }
- return false;
+ return instance_data.float_buffers.ensure_float_buffer(image_buffer);
}
- void do_full_update_texture_slot(const IMAGE_InstanceData &instance_data,
+ void do_full_update_texture_slot(IMAGE_InstanceData &instance_data,
const TextureInfo &texture_info,
ImBuf &texture_buffer,
ImBuf &tile_buffer,
@@ -393,7 +419,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
{
const int texture_width = texture_buffer.x;
const int texture_height = texture_buffer.y;
- const bool do_free_float_buffer = ensure_float_buffer(tile_buffer);
+ ImBuf *float_tile_buffer = ensure_float_buffer(instance_data, &tile_buffer);
/* IMB_transform works in a non-consistent space. This should be documented or fixed!.
* Construct a variant of the info_uv_to_texture that adds the texel space
@@ -424,16 +450,12 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
transform_mode = IMB_TRANSFORM_MODE_CROP_SRC;
}
- IMB_transform(&tile_buffer,
+ IMB_transform(float_tile_buffer,
&texture_buffer,
transform_mode,
IMB_FILTER_NEAREST,
uv_to_texel,
crop_rect_ptr);
-
- if (do_free_float_buffer) {
- imb_freerectfloatImBuf(&tile_buffer);
- }
}
public:
@@ -452,6 +474,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
instance_data->partial_update.ensure_image(image);
instance_data->clear_dirty_flag();
+ instance_data->float_buffers.reset_usage_flags();
/* Step: Find out which screen space textures are needed to draw on the screen. Remove the
* screen space textures that aren't needed. */
@@ -472,8 +495,10 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
add_shgroups(instance_data);
}
- void draw_finish(IMAGE_Data *UNUSED(vedata)) const override
+ void draw_finish(IMAGE_Data *vedata) const override
{
+ IMAGE_InstanceData *instance_data = vedata->instance_data;
+ instance_data->float_buffers.remove_unused_buffers();
}
void draw_scene(IMAGE_Data *vedata) const override
diff --git a/source/blender/draw/engines/image/image_instance_data.hh b/source/blender/draw/engines/image/image_instance_data.hh
index be846799293..a7ae8666968 100644
--- a/source/blender/draw/engines/image/image_instance_data.hh
+++ b/source/blender/draw/engines/image/image_instance_data.hh
@@ -8,6 +8,7 @@
#pragma once
#include "image_batches.hh"
+#include "image_buffer_cache.hh"
#include "image_partial_updater.hh"
#include "image_private.hh"
#include "image_shader_params.hh"
@@ -48,11 +49,18 @@ struct IMAGE_InstanceData {
DRWPass *depth_pass;
} passes;
+ /**
+ * Cache containing the float buffers when drawing byte images.
+ */
+ FloatBufferCache float_buffers;
+
/** \brief Transform matrix to convert a normalized screen space coordinates to texture space. */
float ss_to_texture[4][4];
TextureInfo texture_infos[SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN];
public:
+ virtual ~IMAGE_InstanceData() = default;
+
void clear_dirty_flag()
{
reset_dirty_flag(false);
@@ -102,6 +110,7 @@ struct IMAGE_InstanceData {
if (last_usage != usage) {
last_usage = usage;
reset_dirty_flag(true);
+ float_buffers.clear();
}
}
diff --git a/source/blender/draw/engines/image/image_usage.hh b/source/blender/draw/engines/image/image_usage.hh
index 2f3f0d23b6a..0643cc87304 100644
--- a/source/blender/draw/engines/image/image_usage.hh
+++ b/source/blender/draw/engines/image/image_usage.hh
@@ -23,6 +23,8 @@ struct ImageUsage {
/** IMA_ALPHA_* */
char alpha_mode;
+ const void *last_image = nullptr;
+
ImageUsage() = default;
ImageUsage(const struct Image *image, const struct ImageUser *image_user)
{
@@ -31,6 +33,7 @@ struct ImageUsage {
view = image_user ? image_user->multi_index : 0;
colorspace_settings = image->colorspace_settings;
alpha_mode = image->alpha_mode;
+ last_image = static_cast<const void *>(image);
}
bool operator==(const ImageUsage &other) const
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 7f4af43eb30..3b40a10eb2a 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -301,6 +301,7 @@ static void bake_targets_refresh(BakeTargets *targets)
Image *ima = targets->images[i].image;
if (ima) {
+ BKE_image_partial_update_mark_full_update(ima);
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
BKE_image_free_gputextures(ima);
DEG_id_tag_update(&ima->id, 0);
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 23b9c85bd5b..6b35e84ca51 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -560,6 +560,9 @@ bool IMB_alpha_affects_rgb(const struct ImBuf *ibuf);
* Create char buffer, color corrected if necessary, for ImBufs that lack one.
*/
void IMB_rect_from_float(struct ImBuf *ibuf);
+void IMB_float_from_rect_ex(struct ImBuf *dst,
+ const struct ImBuf *src,
+ const struct rcti *region_to_update);
void IMB_float_from_rect(struct ImBuf *ibuf);
/**
* No profile conversion.
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index 0bf50937674..588c92d748d 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -6,6 +6,7 @@
*/
#include "BLI_math.h"
+#include "BLI_rect.h"
#include "BLI_utildefines.h"
#include "IMB_filter.h"
@@ -752,6 +753,61 @@ void IMB_rect_from_float(ImBuf *ibuf)
ibuf->userflags &= ~IB_RECT_INVALID;
}
+void IMB_float_from_rect_ex(struct ImBuf *dst,
+ const struct ImBuf *src,
+ const rcti *region_to_update)
+{
+ BLI_assert_msg(dst->rect_float != NULL,
+ "Destination buffer should have a float buffer assigned.");
+ BLI_assert_msg(src->rect != NULL, "Source buffer should have a byte buffer assigned.");
+ BLI_assert_msg(dst->x == src->x, "Source and destination buffer should have the same dimension");
+ BLI_assert_msg(dst->y == src->y, "Source and destination buffer should have the same dimension");
+ BLI_assert_msg(dst->channels = 4, "Destination buffer should have 4 channels.");
+ BLI_assert_msg(region_to_update->xmin >= 0,
+ "Region to update should be clipped to the given buffers.");
+ BLI_assert_msg(region_to_update->ymin >= 0,
+ "Region to update should be clipped to the given buffers.");
+ BLI_assert_msg(region_to_update->xmax <= dst->x,
+ "Region to update should be clipped to the given buffers.");
+ BLI_assert_msg(region_to_update->ymax <= dst->y,
+ "Region to update should be clipped to the given buffers.");
+
+ float *rect_float = dst->rect_float;
+ rect_float += (region_to_update->xmin + region_to_update->ymin * dst->x) * 4;
+ unsigned char *rect = (unsigned char *)src->rect;
+ rect += (region_to_update->xmin + region_to_update->ymin * dst->x) * 4;
+ const int region_width = BLI_rcti_size_x(region_to_update);
+ const int region_height = BLI_rcti_size_y(region_to_update);
+
+ /* Convert byte buffer to float buffer without color or alpha conversion. */
+ IMB_buffer_float_from_byte(rect_float,
+ rect,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ false,
+ region_width,
+ region_height,
+ src->x,
+ dst->x);
+
+ /* Perform color space conversion from rect color space to linear. */
+ float *float_ptr = rect_float;
+ for (int i = 0; i < region_height; i++) {
+ IMB_colormanagement_colorspace_to_scene_linear(
+ float_ptr, region_width, 1, dst->channels, src->rect_colorspace, false);
+ float_ptr += 4 * dst->x;
+ }
+
+ /* Perform alpha conversion. */
+ if (IMB_alpha_affects_rgb(src)) {
+ float_ptr = rect_float;
+ for (int i = 0; i < region_height; i++) {
+ IMB_premultiply_rect_float(float_ptr, dst->channels, region_width, 1);
+ float_ptr += 4 * dst->x;
+ }
+ }
+}
+
void IMB_float_from_rect(ImBuf *ibuf)
{
float *rect_float;
@@ -775,33 +831,14 @@ void IMB_float_from_rect(ImBuf *ibuf)
}
ibuf->channels = 4;
- }
-
- /* first, create float buffer in non-linear space */
- IMB_buffer_float_from_byte(rect_float,
- (unsigned char *)ibuf->rect,
- IB_PROFILE_SRGB,
- IB_PROFILE_SRGB,
- false,
- ibuf->x,
- ibuf->y,
- ibuf->x,
- ibuf->x);
-
- /* then make float be in linear space */
- IMB_colormanagement_colorspace_to_scene_linear(
- rect_float, ibuf->x, ibuf->y, ibuf->channels, ibuf->rect_colorspace, false);
-
- /* byte buffer is straight alpha, float should always be premul */
- if (IMB_alpha_affects_rgb(ibuf)) {
- IMB_premultiply_rect_float(rect_float, ibuf->channels, ibuf->x, ibuf->y);
- }
-
- if (ibuf->rect_float == NULL) {
ibuf->rect_float = rect_float;
ibuf->mall |= IB_rectfloat;
ibuf->flags |= IB_rectfloat;
}
+
+ rcti region_to_update;
+ BLI_rcti_init(&region_to_update, 0, ibuf->x, 0, ibuf->y);
+ IMB_float_from_rect_ex(ibuf, ibuf, &region_to_update);
}
/** \} */
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index e40fafd2069..56e23278176 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -103,6 +103,7 @@ static void rna_Image_generated_update(Main *bmain, Scene *UNUSED(scene), Pointe
{
Image *ima = (Image *)ptr->owner_id;
BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_FREE);
+ BKE_image_partial_update_mark_full_update(ima);
}
static void rna_Image_colormanage_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
@@ -141,6 +142,7 @@ static void rna_Image_views_format_update(Main *bmain, Scene *scene, PointerRNA
}
BKE_image_release_ibuf(ima, ibuf, lock);
+ BKE_image_partial_update_mark_full_update(ima);
}
static void rna_ImageUser_update(Main *bmain, Scene *scene, PointerRNA *ptr)