Coverage Report

Created: 2018-09-25 14:53

/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