| 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 | }; |
| 381 | |
| 382 | bool mFrameCallbackEnabled = true; |
| 383 | std::function<void(bool)> mFrameCallbackStateHandler = nullptr; |
| 384 | |
| 385 | // Frame callback handler called every frame |
| 386 | FrameCallback mFrameCallbackHandler; |
| 387 | |
| 388 | // WaylandSurface is used from Compositor/Rendering/Main threads. |
| 389 | mozilla::Mutex mMutex{"WaylandSurface"}; |
| 390 | WaylandSurfaceLock* mSurfaceLock = nullptr; |
| 391 | |
| 392 | // We may mark part of mSurface as opaque (non-transparent) if it's supported |
| 393 | // by Gtk which allows compositor to skip painting of covered parts. |
| 394 | mozilla::Atomic<bool, mozilla::Relaxed> mIsOpaqueSurfaceHandlerSet{false}; |
| 395 | gulong mGdkAfterPaintId = 0; |
| 396 | static bool sIsOpaqueRegionEnabled; |
| 397 | static void (*sGdkWaylandWindowAddCallbackSurface)(GdkWindow*, |
| 398 | struct wl_surface*); |
| 399 | static void (*sGdkWaylandWindowRemoveCallbackSurface)(GdkWindow*, |
| 400 | struct wl_surface*); |
| 401 | guint mEmulatedFrameCallbackTimerID = 0; |
| 402 | constexpr static int sEmulatedFrameCallbackTimeoutMs = (int)(1000.0 / 60.0); |
| 403 | |
| 404 | // We use two scale systems in Firefox/Wayland. Ceiled (integer) scale and |
| 405 | // fractional scale. Ceiled scale is easy to implement but comes with |
| 406 | // rendering overhead while fractional rendering paints buffers with exact |
| 407 | // scale. |
| 408 | // |
| 409 | // Fractional scale is used as rendering optimization. |
| 410 | // For instance if 225% scale is used, ceiled scale is 3 |
| 411 | // and fractional 2.20. |
| 412 | // |
| 413 | // If we paint content with ceiled scale 3 and desktop uses scale 225%, |
| 414 | // Wayland compositor downscales buffer to 2.20 on rendering |
| 415 | // but we paint more pixels than neccessary (so we use name ceiled). |
| 416 | // |
| 417 | // Scale is used by wp_viewport. If a surface has a surface-local size |
| 418 | // of 100 px by 50 px and wishes to submit buffers with a scale of 1.5, |
| 419 | // then a buffer of 150px by 75 px should be used and the wp_viewport |
| 420 | // destination rectangle should be 100 px by 50 px. |
| 421 | // The wl_surface buffer scale should remain set to 1. |
| 422 | // |
| 423 | // For scale 2 (200%) we use surface size 200 x 100 px and set |
| 424 | // viewport size to 100 x 50 px. |
| 425 | // |
| 426 | // We're getting fractional scale number with a small delay from |
| 427 | // wp_fractional_scale_v1 after fist commit to surface. |
| 428 | // Meanwhile we can use ceiled scale number instead of fractional one or |
| 429 | // get fractional scale from parent window (if there's any). |
| 430 | // |
| 431 | enum class ScaleType { |
| 432 | Disabled, |
| 433 | Ceiled, |
| 434 | Fractional, |
| 435 | }; |
| 436 | |
| 437 | ScaleType mScaleType = ScaleType::Disabled; |
| 438 | |
| 439 | // mScreenScale is set from main thread only but read from |
| 440 | // different threads. |
| 441 | mozilla::Atomic<double, mozilla::Relaxed> mScreenScale{sNoScale}; |
| 442 | |
| 443 | wp_fractional_scale_v1* mFractionalScaleListener = nullptr; |
| 444 | |
| 445 | // mFractionalScaleCallback is called from |
| 446 | // wp_fractional_scale_v1_add_listener when scale is changed. |
| 447 | std::function<void(void)> mFractionalScaleCallback = []() {}; |
| 448 | |
| 449 | bool mUseDMABufFormats = false; |
| 450 | // Wayland display notifies us when available DRM formats are are changed. |
| 451 | // For instance if wl_surface becomes fullscreen we may get DRM formats |
| 452 | // for direct scanout. |
| 453 | std::function<void(DMABufFormats*)> mDMABufFormatRefreshCallback; |
| 454 | RefPtr<DMABufFormats> mFormats; |
| 455 | |
| 456 | // HDR support |
| 457 | bool mHDRSet = false; |
| 458 | wp_color_management_surface_v1* mColorSurface = nullptr; |
| 459 | wp_image_description_v1* mImageDescription = nullptr; |
| 460 | }; |
| 461 | |
| 462 | } // namespace mozilla::widget |
| 463 | |
| 464 | #endif /* __MOZ_WAYLAND_SURFACE_H__ */ |