|
Packit |
f0b94e |
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
Packit |
f0b94e |
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
Packit |
f0b94e |
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
Packit |
f0b94e |
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#include "WebGLShader.h"
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#include "GLSLANG/ShaderLang.h"
|
|
Packit |
f0b94e |
#include "GLContext.h"
|
|
Packit |
f0b94e |
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
|
Packit |
f0b94e |
#include "mozilla/MemoryReporting.h"
|
|
Packit |
f0b94e |
#include "nsPrintfCString.h"
|
|
Packit |
f0b94e |
#include "nsString.h"
|
|
Packit |
f0b94e |
#include "prenv.h"
|
|
Packit |
f0b94e |
#include "WebGLContext.h"
|
|
Packit |
f0b94e |
#include "WebGLObjectModel.h"
|
|
Packit |
f0b94e |
#include "WebGLShaderValidator.h"
|
|
Packit |
f0b94e |
#include "WebGLValidateStrings.h"
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
namespace mozilla {
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// On success, writes to out_validator and out_translatedSource.
|
|
Packit |
f0b94e |
// On failure, writes to out_translationLog.
|
|
Packit |
f0b94e |
static bool Translate(const nsACString& source,
|
|
Packit |
f0b94e |
webgl::ShaderValidator* validator,
|
|
Packit |
f0b94e |
nsACString* const out_translationLog,
|
|
Packit |
f0b94e |
nsACString* const out_translatedSource) {
|
|
Packit |
f0b94e |
if (!validator->ValidateAndTranslate(source.BeginReading())) {
|
|
Packit |
f0b94e |
validator->GetInfoLog(out_translationLog);
|
|
Packit |
f0b94e |
return false;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// Success
|
|
Packit |
f0b94e |
validator->GetOutput(out_translatedSource);
|
|
Packit |
f0b94e |
return true;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
template <size_t N>
|
|
Packit |
f0b94e |
static bool SubstringStartsWith(const std::string& testStr, size_t offset,
|
|
Packit |
f0b94e |
const char (&refStr)[N]) {
|
|
Packit |
f0b94e |
for (size_t i = 0; i < N - 1; i++) {
|
|
Packit |
f0b94e |
if (testStr[offset + i] != refStr[i]) return false;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
return true;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/* On success, writes to out_translatedSource.
|
|
Packit |
f0b94e |
* On failure, writes to out_translationLog.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* Requirements:
|
|
Packit |
f0b94e |
* #version is either omitted, `#version 100`, or `version 300 es`.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
static bool TranslateWithoutValidation(const nsACString& sourceNS,
|
|
Packit |
f0b94e |
bool isWebGL2,
|
|
Packit |
f0b94e |
nsACString* const out_translationLog,
|
|
Packit |
f0b94e |
nsACString* const out_translatedSource) {
|
|
Packit |
f0b94e |
std::string source = sourceNS.BeginReading();
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
size_t versionStrStart = source.find("#version");
|
|
Packit |
f0b94e |
size_t versionStrLen;
|
|
Packit |
f0b94e |
uint32_t glesslVersion;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (versionStrStart != std::string::npos) {
|
|
Packit |
f0b94e |
static const char versionStr100[] = "#version 100\n";
|
|
Packit |
f0b94e |
static const char versionStr300es[] = "#version 300 es\n";
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (isWebGL2 &&
|
|
Packit |
f0b94e |
SubstringStartsWith(source, versionStrStart, versionStr300es)) {
|
|
Packit |
f0b94e |
glesslVersion = 300;
|
|
Packit |
f0b94e |
versionStrLen = strlen(versionStr300es);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
} else if (SubstringStartsWith(source, versionStrStart, versionStr100)) {
|
|
Packit |
f0b94e |
glesslVersion = 100;
|
|
Packit |
f0b94e |
versionStrLen = strlen(versionStr100);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
} else {
|
|
Packit |
f0b94e |
nsPrintfCString error("#version, if declared, must be %s.",
|
|
Packit |
f0b94e |
isWebGL2 ? "`100` or `300 es`" : "`100`");
|
|
Packit |
f0b94e |
*out_translationLog = error;
|
|
Packit |
f0b94e |
return false;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
} else {
|
|
Packit |
f0b94e |
versionStrStart = 0;
|
|
Packit |
f0b94e |
versionStrLen = 0;
|
|
Packit |
f0b94e |
glesslVersion = 100;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
std::string reversionedSource = source;
|
|
Packit |
f0b94e |
reversionedSource.erase(versionStrStart, versionStrLen);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
switch (glesslVersion) {
|
|
Packit |
f0b94e |
case 100:
|
|
Packit |
f0b94e |
/* According to ARB_ES2_compatibility extension glsl
|
|
Packit |
f0b94e |
* should accept #version 100 for ES 2 shaders. */
|
|
Packit |
f0b94e |
reversionedSource.insert(versionStrStart, "#version 100\n");
|
|
Packit |
f0b94e |
break;
|
|
Packit |
f0b94e |
case 300:
|
|
Packit |
f0b94e |
reversionedSource.insert(versionStrStart, "#version 330\n");
|
|
Packit |
f0b94e |
break;
|
|
Packit |
f0b94e |
default:
|
|
Packit |
f0b94e |
MOZ_CRASH("GFX: Bad `glesslVersion`.");
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
out_translatedSource->Assign(reversionedSource.c_str(),
|
|
Packit |
f0b94e |
reversionedSource.length());
|
|
Packit |
f0b94e |
return true;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
static void GetCompilationStatusAndLog(gl::GLContext* gl, GLuint shader,
|
|
Packit |
f0b94e |
bool* const out_success,
|
|
Packit |
f0b94e |
nsACString* const out_log) {
|
|
Packit |
f0b94e |
GLint compileStatus = LOCAL_GL_FALSE;
|
|
Packit |
f0b94e |
gl->fGetShaderiv(shader, LOCAL_GL_COMPILE_STATUS, &compileStatus);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// It's simpler if we always get the log.
|
|
Packit |
f0b94e |
GLint lenWithNull = 0;
|
|
Packit |
f0b94e |
gl->fGetShaderiv(shader, LOCAL_GL_INFO_LOG_LENGTH, &lenWithNull);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (lenWithNull > 1) {
|
|
Packit |
f0b94e |
// SetLength takes the length without the null.
|
|
Packit |
f0b94e |
out_log->SetLength(lenWithNull - 1);
|
|
Packit |
f0b94e |
gl->fGetShaderInfoLog(shader, lenWithNull, nullptr,
|
|
Packit |
f0b94e |
out_log->BeginWriting());
|
|
Packit |
f0b94e |
} else {
|
|
Packit |
f0b94e |
out_log->SetLength(0);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
*out_success = (compileStatus == LOCAL_GL_TRUE);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
////////////////////////////////////////////////////////////////////////////////
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
WebGLShader::WebGLShader(WebGLContext* webgl, GLenum type)
|
|
Packit |
f0b94e |
: WebGLRefCountedObject(webgl),
|
|
Packit |
f0b94e |
mGLName(webgl->gl->fCreateShader(type)),
|
|
Packit |
f0b94e |
mType(type),
|
|
Packit |
f0b94e |
mTranslationSuccessful(false),
|
|
Packit |
f0b94e |
mCompilationSuccessful(false) {
|
|
Packit |
f0b94e |
mContext->mShaders.insertBack(this);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
WebGLShader::~WebGLShader() { DeleteOnce(); }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
void WebGLShader::ShaderSource(const nsAString& source) {
|
|
Packit |
f0b94e |
const char funcName[] = "shaderSource";
|
|
Packit |
f0b94e |
nsString sourceWithoutComments;
|
|
Packit |
f0b94e |
if (!TruncateComments(source, &sourceWithoutComments)) {
|
|
Packit |
f0b94e |
mContext->ErrorOutOfMemory(
|
|
Packit |
f0b94e |
"%s: Failed to alloc for empting comment contents.", funcName);
|
|
Packit |
f0b94e |
return;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (!ValidateGLSLPreprocString(mContext, funcName, sourceWithoutComments))
|
|
Packit |
f0b94e |
return;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// We checked that the source stripped of comments is in the
|
|
Packit |
f0b94e |
// 7-bit ASCII range, so we can skip the NS_IsAscii() check.
|
|
Packit |
f0b94e |
const NS_LossyConvertUTF16toASCII cleanSource(sourceWithoutComments);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (PR_GetEnv("MOZ_WEBGL_DUMP_SHADERS")) {
|
|
Packit |
f0b94e |
printf_stderr("////////////////////////////////////////\n");
|
|
Packit |
f0b94e |
printf_stderr("// MOZ_WEBGL_DUMP_SHADERS:\n");
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// Wow - Roll Your Own Foreach-Lines because printf_stderr has a hard-coded
|
|
Packit |
f0b94e |
// internal size, so long strings are truncated.
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
const size_t maxChunkSize = 1024 - 1; // -1 for null-term.
|
|
Packit |
f0b94e |
const UniqueBuffer buf(moz_xmalloc(maxChunkSize + 1)); // +1 for null-term
|
|
Packit |
f0b94e |
const auto bufBegin = (char*)buf.get();
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
size_t chunkStart = 0;
|
|
Packit |
f0b94e |
while (chunkStart != cleanSource.Length()) {
|
|
Packit |
f0b94e |
const auto chunkEnd =
|
|
Packit |
f0b94e |
std::min(chunkStart + maxChunkSize, size_t(cleanSource.Length()));
|
|
Packit |
f0b94e |
const auto chunkSize = chunkEnd - chunkStart;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
memcpy(bufBegin, cleanSource.BeginReading() + chunkStart, chunkSize);
|
|
Packit |
f0b94e |
bufBegin[chunkSize + 1] = '\0';
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
printf_stderr("%s", bufBegin);
|
|
Packit |
f0b94e |
chunkStart += chunkSize;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
printf_stderr("////////////////////////////////////////\n");
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
mSource = source;
|
|
Packit |
f0b94e |
mCleanSource = cleanSource;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
void WebGLShader::CompileShader() {
|
|
Packit |
f0b94e |
mValidator = nullptr;
|
|
Packit |
f0b94e |
mTranslationSuccessful = false;
|
|
Packit |
f0b94e |
mCompilationSuccessful = false;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
gl::GLContext* gl = mContext->gl;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
mValidator.reset(mContext->CreateShaderValidator(mType));
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
bool success;
|
|
Packit |
f0b94e |
if (mValidator) {
|
|
Packit |
f0b94e |
success = Translate(mCleanSource, mValidator.get(), &mValidationLog,
|
|
Packit |
f0b94e |
&mTranslatedSource);
|
|
Packit |
f0b94e |
} else {
|
|
Packit |
f0b94e |
success = TranslateWithoutValidation(mCleanSource, mContext->IsWebGL2(),
|
|
Packit |
f0b94e |
&mValidationLog, &mTranslatedSource);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (!success) return;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
mTranslationSuccessful = true;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
const char* const parts[] = {mTranslatedSource.BeginReading()};
|
|
Packit |
f0b94e |
gl->fShaderSource(mGLName, ArrayLength(parts), parts, nullptr);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
gl->fCompileShader(mGLName);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
GetCompilationStatusAndLog(gl, mGLName, &mCompilationSuccessful,
|
|
Packit |
f0b94e |
&mCompilationLog);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
void WebGLShader::GetShaderInfoLog(nsAString* out) const {
|
|
Packit |
f0b94e |
const nsCString& log =
|
|
Packit |
f0b94e |
!mTranslationSuccessful ? mValidationLog : mCompilationLog;
|
|
Packit |
f0b94e |
CopyASCIItoUTF16(log, *out);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
JS::Value WebGLShader::GetShaderParameter(GLenum pname) const {
|
|
Packit |
f0b94e |
switch (pname) {
|
|
Packit |
f0b94e |
case LOCAL_GL_SHADER_TYPE:
|
|
Packit |
f0b94e |
return JS::NumberValue(mType);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
case LOCAL_GL_DELETE_STATUS:
|
|
Packit |
f0b94e |
return JS::BooleanValue(IsDeleteRequested());
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
case LOCAL_GL_COMPILE_STATUS:
|
|
Packit |
f0b94e |
return JS::BooleanValue(mCompilationSuccessful);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
default:
|
|
Packit |
f0b94e |
mContext->ErrorInvalidEnumInfo("getShaderParameter: `pname`", pname);
|
|
Packit |
f0b94e |
return JS::NullValue();
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
void WebGLShader::GetShaderSource(nsAString* out) const {
|
|
Packit |
f0b94e |
out->SetIsVoid(false);
|
|
Packit |
f0b94e |
*out = mSource;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
void WebGLShader::GetShaderTranslatedSource(nsAString* out) const {
|
|
Packit |
f0b94e |
out->SetIsVoid(false);
|
|
Packit |
f0b94e |
CopyASCIItoUTF16(mTranslatedSource, *out);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
////////////////////////////////////////////////////////////////////////////////
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
bool WebGLShader::CanLinkTo(const WebGLShader* prev,
|
|
Packit |
f0b94e |
nsCString* const out_log) const {
|
|
Packit |
f0b94e |
if (!mValidator) return true;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
return mValidator->CanLinkTo(prev->mValidator.get(), out_log);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
size_t WebGLShader::CalcNumSamplerUniforms() const {
|
|
Packit |
f0b94e |
if (mValidator) return mValidator->CalcNumSamplerUniforms();
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// TODO
|
|
Packit |
f0b94e |
return 0;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
size_t WebGLShader::NumAttributes() const {
|
|
Packit |
f0b94e |
if (mValidator) return mValidator->NumAttributes();
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// TODO
|
|
Packit |
f0b94e |
return 0;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
void WebGLShader::BindAttribLocation(GLuint prog, const nsCString& userName,
|
|
Packit |
f0b94e |
GLuint index) const {
|
|
Packit |
f0b94e |
std::string userNameStr(userName.BeginReading());
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
const std::string* mappedNameStr = &userNameStr;
|
|
Packit |
f0b94e |
if (mValidator)
|
|
Packit |
f0b94e |
mValidator->FindAttribMappedNameByUserName(userNameStr, &mappedNameStr);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
mContext->gl->fBindAttribLocation(prog, index, mappedNameStr->c_str());
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
bool WebGLShader::FindAttribUserNameByMappedName(
|
|
Packit |
f0b94e |
const nsACString& mappedName, nsCString* const out_userName) const {
|
|
Packit |
f0b94e |
if (!mValidator) return false;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
const std::string mappedNameStr(mappedName.BeginReading());
|
|
Packit |
f0b94e |
const std::string* userNameStr;
|
|
Packit |
f0b94e |
if (!mValidator->FindAttribUserNameByMappedName(mappedNameStr, &userNameStr))
|
|
Packit |
f0b94e |
return false;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
*out_userName = userNameStr->c_str();
|
|
Packit |
f0b94e |
return true;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
bool WebGLShader::FindVaryingByMappedName(const nsACString& mappedName,
|
|
Packit |
f0b94e |
nsCString* const out_userName,
|
|
Packit |
f0b94e |
bool* const out_isArray) const {
|
|
Packit |
f0b94e |
if (!mValidator) return false;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
const std::string mappedNameStr(mappedName.BeginReading());
|
|
Packit |
f0b94e |
std::string userNameStr;
|
|
Packit |
f0b94e |
if (!mValidator->FindVaryingByMappedName(mappedNameStr, &userNameStr,
|
|
Packit |
f0b94e |
out_isArray))
|
|
Packit |
f0b94e |
return false;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
*out_userName = userNameStr.c_str();
|
|
Packit |
f0b94e |
return true;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
bool WebGLShader::FindUniformByMappedName(const nsACString& mappedName,
|
|
Packit |
f0b94e |
nsCString* const out_userName,
|
|
Packit |
f0b94e |
bool* const out_isArray) const {
|
|
Packit |
f0b94e |
if (!mValidator) return false;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
const std::string mappedNameStr(mappedName.BeginReading(),
|
|
Packit |
f0b94e |
mappedName.Length());
|
|
Packit |
f0b94e |
std::string userNameStr;
|
|
Packit |
f0b94e |
if (!mValidator->FindUniformByMappedName(mappedNameStr, &userNameStr,
|
|
Packit |
f0b94e |
out_isArray))
|
|
Packit |
f0b94e |
return false;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
*out_userName = userNameStr.c_str();
|
|
Packit |
f0b94e |
return true;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
bool WebGLShader::UnmapUniformBlockName(
|
|
Packit |
f0b94e |
const nsACString& baseMappedName, nsCString* const out_baseUserName) const {
|
|
Packit |
f0b94e |
if (!mValidator) {
|
|
Packit |
f0b94e |
*out_baseUserName = baseMappedName;
|
|
Packit |
f0b94e |
return true;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
return mValidator->UnmapUniformBlockName(baseMappedName, out_baseUserName);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
void WebGLShader::EnumerateFragOutputs(
|
|
Packit |
f0b94e |
std::map<nsCString, const nsCString>& out_FragOutputs) const {
|
|
Packit |
f0b94e |
out_FragOutputs.clear();
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (!mValidator) {
|
|
Packit |
f0b94e |
return;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
mValidator->EnumerateFragOutputs(out_FragOutputs);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
void WebGLShader::MapTransformFeedbackVaryings(
|
|
Packit |
f0b94e |
const std::vector<nsString>& varyings,
|
|
Packit |
f0b94e |
std::vector<std::string>* out_mappedVaryings) const {
|
|
Packit |
f0b94e |
MOZ_ASSERT(mType == LOCAL_GL_VERTEX_SHADER);
|
|
Packit |
f0b94e |
MOZ_ASSERT(out_mappedVaryings);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
out_mappedVaryings->clear();
|
|
Packit |
f0b94e |
out_mappedVaryings->reserve(varyings.size());
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
for (const auto& wideUserName : varyings) {
|
|
Packit |
f0b94e |
const NS_LossyConvertUTF16toASCII mozUserName(
|
|
Packit |
f0b94e |
wideUserName); // Don't validate here.
|
|
Packit |
f0b94e |
const std::string userName(mozUserName.BeginReading(),
|
|
Packit |
f0b94e |
mozUserName.Length());
|
|
Packit |
f0b94e |
const std::string* pMappedName = &userName;
|
|
Packit |
f0b94e |
if (mValidator) {
|
|
Packit |
f0b94e |
mValidator->FindVaryingMappedNameByUserName(userName, &pMappedName);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
out_mappedVaryings->push_back(*pMappedName);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
////////////////////////////////////////////////////////////////////////////////
|
|
Packit |
f0b94e |
// Boilerplate
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
JSObject* WebGLShader::WrapObject(JSContext* js,
|
|
Packit |
f0b94e |
JS::Handle<JSObject*> givenProto) {
|
|
Packit |
f0b94e |
return dom::WebGLShaderBinding::Wrap(js, this, givenProto);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
size_t WebGLShader::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const {
|
|
Packit |
f0b94e |
size_t validatorSize = mValidator ? mallocSizeOf(mValidator.get()) : 0;
|
|
Packit |
f0b94e |
return mallocSizeOf(this) +
|
|
Packit |
f0b94e |
mSource.SizeOfExcludingThisIfUnshared(mallocSizeOf) +
|
|
Packit |
f0b94e |
mCleanSource.SizeOfExcludingThisIfUnshared(mallocSizeOf) +
|
|
Packit |
f0b94e |
validatorSize +
|
|
Packit |
f0b94e |
mValidationLog.SizeOfExcludingThisIfUnshared(mallocSizeOf) +
|
|
Packit |
f0b94e |
mTranslatedSource.SizeOfExcludingThisIfUnshared(mallocSizeOf) +
|
|
Packit |
f0b94e |
mCompilationLog.SizeOfExcludingThisIfUnshared(mallocSizeOf);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
void WebGLShader::Delete() {
|
|
Packit |
f0b94e |
gl::GLContext* gl = mContext->GL();
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
gl->fDeleteShader(mGLName);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
LinkedListElement<WebGLShader>::removeFrom(mContext->mShaders);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLShader)
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLShader, AddRef)
|
|
Packit |
f0b94e |
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLShader, Release)
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
} // namespace mozilla
|