1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
|
/* -*- 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 <memory>
#include <set>
#include <vector>
#include "CacheInvalidator.h"
#include "WebGLObjectModel.h"
#include "WebGLTypes.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Vector.h"
#include "mozilla/WeakPtr.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 nsTArray<RefPtr<WebGLTexture>>& texListForType;
// = const decltype(WebGLContext::mBound2DTextures)&
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_
|