mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1102667 - Fix our float texture/rb/fb support. - r=kamidphish
This commit is contained in:
parent
6d1fabc862
commit
d0bc2cd8e5
@ -1084,6 +1084,9 @@ public:
|
||||
return mGLMaxVertexAttribs;
|
||||
}
|
||||
|
||||
|
||||
bool IsFormatValidForFB(GLenum sizedFormat) const;
|
||||
|
||||
protected:
|
||||
// Represents current status of the context with respect to context loss.
|
||||
// That is, whether the context is lost, and what part of the context loss
|
||||
@ -1116,6 +1119,10 @@ protected:
|
||||
// enable an extension. the extension should not be enabled before.
|
||||
void EnableExtension(WebGLExtensionID ext);
|
||||
|
||||
// Enable an extension if it's supported. Return the extension on success.
|
||||
WebGLExtensionBase* EnableSupportedExtension(JSContext* js,
|
||||
WebGLExtensionID ext);
|
||||
|
||||
// returns true if the extension has been enabled by calling getExtension.
|
||||
bool IsExtensionEnabled(WebGLExtensionID ext) const;
|
||||
|
||||
|
@ -186,6 +186,19 @@ CompareWebGLExtensionName(const nsACString& name, const char *other)
|
||||
return name.Equals(other, nsCaseInsensitiveCStringComparator());
|
||||
}
|
||||
|
||||
WebGLExtensionBase*
|
||||
WebGLContext::EnableSupportedExtension(JSContext* js, WebGLExtensionID ext)
|
||||
{
|
||||
if (!IsExtensionEnabled(ext)) {
|
||||
if (!IsExtensionSupported(js, ext))
|
||||
return nullptr;
|
||||
|
||||
EnableExtension(ext);
|
||||
}
|
||||
|
||||
return mExtensions[ext];
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::GetExtension(JSContext *cx, const nsAString& aName,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
@ -201,8 +214,7 @@ WebGLContext::GetExtension(JSContext *cx, const nsAString& aName,
|
||||
WebGLExtensionID ext = WebGLExtensionID::Unknown;
|
||||
|
||||
// step 1: figure what extension is wanted
|
||||
for (size_t i = 0; i < size_t(WebGLExtensionID::Max); i++)
|
||||
{
|
||||
for (size_t i = 0; i < size_t(WebGLExtensionID::Max); i++) {
|
||||
WebGLExtensionID extension = WebGLExtensionID(i);
|
||||
|
||||
if (CompareWebGLExtensionName(name, GetExtensionString(extension))) {
|
||||
@ -211,8 +223,7 @@ WebGLContext::GetExtension(JSContext *cx, const nsAString& aName,
|
||||
}
|
||||
}
|
||||
|
||||
if (ext == WebGLExtensionID::Unknown)
|
||||
{
|
||||
if (ext == WebGLExtensionID::Unknown) {
|
||||
/**
|
||||
* We keep backward compatibility for these deprecated vendor-prefixed
|
||||
* alias. Do not add new ones anymore. Hide it behind the
|
||||
@ -254,11 +265,27 @@ WebGLContext::GetExtension(JSContext *cx, const nsAString& aName,
|
||||
}
|
||||
|
||||
// step 3: if the extension hadn't been previously been created, create it now, thus enabling it
|
||||
if (!IsExtensionEnabled(ext)) {
|
||||
EnableExtension(ext);
|
||||
WebGLExtensionBase* extObj = EnableSupportedExtension(cx, ext);
|
||||
if (!extObj) {
|
||||
aRetval.set(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
aRetval.set(WebGLObjectAsJSObject(cx, mExtensions[ext].get(), rv));
|
||||
// Step 4: Enable any implied extensions.
|
||||
switch (ext) {
|
||||
case WebGLExtensionID::OES_texture_float:
|
||||
EnableSupportedExtension(cx, WebGLExtensionID::WEBGL_color_buffer_float);
|
||||
break;
|
||||
|
||||
case WebGLExtensionID::OES_texture_half_float:
|
||||
EnableSupportedExtension(cx, WebGLExtensionID::EXT_color_buffer_half_float);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
aRetval.set(WebGLObjectAsJSObject(cx, extObj, rv));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -23,8 +23,13 @@ WebGLExtensionColorBufferFloat::~WebGLExtensionColorBufferFloat()
|
||||
bool
|
||||
WebGLExtensionColorBufferFloat::IsSupported(const WebGLContext* context)
|
||||
{
|
||||
return context->GL()->IsSupported(gl::GLFeature::renderbuffer_color_float) &&
|
||||
context->GL()->IsSupported(gl::GLFeature::frag_color_float);
|
||||
gl::GLContext* gl = context->GL();
|
||||
|
||||
// ANGLE supports this, but doesn't have a way to advertize its support,
|
||||
// since it's compliant with WEBGL_color_buffer_float's clamping, but not
|
||||
// EXT_color_buffer_float.
|
||||
return gl->IsSupported(gl::GLFeature::renderbuffer_color_float) ||
|
||||
gl->IsANGLE();
|
||||
}
|
||||
|
||||
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionColorBufferFloat)
|
||||
|
@ -23,8 +23,10 @@ WebGLExtensionColorBufferHalfFloat::~WebGLExtensionColorBufferHalfFloat()
|
||||
bool
|
||||
WebGLExtensionColorBufferHalfFloat::IsSupported(const WebGLContext* context)
|
||||
{
|
||||
return context->GL()->IsSupported(gl::GLFeature::renderbuffer_color_half_float) &&
|
||||
context->GL()->IsSupported(gl::GLFeature::frag_color_float);
|
||||
gl::GLContext* gl = context->GL();
|
||||
|
||||
// ANGLE doesn't support ReadPixels from a RGBA16F with RGBA/FLOAT.
|
||||
return gl->IsSupported(gl::GLFeature::renderbuffer_color_half_float);
|
||||
}
|
||||
|
||||
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionColorBufferHalfFloat)
|
||||
|
@ -283,6 +283,36 @@ IsValidFBORenderbufferStencilFormat(GLenum internalFormat)
|
||||
return internalFormat == LOCAL_GL_STENCIL_INDEX8;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::IsFormatValidForFB(GLenum sizedFormat) const
|
||||
{
|
||||
switch (sizedFormat) {
|
||||
case LOCAL_GL_ALPHA8:
|
||||
case LOCAL_GL_LUMINANCE8:
|
||||
case LOCAL_GL_LUMINANCE8_ALPHA8:
|
||||
case LOCAL_GL_RGB8:
|
||||
case LOCAL_GL_RGBA8:
|
||||
case LOCAL_GL_RGB565:
|
||||
case LOCAL_GL_RGB5_A1:
|
||||
case LOCAL_GL_RGBA4:
|
||||
return true;
|
||||
|
||||
case LOCAL_GL_SRGB8:
|
||||
case LOCAL_GL_SRGB8_ALPHA8_EXT:
|
||||
return IsExtensionEnabled(WebGLExtensionID::EXT_sRGB);
|
||||
|
||||
case LOCAL_GL_RGB32F:
|
||||
case LOCAL_GL_RGBA32F:
|
||||
return IsExtensionEnabled(WebGLExtensionID::WEBGL_color_buffer_float);
|
||||
|
||||
case LOCAL_GL_RGB16F:
|
||||
case LOCAL_GL_RGBA16F:
|
||||
return IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_half_float);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLFramebuffer::Attachment::IsComplete() const
|
||||
{
|
||||
@ -301,23 +331,24 @@ WebGLFramebuffer::Attachment::IsComplete() const
|
||||
MOZ_ASSERT(Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel));
|
||||
const WebGLTexture::ImageInfo& imageInfo =
|
||||
Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel);
|
||||
GLenum internalformat = imageInfo.EffectiveInternalFormat().get();
|
||||
GLenum sizedFormat = imageInfo.EffectiveInternalFormat().get();
|
||||
|
||||
if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT)
|
||||
return IsValidFBOTextureDepthFormat(internalformat);
|
||||
return IsValidFBOTextureDepthFormat(sizedFormat);
|
||||
|
||||
if (mAttachmentPoint == LOCAL_GL_STENCIL_ATTACHMENT)
|
||||
return false; // Textures can't have the correct format for stencil buffers
|
||||
|
||||
if (mAttachmentPoint == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
|
||||
return IsValidFBOTextureDepthStencilFormat(internalformat);
|
||||
return IsValidFBOTextureDepthStencilFormat(sizedFormat);
|
||||
}
|
||||
|
||||
if (mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0 &&
|
||||
mAttachmentPoint <= FBAttachment(LOCAL_GL_COLOR_ATTACHMENT0 - 1 +
|
||||
WebGLContext::kMaxColorAttachments))
|
||||
{
|
||||
return IsValidFBOTextureColorFormat(internalformat);
|
||||
WebGLContext* webgl = Texture()->Context();
|
||||
return webgl->IsFormatValidForFB(sizedFormat);
|
||||
}
|
||||
MOZ_ASSERT(false, "Invalid WebGL attachment point?");
|
||||
return false;
|
||||
@ -339,7 +370,8 @@ WebGLFramebuffer::Attachment::IsComplete() const
|
||||
mAttachmentPoint <= FBAttachment(LOCAL_GL_COLOR_ATTACHMENT0 - 1 +
|
||||
WebGLContext::kMaxColorAttachments))
|
||||
{
|
||||
return IsValidFBORenderbufferColorFormat(internalFormat);
|
||||
WebGLContext* webgl = Renderbuffer()->Context();
|
||||
return webgl->IsFormatValidForFB(internalFormat);
|
||||
}
|
||||
MOZ_ASSERT(false, "Invalid WebGL attachment point?");
|
||||
return false;
|
||||
|
@ -13,6 +13,7 @@ fail-if = (os == 'b2g')
|
||||
[webgl-mochitest/test_fb_param_crash.html]
|
||||
[webgl-mochitest/test_hidden_alpha.html]
|
||||
skip-if = (os == 'b2g') || buildapp == 'mulet' # Mulet - bug 1093639 (crashes in libLLVM-3.0.so)
|
||||
[webgl-mochitest/test_implicit_color_buffer_float.html]
|
||||
[webgl-mochitest/test_highp_fs.html]
|
||||
[webgl-mochitest/test_no_arr_points.html]
|
||||
skip-if = android_version == '10' #Android 2.3 aws only; bug 1030942
|
||||
|
@ -0,0 +1,199 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
var RGBA32F_EXT = 0x8814;
|
||||
var RGBA16F_EXT = 0x881A; // Yep, it's really 4 and A.
|
||||
var HALF_FLOAT_OES = 0x8D61;
|
||||
|
||||
function IsFormatValidForRB(gl, format) {
|
||||
ok(!gl.getError(), 'Should have no errors here.');
|
||||
|
||||
var rb = gl.createRenderbuffer();
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
|
||||
gl.renderbufferStorage(gl.RENDERBUFFER, format, 4, 4);
|
||||
|
||||
var error = gl.getError();
|
||||
if (error == gl.INVALID_ENUM)
|
||||
return false;
|
||||
|
||||
ok(error == gl.NO_ERROR, 'Error should be INVALID_ENUM or NO_ERROR.');
|
||||
return error == gl.NO_ERROR;
|
||||
}
|
||||
|
||||
function IsFormatValidForTex(gl, format, type) {
|
||||
ok(!gl.getError(), 'Should have no errors here.');
|
||||
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, format, 4, 4, 0, format, type, null);
|
||||
|
||||
var error = gl.getError();
|
||||
if (error == gl.INVALID_ENUM)
|
||||
return false;
|
||||
|
||||
ok(error == gl.NO_ERROR, 'Error should be INVALID_ENUM or NO_ERROR.');
|
||||
return error == gl.NO_ERROR;
|
||||
}
|
||||
|
||||
function IsFormatValidForTexFB(gl, format, type) {
|
||||
ok(!gl.getError(), 'Should have no errors here.');
|
||||
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, format, 4, 4, 0, format, type, null);
|
||||
|
||||
var error = gl.getError();
|
||||
if (error == gl.INVALID_ENUM)
|
||||
return false;
|
||||
|
||||
ok(error == gl.NO_ERROR, 'Error should be INVALID_ENUM or NO_ERROR.');
|
||||
|
||||
var fb = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D,
|
||||
tex, 0);
|
||||
error = gl.getError();
|
||||
ok(error == gl.NO_ERROR, 'Error should be NO_ERROR.');
|
||||
|
||||
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
||||
return status == gl.FRAMEBUFFER_COMPLETE;
|
||||
}
|
||||
|
||||
function IsFormatValidForTexFBRead(gl, texFormat, texType, readType) {
|
||||
ok(!gl.getError(), 'Should have no errors here.');
|
||||
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, texFormat, 4, 4, 0, texFormat, texType,
|
||||
null);
|
||||
|
||||
var error = gl.getError();
|
||||
if (error == gl.INVALID_ENUM)
|
||||
return false;
|
||||
|
||||
ok(error == gl.NO_ERROR, 'Error should be INVALID_ENUM or NO_ERROR.');
|
||||
|
||||
var fb = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D,
|
||||
tex, 0);
|
||||
error = gl.getError();
|
||||
ok(error == gl.NO_ERROR, 'Error should be NO_ERROR.');
|
||||
|
||||
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
||||
if (status != gl.FRAMEBUFFER_COMPLETE)
|
||||
return false;
|
||||
|
||||
var data;
|
||||
switch (readType) {
|
||||
case gl.UNSIGNED_BYTE:
|
||||
data = new Uint8Array(4);
|
||||
break;
|
||||
case HALF_FLOAT_OES:
|
||||
data = new Uint16Array(4);
|
||||
break;
|
||||
case gl.FLOAT:
|
||||
data = new Float32Array(4);
|
||||
break;
|
||||
default:
|
||||
throw 'Bad `readType`.';
|
||||
}
|
||||
gl.readPixels(0, 0, 1, 1, gl.RGBA, readType, data);
|
||||
|
||||
error = gl.getError();
|
||||
return error == gl.NO_ERROR;
|
||||
}
|
||||
|
||||
function TestColorBufferExt(gl, rbFormat, texFormat, texType, readType)
|
||||
{
|
||||
var isTexFBValid = IsFormatValidForTexFB(gl, texFormat, texType);
|
||||
var isTexFBReadValid = IsFormatValidForTexFBRead(gl, texFormat, texType,
|
||||
readType);
|
||||
var isRBValid = IsFormatValidForRB(gl, rbFormat);
|
||||
|
||||
var validSubsetCount = isTexFBValid + isTexFBReadValid + isRBValid;
|
||||
|
||||
if (validSubsetCount) {
|
||||
ok(isTexFBValid, 'If active, texture-fbs should work.');
|
||||
ok(isTexFBReadValid, 'If active, reading texture-fbs should work.');
|
||||
ok(isRBValid, 'If active, renderbuffers should work.');
|
||||
}
|
||||
|
||||
return validSubsetCount == 3;
|
||||
}
|
||||
|
||||
function TestImpliedExtension(gl, baseExtName, impliedExtName, rbFormat,
|
||||
texFormat, texType, readType)
|
||||
{
|
||||
ok(true, '========');
|
||||
ok(true, 'Testing if ' + baseExtName + ' implies ' + impliedExtName + '.');
|
||||
ok(true, '--------');
|
||||
|
||||
var baseExt = gl.getExtension(baseExtName);
|
||||
if (!baseExt) {
|
||||
ok(!baseExt, 'Ext \'' + baseExtName + '\' can be unsupported.');
|
||||
return;
|
||||
}
|
||||
|
||||
var isTexValid = IsFormatValidForTex(gl, texFormat, texType);
|
||||
ok(isTexValid, baseExtName + ' should allow float textures.');
|
||||
if (!isTexValid)
|
||||
return;
|
||||
|
||||
var isImplicitlyActive = TestColorBufferExt(gl, rbFormat, texFormat,
|
||||
texType, readType);
|
||||
|
||||
if (isImplicitlyActive) {
|
||||
ok(true, 'Activating ' + baseExtName + ' has implicitly activated ' +
|
||||
impliedExtName + '.');
|
||||
|
||||
var impliedExt = gl.getExtension(impliedExtName);
|
||||
ok(impliedExt, 'If ' + impliedExtName + ' is supported implicitly, it' +
|
||||
' must be supported explicitly as well.');
|
||||
return;
|
||||
}
|
||||
|
||||
ok(true, 'Activating ' + baseExtName + ' has not implicitly activated ' +
|
||||
impliedExtName + '.');
|
||||
ok(true, '--------');
|
||||
|
||||
var impliedExt = gl.getExtension(impliedExtName);
|
||||
if (!impliedExt) {
|
||||
ok(true, impliedExtName + ' can be unsupported.');
|
||||
return;
|
||||
}
|
||||
ok(true, 'Explicit activation of ' + impliedExtName + ' successful.');
|
||||
|
||||
var isFunctional = TestColorBufferExt(gl, rbFormat, texFormat, texType,
|
||||
readType);
|
||||
ok(isFunctional, impliedExtName + ' should be fully functional.');
|
||||
}
|
||||
|
||||
(function() {
|
||||
var canvas = document.createElement('canvas');
|
||||
var gl = canvas.getContext('experimental-webgl');
|
||||
if (!gl) {
|
||||
ok(!gl, 'WebGL can be unsupported.');
|
||||
return;
|
||||
}
|
||||
|
||||
TestImpliedExtension(gl, 'OES_texture_float', 'WEBGL_color_buffer_float',
|
||||
RGBA32F_EXT, gl.RGBA, gl.FLOAT, gl.FLOAT);
|
||||
TestImpliedExtension(gl, 'OES_texture_half_float',
|
||||
'EXT_color_buffer_half_float', RGBA16F_EXT, gl.RGBA,
|
||||
HALF_FLOAT_OES, gl.FLOAT);
|
||||
ok(true, '========');
|
||||
ok(true, 'TEST COMPLETE');
|
||||
})();
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user