// dvx_comp.h  -- Layer 3: Dirty rectangle compositor for DVX GUI
//
// The compositor tracks which screen regions have changed and ensures
// only those regions are redrawn and flushed to video memory. This is
// the key to acceptable frame rates on 486/Pentium hardware  -- a full
// 640x480x32bpp frame is 1.2 MB, but a typical dirty region during
// normal interaction (e.g. typing in a text field) might be a few KB.
//
// The compositing pipeline each frame:
//   1. Layers above (WM, app) call dirtyListAdd() for changed regions
//   2. dirtyListMerge() consolidates overlapping/adjacent rects
//   3. For each merged dirty rect, the compositor clips and redraws
//      the desktop, then each window (back-to-front, painter's algorithm)
//   4. flushRect() copies each dirty rect from backBuf to the LFB
//
// The merge step is important because many small dirty rects (e.g. from
// a window drag) often cluster together, and flushing one large rect is
// much faster than many small ones due to reduced per-rect overhead and
// better memory bus utilization.
#ifndef DVX_COMP_H
#define DVX_COMP_H

#include "dvxTypes.h"

// Zero the dirty rect count. Called at the start of each frame.
void dirtyListInit(DirtyListT *dl);

// Enqueue a dirty rectangle. Grows dynamically; merges at a soft cap.
void dirtyListAdd(DirtyListT *dl, int32_t x, int32_t y, int32_t w, int32_t h);

// Consolidate the dirty list by merging overlapping and adjacent rects.
// Uses an iterative pairwise merge: for each pair of rects, if merging
// them doesn't increase the total area by more than a threshold, they're
// combined. This reduces the number of compositor passes and LFB flush
// operations at the cost of potentially redrawing some clean pixels.
void dirtyListMerge(DirtyListT *dl);

// Reset the dirty list to empty.
void dirtyListClear(DirtyListT *dl);

// Copy a rectangle from the system RAM backbuffer to the LFB (video memory).
// This is the final step  -- the only place where the real framebuffer is
// written. Uses platform-specific fast copy (rep movsd on DOS) for each
// scanline of the rect.
void flushRect(DisplayT *d, const RectT *r);

// Compute the intersection of two rectangles. Returns true if they overlap,
// with the intersection written to result. Used extensively during
// compositing to clip window content to dirty regions.
bool rectIntersect(const RectT *a, const RectT *b, RectT *result);

// Returns true if the rectangle has zero or negative area.
bool rectIsEmpty(const RectT *r);

#endif // DVX_COMP_H
