Backed out changeset 7f86a5d0334d (bug 1853821) for causing xpcshell failures on...
[gecko.git] / gfx / gl / GLScreenBuffer.cpp
blob6550698eb516c67ade8bf826d0f6d75a22ac25d9
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"
13 #include "mozilla/gfx/BuildConstants.h"
15 namespace mozilla::gl {
17 // -
18 // SwapChainPresenter
20 UniquePtr<SwapChainPresenter> SwapChain::Acquire(
21 const gfx::IntSize& size, const gfx::ColorSpace2 colorSpace) {
22 MOZ_ASSERT(mFactory);
24 std::shared_ptr<SharedSurface> surf;
25 if (!mPool.empty()) {
26 // Try reuse
27 const auto& existingDesc = mPool.front()->mDesc;
28 auto newDesc = existingDesc;
29 newDesc.size = size;
30 newDesc.colorSpace = colorSpace;
31 if (newDesc != existingDesc || !mPool.front()->IsValid()) {
32 mPool = {};
36 // When pooling is disabled, recycling of SharedSurfaces is managed by the
37 // owner of the SwapChain by calling StoreRecycledSurface().
38 if (!mPool.empty() && (!mPoolLimit || mPool.size() >= mPoolLimit)) {
39 surf = mPool.front();
40 mPool.pop();
42 if (!surf) {
43 auto uniquePtrSurf = mFactory->CreateShared(size, colorSpace);
44 if (!uniquePtrSurf) return nullptr;
45 surf.reset(uniquePtrSurf.release());
47 if (mPoolLimit > 0) {
48 mPool.push(surf);
49 while (mPool.size() > mPoolLimit) {
50 mPool.pop();
54 auto ret = MakeUnique<SwapChainPresenter>(*this);
55 const auto old = ret->SwapBackBuffer(surf);
56 MOZ_ALWAYS_TRUE(!old);
57 return ret;
60 void SwapChain::ClearPool() {
61 mPool = {};
62 mPrevFrontBuffer = nullptr;
65 bool SwapChain::StoreRecycledSurface(
66 const std::shared_ptr<SharedSurface>& surf) {
67 MOZ_ASSERT(mFactory);
68 // Don't allow external recycled surfaces if SwapChain is managing own pool.
69 MOZ_ASSERT(!mPoolLimit);
70 if (mPoolLimit > 0 || !mFactory ||
71 NS_WARN_IF(surf->mDesc.gl != mFactory->mDesc.gl)) {
72 // Ensure we don't accidentally store an expired shared surface or from a
73 // different context.
74 return false;
76 mPool.push(surf);
77 return true;
80 // -
82 SwapChainPresenter::SwapChainPresenter(SwapChain& swapChain)
83 : mSwapChain(&swapChain) {
84 MOZ_RELEASE_ASSERT(mSwapChain->mPresenter == nullptr);
85 mSwapChain->mPresenter = this;
88 SwapChainPresenter::~SwapChainPresenter() {
89 if (!mSwapChain) return;
90 MOZ_RELEASE_ASSERT(mSwapChain->mPresenter == this);
91 mSwapChain->mPresenter = nullptr;
93 auto newFront = SwapBackBuffer(nullptr);
94 if (newFront) {
95 mSwapChain->mPrevFrontBuffer = mSwapChain->mFrontBuffer;
96 mSwapChain->mFrontBuffer = newFront;
100 std::shared_ptr<SharedSurface> SwapChainPresenter::SwapBackBuffer(
101 std::shared_ptr<SharedSurface> back) {
102 if (mBackBuffer) {
103 mBackBuffer->UnlockProd();
104 mBackBuffer->ProducerRelease();
105 mBackBuffer->Commit();
107 auto old = mBackBuffer;
108 mBackBuffer = back;
109 if (mBackBuffer) {
110 mBackBuffer->WaitForBufferOwnership();
111 mBackBuffer->ProducerAcquire();
112 mBackBuffer->LockProd();
114 return old;
117 GLuint SwapChainPresenter::Fb() const {
118 if (!mBackBuffer) return 0;
119 const auto& fb = mBackBuffer->mFb;
120 if (!fb) return 0;
121 return fb->mFB;
124 // -
125 // SwapChain
127 SwapChain::SwapChain()
128 : // We need to apply pooling on Android because of the AndroidSurface slow
129 // destructor bugs. They cause a noticeable performance hit. See bug
130 // #1646073.
131 mPoolLimit(kIsAndroid ? 4 : 0) {}
133 SwapChain::~SwapChain() {
134 if (mPresenter) {
135 // Out of order destruction, but ok.
136 (void)mPresenter->SwapBackBuffer(nullptr);
137 mPresenter->mSwapChain = nullptr;
138 mPresenter = nullptr;
140 if (mDestroyedCallback) {
141 mDestroyedCallback();
145 } // namespace mozilla::gl