npm package: @obinexusltd/obix-driver-compositor
Description: OBIX Compositor Driver - Layer management, z-index optimization, and occlusion culling
Author: OBINexus
Latest version: 0.1.1

# @obinexusltd/obix-driver-compositor

Layer management, AABB occlusion culling, CSS stacking context isolation, painter's algorithm paint ordering, blend mode registry, and performance profiling for the OBIX SDK.

## Installation

```bash
npm install @obinexusltd/obix-driver-compositor
```

## Quick Start

```typescript
import { createCompositorDriver } from '@obinexusltd/obix-driver-compositor';

const compositor = createCompositorDriver({
  occlusionCulling: true,
  zIndexStrategy: 'auto',
  enableProfiling: true,
});

await compositor.initialize();

const el = document.getElementById('layer-a')!;
await compositor.createLayer('background', el, 0);
compositor.setBounds('background', { x: 0, y: 0, width: 1920, height: 1080 });

const overlay = document.getElementById('layer-b')!;
await compositor.createLayer('overlay', overlay, 10);
compositor.setBounds('overlay', { x: 100, y: 100, width: 400, height: 300 });

compositor.optimize();

const displayList = compositor.getDisplayList();
// [{ layerId: 'background', paintOrder: 0, zIndex: 0, bounds: ... },
//  { layerId: 'overlay',    paintOrder: 1, zIndex: 10, bounds: ... }]

const metrics = compositor.getMetrics();
console.log(`Occlusion rate: ${(metrics.occlusionRate * 100).toFixed(1)}%`);

await compositor.destroy();
```

## API Reference

### Driver Lifecycle

| Method | Description |
|--------|-------------|
| `initialize(): Promise<void>` | Initializes the driver (no-op; reserved for async setup) |
| `destroy(): Promise<void>` | Destroys all sub-modules and clears all state |

### Configuration

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `maxLayers` | `number` | unlimited | Maximum number of layers allowed |
| `occlusionCulling` | `boolean` | `true` | Enable AABB-based occlusion culling |
| `zIndexStrategy` | `'auto' \| 'manual' \| 'stacking-context'` | `'auto'` | Stacking context grouping strategy |
| `defaultBlendMode` | `BlendMode` | `'normal'` | Default blend mode for new layers |
| `compactZIndices` | `boolean` | `false` | Compact z-indices to sequential integers during `optimize()` |
| `enableProfiling` | `boolean` | `true` | Enable paint time and occlusion rate metrics |

### Layer Management

| Method | Description |
|--------|-------------|
| `createLayer(id, element, zIndex): Promise<void>` | Creates a new compositor layer |
| `removeLayer(id): Promise<void>` | Removes a layer by id |
| `setZIndex(id, zIndex): void` | Updates a layer's z-index and recomputes occlusion |
| `setVisible(id, visible): void` | Toggles layer visibility (hidden layers are excluded from display list) |
| `setBounds(id, bounds): void` | Sets the AABB bounds used for occlusion tests |
| `getLayers(): CompositorLayer[]` | Returns all layers sorted by z-index ascending |
| `getLayer(id): CompositorLayer \| null` | Returns a layer by id |

### Occlusion Culling

The occlusion engine uses **AABB (Axis-Aligned Bounding Box) containment tests** rather than a naive z-stack approach.

A layer is marked `isOccluded = true` only when a higher-z-index layer's `bounds` **fully contains** the layer's `bounds`. Non-overlapping layers are never marked as occluded, even if a layer with a higher z-index exists.

Layers without `bounds` set fall back to z-stack ordering: any higher-z-index layer causes occlusion.

```
Layer A (z=1, bounds: {0,0,200,200})       ← occluded by B
Layer B (z=2, bounds: {0,0,500,500})       ← not occluded

Layer C (z=1, bounds: {0,0,100,100})       ← NOT occluded by D (non-overlapping)
Layer D (z=2, bounds: {200,0,100,100})     ← not occluded
```

| Method | Description |
|--------|-------------|
| `isOccluded(id): boolean` | Returns whether a layer is currently occluded |
| `getOcclusionMap(): Map<string, boolean>` | Returns a snapshot of the full occlusion map |

### Stacking Contexts

| Strategy | Behavior |
|----------|----------|
| `'stacking-context'` | Groups all layers with `paintIsolated === true` into a shared context |
| `'auto'` | Partitions layers into contexts at natural z-index gaps (gap > 1) |
| `'manual'` | Only respects explicit `stackingContext.assignToContext()` calls |

| Method | Description |
|--------|-------------|
| `rebuildStackingContext(): Promise<void>` | Rebuilds all stacking contexts using the configured strategy |

### Paint Order

The display list is built using the **painter's algorithm** (back-to-front), assigning sequential `paintOrder` integers to visible layers sorted by z-index.

| Method | Description |
|--------|-------------|
| `getDisplayList(): DisplayListEntry[]` | Returns the current display list (visible layers only, sorted by z-index) |
| `optimize(): void` | Recomputes occlusion, rebuilds stacking contexts, optionally compacts z-indices, and records profiler metrics |

### Blend Modes

12 CSS compositing blend modes are supported:

`normal` · `multiply` · `screen` · `overlay` · `darken` · `lighten` · `color-dodge` · `color-burn` · `hard-light` · `soft-light` · `difference` · `exclusion`

| Method | Description |
|--------|-------------|
| `setBlendMode(layerId, mode): void` | Sets the blend mode on a layer (throws for invalid values) |

### Metrics

| Field | Type | Description |
|-------|------|-------------|
| `layerCount` | `number` | Total number of layers |
| `visibleCount` | `number` | Number of visible layers |
| `occludedCount` | `number` | Number of occluded layers |
| `occlusionRate` | `number` | `occludedCount / layerCount` (0–1) |
| `paintTimeMs` | `number` | Rolling average paint time in milliseconds |
| `stackingContextCount` | `number` | Number of active stacking contexts |

```typescript
const metrics = compositor.getMetrics();
```

### Sub-Module Accessors

The driver exposes its sub-modules for advanced use:

| Accessor | Type | Description |
|----------|------|-------------|
| `layerManager` | `LayerManagerAPI` | Direct layer CRUD access |
| `occlusionEngine` | `OcclusionEngineAPI` | Direct occlusion engine access |
| `stackingContext` | `StackingContextAPI` | Direct stacking context management |
| `paintOrder` | `PaintOrderAPI` | Direct display list and compaction access |
| `blendModes` | `BlendModeAPI` | Direct blend mode registry access |
| `profiler` | `CompositorProfilerAPI \| null` | Direct profiler access (null if `enableProfiling: false`) |

## Architecture

| Module | File | Responsibility |
|--------|------|---------------|
| Types | `src/types.ts` | All shared interfaces and type aliases |
| Layer Manager | `src/layer-manager.ts` | Layer CRUD, z-index ordering, maxLayers enforcement |
| Occlusion Engine | `src/occlusion-engine.ts` | AABB containment tests, occlusion map |
| Stacking Context | `src/stacking-context.ts` | CSS stacking context isolation, paint groups |
| Paint Order | `src/paint-order.ts` | Painter's algorithm display list, z-index compaction |
| Blend Mode | `src/blend-mode.ts` | Blend mode registry and validation |
| Compositor Profiler | `src/compositor-profiler.ts` | Paint time, layer counts, occlusion rate |
| Driver | `src/index.ts` | Orchestrates all sub-modules, main public API |

## License

MIT — OBINexus &lt;okpalan@protonmail.com&gt;