Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/engines/image/image_drawing_mode.hh
| Show First 20 Lines • Show All 151 Lines • ▼ Show 20 Lines | for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) { | ||||
| /* NOTE: `BKE_image_has_ibuf` doesn't work as it fails for render results. That could be a | /* NOTE: `BKE_image_has_ibuf` doesn't work as it fails for render results. That could be a | ||||
| * bug or a feature. For now we just acquire to determine if there is a texture. */ | * bug or a feature. For now we just acquire to determine if there is a texture. */ | ||||
| void *lock; | void *lock; | ||||
| ImBuf *tile_buffer = BKE_image_acquire_ibuf(image, &tile_user, &lock); | ImBuf *tile_buffer = BKE_image_acquire_ibuf(image, &tile_user, &lock); | ||||
| if (tile_buffer == nullptr) { | if (tile_buffer == nullptr) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| instance_data.float_buffers.mark_used(tile_buffer); | IMAGE_buffer_cache_mark_used(tile_buffer); | ||||
| BKE_image_release_ibuf(image, tile_buffer, lock); | BKE_image_release_ibuf(image, tile_buffer, lock); | ||||
| DRWShadingGroup *shsub = DRW_shgroup_create_sub(shgrp); | DRWShadingGroup *shsub = DRW_shgroup_create_sub(shgrp); | ||||
| float4 min_max_uv(tile_x, tile_y, tile_x + 1, tile_y + 1); | float4 min_max_uv(tile_x, tile_y, tile_x + 1, tile_y + 1); | ||||
| DRW_shgroup_uniform_vec4_copy(shsub, "min_max_uv", min_max_uv); | DRW_shgroup_uniform_vec4_copy(shsub, "min_max_uv", min_max_uv); | ||||
| DRW_shgroup_call_obmat(shsub, info.batch, image_mat); | DRW_shgroup_call_obmat(shsub, info.batch, image_mat); | ||||
| } | } | ||||
| } | } | ||||
| Show All 11 Lines | private: | ||||
| { | { | ||||
| PartialUpdateChecker<ImageTileData> checker( | PartialUpdateChecker<ImageTileData> checker( | ||||
| image, image_user, instance_data.partial_update.user); | image, image_user, instance_data.partial_update.user); | ||||
| PartialUpdateChecker<ImageTileData>::CollectResult changes = checker.collect_changes(); | PartialUpdateChecker<ImageTileData>::CollectResult changes = checker.collect_changes(); | ||||
| switch (changes.get_result_code()) { | switch (changes.get_result_code()) { | ||||
| case ePartialUpdateCollectResult::FullUpdateNeeded: | case ePartialUpdateCollectResult::FullUpdateNeeded: | ||||
| instance_data.mark_all_texture_slots_dirty(); | instance_data.mark_all_texture_slots_dirty(); | ||||
| instance_data.float_buffers.clear(); | |||||
| break; | break; | ||||
| case ePartialUpdateCollectResult::NoChangesDetected: | case ePartialUpdateCollectResult::NoChangesDetected: | ||||
| break; | break; | ||||
| case ePartialUpdateCollectResult::PartialChangesDetected: | case ePartialUpdateCollectResult::PartialChangesDetected: | ||||
| /* Partial update when wrap repeat is enabled is not supported. */ | /* Partial update when wrap repeat is enabled is not supported. */ | ||||
| if (instance_data.flags.do_tile_drawing) { | if (instance_data.flags.do_tile_drawing) { | ||||
| instance_data.float_buffers.clear(); | |||||
| instance_data.mark_all_texture_slots_dirty(); | instance_data.mark_all_texture_slots_dirty(); | ||||
| } | } | ||||
| else { | else { | ||||
| do_partial_update(changes, instance_data); | do_partial_update(changes, instance_data); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| do_full_update_for_dirty_textures(instance_data, image_user); | do_full_update_for_dirty_textures(instance_data, image_user); | ||||
| Show All 30 Lines | private: | ||||
| void do_partial_update(PartialUpdateChecker<ImageTileData>::CollectResult &iterator, | void do_partial_update(PartialUpdateChecker<ImageTileData>::CollectResult &iterator, | ||||
| IMAGE_InstanceData &instance_data) const | IMAGE_InstanceData &instance_data) const | ||||
| { | { | ||||
| while (iterator.get_next_change() == ePartialUpdateIterResult::ChangeAvailable) { | while (iterator.get_next_change() == ePartialUpdateIterResult::ChangeAvailable) { | ||||
| /* Quick exit when tile_buffer isn't available. */ | /* Quick exit when tile_buffer isn't available. */ | ||||
| if (iterator.tile_data.tile_buffer == nullptr) { | if (iterator.tile_data.tile_buffer == nullptr) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| ImBuf *tile_buffer = ensure_float_buffer(instance_data, iterator.tile_data.tile_buffer); | ImBuf *tile_buffer = IMAGE_buffer_cache_float_ensure(iterator.tile_data.tile_buffer); | ||||
| if (tile_buffer != iterator.tile_data.tile_buffer) { | if (tile_buffer != iterator.tile_data.tile_buffer) { | ||||
| do_partial_update_float_buffer(tile_buffer, iterator); | do_partial_update_float_buffer(tile_buffer, iterator); | ||||
| } | } | ||||
| const float tile_width = static_cast<float>(iterator.tile_data.tile_buffer->x); | 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); | const float tile_height = static_cast<float>(iterator.tile_data.tile_buffer->y); | ||||
| for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) { | for (int i = 0; i < SCREEN_SPACE_DRAWING_MODE_TEXTURE_LEN; i++) { | ||||
| ▲ Show 20 Lines • Show All 142 Lines • ▼ Show 20 Lines | LISTBASE_FOREACH (ImageTile *, image_tile_ptr, &image->tiles) { | ||||
| } | } | ||||
| do_full_update_texture_slot(instance_data, info, texture_buffer, *tile_buffer, image_tile); | do_full_update_texture_slot(instance_data, info, texture_buffer, *tile_buffer, image_tile); | ||||
| BKE_image_release_ibuf(image, tile_buffer, lock); | BKE_image_release_ibuf(image, tile_buffer, lock); | ||||
| } | } | ||||
| GPU_texture_update(info.texture, GPU_DATA_FLOAT, texture_buffer.rect_float); | GPU_texture_update(info.texture, GPU_DATA_FLOAT, texture_buffer.rect_float); | ||||
| imb_freerectImbuf_all(&texture_buffer); | imb_freerectImbuf_all(&texture_buffer); | ||||
| } | } | ||||
| /** | |||||
| * \brief Ensure that the float buffer of the given image buffer is available. | |||||
| * | |||||
| * Returns true when a float buffer was created. Somehow the sequencer cache increases the ref | |||||
| * counter, but might use a different mechanism for destructing the image, that doesn't free the | |||||
| * rect_float as the reference-counter isn't 0. To work around this we destruct any created local | |||||
| * buffers ourself. | |||||
| */ | |||||
| ImBuf *ensure_float_buffer(IMAGE_InstanceData &instance_data, ImBuf *image_buffer) const | |||||
| { | |||||
| return instance_data.float_buffers.ensure_float_buffer(image_buffer); | |||||
| } | |||||
| void do_full_update_texture_slot(IMAGE_InstanceData &instance_data, | void do_full_update_texture_slot(IMAGE_InstanceData &instance_data, | ||||
| const TextureInfo &texture_info, | const TextureInfo &texture_info, | ||||
| ImBuf &texture_buffer, | ImBuf &texture_buffer, | ||||
| ImBuf &tile_buffer, | ImBuf &tile_buffer, | ||||
| const ImageTileWrapper &image_tile) const | const ImageTileWrapper &image_tile) const | ||||
| { | { | ||||
| const int texture_width = texture_buffer.x; | const int texture_width = texture_buffer.x; | ||||
| const int texture_height = texture_buffer.y; | const int texture_height = texture_buffer.y; | ||||
| ImBuf *float_tile_buffer = ensure_float_buffer(instance_data, &tile_buffer); | ImBuf *float_tile_buffer = IMAGE_buffer_cache_float_ensure(&tile_buffer); | ||||
| /* IMB_transform works in a non-consistent space. This should be documented or fixed!. | /* 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 | * Construct a variant of the info_uv_to_texture that adds the texel space | ||||
| * transformation.*/ | * transformation.*/ | ||||
| float uv_to_texel[4][4]; | float uv_to_texel[4][4]; | ||||
| copy_m4_m4(uv_to_texel, instance_data.ss_to_texture); | copy_m4_m4(uv_to_texel, instance_data.ss_to_texture); | ||||
| float scale[3] = {static_cast<float>(texture_width) / static_cast<float>(tile_buffer.x), | 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), | static_cast<float>(texture_height) / static_cast<float>(tile_buffer.y), | ||||
| Show All 38 Lines | public: | ||||
| void cache_image(IMAGE_Data *vedata, Image *image, ImageUser *iuser) const override | void cache_image(IMAGE_Data *vedata, Image *image, ImageUser *iuser) const override | ||||
| { | { | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| IMAGE_InstanceData *instance_data = vedata->instance_data; | IMAGE_InstanceData *instance_data = vedata->instance_data; | ||||
| TextureMethod method(instance_data); | TextureMethod method(instance_data); | ||||
| instance_data->partial_update.ensure_image(image); | instance_data->partial_update.ensure_image(image); | ||||
| instance_data->clear_dirty_flag(); | 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 | /* Step: Find out which screen space textures are needed to draw on the screen. Remove the | ||||
| * screen space textures that aren't needed. */ | * screen space textures that aren't needed. */ | ||||
| const ARegion *region = draw_ctx->region; | const ARegion *region = draw_ctx->region; | ||||
| method.update_screen_space_bounds(region); | method.update_screen_space_bounds(region); | ||||
| method.update_screen_uv_bounds(); | method.update_screen_uv_bounds(); | ||||
| /* Check for changes in the image user compared to the last time. */ | /* Check for changes in the image user compared to the last time. */ | ||||
| instance_data->update_image_usage(iuser); | instance_data->update_image_usage(iuser); | ||||
| /* Step: Update the GPU textures based on the changes in the image. */ | /* Step: Update the GPU textures based on the changes in the image. */ | ||||
| instance_data->update_gpu_texture_allocations(); | instance_data->update_gpu_texture_allocations(); | ||||
| update_textures(*instance_data, image, iuser); | update_textures(*instance_data, image, iuser); | ||||
| /* Step: Add the GPU textures to the shgroup. */ | /* Step: Add the GPU textures to the shgroup. */ | ||||
| instance_data->update_batches(); | instance_data->update_batches(); | ||||
| if (!instance_data->flags.do_tile_drawing) { | if (!instance_data->flags.do_tile_drawing) { | ||||
| add_depth_shgroups(*instance_data, image, iuser); | add_depth_shgroups(*instance_data, image, iuser); | ||||
| } | } | ||||
| add_shgroups(instance_data); | add_shgroups(instance_data); | ||||
| } | } | ||||
| void draw_finish(IMAGE_Data *vedata) const override | void draw_finish(IMAGE_Data *UNUSED(vedata)) const override | ||||
| { | { | ||||
| IMAGE_InstanceData *instance_data = vedata->instance_data; | IMAGE_buffer_cache_free_unused(); | ||||
| instance_data->float_buffers.remove_unused_buffers(); | |||||
| } | } | ||||
| void draw_scene(IMAGE_Data *vedata) const override | void draw_scene(IMAGE_Data *vedata) const override | ||||
| { | { | ||||
| IMAGE_InstanceData *instance_data = vedata->instance_data; | IMAGE_InstanceData *instance_data = vedata->instance_data; | ||||
| DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); | DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); | ||||
| GPU_framebuffer_bind(dfbl->default_fb); | GPU_framebuffer_bind(dfbl->default_fb); | ||||
| Show All 15 Lines | |||||