// The MIT License (MIT)
//
// Copyright (C) 2026 Scott Duensing
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

// 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 they overlap
// or the gap between them is within DIRTY_MERGE_GAP pixels, they're combined
// into their axis-aligned bounding box. 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);

#endif // DVX_COMP_H
