LCOV - code coverage report
Current view: top level - gfx/layers/mlgpu - SharedBufferMLGPU.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 87 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       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 "SharedBufferMLGPU.h"
       7             : #include "BufferCache.h"
       8             : #include "MLGDevice.h"
       9             : 
      10             : using namespace std;
      11             : 
      12             : namespace mozilla {
      13             : namespace layers {
      14             : 
      15           0 : SharedBufferMLGPU::SharedBufferMLGPU(MLGDevice* aDevice, MLGBufferType aType, size_t aDefaultSize)
      16             :  : mDevice(aDevice),
      17             :    mType(aType),
      18             :    mDefaultSize(aDefaultSize),
      19             :    mCanUseOffsetAllocation(true),
      20             :    mCurrentPosition(0),
      21             :    mMaxSize(0),
      22             :    mMapped(false),
      23             :    mBytesUsedThisFrame(0),
      24           0 :    mNumSmallFrames(0)
      25             : {
      26           0 :   MOZ_COUNT_CTOR(SharedBufferMLGPU);
      27           0 : }
      28             : 
      29           0 : SharedBufferMLGPU::~SharedBufferMLGPU()
      30             : {
      31           0 :   MOZ_COUNT_DTOR(SharedBufferMLGPU);
      32           0 :   Unmap();
      33           0 : }
      34             : 
      35             : bool
      36           0 : SharedBufferMLGPU::Init()
      37             : {
      38             :   // If we can't use buffer offset binding, we never allocated shared buffers.
      39           0 :   if (!mCanUseOffsetAllocation) {
      40           0 :     return true;
      41             :   }
      42             : 
      43             :   // If we can use offset binding, allocate an initial shared buffer now.
      44           0 :   if (!GrowBuffer(mDefaultSize)) {
      45           0 :     return false;
      46             :   }
      47           0 :   return true;
      48             : }
      49             : 
      50             : void
      51           0 : SharedBufferMLGPU::Reset()
      52             : {
      53             :   // We shouldn't be mapped here, but just in case, unmap now.
      54           0 :   Unmap();
      55           0 :   mBytesUsedThisFrame = 0;
      56             : 
      57             :   // If we allocated a large buffer for a particularly heavy layer tree,
      58             :   // but have not used most of the buffer again for many frames, we
      59             :   // discard the buffer. This is to prevent having to perform large
      60             :   // pointless uploads after visiting a single havy page - it also
      61             :   // lessens ping-ponging between large and small buffers.
      62           0 :   if (mBuffer &&
      63           0 :       (mBuffer->GetSize() > mDefaultSize * 4) &&
      64           0 :       mNumSmallFrames >= 10)
      65             :   {
      66           0 :     mBuffer = nullptr;
      67             :   }
      68             : 
      69             :   // Note that we do not aggressively map a new buffer. There's no reason to,
      70             :   // and it'd cause unnecessary uploads when painting empty frames.
      71           0 : }
      72             : 
      73             : bool
      74           0 : SharedBufferMLGPU::EnsureMappedBuffer(size_t aBytes)
      75             : {
      76           0 :   if (!mBuffer || (mMaxSize - mCurrentPosition < aBytes)) {
      77           0 :     if (!GrowBuffer(aBytes)) {
      78           0 :       return false;
      79             :     }
      80             :   }
      81           0 :   if (!mMapped && !Map()) {
      82           0 :     return false;
      83             :   }
      84           0 :   return true;
      85             : }
      86             : 
      87             : // We don't want to cache large buffers, since it results in larger uploads
      88             : // that might not be needed.
      89             : static const size_t kMaxCachedBufferSize = 128 * 1024;
      90             : 
      91             : bool
      92           0 : SharedBufferMLGPU::GrowBuffer(size_t aBytes)
      93             : {
      94             :   // We only pre-allocate buffers if we can use offset allocation.
      95           0 :   MOZ_ASSERT(mCanUseOffsetAllocation);
      96             : 
      97             :   // Unmap the previous buffer. This will retain mBuffer, but free up the
      98             :   // address space used by its mapping.
      99           0 :   Unmap();
     100             : 
     101           0 :   size_t maybeSize = mDefaultSize;
     102           0 :   if (mBuffer) {
     103             :     // Try to first grow the previous allocation size.
     104           0 :     maybeSize = std::min(kMaxCachedBufferSize, mBuffer->GetSize() * 2);
     105             :   }
     106             : 
     107           0 :   size_t bytes = std::max(aBytes, maybeSize);
     108           0 :   mBuffer = mDevice->CreateBuffer(mType, bytes, MLGUsage::Dynamic);
     109           0 :   if (!mBuffer) {
     110           0 :     return false;
     111             :   }
     112             : 
     113           0 :   mCurrentPosition = 0;
     114           0 :   mMaxSize = mBuffer->GetSize();
     115           0 :   return true;
     116             : }
     117             : 
     118             : void
     119           0 : SharedBufferMLGPU::PrepareForUsage()
     120             : {
     121           0 :   Unmap();
     122             : 
     123           0 :   if (mBytesUsedThisFrame <= mDefaultSize) {
     124           0 :     mNumSmallFrames++;
     125             :   } else {
     126           0 :     mNumSmallFrames = 0;
     127             :   }
     128           0 : }
     129             : 
     130             : bool
     131           0 : SharedBufferMLGPU::Map()
     132             : {
     133           0 :   MOZ_ASSERT(mBuffer);
     134           0 :   MOZ_ASSERT(!mMapped);
     135             : 
     136           0 :   if (!mDevice->Map(mBuffer, MLGMapType::WRITE_DISCARD, &mMap)) {
     137             :     // Don't retain the buffer, it's useless if we can't map it.
     138           0 :     mBuffer = nullptr;
     139           0 :     return false;
     140             :   }
     141             : 
     142           0 :   mCurrentPosition = 0;
     143           0 :   mMapped = true;
     144           0 :   return true;
     145             : }
     146             : 
     147             : void
     148           0 : SharedBufferMLGPU::Unmap()
     149             : {
     150           0 :   if (!mMapped) {
     151           0 :     return;
     152             :   }
     153             : 
     154           0 :   mBytesUsedThisFrame += mCurrentPosition;
     155             : 
     156           0 :   mDevice->Unmap(mBuffer);
     157           0 :   mMap = MLGMappedResource();
     158           0 :   mMapped = false;
     159             : }
     160             : 
     161           0 : SharedVertexBuffer::SharedVertexBuffer(MLGDevice* aDevice, size_t aDefaultSize)
     162           0 :  : SharedBufferMLGPU(aDevice, MLGBufferType::Vertex, aDefaultSize)
     163             : {
     164           0 : }
     165             : 
     166           0 : SharedConstantBuffer::SharedConstantBuffer(MLGDevice* aDevice, size_t aDefaultSize)
     167           0 :  : SharedBufferMLGPU(aDevice, MLGBufferType::Constant, aDefaultSize)
     168             : {
     169           0 :   mMaxConstantBufferBindSize = aDevice->GetMaxConstantBufferBindSize();
     170           0 :   mCanUseOffsetAllocation = aDevice->CanUseConstantBufferOffsetBinding();
     171           0 : }
     172             : 
     173             : uint8_t*
     174           0 : SharedConstantBuffer::AllocateNewBuffer(size_t aBytes, ptrdiff_t* aOutOffset, RefPtr<MLGBuffer>* aOutBuffer)
     175             : {
     176           0 :   RefPtr<MLGBuffer> buffer;
     177           0 :   if (BufferCache* cache = mDevice->GetConstantBufferCache()) {
     178           0 :     buffer = cache->GetOrCreateBuffer(aBytes);
     179             :   } else {
     180           0 :     buffer = mDevice->CreateBuffer(MLGBufferType::Constant, aBytes, MLGUsage::Dynamic);
     181             :   }
     182           0 :   if (!buffer) {
     183           0 :     return nullptr;
     184             :   }
     185             : 
     186             :   MLGMappedResource map;
     187           0 :   if (!mDevice->Map(buffer, MLGMapType::WRITE_DISCARD, &map)) {
     188           0 :     return nullptr;
     189             :   }
     190             : 
     191             :   // Signal that offsetting is not supported.
     192           0 :   *aOutOffset = -1;
     193           0 :   *aOutBuffer = buffer;
     194           0 :   return reinterpret_cast<uint8_t*>(map.mData);
     195             : }
     196             : 
     197             : void
     198           0 : AutoBufferUploadBase::UnmapBuffer()
     199             : {
     200           0 :   mDevice->Unmap(mBuffer);
     201           0 : }
     202             : 
     203             : } // namespace layers
     204             : } // namespace mozilla

Generated by: LCOV version 1.13