Multiple calls to `draw` per frame even when sprite is marked dirty


I'm not certain this is a bug, but it certainly seems like unexpected behavior. I recently noticed that draw was being called multiple times per frame for one of my sprites. Admittedly, I hadn't even realized that the function accepted arguments for the subrect to draw (and I suspect few folks actually leverage those to do selective drawing in practice). Anyway, the reason I believe there may be a bug is because that particular sprite was marked dirty in update to force a redraw every frame.

I was seeing two calls to draw each frame:

  1. First with a subrect identifying the bottom right quadrant (x = 12, y = 9, w = 12, h = 9, sprite.width = 24, sprite.height = 18)
  2. A second call in which all four provided parameters were nil (which begs the question of whether that's also a bug — should those reflect the sprite bounds in that case?)

Given that it's marked for redraw anyway, it seems wasteful to have draw called multiple times per frame. Incidentally, I discovered this by accident because I had made the mistake of incrementing a frame counter — which was used to animate some aspects of the drawing — within draw instead of update, and so it was running at 2x speed. I noticed that the effective frame rate of the animation was very different depending on the display scale, even though the FPS was locked at 40 and the entire sprite was visible at all display scales. Specifically, the call to draw with the non-nil subrect parameters does not happen at larger display scales (4x, 8x, etc), and I have no idea why.

I'm happy to provide more details about those specific circumstances if needed, but they're tangential to the root question of whether draw should ever be called twice even when the sprite is marked dirty. Thanks!

Forgive me: I completely disregarded an abnormal usage of this particular sprite, which the Playdate Squad discord channel helped me realize. I had expected to use it as a normal sprite, but wound up needing to render it into another context instead, and so I'm calling draw() directly — with no arguments — to have it render where I need it each frame. That explains most of the situation.

I'm still unclear on why the display scale impacts the other calls to draw that I'm not making, but I'm far less concerned that there's a bug with markDirty at this point. Although: given that I am marking it dirty, why isn't there a call to draw for the full bounds of the sprite`?