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:
authorJeroen Bakker <jeroen@blender.org>2022-03-01 10:40:08 +0300
committerJeroen Bakker <jeroen@blender.org>2022-03-01 10:41:25 +0300
commit5e9c1feb8aff0ca40eff6689f9bf6a9678711a9e (patch)
tree90d6da9466714511a49c536886bcfd08ca556239 /source/blender/draw/engines/image/image_drawing_mode.hh
parent91de337dc5704d6a74a7aed76e2487187e559e8d (diff)
Image Engine: Performance 8 byte images.
Previously we used to cache a float image representation of the image in rect_float. This adds some incorrect behavior as many areas only expect one of these buffers to be used. This patch stores float buffers inside the image engine. This is done per instance. In the future we should consider making a global cache.
Diffstat (limited to 'source/blender/draw/engines/image/image_drawing_mode.hh')
-rw-r--r--source/blender/draw/engines/image/image_drawing_mode.hh64
1 files changed, 44 insertions, 20 deletions
diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh
index ccb0f3e963a..f0f7f221069 100644
--- a/source/blender/draw/engines/image/image_drawing_mode.hh
+++ b/source/blender/draw/engines/image/image_drawing_mode.hh
@@ -172,6 +172,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);
@@ -199,12 +200,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 {
@@ -215,6 +218,33 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
do_full_update_for_dirty_textures(instance_data, image_user);
}
+ /**
+ * Update the float buffer.
+ *
+ * TODO(jbakker): This is a very expensive operation and should be optimized to perform the
+ * color space conversion + alpha premultiplication on a part of the buffer.
+ * Basically perform a float_from_rect on a given rectangle.
+ */
+ void do_partial_update_float_buffer(
+ ImBuf *float_buffer, PartialUpdateChecker<ImageTileData>::CollectResult &iterator) const
+ {
+#if 0
+ ImBuf *src = iterator.tile_data.tile_buffer;
+ src->rect_float = float_buffer->rect_float;
+ IMB_float_from_rect(src);
+
+ src->rect_float = nullptr;
+#else
+ ImBuf *src = iterator.tile_data.tile_buffer;
+ BLI_assert(float_buffer->float_rect != nullptr);
+ BLI_assert(float_buffer->rect == nullptr);
+ BLI_assert(src->float_rect == nullptr);
+ BLI_assert(src->rect != nullptr);
+ IMB_float_from_rect_ex(float_buffer, src, &iterator.changed_region.region);
+
+#endif
+ }
+
void do_partial_update(PartialUpdateChecker<ImageTileData>::CollectResult &iterator,
IMAGE_InstanceData &instance_data) const
{
@@ -223,7 +253,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);
@@ -299,7 +333,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;
@@ -330,10 +363,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);
- }
}
}
@@ -392,16 +421,12 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
* rect_float as the refcounter 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,
@@ -409,7 +434,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
@@ -440,16 +465,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:
@@ -468,6 +489,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. */
@@ -488,8 +510,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