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