Lighting Performance Tweaks & Fixes (#3325)

changes:

SSlighting is now FIFO - lights are processed in the order they are received instead of by whatever one was queued most recently.
Instant lighting updates now check CURRENT_TICKLIMIT instead of ITL. ITL has been removed due to it no longer being used.
SSlighting will no longer double-process lighting datums that have already been processed by instant lighting.
Instant/Intelligent lighting updates can now be disabled via. compile-time define.
Sunlight should no longer shine indoors.
Directional lighting now properly updates on direction changes again.
/datum/light_source/novis has been renamed to /datum/light_source/sunlight.
More lighting microoptimizations.
Converted two storage lists to be lazy.
This commit is contained in:
Lohikar
2017-08-28 01:06:17 +03:00
committed by Erki
parent fb3ac0d718
commit f8bcaf4864
10 changed files with 131 additions and 90 deletions
+67 -28
View File
@@ -13,17 +13,20 @@ var/datum/controller/subsystem/lighting/SSlighting
var/list/lighting_corners // List of all lighting corners in the world.
var/list/light_queue = list() // lighting sources queued for update.
var/lq_idex = 1
var/list/corner_queue = list() // lighting corners queued for update.
var/cq_idex = 1
var/list/overlay_queue = list() // lighting overlays queued for update.
var/oq_idex = 1
var/tmp/processed_lights = 0
var/tmp/processed_corners = 0
var/tmp/processed_overlays = 0
#ifdef USE_INTELLIGENT_LIGHTING_UPDATES
var/force_queued = TRUE
var/force_override = FALSE // For admins.
var/instant_tick_limit = 80 // Tick limit used by instant lighting updates. If world.tick_usage is higher than this when a light updates, it will be updated via. SSlighting.
#endif
/datum/controller/subsystem/lighting/New()
NEW_SS_GLOBAL(SSlighting)
@@ -31,10 +34,14 @@ var/datum/controller/subsystem/lighting/SSlighting
LAZYINITLIST(lighting_overlays)
/datum/controller/subsystem/lighting/stat_entry()
var/out = "O:[lighting_overlays.len] C:[lighting_corners.len] ITL:[round(instant_tick_limit, 0.1)]%\n"
out += "\tP:{L:[light_queue.len]|C:[corner_queue.len]|O:[overlay_queue.len]}\n"
out += "\tL:{L:[processed_lights]|C:[processed_corners]|O:[processed_overlays]}\n"
..(out)
var/list/out = list(
"O:[lighting_overlays.len] C:[lighting_corners.len]\n",
"\tP:{L:[light_queue.len - (lq_idex - 1)]|C:[corner_queue.len - (cq_idex - 1)]|O:[overlay_queue.len - (oq_idex - 1)]}\n",
"\tL:{L:[processed_lights]|C:[processed_corners]|O:[processed_overlays]}\n"
)
..(out.Join())
#ifdef USE_INTELLIGENT_LIGHTING_UPDATES
/datum/controller/subsystem/lighting/ExplosionStart()
force_queued = TRUE
@@ -43,9 +50,12 @@ var/datum/controller/subsystem/lighting/SSlighting
if (!force_override)
force_queued = FALSE
/datum/controller/subsystem/lighting/proc/handle_roundstart()
force_queued = FALSE
#endif
/datum/controller/subsystem/lighting/Initialize(timeofday)
var/overlaycount = 0
var/starttime = REALTIMEOFDAY
@@ -80,7 +90,9 @@ var/datum/controller/subsystem/lighting/SSlighting
log_ss("lighting", "NOv:[overlaycount] L:[processed_lights] C:[processed_corners] O:[processed_overlays]")
#ifdef USE_INTELLIGENT_LIGHTING_UPDATES
SSticker.OnRoundstart(CALLBACK(src, .proc/handle_roundstart))
#endif
..()
@@ -89,8 +101,6 @@ var/datum/controller/subsystem/lighting/SSlighting
processed_lights = 0
processed_corners = 0
processed_overlays = 0
instant_tick_limit = CURRENT_TICKLIMIT * 0.8
MC_SPLIT_TICK_INIT(3)
if (!no_mc_tick)
@@ -100,59 +110,88 @@ var/datum/controller/subsystem/lighting/SSlighting
var/list/curr_corners = corner_queue
var/list/curr_overlays = overlay_queue
while (curr_lights.len)
var/datum/light_source/L = curr_lights[curr_lights.len]
curr_lights.len--
while (lq_idex <= curr_lights.len)
var/datum/light_source/L = curr_lights[lq_idex++]
L.update_corners()
if (L.needs_update != LIGHTING_NO_UPDATE)
L.update_corners()
L.needs_update = LIGHTING_NO_UPDATE
L.needs_update = LIGHTING_NO_UPDATE
processed_lights++
processed_lights++
if (no_mc_tick)
CHECK_TICK
else if (MC_TICK_CHECK)
break
if (lq_idex > 1)
curr_lights.Cut(1, lq_idex)
lq_idex = 1
if (!no_mc_tick)
MC_SPLIT_TICK
while (curr_corners.len)
var/datum/lighting_corner/C = curr_corners[curr_corners.len]
curr_corners.len--
while (cq_idex <= curr_corners.len)
var/datum/lighting_corner/C = curr_corners[cq_idex++]
C.update_overlays()
if (C.needs_update)
C.update_overlays()
C.needs_update = FALSE
C.needs_update = FALSE
processed_corners++
processed_corners++
if (no_mc_tick)
CHECK_TICK
else if (MC_TICK_CHECK)
break
if (cq_idex > 1)
curr_corners.Cut(1, cq_idex)
cq_idex = 1
if (!no_mc_tick)
MC_SPLIT_TICK
while (curr_overlays.len)
var/atom/movable/lighting_overlay/O = curr_overlays[curr_overlays.len]
curr_overlays.len--
while (oq_idex <= curr_overlays.len)
var/atom/movable/lighting_overlay/O = curr_overlays[oq_idex++]
O.update_overlay()
O.needs_update = FALSE
if (O.needs_update)
O.update_overlay()
O.needs_update = FALSE
processed_overlays++
processed_overlays++
if (no_mc_tick)
CHECK_TICK
else if (MC_TICK_CHECK)
break
if (oq_idex > 1)
curr_overlays.Cut(1, oq_idex)
oq_idex = 1
/datum/controller/subsystem/lighting/Recover()
lighting_corners = SSlighting.lighting_corners
lighting_overlays = SSlighting.lighting_overlays
src.light_queue = SSlighting.light_queue
src.corner_queue = SSlighting.corner_queue
src.overlay_queue = SSlighting.overlay_queue
lighting_corners = SSlighting.lighting_corners
lighting_overlays = SSlighting.lighting_overlays
lq_idex = SSlighting.lq_idex
cq_idex = SSlighting.cq_idex
oq_idex = SSlighting.oq_idex
if (lq_idex > 1)
light_queue.Cut(1, lq_idex)
lq_idex = 1
if (cq_idex > 1)
corner_queue.Cut(1, cq_idex)
cq_idex = 1
if (oq_idex > 1)
overlay_queue.Cut(1, oq_idex)
oq_idex = 1
-4
View File
@@ -41,16 +41,12 @@
/datum/controller/subsystem/sunlight/proc/set_overall_light(...)
. = 0
SSlighting.force_queued = TRUE
for (var/thing in light_points)
var/atom/movable/AM = thing
AM.set_light(arglist(args))
.++
CHECK_TICK
if (!SSlighting.force_override)
SSlighting.force_queued = FALSE
/datum/controller/subsystem/sunlight/proc/apply_sun_state(datum/sun_state/S)
log_debug("sunlight: Applying preset [S].")
set_overall_light(config.sun_accuracy * 1.2, 1, S.color)