CanvasChild.h (7056B)
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 https://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_layers_CanvasChild_h 8 #define mozilla_layers_CanvasChild_h 9 10 #include "mozilla/gfx/RecordedEvent.h" 11 #include "mozilla/ipc/CrossProcessSemaphore.h" 12 #include "mozilla/ipc/SharedMemoryMapping.h" 13 #include "mozilla/layers/PCanvasChild.h" 14 #include "mozilla/layers/SourceSurfaceSharedData.h" 15 #include "mozilla/WeakPtr.h" 16 17 class nsICanvasRenderingContextInternal; 18 19 namespace mozilla { 20 21 namespace dom { 22 class ThreadSafeWorkerRef; 23 } 24 25 namespace gfx { 26 class DrawTargetRecording; 27 class SourceSurface; 28 } // namespace gfx 29 30 namespace layers { 31 class CanvasDrawEventRecorder; 32 struct RemoteTextureOwnerId; 33 34 class CanvasChild final : public PCanvasChild, public SupportsWeakPtr { 35 public: 36 NS_INLINE_DECL_REFCOUNTING(CanvasChild) 37 38 explicit CanvasChild(dom::ThreadSafeWorkerRef* aWorkerRef); 39 40 /** 41 * @returns true if remote canvas has been deactivated due to failure. 42 */ 43 static bool Deactivated() { return mDeactivated; } 44 45 /** 46 * Release resources until they are next required. 47 */ 48 void ClearCachedResources(); 49 50 ipc::IPCResult RecvNotifyDeviceReset( 51 const nsTArray<RemoteTextureOwnerId>& aOwnerIds); 52 53 ipc::IPCResult RecvDeactivate(); 54 55 ipc::IPCResult RecvBlockCanvas(); 56 57 ipc::IPCResult RecvNotifyRequiresRefresh( 58 const RemoteTextureOwnerId aTextureOwnerId); 59 60 ipc::IPCResult RecvSnapshotShmem( 61 const RemoteTextureOwnerId aTextureOwnerId, 62 ipc::ReadOnlySharedMemoryHandle&& aShmemHandle, 63 SnapshotShmemResolver&& aResolve); 64 65 ipc::IPCResult RecvNotifyTextureDestruction( 66 const RemoteTextureOwnerId aTextureOwnerId); 67 68 /** 69 * Ensures that the DrawEventRecorder has been created. 70 * 71 * @params aTextureType the TextureType to create in the CanvasTranslator. 72 * @returns true if the recorder was successfully created 73 */ 74 bool EnsureRecorder(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, 75 TextureType aTextureType, TextureType aWebglTextureType); 76 77 /** 78 * Clean up IPDL actor. 79 */ 80 void Destroy(); 81 82 /** 83 * @returns true if we should be caching data surfaces in the GPU process. 84 */ 85 bool ShouldCacheDataSurface() const { 86 return mTransactionsSinceGetDataSurface < kCacheDataSurfaceThreshold; 87 } 88 89 /** 90 * Ensures that we have sent a begin transaction event, since the last 91 * end transaction. 92 * @returns false on failure to begin transaction 93 */ 94 bool EnsureBeginTransaction(); 95 96 /** 97 * Send an end transaction event to indicate the end of events for this frame. 98 */ 99 void EndTransaction(); 100 101 /** 102 * @returns true if the canvas IPC classes have not been used for some time 103 * and can be cleaned up. 104 */ 105 bool ShouldBeCleanedUp() const; 106 107 /** 108 * Create a DrawTargetRecording for a canvas texture. 109 * @param aTextureOwnerId the id of the new texture 110 * @param aSize size for the DrawTarget 111 * @param aFormat SurfaceFormat for the DrawTarget 112 * @returns newly created DrawTargetRecording 113 */ 114 already_AddRefed<gfx::DrawTargetRecording> CreateDrawTarget( 115 const RemoteTextureOwnerId& aTextureOwnerId, gfx::IntSize aSize, 116 gfx::SurfaceFormat aFormat); 117 118 /** 119 * Record an event for processing by the CanvasParent's CanvasTranslator. 120 * @param aEvent the event to record 121 */ 122 void RecordEvent(const gfx::RecordedEvent& aEvent); 123 124 int64_t CreateCheckpoint(); 125 126 /** 127 * Wrap the given surface, so that we can provide a DataSourceSurface if 128 * required. 129 * @param aSurface the SourceSurface to wrap 130 * @param aTextureOwnerId the texture id of the source TextureData 131 * @returns a SourceSurface that can provide a DataSourceSurface if required 132 */ 133 already_AddRefed<gfx::SourceSurface> WrapSurface( 134 const RefPtr<gfx::SourceSurface>& aSurface, 135 const RemoteTextureOwnerId aTextureOwnerId); 136 137 /** 138 * The DrawTargetRecording backing the surface has not been modified since the 139 * previous use, so it is safe to reattach the snapshot for readback. 140 */ 141 void AttachSurface(const RefPtr<gfx::SourceSurface>& aSurface); 142 143 /** 144 * The DrawTargetRecording is about to change, so detach the old snapshot. 145 */ 146 void DetachSurface(const RefPtr<gfx::SourceSurface>& aSurface, 147 bool aInvalidate = false); 148 149 /** 150 * Get DataSourceSurface from the translated equivalent version of aSurface in 151 * the GPU process. 152 * @param aTextureOwnerId the source TextureData to read from 153 * @param aSurface the SourceSurface in this process for which we need a 154 * DataSourceSurface 155 * @param aDetached whether the surface is old 156 * @param aMayInvalidate whether the data may be invalidated by future changes 157 * @returns a DataSourceSurface created from data for aSurface retrieve from 158 * GPU process 159 */ 160 already_AddRefed<gfx::DataSourceSurface> GetDataSurface( 161 const RemoteTextureOwnerId aTextureOwnerId, 162 const gfx::SourceSurface* aSurface, bool aDetached, bool& aMayInvalidate); 163 164 bool RequiresRefresh(const RemoteTextureOwnerId aTextureOwnerId) const; 165 166 void ReturnDataSurfaceShmem( 167 std::shared_ptr<ipc::ReadOnlySharedMemoryMapping>&& aDataSurfaceShmem); 168 169 already_AddRefed<gfx::SourceSurface> SnapshotExternalCanvas( 170 gfx::DrawTargetRecording* aTarget, 171 nsICanvasRenderingContextInternal* aCanvas, 172 mozilla::ipc::IProtocol* aActor); 173 174 protected: 175 void ActorDestroy(ActorDestroyReason aWhy) final; 176 177 private: 178 DISALLOW_COPY_AND_ASSIGN(CanvasChild); 179 180 ~CanvasChild() final; 181 182 size_t SizeOfDataSurfaceShmem(gfx::IntSize, gfx::SurfaceFormat aFormat); 183 bool ShouldGrowDataSurfaceShmem(size_t aSizeRequired); 184 bool EnsureDataSurfaceShmem(size_t aSizeRequired); 185 bool EnsureDataSurfaceShmem(gfx::IntSize aSize, gfx::SurfaceFormat aFormat); 186 187 static void ReleaseDataShmemHolder(void* aClosure); 188 189 void DropFreeBuffersWhenDormant(); 190 191 static const uint32_t kCacheDataSurfaceThreshold = 10; 192 193 static bool mDeactivated; 194 195 RefPtr<dom::ThreadSafeWorkerRef> mWorkerRef; 196 RefPtr<CanvasDrawEventRecorder> mRecorder; 197 198 std::shared_ptr<ipc::ReadOnlySharedMemoryMapping> mDataSurfaceShmem; 199 bool mDataSurfaceShmemAvailable = false; 200 uint32_t mNextDataSurfaceShmemId = 0; 201 int64_t mLastWriteLockCheckpoint = 0; 202 uint32_t mTransactionsSinceGetDataSurface = kCacheDataSurfaceThreshold; 203 struct TextureInfo { 204 std::shared_ptr<mozilla::ipc::ReadOnlySharedMemoryMapping> mSnapshotShmem; 205 bool mRequiresRefresh = false; 206 }; 207 std::unordered_map<RemoteTextureOwnerId, TextureInfo, 208 RemoteTextureOwnerId::HashFn> 209 mTextureInfo; 210 bool mIsInTransaction = false; 211 bool mDormant = false; 212 bool mBlocked = false; 213 uint64_t mLastSyncId = 0; 214 }; 215 216 } // namespace layers 217 } // namespace mozilla 218 219 #endif // mozilla_layers_CanvasChild_h