glass dirty-skip: fold palette generation into the repaint token

Latent flaw in the c9e25e5 dirty-skip (now in master): the token hashes plane
PIXELS + lamp state only, but the ColorMapper gauge family (armor rosette
tints, the adpal/adpal2 damage flash) animates by writing CLUT entries with
ZERO pixel churn -- so a glass window whose plane is pixel-static held stale
colors while the D3D surround (which re-expands every frame) tracked live.

New SVGA16::paletteGeneration, bumped by the palette writers:
  - BuildSecondaryColor: only on a REAL entry change (the flash alternates
    palettes every Execute writing identical RGB at zero damage -- an
    unconditional bump would repaint every palette-expanding window every
    pump for nothing);
  - BuildSecondaryPalette / BuildAuxiliaryPalette / BlankPalette (full
    rebuilds): unconditionally.
GlassWindowToken folds it in for palette-expanding windows (monoTint < 0, or
all windows under BT_GLASS_MFD_PAL); mono-tint windows don't read the palette
and keep their pixel-only token.

KB: glass-cockpit.md gains the repaint-pump section (records f3d27f5 +
c9e25e5 + this).  Companion branch sec-phantom-fix carries the idx-254
translation-table fix -- disjoint hunks, merges in either order.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-08-10 21:29:56 -05:00
co-authored by Claude Opus 4.8
parent 40c35946cd
commit 47648d61be
4 changed files with 75 additions and 0 deletions
+23
View File
@@ -5445,6 +5445,7 @@ SVGA16::SVGA16(
BuildWindows(init_width,init_height,windowed, secondaryIndex, aux1Index, aux2Index);
for (int _i = 0; _i < 10; _i++) // DEV-COMPOSITE: lazily created on first surface draw
mDevSurfaceTex[_i] = NULL;
paletteGeneration = 0; // GLASS dirty-skip palette tracking
//STUBBED: VIDEO RB 1/15/07
# if defined(DEBUG)
Tell("SVGA16::SVGA16()\n");
@@ -7190,6 +7191,7 @@ void
svga_palette->paletteData.Valid = True;
svga_palette->modified = True;
((SVGA16 *) graphicsDisplay)->paletteGeneration++; // glass dirty-skip (full rebuild)
Check_Fpu();
}
@@ -7234,6 +7236,13 @@ void
SVGA16Palette
*svga_palette(&((SVGA16 *) graphicsDisplay)->palette[paletteID]);
// GLASS dirty-skip: track whether this write CHANGES anything -- the
// ColorMapper family calls this every Execute (the adpal/adpal2 flash
// alternates palettes even at zero damage, usually writing identical RGB),
// so bump the generation only on a real change or every glass window that
// palette-expands would repaint every pump for nothing.
int palette_changed = 0;
//-------------------------------------------
// If any of the ...TransparentZero modes are used,
// leave color zero undefined for this bit group by
@@ -7275,21 +7284,31 @@ void
{
case RedChannel:
case RedChannelTransparentZero:
if (destination_triplet->Red != source_triplet->Red)
palette_changed = 1;
destination_triplet->Red = source_triplet->Red;
break;
case GreenChannel:
case GreenChannelTransparentZero:
if (destination_triplet->Green != source_triplet->Green)
palette_changed = 1;
destination_triplet->Green = source_triplet->Green;
break;
case BlueChannel:
case BlueChannelTransparentZero:
if (destination_triplet->Blue != source_triplet->Blue)
palette_changed = 1;
destination_triplet->Blue = source_triplet->Blue;
break;
case AllChannels:
case AllChannelsTransparentZero:
if (destination_triplet->Red != source_triplet->Red
|| destination_triplet->Green != source_triplet->Green
|| destination_triplet->Blue != source_triplet->Blue)
palette_changed = 1;
*destination_triplet = *source_triplet;
break;
}
@@ -7310,6 +7329,8 @@ void
svga_palette->paletteData.Valid = True;
svga_palette->modified = True;
if (palette_changed)
((SVGA16 *) graphicsDisplay)->paletteGeneration++; // glass dirty-skip
Check_Fpu();
}
@@ -7413,6 +7434,7 @@ void
svga_palette->paletteData.Valid = True;
svga_palette->modified = True;
((SVGA16 *) graphicsDisplay)->paletteGeneration++; // glass dirty-skip (full rebuild)
# if defined(TESTPALETTE)
std::cout << "L4GraphicsPort::BuildAuxiliaryPalette for port " <<
@@ -7523,6 +7545,7 @@ void
svga_palette->paletteData.Valid = True;
svga_palette->modified = True;
((SVGA16 *) graphicsDisplay)->paletteGeneration++; // glass dirty-skip (full rebuild)
Check_Fpu();
}