LCOV - code coverage report
Current view: top level - source/renderer - VertexBuffer.h (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 0 3 0.0 %
Date: 2022-03-08 13:03:03 Functions: 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             : /*
      19             :  * encapsulation of VBOs with batching and sharing
      20             :  */
      21             : 
      22             : #ifndef INCLUDED_VERTEXBUFFER
      23             : #define INCLUDED_VERTEXBUFFER
      24             : 
      25             : #include "renderer/backend/gl/Buffer.h"
      26             : #include "renderer/backend/gl/DeviceCommandContext.h"
      27             : 
      28             : #include <memory>
      29             : #include <vector>
      30             : 
      31             : /**
      32             :  * CVertexBuffer: encapsulation of ARB_vertex_buffer_object, also supplying
      33             :  * some additional functionality for sharing buffers between multiple objects.
      34             :  *
      35             :  * The class can be used in two modes, depending on the usage parameter:
      36             :  *
      37             :  * GL_STATIC_DRAW: Call Allocate() with backingStore = NULL. Then call
      38             :  * UpdateChunkVertices() with any pointer - the data will be immediately copied
      39             :  * to the VBO. This should be used for vertex data that rarely changes.
      40             :  *
      41             :  * GL_DYNAMIC_DRAW, GL_STREAM_DRAW: Call Allocate() with backingStore pointing
      42             :  * at some memory that will remain valid for the lifetime of the CVertexBuffer.
      43             :  * This should be used for vertex data that may change every frame.
      44             :  * Rendering is expected to occur in two phases:
      45             :  *   - "Prepare" phase:
      46             :  *       If this chunk is going to be used for rendering during the next Bind phase,
      47             :  *       you must call PrepareForRendering().
      48             :  *       If the vertex data in backingStore has been modified since the last Bind phase,
      49             :  *       you must call UpdateChunkVertices().
      50             :  *   - "Bind" phase:
      51             :  *       Bind() can be called (multiple times). The vertex data will be uploaded
      52             :  *       to the GPU if necessary.
      53             :  * It is okay to have multiple prepare/bind cycles per frame (though slightly less
      54             :  * efficient), but they must occur sequentially.
      55             :  */
      56             : class CVertexBuffer
      57             : {
      58             :     NONCOPYABLE(CVertexBuffer);
      59             : 
      60             : public:
      61             : 
      62             :     /// VBChunk: describes a portion of this vertex buffer
      63             :     struct VBChunk
      64             :     {
      65             :         /// Owning (parent) vertex buffer
      66             :         CVertexBuffer* m_Owner;
      67             :         /// Start index of this chunk in owner
      68             :         size_t m_Index;
      69             :         /// Number of vertices used by chunk
      70             :         size_t m_Count;
      71             :         /// If UseStreaming() is true, points at the data for this chunk
      72             :         void* m_BackingStore;
      73             : 
      74             :         /// If true, the VBO is not consistent with the chunk's backing store
      75             :         /// (and will need to be re-uploaded before rendering with this chunk)
      76             :         bool m_Dirty;
      77             : 
      78             :         /// If true, we have been told this chunk is going to be used for
      79             :         /// rendering in the next bind phase and will need to be uploaded
      80             :         bool m_Needed;
      81             : 
      82             :     private:
      83             :         // Only CVertexBuffer can construct/delete these
      84             :         // (Other people should use g_VBMan.Allocate, g_VBMan.Release)
      85             :         friend class CVertexBuffer;
      86           0 :         VBChunk() {}
      87           0 :         ~VBChunk() {}
      88             :     };
      89             : 
      90             : public:
      91             :     // constructor, destructor
      92             :     CVertexBuffer(
      93             :         const char* name, const size_t vertexSize,
      94             :         const Renderer::Backend::GL::CBuffer::Type type, const bool dynamic);
      95             :     CVertexBuffer(
      96             :         const char* name, const size_t vertexSize,
      97             :         const Renderer::Backend::GL::CBuffer::Type type, const bool dynamic,
      98             :         const size_t maximumBufferSize);
      99             :     ~CVertexBuffer();
     100             : 
     101             :     /// Bind to this buffer; return pointer to address required as parameter
     102             :     /// to glVertexPointer ( + etc) calls
     103             :     u8* Bind(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
     104             : 
     105             :     void UploadIfNeeded(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
     106             : 
     107             :     /// Unbind any currently-bound buffer, so glVertexPointer etc calls will not attempt to use it
     108             :     static void Unbind(
     109             :         Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
     110             : 
     111             :     /// Make the vertex data available for the next call to Bind()
     112             :     void PrepareForRendering(VBChunk* chunk);
     113             : 
     114             :     /// Update vertex data for given chunk. Transfers the provided data to the actual OpenGL vertex buffer.
     115             :     void UpdateChunkVertices(VBChunk* chunk, void* data);
     116             : 
     117             :     size_t GetVertexSize() const { return m_VertexSize; }
     118             :     size_t GetBytesReserved() const;
     119             :     size_t GetBytesAllocated() const;
     120             : 
     121             :     /// Returns true if this vertex buffer is compatible with the specified vertex type and intended usage.
     122             :     bool CompatibleVertexType(
     123             :         const size_t vertexSize, const Renderer::Backend::GL::CBuffer::Type type,
     124             :         const bool dynamic) const;
     125             : 
     126             :     void DumpStatus() const;
     127             : 
     128             :     /**
     129             :      * Given the usage flags of a buffer that has been (or will be) allocated:
     130             :      *
     131             :      * If true, we assume the buffer is going to be modified on every frame,
     132             :      * so we will re-upload the entire buffer every frame using glMapBuffer.
     133             :      * This requires the buffer's owner to hold onto its backing store.
     134             :      *
     135             :      * If false, we assume it will change rarely, and use direct upload to
     136             :      * update it incrementally. The backing store can be freed to save memory.
     137             :      */
     138             :     static bool UseStreaming(const bool dynamic);
     139             : 
     140           0 :     Renderer::Backend::GL::CBuffer* GetBuffer() { return m_Buffer.get(); }
     141             : 
     142             : private:
     143             :     friend class CVertexBufferManager;      // allow allocate only via CVertexBufferManager
     144             : 
     145             :     /// Try to allocate a buffer of given number of vertices (each of given size),
     146             :     /// and with the given type - return null if no free chunks available
     147             :     VBChunk* Allocate(
     148             :         const size_t vertexSize, const size_t numberOfVertices,
     149             :         const Renderer::Backend::GL::CBuffer::Type type, const bool dynamic,
     150             :         void* backingStore);
     151             :     /// Return given chunk to this buffer
     152             :     void Release(VBChunk* chunk);
     153             : 
     154             :     /// Vertex size of this vertex buffer
     155             :     size_t m_VertexSize;
     156             :     /// Number of vertices of above size in this buffer
     157             :     size_t m_MaxVertices;
     158             :     /// List of free chunks in this buffer
     159             :     std::vector<VBChunk*> m_FreeList;
     160             :     /// List of allocated chunks
     161             :     std::vector<VBChunk*> m_AllocList;
     162             :     /// Available free vertices - total of all free vertices in the free list
     163             :     size_t m_FreeVertices;
     164             : 
     165             :     std::unique_ptr<Renderer::Backend::GL::CBuffer> m_Buffer;
     166             : 
     167             :     bool m_HasNeededChunks;
     168             : };
     169             : 
     170             : #endif // INCLUDED_VERTEXBUFFER

Generated by: LCOV version 1.13