From 812e9e5b76d530f0cecc9ccf43f0ef285b544f0a Mon Sep 17 00:00:00 2001 From: minjaesong Date: Wed, 5 Jun 2019 21:04:01 +0900 Subject: [PATCH] light parallel failed attempt --- src/net/torvald/terrarum/DefaultConfig.kt | 2 +- .../terrarum/concurrent/ThreadParallel.kt | 21 ++++++--- .../torvald/terrarum/tests/NoiseGenerator.kt | 2 +- .../worlddrawer/LightmapRendererNew.kt | 46 ++++++++++++++++--- 4 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/net/torvald/terrarum/DefaultConfig.kt b/src/net/torvald/terrarum/DefaultConfig.kt index a0eed89f3..b2df63eeb 100644 --- a/src/net/torvald/terrarum/DefaultConfig.kt +++ b/src/net/torvald/terrarum/DefaultConfig.kt @@ -25,7 +25,7 @@ object DefaultConfig { jsonObject.addProperty("language", AppLoader.getSysLang()) jsonObject.addProperty("notificationshowuptime", 4000) jsonObject.addProperty("multithread", true) // experimental! - jsonObject.addProperty("multithreadedlight", false) // experimental! + jsonObject.addProperty("multithreadedlight", true) // experimental! diff --git a/src/net/torvald/terrarum/concurrent/ThreadParallel.kt b/src/net/torvald/terrarum/concurrent/ThreadParallel.kt index 3d5e5d208..5e144b270 100644 --- a/src/net/torvald/terrarum/concurrent/ThreadParallel.kt +++ b/src/net/torvald/terrarum/concurrent/ThreadParallel.kt @@ -1,6 +1,7 @@ package net.torvald.terrarum.concurrent import net.torvald.terrarum.Terrarum +import kotlin.math.absoluteValue typealias RunnableFun = () -> Unit /** Int: index of the processing core */ @@ -12,7 +13,7 @@ typealias ThreadableFun = (Int) -> Unit object ThreadParallel { val threadCount = Terrarum.THREADS // modify this to your taste - private val pool: Array = Array(threadCount, { null }) + private val pool: Array = Array(threadCount) { null } /** * Map Runnable object to certain index of the thread pool. @@ -189,13 +190,19 @@ object ParallelUtils { } } - fun IntRange.sliceEvenly(slices: Int): List { - if (this.step != 1) throw UnsupportedOperationException("Sorry, step != 1") - val size = this.last - this.first + 1f + fun IntProgression.sliceEvenly(slices: Int): List { + if (this.step.absoluteValue != 1) throw UnsupportedOperationException("Sorry, step != +1/-1") + val size = (this.last - this.first).absoluteValue + (this.step.toFloat()).absoluteValue - return (0 until slices).map { - size.div(slices).times(it).roundInt() until - size.div(slices).times(it + 1).roundInt() + // println(size) + + return if (this.first < this.last) (0 until slices).map { + this.first + size.div(slices).times(it).roundInt() .. + this.first + size.div(slices).times(it + 1).roundInt() - 1 + } + else (0 until slices).map { + this.first - size.div(slices).times(it).roundInt() downTo + this.first - size.div(slices).times(it + 1).roundInt() + 1 } } diff --git a/src/net/torvald/terrarum/tests/NoiseGenerator.kt b/src/net/torvald/terrarum/tests/NoiseGenerator.kt index 3ab951cf3..7fda7fb6a 100644 --- a/src/net/torvald/terrarum/tests/NoiseGenerator.kt +++ b/src/net/torvald/terrarum/tests/NoiseGenerator.kt @@ -65,7 +65,7 @@ class NoiseGenerator : ScreenAdapter() { private val jobsCount: Int get() = (IMAGE_SIZE * IMAGE_SIZE) / pixelsInSingleJob - private val rawPixelsList: List + private val rawPixelsList: List get() = (0 until IMAGE_SIZE * IMAGE_SIZE).sliceEvenly(jobsCount) private fun makeGenFun(seed: Long, index: Int) = { //i: Int -> val module = ModuleFractal() diff --git a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt index 1d460a6f4..ece016522 100644 --- a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt +++ b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt @@ -12,6 +12,7 @@ import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.blockproperties.BlockCodex import net.torvald.terrarum.blockproperties.Fluid import net.torvald.terrarum.concurrent.ParallelUtils.sliceEvenly +import net.torvald.terrarum.concurrent.ThreadParallel import net.torvald.terrarum.gameactors.ActorWBMovable import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.gameactors.Luminous @@ -186,6 +187,8 @@ object LightmapRenderer { return // quit prematurely } + if (world.worldIndex == -1) return + for_x_start = WorldCamera.x / TILE_SIZE // fix for premature lightmap rendering for_y_start = WorldCamera.y / TILE_SIZE // on topmost/leftmost side @@ -251,38 +254,67 @@ object LightmapRenderer { AppLoader.measureDebugTime("Renderer.LightTotal") { // Round 2 for (y in for_y_end + overscan_open downTo for_y_start) { + // TODO multithread the following for loop duh for (x in for_x_start - overscan_open..for_x_end) { calculateAndAssign(lightmap, x, y) } } // Round 3 for (y in for_y_end + overscan_open downTo for_y_start) { + // TODO multithread the following for loop duh for (x in for_x_end + overscan_open downTo for_x_start) { calculateAndAssign(lightmap, x, y) } } // Round 4 for (y in for_y_start - overscan_open..for_y_end) { + // TODO multithread the following for loop duh for (x in for_x_end + overscan_open downTo for_x_start) { calculateAndAssign(lightmap, x, y) } } // Round 1 for (y in for_y_start - overscan_open..for_y_end) { + // TODO multithread the following for loop duh for (x in for_x_start - overscan_open..for_x_end) { calculateAndAssign(lightmap, x, y) } } - // Round 2 again - /*for (y in for_y_end + overscan_open downTo for_y_start) { - for (x in for_x_start - overscan_open..for_x_end) { - calculateAndAssign(lightmap, x, y) - } - }*/ } } else if (world.worldIndex != -1) { // to avoid updating on the null world - TODO() + val roundsY = arrayOf( + (for_y_end + overscan_open downTo for_y_start).sliceEvenly(ThreadParallel.threadCount), + (for_y_end + overscan_open downTo for_y_start).sliceEvenly(ThreadParallel.threadCount), + (for_y_start - overscan_open..for_y_end).sliceEvenly(ThreadParallel.threadCount), + (for_y_start - overscan_open..for_y_end).sliceEvenly(ThreadParallel.threadCount) + ) + val roundsX = arrayOf( + (for_x_start - overscan_open..for_x_end), + (for_x_end + overscan_open downTo for_x_start), + (for_x_end + overscan_open downTo for_x_start), + (for_x_start - overscan_open..for_x_end) + ) + + AppLoader.measureDebugTime("Renderer.LightParallelPre") { + for (round in 0..roundsY.lastIndex) { + roundsY[round].forEachIndexed { index, yRange -> + ThreadParallel.map(index, "lightrender-round${round + 1}") { + for (y in yRange) { + for (x in roundsX[round]) { + calculateAndAssign(lightmap, x, y) + } + } + } + } + } + } + + AppLoader.measureDebugTime("Renderer.LightParallelRun") { + ThreadParallel.startAllWaitForDie() + } + + } }