Vulkan: Clearing Framebuffer + Scissors #106044
|
@ -309,7 +309,7 @@ class Device {
|
|||
static uint devices_initialized_mask;
|
||||
};
|
||||
|
||||
/* Device, which is GPU, with some common functionality for GPU backends */
|
||||
/* Device, which is GPU, with some common functionality for GPU back-ends. */
|
||||
class GPUDevice : public Device {
|
||||
protected:
|
||||
GPUDevice(const DeviceInfo &info_, Stats &stats_, Profiler &profiler_)
|
||||
|
|
|
@ -924,19 +924,9 @@ extern bool GHOST_setConsoleWindowState(GHOST_TConsoleWindowState action);
|
|||
extern bool GHOST_UseNativePixels(void);
|
||||
|
||||
/**
|
||||
* Warp the cursor, if supported.
|
||||
* Return features which are supported by the GHOST back-end.
|
||||
*/
|
||||
extern bool GHOST_SupportsCursorWarp(void);
|
||||
|
||||
/**
|
||||
* Support positioning windows (when false `wmWindow.x,y` are meaningless).
|
||||
*/
|
||||
extern bool GHOST_SupportsWindowPosition(void);
|
||||
|
||||
/**
|
||||
* Support a separate primary clipboard.
|
||||
*/
|
||||
extern bool GHOST_SupportsPrimaryClipboard(void);
|
||||
extern GHOST_TCapabilityFlag GHOST_GetCapabilities(void);
|
||||
|
||||
/**
|
||||
* Assign the callback which generates a back-trace (may be NULL).
|
||||
|
|
|
@ -318,19 +318,11 @@ class GHOST_ISystem {
|
|||
virtual bool useNativePixel(void) = 0;
|
||||
|
||||
/**
|
||||
* Return true when warping the cursor is supported.
|
||||
* Return features supported by the system back-end.
|
||||
*
|
||||
* The resulting value doesn't change at run-time.
|
||||
*/
|
||||
virtual bool supportsCursorWarp() = 0;
|
||||
|
||||
/**
|
||||
* Return true getting/setting the window position is supported.
|
||||
*/
|
||||
virtual bool supportsWindowPosition() = 0;
|
||||
|
||||
/**
|
||||
* Return true when a separate primary clipboard is supported.
|
||||
*/
|
||||
virtual bool supportsPrimaryClipboard() = 0;
|
||||
virtual GHOST_TCapabilityFlag getCapabilities() const = 0;
|
||||
|
||||
/**
|
||||
* Focus window after opening, or put them in the background.
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
/* This is used by `GHOST_C-api.h` too, cannot use C++ conventions. */
|
||||
// NOLINTBEGIN: modernize-use-using
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
# include "MEM_guardedalloc.h"
|
||||
#else
|
||||
|
@ -74,6 +77,37 @@ typedef void *GHOST_TUserDataPtr;
|
|||
|
||||
typedef enum { GHOST_kFailure = 0, GHOST_kSuccess } GHOST_TSuccess;
|
||||
|
||||
/**
|
||||
* Static flag (relating to the back-ends support for features).
|
||||
*
|
||||
* \note When adding new capabilities, add to #GHOST_CAPABILITY_FLAG_ALL,
|
||||
* then mask out of from the `getCapabilities(..)` callback with an explanation for why
|
||||
* the feature is not supported.
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* Set when warping the cursor is supported (re-positioning the users cursor).
|
||||
*/
|
||||
GHOST_kCapabilityCursorWarp = (1 << 0),
|
||||
/**
|
||||
* Set when getting/setting the window position is supported.
|
||||
*/
|
||||
GHOST_kCapabilityWindowPosition = (1 << 1),
|
||||
/**
|
||||
* Set when a separate primary clipboard is supported.
|
||||
* This is a convention for X11/WAYLAND, select text & MMB to paste (without an explicit copy).
|
||||
*/
|
||||
GHOST_kCapabilityPrimaryClipboard = (1 << 2),
|
||||
} GHOST_TCapabilityFlag;
|
||||
|
||||
/**
|
||||
* Back-ends should use this, masking out features which are not supported
|
||||
* with notes as to why those features cannot be supported.
|
||||
*/
|
||||
#define GHOST_CAPABILITY_FLAG_ALL \
|
||||
(GHOST_kCapabilityCursorWarp | GHOST_kCapabilityWindowPosition | \
|
||||
GHOST_kCapabilityPrimaryClipboard)
|
||||
|
||||
/* Xtilt and Ytilt represent how much the pen is tilted away from
|
||||
* vertically upright in either the X or Y direction, with X and Y the
|
||||
* axes of the tablet surface.
|
||||
|
@ -848,3 +882,5 @@ typedef struct GHOST_XrControllerModelData {
|
|||
} GHOST_XrControllerModelData;
|
||||
|
||||
#endif /* WITH_XR_OPENXR */
|
||||
|
||||
// NOLINTEND: modernize-use-using
|
||||
|
|
|
@ -895,22 +895,10 @@ bool GHOST_UseNativePixels(void)
|
|||
return system->useNativePixel();
|
||||
}
|
||||
|
||||
bool GHOST_SupportsCursorWarp(void)
|
||||
GHOST_TCapabilityFlag GHOST_GetCapabilities(void)
|
||||
{
|
||||
GHOST_ISystem *system = GHOST_ISystem::getSystem();
|
||||
return system->supportsCursorWarp();
|
||||
}
|
||||
|
||||
bool GHOST_SupportsWindowPosition(void)
|
||||
{
|
||||
GHOST_ISystem *system = GHOST_ISystem::getSystem();
|
||||
return system->supportsWindowPosition();
|
||||
}
|
||||
|
||||
bool GHOST_SupportsPrimaryClipboard(void)
|
||||
{
|
||||
GHOST_ISystem *system = GHOST_ISystem::getSystem();
|
||||
return system->supportsPrimaryClipboard();
|
||||
return system->getCapabilities();
|
||||
}
|
||||
|
||||
void GHOST_SetBacktraceHandler(GHOST_TBacktraceFn backtrace_fn)
|
||||
|
|
|
@ -418,21 +418,6 @@ void GHOST_System::setAutoFocus(const bool auto_focus)
|
|||
m_autoFocus = auto_focus;
|
||||
}
|
||||
|
||||
bool GHOST_System::supportsCursorWarp()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GHOST_System::supportsWindowPosition()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GHOST_System::supportsPrimaryClipboard()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void GHOST_System::initDebug(GHOST_Debug debug)
|
||||
{
|
||||
m_is_debug_enabled = debug.flags & GHOST_kDebugDefault;
|
||||
|
|
|
@ -150,10 +150,6 @@ class GHOST_System : public GHOST_ISystem {
|
|||
bool useNativePixel(void);
|
||||
bool m_nativePixel;
|
||||
|
||||
bool supportsCursorWarp(void);
|
||||
bool supportsWindowPosition(void);
|
||||
bool supportsPrimaryClipboard(void);
|
||||
|
||||
/**
|
||||
* Focus window after opening, or put them in the background.
|
||||
*/
|
||||
|
|
|
@ -193,6 +193,8 @@ class GHOST_SystemCocoa : public GHOST_System {
|
|||
*/
|
||||
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
|
||||
|
||||
GHOST_TCapabilityFlag getCapabilities() const;
|
||||
|
||||
/**
|
||||
* Returns Clipboard data
|
||||
* \param selection: Indicate which buffer to return.
|
||||
|
|
|
@ -900,6 +900,14 @@ GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons &buttons) const
|
|||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
GHOST_TCapabilityFlag GHOST_SystemCocoa::getCapabilities() const
|
||||
{
|
||||
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL &
|
||||
~(
|
||||
/* Cocoa has no support for a primary selection clipboard. */
|
||||
GHOST_kCapabilityPrimaryClipboard));
|
||||
}
|
||||
|
||||
#pragma mark Event handlers
|
||||
|
||||
/**
|
||||
|
|
|
@ -42,6 +42,13 @@ class GHOST_SystemHeadless : public GHOST_System {
|
|||
{
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
GHOST_TCapabilityFlag getCapabilities() const override
|
||||
{
|
||||
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL &
|
||||
/* No windowing functionality supported. */
|
||||
~(GHOST_kCapabilityWindowPosition | GHOST_kCapabilityCursorWarp |
|
||||
GHOST_kCapabilityPrimaryClipboard));
|
||||
}
|
||||
char *getClipboard(bool /*selection*/) const override
|
||||
{
|
||||
return nullptr;
|
||||
|
|
|
@ -715,7 +715,7 @@ GHOST_WindowSDL *GHOST_SystemSDL::findGhostWindow(SDL_Window *sdl_win)
|
|||
if (sdl_win == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
/* It is not entirely safe to do this as the backptr may point
|
||||
/* It is not entirely safe to do this as the back-pointer may point
|
||||
* to a window that has recently been removed.
|
||||
* We should always check the window manager's list of windows
|
||||
* and only process events on these windows. */
|
||||
|
@ -751,6 +751,15 @@ GHOST_TSuccess GHOST_SystemSDL::getButtons(GHOST_Buttons &buttons) const
|
|||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
GHOST_TCapabilityFlag GHOST_SystemSDL::getCapabilities() const
|
||||
{
|
||||
return GHOST_TCapabilityFlag(
|
||||
GHOST_CAPABILITY_FLAG_ALL &
|
||||
~(
|
||||
/* This SDL back-end has not yet implemented primary clipboard. */
|
||||
GHOST_kCapabilityPrimaryClipboard));
|
||||
}
|
||||
|
||||
char *GHOST_SystemSDL::getClipboard(bool /*selection*/) const
|
||||
{
|
||||
return (char *)SDL_GetClipboardText();
|
||||
|
|
|
@ -42,6 +42,8 @@ class GHOST_SystemSDL : public GHOST_System {
|
|||
|
||||
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
|
||||
|
||||
GHOST_TCapabilityFlag getCapabilities() const;
|
||||
|
||||
char *getClipboard(bool selection) const;
|
||||
|
||||
void putClipboard(const char *buffer, bool selection) const;
|
||||
|
|
|
@ -6675,22 +6675,16 @@ GHOST_TSuccess GHOST_SystemWayland::cursor_visibility_set(const bool visible)
|
|||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
bool GHOST_SystemWayland::supportsCursorWarp()
|
||||
GHOST_TCapabilityFlag GHOST_SystemWayland::getCapabilities() const
|
||||
{
|
||||
/* WAYLAND doesn't support setting the cursor position directly,
|
||||
* this is an intentional choice, forcing us to use a software cursor in this case. */
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GHOST_SystemWayland::supportsWindowPosition()
|
||||
{
|
||||
/* WAYLAND doesn't support accessing the window position. */
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GHOST_SystemWayland::supportsPrimaryClipboard()
|
||||
{
|
||||
return true;
|
||||
return GHOST_TCapabilityFlag(
|
||||
GHOST_CAPABILITY_FLAG_ALL &
|
||||
~(
|
||||
/* WAYLAND doesn't support accessing the window position. */
|
||||
GHOST_kCapabilityWindowPosition |
|
||||
/* WAYLAND doesn't support setting the cursor position directly,
|
||||
* this is an intentional choice, forcing us to use a software cursor in this case. */
|
||||
GHOST_kCapabilityCursorWarp));
|
||||
}
|
||||
|
||||
bool GHOST_SystemWayland::cursor_grab_use_software_display_get(const GHOST_TGrabCursorMode mode)
|
||||
|
@ -7038,7 +7032,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
|
|||
const struct GWL_SeatStateGrab grab_state_next = seat_grab_state_from_mode(mode,
|
||||
use_software_confine);
|
||||
|
||||
/* Check for wrap as #supportsCursorWarp isn't supported. */
|
||||
/* Check for wrap as #GHOST_kCapabilityCursorWarp isn't supported. */
|
||||
const bool use_visible = !(ELEM(mode, GHOST_kGrabHide, GHOST_kGrabWrap) || use_software_confine);
|
||||
const bool is_hardware_cursor = !cursor_is_software(mode, use_software_confine);
|
||||
|
||||
|
|
|
@ -142,9 +142,7 @@ class GHOST_SystemWayland : public GHOST_System {
|
|||
const bool is_dialog,
|
||||
const GHOST_IWindow *parentWindow) override;
|
||||
|
||||
bool supportsCursorWarp() override;
|
||||
bool supportsWindowPosition() override;
|
||||
bool supportsPrimaryClipboard() override;
|
||||
GHOST_TCapabilityFlag getCapabilities() const override;
|
||||
|
||||
/* WAYLAND utility functions (share window/system logic). */
|
||||
|
||||
|
|
|
@ -496,6 +496,14 @@ GHOST_TSuccess GHOST_SystemWin32::getButtons(GHOST_Buttons &buttons) const
|
|||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
GHOST_TCapabilityFlag GHOST_SystemWin32::getCapabilities() const
|
||||
{
|
||||
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL &
|
||||
~(
|
||||
/* WIN32 has no support for a primary selection clipboard. */
|
||||
GHOST_kCapabilityPrimaryClipboard));
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_SystemWin32::init()
|
||||
{
|
||||
GHOST_TSuccess success = GHOST_System::init();
|
||||
|
|
|
@ -199,6 +199,8 @@ class GHOST_SystemWin32 : public GHOST_System {
|
|||
*/
|
||||
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
|
||||
|
||||
GHOST_TCapabilityFlag getCapabilities() const;
|
||||
|
||||
/**
|
||||
* Returns unsigned char from CUT_BUFFER0
|
||||
* \param selection: Used by X11 only.
|
||||
|
|
|
@ -497,7 +497,7 @@ GHOST_WindowX11 *GHOST_SystemX11::findGhostWindow(Window xwind) const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/* It is not entirely safe to do this as the backptr may point
|
||||
/* It is not entirely safe to do this as the back-pointer may point
|
||||
* to a window that has recently been removed.
|
||||
* We should always check the window manager's list of windows
|
||||
* and only process events on these windows. */
|
||||
|
@ -1740,9 +1740,9 @@ GHOST_TSuccess GHOST_SystemX11::setCursorPosition(int32_t x, int32_t y)
|
|||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
bool GHOST_SystemX11::supportsPrimaryClipboard()
|
||||
GHOST_TCapabilityFlag GHOST_SystemX11::getCapabilities() const
|
||||
{
|
||||
return true;
|
||||
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL);
|
||||
}
|
||||
|
||||
void GHOST_SystemX11::addDirtyWindow(GHOST_WindowX11 *bad_wind)
|
||||
|
|
|
@ -168,7 +168,7 @@ class GHOST_SystemX11 : public GHOST_System {
|
|||
*/
|
||||
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
|
||||
|
||||
bool supportsPrimaryClipboard() override;
|
||||
GHOST_TCapabilityFlag getCapabilities() const;
|
||||
|
||||
/**
|
||||
* Flag a window as dirty. This will
|
||||
|
|
|
@ -1479,7 +1479,7 @@ struct FaceDetails {
|
|||
/* Details about the fallback fonts we ship, so that we can load only when needed. */
|
||||
static const struct FaceDetails static_face_details[] = {
|
||||
{"lastresort.woff2", UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX},
|
||||
{"Noto Sans CJK Regular.woff2", 0x30000083L, 0x2BDF3C10L, 0x16L, 0},
|
||||
{"Noto Sans CJK Regular.woff2", 0x30000083L, 0x29DF3C10L, 0x16L, 0},
|
||||
{"NotoEmoji-VariableFont_wght.woff2", 0x80000003L, 0x241E4ACL, 0x14000000L, 0x4000000L},
|
||||
{"NotoSansArabic-VariableFont_wdth,wght.woff2",
|
||||
TT_UCR_ARABIC,
|
||||
|
|
|
@ -631,20 +631,53 @@ static FT_UInt blf_glyph_index_from_charcode(FontBLF **font, const uint charcode
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Not found in main font, so look in the others. */
|
||||
FontBLF *last_resort = NULL;
|
||||
/* First look in currently-loaded cached fonts that match the coverage bit. Super fast. */
|
||||
int coverage_bit = blf_charcode_to_coverage_bit(charcode);
|
||||
for (int i = 0; i < BLF_MAX_FONT; i++) {
|
||||
FontBLF *f = global_font[i];
|
||||
if (!f || f == *font || !(f->face) || !(f->flags & BLF_DEFAULT) ||
|
||||
(!((*font)->flags & BLF_MONOSPACED) && (f->flags & BLF_MONOSPACED)) ||
|
||||
f->flags & BLF_LAST_RESORT) {
|
||||
continue;
|
||||
}
|
||||
if (coverage_bit < 0 || blf_font_has_coverage_bit(f, coverage_bit)) {
|
||||
glyph_index = blf_get_char_index(f, charcode);
|
||||
if (glyph_index) {
|
||||
*font = f;
|
||||
return glyph_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Next look only in unloaded fonts that match the coverage bit. */
|
||||
for (int i = 0; i < BLF_MAX_FONT; i++) {
|
||||
FontBLF *f = global_font[i];
|
||||
if (!f || f == *font || (f->face) || !(f->flags & BLF_DEFAULT) ||
|
||||
(!((*font)->flags & BLF_MONOSPACED) && (f->flags & BLF_MONOSPACED)) ||
|
||||
f->flags & BLF_LAST_RESORT) {
|
||||
continue;
|
||||
}
|
||||
if (coverage_bit < 0 || blf_font_has_coverage_bit(f, coverage_bit)) {
|
||||
glyph_index = blf_get_char_index(f, charcode);
|
||||
if (glyph_index) {
|
||||
*font = f;
|
||||
return glyph_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Last look in anything else. Also check if we have a last-resort font. */
|
||||
FontBLF *last_resort = NULL;
|
||||
for (int i = 0; i < BLF_MAX_FONT; i++) {
|
||||
FontBLF *f = global_font[i];
|
||||
if (!f || f == *font || !(f->flags & BLF_DEFAULT)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (f->flags & BLF_LAST_RESORT) {
|
||||
last_resort = f;
|
||||
continue;
|
||||
}
|
||||
if (coverage_bit < 0 || blf_font_has_coverage_bit(f, coverage_bit)) {
|
||||
if (coverage_bit >= 0 && !blf_font_has_coverage_bit(f, coverage_bit)) {
|
||||
glyph_index = blf_get_char_index(f, charcode);
|
||||
if (glyph_index) {
|
||||
*font = f;
|
||||
|
|
|
@ -132,22 +132,22 @@ bool CustomData_bmesh_has_free(const struct CustomData *data);
|
|||
bool CustomData_has_referenced(const struct CustomData *data);
|
||||
|
||||
/**
|
||||
* Copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
|
||||
* Copies the "value" (e.g. `mloopuv` UV or `mloopcol` colors) from one block to
|
||||
* another, while not overwriting anything else (e.g. flags). probably only
|
||||
* implemented for mloopuv/mloopcol, for now.
|
||||
* implemented for `mloopuv/mloopcol`, for now.
|
||||
*/
|
||||
void CustomData_data_copy_value(int type, const void *source, void *dest);
|
||||
void CustomData_data_set_default_value(int type, void *elem);
|
||||
|
||||
/**
|
||||
* Mixes the "value" (e.g. mloopuv uv or mloopcol colors) from one block into
|
||||
* Mixes the "value" (e.g. `mloopuv` UV or `mloopcol` colors) from one block into
|
||||
* another, while not overwriting anything else (e.g. flags).
|
||||
*/
|
||||
void CustomData_data_mix_value(
|
||||
int type, const void *source, void *dest, int mixmode, float mixfactor);
|
||||
|
||||
/**
|
||||
* Compares if data1 is equal to data2. type is a valid CustomData type
|
||||
* Compares if data1 is equal to data2. type is a valid #CustomData type
|
||||
* enum (e.g. #CD_PROP_FLOAT). the layer type's equal function is used to compare
|
||||
* the data, if it exists, otherwise #memcmp is used.
|
||||
*/
|
||||
|
|
|
@ -501,7 +501,7 @@ struct GPUTexture *BKE_image_create_gpu_texture_from_ibuf(struct Image *image, s
|
|||
*
|
||||
* This is provided as a separate function and not implemented as part of the GPU texture retrieval
|
||||
* functions because the current cache system only allows a single pass, layer, and stereo view to
|
||||
* be cached, so possible frequent invalidations of the cache can have performance implications,
|
||||
* be cached, so possible frequent cache invalidation can have performance implications,
|
||||
* and making invalidation explicit by calling this function will help make that clear and pave the
|
||||
* way for a more complete cache system in the future.
|
||||
*/
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "BLI_string.h"
|
||||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_string_utils.h"
|
||||
#include "BLI_tempfile.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_appdir.h" /* own include */
|
||||
|
@ -1089,7 +1090,7 @@ void BKE_appdir_app_templates(ListBase *templates)
|
|||
* Also make sure the temp dir has a trailing slash
|
||||
*
|
||||
* \param tempdir: The full path to the temporary temp directory.
|
||||
* \param tempdir_len: The size of the \a tempdir buffer.
|
||||
* \param tempdir_maxlen: The size of the \a tempdir buffer.
|
||||
* \param userdir: Directory specified in user preferences (may be NULL).
|
||||
* note that by default this is an empty string, only use when non-empty.
|
||||
*/
|
||||
|
@ -1098,37 +1099,14 @@ static void where_is_temp(char *tempdir, const size_t tempdir_maxlen, const char
|
|||
|
||||
tempdir[0] = '\0';
|
||||
|
||||
if (userdir && BLI_is_dir(userdir)) {
|
||||
if (userdir && userdir[0] != '\0' && BLI_is_dir(userdir)) {
|
||||
BLI_strncpy(tempdir, userdir, tempdir_maxlen);
|
||||
}
|
||||
|
||||
if (tempdir[0] == '\0') {
|
||||
const char *env_vars[] = {
|
||||
#ifdef WIN32
|
||||
"TEMP",
|
||||
#else
|
||||
/* Non standard (could be removed). */
|
||||
"TMP",
|
||||
/* Posix standard. */
|
||||
"TMPDIR",
|
||||
#endif
|
||||
};
|
||||
for (int i = 0; i < ARRAY_SIZE(env_vars); i++) {
|
||||
const char *tmp = BLI_getenv(env_vars[i]);
|
||||
if (tmp && (tmp[0] != '\0') && BLI_is_dir(tmp)) {
|
||||
BLI_strncpy(tempdir, tmp, tempdir_maxlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tempdir[0] == '\0') {
|
||||
BLI_strncpy(tempdir, "/tmp/", tempdir_maxlen);
|
||||
}
|
||||
else {
|
||||
/* add a trailing slash if needed */
|
||||
/* Add a trailing slash if needed. */
|
||||
BLI_path_slash_ensure(tempdir, tempdir_maxlen);
|
||||
return;
|
||||
}
|
||||
|
||||
BLI_temp_directory_path_get(tempdir, tempdir_maxlen);
|
||||
}
|
||||
|
||||
static void tempdir_session_create(char *tempdir_session,
|
||||
|
|
|
@ -1015,7 +1015,7 @@ static void layerInterp_mloopcol(const void **sources,
|
|||
/** \name Callbacks for #OrigSpaceLoop
|
||||
* \{ */
|
||||
|
||||
/* origspace is almost exact copy of mloopuv's, keep in sync */
|
||||
/* origspace is almost exact copy of #MLoopUV, keep in sync. */
|
||||
static void layerCopyValue_mloop_origspace(const void *source,
|
||||
void *dest,
|
||||
const int /*mixmode*/,
|
||||
|
|
|
@ -1847,6 +1847,13 @@ static void sculpt_update_object(
|
|||
}
|
||||
|
||||
if (is_paint_tool) {
|
||||
if (ss->vcol_domain == ATTR_DOMAIN_CORNER) {
|
||||
/* Ensure pbvh nodes have loop indices; the sculpt undo system
|
||||
* needs them for color attributes.
|
||||
*/
|
||||
BKE_pbvh_ensure_node_loops(ss->pbvh);
|
||||
}
|
||||
|
||||
/*
|
||||
* We should rebuild the PBVH_pixels when painting canvas changes.
|
||||
*
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
* This design allows some function overloads to be more efficient with certain types.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "BLI_math_base.hh"
|
||||
|
||||
namespace blender::math {
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
* the fastest and more correct option.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "BLI_math_angle_types.hh"
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_math_basis_types.hh"
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
* - Curve Tangent-Space: X-left, Y-up, Z-forward
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
* eg: `Euler3 my_euler(EulerOrder::XYZ); my_euler = my_quaternion:`
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "BLI_math_angle_types.hh"
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_math_basis_types.hh"
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* \ingroup bli
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "BLI_math_angle_types.hh"
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_math_basis_types.hh"
|
||||
|
|
|
@ -19,6 +19,7 @@ extern "C" {
|
|||
/**
|
||||
* Stored in R8G8 format. Load it in the following format:
|
||||
* - DX10: DXGI_FORMAT_R8G8_UNORM
|
||||
* - GPU: GPU_RG8 texture format and GPU_DATA_UBYTE data format.
|
||||
*/
|
||||
extern const unsigned char areaTexBytes[];
|
||||
|
||||
|
@ -30,6 +31,7 @@ extern const unsigned char areaTexBytes[];
|
|||
/**
|
||||
* Stored in R8 format. Load it in the following format:
|
||||
* - DX10: DXGI_FORMAT_R8_UNORM
|
||||
* - GPU: GPU_R8 texture format and GPU_DATA_UBYTE data format.
|
||||
*/
|
||||
extern const unsigned char searchTexBytes[];
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2023 Blender Foundation. */
|
||||
|
||||
/** \file
|
||||
* \ingroup bli
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Get the path to a directory suitable for temporary files.
|
||||
*
|
||||
* The return path is guaranteed to exist and to be a directory, as well as to contain a trailing
|
||||
* directory separator.
|
||||
*
|
||||
* At maximum the buffer_size number of characters is written to the temp_directory. The directory
|
||||
* path is always null-terminated. */
|
||||
void BLI_temp_directory_path_get(char *temp_directory, const size_t buffer_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -24,7 +24,7 @@ struct ProjCameraInfo *BLI_uvproject_camera_info(struct Object *ob,
|
|||
float winy);
|
||||
|
||||
/**
|
||||
* Apply UV from uvinfo (camera).
|
||||
* Apply UV from #ProjCameraInfo (camera).
|
||||
*/
|
||||
void BLI_uvproject_from_camera(float target[2], float source[3], struct ProjCameraInfo *uci);
|
||||
|
||||
|
|
|
@ -131,6 +131,7 @@ set(SRC
|
|||
intern/scanfill_utils.c
|
||||
intern/serialize.cc
|
||||
intern/session_uuid.c
|
||||
intern/smaa_textures.c
|
||||
intern/smallhash.c
|
||||
intern/sort.c
|
||||
intern/sort_utils.c
|
||||
|
@ -147,6 +148,7 @@ set(SRC
|
|||
intern/task_pool.cc
|
||||
intern/task_range.cc
|
||||
intern/task_scheduler.cc
|
||||
intern/tempfile.c
|
||||
intern/threads.cc
|
||||
intern/time.c
|
||||
intern/timecode.c
|
||||
|
@ -329,6 +331,7 @@ set(SRC
|
|||
BLI_set_slots.hh
|
||||
BLI_shared_cache.hh
|
||||
BLI_simd.h
|
||||
BLI_smaa_textures.h
|
||||
BLI_smallhash.h
|
||||
BLI_sort.h
|
||||
BLI_sort.hh
|
||||
|
@ -347,6 +350,7 @@ set(SRC
|
|||
BLI_system.h
|
||||
BLI_task.h
|
||||
BLI_task.hh
|
||||
BLI_tempfile.h
|
||||
BLI_threads.h
|
||||
BLI_timecode.h
|
||||
BLI_timeit.hh
|
||||
|
@ -533,6 +537,7 @@ if(WITH_GTESTS)
|
|||
tests/BLI_string_utf8_test.cc
|
||||
tests/BLI_task_graph_test.cc
|
||||
tests/BLI_task_test.cc
|
||||
tests/BLI_tempfile_test.cc
|
||||
tests/BLI_uuid_test.cc
|
||||
tests/BLI_vector_set_test.cc
|
||||
tests/BLI_vector_test.cc
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2013 Fernando Navarro <fernandn@microsoft.com>
|
||||
* 2013 Diego Gutierrez <diegog@unizar.es> */
|
||||
|
||||
#include "smaa_textures.h"
|
||||
#include "BLI_smaa_textures.h"
|
||||
|
||||
/* Don't re-wrap large data definitions. */
|
||||
/* clang-format off */
|
||||
|
@ -13,6 +13,7 @@
|
|||
/**
|
||||
* Stored in R8G8 format. Load it in the following format:
|
||||
* - DX10: DXGI_FORMAT_R8G8_UNORM
|
||||
* - GPU: GPU_RG8 texture format and GPU_DATA_UBYTE data format.
|
||||
*/
|
||||
const unsigned char areaTexBytes[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -14954,6 +14955,7 @@ const unsigned char areaTexBytes[] = {
|
|||
/**
|
||||
* Stored in R8 format. Load it in the following format:
|
||||
* - DX10: DXGI_FORMAT_R8_UNORM
|
||||
* - GPU: GPU_R8 texture format and GPU_DATA_UBYTE data format.
|
||||
*/
|
||||
const unsigned char searchTexBytes[] = {
|
||||
0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f,
|
|
@ -0,0 +1,42 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2023 Blender Foundation. */
|
||||
|
||||
#include "BLI_tempfile.h"
|
||||
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
void BLI_temp_directory_path_get(char *temp_directory, const size_t buffer_size)
|
||||
{
|
||||
temp_directory[0] = '\0';
|
||||
|
||||
const char *env_vars[] = {
|
||||
#ifdef WIN32
|
||||
"TEMP",
|
||||
#else
|
||||
/* Non standard (could be removed). */
|
||||
"TMP",
|
||||
/* Posix standard. */
|
||||
"TMPDIR",
|
||||
#endif
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(env_vars); i++) {
|
||||
const char *tmp = BLI_getenv(env_vars[i]);
|
||||
if (tmp && (tmp[0] != '\0') && BLI_is_dir(tmp)) {
|
||||
BLI_strncpy(temp_directory, tmp, buffer_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (temp_directory[0] == '\0') {
|
||||
BLI_strncpy(temp_directory, "/tmp/", buffer_size);
|
||||
}
|
||||
else {
|
||||
/* Add a trailing slash if needed. */
|
||||
BLI_path_slash_ensure(temp_directory, buffer_size);
|
||||
}
|
||||
|
||||
BLI_dir_create_recursive(temp_directory);
|
||||
}
|
|
@ -1,11 +1,16 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#include "testing/testing.h"
|
||||
|
||||
#include "BLI_fileops.hh"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_system.h"
|
||||
#include "BLI_tempfile.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include BLI_SYSTEM_PID_H
|
||||
|
||||
namespace blender::tests {
|
||||
|
||||
class ChangeWorkingDirectoryTest : public testing::Test {
|
||||
|
@ -26,6 +31,20 @@ class ChangeWorkingDirectoryTest : public testing::Test {
|
|||
|
||||
BLI_threadapi_exit();
|
||||
}
|
||||
|
||||
/* Make a pseudo-unique file name file within the temp directory in a cross-platform manner. */
|
||||
static std::string make_pseudo_unique_temp_filename()
|
||||
{
|
||||
char temp_dir[FILE_MAX];
|
||||
BLI_temp_directory_path_get(temp_dir, sizeof(temp_dir));
|
||||
|
||||
const std::string directory_name = "blender_test_" + std::to_string(getpid());
|
||||
|
||||
char filepath[FILE_MAX];
|
||||
BLI_path_join(filepath, sizeof(filepath), temp_dir, directory_name.c_str());
|
||||
|
||||
return filepath;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(fileops, fstream_open_string_filename)
|
||||
|
@ -71,7 +90,7 @@ TEST_F(ChangeWorkingDirectoryTest, change_working_directory)
|
|||
ASSERT_TRUE(original_cwd == original_cwd_buff)
|
||||
<< "Returned CWD path unexpectedly different than given char buffer.";
|
||||
|
||||
std::string temp_file_name(std::tmpnam(nullptr));
|
||||
std::string temp_file_name = make_pseudo_unique_temp_filename();
|
||||
test_temp_dir = temp_file_name + "_новый";
|
||||
|
||||
if (BLI_exists(test_temp_dir.c_str())) {
|
||||
|
@ -94,7 +113,7 @@ TEST_F(ChangeWorkingDirectoryTest, change_working_directory)
|
|||
<< "Returned CWD path unexpectedly different than given char buffer.";
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* The name returned by std::tmpnam is fine but the Apple OS method
|
||||
/* The name returned by `std::tmpnam` is fine but the Apple OS method
|
||||
* picks the true var folder, not the alias, meaning the below
|
||||
* comparison always fails unless we prepend with the correct value. */
|
||||
test_temp_dir = "/private" + test_temp_dir;
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#include "BLI_tempfile.h"
|
||||
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
#include "testing/testing.h"
|
||||
|
||||
namespace blender::tests {
|
||||
|
||||
TEST(BLI_tempfile, BLI_temp_directory_path_get)
|
||||
{
|
||||
char temp_dir[FILE_MAX];
|
||||
BLI_temp_directory_path_get(temp_dir, sizeof(temp_dir));
|
||||
|
||||
ASSERT_STRNE(temp_dir, "");
|
||||
|
||||
EXPECT_EQ(temp_dir[strlen(temp_dir) - 1], SEP);
|
||||
|
||||
EXPECT_TRUE(BLI_exists(temp_dir));
|
||||
EXPECT_TRUE(BLI_is_dir(temp_dir));
|
||||
|
||||
EXPECT_TRUE(BLI_path_is_abs_from_cwd(temp_dir));
|
||||
}
|
||||
|
||||
} // namespace blender::tests
|
|
@ -91,7 +91,7 @@
|
|||
* \subsection bm_ops Operators
|
||||
*
|
||||
* Operators are an integral part of BMesh. Unlike regular blender operators,
|
||||
* BMesh operators **bmo's** are designed to be nested (e.g. call other operators).
|
||||
* BMesh operators (abbreviated to `bmo`) are designed to be nested (e.g. call other operators).
|
||||
*
|
||||
* Each operator has a number of input/output "slots"
|
||||
* which are used to pass settings & data into/out of the operator
|
||||
|
|
|
@ -269,7 +269,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
|
|||
data1 = (fREAL *)MEM_callocN(3 * w2 * h2 * sizeof(fREAL), "convolve_fast FHT data1");
|
||||
data2 = (fREAL *)MEM_callocN(w2 * h2 * sizeof(fREAL), "convolve_fast FHT data2");
|
||||
|
||||
/* Normalize convolutor. */
|
||||
/* Normalize convolution. */
|
||||
wt[0] = wt[1] = wt[2] = 0.0f;
|
||||
for (y = 0; y < kernel_height; y++) {
|
||||
colp = (fRGB *)&kernel_buffer[y * kernel_width * COM_DATA_TYPE_COLOR_CHANNELS];
|
||||
|
|
|
@ -63,17 +63,21 @@ set(SRC
|
|||
COM_utilities.hh
|
||||
|
||||
algorithms/intern/algorithm_parallel_reduction.cc
|
||||
algorithms/intern/smaa.cc
|
||||
algorithms/intern/symmetric_separable_blur.cc
|
||||
|
||||
algorithms/COM_algorithm_parallel_reduction.hh
|
||||
algorithms/COM_algorithm_smaa.hh
|
||||
algorithms/COM_algorithm_symmetric_separable_blur.hh
|
||||
|
||||
cached_resources/intern/morphological_distance_feather_weights.cc
|
||||
cached_resources/intern/smaa_precomputed_textures.cc
|
||||
cached_resources/intern/symmetric_blur_weights.cc
|
||||
cached_resources/intern/symmetric_separable_blur_weights.cc
|
||||
|
||||
cached_resources/COM_cached_resource.hh
|
||||
cached_resources/COM_morphological_distance_feather_weights.hh
|
||||
cached_resources/COM_smaa_precomputed_textures.hh
|
||||
cached_resources/COM_symmetric_blur_weights.hh
|
||||
cached_resources/COM_symmetric_separable_blur_weights.hh
|
||||
)
|
||||
|
@ -122,6 +126,9 @@ set(GLSL_SRC
|
|||
shaders/compositor_read_pass.glsl
|
||||
shaders/compositor_realize_on_domain.glsl
|
||||
shaders/compositor_screen_lens_distortion.glsl
|
||||
shaders/compositor_smaa_blending_weight_calculation.glsl
|
||||
shaders/compositor_smaa_edge_detection.glsl
|
||||
shaders/compositor_smaa_neighborhood_blending.glsl
|
||||
shaders/compositor_split_viewer.glsl
|
||||
shaders/compositor_symmetric_blur.glsl
|
||||
shaders/compositor_symmetric_blur_variable_size.glsl
|
||||
|
@ -211,6 +218,7 @@ set(SRC_SHADER_CREATE_INFOS
|
|||
shaders/infos/compositor_read_pass_info.hh
|
||||
shaders/infos/compositor_realize_on_domain_info.hh
|
||||
shaders/infos/compositor_screen_lens_distortion_info.hh
|
||||
shaders/infos/compositor_smaa_info.hh
|
||||
shaders/infos/compositor_split_viewer_info.hh
|
||||
shaders/infos/compositor_symmetric_blur_info.hh
|
||||
shaders/infos/compositor_symmetric_blur_variable_size_info.hh
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
#include "COM_morphological_distance_feather_weights.hh"
|
||||
#include "COM_smaa_precomputed_textures.hh"
|
||||
#include "COM_symmetric_blur_weights.hh"
|
||||
#include "COM_symmetric_separable_blur_weights.hh"
|
||||
|
||||
|
@ -47,6 +48,9 @@ class StaticCacheManager {
|
|||
Map<MorphologicalDistanceFeatherWeightsKey, std::unique_ptr<MorphologicalDistanceFeatherWeights>>
|
||||
morphological_distance_feather_weights_;
|
||||
|
||||
/* A unique pointers that stores the cached SMAAPrecomputedTextures, if one is cached. */
|
||||
std::unique_ptr<SMAAPrecomputedTextures> smaa_precomputed_textures_;
|
||||
|
||||
public:
|
||||
/* Reset the cache manager by deleting the cached resources that are no longer needed because
|
||||
* they weren't used in the last evaluation and prepare the remaining cached resources to track
|
||||
|
@ -72,6 +76,11 @@ class StaticCacheManager {
|
|||
* cached for the next evaluation. */
|
||||
MorphologicalDistanceFeatherWeights &get_morphological_distance_feather_weights(int type,
|
||||
int radius);
|
||||
|
||||
/* Check if a cached SMAA precomputed texture exists, if it does, return it, otherwise, return
|
||||
* a newly created one and store it in the manager. In both cases, tag the cached resource as
|
||||
* needed to keep it cached for the next evaluation. */
|
||||
SMAAPrecomputedTextures &get_smaa_precomputed_textures();
|
||||
};
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "COM_context.hh"
|
||||
#include "COM_result.hh"
|
||||
|
||||
namespace blender::realtime_compositor {
|
||||
|
||||
/* Anti-alias the given input using the SMAA algorithm and write the result into the given output.
|
||||
* See the SMAA_THRESHOLD, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR, and SMAA_CORNER_ROUNDING defines
|
||||
* in gpu_shader_smaa_lib.glsl for information on the parameters. */
|
||||
void smaa(Context &context,
|
||||
Result &input,
|
||||
Result &output,
|
||||
float threshold,
|
||||
float local_contrast_adaptation_factor,
|
||||
int corner_rounding);
|
||||
|
||||
} // namespace blender::realtime_compositor
|
|
@ -0,0 +1,115 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_texture.h"
|
||||
|
||||
#include "COM_context.hh"
|
||||
#include "COM_utilities.hh"
|
||||
|
||||
#include "COM_algorithm_smaa.hh"
|
||||
|
||||
#include "COM_smaa_precomputed_textures.hh"
|
||||
|
||||
namespace blender::realtime_compositor {
|
||||
|
||||
static Result detect_edges(Context &context,
|
||||
Result &input,
|
||||
float threshold,
|
||||
float local_contrast_adaptation_factor)
|
||||
{
|
||||
GPUShader *shader = context.shader_manager().get("compositor_smaa_edge_detection");
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
float luminance_coefficients[3];
|
||||
IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
|
||||
|
||||
GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
|
||||
GPU_shader_uniform_1f(shader, "smaa_threshold", threshold);
|
||||
GPU_shader_uniform_1f(
|
||||
shader, "smaa_local_contrast_adaptation_factor", local_contrast_adaptation_factor);
|
||||
|
||||
GPU_texture_filter_mode(input.texture(), true);
|
||||
input.bind_as_texture(shader, "input_tx");
|
||||
|
||||
Result edges = Result::Temporary(ResultType::Color, context.texture_pool());
|
||||
edges.allocate_texture(input.domain());
|
||||
edges.bind_as_image(shader, "edges_img");
|
||||
|
||||
compute_dispatch_threads_at_least(shader, input.domain().size);
|
||||
|
||||
GPU_shader_unbind();
|
||||
input.unbind_as_texture();
|
||||
edges.unbind_as_image();
|
||||
|
||||
return edges;
|
||||
}
|
||||
|
||||
static Result calculate_blending_weights(Context &context, Result &edges, int corner_rounding)
|
||||
{
|
||||
GPUShader *shader = context.shader_manager().get("compositor_smaa_blending_weight_calculation");
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
GPU_shader_uniform_1i(shader, "smaa_corner_rounding", corner_rounding);
|
||||
|
||||
GPU_texture_filter_mode(edges.texture(), true);
|
||||
edges.bind_as_texture(shader, "edges_tx");
|
||||
|
||||
const SMAAPrecomputedTextures &smaa_precomputed_textures =
|
||||
context.cache_manager().get_smaa_precomputed_textures();
|
||||
smaa_precomputed_textures.bind_area_texture(shader, "area_tx");
|
||||
smaa_precomputed_textures.bind_search_texture(shader, "search_tx");
|
||||
|
||||
Result weights = Result::Temporary(ResultType::Color, context.texture_pool());
|
||||
weights.allocate_texture(edges.domain());
|
||||
weights.bind_as_image(shader, "weights_img");
|
||||
|
||||
compute_dispatch_threads_at_least(shader, edges.domain().size);
|
||||
|
||||
GPU_shader_unbind();
|
||||
edges.unbind_as_texture();
|
||||
smaa_precomputed_textures.unbind_area_texture();
|
||||
smaa_precomputed_textures.unbind_search_texture();
|
||||
weights.unbind_as_image();
|
||||
|
||||
return weights;
|
||||
}
|
||||
|
||||
static void blend_neighborhood(Context &context, Result &input, Result &weights, Result &output)
|
||||
{
|
||||
GPUShader *shader = context.shader_manager().get("compositor_smaa_neighborhood_blending");
|
||||
GPU_shader_bind(shader);
|
||||
|
||||
GPU_texture_filter_mode(input.texture(), true);
|
||||
input.bind_as_texture(shader, "input_tx");
|
||||
|
||||
GPU_texture_filter_mode(weights.texture(), true);
|
||||
weights.bind_as_texture(shader, "weights_tx");
|
||||
|
||||
output.allocate_texture(input.domain());
|
||||
output.bind_as_image(shader, "output_img");
|
||||
|
||||
compute_dispatch_threads_at_least(shader, input.domain().size);
|
||||
|
||||
GPU_shader_unbind();
|
||||
input.unbind_as_texture();
|
||||
weights.unbind_as_texture();
|
||||
output.unbind_as_image();
|
||||
}
|
||||
|
||||
void smaa(Context &context,
|
||||
Result &input,
|
||||
Result &output,
|
||||
float threshold,
|
||||
float local_contrast_adaptation_factor,
|
||||
int corner_rounding)
|
||||
{
|
||||
Result edges = detect_edges(context, input, threshold, local_contrast_adaptation_factor);
|
||||
Result weights = calculate_blending_weights(context, edges, corner_rounding);
|
||||
edges.release();
|
||||
blend_neighborhood(context, input, weights, output);
|
||||
weights.release();
|
||||
}
|
||||
|
||||
} // namespace blender::realtime_compositor
|
|
@ -0,0 +1,36 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_texture.h"
|
||||
|
||||
#include "COM_cached_resource.hh"
|
||||
|
||||
namespace blender::realtime_compositor {
|
||||
|
||||
/* -------------------------------------------------------------------------------------------------
|
||||
* SMAA Precomputed Textures.
|
||||
*
|
||||
* A cached resource that caches the precomputed textures needed by the SMAA algorithm. The
|
||||
* precomputed textures are constants, so this is a parameterless cached resource. */
|
||||
class SMAAPrecomputedTextures : public CachedResource {
|
||||
private:
|
||||
GPUTexture *search_texture_ = nullptr;
|
||||
GPUTexture *area_texture_ = nullptr;
|
||||
|
||||
public:
|
||||
SMAAPrecomputedTextures();
|
||||
|
||||
~SMAAPrecomputedTextures();
|
||||
|
||||
void bind_search_texture(GPUShader *shader, const char *sampler_name) const;
|
||||
|
||||
void unbind_search_texture() const;
|
||||
|
||||
void bind_area_texture(GPUShader *shader, const char *sampler_name) const;
|
||||
|
||||
void unbind_area_texture() const;
|
||||
};
|
||||
|
||||
} // namespace blender::realtime_compositor
|
|
@ -0,0 +1,64 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_smaa_textures.h"
|
||||
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_texture.h"
|
||||
|
||||
#include "COM_smaa_precomputed_textures.hh"
|
||||
|
||||
namespace blender::realtime_compositor {
|
||||
|
||||
SMAAPrecomputedTextures::SMAAPrecomputedTextures()
|
||||
{
|
||||
search_texture_ = GPU_texture_create_2d("SMAA Search",
|
||||
SEARCHTEX_WIDTH,
|
||||
SEARCHTEX_HEIGHT,
|
||||
1,
|
||||
GPU_R8,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ,
|
||||
nullptr);
|
||||
GPU_texture_update(search_texture_, GPU_DATA_UBYTE, searchTexBytes);
|
||||
GPU_texture_filter_mode(search_texture_, true);
|
||||
|
||||
area_texture_ = GPU_texture_create_2d("SMAA Area",
|
||||
AREATEX_WIDTH,
|
||||
AREATEX_HEIGHT,
|
||||
1,
|
||||
GPU_RG8,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ,
|
||||
nullptr);
|
||||
GPU_texture_update(area_texture_, GPU_DATA_UBYTE, areaTexBytes);
|
||||
GPU_texture_filter_mode(area_texture_, true);
|
||||
}
|
||||
|
||||
SMAAPrecomputedTextures::~SMAAPrecomputedTextures()
|
||||
{
|
||||
GPU_texture_free(search_texture_);
|
||||
GPU_texture_free(area_texture_);
|
||||
}
|
||||
|
||||
void SMAAPrecomputedTextures::bind_search_texture(GPUShader *shader,
|
||||
const char *sampler_name) const
|
||||
{
|
||||
const int texture_image_unit = GPU_shader_get_sampler_binding(shader, sampler_name);
|
||||
GPU_texture_bind(search_texture_, texture_image_unit);
|
||||
}
|
||||
|
||||
void SMAAPrecomputedTextures::unbind_search_texture() const
|
||||
{
|
||||
GPU_texture_unbind(search_texture_);
|
||||
}
|
||||
|
||||
void SMAAPrecomputedTextures::bind_area_texture(GPUShader *shader, const char *sampler_name) const
|
||||
{
|
||||
const int texture_image_unit = GPU_shader_get_sampler_binding(shader, sampler_name);
|
||||
GPU_texture_bind(area_texture_, texture_image_unit);
|
||||
}
|
||||
|
||||
void SMAAPrecomputedTextures::unbind_area_texture() const
|
||||
{
|
||||
GPU_texture_unbind(area_texture_);
|
||||
}
|
||||
|
||||
} // namespace blender::realtime_compositor
|
|
@ -5,6 +5,7 @@
|
|||
#include "BLI_math_vector_types.hh"
|
||||
|
||||
#include "COM_morphological_distance_feather_weights.hh"
|
||||
#include "COM_smaa_precomputed_textures.hh"
|
||||
#include "COM_symmetric_blur_weights.hh"
|
||||
#include "COM_symmetric_separable_blur_weights.hh"
|
||||
|
||||
|
@ -22,6 +23,9 @@ void StaticCacheManager::reset()
|
|||
symmetric_blur_weights_.remove_if([](auto item) { return !item.value->needed; });
|
||||
symmetric_separable_blur_weights_.remove_if([](auto item) { return !item.value->needed; });
|
||||
morphological_distance_feather_weights_.remove_if([](auto item) { return !item.value->needed; });
|
||||
if (smaa_precomputed_textures_ && !smaa_precomputed_textures_->needed) {
|
||||
smaa_precomputed_textures_.reset();
|
||||
}
|
||||
|
||||
/* Second, reset the needed status of the remaining resources to false to ready them to track
|
||||
* their needed status for the next evaluation. */
|
||||
|
@ -34,6 +38,9 @@ void StaticCacheManager::reset()
|
|||
for (auto &value : morphological_distance_feather_weights_.values()) {
|
||||
value->needed = false;
|
||||
}
|
||||
if (smaa_precomputed_textures_) {
|
||||
smaa_precomputed_textures_->needed = false;
|
||||
}
|
||||
}
|
||||
|
||||
SymmetricBlurWeights &StaticCacheManager::get_symmetric_blur_weights(int type, float2 radius)
|
||||
|
@ -71,4 +78,14 @@ MorphologicalDistanceFeatherWeights &StaticCacheManager::
|
|||
return weights;
|
||||
}
|
||||
|
||||
SMAAPrecomputedTextures &StaticCacheManager::get_smaa_precomputed_textures()
|
||||
{
|
||||
if (!smaa_precomputed_textures_) {
|
||||
smaa_precomputed_textures_ = std::make_unique<SMAAPrecomputedTextures>();
|
||||
}
|
||||
|
||||
smaa_precomputed_textures_->needed = true;
|
||||
return *smaa_precomputed_textures_;
|
||||
}
|
||||
|
||||
} // namespace blender::realtime_compositor
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
/* The dispatch domain covers the output image size, which might be a fraction of the input image
|
||||
|
@ -7,16 +5,9 @@ void main()
|
|||
* one. */
|
||||
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
/* Since the output image might be a fraction of the input image size, and since we want to
|
||||
* evaluate the input sampler at the center of the output pixel, we add an offset equal to half
|
||||
* the number of input pixels that covers a single output pixel. In case the input and output
|
||||
* have the same size, this will be 0.5, which is the offset required to evaluate the sampler at
|
||||
* the center of the pixel. */
|
||||
vec2 offset = vec2(texture_size(input_tx) / imageSize(output_img)) / 2.0;
|
||||
|
||||
/* Add the aforementioned offset and divide by the output image size to get the coordinates into
|
||||
* the sampler's expected [0, 1] range. */
|
||||
vec2 normalized_coordinates = (vec2(texel) + offset) / vec2(imageSize(output_img));
|
||||
/* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size
|
||||
* to get the coordinates into the sampler's expected [0, 1] range. */
|
||||
vec2 normalized_coordinates = (vec2(texel) + vec2(0.5)) / vec2(imageSize(output_img));
|
||||
|
||||
vec4 input_color = texture(input_tx, normalized_coordinates);
|
||||
float luminance = dot(input_color.rgb, luminance_coefficients);
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#pragma BLENDER_REQUIRE(gpu_shader_smaa_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
/* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size
|
||||
* to get the coordinates into the sampler's expected [0, 1] range. */
|
||||
vec2 coordinates = (vec2(texel) + vec2(0.5)) / vec2(texture_size(edges_tx));
|
||||
|
||||
float4 offset[3];
|
||||
vec2 pixel_coordinates;
|
||||
SMAABlendingWeightCalculationVS(coordinates, pixel_coordinates, offset);
|
||||
|
||||
vec4 weights = SMAABlendingWeightCalculationPS(
|
||||
coordinates, pixel_coordinates, offset, edges_tx, area_tx, search_tx, vec4(0.0));
|
||||
imageStore(weights_img, texel, weights);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#pragma BLENDER_REQUIRE(gpu_shader_smaa_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
/* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size
|
||||
* to get the coordinates into the sampler's expected [0, 1] range. */
|
||||
vec2 coordinates = (vec2(texel) + vec2(0.5)) / vec2(texture_size(input_tx));
|
||||
|
||||
float4 offset[3];
|
||||
SMAAEdgeDetectionVS(coordinates, offset);
|
||||
|
||||
vec2 edge = SMAALumaEdgeDetectionPS(coordinates, offset, input_tx);
|
||||
imageStore(edges_img, texel, vec4(edge, vec2(0.0)));
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#pragma BLENDER_REQUIRE(gpu_shader_smaa_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
/* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size
|
||||
* to get the coordinates into the sampler's expected [0, 1] range. */
|
||||
vec2 coordinates = (vec2(texel) + vec2(0.5)) / vec2(texture_size(input_tx));
|
||||
|
||||
vec4 offset;
|
||||
SMAANeighborhoodBlendingVS(coordinates, offset);
|
||||
|
||||
vec4 result = SMAANeighborhoodBlendingPS(coordinates, offset, input_tx, weights_tx);
|
||||
imageStore(output_img, texel, result);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "gpu_shader_create_info.hh"
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_smaa_edge_detection)
|
||||
.local_group_size(16, 16)
|
||||
.define("SMAA_GLSL_3")
|
||||
.define("SMAA_RT_METRICS",
|
||||
"vec4(1.0 / vec2(textureSize(input_tx, 0)), vec2(textureSize(input_tx, 0)))")
|
||||
.define("SMAA_LUMA_WEIGHT", "vec4(luminance_coefficients, 0.0)")
|
||||
.define("SMAA_THRESHOLD", "smaa_threshold")
|
||||
.define("SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR", "smaa_local_contrast_adaptation_factor")
|
||||
.push_constant(Type::VEC3, "luminance_coefficients")
|
||||
.push_constant(Type::FLOAT, "smaa_threshold")
|
||||
.push_constant(Type::FLOAT, "smaa_local_contrast_adaptation_factor")
|
||||
.sampler(0, ImageType::FLOAT_2D, "input_tx")
|
||||
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "edges_img")
|
||||
.compute_source("compositor_smaa_edge_detection.glsl")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_smaa_blending_weight_calculation)
|
||||
.local_group_size(16, 16)
|
||||
.define("SMAA_GLSL_3")
|
||||
.define("SMAA_RT_METRICS",
|
||||
"vec4(1.0 / vec2(textureSize(edges_tx, 0)), vec2(textureSize(edges_tx, 0)))")
|
||||
.define("SMAA_CORNER_ROUNDING", "smaa_corner_rounding")
|
||||
.push_constant(Type::INT, "smaa_corner_rounding")
|
||||
.sampler(0, ImageType::FLOAT_2D, "edges_tx")
|
||||
.sampler(1, ImageType::FLOAT_2D, "area_tx")
|
||||
.sampler(2, ImageType::FLOAT_2D, "search_tx")
|
||||
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "weights_img")
|
||||
.compute_source("compositor_smaa_blending_weight_calculation.glsl")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(compositor_smaa_neighborhood_blending)
|
||||
.local_group_size(16, 16)
|
||||
.define("SMAA_GLSL_3")
|
||||
.define("SMAA_RT_METRICS",
|
||||
"vec4(1.0 / vec2(textureSize(input_tx, 0)), vec2(textureSize(input_tx, 0)))")
|
||||
.sampler(0, ImageType::FLOAT_2D, "input_tx")
|
||||
.sampler(1, ImageType::FLOAT_2D, "weights_tx")
|
||||
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
|
||||
.compute_source("compositor_smaa_neighborhood_blending.glsl")
|
||||
.do_static_compilation(true);
|
|
@ -41,7 +41,7 @@ static inline bool is_removable_relation(const Relation *relation)
|
|||
|
||||
/* If the relation connects two different IDs there is a high risk that the removal of the
|
||||
* relation will make it so visibility flushing is not possible at runtime. This happens with
|
||||
* relations like the DoF on camera of custom shape on bines: such relation do not lead to an
|
||||
* relations like the DoF on camera of custom shape on bones: such relation do not lead to an
|
||||
* actual depsgraph evaluation operation as they are handled on render engine level.
|
||||
*
|
||||
* The indirectly linked objects could have some of their components invisible as well, so
|
||||
|
|
|
@ -103,7 +103,6 @@ set(SRC
|
|||
intern/draw_view.c
|
||||
intern/draw_view_data.cc
|
||||
intern/draw_volume.cc
|
||||
intern/smaa_textures.c
|
||||
engines/basic/basic_engine.c
|
||||
engines/basic/basic_shader.c
|
||||
engines/compositor/compositor_engine.cc
|
||||
|
@ -260,7 +259,6 @@ set(SRC
|
|||
intern/draw_view.hh
|
||||
intern/draw_view_data.h
|
||||
intern/mesh_extractors/extract_mesh.hh
|
||||
intern/smaa_textures.h
|
||||
engines/basic/basic_engine.h
|
||||
engines/basic/basic_private.h
|
||||
engines/compositor/compositor_engine.h
|
||||
|
@ -554,7 +552,6 @@ set(GLSL_SRC
|
|||
intern/shaders/common_math_lib.glsl
|
||||
intern/shaders/common_pointcloud_lib.glsl
|
||||
intern/shaders/common_shape_lib.glsl
|
||||
intern/shaders/common_smaa_lib.glsl
|
||||
intern/shaders/common_subdiv_custom_data_interp_comp.glsl
|
||||
intern/shaders/common_subdiv_ibo_lines_comp.glsl
|
||||
intern/shaders/common_subdiv_ibo_tris_comp.glsl
|
||||
|
|
|
@ -85,7 +85,7 @@ void eevee_shader_material_create_info_amend(GPUMaterial *gpumat,
|
|||
info.vertex_inputs_.clear();
|
||||
}
|
||||
else if (do_fragment_attrib_load && !info.vertex_out_interfaces_.is_empty()) {
|
||||
/* Codegen outputs only one interface. */
|
||||
/* Code-generation outputs only one interface. */
|
||||
const StageInterfaceInfo &iface = *info.vertex_out_interfaces_.first();
|
||||
/* Globals the attrib_load() can write to when it is in the fragment shader. */
|
||||
attr_load << "struct " << iface.name << " {\n";
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "gpencil_engine.h"
|
||||
|
||||
#include "smaa_textures.h"
|
||||
#include "BLI_smaa_textures.h"
|
||||
|
||||
void GPENCIL_antialiasing_init(struct GPENCIL_Data *vedata)
|
||||
{
|
||||
|
|
|
@ -21,7 +21,6 @@ extern char datatoc_gpencil_vfx_frag_glsl[];
|
|||
|
||||
extern char datatoc_common_colormanagement_lib_glsl[];
|
||||
extern char datatoc_common_fullscreen_vert_glsl[];
|
||||
extern char datatoc_common_smaa_lib_glsl[];
|
||||
extern char datatoc_common_view_lib_glsl[];
|
||||
|
||||
static struct {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
#pragma BLENDER_REQUIRE(common_smaa_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(gpu_shader_smaa_lib.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
#pragma BLENDER_REQUIRE(common_smaa_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(gpu_shader_smaa_lib.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
@ -61,10 +61,8 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
|
|||
bool show_face_dots = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) != 0 ||
|
||||
pd->edit_mesh.do_zbufclip;
|
||||
|
||||
bool show_retopology = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_RETOPOLOGY) != 0;
|
||||
float retopology_offset = (show_retopology) ?
|
||||
max_ff(v3d->overlay.retopology_offset, FLT_EPSILON) :
|
||||
0.0f;
|
||||
bool show_retopology = RETOPOLOGY_ENABLED(v3d);
|
||||
float retopology_offset = RETOPOLOGY_OFFSET(v3d);
|
||||
|
||||
pd->edit_mesh.do_faces = true;
|
||||
pd->edit_mesh.do_edges = true;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "gpu_shader_create_info.hh"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Outline Prepass
|
||||
/** \name Outline Pre-pass
|
||||
* \{ */
|
||||
|
||||
GPU_SHADER_INTERFACE_INFO(overlay_outline_prepass_iface, "interp").flat(Type::UINT, "ob_id");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
#pragma BLENDER_REQUIRE(common_smaa_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(gpu_shader_smaa_lib.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
#pragma BLENDER_REQUIRE(common_smaa_lib.glsl)
|
||||
#pragma BLENDER_REQUIRE(gpu_shader_smaa_lib.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include "BLI_jitter_2d.h"
|
||||
|
||||
#include "smaa_textures.h"
|
||||
#include "BLI_smaa_textures.h"
|
||||
|
||||
#include "workbench_private.h"
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "workbench_private.hh"
|
||||
|
||||
#include "BLI_jitter_2d.h"
|
||||
#include "smaa_textures.h"
|
||||
#include "BLI_smaa_textures.h"
|
||||
|
||||
namespace blender::workbench {
|
||||
|
||||
|
|
|
@ -188,7 +188,7 @@ bool DRW_object_is_renderable(const Object *ob)
|
|||
if (ob->type == OB_MESH) {
|
||||
if ((ob == DST.draw_ctx.object_edit) || DRW_object_is_in_edit_mode(ob)) {
|
||||
View3D *v3d = DST.draw_ctx.v3d;
|
||||
if (v3d && v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_RETOPOLOGY) {
|
||||
if (v3d && RETOPOLOGY_ENABLED(v3d)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -281,6 +281,12 @@ static bool find_fcurve_segment(FCurve *fcu,
|
|||
ListBase find_fcurve_segments(FCurve *fcu)
|
||||
{
|
||||
ListBase segments = {NULL, NULL};
|
||||
|
||||
/* Ignore baked curves. */
|
||||
if (!fcu->bezt) {
|
||||
return segments;
|
||||
}
|
||||
|
||||
int segment_start_idx = 0;
|
||||
int segment_len = 0;
|
||||
int current_index = 0;
|
||||
|
|
|
@ -1097,7 +1097,7 @@ static void extrude_points_from_selected_vertices(const ViewContext *vc,
|
|||
if (sel_exists) {
|
||||
float disp_3d[3];
|
||||
sub_v3_v3v3(disp_3d, location, center);
|
||||
/* Reimplemenented due to unexpected behavior for extrusion of 2-point spline. */
|
||||
/* Reimplemented due to unexpected behavior for extrusion of 2-point spline. */
|
||||
extrude_vertices_from_selected_endpoints(editnurb, nurbs, cu, disp_3d);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -695,6 +695,7 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
|
|||
}
|
||||
}
|
||||
|
||||
curves.tag_positions_changed();
|
||||
DEG_id_tag_update(&curves_id.id, ID_RECALC_GEOMETRY);
|
||||
}
|
||||
|
||||
|
|
|
@ -1328,6 +1328,14 @@ void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrAr
|
|||
#define XRAY_ENABLED(v3d) SHADING_XRAY_ENABLED((v3d)->shading)
|
||||
#define XRAY_ACTIVE(v3d) SHADING_XRAY_ACTIVE((v3d)->shading)
|
||||
|
||||
#define OVERLAY_RETOPOLOGY_ENABLED(overlay) \
|
||||
(((overlay).edit_flag & V3D_OVERLAY_EDIT_RETOPOLOGY) != 0)
|
||||
#define OVERLAY_RETOPOLOGY_OFFSET(overlay) \
|
||||
(OVERLAY_RETOPOLOGY_ENABLED(overlay) ? max_ff((overlay).retopology_offset, FLT_EPSILON) : 0.0f)
|
||||
|
||||
#define RETOPOLOGY_ENABLED(v3d) (OVERLAY_RETOPOLOGY_ENABLED((v3d)->overlay))
|
||||
#define RETOPOLOGY_OFFSET(v3d) (OVERLAY_RETOPOLOGY_OFFSET((v3d)->overlay))
|
||||
|
||||
/* view3d_draw_legacy.c */
|
||||
|
||||
/**
|
||||
|
|
|
@ -512,6 +512,7 @@ bool paintface_mouse_select(bContext *C,
|
|||
ED_region_tag_redraw(CTX_wm_region(C)); /* XXX: should redraw all 3D views. */
|
||||
changed = true;
|
||||
}
|
||||
select_poly.finish();
|
||||
return changed || found;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,11 +34,13 @@
|
|||
#include "ED_mesh.h"
|
||||
|
||||
#include "paint_intern.h" /* own include */
|
||||
#include "sculpt_intern.hh"
|
||||
|
||||
using blender::Array;
|
||||
using blender::ColorGeometry4f;
|
||||
using blender::GMutableSpan;
|
||||
using blender::IndexMask;
|
||||
using blender::IndexRange;
|
||||
using blender::Vector;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -245,20 +247,20 @@ void PAINT_OT_vertex_color_smooth(wmOperatorType *ot)
|
|||
* \{ */
|
||||
|
||||
template<typename TransformFn>
|
||||
static bool transform_active_color(Mesh &mesh, const TransformFn &transform_fn)
|
||||
static void transform_active_color_data(Mesh &mesh, const TransformFn &transform_fn)
|
||||
{
|
||||
using namespace blender;
|
||||
const StringRef name = mesh.active_color_attribute;
|
||||
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
|
||||
if (!attributes.contains(name)) {
|
||||
BLI_assert_unreachable();
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
bke::GAttributeWriter color_attribute = attributes.lookup_for_write(name);
|
||||
if (!color_attribute) {
|
||||
BLI_assert_unreachable();
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
Vector<int64_t> indices;
|
||||
|
@ -286,8 +288,34 @@ static bool transform_active_color(Mesh &mesh, const TransformFn &transform_fn)
|
|||
color_attribute.finish();
|
||||
|
||||
DEG_id_tag_update(&mesh.id, 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
template<typename TransformFn>
|
||||
static void transform_active_color(bContext *C, wmOperator *op, const TransformFn &transform_fn)
|
||||
{
|
||||
Object *obact = CTX_data_active_object(C);
|
||||
|
||||
/* Ensure valid sculpt state. */
|
||||
BKE_sculpt_update_object_for_edit(
|
||||
CTX_data_ensure_evaluated_depsgraph(C), obact, true, false, true);
|
||||
|
||||
SCULPT_undo_push_begin(obact, op);
|
||||
PBVHNode **nodes;
|
||||
int nodes_num;
|
||||
|
||||
BKE_pbvh_search_gather(obact->sculpt->pbvh, nullptr, nullptr, &nodes, &nodes_num);
|
||||
for (int i : IndexRange(nodes_num)) {
|
||||
SCULPT_undo_push_node(obact, nodes[i], SCULPT_UNDO_COLOR);
|
||||
}
|
||||
|
||||
transform_active_color_data(*BKE_mesh_from_object(obact), transform_fn);
|
||||
|
||||
for (int i : IndexRange(nodes_num)) {
|
||||
BKE_pbvh_node_mark_update_color(nodes[i]);
|
||||
}
|
||||
|
||||
SCULPT_undo_push_end(obact);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
|
||||
}
|
||||
|
||||
static int vertex_color_brightness_contrast_exec(bContext *C, wmOperator *op)
|
||||
|
@ -323,14 +351,12 @@ static int vertex_color_brightness_contrast_exec(bContext *C, wmOperator *op)
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
transform_active_color(*me, [&](ColorGeometry4f &color) {
|
||||
transform_active_color(C, op, [&](ColorGeometry4f &color) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
color[i] = gain * color[i] + offset;
|
||||
}
|
||||
});
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
@ -371,7 +397,7 @@ static int vertex_color_hsv_exec(bContext *C, wmOperator *op)
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
transform_active_color(*me, [&](ColorGeometry4f &color) {
|
||||
transform_active_color(C, op, [&](ColorGeometry4f &color) {
|
||||
float hsv[3];
|
||||
rgb_to_hsv_v(color, hsv);
|
||||
|
||||
|
@ -388,8 +414,6 @@ static int vertex_color_hsv_exec(bContext *C, wmOperator *op)
|
|||
hsv_to_rgb_v(hsv, color);
|
||||
});
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
@ -413,7 +437,7 @@ void PAINT_OT_vertex_color_hsv(wmOperatorType *ot)
|
|||
RNA_def_float(ot->srna, "v", 1.0f, 0.0f, 2.0f, "Value", "", 0.0f, 2.0f);
|
||||
}
|
||||
|
||||
static int vertex_color_invert_exec(bContext *C, wmOperator * /*op*/)
|
||||
static int vertex_color_invert_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *obact = CTX_data_active_object(C);
|
||||
|
||||
|
@ -423,14 +447,12 @@ static int vertex_color_invert_exec(bContext *C, wmOperator * /*op*/)
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
transform_active_color(*me, [&](ColorGeometry4f &color) {
|
||||
transform_active_color(C, op, [&](ColorGeometry4f &color) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
color[i] = 1.0f - color[i];
|
||||
}
|
||||
});
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
@ -462,7 +484,7 @@ static int vertex_color_levels_exec(bContext *C, wmOperator *op)
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
transform_active_color(*me, [&](ColorGeometry4f &color) {
|
||||
transform_active_color(C, op, [&](ColorGeometry4f &color) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
color[i] = gain * (color[i] + offset);
|
||||
}
|
||||
|
|
|
@ -480,7 +480,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region
|
|||
/** \name Timeline - Caches
|
||||
* \{ */
|
||||
|
||||
static bool timeline_cache_is_hidden_by_setting(SpaceAction *saction, PTCacheID *pid)
|
||||
static bool timeline_cache_is_hidden_by_setting(const SpaceAction *saction, const PTCacheID *pid)
|
||||
{
|
||||
switch (pid->type) {
|
||||
case PTCACHE_TYPE_SOFTBODY:
|
||||
|
@ -674,14 +674,14 @@ static void timeline_cache_draw_single(PTCacheID *pid, float y_offset, float hei
|
|||
GPU_matrix_pop();
|
||||
}
|
||||
|
||||
void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene)
|
||||
void timeline_draw_cache(const SpaceAction *saction, const Object *ob, const Scene *scene)
|
||||
{
|
||||
if ((saction->cache_display & TIME_CACHE_DISPLAY) == 0 || ob == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
ListBase pidlist;
|
||||
BKE_ptcache_ids_from_object(&pidlist, ob, scene, 0);
|
||||
BKE_ptcache_ids_from_object(&pidlist, const_cast<Object *>(ob), const_cast<Scene *>(scene), 0);
|
||||
|
||||
uint pos_id = GPU_vertformat_attr_add(
|
||||
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
|
|
|
@ -35,7 +35,7 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region);
|
|||
*/
|
||||
void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region);
|
||||
|
||||
void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene);
|
||||
void timeline_draw_cache(const SpaceAction *saction, const Object *ob, const Scene *scene);
|
||||
|
||||
/* ***************************************** */
|
||||
/* action_select.c */
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
|
||||
#include "BLO_read_write.h"
|
||||
|
||||
#include "GPU_matrix.h"
|
||||
|
||||
#include "action_intern.hh" /* own include */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -212,11 +214,6 @@ static void action_main_region_draw(const bContext *C, ARegion *region)
|
|||
ED_markers_draw(C, marker_flag);
|
||||
}
|
||||
|
||||
/* caches */
|
||||
if (saction->mode == SACTCONT_TIMELINE) {
|
||||
timeline_draw_cache(saction, obact, scene);
|
||||
}
|
||||
|
||||
/* preview range */
|
||||
UI_view2d_view_ortho(v2d);
|
||||
ANIM_draw_previewrange(C, v2d, 0);
|
||||
|
@ -240,8 +237,17 @@ static void action_main_region_draw_overlay(const bContext *C, ARegion *region)
|
|||
/* draw entirely, view changes should be handled here */
|
||||
const SpaceAction *saction = CTX_wm_space_action(C);
|
||||
const Scene *scene = CTX_data_scene(C);
|
||||
const Object *obact = CTX_data_active_object(C);
|
||||
View2D *v2d = ®ion->v2d;
|
||||
|
||||
/* caches */
|
||||
if (saction->mode == SACTCONT_TIMELINE) {
|
||||
GPU_matrix_push_projection();
|
||||
UI_view2d_view_orthoSpecial(region, v2d, 1);
|
||||
timeline_draw_cache(saction, obact, scene);
|
||||
GPU_matrix_pop_projection();
|
||||
}
|
||||
|
||||
/* scrubbing region */
|
||||
ED_time_scrub_draw_current_frame(region, scene, saction->flag & SACTION_DRAWTIME);
|
||||
|
||||
|
|
|
@ -703,7 +703,7 @@ static void draw_fcurve_curve_samples(bAnimContext *ac,
|
|||
const uint shdr_pos,
|
||||
const bool draw_extrapolation)
|
||||
{
|
||||
if (!draw_extrapolation) {
|
||||
if (!draw_extrapolation && fcu->totvert == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -816,7 +816,7 @@ static bool fcurve_can_use_simple_bezt_drawing(FCurve *fcu)
|
|||
static void draw_fcurve_curve_bezts(
|
||||
bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, uint pos, const bool draw_extrapolation)
|
||||
{
|
||||
if (!draw_extrapolation) {
|
||||
if (!draw_extrapolation && fcu->totvert == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1136,12 +1136,11 @@ static void gaussian_smooth_free_operator_data(void *operator_data)
|
|||
static void gaussian_smooth_draw_status_header(bContext *C, tGraphSliderOp *gso)
|
||||
{
|
||||
char status_str[UI_MAX_DRAW_STR];
|
||||
char mode_str[32];
|
||||
char slider_string[UI_MAX_DRAW_STR];
|
||||
|
||||
ED_slider_status_string_get(gso->slider, slider_string, UI_MAX_DRAW_STR);
|
||||
|
||||
strcpy(mode_str, TIP_("Gauss Smooth"));
|
||||
const char *mode_str = TIP_("Gaussian Smooth");
|
||||
|
||||
if (hasNumInput(&gso->num)) {
|
||||
char str_ofs[NUM_STR_REP_LEN];
|
||||
|
@ -1274,7 +1273,7 @@ void GRAPH_OT_gaussian_smooth(wmOperatorType *ot)
|
|||
/* Identifiers. */
|
||||
ot->name = "Gaussian Smooth";
|
||||
ot->idname = "GRAPH_OT_gaussian_smooth";
|
||||
ot->description = "Smooth the curve using a Gauss filter";
|
||||
ot->description = "Smooth the curve using a Gaussian filter";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->invoke = gaussian_smooth_invoke;
|
||||
|
@ -1301,7 +1300,7 @@ void GRAPH_OT_gaussian_smooth(wmOperatorType *ot)
|
|||
0.001f,
|
||||
FLT_MAX,
|
||||
"Sigma",
|
||||
"The shape of the gauss distribution, lower values make it sharper",
|
||||
"The shape of the gaussian distribution, lower values make it sharper",
|
||||
0.001f,
|
||||
100.0f);
|
||||
|
||||
|
|
|
@ -805,7 +805,7 @@ static bool image_undosys_step_encode(struct bContext *C, struct Main * /*bmain*
|
|||
us_reference = reinterpret_cast<ImageUndoStep *>(us_reference->step.prev);
|
||||
}
|
||||
|
||||
/* Initialize undo tiles from ptiles (if they exist). */
|
||||
/* Initialize undo tiles from paint-tiles (if they exist). */
|
||||
for (PaintTile *ptile : us->paint_tile_map->map.values()) {
|
||||
if (ptile->valid) {
|
||||
UndoImageHandle *uh = uhandle_ensure(&us->handles, ptile->image, &ptile->iuser);
|
||||
|
|
|
@ -263,8 +263,11 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
|
|||
const float2 offset = (mouse_location - center) / UI_SCALE_FAC;
|
||||
|
||||
for (bNode *new_node : node_map.values()) {
|
||||
new_node->locx += offset.x;
|
||||
new_node->locy += offset.y;
|
||||
/* Skip the offset for parented nodes since the location is in parent space. */
|
||||
if (new_node->parent == nullptr) {
|
||||
new_node->locx += offset.x;
|
||||
new_node->locy += offset.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2722,7 +2722,8 @@ static void frame_node_prepare_for_draw(bNode &node, Span<bNode *> nodes)
|
|||
const float has_label = node.label[0] != '\0';
|
||||
|
||||
const float label_height = frame_node_label_height(*data);
|
||||
/* Add an additional 25 % to account for the descenders. This works well in most cases. */
|
||||
/* Add an additional 25% to account for the glyphs descender.
|
||||
* This works well in most cases. */
|
||||
const float margin_top = 0.5f * margin + (has_label ? 1.25f * label_height : 0.5f * margin);
|
||||
|
||||
/* Initialize rect from current frame size. */
|
||||
|
|
|
@ -419,16 +419,6 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
exit_code = transformEvent(t, event);
|
||||
t->context = NULL;
|
||||
|
||||
/* XXX, workaround: active needs to be calculated before transforming,
|
||||
* since we're not reading from 'td->center' in this case. see: #40241 */
|
||||
if (t->tsnap.source_operation == SCE_SNAP_SOURCE_ACTIVE) {
|
||||
/* In camera view, tsnap callback is not set
|
||||
* (see #initSnappingMode() in transform_snap.c, and #40348). */
|
||||
if (t->tsnap.snap_source_fn && ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0)) {
|
||||
t->tsnap.snap_source_fn(t);
|
||||
}
|
||||
}
|
||||
|
||||
transformApply(C, t);
|
||||
|
||||
exit_code |= transformEnd(C, t);
|
||||
|
|
|
@ -947,6 +947,11 @@ static void setSnappingCallback(TransInfo *t)
|
|||
break;
|
||||
case SCE_SNAP_SOURCE_ACTIVE:
|
||||
t->tsnap.snap_source_fn = snap_source_active_fn;
|
||||
|
||||
/* XXX, workaround: active needs to be calculated before transforming, otherwise
|
||||
* `t->tsnap.snap_source` will be calculated with the transformed data since we're not
|
||||
* reading from 'td->center' in this case. (See: #40241 and #40348). */
|
||||
snap_source_active_fn(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1230,13 +1235,18 @@ static void snap_source_active_fn(TransInfo *t)
|
|||
{
|
||||
/* Only need to calculate once */
|
||||
if ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0) {
|
||||
if (calculateCenterActive(t, true, t->tsnap.snap_source)) {
|
||||
if (t->around == V3D_AROUND_ACTIVE) {
|
||||
/* Just copy the already calculated active center. */
|
||||
copy_v3_v3(t->tsnap.snap_source, t->center_global);
|
||||
TargetSnapOffset(t, nullptr);
|
||||
t->tsnap.status |= SNAP_SOURCE_FOUND;
|
||||
}
|
||||
else if (calculateCenterActive(t, true, t->tsnap.snap_source)) {
|
||||
TargetSnapOffset(t, nullptr);
|
||||
|
||||
t->tsnap.status |= SNAP_SOURCE_FOUND;
|
||||
}
|
||||
/* No active, default to median */
|
||||
else {
|
||||
/* No active, default to median, */
|
||||
t->tsnap.source_operation = SCE_SNAP_SOURCE_MEDIAN;
|
||||
t->tsnap.snap_source_fn = snap_source_median_fn;
|
||||
snap_source_median_fn(t);
|
||||
|
|
|
@ -1166,8 +1166,8 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Object *obedit)
|
|||
bool changed = false;
|
||||
const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
|
||||
|
||||
/* index every vert that has a selected UV using it, but only once so as to
|
||||
* get unique indices and to count how much to malloc */
|
||||
/* Index every vert that has a selected UV using it, but only once so as to
|
||||
* get unique indices and to count how much to `malloc`. */
|
||||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
||||
if (uvedit_face_visible_test(scene, f)) {
|
||||
BM_elem_flag_enable(f, BM_ELEM_TAG);
|
||||
|
|
|
@ -280,7 +280,7 @@ class Occupancy {
|
|||
mutable float witness_distance_; /* Signed distance to nearest placed island. */
|
||||
mutable uint triangle_hint_; /* Hint to a previously suspected overlapping triangle. */
|
||||
|
||||
const float terminal = 1048576.0f; /* A "very" large number, much bigger than 4 * bitmap_radix */
|
||||
const float terminal = 1048576.0f; /* 4 * bitmap_radix < terminal < INT_MAX / 4. */
|
||||
};
|
||||
|
||||
Occupancy::Occupancy(const float initial_scale)
|
||||
|
@ -352,8 +352,9 @@ float Occupancy::trace_triangle(const float2 &uv0,
|
|||
if (iy0 <= witness_.y && witness_.y < iy1) {
|
||||
const float distance = signed_distance_fat_triangle(witness_, uv0s, uv1s, uv2s);
|
||||
const float extent = epsilon - distance - witness_distance_;
|
||||
if (extent > 0.0f) {
|
||||
return extent; /* Witness observes occupied. */
|
||||
const float pixel_round_off = -0.1f; /* Go faster on nearly-axis aligned edges. */
|
||||
if (extent > pixel_round_off) {
|
||||
return std::max(0.0f, extent); /* Witness observes occupied. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -392,7 +393,7 @@ float Occupancy::trace_island(PackIsland *island,
|
|||
|
||||
if (!write) {
|
||||
if (uv.x <= 0.0f || uv.y <= 0.0f) {
|
||||
return std::max(-uv.x, -uv.y); /* Occupied. */
|
||||
return terminal; /* Occupied. */
|
||||
}
|
||||
}
|
||||
const float2 origin(island->bounds_rect.xmin, island->bounds_rect.ymin);
|
||||
|
@ -421,9 +422,21 @@ static float2 find_best_fit_for_island(
|
|||
const float size_x_scaled = BLI_rctf_size_x(&island->bounds_rect) * scale;
|
||||
const float size_y_scaled = BLI_rctf_size_y(&island->bounds_rect) * scale;
|
||||
|
||||
/* Scan using an "Alpaca"-style search, first vertically. */
|
||||
/* Scan using an "Alpaca"-style search, first horizontally using "less-than". */
|
||||
|
||||
int t = 0;
|
||||
int t = int(ceilf(size_x_scaled * occupancy.bitmap_scale_reciprocal));
|
||||
while (t < scan_line) {
|
||||
const float t_bscaled = t / occupancy.bitmap_scale_reciprocal;
|
||||
const float2 probe(t_bscaled - size_x_scaled, scan_line_bscaled - size_y_scaled);
|
||||
const float extent = occupancy.trace_island(island, scale, margin, probe, false);
|
||||
if (extent < 0.0f) {
|
||||
return probe;
|
||||
}
|
||||
t = t + std::max(1, int(extent));
|
||||
}
|
||||
|
||||
/* Then scan vertically using "less-than-or-equal" */
|
||||
t = int(ceilf(size_y_scaled * occupancy.bitmap_scale_reciprocal));
|
||||
while (t <= scan_line) {
|
||||
const float t_bscaled = t / occupancy.bitmap_scale_reciprocal;
|
||||
const float2 probe(scan_line_bscaled - size_x_scaled, t_bscaled - size_y_scaled);
|
||||
|
@ -434,17 +447,6 @@ static float2 find_best_fit_for_island(
|
|||
t = t + std::max(1, int(extent));
|
||||
}
|
||||
|
||||
/* Now scan horizontally. */
|
||||
t = 0;
|
||||
while (t <= scan_line) {
|
||||
const float t_bscaled = t / occupancy.bitmap_scale_reciprocal;
|
||||
const float2 probe(t_bscaled - size_x_scaled, scan_line_bscaled - size_y_scaled);
|
||||
const float extent = occupancy.trace_island(island, scale, margin, probe, false);
|
||||
if (extent < 0.0f) {
|
||||
return probe;
|
||||
}
|
||||
t = t + std::max(1, int(extent));
|
||||
}
|
||||
return float2(-1, -1);
|
||||
}
|
||||
|
||||
|
@ -458,7 +460,7 @@ static float guess_initial_scale(const Span<PackIsland *> islands,
|
|||
sum += BLI_rctf_size_x(&island->bounds_rect) * scale + 2 * margin;
|
||||
sum += BLI_rctf_size_y(&island->bounds_rect) * scale + 2 * margin;
|
||||
}
|
||||
return sqrtf(sum) / 3.0f;
|
||||
return sqrtf(sum) / 6.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -437,6 +437,7 @@ set(GLSL_SRC
|
|||
shaders/common/gpu_shader_math_matrix_lib.glsl
|
||||
shaders/common/gpu_shader_math_rotation_lib.glsl
|
||||
shaders/common/gpu_shader_math_vector_lib.glsl
|
||||
shaders/common/gpu_shader_smaa_lib.glsl
|
||||
shaders/common/gpu_shader_test_lib.glsl
|
||||
shaders/common/gpu_shader_utildefines_lib.glsl
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
typedef struct TestOutputRawData TestOutputRawData;
|
||||
#endif
|
||||
|
||||
/* NOTE: float3 has differing stride and alignment rules across different GPU backends. If 12 byte
|
||||
/* NOTE: float3 has differing stride and alignment rules across different GPU back-ends. If 12 byte
|
||||
* stride and alignment is essential, use `packed_float3` to avoid data read issues. This is
|
||||
* required in the common use-case where a float3 and an int/float are paired together for optimal
|
||||
* data transfer. */
|
||||
|
|
|
@ -34,9 +34,9 @@ namespace gpu {
|
|||
class GLBackend : public GPUBackend {
|
||||
private:
|
||||
GLSharedOrphanLists shared_orphan_list_;
|
||||
#ifdef WITH_RENDERDOC
|
||||
#ifdef WITH_RENDERDOC
|
||||
renderdoc::api::Renderdoc renderdoc_;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
public:
|
||||
GLBackend()
|
||||
|
|
|
@ -774,14 +774,19 @@ float2 SMAALumaEdgeDetectionPS(float2 texcoord,
|
|||
delta.xy = abs(L - float2(Lleft, Ltop));
|
||||
float2 edges = step(threshold, delta.xy);
|
||||
|
||||
# ifndef SMAA_NO_DISCARD
|
||||
# ifdef GPU_FRAGMENT_SHADER
|
||||
# ifdef GPU_FRAGMENT_SHADER
|
||||
# ifndef SMAA_NO_DISCARD
|
||||
// Then discard if there is no edge:
|
||||
if (dot(edges, float2(1.0, 1.0)) == 0.0) {
|
||||
discard;
|
||||
return float2(0.0, 0.0);
|
||||
}
|
||||
# endif
|
||||
# elif defined(GPU_COMPUTE_SHADER)
|
||||
// Then return early if there is no edge:
|
||||
if (dot(edges, float2(1.0, 1.0)) == 0.0) {
|
||||
return float2(0.0);
|
||||
}
|
||||
# endif
|
||||
|
||||
// Calculate right and bottom deltas:
|
||||
|
@ -802,9 +807,7 @@ float2 SMAALumaEdgeDetectionPS(float2 texcoord,
|
|||
float finalDelta = max(maxDelta.x, maxDelta.y);
|
||||
|
||||
// Local contrast adaptation:
|
||||
# if !defined(SHADER_API_OPENGL)
|
||||
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
|
||||
# endif
|
||||
|
||||
return edges;
|
||||
}
|
||||
|
@ -882,9 +885,7 @@ float2 SMAAColorEdgeDetectionPS(float2 texcoord,
|
|||
float finalDelta = max(maxDelta.x, maxDelta.y);
|
||||
|
||||
// Local contrast adaptation:
|
||||
# if !defined(SHADER_API_OPENGL)
|
||||
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
|
||||
# endif
|
||||
|
||||
return edges;
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
#define RUN_UNSUPPORTED false
|
||||
|
||||
/* Skip tests that haven't been developed yet due to non standard data types or it needs an
|
||||
* framebuffer to create the texture. */
|
||||
* frame-buffer to create the texture. */
|
||||
#define RUN_SRGB_UNIMPLEMENTED false
|
||||
#define RUN_NON_STANDARD_UNIMPLEMENTED false
|
||||
#define RUN_COMPONENT_UNIMPLEMENTED false
|
||||
|
@ -168,7 +168,7 @@ static void texture_create_upload_read_pixel()
|
|||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_FLOAT
|
||||
/** \name Round-trip testing GPU_DATA_FLOAT
|
||||
* \{ */
|
||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8()
|
||||
{
|
||||
|
@ -422,7 +422,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT16);
|
|||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_HALF_FLOAT
|
||||
/** \name Round-trip testing GPU_DATA_HALF_FLOAT
|
||||
* \{ */
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGBA16F()
|
||||
|
@ -454,7 +454,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGB16F);
|
|||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_INT
|
||||
/** \name Round-trip testing GPU_DATA_INT
|
||||
* \{ */
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGBA8I()
|
||||
|
@ -534,7 +534,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGB32I);
|
|||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_UINT
|
||||
/** \name Round-trip testing GPU_DATA_UINT
|
||||
* \{ */
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGBA8UI()
|
||||
|
@ -648,7 +648,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT16);
|
|||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_UBYTE
|
||||
/** \name Round-trip testing GPU_DATA_UBYTE
|
||||
* \{ */
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RGBA8UI()
|
||||
|
@ -717,7 +717,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8);
|
|||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_UINT_24_8
|
||||
/** \name Round-trip testing GPU_DATA_UINT_24_8
|
||||
* \{ */
|
||||
|
||||
#if RUN_UNSUPPORTED
|
||||
|
@ -737,7 +737,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_UINT_24_8__GPU_DEPTH24_STENCIL8);
|
|||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_10_11_11_REV
|
||||
/** \name Round-trip testing GPU_DATA_10_11_11_REV
|
||||
* \{ */
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_10_11_11_REV__GPU_R11F_G11F_B10F()
|
||||
|
@ -749,7 +749,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_10_11_11_REV__GPU_R11F_G11F_B10F);
|
|||
/* \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Roundtrip testing GPU_DATA_2_10_10_10_REV
|
||||
/** \name Round-trip testing GPU_DATA_2_10_10_10_REV
|
||||
* \{ */
|
||||
|
||||
static void test_texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2()
|
||||
|
|
|
@ -89,7 +89,7 @@ typedef struct NoiseGpencilModifierData {
|
|||
char layername[64];
|
||||
/** Material name. */
|
||||
char materialname[64] DNA_DEPRECATED;
|
||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
||||
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||
char vgname[64];
|
||||
/** Custom index for passes. */
|
||||
int pass_index;
|
||||
|
@ -175,7 +175,7 @@ typedef struct ThickGpencilModifierData {
|
|||
char layername[64];
|
||||
/** Material name. */
|
||||
char materialname[64] DNA_DEPRECATED;
|
||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
||||
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||
char vgname[64];
|
||||
/** Custom index for passes. */
|
||||
int pass_index;
|
||||
|
@ -308,7 +308,7 @@ typedef struct OpacityGpencilModifierData {
|
|||
char layername[64];
|
||||
/** Material name. */
|
||||
char materialname[64] DNA_DEPRECATED;
|
||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
||||
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||
char vgname[64];
|
||||
/** Custom index for passes. */
|
||||
int pass_index;
|
||||
|
@ -457,11 +457,11 @@ typedef struct BuildGpencilModifierData {
|
|||
*/
|
||||
short time_alignment;
|
||||
|
||||
/* Speed factor for GP_BUILD_TIMEMODE_DRAWSPEED. */
|
||||
/** Speed factor for #GP_BUILD_TIMEMODE_DRAWSPEED. */
|
||||
float speed_fac;
|
||||
/* Maxmium time gap between strokes for GP_BUILD_TIMEMODE_DRAWSPEED. */
|
||||
/** Maximum time gap between strokes for #GP_BUILD_TIMEMODE_DRAWSPEED. */
|
||||
float speed_maxgap;
|
||||
/* Which time mode should be used. */
|
||||
/** Which time mode should be used. */
|
||||
short time_mode;
|
||||
char _pad[6];
|
||||
|
||||
|
@ -473,7 +473,7 @@ typedef struct BuildGpencilModifierData {
|
|||
|
||||
/** Weight fading at the end of the stroke. */
|
||||
float fade_fac;
|
||||
/** Target vertexgroup name, MAX_VGROUP_NAME. */
|
||||
/** Target vertex-group name, #MAX_VGROUP_NAME. */
|
||||
char target_vgname[64];
|
||||
/** Fading strength of opacity and thickness */
|
||||
float fade_opacity_strength;
|
||||
|
@ -508,11 +508,11 @@ typedef enum eBuildGpencil_TimeAlignment {
|
|||
} eBuildGpencil_TimeAlignment;
|
||||
|
||||
typedef enum eBuildGpencil_TimeMode {
|
||||
/* Use a number of frames build. */
|
||||
/** Use a number of frames build. */
|
||||
GP_BUILD_TIMEMODE_FRAMES = 0,
|
||||
/* Use manual percentage to build. */
|
||||
/** Use manual percentage to build. */
|
||||
GP_BUILD_TIMEMODE_PERCENTAGE = 1,
|
||||
/* Use factor of recorded speed to build. */
|
||||
/** Use factor of recorded speed to build. */
|
||||
GP_BUILD_TIMEMODE_DRAWSPEED = 2,
|
||||
} eBuildGpencil_TimeMode;
|
||||
|
||||
|
@ -536,7 +536,7 @@ typedef struct LatticeGpencilModifierData {
|
|||
char layername[64];
|
||||
/** Material name. */
|
||||
char materialname[64] DNA_DEPRECATED;
|
||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
||||
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||
char vgname[64];
|
||||
/** Custom index for passes. */
|
||||
int pass_index;
|
||||
|
@ -685,7 +685,7 @@ typedef struct HookGpencilModifierData {
|
|||
char layername[64];
|
||||
/** Material name. */
|
||||
char materialname[64] DNA_DEPRECATED;
|
||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
||||
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||
char vgname[64];
|
||||
/** Custom index for passes. */
|
||||
int pass_index;
|
||||
|
@ -694,7 +694,7 @@ typedef struct HookGpencilModifierData {
|
|||
char _pad[4];
|
||||
|
||||
int flag;
|
||||
/** Use enums from WarpGpencilModifier (exact same functionality). */
|
||||
/** #eHookGpencil_Falloff. */
|
||||
char falloff_type;
|
||||
char _pad1[3];
|
||||
/** Matrix making current transform unmodified. */
|
||||
|
@ -790,7 +790,7 @@ typedef struct OffsetGpencilModifierData {
|
|||
char layername[64];
|
||||
/** Material name. */
|
||||
char materialname[64] DNA_DEPRECATED;
|
||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
||||
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||
char vgname[64];
|
||||
/** Custom index for passes. */
|
||||
int pass_index;
|
||||
|
@ -832,7 +832,7 @@ typedef struct SmoothGpencilModifierData {
|
|||
char layername[64];
|
||||
/** Material name. */
|
||||
char materialname[64] DNA_DEPRECATED;
|
||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
||||
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||
char vgname[64];
|
||||
/** Custom index for passes. */
|
||||
int pass_index;
|
||||
|
@ -871,7 +871,7 @@ typedef struct ArmatureGpencilModifierData {
|
|||
struct Object *object;
|
||||
/** Stored input of previous modifier, for vertex-group blending. */
|
||||
float (*vert_coords_prev)[3];
|
||||
/** MAX_VGROUP_NAME. */
|
||||
/** #MAX_VGROUP_NAME. */
|
||||
char vgname[64];
|
||||
|
||||
} ArmatureGpencilModifierData;
|
||||
|
@ -919,7 +919,7 @@ typedef struct TintGpencilModifierData {
|
|||
char layername[64];
|
||||
/** Material name. */
|
||||
char materialname[64] DNA_DEPRECATED;
|
||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
||||
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||
char vgname[64];
|
||||
/** Custom index for passes. */
|
||||
int pass_index;
|
||||
|
@ -965,7 +965,7 @@ typedef struct TextureGpencilModifierData {
|
|||
char layername[64];
|
||||
/** Material name. */
|
||||
char materialname[64] DNA_DEPRECATED;
|
||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
||||
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||
char vgname[64];
|
||||
/** Custom index for passes. */
|
||||
int pass_index;
|
||||
|
@ -1010,13 +1010,13 @@ typedef enum eTextureGpencil_Mode {
|
|||
|
||||
typedef struct WeightProxGpencilModifierData {
|
||||
GpencilModifierData modifier;
|
||||
/** Target vertexgroup name, MAX_VGROUP_NAME. */
|
||||
/** Target vertex-group name, #MAX_VGROUP_NAME. */
|
||||
char target_vgname[64];
|
||||
/** Material for filtering. */
|
||||
struct Material *material;
|
||||
/** Layer name. */
|
||||
char layername[64];
|
||||
/** Optional vertexgroup filter name, MAX_VGROUP_NAME. */
|
||||
/** Optional vertex-group filter name, #MAX_VGROUP_NAME. */
|
||||
char vgname[64];
|
||||
/** Custom index for passes. */
|
||||
int pass_index;
|
||||
|
@ -1036,13 +1036,13 @@ typedef struct WeightProxGpencilModifierData {
|
|||
|
||||
typedef struct WeightAngleGpencilModifierData {
|
||||
GpencilModifierData modifier;
|
||||
/** Target vertexgroup name, MAX_VGROUP_NAME. */
|
||||
/** Target vertex-group name, #MAX_VGROUP_NAME. */
|
||||
char target_vgname[64];
|
||||
/** Material for filtering. */
|
||||
struct Material *material;
|
||||
/** Layer name. */
|
||||
char layername[64];
|
||||
/** Optional vertexgroup filter name, MAX_VGROUP_NAME. */
|
||||
/** Optional vertex-group filter name, #MAX_VGROUP_NAME. */
|
||||
char vgname[64];
|
||||
/** Custom index for passes. */
|
||||
int pass_index;
|
||||
|
@ -1209,7 +1209,7 @@ typedef struct LineartGpencilModifierData {
|
|||
char _pad2[6];
|
||||
|
||||
struct LineartCache *cache;
|
||||
/* Keep a pointer to the render buffer so we can call destroy from ModifierData. */
|
||||
/** Keep a pointer to the render buffer so we can call destroy from #ModifierData. */
|
||||
struct LineartData *la_data_ptr;
|
||||
|
||||
} LineartGpencilModifierData;
|
||||
|
@ -1224,7 +1224,7 @@ typedef struct ShrinkwrapGpencilModifierData {
|
|||
struct Material *material;
|
||||
/** Layer name. */
|
||||
char layername[64];
|
||||
/** Optional vertexgroup filter name, MAX_VGROUP_NAME. */
|
||||
/** Optional vertex-group filter name, #MAX_VGROUP_NAME. */
|
||||
char vgname[64];
|
||||
/** Custom index for passes. */
|
||||
int pass_index;
|
||||
|
@ -1274,7 +1274,7 @@ typedef struct EnvelopeGpencilModifierData {
|
|||
struct Material *material;
|
||||
/** Layer name. */
|
||||
char layername[64];
|
||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
||||
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||
char vgname[64];
|
||||
/** Custom index for passes. */
|
||||
int pass_index;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "COM_algorithm_smaa.hh"
|
||||
#include "COM_node_operation.hh"
|
||||
|
||||
#include "node_composite_util.hh"
|
||||
|
@ -18,9 +19,13 @@
|
|||
|
||||
namespace blender::nodes::node_composite_antialiasing_cc {
|
||||
|
||||
NODE_STORAGE_FUNCS(NodeAntiAliasingData)
|
||||
|
||||
static void cmp_node_antialiasing_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Color>(N_("Image")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
b.add_input<decl::Color>(N_("Image"))
|
||||
.default_value({1.0f, 1.0f, 1.0f, 1.0f})
|
||||
.compositor_domain_priority(0);
|
||||
b.add_output<decl::Color>(N_("Image"));
|
||||
}
|
||||
|
||||
|
@ -54,8 +59,33 @@ class AntiAliasingOperation : public NodeOperation {
|
|||
|
||||
void execute() override
|
||||
{
|
||||
get_input("Image").pass_through(get_result("Image"));
|
||||
context().set_info_message("Viewport compositor setup not fully supported");
|
||||
smaa(context(),
|
||||
get_input("Image"),
|
||||
get_result("Image"),
|
||||
get_threshold(),
|
||||
get_local_contrast_adaptation_factor(),
|
||||
get_corner_rounding());
|
||||
}
|
||||
|
||||
/* Blender encodes the threshold in the [0, 1] range, while the SMAA algorithm expects it in
|
||||
* the [0, 0.5] range. */
|
||||
float get_threshold()
|
||||
{
|
||||
return node_storage(bnode()).threshold / 2.0f;
|
||||
}
|
||||
|
||||
/* Blender encodes the local contrast adaptation factor in the [0, 1] range, while the SMAA
|
||||
* algorithm expects it in the [0, 10] range. */
|
||||
float get_local_contrast_adaptation_factor()
|
||||
{
|
||||
return node_storage(bnode()).threshold * 10.0f;
|
||||
}
|
||||
|
||||
/* Blender encodes the corner rounding factor in the float [0, 1] range, while the SMAA algorithm
|
||||
* expects it in the integer [0, 100] range. */
|
||||
int get_corner_rounding()
|
||||
{
|
||||
return int(node_storage(bnode()).corner_rounding * 100.0f);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -81,8 +111,6 @@ void register_node_type_cmp_antialiasing()
|
|||
node_type_storage(
|
||||
&ntype, "NodeAntiAliasingData", 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);
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ class BlurOperation : public NodeOperation {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!get_input("Size").is_single_value() && get_variable_size()) {
|
||||
if (use_variable_size()) {
|
||||
execute_variable_size();
|
||||
}
|
||||
else if (use_separable_filter()) {
|
||||
|
@ -261,6 +261,12 @@ class BlurOperation : public NodeOperation {
|
|||
}
|
||||
}
|
||||
|
||||
bool use_variable_size()
|
||||
{
|
||||
return get_variable_size() && !get_input("Size").is_single_value() &&
|
||||
node_storage(bnode()).filtertype != R_FILTER_FAST_GAUSS;
|
||||
}
|
||||
|
||||
float2 get_size_factor()
|
||||
{
|
||||
return float2(node_storage(bnode()).percentx, node_storage(bnode()).percenty) / 100.0f;
|
||||
|
|
|
@ -179,7 +179,7 @@ struct GrabState {
|
|||
static bool wm_software_cursor_needed(void)
|
||||
{
|
||||
if (UNLIKELY(g_software_cursor.enabled == -1)) {
|
||||
g_software_cursor.enabled = !GHOST_SupportsCursorWarp();
|
||||
g_software_cursor.enabled = !(WM_capabilities_flag() & WM_CAPABILITY_CURSOR_WARP);
|
||||
}
|
||||
return g_software_cursor.enabled;
|
||||
}
|
||||
|
|
|
@ -5165,7 +5165,8 @@ static void attach_ndof_data(wmEvent *event, const GHOST_TEventNDOFMotionData *g
|
|||
static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *event)
|
||||
{
|
||||
/* If GHOST doesn't support window positioning, don't use this feature at all. */
|
||||
const static int8_t supports_window_position = GHOST_SupportsWindowPosition();
|
||||
const static int8_t supports_window_position = (WM_capabilities_flag() &
|
||||
WM_CAPABILITY_WINDOW_POSITION) != 0;
|
||||
if (!supports_window_position) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -998,7 +998,11 @@ wmWindow *WM_window_open(bContext *C,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* ****************** Operators ****************** */
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Operators
|
||||
* \{ */
|
||||
|
||||
int wm_window_close_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
|
@ -1063,7 +1067,11 @@ int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/* ************ events *************** */
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Events
|
||||
* \{ */
|
||||
|
||||
void wm_cursor_position_from_ghost_client_coords(wmWindow *win, int *x, int *y)
|
||||
{
|
||||
|
@ -1827,14 +1835,14 @@ eWM_CapabilitiesFlag WM_capabilities_flag(void)
|
|||
return flag;
|
||||
}
|
||||
|
||||
flag = 0;
|
||||
if (GHOST_SupportsCursorWarp()) {
|
||||
const GHOST_TCapabilityFlag ghost_flag = GHOST_GetCapabilities();
|
||||
if (ghost_flag & GHOST_kCapabilityCursorWarp) {
|
||||
flag |= WM_CAPABILITY_CURSOR_WARP;
|
||||
}
|
||||
if (GHOST_SupportsWindowPosition()) {
|
||||
if (ghost_flag & GHOST_kCapabilityWindowPosition) {
|
||||
flag |= WM_CAPABILITY_WINDOW_POSITION;
|
||||
}
|
||||
if (GHOST_SupportsPrimaryClipboard()) {
|
||||
if (ghost_flag & GHOST_kCapabilityPrimaryClipboard) {
|
||||
flag |= WM_CAPABILITY_PRIMARY_CLIPBOARD;
|
||||
}
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ dict_custom = {
|
|||
"dialogs",
|
||||
"digitizers",
|
||||
"dihedral",
|
||||
"directionality",
|
||||
"discoverability",
|
||||
"discretization",
|
||||
"discretized",
|
||||
|
@ -144,6 +145,7 @@ dict_custom = {
|
|||
"interdependencies",
|
||||
"interferences",
|
||||
"interocular",
|
||||
"interpolator",
|
||||
"invariant",
|
||||
"invariants",
|
||||
"invisibilities",
|
||||
|
@ -157,6 +159,8 @@ dict_custom = {
|
|||
"linearizing",
|
||||
"linkable",
|
||||
"lockless",
|
||||
"looper",
|
||||
"loopers",
|
||||
"losslessly",
|
||||
"luminances",
|
||||
"mappable",
|
||||
|
@ -174,6 +178,8 @@ dict_custom = {
|
|||
"occludee",
|
||||
"occluder",
|
||||
"occluders",
|
||||
"octant",
|
||||
"octants",
|
||||
"optionals",
|
||||
"orthogonalize",
|
||||
"orthogonally",
|
||||
|
@ -186,6 +192,7 @@ dict_custom = {
|
|||
"parallelize",
|
||||
"parallelizing",
|
||||
"parameterization",
|
||||
"parameterless",
|
||||
"parametrization",
|
||||
"parentless",
|
||||
"passepartout",
|
||||
|
@ -247,6 +254,8 @@ dict_custom = {
|
|||
"redistributions",
|
||||
"registerable",
|
||||
"reimplement",
|
||||
"reimplemented",
|
||||
"reimplementing",
|
||||
"remappable",
|
||||
"remapper",
|
||||
"remappings",
|
||||
|
@ -258,9 +267,14 @@ dict_custom = {
|
|||
"reparameterization",
|
||||
"reparametization",
|
||||
"representable",
|
||||
"reprojected",
|
||||
"reprojecting",
|
||||
"reprojection",
|
||||
"reprojections",
|
||||
"repurpose",
|
||||
"respecialized",
|
||||
"resynced",
|
||||
"resyncing",
|
||||
"retiming",
|
||||
"reusability",
|
||||
"saveable",
|
||||
|
@ -325,6 +339,7 @@ dict_custom = {
|
|||
"undistored",
|
||||
"undistorted",
|
||||
"undistorting",
|
||||
"unduplicated",
|
||||
"uneditable",
|
||||
"unflagged",
|
||||
"unflip",
|
||||
|
@ -368,6 +383,7 @@ dict_custom = {
|
|||
"unpoision",
|
||||
"unproject",
|
||||
"unquantifiable",
|
||||
"unreferenced",
|
||||
"unregister",
|
||||
"unregistering",
|
||||
"unregisters",
|
||||
|
@ -429,6 +445,7 @@ dict_custom = {
|
|||
"addon",
|
||||
"addons",
|
||||
"autocomplete",
|
||||
"codegen",
|
||||
"colospace",
|
||||
"datablock",
|
||||
"datablocks",
|
||||
|
@ -451,6 +468,7 @@ dict_custom = {
|
|||
"config", # configuration.
|
||||
"coord",
|
||||
"coords",
|
||||
"ctrl", # control (modifier key).
|
||||
"iter", # iteration.
|
||||
"multi",
|
||||
"numpad", # numeric-pad.
|
||||
|
|
Loading…
Reference in New Issue