tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

GLScreenBuffer.cpp (3746B)


      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/. */
      5 
      6 #include "GLScreenBuffer.h"
      7 
      8 #include "CompositorTypes.h"
      9 #include "GLContext.h"
     10 #include "gfx2DGlue.h"
     11 #include "MozFramebuffer.h"
     12 #include "SharedSurface.h"
     13 #include "mozilla/gfx/BuildConstants.h"
     14 
     15 namespace mozilla::gl {
     16 
     17 // -
     18 // SwapChainPresenter
     19 
     20 UniquePtr<SwapChainPresenter> SwapChain::Acquire(
     21    const gfx::IntSize& size, const gfx::ColorSpace2 colorSpace) {
     22  MOZ_ASSERT(mFactory);
     23 
     24  std::shared_ptr<SharedSurface> surf;
     25  if (!mPool.empty()) {
     26    // Try reuse
     27    const auto& existingDesc = mPool.front()->mDesc;
     28    auto newDesc = existingDesc;
     29    newDesc.size = size;
     30    newDesc.colorSpace = colorSpace;
     31    if (newDesc != existingDesc || !mPool.front()->IsValid()) {
     32      mPool = {};
     33    }
     34  }
     35 
     36  // When pooling is disabled, recycling of SharedSurfaces is managed by the
     37  // owner of the SwapChain by calling StoreRecycledSurface().
     38  if (!mPool.empty() && (!mPoolLimit || mPool.size() >= mPoolLimit)) {
     39    surf = mPool.front();
     40    mPool.pop();
     41  }
     42  if (!surf) {
     43    auto uniquePtrSurf = mFactory->CreateShared(size, colorSpace);
     44    if (!uniquePtrSurf) return nullptr;
     45    surf.reset(uniquePtrSurf.release());
     46  }
     47  if (mPoolLimit > 0) {
     48    mPool.push(surf);
     49    while (mPool.size() > mPoolLimit) {
     50      mPool.pop();
     51    }
     52  }
     53 
     54  auto ret = MakeUnique<SwapChainPresenter>(*this);
     55  const auto old = ret->SwapBackBuffer(surf);
     56  MOZ_ALWAYS_TRUE(!old);
     57  return ret;
     58 }
     59 
     60 void SwapChain::ClearPool() {
     61  mPool = {};
     62  mPrevFrontBuffer = nullptr;
     63 }
     64 
     65 bool SwapChain::StoreRecycledSurface(
     66    const std::shared_ptr<SharedSurface>& surf) {
     67  MOZ_ASSERT(mFactory);
     68  // Don't allow external recycled surfaces if SwapChain is managing own pool.
     69  MOZ_ASSERT(!mPoolLimit);
     70  if (mPoolLimit > 0 || !mFactory ||
     71      NS_WARN_IF(surf->mDesc.gl != mFactory->mDesc.gl)) {
     72    // Ensure we don't accidentally store an expired shared surface or from a
     73    // different context.
     74    return false;
     75  }
     76  mPool.push(surf);
     77  return true;
     78 }
     79 
     80 // -
     81 
     82 SwapChainPresenter::SwapChainPresenter(SwapChain& swapChain)
     83    : mSwapChain(&swapChain) {
     84  MOZ_RELEASE_ASSERT(mSwapChain->mPresenter == nullptr);
     85  mSwapChain->mPresenter = this;
     86 }
     87 
     88 SwapChainPresenter::~SwapChainPresenter() {
     89  if (!mSwapChain) return;
     90  MOZ_RELEASE_ASSERT(mSwapChain->mPresenter == this);
     91  mSwapChain->mPresenter = nullptr;
     92 
     93  auto newFront = SwapBackBuffer(nullptr);
     94  if (newFront) {
     95    mSwapChain->mPrevFrontBuffer = mSwapChain->mFrontBuffer;
     96    mSwapChain->mFrontBuffer = newFront;
     97  }
     98 }
     99 
    100 std::shared_ptr<SharedSurface> SwapChainPresenter::SwapBackBuffer(
    101    std::shared_ptr<SharedSurface> back) {
    102  if (mBackBuffer) {
    103    mBackBuffer->EndWrite();
    104  }
    105  auto old = mBackBuffer;
    106  mBackBuffer = back;
    107  if (mBackBuffer) {
    108    mBackBuffer->BeginWrite();
    109  }
    110  return old;
    111 }
    112 
    113 GLuint SwapChainPresenter::Fb() const {
    114  if (!mBackBuffer) return 0;
    115  const auto& fb = mBackBuffer->mFb;
    116  if (!fb) return 0;
    117  return fb->mFB;
    118 }
    119 
    120 // -
    121 // SwapChain
    122 
    123 SwapChain::SwapChain()
    124    :  // We need to apply pooling on Android because of the AndroidSurface slow
    125       // destructor bugs. They cause a noticeable performance hit. See bug
    126       // #1646073.
    127      mPoolLimit(kIsAndroid ? 4 : 0) {}
    128 
    129 SwapChain::~SwapChain() {
    130  if (mPresenter) {
    131    // Out of order destruction, but ok.
    132    (void)mPresenter->SwapBackBuffer(nullptr);
    133    mPresenter->mSwapChain = nullptr;
    134    mPresenter = nullptr;
    135  }
    136  if (mDestroyedCallback) {
    137    mDestroyedCallback();
    138  }
    139 }
    140 
    141 }  // namespace mozilla::gl