WebGLProgram.h (5455B)
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 WEBGL_PROGRAM_H_ 7 #define WEBGL_PROGRAM_H_ 8 9 #include <bitset> 10 #include <map> 11 #include <memory> 12 #include <vector> 13 14 #include "CacheInvalidator.h" 15 #include "WebGLObjectModel.h" 16 #include "WebGLTypes.h" 17 #include "mozilla/RefPtr.h" 18 #include "mozilla/Vector.h" 19 #include "mozilla/WeakPtr.h" 20 21 namespace mozilla { 22 class ErrorResult; 23 class WebGLContext; 24 class WebGLProgram; 25 class WebGLShader; 26 27 namespace dom { 28 template <typename> 29 struct Nullable; 30 class OwningUnsignedLongOrUint32ArrayOrBoolean; 31 template <typename> 32 class Sequence; 33 } // namespace dom 34 35 namespace webgl { 36 37 enum class TextureBaseType : uint8_t; 38 39 struct UniformBlockInfo final { 40 const ActiveUniformBlockInfo& info; 41 const IndexedBufferBinding* binding = nullptr; 42 }; 43 44 struct FragOutputInfo final { 45 const uint8_t loc; 46 const std::string userName; 47 const std::string mappedName; 48 const TextureBaseType baseType; 49 }; 50 51 struct CachedDrawFetchLimits final { 52 uint64_t maxVerts = UINT64_MAX; 53 uint64_t maxInstances = UINT64_MAX; 54 std::vector<BufferAndIndex> usedBuffers; 55 56 CachedDrawFetchLimits() = default; 57 explicit CachedDrawFetchLimits(const CachedDrawFetchLimits&) = delete; 58 CachedDrawFetchLimits(CachedDrawFetchLimits&&) = default; 59 60 CachedDrawFetchLimits& operator=(CachedDrawFetchLimits&&) = default; 61 }; 62 63 // - 64 65 void UniformAs1fv(gl::GLContext& gl, GLint location, GLsizei count, 66 bool transpose, const void* any); 67 68 struct ActiveUniformValidationInfo final { 69 const ActiveUniformInfo& info; 70 bool isArray = false; 71 uint8_t channelsPerElem = 0; 72 decltype(&UniformAs1fv) pfn = nullptr; 73 74 static ActiveUniformValidationInfo Make(const ActiveUniformInfo&); 75 }; 76 77 struct SamplerUniformInfo final { 78 const nsTArray<RefPtr<WebGLTexture>>& texListForType; 79 // = const decltype(WebGLContext::mBound2DTextures)& 80 const webgl::TextureBaseType texBaseType; 81 const bool isShadowSampler; 82 Vector<uint8_t, 8> texUnits = decltype(texUnits)(); 83 }; 84 85 struct LocationInfo final { 86 const ActiveUniformValidationInfo info; 87 const uint32_t indexIntoUniform; 88 SamplerUniformInfo* const samplerInfo; 89 90 auto PrettyName() const { 91 auto ret = info.info.name; 92 if (info.isArray) { 93 ret += "["; 94 ret += std::to_string(indexIntoUniform); 95 ret += "]"; 96 } 97 return ret; 98 } 99 }; 100 101 // - 102 103 struct LinkedProgramInfo final : public RefCounted<LinkedProgramInfo>, 104 public SupportsWeakPtr, 105 public CacheInvalidator { 106 friend class mozilla::WebGLProgram; 107 108 MOZ_DECLARE_REFCOUNTED_TYPENAME(LinkedProgramInfo) 109 110 ////// 111 112 WebGLProgram* const prog; 113 const GLenum transformFeedbackBufferMode; 114 115 std::bitset<kMaxDrawBuffers> hasOutput = 0; 116 std::unordered_map<uint8_t, const FragOutputInfo> fragOutputs; 117 uint8_t zLayerCount = 1; 118 119 mutable std::vector<size_t> componentsPerTFVert; 120 121 bool attrib0Active = false; 122 GLint webgl_gl_VertexID_Offset = -1; // Location 123 124 // - 125 126 std::map<std::string, std::string> nameMap; 127 webgl::LinkActiveInfo active; 128 129 std::vector<std::unique_ptr<SamplerUniformInfo>> samplerUniforms; 130 std::unordered_map<uint32_t, LocationInfo> locationMap; 131 132 mutable std::vector<UniformBlockInfo> uniformBlocks; 133 134 ////// 135 136 private: 137 mutable CachedDrawFetchLimits mScratchFetchLimits; 138 139 public: 140 const CachedDrawFetchLimits* GetDrawFetchLimits() const; 141 142 ////// 143 144 explicit LinkedProgramInfo(WebGLProgram* prog); 145 ~LinkedProgramInfo(); 146 }; 147 148 } // namespace webgl 149 150 class WebGLProgram final : public WebGLContextBoundObject { 151 friend class WebGLTransformFeedback; 152 friend struct webgl::LinkedProgramInfo; 153 154 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(WebGLProgram, override) 155 156 public: 157 explicit WebGLProgram(WebGLContext* webgl); 158 159 void Delete(); 160 161 // GL funcs 162 void AttachShader(WebGLShader& shader); 163 void BindAttribLocation(GLuint index, const std::string& name); 164 void DetachShader(const WebGLShader& shader); 165 void UniformBlockBinding(GLuint uniformBlockIndex, 166 GLuint uniformBlockBinding) const; 167 168 void LinkProgram(); 169 bool UseProgram() const; 170 bool ValidateProgram() const; 171 172 //////////////// 173 174 void TransformFeedbackVaryings(const std::vector<std::string>& varyings, 175 GLenum bufferMode); 176 177 bool IsLinked() const { return mMostRecentLinkInfo; } 178 179 const webgl::LinkedProgramInfo* LinkInfo() const { 180 return mMostRecentLinkInfo.get(); 181 } 182 183 const auto& VertShader() const { return mVertShader; } 184 const auto& FragShader() const { return mFragShader; } 185 186 const auto& LinkLog() const { return mLinkLog; } 187 188 private: 189 ~WebGLProgram(); 190 191 void LinkAndUpdate(); 192 bool ValidateForLink(); 193 bool ValidateAfterTentativeLink(std::string* const out_linkLog) const; 194 195 public: 196 const GLuint mGLName; 197 198 private: 199 RefPtr<WebGLShader> mVertShader; 200 RefPtr<WebGLShader> mFragShader; 201 size_t mNumActiveTFOs; 202 203 std::map<std::string, GLuint> mNextLink_BoundAttribLocs; 204 205 std::vector<std::string> mNextLink_TransformFeedbackVaryings; 206 GLenum mNextLink_TransformFeedbackBufferMode; 207 208 std::string mLinkLog; 209 RefPtr<const webgl::LinkedProgramInfo> mMostRecentLinkInfo; 210 }; 211 212 } // namespace mozilla 213 214 #endif // WEBGL_PROGRAM_H_