Bug 1632249 - Create a separate WebGLContext::PresentInto function for WebXR. r=jgilbert

- Do not apply mIsCanvasDirty bailout when presenting from a opaque FBO
back buffer.
- Create a separate WebGLContext::PresentInto with more specific XR
validations and logic.
- Use the Opaque FBO backbuffer as source when calling
BlitBackbufferToCurDriverFB
- Always invalidate OpaqueFBO regardless of the WebGL context's
preserveDrawingBuffer value.

Differential Revision: https://phabricator.services.mozilla.com/D78301
This commit is contained in:
Jeff Gilbert 2020-06-15 18:26:00 +00:00
Родитель fd44ed35e8
Коммит a3bc94c178
3 изменённых файлов: 40 добавлений и 3 удалений

Просмотреть файл

@ -419,7 +419,7 @@ void ClientWebGLContext::EndComposition() {
void ClientWebGLContext::Present(WebGLFramebufferJS* const fb,
const layers::TextureType type) {
if (!mIsCanvasDirty) return;
if (!mIsCanvasDirty && !fb) return;
mIsCanvasDirty = false;
mFrontBufferSnapshot = nullptr;

Просмотреть файл

@ -942,14 +942,46 @@ bool WebGLContext::PresentInto(gl::SwapChain& swapChain) {
return true;
}
bool WebGLContext::PresentIntoXR(gl::SwapChain& swapChain,
const gl::MozFramebuffer& fb) {
OnEndOfFrame();
auto presenter = swapChain.Acquire(fb.mSize);
if (!presenter) {
GenerateWarning("Swap chain surface creation failed.");
LoseContext();
return false;
}
const auto destFb = presenter->Fb();
gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, destFb);
BlitBackbufferToCurDriverFB(&fb);
// https://immersive-web.github.io/webxr/#opaque-framebuffer
// Opaque framebuffers will always be cleared regardless of the
// associated WebGL contexts preserveDrawingBuffer value.
if (gl->IsSupported(gl::GLFeature::invalidate_framebuffer)) {
gl->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, fb.mFB);
constexpr auto attachments = MakeArray<GLenum>(
LOCAL_GL_COLOR_ATTACHMENT0, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT);
gl->fInvalidateFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, attachments.size(),
attachments.data());
}
return true;
}
void WebGLContext::Present(WebGLFramebuffer* const fb,
const layers::TextureType consumerType) {
const FuncScope funcScope(*this, "<Present>");
if (IsContextLost()) return;
auto swapChain = &mSwapChain;
const gl::MozFramebuffer* maybeFB = nullptr;
if (fb) {
swapChain = &fb->mOpaqueSwapChain;
maybeFB = fb->mOpaque.get();
} else {
mResolvedDefaultFB = nullptr;
}
@ -966,7 +998,11 @@ void WebGLContext::Present(WebGLFramebuffer* const fb,
}
MOZ_ASSERT(swapChain->mFactory);
(void)PresentInto(*swapChain);
if (maybeFB) {
(void)PresentIntoXR(*swapChain, *maybeFB);
} else {
(void)PresentInto(*swapChain);
}
}
Maybe<layers::SurfaceDescriptor> WebGLContext::GetFrontBuffer(

Просмотреть файл

@ -101,7 +101,7 @@ class MozFramebuffer;
namespace layers {
class CompositableHost;
class SurfaceDescriptor;
}
} // namespace layers
namespace webgl {
class AvailabilityRunnable;
@ -483,6 +483,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr<WebGLContext> {
// Present to compositor
private:
bool PresentInto(gl::SwapChain& swapChain);
bool PresentIntoXR(gl::SwapChain& swapChain, const gl::MozFramebuffer& fb);
public:
void Present(WebGLFramebuffer*, layers::TextureType);