1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef _include_mozilla_gfx_ipc_CrossProcessPaint_h_
7 #define _include_mozilla_gfx_ipc_CrossProcessPaint_h_
9 #include "nsISupportsImpl.h"
11 #include "mozilla/dom/ipc/IdType.h"
12 #include "mozilla/gfx/Point.h"
13 #include "mozilla/gfx/RecordedEvent.h"
14 #include "mozilla/gfx/Rect.h"
15 #include "mozilla/MozPromise.h"
16 #include "mozilla/ipc/ByteBuf.h"
18 #include "nsTHashMap.h"
19 #include "nsHashKeys.h"
20 #include "nsRefPtrHashtable.h"
21 #include "nsTHashSet.h"
35 class WindowGlobalParent
;
40 class CrossProcessPaint
;
42 enum class CrossProcessPaintFlags
{
47 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CrossProcessPaintFlags
)
50 * A fragment of a paint of a cross process document tree.
52 class PaintFragment final
{
54 /// Initializes an empty PaintFragment
55 PaintFragment() = default;
58 * Creates a paint fragment by recording the draw commands and dependent tabs
59 * for a BrowsingContext.
61 * @param aBrowsingContext The frame to record.
62 * @param aRect The rectangle relative to the viewport to use. If no
63 * rectangle is specified, then the whole viewport will be used.
64 * @param aScale The coordinate scale to use. The size of the resolved
65 * surface will be `aRect.Size() * aScale`, with aScale clamped to
66 * at least kMinPaintScale.
67 * @param aBackgroundColor The background color to use.
69 * @return A paint fragment. The paint fragment may be `empty` if rendering
70 * was unable to be accomplished for some reason.
72 static PaintFragment
Record(dom::BrowsingContext
* aBc
,
73 const Maybe
<IntRect
>& aRect
, float aScale
,
74 nscolor aBackgroundColor
,
75 CrossProcessPaintFlags aFlags
);
77 /// Returns whether this paint fragment contains a valid recording.
80 PaintFragment(PaintFragment
&&) = default;
81 PaintFragment
& operator=(PaintFragment
&&) = default;
84 friend struct mozilla::ipc::IPDLParamTraits
<PaintFragment
>;
85 friend CrossProcessPaint
;
87 typedef mozilla::ipc::ByteBuf ByteBuf
;
89 PaintFragment(IntSize
, ByteBuf
&&, nsTHashSet
<uint64_t>&&);
93 nsTHashSet
<uint64_t> mDependencies
;
97 * An object for painting a cross process document tree.
99 class CrossProcessPaint final
{
100 NS_INLINE_DECL_REFCOUNTING(CrossProcessPaint
);
103 typedef nsRefPtrHashtable
<nsUint64HashKey
, RecordedDependentSurface
>
105 typedef MozPromise
<ResolvedFragmentMap
, nsresult
, true> ResolvePromise
;
107 * Begin an asynchronous paint of a cross process document tree starting at
108 * a WindowGlobalParent. A maybe-async paint for the root WGP will be done,
109 * then async paints will be recursively queued for remote subframes. Once
110 * all subframes have been recorded, the final image will be resolved, and
111 * the promise will be resolved with a dom::ImageBitmap.
113 * @param aRoot The WindowGlobalParent to paint.
114 * @param aRect The rectangle relative to the viewport to use, or null to
115 * render the whole viewport.
116 * @param aScale The coordinate scale to use. The size of the resolved
117 * surface will be `aRect.Size() * aScale`, with aScale clamped to
118 * at least kMinPaintScale. See the implementation for the current
120 * @param aBackgroundColor The background color to use.
121 * @param aPromise The promise to resolve with a dom::ImageBitmap.
123 * @returns Whether the paint was able to be initiated or not.
125 static bool Start(dom::WindowGlobalParent
* aRoot
, const dom::DOMRect
* aRect
,
126 float aScale
, nscolor aBackgroundColor
,
127 CrossProcessPaintFlags aFlags
, dom::Promise
* aPromise
);
129 static RefPtr
<ResolvePromise
> Start(nsTHashSet
<uint64_t>&& aDependencies
);
131 void ReceiveFragment(dom::WindowGlobalParent
* aWGP
,
132 PaintFragment
&& aFragment
);
133 void LostFragment(dom::WindowGlobalParent
* aWGP
);
136 typedef nsTHashMap
<nsUint64HashKey
, PaintFragment
> ReceivedFragmentMap
;
138 CrossProcessPaint(float aScale
, dom::TabId aRoot
);
139 ~CrossProcessPaint();
141 void QueueDependencies(const nsTHashSet
<uint64_t>& aDependencies
);
144 dom::WindowGlobalParent
* aWGP
, const Maybe
<IntRect
>& aRect
,
145 nscolor aBackgroundColor
= NS_RGBA(0, 0, 0, 0),
146 CrossProcessPaintFlags aFlags
= CrossProcessPaintFlags::DrawView
);
148 /// Clear the state of this paint so that it cannot be resolved or receive
149 /// any paint fragments.
150 void Clear(nsresult aStatus
);
152 /// Returns if this paint has been cleared.
153 bool IsCleared() const;
155 /// Resolves the paint fragments if we have none pending and resolves the
158 nsresult
ResolveInternal(dom::TabId aTabId
, ResolvedFragmentMap
* aResolved
);
160 RefPtr
<ResolvePromise
> Init() {
161 MOZ_ASSERT(mPromise
.IsEmpty());
162 return mPromise
.Ensure(__func__
);
165 MozPromiseHolder
<ResolvePromise
> mPromise
;
168 uint32_t mPendingFragments
;
169 ReceivedFragmentMap mReceivedFragments
;
173 } // namespace mozilla
175 #endif // _include_mozilla_gfx_ipc_CrossProcessPaint_h_