Engine 0064, 0065 (T-527): a layer paint with nothing pending skipped, a moved displayport base repainted; a failed band surface not retried every frame
UXP_PIN and the recipe's SRCREV at the engine branch's f4fefca0; patch-queue --check reproduces it with the 65 patches. Device: pans unchanged (the long page 33.1 fps, desktop Wikipedia 23.6), verify 0 rows wrong, default-check on the GPU path with 0 faults. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f43a016509
commit
eb9987b742
6 files changed
+152
-3
No files matched your search
@@ -0,0 +1,88 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NotAlexNoyle <alexnoyle@icloud.com>
|
||||
Date: Mon, 26 Oct 2026 00:01:48 -0400
|
||||
Subject: [PATCH] widget: a GPU-path layer paint with nothing pending is
|
||||
skipped; a moved displayport base schedules a paint
|
||||
|
||||
T-527. JihadPaintLayers returns at once after the first paint when the widget has no invalid region,
|
||||
no paint task pending and the refresh driver owes no view-manager flush: the layer tree is current
|
||||
and a paint would only build the display list again (JIHAD_GPU_PAINT_ALWAYS=1 paints every time).
|
||||
jihad_layout_set_displayport2 schedules a paint of the root scroll frame when the base moved
|
||||
(SetDisplayPortMargins compares displayports computed with the new base on both sides).
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
---
|
||||
layout/base/nsLayoutUtils.cpp | 7 +++++++
|
||||
widget/PuppetWidget.cpp | 20 ++++++++++++++++++++
|
||||
widget/PuppetWidget.h | 1 +
|
||||
3 files changed, 28 insertions(+)
|
||||
|
||||
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
|
||||
index 036734c9eb..026f65cd6a 100644
|
||||
--- a/layout/base/nsLayoutUtils.cpp
|
||||
+++ b/layout/base/nsLayoutUtils.cpp
|
||||
@@ -9484,7 +9484,14 @@ jihad_layout_set_displayport2(nsIDocShell* aDocShell, float aVisW, float aVisH,
|
||||
const float baseH = std::max(aVisH, aShiftY > 0.0f ? 0.0f : portH);
|
||||
const nsRect base(nsPresContext::CSSPixelsToAppUnits(aShiftX * res), nsPresContext::CSSPixelsToAppUnits(aShiftY * res),
|
||||
nsPresContext::CSSPixelsToAppUnits(baseW * res), nsPresContext::CSSPixelsToAppUnits(baseH * res));
|
||||
+ // T-527: a new base is a new displayport even when the margins are the same (SetDisplayPortMargins
|
||||
+ // compares the displayport computed with the new base on both sides and schedules no paint)
|
||||
+ const nsRect* oldBase = static_cast<nsRect*>(content->GetProperty(nsGkAtoms::DisplayPortBase));
|
||||
+ const bool baseMoved = !oldBase || !oldBase->IsEqualEdges(base);
|
||||
nsLayoutUtils::SetDisplayPortBase(content, base);
|
||||
+ if (baseMoved) {
|
||||
+ rsf->SchedulePaint();
|
||||
+ }
|
||||
const ScreenMargin margins(aTop * res, aSide * res, aBottom * res, aSide * res);
|
||||
static int sLogged = 0;
|
||||
if (sLogged++ < 12) {
|
||||
diff --git a/widget/PuppetWidget.cpp b/widget/PuppetWidget.cpp
|
||||
index b056433871..1e32b2e6eb 100644
|
||||
--- a/widget/PuppetWidget.cpp
|
||||
+++ b/widget/PuppetWidget.cpp
|
||||
@@ -50,6 +50,7 @@ namespace mozilla { namespace layers { extern std::atomic<uint32_t> gJihadLateWr
|
||||
// jihad_offscreen_composite_popups at the bottom of this file):
|
||||
#include "nsXULPopupManager.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
+#include "nsRefreshDriver.h" // T-527: a paint already scheduled (JihadPaintLayers)
|
||||
#include "nsRenderingContext.h"
|
||||
#include "nsMenuPopupFrame.h"
|
||||
#include "nsMenuFrame.h"
|
||||
@@ -967,6 +968,25 @@ PuppetWidget::JihadPaintLayers(nsIDocShell* aDocShell)
|
||||
if (!mozilla::layers::CompositorThreadHolder::Loop()) {
|
||||
return false;
|
||||
}
|
||||
+ // T-527: nothing to paint — no invalidation waiting (the widget's region, its paint task), no paint
|
||||
+ // the refresh driver has scheduled, the layers painted before: the layer tree is current, and a paint
|
||||
+ // would only build the whole display list again (desktop Wikipedia: 16-90 ms of the main thread; the
|
||||
+ // daemon asks for a layer paint every 40 ms during a pan and right after the refresh driver's own
|
||||
+ // paint of a zoom). JIHAD_GPU_PAINT_ALWAYS=1 paints every time, as before.
|
||||
+ {
|
||||
+ static const bool sAlways = getenv("JIHAD_GPU_PAINT_ALWAYS") != nullptr;
|
||||
+ nsPresContext* pc = presShell->GetPresContext();
|
||||
+ nsRefreshDriver* rd = pc ? pc->RefreshDriver() : nullptr;
|
||||
+ if (!sAlways && mJihadLayersPainted && mDirtyRegion.IsEmpty() && !mPaintTask.IsPending() && rd &&
|
||||
+ !rd->ViewManagerFlushIsPending()) {
|
||||
+ static uint32_t sSkipped = 0;
|
||||
+ if ((++sSkipped % 100) == 1) {
|
||||
+ JIHAD_GPU_LOG("[jihad-gpu] layer paint skipped: nothing pending (%u so far)\n", sSkipped);
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ mJihadLayersPainted = true;
|
||||
mozilla::TimeStamp t0 = mozilla::TimeStamp::Now();
|
||||
nsRegion dirty(root->GetDimensions());
|
||||
presShell->Paint(root, dirty, nsIPresShell::PAINT_LAYERS);
|
||||
diff --git a/widget/PuppetWidget.h b/widget/PuppetWidget.h
|
||||
index 7b570ef46d..755f67de5a 100644
|
||||
--- a/widget/PuppetWidget.h
|
||||
+++ b/widget/PuppetWidget.h
|
||||
@@ -459,6 +459,7 @@ private:
|
||||
RefPtr<PuppetWidget> mChild;
|
||||
LayoutDeviceIntRegion mDirtyRegion;
|
||||
bool mJihadDirty = false; // sticky Invalidate() flag, drained by JihadTakeDirty()
|
||||
+ bool mJihadLayersPainted = false; // T-527: JihadPaintLayers has painted this widget's layers once
|
||||
bool mJihadCompositorTried = false; // T-502: CreateCompositor attempted once per widget
|
||||
bool mJihadSharedLayerManager = false; // T-502: mLayerManager is the parent's (a child widget)
|
||||
float mJihadScale = 1.0f; // T-502: the card's zoom, applied by the compositor
|
||||
@@ -0,0 +1,59 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: NotAlexNoyle <alexnoyle@icloud.com>
|
||||
Date: Mon, 26 Oct 2026 00:01:48 -0400
|
||||
Subject: [PATCH] gpu-compositor: a band surface that cannot be made at a width
|
||||
is not tried again every frame
|
||||
|
||||
T-527 (review). A pbuffer or render target that failed at a width was re-created, and a line logged,
|
||||
on every band frame (~25 a second into the device's small /var). The width it failed at is kept per
|
||||
surface and the frame's own surface does the pass.
|
||||
|
||||
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
||||
---
|
||||
gfx/layers/opengl/CompositorOGL.cpp | 10 +++++++++-
|
||||
gfx/layers/opengl/CompositorOGL.h | 1 +
|
||||
2 files changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp
|
||||
index ed16534208..9b7f244915 100644
|
||||
--- a/gfx/layers/opengl/CompositorOGL.cpp
|
||||
+++ b/gfx/layers/opengl/CompositorOGL.cpp
|
||||
@@ -2347,8 +2347,15 @@ CompositorOGL::JihadBeginBandPass(int aWidth, int aRows)
|
||||
GLuint& rb = tall ? mJihadBandTallRB : mJihadBandRB;
|
||||
GLuint& fbo = tall ? mJihadBandTallFBO : mJihadBandFBO;
|
||||
int& w = tall ? mJihadBandTallW : mJihadBandW;
|
||||
+ // a surface that could not be made at this width is not made again every band frame (a line each,
|
||||
+ // ~25 a second, into the device's small /var): the frame's own surface does the pass
|
||||
+ int& failW = mJihadBandFailW[tall ? 1 : 0];
|
||||
+ if (failW == aWidth) {
|
||||
+ return 0;
|
||||
+ }
|
||||
GLContextEGL* egl = static_cast<GLContextEGL*>(mGLContext.get());
|
||||
if (!egl->JihadUseBandPBuffer(aWidth, rows, tall)) {
|
||||
+ failW = aWidth;
|
||||
return 0;
|
||||
}
|
||||
if (!fbo || w != aWidth) {
|
||||
@@ -2361,8 +2368,9 @@ CompositorOGL::JihadBeginBandPass(int aWidth, int aRows)
|
||||
mGLContext->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0, LOCAL_GL_RENDERBUFFER, rb);
|
||||
const GLenum st = mGLContext->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
|
||||
if (st != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
|
||||
- fprintf(stderr, "[jihad-gpu] band target %dx%d incomplete (0x%x)\n", aWidth, rows, st);
|
||||
+ fprintf(stderr, "[jihad-gpu] band target %dx%d incomplete (0x%x): not tried again at this width\n", aWidth, rows, st);
|
||||
egl->JihadUseFramePBuffer();
|
||||
+ failW = aWidth;
|
||||
return 0;
|
||||
}
|
||||
w = aWidth;
|
||||
diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h
|
||||
index 0c27bb890a..39968a8791 100644
|
||||
--- a/gfx/layers/opengl/CompositorOGL.h
|
||||
+++ b/gfx/layers/opengl/CompositorOGL.h
|
||||
@@ -258,6 +258,7 @@ public:
|
||||
int mJihadBandW = 0;
|
||||
GLuint mJihadBandTallRB = 0, mJihadBandTallFBO = 0; // T-527: the tall band surface's target
|
||||
int mJihadBandTallW = 0;
|
||||
+ int mJihadBandFailW[2] = { 0, 0 }; // T-527: the width a band surface (0) or the tall one (1) failed at: not tried again
|
||||
// the band surface's rows: JIHAD_GPU_BAND_ROWS (64..942, default 256; round 137)
|
||||
static int JihadBandRows() {
|
||||
static const int sRows = [] {
|
||||
@@ -9,7 +9,7 @@ UXP_BASE=5f290d1097a8350b56ce2092aa9d5fc9147c6661
|
||||
# The tip of our engine branch (NotAlexNoyle/UXP-Jihad, jihad/uxp-<UXP_TAG>: one commit per patch
|
||||
# in build/desktop/patches) the build uses. The third_party/uxp gitlink and the OE recipe's SRCREV
|
||||
# must both be this commit.
|
||||
UXP_PIN=bda3141209f1e97571e6e0879d85c51bb1386df1
|
||||
UXP_PIN=f4fefca0d2177c706cfbee2c1d5d520be1896228
|
||||
# What the user agent and the start pages say: Goanna version and the short UPSTREAM base.
|
||||
GOANNA_VERSION=6.9
|
||||
UXP_SHORT=5f290d1
|
||||
|
||||
@@ -34,7 +34,7 @@ COMPATIBLE_MACHINE = "(tenderloin|opal)"
|
||||
# for real (build/engine/patch-queue.sh --check proves it reproduces SRCREV's tree):
|
||||
# SRC_URI = "git://repo.palemoon.org/MoonchildProductions/UXP.git;protocol=https;tag=<UXP_TAG>"
|
||||
SRC_URI = "git://${JIHAD_REPO}/third_party/uxp;protocol=file;nobranch=1"
|
||||
SRCREV = "bda3141209f1e97571e6e0879d85c51bb1386df1"
|
||||
SRCREV = "f4fefca0d2177c706cfbee2c1d5d520be1896228"
|
||||
S = "${WORKDIR}/git"
|
||||
|
||||
# Modern C++14 toolchain (device-build R1) — the stock dylan/device gcc cannot build UXP.
|
||||
|
||||
@@ -86,6 +86,8 @@ modifications; the same changes are the commits of `jihad/uxp-RB_20261006`, one
|
||||
| `0061-security-a-certificate-error-is-not-TLS-intolerance-.patch` | `security/manager/ssl/nsNSSIOLayer.cpp` | T-534: a SEC_ERROR_* / mozilla::pkix / bad-cert-domain failure is never retried at a lower TLS version (the retry tripped a TLS 1.3 server's downgrade sentinel and a revoked certificate read "SSL_ERROR_RX_MALFORMED_SERVER_HELLO") |
|
||||
| `0062-layout-the-GPU-path-s-root-displayport-base-is-the-d.patch` | `layout/base/nsLayoutUtils.{h,cpp}`, `layout/generic/nsGfxScrollFrame.cpp` | T-527: on the GPU path the root's displayport base set by the daemon (0059's `jihad_layout_set_displayport2`) is kept by the paint (`nsLayoutUtils::JihadKeepsDisplayPortBase`): `nsLayoutUtils::PaintFrame`'s `DecideScrollableLayer` replaced it on every paint with the composition size at the origin in CSS px, and a zoomed-in card's first paint without margins covered 660 of the 531..861 CSS px shown (`docs/rounds/t527-2026-10-25/notes.txt`) |
|
||||
| `0063-gpu-compositor-a-tall-band-surface-for-a-change-that.patch` | `gfx/gl/GLContextEGL.h`, `gfx/gl/GLContextProviderEGL.cpp`, `gfx/layers/ipc/CompositorBridgeParent.cpp`, `gfx/layers/opengl/CompositorOGL.{h,cpp}` | T-527 (R8): a change that does not fit the 256-row band surface takes a second, 512-row band surface (`JIHAD_GPU_BAND_TALL`, its own pbuffer and target) instead of the frame-sized target; frames are packed for the band surface first. The 480 px WebGL cube's job 15-30 ms where it took ~45 |
|
||||
| `0064-widget-a-GPU-path-layer-paint-with-nothing-pending-i.patch` | `widget/PuppetWidget.{h,cpp}`, `layout/base/nsLayoutUtils.cpp` | T-527: the daemon's layer paint returns at once after the first when nothing is pending (no invalid region, no paint task, no view-manager flush owed): the display list is not built again for nothing (`JIHAD_GPU_PAINT_ALWAYS=1`: every time); a moved displayport base schedules the root's paint (the margins' comparison saw no change). Desktop Wikipedia's pan 23.6 fps and the long page's 33.1, verify 0 rows wrong: the compositor thread stays the bound |
|
||||
| `0065-gpu-compositor-a-band-surface-that-cannot-be-made-at.patch` | `gfx/layers/opengl/CompositorOGL.{h,cpp}` | T-527 (review): a band surface or its target that cannot be made at a width is not made again every band frame (a line each into /var); the frame's own surface does the pass |
|
||||
| `0054-gpu-compositor-kept-rects-all-saved-before-any-is-wr.patch` | `gfx/layers/opengl/CompositorOGL.cpp`, `widget/PuppetWidget.cpp`, `dom/canvas/WebGLContext.cpp`, `widget/headless/GfxInfo.cpp` | T-517/T-511 review: a window-moved shift saves every kept rect before writing any; `jihad_offscreen_gpu_given_up()` / `jihad_gpu_compositor_on()`, so WebGL makes no EGL contexts once the daemon has given the GPU path up |
|
||||
| `0053-gpu-compositor-a-shift-that-is-the-daemon-s-window-m.patch` | `gfx/layers/opengl/CompositorOGL.{h,cpp}`, `widget/PuppetWidget.cpp` | T-517: a compose job's shift may be the daemon's move of the frame's window in its segment (flag 8): the rows are in place, only the kept rects are copied from where they were |
|
||||
| `0052-gpu-compositor-the-frame-s-bands-read-as-one-column-.patch` | `widget/PuppetWidget.{h,cpp}`, `gfx/layers/ipc/CompositorBridgeParent.cpp`, `gfx/layers/opengl/CompositorOGL.{h,cpp}` | T-511: a compose job may give its bands' stale columns (flag 4); with no shift, kept rows or fixed columns, the bands are read as the one column the change and they span when it is under three quarters of the width; the poll reports the change's columns (twelve ints); `JIHAD_GPU_NO_COLUMN_READ=1` reads whole rows |
|
||||
|
||||
Vendored
+1
-1
Submodule third_party/uxp updated: bda3141209...f4fefca0d2.
Reference in new issue
Block a user