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 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
/* -*- 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/gfx/Point.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/MozPromise.h"
#include "mozilla/ipc/ByteBuf.h"
#include "nsColor.h"
#include "nsTHashMap.h"
#include "nsHashKeys.h"
#include "nsRefPtrHashtable.h"
#include "nsTHashSet.h"
class nsIDocShell;
namespace IPC {
template <typename T>
struct ParamTraits;
} // namespace IPC
namespace mozilla {
namespace dom {
class CanonicalBrowsingContext;
class DOMRect;
class Promise;
class WindowGlobalParent;
} // namespace dom
namespace gfx {
class CrossProcessPaint;
enum class CrossProcessPaintFlags {
None = 0,
DrawView = 1 << 1,
ResetScrollPosition = 1 << 2,
UseHighQualityScaling = 1 << 3,
};
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 a BrowsingContext.
*
* @param aBrowsingContext The frame 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(dom::BrowsingContext* aBc,
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 IPC::ParamTraits<PaintFragment>;
friend CrossProcessPaint;
typedef mozilla::ipc::ByteBuf ByteBuf;
PaintFragment(IntSize, ByteBuf&&, nsTHashSet<uint64_t>&&);
IntSize mSize;
ByteBuf mRecording;
nsTHashSet<uint64_t> mDependencies;
};
struct RecordedDependentSurface;
/**
* An object for painting a cross process document tree.
*/
class CrossProcessPaint final {
NS_INLINE_DECL_REFCOUNTING(CrossProcessPaint);
public:
typedef nsRefPtrHashtable<nsUint64HashKey, RecordedDependentSurface>
ResolvedFragmentMap;
typedef MozPromise<ResolvedFragmentMap, nsresult, true> ResolvePromise;
/**
* 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);
static RefPtr<ResolvePromise> Start(nsTHashSet<uint64_t>&& aDependencies);
void ReceiveFragment(dom::WindowGlobalParent* aWGP,
PaintFragment&& aFragment);
void LostFragment(dom::WindowGlobalParent* aWGP);
private:
typedef nsTHashMap<nsUint64HashKey, PaintFragment> ReceivedFragmentMap;
CrossProcessPaint(float aScale, dom::TabId aRoot,
CrossProcessPaintFlags aFlags);
~CrossProcessPaint();
void QueueDependencies(const nsTHashSet<uint64_t>& aDependencies);
void QueuePaint(
dom::WindowGlobalParent* aWGP, const Maybe<IntRect>& aRect,
nscolor aBackgroundColor = NS_RGBA(0, 0, 0, 0),
CrossProcessPaintFlags aFlags = CrossProcessPaintFlags::DrawView);
void QueuePaint(dom::CanonicalBrowsingContext* aBc);
/// Clear the state of this paint so that it cannot be resolved or receive
/// any paint fragments.
void Clear(nsresult aStatus);
/// 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, ResolvedFragmentMap* aResolved);
RefPtr<ResolvePromise> Init() {
MOZ_ASSERT(mPromise.IsEmpty());
return mPromise.Ensure(__func__);
}
// UseHighQualityScaling is the only flag that dependencies inherit, and we
// always want to use DrawView for dependencies.
CrossProcessPaintFlags GetFlagsForDependencies() const {
return (mFlags & CrossProcessPaintFlags::UseHighQualityScaling) |
CrossProcessPaintFlags::DrawView;
}
MozPromiseHolder<ResolvePromise> mPromise;
dom::TabId mRoot;
float mScale;
uint32_t mPendingFragments;
ReceivedFragmentMap mReceivedFragments;
CrossProcessPaintFlags mFlags;
};
} // namespace gfx
} // namespace mozilla
#endif // _include_mozilla_gfx_ipc_CrossProcessPaint_h_
|