1 /* -*- Mode: C++; tab-width: 4; 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/. */
10 #include "ipc/EnumSerializer.h"
11 #include "ipc/IPCMessageUtils.h"
12 #include "mozilla/GfxMessageUtils.h"
13 #include "mozilla/dom/BindingIPCUtils.h"
14 #include "mozilla/ipc/IPDLParamTraits.h"
15 #include "mozilla/ipc/Shmem.h"
16 #include "mozilla/layers/LayersSurfaces.h"
17 #include "mozilla/ParamTraits_IsEnumCase.h"
18 #include "mozilla/ParamTraits_STL.h"
19 #include "mozilla/ParamTraits_TiedFields.h"
20 #include "WebGLTypes.h"
25 // TODO: This should probably replace Shmem, or at least this should move to
28 class RaiiShmem final
{
29 RefPtr
<mozilla::ipc::ActorLifecycleProxy
> mWeakRef
;
30 mozilla::ipc::Shmem mShmem
= {};
33 /// Returns zeroed data.
34 static RaiiShmem
Alloc(mozilla::ipc::IProtocol
* const allocator
,
36 mozilla::ipc::Shmem shmem
;
37 if (!allocator
->AllocShmem(size
, &shmem
)) return {};
38 return {allocator
, shmem
};
41 static RaiiShmem
AllocUnsafe(mozilla::ipc::IProtocol
* const allocator
,
43 mozilla::ipc::Shmem shmem
;
44 if (!allocator
->AllocUnsafeShmem(size
, &shmem
)) return {};
45 return {allocator
, shmem
};
50 RaiiShmem() = default;
52 RaiiShmem(mozilla::ipc::IProtocol
* const allocator
,
53 const mozilla::ipc::Shmem
& shmem
) {
54 if (!allocator
|| !allocator
->CanSend()) {
58 // Shmems are handled by the top-level, so use that or we might leak after
60 mWeakRef
= allocator
->ToplevelProtocol()->GetLifecycleProxy();
62 if (!mWeakRef
|| !mWeakRef
->Get() || !IsShmem()) {
69 const auto& allocator
= mWeakRef
->Get();
71 allocator
->DeallocShmem(mShmem
);
78 ~RaiiShmem() { reset(); }
82 RaiiShmem(RaiiShmem
&& rhs
) { *this = std::move(rhs
); }
83 RaiiShmem
& operator=(RaiiShmem
&& rhs
) {
85 mWeakRef
= rhs
.mWeakRef
;
86 mShmem
= rhs
.Extract();
92 bool IsShmem() const { return mShmem
.IsReadable(); }
94 explicit operator bool() const { return IsShmem(); }
98 const auto& Shmem() const {
99 MOZ_ASSERT(IsShmem());
103 Range
<uint8_t> ByteRange() const {
107 return {mShmem
.get
<uint8_t>(), mShmem
.Size
<uint8_t>()};
110 mozilla::ipc::Shmem
Extract() {
118 using Int32Vector
= std::vector
<int32_t>;
125 struct IPDLParamTraits
<mozilla::webgl::FrontBufferSnapshotIpc
> final
{
126 using T
= mozilla::webgl::FrontBufferSnapshotIpc
;
128 static void Write(IPC::MessageWriter
* const writer
, IProtocol
* actor
, T
& in
) {
129 WriteParam(writer
, in
.surfSize
);
130 WriteIPDLParam(writer
, actor
, std::move(in
.shmem
));
133 static bool Read(IPC::MessageReader
* const reader
, IProtocol
* actor
,
135 return ReadParam(reader
, &out
->surfSize
) &&
136 ReadIPDLParam(reader
, actor
, &out
->shmem
);
143 struct IPDLParamTraits
<mozilla::webgl::ReadPixelsResultIpc
> final
{
144 using T
= mozilla::webgl::ReadPixelsResultIpc
;
146 static void Write(IPC::MessageWriter
* const writer
, IProtocol
* actor
, T
& in
) {
147 WriteParam(writer
, in
.subrect
);
148 WriteParam(writer
, in
.byteStride
);
149 WriteIPDLParam(writer
, actor
, std::move(in
.shmem
));
152 static bool Read(IPC::MessageReader
* const reader
, IProtocol
* actor
,
154 return ReadParam(reader
, &out
->subrect
) &&
155 ReadParam(reader
, &out
->byteStride
) &&
156 ReadIPDLParam(reader
, actor
, &out
->shmem
);
163 struct IPDLParamTraits
<mozilla::webgl::TexUnpackBlobDesc
> final
{
164 using T
= mozilla::webgl::TexUnpackBlobDesc
;
166 static void Write(IPC::MessageWriter
* const writer
, IProtocol
* actor
,
168 WriteParam(writer
, in
.imageTarget
);
169 WriteParam(writer
, in
.size
);
170 WriteParam(writer
, in
.srcAlphaType
);
171 MOZ_RELEASE_ASSERT(!in
.cpuData
);
172 MOZ_RELEASE_ASSERT(!in
.pboOffset
);
173 WriteParam(writer
, in
.structuredSrcSize
);
174 MOZ_RELEASE_ASSERT(!in
.image
);
175 WriteIPDLParam(writer
, actor
, std::move(in
.sd
));
176 MOZ_RELEASE_ASSERT(!in
.dataSurf
);
177 WriteParam(writer
, in
.unpacking
);
178 WriteParam(writer
, in
.applyUnpackTransforms
);
181 static bool Read(IPC::MessageReader
* const reader
, IProtocol
* actor
,
183 return ReadParam(reader
, &out
->imageTarget
) &&
184 ReadParam(reader
, &out
->size
) &&
185 ReadParam(reader
, &out
->srcAlphaType
) &&
186 ReadParam(reader
, &out
->structuredSrcSize
) &&
187 ReadIPDLParam(reader
, actor
, &out
->sd
) &&
188 ReadParam(reader
, &out
->unpacking
) &&
189 ReadParam(reader
, &out
->applyUnpackTransforms
);
196 using Int32Vector
= std::vector
<int32_t>;
198 } // namespace mozilla
204 template <class U
, size_t PaddedSize
>
205 struct ParamTraits
<mozilla::webgl::Padded
<U
, PaddedSize
>> final
{
206 using T
= mozilla::webgl::Padded
<U
, PaddedSize
>;
208 static void Write(MessageWriter
* const writer
, const T
& in
) {
209 WriteParam(writer
, *in
);
212 static bool Read(MessageReader
* const reader
, T
* const out
) {
213 return ReadParam(reader
, &**out
);
220 struct ParamTraits
<mozilla::webgl::AttribBaseType
>
221 : public ContiguousEnumSerializerInclusive
<
222 mozilla::webgl::AttribBaseType
,
223 mozilla::webgl::AttribBaseType::Boolean
,
224 mozilla::webgl::AttribBaseType::Uint
> {};
227 struct ParamTraits
<mozilla::webgl::ContextLossReason
>
228 : public ContiguousEnumSerializerInclusive
<
229 mozilla::webgl::ContextLossReason
,
230 mozilla::webgl::ContextLossReason::None
,
231 mozilla::webgl::ContextLossReason::Guilty
> {};
234 struct ParamTraits
<gfxAlphaType
>
235 : public ContiguousEnumSerializerInclusive
<
236 gfxAlphaType
, gfxAlphaType::Opaque
, gfxAlphaType::NonPremult
> {};
239 struct ParamTraits
<mozilla::dom::WebGLPowerPreference
> final
240 : public mozilla::dom::WebIDLEnumSerializer
<
241 mozilla::dom::WebGLPowerPreference
> {};
244 struct ParamTraits
<mozilla::dom::PredefinedColorSpace
> final
245 : public mozilla::dom::WebIDLEnumSerializer
<
246 mozilla::dom::PredefinedColorSpace
> {};
249 // ParamTraits_IsEnumCase
251 #define USE_IS_ENUM_CASE(T) \
253 struct ParamTraits<T> : public ParamTraits_IsEnumCase<T> {};
255 USE_IS_ENUM_CASE(mozilla::webgl::OptionalRenderableFormatBits
)
257 #undef USE_IS_ENUM_CASE
260 // ParamTraits_TiedFields
263 struct ParamTraits
<mozilla::webgl::InitContextDesc
> final
264 : public ParamTraits_TiedFields
<mozilla::webgl::InitContextDesc
> {};
267 struct ParamTraits
<mozilla::WebGLContextOptions
> final
268 : public ParamTraits_TiedFields
<mozilla::WebGLContextOptions
> {};
271 struct ParamTraits
<mozilla::webgl::OpaqueFramebufferOptions
> final
272 : public ParamTraits_TiedFields
<mozilla::webgl::OpaqueFramebufferOptions
> {
278 struct ParamTraits
<mozilla::gl::GLVendor
>
279 : public ContiguousEnumSerializerInclusive
<mozilla::gl::GLVendor
,
280 mozilla::gl::GLVendor::Intel
,
281 mozilla::gl::kHighestGLVendor
> {
284 template <typename U
>
285 struct ParamTraits
<mozilla::webgl::EnumMask
<U
>> final
286 : public ParamTraits_TiedFields
<mozilla::webgl::EnumMask
<U
>> {};
289 struct ParamTraits
<mozilla::webgl::InitContextResult
> final
290 : public ParamTraits_TiedFields
<mozilla::webgl::InitContextResult
> {};
293 struct ParamTraits
<mozilla::webgl::Limits
> final
294 : public ParamTraits_TiedFields
<mozilla::webgl::Limits
> {};
297 struct ParamTraits
<mozilla::webgl::PixelPackingState
> final
298 : public ParamTraits_TiedFields
<mozilla::webgl::PixelPackingState
> {};
300 struct ParamTraits
<mozilla::webgl::PixelUnpackStateWebgl
> final
301 : public ParamTraits_TiedFields
<mozilla::webgl::PixelUnpackStateWebgl
> {};
306 struct ParamTraits
<mozilla::webgl::ReadPixelsDesc
> final
{
307 using T
= mozilla::webgl::ReadPixelsDesc
;
309 static void Write(MessageWriter
* const writer
, const T
& in
) {
310 WriteParam(writer
, in
.srcOffset
);
311 WriteParam(writer
, in
.size
);
312 WriteParam(writer
, in
.pi
);
313 WriteParam(writer
, in
.packState
);
316 static bool Read(MessageReader
* const reader
, T
* const out
) {
317 return ReadParam(reader
, &out
->srcOffset
) &&
318 ReadParam(reader
, &out
->size
) && ReadParam(reader
, &out
->pi
) &&
319 ReadParam(reader
, &out
->packState
);
326 struct ParamTraits
<mozilla::webgl::PackingInfo
> final
{
327 using T
= mozilla::webgl::PackingInfo
;
329 static void Write(MessageWriter
* const writer
, const T
& in
) {
330 WriteParam(writer
, in
.format
);
331 WriteParam(writer
, in
.type
);
334 static bool Read(MessageReader
* const reader
, T
* const out
) {
335 return ReadParam(reader
, &out
->format
) && ReadParam(reader
, &out
->type
);
342 struct ParamTraits
<mozilla::webgl::CompileResult
> final
{
343 using T
= mozilla::webgl::CompileResult
;
345 static void Write(MessageWriter
* const writer
, const T
& in
) {
346 WriteParam(writer
, in
.pending
);
347 WriteParam(writer
, in
.log
);
348 WriteParam(writer
, in
.translatedSource
);
349 WriteParam(writer
, in
.success
);
352 static bool Read(MessageReader
* const reader
, T
* const out
) {
353 return ReadParam(reader
, &out
->pending
) && ReadParam(reader
, &out
->log
) &&
354 ReadParam(reader
, &out
->translatedSource
) &&
355 ReadParam(reader
, &out
->success
);
362 struct ParamTraits
<mozilla::webgl::LinkResult
> final
{
363 using T
= mozilla::webgl::LinkResult
;
365 static void Write(MessageWriter
* const writer
, const T
& in
) {
366 WriteParam(writer
, in
.pending
);
367 WriteParam(writer
, in
.log
);
368 WriteParam(writer
, in
.success
);
369 WriteParam(writer
, in
.active
);
370 WriteParam(writer
, in
.tfBufferMode
);
373 static bool Read(MessageReader
* const reader
, T
* const out
) {
374 return ReadParam(reader
, &out
->pending
) && ReadParam(reader
, &out
->log
) &&
375 ReadParam(reader
, &out
->success
) &&
376 ReadParam(reader
, &out
->active
) &&
377 ReadParam(reader
, &out
->tfBufferMode
);
384 struct ParamTraits
<mozilla::webgl::LinkActiveInfo
> final
{
385 using T
= mozilla::webgl::LinkActiveInfo
;
387 static void Write(MessageWriter
* const writer
, const T
& in
) {
388 WriteParam(writer
, in
.activeAttribs
);
389 WriteParam(writer
, in
.activeUniforms
);
390 WriteParam(writer
, in
.activeUniformBlocks
);
391 WriteParam(writer
, in
.activeTfVaryings
);
394 static bool Read(MessageReader
* const reader
, T
* const out
) {
395 return ReadParam(reader
, &out
->activeAttribs
) &&
396 ReadParam(reader
, &out
->activeUniforms
) &&
397 ReadParam(reader
, &out
->activeUniformBlocks
) &&
398 ReadParam(reader
, &out
->activeTfVaryings
);
405 struct ParamTraits
<mozilla::webgl::ActiveInfo
> final
{
406 using T
= mozilla::webgl::ActiveInfo
;
408 static void Write(MessageWriter
* const writer
, const T
& in
) {
409 WriteParam(writer
, in
.elemType
);
410 WriteParam(writer
, in
.elemCount
);
411 WriteParam(writer
, in
.name
);
414 static bool Read(MessageReader
* const reader
, T
* const out
) {
415 return ReadParam(reader
, &out
->elemType
) &&
416 ReadParam(reader
, &out
->elemCount
) && ReadParam(reader
, &out
->name
);
423 struct ParamTraits
<mozilla::webgl::ActiveAttribInfo
> final
{
424 using T
= mozilla::webgl::ActiveAttribInfo
;
426 static void Write(MessageWriter
* const writer
, const T
& in
) {
427 WriteParam(writer
, static_cast<const mozilla::webgl::ActiveInfo
&>(in
));
428 WriteParam(writer
, in
.location
);
429 WriteParam(writer
, in
.baseType
);
432 static bool Read(MessageReader
* const reader
, T
* const out
) {
433 return ReadParam(reader
, static_cast<mozilla::webgl::ActiveInfo
*>(out
)) &&
434 ReadParam(reader
, &out
->location
) &&
435 ReadParam(reader
, &out
->baseType
);
442 struct ParamTraits
<mozilla::webgl::ActiveUniformInfo
> final
{
443 using T
= mozilla::webgl::ActiveUniformInfo
;
445 static void Write(MessageWriter
* const writer
, const T
& in
) {
446 WriteParam(writer
, static_cast<const mozilla::webgl::ActiveInfo
&>(in
));
447 WriteParam(writer
, in
.locByIndex
);
448 WriteParam(writer
, in
.block_index
);
449 WriteParam(writer
, in
.block_offset
);
450 WriteParam(writer
, in
.block_arrayStride
);
451 WriteParam(writer
, in
.block_matrixStride
);
452 WriteParam(writer
, in
.block_isRowMajor
);
455 static bool Read(MessageReader
* const reader
, T
* const out
) {
456 return ReadParam(reader
, static_cast<mozilla::webgl::ActiveInfo
*>(out
)) &&
457 ReadParam(reader
, &out
->locByIndex
) &&
458 ReadParam(reader
, &out
->block_index
) &&
459 ReadParam(reader
, &out
->block_offset
) &&
460 ReadParam(reader
, &out
->block_arrayStride
) &&
461 ReadParam(reader
, &out
->block_matrixStride
) &&
462 ReadParam(reader
, &out
->block_isRowMajor
);
469 struct ParamTraits
<mozilla::webgl::ActiveUniformBlockInfo
> final
{
470 using T
= mozilla::webgl::ActiveUniformBlockInfo
;
472 static void Write(MessageWriter
* const writer
, const T
& in
) {
473 WriteParam(writer
, in
.name
);
474 WriteParam(writer
, in
.dataSize
);
475 WriteParam(writer
, in
.activeUniformIndices
);
476 WriteParam(writer
, in
.referencedByVertexShader
);
477 WriteParam(writer
, in
.referencedByFragmentShader
);
480 static bool Read(MessageReader
* const reader
, T
* const out
) {
481 return ReadParam(reader
, &out
->name
) && ReadParam(reader
, &out
->dataSize
) &&
482 ReadParam(reader
, &out
->activeUniformIndices
) &&
483 ReadParam(reader
, &out
->referencedByVertexShader
) &&
484 ReadParam(reader
, &out
->referencedByFragmentShader
);
491 struct ParamTraits
<mozilla::webgl::ShaderPrecisionFormat
> final
{
492 using T
= mozilla::webgl::ShaderPrecisionFormat
;
494 static void Write(MessageWriter
* const writer
, const T
& in
) {
495 WriteParam(writer
, in
.rangeMin
);
496 WriteParam(writer
, in
.rangeMax
);
497 WriteParam(writer
, in
.precision
);
500 static bool Read(MessageReader
* const reader
, T
* const out
) {
501 return ReadParam(reader
, &out
->rangeMin
) &&
502 ReadParam(reader
, &out
->rangeMax
) &&
503 ReadParam(reader
, &out
->precision
);
510 struct ParamTraits
<mozilla::webgl::GetUniformData
> final
{
511 using T
= mozilla::webgl::GetUniformData
;
513 static void Write(MessageWriter
* const writer
, const T
& in
) {
514 ParamTraits
<decltype(in
.data
)>::Write(writer
, in
.data
);
515 WriteParam(writer
, in
.type
);
518 static bool Read(MessageReader
* const reader
, T
* const out
) {
519 return ParamTraits
<decltype(out
->data
)>::Read(reader
, &out
->data
) &&
520 ReadParam(reader
, &out
->type
);
526 template <typename U
>
527 struct ParamTraits
<mozilla::avec2
<U
>> final
{
528 using T
= mozilla::avec2
<U
>;
530 static void Write(MessageWriter
* const writer
, const T
& in
) {
531 WriteParam(writer
, in
.x
);
532 WriteParam(writer
, in
.y
);
535 static bool Read(MessageReader
* const reader
, T
* const out
) {
536 return ReadParam(reader
, &out
->x
) && ReadParam(reader
, &out
->y
);
542 template <typename U
>
543 struct ParamTraits
<mozilla::avec3
<U
>> final
{
544 using T
= mozilla::avec3
<U
>;
546 static void Write(MessageWriter
* const writer
, const T
& in
) {
547 WriteParam(writer
, in
.x
);
548 WriteParam(writer
, in
.y
);
549 WriteParam(writer
, in
.z
);
552 static bool Read(MessageReader
* const reader
, T
* const out
) {
553 return ReadParam(reader
, &out
->x
) && ReadParam(reader
, &out
->y
) &&
554 ReadParam(reader
, &out
->z
);