зеркало из https://github.com/mozilla/gecko-dev.git
217 строки
5.3 KiB
C++
217 строки
5.3 KiB
C++
/* -*- 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 "mozilla/RefPtr.h"
|
|
#include "mozilla/Vector.h"
|
|
#include "mozilla/WeakPtr.h"
|
|
|
|
#include "CacheInvalidator.h"
|
|
#include "WebGLObjectModel.h"
|
|
#include "WebGLTypes.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_
|