summaryrefslogtreecommitdiffstats
path: root/gfx/ipc/CrossProcessPaint.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/ipc/CrossProcessPaint.h')
-rw-r--r--gfx/ipc/CrossProcessPaint.h176
1 files changed, 176 insertions, 0 deletions
diff --git a/gfx/ipc/CrossProcessPaint.h b/gfx/ipc/CrossProcessPaint.h
new file mode 100644
index 0000000000..8179b49b41
--- /dev/null
+++ b/gfx/ipc/CrossProcessPaint.h
@@ -0,0 +1,176 @@
+/* -*- 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/RecordedEvent.h"
+#include "mozilla/gfx/Rect.h"
+#include "mozilla/MozPromise.h"
+#include "mozilla/ipc/ByteBuf.h"
+#include "nsColor.h"
+#include "nsDataHashtable.h"
+#include "nsHashKeys.h"
+#include "nsRefPtrHashtable.h"
+#include "nsTHashtable.h"
+
+class nsIDocShell;
+
+namespace IPC {
+template <typename T>
+struct ParamTraits;
+} // namespace IPC
+
+namespace mozilla {
+
+namespace dom {
+class DOMRect;
+class Promise;
+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 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 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:
+ 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(
+ nsTHashtable<nsUint64HashKey>&& aDependencies);
+
+ void ReceiveFragment(dom::WindowGlobalParent* aWGP,
+ PaintFragment&& aFragment);
+ void LostFragment(dom::WindowGlobalParent* aWGP);
+
+ private:
+ typedef nsDataHashtable<nsUint64HashKey, PaintFragment> ReceivedFragmentMap;
+
+ CrossProcessPaint(float aScale, dom::TabId aRoot);
+ ~CrossProcessPaint();
+
+ void QueueDependencies(const nsTHashtable<nsUint64HashKey>& aDependencies);
+
+ 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(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__);
+ }
+
+ MozPromiseHolder<ResolvePromise> mPromise;
+ dom::TabId mRoot;
+ float mScale;
+ uint32_t mPendingFragments;
+ ReceivedFragmentMap mReceivedFragments;
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif // _include_mozilla_gfx_ipc_CrossProcessPaint_h_