Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set sw=2 sts=2 ts=8 et tw=99 : */
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 "nsRefPtrHashtable.h"
16 : #include "ThreadSafeRefcountingWithMainThreadDestruction.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 : namespace mozilla {
24 : namespace wr {
25 :
26 : class RendererOGL;
27 : class RenderTextureHost;
28 : class RenderThread;
29 :
30 : /// A rayon thread pool that is shared by all WebRender instances within a process.
31 : class WebRenderThreadPool {
32 : public:
33 : WebRenderThreadPool();
34 :
35 : ~WebRenderThreadPool();
36 :
37 0 : WrThreadPool* Raw() { return mThreadPool; }
38 :
39 : protected:
40 : WrThreadPool* mThreadPool;
41 : };
42 :
43 :
44 : /// Base class for an event that can be scheduled to run on the render thread.
45 : ///
46 : /// The event can be passed through the same channels as regular WebRender messages
47 : /// to preserve ordering.
48 0 : class RendererEvent
49 : {
50 : public:
51 0 : virtual ~RendererEvent() {}
52 : virtual void Run(RenderThread& aRenderThread, wr::WindowId aWindow) = 0;
53 : };
54 :
55 : /// The render thread is where WebRender issues all of its GPU work, and as much
56 : /// as possible this thread should only serve this purpose.
57 : ///
58 : /// The render thread owns the different RendererOGLs (one per window) and implements
59 : /// the RenderNotifier api exposed by the WebRender bindings.
60 : ///
61 : /// We should generally avoid posting tasks to the render thread's event loop directly
62 : /// and instead use the RendererEvent mechanism which avoids races between the events
63 : /// and WebRender's own messages.
64 : ///
65 : /// The GL context(s) should be created and used on this thread only.
66 : /// XXX - I've tried to organize code so that we can potentially avoid making
67 : /// this a singleton since this bad habit has a tendency to bite us later, but
68 : /// I haven't gotten all the way there either, in order to focus on the more
69 : /// important pieces first. So we are a bit in-between (this is totally a singleton
70 : /// but in some places we pretend it's not). Hopefully we can evolve this in a way
71 : /// that keeps the door open to removing the singleton bits.
72 : class RenderThread final
73 : {
74 0 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(RenderThread)
75 :
76 : public:
77 : /// Can be called from any thread.
78 : static RenderThread* Get();
79 :
80 : /// Can only be called from the main thread.
81 : static void Start();
82 :
83 : /// Can only be called from the main thread.
84 : static void ShutDown();
85 :
86 : /// Can be called from any thread.
87 : /// In most cases it is best to post RendererEvents through WebRenderAPI instead
88 : /// of scheduling directly to this message loop (so as to preserve the ordering
89 : /// of the messages).
90 : static MessageLoop* Loop();
91 :
92 : /// Can be called from any thread.
93 : static bool IsInRenderThread();
94 :
95 : /// Can only be called from the render thread.
96 : void AddRenderer(wr::WindowId aWindowId, UniquePtr<RendererOGL> aRenderer);
97 :
98 : /// Can only be called from the render thread.
99 : void RemoveRenderer(wr::WindowId aWindowId);
100 :
101 : /// Can only be called from the render thread.
102 : RendererOGL* GetRenderer(wr::WindowId aWindowId);
103 :
104 : // RenderNotifier implementation
105 :
106 : /// Automatically forwarded to the render thread.
107 : void NewFrameReady(wr::WindowId aWindowId);
108 :
109 : /// Automatically forwarded to the render thread.
110 : void PipelineSizeChanged(wr::WindowId aWindowId, uint64_t aPipelineId, float aWidth, float aHeight);
111 :
112 : /// Automatically forwarded to the render thread.
113 : void RunEvent(wr::WindowId aWindowId, UniquePtr<RendererEvent> aCallBack);
114 :
115 : /// Can only be called from the render thread.
116 : void UpdateAndRender(wr::WindowId aWindowId);
117 :
118 : void Pause(wr::WindowId aWindowId);
119 : bool Resume(wr::WindowId aWindowId);
120 :
121 : /// Can be called from any thread.
122 : void RegisterExternalImage(uint64_t aExternalImageId, already_AddRefed<RenderTextureHost> aTexture);
123 :
124 : /// Can be called from any thread.
125 : void UnregisterExternalImage(uint64_t aExternalImageId);
126 :
127 : /// Can only be called from the render thread.
128 : RenderTextureHost* GetRenderTexture(WrExternalImageId aExternalImageId);
129 :
130 : /// Can be called from any thread.
131 : uint32_t GetPendingFrameCount(wr::WindowId aWindowId);
132 : /// Can be called from any thread.
133 : void IncPendingFrameCount(wr::WindowId aWindowId);
134 : /// Can be called from any thread.
135 : void DecPendingFrameCount(wr::WindowId aWindowId);
136 :
137 : /// Can be called from any thread.
138 0 : WebRenderThreadPool& ThreadPool() { return mThreadPool; }
139 :
140 : private:
141 : explicit RenderThread(base::Thread* aThread);
142 :
143 : void DeferredRenderTextureHostDestroy(RefPtr<RenderTextureHost> aTexture);
144 : void ShutDownTask(layers::SynchronousTask* aTask);
145 :
146 : ~RenderThread();
147 :
148 : base::Thread* const mThread;
149 :
150 : WebRenderThreadPool mThreadPool;
151 :
152 : std::map<wr::WindowId, UniquePtr<RendererOGL>> mRenderers;
153 :
154 : Mutex mPendingFrameCountMapLock;
155 : nsDataHashtable<nsUint64HashKey, uint32_t> mPendingFrameCounts;
156 :
157 : Mutex mRenderTextureMapLock;
158 : nsRefPtrHashtable<nsUint64HashKey, RenderTextureHost> mRenderTextures;
159 : bool mHasShutdown;
160 : };
161 :
162 : } // namespace wr
163 : } // namespace mozilla
164 :
165 : #endif
|