forked from mirrors/gecko-dev
Bug 1894929 - Disable gl::SwapChain's internal pooling when RemoteTextureMap is used. r=jnicol,gfx-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D210864
This commit is contained in:
parent
657651cbad
commit
16ec378645
3 changed files with 42 additions and 28 deletions
|
|
@ -1126,7 +1126,7 @@ bool WebGLContext::PresentIntoXR(gl::SwapChain& swapChain,
|
||||||
|
|
||||||
// Initialize a swap chain's surface factory given the desired surface type.
|
// Initialize a swap chain's surface factory given the desired surface type.
|
||||||
void InitSwapChain(gl::GLContext& gl, gl::SwapChain& swapChain,
|
void InitSwapChain(gl::GLContext& gl, gl::SwapChain& swapChain,
|
||||||
const layers::TextureType consumerType) {
|
const layers::TextureType consumerType, bool useAsync) {
|
||||||
if (!swapChain.mFactory) {
|
if (!swapChain.mFactory) {
|
||||||
auto typedFactory = gl::SurfaceFactory::Create(&gl, consumerType);
|
auto typedFactory = gl::SurfaceFactory::Create(&gl, consumerType);
|
||||||
if (typedFactory) {
|
if (typedFactory) {
|
||||||
|
|
@ -1138,6 +1138,11 @@ void InitSwapChain(gl::GLContext& gl, gl::SwapChain& swapChain,
|
||||||
swapChain.mFactory = MakeUnique<gl::SurfaceFactory_Basic>(gl);
|
swapChain.mFactory = MakeUnique<gl::SurfaceFactory_Basic>(gl);
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(swapChain.mFactory);
|
MOZ_ASSERT(swapChain.mFactory);
|
||||||
|
if (useAsync) {
|
||||||
|
// RemoteTextureMap will handle recycling any surfaces, so don't rely on the
|
||||||
|
// SwapChain's internal pooling.
|
||||||
|
swapChain.DisablePool();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebGLContext::Present(WebGLFramebuffer* const xrFb,
|
void WebGLContext::Present(WebGLFramebuffer* const xrFb,
|
||||||
|
|
@ -1158,7 +1163,10 @@ void WebGLContext::Present(WebGLFramebuffer* const xrFb,
|
||||||
mResolvedDefaultFB = nullptr;
|
mResolvedDefaultFB = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
InitSwapChain(*gl, *swapChain, consumerType);
|
bool useAsync = options.remoteTextureOwnerId.IsValid() &&
|
||||||
|
options.remoteTextureId.IsValid();
|
||||||
|
|
||||||
|
InitSwapChain(*gl, *swapChain, consumerType, useAsync);
|
||||||
|
|
||||||
bool valid =
|
bool valid =
|
||||||
maybeFB ? PresentIntoXR(*swapChain, *maybeFB) : PresentInto(*swapChain);
|
maybeFB ? PresentIntoXR(*swapChain, *maybeFB) : PresentInto(*swapChain);
|
||||||
|
|
@ -1167,8 +1175,6 @@ void WebGLContext::Present(WebGLFramebuffer* const xrFb,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool useAsync = options.remoteTextureOwnerId.IsValid() &&
|
|
||||||
options.remoteTextureId.IsValid();
|
|
||||||
if (useAsync) {
|
if (useAsync) {
|
||||||
PushRemoteTexture(nullptr, *swapChain, swapChain->FrontBuffer(), options);
|
PushRemoteTexture(nullptr, *swapChain, swapChain->FrontBuffer(), options);
|
||||||
}
|
}
|
||||||
|
|
@ -1205,10 +1211,11 @@ bool WebGLContext::CopyToSwapChain(
|
||||||
}
|
}
|
||||||
gfx::IntSize size(info->width, info->height);
|
gfx::IntSize size(info->width, info->height);
|
||||||
|
|
||||||
InitSwapChain(*gl, srcFb->mSwapChain, consumerType);
|
|
||||||
|
|
||||||
bool useAsync = options.remoteTextureOwnerId.IsValid() &&
|
bool useAsync = options.remoteTextureOwnerId.IsValid() &&
|
||||||
options.remoteTextureId.IsValid();
|
options.remoteTextureId.IsValid();
|
||||||
|
|
||||||
|
InitSwapChain(*gl, srcFb->mSwapChain, consumerType, useAsync);
|
||||||
|
|
||||||
// If we're using async present and if there is no way to serialize surfaces,
|
// If we're using async present and if there is no way to serialize surfaces,
|
||||||
// then a readback is required to do the copy. In this case, there's no reason
|
// then a readback is required to do the copy. In this case, there's no reason
|
||||||
// to copy into a separate shared surface for the front buffer. Just directly
|
// to copy into a separate shared surface for the front buffer. Just directly
|
||||||
|
|
@ -2429,7 +2436,7 @@ webgl::LinkActiveInfo GetLinkActiveInfo(
|
||||||
|
|
||||||
ret.activeUniforms.push_back(std::move(info));
|
ret.activeUniforms.push_back(std::move(info));
|
||||||
} // for i
|
} // for i
|
||||||
} // anon
|
} // anon
|
||||||
|
|
||||||
if (webgl2) {
|
if (webgl2) {
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
|
|
@ -2475,7 +2482,7 @@ webgl::LinkActiveInfo GetLinkActiveInfo(
|
||||||
|
|
||||||
ret.activeUniformBlocks.push_back(std::move(info));
|
ret.activeUniformBlocks.push_back(std::move(info));
|
||||||
} // for i
|
} // for i
|
||||||
} // anon
|
} // anon
|
||||||
|
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
// active tf varyings
|
// active tf varyings
|
||||||
|
|
|
||||||
|
|
@ -10,22 +10,13 @@
|
||||||
#include "gfx2DGlue.h"
|
#include "gfx2DGlue.h"
|
||||||
#include "MozFramebuffer.h"
|
#include "MozFramebuffer.h"
|
||||||
#include "SharedSurface.h"
|
#include "SharedSurface.h"
|
||||||
|
#include "mozilla/gfx/BuildConstants.h"
|
||||||
|
|
||||||
namespace mozilla::gl {
|
namespace mozilla::gl {
|
||||||
|
|
||||||
// -
|
// -
|
||||||
// SwapChainPresenter
|
// SwapChainPresenter
|
||||||
|
|
||||||
// We need to apply pooling on Android because of the AndroidSurface slow
|
|
||||||
// destructor bugs. They cause a noticeable performance hit. See bug
|
|
||||||
// #1646073.
|
|
||||||
static constexpr size_t kPoolSize =
|
|
||||||
#if defined(MOZ_WIDGET_ANDROID)
|
|
||||||
4;
|
|
||||||
#else
|
|
||||||
0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
UniquePtr<SwapChainPresenter> SwapChain::Acquire(
|
UniquePtr<SwapChainPresenter> SwapChain::Acquire(
|
||||||
const gfx::IntSize& size, const gfx::ColorSpace2 colorSpace) {
|
const gfx::IntSize& size, const gfx::ColorSpace2 colorSpace) {
|
||||||
MOZ_ASSERT(mFactory);
|
MOZ_ASSERT(mFactory);
|
||||||
|
|
@ -42,11 +33,9 @@ UniquePtr<SwapChainPresenter> SwapChain::Acquire(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When mDestroyedCallback exists, recycling of SharedSurfaces is managed by
|
// When pooling is disabled, recycling of SharedSurfaces is managed by the
|
||||||
// the owner of the SwapChain by calling StoreRecycledSurface().
|
// owner of the SwapChain by calling StoreRecycledSurface().
|
||||||
const auto poolSize = mDestroyedCallback ? 0 : kPoolSize;
|
if (!mPool.empty() && (!mPoolLimit || mPool.size() >= mPoolLimit)) {
|
||||||
|
|
||||||
if (!mPool.empty() && (!poolSize || mPool.size() == poolSize)) {
|
|
||||||
surf = mPool.front();
|
surf = mPool.front();
|
||||||
mPool.pop();
|
mPool.pop();
|
||||||
}
|
}
|
||||||
|
|
@ -55,9 +44,11 @@ UniquePtr<SwapChainPresenter> SwapChain::Acquire(
|
||||||
if (!uniquePtrSurf) return nullptr;
|
if (!uniquePtrSurf) return nullptr;
|
||||||
surf.reset(uniquePtrSurf.release());
|
surf.reset(uniquePtrSurf.release());
|
||||||
}
|
}
|
||||||
mPool.push(surf);
|
if (mPoolLimit > 0) {
|
||||||
while (mPool.size() > poolSize) {
|
mPool.push(surf);
|
||||||
mPool.pop();
|
while (mPool.size() > mPoolLimit) {
|
||||||
|
mPool.pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ret = MakeUnique<SwapChainPresenter>(*this);
|
auto ret = MakeUnique<SwapChainPresenter>(*this);
|
||||||
|
|
@ -74,7 +65,10 @@ void SwapChain::ClearPool() {
|
||||||
bool SwapChain::StoreRecycledSurface(
|
bool SwapChain::StoreRecycledSurface(
|
||||||
const std::shared_ptr<SharedSurface>& surf) {
|
const std::shared_ptr<SharedSurface>& surf) {
|
||||||
MOZ_ASSERT(mFactory);
|
MOZ_ASSERT(mFactory);
|
||||||
if (!mFactory || NS_WARN_IF(surf->mDesc.gl != mFactory->mDesc.gl)) {
|
// Don't allow external recycled surfaces if SwapChain is managing own pool.
|
||||||
|
MOZ_ASSERT(!mPoolLimit);
|
||||||
|
if (mPoolLimit > 0 || !mFactory ||
|
||||||
|
NS_WARN_IF(surf->mDesc.gl != mFactory->mDesc.gl)) {
|
||||||
// Ensure we don't accidentally store an expired shared surface or from a
|
// Ensure we don't accidentally store an expired shared surface or from a
|
||||||
// different context.
|
// different context.
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -130,7 +124,11 @@ GLuint SwapChainPresenter::Fb() const {
|
||||||
// -
|
// -
|
||||||
// SwapChain
|
// SwapChain
|
||||||
|
|
||||||
SwapChain::SwapChain() = default;
|
SwapChain::SwapChain()
|
||||||
|
: // We need to apply pooling on Android because of the AndroidSurface slow
|
||||||
|
// destructor bugs. They cause a noticeable performance hit. See bug
|
||||||
|
// #1646073.
|
||||||
|
mPoolLimit(kIsAndroid ? 4 : 0) {}
|
||||||
|
|
||||||
SwapChain::~SwapChain() {
|
SwapChain::~SwapChain() {
|
||||||
if (mPresenter) {
|
if (mPresenter) {
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ class SwapChain final {
|
||||||
UniquePtr<SurfaceFactory> mFactory;
|
UniquePtr<SurfaceFactory> mFactory;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
size_t mPoolLimit;
|
||||||
std::queue<std::shared_ptr<SharedSurface>> mPool;
|
std::queue<std::shared_ptr<SharedSurface>> mPool;
|
||||||
std::shared_ptr<SharedSurface> mFrontBuffer;
|
std::shared_ptr<SharedSurface> mFrontBuffer;
|
||||||
std::function<void()> mDestroyedCallback;
|
std::function<void()> mDestroyedCallback;
|
||||||
|
|
@ -69,6 +70,14 @@ class SwapChain final {
|
||||||
SwapChain();
|
SwapChain();
|
||||||
virtual ~SwapChain();
|
virtual ~SwapChain();
|
||||||
|
|
||||||
|
void DisablePool() {
|
||||||
|
if (mPoolLimit) {
|
||||||
|
MOZ_ASSERT(mPool.empty());
|
||||||
|
mPool = {};
|
||||||
|
mPoolLimit = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ClearPool();
|
void ClearPool();
|
||||||
bool StoreRecycledSurface(const std::shared_ptr<SharedSurface>& surf);
|
bool StoreRecycledSurface(const std::shared_ptr<SharedSurface>& surf);
|
||||||
const auto& FrontBuffer() const { return mFrontBuffer; }
|
const auto& FrontBuffer() const { return mFrontBuffer; }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue