mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
WebGL2: Implement invalidateFramebuffer and invalidateSubFramebuffer (bug 1076456, r=jgilbert).
--HG-- extra : rebase_source : 5ce9c956475388896fe193ca37c9595978adf15c
This commit is contained in:
parent
ab72b35cb5
commit
e8609c1ba4
@ -78,7 +78,8 @@ WebGLContext::InitWebGL2()
|
||||
};
|
||||
const GLFeature sFeatureRequiredArr[] = {
|
||||
GLFeature::instanced_non_arrays,
|
||||
GLFeature::transform_feedback2
|
||||
GLFeature::transform_feedback2,
|
||||
GLFeature::invalidate_framebuffer
|
||||
};
|
||||
|
||||
// check WebGL extensions that are supposed to be natively supported
|
||||
|
@ -32,17 +32,73 @@ WebGL2Context::GetInternalformatParameter(JSContext*, GLenum target, GLenum inte
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::InvalidateFramebuffer(GLenum target, const dom::Sequence<GLenum>& attachments)
|
||||
// Map attachments intended for the default buffer, to attachments for a non-
|
||||
// default buffer.
|
||||
static void
|
||||
TranslateDefaultAttachments(const dom::Sequence<GLenum>& in, dom::Sequence<GLenum>* out)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
for (size_t i = 0; i < in.Length(); i++) {
|
||||
switch (in[i]) {
|
||||
case LOCAL_GL_COLOR:
|
||||
out->AppendElement(LOCAL_GL_COLOR_ATTACHMENT0);
|
||||
break;
|
||||
case LOCAL_GL_DEPTH:
|
||||
out->AppendElement(LOCAL_GL_DEPTH_ATTACHMENT);
|
||||
break;
|
||||
case LOCAL_GL_STENCIL:
|
||||
out->AppendElement(LOCAL_GL_STENCIL_ATTACHMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::InvalidateSubFramebuffer (GLenum target, const dom::Sequence<GLenum>& attachments,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height)
|
||||
WebGL2Context::InvalidateFramebuffer(GLenum target, const dom::Sequence<GLenum>& attachments)
|
||||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
if (IsContextLost())
|
||||
return;
|
||||
MakeContextCurrent();
|
||||
|
||||
if (target != LOCAL_GL_FRAMEBUFFER)
|
||||
return ErrorInvalidEnumInfo("invalidateFramebuffer: target", target);
|
||||
for (size_t i = 0; i < attachments.Length(); i++) {
|
||||
if (!ValidateFramebufferAttachment(attachments[i], "invalidateFramebuffer"))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mBoundFramebuffer && !gl->IsDrawingToDefaultFramebuffer()) {
|
||||
dom::Sequence<GLenum> tmpAttachments;
|
||||
TranslateDefaultAttachments(attachments, &tmpAttachments);
|
||||
gl->fInvalidateFramebuffer(target, tmpAttachments.Length(), tmpAttachments.Elements());
|
||||
} else {
|
||||
gl->fInvalidateFramebuffer(target, attachments.Length(), attachments.Elements());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::InvalidateSubFramebuffer(GLenum target, const dom::Sequence<GLenum>& attachments,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
MakeContextCurrent();
|
||||
|
||||
if (target != LOCAL_GL_FRAMEBUFFER)
|
||||
return ErrorInvalidEnumInfo("invalidateFramebuffer: target", target);
|
||||
for (size_t i = 0; i < attachments.Length(); i++) {
|
||||
if (!ValidateFramebufferAttachment(attachments[i], "invalidateSubFramebuffer"))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mBoundFramebuffer && !gl->IsDrawingToDefaultFramebuffer()) {
|
||||
dom::Sequence<GLenum> tmpAttachments;
|
||||
TranslateDefaultAttachments(attachments, &tmpAttachments);
|
||||
gl->fInvalidateSubFramebuffer(target, tmpAttachments.Length(), tmpAttachments.Elements(),
|
||||
x, y, width, height);
|
||||
} else {
|
||||
gl->fInvalidateSubFramebuffer(target, attachments.Length(), attachments.Elements(),
|
||||
x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -339,6 +339,18 @@ bool WebGLContext::ValidateGLSLString(const nsAString& string, const char *info)
|
||||
bool
|
||||
WebGLContext::ValidateFramebufferAttachment(GLenum attachment, const char* funcName)
|
||||
{
|
||||
if (!mBoundFramebuffer) {
|
||||
switch (attachment) {
|
||||
case LOCAL_GL_COLOR:
|
||||
case LOCAL_GL_DEPTH:
|
||||
case LOCAL_GL_STENCIL:
|
||||
return true;
|
||||
default:
|
||||
ErrorInvalidEnum("%s: attachment: invalid enum value 0x%x.", funcName, attachment);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (attachment == LOCAL_GL_DEPTH_ATTACHMENT ||
|
||||
attachment == LOCAL_GL_STENCIL_ATTACHMENT ||
|
||||
attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
|
||||
|
@ -24,3 +24,5 @@ skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests
|
||||
skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
|
||||
[webgl-mochitest/test_webgl2_not_exposed.html]
|
||||
skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
|
||||
[webgl-mochitest/test_webgl2_invalidate_framebuffer.html]
|
||||
skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
|
||||
|
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE HTML>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
|
||||
<title>WebGL2 test: Framebuffers</title>
|
||||
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
<script src="driver-info.js"></script>
|
||||
<script src="webgl-util.js"></script>
|
||||
<body>
|
||||
<canvas id="c" width="64" height="64"></canvas>
|
||||
<script>
|
||||
|
||||
WebGLUtil.withWebGL2('c', function (gl) {
|
||||
gl.invalidateFramebuffer(gl.FRAMEBUFFER, [gl.COLOR]);
|
||||
ok(gl.getError() == 0, 'invalidateFramebuffer');
|
||||
gl.invalidateSubFramebuffer(gl.FRAMEBUFFER, [gl.COLOR], 0, 0, 64, 64);
|
||||
ok(gl.getError() == 0, 'invalidateSubFramebuffer');
|
||||
gl.invalidateFramebuffer(gl.FRAMEBUFFER, [gl.GL_COLOR_ATTACHMENT0]);
|
||||
ok(gl.getError() == gl.INVALID_ENUM, 'invalidateFrameBuffer should fail with GL_COLOR_ATTACHMENT on the default framebuffer');
|
||||
}, function () {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
@ -58,6 +58,44 @@ WebGLUtil = (function() {
|
||||
return gl;
|
||||
}
|
||||
|
||||
function withWebGL2(canvasId, callback, onFinished) {
|
||||
var prefArrArr = [
|
||||
['webgl.force-enabled', true],
|
||||
['webgl.disable-angle', true],
|
||||
['webgl.enable-prototype-webgl2', true],
|
||||
];
|
||||
var prefEnv = {'set': prefArrArr};
|
||||
SpecialPowers.pushPrefEnv(prefEnv, function() {
|
||||
var canvas = document.getElementById(canvasId);
|
||||
|
||||
var gl = null;
|
||||
try {
|
||||
gl = canvas.getContext('webgl2');
|
||||
} catch(e) {}
|
||||
|
||||
if (!gl) {
|
||||
try {
|
||||
gl = canvas.getContext('experimental-webgl2');
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
if (!gl) {
|
||||
todo(false, 'WebGL2 is not supported');
|
||||
onFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
function errorFunc(str) {
|
||||
ok(false, 'Error: ' + str);
|
||||
}
|
||||
setErrorFunc(errorFunc);
|
||||
setWarningFunc(errorFunc);
|
||||
|
||||
callback(gl);
|
||||
onFinished();
|
||||
});
|
||||
}
|
||||
|
||||
function getContentFromElem(elem) {
|
||||
var str = "";
|
||||
var k = elem.firstChild;
|
||||
@ -125,6 +163,7 @@ WebGLUtil = (function() {
|
||||
setWarningFunc: setWarningFunc,
|
||||
|
||||
getWebGL: getWebGL,
|
||||
withWebGL2: withWebGL2,
|
||||
createShaderById: createShaderById,
|
||||
createProgramByIds: createProgramByIds,
|
||||
};
|
||||
|
@ -84,6 +84,7 @@ static const char *sExtensionNames[] = {
|
||||
"GL_ARB_framebuffer_sRGB",
|
||||
"GL_ARB_half_float_pixel",
|
||||
"GL_ARB_instanced_arrays",
|
||||
"GL_ARB_invalidate_subdata",
|
||||
"GL_ARB_map_buffer_range",
|
||||
"GL_ARB_occlusion_query2",
|
||||
"GL_ARB_pixel_buffer_object",
|
||||
@ -1356,6 +1357,21 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
||||
}
|
||||
}
|
||||
|
||||
if (IsSupported(GLFeature::invalidate_framebuffer)) {
|
||||
SymLoadStruct invSymbols[] = {
|
||||
{ (PRFuncPtr *) &mSymbols.fInvalidateFramebuffer, { "InvalidateFramebuffer", nullptr } },
|
||||
{ (PRFuncPtr *) &mSymbols.fInvalidateSubFramebuffer, { "InvalidateSubFramebuffer", nullptr } },
|
||||
END_SYMBOLS
|
||||
};
|
||||
|
||||
if (!LoadSymbols(&invSymbols[0], trygl, prefix)) {
|
||||
NS_ERROR("GL supports framebuffer invalidation without supplying its functions.");
|
||||
|
||||
MarkUnsupported(GLFeature::invalidate_framebuffer);
|
||||
ClearSymbols(invSymbols);
|
||||
}
|
||||
}
|
||||
|
||||
if (IsExtensionSupported(KHR_debug)) {
|
||||
SymLoadStruct extSymbols[] = {
|
||||
{ (PRFuncPtr*) &mSymbols.fDebugMessageControl, { "DebugMessageControl", "DebugMessageControlKHR", nullptr } },
|
||||
|
@ -100,6 +100,7 @@ MOZ_BEGIN_ENUM_CLASS(GLFeature)
|
||||
gpu_shader4,
|
||||
instanced_arrays,
|
||||
instanced_non_arrays,
|
||||
invalidate_framebuffer,
|
||||
map_buffer_range,
|
||||
occlusion_query,
|
||||
occlusion_query_boolean,
|
||||
@ -367,6 +368,7 @@ public:
|
||||
ARB_framebuffer_sRGB,
|
||||
ARB_half_float_pixel,
|
||||
ARB_instanced_arrays,
|
||||
ARB_invalidate_subdata,
|
||||
ARB_map_buffer_range,
|
||||
ARB_occlusion_query2,
|
||||
ARB_pixel_buffer_object,
|
||||
@ -890,6 +892,20 @@ public:
|
||||
raw_fBindFramebuffer(target, framebuffer);
|
||||
}
|
||||
|
||||
void fInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) {
|
||||
BEFORE_GL_CALL;
|
||||
ASSERT_SYMBOL_PRESENT(fInvalidateFramebuffer);
|
||||
mSymbols.fInvalidateFramebuffer(target, numAttachments, attachments);
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
BEFORE_GL_CALL;
|
||||
ASSERT_SYMBOL_PRESENT(fInvalidateSubFramebuffer);
|
||||
mSymbols.fInvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height);
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fBindTexture(GLenum target, GLuint texture) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fBindTexture(target, texture);
|
||||
@ -3537,6 +3553,10 @@ public:
|
||||
|
||||
bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
|
||||
|
||||
bool IsDrawingToDefaultFramebuffer() {
|
||||
return Screen()->IsDrawFramebufferDefault();
|
||||
}
|
||||
|
||||
protected:
|
||||
nsRefPtr<TextureGarbageBin> mTexGarbageBin;
|
||||
|
||||
|
@ -288,6 +288,15 @@ static const FeatureInfo sFeatureInfoArr[] = {
|
||||
* has no such restriction.
|
||||
*/
|
||||
},
|
||||
{
|
||||
"invalidate_framebuffer",
|
||||
430, // OpenGL version
|
||||
300, // OpenGL ES version
|
||||
GLContext::ARB_invalidate_subdata,
|
||||
{
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"map_buffer_range",
|
||||
300, // OpenGL version
|
||||
|
@ -334,6 +334,11 @@ struct GLContextSymbols
|
||||
typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGE) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height);
|
||||
PFNGLRENDERBUFFERSTORAGE fRenderbufferStorage;
|
||||
|
||||
typedef void (GLAPIENTRY * PFNINVALIDATEFRAMEBUFFER) (GLenum target, GLsizei numAttachments, const GLenum* attachments);
|
||||
PFNINVALIDATEFRAMEBUFFER fInvalidateFramebuffer;
|
||||
typedef void (GLAPIENTRY * PFNINVALIDATESUBFRAMEBUFFER) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
PFNINVALIDATESUBFRAMEBUFFER fInvalidateSubFramebuffer;
|
||||
|
||||
// These functions are only used by Skia/GL in desktop mode.
|
||||
// Other parts of Gecko should avoid using these
|
||||
typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTURE) (GLenum texture);
|
||||
|
@ -529,6 +529,20 @@ GLScreenBuffer::Readback(SharedSurface* src, gfx::DataSourceSurface* dest)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GLScreenBuffer::IsDrawFramebufferDefault() const
|
||||
{
|
||||
if (!mDraw)
|
||||
return IsReadFramebufferDefault();
|
||||
return mDraw->mFB == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
GLScreenBuffer::IsReadFramebufferDefault() const
|
||||
{
|
||||
return SharedSurf()->mAttachType == AttachmentType::Screen;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// DrawBuffer
|
||||
|
||||
|
@ -261,6 +261,9 @@ public:
|
||||
void BindFB_Internal(GLuint fb);
|
||||
void BindDrawFB_Internal(GLuint fb);
|
||||
void BindReadFB_Internal(GLuint fb);
|
||||
|
||||
bool IsDrawFramebufferDefault() const;
|
||||
bool IsReadFramebufferDefault() const;
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
Loading…
Reference in New Issue
Block a user