Bug 1698238 add a GetUserMediaRequest variant for selectAudioOutput() r=jib,emilio
[gecko.git] / gfx / ipc / CrossProcessPaint.h
blob1aa394bda2ffe39598caf25346e989d803b19616
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 DOMRect;
34 class Promise;
35 class WindowGlobalParent;
36 } // namespace dom
38 namespace gfx {
40 class CrossProcessPaint;
42 enum class CrossProcessPaintFlags {
43 None = 0,
44 DrawView = 1 << 1,
47 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CrossProcessPaintFlags)
49 /**
50 * A fragment of a paint of a cross process document tree.
52 class PaintFragment final {
53 public:
54 /// Initializes an empty PaintFragment
55 PaintFragment() = default;
57 /**
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.
78 bool IsEmpty() const;
80 PaintFragment(PaintFragment&&) = default;
81 PaintFragment& operator=(PaintFragment&&) = default;
83 protected:
84 friend struct mozilla::ipc::IPDLParamTraits<PaintFragment>;
85 friend CrossProcessPaint;
87 typedef mozilla::ipc::ByteBuf ByteBuf;
89 PaintFragment(IntSize, ByteBuf&&, nsTHashSet<uint64_t>&&);
91 IntSize mSize;
92 ByteBuf mRecording;
93 nsTHashSet<uint64_t> mDependencies;
96 /**
97 * An object for painting a cross process document tree.
99 class CrossProcessPaint final {
100 NS_INLINE_DECL_REFCOUNTING(CrossProcessPaint);
102 public:
103 typedef nsRefPtrHashtable<nsUint64HashKey, RecordedDependentSurface>
104 ResolvedFragmentMap;
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
119 * minimum value.
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);
135 private:
136 typedef nsTHashMap<nsUint64HashKey, PaintFragment> ReceivedFragmentMap;
138 CrossProcessPaint(float aScale, dom::TabId aRoot);
139 ~CrossProcessPaint();
141 void QueueDependencies(const nsTHashSet<uint64_t>& aDependencies);
143 void QueuePaint(
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
156 /// promise.
157 void MaybeResolve();
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;
166 dom::TabId mRoot;
167 float mScale;
168 uint32_t mPendingFragments;
169 ReceivedFragmentMap mReceivedFragments;
172 } // namespace gfx
173 } // namespace mozilla
175 #endif // _include_mozilla_gfx_ipc_CrossProcessPaint_h_