Skip to content

Refactor scene transitions to reduce memory usage and improve cleanup - #55

Open
bubbadubc wants to merge 1 commit into
Stencyl:masterfrom
bubbadubc:master
Open

Refactor scene transitions to reduce memory usage and improve cleanup#55
bubbadubc wants to merge 1 commit into
Stencyl:masterfrom
bubbadubc:master

Conversation

@bubbadubc

Copy link
Copy Markdown

This refactors Stencyl's built-in scene transitions to reduce unnecessary full-screen bitmap allocations, remove redundant scene redraws, and make transition-owned rendering resources cleanly disposable.

The main issue was that several transitions created one or more full-screen BitmapData objects and repeatedly redrew the scene into them during the transition. At high resolutions this becomes expensive very quickly, and it also interacts poorly with shader-based rendering because the final shader-composited image already exists on the GPU.

The fix:

  • Added TransitionSnapshot.hx as a shared screenshot/capture path.

  • On native OpenGL/OpenGLES targets, transition snapshots are copied directly from the already-rendered backbuffer into a GPU texture using copyTexSubImage2D rather than redrawing the scene into a CPU BitmapData.

  • If GPU capture is unavailable, TransitionSnapshot falls back to the existing BitmapData.draw() behavior so non-GPU targets remain supported.

  • TransitionSnapshot explicitly disposes both its BitmapData wrapper and any GPU texture it creates.

  • Crossfade now uses the shared snapshot implementation instead of owning its own full-screen capture logic.

  • Slide no longer maintains multiple full-screen scene buffers or recomposites them every frame. It keeps only the scene state required for the transition.

  • Circle/Spotlight and Rectangle no longer require a full-screen screenshot. Their reveal areas are generated directly as transition geometry over the live scene.

  • Bubbles no longer captures the full screen into BitmapData. The transition operates on the live scene using expanding circular regions.

  • Pixelize/Blur removes the two full-resolution BitmapData buffers and the per-pixel CPU processing loop. It now renders into one reusable low-resolution buffer and scales that result with nearest-neighbor filtering.

  • Blinds, Fade In, and Fade Out remain lightweight vector transitions, with cleanup tightened so owned graphics and tween references are released consistently.

  • Public transition constructors, directions, and timing behavior remain unchanged.

At 3840x2160, a single 32-bit full-screen BitmapData is roughly 31.6 MiB. Several of the previous transitions allocated multiple buffers of this size, so this removes a significant amount of avoidable transition memory usage.

The goal of this change is not to introduce a new rendering system. It keeps the existing transition API and behavior while using the already-rendered GPU frame when available, falling back safely where necessary, and making resource ownership and cleanup explicit.

TODO / Known limitation:

  • Bubbles and Spotlight still use more memory during the transition than I would ideally like.
  • Their current peak usage is not worse than the existing implementation; it is roughly in line with the previous behavior.
  • The current refactor removes the unnecessary full-screen bitmap capture/redraw paths, but these two transitions still have a relatively expensive rendering cost because of their animated circular geometry/masking.
  • This is not considered a blocker for the refactor, but there is still room to investigate whether their temporary rendering cost can be reduced further.

This refactors Stencyl's built-in scene transitions to reduce unnecessary
full-screen bitmap allocations, remove redundant scene redraws, and make
transition-owned rendering resources cleanly disposable.

The main issue was that several transitions created one or more full-screen
BitmapData objects and repeatedly redrew the scene into them during the
transition. At high resolutions this becomes expensive very quickly, and it
also interacts poorly with shader-based rendering because the final
shader-composited image already exists on the GPU.

The fix:

- Added TransitionSnapshot.hx as a shared screenshot/capture path.

- On native OpenGL/OpenGLES targets, transition snapshots are copied directly
  from the already-rendered backbuffer into a GPU texture using
  copyTexSubImage2D rather than redrawing the scene into a CPU BitmapData.

- If GPU capture is unavailable, TransitionSnapshot falls back to the existing
  BitmapData.draw() behavior so non-GPU targets remain supported.

- TransitionSnapshot explicitly disposes both its BitmapData wrapper and any
  GPU texture it creates.

- Crossfade now uses the shared snapshot implementation instead of owning its
  own full-screen capture logic.

- Slide no longer maintains multiple full-screen scene buffers or recomposites
  them every frame. It keeps only the scene state required for the transition.

- Circle/Spotlight and Rectangle no longer require a full-screen screenshot.
  Their reveal areas are generated directly as transition geometry over the
  live scene.

- Bubbles no longer captures the full screen into BitmapData. The transition
  operates on the live scene using expanding circular regions.

- Pixelize/Blur removes the two full-resolution BitmapData buffers and the
  per-pixel CPU processing loop. It now renders into one reusable
  low-resolution buffer and scales that result with nearest-neighbor filtering.

- Blinds, Fade In, and Fade Out remain lightweight vector transitions, with
  cleanup tightened so owned graphics and tween references are released
  consistently.

- Public transition constructors, directions, and timing behavior remain
  unchanged.

At 3840x2160, a single 32-bit full-screen BitmapData is roughly 31.6 MiB.
Several of the previous transitions allocated multiple buffers of this size,
so this removes a significant amount of avoidable transition memory usage.

The goal of this change is not to introduce a new rendering system. It keeps
the existing transition API and behavior while using the already-rendered GPU
frame when available, falling back safely where necessary, and making resource
ownership and cleanup explicit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant