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/. */
9 #include "ipc/EnumSerializer.h"
10 #include "mozilla/ipc/IPDLParamTraits.h"
11 #include "mozilla/ipc/Shmem.h"
12 #include "mozilla/layers/LayersSurfaces.h"
13 #include "WebGLTypes.h"
18 // TODO: This should probably replace Shmem, or at least this should move to
21 class RaiiShmem final
{
22 RefPtr
<mozilla::ipc::ActorLifecycleProxy
> mWeakRef
;
23 mozilla::ipc::Shmem mShmem
= {};
26 /// Returns zeroed data.
27 static RaiiShmem
Alloc(
28 mozilla::ipc::IProtocol
* const allocator
, const size_t size
,
29 const mozilla::ipc::SharedMemory::SharedMemoryType type
) {
30 mozilla::ipc::Shmem shmem
;
31 if (!allocator
->AllocShmem(size
, type
, &shmem
)) return {};
32 return {allocator
, shmem
};
37 RaiiShmem() = default;
39 RaiiShmem(mozilla::ipc::IProtocol
* const allocator
,
40 const mozilla::ipc::Shmem
& shmem
) {
41 if (!allocator
|| !allocator
->CanSend()) {
45 // Shmems are handled by the top-level, so use that or we might leak after
47 mWeakRef
= allocator
->ToplevelProtocol()->GetLifecycleProxy();
49 if (!mWeakRef
|| !mWeakRef
->Get() || !IsShmem()) {
56 const auto& allocator
= mWeakRef
->Get();
58 allocator
->DeallocShmem(mShmem
);
65 ~RaiiShmem() { reset(); }
69 RaiiShmem(RaiiShmem
&& rhs
) { *this = std::move(rhs
); }
70 RaiiShmem
& operator=(RaiiShmem
&& rhs
) {
72 mWeakRef
= rhs
.mWeakRef
;
73 mShmem
= rhs
.Extract();
79 bool IsShmem() const { return mShmem
.IsReadable(); }
81 explicit operator bool() const { return IsShmem(); }
85 const auto& Shmem() const {
86 MOZ_ASSERT(IsShmem());
90 Range
<uint8_t> ByteRange() const {
94 return {mShmem
.get
<uint8_t>(), mShmem
.Size
<uint8_t>()};
97 mozilla::ipc::Shmem
Extract() {
105 using Int32Vector
= std::vector
<int32_t>;
112 struct IPDLParamTraits
<mozilla::webgl::FrontBufferSnapshotIpc
> final
{
113 using T
= mozilla::webgl::FrontBufferSnapshotIpc
;
115 static void Write(IPC::Message
* const msg
, IProtocol
* actor
, T
& in
) {
116 WriteParam(msg
, in
.surfSize
);
117 WriteIPDLParam(msg
, actor
, std::move(in
.shmem
));
120 static bool Read(const IPC::Message
* const msg
, PickleIterator
* const itr
,
121 IProtocol
* actor
, T
* const out
) {
122 return ReadParam(msg
, itr
, &out
->surfSize
) &&
123 ReadIPDLParam(msg
, itr
, actor
, &out
->shmem
);
130 struct IPDLParamTraits
<mozilla::webgl::ReadPixelsResultIpc
> final
{
131 using T
= mozilla::webgl::ReadPixelsResultIpc
;
133 static void Write(IPC::Message
* const msg
, IProtocol
* actor
, T
& in
) {
134 WriteParam(msg
, in
.subrect
);
135 WriteParam(msg
, in
.byteStride
);
136 WriteIPDLParam(msg
, actor
, std::move(in
.shmem
));
139 static bool Read(const IPC::Message
* const msg
, PickleIterator
* const itr
,
140 IProtocol
* actor
, T
* const out
) {
141 return ReadParam(msg
, itr
, &out
->subrect
) &&
142 ReadParam(msg
, itr
, &out
->byteStride
) &&
143 ReadIPDLParam(msg
, itr
, actor
, &out
->shmem
);
150 using Int32Vector
= std::vector
<int32_t>;
152 } // namespace mozilla
157 struct ParamTraits
<mozilla::webgl::ContextLossReason
>
158 : public ContiguousEnumSerializerInclusive
<
159 mozilla::webgl::ContextLossReason
,
160 mozilla::webgl::ContextLossReason::None
,
161 mozilla::webgl::ContextLossReason::Guilty
> {};
164 struct ParamTraits
<mozilla::webgl::AttribBaseType
>
165 : public ContiguousEnumSerializerInclusive
<
166 mozilla::webgl::AttribBaseType
,
167 mozilla::webgl::AttribBaseType::Boolean
,
168 mozilla::webgl::AttribBaseType::Uint
> {};
172 template <typename T
>
173 bool ValidateParam(const T
& val
) {
174 return ParamTraits
<T
>::Validate(val
);
177 template <typename T
>
178 struct ValidatedPlainOldDataSerializer
: public PlainOldDataSerializer
<T
> {
179 static void Write(Message
* const msg
, const T
& in
) {
180 MOZ_ASSERT(ValidateParam(in
));
181 PlainOldDataSerializer
<T
>::Write(msg
, in
);
184 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
186 if (!PlainOldDataSerializer
<T
>::Read(msg
, itr
, out
)) return false;
187 return ValidateParam(*out
);
190 // static bool Validate(const T&) = 0;
196 struct ParamTraits
<mozilla::webgl::InitContextDesc
> final
197 : public ValidatedPlainOldDataSerializer
<mozilla::webgl::InitContextDesc
> {
198 using T
= mozilla::webgl::InitContextDesc
;
200 static bool Validate(const T
& val
) {
201 return ValidateParam(val
.options
) && (val
.size
.x
&& val
.size
.y
);
206 struct ParamTraits
<mozilla::WebGLContextOptions
> final
207 : public ValidatedPlainOldDataSerializer
<mozilla::WebGLContextOptions
> {
208 using T
= mozilla::WebGLContextOptions
;
210 static bool Validate(const T
& val
) {
211 return ValidateParam(val
.powerPreference
);
216 struct ParamTraits
<mozilla::dom::WebGLPowerPreference
> final
217 : public ValidatedPlainOldDataSerializer
<
218 mozilla::dom::WebGLPowerPreference
> {
219 using T
= mozilla::dom::WebGLPowerPreference
;
221 static bool Validate(const T
& val
) { return val
<= T::High_performance
; }
225 struct ParamTraits
<mozilla::webgl::OpaqueFramebufferOptions
> final
226 : public PlainOldDataSerializer
<mozilla::webgl::OpaqueFramebufferOptions
> {
231 template <typename T
>
232 struct ParamTraits
<mozilla::webgl::EnumMask
<T
>> final
233 : public PlainOldDataSerializer
<mozilla::webgl::EnumMask
<T
>> {};
236 struct ParamTraits
<mozilla::webgl::InitContextResult
> final
{
237 using T
= mozilla::webgl::InitContextResult
;
239 static void Write(Message
* const msg
, const T
& in
) {
240 WriteParam(msg
, in
.error
);
241 WriteParam(msg
, in
.options
);
242 WriteParam(msg
, in
.limits
);
243 WriteParam(msg
, in
.uploadableSdTypes
);
246 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
248 return ReadParam(msg
, itr
, &out
->error
) &&
249 ReadParam(msg
, itr
, &out
->options
) &&
250 ReadParam(msg
, itr
, &out
->limits
) &&
251 ReadParam(msg
, itr
, &out
->uploadableSdTypes
);
256 struct ParamTraits
<mozilla::webgl::ExtensionBits
> final
257 : public PlainOldDataSerializer
<mozilla::webgl::ExtensionBits
> {};
260 struct ParamTraits
<mozilla::webgl::Limits
> final
261 : public PlainOldDataSerializer
<mozilla::webgl::Limits
> {};
266 struct ParamTraits
<mozilla::webgl::ReadPixelsDesc
> final
{
267 using T
= mozilla::webgl::ReadPixelsDesc
;
269 static void Write(Message
* const msg
, const T
& in
) {
270 WriteParam(msg
, in
.srcOffset
);
271 WriteParam(msg
, in
.size
);
272 WriteParam(msg
, in
.pi
);
273 WriteParam(msg
, in
.packState
);
276 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
278 return ReadParam(msg
, itr
, &out
->srcOffset
) &&
279 ReadParam(msg
, itr
, &out
->size
) && ReadParam(msg
, itr
, &out
->pi
) &&
280 ReadParam(msg
, itr
, &out
->packState
);
287 struct ParamTraits
<mozilla::webgl::PixelPackState
> final
{
288 using T
= mozilla::webgl::PixelPackState
;
290 static void Write(Message
* const msg
, const T
& in
) {
291 WriteParam(msg
, in
.alignment
);
292 WriteParam(msg
, in
.rowLength
);
293 WriteParam(msg
, in
.skipRows
);
294 WriteParam(msg
, in
.skipPixels
);
297 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
299 return ReadParam(msg
, itr
, &out
->alignment
) &&
300 ReadParam(msg
, itr
, &out
->rowLength
) &&
301 ReadParam(msg
, itr
, &out
->skipRows
) &&
302 ReadParam(msg
, itr
, &out
->skipPixels
);
309 struct ParamTraits
<mozilla::webgl::PackingInfo
> final
{
310 using T
= mozilla::webgl::PackingInfo
;
312 static void Write(Message
* const msg
, const T
& in
) {
313 WriteParam(msg
, in
.format
);
314 WriteParam(msg
, in
.type
);
317 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
319 return ReadParam(msg
, itr
, &out
->format
) && ReadParam(msg
, itr
, &out
->type
);
326 struct ParamTraits
<mozilla::webgl::CompileResult
> final
{
327 using T
= mozilla::webgl::CompileResult
;
329 static void Write(Message
* const msg
, const T
& in
) {
330 WriteParam(msg
, in
.pending
);
331 WriteParam(msg
, in
.log
);
332 WriteParam(msg
, in
.translatedSource
);
333 WriteParam(msg
, in
.success
);
336 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
338 return ReadParam(msg
, itr
, &out
->pending
) &&
339 ReadParam(msg
, itr
, &out
->log
) &&
340 ReadParam(msg
, itr
, &out
->translatedSource
) &&
341 ReadParam(msg
, itr
, &out
->success
);
348 struct ParamTraits
<mozilla::webgl::LinkResult
> final
{
349 using T
= mozilla::webgl::LinkResult
;
351 static void Write(Message
* const msg
, const T
& in
) {
352 WriteParam(msg
, in
.pending
);
353 WriteParam(msg
, in
.log
);
354 WriteParam(msg
, in
.success
);
355 WriteParam(msg
, in
.active
);
356 WriteParam(msg
, in
.tfBufferMode
);
359 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
361 return ReadParam(msg
, itr
, &out
->pending
) &&
362 ReadParam(msg
, itr
, &out
->log
) &&
363 ReadParam(msg
, itr
, &out
->success
) &&
364 ReadParam(msg
, itr
, &out
->active
) &&
365 ReadParam(msg
, itr
, &out
->tfBufferMode
);
372 struct ParamTraits
<mozilla::webgl::LinkActiveInfo
> final
{
373 using T
= mozilla::webgl::LinkActiveInfo
;
375 static void Write(Message
* const msg
, const T
& in
) {
376 WriteParam(msg
, in
.activeAttribs
);
377 WriteParam(msg
, in
.activeUniforms
);
378 WriteParam(msg
, in
.activeUniformBlocks
);
379 WriteParam(msg
, in
.activeTfVaryings
);
382 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
384 return ReadParam(msg
, itr
, &out
->activeAttribs
) &&
385 ReadParam(msg
, itr
, &out
->activeUniforms
) &&
386 ReadParam(msg
, itr
, &out
->activeUniformBlocks
) &&
387 ReadParam(msg
, itr
, &out
->activeTfVaryings
);
394 struct ParamTraits
<mozilla::webgl::ActiveInfo
> final
{
395 using T
= mozilla::webgl::ActiveInfo
;
397 static void Write(Message
* const msg
, const T
& in
) {
398 WriteParam(msg
, in
.elemType
);
399 WriteParam(msg
, in
.elemCount
);
400 WriteParam(msg
, in
.name
);
403 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
405 return ReadParam(msg
, itr
, &out
->elemType
) &&
406 ReadParam(msg
, itr
, &out
->elemCount
) &&
407 ReadParam(msg
, itr
, &out
->name
);
414 struct ParamTraits
<mozilla::webgl::ActiveAttribInfo
> final
{
415 using T
= mozilla::webgl::ActiveAttribInfo
;
417 static void Write(Message
* const msg
, const T
& in
) {
418 WriteParam(msg
, static_cast<const mozilla::webgl::ActiveInfo
&>(in
));
419 WriteParam(msg
, in
.location
);
420 WriteParam(msg
, in
.baseType
);
423 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
425 return ReadParam(msg
, itr
, static_cast<mozilla::webgl::ActiveInfo
*>(out
)) &&
426 ReadParam(msg
, itr
, &out
->location
) &&
427 ReadParam(msg
, itr
, &out
->baseType
);
434 struct ParamTraits
<mozilla::webgl::ActiveUniformInfo
> final
{
435 using T
= mozilla::webgl::ActiveUniformInfo
;
437 static void Write(Message
* const msg
, const T
& in
) {
438 WriteParam(msg
, static_cast<const mozilla::webgl::ActiveInfo
&>(in
));
439 WriteParam(msg
, in
.locByIndex
);
440 WriteParam(msg
, in
.block_index
);
441 WriteParam(msg
, in
.block_offset
);
442 WriteParam(msg
, in
.block_arrayStride
);
443 WriteParam(msg
, in
.block_matrixStride
);
444 WriteParam(msg
, in
.block_isRowMajor
);
447 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
449 return ReadParam(msg
, itr
, static_cast<mozilla::webgl::ActiveInfo
*>(out
)) &&
450 ReadParam(msg
, itr
, &out
->locByIndex
) &&
451 ReadParam(msg
, itr
, &out
->block_index
) &&
452 ReadParam(msg
, itr
, &out
->block_offset
) &&
453 ReadParam(msg
, itr
, &out
->block_arrayStride
) &&
454 ReadParam(msg
, itr
, &out
->block_matrixStride
) &&
455 ReadParam(msg
, itr
, &out
->block_isRowMajor
);
462 struct ParamTraits
<mozilla::webgl::ActiveUniformBlockInfo
> final
{
463 using T
= mozilla::webgl::ActiveUniformBlockInfo
;
465 static void Write(Message
* const msg
, const T
& in
) {
466 WriteParam(msg
, in
.name
);
467 WriteParam(msg
, in
.dataSize
);
468 WriteParam(msg
, in
.activeUniformIndices
);
469 WriteParam(msg
, in
.referencedByVertexShader
);
470 WriteParam(msg
, in
.referencedByFragmentShader
);
473 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
475 return ReadParam(msg
, itr
, &out
->name
) &&
476 ReadParam(msg
, itr
, &out
->dataSize
) &&
477 ReadParam(msg
, itr
, &out
->activeUniformIndices
) &&
478 ReadParam(msg
, itr
, &out
->referencedByVertexShader
) &&
479 ReadParam(msg
, itr
, &out
->referencedByFragmentShader
);
486 struct ParamTraits
<mozilla::webgl::ShaderPrecisionFormat
> final
{
487 using T
= mozilla::webgl::ShaderPrecisionFormat
;
489 static void Write(Message
* const msg
, const T
& in
) {
490 WriteParam(msg
, in
.rangeMin
);
491 WriteParam(msg
, in
.rangeMax
);
492 WriteParam(msg
, in
.precision
);
495 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
497 return ReadParam(msg
, itr
, &out
->rangeMin
) &&
498 ReadParam(msg
, itr
, &out
->rangeMax
) &&
499 ReadParam(msg
, itr
, &out
->precision
);
505 template <typename U
, size_t N
>
506 struct ParamTraits
<U
[N
]> final
{
508 static constexpr size_t kByteSize
= sizeof(U
) * N
;
510 static_assert(std::is_trivial
<U
>::value
);
512 static void Write(Message
* const msg
, const T
& in
) {
513 msg
->WriteBytes(in
, kByteSize
);
516 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
518 if (!msg
->HasBytesAvailable(itr
, kByteSize
)) {
521 return msg
->ReadBytesInto(itr
, *out
, kByteSize
);
528 struct ParamTraits
<mozilla::webgl::GetUniformData
> final
{
529 using T
= mozilla::webgl::GetUniformData
;
531 static void Write(Message
* const msg
, const T
& in
) {
532 ParamTraits
<decltype(in
.data
)>::Write(msg
, in
.data
);
533 WriteParam(msg
, in
.type
);
536 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
538 return ParamTraits
<decltype(out
->data
)>::Read(msg
, itr
, &out
->data
) &&
539 ReadParam(msg
, itr
, &out
->type
);
545 template <typename U
>
546 struct ParamTraits
<mozilla::avec2
<U
>> final
{
547 using T
= mozilla::avec2
<U
>;
549 static void Write(Message
* const msg
, const T
& in
) {
550 WriteParam(msg
, in
.x
);
551 WriteParam(msg
, in
.y
);
554 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
556 return ReadParam(msg
, itr
, &out
->x
) && ReadParam(msg
, itr
, &out
->y
);
562 template <typename U
>
563 struct ParamTraits
<mozilla::avec3
<U
>> final
{
564 using T
= mozilla::avec3
<U
>;
566 static void Write(Message
* const msg
, const T
& in
) {
567 WriteParam(msg
, in
.x
);
568 WriteParam(msg
, in
.y
);
569 WriteParam(msg
, in
.z
);
572 static bool Read(const Message
* const msg
, PickleIterator
* const itr
,
574 return ReadParam(msg
, itr
, &out
->x
) && ReadParam(msg
, itr
, &out
->y
) &&
575 ReadParam(msg
, itr
, &out
->z
);