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/LayerTransactionParent.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
&& !out
->error
.size()) {
22 return IPC_FAIL(this, "Abnormally failed to create HostWebGLContext.");
28 WebGLParent::WebGLParent() = default;
29 WebGLParent::~WebGLParent() = default;
33 using IPCResult
= mozilla::ipc::IPCResult
;
35 IPCResult
WebGLParent::RecvDispatchCommands(Shmem
&& rawShmem
,
36 const uint64_t cmdsByteSize
) {
37 auto shmem
= webgl::RaiiShmem(this, std::move(rawShmem
));
39 const auto& gl
= mHost
->mContext
->GL();
40 const gl::GLContext::TlsScope
tlsIsCurrent(gl
);
42 MOZ_ASSERT(cmdsByteSize
);
43 const auto shmemBytes
= shmem
.ByteRange();
44 const auto byteSize
= std::min
<uint64_t>(shmemBytes
.length(), cmdsByteSize
);
45 const auto cmdsBytes
=
46 Range
<const uint8_t>{shmemBytes
.begin(), shmemBytes
.begin() + byteSize
};
47 auto view
= webgl::RangeConsumerView
{cmdsBytes
};
50 view
.AlignTo(kUniversalAlignment
);
52 const auto status
= view
.ReadParam(&id
);
53 if (status
!= QueueStatus::kSuccess
) break;
55 WebGLMethodDispatcher
<0>::DispatchCommand(*mHost
, id
, view
);
63 mozilla::ipc::IPCResult
WebGLParent::Recv__delete__() {
68 void WebGLParent::ActorDestroy(ActorDestroyReason aWhy
) { mHost
= nullptr; }
72 IPCResult
WebGLParent::RecvGetFrontBufferSnapshot(
73 webgl::FrontBufferSnapshotIpc
* const ret
) {
76 const auto surfSize
= mHost
->GetFrontBufferSize();
77 const auto byteSize
= 4 * surfSize
.x
* surfSize
.y
;
79 auto shmem
= webgl::RaiiShmem::Alloc(
80 this, byteSize
, mozilla::ipc::SharedMemory::SharedMemoryType::TYPE_BASIC
);
82 NS_WARNING("Failed to alloc shmem for RecvGetFrontBufferSnapshot.");
83 return IPC_FAIL(this, "Failed to allocate shmem for result");
86 const auto range
= shmem
.ByteRange();
87 auto retSize
= surfSize
;
88 if (!mHost
->FrontBufferSnapshotInto(range
)) {
89 retSize
= {0, 0}; // Zero means failure.
91 *ret
= {retSize
, shmem
.Extract()};
95 IPCResult
WebGLParent::RecvGetBufferSubData(const GLenum target
,
96 const uint64_t srcByteOffset
,
97 const uint64_t byteSize
,
99 const auto allocSize
= 1 + byteSize
;
100 auto shmem
= webgl::RaiiShmem::Alloc(
102 mozilla::ipc::SharedMemory::SharedMemoryType::TYPE_BASIC
);
104 NS_WARNING("Failed to alloc shmem for RecvGetBufferSubData.");
105 return IPC_FAIL(this, "Failed to allocate shmem for result");
108 const auto shmemRange
= shmem
.ByteRange();
109 const auto dataRange
=
110 Range
<uint8_t>{shmemRange
.begin() + 1, shmemRange
.end()};
112 // We need to always send the shmem:
113 // https://bugzilla.mozilla.org/show_bug.cgi?id=1463831#c2
114 const auto ok
= mHost
->GetBufferSubData(target
, srcByteOffset
, dataRange
);
115 *(shmemRange
.begin().get()) = ok
;
116 *ret
= shmem
.Extract();
120 IPCResult
WebGLParent::RecvReadPixels(const webgl::ReadPixelsDesc
& desc
,
121 const uint64_t byteSize
,
122 webgl::ReadPixelsResultIpc
* const ret
) {
125 const auto allocSize
= std::max
<uint64_t>(1, byteSize
);
126 auto shmem
= webgl::RaiiShmem::Alloc(
128 mozilla::ipc::SharedMemory::SharedMemoryType::TYPE_BASIC
);
130 NS_WARNING("Failed to alloc shmem for RecvReadPixels.");
131 return IPC_FAIL(this, "Failed to allocate shmem for result");
134 const auto range
= shmem
.ByteRange();
136 const auto res
= mHost
->ReadPixelsInto(desc
, range
);
137 *ret
= {res
, shmem
.Extract()};
143 IPCResult
WebGLParent::RecvCheckFramebufferStatus(GLenum target
,
145 *ret
= mHost
->CheckFramebufferStatus(target
);
149 IPCResult
WebGLParent::RecvClientWaitSync(ObjectId id
, GLbitfield flags
,
150 GLuint64 timeout
, GLenum
* const ret
) {
151 *ret
= mHost
->ClientWaitSync(id
, flags
, timeout
);
155 IPCResult
WebGLParent::RecvCreateOpaqueFramebuffer(
156 const ObjectId id
, const OpaqueFramebufferOptions
& options
,
158 *ret
= mHost
->CreateOpaqueFramebuffer(id
, options
);
162 IPCResult
WebGLParent::RecvDrawingBufferSize(uvec2
* const ret
) {
163 *ret
= mHost
->DrawingBufferSize();
167 IPCResult
WebGLParent::RecvFinish() {
172 IPCResult
WebGLParent::RecvGetBufferParameter(GLenum target
, GLenum pname
,
173 Maybe
<double>* const ret
) {
174 *ret
= mHost
->GetBufferParameter(target
, pname
);
178 IPCResult
WebGLParent::RecvGetCompileResult(ObjectId id
,
179 webgl::CompileResult
* const ret
) {
180 *ret
= mHost
->GetCompileResult(id
);
184 IPCResult
WebGLParent::RecvGetError(GLenum
* const ret
) {
185 *ret
= mHost
->GetError();
189 IPCResult
WebGLParent::RecvGetFragDataLocation(ObjectId id
,
190 const std::string
& name
,
192 *ret
= mHost
->GetFragDataLocation(id
, name
);
196 IPCResult
WebGLParent::RecvGetFramebufferAttachmentParameter(
197 ObjectId id
, GLenum attachment
, GLenum pname
, Maybe
<double>* const ret
) {
198 *ret
= mHost
->GetFramebufferAttachmentParameter(id
, attachment
, pname
);
202 IPCResult
WebGLParent::RecvGetFrontBuffer(
203 ObjectId fb
, const bool vr
, Maybe
<layers::SurfaceDescriptor
>* const ret
) {
204 *ret
= mHost
->GetFrontBuffer(fb
, vr
);
208 IPCResult
WebGLParent::RecvGetIndexedParameter(GLenum target
, GLuint index
,
209 Maybe
<double>* const ret
) {
210 *ret
= mHost
->GetIndexedParameter(target
, index
);
214 IPCResult
WebGLParent::RecvGetInternalformatParameter(
215 const GLenum target
, const GLuint format
, const GLuint pname
,
216 Maybe
<std::vector
<int32_t>>* const ret
) {
217 *ret
= mHost
->GetInternalformatParameter(target
, format
, pname
);
221 IPCResult
WebGLParent::RecvGetLinkResult(ObjectId id
,
222 webgl::LinkResult
* const ret
) {
223 *ret
= mHost
->GetLinkResult(id
);
227 IPCResult
WebGLParent::RecvGetNumber(GLenum pname
, Maybe
<double>* const ret
) {
228 *ret
= mHost
->GetNumber(pname
);
232 IPCResult
WebGLParent::RecvGetQueryParameter(ObjectId id
, GLenum pname
,
233 Maybe
<double>* const ret
) {
234 *ret
= mHost
->GetQueryParameter(id
, pname
);
238 IPCResult
WebGLParent::RecvGetRenderbufferParameter(ObjectId id
, GLenum pname
,
239 Maybe
<double>* const ret
) {
240 *ret
= mHost
->GetRenderbufferParameter(id
, pname
);
244 IPCResult
WebGLParent::RecvGetSamplerParameter(ObjectId id
, GLenum pname
,
245 Maybe
<double>* const ret
) {
246 *ret
= mHost
->GetSamplerParameter(id
, pname
);
250 IPCResult
WebGLParent::RecvGetShaderPrecisionFormat(
251 GLenum shaderType
, GLenum precisionType
,
252 Maybe
<webgl::ShaderPrecisionFormat
>* const ret
) {
253 *ret
= mHost
->GetShaderPrecisionFormat(shaderType
, precisionType
);
257 IPCResult
WebGLParent::RecvGetString(GLenum pname
,
258 Maybe
<std::string
>* const ret
) {
259 *ret
= mHost
->GetString(pname
);
263 IPCResult
WebGLParent::RecvGetTexParameter(ObjectId id
, GLenum pname
,
264 Maybe
<double>* const ret
) {
265 *ret
= mHost
->GetTexParameter(id
, pname
);
269 IPCResult
WebGLParent::RecvGetUniform(ObjectId id
, uint32_t loc
,
270 webgl::GetUniformData
* const ret
) {
271 *ret
= mHost
->GetUniform(id
, loc
);
275 IPCResult
WebGLParent::RecvGetVertexAttrib(GLuint index
, GLenum pname
,
276 Maybe
<double>* const ret
) {
277 *ret
= mHost
->GetVertexAttrib(index
, pname
);
281 IPCResult
WebGLParent::RecvIsEnabled(GLenum cap
, bool* const ret
) {
282 *ret
= mHost
->IsEnabled(cap
);
286 IPCResult
WebGLParent::RecvOnMemoryPressure() {
287 mHost
->OnMemoryPressure();
291 IPCResult
WebGLParent::RecvValidateProgram(ObjectId id
, bool* const ret
) {
292 *ret
= mHost
->ValidateProgram(id
);
296 } // namespace mozilla::dom