Bug 1941128 - Turn off network.dns.native_https_query on Mac again
[gecko.git] / dom / canvas / WebGLParent.cpp
blob2f94238ad17bda416fe95eb143d1c1a8b9a15c7e
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/. */
6 #include "WebGLParent.h"
8 #include "WebGLChild.h"
9 #include "mozilla/layers/SharedSurfacesParent.h"
10 #include "mozilla/layers/TextureClientSharedSurface.h"
11 #include "ImageContainer.h"
12 #include "HostWebGLContext.h"
13 #include "WebGLMethodDispatcher.h"
15 namespace mozilla::dom {
17 mozilla::ipc::IPCResult WebGLParent::RecvInitialize(
18 const webgl::InitContextDesc& desc, webgl::InitContextResult* const out) {
19 mHost = HostWebGLContext::Create({nullptr, this}, desc, out);
21 if (!mHost) {
22 MOZ_ASSERT(!out->error->empty());
25 return IPC_OK();
28 WebGLParent::WebGLParent(layers::SharedSurfacesHolder* aSharedSurfacesHolder,
29 const dom::ContentParentId& aContentId)
30 : mSharedSurfacesHolder(aSharedSurfacesHolder), mContentId(aContentId) {}
32 WebGLParent::~WebGLParent() = default;
34 // -
36 using IPCResult = mozilla::ipc::IPCResult;
38 IPCResult WebGLParent::RecvDispatchCommands(BigBuffer&& shmem,
39 const uint64_t cmdsByteSize) {
40 AUTO_PROFILER_LABEL("WebGLParent::RecvDispatchCommands", GRAPHICS);
41 if (!mHost) {
42 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
45 const auto& gl = mHost->mContext->GL();
46 const gl::GLContext::TlsScope tlsIsCurrent(gl);
48 MOZ_ASSERT(cmdsByteSize);
49 const auto shmemBytes = Range<uint8_t>{shmem.AsSpan()};
50 const auto byteSize = std::min<uint64_t>(shmemBytes.length(), cmdsByteSize);
51 const auto cmdsBytes =
52 Range<const uint8_t>{shmemBytes.begin(), shmemBytes.begin() + byteSize};
53 auto view = webgl::RangeConsumerView{cmdsBytes};
55 if (kIsDebug) {
56 const auto initialOffset =
57 AlignmentOffset(kUniversalAlignment, cmdsBytes.begin().get());
58 MOZ_ALWAYS_TRUE(!initialOffset);
61 std::optional<std::string> fatalError;
63 while (true) {
64 view.AlignTo(kUniversalAlignment);
65 size_t id = 0;
66 if (!view.ReadParam(&id)) break;
68 // We split this up so that we don't end up in a long callstack chain of
69 // WebGLMethodDispatcher<i>|i=0->N. First get the lambda for dispatch, then
70 // invoke the lambda with our args.
71 const auto pfn =
72 WebGLMethodDispatcher<0>::DispatchCommandFuncById<HostWebGLContext>(id);
73 if (!pfn) {
74 const nsPrintfCString cstr(
75 "MethodDispatcher<%zu> not found. Please file a bug!", id);
76 fatalError = ToString(cstr);
77 gfxCriticalError() << *fatalError;
78 break;
81 const auto ok = (*pfn)(*mHost, view);
82 if (!ok) {
83 const nsPrintfCString cstr(
84 "DispatchCommand(id: %zu) failed. Please file a bug!", id);
85 fatalError = ToString(cstr);
86 gfxCriticalError() << *fatalError;
87 break;
91 if (fatalError) {
92 mHost->JsWarning(*fatalError);
93 mHost->OnContextLoss(webgl::ContextLossReason::None);
96 return IPC_OK();
99 IPCResult WebGLParent::RecvTexImage(const uint32_t level,
100 const uint32_t respecFormat,
101 const uvec3& offset,
102 const webgl::PackingInfo& pi,
103 webgl::TexUnpackBlobDesc&& desc) {
104 if (!mHost) {
105 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
108 mHost->TexImage(level, respecFormat, offset, pi, desc);
109 return IPC_OK();
112 // -
114 mozilla::ipc::IPCResult WebGLParent::Recv__delete__() {
115 mHost = nullptr;
116 return IPC_OK();
119 void WebGLParent::ActorDestroy(ActorDestroyReason aWhy) { mHost = nullptr; }
121 mozilla::ipc::IPCResult WebGLParent::RecvWaitForTxn(
122 layers::RemoteTextureOwnerId aOwnerId,
123 layers::RemoteTextureTxnType aTxnType, layers::RemoteTextureTxnId aTxnId) {
124 if (mHost) {
125 mHost->WaitForTxn(aOwnerId, aTxnType, aTxnId);
127 return IPC_OK();
130 // -
132 IPCResult WebGLParent::RecvGetFrontBufferSnapshot(
133 webgl::FrontBufferSnapshotIpc* const ret) {
134 return GetFrontBufferSnapshot(ret, this);
137 IPCResult WebGLParent::GetFrontBufferSnapshot(
138 webgl::FrontBufferSnapshotIpc* const ret, IProtocol* aProtocol) {
139 AUTO_PROFILER_LABEL("WebGLParent::GetFrontBufferSnapshot", GRAPHICS);
140 *ret = {};
141 if (!mHost) {
142 return IPC_FAIL(aProtocol, "HostWebGLContext is not initialized.");
145 const bool ok = [&]() {
146 const auto maybeSize = mHost->FrontBufferSnapshotInto({});
147 if (maybeSize) {
148 const auto& surfSize = *maybeSize;
149 const auto byteSize = 4 * surfSize.x * surfSize.y;
151 auto shmem = webgl::RaiiShmem::Alloc(aProtocol, byteSize);
152 if (!shmem) {
153 NS_WARNING("Failed to alloc shmem for RecvGetFrontBufferSnapshot.");
154 return false;
156 const auto range = shmem.ByteRange();
157 *ret = {surfSize, Some(shmem.Extract())};
159 if (!mHost->FrontBufferSnapshotInto(Some(range))) {
160 gfxCriticalNote << "WebGLParent::RecvGetFrontBufferSnapshot: "
161 "FrontBufferSnapshotInto(some) failed after "
162 "FrontBufferSnapshotInto(none)";
163 return false;
166 return true;
167 }();
168 if (!ok) {
169 // Zero means failure, as we still need to send any shmem we alloc.
170 ret->surfSize = {0, 0};
172 return IPC_OK();
175 IPCResult WebGLParent::RecvGetBufferSubData(const GLenum target,
176 const uint64_t srcByteOffset,
177 const uint64_t byteSize,
178 Shmem* const ret) {
179 AUTO_PROFILER_LABEL("WebGLParent::RecvGetBufferSubData", GRAPHICS);
180 if (!mHost) {
181 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
184 const auto allocSize = 1 + byteSize;
185 auto shmem = webgl::RaiiShmem::Alloc(this, allocSize);
186 if (!shmem) {
187 NS_WARNING("Failed to alloc shmem for RecvGetBufferSubData.");
188 return IPC_OK();
191 const auto shmemRange = shmem.ByteRange();
192 const auto dataRange =
193 Range<uint8_t>{shmemRange.begin() + 1, shmemRange.end()};
195 // We need to always send the shmem:
196 // https://bugzilla.mozilla.org/show_bug.cgi?id=1463831#c2
197 const auto ok = mHost->GetBufferSubData(target, srcByteOffset, dataRange);
198 *(shmemRange.begin().get()) = ok;
199 *ret = shmem.Extract();
200 return IPC_OK();
203 IPCResult WebGLParent::RecvReadPixels(const webgl::ReadPixelsDesc& desc,
204 ReadPixelsBuffer&& buffer,
205 webgl::ReadPixelsResultIpc* const ret) {
206 AUTO_PROFILER_LABEL("WebGLParent::RecvReadPixels", GRAPHICS);
207 *ret = {};
208 if (!mHost) {
209 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
212 if (buffer.type() == ReadPixelsBuffer::TShmem) {
213 const auto& shmem = buffer.get_Shmem();
214 const auto range = shmem.Range<uint8_t>();
215 const auto res = mHost->ReadPixelsInto(desc, range);
216 *ret = {res, {}};
217 return IPC_OK();
220 const uint64_t byteSize = buffer.get_uint64_t();
221 const auto allocSize = std::max<uint64_t>(1, byteSize);
222 auto shmem = webgl::RaiiShmem::Alloc(this, allocSize);
223 if (!shmem) {
224 NS_WARNING("Failed to alloc shmem for RecvReadPixels.");
225 return IPC_OK();
228 const auto range = shmem.ByteRange();
230 const auto res = mHost->ReadPixelsInto(desc, range);
231 *ret = {res, Some(shmem.Extract())};
232 return IPC_OK();
235 // -
237 IPCResult WebGLParent::RecvCheckFramebufferStatus(GLenum target,
238 GLenum* const ret) {
239 if (!mHost) {
240 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
243 *ret = mHost->CheckFramebufferStatus(target);
244 return IPC_OK();
247 IPCResult WebGLParent::RecvClientWaitSync(ObjectId id, GLbitfield flags,
248 GLuint64 timeout, GLenum* const ret) {
249 if (!mHost) {
250 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
253 *ret = mHost->ClientWaitSync(id, flags, timeout);
254 return IPC_OK();
257 IPCResult WebGLParent::RecvCreateOpaqueFramebuffer(
258 const ObjectId id, const OpaqueFramebufferOptions& options,
259 bool* const ret) {
260 if (!mHost) {
261 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
264 *ret = mHost->CreateOpaqueFramebuffer(id, options);
265 return IPC_OK();
268 IPCResult WebGLParent::RecvDrawingBufferSize(uvec2* const ret) {
269 if (!mHost) {
270 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
273 *ret = mHost->DrawingBufferSize();
274 return IPC_OK();
277 IPCResult WebGLParent::RecvFinish() {
278 if (!mHost) {
279 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
282 mHost->Finish();
283 return IPC_OK();
286 IPCResult WebGLParent::RecvGetBufferParameter(GLenum target, GLenum pname,
287 Maybe<double>* const ret) {
288 if (!mHost) {
289 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
292 *ret = mHost->GetBufferParameter(target, pname);
293 return IPC_OK();
296 IPCResult WebGLParent::RecvGetCompileResult(ObjectId id,
297 webgl::CompileResult* const ret) {
298 if (!mHost) {
299 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
302 *ret = mHost->GetCompileResult(id);
303 return IPC_OK();
306 IPCResult WebGLParent::RecvGetError(GLenum* const ret) {
307 if (!mHost) {
308 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
311 *ret = mHost->GetError();
312 return IPC_OK();
315 IPCResult WebGLParent::RecvGetFragDataLocation(ObjectId id,
316 const std::string& name,
317 GLint* const ret) {
318 if (!mHost) {
319 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
322 *ret = mHost->GetFragDataLocation(id, name);
323 return IPC_OK();
326 IPCResult WebGLParent::RecvGetFramebufferAttachmentParameter(
327 ObjectId id, GLenum attachment, GLenum pname, Maybe<double>* const ret) {
328 if (!mHost) {
329 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
332 *ret = mHost->GetFramebufferAttachmentParameter(id, attachment, pname);
333 return IPC_OK();
336 IPCResult WebGLParent::RecvGetFrontBuffer(
337 ObjectId fb, const bool vr, Maybe<layers::SurfaceDescriptor>* const ret) {
338 if (!mHost) {
339 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
342 *ret = mHost->GetFrontBuffer(fb, vr);
343 return IPC_OK();
346 IPCResult WebGLParent::RecvGetIndexedParameter(GLenum target, GLuint index,
347 Maybe<double>* const ret) {
348 if (!mHost) {
349 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
352 *ret = mHost->GetIndexedParameter(target, index);
353 return IPC_OK();
356 IPCResult WebGLParent::RecvGetInternalformatParameter(
357 const GLenum target, const GLuint format, const GLuint pname,
358 Maybe<std::vector<int32_t>>* const ret) {
359 if (!mHost) {
360 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
363 *ret = mHost->GetInternalformatParameter(target, format, pname);
364 return IPC_OK();
367 IPCResult WebGLParent::RecvGetLinkResult(ObjectId id,
368 webgl::LinkResult* const ret) {
369 if (!mHost) {
370 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
373 *ret = mHost->GetLinkResult(id);
374 return IPC_OK();
377 IPCResult WebGLParent::RecvGetNumber(GLenum pname, Maybe<double>* const ret) {
378 if (!mHost) {
379 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
382 *ret = mHost->GetNumber(pname);
383 return IPC_OK();
386 IPCResult WebGLParent::RecvGetQueryParameter(ObjectId id, GLenum pname,
387 Maybe<double>* const ret) {
388 if (!mHost) {
389 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
392 *ret = mHost->GetQueryParameter(id, pname);
393 return IPC_OK();
396 IPCResult WebGLParent::RecvGetRenderbufferParameter(ObjectId id, GLenum pname,
397 Maybe<double>* const ret) {
398 if (!mHost) {
399 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
402 *ret = mHost->GetRenderbufferParameter(id, pname);
403 return IPC_OK();
406 IPCResult WebGLParent::RecvGetSamplerParameter(ObjectId id, GLenum pname,
407 Maybe<double>* const ret) {
408 if (!mHost) {
409 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
412 *ret = mHost->GetSamplerParameter(id, pname);
413 return IPC_OK();
416 IPCResult WebGLParent::RecvGetShaderPrecisionFormat(
417 GLenum shaderType, GLenum precisionType,
418 Maybe<webgl::ShaderPrecisionFormat>* const ret) {
419 if (!mHost) {
420 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
423 *ret = mHost->GetShaderPrecisionFormat(shaderType, precisionType);
424 return IPC_OK();
427 IPCResult WebGLParent::RecvGetString(GLenum pname,
428 Maybe<std::string>* const ret) {
429 if (!mHost) {
430 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
433 *ret = mHost->GetString(pname);
434 return IPC_OK();
437 IPCResult WebGLParent::RecvGetTexParameter(ObjectId id, GLenum pname,
438 Maybe<double>* const ret) {
439 if (!mHost) {
440 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
443 *ret = mHost->GetTexParameter(id, pname);
444 return IPC_OK();
447 IPCResult WebGLParent::RecvGetUniform(ObjectId id, uint32_t loc,
448 webgl::GetUniformData* const ret) {
449 if (!mHost) {
450 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
453 *ret = mHost->GetUniform(id, loc);
454 return IPC_OK();
457 IPCResult WebGLParent::RecvGetVertexAttrib(GLuint index, GLenum pname,
458 Maybe<double>* const ret) {
459 if (!mHost) {
460 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
463 *ret = mHost->GetVertexAttrib(index, pname);
464 return IPC_OK();
467 IPCResult WebGLParent::RecvOnMemoryPressure() {
468 if (!mHost) {
469 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
472 mHost->OnMemoryPressure();
473 return IPC_OK();
476 IPCResult WebGLParent::RecvValidateProgram(ObjectId id, bool* const ret) {
477 if (!mHost) {
478 return IPC_FAIL(this, "HostWebGLContext is not initialized.");
481 *ret = mHost->ValidateProgram(id);
482 return IPC_OK();
485 } // namespace mozilla::dom