/* SPDX-FileCopyrightText: 2021-2022 Blender Foundation * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include #include "session/display_driver.h" #include "util/thread.h" #include "util/unique_ptr.h" namespace blender { struct GPUContext; struct GPUFence; struct RenderEngine; struct Scene; namespace gpu { class Shader; } // namespace gpu } // namespace blender CCL_NAMESPACE_BEGIN /* Base class of shader used for display driver rendering. */ class BlenderDisplayShader { public: static constexpr const char *position_attribute_name = "pos"; static constexpr const char *tex_coord_attribute_name = "texCoord"; /* Create shader implementation suitable for the given render engine and scene configuration. */ static unique_ptr create(blender::RenderEngine &b_engine, blender::Scene &b_scene); BlenderDisplayShader() = default; virtual ~BlenderDisplayShader() = default; virtual blender::gpu::Shader *bind(const int width, const int height) = 0; virtual void unbind() = 0; /* Get attribute location for position and texture coordinate respectively. * NOTE: The shader needs to be bound to have access to those. */ virtual int get_position_attrib_location(); virtual int get_tex_coord_attrib_location(); protected: /* Get program of this display shader. * NOTE: The shader needs to be bound to have access to this. */ virtual blender::gpu::Shader *get_shader_program() = 0; /* Cached values of various OpenGL resources. */ int position_attribute_location_ = -1; int tex_coord_attribute_location_ = -1; }; class BlenderDisplaySpaceShader : public BlenderDisplayShader { public: BlenderDisplaySpaceShader(blender::RenderEngine &b_engine, blender::Scene &b_scene); blender::gpu::Shader *bind(const int width, const int height) override; void unbind() override; protected: blender::gpu::Shader *get_shader_program() override; blender::RenderEngine &b_engine_; blender::Scene &b_scene_; /* Cached values of various OpenGL resources. */ blender::gpu::Shader *shader_program_ = nullptr; }; /* Display driver implementation which is specific for Blender viewport integration. */ class BlenderDisplayDriver : public DisplayDriver { public: BlenderDisplayDriver(blender::RenderEngine &b_engine, blender::Scene &b_scene, blender::RegionView3D *b_rv3d, const bool background); ~BlenderDisplayDriver() override; void graphics_interop_activate() override; void graphics_interop_deactivate() override; void zero() override; void set_zoom(const float zoom_x, const float zoom_y); protected: void next_tile_begin() override; bool update_begin(const Params ¶ms, const int texture_width, const int texture_height) override; void update_end() override; half4 *map_texture_buffer() override; void unmap_texture_buffer() override; GraphicsInteropDevice graphics_interop_get_device() override; void graphics_interop_update_buffer() override; void draw(const Params ¶ms) override; void flush() override; /* Helper function which allocates new GPU context. */ void gpu_context_create(); bool gpu_context_enable(); void gpu_context_disable(); void gpu_context_destroy(); void gpu_context_lock(); void gpu_context_unlock(); /* Create GPU resources used by the display driver. */ bool gpu_resources_create(); /* Destroy all GPU resources which are being used by this object. */ void gpu_resources_destroy(); blender::RenderEngine &b_engine_; blender::RegionView3D *b_rv3d_; bool background_; /* Content of the display is to be filled with zeroes. */ std::atomic need_zero_ = true; unique_ptr display_shader_; /* Opaque storage for an internal state and data for tiles. */ struct Tiles; unique_ptr tiles_; blender::GPUFence *gpu_render_sync_ = nullptr; blender::GPUFence *gpu_upload_sync_ = nullptr; float2 zoom_ = make_float2(1.0f, 1.0f); thread_condition_variable has_update_cond_; thread_mutex has_update_mutex_; }; CCL_NAMESPACE_END