From 1fb6181ba63c1b258dbeff3ac0e577a664f03a26 Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Sat, 11 Apr 2020 17:40:30 +0100 Subject: [PATCH] Revert to default Rect drawing code for single rects Determined that a large reason for the decrease in performance in unbatchable scenes was due to the new routine being analogous to the 'nvidia workaround' code, that is about half the speed. So this simply uses the old routine in the case of single unbatchable rects. Hopefully we will be able to remove the old path at a later stage. --- drivers/gles2/rasterizer_canvas_gles2.cpp | 48 +++++++++++++++++------ drivers/gles2/rasterizer_canvas_gles2.h | 14 +++++++ 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index 2698e49f570..17d22b6b061 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -250,21 +250,45 @@ bool RasterizerCanvasGLES2::prefill_joined_item(FillState &r_fill_state, int &r_ switch (command->type) { default: { - if (r_fill_state.curr_batch->type == Batch::BT_DEFAULT) { - // another default command, just add to the existing batch - r_fill_state.curr_batch->num_commands++; - } else { - // end of previous different type batch, so start new default batch - r_fill_state.curr_batch = _batch_request_new(); - r_fill_state.curr_batch->type = Batch::BT_DEFAULT; - r_fill_state.curr_batch->first_command = command_num; - r_fill_state.curr_batch->num_commands = 1; - } + _prefill_default_batch(r_fill_state, command_num); } break; case Item::Command::TYPE_RECT: { Item::CommandRect *rect = static_cast(command); + bool change_batch = false; + + // conditions for creating a new batch + if (r_fill_state.curr_batch->type != Batch::BT_RECT) { + change_batch = true; + + // check for special case if there is only a single or small number of rects, + // in which case we will use the legacy default rect renderer + // because it is faster for single rects + + // we only want to do this if not a joined item with more than 1 item, + // because joined items with more than 1, the command * will be incorrect + // NOTE - this is assuming that use_hardware_transform means that it is a non-joined item!! + // If that assumption is incorrect this will go horribly wrong. + if (r_fill_state.use_hardware_transform) { + bool is_single_rect = false; + int command_num_next = command_num + 1; + if (command_num_next < command_count) { + Item::Command *command_next = commands[command_num_next]; + if (command_next->type != Item::Command::TYPE_RECT) { + is_single_rect = true; + } + } else { + is_single_rect = true; + } + // if it is a rect on its own, do exactly the same as the default routine + if (is_single_rect) { + _prefill_default_batch(r_fill_state, command_num); + break; + } + } + } // if use hardware transform + Color col = rect->modulate; if (multiply_final_modulate) { col *= r_fill_state.final_modulate; @@ -290,10 +314,8 @@ bool RasterizerCanvasGLES2::prefill_joined_item(FillState &r_fill_state, int &r_ return true; } - bool change_batch = false; - // conditions for creating a new batch - if ((r_fill_state.curr_batch->type != Batch::BT_RECT) || (old_batch_tex_id != r_fill_state.batch_tex_id)) { + if (old_batch_tex_id != r_fill_state.batch_tex_id) { change_batch = true; } diff --git a/drivers/gles2/rasterizer_canvas_gles2.h b/drivers/gles2/rasterizer_canvas_gles2.h index 44cb1584ad4..a1eab4fef41 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.h +++ b/drivers/gles2/rasterizer_canvas_gles2.h @@ -242,6 +242,7 @@ private: void _software_transform_vertex(BatchVector2 &r_v, const Transform2D &p_tr) const; void _software_transform_vertex(Vector2 &r_v, const Transform2D &p_tr) const; TransformMode _find_transform_mode(bool p_use_hardware_transform, const Transform2D &p_tr, Transform2D &r_tr) const; + _FORCE_INLINE_ void _prefill_default_batch(FillState &r_fill_state, int p_command_num); // light scissoring bool _light_find_intersection(const Rect2 &p_item_rect, const Transform2D &p_light_xform, const Rect2 &p_light_rect, Rect2 &r_cliprect) const; @@ -255,6 +256,19 @@ public: ////////////////////////////////////////////////////////////// +_FORCE_INLINE_ void RasterizerCanvasGLES2::_prefill_default_batch(FillState &r_fill_state, int p_command_num) { + if (r_fill_state.curr_batch->type == Batch::BT_DEFAULT) { + // another default command, just add to the existing batch + r_fill_state.curr_batch->num_commands++; + } else { + // end of previous different type batch, so start new default batch + r_fill_state.curr_batch = _batch_request_new(); + r_fill_state.curr_batch->type = Batch::BT_DEFAULT; + r_fill_state.curr_batch->first_command = p_command_num; + r_fill_state.curr_batch->num_commands = 1; + } +} + _FORCE_INLINE_ void RasterizerCanvasGLES2::_software_transform_vertex(BatchVector2 &r_v, const Transform2D &p_tr) const { Vector2 vc(r_v.x, r_v.y); vc = p_tr.xform(vc);