mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1077183 - Untangle the confusion between effective and unsized internalformats in the WebGL implementation - r=jgilbert
This commit is contained in:
parent
efd9df19a5
commit
9fc8a1b4bc
@ -153,16 +153,9 @@ WebGL2Context::TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat
|
||||
GLsizei h = height;
|
||||
for (size_t l = 0; l < size_t(levels); l++) {
|
||||
for (size_t f = 0; f < facesCount; f++) {
|
||||
TexImageTarget imageTarget = TexImageTargetForTargetAndFace(target, f);
|
||||
// FIXME: SetImageInfo wants a type, to go with the internalformat that it stores.
|
||||
// 'type' is deprecated by sized internalformats, which are how TexStorage works.
|
||||
// We must fix WebGLTexture::ImageInfo to store an "effective internalformat",
|
||||
// which in the present case is just the sized internalformat, and drop 'types'
|
||||
// altogether. For now, we just pass LOCAL_GL_UNSIGNED_BYTE, which works For
|
||||
// the most commonly used formats.
|
||||
const GLenum type = LOCAL_GL_UNSIGNED_BYTE;
|
||||
tex->SetImageInfo(imageTarget, l, w, h,
|
||||
internalformat, type,
|
||||
tex->SetImageInfo(TexImageTargetForTargetAndFace(target, f),
|
||||
l, w, h,
|
||||
internalformat,
|
||||
WebGLImageDataStatus::UninitializedImageData);
|
||||
}
|
||||
w = std::max(1, w/2);
|
||||
|
@ -1760,6 +1760,13 @@ bool WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget,
|
||||
GLenum internalformat, GLenum format, GLenum type,
|
||||
mozilla::dom::Element& elt)
|
||||
{
|
||||
if (type == LOCAL_GL_HALF_FLOAT_OES) {
|
||||
type = LOCAL_GL_HALF_FLOAT;
|
||||
}
|
||||
|
||||
if (!ValidateTexImageFormatAndType(format, type, WebGLTexImageFunc::TexImage))
|
||||
return false;
|
||||
|
||||
HTMLVideoElement* video = HTMLVideoElement::FromContentOrNull(&elt);
|
||||
if (!video) {
|
||||
return false;
|
||||
@ -1807,8 +1814,11 @@ bool WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget,
|
||||
}
|
||||
bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage.get(), srcImage->GetSize(), tex->GLName(), texImageTarget.get(), mPixelStoreFlipY);
|
||||
if (ok) {
|
||||
tex->SetImageInfo(texImageTarget, level, srcImage->GetSize().width, srcImage->GetSize().height, internalformat, type,
|
||||
WebGLImageDataStatus::InitializedImageData);
|
||||
TexInternalFormat effectiveinternalformat =
|
||||
EffectiveInternalFormatFromInternalFormatAndType(internalformat, type);
|
||||
MOZ_ASSERT(effectiveinternalformat != LOCAL_GL_NONE);
|
||||
tex->SetImageInfo(texImageTarget, level, srcImage->GetSize().width, srcImage->GetSize().height,
|
||||
effectiveinternalformat, WebGLImageDataStatus::InitializedImageData);
|
||||
tex->Bind(TexImageTargetToTexTarget(texImageTarget));
|
||||
}
|
||||
srcImage = nullptr;
|
||||
|
@ -94,7 +94,7 @@ namespace gfx {
|
||||
class SourceSurface;
|
||||
}
|
||||
|
||||
WebGLTexelFormat GetWebGLTexelFormat(TexInternalFormat format, TexType type);
|
||||
WebGLTexelFormat GetWebGLTexelFormat(TexInternalFormat format);
|
||||
|
||||
void AssertUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint shadow);
|
||||
|
||||
@ -490,9 +490,6 @@ public:
|
||||
|
||||
const TexImageTarget texImageTarget(rawTexImgTarget);
|
||||
|
||||
if (!ValidateTexImageFormatAndType(format, type, WebGLTexImageFunc::TexImage))
|
||||
return;
|
||||
|
||||
if (level < 0)
|
||||
return ErrorInvalidValue("texImage2D: level is negative");
|
||||
|
||||
@ -560,9 +557,6 @@ public:
|
||||
|
||||
const TexImageTarget texImageTarget(rawTexImageTarget);
|
||||
|
||||
if (!ValidateTexImageFormatAndType(format, type, WebGLTexImageFunc::TexImage))
|
||||
return;
|
||||
|
||||
if (level < 0)
|
||||
return ErrorInvalidValue("texSubImage2D: level is negative");
|
||||
|
||||
@ -575,7 +569,7 @@ public:
|
||||
return ErrorInvalidOperation("texSubImage2D: no texture bound on active texture unit");
|
||||
}
|
||||
const WebGLTexture::ImageInfo &imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||
const TexInternalFormat internalformat = imageInfo.InternalFormat();
|
||||
const TexInternalFormat internalformat = imageInfo.EffectiveInternalFormat();
|
||||
|
||||
// Trying to handle the video by GPU directly first
|
||||
if (TexImageFromVideoElement(texImageTarget, level,
|
||||
@ -1145,8 +1139,6 @@ protected:
|
||||
GLsizei width, GLsizei height,
|
||||
uint32_t byteLength, WebGLTexImageFunc func);
|
||||
|
||||
static uint32_t GetBitsPerTexel(TexInternalFormat format, TexType type);
|
||||
|
||||
void Invalidate();
|
||||
void DestroyResourcesAndContext();
|
||||
|
||||
@ -1203,7 +1195,7 @@ protected:
|
||||
|
||||
void CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
||||
GLint level,
|
||||
GLenum internalformat,
|
||||
TexInternalFormat internalformat,
|
||||
GLint xoffset,
|
||||
GLint yoffset,
|
||||
GLint x,
|
||||
|
@ -676,7 +676,7 @@ WebGLContext::BindFakeBlackTexturesHelper(
|
||||
}
|
||||
|
||||
bool alpha = s == WebGLTextureFakeBlackStatus::UninitializedImageData &&
|
||||
FormatHasAlpha(boundTexturesArray[i]->ImageInfoBase().InternalFormat());
|
||||
FormatHasAlpha(boundTexturesArray[i]->ImageInfoBase().EffectiveInternalFormat());
|
||||
UniquePtr<FakeBlackTexture>&
|
||||
blackTexturePtr = alpha
|
||||
? transparentTextureScopedPtr
|
||||
|
@ -354,7 +354,7 @@ WebGLContext::CheckFramebufferStatus(GLenum target)
|
||||
void
|
||||
WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
||||
GLint level,
|
||||
GLenum internalformat,
|
||||
TexInternalFormat internalformat,
|
||||
GLint xoffset,
|
||||
GLint yoffset,
|
||||
GLint x,
|
||||
@ -372,7 +372,7 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
||||
|
||||
// TODO: This changes with color_buffer_float. Reassess when the
|
||||
// patch lands.
|
||||
if (!ValidateTexImage(2, texImageTarget, level, internalformat,
|
||||
if (!ValidateTexImage(2, texImageTarget, level, internalformat.get(),
|
||||
xoffset, yoffset, 0,
|
||||
width, height, 0,
|
||||
0,
|
||||
@ -382,7 +382,7 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateCopyTexImage(internalformat, func))
|
||||
if (!ValidateCopyTexImage(internalformat.get(), func))
|
||||
return;
|
||||
|
||||
if (!mBoundFramebuffer)
|
||||
@ -401,50 +401,50 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
||||
}
|
||||
}
|
||||
|
||||
TexType framebuffertype = LOCAL_GL_NONE;
|
||||
if (mBoundFramebuffer) {
|
||||
TexInternalFormat framebuffereffectiveformat = mBoundFramebuffer->ColorAttachment(0).EffectiveInternalFormat();
|
||||
framebuffertype = TypeFromInternalFormat(framebuffereffectiveformat);
|
||||
} else {
|
||||
// FIXME - here we're assuming that the default framebuffer is backed by UNSIGNED_BYTE
|
||||
// that might not always be true, say if we had a 16bpp default framebuffer.
|
||||
framebuffertype = LOCAL_GL_UNSIGNED_BYTE;
|
||||
}
|
||||
|
||||
TexInternalFormat effectiveinternalformat =
|
||||
EffectiveInternalFormatFromUnsizedInternalFormatAndType(internalformat, framebuffertype);
|
||||
|
||||
// this should never fail, validation happened earlier.
|
||||
MOZ_ASSERT(effectiveinternalformat != LOCAL_GL_NONE);
|
||||
|
||||
// check if the memory size of this texture may change with this call
|
||||
bool sizeMayChange = !sub;
|
||||
if (!sub && tex->HasImageInfoAt(texImageTarget, level)) {
|
||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||
sizeMayChange = width != imageInfo.Width() ||
|
||||
height != imageInfo.Height() ||
|
||||
effectiveinternalformat != imageInfo.EffectiveInternalFormat();
|
||||
}
|
||||
|
||||
if (sizeMayChange)
|
||||
GetAndFlushUnderlyingGLErrors();
|
||||
|
||||
if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, framebufferWidth, framebufferHeight)) {
|
||||
if (sub)
|
||||
gl->fCopyTexSubImage2D(texImageTarget.get(), level, xoffset, yoffset, x, y, width, height);
|
||||
else
|
||||
gl->fCopyTexImage2D(texImageTarget.get(), level, internalformat, x, y, width, height, 0);
|
||||
gl->fCopyTexImage2D(texImageTarget.get(), level, internalformat.get(), x, y, width, height, 0);
|
||||
} else {
|
||||
|
||||
// the rect doesn't fit in the framebuffer
|
||||
|
||||
/*** first, we initialize the texture as black ***/
|
||||
|
||||
// first, compute the size of the buffer we should allocate to initialize the texture as black
|
||||
|
||||
if (!ValidateTexInputData(LOCAL_GL_UNSIGNED_BYTE, -1, func))
|
||||
return;
|
||||
|
||||
uint32_t texelSize = GetBitsPerTexel(internalformat, LOCAL_GL_UNSIGNED_BYTE) / 8;
|
||||
|
||||
CheckedUint32 checked_neededByteLength =
|
||||
GetImageSize(height, width, texelSize, mPixelStoreUnpackAlignment);
|
||||
|
||||
if (!checked_neededByteLength.isValid())
|
||||
return ErrorInvalidOperation("%s: integer overflow computing the needed buffer size", info);
|
||||
|
||||
uint32_t bytesNeeded = checked_neededByteLength.value();
|
||||
|
||||
// now that the size is known, create the buffer
|
||||
|
||||
// We need some zero pages, because GL doesn't guarantee the
|
||||
// contents of a texture allocated with nullptr data.
|
||||
// Hopefully calloc will just mmap zero pages here.
|
||||
void* tempZeroData = calloc(1, bytesNeeded);
|
||||
if (!tempZeroData)
|
||||
return ErrorOutOfMemory("%s: could not allocate %d bytes (for zero fill)", info, bytesNeeded);
|
||||
|
||||
// now initialize the texture as black
|
||||
|
||||
if (sub)
|
||||
gl->fTexSubImage2D(texImageTarget.get(), level, 0, 0, width, height,
|
||||
internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
|
||||
else
|
||||
gl->fTexImage2D(texImageTarget.get(), level, internalformat, width, height,
|
||||
0, internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
|
||||
free(tempZeroData);
|
||||
// first, we initialize the texture as black
|
||||
if (!sub) {
|
||||
tex->SetImageInfo(texImageTarget, level, width, height,
|
||||
effectiveinternalformat,
|
||||
WebGLImageDataStatus::UninitializedImageData);
|
||||
tex->DoDeferredImageInitialization(texImageTarget, level);
|
||||
}
|
||||
|
||||
// if we are completely outside of the framebuffer, we can exit now with our black texture
|
||||
if ( x >= framebufferWidth
|
||||
@ -468,6 +468,20 @@ WebGLContext::CopyTexSubImage2D_base(TexImageTarget texImageTarget,
|
||||
|
||||
gl->fCopyTexSubImage2D(texImageTarget.get(), level, actual_xoffset, actual_yoffset, actual_x, actual_y, actual_width, actual_height);
|
||||
}
|
||||
|
||||
if (sizeMayChange) {
|
||||
GLenum error = GetAndFlushUnderlyingGLErrors();
|
||||
if (error) {
|
||||
GenerateWarning("copyTexImage2D generated error %s", ErrorName(error));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sub) {
|
||||
tex->SetImageInfo(texImageTarget, level, width, height,
|
||||
effectiveinternalformat,
|
||||
WebGLImageDataStatus::InitializedImageData);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -504,37 +518,7 @@ WebGLContext::CopyTexImage2D(GLenum rawTexImgTarget,
|
||||
if (!mBoundFramebuffer)
|
||||
ClearBackbufferIfNeeded();
|
||||
|
||||
const TexImageTarget texImageTarget(rawTexImgTarget);
|
||||
|
||||
// check if the memory size of this texture may change with this call
|
||||
bool sizeMayChange = true;
|
||||
WebGLTexture* tex = activeBoundTextureForTexImageTarget(texImageTarget);
|
||||
if (tex->HasImageInfoAt(texImageTarget, level)) {
|
||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||
|
||||
sizeMayChange = width != imageInfo.Width() ||
|
||||
height != imageInfo.Height() ||
|
||||
internalformat != imageInfo.InternalFormat();
|
||||
}
|
||||
|
||||
if (sizeMayChange)
|
||||
GetAndFlushUnderlyingGLErrors();
|
||||
|
||||
CopyTexSubImage2D_base(texImageTarget, level, internalformat, 0, 0, x, y, width, height, false);
|
||||
|
||||
if (sizeMayChange) {
|
||||
GLenum error = GetAndFlushUnderlyingGLErrors();
|
||||
if (error) {
|
||||
GenerateWarning("copyTexImage2D generated error %s", ErrorName(error));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
tex->SetImageInfo(texImageTarget, level, width, height,
|
||||
internalformat,
|
||||
LOCAL_GL_UNSIGNED_BYTE, /* dummy, artifact of us storing
|
||||
the wrong data in ImageInfo */
|
||||
WebGLImageDataStatus::InitializedImageData);
|
||||
CopyTexSubImage2D_base(rawTexImgTarget, level, internalformat, 0, 0, x, y, width, height, false);
|
||||
}
|
||||
|
||||
void
|
||||
@ -602,7 +586,11 @@ WebGLContext::CopyTexSubImage2D(GLenum rawTexImgTarget,
|
||||
tex->DoDeferredImageInitialization(texImageTarget, level);
|
||||
}
|
||||
|
||||
return CopyTexSubImage2D_base(texImageTarget, level, imageInfo.InternalFormat().get(), xoffset, yoffset, x, y, width, height, true);
|
||||
TexInternalFormat internalformat;
|
||||
TexType type;
|
||||
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(imageInfo.EffectiveInternalFormat(),
|
||||
&internalformat, &type);
|
||||
return CopyTexSubImage2D_base(texImageTarget, level, internalformat, xoffset, yoffset, x, y, width, height, true);
|
||||
}
|
||||
|
||||
|
||||
@ -922,7 +910,7 @@ WebGLContext::GenerateMipmap(GLenum rawTarget)
|
||||
if (!tex->IsFirstImagePowerOfTwo())
|
||||
return ErrorInvalidOperation("generateMipmap: Level zero of texture does not have power-of-two width and height.");
|
||||
|
||||
TexInternalFormat internalformat = tex->ImageInfoAt(imageTarget, 0).InternalFormat();
|
||||
TexInternalFormat internalformat = tex->ImageInfoAt(imageTarget, 0).EffectiveInternalFormat();
|
||||
if (IsTextureFormatCompressed(internalformat))
|
||||
return ErrorInvalidOperation("generateMipmap: Texture data at level zero is compressed.");
|
||||
|
||||
@ -1183,12 +1171,17 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
|
||||
switch (pname) {
|
||||
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT:
|
||||
if (IsExtensionEnabled(WebGLExtensionID::EXT_sRGB)) {
|
||||
const TexInternalFormat internalformat =
|
||||
fba.Texture()->ImageInfoBase().InternalFormat();
|
||||
return (internalformat == LOCAL_GL_SRGB ||
|
||||
internalformat == LOCAL_GL_SRGB_ALPHA) ?
|
||||
JS::NumberValue(uint32_t(LOCAL_GL_SRGB)) :
|
||||
JS::NumberValue(uint32_t(LOCAL_GL_LINEAR));
|
||||
const TexInternalFormat effectiveinternalformat =
|
||||
fba.Texture()->ImageInfoBase().EffectiveInternalFormat();
|
||||
TexInternalFormat unsizedinternalformat = LOCAL_GL_NONE;
|
||||
TexType type = LOCAL_GL_NONE;
|
||||
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(
|
||||
effectiveinternalformat, &unsizedinternalformat, &type);
|
||||
MOZ_ASSERT(unsizedinternalformat != LOCAL_GL_NONE);
|
||||
const bool srgb = unsizedinternalformat == LOCAL_GL_SRGB ||
|
||||
unsizedinternalformat == LOCAL_GL_SRGB_ALPHA;
|
||||
return srgb ? JS::NumberValue(uint32_t(LOCAL_GL_SRGB))
|
||||
: JS::NumberValue(uint32_t(LOCAL_GL_LINEAR));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1224,9 +1217,10 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
|
||||
if (!fba.IsComplete())
|
||||
return JS::NumberValue(uint32_t(LOCAL_GL_NONE));
|
||||
|
||||
uint32_t ret = LOCAL_GL_NONE;
|
||||
TexType type = fba.Texture()->ImageInfoAt(fba.ImageTarget(),
|
||||
fba.MipLevel()).Type();
|
||||
TexInternalFormat effectiveinternalformat =
|
||||
fba.Texture()->ImageInfoAt(fba.ImageTarget(), fba.MipLevel()).EffectiveInternalFormat();
|
||||
TexType type = TypeFromInternalFormat(effectiveinternalformat);
|
||||
GLenum ret = LOCAL_GL_NONE;
|
||||
switch (type.get()) {
|
||||
case LOCAL_GL_UNSIGNED_BYTE:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
@ -1235,7 +1229,7 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
|
||||
ret = LOCAL_GL_UNSIGNED_NORMALIZED;
|
||||
break;
|
||||
case LOCAL_GL_FLOAT:
|
||||
case LOCAL_GL_HALF_FLOAT_OES:
|
||||
case LOCAL_GL_HALF_FLOAT:
|
||||
ret = LOCAL_GL_FLOAT;
|
||||
break;
|
||||
case LOCAL_GL_UNSIGNED_SHORT:
|
||||
@ -3353,7 +3347,7 @@ WebGLContext::CompressedTexImage2D(GLenum rawTexImgTarget,
|
||||
MakeContextCurrent();
|
||||
gl->fCompressedTexImage2D(texImageTarget.get(), level, internalformat, width, height, border, byteLength, view.Data());
|
||||
|
||||
tex->SetImageInfo(texImageTarget, level, width, height, internalformat, LOCAL_GL_UNSIGNED_BYTE,
|
||||
tex->SetImageInfo(texImageTarget, level, width, height, internalformat,
|
||||
WebGLImageDataStatus::InitializedImageData);
|
||||
}
|
||||
|
||||
@ -3387,7 +3381,7 @@ WebGLContext::CompressedTexSubImage2D(GLenum rawTexImgTarget, GLint level, GLint
|
||||
MOZ_ASSERT(tex);
|
||||
WebGLTexture::ImageInfo& levelInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||
|
||||
if (internalformat != levelInfo.InternalFormat()) {
|
||||
if (internalformat != levelInfo.EffectiveInternalFormat()) {
|
||||
return ErrorInvalidOperation("compressedTexImage2D: internalformat does not match the existing image");
|
||||
}
|
||||
|
||||
@ -3599,7 +3593,7 @@ WebGLContext::GetShaderTranslatedSource(WebGLShader *shader, nsAString& retval)
|
||||
|
||||
GLenum WebGLContext::CheckedTexImage2D(TexImageTarget texImageTarget,
|
||||
GLint level,
|
||||
TexInternalFormat internalFormat,
|
||||
TexInternalFormat internalformat,
|
||||
GLsizei width,
|
||||
GLsizei height,
|
||||
GLint border,
|
||||
@ -3610,20 +3604,26 @@ GLenum WebGLContext::CheckedTexImage2D(TexImageTarget texImageTarget,
|
||||
WebGLTexture *tex = activeBoundTextureForTexImageTarget(texImageTarget);
|
||||
MOZ_ASSERT(tex != nullptr, "no texture bound");
|
||||
|
||||
TexInternalFormat effectiveInternalFormat =
|
||||
EffectiveInternalFormatFromInternalFormatAndType(internalformat, type);
|
||||
bool sizeMayChange = true;
|
||||
|
||||
if (tex->HasImageInfoAt(texImageTarget, level)) {
|
||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||
sizeMayChange = width != imageInfo.Width() ||
|
||||
height != imageInfo.Height() ||
|
||||
internalFormat != imageInfo.InternalFormat();
|
||||
effectiveInternalFormat != imageInfo.EffectiveInternalFormat();
|
||||
}
|
||||
|
||||
// Convert to format and type required by OpenGL 'driver'.
|
||||
GLenum driverType = DriverTypeFromType(gl, type);
|
||||
GLenum driverType = LOCAL_GL_NONE;
|
||||
GLenum driverInternalFormat = LOCAL_GL_NONE;
|
||||
GLenum driverFormat = LOCAL_GL_NONE;
|
||||
DriverFormatsFromFormatAndType(gl, internalFormat, type, &driverInternalFormat, &driverFormat);
|
||||
DriverFormatsFromEffectiveInternalFormat(gl,
|
||||
effectiveInternalFormat,
|
||||
&driverInternalFormat,
|
||||
&driverFormat,
|
||||
&driverType);
|
||||
|
||||
if (sizeMayChange) {
|
||||
GetAndFlushUnderlyingGLErrors();
|
||||
@ -3652,6 +3652,10 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||
{
|
||||
const WebGLTexImageFunc func = WebGLTexImageFunc::TexImage;
|
||||
|
||||
if (type == LOCAL_GL_HALF_FLOAT_OES) {
|
||||
type = LOCAL_GL_HALF_FLOAT;
|
||||
}
|
||||
|
||||
if (!ValidateTexImage(2, texImageTarget, level, internalformat,
|
||||
0, 0, 0,
|
||||
width, height, 0,
|
||||
@ -3674,7 +3678,14 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||
if (!ValidateTexInputData(type, jsArrayType, func))
|
||||
return;
|
||||
|
||||
WebGLTexelFormat dstFormat = GetWebGLTexelFormat(internalformat, type);
|
||||
TexInternalFormat effectiveinternalformat =
|
||||
EffectiveInternalFormatFromInternalFormatAndType(internalformat, type);
|
||||
|
||||
if (effectiveinternalformat == LOCAL_GL_NONE) {
|
||||
return ErrorInvalidOperation("texImage2D: bad combination of internalformat and type");
|
||||
}
|
||||
|
||||
WebGLTexelFormat dstFormat = GetWebGLTexelFormat(effectiveinternalformat);
|
||||
WebGLTexelFormat actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
|
||||
|
||||
uint32_t srcTexelSize = WebGLTexelConversions::TexelBytesForFormat(actualSrcFormat);
|
||||
@ -3712,8 +3723,10 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||
WebGLImageDataStatus imageInfoStatusIfSuccess = WebGLImageDataStatus::UninitializedImageData;
|
||||
|
||||
if (byteLength) {
|
||||
size_t bitspertexel = GetBitsPerTexel(effectiveinternalformat);
|
||||
MOZ_ASSERT((bitspertexel % 8) == 0); // should not have compressed formats here.
|
||||
size_t dstTexelSize = bitspertexel / 8;
|
||||
size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
|
||||
uint32_t dstTexelSize = GetBitsPerTexel(internalformat, type) / 8;
|
||||
size_t dstPlainRowSize = dstTexelSize * width;
|
||||
size_t unpackAlignment = mPixelStoreUnpackAlignment;
|
||||
size_t dstStride = ((dstPlainRowSize + unpackAlignment-1) / unpackAlignment) * unpackAlignment;
|
||||
@ -3752,7 +3765,8 @@ WebGLContext::TexImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||
// have NoImageData at this point.
|
||||
MOZ_ASSERT(imageInfoStatusIfSuccess != WebGLImageDataStatus::NoImageData);
|
||||
|
||||
tex->SetImageInfo(texImageTarget, level, width, height, internalformat, type, imageInfoStatusIfSuccess);
|
||||
tex->SetImageInfo(texImageTarget, level, width, height,
|
||||
effectiveinternalformat, imageInfoStatusIfSuccess);
|
||||
}
|
||||
|
||||
void
|
||||
@ -3830,14 +3844,28 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||
{
|
||||
const WebGLTexImageFunc func = WebGLTexImageFunc::TexSubImage;
|
||||
|
||||
if (type == LOCAL_GL_HALF_FLOAT_OES) {
|
||||
type = LOCAL_GL_HALF_FLOAT;
|
||||
}
|
||||
|
||||
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(),
|
||||
if (!tex->HasImageInfoAt(texImageTarget, level)) {
|
||||
return ErrorInvalidOperation("texSubImage2D: no previously defined texture image");
|
||||
}
|
||||
|
||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||
const TexInternalFormat existingEffectiveInternalFormat = imageInfo.EffectiveInternalFormat();
|
||||
TexInternalFormat existingUnsizedInternalFormat = LOCAL_GL_NONE;
|
||||
TexType existingType = LOCAL_GL_NONE;
|
||||
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(existingEffectiveInternalFormat,
|
||||
&existingUnsizedInternalFormat,
|
||||
&existingType);
|
||||
|
||||
if (!ValidateTexImage(2, texImageTarget, level, existingUnsizedInternalFormat.get(),
|
||||
xoffset, yoffset, 0,
|
||||
width, height, 0,
|
||||
0, format, type, func))
|
||||
@ -3848,11 +3876,11 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||
if (!ValidateTexInputData(type, jsArrayType, func))
|
||||
return;
|
||||
|
||||
if (imageInfo.Type() != type) {
|
||||
return ErrorInvalidOperation("texSubImage2D: type parameter does not match the existing image");
|
||||
if (type != existingType) {
|
||||
return ErrorInvalidOperation("texSubImage2D: type differs from that of the existing image");
|
||||
}
|
||||
|
||||
WebGLTexelFormat dstFormat = GetWebGLTexelFormat(internalformat, type);
|
||||
WebGLTexelFormat dstFormat = GetWebGLTexelFormat(existingEffectiveInternalFormat);
|
||||
WebGLTexelFormat actualSrcFormat = srcFormat == WebGLTexelFormat::Auto ? dstFormat : srcFormat;
|
||||
|
||||
uint32_t srcTexelSize = WebGLTexelConversions::TexelBytesForFormat(actualSrcFormat);
|
||||
@ -3882,7 +3910,7 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||
MakeContextCurrent();
|
||||
|
||||
size_t srcStride = srcStrideOrZero ? srcStrideOrZero : checked_alignedRowSize.value();
|
||||
uint32_t dstTexelSize = GetBitsPerTexel(internalformat, type) / 8;
|
||||
uint32_t dstTexelSize = GetBitsPerTexel(existingEffectiveInternalFormat) / 8;
|
||||
size_t dstPlainRowSize = dstTexelSize * width;
|
||||
// There are checks above to ensure that this won't overflow.
|
||||
size_t dstStride = RoundedToNextMultipleOf(dstPlainRowSize, mPixelStoreUnpackAlignment).value();
|
||||
@ -3906,10 +3934,14 @@ WebGLContext::TexSubImage2D_base(TexImageTarget texImageTarget, GLint level,
|
||||
pixels = reinterpret_cast<void*>(convertedData.get());
|
||||
}
|
||||
|
||||
GLenum driverType = DriverTypeFromType(gl, type);
|
||||
GLenum driverType = LOCAL_GL_NONE;
|
||||
GLenum driverInternalFormat = LOCAL_GL_NONE;
|
||||
GLenum driverFormat = LOCAL_GL_NONE;
|
||||
DriverFormatsFromFormatAndType(gl, internalformat, type, &driverInternalFormat, &driverFormat);
|
||||
DriverFormatsFromEffectiveInternalFormat(gl,
|
||||
existingEffectiveInternalFormat,
|
||||
&driverInternalFormat,
|
||||
&driverFormat,
|
||||
&driverType);
|
||||
|
||||
gl->fTexSubImage2D(texImageTarget.get(), level, xoffset, yoffset, width, height, driverFormat, driverType, pixels);
|
||||
}
|
||||
@ -4066,119 +4098,37 @@ BaseTypeAndSizeFromUniformType(GLenum uType, GLenum *baseType, GLint *unitSize)
|
||||
}
|
||||
|
||||
|
||||
WebGLTexelFormat mozilla::GetWebGLTexelFormat(TexInternalFormat internalformat, TexType type)
|
||||
WebGLTexelFormat
|
||||
mozilla::GetWebGLTexelFormat(TexInternalFormat effectiveinternalformat)
|
||||
{
|
||||
//
|
||||
// WEBGL_depth_texture
|
||||
if (internalformat == LOCAL_GL_DEPTH_COMPONENT) {
|
||||
switch (type.get()) {
|
||||
case LOCAL_GL_UNSIGNED_SHORT:
|
||||
return WebGLTexelFormat::D16;
|
||||
case LOCAL_GL_UNSIGNED_INT:
|
||||
return WebGLTexelFormat::D32;
|
||||
}
|
||||
|
||||
MOZ_CRASH("Invalid WebGL texture format/type?");
|
||||
}
|
||||
|
||||
if (internalformat == LOCAL_GL_DEPTH_STENCIL) {
|
||||
switch (type.get()) {
|
||||
case LOCAL_GL_UNSIGNED_INT_24_8_EXT:
|
||||
return WebGLTexelFormat::D24S8;
|
||||
}
|
||||
|
||||
MOZ_CRASH("Invalid WebGL texture format/type?");
|
||||
}
|
||||
|
||||
if (internalformat == LOCAL_GL_DEPTH_COMPONENT16) {
|
||||
return WebGLTexelFormat::D16;
|
||||
}
|
||||
|
||||
if (internalformat == LOCAL_GL_DEPTH_COMPONENT32) {
|
||||
return WebGLTexelFormat::D32;
|
||||
}
|
||||
|
||||
if (internalformat == LOCAL_GL_DEPTH24_STENCIL8) {
|
||||
return WebGLTexelFormat::D24S8;
|
||||
}
|
||||
|
||||
if (type == LOCAL_GL_UNSIGNED_BYTE) {
|
||||
switch (internalformat.get()) {
|
||||
case LOCAL_GL_RGBA:
|
||||
case LOCAL_GL_SRGB_ALPHA_EXT:
|
||||
return WebGLTexelFormat::RGBA8;
|
||||
case LOCAL_GL_RGB:
|
||||
case LOCAL_GL_SRGB_EXT:
|
||||
return WebGLTexelFormat::RGB8;
|
||||
case LOCAL_GL_ALPHA:
|
||||
return WebGLTexelFormat::A8;
|
||||
case LOCAL_GL_LUMINANCE:
|
||||
return WebGLTexelFormat::R8;
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
return WebGLTexelFormat::RA8;
|
||||
}
|
||||
|
||||
MOZ_CRASH("Invalid WebGL texture format/type?");
|
||||
}
|
||||
|
||||
if (type == LOCAL_GL_FLOAT) {
|
||||
// OES_texture_float
|
||||
switch (internalformat.get()) {
|
||||
case LOCAL_GL_RGBA:
|
||||
case LOCAL_GL_RGBA32F:
|
||||
return WebGLTexelFormat::RGBA32F;
|
||||
case LOCAL_GL_RGB:
|
||||
case LOCAL_GL_RGB32F:
|
||||
return WebGLTexelFormat::RGB32F;
|
||||
case LOCAL_GL_ALPHA:
|
||||
case LOCAL_GL_ALPHA32F_ARB:
|
||||
return WebGLTexelFormat::A32F;
|
||||
case LOCAL_GL_LUMINANCE:
|
||||
case LOCAL_GL_LUMINANCE32F_ARB:
|
||||
return WebGLTexelFormat::R32F;
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
case LOCAL_GL_LUMINANCE_ALPHA32F_ARB:
|
||||
return WebGLTexelFormat::RA32F;
|
||||
}
|
||||
|
||||
MOZ_CRASH("Invalid WebGL texture format/type?");
|
||||
} else if (type == LOCAL_GL_HALF_FLOAT_OES) {
|
||||
// OES_texture_half_float
|
||||
switch (internalformat.get()) {
|
||||
case LOCAL_GL_RGBA:
|
||||
case LOCAL_GL_RGBA16F:
|
||||
return WebGLTexelFormat::RGBA16F;
|
||||
case LOCAL_GL_RGB:
|
||||
case LOCAL_GL_RGB16F:
|
||||
return WebGLTexelFormat::RGB16F;
|
||||
case LOCAL_GL_ALPHA:
|
||||
case LOCAL_GL_ALPHA16F_ARB:
|
||||
return WebGLTexelFormat::A16F;
|
||||
case LOCAL_GL_LUMINANCE:
|
||||
case LOCAL_GL_LUMINANCE16F_ARB:
|
||||
return WebGLTexelFormat::R16F;
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
case LOCAL_GL_LUMINANCE_ALPHA16F_ARB:
|
||||
return WebGLTexelFormat::RA16F;
|
||||
default:
|
||||
MOZ_ASSERT(false, "Coding mistake?! Should never reach this point.");
|
||||
return WebGLTexelFormat::BadFormat;
|
||||
}
|
||||
}
|
||||
|
||||
switch (type.get()) {
|
||||
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
return WebGLTexelFormat::RGBA4444;
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
return WebGLTexelFormat::RGBA5551;
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
|
||||
return WebGLTexelFormat::RGB565;
|
||||
switch (effectiveinternalformat.get()) {
|
||||
case LOCAL_GL_DEPTH_COMPONENT16: return WebGLTexelFormat::D16;
|
||||
case LOCAL_GL_DEPTH_COMPONENT24: return WebGLTexelFormat::D32;
|
||||
case LOCAL_GL_DEPTH24_STENCIL8: return WebGLTexelFormat::D24S8;
|
||||
case LOCAL_GL_RGBA8: return WebGLTexelFormat::RGBA8;
|
||||
case LOCAL_GL_SRGB8_ALPHA8: return WebGLTexelFormat::RGBA8;
|
||||
case LOCAL_GL_RGB8: return WebGLTexelFormat::RGB8;
|
||||
case LOCAL_GL_SRGB8: return WebGLTexelFormat::RGB8;
|
||||
case LOCAL_GL_ALPHA8: return WebGLTexelFormat::A8;
|
||||
case LOCAL_GL_LUMINANCE8: return WebGLTexelFormat::R8;
|
||||
case LOCAL_GL_LUMINANCE8_ALPHA8: return WebGLTexelFormat::RA8;
|
||||
case LOCAL_GL_RGBA32F: return WebGLTexelFormat::RGBA32F;
|
||||
case LOCAL_GL_RGB32F: return WebGLTexelFormat::RGB32F;
|
||||
case LOCAL_GL_ALPHA32F_EXT: return WebGLTexelFormat::A32F;
|
||||
case LOCAL_GL_LUMINANCE32F_EXT: return WebGLTexelFormat::R32F;
|
||||
case LOCAL_GL_LUMINANCE_ALPHA32F_EXT: return WebGLTexelFormat::RA32F;
|
||||
case LOCAL_GL_RGBA16F: return WebGLTexelFormat::RGBA16F;
|
||||
case LOCAL_GL_RGB16F: return WebGLTexelFormat::RGB16F;
|
||||
case LOCAL_GL_ALPHA16F_EXT: return WebGLTexelFormat::A16F;
|
||||
case LOCAL_GL_LUMINANCE16F_EXT: return WebGLTexelFormat::R16F;
|
||||
case LOCAL_GL_LUMINANCE_ALPHA16F_EXT: return WebGLTexelFormat::RA16F;
|
||||
case LOCAL_GL_RGBA4: return WebGLTexelFormat::RGBA4444;
|
||||
case LOCAL_GL_RGB5_A1: return WebGLTexelFormat::RGBA5551;
|
||||
case LOCAL_GL_RGB565: return WebGLTexelFormat::RGB565;
|
||||
default:
|
||||
MOZ_ASSERT(false, "Coding mistake?! Should never reach this point.");
|
||||
MOZ_CRASH("Unhandled format");
|
||||
return WebGLTexelFormat::BadFormat;
|
||||
}
|
||||
|
||||
MOZ_CRASH("Invalid WebGL texture format/type?");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -31,29 +31,28 @@ namespace mozilla {
|
||||
using namespace gl;
|
||||
|
||||
bool
|
||||
IsGLDepthFormat(TexInternalFormat webGLFormat)
|
||||
IsGLDepthFormat(TexInternalFormat internalformat)
|
||||
{
|
||||
return (webGLFormat == LOCAL_GL_DEPTH_COMPONENT ||
|
||||
webGLFormat == LOCAL_GL_DEPTH_COMPONENT16 ||
|
||||
webGLFormat == LOCAL_GL_DEPTH_COMPONENT32);
|
||||
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
|
||||
return unsizedformat == LOCAL_GL_DEPTH_COMPONENT;
|
||||
}
|
||||
|
||||
bool
|
||||
IsGLDepthStencilFormat(TexInternalFormat webGLFormat)
|
||||
IsGLDepthStencilFormat(TexInternalFormat internalformat)
|
||||
{
|
||||
return (webGLFormat == LOCAL_GL_DEPTH_STENCIL ||
|
||||
webGLFormat == LOCAL_GL_DEPTH24_STENCIL8);
|
||||
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
|
||||
return unsizedformat == LOCAL_GL_DEPTH_STENCIL;
|
||||
}
|
||||
|
||||
bool
|
||||
FormatHasAlpha(TexInternalFormat webGLFormat)
|
||||
FormatHasAlpha(TexInternalFormat internalformat)
|
||||
{
|
||||
return webGLFormat == LOCAL_GL_RGBA ||
|
||||
webGLFormat == LOCAL_GL_LUMINANCE_ALPHA ||
|
||||
webGLFormat == LOCAL_GL_ALPHA ||
|
||||
webGLFormat == LOCAL_GL_RGBA4 ||
|
||||
webGLFormat == LOCAL_GL_RGB5_A1 ||
|
||||
webGLFormat == LOCAL_GL_SRGB_ALPHA;
|
||||
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
|
||||
return unsizedformat == LOCAL_GL_RGBA ||
|
||||
unsizedformat == LOCAL_GL_LUMINANCE_ALPHA ||
|
||||
unsizedformat == LOCAL_GL_ALPHA ||
|
||||
unsizedformat == LOCAL_GL_SRGB_ALPHA ||
|
||||
unsizedformat == LOCAL_GL_RGBA_INTEGER;
|
||||
}
|
||||
|
||||
TexTarget
|
||||
@ -76,11 +75,12 @@ TexImageTargetToTexTarget(TexImageTarget texImageTarget)
|
||||
}
|
||||
}
|
||||
|
||||
GLComponents::GLComponents(TexInternalFormat format)
|
||||
GLComponents::GLComponents(TexInternalFormat internalformat)
|
||||
{
|
||||
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
|
||||
mComponents = 0;
|
||||
|
||||
switch (format.get()) {
|
||||
switch (unsizedformat.get()) {
|
||||
case LOCAL_GL_RGBA:
|
||||
case LOCAL_GL_RGBA4:
|
||||
case LOCAL_GL_RGBA8:
|
||||
@ -117,152 +117,277 @@ GLComponents::IsSubsetOf(const GLComponents& other) const
|
||||
return (mComponents | other.mComponents) == other.mComponents;
|
||||
}
|
||||
|
||||
TexType
|
||||
TypeFromInternalFormat(TexInternalFormat internalformat)
|
||||
{
|
||||
#define HANDLE_WEBGL_INTERNAL_FORMAT(table_effectiveinternalformat, table_internalformat, table_type) \
|
||||
if (internalformat == table_effectiveinternalformat) { \
|
||||
return table_type; \
|
||||
}
|
||||
|
||||
#include "WebGLInternalFormatsTable.h"
|
||||
|
||||
// if we're here, then internalformat is not an effective internalformat i.e. is an unsized internalformat.
|
||||
return LOCAL_GL_NONE; // no size, no type
|
||||
}
|
||||
|
||||
TexInternalFormat
|
||||
UnsizedInternalFormatFromInternalFormat(TexInternalFormat internalformat)
|
||||
{
|
||||
#define HANDLE_WEBGL_INTERNAL_FORMAT(table_effectiveinternalformat, table_internalformat, table_type) \
|
||||
if (internalformat == table_effectiveinternalformat) { \
|
||||
return table_internalformat; \
|
||||
}
|
||||
|
||||
#include "WebGLInternalFormatsTable.h"
|
||||
|
||||
// if we're here, then internalformat is not an effective internalformat i.e. is an unsized internalformat.
|
||||
// so we can just return it.
|
||||
return internalformat;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that the following two functions are inverse of each other:
|
||||
* EffectiveInternalFormatFromInternalFormatAndType and
|
||||
* InternalFormatAndTypeFromEffectiveInternalFormat both implement OpenGL ES 3.0.3 Table 3.2
|
||||
* but in opposite directions.
|
||||
*/
|
||||
TexInternalFormat
|
||||
EffectiveInternalFormatFromUnsizedInternalFormatAndType(TexInternalFormat internalformat,
|
||||
TexType type)
|
||||
{
|
||||
MOZ_ASSERT(TypeFromInternalFormat(internalformat) == LOCAL_GL_NONE);
|
||||
|
||||
#define HANDLE_WEBGL_INTERNAL_FORMAT(table_effectiveinternalformat, table_internalformat, table_type) \
|
||||
if (internalformat == table_internalformat && type == table_type) { \
|
||||
return table_effectiveinternalformat; \
|
||||
}
|
||||
|
||||
#include "WebGLInternalFormatsTable.h"
|
||||
|
||||
// If we're here, that means that type was incompatible with the given internalformat.
|
||||
return LOCAL_GL_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(TexInternalFormat effectiveinternalformat,
|
||||
TexInternalFormat* out_internalformat,
|
||||
TexType* out_type)
|
||||
{
|
||||
MOZ_ASSERT(TypeFromInternalFormat(effectiveinternalformat) != LOCAL_GL_NONE);
|
||||
|
||||
MOZ_ASSERT(out_internalformat);
|
||||
MOZ_ASSERT(out_type);
|
||||
|
||||
GLenum internalformat = LOCAL_GL_NONE;
|
||||
GLenum type = LOCAL_GL_NONE;
|
||||
|
||||
switch (effectiveinternalformat.get()) {
|
||||
|
||||
#define HANDLE_WEBGL_INTERNAL_FORMAT(table_effectiveinternalformat, table_internalformat, table_type) \
|
||||
case table_effectiveinternalformat: \
|
||||
internalformat = table_internalformat; \
|
||||
type = table_type; \
|
||||
break;
|
||||
|
||||
#include "WebGLInternalFormatsTable.h"
|
||||
|
||||
default:
|
||||
MOZ_CRASH(); // impossible to get here
|
||||
}
|
||||
|
||||
*out_internalformat = internalformat;
|
||||
*out_type = type;
|
||||
}
|
||||
|
||||
TexInternalFormat
|
||||
EffectiveInternalFormatFromInternalFormatAndType(TexInternalFormat internalformat,
|
||||
TexType type)
|
||||
{
|
||||
TexType typeOfInternalFormat = TypeFromInternalFormat(internalformat);
|
||||
if (typeOfInternalFormat == LOCAL_GL_NONE) {
|
||||
return EffectiveInternalFormatFromUnsizedInternalFormatAndType(internalformat, type);
|
||||
} else if (typeOfInternalFormat == type) {
|
||||
return internalformat;
|
||||
} else {
|
||||
return LOCAL_GL_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert WebGL/ES format and type into GL internal
|
||||
* format valid for underlying driver.
|
||||
* Convert effective internalformat into GL function parameters
|
||||
* valid for underlying driver.
|
||||
*/
|
||||
void
|
||||
DriverFormatsFromFormatAndType(GLContext* gl, TexInternalFormat webGLInternalFormat, TexType webGLType,
|
||||
GLenum* out_driverInternalFormat, GLenum* out_driverFormat)
|
||||
DriverFormatsFromEffectiveInternalFormat(gl::GLContext* gl,
|
||||
TexInternalFormat effectiveinternalformat,
|
||||
GLenum* out_driverInternalFormat,
|
||||
GLenum* out_driverFormat,
|
||||
GLenum* out_driverType)
|
||||
{
|
||||
MOZ_ASSERT(out_driverInternalFormat);
|
||||
MOZ_ASSERT(out_driverFormat);
|
||||
MOZ_ASSERT(out_driverType);
|
||||
|
||||
// ES2 requires that format == internalformat; floating-point is
|
||||
// indicated purely by the type that's loaded. For desktop GL, we
|
||||
// have to specify a floating point internal format.
|
||||
if (gl->IsGLES()) {
|
||||
*out_driverFormat = *out_driverInternalFormat = webGLInternalFormat.get();
|
||||
return;
|
||||
TexInternalFormat unsizedinternalformat = LOCAL_GL_NONE;
|
||||
TexType type = LOCAL_GL_NONE;
|
||||
|
||||
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(effectiveinternalformat,
|
||||
&unsizedinternalformat, &type);
|
||||
|
||||
// driverType: almost always the generic type that we just got, except on ES
|
||||
// we must replace HALF_FLOAT by HALF_FLOAT_OES
|
||||
GLenum driverType = type.get();
|
||||
if (gl->IsGLES() && type == LOCAL_GL_HALF_FLOAT) {
|
||||
driverType = LOCAL_GL_HALF_FLOAT_OES;
|
||||
}
|
||||
|
||||
GLenum internalFormat = LOCAL_GL_NONE;
|
||||
GLenum format = LOCAL_GL_NONE;
|
||||
// driverFormat: always just the unsized internalformat that we just got
|
||||
GLenum driverFormat = unsizedinternalformat.get();
|
||||
|
||||
if (webGLInternalFormat == LOCAL_GL_DEPTH_COMPONENT) {
|
||||
format = LOCAL_GL_DEPTH_COMPONENT;
|
||||
if (webGLType == LOCAL_GL_UNSIGNED_SHORT)
|
||||
internalFormat = LOCAL_GL_DEPTH_COMPONENT16;
|
||||
else if (webGLType == LOCAL_GL_UNSIGNED_INT)
|
||||
internalFormat = LOCAL_GL_DEPTH_COMPONENT32;
|
||||
} else if (webGLInternalFormat == LOCAL_GL_DEPTH_STENCIL) {
|
||||
format = LOCAL_GL_DEPTH_STENCIL;
|
||||
if (webGLType == LOCAL_GL_UNSIGNED_INT_24_8_EXT)
|
||||
internalFormat = LOCAL_GL_DEPTH24_STENCIL8;
|
||||
} else {
|
||||
switch (webGLType.get()) {
|
||||
case LOCAL_GL_UNSIGNED_BYTE:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
|
||||
format = internalFormat = webGLInternalFormat.get();
|
||||
break;
|
||||
|
||||
case LOCAL_GL_FLOAT:
|
||||
switch (webGLInternalFormat.get()) {
|
||||
case LOCAL_GL_RGBA:
|
||||
format = LOCAL_GL_RGBA;
|
||||
internalFormat = LOCAL_GL_RGBA32F;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_RGB:
|
||||
format = LOCAL_GL_RGB;
|
||||
internalFormat = LOCAL_GL_RGB32F;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_ALPHA:
|
||||
format = LOCAL_GL_ALPHA;
|
||||
internalFormat = LOCAL_GL_ALPHA32F_ARB;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_LUMINANCE:
|
||||
format = LOCAL_GL_LUMINANCE;
|
||||
internalFormat = LOCAL_GL_LUMINANCE32F_ARB;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
format = LOCAL_GL_LUMINANCE_ALPHA;
|
||||
internalFormat = LOCAL_GL_LUMINANCE_ALPHA32F_ARB;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case LOCAL_GL_HALF_FLOAT_OES:
|
||||
switch (webGLInternalFormat.get()) {
|
||||
case LOCAL_GL_RGBA:
|
||||
format = LOCAL_GL_RGBA;
|
||||
internalFormat = LOCAL_GL_RGBA16F;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_RGB:
|
||||
format = LOCAL_GL_RGB;
|
||||
internalFormat = LOCAL_GL_RGB16F;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_ALPHA:
|
||||
format = LOCAL_GL_ALPHA;
|
||||
internalFormat = LOCAL_GL_ALPHA16F_ARB;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_LUMINANCE:
|
||||
format = LOCAL_GL_LUMINANCE;
|
||||
internalFormat = LOCAL_GL_LUMINANCE16F_ARB;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
format = LOCAL_GL_LUMINANCE_ALPHA;
|
||||
internalFormat = LOCAL_GL_LUMINANCE_ALPHA16F_ARB;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
// driverInternalFormat: almost always the same as driverFormat, but on desktop GL,
|
||||
// in some cases we must pass a different value. On ES, they are equal by definition
|
||||
// as it is an error to pass internalformat!=format.
|
||||
GLenum driverInternalFormat = driverFormat;
|
||||
if (!gl->IsGLES()) {
|
||||
// Cases where desktop OpenGL requires a tweak to 'format'
|
||||
if (driverFormat == LOCAL_GL_SRGB) {
|
||||
driverFormat = LOCAL_GL_RGB;
|
||||
} else if (driverFormat == LOCAL_GL_SRGB_ALPHA) {
|
||||
driverFormat = LOCAL_GL_RGBA;
|
||||
}
|
||||
|
||||
// Handle ES2 and GL differences when supporting sRGB internal formats. GL ES
|
||||
// requires that format == internalformat, but GL will fail in this case.
|
||||
// GL requires:
|
||||
// format -> internalformat
|
||||
// GL_RGB GL_SRGB_EXT
|
||||
// GL_RGBA GL_SRGB_ALPHA_EXT
|
||||
switch (webGLInternalFormat.get()) {
|
||||
case LOCAL_GL_SRGB:
|
||||
format = LOCAL_GL_RGB;
|
||||
internalFormat = LOCAL_GL_SRGB;
|
||||
break;
|
||||
case LOCAL_GL_SRGB_ALPHA:
|
||||
format = LOCAL_GL_RGBA;
|
||||
internalFormat = LOCAL_GL_SRGB_ALPHA;
|
||||
break;
|
||||
// Cases where desktop OpenGL requires a sized internalformat,
|
||||
// as opposed to the unsized internalformat that had the same
|
||||
// GLenum value as 'format', in order to get the precise
|
||||
// semantics that we want. For example, for floating-point formats,
|
||||
// we seem to need a sized internalformat to get non-clamped floating
|
||||
// point texture sampling. Can't find the spec reference for that,
|
||||
// but that's at least the case on my NVIDIA driver version 331.
|
||||
if (unsizedinternalformat == LOCAL_GL_DEPTH_COMPONENT ||
|
||||
unsizedinternalformat == LOCAL_GL_DEPTH_STENCIL ||
|
||||
type == LOCAL_GL_FLOAT ||
|
||||
type == LOCAL_GL_HALF_FLOAT)
|
||||
{
|
||||
driverInternalFormat = effectiveinternalformat.get();
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(webGLInternalFormat != LOCAL_GL_NONE && internalFormat != LOCAL_GL_NONE,
|
||||
"Coding mistake -- bad format/type passed?");
|
||||
|
||||
*out_driverInternalFormat = internalFormat;
|
||||
*out_driverFormat = format;
|
||||
*out_driverInternalFormat = driverInternalFormat;
|
||||
*out_driverFormat = driverFormat;
|
||||
*out_driverType = driverType;
|
||||
}
|
||||
|
||||
GLenum
|
||||
DriverTypeFromType(GLContext* gl, TexType webGLType)
|
||||
/**
|
||||
* Return the bits per texel for format & type combination.
|
||||
* Assumes that format & type are a valid combination as checked with
|
||||
* ValidateTexImageFormatAndType().
|
||||
*/
|
||||
size_t
|
||||
GetBitsPerTexel(TexInternalFormat effectiveinternalformat)
|
||||
{
|
||||
GLenum type = webGLType.get();
|
||||
switch (effectiveinternalformat.get()) {
|
||||
case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
|
||||
return 2;
|
||||
|
||||
if (gl->IsGLES())
|
||||
return type;
|
||||
case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||
case LOCAL_GL_ATC_RGB:
|
||||
case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
|
||||
case LOCAL_GL_ETC1_RGB8_OES:
|
||||
return 4;
|
||||
|
||||
// convert type for half float if not on GLES2
|
||||
if (type == LOCAL_GL_HALF_FLOAT_OES) {
|
||||
if (gl->IsSupported(gl::GLFeature::texture_half_float)) {
|
||||
return LOCAL_GL_HALF_FLOAT;
|
||||
} else {
|
||||
MOZ_ASSERT(gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float));
|
||||
}
|
||||
case LOCAL_GL_ALPHA8:
|
||||
case LOCAL_GL_LUMINANCE8:
|
||||
case LOCAL_GL_R8:
|
||||
case LOCAL_GL_R8I:
|
||||
case LOCAL_GL_R8UI:
|
||||
case LOCAL_GL_R8_SNORM:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||
case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
|
||||
case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
|
||||
return 8;
|
||||
|
||||
case LOCAL_GL_LUMINANCE8_ALPHA8:
|
||||
case LOCAL_GL_RGBA4:
|
||||
case LOCAL_GL_RGB5_A1:
|
||||
case LOCAL_GL_DEPTH_COMPONENT16:
|
||||
case LOCAL_GL_RG8:
|
||||
case LOCAL_GL_R16I:
|
||||
case LOCAL_GL_R16UI:
|
||||
case LOCAL_GL_RGB565:
|
||||
case LOCAL_GL_R16F:
|
||||
case LOCAL_GL_RG8I:
|
||||
case LOCAL_GL_RG8UI:
|
||||
case LOCAL_GL_RG8_SNORM:
|
||||
case LOCAL_GL_ALPHA16F_EXT:
|
||||
case LOCAL_GL_LUMINANCE16F_EXT:
|
||||
return 16;
|
||||
|
||||
case LOCAL_GL_RGB8:
|
||||
case LOCAL_GL_DEPTH_COMPONENT24:
|
||||
case LOCAL_GL_SRGB8:
|
||||
case LOCAL_GL_RGB8UI:
|
||||
case LOCAL_GL_RGB8I:
|
||||
case LOCAL_GL_RGB8_SNORM:
|
||||
return 24;
|
||||
|
||||
case LOCAL_GL_RGBA8:
|
||||
case LOCAL_GL_RGB10_A2:
|
||||
case LOCAL_GL_R32F:
|
||||
case LOCAL_GL_RG16F:
|
||||
case LOCAL_GL_R32I:
|
||||
case LOCAL_GL_R32UI:
|
||||
case LOCAL_GL_RG16I:
|
||||
case LOCAL_GL_RG16UI:
|
||||
case LOCAL_GL_DEPTH24_STENCIL8:
|
||||
case LOCAL_GL_R11F_G11F_B10F:
|
||||
case LOCAL_GL_RGB9_E5:
|
||||
case LOCAL_GL_SRGB8_ALPHA8:
|
||||
case LOCAL_GL_DEPTH_COMPONENT32F:
|
||||
case LOCAL_GL_RGBA8UI:
|
||||
case LOCAL_GL_RGBA8I:
|
||||
case LOCAL_GL_RGBA8_SNORM:
|
||||
case LOCAL_GL_RGB10_A2UI:
|
||||
case LOCAL_GL_LUMINANCE_ALPHA16F_EXT:
|
||||
case LOCAL_GL_ALPHA32F_EXT:
|
||||
case LOCAL_GL_LUMINANCE32F_EXT:
|
||||
return 32;
|
||||
|
||||
case LOCAL_GL_DEPTH32F_STENCIL8:
|
||||
return 40;
|
||||
|
||||
case LOCAL_GL_RGB16F:
|
||||
case LOCAL_GL_RGB16UI:
|
||||
case LOCAL_GL_RGB16I:
|
||||
return 48;
|
||||
|
||||
case LOCAL_GL_RG32F:
|
||||
case LOCAL_GL_RG32I:
|
||||
case LOCAL_GL_RG32UI:
|
||||
case LOCAL_GL_RGBA16F:
|
||||
case LOCAL_GL_RGBA16UI:
|
||||
case LOCAL_GL_RGBA16I:
|
||||
case LOCAL_GL_LUMINANCE_ALPHA32F_EXT:
|
||||
return 64;
|
||||
|
||||
case LOCAL_GL_RGB32F:
|
||||
case LOCAL_GL_RGB32UI:
|
||||
case LOCAL_GL_RGB32I:
|
||||
return 96;
|
||||
|
||||
case LOCAL_GL_RGBA32F:
|
||||
case LOCAL_GL_RGBA32UI:
|
||||
case LOCAL_GL_RGBA32I:
|
||||
return 128;
|
||||
|
||||
default:
|
||||
MOZ_ASSERT(false, "Unhandled format");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -16,9 +16,28 @@ namespace mozilla {
|
||||
bool IsGLDepthFormat(TexInternalFormat webGLFormat);
|
||||
bool IsGLDepthStencilFormat(TexInternalFormat webGLFormat);
|
||||
bool FormatHasAlpha(TexInternalFormat webGLFormat);
|
||||
void DriverFormatsFromFormatAndType(gl::GLContext* gl, TexInternalFormat webGLFormat, TexType webGLType,
|
||||
GLenum* out_driverInternalFormat, GLenum* out_driverFormat);
|
||||
GLenum DriverTypeFromType(gl::GLContext* gl, TexType webGLType);
|
||||
void
|
||||
DriverFormatsFromEffectiveInternalFormat(gl::GLContext* gl,
|
||||
TexInternalFormat internalformat,
|
||||
GLenum* out_driverInternalFormat,
|
||||
GLenum* out_driverFormat,
|
||||
GLenum* out_driverType);
|
||||
TexInternalFormat
|
||||
EffectiveInternalFormatFromInternalFormatAndType(TexInternalFormat internalformat,
|
||||
TexType type);
|
||||
TexInternalFormat
|
||||
EffectiveInternalFormatFromUnsizedInternalFormatAndType(TexInternalFormat internalformat,
|
||||
TexType type);
|
||||
void
|
||||
UnsizedInternalFormatAndTypeFromEffectiveInternalFormat(TexInternalFormat effectiveinternalformat,
|
||||
TexInternalFormat* out_internalformat,
|
||||
TexType* out_type);
|
||||
TexType
|
||||
TypeFromInternalFormat(TexInternalFormat internalformat);
|
||||
TexInternalFormat
|
||||
UnsizedInternalFormatFromInternalFormat(TexInternalFormat internalformat);
|
||||
size_t
|
||||
GetBitsPerTexel(TexInternalFormat effectiveinternalformat);
|
||||
|
||||
// For use with the different texture calls, i.e.
|
||||
// TexImage2D, CopyTex[Sub]Image2D, ...
|
||||
|
@ -673,7 +673,7 @@ WebGLContext::ValidateTexImageType(GLenum type,
|
||||
}
|
||||
|
||||
/* OES_texture_half_float add types */
|
||||
if (type == LOCAL_GL_HALF_FLOAT_OES) {
|
||||
if (type == LOCAL_GL_HALF_FLOAT) {
|
||||
bool validType = IsExtensionEnabled(WebGLExtensionID::OES_texture_half_float);
|
||||
if (!validType)
|
||||
ErrorInvalidEnum("%s: invalid type %s: need OES_texture_half_float enabled",
|
||||
@ -1025,95 +1025,6 @@ WebGLContext::ValidateTexSubImageSize(GLint xoffset, GLint yoffset, GLint /*zoff
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bits per texel for format & type combination.
|
||||
* Assumes that format & type are a valid combination as checked with
|
||||
* ValidateTexImageFormatAndType().
|
||||
*/
|
||||
uint32_t
|
||||
WebGLContext::GetBitsPerTexel(TexInternalFormat format, TexType type)
|
||||
{
|
||||
/* Known fixed-sized types */
|
||||
if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
|
||||
type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
|
||||
type == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
if (type == LOCAL_GL_UNSIGNED_INT_24_8)
|
||||
return 32;
|
||||
|
||||
int bitsPerComponent = 0;
|
||||
switch (type.get()) {
|
||||
case LOCAL_GL_UNSIGNED_BYTE:
|
||||
bitsPerComponent = 8;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_HALF_FLOAT:
|
||||
case LOCAL_GL_HALF_FLOAT_OES:
|
||||
case LOCAL_GL_UNSIGNED_SHORT:
|
||||
bitsPerComponent = 16;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_FLOAT:
|
||||
case LOCAL_GL_UNSIGNED_INT:
|
||||
bitsPerComponent = 32;
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_ASSERT(false, "Unhandled type.");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (format.get()) {
|
||||
// Uncompressed formats
|
||||
case LOCAL_GL_ALPHA:
|
||||
case LOCAL_GL_LUMINANCE:
|
||||
case LOCAL_GL_DEPTH_COMPONENT:
|
||||
case LOCAL_GL_DEPTH_STENCIL:
|
||||
return 1 * bitsPerComponent;
|
||||
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
return 2 * bitsPerComponent;
|
||||
|
||||
case LOCAL_GL_RGB:
|
||||
case LOCAL_GL_RGB32F:
|
||||
case LOCAL_GL_SRGB_EXT:
|
||||
return 3 * bitsPerComponent;
|
||||
|
||||
case LOCAL_GL_RGBA:
|
||||
case LOCAL_GL_RGBA32F:
|
||||
case LOCAL_GL_SRGB_ALPHA_EXT:
|
||||
return 4 * bitsPerComponent;
|
||||
|
||||
// Compressed formats
|
||||
case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
|
||||
return 2;
|
||||
|
||||
case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||
case LOCAL_GL_ATC_RGB:
|
||||
case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
|
||||
case LOCAL_GL_ETC1_RGB8_OES:
|
||||
return 4;
|
||||
|
||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||
case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
|
||||
case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
|
||||
return 8;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(false, "Unhandled format+type combo.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform validation of format/type combinations for TexImage variants.
|
||||
* Returns true if the format/type is a valid combination, false otherwise.
|
||||
@ -1141,7 +1052,6 @@ WebGLContext::ValidateTexImageFormatAndType(GLenum format,
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
validCombo = (type == LOCAL_GL_UNSIGNED_BYTE ||
|
||||
type == LOCAL_GL_HALF_FLOAT ||
|
||||
type == LOCAL_GL_HALF_FLOAT_OES ||
|
||||
type == LOCAL_GL_FLOAT);
|
||||
break;
|
||||
|
||||
@ -1150,7 +1060,6 @@ WebGLContext::ValidateTexImageFormatAndType(GLenum format,
|
||||
validCombo = (type == LOCAL_GL_UNSIGNED_BYTE ||
|
||||
type == LOCAL_GL_UNSIGNED_SHORT_5_6_5 ||
|
||||
type == LOCAL_GL_HALF_FLOAT ||
|
||||
type == LOCAL_GL_HALF_FLOAT_OES ||
|
||||
type == LOCAL_GL_FLOAT);
|
||||
break;
|
||||
|
||||
@ -1160,7 +1069,6 @@ WebGLContext::ValidateTexImageFormatAndType(GLenum format,
|
||||
type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
|
||||
type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
|
||||
type == LOCAL_GL_HALF_FLOAT ||
|
||||
type == LOCAL_GL_HALF_FLOAT_OES ||
|
||||
type == LOCAL_GL_FLOAT);
|
||||
break;
|
||||
|
||||
@ -1291,7 +1199,6 @@ WebGLContext::ValidateTexInputData(GLenum type, int jsArrayType, WebGLTexImageFu
|
||||
break;
|
||||
|
||||
case LOCAL_GL_HALF_FLOAT:
|
||||
case LOCAL_GL_HALF_FLOAT_OES:
|
||||
case LOCAL_GL_UNSIGNED_SHORT:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
@ -1449,6 +1356,7 @@ WebGLContext::ValidateTexImage(GLuint dims, TexImageTarget texImageTarget,
|
||||
}
|
||||
|
||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||
|
||||
if (!ValidateTexSubImageSize(xoffset, yoffset, zoffset,
|
||||
width, height, depth,
|
||||
imageInfo.Width(), imageInfo.Height(), 0,
|
||||
|
@ -79,7 +79,7 @@ WebGLFramebuffer::Attachment::HasAlpha() const
|
||||
MOZ_ASSERT(HasImage());
|
||||
|
||||
if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
|
||||
return FormatHasAlpha(Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).InternalFormat());
|
||||
return FormatHasAlpha(Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).EffectiveInternalFormat());
|
||||
else if (Renderbuffer())
|
||||
return FormatHasAlpha(Renderbuffer()->InternalFormat());
|
||||
else return false;
|
||||
@ -96,7 +96,7 @@ WebGLFramebuffer::GetFormatForAttachment(const WebGLFramebuffer::Attachment& att
|
||||
MOZ_ASSERT(tex.HasImageInfoAt(attachment.ImageTarget(), 0));
|
||||
|
||||
const WebGLTexture::ImageInfo& imgInfo = tex.ImageInfoAt(attachment.ImageTarget(), 0);
|
||||
return imgInfo.InternalFormat().get();
|
||||
return imgInfo.EffectiveInternalFormat().get();
|
||||
}
|
||||
|
||||
if (attachment.Renderbuffer())
|
||||
@ -105,37 +105,30 @@ WebGLFramebuffer::GetFormatForAttachment(const WebGLFramebuffer::Attachment& att
|
||||
return LOCAL_GL_NONE;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLFramebuffer::Attachment::IsReadableFloat() const
|
||||
TexInternalFormat
|
||||
WebGLFramebuffer::Attachment::EffectiveInternalFormat() const
|
||||
{
|
||||
const WebGLTexture* tex = Texture();
|
||||
if (tex && tex->HasImageInfoAt(mTexImageTarget, mTexImageLevel)) {
|
||||
GLenum type = tex->ImageInfoAt(mTexImageTarget, mTexImageLevel).Type().get();
|
||||
switch (type) {
|
||||
case LOCAL_GL_FLOAT:
|
||||
case LOCAL_GL_HALF_FLOAT_OES:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return tex->ImageInfoAt(mTexImageTarget, mTexImageLevel).EffectiveInternalFormat();
|
||||
}
|
||||
|
||||
const WebGLRenderbuffer* rb = Renderbuffer();
|
||||
if (rb) {
|
||||
GLenum format = rb->InternalFormat();
|
||||
switch (format) {
|
||||
case LOCAL_GL_RGB16F:
|
||||
case LOCAL_GL_RGBA16F:
|
||||
case LOCAL_GL_RGB32F:
|
||||
case LOCAL_GL_RGBA32F:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return rb->InternalFormat();
|
||||
}
|
||||
|
||||
// If we arrive here Attachment isn't correct setup because it has
|
||||
// no texture nor render buffer pointer.
|
||||
MOZ_ASSERT(false, "Should not get here.");
|
||||
return false;
|
||||
return LOCAL_GL_NONE;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLFramebuffer::Attachment::IsReadableFloat() const
|
||||
{
|
||||
TexInternalFormat internalformat = EffectiveInternalFormat();
|
||||
MOZ_ASSERT(internalformat != LOCAL_GL_NONE);
|
||||
TexType type = TypeFromInternalFormat(internalformat);
|
||||
return type == LOCAL_GL_FLOAT ||
|
||||
type == LOCAL_GL_HALF_FLOAT;
|
||||
}
|
||||
|
||||
void
|
||||
@ -230,7 +223,7 @@ WebGLFramebuffer::Attachment::RectangleObject() const
|
||||
corresponds to the state that is stored in
|
||||
WebGLTexture::ImageInfo::InternalFormat()*/
|
||||
static inline bool
|
||||
IsValidFBOTextureColorFormat(GLenum internalFormat)
|
||||
IsValidFBOTextureColorFormat(TexInternalFormat internalformat)
|
||||
{
|
||||
/* These formats are internal formats for each texture -- the actual
|
||||
* low level format, which we might have to do conversions for when
|
||||
@ -239,46 +232,26 @@ IsValidFBOTextureColorFormat(GLenum internalFormat)
|
||||
* This function just handles all of them whether desktop GL or ES.
|
||||
*/
|
||||
|
||||
return (
|
||||
/* linear 8-bit formats */
|
||||
internalFormat == LOCAL_GL_ALPHA ||
|
||||
internalFormat == LOCAL_GL_LUMINANCE ||
|
||||
internalFormat == LOCAL_GL_LUMINANCE_ALPHA ||
|
||||
internalFormat == LOCAL_GL_RGB ||
|
||||
internalFormat == LOCAL_GL_RGBA ||
|
||||
/* sRGB 8-bit formats */
|
||||
internalFormat == LOCAL_GL_SRGB_EXT ||
|
||||
internalFormat == LOCAL_GL_SRGB_ALPHA_EXT ||
|
||||
/* linear float32 formats */
|
||||
internalFormat == LOCAL_GL_ALPHA32F_ARB ||
|
||||
internalFormat == LOCAL_GL_LUMINANCE32F_ARB ||
|
||||
internalFormat == LOCAL_GL_LUMINANCE_ALPHA32F_ARB ||
|
||||
internalFormat == LOCAL_GL_RGB32F_ARB ||
|
||||
internalFormat == LOCAL_GL_RGBA32F_ARB ||
|
||||
/* texture_half_float formats */
|
||||
internalFormat == LOCAL_GL_ALPHA16F_ARB ||
|
||||
internalFormat == LOCAL_GL_LUMINANCE16F_ARB ||
|
||||
internalFormat == LOCAL_GL_LUMINANCE_ALPHA16F_ARB ||
|
||||
internalFormat == LOCAL_GL_RGB16F_ARB ||
|
||||
internalFormat == LOCAL_GL_RGBA16F_ARB
|
||||
);
|
||||
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
|
||||
return unsizedformat == LOCAL_GL_ALPHA ||
|
||||
unsizedformat == LOCAL_GL_LUMINANCE ||
|
||||
unsizedformat == LOCAL_GL_LUMINANCE_ALPHA ||
|
||||
unsizedformat == LOCAL_GL_RGB ||
|
||||
unsizedformat == LOCAL_GL_RGBA ||
|
||||
unsizedformat == LOCAL_GL_SRGB ||
|
||||
unsizedformat == LOCAL_GL_SRGB_ALPHA;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsValidFBOTextureDepthFormat(GLenum internalFormat)
|
||||
IsValidFBOTextureDepthFormat(GLenum internalformat)
|
||||
{
|
||||
return (
|
||||
internalFormat == LOCAL_GL_DEPTH_COMPONENT ||
|
||||
internalFormat == LOCAL_GL_DEPTH_COMPONENT16 ||
|
||||
internalFormat == LOCAL_GL_DEPTH_COMPONENT32);
|
||||
return IsGLDepthFormat(internalformat);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsValidFBOTextureDepthStencilFormat(GLenum internalFormat)
|
||||
IsValidFBOTextureDepthStencilFormat(GLenum internalformat)
|
||||
{
|
||||
return (
|
||||
internalFormat == LOCAL_GL_DEPTH_STENCIL ||
|
||||
internalFormat == LOCAL_GL_DEPTH24_STENCIL8);
|
||||
return IsGLDepthStencilFormat(internalformat);
|
||||
}
|
||||
|
||||
/* The following IsValidFBORenderbufferXXX functions check the internal
|
||||
@ -330,7 +303,7 @@ WebGLFramebuffer::Attachment::IsComplete() const
|
||||
MOZ_ASSERT(Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel));
|
||||
const WebGLTexture::ImageInfo& imageInfo =
|
||||
Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel);
|
||||
GLenum internalformat = imageInfo.InternalFormat().get();
|
||||
GLenum internalformat = imageInfo.EffectiveInternalFormat().get();
|
||||
|
||||
if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT)
|
||||
return IsValidFBOTextureDepthFormat(internalformat);
|
||||
|
@ -53,6 +53,8 @@ public:
|
||||
|
||||
bool IsDeleteRequested() const;
|
||||
|
||||
TexInternalFormat EffectiveInternalFormat() const;
|
||||
|
||||
bool HasAlpha() const;
|
||||
bool IsReadableFloat() const;
|
||||
|
||||
|
82
dom/canvas/WebGLInternalFormatsTable.h
Normal file
82
dom/canvas/WebGLInternalFormatsTable.h
Normal file
@ -0,0 +1,82 @@
|
||||
// intentionally no include guard here.
|
||||
|
||||
#ifndef HANDLE_WEBGL_INTERNAL_FORMAT
|
||||
#error This header is meant to be included by other files defining HANDLE_WEBGL_INTERNAL_FORMAT.
|
||||
#endif
|
||||
|
||||
#define WEBGL_INTERNAL_FORMAT(effectiveinternalformat, unsizedinternalformat, type) \
|
||||
HANDLE_WEBGL_INTERNAL_FORMAT(LOCAL_GL_##effectiveinternalformat, \
|
||||
LOCAL_GL_##unsizedinternalformat, \
|
||||
LOCAL_GL_##type)
|
||||
|
||||
// OpenGL ES 3.0.3, Table 3.2
|
||||
//
|
||||
// Maps effective internal formats to (unsized internal format, type) pairs.
|
||||
//
|
||||
// Effective int. fmt. Unsized int. fmt. Type
|
||||
WEBGL_INTERNAL_FORMAT(ALPHA8, ALPHA, UNSIGNED_BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(LUMINANCE8, LUMINANCE, UNSIGNED_BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(LUMINANCE8_ALPHA8, LUMINANCE_ALPHA, UNSIGNED_BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(RGB8, RGB, UNSIGNED_BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(RGBA4, RGBA, UNSIGNED_SHORT_4_4_4_4)
|
||||
WEBGL_INTERNAL_FORMAT(RGB5_A1, RGBA, UNSIGNED_SHORT_5_5_5_1)
|
||||
WEBGL_INTERNAL_FORMAT(RGBA8, RGBA, UNSIGNED_BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(RGB10_A2, RGB, UNSIGNED_INT_2_10_10_10_REV)
|
||||
WEBGL_INTERNAL_FORMAT(DEPTH_COMPONENT16, DEPTH_COMPONENT, UNSIGNED_SHORT)
|
||||
WEBGL_INTERNAL_FORMAT(DEPTH_COMPONENT24, DEPTH_COMPONENT, UNSIGNED_INT)
|
||||
WEBGL_INTERNAL_FORMAT(R8, RED, UNSIGNED_BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(RG8, RG, UNSIGNED_BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(R16F, RED, HALF_FLOAT)
|
||||
WEBGL_INTERNAL_FORMAT(R32F, RED, FLOAT)
|
||||
WEBGL_INTERNAL_FORMAT(RG16F, RG, HALF_FLOAT)
|
||||
WEBGL_INTERNAL_FORMAT(RG32F, RG, UNSIGNED_BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(R8I, RED_INTEGER, BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(R8UI, RED_INTEGER, UNSIGNED_BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(R16I, RED_INTEGER, BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(R16UI, RED_INTEGER, UNSIGNED_SHORT)
|
||||
WEBGL_INTERNAL_FORMAT(R32I, RED_INTEGER, INT)
|
||||
WEBGL_INTERNAL_FORMAT(R32UI, RED_INTEGER, UNSIGNED_INT)
|
||||
WEBGL_INTERNAL_FORMAT(RG8I, RG_INTEGER, BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(RG8UI, RG_INTEGER, UNSIGNED_BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(RG16I, RG_INTEGER, SHORT)
|
||||
WEBGL_INTERNAL_FORMAT(RG16UI, RG_INTEGER, UNSIGNED_SHORT)
|
||||
WEBGL_INTERNAL_FORMAT(RG32I, RG_INTEGER, INT)
|
||||
WEBGL_INTERNAL_FORMAT(RG32UI, RG_INTEGER, UNSIGNED_INT)
|
||||
WEBGL_INTERNAL_FORMAT(RGBA32F, RGBA, FLOAT)
|
||||
WEBGL_INTERNAL_FORMAT(RGB32F, RGB, FLOAT)
|
||||
WEBGL_INTERNAL_FORMAT(ALPHA32F_EXT, ALPHA, FLOAT)
|
||||
WEBGL_INTERNAL_FORMAT(LUMINANCE32F_EXT, LUMINANCE, FLOAT)
|
||||
WEBGL_INTERNAL_FORMAT(LUMINANCE_ALPHA32F_EXT, LUMINANCE_ALPHA, FLOAT)
|
||||
WEBGL_INTERNAL_FORMAT(RGBA16F, RGBA, HALF_FLOAT)
|
||||
WEBGL_INTERNAL_FORMAT(RGB16F, RGB, HALF_FLOAT)
|
||||
WEBGL_INTERNAL_FORMAT(ALPHA16F_EXT, ALPHA, HALF_FLOAT)
|
||||
WEBGL_INTERNAL_FORMAT(LUMINANCE16F_EXT, LUMINANCE, HALF_FLOAT)
|
||||
WEBGL_INTERNAL_FORMAT(LUMINANCE_ALPHA16F_EXT, LUMINANCE_ALPHA, HALF_FLOAT)
|
||||
WEBGL_INTERNAL_FORMAT(DEPTH24_STENCIL8, DEPTH_STENCIL, UNSIGNED_INT_24_8)
|
||||
WEBGL_INTERNAL_FORMAT(R11F_G11F_B10F, RGB, UNSIGNED_INT_10F_11F_11F_REV)
|
||||
WEBGL_INTERNAL_FORMAT(RGB9_E5, RGB, UNSIGNED_INT_5_9_9_9_REV)
|
||||
WEBGL_INTERNAL_FORMAT(SRGB8, SRGB, UNSIGNED_BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(SRGB8_ALPHA8, SRGB_ALPHA, UNSIGNED_BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(DEPTH_COMPONENT32F, DEPTH_COMPONENT, FLOAT)
|
||||
WEBGL_INTERNAL_FORMAT(DEPTH32F_STENCIL8, DEPTH_STENCIL, FLOAT_32_UNSIGNED_INT_24_8_REV)
|
||||
WEBGL_INTERNAL_FORMAT(RGB565, RGB, UNSIGNED_SHORT_5_6_5)
|
||||
WEBGL_INTERNAL_FORMAT(RGBA32UI, RGBA_INTEGER, UNSIGNED_INT)
|
||||
WEBGL_INTERNAL_FORMAT(RGB32UI, RGB_INTEGER, UNSIGNED_INT)
|
||||
WEBGL_INTERNAL_FORMAT(RGBA16UI, RGBA_INTEGER, UNSIGNED_SHORT)
|
||||
WEBGL_INTERNAL_FORMAT(RGB16UI, RGB_INTEGER, UNSIGNED_SHORT)
|
||||
WEBGL_INTERNAL_FORMAT(RGBA8UI, RGBA_INTEGER, UNSIGNED_BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(RGB8UI, RGB_INTEGER, UNSIGNED_BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(RGBA32I, RGBA_INTEGER, INT)
|
||||
WEBGL_INTERNAL_FORMAT(RGB32I, RGB_INTEGER, INT)
|
||||
WEBGL_INTERNAL_FORMAT(RGBA16I, RGBA_INTEGER, SHORT)
|
||||
WEBGL_INTERNAL_FORMAT(RGB16I, RGB_INTEGER, SHORT)
|
||||
WEBGL_INTERNAL_FORMAT(RGBA8I, RGBA_INTEGER, BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(RGB8I, RGB_INTEGER, BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(R8_SNORM, RED, BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(RG8_SNORM, RG, BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(RGB8_SNORM, RGB, BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(RGBA8_SNORM, RGBA, BYTE)
|
||||
WEBGL_INTERNAL_FORMAT(RGB10_A2UI, RGBA_INTEGER, UNSIGNED_INT_2_10_10_10_REV)
|
||||
|
||||
#undef WEBGL_INTERNAL_FORMAT
|
||||
#undef HANDLE_WEBGL_INTERNAL_FORMAT
|
@ -299,6 +299,9 @@ STRONG_GLENUM_BEGIN(TexInternalFormat)
|
||||
STRONG_GLENUM_VALUE(RGBA),
|
||||
STRONG_GLENUM_VALUE(LUMINANCE),
|
||||
STRONG_GLENUM_VALUE(LUMINANCE_ALPHA),
|
||||
STRONG_GLENUM_VALUE(ALPHA8),
|
||||
STRONG_GLENUM_VALUE(LUMINANCE8),
|
||||
STRONG_GLENUM_VALUE(LUMINANCE8_ALPHA8),
|
||||
STRONG_GLENUM_VALUE(RGB8),
|
||||
STRONG_GLENUM_VALUE(RGBA4),
|
||||
STRONG_GLENUM_VALUE(RGB5_A1),
|
||||
@ -332,8 +335,14 @@ STRONG_GLENUM_BEGIN(TexInternalFormat)
|
||||
STRONG_GLENUM_VALUE(ATC_RGBA_INTERPOLATED_ALPHA),
|
||||
STRONG_GLENUM_VALUE(RGBA32F),
|
||||
STRONG_GLENUM_VALUE(RGB32F),
|
||||
STRONG_GLENUM_VALUE(ALPHA32F_EXT),
|
||||
STRONG_GLENUM_VALUE(LUMINANCE32F_EXT),
|
||||
STRONG_GLENUM_VALUE(LUMINANCE_ALPHA32F_EXT),
|
||||
STRONG_GLENUM_VALUE(RGBA16F),
|
||||
STRONG_GLENUM_VALUE(RGB16F),
|
||||
STRONG_GLENUM_VALUE(ALPHA16F_EXT),
|
||||
STRONG_GLENUM_VALUE(LUMINANCE16F_EXT),
|
||||
STRONG_GLENUM_VALUE(LUMINANCE_ALPHA16F_EXT),
|
||||
STRONG_GLENUM_VALUE(DEPTH24_STENCIL8),
|
||||
STRONG_GLENUM_VALUE(COMPRESSED_RGB_PVRTC_4BPPV1),
|
||||
STRONG_GLENUM_VALUE(COMPRESSED_RGB_PVRTC_2BPPV1),
|
||||
|
@ -52,7 +52,7 @@ int64_t
|
||||
WebGLTexture::ImageInfo::MemoryUsage() const {
|
||||
if (mImageDataStatus == WebGLImageDataStatus::NoImageData)
|
||||
return 0;
|
||||
int64_t bitsPerTexel = WebGLContext::GetBitsPerTexel(mInternalFormat, mType);
|
||||
int64_t bitsPerTexel = GetBitsPerTexel(mEffectiveInternalFormat);
|
||||
return int64_t(mWidth) * int64_t(mHeight) * bitsPerTexel/8;
|
||||
}
|
||||
|
||||
@ -138,8 +138,7 @@ WebGLTexture::Bind(TexTarget aTexTarget) {
|
||||
void
|
||||
WebGLTexture::SetImageInfo(TexImageTarget aTexImageTarget, GLint aLevel,
|
||||
GLsizei aWidth, GLsizei aHeight,
|
||||
TexInternalFormat aInternalFormat, TexType aType,
|
||||
WebGLImageDataStatus aStatus)
|
||||
TexInternalFormat aEffectiveInternalFormat, WebGLImageDataStatus aStatus)
|
||||
{
|
||||
MOZ_ASSERT(TexImageTargetToTexTarget(aTexImageTarget) == mTarget);
|
||||
if (TexImageTargetToTexTarget(aTexImageTarget) != mTarget)
|
||||
@ -147,7 +146,7 @@ WebGLTexture::SetImageInfo(TexImageTarget aTexImageTarget, GLint aLevel,
|
||||
|
||||
EnsureMaxLevelWithCustomImagesAtLeast(aLevel);
|
||||
|
||||
ImageInfoAt(aTexImageTarget, aLevel) = ImageInfo(aWidth, aHeight, aInternalFormat, aType, aStatus);
|
||||
ImageInfoAt(aTexImageTarget, aLevel) = ImageInfo(aWidth, aHeight, aEffectiveInternalFormat, aStatus);
|
||||
|
||||
if (aLevel > 0)
|
||||
SetCustomMipmap();
|
||||
@ -329,7 +328,9 @@ WebGLTexture::ResolvedFakeBlackStatus() {
|
||||
}
|
||||
}
|
||||
|
||||
if (ImageInfoBase().mType == LOCAL_GL_FLOAT &&
|
||||
TexType type = TypeFromInternalFormat(ImageInfoBase().mEffectiveInternalFormat);
|
||||
|
||||
if (type == LOCAL_GL_FLOAT &&
|
||||
!Context()->IsExtensionEnabled(WebGLExtensionID::OES_texture_float_linear))
|
||||
{
|
||||
if (mMinFilter == LOCAL_GL_LINEAR ||
|
||||
@ -349,7 +350,7 @@ WebGLTexture::ResolvedFakeBlackStatus() {
|
||||
"Try enabling the OES_texture_float_linear extension if supported.", msg_rendering_as_black);
|
||||
mFakeBlackStatus = WebGLTextureFakeBlackStatus::IncompleteTexture;
|
||||
}
|
||||
} else if (ImageInfoBase().mType == LOCAL_GL_HALF_FLOAT_OES &&
|
||||
} else if (type == LOCAL_GL_HALF_FLOAT &&
|
||||
!Context()->IsExtensionEnabled(WebGLExtensionID::OES_texture_half_float_linear))
|
||||
{
|
||||
if (mMinFilter == LOCAL_GL_LINEAR ||
|
||||
@ -534,13 +535,11 @@ WebGLTexture::DoDeferredImageInitialization(TexImageTarget imageTarget, GLint le
|
||||
mContext->MakeContextCurrent();
|
||||
|
||||
// Try to clear with glCLear.
|
||||
TexInternalFormat internalformat = imageInfo.mInternalFormat;
|
||||
TexType type = imageInfo.mType;
|
||||
WebGLTexelFormat texelformat = GetWebGLTexelFormat(internalformat, type);
|
||||
|
||||
bool cleared = ClearWithTempFB(mContext, GLName(),
|
||||
imageTarget, level,
|
||||
internalformat, imageInfo.mHeight, imageInfo.mWidth);
|
||||
imageInfo.mEffectiveInternalFormat,
|
||||
imageInfo.mHeight, imageInfo.mWidth);
|
||||
if (cleared) {
|
||||
SetImageDataStatus(imageTarget, level, WebGLImageDataStatus::InitializedImageData);
|
||||
return;
|
||||
@ -549,22 +548,26 @@ WebGLTexture::DoDeferredImageInitialization(TexImageTarget imageTarget, GLint le
|
||||
// That didn't work. Try uploading zeros then.
|
||||
gl::ScopedBindTexture autoBindTex(mContext->gl, GLName(), mTarget.get());
|
||||
|
||||
uint32_t texelsize = WebGLTexelConversions::TexelBytesForFormat(texelformat);
|
||||
size_t bitspertexel = GetBitsPerTexel(imageInfo.mEffectiveInternalFormat);
|
||||
MOZ_ASSERT((bitspertexel % 8) == 0); // that would only happen for compressed images, which
|
||||
// cannot use deferred initialization.
|
||||
size_t bytespertexel = bitspertexel / 8;
|
||||
CheckedUint32 checked_byteLength
|
||||
= WebGLContext::GetImageSize(
|
||||
imageInfo.mHeight,
|
||||
imageInfo.mWidth,
|
||||
texelsize,
|
||||
bytespertexel,
|
||||
mContext->mPixelStoreUnpackAlignment);
|
||||
MOZ_ASSERT(checked_byteLength.isValid()); // should have been checked earlier
|
||||
ScopedFreePtr<void> zeros;
|
||||
zeros = calloc(1, checked_byteLength.value());
|
||||
|
||||
gl::GLContext* gl = mContext->gl;
|
||||
GLenum driverType = DriverTypeFromType(gl, type);
|
||||
GLenum driverInternalFormat = LOCAL_GL_NONE;
|
||||
GLenum driverFormat = LOCAL_GL_NONE;
|
||||
DriverFormatsFromFormatAndType(gl, internalformat, type, &driverInternalFormat, &driverFormat);
|
||||
GLenum driverType = LOCAL_GL_NONE;
|
||||
DriverFormatsFromEffectiveInternalFormat(gl, imageInfo.mEffectiveInternalFormat,
|
||||
&driverInternalFormat, &driverFormat, &driverType);
|
||||
|
||||
mContext->GetAndFlushUnderlyingGLErrors();
|
||||
gl->fTexImage2D(imageTarget.get(), level, driverInternalFormat,
|
||||
|
@ -67,19 +67,16 @@ public:
|
||||
{
|
||||
public:
|
||||
ImageInfo()
|
||||
: mInternalFormat(LOCAL_GL_NONE)
|
||||
, mType(LOCAL_GL_NONE)
|
||||
: mEffectiveInternalFormat(LOCAL_GL_NONE)
|
||||
, mImageDataStatus(WebGLImageDataStatus::NoImageData)
|
||||
{}
|
||||
|
||||
ImageInfo(GLsizei width,
|
||||
GLsizei height,
|
||||
TexInternalFormat internalFormat,
|
||||
TexType type,
|
||||
TexInternalFormat effectiveInternalFormat,
|
||||
WebGLImageDataStatus status)
|
||||
: WebGLRectangleObject(width, height)
|
||||
, mInternalFormat(internalFormat)
|
||||
, mType(type)
|
||||
, mEffectiveInternalFormat(effectiveInternalFormat)
|
||||
, mImageDataStatus(status)
|
||||
{
|
||||
// shouldn't use this constructor to construct a null ImageInfo
|
||||
@ -90,8 +87,7 @@ public:
|
||||
return mImageDataStatus == a.mImageDataStatus &&
|
||||
mWidth == a.mWidth &&
|
||||
mHeight == a.mHeight &&
|
||||
mInternalFormat == a.mInternalFormat &&
|
||||
mType == a.mType;
|
||||
mEffectiveInternalFormat == a.mEffectiveInternalFormat;
|
||||
}
|
||||
bool operator!=(const ImageInfo& a) const {
|
||||
return !(*this == a);
|
||||
@ -110,21 +106,17 @@ public:
|
||||
return mImageDataStatus == WebGLImageDataStatus::UninitializedImageData;
|
||||
}
|
||||
int64_t MemoryUsage() const;
|
||||
/*! This is the format passed from JS to WebGL.
|
||||
* It can be converted to a value to be passed to driver with
|
||||
* DriverFormatsFromFormatAndType().
|
||||
*/
|
||||
TexInternalFormat InternalFormat() const { return mInternalFormat; }
|
||||
|
||||
/*! This is the type passed from JS to WebGL.
|
||||
* It can be converted to a value to be passed to driver with
|
||||
* DriverTypeFromType().
|
||||
*/
|
||||
TexType Type() const { return mType; }
|
||||
TexInternalFormat EffectiveInternalFormat() const { return mEffectiveInternalFormat; }
|
||||
|
||||
protected:
|
||||
TexInternalFormat mInternalFormat; //!< This is the WebGL/GLES internal format.
|
||||
TexType mType; //!< This is the WebGL/GLES type
|
||||
/*
|
||||
* This is the "effective internal format" of the texture,
|
||||
* an official OpenGL spec concept, see
|
||||
* OpenGL ES 3.0.3 spec, section 3.8.3, page 126 and below.
|
||||
*/
|
||||
TexInternalFormat mEffectiveInternalFormat;
|
||||
|
||||
WebGLImageDataStatus mImageDataStatus;
|
||||
|
||||
friend class WebGLTexture;
|
||||
@ -230,8 +222,7 @@ public:
|
||||
|
||||
void SetImageInfo(TexImageTarget aTarget, GLint aLevel,
|
||||
GLsizei aWidth, GLsizei aHeight,
|
||||
TexInternalFormat aInternalFormat, TexType aType,
|
||||
WebGLImageDataStatus aStatus);
|
||||
TexInternalFormat aFormat, WebGLImageDataStatus aStatus);
|
||||
|
||||
void SetMinFilter(TexMinFilter aMinFilter) {
|
||||
mMinFilter = aMinFilter;
|
||||
|
@ -2365,7 +2365,6 @@ GLContext::ResizeScreenBuffer(const IntSize& size)
|
||||
return mScreen->Resize(size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GLContext::DestroyScreenBuffer()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user