joeylib2/src/amiga/amigaPlanar.h

55 lines
2.4 KiB
C

// Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
// See LICENSE.md for license information.
// SPDX-License-Identifier: MIT
//
// Amiga per-surface planar storage, shared between the HAL
// (src/amiga/hal.c) and the cross-platform sprite dispatchers
// (src/codegen/spriteCompile.c) so plane-pointer access inlines
// instead of paying a cross-TU function call per plane (NATIVE-PERF
// Phase 2). Plane pointers are lifetime-immutable: portData is written
// only at surface create/destroy, so reading them needs no cache and
// no invalidation.
#ifndef JOEY_AMIGA_PLANAR_H
#define JOEY_AMIGA_PLANAR_H
#include <stdint.h>
#include <stdbool.h>
#include "surfaceInternal.h"
#define AMIGA_BITPLANES 4
#define AMIGA_BYTES_PER_ROW (JL_SURFACE_WIDTH / 8)
#define AMIGA_PLANE_SIZE (AMIGA_BYTES_PER_ROW * JL_SURFACE_HEIGHT)
// What a surface actually allocates per plane: one byte of slack past the end,
// which src/m68k/planarFill.s relies on. See the note at the AllocMem in
// jlpSurfaceAllocPortData.
#define AMIGA_PLANE_ALLOC (AMIGA_PLANE_SIZE + 1u)
// jlSurfaceT.portData points to this on Amiga: the 4 plane base
// pointers + stride. Every surface (including the stage, which gets
// its OWN shadow planes, NOT aliased to the displayed gPlanes) owns
// AllocMem'd planes, in chip RAM where the blitter can reach them; a
// surface other than the stage made when chip RAM has run out gets them
// anywhere (chip false), and its fills and copies run on the CPU. present
// copies shadow -> display planes atomically.
//
// Direct fields rather than a union because the consumer is asm /
// inline C that wants minimal indirection in the inner loop.
typedef struct {
uint8_t *planes[AMIGA_BITPLANES];
uint16_t bytesPerRow; // = AMIGA_BYTES_PER_ROW (40)
uint16_t bytesPerPlane; // = AMIGA_PLANE_SIZE (8000)
bool ownsPlanes; // true = AllocMem'd (free at destroy);
// false = aliased (don't free)
bool chip; // the planes are chip RAM: the blitter reaches them
} AmigaPlanarT;
// NULL means "surface has no planar storage" -- callers use that as
// their route-to-generic / no-op gate, exactly the contract the old
// jlpSurfacePlanePtr cross-TU function provided.
static inline AmigaPlanarT *amigaSurfacePlanar(const jlSurfaceT *s) {
return (AmigaPlanarT *)s->portData;
}
#endif