1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2016 by Mike Erwin.
* All rights reserved.
*/
/** \file
* \ingroup gpu
*/
#include "gl_context.hh"
#include "gl_vertex_buffer.hh"
namespace blender::gpu {
void GLVertBuf::acquire_data()
{
/* Discard previous data if any. */
MEM_SAFE_FREE(data);
data = (uchar *)MEM_mallocN(sizeof(uchar) * this->size_alloc_get(), __func__);
}
void GLVertBuf::resize_data()
{
data = (uchar *)MEM_reallocN(data, sizeof(uchar) * this->size_alloc_get());
}
void GLVertBuf::release_data()
{
if (vbo_id_ != 0) {
GLContext::buf_free(vbo_id_);
vbo_id_ = 0;
memory_usage -= vbo_size_;
}
MEM_SAFE_FREE(data);
}
void GLVertBuf::duplicate_data(VertBuf *dst_)
{
BLI_assert(GLContext::get() != nullptr);
GLVertBuf *src = this;
GLVertBuf *dst = static_cast<GLVertBuf *>(dst_);
if (src->vbo_id_ != 0) {
dst->vbo_size_ = src->size_used_get();
glGenBuffers(1, &dst->vbo_id_);
glBindBuffer(GL_COPY_WRITE_BUFFER, dst->vbo_id_);
glBufferData(GL_COPY_WRITE_BUFFER, dst->vbo_size_, nullptr, to_gl(dst->usage_));
glBindBuffer(GL_COPY_READ_BUFFER, src->vbo_id_);
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, dst->vbo_size_);
memory_usage += dst->vbo_size_;
}
if (data != nullptr) {
dst->data = (uchar *)MEM_dupallocN(src->data);
}
}
void GLVertBuf::upload_data()
{
this->bind();
}
void GLVertBuf::bind()
{
BLI_assert(GLContext::get() != nullptr);
if (vbo_id_ == 0) {
glGenBuffers(1, &vbo_id_);
}
glBindBuffer(GL_ARRAY_BUFFER, vbo_id_);
if (flag & GPU_VERTBUF_DATA_DIRTY) {
vbo_size_ = this->size_used_get();
/* Orphan the vbo to avoid sync then upload data. */
glBufferData(GL_ARRAY_BUFFER, vbo_size_, nullptr, to_gl(usage_));
glBufferSubData(GL_ARRAY_BUFFER, 0, vbo_size_, data);
memory_usage += vbo_size_;
if (usage_ == GPU_USAGE_STATIC) {
MEM_SAFE_FREE(data);
}
flag &= ~GPU_VERTBUF_DATA_DIRTY;
flag |= GPU_VERTBUF_DATA_UPLOADED;
}
}
void GLVertBuf::update_sub(uint start, uint len, void *data)
{
glBufferSubData(GL_ARRAY_BUFFER, start, len, data);
}
} // namespace blender::gpu
|