WIP: Vulkan: Workbench #107886

Closed
Jeroen Bakker wants to merge 88 commits from Jeroen-Bakker:vulkan-draw-manager-workbench into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
96 changed files with 1270 additions and 787 deletions
Showing only changes of commit 45151faea2 - Show all commits

View File

@ -162,7 +162,7 @@ extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
* \param height: The height the window.
* \param state: The state of the window when opened.
* \param is_dialog: Stay on top of parent window, no icon in taskbar, can't be minimized.
* \param glSettings: Misc OpenGL options.
* \param gpuSettings: Misc GPU options.
* \return A handle to the new window ( == NULL if creation failed).
*/
extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
@ -174,17 +174,17 @@ extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
uint32_t height,
GHOST_TWindowState state,
bool is_dialog,
GHOST_GLSettings glSettings);
GHOST_GPUSettings gpuSettings);
/**
* Create a new off-screen context.
* Never explicitly delete the context, use #disposeContext() instead.
* \param systemhandle: The handle to the system.
* \param glSettings: Misc OpenGL options.
* \param gpuSettings: Misc GPU options.
* \return A handle to the new context ( == NULL if creation failed).
*/
extern GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemhandle,
GHOST_GLSettings glSettings);
extern GHOST_ContextHandle GHOST_CreateGPUContext(GHOST_SystemHandle systemhandle,
GHOST_GPUSettings gpuSettings);
/**
* Dispose of a context.
@ -192,8 +192,8 @@ extern GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemha
* \param contexthandle: Handle to the context to be disposed.
* \return Indication of success.
*/
extern GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
GHOST_ContextHandle contexthandle);
extern GHOST_TSuccess GHOST_DisposeGPUContext(GHOST_SystemHandle systemhandle,
GHOST_ContextHandle contexthandle);
/**
* Returns the window user data.
@ -730,24 +730,24 @@ extern GHOST_TSuccess GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle);
* \param contexthandle: The handle to the context.
* \return A success indicator.
*/
extern GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthandle);
extern GHOST_TSuccess GHOST_ActivateGPUContext(GHOST_ContextHandle contexthandle);
/**
* Release the drawing context bound to this thread.
* \param contexthandle: The handle to the context.
* \return A success indicator.
*/
extern GHOST_TSuccess GHOST_ReleaseOpenGLContext(GHOST_ContextHandle contexthandle);
extern GHOST_TSuccess GHOST_ReleaseGPUContext(GHOST_ContextHandle contexthandle);
/**
* Get the OpenGL frame-buffer handle that serves as a default frame-buffer.
* Get the GPU frame-buffer handle that serves as a default frame-buffer.
*/
extern unsigned int GHOST_GetContextDefaultOpenGLFramebuffer(GHOST_ContextHandle contexthandle);
extern unsigned int GHOST_GetContextDefaultGPUFramebuffer(GHOST_ContextHandle contexthandle);
/**
* Get the OpenGL frame-buffer handle that serves as a default frame-buffer.
* Get the GPU frame-buffer handle that serves as a default frame-buffer.
*/
extern unsigned int GHOST_GetDefaultOpenGLFramebuffer(GHOST_WindowHandle windowhandle);
extern unsigned int GHOST_GetDefaultGPUFramebuffer(GHOST_WindowHandle windowhandle);
/**
* Use multi-touch gestures if supported.
@ -1072,7 +1072,7 @@ int GHOST_XrSessionIsRunning(const GHOST_XrContextHandle xr_context);
/**
* Check if \a xr_context has a session that requires an upside-down frame-buffer (compared to
* OpenGL). If true, the render result should be flipped vertically for correct output.
* GPU). If true, the render result should be flipped vertically for correct output.
* \note Only to be called after session start, may otherwise result in a false negative.
*/
int GHOST_XrSessionNeedsUpsideDownDrawing(const GHOST_XrContextHandle xr_context);

View File

@ -230,7 +230,7 @@ class GHOST_ISystem {
* \param width: The width the window.
* \param height: The height the window.
* \param state: The state of the window when opened.
* \param glSettings: Misc OpenGL settings.
* \param gpuSettings: Misc GPU settings.
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
* \param is_dialog: Stay on top of parent window, no icon in taskbar, can't be minimized.
* \param parentWindow: Parent (embedder) window
@ -242,7 +242,7 @@ class GHOST_ISystem {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
GHOST_GLSettings glSettings,
GHOST_GPUSettings gpuSettings,
const bool exclusive = false,
const bool is_dialog = false,
const GHOST_IWindow *parentWindow = NULL) = 0;
@ -259,7 +259,7 @@ class GHOST_ISystem {
* Never explicitly delete the context, use #disposeContext() instead.
* \return The new context (or 0 if creation failed).
*/
virtual GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) = 0;
virtual GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings) = 0;
/**
* Dispose of a context.

View File

@ -64,9 +64,9 @@ typedef struct {
} GHOST_CursorBitmapRef;
typedef enum {
GHOST_glStereoVisual = (1 << 0),
GHOST_glDebugContext = (1 << 1),
} GHOST_GLFlags;
GHOST_gpuStereoVisual = (1 << 0),
GHOST_gpuDebugContext = (1 << 1),
} GHOST_GPUFlags;
typedef enum GHOST_DialogOptions {
GHOST_DialogWarning = (1 << 0),
@ -681,7 +681,7 @@ typedef struct {
typedef struct {
int flags;
GHOST_TDrawingContextType context_type;
} GHOST_GLSettings;
} GHOST_GPUSettings;
typedef enum {
/** Axis that cursor grab will wrap. */

View File

@ -135,16 +135,16 @@ void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
system->getAllDisplayDimensions(*width, *height);
}
GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemhandle,
GHOST_GLSettings glSettings)
GHOST_ContextHandle GHOST_CreateGPUContext(GHOST_SystemHandle systemhandle,
GHOST_GPUSettings gpuSettings)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
return (GHOST_ContextHandle)system->createOffscreenContext(glSettings);
return (GHOST_ContextHandle)system->createOffscreenContext(gpuSettings);
}
GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
GHOST_ContextHandle contexthandle)
GHOST_TSuccess GHOST_DisposeGPUContext(GHOST_SystemHandle systemhandle,
GHOST_ContextHandle contexthandle)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
GHOST_IContext *context = (GHOST_IContext *)contexthandle;
@ -161,7 +161,7 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
uint32_t height,
GHOST_TWindowState state,
bool is_dialog,
GHOST_GLSettings glSettings)
GHOST_GPUSettings gpuSettings)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
@ -171,7 +171,7 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
width,
height,
state,
glSettings,
gpuSettings,
false,
is_dialog,
(GHOST_IWindow *)parent_windowhandle);
@ -716,7 +716,7 @@ GHOST_TSuccess GHOST_ActivateWindowDrawingContext(GHOST_WindowHandle windowhandl
return window->activateDrawingContext();
}
GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthandle)
GHOST_TSuccess GHOST_ActivateGPUContext(GHOST_ContextHandle contexthandle)
{
GHOST_IContext *context = (GHOST_IContext *)contexthandle;
if (context) {
@ -726,21 +726,21 @@ GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthandle)
return GHOST_kFailure;
}
GHOST_TSuccess GHOST_ReleaseOpenGLContext(GHOST_ContextHandle contexthandle)
GHOST_TSuccess GHOST_ReleaseGPUContext(GHOST_ContextHandle contexthandle)
{
GHOST_IContext *context = (GHOST_IContext *)contexthandle;
return context->releaseDrawingContext();
}
uint GHOST_GetContextDefaultOpenGLFramebuffer(GHOST_ContextHandle contexthandle)
uint GHOST_GetContextDefaultGPUFramebuffer(GHOST_ContextHandle contexthandle)
{
GHOST_IContext *context = (GHOST_IContext *)contexthandle;
return context->getDefaultFramebuffer();
}
uint GHOST_GetDefaultOpenGLFramebuffer(GHOST_WindowHandle windowhandle)
uint GHOST_GetDefaultGPUFramebuffer(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;

View File

@ -397,12 +397,12 @@ GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window,
const GHOST_DisplaySetting &settings,
const bool stereoVisual)
{
GHOST_GLSettings glSettings = {0};
GHOST_GPUSettings gpuSettings = {0};
if (stereoVisual) {
glSettings.flags |= GHOST_glStereoVisual;
gpuSettings.flags |= GHOST_gpuStereoVisual;
}
glSettings.context_type = GHOST_kDrawingContextTypeOpenGL;
gpuSettings.context_type = GHOST_kDrawingContextTypeOpenGL;
/* NOTE: don't use #getCurrentDisplaySetting() because on X11 we may
* be zoomed in and the desktop may be bigger than the viewport. */
GHOST_ASSERT(m_displayManager,
@ -414,7 +414,7 @@ GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window,
settings.xPixels,
settings.yPixels,
GHOST_kWindowStateNormal,
glSettings,
gpuSettings,
true /* exclusive */);
return (*window == nullptr) ? GHOST_kFailure : GHOST_kSuccess;
}

View File

@ -101,7 +101,7 @@ class GHOST_System : public GHOST_ISystem {
* Never explicitly delete the context, use #disposeContext() instead.
* \return The new context (or 0 if creation failed).
*/
virtual GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) = 0;
virtual GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings) = 0;
/**
* Returns whether a window is valid.

View File

@ -77,7 +77,7 @@ class GHOST_SystemCocoa : public GHOST_System {
* \param width: The width the window.
* \param height: The height the window.
* \param state: The state of the window when opened.
* \param glSettings: Misc OpenGL settings.
* \param gpuSettings: Misc GPU settings.
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
* \param parentWindow: Parent (embedder) window.
* \return The new window (or 0 if creation failed).
@ -88,7 +88,7 @@ class GHOST_SystemCocoa : public GHOST_System {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
GHOST_GLSettings glSettings,
GHOST_GPUSettings gpuSettings,
const bool exclusive = false,
const bool is_dialog = false,
const GHOST_IWindow *parentWindow = NULL);
@ -98,7 +98,7 @@ class GHOST_SystemCocoa : public GHOST_System {
* Never explicitly delete the context, use #disposeContext() instead.
* \return The new context (or 0 if creation failed).
*/
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings);
GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings);
/**
* Dispose of a context.

View File

@ -696,7 +696,7 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
GHOST_GLSettings glSettings,
GHOST_GPUSettings gpuSettings,
const bool exclusive,
const bool is_dialog,
const GHOST_IWindow *parentWindow)
@ -725,9 +725,9 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
width,
height,
state,
glSettings.context_type,
glSettings.flags & GHOST_glStereoVisual,
glSettings.flags & GHOST_glDebugContext,
gpuSettings.context_type,
gpuSettings.flags & GHOST_gpuStereoVisual,
gpuSettings.flags & GHOST_gpuDebugContext,
is_dialog,
(GHOST_WindowCocoa *)parentWindow);
@ -755,11 +755,11 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title,
* Never explicitly delete the context, use #disposeContext() instead.
* \return The new context (or 0 if creation failed).
*/
GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_GLSettings glSettings)
GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_GPUSettings gpuSettings)
{
#ifdef WITH_VULKAN_BACKEND
if (glSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
const bool debug_context = (glSettings.flags & GHOST_glDebugContext) != 0;
if (gpuSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
const bool debug_context = (gpuSettings.flags & GHOST_gpuDebugContext) != 0;
GHOST_Context *context = new GHOST_ContextVK(false, NULL, 1, 2, debug_context);
if (!context->initializeDrawingContext()) {
delete context;
@ -769,7 +769,7 @@ GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_GLSettings glSet
}
#endif
GHOST_Context *context = new GHOST_ContextCGL(false, NULL, NULL, NULL, glSettings.context_type);
GHOST_Context *context = new GHOST_ContextCGL(false, NULL, NULL, NULL, gpuSettings.context_type);
if (context->initializeDrawingContext())
return context;
else

View File

@ -79,7 +79,7 @@ class GHOST_SystemHeadless : public GHOST_System {
void getAllDisplayDimensions(uint32_t & /*width*/, uint32_t & /*height*/) const override
{ /* nop */
}
GHOST_IContext *createOffscreenContext(GHOST_GLSettings /*glSettings*/) override
GHOST_IContext *createOffscreenContext(GHOST_GPUSettings /*gpuSettings*/) override
{
#ifdef __linux__
GHOST_Context *context;
@ -150,7 +150,7 @@ class GHOST_SystemHeadless : public GHOST_System {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
GHOST_GLSettings glSettings,
GHOST_GPUSettings gpuSettings,
const bool /*exclusive*/,
const bool /*is_dialog*/,
const GHOST_IWindow *parentWindow) override
@ -162,8 +162,8 @@ class GHOST_SystemHeadless : public GHOST_System {
height,
state,
parentWindow,
glSettings.context_type,
((glSettings.flags & GHOST_glStereoVisual) != 0));
gpuSettings.context_type,
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0));
}
GHOST_IWindow *getWindowUnderCursor(int32_t /*x*/, int32_t /*y*/) override

View File

@ -42,7 +42,7 @@ GHOST_IWindow *GHOST_SystemSDL::createWindow(const char *title,
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
GHOST_GLSettings glSettings,
GHOST_GPUSettings gpuSettings,
const bool exclusive,
const bool /* is_dialog */,
const GHOST_IWindow *parentWindow)
@ -56,8 +56,8 @@ GHOST_IWindow *GHOST_SystemSDL::createWindow(const char *title,
width,
height,
state,
glSettings.context_type,
((glSettings.flags & GHOST_glStereoVisual) != 0),
gpuSettings.context_type,
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0),
exclusive,
parentWindow);
@ -125,7 +125,7 @@ uint8_t GHOST_SystemSDL::getNumDisplays() const
return SDL_GetNumVideoDisplays();
}
GHOST_IContext *GHOST_SystemSDL::createOffscreenContext(GHOST_GLSettings /*glSettings*/)
GHOST_IContext *GHOST_SystemSDL::createOffscreenContext(GHOST_GPUSettings /*gpuSettings*/)
{
GHOST_Context *context = new GHOST_ContextSDL(false,
nullptr,

View File

@ -60,7 +60,7 @@ class GHOST_SystemSDL : public GHOST_System {
void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const override;
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) override;
GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings) override;
GHOST_TSuccess disposeContext(GHOST_IContext *context) override;
@ -73,7 +73,7 @@ class GHOST_SystemSDL : public GHOST_System {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
GHOST_GLSettings glSettings,
GHOST_GPUSettings gpuSettings,
const bool exclusive = false,
const bool is_dialog = false,
const GHOST_IWindow *parentWindow = nullptr) override;

View File

@ -6279,7 +6279,7 @@ static GHOST_Context *createOffscreenContext_impl(GHOST_SystemWayland *system,
return nullptr;
}
GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GLSettings glSettings)
GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GPUSettings gpuSettings)
{
#ifdef USE_EVENT_BACKGROUND_THREAD
std::lock_guard lock_server_guard{*server_mutex};
@ -6289,9 +6289,9 @@ GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GLSettings glS
wl_surface *wl_surface = wl_compositor_create_surface(wl_compositor());
#ifdef WITH_VULKAN_BACKEND
const bool debug_context = (glSettings.flags & GHOST_glDebugContext) != 0;
const bool debug_context = (gpuSettings.flags & GHOST_gpuDebugContext) != 0;
if (glSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
if (gpuSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
GHOST_Context *context = new GHOST_ContextVK(false,
GHOST_kVulkanPlatformWayland,
0,
@ -6310,7 +6310,7 @@ GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GLSettings glS
return context;
}
#else
(void)glSettings;
(void)gpuSettings;
#endif
wl_egl_window *egl_window = wl_surface ? wl_egl_window_create(wl_surface, 1, 1) : nullptr;
@ -6359,7 +6359,7 @@ GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title,
const uint32_t width,
const uint32_t height,
const GHOST_TWindowState state,
const GHOST_GLSettings glSettings,
const GHOST_GPUSettings gpuSettings,
const bool exclusive,
const bool is_dialog,
const GHOST_IWindow *parentWindow)
@ -6374,9 +6374,9 @@ GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title,
height,
state,
parentWindow,
glSettings.context_type,
gpuSettings.context_type,
is_dialog,
((glSettings.flags & GHOST_glStereoVisual) != 0),
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0),
exclusive);
if (window) {

View File

@ -157,7 +157,7 @@ class GHOST_SystemWayland : public GHOST_System {
void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const override;
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) override;
GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings) override;
GHOST_TSuccess disposeContext(GHOST_IContext *context) override;
@ -167,7 +167,7 @@ class GHOST_SystemWayland : public GHOST_System {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
GHOST_GLSettings glSettings,
GHOST_GPUSettings gpuSettings,
const bool exclusive,
const bool is_dialog,
const GHOST_IWindow *parentWindow) override;

View File

@ -224,7 +224,7 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title,
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
GHOST_GLSettings glSettings,
GHOST_GPUSettings gpuSettings,
const bool /*exclusive*/,
const bool is_dialog,
const GHOST_IWindow *parentWindow)
@ -237,11 +237,11 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title,
width,
height,
state,
glSettings.context_type,
((glSettings.flags & GHOST_glStereoVisual) != 0),
gpuSettings.context_type,
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0),
false,
(GHOST_WindowWin32 *)parentWindow,
((glSettings.flags & GHOST_glDebugContext) != 0),
((gpuSettings.flags & GHOST_gpuDebugContext) != 0),
is_dialog);
if (window->getValid()) {
@ -263,15 +263,15 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(const char *title,
* Never explicitly delete the window, use #disposeContext() instead.
* \return The new context (or 0 if creation failed).
*/
GHOST_IContext *GHOST_SystemWin32::createOffscreenContext(GHOST_GLSettings glSettings)
GHOST_IContext *GHOST_SystemWin32::createOffscreenContext(GHOST_GPUSettings gpuSettings)
{
const bool debug_context = (glSettings.flags & GHOST_glDebugContext) != 0;
const bool debug_context = (gpuSettings.flags & GHOST_gpuDebugContext) != 0;
GHOST_Context *context = nullptr;
#ifdef WITH_VULKAN_BACKEND
/* Vulkan does not need a window. */
if (glSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
if (gpuSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
context = new GHOST_ContextVK(false, (HWND)0, 1, 2, debug_context);
if (!context->initializeDrawingContext()) {

View File

@ -103,7 +103,7 @@ class GHOST_SystemWin32 : public GHOST_System {
* \param width: The width the window.
* \param height: The height the window.
* \param state: The state of the window when opened.
* \param glSettings: Misc OpenGL settings.
* \param gpuSettings: Misc GPU settings.
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
* \param parentWindow: Parent window.
* \return The new window (or 0 if creation failed).
@ -114,7 +114,7 @@ class GHOST_SystemWin32 : public GHOST_System {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
GHOST_GLSettings glSettings,
GHOST_GPUSettings gpuSettings,
const bool exclusive = false,
const bool is_dialog = false,
const GHOST_IWindow *parentWindow = 0);
@ -124,7 +124,7 @@ class GHOST_SystemWin32 : public GHOST_System {
* Never explicitly delete the window, use #disposeContext() instead.
* \return The new context (or 0 if creation failed).
*/
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings);
GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings);
/**
* Dispose of a context.

View File

@ -304,7 +304,7 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title,
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
GHOST_GLSettings glSettings,
GHOST_GPUSettings gpuSettings,
const bool exclusive,
const bool is_dialog,
const GHOST_IWindow *parentWindow)
@ -324,11 +324,11 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title,
height,
state,
(GHOST_WindowX11 *)parentWindow,
glSettings.context_type,
gpuSettings.context_type,
is_dialog,
((glSettings.flags & GHOST_glStereoVisual) != 0),
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0),
exclusive,
(glSettings.flags & GHOST_glDebugContext) != 0);
(gpuSettings.flags & GHOST_gpuDebugContext) != 0);
if (window) {
/* Both are now handle in GHOST_WindowX11.cc
@ -399,7 +399,7 @@ static GHOST_Context *create_glx_context(Display *display,
return nullptr;
}
GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSettings)
GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GPUSettings gpuSettings)
{
/* During development:
* try 4.x compatibility profile
@ -411,11 +411,11 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSetti
* try 3.3 core profile
* no fall-backs. */
const bool debug_context = (glSettings.flags & GHOST_glDebugContext) != 0;
const bool debug_context = (gpuSettings.flags & GHOST_gpuDebugContext) != 0;
GHOST_Context *context = nullptr;
#ifdef WITH_VULKAN_BACKEND
if (glSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
if (gpuSettings.context_type == GHOST_kDrawingContextTypeVulkan) {
context = new GHOST_ContextVK(
false, GHOST_kVulkanPlatformX11, 0, m_display, NULL, NULL, 1, 2, debug_context);

View File

@ -124,7 +124,7 @@ class GHOST_SystemX11 : public GHOST_System {
uint32_t width,
uint32_t height,
GHOST_TWindowState state,
GHOST_GLSettings glSettings,
GHOST_GPUSettings gpuSettings,
const bool exclusive = false,
const bool is_dialog = false,
const GHOST_IWindow *parentWindow = nullptr) override;
@ -134,7 +134,7 @@ class GHOST_SystemX11 : public GHOST_System {
* Never explicitly delete the context, use #disposeContext() instead.
* \return The new context (or 0 if creation failed).
*/
GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) override;
GHOST_IContext *createOffscreenContext(GHOST_GPUSettings gpuSettings) override;
/**
* Dispose of a context.

View File

@ -412,7 +412,7 @@ bool processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
int main(int argc, char **argv)
{
GHOST_GLSettings glSettings = {0};
GHOST_GPUSettings gpuSettings = {0};
char *title1 = "gears - main window";
char *title2 = "gears - secondary window";
GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(processEvent, NULL);
@ -433,7 +433,7 @@ int main(int argc, char **argv)
GHOST_kWindowStateNormal,
false,
GHOST_kDrawingContextTypeOpenGL,
glSettings);
gpuSettings);
if (!sMainWindow) {
printf("could not create main window\n");
exit(-1);
@ -450,7 +450,7 @@ int main(int argc, char **argv)
GHOST_kWindowStateNormal,
false,
GHOST_kDrawingContextTypeOpenGL,
glSettings);
gpuSettings);
if (!sSecondaryWindow) {
printf("could not create secondary window\n");
exit(-1);

View File

@ -406,13 +406,13 @@ Application::Application(GHOST_ISystem *system)
m_exitRequested(false),
stereo(false)
{
GHOST_GLSettings glSettings = {0};
glSettings.context_type = GHOST_kDrawingContextTypeOpenGL;
GHOST_GPUSettings gpuSettings = {0};
gpuSettings.context_type = GHOST_kDrawingContextTypeOpenGL;
fApp = this;
// Create the main window
m_mainWindow = system->createWindow(
"gears - main window", 10, 64, 320, 200, GHOST_kWindowStateNormal, glSettings);
"gears - main window", 10, 64, 320, 200, GHOST_kWindowStateNormal, gpuSettings);
if (!m_mainWindow) {
std::cout << "could not create main window\n";
@ -421,7 +421,7 @@ Application::Application(GHOST_ISystem *system)
// Create a secondary window
m_secondaryWindow = system->createWindow(
"gears - secondary window", 340, 64, 320, 200, GHOST_kWindowStateNormal, glSettings);
"gears - secondary window", 340, 64, 320, 200, GHOST_kWindowStateNormal, gpuSettings);
if (!m_secondaryWindow) {
std::cout << "could not create secondary window\n";
exit(-1);

View File

@ -306,7 +306,7 @@ MainWindow *mainwindow_new(MultiTestApp *app)
{
GHOST_SystemHandle sys = multitestapp_get_system(app);
GHOST_WindowHandle win;
GHOST_GLSettings glSettings = {0};
GHOST_GPUSettings gpuSettings = {0};
win = GHOST_CreateWindow(sys,
NULL,
@ -318,7 +318,7 @@ MainWindow *mainwindow_new(MultiTestApp *app)
GHOST_kWindowStateNormal,
false,
GHOST_kDrawingContextTypeOpenGL,
glSettings);
gpuSettings);
if (win) {
MainWindow *mw = MEM_callocN(sizeof(*mw), "mainwindow_new");
@ -557,7 +557,7 @@ static void loggerwindow_handle(void *priv, GHOST_EventHandle evt)
LoggerWindow *loggerwindow_new(MultiTestApp *app)
{
GHOST_GLSettings glSettings = {0};
GHOST_GPUSettings gpuSettings = {0};
GHOST_SystemHandle sys = multitestapp_get_system(app);
uint32_t screensize[2];
GHOST_WindowHandle win;
@ -573,7 +573,7 @@ LoggerWindow *loggerwindow_new(MultiTestApp *app)
GHOST_kWindowStateNormal,
false,
GHOST_kDrawingContextTypeOpenGL,
glSettings);
gpuSettings);
if (win) {
LoggerWindow *lw = MEM_callocN(sizeof(*lw), "loggerwindow_new");
@ -761,7 +761,7 @@ static void extrawindow_handle(void *priv, GHOST_EventHandle evt)
ExtraWindow *extrawindow_new(MultiTestApp *app)
{
GHOST_GLSettings glSettings = {0};
GHOST_GPUSettings gpuSettings = {0};
GHOST_SystemHandle sys = multitestapp_get_system(app);
GHOST_WindowHandle win;
@ -775,7 +775,7 @@ ExtraWindow *extrawindow_new(MultiTestApp *app)
GHOST_kWindowStateNormal,
false,
GHOST_kDrawingContextTypeOpenGL,
glSettings);
gpuSettings);
if (win) {
ExtraWindow *ew = MEM_callocN(sizeof(*ew), "mainwindow_new");

View File

@ -350,7 +350,7 @@ def main():
if name.rpartition(".")[2].isdigit():
continue
if not ob_eval.data.attributes.active_color:
if (not hasattr(ob_eval.data, 'attributes')) or not ob_eval.data.attributes.active_color:
print("Skipping:", name, "(no vertex colors)")
continue

View File

@ -1836,6 +1836,10 @@ def km_graph_editor(params):
("graph.delete", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("confirm", False)]}),
("graph.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
("graph.keyframe_insert", {"type": 'I', "value": 'PRESS'}, None),
("graph.keyframe_jump", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True},
{"properties": [("next", True)]}),
("graph.keyframe_jump", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True},
{"properties": [("next", False)]}),
("graph.click_insert", {"type": params.action_mouse, "value": 'CLICK', "ctrl": True}, None),
("graph.click_insert", {"type": params.action_mouse, "value": 'CLICK', "shift": True, "ctrl": True},
{"properties": [("extend", True)]}),

View File

@ -3111,7 +3111,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
*_tools_annotate,
],
'EDIT_GPENCIL': [
*_tools_gpencil_select,
*_tools_select,
_defs_view3d_generic.cursor,
None,
*_tools_transform,

View File

@ -38,6 +38,13 @@ typedef struct AssetTypeInfo {
struct AssetMetaData *BKE_asset_metadata_create(void);
void BKE_asset_metadata_free(struct AssetMetaData **asset_data);
/**
* Create a copy of the #AssetMetaData so that it can be assigned to another asset.
*
* The caller becomes the owner of the returned pointer.
*/
struct AssetMetaData *BKE_asset_metadata_copy(const struct AssetMetaData *source);
struct AssetTagEnsureResult {
struct AssetTag *tag;
/* Set to false if a tag of this name was already present. */

View File

@ -51,5 +51,8 @@ struct GeometryDeformation {
GeometryDeformation get_evaluated_curves_deformation(const Object *ob_eval, const Object &ob_orig);
GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
const Object &ob_orig);
GeometryDeformation get_evaluated_grease_pencil_drawing_deformation(const Object *ob_eval,
const Object &ob_orig,
int drawing_index);
} // namespace blender::bke::crazyspace

View File

@ -39,6 +39,38 @@ void BKE_asset_metadata_free(AssetMetaData **asset_data)
*asset_data = nullptr;
}
AssetMetaData *BKE_asset_metadata_copy(const AssetMetaData *source)
{
AssetMetaData *copy = BKE_asset_metadata_create();
copy->local_type_info = source->local_type_info;
if (source->properties) {
copy->properties = IDP_CopyProperty(source->properties);
}
BKE_asset_metadata_catalog_id_set(copy, source->catalog_id, source->catalog_simple_name);
if (source->author) {
copy->author = BLI_strdup(source->author);
}
if (source->description) {
copy->description = BLI_strdup(source->description);
}
if (source->copyright) {
copy->copyright = BLI_strdup(source->copyright);
}
if (source->license) {
copy->license = BLI_strdup(source->license);
}
BLI_duplicatelist(&copy->tags, &source->tags);
copy->active_tag = source->active_tag;
copy->tot_tags = source->tot_tags;
return copy;
}
AssetMetaData::~AssetMetaData()
{
if (properties) {

View File

@ -24,6 +24,7 @@
#include "BKE_curves.hh"
#include "BKE_editmesh.h"
#include "BKE_geometry_set.hh"
#include "BKE_grease_pencil.hh"
#include "BKE_lib_id.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_wrapper.h"
@ -662,4 +663,37 @@ GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph,
return get_evaluated_curves_deformation(ob_eval, ob_orig);
}
GeometryDeformation get_evaluated_grease_pencil_drawing_deformation(const Object *ob_eval,
const Object &ob_orig,
const int drawing_index)
{
BLI_assert(ob_orig.type == OB_GREASE_PENCIL);
const GreasePencil &grease_pencil_orig = *static_cast<const GreasePencil *>(ob_orig.data);
GreasePencilDrawingBase *drawing_base = grease_pencil_orig.drawings()[drawing_index];
GeometryDeformation deformation;
if (drawing_base->type == GP_DRAWING) {
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
/* Use the undeformed positions by default. */
deformation.positions = drawing->geometry.wrap().positions();
}
else if (drawing_base->type == GP_DRAWING_REFERENCE) {
/* TODO */
}
if (ob_eval == nullptr) {
return deformation;
}
const GeometrySet *geometry_eval = ob_eval->runtime.geometry_set_eval;
if (geometry_eval == nullptr) {
return deformation;
}
/* TODO: Read `GeometryComponentEditData` from `geometry_eval` and populate deformation with it.
*/
return deformation;
}
} // namespace blender::bke::crazyspace

View File

@ -18,8 +18,6 @@
#include "attribute_access_intern.hh"
using blender::GVArray;
/* -------------------------------------------------------------------- */
/** \name Geometry Component Implementation
* \{ */
@ -292,47 +290,43 @@ std::optional<eAttrDomain> CurveLengthFieldInput::preferred_domain(
/** \} */
} // namespace blender::bke
/* -------------------------------------------------------------------- */
/** \name Attribute Access Helper Functions
* \{ */
static void tag_component_topology_changed(void *owner)
{
blender::bke::CurvesGeometry &curves = *static_cast<blender::bke::CurvesGeometry *>(owner);
CurvesGeometry &curves = *static_cast<CurvesGeometry *>(owner);
curves.tag_topology_changed();
}
static void tag_component_curve_types_changed(void *owner)
{
blender::bke::CurvesGeometry &curves = *static_cast<blender::bke::CurvesGeometry *>(owner);
CurvesGeometry &curves = *static_cast<CurvesGeometry *>(owner);
curves.update_curve_types();
curves.tag_topology_changed();
}
static void tag_component_positions_changed(void *owner)
{
blender::bke::CurvesGeometry &curves = *static_cast<blender::bke::CurvesGeometry *>(owner);
CurvesGeometry &curves = *static_cast<CurvesGeometry *>(owner);
curves.tag_positions_changed();
}
static void tag_component_radii_changed(void *owner)
{
blender::bke::CurvesGeometry &curves = *static_cast<blender::bke::CurvesGeometry *>(owner);
CurvesGeometry &curves = *static_cast<CurvesGeometry *>(owner);
curves.tag_radii_changed();
}
static void tag_component_normals_changed(void *owner)
{
blender::bke::CurvesGeometry &curves = *static_cast<blender::bke::CurvesGeometry *>(owner);
CurvesGeometry &curves = *static_cast<CurvesGeometry *>(owner);
curves.tag_normals_changed();
}
/** \} */
namespace blender::bke {
/* -------------------------------------------------------------------- */
/** \name Attribute Provider Declaration
* \{ */
@ -590,7 +584,7 @@ static AttributeAccessorFunctions get_curves_accessor_functions()
return ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE);
};
fn.adapt_domain = [](const void *owner,
const blender::GVArray &varray,
const GVArray &varray,
const eAttrDomain from_domain,
const eAttrDomain to_domain) -> GVArray {
if (owner == nullptr) {

View File

@ -24,17 +24,6 @@
#include "BLI_cpp_type_make.hh"
using blender::float4x4;
using blender::GSpan;
using blender::IndexMask;
using blender::Map;
using blender::MutableSpan;
using blender::Set;
using blender::Span;
using blender::VectorSet;
using blender::bke::InstanceReference;
using blender::bke::Instances;
/* -------------------------------------------------------------------- */
/** \name Geometry Component Implementation
* \{ */
@ -50,7 +39,7 @@ GeometryComponent *InstancesComponent::copy() const
{
InstancesComponent *new_component = new InstancesComponent();
if (instances_ != nullptr) {
new_component->instances_ = new Instances(*instances_);
new_component->instances_ = new blender::bke::Instances(*instances_);
new_component->ownership_ = GeometryOwnershipType::Owned;
}
return new_component;
@ -99,13 +88,14 @@ blender::bke::Instances *InstancesComponent::get_for_write()
{
BLI_assert(this->is_mutable());
if (ownership_ == GeometryOwnershipType::ReadOnly) {
instances_ = new Instances(*instances_);
instances_ = new blender::bke::Instances(*instances_);
ownership_ = GeometryOwnershipType::Owned;
}
return instances_;
}
void InstancesComponent::replace(Instances *instances, GeometryOwnershipType ownership)
void InstancesComponent::replace(blender::bke::Instances *instances,
GeometryOwnershipType ownership)
{
BLI_assert(this->is_mutable());
this->clear();
@ -233,13 +223,13 @@ static AttributeAccessorFunctions get_instances_accessor_functions()
return domain == ATTR_DOMAIN_INSTANCE;
};
fn.adapt_domain = [](const void * /*owner*/,
const blender::GVArray &varray,
const GVArray &varray,
const eAttrDomain from_domain,
const eAttrDomain to_domain) {
if (from_domain == to_domain && from_domain == ATTR_DOMAIN_INSTANCE) {
return varray;
}
return blender::GVArray{};
return GVArray{};
};
return fn;
}

View File

@ -21,8 +21,6 @@
#include "attribute_access_intern.hh"
extern "C" MDeformVert *BKE_object_defgroup_data_create(ID *id);
/* -------------------------------------------------------------------- */
/** \name Geometry Component Implementation
* \{ */
@ -158,16 +156,12 @@ VArray<float3> mesh_normals_varray(const Mesh &mesh,
}
}
} // namespace blender::bke
/** \} */
/* -------------------------------------------------------------------- */
/** \name Attribute Access
* \{ */
namespace blender::bke {
template<typename T>
static void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
const VArray<T> &old_values,
@ -740,8 +734,6 @@ static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &v
return new_varray;
}
} // namespace blender::bke
static bool can_simple_adapt_for_single(const Mesh &mesh,
const eAttrDomain from_domain,
const eAttrDomain to_domain)
@ -780,10 +772,10 @@ static bool can_simple_adapt_for_single(const Mesh &mesh,
}
}
static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
const blender::GVArray &varray,
const eAttrDomain from_domain,
const eAttrDomain to_domain)
static GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
const GVArray &varray,
const eAttrDomain from_domain,
const eAttrDomain to_domain)
{
if (!varray) {
return {};
@ -798,8 +790,7 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
if (can_simple_adapt_for_single(mesh, from_domain, to_domain)) {
BUFFER_FOR_CPP_TYPE_VALUE(varray.type(), value);
varray.get_internal_single(value);
return blender::GVArray::ForSingle(
varray.type(), mesh.attributes().domain_size(to_domain), value);
return GVArray::ForSingle(varray.type(), mesh.attributes().domain_size(to_domain), value);
}
}
@ -807,11 +798,11 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
case ATTR_DOMAIN_CORNER: {
switch (to_domain) {
case ATTR_DOMAIN_POINT:
return blender::bke::adapt_mesh_domain_corner_to_point(mesh, varray);
return adapt_mesh_domain_corner_to_point(mesh, varray);
case ATTR_DOMAIN_FACE:
return blender::bke::adapt_mesh_domain_corner_to_face(mesh, varray);
return adapt_mesh_domain_corner_to_face(mesh, varray);
case ATTR_DOMAIN_EDGE:
return blender::bke::adapt_mesh_domain_corner_to_edge(mesh, varray);
return adapt_mesh_domain_corner_to_edge(mesh, varray);
default:
break;
}
@ -820,11 +811,11 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
case ATTR_DOMAIN_POINT: {
switch (to_domain) {
case ATTR_DOMAIN_CORNER:
return blender::bke::adapt_mesh_domain_point_to_corner(mesh, varray);
return adapt_mesh_domain_point_to_corner(mesh, varray);
case ATTR_DOMAIN_FACE:
return blender::bke::adapt_mesh_domain_point_to_face(mesh, varray);
return adapt_mesh_domain_point_to_face(mesh, varray);
case ATTR_DOMAIN_EDGE:
return blender::bke::adapt_mesh_domain_point_to_edge(mesh, varray);
return adapt_mesh_domain_point_to_edge(mesh, varray);
default:
break;
}
@ -833,11 +824,11 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
case ATTR_DOMAIN_FACE: {
switch (to_domain) {
case ATTR_DOMAIN_POINT:
return blender::bke::adapt_mesh_domain_face_to_point(mesh, varray);
return adapt_mesh_domain_face_to_point(mesh, varray);
case ATTR_DOMAIN_CORNER:
return blender::bke::adapt_mesh_domain_face_to_corner(mesh, varray);
return adapt_mesh_domain_face_to_corner(mesh, varray);
case ATTR_DOMAIN_EDGE:
return blender::bke::adapt_mesh_domain_face_to_edge(mesh, varray);
return adapt_mesh_domain_face_to_edge(mesh, varray);
default:
break;
}
@ -846,11 +837,11 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
case ATTR_DOMAIN_EDGE: {
switch (to_domain) {
case ATTR_DOMAIN_CORNER:
return blender::bke::adapt_mesh_domain_edge_to_corner(mesh, varray);
return adapt_mesh_domain_edge_to_corner(mesh, varray);
case ATTR_DOMAIN_POINT:
return blender::bke::adapt_mesh_domain_edge_to_point(mesh, varray);
return adapt_mesh_domain_edge_to_point(mesh, varray);
case ATTR_DOMAIN_FACE:
return blender::bke::adapt_mesh_domain_edge_to_face(mesh, varray);
return adapt_mesh_domain_edge_to_face(mesh, varray);
default:
break;
}
@ -863,8 +854,6 @@ static blender::GVArray adapt_mesh_attribute_domain(const Mesh &mesh,
return {};
}
namespace blender::bke {
static void tag_component_positions_changed(void *owner)
{
Mesh *mesh = static_cast<Mesh *>(owner);
@ -1269,9 +1258,9 @@ static AttributeAccessorFunctions get_mesh_accessor_functions()
return ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE, ATTR_DOMAIN_FACE, ATTR_DOMAIN_CORNER);
};
fn.adapt_domain = [](const void *owner,
const blender::GVArray &varray,
const GVArray &varray,
const eAttrDomain from_domain,
const eAttrDomain to_domain) -> blender::GVArray {
const eAttrDomain to_domain) -> GVArray {
if (owner == nullptr) {
return {};
}

View File

@ -1061,7 +1061,7 @@ enum ForeachDrawingMode {
static void foreach_drawing_ex(GreasePencil &grease_pencil,
int frame,
ForeachDrawingMode mode,
blender::FunctionRef<void(GreasePencilDrawing &)> function)
blender::FunctionRef<void(int, GreasePencilDrawing &)> function)
{
using namespace blender::bke::greasepencil;
@ -1089,7 +1089,7 @@ static void foreach_drawing_ex(GreasePencil &grease_pencil,
GreasePencilDrawingBase *drawing_base = drawings[index];
if (drawing_base->type == GP_DRAWING) {
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
function(*drawing);
function(index, *drawing);
}
else if (drawing_base->type == GP_DRAWING_REFERENCE) {
/* TODO */
@ -1098,13 +1098,13 @@ static void foreach_drawing_ex(GreasePencil &grease_pencil,
}
void GreasePencil::foreach_visible_drawing(
int frame, blender::FunctionRef<void(GreasePencilDrawing &)> function)
int frame, blender::FunctionRef<void(int, GreasePencilDrawing &)> function)
{
foreach_drawing_ex(*this, frame, VISIBLE, function);
}
void GreasePencil::foreach_editable_drawing(
int frame, blender::FunctionRef<void(GreasePencilDrawing &)> function)
int frame, blender::FunctionRef<void(int, GreasePencilDrawing &)> function)
{
foreach_drawing_ex(*this, frame, EDITABLE, function);
}

View File

@ -669,7 +669,7 @@ static void autotrack_context_step_cb(void *__restrict userdata,
&libmv_reference_marker);
}
else {
BLI_assert(track->pattern_match == TRACK_MATCH_PREVIOS_FRAME);
BLI_assert(track->pattern_match == TRACK_MATCH_PREVIOUS_FRAME);
autotrack_result->libmv_marker.reference_frame = libmv_current_marker->frame;
libmv_reference_marker = *libmv_current_marker;
}

View File

@ -152,6 +152,7 @@ set(GLSL_SRC
shaders/compositor_smaa_edge_detection.glsl
shaders/compositor_smaa_neighborhood_blending.glsl
shaders/compositor_split_viewer.glsl
shaders/compositor_sun_beams.glsl
shaders/compositor_symmetric_blur.glsl
shaders/compositor_symmetric_blur_variable_size.glsl
shaders/compositor_symmetric_separable_blur.glsl
@ -252,6 +253,7 @@ set(SRC_SHADER_CREATE_INFOS
shaders/infos/compositor_screen_lens_distortion_info.hh
shaders/infos/compositor_smaa_info.hh
shaders/infos/compositor_split_viewer_info.hh
shaders/infos/compositor_sun_beams_info.hh
shaders/infos/compositor_symmetric_blur_info.hh
shaders/infos/compositor_symmetric_blur_variable_size_info.hh
shaders/infos/compositor_symmetric_separable_blur_info.hh

View File

@ -0,0 +1,32 @@
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
void main()
{
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
ivec2 input_size = texture_size(input_tx);
vec2 coordinates = (vec2(texel) + vec2(0.5)) / vec2(input_size);
vec2 vector_to_source = source - coordinates;
float distance_to_source = length(vector_to_source);
vec2 direction_to_source = vector_to_source / distance_to_source;
/* We integrate from the current pixel to the source pixel, but up until the user specified
* maximum ray length. The number of integration steps is roughly equivalent to the number of
* pixels along the integration path. Assume a minimum number of steps of 1 to avoid zero
* division handling and return source pixels as is. */
float integration_length = min(distance_to_source, max_ray_length);
float integration_length_in_pixels = length(input_size) * integration_length;
int steps = max(1, int(integration_length_in_pixels));
vec2 step_vector = (direction_to_source * integration_length) / steps;
vec4 accumulated_color = vec4(0.0);
for (int i = 0; i < steps; i++) {
/* Attenuate the contributions of pixels that are further away from the source using a
* quadratic falloff. */
float weight = pow(1.0f - i / integration_length_in_pixels, 2.0);
accumulated_color += texture(input_tx, coordinates + i * step_vector) * weight;
}
imageStore(output_img, texel, accumulated_color / steps);
}

View File

@ -0,0 +1,14 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "gpu_shader_create_info.hh"
GPU_SHADER_CREATE_INFO(compositor_sun_beams)
.local_group_size(16, 16)
.push_constant(Type::VEC2, "source")
.push_constant(Type::FLOAT, "max_ray_length")
.sampler(0, ImageType::FLOAT_2D, "input_tx")
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
.compute_source("compositor_sun_beams.glsl")
.do_static_compilation(true);

View File

@ -162,15 +162,15 @@ void DRW_uniform_attrs_pool_free(struct GHash *table);
void DRW_render_context_enable(struct Render *render);
void DRW_render_context_disable(struct Render *render);
void DRW_opengl_context_create(void);
void DRW_opengl_context_destroy(void);
void DRW_opengl_context_enable(void);
void DRW_opengl_context_disable(void);
void DRW_gpu_context_create(void);
void DRW_gpu_context_destroy(void);
void DRW_gpu_context_enable(void);
void DRW_gpu_context_disable(void);
#ifdef WITH_XR_OPENXR
/* XXX: see comment on #DRW_xr_opengl_context_get() */
void *DRW_xr_opengl_context_get(void);
void *DRW_xr_gpu_context_get(void);
/* XXX: see comment on #DRW_system_gpu_context_get() */
void *DRW_system_gpu_context_get(void);
void *DRW_xr_blender_gpu_context_get(void);
void DRW_xr_drawing_begin(void);
void DRW_xr_drawing_end(void);
#endif
@ -183,19 +183,16 @@ void DRW_cache_free_old_subdiv(void);
void DRW_subdiv_free(void);
/* Never use this. Only for closing blender. */
void DRW_opengl_context_enable_ex(bool restore);
void DRW_opengl_context_disable_ex(bool restore);
void DRW_gpu_context_enable_ex(bool restore);
void DRW_gpu_context_disable_ex(bool restore);
void DRW_opengl_render_context_enable(void *re_gl_context);
void DRW_opengl_render_context_disable(void *re_gl_context);
/**
* Needs to be called AFTER #DRW_opengl_render_context_enable().
*/
void DRW_gpu_render_context_enable(void *re_gpu_context);
/**
* Needs to be called BEFORE #DRW_opengl_render_context_disable().
*/
void DRW_gpu_render_context_disable(void *re_gpu_context);
/* Render pipeline GPU context control.
* Enable system context first, then enable blender context,
* then disable blender context, then disable system context. */
void DRW_system_gpu_render_context_enable(void *re_system_gpu_context);
void DRW_system_gpu_render_context_disable(void *re_system_gpu_context);
void DRW_blender_gpu_render_context_enable(void *re_gpu_context);
void DRW_blender_gpu_render_context_disable(void *re_gpu_context);
void DRW_deferred_shader_remove(struct GPUMaterial *mat);
void DRW_deferred_shader_optimize_remove(struct GPUMaterial *mat);
@ -210,8 +207,8 @@ void DRW_drawdata_free(struct ID *id);
struct DRWData *DRW_viewport_data_create(void);
void DRW_viewport_data_free(struct DRWData *drw_data);
bool DRW_opengl_context_release(void);
void DRW_opengl_context_activate(bool drw_state);
bool DRW_gpu_context_release(void);
void DRW_gpu_context_activate(bool drw_state);
/**
* We may want to move this into a more general location.

View File

@ -62,13 +62,13 @@
(IRRADIANCE_MAX_POOL_SIZE / IRRADIANCE_SAMPLE_SIZE_Y)
/* TODO: should be replace by a more elegant alternative. */
extern void DRW_opengl_context_enable(void);
extern void DRW_opengl_context_disable(void);
extern void DRW_gpu_context_enable(void);
extern void DRW_gpu_context_disable(void);
extern void DRW_opengl_render_context_enable(void *re_gl_context);
extern void DRW_opengl_render_context_disable(void *re_gl_context);
extern void DRW_gpu_render_context_enable(void *re_gpu_context);
extern void DRW_gpu_render_context_disable(void *re_gpu_context);
extern void DRW_system_gpu_render_context_enable(void *re_system_gpu_context);
extern void DRW_system_gpu_render_context_disable(void *re_system_gpu_context);
extern void DRW_blender_gpu_render_context_enable(void *re_blender_gpu_context);
extern void DRW_blender_gpu_render_context_disable(void *re_blender_gpu_context);
typedef struct EEVEE_LightBake {
Depsgraph *depsgraph;
@ -157,7 +157,7 @@ typedef struct EEVEE_LightBake {
int frame;
/** If running in parallel (in a separate thread), use this context. */
void *gl_context, *gpu_context;
void *system_gpu_context, *blender_gpu_context;
ThreadMutex *mutex;
} EEVEE_LightBake;
@ -601,20 +601,20 @@ static void eevee_lightbake_context_enable(EEVEE_LightBake *lbake)
{
if (GPU_use_main_context_workaround() && !BLI_thread_is_main()) {
GPU_context_main_lock();
DRW_opengl_context_enable();
DRW_gpu_context_enable();
GPU_render_begin();
return;
}
if (lbake->gl_context) {
DRW_opengl_render_context_enable(lbake->gl_context);
if (lbake->gpu_context == NULL) {
lbake->gpu_context = GPU_context_create(NULL, lbake->gl_context);
if (lbake->system_gpu_context) {
DRW_system_gpu_render_context_enable(lbake->system_gpu_context);
if (lbake->blender_gpu_context == NULL) {
lbake->blender_gpu_context = GPU_context_create(NULL, lbake->system_gpu_context);
}
DRW_gpu_render_context_enable(lbake->gpu_context);
DRW_blender_gpu_render_context_enable(lbake->blender_gpu_context);
}
else {
DRW_opengl_context_enable();
DRW_gpu_context_enable();
}
GPU_render_begin();
}
@ -623,19 +623,19 @@ static void eevee_lightbake_context_disable(EEVEE_LightBake *lbake)
{
if (GPU_use_main_context_workaround() && !BLI_thread_is_main()) {
DRW_opengl_context_disable();
DRW_gpu_context_disable();
GPU_render_end();
GPU_context_main_unlock();
return;
}
if (lbake->gl_context) {
DRW_gpu_render_context_disable(lbake->gpu_context);
if (lbake->system_gpu_context) {
DRW_blender_gpu_render_context_disable(lbake->blender_gpu_context);
GPU_render_end();
DRW_opengl_render_context_disable(lbake->gl_context);
DRW_system_gpu_render_context_disable(lbake->system_gpu_context);
}
else {
DRW_opengl_context_disable();
DRW_gpu_context_disable();
GPU_render_end();
}
}
@ -788,13 +788,13 @@ wmJob *EEVEE_lightbake_job_create(wmWindowManager *wm,
lbake->scene = scene;
lbake->bmain = bmain;
lbake->view_layer_input = view_layer;
lbake->gl_context = old_lbake->gl_context;
lbake->system_gpu_context = old_lbake->system_gpu_context;
lbake->own_resources = true;
lbake->delay = delay;
lbake->frame = frame;
if (lbake->gl_context == NULL && !GPU_use_main_context_workaround()) {
lbake->gl_context = WM_opengl_context_create();
if (lbake->system_gpu_context == NULL && !GPU_use_main_context_workaround()) {
lbake->system_gpu_context = WM_system_gpu_context_create();
wm_window_reset_drawable();
}
@ -835,7 +835,7 @@ void *EEVEE_lightbake_job_data_alloc(
lbake->frame = frame;
if (run_as_job && !GPU_use_main_context_workaround()) {
lbake->gl_context = WM_opengl_context_create();
lbake->system_gpu_context = WM_system_gpu_context_create();
wm_window_reset_drawable();
}
@ -865,12 +865,12 @@ static void eevee_lightbake_delete_resources(EEVEE_LightBake *lbake)
BLI_mutex_lock(lbake->mutex);
}
if (lbake->gl_context) {
DRW_opengl_render_context_enable(lbake->gl_context);
DRW_gpu_render_context_enable(lbake->gpu_context);
if (lbake->system_gpu_context) {
DRW_system_gpu_render_context_enable(lbake->system_gpu_context);
DRW_blender_gpu_render_context_enable(lbake->blender_gpu_context);
}
else if (!lbake->resource_only) {
DRW_opengl_context_enable();
DRW_gpu_context_enable();
}
/* XXX: Free the resources contained in the view-layer data
@ -887,24 +887,24 @@ static void eevee_lightbake_delete_resources(EEVEE_LightBake *lbake)
GPU_FRAMEBUFFER_FREE_SAFE(lbake->rt_fb[i]);
}
if (lbake->gpu_context) {
DRW_gpu_render_context_disable(lbake->gpu_context);
DRW_gpu_render_context_enable(lbake->gpu_context);
GPU_context_discard(lbake->gpu_context);
if (lbake->blender_gpu_context) {
DRW_blender_gpu_render_context_disable(lbake->blender_gpu_context);
DRW_blender_gpu_render_context_enable(lbake->blender_gpu_context);
GPU_context_discard(lbake->blender_gpu_context);
}
if (lbake->gl_context && lbake->own_resources) {
if (lbake->system_gpu_context && lbake->own_resources) {
/* Delete the baking context. */
DRW_opengl_render_context_disable(lbake->gl_context);
WM_opengl_context_dispose(lbake->gl_context);
lbake->gpu_context = NULL;
lbake->gl_context = NULL;
DRW_system_gpu_render_context_disable(lbake->system_gpu_context);
WM_system_gpu_context_dispose(lbake->system_gpu_context);
lbake->blender_gpu_context = NULL;
lbake->system_gpu_context = NULL;
}
else if (lbake->gl_context) {
DRW_opengl_render_context_disable(lbake->gl_context);
else if (lbake->system_gpu_context) {
DRW_system_gpu_render_context_disable(lbake->system_gpu_context);
}
else if (!lbake->resource_only) {
DRW_opengl_context_disable();
DRW_gpu_context_disable();
}
if (!lbake->resource_only) {
@ -1490,10 +1490,10 @@ void EEVEE_lightbake_job(void *custom_data, bool *stop, bool *do_update, float *
lcache->flag |= LIGHTCACHE_BAKED;
lcache->flag &= ~LIGHTCACHE_BAKING;
/* Assume that if lbake->gl_context is NULL
/* Assume that if lbake->system_gpu_context is NULL
* we are not running in this in a job, so update
* the scene light-cache pointer before deleting it. */
if (lbake->gl_context == NULL) {
if (lbake->system_gpu_context == NULL) {
BLI_assert(BLI_thread_is_main());
EEVEE_lightbake_update(lbake);
}

View File

@ -710,7 +710,7 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved
/* If light-cache auto-update is enable we tag the relevant part
* of the cache to update and fire up a baking job. */
if (!DRW_state_is_image_render() && !DRW_state_is_opengl_render() &&
if (!DRW_state_is_image_render() && !DRW_state_is_viewport_image_render() &&
(pinfo->do_grid_update || pinfo->do_cube_update))
{
BLI_assert(draw_ctx->evil_C);

View File

@ -94,7 +94,7 @@ void EEVEE_lookdev_init(EEVEE_Data *vedata)
/* Viewport / Spheres size. */
const rcti *rect;
rcti fallback_rect;
if (DRW_state_is_opengl_render()) {
if (DRW_state_is_viewport_image_render()) {
const float *vp_size = DRW_viewport_size_get();
fallback_rect.xmax = vp_size[0];
fallback_rect.ymax = vp_size[1];

View File

@ -431,7 +431,7 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
bool is_valid = (render_pass & EEVEE_RENDERPASSES_ALL) != 0;
bool needs_color_transfer = (render_pass & EEVEE_RENDERPASSES_COLOR_PASS) != 0 &&
DRW_state_is_opengl_render();
DRW_state_is_viewport_image_render();
UNUSED_VARS(needs_color_transfer);
if ((render_pass & EEVEE_RENDER_PASS_BLOOM) != 0 &&

View File

@ -245,7 +245,7 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
* Reset for each "redraw". When rendering using OpenGL render,
* we accumulate the redraw inside the drawing loop in eevee_draw_scene().
*/
if (DRW_state_is_opengl_render()) {
if (DRW_state_is_viewport_image_render()) {
effects->taa_render_sample = 1;
}
effects->bypass_drawing = false;

View File

@ -30,7 +30,7 @@ void OVERLAY_background_cache_init(OVERLAY_Data *vedata)
float color_override[4] = {0.0f, 0.0f, 0.0f, 0.0f};
int background_type;
if (DRW_state_is_opengl_render() && !DRW_state_draw_background()) {
if (DRW_state_is_viewport_image_render() && !DRW_state_draw_background()) {
background_type = BG_SOLID;
color_override[3] = 1.0f;
}

View File

@ -23,7 +23,7 @@ class Background {
float4 color_override(0.0f, 0.0f, 0.0f, 0.0f);
int background_type;
if (DRW_state_is_opengl_render() && !DRW_state_draw_background()) {
if (DRW_state_is_viewport_image_render() && !DRW_state_draw_background()) {
background_type = BG_SOLID;
color_override[3] = 1.0f;
}

View File

@ -630,7 +630,7 @@ static void workbench_draw_scene(void *ved)
WORKBENCH_Data *vedata = ved;
WORKBENCH_PrivateData *wpd = vedata->stl->wpd;
if (DRW_state_is_opengl_render()) {
if (DRW_state_is_viewport_image_render()) {
while (wpd->taa_sample < max_ii(1, wpd->taa_sample_len)) {
workbench_update_world_ubo(wpd);

View File

@ -944,7 +944,7 @@ bool DRW_state_is_scene_render(void);
/**
* Whether we are rendering simple opengl render
*/
bool DRW_state_is_opengl_render(void);
bool DRW_state_is_viewport_image_render(void);
bool DRW_state_is_playback(void);
/**
* Is the user navigating the region.

View File

@ -204,7 +204,8 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr
/* Get the visible drawings. */
Vector<const GreasePencilDrawing *> drawings;
grease_pencil.foreach_visible_drawing(
cfra, [&](GreasePencilDrawing &drawing) { drawings.append(&drawing); });
cfra,
[&](int /*drawing_index*/, GreasePencilDrawing &drawing) { drawings.append(&drawing); });
/* First, count how many vertices and triangles are needed for the whole object. Also record the
* offsets into the curves for the vertices and triangles. */

View File

@ -61,7 +61,7 @@ BLI_INLINE void DRW_ibo_request(GPUBatch *batch, GPUIndexBuf **ibo)
BLI_INLINE bool DRW_ibo_requested(GPUIndexBuf *ibo)
{
/* TODO: do not rely on data uploaded. This prevents multi-threading.
* (need access to a OpenGL context). */
* (need access to a GPU context). */
return (ibo != NULL && !GPU_indexbuf_is_init(ibo));
}

View File

@ -116,7 +116,7 @@ static struct {
static void drw_state_prepare_clean_for_draw(DRWManager *dst)
{
memset(dst, 0x0, offsetof(DRWManager, gl_context));
memset(dst, 0x0, offsetof(DRWManager, system_gpu_context));
}
/* This function is used to reset draw manager to a state
@ -126,7 +126,7 @@ static void drw_state_prepare_clean_for_draw(DRWManager *dst)
#ifdef DEBUG
static void drw_state_ensure_not_reused(DRWManager *dst)
{
memset(dst, 0xff, offsetof(DRWManager, gl_context));
memset(dst, 0xff, offsetof(DRWManager, system_gpu_context));
}
#endif
@ -1341,7 +1341,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
/* XXX Really nasty locking. But else this could
* be executed by the material previews thread
* while rendering a viewport. */
BLI_ticket_mutex_lock(DST.gl_context_mutex);
BLI_ticket_mutex_lock(DST.system_gpu_context_mutex);
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
@ -1378,7 +1378,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx)
drw_manager_exit(&DST);
BLI_ticket_mutex_unlock(DST.gl_context_mutex);
BLI_ticket_mutex_unlock(DST.system_gpu_context_mutex);
}
/* update a viewport which belongs to a GPUOffscreen */
@ -1905,7 +1905,7 @@ static void DRW_render_gpencil_to_image(RenderEngine *engine,
void DRW_render_gpencil(RenderEngine *engine, Depsgraph *depsgraph)
{
/* This function should only be called if there are grease pencil objects,
* especially important to avoid failing in background renders without OpenGL context. */
* especially important to avoid failing in background renders without GPU context. */
BLI_assert(DRW_render_check_grease_pencil(depsgraph));
Scene *scene = DEG_get_evaluated_scene(depsgraph);
@ -2964,7 +2964,7 @@ bool DRW_state_is_scene_render(void)
return DST.options.is_scene_render;
}
bool DRW_state_is_opengl_render(void)
bool DRW_state_is_viewport_image_render(void)
{
return DST.options.is_image_render && !DST.options.is_scene_render;
}
@ -3119,14 +3119,14 @@ void DRW_engines_free(void)
{
drw_registered_engines_free();
if (DST.gl_context == NULL) {
if (DST.system_gpu_context == NULL) {
/* Nothing has been setup. Nothing to clear.
* Otherwise, DRW_opengl_context_enable can
* Otherwise, DRW_gpu_context_enable can
* create a context in background mode. (see #62355) */
return;
}
DRW_opengl_context_enable();
DRW_gpu_context_enable();
DRW_TEXTURE_FREE_SAFE(g_select_buffer.texture_depth);
GPU_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer_depth_only);
@ -3152,59 +3152,59 @@ void DRW_engines_free(void)
GPU_draw_list_discard(DST.draw_list);
}
DRW_opengl_context_disable();
DRW_gpu_context_disable();
}
void DRW_render_context_enable(Render *render)
{
if (G.background && DST.gl_context == NULL) {
WM_init_opengl();
if (G.background && DST.system_gpu_context == NULL) {
WM_init_gpu();
}
GPU_render_begin();
if (GPU_use_main_context_workaround()) {
GPU_context_main_lock();
DRW_opengl_context_enable();
DRW_gpu_context_enable();
return;
}
void *re_gl_context = RE_gl_context_get(render);
void *re_system_gpu_context = RE_system_gpu_context_get(render);
/* Changing Context */
if (re_gl_context != NULL) {
DRW_opengl_render_context_enable(re_gl_context);
if (re_system_gpu_context != NULL) {
DRW_system_gpu_render_context_enable(re_system_gpu_context);
/* We need to query gpu context after a gl context has been bound. */
void *re_gpu_context = NULL;
re_gpu_context = RE_gpu_context_get(render);
DRW_gpu_render_context_enable(re_gpu_context);
void *re_blender_gpu_context = NULL;
re_blender_gpu_context = RE_blender_gpu_context_get(render);
DRW_blender_gpu_render_context_enable(re_blender_gpu_context);
}
else {
DRW_opengl_context_enable();
DRW_gpu_context_enable();
}
}
void DRW_render_context_disable(Render *render)
{
if (GPU_use_main_context_workaround()) {
DRW_opengl_context_disable();
DRW_gpu_context_disable();
GPU_render_end();
GPU_context_main_unlock();
return;
}
void *re_gl_context = RE_gl_context_get(render);
void *re_system_gpu_context = RE_system_gpu_context_get(render);
if (re_gl_context != NULL) {
void *re_gpu_context = NULL;
re_gpu_context = RE_gpu_context_get(render);
if (re_system_gpu_context != NULL) {
void *re_blender_gpu_context = NULL;
re_blender_gpu_context = RE_blender_gpu_context_get(render);
/* GPU rendering may occur during context disable. */
DRW_gpu_render_context_disable(re_gpu_context);
DRW_blender_gpu_render_context_disable(re_blender_gpu_context);
GPU_render_end();
DRW_opengl_render_context_disable(re_gl_context);
DRW_system_gpu_render_context_disable(re_system_gpu_context);
}
else {
DRW_opengl_context_disable();
DRW_gpu_context_disable();
GPU_render_end();
}
}
@ -3212,51 +3212,51 @@ void DRW_render_context_disable(Render *render)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Init/Exit (DRW_opengl_ctx)
/** \name Init/Exit (DRW_gpu_ctx)
* \{ */
void DRW_opengl_context_create(void)
void DRW_gpu_context_create(void)
{
BLI_assert(DST.gl_context == NULL); /* Ensure it's called once */
BLI_assert(DST.system_gpu_context == NULL); /* Ensure it's called once */
DST.gl_context_mutex = BLI_ticket_mutex_alloc();
DST.system_gpu_context_mutex = BLI_ticket_mutex_alloc();
/* This changes the active context. */
DST.gl_context = WM_opengl_context_create();
WM_opengl_context_activate(DST.gl_context);
/* Be sure to create gpu_context too. */
DST.gpu_context = GPU_context_create(0, DST.gl_context);
DST.system_gpu_context = WM_system_gpu_context_create();
WM_system_gpu_context_activate(DST.system_gpu_context);
/* Be sure to create blender_gpu_context too. */
DST.blender_gpu_context = GPU_context_create(0, DST.system_gpu_context);
/* So we activate the window's one afterwards. */
wm_window_reset_drawable();
}
void DRW_opengl_context_destroy(void)
void DRW_gpu_context_destroy(void)
{
BLI_assert(BLI_thread_is_main());
if (DST.gl_context != NULL) {
WM_opengl_context_activate(DST.gl_context);
GPU_context_active_set(DST.gpu_context);
GPU_context_discard(DST.gpu_context);
WM_opengl_context_dispose(DST.gl_context);
BLI_ticket_mutex_free(DST.gl_context_mutex);
if (DST.system_gpu_context != NULL) {
WM_system_gpu_context_activate(DST.system_gpu_context);
GPU_context_active_set(DST.blender_gpu_context);
GPU_context_discard(DST.blender_gpu_context);
WM_system_gpu_context_dispose(DST.system_gpu_context);
BLI_ticket_mutex_free(DST.system_gpu_context_mutex);
}
}
void DRW_opengl_context_enable_ex(bool UNUSED(restore))
void DRW_gpu_context_enable_ex(bool UNUSED(restore))
{
if (DST.gl_context != NULL) {
if (DST.system_gpu_context != NULL) {
/* IMPORTANT: We don't support immediate mode in render mode!
* This shall remain in effect until immediate mode supports
* multiple threads. */
BLI_ticket_mutex_lock(DST.gl_context_mutex);
BLI_ticket_mutex_lock(DST.system_gpu_context_mutex);
GPU_render_begin();
WM_opengl_context_activate(DST.gl_context);
GPU_context_active_set(DST.gpu_context);
WM_system_gpu_context_activate(DST.system_gpu_context);
GPU_context_active_set(DST.blender_gpu_context);
}
}
void DRW_opengl_context_disable_ex(bool restore)
void DRW_gpu_context_disable_ex(bool restore)
{
if (DST.gl_context != NULL) {
if (DST.system_gpu_context != NULL) {
#ifdef __APPLE__
/* Need to flush before disabling draw context, otherwise it does not
* always finish drawing and viewport can be empty or partially drawn */
@ -3269,7 +3269,7 @@ void DRW_opengl_context_disable_ex(bool restore)
wm_window_reset_drawable();
}
else {
WM_opengl_context_release(DST.gl_context);
WM_system_gpu_context_release(DST.system_gpu_context);
GPU_context_active_set(NULL);
}
@ -3277,51 +3277,51 @@ void DRW_opengl_context_disable_ex(bool restore)
* called outside of an existing render loop. */
GPU_render_end();
BLI_ticket_mutex_unlock(DST.gl_context_mutex);
BLI_ticket_mutex_unlock(DST.system_gpu_context_mutex);
}
}
void DRW_opengl_context_enable(void)
void DRW_gpu_context_enable(void)
{
/* TODO: should be replace by a more elegant alternative. */
if (G.background && DST.gl_context == NULL) {
WM_init_opengl();
if (G.background && DST.system_gpu_context == NULL) {
WM_init_gpu();
}
DRW_opengl_context_enable_ex(true);
DRW_gpu_context_enable_ex(true);
}
void DRW_opengl_context_disable(void)
void DRW_gpu_context_disable(void)
{
DRW_opengl_context_disable_ex(true);
DRW_gpu_context_disable_ex(true);
}
void DRW_opengl_render_context_enable(void *re_gl_context)
void DRW_system_gpu_render_context_enable(void *re_system_gpu_context)
{
/* If thread is main you should use DRW_opengl_context_enable(). */
/* If thread is main you should use DRW_gpu_context_enable(). */
BLI_assert(!BLI_thread_is_main());
/* TODO: get rid of the blocking. Only here because of the static global DST. */
BLI_ticket_mutex_lock(DST.gl_context_mutex);
WM_opengl_context_activate(re_gl_context);
BLI_ticket_mutex_lock(DST.system_gpu_context_mutex);
WM_system_gpu_context_activate(re_system_gpu_context);
}
void DRW_opengl_render_context_disable(void *re_gl_context)
void DRW_system_gpu_render_context_disable(void *re_system_gpu_context)
{
WM_opengl_context_release(re_gl_context);
WM_system_gpu_context_release(re_system_gpu_context);
/* TODO: get rid of the blocking. */
BLI_ticket_mutex_unlock(DST.gl_context_mutex);
BLI_ticket_mutex_unlock(DST.system_gpu_context_mutex);
}
void DRW_gpu_render_context_enable(void *re_gpu_context)
void DRW_blender_gpu_render_context_enable(void *re_gpu_context)
{
/* If thread is main you should use DRW_opengl_context_enable(). */
/* If thread is main you should use DRW_gpu_context_enable(). */
BLI_assert(!BLI_thread_is_main());
GPU_context_active_set(re_gpu_context);
}
void DRW_gpu_render_context_disable(void *UNUSED(re_gpu_context))
void DRW_blender_gpu_render_context_disable(void *UNUSED(re_gpu_context))
{
GPU_flush();
GPU_context_active_set(NULL);
@ -3331,39 +3331,39 @@ void DRW_gpu_render_context_disable(void *UNUSED(re_gpu_context))
#ifdef WITH_XR_OPENXR
void *DRW_xr_opengl_context_get(void)
void *DRW_system_gpu_context_get(void)
{
/* XXX: There should really be no such getter, but for VR we currently can't easily avoid it.
* OpenXR needs some low level info for the OpenGL context that will be used for submitting the
* OpenXR needs some low level info for the GPU context that will be used for submitting the
* final frame-buffer. VR could in theory create its own context, but that would mean we have to
* switch to it just to submit the final frame, which has notable performance impact.
*
* We could "inject" a context through DRW_opengl_render_context_enable(), but that would have to
* work from the main thread, which is tricky to get working too. The preferable solution would
* be using a separate thread for VR drawing where a single context can stay active. */
* We could "inject" a context through DRW_system_gpu_render_context_enable(), but that would
* have to work from the main thread, which is tricky to get working too. The preferable solution
* would be using a separate thread for VR drawing where a single context can stay active. */
return DST.gl_context;
return DST.system_gpu_context;
}
void *DRW_xr_gpu_context_get(void)
void *DRW_xr_blender_gpu_context_get(void)
{
/* XXX: See comment on #DRW_xr_opengl_context_get(). */
/* XXX: See comment on #DRW_system_gpu_context_get(). */
return DST.gpu_context;
return DST.blender_gpu_context;
}
void DRW_xr_drawing_begin(void)
{
/* XXX: See comment on #DRW_xr_opengl_context_get(). */
/* XXX: See comment on #DRW_system_gpu_context_get(). */
BLI_ticket_mutex_lock(DST.gl_context_mutex);
BLI_ticket_mutex_lock(DST.system_gpu_context_mutex);
}
void DRW_xr_drawing_end(void)
{
/* XXX: See comment on #DRW_xr_opengl_context_get(). */
/* XXX: See comment on #DRW_system_gpu_context_get(). */
BLI_ticket_mutex_unlock(DST.gl_context_mutex);
BLI_ticket_mutex_unlock(DST.system_gpu_context_mutex);
}
#endif
@ -3388,58 +3388,59 @@ void DRW_draw_state_init_gtests(eGPUShaderConfig sh_cfg)
/* -------------------------------------------------------------------- */
/** \name Draw manager context release/activation
*
* These functions are used in cases when an OpenGL context creation is needed during the draw.
* This happens, for example, when an external engine needs to create its own OpenGL context from
* These functions are used in cases when an GPU context creation is needed during the draw.
* This happens, for example, when an external engine needs to create its own GPU context from
* the engine initialization.
*
* Example of context creation:
*
* const bool drw_state = DRW_opengl_context_release();
* gl_context = WM_opengl_context_create();
* DRW_opengl_context_activate(drw_state);
* const bool drw_state = DRW_gpu_context_release();
* system_gpu_context = WM_system_gpu_context_create();
* DRW_gpu_context_activate(drw_state);
*
* Example of context destruction:
*
* const bool drw_state = DRW_opengl_context_release();
* WM_opengl_context_activate(gl_context);
* WM_opengl_context_dispose(gl_context);
* DRW_opengl_context_activate(drw_state);
* const bool drw_state = DRW_gpu_context_release();
* WM_system_gpu_context_activate(system_gpu_context);
* WM_system_gpu_context_dispose(system_gpu_context);
* DRW_gpu_context_activate(drw_state);
*
*
* NOTE: Will only perform context modification when on main thread. This way these functions can
* be used in an engine without check on whether it is a draw manager which manages OpenGL context
* on the current thread. The downside of this is that if the engine performs OpenGL creation from
* a non-main thread, that thread is supposed to not have OpenGL context ever bound by Blender.
* be used in an engine without check on whether it is a draw manager which manages GPU context
* on the current thread. The downside of this is that if the engine performs GPU creation from
* a non-main thread, that thread is supposed to not have GPU context ever bound by Blender.
*
* \{ */
bool DRW_opengl_context_release(void)
bool DRW_gpu_context_release(void)
{
if (!BLI_thread_is_main()) {
return false;
}
if (GPU_context_active_get() != DST.gpu_context) {
if (GPU_context_active_get() != DST.blender_gpu_context) {
/* Context release is requested from the outside of the draw manager main draw loop, indicate
* this to the `DRW_opengl_context_activate()` so that it restores drawable of the window. */
* this to the `DRW_gpu_context_activate()` so that it restores drawable of the window.
*/
return false;
}
GPU_context_active_set(NULL);
WM_opengl_context_release(DST.gl_context);
WM_system_gpu_context_release(DST.system_gpu_context);
return true;
}
void DRW_opengl_context_activate(bool drw_state)
void DRW_gpu_context_activate(bool drw_state)
{
if (!BLI_thread_is_main()) {
return;
}
if (drw_state) {
WM_opengl_context_activate(DST.gl_context);
GPU_context_active_set(DST.gpu_context);
WM_system_gpu_context_activate(DST.system_gpu_context);
GPU_context_active_set(DST.blender_gpu_context);
}
else {
wm_window_reset_drawable();

View File

@ -666,13 +666,13 @@ typedef struct DRWManager {
/* ---------- Nothing after this point is cleared after use ----------- */
/* gl_context serves as the offset for clearing only
/* system_gpu_context serves as the offset for clearing only
* the top portion of the struct so DO NOT MOVE IT! */
/** Unique ghost context used by the draw manager. */
void *gl_context;
GPUContext *gpu_context;
void *system_gpu_context;
GPUContext *blender_gpu_context;
/** Mutex to lock the drw manager and avoid concurrent context usage. */
TicketMutex *gl_context_mutex;
TicketMutex *system_gpu_context_mutex;
GPUDrawList *draw_list;

View File

@ -59,8 +59,8 @@ typedef struct DRWShaderCompiler {
/** Optimization queue. */
ListBase optimize_queue; /* GPUMaterial */
void *gl_context;
GPUContext *gpu_context;
void *system_gpu_context;
GPUContext *blender_gpu_context;
bool own_context;
} DRWShaderCompiler;
@ -74,20 +74,20 @@ static void drw_deferred_shader_compilation_exec(
{
GPU_render_begin();
DRWShaderCompiler *comp = (DRWShaderCompiler *)custom_data;
void *gl_context = comp->gl_context;
GPUContext *gpu_context = comp->gpu_context;
void *system_gpu_context = comp->system_gpu_context;
GPUContext *blender_gpu_context = comp->blender_gpu_context;
BLI_assert(gl_context != NULL);
BLI_assert(gpu_context != NULL);
BLI_assert(system_gpu_context != NULL);
BLI_assert(blender_gpu_context != NULL);
const bool use_main_context_workaround = GPU_use_main_context_workaround();
if (use_main_context_workaround) {
BLI_assert(gl_context == DST.gl_context);
BLI_assert(system_gpu_context == DST.system_gpu_context);
GPU_context_main_lock();
}
WM_opengl_context_activate(gl_context);
GPU_context_active_set(gpu_context);
WM_system_gpu_context_activate(system_gpu_context);
GPU_context_active_set(blender_gpu_context);
while (true) {
if (*stop != 0) {
@ -145,7 +145,7 @@ static void drw_deferred_shader_compilation_exec(
}
GPU_context_active_set(NULL);
WM_opengl_context_release(gl_context);
WM_system_gpu_context_release(system_gpu_context);
if (use_main_context_workaround) {
GPU_context_main_unlock();
}
@ -163,10 +163,10 @@ static void drw_deferred_shader_compilation_free(void *custom_data)
if (comp->own_context) {
/* Only destroy if the job owns the context. */
WM_opengl_context_activate(comp->gl_context);
GPU_context_active_set(comp->gpu_context);
GPU_context_discard(comp->gpu_context);
WM_opengl_context_dispose(comp->gl_context);
WM_system_gpu_context_activate(comp->system_gpu_context);
GPU_context_active_set(comp->blender_gpu_context);
GPU_context_discard(comp->blender_gpu_context);
WM_system_gpu_context_dispose(comp->system_gpu_context);
wm_window_reset_drawable();
}
@ -204,9 +204,9 @@ static void drw_deferred_queue_append(GPUMaterial *mat, bool is_optimization_job
BLI_movelisttolist(&comp->optimize_queue, &old_comp->optimize_queue);
BLI_spin_unlock(&old_comp->list_lock);
/* Do not recreate context, just pass ownership. */
if (old_comp->gl_context) {
comp->gl_context = old_comp->gl_context;
comp->gpu_context = old_comp->gpu_context;
if (old_comp->system_gpu_context) {
comp->system_gpu_context = old_comp->system_gpu_context;
comp->blender_gpu_context = old_comp->blender_gpu_context;
old_comp->own_context = false;
comp->own_context = job_own_context;
}
@ -226,18 +226,18 @@ static void drw_deferred_queue_append(GPUMaterial *mat, bool is_optimization_job
}
/* Create only one context. */
if (comp->gl_context == NULL) {
if (comp->system_gpu_context == NULL) {
if (use_main_context) {
comp->gl_context = DST.gl_context;
comp->gpu_context = DST.gpu_context;
comp->system_gpu_context = DST.system_gpu_context;
comp->blender_gpu_context = DST.blender_gpu_context;
}
else {
comp->gl_context = WM_opengl_context_create();
comp->gpu_context = GPU_context_create(NULL, comp->gl_context);
comp->system_gpu_context = WM_system_gpu_context_create();
comp->blender_gpu_context = GPU_context_create(NULL, comp->system_gpu_context);
GPU_context_active_set(NULL);
WM_opengl_context_activate(DST.gl_context);
GPU_context_active_set(DST.gpu_context);
WM_system_gpu_context_activate(DST.system_gpu_context);
GPU_context_active_set(DST.blender_gpu_context);
}
comp->own_context = job_own_context;
}

View File

@ -53,7 +53,7 @@ uint *DRW_select_buffer_read(
if (BLI_rcti_isect(&r, &rect_clamp, &rect_clamp)) {
SELECTID_Context *select_ctx = DRW_select_engine_context_get();
DRW_opengl_context_enable();
DRW_gpu_context_enable();
/* Update the drawing. */
DRW_draw_select_id(depsgraph, region, v3d, rect);
@ -84,7 +84,7 @@ uint *DRW_select_buffer_read(
}
GPU_framebuffer_restore();
DRW_opengl_context_disable();
DRW_gpu_context_disable();
}
if (r_buf_len) {

View File

@ -27,7 +27,7 @@ set(SRC
anim_channels_edit.c
anim_deps.c
anim_draw.c
anim_filter.c
anim_filter.cc
anim_ipo_utils.c
anim_markers.c
anim_motion_paths.c

View File

@ -12,6 +12,7 @@
extern "C" {
#endif
struct AssetMetaData;
struct ID;
struct Main;
struct bContext;
@ -42,6 +43,18 @@ void ED_asset_generate_preview(const struct bContext *C, struct ID *id);
*/
bool ED_asset_clear_id(struct ID *id);
/**
* Copy the asset metadata to the given destination ID.
*
* The copy is assigned to \a destination, any pre-existing asset metadata is
* freed before that. If \a destination was not yet marked as asset, it will be
* after this call.
*
* \return true when the copy succeeded, false otherwise. The only reason for
* failure is when \a destination is of a type that cannot be an asset.
*/
bool ED_asset_copy_to_id(const struct AssetMetaData *asset_data, struct ID *destination);
void ED_assets_pre_save(struct Main *bmain);
bool ED_asset_can_mark_single_from_context(const struct bContext *C);

View File

@ -27,6 +27,9 @@
#include "ED_asset_mark_clear.h"
#include "ED_asset_type.h"
#include "WM_api.h"
#include "WM_types.h"
bool ED_asset_mark_id(ID *id)
{
if (id->asset_data) {
@ -96,3 +99,16 @@ bool ED_asset_can_mark_single_from_context(const bContext *C)
}
return ED_asset_type_is_supported(id);
}
bool ED_asset_copy_to_id(const struct AssetMetaData *asset_data, struct ID *destination)
{
if (!BKE_id_can_be_asset(destination)) {
return false;
}
if (destination->asset_data) {
BKE_asset_metadata_free(&destination->asset_data);
}
destination->asset_data = BKE_asset_metadata_copy(asset_data);
return true;
}

View File

@ -48,10 +48,11 @@ static int select_all_exec(bContext *C, wmOperator *op)
Object *object = CTX_data_active_object(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
grease_pencil.foreach_editable_drawing(scene->r.cfra, [action](GreasePencilDrawing &drawing) {
// TODO: Support different selection domains.
blender::ed::curves::select_all(drawing.geometry.wrap(), ATTR_DOMAIN_POINT, action);
});
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [action](int /*drawing_index*/, GreasePencilDrawing &drawing) {
// TODO: Support different selection domains.
blender::ed::curves::select_all(drawing.geometry.wrap(), ATTR_DOMAIN_POINT, action);
});
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
* attribute for now. */

View File

@ -35,6 +35,7 @@
#include "interface_intern.hh"
#include "RNA_access.h"
#include "RNA_path.h"
#include "RNA_prototypes.h"
#ifdef WITH_PYTHON
@ -344,7 +345,10 @@ static bUserMenuItem *ui_but_user_menu_find(bContext *C, uiBut *but, bUserMenu *
}
if (but->rnaprop) {
char *member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin);
const char *prop_id = RNA_property_identifier(but->rnaprop);
/* Ignore the actual array index [pass -1] since the index is handled separately. */
const char *prop_id = RNA_property_is_idprop(but->rnaprop) ?
RNA_path_property_py(&but->rnapoin, but->rnaprop, -1) :
RNA_property_identifier(but->rnaprop);
bUserMenuItem *umi = (bUserMenuItem *)ED_screen_user_menu_item_find_prop(
&um->items, member_id_data_path, prop_id, but->rnaindex);
MEM_freeN(member_id_data_path);
@ -419,7 +423,10 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
else if (but->rnaprop) {
/* NOTE: 'member_id' may be a path. */
char *member_id_data_path = WM_context_path_resolve_full(C, &but->rnapoin);
const char *prop_id = RNA_property_identifier(but->rnaprop);
/* Ignore the actual array index [pass -1] since the index is handled separately. */
const char *prop_id = RNA_property_is_idprop(but->rnaprop) ?
RNA_path_property_py(&but->rnapoin, but->rnaprop, -1) :
RNA_property_identifier(but->rnaprop);
/* NOTE: ignore 'drawstr', use property idname always. */
ED_screen_user_menu_item_add_prop(&um->items, "", member_id_data_path, prop_id, but->rnaindex);
MEM_freeN(member_id_data_path);

View File

@ -503,7 +503,7 @@ void paintface_select_loop(bContext *C, Object *ob, const int mval[2], const boo
edge_to_poly_map,
polys_to_select);
if (!traced_full_loop) {
if (!traced_full_loop && polys_to_closest_edge.size() > 1) {
/* Trace the other way. */
follow_face_loop(polys_to_closest_edge[1],
closest_edge_index,
@ -517,7 +517,14 @@ void paintface_select_loop(bContext *C, Object *ob, const int mval[2], const boo
bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>(
".select_poly", ATTR_DOMAIN_FACE);
select_poly.span.fill_indices(polys_to_select.as_span(), select);
/* Toggling behavior. When one of the faces of the picked edge is already selected,
* it deselects the loop instead. */
bool any_adjacent_poly_selected = false;
for (const int i : polys_to_closest_edge) {
any_adjacent_poly_selected |= select_poly.span[i];
}
const bool select_toggle = select && !any_adjacent_poly_selected;
select_poly.span.fill_indices(polys_to_select.as_span(), select_toggle);
select_poly.finish();
paintface_flush_flags(C, ob, true, false);

View File

@ -1088,7 +1088,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
RE_current_scene_update_cb(re, rj, current_scene_update);
RE_stats_draw_cb(re, rj, image_renderinfo_cb);
RE_progress_cb(re, rj, render_progress_update);
RE_gl_context_create(re);
RE_system_gpu_context_create(re);
rj->re = re;
G.is_break = false;

View File

@ -302,7 +302,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
uchar *gp_rect;
uchar *render_rect = ibuf_result->byte_buffer.data;
DRW_opengl_context_enable();
DRW_gpu_context_enable();
GPU_offscreen_bind(oglrender->ofs, true);
GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
@ -324,7 +324,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
blend_color_mix_byte(&render_rect[i], &render_rect[i], &gp_rect[i]);
}
GPU_offscreen_unbind(oglrender->ofs, true);
DRW_opengl_context_disable();
DRW_gpu_context_disable();
MEM_freeN(gp_rect);
}
@ -744,14 +744,14 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
BKE_render_resolution(&scene->r, false, &sizex, &sizey);
/* corrects render size with actual size, not every card supports non-power-of-two dimensions */
DRW_opengl_context_enable(); /* Off-screen creation needs to be done in DRW context. */
DRW_gpu_context_enable(); /* Off-screen creation needs to be done in DRW context. */
ofs = GPU_offscreen_create(sizex,
sizey,
true,
GPU_RGBA16F,
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_HOST_READ,
err_out);
DRW_opengl_context_disable();
DRW_gpu_context_disable();
if (!ofs) {
BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out);
@ -925,9 +925,9 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);
DRW_opengl_context_enable();
DRW_gpu_context_enable();
GPU_offscreen_free(oglrender->ofs);
DRW_opengl_context_disable();
DRW_gpu_context_disable();
if (oglrender->is_sequencer) {
MEM_freeN(oglrender->seq_data.ibufs_arr);

View File

@ -3180,6 +3180,12 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static bool keyframe_jump_poll(bContext *C)
{
/* There is a keyframe jump operator specifically for the Graph Editor. */
return ED_operator_screenactive_norender(C) && CTX_wm_area(C)->spacetype != SPACE_GRAPH;
}
static void SCREEN_OT_keyframe_jump(wmOperatorType *ot)
{
ot->name = "Jump to Keyframe";
@ -3188,7 +3194,7 @@ static void SCREEN_OT_keyframe_jump(wmOperatorType *ot)
ot->exec = keyframe_jump_exec;
ot->poll = ED_operator_screenactive_norender;
ot->poll = keyframe_jump_poll;
ot->flag = OPTYPE_UNDO_GROUPED;
ot->undo_group = "Frame Change";

View File

@ -39,6 +39,7 @@
#include "BKE_global.h"
#include "BKE_nla.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "DEG_depsgraph_build.h"
@ -2179,6 +2180,104 @@ void GRAPH_OT_frame_jump(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static bool find_closest_frame(const FCurve *fcu,
const float frame,
const bool next,
float *closest_frame)
{
bool replace;
int bezt_index = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, frame, fcu->totvert, &replace);
BezTriple *bezt;
if (next) {
if (replace) {
bezt_index++;
}
if (bezt_index > fcu->totvert - 1) {
return false;
}
bezt = &fcu->bezt[bezt_index];
}
else {
if (bezt_index - 1 < 0) {
return false;
}
bezt = &fcu->bezt[bezt_index - 1];
}
*closest_frame = bezt->vec[1][0];
return true;
}
static int keyframe_jump_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
Scene *scene = CTX_data_scene(C);
bool next = RNA_boolean_get(op->ptr, "next");
/* Get editor data. */
if (ANIM_animdata_get_context(C, &ac) == 0) {
return OPERATOR_CANCELLED;
}
ListBase anim_data = {NULL, NULL};
int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY |
ANIMFILTER_NODUPLIS);
if (U.animation_flag & USER_ANIM_ONLY_SHOW_SELECTED_CURVE_KEYS) {
filter |= ANIMFILTER_SEL;
}
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
float closest_frame = next ? FLT_MAX : -FLT_MAX;
bool found = false;
const float current_frame = BKE_scene_frame_get(scene);
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
const FCurve *fcu = ale->key_data;
if (!fcu->bezt) {
continue;
}
float closest_fcu_frame;
if (!find_closest_frame(fcu, current_frame, next, &closest_fcu_frame)) {
continue;
}
if ((next && closest_fcu_frame < closest_frame) ||
(!next && closest_fcu_frame > closest_frame)) {
closest_frame = closest_fcu_frame;
found = true;
}
}
if (!found) {
BKE_report(op->reports, RPT_INFO, "No more keyframes to jump to in this direction");
return OPERATOR_CANCELLED;
}
BKE_scene_frame_set(scene, closest_frame);
/* Set notifier that things have changed. */
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
return OPERATOR_FINISHED;
}
void GRAPH_OT_keyframe_jump(wmOperatorType *ot)
{
ot->name = "Jump to Keyframe";
ot->description = "Jump to previous/next keyframe";
ot->idname = "GRAPH_OT_keyframe_jump";
ot->exec = keyframe_jump_exec;
ot->poll = graphkeys_framejump_poll;
ot->flag = OPTYPE_UNDO_GROUPED;
ot->undo_group = "Frame Change";
/* properties */
RNA_def_boolean(ot->srna, "next", true, "Next Keyframe", "");
}
/* snap 2D cursor value to the average value of selected keyframe */
static int graphkeys_snap_cursor_value_exec(bContext *C, wmOperator *UNUSED(op))
{

View File

@ -131,6 +131,7 @@ void GRAPH_OT_extrapolation_type(struct wmOperatorType *ot);
void GRAPH_OT_easing_type(struct wmOperatorType *ot);
void GRAPH_OT_frame_jump(struct wmOperatorType *ot);
void GRAPH_OT_keyframe_jump(struct wmOperatorType *ot);
void GRAPH_OT_snap_cursor_value(struct wmOperatorType *ot);
void GRAPH_OT_snap(struct wmOperatorType *ot);
void GRAPH_OT_equalize_handles(struct wmOperatorType *ot);

View File

@ -449,6 +449,7 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPH_OT_equalize_handles);
WM_operatortype_append(GRAPH_OT_mirror);
WM_operatortype_append(GRAPH_OT_frame_jump);
WM_operatortype_append(GRAPH_OT_keyframe_jump);
WM_operatortype_append(GRAPH_OT_snap_cursor_value);
WM_operatortype_append(GRAPH_OT_handle_type);
WM_operatortype_append(GRAPH_OT_interpolation_type);

View File

@ -243,7 +243,7 @@ static void compo_initjob(void *cjv)
}
cj->re = RE_NewSceneRender(scene);
RE_gl_context_create(cj->re);
RE_system_gpu_context_create(cj->re);
}
/* Called before redraw notifiers, it moves finished previews over. */
@ -302,7 +302,7 @@ static void compo_startjob(void *cjv,
}
}
RE_gl_context_destroy(cj->re);
RE_system_gpu_context_destroy(cj->re);
ntree->runtime->test_break = nullptr;
ntree->runtime->stats_draw = nullptr;

View File

@ -1899,7 +1899,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
}
const bool own_ofs = (ofs == nullptr);
DRW_opengl_context_enable();
DRW_gpu_context_enable();
if (own_ofs) {
/* bind */
@ -1910,7 +1910,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_HOST_READ,
err_out);
if (ofs == nullptr) {
DRW_opengl_context_disable();
DRW_gpu_context_disable();
return nullptr;
}
}
@ -2006,7 +2006,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
GPU_offscreen_free(ofs);
}
DRW_opengl_context_disable();
DRW_gpu_context_disable();
if (old_fb) {
GPU_framebuffer_bind(old_fb);

View File

@ -53,6 +53,7 @@
#include "BKE_crazyspace.hh"
#include "BKE_curve.h"
#include "BKE_editmesh.h"
#include "BKE_grease_pencil.hh"
#include "BKE_layer.h"
#include "BKE_mball.h"
#include "BKE_mesh.hh"
@ -1171,6 +1172,43 @@ static bool do_lasso_select_meta(ViewContext *vc,
return data.is_changed;
}
static bool do_lasso_select_grease_pencil(ViewContext *vc,
const int mcoords[][2],
const int mcoords_len,
const eSelectOp sel_op)
{
using namespace blender;
const Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph,
const_cast<Object *>(vc->obedit));
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(vc->obedit->data);
bool changed = false;
grease_pencil.foreach_editable_drawing(
vc->scene->r.cfra, [&](int drawing_index, GreasePencilDrawing &drawing) {
bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_grease_pencil_drawing_deformation(
ob_eval, *vc->obedit, drawing_index);
/* TODO: Support different selection domains. */
changed = ed::curves::select_lasso(
*vc,
drawing.geometry.wrap(),
deformation.positions,
ATTR_DOMAIN_POINT,
Span<int2>(reinterpret_cast<const int2 *>(mcoords), mcoords_len),
sel_op);
});
if (changed) {
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a
* generic attribute for now. */
DEG_id_tag_update(static_cast<ID *>(vc->obedit->data), ID_RECALC_GEOMETRY);
WM_event_add_notifier(vc->C, NC_GEOM | ND_DATA, vc->obedit->data);
}
return changed;
}
struct LassoSelectUserData_ForMeshVert {
LassoSelectUserData lasso_data;
blender::MutableSpan<bool> select_vert;
@ -1388,6 +1426,10 @@ static bool view3d_lasso_select(bContext *C,
}
break;
}
case OB_GREASE_PENCIL: {
changed = do_lasso_select_grease_pencil(vc, mcoords, mcoords_len, sel_op);
break;
}
default:
BLI_assert_msg(0, "lasso select on incorrect object type");
break;
@ -3097,6 +3139,112 @@ static bool ed_curves_select_pick(bContext &C, const int mval[2], const SelectPi
return true;
}
struct ClosestGreasePencilDrawing {
GreasePencilDrawing *drawing = nullptr;
blender::ed::curves::FindClosestData elem = {};
};
/**
* Cursor selection for all Grease Pencil curves in edit mode.
*
* \returns true if the selection changed.
*/
static bool ed_grease_pencil_select_pick(bContext *C,
const int mval[2],
const SelectPick_Params &params)
{
using namespace blender;
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ViewContext vc;
/* Setup view context for argument to callbacks. */
ED_view3d_viewcontext_init(C, &vc, depsgraph);
/* Collect editable drawings. */
const Object *ob_eval = DEG_get_evaluated_object(vc.depsgraph, const_cast<Object *>(vc.obedit));
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(vc.obedit->data);
Vector<GreasePencilDrawing *> drawings;
Vector<int> drawing_indices;
grease_pencil.foreach_editable_drawing(vc.scene->r.cfra,
[&](int drawing_index, GreasePencilDrawing &drawing) {
drawings.append(&drawing);
drawing_indices.append(drawing_index);
});
/* TODO: Support different selection domains. */
const eAttrDomain selection_domain = ATTR_DOMAIN_POINT;
const ClosestGreasePencilDrawing closest = threading::parallel_reduce(
drawings.index_range(),
1L,
ClosestGreasePencilDrawing(),
[&](const IndexRange range, const ClosestGreasePencilDrawing &init) {
ClosestGreasePencilDrawing new_closest = init;
for (const int i : range) {
/* Get deformation by modifiers. */
bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_grease_pencil_drawing_deformation(
ob_eval, *vc.obedit, drawing_indices[i]);
std::optional<ed::curves::FindClosestData> new_closest_elem =
ed::curves::closest_elem_find_screen_space(vc,
*vc.obedit,
drawings[i]->geometry.wrap(),
deformation.positions,
selection_domain,
mval,
new_closest.elem);
if (new_closest_elem) {
new_closest.elem = *new_closest_elem;
new_closest.drawing = drawings[i];
}
}
return new_closest;
},
[](const ClosestGreasePencilDrawing &a, const ClosestGreasePencilDrawing &b) {
return (a.elem.distance < b.elem.distance) ? a : b;
});
std::atomic<bool> deselected = false;
if (params.deselect_all || params.sel_op == SEL_OP_SET) {
threading::parallel_for(drawings.index_range(), 1L, [&](const IndexRange range) {
for (const int i : range) {
bke::CurvesGeometry &curves = drawings[i]->geometry.wrap();
if (ed::curves::has_anything_selected(curves)) {
bke::GSpanAttributeWriter selection = ed::curves::ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
ed::curves::fill_selection_false(selection.span);
selection.finish();
deselected = true;
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a
* generic attribute for now. */
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
}
}
});
}
if (!closest.drawing) {
return deselected;
}
bke::GSpanAttributeWriter selection = ed::curves::ensure_selection_attribute(
closest.drawing->geometry.wrap(), selection_domain, CD_PROP_BOOL);
ed::curves::apply_selection_operation_at_index(
selection.span, closest.elem.index, params.sel_op);
selection.finish();
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a
* generic attribute for now. */
if (!deselected) {
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
}
return true;
}
static int view3d_select_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
@ -3193,6 +3341,9 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
else if (obedit->type == OB_CURVES) {
changed = ed_curves_select_pick(*C, mval, params);
}
else if (obedit->type == OB_GREASE_PENCIL) {
changed = ed_grease_pencil_select_pick(C, mval, params);
}
}
else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
changed = PE_mouse_particles(C, mval, &params);
@ -4028,6 +4179,32 @@ static bool do_pose_box_select(bContext *C,
return changed_multi;
}
static bool do_grease_pencil_box_select(ViewContext *vc, const rcti *rect, const eSelectOp sel_op)
{
using namespace blender;
Scene *scene = vc->scene;
const Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph,
const_cast<Object *>(vc->obedit));
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(vc->obedit->data);
bool changed = false;
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [&](int drawing_index, GreasePencilDrawing &drawing) {
bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_grease_pencil_drawing_deformation(
ob_eval, *vc->obedit, drawing_index);
changed |= ed::curves::select_box(
*vc, drawing.geometry.wrap(), deformation.positions, ATTR_DOMAIN_POINT, *rect, sel_op);
});
if (changed) {
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(vc->C, NC_GEOM | ND_DATA, &grease_pencil);
}
return changed;
}
static int view3d_box_select_exec(bContext *C, wmOperator *op)
{
using namespace blender;
@ -4113,6 +4290,10 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
}
break;
}
case OB_GREASE_PENCIL: {
changed = do_grease_pencil_box_select(&vc, &rect, sel_op);
break;
}
default:
BLI_assert_msg(0, "box select on incorrect object type");
break;

View File

@ -666,7 +666,7 @@ int view3d_opengl_select_ex(ViewContext *vc,
UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW);
/* All of the queries need to be perform on the drawing context. */
DRW_opengl_context_enable();
DRW_gpu_context_enable();
G.f |= G_FLAG_PICKSEL;
@ -746,7 +746,7 @@ int view3d_opengl_select_ex(ViewContext *vc,
GPU_depth_test(GPU_DEPTH_NONE);
}
DRW_opengl_context_disable();
DRW_gpu_context_disable();
UI_Theme_Restore(&theme_state);

View File

@ -60,7 +60,7 @@ void GPU_viewport_colorspace_set(GPUViewport *viewport,
float dither);
/**
* Should be called from DRW after DRW_opengl_context_enable.
* Should be called from DRW after DRW_gpu_context_enable.
*/
void GPU_viewport_bind_from_offscreen(GPUViewport *viewport,
struct GPUOffScreen *ofs,

View File

@ -43,21 +43,21 @@ void ShaderBuilder::init()
{
CLG_init();
GHOST_GLSettings glSettings = {0};
GHOST_GPUSettings gpuSettings = {0};
switch (GPU_backend_type_selection_get()) {
case GPU_BACKEND_OPENGL:
glSettings.context_type = GHOST_kDrawingContextTypeOpenGL;
gpuSettings.context_type = GHOST_kDrawingContextTypeOpenGL;
break;
#ifdef WITH_METAL_BACKEND
case GPU_BACKEND_METAL:
glSettings.context_type = GHOST_kDrawingContextTypeMetal;
gpuSettings.context_type = GHOST_kDrawingContextTypeMetal;
break;
#endif
#ifdef WITH_VULKAN_BACKEND
case GPU_BACKEND_VULKAN:
glSettings.context_type = GHOST_kDrawingContextTypeVulkan;
gpuSettings.context_type = GHOST_kDrawingContextTypeVulkan;
break;
#endif
@ -67,8 +67,8 @@ void ShaderBuilder::init()
}
ghost_system_ = GHOST_CreateSystemBackground();
ghost_context_ = GHOST_CreateOpenGLContext(ghost_system_, glSettings);
GHOST_ActivateOpenGLContext(ghost_context_);
ghost_context_ = GHOST_CreateGPUContext(ghost_system_, gpuSettings);
GHOST_ActivateGPUContext(ghost_context_);
gpu_context_ = GPU_context_create(nullptr, ghost_context_);
GPU_init();
@ -80,7 +80,7 @@ void ShaderBuilder::exit()
GPU_context_discard(gpu_context_);
GHOST_DisposeOpenGLContext(ghost_system_, ghost_context_);
GHOST_DisposeGPUContext(ghost_system_, ghost_context_);
GHOST_DisposeSystem(ghost_system_);
CLG_exit();

View File

@ -194,7 +194,7 @@ void GPU_viewport_bind(GPUViewport *viewport, int view, const rcti *rect)
rect_size[0] = BLI_rcti_size_x(rect) + 1;
rect_size[1] = BLI_rcti_size_y(rect) + 1;
DRW_opengl_context_enable();
DRW_gpu_context_enable();
if (!equals_v2v2_int(viewport->size, rect_size)) {
copy_v2_v2_int(viewport->size, rect_size);
@ -562,7 +562,7 @@ void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport,
void GPU_viewport_unbind(GPUViewport *UNUSED(viewport))
{
GPU_framebuffer_restore();
DRW_opengl_context_disable();
DRW_gpu_context_disable();
}
int GPU_viewport_active_view_get(GPUViewport *viewport)

View File

@ -51,7 +51,7 @@ GLContext::GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list
ghost_window_ = ghost_window;
if (ghost_window) {
GLuint default_fbo = GHOST_GetDefaultOpenGLFramebuffer((GHOST_WindowHandle)ghost_window);
GLuint default_fbo = GHOST_GetDefaultGPUFramebuffer((GHOST_WindowHandle)ghost_window);
GHOST_RectangleHandle bounds = GHOST_GetClientBounds((GHOST_WindowHandle)ghost_window);
int w = GHOST_GetWidthRectangle(bounds);
int h = GHOST_GetHeightRectangle(bounds);

View File

@ -24,12 +24,12 @@ void GPUTest::SetUp()
CLG_init();
GPU_backend_type_selection_set(gpu_backend_type);
GHOST_GLSettings glSettings = {};
glSettings.context_type = draw_context_type;
glSettings.flags = GHOST_glDebugContext;
GHOST_GPUSettings gpuSettings = {};
gpuSettings.context_type = draw_context_type;
gpuSettings.flags = GHOST_gpuDebugContext;
ghost_system = GHOST_CreateSystem();
ghost_context = GHOST_CreateOpenGLContext(ghost_system, glSettings);
GHOST_ActivateOpenGLContext(ghost_context);
ghost_context = GHOST_CreateGPUContext(ghost_system, gpuSettings);
GHOST_ActivateGPUContext(ghost_context);
context = GPU_context_create(nullptr, ghost_context);
GPU_init();
@ -46,7 +46,7 @@ void GPUTest::TearDown()
GPU_exit();
GPU_context_discard(context);
GHOST_DisposeOpenGLContext(ghost_system, ghost_context);
GHOST_DisposeGPUContext(ghost_system, ghost_context);
GHOST_DisposeSystem(ghost_system);
CLG_exit();

View File

@ -1,4 +1,4 @@
/* SPDX-FileCopyrightText: 2022 Blender Foundation
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */

View File

@ -1,4 +1,4 @@
/* SPDX-FileCopyrightText: 2022 Blender Foundation
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
@ -41,4 +41,4 @@ class VKImageView : NonCopyable {
static VkImageView create_vk_image_view(VKTexture &texture, int mip_level, StringRefNull name);
};
} // namespace blender::gpu
} // namespace blender::gpu

View File

@ -515,6 +515,7 @@ void VKTexture::layout_ensure(VKContext &context,
barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
context.command_buffer_get().pipeline_barrier(Span<VkImageMemoryBarrier>(&barrier, 1));
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -30,7 +30,9 @@ class VKTexture : public Texture {
* can be done. */
VkImageLayout current_layout_ = VK_IMAGE_LAYOUT_UNDEFINED;
const int IMAGE_VIEW_DIRTY = (1 << 0);
enum eDirtyFlags {
IMAGE_VIEW_DIRTY = (1 << 0),
};
int flags_ = IMAGE_VIEW_DIRTY;

View File

@ -453,9 +453,9 @@ typedef struct GreasePencil {
void remove_drawing(int index);
void foreach_visible_drawing(int frame,
blender::FunctionRef<void(GreasePencilDrawing &)> function);
blender::FunctionRef<void(int, GreasePencilDrawing &)> function);
void foreach_editable_drawing(int frame,
blender::FunctionRef<void(GreasePencilDrawing &)> function);
blender::FunctionRef<void(int, GreasePencilDrawing &)> function);
bool bounds_min_max(blender::float3 &min, blender::float3 &max) const;

View File

@ -522,7 +522,7 @@ enum {
/** #MovieTrackingTrack.pattern_match */
typedef enum eTrackFrameMatch {
TRACK_MATCH_KEYFRAME = 0,
TRACK_MATCH_PREVIOS_FRAME = 1,
TRACK_MATCH_PREVIOUS_FRAME = 1,
} eTrackFrameMatch;
/** #MovieTrackingSettings.motion_flag */

View File

@ -725,6 +725,38 @@ static void rna_ID_asset_clear(ID *id)
}
}
static void rna_ID_asset_data_set(PointerRNA *ptr, PointerRNA value, struct ReportList *reports)
{
ID *destination = ptr->data;
/* Avoid marking as asset by assigning. This should be done wiht .asset_mark(). This is just for
* clarity of the API, and to accomodate future changes. */
if (destination->asset_data == NULL) {
BKE_report(reports,
RPT_ERROR,
"Asset data can only be assigned to assets. Use asset_mark() to mark as an asset");
return;
}
const AssetMetaData *asset_data = value.data;
if (asset_data == NULL) {
/* Avoid clearing the asset data on assets. Un-marking as asset should be done with
* .asset_clear(). This is just for clarity of the API, and to accomodate future changes. */
BKE_report(reports, RPT_ERROR, "Asset data cannot be None");
return;
}
const bool assigned_ok = ED_asset_copy_to_id(asset_data, destination);
if (!assigned_ok) {
BKE_reportf(
reports, RPT_ERROR, "'%s' is of a type that cannot be an asset", destination->name + 2);
return;
}
WM_main_add_notifier(NC_ASSET | NA_EDITED, NULL);
WM_main_add_notifier(NC_ID | NA_EDITED, NULL);
}
static ID *rna_ID_override_create(ID *id, Main *bmain, bool remap_local_usages)
{
if (!ID_IS_OVERRIDABLE_LIBRARY(id)) {
@ -2131,7 +2163,8 @@ static void rna_def_ID(BlenderRNA *brna)
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
prop = RNA_def_property(srna, "asset_data", PROP_POINTER, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_pointer_funcs(prop, NULL, "rna_ID_asset_data_set", NULL, NULL);
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
RNA_def_property_ui_text(prop, "Asset Data", "Additional data for an asset data-block");

View File

@ -900,7 +900,7 @@ static const EnumPropertyItem tracker_motion_model[] = {
static const EnumPropertyItem pattern_match_items[] = {
{TRACK_MATCH_KEYFRAME, "KEYFRAME", 0, "Keyframe", "Track pattern from keyframe to next frame"},
{TRACK_MATCH_PREVIOS_FRAME,
{TRACK_MATCH_PREVIOUS_FRAME,
"PREV_FRAME",
0,
"Previous frame",

View File

@ -9,15 +9,22 @@
#include "UI_interface.h"
#include "UI_resources.h"
#include "GPU_shader.h"
#include "COM_node_operation.hh"
#include "COM_utilities.hh"
#include "node_composite_util.hh"
namespace blender::nodes::node_composite_sunbeams_cc {
NODE_STORAGE_FUNCS(NodeSunBeams)
static void cmp_node_sunbeams_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Color>("Image").default_value({1.0f, 1.0f, 1.0f, 1.0f});
b.add_input<decl::Color>("Image")
.default_value({1.0f, 1.0f, 1.0f, 1.0f})
.compositor_domain_priority(0);
b.add_output<decl::Color>("Image");
}
@ -49,8 +56,27 @@ class SunBeamsOperation : public NodeOperation {
void execute() override
{
get_input("Image").pass_through(get_result("Image"));
context().set_info_message("Viewport compositor setup not fully supported");
GPUShader *shader = shader_manager().get("compositor_sun_beams");
GPU_shader_bind(shader);
GPU_shader_uniform_2fv(shader, "source", node_storage(bnode()).source);
GPU_shader_uniform_1f(shader, "max_ray_length", node_storage(bnode()).ray_length);
const Result &input_image = get_input("Image");
GPU_texture_filter_mode(input_image.texture(), true);
GPU_texture_extend_mode(input_image.texture(), GPU_SAMPLER_EXTEND_MODE_CLAMP_TO_BORDER);
input_image.bind_as_texture(shader, "input_tx");
const Domain domain = compute_domain();
Result &output_image = get_result("Image");
output_image.allocate_texture(domain);
output_image.bind_as_image(shader, "output_img");
compute_dispatch_threads_at_least(shader, domain.size);
GPU_shader_unbind();
output_image.unbind_as_image();
input_image.unbind_as_texture();
}
};
@ -74,8 +100,6 @@ void register_node_type_cmp_sunbeams()
node_type_storage(
&ntype, "NodeSunBeams", node_free_standard_storage, node_copy_standard_storage);
ntype.get_compositor_operation = file_ns::get_compositor_operation;
ntype.realtime_compositor_unsupported_message = N_(
"Node not supported in the Viewport compositor");
nodeRegisterType(&ntype);
}

View File

@ -162,10 +162,10 @@ typedef struct RenderEngine {
void *update_render_passes_data;
/* GPU context. */
void *wm_gpu_context; /* WindowManager GPU context -> GHOSTContext. */
ThreadMutex gpu_context_mutex;
void *wm_blender_gpu_context; /* WindowManager GPU context -> GHOSTContext. */
ThreadMutex blender_gpu_context_mutex;
bool use_drw_render_context;
struct GPUContext *gpu_context;
struct GPUContext *blender_gpu_context;
/* Whether to restore DRWState after RenderEngine display pass. */
bool gpu_restore_context;
} RenderEngine;
@ -272,8 +272,6 @@ void RE_engines_init_experimental(void);
void RE_engines_exit(void);
void RE_engines_register(RenderEngineType *render_type);
bool RE_engine_is_opengl(RenderEngineType *render_type);
/**
* Return true if the RenderEngineType has native support for direct loading of Alembic data. For
* Cycles, this also checks that the experimental feature set is enabled.

View File

@ -426,10 +426,10 @@ void RE_current_scene_update_cb(struct Render *re,
void *handle,
void (*f)(void *handle, struct Scene *scene));
void RE_gl_context_create(Render *re);
void RE_gl_context_destroy(Render *re);
void *RE_gl_context_get(Render *re);
void *RE_gpu_context_get(Render *re);
void RE_system_gpu_context_create(Render *re);
void RE_system_gpu_context_destroy(Render *re);
void *RE_system_gpu_context_get(Render *re);
void *RE_blender_gpu_context_get(Render *re);
/**
* \param x: ranges from -1 to 1.

View File

@ -115,13 +115,6 @@ bool RE_engine_is_external(const Render *re)
return (re->engine && re->engine->type && re->engine->type->render);
}
bool RE_engine_is_opengl(RenderEngineType *render_type)
{
/* TODO: refine? Can we have OpenGL render engine without OpenGL render pipeline? */
return (render_type->draw_engine != nullptr) &&
DRW_engine_render_support(render_type->draw_engine);
}
bool RE_engine_supports_alembic_procedural(const RenderEngineType *render_type, Scene *scene)
{
if ((render_type->flag & RE_USE_ALEMBIC_PROCEDURAL) == 0) {
@ -143,7 +136,7 @@ RenderEngine *RE_engine_create(RenderEngineType *type)
engine->type = type;
BLI_mutex_init(&engine->update_render_passes_mutex);
BLI_mutex_init(&engine->gpu_context_mutex);
BLI_mutex_init(&engine->blender_gpu_context_mutex);
return engine;
}
@ -176,7 +169,7 @@ void RE_engine_free(RenderEngine *engine)
engine_depsgraph_free(engine);
BLI_mutex_end(&engine->gpu_context_mutex);
BLI_mutex_end(&engine->blender_gpu_context_mutex);
BLI_mutex_end(&engine->update_render_passes_mutex);
MEM_freeN(engine);
@ -1271,7 +1264,7 @@ void RE_engine_tile_highlight_clear_all(RenderEngine *engine)
}
/* -------------------------------------------------------------------- */
/** \name OpenGL context manipulation.
/** \name GPU context manipulation.
*
* GPU context for engine to create and update GPU resources in its own thread,
* without blocking the main thread. Used by Cycles' display driver to create
@ -1282,7 +1275,7 @@ void RE_engine_tile_highlight_clear_all(RenderEngine *engine)
bool RE_engine_gpu_context_create(RenderEngine *engine)
{
/* If the there already is a draw manager render context available, reuse it. */
engine->use_drw_render_context = (engine->re && RE_gl_context_get(engine->re));
engine->use_drw_render_context = (engine->re && RE_system_gpu_context_get(engine->re));
if (engine->use_drw_render_context) {
return true;
}
@ -1291,49 +1284,49 @@ bool RE_engine_gpu_context_create(RenderEngine *engine)
* the main thread here to safely create a context. */
BLI_assert(BLI_thread_is_main());
const bool drw_state = DRW_opengl_context_release();
engine->wm_gpu_context = WM_opengl_context_create();
const bool drw_state = DRW_gpu_context_release();
engine->wm_blender_gpu_context = WM_system_gpu_context_create();
if (engine->wm_gpu_context) {
/* Activate new OpenGL Context for GPUContext creation. */
WM_opengl_context_activate(engine->wm_gpu_context);
if (engine->wm_blender_gpu_context) {
/* Activate new GPU Context for GPUContext creation. */
WM_system_gpu_context_activate(engine->wm_blender_gpu_context);
/* Requires GPUContext for usage of GPU Module for displaying results. */
engine->gpu_context = GPU_context_create(nullptr, engine->wm_gpu_context);
engine->blender_gpu_context = GPU_context_create(nullptr, engine->wm_blender_gpu_context);
GPU_context_active_set(nullptr);
/* Deactivate newly created OpenGL Context, as it is not needed until
/* Deactivate newly created GPU Context, as it is not needed until
* `RE_engine_gpu_context_enable` is called. */
WM_opengl_context_release(engine->wm_gpu_context);
WM_system_gpu_context_release(engine->wm_blender_gpu_context);
}
else {
engine->gpu_context = nullptr;
engine->blender_gpu_context = nullptr;
}
DRW_opengl_context_activate(drw_state);
DRW_gpu_context_activate(drw_state);
return engine->wm_gpu_context != nullptr;
return engine->wm_blender_gpu_context != nullptr;
}
void RE_engine_gpu_context_destroy(RenderEngine *engine)
{
if (!engine->wm_gpu_context) {
if (!engine->wm_blender_gpu_context) {
return;
}
const bool drw_state = DRW_opengl_context_release();
const bool drw_state = DRW_gpu_context_release();
WM_opengl_context_activate(engine->wm_gpu_context);
if (engine->gpu_context) {
WM_system_gpu_context_activate(engine->wm_blender_gpu_context);
if (engine->blender_gpu_context) {
GPUContext *restore_context = GPU_context_active_get();
GPU_context_active_set(engine->gpu_context);
GPU_context_discard(engine->gpu_context);
if (restore_context != engine->gpu_context) {
GPU_context_active_set(engine->blender_gpu_context);
GPU_context_discard(engine->blender_gpu_context);
if (restore_context != engine->blender_gpu_context) {
GPU_context_active_set(restore_context);
}
engine->gpu_context = nullptr;
engine->blender_gpu_context = nullptr;
}
WM_opengl_context_dispose(engine->wm_gpu_context);
WM_system_gpu_context_dispose(engine->wm_blender_gpu_context);
DRW_opengl_context_activate(drw_state);
DRW_gpu_context_activate(drw_state);
}
bool RE_engine_gpu_context_enable(RenderEngine *engine)
@ -1343,16 +1336,16 @@ bool RE_engine_gpu_context_enable(RenderEngine *engine)
DRW_render_context_enable(engine->re);
return true;
}
if (engine->wm_gpu_context) {
BLI_mutex_lock(&engine->gpu_context_mutex);
/* If a previous OpenGL/GPUContext was active (DST.gpu_context), we should later restore this
* when disabling the RenderEngine context. */
engine->gpu_restore_context = DRW_opengl_context_release();
if (engine->wm_blender_gpu_context) {
BLI_mutex_lock(&engine->blender_gpu_context_mutex);
/* If a previous GPU/GPUContext was active (DST.blender_gpu_context), we should later
* restore this when disabling the RenderEngine context. */
engine->gpu_restore_context = DRW_gpu_context_release();
/* Activate RenderEngine OpenGL and GPU Context. */
WM_opengl_context_activate(engine->wm_gpu_context);
if (engine->gpu_context) {
GPU_context_active_set(engine->gpu_context);
/* Activate RenderEngine System and Blender GPU Context. */
WM_system_gpu_context_activate(engine->wm_blender_gpu_context);
if (engine->blender_gpu_context) {
GPU_context_active_set(engine->blender_gpu_context);
GPU_render_begin();
}
return true;
@ -1366,15 +1359,15 @@ void RE_engine_gpu_context_disable(RenderEngine *engine)
DRW_render_context_disable(engine->re);
}
else {
if (engine->wm_gpu_context) {
if (engine->gpu_context) {
if (engine->wm_blender_gpu_context) {
if (engine->blender_gpu_context) {
GPU_render_end();
GPU_context_active_set(nullptr);
}
WM_opengl_context_release(engine->wm_gpu_context);
WM_system_gpu_context_release(engine->wm_blender_gpu_context);
/* Restore DRW state context if previously active. */
DRW_opengl_context_activate(engine->gpu_restore_context);
BLI_mutex_unlock(&engine->gpu_context_mutex);
DRW_gpu_context_activate(engine->gpu_restore_context);
BLI_mutex_unlock(&engine->blender_gpu_context_mutex);
}
}
}
@ -1385,8 +1378,8 @@ void RE_engine_gpu_context_lock(RenderEngine *engine)
/* Locking already handled by the draw manager. */
}
else {
if (engine->wm_gpu_context) {
BLI_mutex_lock(&engine->gpu_context_mutex);
if (engine->wm_blender_gpu_context) {
BLI_mutex_lock(&engine->blender_gpu_context_mutex);
}
}
}
@ -1397,8 +1390,8 @@ void RE_engine_gpu_context_unlock(RenderEngine *engine)
/* Locking already handled by the draw manager. */
}
else {
if (engine->wm_gpu_context) {
BLI_mutex_unlock(&engine->gpu_context_mutex);
if (engine->wm_blender_gpu_context) {
BLI_mutex_unlock(&engine->blender_gpu_context_mutex);
}
}
}

View File

@ -877,44 +877,44 @@ void RE_test_break_cb(Render *re, void *handle, bool (*f)(void *handle))
/** \} */
/* -------------------------------------------------------------------- */
/** \name OpenGL Context
/** \name GPU Context
* \{ */
void RE_gl_context_create(Render *re)
void RE_system_gpu_context_create(Render *re)
{
/* Needs to be created in the main OpenGL thread. */
re->gl_context = WM_opengl_context_create();
/* Needs to be created in the main thread. */
re->system_gpu_context = WM_system_gpu_context_create();
/* So we activate the window's one afterwards. */
wm_window_reset_drawable();
}
void RE_gl_context_destroy(Render *re)
void RE_system_gpu_context_destroy(Render *re)
{
/* Needs to be called from the thread which used the OpenGL context for rendering. */
if (re->gl_context) {
if (re->gpu_context) {
WM_opengl_context_activate(re->gl_context);
GPU_context_active_set(static_cast<GPUContext *>(re->gpu_context));
GPU_context_discard(static_cast<GPUContext *>(re->gpu_context));
re->gpu_context = nullptr;
/* Needs to be called from the thread which used the GPU context for rendering. */
if (re->system_gpu_context) {
if (re->blender_gpu_context) {
WM_system_gpu_context_activate(re->system_gpu_context);
GPU_context_active_set(static_cast<GPUContext *>(re->blender_gpu_context));
GPU_context_discard(static_cast<GPUContext *>(re->blender_gpu_context));
re->blender_gpu_context = nullptr;
}
WM_opengl_context_dispose(re->gl_context);
re->gl_context = nullptr;
WM_system_gpu_context_dispose(re->system_gpu_context);
re->system_gpu_context = nullptr;
}
}
void *RE_gl_context_get(Render *re)
void *RE_system_gpu_context_get(Render *re)
{
return re->gl_context;
return re->system_gpu_context;
}
void *RE_gpu_context_get(Render *re)
void *RE_blender_gpu_context_get(Render *re)
{
if (re->gpu_context == nullptr) {
re->gpu_context = GPU_context_create(nullptr, re->gl_context);
if (re->blender_gpu_context == nullptr) {
re->blender_gpu_context = GPU_context_create(nullptr, re->system_gpu_context);
}
return re->gpu_context;
return re->blender_gpu_context;
}
/** \} */
@ -1752,7 +1752,7 @@ static void render_pipeline_free(Render *re)
re->pipeline_scene_eval = nullptr;
}
/* Destroy the opengl context in the correct thread. */
RE_gl_context_destroy(re);
RE_system_gpu_context_destroy(re);
/* In the case the engine did not mark tiles as finished (un-highlight, which could happen in the
* case of cancelled render) ensure the storage is empty. */

View File

@ -124,8 +124,8 @@ struct Render {
char viewname[MAX_NAME];
/* TODO: replace by a whole draw manager. */
void *gl_context;
void *gpu_context;
void *system_gpu_context;
void *blender_gpu_context;
};
/* **************** defines ********************* */

View File

@ -144,7 +144,7 @@ void WM_init_splash_on_startup(struct bContext *C);
*/
void WM_init_splash(struct bContext *C);
void WM_init_opengl(void);
void WM_init_gpu(void);
/**
* Return an identifier for the underlying GHOST implementation.
@ -313,10 +313,10 @@ void WM_window_ensure_active_view_layer(struct wmWindow *win) ATTR_NONNULL(1);
bool WM_window_is_temp_screen(const struct wmWindow *win) ATTR_WARN_UNUSED_RESULT;
void *WM_opengl_context_create(void);
void WM_opengl_context_dispose(void *context);
void WM_opengl_context_activate(void *context);
void WM_opengl_context_release(void *context);
void *WM_system_gpu_context_create(void);
void WM_system_gpu_context_dispose(void *context);
void WM_system_gpu_context_activate(void *context);
void WM_system_gpu_context_release(void *context);
/* #WM_window_open alignment */
typedef enum eWindowAlignment {

View File

@ -1199,11 +1199,11 @@ static void wm_draw_surface(bContext *C, wmSurface *surface)
wm_window_clear_drawable(CTX_wm_manager(C));
wm_surface_make_drawable(surface);
GPU_context_begin_frame(surface->gpu_ctx);
GPU_context_begin_frame(surface->blender_gpu_context);
surface->draw(C);
GPU_context_end_frame(surface->gpu_ctx);
GPU_context_end_frame(surface->blender_gpu_context);
/* Avoid interference with window drawable */
wm_surface_clear_drawable();

View File

@ -159,12 +159,12 @@ void WM_init_state_start_with_console_set(bool value)
* so that it does not break anything that can run in headless mode (as in
* without display server attached).
*/
static bool opengl_is_init = false;
static bool gpu_is_init = false;
void WM_init_opengl(void)
void WM_init_gpu(void)
{
/* Must be called only once. */
BLI_assert(opengl_is_init == false);
BLI_assert(gpu_is_init == false);
if (G.background) {
/* Ghost is still not initialized elsewhere in background mode. */
@ -176,13 +176,13 @@ void WM_init_opengl(void)
}
/* Needs to be first to have an OpenGL context bound. */
DRW_opengl_context_create();
DRW_gpu_context_create();
GPU_init();
GPU_pass_cache_init();
opengl_is_init = true;
gpu_is_init = true;
}
static void sound_jack_sync_callback(Main *bmain, int mode, double time)
@ -317,7 +317,7 @@ void WM_init(bContext *C, int argc, const char **argv)
/* Sets 3D mouse dead-zone. */
WM_ndof_deadzone_set(U.ndof_deadzone);
#endif
WM_init_opengl();
WM_init_gpu();
if (!WM_platform_support_perform_checks()) {
/* No attempt to avoid memory leaks here. */
@ -603,7 +603,7 @@ void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actio
BKE_subdiv_exit();
if (opengl_is_init) {
if (gpu_is_init) {
BKE_image_free_unused_gpu_textures();
}
@ -617,7 +617,7 @@ void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actio
/* Free the GPU subdivision data after the database to ensure that subdivision structs used by
* the modifiers were garbage collected. */
if (opengl_is_init) {
if (gpu_is_init) {
DRW_subdiv_free();
}
@ -664,13 +664,13 @@ void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actio
/* Delete GPU resources and context. The UI also uses GPU resources and so
* is also deleted with the context active. */
if (opengl_is_init) {
DRW_opengl_context_enable_ex(false);
if (gpu_is_init) {
DRW_gpu_context_enable_ex(false);
UI_exit();
GPU_pass_cache_free();
GPU_exit();
DRW_opengl_context_disable_ex(false);
DRW_opengl_context_destroy();
DRW_gpu_context_disable_ex(false);
DRW_gpu_context_destroy();
}
else {
UI_exit();

View File

@ -191,7 +191,7 @@ typedef enum eWS_Qual {
static struct WindowStateGlobal {
GHOST_SystemHandle ghost_system;
void *ghost_window;
GPUContext *gpu_context;
GPUContext *blender_gpu_context;
/* events */
eWS_Qual qual;
@ -1350,9 +1350,9 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
static void playanim_window_open(const char *title, int posx, int posy, int sizex, int sizey)
{
GHOST_GLSettings glsettings = {0};
GHOST_GPUSettings gpusettings = {0};
const eGPUBackendType gpu_backend = GPU_backend_type_selection_get();
glsettings.context_type = wm_ghost_drawing_context_type(gpu_backend);
gpusettings.context_type = wm_ghost_drawing_context_type(gpu_backend);
uint32_t scr_w, scr_h;
GHOST_GetMainDisplayDimensions(g_WS.ghost_system, &scr_w, &scr_h);
@ -1369,7 +1369,7 @@ static void playanim_window_open(const char *title, int posx, int posy, int size
/* Could optionally start full-screen. */
GHOST_kWindowStateNormal,
false,
glsettings);
gpusettings);
}
static void playanim_window_zoom(PlayState *ps, const float zoom_offset)
@ -1569,7 +1569,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
// GHOST_ActivateWindowDrawingContext(g_WS.ghost_window);
/* initialize OpenGL immediate mode */
g_WS.gpu_context = GPU_context_create(g_WS.ghost_window, NULL);
g_WS.blender_gpu_context = GPU_context_create(g_WS.ghost_window, NULL);
GPU_init();
/* initialize the font */
@ -1832,11 +1832,11 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
BLF_exit();
if (g_WS.gpu_context) {
GPU_context_active_set(g_WS.gpu_context);
if (g_WS.blender_gpu_context) {
GPU_context_active_set(g_WS.blender_gpu_context);
GPU_exit();
GPU_context_discard(g_WS.gpu_context);
g_WS.gpu_context = NULL;
GPU_context_discard(g_WS.blender_gpu_context);
g_WS.blender_gpu_context = NULL;
}
GHOST_DisposeWindow(g_WS.ghost_system, g_WS.ghost_window);

View File

@ -54,7 +54,7 @@ void wm_surfaces_do_depsgraph(bContext *C)
void wm_surface_clear_drawable(void)
{
if (g_drawable) {
WM_opengl_context_release(g_drawable->ghost_ctx);
WM_system_gpu_context_release(g_drawable->system_gpu_context);
GPU_context_active_set(NULL);
if (g_drawable->deactivate) {
@ -74,10 +74,10 @@ void wm_surface_set_drawable(wmSurface *surface, bool activate)
if (surface->activate) {
surface->activate();
}
WM_opengl_context_activate(surface->ghost_ctx);
WM_system_gpu_context_activate(surface->system_gpu_context);
}
GPU_context_active_set(surface->gpu_ctx);
GPU_context_active_set(surface->blender_gpu_context);
}
void wm_surface_make_drawable(wmSurface *surface)

View File

@ -216,7 +216,7 @@ static void wm_ghostwindow_destroy(wmWindowManager *wm, wmWindow *win)
wm->winactive = NULL;
}
/* We need this window's opengl context active to discard it. */
/* We need this window's GPU context active to discard it. */
GHOST_ActivateWindowDrawingContext(win->ghostwin);
GPU_context_active_set(win->gpuctx);
@ -670,17 +670,17 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm,
bool is_dialog)
{
/* A new window is created when page-flip mode is required for a window. */
GHOST_GLSettings glSettings = {0};
GHOST_GPUSettings gpuSettings = {0};
if (win->stereo3d_format->display_mode == S3D_DISPLAY_PAGEFLIP) {
glSettings.flags |= GHOST_glStereoVisual;
gpuSettings.flags |= GHOST_gpuStereoVisual;
}
if (G.debug & G_DEBUG_GPU) {
glSettings.flags |= GHOST_glDebugContext;
gpuSettings.flags |= GHOST_gpuDebugContext;
}
eGPUBackendType gpu_backend = GPU_backend_type_selection_get();
glSettings.context_type = wm_ghost_drawing_context_type(gpu_backend);
gpuSettings.context_type = wm_ghost_drawing_context_type(gpu_backend);
int scr_w, scr_h;
wm_get_desktopsize(&scr_w, &scr_h);
@ -699,7 +699,7 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm,
win->sizey,
(GHOST_TWindowState)win->windowstate,
is_dialog,
glSettings);
gpuSettings);
if (ghostwin) {
win->gpuctx = GPU_context_create(ghostwin, NULL);
@ -2632,10 +2632,10 @@ void wm_window_IME_end(wmWindow *win)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Direct OpenGL Context Management
/** \name Direct GPU Context Management
* \{ */
void *WM_opengl_context_create(void)
void *WM_system_gpu_context_create(void)
{
/* On Windows there is a problem creating contexts that share resources (almost any object,
* including legacy display lists, but also textures) with a context which is current in another
@ -2649,31 +2649,31 @@ void *WM_opengl_context_create(void)
BLI_assert(BLI_thread_is_main());
BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get());
GHOST_GLSettings glSettings = {0};
GHOST_GPUSettings gpuSettings = {0};
const eGPUBackendType gpu_backend = GPU_backend_type_selection_get();
glSettings.context_type = wm_ghost_drawing_context_type(gpu_backend);
gpuSettings.context_type = wm_ghost_drawing_context_type(gpu_backend);
if (G.debug & G_DEBUG_GPU) {
glSettings.flags |= GHOST_glDebugContext;
gpuSettings.flags |= GHOST_gpuDebugContext;
}
return GHOST_CreateOpenGLContext(g_system, glSettings);
return GHOST_CreateGPUContext(g_system, gpuSettings);
}
void WM_opengl_context_dispose(void *context)
void WM_system_gpu_context_dispose(void *context)
{
BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get());
GHOST_DisposeOpenGLContext(g_system, (GHOST_ContextHandle)context);
GHOST_DisposeGPUContext(g_system, (GHOST_ContextHandle)context);
}
void WM_opengl_context_activate(void *context)
void WM_system_gpu_context_activate(void *context)
{
BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get());
GHOST_ActivateOpenGLContext((GHOST_ContextHandle)context);
GHOST_ActivateGPUContext((GHOST_ContextHandle)context);
}
void WM_opengl_context_release(void *context)
void WM_system_gpu_context_release(void *context)
{
BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get());
GHOST_ReleaseOpenGLContext((GHOST_ContextHandle)context);
GHOST_ReleaseGPUContext((GHOST_ContextHandle)context);
}
void WM_ghost_show_message_box(const char *title,

View File

@ -21,8 +21,8 @@ extern "C" {
typedef struct wmSurface {
struct wmSurface *next, *prev;
GHOST_ContextHandle ghost_ctx;
struct GPUContext *gpu_ctx;
GHOST_ContextHandle system_gpu_context;
struct GPUContext *blender_gpu_context;
void *customdata;

View File

@ -86,7 +86,7 @@ void wm_window_process_events(const bContext *C);
void wm_window_clear_drawable(wmWindowManager *wm);
void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win);
/**
* Reset active the current window opengl drawing context.
* Reset active the current window gpu drawing context.
*/
void wm_window_reset_drawable(void);

View File

@ -1469,8 +1469,8 @@ static wmSurface *wm_xr_session_surface_create(void)
surface->activate = DRW_xr_drawing_begin;
surface->deactivate = DRW_xr_drawing_end;
surface->ghost_ctx = DRW_xr_opengl_context_get();
surface->gpu_ctx = DRW_xr_gpu_context_get();
surface->system_gpu_context = DRW_system_gpu_context_get();
surface->blender_gpu_context = DRW_xr_blender_gpu_context_get();
data->controller_art->regionid = RGN_TYPE_XR;
surface->customdata = data;
@ -1490,7 +1490,7 @@ void *wm_xr_session_gpu_binding_context_create(void)
* and running. */
WM_main_add_notifier(NC_WM | ND_XR_DATA_CHANGED, NULL);
return surface->ghost_ctx;
return surface->system_gpu_context;
}
void wm_xr_session_gpu_binding_context_destroy(GHOST_ContextHandle UNUSED(context))