68 rctf new_clipping_uv_bounds;
80 rcti new_clipping_bounds;
113 struct TextureInfoBounds {
141 float2 region_uv_span = region_uv_max - region_uv_min;
147 assign_texture_infos_by_uv_bounds(info_bounds, unassigned_textures);
148 assign_unused_texture_infos(info_bounds, unassigned_textures);
151 rctf region_uv_bounds;
153 ®ion_uv_bounds, region_uv_min.x, region_uv_max.x, region_uv_min.y, region_uv_max.y);
154 update_region_bounds_from_uv_bounds(region_uv_bounds,
int2(region->
winx, region->
winy));
163 int2 texture_size(
ceil(viewport_size.x / Divisions),
ceil(viewport_size.y / Divisions));
179 float2 region_tile_uv_span = region_uv_span /
float2(
float(Divisions));
185 uv_coords[
x][
y] = region_tile_uv_span *
float2(
float(
x - 1),
float(
y - 1)) +
193 TextureInfoBounds texture_info_bounds;
194 texture_info_bounds.tile_id =
int2(
x,
y);
197 uv_coords[
x + 1][
y + 1].x,
199 uv_coords[
x + 1][
y + 1].y);
200 info_bounds.
append(texture_info_bounds);
206 void assign_texture_infos_by_uv_bounds(Vector<TextureInfoBounds> &info_bounds,
207 Vector<TextureInfo *> &r_unassigned_textures)
210 bool assigned =
false;
211 for (TextureInfoBounds &info_bound : info_bounds) {
212 if (info_bound.info ==
nullptr &&
215 info_bound.info = &info;
216 info.tile_id = info_bound.tile_id;
222 r_unassigned_textures.
append(&info);
227 void assign_unused_texture_infos(Vector<TextureInfoBounds> &info_bounds,
228 Vector<TextureInfo *> &unassigned_textures)
230 for (TextureInfoBounds &info_bound : info_bounds) {
231 if (info_bound.info ==
nullptr) {
232 info_bound.info = unassigned_textures.
pop_last();
233 info_bound.info->tile_id = info_bound.tile_id;
234 info_bound.info->need_full_update =
true;
235 info_bound.info->clipping_uv_bounds = info_bound.uv_bounds;
240 void update_region_bounds_from_uv_bounds(
const rctf ®ion_uv_bounds,
const int2 region_size)
248 if (info.tile_id ==
int2(0)) {
251 float3(info.clipping_uv_bounds.xmin, info.clipping_uv_bounds.ymin, 0.0)));
258 int2 bottom_left = tile_origin + texture_size * info.tile_id;
259 int2 top_right = bottom_left + texture_size;
260 BLI_rcti_init(&info.clipping_bounds, bottom_left.
x, top_right.
x, bottom_left.
y, top_right.
y);
265using namespace blender::bke::image::partial_update;
266using namespace blender::bke::image;
270 DRWPass *create_image_pass()
const
277 DRWPass *create_depth_pass()
const
297 float image_mat[4][4];
320 float image_mat[4][4];
325 tile_user = *image_user;
339 if (tile_buffer !=
nullptr) {
343 float4 min_max_uv(tile_x, tile_y, tile_x + 1, tile_y + 1);
380 do_partial_update(changes, instance_data);
384 do_full_update_for_dirty_textures(instance_data, image_user);
390 void do_partial_update_float_buffer(
405 rcti clipped_update_region;
407 &buffer_rect, &
iterator.changed_region.region, &clipped_update_region);
420 if (
iterator.tile_data.tile_buffer ==
nullptr) {
425 if (tile_buffer !=
iterator.tile_data.tile_buffer) {
426 do_partial_update_float_buffer(tile_buffer,
iterator);
429 const float tile_width =
float(
iterator.tile_data.tile_buffer->x);
430 const float tile_height =
float(
iterator.tile_data.tile_buffer->y);
444 rcti *changed_region_in_texel_space = &
iterator.changed_region.region;
445 rctf changed_region_in_uv_space;
447 &changed_region_in_uv_space,
448 float(changed_region_in_texel_space->
xmin) /
float(
iterator.tile_data.tile_buffer->x) +
450 float(changed_region_in_texel_space->
xmax) /
float(
iterator.tile_data.tile_buffer->x) +
452 float(changed_region_in_texel_space->
ymin) /
float(
iterator.tile_data.tile_buffer->y) +
454 float(changed_region_in_texel_space->
ymax) /
float(
iterator.tile_data.tile_buffer->y) +
456 rctf changed_overlapping_region_in_uv_space;
458 &changed_region_in_uv_space,
459 &changed_overlapping_region_in_uv_space);
460 if (!region_overlap) {
466 rcti gpu_texture_region_to_update;
468 &gpu_texture_region_to_update,
478 rcti tile_region_to_extract;
480 &tile_region_to_extract,
481 floor((changed_overlapping_region_in_uv_space.
xmin - tile_offset_x) * tile_width),
482 floor((changed_overlapping_region_in_uv_space.
xmax - tile_offset_x) * tile_width),
483 ceil((changed_overlapping_region_in_uv_space.
ymin - tile_offset_y) * tile_height),
484 ceil((changed_overlapping_region_in_uv_space.
ymax - tile_offset_y) * tile_height));
488 const int texture_region_width =
BLI_rcti_size_x(&gpu_texture_region_to_update);
489 const int texture_region_height =
BLI_rcti_size_y(&gpu_texture_region_to_update);
491 ImBuf extracted_buffer;
493 &extracted_buffer, texture_region_width, texture_region_height, 32,
IB_rectfloat);
496 for (
int y = gpu_texture_region_to_update.
ymin;
y < gpu_texture_region_to_update.
ymax;
y++)
498 float yf =
y / (
float)texture_height;
501 for (
int x = gpu_texture_region_to_update.
xmin;
x < gpu_texture_region_to_update.
xmax;
504 float xf =
x / (
float)texture_width;
519 gpu_texture_region_to_update.
xmin,
520 gpu_texture_region_to_update.
ymin,
537 do_full_update_gpu_texture(info, instance_data, image_user);
545 ImBuf texture_buffer;
551 tile_user = *image_user;
562 if (tile_buffer !=
nullptr) {
563 do_full_update_texture_slot(instance_data, info, texture_buffer, *tile_buffer, image_tile);
578 ImBuf &texture_buffer,
582 const int texture_width = texture_buffer.
x;
583 const int texture_height = texture_buffer.
y;
593 BLI_rctf_init(&texture_area, 0.0, texture_width, 0.0, texture_height);
604 const rctf *crop_rect_ptr =
nullptr;
611 crop_rect_ptr = &crop_rect;
636 TextureMethod method(instance_data);
637 method.ensure_texture_infos();
646 method.update_bounds(region);
652 method.ensure_gpu_textures_allocation();
653 update_textures(*instance_data,
image, iuser);
658 add_depth_shgroups(*instance_data,
image, iuser);
660 add_shgroups(instance_data);
676 static float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
ImBuf * BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
#define LISTBASE_FOREACH(type, var, list)
void unit_m4(float m[4][4])
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
bool BLI_rctf_isect(const struct rctf *src1, const struct rctf *src2, struct rctf *dest)
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
void BLI_rctf_transform_calc_m4_pivot_min(const rctf *dst, const rctf *src, float matrix[4][4])
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax)
bool BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest)
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
bool BLI_rctf_compare(const struct rctf *rect_a, const struct rctf *rect_b, float limit)
#define DRW_shgroup_call_obmat(shgroup, geom, obmat)
void GPU_framebuffer_clear_color_depth(GPUFrameBuffer *fb, const float clear_col[4], float clear_depth)
void GPU_framebuffer_bind(GPUFrameBuffer *framebuffer)
int GPU_texture_height(const GPUTexture *texture)
int GPU_texture_width(const GPUTexture *texture)
void GPU_texture_update_sub(GPUTexture *texture, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
void GPU_texture_update(GPUTexture *texture, eGPUDataFormat data_format, const void *data)
void IMB_float_from_rect_ex(ImBuf *dst, const ImBuf *src, const rcti *region_to_update)
void imb_freerectImbuf_all(ImBuf *ibuf)
eIMBTransformMode
Transform modes to use for IMB_transform function.
@ IMB_TRANSFORM_MODE_WRAP_REPEAT
Wrap repeat the source buffer. Only supported in with nearest filtering.
@ IMB_TRANSFORM_MODE_CROP_SRC
Crop the source buffer.
void IMB_transform(const ImBuf *src, ImBuf *dst, eIMBTransformMode mode, eIMBInterpolationFilterMode filter, const float transform_matrix[4][4], const rctf *src_crop)
Transform source image buffer onto destination image buffer using a transform matrix.
bool IMB_initImBuf(ImBuf *ibuf, unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
void IMB_gpu_clamp_half_float(ImBuf *image_buffer)
Contains defines and structs used throughout the imbuf module.
struct GPUShader GPUShader
ATTR_WARN_UNUSED_RESULT const BMVert * v
void append(const T &value)
void append(const T &value)
virtual void update_bounds(const ARegion *region)=0
Update the uv and region bounds of all texture_infos of instance_data.
virtual void ensure_gpu_textures_allocation()=0
virtual void ensure_texture_infos()=0
Ensure enough texture infos are allocated in instance_data.
BaseTextureMethod(IMAGE_InstanceData *instance_data)
IMAGE_InstanceData * instance_data
void ensure_gpu_textures_allocation() override
OneTexture(IMAGE_InstanceData *instance_data)
void ensure_texture_infos() override
Ensure enough texture infos are allocated in instance_data.
void update_bounds(const ARegion *region) override
Update the uv and region bounds of all texture_infos of instance_data.
void image_sync(IMAGE_Data *vedata, Image *image, ImageUser *iuser) const override
void draw_viewport(IMAGE_Data *vedata) const override
void draw_finish(IMAGE_Data *vedata) const override
void begin_sync(IMAGE_Data *vedata) const override
void ensure_gpu_textures_allocation() override
void ensure_texture_infos() override
Ensure enough texture infos are allocated in instance_data.
int2 gpu_texture_size() const
static const size_t TexturesRequired
static const size_t TexturesPerDimension
static const size_t VerticesPerDimension
void update_bounds(const ARegion *region) override
Update the uv and region bounds of all texture_infos of instance_data.
ScreenTileTextures(IMAGE_InstanceData *instance_data)
input_tx image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "preview_img") .compute_source("compositor_compute_preview.glsl") .do_static_compilation(true)
local_group_size(16, 16) .push_constant(Type texture
DefaultFramebufferList * DRW_viewport_framebuffer_list_get()
const float * DRW_viewport_size_get()
DefaultTextureList * DRW_viewport_texture_list_get()
const DRWContextState * DRW_context_state_get()
DRWShadingGroup * DRW_shgroup_create(GPUShader *shader, DRWPass *pass)
void DRW_shgroup_uniform_texture_ex(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex, GPUSamplerState sampler_state)
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
DRWPass * DRW_pass_create(const char *name, DRWState state)
void DRW_shgroup_uniform_ivec2_copy(DRWShadingGroup *shgroup, const char *name, const int *value)
DRWShadingGroup * DRW_shgroup_create_sub(DRWShadingGroup *shgroup)
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value)
void DRW_shgroup_uniform_vec4_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value)
void DRW_shgroup_uniform_vec2_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
void DRW_draw_pass(DRWPass *pass)
void DRW_view_set_active(const DRWView *view)
@ DRW_STATE_DEPTH_LESS_EQUAL
@ DRW_STATE_BLEND_ALPHA_PREMUL
draw_view in_light_buf[] float
@ PartialChangesDetected
Changes detected since the last time requested.
@ FullUpdateNeeded
Unable to construct partial updates. Caller should perform a full update.
@ NoChangesDetected
No changes detected since the last time requested.
@ ChangeAvailable
a chunk was available and has been loaded.
GPUShader * IMAGE_shader_image_get()
constexpr float EPSILON_UV_BOUNDS
GPUShader * IMAGE_shader_depth_get()
float4 interpolate_nearest_border_fl(const ImBuf *in, float u, float v)
CartesianBasis invert(const CartesianBasis &basis)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
MatBase< float, 4, 4 > float4x4
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< float, 3 > float3
GPUFrameBuffer * color_only_fb
GPUFrameBuffer * default_fb
static constexpr GPUSamplerState default_sampler()
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
void ensure_image(const Image *new_image)
Ensure that there is a partial update user for the given image.
const c_style_mat & ptr() const
VecBase< T, 2 > xy() const
int get_tile_y_offset() const
int get_tile_x_offset() const
TileNumber get_tile_number() const
const ePartialUpdateCollectResult get_result_code() const
CollectResult collect_changes()
Check for new changes since the last time this method was invoked for this user.
ImBuf * cached_float_buffer(ImBuf *image_buffer)
void mark_used(const ImBuf *image_buffer)
void remove_unused_buffers()
IMAGE_InstanceData * instance_data
void clear_need_full_update_flag()
struct blender::draw::image_engine::IMAGE_InstanceData::@267141255116343153226330167071100055100300207202 passes
struct blender::draw::image_engine::IMAGE_InstanceData::@056357114157266241110201011061345055116246250141 flags
void update_image_usage(const ImageUser *image_user)
FloatBufferCache float_buffers
PartialImageUpdater partial_update
bool do_tile_drawing
should we perform tiled drawing (wrap repeat).
ShaderParameters sh_params
void mark_all_texture_slots_dirty()
Vector< TextureInfo > texture_infos
GPUTexture * texture
GPU Texture for a partial region of the image editor.
gpu::Batch * batch
Batch to draw the associated text on the screen.
bool need_full_update
does this texture need a full update.
rcti clipping_bounds
area of the texture in screen space.
int2 offset() const
return the offset of the texture with the area.
void ensure_gpu_texture(int2 texture_size)
rctf clipping_uv_bounds
uv area of the texture in screen space.
struct TextureInfo TextureInfo