Bug 1857841 - pt 3. Add a new page kind named "fresh" r=glandium
[gecko.git] / gfx / webrender_bindings / RenderThread.h
blobf9ab1e742e139122b9a38ec223e6ad27d4f89cbd
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_RENDERTHREAD_H
8 #define MOZILLA_LAYERS_RENDERTHREAD_H
10 #include "base/basictypes.h" // for DISALLOW_EVIL_CONSTRUCTORS
11 #include "base/platform_thread.h" // for PlatformThreadId
12 #include "base/thread.h" // for Thread
13 #include "base/message_loop.h"
14 #include "GLTypes.h" // for GLenum
15 #include "nsISupportsImpl.h"
16 #include "mozilla/gfx/Point.h"
17 #include "mozilla/Hal.h"
18 #include "mozilla/MozPromise.h"
19 #include "mozilla/DataMutex.h"
20 #include "mozilla/Maybe.h"
21 #include "mozilla/webrender/webrender_ffi.h"
22 #include "mozilla/UniquePtr.h"
23 #include "mozilla/webrender/WebRenderTypes.h"
24 #include "mozilla/layers/CompositionRecorder.h"
25 #include "mozilla/layers/SynchronousTask.h"
26 #include "mozilla/UniquePtr.h"
27 #include "mozilla/VsyncDispatcher.h"
29 #include <list>
30 #include <queue>
31 #include <unordered_map>
33 namespace mozilla {
34 namespace gl {
35 class GLContext;
36 } // namespace gl
37 namespace layers {
38 class CompositorBridgeParent;
39 class ShaderProgramOGLsHolder;
40 class SurfacePool;
41 } // namespace layers
42 namespace wr {
44 typedef MozPromise<MemoryReport, bool, true> MemoryReportPromise;
46 class RendererOGL;
47 class RenderTextureHost;
48 class RenderThread;
50 /// A rayon thread pool that is shared by all WebRender instances within a
51 /// process.
52 class WebRenderThreadPool {
53 public:
54 explicit WebRenderThreadPool(bool low_priority);
56 ~WebRenderThreadPool();
58 wr::WrThreadPool* Raw() {
59 // If this pointer is null we are likely at some late shutdown stage,
60 // when threads are no longer safe to interact with.
61 MOZ_RELEASE_ASSERT(mThreadPool);
62 return mThreadPool;
65 /// Prematurely destroys this handle to the thread pool.
66 /// After calling this the object is useless.
67 void Release();
69 protected:
70 wr::WrThreadPool* mThreadPool;
73 class WebRenderProgramCache final {
74 public:
75 explicit WebRenderProgramCache(wr::WrThreadPool* aThreadPool);
77 ~WebRenderProgramCache();
79 wr::WrProgramCache* Raw() { return mProgramCache; }
81 protected:
82 wr::WrProgramCache* mProgramCache;
85 class WebRenderShaders final {
86 public:
87 WebRenderShaders(gl::GLContext* gl, WebRenderProgramCache* programCache);
88 ~WebRenderShaders();
90 wr::WrShaders* RawShaders() { return mShaders; }
92 protected:
93 RefPtr<gl::GLContext> mGL;
94 wr::WrShaders* mShaders;
97 class WebRenderPipelineInfo final {
98 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderPipelineInfo);
100 const wr::WrPipelineInfo& Raw() const { return mPipelineInfo; }
101 wr::WrPipelineInfo& Raw() { return mPipelineInfo; }
103 protected:
104 ~WebRenderPipelineInfo() = default;
105 wr::WrPipelineInfo mPipelineInfo;
108 /// Base class for an event that can be scheduled to run on the render thread.
110 /// The event can be passed through the same channels as regular WebRender
111 /// messages to preserve ordering.
112 class RendererEvent {
113 public:
114 virtual ~RendererEvent() = default;
115 virtual void Run(RenderThread& aRenderThread, wr::WindowId aWindow) = 0;
118 /// The render thread is where WebRender issues all of its GPU work, and as much
119 /// as possible this thread should only serve this purpose.
121 /// The render thread owns the different RendererOGLs (one per window) and
122 /// implements the RenderNotifier api exposed by the WebRender bindings.
124 /// Callers are not allowed to post tasks to the render thread's event loop
125 /// directly and must instead use the RendererEvent mechanism which avoids races
126 /// between the events and WebRender's own messages.
128 /// The GL context(s) should be created and used on this thread only.
129 /// XXX - I've tried to organize code so that we can potentially avoid making
130 /// this a singleton since this bad habit has a tendency to bite us later, but
131 /// I haven't gotten all the way there either, in order to focus on the more
132 /// important pieces first. So we are a bit in-between (this is totally a
133 /// singleton but in some places we pretend it's not). Hopefully we can evolve
134 /// this in a way that keeps the door open to removing the singleton bits.
135 class RenderThread final {
136 NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DELETE_ON_MAIN_THREAD(RenderThread)
138 public:
139 /// Can be called from any thread.
140 static RenderThread* Get();
142 /// Can only be called from the main thread.
143 static void Start(uint32_t aNamespace);
145 /// Can only be called from the main thread.
146 static void ShutDown();
148 /// Can be called from any thread.
149 static bool IsInRenderThread();
151 /// Can be called from any thread.
152 static already_AddRefed<nsIThread> GetRenderThread();
154 // Can be called from any thread. Dispatches an event to the Renderer thread
155 // to iterate over all Renderers, accumulates memory statistics, and resolves
156 // the return promise.
157 static RefPtr<MemoryReportPromise> AccumulateMemoryReport(
158 MemoryReport aInitial);
160 /// Can only be called from the render thread.
161 void AddRenderer(wr::WindowId aWindowId, UniquePtr<RendererOGL> aRenderer);
163 /// Can only be called from the render thread.
164 void RemoveRenderer(wr::WindowId aWindowId);
166 /// Can only be called from the render thread.
167 RendererOGL* GetRenderer(wr::WindowId aWindowId);
169 /// Automatically forwarded to the render thread.
170 void SetClearColor(wr::WindowId aWindowId, wr::ColorF aColor);
172 /// Automatically forwarded to the render thread.
173 void SetProfilerUI(wr::WindowId aWindowId, const nsACString& aUI);
175 /// Automatically forwarded to the render thread.
176 void PipelineSizeChanged(wr::WindowId aWindowId, uint64_t aPipelineId,
177 float aWidth, float aHeight);
179 /// Post RendererEvent to the render thread.
180 void PostEvent(wr::WindowId aWindowId, UniquePtr<RendererEvent> aEvent);
182 /// Can only be called from the render thread.
183 void SetFramePublishId(wr::WindowId aWindowId, FramePublishId aPublishId);
185 /// Can only be called from the render thread.
186 void UpdateAndRender(wr::WindowId aWindowId, const VsyncId& aStartId,
187 const TimeStamp& aStartTime, bool aRender,
188 const Maybe<gfx::IntSize>& aReadbackSize,
189 const Maybe<wr::ImageFormat>& aReadbackFormat,
190 const Maybe<Range<uint8_t>>& aReadbackBuffer,
191 bool* aNeedsYFlip = nullptr);
193 void Pause(wr::WindowId aWindowId);
194 bool Resume(wr::WindowId aWindowId);
196 /// Can be called from any thread.
197 void RegisterExternalImage(const wr::ExternalImageId& aExternalImageId,
198 already_AddRefed<RenderTextureHost> aTexture);
200 /// Can be called from any thread.
201 void UnregisterExternalImage(const wr::ExternalImageId& aExternalImageId);
203 /// Can be called from any thread.
204 void DestroyExternalImagesSyncWait(
205 const std::vector<wr::ExternalImageId>&& aIds);
207 /// Can be called from any thread.
208 void PrepareForUse(const wr::ExternalImageId& aExternalImageId);
210 /// Can be called from any thread.
211 void NotifyNotUsed(const wr::ExternalImageId& aExternalImageId);
213 /// Can be called from any thread.
214 void NotifyForUse(const wr::ExternalImageId& aExternalImageId);
216 void HandleRenderTextureOps();
218 /// Can only be called from the render thread.
219 void UnregisterExternalImageDuringShutdown(
220 const wr::ExternalImageId& aExternalImageId);
222 /// Can only be called from the render thread.
223 RenderTextureHost* GetRenderTexture(
224 const wr::ExternalImageId& aExternalImageId);
226 /// Can be called from any thread.
227 bool IsDestroyed(wr::WindowId aWindowId);
228 /// Can be called from any thread.
229 void SetDestroyed(wr::WindowId aWindowId);
230 /// Can be called from any thread.
231 bool TooManyPendingFrames(wr::WindowId aWindowId);
232 /// Can be called from any thread.
233 void IncPendingFrameCount(wr::WindowId aWindowId, const VsyncId& aStartId,
234 const TimeStamp& aStartTime);
235 /// Can be called from any thread.
236 void DecPendingFrameBuildCount(wr::WindowId aWindowId);
237 void DecPendingFrameCount(wr::WindowId aWindowId);
239 // RenderNotifier implementation
240 void WrNotifierEvent_WakeUp(WrWindowId aWindowId, bool aCompositeNeeded);
241 void WrNotifierEvent_NewFrameReady(WrWindowId aWindowId,
242 bool aCompositeNeeded,
243 FramePublishId aPublishId);
244 void WrNotifierEvent_ExternalEvent(WrWindowId aWindowId, size_t aRawEvent);
246 /// Can be called from any thread.
247 WebRenderThreadPool& ThreadPool() { return mThreadPool; }
249 /// Thread pool for low priority scene building
250 /// Can be called from any thread.
251 WebRenderThreadPool& ThreadPoolLP() { return mThreadPoolLP; }
253 /// Returns the cache used to serialize shader programs to disk, if enabled.
255 /// Can only be called from the render thread.
256 WebRenderProgramCache* GetProgramCache() {
257 MOZ_ASSERT(IsInRenderThread());
258 return mProgramCache.get();
261 /// Can only be called from the render thread.
262 WebRenderShaders* GetShaders() {
263 MOZ_ASSERT(IsInRenderThread());
264 return mShaders.get();
267 /// Can only be called from the render thread.
268 gl::GLContext* SingletonGL(nsACString& aError);
269 gl::GLContext* SingletonGL();
270 gl::GLContext* SingletonGLForCompositorOGL();
271 void ClearSingletonGL();
272 RefPtr<layers::SurfacePool> SharedSurfacePool();
273 void ClearSharedSurfacePool();
275 RefPtr<layers::ShaderProgramOGLsHolder> GetProgramsForCompositorOGL();
277 /// Can only be called from the render thread.
278 void HandleDeviceReset(const char* aWhere, GLenum aReason);
279 /// Can only be called from the render thread.
280 bool IsHandlingDeviceReset();
281 /// Can be called from any thread.
282 void SimulateDeviceReset();
284 /// Can only be called from the render thread.
285 void NotifyWebRenderError(WebRenderError aError);
287 /// Can only be called from the render thread.
288 void HandleWebRenderError(WebRenderError aError);
289 /// Can only be called from the render thread.
290 bool IsHandlingWebRenderError();
292 /// Can only be called from the render thread.
293 bool SyncObjectNeeded();
295 size_t RendererCount() const;
296 size_t ActiveRendererCount() const { return sActiveRendererCount; };
297 void UpdateActiveRendererCount();
299 void BeginRecordingForWindow(wr::WindowId aWindowId,
300 const TimeStamp& aRecordingStart,
301 wr::PipelineId aRootPipelineId);
303 Maybe<layers::FrameRecording> EndRecordingForWindow(wr::WindowId aWindowId);
305 static void MaybeEnableGLDebugMessage(gl::GLContext* aGLContext);
307 void SetBatteryInfo(const hal::BatteryInformation& aBatteryInfo);
308 bool GetPowerIsCharging();
310 private:
311 static size_t sRendererCount;
312 static size_t sActiveRendererCount;
314 enum class RenderTextureOp {
315 PrepareForUse,
316 NotifyForUse,
317 NotifyNotUsed,
319 class WrNotifierEvent {
320 public:
321 enum class Tag {
322 WakeUp,
323 NewFrameReady,
324 ExternalEvent,
326 const Tag mTag;
328 private:
329 WrNotifierEvent(const Tag aTag, const bool aCompositeNeeded)
330 : mTag(aTag), mCompositeNeeded(aCompositeNeeded) {
331 MOZ_ASSERT(mTag == Tag::WakeUp);
333 WrNotifierEvent(const Tag aTag, bool aCompositeNeeded,
334 FramePublishId aPublishId)
335 : mTag(aTag),
336 mCompositeNeeded(aCompositeNeeded),
337 mPublishId(aPublishId) {
338 MOZ_ASSERT(mTag == Tag::NewFrameReady);
340 WrNotifierEvent(const Tag aTag, UniquePtr<RendererEvent>&& aRendererEvent)
341 : mTag(aTag), mRendererEvent(std::move(aRendererEvent)) {
342 MOZ_ASSERT(mTag == Tag::ExternalEvent);
345 const bool mCompositeNeeded = false;
346 const FramePublishId mPublishId = FramePublishId::INVALID;
347 UniquePtr<RendererEvent> mRendererEvent;
349 public:
350 static WrNotifierEvent WakeUp(const bool aCompositeNeeded) {
351 return WrNotifierEvent(Tag::WakeUp, aCompositeNeeded);
354 static WrNotifierEvent NewFrameReady(const bool aCompositeNeeded,
355 const FramePublishId aPublishId) {
356 return WrNotifierEvent(Tag::NewFrameReady, aCompositeNeeded, aPublishId);
359 static WrNotifierEvent ExternalEvent(
360 UniquePtr<RendererEvent>&& aRendererEvent) {
361 return WrNotifierEvent(Tag::ExternalEvent, std::move(aRendererEvent));
364 bool CompositeNeeded() {
365 if (mTag == Tag::WakeUp || mTag == Tag::NewFrameReady) {
366 return mCompositeNeeded;
368 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
369 return false;
371 FramePublishId PublishId() {
372 if (mTag == Tag::NewFrameReady) {
373 return mPublishId;
375 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
376 return FramePublishId::INVALID;
378 UniquePtr<RendererEvent> ExternalEvent() {
379 if (mTag == Tag::ExternalEvent) {
380 MOZ_ASSERT(mRendererEvent);
381 return std::move(mRendererEvent);
383 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
384 return nullptr;
388 explicit RenderThread(RefPtr<nsIThread> aThread);
390 void HandleFrameOneDocInner(wr::WindowId aWindowId, bool aRender,
391 bool aTrackedFrame,
392 Maybe<FramePublishId> aPublishId);
394 void DeferredRenderTextureHostDestroy();
395 void ShutDownTask();
396 void InitDeviceTask();
397 void HandleFrameOneDoc(wr::WindowId aWindowId, bool aRender,
398 bool aTrackedFrame, Maybe<FramePublishId> aPublishId);
399 void RunEvent(wr::WindowId aWindowId, UniquePtr<RendererEvent> aEvent);
400 void PostRunnable(already_AddRefed<nsIRunnable> aRunnable);
402 void DoAccumulateMemoryReport(MemoryReport,
403 const RefPtr<MemoryReportPromise::Private>&);
405 void AddRenderTextureOp(RenderTextureOp aOp,
406 const wr::ExternalImageId& aExternalImageId);
408 void CreateSingletonGL(nsACString& aError);
410 void DestroyExternalImages(const std::vector<wr::ExternalImageId>&& aIds);
412 struct WindowInfo;
414 void PostWrNotifierEvents(WrWindowId aWindowId);
415 void PostWrNotifierEvents(WrWindowId aWindowId, WindowInfo* aInfo);
416 void HandleWrNotifierEvents(WrWindowId aWindowId);
417 void WrNotifierEvent_HandleWakeUp(wr::WindowId aWindowId,
418 bool aCompositeNeeded);
419 void WrNotifierEvent_HandleNewFrameReady(wr::WindowId aWindowId,
420 bool aCompositeNeeded,
421 FramePublishId aPublishId);
422 void WrNotifierEvent_HandleExternalEvent(
423 wr::WindowId aWindowId, UniquePtr<RendererEvent> aRendererEvent);
425 ~RenderThread();
427 RefPtr<nsIThread> const mThread;
429 WebRenderThreadPool mThreadPool;
430 WebRenderThreadPool mThreadPoolLP;
432 UniquePtr<WebRenderProgramCache> mProgramCache;
433 UniquePtr<WebRenderShaders> mShaders;
434 RefPtr<layers::ShaderProgramOGLsHolder> mProgramsForCompositorOGL;
436 // An optional shared GLContext to be used for all
437 // windows.
438 RefPtr<gl::GLContext> mSingletonGL;
439 bool mSingletonGLIsForHardwareWebRender;
441 RefPtr<layers::SurfacePool> mSurfacePool;
443 std::map<wr::WindowId, UniquePtr<RendererOGL>> mRenderers;
445 DataMutex<Maybe<hal::BatteryInformation>> mBatteryInfo;
447 struct PendingFrameInfo {
448 TimeStamp mStartTime;
449 VsyncId mStartId;
452 struct WindowInfo {
453 int64_t PendingCount() { return mPendingFrames.size(); }
454 std::queue<PendingFrameInfo> mPendingFrames;
455 uint8_t mPendingFrameBuild = 0;
456 bool mIsDestroyed = false;
457 RefPtr<nsIRunnable> mWrNotifierEventsRunnable;
458 std::queue<WrNotifierEvent> mPendingWrNotifierEvents;
461 DataMutex<std::unordered_map<uint64_t, UniquePtr<WindowInfo>>> mWindowInfos;
463 std::unordered_map<uint64_t, UniquePtr<std::queue<WrNotifierEvent>>>
464 mWrNotifierEventsQueues;
466 struct ExternalImageIdHashFn {
467 std::size_t operator()(const wr::ExternalImageId& aId) const {
468 return HashGeneric(wr::AsUint64(aId));
472 Mutex mRenderTextureMapLock;
473 std::unordered_map<wr::ExternalImageId, RefPtr<RenderTextureHost>,
474 ExternalImageIdHashFn>
475 mRenderTextures MOZ_GUARDED_BY(mRenderTextureMapLock);
476 std::unordered_map<wr::ExternalImageId, RefPtr<RenderTextureHost>,
477 ExternalImageIdHashFn>
478 mSyncObjectNeededRenderTextures MOZ_GUARDED_BY(mRenderTextureMapLock);
479 std::list<std::pair<RenderTextureOp, RefPtr<RenderTextureHost>>>
480 mRenderTextureOps MOZ_GUARDED_BY(mRenderTextureMapLock);
482 // Used to remove all RenderTextureHost that are going to be removed by
483 // a deferred callback and remove them right away without waiting for the
484 // callback. On device reset we have to remove all GL related resources right
485 // away.
486 std::list<RefPtr<RenderTextureHost>> mRenderTexturesDeferred
487 MOZ_GUARDED_BY(mRenderTextureMapLock);
489 RefPtr<nsIRunnable> mRenderTextureOpsRunnable
490 MOZ_GUARDED_BY(mRenderTextureMapLock);
492 // Set from MainThread, read from either MainThread or RenderThread
493 bool mHasShutdown;
495 // Only accessed from the RenderThread
496 bool mHandlingDeviceReset;
497 bool mHandlingWebRenderError;
500 } // namespace wr
501 } // namespace mozilla
503 #endif