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:
authorFabian Schempp <fabianschempp@googlemail.com>2021-08-15 10:13:45 +0300
committerFabian Schempp <fabianschempp@googlemail.com>2021-08-15 10:13:45 +0300
commitfad55ce70bed63b4fee7944bc04ddf0998230b77 (patch)
tree633e6fcc65a273f122eecca3e56cef02729c242d /intern
parentc54bdc7fb6a5db764695b07b871b94ee5b189071 (diff)
parentd5261e973b5624b40b80771903e9d2a0c9ff37e4 (diff)
Merge branch 'master' into soc-2021-porting-modifiers-to-nodes-extrude-and-move
# Conflicts: # source/blender/blenkernel/BKE_node.h
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/blender_python.cpp107
-rw-r--r--intern/cycles/blender/blender_shader.cpp90
-rw-r--r--intern/cycles/blender/blender_util.h2
-rw-r--r--intern/cycles/render/session.cpp287
-rw-r--r--intern/cycles/render/session.h45
-rw-r--r--intern/ghost/GHOST_C-api.h4
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp4
-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_XrAction.cpp8
-rw-r--r--intern/ghost/intern/GHOST_XrAction.h4
-rw-r--r--intern/ghost/intern/GHOST_XrSession.cpp4
-rw-r--r--intern/ghost/intern/GHOST_XrSession.h4
-rw-r--r--intern/guardedalloc/intern/mallocn_guarded_impl.c2
15 files changed, 411 insertions, 386 deletions
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index fd145effde7..6e06b6a468f 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -487,6 +487,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;
@@ -494,6 +512,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";
@@ -523,10 +542,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";
@@ -546,33 +574,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) {
@@ -590,9 +642,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..1404c58290d 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,48 @@ 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 {
+ 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();
+ string name = b_socket.identifier();
+ ShaderOutput *output = node->output(name.c_str());
- 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++;
- }
-
- 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 +1191,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 +1201,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 2b2188b023d..82da3512269 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/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 19d4a66353d..1b91c49f0ea 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -57,23 +57,26 @@ Session::Session(const SessionParams &params_)
stats(),
profiler()
{
- device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background);
+ device_use_gl_ = ((params.device.type != DEVICE_CPU) && !params.background);
TaskScheduler::init(params.threads);
- session_thread = NULL;
+ session_thread_ = NULL;
scene = NULL;
- reset_time = 0.0;
- last_update_time = 0.0;
+ reset_time_ = 0.0;
+ last_update_time_ = 0.0;
- delayed_reset.do_reset = false;
- delayed_reset.samples = 0;
+ delayed_reset_.do_reset = false;
+ delayed_reset_.samples = 0;
- display_outdated = false;
- gpu_draw_ready = false;
- gpu_need_display_buffer_update = false;
- pause = false;
+ display_outdated_ = false;
+ gpu_draw_ready_ = false;
+ gpu_need_display_buffer_update_ = false;
+
+ pause_ = false;
+ cancel_ = false;
+ new_work_added_ = false;
buffers = NULL;
display = NULL;
@@ -127,25 +130,26 @@ Session::~Session()
void Session::start()
{
- if (!session_thread) {
- session_thread = new thread(function_bind(&Session::run, this));
+ if (!session_thread_) {
+ session_thread_ = new thread(function_bind(&Session::run, this));
}
}
void Session::cancel()
{
- if (session_thread) {
+ if (session_thread_) {
/* wait for session thread to end */
progress.set_cancel("Exiting");
- gpu_need_display_buffer_update = false;
- gpu_need_display_buffer_update_cond.notify_all();
+ gpu_need_display_buffer_update_ = false;
+ gpu_need_display_buffer_update_cond_.notify_all();
{
- thread_scoped_lock pause_lock(pause_mutex);
- pause = false;
+ thread_scoped_lock pause_lock(pause_mutex_);
+ pause_ = false;
+ cancel_ = true;
}
- pause_cond.notify_all();
+ pause_cond_.notify_all();
wait();
}
@@ -153,9 +157,9 @@ void Session::cancel()
bool Session::ready_to_reset()
{
- double dt = time_dt() - reset_time;
+ double dt = time_dt() - reset_time_;
- if (!display_outdated)
+ if (!display_outdated_)
return (dt > params.reset_timeout);
else
return (dt > params.cancel_timeout);
@@ -165,48 +169,50 @@ bool Session::ready_to_reset()
void Session::reset_gpu(BufferParams &buffer_params, int samples)
{
- thread_scoped_lock pause_lock(pause_mutex);
+ thread_scoped_lock pause_lock(pause_mutex_);
/* block for buffer access and reset immediately. we can't do this
* in the thread, because we need to allocate an OpenGL buffer, and
* that only works in the main thread */
- thread_scoped_lock display_lock(display_mutex);
- thread_scoped_lock buffers_lock(buffers_mutex);
+ thread_scoped_lock display_lock(display_mutex_);
+ thread_scoped_lock buffers_lock(buffers_mutex_);
- display_outdated = true;
- reset_time = time_dt();
+ display_outdated_ = true;
+ reset_time_ = time_dt();
reset_(buffer_params, samples);
- gpu_need_display_buffer_update = false;
- gpu_need_display_buffer_update_cond.notify_all();
+ gpu_need_display_buffer_update_ = false;
+ gpu_need_display_buffer_update_cond_.notify_all();
+
+ new_work_added_ = true;
- pause_cond.notify_all();
+ pause_cond_.notify_all();
}
bool Session::draw_gpu(BufferParams &buffer_params, DeviceDrawParams &draw_params)
{
/* block for buffer access */
- thread_scoped_lock display_lock(display_mutex);
+ thread_scoped_lock display_lock(display_mutex_);
/* first check we already rendered something */
- if (gpu_draw_ready) {
+ if (gpu_draw_ready_) {
/* then verify the buffers have the expected size, so we don't
* draw previous results in a resized window */
if (buffer_params.width == display->params.width &&
buffer_params.height == display->params.height) {
/* for CUDA we need to do tone-mapping still, since we can
* only access GL buffers from the main thread. */
- if (gpu_need_display_buffer_update) {
- thread_scoped_lock buffers_lock(buffers_mutex);
+ if (gpu_need_display_buffer_update_) {
+ thread_scoped_lock buffers_lock(buffers_mutex_);
copy_to_display_buffer(tile_manager.state.sample);
- gpu_need_display_buffer_update = false;
- gpu_need_display_buffer_update_cond.notify_all();
+ gpu_need_display_buffer_update_ = false;
+ gpu_need_display_buffer_update_cond_.notify_all();
}
display->draw(device, draw_params);
- if (display_outdated && (time_dt() - reset_time) > params.text_timeout)
+ if (display_outdated_ && (time_dt() - reset_time_) > params.text_timeout)
return false;
return true;
@@ -220,9 +226,9 @@ void Session::run_gpu()
{
bool tiles_written = false;
- reset_time = time_dt();
- last_update_time = time_dt();
- last_display_time = last_update_time;
+ reset_time_ = time_dt();
+ last_update_time_ = time_dt();
+ last_display_time_ = last_update_time_;
progress.set_render_start_time();
@@ -255,7 +261,7 @@ void Session::run_gpu()
/* buffers mutex is locked entirely while rendering each
* sample, and released/reacquired on each iteration to allow
* reset and draw in between */
- thread_scoped_lock buffers_lock(buffers_mutex);
+ thread_scoped_lock buffers_lock(buffers_mutex_);
/* update status and timing */
update_status_time();
@@ -273,17 +279,17 @@ void Session::run_gpu()
/* update status and timing */
update_status_time();
- gpu_need_display_buffer_update = !delayed_denoise;
- gpu_draw_ready = true;
+ gpu_need_display_buffer_update_ = !delayed_denoise;
+ gpu_draw_ready_ = true;
progress.set_update();
/* wait for until display buffer is updated */
if (!params.background) {
- while (gpu_need_display_buffer_update) {
+ while (gpu_need_display_buffer_update_) {
if (progress.get_cancel())
break;
- gpu_need_display_buffer_update_cond.wait(buffers_lock);
+ gpu_need_display_buffer_update_cond_.wait(buffers_lock);
}
}
@@ -305,23 +311,23 @@ void Session::run_gpu()
void Session::reset_cpu(BufferParams &buffer_params, int samples)
{
- thread_scoped_lock reset_lock(delayed_reset.mutex);
- thread_scoped_lock pause_lock(pause_mutex);
+ thread_scoped_lock reset_lock(delayed_reset_.mutex);
+ thread_scoped_lock pause_lock(pause_mutex_);
- display_outdated = true;
- reset_time = time_dt();
+ display_outdated_ = true;
+ reset_time_ = time_dt();
- delayed_reset.params = buffer_params;
- delayed_reset.samples = samples;
- delayed_reset.do_reset = true;
+ delayed_reset_.params = buffer_params;
+ delayed_reset_.samples = samples;
+ delayed_reset_.do_reset = true;
device->task_cancel();
- pause_cond.notify_all();
+ pause_cond_.notify_all();
}
bool Session::draw_cpu(BufferParams &buffer_params, DeviceDrawParams &draw_params)
{
- thread_scoped_lock display_lock(display_mutex);
+ thread_scoped_lock display_lock(display_mutex_);
/* first check we already rendered something */
if (display->draw_ready()) {
@@ -331,7 +337,7 @@ bool Session::draw_cpu(BufferParams &buffer_params, DeviceDrawParams &draw_param
buffer_params.height == display->params.height) {
display->draw(device, draw_params);
- if (display_outdated && (time_dt() - reset_time) > params.text_timeout)
+ if (display_outdated_ && (time_dt() - reset_time_) > params.text_timeout)
return false;
return true;
@@ -345,46 +351,46 @@ bool Session::steal_tile(RenderTile &rtile, Device *tile_device, thread_scoped_l
{
/* Devices that can get their tiles stolen don't steal tiles themselves.
* Additionally, if there are no stealable tiles in flight, give up here. */
- if (tile_device->info.type == DEVICE_CPU || stealable_tiles == 0) {
+ if (tile_device->info.type == DEVICE_CPU || stealable_tiles_ == 0) {
return false;
}
/* Wait until no other thread is trying to steal a tile. */
- while (tile_stealing_state != NOT_STEALING && stealable_tiles > 0) {
+ while (tile_stealing_state_ != NOT_STEALING && stealable_tiles_ > 0) {
/* Someone else is currently trying to get a tile.
* Wait on the condition variable and try later. */
- tile_steal_cond.wait(tile_lock);
+ tile_steal_cond_.wait(tile_lock);
}
/* If another thread stole the last stealable tile in the meantime, give up. */
- if (stealable_tiles == 0) {
+ if (stealable_tiles_ == 0) {
return false;
}
/* There are stealable tiles in flight, so signal that one should be released. */
- tile_stealing_state = WAITING_FOR_TILE;
+ tile_stealing_state_ = WAITING_FOR_TILE;
/* Wait until a device notices the signal and releases its tile. */
- while (tile_stealing_state != GOT_TILE && stealable_tiles > 0) {
- tile_steal_cond.wait(tile_lock);
+ while (tile_stealing_state_ != GOT_TILE && stealable_tiles_ > 0) {
+ tile_steal_cond_.wait(tile_lock);
}
/* If the last stealable tile finished on its own, give up. */
- if (tile_stealing_state != GOT_TILE) {
- tile_stealing_state = NOT_STEALING;
+ if (tile_stealing_state_ != GOT_TILE) {
+ tile_stealing_state_ = NOT_STEALING;
return false;
}
/* Successfully stole a tile, now move it to the new device. */
- rtile = stolen_tile;
+ rtile = stolen_tile_;
rtile.buffers->buffer.move_device(tile_device);
rtile.buffer = rtile.buffers->buffer.device_pointer;
rtile.stealing_state = RenderTile::NO_STEALING;
rtile.num_samples -= (rtile.sample - rtile.start_sample);
rtile.start_sample = rtile.sample;
- tile_stealing_state = NOT_STEALING;
+ tile_stealing_state_ = NOT_STEALING;
/* Poke any threads which might be waiting for NOT_STEALING above. */
- tile_steal_cond.notify_one();
+ tile_steal_cond_.notify_one();
return true;
}
@@ -394,7 +400,7 @@ bool Session::get_tile_stolen()
/* If tile_stealing_state is WAITING_FOR_TILE, atomically set it to RELEASING_TILE
* and return true. */
TileStealingState expected = WAITING_FOR_TILE;
- return tile_stealing_state.compare_exchange_weak(expected, RELEASING_TILE);
+ return tile_stealing_state_.compare_exchange_weak(expected, RELEASING_TILE);
}
bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_types)
@@ -406,7 +412,7 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
}
}
- thread_scoped_lock tile_lock(tile_mutex);
+ thread_scoped_lock tile_lock(tile_mutex_);
/* get next tile from manager */
Tile *tile;
@@ -423,7 +429,7 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
/* Wait for denoising tiles to become available */
if ((tile_types & RenderTile::DENOISE) && !progress.get_cancel() && tile_manager.has_tiles()) {
- denoising_cond.wait(tile_lock);
+ denoising_cond_.wait(tile_lock);
continue;
}
@@ -446,7 +452,7 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
}
else {
if (tile_device->info.type == DEVICE_CPU) {
- stealable_tiles++;
+ stealable_tiles_++;
rtile.stealing_state = RenderTile::CAN_BE_STOLEN;
}
@@ -515,7 +521,7 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
/* This will read any passes needed as input for baking. */
if (tile_manager.state.sample == tile_manager.range_start_sample) {
{
- thread_scoped_lock tile_lock(tile_mutex);
+ thread_scoped_lock tile_lock(tile_mutex_);
read_bake_tile_cb(rtile);
}
rtile.buffers->buffer.copy_to_device();
@@ -533,7 +539,7 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
void Session::update_tile_sample(RenderTile &rtile)
{
- thread_scoped_lock tile_lock(tile_mutex);
+ thread_scoped_lock tile_lock(tile_mutex_);
if (update_render_tile_cb) {
if (params.progressive_refine == false) {
@@ -548,25 +554,25 @@ void Session::update_tile_sample(RenderTile &rtile)
void Session::release_tile(RenderTile &rtile, const bool need_denoise)
{
- thread_scoped_lock tile_lock(tile_mutex);
+ thread_scoped_lock tile_lock(tile_mutex_);
if (rtile.stealing_state != RenderTile::NO_STEALING) {
- stealable_tiles--;
+ stealable_tiles_--;
if (rtile.stealing_state == RenderTile::WAS_STOLEN) {
/* If the tile is being stolen, don't release it here - the new device will pick up where
* the old one left off. */
- assert(tile_stealing_state == RELEASING_TILE);
+ assert(tile_stealing_state_ == RELEASING_TILE);
assert(rtile.sample < rtile.start_sample + rtile.num_samples);
- tile_stealing_state = GOT_TILE;
- stolen_tile = rtile;
- tile_steal_cond.notify_all();
+ tile_stealing_state_ = GOT_TILE;
+ stolen_tile_ = rtile;
+ tile_steal_cond_.notify_all();
return;
}
- else if (stealable_tiles == 0) {
+ else if (stealable_tiles_ == 0) {
/* If this was the last stealable tile, wake up any threads still waiting for one. */
- tile_steal_cond.notify_all();
+ tile_steal_cond_.notify_all();
}
}
@@ -595,12 +601,12 @@ void Session::release_tile(RenderTile &rtile, const bool need_denoise)
update_status_time();
/* Notify denoising thread that a tile was finished. */
- denoising_cond.notify_all();
+ denoising_cond_.notify_all();
}
void Session::map_neighbor_tiles(RenderTileNeighbors &neighbors, Device *tile_device)
{
- thread_scoped_lock tile_lock(tile_mutex);
+ thread_scoped_lock tile_lock(tile_mutex_);
const int4 image_region = make_int4(
tile_manager.state.buffer.full_x,
@@ -677,7 +683,7 @@ void Session::map_neighbor_tiles(RenderTileNeighbors &neighbors, Device *tile_de
void Session::unmap_neighbor_tiles(RenderTileNeighbors &neighbors, Device *tile_device)
{
- thread_scoped_lock tile_lock(tile_mutex);
+ thread_scoped_lock tile_lock(tile_mutex_);
device->unmap_neighbor_tiles(tile_device, neighbors);
}
@@ -685,8 +691,8 @@ void Session::run_cpu()
{
bool tiles_written = false;
- last_update_time = time_dt();
- last_display_time = last_update_time;
+ last_update_time_ = time_dt();
+ last_display_time_ = last_update_time_;
while (!progress.get_cancel()) {
const bool no_tiles = !run_update_for_next_iteration();
@@ -718,7 +724,7 @@ void Session::run_cpu()
/* buffers mutex is locked entirely while rendering each
* sample, and released/reacquired on each iteration to allow
* reset and draw in between */
- thread_scoped_lock buffers_lock(buffers_mutex);
+ thread_scoped_lock buffers_lock(buffers_mutex_);
/* update status and timing */
update_status_time();
@@ -741,14 +747,14 @@ void Session::run_cpu()
device->task_wait();
{
- thread_scoped_lock reset_lock(delayed_reset.mutex);
- thread_scoped_lock buffers_lock(buffers_mutex);
- thread_scoped_lock display_lock(display_mutex);
+ thread_scoped_lock reset_lock(delayed_reset_.mutex);
+ thread_scoped_lock buffers_lock(buffers_mutex_);
+ thread_scoped_lock display_lock(display_mutex_);
- if (delayed_reset.do_reset) {
+ if (delayed_reset_.do_reset) {
/* reset rendering if request from main thread */
- delayed_reset.do_reset = false;
- reset_(delayed_reset.params, delayed_reset.samples);
+ delayed_reset_.do_reset = false;
+ reset_(delayed_reset_.params, delayed_reset_.samples);
}
else if (need_copy_to_display_buffer) {
/* Only copy to display_buffer if we do not reset, we don't
@@ -783,7 +789,7 @@ void Session::run()
/* reset number of rendered samples */
progress.reset_sample();
- if (device_use_gl)
+ if (device_use_gl_)
run_gpu();
else
run_cpu();
@@ -801,12 +807,12 @@ void Session::run()
bool Session::run_update_for_next_iteration()
{
thread_scoped_lock scene_lock(scene->mutex);
- thread_scoped_lock reset_lock(delayed_reset.mutex);
+ thread_scoped_lock reset_lock(delayed_reset_.mutex);
- if (delayed_reset.do_reset) {
- thread_scoped_lock buffers_lock(buffers_mutex);
- reset_(delayed_reset.params, delayed_reset.samples);
- delayed_reset.do_reset = false;
+ if (delayed_reset_.do_reset) {
+ thread_scoped_lock buffers_lock(buffers_mutex_);
+ reset_(delayed_reset_.params, delayed_reset_.samples);
+ delayed_reset_.do_reset = false;
}
const bool have_tiles = tile_manager.next();
@@ -829,35 +835,43 @@ bool Session::run_wait_for_work(bool no_tiles)
return false;
}
- thread_scoped_lock pause_lock(pause_mutex);
+ thread_scoped_lock pause_lock(pause_mutex_);
- if (!pause && !no_tiles) {
+ if (!pause_ && !no_tiles) {
+ /* Rendering is not paused and there is work to be done. No need to wait for anything. */
return false;
}
- update_status_time(pause, no_tiles);
+ update_status_time(pause_, no_tiles);
- while (true) {
+ /* Only leave the loop when rendering is not paused. But even if the current render is un-paused
+ * but there is nothing to render keep waiting until new work is added. */
+ while (!cancel_) {
scoped_timer pause_timer;
- pause_cond.wait(pause_lock);
- if (pause) {
- progress.add_skip_time(pause_timer, params.background);
+
+ if (!pause_ && (!no_tiles || new_work_added_ || delayed_reset_.do_reset)) {
+ break;
}
- update_status_time(pause, no_tiles);
- progress.set_update();
+ /* Wait for either pause state changed, or extra samples added to render. */
+ pause_cond_.wait(pause_lock);
- if (!pause) {
- break;
+ if (pause_) {
+ progress.add_skip_time(pause_timer, params.background);
}
+
+ update_status_time(pause_, no_tiles);
+ progress.set_update();
}
+ new_work_added_ = false;
+
return no_tiles;
}
bool Session::draw(BufferParams &buffer_params, DeviceDrawParams &draw_params)
{
- if (device_use_gl)
+ if (device_use_gl_)
return draw_gpu(buffer_params, draw_params);
else
return draw_cpu(buffer_params, draw_params);
@@ -866,7 +880,7 @@ bool Session::draw(BufferParams &buffer_params, DeviceDrawParams &draw_params)
void Session::reset_(BufferParams &buffer_params, int samples)
{
if (buffers && buffer_params.modified(tile_manager.params)) {
- gpu_draw_ready = false;
+ gpu_draw_ready_ = false;
buffers->reset(buffer_params);
if (display) {
display->reset(buffer_params);
@@ -874,8 +888,8 @@ void Session::reset_(BufferParams &buffer_params, int samples)
}
tile_manager.reset(buffer_params, samples);
- stealable_tiles = 0;
- tile_stealing_state = NOT_STEALING;
+ stealable_tiles_ = 0;
+ tile_stealing_state_ = NOT_STEALING;
progress.reset_sample();
bool show_progress = params.background || tile_manager.get_num_effective_samples() != INT_MAX;
@@ -888,7 +902,7 @@ void Session::reset_(BufferParams &buffer_params, int samples)
void Session::reset(BufferParams &buffer_params, int samples)
{
- if (device_use_gl)
+ if (device_use_gl_)
reset_gpu(buffer_params, samples);
else
reset_cpu(buffer_params, samples);
@@ -896,30 +910,37 @@ void Session::reset(BufferParams &buffer_params, int samples)
void Session::set_samples(int samples)
{
- if (samples != params.samples) {
- params.samples = samples;
- tile_manager.set_samples(samples);
+ if (samples == params.samples) {
+ return;
+ }
+
+ params.samples = samples;
+ tile_manager.set_samples(samples);
- pause_cond.notify_all();
+ {
+ thread_scoped_lock pause_lock(pause_mutex_);
+ new_work_added_ = true;
}
+
+ pause_cond_.notify_all();
}
-void Session::set_pause(bool pause_)
+void Session::set_pause(bool pause)
{
bool notify = false;
{
- thread_scoped_lock pause_lock(pause_mutex);
+ thread_scoped_lock pause_lock(pause_mutex_);
if (pause != pause_) {
- pause = pause_;
+ pause_ = pause;
notify = true;
}
}
- if (session_thread) {
+ if (session_thread_) {
if (notify) {
- pause_cond.notify_all();
+ pause_cond_.notify_all();
}
}
else if (pause_) {
@@ -932,7 +953,7 @@ void Session::set_denoising(const DenoiseParams &denoising)
bool need_denoise = denoising.need_denoising_task();
/* Lock buffers so no denoising operation is triggered while the settings are changed here. */
- thread_scoped_lock buffers_lock(buffers_mutex);
+ thread_scoped_lock buffers_lock(buffers_mutex_);
params.denoising = denoising;
if (!(params.device.denoisers & denoising.type)) {
@@ -957,18 +978,18 @@ void Session::set_denoising_start_sample(int sample)
if (sample != params.denoising.start_sample) {
params.denoising.start_sample = sample;
- pause_cond.notify_all();
+ pause_cond_.notify_all();
}
}
void Session::wait()
{
- if (session_thread) {
- session_thread->join();
- delete session_thread;
+ if (session_thread_) {
+ session_thread_->join();
+ delete session_thread_;
}
- session_thread = NULL;
+ session_thread_ = NULL;
}
bool Session::update_scene()
@@ -1099,7 +1120,7 @@ bool Session::render_need_denoise(bool &delayed)
/* Avoid excessive denoising in viewport after reaching a certain amount of samples. */
delayed = (tile_manager.state.sample >= 20 &&
- (time_dt() - last_display_time) < params.progressive_update_timeout);
+ (time_dt() - last_display_time_) < params.progressive_update_timeout);
return !delayed;
}
@@ -1197,10 +1218,10 @@ void Session::copy_to_display_buffer(int sample)
/* set display to new size */
display->draw_set(task.w, task.h);
- last_display_time = time_dt();
+ last_display_time_ = time_dt();
}
- display_outdated = false;
+ display_outdated_ = false;
}
bool Session::update_progressive_refine(bool cancel)
@@ -1210,7 +1231,7 @@ bool Session::update_progressive_refine(bool cancel)
double current_time = time_dt();
- if (current_time - last_update_time < params.progressive_update_timeout) {
+ if (current_time - last_update_time_ < params.progressive_update_timeout) {
/* If last sample was processed, we need to write buffers anyway. */
if (!write && sample != 1)
return false;
@@ -1241,7 +1262,7 @@ bool Session::update_progressive_refine(bool cancel)
}
}
- last_update_time = current_time;
+ last_update_time_ = current_time;
return write;
}
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index bc3b8366c05..05025c10f9c 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -174,7 +174,7 @@ class Session {
bool do_reset;
BufferParams params;
int samples;
- } delayed_reset;
+ } delayed_reset_;
void run();
@@ -207,38 +207,41 @@ class Session {
void map_neighbor_tiles(RenderTileNeighbors &neighbors, Device *tile_device);
void unmap_neighbor_tiles(RenderTileNeighbors &neighbors, Device *tile_device);
- bool device_use_gl;
+ bool device_use_gl_;
- thread *session_thread;
+ thread *session_thread_;
- volatile bool display_outdated;
+ volatile bool display_outdated_;
- volatile bool gpu_draw_ready;
- volatile bool gpu_need_display_buffer_update;
- thread_condition_variable gpu_need_display_buffer_update_cond;
+ volatile bool gpu_draw_ready_;
+ volatile bool gpu_need_display_buffer_update_;
+ thread_condition_variable gpu_need_display_buffer_update_cond_;
- bool pause;
- thread_condition_variable pause_cond;
- thread_mutex pause_mutex;
- thread_mutex tile_mutex;
- thread_mutex buffers_mutex;
- thread_mutex display_mutex;
- thread_condition_variable denoising_cond;
- thread_condition_variable tile_steal_cond;
+ bool pause_;
+ bool cancel_;
+ bool new_work_added_;
- double reset_time;
- double last_update_time;
- double last_display_time;
+ thread_condition_variable pause_cond_;
+ thread_mutex pause_mutex_;
+ thread_mutex tile_mutex_;
+ thread_mutex buffers_mutex_;
+ thread_mutex display_mutex_;
+ thread_condition_variable denoising_cond_;
+ thread_condition_variable tile_steal_cond_;
- RenderTile stolen_tile;
+ double reset_time_;
+ double last_update_time_;
+ double last_display_time_;
+
+ RenderTile stolen_tile_;
typedef enum {
NOT_STEALING, /* There currently is no tile stealing in progress. */
WAITING_FOR_TILE, /* A device is waiting for another device to release a tile. */
RELEASING_TILE, /* A device has releasing a stealable tile. */
GOT_TILE /* A device has released a stealable tile, which is now stored in stolen_tile. */
} TileStealingState;
- std::atomic<TileStealingState> tile_stealing_state;
- int stealable_tiles;
+ std::atomic<TileStealingState> tile_stealing_state_;
+ int stealable_tiles_;
/* progressive refine */
bool update_progressive_refine(bool cancel);
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 83c67f83908..b78aac6f5eb 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -1102,7 +1102,7 @@ int GHOST_XrSyncActions(GHOST_XrContextHandle xr_context, const char *action_set
int GHOST_XrApplyHapticAction(GHOST_XrContextHandle xr_context,
const char *action_set_name,
const char *action_name,
- const char **subaction_path,
+ const char *subaction_path,
const int64_t *duration,
const float *frequency,
const float *amplitude);
@@ -1113,7 +1113,7 @@ int GHOST_XrApplyHapticAction(GHOST_XrContextHandle xr_context,
void GHOST_XrStopHapticAction(GHOST_XrContextHandle xr_context,
const char *action_set_name,
const char *action_name,
- const char **subaction_path);
+ const char *subaction_path);
/**
* Get action set custom data (owned by Blender, not GHOST).
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index b1af5c131ab..a2871b46222 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -1005,7 +1005,7 @@ int GHOST_XrSyncActions(GHOST_XrContextHandle xr_contexthandle, const char *acti
int GHOST_XrApplyHapticAction(GHOST_XrContextHandle xr_contexthandle,
const char *action_set_name,
const char *action_name,
- const char **subaction_path,
+ const char *subaction_path,
const int64_t *duration,
const float *frequency,
const float *amplitude)
@@ -1022,7 +1022,7 @@ int GHOST_XrApplyHapticAction(GHOST_XrContextHandle xr_contexthandle,
void GHOST_XrStopHapticAction(GHOST_XrContextHandle xr_contexthandle,
const char *action_set_name,
const char *action_name,
- const char **subaction_path)
+ const char *subaction_path)
{
GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
GHOST_XrSession *xr_session = xr_context->getSession();
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_XrAction.cpp b/intern/ghost/intern/GHOST_XrAction.cpp
index 07eb42c14e6..704b1ce9fac 100644
--- a/intern/ghost/intern/GHOST_XrAction.cpp
+++ b/intern/ghost/intern/GHOST_XrAction.cpp
@@ -375,7 +375,7 @@ void GHOST_XrAction::updateState(XrSession session,
void GHOST_XrAction::applyHapticFeedback(XrSession session,
const char *action_name,
- const char **subaction_path_str,
+ const char *subaction_path_str,
const int64_t &duration,
const float &frequency,
const float &amplitude)
@@ -390,7 +390,7 @@ void GHOST_XrAction::applyHapticFeedback(XrSession session,
haptic_info.action = m_action;
if (subaction_path_str != nullptr) {
- SubactionIndexMap::iterator it = m_subaction_indices.find(*subaction_path_str);
+ SubactionIndexMap::iterator it = m_subaction_indices.find(subaction_path_str);
if (it != m_subaction_indices.end()) {
haptic_info.subactionPath = m_subaction_paths[it->second];
CHECK_XR(
@@ -410,13 +410,13 @@ void GHOST_XrAction::applyHapticFeedback(XrSession session,
void GHOST_XrAction::stopHapticFeedback(XrSession session,
const char *action_name,
- const char **subaction_path_str)
+ const char *subaction_path_str)
{
XrHapticActionInfo haptic_info{XR_TYPE_HAPTIC_ACTION_INFO};
haptic_info.action = m_action;
if (subaction_path_str != nullptr) {
- SubactionIndexMap::iterator it = m_subaction_indices.find(*subaction_path_str);
+ SubactionIndexMap::iterator it = m_subaction_indices.find(subaction_path_str);
if (it != m_subaction_indices.end()) {
haptic_info.subactionPath = m_subaction_paths[it->second];
CHECK_XR(xrStopHapticFeedback(session, &haptic_info),
diff --git a/intern/ghost/intern/GHOST_XrAction.h b/intern/ghost/intern/GHOST_XrAction.h
index 70eaa694ae9..3e2224fe3ff 100644
--- a/intern/ghost/intern/GHOST_XrAction.h
+++ b/intern/ghost/intern/GHOST_XrAction.h
@@ -103,11 +103,11 @@ class GHOST_XrAction {
const XrTime &predicted_display_time);
void applyHapticFeedback(XrSession session,
const char *action_name,
- const char **subaction_path,
+ const char *subaction_path,
const int64_t &duration,
const float &frequency,
const float &amplitude);
- void stopHapticFeedback(XrSession session, const char *action_name, const char **subaction_path);
+ void stopHapticFeedback(XrSession session, const char *action_name, const char *subaction_path);
void *getCustomdata();
void getBindings(std::map<XrPath, std::vector<XrActionSuggestedBinding>> &r_bindings) const;
diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp
index a63ce5c9344..4cab22ee676 100644
--- a/intern/ghost/intern/GHOST_XrSession.cpp
+++ b/intern/ghost/intern/GHOST_XrSession.cpp
@@ -754,7 +754,7 @@ bool GHOST_XrSession::syncActions(const char *action_set_name)
bool GHOST_XrSession::applyHapticAction(const char *action_set_name,
const char *action_name,
- const char **subaction_path,
+ const char *subaction_path,
const int64_t &duration,
const float &frequency,
const float &amplitude)
@@ -777,7 +777,7 @@ bool GHOST_XrSession::applyHapticAction(const char *action_set_name,
void GHOST_XrSession::stopHapticAction(const char *action_set_name,
const char *action_name,
- const char **subaction_path)
+ const char *subaction_path)
{
GHOST_XrActionSet *action_set = find_action_set(m_oxr.get(), action_set_name);
if (action_set == nullptr) {
diff --git a/intern/ghost/intern/GHOST_XrSession.h b/intern/ghost/intern/GHOST_XrSession.h
index ec15897058f..a76e11aede1 100644
--- a/intern/ghost/intern/GHOST_XrSession.h
+++ b/intern/ghost/intern/GHOST_XrSession.h
@@ -76,13 +76,13 @@ class GHOST_XrSession {
bool syncActions(const char *action_set_name = nullptr);
bool applyHapticAction(const char *action_set_name,
const char *action_name,
- const char **subaction_path,
+ const char *subaction_path,
const int64_t &duration,
const float &frequency,
const float &amplitude);
void stopHapticAction(const char *action_set_name,
const char *action_name,
- const char **subaction_path);
+ const char *subaction_path);
/* Custom data (owned by Blender, not GHOST) accessors. */
void *getActionSetCustomdata(const char *action_set_name);
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;
}