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"
10 #include "gfx2DGlue.h"
11 #include "MozFramebuffer.h"
12 #include "SharedSurface.h"
14 namespace mozilla::gl
{
19 // We need to apply pooling on Android because of the AndroidSurface slow
20 // destructor bugs. They cause a noticeable performance hit. See bug
22 static constexpr size_t kPoolSize
=
23 #if defined(MOZ_WIDGET_ANDROID)
29 UniquePtr
<SwapChainPresenter
> SwapChain::Acquire(
30 const gfx::IntSize
& size
, const gfx::ColorSpace2 colorSpace
) {
33 std::shared_ptr
<SharedSurface
> surf
;
36 const auto& existingDesc
= mPool
.front()->mDesc
;
37 auto newDesc
= existingDesc
;
39 newDesc
.colorSpace
= colorSpace
;
40 if (newDesc
!= existingDesc
|| !mPool
.front()->IsValid()) {
45 if (!mPool
.empty() && (!kPoolSize
|| mPool
.size() == kPoolSize
)) {
50 auto uniquePtrSurf
= mFactory
->CreateShared(size
, colorSpace
);
51 if (!uniquePtrSurf
) return nullptr;
52 surf
.reset(uniquePtrSurf
.release());
55 while (mPool
.size() > kPoolSize
) {
59 auto ret
= MakeUnique
<SwapChainPresenter
>(*this);
60 const auto old
= ret
->SwapBackBuffer(surf
);
61 MOZ_ALWAYS_TRUE(!old
);
65 void SwapChain::ClearPool() {
67 mPrevFrontBuffer
= nullptr;
70 void SwapChain::StoreRecycledSurface(
71 const std::shared_ptr
<SharedSurface
>& surf
) {
77 SwapChainPresenter::SwapChainPresenter(SwapChain
& swapChain
)
78 : mSwapChain(&swapChain
) {
79 MOZ_RELEASE_ASSERT(mSwapChain
->mPresenter
== nullptr);
80 mSwapChain
->mPresenter
= this;
83 SwapChainPresenter::~SwapChainPresenter() {
84 if (!mSwapChain
) return;
85 MOZ_RELEASE_ASSERT(mSwapChain
->mPresenter
== this);
86 mSwapChain
->mPresenter
= nullptr;
88 auto newFront
= SwapBackBuffer(nullptr);
90 mSwapChain
->mPrevFrontBuffer
= mSwapChain
->mFrontBuffer
;
91 mSwapChain
->mFrontBuffer
= newFront
;
95 std::shared_ptr
<SharedSurface
> SwapChainPresenter::SwapBackBuffer(
96 std::shared_ptr
<SharedSurface
> back
) {
98 mBackBuffer
->UnlockProd();
99 mBackBuffer
->ProducerRelease();
100 mBackBuffer
->Commit();
102 auto old
= mBackBuffer
;
105 mBackBuffer
->WaitForBufferOwnership();
106 mBackBuffer
->ProducerAcquire();
107 mBackBuffer
->LockProd();
112 GLuint
SwapChainPresenter::Fb() const {
113 if (!mBackBuffer
) return 0;
114 const auto& fb
= mBackBuffer
->mFb
;
122 SwapChain::SwapChain() = default;
124 SwapChain::~SwapChain() {
126 // Out of order destruction, but ok.
127 (void)mPresenter
->SwapBackBuffer(nullptr);
128 mPresenter
->mSwapChain
= nullptr;
129 mPresenter
= nullptr;
131 if (mDestroyedCallback
) {
132 mDestroyedCallback();
136 } // namespace mozilla::gl