00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "mmsgui/fb/mmsfbbuffer.h"
00034 #include "mmsgui/fb/mmsfb.h"
00035
00036
00037
00038 MMSFBBuffer::EXTKEY_INDEX MMSFBBuffer::extkey_index;
00039 MMSFBBuffer::BUFFER_INDEX MMSFBBuffer::buffer_index;
00040
00041 MMSFBBuffer::MMSFBBuffer(unsigned int extkey, unsigned int subkey) {
00042
00043 EXTKEY_INDEX::iterator extkey_it = this->extkey_index.find(extkey);
00044 if (extkey_it == this->extkey_index.end()) {
00045
00046 this->extkey = new EXTKEY(extkey);
00047 this->extkey_index.insert(make_pair(extkey, this->extkey));
00048 }
00049 else {
00050
00051 this->extkey = extkey_it->second;
00052 this->extkey->use_count++;
00053 }
00054
00055
00056 this->ext_id = (((unsigned long long)extkey) << 32) + (unsigned long long)subkey;
00057
00058
00059 BUFFER_INDEX::iterator buffer_it = this->buffer_index.find(this->ext_id);
00060 if (buffer_it == this->buffer_index.end()) {
00061
00062 this->buffer = new BUFFER();
00063 this->buffer_index.insert(make_pair(this->ext_id, this->buffer));
00064 }
00065 else {
00066
00067 this->buffer = buffer_it->second;
00068 this->buffer->use_count++;
00069 }
00070 }
00071
00072 MMSFBBuffer::~MMSFBBuffer() {
00073
00074 BUFFER_INDEX::iterator buffer_it = this->buffer_index.find(this->ext_id);
00075 if (buffer_it != this->buffer_index.end()) {
00076
00077 buffer_it->second->use_count--;
00078 if (buffer_it->second->use_count == 0) {
00079
00080 delete buffer_it->second;
00081 this->buffer_index.erase(buffer_it);
00082 }
00083 }
00084
00085
00086 EXTKEY_INDEX::iterator extkey_it = this->extkey_index.find(this->extkey->key);
00087 if (extkey_it != this->extkey_index.end()) {
00088
00089 extkey_it->second->use_count--;
00090 if (extkey_it->second->use_count == 0) {
00091
00092 delete extkey_it->second;
00093 this->extkey_index.erase(extkey_it);
00094 }
00095 }
00096 }
00097
00098 bool MMSFBBuffer::isInitialized() {
00099 if (!this->buffer) return false;
00100 return this->buffer->initialized;
00101 }
00102
00103 bool MMSFBBuffer::getExtKey(MMSFBBuffer::EXTKEY **extkey) {
00104 if (!isInitialized()) return false;
00105 if (extkey) *extkey = this->extkey;
00106 return true;
00107 }
00108
00109
00110
00111 bool MMSFBBuffer::initBuffer(INDEX_BUFFER index_buffer, VERTEX_BUFFER vertex_buffer) {
00112 if (isInitialized()) return false;
00113 if (this->buffer) {
00114 this->buffer->type = BUFFER_TYPE_INDEX_VERTEX;
00115
00116 this->buffer->initIndexBuffer(this->extkey, index_buffer);
00117
00118 this->extkey->allocVertexArray(256*1024);
00119 this->buffer->initVertexBuffer(this->extkey, vertex_buffer);
00120
00121 this->buffer->initialized = true;
00122 return true;
00123 }
00124 return false;
00125 }
00126
00127 bool MMSFBBuffer::getBuffer(MMSFBBuffer::BUFFER **buffer) {
00128 if (!isInitialized()) return false;
00129 if (buffer) *buffer = this->buffer;
00130 return true;
00131 }
00132
00133
00134
00135 MMSFBBuffer::EXTKEY::EXTKEY(unsigned int key) : initialized(false), use_count(1) {
00136 this->key = key;
00137 #ifdef __HAVE_OPENGL__
00138 this->ibo = 0;
00139 this->ibo_size = 0;
00140 this->ibo_used = 0;
00141 this->vbo = 0;
00142 this->vbo_size = 0;
00143 this->vbo_used = 0;
00144 #endif
00145 }
00146
00147 MMSFBBuffer::EXTKEY::~EXTKEY() {
00148 #ifdef __HAVE_OPENGL__
00149 if (mmsfb->bei) {
00150
00151 if (this->ibo) mmsfb->bei->deleteBuffer(this->ibo);
00152 if (this->vbo) mmsfb->bei->deleteBuffer(this->vbo);
00153 }
00154 #endif
00155 }
00156
00157 bool MMSFBBuffer::EXTKEY::allocVertexArray(unsigned int size) {
00158 #ifdef __HAVE_OPENGL__
00159 if (!this->vbo) {
00160
00161 this->vbo_size = size;
00162 this->vbo_used = 0;
00163 if (mmsfb->bei) {
00164 mmsfb->bei->initVertexBuffer(&this->vbo, this->vbo_size);
00165 if (!this->vbo) {
00166 this->vbo_size = 0;
00167 return false;
00168 }
00169 }
00170 }
00171 #endif
00172
00173 return true;
00174 }
00175
00176
00177 bool MMSFBBuffer::EXTKEY::reserveIndexArray(unsigned int requested_size, unsigned int *offset) {
00178 #ifdef __HAVE_OPENGL__
00179 if (!this->ibo) return false;
00180 if (this->ibo_used + requested_size > this->ibo_size) return false;
00181 *offset = this->ibo_used;
00182 this->ibo_used+= requested_size;
00183 #endif
00184 return true;
00185 }
00186
00187 bool MMSFBBuffer::EXTKEY::reserveVertexArray(unsigned int requested_size, unsigned int *offset) {
00188 #ifdef __HAVE_OPENGL__
00189 if (!this->vbo) return false;
00190 if (this->vbo_used + requested_size > this->vbo_size) return false;
00191 *offset = this->vbo_used;
00192 this->vbo_used+= requested_size;
00193 #endif
00194 return true;
00195 }
00196
00197
00198
00199 MMSFBBuffer::BUFFER::BUFFER() : initialized(false), use_count(1), type(BUFFER_TYPE_NOTSET) {
00200 #ifdef __HAVE_OPENGL__
00201 this->index_bo.bo = 0;
00202 this->index_bo.buffers = NULL;
00203 this->index_bo.num_buffers = 0;
00204 this->vertex_bo.bo = 0;
00205 this->vertex_bo.buffers = NULL;
00206 this->vertex_bo.num_buffers = 0;
00207 #endif
00208 }
00209
00210 MMSFBBuffer::BUFFER::~BUFFER() {
00211 #ifdef __HAVE_OPENGL__
00212 switch (this->type) {
00213 case BUFFER_TYPE_INDEX_VERTEX:
00214 if (this->index_buffer.arrays) {
00215 for (unsigned int i = 0; i < this->index_buffer.num_arrays; i++)
00216 if (this->index_buffer.arrays[i].data) free(this->index_buffer.arrays[i].data);
00217 free(this->index_buffer.arrays);
00218 }
00219 if (this->vertex_buffer.arrays) {
00220 for (unsigned int i = 0; i < this->vertex_buffer.num_arrays; i++)
00221 if (this->vertex_buffer.arrays[i].data) free(this->vertex_buffer.arrays[i].data);
00222 free(this->vertex_buffer.arrays);
00223 }
00224 break;
00225 default:
00226 break;
00227 }
00228
00229 if (this->index_bo.buffers)
00230 free(this->index_bo.buffers);
00231 if (this->vertex_bo.buffers)
00232 free(this->vertex_bo.buffers);
00233 #endif
00234 }
00235
00236 void MMSFBBuffer::BUFFER::initIndexBuffer(EXTKEY *extkey, INDEX_BUFFER index_buffer) {
00237
00238 this->index_buffer = index_buffer;
00239
00240 #ifdef __HAVE_OPENGL__
00241
00242
00243 this->index_bo.num_buffers = this->index_buffer.num_arrays;
00244 if (this->index_bo.num_buffers == 0) {
00245
00246 this->index_bo.bo = 0;
00247 this->index_bo.buffers = NULL;
00248 this->index_bo.num_buffers = 0;
00249 return;
00250 }
00251 this->index_bo.buffers = (MMS_INDEX_BUFFER *)malloc(sizeof(MMS_INDEX_BUFFER) * this->index_bo.num_buffers);
00252 if (!this->index_bo.buffers) {
00253
00254 this->index_bo.bo = 0;
00255 this->index_bo.buffers = NULL;
00256 this->index_bo.num_buffers = 0;
00257 return;
00258 }
00259 this->index_bo.bo = extkey->ibo;
00260
00261
00262 unsigned int size = 0;
00263 for (unsigned int i = 0; i < this->index_bo.num_buffers; i++) {
00264 MMS_INDEX_ARRAY *array = &this->index_buffer.arrays[i];
00265 this->index_bo.buffers[i].bo = 0;
00266 this->index_bo.buffers[i].offs = size;
00267 this->index_bo.buffers[i].type = array->type;
00268 this->index_bo.buffers[i].eNum = array->eNum;
00269 size+= sizeof(unsigned int) * array->eNum;
00270 }
00271
00272 if (!this->index_bo.bo && size) {
00273
00274 free(this->index_bo.buffers);
00275 this->index_bo.bo = 0;
00276 this->index_bo.buffers = NULL;
00277 this->index_bo.num_buffers = 0;
00278 return;
00279 }
00280
00281 if (size) {
00282
00283 unsigned int ibo_offset = 0;
00284 if (extkey->reserveIndexArray(size, &ibo_offset)) {
00285
00286 for (unsigned int i = 0; i < this->index_bo.num_buffers; i++) {
00287 MMS_INDEX_ARRAY *array = &this->index_buffer.arrays[i];
00288
00289 this->index_bo.buffers[i].bo = this->index_bo.bo;
00290 this->index_bo.buffers[i].offs+= ibo_offset;
00291
00292 unsigned int size = sizeof(unsigned int) * array->eNum;
00293
00294 if (mmsfb->bei)
00295 mmsfb->bei->initIndexSubBuffer(this->index_bo.buffers[i].bo, this->index_bo.buffers[i].offs, size, array->data);
00296 }
00297 }
00298 }
00299 #endif
00300 }
00301
00302 void MMSFBBuffer::BUFFER::initVertexBuffer(EXTKEY *extkey, VERTEX_BUFFER vertex_buffer) {
00303
00304 this->vertex_buffer = vertex_buffer;
00305
00306 #ifdef __HAVE_OPENGL__
00307
00308
00309 this->vertex_bo.num_buffers = this->vertex_buffer.num_arrays;
00310 if (this->vertex_bo.num_buffers == 0) {
00311
00312 this->vertex_bo.bo = 0;
00313 this->vertex_bo.buffers = NULL;
00314 this->vertex_bo.num_buffers = 0;
00315 return;
00316 }
00317 this->vertex_bo.buffers = (MMS_VERTEX_BUFFER *)malloc(sizeof(MMS_VERTEX_BUFFER) * this->vertex_bo.num_buffers);
00318 if (!this->vertex_bo.buffers) {
00319
00320 this->vertex_bo.bo = 0;
00321 this->vertex_bo.buffers = NULL;
00322 this->vertex_bo.num_buffers = 0;
00323 return;
00324 }
00325 this->vertex_bo.bo = extkey->vbo;
00326
00327
00328 unsigned int size = 0;
00329 for (unsigned int i = 0; i < this->vertex_bo.num_buffers; i++) {
00330 MMS_VERTEX_ARRAY *array = &this->vertex_buffer.arrays[i];
00331 this->vertex_bo.buffers[i].dtype = array->dtype;
00332 this->vertex_bo.buffers[i].bo = 0;
00333 this->vertex_bo.buffers[i].offs = size;
00334 this->vertex_bo.buffers[i].eSize = array->eSize;
00335 this->vertex_bo.buffers[i].eNum = array->eNum;
00336
00337 switch (this->vertex_bo.buffers[i].dtype) {
00338 case MMS_VERTEX_DATA_TYPE_HALF_FLOAT:
00339 size+= sizeof(MMS_HALF_FLOAT) * array->eSize * array->eNum;
00340 break;
00341 default:
00342 size+= sizeof(float) * array->eSize * array->eNum;
00343 break;
00344 }
00345 }
00346
00347 if (!this->vertex_bo.bo && size) {
00348
00349 free(this->vertex_bo.buffers);
00350 this->vertex_bo.bo = 0;
00351 this->vertex_bo.buffers = NULL;
00352 this->vertex_bo.num_buffers = 0;
00353 return;
00354 }
00355
00356 if (size) {
00357
00358 unsigned int vbo_offset = 0;
00359 if (extkey->reserveVertexArray(size, &vbo_offset)) {
00360
00361 for (unsigned int i = 0; i < this->vertex_bo.num_buffers; i++) {
00362 MMS_VERTEX_ARRAY *array = &this->vertex_buffer.arrays[i];
00363
00364 this->vertex_bo.buffers[i].bo = this->vertex_bo.bo;
00365 this->vertex_bo.buffers[i].offs+= vbo_offset;
00366
00367 unsigned int size;
00368 switch (this->vertex_bo.buffers[i].dtype) {
00369 case MMS_VERTEX_DATA_TYPE_HALF_FLOAT:
00370 size = sizeof(MMS_HALF_FLOAT) * array->eSize * array->eNum;
00371 break;
00372 default:
00373 size = sizeof(float) * array->eSize * array->eNum;
00374 break;
00375 }
00376
00377 if (mmsfb->bei)
00378 mmsfb->bei->initVertexSubBuffer(this->vertex_bo.buffers[i].bo, this->vertex_bo.buffers[i].offs, size, array->data);
00379 }
00380 }
00381 }
00382 #endif
00383 }
00384
00385 bool MMSFBBuffer::BUFFER::getBuffers(MMSFBBuffer::INDEX_BUFFER **index_buffer, MMSFBBuffer::VERTEX_BUFFER **vertex_buffer) {
00386 if (this->type != BUFFER_TYPE_INDEX_VERTEX) return false;
00387 if (index_buffer) *index_buffer = &this->index_buffer;
00388 if (vertex_buffer) *vertex_buffer = &this->vertex_buffer;
00389 return true;
00390 }
00391
00392 #ifdef __HAVE_OPENGL__
00393 bool MMSFBBuffer::BUFFER::getBufferObjects(MMSFBBuffer::INDEX_BUFFER_OBJECT **index_bo, MMSFBBuffer::VERTEX_BUFFER_OBJECT **vertex_bo) {
00394 if (this->type != BUFFER_TYPE_INDEX_VERTEX) return false;
00395 if (index_bo) *index_bo = &this->index_bo;
00396 if (vertex_bo) *vertex_bo = &this->vertex_bo;
00397 return true;
00398 }
00399 #endif
00400
00401
00402
00403
00404