713cc06056876ff148c7555a4eb520e8987fb793
hiram
  Mon Mar 30 12:53:19 2026 -0700
switch gcOnFly to bigWig file at a specified density refs #35958

diff --git src/hg/hgTracks/bigWigTrack.c src/hg/hgTracks/bigWigTrack.c
index 022d30cae2a..61199f9535c 100644
--- src/hg/hgTracks/bigWigTrack.c
+++ src/hg/hgTracks/bigWigTrack.c
@@ -413,32 +413,44 @@
             if (gcPct < preDraw[xCoord].min) preDraw[xCoord].min = gcPct;
             preDraw[xCoord].sumData    += gcPct;
             preDraw[xCoord].sumSquares += gcPct * gcPct;
             }
         }
     }
 
 freeMem(windows);
 return pre;
 }
 
 static void gc5BaseOnTheFlyLoadItems(struct track *tg)
 /* Compute GC percent from genome sequence; called in the loadItems phase
  * just as bigWigLoadItems calls bigWigLoadPreDraw to fill preDrawContainer.
  * Fetch sequence that covers the preDraw smoothing margins on each side so
- * the smoothing/averaging machinery has data at the window edges. */
+ * the smoothing/averaging machinery has data at the window edges.
+ * When the display density exceeds gcOnFlyMaxDensity bases per pixel,
+ * fall back to reading a pre-computed bigWig file via bigWigLoadItems. */
 {
+char *maxDenseStr = trackDbSettingClosestToHomeOrDefault(tg->tdb, "gcOnFlyMaxDensity", "50000");
+if (maxDenseStr != NULL)
+    {
+    double basesPerPixel = (double)(winEnd - winStart) / insideWidth;
+    if (basesPerPixel > atof(maxDenseStr))
+	{
+	bigWigLoadItems(tg);
+	return;
+	}
+    }
 tg->items = NULL;
 tg->mapsSelf = TRUE;
 /* Extend the fetch range by wiggleSmoothingMax pixels worth of bases on
  * each side, rounded up to the nearest 5-base span.  Use long long for
  * the arithmetic to avoid 32-bit overflow near the ends of large chroms. */
 double basesPerPixel = (double)(winEnd - winStart) / insideWidth;
 int marginBases = ((int)(wiggleSmoothingMax * basesPerPixel) / 5 + 1) * 5;
 int chromSize = hChromSize(database, chromName);
 long long fetchStartLong = (long long)winStart - marginBases;
 int fetchStart = (fetchStartLong < 0) ? 0 : (int)fetchStartLong;
 long long fetchEndLong = (long long)winEnd + marginBases;
 int fetchEnd = (fetchEndLong > chromSize) ? chromSize : (int)fetchEndLong;
 gc5BaseOnTheFlyLoadPreDraw(tg, fetchStart, fetchEnd, insideWidth);
 }