Bug 1866777 - Disable test_race_cache_with_network.js on windows opt for frequent...
[gecko.git] / gfx / gl / GLScreenBuffer.cpp
blob1120c18af419da409243d448c4995a0b53ffdc39
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 bool success = false;
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)) {
68 return nullptr;
70 return ret;
73 void SwapChain::ClearPool() {
74 mPool = {};
75 mPrevFrontBuffer = nullptr;
78 void SwapChain::StoreRecycledSurface(
79 const std::shared_ptr<SharedSurface>& surf) {
80 mPool.push(surf);
83 // -
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;
96 bool success;
97 auto newFront = SwapBackBuffer(nullptr, success);
98 if (newFront) {
99 mSwapChain->mPrevFrontBuffer = mSwapChain->mFrontBuffer;
100 mSwapChain->mFrontBuffer = newFront;
104 std::shared_ptr<SharedSurface> SwapChainPresenter::SwapBackBuffer(
105 std::shared_ptr<SharedSurface> back, bool& aSuccess) {
106 if (mBackBuffer) {
107 mBackBuffer->UnlockProd();
108 mBackBuffer->ProducerRelease();
109 mBackBuffer->Commit();
111 auto old = mBackBuffer;
112 mBackBuffer = back;
113 if (mBackBuffer) {
114 mBackBuffer->WaitForBufferOwnership();
115 if (NS_WARN_IF(!mBackBuffer->ProducerAcquire())) {
116 mBackBuffer = nullptr;
117 aSuccess = false;
118 return old;
120 mBackBuffer->LockProd();
122 aSuccess = true;
123 return old;
126 GLuint SwapChainPresenter::Fb() const {
127 if (!mBackBuffer) return 0;
128 const auto& fb = mBackBuffer->mFb;
129 if (!fb) return 0;
130 return fb->mFB;
133 // -
134 // SwapChain
136 SwapChain::SwapChain() = default;
138 SwapChain::~SwapChain() {
139 if (mPresenter) {
140 // Out of order destruction, but ok.
141 bool success;
142 (void)mPresenter->SwapBackBuffer(nullptr, success);
143 mPresenter->mSwapChain = nullptr;
144 mPresenter = nullptr;
146 if (mDestroyedCallback) {
147 mDestroyedCallback();
151 } // namespace mozilla::gl