| 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__ */ |