]> git.tdb.fi Git - gldbg.git/blob - flavors/gl/source/bufferstate.cpp
Fix several problems reported by valgrind
[gldbg.git] / flavors / gl / source / bufferstate.cpp
1 #include "arraysize.h"
2 #include "arraystate.h"
3 #include "bufferstate.h"
4 #include "enums.h"
5 #include "strformat.h"
6
7 using namespace std;
8
9 BufferContent::BufferContent():
10         consistent(true),
11         stride(0)
12 { }
13
14 void BufferContent::update(const ArrayState &array)
15 {
16         if(array.stride!=stride)
17                 consistent = false;
18
19         stride = array.stride;
20
21         for(vector<Array>::iterator i=arrays.begin(); i!=arrays.end(); ++i)
22                 if(i->kind==array.kind && i->index==array.index)
23                 {
24                         if(array.size!=i->size || array.type!=i->type || array.pointer!=i->offset)
25                         {
26                                 consistent = false;
27                                 arrays.erase(i);
28                         }
29                         else
30                                 return;
31
32
33                         break;
34                 }
35
36         vector<Array>::iterator place = arrays.end();
37         for(vector<Array>::iterator i=arrays.begin(); i!=arrays.end(); ++i)
38                 if(i->offset>array.pointer)
39                 {
40                         place = i;
41                         break;
42                 }
43
44         arrays.insert(place, array);
45 }
46
47 void BufferContent::update_elements(GLenum type)
48 {
49         if(arrays.empty())
50         {
51                 Array array;
52                 array.kind = GL_ELEMENT_ARRAY_BUFFER;
53                 array.type = type;
54                 arrays.push_back(array);
55                 stride = typesize(type);
56         }
57         else if(arrays.size()>1 || arrays.front().kind!=GL_ELEMENT_ARRAY_BUFFER)
58                 consistent = false;
59         else
60         {
61                 if(arrays.front().type!=type)
62                         consistent = false;
63                 arrays.front().type = type;
64                 stride = typesize(type);
65         }
66 }
67
68 string BufferContent::describe() const
69 {
70         if(arrays.empty())
71                 return "(unknown)";
72
73         string result;
74         for(vector<Array>::const_iterator i=arrays.begin(); i!=arrays.end(); ++i)
75         {
76                 char kind = '?';
77                 if(i->kind==GL_VERTEX_ARRAY)
78                         kind = 'V';
79                 else if(i->kind==GL_NORMAL_ARRAY)
80                         kind = 'N';
81                 else if(i->kind==GL_COLOR_ARRAY)
82                         kind = 'C';
83                 else if(i->kind==GL_TEXTURE_COORD_ARRAY && i->index==0)
84                         kind = 'T';
85                 else if(i->kind==GL_ELEMENT_ARRAY_BUFFER)
86                         kind = 'E';
87
88                 char type[3] = { '?', 0, 0 };
89                 if(i->type==GL_FLOAT)
90                         type[0] = 'F';
91                 else if(i->type==GL_DOUBLE)
92                         type[0] = 'D';
93                 else if(i->type==GL_INT || i->type==GL_UNSIGNED_INT)
94                         type[0] = 'I';
95                 else if(i->type==GL_SHORT || i->type==GL_UNSIGNED_SHORT)
96                         type[0] = 'S';
97                 else if(i->type==GL_BYTE || i->type==GL_UNSIGNED_BYTE)
98                         type[0] = 'B';
99
100                 if(i->type==GL_UNSIGNED_INT || i->type==GL_UNSIGNED_SHORT || i->type==GL_UNSIGNED_BYTE)
101                 {
102                         type[1] = type[0];
103                         type[0] = 'U';
104                 }
105
106                 if(!result.empty())
107                         result += '_';
108                 result += strformat("%c%d%s", kind, i->size, type);
109         }
110
111         return result;
112 }
113
114
115 BufferContent::Array::Array():
116         kind(GL_NONE),
117         index(0),
118         size(1),
119         type(GL_NONE),
120         offset(0)
121 { }
122
123 BufferContent::Array::Array(const ArrayState &a):
124         kind(a.kind),
125         index(a.index),
126         size(a.size),
127         type(a.type),
128         offset(a.pointer)
129 { }
130
131
132 BufferState::BufferState():
133         id(0),
134         target(0),
135         usage(GL_STATIC_DRAW),
136         size(0),
137         data(0)
138 { }
139
140 BufferState::~BufferState()
141 {
142         delete[] data;
143 }
144
145 void BufferState::set_data(unsigned sz, const void *ptr, GLenum use)
146 {
147         usage = use;
148         size = sz;
149         delete[] data;
150         data = new char[size];
151         if(ptr)
152                 set_sub_data(0, size, ptr);
153         content = BufferContent();
154 }
155
156 void BufferState::set_sub_data(unsigned off, unsigned sz, const void *ptr)
157 {
158         if(data && off+sz<=size)
159         {
160                 const char *cptr = reinterpret_cast<const char *>(ptr);
161                 copy(cptr, cptr+sz, data+off);
162         }
163 }
164
165 string BufferState::describe() const
166 {
167         if(content.stride)
168         {
169                 const char *what = (content.arrays.front().kind==GL_ELEMENT_ARRAY_BUFFER ? "indices" : "vertices");
170                 return content.describe()+strformat(", %d %s (%d bytes), %s",
171                         size/content.stride, what, size, describe_enum(usage, ""));
172         }
173         else
174                 return strformat("%d bytes, %s", size, describe_enum(usage, ""));
175 }
176
177
178 BufferBindingState::BufferBindingState():
179         buffer(0),
180         offset(0),
181         size(0)
182 { }