Blender V5.0
session/display_driver.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7#include "util/half.h"
8#include "util/types.h"
9#include "util/vector.h"
10
12
13/* Info about the display device that will be used for graphics interop, so it
14 * can be verified if interop is compatible with the rendering device. */
27
28/* Handle to a native graphics API pixel buffer. If supported, the rendering device
29 * may write directly to this buffer instead of calling map_texture_buffer() and
30 * unmap_texture_buffer().
31 *
32 * This must be a pixel buffer with the specified with and height, and half float
33 * with RGBA channels. */
35 public:
38
43
44 /* Display Driver API. */
45
46 /* Assign handle. For Vulkan, this transfers ownership of the handle. */
47 void assign(GraphicsInteropDevice::Type type, int64_t handle, size_t size);
48 /* Is a handle assigned? */
49 bool is_empty() const;
50 /* Zero memory. */
51 void zero();
52 /* Clear handle. */
53 void clear();
54
55 /* Device graphics interop API. */
56
57 /* Get type of handle. */
59 /* Get size of buffer. */
60 size_t get_size() const;
61
62 /* Is there a new handle to take ownership of? */
63 bool has_new_handle() const;
64 /* Take ownership of the handle. */
66
67 /* Take ownership of zeroing the buffer. */
68 bool take_zero();
69
70 protected:
71 /* The handle is expected to be:
72 * - OpenGL: pixel buffer object ID.
73 * - Vulkan on Windows: opaque handle for VkBuffer.
74 * - Vulkan on Unix: opaque file descriptor for VkBuffer.
75 * - Metal: MTLBuffer with unified memory. */
78 bool own_handle_ = false;
79
80 /* Actual size of the memory, which must be `>= width * height * sizeof(half4)`. */
81 size_t size_ = 0;
82
83 /* Clear the entire buffer before doing partial write to it. */
84 bool need_zero_ = false;
85};
86
87/* Display driver for efficient interactive display of renders.
88 *
89 * Host applications implement this interface for viewport rendering. For best performance, we
90 * recommend:
91 * - Allocating a texture on the GPU to be interactively updated
92 * - Using the graphics interop mechanism to avoid CPU-GPU copying overhead
93 * - Using a dedicated or thread-safe graphics API context for updates, to avoid
94 * blocking the host application.
95 */
97 public:
98 DisplayDriver() = default;
99 virtual ~DisplayDriver() = default;
100
101 /* Render buffer parameters. */
102 struct Params {
103 public:
104 /* Render resolution, ignoring progressive resolution changes.
105 * The texture buffer should be allocated with this size. */
107
108 /* For border rendering, the full resolution of the render, and the offset within that larger
109 * render. */
112
113 bool modified(const Params &other) const
114 {
115 return !(full_offset == other.full_offset && full_size == other.full_size &&
116 size == other.size);
117 }
118 };
119
120 virtual void next_tile_begin() = 0;
121
122 /* Update the render from the rendering thread.
123 *
124 * Cycles periodically updates the render to be displayed. For multithreaded updates with
125 * potentially multiple rendering devices, it will call these methods as follows.
126 *
127 * if (driver.update_begin(params, width, height)) {
128 * parallel_for_each(rendering_device) {
129 * buffer = driver.map_texture_buffer();
130 * if (buffer) {
131 * fill(buffer);
132 * driver.unmap_texture_buffer();
133 * }
134 * }
135 * driver.update_end();
136 * }
137 *
138 * The parameters may dynamically change due to camera changes in the scene, and resources should
139 * be re-allocated accordingly.
140 *
141 * The width and height passed to update_begin() are the effective render resolution taking into
142 * account progressive resolution changes, which may be equal to or smaller than the params.size.
143 * For efficiency, changes in this resolution should be handled without re-allocating resources,
144 * but rather by using a subset of the full resolution buffer. */
145 virtual bool update_begin(const Params &params, const int width, const int height) = 0;
146 virtual void update_end() = 0;
147
148 /* Optionally flush outstanding display commands before ending the render loop. */
149 virtual void flush() {};
150
151 virtual half4 *map_texture_buffer() = 0;
152 virtual void unmap_texture_buffer() = 0;
153
155
156 /* Graphics interop to avoid CPU - GPU transfer. See GraphicsInteropBuffer for details. */
161
163
168
169 /* (De)activate graphics context required for editing or deleting the graphics interop
170 * object.
171 *
172 * For example, destruction of the CUDA object associated with an OpenGL requires the
173 * OpenGL context to be active. */
174 virtual void graphics_interop_activate() {};
176
177 /* Clear the display buffer by filling it with zeros. */
178 virtual void zero() = 0;
179
180 /* Draw the render using the native graphics API.
181 *
182 * Note that this may be called in parallel to updates. The implementation is responsible for
183 * mutex locking or other mechanisms to avoid conflicts.
184 *
185 * The parameters may have changed since the last update. The implementation is responsible for
186 * deciding to skip or adjust render display for such changes.
187 *
188 * Host application drawing the render buffer should use Session.draw(), which will
189 * call this method. */
190 virtual void draw(const Params &params) = 0;
191};
192
long long int int64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
virtual void update_end()=0
virtual void next_tile_begin()=0
virtual void graphics_interop_update_buffer()
virtual void zero()=0
virtual void draw(const Params &params)=0
DisplayDriver()=default
virtual half4 * map_texture_buffer()=0
virtual ~DisplayDriver()=default
GraphicsInteropBuffer graphics_interop_buffer_
virtual bool update_begin(const Params &params, const int width, const int height)=0
virtual GraphicsInteropDevice graphics_interop_get_device()
virtual void unmap_texture_buffer()=0
virtual void graphics_interop_activate()
GraphicsInteropBuffer & graphics_interop_get_buffer()
virtual void graphics_interop_deactivate()
GraphicsInteropBuffer(const GraphicsInteropBuffer &other)=delete
GraphicsInteropBuffer()=default
void assign(GraphicsInteropDevice::Type type, int64_t handle, size_t size)
GraphicsInteropBuffer & operator=(const GraphicsInteropBuffer &other)=delete
GraphicsInteropDevice::Type type_
GraphicsInteropBuffer & operator=(GraphicsInteropBuffer &&other)=delete
GraphicsInteropDevice::Type get_type() const
GraphicsInteropBuffer(GraphicsInteropBuffer &&other)=delete
#define CCL_NAMESPACE_END
ccl_device_forceinline int2 make_int2(const int x, const int y)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
bool modified(const Params &other) const
Definition half.h:60