summaryrefslogtreecommitdiffstats
path: root/gfx/layers/ipc/SharedSurfacesChild.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/ipc/SharedSurfacesChild.h')
-rw-r--r--gfx/layers/ipc/SharedSurfacesChild.h250
1 files changed, 250 insertions, 0 deletions
diff --git a/gfx/layers/ipc/SharedSurfacesChild.h b/gfx/layers/ipc/SharedSurfacesChild.h
new file mode 100644
index 0000000000..6fb40931fb
--- /dev/null
+++ b/gfx/layers/ipc/SharedSurfacesChild.h
@@ -0,0 +1,250 @@
+/* -*- 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 MOZILLA_GFX_SHAREDSURFACESCHILD_H
+#define MOZILLA_GFX_SHAREDSURFACESCHILD_H
+
+#include <stdint.h> // for uint32_t, uint64_t
+#include "mozilla/Attributes.h" // for override
+#include "mozilla/Maybe.h" // for Maybe
+#include "mozilla/RefPtr.h" // for already_AddRefed
+#include "mozilla/StaticPtr.h" // for StaticRefPtr
+#include "mozilla/gfx/UserData.h" // for UserDataKey
+#include "mozilla/webrender/WebRenderTypes.h" // for wr::ImageKey
+#include "nsTArray.h" // for AutoTArray
+#include "nsThreadUtils.h" // for Runnable
+#include "ImageTypes.h" // for ContainerProducerID
+
+namespace mozilla {
+namespace layers {
+class AnimationImageKeyData;
+} // namespace layers
+} // namespace mozilla
+
+template <>
+struct nsTArray_RelocationStrategy<mozilla::layers::AnimationImageKeyData> {
+ typedef nsTArray_RelocateUsingMoveConstructor<
+ mozilla::layers::AnimationImageKeyData>
+ Type;
+};
+
+namespace mozilla {
+namespace gfx {
+class SourceSurface;
+class SourceSurfaceSharedData;
+} // namespace gfx
+
+namespace wr {
+class IpcResourceUpdateQueue;
+} // namespace wr
+
+namespace layers {
+
+class CompositorManagerChild;
+class RenderRootStateManager;
+
+class SharedSurfacesChild {
+ public:
+ /**
+ * Request that the surface be mapped into the compositor thread's memory
+ * space. This is useful for when the caller itself has no present need for
+ * the surface to be mapped, but knows there will be such a need in the
+ * future. This may be called from any thread, but it may cause a dispatch to
+ * the main thread.
+ */
+ static void Share(gfx::SourceSurfaceSharedData* aSurface);
+
+ /**
+ * Request that the surface be mapped into the compositor thread's memory
+ * space, and a valid ExternalImageId be generated for it for use with
+ * WebRender. This must be called from the main thread.
+ */
+ static nsresult Share(gfx::SourceSurface* aSurface, wr::ExternalImageId& aId);
+
+ /**
+ * Request that the surface be mapped into the compositor thread's memory
+ * space, and a valid ImageKey be generated for it for use with WebRender.
+ * This must be called from the main thread.
+ */
+ static nsresult Share(gfx::SourceSurfaceSharedData* aSurface,
+ RenderRootStateManager* aManager,
+ wr::IpcResourceUpdateQueue& aResources,
+ wr::ImageKey& aKey);
+
+ /**
+ * Request that the surface be mapped into the compositor thread's memory
+ * space, and a valid ImageKey be generated for it for use with WebRender.
+ * This must be called from the main thread.
+ */
+ static nsresult Share(gfx::SourceSurface* aSurface,
+ RenderRootStateManager* aManager,
+ wr::IpcResourceUpdateQueue& aResources,
+ wr::ImageKey& aKey);
+
+ /**
+ * Get the external ID, if any, bound to the shared surface. Used for memory
+ * reporting purposes.
+ */
+ static Maybe<wr::ExternalImageId> GetExternalId(
+ const gfx::SourceSurfaceSharedData* aSurface);
+
+ /**
+ * Get the surface (or its underlying surface) as a SourceSurfaceSharedData
+ * pointer, if valid.
+ */
+ static gfx::SourceSurfaceSharedData* AsSourceSurfaceSharedData(
+ gfx::SourceSurface* aSurface);
+
+ class ImageKeyData {
+ public:
+ ImageKeyData(RenderRootStateManager* aManager,
+ const wr::ImageKey& aImageKey);
+ virtual ~ImageKeyData();
+
+ ImageKeyData(ImageKeyData&& aOther);
+ ImageKeyData& operator=(ImageKeyData&& aOther);
+ ImageKeyData(const ImageKeyData&) = delete;
+ ImageKeyData& operator=(const ImageKeyData&) = delete;
+
+ void MergeDirtyRect(const Maybe<gfx::IntRect>& aDirtyRect);
+
+ Maybe<gfx::IntRect> TakeDirtyRect() { return std::move(mDirtyRect); }
+
+ RefPtr<RenderRootStateManager> mManager;
+ Maybe<gfx::IntRect> mDirtyRect;
+ wr::ImageKey mImageKey;
+ };
+
+ private:
+ SharedSurfacesChild() = delete;
+ ~SharedSurfacesChild() = delete;
+
+ friend class SharedSurfacesAnimation;
+
+ class SharedUserData final : public Runnable {
+ public:
+ explicit SharedUserData(const wr::ExternalImageId& aId);
+ virtual ~SharedUserData();
+
+ SharedUserData(const SharedUserData& aOther) = delete;
+ SharedUserData& operator=(const SharedUserData& aOther) = delete;
+
+ SharedUserData(SharedUserData&& aOther) = delete;
+ SharedUserData& operator=(SharedUserData&& aOther) = delete;
+
+ static void Destroy(void* aClosure);
+
+ NS_IMETHOD Run() override;
+
+ const wr::ExternalImageId& Id() const { return mId; }
+
+ void SetId(const wr::ExternalImageId& aId) {
+ mId = aId;
+ mKeys.Clear();
+ mShared = false;
+ }
+
+ bool IsShared() const { return mShared; }
+
+ void MarkShared() {
+ MOZ_ASSERT(!mShared);
+ mShared = true;
+ }
+
+ wr::ImageKey UpdateKey(RenderRootStateManager* aManager,
+ wr::IpcResourceUpdateQueue& aResources,
+ const Maybe<gfx::IntRect>& aDirtyRect);
+
+ protected:
+ AutoTArray<ImageKeyData, 1> mKeys;
+ wr::ExternalImageId mId;
+ bool mShared : 1;
+ };
+
+ static nsresult ShareInternal(gfx::SourceSurfaceSharedData* aSurface,
+ SharedUserData** aUserData);
+
+ static void Unshare(const wr::ExternalImageId& aId, bool aReleaseId,
+ nsTArray<ImageKeyData>& aKeys);
+
+ static void DestroySharedUserData(void* aClosure);
+
+ static gfx::UserDataKey sSharedKey;
+};
+
+class AnimationImageKeyData final : public SharedSurfacesChild::ImageKeyData {
+ public:
+ AnimationImageKeyData(RenderRootStateManager* aManager,
+ const wr::ImageKey& aImageKey);
+
+ virtual ~AnimationImageKeyData();
+
+ AnimationImageKeyData(AnimationImageKeyData&& aOther);
+ AnimationImageKeyData& operator=(AnimationImageKeyData&& aOther);
+
+ AutoTArray<RefPtr<gfx::SourceSurfaceSharedData>, 2> mPendingRelease;
+};
+
+/**
+ * This helper class owns a single ImageKey which will map to different external
+ * image IDs representing different frames in an animation.
+ */
+class SharedSurfacesAnimation final {
+ public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedSurfacesAnimation)
+
+ SharedSurfacesAnimation() = default;
+
+ void Destroy();
+
+ /**
+ * Set the animation to display the given frame.
+ * @param aSurface The current frame.
+ * @param aDirtyRect Dirty rect representing the change between the new frame
+ * and the previous frame. We will request only the delta
+ * be reuploaded by WebRender.
+ */
+ nsresult SetCurrentFrame(gfx::SourceSurfaceSharedData* aSurface,
+ const gfx::IntRect& aDirtyRect);
+
+ /**
+ * Generate an ImageKey for the given frame.
+ * @param aSurface The current frame. This should match what was cached via
+ * SetCurrentFrame, but if it does not, it will need to
+ * regenerate the cached ImageKey.
+ */
+ nsresult UpdateKey(gfx::SourceSurfaceSharedData* aSurface,
+ RenderRootStateManager* aManager,
+ wr::IpcResourceUpdateQueue& aResources,
+ wr::ImageKey& aKey);
+
+ /**
+ * Release our reference to all frames up to and including the frame which
+ * has an external image ID which matches aId.
+ */
+ void ReleasePreviousFrame(RenderRootStateManager* aManager,
+ const wr::ExternalImageId& aId);
+
+ /**
+ * Destroy any state information bound for the given layer manager. Any
+ * image keys are already invalid.
+ */
+ void Invalidate(RenderRootStateManager* aManager);
+
+ private:
+ ~SharedSurfacesAnimation();
+
+ void HoldSurfaceForRecycling(AnimationImageKeyData& aEntry,
+ gfx::SourceSurfaceSharedData* aSurface);
+
+ AutoTArray<AnimationImageKeyData, 1> mKeys;
+ wr::ExternalImageId mId;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif