Skip to content

Commit

Permalink
Add support for Remotery profiler
Browse files Browse the repository at this point in the history
  • Loading branch information
skalarproduktraum committed Nov 29, 2019
1 parent 51890e6 commit aaf900b
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 1 deletion.
13 changes: 12 additions & 1 deletion pom.xml
Expand Up @@ -395,7 +395,18 @@
<version>${lwjgl.version}</version>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<!-- LWJGL dependencies END -->
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-remotery</artifactId>
<version>${lwjgl.version}</version>
</dependency>
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-remotery</artifactId>
<version>${lwjgl.version}</version>
<classifier>${lwjgl.natives}</classifier>
</dependency>
<!-- LWJGL dependencies END -->

<!-- jackson dependencies -->
<dependency>
Expand Down
12 changes: 12 additions & 0 deletions src/main/kotlin/graphics/scenery/SceneryBase.kt
Expand Up @@ -12,6 +12,7 @@ import graphics.scenery.net.NodePublisher
import graphics.scenery.net.NodeSubscriber
import graphics.scenery.repl.REPL
import graphics.scenery.utils.LazyLogger
import graphics.scenery.utils.Remotery
import graphics.scenery.utils.Renderdoc
import graphics.scenery.utils.SceneryPanel
import graphics.scenery.utils.Statistics
Expand All @@ -21,6 +22,7 @@ import org.scijava.ui.behaviour.ClickBehaviour
import java.lang.Boolean.parseBoolean
import java.lang.management.ManagementFactory
import java.nio.file.Paths
import java.rmi.Remote
import java.util.*
import java.util.concurrent.CountDownLatch
import kotlin.concurrent.thread
Expand Down Expand Up @@ -142,6 +144,10 @@ open class SceneryBase @JvmOverloads constructor(var applicationName: String,
logger.info("Started application as PID ${getProcessID()}")
running = true

if(parseBoolean(System.getProperty("scenery.Profiler", "false"))) {
hub.add(Remotery(hub))
}

val headless = parseBoolean(System.getProperty("scenery.Headless", "false"))
val renderdoc = if(System.getProperty("scenery.AttachRenderdoc")?.toBoolean() == true) {
Renderdoc()
Expand Down Expand Up @@ -234,16 +240,20 @@ open class SceneryBase @JvmOverloads constructor(var applicationName: String,
val frameTimes = ArrayDeque<Float>(16)
val frameTimeKeepCount = 16

val profiler = hub.get<Remotery>()

while (!shouldClose || gracePeriod > 0) {
runtime = (System.nanoTime() - startTime) / 1000000f
settings.set("System.Runtime", runtime)

profiler?.begin("Render")
if (renderer?.managesRenderLoop != false) {
renderer?.render()
Thread.sleep(1)
} else {
stats.addTimed("render") { renderer?.render() ?: 0.0f }
}
profiler?.end()

// only run loop if we are either in standalone mode, or master
// for details about the interpolation code, see
Expand Down Expand Up @@ -328,6 +338,8 @@ open class SceneryBase @JvmOverloads constructor(var applicationName: String,
inputHandler?.close()
renderer?.close()
renderdoc?.close()

hub.get<Remotery>()?.close()
}

/**
Expand Down
78 changes: 78 additions & 0 deletions src/main/kotlin/graphics/scenery/utils/Remotery.kt
@@ -0,0 +1,78 @@
package graphics.scenery.utils

import graphics.scenery.Hub
import graphics.scenery.Hubable
import org.lwjgl.PointerBuffer
import org.lwjgl.util.remotery.Remotery.RMTSF_Aggregate
import org.lwjgl.util.remotery.Remotery.RMTSF_None
import org.lwjgl.util.remotery.Remotery.RMTSF_Recursive
import org.lwjgl.util.remotery.Remotery.rmt_BeginCPUSample
import org.lwjgl.util.remotery.Remotery.rmt_CreateGlobalInstance
import org.lwjgl.util.remotery.Remotery.rmt_DestroyGlobalInstance
import org.lwjgl.util.remotery.Remotery.rmt_EndCPUSample
import org.lwjgl.util.remotery.Remotery.rmt_SetCurrentThreadName

/**
* Class for using the Remotery profiler.
* To use, set `scenery.Profiler` to true, and connect to the profiler
* by using opening `vis/index.html` from the [Remotery Github repository](https://github.com/Celtoys/Remotery).
*
* As parameter, the class requires a [hub] to attach to.
*
* @author Ulrik Guenther <hello@ulrik.is>
*/
class Remotery(override var hub : Hub?) : Hubable, AutoCloseable {
private var instance = PointerBuffer.allocateDirect(1)
private val logger by LazyLogger()

/**
* Remotery sample type.
*/
enum class SampleType(val t: Int) {
/** Default behaviour, samples will not be merged. */
Default(RMTSF_None),
/** Search parent for samples of the same name and merge the timing instead of adding a new sample. */
Aggregate(RMTSF_Aggregate),
/** Merge sample with the parent's if it is the same sample. */
Recursive(RMTSF_Recursive)
}

init {
val error = rmt_CreateGlobalInstance(instance)
if(error == 0) {
logger.info("Created Remotery profiler instance")
} else {
throw IllegalStateException("Could not create Remotery profiler ($error)")
}
}

/**
* Sets the current thread name to [name].
*/
fun setThreadName(name: String) {
rmt_SetCurrentThreadName(name)
}

/**
* Begins a new sample with [name]. Default type is [SampleType.Default].
* Calls to [begin] and [end] behave like brackets an can be nested.
*/
fun begin(name: String = "", type: SampleType = SampleType.Default) {
rmt_BeginCPUSample(name, type.ordinal, null)
}

/**
* Ends the current sample. Must have a corresponding [begin].
*/
fun end() {
rmt_EndCPUSample()
}

/**
* Closes the Remotery instance.
*/
override fun close() {
rmt_DestroyGlobalInstance(instance.get(0))
logger.info("Closing Remotery...")
}
}

0 comments on commit aaf900b

Please sign in to comment.