Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2021-08-17 12:30:58 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2021-08-17 12:30:58 +0300
commit96f5f20d53e4234b89d471a64f52002c838d85fa (patch)
treeb8b74e6aee79e6538f1acbb5e499a7ec3d360bf5 /intern
parentf3d502bf63fc7c98ccce87f109947805fb28b91e (diff)
parentf8dd0080a9c490b017a95857ff750e79d4c6943a (diff)
Merge branch 'master' into cycles_procedural_api
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/blender_python.cpp107
-rw-r--r--intern/cycles/blender/blender_shader.cpp93
-rw-r--r--intern/cycles/blender/blender_util.h2
-rw-r--r--intern/ghost/GHOST_Types.h9
-rw-r--r--intern/ghost/intern/GHOST_ContextD3D.cpp15
-rw-r--r--intern/ghost/intern/GHOST_ContextD3D.h8
-rw-r--r--intern/ghost/intern/GHOST_IXrGraphicsBinding.h1
-rw-r--r--intern/ghost/intern/GHOST_ImeWin32.cpp199
-rw-r--r--intern/ghost/intern/GHOST_ImeWin32.h35
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm2
-rw-r--r--intern/ghost/intern/GHOST_XrGraphicsBinding.cpp103
-rw-r--r--intern/ghost/intern/GHOST_XrSession.cpp1
-rw-r--r--intern/ghost/intern/GHOST_XrSwapchain.cpp12
-rw-r--r--intern/ghost/intern/GHOST_XrSwapchain.h4
-rw-r--r--intern/guardedalloc/intern/mallocn_guarded_impl.c2
15 files changed, 357 insertions, 236 deletions
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index fb153d8a343..486d1f67621 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -491,6 +491,24 @@ static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
if (param->varlenarray || param->isstruct || param->type.arraylen > 1)
continue;
+ /* Read metadata. */
+ bool is_bool_param = false;
+ ustring param_label = param->name;
+
+ for (const OSL::OSLQuery::Parameter &metadata : param->metadata) {
+ if (metadata.type == TypeDesc::STRING) {
+ if (metadata.name == "widget") {
+ /* Boolean socket. */
+ if (metadata.sdefault[0] == "boolean" || metadata.sdefault[0] == "checkBox") {
+ is_bool_param = true;
+ }
+ }
+ else if (metadata.name == "label") {
+ /* Socket label. */
+ param_label = metadata.sdefault[0];
+ }
+ }
+ }
/* determine socket type */
string socket_type;
BL::NodeSocket::type_enum data_type = BL::NodeSocket::type_VALUE;
@@ -498,6 +516,7 @@ static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
float default_float = 0.0f;
int default_int = 0;
string default_string = "";
+ bool default_boolean = false;
if (param->isclosure) {
socket_type = "NodeSocketShader";
@@ -527,10 +546,19 @@ static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
}
else if (param->type.aggregate == TypeDesc::SCALAR) {
if (param->type.basetype == TypeDesc::INT) {
- socket_type = "NodeSocketInt";
- data_type = BL::NodeSocket::type_INT;
- if (param->validdefault)
- default_int = param->idefault[0];
+ if (is_bool_param) {
+ socket_type = "NodeSocketBool";
+ data_type = BL::NodeSocket::type_BOOLEAN;
+ if (param->validdefault) {
+ default_boolean = (bool)param->idefault[0];
+ }
+ }
+ else {
+ socket_type = "NodeSocketInt";
+ data_type = BL::NodeSocket::type_INT;
+ if (param->validdefault)
+ default_int = param->idefault[0];
+ }
}
else if (param->type.basetype == TypeDesc::FLOAT) {
socket_type = "NodeSocketFloat";
@@ -550,33 +578,57 @@ static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
else
continue;
- /* find socket socket */
- BL::NodeSocket b_sock(PointerRNA_NULL);
+ /* Update existing socket. */
+ bool found_existing = false;
if (param->isoutput) {
- b_sock = b_node.outputs[param->name.string()];
- /* remove if type no longer matches */
- if (b_sock && b_sock.bl_idname() != socket_type) {
- b_node.outputs.remove(b_data, b_sock);
- b_sock = BL::NodeSocket(PointerRNA_NULL);
+ for (BL::NodeSocket &b_sock : b_node.outputs) {
+ if (b_sock.identifier() == param->name) {
+ if (b_sock.bl_idname() != socket_type) {
+ /* Remove if type no longer matches. */
+ b_node.outputs.remove(b_data, b_sock);
+ }
+ else {
+ /* Reuse and update label. */
+ if (b_sock.name() != param_label) {
+ b_sock.name(param_label.string());
+ }
+ used_sockets.insert(b_sock.ptr.data);
+ found_existing = true;
+ }
+ break;
+ }
}
}
else {
- b_sock = b_node.inputs[param->name.string()];
- /* remove if type no longer matches */
- if (b_sock && b_sock.bl_idname() != socket_type) {
- b_node.inputs.remove(b_data, b_sock);
- b_sock = BL::NodeSocket(PointerRNA_NULL);
+ for (BL::NodeSocket &b_sock : b_node.inputs) {
+ if (b_sock.identifier() == param->name) {
+ if (b_sock.bl_idname() != socket_type) {
+ /* Remove if type no longer matches. */
+ b_node.inputs.remove(b_data, b_sock);
+ }
+ else {
+ /* Reuse and update label. */
+ if (b_sock.name() != param_label) {
+ b_sock.name(param_label.string());
+ }
+ used_sockets.insert(b_sock.ptr.data);
+ found_existing = true;
+ }
+ break;
+ }
}
}
- if (!b_sock) {
- /* create new socket */
- if (param->isoutput)
- b_sock = b_node.outputs.create(
- b_data, socket_type.c_str(), param->name.c_str(), param->name.c_str());
- else
- b_sock = b_node.inputs.create(
- b_data, socket_type.c_str(), param->name.c_str(), param->name.c_str());
+ if (!found_existing) {
+ /* Create new socket. */
+ BL::NodeSocket b_sock = (param->isoutput) ? b_node.outputs.create(b_data,
+ socket_type.c_str(),
+ param_label.c_str(),
+ param->name.c_str()) :
+ b_node.inputs.create(b_data,
+ socket_type.c_str(),
+ param_label.c_str(),
+ param->name.c_str());
/* set default value */
if (data_type == BL::NodeSocket::type_VALUE) {
@@ -594,9 +646,12 @@ static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
else if (data_type == BL::NodeSocket::type_STRING) {
set_string(b_sock.ptr, "default_value", default_string);
}
- }
+ else if (data_type == BL::NodeSocket::type_BOOLEAN) {
+ set_boolean(b_sock.ptr, "default_value", default_boolean);
+ }
- used_sockets.insert(b_sock.ptr.data);
+ used_sockets.insert(b_sock.ptr.data);
+ }
}
/* remove unused parameters */
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 7f129310736..24819bacbb5 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -149,7 +149,7 @@ BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_r
static BL::NodeSocket get_node_output(BL::Node &b_node, const string &name)
{
for (BL::NodeSocket &b_out : b_node.outputs) {
- if (b_out.name() == name) {
+ if (b_out.identifier() == name) {
return b_out;
}
}
@@ -215,7 +215,12 @@ static void set_default_value(ShaderInput *input,
break;
}
case SocketType::INT: {
- node->set(socket, get_int(b_sock.ptr, "default_value"));
+ if (b_sock.type() == BL::NodeSocket::type_BOOLEAN) {
+ node->set(socket, get_boolean(b_sock.ptr, "default_value"));
+ }
+ else {
+ node->set(socket, get_int(b_sock.ptr, "default_value"));
+ }
break;
}
case SocketType::COLOR: {
@@ -1002,71 +1007,51 @@ static bool node_use_modified_socket_name(ShaderNode *node)
return true;
}
-static ShaderInput *node_find_input_by_name(ShaderNode *node,
- BL::Node &b_node,
- BL::NodeSocket &b_socket)
+static ShaderInput *node_find_input_by_name(ShaderNode *node, BL::NodeSocket &b_socket)
{
- string name = b_socket.name();
+ string name = b_socket.identifier();
+ ShaderInput *input = node->input(name.c_str());
- if (node_use_modified_socket_name(node)) {
- bool found = false;
- int counter = 0, total = 0;
+ if (!input && node_use_modified_socket_name(node)) {
+ /* Different internal name for shader. */
+ if (string_startswith(name, "Shader")) {
+ string_replace(name, "Shader", "Closure");
+ }
+ input = node->input(name.c_str());
- for (BL::NodeSocket &b_input : b_node.inputs) {
- if (b_input.name() == name) {
- if (!found) {
- counter++;
- }
- total++;
+ if (!input) {
+ /* Different internal numbering of two sockets with same name. */
+ if (string_endswith(name, "_001")) {
+ string_replace(name, "_001", "2");
+ }
+ else if (string_endswith(name, "_002")) {
+ string_replace(name, "_002", "3");
+ }
+ else {
+ name += "1";
}
- if (b_input.ptr.data == b_socket.ptr.data)
- found = true;
+ input = node->input(name.c_str());
}
-
- /* rename if needed */
- if (name == "Shader")
- name = "Closure";
-
- if (total > 1)
- name = string_printf("%s%d", name.c_str(), counter);
}
- return node->input(name.c_str());
+ return input;
}
-static ShaderOutput *node_find_output_by_name(ShaderNode *node,
- BL::Node &b_node,
- BL::NodeSocket &b_socket)
+static ShaderOutput *node_find_output_by_name(ShaderNode *node, BL::NodeSocket &b_socket)
{
- string name = b_socket.name();
-
- if (node_use_modified_socket_name(node)) {
- bool found = false;
- int counter = 0, total = 0;
-
- for (BL::NodeSocket &b_output : b_node.outputs) {
- if (b_output.name() == name) {
- if (!found) {
- counter++;
- }
- total++;
- }
+ string name = b_socket.identifier();
+ ShaderOutput *output = node->output(name.c_str());
- if (b_output.ptr.data == b_socket.ptr.data) {
- found = true;
- }
- }
-
- /* rename if needed */
- if (name == "Shader")
+ if (!output && node_use_modified_socket_name(node)) {
+ /* Different internal name for shader. */
+ if (name == "Shader") {
name = "Closure";
-
- if (total > 1)
- name = string_printf("%s%d", name.c_str(), counter);
+ output = node->output(name.c_str());
+ }
}
- return node->output(name.c_str());
+ return output;
}
static void add_nodes(Scene *scene,
@@ -1209,7 +1194,7 @@ static void add_nodes(Scene *scene,
if (node) {
/* map node sockets for linking */
for (BL::NodeSocket &b_input : b_node.inputs) {
- ShaderInput *input = node_find_input_by_name(node, b_node, b_input);
+ ShaderInput *input = node_find_input_by_name(node, b_input);
if (!input) {
/* XXX should not happen, report error? */
continue;
@@ -1219,7 +1204,7 @@ static void add_nodes(Scene *scene,
set_default_value(input, b_input, b_data, b_ntree);
}
for (BL::NodeSocket &b_output : b_node.outputs) {
- ShaderOutput *output = node_find_output_by_name(node, b_node, b_output);
+ ShaderOutput *output = node_find_output_by_name(node, b_output);
if (!output) {
/* XXX should not happen, report error? */
continue;
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index cfd30d44cb6..da89592c2ea 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -145,7 +145,7 @@ static inline void curvemapping_minmax(/*const*/ BL::CurveMapping &cumap,
float *min_x,
float *max_x)
{
- /* const int num_curves = cumap.curves.length(); */ /* Gives linking error so far. */
+ // const int num_curves = cumap.curves.length(); /* Gives linking error so far. */
const int num_curves = rgb_curve ? 4 : 3;
*min_x = FLT_MAX;
*max_x = -FLT_MAX;
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index fb19b9535ad..e46f712cb64 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -669,6 +669,14 @@ typedef struct {
void *exit_customdata;
} GHOST_XrSessionBeginInfo;
+/** Texture format for XR swapchain. */
+typedef enum GHOST_TXrSwapchainFormat {
+ GHOST_kXrSwapchainFormatRGBA8,
+ GHOST_kXrSwapchainFormatRGBA16,
+ GHOST_kXrSwapchainFormatRGBA16F,
+ GHOST_kXrSwapchainFormatRGB10_A2,
+} GHOST_TXrSwapchainFormat;
+
typedef struct GHOST_XrDrawViewInfo {
int ofsx, ofsy;
int width, height;
@@ -681,6 +689,7 @@ typedef struct GHOST_XrDrawViewInfo {
float angle_up, angle_down;
} fov;
+ GHOST_TXrSwapchainFormat swapchain_format;
/** Set if the buffer should be submitted with a SRGB transfer applied. */
char expects_srgb_buffer;
diff --git a/intern/ghost/intern/GHOST_ContextD3D.cpp b/intern/ghost/intern/GHOST_ContextD3D.cpp
index ad948578d53..73f6c12e100 100644
--- a/intern/ghost/intern/GHOST_ContextD3D.cpp
+++ b/intern/ghost/intern/GHOST_ContextD3D.cpp
@@ -132,6 +132,7 @@ class GHOST_SharedOpenGLResource {
ID3D11DeviceContext *device_ctx,
unsigned int width,
unsigned int height,
+ DXGI_FORMAT format,
ID3D11RenderTargetView *render_target = nullptr)
: m_device(device), m_device_ctx(device_ctx), m_cur_width(width), m_cur_height(height)
{
@@ -144,7 +145,7 @@ class GHOST_SharedOpenGLResource {
texDesc.Width = width;
texDesc.Height = height;
- texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ texDesc.Format = format;
texDesc.SampleDesc.Count = 1;
texDesc.ArraySize = 1;
texDesc.MipLevels = 1;
@@ -321,7 +322,10 @@ class GHOST_SharedOpenGLResource {
};
GHOST_SharedOpenGLResource *GHOST_ContextD3D::createSharedOpenGLResource(
- unsigned int width, unsigned int height, ID3D11RenderTargetView *render_target)
+ unsigned int width,
+ unsigned int height,
+ DXGI_FORMAT format,
+ ID3D11RenderTargetView *render_target)
{
if (!(WGL_NV_DX_interop && WGL_NV_DX_interop2)) {
fprintf(stderr,
@@ -330,14 +334,15 @@ GHOST_SharedOpenGLResource *GHOST_ContextD3D::createSharedOpenGLResource(
return nullptr;
}
GHOST_SharedOpenGLResource *shared_res = new GHOST_SharedOpenGLResource(
- m_device, m_device_ctx, width, height, render_target);
+ m_device, m_device_ctx, width, height, format, render_target);
return shared_res;
}
GHOST_SharedOpenGLResource *GHOST_ContextD3D::createSharedOpenGLResource(unsigned int width,
- unsigned int height)
+ unsigned int height,
+ DXGI_FORMAT format)
{
- return createSharedOpenGLResource(width, height, nullptr);
+ return createSharedOpenGLResource(width, height, format, nullptr);
}
void GHOST_ContextD3D::disposeSharedOpenGLResource(GHOST_SharedOpenGLResource *shared_res)
diff --git a/intern/ghost/intern/GHOST_ContextD3D.h b/intern/ghost/intern/GHOST_ContextD3D.h
index 8b9537ca439..c18c9d3c286 100644
--- a/intern/ghost/intern/GHOST_ContextD3D.h
+++ b/intern/ghost/intern/GHOST_ContextD3D.h
@@ -106,9 +106,13 @@ class GHOST_ContextD3D : public GHOST_Context {
}
class GHOST_SharedOpenGLResource *createSharedOpenGLResource(
- unsigned int width, unsigned int height, ID3D11RenderTargetView *render_target);
+ unsigned int width,
+ unsigned int height,
+ DXGI_FORMAT format,
+ ID3D11RenderTargetView *render_target);
class GHOST_SharedOpenGLResource *createSharedOpenGLResource(unsigned int width,
- unsigned int height);
+ unsigned int height,
+ DXGI_FORMAT format);
void disposeSharedOpenGLResource(class GHOST_SharedOpenGLResource *shared_res);
GHOST_TSuccess blitFromOpenGLContext(class GHOST_SharedOpenGLResource *shared_res,
unsigned int width,
diff --git a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
index a7339158dc4..bfdf0cac633 100644
--- a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
+++ b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
@@ -60,6 +60,7 @@ class GHOST_IXrGraphicsBinding {
std::string *r_requirement_info) const = 0;
virtual void initFromGhostContext(class GHOST_Context &ghost_ctx) = 0;
virtual std::optional<int64_t> chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
+ GHOST_TXrSwapchainFormat &r_format,
bool &r_is_rgb_format) const = 0;
virtual std::vector<XrSwapchainImageBaseHeader *> createSwapchainImages(
uint32_t image_count) = 0;
diff --git a/intern/ghost/intern/GHOST_ImeWin32.cpp b/intern/ghost/intern/GHOST_ImeWin32.cpp
index 343f4d68078..47b5f5688df 100644
--- a/intern/ghost/intern/GHOST_ImeWin32.cpp
+++ b/intern/ghost/intern/GHOST_ImeWin32.cpp
@@ -30,9 +30,15 @@
# include "GHOST_WindowWin32.h"
# include "utfconv.h"
+/* ISO_639-1 2-Letter Abbreviations. */
+# define IMELANG_ENGLISH "en"
+# define IMELANG_CHINESE "zh"
+# define IMELANG_JAPANESE "ja"
+# define IMELANG_KOREAN "ko"
+
GHOST_ImeWin32::GHOST_ImeWin32()
: is_composing_(false),
- input_language_id_(LANG_USER_DEFAULT),
+ language_(IMELANG_ENGLISH),
conversion_modes_(IME_CMODE_ALPHANUMERIC),
sentence_mode_(IME_SMODE_NONE),
system_caret_(false),
@@ -48,16 +54,21 @@ GHOST_ImeWin32::~GHOST_ImeWin32()
void GHOST_ImeWin32::UpdateInputLanguage()
{
- /**
- * Store the current input language.
- */
- HKL input_locale = ::GetKeyboardLayout(0);
- input_language_id_ = LOWORD(input_locale);
+ /* Get the current input locale full name. */
+ WCHAR locale[LOCALE_NAME_MAX_LENGTH];
+ LCIDToLocaleName(
+ MAKELCID(LOWORD(::GetKeyboardLayout(0)), SORT_DEFAULT), locale, LOCALE_NAME_MAX_LENGTH, 0);
+ /* Get the 2-letter ISO-63901 abbreviation of the input locale name. */
+ WCHAR language_u16[W32_ISO639_LEN];
+ GetLocaleInfoEx(locale, LOCALE_SISO639LANGNAME, language_u16, W32_ISO639_LEN);
+ /* Store this as a UTF-8 string. */
+ WideCharToMultiByte(
+ CP_UTF8, 0, language_u16, W32_ISO639_LEN, language_, W32_ISO639_LEN, NULL, NULL);
}
-WORD GHOST_ImeWin32::GetInputLanguage()
+BOOL GHOST_ImeWin32::IsLanguage(const char name[W32_ISO639_LEN])
{
- return input_language_id_;
+ return (strcmp(name, language_) == 0);
}
void GHOST_ImeWin32::UpdateConversionStatus(HWND window_handle)
@@ -92,21 +103,11 @@ bool GHOST_ImeWin32::IsImeKeyEvent(char ascii)
if ((ascii >= 'A' && ascii <= 'Z') || (ascii >= 'a' && ascii <= 'z')) {
return true;
}
- switch (PRIMARYLANGID(GetInputLanguage())) {
- /* In Japanese, all symbolic characters are also processed by IME. */
- case LANG_JAPANESE: {
- if (ascii >= ' ' && ascii <= '~') {
- return true;
- }
- break;
- }
- /* In Chinese, some symbolic characters are also processed by IME. */
- case LANG_CHINESE: {
- if (ascii && strchr("!\"$'(),.:;<>?[\\]^_`", ascii)) {
- return true;
- }
- break;
- }
+ if (IsLanguage(IMELANG_JAPANESE) && (ascii >= ' ' && ascii <= '~')) {
+ return true;
+ }
+ else if (IsLanguage(IMELANG_CHINESE) && ascii && strchr("!\"$'(),.:;<>?[\\]^_`", ascii)) {
+ return true;
}
}
return false;
@@ -126,13 +127,8 @@ void GHOST_ImeWin32::CreateImeWindow(HWND window_handle)
* Since some third-party Japanese IME also uses ::GetCaretPos() to determine
* their window position, we also create a caret for Japanese IMEs.
*/
- if (PRIMARYLANGID(input_language_id_) == LANG_CHINESE ||
- PRIMARYLANGID(input_language_id_) == LANG_JAPANESE) {
- if (!system_caret_) {
- if (::CreateCaret(window_handle, NULL, 1, 1)) {
- system_caret_ = true;
- }
- }
+ if (!system_caret_ && (IsLanguage(IMELANG_CHINESE) || IsLanguage(IMELANG_JAPANESE))) {
+ system_caret_ = ::CreateCaret(window_handle, NULL, 1, 1);
}
/* Restore the positions of the IME windows. */
UpdateImeWindow(window_handle);
@@ -185,16 +181,9 @@ void GHOST_ImeWin32::MoveImeWindow(HWND window_handle, HIMC imm_context)
CANDIDATEFORM candidate_position = {0, CFS_CANDIDATEPOS, {x, y}, {0, 0, 0, 0}};
::ImmSetCandidateWindow(imm_context, &candidate_position);
if (system_caret_) {
- switch (PRIMARYLANGID(input_language_id_)) {
- case LANG_JAPANESE:
- ::SetCaretPos(x, y + caret_rect_.getHeight());
- break;
- default:
- ::SetCaretPos(x, y);
- break;
- }
+ ::SetCaretPos(x, y);
}
- if (PRIMARYLANGID(input_language_id_) == LANG_KOREAN) {
+ if (IsLanguage(IMELANG_KOREAN)) {
/**
* Chinese IMEs and Japanese IMEs require the upper-left corner of
* the caret to move the position of their candidate windows.
@@ -284,83 +273,79 @@ void GHOST_ImeWin32::GetCaret(HIMC imm_context, LPARAM lparam, ImeComposition *c
*/
int target_start = -1;
int target_end = -1;
- switch (PRIMARYLANGID(input_language_id_)) {
- case LANG_KOREAN:
- if (lparam & CS_NOMOVECARET) {
- target_start = 0;
- target_end = 1;
+ if (IsLanguage(IMELANG_KOREAN)) {
+ if (lparam & CS_NOMOVECARET) {
+ target_start = 0;
+ target_end = 1;
+ }
+ }
+ else if (IsLanguage(IMELANG_CHINESE)) {
+ int clause_size = ImmGetCompositionStringW(imm_context, GCS_COMPCLAUSE, NULL, 0);
+ if (clause_size) {
+ static std::vector<unsigned long> clauses;
+ clause_size = clause_size / sizeof(clauses[0]);
+ clauses.resize(clause_size);
+ ImmGetCompositionStringW(
+ imm_context, GCS_COMPCLAUSE, &clauses[0], sizeof(clauses[0]) * clause_size);
+ if (composition->cursor_position == composition->ime_string.size()) {
+ target_start = clauses[clause_size - 2];
+ target_end = clauses[clause_size - 1];
}
- break;
- case LANG_CHINESE: {
- int clause_size = ImmGetCompositionStringW(imm_context, GCS_COMPCLAUSE, NULL, 0);
- if (clause_size) {
- static std::vector<unsigned long> clauses;
- clause_size = clause_size / sizeof(clauses[0]);
- clauses.resize(clause_size);
- ImmGetCompositionStringW(
- imm_context, GCS_COMPCLAUSE, &clauses[0], sizeof(clauses[0]) * clause_size);
- if (composition->cursor_position == composition->ime_string.size()) {
- target_start = clauses[clause_size - 2];
- target_end = clauses[clause_size - 1];
- }
- else {
- for (int i = 0; i < clause_size - 1; i++) {
- if (clauses[i] == composition->cursor_position) {
- target_start = clauses[i];
- target_end = clauses[i + 1];
- break;
- }
+ else {
+ for (int i = 0; i < clause_size - 1; i++) {
+ if (clauses[i] == composition->cursor_position) {
+ target_start = clauses[i];
+ target_end = clauses[i + 1];
+ break;
}
}
}
- else {
- if (composition->cursor_position != -1) {
- target_start = composition->cursor_position;
- target_end = composition->ime_string.size();
- }
+ }
+ else {
+ if (composition->cursor_position != -1) {
+ target_start = composition->cursor_position;
+ target_end = composition->ime_string.size();
}
- break;
}
- case LANG_JAPANESE:
-
- /**
- * For Japanese IMEs, the robustest way to retrieve the caret
- * is scanning the attribute of the latest composition string and
- * retrieving the beginning and the end of the target clause, i.e.
- * a clause being converted.
- */
- if (lparam & GCS_COMPATTR) {
- int attribute_size = ::ImmGetCompositionStringW(imm_context, GCS_COMPATTR, NULL, 0);
- if (attribute_size > 0) {
- char *attribute_data = new char[attribute_size];
- if (attribute_data) {
- ::ImmGetCompositionStringW(imm_context, GCS_COMPATTR, attribute_data, attribute_size);
- for (target_start = 0; target_start < attribute_size; ++target_start) {
- if (IsTargetAttribute(attribute_data[target_start]))
- break;
- }
- for (target_end = target_start; target_end < attribute_size; ++target_end) {
- if (!IsTargetAttribute(attribute_data[target_end]))
- break;
- }
- if (target_start == attribute_size) {
- /**
- * This composition clause does not contain any target clauses,
- * i.e. this clauses is an input clause.
- * We treat whole this clause as a target clause.
- */
- target_end = target_start;
- target_start = 0;
- }
- if (target_start != -1 && target_start < attribute_size &&
- attribute_data[target_start] == ATTR_TARGET_NOTCONVERTED) {
- composition->cursor_position = target_start;
- }
+ }
+ else if (IsLanguage(IMELANG_JAPANESE)) {
+ /**
+ * For Japanese IMEs, the robustest way to retrieve the caret
+ * is scanning the attribute of the latest composition string and
+ * retrieving the beginning and the end of the target clause, i.e.
+ * a clause being converted.
+ */
+ if (lparam & GCS_COMPATTR) {
+ int attribute_size = ::ImmGetCompositionStringW(imm_context, GCS_COMPATTR, NULL, 0);
+ if (attribute_size > 0) {
+ char *attribute_data = new char[attribute_size];
+ if (attribute_data) {
+ ::ImmGetCompositionStringW(imm_context, GCS_COMPATTR, attribute_data, attribute_size);
+ for (target_start = 0; target_start < attribute_size; ++target_start) {
+ if (IsTargetAttribute(attribute_data[target_start]))
+ break;
+ }
+ for (target_end = target_start; target_end < attribute_size; ++target_end) {
+ if (!IsTargetAttribute(attribute_data[target_end]))
+ break;
+ }
+ if (target_start == attribute_size) {
+ /**
+ * This composition clause does not contain any target clauses,
+ * i.e. this clauses is an input clause.
+ * We treat whole this clause as a target clause.
+ */
+ target_end = target_start;
+ target_start = 0;
+ }
+ if (target_start != -1 && target_start < attribute_size &&
+ attribute_data[target_start] == ATTR_TARGET_NOTCONVERTED) {
+ composition->cursor_position = target_start;
}
- delete[] attribute_data;
}
+ delete[] attribute_data;
}
- break;
+ }
}
composition->target_start = target_start;
composition->target_end = target_end;
diff --git a/intern/ghost/intern/GHOST_ImeWin32.h b/intern/ghost/intern/GHOST_ImeWin32.h
index d430a7d745d..ce0e4d64d53 100644
--- a/intern/ghost/intern/GHOST_ImeWin32.h
+++ b/intern/ghost/intern/GHOST_ImeWin32.h
@@ -36,6 +36,9 @@
# include "GHOST_Rect.h"
# include <vector>
+/* MSDN LOCALE_SISO639LANGNAME states maximum length of 9, including terminating null. */
+# define W32_ISO639_LEN 9
+
class GHOST_EventIME : public GHOST_Event {
public:
/**
@@ -146,13 +149,10 @@ class GHOST_ImeWin32 {
return is_composing_;
}
- /**
- * Retrieves the input language from Windows and update it.
- */
+ /* Retrieve the input language from Windows and store it. */
void UpdateInputLanguage();
- /* Returns the current input language id. */
- WORD GetInputLanguage();
+ BOOL IsLanguage(const char name[W32_ISO639_LEN]);
/* Saves the current conversion status. */
void UpdateConversionStatus(HWND window_handle);
@@ -345,29 +345,8 @@ class GHOST_ImeWin32 {
*/
bool is_composing_;
- /**
- * The current input Language ID retrieved from Windows, which consists of:
- * * Primary Language ID (bit 0 to bit 9), which shows a natural language
- * (English, Korean, Chinese, Japanese, etc.) and;
- * * Sub-Language ID (bit 10 to bit 15), which shows a geometrical region
- * the language is spoken (For English, United States, United Kingdom,
- * Australia, Canada, etc.)
- * The following list enumerates some examples for the Language ID:
- * * "en-US" (0x0409)
- * MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
- * * "ko-KR" (0x0412)
- * MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN);
- * * "zh-TW" (0x0404)
- * MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL);
- * * "zh-CN" (0x0804)
- * MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED);
- * * "ja-JP" (0x0411)
- * MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), etc.
- * (See `winnt.h` for other available values.)
- * This Language ID is used for processing language-specific operations in
- * IME functions.
- */
- LANGID input_language_id_;
+ /* Abbreviated ISO 639-1 name of the input language, such as "en" for English. */
+ char language_[W32_ISO639_LEN];
/* Current Conversion Mode Values. Retrieved with ImmGetConversionStatus. */
DWORD conversion_modes_;
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index 2b4c3237c73..933e0c70cc8 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -1629,7 +1629,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
y_accum + (y_mouse - warped_y_mouse));
/* This is the current time that matches NSEvent timestamp. */
- m_last_warp_timestamp = mach_absolute_time() * 1e-9;
+ m_last_warp_timestamp = [[NSProcessInfo processInfo] systemUptime];
}
// Generate event
diff --git a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
index dd0205ea867..936b973c97e 100644
--- a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
+++ b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
@@ -38,6 +38,7 @@
# include "GHOST_SystemWin32.h"
#endif
#include "GHOST_C-api.h"
+#include "GHOST_XrException.h"
#include "GHOST_Xr_intern.h"
#include "GHOST_IXrGraphicsBinding.h"
@@ -160,16 +161,41 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
}
std::optional<int64_t> chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
+ GHOST_TXrSwapchainFormat &r_format,
bool &r_is_srgb_format) const override
{
std::vector<int64_t> gpu_binding_formats = {
+ GL_RGB10_A2,
+ GL_RGBA16,
+ GL_RGBA16F,
GL_RGBA8,
GL_SRGB8_ALPHA8,
};
std::optional result = choose_swapchain_format_from_candidates(gpu_binding_formats,
runtime_formats);
- r_is_srgb_format = result ? (*result == GL_SRGB8_ALPHA8) : false;
+ if (result) {
+ switch (*result) {
+ case GL_RGB10_A2:
+ r_format = GHOST_kXrSwapchainFormatRGB10_A2;
+ break;
+ case GL_RGBA16:
+ r_format = GHOST_kXrSwapchainFormatRGBA16;
+ break;
+ case GL_RGBA16F:
+ r_format = GHOST_kXrSwapchainFormatRGBA16F;
+ break;
+ case GL_RGBA8:
+ case GL_SRGB8_ALPHA8:
+ r_format = GHOST_kXrSwapchainFormatRGBA8;
+ break;
+ }
+ r_is_srgb_format = (*result == GL_SRGB8_ALPHA8);
+ }
+ else {
+ r_format = GHOST_kXrSwapchainFormatRGBA8;
+ r_is_srgb_format = false;
+ }
return result;
}
@@ -228,6 +254,33 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
};
#ifdef WIN32
+static void ghost_format_to_dx_format(GHOST_TXrSwapchainFormat ghost_format,
+ bool expects_srgb_buffer,
+ DXGI_FORMAT &r_dx_format)
+{
+ r_dx_format = DXGI_FORMAT_UNKNOWN;
+
+ switch (ghost_format) {
+ case GHOST_kXrSwapchainFormatRGBA8:
+ r_dx_format = expects_srgb_buffer ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB :
+ DXGI_FORMAT_R8G8B8A8_UNORM;
+ break;
+ case GHOST_kXrSwapchainFormatRGBA16:
+ r_dx_format = DXGI_FORMAT_R16G16B16A16_UNORM;
+ break;
+ case GHOST_kXrSwapchainFormatRGBA16F:
+ r_dx_format = DXGI_FORMAT_R16G16B16A16_FLOAT;
+ break;
+ case GHOST_kXrSwapchainFormatRGB10_A2:
+ r_dx_format = DXGI_FORMAT_R10G10B10A2_UNORM;
+ break;
+ }
+
+ if (r_dx_format == DXGI_FORMAT_UNKNOWN) {
+ throw GHOST_XrException("No supported DirectX swapchain format found.");
+ }
+}
+
class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
public:
GHOST_XrGraphicsBindingD3D(GHOST_Context &ghost_ctx)
@@ -284,16 +337,48 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
}
std::optional<int64_t> chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
+ GHOST_TXrSwapchainFormat &r_format,
bool &r_is_srgb_format) const override
{
std::vector<int64_t> gpu_binding_formats = {
- DXGI_FORMAT_R8G8B8A8_UNORM,
- DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+# if 0 /* RGB10A2 doesn't seem to work with Oculus head-sets, \
+ * so move it after RGB16AF for the time being. */
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+# endif
+ DXGI_FORMAT_R16G16B16A16_UNORM,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+# if 1
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+# endif
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
};
std::optional result = choose_swapchain_format_from_candidates(gpu_binding_formats,
runtime_formats);
- r_is_srgb_format = result ? (*result == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) : false;
+ if (result) {
+ switch (*result) {
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ r_format = GHOST_kXrSwapchainFormatRGB10_A2;
+ break;
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ r_format = GHOST_kXrSwapchainFormatRGBA16;
+ break;
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ r_format = GHOST_kXrSwapchainFormatRGBA16F;
+ break;
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ r_format = GHOST_kXrSwapchainFormatRGBA8;
+ break;
+ }
+ r_is_srgb_format = (*result == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
+ }
+ else {
+ r_format = GHOST_kXrSwapchainFormatRGBA8;
+ r_is_srgb_format = false;
+ }
+
return result;
}
@@ -334,14 +419,18 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
m_ghost_ctx->m_device->CreateRenderTargetView(d3d_swapchain_image.texture, &rtv_desc, &rtv);
if (!m_shared_resource) {
+ DXGI_FORMAT format;
+ ghost_format_to_dx_format(draw_info.swapchain_format, draw_info.expects_srgb_buffer, format);
m_shared_resource = m_ghost_ctx->createSharedOpenGLResource(
- draw_info.width, draw_info.height, rtv);
+ draw_info.width, draw_info.height, format, rtv);
}
m_ghost_ctx->blitFromOpenGLContext(m_shared_resource, draw_info.width, draw_info.height);
# else
if (!m_shared_resource) {
- m_shared_resource = m_ghost_d3d_ctx->createSharedOpenGLResource(draw_info.width,
- draw_info.height);
+ DXGI_FORMAT format;
+ ghost_format_to_dx_format(draw_info.swapchain_format, draw_info.expects_srgb_buffer, format);
+ m_shared_resource = m_ghost_d3d_ctx->createSharedOpenGLResource(
+ draw_info.width, draw_info.height, format);
}
m_ghost_d3d_ctx->blitFromOpenGLContext(m_shared_resource, draw_info.width, draw_info.height);
diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp
index 4cab22ee676..8b0320ef358 100644
--- a/intern/ghost/intern/GHOST_XrSession.cpp
+++ b/intern/ghost/intern/GHOST_XrSession.cpp
@@ -422,6 +422,7 @@ void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain,
assert(view_idx < 256);
draw_view_info.view_idx = (char)view_idx;
+ draw_view_info.swapchain_format = swapchain.getFormat();
draw_view_info.expects_srgb_buffer = swapchain.isBufferSRGB();
draw_view_info.ofsx = r_proj_layer_view.subImage.imageRect.offset.x;
draw_view_info.ofsy = r_proj_layer_view.subImage.imageRect.offset.y;
diff --git a/intern/ghost/intern/GHOST_XrSwapchain.cpp b/intern/ghost/intern/GHOST_XrSwapchain.cpp
index 9973d99cc37..f89b7227ab1 100644
--- a/intern/ghost/intern/GHOST_XrSwapchain.cpp
+++ b/intern/ghost/intern/GHOST_XrSwapchain.cpp
@@ -67,8 +67,8 @@ GHOST_XrSwapchain::GHOST_XrSwapchain(GHOST_IXrGraphicsBinding &gpu_binding,
"Failed to get swapchain image formats.");
assert(swapchain_formats.size() == format_count);
- std::optional chosen_format = gpu_binding.chooseSwapchainFormat(swapchain_formats,
- m_is_srgb_buffer);
+ std::optional chosen_format = gpu_binding.chooseSwapchainFormat(
+ swapchain_formats, m_format, m_is_srgb_buffer);
if (!chosen_format) {
throw GHOST_XrException(
"Error: No format matching OpenXR runtime supported swapchain formats found.");
@@ -97,6 +97,7 @@ GHOST_XrSwapchain::GHOST_XrSwapchain(GHOST_XrSwapchain &&other)
: m_oxr(std::move(other.m_oxr)),
m_image_width(other.m_image_width),
m_image_height(other.m_image_height),
+ m_format(other.m_format),
m_is_srgb_buffer(other.m_is_srgb_buffer)
{
/* Prevent xrDestroySwapchain call for the moved out item. */
@@ -134,7 +135,12 @@ void GHOST_XrSwapchain::updateCompositionLayerProjectViewSubImage(XrSwapchainSub
r_sub_image.imageRect.extent = {m_image_width, m_image_height};
}
-bool GHOST_XrSwapchain::isBufferSRGB()
+GHOST_TXrSwapchainFormat GHOST_XrSwapchain::getFormat() const
+{
+ return m_format;
+}
+
+bool GHOST_XrSwapchain::isBufferSRGB() const
{
return m_is_srgb_buffer;
}
diff --git a/intern/ghost/intern/GHOST_XrSwapchain.h b/intern/ghost/intern/GHOST_XrSwapchain.h
index 33a1c17b993..0c6592e2db6 100644
--- a/intern/ghost/intern/GHOST_XrSwapchain.h
+++ b/intern/ghost/intern/GHOST_XrSwapchain.h
@@ -37,10 +37,12 @@ class GHOST_XrSwapchain {
void updateCompositionLayerProjectViewSubImage(XrSwapchainSubImage &r_sub_image);
- bool isBufferSRGB();
+ GHOST_TXrSwapchainFormat getFormat() const;
+ bool isBufferSRGB() const;
private:
std::unique_ptr<OpenXRSwapchainData> m_oxr; /* Could use stack, but PImpl is preferable. */
int32_t m_image_width, m_image_height;
+ GHOST_TXrSwapchainFormat m_format;
bool m_is_srgb_buffer = false;
};
diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c
index a7c3dc0951e..98a8553a3eb 100644
--- a/intern/guardedalloc/intern/mallocn_guarded_impl.c
+++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c
@@ -871,7 +871,7 @@ void MEM_guarded_freeN(void *vmemh)
if (memh == NULL) {
MemorY_ErroR("free", "attempt to free NULL pointer");
- /* print_error(err_stream, "%d\n", (memh+4000)->tag1); */
+ // print_error(err_stream, "%d\n", (memh+4000)->tag1);
return;
}