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"
20 #include "IpdlQueue.h"
22 #include <unordered_map>
23 #include <unordered_set>
32 class CompositableHost
;
35 struct LockedOutstandingContexts final
{
37 // StaticMutexAutoLock lock; // We can't use it directly (STACK_CLASS), but
38 // this is effectively what we hold via RAII.
41 const std::unordered_set
<HostWebGLContext
*>& contexts
;
43 LockedOutstandingContexts();
44 ~LockedOutstandingContexts();
48 * Host endpoint of a WebGLContext. HostWebGLContext owns a WebGLContext
49 * that it uses to execute commands sent from its ClientWebGLContext.
51 * A HostWebGLContext continuously issues a Task to the Compositor thread that
52 * causes it to drain its queue of commands. It also maintains a map of WebGL
53 * objects (e.g. ObjectIdMap<WebGLShader>) that it uses associate them with
54 * their cross-process IDs.
56 * This class is not an implementation of the
57 * nsICanvasRenderingContextInternal DOM class. That is the
60 class HostWebGLContext final
: public SupportsWeakPtr
{
61 friend class WebGLContext
;
62 friend class WebGLMemoryTracker
;
63 friend class dom::WebGLParent
;
65 using ObjectId
= webgl::ObjectId
;
67 static std::unique_ptr
<LockedOutstandingContexts
> OutstandingContexts() {
68 return std::make_unique
<LockedOutstandingContexts
>();
72 struct OwnerData final
{
73 ClientWebGLContext
* inProcess
= nullptr;
74 dom::WebGLParent
* outOfProcess
= nullptr;
77 static UniquePtr
<HostWebGLContext
> Create(const OwnerData
&,
78 const webgl::InitContextDesc
&,
79 webgl::InitContextResult
* out
);
82 explicit HostWebGLContext(const OwnerData
&);
85 virtual ~HostWebGLContext();
87 WebGLContext
* GetWebGLContext() const { return mContext
; }
90 const OwnerData mOwnerData
;
93 RefPtr
<WebGLContext
> mContext
;
95 #define _(X) std::unordered_map<ObjectId, RefPtr<WebGL##X>> m##X##Map;
111 class AutoResolveT final
{
112 friend class HostWebGLContext
;
114 const HostWebGLContext
& mParent
;
118 AutoResolveT(const HostWebGLContext
& parent
, const ObjectId id
)
119 : mParent(parent
), mId(id
) {}
122 WebGL##X* As(WebGL##X*) const { \
123 const auto maybe = MaybeFind(mParent.m##X##Map, mId); \
124 if (!maybe) return nullptr; \
125 return maybe->get(); \
141 template <typename T
>
142 MOZ_IMPLICIT
operator T
*() const {
143 T
* coercer
= nullptr;
147 template <typename T
>
148 MOZ_IMPLICIT
operator const T
*() const {
149 T
* coercer
= nullptr;
154 AutoResolveT
AutoResolve(const ObjectId id
) const { return {*this, id
}; }
155 template <typename T
>
156 T
* ById(const ObjectId id
) const {
157 T
* coercer
= nullptr;
158 return AutoResolve(id
).As(coercer
);
161 // -------------------------------------------------------------------------
162 // Host-side methods. Calls in the client are forwarded to the host.
163 // -------------------------------------------------------------------------
166 // ------------------------- Composition -------------------------
168 void SetCompositableHost(RefPtr
<layers::CompositableHost
>& compositableHost
) {
169 mContext
->SetCompositableHost(compositableHost
);
172 void Present(const ObjectId xrFb
, const layers::TextureType t
,
173 const bool webvr
) const {
174 return (void)mContext
->Present(AutoResolve(xrFb
), t
, webvr
);
176 Maybe
<layers::SurfaceDescriptor
> GetFrontBuffer(ObjectId xrFb
,
177 const bool webvr
) const;
181 uvec2
GetFrontBufferSize() const { return mContext
->DrawingBufferSize(); }
182 bool FrontBufferSnapshotInto(Range
<uint8_t> dest
) const {
183 return mContext
->FrontBufferSnapshotInto(dest
);
186 void ClearVRSwapChain() const { mContext
->ClearVRSwapChain(); }
190 void Resize(const uvec2
& size
) { return mContext
->Resize(size
); }
192 uvec2
DrawingBufferSize() { return mContext
->DrawingBufferSize(); }
194 void OnMemoryPressure() { return mContext
->OnMemoryPressure(); }
196 void DidRefresh() { mContext
->DidRefresh(); }
198 void GenerateError(const GLenum error
, const std::string
& text
) const {
199 mContext
->GenerateErrorImpl(error
, text
);
202 void OnContextLoss(webgl::ContextLossReason
);
204 void RequestExtension(const WebGLExtensionID ext
) {
205 mContext
->RequestExtension(ext
);
211 void JsWarning(const std::string
&) const;
214 // Creation and destruction
216 void CreateBuffer(ObjectId
);
217 void CreateFramebuffer(ObjectId
);
218 bool CreateOpaqueFramebuffer(ObjectId
,
219 const webgl::OpaqueFramebufferOptions
& options
);
220 void CreateProgram(ObjectId
);
221 void CreateQuery(ObjectId
);
222 void CreateRenderbuffer(ObjectId
);
223 void CreateSampler(ObjectId
);
224 void CreateShader(ObjectId
, GLenum type
);
225 void CreateSync(ObjectId
);
226 void CreateTexture(ObjectId
);
227 void CreateTransformFeedback(ObjectId
);
228 void CreateVertexArray(ObjectId
);
230 void DeleteBuffer(ObjectId
);
231 void DeleteFramebuffer(ObjectId
);
232 void DeleteProgram(ObjectId
);
233 void DeleteQuery(ObjectId
);
234 void DeleteRenderbuffer(ObjectId
);
235 void DeleteSampler(ObjectId
);
236 void DeleteShader(ObjectId
);
237 void DeleteSync(ObjectId
);
238 void DeleteTexture(ObjectId
);
239 void DeleteTransformFeedback(ObjectId
);
240 void DeleteVertexArray(ObjectId
);
242 // ------------------------- GL State -------------------------
243 bool IsContextLost() const { return mContext
->IsContextLost(); }
245 void Disable(GLenum cap
) const { mContext
->Disable(cap
); }
247 void Enable(GLenum cap
) const { mContext
->Enable(cap
); }
249 bool IsEnabled(GLenum cap
) const { return mContext
->IsEnabled(cap
); }
251 Maybe
<double> GetNumber(GLenum pname
) const {
252 return mContext
->GetParameter(pname
);
255 Maybe
<std::string
> GetString(GLenum pname
) const {
256 return mContext
->GetString(pname
);
259 void AttachShader(ObjectId prog
, ObjectId shader
) const {
260 const auto pProg
= ById
<WebGLProgram
>(prog
);
261 const auto pShader
= ById
<WebGLShader
>(shader
);
262 if (!pProg
|| !pShader
) return;
263 mContext
->AttachShader(*pProg
, *pShader
);
266 void BindAttribLocation(ObjectId id
, GLuint location
,
267 const std::string
& name
) const {
268 const auto obj
= ById
<WebGLProgram
>(id
);
270 mContext
->BindAttribLocation(*obj
, location
, name
);
273 void BindFramebuffer(GLenum target
, ObjectId id
) const {
274 mContext
->BindFramebuffer(target
, AutoResolve(id
));
277 void BlendColor(GLclampf r
, GLclampf g
, GLclampf b
, GLclampf a
) const {
278 mContext
->BlendColor(r
, g
, b
, a
);
281 void BlendEquationSeparate(GLenum modeRGB
, GLenum modeAlpha
) const {
282 mContext
->BlendEquationSeparate(modeRGB
, modeAlpha
);
285 void BlendFuncSeparate(GLenum srcRGB
, GLenum dstRGB
, GLenum srcAlpha
,
286 GLenum dstAlpha
) const {
287 mContext
->BlendFuncSeparate(srcRGB
, dstRGB
, srcAlpha
, dstAlpha
);
290 GLenum
CheckFramebufferStatus(GLenum target
) const {
291 return mContext
->CheckFramebufferStatus(target
);
294 void Clear(GLbitfield mask
) const { mContext
->Clear(mask
); }
296 void ClearColor(GLclampf r
, GLclampf g
, GLclampf b
, GLclampf a
) const {
297 mContext
->ClearColor(r
, g
, b
, a
);
300 void ClearDepth(GLclampf v
) const { mContext
->ClearDepth(v
); }
302 void ClearStencil(GLint v
) const { mContext
->ClearStencil(v
); }
304 void ColorMask(WebGLboolean r
, WebGLboolean g
, WebGLboolean b
,
305 WebGLboolean a
) const {
306 mContext
->ColorMask(r
, g
, b
, a
);
309 void CompileShader(const ObjectId id
) const {
310 const auto obj
= ById
<WebGLShader
>(id
);
312 mContext
->CompileShader(*obj
);
315 void CullFace(GLenum face
) const { mContext
->CullFace(face
); }
317 void DepthFunc(GLenum func
) const { mContext
->DepthFunc(func
); }
319 void DepthMask(WebGLboolean b
) const { mContext
->DepthMask(b
); }
321 void DepthRange(GLclampf zNear
, GLclampf zFar
) const {
322 mContext
->DepthRange(zNear
, zFar
);
325 void DetachShader(const ObjectId prog
, const ObjectId shader
) const {
326 const auto pProg
= ById
<WebGLProgram
>(prog
);
327 const auto pShader
= ById
<WebGLShader
>(shader
);
328 if (!pProg
|| !pShader
) return;
329 mContext
->DetachShader(*pProg
, *pShader
);
332 void Flush() const { mContext
->Flush(); }
334 void Finish() const { mContext
->Finish(); }
336 void FramebufferAttach(const GLenum target
, const GLenum attachSlot
,
337 const GLenum bindImageTarget
, const ObjectId id
,
338 const GLint mipLevel
, const GLint zLayerBase
,
339 const GLsizei numViewLayers
) const {
340 webgl::FbAttachInfo toAttach
;
341 toAttach
.rb
= AutoResolve(id
);
342 toAttach
.tex
= AutoResolve(id
);
343 toAttach
.mipLevel
= mipLevel
;
344 toAttach
.zLayer
= zLayerBase
;
346 toAttach
.zLayerCount
= numViewLayers
;
347 toAttach
.isMultiview
= true;
350 mContext
->FramebufferAttach(target
, attachSlot
, bindImageTarget
, toAttach
);
353 void FrontFace(GLenum mode
) const { mContext
->FrontFace(mode
); }
355 Maybe
<double> GetBufferParameter(GLenum target
, GLenum pname
) const {
356 return mContext
->GetBufferParameter(target
, pname
);
359 webgl::CompileResult
GetCompileResult(ObjectId id
) const {
360 const auto obj
= ById
<WebGLShader
>(id
);
362 return mContext
->GetCompileResult(*obj
);
365 GLenum
GetError() const { return mContext
->GetError(); }
367 GLint
GetFragDataLocation(ObjectId id
, const std::string
& name
) const {
368 const auto obj
= ById
<WebGLProgram
>(id
);
370 return mContext
->GetFragDataLocation(*obj
, name
);
373 Maybe
<double> GetFramebufferAttachmentParameter(ObjectId id
,
375 GLenum pname
) const {
376 return mContext
->GetFramebufferAttachmentParameter(AutoResolve(id
),
380 webgl::LinkResult
GetLinkResult(ObjectId id
) const {
381 const auto obj
= ById
<WebGLProgram
>(id
);
383 return mContext
->GetLinkResult(*obj
);
386 Maybe
<double> GetRenderbufferParameter(ObjectId id
, GLenum pname
) const {
387 const auto obj
= ById
<WebGLRenderbuffer
>(id
);
389 return mContext
->GetRenderbufferParameter(*obj
, pname
);
392 Maybe
<webgl::ShaderPrecisionFormat
> GetShaderPrecisionFormat(
393 GLenum shaderType
, GLenum precisionType
) const {
394 return mContext
->GetShaderPrecisionFormat(shaderType
, precisionType
);
397 webgl::GetUniformData
GetUniform(ObjectId id
, uint32_t loc
) const {
398 const auto obj
= ById
<WebGLProgram
>(id
);
400 return mContext
->GetUniform(*obj
, loc
);
403 void Hint(GLenum target
, GLenum mode
) const { mContext
->Hint(target
, mode
); }
405 void LineWidth(GLfloat width
) const { mContext
->LineWidth(width
); }
407 void LinkProgram(const ObjectId id
) const {
408 const auto obj
= ById
<WebGLProgram
>(id
);
410 mContext
->LinkProgram(*obj
);
413 void PolygonOffset(GLfloat factor
, GLfloat units
) const {
414 mContext
->PolygonOffset(factor
, units
);
417 void SampleCoverage(GLclampf value
, bool invert
) const {
418 mContext
->SampleCoverage(value
, invert
);
421 void Scissor(GLint x
, GLint y
, GLsizei width
, GLsizei height
) const {
422 mContext
->Scissor(x
, y
, width
, height
);
425 // TODO: s/nsAString/std::string/
426 void ShaderSource(const ObjectId id
, const std::string
& source
) const {
427 const auto obj
= ById
<WebGLShader
>(id
);
429 mContext
->ShaderSource(*obj
, source
);
432 void StencilFuncSeparate(GLenum face
, GLenum func
, GLint ref
,
434 mContext
->StencilFuncSeparate(face
, func
, ref
, mask
);
436 void StencilMaskSeparate(GLenum face
, GLuint mask
) const {
437 mContext
->StencilMaskSeparate(face
, mask
);
439 void StencilOpSeparate(GLenum face
, GLenum sfail
, GLenum dpfail
,
440 GLenum dppass
) const {
441 mContext
->StencilOpSeparate(face
, sfail
, dpfail
, dppass
);
444 void Viewport(GLint x
, GLint y
, GLsizei width
, GLsizei height
) const {
445 mContext
->Viewport(x
, y
, width
, height
);
448 // ------------------------- Buffer Objects -------------------------
449 void BindBuffer(GLenum target
, const ObjectId id
) const {
450 mContext
->BindBuffer(target
, AutoResolve(id
));
453 void BindBufferRange(GLenum target
, GLuint index
, const ObjectId id
,
454 uint64_t offset
, uint64_t size
) const {
455 GetWebGL2Context()->BindBufferRange(target
, index
, AutoResolve(id
), offset
,
459 void CopyBufferSubData(GLenum readTarget
, GLenum writeTarget
,
460 uint64_t readOffset
, uint64_t writeOffset
,
461 uint64_t size
) const {
462 GetWebGL2Context()->CopyBufferSubData(readTarget
, writeTarget
, readOffset
,
466 bool GetBufferSubData(GLenum target
, uint64_t srcByteOffset
,
467 const Range
<uint8_t>& dest
) const {
468 return GetWebGL2Context()->GetBufferSubData(target
, srcByteOffset
, dest
);
471 void BufferData(GLenum target
, const RawBuffer
<>& data
, GLenum usage
) const {
472 const auto& beginOrNull
= data
.begin();
473 mContext
->BufferData(target
, data
.size(), beginOrNull
, usage
);
476 void BufferSubData(GLenum target
, uint64_t dstByteOffset
,
477 const RawBuffer
<>& srcData
) const {
478 const auto& range
= srcData
.Data();
479 mContext
->BufferSubData(target
, dstByteOffset
, range
.length(),
480 range
.begin().get());
483 // -------------------------- Framebuffer Objects --------------------------
484 void BlitFramebuffer(GLint srcX0
, GLint srcY0
, GLint srcX1
, GLint srcY1
,
485 GLint dstX0
, GLint dstY0
, GLint dstX1
, GLint dstY1
,
486 GLbitfield mask
, GLenum filter
) const {
487 GetWebGL2Context()->BlitFramebuffer(srcX0
, srcY0
, srcX1
, srcY1
, dstX0
,
488 dstY0
, dstX1
, dstY1
, mask
, filter
);
491 void InvalidateFramebuffer(GLenum target
,
492 const RawBuffer
<const GLenum
>& attachments
) const {
493 GetWebGL2Context()->InvalidateFramebuffer(target
, MakeRange(attachments
));
496 void InvalidateSubFramebuffer(GLenum target
,
497 const RawBuffer
<const GLenum
>& attachments
,
498 GLint x
, GLint y
, GLsizei width
,
499 GLsizei height
) const {
500 GetWebGL2Context()->InvalidateSubFramebuffer(target
, MakeRange(attachments
),
501 x
, y
, width
, height
);
504 void ReadBuffer(GLenum mode
) const { GetWebGL2Context()->ReadBuffer(mode
); }
506 // ----------------------- Renderbuffer objects -----------------------
507 Maybe
<std::vector
<int32_t>> GetInternalformatParameter(GLenum target
,
508 GLenum internalformat
,
509 GLenum pname
) const {
510 return GetWebGL2Context()->GetInternalformatParameter(
511 target
, internalformat
, pname
);
514 void RenderbufferStorageMultisample(ObjectId id
, uint32_t samples
,
515 GLenum internalFormat
, uint32_t width
,
516 uint32_t height
) const {
517 const auto obj
= ById
<WebGLRenderbuffer
>(id
);
519 mContext
->RenderbufferStorageMultisample(*obj
, samples
, internalFormat
,
523 // --------------------------- Texture objects ---------------------------
524 void ActiveTexture(uint32_t texUnit
) const {
525 mContext
->ActiveTexture(texUnit
);
528 void BindTexture(GLenum texTarget
, const ObjectId id
) const {
529 mContext
->BindTexture(texTarget
, AutoResolve(id
));
532 void GenerateMipmap(GLenum texTarget
) const {
533 mContext
->GenerateMipmap(texTarget
);
536 // CompressedTexSubImage if `sub`
537 void CompressedTexImage(bool sub
, GLenum imageTarget
, uint32_t level
,
538 GLenum format
, const uvec3
& offset
, const uvec3
& size
,
539 const RawBuffer
<>& src
, const uint32_t pboImageSize
,
540 const Maybe
<uint64_t>& pboOffset
) const {
541 mContext
->CompressedTexImage(sub
, imageTarget
, level
, format
, offset
, size
,
542 MakeRange(src
), pboImageSize
, pboOffset
);
545 // CopyTexSubImage if `!respecFormat`
546 void CopyTexImage(GLenum imageTarget
, uint32_t level
, GLenum respecFormat
,
547 const uvec3
& dstOffset
, const ivec2
& srcOffset
,
548 const uvec2
& size
) const {
549 mContext
->CopyTexImage(imageTarget
, level
, respecFormat
, dstOffset
,
553 // TexSubImage if `!respecFormat`
554 void TexImage(uint32_t level
, GLenum respecFormat
, const uvec3
& offset
,
555 const webgl::PackingInfo
& pi
,
556 const webgl::TexUnpackBlobDesc
& src
) const {
557 mContext
->TexImage(level
, respecFormat
, offset
, pi
, src
);
560 void TexStorage(GLenum texTarget
, uint32_t levels
, GLenum internalFormat
,
561 const uvec3
& size
) const {
562 GetWebGL2Context()->TexStorage(texTarget
, levels
, internalFormat
, size
);
565 Maybe
<double> GetTexParameter(ObjectId id
, GLenum pname
) const {
566 const auto obj
= ById
<WebGLTexture
>(id
);
568 return mContext
->GetTexParameter(*obj
, pname
);
571 void TexParameter_base(GLenum texTarget
, GLenum pname
,
572 const FloatOrInt
& param
) const {
573 mContext
->TexParameter_base(texTarget
, pname
, param
);
576 // ------------------- Programs and shaders --------------------------------
577 void UseProgram(ObjectId id
) const { mContext
->UseProgram(AutoResolve(id
)); }
579 bool ValidateProgram(ObjectId id
) const {
580 const auto obj
= ById
<WebGLProgram
>(id
);
581 if (!obj
) return false;
582 return mContext
->ValidateProgram(*obj
);
585 // ------------------------ Uniforms and attributes ------------------------
587 void UniformData(uint32_t loc
, bool transpose
,
588 const RawBuffer
<>& data
) const {
589 mContext
->UniformData(loc
, transpose
, data
.Data());
592 void VertexAttrib4T(GLuint index
, const webgl::TypedQuad
& data
) const {
593 mContext
->VertexAttrib4T(index
, data
);
596 void VertexAttribDivisor(GLuint index
, GLuint divisor
) const {
597 mContext
->VertexAttribDivisor(index
, divisor
);
600 Maybe
<double> GetIndexedParameter(GLenum target
, GLuint index
) const {
601 return GetWebGL2Context()->GetIndexedParameter(target
, index
);
604 void UniformBlockBinding(const ObjectId id
, GLuint uniformBlockIndex
,
605 GLuint uniformBlockBinding
) const {
606 const auto obj
= ById
<WebGLProgram
>(id
);
608 GetWebGL2Context()->UniformBlockBinding(*obj
, uniformBlockIndex
,
609 uniformBlockBinding
);
612 void EnableVertexAttribArray(GLuint index
) const {
613 mContext
->EnableVertexAttribArray(index
);
616 void DisableVertexAttribArray(GLuint index
) const {
617 mContext
->DisableVertexAttribArray(index
);
620 Maybe
<double> GetVertexAttrib(GLuint index
, GLenum pname
) const {
621 return mContext
->GetVertexAttrib(index
, pname
);
624 void VertexAttribPointer(GLuint index
,
625 const webgl::VertAttribPointerDesc
& desc
) const {
626 mContext
->VertexAttribPointer(index
, desc
);
629 // --------------------------- Buffer Operations --------------------------
630 void ClearBufferTv(GLenum buffer
, GLint drawBuffer
,
631 const webgl::TypedQuad
& data
) const {
632 GetWebGL2Context()->ClearBufferTv(buffer
, drawBuffer
, data
);
635 void ClearBufferfi(GLenum buffer
, GLint drawBuffer
, GLfloat depth
,
636 GLint stencil
) const {
637 GetWebGL2Context()->ClearBufferfi(buffer
, drawBuffer
, depth
, stencil
);
640 // ------------------------------ Readback -------------------------------
641 void ReadPixelsPbo(const webgl::ReadPixelsDesc
& desc
,
642 const uint64_t offset
) const {
643 mContext
->ReadPixelsPbo(desc
, offset
);
646 webgl::ReadPixelsResult
ReadPixelsInto(const webgl::ReadPixelsDesc
& desc
,
647 const Range
<uint8_t>& dest
) const {
648 return mContext
->ReadPixelsInto(desc
, dest
);
651 // ----------------------------- Sampler -----------------------------------
653 void BindSampler(GLuint unit
, ObjectId id
) const {
654 GetWebGL2Context()->BindSampler(unit
, AutoResolve(id
));
657 void SamplerParameteri(ObjectId id
, GLenum pname
, GLint param
) const {
658 const auto obj
= ById
<WebGLSampler
>(id
);
660 GetWebGL2Context()->SamplerParameteri(*obj
, pname
, param
);
663 void SamplerParameterf(ObjectId id
, GLenum pname
, GLfloat param
) const {
664 const auto obj
= ById
<WebGLSampler
>(id
);
666 GetWebGL2Context()->SamplerParameterf(*obj
, pname
, param
);
669 Maybe
<double> GetSamplerParameter(ObjectId id
, GLenum pname
) const {
670 const auto obj
= ById
<WebGLSampler
>(id
);
672 return GetWebGL2Context()->GetSamplerParameter(*obj
, pname
);
675 // ------------------------------- GL Sync ---------------------------------
677 GLenum
ClientWaitSync(ObjectId id
, GLbitfield flags
, GLuint64 timeout
) const {
678 const auto obj
= ById
<WebGLSync
>(id
);
679 if (!obj
) return LOCAL_GL_WAIT_FAILED
;
680 return GetWebGL2Context()->ClientWaitSync(*obj
, flags
, timeout
);
683 // -------------------------- Transform Feedback ---------------------------
684 void BindTransformFeedback(ObjectId id
) const {
685 GetWebGL2Context()->BindTransformFeedback(AutoResolve(id
));
688 void BeginTransformFeedback(GLenum primitiveMode
) const {
689 GetWebGL2Context()->BeginTransformFeedback(primitiveMode
);
692 void EndTransformFeedback() const {
693 GetWebGL2Context()->EndTransformFeedback();
696 void PauseTransformFeedback() const {
697 GetWebGL2Context()->PauseTransformFeedback();
700 void ResumeTransformFeedback() const {
701 GetWebGL2Context()->ResumeTransformFeedback();
704 void TransformFeedbackVaryings(ObjectId id
,
705 const std::vector
<std::string
>& varyings
,
706 GLenum bufferMode
) const {
707 const auto obj
= ById
<WebGLProgram
>(id
);
709 GetWebGL2Context()->TransformFeedbackVaryings(*obj
, varyings
, bufferMode
);
712 // -------------------------- Opaque Framebuffers ---------------------------
713 void SetFramebufferIsInOpaqueRAF(ObjectId id
, bool value
) {
714 WebGLFramebuffer
* fb
= AutoResolve(id
);
716 fb
->mInOpaqueRAF
= value
;
720 // -------------------------------------------------------------------------
721 // Host-side extension methods. Calls in the client are forwarded to the
722 // host. Some extension methods are also available in WebGL2 Contexts. For
723 // them, the final parameter is a boolean indicating if the call originated
724 // from an extension.
725 // -------------------------------------------------------------------------
728 void DrawBuffers(const std::vector
<GLenum
>& buffers
) const {
729 mContext
->DrawBuffers(buffers
);
732 // VertexArrayObjectEXT
733 void BindVertexArray(ObjectId id
) const {
734 mContext
->BindVertexArray(AutoResolve(id
));
737 // InstancedElementsEXT
738 void DrawArraysInstanced(GLenum mode
, GLint first
, GLsizei vertCount
,
739 GLsizei primCount
) const {
740 mContext
->DrawArraysInstanced(mode
, first
, vertCount
, primCount
);
743 void DrawElementsInstanced(GLenum mode
, GLsizei vertCount
, GLenum type
,
744 WebGLintptr offset
, GLsizei primCount
) const {
745 mContext
->DrawElementsInstanced(mode
, vertCount
, type
, offset
, primCount
);
749 void BeginQuery(GLenum target
, ObjectId id
) const {
750 const auto obj
= ById
<WebGLQuery
>(id
);
752 mContext
->BeginQuery(target
, *obj
);
755 void EndQuery(GLenum target
) const { mContext
->EndQuery(target
); }
757 void QueryCounter(ObjectId id
) const {
758 const auto obj
= ById
<WebGLQuery
>(id
);
760 mContext
->QueryCounter(*obj
);
763 Maybe
<double> GetQueryParameter(ObjectId id
, GLenum pname
) const {
764 const auto obj
= ById
<WebGLQuery
>(id
);
766 return mContext
->GetQueryParameter(*obj
, pname
);
769 // -------------------------------------------------------------------------
770 // Client-side methods. Calls in the Host are forwarded to the client.
771 // -------------------------------------------------------------------------
773 void OnLostContext();
774 void OnRestoredContext();
777 WebGL2Context
* GetWebGL2Context() const {
778 MOZ_RELEASE_ASSERT(mContext
->IsWebGL2(), "Requires WebGL2 context");
779 return static_cast<WebGL2Context
*>(mContext
.get());
783 } // namespace mozilla
785 #endif // HOSTWEBGLCONTEXT_H_