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 bool SwapChain::StoreRecycledSurface(
79 const std::shared_ptr
<SharedSurface
>& surf
) {
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
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;
104 auto newFront
= SwapBackBuffer(nullptr, success
);
106 mSwapChain
->mPrevFrontBuffer
= mSwapChain
->mFrontBuffer
;
107 mSwapChain
->mFrontBuffer
= newFront
;
111 std::shared_ptr
<SharedSurface
> SwapChainPresenter::SwapBackBuffer(
112 std::shared_ptr
<SharedSurface
> back
, bool& aSuccess
) {
114 mBackBuffer
->UnlockProd();
115 mBackBuffer
->ProducerRelease();
116 mBackBuffer
->Commit();
118 auto old
= mBackBuffer
;
121 mBackBuffer
->WaitForBufferOwnership();
122 if (NS_WARN_IF(!mBackBuffer
->ProducerAcquire())) {
123 mBackBuffer
= nullptr;
127 mBackBuffer
->LockProd();
133 GLuint
SwapChainPresenter::Fb() const {
134 if (!mBackBuffer
) return 0;
135 const auto& fb
= mBackBuffer
->mFb
;
143 SwapChain::SwapChain() = default;
145 SwapChain::~SwapChain() {
147 // Out of order destruction, but ok.
149 (void)mPresenter
->SwapBackBuffer(nullptr, success
);
150 mPresenter
->mSwapChain
= nullptr;
151 mPresenter
= nullptr;
153 if (mDestroyedCallback
) {
154 mDestroyedCallback();
158 } // namespace mozilla::gl