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/dom/WebGLCrossProcessCommandQueue.h"
10 #include "mozilla/layers/LayerTransactionParent.h"
11 #include "mozilla/layers/TextureClientSharedSurface.h"
12 #include "ImageContainer.h"
13 #include "HostWebGLContext.h"
14 #include "WebGLMethodDispatcher.h"
16 namespace mozilla::dom
{
18 mozilla::ipc::IPCResult
WebGLParent::RecvInitialize(
19 const webgl::InitContextDesc
& desc
,
20 UniquePtr
<HostWebGLCommandSinkP
>&& aSinkP
,
21 UniquePtr
<HostWebGLCommandSinkI
>&& aSinkI
,
22 webgl::InitContextResult
* const out
) {
23 auto remotingData
= Some(HostWebGLContext::RemotingData
{
24 *this, {}, // std::move(commandSink),
27 mHost
= HostWebGLContext::Create(
30 std::move(remotingData
),
34 if (!mHost
&& !out
->error
.size()) {
35 return IPC_FAIL(this, "Abnormally failed to create HostWebGLContext.");
41 WebGLParent::WebGLParent() = default;
42 WebGLParent::~WebGLParent() = default;
46 using IPCResult
= mozilla::ipc::IPCResult
;
48 IPCResult
WebGLParent::RecvDispatchCommands(Shmem
&& rawShmem
,
49 const uint64_t cmdsByteSize
) {
50 auto shmem
= webgl::RaiiShmem(this, std::move(rawShmem
));
52 const auto& gl
= mHost
->mContext
->GL();
53 const gl::GLContext::TlsScope
tlsIsCurrent(gl
);
55 MOZ_ASSERT(cmdsByteSize
);
56 const auto shmemBytes
= shmem
.ByteRange();
57 const auto byteSize
= std::min
<uint64_t>(shmemBytes
.length(), cmdsByteSize
);
58 const auto cmdsBytes
=
59 Range
<const uint8_t>{shmemBytes
.begin(), shmemBytes
.begin() + byteSize
};
60 auto view
= webgl::RangeConsumerView
{cmdsBytes
};
63 view
.AlignTo(kUniversalAlignment
);
65 const auto status
= view
.ReadParam(&id
);
66 if (status
!= QueueStatus::kSuccess
) break;
68 WebGLMethodDispatcher
<0>::DispatchCommand(*mHost
, id
, view
);
76 mozilla::ipc::IPCResult
WebGLParent::Recv__delete__() {
81 void WebGLParent::ActorDestroy(ActorDestroyReason aWhy
) { mHost
= nullptr; }
85 IPCResult
WebGLParent::RecvGetFrontBufferSnapshot(
86 webgl::FrontBufferSnapshotIpc
* const ret
) {
89 const auto surfSize
= mHost
->GetFrontBufferSize();
90 const auto byteSize
= 4 * surfSize
.x
* surfSize
.y
;
92 auto shmem
= webgl::RaiiShmem::Alloc(
93 this, byteSize
, mozilla::ipc::SharedMemory::SharedMemoryType::TYPE_BASIC
);
95 NS_WARNING("Failed to alloc shmem for RecvGetFrontBufferSnapshot.");
96 return IPC_FAIL(this, "Failed to allocate shmem for result");
99 const auto range
= shmem
.ByteRange();
100 auto retSize
= surfSize
;
101 if (!mHost
->FrontBufferSnapshotInto(range
)) {
102 retSize
= {0, 0}; // Zero means failure.
104 *ret
= {retSize
, shmem
.Extract()};
108 IPCResult
WebGLParent::RecvGetBufferSubData(const GLenum target
,
109 const uint64_t srcByteOffset
,
110 const uint64_t byteSize
,
112 const auto allocSize
= 1 + byteSize
;
113 auto shmem
= webgl::RaiiShmem::Alloc(
115 mozilla::ipc::SharedMemory::SharedMemoryType::TYPE_BASIC
);
117 NS_WARNING("Failed to alloc shmem for RecvGetBufferSubData.");
118 return IPC_FAIL(this, "Failed to allocate shmem for result");
121 const auto shmemRange
= shmem
.ByteRange();
122 const auto dataRange
=
123 Range
<uint8_t>{shmemRange
.begin() + 1, shmemRange
.end()};
125 // We need to always send the shmem:
126 // https://bugzilla.mozilla.org/show_bug.cgi?id=1463831#c2
127 const auto ok
= mHost
->GetBufferSubData(target
, srcByteOffset
, dataRange
);
128 *(shmemRange
.begin().get()) = ok
;
129 *ret
= shmem
.Extract();
133 IPCResult
WebGLParent::RecvReadPixels(const webgl::ReadPixelsDesc
& desc
,
134 const uint64_t byteSize
,
135 webgl::ReadPixelsResultIpc
* const ret
) {
138 const auto allocSize
= std::max
<uint64_t>(1, byteSize
);
139 auto shmem
= webgl::RaiiShmem::Alloc(
141 mozilla::ipc::SharedMemory::SharedMemoryType::TYPE_BASIC
);
143 NS_WARNING("Failed to alloc shmem for RecvReadPixels.");
144 return IPC_FAIL(this, "Failed to allocate shmem for result");
147 const auto range
= shmem
.ByteRange();
149 const auto res
= mHost
->ReadPixelsInto(desc
, range
);
150 *ret
= {res
, shmem
.Extract()};
156 IPCResult
WebGLParent::RecvCheckFramebufferStatus(GLenum target
,
158 *ret
= mHost
->CheckFramebufferStatus(target
);
162 IPCResult
WebGLParent::RecvClientWaitSync(ObjectId id
, GLbitfield flags
,
163 GLuint64 timeout
, GLenum
* const ret
) {
164 *ret
= mHost
->ClientWaitSync(id
, flags
, timeout
);
168 IPCResult
WebGLParent::RecvCreateOpaqueFramebuffer(
169 const ObjectId id
, const OpaqueFramebufferOptions
& options
,
171 *ret
= mHost
->CreateOpaqueFramebuffer(id
, options
);
175 IPCResult
WebGLParent::RecvDrawingBufferSize(uvec2
* const ret
) {
176 *ret
= mHost
->DrawingBufferSize();
180 IPCResult
WebGLParent::RecvFinish() {
185 IPCResult
WebGLParent::RecvGetBufferParameter(GLenum target
, GLenum pname
,
186 Maybe
<double>* const ret
) {
187 *ret
= mHost
->GetBufferParameter(target
, pname
);
191 IPCResult
WebGLParent::RecvGetCompileResult(ObjectId id
,
192 webgl::CompileResult
* const ret
) {
193 *ret
= mHost
->GetCompileResult(id
);
197 IPCResult
WebGLParent::RecvGetError(GLenum
* const ret
) {
198 *ret
= mHost
->GetError();
202 IPCResult
WebGLParent::RecvGetFragDataLocation(ObjectId id
,
203 const std::string
& name
,
205 *ret
= mHost
->GetFragDataLocation(id
, name
);
209 IPCResult
WebGLParent::RecvGetFramebufferAttachmentParameter(
210 ObjectId id
, GLenum attachment
, GLenum pname
, Maybe
<double>* const ret
) {
211 *ret
= mHost
->GetFramebufferAttachmentParameter(id
, attachment
, pname
);
215 IPCResult
WebGLParent::RecvGetFrontBuffer(
216 ObjectId fb
, const bool vr
, Maybe
<layers::SurfaceDescriptor
>* const ret
) {
217 *ret
= mHost
->GetFrontBuffer(fb
, vr
);
221 IPCResult
WebGLParent::RecvGetIndexedParameter(GLenum target
, GLuint index
,
222 Maybe
<double>* const ret
) {
223 *ret
= mHost
->GetIndexedParameter(target
, index
);
227 IPCResult
WebGLParent::RecvGetInternalformatParameter(
228 const GLenum target
, const GLuint format
, const GLuint pname
,
229 Maybe
<std::vector
<int32_t>>* const ret
) {
230 *ret
= mHost
->GetInternalformatParameter(target
, format
, pname
);
234 IPCResult
WebGLParent::RecvGetLinkResult(ObjectId id
,
235 webgl::LinkResult
* const ret
) {
236 *ret
= mHost
->GetLinkResult(id
);
240 IPCResult
WebGLParent::RecvGetNumber(GLenum pname
, Maybe
<double>* const ret
) {
241 *ret
= mHost
->GetNumber(pname
);
245 IPCResult
WebGLParent::RecvGetQueryParameter(ObjectId id
, GLenum pname
,
246 Maybe
<double>* const ret
) {
247 *ret
= mHost
->GetQueryParameter(id
, pname
);
251 IPCResult
WebGLParent::RecvGetRenderbufferParameter(ObjectId id
, GLenum pname
,
252 Maybe
<double>* const ret
) {
253 *ret
= mHost
->GetRenderbufferParameter(id
, pname
);
257 IPCResult
WebGLParent::RecvGetSamplerParameter(ObjectId id
, GLenum pname
,
258 Maybe
<double>* const ret
) {
259 *ret
= mHost
->GetSamplerParameter(id
, pname
);
263 IPCResult
WebGLParent::RecvGetShaderPrecisionFormat(
264 GLenum shaderType
, GLenum precisionType
,
265 Maybe
<webgl::ShaderPrecisionFormat
>* const ret
) {
266 *ret
= mHost
->GetShaderPrecisionFormat(shaderType
, precisionType
);
270 IPCResult
WebGLParent::RecvGetString(GLenum pname
,
271 Maybe
<std::string
>* const ret
) {
272 *ret
= mHost
->GetString(pname
);
276 IPCResult
WebGLParent::RecvGetTexParameter(ObjectId id
, GLenum pname
,
277 Maybe
<double>* const ret
) {
278 *ret
= mHost
->GetTexParameter(id
, pname
);
282 IPCResult
WebGLParent::RecvGetUniform(ObjectId id
, uint32_t loc
,
283 webgl::GetUniformData
* const ret
) {
284 *ret
= mHost
->GetUniform(id
, loc
);
288 IPCResult
WebGLParent::RecvGetVertexAttrib(GLuint index
, GLenum pname
,
289 Maybe
<double>* const ret
) {
290 *ret
= mHost
->GetVertexAttrib(index
, pname
);
294 IPCResult
WebGLParent::RecvIsEnabled(GLenum cap
, bool* const ret
) {
295 *ret
= mHost
->IsEnabled(cap
);
299 IPCResult
WebGLParent::RecvOnMemoryPressure() {
300 mHost
->OnMemoryPressure();
304 IPCResult
WebGLParent::RecvValidateProgram(ObjectId id
, bool* const ret
) {
305 *ret
= mHost
->ValidateProgram(id
);
309 } // namespace mozilla::dom