Bug 1785744 [wpt PR 35504] - Recalc style for elements where :toggle() pseudo-class...
[gecko.git] / gfx / gl / GLScreenBuffer.cpp
blob658df6a84a3f024fce2824e1286d84477cdc93b3
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 if (!mPool.empty() && (!kPoolSize || mPool.size() == kPoolSize)) {
46 surf = mPool.front();
47 mPool.pop();
49 if (!surf) {
50 auto uniquePtrSurf = mFactory->CreateShared(size, colorSpace);
51 if (!uniquePtrSurf) return nullptr;
52 surf.reset(uniquePtrSurf.release());
54 mPool.push(surf);
55 while (mPool.size() > kPoolSize) {
56 mPool.pop();
59 auto ret = MakeUnique<SwapChainPresenter>(*this);
60 const auto old = ret->SwapBackBuffer(surf);
61 MOZ_ALWAYS_TRUE(!old);
62 return ret;
65 void SwapChain::ClearPool() {
66 mPool = {};
67 mPrevFrontBuffer = nullptr;
70 void SwapChain::StoreRecycledSurface(
71 const std::shared_ptr<SharedSurface>& surf) {
72 mPool.push(surf);
75 // -
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);
89 if (newFront) {
90 mSwapChain->mPrevFrontBuffer = mSwapChain->mFrontBuffer;
91 mSwapChain->mFrontBuffer = newFront;
95 std::shared_ptr<SharedSurface> SwapChainPresenter::SwapBackBuffer(
96 std::shared_ptr<SharedSurface> back) {
97 if (mBackBuffer) {
98 mBackBuffer->UnlockProd();
99 mBackBuffer->ProducerRelease();
100 mBackBuffer->Commit();
102 auto old = mBackBuffer;
103 mBackBuffer = back;
104 if (mBackBuffer) {
105 mBackBuffer->WaitForBufferOwnership();
106 mBackBuffer->ProducerAcquire();
107 mBackBuffer->LockProd();
109 return old;
112 GLuint SwapChainPresenter::Fb() const {
113 if (!mBackBuffer) return 0;
114 const auto& fb = mBackBuffer->mFb;
115 if (!fb) return 0;
116 return fb->mFB;
119 // -
120 // SwapChain
122 SwapChain::SwapChain() = default;
124 SwapChain::~SwapChain() {
125 if (mPresenter) {
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