mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-12 23:54:04 +09:00
graphics mode 5, faster RGB upload
This commit is contained in:
@@ -1462,20 +1462,60 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
val nativeWidth = gpu.config.width
|
val nativeWidth = gpu.config.width
|
||||||
val nativeHeight = gpu.config.height
|
val nativeHeight = gpu.config.height
|
||||||
val totalNativePixels = (nativeWidth * nativeHeight)
|
val totalNativePixels = (nativeWidth * nativeHeight)
|
||||||
|
val totalVideoPixels = width * height
|
||||||
|
|
||||||
|
val chunkSize = 32768
|
||||||
|
val rgChunk = ByteArray(chunkSize)
|
||||||
|
val baChunk = ByteArray(chunkSize)
|
||||||
|
val rChunk = ByteArray(chunkSize)
|
||||||
|
val gChunk = ByteArray(chunkSize)
|
||||||
|
val bChunk = ByteArray(chunkSize)
|
||||||
|
val aChunk = ByteArray(chunkSize); aChunk.fill(-1)
|
||||||
|
var pixelsProcessed = 0
|
||||||
|
|
||||||
|
// Helper function to write chunks to framebuffer (shared between native size and resize paths)
|
||||||
|
fun writeChunksToFramebuffer(
|
||||||
|
pixelsProcessed: Int, pixelsInChunk: Int,
|
||||||
|
rgChunk: ByteArray, baChunk: ByteArray,
|
||||||
|
rChunk: ByteArray, gChunk: ByteArray, bChunk: ByteArray, aChunk: ByteArray
|
||||||
|
) {
|
||||||
|
val pixelIndex = pixelsProcessed
|
||||||
|
val videoY = pixelIndex / width
|
||||||
|
val videoX = pixelIndex % width
|
||||||
|
val nativePos = videoY * nativeWidth + videoX
|
||||||
|
if (graphicsMode == 4) {
|
||||||
|
UnsafeHelper.memcpyRaw(
|
||||||
|
rgChunk, UnsafeHelper.getArrayOffset(rgChunk),
|
||||||
|
null, gpu.framebuffer.ptr + nativePos, pixelsInChunk.toLong()
|
||||||
|
)
|
||||||
|
UnsafeHelper.memcpyRaw(
|
||||||
|
baChunk, UnsafeHelper.getArrayOffset(baChunk),
|
||||||
|
null, gpu.framebuffer2!!.ptr + nativePos, pixelsInChunk.toLong()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else if (graphicsMode == 5) {
|
||||||
|
UnsafeHelper.memcpyRaw(
|
||||||
|
rChunk, UnsafeHelper.getArrayOffset(rChunk),
|
||||||
|
null, gpu.framebuffer.ptr + nativePos, pixelsInChunk.toLong()
|
||||||
|
)
|
||||||
|
UnsafeHelper.memcpyRaw(
|
||||||
|
gChunk, UnsafeHelper.getArrayOffset(gChunk),
|
||||||
|
null, gpu.framebuffer2!!.ptr + nativePos, pixelsInChunk.toLong()
|
||||||
|
)
|
||||||
|
UnsafeHelper.memcpyRaw(
|
||||||
|
bChunk, UnsafeHelper.getArrayOffset(bChunk),
|
||||||
|
null, gpu.framebuffer3!!.ptr + nativePos, pixelsInChunk.toLong()
|
||||||
|
)
|
||||||
|
UnsafeHelper.memcpyRaw(
|
||||||
|
aChunk, UnsafeHelper.getArrayOffset(aChunk),
|
||||||
|
null, gpu.framebuffer4!!.ptr + nativePos, pixelsInChunk.toLong()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (width == nativeWidth && height == nativeHeight) {
|
if (width == nativeWidth && height == nativeHeight) {
|
||||||
val chunkSize = 32768 // Larger chunks for bulk processing
|
// Pre-allocate RGB buffer for bulk reads and chunk arrays
|
||||||
|
|
||||||
var pixelsProcessed = 0
|
|
||||||
|
|
||||||
// Pre-allocate RGB buffer for bulk reads
|
|
||||||
val rgbBulkBuffer = ByteArray(chunkSize * 3)
|
val rgbBulkBuffer = ByteArray(chunkSize * 3)
|
||||||
val rgChunk = ByteArray(chunkSize)
|
|
||||||
val baChunk = ByteArray(chunkSize)
|
|
||||||
val rChunk = ByteArray(chunkSize)
|
|
||||||
val gChunk = ByteArray(chunkSize)
|
|
||||||
val bChunk = ByteArray(chunkSize)
|
|
||||||
val aChunk = ByteArray(chunkSize); aChunk.fill(-1)
|
|
||||||
|
|
||||||
while (pixelsProcessed < totalNativePixels) {
|
while (pixelsProcessed < totalNativePixels) {
|
||||||
val pixelsInChunk = kotlin.math.min(chunkSize, totalNativePixels - pixelsProcessed)
|
val pixelsInChunk = kotlin.math.min(chunkSize, totalNativePixels - pixelsProcessed)
|
||||||
@@ -1512,38 +1552,9 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
bChunk[i] = b.toByte()
|
bChunk[i] = b.toByte()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val pixelIndex = pixelsProcessed
|
|
||||||
val videoY = pixelIndex / width
|
// Write chunks to framebuffer
|
||||||
val videoX = pixelIndex % width
|
writeChunksToFramebuffer(pixelsProcessed, pixelsInChunk, rgChunk, baChunk, rChunk, gChunk, bChunk, aChunk)
|
||||||
val nativePos = videoY * nativeWidth + videoX
|
|
||||||
if (graphicsMode == 4) {
|
|
||||||
UnsafeHelper.memcpyRaw(
|
|
||||||
rgChunk, UnsafeHelper.getArrayOffset(rgChunk),
|
|
||||||
null, gpu.framebuffer.ptr + nativePos, pixelsInChunk.toLong()
|
|
||||||
)
|
|
||||||
UnsafeHelper.memcpyRaw(
|
|
||||||
baChunk, UnsafeHelper.getArrayOffset(baChunk),
|
|
||||||
null, gpu.framebuffer2!!.ptr + nativePos, pixelsInChunk.toLong()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else if (graphicsMode == 5) {
|
|
||||||
UnsafeHelper.memcpyRaw(
|
|
||||||
rChunk, UnsafeHelper.getArrayOffset(rChunk),
|
|
||||||
null, gpu.framebuffer.ptr + nativePos, pixelsInChunk.toLong()
|
|
||||||
)
|
|
||||||
UnsafeHelper.memcpyRaw(
|
|
||||||
gChunk, UnsafeHelper.getArrayOffset(gChunk),
|
|
||||||
null, gpu.framebuffer2!!.ptr + nativePos, pixelsInChunk.toLong()
|
|
||||||
)
|
|
||||||
UnsafeHelper.memcpyRaw(
|
|
||||||
bChunk, UnsafeHelper.getArrayOffset(bChunk),
|
|
||||||
null, gpu.framebuffer3!!.ptr + nativePos, pixelsInChunk.toLong()
|
|
||||||
)
|
|
||||||
UnsafeHelper.memcpyRaw(
|
|
||||||
aChunk, UnsafeHelper.getArrayOffset(aChunk),
|
|
||||||
null, gpu.framebuffer4!!.ptr + nativePos, pixelsInChunk.toLong()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pixelsProcessed += pixelsInChunk
|
pixelsProcessed += pixelsInChunk
|
||||||
}
|
}
|
||||||
@@ -1553,17 +1564,6 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
val scaleX = width.toFloat() / nativeWidth.toFloat()
|
val scaleX = width.toFloat() / nativeWidth.toFloat()
|
||||||
val scaleY = height.toFloat() / nativeHeight.toFloat()
|
val scaleY = height.toFloat() / nativeHeight.toFloat()
|
||||||
|
|
||||||
// Process native pixels in 8KB chunks
|
|
||||||
val chunkSize = 32768
|
|
||||||
val rgChunk = ByteArray(chunkSize)
|
|
||||||
val baChunk = ByteArray(chunkSize)
|
|
||||||
val rChunk = ByteArray(chunkSize)
|
|
||||||
val gChunk = ByteArray(chunkSize)
|
|
||||||
val bChunk = ByteArray(chunkSize)
|
|
||||||
val aChunk = ByteArray(chunkSize); aChunk.fill(-1)
|
|
||||||
|
|
||||||
var pixelsProcessed = 0
|
|
||||||
|
|
||||||
while (pixelsProcessed < totalNativePixels) {
|
while (pixelsProcessed < totalNativePixels) {
|
||||||
val pixelsInChunk = kotlin.math.min(chunkSize, (totalNativePixels - pixelsProcessed).toInt())
|
val pixelsInChunk = kotlin.math.min(chunkSize, (totalNativePixels - pixelsProcessed).toInt())
|
||||||
|
|
||||||
@@ -1599,38 +1599,9 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
bChunk[i] = b.toByte()
|
bChunk[i] = b.toByte()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val pixelIndex = pixelsProcessed
|
|
||||||
val videoY = pixelIndex / width
|
// Write chunks to framebuffer
|
||||||
val videoX = pixelIndex % width
|
writeChunksToFramebuffer(pixelsProcessed, pixelsInChunk, rgChunk, baChunk, rChunk, gChunk, bChunk, aChunk)
|
||||||
val nativePos = videoY * nativeWidth + videoX
|
|
||||||
if (graphicsMode == 4) {
|
|
||||||
UnsafeHelper.memcpyRaw(
|
|
||||||
rgChunk, UnsafeHelper.getArrayOffset(rgChunk),
|
|
||||||
null, gpu.framebuffer.ptr + nativePos, pixelsInChunk.toLong()
|
|
||||||
)
|
|
||||||
UnsafeHelper.memcpyRaw(
|
|
||||||
baChunk, UnsafeHelper.getArrayOffset(baChunk),
|
|
||||||
null, gpu.framebuffer2!!.ptr + nativePos, pixelsInChunk.toLong()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else if (graphicsMode == 5) {
|
|
||||||
UnsafeHelper.memcpyRaw(
|
|
||||||
rChunk, UnsafeHelper.getArrayOffset(rChunk),
|
|
||||||
null, gpu.framebuffer.ptr + nativePos, pixelsInChunk.toLong()
|
|
||||||
)
|
|
||||||
UnsafeHelper.memcpyRaw(
|
|
||||||
gChunk, UnsafeHelper.getArrayOffset(gChunk),
|
|
||||||
null, gpu.framebuffer2!!.ptr + nativePos, pixelsInChunk.toLong()
|
|
||||||
)
|
|
||||||
UnsafeHelper.memcpyRaw(
|
|
||||||
bChunk, UnsafeHelper.getArrayOffset(bChunk),
|
|
||||||
null, gpu.framebuffer3!!.ptr + nativePos, pixelsInChunk.toLong()
|
|
||||||
)
|
|
||||||
UnsafeHelper.memcpyRaw(
|
|
||||||
aChunk, UnsafeHelper.getArrayOffset(aChunk),
|
|
||||||
null, gpu.framebuffer4!!.ptr + nativePos, pixelsInChunk.toLong()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pixelsProcessed += pixelsInChunk
|
pixelsProcessed += pixelsInChunk
|
||||||
}
|
}
|
||||||
@@ -1639,11 +1610,6 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
val offsetX = (nativeWidth - width) / 2
|
val offsetX = (nativeWidth - width) / 2
|
||||||
val offsetY = (nativeHeight - height) / 2
|
val offsetY = (nativeHeight - height) / 2
|
||||||
|
|
||||||
val totalVideoPixels = width * height
|
|
||||||
val chunkSize = 32768 // Larger chunks for bulk processing
|
|
||||||
|
|
||||||
var pixelsProcessed = 0
|
|
||||||
|
|
||||||
// Pre-allocate RGB buffer for bulk reads
|
// Pre-allocate RGB buffer for bulk reads
|
||||||
val rgbBulkBuffer = ByteArray(chunkSize * 3)
|
val rgbBulkBuffer = ByteArray(chunkSize * 3)
|
||||||
val rgChunk = ByteArray(chunkSize)
|
val rgChunk = ByteArray(chunkSize)
|
||||||
@@ -1677,26 +1643,27 @@ class GraphicsJSR223Delegate(private val vm: VM) {
|
|||||||
val g = rgbBulkBuffer[rgbIndex + 1].toUint()
|
val g = rgbBulkBuffer[rgbIndex + 1].toUint()
|
||||||
val b = rgbBulkBuffer[rgbIndex + 2].toUint()
|
val b = rgbBulkBuffer[rgbIndex + 2].toUint()
|
||||||
|
|
||||||
// Apply Bayer dithering and convert to 4-bit
|
if (graphicsMode == 4) {
|
||||||
val r4 = ditherValue(r, videoX, videoY, frameCount)
|
// Apply Bayer dithering and convert to 4-bit
|
||||||
val g4 = ditherValue(g, videoX, videoY, frameCount)
|
val r4 = ditherValue(r, videoX, videoY, frameCount)
|
||||||
val b4 = ditherValue(b, videoX, videoY, frameCount)
|
val g4 = ditherValue(g, videoX, videoY, frameCount)
|
||||||
|
val b4 = ditherValue(b, videoX, videoY, frameCount)
|
||||||
|
|
||||||
// Pack RGB values and store in chunk arrays for batch processing
|
// Pack RGB values and store in chunk arrays for batch processing
|
||||||
val validIndex = i
|
rgChunk[i] = ((r4 shl 4) or g4).toByte()
|
||||||
rgChunk[validIndex] = ((r4 shl 4) or g4).toByte()
|
baChunk[i] = ((b4 shl 4) or 15).toByte()
|
||||||
baChunk[validIndex] = ((b4 shl 4) or 15).toByte()
|
|
||||||
|
|
||||||
// Write directly to framebuffer position
|
}
|
||||||
val nativePos = nativeY * nativeWidth + nativeX
|
else if (graphicsMode == 5) {
|
||||||
UnsafeHelper.memcpyRaw(
|
rChunk[i] = r.toByte()
|
||||||
rgChunk, UnsafeHelper.getArrayOffset(rgChunk) + validIndex,
|
gChunk[i] = g.toByte()
|
||||||
null, gpu.framebuffer.ptr + nativePos, 1L)
|
bChunk[i] = b.toByte()
|
||||||
UnsafeHelper.memcpyRaw(
|
}
|
||||||
baChunk, UnsafeHelper.getArrayOffset(baChunk) + validIndex,
|
|
||||||
null, gpu.framebuffer2!!.ptr + nativePos, 1L)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write chunks to framebuffer
|
||||||
|
writeChunksToFramebuffer(pixelsProcessed, pixelsInChunk, rgChunk, baChunk, rChunk, gChunk, bChunk, aChunk)
|
||||||
|
|
||||||
pixelsProcessed += pixelsInChunk
|
pixelsProcessed += pixelsInChunk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user