mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1072680 - Untangle the mixup of formats vs internalformats in the WebGL implementation - r=jgilbert
This commit is contained in:
parent
bbaadc6b16
commit
2ff4bedf68
@ -17,6 +17,7 @@
|
||||
#include "WebGLActiveInfo.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLRenderbuffer.h"
|
||||
#include "WebGLTexture.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
@ -221,6 +222,7 @@ public:
|
||||
*/
|
||||
static const char *EnumName(GLenum glenum);
|
||||
|
||||
bool IsCompressedTextureFormat(GLenum format);
|
||||
bool IsTextureFormatCompressed(TexInternalFormat format);
|
||||
|
||||
void DummyFramebufferOperation(const char *info);
|
||||
@ -543,9 +545,12 @@ public:
|
||||
// Allow whatever element types the bindings are willing to pass
|
||||
// us in TexSubImage2D
|
||||
template<class ElementType>
|
||||
void TexSubImage2D(GLenum rawTexImageTarget, GLint level,
|
||||
GLint xoffset, GLint yoffset, GLenum format,
|
||||
GLenum type, ElementType& elt, ErrorResult& rv)
|
||||
void TexSubImage2D(GLenum rawTexImageTarget,
|
||||
GLint level,
|
||||
GLint xoffset, GLint yoffset,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
ElementType& elt, ErrorResult& rv)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
@ -565,8 +570,17 @@ public:
|
||||
if (level > maxLevel)
|
||||
return ErrorInvalidValue("texSubImage2D: level %d is too large, max is %d", level, maxLevel);
|
||||
|
||||
WebGLTexture* tex = activeBoundTextureForTexImageTarget(texImageTarget);
|
||||
if (!tex) {
|
||||
return ErrorInvalidOperation("texSubImage2D: no texture bound on active texture unit");
|
||||
}
|
||||
const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||
const TexInternalFormat internalformat = imageInfo.InternalFormat();
|
||||
|
||||
// Trying to handle the video by GPU directly first
|
||||
if (TexImageFromVideoElement(texImageTarget, level, format, format, type, elt)) {
|
||||
if (TexImageFromVideoElement(texImageTarget, level,
|
||||
internalformat.get(), format, type, elt))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@ -580,7 +594,7 @@ public:
|
||||
|
||||
gfx::IntSize size = data->GetSize();
|
||||
uint32_t byteLength = data->Stride() * size.height;
|
||||
return TexSubImage2D_base(texImageTarget, level, xoffset, yoffset,
|
||||
return TexSubImage2D_base(texImageTarget.get(), level, xoffset, yoffset,
|
||||
size.width, size.height,
|
||||
data->Stride(), format, type,
|
||||
data->GetData(), byteLength,
|
||||
@ -1073,7 +1087,7 @@ protected:
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Validation functions (implemented in WebGLContextValidate.cpp)
|
||||
TexFormat BaseTexFormat(TexInternalFormat internalFormat) const;
|
||||
TexInternalFormat BaseTexFormat(TexInternalFormat internalFormat) const;
|
||||
|
||||
bool CreateOffscreenGL(bool forceEnabled);
|
||||
bool InitAndValidateGL();
|
||||
@ -1095,7 +1109,8 @@ protected:
|
||||
bool ValidateGLSLCharacter(char16_t c);
|
||||
bool ValidateGLSLString(const nsAString& string, const char *info);
|
||||
|
||||
bool ValidateCopyTexImage(GLenum format, WebGLTexImageFunc func);
|
||||
bool ValidateCopyTexImage(GLenum internalformat,
|
||||
WebGLTexImageFunc func);
|
||||
bool ValidateTexImage(GLuint dims, TexImageTarget texImageTarget,
|
||||
GLint level, GLenum internalFormat,
|
||||
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
@ -1103,9 +1118,14 @@ protected:
|
||||
GLint border, GLenum format, GLenum type,
|
||||
WebGLTexImageFunc func);
|
||||
bool ValidateTexImageTarget(GLuint dims, GLenum target, WebGLTexImageFunc func);
|
||||
bool ValidateTexImageFormat(GLenum format, WebGLTexImageFunc func);
|
||||
bool ValidateTexImageFormat(GLenum internalformat,
|
||||
WebGLTexImageFunc func);
|
||||
bool ValidateTexImageType(GLenum type, WebGLTexImageFunc func);
|
||||
bool ValidateTexImageFormatAndType(GLenum format, GLenum type, WebGLTexImageFunc func);
|
||||
bool ValidateCompTexImageInternalFormat(GLenum format,
|
||||
WebGLTexImageFunc func);
|
||||
bool ValidateCopyTexImageInternalFormat(GLenum format,
|
||||
WebGLTexImageFunc func);
|
||||
bool ValidateTexImageSize(TexImageTarget target, GLint level,
|
||||
GLint width, GLint height, GLint depth,
|
||||
WebGLTexImageFunc func);
|
||||
@ -1114,16 +1134,17 @@ protected:
|
||||
GLsizei baseWidth, GLsizei baseHeight, GLsizei baseDepth,
|
||||
WebGLTexImageFunc func);
|
||||
|
||||
bool ValidateCompTexImageSize(GLint level, GLenum format,
|
||||
bool ValidateCompTexImageSize(GLint level,
|
||||
GLenum internalformat,
|
||||
GLint xoffset, GLint yoffset,
|
||||
GLsizei width, GLsizei height,
|
||||
GLsizei levelWidth, GLsizei levelHeight,
|
||||
WebGLTexImageFunc func);
|
||||
bool ValidateCompTexImageDataSize(GLint level, GLenum format,
|
||||
bool ValidateCompTexImageDataSize(GLint level,
|
||||
GLenum internalformat,
|
||||
GLsizei width, GLsizei height,
|
||||
uint32_t byteLength, WebGLTexImageFunc func);
|
||||
|
||||
|
||||
static uint32_t GetBitsPerTexel(TexInternalFormat format, TexType type);
|
||||
|
||||
void Invalidate();
|
||||
@ -1132,16 +1153,20 @@ protected:
|
||||
void MakeContextCurrent() const;
|
||||
|
||||
// helpers
|
||||
void TexImage2D_base(TexImageTarget target, GLint level, GLenum internalformat,
|
||||
void TexImage2D_base(TexImageTarget target,
|
||||
GLint level,
|
||||
GLenum internalformat,
|
||||
GLsizei width, GLsizei height, GLsizei srcStrideOrZero, GLint border,
|
||||
GLenum format, GLenum type,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
void *data, uint32_t byteLength,
|
||||
int jsArrayType,
|
||||
WebGLTexelFormat srcFormat, bool srcPremultiplied);
|
||||
void TexSubImage2D_base(TexImageTarget target, GLint level,
|
||||
GLint xoffset, GLint yoffset,
|
||||
GLsizei width, GLsizei height, GLsizei srcStrideOrZero,
|
||||
GLenum format, GLenum type,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
void *pixels, uint32_t byteLength,
|
||||
int jsArrayType,
|
||||
WebGLTexelFormat srcFormat, bool srcPremultiplied);
|
||||
@ -1227,12 +1252,12 @@ protected:
|
||||
* by this glTexImage2D call and returns it */
|
||||
GLenum CheckedTexImage2D(TexImageTarget texImageTarget,
|
||||
GLint level,
|
||||
GLenum internalFormat,
|
||||
TexInternalFormat internalFormat,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLint border,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
TexFormat format,
|
||||
TexType type,
|
||||
const GLvoid *data);
|
||||
|
||||
void ForceLoseContext(bool simulateLosing = false);
|
||||
|
@ -375,7 +375,8 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
||||
if (!ValidateTexImage(2, texImageTarget, level, internalformat,
|
||||
xoffset, yoffset, 0,
|
||||
width, height, 0,
|
||||
0, internalformat, LOCAL_GL_UNSIGNED_BYTE,
|
||||
0,
|
||||
LOCAL_GL_NONE, LOCAL_GL_NONE,
|
||||
func))
|
||||
{
|
||||
return;
|
||||
@ -478,22 +479,20 @@ WebGLContext::CopyTexImage2D(GLenum rawTexImgTarget,
|
||||
|
||||
// copyTexImage2D only generates textures with type = UNSIGNED_BYTE
|
||||
const WebGLTexImageFunc func = WebGLTexImageFunc::CopyTexImage;
|
||||
const GLenum format = internalformat; // WebGL/ES Format
|
||||
const GLenum type = LOCAL_GL_UNSIGNED_BYTE; // WebGL/ES Format
|
||||
|
||||
if (!ValidateTexImageTarget(2, rawTexImgTarget, WebGLTexImageFunc::CopyTexImage))
|
||||
return;
|
||||
|
||||
if (!ValidateTexImage(2, rawTexImgTarget, level, format,
|
||||
if (!ValidateTexImage(2, rawTexImgTarget, level, internalformat,
|
||||
0, 0, 0,
|
||||
width, height, 0,
|
||||
border, format, type,
|
||||
border, LOCAL_GL_NONE, LOCAL_GL_NONE,
|
||||
func))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateCopyTexImage(format, func))
|
||||
if (!ValidateCopyTexImage(internalformat, func))
|
||||
return;
|
||||
|
||||
if (!mBoundFramebuffer)
|
||||
@ -509,14 +508,13 @@ WebGLContext::CopyTexImage2D(GLenum rawTexImgTarget,
|
||||
|
||||
sizeMayChange = width != imageInfo.Width() ||
|
||||
height != imageInfo.Height() ||
|
||||
internalformat != imageInfo.InternalFormat() ||
|
||||
type != imageInfo.Type();
|
||||
internalformat != imageInfo.InternalFormat();
|
||||
}
|
||||
|
||||
if (sizeMayChange)
|
||||
GetAndFlushUnderlyingGLErrors();
|
||||
|
||||
CopyTexSubImage2D_base(texImageTarget, level, format, 0, 0, x, y, width, height, false);
|
||||
CopyTexSubImage2D_base(texImageTarget, level, internalformat, 0, 0, x, y, width, height, false);
|
||||
|
||||
if (sizeMayChange) {
|
||||
GLenum error = GetAndFlushUnderlyingGLErrors();
|
||||
@ -526,7 +524,10 @@ WebGLContext::CopyTexImage2D(GLenum rawTexImgTarget,
|
||||
}
|
||||
}
|
||||
|
||||
tex->SetImageInfo(texImageTarget, level, width, height, internalformat, type,
|
||||
tex->SetImageInfo(texImageTarget, level, width, height,
|
||||
internalformat,
|
||||
LOCAL_GL_UNSIGNED_BYTE, /* dummy, artifact of us storing
|
||||
the wrong data in ImageInfo */
|
||||
WebGLImageDataStatus::InitializedImageData);
|
||||
}
|
||||
|
||||
@ -3298,7 +3299,9 @@ WebGLContext::CompileShader(WebGLShader *shader)
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::CompressedTexImage2D(GLenum rawTexImgTarget, GLint level, GLenum internalformat,
|
||||
WebGLContext::CompressedTexImage2D(GLenum rawTexImgTarget,
|
||||
GLint level,
|
||||
GLenum internalformat,
|
||||
GLsizei width, GLsizei height, GLint border,
|
||||
const ArrayBufferView& view)
|
||||
{
|
||||
@ -3312,7 +3315,8 @@ WebGLContext::CompressedTexImage2D(GLenum rawTexImgTarget, GLint level, GLenum i
|
||||
|
||||
if (!ValidateTexImage(2, rawTexImgTarget, level, internalformat,
|
||||
0, 0, 0, width, height, 0,
|
||||
border, internalformat, LOCAL_GL_UNSIGNED_BYTE,
|
||||
border, LOCAL_GL_NONE,
|
||||
LOCAL_GL_NONE,
|
||||
func))
|
||||
{
|
||||
return;
|
||||
@ -3343,7 +3347,8 @@ WebGLContext::CompressedTexImage2D(GLenum rawTexImgTarget, GLint level, GLenum i
|
||||
void
|
||||
WebGLContext::CompressedTexSubImage2D(GLenum rawTexImgTarget, GLint level, GLint xoffset,
|
||||
GLint yoffset, GLsizei width, GLsizei height,
|
||||
GLenum format, const ArrayBufferView& view)
|
||||
GLenum internalformat,
|
||||
const ArrayBufferView& view)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
@ -3354,10 +3359,10 @@ WebGLContext::CompressedTexSubImage2D(GLenum rawTexImgTarget, GLint level, GLint
|
||||
return;
|
||||
|
||||
if (!ValidateTexImage(2, rawTexImgTarget,
|
||||
level, format,
|
||||
level, internalformat,
|
||||
xoffset, yoffset, 0,
|
||||
width, height, 0,
|
||||
0, format, LOCAL_GL_UNSIGNED_BYTE,
|
||||
0, LOCAL_GL_NONE, LOCAL_GL_NONE,
|
||||
func))
|
||||
{
|
||||
return;
|
||||
@ -3369,13 +3374,17 @@ WebGLContext::CompressedTexSubImage2D(GLenum rawTexImgTarget, GLint level, GLint
|
||||
MOZ_ASSERT(tex);
|
||||
WebGLTexture::ImageInfo& levelInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||
|
||||
if (internalformat != levelInfo.InternalFormat()) {
|
||||
return ErrorInvalidOperation("compressedTexImage2D: internalformat does not match the existing image");
|
||||
}
|
||||
|
||||
view.ComputeLengthAndData();
|
||||
|
||||
uint32_t byteLength = view.Length();
|
||||
if (!ValidateCompTexImageDataSize(level, format, width, height, byteLength, func))
|
||||
if (!ValidateCompTexImageDataSize(level, internalformat, width, height, byteLength, func))
|
||||
return;
|
||||
|
||||
if (!ValidateCompTexImageSize(level, format,
|
||||
if (!ValidateCompTexImageSize(level, internalformat,
|
||||
xoffset, yoffset,
|
||||
width, height,
|
||||
levelInfo.Width(), levelInfo.Height(),
|
||||
@ -3388,7 +3397,7 @@ WebGLContext::CompressedTexSubImage2D(GLenum rawTexImgTarget, GLint level, GLint
|
||||
tex->DoDeferredImageInitialization(texImageTarget, level);
|
||||
|
||||
MakeContextCurrent();
|
||||
gl->fCompressedTexSubImage2D(texImageTarget.get(), level, xoffset, yoffset, width, height, format, byteLength, view.Data());
|
||||
gl->fCompressedTexSubImage2D(texImageTarget.get(), level, xoffset, yoffset, width, height, internalformat, byteLength, view.Data());
|
||||
}
|
||||
|
||||
JS::Value
|
||||
@ -3577,15 +3586,14 @@ WebGLContext::GetShaderTranslatedSource(WebGLShader *shader, nsAString& retval)
|
||||
|
||||
GLenum WebGLContext::CheckedTexImage2D(TexImageTarget texImageTarget,
|
||||
GLint level,
|
||||
GLenum internalFormat,
|
||||
TexInternalFormat internalFormat,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLint border,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
TexFormat format,
|
||||
TexType type,
|
||||
const GLvoid *data)
|
||||
{
|
||||
MOZ_ASSERT(internalFormat == format);
|
||||
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
|
||||
MOZ_ASSERT(tex != nullptr, "no texture bound");
|
||||
|
||||
@ -3595,15 +3603,14 @@ GLenum WebGLContext::CheckedTexImage2D(TexImageTarget texImageTarget,
|
||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||
sizeMayChange = width != imageInfo.Width() ||
|
||||
height != imageInfo.Height() ||
|
||||
format != imageInfo.InternalFormat() ||
|
||||
type != imageInfo.Type();
|
||||
internalFormat != imageInfo.InternalFormat();
|
||||
}
|
||||
|
||||
// Convert to format and type required by OpenGL 'driver'.
|
||||
GLenum driverType = DriverTypeFromType(gl, type);
|
||||
GLenum driverInternalFormat = LOCAL_GL_NONE;
|
||||
GLenum driverFormat = LOCAL_GL_NONE;
|
||||
DriverFormatsFromFormatAndType(gl, format, type, &driverInternalFormat, &driverFormat);
|
||||
DriverFormatsFromFormatAndType(gl, internalFormat, type, &driverInternalFormat, &driverFormat);
|
||||
|
||||
if (sizeMayChange) {
|
||||
GetAndFlushUnderlyingGLErrors();
|
||||
@ -3620,10 +3627,12 @@ GLenum WebGLContext::CheckedTexImage2D(TexImageTarget texImageTarget,
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level, GLenum internalformat,
|
||||
WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||
GLenum internalformat,
|
||||
GLsizei width, GLsizei height, GLsizei srcStrideOrZero,
|
||||
GLint border,
|
||||
GLenum format, GLenum type,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
void* data, uint32_t byteLength,
|
||||
int jsArrayType, // a TypedArray format enum, or -1 if not relevant
|
||||
WebGLTexelFormat srcFormat, bool srcPremultiplied)
|
||||
@ -3652,7 +3661,7 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level, GLenum
|
||||
if (!ValidateTexInputData(type, jsArrayType, func))
|
||||
return;
|
||||
|
||||
WebGLTexelFormat dstFormat = GetWebGLTexelFormat(format, type);
|
||||
WebGLTexelFormat dstFormat = GetWebGLTexelFormat(internalformat, type);
|
||||
WebGLTexelFormat actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
|
||||
|
||||
uint32_t srcTexelSize = WebGLTexelConversions::TexelBytesForFormat(actualSrcFormat);
|
||||
@ -3686,7 +3695,7 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level, GLenum
|
||||
|
||||
if (byteLength) {
|
||||
size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
|
||||
uint32_t dstTexelSize = GetBitsPerTexel(format, type) / 8;
|
||||
uint32_t dstTexelSize = GetBitsPerTexel(internalformat, type) / 8;
|
||||
size_t dstPlainRowSize = dstTexelSize * width;
|
||||
size_t unpackAlignment = mPixelStoreUnpackAlignment;
|
||||
size_t dstStride = ((dstPlainRowSize + unpackAlignment-1) / unpackAlignment) * unpackAlignment;
|
||||
@ -3803,7 +3812,14 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||
{
|
||||
const WebGLTexImageFunc func = WebGLTexImageFunc::TexSubImage;
|
||||
|
||||
if (!ValidateTexImage(2, texImageTarget, level, format,
|
||||
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
|
||||
if (!tex) {
|
||||
return ErrorInvalidOperation("texSubImage2D: no texture bound on active texture unit");
|
||||
}
|
||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||
const TexInternalFormat internalformat = imageInfo.InternalFormat();
|
||||
|
||||
if (!ValidateTexImage(2, texImageTarget, level, internalformat.get(),
|
||||
xoffset, yoffset, 0,
|
||||
width, height, 0,
|
||||
0, format, type, func))
|
||||
@ -3814,7 +3830,11 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||
if (!ValidateTexInputData(type, jsArrayType, func))
|
||||
return;
|
||||
|
||||
WebGLTexelFormat dstFormat = GetWebGLTexelFormat(format, type);
|
||||
if (imageInfo.Type() != type) {
|
||||
return ErrorInvalidOperation("texSubImage2D: type parameter does not match the existing image");
|
||||
}
|
||||
|
||||
WebGLTexelFormat dstFormat = GetWebGLTexelFormat(internalformat, type);
|
||||
WebGLTexelFormat actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
|
||||
|
||||
uint32_t srcTexelSize = WebGLTexelConversions::TexelBytesForFormat(actualSrcFormat);
|
||||
@ -3838,16 +3858,13 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||
if (byteLength < bytesNeeded)
|
||||
return ErrorInvalidOperation("texSubImage2D: not enough data for operation (need %d, have %d)", bytesNeeded, byteLength);
|
||||
|
||||
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
|
||||
const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||
|
||||
if (imageInfo.HasUninitializedImageData())
|
||||
tex->DoDeferredImageInitialization(texImageTarget, level);
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
|
||||
uint32_t dstTexelSize = GetBitsPerTexel(format, type) / 8;
|
||||
uint32_t dstTexelSize = GetBitsPerTexel(internalformat, type) / 8;
|
||||
size_t dstPlainRowSize = dstTexelSize * width;
|
||||
// There are checks above to ensure that this won't overflow.
|
||||
size_t dstStride = RoundedToNextMultipleOf(dstPlainRowSize, mPixelStoreUnpackAlignment).value();
|
||||
@ -3874,7 +3891,7 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||
GLenum driverType = DriverTypeFromType(gl, type);
|
||||
GLenum driverInternalFormat = LOCAL_GL_NONE;
|
||||
GLenum driverFormat = LOCAL_GL_NONE;
|
||||
DriverFormatsFromFormatAndType(gl, format, type, &driverInternalFormat, &driverFormat);
|
||||
DriverFormatsFromFormatAndType(gl, internalformat, type, &driverInternalFormat, &driverFormat);
|
||||
|
||||
gl->fTexSubImage2D(texImageTarget.get(), level, xoffset, yoffset, width, height, driverFormat, driverType, pixels);
|
||||
}
|
||||
|
@ -490,11 +490,10 @@ WebGLContext::EnumName(GLenum glenum)
|
||||
return "[Unknown enum name]";
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WebGLContext::IsTextureFormatCompressed(TexInternalFormat format)
|
||||
WebGLContext::IsCompressedTextureFormat(GLenum format)
|
||||
{
|
||||
switch (format.get()) {
|
||||
switch (format) {
|
||||
case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||
@ -513,6 +512,13 @@ WebGLContext::IsTextureFormatCompressed(TexInternalFormat format)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WebGLContext::IsTextureFormatCompressed(TexInternalFormat format)
|
||||
{
|
||||
return IsCompressedTextureFormat(format.get());
|
||||
}
|
||||
|
||||
GLenum
|
||||
WebGLContext::GetAndFlushUnderlyingGLErrors()
|
||||
{
|
||||
|
@ -82,6 +82,13 @@ InfoFrom(WebGLTexImageFunc func)
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
IsCompressedFunc(WebGLTexImageFunc func)
|
||||
{
|
||||
return func == WebGLTexImageFunc::CompTexImage ||
|
||||
func == WebGLTexImageFunc::CompTexSubImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as ErrorInvalidEnum but uses WebGLContext::EnumName to print displayable
|
||||
* name for \a glenum.
|
||||
@ -248,7 +255,7 @@ WebGLProgram::UpdateInfo()
|
||||
* \return the corresponding \u base internal format (GL_ALPHA, GL_LUMINANCE,
|
||||
* GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA), or GL_NONE if invalid enum.
|
||||
*/
|
||||
TexFormat
|
||||
TexInternalFormat
|
||||
WebGLContext::BaseTexFormat(TexInternalFormat internalFormat) const
|
||||
{
|
||||
if (internalFormat == LOCAL_GL_ALPHA ||
|
||||
@ -257,56 +264,56 @@ WebGLContext::BaseTexFormat(TexInternalFormat internalFormat) const
|
||||
internalFormat == LOCAL_GL_RGB ||
|
||||
internalFormat == LOCAL_GL_RGBA)
|
||||
{
|
||||
return TexFormat(internalFormat.get());
|
||||
return internalFormat;
|
||||
}
|
||||
|
||||
if (IsExtensionEnabled(WebGLExtensionID::EXT_sRGB)) {
|
||||
if (internalFormat == LOCAL_GL_SRGB)
|
||||
return TexFormat(LOCAL_GL_RGB);
|
||||
return LOCAL_GL_RGB;
|
||||
|
||||
if (internalFormat == LOCAL_GL_SRGB_ALPHA)
|
||||
return TexFormat(LOCAL_GL_RGBA);
|
||||
return LOCAL_GL_RGBA;
|
||||
}
|
||||
|
||||
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_atc)) {
|
||||
if (internalFormat == LOCAL_GL_ATC_RGB)
|
||||
return TexFormat(LOCAL_GL_RGB);
|
||||
return LOCAL_GL_RGB;
|
||||
|
||||
if (internalFormat == LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA ||
|
||||
internalFormat == LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA)
|
||||
{
|
||||
return TexFormat(LOCAL_GL_RGBA);
|
||||
return LOCAL_GL_RGBA;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_etc1)) {
|
||||
if (internalFormat == LOCAL_GL_ETC1_RGB8_OES)
|
||||
return TexFormat(LOCAL_GL_RGB);
|
||||
return LOCAL_GL_RGB;
|
||||
}
|
||||
|
||||
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_pvrtc)) {
|
||||
if (internalFormat == LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1 ||
|
||||
internalFormat == LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1)
|
||||
{
|
||||
return TexFormat(LOCAL_GL_RGB);
|
||||
return LOCAL_GL_RGB;
|
||||
}
|
||||
|
||||
if (internalFormat == LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1 ||
|
||||
internalFormat == LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1)
|
||||
{
|
||||
return TexFormat(LOCAL_GL_RGBA);
|
||||
return LOCAL_GL_RGBA;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_s3tc)) {
|
||||
if (internalFormat == LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
|
||||
return TexFormat(LOCAL_GL_RGB);
|
||||
return LOCAL_GL_RGB;
|
||||
|
||||
if (internalFormat == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
|
||||
internalFormat == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
|
||||
internalFormat == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
|
||||
{
|
||||
return TexFormat(LOCAL_GL_RGBA);
|
||||
return LOCAL_GL_RGBA;
|
||||
}
|
||||
}
|
||||
|
||||
@ -315,13 +322,13 @@ WebGLContext::BaseTexFormat(TexInternalFormat internalFormat) const
|
||||
internalFormat == LOCAL_GL_DEPTH_COMPONENT16 ||
|
||||
internalFormat == LOCAL_GL_DEPTH_COMPONENT32)
|
||||
{
|
||||
return TexFormat(LOCAL_GL_DEPTH_COMPONENT);
|
||||
return LOCAL_GL_DEPTH_COMPONENT;
|
||||
}
|
||||
|
||||
if (internalFormat == LOCAL_GL_DEPTH_STENCIL ||
|
||||
internalFormat == LOCAL_GL_DEPTH24_STENCIL8)
|
||||
{
|
||||
return TexFormat(LOCAL_GL_DEPTH_STENCIL);
|
||||
return LOCAL_GL_DEPTH_STENCIL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -608,53 +615,6 @@ WebGLContext::ValidateTexImageFormat(GLenum format, WebGLTexImageFunc func)
|
||||
return validFormat;
|
||||
}
|
||||
|
||||
/* WEBGL_compressed_texture_atc added formats */
|
||||
if (format == LOCAL_GL_ATC_RGB ||
|
||||
format == LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA ||
|
||||
format == LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA)
|
||||
{
|
||||
bool validFormat = IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_atc);
|
||||
if (!validFormat)
|
||||
ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_atc enabled",
|
||||
InfoFrom(func), WebGLContext::EnumName(format));
|
||||
return validFormat;
|
||||
}
|
||||
|
||||
// WEBGL_compressed_texture_etc1
|
||||
if (format == LOCAL_GL_ETC1_RGB8_OES) {
|
||||
bool validFormat = IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_etc1);
|
||||
if (!validFormat)
|
||||
ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_etc1 enabled",
|
||||
InfoFrom(func), WebGLContext::EnumName(format));
|
||||
return validFormat;
|
||||
}
|
||||
|
||||
|
||||
if (format == LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1 ||
|
||||
format == LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1 ||
|
||||
format == LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1 ||
|
||||
format == LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1)
|
||||
{
|
||||
bool validFormat = IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_pvrtc);
|
||||
if (!validFormat)
|
||||
ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_pvrtc enabled",
|
||||
InfoFrom(func), WebGLContext::EnumName(format));
|
||||
return validFormat;
|
||||
}
|
||||
|
||||
|
||||
if (format == LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
|
||||
format == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
|
||||
format == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
|
||||
format == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
|
||||
{
|
||||
bool validFormat = IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_s3tc);
|
||||
if (!validFormat)
|
||||
ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_s3tc enabled",
|
||||
InfoFrom(func), WebGLContext::EnumName(format));
|
||||
return validFormat;
|
||||
}
|
||||
|
||||
ErrorInvalidEnumWithName(this, "invalid format", format, func);
|
||||
|
||||
return false;
|
||||
@ -664,7 +624,9 @@ WebGLContext::ValidateTexImageFormat(GLenum format, WebGLTexImageFunc func)
|
||||
* Check if the given texture target is valid for TexImage.
|
||||
*/
|
||||
bool
|
||||
WebGLContext::ValidateTexImageTarget(GLuint dims, GLenum target, WebGLTexImageFunc func)
|
||||
WebGLContext::ValidateTexImageTarget(GLuint dims,
|
||||
GLenum target,
|
||||
WebGLTexImageFunc func)
|
||||
{
|
||||
switch (dims) {
|
||||
case 2:
|
||||
@ -689,7 +651,8 @@ WebGLContext::ValidateTexImageTarget(GLuint dims, GLenum target, WebGLTexImageFu
|
||||
* taking into account enabled WebGL extensions.
|
||||
*/
|
||||
bool
|
||||
WebGLContext::ValidateTexImageType(GLenum type, WebGLTexImageFunc func)
|
||||
WebGLContext::ValidateTexImageType(GLenum type,
|
||||
WebGLTexImageFunc func)
|
||||
{
|
||||
/* Core WebGL texture types */
|
||||
if (type == LOCAL_GL_UNSIGNED_BYTE ||
|
||||
@ -740,7 +703,8 @@ WebGLContext::ValidateTexImageType(GLenum type, WebGLTexImageFunc func)
|
||||
*/
|
||||
// TODO: WebGL 2
|
||||
bool
|
||||
WebGLContext::ValidateCompTexImageSize(GLint level, GLenum format,
|
||||
WebGLContext::ValidateCompTexImageSize(GLint level,
|
||||
GLenum format,
|
||||
GLint xoffset, GLint yoffset,
|
||||
GLsizei width, GLsizei height,
|
||||
GLsizei levelWidth, GLsizei levelHeight,
|
||||
@ -1155,8 +1119,14 @@ WebGLContext::GetBitsPerTexel(TexInternalFormat format, TexType type)
|
||||
* Returns true if the format/type is a valid combination, false otherwise.
|
||||
*/
|
||||
bool
|
||||
WebGLContext::ValidateTexImageFormatAndType(GLenum format, GLenum type, WebGLTexImageFunc func)
|
||||
WebGLContext::ValidateTexImageFormatAndType(GLenum format,
|
||||
GLenum type, WebGLTexImageFunc func)
|
||||
{
|
||||
if (IsCompressedFunc(func) || IsCopyFunc(func))
|
||||
{
|
||||
MOZ_ASSERT(type == LOCAL_GL_NONE && format == LOCAL_GL_NONE);
|
||||
return true;
|
||||
}
|
||||
if (!ValidateTexImageFormat(format, func) ||
|
||||
!ValidateTexImageType(type, func))
|
||||
{
|
||||
@ -1203,21 +1173,6 @@ WebGLContext::ValidateTexImageFormatAndType(GLenum format, GLenum type, WebGLTex
|
||||
validCombo = (type == LOCAL_GL_UNSIGNED_INT_24_8);
|
||||
break;
|
||||
|
||||
case LOCAL_GL_ATC_RGB:
|
||||
case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
|
||||
case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
|
||||
case LOCAL_GL_ETC1_RGB8_OES:
|
||||
case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
|
||||
case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
|
||||
case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||
validCombo = (type == LOCAL_GL_UNSIGNED_BYTE);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Only valid formats should be passed to the switch stmt.
|
||||
MOZ_ASSERT(false, "Unexpected format and type combo. How'd this happen?");
|
||||
@ -1233,6 +1188,89 @@ WebGLContext::ValidateTexImageFormatAndType(GLenum format, GLenum type, WebGLTex
|
||||
return validCombo;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::ValidateCompTexImageInternalFormat(GLenum format,
|
||||
WebGLTexImageFunc func)
|
||||
{
|
||||
if (!IsCompressedTextureFormat(format)) {
|
||||
ErrorInvalidEnum("%s: invalid compressed texture format: %s",
|
||||
InfoFrom(func), WebGLContext::EnumName(format));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* WEBGL_compressed_texture_atc added formats */
|
||||
if (format == LOCAL_GL_ATC_RGB ||
|
||||
format == LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA ||
|
||||
format == LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA)
|
||||
{
|
||||
bool validFormat = IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_atc);
|
||||
if (!validFormat)
|
||||
ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_atc enabled",
|
||||
InfoFrom(func), WebGLContext::EnumName(format));
|
||||
return validFormat;
|
||||
}
|
||||
|
||||
// WEBGL_compressed_texture_etc1
|
||||
if (format == LOCAL_GL_ETC1_RGB8_OES) {
|
||||
bool validFormat = IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_etc1);
|
||||
if (!validFormat)
|
||||
ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_etc1 enabled",
|
||||
InfoFrom(func), WebGLContext::EnumName(format));
|
||||
return validFormat;
|
||||
}
|
||||
|
||||
|
||||
if (format == LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1 ||
|
||||
format == LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1 ||
|
||||
format == LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1 ||
|
||||
format == LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1)
|
||||
{
|
||||
bool validFormat = IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_pvrtc);
|
||||
if (!validFormat)
|
||||
ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_pvrtc enabled",
|
||||
InfoFrom(func), WebGLContext::EnumName(format));
|
||||
return validFormat;
|
||||
}
|
||||
|
||||
|
||||
if (format == LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
|
||||
format == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
|
||||
format == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
|
||||
format == LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
|
||||
{
|
||||
bool validFormat = IsExtensionEnabled(WebGLExtensionID::WEBGL_compressed_texture_s3tc);
|
||||
if (!validFormat)
|
||||
ErrorInvalidEnum("%s: invalid format %s: need WEBGL_compressed_texture_s3tc enabled",
|
||||
InfoFrom(func), WebGLContext::EnumName(format));
|
||||
return validFormat;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::ValidateCopyTexImageInternalFormat(GLenum format,
|
||||
WebGLTexImageFunc func)
|
||||
{
|
||||
bool valid = format == LOCAL_GL_RGBA ||
|
||||
format == LOCAL_GL_RGB ||
|
||||
format == LOCAL_GL_LUMINANCE_ALPHA ||
|
||||
format == LOCAL_GL_LUMINANCE ||
|
||||
format == LOCAL_GL_ALPHA;
|
||||
if (!valid)
|
||||
{
|
||||
// in CopyTexImage, the internalformat is a function parameter,
|
||||
// so a bad value is an INVALID_ENUM error.
|
||||
// in CopyTexSubImage, the internalformat is part of existing state,
|
||||
// so this is an INVALID_OPERATION error.
|
||||
GenerateWarning("%s: invalid texture internal format: %s",
|
||||
InfoFrom(func), WebGLContext::EnumName(format));
|
||||
SynthesizeGLError(func == WebGLTexImageFunc::CopyTexImage
|
||||
? LOCAL_GL_INVALID_ENUM
|
||||
: LOCAL_GL_INVALID_OPERATION);
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
/**
|
||||
* Return true if format, type and jsArrayType are a valid combination.
|
||||
* Also returns the size for texel of format and type (in bytes) via
|
||||
@ -1287,7 +1325,8 @@ WebGLContext::ValidateTexInputData(GLenum type, int jsArrayType, WebGLTexImageFu
|
||||
* - Copy format is a subset of framebuffer format (i.e. all required components are available)
|
||||
*/
|
||||
bool
|
||||
WebGLContext::ValidateCopyTexImage(GLenum format, WebGLTexImageFunc func)
|
||||
WebGLContext::ValidateCopyTexImage(GLenum format,
|
||||
WebGLTexImageFunc func)
|
||||
{
|
||||
MOZ_ASSERT(IsCopyFunc(func));
|
||||
|
||||
@ -1332,10 +1371,13 @@ WebGLContext::ValidateCopyTexImage(GLenum format, WebGLTexImageFunc func)
|
||||
// TODO: Texture dims is here for future expansion in WebGL 2.0
|
||||
bool
|
||||
WebGLContext::ValidateTexImage(GLuint dims, TexImageTarget texImageTarget,
|
||||
GLint level, GLenum internalFormat,
|
||||
GLint level,
|
||||
GLenum internalFormat,
|
||||
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLint width, GLint height, GLint depth,
|
||||
GLint border, GLenum format, GLenum type,
|
||||
GLint border,
|
||||
GLenum format,
|
||||
GLenum type,
|
||||
WebGLTexImageFunc func)
|
||||
{
|
||||
const char* info = InfoFrom(func);
|
||||
@ -1356,13 +1398,21 @@ WebGLContext::ValidateTexImage(GLuint dims, TexImageTarget texImageTarget,
|
||||
if (!ValidateTexImageFormatAndType(format, type, func))
|
||||
return false;
|
||||
|
||||
if (IsCompressedFunc(func)) {
|
||||
if (!ValidateCompTexImageInternalFormat(internalFormat, func)) {
|
||||
return false;
|
||||
}
|
||||
} else if (IsCopyFunc(func)) {
|
||||
if (!ValidateCopyTexImageInternalFormat(internalFormat, func)) {
|
||||
return false;
|
||||
}
|
||||
} else if (format != internalFormat) {
|
||||
/* WebGL and OpenGL ES 2.0 impose additional restrictions on the
|
||||
* combinations of format, internalFormat, and type that can be
|
||||
* used. Formats and types that require additional extensions
|
||||
* (e.g., GL_FLOAT requires GL_OES_texture_float) are filtered
|
||||
* elsewhere.
|
||||
*/
|
||||
if (format != internalFormat) {
|
||||
ErrorInvalidOperation("%s: format does not match internalformat", info);
|
||||
return false;
|
||||
}
|
||||
@ -1406,17 +1456,6 @@ WebGLContext::ValidateTexImage(GLuint dims, TexImageTarget texImageTarget,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Require the format and type to match that of the existing
|
||||
* texture as created
|
||||
*/
|
||||
if (imageInfo.InternalFormat() != internalFormat ||
|
||||
imageInfo.Type() != type)
|
||||
{
|
||||
ErrorInvalidOperation("%s: format or type doesn't match the existing texture",
|
||||
info);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Additional checks for depth textures */
|
||||
@ -1430,7 +1469,7 @@ WebGLContext::ValidateTexImage(GLuint dims, TexImageTarget texImageTarget,
|
||||
}
|
||||
|
||||
/* Additional checks for compressed textures */
|
||||
if (!IsAllowedFromSource(format, func)) {
|
||||
if (!IsAllowedFromSource(internalFormat, func)) {
|
||||
ErrorInvalidOperation("%s: Invalid format %s for this operation",
|
||||
info, WebGLContext::EnumName(format));
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user