Performance of graphics.image:drawBlurred method on Rev B hardware

I've encountered really poor performance in Casual Birder with my Rev B Playdate.
I thought my hardware was faulty at first and sent my console back to Panic, but the replacement exhibits the same problem which makes me think there's something funky going on with the graphics API.

Here's a video of the issue.

This area of the game is particularly bad, but the intermittent stuttering when moving the viewfinder around persists throughout the whole game.

Steps to reproduce:

  • Open Casual Birder
  • Load this save file (pulled from my console, not modified)
  • Crank to equip the camera
  • Press the A button to open the viewfinder
  • Crank until the viewfinder is completely out of focus
  • Move the viewfinder around the top half of the screen

Here's what the Device Info screen shows when the camera isn't being used.

Versus when it is being used, is out of focus, and being moved around (probably forcing it to generate new blurred images instead of using cached ones). The framerate sits at around 5~7 FPS.

The sampler shows the game is spending a huge amount of time in the graphics.image:drawBlurred method.

Interestingly though, a user on the unofficial Discord was unable to reproduce the problem on their Rev A hardware. Their Device Info screen looks like this instead. There's a performance drop when moving the viewfinder around, but not anything like the one I'm experiencing.

Does anyone else have a free moment to test this out? It'd be interesting to know if there is a difference in performance between Rev A and B here. It seems odd that a game that comes preinstalled with the console is hitting 5 FPS in certain areas of the game.

@dave is this the same performance issue as seen with rotating bitmaps 90 degrees ? It's affecting a season game (casual birder) on the rev B units, i tested on my REV A and it works more performantly on it in that situation, like i get 15 fps in that situation which is still ok, while on rev b units they get about 5-7 fps which is very choppy and noticeable

Yeah, it's the same core issue as the rotation problem--the new hardware is more sensitive to cache misses, and these algorithms are a worst case scenario there. I reworked the blur function, grouping the data so that it fits in data cache better, and got it up from 20% of the rev A speed to 75%. The casual birder demo case above runs around 16 fps now.. Not ideal but a lot better than before.

I'll try and get the fix on the schedule soon! It won't make it into 2.1, but hopefully 2.1.1. Thank you @adamblance for the excellent bug report!

5 Likes

Maybe it's interesting for others too, so I decided to share this here. I created a tiny test program to check the performance of a fullscreen image blur on device:
Blur Image Benchmark v0.0.1_b9.pdx.zip (3.7 KB)

I'm getting ~0.15 seconds per frame with a single blur pass on my Rev-B Playdate.

This is the source code:

local pd <const> = playdate
local gfx <const> = pd.graphics

-- a 400x240 image with some black shapes on white background
local img = gfx.image.new("image")

pd.display.setRefreshRate(0)
pd.setCollectsGarbage(false)
local gc <const> = collectgarbage

local menu = pd.getSystemMenu()

local radius = 2
local passes = 1

menu:addOptionsMenuItem("blur radius",
  {"0", "1", "2", "3", "4", "5"}, tostring(radius),
  function(x) radius = tonumber(x) end)

menu:addOptionsMenuItem("blur passes",
  {"1", "2", "3", "4", "5"}, tostring(passes),
  function(x) passes = tonumber(x) end)

function playdate.update()
  local spf = pd.getElapsedTime()
  local fps = 1/spf
  gc() -- don't count garbage collection in measurments
  pd.resetElapsedTime()

  if radius == 0 then
    img:draw(0,0)
  else
    img:drawBlurred(0, 0, radius, passes, gfx.image.kDitherTypeBayer2x2)
  end

  gfx.drawText("seconds/frame: "..tostring(spf), 3, 5)
  gfx.drawText("frames/second: "..tostring(fps), 3, 25)
end

2 Likes

I'm guessing you have a REV B playdate right ?

I ran the program on my REV A Playdate and by default (burradiaus 2 & passes 1) when just running it i get
0.044 - 0.045 second per frame and about 21 tot 22 frames per second

with blurradius 5 & 1 passes 1 i get
0.046 second per frame and 21 frames per second

The blur radius doesn't seem to affect it much on my REV A playdate

Yeah I have a Rev B. The blur radius doesn't seem to have an effect on mine either.

@adamblance have you tried the new 2.1.0 update yet ? it contains a fix for it and should improve the speed of it

It has definitely improved a lot! My little test program improved from ~0.15 seconds/frame to ~0.055 seconds/frame on my REV B device. Around a ~2.7x increase. :slight_smile:

I'm curious if it sped up on REV A hardware too?

2 Likes

on my rev A i don't see really an increase it's still 0.044 -0.045 second per frame. But the rev b increases are nice So casual birder should play better now on a rev b unit

2 Likes

Casual Birder is a much smoother experience now, thanks @dave! :pray:
I'm curious, is the difference in cache performance a result of the underclock on the H7 chip? Like does the new CPU spend longer resolving cache misses than the old one at a given clockspeed?

If that's the case, could cache performance be matched between the units by increasing clock speed? Or would that cause other performance metrics like graphics draw speed to drift too far between the RevA and RevB models?

1 Like

No, it's because we also had to switch memory chips because of supply chain problems. :frowning: The new one is on the octoSPI interface which has less throughput. Most of the time the H7's larger cache makes up for that but in cases like this where the algorithm winds up thrashing the cache it becomes a problem.

1 Like