HostWebGLContext.h (27161B)
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/. */ 5 6 #ifndef HOSTWEBGLCONTEXT_H_ 7 #define HOSTWEBGLCONTEXT_H_ 8 9 #include <memory> 10 #include <unordered_map> 11 #include <unordered_set> 12 #include <vector> 13 14 #include "ClientWebGLContext.h" 15 #include "GLContext.h" 16 #include "WebGL2Context.h" 17 #include "WebGLCommandQueue.h" 18 #include "WebGLContext.h" 19 #include "WebGLFramebuffer.h" 20 #include "WebGLTypes.h" 21 #include "mozilla/GfxMessageUtils.h" 22 #include "mozilla/Maybe.h" 23 #include "mozilla/dom/BindingUtils.h" 24 25 namespace mozilla { 26 27 namespace dom { 28 class WebGLParent; 29 } 30 namespace layers { 31 class CompositableHost; 32 } 33 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. 38 39 public: 40 const std::unordered_set<HostWebGLContext*>& contexts; 41 42 LockedOutstandingContexts(); 43 ~LockedOutstandingContexts(); 44 }; 45 46 /** 47 * Host endpoint of a WebGLContext. HostWebGLContext owns a WebGLContext 48 * that it uses to execute commands sent from its ClientWebGLContext. 49 * 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. 54 * 55 * This class is not an implementation of the 56 * nsICanvasRenderingContextInternal DOM class. That is the 57 * ClientWebGLContext. 58 */ 59 class HostWebGLContext final : public SupportsWeakPtr { 60 friend class WebGLContext; 61 friend class WebGLMemoryTracker; 62 friend class dom::WebGLParent; 63 64 using ObjectId = webgl::ObjectId; 65 66 static std::unique_ptr<LockedOutstandingContexts> OutstandingContexts() { 67 return std::make_unique<LockedOutstandingContexts>(); 68 } 69 70 public: 71 struct OwnerData final { 72 ClientWebGLContext* inProcess = nullptr; 73 dom::WebGLParent* outOfProcess = nullptr; 74 }; 75 76 static std::unique_ptr<HostWebGLContext> Create( 77 const OwnerData&, const webgl::InitContextDesc&, 78 webgl::InitContextResult* out); 79 80 private: 81 explicit HostWebGLContext(const OwnerData&); 82 83 public: 84 virtual ~HostWebGLContext(); 85 86 WebGLContext* GetWebGLContext() const { return mContext; } 87 88 public: 89 const OwnerData mOwnerData; 90 91 private: 92 RefPtr<WebGLContext> mContext; 93 94 #define _(X) std::unordered_map<ObjectId, RefPtr<WebGL##X>> m##X##Map; 95 96 _(Buffer) 97 _(Framebuffer) 98 _(Program) 99 _(Query) 100 _(Renderbuffer) 101 _(Sampler) 102 _(Shader) 103 _(Sync) 104 _(Texture) 105 _(TransformFeedback) 106 _(VertexArray) 107 108 #undef _ 109 110 class AutoResolveT final { 111 friend class HostWebGLContext; 112 113 const HostWebGLContext& mParent; 114 const ObjectId mId; 115 116 public: 117 AutoResolveT(const HostWebGLContext& parent, const ObjectId id) 118 : mParent(parent), mId(id) {} 119 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(); \ 125 } 126 127 _(Buffer) 128 _(Framebuffer) 129 _(Program) 130 _(Query) 131 _(Renderbuffer) 132 _(Sampler) 133 _(Shader) 134 _(Sync) 135 _(Texture) 136 _(TransformFeedback) 137 _(VertexArray) 138 139 #undef _ 140 template <typename T> 141 MOZ_IMPLICIT operator T*() const { 142 T* coercer = nullptr; 143 return As(coercer); 144 } 145 146 template <typename T> 147 MOZ_IMPLICIT operator const T*() const { 148 T* coercer = nullptr; 149 return As(coercer); 150 } 151 }; 152 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); 158 } 159 160 // ------------------------------------------------------------------------- 161 // Host-side methods. Calls in the client are forwarded to the host. 162 // ------------------------------------------------------------------------- 163 164 public: 165 // ------------------------- Composition ------------------------- 166 167 void SetCompositableHost(RefPtr<layers::CompositableHost>& compositableHost) { 168 mContext->SetCompositableHost(compositableHost); 169 } 170 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); 174 } 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); 178 } 179 void WaitForTxn(const layers::RemoteTextureOwnerId aOwnerId, 180 const layers::RemoteTextureTxnType txnType, 181 const layers::RemoteTextureTxnId txnId) { 182 mContext->WaitForTxn(aOwnerId, txnType, txnId); 183 } 184 void EndOfFrame() const { return (void)mContext->EndOfFrame(); } 185 Maybe<layers::SurfaceDescriptor> GetFrontBuffer(ObjectId xrFb, 186 const bool webvr) const; 187 188 // - 189 190 Maybe<uvec2> FrontBufferSnapshotInto(Maybe<Range<uint8_t>> dest) const { 191 return mContext->FrontBufferSnapshotInto(dest); 192 } 193 194 Maybe<uvec2> FrontBufferSnapshotInto( 195 std::shared_ptr<gl::SharedSurface>& front, 196 Maybe<Range<uint8_t>> dest) const { 197 return mContext->FrontBufferSnapshotInto(front, dest); 198 } 199 200 void ClearVRSwapChain() const { mContext->ClearVRSwapChain(); } 201 202 // - 203 204 void SetDrawingBufferColorSpace(const dom::PredefinedColorSpace val) const { 205 mContext->SetDrawingBufferColorSpace(val); 206 } 207 void SetUnpackColorSpace(const dom::PredefinedColorSpace val) const { 208 mContext->SetUnpackColorSpace(val); 209 } 210 void Resize(const uvec2& size) { return mContext->Resize(size); } 211 212 uvec2 DrawingBufferSize() { return mContext->DrawingBufferSize(); } 213 214 void OnMemoryPressure() { return mContext->OnMemoryPressure(); } 215 216 void DidRefresh() { mContext->DidRefresh(); } 217 218 void GenerateError(const GLenum error, const std::string& text) const { 219 mContext->GenerateErrorImpl(error, text); 220 } 221 222 void OnContextLoss(webgl::ContextLossReason); 223 224 void RequestExtension(const WebGLExtensionID ext) { 225 mContext->RequestExtension(ext); 226 } 227 228 // - 229 // Child-ward 230 231 void JsWarning(const std::string&) const; 232 233 // - 234 // Creation and destruction 235 236 void CreateBuffer(ObjectId); 237 void CreateFramebuffer(ObjectId); 238 bool CreateOpaqueFramebuffer(ObjectId, 239 const webgl::OpaqueFramebufferOptions& options); 240 void CreateProgram(ObjectId); 241 void CreateQuery(ObjectId); 242 void CreateRenderbuffer(ObjectId); 243 void CreateSampler(ObjectId); 244 void CreateShader(ObjectId, GLenum type); 245 void CreateSync(ObjectId); 246 void CreateTexture(ObjectId); 247 void CreateTransformFeedback(ObjectId); 248 void CreateVertexArray(ObjectId); 249 250 void DeleteBuffer(ObjectId); 251 void DeleteFramebuffer(ObjectId); 252 void DeleteProgram(ObjectId); 253 void DeleteQuery(ObjectId); 254 void DeleteRenderbuffer(ObjectId); 255 void DeleteSampler(ObjectId); 256 void DeleteShader(ObjectId); 257 void DeleteSync(ObjectId); 258 void DeleteTexture(ObjectId); 259 void DeleteTransformFeedback(ObjectId); 260 void DeleteVertexArray(ObjectId); 261 262 // ------------------------- GL State ------------------------- 263 bool IsContextLost() const { return mContext->IsContextLost(); } 264 265 void SetEnabled(GLenum cap, Maybe<GLuint> i, bool val) const { 266 mContext->SetEnabled(cap, i, val); 267 } 268 269 Maybe<double> GetNumber(GLenum pname) const { 270 return mContext->GetParameter(pname); 271 } 272 273 Maybe<std::string> GetString(GLenum pname) const { 274 return mContext->GetString(pname); 275 } 276 277 void AttachShader(ObjectId prog, ObjectId shader) const { 278 const auto pProg = ById<WebGLProgram>(prog); 279 const auto pShader = ById<WebGLShader>(shader); 280 if (!pProg || !pShader) return; 281 mContext->AttachShader(*pProg, *pShader); 282 } 283 284 void BindAttribLocation(ObjectId id, GLuint location, 285 const std::string& name) const { 286 const auto obj = ById<WebGLProgram>(id); 287 if (!obj) return; 288 mContext->BindAttribLocation(*obj, location, name); 289 } 290 291 void BindFramebuffer(GLenum target, ObjectId id) const { 292 mContext->BindFramebuffer(target, AutoResolve(id)); 293 } 294 295 void BlendColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) const { 296 mContext->BlendColor(r, g, b, a); 297 } 298 299 void BlendEquationSeparate(Maybe<GLuint> i, GLenum modeRGB, 300 GLenum modeAlpha) const { 301 mContext->BlendEquationSeparate(i, modeRGB, modeAlpha); 302 } 303 304 void BlendFuncSeparate(Maybe<GLuint> i, GLenum srcRGB, GLenum dstRGB, 305 GLenum srcAlpha, GLenum dstAlpha) const { 306 mContext->BlendFuncSeparate(i, srcRGB, dstRGB, srcAlpha, dstAlpha); 307 } 308 309 GLenum CheckFramebufferStatus(GLenum target) const { 310 return mContext->CheckFramebufferStatus(target); 311 } 312 313 void Clear(GLbitfield mask) const { mContext->Clear(mask); } 314 315 void ClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) const { 316 mContext->ClearColor(r, g, b, a); 317 } 318 319 void ClearDepth(GLclampf v) const { mContext->ClearDepth(v); } 320 321 void ClearStencil(GLint v) const { mContext->ClearStencil(v); } 322 323 void ColorMask(Maybe<GLuint> i, uint8_t mask) const { 324 mContext->ColorMask(i, mask); 325 } 326 327 void CompileShader(const ObjectId id) const { 328 const auto obj = ById<WebGLShader>(id); 329 if (!obj) return; 330 mContext->CompileShader(*obj); 331 } 332 333 void CullFace(GLenum face) const { mContext->CullFace(face); } 334 335 void DepthFunc(GLenum func) const { mContext->DepthFunc(func); } 336 337 void DepthMask(WebGLboolean b) const { mContext->DepthMask(b); } 338 339 void DepthRange(GLclampf zNear, GLclampf zFar) const { 340 mContext->DepthRange(zNear, zFar); 341 } 342 343 void DetachShader(const ObjectId prog, const ObjectId shader) const { 344 const auto pProg = ById<WebGLProgram>(prog); 345 const auto pShader = ById<WebGLShader>(shader); 346 if (!pProg || !pShader) return; 347 mContext->DetachShader(*pProg, *pShader); 348 } 349 350 void Flush() const { mContext->Flush(); } 351 352 void Finish() const { mContext->Finish(); } 353 354 void FramebufferAttach(const GLenum target, const GLenum attachSlot, 355 const GLenum bindImageTarget, const ObjectId id, 356 const GLint mipLevel, const GLint zLayerBase, 357 const GLsizei numViewLayers) const { 358 webgl::FbAttachInfo toAttach; 359 toAttach.rb = AutoResolve(id); 360 toAttach.tex = AutoResolve(id); 361 toAttach.mipLevel = mipLevel; 362 toAttach.zLayer = zLayerBase; 363 if (numViewLayers) { 364 toAttach.zLayerCount = numViewLayers; 365 toAttach.isMultiview = true; 366 } 367 368 mContext->FramebufferAttach(target, attachSlot, bindImageTarget, toAttach); 369 } 370 371 void FrontFace(GLenum mode) const { mContext->FrontFace(mode); } 372 373 Maybe<double> GetBufferParameter(GLenum target, GLenum pname) const { 374 return mContext->GetBufferParameter(target, pname); 375 } 376 377 webgl::CompileResult GetCompileResult(ObjectId id) const { 378 const auto obj = ById<WebGLShader>(id); 379 if (!obj) return {}; 380 return mContext->GetCompileResult(*obj); 381 } 382 383 GLenum GetError() const { return mContext->GetError(); } 384 385 GLint GetFragDataLocation(ObjectId id, const std::string& name) const { 386 const auto obj = ById<WebGLProgram>(id); 387 if (!obj) return -1; 388 return mContext->GetFragDataLocation(*obj, name); 389 } 390 391 Maybe<double> GetFramebufferAttachmentParameter(ObjectId id, 392 GLenum attachment, 393 GLenum pname) const { 394 return mContext->GetFramebufferAttachmentParameter(AutoResolve(id), 395 attachment, pname); 396 } 397 398 webgl::LinkResult GetLinkResult(ObjectId id) const { 399 const auto obj = ById<WebGLProgram>(id); 400 if (!obj) return {}; 401 return mContext->GetLinkResult(*obj); 402 } 403 404 Maybe<double> GetRenderbufferParameter(ObjectId id, GLenum pname) const { 405 const auto obj = ById<WebGLRenderbuffer>(id); 406 if (!obj) return {}; 407 return mContext->GetRenderbufferParameter(*obj, pname); 408 } 409 410 webgl::GetUniformData GetUniform(ObjectId id, uint32_t loc) const { 411 const auto obj = ById<WebGLProgram>(id); 412 if (!obj) return {}; 413 return mContext->GetUniform(*obj, loc); 414 } 415 416 void Hint(GLenum target, GLenum mode) const { mContext->Hint(target, mode); } 417 418 void LineWidth(GLfloat width) const { mContext->LineWidth(width); } 419 420 void LinkProgram(const ObjectId id) const { 421 const auto obj = ById<WebGLProgram>(id); 422 if (!obj) return; 423 mContext->LinkProgram(*obj); 424 } 425 426 void PolygonOffset(GLfloat factor, GLfloat units) const { 427 mContext->PolygonOffset(factor, units); 428 } 429 430 void SampleCoverage(GLclampf value, bool invert) const { 431 mContext->SampleCoverage(value, invert); 432 } 433 434 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) const { 435 mContext->Scissor(x, y, width, height); 436 } 437 438 // TODO: s/nsAString/std::string/ 439 void ShaderSource(const ObjectId id, const std::string& source) const { 440 const auto obj = ById<WebGLShader>(id); 441 if (!obj) return; 442 mContext->ShaderSource(*obj, source); 443 } 444 445 void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, 446 GLuint mask) const { 447 mContext->StencilFuncSeparate(face, func, ref, mask); 448 } 449 void StencilMaskSeparate(GLenum face, GLuint mask) const { 450 mContext->StencilMaskSeparate(face, mask); 451 } 452 void StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, 453 GLenum dppass) const { 454 mContext->StencilOpSeparate(face, sfail, dpfail, dppass); 455 } 456 457 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) const { 458 mContext->Viewport(x, y, width, height); 459 } 460 461 // ------------------------- Buffer Objects ------------------------- 462 void BindBuffer(GLenum target, const ObjectId id) const { 463 mContext->BindBuffer(target, AutoResolve(id)); 464 } 465 466 void BindBufferRange(GLenum target, GLuint index, const ObjectId id, 467 uint64_t offset, uint64_t size) const { 468 GetWebGL2Context()->BindBufferRange(target, index, AutoResolve(id), offset, 469 size); 470 } 471 472 void CopyBufferSubData(GLenum readTarget, GLenum writeTarget, 473 uint64_t readOffset, uint64_t writeOffset, 474 uint64_t size) const { 475 GetWebGL2Context()->CopyBufferSubData(readTarget, writeTarget, readOffset, 476 writeOffset, size); 477 } 478 479 bool GetBufferSubData(GLenum target, uint64_t srcByteOffset, 480 const Range<uint8_t>& dest) const { 481 return GetWebGL2Context()->GetBufferSubData(target, srcByteOffset, dest); 482 } 483 484 void BufferData(GLenum target, const Span<const uint8_t>& srcData, 485 GLenum usage) const { 486 mContext->BufferData(target, srcData.size(), srcData.data(), usage); 487 } 488 489 void BufferData_SizeOnly(GLenum target, size_t byteSize, GLenum usage) const { 490 mContext->BufferData(target, byteSize, nullptr, usage); 491 } 492 493 void BufferSubData(GLenum target, uint64_t dstByteOffset, 494 const Span<const uint8_t>& srcData, 495 bool unsynchronized = false) const { 496 mContext->BufferSubData(target, dstByteOffset, srcData.size(), 497 srcData.data(), unsynchronized); 498 } 499 500 // -------------------------- Framebuffer Objects -------------------------- 501 void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 502 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 503 GLbitfield mask, GLenum filter) const { 504 GetWebGL2Context()->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, 505 dstY0, dstX1, dstY1, mask, filter); 506 } 507 508 void InvalidateFramebuffer(GLenum target, 509 const Span<const GLenum>& attachments) const { 510 GetWebGL2Context()->InvalidateFramebuffer(target, attachments); 511 } 512 513 void InvalidateSubFramebuffer(GLenum target, 514 const Span<const GLenum>& attachments, GLint x, 515 GLint y, GLsizei width, GLsizei height) const { 516 GetWebGL2Context()->InvalidateSubFramebuffer(target, attachments, x, y, 517 width, height); 518 } 519 520 void ReadBuffer(GLenum mode) const { GetWebGL2Context()->ReadBuffer(mode); } 521 522 // ----------------------- Renderbuffer objects ----------------------- 523 Maybe<std::vector<int32_t>> GetInternalformatParameter(GLenum target, 524 GLenum internalformat, 525 GLenum pname) const { 526 return GetWebGL2Context()->GetInternalformatParameter( 527 target, internalformat, pname); 528 } 529 530 void RenderbufferStorageMultisample(ObjectId id, uint32_t samples, 531 GLenum internalFormat, uint32_t width, 532 uint32_t height) const { 533 const auto obj = ById<WebGLRenderbuffer>(id); 534 if (!obj) return; 535 mContext->RenderbufferStorageMultisample(*obj, samples, internalFormat, 536 width, height); 537 } 538 539 // --------------------------- Texture objects --------------------------- 540 void ActiveTexture(uint32_t texUnit) const { 541 mContext->ActiveTexture(texUnit); 542 } 543 544 void BindTexture(GLenum texTarget, const ObjectId id) const { 545 mContext->BindTexture(texTarget, AutoResolve(id)); 546 } 547 548 void GenerateMipmap(GLenum texTarget) const { 549 mContext->GenerateMipmap(texTarget); 550 } 551 552 // CompressedTexSubImage if `sub` 553 void CompressedTexImage(bool sub, GLenum imageTarget, uint32_t level, 554 GLenum format, const uvec3& offset, const uvec3& size, 555 const Span<const uint8_t>& src, 556 const uint32_t pboImageSize, 557 const Maybe<uint64_t>& pboOffset) const { 558 mContext->CompressedTexImage(sub, imageTarget, level, format, offset, size, 559 src, pboImageSize, pboOffset); 560 } 561 562 // CopyTexSubImage if `!respecFormat` 563 void CopyTexImage(GLenum imageTarget, uint32_t level, GLenum respecFormat, 564 const uvec3& dstOffset, const ivec2& srcOffset, 565 const uvec2& size) const { 566 mContext->CopyTexImage(imageTarget, level, respecFormat, dstOffset, 567 srcOffset, size); 568 } 569 570 // TexSubImage if `!respecFormat` 571 void TexImage(uint32_t level, GLenum respecFormat, const uvec3& offset, 572 const webgl::PackingInfo& pi, 573 const webgl::TexUnpackBlobDesc& src) const { 574 mContext->TexImage(level, respecFormat, offset, pi, src); 575 } 576 577 void TexStorage(GLenum texTarget, uint32_t levels, GLenum internalFormat, 578 const uvec3& size) const { 579 GetWebGL2Context()->TexStorage(texTarget, levels, internalFormat, size); 580 } 581 582 Maybe<double> GetTexParameter(ObjectId id, GLenum pname) const { 583 const auto obj = ById<WebGLTexture>(id); 584 if (!obj) return {}; 585 return mContext->GetTexParameter(*obj, pname); 586 } 587 588 void TexParameter_base(GLenum texTarget, GLenum pname, 589 const FloatOrInt& param) const { 590 mContext->TexParameter_base(texTarget, pname, param); 591 } 592 593 // ------------------- Programs and shaders -------------------------------- 594 void UseProgram(ObjectId id) const { mContext->UseProgram(AutoResolve(id)); } 595 596 bool ValidateProgram(ObjectId id) const { 597 const auto obj = ById<WebGLProgram>(id); 598 if (!obj) return false; 599 return mContext->ValidateProgram(*obj); 600 } 601 602 // ------------------------ Uniforms and attributes ------------------------ 603 604 void UniformData(uint32_t loc, bool transpose, 605 const Span<const webgl::UniformDataVal>& data) const { 606 mContext->UniformData(loc, transpose, data); 607 } 608 609 void VertexAttrib4T(GLuint index, const webgl::TypedQuad& data) const { 610 mContext->VertexAttrib4T(index, data); 611 } 612 613 void VertexAttribDivisor(GLuint index, GLuint divisor) const { 614 mContext->VertexAttribDivisor(index, divisor); 615 } 616 617 Maybe<double> GetIndexedParameter(GLenum target, GLuint index) const { 618 return GetWebGL2Context()->GetIndexedParameter(target, index); 619 } 620 621 void UniformBlockBinding(const ObjectId id, GLuint uniformBlockIndex, 622 GLuint uniformBlockBinding) const { 623 const auto obj = ById<WebGLProgram>(id); 624 if (!obj) return; 625 GetWebGL2Context()->UniformBlockBinding(*obj, uniformBlockIndex, 626 uniformBlockBinding); 627 } 628 629 void EnableVertexAttribArray(GLuint index) const { 630 mContext->EnableVertexAttribArray(index); 631 } 632 633 void DisableVertexAttribArray(GLuint index) const { 634 mContext->DisableVertexAttribArray(index); 635 } 636 637 Maybe<double> GetVertexAttrib(GLuint index, GLenum pname) const { 638 return mContext->GetVertexAttrib(index, pname); 639 } 640 641 void VertexAttribPointer(GLuint index, 642 const webgl::VertAttribPointerDesc& desc) const { 643 mContext->VertexAttribPointer(index, desc); 644 } 645 646 // --------------------------- Buffer Operations -------------------------- 647 void ClearBufferTv(GLenum buffer, GLint drawBuffer, 648 const webgl::TypedQuad& data) const { 649 GetWebGL2Context()->ClearBufferTv(buffer, drawBuffer, data); 650 } 651 652 void ClearBufferfi(GLenum buffer, GLint drawBuffer, GLfloat depth, 653 GLint stencil) const { 654 GetWebGL2Context()->ClearBufferfi(buffer, drawBuffer, depth, stencil); 655 } 656 657 // ------------------------------ Readback ------------------------------- 658 void ReadPixelsPbo(const webgl::ReadPixelsDesc& desc, 659 const uint64_t offset) const { 660 mContext->ReadPixelsPbo(desc, offset); 661 } 662 663 webgl::ReadPixelsResult ReadPixelsInto(const webgl::ReadPixelsDesc& desc, 664 const Range<uint8_t>& dest) const { 665 return mContext->ReadPixelsInto(desc, dest); 666 } 667 668 // ----------------------------- Sampler ----------------------------------- 669 670 void BindSampler(GLuint unit, ObjectId id) const { 671 GetWebGL2Context()->BindSampler(unit, AutoResolve(id)); 672 } 673 674 void SamplerParameteri(ObjectId id, GLenum pname, GLint param) const { 675 const auto obj = ById<WebGLSampler>(id); 676 if (!obj) return; 677 GetWebGL2Context()->SamplerParameteri(*obj, pname, param); 678 } 679 680 void SamplerParameterf(ObjectId id, GLenum pname, GLfloat param) const { 681 const auto obj = ById<WebGLSampler>(id); 682 if (!obj) return; 683 GetWebGL2Context()->SamplerParameterf(*obj, pname, param); 684 } 685 686 Maybe<double> GetSamplerParameter(ObjectId id, GLenum pname) const { 687 const auto obj = ById<WebGLSampler>(id); 688 if (!obj) return {}; 689 return GetWebGL2Context()->GetSamplerParameter(*obj, pname); 690 } 691 692 // ------------------------------- GL Sync --------------------------------- 693 694 GLenum ClientWaitSync(ObjectId id, GLbitfield flags, GLuint64 timeout) const { 695 const auto obj = ById<WebGLSync>(id); 696 if (!obj) return LOCAL_GL_WAIT_FAILED; 697 return GetWebGL2Context()->ClientWaitSync(*obj, flags, timeout); 698 } 699 700 // -------------------------- Transform Feedback --------------------------- 701 void BindTransformFeedback(ObjectId id) const { 702 GetWebGL2Context()->BindTransformFeedback(AutoResolve(id)); 703 } 704 705 void BeginTransformFeedback(GLenum primitiveMode) const { 706 GetWebGL2Context()->BeginTransformFeedback(primitiveMode); 707 } 708 709 void EndTransformFeedback() const { 710 GetWebGL2Context()->EndTransformFeedback(); 711 } 712 713 void PauseTransformFeedback() const { 714 GetWebGL2Context()->PauseTransformFeedback(); 715 } 716 717 void ResumeTransformFeedback() const { 718 GetWebGL2Context()->ResumeTransformFeedback(); 719 } 720 721 void TransformFeedbackVaryings(ObjectId id, 722 const std::vector<std::string>& varyings, 723 GLenum bufferMode) const { 724 const auto obj = ById<WebGLProgram>(id); 725 if (!obj) return; 726 GetWebGL2Context()->TransformFeedbackVaryings(*obj, varyings, bufferMode); 727 } 728 729 // -------------------------- Opaque Framebuffers --------------------------- 730 void SetFramebufferIsInOpaqueRAF(ObjectId id, bool value) { 731 WebGLFramebuffer* fb = AutoResolve(id); 732 if (fb) { 733 fb->mInOpaqueRAF = value; 734 } 735 } 736 737 // ------------------------------------------------------------------------- 738 // Host-side extension methods. Calls in the client are forwarded to the 739 // host. Some extension methods are also available in WebGL2 Contexts. For 740 // them, the final parameter is a boolean indicating if the call originated 741 // from an extension. 742 // ------------------------------------------------------------------------- 743 744 // Misc. Extensions 745 void DrawBuffers(const std::vector<GLenum>& buffers) const { 746 mContext->DrawBuffers(buffers); 747 } 748 749 // VertexArrayObjectEXT 750 void BindVertexArray(ObjectId id) const { 751 mContext->BindVertexArray(AutoResolve(id)); 752 } 753 754 // InstancedElementsEXT 755 void DrawArraysInstanced(GLenum mode, GLint first, GLsizei vertCount, 756 GLsizei primCount) const { 757 mContext->DrawArraysInstanced(mode, first, vertCount, primCount); 758 } 759 760 void DrawElementsInstanced(GLenum mode, GLsizei vertCount, GLenum type, 761 WebGLintptr offset, GLsizei primCount) const { 762 mContext->DrawElementsInstanced(mode, vertCount, type, offset, primCount); 763 } 764 765 // GLQueryEXT 766 void BeginQuery(GLenum target, ObjectId id) const { 767 const auto obj = ById<WebGLQuery>(id); 768 if (!obj) return; 769 mContext->BeginQuery(target, *obj); 770 } 771 772 void EndQuery(GLenum target) const { mContext->EndQuery(target); } 773 774 void QueryCounter(ObjectId id) const { 775 const auto obj = ById<WebGLQuery>(id); 776 if (!obj) return; 777 mContext->QueryCounter(*obj); 778 } 779 780 Maybe<double> GetQueryParameter(ObjectId id, GLenum pname) const { 781 const auto obj = ById<WebGLQuery>(id); 782 if (!obj) return {}; 783 return mContext->GetQueryParameter(*obj, pname); 784 } 785 786 // WEBGL_provoking_vertex 787 void ProvokingVertex(const webgl::ProvokingVertex mode) const { 788 mContext->ProvokingVertex(mode); 789 } 790 791 // ------------------------------------------------------------------------- 792 // Client-side methods. Calls in the Host are forwarded to the client. 793 // ------------------------------------------------------------------------- 794 public: 795 void OnLostContext(); 796 void OnRestoredContext(); 797 798 protected: 799 WebGL2Context* GetWebGL2Context() const { 800 MOZ_RELEASE_ASSERT(mContext->IsWebGL2(), "Requires WebGL2 context"); 801 return static_cast<WebGL2Context*>(mContext.get()); 802 } 803 }; 804 805 } // namespace mozilla 806 807 #endif // HOSTWEBGLCONTEXT_H_