-
Notifications
You must be signed in to change notification settings - Fork 54
/
CrossProcessPaint.h
160 lines (131 loc) · 5.28 KB
/
CrossProcessPaint.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _include_mozilla_gfx_ipc_CrossProcessPaint_h_
#define _include_mozilla_gfx_ipc_CrossProcessPaint_h_
#include "nsISupportsImpl.h"
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/DOMRect.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/Maybe.h"
#include "mozilla/ipc/ByteBuf.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "nsRefPtrHashtable.h"
#include "nsTHashtable.h"
namespace IPC {
template <typename T>
struct ParamTraits;
} // namespace IPC
namespace mozilla {
namespace dom {
class WindowGlobalParent;
} // namespace dom
namespace gfx {
class CrossProcessPaint;
enum class CrossProcessPaintFlags {
None = 0,
DrawView = 1 << 1,
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CrossProcessPaintFlags)
/**
* A fragment of a paint of a cross process document tree.
*/
class PaintFragment final {
public:
/// Initializes an empty PaintFragment
PaintFragment() = default;
/**
* Creates a paint fragment by recording the draw commands and dependent tabs
* for an nsIDocShell.
*
* @param aDocShell The document shell to record.
* @param aRect The rectangle relative to the viewport to use. If no
* rectangle is specified, then the whole viewport will be used.
* @param aScale The coordinate scale to use. The size of the resolved
* surface will be `aRect.Size() * aScale`, with aScale clamped to
* at least kMinPaintScale.
* @param aBackgroundColor The background color to use.
*
* @return A paint fragment. The paint fragment may be `empty` if rendering
* was unable to be accomplished for some reason.
*/
static PaintFragment Record(nsIDocShell* aDocShell,
const Maybe<IntRect>& aRect, float aScale,
nscolor aBackgroundColor,
CrossProcessPaintFlags aFlags);
/// Returns whether this paint fragment contains a valid recording.
bool IsEmpty() const;
PaintFragment(PaintFragment&&) = default;
PaintFragment& operator=(PaintFragment&&) = default;
protected:
friend struct mozilla::ipc::IPDLParamTraits<PaintFragment>;
friend CrossProcessPaint;
typedef mozilla::ipc::ByteBuf ByteBuf;
PaintFragment(IntSize, ByteBuf&&, nsTHashtable<nsUint64HashKey>&&);
IntSize mSize;
ByteBuf mRecording;
nsTHashtable<nsUint64HashKey> mDependencies;
};
/**
* An object for painting a cross process document tree.
*/
class CrossProcessPaint final {
NS_INLINE_DECL_REFCOUNTING(CrossProcessPaint);
public:
/**
* Begin an asynchronous paint of a cross process document tree starting at
* a WindowGlobalParent. A maybe-async paint for the root WGP will be done,
* then async paints will be recursively queued for remote subframes. Once
* all subframes have been recorded, the final image will be resolved, and
* the promise will be resolved with a dom::ImageBitmap.
*
* @param aRoot The WindowGlobalParent to paint.
* @param aRect The rectangle relative to the viewport to use, or null to
* render the whole viewport.
* @param aScale The coordinate scale to use. The size of the resolved
* surface will be `aRect.Size() * aScale`, with aScale clamped to
* at least kMinPaintScale. See the implementation for the current
* minimum value.
* @param aBackgroundColor The background color to use.
* @param aPromise The promise to resolve with a dom::ImageBitmap.
*
* @returns Whether the paint was able to be initiated or not.
*/
static bool Start(dom::WindowGlobalParent* aRoot, const dom::DOMRect* aRect,
float aScale, nscolor aBackgroundColor,
CrossProcessPaintFlags aFlags, dom::Promise* aPromise);
void ReceiveFragment(dom::WindowGlobalParent* aWGP,
PaintFragment&& aFragment);
void LostFragment(dom::WindowGlobalParent* aWGP);
private:
typedef nsRefPtrHashtable<nsUint64HashKey, SourceSurface> ResolvedSurfaceMap;
typedef nsDataHashtable<nsUint64HashKey, PaintFragment> ReceivedFragmentMap;
CrossProcessPaint(dom::Promise* aPromise, float aScale,
dom::WindowGlobalParent* aRoot);
~CrossProcessPaint();
void QueuePaint(
dom::WindowGlobalParent* aWGP, const Maybe<IntRect>& aRect,
nscolor aBackgroundColor = NS_RGBA(0, 0, 0, 0),
CrossProcessPaintFlags aFlags = CrossProcessPaintFlags::DrawView);
/// Clear the state of this paint so that it cannot be resolved or receive
/// any paint fragments.
void Clear();
/// Returns if this paint has been cleared.
bool IsCleared() const;
/// Resolves the paint fragments if we have none pending and resolves the
/// promise.
void MaybeResolve();
nsresult ResolveInternal(dom::TabId aTabId, ResolvedSurfaceMap* aResolved);
RefPtr<dom::Promise> mPromise;
RefPtr<dom::WindowGlobalParent> mRoot;
float mScale;
uint32_t mPendingFragments;
ReceivedFragmentMap mReceivedFragments;
};
} // namespace gfx
} // namespace mozilla
#endif // _include_mozilla_gfx_ipc_CrossProcessPaint_h_