Skip to content

Commit

Permalink
optimize color write and increase bitblt limits
Browse files Browse the repository at this point in the history
the color write improvements appears to give clients a 90% speed up on loading color nbt
  • Loading branch information
payonel committed May 24, 2020
1 parent 6ff0d78 commit 20f2cc4
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 21 deletions.
6 changes: 3 additions & 3 deletions src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -1598,8 +1598,8 @@ opencomputers {
# This setting assigns the budget call cost to invoke bitblt to write vram
# to a screen. Video ram can bitblit to a screen which can cause real life
# network laod the defaults settings put bitblit network impact close to gpu.set
# Increase these values to throttle bitblt more. These values appear inverted
# but the cost of bitblt is based on the max resolution of the device
bitbltCosts: [ 1, 2, 8 ]
# Increase these values to throttle bitblt more. The cost tier N is bitbltCost * 2^(tier)
# default is .5, which gives: .5, 1, 4
bitbltCost: 0.5
}
}
7 changes: 1 addition & 6 deletions src/main/scala/li/cil/oc/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -476,12 +476,7 @@ class Settings(val config: Config) {
Array(1, 2, 3)
}

val bitbltCosts: Array[Double] = Array(config.getDoubleList("gpu.bitbltCosts"): _*) match {
case Array(tier1, tier2, tier3) => Array(tier1: Double, tier2: Double, tier3: Double)
case _ =>
OpenComputers.log.warn("Bad number of bitblit costs (expected 3), ignoring.")
Array(1, 2, 8)
}
val bitbltCost: Double = if (config.hasPath("gpu.bitbltCost")) config.getDouble("gpu.bitbltCost") else 0.5
}

object Settings {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class GraphicsCard(val tier: Int) extends prefab.ManagedEnvironment with DeviceI
// These are dirty page bitblt budget costs
// a single bitblt can send a screen of data, which is n*set calls where set is writing an entire line
// So for each tier, we multiple the set cost with the number of lines the screen may have
final val bitbltCost: Double = Settings.get.bitbltCosts(0 max tier min 2)
final val bitbltCost: Double = Settings.get.bitbltCost * scala.math.pow(2, tier)
final val totalVRAM: Double = (maxResolution._1 * maxResolution._2) * Settings.get.vramSizes(0 max tier min 2)

var budgetExhausted: Boolean = false // for especially expensive calls, bitblt
Expand Down
49 changes: 49 additions & 0 deletions src/main/scala/li/cil/oc/util/NbtDataStream.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package li.cil.oc.util

import net.minecraft.nbt.NBTTagCompound

object NbtDataStream {
def getShortArray(nbt: NBTTagCompound, key: String, array2d: Array[Array[Short]], w: Int, h: Int) : Boolean = {
if (!nbt.hasKey(key)) {
return false
}

val rawByteReader = new java.io.ByteArrayInputStream(nbt.getByteArray(key))
val memReader = new java.io.DataInputStream(rawByteReader)
for (y <- 0 until h) {
for (x <- 0 until w) {
if (2 > memReader.available()) {
return true // not great, but get out now
}
array2d(y)(x) = memReader.readShort()
}
}
true
}

def getIntArrayLegacy(nbt: NBTTagCompound, key: String, array2d: Array[Array[Short]], w: Int, h: Int) : Boolean = {
if (!nbt.hasKey(key)) {
return false
}
// legacy format
val c = nbt.getIntArray(key)
for (y <- 0 until h) {
val rowColor = array2d(y)
for (x <- 0 until w) {
val index = x + y * w
if (index >= c.length) {
return true // not great, but, the read at least started
}
rowColor(x) = c(index).toShort
}
}
true
}

def setShortArray(nbt: NBTTagCompound, key: String, array: Array[Short]): Unit = {
val rawByteWriter = new java.io.ByteArrayOutputStream()
val memWriter = new java.io.DataOutputStream(rawByteWriter)
array.foreach(memWriter.writeShort(_))
nbt.setByteArray(key, rawByteWriter.toByteArray)
}
}
15 changes: 4 additions & 11 deletions src/main/scala/li/cil/oc/util/TextBuffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -262,15 +262,8 @@ class TextBuffer(var width: Int, var height: Int, initialFormat: PackedColor.Col
foreground = PackedColor.Color(nbt.getInteger("foreground"), nbt.getBoolean("foregroundIsPalette"))
background = PackedColor.Color(nbt.getInteger("background"), nbt.getBoolean("backgroundIsPalette"))

val c = nbt.getIntArray("color")
for (i <- 0 until h) {
val rowColor = color(i)
for (j <- 0 until w) {
val index = j + i * w
if (index < c.length) {
rowColor(j) = c(index).toShort
}
}
if (!NbtDataStream.getShortArray(nbt, "color_bytes", color, w, h)) {
NbtDataStream.getIntArrayLegacy(nbt, "color", color, w, h)
}
}

Expand All @@ -291,10 +284,10 @@ class TextBuffer(var width: Int, var height: Int, initialFormat: PackedColor.Col
nbt.setInteger("background", _background.value)
nbt.setBoolean("backgroundIsPalette", _background.isPalette)

nbt.setTag("color", new NBTTagIntArray(color.flatten.map(_.toInt)))
NbtDataStream.setShortArray(nbt, "color_bytes", color.flatten.map(_.toShort))
}

override def toString = {
override def toString: String = {
val b = StringBuilder.newBuilder
if (buffer.length > 0) {
b.appendAll(buffer(0))
Expand Down

0 comments on commit 20f2cc4

Please sign in to comment.