Bug 1822393 - Consume GeckoView directly in Android Components for CI builds. r=owlis...
[gecko.git] / gfx / ipc / CrossProcessPaint.h
blob55dc9a8b048342ab1e57c8a5b3f8f30f7432eb17
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"
17 #include "nsColor.h"
18 #include "nsTHashMap.h"
19 #include "nsHashKeys.h"
20 #include "nsRefPtrHashtable.h"
21 #include "nsTHashSet.h"
23 class nsIDocShell;
25 namespace IPC {
26 template <typename T>
27 struct ParamTraits;
28 } // namespace IPC
30 namespace mozilla {
32 namespace dom {
33 class CanonicalBrowsingContext;
34 class DOMRect;
35 class Promise;
36 class WindowGlobalParent;
37 } // namespace dom
39 namespace gfx {
41 class CrossProcessPaint;
43 enum class CrossProcessPaintFlags {
44 None = 0,
45 DrawView = 1 << 1,
46 ResetScrollPosition = 1 << 2,
47 UseHighQualityScaling = 1 << 3,
50 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CrossProcessPaintFlags)
52 /**
53 * A fragment of a paint of a cross process document tree.
55 class PaintFragment final {
56 public:
57 /// Initializes an empty PaintFragment
58 PaintFragment() = default;
60 /**
61 * Creates a paint fragment by recording the draw commands and dependent tabs
62 * for a BrowsingContext.
64 * @param aBrowsingContext The frame to record.
65 * @param aRect The rectangle relative to the viewport to use. If no
66 * rectangle is specified, then the whole viewport will be used.
67 * @param aScale The coordinate scale to use. The size of the resolved
68 * surface will be `aRect.Size() * aScale`, with aScale clamped to
69 * at least kMinPaintScale.
70 * @param aBackgroundColor The background color to use.
72 * @return A paint fragment. The paint fragment may be `empty` if rendering
73 * was unable to be accomplished for some reason.
75 static PaintFragment Record(dom::BrowsingContext* aBc,
76 const Maybe<IntRect>& aRect, float aScale,
77 nscolor aBackgroundColor,
78 CrossProcessPaintFlags aFlags);
80 /// Returns whether this paint fragment contains a valid recording.
81 bool IsEmpty() const;
83 PaintFragment(PaintFragment&&) = default;
84 PaintFragment& operator=(PaintFragment&&) = default;
86 protected:
87 friend struct mozilla::ipc::IPDLParamTraits<PaintFragment>;
88 friend CrossProcessPaint;
90 typedef mozilla::ipc::ByteBuf ByteBuf;
92 PaintFragment(IntSize, ByteBuf&&, nsTHashSet<uint64_t>&&);
94 IntSize mSize;
95 ByteBuf mRecording;
96 nsTHashSet<uint64_t> mDependencies;
99 /**
100 * An object for painting a cross process document tree.
102 class CrossProcessPaint final {
103 NS_INLINE_DECL_REFCOUNTING(CrossProcessPaint);
105 public:
106 typedef nsRefPtrHashtable<nsUint64HashKey, RecordedDependentSurface>
107 ResolvedFragmentMap;
108 typedef MozPromise<ResolvedFragmentMap, nsresult, true> ResolvePromise;
110 * Begin an asynchronous paint of a cross process document tree starting at
111 * a WindowGlobalParent. A maybe-async paint for the root WGP will be done,
112 * then async paints will be recursively queued for remote subframes. Once
113 * all subframes have been recorded, the final image will be resolved, and
114 * the promise will be resolved with a dom::ImageBitmap.
116 * @param aRoot The WindowGlobalParent to paint.
117 * @param aRect The rectangle relative to the viewport to use, or null to
118 * render the whole viewport.
119 * @param aScale The coordinate scale to use. The size of the resolved
120 * surface will be `aRect.Size() * aScale`, with aScale clamped to
121 * at least kMinPaintScale. See the implementation for the current
122 * minimum value.
123 * @param aBackgroundColor The background color to use.
124 * @param aPromise The promise to resolve with a dom::ImageBitmap.
126 * @returns Whether the paint was able to be initiated or not.
128 static bool Start(dom::WindowGlobalParent* aRoot, const dom::DOMRect* aRect,
129 float aScale, nscolor aBackgroundColor,
130 CrossProcessPaintFlags aFlags, dom::Promise* aPromise);
132 static RefPtr<ResolvePromise> Start(nsTHashSet<uint64_t>&& aDependencies);
134 void ReceiveFragment(dom::WindowGlobalParent* aWGP,
135 PaintFragment&& aFragment);
136 void LostFragment(dom::WindowGlobalParent* aWGP);
138 private:
139 typedef nsTHashMap<nsUint64HashKey, PaintFragment> ReceivedFragmentMap;
141 CrossProcessPaint(float aScale, dom::TabId aRoot,
142 CrossProcessPaintFlags aFlags);
143 ~CrossProcessPaint();
145 void QueueDependencies(const nsTHashSet<uint64_t>& aDependencies);
147 void QueuePaint(
148 dom::WindowGlobalParent* aWGP, const Maybe<IntRect>& aRect,
149 nscolor aBackgroundColor = NS_RGBA(0, 0, 0, 0),
150 CrossProcessPaintFlags aFlags = CrossProcessPaintFlags::DrawView);
152 void QueuePaint(dom::CanonicalBrowsingContext* aBc);
154 /// Clear the state of this paint so that it cannot be resolved or receive
155 /// any paint fragments.
156 void Clear(nsresult aStatus);
158 /// Returns if this paint has been cleared.
159 bool IsCleared() const;
161 /// Resolves the paint fragments if we have none pending and resolves the
162 /// promise.
163 void MaybeResolve();
164 nsresult ResolveInternal(dom::TabId aTabId, ResolvedFragmentMap* aResolved);
166 RefPtr<ResolvePromise> Init() {
167 MOZ_ASSERT(mPromise.IsEmpty());
168 return mPromise.Ensure(__func__);
171 // UseHighQualityScaling is the only flag that dependencies inherit, and we
172 // always want to use DrawView for dependencies.
173 CrossProcessPaintFlags GetFlagsForDependencies() const {
174 return (mFlags & CrossProcessPaintFlags::UseHighQualityScaling) |
175 CrossProcessPaintFlags::DrawView;
178 MozPromiseHolder<ResolvePromise> mPromise;
179 dom::TabId mRoot;
180 float mScale;
181 uint32_t mPendingFragments;
182 ReceivedFragmentMap mReceivedFragments;
183 CrossProcessPaintFlags mFlags;
186 } // namespace gfx
187 } // namespace mozilla
189 #endif // _include_mozilla_gfx_ipc_CrossProcessPaint_h_