diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2021-08-17 12:30:58 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2021-08-17 12:30:58 +0300 |
commit | 96f5f20d53e4234b89d471a64f52002c838d85fa (patch) | |
tree | b8b74e6aee79e6538f1acbb5e499a7ec3d360bf5 /intern | |
parent | f3d502bf63fc7c98ccce87f109947805fb28b91e (diff) | |
parent | f8dd0080a9c490b017a95857ff750e79d4c6943a (diff) |
Merge branch 'master' into cycles_procedural_api
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/blender_python.cpp | 107 | ||||
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 93 | ||||
-rw-r--r-- | intern/cycles/blender/blender_util.h | 2 | ||||
-rw-r--r-- | intern/ghost/GHOST_Types.h | 9 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ContextD3D.cpp | 15 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ContextD3D.h | 8 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_IXrGraphicsBinding.h | 1 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ImeWin32.cpp | 199 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ImeWin32.h | 35 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemCocoa.mm | 2 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_XrGraphicsBinding.cpp | 103 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_XrSession.cpp | 1 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_XrSwapchain.cpp | 12 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_XrSwapchain.h | 4 | ||||
-rw-r--r-- | intern/guardedalloc/intern/mallocn_guarded_impl.c | 2 |
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; } |