diff options
author | Jeroen Bakker <jbakker> | 2022-01-28 10:37:12 +0300 |
---|---|---|
committer | Jeroen Bakker <jeroen@blender.org> | 2022-01-28 10:37:45 +0300 |
commit | bdd74e1e9338b18e4f80458f284d0c6a4d100f30 (patch) | |
tree | 86daecf79b6a9d0896482d7fe8d85da9a6becc81 /source/blender/draw/engines/image/image_drawing_mode_image_space.hh | |
parent | 0a32ac02e976a4723802ed09bed64c0625e889a2 (diff) |
DrawManager: Image engine support huge images.
Adding better support for drawing huge images in the image/uv editor. Also solved tearing artifacts.
The approach is that for each image/uv editor a screen space gpu texture is created that only contains
the visible pixels. When zooming or panning the gpu texture is rebuild.
Although the solution isn't memory intensive other parts of blender memory usage scales together with
the image size.
* Due to complexity we didn't implement partial updates when drawing images tiled (wrap repeat).
This could be added, but is complicated as a change in the source could mean many different
changes on the GPU texture. The work around for now is to tag all gpu textures to be dirty when
changes are detected.
Original plan was to have 4 screen space images to support panning without gpu texture creation.
For now we don't see the need to implement it as the solution is already fast. Especially when
GPU memory is shared with CPU ram.
Reviewed By: fclem
Maniphest Tasks: T92525, T92903
Differential Revision: https://developer.blender.org/D13424
Diffstat (limited to 'source/blender/draw/engines/image/image_drawing_mode_image_space.hh')
-rw-r--r-- | source/blender/draw/engines/image/image_drawing_mode_image_space.hh | 147 |
1 files changed, 0 insertions, 147 deletions
diff --git a/source/blender/draw/engines/image/image_drawing_mode_image_space.hh b/source/blender/draw/engines/image/image_drawing_mode_image_space.hh deleted file mode 100644 index 26f4bc28106..00000000000 --- a/source/blender/draw/engines/image/image_drawing_mode_image_space.hh +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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 2021, Blender Foundation. - */ - -/** \file - * \ingroup draw_engine - */ - -#pragma once - -#include "image_private.hh" - -namespace blender::draw::image_engine { - -class ImageSpaceDrawingMode : public AbstractDrawingMode { - private: - DRWPass *create_image_pass() const - { - /* Write depth is needed for background overlay rendering. Near depth is used for - * transparency checker and Far depth is used for indicating the image size. */ - DRWState state = static_cast<DRWState>(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | - DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA_PREMUL); - return DRW_pass_create("Image", state); - } - - void add_to_shgroup(AbstractSpaceAccessor *space, - DRWShadingGroup *grp, - const Image *image, - const ImBuf *image_buffer) const - { - float image_mat[4][4]; - - const DRWContextState *draw_ctx = DRW_context_state_get(); - const ARegion *region = draw_ctx->region; - space->get_image_mat(image_buffer, region, image_mat); - - GPUBatch *geom = DRW_cache_quad_get(); - - const float translate_x = image_mat[3][0]; - const float translate_y = image_mat[3][1]; - LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) { - const int tile_x = ((tile->tile_number - 1001) % 10); - const int tile_y = ((tile->tile_number - 1001) / 10); - image_mat[3][0] = (float)tile_x + translate_x; - image_mat[3][1] = (float)tile_y + translate_y; - DRW_shgroup_call_obmat(grp, geom, image_mat); - } - } - - public: - void cache_init(IMAGE_Data *vedata) const override - { - IMAGE_PassList *psl = vedata->psl; - - psl->image_pass = create_image_pass(); - } - - void cache_image(AbstractSpaceAccessor *space, - IMAGE_Data *vedata, - Image *image, - ImageUser *iuser, - ImBuf *image_buffer) const override - { - IMAGE_PassList *psl = vedata->psl; - IMAGE_StorageList *stl = vedata->stl; - IMAGE_PrivateData *pd = stl->pd; - - GPUTexture *tex_tile_data = nullptr; - space->get_gpu_textures( - image, iuser, image_buffer, &pd->texture, &pd->owns_texture, &tex_tile_data); - if (pd->texture == nullptr) { - return; - } - const bool is_tiled_texture = tex_tile_data != nullptr; - - ShaderParameters sh_params; - sh_params.use_premul_alpha = BKE_image_has_gpu_texture_premultiplied_alpha(image, - image_buffer); - const DRWContextState *draw_ctx = DRW_context_state_get(); - const Scene *scene = draw_ctx->scene; - if (scene->camera && scene->camera->type == OB_CAMERA) { - Camera *camera = static_cast<Camera *>(scene->camera->data); - copy_v2_fl2(sh_params.far_near, camera->clip_end, camera->clip_start); - } - space->get_shader_parameters(sh_params, image_buffer, is_tiled_texture); - - GPUShader *shader = IMAGE_shader_image_get(is_tiled_texture); - DRWShadingGroup *shgrp = DRW_shgroup_create(shader, psl->image_pass); - if (is_tiled_texture) { - DRW_shgroup_uniform_texture_ex(shgrp, "imageTileArray", pd->texture, GPU_SAMPLER_DEFAULT); - DRW_shgroup_uniform_texture(shgrp, "imageTileData", tex_tile_data); - } - else { - DRW_shgroup_uniform_texture_ex(shgrp, "imageTexture", pd->texture, GPU_SAMPLER_DEFAULT); - } - DRW_shgroup_uniform_vec2_copy(shgrp, "farNearDistances", sh_params.far_near); - DRW_shgroup_uniform_vec4_copy(shgrp, "color", ShaderParameters::color); - DRW_shgroup_uniform_vec4_copy(shgrp, "shuffle", sh_params.shuffle); - DRW_shgroup_uniform_int_copy(shgrp, "drawFlags", sh_params.flags); - DRW_shgroup_uniform_bool_copy(shgrp, "imgPremultiplied", sh_params.use_premul_alpha); - - add_to_shgroup(space, shgrp, image, image_buffer); - } - - void draw_finish(IMAGE_Data *vedata) const override - { - IMAGE_StorageList *stl = vedata->stl; - IMAGE_PrivateData *pd = stl->pd; - - if (pd->texture && pd->owns_texture) { - GPU_texture_free(pd->texture); - pd->owns_texture = false; - } - pd->texture = nullptr; - } - - void draw_scene(IMAGE_Data *vedata) const override - { - IMAGE_PassList *psl = vedata->psl; - IMAGE_PrivateData *pd = vedata->stl->pd; - - DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); - GPU_framebuffer_bind(dfbl->default_fb); - static float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - GPU_framebuffer_clear_color_depth(dfbl->default_fb, clear_col, 1.0); - - DRW_view_set_active(pd->view); - DRW_draw_pass(psl->image_pass); - DRW_view_set_active(nullptr); - } -}; - -} // namespace blender::draw::image_engine |