Bug 1874684 - Part 28: Return DateDuration from DifferenceISODateTime. r=mgaudet
[gecko.git] / gfx / gl / GLScreenBuffer.cpp
blob9dda11b41a3ad15d9e3af0d6a58d527f139b8d97
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 auto ret = MakeUnique<SwapChainPresenter>(*this);
64 const auto old = ret->SwapBackBuffer(surf);
65 MOZ_ALWAYS_TRUE(!old);
66 return ret;
69 void SwapChain::ClearPool() {
70 mPool = {};
71 mPrevFrontBuffer = nullptr;
74 bool SwapChain::StoreRecycledSurface(
75 const std::shared_ptr<SharedSurface>& surf) {
76 MOZ_ASSERT(mFactory);
77 if (!mFactory || NS_WARN_IF(surf->mDesc.gl != mFactory->mDesc.gl)) {
78 // Ensure we don't accidentally store an expired shared surface or from a
79 // different context.
80 return false;
82 mPool.push(surf);
83 return true;
86 // -
88 SwapChainPresenter::SwapChainPresenter(SwapChain& swapChain)
89 : mSwapChain(&swapChain) {
90 MOZ_RELEASE_ASSERT(mSwapChain->mPresenter == nullptr);
91 mSwapChain->mPresenter = this;
94 SwapChainPresenter::~SwapChainPresenter() {
95 if (!mSwapChain) return;
96 MOZ_RELEASE_ASSERT(mSwapChain->mPresenter == this);
97 mSwapChain->mPresenter = nullptr;
99 auto newFront = SwapBackBuffer(nullptr);
100 if (newFront) {
101 mSwapChain->mPrevFrontBuffer = mSwapChain->mFrontBuffer;
102 mSwapChain->mFrontBuffer = newFront;
106 std::shared_ptr<SharedSurface> SwapChainPresenter::SwapBackBuffer(
107 std::shared_ptr<SharedSurface> back) {
108 if (mBackBuffer) {
109 mBackBuffer->UnlockProd();
110 mBackBuffer->ProducerRelease();
111 mBackBuffer->Commit();
113 auto old = mBackBuffer;
114 mBackBuffer = back;
115 if (mBackBuffer) {
116 mBackBuffer->WaitForBufferOwnership();
117 mBackBuffer->ProducerAcquire();
118 mBackBuffer->LockProd();
120 return old;
123 GLuint SwapChainPresenter::Fb() const {
124 if (!mBackBuffer) return 0;
125 const auto& fb = mBackBuffer->mFb;
126 if (!fb) return 0;
127 return fb->mFB;
130 // -
131 // SwapChain
133 SwapChain::SwapChain() = default;
135 SwapChain::~SwapChain() {
136 if (mPresenter) {
137 // Out of order destruction, but ok.
138 (void)mPresenter->SwapBackBuffer(nullptr);
139 mPresenter->mSwapChain = nullptr;
140 mPresenter = nullptr;
142 if (mDestroyedCallback) {
143 mDestroyedCallback();
147 } // namespace mozilla::gl