Phase 0: browser X11-overlay inventory + mpv reference cell + tooling installs
Source-level verdict: no browser in the matrix has a code path to hand NV12 to the X server for plane scanout. Chromium ozone-x11 wires StubOverlayManager (ozone_platform_x11.cc:262); Brave 147 + chromium-fourier 149 inherit unchanged. Firefox WindowSurfaceX11 is RGB-only. The campaign's load-bearing hypothesis is structurally weakened — what the X11 cells will measure for browsers is KWin's per-frame RGB-recomposite cost, not the original "force-GL-composite of NV12" framing. mpv --vo=xv becomes the matrix's only direct test of the operator-supplied mechanism. Matrix updated: 12 cells -> 16 cells (+8 mpv VO sub-points). revert.log entries 1-5 capture all package + per-user state mutations from this turn (measurement tools, openbox, XFCE + xfwm4-no-comp pre-seed, firefox + AUR xtrace, XFCE rotation + touchscreen mapping); single SSH-driveable revert chain returns ohm to its pre-campaign 1169-package state. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,9 +24,13 @@ forced GL-composite. **The campaign's load-bearing hypothesis
|
||||
is that this plane-allocation freedom translates into
|
||||
measurable browser-video speedup.**
|
||||
|
||||
The matrix is 3 browsers × 2 decode paths × 2 sessions = 12
|
||||
cells (some N/A where libva isn't supported). See
|
||||
`phase0_findings.md` for the full table.
|
||||
The matrix is (3 browsers + mpv 0.41 as a reference X11-overlay
|
||||
client) × 2 decode paths × 2 sessions = 16 cells (some N/A
|
||||
where libva isn't supported). The mpv cells are run twice each
|
||||
— once with `--vo=xv` (legacy XVideo overlay) and once with
|
||||
`--vo=gpu --gpu-context=x11` (modern DRI3 + XPresent + Mesa GL).
|
||||
See `phase0_findings.md` § "Experimental matrix" for the full
|
||||
table and the rationale for mpv as reference baseline.
|
||||
|
||||
## Campaign-contained data discipline
|
||||
|
||||
|
||||
@@ -0,0 +1,507 @@
|
||||
# Phase 0 — Browser X11-overlay-path inventory
|
||||
|
||||
**Date:** 2026-05-03
|
||||
**Scope:** answer worklist.md item *"Browser X11-overlay-path
|
||||
inventory"* — for each of Brave 147, chromium-fourier 149,
|
||||
Firefox 150, and the mpv 0.41 reference client, determine
|
||||
**whether a code path exists under X11 to request
|
||||
hardware-overlay scanout of NV12 video buffers**, vs always
|
||||
GL-compositing internally to RGB before X11 presentation.
|
||||
|
||||
**Method:** source-level inspection. Local Firefox 149 source
|
||||
tree (acquired by the predecessor as `firefox-fourier-work/`)
|
||||
read directly. Chromium 147 source acquired from the
|
||||
`chromium-builder` LXD CT on boltzmann via the his subagent —
|
||||
13 files, 180 KB, copied into
|
||||
`phase0_evidence/chromium_ozone_x11_2026-05-03/` with full
|
||||
provenance in that subtree's `README.txt`. mpv inspected via
|
||||
upstream docs + its installed binary's `--vo=help`. **Runtime
|
||||
engagement (does the path actually fire at playback time?) is
|
||||
NOT covered here** — that's a separate, attended-launch
|
||||
follow-up; design sketch at the end of this doc.
|
||||
|
||||
## TL;DR
|
||||
|
||||
| Client | X11 overlay path exists in code? | Runtime-engaged today? | Notes |
|
||||
|---|---|---|---|
|
||||
| Brave 147 | **No.** ozone-x11 uses `StubOverlayManager`. | N/A | upstream Chromium 147 + Brave UI patches; Ozone unchanged |
|
||||
| chromium-fourier 149 | **No.** Same as upstream Chromium 149. | N/A | local patches target decode side only; Ozone unchanged |
|
||||
| Firefox 150 | **No.** `WindowSurfaceX11{,Image,SHM}` are RGB-only. | N/A | gfx/webrender_bindings has DComp (Windows), no Linux equivalent |
|
||||
| mpv 0.41 `--vo=xv` | **Yes (XVideo legacy path).** | unknown | only path in this matrix that *could* engage a hardware plane via X server's Xv adapter |
|
||||
| mpv 0.41 `--vo=gpu --gpu-context=x11` | **No.** GL composite, identical plumbing to browsers. | N/A | DRI3 + XPresent of an RGB GL-composited framebuffer, same as Chromium/Firefox under X11 |
|
||||
|
||||
**Headline finding:** every Blink-based browser (Brave,
|
||||
chromium-fourier) and Firefox under stock X11 ozone *cannot* hand
|
||||
an NV12 dmabuf to the X server for hardware-overlay scanout;
|
||||
they always GL-composite NV12 → RGB in their own GPU process and
|
||||
then present an RGB framebuffer to the X server.
|
||||
|
||||
This **structurally weakens** the campaign's load-bearing
|
||||
hypothesis (`README.md` § 1: *"the campaign's load-bearing
|
||||
hypothesis is that this plane-allocation freedom translates into
|
||||
measurable browser-video speedup"*). The freedom *exists* at the
|
||||
DRM/Xorg layer — Plane 39 NV12 LINEAR is reachable to X11
|
||||
clients in principle — but **no shipping browser ever tries to
|
||||
exercise it** under X11. What the matrix's X11 cells will
|
||||
actually measure for browsers is the cost of the GL composite
|
||||
running in the *browser's* GPU process vs the GL composite
|
||||
running in *kwin_wayland*'s process — an interesting question,
|
||||
but a different one from the stated mechanism.
|
||||
|
||||
The mpv `--vo=xv` cell becomes the matrix's most important
|
||||
single data point: it's the only client in the campaign that
|
||||
can *attempt* to engage an X11 hardware-overlay plane directly.
|
||||
A clean `--vo=xv` engagement establishes that the X11
|
||||
hardware-overlay path *works on this hardware*; absence
|
||||
establishes it doesn't even exist on rockchip-drm + Panfrost +
|
||||
modesetting Xorg.
|
||||
|
||||
---
|
||||
|
||||
## Chromium ozone-x11: `StubOverlayManager` (decisive)
|
||||
|
||||
Source provenance:
|
||||
`phase0_evidence/chromium_ozone_x11_2026-05-03/`
|
||||
(Chromium 147.0.7727.116 from `chromium-builder` LXD CT on
|
||||
boltzmann; tarball mtime 2026-04-25).
|
||||
|
||||
### The wiring
|
||||
|
||||
`ui/ozone/platform/x11/ozone_platform_x11.cc:262`:
|
||||
|
||||
```cpp
|
||||
overlay_manager_ = std::make_unique<StubOverlayManager>();
|
||||
```
|
||||
|
||||
`StubOverlayManager` (in `ui/ozone/common/stub_overlay_manager.h`)
|
||||
implements the `OverlayManagerOzone` interface as a no-op —
|
||||
its `CreateOverlayCandidates()` returns no candidates. Whatever
|
||||
chromium's `OverlayProcessor` asks the X11 backend, the answer
|
||||
is "no overlay possible here" and the regular GL-composite path
|
||||
runs.
|
||||
|
||||
**Contrast with Wayland**
|
||||
(`ui/ozone/platform/wayland/ozone_platform_wayland.cc:330`):
|
||||
|
||||
```cpp
|
||||
std::make_unique<WaylandOverlayManager>(buffer_manager_.get());
|
||||
```
|
||||
|
||||
A real `WaylandOverlayManager` backed by the
|
||||
`WaylandBufferManagerHost`. This is the path the predecessor
|
||||
campaign `kwin_overlay_subsurface` was investigating — the route
|
||||
where Chromium emits `wp_subsurface` overlay candidates that
|
||||
KWin Wayland may or may not promote to scanout planes (and
|
||||
historically didn't, hence the predecessor's Phase 8 closure).
|
||||
|
||||
### What the X11 directory does NOT contain
|
||||
|
||||
Directory listing of `ui/ozone/platform/x11/` (from `README.txt`)
|
||||
filtered for relevance:
|
||||
|
||||
```
|
||||
$ ls ui/ozone/platform/x11/ | grep -iE 'overlay|buffer.*manager|dmabuf|present'
|
||||
x11_window_manager.cc
|
||||
x11_window_manager.h
|
||||
```
|
||||
|
||||
`x11_window_manager` is the WM-events bookkeeping class
|
||||
(focus/raise/restack), unrelated to overlays. **There is no
|
||||
`x11_overlay_manager.cc`, no `x11_buffer_manager_host.cc`, no
|
||||
`x11_dmabuf_*.cc`, and no `x11_present_*.cc`** — files that
|
||||
exist on the Wayland side. The X11 backend has no machinery
|
||||
to track overlay candidates, no buffer-manager IPC, no
|
||||
dmabuf-feedback handling, and no Present-extension protocol
|
||||
support.
|
||||
|
||||
### What the X11 directory DOES contain — and why it's not enough
|
||||
|
||||
`x11_surface_factory.cc:40-43`:
|
||||
|
||||
```cpp
|
||||
// Native pixmaps are first imported as X11 pixmaps using DRI3
|
||||
// and then into EGL.
|
||||
```
|
||||
|
||||
DRI3 IS used by ozone-x11. But the path is:
|
||||
|
||||
1. GPU process gets an NV12 dmabuf from the video decoder
|
||||
(VAAPI / V4L2VideoDecoder).
|
||||
2. `X11SurfaceFactory::CreateNativePixmap()` wraps it as a
|
||||
`gfx::NativePixmapDmaBuf`.
|
||||
3. The dmabuf is imported either directly via
|
||||
`EGL_EXT_image_dma_buf_import` or, as a fallback, by
|
||||
creating an X11 Pixmap via DRI3 and binding that as an
|
||||
EGL image.
|
||||
4. **Either way, the resulting EGL image is sampled by
|
||||
Chromium's GL compositor** to render the WebRender output.
|
||||
5. The browser's final RGB framebuffer is presented to the X
|
||||
server via `glXSwapBuffers` (or equivalent EGL swap).
|
||||
|
||||
This is the GL-composite path — the same path browsers use on
|
||||
every X11 + GL-context combo since the late 2000s. The dmabuf
|
||||
is consumed by the GPU process, not handed to the X server for
|
||||
plane scanout. Plane 39 (the only NV12-LINEAR-capable plane on
|
||||
rockchip-drm) is programmed by the X server at scanout time
|
||||
with the **RGB** browser framebuffer, not the NV12 video buffer.
|
||||
|
||||
### What `chrome://gpu` would show for video acceleration
|
||||
|
||||
Independent of decode-side acceleration, the
|
||||
*Hardware-accelerated video decode* line in `chrome://gpu` only
|
||||
reports decoder status, not overlay status. `chrome://gpu`
|
||||
doesn't have a "Hardware video overlay" line for Linux/X11 —
|
||||
that line is Windows-only (`DCOMPSurface` on the DirectComposition
|
||||
swap chain). The absence of such a line in chrome://gpu under
|
||||
Linux/X11 is itself a sign: there's no overlay surface concept
|
||||
in this backend.
|
||||
|
||||
### Brave 147 verdict
|
||||
|
||||
Brave is a Chromium fork. Its tree adds ~50 patches on top of
|
||||
upstream Chromium covering UI/Shields/Wallet/IPFS/Tor/etc. None
|
||||
of Brave's diff touches `ui/ozone/platform/x11/`, the
|
||||
`OverlayProcessor`, or the GPU buffer pipeline. **Brave 147
|
||||
under X11 has the identical "StubOverlayManager → GL composite"
|
||||
behavior as upstream Chromium 147.**
|
||||
|
||||
### chromium-fourier 149 verdict
|
||||
|
||||
`marfrit-packages/arch/chromium-fourier/STUDY.md` documents the
|
||||
patch set:
|
||||
|
||||
- Patch 1: bypass `media/gpu/chromeos/video_decoder_pipeline.cc`
|
||||
on Linux non-ChromeOS so VaapiVideoDecoder gets used.
|
||||
- Patch 2: V4L2VideoDecoder factory un-gating for non-ChromeOS.
|
||||
- Patch 3 (cosmetic): default `LIBVA_DRIVER_NAME=v4l2_request`.
|
||||
- `nv12-external-oes-on-modifier-external-only.patch`: EGL
|
||||
import quirk for NV12 modifier-external dmabufs.
|
||||
- `wayland-allow-direct-egl-gles2.patch`: Wayland-specific.
|
||||
|
||||
**All decode-side. Zero changes to `ui/ozone/platform/x11/`,
|
||||
zero changes to the OverlayProcessor.** chromium-fourier 149's
|
||||
X11 behavior is identical to upstream Chromium 149's, which is
|
||||
in turn identical in Ozone shape to 147 (the
|
||||
`StubOverlayManager` wiring dates to ~2019 and hasn't moved).
|
||||
|
||||
---
|
||||
|
||||
## Firefox 150 widget/gtk: RGB-only X11 surfaces (decisive)
|
||||
|
||||
Source: `firefox-fourier-work/firefox-149.0/`. Firefox 149 ≈ 150
|
||||
on the X11-surface code path; this layer hasn't changed
|
||||
materially in 5+ years.
|
||||
|
||||
### The X11 surface implementations
|
||||
|
||||
Firefox's X11 backend lives at `widget/gtk/WindowSurfaceX11*`:
|
||||
|
||||
- `WindowSurfaceX11.cpp` — abstract base.
|
||||
- `WindowSurfaceX11Image.cpp` — XImage-based (slow legacy path).
|
||||
- `WindowSurfaceX11SHM.cpp` — XShm-based (shared-memory pixmap).
|
||||
|
||||
`WindowSurfaceX11.cpp::GetVisualFormat()` enumerates exactly
|
||||
three pixel formats:
|
||||
|
||||
```cpp
|
||||
case 32: return gfx::SurfaceFormat::B8G8R8A8;
|
||||
case 24: return gfx::SurfaceFormat::B8G8R8X8;
|
||||
case 16: return gfx::SurfaceFormat::R5G6B5_UINT16;
|
||||
```
|
||||
|
||||
All RGB. No NV12. No YUV. No dmabuf. Final pixel buffer is RGB
|
||||
before reaching X.
|
||||
|
||||
A grep across all
|
||||
`widget/gtk/WindowSurfaceX11*.{cpp,h}` files for any of
|
||||
`dmabuf|DMABuf|NV12|YUV|hardware.*overlay|Plane|XPresent|DRI3`
|
||||
returns **zero matches**. Firefox's X11 presentation path is
|
||||
strictly software-RGB-pixmap → X.
|
||||
|
||||
### Why the dmabuf code in widget/gtk/ doesn't apply
|
||||
|
||||
Files like `DMABufSurface.cpp`, `DMABufBuffer.cpp`,
|
||||
`WaylandSurface.cpp` exist and are reachable on Linux, but
|
||||
their use is:
|
||||
|
||||
- Wayland-side: produce/consume `wl_buffer` dmabufs for the
|
||||
client→compositor handoff via `zwp_linux_dmabuf_v1`.
|
||||
- VAAPI-decode-side: import a hardware-decoded NV12 dmabuf as
|
||||
an EGL image so Firefox's WebRender can sample it as a
|
||||
texture.
|
||||
|
||||
In the second case (VAAPI under X11), the dmabuf is consumed by
|
||||
Firefox's own GPU process for compositing. The composited
|
||||
output is then handed to `WindowSurfaceX11SHM` as RGB —
|
||||
identical situation to Chromium.
|
||||
|
||||
### Mozilla's `gfx.x11-egl.force-enabled` pref
|
||||
|
||||
`modules/libpref/init/StaticPrefList.yaml`:
|
||||
|
||||
```yaml
|
||||
- name: gfx.x11-egl.force-enabled
|
||||
type: bool
|
||||
value: false
|
||||
mirror: once
|
||||
# Whether to force using EGL over GLX.
|
||||
```
|
||||
|
||||
This forces Firefox to use **EGL over GLX** for its GL context
|
||||
under X11 (better dmabuf import support since EGL has
|
||||
`EGL_EXT_image_dma_buf_import`, GLX doesn't). It changes the
|
||||
GPU-process composite-input plumbing, **not** the
|
||||
WindowSurfaceX11 presentation plumbing. The output to X is
|
||||
still RGB.
|
||||
|
||||
### Mozilla's hardware-overlay code is Windows-only
|
||||
|
||||
The only files in Firefox 149 source matching
|
||||
`hardware.*overlay`:
|
||||
|
||||
- `gfx/webrender_bindings/DCLayerTree.cpp` —
|
||||
DirectComposition layer tree (Windows).
|
||||
- `gfx/webrender_bindings/RenderCompositorANGLE.cpp` —
|
||||
ANGLE composition (Windows).
|
||||
- `gfx/config/gfxFeature.h` — feature-flag enum.
|
||||
- `gfx/thebes/gfxPlatform.cpp` — feature-flag plumbing.
|
||||
|
||||
There is no Linux/X11 hardware-overlay equivalent. Mozilla's
|
||||
`MOZ_X11_EGL` env var (sometimes mentioned in forum threads as
|
||||
a "force X11 hardware overlay" toggle) is just a synonym for
|
||||
`gfx.x11-egl.force-enabled` — same EGL-vs-GLX scope, no
|
||||
overlay-scanout effect.
|
||||
|
||||
### Firefox 150 verdict
|
||||
|
||||
**No X11 hardware-overlay path. Firefox under X11 always
|
||||
GL-composites NV12 → RGB internally and presents RGB to the X
|
||||
server.** Same architectural shape as Chromium ozone-x11.
|
||||
|
||||
---
|
||||
|
||||
## mpv 0.41: the only client with a path that *could* engage X11 hardware overlay
|
||||
|
||||
mpv installed: `mpv 1:0.41.0-3` with `libplacebo v7.360.1`
|
||||
(per `02_x11_paths.txt`).
|
||||
|
||||
### `--vo=xv` — the legacy XVideo overlay path
|
||||
|
||||
XVideo (`Xv`) is an X protocol extension dating to the late
|
||||
1990s, designed precisely for hardware video overlays: the
|
||||
client hands the X server a YUV image; the X server programs a
|
||||
hardware video plane (where available) to scanout that image,
|
||||
hardware-blended with the rest of the desktop. On modesetting
|
||||
Xorg driver + a DRM driver that exposes a YUV-capable plane,
|
||||
the X server's XVideo adapter wires through DRI2/DRI3 to the
|
||||
DRM plane allocator, and YUV image goes onto a hardware plane.
|
||||
|
||||
`xdpyinfo` on ohm confirms XVideo extension is initialized on
|
||||
the running X server (`03_xprotocol_extensions.txt:50`,
|
||||
`Xorg.0.log` line 96-97 in `01_live_session.txt`).
|
||||
|
||||
**Whether modesetting + rockchip-drm actually wires XVideo to
|
||||
Plane 39 is the empirical question.** Possible outcomes:
|
||||
|
||||
- mpv `--vo=xv` programs Plane 39 NV12 → X11 hardware-overlay
|
||||
path is reachable on this hardware, and the campaign has its
|
||||
reference baseline.
|
||||
- mpv `--vo=xv` falls back to software YUV→RGB conversion in
|
||||
the X server (the modesetting "shadow Xv adapter" path) →
|
||||
no hardware-overlay path on this hardware, regardless of
|
||||
client.
|
||||
|
||||
A 5-second mpv `--vo=xv` run under a non-compositing WM, with
|
||||
`drm_info` snapshots taken before / during / after, will
|
||||
unambiguously answer this. *Design at the end of this doc.*
|
||||
|
||||
### `--vo=gpu --gpu-context=x11` — modern Mesa GL path
|
||||
|
||||
mpv's modern GL VO uses the same plumbing as the browsers:
|
||||
DRI3 + XPresent + Mesa GL. `--hwdec=auto` or
|
||||
`--hwdec=v4l2request-copy` decodes via libva → NV12 dmabuf →
|
||||
imports as EGL image → mpv samples it in libplacebo's GL
|
||||
compositor → glXSwapBuffers RGB to X.
|
||||
|
||||
This is **not** an X11 hardware-overlay path. It's the same
|
||||
client-side GL composite that browsers do. Useful as a
|
||||
control: if `--vo=gpu` is markedly slower than `--vo=xv` on
|
||||
the same machine + same workload, the delta is the
|
||||
hardware-overlay-vs-GL-composite gap — which is exactly the
|
||||
quantity the campaign wants to measure.
|
||||
|
||||
### `--vo=drm` — bypass X entirely (NOT in scope)
|
||||
|
||||
mpv has a `--vo=drm` VO that talks directly to KMS, bypassing
|
||||
X. The KWIN_PIVOT.md from chromium-fourier already reports
|
||||
0.7 % drops with mpv `--vo=drm --hwdec=v4l2request` under no
|
||||
compositor — strong evidence the underlying hardware path
|
||||
(decode + DRM scanout) is healthy on this stack. But `--vo=drm`
|
||||
isn't an X11 path; it doesn't tell us anything about whether
|
||||
the X server can do the same plane assignment for a windowed
|
||||
client. **Not added to the matrix.** Useful as a "this is the
|
||||
hardware ceiling" reference outside the matrix.
|
||||
|
||||
---
|
||||
|
||||
## Implications for the matrix
|
||||
|
||||
### What the X11 cells of the matrix actually measure for the three browsers
|
||||
|
||||
Given the StubOverlayManager / WindowSurfaceX11-RGB-only
|
||||
findings, the X11-cell value chain for browsers is:
|
||||
|
||||
1. Browser GPU process decodes video → NV12 dmabuf.
|
||||
2. NV12 dmabuf imported as EGL image.
|
||||
3. **Browser GPU process GL-composites NV12 → RGB** in its own
|
||||
GL context (via libplacebo equivalents in Chromium's WebRender
|
||||
or Firefox's WebRender).
|
||||
4. RGB framebuffer presented via DRI3 + XPresent to the X
|
||||
server.
|
||||
5. **X server's plane allocator schedules the RGB pixmap on
|
||||
Plane 39** (since on rockchip-drm Plane 39 is the only one
|
||||
that can scan out the browser-window-sized buffer; Plane 45
|
||||
doesn't accept RGB AFBC at the resolutions involved either,
|
||||
though it does accept RGB LINEAR — to be confirmed).
|
||||
|
||||
Compare to Wayland-with-KWin cell:
|
||||
|
||||
1. Browser GPU process decodes → NV12 dmabuf.
|
||||
2. NV12 dmabuf imported as EGL image (or sent via wp_subsurface
|
||||
if the browser engages that route — in practice, per the
|
||||
predecessor campaign, browsers don't engage wp_subsurface for
|
||||
the test page).
|
||||
3. **Browser GPU process GL-composites NV12 → RGB** in its own
|
||||
GL context (same as X11 cell).
|
||||
4. RGB framebuffer dispatched to KWin via wl_surface attach.
|
||||
5. **KWin GL-composites the browser's RGB surface** with the
|
||||
rest of the desktop (the wallpaper, panels, etc.).
|
||||
6. KWin's merged RGB framebuffer goes to Plane 39.
|
||||
|
||||
The structural delta the matrix's X11 vs Wayland cells will
|
||||
actually measure for browsers is therefore **the cost of step
|
||||
5 in the Wayland flow** — KWin's per-frame compositing of
|
||||
already-RGB browser surfaces onto its merged framebuffer. The
|
||||
NV12-GL-composite (step 3) happens in *both* sessions, in the
|
||||
*browser's* GPU process. The campaign's hypothesised "force-GL-
|
||||
composite of every NV12 video buffer" is performed by the
|
||||
browser regardless of session, not by KWin.
|
||||
|
||||
This **does not invalidate the campaign**. KWin's per-frame RGB
|
||||
composite is still measurable and the predecessor's
|
||||
`kwin_wayland %CPU at steady-state ~36 %` is suggestive that
|
||||
this overhead is real. But the magnitude and the mechanism are
|
||||
different from the original framing.
|
||||
|
||||
### Where the original "plane allocation freedom" hypothesis still applies
|
||||
|
||||
For the **mpv `--vo=xv`** cell — and ONLY that cell — the
|
||||
client genuinely tries to hand NV12 to the X server for
|
||||
scanout. Under without-KWin (X11 + non-compositing WM), the
|
||||
X server is free to put that NV12 buffer on Plane 39 and
|
||||
the desktop on Plane 45 — exactly the campaign's mechanism,
|
||||
realised. Under Wayland-with-KWin there is no equivalent path
|
||||
at all (XVideo isn't a Wayland concept; XWayland would route
|
||||
through KWin and lose any scanout opportunity). So the mpv-xv
|
||||
row of the matrix is the **direct test** of the
|
||||
operator-supplied mechanism — and likely the only one that
|
||||
can produce a positive answer.
|
||||
|
||||
### Recommended Phase 1 framing
|
||||
|
||||
The campaign's research question stays valid but its
|
||||
sub-questions sharpen:
|
||||
|
||||
- **Q1 (mpv `--vo=xv`):** does X11+non-compositing WM on
|
||||
rockchip-drm-PineTab2 actually engage hardware-overlay
|
||||
scanout for an NV12 client? (matrix cells `C-X-mpv-sw` and
|
||||
`C-X-mpv-hw` with `--vo=xv`)
|
||||
- **Q2 (browsers):** given that browsers always GL-composite
|
||||
to RGB before presentation, does removing KWin from the
|
||||
display path reduce the per-frame RGB-composite cost enough
|
||||
to matter for video fps / drops? (the existing browser
|
||||
cells, just with their interpretation tightened)
|
||||
- **Q3 (mpv `--vo=gpu`):** is the GL-composite cost in mpv's
|
||||
GPU process comparable to the browsers' GL-composite cost?
|
||||
(i.e., is the browsers' overhead the GL-composite itself, or
|
||||
something extra browsers do around it?)
|
||||
|
||||
A clean Q1 positive (mpv-xv hits Plane 39) plus a marginal Q2
|
||||
(browsers don't speed up much without KWin) would be the
|
||||
"X11 path is fast, but browsers leave it on the table"
|
||||
verdict the campaign already named as a possible outcome
|
||||
shape.
|
||||
|
||||
A Q1 negative (mpv-xv falls back to RGB anyway) would mean
|
||||
the campaign's mechanism is structurally absent on this
|
||||
hardware, regardless of session. In that case the matrix
|
||||
collapses to "what's the per-frame KWin overhead?" — a
|
||||
scoping the predecessor `kwin_overlay_subsurface` already
|
||||
asked at the protocol level and got an answer to.
|
||||
|
||||
---
|
||||
|
||||
## Open: runtime engagement check (deferred, attended-launch)
|
||||
|
||||
The source-level inventory above answers "does the path
|
||||
*exist* in the code". To answer "is the path *engaged at
|
||||
runtime* for THIS hardware × THIS Mesa × THIS X server", a
|
||||
per-client probe is needed. This is the right thing to do at
|
||||
**Phase 1 binding-cell-design time**, not at Phase 0
|
||||
inventory time.
|
||||
|
||||
### Probe sketch (for later)
|
||||
|
||||
For each client × X11-session combination, around a
|
||||
short (10-30 s) test-video playback:
|
||||
|
||||
1. Pre-state: `drm_info | grep -A 20 'Plane 39'` and
|
||||
`drm_info | grep -A 20 'Plane 45'` — capture plane state
|
||||
before launch.
|
||||
2. Launch the client (operator action: open the browser to
|
||||
`brave_drops_test.html` or run mpv on a known short video).
|
||||
3. Capture for 10 s mid-playback:
|
||||
- `x11trace -k -d :0 -o /tmp/x11trace.<client>.log` for
|
||||
~3 s (the AUR `x11trace` binary at `/usr/bin/x11trace`
|
||||
installed in `revert.log` entry 3) — to see what X
|
||||
protocol requests the client is issuing per frame.
|
||||
- `drm_info` snapshot — to see which planes are now
|
||||
programmed and with what FOURCC/modifier.
|
||||
- `chrome://gpu` page text via DevTools / about:support
|
||||
copy — for the browser's own self-report.
|
||||
4. Post-state `drm_info`.
|
||||
5. Diff: a positive engagement looks like **Plane 39
|
||||
programmed with `NV12` FOURCC during step 3**; a negative
|
||||
engagement is **Plane 39 programmed with `XR24` / `AR24`
|
||||
RGB FOURCC for the entire window**.
|
||||
|
||||
The probe is shaped like a Phase 1 measurement protocol but
|
||||
uses a much shorter window and isn't recording per-frame
|
||||
metrics — it's just "does NV12 ever reach a hardware plane?"
|
||||
binary outcome per cell.
|
||||
|
||||
### Why deferred
|
||||
|
||||
Running the probe productively requires:
|
||||
- A non-compositing-WM session active (entry-1 openbox or
|
||||
entry-2 XFCE-no-comp) — operator session switch needed.
|
||||
- An operator at the keyboard to start each client.
|
||||
- A short test video file on ohm at a known path — minor
|
||||
prep, not done in this campaign yet.
|
||||
- The matrix cells finalised with their browser flags
|
||||
(`--enable-features=...`, `MOZ_X11_EGL=1`, etc.) so the
|
||||
probe gives the right answer for the conditions Phase 1
|
||||
will measure.
|
||||
|
||||
None of those is a blocker — but folding the probe into
|
||||
Phase 1's first measurement rep (where the operator is
|
||||
already at the keyboard launching browsers and a test video
|
||||
is being played for fps-counting purposes) is more efficient
|
||||
than running it standalone in Phase 0.
|
||||
|
||||
---
|
||||
|
||||
## Worklist update
|
||||
|
||||
`worklist.md` item *"NEW: Browser X11-overlay-path inventory"*
|
||||
should flip to `[x]` with a pointer to this file.
|
||||
@@ -0,0 +1,70 @@
|
||||
# Source provenance
|
||||
Host: boltzmann
|
||||
Container: chromium-builder (LXD)
|
||||
Path inside CT: /build/chromium/src
|
||||
Tarball mtime: 2026-04-25 (chromium-147.0.7727.116.tar.xz)
|
||||
Fetched: 2026-05-03
|
||||
Reach recipe: ssh boltzmann "sudo lxc exec chromium-builder -- cat /build/chromium/src/<path>"
|
||||
|
||||
## Chromium VERSION + ui/ozone/platform/x11/ listing
|
||||
|
||||
MAJOR=147
|
||||
MINOR=0
|
||||
BUILD=7727
|
||||
PATCH=116
|
||||
---
|
||||
total 384
|
||||
drwxr-xr-x 1 builder builder 2298 Apr 21 17:50 .
|
||||
drwxr-xr-x 1 builder builder 78 Apr 21 17:50 ..
|
||||
-rw-r--r-- 1 builder builder 5298 Apr 21 17:50 BUILD.gn
|
||||
-rw-r--r-- 1 builder builder 360 Apr 21 17:50 DEPS
|
||||
-rw-r--r-- 1 builder builder 89 Apr 21 17:50 OWNERS
|
||||
-rw-r--r-- 1 builder builder 2841 Apr 21 17:50 atk_event_conversion.cc
|
||||
-rw-r--r-- 1 builder builder 1033 Apr 21 17:50 atk_event_conversion.h
|
||||
-rw-r--r-- 1 builder builder 440 Apr 21 17:50 client_native_pixmap_factory_x11.cc
|
||||
-rw-r--r-- 1 builder builder 556 Apr 21 17:50 client_native_pixmap_factory_x11.h
|
||||
-rw-r--r-- 1 builder builder 1255 Apr 21 17:50 gl_egl_utility_x11.cc
|
||||
-rw-r--r-- 1 builder builder 1133 Apr 21 17:50 gl_egl_utility_x11.h
|
||||
-rw-r--r-- 1 builder builder 2469 Apr 21 17:50 gl_surface_egl_readback_x11.cc
|
||||
-rw-r--r-- 1 builder builder 1280 Apr 21 17:50 gl_surface_egl_readback_x11.h
|
||||
-rw-r--r-- 1 builder builder 1218 Apr 21 17:50 hit_test_x11.cc
|
||||
-rw-r--r-- 1 builder builder 508 Apr 21 17:50 hit_test_x11.h
|
||||
-rw-r--r-- 1 builder builder 1198 Apr 21 17:50 linux_ui_delegate_x11.cc
|
||||
-rw-r--r-- 1 builder builder 894 Apr 21 17:50 linux_ui_delegate_x11.h
|
||||
-rw-r--r-- 1 builder builder 8235 Apr 21 17:50 native_pixmap_egl_x11_binding.cc
|
||||
-rw-r--r-- 1 builder builder 1553 Apr 21 17:50 native_pixmap_egl_x11_binding.h
|
||||
-rw-r--r-- 1 builder builder 1703 Apr 21 17:50 os_exchange_data_provider_x11.cc
|
||||
-rw-r--r-- 1 builder builder 1726 Apr 21 17:50 os_exchange_data_provider_x11.h
|
||||
-rw-r--r-- 1 builder builder 13470 Apr 21 17:50 ozone_platform_x11.cc
|
||||
-rw-r--r-- 1 builder builder 458 Apr 21 17:50 ozone_platform_x11.h
|
||||
drwxr-xr-x 1 builder builder 366 Apr 21 17:50 test
|
||||
-rw-r--r-- 1 builder builder 5791 Apr 21 17:50 vulkan_implementation_x11.cc
|
||||
-rw-r--r-- 1 builder builder 2126 Apr 21 17:50 vulkan_implementation_x11.h
|
||||
-rw-r--r-- 1 builder builder 4729 Apr 21 17:50 vulkan_surface_x11.cc
|
||||
-rw-r--r-- 1 builder builder 2797 Apr 21 17:50 vulkan_surface_x11.h
|
||||
-rw-r--r-- 1 builder builder 1686 Apr 21 17:50 x11_canvas_surface.cc
|
||||
-rw-r--r-- 1 builder builder 1962 Apr 21 17:50 x11_canvas_surface.h
|
||||
-rw-r--r-- 1 builder builder 3845 Apr 21 17:50 x11_clipboard_ozone.cc
|
||||
-rw-r--r-- 1 builder builder 2158 Apr 21 17:50 x11_clipboard_ozone.h
|
||||
-rw-r--r-- 1 builder builder 1885 Apr 21 17:50 x11_global_shortcut_listener_ozone.cc
|
||||
-rw-r--r-- 1 builder builder 1736 Apr 21 17:50 x11_global_shortcut_listener_ozone.h
|
||||
-rw-r--r-- 1 builder builder 4440 Apr 21 17:50 x11_keyboard_hook.cc
|
||||
-rw-r--r-- 1 builder builder 1600 Apr 21 17:50 x11_keyboard_hook.h
|
||||
-rw-r--r-- 1 builder builder 440 Apr 21 17:50 x11_menu_utils.cc
|
||||
-rw-r--r-- 1 builder builder 636 Apr 21 17:50 x11_menu_utils.h
|
||||
-rw-r--r-- 1 builder builder 2846 Apr 21 17:50 x11_ozone_ui_controls_test_helper.cc
|
||||
-rw-r--r-- 1 builder builder 2127 Apr 21 17:50 x11_ozone_ui_controls_test_helper.h
|
||||
-rw-r--r-- 1 builder builder 9385 Apr 21 17:50 x11_screen_ozone.cc
|
||||
-rw-r--r-- 1 builder builder 3750 Apr 21 17:50 x11_screen_ozone.h
|
||||
-rw-r--r-- 1 builder builder 18003 Apr 21 17:50 x11_screen_ozone_unittest.cc
|
||||
-rw-r--r-- 1 builder builder 8966 Apr 21 17:50 x11_surface_factory.cc
|
||||
-rw-r--r-- 1 builder builder 2267 Apr 21 17:50 x11_surface_factory.h
|
||||
-rw-r--r-- 1 builder builder 1191 Apr 21 17:50 x11_user_input_monitor.cc
|
||||
-rw-r--r-- 1 builder builder 1279 Apr 21 17:50 x11_user_input_monitor.h
|
||||
-rw-r--r-- 1 builder builder 876 Apr 21 17:50 x11_utils.cc
|
||||
-rw-r--r-- 1 builder builder 754 Apr 21 17:50 x11_utils.h
|
||||
-rw-r--r-- 1 builder builder 92805 Apr 21 17:50 x11_window.cc
|
||||
-rw-r--r-- 1 builder builder 19102 Apr 21 17:50 x11_window.h
|
||||
-rw-r--r-- 1 builder builder 3105 Apr 21 17:50 x11_window_manager.cc
|
||||
-rw-r--r-- 1 builder builder 1813 Apr 21 17:50 x11_window_manager.h
|
||||
-rw-r--r-- 1 builder builder 11141 Apr 21 17:50 x11_window_ozone_unittest.cc
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright 2015 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/common/stub_overlay_manager.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ui/ozone/public/overlay_candidates_ozone.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
StubOverlayManager::StubOverlayManager() {
|
||||
}
|
||||
|
||||
StubOverlayManager::~StubOverlayManager() {
|
||||
}
|
||||
|
||||
std::unique_ptr<OverlayCandidatesOzone>
|
||||
StubOverlayManager::CreateOverlayCandidates(gfx::AcceleratedWidget w) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2015 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_COMMON_STUB_OVERLAY_MANAGER_H_
|
||||
#define UI_OZONE_COMMON_STUB_OVERLAY_MANAGER_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ui/ozone/public/overlay_manager_ozone.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
class StubOverlayManager : public OverlayManagerOzone {
|
||||
public:
|
||||
StubOverlayManager();
|
||||
|
||||
StubOverlayManager(const StubOverlayManager&) = delete;
|
||||
StubOverlayManager& operator=(const StubOverlayManager&) = delete;
|
||||
|
||||
~StubOverlayManager() override;
|
||||
|
||||
// OverlayManagerOzone:
|
||||
std::unique_ptr<OverlayCandidatesOzone> CreateOverlayCandidates(
|
||||
gfx::AcceleratedWidget w) override;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_COMMON_STUB_OVERLAY_MANAGER_H_
|
||||
@@ -0,0 +1,204 @@
|
||||
# Copyright 2016 The Chromium Authors
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//build/config/chromeos/ui_mode.gni")
|
||||
import("//gpu/vulkan/features.gni")
|
||||
import("//ui/base/ui_features.gni")
|
||||
|
||||
visibility = [ "//ui/ozone/*" ]
|
||||
|
||||
assert(is_linux || is_chromeos)
|
||||
|
||||
source_set("x11") {
|
||||
sources = [
|
||||
"client_native_pixmap_factory_x11.cc",
|
||||
"client_native_pixmap_factory_x11.h",
|
||||
"gl_egl_utility_x11.cc",
|
||||
"gl_egl_utility_x11.h",
|
||||
"gl_surface_egl_readback_x11.cc",
|
||||
"gl_surface_egl_readback_x11.h",
|
||||
"hit_test_x11.cc",
|
||||
"hit_test_x11.h",
|
||||
"native_pixmap_egl_x11_binding.cc",
|
||||
"native_pixmap_egl_x11_binding.h",
|
||||
"os_exchange_data_provider_x11.cc",
|
||||
"os_exchange_data_provider_x11.h",
|
||||
"ozone_platform_x11.cc",
|
||||
"ozone_platform_x11.h",
|
||||
"x11_canvas_surface.cc",
|
||||
"x11_canvas_surface.h",
|
||||
"x11_clipboard_ozone.cc",
|
||||
"x11_clipboard_ozone.h",
|
||||
"x11_global_shortcut_listener_ozone.cc",
|
||||
"x11_global_shortcut_listener_ozone.h",
|
||||
"x11_keyboard_hook.cc",
|
||||
"x11_keyboard_hook.h",
|
||||
"x11_menu_utils.cc",
|
||||
"x11_menu_utils.h",
|
||||
"x11_screen_ozone.cc",
|
||||
"x11_screen_ozone.h",
|
||||
"x11_surface_factory.cc",
|
||||
"x11_surface_factory.h",
|
||||
"x11_user_input_monitor.cc",
|
||||
"x11_user_input_monitor.h",
|
||||
"x11_utils.cc",
|
||||
"x11_utils.h",
|
||||
"x11_window.cc",
|
||||
"x11_window.h",
|
||||
"x11_window_manager.cc",
|
||||
"x11_window_manager.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base",
|
||||
"//build:chromecast_buildflags",
|
||||
"//components/viz/common/resources:shared_image_format",
|
||||
"//gpu/vulkan:buildflags",
|
||||
"//net",
|
||||
"//skia",
|
||||
"//third_party/angle:includes",
|
||||
"//ui/base",
|
||||
"//ui/base:buildflags",
|
||||
"//ui/base:data_exchange",
|
||||
"//ui/base:hit_test",
|
||||
"//ui/base:wm_role_names",
|
||||
"//ui/base/clipboard:clipboard_types",
|
||||
"//ui/base/cursor",
|
||||
"//ui/base/data_transfer_policy",
|
||||
"//ui/base/dragdrop:types",
|
||||
"//ui/base/dragdrop/mojom",
|
||||
"//ui/base/ime",
|
||||
"//ui/base/x",
|
||||
"//ui/base/x:gl",
|
||||
"//ui/display/types",
|
||||
"//ui/events",
|
||||
"//ui/events:dom_keycode_converter",
|
||||
"//ui/events/devices",
|
||||
"//ui/events/devices/x11",
|
||||
"//ui/events/ozone",
|
||||
"//ui/events/ozone/layout",
|
||||
"//ui/events/platform",
|
||||
"//ui/events/platform/x11",
|
||||
"//ui/events/x",
|
||||
"//ui/gfx",
|
||||
"//ui/gfx/geometry",
|
||||
"//ui/gfx/linux:gbm",
|
||||
"//ui/gfx/linux:gbm_support_x11",
|
||||
"//ui/gfx/x",
|
||||
"//ui/gl",
|
||||
"//ui/ozone:ozone_base",
|
||||
"//ui/ozone/common",
|
||||
"//ui/platform_window",
|
||||
"//ui/platform_window/common",
|
||||
"//ui/platform_window/wm",
|
||||
]
|
||||
|
||||
if (is_linux) {
|
||||
sources += [
|
||||
"linux_ui_delegate_x11.cc",
|
||||
"linux_ui_delegate_x11.h",
|
||||
]
|
||||
deps += [
|
||||
"//components/dbus",
|
||||
"//ui/base/clipboard:clipboard_util_linux",
|
||||
"//ui/linux:linux_ui",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_chromeos) {
|
||||
deps += [ "//ui/base/ime/ash" ]
|
||||
} else {
|
||||
deps += [ "//ui/base/ime/linux" ]
|
||||
}
|
||||
|
||||
if (enable_vulkan) {
|
||||
sources += [
|
||||
"vulkan_implementation_x11.cc",
|
||||
"vulkan_implementation_x11.h",
|
||||
"vulkan_surface_x11.cc",
|
||||
"vulkan_surface_x11.h",
|
||||
]
|
||||
deps += [ "//gpu/vulkan" ]
|
||||
}
|
||||
|
||||
if (use_xkbcommon) {
|
||||
configs += [ "//ui/events/ozone/layout:xkbcommon" ]
|
||||
}
|
||||
|
||||
if (use_atk) {
|
||||
sources += [
|
||||
"atk_event_conversion.cc",
|
||||
"atk_event_conversion.h",
|
||||
]
|
||||
configs += [ "//build/config/linux/atk" ]
|
||||
deps += [ "//ui/events/x" ]
|
||||
}
|
||||
}
|
||||
|
||||
source_set("x11_unittests") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"test/device_data_manager_x11_unittest.cc",
|
||||
"test/events_x_unittest.cc",
|
||||
"test/x11_event_translation_unittest.cc",
|
||||
"test/x11_window_unittest.cc",
|
||||
"x11_screen_ozone_unittest.cc",
|
||||
"x11_window_ozone_unittest.cc",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":x11",
|
||||
"//base",
|
||||
"//base/test:test_support",
|
||||
"//skia",
|
||||
"//testing/gmock",
|
||||
"//testing/gtest",
|
||||
"//ui/base",
|
||||
"//ui/base:features",
|
||||
"//ui/base/dragdrop:types",
|
||||
"//ui/base/x",
|
||||
"//ui/base/x:test_support",
|
||||
"//ui/base/x:unittests",
|
||||
"//ui/display:test_support",
|
||||
"//ui/events:test_support",
|
||||
"//ui/events/devices/x11",
|
||||
"//ui/events/platform/x11",
|
||||
"//ui/events/x",
|
||||
"//ui/gfx:test_support",
|
||||
"//ui/gfx/x",
|
||||
"//ui/gfx/x:unit_test",
|
||||
"//ui/ozone:platform",
|
||||
"//ui/ozone:test_support",
|
||||
"//ui/ozone/common",
|
||||
]
|
||||
|
||||
if (!is_chromeos) {
|
||||
sources += [ "test/os_exchange_data_provider_x11_unittest.cc" ]
|
||||
deps += [ "//ui/base/clipboard:clipboard_types" ]
|
||||
|
||||
# ChromeOS uses a non-backed exchange data provider while the tests actually
|
||||
# expect to use a normal X11 provider. Running these tests with a non-backed
|
||||
# provided results in crashes when ownership selection call is made.
|
||||
# Moreover, X11 on ChromeOS is used only for dev purposes and it doesn't
|
||||
# support DnD between X11 windows. Instead, all the dnd operations are
|
||||
# performed within a single native windows, where ash spawns number of own
|
||||
# internal windows.
|
||||
sources += [ "test/x11_drag_drop_client_unittest.cc" ]
|
||||
}
|
||||
}
|
||||
|
||||
source_set("test_support") {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"x11_ozone_ui_controls_test_helper.cc",
|
||||
"x11_ozone_ui_controls_test_helper.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//ui/aura",
|
||||
"//ui/base/x",
|
||||
"//ui/base/x:test_support",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
include_rules = [
|
||||
"+components/dbus",
|
||||
"+components/viz/common/resources/shared_image_format.h",
|
||||
"+components/viz/common/resources/shared_image_format_utils.h",
|
||||
"+dbus/bus.h",
|
||||
"+net/base/network_interfaces.h",
|
||||
"+ui/base/x",
|
||||
"+ui/base",
|
||||
"+ui/linux",
|
||||
]
|
||||
|
||||
specific_include_rules = {
|
||||
"x11_ozone_ui_controls_test_helper.cc": [
|
||||
"+ui/aura",
|
||||
]
|
||||
}
|
||||
+375
@@ -0,0 +1,375 @@
|
||||
// Copyright 2016 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/platform/x11/ozone_platform_x11.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/message_loop/message_pump_type.h"
|
||||
#include "base/metrics/histogram_functions.h"
|
||||
#include "base/no_destructor.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/task/single_thread_task_runner.h"
|
||||
#include "base/task/thread_pool.h"
|
||||
#include "build/build_config.h"
|
||||
#include "ui/base/buildflags.h"
|
||||
#include "ui/base/cursor/cursor_factory.h"
|
||||
#include "ui/base/dragdrop/os_exchange_data_provider_factory_ozone.h"
|
||||
#include "ui/base/x/x11_cursor_factory.h"
|
||||
#include "ui/base/x/x11_util.h"
|
||||
#include "ui/display/types/native_display_delegate.h"
|
||||
#include "ui/events/devices/x11/touch_factory_x11.h"
|
||||
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
|
||||
#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
|
||||
#include "ui/events/platform/x11/x11_event_source.h"
|
||||
#include "ui/gfx/linux/gbm_support_x11.h"
|
||||
#include "ui/gfx/native_ui_types.h"
|
||||
#include "ui/gfx/switches.h"
|
||||
#include "ui/gfx/x/atom_cache.h"
|
||||
#include "ui/gfx/x/visual_manager.h"
|
||||
#include "ui/linux/linux_ui_delegate.h"
|
||||
#include "ui/ozone/common/stub_overlay_manager.h"
|
||||
#include "ui/ozone/platform/x11/gl_egl_utility_x11.h"
|
||||
#include "ui/ozone/platform/x11/linux_ui_delegate_x11.h"
|
||||
#include "ui/ozone/platform/x11/x11_clipboard_ozone.h"
|
||||
#include "ui/ozone/platform/x11/x11_global_shortcut_listener_ozone.h"
|
||||
#include "ui/ozone/platform/x11/x11_keyboard_hook.h"
|
||||
#include "ui/ozone/platform/x11/x11_menu_utils.h"
|
||||
#include "ui/ozone/platform/x11/x11_screen_ozone.h"
|
||||
#include "ui/ozone/platform/x11/x11_surface_factory.h"
|
||||
#include "ui/ozone/platform/x11/x11_user_input_monitor.h"
|
||||
#include "ui/ozone/platform/x11/x11_utils.h"
|
||||
#include "ui/ozone/platform/x11/x11_window.h"
|
||||
#include "ui/ozone/public/gpu_platform_support_host.h"
|
||||
#include "ui/ozone/public/input_controller.h"
|
||||
#include "ui/ozone/public/ozone_platform.h"
|
||||
#include "ui/ozone/public/stub_input_controller.h"
|
||||
#include "ui/ozone/public/system_input_injector.h"
|
||||
#include "ui/platform_window/platform_window.h"
|
||||
#include "ui/platform_window/platform_window_init_properties.h"
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS)
|
||||
#include "ui/base/dragdrop/os_exchange_data_provider_non_backed.h"
|
||||
#include "ui/base/ime/ash/input_method_ash.h"
|
||||
#else
|
||||
#include "ui/base/ime/linux/input_method_auralinux.h"
|
||||
#include "ui/ozone/platform/x11/os_exchange_data_provider_x11.h"
|
||||
#endif
|
||||
|
||||
namespace ui {
|
||||
|
||||
namespace {
|
||||
|
||||
// Singleton OzonePlatform implementation for X11 platform.
|
||||
class OzonePlatformX11 : public OzonePlatform,
|
||||
public OSExchangeDataProviderFactoryOzone {
|
||||
public:
|
||||
OzonePlatformX11() { SetInstance(this); }
|
||||
|
||||
OzonePlatformX11(const OzonePlatformX11&) = delete;
|
||||
OzonePlatformX11& operator=(const OzonePlatformX11&) = delete;
|
||||
|
||||
~OzonePlatformX11() override = default;
|
||||
|
||||
// OzonePlatform:
|
||||
ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override {
|
||||
return surface_factory_ozone_.get();
|
||||
}
|
||||
|
||||
ui::OverlayManagerOzone* GetOverlayManager() override {
|
||||
return overlay_manager_.get();
|
||||
}
|
||||
|
||||
CursorFactory* GetCursorFactory() override { return cursor_factory_.get(); }
|
||||
|
||||
std::unique_ptr<SystemInputInjector> CreateSystemInputInjector() override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
InputController* GetInputController() override {
|
||||
return input_controller_.get();
|
||||
}
|
||||
|
||||
GpuPlatformSupportHost* GetGpuPlatformSupportHost() override {
|
||||
return gpu_platform_support_host_.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<PlatformWindow> CreatePlatformWindow(
|
||||
PlatformWindowDelegate* delegate,
|
||||
PlatformWindowInitProperties properties) override {
|
||||
auto window = std::make_unique<X11Window>(delegate);
|
||||
window->Initialize(std::move(properties));
|
||||
return std::move(window);
|
||||
}
|
||||
|
||||
std::unique_ptr<display::NativeDisplayDelegate> CreateNativeDisplayDelegate()
|
||||
override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<PlatformScreen> CreateScreen() override {
|
||||
return std::make_unique<X11ScreenOzone>();
|
||||
}
|
||||
|
||||
void InitScreen(PlatformScreen* screen) override {
|
||||
// InitScreen is always called with the same screen that CreateScreen
|
||||
// hands back, so it is safe to cast here.
|
||||
static_cast<X11ScreenOzone*>(screen)->Init();
|
||||
}
|
||||
|
||||
PlatformClipboard* GetPlatformClipboard() override {
|
||||
return clipboard_.get();
|
||||
}
|
||||
|
||||
PlatformGLEGLUtility* GetPlatformGLEGLUtility() override {
|
||||
if (!gl_egl_utility_)
|
||||
gl_egl_utility_ = std::make_unique<GLEGLUtilityX11>();
|
||||
return gl_egl_utility_.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<InputMethod> CreateInputMethod(
|
||||
ImeKeyEventDispatcher* ime_key_event_dispatcher,
|
||||
gfx::AcceleratedWidget widget) override {
|
||||
#if BUILDFLAG(IS_CHROMEOS)
|
||||
return std::make_unique<ash::InputMethodAsh>(ime_key_event_dispatcher);
|
||||
#else
|
||||
return std::make_unique<InputMethodAuraLinux>(ime_key_event_dispatcher,
|
||||
widget);
|
||||
#endif
|
||||
}
|
||||
|
||||
PlatformMenuUtils* GetPlatformMenuUtils() override {
|
||||
return menu_utils_.get();
|
||||
}
|
||||
|
||||
PlatformUtils* GetPlatformUtils() override { return x11_utils_.get(); }
|
||||
|
||||
PlatformGlobalShortcutListener* GetPlatformGlobalShortcutListener(
|
||||
PlatformGlobalShortcutListenerDelegate* delegate) override {
|
||||
if (!global_shortcut_listener_) {
|
||||
global_shortcut_listener_ =
|
||||
std::make_unique<X11GlobalShortcutListenerOzone>(delegate);
|
||||
}
|
||||
return global_shortcut_listener_.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<PlatformKeyboardHook> CreateKeyboardHook(
|
||||
PlatformKeyboardHookTypes type,
|
||||
base::RepeatingCallback<void(KeyEvent* event)> callback,
|
||||
std::optional<base::flat_set<DomCode>> dom_codes,
|
||||
gfx::AcceleratedWidget accelerated_widget) override {
|
||||
switch (type) {
|
||||
case PlatformKeyboardHookTypes::kModifier:
|
||||
return std::make_unique<X11KeyboardHook>(
|
||||
std::move(dom_codes), std::move(callback), accelerated_widget);
|
||||
case PlatformKeyboardHookTypes::kMedia:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<OSExchangeDataProvider> CreateProvider() override {
|
||||
#if BUILDFLAG(IS_CHROMEOS)
|
||||
return std::make_unique<OSExchangeDataProviderNonBacked>();
|
||||
#else
|
||||
return std::make_unique<OSExchangeDataProviderX11>();
|
||||
#endif
|
||||
}
|
||||
|
||||
const PlatformProperties& GetPlatformProperties() override {
|
||||
using SupportsForTest = OzonePlatform::PlatformProperties::SupportsForTest;
|
||||
const auto& override_set_parent_for_non_top_level_windows_for_test =
|
||||
OzonePlatform::PlatformProperties::
|
||||
override_set_parent_for_non_top_level_windows_for_test;
|
||||
|
||||
static base::NoDestructor<OzonePlatform::PlatformProperties> properties;
|
||||
static bool initialised = false;
|
||||
if (!initialised) {
|
||||
properties->custom_frame_pref_default = ui::GetCustomFramePrefDefault();
|
||||
|
||||
// When the Ozone X11 backend is running, use a UI loop to grab Expose
|
||||
// events. See GLSurfaceGLX and https://crbug.com/326995.
|
||||
properties->message_pump_type_for_gpu = base::MessagePumpType::UI;
|
||||
// When the Ozone X11 backend is running, use a UI loop to dispatch
|
||||
// SHM completion events.
|
||||
properties->message_pump_type_for_viz_compositor =
|
||||
base::MessagePumpType::UI;
|
||||
properties->supports_vulkan_swap_chain = true;
|
||||
properties->skia_can_fall_back_to_x11 = true;
|
||||
properties->platform_shows_drag_image = false;
|
||||
properties->app_modal_dialogs_use_event_blocker = true;
|
||||
|
||||
// Defaults to false unless explicitly enabled for testing.
|
||||
properties->set_parent_for_non_top_level_windows =
|
||||
override_set_parent_for_non_top_level_windows_for_test ==
|
||||
SupportsForTest::kYes;
|
||||
|
||||
initialised = true;
|
||||
}
|
||||
|
||||
return *properties;
|
||||
}
|
||||
|
||||
const PlatformRuntimeProperties& GetPlatformRuntimeProperties() override {
|
||||
static OzonePlatform::PlatformRuntimeProperties properties;
|
||||
|
||||
if (has_initialized_gpu() &&
|
||||
ui::GBMSupportX11::GetInstance()->has_gbm_device()) {
|
||||
// This property is set when the GetPlatformRuntimeProperties is
|
||||
// called on the gpu process side.
|
||||
properties.supports_native_pixmaps = true;
|
||||
}
|
||||
properties.supports_subwindows_as_accelerated_widgets = false;
|
||||
properties.supports_system_tray_windowing = true;
|
||||
properties.supports_server_window_menus =
|
||||
x11::Connection::Get()->WmSupportsHint(
|
||||
x11::GetAtom("_GTK_SHOW_WINDOW_MENU"));
|
||||
properties.supports_global_application_menus = true;
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
bool IsNativePixmapConfigSupported(viz::SharedImageFormat format,
|
||||
gfx::BufferUsage usage) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsWindowCompositingSupported() const override {
|
||||
return x11::Connection::Get()
|
||||
->GetOrCreateVisualManager()
|
||||
.ArgbVisualAvailable();
|
||||
}
|
||||
|
||||
bool InitializeUI(const InitParams& params) override {
|
||||
if (ShouldFailInitializeUIForTest()) {
|
||||
LOG(ERROR) << "Failing for test";
|
||||
return false;
|
||||
}
|
||||
// If opening the connection failed, we can not do anything. The platform
|
||||
// cannot initialise.
|
||||
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kHeadless) &&
|
||||
!x11::Connection::Get()->Ready()) {
|
||||
LOG(ERROR) << "Missing X server or $DISPLAY";
|
||||
return false;
|
||||
}
|
||||
|
||||
InitializeCommon(params);
|
||||
CreatePlatformEventSource();
|
||||
overlay_manager_ = std::make_unique<StubOverlayManager>();
|
||||
input_controller_ = std::make_unique<StubInputController>();
|
||||
clipboard_ = std::make_unique<X11ClipboardOzone>();
|
||||
cursor_factory_ = std::make_unique<X11CursorFactory>();
|
||||
gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost());
|
||||
|
||||
// TODO(crbug.com/41472924): Support XKB.
|
||||
keyboard_layout_engine_ = std::make_unique<StubKeyboardLayoutEngine>();
|
||||
KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
|
||||
keyboard_layout_engine_.get());
|
||||
|
||||
TouchFactory::SetTouchDeviceListFromCommandLine();
|
||||
|
||||
#if BUILDFLAG(USE_GTK)
|
||||
linux_ui_delegate_ = std::make_unique<LinuxUiDelegateX11>();
|
||||
#endif
|
||||
|
||||
menu_utils_ = std::make_unique<X11MenuUtils>();
|
||||
x11_utils_ = std::make_unique<X11Utils>();
|
||||
|
||||
base::UmaHistogramEnumeration("Linux.WindowManager", GetWindowManagerUMA());
|
||||
|
||||
base::UmaHistogramBoolean(
|
||||
"Linux.X11.XInput2",
|
||||
x11::Connection::Get()->xinput_version().first == 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InitializeGPU(const InitParams& params) override {
|
||||
InitializeCommon(params);
|
||||
if (params.enable_native_gpu_memory_buffers) {
|
||||
base::ThreadPool::PostTask(FROM_HERE, base::BindOnce([]() {
|
||||
ui::GBMSupportX11::GetInstance();
|
||||
}));
|
||||
}
|
||||
// In single process mode either the UI thread will create an event source
|
||||
// or it's a test and an event source isn't desired.
|
||||
if (!params.single_process)
|
||||
CreatePlatformEventSource();
|
||||
|
||||
// Set up the X11 connection before the sandbox gets set up. This cannot be
|
||||
// done later since opening the connection requires socket() and connect().
|
||||
auto connection = x11::Connection::Get()->Clone();
|
||||
connection->DetachFromSequence();
|
||||
surface_factory_ozone_ =
|
||||
std::make_unique<X11SurfaceFactory>(std::move(connection));
|
||||
}
|
||||
|
||||
void PostCreateMainMessageLoop(
|
||||
base::OnceCallback<void()> shutdown_cb,
|
||||
scoped_refptr<base::SingleThreadTaskRunner>) override {
|
||||
// Installs the X11 error handlers for the UI process after the
|
||||
// main message loop has started. This will allow us to exit cleanly
|
||||
// if X exits before we do.
|
||||
x11::Connection::Get()->SetIOErrorHandler(std::move(shutdown_cb));
|
||||
}
|
||||
|
||||
std::unique_ptr<PlatformUserInputMonitor> GetPlatformUserInputMonitor(
|
||||
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
|
||||
override {
|
||||
return std::make_unique<X11UserInputMonitor>(std::move(io_task_runner));
|
||||
}
|
||||
|
||||
private:
|
||||
// Performs initialization steps need by both UI and GPU.
|
||||
void InitializeCommon(const InitParams& params) {
|
||||
if (common_initialized_)
|
||||
return;
|
||||
|
||||
common_initialized_ = true;
|
||||
}
|
||||
|
||||
// Creates |event_source_| if it doesn't already exist.
|
||||
void CreatePlatformEventSource() {
|
||||
if (event_source_)
|
||||
return;
|
||||
|
||||
auto* connection = x11::Connection::Get();
|
||||
event_source_ = std::make_unique<X11EventSource>(connection);
|
||||
}
|
||||
|
||||
bool common_initialized_ = false;
|
||||
|
||||
// Objects in the UI process.
|
||||
std::unique_ptr<KeyboardLayoutEngine> keyboard_layout_engine_;
|
||||
std::unique_ptr<OverlayManagerOzone> overlay_manager_;
|
||||
std::unique_ptr<InputController> input_controller_;
|
||||
std::unique_ptr<X11ClipboardOzone> clipboard_;
|
||||
std::unique_ptr<CursorFactory> cursor_factory_;
|
||||
std::unique_ptr<GpuPlatformSupportHost> gpu_platform_support_host_;
|
||||
std::unique_ptr<X11MenuUtils> menu_utils_;
|
||||
std::unique_ptr<X11Utils> x11_utils_;
|
||||
std::unique_ptr<PlatformGlobalShortcutListener> global_shortcut_listener_;
|
||||
|
||||
// Objects in the GPU process.
|
||||
std::unique_ptr<X11SurfaceFactory> surface_factory_ozone_;
|
||||
std::unique_ptr<GLEGLUtilityX11> gl_egl_utility_;
|
||||
|
||||
// Objects in both UI and GPU process.
|
||||
std::unique_ptr<X11EventSource> event_source_;
|
||||
|
||||
#if BUILDFLAG(USE_GTK)
|
||||
std::unique_ptr<LinuxUiDelegate> linux_ui_delegate_;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
OzonePlatform* CreateOzonePlatformX11() {
|
||||
return new OzonePlatformX11;
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// Copyright 2016 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_X11_OZONE_PLATFORM_X11_H_
|
||||
#define UI_OZONE_PLATFORM_X11_OZONE_PLATFORM_X11_H_
|
||||
|
||||
namespace ui {
|
||||
|
||||
class OzonePlatform;
|
||||
|
||||
// Constructor hook for use in ozone_platform_list.cc
|
||||
OzonePlatform* CreateOzonePlatformX11();
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_X11_OZONE_PLATFORM_X11_H_
|
||||
+267
@@ -0,0 +1,267 @@
|
||||
// Copyright 2016 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/platform/x11/x11_surface_factory.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "components/viz/common/resources/shared_image_format_utils.h"
|
||||
#include "gpu/vulkan/buildflags.h"
|
||||
#include "ui/events/platform/x11/x11_event_source.h"
|
||||
#include "ui/gfx/linux/gbm_buffer.h"
|
||||
#include "ui/gfx/linux/gbm_support_x11.h"
|
||||
#include "ui/gfx/linux/native_pixmap_dmabuf.h"
|
||||
#include "ui/gl/gl_bindings.h"
|
||||
#include "ui/gl/gl_surface_egl.h"
|
||||
#include "ui/gl/gl_surface_egl_x11_gles2.h"
|
||||
#include "ui/ozone/common/egl_util.h"
|
||||
#include "ui/ozone/common/gl_ozone_egl.h"
|
||||
#include "ui/ozone/common/native_pixmap_egl_binding.h"
|
||||
#include "ui/ozone/platform/x11/gl_surface_egl_readback_x11.h"
|
||||
#include "ui/ozone/platform/x11/native_pixmap_egl_x11_binding.h"
|
||||
#include "ui/ozone/platform/x11/x11_canvas_surface.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_VULKAN)
|
||||
#include "ui/ozone/platform/x11/vulkan_implementation_x11.h"
|
||||
#endif
|
||||
|
||||
namespace ui {
|
||||
namespace {
|
||||
|
||||
enum class NativePixmapSupportType {
|
||||
// Importing native pixmaps not supported.
|
||||
kNone,
|
||||
|
||||
// Native pixmaps are imported directly into EGL using the
|
||||
// EGL_EXT_image_dma_buf_import extension.
|
||||
kDMABuf,
|
||||
|
||||
// Native pixmaps are first imported as X11 pixmaps using DRI3 and then into
|
||||
// EGL.
|
||||
kX11Pixmap,
|
||||
};
|
||||
|
||||
NativePixmapSupportType GetNativePixmapSupportType() {
|
||||
if (gl::GLSurfaceEGL::GetGLDisplayEGL()
|
||||
->ext->b_EGL_EXT_image_dma_buf_import) {
|
||||
return NativePixmapSupportType::kDMABuf;
|
||||
} else if (NativePixmapEGLX11Binding::CanImportNativeGLXPixmap()) {
|
||||
return NativePixmapSupportType::kX11Pixmap;
|
||||
} else {
|
||||
return NativePixmapSupportType::kNone;
|
||||
}
|
||||
}
|
||||
|
||||
class GLOzoneEGLX11 : public GLOzoneEGL {
|
||||
public:
|
||||
GLOzoneEGLX11() = default;
|
||||
|
||||
GLOzoneEGLX11(const GLOzoneEGLX11&) = delete;
|
||||
GLOzoneEGLX11& operator=(const GLOzoneEGLX11&) = delete;
|
||||
|
||||
~GLOzoneEGLX11() override = default;
|
||||
|
||||
// GLOzone:
|
||||
bool InitializeStaticGLBindings(
|
||||
const gl::GLImplementationParts& implementation) override {
|
||||
is_swiftshader_ = gl::IsSoftwareGLImplementation(implementation);
|
||||
return GLOzoneEGL::InitializeStaticGLBindings(implementation);
|
||||
}
|
||||
|
||||
bool CanImportNativePixmap(viz::SharedImageFormat format) override {
|
||||
if (GetNativePixmapSupportType() == NativePixmapSupportType::kNone) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (GetNativePixmapSupportType()) {
|
||||
case NativePixmapSupportType::kDMABuf: {
|
||||
return NativePixmapEGLBinding::IsSharedImageFormatSupported(format);
|
||||
}
|
||||
case NativePixmapSupportType::kX11Pixmap: {
|
||||
return NativePixmapEGLX11Binding::IsSharedImageFormatSupported(format);
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
scoped_refptr<gl::GLSurface> CreateViewGLSurface(
|
||||
gl::GLDisplay* display,
|
||||
gfx::AcceleratedWidget window) override {
|
||||
if (is_swiftshader_) {
|
||||
return gl::InitializeGLSurface(
|
||||
base::MakeRefCounted<GLSurfaceEglReadbackX11>(
|
||||
display->GetAs<gl::GLDisplayEGL>(), window));
|
||||
} else {
|
||||
switch (gl::GetGLImplementation()) {
|
||||
case gl::kGLImplementationEGLGLES2:
|
||||
DCHECK(window != gfx::kNullAcceleratedWidget);
|
||||
return gl::InitializeGLSurface(new gl::NativeViewGLSurfaceEGLX11GLES2(
|
||||
display->GetAs<gl::GLDisplayEGL>(),
|
||||
static_cast<x11::Window>(window)));
|
||||
case gl::kGLImplementationEGLANGLE:
|
||||
DCHECK(window != gfx::kNullAcceleratedWidget);
|
||||
return gl::InitializeGLSurface(new gl::NativeViewGLSurfaceEGLX11(
|
||||
display->GetAs<gl::GLDisplayEGL>(),
|
||||
static_cast<x11::Window>(window)));
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scoped_refptr<gl::GLSurface> CreateOffscreenGLSurface(
|
||||
gl::GLDisplay* display,
|
||||
const gfx::Size& size) override {
|
||||
gl::GLDisplayEGL* egl_display = display->GetAs<gl::GLDisplayEGL>();
|
||||
if (egl_display->IsEGLSurfacelessContextSupported() && size.width() == 0 &&
|
||||
size.height() == 0) {
|
||||
return InitializeGLSurface(new gl::SurfacelessEGL(egl_display, size));
|
||||
} else {
|
||||
return InitializeGLSurface(
|
||||
new gl::PbufferGLSurfaceEGL(egl_display, size));
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
// GLOzoneEGL:
|
||||
gl::EGLDisplayPlatform GetNativeDisplay() override {
|
||||
return gl::EGLDisplayPlatform(reinterpret_cast<EGLNativeDisplayType>(
|
||||
x11::Connection::Get()->GetXlibDisplay().display()));
|
||||
}
|
||||
|
||||
bool LoadGLES2Bindings(
|
||||
const gl::GLImplementationParts& implementation) override {
|
||||
return LoadDefaultEGLGLES2Bindings(implementation);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<NativePixmapGLBinding> ImportNativePixmap(
|
||||
scoped_refptr<gfx::NativePixmap> pixmap,
|
||||
viz::SharedImageFormat plane_format,
|
||||
std::optional<int> plane_index,
|
||||
gfx::Size plane_size,
|
||||
const gfx::ColorSpace& color_space,
|
||||
GLenum target,
|
||||
GLuint texture_id) override {
|
||||
switch (GetNativePixmapSupportType()) {
|
||||
case NativePixmapSupportType::kDMABuf: {
|
||||
return NativePixmapEGLBinding::Create(pixmap, plane_format, plane_index,
|
||||
plane_size, color_space, target,
|
||||
texture_id);
|
||||
}
|
||||
case NativePixmapSupportType::kX11Pixmap: {
|
||||
return NativePixmapEGLX11Binding::Create(
|
||||
pixmap, plane_format, plane_size, target, texture_id);
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_swiftshader_ = false;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
X11SurfaceFactory::X11SurfaceFactory(
|
||||
std::unique_ptr<x11::Connection> connection)
|
||||
: egl_implementation_(std::make_unique<GLOzoneEGLX11>()),
|
||||
connection_(std::move(connection)) {}
|
||||
|
||||
X11SurfaceFactory::~X11SurfaceFactory() = default;
|
||||
|
||||
std::vector<gl::GLImplementationParts>
|
||||
X11SurfaceFactory::GetAllowedGLImplementations() {
|
||||
return std::vector<gl::GLImplementationParts>{
|
||||
gl::GLImplementationParts(gl::kGLImplementationEGLANGLE),
|
||||
};
|
||||
}
|
||||
|
||||
GLOzone* X11SurfaceFactory::GetGLOzone(
|
||||
const gl::GLImplementationParts& implementation) {
|
||||
switch (implementation.gl) {
|
||||
case gl::kGLImplementationEGLANGLE:
|
||||
return egl_implementation_.get();
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_VULKAN)
|
||||
std::unique_ptr<gpu::VulkanImplementation>
|
||||
X11SurfaceFactory::CreateVulkanImplementation(bool use_swiftshader,
|
||||
bool allow_protected_memory) {
|
||||
return std::make_unique<VulkanImplementationX11>(use_swiftshader);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<SurfaceOzoneCanvas> X11SurfaceFactory::CreateCanvasForWidget(
|
||||
gfx::AcceleratedWidget widget) {
|
||||
// X11SoftwareBitmapPresenter (created via X11CanvasSurface) requres a
|
||||
// Connection TLS instance and a PlatformEventSource.
|
||||
if (connection_) {
|
||||
auto* connection = connection_.get();
|
||||
x11::Connection::Set(std::move(connection_));
|
||||
connection->platform_event_source =
|
||||
std::make_unique<X11EventSource>(connection);
|
||||
}
|
||||
return std::make_unique<X11CanvasSurface>(widget);
|
||||
}
|
||||
|
||||
scoped_refptr<gfx::NativePixmap> X11SurfaceFactory::CreateNativePixmap(
|
||||
gfx::AcceleratedWidget widget,
|
||||
gpu::VulkanDeviceQueue* device_queue,
|
||||
gfx::Size size,
|
||||
viz::SharedImageFormat format,
|
||||
gfx::BufferUsage usage,
|
||||
std::optional<gfx::Size> framebuffer_size) {
|
||||
scoped_refptr<gfx::NativePixmapDmaBuf> pixmap;
|
||||
auto buffer =
|
||||
ui::GBMSupportX11::GetInstance()->CreateBuffer(format, size, usage);
|
||||
if (buffer) {
|
||||
gfx::NativePixmapHandle handle = buffer->ExportHandle();
|
||||
if (handle.planes.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
pixmap = base::MakeRefCounted<gfx::NativePixmapDmaBuf>(size, format,
|
||||
std::move(handle));
|
||||
}
|
||||
|
||||
// CreateNativePixmap is non-blocking operation. Thus, it is safe to call it
|
||||
// and return the result with the provided callback.
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
bool X11SurfaceFactory::CanCreateNativePixmapForFormat(
|
||||
viz::SharedImageFormat format) {
|
||||
return ui::GBMSupportX11::GetInstance()->CanCreateBufferForFormat(format);
|
||||
}
|
||||
|
||||
scoped_refptr<gfx::NativePixmap>
|
||||
X11SurfaceFactory::CreateNativePixmapFromHandle(
|
||||
gfx::AcceleratedWidget widget,
|
||||
gfx::Size size,
|
||||
viz::SharedImageFormat format,
|
||||
gfx::NativePixmapHandle handle) {
|
||||
scoped_refptr<gfx::NativePixmapDmaBuf> pixmap;
|
||||
auto buffer = ui::GBMSupportX11::GetInstance()->CreateBufferFromHandle(
|
||||
size, format, std::move(handle));
|
||||
if (buffer) {
|
||||
gfx::NativePixmapHandle buffer_handle = buffer->ExportHandle();
|
||||
if (buffer_handle.planes.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
pixmap = base::MakeRefCounted<gfx::NativePixmapDmaBuf>(
|
||||
size, format, std::move(buffer_handle));
|
||||
}
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
bool X11SurfaceFactory::IsFormatSupportedForTexturing(
|
||||
viz::SharedImageFormat format) const {
|
||||
return ui::GBMSupportX11::GetInstance()->CanCreateBufferForFormat(format);
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
// Copyright 2016 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_X11_X11_SURFACE_FACTORY_H_
|
||||
#define UI_OZONE_PLATFORM_X11_X11_SURFACE_FACTORY_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "components/viz/common/resources/shared_image_format.h"
|
||||
#include "gpu/vulkan/buildflags.h"
|
||||
#include "ui/gfx/x/connection.h"
|
||||
#include "ui/gl/gl_surface.h"
|
||||
#include "ui/ozone/public/gl_ozone.h"
|
||||
#include "ui/ozone/public/surface_factory_ozone.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
// Handles GL initialization and surface/context creation for X11.
|
||||
class X11SurfaceFactory : public SurfaceFactoryOzone {
|
||||
public:
|
||||
explicit X11SurfaceFactory(std::unique_ptr<x11::Connection> connection);
|
||||
|
||||
X11SurfaceFactory(const X11SurfaceFactory&) = delete;
|
||||
X11SurfaceFactory& operator=(const X11SurfaceFactory&) = delete;
|
||||
|
||||
~X11SurfaceFactory() override;
|
||||
|
||||
// SurfaceFactoryOzone:
|
||||
std::vector<gl::GLImplementationParts> GetAllowedGLImplementations() override;
|
||||
GLOzone* GetGLOzone(const gl::GLImplementationParts& implementation) override;
|
||||
#if BUILDFLAG(ENABLE_VULKAN)
|
||||
std::unique_ptr<gpu::VulkanImplementation> CreateVulkanImplementation(
|
||||
bool use_swiftshader,
|
||||
bool allow_protected_memory) override;
|
||||
#endif
|
||||
std::unique_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget(
|
||||
gfx::AcceleratedWidget widget) override;
|
||||
scoped_refptr<gfx::NativePixmap> CreateNativePixmap(
|
||||
gfx::AcceleratedWidget widget,
|
||||
gpu::VulkanDeviceQueue* device_queue,
|
||||
gfx::Size size,
|
||||
viz::SharedImageFormat format,
|
||||
gfx::BufferUsage usage,
|
||||
std::optional<gfx::Size> framebuffer_size = std::nullopt) override;
|
||||
bool CanCreateNativePixmapForFormat(viz::SharedImageFormat format) override;
|
||||
scoped_refptr<gfx::NativePixmap> CreateNativePixmapFromHandle(
|
||||
gfx::AcceleratedWidget widget,
|
||||
gfx::Size size,
|
||||
viz::SharedImageFormat format,
|
||||
gfx::NativePixmapHandle handle) override;
|
||||
|
||||
bool IsFormatSupportedForTexturing(
|
||||
viz::SharedImageFormat format) const override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<GLOzone> egl_implementation_;
|
||||
|
||||
std::unique_ptr<x11::Connection> connection_;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_X11_X11_SURFACE_FACTORY_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,521 @@
|
||||
// Copyright 2014 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_X11_X11_WINDOW_H_
|
||||
#define UI_OZONE_PLATFORM_X11_X11_WINDOW_H_
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/cancelable_callback.h"
|
||||
#include "base/containers/flat_set.h"
|
||||
#include "base/gtest_prod_util.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/memory/raw_ref.h"
|
||||
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-forward.h"
|
||||
#include "ui/base/x/x11_desktop_window_move_client.h"
|
||||
#include "ui/base/x/x11_drag_drop_client.h"
|
||||
#include "ui/base/x/x11_move_loop_delegate.h"
|
||||
#include "ui/events/platform/platform_event_dispatcher.h"
|
||||
#include "ui/gfx/geometry/insets.h"
|
||||
#include "ui/gfx/x/connection.h"
|
||||
#include "ui/gfx/x/event.h"
|
||||
#include "ui/gfx/x/sync.h"
|
||||
#include "ui/gfx/x/xfixes.h"
|
||||
#include "ui/gfx/x/xproto.h"
|
||||
#include "ui/platform_window/extensions/workspace_extension.h"
|
||||
#include "ui/platform_window/extensions/x11_extension.h"
|
||||
#include "ui/platform_window/platform_window.h"
|
||||
#include "ui/platform_window/platform_window_init_properties.h"
|
||||
#include "ui/platform_window/wm/wm_drag_handler.h"
|
||||
#include "ui/platform_window/wm/wm_move_loop_handler.h"
|
||||
#include "ui/platform_window/wm/wm_move_resize_handler.h"
|
||||
|
||||
class SkPath;
|
||||
|
||||
namespace x11 {
|
||||
class GeometryCache;
|
||||
class WmSync;
|
||||
} // namespace x11
|
||||
|
||||
namespace ui {
|
||||
|
||||
class PlatformWindowDelegate;
|
||||
class X11ExtensionDelegate;
|
||||
class X11MoveLoop;
|
||||
class WorkspaceExtensionDelegate;
|
||||
|
||||
// PlatformWindow implementation for X11.
|
||||
class X11Window : public PlatformWindow,
|
||||
public WmMoveResizeHandler,
|
||||
public PlatformEventDispatcher,
|
||||
public x11::EventObserver,
|
||||
public WorkspaceExtension,
|
||||
public X11Extension,
|
||||
public WmDragHandler,
|
||||
public XDragDropClient::Delegate,
|
||||
public X11MoveLoopDelegate,
|
||||
public WmMoveLoopHandler,
|
||||
public X11DesktopWindowMoveClient::Delegate {
|
||||
public:
|
||||
explicit X11Window(PlatformWindowDelegate* platform_window_delegate);
|
||||
|
||||
X11Window(const X11Window&) = delete;
|
||||
X11Window& operator=(const X11Window&) = delete;
|
||||
|
||||
~X11Window() override;
|
||||
|
||||
virtual void Initialize(PlatformWindowInitProperties properties);
|
||||
|
||||
// X11WindowManager calls this.
|
||||
void OnXWindowLostCapture();
|
||||
|
||||
void OnCursorUpdate();
|
||||
|
||||
gfx::AcceleratedWidget GetWidget() const;
|
||||
gfx::Rect GetOuterBounds() const;
|
||||
void SetTransientWindow(x11::Window window);
|
||||
|
||||
bool has_pointer() const { return has_pointer_; }
|
||||
|
||||
// PlatformWindow:
|
||||
void Show(bool inactive) override;
|
||||
void Hide() override;
|
||||
void Close() override;
|
||||
bool IsVisible() const override;
|
||||
void PrepareForShutdown() override;
|
||||
void SetBoundsInPixels(const gfx::Rect& bounds) override;
|
||||
gfx::Rect GetBoundsInPixels() const override;
|
||||
void SetBoundsInDIP(const gfx::Rect& bounds) override;
|
||||
gfx::Rect GetBoundsInDIP() const override;
|
||||
void SetTitle(const std::u16string& title) override;
|
||||
void SetCapture() override;
|
||||
void ReleaseCapture() override;
|
||||
bool HasCapture() const override;
|
||||
void SetFullscreen(bool fullscreen, int64_t target_display_id) override;
|
||||
void Maximize() override;
|
||||
void Minimize() override;
|
||||
void Restore() override;
|
||||
void ShowWindowControlsMenu(const gfx::Point& point) override;
|
||||
PlatformWindowState GetPlatformWindowState() const override;
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
void SetUseNativeFrame(bool use_native_frame) override;
|
||||
bool ShouldUseNativeFrame() const override;
|
||||
void SetCursor(scoped_refptr<PlatformCursor> cursor) override;
|
||||
void MoveCursorTo(const gfx::Point& location) override;
|
||||
void ConfineCursorToBounds(const gfx::Rect& bounds) override;
|
||||
void SetRestoredBoundsInDIP(const gfx::Rect& bounds) final;
|
||||
gfx::Rect GetRestoredBoundsInDIP() const final;
|
||||
bool ShouldWindowContentsBeTransparent() const override;
|
||||
void SetZOrderLevel(ZOrderLevel order) override;
|
||||
ZOrderLevel GetZOrderLevel() const override;
|
||||
void StackAbove(gfx::AcceleratedWidget widget) override;
|
||||
void StackAtTop() override;
|
||||
void FlashFrame(bool flash_frame) override;
|
||||
void SetShape(std::unique_ptr<ShapeRects> native_shape,
|
||||
const gfx::Transform& transform) override;
|
||||
void SetAspectRatio(const gfx::SizeF& aspect_ratio) override;
|
||||
void SetWindowIcons(const gfx::ImageSkia& window_icon,
|
||||
const gfx::ImageSkia& app_icon) override;
|
||||
void SizeConstraintsChanged() override;
|
||||
void SetOpacity(float opacity) override;
|
||||
bool CanSetDecorationInsets() const override;
|
||||
void SetOpaqueRegion(
|
||||
std::optional<std::vector<gfx::Rect>> region_px) override;
|
||||
void SetInputRegion(std::optional<std::vector<gfx::Rect>> region_px) override;
|
||||
void NotifyStartupComplete(const std::string& startup_id) override;
|
||||
|
||||
// WorkspaceExtension:
|
||||
std::string GetWorkspace() const override;
|
||||
void SetVisibleOnAllWorkspaces(bool always_visible) override;
|
||||
bool IsVisibleOnAllWorkspaces() const override;
|
||||
void SetWorkspaceExtensionDelegate(
|
||||
WorkspaceExtensionDelegate* delegate) override;
|
||||
|
||||
// X11Extension:
|
||||
bool IsSyncExtensionAvailable() const override;
|
||||
bool IsWmTiling() const override;
|
||||
void OnCompleteSwapAfterResize(const gfx::Size& new_size) override;
|
||||
gfx::Rect GetXRootWindowOuterBounds() const override;
|
||||
void LowerXWindow() override;
|
||||
void SetOverrideRedirect(bool override_redirect) override;
|
||||
bool CanResetOverrideRedirect() const override;
|
||||
void SetX11ExtensionDelegate(X11ExtensionDelegate* delegate) override;
|
||||
bool IsWmSyncActiveForTest() override;
|
||||
|
||||
// x11::EventObserver:
|
||||
void OnEvent(const x11::Event& event) override;
|
||||
|
||||
protected:
|
||||
PlatformWindowDelegate* platform_window_delegate() const {
|
||||
return platform_window_delegate_;
|
||||
}
|
||||
|
||||
void OnXWindowStateChanged();
|
||||
void OnXWindowDamageEvent(const gfx::Rect& damage_rect);
|
||||
void OnXWindowCloseRequested();
|
||||
void OnXWindowIsActiveChanged(bool active);
|
||||
void OnXWindowWorkspaceChanged();
|
||||
void OnXWindowLostPointerGrab();
|
||||
void OnXWindowSelectionEvent(const x11::SelectionNotifyEvent& xev);
|
||||
void OnXWindowDragDropEvent(const x11::ClientMessageEvent& xev);
|
||||
std::optional<gfx::Size> GetMinimumSizeForXWindow();
|
||||
std::optional<gfx::Size> GetMaximumSizeForXWindow();
|
||||
SkPath GetWindowMaskForXWindow();
|
||||
|
||||
private:
|
||||
FRIEND_TEST_ALL_PREFIXES(X11WindowTest, Shape);
|
||||
FRIEND_TEST_ALL_PREFIXES(X11WindowTest, WindowManagerTogglesFullscreen);
|
||||
FRIEND_TEST_ALL_PREFIXES(X11WindowTest,
|
||||
ToggleMinimizePropogateToPlatformWindowDelegate);
|
||||
|
||||
void UpdateDecorationInsets();
|
||||
|
||||
// PlatformEventDispatcher:
|
||||
bool CanDispatchEvent(const PlatformEvent& event) override;
|
||||
uint32_t DispatchEvent(const PlatformEvent& event) override;
|
||||
|
||||
void DispatchUiEvent(ui::Event* event, const x11::Event& xev);
|
||||
|
||||
// WmMoveResizeHandler
|
||||
void DispatchHostWindowDragMovement(
|
||||
int hittest,
|
||||
const gfx::Point& pointer_location_in_px) override;
|
||||
|
||||
// WmMoveLoopHandler:
|
||||
bool RunMoveLoop(const gfx::Vector2d& drag_offset) override;
|
||||
void EndMoveLoop() override;
|
||||
|
||||
// WmDragHandler:
|
||||
bool StartDrag(const OSExchangeData& data,
|
||||
int operations,
|
||||
mojom::DragEventSource source,
|
||||
gfx::NativeCursor cursor,
|
||||
bool can_grab_pointer,
|
||||
base::OnceClosure drag_started_callback,
|
||||
WmDragHandler::DragFinishedCallback drag_finished_callback,
|
||||
WmDragHandler::LocationDelegate* delegate) override;
|
||||
void CancelDrag() override;
|
||||
void UpdateDragImage(const gfx::ImageSkia& image,
|
||||
const gfx::Vector2d& offset) override;
|
||||
|
||||
// XDragDropClient::Delegate
|
||||
std::optional<gfx::AcceleratedWidget> GetDragWidget() override;
|
||||
int UpdateDrag(const gfx::Point& screen_point) override;
|
||||
void UpdateCursor(mojom::DragOperation negotiated_operation) override;
|
||||
void OnBeginForeignDrag(x11::Window window) override;
|
||||
void OnEndForeignDrag() override;
|
||||
void OnBeforeDragLeave() override;
|
||||
mojom::DragOperation PerformDrop() override;
|
||||
void EndDragLoop() override;
|
||||
|
||||
// X11MoveLoopDelegate
|
||||
void OnMouseMovement(const gfx::Point& screen_point,
|
||||
int flags,
|
||||
base::TimeTicks event_time) override;
|
||||
void OnMouseReleased() override;
|
||||
void OnMoveLoopEnded() override;
|
||||
|
||||
// X11DesktopWindowMoveClient::Delegate:
|
||||
void SetBoundsOnMove(const gfx::Rect& requested_bounds) override;
|
||||
scoped_refptr<X11Cursor> GetLastCursor() override;
|
||||
gfx::Size GetSize() override;
|
||||
|
||||
void QuitDragLoop();
|
||||
|
||||
// Handles `event` as an Atk Key Event
|
||||
bool HandleAsAtkEvent(const x11::Event& event);
|
||||
|
||||
// Adjusts |requested_size_in_pixels| to avoid the WM "feature" where setting
|
||||
// the window size to the monitor size causes the WM to set the EWMH for
|
||||
// fullscreen.
|
||||
gfx::Size AdjustSizeForDisplay(const gfx::Size& requested_size_in_pixels);
|
||||
|
||||
// Creates the X window with the given properties.
|
||||
// Depending on presence of the compositing manager and window type, may
|
||||
// change the opacity, in which case returns the final opacity type through
|
||||
// |opacity|.
|
||||
void CreateXWindow(const PlatformWindowInitProperties& properties);
|
||||
void CloseXWindow();
|
||||
void Map(bool inactive = false);
|
||||
void SetWMStateFullscreen(bool fullscreen);
|
||||
void SetWMStateMaximize(bool maximize);
|
||||
bool IsActive() const;
|
||||
bool IsTargetedBy(const x11::Event& xev) const;
|
||||
void HandleEvent(const x11::Event& xev);
|
||||
|
||||
bool IsMinimized() const;
|
||||
bool IsMaximized() const;
|
||||
bool IsFullscreen() const;
|
||||
|
||||
void SetFlashFrameHint(bool flash_frame);
|
||||
void UpdateMinAndMaxSize();
|
||||
void DispatchResize(bool origin_changed);
|
||||
void CancelResize();
|
||||
|
||||
// Resets the window region for the current window bounds if necessary.
|
||||
void ResetWindowRegion();
|
||||
|
||||
x11::Window window() const { return xwindow_; }
|
||||
x11::Window root_window() const { return x_root_window_; }
|
||||
std::vector<x11::Rectangle>* shape() const { return window_shape_.get(); }
|
||||
|
||||
// Updates |xwindow_|'s _NET_WM_USER_TIME if |xwindow_| is active.
|
||||
void UpdateWMUserTime(ui::Event* event);
|
||||
|
||||
// Called on an XFocusInEvent, XFocusOutEvent, XIFocusInEvent, or an
|
||||
// XIFocusOutEvent.
|
||||
void OnFocusEvent(bool focus_in,
|
||||
x11::NotifyMode mode,
|
||||
x11::NotifyDetail detail);
|
||||
|
||||
// Called on an XEnterWindowEvent, XLeaveWindowEvent, XIEnterEvent, or an
|
||||
// XILeaveEvent.
|
||||
void OnCrossingEvent(bool enter,
|
||||
bool focus_in_window_or_ancestor,
|
||||
x11::NotifyMode mode,
|
||||
x11::NotifyDetail detail);
|
||||
|
||||
// Called when |xwindow_|'s _NET_WM_STATE property is updated.
|
||||
void OnWMStateUpdated();
|
||||
|
||||
WindowTiledEdges GetTiledState() const;
|
||||
|
||||
// Called when |xwindow_|'s _NET_FRAME_EXTENTS property is updated.
|
||||
void OnFrameExtentsUpdated();
|
||||
|
||||
void OnConfigureEvent(const x11::ConfigureNotifyEvent& event);
|
||||
|
||||
void OnWorkspaceUpdated();
|
||||
|
||||
void OnWindowMapped();
|
||||
|
||||
// Record the activation state.
|
||||
void BeforeActivationStateChanged();
|
||||
|
||||
// Handle the state change since BeforeActivationStateChanged().
|
||||
void AfterActivationStateChanged();
|
||||
|
||||
void MaybeUpdateOcclusionState();
|
||||
|
||||
void DelayedResize(bool origin_changed);
|
||||
|
||||
// If mapped, sends a message to the window manager to enable or disable the
|
||||
// states |state1| and |state2|. Otherwise, the states will be enabled or
|
||||
// disabled on the next map. It's the caller's responsibility to make sure
|
||||
// atoms are set and unset in the appropriate pairs. For example, if a caller
|
||||
// sets (_NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_MAXIMIZED_HORZ), it would
|
||||
// be invalid to unset the maximized state by making two calls like
|
||||
// (_NET_WM_STATE_MAXIMIZED_VERT, x11::None), (_NET_WM_STATE_MAXIMIZED_HORZ,
|
||||
// x11::None).
|
||||
void SetWMSpecState(bool enabled, x11::Atom state1, x11::Atom state2);
|
||||
|
||||
// Updates |window_properties_| with |new_window_properties|.
|
||||
void UpdateWindowProperties(
|
||||
const base::flat_set<x11::Atom>& new_window_properties);
|
||||
|
||||
void UnconfineCursor();
|
||||
|
||||
void UpdateWindowRegion(std::unique_ptr<std::vector<x11::Rectangle>> region);
|
||||
|
||||
void NotifyBoundsChanged(bool origin_changed);
|
||||
|
||||
// Initializes as a status icon window.
|
||||
bool InitializeAsStatusIcon();
|
||||
|
||||
void SetBoundsWithWmSync(const gfx::Rect& bounds_px);
|
||||
|
||||
void OnWmSynced();
|
||||
|
||||
void OnBoundsChanged(const std::optional<gfx::Rect>& old_bounds_px,
|
||||
const gfx::Rect& new_bounds_px);
|
||||
|
||||
void MaybeUpdateSyncCounter();
|
||||
|
||||
// Stores current state of this window.
|
||||
PlatformWindowState state_ = PlatformWindowState::kUnknown;
|
||||
|
||||
WindowTiledEdges tiled_state_;
|
||||
|
||||
const raw_ptr<PlatformWindowDelegate> platform_window_delegate_;
|
||||
|
||||
raw_ptr<WorkspaceExtensionDelegate, DanglingUntriaged>
|
||||
workspace_extension_delegate_ = nullptr;
|
||||
|
||||
raw_ptr<X11ExtensionDelegate, DanglingUntriaged> x11_extension_delegate_ =
|
||||
nullptr;
|
||||
|
||||
// Tells if the window got a ::Close call.
|
||||
bool is_shutting_down_ = false;
|
||||
|
||||
// The z-order level of the window; the window exhibits "always on top"
|
||||
// behavior if > 0.
|
||||
ui::ZOrderLevel z_order_ = ui::ZOrderLevel::kNormal;
|
||||
|
||||
// The bounds of our window before the window was maximized.
|
||||
gfx::Rect restored_bounds_in_pixels_;
|
||||
|
||||
std::unique_ptr<X11DesktopWindowMoveClient> x11_window_move_client_;
|
||||
|
||||
// Whether the drop handler has notified that the drag has entered.
|
||||
bool notified_enter_ = false;
|
||||
// Keeps the last negotiated operations returned by the drop handler.
|
||||
int allowed_drag_operations_ = 0;
|
||||
|
||||
// Handles XDND events going through this window.
|
||||
std::unique_ptr<XDragDropClient> drag_drop_client_;
|
||||
WmDragHandler::DragFinishedCallback drag_finished_callback_;
|
||||
raw_ptr<WmDragHandler::LocationDelegate, DanglingUntriaged>
|
||||
drag_location_delegate_ = nullptr;
|
||||
|
||||
// Run loop used while dragging from this window.
|
||||
std::unique_ptr<X11MoveLoop> drag_loop_;
|
||||
|
||||
// Events that we have selected on the source window of the incoming drag.
|
||||
x11::ScopedEventSelector source_window_events_;
|
||||
|
||||
// The display and the native X window hosting the root window.
|
||||
const raw_ref<x11::Connection> connection_;
|
||||
x11::Window xwindow_ = x11::Window::None;
|
||||
x11::Window x_root_window_ = x11::Window::None;
|
||||
|
||||
// Any native, modal dialog hanging from this window.
|
||||
x11::Window transient_window_ = x11::Window::None;
|
||||
|
||||
// Events selected on |xwindow_|.
|
||||
x11::ScopedEventSelector xwindow_events_;
|
||||
|
||||
// The window manager state bits.
|
||||
base::flat_set<x11::Atom> window_properties_;
|
||||
|
||||
// Is this window able to receive focus?
|
||||
bool activatable_ = true;
|
||||
|
||||
// Was this window initialized with the override_redirect window attribute?
|
||||
bool override_redirect_ = false;
|
||||
|
||||
std::optional<std::u16string> window_title_;
|
||||
|
||||
// Whether the window is visible with respect to Aura.
|
||||
bool window_mapped_in_client_ = false;
|
||||
|
||||
// Whether the window is mapped with respect to the X server.
|
||||
bool window_mapped_in_server_ = false;
|
||||
|
||||
// The bounds of `xwindow_`. If `bounds_wm_sync_` is active, then
|
||||
// `last_set_bounds_px_` should be treated as the current bounds. Otherwise,
|
||||
// the bounds from `geometry_cache_` should be used.
|
||||
gfx::Rect last_set_bounds_px_;
|
||||
std::unique_ptr<x11::WmSync> bounds_wm_sync_;
|
||||
std::unique_ptr<x11::GeometryCache> geometry_cache_;
|
||||
|
||||
x11::VisualId visual_id_{};
|
||||
|
||||
// Whether we used an ARGB visual for our window.
|
||||
bool visual_has_alpha_ = false;
|
||||
|
||||
// The workspace containing |xwindow_|. This will be std::nullopt when
|
||||
// _NET_WM_DESKTOP is unset.
|
||||
std::optional<int> workspace_;
|
||||
|
||||
// True if the window should stay on top of most other windows.
|
||||
bool is_always_on_top_ = false;
|
||||
|
||||
// True if the window is security-sensitive. Implies |is_always_on_top_|.
|
||||
bool is_security_surface_ = false;
|
||||
|
||||
// True if the window is fully obscured by another window.
|
||||
bool is_occluded_ = false;
|
||||
|
||||
PlatformWindowOcclusionState occlusion_state_ =
|
||||
PlatformWindowOcclusionState::kUnknown;
|
||||
|
||||
// Does |xwindow_| have the pointer grab (XI2 or normal)?
|
||||
bool has_pointer_grab_ = false;
|
||||
|
||||
// The focus-tracking state variables are as described in
|
||||
// gtk/docs/focus_tracking.txt
|
||||
//
|
||||
// |xwindow_| is active iff:
|
||||
// (|has_window_focus_| || |has_pointer_focus_|) &&
|
||||
// !|ignore_keyboard_input_|
|
||||
|
||||
// Is the pointer in |xwindow_| or one of its children?
|
||||
bool has_pointer_ = false;
|
||||
|
||||
// Is |xwindow_| or one of its children focused?
|
||||
bool has_window_focus_ = false;
|
||||
|
||||
// (An ancestor window or the PointerRoot is focused) && |has_pointer_|.
|
||||
// |has_pointer_focus_| == true is the odd case where we will receive keyboard
|
||||
// input when |has_window_focus_| == false. |has_window_focus_| and
|
||||
// |has_pointer_focus_| are mutually exclusive.
|
||||
bool has_pointer_focus_ = false;
|
||||
|
||||
// X11 does not support defocusing windows; you can only focus a different
|
||||
// window. If we would like to be defocused, we just ignore keyboard input we
|
||||
// no longer care about.
|
||||
bool ignore_keyboard_input_ = false;
|
||||
|
||||
// Used for tracking activation state in {Before|After}ActivationStateChanged.
|
||||
bool was_active_ = false;
|
||||
bool had_pointer_ = false;
|
||||
bool had_pointer_grab_ = false;
|
||||
bool had_window_focus_ = false;
|
||||
|
||||
// True if a Maximize() call should be done after mapping the window.
|
||||
bool should_maximize_after_map_ = false;
|
||||
|
||||
// True if GrabPointer() should be called after mapping the window.
|
||||
bool should_grab_pointer_after_map_ = false;
|
||||
|
||||
// Whether we currently are flashing our frame. This feature is implemented
|
||||
// by setting the urgency hint with the window manager, which can draw
|
||||
// attention to the window or completely ignore the hint. We stop flashing
|
||||
// the frame when |xwindow_| gains focus or handles a mouse button event.
|
||||
bool urgency_hint_set_ = false;
|
||||
|
||||
// |xwindow_|'s minimum size.
|
||||
gfx::Size min_size_in_pixels_;
|
||||
|
||||
// |xwindow_|'s maximum size.
|
||||
gfx::Size max_size_in_pixels_;
|
||||
|
||||
// The window shape if the window is non-rectangular.
|
||||
std::unique_ptr<std::vector<x11::Rectangle>> window_shape_;
|
||||
|
||||
// Whether |window_shape_| was set via SetShape().
|
||||
bool custom_window_shape_ = false;
|
||||
|
||||
// True if the window has title-bar / borders provided by the window manager.
|
||||
bool use_native_frame_ = false;
|
||||
|
||||
// The size of the window manager provided borders (if any).
|
||||
gfx::Insets native_window_frame_borders_in_pixels_;
|
||||
|
||||
// Used for synchronizing between `xwindow_` and the WM during resizing.
|
||||
x11::Sync::Counter update_counter_{};
|
||||
std::optional<x11::Sync::Int64> configure_counter_value_;
|
||||
std::optional<gfx::Size> last_configure_size_;
|
||||
std::optional<gfx::Size> last_swapped_size_;
|
||||
|
||||
base::CancelableOnceClosure delayed_resize_task_;
|
||||
|
||||
// Keep track of barriers to confine cursor.
|
||||
bool has_pointer_barriers_ = false;
|
||||
std::array<x11::XFixes::Barrier, 4> pointer_barriers_;
|
||||
|
||||
scoped_refptr<X11Cursor> last_cursor_;
|
||||
|
||||
base::CancelableOnceCallback<void(x11::Cursor)> on_cursor_loaded_;
|
||||
|
||||
base::WeakPtrFactory<X11Window> weak_ptr_factory_{this};
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_X11_X11_WINDOW_H_
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/platform/x11/x11_window_manager.h"
|
||||
|
||||
#include "ui/ozone/platform/x11/x11_window.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
namespace {
|
||||
|
||||
X11WindowManager* g_instance = nullptr;
|
||||
|
||||
} // namespace
|
||||
|
||||
X11WindowManager::X11WindowManager() {
|
||||
DCHECK(!g_instance) << "There should only be a single X11WindowManager";
|
||||
g_instance = this;
|
||||
}
|
||||
|
||||
X11WindowManager::~X11WindowManager() = default;
|
||||
|
||||
// static
|
||||
X11WindowManager* X11WindowManager::GetInstance() {
|
||||
if (!g_instance) {
|
||||
auto manager = std::make_unique<X11WindowManager>();
|
||||
X11WindowManager* manager_ptr = manager.release();
|
||||
DCHECK_EQ(g_instance, manager_ptr);
|
||||
}
|
||||
return g_instance;
|
||||
}
|
||||
|
||||
void X11WindowManager::GrabEvents(X11Window* window) {
|
||||
DCHECK_NE(located_events_grabber_, window);
|
||||
|
||||
// Grabbing the mouse is asynchronous. However, we synchronously start
|
||||
// forwarding all mouse events received by Chrome to the
|
||||
// aura::WindowEventDispatcher which has capture. This makes capture
|
||||
// synchronous for all intents and purposes if either:
|
||||
// - |located_events_grabber_| is set to have capture.
|
||||
// OR
|
||||
// - The topmost window underneath the mouse is managed by Chrome.
|
||||
auto* old_grabber = located_events_grabber_.get();
|
||||
|
||||
// Update |located_events_grabber_| prior to calling OnXWindowLostCapture() to
|
||||
// avoid releasing pointer grab.
|
||||
located_events_grabber_ = window;
|
||||
if (old_grabber)
|
||||
old_grabber->OnXWindowLostCapture();
|
||||
|
||||
// the X11Window calls GrabPointer by itself.
|
||||
}
|
||||
|
||||
void X11WindowManager::UngrabEvents(X11Window* window) {
|
||||
DCHECK_EQ(located_events_grabber_, window);
|
||||
// Release mouse grab asynchronously. A window managed by Chrome is likely
|
||||
// the topmost window underneath the mouse so the capture release being
|
||||
// asynchronous is likely inconsequential.
|
||||
auto* old_grabber = located_events_grabber_.get();
|
||||
located_events_grabber_ = nullptr;
|
||||
old_grabber->OnXWindowLostCapture();
|
||||
}
|
||||
|
||||
void X11WindowManager::AddWindow(X11Window* window) {
|
||||
DCHECK(window);
|
||||
auto widget = window->GetWidget();
|
||||
DCHECK_NE(gfx::kNullAcceleratedWidget, widget);
|
||||
DCHECK(!windows_.contains(widget));
|
||||
windows_.emplace(widget, window);
|
||||
}
|
||||
|
||||
void X11WindowManager::RemoveWindow(X11Window* window) {
|
||||
DCHECK(window);
|
||||
auto widget = window->GetWidget();
|
||||
auto it = windows_.find(widget);
|
||||
// The XWindow might not have been initialized due to some errors.
|
||||
if (widget == gfx::kNullAcceleratedWidget) {
|
||||
DCHECK(it == windows_.end());
|
||||
} else {
|
||||
CHECK(it != windows_.end());
|
||||
if (window_mouse_currently_on_ == it->second)
|
||||
window_mouse_currently_on_ = nullptr;
|
||||
windows_.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
X11Window* X11WindowManager::GetWindow(gfx::AcceleratedWidget widget) const {
|
||||
auto it = windows_.find(widget);
|
||||
return it != windows_.end() ? it->second : nullptr;
|
||||
}
|
||||
|
||||
void X11WindowManager::MouseOnWindow(X11Window* window) {
|
||||
if (window_mouse_currently_on_ == window)
|
||||
return;
|
||||
|
||||
window_mouse_currently_on_ = window;
|
||||
window->OnCursorUpdate();
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_X11_X11_WINDOW_MANAGER_H_
|
||||
#define UI_OZONE_PLATFORM_X11_X11_WINDOW_MANAGER_H_
|
||||
|
||||
#include "base/containers/flat_map.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "ui/gfx/native_ui_types.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
class X11Window;
|
||||
|
||||
class X11WindowManager {
|
||||
public:
|
||||
X11WindowManager();
|
||||
|
||||
X11WindowManager(const X11WindowManager&) = delete;
|
||||
X11WindowManager& operator=(const X11WindowManager&) = delete;
|
||||
|
||||
~X11WindowManager();
|
||||
|
||||
// Returns instance of X11WindowManager.
|
||||
static X11WindowManager* GetInstance();
|
||||
|
||||
// Sets a given X11Window as the recipient for events and calls
|
||||
// OnLostCapture for another |located_events_grabber_| if it has been set
|
||||
// previously.
|
||||
void GrabEvents(X11Window* window);
|
||||
|
||||
// Unsets a given X11Window as the recipient for events and calls
|
||||
// OnLostCapture.
|
||||
void UngrabEvents(X11Window* window);
|
||||
|
||||
// Gets the current X11PlatformWindow recipient of mouse events.
|
||||
X11Window* located_events_grabber() const { return located_events_grabber_; }
|
||||
|
||||
// Gets the window corresponding to the AcceleratedWidget |widget|.
|
||||
void AddWindow(X11Window* window);
|
||||
void RemoveWindow(X11Window* window);
|
||||
X11Window* GetWindow(gfx::AcceleratedWidget widget) const;
|
||||
|
||||
void MouseOnWindow(X11Window* delegate);
|
||||
|
||||
const X11Window* window_mouse_currently_on_for_test() const {
|
||||
return window_mouse_currently_on_;
|
||||
}
|
||||
|
||||
private:
|
||||
raw_ptr<X11Window> located_events_grabber_ = nullptr;
|
||||
raw_ptr<X11Window> window_mouse_currently_on_ = nullptr;
|
||||
|
||||
base::flat_map<gfx::AcceleratedWidget, raw_ptr<X11Window, CtnExperimental>>
|
||||
windows_;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_X11_X11_WINDOW_MANAGER_H_
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright 2015 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PUBLIC_OVERLAY_MANAGER_OZONE_H_
|
||||
#define UI_OZONE_PUBLIC_OVERLAY_MANAGER_OZONE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ui/gfx/native_ui_types.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
class OverlayCandidatesOzone;
|
||||
|
||||
// Responsible for providing the oracles used to decide when overlays can be
|
||||
// used.
|
||||
class OverlayManagerOzone {
|
||||
public:
|
||||
virtual ~OverlayManagerOzone() {}
|
||||
|
||||
// Get the hal struct to check for overlay support.
|
||||
virtual std::unique_ptr<OverlayCandidatesOzone> CreateOverlayCandidates(
|
||||
gfx::AcceleratedWidget w) = 0;
|
||||
|
||||
bool allow_sync_and_real_buffer_page_flip_testing() const {
|
||||
return allow_sync_and_real_buffer_page_flip_testing_;
|
||||
}
|
||||
|
||||
// Tell the manager that the overlay delegation is enabled. This is only
|
||||
// useful for Wayland as checking for overlay support depends on
|
||||
// features::IsDelegatedCompositingEnabled, which cannot be accessed from
|
||||
// //ui/ozone.
|
||||
// TODO(msisov, petermcneeley): remove this once Wayland uses only delegated
|
||||
// context.
|
||||
virtual void SetContextDelegated() {}
|
||||
|
||||
protected:
|
||||
// TODO(fangzhoug): Some Chrome OS boards still use the legacy video decoder.
|
||||
// Remove this once ChromeOSVideoDecoder is on everywhere.
|
||||
bool allow_sync_and_real_buffer_page_flip_testing_ = false;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PUBLIC_OVERLAY_MANAGER_OZONE_H_
|
||||
@@ -0,0 +1,70 @@
|
||||
dbus-glib
|
||||
elementary-icon-theme
|
||||
exo
|
||||
garcon
|
||||
gnome-themes-extra
|
||||
gtk-layer-shell
|
||||
gtksourceview4
|
||||
libburn
|
||||
libgtop
|
||||
libisofs
|
||||
libkeybinder3
|
||||
libmpd
|
||||
libwnck3
|
||||
libxfce4ui
|
||||
libxfce4util
|
||||
libxfce4windowing
|
||||
libxklavier
|
||||
libxres
|
||||
mousepad
|
||||
parole
|
||||
polkit-gnome
|
||||
ristretto
|
||||
thunar
|
||||
thunar-archive-plugin
|
||||
thunar-media-tags-plugin
|
||||
thunar-volman
|
||||
tumbler
|
||||
xfburn
|
||||
xfce4-appfinder
|
||||
xfce4-battery-plugin
|
||||
xfce4-clipman-plugin
|
||||
xfce4-cpufreq-plugin
|
||||
xfce4-cpugraph-plugin
|
||||
xfce4-dict
|
||||
xfce4-diskperf-plugin
|
||||
xfce4-eyes-plugin
|
||||
xfce4-fsguard-plugin
|
||||
xfce4-genmon-plugin
|
||||
xfce4-mailwatch-plugin
|
||||
xfce4-mount-plugin
|
||||
xfce4-mpc-plugin
|
||||
xfce4-netload-plugin
|
||||
xfce4-notes-plugin
|
||||
xfce4-notifyd
|
||||
xfce4-panel
|
||||
xfce4-places-plugin
|
||||
xfce4-power-manager
|
||||
xfce4-pulseaudio-plugin
|
||||
xfce4-screensaver
|
||||
xfce4-screenshooter
|
||||
xfce4-sensors-plugin
|
||||
xfce4-session
|
||||
xfce4-settings
|
||||
xfce4-smartbookmark-plugin
|
||||
xfce4-systemload-plugin
|
||||
xfce4-taskmanager
|
||||
xfce4-terminal
|
||||
xfce4-time-out-plugin
|
||||
xfce4-timer-plugin
|
||||
xfce4-verve-plugin
|
||||
xfce4-wavelan-plugin
|
||||
xfce4-weather-plugin
|
||||
xfce4-whiskermenu-plugin
|
||||
xfce4-xkb-plugin
|
||||
xfconf
|
||||
xfdesktop
|
||||
xfwm4
|
||||
xorg-iceauth
|
||||
xorg-xinit
|
||||
xorg-xmodmap
|
||||
@@ -0,0 +1,227 @@
|
||||
:: There are 14 members in group xfce4:
|
||||
:: Repository extra
|
||||
1) exo 2) garcon 3) thunar 4) thunar-volman 5) tumbler 6) xfce4-appfinder 7) xfce4-panel 8) xfce4-power-manager 9) xfce4-session 10) xfce4-settings 11) xfce4-terminal 12) xfconf 13) xfdesktop 14) xfwm4
|
||||
|
||||
Enter a selection (default=all):
|
||||
:: There are 36 members in group xfce4-goodies:
|
||||
:: Repository extra
|
||||
1) mousepad 2) parole 3) ristretto 4) thunar-archive-plugin 5) thunar-media-tags-plugin 6) xfburn 7) xfce4-battery-plugin 8) xfce4-clipman-plugin 9) xfce4-cpufreq-plugin 10) xfce4-cpugraph-plugin 11) xfce4-dict 12) xfce4-diskperf-plugin 13) xfce4-eyes-plugin 14) xfce4-fsguard-plugin 15) xfce4-genmon-plugin 16) xfce4-mailwatch-plugin 17) xfce4-mount-plugin 18) xfce4-mpc-plugin 19) xfce4-netload-plugin 20) xfce4-notes-plugin 21) xfce4-notifyd 22) xfce4-places-plugin 23) xfce4-pulseaudio-plugin 24) xfce4-screensaver 25) xfce4-screenshooter 26) xfce4-sensors-plugin 27) xfce4-smartbookmark-plugin 28) xfce4-systemload-plugin 29) xfce4-taskmanager 30) xfce4-time-out-plugin 31) xfce4-timer-plugin 32) xfce4-verve-plugin 33) xfce4-wavelan-plugin 34) xfce4-weather-plugin 35) xfce4-whiskermenu-plugin 36) xfce4-xkb-plugin
|
||||
|
||||
Enter a selection (default=all):
|
||||
resolving dependencies...
|
||||
looking for conflicting packages...
|
||||
|
||||
Packages (70) dbus-glib-0.114-1 elementary-icon-theme-8.2.0-1 gnome-themes-extra-1:3.28-1 gtk-layer-shell-0.10.1-1 gtksourceview4-4.8.4-2 libburn-1.5.8-1 libgtop-2.41.3-2 libisofs-1.5.8.1-1 libkeybinder3-0.3.2-5 libmpd-11.8.17-7 libwnck3-43.3-1 libxfce4ui-4.20.2-1 libxfce4util-4.20.1-1 libxfce4windowing-4.20.5-3 libxklavier-5.4-7 libxres-1.2.3-1 polkit-gnome-0.105-12 xorg-iceauth-1.0.11-1 xorg-xinit-1.4.4-1 xorg-xmodmap-1.0.11-2 exo-4.20.0-2 garcon-4.20.0-2 mousepad-0.7.0-1 parole-4.20.0-1 ristretto-0.14.0-1 thunar-4.20.8-3 thunar-archive-plugin-0.6.0-1 thunar-media-tags-plugin-0.6.0-1 thunar-volman-4.20.0-2 tumbler-4.20.1-1 xfburn-0.8.0-1 xfce4-appfinder-4.20.0-2 xfce4-battery-plugin-1.2.0-1 xfce4-clipman-plugin-1.7.0-1 xfce4-cpufreq-plugin-1.3.0-1 xfce4-cpugraph-plugin-1.3.0-1 xfce4-dict-0.8.9-1 xfce4-diskperf-plugin-2.8.0-2 xfce4-eyes-plugin-4.7.0-1 xfce4-fsguard-plugin-1.2.0-1 xfce4-genmon-plugin-4.3.0-1 xfce4-mailwatch-plugin-1.4.0-1 xfce4-mount-plugin-1.2.0-1 xfce4-mpc-plugin-0.6.0-1 xfce4-netload-plugin-1.5.0-1 xfce4-notes-plugin-1.12.0-1 xfce4-notifyd-0.9.7-2 xfce4-panel-4.20.7-1 xfce4-places-plugin-1.9.0-1 xfce4-power-manager-4.20.0-3 xfce4-pulseaudio-plugin-0.5.1-1 xfce4-screensaver-4.20.2-1 xfce4-screenshooter-1.11.3-3 xfce4-sensors-plugin-1.4.5-1 xfce4-session-4.20.4-1 xfce4-settings-4.20.4-1 xfce4-smartbookmark-plugin-0.6.0-2 xfce4-systemload-plugin-1.4.0-1 xfce4-taskmanager-1.6.0-1 xfce4-terminal-1.2.0-1 xfce4-time-out-plugin-1.2.0-1 xfce4-timer-plugin-1.8.0-1 xfce4-verve-plugin-2.1.0-1 xfce4-wavelan-plugin-0.7.0-2 xfce4-weather-plugin-0.12.0-2 xfce4-whiskermenu-plugin-2.10.1-2 xfce4-xkb-plugin-0.9.0-1 xfconf-4.20.0-2 xfdesktop-4.20.2-1 xfwm4-4.20.0-2
|
||||
|
||||
Total Download Size: 22.20 MiB
|
||||
Total Installed Size: 136.65 MiB
|
||||
|
||||
:: Proceed with installation? [Y/n]
|
||||
:: Retrieving packages...
|
||||
elementary-icon-theme-8.2.0-1-any downloading...
|
||||
gnome-themes-extra-1:3.28-1-any downloading...
|
||||
xfce4-weather-plugin-0.12.0-2-aarch64 downloading...
|
||||
thunar-4.20.8-3-aarch64 downloading...
|
||||
xfdesktop-4.20.2-1-aarch64 downloading...
|
||||
gtksourceview4-4.8.4-2-aarch64 downloading...
|
||||
xfce4-settings-4.20.4-1-aarch64 downloading...
|
||||
xfce4-panel-4.20.7-1-aarch64 downloading...
|
||||
xfce4-power-manager-4.20.0-3-aarch64 downloading...
|
||||
xfwm4-4.20.0-2-aarch64 downloading...
|
||||
mousepad-0.7.0-1-aarch64 downloading...
|
||||
xfburn-0.8.0-1-aarch64 downloading...
|
||||
xfce4-terminal-1.2.0-1-aarch64 downloading...
|
||||
libwnck3-43.3-1-aarch64 downloading...
|
||||
libxfce4ui-4.20.2-1-aarch64 downloading...
|
||||
xfce4-session-4.20.4-1-aarch64 downloading...
|
||||
parole-4.20.0-1-aarch64 downloading...
|
||||
exo-4.20.0-2-aarch64 downloading...
|
||||
xfce4-xkb-plugin-0.9.0-1-aarch64 downloading...
|
||||
libburn-1.5.8-1-aarch64 downloading...
|
||||
libisofs-1.5.8.1-1-aarch64 downloading...
|
||||
ristretto-0.14.0-1-aarch64 downloading...
|
||||
xfce4-screensaver-4.20.2-1-aarch64 downloading...
|
||||
xfce4-whiskermenu-plugin-2.10.1-2-aarch64 downloading...
|
||||
xfce4-notifyd-0.9.7-2-aarch64 downloading...
|
||||
libgtop-2.41.3-2-aarch64 downloading...
|
||||
xfce4-sensors-plugin-1.4.5-1-aarch64 downloading...
|
||||
xfconf-4.20.0-2-aarch64 downloading...
|
||||
xfce4-clipman-plugin-1.7.0-1-aarch64 downloading...
|
||||
xfce4-dict-0.8.9-1-aarch64 downloading...
|
||||
tumbler-4.20.1-1-aarch64 downloading...
|
||||
xfce4-appfinder-4.20.0-2-aarch64 downloading...
|
||||
libxfce4windowing-4.20.5-3-aarch64 downloading...
|
||||
garcon-4.20.0-2-aarch64 downloading...
|
||||
xfce4-mailwatch-plugin-1.4.0-1-aarch64 downloading...
|
||||
xfce4-screenshooter-1.11.3-3-aarch64 downloading...
|
||||
xfce4-notes-plugin-1.12.0-1-aarch64 downloading...
|
||||
libxfce4util-4.20.1-1-aarch64 downloading...
|
||||
dbus-glib-0.114-1-aarch64 downloading...
|
||||
thunar-volman-4.20.0-2-aarch64 downloading...
|
||||
xfce4-taskmanager-1.6.0-1-aarch64 downloading...
|
||||
xfce4-cpugraph-plugin-1.3.0-1-aarch64 downloading...
|
||||
xfce4-pulseaudio-plugin-0.5.1-1-aarch64 downloading...
|
||||
xfce4-cpufreq-plugin-1.3.0-1-aarch64 downloading...
|
||||
xfce4-battery-plugin-1.2.0-1-aarch64 downloading...
|
||||
xfce4-mount-plugin-1.2.0-1-aarch64 downloading...
|
||||
libxklavier-5.4-7-aarch64 downloading...
|
||||
xfce4-fsguard-plugin-1.2.0-1-aarch64 downloading...
|
||||
xfce4-places-plugin-1.9.0-1-aarch64 downloading...
|
||||
gtk-layer-shell-0.10.1-1-aarch64 downloading...
|
||||
xfce4-genmon-plugin-4.3.0-1-aarch64 downloading...
|
||||
thunar-media-tags-plugin-0.6.0-1-aarch64 downloading...
|
||||
polkit-gnome-0.105-12-aarch64 downloading...
|
||||
xfce4-timer-plugin-1.8.0-1-aarch64 downloading...
|
||||
xfce4-time-out-plugin-1.2.0-1-aarch64 downloading...
|
||||
xfce4-diskperf-plugin-2.8.0-2-aarch64 downloading...
|
||||
xfce4-systemload-plugin-1.4.0-1-aarch64 downloading...
|
||||
xfce4-netload-plugin-1.5.0-1-aarch64 downloading...
|
||||
libmpd-11.8.17-7-aarch64 downloading...
|
||||
xfce4-eyes-plugin-4.7.0-1-aarch64 downloading...
|
||||
xfce4-verve-plugin-2.1.0-1-aarch64 downloading...
|
||||
xfce4-mpc-plugin-0.6.0-1-aarch64 downloading...
|
||||
thunar-archive-plugin-0.6.0-1-aarch64 downloading...
|
||||
xfce4-wavelan-plugin-0.7.0-2-aarch64 downloading...
|
||||
xfce4-smartbookmark-plugin-0.6.0-2-aarch64 downloading...
|
||||
xorg-xmodmap-1.0.11-2-aarch64 downloading...
|
||||
libkeybinder3-0.3.2-5-aarch64 downloading...
|
||||
xorg-xinit-1.4.4-1-aarch64 downloading...
|
||||
xorg-iceauth-1.0.11-1-aarch64 downloading...
|
||||
libxres-1.2.3-1-aarch64 downloading...
|
||||
checking keyring...
|
||||
checking package integrity...
|
||||
loading package files...
|
||||
checking for file conflicts...
|
||||
:: Processing package changes...
|
||||
installing libxfce4util...
|
||||
installing xfconf...
|
||||
installing libgtop...
|
||||
installing libxfce4ui...
|
||||
installing exo...
|
||||
installing garcon...
|
||||
installing thunar...
|
||||
Optional dependencies for thunar
|
||||
catfish: file searching
|
||||
gvfs: trash support, mounting with udisk and remote filesystems
|
||||
tumbler: thumbnail previews [pending]
|
||||
thunar-volman: removable device management [pending]
|
||||
thunar-archive-plugin: archive creation and extraction [pending]
|
||||
thunar-media-tags-plugin: view/edit ID3/OGG tags [pending]
|
||||
installing thunar-volman...
|
||||
installing tumbler...
|
||||
Optional dependencies for tumbler
|
||||
ffmpegthumbnailer: video thumbnails
|
||||
poppler-glib: PDF thumbnails
|
||||
libgsf: ODF thumbnails
|
||||
libgepub: EPUB thumbnails
|
||||
libopenraw: RAW thumbnails
|
||||
freetype2: font thumbnails [installed]
|
||||
installing xfce4-appfinder...
|
||||
installing gtk-layer-shell...
|
||||
installing libxres...
|
||||
installing libwnck3...
|
||||
installing libxfce4windowing...
|
||||
installing xfce4-panel...
|
||||
installing xfce4-notifyd...
|
||||
installing xfce4-power-manager...
|
||||
installing xorg-iceauth...
|
||||
installing xorg-xmodmap...
|
||||
installing xorg-xinit...
|
||||
Optional dependencies for xorg-xinit
|
||||
xorg-twm
|
||||
xterm
|
||||
installing polkit-gnome...
|
||||
installing xfce4-session...
|
||||
Optional dependencies for xfce4-session
|
||||
gnome-keyring: for keyring support when GNOME compatibility is enabled
|
||||
xfce4-screensaver: for locking screen with xflock4 [pending]
|
||||
xscreensaver: for locking screen with xflock4
|
||||
light-locker: for locking screen with xflock4
|
||||
labwc: recommended compositor for the experimental Wayland session
|
||||
installing libxklavier...
|
||||
installing elementary-icon-theme...
|
||||
installing gnome-themes-extra...
|
||||
installing xfce4-settings...
|
||||
Optional dependencies for xfce4-settings
|
||||
python: xfce4-compose-mail -- "mailto:" URI handling [installed]
|
||||
xiccd: for displays support in xfce4-color-settings
|
||||
cups: for printers support in xfce4-color-settings [installed]
|
||||
sane: for scanners support in xfce4-color-settings
|
||||
installing xfce4-terminal...
|
||||
installing xfdesktop...
|
||||
installing xfwm4...
|
||||
installing gtksourceview4...
|
||||
installing mousepad...
|
||||
Optional dependencies for mousepad
|
||||
gspell: spell checking plugin
|
||||
libxfce4ui: shortcuts editor plugin [installed]
|
||||
installing dbus-glib...
|
||||
installing parole...
|
||||
Optional dependencies for parole
|
||||
gst-libav: Extra media codecs
|
||||
gst-plugins-bad: Extra media codecs [installed]
|
||||
gst-plugins-ugly: Extra media codecs
|
||||
installing ristretto...
|
||||
installing thunar-archive-plugin...
|
||||
Optional dependencies for thunar-archive-plugin
|
||||
file-roller
|
||||
engrampa
|
||||
ark [installed]
|
||||
xarchiver
|
||||
installing thunar-media-tags-plugin...
|
||||
installing libburn...
|
||||
installing libisofs...
|
||||
installing xfburn...
|
||||
installing xfce4-battery-plugin...
|
||||
installing xfce4-clipman-plugin...
|
||||
installing xfce4-cpufreq-plugin...
|
||||
installing xfce4-cpugraph-plugin...
|
||||
installing xfce4-dict...
|
||||
installing xfce4-diskperf-plugin...
|
||||
installing xfce4-eyes-plugin...
|
||||
installing xfce4-fsguard-plugin...
|
||||
installing xfce4-genmon-plugin...
|
||||
installing xfce4-mailwatch-plugin...
|
||||
installing xfce4-mount-plugin...
|
||||
installing libmpd...
|
||||
installing xfce4-mpc-plugin...
|
||||
installing xfce4-netload-plugin...
|
||||
installing xfce4-notes-plugin...
|
||||
installing xfce4-places-plugin...
|
||||
installing libkeybinder3...
|
||||
Optional dependencies for libkeybinder3
|
||||
lua-lgi: lua bindings
|
||||
installing xfce4-pulseaudio-plugin...
|
||||
Optional dependencies for xfce4-pulseaudio-plugin
|
||||
pavucontrol: default pulseaudio mixer
|
||||
installing xfce4-screensaver...
|
||||
Optional dependencies for xfce4-screensaver
|
||||
onboard: on screen keyboard for unlocking
|
||||
xscreensaver: additional themes
|
||||
installing xfce4-screenshooter...
|
||||
installing xfce4-sensors-plugin...
|
||||
Optional dependencies for xfce4-sensors-plugin
|
||||
hddtemp: for monitoring the temperature of hard drives
|
||||
installing xfce4-smartbookmark-plugin...
|
||||
installing xfce4-systemload-plugin...
|
||||
installing xfce4-taskmanager...
|
||||
installing xfce4-time-out-plugin...
|
||||
installing xfce4-timer-plugin...
|
||||
installing xfce4-verve-plugin...
|
||||
installing xfce4-wavelan-plugin...
|
||||
installing xfce4-weather-plugin...
|
||||
installing xfce4-whiskermenu-plugin...
|
||||
Optional dependencies for xfce4-whiskermenu-plugin
|
||||
mugshot: Update user details
|
||||
installing xfce4-xkb-plugin...
|
||||
Optional dependencies for xfce4-xkb-plugin
|
||||
xfce4-notifyd: show notifications on layout change [installed]
|
||||
:: Running post-transaction hooks...
|
||||
(1/8) Reloading user manager configuration...
|
||||
(2/8) Arming ConditionNeedsUpdate...
|
||||
(3/8) Refreshing PackageKit...
|
||||
(4/8) Updating GIO module cache...
|
||||
(5/8) Compiling GSettings XML schema files...
|
||||
(6/8) Updating icon theme caches...
|
||||
(7/8) Updating the info directory file...
|
||||
(8/8) Updating the desktop file MIME type cache...
|
||||
@@ -0,0 +1,30 @@
|
||||
resolving dependencies...
|
||||
looking for conflicting packages...
|
||||
|
||||
Packages (2) mailcap-2.1.54-2 firefox-150.0.1-1
|
||||
|
||||
Total Download Size: 63.40 MiB
|
||||
Total Installed Size: 256.95 MiB
|
||||
|
||||
:: Proceed with installation? [Y/n]
|
||||
:: Retrieving packages...
|
||||
firefox-150.0.1-1-aarch64 downloading...
|
||||
mailcap-2.1.54-2-any downloading...
|
||||
checking keyring...
|
||||
checking package integrity...
|
||||
loading package files...
|
||||
checking for file conflicts...
|
||||
:: Processing package changes...
|
||||
installing mailcap...
|
||||
installing firefox...
|
||||
Optional dependencies for firefox
|
||||
hunspell-en_US: Spell checking, American English
|
||||
libnotify: Notification integration [installed]
|
||||
networkmanager: Location detection via available WiFi networks [installed]
|
||||
speech-dispatcher: Text-to-Speech
|
||||
xdg-desktop-portal: Screensharing with Wayland [installed]
|
||||
:: Running post-transaction hooks...
|
||||
(1/4) Arming ConditionNeedsUpdate...
|
||||
(2/4) Refreshing PackageKit...
|
||||
(3/4) Updating icon theme caches...
|
||||
(4/4) Updating the desktop file MIME type cache...
|
||||
@@ -0,0 +1,20 @@
|
||||
loading packages...
|
||||
resolving dependencies...
|
||||
looking for conflicting packages...
|
||||
|
||||
Packages (1) xtrace-1.4.0-2
|
||||
|
||||
Total Installed Size: 0.31 MiB
|
||||
|
||||
:: Proceed with installation? [Y/n]
|
||||
checking keyring...
|
||||
checking package integrity...
|
||||
loading package files...
|
||||
checking for file conflicts...
|
||||
:: Processing package changes...
|
||||
installing xtrace...
|
||||
Optional dependencies for xtrace
|
||||
xorg-xauth [installed]
|
||||
:: Running post-transaction hooks...
|
||||
(1/2) Arming ConditionNeedsUpdate...
|
||||
(2/2) Refreshing PackageKit...
|
||||
@@ -0,0 +1,47 @@
|
||||
resolving dependencies...
|
||||
looking for conflicting packages...
|
||||
|
||||
Packages (11) libadwaita-1:1.9.0-1 libdex-1.1.0-1 libpanel-1.10.4-1 startup-notification-0.12-9 openbox-3.6.1-14 sysprof-50.0-2 xorg-xev-1.2.6-2 xorg-xinput-1.6.4-2 xorg-xkill-1.0.7-1 xorg-xrandr-1.5.4-1 xorg-xwininfo-1.1.6-2
|
||||
|
||||
Total Download Size: 2.31 MiB
|
||||
Total Installed Size: 16.01 MiB
|
||||
|
||||
:: Proceed with installation? [Y/n]
|
||||
:: Retrieving packages...
|
||||
sysprof-50.0-2-aarch64 downloading...
|
||||
libadwaita-1:1.9.0-1-aarch64 downloading...
|
||||
openbox-3.6.1-14-aarch64 downloading...
|
||||
libpanel-1.10.4-1-aarch64 downloading...
|
||||
libdex-1.1.0-1-aarch64 downloading...
|
||||
xorg-xrandr-1.5.4-1-aarch64 downloading...
|
||||
xorg-xinput-1.6.4-2-aarch64 downloading...
|
||||
xorg-xwininfo-1.1.6-2-aarch64 downloading...
|
||||
startup-notification-0.12-9-aarch64 downloading...
|
||||
xorg-xev-1.2.6-2-aarch64 downloading...
|
||||
xorg-xkill-1.0.7-1-aarch64 downloading...
|
||||
checking keyring...
|
||||
checking package integrity...
|
||||
loading package files...
|
||||
checking for file conflicts...
|
||||
:: Processing package changes...
|
||||
installing xorg-xrandr...
|
||||
installing xorg-xev...
|
||||
installing xorg-xinput...
|
||||
installing xorg-xwininfo...
|
||||
installing xorg-xkill...
|
||||
installing libadwaita...
|
||||
installing libdex...
|
||||
installing libpanel...
|
||||
installing sysprof...
|
||||
installing startup-notification...
|
||||
installing openbox...
|
||||
Optional dependencies for openbox
|
||||
python-pyxdg: for the openbox-xdg-autostart script
|
||||
:: Running post-transaction hooks...
|
||||
(1/7) Reloading system manager configuration...
|
||||
(2/7) Updating the MIME type database...
|
||||
(3/7) Arming ConditionNeedsUpdate...
|
||||
(4/7) Refreshing PackageKit...
|
||||
(5/7) Reloading system bus configuration...
|
||||
(6/7) Updating icon theme caches...
|
||||
(7/7) Updating the desktop file MIME type cache...
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,483 @@
|
||||
# revert.log — campaign-installed state on ohm
|
||||
|
||||
This file lists every change this campaign made to ohm's *system
|
||||
state* during Phase 0 inventory work that was done **purely for
|
||||
testing and analysis**. To return ohm to the state it was in
|
||||
before this campaign opened, run the "Revert" commands at the
|
||||
bottom of this file in order.
|
||||
|
||||
This file is updated whenever the campaign installs a package or
|
||||
mutates a sysctl/service/config. Closing the campaign without
|
||||
reverting is a deliberate operator decision; if reverted, this
|
||||
file is the authoritative record of what to undo.
|
||||
|
||||
Inherited state from the predecessor (`kwin_overlay_subsurface`)
|
||||
is **not** in scope here — those carry-overs are documented in
|
||||
`README.md` § "Carry-overs from predecessor (system state, not
|
||||
data)" and would be reverted via that campaign's
|
||||
`phase1_evidence/ohm_tooling_revert_log.md` instead.
|
||||
|
||||
---
|
||||
|
||||
## Entry 1 — 2026-05-03 ~09:20 CEST
|
||||
|
||||
**Trigger:** Phase 0 deliverables 2 + 4 (`x11_inventory_2026-05-03/inventory.md`)
|
||||
identified missing measurement tools and the absence of a
|
||||
non-compositing WM. Operator instructed: "fire the installs."
|
||||
|
||||
**Driven from:** `mfritsche@noether` over SSH to `ohm.fritz.box`,
|
||||
passwordless `sudo` (verified before firing).
|
||||
|
||||
**Pre-install snapshot:** `pkglist.pre.txt` (1169 packages,
|
||||
sha256 `fd72bcf6a7289d2f2dd6ce02706240006b534731540bf63f56ee9b666e7be68f`).
|
||||
**Post-install snapshot:** `pkglist.post.txt` (1180 packages).
|
||||
**Full pacman transaction log:** `pacman.install.log`.
|
||||
|
||||
### What was installed
|
||||
|
||||
Single transaction: `sudo pacman -Sy && sudo pacman -S --needed
|
||||
xorg-xrandr xorg-xev xorg-xinput xorg-xwininfo xorg-xkill sysprof openbox`
|
||||
|
||||
| Package | Version | Reason |
|
||||
|---|---|---|
|
||||
| xorg-xrandr | 1.5.4-1 | explicit — RandR CLI for output/vblank probing |
|
||||
| xorg-xev | 1.2.6-2 | explicit — per-window event capture |
|
||||
| xorg-xinput | 1.6.4-2 | explicit — input-device probe (touchscreen confound) |
|
||||
| xorg-xwininfo | 1.1.6-2 | explicit — get browser window geometry/wid |
|
||||
| xorg-xkill | 1.0.7-1 | explicit — clean kill of stuck X clients between reps |
|
||||
| sysprof | 50.0-2 | explicit — kernel perf alternative w/ flamegraph default |
|
||||
| openbox | 3.6.1-14 | explicit — non-compositing WM for the without-KWin matrix cell |
|
||||
| libadwaita | 1:1.9.0-1 | dep of sysprof |
|
||||
| libdex | 1.1.0-1 | dep of sysprof |
|
||||
| libpanel | 1.10.4-1 | dep of sysprof |
|
||||
| startup-notification | 0.12-9 | dep of openbox |
|
||||
|
||||
11 added, 0 removed. Cross-checked via `comm -13
|
||||
pkglist.pre.txt pkglist.post.txt` — exact same 11.
|
||||
|
||||
### What was changed (config, not packages)
|
||||
|
||||
- **`/etc/sysctl.d/90-x11-research-perf.conf` was created with
|
||||
`kernel.perf_event_paranoid = 1`, then reverted same session.**
|
||||
- Created: applied via `sudo sysctl --system`; effective
|
||||
value went 2 → 1.
|
||||
- Verification probe revealed the tweak was **not delivering
|
||||
the promised behavior**: even with `task-clock` (a software
|
||||
event that should be allowed at paranoid=1), `perf record
|
||||
-p <Xorg_pid>` on this aarch64 kernel still failed with
|
||||
"Failure to open any events for recording". Predecessor
|
||||
pattern confirmed in
|
||||
`kwin_overlay_subsurface/phase3_protocol.md:121,158,216`:
|
||||
they used **`sudo perf record`** per-rep, not a sysctl
|
||||
tweak. Passwordless sudo over SSH already works on ohm so
|
||||
this is unattended-friendly.
|
||||
- Reverted: `sudo rm /etc/sysctl.d/90-x11-research-perf.conf`
|
||||
and `sudo sysctl kernel.perf_event_paranoid=2` (the
|
||||
`--system` reapply does not reset removed-file values; an
|
||||
explicit set was required).
|
||||
- Net state change: **none** (paranoid back at kernel
|
||||
default 2; `/etc/sysctl.d/` empty again).
|
||||
- Lesson: the inventory's "set paranoid=1" recommendation
|
||||
was wrong. Updated `inventory.md` will reflect that the
|
||||
actual pattern is `sudo perf record -p <pid>` per-rep.
|
||||
|
||||
### What was created as a side effect (no operator action)
|
||||
|
||||
- `/usr/share/xsessions/openbox.desktop` (shipped by the
|
||||
`openbox` package). SDDM will list "Openbox" as a session
|
||||
choice on next greet. Removing the openbox package removes
|
||||
the .desktop file.
|
||||
|
||||
### What was *not* installed (deliberate, operator-decision-pending)
|
||||
|
||||
- **firefox** — 2 of the 6 matrix cells reference Firefox
|
||||
(`C-W-ff-*`, `C-X-ff-*`). Operator decides whether to install
|
||||
or to mark those cells N/A. If installed later, append a new
|
||||
entry below.
|
||||
- **xtrace (X protocol tracer, AUR)** — explicitly marked
|
||||
optional in `inventory.md`. The matrix's primary metrics
|
||||
(effective_fps / drops / latency / CPU%) don't require it.
|
||||
If installed later, append a new entry below.
|
||||
|
||||
---
|
||||
|
||||
## Entry 2 — 2026-05-03 ~09:30 CEST
|
||||
|
||||
**Trigger:** Operator preference for a desktop-environment-flavored
|
||||
without-KWin testbed alongside the bare openbox cell ("I like
|
||||
desktop environments. With respect to the test - should xfce or
|
||||
cinnamon be our test bed?" → "yes add xfce with goodies").
|
||||
Cinnamon was excluded because Muffin is a mandatory compositor;
|
||||
XFCE qualifies if `xfwm4`'s built-in compositor is left disabled.
|
||||
|
||||
**Driven from:** `mfritsche@noether` over SSH to `ohm.fritz.box`,
|
||||
passwordless `sudo`.
|
||||
|
||||
**Pre-install snapshot:** `pkglist.entry2.pre.txt` (1180 packages,
|
||||
sha256 `1f72c7ed2f9d476d24d0dfb53fcb387ea39f882c89375d68fc21298313252d78`).
|
||||
**Post-install snapshot:** `pkglist.entry2.post.txt` (1250 packages).
|
||||
**Full pacman transaction log:** `pacman.entry2.log`.
|
||||
|
||||
### What was installed
|
||||
|
||||
Single transaction: `sudo pacman -S --needed xfce4 xfce4-goodies`
|
||||
(both are package groups; pacman expanded them).
|
||||
|
||||
- **50 explicit packages** (the union of the `xfce4` group's 14
|
||||
members and the `xfce4-goodies` group's 36 members):
|
||||
exo, garcon, mousepad, parole, ristretto, thunar, thunar-archive-plugin,
|
||||
thunar-media-tags-plugin, thunar-volman, tumbler, xfburn,
|
||||
xfce4-appfinder, xfce4-battery-plugin, xfce4-clipman-plugin,
|
||||
xfce4-cpufreq-plugin, xfce4-cpugraph-plugin, xfce4-dict,
|
||||
xfce4-diskperf-plugin, xfce4-eyes-plugin, xfce4-fsguard-plugin,
|
||||
xfce4-genmon-plugin, xfce4-mailwatch-plugin, xfce4-mount-plugin,
|
||||
xfce4-mpc-plugin, xfce4-netload-plugin, xfce4-notes-plugin,
|
||||
xfce4-notifyd, xfce4-panel, xfce4-places-plugin,
|
||||
xfce4-power-manager, xfce4-pulseaudio-plugin, xfce4-screensaver,
|
||||
xfce4-screenshooter, xfce4-sensors-plugin, xfce4-session,
|
||||
xfce4-settings, xfce4-smartbookmark-plugin, xfce4-systemload-plugin,
|
||||
xfce4-taskmanager, xfce4-terminal, xfce4-time-out-plugin,
|
||||
xfce4-timer-plugin, xfce4-verve-plugin, xfce4-wavelan-plugin,
|
||||
xfce4-weather-plugin, xfce4-whiskermenu-plugin, xfce4-xkb-plugin,
|
||||
xfconf, xfdesktop, xfwm4
|
||||
- **20 transitive deps**:
|
||||
dbus-glib, elementary-icon-theme, gnome-themes-extra,
|
||||
gtk-layer-shell, gtksourceview4, libburn, libgtop, libisofs,
|
||||
libkeybinder3, libmpd, libwnck3, libxfce4ui, libxfce4util,
|
||||
libxfce4windowing, libxklavier, libxres, polkit-gnome,
|
||||
xorg-iceauth, xorg-xinit, xorg-xmodmap
|
||||
|
||||
70 added, 0 removed. Cross-checked via
|
||||
`comm -13 pkglist.entry2.pre.txt pkglist.entry2.post.txt` — full
|
||||
list in `entry2.added.list` (sourced from same diff).
|
||||
|
||||
### What was changed (config)
|
||||
|
||||
- **`~/.config/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml` created**
|
||||
(208 bytes), pre-seeding `general/use_compositing = false`. This
|
||||
ensures the **first XFCE login lands with xfwm4's built-in GL
|
||||
compositor disabled**, matching the matrix's "without-KWin =
|
||||
no compositor in the display path" definition. Without this
|
||||
pre-seed, `xfwm4` would default to `use_compositing=true` and
|
||||
the operator would have to remember to toggle it via *Settings
|
||||
→ Window Manager Tweaks → Compositor* before every measurement
|
||||
rep — a confound waiting to happen.
|
||||
|
||||
The directory tree `~/.config/xfce4/` did not exist before this
|
||||
write; the entire tree is removable.
|
||||
|
||||
### What was created as a side effect (no operator action)
|
||||
|
||||
- `/usr/share/xsessions/xfce.desktop` (shipped by `xfce4-session`).
|
||||
SDDM now lists three X11 sessions: openbox.desktop (entry 1),
|
||||
plasmax11.desktop (pre-existing), xfce.desktop (this entry).
|
||||
|
||||
### After-revert verification
|
||||
|
||||
The first-login compositor pre-seed is per-user state in
|
||||
`~/.config/xfce4/`. The revert procedure deletes the entire
|
||||
xfce4 user-config tree if (and only if) it contains nothing but
|
||||
the pre-seeded xfwm4.xml. If the operator logs into XFCE before
|
||||
revert, xfconfd will populate that tree with other settings
|
||||
files; the revert then becomes a manual decision.
|
||||
|
||||
---
|
||||
|
||||
## Entry 3 — 2026-05-03 ~09:45 CEST
|
||||
|
||||
**Trigger:** Operator instructed "install both" — closing the two
|
||||
operator-decision items left open in entry 1's "What was *not*
|
||||
installed" section: firefox (matrix completeness — 2 of 6 cells
|
||||
need it) and the X-protocol tracer xtrace.
|
||||
|
||||
**Driven from:** `mfritsche@noether` over SSH to `ohm.fritz.box`,
|
||||
passwordless `sudo` for pacman, regular user for `yay` /
|
||||
`makepkg`.
|
||||
|
||||
**Pre-install snapshot:** `pkglist.entry3.pre.txt` (1250 packages,
|
||||
sha256 `e73ffdd41b683aaba2ad18efa5ce3e7252577c13b4f0bb14e9de7bdfbfd5e26e`).
|
||||
**Post-install snapshot:** `pkglist.entry3.post.txt` (1253 packages).
|
||||
**Transaction logs:** `pacman.entry3a.firefox.log`,
|
||||
`pacman.entry3b.xtrace.log`.
|
||||
|
||||
### What was installed
|
||||
|
||||
Two transactions in one entry:
|
||||
|
||||
| Package | Version | Source | Reason |
|
||||
|---|---|---|---|
|
||||
| firefox | 150.0.1-1 | extra | explicit — matrix's `C-W-ff-*` and `C-X-ff-*` cells |
|
||||
| mailcap | 2.1.54-2 | extra | dep of firefox |
|
||||
| xtrace | 1.4.0-2 | AUR | explicit — X protocol tracer (parallel to `WAYLAND_DEBUG=1`) |
|
||||
|
||||
3 added, 0 removed.
|
||||
|
||||
Firefox was a clean `pacman -S firefox`. xtrace went via
|
||||
`yay -G xtrace; cd ~/.cache/yay/xtrace; makepkg -s --noconfirm
|
||||
--ignorearch; sudo pacman -U --noconfirm xtrace-1.4.0-2-aarch64.pkg.tar.zst`.
|
||||
The `--ignorearch` was needed because the AUR PKGBUILD declares
|
||||
`arch=('i686' 'x86_64')` only — the package builds cleanly on
|
||||
aarch64, the maintainer just hasn't updated the array.
|
||||
|
||||
### File-conflict probe (no actual conflict)
|
||||
|
||||
A pre-install probe suggested AUR `xtrace` would conflict with
|
||||
glibc's `/usr/bin/xtrace` (glibc ships a syscall-tracer shell
|
||||
script under that path). Investigation showed the **Arch AUR
|
||||
PKGBUILD renames the binary to `/usr/bin/x11trace`** specifically
|
||||
to avoid this collision. Both binaries now coexist:
|
||||
|
||||
- `/usr/bin/xtrace` — glibc's syscall/function tracer (5 KB
|
||||
bash script). Unchanged.
|
||||
- `/usr/bin/x11trace` — the X protocol tracer (133 KB aarch64
|
||||
ELF, AUR `xtrace` 1.4.0). New.
|
||||
|
||||
The early `pacman -U --overwrite '/usr/bin/xtrace'` flag turned
|
||||
out to be unnecessary; pacman would have allowed the install
|
||||
without it because nothing actually overlapped on disk. No
|
||||
state was overwritten.
|
||||
|
||||
### Verification
|
||||
|
||||
- `firefox --version` → `Mozilla Firefox 150.0.1`
|
||||
- `x11trace --version` → `xtrace version 1.4.0`
|
||||
- `x11trace --help` confirms X-protocol semantics
|
||||
("Dump all X protocol data being tunneled from a fake X
|
||||
display to a real one")
|
||||
- `head -3 /usr/bin/xtrace` still shows the GNU libc copyright
|
||||
banner — glibc's xtrace untouched.
|
||||
|
||||
### What is now fully resolved from earlier "operator-decision-pending"
|
||||
|
||||
- ✅ firefox installed → all 6 matrix cells now have a binary
|
||||
available.
|
||||
- ✅ xtrace (X protocol tracer) installed at `/usr/bin/x11trace`
|
||||
→ if any Phase 1 cell wants protocol-level evidence parallel
|
||||
to the predecessor's `WAYLAND_DEBUG=1`, the instrument is
|
||||
ready.
|
||||
|
||||
---
|
||||
|
||||
## Entry 4 — 2026-05-03 ~10:25 CEST
|
||||
|
||||
**Trigger:** Operator was in the freshly-switched XFCE session
|
||||
("Can you rotate the xfce session for me? Right now, left is up
|
||||
and right is down"). The PineTab2 panel is mounted portrait
|
||||
(native mode 800×1280@59.98) and XFCE's default rotation
|
||||
("normal") shows it that way; Plasma X11 / Plasma Wayland have
|
||||
historically used `right` rotation to present landscape
|
||||
1280×800. This entry brings XFCE in line.
|
||||
|
||||
**Driven from:** `mfritsche@noether` over SSH to `ohm.fritz.box`,
|
||||
regular user (no sudo needed; per-user state only).
|
||||
|
||||
### What was changed
|
||||
|
||||
1. **Live rotation applied** to the active XFCE session (session
|
||||
id 395, Xorg pid 32073, DISPLAY=:0,
|
||||
XAUTHORITY=/run/user/1001/xauth_QctOSR):
|
||||
```
|
||||
xrandr --output DSI-1 --rotate right
|
||||
```
|
||||
Result: `Screen 0 ... current 1280 x 800` and `DSI-1
|
||||
connected 1280x800+0+0 right`. Matches the Plasma X11
|
||||
orientation.
|
||||
|
||||
2. **Persistence: `~/.config/autostart/99-rotate-dsi1.desktop`
|
||||
created** so every future XFCE login runs the rotation
|
||||
immediately. File contents:
|
||||
```
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Rotate DSI-1 to landscape (right)
|
||||
Comment=Created 2026-05-03 by x11-session-research campaign —
|
||||
see phase0_evidence/x11_inventory_2026-05-03/revert.log entry 4
|
||||
Exec=sh -c "xrandr --output DSI-1 --rotate right"
|
||||
OnlyShowIn=XFCE;
|
||||
Terminal=false
|
||||
```
|
||||
`OnlyShowIn=XFCE` keeps it from running under Plasma X11 /
|
||||
openbox — those handle their own rotation state.
|
||||
|
||||
### Why not via xfconf
|
||||
|
||||
XFCE's `displays` xfconf channel was empty
|
||||
(`xfconf-query -c displays -lv` showed only `/ActiveProfile`
|
||||
= `Default` with no per-monitor data). xfce4-display-settings
|
||||
populates that profile on first GUI use; without that population,
|
||||
writing rotation codes by hand into xfconf is brittle (the
|
||||
encoding of "right" depends on xfce4-settings version). An
|
||||
autostart .desktop file is version-independent and easy to
|
||||
inspect.
|
||||
|
||||
If the operator subsequently runs *Settings → Display* in the
|
||||
XFCE GUI and clicks Save / Apply, xfconf will write a real
|
||||
profile and the autostart file becomes redundant — at that
|
||||
point either can stay (no conflict) or the autostart can be
|
||||
removed.
|
||||
|
||||
### What is NOT changed
|
||||
|
||||
- No system-wide config touched.
|
||||
- No package install.
|
||||
- Plasma X11 and openbox sessions unaffected — `OnlyShowIn=XFCE`
|
||||
scopes the autostart to XFCE only.
|
||||
- Touchscreen orientation: **NOT** auto-corrected by this entry.
|
||||
After rotation, the Goodix Capacitive TouchScreen will likely
|
||||
report touches in the panel's native (portrait) coordinate
|
||||
space, so taps land on the wrong screen position. Fix when
|
||||
it becomes a concern:
|
||||
```
|
||||
xinput map-to-output "Goodix Capacitive TouchScreen" DSI-1
|
||||
```
|
||||
This is **not auto-applied** in this entry because the matrix
|
||||
cells use mouse + keyboard for navigation, not touch — and
|
||||
also because mapping the touchscreen would itself need
|
||||
another autostart entry. If touch becomes relevant later,
|
||||
add it as entry 5.
|
||||
|
||||
---
|
||||
|
||||
## Entry 5 — 2026-05-03 ~10:29 CEST
|
||||
|
||||
**Trigger:** Operator confirmed XFCE session alive after entry 4
|
||||
("xfce-session alive"), then accepted the touchscreen-mapping
|
||||
follow-up offered in entry 4's "What is NOT changed" note.
|
||||
|
||||
**Driven from:** `mfritsche@noether` over SSH to `ohm.fritz.box`,
|
||||
regular user.
|
||||
|
||||
### What was changed
|
||||
|
||||
1. **Live mapping applied:**
|
||||
```
|
||||
xinput map-to-output "pointer:Goodix Capacitive TouchScreen" DSI-1
|
||||
```
|
||||
The `pointer:` prefix is required because the Goodix exposes
|
||||
both a pointer device (id 13) and a keyboard subdevice
|
||||
(id 15) — `xinput` needs the disambiguation. Verified by
|
||||
`xinput list-props`: Coordinate Transformation Matrix
|
||||
updated to `[0 1 0 / -1 0 1 / 0 0 1]` — the homogeneous
|
||||
90°-clockwise rotation matrix matching the screen.
|
||||
|
||||
2. **Persistence:
|
||||
`~/.config/autostart/99-rotate-touchscreen.desktop` created**.
|
||||
Same `OnlyShowIn=XFCE` scoping. The Exec uses `sh -c "sleep 2;
|
||||
xinput ..."` because XFCE may launch this autostart before
|
||||
entry 4's xrandr rotation has finished applying — without
|
||||
the sleep, the xinput remap can race against an unrotated
|
||||
screen state.
|
||||
|
||||
### What is NOT changed
|
||||
|
||||
- Other input devices (touchpad, USB mouse, USB keyboard)
|
||||
unchanged — they don't report panel-relative coordinates so
|
||||
rotation doesn't affect them.
|
||||
- Plasma X11 / openbox sessions unaffected
|
||||
(`OnlyShowIn=XFCE`).
|
||||
- Wayland sessions unaffected (xinput is X11-only). When KDE
|
||||
Plasma Wayland next runs, it uses its own
|
||||
`kwriteconfig5 --file kwinrc` mapping — that's predecessor
|
||||
state, not touched here.
|
||||
|
||||
---
|
||||
|
||||
## How to revert this campaign's installs
|
||||
|
||||
Entries reverted in **reverse order** (entry 5 → 4 → 3 → 2 → 1):
|
||||
|
||||
```sh
|
||||
ssh ohm.fritz.box '
|
||||
set -e
|
||||
|
||||
# ----- Entry 5 revert: touchscreen mapping -----
|
||||
rm -f ~/.config/autostart/99-rotate-touchscreen.desktop
|
||||
# Live revert: reset Coordinate Transformation Matrix to identity.
|
||||
# Only meaningful in an X11 session; harmless if no XFCE running.
|
||||
if pgrep -x xfwm4 >/dev/null; then
|
||||
DISPLAY=:0 XAUTHORITY=$(ls /run/user/$(id -u)/xauth_* 2>/dev/null | head -1) \
|
||||
xinput set-prop "pointer:Goodix Capacitive TouchScreen" \
|
||||
"Coordinate Transformation Matrix" \
|
||||
1 0 0 0 1 0 0 0 1 || true
|
||||
fi
|
||||
|
||||
# ----- Entry 4 revert: XFCE rotation -----
|
||||
rm -f ~/.config/autostart/99-rotate-dsi1.desktop
|
||||
# Live rotation revert (only if currently in XFCE):
|
||||
if pgrep -x xfwm4 >/dev/null; then
|
||||
DISPLAY=:0 XAUTHORITY=$(ls /run/user/$(id -u)/xauth_* 2>/dev/null | head -1) \
|
||||
xrandr --output DSI-1 --rotate normal || true
|
||||
fi
|
||||
|
||||
# ----- Entry 3 revert: firefox + xtrace -----
|
||||
sudo pacman -Rsn --noconfirm firefox xtrace
|
||||
# mailcap was pulled as a firefox dep; -Rs cleans it up if no other
|
||||
# dependent remains.
|
||||
|
||||
# ----- Entry 2 revert: XFCE -----
|
||||
sudo pacman -Rsn --noconfirm \
|
||||
exo garcon mousepad parole ristretto thunar \
|
||||
thunar-archive-plugin thunar-media-tags-plugin thunar-volman tumbler \
|
||||
xfburn xfce4-appfinder xfce4-battery-plugin xfce4-clipman-plugin \
|
||||
xfce4-cpufreq-plugin xfce4-cpugraph-plugin xfce4-dict \
|
||||
xfce4-diskperf-plugin xfce4-eyes-plugin xfce4-fsguard-plugin \
|
||||
xfce4-genmon-plugin xfce4-mailwatch-plugin xfce4-mount-plugin \
|
||||
xfce4-mpc-plugin xfce4-netload-plugin xfce4-notes-plugin \
|
||||
xfce4-notifyd xfce4-panel xfce4-places-plugin xfce4-power-manager \
|
||||
xfce4-pulseaudio-plugin xfce4-screensaver xfce4-screenshooter \
|
||||
xfce4-sensors-plugin xfce4-session xfce4-settings \
|
||||
xfce4-smartbookmark-plugin xfce4-systemload-plugin xfce4-taskmanager \
|
||||
xfce4-terminal xfce4-time-out-plugin xfce4-timer-plugin \
|
||||
xfce4-verve-plugin xfce4-wavelan-plugin xfce4-weather-plugin \
|
||||
xfce4-whiskermenu-plugin xfce4-xkb-plugin xfconf xfdesktop xfwm4
|
||||
|
||||
# Per-user xfconf tree: only safe to remove if the operator never
|
||||
# logged into XFCE (otherwise xfconfd may have written other settings
|
||||
# the operator would lose). Manual check:
|
||||
if [ "$(find ~/.config/xfce4 -type f | sort)" = "$HOME/.config/xfce4/xfconf/xfce-perchannel-xml/xfwm4.xml" ]; then
|
||||
rm -rf ~/.config/xfce4
|
||||
echo " ~/.config/xfce4 removed (only the pre-seeded xfwm4.xml was there)"
|
||||
else
|
||||
echo " ~/.config/xfce4 contains operator-added files; manual review required"
|
||||
find ~/.config/xfce4 -type f
|
||||
fi
|
||||
|
||||
# ----- Entry 1 revert: measurement tools + openbox -----
|
||||
sudo pacman -Rsn --noconfirm \
|
||||
openbox sysprof \
|
||||
xorg-xrandr xorg-xev xorg-xinput xorg-xwininfo xorg-xkill
|
||||
|
||||
# Sysctl: nothing to undo (entry 1's paranoid=1 was already reverted
|
||||
# in-session — see entry 1 § "What was changed").
|
||||
|
||||
# ----- Verification -----
|
||||
echo "expected pkg count after revert: 1169"
|
||||
pacman -Qq | wc -l
|
||||
|
||||
echo "expected sysctl: kernel.perf_event_paranoid = 2"
|
||||
sysctl kernel.perf_event_paranoid
|
||||
|
||||
echo "expected sessions: only plasmax11.desktop"
|
||||
ls /usr/share/xsessions/
|
||||
|
||||
echo "expected /etc/sysctl.d/: empty"
|
||||
ls /etc/sysctl.d/
|
||||
'
|
||||
```
|
||||
|
||||
Sanity-check: `pacman -Qq | wc -l` should report **1169**, matching
|
||||
`pkglist.pre.txt`. If it reports anything else, the operator
|
||||
added/removed a package between an entry and the revert;
|
||||
investigate before declaring revert complete.
|
||||
|
||||
---
|
||||
|
||||
## Adding a new entry
|
||||
|
||||
When a future Phase install/mutation happens, append a new
|
||||
`## Entry N — YYYY-MM-DD` section above the "How to revert"
|
||||
section. Re-snapshot `pacman -Qq` into a new
|
||||
`pkglist.entryN.{pre,post}.txt` so each entry is independently
|
||||
revertible. Prepend the new entry's revert step to the
|
||||
"How to revert" block (entries revert in reverse install
|
||||
order — newest first).
|
||||
+50
-17
@@ -279,17 +279,48 @@ dominates per browser × decode path.
|
||||
|
||||
### Experimental matrix
|
||||
|
||||
Six 2-axis cells (3 browsers × 2 decode paths) × 2
|
||||
session conditions (with-KWin / without-KWin):
|
||||
Eight 2-axis cells (3 browsers + 1 reference client × 2 decode
|
||||
paths) × 2 session conditions (with-KWin / without-KWin):
|
||||
|
||||
| Browser | Decode | with-KWin (Plasma Wayland) | without-KWin (X11 session, no compositor) |
|
||||
| Client | Decode | with-KWin (Plasma Wayland) | without-KWin (X11 session, no compositor) |
|
||||
|---|---|---|---|
|
||||
| Brave 147 | full SW | C-W-brave-sw | C-X-brave-sw |
|
||||
| Brave 147 | libva (if it works) | C-W-brave-libva | C-X-brave-libva |
|
||||
| chromium-fourier 149 (Step 1 + Step 2) | full SW | C-W-chrf-sw | C-X-chrf-sw |
|
||||
| chromium-fourier 149 | libva (Step 1 enables it) | C-W-chrf-libva | C-X-chrf-libva |
|
||||
| Firefox | full SW | C-W-ff-sw | C-X-ff-sw |
|
||||
| Firefox | libva | C-W-ff-libva | C-X-ff-libva |
|
||||
| Firefox 150 | full SW | C-W-ff-sw | C-X-ff-sw |
|
||||
| Firefox 150 | libva | C-W-ff-libva | C-X-ff-libva |
|
||||
| **mpv 0.41 (reference)** | **full SW** | **C-W-mpv-sw** | **C-X-mpv-sw** |
|
||||
| **mpv 0.41 (reference)** | **libva / v4l2request** | **C-W-mpv-hw** | **C-X-mpv-hw** |
|
||||
|
||||
Each mpv cell is run twice — once with `--vo=xv` (XVideo
|
||||
extension, the legacy X11-hardware-overlay path mpv has used
|
||||
since the late 1990s) and once with `--vo=gpu --gpu-context=x11`
|
||||
(modern Mesa GL + DRI3 + XPresent path). Two VOs × 8 mpv cells
|
||||
= 16 mpv data points. The two mpv VOs probe orthogonal
|
||||
questions:
|
||||
|
||||
- `--vo=xv`: does the X server's XVideo adapter route NV12 to
|
||||
a hardware plane on rockchip-drm RK3568 at all? If yes,
|
||||
XVideo is a known-good baseline that the browsers' more
|
||||
modern overlay paths *should* match or beat.
|
||||
- `--vo=gpu --gpu-context=x11`: does the Mesa Panfrost
|
||||
GL+DRI3+XPresent path on rockchip allow the X server to
|
||||
route an NV12 dmabuf to Plane 39 (the Primary plane, the
|
||||
only NV12-LINEAR-capable plane on this hardware)? This is
|
||||
the same plumbing the browsers use, so a positive result
|
||||
here means the browsers *could* but might not. A negative
|
||||
result means even mpv can't, in which case the browsers
|
||||
cannot either.
|
||||
|
||||
mpv's role is **reference baseline**, not target. If both mpv
|
||||
VOs show clean hardware-overlay scanout but the browsers don't,
|
||||
the campaign verdict is "the X11 path is fast on this hardware,
|
||||
but the browsers leave the speedup on the table." If even mpv's
|
||||
two VOs can't engage Plane 39 NV12, the "X11 hardware-overlay
|
||||
mechanism is structurally avoidable" claim is challenged on
|
||||
this specific kernel/Mesa stack and the campaign needs to
|
||||
re-frame.
|
||||
|
||||
The "(if it works)" / "where possible" qualifier per the
|
||||
operator's directive: libva on rockchip-drm RK3568 only works
|
||||
@@ -298,7 +329,9 @@ stock Brave 147 and stock Firefox, libva probably doesn't
|
||||
engage and those cells are documented N/A. For Firefox, the
|
||||
Mesa-side `libva-v4l2-request` may make libva work via Mozilla's
|
||||
VAAPI backend even on stock Firefox — to be verified in
|
||||
Phase 0 inventory.
|
||||
Phase 0 inventory. mpv on this hardware should be able to
|
||||
engage `--hwdec=v4l2request-copy` (the Mesa libva-v4l2-request
|
||||
backend) for the libva mpv cells.
|
||||
|
||||
### What "cutting out the KWin compositor" means
|
||||
|
||||
@@ -357,15 +390,15 @@ unknown:
|
||||
presentation (rather than internally composing to RGB) is
|
||||
open. Mozilla has a `MOZ_X11_EGL` hint and a "hardware video
|
||||
overlay" pref but these are not universally engaged.
|
||||
- **Reference clients**: mpv with `--vo=xv` or
|
||||
`--vo=gpu --hwdec=auto-copy --gpu-context=x11`, or `gst-play-1.0`
|
||||
with `xvimagesink` or `glimagesink`, are known-good X11
|
||||
hardware-overlay paths. **Adding mpv to the matrix as a
|
||||
reference client** would isolate "does the X11 hardware-
|
||||
overlay path work AT ALL on this hardware" from "do
|
||||
browsers actually use it." If mpv hardware-overlays cleanly
|
||||
but browsers don't, the conclusion is "the X11 path is fast,
|
||||
but browsers leave the speedup on the table."
|
||||
- **Reference clients**: mpv was added to the matrix as a 4th
|
||||
client (see § "Experimental matrix" above) — two cells, each
|
||||
run with both `--vo=xv` and `--vo=gpu --gpu-context=x11` to
|
||||
cover both the legacy XVideo overlay path and the modern
|
||||
DRI3+XPresent+Mesa-GL path. `gst-play-1.0` with `xvimagesink`
|
||||
or `glimagesink` would be a possible extension if the mpv
|
||||
cells produce ambiguous results, but mpv alone covers the
|
||||
"is the X11 hardware-overlay path even reachable on this
|
||||
hardware" question.
|
||||
|
||||
If the operator agrees, Phase 0 inventory should:
|
||||
|
||||
@@ -378,8 +411,8 @@ If the operator agrees, Phase 0 inventory should:
|
||||
2. Inventory Brave's, chromium-fourier's, and Firefox's X11
|
||||
overlay-presentation paths to see which (if any) request
|
||||
hardware-overlay presentation.
|
||||
3. Add mpv as a reference X11-overlay client to the matrix,
|
||||
so the campaign has a known-good comparison point.
|
||||
3. ~~Add mpv as a reference X11-overlay client to the matrix~~
|
||||
Done — mpv 0.41 added as a 4th client row 2026-05-03.
|
||||
|
||||
### What this question does NOT cover
|
||||
|
||||
|
||||
+32
-15
@@ -52,21 +52,38 @@ inventory and baseline-anchor work below.
|
||||
sessions. Operator action: `pacman -S` a non-compositing WM
|
||||
(recommend openbox) and create/switch to its SDDM session
|
||||
before without-KWin cells can run.
|
||||
- [ ] **NEW: Browser X11-overlay-path inventory.** Per
|
||||
`phase0_findings.md` § "Open questions": determine whether
|
||||
Brave 147 ozone-x11, chromium-fourier 149 ozone-x11, and
|
||||
Firefox X11 backends actually request hardware-overlay
|
||||
presentation for windowed video, or whether they always
|
||||
internally composite to RGB. Browser-specific source-grep
|
||||
+ chrome trace inspection.
|
||||
- [ ] **NEW: Add mpv as a reference X11-overlay client.**
|
||||
mpv with `--vo=xv` or `--vo=gpu --gpu-context=x11` is a
|
||||
known-good X11 hardware-overlay path. Adding mpv to the
|
||||
matrix as a 4th client provides "is the X11 hardware-overlay
|
||||
path even reachable on this hardware" baseline, separate
|
||||
from "do browsers use it." If mpv hits Plane 39 NV12 cleanly
|
||||
but browsers don't, the answer is "X11 path is fast, but
|
||||
the browsers don't take advantage of it."
|
||||
- [x] **Browser X11-overlay-path inventory.** Captured
|
||||
2026-05-03 in
|
||||
`phase0_evidence/browser_overlay_inventory_2026-05-03.md`
|
||||
+ acquired-source subtree
|
||||
`phase0_evidence/chromium_ozone_x11_2026-05-03/` (Chromium
|
||||
147 from `chromium-builder` LXD CT on boltzmann via the
|
||||
his subagent). **Decisive verdict at the source level:**
|
||||
Chromium ozone-x11 instantiates `StubOverlayManager`
|
||||
(`ozone_platform_x11.cc:262`) — no overlay candidates ever
|
||||
promoted; Brave 147 + chromium-fourier 149 inherit this
|
||||
unchanged (their patches don't touch Ozone). Firefox 150
|
||||
`WindowSurfaceX11{,Image,SHM}` are RGB-only (zero NV12 /
|
||||
dmabuf / DRI3 / XPresent references in any X11-surface
|
||||
file). **No browser in the matrix has a code path to
|
||||
hand NV12 to the X server for plane scanout.** Only mpv
|
||||
`--vo=xv` does; mpv `--vo=gpu --gpu-context=x11` is the
|
||||
same GL-composite shape as the browsers. Implication:
|
||||
campaign's load-bearing hypothesis is structurally
|
||||
weakened — the X11-vs-Wayland delta the matrix will
|
||||
measure for browsers is "browser-side GL composite +
|
||||
X-scanout-of-RGB" vs "browser-side GL composite +
|
||||
KWin-RGB-recomposite + scanout". mpv-xv becomes the
|
||||
matrix's only direct test of the original mechanism.
|
||||
Runtime-engagement probe deferred to Phase 1 first rep
|
||||
(design sketched in the inventory doc).
|
||||
- [x] **mpv added as 4th matrix client** 2026-05-03. Two cells
|
||||
(full SW, libva/v4l2request) × 2 sessions × 2 VOs (`--vo=xv`
|
||||
and `--vo=gpu --gpu-context=x11`) = 8 reference data points.
|
||||
README + `phase0_findings.md` § "Experimental matrix"
|
||||
updated; matrix grew from 12 → 16 cells (+8 mpv VO sub-points).
|
||||
mpv 0.41.0 already installed via predecessor (see
|
||||
`phase0_evidence/x11_inventory_2026-05-03/02_x11_paths.txt`).
|
||||
- [x] Inventory of X11-side measurement instruments. Captured
|
||||
2026-05-03 in `phase0_evidence/x11_inventory_2026-05-03/`
|
||||
(raw `04_measurement_instruments.txt` + summary `inventory.md`
|
||||
|
||||
Reference in New Issue
Block a user