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 EndOfFrame() const { return (void)mContext
->EndOfFrame(); }
180 Maybe
<layers::SurfaceDescriptor
> GetFrontBuffer(ObjectId xrFb
,
181 const bool webvr
) const;
185 Maybe
<uvec2
> FrontBufferSnapshotInto(Maybe
<Range
<uint8_t>> dest
) const {
186 return mContext
->FrontBufferSnapshotInto(dest
);
189 Maybe
<uvec2
> FrontBufferSnapshotInto(
190 std::shared_ptr
<gl::SharedSurface
>& front
,
191 Maybe
<Range
<uint8_t>> dest
) const {
192 return mContext
->FrontBufferSnapshotInto(front
, dest
);
195 void ClearVRSwapChain() const { mContext
->ClearVRSwapChain(); }
199 void Resize(const uvec2
& size
) { return mContext
->Resize(size
); }
201 uvec2
DrawingBufferSize() { return mContext
->DrawingBufferSize(); }
203 void OnMemoryPressure() { return mContext
->OnMemoryPressure(); }
205 void DidRefresh() { mContext
->DidRefresh(); }
207 void GenerateError(const GLenum error
, const std::string
& text
) const {
208 mContext
->GenerateErrorImpl(error
, text
);
211 void OnContextLoss(webgl::ContextLossReason
);
213 void RequestExtension(const WebGLExtensionID ext
) {
214 mContext
->RequestExtension(ext
);
220 void JsWarning(const std::string
&) const;
223 // Creation and destruction
225 void CreateBuffer(ObjectId
);
226 void CreateFramebuffer(ObjectId
);
227 bool CreateOpaqueFramebuffer(ObjectId
,
228 const webgl::OpaqueFramebufferOptions
& options
);
229 void CreateProgram(ObjectId
);
230 void CreateQuery(ObjectId
);
231 void CreateRenderbuffer(ObjectId
);
232 void CreateSampler(ObjectId
);
233 void CreateShader(ObjectId
, GLenum type
);
234 void CreateSync(ObjectId
);
235 void CreateTexture(ObjectId
);
236 void CreateTransformFeedback(ObjectId
);
237 void CreateVertexArray(ObjectId
);
239 void DeleteBuffer(ObjectId
);
240 void DeleteFramebuffer(ObjectId
);
241 void DeleteProgram(ObjectId
);
242 void DeleteQuery(ObjectId
);
243 void DeleteRenderbuffer(ObjectId
);
244 void DeleteSampler(ObjectId
);
245 void DeleteShader(ObjectId
);
246 void DeleteSync(ObjectId
);
247 void DeleteTexture(ObjectId
);
248 void DeleteTransformFeedback(ObjectId
);
249 void DeleteVertexArray(ObjectId
);
251 // ------------------------- GL State -------------------------
252 bool IsContextLost() const { return mContext
->IsContextLost(); }
254 void SetEnabled(GLenum cap
, Maybe
<GLuint
> i
, bool val
) const {
255 mContext
->SetEnabled(cap
, i
, val
);
258 bool IsEnabled(GLenum cap
) const { return mContext
->IsEnabled(cap
); }
260 Maybe
<double> GetNumber(GLenum pname
) const {
261 return mContext
->GetParameter(pname
);
264 Maybe
<std::string
> GetString(GLenum pname
) const {
265 return mContext
->GetString(pname
);
268 void AttachShader(ObjectId prog
, ObjectId shader
) const {
269 const auto pProg
= ById
<WebGLProgram
>(prog
);
270 const auto pShader
= ById
<WebGLShader
>(shader
);
271 if (!pProg
|| !pShader
) return;
272 mContext
->AttachShader(*pProg
, *pShader
);
275 void BindAttribLocation(ObjectId id
, GLuint location
,
276 const std::string
& name
) const {
277 const auto obj
= ById
<WebGLProgram
>(id
);
279 mContext
->BindAttribLocation(*obj
, location
, name
);
282 void BindFramebuffer(GLenum target
, ObjectId id
) const {
283 mContext
->BindFramebuffer(target
, AutoResolve(id
));
286 void BlendColor(GLclampf r
, GLclampf g
, GLclampf b
, GLclampf a
) const {
287 mContext
->BlendColor(r
, g
, b
, a
);
290 void BlendEquationSeparate(Maybe
<GLuint
> i
, GLenum modeRGB
,
291 GLenum modeAlpha
) const {
292 mContext
->BlendEquationSeparate(i
, modeRGB
, modeAlpha
);
295 void BlendFuncSeparate(Maybe
<GLuint
> i
, GLenum srcRGB
, GLenum dstRGB
,
296 GLenum srcAlpha
, GLenum dstAlpha
) const {
297 mContext
->BlendFuncSeparate(i
, srcRGB
, dstRGB
, srcAlpha
, dstAlpha
);
300 GLenum
CheckFramebufferStatus(GLenum target
) const {
301 return mContext
->CheckFramebufferStatus(target
);
304 void Clear(GLbitfield mask
) const { mContext
->Clear(mask
); }
306 void ClearColor(GLclampf r
, GLclampf g
, GLclampf b
, GLclampf a
) const {
307 mContext
->ClearColor(r
, g
, b
, a
);
310 void ClearDepth(GLclampf v
) const { mContext
->ClearDepth(v
); }
312 void ClearStencil(GLint v
) const { mContext
->ClearStencil(v
); }
314 void ColorMask(Maybe
<GLuint
> i
, uint8_t mask
) const {
315 mContext
->ColorMask(i
, mask
);
318 void CompileShader(const ObjectId id
) const {
319 const auto obj
= ById
<WebGLShader
>(id
);
321 mContext
->CompileShader(*obj
);
324 void CullFace(GLenum face
) const { mContext
->CullFace(face
); }
326 void DepthFunc(GLenum func
) const { mContext
->DepthFunc(func
); }
328 void DepthMask(WebGLboolean b
) const { mContext
->DepthMask(b
); }
330 void DepthRange(GLclampf zNear
, GLclampf zFar
) const {
331 mContext
->DepthRange(zNear
, zFar
);
334 void DetachShader(const ObjectId prog
, const ObjectId shader
) const {
335 const auto pProg
= ById
<WebGLProgram
>(prog
);
336 const auto pShader
= ById
<WebGLShader
>(shader
);
337 if (!pProg
|| !pShader
) return;
338 mContext
->DetachShader(*pProg
, *pShader
);
341 void Flush() const { mContext
->Flush(); }
343 void Finish() const { mContext
->Finish(); }
345 void FramebufferAttach(const GLenum target
, const GLenum attachSlot
,
346 const GLenum bindImageTarget
, const ObjectId id
,
347 const GLint mipLevel
, const GLint zLayerBase
,
348 const GLsizei numViewLayers
) const {
349 webgl::FbAttachInfo toAttach
;
350 toAttach
.rb
= AutoResolve(id
);
351 toAttach
.tex
= AutoResolve(id
);
352 toAttach
.mipLevel
= mipLevel
;
353 toAttach
.zLayer
= zLayerBase
;
355 toAttach
.zLayerCount
= numViewLayers
;
356 toAttach
.isMultiview
= true;
359 mContext
->FramebufferAttach(target
, attachSlot
, bindImageTarget
, toAttach
);
362 void FrontFace(GLenum mode
) const { mContext
->FrontFace(mode
); }
364 Maybe
<double> GetBufferParameter(GLenum target
, GLenum pname
) const {
365 return mContext
->GetBufferParameter(target
, pname
);
368 webgl::CompileResult
GetCompileResult(ObjectId id
) const {
369 const auto obj
= ById
<WebGLShader
>(id
);
371 return mContext
->GetCompileResult(*obj
);
374 GLenum
GetError() const { return mContext
->GetError(); }
376 GLint
GetFragDataLocation(ObjectId id
, const std::string
& name
) const {
377 const auto obj
= ById
<WebGLProgram
>(id
);
379 return mContext
->GetFragDataLocation(*obj
, name
);
382 Maybe
<double> GetFramebufferAttachmentParameter(ObjectId id
,
384 GLenum pname
) const {
385 return mContext
->GetFramebufferAttachmentParameter(AutoResolve(id
),
389 webgl::LinkResult
GetLinkResult(ObjectId id
) const {
390 const auto obj
= ById
<WebGLProgram
>(id
);
392 return mContext
->GetLinkResult(*obj
);
395 Maybe
<double> GetRenderbufferParameter(ObjectId id
, GLenum pname
) const {
396 const auto obj
= ById
<WebGLRenderbuffer
>(id
);
398 return mContext
->GetRenderbufferParameter(*obj
, pname
);
401 Maybe
<webgl::ShaderPrecisionFormat
> GetShaderPrecisionFormat(
402 GLenum shaderType
, GLenum precisionType
) const {
403 return mContext
->GetShaderPrecisionFormat(shaderType
, precisionType
);
406 webgl::GetUniformData
GetUniform(ObjectId id
, uint32_t loc
) const {
407 const auto obj
= ById
<WebGLProgram
>(id
);
409 return mContext
->GetUniform(*obj
, loc
);
412 void Hint(GLenum target
, GLenum mode
) const { mContext
->Hint(target
, mode
); }
414 void LineWidth(GLfloat width
) const { mContext
->LineWidth(width
); }
416 void LinkProgram(const ObjectId id
) const {
417 const auto obj
= ById
<WebGLProgram
>(id
);
419 mContext
->LinkProgram(*obj
);
422 void PolygonOffset(GLfloat factor
, GLfloat units
) const {
423 mContext
->PolygonOffset(factor
, units
);
426 void SampleCoverage(GLclampf value
, bool invert
) const {
427 mContext
->SampleCoverage(value
, invert
);
430 void Scissor(GLint x
, GLint y
, GLsizei width
, GLsizei height
) const {
431 mContext
->Scissor(x
, y
, width
, height
);
434 // TODO: s/nsAString/std::string/
435 void ShaderSource(const ObjectId id
, const std::string
& source
) const {
436 const auto obj
= ById
<WebGLShader
>(id
);
438 mContext
->ShaderSource(*obj
, source
);
441 void StencilFuncSeparate(GLenum face
, GLenum func
, GLint ref
,
443 mContext
->StencilFuncSeparate(face
, func
, ref
, mask
);
445 void StencilMaskSeparate(GLenum face
, GLuint mask
) const {
446 mContext
->StencilMaskSeparate(face
, mask
);
448 void StencilOpSeparate(GLenum face
, GLenum sfail
, GLenum dpfail
,
449 GLenum dppass
) const {
450 mContext
->StencilOpSeparate(face
, sfail
, dpfail
, dppass
);
453 void Viewport(GLint x
, GLint y
, GLsizei width
, GLsizei height
) const {
454 mContext
->Viewport(x
, y
, width
, height
);
457 // ------------------------- Buffer Objects -------------------------
458 void BindBuffer(GLenum target
, const ObjectId id
) const {
459 mContext
->BindBuffer(target
, AutoResolve(id
));
462 void BindBufferRange(GLenum target
, GLuint index
, const ObjectId id
,
463 uint64_t offset
, uint64_t size
) const {
464 GetWebGL2Context()->BindBufferRange(target
, index
, AutoResolve(id
), offset
,
468 void CopyBufferSubData(GLenum readTarget
, GLenum writeTarget
,
469 uint64_t readOffset
, uint64_t writeOffset
,
470 uint64_t size
) const {
471 GetWebGL2Context()->CopyBufferSubData(readTarget
, writeTarget
, readOffset
,
475 bool GetBufferSubData(GLenum target
, uint64_t srcByteOffset
,
476 const Range
<uint8_t>& dest
) const {
477 return GetWebGL2Context()->GetBufferSubData(target
, srcByteOffset
, dest
);
480 void BufferData(GLenum target
, const RawBuffer
<>& data
, GLenum usage
) const {
481 const auto& beginOrNull
= data
.begin();
482 mContext
->BufferData(target
, data
.size(), beginOrNull
, usage
);
485 void BufferSubData(GLenum target
, uint64_t dstByteOffset
,
486 const RawBuffer
<>& srcData
,
487 bool unsynchronized
= false) const {
488 const auto& range
= srcData
.Data();
489 mContext
->BufferSubData(target
, dstByteOffset
, range
.length(),
490 range
.begin().get(), unsynchronized
);
493 // -------------------------- Framebuffer Objects --------------------------
494 void BlitFramebuffer(GLint srcX0
, GLint srcY0
, GLint srcX1
, GLint srcY1
,
495 GLint dstX0
, GLint dstY0
, GLint dstX1
, GLint dstY1
,
496 GLbitfield mask
, GLenum filter
) const {
497 GetWebGL2Context()->BlitFramebuffer(srcX0
, srcY0
, srcX1
, srcY1
, dstX0
,
498 dstY0
, dstX1
, dstY1
, mask
, filter
);
501 void InvalidateFramebuffer(GLenum target
,
502 const RawBuffer
<const GLenum
>& attachments
) const {
503 GetWebGL2Context()->InvalidateFramebuffer(target
, MakeRange(attachments
));
506 void InvalidateSubFramebuffer(GLenum target
,
507 const RawBuffer
<const GLenum
>& attachments
,
508 GLint x
, GLint y
, GLsizei width
,
509 GLsizei height
) const {
510 GetWebGL2Context()->InvalidateSubFramebuffer(target
, MakeRange(attachments
),
511 x
, y
, width
, height
);
514 void ReadBuffer(GLenum mode
) const { GetWebGL2Context()->ReadBuffer(mode
); }
516 // ----------------------- Renderbuffer objects -----------------------
517 Maybe
<std::vector
<int32_t>> GetInternalformatParameter(GLenum target
,
518 GLenum internalformat
,
519 GLenum pname
) const {
520 return GetWebGL2Context()->GetInternalformatParameter(
521 target
, internalformat
, pname
);
524 void RenderbufferStorageMultisample(ObjectId id
, uint32_t samples
,
525 GLenum internalFormat
, uint32_t width
,
526 uint32_t height
) const {
527 const auto obj
= ById
<WebGLRenderbuffer
>(id
);
529 mContext
->RenderbufferStorageMultisample(*obj
, samples
, internalFormat
,
533 // --------------------------- Texture objects ---------------------------
534 void ActiveTexture(uint32_t texUnit
) const {
535 mContext
->ActiveTexture(texUnit
);
538 void BindTexture(GLenum texTarget
, const ObjectId id
) const {
539 mContext
->BindTexture(texTarget
, AutoResolve(id
));
542 void GenerateMipmap(GLenum texTarget
) const {
543 mContext
->GenerateMipmap(texTarget
);
546 // CompressedTexSubImage if `sub`
547 void CompressedTexImage(bool sub
, GLenum imageTarget
, uint32_t level
,
548 GLenum format
, const uvec3
& offset
, const uvec3
& size
,
549 const RawBuffer
<>& src
, const uint32_t pboImageSize
,
550 const Maybe
<uint64_t>& pboOffset
) const {
551 mContext
->CompressedTexImage(sub
, imageTarget
, level
, format
, offset
, size
,
552 MakeRange(src
), pboImageSize
, pboOffset
);
555 // CopyTexSubImage if `!respecFormat`
556 void CopyTexImage(GLenum imageTarget
, uint32_t level
, GLenum respecFormat
,
557 const uvec3
& dstOffset
, const ivec2
& srcOffset
,
558 const uvec2
& size
) const {
559 mContext
->CopyTexImage(imageTarget
, level
, respecFormat
, dstOffset
,
563 // TexSubImage if `!respecFormat`
564 void TexImage(uint32_t level
, GLenum respecFormat
, const uvec3
& offset
,
565 const webgl::PackingInfo
& pi
,
566 const webgl::TexUnpackBlobDesc
& src
) const {
567 mContext
->TexImage(level
, respecFormat
, offset
, pi
, src
);
570 void TexStorage(GLenum texTarget
, uint32_t levels
, GLenum internalFormat
,
571 const uvec3
& size
) const {
572 GetWebGL2Context()->TexStorage(texTarget
, levels
, internalFormat
, size
);
575 Maybe
<double> GetTexParameter(ObjectId id
, GLenum pname
) const {
576 const auto obj
= ById
<WebGLTexture
>(id
);
578 return mContext
->GetTexParameter(*obj
, pname
);
581 void TexParameter_base(GLenum texTarget
, GLenum pname
,
582 const FloatOrInt
& param
) const {
583 mContext
->TexParameter_base(texTarget
, pname
, param
);
586 // ------------------- Programs and shaders --------------------------------
587 void UseProgram(ObjectId id
) const { mContext
->UseProgram(AutoResolve(id
)); }
589 bool ValidateProgram(ObjectId id
) const {
590 const auto obj
= ById
<WebGLProgram
>(id
);
591 if (!obj
) return false;
592 return mContext
->ValidateProgram(*obj
);
595 // ------------------------ Uniforms and attributes ------------------------
597 void UniformData(uint32_t loc
, bool transpose
,
598 const RawBuffer
<webgl::UniformDataVal
>& data
) const {
599 mContext
->UniformData(loc
, transpose
, data
.Data());
602 void VertexAttrib4T(GLuint index
, const webgl::TypedQuad
& data
) const {
603 mContext
->VertexAttrib4T(index
, data
);
606 void VertexAttribDivisor(GLuint index
, GLuint divisor
) const {
607 mContext
->VertexAttribDivisor(index
, divisor
);
610 Maybe
<double> GetIndexedParameter(GLenum target
, GLuint index
) const {
611 return GetWebGL2Context()->GetIndexedParameter(target
, index
);
614 void UniformBlockBinding(const ObjectId id
, GLuint uniformBlockIndex
,
615 GLuint uniformBlockBinding
) const {
616 const auto obj
= ById
<WebGLProgram
>(id
);
618 GetWebGL2Context()->UniformBlockBinding(*obj
, uniformBlockIndex
,
619 uniformBlockBinding
);
622 void EnableVertexAttribArray(GLuint index
) const {
623 mContext
->EnableVertexAttribArray(index
);
626 void DisableVertexAttribArray(GLuint index
) const {
627 mContext
->DisableVertexAttribArray(index
);
630 Maybe
<double> GetVertexAttrib(GLuint index
, GLenum pname
) const {
631 return mContext
->GetVertexAttrib(index
, pname
);
634 void VertexAttribPointer(GLuint index
,
635 const webgl::VertAttribPointerDesc
& desc
) const {
636 mContext
->VertexAttribPointer(index
, desc
);
639 // --------------------------- Buffer Operations --------------------------
640 void ClearBufferTv(GLenum buffer
, GLint drawBuffer
,
641 const webgl::TypedQuad
& data
) const {
642 GetWebGL2Context()->ClearBufferTv(buffer
, drawBuffer
, data
);
645 void ClearBufferfi(GLenum buffer
, GLint drawBuffer
, GLfloat depth
,
646 GLint stencil
) const {
647 GetWebGL2Context()->ClearBufferfi(buffer
, drawBuffer
, depth
, stencil
);
650 // ------------------------------ Readback -------------------------------
651 void ReadPixelsPbo(const webgl::ReadPixelsDesc
& desc
,
652 const uint64_t offset
) const {
653 mContext
->ReadPixelsPbo(desc
, offset
);
656 webgl::ReadPixelsResult
ReadPixelsInto(const webgl::ReadPixelsDesc
& desc
,
657 const Range
<uint8_t>& dest
) const {
658 return mContext
->ReadPixelsInto(desc
, dest
);
661 // ----------------------------- Sampler -----------------------------------
663 void BindSampler(GLuint unit
, ObjectId id
) const {
664 GetWebGL2Context()->BindSampler(unit
, AutoResolve(id
));
667 void SamplerParameteri(ObjectId id
, GLenum pname
, GLint param
) const {
668 const auto obj
= ById
<WebGLSampler
>(id
);
670 GetWebGL2Context()->SamplerParameteri(*obj
, pname
, param
);
673 void SamplerParameterf(ObjectId id
, GLenum pname
, GLfloat param
) const {
674 const auto obj
= ById
<WebGLSampler
>(id
);
676 GetWebGL2Context()->SamplerParameterf(*obj
, pname
, param
);
679 Maybe
<double> GetSamplerParameter(ObjectId id
, GLenum pname
) const {
680 const auto obj
= ById
<WebGLSampler
>(id
);
682 return GetWebGL2Context()->GetSamplerParameter(*obj
, pname
);
685 // ------------------------------- GL Sync ---------------------------------
687 GLenum
ClientWaitSync(ObjectId id
, GLbitfield flags
, GLuint64 timeout
) const {
688 const auto obj
= ById
<WebGLSync
>(id
);
689 if (!obj
) return LOCAL_GL_WAIT_FAILED
;
690 return GetWebGL2Context()->ClientWaitSync(*obj
, flags
, timeout
);
693 // -------------------------- Transform Feedback ---------------------------
694 void BindTransformFeedback(ObjectId id
) const {
695 GetWebGL2Context()->BindTransformFeedback(AutoResolve(id
));
698 void BeginTransformFeedback(GLenum primitiveMode
) const {
699 GetWebGL2Context()->BeginTransformFeedback(primitiveMode
);
702 void EndTransformFeedback() const {
703 GetWebGL2Context()->EndTransformFeedback();
706 void PauseTransformFeedback() const {
707 GetWebGL2Context()->PauseTransformFeedback();
710 void ResumeTransformFeedback() const {
711 GetWebGL2Context()->ResumeTransformFeedback();
714 void TransformFeedbackVaryings(ObjectId id
,
715 const std::vector
<std::string
>& varyings
,
716 GLenum bufferMode
) const {
717 const auto obj
= ById
<WebGLProgram
>(id
);
719 GetWebGL2Context()->TransformFeedbackVaryings(*obj
, varyings
, bufferMode
);
722 // -------------------------- Opaque Framebuffers ---------------------------
723 void SetFramebufferIsInOpaqueRAF(ObjectId id
, bool value
) {
724 WebGLFramebuffer
* fb
= AutoResolve(id
);
726 fb
->mInOpaqueRAF
= value
;
730 // -------------------------------------------------------------------------
731 // Host-side extension methods. Calls in the client are forwarded to the
732 // host. Some extension methods are also available in WebGL2 Contexts. For
733 // them, the final parameter is a boolean indicating if the call originated
734 // from an extension.
735 // -------------------------------------------------------------------------
738 void DrawBuffers(const std::vector
<GLenum
>& buffers
) const {
739 mContext
->DrawBuffers(buffers
);
742 // VertexArrayObjectEXT
743 void BindVertexArray(ObjectId id
) const {
744 mContext
->BindVertexArray(AutoResolve(id
));
747 // InstancedElementsEXT
748 void DrawArraysInstanced(GLenum mode
, GLint first
, GLsizei vertCount
,
749 GLsizei primCount
) const {
750 mContext
->DrawArraysInstanced(mode
, first
, vertCount
, primCount
);
753 void DrawElementsInstanced(GLenum mode
, GLsizei vertCount
, GLenum type
,
754 WebGLintptr offset
, GLsizei primCount
) const {
755 mContext
->DrawElementsInstanced(mode
, vertCount
, type
, offset
, primCount
);
759 void BeginQuery(GLenum target
, ObjectId id
) const {
760 const auto obj
= ById
<WebGLQuery
>(id
);
762 mContext
->BeginQuery(target
, *obj
);
765 void EndQuery(GLenum target
) const { mContext
->EndQuery(target
); }
767 void QueryCounter(ObjectId id
) const {
768 const auto obj
= ById
<WebGLQuery
>(id
);
770 mContext
->QueryCounter(*obj
);
773 Maybe
<double> GetQueryParameter(ObjectId id
, GLenum pname
) const {
774 const auto obj
= ById
<WebGLQuery
>(id
);
776 return mContext
->GetQueryParameter(*obj
, pname
);
779 // WEBGL_provoking_vertex
780 void ProvokingVertex(const webgl::ProvokingVertex mode
) const {
781 mContext
->ProvokingVertex(mode
);
784 // -------------------------------------------------------------------------
785 // Client-side methods. Calls in the Host are forwarded to the client.
786 // -------------------------------------------------------------------------
788 void OnLostContext();
789 void OnRestoredContext();
792 WebGL2Context
* GetWebGL2Context() const {
793 MOZ_RELEASE_ASSERT(mContext
->IsWebGL2(), "Requires WebGL2 context");
794 return static_cast<WebGL2Context
*>(mContext
.get());
798 } // namespace mozilla
800 #endif // HOSTWEBGLCONTEXT_H_