Merge branch 'master' into blender-projects-basics

This commit is contained in:
Julian Eisel 2022-10-13 12:06:12 +02:00
commit f22cc99944
616 changed files with 5798 additions and 3408 deletions

View File

@ -242,17 +242,17 @@ if(UNIX AND NOT (APPLE OR HAIKU))
option(WITH_GHOST_X11 "Enable building Blender against X11 for windowing" ON)
mark_as_advanced(WITH_GHOST_X11)
option(WITH_GHOST_WAYLAND "Enable building Blender against Wayland for windowing (under development)" OFF)
option(WITH_GHOST_WAYLAND "Enable building Blender against Wayland for windowing" ON)
mark_as_advanced(WITH_GHOST_WAYLAND)
if(WITH_GHOST_WAYLAND)
option(WITH_GHOST_WAYLAND_LIBDECOR "Optionally build with LibDecor window decorations" OFF)
option(WITH_GHOST_WAYLAND_LIBDECOR "Optionally build with LibDecor window decorations" ON)
mark_as_advanced(WITH_GHOST_WAYLAND_LIBDECOR)
option(WITH_GHOST_WAYLAND_DBUS "Optionally build with DBUS support (used for Cursor themes). May hang on startup systems where DBUS is not used." OFF)
mark_as_advanced(WITH_GHOST_WAYLAND_DBUS)
option(WITH_GHOST_WAYLAND_DYNLOAD "Enable runtime dynamic WAYLAND libraries loading" OFF)
option(WITH_GHOST_WAYLAND_DYNLOAD "Enable runtime dynamic WAYLAND libraries loading" ON)
mark_as_advanced(WITH_GHOST_WAYLAND_DYNLOAD)
endif()
endif()
@ -1913,9 +1913,25 @@ if(FIRST_RUN)
info_cfg_option(WITH_INSTALL_PORTABLE)
info_cfg_option(WITH_MEM_JEMALLOC)
info_cfg_option(WITH_MEM_VALGRIND)
info_cfg_option(WITH_X11_XF86VMODE)
info_cfg_option(WITH_X11_XFIXES)
info_cfg_option(WITH_X11_XINPUT)
info_cfg_text("GHOST Options:")
info_cfg_option(WITH_GHOST_DEBUG)
info_cfg_option(WITH_GHOST_SDL)
if(UNIX AND NOT APPLE)
info_cfg_option(WITH_GHOST_X11)
info_cfg_option(WITH_GHOST_WAYLAND)
if(WITH_GHOST_X11)
info_cfg_option(WITH_GHOST_XDND)
info_cfg_option(WITH_X11_XF86VMODE)
info_cfg_option(WITH_X11_XFIXES)
info_cfg_option(WITH_X11_XINPUT)
endif()
if(WITH_GHOST_WAYLAND)
info_cfg_option(WITH_GHOST_WAYLAND_DYNLOAD)
info_cfg_option(WITH_GHOST_WAYLAND_LIBDECOR)
info_cfg_option(WITH_GHOST_WAYLAND_DBUS)
endif()
endif()
info_cfg_text("Image Formats:")
info_cfg_option(WITH_IMAGE_CINEON)

View File

@ -172,6 +172,8 @@ if(UNIX AND NOT APPLE)
include(cmake/wayland_protocols.cmake)
# Can be removed when the build-bot upgrades to v1.20.x or newer.
include(cmake/wayland.cmake)
include(cmake/wayland_libdecor.cmake)
endif()
include(cmake/harvest.cmake)
include(cmake/cve_check.cmake)

View File

@ -0,0 +1,73 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# CVE Check requirements
#
# - A working installation of intels cve-bin-tool [1] has to be available in
# your path
#
# - Not strictly required, but highly recommended is obtaining a NVD key from
# nist since it significantly speeds up downloading/updating the required
# databases one can request a key on the following website:
# https://nvd.nist.gov/developers/request-an-api-key
# Bill of Materials construction
#
# This constructs a CSV cve-bin-tool [1] can read and process. Sadly
# cve-bin-tool at this point does not take a list of CPE's and output a check
# based on that list. so we need to pick apart the CPE retrieve the vendor,
# product and version tokens and generate a CSV.
#
# [1] https://github.com/intel/cve-bin-tool
# Because not all deps are downloaded (ie python packages) but can still have a
# xxx_CPE declared loop over all variables and look for variables ending in CPE.
set(SBOMCONTENTS)
get_cmake_property(_variableNames VARIABLES)
foreach (_variableName ${_variableNames})
if(_variableName MATCHES "CPE$")
string(REPLACE ":" ";" CPE_LIST ${${_variableName}})
list(GET CPE_LIST 3 CPE_VENDOR)
list(GET CPE_LIST 4 CPE_NAME)
list(GET CPE_LIST 5 CPE_VERSION)
set(SBOMCONTENTS "${SBOMCONTENTS}${CPE_VENDOR},${CPE_NAME},${CPE_VERSION}\n")
endif()
endforeach()
configure_file(${CMAKE_SOURCE_DIR}/cmake/cve_check.csv.in ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv @ONLY)
# Custom Targets
#
# This defines two new custom targets one could run in the build folder
# `cve_check` which will output the report to the console, and `cve_check_html`
# which will write out blender_dependencies.html in the build folder that one
# could share with other people or be used to get more information on the
# reported CVE's.
#
# cve-bin-tool takes data from the nist nvd database which rate limits
# unauthenticated requests to 1 requests per 6 seconds making the database
# download take "quite a bit" of time.
#
# When adding -DCVE_CHECK_NVD_KEY=your_api_key_here to your cmake invocation
# this key will be passed on to cve-bin-tool speeding up the process.
#
if(DEFINED CVE_CHECK_NVD_KEY)
set(NVD_ARGS --nvd-api-key ${CVE_CHECK_NVD_KEY})
endif()
# This will just report to the console
add_custom_target(cve_check
COMMAND cve-bin-tool
${NVD_ARGS}
-i ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv
--affected-versions
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv
)
# This will write out blender_dependencies.html
add_custom_target(cve_check_html
COMMAND cve-bin-tool
${NVD_ARGS}
-i ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv
-f html
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv
)

View File

@ -0,0 +1,2 @@
vendor,product,version
@SBOMCONTENTS@

View File

@ -133,6 +133,7 @@ download_source(NASM)
download_source(XR_OPENXR_SDK)
download_source(WL_PROTOCOLS)
download_source(WAYLAND)
download_source(WAYLAND_LIBDECOR)
download_source(ISPC)
download_source(GMP)
download_source(POTRACE)

View File

@ -118,6 +118,8 @@ else()
harvest(wayland-protocols/share/wayland-protocols wayland-protocols/share/wayland-protocols/ "*.xml")
harvest(wayland/bin wayland/bin "wayland-scanner")
harvest(wayland/include wayland/include "*.h")
harvest(wayland_libdecor/include wayland_libdecor/include "*.h")
else()
harvest(blosc/lib openvdb/lib "*.a")
harvest(xml2/lib opencollada/lib "*.a")

View File

@ -43,6 +43,7 @@ if(WIN32)
else()
ExternalProject_Add_Step(external_openpgl after_install
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openpgl/lib/openpgl_d.lib ${HARVEST_TARGET}/openpgl/lib/openpgl_d.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openpgl/lib/cmake/openpgl-${OPENPGL_SHORT_VERSION}/openpgl_Exports-debug.cmake ${HARVEST_TARGET}/openpgl/lib/cmake/openpgl-${OPENPGL_SHORT_VERSION}/openpgl_Exports-debug.cmake
DEPENDEES install
)
endif()

View File

@ -1,10 +1,19 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# CPE's are used to identify dependencies, for more information on what they
# are please see https://nvd.nist.gov/products/cpe
#
# We use them in combination with cve-bin-tool to scan for known security issues.
#
# Not all of our dependencies are currently in the nvd database so not all
# dependencies have one assigned.
set(ZLIB_VERSION 1.2.12)
set(ZLIB_URI https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz)
set(ZLIB_HASH 5fc414a9726be31427b440b434d05f78)
set(ZLIB_HASH_TYPE MD5)
set(ZLIB_FILE zlib-${ZLIB_VERSION}.tar.gz)
set(ZLIB_CPE "cpe:2.3:a:zlib:zlib:${ZLIB_VERSION}:*:*:*:*:*:*:*")
set(OPENAL_VERSION 1.21.1)
set(OPENAL_URI http://openal-soft.org/openal-releases/openal-soft-${OPENAL_VERSION}.tar.bz2)
@ -17,12 +26,14 @@ set(PNG_URI http://prdownloads.sourceforge.net/libpng/libpng-${PNG_VERSION}.tar.
set(PNG_HASH 505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca)
set(PNG_HASH_TYPE SHA256)
set(PNG_FILE libpng-${PNG_VERSION}.tar.xz)
set(PNG_CPE "cpe:2.3:a:libpng:libpng:${PNG_VERSION}:*:*:*:*:*:*:*")
set(JPEG_VERSION 2.1.3)
set(JPEG_URI https://github.com/libjpeg-turbo/libjpeg-turbo/archive/${JPEG_VERSION}.tar.gz)
set(JPEG_HASH 627b980fad0573e08e4c3b80b290fc91)
set(JPEG_HASH_TYPE MD5)
set(JPEG_FILE libjpeg-turbo-${JPEG_VERSION}.tar.gz)
set(JPEG_CPE "cpe:2.3:a:d.r.commander:libjpeg-turbo:${JPEG_VERSION}:*:*:*:*:*:*:*")
set(BOOST_VERSION 1.78.0)
set(BOOST_VERSION_SHORT 1.78)
@ -32,12 +43,14 @@ set(BOOST_URI https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION
set(BOOST_HASH c2f6428ac52b0e5a3c9b2e1d8cc832b5)
set(BOOST_HASH_TYPE MD5)
set(BOOST_FILE boost_${BOOST_VERSION_NODOTS}.tar.gz)
set(BOOST_CPE "cpe:2.3:a:boost:boost:${BOOST_VERSION}:*:*:*:*:*:*:*")
set(BLOSC_VERSION 1.21.1)
set(BLOSC_URI https://github.com/Blosc/c-blosc/archive/v${BLOSC_VERSION}.tar.gz)
set(BLOSC_HASH 134b55813b1dca57019d2a2dc1f7a923)
set(BLOSC_HASH_TYPE MD5)
set(BLOSC_FILE blosc-${BLOSC_VERSION}.tar.gz)
set(BLOSC_CPE "cpe:2.3:a:c-blosc2_project:c-blosc2:${BLOSC_VERSION}:*:*:*:*:*:*:*")
set(PTHREADS_VERSION 3.0.0)
set(PTHREADS_URI http://prdownloads.sourceforge.net/pthreads4w/pthreads4w-code-v${PTHREADS_VERSION}.zip)
@ -50,6 +63,7 @@ set(OPENEXR_URI https://github.com/AcademySoftwareFoundation/openexr/archive/v${
set(OPENEXR_HASH a92f38eedd43e56c0af56d4852506886)
set(OPENEXR_HASH_TYPE MD5)
set(OPENEXR_FILE openexr-${OPENEXR_VERSION}.tar.gz)
set(OPENEXR_CPE "cpe:2.3:a:openexr:openexr:${OPENEXR_VERSION}:*:*:*:*:*:*:*")
set(IMATH_VERSION 3.1.5)
set(IMATH_URI https://github.com/AcademySoftwareFoundation/Imath/archive/v${OPENEXR_VERSION}.tar.gz)
@ -79,6 +93,7 @@ set(FREETYPE_URI http://prdownloads.sourceforge.net/freetype/freetype-${FREETYPE
set(FREETYPE_HASH bd4e3b007474319909a6b79d50908e85)
set(FREETYPE_HASH_TYPE MD5)
set(FREETYPE_FILE freetype-${FREETYPE_VERSION}.tar.gz)
SET(FREETYPE_CPE "cpe:2.3:a:freetype:freetype:${FREETYPE_VERSION}:*:*:*:*:*:*:*")
set(EPOXY_VERSION 1.5.10)
set(EPOXY_URI https://github.com/anholt/libepoxy/archive/refs/tags/${EPOXY_VERSION}.tar.gz)
@ -97,6 +112,7 @@ set(ALEMBIC_URI https://github.com/alembic/alembic/archive/${ALEMBIC_VERSION}.ta
set(ALEMBIC_HASH 2cd8d6e5a3ac4a014e24a4b04f4fadf9)
set(ALEMBIC_HASH_TYPE MD5)
set(ALEMBIC_FILE alembic-${ALEMBIC_VERSION}.tar.gz)
SET(FREETYPE_CPE "cpe:2.3:a:freetype:freetype:${FREETYPE_VERSION}:*:*:*:*:*:*:*")
set(OPENSUBDIV_VERSION v3_4_4)
set(OPENSUBDIV_URI https://github.com/PixarAnimationStudios/OpenSubdiv/archive/${OPENSUBDIV_VERSION}.tar.gz)
@ -109,6 +125,7 @@ set(SDL_URI https://www.libsdl.org/release/SDL2-${SDL_VERSION}.tar.gz)
set(SDL_HASH a53acc02e1cca98c4123229069b67c9e)
set(SDL_HASH_TYPE MD5)
set(SDL_FILE SDL2-${SDL_VERSION}.tar.gz)
set(SDL_CPE "cpe:2.3:a:libsdl:sdl:${SDL_VERSION}:*:*:*:*:*:*:*")
set(OPENCOLLADA_VERSION v1.6.68)
set(OPENCOLLADA_URI https://github.com/KhronosGroup/OpenCOLLADA/archive/${OPENCOLLADA_VERSION}.tar.gz)
@ -127,6 +144,7 @@ set(LLVM_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${LL
set(LLVM_HASH 5a4fab4d7fc84aefffb118ac2c8a4fc0)
set(LLVM_HASH_TYPE MD5)
set(LLVM_FILE llvm-project-${LLVM_VERSION}.src.tar.xz)
set(LLVM_CPE "cpe:2.3:a:llvm:compiler:${LLVM_VERSION}:*:*:*:*:*:*:*")
if(APPLE)
# Cloth physics test is crashing due to this bug:
@ -154,6 +172,7 @@ set(FMT_URI https://github.com/fmtlib/fmt/archive/refs/tags/${FMT_VERSION}.tar.g
set(FMT_HASH 7bce0e9e022e586b178b150002e7c2339994e3c2bbe44027e9abb0d60f9cce83)
set(FMT_HASH_TYPE SHA256)
set(FMT_FILE fmt-${FMT_VERSION}.tar.gz)
set(FMT_CPE "cpe:2.3:a:fmt:fmt:${FMT_VERSION}:*:*:*:*:*:*:*")
# 0.6.2 is currently oiio's preferred version although never versions may be available.
# the preferred version can be found in oiio's externalpackages.cmake
@ -168,6 +187,7 @@ set(TIFF_URI http://download.osgeo.org/libtiff/tiff-${TIFF_VERSION}.tar.gz)
set(TIFF_HASH 376f17f189e9d02280dfe709b2b2bbea)
set(TIFF_HASH_TYPE MD5)
set(TIFF_FILE tiff-${TIFF_VERSION}.tar.gz)
set(TIFF_CPE "cpe:2.3:a:libtiff:libtiff:${TIFF_VERSION}:*:*:*:*:*:*:*")
set(OSL_VERSION 1.11.17.0)
set(OSL_URI https://github.com/imageworks/OpenShadingLanguage/archive/Release-${OSL_VERSION}.tar.gz)
@ -182,12 +202,15 @@ set(PYTHON_URI https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTH
set(PYTHON_HASH 14e8c22458ed7779a1957b26cde01db9)
set(PYTHON_HASH_TYPE MD5)
set(PYTHON_FILE Python-${PYTHON_VERSION}.tar.xz)
set(PYTHON_CPE "cpe:2.3:a:python:python:${PYTHON_VERSION}:-:*:*:*:*:*:*")
set(TBB_VERSION 2020_U3)
set(TBB_YEAR 2020)
set(TBB_VERSION ${TBB_YEAR}_U3)
set(TBB_URI https://github.com/oneapi-src/oneTBB/archive/${TBB_VERSION}.tar.gz)
set(TBB_HASH 55ec8df6eae5ed6364a47f0e671e460c)
set(TBB_HASH_TYPE MD5)
set(TBB_FILE oneTBB-${TBB_VERSION}.tar.gz)
set(TBB_CPE "cpe:2.3:a:intel:threading_building_blocks:${TBB_YEAR}:*:*:*:*:*:*:*")
set(OPENVDB_VERSION 9.0.0)
set(OPENVDB_URI https://github.com/AcademySoftwareFoundation/openvdb/archive/v${OPENVDB_VERSION}.tar.gz)
@ -198,6 +221,7 @@ set(OPENVDB_FILE openvdb-${OPENVDB_VERSION}.tar.gz)
set(IDNA_VERSION 3.3)
set(CHARSET_NORMALIZER_VERSION 2.0.10)
set(URLLIB3_VERSION 1.26.8)
set(URLLIB3_CPE "cpe:2.3:a:urllib3:urllib3:${URLLIB3_VERSION}:*:*:*:*:*:*:*")
set(CERTIFI_VERSION 2021.10.8)
set(REQUESTS_VERSION 2.27.1)
set(CYTHON_VERSION 0.29.26)
@ -214,12 +238,14 @@ set(NUMPY_URI https://github.com/numpy/numpy/releases/download/v${NUMPY_VERSION}
set(NUMPY_HASH 252de134862a27bd66705d29622edbfe)
set(NUMPY_HASH_TYPE MD5)
set(NUMPY_FILE numpy-${NUMPY_VERSION}.zip)
set(NUMPY_CPE "cpe:2.3:a:numpy:numpy:${NUMPY_VERSION}:*:*:*:*:*:*:*")
set(LAME_VERSION 3.100)
set(LAME_URI http://downloads.sourceforge.net/project/lame/lame/3.100/lame-${LAME_VERSION}.tar.gz)
set(LAME_HASH 83e260acbe4389b54fe08e0bdbf7cddb)
set(LAME_HASH_TYPE MD5)
set(LAME_FILE lame-${LAME_VERSION}.tar.gz)
set(LAME_CPE "cpe:2.3:a:lame_project:lame:${LAME_VERSION}:*:*:*:*:*:*:*")
set(OGG_VERSION 1.3.5)
set(OGG_URI http://downloads.xiph.org/releases/ogg/libogg-${OGG_VERSION}.tar.gz)
@ -232,6 +258,7 @@ set(VORBIS_URI http://downloads.xiph.org/releases/vorbis/libvorbis-${VORBIS_VERS
set(VORBIS_HASH 0e982409a9c3fc82ee06e08205b1355e5c6aa4c36bca58146ef399621b0ce5ab)
set(VORBIS_HASH_TYPE SHA256)
set(VORBIS_FILE libvorbis-${VORBIS_VERSION}.tar.gz)
set(VORBIS_CPE "cpe:2.3:a:xiph.org:libvorbis:${VORBIS_VERSION}:*:*:*:*:*:*:*")
set(THEORA_VERSION 1.1.1)
set(THEORA_URI http://downloads.xiph.org/releases/theora/libtheora-${THEORA_VERSION}.tar.bz2)
@ -244,12 +271,14 @@ set(FLAC_URI http://downloads.xiph.org/releases/flac/flac-${FLAC_VERSION}.tar.xz
set(FLAC_HASH 8ff0607e75a322dd7cd6ec48f4f225471404ae2730d0ea945127b1355155e737 )
set(FLAC_HASH_TYPE SHA256)
set(FLAC_FILE flac-${FLAC_VERSION}.tar.xz)
set(FLAC_CPE "cpe:2.3:a:flac_project:flac:${FLAC_VERSION}:*:*:*:*:*:*:*")
set(VPX_VERSION 1.11.0)
set(VPX_URI https://github.com/webmproject/libvpx/archive/v${VPX_VERSION}/libvpx-v${VPX_VERSION}.tar.gz)
set(VPX_HASH 965e51c91ad9851e2337aebcc0f517440c637c506f3a03948062e3d5ea129a83)
set(VPX_HASH_TYPE SHA256)
set(VPX_FILE libvpx-v${VPX_VERSION}.tar.gz)
set(VPX_CPE "cpe:2.3:a:webmproject:libvpx:${VPX_VERSION}:*:*:*:*:*:*:*")
set(OPUS_VERSION 1.3.1)
set(OPUS_URI https://archive.mozilla.org/pub/opus/opus-${OPUS_VERSION}.tar.gz)
@ -275,12 +304,14 @@ set(OPENJPEG_URI https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSI
set(OPENJPEG_HASH 8702ba68b442657f11aaeb2b338443ca8d5fb95b0d845757968a7be31ef7f16d)
set(OPENJPEG_HASH_TYPE SHA256)
set(OPENJPEG_FILE openjpeg-v${OPENJPEG_VERSION}.tar.gz)
set(OPENJPEG_CPE "cpe:2.3:a:uclouvain:openjpeg:${OPENJPEG_VERSION}:*:*:*:*:*:*:*")
set(FFMPEG_VERSION 5.0)
set(FFMPEG_URI http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2)
set(FFMPEG_HASH c0130b8db2c763430fd1c6905288d61bc44ee0548ad5fcd2dfd650b88432bed9)
set(FFMPEG_HASH_TYPE SHA256)
set(FFMPEG_FILE ffmpeg-${FFMPEG_VERSION}.tar.bz2)
set(FFMPEG_CPE "cpe:2.3:a:ffmpeg:ffmpeg:${FFMPEG_VERSION}:*:*:*:*:*:*:*")
set(FFTW_VERSION 3.3.10)
set(FFTW_URI http://www.fftw.org/fftw-${FFTW_VERSION}.tar.gz)
@ -299,12 +330,14 @@ set(SNDFILE_URI http://www.mega-nerd.com/libsndfile/files/libsndfile-${SNDFILE_V
set(SNDFILE_HASH 646b5f98ce89ac60cdb060fcd398247c)
set(SNDFILE_HASH_TYPE MD5)
set(SNDFILE_FILE libsndfile-${SNDFILE_VERSION}.tar.gz)
set(SNDFILE_CPE "cpe:2.3:a:libsndfile_project:libsndfile:${SNDFILE_VERSION}:*:*:*:*:*:*:*")
set(WEBP_VERSION 1.2.2)
set(WEBP_URI https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-${WEBP_VERSION}.tar.gz)
set(WEBP_HASH b5e2e414a8adee4c25fe56b18dd9c549)
set(WEBP_HASH_TYPE MD5)
set(WEBP_FILE libwebp-${WEBP_VERSION}.tar.gz)
set(WEBP_CPE "cpe:2.3:a:webmproject:libwebp:${WEBP_VERSION}:*:*:*:*:*:*:*")
set(SPNAV_VERSION 0.2.3)
set(SPNAV_URI http://downloads.sourceforge.net/project/spacenav/spacenav%20library%20%28SDK%29/libspnav%20${SPNAV_VERSION}/libspnav-${SPNAV_VERSION}.tar.gz)
@ -323,6 +356,7 @@ set(XML2_URI http://xmlsoft.org/sources/libxml2-${XML2_VERSION}.tar.gz)
set(XML2_HASH 10942a1dc23137a8aa07f0639cbfece5)
set(XML2_HASH_TYPE MD5)
set(XML2_FILE libxml2-${XML2_VERSION}.tar.gz)
set(XML2_CPE "cpe:2.3:a:xmlsoft:libxml2:${XML2_VERSION}:*:*:*:*:*:*:*")
set(TINYXML_VERSION 2_6_2)
set(TINYXML_VERSION_DOTS 2.6.2)
@ -330,12 +364,14 @@ set(TINYXML_URI https://nchc.dl.sourceforge.net/project/tinyxml/tinyxml/${TINYXM
set(TINYXML_HASH c1b864c96804a10526540c664ade67f0)
set(TINYXML_HASH_TYPE MD5)
set(TINYXML_FILE tinyxml_${TINYXML_VERSION}.tar.gz)
set(TINYXML_CPE "cpe:2.3:a:tinyxml_project:tinyxml:${TINYXML_VERSION_DOTS}:*:*:*:*:*:*:*")
set(YAMLCPP_VERSION 0.6.3)
set(YAMLCPP_URI https://codeload.github.com/jbeder/yaml-cpp/tar.gz/yaml-cpp-${YAMLCPP_VERSION})
set(YAMLCPP_HASH b45bf1089a382e81f6b661062c10d0c2)
set(YAMLCPP_HASH_TYPE MD5)
set(YAMLCPP_FILE yaml-cpp-${YAMLCPP_VERSION}.tar.gz)
set(YAMLCPP "cpe:2.3:a:yaml-cpp_project:yaml-cpp:${YAMLCPP_VERSION}:*:*:*:*:*:*:*")
set(PYSTRING_VERSION v1.1.3)
set(PYSTRING_URI https://codeload.github.com/imageworks/pystring/tar.gz/refs/tags/${PYSTRING_VERSION})
@ -344,16 +380,19 @@ set(PYSTRING_HASH_TYPE MD5)
set(PYSTRING_FILE pystring-${PYSTRING_VERSION}.tar.gz)
set(EXPAT_VERSION 2_4_4)
set(EXPAT_VERSION_DOTS 2.4.4)
set(EXPAT_URI https://github.com/libexpat/libexpat/archive/R_${EXPAT_VERSION}.tar.gz)
set(EXPAT_HASH 2d3e81dee94b452369dc6394ff0f8f98)
set(EXPAT_HASH_TYPE MD5)
set(EXPAT_FILE libexpat-${EXPAT_VERSION}.tar.gz)
set(EXPAT_CPE "cpe:2.3:a:libexpat_project:libexpat:${EXPAT_VERSION_DOTS}:*:*:*:*:*:*:*")
set(PUGIXML_VERSION 1.10)
set(PUGIXML_URI https://github.com/zeux/pugixml/archive/v${PUGIXML_VERSION}.tar.gz)
set(PUGIXML_HASH 0c208b0664c7fb822bf1b49ad035e8fd)
set(PUGIXML_HASH_TYPE MD5)
set(PUGIXML_FILE pugixml-${PUGIXML_VERSION}.tar.gz)
set(PUGIXML_CPE "cpe:2.3:a:pugixml_project:pugixml:${PUGIXML_VERSION}:*:*:*:*:*:*:*")
set(FLEXBISON_VERSION 2.5.24)
set(FLEXBISON_URI http://prdownloads.sourceforge.net/winflexbison/win_flex_bison-${FLEXBISON_VERSION}.zip)
@ -376,12 +415,14 @@ set(BZIP2_URI http://http.debian.net/debian/pool/main/b/bzip2/bzip2_${BZIP2_VERS
set(BZIP2_HASH ab5a03176ee106d3f0fa90e381da478ddae405918153cca248e682cd0c4a2269)
set(BZIP2_HASH_TYPE SHA256)
set(BZIP2_FILE bzip2_${BZIP2_VERSION}.orig.tar.gz)
set(BZIP2_CPE "cpe:2.3:a:bzip:bzip2:${BZIP2_VERSION}:*:*:*:*:*:*:*")
set(FFI_VERSION 3.3)
set(FFI_URI https://sourceware.org/pub/libffi/libffi-${FFI_VERSION}.tar.gz)
set(FFI_HASH 72fba7922703ddfa7a028d513ac15a85c8d54c8d67f55fa5a4802885dc652056)
set(FFI_HASH_TYPE SHA256)
set(FFI_FILE libffi-${FFI_VERSION}.tar.gz)
set(FFI_CPE "cpe:2.3:a:libffi_project:libffi:${FFI_VERSION}:*:*:*:*:*:*:*")
set(LZMA_VERSION 5.2.5)
set(LZMA_URI https://tukaani.org/xz/xz-${LZMA_VERSION}.tar.bz2)
@ -403,12 +444,14 @@ else()
set(SSL_HASH_TYPE SHA256)
set(SSL_FILE openssl-${SSL_VERSION}.tar.gz)
endif()
set(SSL_CPE "cpe:2.3:a:openssl:openssl:${SSL_VERSION}:*:*:*:*:*:*:*")
set(SQLITE_VERSION 3.31.1)
set(SQLITE_URI https://www.sqlite.org/2018/sqlite-src-3240000.zip)
set(SQLITE_HASH fb558c49ee21a837713c4f1e7e413309aabdd9c7)
set(SQLITE_HASH_TYPE SHA1)
set(SQLITE_FILE sqlite-src-3240000.zip)
set(SQLITE_CPE "cpe:2.3:a:sqlite:sqlite:${SQLITE_VERSION}:*:*:*:*:*:*:*")
set(EMBREE_VERSION 3.13.4)
set(EMBREE_URI https://github.com/embree/embree/archive/v${EMBREE_VERSION}.zip)
@ -439,12 +482,14 @@ set(MESA_URI ftp://ftp.freedesktop.org/pub/mesa/mesa-${MESA_VERSION}.tar.xz)
set(MESA_HASH 022c7293074aeeced2278c872db4fa693147c70f8595b076cf3f1ef81520766d)
set(MESA_HASH_TYPE SHA256)
set(MESA_FILE mesa-${MESA_VERSION}.tar.xz)
set(MESA_CPE "cpe:2.3:a:mesa3d:mesa:${MESA_VERSION}:*:*:*:*:*:*:*")
set(NASM_VERSION 2.15.02)
set(NASM_URI https://github.com/netwide-assembler/nasm/archive/nasm-${NASM_VERSION}.tar.gz)
set(NASM_HASH aded8b796c996a486a56e0515c83e414116decc3b184d88043480b32eb0a8589)
set(NASM_HASH_TYPE SHA256)
set(NASM_FILE nasm-${NASM_VERSION}.tar.gz)
set(NASM_PCE "cpe:2.3:a:nasm:nasm:${NASM_VERSION}:*:*:*:*:*:*:*")
set(XR_OPENXR_SDK_VERSION 1.0.22)
set(XR_OPENXR_SDK_URI https://github.com/KhronosGroup/OpenXR-SDK/archive/release-${XR_OPENXR_SDK_VERSION}.tar.gz)
@ -464,6 +509,12 @@ set(WAYLAND_URI https://gitlab.freedesktop.org/wayland/wayland/-/releases/1.21.0
set(WAYLAND_HASH f2653a2293bcd882d756c6a83d278903)
set(WAYLAND_HASH_TYPE MD5)
set(WAYLAND_LIBDECOR_VERSION 0.1.0)
set(WAYLAND_LIBDECOR_FILE libdecor-${WAYLAND_LIBDECOR_VERSION}.tar.xz)
set(WAYLAND_LIBDECOR_URI https://gitlab.gnome.org/jadahl/libdecor/uploads/81adf91d27620e20bcc5f6b9b312d768/libdecor-${WAYLAND_LIBDECOR_VERSION}.tar.xz )
set(WAYLAND_LIBDECOR_HASH 47b59eba76faa3787f0878bf8700e912)
set(WAYLAND_LIBDECOR_HASH_TYPE MD5)
set(ISPC_VERSION v1.17.0)
set(ISPC_URI https://github.com/ispc/ispc/archive/${ISPC_VERSION}.tar.gz)
set(ISPC_HASH 4f476a3109332a77fe839a9014c60ca9)
@ -475,12 +526,14 @@ set(GMP_URI https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.xz)
set(GMP_HASH 0b82665c4a92fd2ade7440c13fcaa42b)
set(GMP_HASH_TYPE MD5)
set(GMP_FILE gmp-${GMP_VERSION}.tar.xz)
set(GMP_CPE "cpe:2.3:a:gmplib:gmp:${GMP_VERSION}:*:*:*:*:*:*:*")
set(POTRACE_VERSION 1.16)
set(POTRACE_URI http://potrace.sourceforge.net/download/${POTRACE_VERSION}/potrace-${POTRACE_VERSION}.tar.gz)
set(POTRACE_HASH 5f0bd87ddd9a620b0c4e65652ef93d69)
set(POTRACE_HASH_TYPE MD5)
set(POTRACE_FILE potrace-${POTRACE_VERSION}.tar.gz)
set(POTRACE_CPE "cpe:2.3:a:icoasoft:potrace:${POTRACE_VERSION}:*:*:*:*:*:*:*")
set(HARU_VERSION 2_3_0)
set(HARU_URI https://github.com/libharu/libharu/archive/RELEASE_${HARU_VERSION}.tar.gz)
@ -493,6 +546,7 @@ set(ZSTD_URI https://github.com/facebook/zstd/releases/download/v${ZSTD_VERSION}
set(ZSTD_HASH 5194fbfa781fcf45b98c5e849651aa7b3b0a008c6b72d4a0db760f3002291e94)
set(ZSTD_HASH_TYPE SHA256)
set(ZSTD_FILE zstd-${ZSTD_VERSION}.tar.gz)
set(ZSTD_CPE "cpe:2.3:a:facebook:zstandard:${ZSTD_VERSION}:*:*:*:*:*:*:*")
set(SSE2NEON_VERSION fe5ff00bb8d19b327714a3c290f3e2ce81ba3525)
set(SSE2NEON_URI https://github.com/DLTcollab/sse2neon/archive/${SSE2NEON_VERSION}.tar.gz)
@ -500,11 +554,12 @@ set(SSE2NEON_HASH 0780253525d299c31775ef95853698d03db9c7739942af8570000f4a25a5d6
set(SSE2NEON_HASH_TYPE SHA256)
set(SSE2NEON_FILE sse2neon-${SSE2NEON_VERSION}.tar.gz)
set(BROTLI_VERSION v1.0.9)
set(BROTLI_URI https://github.com/google/brotli/archive/refs/tags/${BROTLI_VERSION}.tar.gz)
set(BROTLI_VERSION 1.0.9)
set(BROTLI_URI https://github.com/google/brotli/archive/refs/tags/v${BROTLI_VERSION}.tar.gz)
set(BROTLI_HASH f9e8d81d0405ba66d181529af42a3354f838c939095ff99930da6aa9cdf6fe46)
set(BROTLI_HASH_TYPE SHA256)
set(BROTLI_FILE brotli-${BROTLI_VERSION}.tar.gz)
set(BROTLI_FILE brotli-v${BROTLI_VERSION}.tar.gz)
set(BROTLI_CPE "cpe:2.3:a:google:brotli:${BROTLI_VERSION}:*:*:*:*:*:*:*")
set(OPENPGL_VERSION v0.3.1-beta)
set(OPENPGL_SHORT_VERSION 0.3.1)

View File

@ -6,9 +6,11 @@ ExternalProject_Add(external_wayland
URL_HASH ${WAYLAND_HASH_TYPE}=${WAYLAND_HASH}
PREFIX ${BUILD_DIR}/wayland
PATCH_COMMAND ${PATCH_CMD} -d ${BUILD_DIR}/wayland/src/external_wayland < ${PATCH_DIR}/wayland.diff
# Use `-E` so the `PKG_CONFIG_PATH` can be defined to link against our own LIBEXPAT.
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env PKG_CONFIG_PATH=${LIBDIR}/expat/lib/pkgconfig:${LIBDIR}/xml2/lib/pkgconfig:$PKG_CONFIG_PATH
meson --prefix ${LIBDIR}/wayland -Ddocumentation=false -Dtests=false -Dlibraries=false . ../external_wayland
# Use `-E` so the `PKG_CONFIG_PATH` can be defined to link against our own LIBEXPAT & LIBXML2.
# Note that passing link args "ffi/lib" should not be needed, but
# `pkgconfig` would incorrectly look in "ffi/lib/../lib64" otherwise.
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env PKG_CONFIG_PATH=${LIBDIR}/expat/lib/pkgconfig:${LIBDIR}/xml2/lib/pkgconfig:${LIBDIR}/ffi/lib/pkgconfig:$PKG_CONFIG_PATH
meson --prefix ${LIBDIR}/wayland -Ddocumentation=false -Dtests=false -Dc_link_args=-L${LIBDIR}/ffi/lib . ../external_wayland
BUILD_COMMAND ninja
INSTALL_COMMAND ninja install
)
@ -17,4 +19,5 @@ add_dependencies(
external_wayland
external_expat
external_xml2
external_ffi
)

View File

@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# NOTE: currently only the header file is extracted, no compilation is needed
# as the library is dynamically loaded when found on the system.
ExternalProject_Add(external_wayland_libdecor
URL file://${PACKAGE_DIR}/${WAYLAND_LIBDECOR_FILE}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH ${WAYLAND_LIBDECOR_HASH_TYPE}=${WAYLAND_LIBDECOR_HASH}
PREFIX ${BUILD_DIR}/wayland_libdecor
BUILD_COMMAND echo .
CONFIGURE_COMMAND echo .
INSTALL_COMMAND cp ../external_wayland_libdecor/src/libdecor.h ${LIBDIR}/wayland_libdecor/include/libdecor-0/libdecor.h
INSTALL_DIR ${LIBDIR}/wayland_libdecor/include/libdecor-0
)

View File

@ -1,4 +1,8 @@
#!/bin/sh
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-2.0-or-later
# This script is part of the official build environment, see WIKI page for details.
# https://wiki.blender.org/wiki/Building_Blender/Other/CentOS7ReleaseEnvironment
set -e
@ -22,18 +26,50 @@ yum -y install centos-release-scl
yum -y install devtoolset-9
# Install packages needed for Blender's dependencies.
yum -y install -y \
git subversion bzip2 tar cmake3 patch make autoconf automake libtool \
meson ninja-build \
libXrandr-devel libXinerama-devel libXcursor-devel libXi-devel \
libX11-devel libXt-devel \
mesa-libEGL-devel mesa-libGL-devel mesa-libGLU-devel \
zlib-devel \
rubygem-asciidoctor \
wget tcl yasm python36 python-setuptools bison flex \
ncurses-devel \
wayland-devel libwayland-client libwayland-server \
PACKAGES=(
git
subversion
bzip2
tar
cmake3
patch
make
autoconf
automake
libtool
meson
ninja-build
libXrandr-devel
libXinerama-devel
libXcursor-devel
libXi-devel
libX11-devel libXt-devel
mesa-libEGL-devel
mesa-libGL-devel
mesa-libGLU-devel
zlib-devel
rubygem-asciidoctor
wget
tcl
yasm
python36
python-setuptools
bison
flex
ncurses-devel
wayland-devel
libwayland-client
libwayland-server
)
yum -y install -y ${PACKAGES[@]}
# Dependencies for Mesa
yum -y install expat-devel

View File

@ -62,6 +62,13 @@ FIND_LIBRARY(SYCL_LIBRARY
lib64 lib
)
if(WIN32)
string(REPLACE ".lib" "d.lib" SYCL_LIBRARY_DEBUG ${SYCL_LIBRARY})
set(SYCL_LIBRARY_DEBUG ${SYCL_LIBRARY_DEBUG} CACHE FILEPATH "Path to SYCL debug library")
else()
set(SYCL_LIBRARY_DEBUG ${SYCL_LIBRARY} CACHE FILEPATH "Path to SYCL debug library")
endif()
FIND_PATH(SYCL_INCLUDE_DIR
NAMES
CL/sycl.hpp
@ -85,4 +92,5 @@ ENDIF()
MARK_AS_ADVANCED(
_SYCL_INCLUDE_PARENT_DIR
SYCL_LIBRARY_DEBUG
)

View File

@ -699,14 +699,23 @@ endif()
if(WITH_GHOST_WAYLAND)
find_package(PkgConfig)
pkg_check_modules(wayland-client wayland-client>=1.12)
pkg_check_modules(wayland-egl wayland-egl)
pkg_check_modules(wayland-scanner wayland-scanner)
pkg_check_modules(xkbcommon xkbcommon)
pkg_check_modules(wayland-cursor wayland-cursor)
pkg_check_modules(wayland-protocols wayland-protocols>=1.15)
if(${wayland-protocols_FOUND})
# When dynamically linked WAYLAND is used and `${LIBDIR}/wayland` is present,
# there is no need to search for the libraries as they are not needed for building.
# Only the headers are needed which can reference the known paths.
if(EXISTS "${LIBDIR}/wayland" AND WITH_GHOST_WAYLAND_DYNLOAD)
set(_use_system_wayland OFF)
else()
set(_use_system_wayland ON)
endif()
if(_use_system_wayland)
pkg_check_modules(wayland-client wayland-client>=1.12)
pkg_check_modules(wayland-egl wayland-egl)
pkg_check_modules(wayland-scanner wayland-scanner)
pkg_check_modules(wayland-cursor wayland-cursor)
pkg_check_modules(wayland-protocols wayland-protocols>=1.15)
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
else()
# CentOS 7 packages have too old a version, a newer version exist in the
@ -720,6 +729,15 @@ if(WITH_GHOST_WAYLAND)
if(EXISTS ${WAYLAND_PROTOCOLS_DIR})
set(wayland-protocols_FOUND ON)
endif()
set(wayland-client_INCLUDE_DIRS "${LIBDIR}/wayland/include")
set(wayland-egl_INCLUDE_DIRS "${LIBDIR}/wayland/include")
set(wayland-cursor_INCLUDE_DIRS "${LIBDIR}/wayland/include")
set(wayland-client_FOUND ON)
set(wayland-egl_FOUND ON)
set(wayland-scanner_FOUND ON)
set(wayland-cursor_FOUND ON)
endif()
if (NOT ${wayland-client_FOUND})
@ -753,34 +771,18 @@ if(WITH_GHOST_WAYLAND)
endif()
if(WITH_GHOST_WAYLAND_LIBDECOR)
pkg_check_modules(libdecor REQUIRED libdecor-0>=0.1)
endif()
list(APPEND PLATFORM_LINKLIBS
${xkbcommon_LINK_LIBRARIES}
)
if(NOT WITH_GHOST_WAYLAND_DYNLOAD)
list(APPEND PLATFORM_LINKLIBS
${wayland-client_LINK_LIBRARIES}
${wayland-egl_LINK_LIBRARIES}
${wayland-cursor_LINK_LIBRARIES}
)
if(_use_system_wayland)
pkg_check_modules(libdecor REQUIRED libdecor-0>=0.1)
else()
set(libdecor_INCLUDE_DIRS "${LIBDIR}/wayland_libdecor/include/libdecor-0")
endif()
endif()
if(WITH_GHOST_WAYLAND_DBUS)
list(APPEND PLATFORM_LINKLIBS
${dbus_LINK_LIBRARIES}
)
add_definitions(-DWITH_GHOST_WAYLAND_DBUS)
endif()
if(WITH_GHOST_WAYLAND_LIBDECOR)
if(NOT WITH_GHOST_WAYLAND_DYNLOAD)
list(APPEND PLATFORM_LINKLIBS
${libdecor_LIBRARIES}
)
endif()
add_definitions(-DWITH_GHOST_WAYLAND_LIBDECOR)
endif()
@ -823,6 +825,8 @@ if(WITH_GHOST_WAYLAND)
# End wayland-scanner version check.
endif()
unset(_use_system_wayland)
endif()
if(WITH_GHOST_X11)
@ -831,12 +835,8 @@ if(WITH_GHOST_X11)
find_path(X11_XF86keysym_INCLUDE_PATH X11/XF86keysym.h ${X11_INC_SEARCH_PATH})
mark_as_advanced(X11_XF86keysym_INCLUDE_PATH)
list(APPEND PLATFORM_LINKLIBS ${X11_X11_LIB})
if(WITH_X11_XINPUT)
if(X11_Xinput_LIB)
list(APPEND PLATFORM_LINKLIBS ${X11_Xinput_LIB})
else()
if(NOT X11_Xinput_LIB)
message(FATAL_ERROR "LibXi not found. Disable WITH_X11_XINPUT if you
want to build without tablet support")
endif()
@ -846,18 +846,14 @@ if(WITH_GHOST_X11)
# XXX, why doesn't cmake make this available?
find_library(X11_Xxf86vmode_LIB Xxf86vm ${X11_LIB_SEARCH_PATH})
mark_as_advanced(X11_Xxf86vmode_LIB)
if(X11_Xxf86vmode_LIB)
list(APPEND PLATFORM_LINKLIBS ${X11_Xxf86vmode_LIB})
else()
if(NOT X11_Xxf86vmode_LIB)
message(FATAL_ERROR "libXxf86vm not found. Disable WITH_X11_XF86VMODE if you
want to build without")
endif()
endif()
if(WITH_X11_XFIXES)
if(X11_Xfixes_LIB)
list(APPEND PLATFORM_LINKLIBS ${X11_Xfixes_LIB})
else()
if(NOT X11_Xfixes_LIB)
message(FATAL_ERROR "libXfixes not found. Disable WITH_X11_XFIXES if you
want to build without")
endif()
@ -866,9 +862,7 @@ if(WITH_GHOST_X11)
if(WITH_X11_ALPHA)
find_library(X11_Xrender_LIB Xrender ${X11_LIB_SEARCH_PATH})
mark_as_advanced(X11_Xrender_LIB)
if(X11_Xrender_LIB)
list(APPEND PLATFORM_LINKLIBS ${X11_Xrender_LIB})
else()
if(NOT X11_Xrender_LIB)
message(FATAL_ERROR "libXrender not found. Disable WITH_X11_ALPHA if you
want to build without")
endif()

View File

@ -958,11 +958,17 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
if(EXISTS ${CYCLES_SYCL} AND NOT SYCL_ROOT_DIR)
set(SYCL_ROOT_DIR ${CYCLES_SYCL})
endif()
file(GLOB _sycl_runtime_libraries
file(GLOB _sycl_runtime_libraries_glob
${SYCL_ROOT_DIR}/bin/sycl.dll
${SYCL_ROOT_DIR}/bin/sycl[0-9].dll
${SYCL_ROOT_DIR}/bin/pi_level_zero.dll
)
foreach(sycl_runtime_library IN LISTS _sycl_runtime_libraries_glob)
string(REPLACE ".dll" "$<$<CONFIG:Debug>:d>.dll" sycl_runtime_library ${sycl_runtime_library})
list(APPEND _sycl_runtime_libraries ${sycl_runtime_library})
endforeach()
unset(_sycl_runtime_libraries_glob)
list(APPEND _sycl_runtime_libraries ${SYCL_ROOT_DIR}/bin/pi_level_zero.dll)
list(APPEND PLATFORM_BUNDLED_LIBRARIES ${_sycl_runtime_libraries})
unset(_sycl_runtime_libraries)
endif()

View File

@ -1,4 +1,4 @@
sphinx==5.1.1
sphinx==5.2.3
# Sphinx dependencies that are important
Jinja2==3.1.2
@ -6,7 +6,7 @@ Pygments==2.13.0
docutils==0.17.1
snowballstemmer==2.2.0
babel==2.10.3
requests==2.27.1
requests==2.28.1
# Only needed to match the theme used for the official documentation.
# Without this theme, the default theme will be used.

View File

@ -525,8 +525,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
use_deterministic_guiding: BoolProperty(
name="Deterministic",
description="Makes path guiding deterministic which means renderings will be"
"reproducible with the same pixel values every time. This feature slows down"
description="Makes path guiding deterministic which means renderings will be "
"reproducible with the same pixel values every time. This feature slows down "
"training",
default=True,
)
@ -562,7 +562,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="The maximum number of samples used for training path guiding. "
"Higher samples lead to more accurate guiding, however may also unnecessarily slow "
"down rendering once guiding is accurate enough. "
"A value 0 will continue training until the last sample",
"A value of 0 will continue training until the last sample",
min=0,
soft_min=1,
default=128,

View File

@ -20,7 +20,7 @@ CCL_NAMESPACE_BEGIN
* Utility class to map between Blender datablocks and Cycles data structures,
* and keep track of recalc tags from the dependency graph. */
template<typename K, typename T> class id_map {
template<typename K, typename T, typename Flags = uint> class id_map {
public:
id_map(Scene *scene_) : scene(scene_)
{
@ -63,6 +63,11 @@ template<typename K, typename T> class id_map {
b_recalc.insert(id_ptr);
}
bool check_recalc(const BL::ID &id)
{
return id.ptr.data && b_recalc.find(id.ptr.data) != b_recalc.end();
}
bool has_recalc()
{
return !(b_recalc.empty());
@ -154,6 +159,7 @@ template<typename K, typename T> class id_map {
TMapPair &pair = *jt;
if (do_delete && used_set.find(pair.second) == used_set.end()) {
flags.erase(pair.second);
scene->delete_node(pair.second);
}
else {
@ -171,9 +177,33 @@ template<typename K, typename T> class id_map {
return b_map;
}
bool test_flag(T *data, Flags val)
{
typename map<T *, uint>::iterator it = flags.find(data);
return it != flags.end() && (it->second & (1 << val)) != 0;
}
void set_flag(T *data, Flags val)
{
flags[data] |= (1 << val);
}
void clear_flag(T *data, Flags val)
{
typename map<T *, uint>::iterator it = flags.find(data);
if (it != flags.end()) {
it->second &= ~(1 << val);
if (it->second == 0) {
flags.erase(it);
}
}
}
protected:
map<K, T *> b_map;
set<T *> used_set;
map<T *, uint> flags;
set<void *> b_recalc;
Scene *scene;
};

View File

@ -96,6 +96,13 @@ bool BlenderSync::object_is_light(BL::Object &b_ob)
return (b_ob_data && b_ob_data.is_a(&RNA_Light));
}
bool BlenderSync::object_is_camera(BL::Object &b_ob)
{
BL::ID b_ob_data = b_ob.data();
return (b_ob_data && b_ob_data.is_a(&RNA_Camera));
}
void BlenderSync::sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob, Object *object)
{
/* Initialize motion blur for object, detecting if it's enabled and creating motion
@ -400,7 +407,8 @@ bool BlenderSync::sync_object_attributes(BL::DepsgraphObjectInstance &b_instance
std::string real_name;
BlenderAttributeType type = blender_attribute_name_split_type(name, &real_name);
if (type != BL::ShaderNodeAttribute::attribute_type_GEOMETRY) {
if (type == BL::ShaderNodeAttribute::attribute_type_OBJECT ||
type == BL::ShaderNodeAttribute::attribute_type_INSTANCER) {
bool use_instancer = (type == BL::ShaderNodeAttribute::attribute_type_INSTANCER);
float4 value = lookup_instance_property(b_instance, real_name, use_instancer);

View File

@ -194,7 +194,7 @@ static void export_pointcloud(Scene *scene,
/* Export points. */
for (int i = 0; i < num_points; i++) {
const float3 co = get_float3(b_attr_position.data[i].vector());
const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.0f;
const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.01f;
pointcloud->add_point(co, radius);
/* Random number per point. */

View File

@ -22,6 +22,8 @@
#include "util/string.h"
#include "util/task.h"
#include "BKE_duplilist.h"
CCL_NAMESPACE_BEGIN
typedef map<void *, ShaderInput *> PtrInputMap;
@ -103,6 +105,7 @@ static ImageAlphaType get_image_alpha_type(BL::Image &b_image)
static const string_view object_attr_prefix("\x01object:");
static const string_view instancer_attr_prefix("\x01instancer:");
static const string_view view_layer_attr_prefix("\x01layer:");
static ustring blender_attribute_name_add_type(const string &name, BlenderAttributeType type)
{
@ -111,6 +114,8 @@ static ustring blender_attribute_name_add_type(const string &name, BlenderAttrib
return ustring::concat(object_attr_prefix, name);
case BL::ShaderNodeAttribute::attribute_type_INSTANCER:
return ustring::concat(instancer_attr_prefix, name);
case BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER:
return ustring::concat(view_layer_attr_prefix, name);
default:
return ustring(name);
}
@ -130,6 +135,11 @@ BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_r
return BL::ShaderNodeAttribute::attribute_type_INSTANCER;
}
if (sname.substr(0, view_layer_attr_prefix.size()) == view_layer_attr_prefix) {
*r_real_name = sname.substr(view_layer_attr_prefix.size());
return BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER;
}
return BL::ShaderNodeAttribute::attribute_type_GEOMETRY;
}
@ -205,7 +215,9 @@ static void set_default_value(ShaderInput *input,
}
case SocketType::INT: {
if (b_sock.type() == BL::NodeSocket::type_BOOLEAN) {
node->set(socket, get_boolean(b_sock.ptr, "default_value"));
/* Make sure to call the int overload of set() since this is an integer socket as far as
* Cycles is concerned. */
node->set(socket, get_boolean(b_sock.ptr, "default_value") ? 1 : 0);
}
else {
node->set(socket, get_int(b_sock.ptr, "default_value"));
@ -1420,6 +1432,89 @@ static void add_nodes(Scene *scene,
empty_proxy_map);
}
/* Look up and constant fold all references to View Layer attributes. */
void BlenderSync::resolve_view_layer_attributes(Shader *shader,
ShaderGraph *graph,
BL::Depsgraph &b_depsgraph)
{
bool updated = false;
foreach (ShaderNode *node, graph->nodes) {
if (node->is_a(AttributeNode::node_type)) {
AttributeNode *attr_node = static_cast<AttributeNode *>(node);
std::string real_name;
BlenderAttributeType type = blender_attribute_name_split_type(attr_node->get_attribute(),
&real_name);
if (type == BL::ShaderNodeAttribute::attribute_type_VIEW_LAYER) {
/* Look up the value. */
BL::ViewLayer b_layer = b_depsgraph.view_layer_eval();
BL::Scene b_scene = b_depsgraph.scene_eval();
float4 value;
BKE_view_layer_find_rgba_attribute((::Scene *)b_scene.ptr.data,
(::ViewLayer *)b_layer.ptr.data,
real_name.c_str(),
&value.x);
/* Replace all outgoing links, using appropriate output types. */
float val_avg = (value.x + value.y + value.z) / 3.0f;
foreach (ShaderOutput *output, node->outputs) {
float val_float;
float3 val_float3;
if (output->type() == SocketType::FLOAT) {
val_float = (output->name() == "Alpha") ? value.w : val_avg;
val_float3 = make_float3(val_float);
}
else {
val_float = val_avg;
val_float3 = float4_to_float3(value);
}
foreach (ShaderInput *sock, output->links) {
if (sock->type() == SocketType::FLOAT) {
sock->set(val_float);
}
else if (SocketType::is_float3(sock->type())) {
sock->set(val_float3);
}
sock->constant_folded_in = true;
}
graph->disconnect(output);
}
/* Clear the attribute name to avoid further attempts to look up. */
attr_node->set_attribute(ustring());
updated = true;
}
}
}
if (updated) {
shader_map.set_flag(shader, SHADER_WITH_LAYER_ATTRS);
}
else {
shader_map.clear_flag(shader, SHADER_WITH_LAYER_ATTRS);
}
}
bool BlenderSync::scene_attr_needs_recalc(Shader *shader, BL::Depsgraph &b_depsgraph)
{
if (shader && shader_map.test_flag(shader, SHADER_WITH_LAYER_ATTRS)) {
BL::Scene scene = b_depsgraph.scene_eval();
return shader_map.check_recalc(scene) || shader_map.check_recalc(scene.world()) ||
shader_map.check_recalc(scene.camera());
}
return false;
}
/* Sync Materials */
void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
@ -1438,7 +1533,8 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
Shader *shader;
/* test if we need to sync */
if (shader_map.add_or_update(&shader, b_mat) || update_all) {
if (shader_map.add_or_update(&shader, b_mat) || update_all ||
scene_attr_needs_recalc(shader, b_depsgraph)) {
ShaderGraph *graph = new ShaderGraph();
shader->name = b_mat.name().c_str();
@ -1459,6 +1555,8 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
graph->connect(diffuse->output("BSDF"), out->input("Surface"));
}
resolve_view_layer_attributes(shader, graph, b_depsgraph);
/* settings */
PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles");
shader->set_use_mis(get_boolean(cmat, "sample_as_light"));
@ -1515,9 +1613,11 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
BlenderViewportParameters new_viewport_parameters(b_v3d, use_developer_ui);
Shader *shader = scene->default_background;
if (world_recalc || update_all || b_world.ptr.data != world_map ||
viewport_parameters.shader_modified(new_viewport_parameters)) {
Shader *shader = scene->default_background;
viewport_parameters.shader_modified(new_viewport_parameters) ||
scene_attr_needs_recalc(shader, b_depsgraph)) {
ShaderGraph *graph = new ShaderGraph();
/* create nodes */
@ -1615,6 +1715,8 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
background->set_visibility(visibility);
}
resolve_view_layer_attributes(shader, graph, b_depsgraph);
shader->set_graph(graph);
shader->tag_update(scene);
}
@ -1681,7 +1783,8 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
Shader *shader;
/* test if we need to sync */
if (shader_map.add_or_update(&shader, b_light) || update_all) {
if (shader_map.add_or_update(&shader, b_light) || update_all ||
scene_attr_needs_recalc(shader, b_depsgraph)) {
ShaderGraph *graph = new ShaderGraph();
/* create nodes */
@ -1702,6 +1805,8 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
graph->connect(emission->output("Emission"), out->input("Surface"));
}
resolve_view_layer_attributes(shader, graph, b_depsgraph);
shader->set_graph(graph);
shader->tag_update(scene);
}

View File

@ -206,6 +206,9 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
}
}
}
else if (object_is_camera(b_ob)) {
shader_map.set_recalc(b_ob);
}
}
/* Mesh */
else if (b_id.is_a(&RNA_Mesh)) {
@ -218,6 +221,11 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
if (world_map == b_world.ptr.data) {
world_recalc = true;
}
shader_map.set_recalc(b_world);
}
/* World */
else if (b_id.is_a(&RNA_Scene)) {
shader_map.set_recalc(b_id);
}
/* Volume */
else if (b_id.is_a(&RNA_Volume)) {

View File

@ -120,6 +120,11 @@ class BlenderSync {
void sync_shaders(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all);
void sync_nodes(Shader *shader, BL::ShaderNodeTree &b_ntree);
bool scene_attr_needs_recalc(Shader *shader, BL::Depsgraph &b_depsgraph);
void resolve_view_layer_attributes(Shader *shader,
ShaderGraph *graph,
BL::Depsgraph &b_depsgraph);
/* Object */
Object *sync_object(BL::Depsgraph &b_depsgraph,
BL::ViewLayer &b_view_layer,
@ -207,13 +212,16 @@ class BlenderSync {
bool object_is_geometry(BObjectInfo &b_ob_info);
bool object_can_have_geometry(BL::Object &b_ob);
bool object_is_light(BL::Object &b_ob);
bool object_is_camera(BL::Object &b_ob);
/* variables */
BL::RenderEngine b_engine;
BL::BlendData b_data;
BL::Scene b_scene;
id_map<void *, Shader> shader_map;
enum ShaderFlags { SHADER_WITH_LAYER_ATTRS };
id_map<void *, Shader, ShaderFlags> shader_map;
id_map<ObjectKey, Object> object_map;
id_map<void *, Procedural> procedural_map;
id_map<GeometryKey, Geometry> geometry_map;

View File

@ -193,8 +193,11 @@ if (WITH_CYCLES_DEVICE_ONEAPI)
set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/../kernel/libcycles_kernel_oneapi.so)
endif()
list(APPEND LIB
${SYCL_LIBRARY}
${cycles_kernel_oneapi_lib}
"$<$<CONFIG:Debug>:${SYCL_LIBRARY_DEBUG}>"
"$<$<CONFIG:Release>:${SYCL_LIBRARY}>"
"$<$<CONFIG:RelWithDebInfo>:${SYCL_LIBRARY}>"
"$<$<CONFIG:MinSizeRel>:${SYCL_LIBRARY}>"
)
add_definitions(-DWITH_ONEAPI)
list(APPEND SRC

View File

@ -254,6 +254,10 @@ void MetalDevice::make_source(MetalPipelineType pso_type, const uint kernel_feat
break;
}
NSProcessInfo *processInfo = [NSProcessInfo processInfo];
NSOperatingSystemVersion macos_ver = [processInfo operatingSystemVersion];
global_defines += "#define __KERNEL_METAL_MACOS__ " + to_string(macos_ver.majorVersion) + "\n";
string &source = this->source[pso_type];
source = "\n#include \"kernel/device/metal/kernel.metal\"\n";
source = path_source_replace_includes(source, path_get("source"));

View File

@ -43,7 +43,7 @@ OneapiDevice::OneapiDevice(const DeviceInfo &info, Stats &stats, Profiler &profi
}
size_t globals_segment_size;
is_finished_ok = kernel_globals_size(device_queue_, globals_segment_size);
is_finished_ok = kernel_globals_size(globals_segment_size);
if (is_finished_ok == false) {
set_error("oneAPI constant memory initialization got runtime exception \"" +
oneapi_error_string_ + "\"");
@ -88,18 +88,26 @@ BVHLayoutMask OneapiDevice::get_bvh_layout_mask() const
bool OneapiDevice::load_kernels(const uint requested_features)
{
assert(device_queue_);
/* NOTE(@nsirgien): oneAPI can support compilation of kernel code with certain feature set
* with specialization constants, but it hasn't been implemented yet. */
(void)requested_features;
bool is_finished_ok = oneapi_run_test_kernel(device_queue_);
if (is_finished_ok == false) {
set_error("oneAPI kernel load: got runtime exception \"" + oneapi_error_string_ + "\"");
set_error("oneAPI test kernel execution: got a runtime exception \"" + oneapi_error_string_ +
"\"");
return false;
}
else {
VLOG_INFO << "Runtime compilation done for \"" << info.description << "\"";
VLOG_INFO << "Test kernel has been executed successfully for \"" << info.description << "\"";
assert(device_queue_);
}
is_finished_ok = oneapi_load_kernels(device_queue_, (const unsigned int)requested_features);
if (is_finished_ok == false) {
set_error("oneAPI kernels loading: got a runtime exception \"" + oneapi_error_string_ + "\"");
}
else {
VLOG_INFO << "Kernels loading (compilation) has been done for \"" << info.description << "\"";
}
return is_finished_ok;
}
@ -425,6 +433,11 @@ void OneapiDevice::check_usm(SyclQueue *queue_, const void *usm_ptr, bool allow_
((device_type == sycl::info::device_type::host ||
device_type == sycl::info::device_type::cpu || allow_host) &&
usm_type == sycl::usm::alloc::host));
# else
/* Silence warning about unused arguments. */
(void)queue_;
(void)usm_ptr;
(void)allow_host;
# endif
}
@ -552,7 +565,7 @@ bool OneapiDevice::queue_synchronize(SyclQueue *queue_)
}
}
bool OneapiDevice::kernel_globals_size(SyclQueue *queue_, size_t &kernel_global_size)
bool OneapiDevice::kernel_globals_size(size_t &kernel_global_size)
{
kernel_global_size = sizeof(KernelGlobalsGPU);

View File

@ -104,7 +104,7 @@ class OneapiDevice : public Device {
int get_num_multiprocessors();
int get_max_num_threads_per_multiprocessor();
bool queue_synchronize(SyclQueue *queue);
bool kernel_globals_size(SyclQueue *queue, size_t &kernel_global_size);
bool kernel_globals_size(size_t &kernel_global_size);
void set_global_memory(SyclQueue *queue,
void *kernel_globals,
const char *memory_name,

View File

@ -43,8 +43,11 @@ PathTrace::PathTrace(Device *device,
/* Create path tracing work in advance, so that it can be reused by incremental sampling as much
* as possible. */
device_->foreach_device([&](Device *path_trace_device) {
path_trace_works_.emplace_back(PathTraceWork::create(
path_trace_device, film, device_scene, &render_cancel_.is_requested));
unique_ptr<PathTraceWork> work = PathTraceWork::create(
path_trace_device, film, device_scene, &render_cancel_.is_requested);
if (work) {
path_trace_works_.emplace_back(std::move(work));
}
});
work_balance_infos_.resize(path_trace_works_.size());

View File

@ -23,6 +23,10 @@ unique_ptr<PathTraceWork> PathTraceWork::create(Device *device,
if (device->info.type == DEVICE_CPU) {
return make_unique<PathTraceWorkCPU>(device, film, device_scene, cancel_requested_flag);
}
if (device->info.type == DEVICE_DUMMY) {
/* Dummy devices can't perform any work. */
return nullptr;
}
return make_unique<PathTraceWorkGPU>(device, film, device_scene, cancel_requested_flag);
}

View File

@ -285,7 +285,7 @@ void PathTraceWorkCPU::cryptomatte_postproces()
}
#ifdef WITH_PATH_GUIDING
/* Note: It seems that this is called before every rendering iteration/progression and not once per
/* NOTE: It seems that this is called before every rendering iteration/progression and not once per
* rendering. May be we find a way to call it only once per rendering. */
void PathTraceWorkCPU::guiding_init_kernel_globals(void *guiding_field,
void *sample_data_storage,

View File

@ -17,6 +17,9 @@ void work_balance_do_initial(vector<WorkBalanceInfo> &work_balance_infos)
work_balance_infos[0].weight = 1.0;
return;
}
else if (num_infos == 0) {
return;
}
/* There is no statistics available, so start with an equal distribution. */
const double weight = 1.0 / num_infos;

View File

@ -727,16 +727,9 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
${SRC_UTIL_HEADERS}
)
set (ONEAPI_OFFLINE_COMPILER_PARALLEL_JOBS 1)
set (SYCL_OFFLINE_COMPILER_PARALLEL_JOBS 1 CACHE STRING "Number of parallel compiler instances to use for device binaries compilation (expect ~8GB peak memory usage per instance).")
if (WITH_CYCLES_ONEAPI_BINARIES)
cmake_host_system_information(RESULT AVAILABLE_MEMORY_AMOUNT QUERY AVAILABLE_PHYSICAL_MEMORY)
# Conservative value of peak consumption here, just to be fully sure that other backend compilers will have enough memory as well
set(ONEAPI_GPU_COMPILER_MEMORY_AT_PEAK_MB 8150)
math(EXPR ONEAPI_OFFLINE_COMPILER_PARALLEL_JOBS "${AVAILABLE_MEMORY_AMOUNT} / ${ONEAPI_GPU_COMPILER_MEMORY_AT_PEAK_MB}")
if (ONEAPI_OFFLINE_COMPILER_PARALLEL_JOBS LESS 1)
set(ONEAPI_OFFLINE_COMPILER_PARALLEL_JOBS 1)
endif()
message(STATUS "${ONEAPI_OFFLINE_COMPILER_PARALLEL_JOBS} instance(s) of oneAPI offline compiler will be used.")
message(STATUS "${SYCL_OFFLINE_COMPILER_PARALLEL_JOBS} instance(s) of oneAPI offline compiler will be used.")
endif()
# SYCL_CPP_FLAGS is a variable that the user can set to pass extra compiler options
set(sycl_compiler_flags
@ -747,7 +740,7 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
-mllvm -inlinedefault-threshold=250
-mllvm -inlinehint-threshold=350
-fsycl-device-code-split=per_kernel
-fsycl-max-parallel-link-jobs=${ONEAPI_OFFLINE_COMPILER_PARALLEL_JOBS}
-fsycl-max-parallel-link-jobs=${SYCL_OFFLINE_COMPILER_PARALLEL_JOBS}
-shared
-DWITH_ONEAPI
-ffast-math
@ -758,7 +751,6 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
${SYCL_CPP_FLAGS}
)
if (WITH_CYCLES_ONEAPI_SYCL_HOST_ENABLED)
list(APPEND sycl_compiler_flags -DWITH_ONEAPI_SYCL_HOST_ENABLED)
endif()
@ -826,36 +818,43 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
-D_CRT_SECURE_NO_DEPRECATE
-DONEAPI_EXPORT)
if(sycl_compiler_compiler_name MATCHES "dpcpp")
# The oneAPI distribution calls the compiler "dpcpp" and comes with a script that sets environment variables.
add_custom_command(
OUTPUT ${cycles_kernel_oneapi_lib}
COMMAND "${sycl_compiler_root}/../../env/vars.bat"
COMMAND ${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
DEPENDS ${cycles_oneapi_kernel_sources})
string(REPLACE /Redist/ /Tools/ MSVC_TOOLS_DIR ${MSVC_REDIST_DIR})
if(NOT CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION) # case for Ninja on Windows
get_filename_component(cmake_mt_dir ${CMAKE_MT} DIRECTORY)
string(REPLACE /bin/ /Lib/ WINDOWS_KIT_DIR ${cmake_mt_dir})
get_filename_component(WINDOWS_KIT_DIR "${WINDOWS_KIT_DIR}/../" ABSOLUTE)
else()
# The open source SYCL compiler just goes by clang++ and does not have such a script.
# Set the variables manually.
string(REPLACE /Redist/ /Tools/ MSVC_TOOLS_DIR ${MSVC_REDIST_DIR})
if(NOT CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION) # case for Ninja on Windows
get_filename_component(cmake_mt_dir ${CMAKE_MT} DIRECTORY)
string(REPLACE /bin/ /Lib/ WINDOWS_KIT_DIR ${cmake_mt_dir})
get_filename_component(WINDOWS_KIT_DIR "${WINDOWS_KIT_DIR}/../" ABSOLUTE)
else()
set(WINDOWS_KIT_DIR ${WINDOWS_KITS_DIR}/Lib/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION})
endif()
list(APPEND sycl_compiler_flags
-L "${MSVC_TOOLS_DIR}/lib/x64"
-L "${WINDOWS_KIT_DIR}/um/x64"
-L "${WINDOWS_KIT_DIR}/ucrt/x64")
add_custom_command(
OUTPUT ${cycles_kernel_oneapi_lib}
COMMAND ${CMAKE_COMMAND} -E env
"LIB=${sycl_compiler_root}/../lib" # for compiler to find sycl.lib
"PATH=${OCLOC_INSTALL_DIR};${sycl_compiler_root}"
${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
DEPENDS ${cycles_oneapi_kernel_sources})
set(WINDOWS_KIT_DIR ${WINDOWS_KITS_DIR}/Lib/${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION})
endif()
list(APPEND sycl_compiler_flags
-L "${MSVC_TOOLS_DIR}/lib/x64"
-L "${WINDOWS_KIT_DIR}/um/x64"
-L "${WINDOWS_KIT_DIR}/ucrt/x64")
set(sycl_compiler_flags_Release ${sycl_compiler_flags})
set(sycl_compiler_flags_Debug ${sycl_compiler_flags})
set(sycl_compiler_flags_RelWithDebInfo ${sycl_compiler_flags})
set(sycl_compiler_flags_MinSizeRel ${sycl_compiler_flags})
list(APPEND sycl_compiler_flags_RelWithDebInfo -g)
get_filename_component(sycl_library_debug_name ${SYCL_LIBRARY_DEBUG} NAME_WE)
list(APPEND sycl_compiler_flags_Debug
-g
-D_DEBUG
-nostdlib -Xclang --dependent-lib=msvcrtd
-Xclang --dependent-lib=${sycl_library_debug_name})
add_custom_command(
OUTPUT ${cycles_kernel_oneapi_lib}
COMMAND ${CMAKE_COMMAND} -E env
"LIB=${sycl_compiler_root}/../lib" # for compiler to find sycl.lib
"PATH=${OCLOC_INSTALL_DIR}\;${sycl_compiler_root}"
${SYCL_COMPILER}
"$<$<CONFIG:Release>:${sycl_compiler_flags_Release}>"
"$<$<CONFIG:RelWithDebInfo>:${sycl_compiler_flags_RelWithDebInfo}>"
"$<$<CONFIG:Debug>:${sycl_compiler_flags_Debug}>"
"$<$<CONFIG:MinSizeRel>:${sycl_compiler_flags_Release}>"
COMMAND_EXPAND_LISTS
DEPENDS ${cycles_oneapi_kernel_sources})
else()
list(APPEND sycl_compiler_flags -fPIC)
@ -867,26 +866,16 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
# libpi_level_zero.so can be placed next to it and get found.
list(APPEND sycl_compiler_flags -Wl,-rpath,'$$ORIGIN')
# The oneAPI distribution calls the compiler "dpcpp" and comes with a script that sets environment variables.
if(sycl_compiler_compiler_name MATCHES "dpcpp")
add_custom_command(
OUTPUT ${cycles_kernel_oneapi_lib}
COMMAND bash -c \"source ${sycl_compiler_root}/../../env/vars.sh&&${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}\"
DEPENDS ${cycles_oneapi_kernel_sources})
else()
# The open source SYCL compiler just goes by clang++ and does not have such a script.
# Set the variables manually.
if(NOT IGC_INSTALL_DIR)
get_filename_component(IGC_INSTALL_DIR "${sycl_compiler_root}/../lib/igc" ABSOLUTE)
endif()
add_custom_command(
OUTPUT ${cycles_kernel_oneapi_lib}
COMMAND ${CMAKE_COMMAND} -E env
"LD_LIBRARY_PATH=${sycl_compiler_root}/../lib:${OCLOC_INSTALL_DIR}/lib:${IGC_INSTALL_DIR}/lib"
"PATH=${OCLOC_INSTALL_DIR}/bin:${sycl_compiler_root}:$ENV{PATH}" # env PATH is for compiler to find ld
${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
DEPENDS ${cycles_oneapi_kernel_sources})
if(NOT IGC_INSTALL_DIR)
get_filename_component(IGC_INSTALL_DIR "${sycl_compiler_root}/../lib/igc" ABSOLUTE)
endif()
add_custom_command(
OUTPUT ${cycles_kernel_oneapi_lib}
COMMAND ${CMAKE_COMMAND} -E env
"LD_LIBRARY_PATH=${sycl_compiler_root}/../lib:${OCLOC_INSTALL_DIR}/lib:${IGC_INSTALL_DIR}/lib"
"PATH=${OCLOC_INSTALL_DIR}/bin:${sycl_compiler_root}:$ENV{PATH}" # env PATH is for compiler to find ld
${SYCL_COMPILER} $<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g> ${sycl_compiler_flags}
DEPENDS ${cycles_oneapi_kernel_sources})
endif()
if(NOT WITH_BLENDER)

View File

@ -123,6 +123,52 @@ size_t oneapi_kernel_preferred_local_size(SyclQueue *queue,
return std::min(limit_work_group_size, preferred_work_group_size);
}
bool oneapi_load_kernels(SyclQueue *queue_, const uint requested_features)
{
assert(queue_);
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
try {
sycl::kernel_bundle<sycl::bundle_state::input> all_kernels_bundle =
sycl::get_kernel_bundle<sycl::bundle_state::input>(queue->get_context(),
{queue->get_device()});
for (const sycl::kernel_id &kernel_id : all_kernels_bundle.get_kernel_ids()) {
const std::string &kernel_name = kernel_id.get_name();
/* NOTE(@nsirgien): Names in this conditions below should match names from
* oneapi_call macro in oneapi_enqueue_kernel below */
if (((requested_features & KERNEL_FEATURE_VOLUME) == 0) &&
kernel_name.find("oneapi_kernel_integrator_shade_volume") != std::string::npos) {
continue;
}
if (((requested_features & KERNEL_FEATURE_MNEE) == 0) &&
kernel_name.find("oneapi_kernel_integrator_shade_surface_mnee") != std::string::npos) {
continue;
}
if (((requested_features & KERNEL_FEATURE_NODE_RAYTRACE) == 0) &&
kernel_name.find("oneapi_kernel_integrator_shade_surface_raytrace") !=
std::string::npos) {
continue;
}
sycl::kernel_bundle<sycl::bundle_state::input> one_kernel_bundle =
sycl::get_kernel_bundle<sycl::bundle_state::input>(queue->get_context(), {kernel_id});
sycl::build(one_kernel_bundle, {queue->get_device()}, sycl::property::queue::in_order());
}
}
catch (sycl::exception const &e) {
if (s_error_cb) {
s_error_cb(e.what(), s_error_user_ptr);
}
return false;
}
return true;
}
bool oneapi_enqueue_kernel(KernelContext *kernel_context,
int kernel,
size_t global_size,

View File

@ -48,6 +48,8 @@ CYCLES_KERNEL_ONEAPI_EXPORT bool oneapi_enqueue_kernel(KernelContext *context,
int kernel,
size_t global_size,
void **args);
CYCLES_KERNEL_ONEAPI_EXPORT bool oneapi_load_kernels(SyclQueue *queue,
const unsigned int requested_features);
# ifdef __cplusplus
}
# endif

View File

@ -279,7 +279,15 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg,
}
/* Compute constraint derivatives. */
ccl_device_forceinline bool mnee_compute_constraint_derivatives(
# if defined(__KERNEL_METAL__)
/* Temporary workaround for front-end compilation bug (incorrect MNEE rendering when this is
* inlined). */
__attribute__((noinline))
# else
ccl_device_forceinline
# endif
bool mnee_compute_constraint_derivatives(
int vertex_count,
ccl_private ManifoldVertex *vertices,
ccl_private const float3 &surface_sample_pos,

View File

@ -100,7 +100,7 @@ ccl_device_inline bool sample_is_class_A(int pattern, int sample)
if (!(pattern == SAMPLING_PATTERN_PMJ || pattern == SAMPLING_PATTERN_SOBOL_BURLEY)) {
/* Fallback: assign samples randomly.
* This is guaranteed to work "okay" for any sampler, but isn't good.
* (Note: the seed constant is just a random number to guard against
* (NOTE: the seed constant is just a random number to guard against
* possible interactions with other uses of the hash. There's nothing
* special about it.)
*/

View File

@ -85,9 +85,9 @@ CCL_NAMESPACE_BEGIN
# define __VOLUME_RECORD_ALL__
#endif /* !__KERNEL_GPU__ */
/* MNEE currently causes "Compute function exceeds available temporary registers"
* on Metal, disabled for now. */
#ifndef __KERNEL_METAL__
/* MNEE caused "Compute function exceeds available temporary registers" in macOS < 13 due to a bug
* in spill buffer allocation sizing. */
#if !defined(__KERNEL_METAL__) || (__KERNEL_METAL_MACOS__ >= 13)
# define __MNEE__
#endif

View File

@ -43,6 +43,10 @@ Session::Session(const SessionParams &params_, const SceneParams &scene_params)
device = Device::create(params.device, stats, profiler);
if (device->have_error()) {
progress.set_error(device->error_message());
}
scene = new Scene(scene_params, device);
/* Configure path tracer. */

View File

@ -262,6 +262,9 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
${xkbcommon_INCLUDE_DIRS}
${wayland-cursor_INCLUDE_DIRS}
)
list(APPEND LIB
${xkbcommon_LINK_LIBRARIES}
)
if(WITH_GHOST_WAYLAND_DYNLOAD)
list(APPEND INC_SYS
@ -271,18 +274,32 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
bf_intern_wayland_dynload
)
add_definitions(-DWITH_GHOST_WAYLAND_DYNLOAD)
else()
list(APPEND LIB
${wayland-client_LINK_LIBRARIES}
${wayland-egl_LINK_LIBRARIES}
${wayland-cursor_LINK_LIBRARIES}
)
endif()
if(WITH_GHOST_WAYLAND_DBUS)
list(APPEND INC_SYS
${dbus_INCLUDE_DIRS}
)
list(APPEND LIB
${dbus_LINK_LIBRARIES}
)
endif()
if(WITH_GHOST_WAYLAND_LIBDECOR)
list(APPEND INC_SYS
${libdecor_INCLUDE_DIRS}
)
if(NOT WITH_GHOST_WAYLAND_DYNLOAD)
list(APPEND LIB
${libdecor_LIBRARIES}
)
endif()
endif()
include(CheckSymbolExists)
@ -332,16 +349,16 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
${INC_DST}
)
if(NOT WITH_GHOST_WAYLAND_LIBDECOR)
# `xdg-shell`.
generate_protocol_bindings(
"${WAYLAND_PROTOCOLS_DIR}/stable/xdg-shell/xdg-shell.xml"
)
# `xdg-decoration`.
generate_protocol_bindings(
"${WAYLAND_PROTOCOLS_DIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
)
endif()
# Used when: LIBDECOR is not needed.
# `xdg-shell`.
generate_protocol_bindings(
"${WAYLAND_PROTOCOLS_DIR}/stable/xdg-shell/xdg-shell.xml"
)
# `xdg-decoration`.
generate_protocol_bindings(
"${WAYLAND_PROTOCOLS_DIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
)
# End LIBDECOR alternative.
# `xdg-output`.
generate_protocol_bindings(

View File

@ -36,6 +36,10 @@ extern GHOST_SystemHandle GHOST_CreateSystemBackground(void);
*/
extern void GHOST_SystemInitDebug(GHOST_SystemHandle systemhandle, GHOST_Debug debug);
#if !(defined(WIN32) || defined(__APPLE__))
extern const char *GHOST_SystemBackend(void);
#endif
/**
* Disposes the one and only system.
* \param systemhandle: The handle to the system.

View File

@ -134,6 +134,15 @@ class GHOST_ISystem {
* \return A pointer to the system.
*/
static GHOST_ISystem *getSystem();
/**
* Return an identifier for the one and only system.
* \warning while it may be tempting this should never be used to check for supported features,
* in that case, the GHOST API should be extended to query capabilities.
* This is needed for X11/WAYLAND on Unix, without this - there is no convenient way for users to
* check if WAYLAND or XWAYLAND are in use since they are dynamically selected at startup.
* When dynamically switching between X11/WAYLAND is removed, this function can go too.
*/
static const char *getSystemBackend();
static GHOST_TBacktraceFn getBacktraceFn();
static void setBacktraceFn(GHOST_TBacktraceFn backtrace_fn);
@ -515,6 +524,7 @@ class GHOST_ISystem {
/** The one and only system */
static GHOST_ISystem *m_system;
static const char *m_system_backend_id;
/** Function to call that sets the back-trace. */
static GHOST_TBacktraceFn m_backtrace_fn;

View File

@ -52,6 +52,13 @@ GHOST_TSuccess GHOST_DisposeSystem(GHOST_SystemHandle systemhandle)
return system->disposeSystem();
}
#if !(defined(WIN32) || defined(__APPLE__))
const char *GHOST_SystemBackend()
{
return GHOST_ISystem::getSystemBackend();
}
#endif
void GHOST_ShowMessageBox(GHOST_SystemHandle systemhandle,
const char *title,
const char *message,

View File

@ -306,7 +306,7 @@ GHOST_TSuccess GHOST_ContextGLX::releaseNativeHandles()
GHOST_TSuccess GHOST_ContextGLX::setSwapInterval(int interval)
{
if (!epoxy_has_glx_extension(m_display, DefaultScreen(m_display), "GLX_EXT_swap_control")) {
if (epoxy_has_glx_extension(m_display, DefaultScreen(m_display), "GLX_EXT_swap_control")) {
::glXSwapIntervalEXT(m_display, m_window, interval);
return GHOST_kSuccess;
}

View File

@ -30,6 +30,7 @@
#endif
GHOST_ISystem *GHOST_ISystem::m_system = nullptr;
const char *GHOST_ISystem::m_system_backend_id = nullptr;
GHOST_TBacktraceFn GHOST_ISystem::m_backtrace_fn = nullptr;
@ -47,7 +48,7 @@ GHOST_TSuccess GHOST_ISystem::createSystem(bool verbose)
/* Pass. */
#elif defined(WITH_GHOST_WAYLAND)
# if defined(WITH_GHOST_WAYLAND_DYNLOAD)
const bool has_wayland_libraries = ghost_wl_dynload_libraries();
const bool has_wayland_libraries = ghost_wl_dynload_libraries_init();
# else
const bool has_wayland_libraries = true;
# endif
@ -65,6 +66,9 @@ GHOST_TSuccess GHOST_ISystem::createSystem(bool verbose)
catch (const std::runtime_error &) {
delete m_system;
m_system = nullptr;
# ifdef WITH_GHOST_WAYLAND_DYNLOAD
ghost_wl_dynload_libraries_exit();
# endif
}
}
else {
@ -100,6 +104,9 @@ GHOST_TSuccess GHOST_ISystem::createSystem(bool verbose)
catch (const std::runtime_error &) {
delete m_system;
m_system = nullptr;
# ifdef WITH_GHOST_WAYLAND_DYNLOAD
ghost_wl_dynload_libraries_exit();
# endif
}
}
else {
@ -122,7 +129,10 @@ GHOST_TSuccess GHOST_ISystem::createSystem(bool verbose)
m_system = new GHOST_SystemCocoa();
#endif
if ((m_system == nullptr) && verbose) {
if (m_system) {
m_system_backend_id = backends_attempted[backends_attempted_num - 1];
}
else if (verbose) {
fprintf(stderr, "GHOST: failed to initialize display for back-end(s): [");
for (int i = 0; i < backends_attempted_num; i++) {
if (i != 0) {
@ -186,6 +196,11 @@ GHOST_ISystem *GHOST_ISystem::getSystem()
return m_system;
}
const char *GHOST_ISystem::getSystemBackend()
{
return m_system_backend_id;
}
GHOST_TBacktraceFn GHOST_ISystem::getBacktraceFn()
{
return GHOST_ISystem::m_backtrace_fn;

View File

@ -54,6 +54,11 @@
#include <tablet-unstable-v2-client-protocol.h>
#include <xdg-output-unstable-v1-client-protocol.h>
/* Decorations `xdg_decor`. */
#include <xdg-decoration-unstable-v1-client-protocol.h>
#include <xdg-shell-client-protocol.h>
/* End `xdg_decor`. */
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
@ -64,6 +69,15 @@
/* Logging, use `ghost.wl.*` prefix. */
#include "CLG_log.h"
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
static bool use_libdecor = true;
# ifdef WITH_GHOST_WAYLAND_DYNLOAD
static bool has_libdecor = false;
# else
static bool has_libdecor = true;
# endif
#endif
static void keyboard_handle_key_repeat_cancel(struct GWL_Seat *seat);
static void output_handle_done(void *data, struct wl_output *wl_output);
@ -106,6 +120,15 @@ static bool use_gnome_confine_hack = false;
*/
#define USE_GNOME_KEYBOARD_SUPPRESS_WARNING
/**
* When GNOME is found, require `libdecor`.
* This is a hack because it seems there is no way to check if the compositor supports
* server side decorations when initializing WAYLAND.
*/
#if defined(WITH_GHOST_WAYLAND_LIBDECOR) && defined(WITH_GHOST_X11)
# define USE_GNOME_NEEDS_LIBDECOR_HACK
#endif
/** \} */
/* -------------------------------------------------------------------- */
@ -357,6 +380,36 @@ struct WGL_KeyboardDepressedState {
int16_t mods[GHOST_KEY_MODIFIER_NUM] = {0};
};
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
struct WGL_LibDecor_System {
struct libdecor *context = nullptr;
};
static void wgl_libdecor_system_destroy(WGL_LibDecor_System *decor)
{
if (decor->context) {
libdecor_unref(decor->context);
}
delete decor;
}
#endif
struct WGL_XDG_Decor_System {
struct xdg_wm_base *shell = nullptr;
struct zxdg_decoration_manager_v1 *manager = nullptr;
};
static void wgl_xdg_decor_system_destroy(WGL_XDG_Decor_System *decor)
{
if (decor->manager) {
zxdg_decoration_manager_v1_destroy(decor->manager);
}
if (decor->shell) {
xdg_wm_base_destroy(decor->shell);
}
delete decor;
}
struct GWL_Seat {
GHOST_SystemWayland *system = nullptr;
@ -455,11 +508,10 @@ struct GWL_Display {
struct wl_compositor *compositor = nullptr;
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
struct libdecor *decor_context = nullptr;
#else
struct xdg_wm_base *xdg_shell = nullptr;
struct zxdg_decoration_manager_v1 *xdg_decoration_manager = nullptr;
WGL_LibDecor_System *libdecor = nullptr;
bool libdecor_required = false;
#endif
WGL_XDG_Decor_System *xdg_decor = nullptr;
struct zxdg_output_manager_v1 *xdg_output_manager = nullptr;
struct wl_shm *shm = nullptr;
@ -626,19 +678,19 @@ static void display_destroy(GWL_Display *d)
}
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
if (d->decor_context) {
libdecor_unref(d->decor_context);
if (use_libdecor) {
if (d->libdecor) {
wgl_libdecor_system_destroy(d->libdecor);
}
}
#else
if (d->xdg_decoration_manager) {
zxdg_decoration_manager_v1_destroy(d->xdg_decoration_manager);
else
#endif
{
if (d->xdg_decor) {
wgl_xdg_decor_system_destroy(d->xdg_decor);
}
}
if (d->xdg_shell) {
xdg_wm_base_destroy(d->xdg_shell);
}
#endif /* !WITH_GHOST_WAYLAND_LIBDECOR */
if (eglGetDisplay) {
::eglTerminate(eglGetDisplay(EGLNativeDisplayType(d->display)));
}
@ -2903,10 +2955,8 @@ static const struct wl_output_listener output_listener = {
/** \name Listener (XDG WM Base), #xdg_wm_base_listener
* \{ */
#ifndef WITH_GHOST_WAYLAND_LIBDECOR
static CLG_LogRef LOG_WL_XDG_WM_BASE = {"ghost.wl.handle.xdg_wm_base"};
# define LOG (&LOG_WL_XDG_WM_BASE)
#define LOG (&LOG_WL_XDG_WM_BASE)
static void shell_handle_ping(void * /*data*/,
struct xdg_wm_base *xdg_wm_base,
@ -2920,9 +2970,7 @@ static const struct xdg_wm_base_listener shell_listener = {
shell_handle_ping,
};
# undef LOG
#endif /* !WITH_GHOST_WAYLAND_LIBDECOR. */
#undef LOG
/** \} */
@ -2978,19 +3026,17 @@ static void global_handle_add(void *data,
display->compositor = static_cast<wl_compositor *>(
wl_registry_bind(wl_registry, name, &wl_compositor_interface, 3));
}
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
/* Pass. */
#else
else if (STREQ(interface, xdg_wm_base_interface.name)) {
display->xdg_shell = static_cast<xdg_wm_base *>(
WGL_XDG_Decor_System &decor = *display->xdg_decor;
decor.shell = static_cast<xdg_wm_base *>(
wl_registry_bind(wl_registry, name, &xdg_wm_base_interface, 1));
xdg_wm_base_add_listener(display->xdg_shell, &shell_listener, nullptr);
xdg_wm_base_add_listener(decor.shell, &shell_listener, nullptr);
}
else if (STREQ(interface, zxdg_decoration_manager_v1_interface.name)) {
display->xdg_decoration_manager = static_cast<zxdg_decoration_manager_v1 *>(
WGL_XDG_Decor_System &decor = *display->xdg_decor;
decor.manager = static_cast<zxdg_decoration_manager_v1 *>(
wl_registry_bind(wl_registry, name, &zxdg_decoration_manager_v1_interface, 1));
}
#endif /* !WITH_GHOST_WAYLAND_LIBDECOR. */
else if (STREQ(interface, zxdg_output_manager_v1_interface.name)) {
display->xdg_output_manager = static_cast<zxdg_output_manager_v1 *>(
wl_registry_bind(wl_registry, name, &zxdg_output_manager_v1_interface, 2));
@ -3048,6 +3094,14 @@ static void global_handle_add(void *data,
}
else {
found = false;
#ifdef USE_GNOME_NEEDS_LIBDECOR_HACK
if (STRPREFIX(interface, "gtk_shell")) { /* `gtk_shell1` at time of writing. */
/* Only require `libdecor` when built with X11 support,
* otherwise there is nothing to fall back on. */
display->libdecor_required = true;
}
#endif
}
CLOG_INFO(LOG,
@ -3102,6 +3156,9 @@ GHOST_SystemWayland::GHOST_SystemWayland() : GHOST_System(), d(new GWL_Display)
throw std::runtime_error("Wayland: unable to connect to display!");
}
/* This may be removed later if decorations are required, needed as part of registration. */
d->xdg_decor = new WGL_XDG_Decor_System;
/* Register interfaces. */
struct wl_registry *registry = wl_display_get_registry(d->display);
wl_registry_add_listener(registry, &registry_listener, d);
@ -3112,17 +3169,45 @@ GHOST_SystemWayland::GHOST_SystemWayland() : GHOST_System(), d(new GWL_Display)
wl_registry_destroy(registry);
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
d->decor_context = libdecor_new(d->display, &libdecor_interface);
if (!d->decor_context) {
display_destroy(d);
throw std::runtime_error("Wayland: unable to create window decorations!");
if (d->libdecor_required) {
wgl_xdg_decor_system_destroy(d->xdg_decor);
d->xdg_decor = nullptr;
if (!has_libdecor) {
# ifdef WITH_GHOST_X11
/* LIBDECOR was the only reason X11 was used, let the user know they need it installed. */
fprintf(stderr,
"WAYLAND found but libdecor was not, install libdecor for Wayland support, "
"falling back to X11\n");
# endif
display_destroy(d);
throw std::runtime_error("Wayland: unable to find libdecor!");
}
}
#else
if (!d->xdg_shell) {
display_destroy(d);
throw std::runtime_error("Wayland: unable to access xdg_shell!");
else {
use_libdecor = false;
}
#endif /* WITH_GHOST_WAYLAND_LIBDECOR */
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
if (use_libdecor) {
d->libdecor = new WGL_LibDecor_System;
WGL_LibDecor_System &decor = *d->libdecor;
decor.context = libdecor_new(d->display, &libdecor_interface);
if (!decor.context) {
display_destroy(d);
throw std::runtime_error("Wayland: unable to create window decorations!");
}
}
else
#endif
{
WGL_XDG_Decor_System &decor = *d->xdg_decor;
if (!decor.shell) {
display_destroy(d);
throw std::runtime_error("Wayland: unable to access xdg_shell!");
}
}
/* Register data device per seat for IPC between Wayland clients. */
if (d->data_device_manager) {
@ -4052,25 +4137,25 @@ wl_compositor *GHOST_SystemWayland::compositor()
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor *GHOST_SystemWayland::decor_context()
libdecor *GHOST_SystemWayland::libdecor_context()
{
return d->decor_context;
}
#else /* WITH_GHOST_WAYLAND_LIBDECOR */
xdg_wm_base *GHOST_SystemWayland::xdg_shell()
{
return d->xdg_shell;
}
zxdg_decoration_manager_v1 *GHOST_SystemWayland::xdg_decoration_manager()
{
return d->xdg_decoration_manager;
return d->libdecor->context;
}
#endif /* !WITH_GHOST_WAYLAND_LIBDECOR */
xdg_wm_base *GHOST_SystemWayland::xdg_decor_shell()
{
return d->xdg_decor->shell;
}
zxdg_decoration_manager_v1 *GHOST_SystemWayland::xdg_decor_manager()
{
return d->xdg_decor->manager;
}
/* End `xdg_decor`. */
const std::vector<GWL_Output *> &GHOST_SystemWayland::outputs() const
{
return d->outputs;
@ -4317,35 +4402,52 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
return GHOST_kSuccess;
}
#ifdef WITH_GHOST_WAYLAND_DYNLOAD
bool ghost_wl_dynload_libraries()
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
bool GHOST_SystemWayland::use_libdecor_runtime()
{
return use_libdecor;
}
#endif
#ifdef WITH_GHOST_WAYLAND_DYNLOAD
bool ghost_wl_dynload_libraries_init()
{
/* Only report when `libwayland-client` is not found when building without X11,
* which will be used as a fallback. */
# ifdef WITH_GHOST_X11
bool verbose = false;
/* When running in WAYLAND, let the user know when a missing library is the only reason
* WAYLAND could not be used. Otherwise it's not obvious why X11 is used as a fallback.
* Otherwise when X11 is used, reporting WAYLAND library warnings is unwelcome noise. */
bool verbose = getenv("WAYLAND_DISPLAY") != nullptr;
# else
bool verbose = true;
# endif
# endif /* !WITH_GHOST_X11 */
if (wayland_dynload_client_init(verbose) && /* `libwayland-client`. */
wayland_dynload_cursor_init(verbose) && /* `libwayland-cursor`. */
wayland_dynload_egl_init(verbose) && /* `libwayland-egl`. */
wayland_dynload_egl_init(verbose) /* `libwayland-egl`. */
) {
# ifdef WITH_GHOST_WAYLAND_LIBDECOR
wayland_dynload_libdecor_init(verbose) && /* `libdecor-0`. */
has_libdecor = wayland_dynload_libdecor_init(verbose); /* `libdecor-0`. */
# endif
true) {
return true;
}
# ifdef WITH_GHOST_WAYLAND_LIBDECOR
wayland_dynload_libdecor_exit();
# endif
wayland_dynload_client_exit();
wayland_dynload_cursor_exit();
wayland_dynload_egl_exit();
return false;
}
void ghost_wl_dynload_libraries_exit()
{
wayland_dynload_client_exit();
wayland_dynload_cursor_exit();
wayland_dynload_egl_exit();
# ifdef WITH_GHOST_WAYLAND_LIBDECOR
wayland_dynload_libdecor_exit();
# endif
}
#endif /* WITH_GHOST_WAYLAND_DYNLOAD */
/** \} */

View File

@ -21,18 +21,12 @@
# include <wayland_dynload_libdecor.h>
# endif
# include <libdecor.h>
#else
/* Generated by `wayland-scanner`. */
# include <xdg-decoration-unstable-v1-client-protocol.h>
# include <xdg-shell-client-protocol.h>
#endif
#include <string>
class GHOST_WindowWayland;
struct GWL_Display;
bool ghost_wl_output_own(const struct wl_output *wl_output);
void ghost_wl_output_tag(struct wl_output *wl_output);
struct GWL_Output *ghost_wl_output_user_data(struct wl_output *wl_output);
@ -52,7 +46,8 @@ void ghost_wl_surface_tag_cursor_tablet(struct wl_surface *surface);
* Return true when all required WAYLAND libraries are present,
* Performs dynamic loading when `WITH_GHOST_WAYLAND_DYNLOAD` is in use.
*/
bool ghost_wl_dynload_libraries();
bool ghost_wl_dynload_libraries_init();
void ghost_wl_dynload_libraries_exit();
#endif
struct GWL_Output {
@ -167,11 +162,11 @@ class GHOST_SystemWayland : public GHOST_System {
wl_compositor *compositor();
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor *decor_context();
#else
xdg_wm_base *xdg_shell();
zxdg_decoration_manager_v1 *xdg_decoration_manager();
libdecor *libdecor_context();
#endif
struct xdg_wm_base *xdg_decor_shell();
struct zxdg_decoration_manager_v1 *xdg_decor_manager();
/* End `xdg_decor`. */
const std::vector<GWL_Output *> &outputs() const;
@ -192,6 +187,10 @@ class GHOST_SystemWayland : public GHOST_System {
wl_surface *wl_surface,
int scale);
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
static bool use_libdecor_runtime();
#endif
private:
struct GWL_Display *d;
std::string selection;

View File

@ -2435,11 +2435,11 @@ GHOST_TSuccess GHOST_SystemX11::showMessageBox(const char *title,
utf8Str,
8,
PropModeReplace,
(const unsigned char *)title,
(const uchar *)title,
int(strlen(title)));
XChangeProperty(
m_display, window, winType, XA_ATOM, 32, PropModeReplace, (unsigned char *)&typeDialog, 1);
m_display, window, winType, XA_ATOM, 32, PropModeReplace, (uchar *)&typeDialog, 1);
}
/* Create buttons GC */

View File

@ -31,13 +31,52 @@
# include <libdecor.h>
#endif
/* Generated by `wayland-scanner`. */
#include <xdg-decoration-unstable-v1-client-protocol.h>
#include <xdg-shell-client-protocol.h>
/* Logging, use `ghost.wl.*` prefix. */
#include "CLG_log.h"
static constexpr size_t base_dpi = 96;
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
/* Access `use_libdecor` in #GHOST_SystemWayland. */
# define use_libdecor GHOST_SystemWayland::use_libdecor_runtime()
#endif
static GHOST_WindowManager *window_manager = nullptr;
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
struct WGL_LibDecor_Window {
struct libdecor_frame *frame = nullptr;
bool configured = false;
};
static void wgl_libdecor_window_destroy(WGL_LibDecor_Window *decor)
{
libdecor_frame_unref(decor->frame);
delete decor;
}
#endif /* WITH_GHOST_WAYLAND_LIBDECOR */
struct WGL_XDG_Decor_Window {
struct xdg_surface *surface = nullptr;
struct zxdg_toplevel_decoration_v1 *toplevel_decor = nullptr;
struct xdg_toplevel *toplevel = nullptr;
enum zxdg_toplevel_decoration_v1_mode mode = (enum zxdg_toplevel_decoration_v1_mode)0;
};
static void wgl_xdg_decor_window_destroy(WGL_XDG_Decor_Window *decor)
{
if (decor->toplevel_decor) {
zxdg_toplevel_decoration_v1_destroy(decor->toplevel_decor);
}
xdg_toplevel_destroy(decor->toplevel);
xdg_surface_destroy(decor->surface);
delete decor;
}
struct GWL_Window {
GHOST_WindowWayland *w = nullptr;
struct wl_surface *wl_surface = nullptr;
@ -60,15 +99,9 @@ struct GWL_Window {
uint32_t dpi = 0;
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
struct libdecor_frame *decor_frame = nullptr;
bool decor_configured = false;
#else
struct xdg_surface *xdg_surface = nullptr;
struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration = nullptr;
struct xdg_toplevel *xdg_toplevel = nullptr;
enum zxdg_toplevel_decoration_v1_mode decoration_mode = (enum zxdg_toplevel_decoration_v1_mode)0;
WGL_LibDecor_Window *libdecor = nullptr;
#endif
WGL_XDG_Decor_Window *xdg_decor = nullptr;
wl_egl_window *egl_window = nullptr;
bool is_maximised = false;
@ -146,10 +179,8 @@ static int outputs_max_scale_or_default(const std::vector<GWL_Output *> &outputs
/** \name Listener (XDG Top Level), #xdg_toplevel_listener
* \{ */
#ifndef WITH_GHOST_WAYLAND_LIBDECOR
static CLG_LogRef LOG_WL_XDG_TOPLEVEL = {"ghost.wl.handle.xdg_toplevel"};
# define LOG (&LOG_WL_XDG_TOPLEVEL)
#define LOG (&LOG_WL_XDG_TOPLEVEL)
static void xdg_toplevel_handle_configure(void *data,
xdg_toplevel * /*xdg_toplevel*/,
@ -197,9 +228,7 @@ static const xdg_toplevel_listener toplevel_listener = {
xdg_toplevel_handle_close,
};
# undef LOG
#endif /* !WITH_GHOST_WAYLAND_LIBDECOR. */
#undef LOG
/** \} */
@ -250,7 +279,7 @@ static void frame_handle_configure(struct libdecor_frame *frame,
libdecor_frame_commit(frame, state, configuration);
libdecor_state_free(state);
win->decor_configured = true;
win->libdecor->configured = true;
}
static void frame_handle_close(struct libdecor_frame * /*frame*/, void *data)
@ -285,10 +314,8 @@ static struct libdecor_frame_interface libdecor_frame_iface = {
/** \name Listener (XDG Decoration Listener), #zxdg_toplevel_decoration_v1_listener
* \{ */
#ifndef WITH_GHOST_WAYLAND_LIBDECOR
static CLG_LogRef LOG_WL_XDG_TOPLEVEL_DECORATION = {"ghost.wl.handle.xdg_toplevel_decoration"};
# define LOG (&LOG_WL_XDG_TOPLEVEL_DECORATION)
#define LOG (&LOG_WL_XDG_TOPLEVEL_DECORATION)
static void xdg_toplevel_decoration_handle_configure(
void *data,
@ -296,16 +323,14 @@ static void xdg_toplevel_decoration_handle_configure(
const uint32_t mode)
{
CLOG_INFO(LOG, 2, "configure (mode=%u)", mode);
static_cast<GWL_Window *>(data)->decoration_mode = (zxdg_toplevel_decoration_v1_mode)mode;
static_cast<GWL_Window *>(data)->xdg_decor->mode = (zxdg_toplevel_decoration_v1_mode)mode;
}
static const zxdg_toplevel_decoration_v1_listener toplevel_decoration_v1_listener = {
xdg_toplevel_decoration_handle_configure,
};
# undef LOG
#endif /* !WITH_GHOST_WAYLAND_LIBDECOR. */
#undef LOG
/** \} */
@ -313,10 +338,8 @@ static const zxdg_toplevel_decoration_v1_listener toplevel_decoration_v1_listene
/** \name Listener (XDG Surface Handle Configure), #xdg_surface_listener
* \{ */
#ifndef WITH_GHOST_WAYLAND_LIBDECOR
static CLG_LogRef LOG_WL_XDG_SURFACE = {"ghost.wl.handle.xdg_surface"};
# define LOG (&LOG_WL_XDG_SURFACE)
#define LOG (&LOG_WL_XDG_SURFACE)
static void xdg_surface_handle_configure(void *data,
xdg_surface *xdg_surface,
@ -324,7 +347,7 @@ static void xdg_surface_handle_configure(void *data,
{
GWL_Window *win = static_cast<GWL_Window *>(data);
if (win->xdg_surface != xdg_surface) {
if (win->xdg_decor->surface != xdg_surface) {
CLOG_INFO(LOG, 2, "configure (skipped)");
return;
}
@ -354,9 +377,7 @@ static const xdg_surface_listener xdg_surface_listener = {
xdg_surface_handle_configure,
};
# undef LOG
#endif /* !WITH_GHOST_WAYLAND_LIBDECOR. */
#undef LOG
/** \} */
@ -476,43 +497,58 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
* when the `w->scale` changed. */
const int32_t size_min[2] = {320, 240};
/* This value is expected to match the base name of the `.desktop` file. see T101779. */
const char *xdg_app_id = "org.blender.Blender";
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
/* create window decorations */
w->decor_frame = libdecor_decorate(
m_system->decor_context(), w->wl_surface, &libdecor_frame_iface, w);
libdecor_frame_map(w->decor_frame);
if (use_libdecor) {
w->libdecor = new WGL_LibDecor_Window;
WGL_LibDecor_Window &decor = *w->libdecor;
libdecor_frame_set_min_content_size(w->decor_frame, UNPACK2(size_min));
/* create window decorations */
decor.frame = libdecor_decorate(
m_system->libdecor_context(), w->wl_surface, &libdecor_frame_iface, w);
libdecor_frame_map(w->libdecor->frame);
if (parentWindow) {
libdecor_frame_set_parent(
w->decor_frame, dynamic_cast<const GHOST_WindowWayland *>(parentWindow)->w->decor_frame);
libdecor_frame_set_min_content_size(decor.frame, UNPACK2(size_min));
libdecor_frame_set_app_id(decor.frame, xdg_app_id);
if (parentWindow) {
WGL_LibDecor_Window &decor_parent =
*dynamic_cast<const GHOST_WindowWayland *>(parentWindow)->w->libdecor;
libdecor_frame_set_parent(decor.frame, decor_parent.frame);
}
}
#else
w->xdg_surface = xdg_wm_base_get_xdg_surface(m_system->xdg_shell(), w->wl_surface);
w->xdg_toplevel = xdg_surface_get_toplevel(w->xdg_surface);
else
#endif
{
w->xdg_decor = new WGL_XDG_Decor_Window;
WGL_XDG_Decor_Window &decor = *w->xdg_decor;
decor.surface = xdg_wm_base_get_xdg_surface(m_system->xdg_decor_shell(), w->wl_surface);
decor.toplevel = xdg_surface_get_toplevel(decor.surface);
xdg_toplevel_set_min_size(w->xdg_toplevel, UNPACK2(size_min));
xdg_toplevel_set_min_size(decor.toplevel, UNPACK2(size_min));
xdg_toplevel_set_app_id(decor.toplevel, xdg_app_id);
if (m_system->xdg_decoration_manager()) {
w->xdg_toplevel_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(
m_system->xdg_decoration_manager(), w->xdg_toplevel);
zxdg_toplevel_decoration_v1_add_listener(
w->xdg_toplevel_decoration, &toplevel_decoration_v1_listener, w);
zxdg_toplevel_decoration_v1_set_mode(w->xdg_toplevel_decoration,
ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
if (m_system->xdg_decor_manager()) {
decor.toplevel_decor = zxdg_decoration_manager_v1_get_toplevel_decoration(
m_system->xdg_decor_manager(), decor.toplevel);
zxdg_toplevel_decoration_v1_add_listener(
decor.toplevel_decor, &toplevel_decoration_v1_listener, w);
zxdg_toplevel_decoration_v1_set_mode(decor.toplevel_decor,
ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
}
xdg_surface_add_listener(decor.surface, &xdg_surface_listener, w);
xdg_toplevel_add_listener(decor.toplevel, &toplevel_listener, w);
if (parentWindow && is_dialog) {
WGL_XDG_Decor_Window &decor_parent =
*dynamic_cast<const GHOST_WindowWayland *>(parentWindow)->w->xdg_decor;
xdg_toplevel_set_parent(decor.toplevel, decor_parent.toplevel);
}
}
xdg_surface_add_listener(w->xdg_surface, &xdg_surface_listener, w);
xdg_toplevel_add_listener(w->xdg_toplevel, &toplevel_listener, w);
if (parentWindow && is_dialog) {
xdg_toplevel_set_parent(
w->xdg_toplevel, dynamic_cast<const GHOST_WindowWayland *>(parentWindow)->w->xdg_toplevel);
}
#endif /* !WITH_GHOST_WAYLAND_LIBDECOR */
setTitle(title);
wl_surface_set_user_data(w->wl_surface, this);
@ -522,11 +558,14 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
wl_display_roundtrip(m_system->display());
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
/* It's important not to return until the window is configured or
* calls to `setState` from Blender will crash `libdecor`. */
while (!w->decor_configured) {
if (libdecor_dispatch(m_system->decor_context(), 0) < 0) {
break;
if (use_libdecor) {
WGL_LibDecor_Window &decor = *w->libdecor;
/* It's important not to return until the window is configured or
* calls to `setState` from Blender will crash `libdecor`. */
while (!decor.configured) {
if (libdecor_dispatch(m_system->libdecor_context(), 0) < 0) {
break;
}
}
}
#endif
@ -535,9 +574,13 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
setOpaque();
#endif
#ifndef WITH_GHOST_WAYLAND_LIBDECOR /* Causes a glitch with `libdecor` for some reason. */
setState(state);
/* Causes a glitch with `libdecor` for some reason. */
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
if (use_libdecor == false)
#endif
{
setState(state);
}
/* EGL context. */
if (setDrawingContextType(type) == GHOST_kFailure) {
@ -596,12 +639,16 @@ GHOST_TSuccess GHOST_WindowWayland::getCursorBitmap(GHOST_CursorBitmapRef *bitma
void GHOST_WindowWayland::setTitle(const char *title)
{
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor_frame_set_app_id(w->decor_frame, title);
libdecor_frame_set_title(w->decor_frame, title);
#else
xdg_toplevel_set_title(w->xdg_toplevel, title);
xdg_toplevel_set_app_id(w->xdg_toplevel, title);
if (use_libdecor) {
WGL_LibDecor_Window &decor = *w->libdecor;
libdecor_frame_set_title(decor.frame, title);
}
else
#endif
{
WGL_XDG_Decor_Window &decor = *w->xdg_decor;
xdg_toplevel_set_title(decor.toplevel, title);
}
this->title = title;
}
@ -672,14 +719,14 @@ GHOST_WindowWayland::~GHOST_WindowWayland()
wl_egl_window_destroy(w->egl_window);
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor_frame_unref(w->decor_frame);
#else
if (w->xdg_toplevel_decoration) {
zxdg_toplevel_decoration_v1_destroy(w->xdg_toplevel_decoration);
if (use_libdecor) {
wgl_libdecor_window_destroy(w->libdecor);
}
xdg_toplevel_destroy(w->xdg_toplevel);
xdg_surface_destroy(w->xdg_surface);
else
#endif
{
wgl_xdg_decor_window_destroy(w->xdg_decor);
}
/* Clear any pointers to this window. This is needed because there are no guarantees
* that flushing the display will the "leave" handlers before handling events. */
@ -711,47 +758,74 @@ GHOST_TSuccess GHOST_WindowWayland::setState(GHOST_TWindowState state)
case GHOST_kWindowStateNormal:
/* Unset states. */
switch (getState()) {
case GHOST_kWindowStateMaximized:
case GHOST_kWindowStateMaximized: {
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor_frame_unset_maximized(w->decor_frame);
#else
xdg_toplevel_unset_maximized(w->xdg_toplevel);
if (use_libdecor) {
libdecor_frame_unset_maximized(w->libdecor->frame);
}
else
#endif
{
xdg_toplevel_unset_maximized(w->xdg_decor->toplevel);
}
break;
case GHOST_kWindowStateFullScreen:
}
case GHOST_kWindowStateFullScreen: {
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor_frame_unset_fullscreen(w->decor_frame);
#else
xdg_toplevel_unset_fullscreen(w->xdg_toplevel);
if (use_libdecor) {
libdecor_frame_unset_fullscreen(w->libdecor->frame);
}
else
#endif
{
xdg_toplevel_unset_fullscreen(w->xdg_decor->toplevel);
}
break;
default:
}
default: {
break;
}
}
break;
case GHOST_kWindowStateMaximized:
case GHOST_kWindowStateMaximized: {
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor_frame_set_maximized(w->decor_frame);
#else
xdg_toplevel_set_maximized(w->xdg_toplevel);
if (use_libdecor) {
libdecor_frame_set_maximized(w->libdecor->frame);
}
else
#endif
{
xdg_toplevel_set_maximized(w->xdg_decor->toplevel);
}
break;
case GHOST_kWindowStateMinimized:
}
case GHOST_kWindowStateMinimized: {
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor_frame_set_minimized(w->decor_frame);
#else
xdg_toplevel_set_minimized(w->xdg_toplevel);
if (use_libdecor) {
libdecor_frame_set_minimized(w->libdecor->frame);
}
else
#endif
{
xdg_toplevel_set_minimized(w->xdg_decor->toplevel);
}
break;
case GHOST_kWindowStateFullScreen:
}
case GHOST_kWindowStateFullScreen: {
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor_frame_set_fullscreen(w->decor_frame, nullptr);
#else
xdg_toplevel_set_fullscreen(w->xdg_toplevel, nullptr);
if (use_libdecor) {
libdecor_frame_set_fullscreen(w->libdecor->frame, nullptr);
}
else
#endif
{
xdg_toplevel_set_fullscreen(w->xdg_decor->toplevel, nullptr);
}
break;
case GHOST_kWindowStateEmbedded:
}
case GHOST_kWindowStateEmbedded: {
return GHOST_kFailure;
}
}
return GHOST_kSuccess;
}
@ -780,20 +854,29 @@ GHOST_TSuccess GHOST_WindowWayland::setOrder(GHOST_TWindowOrder /*order*/)
GHOST_TSuccess GHOST_WindowWayland::beginFullScreen() const
{
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor_frame_set_fullscreen(w->decor_frame, nullptr);
#else
xdg_toplevel_set_fullscreen(w->xdg_toplevel, nullptr);
if (use_libdecor) {
libdecor_frame_set_fullscreen(w->libdecor->frame, nullptr);
}
else
#endif
{
xdg_toplevel_set_fullscreen(w->xdg_decor->toplevel, nullptr);
}
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_WindowWayland::endFullScreen() const
{
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
libdecor_frame_unset_fullscreen(w->decor_frame);
#else
xdg_toplevel_unset_fullscreen(w->xdg_toplevel);
if (use_libdecor) {
libdecor_frame_unset_fullscreen(w->libdecor->frame);
}
else
#endif
{
xdg_toplevel_unset_fullscreen(w->xdg_decor->toplevel);
}
return GHOST_kSuccess;
}

View File

@ -43,7 +43,7 @@ void (*MEM_set_error_callback)(void (*func)(const char *)) = MEM_lockfree_set_er
bool (*MEM_consistency_check)(void) = MEM_lockfree_consistency_check;
void (*MEM_set_memory_debug)(void) = MEM_lockfree_set_memory_debug;
size_t (*MEM_get_memory_in_use)(void) = MEM_lockfree_get_memory_in_use;
unsigned int (*MEM_get_memory_blocks_in_use)(void) = MEM_lockfree_get_memory_blocks_in_use;
uint (*MEM_get_memory_blocks_in_use)(void) = MEM_lockfree_get_memory_blocks_in_use;
void (*MEM_reset_peak_memory)(void) = MEM_lockfree_reset_peak_memory;
size_t (*MEM_get_peak_memory)(void) = MEM_lockfree_get_peak_memory;

View File

@ -233,7 +233,7 @@ void *MEM_lockfree_callocN(size_t len, const char *str)
print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
SIZET_ARG(len),
str,
(unsigned int)mem_in_use);
(uint)mem_in_use);
return NULL;
}
@ -278,7 +278,7 @@ void *MEM_lockfree_mallocN(size_t len, const char *str)
print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
SIZET_ARG(len),
str,
(unsigned int)mem_in_use);
(uint)mem_in_use);
return NULL;
}
@ -292,7 +292,7 @@ void *MEM_lockfree_malloc_arrayN(size_t len, size_t size, const char *str)
SIZET_ARG(len),
SIZET_ARG(size),
str,
(unsigned int)mem_in_use);
(uint)mem_in_use);
abort();
return NULL;
}
@ -349,7 +349,7 @@ void *MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *str
print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
SIZET_ARG(len),
str,
(unsigned int)mem_in_use);
(uint)mem_in_use);
return NULL;
}
@ -401,7 +401,7 @@ size_t MEM_lockfree_get_memory_in_use(void)
return mem_in_use;
}
unsigned int MEM_lockfree_get_memory_blocks_in_use(void)
uint MEM_lockfree_get_memory_blocks_in_use(void)
{
return totblock;
}

View File

@ -723,12 +723,11 @@ template<typename Mesh> class Mikktspace {
void build4RuleGroups()
{
/* Note: This could be parallelized by grouping all [t, i] pairs into
/* NOTE: This could be parallelized by grouping all [t, i] pairs into
* shards by hash(triangles[t].vertices[i]). This way, each shard can be processed
* independently and in parallel.
* However, the groupWithAny logic needs special handling (e.g. lock a mutex when
* encountering a groupWithAny triangle, then sort it out, then unlock and proceed).
*/
* However, the `groupWithAny` logic needs special handling (e.g. lock a mutex when
* encountering a `groupWithAny` triangle, then sort it out, then unlock and proceed). */
for (uint t = 0; t < nrTriangles; t++) {
Triangle &triangle = triangles[t];
for (uint i = 0; i < 3; i++) {

View File

@ -22,7 +22,7 @@ bool wayland_dynload_egl_init(const bool verbose)
{
/* Library paths. */
const char *paths[] = {
"libwayland-egl.so.0",
"libwayland-egl.so.1",
"libwayland-egl.so",
};
const int paths_num = sizeof(paths) / sizeof(*paths);

View File

@ -367,9 +367,9 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
"all and invert unselected",
"and AMD driver version 22.10 or newer",
"and AMD Radeon Pro 21.Q4 driver or newer",
"and Linux driver version xx.xx.23570 or newer",
"and Linux driver version xx.xx.23904 or newer",
"and NVIDIA driver version 470 or newer",
"and Windows driver version 101.3268 or newer",
"and Windows driver version 101.3430 or newer",
"available with",
"brown fox",
"can't save image while rendering",

View File

@ -389,6 +389,8 @@ class SpellChecker:
"albedo",
"anamorphic",
"anisotropic", "anisotropy",
"arcminute", "arcminutes",
"arcsecond", "arcseconds",
"bimanual", # OpenXR?
"bitangent",
"boid", "boids",
@ -449,7 +451,7 @@ class SpellChecker:
"superellipse",
"thumbstick",
"tooltip", "tooltips",
"trackpad",
"touchpad", "trackpad",
"tuple",
"unicode",
"viewport", "viewports",
@ -650,6 +652,7 @@ class SpellChecker:
"mikktspace",
"minkowski",
"minnaert",
"mises", # von Mises-Fisher
"moskowitz", # Pierson-Moskowitz
"musgrave",
"nayar",
@ -665,6 +668,7 @@ class SpellChecker:
"runge",
"sobol",
"verlet",
"von", # von Mises-Fisher
"wilkie",
"worley",
@ -724,6 +728,7 @@ class SpellChecker:
"lmb", "mmb", "rmb",
"lscm",
"kb",
"mis",
"mocap",
"msgid", "msgids",
"mux",
@ -751,6 +756,7 @@ class SpellChecker:
"uuid",
"vbo", "vbos",
"vfx",
"vmm",
"vr",
"wxyz",
"xr",

View File

@ -53,6 +53,13 @@ def write_sysinfo(filepath):
output.write("build linkflags: %s\n" % prepr(bpy.app.build_linkflags))
output.write("build system: %s\n" % prepr(bpy.app.build_system))
# Windowing Environment (include when dynamically selectable).
from _bpy import _ghost_backend
ghost_backend = _ghost_backend()
if ghost_backend not in {'NONE', 'DEFAULT'}:
output.write("windowing environment: %s\n" % prepr(ghost_backend))
del _ghost_backend, ghost_backend
# Python info.
output.write(title("Python"))
output.write("version: %s\n" % (sys.version.replace("\n", " ")))

View File

@ -89,6 +89,17 @@ class PREFERENCES_OT_copy_prev(Operator):
if os.path.isdir(cls._old_version_path(version_split)):
return version_split
version_old = version_old - 1
# Support loading 2.8x..2.9x startup (any older isn't so useful to load).
# NOTE: remove this block for Blender 4.0 and later.
if version_old == 299:
version_old = 294
while version_old >= 280:
version_split = version_old // 100, version_old % 100
if os.path.isdir(cls._old_version_path(version_split)):
return version_split
version_old = version_old - 1
return None
@classmethod

View File

@ -3158,6 +3158,15 @@ class WM_MT_splash_about(Menu):
bpy.app.build_commit_time.decode('utf-8', 'replace')), translate=False)
col.label(text=iface_("Hash: %s") % bpy.app.build_hash.decode('ascii'), translate=False)
col.label(text=iface_("Branch: %s") % bpy.app.build_branch.decode('utf-8', 'replace'), translate=False)
# This isn't useful information on MS-Windows or Apple systems as dynamically switching
# between windowing systems is only supported between X11/WAYLAND.
from _bpy import _ghost_backend
ghost_backend = _ghost_backend()
if ghost_backend not in {'NONE', 'DEFAULT'}:
col.label(text=iface_("Windowing Environment: %s") % _ghost_backend(), translate=False)
del _ghost_backend, ghost_backend
col.separator(factor=2.0)
col.label(text="Blender is free software")
col.label(text="Licensed under the GNU General Public License")

View File

@ -239,6 +239,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
class PARTICLE_PT_emission(ParticleButtonsPanel, Panel):
bl_label = "Emission"
bl_translation_context = i18n_contexts.id_particlesettings
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}
@classmethod

View File

@ -2,7 +2,10 @@
import bpy
from bpy.types import Panel, Header, Menu, UIList
from bpy.app.translations import pgettext_iface as iface_
from bpy.app.translations import (
pgettext_iface as iface_,
contexts as i18n_contexts,
)
from bl_ui.utils import PresetPanel
from bl_ui.properties_grease_pencil_common import (
AnnotationDrawingToolsPanel,
@ -1751,6 +1754,7 @@ class CLIP_MT_marker_pie(Menu):
class CLIP_MT_tracking_pie(Menu):
# Tracking Operators
bl_label = "Tracking"
bl_translation_context = i18n_contexts.id_movieclip
@classmethod
def poll(cls, context):

View File

@ -1528,36 +1528,23 @@ class IMAGE_PT_overlay_guides(Panel):
layout.active = overlay.show_overlays
row = layout.row()
row_el = row.column()
row_el.prop(overlay, "show_grid_background", text="Grid")
row.prop(overlay, "show_grid_background", text="Grid")
if overlay.show_grid_background:
layout.use_property_split = True
col = layout.column(align=False, heading="Grid Over Image")
col.use_property_decorate = False
row = col.row(align=True)
sub = row.row(align=True)
sub.prop(uvedit, "show_grid_over_image", text="")
sub = row.row()
sub.prop(uvedit, "show_grid_over_image", text="Over Image")
sub.active = sima.image is not None
col = layout.column(align=False, heading="Fixed Subdivisions")
col.use_property_decorate = False
layout.row().prop(uvedit, "grid_shape_source", expand=True)
row = col.row(align=True)
sub = row.row(align=True)
sub.prop(uvedit, "use_custom_grid", text="")
if uvedit.use_custom_grid:
row = layout.row()
row.use_property_split = True
row.use_property_decorate = False
sub = sub.row(align=True)
sub.prop(uvedit, "custom_grid_subdivisions", text="")
layout.use_property_split = True
layout.use_property_decorate = False
row = layout.row()
row.use_property_split = True
row.use_property_decorate = False
row.prop(uvedit, "tile_grid_shape", text="Tiles")
row.prop(uvedit, "custom_grid_subdivisions", text="Fixed Subdivisions")
row.active = uvedit.grid_shape_source == 'FIXED'
layout.prop(uvedit, "tile_grid_shape", text="Tiles")
class IMAGE_PT_overlay_uv_edit(Panel):

View File

@ -683,7 +683,7 @@ class SEQUENCER_MT_add(Menu):
elif bpy_data_movieclips_len > 0:
layout.operator_menu_enum("sequencer.movieclip_strip_add", "clip", text="Clip", icon='TRACKER')
else:
layout.menu("SEQUENCER_MT_add_empty", text="Clip", icon='TRACKER')
layout.menu("SEQUENCER_MT_add_empty", text="Clip", text_ctxt=i18n_contexts.id_movieclip, icon='TRACKER')
del bpy_data_movieclips_len
bpy_data_masks_len = len(bpy.data.masks)

View File

@ -3356,8 +3356,7 @@ class VIEW3D_MT_face_sets(Menu):
op = layout.operator("sculpt.face_set_change_visibility", text='Invert Visible Face Sets')
op.mode = 'INVERT'
op = layout.operator("sculpt.face_set_change_visibility", text='Show All Face Sets')
op.mode = 'SHOW_ALL'
op = layout.operator("sculpt.reveal_all", text='Show All Face Sets')
layout.separator()
@ -5518,8 +5517,7 @@ class VIEW3D_MT_sculpt_face_sets_edit_pie(Menu):
op = pie.operator("sculpt.face_set_change_visibility", text='Invert Visible')
op.mode = 'INVERT'
op = pie.operator("sculpt.face_set_change_visibility", text='Show All')
op.mode = 'SHOW_ALL'
op = pie.operator("sculpt.reveal_all", text='Show All')
class VIEW3D_MT_wpaint_vgroup_lock_pie(Menu):

View File

@ -98,7 +98,7 @@ static int blf_search(const char *name)
{
for (int i = 0; i < BLF_MAX_FONT; i++) {
const FontBLF *font = global_font[i];
if (font && (STREQ(font->name, name))) {
if (font && STREQ(font->name, name)) {
return i;
}
}
@ -226,7 +226,7 @@ void BLF_unload(const char *name)
for (int i = 0; i < BLF_MAX_FONT; i++) {
FontBLF *font = global_font[i];
if (font && (STREQ(font->name, name))) {
if (font && STREQ(font->name, name)) {
BLI_assert(font->reference_count > 0);
font->reference_count--;

View File

@ -54,7 +54,7 @@
*/
static FT_Fixed to_16dot16(double val)
{
return (FT_Fixed)(lround(val * 65536.0));
return (FT_Fixed)lround(val * 65536.0);
}
/** \} */

View File

@ -10,6 +10,10 @@
#include "BLI_kdopbvh.h"
#include "BLI_threads.h"
#ifdef __cplusplus
# include <mutex>
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -196,6 +200,8 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
BVHCacheType bvh_cache_type,
int tree_type);
#ifdef __cplusplus
/**
* Builds or queries a BVH-cache for the cache BVH-tree of the request type.
*/
@ -204,7 +210,9 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
int tree_type,
BVHCacheType bvh_cache_type,
struct BVHCache **bvh_cache_p,
ThreadMutex *mesh_eval_mutex);
std::mutex *mesh_eval_mutex);
#endif
/**
* Frees data allocated by a call to `bvhtree_from_editmesh_*`.

View File

@ -16,6 +16,7 @@ struct ListBase;
struct Object;
struct ParticleSystem;
struct Scene;
struct ViewLayer;
struct ViewerPath;
struct GeometrySet;
@ -83,6 +84,13 @@ bool BKE_object_dupli_find_rgba_attribute(struct Object *ob,
const char *name,
float r_value[4]);
/** Look up the RGBA value of a view layer/scene/world shader attribute.
* \return true if the attribute was found; if not, r_value is also set to zero. */
bool BKE_view_layer_find_rgba_attribute(struct Scene *scene,
struct ViewLayer *layer,
const char *name,
float r_value[4]);
#ifdef __cplusplus
}
#endif

View File

@ -11,15 +11,25 @@ extern "C" {
#endif
struct BMEditMesh;
struct EditMeshData;
void BKE_editmesh_cache_ensure_poly_normals(struct BMEditMesh *em, struct EditMeshData *emd);
void BKE_editmesh_cache_ensure_vert_normals(struct BMEditMesh *em, struct EditMeshData *emd);
typedef struct EditMeshData {
/** when set, \a vertexNos, polyNos are lazy initialized */
const float (*vertexCos)[3];
void BKE_editmesh_cache_ensure_poly_centers(struct BMEditMesh *em, struct EditMeshData *emd);
/** lazy initialize (when \a vertexCos is set) */
float const (*vertexNos)[3];
float const (*polyNos)[3];
/** also lazy init but don't depend on \a vertexCos */
const float (*polyCos)[3];
} EditMeshData;
void BKE_editmesh_cache_ensure_poly_normals(struct BMEditMesh *em, EditMeshData *emd);
void BKE_editmesh_cache_ensure_vert_normals(struct BMEditMesh *em, EditMeshData *emd);
void BKE_editmesh_cache_ensure_poly_centers(struct BMEditMesh *em, EditMeshData *emd);
bool BKE_editmesh_cache_calc_minmax(struct BMEditMesh *em,
struct EditMeshData *emd,
EditMeshData *emd,
float min[3],
float max[3]);

View File

@ -490,7 +490,7 @@ void BKE_mesh_calc_normals(struct Mesh *me);
* Called after calculating all modifiers.
*/
void BKE_mesh_ensure_normals_for_display(struct Mesh *mesh);
void BKE_mesh_calc_normals_looptri(struct MVert *mverts,
void BKE_mesh_calc_normals_looptri(const struct MVert *mverts,
int numVerts,
const struct MLoop *mloop,
const struct MLoopTri *looptri,

View File

@ -336,7 +336,7 @@ int *BKE_mesh_calc_smoothgroups(const struct MEdge *medge,
#endif
#ifdef __cplusplus
namespace blender::mesh_topology {
namespace blender::bke::mesh_topology {
Array<int> build_loop_to_poly_map(Span<MPoly> polys, int loops_num);
@ -348,5 +348,5 @@ inline int previous_poly_loop(const MPoly &poly, int loop_i)
return loop_i - 1 + (loop_i == poly.loopstart) * poly.totloop;
}
} // namespace blender::mesh_topology
} // namespace blender::bke::mesh_topology
#endif

View File

@ -9,6 +9,7 @@
*/
//#include "BKE_customdata.h" /* for eCustomDataMask */
#include "BKE_mesh_types.h"
#ifdef __cplusplus
extern "C" {
@ -25,22 +26,11 @@ struct Mesh;
struct Object;
struct Scene;
/**
* \brief Initialize the runtime of the given mesh.
*
* Function expects that the runtime is already cleared.
*/
void BKE_mesh_runtime_init_data(struct Mesh *mesh);
/**
* \brief Free all data (and mutexes) inside the runtime of the given mesh.
*/
void BKE_mesh_runtime_free_data(struct Mesh *mesh);
/**
* Clear all pointers which we don't want to be shared on copying the datablock.
* However, keep all the flags which defines what the mesh is (for example, that
* it's deformed only, or that its custom data layers are out of date.)
*/
void BKE_mesh_runtime_reset_on_copy(struct Mesh *mesh, int flag);
int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh);
void BKE_mesh_runtime_looptri_recalc(struct Mesh *mesh);
/**
@ -66,6 +56,11 @@ void BKE_mesh_runtime_verttri_from_looptri(struct MVertTri *r_verttri,
const struct MLoopTri *looptri,
int looptri_num);
/** \note Only used for access in C. */
bool BKE_mesh_is_deformed_only(const struct Mesh *mesh);
/** \note Only used for access in C. */
eMeshWrapperType BKE_mesh_wrapper_type(const struct Mesh *mesh);
/* NOTE: the functions below are defined in DerivedMesh.cc, and are intended to be moved
* to a more suitable location when that file is removed.
* They should also be renamed to use conventions from BKE, not old DerivedMesh.cc.

View File

@ -1,11 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2020 Blender Foundation. All rights reserved. */
#pragma once
/** \file
* \ingroup bke
*/
#ifdef __cplusplus
# include <mutex>
# include "BLI_span.hh"
# include "DNA_customdata_types.h"
# include "MEM_guardedalloc.h"
struct BVHCache;
struct EditMeshData;
struct MLoopTri;
struct ShrinkwrapBoundaryData;
struct SubdivCCG;
struct SubsurfRuntimeData;
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef enum eMeshBatchDirtyMode {
BKE_MESH_BATCH_DIRTY_ALL = 0,
BKE_MESH_BATCH_DIRTY_SELECT,
@ -14,3 +38,125 @@ typedef enum eMeshBatchDirtyMode {
BKE_MESH_BATCH_DIRTY_UVEDIT_ALL,
BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT,
} eMeshBatchDirtyMode;
/** #MeshRuntime.wrapper_type */
typedef enum eMeshWrapperType {
/** Use mesh data (#Mesh.mvert, #Mesh.medge, #Mesh.mloop, #Mesh.mpoly). */
ME_WRAPPER_TYPE_MDATA = 0,
/** Use edit-mesh data (#Mesh.edit_mesh, #MeshRuntime.edit_data). */
ME_WRAPPER_TYPE_BMESH = 1,
/** Use subdivision mesh data (#MeshRuntime.mesh_eval). */
ME_WRAPPER_TYPE_SUBD = 2,
} eMeshWrapperType;
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
namespace blender::bke {
/**
* \warning Typical access is done via #Mesh::looptris().
*/
struct MLoopTri_Store {
/* WARNING! swapping between array (ready-to-be-used data) and array_wip
* (where data is actually computed)
* shall always be protected by same lock as one used for looptris computing. */
MLoopTri *array = nullptr;
MLoopTri *array_wip = nullptr;
int len = 0;
int len_alloc = 0;
};
struct MeshRuntime {
/* Evaluated mesh for objects which do not have effective modifiers.
* This mesh is used as a result of modifier stack evaluation.
* Since modifier stack evaluation is threaded on object level we need some synchronization. */
Mesh *mesh_eval = nullptr;
std::mutex eval_mutex;
/* A separate mutex is needed for normal calculation, because sometimes
* the normals are needed while #eval_mutex is already locked. */
std::mutex normals_mutex;
/** Needed to ensure some thread-safety during render data pre-processing. */
std::mutex render_mutex;
/** Lazily initialized SoA data from the #edit_mesh field in #Mesh. */
EditMeshData *edit_data = nullptr;
/**
* Data used to efficiently draw the mesh in the viewport, especially useful when
* the same mesh is used in many objects or instances. See `draw_cache_impl_mesh.cc`.
*/
void *batch_cache = nullptr;
/** Cache for derived triangulation of the mesh. */
MLoopTri_Store looptris;
/** Cache for BVH trees generated for the mesh. Defined in 'BKE_bvhutil.c' */
BVHCache *bvh_cache = nullptr;
/** Cache of non-manifold boundary data for Shrinkwrap Target Project. */
ShrinkwrapBoundaryData *shrinkwrap_data = nullptr;
/** Needed in case we need to lazily initialize the mesh. */
CustomData_MeshMasks cd_mask_extra = {};
SubdivCCG *subdiv_ccg = nullptr;
int subdiv_ccg_tot_level = 0;
/** Set by modifier stack if only deformed from original. */
bool deformed_only = false;
/**
* Copied from edit-mesh (hint, draw with edit-mesh data when true).
*
* Modifiers that edit the mesh data in-place must set this to false
* (most #eModifierTypeType_NonGeometrical modifiers). Otherwise the edit-mesh
* data will be used for drawing, missing changes from modifiers. See T79517.
*/
bool is_original_bmesh = false;
/** #eMeshWrapperType and others. */
eMeshWrapperType wrapper_type = ME_WRAPPER_TYPE_MDATA;
/**
* A type mask from wrapper_type,
* in case there are differences in finalizing logic between types.
*/
eMeshWrapperType wrapper_type_finalize = ME_WRAPPER_TYPE_MDATA;
/**
* Settings for lazily evaluating the subdivision on the CPU if needed. These are
* set in the modifier when GPU subdivision can be performed, and owned by the by
* the modifier in the object.
*/
SubsurfRuntimeData *subsurf_runtime_data = nullptr;
/**
* Caches for lazily computed vertex and polygon normals. These are stored here rather than in
* #CustomData because they can be calculated on a const mesh, and adding custom data layers on a
* const mesh is not thread-safe.
*/
bool vert_normals_dirty = false;
bool poly_normals_dirty = false;
float (*vert_normals)[3] = nullptr;
float (*poly_normals)[3] = nullptr;
/**
* A #BLI_bitmap containing tags for the center vertices of subdivided polygons, set by the
* subdivision surface modifier and used by drawing code instead of polygon center face dots.
*/
uint32_t *subsurf_face_dot_tags = nullptr;
MeshRuntime() = default;
/** \warning This does not free all data currently. See #BKE_mesh_runtime_free_data. */
~MeshRuntime() = default;
MEM_CXX_CLASS_ALLOC_FUNCS("MeshRuntime")
};
} // namespace blender::bke
#endif

View File

@ -246,6 +246,24 @@ float BKE_nlastrip_compute_frame_from_previous_strip(struct NlaStrip *strip);
*/
float BKE_nlastrip_compute_frame_to_next_strip(struct NlaStrip *strip);
/**
* Returns the next strip in this strip's NLA track, or a null pointer.
*
* \param strip The strip to find the next trip from.
* \param check_transitions Whether or not to skip transitions.
* \return The next strip in the track, or NULL if none are present.
*/
struct NlaStrip *BKE_nlastrip_next_in_track(struct NlaStrip *strip, bool skip_transitions);
/**
* Returns the previous strip in this strip's NLA track, or a null pointer.
*
* \param strip The strip to find the previous trip from.
* \param check_transitions Whether or not to skip transitions.
* \return The previous strip in the track, or NULL if none are present.
*/
struct NlaStrip *BKE_nlastrip_prev_in_track(struct NlaStrip *strip, bool skip_transitions);
/* ............ */
/**

View File

@ -125,6 +125,7 @@ typedef enum {
PBVH_UpdateTopology = 1 << 13,
PBVH_UpdateColor = 1 << 14,
PBVH_RebuildPixels = 1 << 15,
PBVH_TopologyUpdated = 1 << 16, /* Used internally by pbvh_bmesh.c */
} PBVHNodeFlags;
@ -485,7 +486,10 @@ struct GSet *BKE_pbvh_bmesh_node_faces(PBVHNode *node);
*
* Skips triangles that are hidden.
*/
void BKE_pbvh_bmesh_node_save_orig(struct BMesh *bm, PBVHNode *node);
void BKE_pbvh_bmesh_node_save_orig(struct BMesh *bm,
struct BMLog *log,
PBVHNode *node,
bool use_original);
void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh);
/* Update Bounding Box/Redraw and clear flags. */
@ -664,7 +668,8 @@ void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot);
void BKE_pbvh_node_get_bm_orco_data(PBVHNode *node,
int (**r_orco_tris)[3],
int *r_orco_tris_num,
float (**r_orco_coords)[3]);
float (**r_orco_coords)[3],
struct BMVert ***r_orco_verts);
/**
* \note doing a full search on all vertices here seems expensive,

View File

@ -35,6 +35,7 @@
#include "BKE_colorband.h"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_editmesh_cache.h"
#include "BKE_geometry_set.hh"
#include "BKE_geometry_set_instances.hh"
#include "BKE_key.h"
@ -537,7 +538,7 @@ static void mesh_calc_modifier_final_normals(const Mesh *mesh_input,
(final_datamask->lmask & CD_MASK_NORMAL) != 0);
/* Needed as `final_datamask` is not preserved outside modifier stack evaluation. */
SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime.subsurf_runtime_data;
SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime->subsurf_runtime_data;
if (subsurf_runtime_data) {
subsurf_runtime_data->calc_loop_normals = calc_loop_normals;
}
@ -585,11 +586,12 @@ static void mesh_calc_finalize(const Mesh *mesh_input, Mesh *mesh_eval)
void BKE_mesh_wrapper_deferred_finalize_mdata(Mesh *me_eval,
const CustomData_MeshMasks *cd_mask_finalize)
{
if (me_eval->runtime.wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) {
if (me_eval->runtime->wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) {
editbmesh_calc_modifier_final_normals(me_eval, cd_mask_finalize);
me_eval->runtime.wrapper_type_finalize &= ~(1 << ME_WRAPPER_TYPE_BMESH);
me_eval->runtime->wrapper_type_finalize = eMeshWrapperType(
me_eval->runtime->wrapper_type_finalize & ~(1 << ME_WRAPPER_TYPE_BMESH));
}
BLI_assert(me_eval->runtime.wrapper_type_finalize == 0);
BLI_assert(me_eval->runtime->wrapper_type_finalize == 0);
}
/**
@ -1052,7 +1054,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
append_mask.lmask |= CD_MASK_PREVIEW_MLOOPCOL;
}
mesh_final->runtime.deformed_only = false;
mesh_final->runtime->deformed_only = false;
}
isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform);
@ -1119,10 +1121,9 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
mesh_calc_finalize(mesh_input, mesh_final);
}
else {
Mesh_Runtime *runtime = &mesh_input->runtime;
blender::bke::MeshRuntime *runtime = mesh_input->runtime;
if (runtime->mesh_eval == nullptr) {
BLI_assert(runtime->eval_mutex != nullptr);
BLI_mutex_lock((ThreadMutex *)runtime->eval_mutex);
std::lock_guard lock{mesh_input->runtime->eval_mutex};
if (runtime->mesh_eval == nullptr) {
/* Not yet finalized by any instance, do it now
* Isolate since computing normals is multithreaded and we are holding a lock. */
@ -1138,7 +1139,6 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
/* Already finalized by another instance, reuse. */
mesh_final = runtime->mesh_eval;
}
BLI_mutex_unlock((ThreadMutex *)runtime->eval_mutex);
}
else if (!mesh_has_modifier_final_normals(mesh_input, &final_datamask, runtime->mesh_eval)) {
/* Modifier stack was (re-)evaluated with a request for additional normals
@ -1207,7 +1207,7 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final,
const bool calc_loop_normals = ((mesh_final->flag & ME_AUTOSMOOTH) != 0 ||
(final_datamask->lmask & CD_MASK_NORMAL) != 0);
SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime.subsurf_runtime_data;
SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime->subsurf_runtime_data;
if (subsurf_runtime_data) {
subsurf_runtime_data->calc_loop_normals = calc_loop_normals;
}
@ -1234,9 +1234,10 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final,
static void editbmesh_calc_modifier_final_normals_or_defer(
Mesh *mesh_final, const CustomData_MeshMasks *final_datamask)
{
if (mesh_final->runtime.wrapper_type != ME_WRAPPER_TYPE_MDATA) {
if (mesh_final->runtime->wrapper_type != ME_WRAPPER_TYPE_MDATA) {
/* Generated at draw time. */
mesh_final->runtime.wrapper_type_finalize = (1 << mesh_final->runtime.wrapper_type);
mesh_final->runtime->wrapper_type_finalize = eMeshWrapperType(
1 << mesh_final->runtime->wrapper_type);
return;
}
@ -1450,7 +1451,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
deformed_verts = nullptr;
}
}
mesh_final->runtime.deformed_only = false;
mesh_final->runtime->deformed_only = false;
}
if (r_cage && i == cageIndex) {
@ -1469,7 +1470,8 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
if (!BKE_mesh_runtime_ensure_edit_data(me_orig)) {
BKE_mesh_runtime_reset_edit_data(me_orig);
}
me_orig->runtime.edit_data->vertexCos = (const float(*)[3])MEM_dupallocN(deformed_verts);
me_orig->runtime->edit_data->vertexCos = (const float(*)[3])MEM_dupallocN(
deformed_verts);
}
mesh_cage = BKE_mesh_wrapper_from_editmesh_with_coords(
em_input,
@ -1583,7 +1585,7 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
* object's runtime: this could cause access freed data on depsgraph destruction (mesh who owns
* the final result might be freed prior to object). */
Mesh *mesh = (Mesh *)ob->data;
const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime.mesh_eval);
const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime->mesh_eval);
BKE_object_eval_assign_data(ob, &mesh_eval->id, is_mesh_eval_owned);
/* Add the final mesh as a non-owning component to the geometry set. */
@ -1643,7 +1645,7 @@ static void editbmesh_build_data(struct Depsgraph *depsgraph,
}
}
const bool is_mesh_eval_owned = (me_final != mesh->runtime.mesh_eval);
const bool is_mesh_eval_owned = (me_final != mesh->runtime->mesh_eval);
BKE_object_eval_assign_data(obedit, &me_final->id, is_mesh_eval_owned);
obedit->runtime.editmesh_eval_cage = me_cage;
@ -1899,7 +1901,7 @@ struct MappedUserData {
static void make_vertexcos__mapFunc(void *userData,
int index,
const float co[3],
const float UNUSED(no[3]))
const float /*no*/[3])
{
MappedUserData *mappedData = (MappedUserData *)userData;
@ -1914,7 +1916,7 @@ static void make_vertexcos__mapFunc(void *userData,
void mesh_get_mapped_verts_coords(Mesh *me_eval, float (*r_cos)[3], const int totcos)
{
if (me_eval->runtime.deformed_only == false) {
if (me_eval->runtime->deformed_only == false) {
MappedUserData userData;
memset(r_cos, 0, sizeof(*r_cos) * totcos);
userData.vertexcos = r_cos;

View File

@ -3198,7 +3198,7 @@ static void animsys_create_action_track_strip(const AnimData *adt,
* (which making new strips doesn't do due to the troublesome nature of that). */
calc_action_range(r_action_strip->act, &r_action_strip->actstart, &r_action_strip->actend, 1);
r_action_strip->start = r_action_strip->actstart;
r_action_strip->end = (IS_EQF(r_action_strip->actstart, r_action_strip->actend)) ?
r_action_strip->end = IS_EQF(r_action_strip->actstart, r_action_strip->actend) ?
(r_action_strip->actstart + 1.0f) :
(r_action_strip->actend);

View File

@ -301,12 +301,22 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data,
}
/* check if there's any point in calculating for this vert */
if (armature_weight == 0.0f) {
return;
}
if (vert_coords_prev) {
if (prevco_weight == 1.0f) {
return;
}
/* get the coord we work on */
co = vert_coords_prev ? vert_coords_prev[i] : vert_coords[i];
/* get the coord we work on */
co = vert_coords_prev[i];
}
else {
if (armature_weight == 0.0f) {
return;
}
/* get the coord we work on */
co = vert_coords[i];
}
/* Apply the object's matrix */
mul_m4_v3(data->premat, co);

View File

@ -25,7 +25,7 @@
bUserMenu *BKE_blender_user_menu_find(ListBase *lb, char space_type, const char *context)
{
LISTBASE_FOREACH (bUserMenu *, um, lb) {
if ((space_type == um->space_type) && (STREQ(context, um->context))) {
if ((space_type == um->space_type) && STREQ(context, um->context)) {
return um;
}
}

View File

@ -51,13 +51,13 @@ struct BVHCache {
* When the `r_locked` is filled and the tree could not be found the caches mutex will be
* locked. This mutex can be unlocked by calling `bvhcache_unlock`.
*
* When `r_locked` is used the `mesh_eval_mutex` must contain the `Mesh_Runtime.eval_mutex`.
* When `r_locked` is used the `mesh_eval_mutex` must contain the `MeshRuntime.eval_mutex`.
*/
static bool bvhcache_find(BVHCache **bvh_cache_p,
BVHCacheType type,
BVHTree **r_tree,
bool *r_locked,
ThreadMutex *mesh_eval_mutex)
std::mutex *mesh_eval_mutex)
{
bool do_lock = r_locked;
if (r_locked) {
@ -69,11 +69,10 @@ static bool bvhcache_find(BVHCache **bvh_cache_p,
return false;
}
/* Lazy initialization of the bvh_cache using the `mesh_eval_mutex`. */
BLI_mutex_lock(mesh_eval_mutex);
std::lock_guard lock{*mesh_eval_mutex};
if (*bvh_cache_p == nullptr) {
*bvh_cache_p = bvhcache_init();
}
BLI_mutex_unlock(mesh_eval_mutex);
}
BVHCache *bvh_cache = *bvh_cache_p;
@ -1222,8 +1221,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
const BVHCacheType bvh_cache_type,
const int tree_type)
{
BVHCache **bvh_cache_p = (BVHCache **)&mesh->runtime.bvh_cache;
ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex;
BVHCache **bvh_cache_p = (BVHCache **)&mesh->runtime->bvh_cache;
const MLoopTri *looptri = nullptr;
int looptri_len = 0;
@ -1248,7 +1246,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
bool lock_started = false;
data->cached = bvhcache_find(
bvh_cache_p, bvh_cache_type, &data->tree, &lock_started, mesh_eval_mutex);
bvh_cache_p, bvh_cache_type, &data->tree, &lock_started, &mesh->runtime->eval_mutex);
if (data->cached) {
BLI_assert(lock_started == false);
@ -1352,7 +1350,7 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
const int tree_type,
const BVHCacheType bvh_cache_type,
BVHCache **bvh_cache_p,
ThreadMutex *mesh_eval_mutex)
std::mutex *mesh_eval_mutex)
{
bool lock_started = false;

View File

@ -713,10 +713,8 @@ static bool camera_frame_fit_calc_from_data(CameraParams *params,
plane_from_point_normal_v3(plane_tx[i], co, data->plane_tx[i]);
}
if ((!isect_plane_plane_v3(
plane_tx[Y_MIN], plane_tx[Y_MAX], plane_isect_1, plane_isect_1_no)) ||
(!isect_plane_plane_v3(
plane_tx[Z_MIN], plane_tx[Z_MAX], plane_isect_2, plane_isect_2_no))) {
if (!isect_plane_plane_v3(plane_tx[Y_MIN], plane_tx[Y_MAX], plane_isect_1, plane_isect_1_no) ||
!isect_plane_plane_v3(plane_tx[Z_MIN], plane_tx[Z_MAX], plane_isect_2, plane_isect_2_no)) {
return false;
}

View File

@ -826,7 +826,7 @@ static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mes
const MLoop *mloop = BKE_mesh_loops(mesh);
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
const uint mvert_num = mesh->totvert;
const uint looptri_num = mesh->runtime.looptris.len;
const uint looptri_num = BKE_mesh_runtime_looptri_len(mesh);
/* Allocate our vertices. */
clmd->clothObject->mvert_num = mvert_num;
@ -1130,7 +1130,7 @@ static void cloth_update_springs(ClothModifierData *clmd)
* because implicit solver would need reset! */
/* Activate / Deactivate existing springs */
if ((!(cloth->verts[spring->ij].flags & CLOTH_VERT_FLAG_PINNED)) &&
if (!(cloth->verts[spring->ij].flags & CLOTH_VERT_FLAG_PINNED) &&
(cloth->verts[spring->ij].goal > ALMOST_ZERO)) {
spring->flags &= ~CLOTH_SPRING_FLAG_DEACTIVATE;
}
@ -1167,7 +1167,7 @@ static Mesh *cloth_make_rest_mesh(ClothModifierData *clmd, Mesh *mesh)
MVert *mvert = BKE_mesh_verts_for_write(mesh);
/* vertex count is already ensured to match */
for (unsigned i = 0; i < mesh->totvert; i++, verts++) {
for (uint i = 0; i < mesh->totvert; i++, verts++) {
copy_v3_v3(mvert[i].co, verts->xrest);
}
BKE_mesh_tag_coords_changed(new_mesh);

View File

@ -946,7 +946,7 @@ bool BKE_collection_has_object(Collection *collection, const Object *ob)
return false;
}
return (BLI_findptr(&collection->gobject, ob, offsetof(CollectionObject, ob)));
return BLI_findptr(&collection->gobject, ob, offsetof(CollectionObject, ob));
}
bool BKE_collection_has_object_recursive(Collection *collection, Object *ob)
@ -956,7 +956,7 @@ bool BKE_collection_has_object_recursive(Collection *collection, Object *ob)
}
const ListBase objects = BKE_collection_object_cache_get(collection);
return (BLI_findptr(&objects, ob, offsetof(Base, object)));
return BLI_findptr(&objects, ob, offsetof(Base, object));
}
bool BKE_collection_has_object_recursive_instanced(Collection *collection, Object *ob)
@ -966,7 +966,7 @@ bool BKE_collection_has_object_recursive_instanced(Collection *collection, Objec
}
const ListBase objects = BKE_collection_object_cache_instanced_get(collection);
return (BLI_findptr(&objects, ob, offsetof(Base, object)));
return BLI_findptr(&objects, ob, offsetof(Base, object));
}
static Collection *collection_next_find(Main *bmain, Scene *scene, Collection *collection)

View File

@ -1629,7 +1629,7 @@ void BKE_scopes_update(Scopes *scopes,
}
/* hmmmm */
if (!(ELEM(ibuf->channels, 3, 4))) {
if (!ELEM(ibuf->channels, 3, 4)) {
return;
}

View File

@ -635,7 +635,7 @@ ListBase CTX_data_dir_get(const bContext *C)
bool CTX_data_equals(const char *member, const char *str)
{
return (STREQ(member, str));
return STREQ(member, str);
}
bool CTX_data_dir(const char *member)

View File

@ -464,7 +464,7 @@ static std::string to_manifest(const CryptomatteLayer *layer)
else {
manifest << ",";
}
manifest << quoted(item.key) << ":\"" << (item.value.hex_encoded()) << "\"";
manifest << quoted(item.key) << ":\"" << item.value.hex_encoded() << "\"";
}
manifest << "}";
return manifest.str();

View File

@ -1935,7 +1935,7 @@ static void calc_bevel_sin_cos(
t02 = M_PI_2;
}
else {
t02 = (saacos(t02)) / 2.0f;
t02 = saacos(t02) / 2.0f;
}
t02 = sinf(t02);
@ -4085,12 +4085,12 @@ void BKE_nurb_bezt_handle_test(BezTriple *bezt,
}
if (bezt->h1 == HD_VECT) {
if ((!(flag & SEL_F1)) != (!(flag & SEL_F2))) {
if (!(flag & SEL_F1) != !(flag & SEL_F2)) {
bezt->h1 = HD_FREE;
}
}
if (bezt->h2 == HD_VECT) {
if ((!(flag & SEL_F3)) != (!(flag & SEL_F2))) {
if (!(flag & SEL_F3) != !(flag & SEL_F2)) {
bezt->h2 = HD_FREE;
}
}
@ -5101,7 +5101,7 @@ bool BKE_curve_minmax(Curve *cu, bool use_radius, float min[3], float max[3])
{
ListBase *nurb_lb = BKE_curve_nurbs_get(cu);
ListBase temp_nurb_lb = {nullptr, nullptr};
const bool is_font = (BLI_listbase_is_empty(nurb_lb)) && (cu->len != 0);
const bool is_font = BLI_listbase_is_empty(nurb_lb) && (cu->len != 0);
/* For font curves we generate temp list of splines.
*
* This is likely to be fine, this function is not supposed to be called

View File

@ -160,7 +160,7 @@ static bool calc_curve_deform(
/* Zero the axis which is not used,
* the big block of text above now applies to these 3 lines.
* The `upflag` argument may be a dummy, set so no rotation is done. */
quat_apply_track(quat, axis, (ELEM(axis, 0, 2)) ? 1 : 0);
quat_apply_track(quat, axis, ELEM(axis, 0, 2) ? 1 : 0);
vec_apply_track(cent, axis);
cent[index] = 0.0f;

View File

@ -121,7 +121,7 @@ BLI_INLINE void value_dissolve(float *r_value,
const float scale,
const bool is_log)
{
*r_value = (is_log) ? (*r_value) * (powf(MIN_WETNESS, 1.0f / (1.2f * time / scale))) :
*r_value = (is_log) ? (*r_value) * powf(MIN_WETNESS, 1.0f / (1.2f * time / scale)) :
(*r_value) - 1.0f / time * scale;
}

View File

@ -189,11 +189,11 @@ struct CageUserData {
static void cage_mapped_verts_callback(void *userData,
int index,
const float co[3],
const float UNUSED(no[3]))
const float /*no*/[3])
{
CageUserData *data = static_cast<CageUserData *>(userData);
if ((index >= 0 && index < data->totvert) && (!BLI_BITMAP_TEST(data->visit_bitmap, index))) {
if ((index >= 0 && index < data->totvert) && !BLI_BITMAP_TEST(data->visit_bitmap, index)) {
BLI_BITMAP_ENABLE(data->visit_bitmap, index);
copy_v3_v3(data->cos_cage[index], co);
}
@ -240,12 +240,12 @@ const float (*BKE_editmesh_vert_coords_when_deformed(Depsgraph *depsgraph,
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object_eval);
if ((me->runtime.edit_data != nullptr) && (me->runtime.edit_data->vertexCos != nullptr)) {
if ((me->runtime->edit_data != nullptr) && (me->runtime->edit_data->vertexCos != nullptr)) {
/* Deformed, and we have deformed coords already. */
coords = me->runtime.edit_data->vertexCos;
coords = me->runtime->edit_data->vertexCos;
}
else if ((editmesh_eval_final != nullptr) &&
(editmesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
(editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
/* If this is an edit-mesh type, leave nullptr as we can use the vertex coords. */
}
else {

View File

@ -79,7 +79,7 @@ PartDeflect *BKE_partdeflect_new(int type)
pd->pdef_sbift = 0.2f;
pd->pdef_sboft = 0.02f;
pd->pdef_cfrict = 5.0f;
pd->seed = ((uint)(ceil(PIL_check_seconds_timer())) + 1) % 128;
pd->seed = ((uint)ceil(PIL_check_seconds_timer()) + 1) % 128;
pd->f_strength = 1.0f;
pd->f_damp = 1.0f;

View File

@ -333,7 +333,7 @@ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
invert_qt_normalized(q1);
mul_qt_qtqt(quat, q1, q2);
angle = 2.0f * (saacos(quat[0]));
angle = 2.0f * saacos(quat[0]);
angle = fabsf(angle);
return (angle > (float)M_PI) ? (float)((2.0f * (float)M_PI) - angle) : (float)(angle);

View File

@ -2204,9 +2204,9 @@ static void adaptive_domain_adjust(
/* add to total shift */
add_v3_v3(fds->shift_f, frame_shift_f);
/* convert to integer */
total_shift[0] = (int)(floorf(fds->shift_f[0]));
total_shift[1] = (int)(floorf(fds->shift_f[1]));
total_shift[2] = (int)(floorf(fds->shift_f[2]));
total_shift[0] = (int)floorf(fds->shift_f[0]);
total_shift[1] = (int)floorf(fds->shift_f[1]);
total_shift[2] = (int)floorf(fds->shift_f[2]);
int temp_shift[3];
copy_v3_v3_int(temp_shift, fds->shift);
sub_v3_v3v3_int(new_shift, total_shift, fds->shift);

View File

@ -13,6 +13,7 @@
#include "BKE_geometry_set.hh"
#include "BKE_lib_id.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "FN_multi_function_builder.hh"
@ -213,11 +214,15 @@ void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
}
/* Deselect loose vertices without corners that are still selected from the 'true' default. */
for (const int vert_index : IndexRange(mesh.totvert)) {
if (loose_verts[vert_index]) {
r_values[vert_index] = false;
/* The record fact says that the value is true.
*Writing to the array from different threads is okay because each thread sets the same value. */
threading::parallel_for(loose_verts.index_range(), 2048, [&](const IndexRange range) {
for (const int vert_index : range) {
if (loose_verts[vert_index]) {
r_values[vert_index] = false;
}
}
}
});
}
static GVArray adapt_mesh_domain_corner_to_point(const Mesh &mesh, const GVArray &varray)
@ -413,16 +418,16 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh,
const Span<MLoop> loops = mesh.loops();
r_values.fill(false);
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
if (old_values[poly_index]) {
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const MLoop &loop = loops[loop_index];
const int vert_index = loop.v;
r_values[vert_index] = true;
threading::parallel_for(polys.index_range(), 2048, [&](const IndexRange range) {
for (const int poly_index : range) {
if (old_values[poly_index]) {
const MPoly &poly = polys[poly_index];
for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
r_values[loop.v] = true;
}
}
}
}
});
}
static GVArray adapt_mesh_domain_face_to_point(const Mesh &mesh, const GVArray &varray)
@ -502,16 +507,16 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh,
const Span<MLoop> loops = mesh.loops();
r_values.fill(false);
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
if (old_values[poly_index]) {
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const MLoop &loop = loops[loop_index];
const int edge_index = loop.e;
r_values[edge_index] = true;
threading::parallel_for(polys.index_range(), 2048, [&](const IndexRange range) {
for (const int poly_index : range) {
if (old_values[poly_index]) {
const MPoly &poly = polys[poly_index];
for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
r_values[loop.e] = true;
}
}
}
}
});
}
static GVArray adapt_mesh_domain_face_to_edge(const Mesh &mesh, const GVArray &varray)
@ -619,7 +624,7 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
/* For every corner, mix the values from the adjacent edges on the face. */
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const int loop_index_prev = loop_index - 1 + (loop_index == poly.loopstart) * poly.totloop;
const int loop_index_prev = mesh_topology::previous_poly_loop(poly, loop_index);
const MLoop &loop = loops[loop_index];
const MLoop &loop_prev = loops[loop_index_prev];
mixer.mix_in(loop_index, old_values[loop.e]);
@ -642,17 +647,19 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
r_values.fill(false);
for (const int poly_index : polys.index_range()) {
const MPoly &poly = polys[poly_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const int loop_index_prev = loop_index - 1 + (loop_index == poly.loopstart) * poly.totloop;
const MLoop &loop = loops[loop_index];
const MLoop &loop_prev = loops[loop_index_prev];
if (old_values[loop.e] && old_values[loop_prev.e]) {
r_values[loop_index] = true;
threading::parallel_for(polys.index_range(), 2048, [&](const IndexRange range) {
for (const int poly_index : range) {
const MPoly &poly = polys[poly_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const int loop_index_prev = mesh_topology::previous_poly_loop(poly, loop_index);
const MLoop &loop = loops[loop_index];
const MLoop &loop_prev = loops[loop_index_prev];
if (old_values[loop.e] && old_values[loop_prev.e]) {
r_values[loop_index] = true;
}
}
}
}
});
}
static GVArray adapt_mesh_domain_edge_to_corner(const Mesh &mesh, const GVArray &varray)
@ -697,14 +704,18 @@ void adapt_mesh_domain_edge_to_point_impl(const Mesh &mesh,
BLI_assert(r_values.size() == mesh.totvert);
const Span<MEdge> edges = mesh.edges();
/* Multiple threads can write to the same index here, but they are only
* writing true, and writing to single bytes is expected to be threadsafe. */
r_values.fill(false);
for (const int edge_index : edges.index_range()) {
const MEdge &edge = edges[edge_index];
if (old_values[edge_index]) {
r_values[edge.v1] = true;
r_values[edge.v2] = true;
threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) {
for (const int edge_index : range) {
if (old_values[edge_index]) {
const MEdge &edge = edges[edge_index];
r_values[edge.v1] = true;
r_values[edge.v2] = true;
}
}
}
});
}
static GVArray adapt_mesh_domain_edge_to_point(const Mesh &mesh, const GVArray &varray)

View File

@ -83,8 +83,8 @@ static void greasepencil_copy_data(Main *UNUSED(bmain),
/* Apply local layer transform to all frames. Calc the active frame is not enough
* because onion skin can use more frames. This is more slow but required here. */
if (gpl_dst->actframe != NULL) {
bool transformed = ((!is_zero_v3(gpl_dst->location)) || (!is_zero_v3(gpl_dst->rotation)) ||
(!is_one_v3(gpl_dst->scale)));
bool transformed = (!is_zero_v3(gpl_dst->location) || !is_zero_v3(gpl_dst->rotation) ||
!is_one_v3(gpl_dst->scale));
if (transformed) {
loc_eul_size_to_mat4(
gpl_dst->layer_mat, gpl_dst->location, gpl_dst->rotation, gpl_dst->scale);
@ -2013,7 +2013,7 @@ bool BKE_gpencil_merge_materials_table_get(Object *ob,
/* Read secondary material to compare with primary material. */
ma_secondary = BKE_gpencil_material(ob, idx_secondary + 1);
if ((ma_secondary == NULL) ||
(BLI_ghash_haskey(r_mat_table, POINTER_FROM_INT(idx_secondary)))) {
BLI_ghash_haskey(r_mat_table, POINTER_FROM_INT(idx_secondary))) {
continue;
}
gp_style_primary = ma_primary->gp_style;
@ -2063,17 +2063,17 @@ bool BKE_gpencil_merge_materials_table_get(Object *ob,
rgb_to_hsv_compat_v(col, f_hsv_b);
/* Check stroke and fill color. */
if ((!compare_ff(s_hsv_a[0], s_hsv_b[0], hue_threshold)) ||
(!compare_ff(s_hsv_a[1], s_hsv_b[1], sat_threshold)) ||
(!compare_ff(s_hsv_a[2], s_hsv_b[2], val_threshold)) ||
(!compare_ff(f_hsv_a[0], f_hsv_b[0], hue_threshold)) ||
(!compare_ff(f_hsv_a[1], f_hsv_b[1], sat_threshold)) ||
(!compare_ff(f_hsv_a[2], f_hsv_b[2], val_threshold)) ||
(!compare_ff(gp_style_primary->stroke_rgba[3],
gp_style_secondary->stroke_rgba[3],
val_threshold)) ||
(!compare_ff(
gp_style_primary->fill_rgba[3], gp_style_secondary->fill_rgba[3], val_threshold))) {
if (!compare_ff(s_hsv_a[0], s_hsv_b[0], hue_threshold) ||
!compare_ff(s_hsv_a[1], s_hsv_b[1], sat_threshold) ||
!compare_ff(s_hsv_a[2], s_hsv_b[2], val_threshold) ||
!compare_ff(f_hsv_a[0], f_hsv_b[0], hue_threshold) ||
!compare_ff(f_hsv_a[1], f_hsv_b[1], sat_threshold) ||
!compare_ff(f_hsv_a[2], f_hsv_b[2], val_threshold) ||
!compare_ff(gp_style_primary->stroke_rgba[3],
gp_style_secondary->stroke_rgba[3],
val_threshold) ||
!compare_ff(
gp_style_primary->fill_rgba[3], gp_style_secondary->fill_rgba[3], val_threshold)) {
continue;
}
@ -2337,7 +2337,7 @@ bool BKE_gpencil_from_image(
static bool gpencil_is_layer_mask(ViewLayer *view_layer, bGPdata *gpd, bGPDlayer *gpl_mask)
{
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
if ((gpl->viewlayername[0] != '\0') && (!STREQ(view_layer->name, gpl->viewlayername))) {
if ((gpl->viewlayername[0] != '\0') && !STREQ(view_layer->name, gpl->viewlayername)) {
continue;
}
@ -2412,7 +2412,7 @@ void BKE_gpencil_visible_stroke_advanced_iter(ViewLayer *view_layer,
int cfra)
{
bGPdata *gpd = (bGPdata *)ob->data;
const bool is_multiedit = (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) && (!GPENCIL_PLAY_ON(gpd)));
const bool is_multiedit = (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) && !GPENCIL_PLAY_ON(gpd));
const bool is_onion = do_onion && ((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0);
const bool is_drawing = (gpd->runtime.sbuffer_used > 0);
@ -2444,7 +2444,7 @@ void BKE_gpencil_visible_stroke_advanced_iter(ViewLayer *view_layer,
* generate renders, putting only selected GP layers for each View Layer.
* This is used only in final render and never in Viewport. */
if ((view_layer != NULL) && (gpl->viewlayername[0] != '\0') &&
(!STREQ(view_layer->name, gpl->viewlayername))) {
!STREQ(view_layer->name, gpl->viewlayername)) {
/* Do not skip masks when rendering the view-layer so that it can still be used to clip
* other layers. Instead set their opacity to zero. */
if (gpencil_is_layer_mask(view_layer, gpd, gpl)) {
@ -2786,8 +2786,8 @@ void BKE_gpencil_update_layer_transforms(const Depsgraph *depsgraph, Object *ob)
}
/* Calc local layer transform. Early out if we have non-animated zero transforms. */
bool transformed = ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) ||
(!is_one_v3(gpl->scale)));
bool transformed = (!is_zero_v3(gpl->location) || !is_zero_v3(gpl->rotation) ||
!is_one_v3(gpl->scale));
float tmp_mat[4][4];
loc_eul_size_to_mat4(tmp_mat, gpl->location, gpl->rotation, gpl->scale);
transformed |= !equals_m4m4(gpl->layer_mat, tmp_mat);
@ -2834,7 +2834,7 @@ int BKE_gpencil_material_find_index_by_name_prefix(Object *ob, const char *name_
for (int i = 0; i < ob->totcol; i++) {
Material *ma = BKE_object_material_get(ob, i + 1);
if ((ma != NULL) && (ma->gp_style != NULL) &&
(STREQLEN(ma->id.name + 2, name_prefix, name_prefix_len))) {
STREQLEN(ma->id.name + 2, name_prefix, name_prefix_len)) {
return i;
}
}

View File

@ -1856,6 +1856,10 @@ bool BKE_gpencil_stroke_close(bGPDstroke *gps)
pt->strength = interpf(pt2->strength, pt1->strength, step);
pt->flag = 0;
interp_v4_v4v4(pt->vert_color, pt1->vert_color, pt2->vert_color, step);
/* Set point as selected. */
if (gps->flag & GP_STROKE_SELECT) {
pt->flag |= GP_SPOINT_SELECT;
}
/* Set weights. */
if (gps->dvert != nullptr) {

View File

@ -722,8 +722,8 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
}
/* Only do layer transformations for non-zero or animated transforms. */
bool transformed = ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) ||
(!is_one_v3(gpl->scale)));
bool transformed = (!is_zero_v3(gpl->location) || !is_zero_v3(gpl->rotation) ||
!is_one_v3(gpl->scale));
float tmp_mat[4][4];
loc_eul_size_to_mat4(tmp_mat, gpl->location, gpl->rotation, gpl->scale);
transformed |= !equals_m4m4(gpl->layer_mat, tmp_mat);
@ -752,7 +752,7 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd_orig);
const bool do_modifiers = (bool)((!is_multiedit) && (!is_curve_edit) &&
(ob_orig->greasepencil_modifiers.first != NULL) &&
(!GPENCIL_SIMPLIFY_MODIF(scene)));
!GPENCIL_SIMPLIFY_MODIF(scene));
if ((!do_modifiers) && (!do_parent) && (!do_transform)) {
BLI_assert(ob->data != NULL);
return;
@ -782,7 +782,7 @@ void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
const bool is_multiedit = (bool)(GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) && !is_render);
const bool do_modifiers = (bool)((!is_multiedit) && (!is_curve_edit) &&
(ob->greasepencil_modifiers.first != NULL) &&
(!GPENCIL_SIMPLIFY_MODIF(scene)));
!GPENCIL_SIMPLIFY_MODIF(scene));
if (!do_modifiers) {
return;
}

View File

@ -520,7 +520,7 @@ static bool do_add_image_extension(char *string,
}
#endif
else { // R_IMF_IMTYPE_AVIRAW, R_IMF_IMTYPE_AVIJPEG, R_IMF_IMTYPE_JPEG90 etc
if (!(BLI_path_extension_check_n(string, extension_test = ".jpg", ".jpeg", nullptr))) {
if (!BLI_path_extension_check_n(string, extension_test = ".jpg", ".jpeg", nullptr)) {
extension = extension_test;
}
}

View File

@ -824,7 +824,7 @@ bool BKE_image_render_write_exr(ReportList *reports,
/* We only store RGBA passes as half float, for
* others precision loss can be problematic. */
const bool pass_RGBA = (STR_ELEM(rp->chan_id, "RGB", "RGBA", "R", "G", "B", "A"));
const bool pass_RGBA = STR_ELEM(rp->chan_id, "RGB", "RGBA", "R", "G", "B", "A");
const bool pass_half_float = half_float && pass_RGBA;
/* Color-space conversion only happens on RGBA passes. */

View File

@ -1542,7 +1542,7 @@ static void icu_to_fcurves(ID *id,
}
/* correct values, by checking if the flag of interest is set */
if (((int)(dst->vec[1][1])) & (abp->bit)) {
if ((int)(dst->vec[1][1]) & (abp->bit)) {
dst->vec[0][1] = dst->vec[1][1] = dst->vec[2][1] = 1.0f;
}
else {

View File

@ -1282,8 +1282,8 @@ BLI_INLINE uint layer_bucket_index_from_xy(MaskRasterLayer *layer, const float x
{
BLI_assert(BLI_rctf_isect_pt_v(&layer->bounds, xy));
return ((uint)((xy[0] - layer->bounds.xmin) * layer->buckets_xy_scalar[0])) +
(((uint)((xy[1] - layer->bounds.ymin) * layer->buckets_xy_scalar[1])) * layer->buckets_x);
return (uint)((xy[0] - layer->bounds.xmin) * layer->buckets_xy_scalar[0]) +
((uint)((xy[1] - layer->bounds.ymin) * layer->buckets_xy_scalar[1]) * layer->buckets_x);
}
static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2])

View File

@ -297,7 +297,7 @@ bool BKE_mball_is_basis(const Object *ob)
/* Just a quick test. */
const int len = strlen(ob->id.name);
return (!isdigit(ob->id.name[len - 1]));
return !isdigit(ob->id.name[len - 1]);
}
bool BKE_mball_is_same_group(const Object *ob1, const Object *ob2)

View File

@ -1498,7 +1498,7 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
for (int i = 0; i < mesh->totvert; i++) {
normalize_v3(process.no[i]);
}
mesh->runtime.vert_normals = process.no;
mesh->runtime->vert_normals = process.no;
BKE_mesh_vertex_normals_clear_dirty(mesh);
mesh->totloop = loop_offset;

Some files were not shown because too many files have changed in this diff Show More