/work/obj-fuzz/dist/include/mozilla/webrender/RenderThread.h
Line | Count | Source (jump to first uncovered line) |
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/. */ |
6 | | |
7 | | #ifndef MOZILLA_LAYERS_RENDERTHREAD_H |
8 | | #define MOZILLA_LAYERS_RENDERTHREAD_H |
9 | | |
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 "nsISupportsImpl.h" |
15 | | #include "ThreadSafeRefcountingWithMainThreadDestruction.h" |
16 | | #include "mozilla/MozPromise.h" |
17 | | #include "mozilla/Mutex.h" |
18 | | #include "mozilla/webrender/webrender_ffi.h" |
19 | | #include "mozilla/UniquePtr.h" |
20 | | #include "mozilla/webrender/WebRenderTypes.h" |
21 | | #include "mozilla/layers/SynchronousTask.h" |
22 | | |
23 | | #include <list> |
24 | | #include <queue> |
25 | | #include <unordered_map> |
26 | | |
27 | | namespace mozilla { |
28 | | namespace wr { |
29 | | |
30 | | typedef MozPromise<MemoryReport, bool, true> MemoryReportPromise; |
31 | | |
32 | | class RendererOGL; |
33 | | class RenderTextureHost; |
34 | | class RenderThread; |
35 | | |
36 | | /// A rayon thread pool that is shared by all WebRender instances within a process. |
37 | | class WebRenderThreadPool { |
38 | | public: |
39 | | WebRenderThreadPool(); |
40 | | |
41 | | ~WebRenderThreadPool(); |
42 | | |
43 | 0 | wr::WrThreadPool* Raw() { return mThreadPool; } |
44 | | |
45 | | protected: |
46 | | wr::WrThreadPool* mThreadPool; |
47 | | }; |
48 | | |
49 | | class WebRenderProgramCache { |
50 | | public: |
51 | | explicit WebRenderProgramCache(wr::WrThreadPool* aThreadPool); |
52 | | |
53 | | ~WebRenderProgramCache(); |
54 | | |
55 | 0 | wr::WrProgramCache* Raw() { return mProgramCache; } |
56 | | |
57 | | protected: |
58 | | wr::WrProgramCache* mProgramCache; |
59 | | }; |
60 | | |
61 | | /// Base class for an event that can be scheduled to run on the render thread. |
62 | | /// |
63 | | /// The event can be passed through the same channels as regular WebRender messages |
64 | | /// to preserve ordering. |
65 | | class RendererEvent |
66 | | { |
67 | | public: |
68 | 0 | virtual ~RendererEvent() {} |
69 | | virtual void Run(RenderThread& aRenderThread, wr::WindowId aWindow) = 0; |
70 | | }; |
71 | | |
72 | | /// The render thread is where WebRender issues all of its GPU work, and as much |
73 | | /// as possible this thread should only serve this purpose. |
74 | | /// |
75 | | /// The render thread owns the different RendererOGLs (one per window) and implements |
76 | | /// the RenderNotifier api exposed by the WebRender bindings. |
77 | | /// |
78 | | /// We should generally avoid posting tasks to the render thread's event loop directly |
79 | | /// and instead use the RendererEvent mechanism which avoids races between the events |
80 | | /// and WebRender's own messages. |
81 | | /// |
82 | | /// The GL context(s) should be created and used on this thread only. |
83 | | /// XXX - I've tried to organize code so that we can potentially avoid making |
84 | | /// this a singleton since this bad habit has a tendency to bite us later, but |
85 | | /// I haven't gotten all the way there either, in order to focus on the more |
86 | | /// important pieces first. So we are a bit in-between (this is totally a singleton |
87 | | /// but in some places we pretend it's not). Hopefully we can evolve this in a way |
88 | | /// that keeps the door open to removing the singleton bits. |
89 | | class RenderThread final |
90 | | { |
91 | | NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(RenderThread) |
92 | | |
93 | | public: |
94 | | /// Can be called from any thread. |
95 | | static RenderThread* Get(); |
96 | | |
97 | | /// Can only be called from the main thread. |
98 | | static void Start(); |
99 | | |
100 | | /// Can only be called from the main thread. |
101 | | static void ShutDown(); |
102 | | |
103 | | /// Can be called from any thread. |
104 | | /// In most cases it is best to post RendererEvents through WebRenderAPI instead |
105 | | /// of scheduling directly to this message loop (so as to preserve the ordering |
106 | | /// of the messages). |
107 | | static MessageLoop* Loop(); |
108 | | |
109 | | /// Can be called from any thread. |
110 | | static bool IsInRenderThread(); |
111 | | |
112 | | // Can be called from any thread. Dispatches an event to the Renderer thread |
113 | | // to iterate over all Renderers, accumulates memory statistics, and resolves |
114 | | // the return promise. |
115 | | static RefPtr<MemoryReportPromise> AccumulateMemoryReport(MemoryReport aInitial); |
116 | | |
117 | | /// Can only be called from the render thread. |
118 | | void AddRenderer(wr::WindowId aWindowId, UniquePtr<RendererOGL> aRenderer); |
119 | | |
120 | | /// Can only be called from the render thread. |
121 | | void RemoveRenderer(wr::WindowId aWindowId); |
122 | | |
123 | | /// Can only be called from the render thread. |
124 | | RendererOGL* GetRenderer(wr::WindowId aWindowId); |
125 | | |
126 | | // RenderNotifier implementation |
127 | | |
128 | | /// Automatically forwarded to the render thread. |
129 | | void NewFrameReady(wr::WindowId aWindowId); |
130 | | |
131 | | /// Automatically forwarded to the render thread. |
132 | | void WakeUp(wr::WindowId aWindowId); |
133 | | |
134 | | /// Automatically forwarded to the render thread. |
135 | | void PipelineSizeChanged(wr::WindowId aWindowId, uint64_t aPipelineId, float aWidth, float aHeight); |
136 | | |
137 | | /// Automatically forwarded to the render thread. |
138 | | void RunEvent(wr::WindowId aWindowId, UniquePtr<RendererEvent> aCallBack); |
139 | | |
140 | | /// Can only be called from the render thread. |
141 | | void UpdateAndRender(wr::WindowId aWindowId, const TimeStamp& aStartTime, bool aReadback = false); |
142 | | |
143 | | void Pause(wr::WindowId aWindowId); |
144 | | bool Resume(wr::WindowId aWindowId); |
145 | | |
146 | | /// Can be called from any thread. |
147 | | void RegisterExternalImage(uint64_t aExternalImageId, already_AddRefed<RenderTextureHost> aTexture); |
148 | | |
149 | | /// Can be called from any thread. |
150 | | void UnregisterExternalImage(uint64_t aExternalImageId); |
151 | | |
152 | | /// Can be called from any thread. |
153 | | void UpdateRenderTextureHost(uint64_t aSrcExternalImageId, uint64_t aWrappedExternalImageId); |
154 | | |
155 | | /// Can only be called from the render thread. |
156 | | void UnregisterExternalImageDuringShutdown(uint64_t aExternalImageId); |
157 | | |
158 | | /// Can only be called from the render thread. |
159 | | RenderTextureHost* GetRenderTexture(WrExternalImageId aExternalImageId); |
160 | | |
161 | | /// Can be called from any thread. |
162 | | bool IsDestroyed(wr::WindowId aWindowId); |
163 | | /// Can be called from any thread. |
164 | | void SetDestroyed(wr::WindowId aWindowId); |
165 | | /// Can be called from any thread. |
166 | | bool TooManyPendingFrames(wr::WindowId aWindowId); |
167 | | /// Can be called from any thread. |
168 | | void IncPendingFrameCount(wr::WindowId aWindowId, const TimeStamp& aStartTime); |
169 | | /// Can be called from any thread. |
170 | | void DecPendingFrameCount(wr::WindowId aWindowId); |
171 | | /// Can be called from any thread. |
172 | | void IncRenderingFrameCount(wr::WindowId aWindowId); |
173 | | /// Can be called from any thread. |
174 | | void FrameRenderingComplete(wr::WindowId aWindowId); |
175 | | |
176 | | /// Can be called from any thread. |
177 | 0 | WebRenderThreadPool& ThreadPool() { return mThreadPool; } |
178 | | |
179 | | /// Can only be called from the render thread. |
180 | | WebRenderProgramCache* ProgramCache(); |
181 | | |
182 | | /// Can only be called from the render thread. |
183 | | void HandleDeviceReset(const char* aWhere, bool aNotify); |
184 | | /// Can only be called from the render thread. |
185 | | bool IsHandlingDeviceReset(); |
186 | | /// Can be called from any thread. |
187 | | void SimulateDeviceReset(); |
188 | | |
189 | | size_t RendererCount(); |
190 | | |
191 | | private: |
192 | | explicit RenderThread(base::Thread* aThread); |
193 | | |
194 | | void DeferredRenderTextureHostDestroy(); |
195 | | void ShutDownTask(layers::SynchronousTask* aTask); |
196 | | void ProgramCacheTask(); |
197 | | |
198 | | void DoAccumulateMemoryReport(MemoryReport, const RefPtr<MemoryReportPromise::Private>&); |
199 | | |
200 | | ~RenderThread(); |
201 | | |
202 | | base::Thread* const mThread; |
203 | | |
204 | | WebRenderThreadPool mThreadPool; |
205 | | UniquePtr<WebRenderProgramCache> mProgramCache; |
206 | | |
207 | | std::map<wr::WindowId, UniquePtr<RendererOGL>> mRenderers; |
208 | | |
209 | | struct WindowInfo { |
210 | | bool mIsDestroyed = false; |
211 | | int64_t mPendingCount = 0; |
212 | | int64_t mRenderingCount = 0; |
213 | | // One entry in this queue for each pending frame, so the length |
214 | | // should always equal mPendingCount |
215 | | std::queue<TimeStamp> mStartTimes; |
216 | | }; |
217 | | |
218 | | Mutex mFrameCountMapLock; |
219 | | std::unordered_map<uint64_t, WindowInfo*> mWindowInfos; |
220 | | |
221 | | Mutex mRenderTextureMapLock; |
222 | | std::unordered_map<uint64_t, RefPtr<RenderTextureHost>> mRenderTextures; |
223 | | // Used to remove all RenderTextureHost that are going to be removed by |
224 | | // a deferred callback and remove them right away without waiting for the callback. |
225 | | // On device reset we have to remove all GL related resources right away. |
226 | | std::list<RefPtr<RenderTextureHost>> mRenderTexturesDeferred; |
227 | | bool mHasShutdown; |
228 | | |
229 | | bool mHandlingDeviceReset; |
230 | | }; |
231 | | |
232 | | } // namespace wr |
233 | | } // namespace mozilla |
234 | | |
235 | | #endif |