Bug 1866777 - Disable test_race_cache_with_network.js on windows opt for frequent...
[gecko.git] / gfx / layers / CanvasDrawEventRecorder.h
blob9c311ac9543f28c68429d2c4e2fa492214e742c7
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 layers {
26 typedef mozilla::ipc::SharedMemoryBasic::Handle Handle;
27 typedef mozilla::CrossProcessSemaphoreHandle CrossProcessSemaphoreHandle;
29 class CanvasDrawEventRecorder final : public gfx::DrawEventRecorderPrivate,
30 public gfx::ContiguousBufferStream {
31 public:
32 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(CanvasDrawEventRecorder, final)
34 CanvasDrawEventRecorder();
36 enum class State : uint32_t {
37 Processing,
39 /**
40 * This is the important state to make sure the other side signals or starts
41 * us as soon as data or space is available. We set AboutToWait first and
42 * then re-check the condition. If we went straight to Waiting or Stopped
43 * then in between the last check and setting the state, the other side
44 * could have used all available data or space and never have signaled us
45 * because it didn't know we were about to wait, causing a deadlock.
46 * While we are in this state, the other side must wait until we resolve the
47 * AboutToWait state to one of the other states and then signal or start us
48 * if it needs to.
50 AboutToWait,
51 Waiting,
52 Paused,
53 Stopped,
54 Failed,
57 struct Header {
58 Atomic<int64_t> eventCount;
59 Atomic<int64_t> writerWaitCount;
60 Atomic<State> writerState;
61 uint8_t padding1[44];
62 Atomic<int64_t> processedCount;
63 Atomic<State> readerState;
66 class Helpers {
67 public:
68 virtual ~Helpers() = default;
70 virtual bool InitTranslator(
71 TextureType aTextureType, gfx::BackendType aBackendType,
72 Handle&& aReadHandle, nsTArray<Handle>&& aBufferHandles,
73 uint64_t aBufferSize, CrossProcessSemaphoreHandle&& aReaderSem,
74 CrossProcessSemaphoreHandle&& aWriterSem, bool aUseIPDLThread) = 0;
76 virtual bool AddBuffer(Handle&& aBufferHandle, uint64_t aBufferSize) = 0;
78 /**
79 * @returns true if the reader of the CanvasEventRingBuffer has permanently
80 * stopped processing, otherwise returns false.
82 virtual bool ReaderClosed() = 0;
84 /**
85 * Causes the reader to resume processing when it is in a stopped state.
87 virtual bool RestartReader() = 0;
90 bool Init(TextureType aTextureType, gfx::BackendType aBackendType,
91 UniquePtr<Helpers> aHelpers);
93 /**
94 * Record an event for processing by the CanvasParent's CanvasTranslator.
95 * @param aEvent the event to record
97 void RecordEvent(const gfx::RecordedEvent& aEvent) final;
99 void StoreSourceSurfaceRecording(gfx::SourceSurface* aSurface,
100 const char* aReason) final;
102 void Flush() final { NS_ASSERT_OWNINGTHREAD(CanvasDrawEventRecorder); }
104 int64_t CreateCheckpoint();
107 * Waits until the given checkpoint has been read by the translator.
109 * @params aCheckpoint the checkpoint to wait for
110 * @returns true if the checkpoint was reached, false if the reader is closed
111 * or we timeout.
113 bool WaitForCheckpoint(int64_t aCheckpoint);
115 TextureType GetTextureType() { return mTextureType; }
117 void DropFreeBuffers();
119 protected:
120 gfx::ContiguousBuffer& GetContiguousBuffer(size_t aSize) final;
122 void IncrementEventCount() final;
124 private:
125 void WriteInternalEvent(EventType aEventType);
127 void CheckAndSignalReader();
129 size_t mDefaultBufferSize;
130 uint32_t mMaxSpinCount;
131 uint32_t mDropBufferLimit;
132 uint32_t mDropBufferOnZero;
134 UniquePtr<Helpers> mHelpers;
136 TextureType mTextureType = TextureType::Unknown;
137 RefPtr<ipc::SharedMemoryBasic> mHeaderShmem;
138 Header* mHeader = nullptr;
140 struct CanvasBuffer : public gfx::ContiguousBuffer {
141 RefPtr<ipc::SharedMemoryBasic> shmem;
143 CanvasBuffer() : ContiguousBuffer(nullptr) {}
145 explicit CanvasBuffer(RefPtr<ipc::SharedMemoryBasic>&& aShmem)
146 : ContiguousBuffer(static_cast<char*>(aShmem->memory()),
147 aShmem->Size()),
148 shmem(std::move(aShmem)) {}
150 size_t Capacity() { return shmem ? shmem->Size() : 0; }
153 struct RecycledBuffer {
154 RefPtr<ipc::SharedMemoryBasic> shmem;
155 int64_t eventCount = 0;
156 explicit RecycledBuffer(RefPtr<ipc::SharedMemoryBasic>&& aShmem,
157 int64_t aEventCount)
158 : shmem(std::move(aShmem)), eventCount(aEventCount) {}
159 size_t Capacity() { return shmem->Size(); }
162 CanvasBuffer mCurrentBuffer;
163 std::queue<RecycledBuffer> mRecycledBuffers;
165 UniquePtr<CrossProcessSemaphore> mWriterSemaphore;
166 UniquePtr<CrossProcessSemaphore> mReaderSemaphore;
169 } // namespace layers
170 } // namespace mozilla
172 #endif // mozilla_layers_CanvasDrawEventRecorder_h