Add editor vital redraws only option

When editor continuous redraws is switched off, the editor only redraws when a redraw_request was issued by an element in the scene. This works well in most situations, but when scenes have dynamic content they will continuously issue redraw_requests.

This can be fine on high power desktops but can be an annoyance on lower power machines.

This PR splits redraw requests into high and low priority requests, defaulting to high priority. Requests due to e.g. shaders using TIME are assigned low priority.

An extra editor setting is used to record the user preference and an extra option is added to the editor spinner menu, to allow the user to select between 3 modes:

* Continuous
* Update all changes
* Update vital changes
This commit is contained in:
lawnjelly 2021-10-05 19:05:57 +01:00
parent b6dbff7621
commit a0c6d16c90
26 changed files with 190 additions and 59 deletions

View file

@ -146,6 +146,10 @@ bool OS::is_in_low_processor_usage_mode() const {
return low_processor_usage_mode;
}
void OS::set_update_vital_only(bool p_enabled) {
_update_vital_only = p_enabled;
}
void OS::set_low_processor_usage_mode_sleep_usec(int p_usec) {
low_processor_usage_mode_sleep_usec = p_usec;
}
@ -834,6 +838,8 @@ OS::OS() {
_keep_screen_on = true; // set default value to true, because this had been true before godot 2.0.
low_processor_usage_mode = false;
low_processor_usage_mode_sleep_usec = 10000;
_update_vital_only = false;
_update_pending = false;
_verbose_stdout = false;
_debug_stdout = false;
_no_window = false;

View file

@ -50,6 +50,8 @@ class OS {
bool _keep_screen_on;
bool low_processor_usage_mode;
int low_processor_usage_mode_sleep_usec;
bool _update_vital_only;
bool _update_pending;
bool _verbose_stdout;
bool _debug_stdout;
String _local_clipboard;
@ -287,6 +289,27 @@ public:
virtual bool is_in_low_processor_usage_mode() const;
virtual void set_low_processor_usage_mode_sleep_usec(int p_usec);
virtual int get_low_processor_usage_mode_sleep_usec() const;
virtual void set_update_vital_only(bool p_enabled);
virtual void set_update_pending(bool p_pending) { _update_pending = p_pending; }
// Convenience easy switch for turning this off outside tools builds, without littering calling code
// with #ifdefs. It will also hopefully be compiled out in release.
#ifdef TOOLS_ENABLED
// This function is used to throttle back updates of animations and particle systems when using UPDATE_VITAL_ONLY mode.
// CASE 1) We are not in UPDATE_VITAL_ONLY mode - always return true and update.
// CASE 2) We are in UPDATE_VITAL_ONLY mode -
// In most cases this will return false and prevent animations etc updating.
// The exception is that we can also choose to receive a true
// each time a frame is redrawn as a result of moving the mouse, clicking etc.
// This enables us to keep e.g. particle systems processing, but ONLY when other
// events have caused a redraw.
virtual bool is_update_pending(bool p_include_redraws = false) const { return !_update_vital_only || (_update_pending && p_include_redraws); }
#else
// Always update when outside the editor, UPDATE_VITAL_ONLY has no effect outside the editor.
virtual bool is_update_pending(bool p_include_redraws = false) const { return true; }
#endif
virtual String get_executable_path() const;
virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr, bool p_open_console = false) = 0;

View file

@ -1178,8 +1178,10 @@
</method>
<method name="has_changed" qualifiers="const">
<return type="bool" />
<argument index="0" name="queried_priority" type="int" enum="VisualServer.ChangedPriority" default="0" />
<description>
Returns [code]true[/code] if changes have been made to the VisualServer's data. [method draw] is usually called if this happens.
As changes are registered as either high or low priority (e.g. dynamic shaders), this function takes an optional argument to query either low or high priority changes, or any changes.
</description>
</method>
<method name="has_feature" qualifiers="const">
@ -3841,5 +3843,14 @@
<constant name="ENV_SSAO_BLUR_3x3" value="3" enum="EnvironmentSSAOBlur">
Performs a 3x3 blur on the SSAO output. Use this for smoothest SSAO.
</constant>
<constant name="CHANGED_PRIORITY_ANY" value="0" enum="ChangedPriority">
Used to query for any changes that request a redraw, whatever the priority.
</constant>
<constant name="CHANGED_PRIORITY_LOW" value="1" enum="ChangedPriority">
Registered changes which have low priority can be optionally prevented from causing editor redraws. Examples might include dynamic shaders (typically using the [code]TIME[/code] built-in).
</constant>
<constant name="CHANGED_PRIORITY_HIGH" value="2" enum="ChangedPriority">
Registered changes which can cause a redraw default to high priority.
</constant>
</constants>
</class>

View file

@ -1659,7 +1659,7 @@ void RasterizerCanvasGLES2::_legacy_canvas_render_item(Item *p_ci, RenderItemSta
if (shader_ptr != r_ris.shader_cache) {
if (shader_ptr->canvas_item.uses_time) {
VisualServerRaster::redraw_request();
VisualServerRaster::redraw_request(false);
}
state.canvas_shader.set_custom_shader(shader_ptr->custom_code_id);
@ -2021,7 +2021,7 @@ void RasterizerCanvasGLES2::render_joined_item(const BItemJoined &p_bij, RenderI
if (shader_ptr != r_ris.shader_cache) {
if (shader_ptr->canvas_item.uses_time) {
VisualServerRaster::redraw_request();
VisualServerRaster::redraw_request(false);
}
state.canvas_shader.set_custom_shader(shader_ptr->custom_code_id);

View file

@ -1242,7 +1242,7 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
// do not add anything here, as lights are duplicated elements..
if (p_material->shader->spatial.uses_time) {
VisualServerRaster::redraw_request();
VisualServerRaster::redraw_request(false);
}
}

View file

@ -170,7 +170,7 @@ void RasterizerCanvasGLES3::_legacy_canvas_render_item(Item *p_ci, RenderItemSta
if (shader_ptr != r_ris.shader_cache || r_ris.rebind_shader) {
if (shader_ptr->canvas_item.uses_time) {
VisualServerRaster::redraw_request();
VisualServerRaster::redraw_request(false);
}
state.canvas_shader.set_custom_shader(shader_ptr->custom_code_id);
@ -968,7 +968,7 @@ void RasterizerCanvasGLES3::render_batches(Item *p_current_clip, bool &r_reclip,
glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1); //not used, so keep white
VisualServerRaster::redraw_request();
VisualServerRaster::redraw_request(false);
storage->particles_request_process(particles_cmd->particles);
//enable instancing
@ -1250,7 +1250,7 @@ void RasterizerCanvasGLES3::render_joined_item(const BItemJoined &p_bij, RenderI
if (shader_ptr != r_ris.shader_cache || r_ris.rebind_shader) {
if (shader_ptr->canvas_item.uses_time) {
VisualServerRaster::redraw_request();
VisualServerRaster::redraw_request(false);
}
state.canvas_shader.set_custom_shader(shader_ptr->custom_code_id);

View file

@ -2406,7 +2406,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
}
if (p_material->shader->spatial.uses_time) {
VisualServerRaster::redraw_request();
VisualServerRaster::redraw_request(false);
}
}

View file

@ -936,7 +936,7 @@ void CodeTextEditor::update_editor_settings() {
text_editor->set_line_length_guideline_hard_column(EditorSettings::get_singleton()->get("text_editor/appearance/line_length_guideline_hard_column"));
text_editor->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file"));
text_editor->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret"));
text_editor->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink"));
text_editor->cursor_set_blink_enabled(EditorSettings::get_singleton()->is_caret_blink_active());
text_editor->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed"));
text_editor->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/completion/auto_brace_complete"));
}

View file

@ -636,9 +636,17 @@ void EditorNode::_update_update_spinner() {
update_spinner->set_visible(EditorSettings::get_singleton()->get("interface/editor/show_update_spinner"));
const bool update_continuously = EditorSettings::get_singleton()->get("interface/editor/update_continuously");
const bool vital_only = EditorSettings::get_singleton()->get("interface/editor/update_vital_only");
PopupMenu *update_popup = update_spinner->get_popup();
update_popup->set_item_checked(update_popup->get_item_index(SETTINGS_UPDATE_CONTINUOUSLY), update_continuously);
update_popup->set_item_checked(update_popup->get_item_index(SETTINGS_UPDATE_WHEN_CHANGED), !update_continuously);
if (update_continuously) {
update_popup->set_item_checked(update_popup->get_item_index(SETTINGS_UPDATE_WHEN_CHANGED), false);
update_popup->set_item_checked(update_popup->get_item_index(SETTINGS_UPDATE_VITAL_ONLY), false);
} else {
update_popup->set_item_checked(update_popup->get_item_index(SETTINGS_UPDATE_WHEN_CHANGED), !vital_only);
update_popup->set_item_checked(update_popup->get_item_index(SETTINGS_UPDATE_VITAL_ONLY), vital_only);
}
if (update_continuously) {
update_spinner->set_tooltip(TTR("Spins when the editor window redraws.\nUpdate Continuously is enabled, which can increase power usage. Click to disable it."));
@ -656,6 +664,11 @@ void EditorNode::_update_update_spinner() {
}
OS::get_singleton()->set_low_processor_usage_mode(!update_continuously);
// Only set low priority redraws to false in the editor.
// When we run the project in the editor, we don't want it to prevent
// rendering any frames.
OS::get_singleton()->set_update_vital_only(vital_only && !update_continuously);
}
void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_name) {
@ -2791,6 +2804,12 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case SETTINGS_UPDATE_WHEN_CHANGED: {
EditorSettings::get_singleton()->set("interface/editor/update_continuously", false);
EditorSettings::get_singleton()->set("interface/editor/update_vital_only", false);
_update_update_spinner();
} break;
case SETTINGS_UPDATE_VITAL_ONLY: {
EditorSettings::get_singleton()->set("interface/editor/update_continuously", false);
EditorSettings::get_singleton()->set("interface/editor/update_vital_only", true);
_update_update_spinner();
} break;
case SETTINGS_UPDATE_SPINNER_HIDE: {
@ -5951,6 +5970,7 @@ EditorNode::EditorNode() {
EDITOR_DEF("interface/editor/quit_confirmation", true);
EDITOR_DEF("interface/editor/show_update_spinner", false);
EDITOR_DEF("interface/editor/update_continuously", false);
EDITOR_DEF("interface/editor/update_vital_only", false);
EDITOR_DEF_RST("interface/scene_tabs/restore_scenes_on_load", false);
EDITOR_DEF_RST("interface/scene_tabs/show_thumbnail_on_hover", true);
EDITOR_DEF_RST("interface/inspector/capitalize_properties", true);
@ -6622,7 +6642,8 @@ EditorNode::EditorNode() {
update_spinner->get_popup()->connect("id_pressed", this, "_menu_option");
p = update_spinner->get_popup();
p->add_radio_check_item(TTR("Update Continuously"), SETTINGS_UPDATE_CONTINUOUSLY);
p->add_radio_check_item(TTR("Update When Changed"), SETTINGS_UPDATE_WHEN_CHANGED);
p->add_radio_check_item(TTR("Update All Changes"), SETTINGS_UPDATE_WHEN_CHANGED);
p->add_radio_check_item(TTR("Update Vital Changes"), SETTINGS_UPDATE_VITAL_ONLY);
p->add_separator();
p->add_item(TTR("Hide Update Spinner"), SETTINGS_UPDATE_SPINNER_HIDE);
_update_update_spinner();

View file

@ -176,6 +176,7 @@ private:
RUN_VCS_SETTINGS,
RUN_VCS_SHUT_DOWN,
SETTINGS_UPDATE_CONTINUOUSLY,
SETTINGS_UPDATE_VITAL_ONLY,
SETTINGS_UPDATE_WHEN_CHANGED,
SETTINGS_UPDATE_ALWAYS,
SETTINGS_UPDATE_CHANGES,

View file

@ -1292,6 +1292,19 @@ void EditorSettings::load_favorites() {
}
}
// The logic for this is rather convoluted as it takes into account whether
// vital updates only is selected.
bool EditorSettings::is_caret_blink_active() const {
bool blink = get("text_editor/cursor/caret_blink");
bool vital_only = get("interface/editor/update_vital_only");
bool continuous = get("interface/editor/update_continuously");
if (vital_only && !continuous) {
blink = false;
}
return blink;
}
bool EditorSettings::is_dark_theme() {
int AUTO_COLOR = 0;
int LIGHT_COLOR = 2;

View file

@ -179,6 +179,7 @@ public:
void load_favorites();
bool is_dark_theme();
bool is_caret_blink_active() const;
void list_text_editor_themes();
void load_text_editor_theme();

View file

@ -370,7 +370,7 @@ void ShaderEditor::_editor_settings_changed() {
shader_editor->get_text_edit()->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/highlighting/syntax_highlighting"));
shader_editor->get_text_edit()->set_highlight_all_occurrences(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_all_occurrences"));
shader_editor->get_text_edit()->set_highlight_current_line(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_current_line"));
shader_editor->get_text_edit()->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink"));
shader_editor->get_text_edit()->cursor_set_blink_enabled(EditorSettings::get_singleton()->is_caret_blink_active());
shader_editor->get_text_edit()->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed"));
shader_editor->get_text_edit()->add_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/theme/line_spacing"));
shader_editor->get_text_edit()->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret"));

View file

@ -2277,7 +2277,16 @@ bool Main::iteration() {
if (OS::get_singleton()->can_draw() && VisualServer::get_singleton()->is_render_loop_enabled()) {
if ((!force_redraw_requested) && OS::get_singleton()->is_in_low_processor_usage_mode()) {
if (VisualServer::get_singleton()->has_changed()) {
// We can choose whether to redraw as a result of any redraw request, or redraw only for vital requests.
VisualServer::ChangedPriority priority = (OS::get_singleton()->is_update_pending() ? VisualServer::CHANGED_PRIORITY_ANY : VisualServer::CHANGED_PRIORITY_HIGH);
// Determine whether the scene has changed, to know whether to draw.
// If it has changed, inform the update pending system so it can keep
// particle systems etc updating when running in vital updates only mode.
bool has_changed = VisualServer::get_singleton()->has_changed(priority);
OS::get_singleton()->set_update_pending(has_changed);
if (has_changed) {
VisualServer::get_singleton()->draw(true, scaled_step); // flush visual commands
Engine::get_singleton()->frames_drawn++;
}

View file

@ -30,6 +30,7 @@
#include "cpu_particles_2d.h"
#include "core/core_string_names.h"
#include "core/os/os.h"
#include "scene/2d/canvas_item.h"
#include "scene/2d/particles_2d.h"
#include "scene/resources/particles_material.h"
@ -1028,9 +1029,11 @@ void CPUParticles2D::_set_redraw(bool p_redraw) {
}
void CPUParticles2D::_update_render_thread() {
update_mutex.lock();
VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data);
update_mutex.unlock();
if (OS::get_singleton()->is_update_pending(true)) {
update_mutex.lock();
VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data);
update_mutex.unlock();
}
}
void CPUParticles2D::_notification(int p_what) {

View file

@ -30,6 +30,7 @@
#include "cpu_particles.h"
#include "core/os/os.h"
#include "scene/3d/camera.h"
#include "scene/3d/particles.h"
#include "scene/resources/particles_material.h"
@ -1152,14 +1153,16 @@ void CPUParticles::_set_redraw(bool p_redraw) {
}
void CPUParticles::_update_render_thread() {
update_mutex.lock();
if (OS::get_singleton()->is_update_pending(true)) {
update_mutex.lock();
if (can_update.is_set()) {
VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data);
can_update.clear(); //wait for next time
if (can_update.is_set()) {
VS::get_singleton()->multimesh_set_as_bulk_array(multimesh, particle_data);
can_update.clear(); //wait for next time
}
update_mutex.unlock();
}
update_mutex.unlock();
}
void CPUParticles::_notification(int p_what) {

View file

@ -1236,12 +1236,14 @@ void AnimationTree::advance(float p_time) {
}
void AnimationTree::_notification(int p_what) {
if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_mode == ANIMATION_PROCESS_PHYSICS) {
_process_graph(get_physics_process_delta_time());
}
if (active && OS::get_singleton()->is_update_pending()) {
if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_mode == ANIMATION_PROCESS_PHYSICS) {
_process_graph(get_physics_process_delta_time());
}
if (active && p_what == NOTIFICATION_INTERNAL_PROCESS && process_mode == ANIMATION_PROCESS_IDLE) {
_process_graph(get_process_delta_time());
if (p_what == NOTIFICATION_INTERNAL_PROCESS && process_mode == ANIMATION_PROCESS_IDLE) {
_process_graph(get_process_delta_time());
}
}
if (p_what == NOTIFICATION_EXIT_TREE) {

View file

@ -31,6 +31,7 @@
#include "animation_tree_player.h"
#include "animation_player.h"
#include "core/os/os.h"
#include "scene/scene_string_names.h"
void AnimationTreePlayer::set_animation_process_mode(AnimationProcessMode p_mode) {
@ -433,7 +434,7 @@ void AnimationTreePlayer::_notification(int p_what) {
break;
}
if (processing) {
if (processing && OS::get_singleton()->is_update_pending()) {
_process_animation(get_process_delta_time());
}
} break;
@ -442,7 +443,7 @@ void AnimationTreePlayer::_notification(int p_what) {
break;
}
if (processing) {
if (processing && OS::get_singleton()->is_update_pending()) {
_process_animation(get_physics_process_delta_time());
}
} break;

View file

@ -687,7 +687,8 @@ void LineEdit::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint() && !get_tree()->is_node_being_edited(this)) {
cursor_set_blink_enabled(EDITOR_DEF("text_editor/cursor/caret_blink", false));
EDITOR_DEF("text_editor/cursor/caret_blink", false);
cursor_set_blink_enabled(EditorSettings::get_singleton()->is_caret_blink_active());
cursor_set_blink_speed(EDITOR_DEF("text_editor/cursor/caret_blink_speed", 0.65));
if (!EditorSettings::get_singleton()->is_connected("settings_changed", this, "_editor_settings_changed")) {
@ -1669,7 +1670,8 @@ PopupMenu *LineEdit::get_menu() const {
void LineEdit::_editor_settings_changed() {
#ifdef TOOLS_ENABLED
cursor_set_blink_enabled(EDITOR_DEF("text_editor/cursor/caret_blink", false));
EDITOR_DEF("text_editor/cursor/caret_blink", false);
cursor_set_blink_enabled(EditorSettings::get_singleton()->is_caret_blink_active());
cursor_set_blink_speed(EDITOR_DEF("text_editor/cursor/caret_blink_speed", 0.65));
#endif
}

View file

@ -172,7 +172,7 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor
}
if (ci->update_when_visible) {
VisualServerRaster::redraw_request();
VisualServerRaster::redraw_request(false);
}
if ((!ci->commands.empty() && p_clip_rect.intersects(global_rect, true)) || ci->vp_render || ci->copy_back_buffer) {

View file

@ -40,7 +40,7 @@
// careful, these may run in different threads than the visual server
int VisualServerRaster::changes = 0;
int VisualServerRaster::changes[2] = { 0 };
/* BLACK BARS */
@ -98,7 +98,8 @@ void VisualServerRaster::draw(bool p_swap_buffers, double frame_step) {
//needs to be done before changes is reset to 0, to not force the editor to redraw
VS::get_singleton()->emit_signal("frame_pre_draw");
changes = 0;
changes[0] = 0;
changes[1] = 0;
VSG::rasterizer->begin_frame(frame_step);
@ -127,8 +128,19 @@ void VisualServerRaster::draw(bool p_swap_buffers, double frame_step) {
}
void VisualServerRaster::sync() {
}
bool VisualServerRaster::has_changed() const {
return changes > 0;
bool VisualServerRaster::has_changed(ChangedPriority p_priority) const {
switch (p_priority) {
default: {
return (changes[0] > 0) || (changes[1] > 0);
} break;
case CHANGED_PRIORITY_LOW: {
return changes[0] > 0;
} break;
case CHANGED_PRIORITY_HIGH: {
return changes[1] > 0;
} break;
}
}
void VisualServerRaster::init() {
VSG::rasterizer->initialize();

View file

@ -53,7 +53,8 @@ class VisualServerRaster : public VisualServer {
};
static int changes;
// low and high priority
static int changes[2];
RID test_cube;
int black_margin[4];
@ -68,27 +69,36 @@ class VisualServerRaster : public VisualServer {
List<FrameDrawnCallbacks> frame_drawn_callbacks;
void _draw_margins();
static void _changes_changed() {}
public:
//if editor is redrawing when it shouldn't, enable this and put a breakpoint in _changes_changed()
//#define DEBUG_CHANGES
#ifdef DEBUG_CHANGES
_FORCE_INLINE_ static void redraw_request() {
changes++;
_changes_changed();
// This function is NOT dead code.
// It is specifically for debugging redraws to help identify problems with
// undesired constant editor updating.
// The function will be called in DEV builds (and thus does not require a recompile),
// allowing you to place a breakpoint either at the first line or the semicolon.
// You can then look at the callstack to find the cause of the redraw.
static void _changes_changed(int p_priority) {
if (p_priority) {
;
}
}
#define DISPLAY_CHANGED \
changes++; \
_changes_changed();
public:
// if editor is redrawing when it shouldn't, use a DEV build and put a breakpoint in _changes_changed()
_FORCE_INLINE_ static void redraw_request(bool p_high_priority = true) {
int priority = p_high_priority ? 1 : 0;
changes[priority] += 1;
#ifdef DEV_ENABLED
_changes_changed(priority);
#endif
}
#ifdef DEV_ENABLED
#define DISPLAY_CHANGED \
changes[1] += 1; \
_changes_changed(1);
#else
_FORCE_INLINE_ static void redraw_request() { changes++; }
#define DISPLAY_CHANGED \
changes++;
changes[1] += 1;
#endif
#define BIND0R(m_r, m_name) \
@ -736,7 +746,7 @@ public:
virtual void draw(bool p_swap_buffers, double frame_step);
virtual void sync();
virtual bool has_changed() const;
virtual bool has_changed(ChangedPriority p_priority = CHANGED_PRIORITY_ANY) const;
virtual void init();
virtual void finish();

View file

@ -2633,7 +2633,7 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(ins->base_data);
if (ins->redraw_if_visible) {
VisualServerRaster::redraw_request();
VisualServerRaster::redraw_request(false);
}
if (ins->base_type == VS::INSTANCE_PARTICLES) {
@ -2642,9 +2642,11 @@ void VisualServerScene::_prepare_scene(const Transform p_cam_transform, const Ca
//but if nothing is going on, don't do it.
keep = false;
} else {
VSG::storage->particles_request_process(ins->base);
//particles visible? request redraw
VisualServerRaster::redraw_request();
if (OS::get_singleton()->is_update_pending(true)) {
VSG::storage->particles_request_process(ins->base);
//particles visible? request redraw
VisualServerRaster::redraw_request(false);
}
}
}

View file

@ -657,7 +657,7 @@ public:
virtual void finish();
virtual void draw(bool p_swap_buffers, double frame_step);
virtual void sync();
FUNC0RC(bool, has_changed)
FUNC1RC(bool, has_changed, ChangedPriority)
/* RENDER INFO */

View file

@ -2230,7 +2230,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &VisualServer::free); // shouldn't conflict with Object::free()
ClassDB::bind_method(D_METHOD("request_frame_drawn_callback", "where", "method", "userdata"), &VisualServer::request_frame_drawn_callback);
ClassDB::bind_method(D_METHOD("has_changed"), &VisualServer::has_changed);
ClassDB::bind_method(D_METHOD("has_changed", "queried_priority"), &VisualServer::has_changed, DEFVAL(CHANGED_PRIORITY_ANY));
ClassDB::bind_method(D_METHOD("init"), &VisualServer::init);
ClassDB::bind_method(D_METHOD("finish"), &VisualServer::finish);
ClassDB::bind_method(D_METHOD("get_render_info", "info"), &VisualServer::get_render_info);
@ -2522,6 +2522,10 @@ void VisualServer::_bind_methods() {
BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_2x2);
BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_3x3);
BIND_ENUM_CONSTANT(CHANGED_PRIORITY_ANY);
BIND_ENUM_CONSTANT(CHANGED_PRIORITY_LOW);
BIND_ENUM_CONSTANT(CHANGED_PRIORITY_HIGH);
ADD_SIGNAL(MethodInfo("frame_pre_draw"));
ADD_SIGNAL(MethodInfo("frame_post_draw"));
}

View file

@ -1103,9 +1103,15 @@ public:
/* EVENT QUEUING */
enum ChangedPriority {
CHANGED_PRIORITY_ANY = 0,
CHANGED_PRIORITY_LOW,
CHANGED_PRIORITY_HIGH,
};
virtual void draw(bool p_swap_buffers = true, double frame_step = 0.0) = 0;
virtual void sync() = 0;
virtual bool has_changed() const = 0;
virtual bool has_changed(ChangedPriority p_priority = CHANGED_PRIORITY_ANY) const = 0;
virtual void init() = 0;
virtual void finish() = 0;
@ -1220,6 +1226,7 @@ VARIANT_ENUM_CAST(VisualServer::EnvironmentSSAOBlur);
VARIANT_ENUM_CAST(VisualServer::InstanceFlags);
VARIANT_ENUM_CAST(VisualServer::ShadowCastingSetting);
VARIANT_ENUM_CAST(VisualServer::TextureType);
VARIANT_ENUM_CAST(VisualServer::ChangedPriority);
//typedef VisualServer VS; // makes it easier to use
#define VS VisualServer