/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef WEBGL2CONTEXT_H_ #define WEBGL2CONTEXT_H_ #include "WebGLContext.h" namespace mozilla { class ErrorResult; class WebGLSampler; class WebGLSync; class WebGLTransformFeedback; class WebGLVertexArrayObject; namespace dom { class OwningUnsignedLongOrUint32ArrayOrBoolean; class OwningWebGLBufferOrLongLong; } // namespace dom class WebGL2Context : public WebGLContext { public: virtual ~WebGL2Context(); static bool IsSupported(); static WebGL2Context* Create(); virtual bool IsWebGL2() const override { return true; } // ------------------------------------------------------------------------- // IMPLEMENT nsWrapperCache virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override; // ------------------------------------------------------------------------- // Buffer objects - WebGL2ContextBuffers.cpp void CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); private: template<typename BufferT> void GetBufferSubDataT(GLenum target, GLintptr offset, const BufferT& data); public: void GetBufferSubData(GLenum target, GLintptr srcByteOffset, const dom::ArrayBufferView& dstData, GLuint dstElemOffset, GLuint dstElemCountOverride); // ------------------------------------------------------------------------- // Framebuffer objects - WebGL2ContextFramebuffers.cpp void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); void FramebufferTextureLayer(GLenum target, GLenum attachment, WebGLTexture* texture, GLint level, GLint layer); virtual JS::Value GetFramebufferAttachmentParameter(JSContext* cx, GLenum target, GLenum attachment, GLenum pname, ErrorResult& rv) override; // Make the inline version from the superclass visible here. using WebGLContext::GetFramebufferAttachmentParameter; void InvalidateFramebuffer(GLenum target, const dom::Sequence<GLenum>& attachments, ErrorResult& rv); void InvalidateSubFramebuffer (GLenum target, const dom::Sequence<GLenum>& attachments, GLint x, GLint y, GLsizei width, GLsizei height, ErrorResult& rv); void ReadBuffer(GLenum mode); // ------------------------------------------------------------------------- // Renderbuffer objects - WebGL2ContextRenderbuffers.cpp void GetInternalformatParameter(JSContext*, GLenum target, GLenum internalformat, GLenum pname, JS::MutableHandleValue retval, ErrorResult& rv); void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); // ------------------------------------------------------------------------- // Texture objects - WebGL2ContextTextures.cpp void TexStorage2D(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height) { const char funcName[] = "TexStorage2D"; const uint8_t funcDims = 2; const GLsizei depth = 1; TexStorage(funcName, funcDims, target, levels, internalFormat, width, height, depth); } void TexStorage3D(GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth) { const char funcName[] = "TexStorage3D"; const uint8_t funcDims = 3; TexStorage(funcName, funcDims, target, levels, internalFormat, width, height, depth); } protected: void TexStorage(const char* funcName, uint8_t funcDims, GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth); //////////////////////////////////// public: template<typename T> void CompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, const T& anySrc, GLuint viewElemOffset = 0, GLuint viewElemLengthOverride = 0) { const char funcName[] = "compressedTexImage3D"; const uint8_t funcDims = 3; const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride); CompressedTexImage(funcName, funcDims, target, level, internalFormat, width, height, depth, border, src); } template<typename T> void CompressedTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width, GLsizei height, GLsizei depth, GLenum unpackFormat, const T& anySrc, GLuint viewElemOffset = 0, GLuint viewElemLengthOverride = 0) { const char funcName[] = "compressedTexSubImage3D"; const uint8_t funcDims = 3; const TexImageSourceAdapter src(&anySrc, viewElemOffset, viewElemLengthOverride); CompressedTexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset, width, height, depth, unpackFormat, src); } //////////////////////////////////// void CopyTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLint zOffset, GLint x, GLint y, GLsizei width, GLsizei height) { const char funcName[] = "copyTexSubImage3D"; const uint8_t funcDims = 3; CopyTexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset, x, y, width, height); } //////////////////////////////////// template<typename T> void TexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum unpackFormat, GLenum unpackType, const T& anySrc, ErrorResult& out_error) { const TexImageSourceAdapter src(&anySrc, &out_error); TexImage3D(target, level, internalFormat, width, height, depth, border, unpackFormat, unpackType, src); } void TexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum unpackFormat, GLenum unpackType, const dom::ArrayBufferView& view, GLuint viewElemOffset, ErrorResult&) { const TexImageSourceAdapter src(&view, viewElemOffset); TexImage3D(target, level, internalFormat, width, height, depth, border, unpackFormat, unpackType, src); } protected: void TexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum unpackFormat, GLenum unpackType, const TexImageSource& src) { const char funcName[] = "texImage3D"; const uint8_t funcDims = 3; TexImage(funcName, funcDims, target, level, internalFormat, width, height, depth, border, unpackFormat, unpackType, src); } //////////////////////////////////// public: template<typename T> void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width, GLsizei height, GLsizei depth, GLenum unpackFormat, GLenum unpackType, const T& anySrc, ErrorResult& out_error) { const TexImageSourceAdapter src(&anySrc, &out_error); TexSubImage3D(target, level, xOffset, yOffset, zOffset, width, height, depth, unpackFormat, unpackType, src); } void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width, GLsizei height, GLsizei depth, GLenum unpackFormat, GLenum unpackType, const dom::Nullable<dom::ArrayBufferView>& maybeSrcView, GLuint srcElemOffset, ErrorResult&) { if (IsContextLost()) return; if (!ValidateNonNull("texSubImage3D", maybeSrcView)) return; const auto& srcView = maybeSrcView.Value(); const TexImageSourceAdapter src(&srcView, srcElemOffset); TexSubImage3D(target, level, xOffset, yOffset, zOffset, width, height, depth, unpackFormat, unpackType, src); } protected: void TexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width, GLsizei height, GLsizei depth, GLenum unpackFormat, GLenum unpackType, const TexImageSource& src) { const char funcName[] = "texSubImage3D"; const uint8_t funcDims = 3; TexSubImage(funcName, funcDims, target, level, xOffset, yOffset, zOffset, width, height, depth, unpackFormat, unpackType, src); } public: // ------------------------------------------------------------------------- // Programs and shaders - WebGL2ContextPrograms.cpp GLint GetFragDataLocation(const WebGLProgram& program, const nsAString& name); // ------------------------------------------------------------------------- // Uniforms and attributes - WebGL2ContextUniforms.cpp void VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); //////////////// // GL 3.0 & ES 3.0 void VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w, const char* funcName = nullptr); void VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w, const char* funcName = nullptr); void VertexAttribI4iv(GLuint index, const Int32ListU& list) { const auto& arr = Int32Arr::From(list); if (!ValidateAttribArraySetter("vertexAttribI4iv", 4, arr.elemCount)) return; const auto& itr = arr.elemBytes; VertexAttribI4i(index, itr[0], itr[1], itr[2], itr[3]); } void VertexAttribI4uiv(GLuint index, const Uint32ListU& list) { const auto& arr = Uint32Arr::From(list); if (!ValidateAttribArraySetter("vertexAttribI4uiv", 4, arr.elemCount)) return; const auto& itr = arr.elemBytes; VertexAttribI4ui(index, itr[0], itr[1], itr[2], itr[3]); } // ------------------------------------------------------------------------- // Writing to the drawing buffer /* Implemented in WebGLContext void VertexAttribDivisor(GLuint index, GLuint divisor); void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount); void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei instanceCount); */ void DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, WebGLintptr byteOffset) { const char funcName[] = "drawRangeElements"; if (IsContextLost()) return; if (end < start) { ErrorInvalidValue("%s: end must be >= start.", funcName); return; } DrawElements(mode, count, type, byteOffset, funcName); } // ------------------------------------------------------------------------ // Multiple Render Targets - WebGL2ContextMRTs.cpp /* Implemented in WebGLContext void DrawBuffers(const dom::Sequence<GLenum>& buffers); */ private: bool ValidateClearBuffer(const char* funcName, GLenum buffer, GLint drawBuffer, size_t availElemCount, GLuint elemOffset, GLenum funcType); void ClearBufferfv(GLenum buffer, GLint drawBuffer, const Float32Arr& src, GLuint srcElemOffset); void ClearBufferiv(GLenum buffer, GLint drawBuffer, const Int32Arr& src, GLuint srcElemOffset); void ClearBufferuiv(GLenum buffer, GLint drawBuffer, const Uint32Arr& src, GLuint srcElemOffset); public: void ClearBufferfv(GLenum buffer, GLint drawBuffer, const Float32ListU& list, GLuint srcElemOffset) { ClearBufferfv(buffer, drawBuffer, Float32Arr::From(list), srcElemOffset); } void ClearBufferiv(GLenum buffer, GLint drawBuffer, const Int32ListU& list, GLuint srcElemOffset) { ClearBufferiv(buffer, drawBuffer, Int32Arr::From(list), srcElemOffset); } void ClearBufferuiv(GLenum buffer, GLint drawBuffer, const Uint32ListU& list, GLuint srcElemOffset) { ClearBufferuiv(buffer, drawBuffer, Uint32Arr::From(list), srcElemOffset); } void ClearBufferfi(GLenum buffer, GLint drawBuffer, GLfloat depth, GLint stencil); // ------------------------------------------------------------------------- // Sampler Objects - WebGL2ContextSamplers.cpp already_AddRefed<WebGLSampler> CreateSampler(); void DeleteSampler(WebGLSampler* sampler); bool IsSampler(const WebGLSampler* sampler); void BindSampler(GLuint unit, WebGLSampler* sampler); void SamplerParameteri(WebGLSampler& sampler, GLenum pname, GLint param); void SamplerParameterf(WebGLSampler& sampler, GLenum pname, GLfloat param); void GetSamplerParameter(JSContext*, const WebGLSampler& sampler, GLenum pname, JS::MutableHandleValue retval); // ------------------------------------------------------------------------- // Sync objects - WebGL2ContextSync.cpp const GLuint64 kMaxClientWaitSyncTimeoutNS = 1000 * 1000 * 1000; // 1000ms in ns. already_AddRefed<WebGLSync> FenceSync(GLenum condition, GLbitfield flags); bool IsSync(const WebGLSync* sync); void DeleteSync(WebGLSync* sync); GLenum ClientWaitSync(const WebGLSync& sync, GLbitfield flags, GLuint64 timeout); void WaitSync(const WebGLSync& sync, GLbitfield flags, GLint64 timeout); void GetSyncParameter(JSContext*, const WebGLSync& sync, GLenum pname, JS::MutableHandleValue retval); // ------------------------------------------------------------------------- // Transform Feedback - WebGL2ContextTransformFeedback.cpp already_AddRefed<WebGLTransformFeedback> CreateTransformFeedback(); void DeleteTransformFeedback(WebGLTransformFeedback* tf); bool IsTransformFeedback(const WebGLTransformFeedback* tf); void BindTransformFeedback(GLenum target, WebGLTransformFeedback* tf); void BeginTransformFeedback(GLenum primitiveMode); void EndTransformFeedback(); void PauseTransformFeedback(); void ResumeTransformFeedback(); void TransformFeedbackVaryings(WebGLProgram& program, const dom::Sequence<nsString>& varyings, GLenum bufferMode); already_AddRefed<WebGLActiveInfo> GetTransformFeedbackVarying(const WebGLProgram& program, GLuint index); // ------------------------------------------------------------------------- // Uniform Buffer Objects and Transform Feedback Buffers - WebGL2ContextUniforms.cpp // TODO(djg): Implemented in WebGLContext /* void BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer); void BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer, GLintptr offset, GLsizeiptr size); */ virtual JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv) override; // Make the inline version from the superclass visible here. using WebGLContext::GetParameter; void GetIndexedParameter(JSContext* cx, GLenum target, GLuint index, JS::MutableHandleValue retval, ErrorResult& rv); void GetUniformIndices(const WebGLProgram& program, const dom::Sequence<nsString>& uniformNames, dom::Nullable< nsTArray<GLuint> >& retval); void GetActiveUniforms(JSContext* cx, const WebGLProgram& program, const dom::Sequence<GLuint>& uniformIndices, GLenum pname, JS::MutableHandleValue retval); GLuint GetUniformBlockIndex(const WebGLProgram& program, const nsAString& uniformBlockName); void GetActiveUniformBlockParameter(JSContext*, const WebGLProgram& program, GLuint uniformBlockIndex, GLenum pname, JS::MutableHandleValue retval, ErrorResult& rv); void GetActiveUniformBlockName(const WebGLProgram& program, GLuint uniformBlockIndex, nsAString& retval); void UniformBlockBinding(WebGLProgram& program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); // ------------------------------------------------------------------------- // Vertex Array Object - WebGL2ContextVAOs.cpp // TODO(djg): Implemented in WebGLContext /* already_AddRefed<WebGLVertexArrayObject> CreateVertexArray(); void DeleteVertexArray(WebGLVertexArrayObject* vertexArray); bool IsVertexArray(WebGLVertexArrayObject* vertexArray); void BindVertexArray(WebGLVertexArrayObject* vertexArray); */ private: WebGL2Context(); virtual UniquePtr<webgl::FormatUsageAuthority> CreateFormatUsage(gl::GLContext* gl) const override; virtual bool IsTexParamValid(GLenum pname) const override; void UpdateBoundQuery(GLenum target, WebGLQuery* query); // CreateVertexArrayImpl is assumed to be infallible. virtual WebGLVertexArray* CreateVertexArrayImpl() override; virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, uint32_t* alignment, const char* info) override; virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) override; }; } // namespace mozilla #endif