LCOV - code coverage report
Current view: top level - source/renderer - VertexBufferManager.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 0 57 0.0 %
Date: 2022-03-08 13:03:03 Functions: 0 9 0.0 %

          Line data    Source code
       1             : /* Copyright (C) 2022 Wildfire Games.
       2             :  * This file is part of 0 A.D.
       3             :  *
       4             :  * 0 A.D. is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * 0 A.D. is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include "precompiled.h"
      19             : 
      20             : #include "VertexBufferManager.h"
      21             : 
      22             : #include "lib/ogl.h"
      23             : #include "ps/CLogger.h"
      24             : 
      25             : #define DUMP_VB_STATS 0 // for debugging
      26             : 
      27             : CVertexBufferManager g_VBMan;
      28             : 
      29           0 : CVertexBufferManager::Handle::Handle(Handle&& other)
      30           0 :     : m_Chunk(other.m_Chunk)
      31             : {
      32           0 :     other.m_Chunk = nullptr;
      33           0 : }
      34             : 
      35           0 : CVertexBufferManager::Handle& CVertexBufferManager::Handle::operator=(Handle&& other)
      36             : {
      37           0 :     if (&other == this)
      38             :         return *this;
      39             : 
      40           0 :     if (IsValid())
      41           0 :         Reset();
      42             : 
      43           0 :     Handle tmp(std::move(other));
      44           0 :     swap(*this, tmp);
      45             : 
      46           0 :     return *this;
      47             : }
      48             : 
      49           0 : CVertexBufferManager::Handle::Handle(CVertexBuffer::VBChunk* chunk)
      50           0 :     : m_Chunk(chunk)
      51             : {
      52           0 : }
      53             : 
      54           0 : void CVertexBufferManager::Handle::Reset()
      55             : {
      56           0 :     if (!IsValid())
      57             :         return;
      58             : 
      59           0 :     g_VBMan.Release(m_Chunk);
      60           0 :     m_Chunk = nullptr;
      61             : }
      62             : 
      63             : // Explicit shutdown of the vertex buffer subsystem.
      64             : // This avoids the ordering issues that arise when using destructors of
      65             : // global instances.
      66           0 : void CVertexBufferManager::Shutdown()
      67             : {
      68           0 :     for (int group = static_cast<int>(Group::DEFAULT); group < static_cast<int>(Group::COUNT); ++group)
      69           0 :         m_Buffers[group].clear();
      70           0 : }
      71             : 
      72             : /**
      73             :  * AllocateChunk: try to allocate a buffer of given number of vertices (each of
      74             :  * given size), with the given type, and using the given texture - return null
      75             :  * if no free chunks available
      76             :  */
      77           0 : CVertexBufferManager::Handle CVertexBufferManager::AllocateChunk(
      78             :     const size_t vertexSize, const size_t numberOfVertices,
      79             :     const Renderer::Backend::GL::CBuffer::Type type,
      80             :     const bool dynamic, void* backingStore, Group group)
      81             : {
      82           0 :     ENSURE(vertexSize > 0);
      83           0 :     ENSURE(numberOfVertices > 0);
      84             : 
      85           0 :     CVertexBuffer::VBChunk* result = nullptr;
      86             : 
      87           0 :     if (CVertexBuffer::UseStreaming(dynamic))
      88           0 :         ENSURE(backingStore != NULL);
      89             : 
      90             :     // TODO, RC - run some sanity checks on allocation request
      91             : 
      92           0 :     std::vector<std::unique_ptr<CVertexBuffer>>& buffers = m_Buffers[static_cast<int>(group)];
      93             : 
      94             : #if DUMP_VB_STATS
      95             :     debug_printf("\n============================\n# allocate vsize=%zu nverts=%zu\n\n", vertexSize, numVertices);
      96             :     for (const std::unique_ptr<CVertexBuffer>& buffer : buffers)
      97             :     {
      98             :         if (buffer->CompatibleVertexType(vertexSize, type, dynamic))
      99             :         {
     100             :             debug_printf("%p\n", buffer.get());
     101             :             buffer->DumpStatus();
     102             :         }
     103             :     }
     104             : #endif
     105             : 
     106             :     // iterate through all existing buffers testing for one that'll
     107             :     // satisfy the allocation
     108           0 :     for (const std::unique_ptr<CVertexBuffer>& buffer : buffers)
     109             :     {
     110           0 :         result = buffer->Allocate(vertexSize, numberOfVertices, type, dynamic, backingStore);
     111           0 :         if (result)
     112           0 :             return Handle(result);
     113             :     }
     114             : 
     115             :     // got this far; need to allocate a new buffer
     116           0 :     buffers.emplace_back(
     117             :         group == Group::DEFAULT
     118           0 :             ? std::make_unique<CVertexBuffer>("VertexBuffer (Default)", vertexSize, type, dynamic)
     119             :             // Reduces the buffer size for not so frequent buffers.
     120           0 :             : std::make_unique<CVertexBuffer>("VertexBuffer", vertexSize, type, dynamic, 1024 * 1024));
     121           0 :     result = buffers.back()->Allocate(vertexSize, numberOfVertices, type, dynamic, backingStore);
     122             : 
     123           0 :     if (!result)
     124             :     {
     125           0 :         LOGERROR("Failed to create VBOs (%zu*%zu)", vertexSize, numberOfVertices);
     126           0 :         return Handle();
     127             :     }
     128             : 
     129           0 :     return Handle(result);
     130             : }
     131             : 
     132           0 : void CVertexBufferManager::Release(CVertexBuffer::VBChunk* chunk)
     133             : {
     134           0 :     ENSURE(chunk);
     135             : #if DUMP_VB_STATS
     136             :     debug_printf("\n============================\n# release %p nverts=%zu\n\n", chunk, chunk->m_Count);
     137             : #endif
     138           0 :     chunk->m_Owner->Release(chunk);
     139           0 : }
     140             : 
     141           0 : size_t CVertexBufferManager::GetBytesReserved() const
     142             : {
     143           0 :     size_t total = 0;
     144           0 :     for (int group = static_cast<int>(Group::DEFAULT); group < static_cast<int>(Group::COUNT); ++group)
     145           0 :         for (const std::unique_ptr<CVertexBuffer>& buffer : m_Buffers[static_cast<int>(group)])
     146           0 :             total += buffer->GetBytesReserved();
     147           0 :     return total;
     148             : }
     149             : 
     150           0 : size_t CVertexBufferManager::GetBytesAllocated() const
     151             : {
     152           0 :     size_t total = 0;
     153           0 :     for (int group = static_cast<int>(Group::DEFAULT); group < static_cast<int>(Group::COUNT); ++group)
     154           0 :         for (const std::unique_ptr<CVertexBuffer>& buffer : m_Buffers[static_cast<int>(group)])
     155           0 :             total += buffer->GetBytesAllocated();
     156           0 :     return total;
     157             : }

Generated by: LCOV version 1.13