File: | root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/mozilla/widget/WaylandSurface.h |
Warning: | line 32, column 7 Excessive padding in 'class mozilla::widget::WaylandSurface' (53 padding bytes, where 5 is optimal). Optimal fields order: mRefCnt, mLoggingWidget, mGdkWindow, mParentSurface, mParent, mSurface, mSubsurface, mEGLWindow, mViewport, mReadyToDrawFrameCallback, mFrameCallback, mSurfaceLock, mGdkAfterPaintId, mScreenScale, mFractionalScaleListener, mFormats, mColorSurface, mImageDescription, mReadyToDrawCallbacks, mGdkCommitCallback, mUnmapCallback, mFrameCallbackStateHandler, mFractionalScaleCallback, mDMABufFormatRefreshCallback, mAttachedBuffers, mFrameCallbackHandler, mMutex, mIsMapped, mIsReadyToDraw, mIsPendingGdkCleanup, mBufferAttached, mIsOpaqueSurfaceHandlerSet, mEmulatedFrameCallbackTimerID, mScaleType, mSizeScaled, mSubsurfacePosition, mViewportDestinationSize, mViewportSourceRect, mSurfaceNeedsCommit, mViewportFollowsSizeChanges, mBufferTransformFlippedX, mBufferTransformFlippedY, mFrameCallbackEnabled, mUseDMABufFormats, mHDRSet, consider reordering the fields or adding explicit padding members |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | /* vim:expandtab:shiftwidth=2:tabstop=2: |
3 | */ |
4 | /* This Source Code Form is subject to the terms of the Mozilla Public |
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
7 | |
8 | #ifndef __MOZ_WAYLAND_SURFACE_H__ |
9 | #define __MOZ_WAYLAND_SURFACE_H__ |
10 | |
11 | #include "nsWaylandDisplay.h" |
12 | #include "mozilla/Mutex.h" |
13 | #include "mozilla/Atomics.h" |
14 | #include "WaylandSurfaceLock.h" |
15 | #include "mozilla/GRefPtr.h" |
16 | |
17 | /* Workaround for bug at wayland-util.h, |
18 | * present in wayland-devel < 1.12 |
19 | */ |
20 | struct wl_surface; |
21 | struct wl_subsurface; |
22 | struct wl_egl_window; |
23 | |
24 | class MessageLoop; |
25 | |
26 | namespace mozilla::widget { |
27 | |
28 | class WaylandBuffer; |
29 | |
30 | // WaylandSurface is a wrapper for Wayland rendering target |
31 | // which is wl_surface / wl_subsurface. |
32 | class WaylandSurface final { |
Excessive padding in 'class mozilla::widget::WaylandSurface' (53 padding bytes, where 5 is optimal). Optimal fields order: mRefCnt, mLoggingWidget, mGdkWindow, mParentSurface, mParent, mSurface, mSubsurface, mEGLWindow, mViewport, mReadyToDrawFrameCallback, mFrameCallback, mSurfaceLock, mGdkAfterPaintId, mScreenScale, mFractionalScaleListener, mFormats, mColorSurface, mImageDescription, mReadyToDrawCallbacks, mGdkCommitCallback, mUnmapCallback, mFrameCallbackStateHandler, mFractionalScaleCallback, mDMABufFormatRefreshCallback, mAttachedBuffers, mFrameCallbackHandler, mMutex, mIsMapped, mIsReadyToDraw, mIsPendingGdkCleanup, mBufferAttached, mIsOpaqueSurfaceHandlerSet, mEmulatedFrameCallbackTimerID, mScaleType, mSizeScaled, mSubsurfacePosition, mViewportDestinationSize, mViewportSourceRect, mSurfaceNeedsCommit, mViewportFollowsSizeChanges, mBufferTransformFlippedX, mBufferTransformFlippedY, mFrameCallbackEnabled, mUseDMABufFormats, mHDRSet, consider reordering the fields or adding explicit padding members | |
33 | friend WaylandSurfaceLock; |
34 | |
35 | 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" , 35); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 35 ); __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" , 35); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 35) ; __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:; |
36 | |
37 | WaylandSurface(RefPtr<WaylandSurface> aParent, gfx::IntSize aSize); |
38 | |
39 | #ifdef MOZ_LOGGING1 |
40 | nsAutoCString GetDebugTag() const; |
41 | void* GetLoggingWidget() const { return mLoggingWidget; }; |
42 | void SetLoggingWidget(void* aWidget) { mLoggingWidget = aWidget; } |
43 | #endif |
44 | |
45 | void ReadyToDrawFrameCallbackHandler(struct wl_callback* aCallback); |
46 | void AddOrFireReadyToDrawCallback(const std::function<void(void)>& aDrawCB); |
47 | void ClearReadyToDrawCallbacks(); |
48 | |
49 | void FrameCallbackHandler(struct wl_callback* aCallback, uint32_t aTime, |
50 | bool aRoutedFromChildSurface); |
51 | |
52 | // Run frame callback repeatedly. Callback is removed on Unmap. |
53 | // If aEmulateFrameCallback is set to true and WaylandSurface is mapped and |
54 | // ready to draw and we don't have buffer attached yet, |
55 | // fire aFrameCallbackHandler without frame callback from |
56 | // compositor in sFrameCheckTimeoutMs. |
57 | void SetFrameCallbackLocked( |
58 | const WaylandSurfaceLock& aProofOfLock, |
59 | const std::function<void(wl_callback*, uint32_t)>& aFrameCallbackHandler, |
60 | bool aEmulateFrameCallback = false); |
61 | |
62 | // Enable/Disable any frame callback emission (includes emulated ones). |
63 | void SetFrameCallbackStateLocked(const WaylandSurfaceLock& aProofOfLock, |
64 | bool aEnabled); |
65 | void SetFrameCallbackStateHandlerLocked( |
66 | const WaylandSurfaceLock& aProofOfLock, |
67 | const std::function<void(bool)>& aFrameCallbackStateHandler); |
68 | |
69 | // Create and resize EGL window. |
70 | // GetEGLWindow() takes unscaled window size as we derive size from GdkWindow. |
71 | // It's scaled internally by WaylandSurface fractional scale. |
72 | wl_egl_window* GetEGLWindow(nsIntSize aUnscaledSize); |
73 | // SetEGLWindowSize() takes scaled size - it's called from rendering code |
74 | // which uses scaled sizes. |
75 | bool SetEGLWindowSize(nsIntSize aScaledSize); |
76 | bool HasEGLWindow() const { return !!mEGLWindow; } |
77 | |
78 | // Read to draw means we got frame callback from parent surface |
79 | // where we attached to. |
80 | bool IsReadyToDraw() const { return mIsReadyToDraw; } |
81 | // Mapped means we have all internals created. |
82 | bool IsMapped() const { return mIsMapped; } |
83 | // Indicate that Wayland surface uses Gdk resources which |
84 | // need to be released on main thread by GdkCleanUpLocked(). |
85 | // It may be called after Unmap() to make sure |
86 | // Gtk resources are not allocated again. |
87 | bool IsPendingGdkCleanup() const { return mIsPendingGdkCleanup; } |
88 | |
89 | bool IsOpaqueSurfaceHandlerSet() const { return mIsOpaqueSurfaceHandlerSet; } |
90 | |
91 | bool HasBufferAttached() const { return mBufferAttached; } |
92 | |
93 | // Mapped as direct surface of MozContainer |
94 | bool MapLocked(const WaylandSurfaceLock& aProofOfLock, |
95 | wl_surface* aParentWLSurface, |
96 | gfx::IntPoint aSubsurfacePosition); |
97 | // Mapped as child of WaylandSurface (used by layers) |
98 | bool MapLocked(const WaylandSurfaceLock& aProofOfLock, |
99 | WaylandSurfaceLock* aParentWaylandSurfaceLock, |
100 | gfx::IntPoint aSubsurfacePosition); |
101 | // Unmap surface which hides it |
102 | void UnmapLocked(WaylandSurfaceLock& aSurfaceLock); |
103 | |
104 | // Clean up Gdk resources, on main thread only |
105 | void GdkCleanUpLocked(const WaylandSurfaceLock& aProofOfLock); |
106 | |
107 | // Allow to register and run unmap callback. |
108 | // Unmap callback needs to be called *before* UnmapLocked() call |
109 | // on main thread. |
110 | void SetUnmapCallbackLocked(const WaylandSurfaceLock& aProofOfLock, |
111 | const std::function<void(void)>& aUnmapCB); |
112 | void ClearUnmapCallbackLocked(const WaylandSurfaceLock& aProofOfLock); |
113 | |
114 | void RunUnmapCallback(); |
115 | |
116 | // Create Viewport to manage surface transformations. |
117 | // aFollowsSizeChanges if set, Viewport destination size |
118 | // is updated according to buffer size. |
119 | bool CreateViewportLocked(const WaylandSurfaceLock& aProofOfLock, |
120 | bool aFollowsSizeChanges); |
121 | |
122 | void AddReadyToDrawCallbackLocked( |
123 | const WaylandSurfaceLock& aProofOfLock, |
124 | const std::function<void(void)>& aInitialDrawCB); |
125 | |
126 | // Attach WaylandBuffer which shows WaylandBuffer content |
127 | // on screen. |
128 | bool AttachLocked(const WaylandSurfaceLock& aSurfaceLock, |
129 | RefPtr<WaylandBuffer> aWaylandBuffer); |
130 | |
131 | // If there's any WaylandBuffer recently attached, detach it. |
132 | // It makes the WaylandSurface invisible and it doesn't have any |
133 | // content. |
134 | void RemoveAttachedBufferLocked(const WaylandSurfaceLock& aProofOfLock); |
135 | |
136 | // Called from Wayland compostor async handler when wl_buffer is |
137 | // detached or deleted. |
138 | void BufferFreeCallbackHandler(uintptr_t aWlBufferID, bool aWlBufferDelete); |
139 | |
140 | // CommitLocked() is needed to call after some of *Locked() method |
141 | // to submit the action to Wayland compositor by wl_surface_commit(). |
142 | |
143 | // It's possible to stack more *Locked() methods |
144 | // together and do commit after the last one to do the changes in atomic way. |
145 | |
146 | // Need of commit is tracked by mSurfaceNeedsCommit flag and |
147 | // if it's set, CommitLocked() is called when WaylandSurfaceLock is destroyed |
148 | // and WaylandSurface is unlocked. |
149 | void CommitLocked(const WaylandSurfaceLock& aProofOfLock, |
150 | bool aForceCommit = false, bool aForceDisplayFlush = false); |
151 | |
152 | void EnableDMABufFormatsLocked( |
153 | const WaylandSurfaceLock& aProofOfLock, |
154 | const std::function<void(DMABufFormats*)>& aFormatRefreshCB); |
155 | void DisableDMABufFormatsLocked(const WaylandSurfaceLock& aProofOfLock); |
156 | |
157 | // Place this WaylandSurface above aLowerSurface |
158 | void PlaceAboveLocked(const WaylandSurfaceLock& aProofOfLock, |
159 | WaylandSurfaceLock& aLowerSurfaceLock); |
160 | void MoveLocked(const WaylandSurfaceLock& aProofOfLock, |
161 | gfx::IntPoint aPosition); |
162 | void SetViewPortSourceRectLocked(const WaylandSurfaceLock& aProofOfLock, |
163 | gfx::Rect aRect); |
164 | void SetViewPortDestLocked(const WaylandSurfaceLock& aProofOfLock, |
165 | gfx::IntSize aDestSize); |
166 | void SetTransformFlippedLocked(const WaylandSurfaceLock& aProofOfLock, |
167 | bool aFlippedX, bool aFlippedY); |
168 | |
169 | void SetOpaqueRegion(const gfx::IntRegion& aRegion); |
170 | void SetOpaqueRegionLocked(const WaylandSurfaceLock& aProofOfLock, |
171 | const gfx::IntRegion& aRegion); |
172 | void SetOpaqueLocked(const WaylandSurfaceLock& aProofOfLock); |
173 | void ClearOpaqueRegionLocked(const WaylandSurfaceLock& aProofOfLock); |
174 | |
175 | bool DisableUserInputLocked(const WaylandSurfaceLock& aProofOfLock); |
176 | void InvalidateRegionLocked(const WaylandSurfaceLock& aProofOfLock, |
177 | const gfx::IntRegion& aInvalidRegion); |
178 | void InvalidateLocked(const WaylandSurfaceLock& aProofOfLock); |
179 | |
180 | bool EnableFractionalScaleLocked( |
181 | const WaylandSurfaceLock& aProofOfLock, |
182 | std::function<void(void)> aFractionalScaleCallback, bool aManageViewport); |
183 | bool EnableCeiledScaleLocked(const WaylandSurfaceLock& aProofOfLock); |
184 | |
185 | bool IsFractionalScaleLocked(const WaylandSurfaceLock& aProofOfLock) const { |
186 | return mScaleType == ScaleType::Disabled; |
187 | } |
188 | bool IsCeiledScaleLocked(const WaylandSurfaceLock& aProofOfLock) const { |
189 | return mScaleType == ScaleType::Ceiled; |
190 | } |
191 | bool IsScaleEnabledLocked(const WaylandSurfaceLock& aProofOfLock) const { |
192 | return mScaleType != ScaleType::Disabled; |
193 | } |
194 | |
195 | // Returns scale as float point number. If WaylandSurface is not mapped, |
196 | // return fractional scale of parent surface. |
197 | // Returns sNoScale is we can't get it. |
198 | static constexpr const double sNoScale = -1; |
199 | double GetScale(); |
200 | |
201 | // The same as GetScale() but returns monitor scale if window scale is |
202 | // missing. |
203 | double GetScaleSafe(); |
204 | |
205 | // Called when screen ceiled scale changed or set initial scale before we map |
206 | // and paint the surface. |
207 | void SetCeiledScaleLocked(const WaylandSurfaceLock& aProofOfLock, |
208 | int aScreenCeiledScale); |
209 | |
210 | // Called by wayland compositor when fractional scale is changed. |
211 | static void FractionalScaleHandler(void* data, |
212 | struct wp_fractional_scale_v1* info, |
213 | uint32_t wire_scale); |
214 | |
215 | static void AfterPaintHandler(GdkFrameClock* aClock, void* aData); |
216 | |
217 | // See https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3111 why we use it. |
218 | // If child surface covers whole area of parent surface and it's opaque, |
219 | // parent surface will not get any events (frame callbacks) from compositor |
220 | // as it's considered as invisible. |
221 | // |
222 | // Firefox uses the parent wl_surface (owned by GdkWindow) to get input |
223 | // events. Without gdk_wayland_window_add_frame_callback_surface() call, |
224 | // Gdk is not getting any events from compostor and we're frozen. |
225 | // |
226 | // So gdk_wayland_window_add_frame_callback_surface() registers wl_surface |
227 | // owned by WaylandSurface to GtkWindow and requests frame callback |
228 | // for it. Such frame callback is then routed to GdkWindow and it's used |
229 | // to fire events like native GdkWindow ones. |
230 | // |
231 | // To make sure WaylandSurface's wl_surface frame callback is generated, |
232 | // we need to commit the wl_surface regularly as Gdk registers frame callback |
233 | // for it at on_frame_clock_after_paint() event of GdkWindow. |
234 | bool AddOpaqueSurfaceHandlerLocked(const WaylandSurfaceLock& aProofOfLock, |
235 | GdkWindow* aGdkWindow, |
236 | bool aRegisterCommitHandler); |
237 | bool RemoveOpaqueSurfaceHandlerLocked(const WaylandSurfaceLock& aProofOfLock); |
238 | |
239 | // Additional callback to call from on_frame_clock_after_paint() |
240 | // and before this wl_surface is commited. |
241 | // It can be used to update subsurfaces from main thread. |
242 | void SetGdkCommitCallbackLocked( |
243 | const WaylandSurfaceLock& aProofOfLock, |
244 | const std::function<void(void)>& aGdkCommitCB); |
245 | void ClearGdkCommitCallbackLocked(const WaylandSurfaceLock& aProofOfLock); |
246 | |
247 | RefPtr<DMABufFormats> GetDMABufFormats() const { return mFormats; } |
248 | |
249 | GdkWindow* GetGdkWindow() const; |
250 | |
251 | static bool IsOpaqueRegionEnabled(); |
252 | |
253 | void SetParentLocked(const WaylandSurfaceLock& aProofOfLock, |
254 | RefPtr<WaylandSurface> aParent); |
255 | |
256 | bool EnableColorManagementLocked(const WaylandSurfaceLock& aProofOfLock); |
257 | |
258 | static void ImageDescriptionFailed( |
259 | void* aData, struct wp_image_description_v1* aImageDescription, |
260 | uint32_t aCause, const char* aMsg); |
261 | static void ImageDescriptionReady( |
262 | void* aData, struct wp_image_description_v1* aImageDescription, |
263 | uint32_t aIdentity); |
264 | |
265 | void AssertCurrentThreadOwnsMutex(); |
266 | |
267 | private: |
268 | ~WaylandSurface(); |
269 | |
270 | bool MapLocked(const WaylandSurfaceLock& aProofOfLock, |
271 | wl_surface* aParentWLSurface, |
272 | WaylandSurfaceLock* aParentWaylandSurfaceLock, |
273 | gfx::IntPoint aSubsurfacePosition, bool aSubsurfaceDesync, |
274 | bool aUseReadyToDrawCallback = true); |
275 | |
276 | void SetSizeLocked(const WaylandSurfaceLock& aProofOfLock, |
277 | gfx::IntSize aSizeScaled, gfx::IntSize aUnscaledSize); |
278 | |
279 | wl_surface* Lock(WaylandSurfaceLock* aWaylandSurfaceLock); |
280 | void Unlock(struct wl_surface** aSurface, |
281 | WaylandSurfaceLock* aWaylandSurfaceLock); |
282 | void Commit(WaylandSurfaceLock* aProofOfLock, bool aForceCommit, |
283 | bool aForceDisplayFlush); |
284 | |
285 | // Force release/detele all buffers. Some of them may be attached to |
286 | // compostor and may get wl_buffer::release callback so we need to sync |
287 | // delete with wayland compostor. |
288 | void ReleaseAllWaylandBuffersLocked(WaylandSurfaceLock& aSurfaceLock); |
289 | |
290 | void RequestFrameCallbackLocked(const WaylandSurfaceLock& aProofOfLock); |
291 | void ClearFrameCallbackLocked(const WaylandSurfaceLock& aProofOfLock); |
292 | bool HasEmulatedFrameCallbackLocked( |
293 | const WaylandSurfaceLock& aProofOfLock) const; |
294 | |
295 | void ClearReadyToDrawCallbacksLocked(const WaylandSurfaceLock& aProofOfLock); |
296 | |
297 | void ClearScaleLocked(const WaylandSurfaceLock& aProofOfLock); |
298 | |
299 | // Weak ref to owning widget (nsWindow or NativeLayerWayland), |
300 | // used for diagnostics/logging only. |
301 | void* mLoggingWidget = nullptr; |
302 | |
303 | // WaylandSurface mapped - we have valid wl_surface where we can paint to. |
304 | mozilla::Atomic<bool, mozilla::Relaxed> mIsMapped{false}; |
305 | |
306 | // Wayland shows only subsurfaces of visible parent surfaces. |
307 | // mIsReadyToDraw means our parent wl_surface has content so |
308 | // this WaylandSurface can be visible on screen and get get frame callback. |
309 | mozilla::Atomic<bool, mozilla::Relaxed> mIsReadyToDraw{false}; |
310 | |
311 | // We used Gdk functions which needs clean up in main thread. |
312 | mozilla::Atomic<bool, mozilla::Relaxed> mIsPendingGdkCleanup{false}; |
313 | |
314 | std::function<void(void)> mGdkCommitCallback; |
315 | std::function<void(void)> mUnmapCallback; |
316 | |
317 | // Scaled surface size, ceiled or fractional. |
318 | // This reflects real surface size which we paint. |
319 | gfx::IntSize mSizeScaled; |
320 | |
321 | // Parent GdkWindow where we paint to, directly or via subsurface. |
322 | RefPtr<GdkWindow> mGdkWindow; |
323 | |
324 | // Parent wl_surface owned by mGdkWindow. It's used when we're attached |
325 | // directly to MozContainer. |
326 | wl_surface* mParentSurface = nullptr; |
327 | |
328 | // Parent WaylandSurface. |
329 | // |
330 | // Layer rendering (compositor) uses mSurface directly attached to |
331 | // wl_surface owned by mParent. |
332 | // |
333 | // For non-compositing rendering (old) mParent is WaylandSurface |
334 | // owned by parent nsWindow. |
335 | RefPtr<WaylandSurface> mParent; |
336 | |
337 | // wl_surface setup/states |
338 | wl_surface* mSurface = nullptr; |
339 | bool mSurfaceNeedsCommit = false; |
340 | wl_subsurface* mSubsurface = nullptr; |
341 | gfx::IntPoint mSubsurfacePosition{-1, -1}; |
342 | |
343 | // Wayland buffers recently attached to this surface or held by |
344 | // Wayland compositor. |
345 | // There may be more than one buffer attached, for instance if |
346 | // previous buffer is hold by compositor. We need to keep |
347 | // there buffers live until compositor notify us that we |
348 | // can release them. |
349 | AutoTArray<RefPtr<WaylandBuffer>, 3> mAttachedBuffers; |
350 | |
351 | // Indicates mSurface has buffer attached so we can attach subsurface |
352 | // to it and expect to get frame callbacks from Wayland compositor. |
353 | // We set it at AttachLocked() or when we get first frame callback |
354 | // (when EGL is used). |
355 | mozilla::Atomic<bool, mozilla::Relaxed> mBufferAttached{false}; |
356 | |
357 | mozilla::Atomic<wl_egl_window*, mozilla::Relaxed> mEGLWindow{nullptr}; |
358 | |
359 | bool mViewportFollowsSizeChanges = true; |
360 | wp_viewport* mViewport = nullptr; |
361 | gfx::Rect mViewportSourceRect{-1, -1, -1, -1}; |
362 | gfx::IntSize mViewportDestinationSize{-1, -1}; |
363 | |
364 | // Surface flip state on X/Y asix |
365 | bool mBufferTransformFlippedX = false; |
366 | bool mBufferTransformFlippedY = false; |
367 | |
368 | // Frame callback registered to parent surface. When we get it we know |
369 | // parent surface is ready and we can paint. |
370 | wl_callback* mReadyToDrawFrameCallback = nullptr; |
371 | std::vector<std::function<void(void)>> mReadyToDrawCallbacks; |
372 | |
373 | // Frame callbacks of this surface |
374 | wl_callback* mFrameCallback = nullptr; |
375 | |
376 | struct FrameCallback { |
377 | std::function<void(wl_callback*, uint32_t)> mCb = nullptr; |
378 | bool mEmulated = false; |
379 | bool IsSet() const { return !!mCb; } |
380 | void Clear() { mCb = nullptr; } |
381 | }; |
382 | |
383 | bool mFrameCallbackEnabled = true; |
384 | std::function<void(bool)> mFrameCallbackStateHandler = nullptr; |
385 | |
386 | // Frame callback handler called every frame |
387 | FrameCallback mFrameCallbackHandler; |
388 | |
389 | // WaylandSurface is used from Compositor/Rendering/Main threads. |
390 | mozilla::Mutex mMutex{"WaylandSurface"}; |
391 | WaylandSurfaceLock* mSurfaceLock = nullptr; |
392 | |
393 | // We may mark part of mSurface as opaque (non-transparent) if it's supported |
394 | // by Gtk which allows compositor to skip painting of covered parts. |
395 | mozilla::Atomic<bool, mozilla::Relaxed> mIsOpaqueSurfaceHandlerSet{false}; |
396 | gulong mGdkAfterPaintId = 0; |
397 | static bool sIsOpaqueRegionEnabled; |
398 | static void (*sGdkWaylandWindowAddCallbackSurface)(GdkWindow*, |
399 | struct wl_surface*); |
400 | static void (*sGdkWaylandWindowRemoveCallbackSurface)(GdkWindow*, |
401 | struct wl_surface*); |
402 | guint mEmulatedFrameCallbackTimerID = 0; |
403 | constexpr static int sEmulatedFrameCallbackTimeoutMs = (int)(1000.0 / 60.0); |
404 | |
405 | // We use two scale systems in Firefox/Wayland. Ceiled (integer) scale and |
406 | // fractional scale. Ceiled scale is easy to implement but comes with |
407 | // rendering overhead while fractional rendering paints buffers with exact |
408 | // scale. |
409 | // |
410 | // Fractional scale is used as rendering optimization. |
411 | // For instance if 225% scale is used, ceiled scale is 3 |
412 | // and fractional 2.20. |
413 | // |
414 | // If we paint content with ceiled scale 3 and desktop uses scale 225%, |
415 | // Wayland compositor downscales buffer to 2.20 on rendering |
416 | // but we paint more pixels than neccessary (so we use name ceiled). |
417 | // |
418 | // Scale is used by wp_viewport. If a surface has a surface-local size |
419 | // of 100 px by 50 px and wishes to submit buffers with a scale of 1.5, |
420 | // then a buffer of 150px by 75 px should be used and the wp_viewport |
421 | // destination rectangle should be 100 px by 50 px. |
422 | // The wl_surface buffer scale should remain set to 1. |
423 | // |
424 | // For scale 2 (200%) we use surface size 200 x 100 px and set |
425 | // viewport size to 100 x 50 px. |
426 | // |
427 | // We're getting fractional scale number with a small delay from |
428 | // wp_fractional_scale_v1 after fist commit to surface. |
429 | // Meanwhile we can use ceiled scale number instead of fractional one or |
430 | // get fractional scale from parent window (if there's any). |
431 | // |
432 | enum class ScaleType { |
433 | Disabled, |
434 | Ceiled, |
435 | Fractional, |
436 | }; |
437 | |
438 | ScaleType mScaleType = ScaleType::Disabled; |
439 | |
440 | // mScreenScale is set from main thread only but read from |
441 | // different threads. |
442 | mozilla::Atomic<double, mozilla::Relaxed> mScreenScale{sNoScale}; |
443 | |
444 | wp_fractional_scale_v1* mFractionalScaleListener = nullptr; |
445 | |
446 | // mFractionalScaleCallback is called from |
447 | // wp_fractional_scale_v1_add_listener when scale is changed. |
448 | std::function<void(void)> mFractionalScaleCallback = []() {}; |
449 | |
450 | bool mUseDMABufFormats = false; |
451 | // Wayland display notifies us when available DRM formats are are changed. |
452 | // For instance if wl_surface becomes fullscreen we may get DRM formats |
453 | // for direct scanout. |
454 | std::function<void(DMABufFormats*)> mDMABufFormatRefreshCallback; |
455 | RefPtr<DMABufFormats> mFormats; |
456 | |
457 | // HDR support |
458 | bool mHDRSet = false; |
459 | wp_color_management_surface_v1* mColorSurface = nullptr; |
460 | wp_image_description_v1* mImageDescription = nullptr; |
461 | }; |
462 | |
463 | } // namespace mozilla::widget |
464 | |
465 | #endif /* __MOZ_WAYLAND_SURFACE_H__ */ |