[Bf-blender-cvs] [decdde81ff3] temp-gpu-image-engine: Add support for tiled images.
Jeroen Bakker
noreply at git.blender.org
Fri Dec 3 10:15:09 CET 2021
Commit: decdde81ff326c4af8fe2f3d0e7ae1223189ce59
Author: Jeroen Bakker
Date: Fri Dec 3 10:14:57 2021 +0100
Branches: temp-gpu-image-engine
https://developer.blender.org/rBdecdde81ff326c4af8fe2f3d0e7ae1223189ce59
Add support for tiled images.
===================================================================
M source/blender/draw/engines/image/image_drawing_mode_screen_space.hh
M source/blender/draw/engines/image/image_private.hh
M source/blender/draw/engines/image/shaders/engine_image_vert.glsl
===================================================================
diff --git a/source/blender/draw/engines/image/image_drawing_mode_screen_space.hh b/source/blender/draw/engines/image/image_drawing_mode_screen_space.hh
index 8f6c11bbdde..15633cdcd8b 100644
--- a/source/blender/draw/engines/image/image_drawing_mode_screen_space.hh
+++ b/source/blender/draw/engines/image/image_drawing_mode_screen_space.hh
@@ -39,7 +39,7 @@ constexpr float EPSILON_UV_BOUNDS = 0.00001f;
struct PrivateDataAccessor {
IMAGE_PrivateData *pd;
IMAGE_TextureList *txl;
- PrivateDataAccessor(IMAGE_PrivateData *pd, IMAGE_TextureList *txl) : pd(pd)
+ PrivateDataAccessor(IMAGE_PrivateData *pd, IMAGE_TextureList *txl) : pd(pd), txl(txl)
{
}
@@ -115,18 +115,18 @@ struct ImageTileAccessor {
{
}
- int get_tile_number()
+ int get_tile_number() const
{
return image_tile->tile_number;
}
- int get_tile_x_offset()
+ int get_tile_x_offset() const
{
int tile_number = get_tile_number();
return (tile_number - 1001) % 10;
}
- int get_tile_y_offset()
+ int get_tile_y_offset() const
{
int tile_number = get_tile_number();
return (tile_number - 1001) / 10;
@@ -138,7 +138,7 @@ using namespace blender::bke::image::partial_update;
/* TODO: Should we use static class functions in stead of a namespace. */
namespace clipping {
-static void update_texture_slots_visibility(const AbstractSpaceAccessor *space,
+static void update_texture_slots_visibility(const AbstractSpaceAccessor *UNUSED(space),
IMAGE_PrivateData *pd)
{
pd->screen_space.texture_infos[0].visible = true;
@@ -282,6 +282,10 @@ class ScreenSpaceDrawingMode : public AbstractDrawingMode {
Image *image) const
{
while (iterator.get_next_change() == ePartialUpdateIterResult::ChangeAvailable) {
+ if (iterator.tile_data.tile_buffer == nullptr) {
+ continue;
+ }
+ ensure_float_buffer(*iterator.tile_data.tile_buffer);
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);
@@ -360,11 +364,12 @@ class ScreenSpaceDrawingMode : public AbstractDrawingMode {
for (int y = gpu_texture_region_to_update.ymin; y < gpu_texture_region_to_update.ymax;
y++) {
float yf = y / (float)texture_height;
- float v = info->uv_bounds.ymax * yf + info->uv_bounds.ymin * (1.0 - yf);
+ float v = info->uv_bounds.ymax * yf + info->uv_bounds.ymin * (1.0 - yf) - tile_offset_y;
for (int x = gpu_texture_region_to_update.xmin; x < gpu_texture_region_to_update.xmax;
x++) {
float xf = x / (float)texture_width;
- float u = info->uv_bounds.xmax * xf + info->uv_bounds.xmin * (1.0 - xf);
+ float u = info->uv_bounds.xmax * xf + info->uv_bounds.xmin * (1.0 - xf) -
+ tile_offset_x;
nearest_interpolation_color(tile_buffer,
nullptr,
&extracted_buffer.rect_float[offset * 4],
@@ -388,10 +393,6 @@ class ScreenSpaceDrawingMode : public AbstractDrawingMode {
}
}
- void do_partial_update()
- {
- }
-
void do_full_update_for_dirty_textures(IMAGE_TextureList *txl,
IMAGE_PrivateData *pd,
const ImageUser *image_user) const
@@ -404,54 +405,82 @@ class ScreenSpaceDrawingMode : public AbstractDrawingMode {
if (!info->visible) {
continue;
}
-
GPUTexture *gpu_texture = txl->screen_space.textures[i];
- const int texture_width = GPU_texture_width(gpu_texture);
- const int texture_height = GPU_texture_height(gpu_texture);
-
- ImBuf tmp;
- IMB_initImBuf(&tmp, texture_width, texture_height, 0, IB_rectfloat);
- ImageUser tile_user = *image_user;
+ do_full_update_gpu_texture(*info, gpu_texture, pd, image_user);
+ }
+ }
- LISTBASE_FOREACH (ImageTile *, image_tile_ptr, &pd->image->tiles) {
- ImageTileAccessor image_tile(image_tile_ptr);
- tile_user.tile = image_tile.get_tile_number();
- ImBuf *tile_buffer = BKE_image_acquire_ibuf(pd->image, &tile_user, NULL);
+ void do_full_update_gpu_texture(const IMAGE_ScreenSpaceTextureInfo &texture_info,
+ GPUTexture *gpu_texture,
+ IMAGE_PrivateData *pd,
+ const ImageUser *image_user) const
+ {
- if (tile_buffer == nullptr) {
- /* Couldn't load the image buffer of the tile. So continue to the next change. */
- continue;
- }
- if (tile_buffer->rect_float == nullptr) {
- IMB_float_from_rect(tile_buffer);
- }
- /* TODO(jbakker): add IMB_transform without cropping. */
- /* TODO(jbakker): add IMB_transform with repeat. */
- rctf crop;
- BLI_rctf_init(&crop, 0.0, tile_buffer->x, 0.0, tile_buffer->y);
- float uv_to_texel[4][4];
-
- /* 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
- * transformation.*/
- copy_m4_m4(uv_to_texel, info->uv_to_texture);
- float scale[3] = {static_cast<float>(texture_width) / static_cast<float>(tile_buffer->x),
- static_cast<float>(texture_height) / static_cast<float>(tile_buffer->y),
- 1.0f};
- rescale_m4(uv_to_texel, scale);
- uv_to_texel[3][0] *= texture_width;
- uv_to_texel[3][1] *= texture_height;
- invert_m4(uv_to_texel);
- IMB_transform(tile_buffer, &tmp, uv_to_texel, &crop, IMB_FILTER_NEAREST);
-
- BKE_image_release_ibuf(pd->image, tile_buffer, nullptr);
+ ImBuf texture_buffer;
+ const int texture_width = GPU_texture_width(gpu_texture);
+ const int texture_height = GPU_texture_height(gpu_texture);
+ IMB_initImBuf(&texture_buffer, texture_width, texture_height, 0, IB_rectfloat);
+ ImageUser tile_user = *image_user;
+
+ LISTBASE_FOREACH (ImageTile *, image_tile_ptr, &pd->image->tiles) {
+ const ImageTileAccessor image_tile(image_tile_ptr);
+ tile_user.tile = image_tile.get_tile_number();
+ ImBuf *tile_buffer = BKE_image_acquire_ibuf(pd->image, &tile_user, NULL);
+ if (tile_buffer == nullptr) {
+ /* Couldn't load the image buffer of the tile. */
+ continue;
}
+ do_full_update_texture_slot(texture_info, texture_buffer, *tile_buffer, image_tile);
+ BKE_image_release_ibuf(pd->image, tile_buffer, nullptr);
+ }
+ GPU_texture_update(gpu_texture, GPU_DATA_FLOAT, texture_buffer.rect_float);
+ imb_freerectImbuf_all(&texture_buffer);
+ }
- GPU_texture_update(gpu_texture, GPU_DATA_FLOAT, tmp.rect_float);
- imb_freerectImbuf_all(&tmp);
+ /**
+ * \brief Ensure that the float buffer of the given image buffer is available.
+ *
+ * TODO: Should we add a ImageBufferAccessor for cleaner access.
+ * (`image_buffer.ensure_float_buffer()`)
+ */
+ void ensure_float_buffer(ImBuf &image_buffer) const
+ {
+ if (image_buffer.rect_float == nullptr) {
+ IMB_float_from_rect(&image_buffer);
}
}
+ void do_full_update_texture_slot(const IMAGE_ScreenSpaceTextureInfo &texture_info,
+ ImBuf &texture_buffer,
+ ImBuf &tile_buffer,
+ const ImageTileAccessor &image_tile) const
+ {
+ const int texture_width = texture_buffer.x;
+ const int texture_height = texture_buffer.y;
+ ensure_float_buffer(tile_buffer);
+
+ /* TODO(jbakker): add IMB_transform without cropping. */
+ /* TODO(jbakker): add IMB_transform with repeat. */
+ rctf crop;
+ BLI_rctf_init(&crop, 0.0, tile_buffer.x, 0.0, tile_buffer.y);
+ float uv_to_texel[4][4];
+
+ /* 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
+ * transformation.*/
+ copy_m4_m4(uv_to_texel, texture_info.uv_to_texture);
+ float scale[3] = {static_cast<float>(texture_width) / static_cast<float>(tile_buffer.x),
+ static_cast<float>(texture_height) / static_cast<float>(tile_buffer.y),
+ 1.0f};
+ rescale_m4(uv_to_texel, scale);
+ uv_to_texel[3][0] += image_tile.get_tile_x_offset() / BLI_rctf_size_x(&texture_info.uv_bounds);
+ uv_to_texel[3][1] += image_tile.get_tile_y_offset() / BLI_rctf_size_y(&texture_info.uv_bounds);
+ uv_to_texel[3][0] *= texture_width;
+ uv_to_texel[3][1] *= texture_height;
+ invert_m4(uv_to_texel);
+ IMB_transform(&tile_buffer, &texture_buffer, uv_to_texel, &crop, IMB_FILTER_NEAREST);
+ }
+
public:
void cache_init(IMAGE_Data *vedata) const override
{
diff --git a/source/blender/draw/engines/image/image_private.hh b/source/blender/draw/engines/image/image_private.hh
index 132494bd966..771a7021ab2 100644
--- a/source/blender/draw/engines/image/image_private.hh
+++ b/source/blender/draw/engines/image/image_private.hh
@@ -29,9 +29,9 @@
/**
* \brief max allowed textures to use by the ScreenSpaceDrawingMode.
*
- * Technically between 4 and 16 textures could be in use.
+ * 4 textures are used to reduce uploading screen space textures when translating the image.
*/
-constexpr int SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN = 16;
+constexpr int SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN = 4;
/* Forward declarations */
extern "C" {
diff --git a/source/blender/draw/engines/image/shaders/engine_image_vert.glsl b/source/blender/draw/engines/image/shaders/engine_image_vert.glsl
index da2b1907c41..b812f08ff3a 100644
--- a/source/blender/draw/engines/image/shaders/engine_image_vert.glsl
+++ b/source/blender/draw/engines/image/shaders/engine_image_vert.glsl
@@ -29,6 +29,7 @@ void main()
position.z = IMAGE_Z_DEPTH;
gl_Position = position;
/* UDIM texture uses the world position for tile selection. */
- uvs = ((drawFlags & IMA
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list