Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/mozilla/widget/WaylandSurface.h
Warning:line 31, column 7
Excessive padding in 'class mozilla::widget::WaylandSurface' (60 padding bytes, where 4 is optimal). Optimal fields order: mRefCnt, mLoggingWidget, mGdkWindow, mParentSurface, mParent, mSurface, mSubsurface, mLatestAttachedBuffer, mEGLWindow, mViewport, mVisibleFrameCallback, mVSyncFrameCallback, mPendingOpaqueRegion, mOpaqueRegionFrameCallback, mSurfaceLock, mGdkAfterPaintId, mScreenScale, mFractionalScaleListener, mCoordinatesScaleManager, mFormats, mColorSurface, mColorRepresentationSurface, mImageDescription, mGdkCommitCallback, mMapCallback, mUnmapCallback, mVSyncCallbackStateHandler, mVSyncEmulateCheck, mDMABufFormatRefreshCallback, mBufferTransactions, mVSyncCallbackHandler, mScaleCallbacks, mMutex, mIsMapped, mIsVisible, mIsPendingGdkCleanup, mSurfaceNeedsCommit, mBufferAttached, mEmulatedVSyncCallbackTimerID, mIsOpaqueSurfaceHandlerSet, mScaleType, mCoordinatesScale, mSize, mSubsurfacePosition, mViewportDestinationSize, mViewportSourceRect, mCommitAllowed, mSubsurfaceDesync, mViewportFollowsSizeChanges, mBufferTransformFlippedX, mBufferTransformFlippedY, mVSyncCallbackEnabled, mUseDMABufFormats, mHDRSet, consider reordering the fields or adding explicit padding members

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Platform.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/accessible/atk -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/accessible/atk -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/accessible/atk -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/accessible/atk -I /root/firefox-clang/accessible/base -I /root/firefox-clang/accessible/generic -I /root/firefox-clang/accessible/html -I /root/firefox-clang/accessible/ipc -I /root/firefox-clang/accessible/xpcom -I /root/firefox-clang/accessible/xul -I /root/firefox-clang/layout/generic -I /root/firefox-clang/other-licenses/atk-1.0 -I /root/firefox-clang/widget -I /root/firefox-clang/widget/gtk -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -I /usr/include/gtk-3.0/unix-print -I /usr/include/gtk-3.0 -I /usr/include/pango-1.0 -I /usr/include/cloudproviders -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/fribidi -I /usr/include/harfbuzz -I /usr/include/atk-1.0 -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/glycin-2 -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/gio-unix-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/sysprof-6 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -Wno-error=unused-function -Wno-unused-local-typedefs -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-10-17-231001-351276-1 -x c++ /root/firefox-clang/accessible/atk/Platform.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#ifndef MOZ_WAYLAND_SURFACE_H_
6#define MOZ_WAYLAND_SURFACE_H_
7
8#include "WUniquePtr.h"
9#include "WaylandSurfaceLock.h"
10#include "mozilla/Atomics.h"
11#include "mozilla/GRefPtr.h"
12#include "mozilla/Mutex.h"
13#include "nsWaylandDisplay.h"
14
15/* Workaround for bug at wayland-util.h,
16 * present in wayland-devel < 1.12
17 */
18struct wl_surface;
19struct wl_subsurface;
20struct wl_egl_window;
21
22class MessageLoop;
23
24namespace mozilla::widget {
25
26class WaylandBuffer;
27class BufferTransaction;
28
29// WaylandSurface is a wrapper for Wayland rendering target
30// which is wl_surface / wl_subsurface.
31class WaylandSurface final {
Excessive padding in 'class mozilla::widget::WaylandSurface' (60 padding bytes, where 4 is optimal). Optimal fields order: mRefCnt, mLoggingWidget, mGdkWindow, mParentSurface, mParent, mSurface, mSubsurface, mLatestAttachedBuffer, mEGLWindow, mViewport, mVisibleFrameCallback, mVSyncFrameCallback, mPendingOpaqueRegion, mOpaqueRegionFrameCallback, mSurfaceLock, mGdkAfterPaintId, mScreenScale, mFractionalScaleListener, mCoordinatesScaleManager, mFormats, mColorSurface, mColorRepresentationSurface, mImageDescription, mGdkCommitCallback, mMapCallback, mUnmapCallback, mVSyncCallbackStateHandler, mVSyncEmulateCheck, mDMABufFormatRefreshCallback, mBufferTransactions, mVSyncCallbackHandler, mScaleCallbacks, mMutex, mIsMapped, mIsVisible, mIsPendingGdkCleanup, mSurfaceNeedsCommit, mBufferAttached, mEmulatedVSyncCallbackTimerID, mIsOpaqueSurfaceHandlerSet, mScaleType, mCoordinatesScale, mSize, mSubsurfacePosition, mViewportDestinationSize, mViewportSourceRect, mCommitAllowed, mSubsurfaceDesync, mViewportFollowsSizeChanges, mBufferTransformFlippedX, mBufferTransformFlippedY, mVSyncCallbackEnabled, mUseDMABufFormats, mHDRSet, consider reordering the fields or adding explicit padding members
32 friend WaylandSurfaceLock;
33
34 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WaylandSurface)public: MozExternalRefCountType AddRef(void) { static_assert(
!std::is_destructible_v<WaylandSurface>, "Reference-counted class "
"WaylandSurface" " should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/mozilla/widget/WaylandSurface.h"
, 34); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 34
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count
), ("WaylandSurface"), (uint32_t)(sizeof(*this))); return (nsrefcnt
)count; } MozExternalRefCountType Release(void) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/mozilla/widget/WaylandSurface.h"
, 34); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 34)
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); nsrefcnt count = --mRefCnt; NS_LogRelease((this), (
count), ("WaylandSurface")); if (count == 0) { delete (this);
return 0; } return count; } using HasThreadSafeRefCnt = std::
true_type; protected: ::mozilla::ThreadSafeAutoRefCnt mRefCnt
; public:
;
35
36 WaylandSurface();
37
38 // aRootLayer is a WaylandSurface root which is used by layered (HDR)
39 // rendering.
40 void Init(RefPtr<WaylandSurface> aRootLayer = nullptr);
41
42#ifdef MOZ_LOGGING1
43 nsAutoCString GetDebugTag() const;
44 void* GetLoggingWidget() const { return mLoggingWidget; };
45 void SetLoggingWidget(void* aWidget) { mLoggingWidget = aWidget; }
46#endif
47
48 // Fire VSync handler registered to this surface.
49 void VSyncCallbackHandler(struct wl_callback* aCallback, uint32_t aTime,
50 bool aEmulated, bool aRoutedFromChildSurface);
51
52 // Set VSync handler which is fired when it's good time for painting
53 // and WalandSurface is visible and VSync is enabled.
54 //
55 // If aEmulateVSyncCallback is set to true, we file VSync handler even
56 // if WaylandSurface is not visible. It's used for painting to hidden
57 // surface.
58 //
59 // Once set, the aVSyncCallbackHandler is preserved between unmap/map.
60 //
61 // It's VSync source responsibility to disable emulated VSync events
62 // by SetVSyncCallbackStateLocked().
63 void SetVSyncCallbackHandlerLocked(
64 const WaylandSurfaceLock& aProofOfLock,
65 const std::function<void(wl_callback*, uint32_t, bool)>&
66 aVSyncCallbackHandler,
67 bool aEmulateVSyncCallback = false);
68
69 // Clears VSync callback handler. It's used if frame callback handler
70 // contains strong reference to WaylandSurface class owner
71 // which we want to clear.
72 void ClearVSyncCallbackHandlerLocked(const WaylandSurfaceLock& aProofOfLock);
73
74 // Enable/Disable any frame callback emission (includes emulated ones).
75 void SetVSyncCallbackStateLocked(const WaylandSurfaceLock& aProofOfLock,
76 bool aEnabled);
77 // Register handler which is called on VSync state change set by
78 // SetVSyncCallbackStateLocked().
79 void SetVSyncCallbackStateHandlerLocked(
80 const WaylandSurfaceLock& aProofOfLock,
81 const std::function<void(bool)>& aVSyncCallbackStateHandler);
82
83 // Set a routine which returns whether we should run emulated callback
84 // or not. Don't overwrite existing one unless aForce is set.
85 void SetVSyncEmulateCheckLocked(
86 const WaylandSurfaceLock& aProofOfLock,
87 const std::function<bool(void)>& aVSyncEmulateCheck, bool aForce = false);
88
89 wl_egl_window* GetEGLWindow(DesktopIntSize aSize);
90 bool HasEGLWindow() const { return !!mEGLWindow; }
91
92 // Set WaylandSurface target size (viewport & ELG surface if it's present).
93 void SetSize(DesktopIntSize aSize);
94
95 // Apply changes to EGLWindow size set by SetSize().
96 // ApplyEGLWindowSize() is called from compostor thread
97 // right before GL rendering to set EGLWindow size / viewport size
98 // for actual back buffer.
99 //
100 // aEGLWindowSize is scaled backbuffer size and it's used similary
101 // as WaylandBuffer size at Attach().
102 void ApplyEGLWindowSize(LayoutDeviceIntSize aEGLWindowSize);
103
104 // Mapped means we have all internals created.
105 bool IsMapped() const { return mIsMapped; }
106
107 // We've got first frame callback so we're really visible now.
108 bool IsVisible() const { return mIsVisible; }
109
110 bool IsToplevelSurface() const { return !mParent; }
111
112 // Called from frame callback and sets the visible flag
113 void VisibleCallbackHandler();
114
115 // Indicate that Wayland surface uses Gdk resources which
116 // need to be released on main thread by GdkCleanUpLocked().
117 // It may be called after Unmap() to make sure
118 // Gtk resources are not allocated again.
119 bool IsPendingGdkCleanup() const { return mIsPendingGdkCleanup; }
120
121 bool IsOpaqueSurfaceHandlerSet() const { return mIsOpaqueSurfaceHandlerSet; }
122
123 bool HasBufferAttached() const { return mBufferAttached; }
124
125 // Mapped as direct surface of MozContainer
126 bool MapLocked(const WaylandSurfaceLock& aProofOfLock,
127 wl_surface* aParentWLSurface,
128 DesktopIntPoint aSubsurfacePosition);
129 // Mapped as child of WaylandSurface (used by layers)
130 bool MapLocked(const WaylandSurfaceLock& aProofOfLock,
131 WaylandSurfaceLock* aParentWaylandSurfaceLock,
132 DesktopIntPoint aSubsurfacePosition);
133 // Unmap surface which hides it
134 void UnmapLocked(WaylandSurfaceLock& aSurfaceLock);
135
136 // Clean up Gdk resources, on main thread only
137 void GdkCleanUpLocked(const WaylandSurfaceLock& aProofOfLock);
138
139 // Allow to register and run a callback when associated widget (nsWindow)
140 // is mapped.
141 //
142 // Map callback is called *after* WaylandSurface::MapLocked() call
143 // by widget code on main thread.
144 void SetMapCallbackLocked(
145 const WaylandSurfaceLock& aProofOfLock,
146 const std::function<void(WaylandSurfaceLock& aProofOfLock)>& aMapCB);
147 void ClearMapCallbackLocked(const WaylandSurfaceLock& aProofOfLock);
148 void RunMapCallbackLocked(WaylandSurfaceLock& aProofOfLock);
149
150 // Allow to register and run a callback when associated widget (nsWindow)
151 // is unmapped.
152 //
153 // Unmap callback is called *before* WaylandSurface::UnmapLocked() call
154 // by widget code on main thread.
155 void SetUnmapCallbackLocked(const WaylandSurfaceLock& aProofOfLock,
156 const std::function<void(void)>& aUnmapCB);
157 void ClearUnmapCallbackLocked(const WaylandSurfaceLock& aProofOfLock);
158 void RunUnmapCallback();
159
160 // Attach WaylandBuffer which shows WaylandBuffer content
161 // on screen.
162 bool AttachLocked(const WaylandSurfaceLock& aSurfaceLock,
163 RefPtr<WaylandBuffer> aBuffer);
164 bool IsBufferAttached(WaylandBuffer* aBuffer);
165
166 // If there's any WaylandBuffer recently attached, detach it.
167 // It makes the WaylandSurface invisible and it doesn't have any
168 // content.
169 void RemoveAttachedBufferLocked(const WaylandSurfaceLock& aProofOfLock);
170
171 // Remove deleted transaction from WaylandSurface, it may release
172 // referenced WaylandBuffer.
173 void RemoveTransactionLocked(const WaylandSurfaceLock& aSurfaceLock,
174 RefPtr<BufferTransaction> aTransaction);
175
176 // CommitLocked() is needed to call after some of *Locked() method
177 // to submit the action to Wayland compositor by wl_surface_commit().
178
179 // It's possible to stack more *Locked() methods
180 // together and do commit after the last one to do the changes in atomic way.
181
182 // Need of commit is tracked by mSurfaceNeedsCommit flag and
183 // if it's set, CommitLocked() is called when WaylandSurfaceLock is destroyed
184 // and WaylandSurface is unlocked.
185 void CommitLocked(const WaylandSurfaceLock& aProofOfLock,
186 bool aForceCommit = false, bool aForceDisplayFlush = false);
187
188 void EnableDMABufFormatsLocked(
189 const WaylandSurfaceLock& aProofOfLock,
190 const std::function<void(DMABufFormats*)>& aFormatRefreshCB);
191 void DisableDMABufFormatsLocked(const WaylandSurfaceLock& aProofOfLock);
192
193 // Place this WaylandSurface above aLowerSurface
194 void PlaceAboveLocked(const WaylandSurfaceLock& aProofOfLock,
195 WaylandSurfaceLock& aLowerSurfaceLock);
196 void MoveLocked(const WaylandSurfaceLock& aProofOfLock,
197 DesktopIntPoint aPosition);
198 void SetViewportFollowsSizeChangesLocked(
199 const WaylandSurfaceLock& aProofOfLock);
200 void SetViewPortSourceRectLocked(const WaylandSurfaceLock& aProofOfLock,
201 const DesktopRect& aRect);
202 void SetViewPortDestLocked(const WaylandSurfaceLock& aProofOfLock,
203 const DesktopIntSize& aDestSize);
204 void SetTransformFlippedLocked(const WaylandSurfaceLock& aProofOfLock,
205 bool aFlippedX, bool aFlippedY);
206
207 void SetOpaqueRegion(const gfx::IntRegion& aRegion);
208 void SetOpaqueRegionLocked(const WaylandSurfaceLock& aProofOfLock,
209 const gfx::IntRegion& aRegion);
210 void SetOpaqueLocked(const WaylandSurfaceLock& aProofOfLock);
211 void ClearOpaqueRegionLocked(const WaylandSurfaceLock& aProofOfLock);
212 void OpaqueCallbackHandler();
213
214 void ClearOpaqueCallbackLocked(const WaylandSurfaceLock& aProofOfLock);
215 void SetOpaqueCallbackLocked(const WaylandSurfaceLock& aProofOfLock);
216
217 bool DisableUserInputLocked(const WaylandSurfaceLock& aProofOfLock);
218 void InvalidateRegionLocked(const WaylandSurfaceLock& aProofOfLock,
219 const gfx::IntRegion& aInvalidRegion);
220 void InvalidateLocked(const WaylandSurfaceLock& aProofOfLock);
221
222 // We use two scale systems in Firefox/Wayland. Ceiled (integer) scale and
223 // fractional scale. Ceiled scale is easy to implement but comes with
224 // rendering overhead while fractional rendering paints buffers with exact
225 // scale.
226 //
227 // Fractional scale is used as rendering optimization.
228 // For instance if 225% scale is used, ceiled scale is 3
229 // and fractional 2.20.
230 //
231 // If we paint content with ceiled scale 3 and desktop uses scale 225%,
232 // Wayland compositor downscales buffer to 2.20 on rendering
233 // but we paint more pixels than necessary (so we use name ceiled).
234 //
235 // Scale is used by wp_viewport. If a surface has a surface-local size
236 // of 100 px by 50 px and wishes to submit buffers with a scale of 1.5,
237 // then a buffer of 150px by 75 px should be used and the wp_viewport
238 // destination rectangle should be 100 px by 50 px.
239 // The wl_surface buffer scale should remain set to 1.
240 //
241 // For scale 2 (200%) we use surface size 200 x 100 px and set
242 // viewport size to 100 x 50 px.
243 //
244 // We're getting fractional scale number with a small delay from
245 // wp_fractional_scale_v1 after first commit to surface.
246 // Meanwhile we can use ceiled scale number instead of fractional one or
247 // get fractional scale from parent window (if there's any).
248 //
249 enum ScaleType {
250 Disabled = 0,
251 Ceiled = 1,
252 Fractional = 2,
253 Coordinates = 3,
254 };
255
256 void SetScaleTypeLocked(const WaylandSurfaceLock& aProofOfLock,
257 ScaleType aScaleType, bool aSetHandler);
258 bool IsCoordinatesScaleLocked(const WaylandSurfaceLock& aProofOfLock) const {
259 MOZ_DIAGNOSTIC_ASSERT(&aProofOfLock == mSurfaceLock)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(&aProofOfLock == mSurfaceLock)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(&aProofOfLock == mSurfaceLock
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"&aProofOfLock == mSurfaceLock", "/root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/mozilla/widget/WaylandSurface.h"
, 259); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "&aProofOfLock == mSurfaceLock"
")"); do { MOZ_CrashSequence(__null, 259); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
260 return mScaleType == ScaleType::Coordinates;
261 }
262
263 // Right now we support two scale change callbacks.
264 // ScaleCallbackType::Widget is used by nsWindow & co to promote scale
265 // changes to layout.
266 // ScaleCallbackType::Layers is used by HDR compositor to propagate
267 // changes to rendered layers/subsurfaces.
268 //
269 // At least one scale callbacks needs to be set before SetScaleTypeLocked()
270 // to run the callback.
271 enum ScaleCallbackType {
272 Widget = 0,
273 Layers = 1,
274 CallbackNum = 2,
275 };
276 void SetScaleCallbackLocked(const WaylandSurfaceLock& aProofOfLock,
277 ScaleCallbackType aCallbackType,
278 std::function<void(void)> aScaleCallback);
279 bool HasScaleCallbacksLocked(const WaylandSurfaceLock& aProofOfLock);
280 void ClearScaleCallbacksLocked(const WaylandSurfaceLock& aProofOfLock);
281
282 // Returns scale as float point number. If WaylandSurface is not mapped,
283 // return fractional scale of parent surface or monitor.
284 static constexpr const double sNoScale = -1;
285 double GetScale() const;
286 uint32_t GetCoordinatesScale() const { return mCoordinatesScale; }
287 double GetCoordinatesScaleRounded() const {
288 return ((double)mCoordinatesScale) / (1 << 24);
289 }
290 bool HasCoordinatesScaleLocked(const WaylandSurfaceLock& aProofOfLock) const {
291 return !!mCoordinatesScaleManager;
292 }
293
294 // Called when screen ceiled scale changes or sets initial scale before we map
295 // and paint the surface.
296 void SetCeiledScaleLocked(const WaylandSurfaceLock& aProofOfLock,
297 int aScreenCeiledScale);
298 // Sets coordinates scale explicitly to the surface,
299 bool SetCoordinatesScaleLocked(const WaylandSurfaceLock& aProofOfLock,
300 uint32_t scale_8_24);
301
302 static void AfterPaintHandler(GdkFrameClock* aClock, void* aData);
303
304 // See https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3111 why we use it.
305 // If child surface covers whole area of parent surface and it's opaque,
306 // parent surface will not get any events (frame callbacks) from compositor
307 // as it's considered as invisible.
308 //
309 // Firefox uses the parent wl_surface (owned by GdkWindow) to get input
310 // events. Without gdk_wayland_window_add_frame_callback_surface() call,
311 // Gdk is not getting any events from compostor and we're frozen.
312 //
313 // So gdk_wayland_window_add_frame_callback_surface() registers wl_surface
314 // owned by WaylandSurface to GtkWindow and requests frame callback
315 // for it. Such frame callback is then routed to GdkWindow and it's used
316 // to fire events like native GdkWindow ones.
317 //
318 // To make sure WaylandSurface's wl_surface frame callback is generated,
319 // we need to commit the wl_surface regularly as Gdk registers frame callback
320 // for it at on_frame_clock_after_paint() event of GdkWindow.
321 bool AddOpaqueSurfaceHandlerLocked(const WaylandSurfaceLock& aProofOfLock,
322 GdkWindow* aGdkWindow,
323 bool aRegisterCommitHandler);
324 bool RemoveOpaqueSurfaceHandlerLocked(const WaylandSurfaceLock& aProofOfLock);
325
326 // Additional callback to call from on_frame_clock_after_paint()
327 // and before this wl_surface is commited.
328 // It can be used to update subsurfaces from main thread.
329 void SetGdkCommitCallbackLocked(
330 const WaylandSurfaceLock& aProofOfLock,
331 const std::function<void(void)>& aGdkCommitCB);
332 void ClearGdkCommitCallbackLocked(const WaylandSurfaceLock& aProofOfLock);
333
334 RefPtr<DMABufFormats> GetDMABufFormats() const { return mFormats; }
335
336 GdkWindow* GetGdkWindow() const;
337
338 static bool IsOpaqueRegionEnabled();
339
340 void SetParentLocked(const WaylandSurfaceLock& aProofOfLock,
341 RefPtr<WaylandSurface> aParent);
342
343 void SetColorRepresentationLocked(const WaylandSurfaceLock& aProofOfLock,
344 int aWLColorCoeficients, bool aFullRange,
345 uint32_t aWPChromaLocation = 0);
346
347 static void ImageDescriptionFailed(
348 void* aData, struct wp_image_description_v1* aImageDescription,
349 uint32_t aCause, const char* aMsg);
350 static void ImageDescriptionReady(
351 void* aData, struct wp_image_description_v1* aImageDescription,
352 uint32_t aIdentity);
353
354 void AssertCurrentThreadOwnsMutex();
355
356 void ForceCommit() { mSurfaceNeedsCommit = true; }
357 void SetCommitStateLocked(const WaylandSurfaceLock& aProofOfLock,
358 bool aCommitAllowed) {
359 mCommitAllowed = aCommitAllowed;
360 }
361
362 static bool SetPrimaries(wp_image_description_creator_params_v1* aParams,
363 mozilla::gfx::YUVColorSpace aColorSpace);
364 static bool SetTransferFunction(
365 wp_image_description_creator_params_v1* aParams,
366 gfx::TransferFunction aTransferFunction);
367
368 void SetHDRMetadata(wp_image_description_creator_params_v1* aParams,
369 gfx::TransferFunction aTransferFunction,
370 GdkWindow* aGdkWindow,
371 const mozilla::gfx::HDRMetadata& aHDRMetadata);
372
373 void SetColorManagementLocked(
374 const WaylandSurfaceLock& aProofOfLock,
375 wp_color_manager_v1* aColorManager,
376 wp_image_description_creator_params_v1* aParams);
377
378 private:
379 ~WaylandSurface();
380
381 bool MapLocked(const WaylandSurfaceLock& aProofOfLock,
382 wl_surface* aParentWLSurface,
383 WaylandSurfaceLock* aParentWaylandSurfaceLock,
384 DesktopIntPoint aSubsurfacePosition, bool aSubsurfaceDesync);
385
386 wl_surface* Lock(WaylandSurfaceLock* aWaylandSurfaceLock);
387 void Unlock(struct wl_surface** aSurface,
388 WaylandSurfaceLock* aWaylandSurfaceLock);
389 void Commit(WaylandSurfaceLock* aProofOfLock, bool aForceCommit,
390 bool aForceDisplayFlush);
391
392 // Get buffer transaction for WaylandBuffer, create new or recycle one.
393 BufferTransaction* GetNextTransactionLocked(
394 const WaylandSurfaceLock& aSurfaceLock, WaylandBuffer* aBuffer);
395 // Force release/detele all transactions and wl_buffers attached to them.
396 void ReleaseAllWaylandTransactionsLocked(WaylandSurfaceLock& aSurfaceLock);
397
398 void SetVSyncCallbackLocked(const WaylandSurfaceLock& aProofOfLock);
399 void ClearVSyncCallbackLocked(const WaylandSurfaceLock& aProofOfLock);
400 bool HasEmulatedVSyncCallbackLocked(
401 const WaylandSurfaceLock& aProofOfLock) const;
402 bool IsEmulatedVSyncEnabledLocked(const WaylandSurfaceLock& aProofOfLock);
403 void RequestEmulatedVSyncLocked(const WaylandSurfaceLock& aProofOfLock);
404
405 // Configures requested scale type. If aSetHandler is set it also
406 // install wayland-protocol handlers to call the scale change callbacks.
407 //
408 // We usually want to install handler to toplevel surfaces only
409 // and propagate the scale change to child surfaces.
410 bool ConfigureScaleLocked(const WaylandSurfaceLock& aProofOfLock,
411 ScaleType aScaleType, bool aSetProtocolHandler);
412 bool ConfigureCoordinateScaleLocked(const WaylandSurfaceLock& aProofOfLock,
413 bool aSetProtocolHandler);
414 bool ConfigureFractionalScaleLocked(const WaylandSurfaceLock& aProofOfLock,
415 bool aSetProtocolHandler);
416
417 // Calculate 'stable' rounded size for subsurface based
418 // on its size and position.
419 LayoutDeviceIntSize GetScaledSize(const DesktopIntSize& aSize) const;
420
421 // Weak ref to owning widget (nsWindow or NativeLayerWayland),
422 // used for diagnostics/logging only.
423 void* mLoggingWidget = nullptr;
424
425 // mIsMapped means we're supposed to be visible
426 // (or not if Wayland compositor decides so).
427 mozilla::Atomic<bool, mozilla::Relaxed> mIsMapped{false};
428
429 // mIsVisible means we're really visible as we've got frame callback.
430 mozilla::Atomic<bool, mozilla::Relaxed> mIsVisible{false};
431
432 // We used Gdk functions which needs clean up in main thread.
433 mozilla::Atomic<bool, mozilla::Relaxed> mIsPendingGdkCleanup{false};
434
435 std::function<void(void)> mGdkCommitCallback;
436 std::function<void(WaylandSurfaceLock& aProofOfLock)> mMapCallback;
437 std::function<void(void)> mUnmapCallback;
438
439 DesktopIntSize mSize;
440
441 // Parent GdkWindow where we paint to, directly or via subsurface.
442 RefPtr<GdkWindow> mGdkWindow;
443
444 // Parent wl_surface owned by mGdkWindow. It's used when we're attached
445 // directly to MozContainer.
446 wl_surface* mParentSurface = nullptr;
447
448 // Parent WaylandSurface.
449 //
450 // Layer rendering (compositor) uses mSurface directly attached to
451 // wl_surface owned by mParent.
452 //
453 // For non-compositing rendering (old) mParent is WaylandSurface
454 // owned by parent nsWindow.
455 RefPtr<WaylandSurface> mParent;
456
457 // wl_surface setup/states
458 WUniquePtr<wl_surface> mSurface;
459 mozilla::Atomic<bool, mozilla::Relaxed> mSurfaceNeedsCommit{false};
460 bool mCommitAllowed = true;
461
462 // When subsurface is desynced, we need to commit to parent surface
463 // to see the change in subsurface (this one).
464 // In such case we set mSurfaceNeedsCommit to parent for it.
465 bool mSubsurfaceDesync = true;
466
467 WUniquePtr<wl_subsurface> mSubsurface;
468 DesktopIntPoint mSubsurfacePosition;
469
470 // Wayland buffers recently attached to this surface or held by
471 // Wayland compositor.
472 // There may be more than one buffer attached, for instance if
473 // previous buffer is hold by compositor. We need to keep
474 // there buffers live until compositor notify us that we
475 // can release them.
476 AutoTArray<RefPtr<BufferTransaction>, 3> mBufferTransactions;
477 uintptr_t mLatestAttachedBuffer = 0;
478
479 // Indicates mSurface has buffer attached so we can attach subsurface
480 // to it and expect to get frame callbacks from Wayland compositor.
481 // We set it at AttachLocked() or when we get first frame callback
482 // (when EGL is used).
483 mozilla::Atomic<bool, mozilla::Relaxed> mBufferAttached{false};
484
485 mozilla::Atomic<wl_egl_window*, mozilla::Relaxed> mEGLWindow{nullptr};
486
487 bool mViewportFollowsSizeChanges = false;
488 WUniquePtr<wp_viewport> mViewport;
489 DesktopRect mViewportSourceRect{-1, -1, -1, -1};
490 DesktopIntSize mViewportDestinationSize{-1, -1};
491
492 // Surface flip state on X/Y asix
493 bool mBufferTransformFlippedX = false;
494 bool mBufferTransformFlippedY = false;
495
496 // Frame callback for mIsVisible flag
497 WUniquePtr<wl_callback> mVisibleFrameCallback;
498
499 // VSync callback handler called every frame or by time for emulated ones.
500 struct VSyncCallback {
501 std::function<void(wl_callback*, uint32_t, bool)> mCb = nullptr;
502 bool mEmulated = false;
503 bool IsSet() const { return !!mCb; }
504 };
505 VSyncCallback mVSyncCallbackHandler;
506
507 WUniquePtr<wl_callback> mVSyncFrameCallback;
508
509 bool mVSyncCallbackEnabled = true;
510 std::function<void(bool)> mVSyncCallbackStateHandler = nullptr;
511 std::function<bool(void)> mVSyncEmulateCheck = nullptr;
512
513 guint mEmulatedVSyncCallbackTimerID = 0;
514 constexpr static int sEmulatedVSyncCallbackTimeoutMs = (int)(1000.0 / 60.0);
515
516 // Frame callback used to set opaque region to wl_surface.
517 WUniquePtr<wl_region> mPendingOpaqueRegion;
518 WUniquePtr<wl_callback> mOpaqueRegionFrameCallback;
519
520 // WaylandSurface is used from Compositor/Rendering/Main threads.
521 mozilla::Mutex mMutex{"WaylandSurface"};
522 WaylandSurfaceLock* mSurfaceLock = nullptr;
523
524 // We may mark part of mSurface as opaque (non-transparent) if it's supported
525 // by Gtk which allows compositor to skip painting of covered parts.
526 mozilla::Atomic<bool, mozilla::Relaxed> mIsOpaqueSurfaceHandlerSet{false};
527 gulong mGdkAfterPaintId = 0;
528 static bool sIsOpaqueRegionEnabled;
529 static void (*sGdkWaylandWindowAddCallbackSurface)(GdkWindow*,
530 struct wl_surface*);
531 static void (*sGdkWaylandWindowRemoveCallbackSurface)(GdkWindow*,
532 struct wl_surface*);
533
534 ScaleType mScaleType = ScaleType::Disabled;
535
536 // mScreenScale is set from main thread only but read from
537 // different threads.
538 mozilla::Atomic<double, mozilla::Relaxed> mScreenScale{sNoScale};
539 // Coordinates scale is in fixed-point 8.24 format.
540 // Use GetCoordinatesScaleRounded() to convert it to float point.
541 mozilla::Atomic<uint32_t, mozilla::Relaxed> mCoordinatesScale{1 << 24};
542
543 // wp_fractional_scale_v1 / xx_fractional_scale_v2 works differently.
544 //
545 // wp_fractional_scale_v1 is needed for scale changes listener only
546 // so it's optional and we don't need it for every surface.
547 //
548 // xx_fractional_scale_v2 is used to set coordinates scale to particular
549 // surface so it must be present.
550 WUniquePtr<wp_fractional_scale_v1> mFractionalScaleListener;
551 WUniquePtr<xx_fractional_scale_v2> mCoordinatesScaleManager;
552
553 // Callback issued when fractional / coordinates scale changes.
554 // Ceiled (integer) scale changes is monitored by nsWindow as it's
555 // tied to GtkWindow.
556 std::function<void(void)> mScaleCallbacks[ScaleCallbackType::CallbackNum] = {
557 nullptr, nullptr};
558
559 bool mUseDMABufFormats = false;
560 // Wayland display notifies us when available DRM formats are are changed.
561 // For instance if wl_surface becomes fullscreen we may get DRM formats
562 // for direct scanout.
563 std::function<void(DMABufFormats*)> mDMABufFormatRefreshCallback;
564 RefPtr<DMABufFormats> mFormats;
565
566 // HDR support
567 bool mHDRSet = false;
568 WUniquePtr<wp_color_management_surface_v1> mColorSurface;
569 WUniquePtr<wp_color_representation_surface_v1> mColorRepresentationSurface;
570 WUniquePtr<wp_image_description_v1> mImageDescription;
571
572 static void SetLuminances(wp_image_description_creator_params_v1* aParams,
573 float minLum, float maxLum, float refLum);
574
575 static void SetContentLightLevel(
576 wp_image_description_creator_params_v1* aParams,
577 const mozilla::gfx::ContentLightLevel& aContentLightLevel);
578
579 static void SetMasteringDisplayColorVolume(
580 wp_image_description_creator_params_v1* aParams,
581 const mozilla::gfx::Smpte2086Metadata& aSmpte2086);
582};
583
584} // namespace mozilla::widget
585
586#endif /* MOZ_WAYLAND_SURFACE_H_ */