Bug 1883287 - Don't wait for the hidden window to be created on Linux to load the...
[gecko.git] / gfx / layers / CanvasDrawEventRecorder.h
blobc9eacf27acfdddb17bb1b6ea3ff464db4f809af4
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 gfx::RecorderType GetRecorderType() const override {
115 return gfx::RecorderType::CANVAS;
118 void Flush() final { NS_ASSERT_OWNINGTHREAD(CanvasDrawEventRecorder); }
120 int64_t CreateCheckpoint();
123 * Waits until the given checkpoint has been read by the translator.
125 * @params aCheckpoint the checkpoint to wait for
126 * @returns true if the checkpoint was reached, false if the reader is closed
127 * or we timeout.
129 bool WaitForCheckpoint(int64_t aCheckpoint);
131 TextureType GetTextureType() { return mTextureType; }
133 void DropFreeBuffers();
135 void ClearProcessedExternalSurfaces();
137 protected:
138 gfx::ContiguousBuffer& GetContiguousBuffer(size_t aSize) final;
140 void IncrementEventCount() final;
142 private:
143 void WriteInternalEvent(EventType aEventType);
145 void CheckAndSignalReader();
147 void QueueProcessPendingDeletions(
148 RefPtr<CanvasDrawEventRecorder>&& aRecorder);
149 void QueueProcessPendingDeletionsLocked(
150 RefPtr<CanvasDrawEventRecorder>&& aRecorder);
152 size_t mDefaultBufferSize;
153 size_t mMaxDefaultBuffers;
154 uint32_t mMaxSpinCount;
155 uint32_t mDropBufferLimit;
156 uint32_t mDropBufferOnZero;
158 UniquePtr<Helpers> mHelpers;
160 TextureType mTextureType = TextureType::Unknown;
161 RefPtr<ipc::SharedMemoryBasic> mHeaderShmem;
162 Header* mHeader = nullptr;
164 struct CanvasBuffer : public gfx::ContiguousBuffer {
165 RefPtr<ipc::SharedMemoryBasic> shmem;
167 CanvasBuffer() : ContiguousBuffer(nullptr) {}
169 explicit CanvasBuffer(RefPtr<ipc::SharedMemoryBasic>&& aShmem)
170 : ContiguousBuffer(static_cast<char*>(aShmem->memory()),
171 aShmem->Size()),
172 shmem(std::move(aShmem)) {}
174 size_t Capacity() { return shmem ? shmem->Size() : 0; }
177 struct RecycledBuffer {
178 RefPtr<ipc::SharedMemoryBasic> shmem;
179 int64_t eventCount = 0;
180 explicit RecycledBuffer(RefPtr<ipc::SharedMemoryBasic>&& aShmem,
181 int64_t aEventCount)
182 : shmem(std::move(aShmem)), eventCount(aEventCount) {}
183 size_t Capacity() { return shmem->Size(); }
186 CanvasBuffer mCurrentBuffer;
187 std::queue<RecycledBuffer> mRecycledBuffers;
189 UniquePtr<CrossProcessSemaphore> mWriterSemaphore;
190 UniquePtr<CrossProcessSemaphore> mReaderSemaphore;
192 RefPtr<dom::ThreadSafeWorkerRef> mWorkerRef;
193 bool mIsOnWorker = false;
196 } // namespace layers
197 } // namespace mozilla
199 #endif // mozilla_layers_CanvasDrawEventRecorder_h