Performance issue drawing sprites/rectangles with text

Hi Codeans,

I wonder if anyone can help me, I’ve hit a strange performance issue on the new UI for our next game, I’ve distilled it down to a simple test harness which either draws sprites or rectangles based on a global variable…

I develop on an iPad2 which is getting a bit clunky, but basically I’m seeing frame rates of about 30-40 when drawing 40-50 rects or sprites…

Here is the test code, if anyone can provide any insights or FPS from a different iPad I’d be very grateful,

If you just dicker with useSprites=true/false and drawText=true/false you can switch between… For me, switching text on or off changes FPS by 5-10…

Regards,
Brookesi


Rect = class()

local count=0
drawText = true
makeSprites = true
useSprites = false

function Rect:init(coords, dims, border)
    
    count = count+1
    self.text = "Rect "..count
    self.coords = coords
    self.dims = dims
    self.border = border or 10
    
    self.rects = {}
end


function Rect:addRects(rects)
    
    local h = self.dims.y / #rects
    for i=1, #rects do
        local r = rects[i]
        r.coords = vec2(self.coords.x + self.border, (self.coords.y + ((i-1) * h)))
        r.dims = vec2(self.dims.x, h)
        self.rects[#self.rects+1] = r
    end
end



function Rect:draw()
        
    pushStyle()
    
    if(useSprites and self.sprite) then
        spriteMode(CORNER)
        sprite(self.coords.x, self.coords.y, self.dims.x, self.dims.y)
    else
        rectMode(CORNER)
        fill(255, 0, 0)
        stroke(0, 0, 255)
        strokeWidth(self.border)
        rect(self.coords.x, self.coords.y, self.dims.x, self.dims.y)
    end
    
    if(drawText) then
        fill(0, 0, 255)
        textMode(CENTER)
        text(self.text, self.coords.x + (self.dims.x/2), self.coords.y + (self.dims.y/2))
    end
    
    popStyle()
    
    for i=1, #self.rects do
        self.rects[i]:draw()
    end
end

function Rect:makeSprite()
    
    self.sprite = image(self.dims.x, self.dims.y)
    local c = self.coords
    self.coords = vec2(1,1)
    setContext(self.sprite)
    self:draw()
    setContext()
    self.coords = c
end



local rand = function(i) 
    local r =  math.random(math.ceil(i)) 
    return r
end

function setup()

    panels = {}
    for i=1, 10 do
        panels[#panels +1] = Rect(vec2(rand(WIDTH*0.75), rand(HEIGHT*0.75)),
                                  vec2(WIDTH*0.25, HEIGHT*0.25))
        local rects = { Rect(), Rect(), Rect() }
        panels[#panels]:addRects(rects)
        
        if(makeSprites) then
            panels[#panels]:makeSprite()
        end
    end
end





local elapsedTimeMem, elapsedTimeFPS = ElapsedTime, ElapsedTime
local memory = 0
local FPS = 0
local metricColour = 255
local metricFont = "Courier"
local msg = ""

-- Calculate and display FPS and memory statistics
local function metrics()
    if (ElapsedTime - elapsedTimeMem > 5) then
        memory = collectgarbage("count") / 1024
        elapsedTimeMem = ElapsedTime
    end

    --pushMatrix()
    --resetMatrix()
    pushStyle()
    fill(metricColour)
    --font(metricFont)
    fontSize(20)
    FPS = FPS * 0.9 + 0.1 / DeltaTime
    if (ElapsedTime - elapsedTimeFPS > 0.25) then
        msg = string.format("%.0fFPS %.1fMB", FPS, memory)
        elapsedTimeFPS = ElapsedTime
    end
    text(msg, WIDTH - 80, HEIGHT - 32)
    popStyle()
    --popMatrix()
end





function draw()
    -- This sets a dark background color 
    background(60)

    -- Do your drawing here
    --currentView:draw()
    for i=1, #panels do
        panels[i]:draw()        
    end
    
    if(makeSprites and useSprites) then
        text("USING SPRITES", WIDTH/2, HEIGHT/2)
    else
        text("USING RECTS", WIDTH/2, HEIGHT/2)
    end
    
    metrics()
end

I can get to about 140 panels (excluding text) on my iPad Air2 before it dips below 60, adding text drops it to 25.

With text, I can only get about 70 panels before it drops below 60.

Have you thought of using meshes, and pre rendering text to images?

Hi @Ignatz,

Many thanks for your input. Looks like the iPad2 is struggling with this…

My actual UI uses a mesh and a shader to create rounded and textured buttons, and that is similarly slow, hence switching out to a basic/sprite/rect model for testing…

Yes, pre-rendering text is probably the next step,

Thanks again,

Brookesi