gecko-dev/dom/canvas/WebGLProgram.h

244 строки
7.5 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 <map>
#include <set>
#include <string>
#include <vector>
#include "mozilla/LinkedList.h"
#include "mozilla/RefPtr.h"
#include "mozilla/WeakPtr.h"
#include "nsString.h"
#include "nsWrapperCache.h"
#include "CacheInvalidator.h"
#include "WebGLContext.h"
#include "WebGLObjectModel.h"
namespace mozilla {
class ErrorResult;
class WebGLActiveInfo;
class WebGLProgram;
class WebGLShader;
class WebGLUniformLocation;
namespace dom {
template <typename>
struct Nullable;
class OwningUnsignedLongOrUint32ArrayOrBoolean;
template <typename>
class Sequence;
} // namespace dom
namespace webgl {
enum class TextureBaseType : uint8_t;
struct AttribInfo final {
const RefPtr<WebGLActiveInfo> mActiveInfo;
const GLint mLoc; // -1 for active built-ins
};
struct UniformInfo final {
typedef decltype(WebGLContext::mBound2DTextures) TexListT;
const RefPtr<WebGLActiveInfo> mActiveInfo;
const TexListT* const mSamplerTexList;
const webgl::TextureBaseType mTexBaseType;
const bool mIsShadowSampler;
std::vector<uint32_t> mSamplerValues;
protected:
static const TexListT* GetTexList(WebGLActiveInfo* activeInfo);
public:
explicit UniformInfo(WebGLActiveInfo* activeInfo);
};
struct UniformBlockInfo final {
const nsCString mUserName;
const nsCString mMappedName;
const uint32_t mDataSize;
const IndexedBufferBinding* mBinding;
UniformBlockInfo(WebGLContext* webgl, const nsACString& userName,
const nsACString& mappedName, uint32_t dataSize)
: mUserName(userName),
mMappedName(mappedName),
mDataSize(dataSize),
mBinding(&webgl->mIndexedUniformBufferBindings[0]) {}
};
struct FragOutputInfo final {
const uint8_t loc;
const nsCString userName;
const nsCString mappedName;
const TextureBaseType baseType;
};
struct CachedDrawFetchLimits final {
uint64_t maxVerts;
uint64_t maxInstances;
};
struct LinkedProgramInfo final : public RefCounted<LinkedProgramInfo>,
public SupportsWeakPtr<LinkedProgramInfo>,
public CacheInvalidator {
friend class mozilla::WebGLProgram;
MOZ_DECLARE_REFCOUNTED_TYPENAME(LinkedProgramInfo)
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(LinkedProgramInfo)
//////
WebGLProgram* const prog;
const GLenum transformFeedbackBufferMode;
std::vector<AttribInfo> attribs;
std::vector<UniformInfo*> uniforms; // Owns its contents.
std::vector<UniformBlockInfo*> uniformBlocks; // Owns its contents.
std::vector<RefPtr<WebGLActiveInfo>> transformFeedbackVaryings;
std::unordered_map<uint8_t, const FragOutputInfo> fragOutputs;
// Needed for draw call validation.
std::vector<UniformInfo*> uniformSamplers;
mutable std::vector<size_t> componentsPerTFVert;
bool attrib0Active;
//////
mutable CacheWeakMap<const WebGLVertexArray*, CachedDrawFetchLimits>
mDrawFetchCache;
const CachedDrawFetchLimits* GetDrawFetchLimits() const;
//////
explicit LinkedProgramInfo(WebGLProgram* prog);
~LinkedProgramInfo();
bool FindAttrib(const nsCString& userName,
const AttribInfo** const out_info) const;
bool FindUniform(const nsCString& userName, nsCString* const out_mappedName,
size_t* const out_arrayIndex,
UniformInfo** const out_info) const;
};
} // namespace webgl
class WebGLProgram final : public nsWrapperCache,
public WebGLRefCountedObject<WebGLProgram>,
public LinkedListElement<WebGLProgram> {
friend class WebGLTransformFeedback;
friend struct webgl::LinkedProgramInfo;
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLProgram)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLProgram)
explicit WebGLProgram(WebGLContext* webgl);
void Delete();
// GL funcs
void AttachShader(WebGLShader* shader);
void BindAttribLocation(GLuint index, const nsAString& name);
void DetachShader(const WebGLShader* shader);
already_AddRefed<WebGLActiveInfo> GetActiveAttrib(GLuint index) const;
already_AddRefed<WebGLActiveInfo> GetActiveUniform(GLuint index) const;
void GetAttachedShaders(nsTArray<RefPtr<WebGLShader>>* const out) const;
GLint GetAttribLocation(const nsAString& name) const;
GLint GetFragDataLocation(const nsAString& name) const;
void GetProgramInfoLog(nsAString* const out) const;
JS::Value GetProgramParameter(GLenum pname) const;
GLuint GetUniformBlockIndex(const nsAString& name) const;
void GetActiveUniformBlockName(GLuint uniformBlockIndex,
nsAString& name) const;
JS::Value GetActiveUniformBlockParam(GLuint uniformBlockIndex,
GLenum pname) const;
JS::Value GetActiveUniformBlockActiveUniforms(
JSContext* cx, GLuint uniformBlockIndex,
ErrorResult* const out_error) const;
already_AddRefed<WebGLUniformLocation> GetUniformLocation(
const nsAString& name) const;
void GetUniformIndices(const dom::Sequence<nsString>& uniformNames,
dom::Nullable<nsTArray<GLuint>>& retval) const;
void UniformBlockBinding(GLuint uniformBlockIndex,
GLuint uniformBlockBinding) const;
void LinkProgram();
bool UseProgram() const;
void ValidateProgram() const;
////////////////
bool FindAttribUserNameByMappedName(const nsACString& mappedName,
nsCString* const out_userName) const;
bool FindVaryingByMappedName(const nsACString& mappedName,
nsCString* const out_userName,
bool* const out_isArray) const;
bool FindUniformByMappedName(const nsACString& mappedName,
nsCString* const out_userName,
bool* const out_isArray) const;
bool UnmapUniformBlockName(const nsCString& mappedName,
nsCString* const out_userName) const;
void TransformFeedbackVaryings(const dom::Sequence<nsString>& varyings,
GLenum bufferMode);
already_AddRefed<WebGLActiveInfo> GetTransformFeedbackVarying(
GLuint index) const;
void EnumerateFragOutputs(
std::map<nsCString, const nsCString>& out_FragOutputs) const;
bool IsLinked() const { return mMostRecentLinkInfo; }
const webgl::LinkedProgramInfo* LinkInfo() const {
return mMostRecentLinkInfo.get();
}
const auto& FragShader() const { return mFragShader; }
WebGLContext* GetParentObject() const { return mContext; }
virtual JSObject* WrapObject(JSContext* js,
JS::Handle<JSObject*> givenProto) override;
private:
~WebGLProgram();
void LinkAndUpdate();
bool ValidateForLink();
bool ValidateAfterTentativeLink(nsCString* const out_linkLog) const;
public:
const GLuint mGLName;
private:
WebGLRefPtr<WebGLShader> mVertShader;
WebGLRefPtr<WebGLShader> mFragShader;
size_t mNumActiveTFOs;
std::map<nsCString, GLuint> mNextLink_BoundAttribLocs;
std::vector<nsString> mNextLink_TransformFeedbackVaryings;
GLenum mNextLink_TransformFeedbackBufferMode;
nsCString mLinkLog;
RefPtr<const webgl::LinkedProgramInfo> mMostRecentLinkInfo;
};
} // namespace mozilla
#endif // WEBGL_PROGRAM_H_