SharedSurfacesChild.h (8646B)
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 7 #ifndef MOZILLA_GFX_SHAREDSURFACESCHILD_H 8 #define MOZILLA_GFX_SHAREDSURFACESCHILD_H 9 10 #include <stdint.h> // for uint32_t, uint64_t 11 #include "mozilla/Maybe.h" // for Maybe 12 #include "mozilla/RefPtr.h" // for already_AddRefed 13 #include "mozilla/StaticPtr.h" // for StaticRefPtr 14 #include "mozilla/gfx/UserData.h" // for UserDataKey 15 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor 16 #include "mozilla/webrender/WebRenderTypes.h" // for wr::ImageKey 17 #include "nsTArray.h" // for AutoTArray 18 #include "nsThreadUtils.h" // for Runnable 19 #include "ImageTypes.h" // for ContainerProducerID 20 21 namespace mozilla { 22 namespace layers { 23 class AnimationImageKeyData; 24 } // namespace layers 25 } // namespace mozilla 26 27 template <> 28 struct nsTArray_RelocationStrategy<mozilla::layers::AnimationImageKeyData> { 29 typedef nsTArray_RelocateUsingMoveConstructor< 30 mozilla::layers::AnimationImageKeyData> 31 Type; 32 }; 33 34 namespace mozilla { 35 namespace gfx { 36 class SourceSurface; 37 class SourceSurfaceSharedData; 38 } // namespace gfx 39 40 namespace wr { 41 class IpcResourceUpdateQueue; 42 } // namespace wr 43 44 namespace layers { 45 46 class CompositorManagerChild; 47 class RenderRootStateManager; 48 49 class SharedSurfacesChild { 50 public: 51 /** 52 * Request that the surface be mapped into the compositor thread's memory 53 * space. This is useful for when the caller itself has no present need for 54 * the surface to be mapped, but knows there will be such a need in the 55 * future. This may be called from any thread, but it may cause a dispatch to 56 * the main thread. 57 */ 58 static void Share(gfx::SourceSurfaceSharedData* aSurface); 59 60 /** 61 * Request that the surface be mapped into the compositor thread's memory 62 * space, and a valid ExternalImageId be generated for it for use with 63 * WebRender. This must be called from the main thread. 64 */ 65 static nsresult Share(gfx::SourceSurface* aSurface, wr::ExternalImageId& aId); 66 67 /** 68 * Request that the surface be mapped into the compositor thread's memory 69 * space, and a valid ExternalImageId be generated for it for use with 70 * WebRender. This must be called from the main thread. 71 */ 72 static nsresult Share(gfx::SourceSurface* aSurface, 73 Maybe<SurfaceDescriptor>& aDesc); 74 75 /** 76 * Request that the surface be mapped into the compositor thread's memory 77 * space, and a valid ImageKey be generated for it for use with WebRender. 78 * This must be called from the main thread. 79 */ 80 static nsresult Share(gfx::SourceSurfaceSharedData* aSurface, 81 RenderRootStateManager* aManager, 82 wr::IpcResourceUpdateQueue& aResources, 83 wr::ImageKey& aKey); 84 85 /** 86 * Request that the surface be mapped into the compositor thread's memory 87 * space, and a valid ImageKey be generated for it for use with WebRender. 88 * This must be called from the main thread. 89 */ 90 static nsresult Share(gfx::SourceSurface* aSurface, 91 RenderRootStateManager* aManager, 92 wr::IpcResourceUpdateQueue& aResources, 93 wr::ImageKey& aKey); 94 95 /** 96 * Get the external ID, if any, bound to the shared surface. Used for memory 97 * reporting purposes. 98 */ 99 static Maybe<wr::ExternalImageId> GetExternalId( 100 const gfx::SourceSurfaceSharedData* aSurface); 101 102 /** 103 * Get the surface (or its underlying surface) as a SourceSurfaceSharedData 104 * pointer, if valid. 105 */ 106 static gfx::SourceSurfaceSharedData* AsSourceSurfaceSharedData( 107 gfx::SourceSurface* aSurface); 108 109 class ImageKeyData { 110 public: 111 ImageKeyData(RenderRootStateManager* aManager, 112 const wr::ImageKey& aImageKey); 113 virtual ~ImageKeyData(); 114 115 ImageKeyData(ImageKeyData&& aOther); 116 ImageKeyData& operator=(ImageKeyData&& aOther); 117 ImageKeyData(const ImageKeyData&) = delete; 118 ImageKeyData& operator=(const ImageKeyData&) = delete; 119 120 void MergeDirtyRect(const Maybe<gfx::IntRect>& aDirtyRect); 121 122 Maybe<gfx::IntRect> TakeDirtyRect() { return std::move(mDirtyRect); } 123 124 RefPtr<RenderRootStateManager> mManager; 125 Maybe<gfx::IntRect> mDirtyRect; 126 wr::ImageKey mImageKey; 127 }; 128 129 private: 130 SharedSurfacesChild() = delete; 131 ~SharedSurfacesChild() = delete; 132 133 friend class SharedSurfacesAnimation; 134 135 class SharedUserData final : public Runnable { 136 public: 137 SharedUserData(); 138 virtual ~SharedUserData(); 139 140 SharedUserData(const SharedUserData& aOther) = delete; 141 SharedUserData& operator=(const SharedUserData& aOther) = delete; 142 143 SharedUserData(SharedUserData&& aOther) = delete; 144 SharedUserData& operator=(SharedUserData&& aOther) = delete; 145 146 static void Destroy(void* aClosure); 147 148 NS_IMETHOD Run() override; 149 150 const wr::ExternalImageId& Id() const { return mId; } 151 152 void ClearShared() { 153 mKeys.Clear(); 154 mShared = false; 155 } 156 157 bool IsShared() const { return mShared; } 158 159 void MarkShared(const wr::ExternalImageId& aId) { 160 MOZ_ASSERT(!mShared); 161 mId = aId; 162 mShared = true; 163 } 164 165 wr::ImageKey UpdateKey(RenderRootStateManager* aManager, 166 wr::IpcResourceUpdateQueue& aResources, 167 const Maybe<gfx::IntRect>& aDirtyRect); 168 169 protected: 170 AutoTArray<ImageKeyData, 1> mKeys; 171 wr::ExternalImageId mId; 172 bool mShared : 1; 173 }; 174 175 static nsresult ShareInternal(gfx::SourceSurfaceSharedData* aSurface, 176 SharedUserData** aUserData); 177 178 static void Unshare(const wr::ExternalImageId& aId, bool aReleaseId, 179 nsTArray<ImageKeyData>& aKeys); 180 181 static void DestroySharedUserData(void* aClosure); 182 183 static gfx::UserDataKey sSharedKey; 184 }; 185 186 class AnimationImageKeyData final : public SharedSurfacesChild::ImageKeyData { 187 public: 188 AnimationImageKeyData(RenderRootStateManager* aManager, 189 const wr::ImageKey& aImageKey); 190 191 virtual ~AnimationImageKeyData(); 192 193 AnimationImageKeyData(AnimationImageKeyData&& aOther); 194 AnimationImageKeyData& operator=(AnimationImageKeyData&& aOther); 195 196 AutoTArray<RefPtr<gfx::SourceSurfaceSharedData>, 2> mPendingRelease; 197 }; 198 199 /** 200 * This helper class owns a single ImageKey which will map to different external 201 * image IDs representing different frames in an animation. 202 */ 203 class SharedSurfacesAnimation final { 204 public: 205 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedSurfacesAnimation) 206 207 SharedSurfacesAnimation() = default; 208 209 void Destroy(); 210 211 /** 212 * Set the animation to display the given frame. 213 * @param aSurface The current frame. 214 * @param aDirtyRect Dirty rect representing the change between the new frame 215 * and the previous frame. We will request only the delta 216 * be reuploaded by WebRender. 217 */ 218 nsresult SetCurrentFrame(gfx::SourceSurfaceSharedData* aSurface, 219 const gfx::IntRect& aDirtyRect); 220 221 /** 222 * Generate an ImageKey for the given frame. 223 * @param aSurface The current frame. This should match what was cached via 224 * SetCurrentFrame, but if it does not, it will need to 225 * regenerate the cached ImageKey. 226 */ 227 nsresult UpdateKey(gfx::SourceSurfaceSharedData* aSurface, 228 RenderRootStateManager* aManager, 229 wr::IpcResourceUpdateQueue& aResources, 230 wr::ImageKey& aKey); 231 232 /** 233 * Release our reference to all frames up to and including the frame which 234 * has an external image ID which matches aId. 235 */ 236 void ReleasePreviousFrame(RenderRootStateManager* aManager, 237 const wr::ExternalImageId& aId); 238 239 /** 240 * Destroy any state information bound for the given layer manager. Any 241 * image keys are already invalid. 242 */ 243 void Invalidate(RenderRootStateManager* aManager); 244 245 private: 246 ~SharedSurfacesAnimation(); 247 248 void HoldSurfaceForRecycling(AnimationImageKeyData& aEntry, 249 gfx::SourceSurfaceSharedData* aSurface); 250 251 AutoTArray<AnimationImageKeyData, 1> mKeys; 252 wr::ExternalImageId mId; 253 }; 254 255 } // namespace layers 256 } // namespace mozilla 257 258 #endif