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/. */
6 #ifndef HOSTWEBGLCONTEXT_H_
7 #define HOSTWEBGLCONTEXT_H_
9 #include "mozilla/dom/BindingUtils.h"
10 #include "mozilla/GfxMessageUtils.h"
11 #include "ClientWebGLContext.h"
12 #include "mozilla/Maybe.h"
13 #include "mozilla/UniquePtr.h"
14 #include "GLContext.h"
15 #include "WebGLContext.h"
16 #include "WebGL2Context.h"
17 #include "WebGLFramebuffer.h"
18 #include "WebGLTypes.h"
19 #include "WebGLCommandQueue.h"
21 #include <unordered_map>
22 #include <unordered_set>
31 class CompositableHost
;
34 struct LockedOutstandingContexts final
{
36 // StaticMutexAutoLock lock; // We can't use it directly (STACK_CLASS), but
37 // this is effectively what we hold via RAII.
40 const std::unordered_set
<HostWebGLContext
*>& contexts
;
42 LockedOutstandingContexts();
43 ~LockedOutstandingContexts();
47 * Host endpoint of a WebGLContext. HostWebGLContext owns a WebGLContext
48 * that it uses to execute commands sent from its ClientWebGLContext.
50 * A HostWebGLContext continuously issues a Task to the Compositor thread that
51 * causes it to drain its queue of commands. It also maintains a map of WebGL
52 * objects (e.g. ObjectIdMap<WebGLShader>) that it uses associate them with
53 * their cross-process IDs.
55 * This class is not an implementation of the
56 * nsICanvasRenderingContextInternal DOM class. That is the
59 class HostWebGLContext final
: public SupportsWeakPtr
{
60 friend class WebGLContext
;
61 friend class WebGLMemoryTracker
;
62 friend class dom::WebGLParent
;
64 using ObjectId
= webgl::ObjectId
;
66 static std::unique_ptr
<LockedOutstandingContexts
> OutstandingContexts() {
67 return std::make_unique
<LockedOutstandingContexts
>();
71 struct OwnerData final
{
72 ClientWebGLContext
* inProcess
= nullptr;
73 dom::WebGLParent
* outOfProcess
= nullptr;
76 static UniquePtr
<HostWebGLContext
> Create(const OwnerData
&,
77 const webgl::InitContextDesc
&,
78 webgl::InitContextResult
* out
);
81 explicit HostWebGLContext(const OwnerData
&);
84 virtual ~HostWebGLContext();
86 WebGLContext
* GetWebGLContext() const { return mContext
; }
89 const OwnerData mOwnerData
;
92 RefPtr
<WebGLContext
> mContext
;
94 #define _(X) std::unordered_map<ObjectId, RefPtr<WebGL##X>> m##X##Map;
110 class AutoResolveT final
{
111 friend class HostWebGLContext
;
113 const HostWebGLContext
& mParent
;
117 AutoResolveT(const HostWebGLContext
& parent
, const ObjectId id
)
118 : mParent(parent
), mId(id
) {}
121 WebGL##X* As(WebGL##X*) const { \
122 const auto maybe = MaybeFind(mParent.m##X##Map, mId); \
123 if (!maybe) return nullptr; \
124 return maybe->get(); \
140 template <typename T
>
141 MOZ_IMPLICIT
operator T
*() const {
142 T
* coercer
= nullptr;
146 template <typename T
>
147 MOZ_IMPLICIT
operator const T
*() const {
148 T
* coercer
= nullptr;
153 AutoResolveT
AutoResolve(const ObjectId id
) const { return {*this, id
}; }
154 template <typename T
>
155 T
* ById(const ObjectId id
) const {
156 T
* coercer
= nullptr;
157 return AutoResolve(id
).As(coercer
);
160 // -------------------------------------------------------------------------
161 // Host-side methods. Calls in the client are forwarded to the host.
162 // -------------------------------------------------------------------------
165 // ------------------------- Composition -------------------------
167 void SetCompositableHost(RefPtr
<layers::CompositableHost
>& compositableHost
) {
168 mContext
->SetCompositableHost(compositableHost
);
171 void Present(const ObjectId xrFb
, const layers::TextureType t
,
172 const bool webvr
, const webgl::SwapChainOptions
& options
) const {
173 return (void)mContext
->Present(AutoResolve(xrFb
), t
, webvr
, options
);
175 void CopyToSwapChain(const ObjectId fb
, const layers::TextureType t
,
176 const webgl::SwapChainOptions
& options
) const {
177 return (void)mContext
->CopyToSwapChain(AutoResolve(fb
), t
, options
);
179 void WaitForTxn(const layers::RemoteTextureOwnerId aOwnerId
,
180 const layers::RemoteTextureTxnType txnType
,
181 const layers::RemoteTextureTxnId txnId
) {
182 mContext
->WaitForTxn(aOwnerId
, txnType
, txnId
);
184 void EndOfFrame() const { return (void)mContext
->EndOfFrame(); }
185 Maybe
<layers::SurfaceDescriptor
> GetFrontBuffer(ObjectId xrFb
,
186 const bool webvr
) const;
190 Maybe
<uvec2
> FrontBufferSnapshotInto(Maybe
<Range
<uint8_t>> dest
) const {
191 return mContext
->FrontBufferSnapshotInto(dest
);
194 Maybe
<uvec2
> FrontBufferSnapshotInto(
195 std::shared_ptr
<gl::SharedSurface
>& front
,
196 Maybe
<Range
<uint8_t>> dest
) const {
197 return mContext
->FrontBufferSnapshotInto(front
, dest
);
200 void ClearVRSwapChain() const { mContext
->ClearVRSwapChain(); }
204 void Resize(const uvec2
& size
) { return mContext
->Resize(size
); }
206 uvec2
DrawingBufferSize() { return mContext
->DrawingBufferSize(); }
208 void OnMemoryPressure() { return mContext
->OnMemoryPressure(); }
210 void DidRefresh() { mContext
->DidRefresh(); }
212 void GenerateError(const GLenum error
, const std::string
& text
) const {
213 mContext
->GenerateErrorImpl(error
, text
);
216 void OnContextLoss(webgl::ContextLossReason
);
218 void RequestExtension(const WebGLExtensionID ext
) {
219 mContext
->RequestExtension(ext
);
225 void JsWarning(const std::string
&) const;
228 // Creation and destruction
230 void CreateBuffer(ObjectId
);
231 void CreateFramebuffer(ObjectId
);
232 bool CreateOpaqueFramebuffer(ObjectId
,
233 const webgl::OpaqueFramebufferOptions
& options
);
234 void CreateProgram(ObjectId
);
235 void CreateQuery(ObjectId
);
236 void CreateRenderbuffer(ObjectId
);
237 void CreateSampler(ObjectId
);
238 void CreateShader(ObjectId
, GLenum type
);
239 void CreateSync(ObjectId
);
240 void CreateTexture(ObjectId
);
241 void CreateTransformFeedback(ObjectId
);
242 void CreateVertexArray(ObjectId
);
244 void DeleteBuffer(ObjectId
);
245 void DeleteFramebuffer(ObjectId
);
246 void DeleteProgram(ObjectId
);
247 void DeleteQuery(ObjectId
);
248 void DeleteRenderbuffer(ObjectId
);
249 void DeleteSampler(ObjectId
);
250 void DeleteShader(ObjectId
);
251 void DeleteSync(ObjectId
);
252 void DeleteTexture(ObjectId
);
253 void DeleteTransformFeedback(ObjectId
);
254 void DeleteVertexArray(ObjectId
);
256 // ------------------------- GL State -------------------------
257 bool IsContextLost() const { return mContext
->IsContextLost(); }
259 void SetEnabled(GLenum cap
, Maybe
<GLuint
> i
, bool val
) const {
260 mContext
->SetEnabled(cap
, i
, val
);
263 Maybe
<double> GetNumber(GLenum pname
) const {
264 return mContext
->GetParameter(pname
);
267 Maybe
<std::string
> GetString(GLenum pname
) const {
268 return mContext
->GetString(pname
);
271 void AttachShader(ObjectId prog
, ObjectId shader
) const {
272 const auto pProg
= ById
<WebGLProgram
>(prog
);
273 const auto pShader
= ById
<WebGLShader
>(shader
);
274 if (!pProg
|| !pShader
) return;
275 mContext
->AttachShader(*pProg
, *pShader
);
278 void BindAttribLocation(ObjectId id
, GLuint location
,
279 const std::string
& name
) const {
280 const auto obj
= ById
<WebGLProgram
>(id
);
282 mContext
->BindAttribLocation(*obj
, location
, name
);
285 void BindFramebuffer(GLenum target
, ObjectId id
) const {
286 mContext
->BindFramebuffer(target
, AutoResolve(id
));
289 void BlendColor(GLclampf r
, GLclampf g
, GLclampf b
, GLclampf a
) const {
290 mContext
->BlendColor(r
, g
, b
, a
);
293 void BlendEquationSeparate(Maybe
<GLuint
> i
, GLenum modeRGB
,
294 GLenum modeAlpha
) const {
295 mContext
->BlendEquationSeparate(i
, modeRGB
, modeAlpha
);
298 void BlendFuncSeparate(Maybe
<GLuint
> i
, GLenum srcRGB
, GLenum dstRGB
,
299 GLenum srcAlpha
, GLenum dstAlpha
) const {
300 mContext
->BlendFuncSeparate(i
, srcRGB
, dstRGB
, srcAlpha
, dstAlpha
);
303 GLenum
CheckFramebufferStatus(GLenum target
) const {
304 return mContext
->CheckFramebufferStatus(target
);
307 void Clear(GLbitfield mask
) const { mContext
->Clear(mask
); }
309 void ClearColor(GLclampf r
, GLclampf g
, GLclampf b
, GLclampf a
) const {
310 mContext
->ClearColor(r
, g
, b
, a
);
313 void ClearDepth(GLclampf v
) const { mContext
->ClearDepth(v
); }
315 void ClearStencil(GLint v
) const { mContext
->ClearStencil(v
); }
317 void ColorMask(Maybe
<GLuint
> i
, uint8_t mask
) const {
318 mContext
->ColorMask(i
, mask
);
321 void CompileShader(const ObjectId id
) const {
322 const auto obj
= ById
<WebGLShader
>(id
);
324 mContext
->CompileShader(*obj
);
327 void CullFace(GLenum face
) const { mContext
->CullFace(face
); }
329 void DepthFunc(GLenum func
) const { mContext
->DepthFunc(func
); }
331 void DepthMask(WebGLboolean b
) const { mContext
->DepthMask(b
); }
333 void DepthRange(GLclampf zNear
, GLclampf zFar
) const {
334 mContext
->DepthRange(zNear
, zFar
);
337 void DetachShader(const ObjectId prog
, const ObjectId shader
) const {
338 const auto pProg
= ById
<WebGLProgram
>(prog
);
339 const auto pShader
= ById
<WebGLShader
>(shader
);
340 if (!pProg
|| !pShader
) return;
341 mContext
->DetachShader(*pProg
, *pShader
);
344 void Flush() const { mContext
->Flush(); }
346 void Finish() const { mContext
->Finish(); }
348 void FramebufferAttach(const GLenum target
, const GLenum attachSlot
,
349 const GLenum bindImageTarget
, const ObjectId id
,
350 const GLint mipLevel
, const GLint zLayerBase
,
351 const GLsizei numViewLayers
) const {
352 webgl::FbAttachInfo toAttach
;
353 toAttach
.rb
= AutoResolve(id
);
354 toAttach
.tex
= AutoResolve(id
);
355 toAttach
.mipLevel
= mipLevel
;
356 toAttach
.zLayer
= zLayerBase
;
358 toAttach
.zLayerCount
= numViewLayers
;
359 toAttach
.isMultiview
= true;
362 mContext
->FramebufferAttach(target
, attachSlot
, bindImageTarget
, toAttach
);
365 void FrontFace(GLenum mode
) const { mContext
->FrontFace(mode
); }
367 Maybe
<double> GetBufferParameter(GLenum target
, GLenum pname
) const {
368 return mContext
->GetBufferParameter(target
, pname
);
371 webgl::CompileResult
GetCompileResult(ObjectId id
) const {
372 const auto obj
= ById
<WebGLShader
>(id
);
374 return mContext
->GetCompileResult(*obj
);
377 GLenum
GetError() const { return mContext
->GetError(); }
379 GLint
GetFragDataLocation(ObjectId id
, const std::string
& name
) const {
380 const auto obj
= ById
<WebGLProgram
>(id
);
382 return mContext
->GetFragDataLocation(*obj
, name
);
385 Maybe
<double> GetFramebufferAttachmentParameter(ObjectId id
,
387 GLenum pname
) const {
388 return mContext
->GetFramebufferAttachmentParameter(AutoResolve(id
),
392 webgl::LinkResult
GetLinkResult(ObjectId id
) const {
393 const auto obj
= ById
<WebGLProgram
>(id
);
395 return mContext
->GetLinkResult(*obj
);
398 Maybe
<double> GetRenderbufferParameter(ObjectId id
, GLenum pname
) const {
399 const auto obj
= ById
<WebGLRenderbuffer
>(id
);
401 return mContext
->GetRenderbufferParameter(*obj
, pname
);
404 Maybe
<webgl::ShaderPrecisionFormat
> GetShaderPrecisionFormat(
405 GLenum shaderType
, GLenum precisionType
) const {
406 return mContext
->GetShaderPrecisionFormat(shaderType
, precisionType
);
409 webgl::GetUniformData
GetUniform(ObjectId id
, uint32_t loc
) const {
410 const auto obj
= ById
<WebGLProgram
>(id
);
412 return mContext
->GetUniform(*obj
, loc
);
415 void Hint(GLenum target
, GLenum mode
) const { mContext
->Hint(target
, mode
); }
417 void LineWidth(GLfloat width
) const { mContext
->LineWidth(width
); }
419 void LinkProgram(const ObjectId id
) const {
420 const auto obj
= ById
<WebGLProgram
>(id
);
422 mContext
->LinkProgram(*obj
);
425 void PolygonOffset(GLfloat factor
, GLfloat units
) const {
426 mContext
->PolygonOffset(factor
, units
);
429 void SampleCoverage(GLclampf value
, bool invert
) const {
430 mContext
->SampleCoverage(value
, invert
);
433 void Scissor(GLint x
, GLint y
, GLsizei width
, GLsizei height
) const {
434 mContext
->Scissor(x
, y
, width
, height
);
437 // TODO: s/nsAString/std::string/
438 void ShaderSource(const ObjectId id
, const std::string
& source
) const {
439 const auto obj
= ById
<WebGLShader
>(id
);
441 mContext
->ShaderSource(*obj
, source
);
444 void StencilFuncSeparate(GLenum face
, GLenum func
, GLint ref
,
446 mContext
->StencilFuncSeparate(face
, func
, ref
, mask
);
448 void StencilMaskSeparate(GLenum face
, GLuint mask
) const {
449 mContext
->StencilMaskSeparate(face
, mask
);
451 void StencilOpSeparate(GLenum face
, GLenum sfail
, GLenum dpfail
,
452 GLenum dppass
) const {
453 mContext
->StencilOpSeparate(face
, sfail
, dpfail
, dppass
);
456 void Viewport(GLint x
, GLint y
, GLsizei width
, GLsizei height
) const {
457 mContext
->Viewport(x
, y
, width
, height
);
460 // ------------------------- Buffer Objects -------------------------
461 void BindBuffer(GLenum target
, const ObjectId id
) const {
462 mContext
->BindBuffer(target
, AutoResolve(id
));
465 void BindBufferRange(GLenum target
, GLuint index
, const ObjectId id
,
466 uint64_t offset
, uint64_t size
) const {
467 GetWebGL2Context()->BindBufferRange(target
, index
, AutoResolve(id
), offset
,
471 void CopyBufferSubData(GLenum readTarget
, GLenum writeTarget
,
472 uint64_t readOffset
, uint64_t writeOffset
,
473 uint64_t size
) const {
474 GetWebGL2Context()->CopyBufferSubData(readTarget
, writeTarget
, readOffset
,
478 bool GetBufferSubData(GLenum target
, uint64_t srcByteOffset
,
479 const Range
<uint8_t>& dest
) const {
480 return GetWebGL2Context()->GetBufferSubData(target
, srcByteOffset
, dest
);
483 void BufferData(GLenum target
, const Span
<const uint8_t>& srcData
,
484 GLenum usage
) const {
485 mContext
->BufferData(target
, srcData
.size(), srcData
.data(), usage
);
488 void BufferData_SizeOnly(GLenum target
, size_t byteSize
, GLenum usage
) const {
489 mContext
->BufferData(target
, byteSize
, nullptr, usage
);
492 void BufferSubData(GLenum target
, uint64_t dstByteOffset
,
493 const Span
<const uint8_t>& srcData
,
494 bool unsynchronized
= false) const {
495 mContext
->BufferSubData(target
, dstByteOffset
, srcData
.size(),
496 srcData
.data(), unsynchronized
);
499 // -------------------------- Framebuffer Objects --------------------------
500 void BlitFramebuffer(GLint srcX0
, GLint srcY0
, GLint srcX1
, GLint srcY1
,
501 GLint dstX0
, GLint dstY0
, GLint dstX1
, GLint dstY1
,
502 GLbitfield mask
, GLenum filter
) const {
503 GetWebGL2Context()->BlitFramebuffer(srcX0
, srcY0
, srcX1
, srcY1
, dstX0
,
504 dstY0
, dstX1
, dstY1
, mask
, filter
);
507 void InvalidateFramebuffer(GLenum target
,
508 const Span
<const GLenum
>& attachments
) const {
509 GetWebGL2Context()->InvalidateFramebuffer(target
, attachments
);
512 void InvalidateSubFramebuffer(GLenum target
,
513 const Span
<const GLenum
>& attachments
, GLint x
,
514 GLint y
, GLsizei width
, GLsizei height
) const {
515 GetWebGL2Context()->InvalidateSubFramebuffer(target
, attachments
, x
, y
,
519 void ReadBuffer(GLenum mode
) const { GetWebGL2Context()->ReadBuffer(mode
); }
521 // ----------------------- Renderbuffer objects -----------------------
522 Maybe
<std::vector
<int32_t>> GetInternalformatParameter(GLenum target
,
523 GLenum internalformat
,
524 GLenum pname
) const {
525 return GetWebGL2Context()->GetInternalformatParameter(
526 target
, internalformat
, pname
);
529 void RenderbufferStorageMultisample(ObjectId id
, uint32_t samples
,
530 GLenum internalFormat
, uint32_t width
,
531 uint32_t height
) const {
532 const auto obj
= ById
<WebGLRenderbuffer
>(id
);
534 mContext
->RenderbufferStorageMultisample(*obj
, samples
, internalFormat
,
538 // --------------------------- Texture objects ---------------------------
539 void ActiveTexture(uint32_t texUnit
) const {
540 mContext
->ActiveTexture(texUnit
);
543 void BindTexture(GLenum texTarget
, const ObjectId id
) const {
544 mContext
->BindTexture(texTarget
, AutoResolve(id
));
547 void GenerateMipmap(GLenum texTarget
) const {
548 mContext
->GenerateMipmap(texTarget
);
551 // CompressedTexSubImage if `sub`
552 void CompressedTexImage(bool sub
, GLenum imageTarget
, uint32_t level
,
553 GLenum format
, const uvec3
& offset
, const uvec3
& size
,
554 const Span
<const uint8_t>& src
,
555 const uint32_t pboImageSize
,
556 const Maybe
<uint64_t>& pboOffset
) const {
557 mContext
->CompressedTexImage(sub
, imageTarget
, level
, format
, offset
, size
,
558 src
, pboImageSize
, pboOffset
);
561 // CopyTexSubImage if `!respecFormat`
562 void CopyTexImage(GLenum imageTarget
, uint32_t level
, GLenum respecFormat
,
563 const uvec3
& dstOffset
, const ivec2
& srcOffset
,
564 const uvec2
& size
) const {
565 mContext
->CopyTexImage(imageTarget
, level
, respecFormat
, dstOffset
,
569 // TexSubImage if `!respecFormat`
570 void TexImage(uint32_t level
, GLenum respecFormat
, const uvec3
& offset
,
571 const webgl::PackingInfo
& pi
,
572 const webgl::TexUnpackBlobDesc
& src
) const {
573 mContext
->TexImage(level
, respecFormat
, offset
, pi
, src
);
576 void TexStorage(GLenum texTarget
, uint32_t levels
, GLenum internalFormat
,
577 const uvec3
& size
) const {
578 GetWebGL2Context()->TexStorage(texTarget
, levels
, internalFormat
, size
);
581 Maybe
<double> GetTexParameter(ObjectId id
, GLenum pname
) const {
582 const auto obj
= ById
<WebGLTexture
>(id
);
584 return mContext
->GetTexParameter(*obj
, pname
);
587 void TexParameter_base(GLenum texTarget
, GLenum pname
,
588 const FloatOrInt
& param
) const {
589 mContext
->TexParameter_base(texTarget
, pname
, param
);
592 // ------------------- Programs and shaders --------------------------------
593 void UseProgram(ObjectId id
) const { mContext
->UseProgram(AutoResolve(id
)); }
595 bool ValidateProgram(ObjectId id
) const {
596 const auto obj
= ById
<WebGLProgram
>(id
);
597 if (!obj
) return false;
598 return mContext
->ValidateProgram(*obj
);
601 // ------------------------ Uniforms and attributes ------------------------
603 void UniformData(uint32_t loc
, bool transpose
,
604 const Span
<const webgl::UniformDataVal
>& data
) const {
605 mContext
->UniformData(loc
, transpose
, data
);
608 void VertexAttrib4T(GLuint index
, const webgl::TypedQuad
& data
) const {
609 mContext
->VertexAttrib4T(index
, data
);
612 void VertexAttribDivisor(GLuint index
, GLuint divisor
) const {
613 mContext
->VertexAttribDivisor(index
, divisor
);
616 Maybe
<double> GetIndexedParameter(GLenum target
, GLuint index
) const {
617 return GetWebGL2Context()->GetIndexedParameter(target
, index
);
620 void UniformBlockBinding(const ObjectId id
, GLuint uniformBlockIndex
,
621 GLuint uniformBlockBinding
) const {
622 const auto obj
= ById
<WebGLProgram
>(id
);
624 GetWebGL2Context()->UniformBlockBinding(*obj
, uniformBlockIndex
,
625 uniformBlockBinding
);
628 void EnableVertexAttribArray(GLuint index
) const {
629 mContext
->EnableVertexAttribArray(index
);
632 void DisableVertexAttribArray(GLuint index
) const {
633 mContext
->DisableVertexAttribArray(index
);
636 Maybe
<double> GetVertexAttrib(GLuint index
, GLenum pname
) const {
637 return mContext
->GetVertexAttrib(index
, pname
);
640 void VertexAttribPointer(GLuint index
,
641 const webgl::VertAttribPointerDesc
& desc
) const {
642 mContext
->VertexAttribPointer(index
, desc
);
645 // --------------------------- Buffer Operations --------------------------
646 void ClearBufferTv(GLenum buffer
, GLint drawBuffer
,
647 const webgl::TypedQuad
& data
) const {
648 GetWebGL2Context()->ClearBufferTv(buffer
, drawBuffer
, data
);
651 void ClearBufferfi(GLenum buffer
, GLint drawBuffer
, GLfloat depth
,
652 GLint stencil
) const {
653 GetWebGL2Context()->ClearBufferfi(buffer
, drawBuffer
, depth
, stencil
);
656 // ------------------------------ Readback -------------------------------
657 void ReadPixelsPbo(const webgl::ReadPixelsDesc
& desc
,
658 const uint64_t offset
) const {
659 mContext
->ReadPixelsPbo(desc
, offset
);
662 webgl::ReadPixelsResult
ReadPixelsInto(const webgl::ReadPixelsDesc
& desc
,
663 const Range
<uint8_t>& dest
) const {
664 return mContext
->ReadPixelsInto(desc
, dest
);
667 // ----------------------------- Sampler -----------------------------------
669 void BindSampler(GLuint unit
, ObjectId id
) const {
670 GetWebGL2Context()->BindSampler(unit
, AutoResolve(id
));
673 void SamplerParameteri(ObjectId id
, GLenum pname
, GLint param
) const {
674 const auto obj
= ById
<WebGLSampler
>(id
);
676 GetWebGL2Context()->SamplerParameteri(*obj
, pname
, param
);
679 void SamplerParameterf(ObjectId id
, GLenum pname
, GLfloat param
) const {
680 const auto obj
= ById
<WebGLSampler
>(id
);
682 GetWebGL2Context()->SamplerParameterf(*obj
, pname
, param
);
685 Maybe
<double> GetSamplerParameter(ObjectId id
, GLenum pname
) const {
686 const auto obj
= ById
<WebGLSampler
>(id
);
688 return GetWebGL2Context()->GetSamplerParameter(*obj
, pname
);
691 // ------------------------------- GL Sync ---------------------------------
693 GLenum
ClientWaitSync(ObjectId id
, GLbitfield flags
, GLuint64 timeout
) const {
694 const auto obj
= ById
<WebGLSync
>(id
);
695 if (!obj
) return LOCAL_GL_WAIT_FAILED
;
696 return GetWebGL2Context()->ClientWaitSync(*obj
, flags
, timeout
);
699 // -------------------------- Transform Feedback ---------------------------
700 void BindTransformFeedback(ObjectId id
) const {
701 GetWebGL2Context()->BindTransformFeedback(AutoResolve(id
));
704 void BeginTransformFeedback(GLenum primitiveMode
) const {
705 GetWebGL2Context()->BeginTransformFeedback(primitiveMode
);
708 void EndTransformFeedback() const {
709 GetWebGL2Context()->EndTransformFeedback();
712 void PauseTransformFeedback() const {
713 GetWebGL2Context()->PauseTransformFeedback();
716 void ResumeTransformFeedback() const {
717 GetWebGL2Context()->ResumeTransformFeedback();
720 void TransformFeedbackVaryings(ObjectId id
,
721 const std::vector
<std::string
>& varyings
,
722 GLenum bufferMode
) const {
723 const auto obj
= ById
<WebGLProgram
>(id
);
725 GetWebGL2Context()->TransformFeedbackVaryings(*obj
, varyings
, bufferMode
);
728 // -------------------------- Opaque Framebuffers ---------------------------
729 void SetFramebufferIsInOpaqueRAF(ObjectId id
, bool value
) {
730 WebGLFramebuffer
* fb
= AutoResolve(id
);
732 fb
->mInOpaqueRAF
= value
;
736 // -------------------------------------------------------------------------
737 // Host-side extension methods. Calls in the client are forwarded to the
738 // host. Some extension methods are also available in WebGL2 Contexts. For
739 // them, the final parameter is a boolean indicating if the call originated
740 // from an extension.
741 // -------------------------------------------------------------------------
744 void DrawBuffers(const std::vector
<GLenum
>& buffers
) const {
745 mContext
->DrawBuffers(buffers
);
748 // VertexArrayObjectEXT
749 void BindVertexArray(ObjectId id
) const {
750 mContext
->BindVertexArray(AutoResolve(id
));
753 // InstancedElementsEXT
754 void DrawArraysInstanced(GLenum mode
, GLint first
, GLsizei vertCount
,
755 GLsizei primCount
) const {
756 mContext
->DrawArraysInstanced(mode
, first
, vertCount
, primCount
);
759 void DrawElementsInstanced(GLenum mode
, GLsizei vertCount
, GLenum type
,
760 WebGLintptr offset
, GLsizei primCount
) const {
761 mContext
->DrawElementsInstanced(mode
, vertCount
, type
, offset
, primCount
);
765 void BeginQuery(GLenum target
, ObjectId id
) const {
766 const auto obj
= ById
<WebGLQuery
>(id
);
768 mContext
->BeginQuery(target
, *obj
);
771 void EndQuery(GLenum target
) const { mContext
->EndQuery(target
); }
773 void QueryCounter(ObjectId id
) const {
774 const auto obj
= ById
<WebGLQuery
>(id
);
776 mContext
->QueryCounter(*obj
);
779 Maybe
<double> GetQueryParameter(ObjectId id
, GLenum pname
) const {
780 const auto obj
= ById
<WebGLQuery
>(id
);
782 return mContext
->GetQueryParameter(*obj
, pname
);
785 // WEBGL_provoking_vertex
786 void ProvokingVertex(const webgl::ProvokingVertex mode
) const {
787 mContext
->ProvokingVertex(mode
);
790 // -------------------------------------------------------------------------
791 // Client-side methods. Calls in the Host are forwarded to the client.
792 // -------------------------------------------------------------------------
794 void OnLostContext();
795 void OnRestoredContext();
798 WebGL2Context
* GetWebGL2Context() const {
799 MOZ_RELEASE_ASSERT(mContext
->IsWebGL2(), "Requires WebGL2 context");
800 return static_cast<WebGL2Context
*>(mContext
.get());
804 } // namespace mozilla
806 #endif // HOSTWEBGLCONTEXT_H_