no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / dom / canvas / HostWebGLContext.h
blob3532603d997986163b5b876115c0d24719479d9f
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>
23 #include <vector>
25 namespace mozilla {
27 namespace dom {
28 class WebGLParent;
30 namespace layers {
31 class CompositableHost;
34 struct LockedOutstandingContexts final {
35 private:
36 // StaticMutexAutoLock lock; // We can't use it directly (STACK_CLASS), but
37 // this is effectively what we hold via RAII.
39 public:
40 const std::unordered_set<HostWebGLContext*>& contexts;
42 LockedOutstandingContexts();
43 ~LockedOutstandingContexts();
46 /**
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
57 * ClientWebGLContext.
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>();
70 public:
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);
80 private:
81 explicit HostWebGLContext(const OwnerData&);
83 public:
84 virtual ~HostWebGLContext();
86 WebGLContext* GetWebGLContext() const { return mContext; }
88 public:
89 const OwnerData mOwnerData;
91 private:
92 RefPtr<WebGLContext> mContext;
94 #define _(X) std::unordered_map<ObjectId, RefPtr<WebGL##X>> m##X##Map;
96 _(Buffer)
97 _(Framebuffer)
98 _(Program)
99 _(Query)
100 _(Renderbuffer)
101 _(Sampler)
102 _(Shader)
103 _(Sync)
104 _(Texture)
105 _(TransformFeedback)
106 _(VertexArray)
108 #undef _
110 class AutoResolveT final {
111 friend class HostWebGLContext;
113 const HostWebGLContext& mParent;
114 const ObjectId mId;
116 public:
117 AutoResolveT(const HostWebGLContext& parent, const ObjectId id)
118 : mParent(parent), mId(id) {}
120 #define _(X) \
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(); \
127 _(Buffer)
128 _(Framebuffer)
129 _(Program)
130 _(Query)
131 _(Renderbuffer)
132 _(Sampler)
133 _(Shader)
134 _(Sync)
135 _(Texture)
136 _(TransformFeedback)
137 _(VertexArray)
139 #undef _
140 template <typename T>
141 MOZ_IMPLICIT operator T*() const {
142 T* coercer = nullptr;
143 return As(coercer);
146 template <typename T>
147 MOZ_IMPLICIT operator const T*() const {
148 T* coercer = nullptr;
149 return As(coercer);
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 // -------------------------------------------------------------------------
164 public:
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;
183 // -
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(); }
197 // -
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);
217 // -
218 // Child-ward
220 void JsWarning(const std::string&) const;
222 // -
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);
278 if (!obj) return;
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);
320 if (!obj) return;
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;
354 if (numViewLayers) {
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);
370 if (!obj) return {};
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);
378 if (!obj) return -1;
379 return mContext->GetFragDataLocation(*obj, name);
382 Maybe<double> GetFramebufferAttachmentParameter(ObjectId id,
383 GLenum attachment,
384 GLenum pname) const {
385 return mContext->GetFramebufferAttachmentParameter(AutoResolve(id),
386 attachment, pname);
389 webgl::LinkResult GetLinkResult(ObjectId id) const {
390 const auto obj = ById<WebGLProgram>(id);
391 if (!obj) return {};
392 return mContext->GetLinkResult(*obj);
395 Maybe<double> GetRenderbufferParameter(ObjectId id, GLenum pname) const {
396 const auto obj = ById<WebGLRenderbuffer>(id);
397 if (!obj) return {};
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);
408 if (!obj) return {};
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);
418 if (!obj) return;
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);
437 if (!obj) return;
438 mContext->ShaderSource(*obj, source);
441 void StencilFuncSeparate(GLenum face, GLenum func, GLint ref,
442 GLuint mask) const {
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,
465 size);
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,
472 writeOffset, size);
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);
528 if (!obj) return;
529 mContext->RenderbufferStorageMultisample(*obj, samples, internalFormat,
530 width, height);
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,
560 srcOffset, size);
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);
577 if (!obj) return {};
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);
617 if (!obj) return;
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);
669 if (!obj) return;
670 GetWebGL2Context()->SamplerParameteri(*obj, pname, param);
673 void SamplerParameterf(ObjectId id, GLenum pname, GLfloat param) const {
674 const auto obj = ById<WebGLSampler>(id);
675 if (!obj) return;
676 GetWebGL2Context()->SamplerParameterf(*obj, pname, param);
679 Maybe<double> GetSamplerParameter(ObjectId id, GLenum pname) const {
680 const auto obj = ById<WebGLSampler>(id);
681 if (!obj) return {};
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);
718 if (!obj) return;
719 GetWebGL2Context()->TransformFeedbackVaryings(*obj, varyings, bufferMode);
722 // -------------------------- Opaque Framebuffers ---------------------------
723 void SetFramebufferIsInOpaqueRAF(ObjectId id, bool value) {
724 WebGLFramebuffer* fb = AutoResolve(id);
725 if (fb) {
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 // -------------------------------------------------------------------------
737 // Misc. Extensions
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);
758 // GLQueryEXT
759 void BeginQuery(GLenum target, ObjectId id) const {
760 const auto obj = ById<WebGLQuery>(id);
761 if (!obj) return;
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);
769 if (!obj) return;
770 mContext->QueryCounter(*obj);
773 Maybe<double> GetQueryParameter(ObjectId id, GLenum pname) const {
774 const auto obj = ById<WebGLQuery>(id);
775 if (!obj) return {};
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 // -------------------------------------------------------------------------
787 public:
788 void OnLostContext();
789 void OnRestoredContext();
791 protected:
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_