Bug 1876177 [wpt PR 44153] - [FedCM] Add a WPT test for authz, a=testonly
[gecko.git] / gfx / gl / GLScreenBuffer.cpp
blob8e6a403b07b75e5f728e9d3bbca7cb977c0d6fbe
1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 4; -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "GLScreenBuffer.h"
8 #include "CompositorTypes.h"
9 #include "GLContext.h"
10 #include "gfx2DGlue.h"
11 #include "MozFramebuffer.h"
12 #include "SharedSurface.h"
14 namespace mozilla::gl {
16 // -
17 // SwapChainPresenter
19 // We need to apply pooling on Android because of the AndroidSurface slow
20 // destructor bugs. They cause a noticeable performance hit. See bug
21 // #1646073.
22 static constexpr size_t kPoolSize =
23 #if defined(MOZ_WIDGET_ANDROID)
25 #else
27 #endif
29 UniquePtr<SwapChainPresenter> SwapChain::Acquire(
30 const gfx::IntSize& size, const gfx::ColorSpace2 colorSpace) {
31 MOZ_ASSERT(mFactory);
33 std::shared_ptr<SharedSurface> surf;
34 if (!mPool.empty()) {
35 // Try reuse
36 const auto& existingDesc = mPool.front()->mDesc;
37 auto newDesc = existingDesc;
38 newDesc.size = size;
39 newDesc.colorSpace = colorSpace;
40 if (newDesc != existingDesc || !mPool.front()->IsValid()) {
41 mPool = {};
45 // When mDestroyedCallback exists, recycling of SharedSurfaces is managed by
46 // the owner of the SwapChain by calling StoreRecycledSurface().
47 const auto poolSize = mDestroyedCallback ? 0 : kPoolSize;
49 if (!mPool.empty() && (!poolSize || mPool.size() == poolSize)) {
50 surf = mPool.front();
51 mPool.pop();
53 if (!surf) {
54 auto uniquePtrSurf = mFactory->CreateShared(size, colorSpace);
55 if (!uniquePtrSurf) return nullptr;
56 surf.reset(uniquePtrSurf.release());
58 mPool.push(surf);
59 while (mPool.size() > poolSize) {
60 mPool.pop();
63 bool success = false;
64 auto ret = MakeUnique<SwapChainPresenter>(*this);
65 const auto old = ret->SwapBackBuffer(surf, success);
66 MOZ_ALWAYS_TRUE(!old);
67 if (NS_WARN_IF(!success)) {
68 return nullptr;
70 return ret;
73 void SwapChain::ClearPool() {
74 mPool = {};
75 mPrevFrontBuffer = nullptr;
78 bool SwapChain::StoreRecycledSurface(
79 const std::shared_ptr<SharedSurface>& surf) {
80 MOZ_ASSERT(mFactory);
81 if (!mFactory || NS_WARN_IF(surf->mDesc.gl != mFactory->mDesc.gl)) {
82 // Ensure we don't accidentally store an expired shared surface or from a
83 // different context.
84 return false;
86 mPool.push(surf);
87 return true;
90 // -
92 SwapChainPresenter::SwapChainPresenter(SwapChain& swapChain)
93 : mSwapChain(&swapChain) {
94 MOZ_RELEASE_ASSERT(mSwapChain->mPresenter == nullptr);
95 mSwapChain->mPresenter = this;
98 SwapChainPresenter::~SwapChainPresenter() {
99 if (!mSwapChain) return;
100 MOZ_RELEASE_ASSERT(mSwapChain->mPresenter == this);
101 mSwapChain->mPresenter = nullptr;
103 bool success;
104 auto newFront = SwapBackBuffer(nullptr, success);
105 if (newFront) {
106 mSwapChain->mPrevFrontBuffer = mSwapChain->mFrontBuffer;
107 mSwapChain->mFrontBuffer = newFront;
111 std::shared_ptr<SharedSurface> SwapChainPresenter::SwapBackBuffer(
112 std::shared_ptr<SharedSurface> back, bool& aSuccess) {
113 if (mBackBuffer) {
114 mBackBuffer->UnlockProd();
115 mBackBuffer->ProducerRelease();
116 mBackBuffer->Commit();
118 auto old = mBackBuffer;
119 mBackBuffer = back;
120 if (mBackBuffer) {
121 mBackBuffer->WaitForBufferOwnership();
122 if (NS_WARN_IF(!mBackBuffer->ProducerAcquire())) {
123 mBackBuffer = nullptr;
124 aSuccess = false;
125 return old;
127 mBackBuffer->LockProd();
129 aSuccess = true;
130 return old;
133 GLuint SwapChainPresenter::Fb() const {
134 if (!mBackBuffer) return 0;
135 const auto& fb = mBackBuffer->mFb;
136 if (!fb) return 0;
137 return fb->mFB;
140 // -
141 // SwapChain
143 SwapChain::SwapChain() = default;
145 SwapChain::~SwapChain() {
146 if (mPresenter) {
147 // Out of order destruction, but ok.
148 bool success;
149 (void)mPresenter->SwapBackBuffer(nullptr, success);
150 mPresenter->mSwapChain = nullptr;
151 mPresenter = nullptr;
153 if (mDestroyedCallback) {
154 mDestroyedCallback();
158 } // namespace mozilla::gl