@displayxr/inline3d 1.37.1 → 1.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -699,7 +699,7 @@ export class SceneViewer {
699
699
 
700
700
  // 1. A short view list is the load-induced mono fallback. Stereo needs two.
701
701
  if (!views || views.length < 2) {
702
- this._replayLastGood();
702
+ this._replayOrFlat();
703
703
  return;
704
704
  }
705
705
 
@@ -725,7 +725,7 @@ export class SceneViewer {
725
725
  for (const view of views) {
726
726
  const vp = layer && typeof layer.getViewport === 'function' ? layer.getViewport(view) : null;
727
727
  if (!vp || !(vp.width > 0) || !(vp.height > 0)) {
728
- this._replayLastGood();
728
+ this._replayOrFlat();
729
729
  return;
730
730
  }
731
731
  vps.push(vp);
@@ -891,11 +891,41 @@ export class SceneViewer {
891
891
  }
892
892
  }
893
893
 
894
+ /**
895
+ * A session frame that cannot draw its own views still PRESENTS (1.38): the last good frame,
896
+ * or, before there is one, the mono camera into both halves — flat, but drawn. An undrawn
897
+ * woven canvas can drop out of the frame the compositor aggregates (woven-canvas-rules,
898
+ * "redraw every frame"), and this viewer used to leave exactly the frames before the first
899
+ * stereo one undrawn. Every clear here is followed by a draw, so the dark-blink rule (web#12)
900
+ * still holds.
901
+ */
902
+ _replayOrFlat() {
903
+ return this._replayLastGood() || this._drawFlatPair();
904
+ }
905
+
906
+ _drawFlatPair() {
907
+ if (this._disposed) return false;
908
+ const r = this.renderer;
909
+ const b = this._bufScale();
910
+ if (!(b.w > 1) || !(b.h > 0)) return false;
911
+ const half = Math.floor(b.w / 2);
912
+ r.clear();
913
+ r.setScissorTest(true);
914
+ for (const x of [0, half]) {
915
+ const vp = { x, y: 0, width: half, height: b.h };
916
+ r.setViewport(vp.x, vp.y, vp.width, vp.height);
917
+ r.setScissor(vp.x, vp.y, vp.width, vp.height);
918
+ r.render(this.scene, this.monoCamera);
919
+ if (this._feather) this._feather.render(r, vp);
920
+ }
921
+ r.setScissorTest(false);
922
+ return true;
923
+ }
924
+
894
925
  /**
895
926
  * Re-render the last good frame from the cached matrices. Returns false when there is no
896
- * cache yet — and the caller must then do NOTHING, not clear: before the first good frame
897
- * the canvas holds either the page's own initial state or the mono fallback's output, both
898
- * of which are better than black.
927
+ * cache yet (onFrame then draws the flat pair, see _replayOrFlat; a resize leaves the
928
+ * freshly cleared store to the next session frame).
899
929
  */
900
930
  _replayLastGood() {
901
931
  const g = this._lastGood;