Update configs. IGNORE BROKEN CHANGESETS CLOSED TREE NO BUG a=release ba=release
[gecko.git] / gfx / layers / CanvasDrawEventRecorder.h
blobaa95eec3e6b96eccaade77a86ab952e79687aae8
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/. */
7 #ifndef mozilla_layers_CanvasDrawEventRecorder_h
8 #define mozilla_layers_CanvasDrawEventRecorder_h
10 #include <queue>
12 #include "mozilla/Atomics.h"
13 #include "mozilla/gfx/DrawEventRecorder.h"
14 #include "mozilla/ipc/CrossProcessSemaphore.h"
15 #include "mozilla/ipc/SharedMemoryBasic.h"
16 #include "mozilla/layers/LayersTypes.h"
17 #include "mozilla/RefPtr.h"
18 #include "mozilla/UniquePtr.h"
20 namespace mozilla {
22 using EventType = gfx::RecordedEvent::EventType;
24 namespace dom {
25 class ThreadSafeWorkerRef;
28 namespace layers {
30 typedef mozilla::ipc::SharedMemoryBasic::Handle Handle;
31 typedef mozilla::CrossProcessSemaphoreHandle CrossProcessSemaphoreHandle;
33 class CanvasDrawEventRecorder final : public gfx::DrawEventRecorderPrivate,
34 public gfx::ContiguousBufferStream {
35 public:
36 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(CanvasDrawEventRecorder, final)
38 explicit CanvasDrawEventRecorder(dom::ThreadSafeWorkerRef* aWorkerRef);
39 ~CanvasDrawEventRecorder() override;
41 enum class State : uint32_t {
42 Processing,
44 /**
45 * This is the important state to make sure the other side signals or starts
46 * us as soon as data or space is available. We set AboutToWait first and
47 * then re-check the condition. If we went straight to Waiting or Stopped
48 * then in between the last check and setting the state, the other side
49 * could have used all available data or space and never have signaled us
50 * because it didn't know we were about to wait, causing a deadlock.
51 * While we are in this state, the other side must wait until we resolve the
52 * AboutToWait state to one of the other states and then signal or start us
53 * if it needs to.
55 AboutToWait,
56 Waiting,
57 Paused,
58 Stopped,
59 Failed,
62 struct Header {
63 Atomic<int64_t> eventCount;
64 Atomic<int64_t> writerWaitCount;
65 Atomic<State> writerState;
66 uint8_t padding1[44];
67 Atomic<int64_t> processedCount;
68 Atomic<State> readerState;
71 class Helpers {
72 public:
73 virtual ~Helpers() = default;
75 virtual bool InitTranslator(TextureType aTextureType,
76 TextureType aWebglTextureType,
77 gfx::BackendType aBackendType,
78 Handle&& aReadHandle,
79 nsTArray<Handle>&& aBufferHandles,
80 uint64_t aBufferSize,
81 CrossProcessSemaphoreHandle&& aReaderSem,
82 CrossProcessSemaphoreHandle&& aWriterSem) = 0;
84 virtual bool AddBuffer(Handle&& aBufferHandle, uint64_t aBufferSize) = 0;
86 /**
87 * @returns true if the reader of the CanvasEventRingBuffer has permanently
88 * stopped processing, otherwise returns false.
90 virtual bool ReaderClosed() = 0;
92 /**
93 * Causes the reader to resume processing when it is in a stopped state.
95 virtual bool RestartReader() = 0;
98 bool Init(TextureType aTextureType, TextureType aWebglTextureType,
99 gfx::BackendType aBackendType, UniquePtr<Helpers> aHelpers);
102 * Record an event for processing by the CanvasParent's CanvasTranslator.
103 * @param aEvent the event to record
105 void RecordEvent(const gfx::RecordedEvent& aEvent) final;
107 void DetachResources() final;
109 void AddPendingDeletion(std::function<void()>&& aPendingDeletion) override;
111 void StoreSourceSurfaceRecording(gfx::SourceSurface* aSurface,
112 const char* aReason) final;
114 void StoreImageRecording(const RefPtr<Image>& aImageOfSurfaceDescriptor,
115 const char* aReasony) final;
117 gfx::RecorderType GetRecorderType() const override {
118 return gfx::RecorderType::CANVAS;
121 void Flush() final { NS_ASSERT_OWNINGTHREAD(CanvasDrawEventRecorder); }
123 int64_t CreateCheckpoint();
126 * Waits until the given checkpoint has been read by the translator.
128 * @params aCheckpoint the checkpoint to wait for
129 * @returns true if the checkpoint was reached, false if the reader is closed
130 * or we timeout.
132 bool WaitForCheckpoint(int64_t aCheckpoint);
134 TextureType GetTextureType() { return mTextureType; }
136 void DropFreeBuffers();
138 void ClearProcessedExternalSurfaces();
140 void ClearProcessedExternalImages();
142 protected:
143 gfx::ContiguousBuffer& GetContiguousBuffer(size_t aSize) final;
145 void IncrementEventCount() final;
147 private:
148 void WriteInternalEvent(EventType aEventType);
150 void CheckAndSignalReader();
152 void QueueProcessPendingDeletions(
153 RefPtr<CanvasDrawEventRecorder>&& aRecorder);
154 void QueueProcessPendingDeletionsLocked(
155 RefPtr<CanvasDrawEventRecorder>&& aRecorder);
157 size_t mDefaultBufferSize;
158 size_t mMaxDefaultBuffers;
159 uint32_t mMaxSpinCount;
160 uint32_t mDropBufferLimit;
161 uint32_t mDropBufferOnZero;
163 UniquePtr<Helpers> mHelpers;
165 TextureType mTextureType = TextureType::Unknown;
166 RefPtr<ipc::SharedMemoryBasic> mHeaderShmem;
167 Header* mHeader = nullptr;
169 struct CanvasBuffer : public gfx::ContiguousBuffer {
170 RefPtr<ipc::SharedMemoryBasic> shmem;
172 CanvasBuffer() : ContiguousBuffer(nullptr) {}
174 explicit CanvasBuffer(RefPtr<ipc::SharedMemoryBasic>&& aShmem)
175 : ContiguousBuffer(static_cast<char*>(aShmem->memory()),
176 aShmem->Size()),
177 shmem(std::move(aShmem)) {}
179 size_t Capacity() { return shmem ? shmem->Size() : 0; }
182 struct RecycledBuffer {
183 RefPtr<ipc::SharedMemoryBasic> shmem;
184 int64_t eventCount = 0;
185 explicit RecycledBuffer(RefPtr<ipc::SharedMemoryBasic>&& aShmem,
186 int64_t aEventCount)
187 : shmem(std::move(aShmem)), eventCount(aEventCount) {}
188 size_t Capacity() { return shmem->Size(); }
191 CanvasBuffer mCurrentBuffer;
192 std::queue<RecycledBuffer> mRecycledBuffers;
194 UniquePtr<CrossProcessSemaphore> mWriterSemaphore;
195 UniquePtr<CrossProcessSemaphore> mReaderSemaphore;
197 RefPtr<dom::ThreadSafeWorkerRef> mWorkerRef;
198 bool mIsOnWorker = false;
201 } // namespace layers
202 } // namespace mozilla
204 #endif // mozilla_layers_CanvasDrawEventRecorder_h