зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1632249 - WebXR compositing fixes. r=imanol
Differential Revision: https://phabricator.services.mozilla.com/D78117
This commit is contained in:
Родитель
9b09e54345
Коммит
28d2828abe
|
@ -398,7 +398,17 @@ ReturnType ClientWebGLContext::Run(Args&&... aArgs) const {
|
|||
|
||||
// ------------------------- Composition, etc -------------------------
|
||||
|
||||
void ClientWebGLContext::OnBeforePaintTransaction() { Present(); }
|
||||
void ClientWebGLContext::OnBeforePaintTransaction() {
|
||||
const RefPtr<layers::ImageBridgeChild> imageBridge =
|
||||
layers::ImageBridgeChild::GetSingleton();
|
||||
|
||||
auto texType = layers::TextureType::Unknown;
|
||||
if (imageBridge) {
|
||||
texType = layers::PreferredCanvasTextureType(*imageBridge);
|
||||
}
|
||||
|
||||
Present(nullptr, texType);
|
||||
}
|
||||
|
||||
void ClientWebGLContext::EndComposition() {
|
||||
// Mark ourselves as no longer invalidated.
|
||||
|
@ -407,43 +417,18 @@ void ClientWebGLContext::EndComposition() {
|
|||
|
||||
// -
|
||||
|
||||
namespace webgl {
|
||||
|
||||
void Present(ClientWebGLContext& webgl) { webgl.Present(); }
|
||||
|
||||
Maybe<layers::SurfaceDescriptor> GetFrontBuffer(
|
||||
ClientWebGLContext& webgl, layers::KnowsCompositor* const kc) {
|
||||
auto texType = layers::TextureType::Unknown;
|
||||
if (kc) {
|
||||
texType = layers::PreferredCanvasTextureType(*kc);
|
||||
}
|
||||
return webgl.GetFrontBuffer(texType);
|
||||
}
|
||||
|
||||
} // namespace webgl
|
||||
|
||||
// -
|
||||
|
||||
void ClientWebGLContext::Present() {
|
||||
void ClientWebGLContext::Present(WebGLFramebufferJS* const fb,
|
||||
const layers::TextureType type) {
|
||||
if (!mIsCanvasDirty) return;
|
||||
mIsCanvasDirty = false;
|
||||
mFrontBufferDesc = nullptr;
|
||||
mFrontBufferSnapshot = nullptr;
|
||||
|
||||
Run<RPROC(Present)>();
|
||||
Run<RPROC(Present)>(fb ? fb->mId : 0, type);
|
||||
}
|
||||
|
||||
Maybe<layers::SurfaceDescriptor> ClientWebGLContext::GetFrontBuffer(
|
||||
const layers::TextureType type) {
|
||||
if (!mFrontBufferDesc) {
|
||||
const auto desc = Run<RPROC(GetFrontBuffer)>(type);
|
||||
if (desc) {
|
||||
mFrontBufferDesc = MakeUnique<layers::SurfaceDescriptor>(*desc);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mFrontBufferDesc) return Nothing();
|
||||
return Some(*mFrontBufferDesc);
|
||||
WebGLFramebufferJS* const fb, const layers::TextureType type) {
|
||||
return Run<RPROC(GetFrontBuffer)>(fb ? fb->mId : 0, type);
|
||||
}
|
||||
|
||||
// -
|
||||
|
@ -620,9 +605,6 @@ ClientWebGLContext::SetDimensions(const int32_t signedWidth,
|
|||
}
|
||||
if (size == curSize) return NS_OK; // MUST skip no-op resize
|
||||
|
||||
if (mIsCanvasDirty) {
|
||||
Present();
|
||||
}
|
||||
state.mDrawingBufferSize = Nothing();
|
||||
Run<RPROC(Resize)>(size);
|
||||
|
||||
|
|
|
@ -974,7 +974,6 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
|
|||
layers::LayersBackend GetCompositorBackendType() const;
|
||||
|
||||
bool mCapturedFrameInvalidated = false;
|
||||
UniquePtr<layers::SurfaceDescriptor> mFrontBufferDesc;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// WebGLRenderingContext Basic Properties and Methods
|
||||
|
@ -995,8 +994,9 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
|
|||
}
|
||||
void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval);
|
||||
|
||||
void Present();
|
||||
Maybe<layers::SurfaceDescriptor> GetFrontBuffer(layers::TextureType);
|
||||
void Present(WebGLFramebufferJS*, layers::TextureType);
|
||||
Maybe<layers::SurfaceDescriptor> GetFrontBuffer(WebGLFramebufferJS*,
|
||||
layers::TextureType);
|
||||
RefPtr<gfx::SourceSurface> GetFrontBufferSnapshot() override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -317,7 +317,7 @@ class ClientWebGLExtensionExplicitPresent : public ClientWebGLExtensionBase {
|
|||
AutoJsWarning("present: Extension is `invalidated`.");
|
||||
return;
|
||||
}
|
||||
mContext->Present();
|
||||
mContext->OnBeforePaintTransaction();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -107,8 +107,8 @@ void HostWebGLContext::JsWarning(const std::string& text) const {
|
|||
}
|
||||
|
||||
Maybe<layers::SurfaceDescriptor> HostWebGLContext::GetFrontBuffer(
|
||||
const layers::TextureType t) const {
|
||||
return mContext->GetFrontBuffer(t);
|
||||
const ObjectId fb, const layers::TextureType t) const {
|
||||
return mContext->GetFrontBuffer(AutoResolve(fb), t);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
|
|
@ -184,9 +184,11 @@ class HostWebGLContext final : public SupportsWeakPtr<HostWebGLContext> {
|
|||
mContext->SetCompositableHost(compositableHost);
|
||||
}
|
||||
|
||||
void Present() { return (void)mContext->Present(); }
|
||||
Maybe<layers::SurfaceDescriptor> GetFrontBuffer(
|
||||
const layers::TextureType t) const;
|
||||
void Present(const ObjectId fb, const layers::TextureType t) const {
|
||||
return (void)mContext->Present(AutoResolve(fb), t);
|
||||
}
|
||||
Maybe<layers::SurfaceDescriptor> GetFrontBuffer(ObjectId fb,
|
||||
layers::TextureType) const;
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> GetFrontBufferSnapshot() const {
|
||||
return mContext->GetFrontBufferSnapshot();
|
||||
|
|
|
@ -942,32 +942,46 @@ bool WebGLContext::PresentInto(gl::SwapChain& swapChain) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void WebGLContext::Present() {
|
||||
void WebGLContext::Present(WebGLFramebuffer* const fb,
|
||||
const layers::TextureType consumerType) {
|
||||
const FuncScope funcScope(*this, "<Present>");
|
||||
if (IsContextLost()) return;
|
||||
|
||||
mResolvedDefaultFB = nullptr;
|
||||
|
||||
if (!mSwapChain.mFactory) {
|
||||
NS_WARNING("Failed to make an ideal SurfaceFactory.");
|
||||
mSwapChain.mFactory = MakeUnique<gl::SurfaceFactory_Basic>(*gl);
|
||||
auto swapChain = &mSwapChain;
|
||||
if (fb) {
|
||||
swapChain = &fb->mOpaqueSwapChain;
|
||||
} else {
|
||||
mResolvedDefaultFB = nullptr;
|
||||
}
|
||||
MOZ_ASSERT(mSwapChain.mFactory);
|
||||
|
||||
(void)PresentInto(mSwapChain);
|
||||
if (!swapChain->mFactory) {
|
||||
auto typedFactory = gl::SurfaceFactory::Create(gl, consumerType);
|
||||
if (typedFactory) {
|
||||
swapChain->mFactory = std::move(typedFactory);
|
||||
}
|
||||
}
|
||||
if (!swapChain->mFactory) {
|
||||
NS_WARNING("Failed to make an ideal SurfaceFactory.");
|
||||
swapChain->mFactory = MakeUnique<gl::SurfaceFactory_Basic>(*gl);
|
||||
}
|
||||
MOZ_ASSERT(swapChain->mFactory);
|
||||
|
||||
(void)PresentInto(*swapChain);
|
||||
}
|
||||
|
||||
Maybe<layers::SurfaceDescriptor> WebGLContext::GetFrontBuffer(
|
||||
const layers::TextureType consumerType) {
|
||||
if (mSwapChain.mFactory &&
|
||||
mSwapChain.mFactory->mDesc.consumerType != consumerType) {
|
||||
auto typedFactory = gl::SurfaceFactory::Create(gl, consumerType);
|
||||
if (typedFactory) {
|
||||
mSwapChain.mFactory = std::move(typedFactory);
|
||||
}
|
||||
WebGLFramebuffer* const fb, const layers::TextureType consumerType) {
|
||||
auto swapChain = &mSwapChain;
|
||||
if (fb) {
|
||||
swapChain = &fb->mOpaqueSwapChain;
|
||||
}
|
||||
|
||||
const auto& front = mSwapChain.FrontBuffer();
|
||||
if (swapChain->mFactory &&
|
||||
swapChain->mFactory->mDesc.consumerType != consumerType) {
|
||||
swapChain->mFactory = nullptr; // Better luck next Present.
|
||||
}
|
||||
|
||||
const auto& front = swapChain->FrontBuffer();
|
||||
if (!front) return {};
|
||||
|
||||
return front->ToSurfaceDescriptor();
|
||||
|
|
|
@ -100,6 +100,7 @@ class MozFramebuffer;
|
|||
|
||||
namespace layers {
|
||||
class CompositableHost;
|
||||
class SurfaceDescriptor;
|
||||
}
|
||||
|
||||
namespace webgl {
|
||||
|
@ -484,9 +485,10 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr<WebGLContext> {
|
|||
bool PresentInto(gl::SwapChain& swapChain);
|
||||
|
||||
public:
|
||||
void Present();
|
||||
void Present(WebGLFramebuffer*, layers::TextureType);
|
||||
RefPtr<gfx::DataSourceSurface> GetFrontBufferSnapshot();
|
||||
Maybe<layers::SurfaceDescriptor> GetFrontBuffer(layers::TextureType);
|
||||
Maybe<layers::SurfaceDescriptor> GetFrontBuffer(WebGLFramebuffer*,
|
||||
layers::TextureType);
|
||||
|
||||
void RunContextLossTimer();
|
||||
void CheckForContextLoss();
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "mozilla/WeakPtr.h"
|
||||
|
||||
#include "GLScreenBuffer.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
#include "WebGLTexture.h"
|
||||
|
@ -138,6 +139,7 @@ class WebGLFramebuffer final : public WebGLContextBoundObject,
|
|||
const GLuint mGLName;
|
||||
bool mHasBeenBound = false;
|
||||
const UniquePtr<gl::MozFramebuffer> mOpaque;
|
||||
gl::SwapChain mOpaqueSwapChain;
|
||||
bool mInOpaqueRAF = false;
|
||||
|
||||
private:
|
||||
|
|
|
@ -989,26 +989,6 @@ inline std::string ToString(const nsACString& text) {
|
|||
return {text.BeginReading(), text.Length()};
|
||||
}
|
||||
|
||||
// -
|
||||
// ClientWebGLContext exports!
|
||||
// (So that you don't need to include the mess that is ClientWebGLContext.h)
|
||||
namespace gfx {
|
||||
class SourceSurface;
|
||||
} // namespace gfx
|
||||
|
||||
namespace layers {
|
||||
class KnowsCompositor;
|
||||
class SurfaceDescriptor;
|
||||
} // namespace layers
|
||||
|
||||
namespace webgl {
|
||||
|
||||
void Present(ClientWebGLContext&);
|
||||
Maybe<layers::SurfaceDescriptor> GetFrontBuffer(ClientWebGLContext&,
|
||||
layers::KnowsCompositor*);
|
||||
|
||||
} // namespace webgl
|
||||
|
||||
// -
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "mozilla/layers/TextureClientSharedSurface.h"
|
||||
#include "mozilla/layers/CompositableForwarder.h"
|
||||
|
||||
#include "ClientWebGLContext.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "GLScreenBuffer.h"
|
||||
#include "nsICanvasRenderingContextInternal.h"
|
||||
|
@ -122,7 +123,12 @@ void ShareableCanvasRenderer::UpdateCompositableClient() {
|
|||
|
||||
if (!webgl) return nullptr;
|
||||
if (!forwarder) return nullptr;
|
||||
const auto desc = webgl::GetFrontBuffer(*webgl, forwarder);
|
||||
|
||||
auto texType = layers::TextureType::Unknown;
|
||||
if (forwarder) {
|
||||
texType = layers::PreferredCanvasTextureType(*forwarder);
|
||||
}
|
||||
const auto desc = webgl->GetFrontBuffer(nullptr, texType);
|
||||
if (!desc) return nullptr;
|
||||
return GetFrontBufferFromDesc(*desc, flags);
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/layers/ImageBridgeChild.h"
|
||||
#include "mozilla/layers/LayersMessages.h" // for TimedTexture
|
||||
#include "mozilla/layers/SyncObject.h" // for SyncObjectClient
|
||||
#include "mozilla/StaticPrefs_webgl.h"
|
||||
|
||||
#include "ClientWebGLContext.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
@ -40,6 +41,7 @@ void VRLayerChild::Initialize(dom::HTMLCanvasElement* aCanvasElement,
|
|||
void VRLayerChild::SetXRFramebuffer(WebGLFramebufferJS* fb) {
|
||||
mFramebuffer = fb;
|
||||
}
|
||||
|
||||
static constexpr bool kIsAndroid =
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
true;
|
||||
|
@ -65,7 +67,6 @@ void VRLayerChild::SubmitFrame(const VRDisplayInfo& aDisplayInfo) {
|
|||
// 1 extra frame, accomodating overlapped asynchronous rendering.
|
||||
mLastFrameTextureDesc = mThisFrameTextureDesc;
|
||||
|
||||
bool forSeparateVrSwapChain = false;
|
||||
bool getNewFrame = true;
|
||||
if (kIsAndroid) {
|
||||
/**
|
||||
|
@ -75,17 +76,24 @@ void VRLayerChild::SubmitFrame(const VRDisplayInfo& aDisplayInfo) {
|
|||
* in the WebGLContext GLScreenBuffer producer. Not doing so causes some
|
||||
* freezes, crashes or other undefined behaviour.
|
||||
*/
|
||||
forSeparateVrSwapChain = true;
|
||||
getNewFrame = (!mThisFrameTextureDesc ||
|
||||
aDisplayInfo.mDisplayState.lastSubmittedFrameId ==
|
||||
mLastSubmittedFrameId);
|
||||
}
|
||||
if (getNewFrame) {
|
||||
webgl::Present(*webgl);
|
||||
|
||||
RefPtr<layers::ImageBridgeChild> imageBridge =
|
||||
const RefPtr<layers::ImageBridgeChild> imageBridge =
|
||||
layers::ImageBridgeChild::GetSingleton();
|
||||
mThisFrameTextureDesc = webgl::GetFrontBuffer(*webgl, imageBridge);
|
||||
|
||||
auto texType = layers::TextureType::Unknown;
|
||||
if (imageBridge) {
|
||||
texType = layers::PreferredCanvasTextureType(*imageBridge);
|
||||
}
|
||||
if (kIsAndroid && StaticPrefs::webgl_enable_surface_texture()) {
|
||||
texType = layers::TextureType::AndroidNativeWindow;
|
||||
}
|
||||
|
||||
webgl->Present(mFramebuffer, texType);
|
||||
mThisFrameTextureDesc = webgl->GetFrontBuffer(mFramebuffer, texType);
|
||||
}
|
||||
|
||||
mLastSubmittedFrameId = frameId;
|
||||
|
|
Загрузка…
Ссылка в новой задаче