Skip to content

[patch] Add a non-blended (opaque) image blit path to the canvas API #194

Description

@andrewd207

Component: corelib — TfpgCanvasBase / THybridCanvas (software renderer)

Description:

The only way to draw an image onto a canvas is DrawImage/DrawImagePart, which always routes through the transparency path. On the hybrid (software/AggPas) renderer this means every image goes through AggPas's per-pixel alpha-blend rasteriser (transformImage → BGRA32_BLEND_SOLID_HSPAN), and for masked images it first builds a temporary alpha-applied copy of the whole image. For fully opaque content — background tiles, double-buffered composites, screenshots, sprite sheets with no transparency — this blending is pure overhead and shows up clearly in profiling.

There was no public way to ask the canvas for a plain copy of pixels.

Fix:

Add a blit operation to the canvas contract that copies image pixels straight into the target, bypassing the transparency path:

  • TfpgCanvasBase gains public BlitImage(x, y, img) and BlitImagePart(x, y, img, xi, yi, w, h), dispatching through a new protected virtual DoBlitImagePart.
  • The default DoBlitImagePart simply forwards to DoDrawImagePart, so every backend keeps rendering correctly — backends without a pixel buffer transparently degrade to the normal image draw, and calling code stays portable.
  • THybridCanvas overrides DoBlitImagePart with a direct row-by-row Move into the pixel buffer: it applies the window delta, clips to the AggPas clip rect, the buffer bounds, and the source image bounds, then copies — no mask lookup, no alpha blend. It falls back to DoDrawImagePart when prerequisites (allocated buffer, 32-bit image) aren't met.

This mirrors the existing opaque fast-path already used in THybridCanvas.DoFillRectangle.

Notes / limitations:

  • The blit is 1:1 (no scaling) — it's a copy, not a StretchDraw replacement.
  • It is intentionally opaque: mask/alpha are ignored. Callers that need transparency should keep using DrawImage/DrawImagePart.

hybrid_canvas_blit.patch

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions