gs-vertexbuffer: Use aligned memory and fix null pointer

This fixes the crash on creation issues, but a crash on exit still happens with the plugin installed. Unsure what exactly is causing it but it looks like something is writing into heap memory.

Related: #9
This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2018-01-08 19:08:49 +01:00
parent 1e2cff48c9
commit cb1ae28b07
2 changed files with 29 additions and 11 deletions

View file

@ -69,7 +69,7 @@ GS::VertexBuffer::VertexBuffer(gs_vertbuffer_t* vb) {
GS::VertexBuffer::VertexBuffer() : VertexBuffer(defaultMaximumVertices) {}
GS::VertexBuffer::VertexBuffer(std::vector<Vertex>& other) : VertexBuffer((uint32_t)other.capacity()) {
GS::VertexBuffer::VertexBuffer(std::vector<Vertex*>& other) : VertexBuffer((uint32_t)other.capacity()) {
std::copy(other.begin(), other.end(), this->end());
}
@ -101,8 +101,19 @@ gs_vertbuffer_t* GS::VertexBuffer::get(bool refreshGPU) {
if (size() > m_maximumVertices)
throw std::runtime_error("Too many vertices in Vertex Buffer.");
// Update data pointer from Graphics Subsystem.
m_vertexbufferdata = gs_vertexbuffer_get_data(m_vertexbuffer);
std::memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
// Resize buffers.
m_data.positions.resize(m_maximumVertices);
m_data.normals.resize(m_maximumVertices);
m_data.tangents.resize(m_maximumVertices);
m_data.colors.resize(m_maximumVertices);
m_data.uvws.resize(m_uvwLayers);
m_data.uvwdata.resize(m_uvwLayers);
// Assign new data.
m_vertexbufferdata->num = m_maximumVertices;
m_vertexbufferdata->points = m_data.positions.data();
m_vertexbufferdata->normals = m_data.normals.data();
@ -110,12 +121,15 @@ gs_vertbuffer_t* GS::VertexBuffer::get(bool refreshGPU) {
m_vertexbufferdata->colors = m_data.colors.data();
m_vertexbufferdata->num_tex = m_uvwLayers;
for (uint32_t n = 0; n < m_uvwLayers; n++) {
m_data.uvws[n].resize(m_maximumVertices);
m_data.uvwdata[n].width = 4;
m_data.uvwdata[n].array = m_data.uvws[n].data();
}
m_vertexbufferdata->tvarray = m_data.uvwdata.data();
// Copy Data
for (size_t vertexIdx = 0; vertexIdx < size(); vertexIdx++) {
Vertex& v = this->at(vertexIdx);
GS::Vertex& v = this->at(vertexIdx);
vec3_copy(&m_data.positions[vertexIdx], &(v.position));
vec3_copy(&m_data.normals[vertexIdx], &(v.normal));
vec3_copy(&m_data.tangents[vertexIdx], &(v.tangent));
@ -124,18 +138,20 @@ gs_vertbuffer_t* GS::VertexBuffer::get(bool refreshGPU) {
}
m_data.colors[vertexIdx] = v.color;
}
m_vertexbufferdata->num = size();
m_vertexbufferdata->num_tex = m_uvwLayers;
// Update GPU
obs_enter_graphics();
gs_vertexbuffer_flush(m_vertexbuffer);
obs_leave_graphics();
// WORKAROUND: OBS Studio 20.x and below incorrectly deletes data that it doesn't own.
std::memset(m_vertexbufferdata, 0, sizeof(gs_vb_data));
m_vertexbufferdata->num = m_maximumVertices;
m_vertexbufferdata->num_tex = m_uvwLayers;
for (uint32_t n = 0; n < m_uvwLayers; n++) {
m_data.uvwdata[n].width = 4;
}
obs_leave_graphics();
}
return m_vertexbuffer;
}

View file

@ -19,6 +19,8 @@
#pragma once
#include "gs-vertex.h"
#include "util-math.h"
#include "util-memory.h"
#include <inttypes.h>
#include <vector>
extern "C" {
@ -29,7 +31,7 @@ extern "C" {
}
namespace GS {
class VertexBuffer : public std::vector<Vertex> {
class VertexBuffer : public std::vector<Vertex, util::AlignmentAllocator<Vertex, 16>> {
public:
/*!
* \brief Create a Vertex Buffer with specific size
@ -59,7 +61,7 @@ namespace GS {
*
* \param other The Vertex array to use
*/
VertexBuffer(std::vector<Vertex>& other);
VertexBuffer(std::vector<Vertex*>& other);
VertexBuffer(gs_vertbuffer_t* vb);
@ -82,11 +84,11 @@ namespace GS {
// Data Storage
struct {
std::vector<vec3> positions;
std::vector<vec3> normals;
std::vector<vec3> tangents;
std::vector<util::vec3a> positions;
std::vector<util::vec3a> normals;
std::vector<util::vec3a> tangents;
std::vector<uint32_t> colors;
std::vector<std::vector<vec4>> uvws;
std::vector<std::vector<util::vec4a>> uvws;
std::vector<gs_tvertarray> uvwdata;
} m_data;
};