make buffers faster

closes #36
This commit is contained in:
zenith391 2024-04-15 16:31:02 +02:00
parent 0dd3789abd
commit c84a071d24
2 changed files with 62 additions and 16 deletions

View File

@ -117,6 +117,9 @@ function obj.freeBuffer(idx)
return false, "no buffer at index" return false, "no buffer at index"
else else
usedMemory = usedMemory - buffers[idx].size usedMemory = usedMemory - buffers[idx].size
if buffers[idx].free then
buffers[idx]:free()
end
buffers[idx] = nil buffers[idx] = nil
if idx == activeBufferIdx then if idx == activeBufferIdx then
activeBufferIdx = 0 activeBufferIdx = 0
@ -237,7 +240,6 @@ function obj.bitblt(dst, col, row, width, height, src, fromCol, fromRow)
end end
local cost = determineBitbltBudgetCost(buf, "screen") local cost = determineBitbltBudgetCost(buf, "screen")
if not machine.consumeCallBudget(cost) then return end if not machine.consumeCallBudget(cost) then return end
buf.dirty = false
width, height = math.min(buf.width, width), math.min(buf.height, height) width, height = math.min(buf.width, width), math.min(buf.height, height)
if fromRow < 1 then if fromRow < 1 then
--error("fromRow is equals to " .. fromRow .. ". Expected > 0") --error("fromRow is equals to " .. fromRow .. ". Expected > 0")
@ -255,9 +257,10 @@ function obj.bitblt(dst, col, row, width, height, src, fromCol, fromRow)
return return
end end
component.cecinvoke(bindaddress, "bitblt", buf, col, row, width, height, fromCol, fromRow) component.cecinvoke(bindaddress, "bitblt", buf, col, row, width, height, fromCol, fromRow)
buf.dirty = false
end end
else else
error("TODO: bitblt from to buffer")
end end
end end

View File

@ -252,7 +252,7 @@ local function screenSet(x,y,c)
screen.bgp[y][x] = scrbgp screen.bgp[y][x] = scrbgp
end end
local function setPos(x,y,c,fg,bg) local function setPos(x,y,c,fg,bg,no_render)
local renderchange = true local renderchange = true
--screen.txt[y][x] ~= utf8.char(c) or --screen.txt[y][x] ~= utf8.char(c) or
--screen.bg[y][x] ~= scrbgc or --screen.bg[y][x] ~= scrbgc or
@ -266,16 +266,20 @@ local function setPos(x,y,c,fg,bg)
screenSet(x,y,c) screenSet(x,y,c)
end end
if renderchange then if renderchange then
if not no_render then
renderChar(c,(x-1)*8,(y-1)*16,fg,bg) renderChar(c,(x-1)*8,(y-1)*16,fg,bg)
end
if charWidth > 1 then if charWidth > 1 then
screenSet(x+1,y,32) screenSet(x+1,y,32)
end end
end end
if renderafter then if renderafter then
if not no_render then
renderChar(32,x*8,(y-1)*16,screen.fg[y][x+1],screen.bg[y][x+1]) renderChar(32,x*8,(y-1)*16,screen.fg[y][x+1],screen.bg[y][x+1])
end end
end end
end end
end
local function compare(value1, value2) local function compare(value1, value2)
local r1,g1,b1 = extract(value1) local r1,g1,b1 = extract(value1)
@ -505,28 +509,67 @@ function cec.fill(x1, y1, w, h, char) -- Fills a portion of the screen at the sp
end end
return true return true
end end
function cec.bitblt(buf, col, row, w, h, fromCol, fromRow)
cprint("(cec) screen.bitblt", tostring(buf), col, row, w, h, fromCol, fromRow) local function rerenderBuffer(buf)
local oldFg = srcfgc local width, height = buf.width * 8, buf.height * 16
local oldBg = srcbgc if not buf.texture then
buf.texture = SDL.createTexture(renderer, SDL.PIXELFORMAT_RGB888, SDL.TEXTUREACCESS_TARGET, width, height);
if buf.texture == ffi.NULL then
error(ffi.string(SDL.getError()))
end
SDL.setTextureBlendMode(buf.texture, SDL.BLENDMODE_BLEND)
SDL.setRenderTarget(renderer, buf.texture)
SDL.setRenderDrawColor(renderer, 0, 0, 0, 255)
SDL.renderFillRect(renderer, ffi.NULL)
SDL.setRenderTarget(renderer, texture)
buf.free = function(self)
SDL.destroyTexture(self.texture)
end
end
SDL.setRenderTarget(renderer, buf.texture)
for y=0, buf.height-1 do
for x=0, buf.width-1 do
local char, fg, bg = buf:bufferGet(x+1, y+1)
local dx = x+1
local dy = y+1
if not utf8.byte(char) then
char = " "
end
renderChar(utf8.byte(char),(dx-1)*8,(dy-1)*16,getColor(fg, true),getColor(bg, false))
end
end
SDL.setRenderTarget(renderer, texture)
end
function cec.bitblt(buf, col, row, w, h, fromRow, fromCol)
cprint("(cec) screen.bitblt", tostring(buf), col, row, w, h, fromRow, fromCol)
if buf.dirty then
rerenderBuffer(buf)
end
for y=0, h-1 do for y=0, h-1 do
for x=0, w-1 do for x=0, w-1 do
local char, fg, bg = buf:bufferGet(x+fromRow, y+fromCol) local char, fg, bg = buf:bufferGet(x+fromCol, y+fromRow)
local dx = x+col local dx = x+col
local dy = y+row local dy = y+row
if not utf8.byte(char) then if not utf8.byte(char) then
--error(tostring(x+fromRow) .. ", " .. (y+fromCol) .. " > " .. buf.width .. ", " .. buf.height .. ": out of bounds")
char = " " char = " "
end end
if dx >= 1 and dx <= width and dy >= 1 and dy <= height then if dx >= 1 and dx <= width and dy >= 1 and dy <= height then
srcfgc = fg getColor(fg, true)
srcbgc = bg getColor(bg, false)
setPos(dx, dy, utf8.byte(char), getColor(fg, true), getColor(bg, false)) screen.txt[dy][dx] = char
screen.fg[dy][dx] = fg
screen.bg[dy][dx] = bg
screen.fgp[dy][dx] = scrfgp
screen.bgp[dy][dx] = scrbgp
end end
end end
end end
srcfgc = oldFg local src = ffi.new("SDL_Rect", {x=(fromCol-1)*8,y=(fromRow-1)*16,w=w*8,h=h*16})
srcbgc = oldBg local dest = ffi.new("SDL_Rect",{x=(col-1)*8,y=(row-1)*16,w=w*8,h=h*16})
SDL.renderCopy(renderer, buf.texture, src, dest)
end end
function cec.getResolution() -- Get the current screen resolution. function cec.getResolution() -- Get the current screen resolution.
cprint("(cec) screen.getResolution") cprint("(cec) screen.getResolution")