mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-09 07:15:11 -04:00
GPU speed up: Writing to the gpu buffer outside the viewport is free. no budget cost, no power cost, (also, writes are already direct calls)
We've discussed a large variety of options for the gpu I've reviewed our options and suggestions. Ultimately - users want faster graphics. Most of the ideas are relating to what api is meaningful to the user. The core issue we have in making graphics faster is an increase load on the server. For example Tier 3 GPU and Tier 3 Screen has a max resolution of 160x50 If you set the viewport (via gpu.setViewport) to 160x25 the bottom half of the buffer will no longer be shown. All gpu.set, gpu.copy, and gpu.fill calls into that space have no cost Overlaps are calculated for partial cost. Half in and half out will have half the power cost. closes #779
This commit is contained in:
parent
a13792aef3
commit
15d34a8660
@ -71,16 +71,40 @@ class GraphicsCard(val tier: Int) extends prefab.ManagedEnvironment with DeviceI
|
||||
DeviceAttribute.Clock -> clockInfo
|
||||
)
|
||||
|
||||
def capacityInfo = (maxResolution._1 * maxResolution._2).toString
|
||||
def capacityInfo: String = (maxResolution._1 * maxResolution._2).toString
|
||||
|
||||
def widthInfo = Array("1", "4", "8").apply(maxDepth.ordinal())
|
||||
def widthInfo: String = Array("1", "4", "8").apply(maxDepth.ordinal())
|
||||
|
||||
def clockInfo = ((2000 / setBackgroundCosts(tier)).toInt / 100).toString + "/" + ((2000 / setForegroundCosts(tier)).toInt / 100).toString + "/" + ((2000 / setPaletteColorCosts(tier)).toInt / 100).toString + "/" + ((2000 / setCosts(tier)).toInt / 100).toString + "/" + ((2000 / copyCosts(tier)).toInt / 100).toString + "/" + ((2000 / fillCosts(tier)).toInt / 100).toString
|
||||
def clockInfo: String = ((2000 / setBackgroundCosts(tier)).toInt / 100).toString + "/" + ((2000 / setForegroundCosts(tier)).toInt / 100).toString + "/" + ((2000 / setPaletteColorCosts(tier)).toInt / 100).toString + "/" + ((2000 / setCosts(tier)).toInt / 100).toString + "/" + ((2000 / copyCosts(tier)).toInt / 100).toString + "/" + ((2000 / fillCosts(tier)).toInt / 100).toString
|
||||
|
||||
override def getDeviceInfo: util.Map[String, String] = deviceInfo
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
private def getViewportOverlapSize(s: api.internal.TextBuffer, x1: Int, y1: Int, x2: Int, y2: Int): Int = {
|
||||
val width = s.getViewportWidth
|
||||
val height = s.getViewportHeight
|
||||
val left = math.min(x1, x2);
|
||||
val right = math.max(x1, x2);
|
||||
val top = math.min(y1, y2);
|
||||
val bottom = math.max(y1, y2);
|
||||
if (right < 0 || left >= width || top >= height || bottom < 0)
|
||||
return 0
|
||||
val box_left = math.max(0, left)
|
||||
val box_right = math.min(width - 1, right)
|
||||
val box_top = math.max(0, top)
|
||||
val box_bottom = math.min(height - 1, bottom)
|
||||
(box_right - box_left + 1) * (box_bottom - box_top + 1)
|
||||
}
|
||||
|
||||
private def consumeViewportPower(overlap: Int, context: Context, budgetCost: Double, callFactor: Double): Boolean = {
|
||||
if (overlap == 0) true
|
||||
else {
|
||||
context.consumeCallBudget(budgetCost)
|
||||
consumePower(overlap, callFactor)
|
||||
}
|
||||
}
|
||||
|
||||
@Callback(doc = """function(address:string[, reset:boolean=true]):boolean -- Binds the GPU to the screen with the specified address and resets screen settings if `reset` is true.""")
|
||||
def bind(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
val address = args.checkString(0)
|
||||
@ -275,14 +299,16 @@ class GraphicsCard(val tier: Int) extends prefab.ManagedEnvironment with DeviceI
|
||||
|
||||
@Callback(direct = true, doc = """function(x:number, y:number, value:string[, vertical:boolean]):boolean -- Plots a string value to the screen at the specified position. Optionally writes the string vertically.""")
|
||||
def set(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
context.consumeCallBudget(setCosts(tier))
|
||||
val x = args.checkInteger(0) - 1
|
||||
val y = args.checkInteger(1) - 1
|
||||
val value = args.checkString(2)
|
||||
val vertical = args.optBoolean(3, false)
|
||||
|
||||
screen(s => {
|
||||
if (consumePower(value.length, Settings.get.gpuSetCost)) {
|
||||
val x2 = if (vertical) x else x + value.length - 1
|
||||
val y2 = if (!vertical) y else y + value.length - 1
|
||||
val overlap: Int = getViewportOverlapSize(s, x, y, x2, y2)
|
||||
if (consumeViewportPower(overlap, context, setCosts(tier), Settings.get.gpuSetCost)) {
|
||||
s.set(x, y, value, vertical)
|
||||
result(true)
|
||||
}
|
||||
@ -292,7 +318,6 @@ class GraphicsCard(val tier: Int) extends prefab.ManagedEnvironment with DeviceI
|
||||
|
||||
@Callback(direct = true, doc = """function(x:number, y:number, width:number, height:number, tx:number, ty:number):boolean -- Copies a portion of the screen from the specified location with the specified size by the specified translation.""")
|
||||
def copy(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
context.consumeCallBudget(copyCosts(tier))
|
||||
val x = args.checkInteger(0) - 1
|
||||
val y = args.checkInteger(1) - 1
|
||||
val w = math.max(0, args.checkInteger(2))
|
||||
@ -300,7 +325,8 @@ class GraphicsCard(val tier: Int) extends prefab.ManagedEnvironment with DeviceI
|
||||
val tx = args.checkInteger(4)
|
||||
val ty = args.checkInteger(5)
|
||||
screen(s => {
|
||||
if (consumePower(w * h, Settings.get.gpuCopyCost)) {
|
||||
val overlap: Int = getViewportOverlapSize(s, x + tx, y + ty, x + tx + w - 1, y + ty + h - 1)
|
||||
if (consumeViewportPower(overlap, context, copyCosts(tier), Settings.get.gpuCopyCost)) {
|
||||
s.copy(x, y, w, h, tx, ty)
|
||||
result(true)
|
||||
}
|
||||
@ -319,7 +345,8 @@ class GraphicsCard(val tier: Int) extends prefab.ManagedEnvironment with DeviceI
|
||||
if (value.length == 1) screen(s => {
|
||||
val c = value.charAt(0)
|
||||
val cost = if (c == ' ') Settings.get.gpuClearCost else Settings.get.gpuFillCost
|
||||
if (consumePower(w * h, cost)) {
|
||||
val overlap: Int = getViewportOverlapSize(s, x, y, x + w - 1, y + h - 1)
|
||||
if (consumeViewportPower(overlap, context, fillCosts(tier), cost)) {
|
||||
s.fill(x, y, w, h, value.charAt(0))
|
||||
result(true)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user