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 // 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
)) {
54 auto uniquePtrSurf
= mFactory
->CreateShared(size
, colorSpace
);
55 if (!uniquePtrSurf
) return nullptr;
56 surf
.reset(uniquePtrSurf
.release());
59 while (mPool
.size() > poolSize
) {
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
)) {
73 void SwapChain::ClearPool() {
75 mPrevFrontBuffer
= nullptr;
78 void SwapChain::StoreRecycledSurface(
79 const std::shared_ptr
<SharedSurface
>& surf
) {
85 SwapChainPresenter::SwapChainPresenter(SwapChain
& swapChain
)
86 : mSwapChain(&swapChain
) {
87 MOZ_RELEASE_ASSERT(mSwapChain
->mPresenter
== nullptr);
88 mSwapChain
->mPresenter
= this;
91 SwapChainPresenter::~SwapChainPresenter() {
92 if (!mSwapChain
) return;
93 MOZ_RELEASE_ASSERT(mSwapChain
->mPresenter
== this);
94 mSwapChain
->mPresenter
= nullptr;
97 auto newFront
= SwapBackBuffer(nullptr, success
);
99 mSwapChain
->mPrevFrontBuffer
= mSwapChain
->mFrontBuffer
;
100 mSwapChain
->mFrontBuffer
= newFront
;
104 std::shared_ptr
<SharedSurface
> SwapChainPresenter::SwapBackBuffer(
105 std::shared_ptr
<SharedSurface
> back
, bool& aSuccess
) {
107 mBackBuffer
->UnlockProd();
108 mBackBuffer
->ProducerRelease();
109 mBackBuffer
->Commit();
111 auto old
= mBackBuffer
;
114 mBackBuffer
->WaitForBufferOwnership();
115 if (NS_WARN_IF(!mBackBuffer
->ProducerAcquire())) {
116 mBackBuffer
= nullptr;
120 mBackBuffer
->LockProd();
126 GLuint
SwapChainPresenter::Fb() const {
127 if (!mBackBuffer
) return 0;
128 const auto& fb
= mBackBuffer
->mFb
;
136 SwapChain::SwapChain() = default;
138 SwapChain::~SwapChain() {
140 // Out of order destruction, but ok.
142 (void)mPresenter
->SwapBackBuffer(nullptr, success
);
143 mPresenter
->mSwapChain
= nullptr;
144 mPresenter
= nullptr;
146 if (mDestroyedCallback
) {
147 mDestroyedCallback();
151 } // namespace mozilla::gl