canvas progress

This commit is contained in:
Elmārs Āboliņš 2020-10-19 00:39:37 +03:00
parent fae63e1b24
commit 7419274205
7 changed files with 86 additions and 80 deletions

View File

@ -10,7 +10,6 @@ return function (base)
return fakeBase[index] or base[index] return fakeBase[index] or base[index]
end, end,
__newindex = function(t, index, val) __newindex = function(t, index, val)
print(index, val)
if fakeBase[index] ~= val then if fakeBase[index] ~= val then
fakeBase[index] = val fakeBase[index] = val
activeContext:bubbleUpdate() activeContext:bubbleUpdate()

View File

@ -1,40 +1,63 @@
local atlas = {} local atlas = {}
local createdAtlas local atlases
local intermediaryCanvas
atlas.__index = atlas atlas.__index = atlas
local BLOCK_SIZE = 5 local BLOCK_SIZE = 5
function atlas.load() function atlas.load()
if not createdAtlas then if not atlases then
atlas.init() atlas.init()
end end
end end
function atlas.getRatio() function atlas.getRatio(index)
return createdAtlas.taken_area/createdAtlas.ideal_area return atlases[index].taken_area/atlases[index].ideal_area
end end
function atlas.getFreeArea() function atlas.getFreeArea(index)
return createdAtlas.ideal_area - createdAtlas.taken_area return atlases[index].ideal_area - atlases[index].taken_area
end end
local sw, sh = love.graphics.getDimensions() local sw, sh = love.graphics.getDimensions()
function atlas.init() function atlas.init()
atlases = {}
createdAtlas = atlas.new(sw*2, sh) atlases[1] = atlas.new(sw, sh)
intermediaryCanvas = love.graphics.newCanvas(sw, sh) atlases[2] = atlas.new(sw, sh)
atlas.createdAtlas = createdAtlas atlas.atlases = atlases
atlas.interCanvas = intermediaryCanvas
end end
local selfRenderTime = false
function atlas.setBench(time)
selfRenderTime = time
end
local coefficient = 1.5
function atlas.assign(element) function atlas.assign(element)
local avg, sum, canvasID = 0, 0, element.context:getCanvasIndex(true) or 1
for i, e in ipairs(element.renderBench) do
sum = sum + e
end
avg = sum/#element.renderBench
local areaBelow = atlas.getFreeArea(canvasID)
local area = element.view.h*element.view.w
local areaCoef = (2-(atlas.getRatio(canvasID)) )-(area/(areaBelow/(4+3*atlas.getRatio(canvasID))))
local speedCoef = avg/selfRenderTime
if not ((areaCoef+speedCoef)>coefficient) then
return
end
local elW = element.view.w local elW = element.view.w
local elH = element.view.h local elH = element.view.h
local canvas, quad, interQuad = createdAtlas:assignElement(element) local canvas, quad, interQuad = atlases[canvasID]:assignElement(element)
if not canvas and createdAtlas.ideal_area < createdAtlas.taken_area*4 then if not canvas and atlases[canvasID].ideal_area < atlases[canvasID].taken_area*4 then
--print('refragmenting ;3') --print('refragmenting ;3')
createdAtlas:refragment() atlases[canvasID]:refragment()
canvas, quad, interQuad = createdAtlas:assignElement(element) canvas, quad, interQuad = atlases[canvasID]:assignElement(element)
if not canvas then if not canvas then
--print('ran out of space') --print('ran out of space')
end end
@ -45,7 +68,8 @@ function atlas.assign(element)
end end
function atlas.unassign(element) function atlas.unassign(element)
createdAtlas:unassignElement(element) local canvasID = element.context:getCanvasIndex(true) or 1
atlases[canvasID]:unassignElement(element)
end end
function atlas.unassignAll() function atlas.unassignAll()

View File

@ -149,48 +149,24 @@ function element:createProxies()
self.context = context.new(self) self.context = context.new(self)
end end
--Random coefficients, if these reach 1.5 then canvas is made local selfRenderTime
local selfRenderTime = false
local screenSize = 1/4
local coefficient = 1.5
function element.setBench(time) function element.setBench(time)
selfRenderTime = time selfRenderTime = time
end end
function element:calculateCanvasCoeficient()
local avg, sum = 0, 0
for i, e in ipairs(self.renderBench) do
sum = sum + e
end
avg = sum/#self.renderBench
local sW, sH = love.graphics.getDimensions()
local areaBelow = helium.atlas.getFreeArea()
local area = self.view.h*self.view.w
local areaCoef = (2-(helium.atlas.getRatio()) )-(area/(areaBelow/(4+3*helium.atlas.getRatio())))
local speedCoef = avg/selfRenderTime
return (areaCoef+speedCoef)>coefficient
end
local newCanvas, newQuad = love.graphics.newCanvas, love.graphics.newQuad local newCanvas, newQuad = love.graphics.newCanvas, love.graphics.newQuad
function element:createCanvas() function element:createCanvas()
self.settings.canvasW = self.view.w
self.settings.canvasH = self.view.h
self.canvas, self.quad, self.interQuad = helium.atlas.assign(self) self.canvas, self.quad = helium.atlas.assign(self)
if not self.canvas then if not self.canvas then
self.settings.failedCanvas = true self.settings.failedCanvas = true
self.settings.hasCanvas = false self.settings.hasCanvas = false
return return
end end
self.settings.canvasW = self.view.w
self.settings.canvasH = self.view.h
self.settings.hasCanvas = true self.settings.hasCanvas = true
end end
@ -230,13 +206,6 @@ function element:setup()
end end
local setColor, rectangle, setFont, printf = love.graphics.setColor, love.graphics.rectangle, love.graphics.setFont, love.graphics.printf local setColor, rectangle, setFont, printf = love.graphics.setColor, love.graphics.rectangle, love.graphics.setFont, love.graphics.printf
function element:errorRender(msg)
setColor(1, 0, 0)
rectangle('line', 0, 0, self.view.w, self.view.h)
setColor(1, 1, 1)
printf("Error: "..msg, 0, 0, self.view.w)
end
local calcT local calcT
function element:internalRender() function element:internalRender()
@ -245,6 +214,7 @@ function element:internalRender()
end end
self.renderer() self.renderer()
if self.settings.testRenderPasses > 0 and selfRenderTime then if self.settings.testRenderPasses > 0 and selfRenderTime then
self.settings.testRenderPasses = self.settings.testRenderPasses-1 self.settings.testRenderPasses = self.settings.testRenderPasses-1
local selfTime = love.timer.getTime()-calcT local selfTime = love.timer.getTime()-calcT
@ -267,7 +237,6 @@ end
function element:externalRender() function element:externalRender()
local cnvs = getCanvas() local cnvs = getCanvas()
love.graphics.push('all') love.graphics.push('all')
love.graphics.translate(self.view.x, self.view.y)
if not self.settings.isSetup then if not self.settings.isSetup then
self:setup() self:setup()
@ -278,18 +247,21 @@ function element:externalRender()
if self.settings.hasCanvas then if self.settings.hasCanvas then
setCanvas(self.canvas) setCanvas(self.canvas)
--need scissors --need scissors
--love.graphics.clear(0,0,0,0)
love.graphics.push('all') love.graphics.push('all')
love.graphics.origin() love.graphics.origin()
local ox, oy = self.quad:getViewport() local ox, oy, w, h = self.quad:getViewport()
love.graphics.translate(ox, oy) love.graphics.translate(ox, oy)
love.graphics.setScissor(ox, oy, w, h)
love.graphics.clear(0,0,0,0)
self:renderWrapper() self:renderWrapper()
self.settings.needsRendering = false self.settings.needsRendering = false
love.graphics.pop() love.graphics.pop()
else else
love.graphics.translate(self.view.x, self.view.y)
local x, y = love.graphics.transformPoint(0, 0)
love.graphics.setScissor(x, y, self.view.w, self.view.h)
self:renderWrapper() self:renderWrapper()
end end
end end
@ -297,19 +269,9 @@ function element:externalRender()
setCanvas(cnvs) setCanvas(cnvs)
if self.settings.hasCanvas then if self.settings.hasCanvas then
if self.canvas == cnvs then love.graphics.translate(self.view.x, self.view.y)
love.graphics.push('all') setColor(1, 1, 1, 1)
love.graphics.origin()
setColor(1,1,1,1)
setCanvas(helium.atlas.interCanvas)
draw(self.canvas, self.quad, 0, 0) draw(self.canvas, self.quad, 0, 0)
love.graphics.pop()
setCanvas(cnvs)
draw(helium.atlas.interCanvas, self.interQuad, 0, 0)
else
setColor(1,1,1,1)
draw(self.canvas, self.quad, 0, 0)
end
end end
love.graphics.pop() love.graphics.pop()
@ -318,14 +280,9 @@ end
function element:externalUpdate() function element:externalUpdate()
self.context:zIndex() self.context:zIndex()
if not self.settings.failedCanvas and self.settings.testRenderPasses == 0 and not self.settings.hasCanvas then if not self.settings.failedCanvas and self.settings.testRenderPasses == 0 and not self.settings.hasCanvas then
if self:calculateCanvasCoeficient() then
self:createCanvas() self:createCanvas()
self.settings.pendingUpdate = true self.settings.pendingUpdate = true
else
self.settings.failedCanvas = true
end
end end
if self.settings.pendingUpdate then if self.settings.pendingUpdate then
@ -381,7 +338,7 @@ function element:draw(x, y, w, h)
self.settings.remove = false self.settings.remove = false
self.settings.firstDraw = false self.settings.firstDraw = false
if cx then if cx then
self.settings.testRenderPasses = self.settings.testRenderPasses-5 self.settings.testRenderPasses = self.settings.testRenderPasses+5
end end
end end
end end

View File

@ -93,7 +93,7 @@ function subscription.create(x, y, w, h, eventType, callback, doff)
input.subscriptions[eventType] = {} input.subscriptions[eventType] = {}
end end
table.insert(input.subscriptions[eventType],1,sub) table.insert(input.subscriptions[eventType], 1, sub)
input.sortZ() input.sortZ()

View File

@ -99,6 +99,21 @@ function context:destroy()
end end
end end
function context:getCanvasIndex(forCanvas)
if self.parentCtx then
if self.element.settings.hasCanvas then
return self.parentCtx:getCanvasIndex() == 1 and 2 or 1
else
if forCanvas then
return self.parentCtx:getCanvasIndex() == 1 and 2 or 1
end
end
else
--No parent path (element becomes the first one cached)
return self.element.settings.hasCanvas and 1 or nil
end
end
function context:getChildrenCount() function context:getChildrenCount()
return #self.childrenContexts return #self.childrenContexts
end end

View File

@ -51,6 +51,7 @@ function helium.draw()
end end
helium.element.setBench((love.timer.getTime()-startTime)/5) helium.element.setBench((love.timer.getTime()-startTime)/5)
helium.atlas.setBench((love.timer.getTime()-startTime)/5)
first = false first = false
--love.graphics.setScissor() --love.graphics.setScissor()

10
shell/button.lua Normal file
View File

@ -0,0 +1,10 @@
local path = string.sub(..., 1, string.len(...) - string.len(".shell.button"))
local state = require(path.. ".control.state")
local input = require(path.. ".core.input")
return function(onClick, onRelease, onEnter, onExit, x, y, w, h)
local button = {}
input('clicked')
return button
end