Blender V4.3
image_engine.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include "DRW_render.hh"
12
13#include <memory>
14#include <optional>
15
16#include "BKE_image.hh"
17#include "BKE_main.hh"
18#include "BKE_object.hh"
19
20#include "DNA_camera_types.h"
21#include "DNA_screen_types.h"
22
23#include "IMB_imbuf.hh"
24#include "IMB_imbuf_types.hh"
25
26#include "ED_image.hh"
27
28#include "GPU_batch.hh"
29
30#include "image_drawing_mode.hh"
31#include "image_engine.h"
32#include "image_private.hh"
33#include "image_space_image.hh"
34#include "image_space_node.hh"
35
37
38static std::unique_ptr<AbstractSpaceAccessor> space_accessor_from_context(
39 const DRWContextState *draw_ctx)
40{
41 const char space_type = draw_ctx->space_data->spacetype;
42 if (space_type == SPACE_IMAGE) {
43 return std::make_unique<SpaceImageAccessor>((SpaceImage *)draw_ctx->space_data);
44 }
45 if (space_type == SPACE_NODE) {
46 return std::make_unique<SpaceNodeAccessor>((SpaceNode *)draw_ctx->space_data);
47 }
49 return nullptr;
50}
51
52template<
57 typename DrawingMode = ScreenSpaceDrawingMode<OneTexture>>
59 private:
60 const DRWContextState *draw_ctx;
61 IMAGE_Data *vedata;
62 std::unique_ptr<AbstractSpaceAccessor> space;
63 DrawingMode drawing_mode;
64
65 public:
66 ImageEngine(const DRWContextState *draw_ctx, IMAGE_Data *vedata)
67 : draw_ctx(draw_ctx), vedata(vedata), space(space_accessor_from_context(draw_ctx))
68 {
69 }
70
71 virtual ~ImageEngine() = default;
72
74 {
75 IMAGE_InstanceData *instance_data = vedata->instance_data;
76 drawing_mode.begin_sync(vedata);
77
78 /* Setup full screen view matrix. */
79 const ARegion *region = draw_ctx->region;
80 float winmat[4][4], viewmat[4][4];
81 orthographic_m4(viewmat, 0.0, region->winx, 0.0, region->winy, 0.0, 1.0);
82 unit_m4(winmat);
83 instance_data->view = DRW_view_create(viewmat, winmat, nullptr, nullptr, nullptr);
84 }
85
87 {
88 IMAGE_InstanceData *instance_data = vedata->instance_data;
89 Main *bmain = CTX_data_main(draw_ctx->evil_C);
90 instance_data->image = space->get_image(bmain);
91 if (instance_data->image == nullptr) {
92 /* Early exit, nothing to draw. */
93 return;
94 }
95 instance_data->flags.do_tile_drawing = instance_data->image->source != IMA_SRC_TILED &&
96 space->use_tile_drawing();
97 void *lock;
98 ImBuf *image_buffer = space->acquire_image_buffer(instance_data->image, &lock);
99
100 /* Setup the matrix to go from screen UV coordinates to UV texture space coordinates. */
101 float image_resolution[2] = {image_buffer ? image_buffer->x : 1024.0f,
102 image_buffer ? image_buffer->y : 1024.0f};
103 space->init_ss_to_texture_matrix(draw_ctx->region,
104 instance_data->image->runtime.backdrop_offset,
105 image_resolution,
106 instance_data->ss_to_texture);
107
108 const Scene *scene = DRW_context_state_get()->scene;
109 instance_data->sh_params.update(space.get(), scene, instance_data->image, image_buffer);
110 space->release_buffer(instance_data->image, image_buffer, lock);
111
112 ImageUser *iuser = space->get_image_user();
113 if (instance_data->image->rr != nullptr) {
114 BKE_image_multilayer_index(instance_data->image->rr, iuser);
115 }
116 else {
117 BKE_image_multiview_index(instance_data->image, iuser);
118 }
119 drawing_mode.image_sync(vedata, instance_data->image, iuser);
120 }
121
123 {
124 drawing_mode.draw_finish(vedata);
125
126 IMAGE_InstanceData *instance_data = vedata->instance_data;
127 instance_data->image = nullptr;
128 }
129
131 {
132 drawing_mode.draw_viewport(vedata);
133 }
134};
135
136/* -------------------------------------------------------------------- */
140static void IMAGE_engine_init(void *ved)
141{
142 IMAGE_Data *vedata = (IMAGE_Data *)ved;
143 if (vedata->instance_data == nullptr) {
144 vedata->instance_data = MEM_new<IMAGE_InstanceData>(__func__);
145 }
146}
147
148static void IMAGE_cache_init(void *vedata)
149{
150 const DRWContextState *draw_ctx = DRW_context_state_get();
151 ImageEngine image_engine(draw_ctx, static_cast<IMAGE_Data *>(vedata));
152 image_engine.begin_sync();
153 image_engine.image_sync();
154}
155
156static void IMAGE_cache_populate(void * /*vedata*/, Object * /*ob*/)
157{
158 /* Function intentional left empty. `cache_populate` is required to be implemented. */
159}
160
161static void IMAGE_draw_scene(void *vedata)
162{
163 const DRWContextState *draw_ctx = DRW_context_state_get();
164 ImageEngine image_engine(draw_ctx, static_cast<IMAGE_Data *>(vedata));
165 image_engine.draw_viewport();
166 image_engine.draw_finish();
167}
168
169static void IMAGE_engine_free()
170{
172}
173
174static void IMAGE_instance_free(void *_instance_data)
175{
176 IMAGE_InstanceData *instance_data = reinterpret_cast<IMAGE_InstanceData *>(_instance_data);
177 MEM_delete(instance_data);
178}
179
183
184} // namespace blender::draw::image_engine
185
186extern "C" {
187
188using namespace blender::draw::image_engine;
189
191 /*next*/ nullptr,
192 /*prev*/ nullptr,
193 /*idname*/ N_("UV/Image"),
194 /*vedata_size*/ &IMAGE_data_size,
195 /*engine_init*/ &IMAGE_engine_init,
196 /*engine_free*/ &IMAGE_engine_free,
197 /*instance_free*/ &IMAGE_instance_free,
198 /*cache_init*/ &IMAGE_cache_init,
199 /*cache_populate*/ &IMAGE_cache_populate,
200 /*cache_finish*/ nullptr,
201 /*draw_scene*/ &IMAGE_draw_scene,
202 /*view_update*/ nullptr,
203 /*id_update*/ nullptr,
204 /*render_to_image*/ nullptr,
205 /*store_metadata*/ nullptr,
206};
207}
Main * CTX_data_main(const bContext *C)
RenderPass * BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser)
void BKE_image_multiview_index(const Image *ima, ImageUser *iuser)
General operations, lookup, etc. for blender objects.
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
void orthographic_m4(float mat[4][4], float left, float right, float bottom, float top, float nearClip, float farClip)
void unit_m4(float m[4][4])
Definition rct.c:1127
@ IMA_SRC_TILED
@ SPACE_NODE
@ SPACE_IMAGE
#define DRW_VIEWPORT_DATA_SIZE(ty)
Contains defines and structs used throughout the imbuf module.
volatile int lock
ImageEngine(const DRWContextState *draw_ctx, IMAGE_Data *vedata)
const DRWContextState * DRW_context_state_get()
DRWView * DRW_view_create(const float viewmat[4][4], const float winmat[4][4], const float(*culling_viewmat)[4], const float(*culling_winmat)[4], DRWCallVisibilityFn *visibility_fn)
DrawEngineType draw_engine_image_type
static void IMAGE_cache_init(void *vedata)
static void IMAGE_cache_populate(void *, Object *)
static void IMAGE_instance_free(void *_instance_data)
static void IMAGE_draw_scene(void *vedata)
static void IMAGE_engine_init(void *ved)
static std::unique_ptr< AbstractSpaceAccessor > space_accessor_from_context(const DRWContextState *draw_ctx)
static const DrawEngineDataSize IMAGE_data_size
ARegion * region
const bContext * evil_C
SpaceLink * space_data
struct blender::draw::image_engine::IMAGE_InstanceData::@205 flags
bool do_tile_drawing
should we perform tiled drawing (wrap repeat).
float ss_to_texture[4][4]
Transform matrix to convert a normalized screen space coordinates to texture space.
void update(AbstractSpaceAccessor *space, const Scene *scene, Image *image, ImBuf *image_buffer)
#define N_(msgid)