diff options
Diffstat (limited to 'dom/canvas/WebGLProgram.h')
-rw-r--r-- | dom/canvas/WebGLProgram.h | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/dom/canvas/WebGLProgram.h b/dom/canvas/WebGLProgram.h new file mode 100644 index 0000000000..f247c9090a --- /dev/null +++ b/dom/canvas/WebGLProgram.h @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 WEBGL_PROGRAM_H_ +#define WEBGL_PROGRAM_H_ + +#include <bitset> +#include <map> +#include <set> +#include <vector> + +#include "mozilla/RefPtr.h" +#include "mozilla/Vector.h" +#include "mozilla/WeakPtr.h" + +#include "CacheInvalidator.h" +#include "WebGLContext.h" +#include "WebGLObjectModel.h" + +namespace mozilla { +class ErrorResult; +class WebGLContext; +class WebGLProgram; +class WebGLShader; + +namespace dom { +template <typename> +struct Nullable; +class OwningUnsignedLongOrUint32ArrayOrBoolean; +template <typename> +class Sequence; +} // namespace dom + +namespace webgl { + +enum class TextureBaseType : uint8_t; + +struct UniformBlockInfo final { + const ActiveUniformBlockInfo& info; + const IndexedBufferBinding* binding = nullptr; +}; + +struct FragOutputInfo final { + const uint8_t loc; + const std::string userName; + const std::string mappedName; + const TextureBaseType baseType; +}; + +struct CachedDrawFetchLimits final { + uint64_t maxVerts = UINT64_MAX; + uint64_t maxInstances = UINT64_MAX; + std::vector<BufferAndIndex> usedBuffers; + + CachedDrawFetchLimits() = default; + explicit CachedDrawFetchLimits(const CachedDrawFetchLimits&) = delete; + CachedDrawFetchLimits(CachedDrawFetchLimits&&) = default; + + CachedDrawFetchLimits& operator=(CachedDrawFetchLimits&&) = default; +}; + +// - + +void UniformAs1fv(gl::GLContext& gl, GLint location, GLsizei count, + bool transpose, const void* any); + +struct ActiveUniformValidationInfo final { + const ActiveUniformInfo& info; + bool isArray = false; + uint8_t channelsPerElem = 0; + decltype(&UniformAs1fv) pfn = nullptr; + + static ActiveUniformValidationInfo Make(const ActiveUniformInfo&); +}; + +struct SamplerUniformInfo final { + const decltype(WebGLContext::mBound2DTextures)& texListForType; + const webgl::TextureBaseType texBaseType; + const bool isShadowSampler; + Vector<uint8_t, 8> texUnits = decltype(texUnits)(); +}; + +struct LocationInfo final { + const ActiveUniformValidationInfo info; + const uint32_t indexIntoUniform; + SamplerUniformInfo* const samplerInfo; + + auto PrettyName() const { + auto ret = info.info.name; + if (info.isArray) { + ret += "["; + ret += std::to_string(indexIntoUniform); + ret += "]"; + } + return ret; + } +}; + +// - + +struct LinkedProgramInfo final : public RefCounted<LinkedProgramInfo>, + public SupportsWeakPtr, + public CacheInvalidator { + friend class mozilla::WebGLProgram; + + MOZ_DECLARE_REFCOUNTED_TYPENAME(LinkedProgramInfo) + + ////// + + WebGLProgram* const prog; + const GLenum transformFeedbackBufferMode; + + std::bitset<kMaxDrawBuffers> hasOutput = 0; + std::unordered_map<uint8_t, const FragOutputInfo> fragOutputs; + uint8_t zLayerCount = 1; + + mutable std::vector<size_t> componentsPerTFVert; + + bool attrib0Active = false; + GLint webgl_gl_VertexID_Offset = -1; // Location + + // - + + std::map<std::string, std::string> nameMap; + webgl::LinkActiveInfo active; + + std::vector<std::unique_ptr<SamplerUniformInfo>> samplerUniforms; + std::unordered_map<uint32_t, LocationInfo> locationMap; + + mutable std::vector<UniformBlockInfo> uniformBlocks; + + ////// + + private: + mutable CachedDrawFetchLimits mScratchFetchLimits; + + public: + const CachedDrawFetchLimits* GetDrawFetchLimits() const; + + ////// + + explicit LinkedProgramInfo(WebGLProgram* prog); + ~LinkedProgramInfo(); +}; + +} // namespace webgl + +class WebGLProgram final : public WebGLContextBoundObject { + friend class WebGLTransformFeedback; + friend struct webgl::LinkedProgramInfo; + + MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(WebGLProgram, override) + + public: + explicit WebGLProgram(WebGLContext* webgl); + + void Delete(); + + // GL funcs + void AttachShader(WebGLShader& shader); + void BindAttribLocation(GLuint index, const std::string& name); + void DetachShader(const WebGLShader& shader); + void UniformBlockBinding(GLuint uniformBlockIndex, + GLuint uniformBlockBinding) const; + + void LinkProgram(); + bool UseProgram() const; + bool ValidateProgram() const; + + //////////////// + + void TransformFeedbackVaryings(const std::vector<std::string>& varyings, + GLenum bufferMode); + + bool IsLinked() const { return mMostRecentLinkInfo; } + + const webgl::LinkedProgramInfo* LinkInfo() const { + return mMostRecentLinkInfo.get(); + } + + const auto& VertShader() const { return mVertShader; } + const auto& FragShader() const { return mFragShader; } + + const auto& LinkLog() const { return mLinkLog; } + + private: + ~WebGLProgram(); + + void LinkAndUpdate(); + bool ValidateForLink(); + bool ValidateAfterTentativeLink(std::string* const out_linkLog) const; + + public: + const GLuint mGLName; + + private: + RefPtr<WebGLShader> mVertShader; + RefPtr<WebGLShader> mFragShader; + size_t mNumActiveTFOs; + + std::map<std::string, GLuint> mNextLink_BoundAttribLocs; + + std::vector<std::string> mNextLink_TransformFeedbackVaryings; + GLenum mNextLink_TransformFeedbackBufferMode; + + std::string mLinkLog; + RefPtr<const webgl::LinkedProgramInfo> mMostRecentLinkInfo; +}; + +} // namespace mozilla + +#endif // WEBGL_PROGRAM_H_ |