WIP: Brush assets project #106303

Draft
Julian Eisel wants to merge 351 commits from brush-assets-project into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
29 changed files with 451 additions and 177 deletions
Showing only changes of commit 74fcbf4523 - Show all commits

View File

@ -259,6 +259,28 @@ else()
set(WITH_UNITY_BUILD OFF)
endif()
if(COMMAND target_precompile_headers)
# Disabling is needed for `./tools/utils_maintenance/code_clean.py` to function.
option(WITH_COMPILER_PRECOMPILED_HEADERS "\
Use pre-compiled headers to speed up compilation."
ON
)
mark_as_advanced(WITH_COMPILER_PRECOMPILED_HEADERS)
if(WITH_CLANG_TIDY AND CMAKE_COMPILER_IS_GNUCC)
if(WITH_COMPILER_PRECOMPILED_HEADERS)
message(STATUS
"Clang-Tidy and GCC precompiled headers are incompatible, disabling precompiled headers"
)
set(WITH_COMPILER_PRECOMPILED_HEADERS OFF)
endif()
endif()
if(NOT WITH_COMPILER_PRECOMPILED_HEADERS)
set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON)
endif()
endif()
option(WITH_IK_ITASC "\
Enable ITASC IK solver (only disable for development & for incompatible C++ compilers)"
ON
@ -759,8 +781,10 @@ if(WIN32)
option(WITH_TBB_MALLOC_PROXY "Enable the TBB malloc replacement" ON)
endif()
option(WITH_EXPERIMENTAL_FEATURES "Enable experimental features" ON)
# This should be turned off when Blender enter beta/rc/release
if("${BLENDER_VERSION_CYCLE}" STREQUAL "alpha")
if("${BLENDER_VERSION_CYCLE}" STREQUAL "alpha" AND WITH_EXPERIMENTAL_FEATURES)
set(WITH_EXPERIMENTAL_FEATURES ON)
else()
set(WITH_EXPERIMENTAL_FEATURES OFF)

View File

@ -25,7 +25,12 @@ if EXIST %PYTHON% (
)
if NOT EXIST %PYTHON% (
echo Warning: Python not found, there is likely an issue with the library folder
REM Only emit this warning when the library folder exists but the
REM python folder does not. As we don't want to concern people that
REM run make update for the first time.
if EXIST %BLENDER_DIR%\..\lib\win64_vc15 (
echo Warning: Python not found, there is likely an issue with the library folder
)
set PYTHON=""
)

View File

@ -135,6 +135,12 @@ static int gwl_registry_handler_interface_slot_max();
static int gwl_registry_handler_interface_slot_from_string(const char *interface);
static const GWL_RegistryHandler *gwl_registry_handler_from_interface_slot(int interface_slot);
static bool xkb_compose_state_feed_and_get_utf8(
xkb_compose_state *compose_state,
xkb_state *state,
const xkb_keycode_t key,
char r_utf8_buf[sizeof(GHOST_TEventKeyData::utf8_buf)]);
#ifdef USE_EVENT_BACKGROUND_THREAD
static void gwl_display_event_thread_destroy(GWL_Display *display);
@ -1103,6 +1109,37 @@ static void gwl_seat_key_layout_active_state_update_mask(GWL_Seat *seat)
}
}
/** Callback that runs from GHOST's timer. */
static void gwl_seat_key_repeat_timer_fn(GHOST_ITimerTask *task, uint64_t time_ms)
{
GWL_KeyRepeatPlayload *payload = static_cast<GWL_KeyRepeatPlayload *>(task->getUserData());
GWL_Seat *seat = payload->seat;
wl_surface *wl_surface_focus = seat->keyboard.wl.surface_window;
if (UNLIKELY(wl_surface_focus == nullptr)) {
return;
}
GHOST_IWindow *win = ghost_wl_surface_user_data(wl_surface_focus);
GHOST_SystemWayland *system = seat->system;
const uint64_t event_ms = payload->time_ms_init + time_ms;
/* Calculate this value every time in case modifier keys are pressed. */
char utf8_buf[sizeof(GHOST_TEventKeyData::utf8_buf)] = {'\0'};
if (seat->xkb.compose_state &&
xkb_compose_state_feed_and_get_utf8(
seat->xkb.compose_state, seat->xkb.state, payload->key_code, utf8_buf))
{
/* `utf8_buf` has been filled by a compose action. */
}
else {
xkb_state_key_get_utf8(seat->xkb.state, payload->key_code, utf8_buf, sizeof(utf8_buf));
}
system->pushEvent_maybe_pending(new GHOST_EventKey(
event_ms, GHOST_kEventKeyDown, win, payload->key_data.gkey, true, utf8_buf));
}
/**
* \note Caller must lock `timer_mutex`.
*/
@ -2761,13 +2798,11 @@ static void keyboard_depressed_state_key_event(GWL_Seat *seat,
}
static void keyboard_depressed_state_push_events_from_change(
GWL_Seat *seat, const GWL_KeyboardDepressedState &key_depressed_prev)
GWL_Seat *seat,
GHOST_IWindow *win,
const uint64_t event_ms,
const GWL_KeyboardDepressedState &key_depressed_prev)
{
GHOST_IWindow *win = ghost_wl_surface_user_data(seat->keyboard.wl.surface_window);
const GHOST_SystemWayland *system = seat->system;
/* Caller has no time-stamp, set from system. */
const uint64_t event_ms = system->getMilliSeconds();
/* Separate key up and down into separate passes so key down events always come after key up.
* Do this so users of GHOST can use the last pressed or released modifier to check
* if the modifier is held instead of counting modifiers pressed as is done here,
@ -4718,6 +4753,8 @@ static void keyboard_handle_enter(void *data,
CLOG_INFO(LOG, 2, "enter");
GWL_Seat *seat = static_cast<GWL_Seat *>(data);
GHOST_IWindow *win = ghost_wl_surface_user_data(wl_surface);
seat->keyboard.serial = serial;
seat->keyboard.wl.surface_window = wl_surface;
@ -4729,6 +4766,12 @@ static void keyboard_handle_enter(void *data,
GWL_KeyboardDepressedState key_depressed_prev = seat->key_depressed;
keyboard_depressed_state_reset(seat);
/* Keep track of the last held repeating key, start the repeat timer if one exists. */
struct {
uint32_t key = std::numeric_limits<uint32_t>::max();
xkb_keysym_t sym = 0;
} repeat;
uint32_t *key;
WL_ARRAY_FOR_EACH (key, keys) {
const xkb_keycode_t key_code = *key + EVDEV_OFFSET;
@ -4738,9 +4781,41 @@ static void keyboard_handle_enter(void *data,
if (gkey != GHOST_kKeyUnknown) {
keyboard_depressed_state_key_event(seat, gkey, GHOST_kEventKeyDown);
}
if (xkb_keymap_key_repeats(xkb_state_get_keymap(seat->xkb.state), key_code)) {
repeat.key = *key;
repeat.sym = sym;
}
}
keyboard_depressed_state_push_events_from_change(seat, key_depressed_prev);
/* Caller has no time-stamp, set from system. */
const uint64_t event_ms = seat->system->getMilliSeconds();
keyboard_depressed_state_push_events_from_change(seat, win, event_ms, key_depressed_prev);
if ((repeat.key != std::numeric_limits<uint32_t>::max()) && (seat->key_repeat.rate > 0)) {
/* Since the key has been held, immediately send a press event.
* This also ensures the key will be registered as pressed, see #117896. */
#ifdef USE_EVENT_BACKGROUND_THREAD
std::lock_guard lock_timer_guard{*seat->system->timer_mutex};
#endif
/* Should have been cleared on leave, set here just in case. */
if (UNLIKELY(seat->key_repeat.timer)) {
keyboard_handle_key_repeat_cancel(seat);
}
const xkb_keycode_t key_code = repeat.key + EVDEV_OFFSET;
const GHOST_TKey gkey = xkb_map_gkey_or_scan_code(repeat.sym, repeat.key);
GWL_KeyRepeatPlayload *key_repeat_payload = new GWL_KeyRepeatPlayload();
key_repeat_payload->seat = seat;
key_repeat_payload->key_code = key_code;
key_repeat_payload->key_data.gkey = gkey;
gwl_seat_key_repeat_timer_add(seat, gwl_seat_key_repeat_timer_fn, key_repeat_payload, false);
/* Ensure there is a press event on enter so this is known to be held before any mouse
* button events which may use a key-binding that depends on this key being held. */
gwl_seat_key_repeat_timer_fn(seat->key_repeat.timer, 0);
}
}
/**
@ -5031,33 +5106,7 @@ static void keyboard_handle_key(void *data,
}
if (key_repeat_payload) {
auto key_repeat_fn = [](GHOST_ITimerTask *task, uint64_t time_ms) {
GWL_KeyRepeatPlayload *payload = static_cast<GWL_KeyRepeatPlayload *>(task->getUserData());
GWL_Seat *seat = payload->seat;
if (wl_surface *wl_surface_focus = seat->keyboard.wl.surface_window) {
GHOST_IWindow *win = ghost_wl_surface_user_data(wl_surface_focus);
GHOST_SystemWayland *system = seat->system;
const uint64_t event_ms = payload->time_ms_init + time_ms;
/* Calculate this value every time in case modifier keys are pressed. */
char utf8_buf[sizeof(GHOST_TEventKeyData::utf8_buf)] = {'\0'};
if (seat->xkb.compose_state &&
xkb_compose_state_feed_and_get_utf8(
seat->xkb.compose_state, seat->xkb.state, payload->key_code, utf8_buf))
{
/* `utf8_buf` has been filled by a compose action. */
}
else {
xkb_state_key_get_utf8(seat->xkb.state, payload->key_code, utf8_buf, sizeof(utf8_buf));
}
system->pushEvent_maybe_pending(new GHOST_EventKey(
event_ms, GHOST_kEventKeyDown, win, payload->key_data.gkey, true, utf8_buf));
}
};
gwl_seat_key_repeat_timer_add(seat, key_repeat_fn, key_repeat_payload, true);
gwl_seat_key_repeat_timer_add(seat, gwl_seat_key_repeat_timer_fn, key_repeat_payload, true);
}
}

View File

@ -106,7 +106,7 @@ class PHYSICS_PT_add(PhysicButtonsPanel, Panel):
)
# cache-type can be 'PSYS' 'HAIR' 'FLUID' etc.
# cache-type can be 'PSYS' 'HAIR' etc. ('FLUID' uses its own cache)
def point_cache_ui(self, cache, enabled, cachetype):
layout = self.layout
@ -130,12 +130,8 @@ def point_cache_ui(self, cache, enabled, cachetype):
col.operator("ptcache.add", icon='ADD', text="")
col.operator("ptcache.remove", icon='REMOVE', text="")
if cachetype in {'PSYS', 'HAIR', 'FLUID'}:
if cachetype in {'PSYS', 'HAIR'}:
col = layout.column()
if cachetype == 'FLUID':
col.prop(cache, "use_library_path", text="Use Library Path")
col.prop(cache, "use_external")
if cache.use_external:
@ -149,14 +145,14 @@ def point_cache_ui(self, cache, enabled, cachetype):
col.alignment = 'RIGHT'
col.label(text=cache_info)
else:
if cachetype in {'FLUID', 'DYNAMIC_PAINT'}:
if cachetype == 'DYNAMIC_PAINT':
if not is_saved:
col = layout.column(align=True)
col.alignment = 'RIGHT'
col.label(text="Cache is disabled until the file is saved")
layout.enabled = False
if not cache.use_external or cachetype == 'FLUID':
if not cache.use_external:
col = layout.column(align=True)
if cachetype not in {'PSYS', 'DYNAMIC_PAINT'}:
@ -164,18 +160,18 @@ def point_cache_ui(self, cache, enabled, cachetype):
col.prop(cache, "frame_start", text="Simulation Start")
col.prop(cache, "frame_end")
if cachetype not in {'FLUID', 'CLOTH', 'DYNAMIC_PAINT', 'RIGID_BODY'}:
if cachetype not in {'CLOTH', 'DYNAMIC_PAINT', 'RIGID_BODY'}:
col.prop(cache, "frame_step")
cache_info = cache.info
if cachetype != 'FLUID' and cache_info: # avoid empty space.
if cache_info: # avoid empty space.
col = layout.column(align=True)
col.alignment = 'RIGHT'
col.label(text=cache_info)
can_bake = True
if cachetype not in {'FLUID', 'DYNAMIC_PAINT', 'RIGID_BODY'}:
if cachetype not in {'DYNAMIC_PAINT', 'RIGID_BODY'}:
if not is_saved:
col = layout.column(align=True)
col.alignment = 'RIGHT'

View File

@ -1598,7 +1598,7 @@ class USERPREF_UL_asset_libraries(UIList):
class USERPREF_UL_extension_repos(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
repo = item
icon = 'WORLD' if repo.use_remote_path else 'DISK_DRIVE'
icon = 'NETWORK_DRIVE' if repo.use_remote_path else 'DISK_DRIVE'
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(repo, "name", text="", icon=icon, emboss=False)
elif self.layout_type == 'GRID':
@ -1615,6 +1615,24 @@ class USERPREF_UL_extension_repos(UIList):
layout.prop(repo, "enabled", text="", emboss=False, icon='CHECKBOX_HLT' if repo.enabled else 'CHECKBOX_DEHLT')
def filter_items(self, _context, data, propname):
# Repositories has no index, converting to a list.
items = list(getattr(data, propname))
flags = [self.bitflag_filter_item] * len(items)
indices = [None] * len(items)
for index, orig_index in enumerate(sorted(
range(len(items)),
key=lambda i: (
items[i].use_remote_path is False,
items[i].name.lower(),
)
)):
indices[orig_index] = index
return flags, indices
# -----------------------------------------------------------------------------
# Save/Load Panels

View File

@ -7,14 +7,6 @@ if(WITH_LEGACY_OPENGL)
endif()
if(WITH_CLANG_TIDY AND NOT MSVC)
if(NOT CMAKE_C_COMPILER_ID MATCHES "Clang")
message(WARNING "Currently Clang-Tidy might fail with GCC toolchain, switch to Clang toolchain if that happens")
if(COMMAND target_precompile_headers)
message(STATUS "Clang-Tidy and GCC precompiled headers are incompatible, disabling precompiled headers")
set(CMAKE_DISABLE_PRECOMPILE_HEADERS ON)
endif()
endif()
find_package(ClangTidy REQUIRED)
set(CMAKE_C_CLANG_TIDY
${CLANG_TIDY_EXECUTABLE};--extra-arg=-Wno-error=unknown-warning-option)

View File

@ -9,7 +9,9 @@
#pragma once
#include "BLI_compiler_attrs.h"
#include "BLI_string_ref.hh"
#include "BLI_sys_types.h"
#include "BLI_vector.hh"
/* Name of sub-directory inside #BLENDER_DATAFILES that contains font files. */
#define BLF_DATAFILES_FONTS_DIR "fonts"
@ -254,6 +256,10 @@ void BLF_rotation(int fontid, float angle);
void BLF_clipping(int fontid, int xmin, int ymin, int xmax, int ymax);
void BLF_wordwrap(int fontid, int wrap_width);
blender::Vector<blender::StringRef> BLF_string_wrap(int fontid,
blender::StringRef str,
const int max_pixel_width);
#if BLF_BLUR_ENABLE
void BLF_blur(int fontid, int size);
#endif

View File

@ -935,6 +935,17 @@ void BLF_draw_buffer(int fontid, const char *str, const size_t str_len)
BLF_draw_buffer_ex(fontid, str, str_len, nullptr);
}
blender::Vector<blender::StringRef> BLF_string_wrap(int fontid,
blender::StringRef str,
const int max_pixel_width)
{
FontBLF *font = blf_get(fontid);
if (!font) {
return {};
}
return blf_font_string_wrap(font, str, max_pixel_width);
}
char *BLF_display_name_from_file(const char *filepath)
{
/* While listing font directories this function can be called simultaneously from a greater

View File

@ -37,6 +37,7 @@
#include "BLI_string_cursor_utf8.h"
#include "BLI_string_utf8.h"
#include "BLI_threads.h"
#include "BLI_vector.hh"
#include "BLF_api.hh"
@ -1085,6 +1086,7 @@ void blf_str_offset_to_glyph_bounds(FontBLF *font,
static void blf_font_wrap_apply(FontBLF *font,
const char *str,
const size_t str_len,
const int max_pixel_width,
ResultBLF *r_info,
void (*callback)(FontBLF *font,
GlyphCacheBLF *gc,
@ -1109,7 +1111,7 @@ static void blf_font_wrap_apply(FontBLF *font,
struct WordWrapVars {
ft_pix wrap_width;
size_t start, last[2];
} wrap = {font->wrap_width != -1 ? ft_pix_from_int(font->wrap_width) : INT_MAX, 0, {0, 0}};
} wrap = {max_pixel_width != -1 ? ft_pix_from_int(max_pixel_width) : INT_MAX, 0, {0, 0}};
// printf("%s wrapping (%d, %d) `%s`:\n", __func__, str_len, strlen(str), str);
while ((i < str_len) && str[i]) {
@ -1198,7 +1200,8 @@ static void blf_font_draw__wrap_cb(FontBLF *font,
}
void blf_font_draw__wrap(FontBLF *font, const char *str, const size_t str_len, ResultBLF *r_info)
{
blf_font_wrap_apply(font, str, str_len, r_info, blf_font_draw__wrap_cb, nullptr);
blf_font_wrap_apply(
font, str, str_len, font->wrap_width, r_info, blf_font_draw__wrap_cb, nullptr);
}
/** Utility for #blf_font_boundbox__wrap. */
@ -1223,7 +1226,8 @@ void blf_font_boundbox__wrap(
box->ymin = 32000;
box->ymax = -32000;
blf_font_wrap_apply(font, str, str_len, r_info, blf_font_boundbox_wrap_cb, box);
blf_font_wrap_apply(
font, str, str_len, font->wrap_width, r_info, blf_font_boundbox_wrap_cb, box);
}
/** Utility for #blf_font_draw_buffer__wrap. */
@ -1241,7 +1245,37 @@ void blf_font_draw_buffer__wrap(FontBLF *font,
const size_t str_len,
ResultBLF *r_info)
{
blf_font_wrap_apply(font, str, str_len, r_info, blf_font_draw_buffer__wrap_cb, nullptr);
blf_font_wrap_apply(
font, str, str_len, font->wrap_width, r_info, blf_font_draw_buffer__wrap_cb, nullptr);
}
/** Wrap a blender::StringRef. */
static void blf_font_string_wrap_cb(FontBLF * /*font*/,
GlyphCacheBLF * /*gc*/,
const char *str,
const size_t str_len,
ft_pix /*pen_y*/,
void *str_list_ptr)
{
blender::Vector<blender::StringRef> *list = static_cast<blender::Vector<blender::StringRef> *>(
str_list_ptr);
blender::StringRef line(str, str + str_len);
list->append(line);
}
blender::Vector<blender::StringRef> blf_font_string_wrap(FontBLF *font,
blender::StringRef str,
int max_pixel_width)
{
blender::Vector<blender::StringRef> list;
blf_font_wrap_apply(font,
str.data(),
size_t(str.size()),
max_pixel_width,
nullptr,
blf_font_string_wrap_cb,
&list);
return list;
}
/** \} */

View File

@ -8,6 +8,9 @@
#pragma once
#include "BLI_string_ref.hh"
#include "BLI_vector.hh"
struct FontBLF;
struct GlyphBLF;
struct GlyphCacheBLF;
@ -96,6 +99,10 @@ void blf_font_draw__wrap(struct FontBLF *font,
size_t str_len,
struct ResultBLF *r_info);
blender::Vector<blender::StringRef> blf_font_string_wrap(FontBLF *font,
blender::StringRef str,
int max_pixel_width);
/**
* Use fixed column width, but an utf8 character may occupy multiple columns.
*/

View File

@ -110,6 +110,7 @@ enum eCbEvent {
BKE_CB_EVT_EXTENSION_REPOS_UPDATE_POST,
BKE_CB_EVT_EXTENSION_REPOS_SYNC,
BKE_CB_EVT_EXTENSION_REPOS_UPGRADE,
BKE_CB_EVT_EXTENSION_DROP_URL,
BKE_CB_EVT_TOT,
};

View File

@ -85,6 +85,8 @@ bUserExtensionRepo *BKE_preferences_extension_repo_add(UserDef *userdef,
const char *module,
const char *custom_dirpath);
void BKE_preferences_extension_repo_remove(UserDef *userdef, bUserExtensionRepo *repo);
bUserExtensionRepo *BKE_preferences_extension_repo_add_default(UserDef *userdef);
bUserExtensionRepo *BKE_preferences_extension_repo_add_default_user(UserDef *userdef);
void BKE_preferences_extension_repo_name_set(UserDef *userdef,
bUserExtensionRepo *repo,

View File

@ -1417,6 +1417,9 @@ UserDef *BKE_blendfile_userdef_from_defaults()
BKE_preferences_asset_library_default_add(userdef);
BKE_preferences_extension_repo_add_default(userdef);
BKE_preferences_extension_repo_add_default_user(userdef);
return userdef;
}

View File

@ -538,7 +538,7 @@ void layer_adjustments_to_modifiers(Main &bmain,
STRNCPY(tmd->influence.layer_name, gpl->info);
char modifier_name[64];
BLI_snprintf(modifier_name, 64, "Tint %s", gpl->info);
SNPRINTF(modifier_name, "Tint %s", gpl->info);
STRNCPY(md->name, modifier_name);
BKE_modifier_unique_name(&dst_object.modifiers, md);
@ -558,7 +558,7 @@ void layer_adjustments_to_modifiers(Main &bmain,
auto *md = reinterpret_cast<NodesModifierData *>(BKE_modifier_new(eModifierType_Nodes));
char modifier_name[64];
BLI_snprintf(modifier_name, 64, "Thickness %s", gpl->info);
SNPRINTF(modifier_name, "Thickness %s", gpl->info);
STRNCPY(md->modifier.name, modifier_name);
BKE_modifier_unique_name(&dst_object.modifiers, &md->modifier);
md->node_group = offset_radius_node_tree;

View File

@ -193,6 +193,22 @@ void BKE_preferences_extension_repo_remove(UserDef *userdef, bUserExtensionRepo
BLI_freelinkN(&userdef->extension_repos, repo);
}
bUserExtensionRepo *BKE_preferences_extension_repo_add_default(UserDef *userdef)
{
bUserExtensionRepo *repo = BKE_preferences_extension_repo_add(
userdef, "Blender Official", "blender_official", "");
STRNCPY(repo->remote_path, "https://extensions.blender.org");
repo->flag |= USER_EXTENSION_REPO_FLAG_USE_REMOTE_PATH;
return repo;
}
bUserExtensionRepo *BKE_preferences_extension_repo_add_default_user(UserDef *userdef)
{
bUserExtensionRepo *repo = BKE_preferences_extension_repo_add(
userdef, "User Default", "user_default", "");
return repo;
}
void BKE_preferences_extension_repo_name_set(UserDef *userdef,
bUserExtensionRepo *repo,
const char *name)

View File

@ -133,3 +133,7 @@ if(WITH_GTESTS)
)
blender_add_test_suite_lib(blenloader "${TEST_SRC}" "${INC}" "${INC_SYS}" "${TEST_LIB}")
endif()
if(WITH_EXPERIMENTAL_FEATURES)
add_definitions(-DWITH_EXPERIMENTAL_FEATURES)
endif()

View File

@ -923,6 +923,13 @@ void blo_do_versions_userdef(UserDef *userdef)
}
}
if (!USER_VERSION_ATLEAST(402, 6)) {
if (BLI_listbase_is_empty(&userdef->extension_repos)) {
BKE_preferences_extension_repo_add_default(userdef);
BKE_preferences_extension_repo_add_default_user(userdef);
}
}
{
BKE_preferences_asset_shelf_settings_ensure_catalog_path_enabled(
userdef, "VIEW3D_AST_brush_sculpt", "Brushes/Mesh/Sculpt/Cloth");
@ -955,10 +962,11 @@ void BLO_sanitize_experimental_features_userpref_blend(UserDef *userdef)
*
* At that time master already has its version bumped so its user preferences
* are not touched by these settings. */
#ifdef WITH_EXPERIMENTAL_FEATURES
if (BKE_blender_version_is_alpha()) {
return;
}
#endif
MEMSET_STRUCT_AFTER(&userdef->experimental, 0, SANITIZE_AFTER_HERE);
}

View File

@ -81,59 +81,29 @@ void GaussianBlurBaseOperation::update_memory_buffer_partial(MemoryBuffer *outpu
const rcti &area,
Span<MemoryBuffer *> inputs)
{
const int2 unit_offset = dimension_ == eDimension::X ? int2(1, 0) : int2(0, 1);
MemoryBuffer *input = inputs[IMAGE_INPUT_INDEX];
const rcti &input_rect = input->get_rect();
BuffersIterator<float> it = output->iterate_with({input}, area);
int min_input_coord = -1;
int max_input_coord = -1;
int elem_stride = -1;
std::function<int()> get_current_coord;
switch (dimension_) {
case eDimension::X:
min_input_coord = input_rect.xmin;
max_input_coord = input_rect.xmax;
elem_stride = input->elem_stride;
get_current_coord = [&] { return it.x; };
break;
case eDimension::Y:
min_input_coord = input_rect.ymin;
max_input_coord = input_rect.ymax;
elem_stride = input->row_stride;
get_current_coord = [&] { return it.y; };
break;
}
for (; !it.is_end(); ++it) {
const int coord = get_current_coord();
const int coord_min = max_ii(coord - filtersize_, min_input_coord);
const int coord_max = min_ii(coord + filtersize_ + 1, max_input_coord);
float ATTR_ALIGN(16) color_accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
float multiplier_accum = 0.0f;
const int step = QualityStepHelper::get_step();
const float *in = it.in(0) + (intptr_t(coord_min) - coord) * elem_stride;
const int in_stride = elem_stride * step;
int gauss_idx = (coord_min - coord) + filtersize_;
const int gauss_end = gauss_idx + (coord_max - coord_min);
for (BuffersIterator<float> it = output->iterate_with({input}, area); !it.is_end(); ++it) {
alignas(16) float4 accumulated_color = float4(0.0f);
#if BLI_HAVE_SSE2
__m128 accum_r = _mm_load_ps(color_accum);
for (; gauss_idx < gauss_end; in += in_stride, gauss_idx += step) {
__m128 reg_a = _mm_load_ps(in);
reg_a = _mm_mul_ps(reg_a, gausstab_sse_[gauss_idx]);
accum_r = _mm_add_ps(accum_r, reg_a);
multiplier_accum += gausstab_[gauss_idx];
__m128 accumulated_color_sse = _mm_setzero_ps();
for (int i = -filtersize_; i <= filtersize_; i++) {
const int2 offset = unit_offset * i;
__m128 weight = gausstab_sse_[i + filtersize_];
__m128 color = _mm_load_ps(input->get_elem_clamped(it.x + offset.x, it.y + offset.y));
__m128 weighted_color = _mm_mul_ps(color, weight);
accumulated_color_sse = _mm_add_ps(accumulated_color_sse, weighted_color);
}
_mm_store_ps(color_accum, accum_r);
_mm_store_ps(accumulated_color, accumulated_color_sse);
#else
for (; gauss_idx < gauss_end; in += in_stride, gauss_idx += step) {
const float multiplier = gausstab_[gauss_idx];
madd_v4_v4fl(color_accum, in, multiplier);
multiplier_accum += multiplier;
for (int i = -filtersize_; i <= filtersize_; i++) {
const int2 offset = unit_offset * i;
const float weight = gausstab_[i + filtersize_];
const float4 color = input->get_elem_clamped(it.x + offset.x, it.y + offset.y);
accumulated_color += color * weight;
}
#endif
mul_v4_v4fl(it.out, color_accum, 1.0f / multiplier_accum);
copy_v4_v4(it.out, accumulated_color);
}
}

View File

@ -32,16 +32,19 @@ void HueSaturationValueCorrectOperation::execute_pixel_sampled(float output[4],
input_program_->read_sampled(hsv, x, y, sampler);
/* We parametrize the curve using the hue value. */
const float parameter = hsv[0];
/* adjust hue, scaling returned default 0.5 up to 1 */
f = BKE_curvemapping_evaluateF(curve_mapping_, 0, hsv[0]);
f = BKE_curvemapping_evaluateF(curve_mapping_, 0, parameter);
hsv[0] += f - 0.5f;
/* adjust saturation, scaling returned default 0.5 up to 1 */
f = BKE_curvemapping_evaluateF(curve_mapping_, 1, hsv[0]);
f = BKE_curvemapping_evaluateF(curve_mapping_, 1, parameter);
hsv[1] *= (f * 2.0f);
/* adjust value, scaling returned default 0.5 up to 1 */
f = BKE_curvemapping_evaluateF(curve_mapping_, 2, hsv[0]);
f = BKE_curvemapping_evaluateF(curve_mapping_, 2, parameter);
hsv[2] *= (f * 2.0f);
hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */
@ -67,16 +70,19 @@ void HueSaturationValueCorrectOperation::update_memory_buffer_partial(MemoryBuff
for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
copy_v4_v4(hsv, it.in(0));
/* We parametrize the curve using the hue value. */
const float parameter = hsv[0];
/* Adjust hue, scaling returned default 0.5 up to 1. */
float f = BKE_curvemapping_evaluateF(curve_mapping_, 0, hsv[0]);
float f = BKE_curvemapping_evaluateF(curve_mapping_, 0, parameter);
hsv[0] += f - 0.5f;
/* Adjust saturation, scaling returned default 0.5 up to 1. */
f = BKE_curvemapping_evaluateF(curve_mapping_, 1, hsv[0]);
f = BKE_curvemapping_evaluateF(curve_mapping_, 1, parameter);
hsv[1] *= (f * 2.0f);
/* Adjust value, scaling returned default 0.5 up to 1. */
f = BKE_curvemapping_evaluateF(curve_mapping_, 2, hsv[0]);
f = BKE_curvemapping_evaluateF(curve_mapping_, 2, parameter);
hsv[2] *= (f * 2.0f);
hsv[0] = hsv[0] - floorf(hsv[0]); /* Mod 1.0. */

View File

@ -4,25 +4,10 @@
#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
/* Curve maps are stored in sampler objects that are evaluated in the [0, 1] range, so normalize
* parameters accordingly. */
#define NORMALIZE_PARAMETER(parameter, minimum, range) ((parameter - minimum) * range)
/* Curve maps are stored in texture samplers, so ensure that the parameters evaluate the sampler at
* the center of the pixels, because samplers are evaluated using linear interpolation. Given the
* parameter in the [0, 1] range. */
float compute_curve_map_coordinates(float parameter)
{
/* Curve maps have a fixed width of 257. We offset by the equivalent of half a pixel and scale
* down such that the normalized parameter 1.0 corresponds to the center of the last pixel. */
const float sampler_resolution = 257.0;
float sampler_offset = 0.5 / sampler_resolution;
float sampler_scale = 1.0 - (1.0 / sampler_resolution);
return parameter * sampler_scale + sampler_offset;
}
/* Same as compute_curve_map_coordinates but vectorized. */
vec2 compute_curve_map_coordinates(vec2 parameters)
vec3 compute_curve_map_coordinates(vec3 parameters)
{
const float sampler_resolution = 257.0;
float sampler_offset = 0.5 / sampler_resolution;
@ -41,21 +26,18 @@ void node_composite_hue_correct(float factor,
vec4 hsv;
rgb_to_hsv(color, hsv);
/* First, adjust the hue channel on its own, since corrections in the saturation and value
* channels depends on the new value of the hue, not its original value. A curve map value of 0.5
* means no change in hue, so adjust the value to get an identity at 0.5. Since the identity of
* addition is 0, we subtract 0.5 (0.5 - 0.5 = 0). */
const float hue_parameter = NORMALIZE_PARAMETER(hsv.x, minimums.x, range_dividers.x);
float hue_coordinates = compute_curve_map_coordinates(hue_parameter);
hsv.x += texture(curve_map, vec2(hue_coordinates, layer)).x - 0.5;
/* Second, adjust the saturation and value based on the new value of the hue. A curve map value
* of 0.5 means no change in hue, so adjust the value to get an identity at 0.5. Since the
* identity of duplication is 1, we multiply by 2 (0.5 * 2 = 1). */
vec2 parameters = NORMALIZE_PARAMETER(hsv.x, minimums.yz, range_dividers.yz);
vec2 coordinates = compute_curve_map_coordinates(parameters);
hsv.y *= texture(curve_map, vec2(coordinates.x, layer)).y * 2.0;
hsv.z *= texture(curve_map, vec2(coordinates.y, layer)).z * 2.0;
/* First, normalize the hue value into the [0, 1] range for each of the curve maps and compute
* the proper sampler coordinates for interpolation, then adjust each of the Hue, Saturation, and
* Values accordingly to the following rules. A curve map value of 0.5 means no change in hue, so
* adjust the value to get an identity at 0.5. Since the identity of addition is 0, we subtract
* 0.5 (0.5 - 0.5 = 0). A curve map value of 0.5 means no change in saturation or value, so
* adjust the value to get an identity at 0.5. Since the identity of multiplication is 1, we
* multiply by 2 (0.5 * 2 = 1). */
vec3 parameters = (hsv.xxx - minimums) * range_dividers;
vec3 coordinates = compute_curve_map_coordinates(parameters);
hsv.x += texture(curve_map, vec2(coordinates.x, layer)).x - 0.5;
hsv.y *= texture(curve_map, vec2(coordinates.y, layer)).y * 2.0;
hsv.z *= texture(curve_map, vec2(coordinates.z, layer)).z * 2.0;
/* Sanitize the new hue and saturation values. */
hsv.x = fract(hsv.x);

View File

@ -123,10 +123,24 @@ vec3 lightprobe_eval(LightProbeSample samp, ClosureReflection reflection, vec3 P
return mix(radiance_cube, radiance_sh, fac);
}
/* Return the equivalent reflective roughness resulting in a similar lobe. */
float lightprobe_refraction_roughness_remapping(float roughness, float ior)
{
/* This is a very rough mapping used by manually curve fitting the apparent roughness
* (blurriness) of GGX reflections and GGX refraction.
* A better fit is desirable if it is in the same order of complexity. */
if (ior > 1.0) {
return roughness * sqrt_fast(1.0 - 1.0 / ior);
}
else {
return roughness * sqrt_fast(saturate(1.0 - ior)) * 0.8;
}
}
vec3 lightprobe_refraction_dominant_dir(vec3 N, vec3 V, float ior, float roughness)
{
/* Reusing same thing as lightprobe_reflection_dominant_dir for now.
* TODO(fclem): Find something better that take IOR and roughness into account. */
/* Reusing same thing as lightprobe_reflection_dominant_dir for now with the roughness mapped to
* reflection roughness. */
float m = square(roughness);
vec3 R = refract(-V, N, 1.0 / ior);
float smoothness = 1.0 - m;
@ -136,13 +150,15 @@ vec3 lightprobe_refraction_dominant_dir(vec3 N, vec3 V, float ior, float roughne
vec3 lightprobe_eval(LightProbeSample samp, ClosureRefraction cl, vec3 P, vec3 V)
{
vec3 L = lightprobe_refraction_dominant_dir(cl.N, V, cl.ior, cl.roughness);
float effective_roughness = lightprobe_refraction_roughness_remapping(cl.roughness, cl.ior);
float lod = sphere_probe_roughness_to_lod(cl.roughness);
vec3 L = lightprobe_refraction_dominant_dir(cl.N, V, cl.ior, effective_roughness);
float lod = sphere_probe_roughness_to_lod(effective_roughness);
vec3 radiance_cube = lightprobe_spherical_sample_normalized_with_parallax(
samp.spherical_id, P, L, lod, samp.volume_irradiance);
float fac = sphere_probe_roughness_to_mix_fac(cl.roughness);
float fac = sphere_probe_roughness_to_mix_fac(effective_roughness);
vec3 radiance_sh = spherical_harmonics_evaluate_lambert(L, samp.volume_irradiance);
return mix(radiance_cube, radiance_sh, fac);
}

View File

@ -3271,6 +3271,9 @@ static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect)
float *hsv = cpicker->hsv_perceptual;
float hsv_n[3];
/* Is this the larger color canvas or narrow color slider? */
bool is_canvas = ELEM(hsv_but->gradient_type, UI_GRAD_SV, UI_GRAD_HV, UI_GRAD_HS);
/* Initialize for compatibility. */
copy_v3_v3(hsv_n, hsv);
@ -3292,15 +3295,15 @@ static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect)
imm_draw_box_wire_2d(pos, (rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax));
immUnbindProgram();
if (BLI_rcti_size_x(rect) / BLI_rcti_size_y(rect) < 3) {
/* This is for the full square HSV cube. */
if (is_canvas) {
/* Round cursor in the large square area. */
float margin = (4.0f * UI_SCALE_FAC);
CLAMP(x, rect->xmin + margin, rect->xmax - margin);
CLAMP(y, rect->ymin + margin, rect->ymax - margin);
ui_hsv_cursor(x, y, zoom, rgb, hsv, but->flag & UI_SELECT);
}
else {
/* This is for the narrow horizontal gradient. */
/* Square indicator in the narrow area. */
rctf rectf;
BLI_rctf_rcti_copy(&rectf, rect);
const float margin = (2.0f * UI_SCALE_FAC);

View File

@ -354,7 +354,7 @@ static void PREFERENCES_OT_extension_repo_add(wmOperatorType *ot)
static const EnumPropertyItem repo_type_items[] = {
{int(bUserExtensionRepoAddType::Remote),
"REMOTE",
ICON_WORLD,
ICON_NETWORK_DRIVE,
"Add Remote Repository",
"Add a repository referencing an remote repository "
"with support for listing and updating extensions"},
@ -630,6 +630,33 @@ static void PREFERENCES_OT_extension_repo_upgrade(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Drop Extension Operator
* \{ */
static int preferences_extension_url_drop_exec(bContext *C, wmOperator *op)
{
char *url = RNA_string_get_alloc(op->ptr, "url", nullptr, 0, nullptr);
BKE_callback_exec_string(CTX_data_main(C), BKE_CB_EVT_EXTENSION_DROP_URL, url);
MEM_freeN(url);
return OPERATOR_FINISHED;
}
static void PREFERENCES_OT_extension_url_drop(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Drop Extension URL";
ot->description = "Handle dropping an extension URL";
ot->idname = "PREFERENCES_OT_extension_url_drop";
/* api callbacks */
ot->exec = preferences_extension_url_drop_exec;
RNA_def_string(ot->srna, "url", nullptr, 0, "URL", "Location of the extension to install");
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Associate File Type Operator (Windows only)
* \{ */
@ -746,6 +773,96 @@ static void PREFERENCES_OT_unassociate_blend(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Drag & Drop URL
* \{ */
static bool drop_extension_url_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/)
{
if (!U.experimental.use_extension_repos) {
return false;
}
if (drag->type != WM_DRAG_STRING) {
return false;
}
const std::string &str = WM_drag_get_string(drag);
/* Only URL formatted text. */
const char *cstr = str.c_str();
if (!(STRPREFIX(cstr, "http://") || STRPREFIX(cstr, "https://") || STRPREFIX(cstr, "file://"))) {
return false;
}
/* Only single line strings. */
if (str.find('\n') != std::string::npos) {
return false;
}
const char *cstr_ext = BLI_path_extension(cstr);
if (!(cstr_ext && STRCASEEQ(cstr_ext, ".zip"))) {
return false;
}
return true;
}
static void drop_extension_url_copy(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
/* Copy drag URL to properties. */
const std::string &str = WM_drag_get_string(drag);
RNA_string_set(drop->ptr, "url", str.c_str());
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Drag & Drop Paths
* \{ */
static bool drop_extension_path_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/)
{
if (!U.experimental.use_extension_repos) {
return false;
}
if (drag->type != WM_DRAG_PATH) {
return false;
}
const char *cstr = WM_drag_get_single_path(drag);
const char *cstr_ext = BLI_path_extension(cstr);
if (!(cstr_ext && STRCASEEQ(cstr_ext, ".zip"))) {
return false;
}
return true;
}
static void drop_extension_path_copy(bContext * /*C*/, wmDrag *drag, wmDropBox *drop)
{
/* Copy drag URL to properties. */
const char *cstr = WM_drag_get_single_path(drag);
RNA_string_set(drop->ptr, "url", cstr);
}
/** \} */
static void ED_dropbox_drop_extension()
{
ListBase *lb = WM_dropboxmap_find("Window", SPACE_EMPTY, RGN_TYPE_WINDOW);
WM_dropbox_add(lb,
"PREFERENCES_OT_extension_url_drop",
drop_extension_url_poll,
drop_extension_url_copy,
nullptr,
nullptr);
WM_dropbox_add(lb,
"PREFERENCES_OT_extension_url_drop",
drop_extension_path_poll,
drop_extension_path_copy,
nullptr,
nullptr);
}
void ED_operatortypes_userpref()
{
WM_operatortype_append(PREFERENCES_OT_reset_default_theme);
@ -760,7 +877,10 @@ void ED_operatortypes_userpref()
WM_operatortype_append(PREFERENCES_OT_extension_repo_remove);
WM_operatortype_append(PREFERENCES_OT_extension_repo_sync);
WM_operatortype_append(PREFERENCES_OT_extension_repo_upgrade);
WM_operatortype_append(PREFERENCES_OT_extension_url_drop);
WM_operatortype_append(PREFERENCES_OT_associate_blend);
WM_operatortype_append(PREFERENCES_OT_unassociate_blend);
ED_dropbox_drop_extension();
}

View File

@ -596,7 +596,7 @@ void GPU_shader_constant_bool_ex(GPUShader *sh, int location, bool value)
Shader &shader = *unwrap(sh);
BLI_assert(shader.constants.types[location] == gpu::shader::Type::BOOL);
shader.constants.is_dirty |= assign_if_different(shader.constants.values[location].u,
static_cast<uint32_t>(value));
uint32_t(value));
}
void GPU_shader_constant_int(GPUShader *sh, const char *name, int value)

View File

@ -63,7 +63,7 @@ void node_tex_voronoi_f1_1d(vec3 coord,
params.max_distance = 0.5 + 0.5 * params.randomness;
VoronoiOutput Output = fractal_voronoi_x_fx(params, w);
outDistance = Output.Distance;
outColor.xyz = Output.Color;
outColor = vec4(Output.Color, 1.0);
outW = Output.Position.w;
}
@ -93,7 +93,7 @@ void node_tex_voronoi_smooth_f1_1d(vec3 coord,
params.max_distance = 0.5 + 0.5 * params.randomness;
VoronoiOutput Output = fractal_voronoi_x_fx(params, w);
outDistance = Output.Distance;
outColor.xyz = Output.Color;
outColor = vec4(Output.Color, 1.0);
outW = Output.Position.w;
}
@ -123,7 +123,7 @@ void node_tex_voronoi_f2_1d(vec3 coord,
params.max_distance = (0.5 + 0.5 * params.randomness) * 2.0;
VoronoiOutput Output = fractal_voronoi_x_fx(params, w);
outDistance = Output.Distance;
outColor.xyz = Output.Color;
outColor = vec4(Output.Color, 1.0);
outW = Output.Position.w;
}
@ -208,7 +208,7 @@ void node_tex_voronoi_f1_2d(vec3 coord,
params.max_distance = voronoi_distance(vec2(0.0), vec2(0.5 + 0.5 * params.randomness), params);
VoronoiOutput Output = fractal_voronoi_x_fx(params, coord.xy);
outDistance = Output.Distance;
outColor.xyz = Output.Color;
outColor = vec4(Output.Color, 1.0);
outPosition = Output.Position.xyz;
}
@ -238,7 +238,7 @@ void node_tex_voronoi_smooth_f1_2d(vec3 coord,
params.max_distance = voronoi_distance(vec2(0.0), vec2(0.5 + 0.5 * params.randomness), params);
VoronoiOutput Output = fractal_voronoi_x_fx(params, coord.xy);
outDistance = Output.Distance;
outColor.xyz = Output.Color;
outColor = vec4(Output.Color, 1.0);
outPosition = Output.Position.xyz;
}
@ -269,7 +269,7 @@ void node_tex_voronoi_f2_2d(vec3 coord,
2.0;
VoronoiOutput Output = fractal_voronoi_x_fx(params, coord.xy);
outDistance = Output.Distance;
outColor.xyz = Output.Color;
outColor = vec4(Output.Color, 1.0);
outPosition = Output.Position.xyz;
}
@ -354,7 +354,7 @@ void node_tex_voronoi_f1_3d(vec3 coord,
params.max_distance = voronoi_distance(vec3(0.0), vec3(0.5 + 0.5 * params.randomness), params);
VoronoiOutput Output = fractal_voronoi_x_fx(params, coord);
outDistance = Output.Distance;
outColor.xyz = Output.Color;
outColor = vec4(Output.Color, 1.0);
outPosition = Output.Position.xyz;
}
@ -384,7 +384,7 @@ void node_tex_voronoi_smooth_f1_3d(vec3 coord,
params.max_distance = voronoi_distance(vec3(0.0), vec3(0.5 + 0.5 * params.randomness), params);
VoronoiOutput Output = fractal_voronoi_x_fx(params, coord);
outDistance = Output.Distance;
outColor.xyz = Output.Color;
outColor = vec4(Output.Color, 1.0);
outPosition = Output.Position.xyz;
}
@ -415,7 +415,7 @@ void node_tex_voronoi_f2_3d(vec3 coord,
2.0;
VoronoiOutput Output = fractal_voronoi_x_fx(params, coord);
outDistance = Output.Distance;
outColor.xyz = Output.Color;
outColor = vec4(Output.Color, 1.0);
outPosition = Output.Position.xyz;
}
@ -501,7 +501,7 @@ void node_tex_voronoi_f1_4d(vec3 coord,
params.max_distance = voronoi_distance(vec4(0.0), vec4(0.5 + 0.5 * params.randomness), params);
VoronoiOutput Output = fractal_voronoi_x_fx(params, vec4(coord, w));
outDistance = Output.Distance;
outColor.xyz = Output.Color;
outColor = vec4(Output.Color, 1.0);
outPosition = Output.Position.xyz;
outW = Output.Position.w;
}
@ -533,7 +533,7 @@ void node_tex_voronoi_smooth_f1_4d(vec3 coord,
params.max_distance = voronoi_distance(vec4(0.0), vec4(0.5 + 0.5 * params.randomness), params);
VoronoiOutput Output = fractal_voronoi_x_fx(params, vec4(coord, w));
outDistance = Output.Distance;
outColor.xyz = Output.Color;
outColor = vec4(Output.Color, 1.0);
outPosition = Output.Position.xyz;
outW = Output.Position.w;
}
@ -566,7 +566,7 @@ void node_tex_voronoi_f2_4d(vec3 coord,
2.0;
VoronoiOutput Output = fractal_voronoi_x_fx(params, vec4(coord, w));
outDistance = Output.Distance;
outColor.xyz = Output.Color;
outColor = vec4(Output.Color, 1.0);
outPosition = Output.Position.xyz;
outW = Output.Position.w;
}

View File

@ -356,5 +356,5 @@ ImbAnimType imb_get_anim_type(const char *filepath)
bool IMB_isanim(const char *filepath)
{
ImbAnimType type = imb_get_anim_type(filepath);
return (type != ImbAnimType::NotAnim && type != ImbAnimType::Sequence);
return !ELEM(type, ImbAnimType::NotAnim, ImbAnimType::Sequence);
}

View File

@ -96,6 +96,7 @@ static PyStructSequence_Field app_cb_info_fields[] = {
{"_extension_repos_update_post", "on changes to extension repos (after)"},
{"_extension_repos_sync", "on creating or synchronizing the active repository"},
{"_extension_repos_upgrade", "on upgrading the active repository"},
{"_extension_drop_url", "on dropping a URL"},
/* sets the permanent tag */
#define APP_CB_OTHER_FIELDS 1

View File

@ -31,7 +31,7 @@ static void __cpuid(
}
#endif
static int cpu_supports_sse42(void)
static int cpu_supports_sse42()
{
int result[4], num;
__cpuid(result, 0);
@ -39,17 +39,17 @@ static int cpu_supports_sse42(void)
if (num >= 1) {
__cpuid(result, 0x00000001);
return (result[2] & ((int)1 << 20)) != 0;
return (result[2] & (int(1) << 20)) != 0;
}
return 0;
}
static const char *cpu_brand_string(void)
static const char *cpu_brand_string()
{
static char buf[49] = {0};
int result[4] = {0};
__cpuid(result, 0x80000000);
if (result[0] >= (int)0x80000004) {
if (result[0] >= int(0x80000004)) {
__cpuid((int *)(buf + 0), 0x80000002);
__cpuid((int *)(buf + 16), 0x80000003);
__cpuid((int *)(buf + 32), 0x80000004);
@ -60,7 +60,7 @@ static const char *cpu_brand_string(void)
}
return buf_ptr;
}
return NULL;
return nullptr;
}
#ifdef _MSC_VER
@ -91,7 +91,7 @@ BOOL WINAPI DllMain(HINSTANCE /* hinstDLL */, DWORD fdwReason, LPVOID /* lpvRese
# include <cstdio>
# include <cstdlib>
static __attribute__((constructor)) void cpu_check(void)
static __attribute__((constructor)) void cpu_check()
{
# ifdef __x86_64
if (!cpu_supports_sse42()) {

View File

@ -327,7 +327,7 @@ def process_commands(cmake_dir: str, data: Sequence[str]) -> Optional[ProcessedC
return None
# Check for unsupported configurations.
for arg in ("WITH_UNITY_BUILD", "WITH_COMPILER_CCACHE"):
for arg in ("WITH_UNITY_BUILD", "WITH_COMPILER_CCACHE", "WITH_COMPILER_PRECOMPILED_HEADERS"):
if cmake_cache_var_is_true(cmake_cache_var(cmake_dir, arg)):
sys.stderr.write("The option '%s' must be disabled for proper functionality\n" % arg)
return None