Files
test/source/blender/draw/engines/image/image_instance.hh
Hans Goudey e51d538ee8 Refactor: Move image runtime out of DNA
Like other runtime structs, it doesn't make sense to write this
data to files. And moving it out of DNA to an allocated C++ struct
means we can use other C++ features in it, like the new Mutex
type which I switched to in this commit.

Pull Request: https://projects.blender.org/blender/blender/pulls/138551
2025-05-07 18:01:34 +02:00

131 lines
3.4 KiB
C++

/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include <DRW_render.hh>
#include "BKE_context.hh"
#include "DRW_engine.hh"
#include "image_drawing_mode.hh"
#include "image_private.hh"
#include "image_space.hh"
#include "image_space_image.hh"
#include "image_space_node.hh"
#include "BLI_math_matrix.hh"
#include "DNA_space_types.h"
namespace blender::image_engine {
static inline std::unique_ptr<AbstractSpaceAccessor> space_accessor_from_space(
SpaceLink *space_link)
{
if (space_link->spacetype == SPACE_IMAGE) {
return std::make_unique<SpaceImageAccessor>(
static_cast<SpaceImage *>(static_cast<void *>(space_link)));
}
if (space_link->spacetype == SPACE_NODE) {
return std::make_unique<SpaceNodeAccessor>(
static_cast<SpaceNode *>(static_cast<void *>(space_link)));
}
BLI_assert_unreachable();
return nullptr;
}
class Instance : public DrawEngine {
private:
std::unique_ptr<AbstractSpaceAccessor> space_;
Main *main_;
ScreenSpaceDrawingMode drawing_mode_;
public:
const ARegion *region;
State state;
Manager *manager = nullptr;
public:
Instance() : drawing_mode_(*this) {}
virtual ~Instance() = default;
StringRefNull name_get() final
{
return "UV/Image";
}
void init() final
{
const DRWContext *ctx_state = DRW_context_get();
main_ = CTX_data_main(ctx_state->evil_C);
region = ctx_state->region;
space_ = space_accessor_from_space(ctx_state->space_data);
manager = DRW_manager_get();
}
void begin_sync() final
{
drawing_mode_.begin_sync();
/* Setup full screen view matrix. */
float4x4 viewmat = math::projection::orthographic(
0.0f, float(region->winx), 0.0f, float(region->winy), 0.0f, 1.0f);
float4x4 winmat = float4x4::identity();
state.view.sync(viewmat, winmat);
state.flags.do_tile_drawing = false;
image_sync();
}
void image_sync()
{
state.image = space_->get_image(main_);
if (state.image == nullptr) {
/* Early exit, nothing to draw. */
return;
}
state.flags.do_tile_drawing = state.image->source != IMA_SRC_TILED &&
space_->use_tile_drawing();
void *lock;
ImBuf *image_buffer = space_->acquire_image_buffer(state.image, &lock);
/* Setup the matrix to go from screen UV coordinates to UV texture space coordinates. */
float image_resolution[2] = {image_buffer ? image_buffer->x : 1024.0f,
image_buffer ? image_buffer->y : 1024.0f};
space_->init_ss_to_texture_matrix(
region, state.image->runtime->backdrop_offset, image_resolution, state.ss_to_texture);
const Scene *scene = DRW_context_get()->scene;
state.sh_params.update(space_.get(), scene, state.image, image_buffer);
space_->release_buffer(state.image, image_buffer, lock);
ImageUser *iuser = space_->get_image_user();
if (state.image->rr != nullptr) {
BKE_image_multilayer_index(state.image->rr, iuser);
}
else {
BKE_image_multiview_index(state.image, iuser);
}
drawing_mode_.image_sync(state.image, iuser);
}
void object_sync(ObjectRef & /*obref*/, Manager & /*manager*/) final {}
void end_sync() final {}
void draw(Manager & /*manager */) final
{
DRW_submission_start();
drawing_mode_.draw_viewport();
drawing_mode_.draw_finish();
state.image = nullptr;
DRW_submission_end();
}
};
} // namespace blender::image_engine