1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "HostWebGLContext.h"
7 
8 #include "CompositableHost.h"
9 #include "mozilla/layers/LayerTransactionChild.h"
10 #include "mozilla/layers/LayersSurfaces.h"
11 
12 #include "MozFramebuffer.h"
13 #include "TexUnpackBlob.h"
14 #include "WebGL2Context.h"
15 #include "WebGLBuffer.h"
16 #include "WebGLContext.h"
17 #include "WebGLFramebuffer.h"
18 #include "WebGLMemoryTracker.h"
19 #include "WebGLParent.h"
20 #include "WebGLProgram.h"
21 #include "WebGLRenderbuffer.h"
22 #include "WebGLSampler.h"
23 #include "WebGLShader.h"
24 #include "WebGLSync.h"
25 #include "WebGLTexture.h"
26 #include "WebGLTransformFeedback.h"
27 #include "WebGLVertexArray.h"
28 #include "WebGLQuery.h"
29 
30 #include "mozilla/StaticMutex.h"
31 
32 namespace mozilla {
33 
34 // -
35 
36 static StaticMutex sContextSetLock;
37 
DeferredStaticContextSet()38 static std::unordered_set<HostWebGLContext*>& DeferredStaticContextSet() {
39   static std::unordered_set<HostWebGLContext*> sContextSet;
40   return sContextSet;
41 }
42 
LockedOutstandingContexts()43 LockedOutstandingContexts::LockedOutstandingContexts()
44     : contexts(DeferredStaticContextSet()) {
45   sContextSetLock.Lock();
46 }
47 
~LockedOutstandingContexts()48 LockedOutstandingContexts::~LockedOutstandingContexts() {
49   sContextSetLock.Unlock();
50 }
51 
52 // -
53 
54 /*static*/
Create(const OwnerData & ownerData,const webgl::InitContextDesc & desc,webgl::InitContextResult * const out)55 UniquePtr<HostWebGLContext> HostWebGLContext::Create(
56     const OwnerData& ownerData, const webgl::InitContextDesc& desc,
57     webgl::InitContextResult* const out) {
58   auto host = WrapUnique(new HostWebGLContext(ownerData));
59   auto webgl = WebGLContext::Create(*host, desc, out);
60   if (!webgl) return nullptr;
61   return host;
62 }
63 
HostWebGLContext(const OwnerData & ownerData)64 HostWebGLContext::HostWebGLContext(const OwnerData& ownerData)
65     : mOwnerData(ownerData) {
66   StaticMutexAutoLock lock(sContextSetLock);
67   auto& contexts = DeferredStaticContextSet();
68   (void)contexts.insert(this);
69 }
70 
~HostWebGLContext()71 HostWebGLContext::~HostWebGLContext() {
72   StaticMutexAutoLock lock(sContextSetLock);
73   auto& contexts = DeferredStaticContextSet();
74   (void)contexts.erase(this);
75 }
76 
77 // -
78 
OnContextLoss(const webgl::ContextLossReason reason)79 void HostWebGLContext::OnContextLoss(const webgl::ContextLossReason reason) {
80   if (mOwnerData.inProcess) {
81     mOwnerData.inProcess->OnContextLoss(reason);
82   } else {
83     (void)mOwnerData.outOfProcess->SendOnContextLoss(reason);
84   }
85 }
86 
JsWarning(const std::string & text) const87 void HostWebGLContext::JsWarning(const std::string& text) const {
88   if (mOwnerData.inProcess) {
89     mOwnerData.inProcess->JsWarning(text);
90     return;
91   }
92   (void)mOwnerData.outOfProcess->SendJsWarning(text);
93 }
94 
GetFrontBuffer(const ObjectId xrFb,const bool webvr) const95 Maybe<layers::SurfaceDescriptor> HostWebGLContext::GetFrontBuffer(
96     const ObjectId xrFb, const bool webvr) const {
97   return mContext->GetFrontBuffer(AutoResolve(xrFb), webvr);
98 }
99 
100 //////////////////////////////////////////////
101 // Creation
102 
CreateBuffer(const ObjectId id)103 void HostWebGLContext::CreateBuffer(const ObjectId id) {
104   auto& slot = mBufferMap[id];
105   if (slot) {
106     MOZ_ASSERT(false, "duplicate ID");
107     return;
108   }
109   slot = mContext->CreateBuffer();
110 }
111 
CreateFramebuffer(const ObjectId id)112 void HostWebGLContext::CreateFramebuffer(const ObjectId id) {
113   auto& slot = mFramebufferMap[id];
114   if (slot) {
115     MOZ_ASSERT(false, "duplicate ID");
116     return;
117   }
118   slot = mContext->CreateFramebuffer();
119 }
120 
CreateOpaqueFramebuffer(const ObjectId id,const webgl::OpaqueFramebufferOptions & options)121 bool HostWebGLContext::CreateOpaqueFramebuffer(
122     const ObjectId id, const webgl::OpaqueFramebufferOptions& options) {
123   auto& slot = mFramebufferMap[id];
124   if (slot) {
125     MOZ_ASSERT(false, "duplicate ID");
126     return false;
127   }
128   slot = mContext->CreateOpaqueFramebuffer(options);
129   return slot;
130 }
131 
CreateProgram(const ObjectId id)132 void HostWebGLContext::CreateProgram(const ObjectId id) {
133   auto& slot = mProgramMap[id];
134   if (slot) {
135     MOZ_ASSERT(false, "duplicate ID");
136     return;
137   }
138   slot = mContext->CreateProgram();
139 }
140 
CreateQuery(const ObjectId id)141 void HostWebGLContext::CreateQuery(const ObjectId id) {
142   auto& slot = mQueryMap[id];
143   if (slot) {
144     MOZ_ASSERT(false, "duplicate ID");
145     return;
146   }
147   slot = mContext->CreateQuery();
148 }
149 
CreateRenderbuffer(const ObjectId id)150 void HostWebGLContext::CreateRenderbuffer(const ObjectId id) {
151   auto& slot = mRenderbufferMap[id];
152   if (slot) {
153     MOZ_ASSERT(false, "duplicate ID");
154     return;
155   }
156   slot = mContext->CreateRenderbuffer();
157 }
158 
CreateSampler(const ObjectId id)159 void HostWebGLContext::CreateSampler(const ObjectId id) {
160   auto& slot = mSamplerMap[id];
161   if (slot) {
162     MOZ_ASSERT(false, "duplicate ID");
163     return;
164   }
165   slot = GetWebGL2Context()->CreateSampler();
166 }
167 
CreateShader(const ObjectId id,GLenum type)168 void HostWebGLContext::CreateShader(const ObjectId id, GLenum type) {
169   auto& slot = mShaderMap[id];
170   if (slot) {
171     MOZ_ASSERT(false, "duplicate ID");
172     return;
173   }
174   slot = mContext->CreateShader(type);
175 }
176 
CreateSync(const ObjectId id)177 void HostWebGLContext::CreateSync(const ObjectId id) {
178   auto& slot = mSyncMap[id];
179   if (slot) {
180     MOZ_ASSERT(false, "duplicate ID");
181     return;
182   }
183   slot = GetWebGL2Context()->FenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
184 }
185 
CreateTexture(const ObjectId id)186 void HostWebGLContext::CreateTexture(const ObjectId id) {
187   auto& slot = mTextureMap[id];
188   if (slot) {
189     MOZ_ASSERT(false, "duplicate ID");
190     return;
191   }
192   slot = mContext->CreateTexture();
193 }
194 
CreateTransformFeedback(const ObjectId id)195 void HostWebGLContext::CreateTransformFeedback(const ObjectId id) {
196   auto& slot = mTransformFeedbackMap[id];
197   if (slot) {
198     MOZ_ASSERT(false, "duplicate ID");
199     return;
200   }
201   slot = GetWebGL2Context()->CreateTransformFeedback();
202 }
203 
CreateVertexArray(const ObjectId id)204 void HostWebGLContext::CreateVertexArray(const ObjectId id) {
205   auto& slot = mVertexArrayMap[id];
206   if (slot) {
207     MOZ_ASSERT(false, "duplicate ID");
208     return;
209   }
210   slot = mContext->CreateVertexArray();
211 }
212 
213 ////////////////////////
214 
215 #define _(X) \
216   void HostWebGLContext::Delete##X(const ObjectId id) { m##X##Map.erase(id); }
217 
218 _(Buffer)
219 _(Framebuffer)
220 _(Program)
221 _(Query)
222 _(Renderbuffer)
223 _(Sampler)
224 _(Shader)
225 _(Sync)
226 _(Texture)
227 _(TransformFeedback)
228 _(VertexArray)
229 
230 #undef _
231 
232 }  // namespace mozilla
233