Backed out 2 changesets (bug 1855992) for causing talos failures @ mozilla::net:...
[gecko.git] / gfx / webrender_bindings / RenderThread.h
blobba4e34b59196cad497c9004b7c23635f5a19b4c6
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/MozPromise.h"
18 #include "mozilla/DataMutex.h"
19 #include "mozilla/Maybe.h"
20 #include "mozilla/webrender/webrender_ffi.h"
21 #include "mozilla/UniquePtr.h"
22 #include "mozilla/webrender/WebRenderTypes.h"
23 #include "mozilla/layers/CompositionRecorder.h"
24 #include "mozilla/layers/SynchronousTask.h"
25 #include "mozilla/UniquePtr.h"
26 #include "mozilla/VsyncDispatcher.h"
28 #include <list>
29 #include <queue>
30 #include <unordered_map>
32 namespace mozilla {
33 namespace gl {
34 class GLContext;
35 } // namespace gl
36 namespace layers {
37 class CompositorBridgeParent;
38 class ShaderProgramOGLsHolder;
39 class SurfacePool;
40 } // namespace layers
41 namespace wr {
43 typedef MozPromise<MemoryReport, bool, true> MemoryReportPromise;
45 class RendererOGL;
46 class RenderTextureHost;
47 class RenderThread;
49 /// A rayon thread pool that is shared by all WebRender instances within a
50 /// process.
51 class WebRenderThreadPool {
52 public:
53 explicit WebRenderThreadPool(bool low_priority);
55 ~WebRenderThreadPool();
57 wr::WrThreadPool* Raw() {
58 // If this pointer is null we are likely at some late shutdown stage,
59 // when threads are no longer safe to interact with.
60 MOZ_RELEASE_ASSERT(mThreadPool);
61 return mThreadPool;
64 /// Prematurely destroys this handle to the thread pool.
65 /// After calling this the object is useless.
66 void Release();
68 protected:
69 wr::WrThreadPool* mThreadPool;
72 class WebRenderProgramCache final {
73 public:
74 explicit WebRenderProgramCache(wr::WrThreadPool* aThreadPool);
76 ~WebRenderProgramCache();
78 wr::WrProgramCache* Raw() { return mProgramCache; }
80 protected:
81 wr::WrProgramCache* mProgramCache;
84 class WebRenderShaders final {
85 public:
86 WebRenderShaders(gl::GLContext* gl, WebRenderProgramCache* programCache);
87 ~WebRenderShaders();
89 wr::WrShaders* RawShaders() { return mShaders; }
91 protected:
92 RefPtr<gl::GLContext> mGL;
93 wr::WrShaders* mShaders;
96 class WebRenderPipelineInfo final {
97 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderPipelineInfo);
99 const wr::WrPipelineInfo& Raw() const { return mPipelineInfo; }
100 wr::WrPipelineInfo& Raw() { return mPipelineInfo; }
102 protected:
103 ~WebRenderPipelineInfo() = default;
104 wr::WrPipelineInfo mPipelineInfo;
107 /// Base class for an event that can be scheduled to run on the render thread.
109 /// The event can be passed through the same channels as regular WebRender
110 /// messages to preserve ordering.
111 class RendererEvent {
112 public:
113 virtual ~RendererEvent() = default;
114 virtual void Run(RenderThread& aRenderThread, wr::WindowId aWindow) = 0;
117 /// The render thread is where WebRender issues all of its GPU work, and as much
118 /// as possible this thread should only serve this purpose.
120 /// The render thread owns the different RendererOGLs (one per window) and
121 /// implements the RenderNotifier api exposed by the WebRender bindings.
123 /// Callers are not allowed to post tasks to the render thread's event loop
124 /// directly and must instead use the RendererEvent mechanism which avoids races
125 /// between the events and WebRender's own messages.
127 /// The GL context(s) should be created and used on this thread only.
128 /// XXX - I've tried to organize code so that we can potentially avoid making
129 /// this a singleton since this bad habit has a tendency to bite us later, but
130 /// I haven't gotten all the way there either, in order to focus on the more
131 /// important pieces first. So we are a bit in-between (this is totally a
132 /// singleton but in some places we pretend it's not). Hopefully we can evolve
133 /// this in a way that keeps the door open to removing the singleton bits.
134 class RenderThread final {
135 NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DELETE_ON_MAIN_THREAD(RenderThread)
137 public:
138 /// Can be called from any thread.
139 static RenderThread* Get();
141 /// Can only be called from the main thread.
142 static void Start(uint32_t aNamespace);
144 /// Can only be called from the main thread.
145 static void ShutDown();
147 /// Can be called from any thread.
148 static bool IsInRenderThread();
150 /// Can be called from any thread.
151 static already_AddRefed<nsIThread> GetRenderThread();
153 // Can be called from any thread. Dispatches an event to the Renderer thread
154 // to iterate over all Renderers, accumulates memory statistics, and resolves
155 // the return promise.
156 static RefPtr<MemoryReportPromise> AccumulateMemoryReport(
157 MemoryReport aInitial);
159 /// Can only be called from the render thread.
160 void AddRenderer(wr::WindowId aWindowId, UniquePtr<RendererOGL> aRenderer);
162 /// Can only be called from the render thread.
163 void RemoveRenderer(wr::WindowId aWindowId);
165 /// Can only be called from the render thread.
166 RendererOGL* GetRenderer(wr::WindowId aWindowId);
168 /// Automatically forwarded to the render thread.
169 void SetClearColor(wr::WindowId aWindowId, wr::ColorF aColor);
171 /// Automatically forwarded to the render thread.
172 void SetProfilerUI(wr::WindowId aWindowId, const nsACString& aUI);
174 /// Automatically forwarded to the render thread.
175 void PipelineSizeChanged(wr::WindowId aWindowId, uint64_t aPipelineId,
176 float aWidth, float aHeight);
178 /// Post RendererEvent to the render thread.
179 void PostEvent(wr::WindowId aWindowId, UniquePtr<RendererEvent> aEvent);
181 /// Can only be called from the render thread.
182 void SetFramePublishId(wr::WindowId aWindowId, FramePublishId aPublishId);
184 /// Can only be called from the render thread.
185 void UpdateAndRender(wr::WindowId aWindowId, const VsyncId& aStartId,
186 const TimeStamp& aStartTime, bool aRender,
187 const Maybe<gfx::IntSize>& aReadbackSize,
188 const Maybe<wr::ImageFormat>& aReadbackFormat,
189 const Maybe<Range<uint8_t>>& aReadbackBuffer,
190 bool* aNeedsYFlip = nullptr);
192 void Pause(wr::WindowId aWindowId);
193 bool Resume(wr::WindowId aWindowId);
195 /// Can be called from any thread.
196 void RegisterExternalImage(const wr::ExternalImageId& aExternalImageId,
197 already_AddRefed<RenderTextureHost> aTexture);
199 /// Can be called from any thread.
200 void UnregisterExternalImage(const wr::ExternalImageId& aExternalImageId);
202 /// Can be called from any thread.
203 void DestroyExternalImagesSyncWait(
204 const std::vector<wr::ExternalImageId>&& aIds);
206 /// Can be called from any thread.
207 void PrepareForUse(const wr::ExternalImageId& aExternalImageId);
209 /// Can be called from any thread.
210 void NotifyNotUsed(const wr::ExternalImageId& aExternalImageId);
212 /// Can be called from any thread.
213 void NotifyForUse(const wr::ExternalImageId& aExternalImageId);
215 void HandleRenderTextureOps();
217 /// Can only be called from the render thread.
218 void UnregisterExternalImageDuringShutdown(
219 const wr::ExternalImageId& aExternalImageId);
221 /// Can only be called from the render thread.
222 RenderTextureHost* GetRenderTexture(
223 const wr::ExternalImageId& aExternalImageId);
225 /// Can be called from any thread.
226 bool IsDestroyed(wr::WindowId aWindowId);
227 /// Can be called from any thread.
228 void SetDestroyed(wr::WindowId aWindowId);
229 /// Can be called from any thread.
230 bool TooManyPendingFrames(wr::WindowId aWindowId);
231 /// Can be called from any thread.
232 void IncPendingFrameCount(wr::WindowId aWindowId, const VsyncId& aStartId,
233 const TimeStamp& aStartTime);
234 /// Can be called from any thread.
235 void DecPendingFrameBuildCount(wr::WindowId aWindowId);
236 void DecPendingFrameCount(wr::WindowId aWindowId);
238 // RenderNotifier implementation
239 void WrNotifierEvent_WakeUp(WrWindowId aWindowId, bool aCompositeNeeded);
240 void WrNotifierEvent_NewFrameReady(WrWindowId aWindowId,
241 bool aCompositeNeeded,
242 FramePublishId aPublishId);
243 void WrNotifierEvent_ExternalEvent(WrWindowId aWindowId, size_t aRawEvent);
245 /// Can be called from any thread.
246 WebRenderThreadPool& ThreadPool() { return mThreadPool; }
248 /// Thread pool for low priority scene building
249 /// Can be called from any thread.
250 WebRenderThreadPool& ThreadPoolLP() { return mThreadPoolLP; }
252 /// Returns the cache used to serialize shader programs to disk, if enabled.
254 /// Can only be called from the render thread.
255 WebRenderProgramCache* GetProgramCache() {
256 MOZ_ASSERT(IsInRenderThread());
257 return mProgramCache.get();
260 /// Can only be called from the render thread.
261 WebRenderShaders* GetShaders() {
262 MOZ_ASSERT(IsInRenderThread());
263 return mShaders.get();
266 /// Can only be called from the render thread.
267 gl::GLContext* SingletonGL(nsACString& aError);
268 gl::GLContext* SingletonGL();
269 gl::GLContext* SingletonGLForCompositorOGL();
270 void ClearSingletonGL();
271 RefPtr<layers::SurfacePool> SharedSurfacePool();
272 void ClearSharedSurfacePool();
274 RefPtr<layers::ShaderProgramOGLsHolder> GetProgramsForCompositorOGL();
276 /// Can only be called from the render thread.
277 void HandleDeviceReset(const char* aWhere, GLenum aReason);
278 /// Can only be called from the render thread.
279 bool IsHandlingDeviceReset();
280 /// Can be called from any thread.
281 void SimulateDeviceReset();
283 /// Can only be called from the render thread.
284 void NotifyWebRenderError(WebRenderError aError);
286 /// Can only be called from the render thread.
287 void HandleWebRenderError(WebRenderError aError);
288 /// Can only be called from the render thread.
289 bool IsHandlingWebRenderError();
291 /// Can only be called from the render thread.
292 bool SyncObjectNeeded();
294 size_t RendererCount() const;
295 size_t ActiveRendererCount() const;
297 void BeginRecordingForWindow(wr::WindowId aWindowId,
298 const TimeStamp& aRecordingStart,
299 wr::PipelineId aRootPipelineId);
301 Maybe<layers::FrameRecording> EndRecordingForWindow(wr::WindowId aWindowId);
303 static void MaybeEnableGLDebugMessage(gl::GLContext* aGLContext);
305 private:
306 enum class RenderTextureOp {
307 PrepareForUse,
308 NotifyForUse,
309 NotifyNotUsed,
311 class WrNotifierEvent {
312 public:
313 enum class Tag {
314 WakeUp,
315 NewFrameReady,
316 ExternalEvent,
318 const Tag mTag;
320 private:
321 WrNotifierEvent(const Tag aTag, const bool aCompositeNeeded)
322 : mTag(aTag), mCompositeNeeded(aCompositeNeeded) {
323 MOZ_ASSERT(mTag == Tag::WakeUp);
325 WrNotifierEvent(const Tag aTag, bool aCompositeNeeded,
326 FramePublishId aPublishId)
327 : mTag(aTag),
328 mCompositeNeeded(aCompositeNeeded),
329 mPublishId(aPublishId) {
330 MOZ_ASSERT(mTag == Tag::NewFrameReady);
332 WrNotifierEvent(const Tag aTag, UniquePtr<RendererEvent>&& aRendererEvent)
333 : mTag(aTag), mRendererEvent(std::move(aRendererEvent)) {
334 MOZ_ASSERT(mTag == Tag::ExternalEvent);
337 const bool mCompositeNeeded = false;
338 const FramePublishId mPublishId = FramePublishId::INVALID;
339 UniquePtr<RendererEvent> mRendererEvent;
341 public:
342 static WrNotifierEvent WakeUp(const bool aCompositeNeeded) {
343 return WrNotifierEvent(Tag::WakeUp, aCompositeNeeded);
346 static WrNotifierEvent NewFrameReady(const bool aCompositeNeeded,
347 const FramePublishId aPublishId) {
348 return WrNotifierEvent(Tag::NewFrameReady, aCompositeNeeded, aPublishId);
351 static WrNotifierEvent ExternalEvent(
352 UniquePtr<RendererEvent>&& aRendererEvent) {
353 return WrNotifierEvent(Tag::ExternalEvent, std::move(aRendererEvent));
356 bool CompositeNeeded() {
357 if (mTag == Tag::WakeUp || mTag == Tag::NewFrameReady) {
358 return mCompositeNeeded;
360 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
361 return false;
363 FramePublishId PublishId() {
364 if (mTag == Tag::NewFrameReady) {
365 return mPublishId;
367 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
368 return FramePublishId::INVALID;
370 UniquePtr<RendererEvent> ExternalEvent() {
371 if (mTag == Tag::ExternalEvent) {
372 MOZ_ASSERT(mRendererEvent);
373 return std::move(mRendererEvent);
375 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
376 return nullptr;
380 explicit RenderThread(RefPtr<nsIThread> aThread);
382 void HandleFrameOneDocInner(wr::WindowId aWindowId, bool aRender,
383 bool aTrackedFrame,
384 Maybe<FramePublishId> aPublishId);
386 void DeferredRenderTextureHostDestroy();
387 void ShutDownTask();
388 void InitDeviceTask();
389 void HandleFrameOneDoc(wr::WindowId aWindowId, bool aRender,
390 bool aTrackedFrame, Maybe<FramePublishId> aPublishId);
391 void RunEvent(wr::WindowId aWindowId, UniquePtr<RendererEvent> aEvent);
392 void PostRunnable(already_AddRefed<nsIRunnable> aRunnable);
394 void DoAccumulateMemoryReport(MemoryReport,
395 const RefPtr<MemoryReportPromise::Private>&);
397 void AddRenderTextureOp(RenderTextureOp aOp,
398 const wr::ExternalImageId& aExternalImageId);
400 void CreateSingletonGL(nsACString& aError);
402 void DestroyExternalImages(const std::vector<wr::ExternalImageId>&& aIds);
404 struct WindowInfo;
406 void PostWrNotifierEvents(WrWindowId aWindowId);
407 void PostWrNotifierEvents(WrWindowId aWindowId, WindowInfo* aInfo);
408 void HandleWrNotifierEvents(WrWindowId aWindowId);
409 void WrNotifierEvent_HandleWakeUp(wr::WindowId aWindowId,
410 bool aCompositeNeeded);
411 void WrNotifierEvent_HandleNewFrameReady(wr::WindowId aWindowId,
412 bool aCompositeNeeded,
413 FramePublishId aPublishId);
414 void WrNotifierEvent_HandleExternalEvent(
415 wr::WindowId aWindowId, UniquePtr<RendererEvent> aRendererEvent);
417 ~RenderThread();
419 RefPtr<nsIThread> const mThread;
421 WebRenderThreadPool mThreadPool;
422 WebRenderThreadPool mThreadPoolLP;
424 UniquePtr<WebRenderProgramCache> mProgramCache;
425 UniquePtr<WebRenderShaders> mShaders;
426 RefPtr<layers::ShaderProgramOGLsHolder> mProgramsForCompositorOGL;
428 // An optional shared GLContext to be used for all
429 // windows.
430 RefPtr<gl::GLContext> mSingletonGL;
431 bool mSingletonGLIsForHardwareWebRender;
433 RefPtr<layers::SurfacePool> mSurfacePool;
435 std::map<wr::WindowId, UniquePtr<RendererOGL>> mRenderers;
437 struct PendingFrameInfo {
438 TimeStamp mStartTime;
439 VsyncId mStartId;
442 struct WindowInfo {
443 int64_t PendingCount() { return mPendingFrames.size(); }
444 std::queue<PendingFrameInfo> mPendingFrames;
445 uint8_t mPendingFrameBuild = 0;
446 bool mIsDestroyed = false;
447 RefPtr<nsIRunnable> mWrNotifierEventsRunnable;
448 std::queue<WrNotifierEvent> mPendingWrNotifierEvents;
451 DataMutex<std::unordered_map<uint64_t, UniquePtr<WindowInfo>>> mWindowInfos;
453 std::unordered_map<uint64_t, UniquePtr<std::queue<WrNotifierEvent>>>
454 mWrNotifierEventsQueues;
456 struct ExternalImageIdHashFn {
457 std::size_t operator()(const wr::ExternalImageId& aId) const {
458 return HashGeneric(wr::AsUint64(aId));
462 Mutex mRenderTextureMapLock MOZ_UNANNOTATED;
463 std::unordered_map<wr::ExternalImageId, RefPtr<RenderTextureHost>,
464 ExternalImageIdHashFn>
465 mRenderTextures;
466 std::unordered_map<wr::ExternalImageId, RefPtr<RenderTextureHost>,
467 ExternalImageIdHashFn>
468 mSyncObjectNeededRenderTextures;
469 std::list<std::pair<RenderTextureOp, RefPtr<RenderTextureHost>>>
470 mRenderTextureOps;
472 // Used to remove all RenderTextureHost that are going to be removed by
473 // a deferred callback and remove them right away without waiting for the
474 // callback. On device reset we have to remove all GL related resources right
475 // away.
476 std::list<RefPtr<RenderTextureHost>> mRenderTexturesDeferred;
478 RefPtr<nsIRunnable> mRenderTextureOpsRunnable;
480 bool mHasShutdown;
482 bool mHandlingDeviceReset;
483 bool mHandlingWebRenderError;
486 } // namespace wr
487 } // namespace mozilla
489 #endif