cleanup: style/indentation
[blender.git] / source / blender / gpu / intern / gpu_buffers.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program 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 this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Brecht Van Lommel.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/gpu/intern/gpu_buffers.c
29  *  \ingroup gpu
30  *
31  * Mesh drawing using OpenGL VBO (Vertex Buffer Objects),
32  * with fall-back to vertex arrays.
33  */
34
35 #include <limits.h>
36 #include <stddef.h>
37 #include <string.h>
38
39 #include "GPU_glew.h"
40
41 #include "MEM_guardedalloc.h"
42
43 #include "BLI_bitmap.h"
44 #include "BLI_math.h"
45 #include "BLI_utildefines.h"
46 #include "BLI_ghash.h"
47 #include "BLI_threads.h"
48
49 #include "DNA_meshdata_types.h"
50
51 #include "BKE_ccg.h"
52 #include "BKE_DerivedMesh.h"
53 #include "BKE_paint.h"
54 #include "BKE_pbvh.h"
55
56 #include "DNA_userdef_types.h"
57
58 #include "GPU_buffers.h"
59 #include "GPU_draw.h"
60
61 #include "bmesh.h"
62
63 typedef enum {
64         GPU_BUFFER_VERTEX_STATE = (1 << 0),
65         GPU_BUFFER_NORMAL_STATE = (1 << 1),
66         GPU_BUFFER_TEXCOORD_UNIT_0_STATE = (1 << 2),
67         GPU_BUFFER_TEXCOORD_UNIT_2_STATE = (1 << 3),
68         GPU_BUFFER_COLOR_STATE = (1 << 4),
69         GPU_BUFFER_ELEMENT_STATE = (1 << 5),
70 } GPUBufferState;
71
72 #define MAX_GPU_ATTRIB_DATA 32
73
74 #define BUFFER_OFFSET(n) ((GLubyte *)NULL + (n))
75
76 /* -1 - undefined, 0 - vertex arrays, 1 - VBOs */
77 static GPUBufferState GLStates = 0;
78 static GPUAttrib attribData[MAX_GPU_ATTRIB_DATA] = { { -1, 0, 0 } };
79
80 static ThreadMutex buffer_mutex = BLI_MUTEX_INITIALIZER;
81
82 /* stores recently-deleted buffers so that new buffers won't have to
83  * be recreated as often
84  *
85  * only one instance of this pool is created, stored in
86  * gpu_buffer_pool
87  *
88  * note that the number of buffers in the pool is usually limited to
89  * MAX_FREE_GPU_BUFFERS, but this limit may be exceeded temporarily
90  * when a GPUBuffer is released outside the main thread; due to OpenGL
91  * restrictions it cannot be immediately released
92  */
93 typedef struct GPUBufferPool {
94         /* number of allocated buffers stored */
95         int totbuf;
96         int totpbvhbufids;
97         /* actual allocated length of the arrays */
98         int maxsize;
99         int maxpbvhsize;
100         GPUBuffer **buffers;
101         GLuint *pbvhbufids;
102 } GPUBufferPool;
103 #define MAX_FREE_GPU_BUFFERS 8
104 #define MAX_FREE_GPU_BUFF_IDS 100
105
106 /* create a new GPUBufferPool */
107 static GPUBufferPool *gpu_buffer_pool_new(void)
108 {
109         GPUBufferPool *pool;
110
111         pool = MEM_callocN(sizeof(GPUBufferPool), "GPUBuffer_Pool");
112
113         pool->maxsize = MAX_FREE_GPU_BUFFERS;
114         pool->maxpbvhsize = MAX_FREE_GPU_BUFF_IDS;
115         pool->buffers = MEM_mallocN(sizeof(*pool->buffers) * pool->maxsize,
116                                     "GPUBufferPool.buffers");
117         pool->pbvhbufids = MEM_mallocN(sizeof(*pool->pbvhbufids) * pool->maxpbvhsize,
118                                        "GPUBufferPool.pbvhbuffers");
119         return pool;
120 }
121
122 /* remove a GPUBuffer from the pool (does not free the GPUBuffer) */
123 static void gpu_buffer_pool_remove_index(GPUBufferPool *pool, int index)
124 {
125         int i;
126
127         if (!pool || index < 0 || index >= pool->totbuf)
128                 return;
129
130         /* shift entries down, overwriting the buffer at `index' */
131         for (i = index; i < pool->totbuf - 1; i++)
132                 pool->buffers[i] = pool->buffers[i + 1];
133
134         /* clear the last entry */
135         if (pool->totbuf > 0)
136                 pool->buffers[pool->totbuf - 1] = NULL;
137
138         pool->totbuf--;
139 }
140
141 /* delete the last entry in the pool */
142 static void gpu_buffer_pool_delete_last(GPUBufferPool *pool)
143 {
144         GPUBuffer *last;
145
146         if (pool->totbuf <= 0)
147                 return;
148
149         /* get the last entry */
150         if (!(last = pool->buffers[pool->totbuf - 1]))
151                 return;
152
153         /* delete the buffer's data */
154         if (last->use_vbo)
155                 glDeleteBuffersARB(1, &last->id);
156         else
157                 MEM_freeN(last->pointer);
158
159         /* delete the buffer and remove from pool */
160         MEM_freeN(last);
161         pool->totbuf--;
162         pool->buffers[pool->totbuf] = NULL;
163 }
164
165 /* free a GPUBufferPool; also frees the data in the pool's
166  * GPUBuffers */
167 static void gpu_buffer_pool_free(GPUBufferPool *pool)
168 {
169         if (!pool)
170                 return;
171         
172         while (pool->totbuf)
173                 gpu_buffer_pool_delete_last(pool);
174
175         MEM_freeN(pool->buffers);
176         MEM_freeN(pool->pbvhbufids);
177         MEM_freeN(pool);
178 }
179
180 static void gpu_buffer_pool_free_unused(GPUBufferPool *pool)
181 {
182         if (!pool)
183                 return;
184
185         BLI_mutex_lock(&buffer_mutex);
186         
187         while (pool->totbuf)
188                 gpu_buffer_pool_delete_last(pool);
189
190         if (pool->totpbvhbufids > 0) {
191                 glDeleteBuffersARB(pool->totpbvhbufids, pool->pbvhbufids);
192                 pool->totpbvhbufids = 0;
193         }
194
195         BLI_mutex_unlock(&buffer_mutex);
196 }
197
198 static GPUBufferPool *gpu_buffer_pool = NULL;
199 static GPUBufferPool *gpu_get_global_buffer_pool(void)
200 {
201         /* initialize the pool */
202         if (!gpu_buffer_pool)
203                 gpu_buffer_pool = gpu_buffer_pool_new();
204
205         return gpu_buffer_pool;
206 }
207
208 void GPU_global_buffer_pool_free(void)
209 {
210         gpu_buffer_pool_free(gpu_buffer_pool);
211         gpu_buffer_pool = NULL;
212 }
213
214 void GPU_global_buffer_pool_free_unused(void)
215 {
216         gpu_buffer_pool_free_unused(gpu_buffer_pool);
217 }
218
219 /* get a GPUBuffer of at least `size' bytes; uses one from the buffer
220  * pool if possible, otherwise creates a new one
221  *
222  * Thread-unsafe version for internal usage only.
223  */
224 static GPUBuffer *gpu_buffer_alloc_intern(int size, bool use_VBO)
225 {
226         GPUBufferPool *pool;
227         GPUBuffer *buf;
228         int i, bufsize, bestfit = -1;
229
230         /* bad case, leads to leak of buf since buf->pointer will allocate
231          * NULL, leading to return without cleanup. In any case better detect early
232          * psy-fi */
233         if (size == 0)
234                 return NULL;
235
236         pool = gpu_get_global_buffer_pool();
237
238         /* not sure if this buffer pool code has been profiled much,
239          * seems to me that the graphics driver and system memory
240          * management might do this stuff anyway. --nicholas
241          */
242
243         /* check the global buffer pool for a recently-deleted buffer
244          * that is at least as big as the request, but not more than
245          * twice as big */
246         for (i = 0; i < pool->totbuf; i++) {
247                 bufsize = pool->buffers[i]->size;
248
249                 /* only return a buffer that matches the VBO preference */
250                 if (pool->buffers[i]->use_vbo != use_VBO) {
251                          continue;
252                 }
253                 
254                 /* check for an exact size match */
255                 if (bufsize == size) {
256                         bestfit = i;
257                         break;
258                 }
259                 /* smaller buffers won't fit data and buffers at least
260                  * twice as big are a waste of memory */
261                 else if (bufsize > size && size > (bufsize / 2)) {
262                         /* is it closer to the required size than the
263                          * last appropriate buffer found. try to save
264                          * memory */
265                         if (bestfit == -1 || pool->buffers[bestfit]->size > bufsize) {
266                                 bestfit = i;
267                         }
268                 }
269         }
270
271         /* if an acceptable buffer was found in the pool, remove it
272          * from the pool and return it */
273         if (bestfit != -1) {
274                 buf = pool->buffers[bestfit];
275                 gpu_buffer_pool_remove_index(pool, bestfit);
276                 return buf;
277         }
278
279         /* no acceptable buffer found in the pool, create a new one */
280         buf = MEM_callocN(sizeof(GPUBuffer), "GPUBuffer");
281         buf->size = size;
282         buf->use_vbo = use_VBO;
283
284         if (use_VBO) {
285                 /* create a new VBO and initialize it to the requested
286                  * size */
287                 glGenBuffersARB(1, &buf->id);
288                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, buf->id);
289                 glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, NULL, GL_STATIC_DRAW_ARB);
290                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
291         }
292         else {
293                 buf->pointer = MEM_mallocN(size, "GPUBuffer.pointer");
294                 
295                 /* purpose of this seems to be dealing with
296                  * out-of-memory errors? looks a bit iffy to me
297                  * though, at least on Linux I expect malloc() would
298                  * just overcommit. --nicholas */
299                 while (!buf->pointer && pool->totbuf > 0) {
300                         gpu_buffer_pool_delete_last(pool);
301                         buf->pointer = MEM_mallocN(size, "GPUBuffer.pointer");
302                 }
303                 if (!buf->pointer)
304                         return NULL;
305         }
306
307         return buf;
308 }
309
310 /* Same as above, but safe for threading. */
311 GPUBuffer *GPU_buffer_alloc(int size, bool force_vertex_arrays)
312 {
313         GPUBuffer *buffer;
314         bool use_VBOs = (GLEW_ARB_vertex_buffer_object) && !(U.gameflags & USER_DISABLE_VBO) && !force_vertex_arrays;
315
316         if (size == 0) {
317                 /* Early out, no lock needed in this case. */
318                 return NULL;
319         }
320
321         BLI_mutex_lock(&buffer_mutex);
322         buffer = gpu_buffer_alloc_intern(size, use_VBOs);
323         BLI_mutex_unlock(&buffer_mutex);
324
325         return buffer;
326 }
327
328 /* release a GPUBuffer; does not free the actual buffer or its data,
329  * but rather moves it to the pool of recently-freed buffers for
330  * possible re-use
331  *
332  * Thread-unsafe version for internal usage only.
333  */
334 static void gpu_buffer_free_intern(GPUBuffer *buffer)
335 {
336         GPUBufferPool *pool;
337         int i;
338
339         if (!buffer)
340                 return;
341
342         pool = gpu_get_global_buffer_pool();
343
344         /* free the last used buffer in the queue if no more space, but only
345          * if we are in the main thread. for e.g. rendering or baking it can
346          * happen that we are in other thread and can't call OpenGL, in that
347          * case cleanup will be done GPU_buffer_pool_free_unused */
348         if (BLI_thread_is_main()) {
349                 /* in main thread, safe to decrease size of pool back
350                  * down to MAX_FREE_GPU_BUFFERS */
351                 while (pool->totbuf >= MAX_FREE_GPU_BUFFERS)
352                         gpu_buffer_pool_delete_last(pool);
353         }
354         else {
355                 /* outside of main thread, can't safely delete the
356                  * buffer, so increase pool size */
357                 if (pool->maxsize == pool->totbuf) {
358                         pool->maxsize += MAX_FREE_GPU_BUFFERS;
359                         pool->buffers = MEM_reallocN(pool->buffers,
360                                                      sizeof(GPUBuffer *) * pool->maxsize);
361                 }
362         }
363
364         /* shift pool entries up by one */
365         for (i = pool->totbuf; i > 0; i--)
366                 pool->buffers[i] = pool->buffers[i - 1];
367
368         /* insert the buffer into the beginning of the pool */
369         pool->buffers[0] = buffer;
370         pool->totbuf++;
371 }
372
373 /* Same as above, but safe for threading. */
374 void GPU_buffer_free(GPUBuffer *buffer)
375 {
376         if (!buffer) {
377                 /* Early output, no need to lock in this case, */
378                 return;
379         }
380
381         BLI_mutex_lock(&buffer_mutex);
382         gpu_buffer_free_intern(buffer);
383         BLI_mutex_unlock(&buffer_mutex);
384 }
385
386 /* currently unused */
387 // #define USE_GPU_POINT_LINK
388
389 typedef struct GPUVertPointLink {
390 #ifdef USE_GPU_POINT_LINK
391         struct GPUVertPointLink *next;
392 #endif
393         /* -1 means uninitialized */
394         int point_index;
395 } GPUVertPointLink;
396
397
398 /* add a new point to the list of points related to a particular
399  * vertex */
400 #ifdef USE_GPU_POINT_LINK
401
402 static void gpu_drawobject_add_vert_point(GPUDrawObject *gdo, int vert_index, int point_index)
403 {
404         GPUVertPointLink *lnk;
405
406         lnk = &gdo->vert_points[vert_index];
407
408         /* if first link is in use, add a new link at the end */
409         if (lnk->point_index != -1) {
410                 /* get last link */
411                 for (; lnk->next; lnk = lnk->next) ;
412
413                 /* add a new link from the pool */
414                 lnk = lnk->next = &gdo->vert_points_mem[gdo->vert_points_usage];
415                 gdo->vert_points_usage++;
416         }
417
418         lnk->point_index = point_index;
419 }
420
421 #else
422
423 static void gpu_drawobject_add_vert_point(GPUDrawObject *gdo, int vert_index, int point_index)
424 {
425         GPUVertPointLink *lnk;
426         lnk = &gdo->vert_points[vert_index];
427         if (lnk->point_index == -1) {
428                 lnk->point_index = point_index;
429         }
430 }
431
432 #endif  /* USE_GPU_POINT_LINK */
433
434 /* update the vert_points and triangle_to_mface fields with a new
435  * triangle */
436 static void gpu_drawobject_add_triangle(GPUDrawObject *gdo,
437                                         int base_point_index,
438                                         int face_index,
439                                         int v1, int v2, int v3)
440 {
441         int i, v[3] = {v1, v2, v3};
442         for (i = 0; i < 3; i++)
443                 gpu_drawobject_add_vert_point(gdo, v[i], base_point_index + i);
444         gdo->triangle_to_mface[base_point_index / 3] = face_index;
445 }
446
447 /* for each vertex, build a list of points related to it; these lists
448  * are stored in an array sized to the number of vertices */
449 static void gpu_drawobject_init_vert_points(GPUDrawObject *gdo, MFace *f, int totface, int totmat)
450 {
451         GPUBufferMaterial *mat;
452         int i, *mat_orig_to_new;
453
454         mat_orig_to_new = MEM_callocN(sizeof(*mat_orig_to_new) * totmat,
455                                                      "GPUDrawObject.mat_orig_to_new");
456         /* allocate the array and space for links */
457         gdo->vert_points = MEM_mallocN(sizeof(GPUVertPointLink) * gdo->totvert,
458                                        "GPUDrawObject.vert_points");
459 #ifdef USE_GPU_POINT_LINK
460         gdo->vert_points_mem = MEM_callocN(sizeof(GPUVertPointLink) * gdo->tot_triangle_point,
461                                            "GPUDrawObject.vert_points_mem");
462         gdo->vert_points_usage = 0;
463 #endif
464
465         /* build a map from the original material indices to the new
466          * GPUBufferMaterial indices */
467         for (i = 0; i < gdo->totmaterial; i++)
468                 mat_orig_to_new[gdo->materials[i].mat_nr] = i;
469
470         /* -1 indicates the link is not yet used */
471         for (i = 0; i < gdo->totvert; i++) {
472 #ifdef USE_GPU_POINT_LINK
473                 gdo->vert_points[i].link = NULL;
474 #endif
475                 gdo->vert_points[i].point_index = -1;
476         }
477
478         for (i = 0; i < totface; i++, f++) {
479                 mat = &gdo->materials[mat_orig_to_new[f->mat_nr]];
480
481                 /* add triangle */
482                 gpu_drawobject_add_triangle(gdo, mat->start + mat->totpoint,
483                                             i, f->v1, f->v2, f->v3);
484                 mat->totpoint += 3;
485
486                 /* add second triangle for quads */
487                 if (f->v4) {
488                         gpu_drawobject_add_triangle(gdo, mat->start + mat->totpoint,
489                                                     i, f->v3, f->v4, f->v1);
490                         mat->totpoint += 3;
491                 }
492         }
493
494         /* map any unused vertices to loose points */
495         for (i = 0; i < gdo->totvert; i++) {
496                 if (gdo->vert_points[i].point_index == -1) {
497                         gdo->vert_points[i].point_index = gdo->tot_triangle_point + gdo->tot_loose_point;
498                         gdo->tot_loose_point++;
499                 }
500         }
501
502         MEM_freeN(mat_orig_to_new);
503 }
504
505 /* see GPUDrawObject's structure definition for a description of the
506  * data being initialized here */
507 GPUDrawObject *GPU_drawobject_new(DerivedMesh *dm)
508 {
509         GPUDrawObject *gdo;
510         MFace *mface;
511         int totmat = dm->totmat;
512         int *points_per_mat;
513         int i, curmat, curpoint, totface;
514
515         /* object contains at least one material (default included) so zero means uninitialized dm */
516         BLI_assert(totmat != 0);
517
518         mface = dm->getTessFaceArray(dm);
519         totface = dm->getNumTessFaces(dm);
520
521         /* get the number of points used by each material, treating
522          * each quad as two triangles */
523         points_per_mat = MEM_callocN(sizeof(*points_per_mat) * totmat, "GPU_drawobject_new.mat_orig_to_new");
524         for (i = 0; i < totface; i++)
525                 points_per_mat[mface[i].mat_nr] += mface[i].v4 ? 6 : 3;
526
527         /* create the GPUDrawObject */
528         gdo = MEM_callocN(sizeof(GPUDrawObject), "GPUDrawObject");
529         gdo->totvert = dm->getNumVerts(dm);
530         gdo->totedge = dm->getNumEdges(dm);
531
532         /* count the number of materials used by this DerivedMesh */
533         for (i = 0; i < totmat; i++) {
534                 if (points_per_mat[i] > 0)
535                         gdo->totmaterial++;
536         }
537
538         /* allocate an array of materials used by this DerivedMesh */
539         gdo->materials = MEM_mallocN(sizeof(GPUBufferMaterial) * gdo->totmaterial,
540                                      "GPUDrawObject.materials");
541
542         /* initialize the materials array */
543         for (i = 0, curmat = 0, curpoint = 0; i < totmat; i++) {
544                 if (points_per_mat[i] > 0) {
545                         gdo->materials[curmat].start = curpoint;
546                         gdo->materials[curmat].totpoint = 0;
547                         gdo->materials[curmat].mat_nr = i;
548
549                         curpoint += points_per_mat[i];
550                         curmat++;
551                 }
552         }
553
554         /* store total number of points used for triangles */
555         gdo->tot_triangle_point = curpoint;
556
557         gdo->triangle_to_mface = MEM_mallocN(sizeof(int) * (gdo->tot_triangle_point / 3),
558                                              "GPUDrawObject.triangle_to_mface");
559
560         gpu_drawobject_init_vert_points(gdo, mface, totface, totmat);
561         MEM_freeN(points_per_mat);
562
563         return gdo;
564 }
565
566 void GPU_drawobject_free(DerivedMesh *dm)
567 {
568         GPUDrawObject *gdo;
569
570         if (!dm || !(gdo = dm->drawObject))
571                 return;
572
573         MEM_freeN(gdo->materials);
574         MEM_freeN(gdo->triangle_to_mface);
575         MEM_freeN(gdo->vert_points);
576 #ifdef USE_GPU_POINT_LINK
577         MEM_freeN(gdo->vert_points_mem);
578 #endif
579         GPU_buffer_free(gdo->points);
580         GPU_buffer_free(gdo->normals);
581         GPU_buffer_free(gdo->uv);
582         GPU_buffer_free(gdo->uv_tex);
583         GPU_buffer_free(gdo->colors);
584         GPU_buffer_free(gdo->edges);
585         GPU_buffer_free(gdo->uvedges);
586
587         MEM_freeN(gdo);
588         dm->drawObject = NULL;
589 }
590
591 static GPUBuffer *gpu_try_realloc(GPUBufferPool *pool, GPUBuffer *buffer, int size, bool use_VBOs)
592 {
593         gpu_buffer_free_intern(buffer);
594         gpu_buffer_pool_delete_last(pool);
595         buffer = NULL;
596         
597         /* try freeing an entry from the pool
598          * and reallocating the buffer */
599         if (pool->totbuf > 0) {
600                 gpu_buffer_pool_delete_last(pool);
601                 buffer = gpu_buffer_alloc_intern(size, use_VBOs);
602         }
603         
604         return buffer;
605 }
606
607 typedef void (*GPUBufferCopyFunc)(DerivedMesh *dm, float *varray, int *index,
608                                   int *mat_orig_to_new, void *user_data);
609
610 static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object,
611                                    int vector_size, int size, GLenum target,
612                                    void *user, GPUBufferCopyFunc copy_f)
613 {
614         GPUBufferPool *pool;
615         GPUBuffer *buffer;
616         float *varray;
617         int *mat_orig_to_new;
618         int *cur_index_per_mat;
619         int i;
620         bool use_VBOs = (GLEW_ARB_vertex_buffer_object) && !(U.gameflags & USER_DISABLE_VBO);
621         GLboolean uploaded;
622
623         pool = gpu_get_global_buffer_pool();
624
625         BLI_mutex_lock(&buffer_mutex);
626
627         /* alloc a GPUBuffer; fall back to legacy mode on failure */
628         if (!(buffer = gpu_buffer_alloc_intern(size, use_VBOs))) {
629                 BLI_mutex_unlock(&buffer_mutex);
630                 return NULL;
631         }
632
633         mat_orig_to_new = MEM_mallocN(sizeof(*mat_orig_to_new) * dm->totmat,
634                                       "GPU_buffer_setup.mat_orig_to_new");
635         cur_index_per_mat = MEM_mallocN(sizeof(int) * object->totmaterial,
636                                         "GPU_buffer_setup.cur_index_per_mat");
637         for (i = 0; i < object->totmaterial; i++) {
638                 /* for each material, the current index to copy data to */
639                 cur_index_per_mat[i] = object->materials[i].start * vector_size;
640
641                 /* map from original material index to new
642                  * GPUBufferMaterial index */
643                 mat_orig_to_new[object->materials[i].mat_nr] = i;
644         }
645
646         if (use_VBOs) {
647                 bool success = false;
648
649                 while (!success) {
650                         /* bind the buffer and discard previous data,
651                          * avoids stalling gpu */
652                         glBindBufferARB(target, buffer->id);
653                         glBufferDataARB(target, buffer->size, NULL, GL_STATIC_DRAW_ARB);
654
655                         /* attempt to map the buffer */
656                         if (!(varray = glMapBufferARB(target, GL_WRITE_ONLY_ARB))) {
657                                 buffer = gpu_try_realloc(pool, buffer, size, true);
658
659                                 /* allocation still failed; fall back
660                                  * to legacy mode */
661                                 if (!buffer) {
662                                         use_VBOs = false;
663                                         success = true;
664                                 }
665                         }
666                         else {
667                                 success = true;
668                         }
669                 }
670
671                 /* check legacy fallback didn't happen */
672                 if (use_VBOs) {
673                         uploaded = GL_FALSE;
674                         /* attempt to upload the data to the VBO */
675                         while (uploaded == GL_FALSE) {
676                                 (*copy_f)(dm, varray, cur_index_per_mat, mat_orig_to_new, user);
677                                 /* glUnmapBuffer returns GL_FALSE if
678                                  * the data store is corrupted; retry
679                                  * in that case */
680                                 uploaded = glUnmapBufferARB(target);
681                         }
682                 }
683                 glBindBufferARB(target, 0);
684         }
685         if (!use_VBOs) {
686                 /* VBO not supported, use vertex array fallback */
687                 if (!buffer || !buffer->pointer) {
688                         buffer = gpu_try_realloc(pool, buffer, size, false);
689                 }
690                 
691                 if (buffer) {
692                         varray = buffer->pointer;
693                         (*copy_f)(dm, varray, cur_index_per_mat, mat_orig_to_new, user);
694                 }
695         }
696
697         MEM_freeN(cur_index_per_mat);
698         MEM_freeN(mat_orig_to_new);
699
700         BLI_mutex_unlock(&buffer_mutex);
701
702         return buffer;
703 }
704
705 static void GPU_buffer_copy_vertex(DerivedMesh *dm, float *varray, int *index, int *mat_orig_to_new, void *UNUSED(user))
706 {
707         MVert *mvert;
708         MFace *f;
709         int i, j, start, totface;
710
711         mvert = dm->getVertArray(dm);
712         f = dm->getTessFaceArray(dm);
713
714         totface = dm->getNumTessFaces(dm);
715         for (i = 0; i < totface; i++, f++) {
716                 start = index[mat_orig_to_new[f->mat_nr]];
717
718                 /* v1 v2 v3 */
719                 copy_v3_v3(&varray[start], mvert[f->v1].co);
720                 copy_v3_v3(&varray[start + 3], mvert[f->v2].co);
721                 copy_v3_v3(&varray[start + 6], mvert[f->v3].co);
722                 index[mat_orig_to_new[f->mat_nr]] += 9;
723
724                 if (f->v4) {
725                         /* v3 v4 v1 */
726                         copy_v3_v3(&varray[start + 9], mvert[f->v3].co);
727                         copy_v3_v3(&varray[start + 12], mvert[f->v4].co);
728                         copy_v3_v3(&varray[start + 15], mvert[f->v1].co);
729                         index[mat_orig_to_new[f->mat_nr]] += 9;
730                 }
731         }
732
733         /* copy loose points */
734         j = dm->drawObject->tot_triangle_point * 3;
735         for (i = 0; i < dm->drawObject->totvert; i++) {
736                 if (dm->drawObject->vert_points[i].point_index >= dm->drawObject->tot_triangle_point) {
737                         copy_v3_v3(&varray[j], mvert[i].co);
738                         j += 3;
739                 }
740         }
741 }
742
743 static void GPU_buffer_copy_normal(DerivedMesh *dm, float *varray, int *index, int *mat_orig_to_new, void *UNUSED(user))
744 {
745         int i, totface;
746         int start;
747         float f_no[3];
748
749         const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
750         short (*tlnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
751         MVert *mvert = dm->getVertArray(dm);
752         MFace *f = dm->getTessFaceArray(dm);
753
754         totface = dm->getNumTessFaces(dm);
755         for (i = 0; i < totface; i++, f++) {
756                 const int smoothnormal = (f->flag & ME_SMOOTH);
757
758                 start = index[mat_orig_to_new[f->mat_nr]];
759                 index[mat_orig_to_new[f->mat_nr]] += f->v4 ? 18 : 9;
760
761                 if (tlnors) {
762                         short (*tlnor)[3] = tlnors[i];
763                         /* Copy loop normals */
764                         normal_short_to_float_v3(&varray[start], tlnor[0]);
765                         normal_short_to_float_v3(&varray[start + 3], tlnor[1]);
766                         normal_short_to_float_v3(&varray[start + 6], tlnor[2]);
767
768                         if (f->v4) {
769                                 normal_short_to_float_v3(&varray[start + 9], tlnor[2]);
770                                 normal_short_to_float_v3(&varray[start + 12], tlnor[3]);
771                                 normal_short_to_float_v3(&varray[start + 15], tlnor[0]);
772                         }
773                 }
774                 else if (smoothnormal) {
775                         /* copy vertex normal */
776                         normal_short_to_float_v3(&varray[start], mvert[f->v1].no);
777                         normal_short_to_float_v3(&varray[start + 3], mvert[f->v2].no);
778                         normal_short_to_float_v3(&varray[start + 6], mvert[f->v3].no);
779
780                         if (f->v4) {
781                                 normal_short_to_float_v3(&varray[start + 9], mvert[f->v3].no);
782                                 normal_short_to_float_v3(&varray[start + 12], mvert[f->v4].no);
783                                 normal_short_to_float_v3(&varray[start + 15], mvert[f->v1].no);
784                         }
785                 }
786                 else if (nors) {
787                         /* copy cached face normal */
788                         copy_v3_v3(&varray[start], &nors[i * 3]);
789                         copy_v3_v3(&varray[start + 3], &nors[i * 3]);
790                         copy_v3_v3(&varray[start + 6], &nors[i * 3]);
791
792                         if (f->v4) {
793                                 copy_v3_v3(&varray[start + 9], &nors[i * 3]);
794                                 copy_v3_v3(&varray[start + 12], &nors[i * 3]);
795                                 copy_v3_v3(&varray[start + 15], &nors[i * 3]);
796                         }
797                 }
798                 else {
799                         /* calculate face normal */
800                         if (f->v4)
801                                 normal_quad_v3(f_no, mvert[f->v1].co, mvert[f->v2].co, mvert[f->v3].co, mvert[f->v4].co);
802                         else
803                                 normal_tri_v3(f_no, mvert[f->v1].co, mvert[f->v2].co, mvert[f->v3].co);
804
805                         copy_v3_v3(&varray[start], f_no);
806                         copy_v3_v3(&varray[start + 3], f_no);
807                         copy_v3_v3(&varray[start + 6], f_no);
808
809                         if (f->v4) {
810                                 copy_v3_v3(&varray[start + 9], f_no);
811                                 copy_v3_v3(&varray[start + 12], f_no);
812                                 copy_v3_v3(&varray[start + 15], f_no);
813                         }
814                 }
815         }
816 }
817
818 static void GPU_buffer_copy_uv(DerivedMesh *dm, float *varray, int *index, int *mat_orig_to_new, void *UNUSED(user))
819 {
820         int start;
821         int i, totface;
822
823         MTFace *mtface;
824         MFace *f;
825
826         if (!(mtface = DM_get_tessface_data_layer(dm, CD_MTFACE)))
827                 return;
828         f = dm->getTessFaceArray(dm);
829                 
830         totface = dm->getNumTessFaces(dm);
831         for (i = 0; i < totface; i++, f++) {
832                 start = index[mat_orig_to_new[f->mat_nr]];
833
834                 /* v1 v2 v3 */
835                 copy_v2_v2(&varray[start], mtface[i].uv[0]);
836                 copy_v2_v2(&varray[start + 2], mtface[i].uv[1]);
837                 copy_v2_v2(&varray[start + 4], mtface[i].uv[2]);
838                 index[mat_orig_to_new[f->mat_nr]] += 6;
839
840                 if (f->v4) {
841                         /* v3 v4 v1 */
842                         copy_v2_v2(&varray[start + 6], mtface[i].uv[2]);
843                         copy_v2_v2(&varray[start + 8], mtface[i].uv[3]);
844                         copy_v2_v2(&varray[start + 10], mtface[i].uv[0]);
845                         index[mat_orig_to_new[f->mat_nr]] += 6;
846                 }
847         }
848 }
849
850
851 static void GPU_buffer_copy_uv_texpaint(DerivedMesh *dm, float *varray, int *index, int *mat_orig_to_new, void *UNUSED(user))
852 {
853         int start;
854         int i, totface;
855
856         int totmaterial = dm->totmat;
857         MTFace **mtface_base;
858         MTFace *stencil_base;
859         int stencil;
860         MFace *mf;
861
862         /* should have been checked for before, reassert */
863         BLI_assert(DM_get_tessface_data_layer(dm, CD_MTFACE));
864         mf = dm->getTessFaceArray(dm);
865         mtface_base = MEM_mallocN(totmaterial * sizeof(*mtface_base), "texslots");
866
867         for (i = 0; i < totmaterial; i++) {
868                 mtface_base[i] = DM_paint_uvlayer_active_get(dm, i);
869         }
870
871         stencil = CustomData_get_stencil_layer(&dm->faceData, CD_MTFACE);
872         stencil_base = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, stencil);
873
874         totface = dm->getNumTessFaces(dm);
875
876         for (i = 0; i < totface; i++, mf++) {
877                 int mat_i = mf->mat_nr;
878                 start = index[mat_orig_to_new[mat_i]];
879
880                 /* v1 v2 v3 */
881                 copy_v2_v2(&varray[start], mtface_base[mat_i][i].uv[0]);
882                 copy_v2_v2(&varray[start + 2], stencil_base[i].uv[0]);
883                 copy_v2_v2(&varray[start + 4], mtface_base[mat_i][i].uv[1]);
884                 copy_v2_v2(&varray[start + 6], stencil_base[i].uv[1]);
885                 copy_v2_v2(&varray[start + 8], mtface_base[mat_i][i].uv[2]);
886                 copy_v2_v2(&varray[start + 10], stencil_base[i].uv[2]);
887                 index[mat_orig_to_new[mat_i]] += 12;
888
889                 if (mf->v4) {
890                         /* v3 v4 v1 */
891                         copy_v2_v2(&varray[start + 12], mtface_base[mat_i][i].uv[2]);
892                         copy_v2_v2(&varray[start + 14], stencil_base[i].uv[2]);
893                         copy_v2_v2(&varray[start + 16], mtface_base[mat_i][i].uv[3]);
894                         copy_v2_v2(&varray[start + 18], stencil_base[i].uv[3]);
895                         copy_v2_v2(&varray[start + 20], mtface_base[mat_i][i].uv[0]);
896                         copy_v2_v2(&varray[start + 22], stencil_base[i].uv[0]);
897                         index[mat_orig_to_new[mat_i]] += 12;
898                 }
899         }
900
901         MEM_freeN(mtface_base);
902 }
903
904
905 static void copy_mcol_uc3(unsigned char *v, unsigned char *col)
906 {
907         v[0] = col[3];
908         v[1] = col[2];
909         v[2] = col[1];
910 }
911
912 /* treat varray_ as an array of MCol, four MCol's per face */
913 static void GPU_buffer_copy_mcol(DerivedMesh *dm, float *varray_, int *index, int *mat_orig_to_new, void *user)
914 {
915         int i, totface;
916         unsigned char *varray = (unsigned char *)varray_;
917         unsigned char *mcol = (unsigned char *)user;
918         MFace *f = dm->getTessFaceArray(dm);
919
920         totface = dm->getNumTessFaces(dm);
921         for (i = 0; i < totface; i++, f++) {
922                 int start = index[mat_orig_to_new[f->mat_nr]];
923
924                 /* v1 v2 v3 */
925                 copy_mcol_uc3(&varray[start], &mcol[i * 16]);
926                 copy_mcol_uc3(&varray[start + 3], &mcol[i * 16 + 4]);
927                 copy_mcol_uc3(&varray[start + 6], &mcol[i * 16 + 8]);
928                 index[mat_orig_to_new[f->mat_nr]] += 9;
929
930                 if (f->v4) {
931                         /* v3 v4 v1 */
932                         copy_mcol_uc3(&varray[start + 9], &mcol[i * 16 + 8]);
933                         copy_mcol_uc3(&varray[start + 12], &mcol[i * 16 + 12]);
934                         copy_mcol_uc3(&varray[start + 15], &mcol[i * 16]);
935                         index[mat_orig_to_new[f->mat_nr]] += 9;
936                 }
937         }
938 }
939
940 static void GPU_buffer_copy_edge(DerivedMesh *dm, float *varray_, int *UNUSED(index), int *UNUSED(mat_orig_to_new), void *UNUSED(user))
941 {
942         MEdge *medge;
943         unsigned int *varray = (unsigned int *)varray_;
944         int i, totedge;
945
946         medge = dm->getEdgeArray(dm);
947         totedge = dm->getNumEdges(dm);
948
949         for (i = 0; i < totedge; i++, medge++) {
950                 varray[i * 2] = dm->drawObject->vert_points[medge->v1].point_index;
951                 varray[i * 2 + 1] = dm->drawObject->vert_points[medge->v2].point_index;
952         }
953 }
954
955 static void GPU_buffer_copy_uvedge(DerivedMesh *dm, float *varray, int *UNUSED(index), int *UNUSED(mat_orig_to_new), void *UNUSED(user))
956 {
957         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
958         int i, j = 0;
959
960         if (!tf)
961                 return;
962
963         for (i = 0; i < dm->numTessFaceData; i++, tf++) {
964                 MFace mf;
965                 dm->getTessFace(dm, i, &mf);
966
967                 copy_v2_v2(&varray[j], tf->uv[0]);
968                 copy_v2_v2(&varray[j + 2], tf->uv[1]);
969
970                 copy_v2_v2(&varray[j + 4], tf->uv[1]);
971                 copy_v2_v2(&varray[j + 6], tf->uv[2]);
972
973                 if (!mf.v4) {
974                         copy_v2_v2(&varray[j + 8], tf->uv[2]);
975                         copy_v2_v2(&varray[j + 10], tf->uv[0]);
976                         j += 12;
977                 }
978                 else {
979                         copy_v2_v2(&varray[j + 8], tf->uv[2]);
980                         copy_v2_v2(&varray[j + 10], tf->uv[3]);
981
982                         copy_v2_v2(&varray[j + 12], tf->uv[3]);
983                         copy_v2_v2(&varray[j + 14], tf->uv[0]);
984                         j += 16;
985                 }
986         }
987 }
988
989 typedef enum {
990         GPU_BUFFER_VERTEX = 0,
991         GPU_BUFFER_NORMAL,
992         GPU_BUFFER_COLOR,
993         GPU_BUFFER_UV,
994         GPU_BUFFER_UV_TEXPAINT,
995         GPU_BUFFER_EDGE,
996         GPU_BUFFER_UVEDGE,
997 } GPUBufferType;
998
999 typedef struct {
1000         GPUBufferCopyFunc copy;
1001         GLenum gl_buffer_type;
1002         int vector_size;
1003 } GPUBufferTypeSettings;
1004
1005 const GPUBufferTypeSettings gpu_buffer_type_settings[] = {
1006         {GPU_buffer_copy_vertex, GL_ARRAY_BUFFER_ARB, 3},
1007         {GPU_buffer_copy_normal, GL_ARRAY_BUFFER_ARB, 3},
1008         {GPU_buffer_copy_mcol, GL_ARRAY_BUFFER_ARB, 3},
1009         {GPU_buffer_copy_uv, GL_ARRAY_BUFFER_ARB, 2},
1010     {GPU_buffer_copy_uv_texpaint, GL_ARRAY_BUFFER_ARB, 4},
1011         {GPU_buffer_copy_edge, GL_ELEMENT_ARRAY_BUFFER_ARB, 2},
1012         {GPU_buffer_copy_uvedge, GL_ELEMENT_ARRAY_BUFFER_ARB, 4}
1013 };
1014
1015 /* get the GPUDrawObject buffer associated with a type */
1016 static GPUBuffer **gpu_drawobject_buffer_from_type(GPUDrawObject *gdo, GPUBufferType type)
1017 {
1018         switch (type) {
1019                 case GPU_BUFFER_VERTEX:
1020                         return &gdo->points;
1021                 case GPU_BUFFER_NORMAL:
1022                         return &gdo->normals;
1023                 case GPU_BUFFER_COLOR:
1024                         return &gdo->colors;
1025                 case GPU_BUFFER_UV:
1026                         return &gdo->uv;
1027                 case GPU_BUFFER_UV_TEXPAINT:
1028                         return &gdo->uv_tex;
1029                 case GPU_BUFFER_EDGE:
1030                         return &gdo->edges;
1031                 case GPU_BUFFER_UVEDGE:
1032                         return &gdo->uvedges;
1033                 default:
1034                         return NULL;
1035         }
1036 }
1037
1038 /* get the amount of space to allocate for a buffer of a particular type */
1039 static int gpu_buffer_size_from_type(DerivedMesh *dm, GPUBufferType type)
1040 {
1041         switch (type) {
1042                 case GPU_BUFFER_VERTEX:
1043                         return sizeof(float) * 3 * (dm->drawObject->tot_triangle_point + dm->drawObject->tot_loose_point);
1044                 case GPU_BUFFER_NORMAL:
1045                         return sizeof(float) * 3 * dm->drawObject->tot_triangle_point;
1046                 case GPU_BUFFER_COLOR:
1047                         return sizeof(char) * 3 * dm->drawObject->tot_triangle_point;
1048                 case GPU_BUFFER_UV:
1049                         return sizeof(float) * 2 * dm->drawObject->tot_triangle_point;
1050                 case GPU_BUFFER_UV_TEXPAINT:
1051                         return sizeof(float) * 4 * dm->drawObject->tot_triangle_point;
1052                 case GPU_BUFFER_EDGE:
1053                         return sizeof(int) * 2 * dm->drawObject->totedge;
1054                 case GPU_BUFFER_UVEDGE:
1055                         /* each face gets 3 points, 3 edges per triangle, and
1056                          * each edge has its own, non-shared coords, so each
1057                          * tri corner needs minimum of 4 floats, quads used
1058                          * less so here we can over allocate and assume all
1059                          * tris. */
1060                         return sizeof(float) * 4 * dm->drawObject->tot_triangle_point;
1061                 default:
1062                         return -1;
1063         }
1064 }
1065
1066 /* call gpu_buffer_setup with settings for a particular type of buffer */
1067 static GPUBuffer *gpu_buffer_setup_type(DerivedMesh *dm, GPUBufferType type)
1068 {
1069         const GPUBufferTypeSettings *ts;
1070         void *user_data = NULL;
1071         GPUBuffer *buf;
1072
1073         ts = &gpu_buffer_type_settings[type];
1074
1075         /* special handling for MCol and UV buffers */
1076         if (type == GPU_BUFFER_COLOR) {
1077                 if (!(user_data = DM_get_tessface_data_layer(dm, dm->drawObject->colType)))
1078                         return NULL;
1079         }
1080         else if (ELEM(type, GPU_BUFFER_UV, GPU_BUFFER_UV_TEXPAINT)) {
1081                 if (!DM_get_tessface_data_layer(dm, CD_MTFACE))
1082                         return NULL;
1083         }
1084
1085         buf = gpu_buffer_setup(dm, dm->drawObject, ts->vector_size,
1086                                gpu_buffer_size_from_type(dm, type),
1087                                ts->gl_buffer_type, user_data, ts->copy);
1088
1089         return buf;
1090 }
1091
1092 /* get the buffer of `type', initializing the GPUDrawObject and
1093  * buffer if needed */
1094 static GPUBuffer *gpu_buffer_setup_common(DerivedMesh *dm, GPUBufferType type)
1095 {
1096         GPUBuffer **buf;
1097
1098         if (!dm->drawObject)
1099                 dm->drawObject = GPU_drawobject_new(dm);
1100
1101         buf = gpu_drawobject_buffer_from_type(dm->drawObject, type);
1102         if (!(*buf))
1103                 *buf = gpu_buffer_setup_type(dm, type);
1104
1105         return *buf;
1106 }
1107
1108 void GPU_vertex_setup(DerivedMesh *dm)
1109 {
1110         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_VERTEX))
1111                 return;
1112
1113         glEnableClientState(GL_VERTEX_ARRAY);
1114         if (dm->drawObject->points->use_vbo) {
1115                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->points->id);
1116                 glVertexPointer(3, GL_FLOAT, 0, 0);
1117         }
1118         else {
1119                 glVertexPointer(3, GL_FLOAT, 0, dm->drawObject->points->pointer);
1120         }
1121         
1122         GLStates |= GPU_BUFFER_VERTEX_STATE;
1123 }
1124
1125 void GPU_normal_setup(DerivedMesh *dm)
1126 {
1127         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_NORMAL))
1128                 return;
1129
1130         glEnableClientState(GL_NORMAL_ARRAY);
1131         if (dm->drawObject->normals->use_vbo) {
1132                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->normals->id);
1133                 glNormalPointer(GL_FLOAT, 0, 0);
1134         }
1135         else {
1136                 glNormalPointer(GL_FLOAT, 0, dm->drawObject->normals->pointer);
1137         }
1138
1139         GLStates |= GPU_BUFFER_NORMAL_STATE;
1140 }
1141
1142 void GPU_uv_setup(DerivedMesh *dm)
1143 {
1144         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_UV))
1145                 return;
1146
1147         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1148         if (dm->drawObject->uv->use_vbo) {
1149                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uv->id);
1150                 glTexCoordPointer(2, GL_FLOAT, 0, 0);
1151         }
1152         else {
1153                 glTexCoordPointer(2, GL_FLOAT, 0, dm->drawObject->uv->pointer);
1154         }
1155
1156         GLStates |= GPU_BUFFER_TEXCOORD_UNIT_0_STATE;
1157 }
1158
1159 void GPU_texpaint_uv_setup(DerivedMesh *dm)
1160 {
1161         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_UV_TEXPAINT))
1162                 return;
1163
1164         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1165         if (dm->drawObject->uv_tex->use_vbo) {
1166                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uv_tex->id);
1167                 glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0);
1168                 glClientActiveTexture(GL_TEXTURE2);
1169                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1170                 glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), BUFFER_OFFSET(2 * sizeof(float)));
1171                 glClientActiveTexture(GL_TEXTURE0);
1172         }
1173         else {
1174                 glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), dm->drawObject->uv_tex->pointer);
1175                 glClientActiveTexture(GL_TEXTURE2);
1176                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1177                 glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)dm->drawObject->uv_tex->pointer + 2 * sizeof(float));
1178                 glClientActiveTexture(GL_TEXTURE0);
1179         }
1180
1181         GLStates |= GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE;
1182 }
1183
1184
1185 void GPU_color_setup(DerivedMesh *dm, int colType)
1186 {
1187         if (!dm->drawObject) {
1188                 /* XXX Not really nice, but we need a valid gpu draw object to set the colType...
1189                  *     Else we would have to add a new param to gpu_buffer_setup_common. */
1190                 dm->drawObject = GPU_drawobject_new(dm);
1191                 dm->dirty &= ~DM_DIRTY_MCOL_UPDATE_DRAW;
1192                 dm->drawObject->colType = colType;
1193         }
1194         /* In paint mode, dm may stay the same during stroke, however we still want to update colors!
1195          * Also check in case we changed color type (i.e. which MCol cdlayer we use). */
1196         else if ((dm->dirty & DM_DIRTY_MCOL_UPDATE_DRAW) || (colType != dm->drawObject->colType)) {
1197                 GPUBuffer **buf = gpu_drawobject_buffer_from_type(dm->drawObject, GPU_BUFFER_COLOR);
1198                 /* XXX Freeing this buffer is a bit stupid, as geometry has not changed, size should remain the same.
1199                  *     Not sure though it would be worth defining a sort of gpu_buffer_update func - nor whether
1200                  *     it is even possible ! */
1201                 GPU_buffer_free(*buf);
1202                 *buf = NULL;
1203                 dm->dirty &= ~DM_DIRTY_MCOL_UPDATE_DRAW;
1204                 dm->drawObject->colType = colType;
1205         }
1206
1207         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_COLOR))
1208                 return;
1209
1210         glEnableClientState(GL_COLOR_ARRAY);
1211         if (dm->drawObject->colors->use_vbo) {
1212                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->colors->id);
1213                 glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0);
1214         }
1215         else {
1216                 glColorPointer(3, GL_UNSIGNED_BYTE, 0, dm->drawObject->colors->pointer);
1217         }
1218
1219         GLStates |= GPU_BUFFER_COLOR_STATE;
1220 }
1221
1222 void GPU_edge_setup(DerivedMesh *dm)
1223 {
1224         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_EDGE))
1225                 return;
1226
1227         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_VERTEX))
1228                 return;
1229
1230         glEnableClientState(GL_VERTEX_ARRAY);
1231         if (dm->drawObject->points->use_vbo) {
1232                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->points->id);
1233                 glVertexPointer(3, GL_FLOAT, 0, 0);
1234         }
1235         else {
1236                 glVertexPointer(3, GL_FLOAT, 0, dm->drawObject->points->pointer);
1237         }
1238         
1239         GLStates |= GPU_BUFFER_VERTEX_STATE;
1240
1241         if (dm->drawObject->edges->use_vbo)
1242                 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, dm->drawObject->edges->id);
1243
1244         GLStates |= GPU_BUFFER_ELEMENT_STATE;
1245 }
1246
1247 void GPU_uvedge_setup(DerivedMesh *dm)
1248 {
1249         if (!gpu_buffer_setup_common(dm, GPU_BUFFER_UVEDGE))
1250                 return;
1251
1252         glEnableClientState(GL_VERTEX_ARRAY);
1253         if (dm->drawObject->uvedges->use_vbo) {
1254                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, dm->drawObject->uvedges->id);
1255                 glVertexPointer(2, GL_FLOAT, 0, 0);
1256         }
1257         else {
1258                 glVertexPointer(2, GL_FLOAT, 0, dm->drawObject->uvedges->pointer);
1259         }
1260         
1261         GLStates |= GPU_BUFFER_VERTEX_STATE;
1262 }
1263
1264 static int GPU_typesize(int type)
1265 {
1266         switch (type) {
1267                 case GL_FLOAT:
1268                         return sizeof(float);
1269                 case GL_INT:
1270                         return sizeof(int);
1271                 case GL_UNSIGNED_INT:
1272                         return sizeof(unsigned int);
1273                 case GL_BYTE:
1274                         return sizeof(char);
1275                 case GL_UNSIGNED_BYTE:
1276                         return sizeof(unsigned char);
1277                 default:
1278                         return 0;
1279         }
1280 }
1281
1282 int GPU_attrib_element_size(GPUAttrib data[], int numdata)
1283 {
1284         int i, elementsize = 0;
1285
1286         for (i = 0; i < numdata; i++) {
1287                 int typesize = GPU_typesize(data[i].type);
1288                 if (typesize != 0)
1289                         elementsize += typesize * data[i].size;
1290         }
1291         return elementsize;
1292 }
1293
1294 void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numdata)
1295 {
1296         int i;
1297         int elementsize;
1298         intptr_t offset = 0;
1299         char *basep;
1300
1301         for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) {
1302                 if (attribData[i].index != -1) {
1303                         glDisableVertexAttribArrayARB(attribData[i].index);
1304                 }
1305                 else
1306                         break;
1307         }
1308         elementsize = GPU_attrib_element_size(data, numdata);
1309
1310         if (buffer->use_vbo) {
1311                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id);
1312                 basep = NULL;
1313         }
1314         else {
1315                 basep = buffer->pointer;
1316         }
1317         
1318         for (i = 0; i < numdata; i++) {
1319                 glEnableVertexAttribArrayARB(data[i].index);
1320                 glVertexAttribPointerARB(data[i].index, data[i].size, data[i].type,
1321                                          GL_FALSE, elementsize, (void *)(basep + offset));
1322                 offset += data[i].size * GPU_typesize(data[i].type);
1323                 
1324                 attribData[i].index = data[i].index;
1325                 attribData[i].size = data[i].size;
1326                 attribData[i].type = data[i].type;
1327         }
1328         
1329         attribData[numdata].index = -1; 
1330 }
1331
1332
1333 void GPU_buffer_unbind(void)
1334 {
1335         int i;
1336
1337         if (GLStates & GPU_BUFFER_VERTEX_STATE)
1338                 glDisableClientState(GL_VERTEX_ARRAY);
1339         if (GLStates & GPU_BUFFER_NORMAL_STATE)
1340                 glDisableClientState(GL_NORMAL_ARRAY);
1341         if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_0_STATE)
1342                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1343         if (GLStates & GPU_BUFFER_TEXCOORD_UNIT_2_STATE) {
1344                 glClientActiveTexture(GL_TEXTURE2);
1345                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1346                 glClientActiveTexture(GL_TEXTURE0);
1347         }
1348         if (GLStates & GPU_BUFFER_COLOR_STATE)
1349                 glDisableClientState(GL_COLOR_ARRAY);
1350         if (GLStates & GPU_BUFFER_ELEMENT_STATE) {
1351                 /* not guaranteed we used VBOs but in that case it's just a no-op */
1352                 if (GLEW_ARB_vertex_buffer_object) {
1353                         glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1354                 }
1355         }
1356         GLStates &= ~(GPU_BUFFER_VERTEX_STATE | GPU_BUFFER_NORMAL_STATE |
1357                       GPU_BUFFER_TEXCOORD_UNIT_0_STATE | GPU_BUFFER_TEXCOORD_UNIT_2_STATE |
1358                       GPU_BUFFER_COLOR_STATE | GPU_BUFFER_ELEMENT_STATE);
1359
1360         for (i = 0; i < MAX_GPU_ATTRIB_DATA; i++) {
1361                 if (attribData[i].index != -1) {
1362                         glDisableVertexAttribArrayARB(attribData[i].index);
1363                 }
1364                 else
1365                         break;
1366         }
1367
1368         /* not guaranteed we used VBOs but in that case it's just a no-op */
1369         if (GLEW_ARB_vertex_buffer_object)
1370                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1371 }
1372
1373 void GPU_color_switch(int mode)
1374 {
1375         if (mode) {
1376                 if (!(GLStates & GPU_BUFFER_COLOR_STATE))
1377                         glEnableClientState(GL_COLOR_ARRAY);
1378                 GLStates |= GPU_BUFFER_COLOR_STATE;
1379         }
1380         else {
1381                 if (GLStates & GPU_BUFFER_COLOR_STATE)
1382                         glDisableClientState(GL_COLOR_ARRAY);
1383                 GLStates &= ~GPU_BUFFER_COLOR_STATE;
1384         }
1385 }
1386
1387 void *GPU_buffer_lock(GPUBuffer *buffer)
1388 {
1389         float *varray;
1390
1391         if (!buffer)
1392                 return 0;
1393
1394         if (buffer->use_vbo) {
1395                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id);
1396                 varray = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
1397                 return varray;
1398         }
1399         else {
1400                 return buffer->pointer;
1401         }
1402 }
1403
1404 void *GPU_buffer_lock_stream(GPUBuffer *buffer)
1405 {
1406         float *varray;
1407
1408         if (!buffer)
1409                 return 0;
1410
1411         if (buffer->use_vbo) {
1412                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer->id);
1413                 /* discard previous data, avoid stalling gpu */
1414                 glBufferDataARB(GL_ARRAY_BUFFER_ARB, buffer->size, 0, GL_STREAM_DRAW_ARB);
1415                 varray = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
1416                 return varray;
1417         }
1418         else {
1419                 return buffer->pointer;
1420         }
1421 }
1422
1423 void GPU_buffer_unlock(GPUBuffer *buffer)
1424 {
1425         if (buffer->use_vbo) {
1426                 /* note: this operation can fail, could return
1427                  * an error code from this function? */
1428                 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
1429                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1430         }
1431 }
1432
1433 /* used for drawing edges */
1434 void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start, int count)
1435 {
1436         glDrawElements(mode, count, GL_UNSIGNED_INT,
1437                        (elements->use_vbo ?
1438                         (void *)(start * sizeof(unsigned int)) :
1439                         ((int *)elements->pointer) + start));
1440 }
1441
1442
1443 /* XXX: the rest of the code in this file is used for optimized PBVH
1444  * drawing and doesn't interact at all with the buffer code above */
1445
1446 /* Return false if VBO is either unavailable or disabled by the user,
1447  * true otherwise */
1448 static int gpu_vbo_enabled(void)
1449 {
1450         return (GLEW_ARB_vertex_buffer_object &&
1451                 !(U.gameflags & USER_DISABLE_VBO));
1452 }
1453
1454 /* Convenience struct for building the VBO. */
1455 typedef struct {
1456         float co[3];
1457         short no[3];
1458
1459         /* inserting this to align the 'color' field to a four-byte
1460          * boundary; drastically increases viewport performance on my
1461          * drivers (Gallium/Radeon) --nicholasbishop */
1462         char pad[2];
1463         
1464         unsigned char color[3];
1465 } VertexBufferFormat;
1466
1467 struct GPU_PBVH_Buffers {
1468         /* opengl buffer handles */
1469         GLuint vert_buf, index_buf;
1470         GLenum index_type;
1471
1472         /* mesh pointers in case buffer allocation fails */
1473         MFace *mface;
1474         MVert *mvert;
1475         const int *face_indices;
1476         int totface;
1477         const float *vmask;
1478
1479         /* grid pointers */
1480         CCGKey gridkey;
1481         CCGElem **grids;
1482         const DMFlagMat *grid_flag_mats;
1483         BLI_bitmap * const *grid_hidden;
1484         const int *grid_indices;
1485         int totgrid;
1486         int has_hidden;
1487
1488         int use_bmesh;
1489
1490         unsigned int tot_tri, tot_quad;
1491
1492         /* The PBVH ensures that either all faces in the node are
1493          * smooth-shaded or all faces are flat-shaded */
1494         int smooth;
1495
1496         bool show_diffuse_color;
1497         bool use_matcaps;
1498         float diffuse_color[4];
1499 };
1500 typedef enum {
1501         VBO_ENABLED,
1502         VBO_DISABLED
1503 } VBO_State;
1504
1505 static void gpu_colors_enable(VBO_State vbo_state)
1506 {
1507         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
1508         glEnable(GL_COLOR_MATERIAL);
1509         if (vbo_state == VBO_ENABLED)
1510                 glEnableClientState(GL_COLOR_ARRAY);
1511 }
1512
1513 static void gpu_colors_disable(VBO_State vbo_state)
1514 {
1515         glDisable(GL_COLOR_MATERIAL);
1516         if (vbo_state == VBO_ENABLED)
1517                 glDisableClientState(GL_COLOR_ARRAY);
1518 }
1519
1520 static float gpu_color_from_mask(float mask)
1521 {
1522         return 1.0f - mask * 0.75f;
1523 }
1524
1525 static void gpu_color_from_mask_copy(float mask, const float diffuse_color[4], unsigned char out[3])
1526 {
1527         float mask_color;
1528
1529         mask_color = gpu_color_from_mask(mask) * 255.0f;
1530
1531         out[0] = diffuse_color[0] * mask_color;
1532         out[1] = diffuse_color[1] * mask_color;
1533         out[2] = diffuse_color[2] * mask_color;
1534 }
1535
1536 static void gpu_color_from_mask_set(float mask, float diffuse_color[4])
1537 {
1538         float color = gpu_color_from_mask(mask);
1539         glColor3f(diffuse_color[0] * color, diffuse_color[1] * color, diffuse_color[2] * color);
1540 }
1541
1542 static float gpu_color_from_mask_quad(const CCGKey *key,
1543                                       CCGElem *a, CCGElem *b,
1544                                       CCGElem *c, CCGElem *d)
1545 {
1546         return gpu_color_from_mask((*CCG_elem_mask(key, a) +
1547                                     *CCG_elem_mask(key, b) +
1548                                     *CCG_elem_mask(key, c) +
1549                                     *CCG_elem_mask(key, d)) * 0.25f);
1550 }
1551
1552 static void gpu_color_from_mask_quad_copy(const CCGKey *key,
1553                                           CCGElem *a, CCGElem *b,
1554                                           CCGElem *c, CCGElem *d,
1555                                           const float *diffuse_color,
1556                                           unsigned char out[3])
1557 {
1558         float mask_color =
1559             gpu_color_from_mask((*CCG_elem_mask(key, a) +
1560                                  *CCG_elem_mask(key, b) +
1561                                  *CCG_elem_mask(key, c) +
1562                                  *CCG_elem_mask(key, d)) * 0.25f) * 255.0f;
1563
1564         out[0] = diffuse_color[0] * mask_color;
1565         out[1] = diffuse_color[1] * mask_color;
1566         out[2] = diffuse_color[2] * mask_color;
1567 }
1568
1569 static void gpu_color_from_mask_quad_set(const CCGKey *key,
1570                                          CCGElem *a, CCGElem *b,
1571                                          CCGElem *c, CCGElem *d,
1572                                          const float diffuse_color[4])
1573 {
1574         float color = gpu_color_from_mask_quad(key, a, b, c, d);
1575         glColor3f(diffuse_color[0] * color, diffuse_color[1] * color, diffuse_color[2] * color);
1576 }
1577
1578 void GPU_update_mesh_pbvh_buffers(GPU_PBVH_Buffers *buffers, MVert *mvert,
1579                              int *vert_indices, int totvert, const float *vmask,
1580                              int (*face_vert_indices)[4], bool show_diffuse_color)
1581 {
1582         VertexBufferFormat *vert_data;
1583         int i, j, k;
1584
1585         buffers->vmask = vmask;
1586         buffers->show_diffuse_color = show_diffuse_color;
1587         buffers->use_matcaps = GPU_material_use_matcaps_get();
1588
1589         if (buffers->vert_buf) {
1590                 int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3));
1591                 float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 0.8f};
1592
1593                 if (buffers->use_matcaps)
1594                         diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
1595                 else if (show_diffuse_color) {
1596                         MFace *f = buffers->mface + buffers->face_indices[0];
1597
1598                         GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
1599                 }
1600
1601                 copy_v4_v4(buffers->diffuse_color, diffuse_color);
1602
1603                 /* Build VBO */
1604                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
1605                 glBufferDataARB(GL_ARRAY_BUFFER_ARB,
1606                                                 sizeof(VertexBufferFormat) * totelem,
1607                                                 NULL, GL_STATIC_DRAW_ARB);
1608
1609                 vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
1610
1611                 if (vert_data) {
1612                         /* Vertex data is shared if smooth-shaded, but separate
1613                          * copies are made for flat shading because normals
1614                          * shouldn't be shared. */
1615                         if (buffers->smooth) {
1616                                 for (i = 0; i < totvert; ++i) {
1617                                         MVert *v = mvert + vert_indices[i];
1618                                         VertexBufferFormat *out = vert_data + i;
1619
1620                                         copy_v3_v3(out->co, v->co);
1621                                         memcpy(out->no, v->no, sizeof(short) * 3);
1622                                 }
1623
1624 #define UPDATE_VERTEX(face, vertex, index, diffuse_color) \
1625                                 { \
1626                                         VertexBufferFormat *out = vert_data + face_vert_indices[face][index]; \
1627                                         if (vmask) \
1628                                                 gpu_color_from_mask_copy(vmask[vertex], diffuse_color, out->color); \
1629                                         else \
1630                                                 rgb_float_to_uchar(out->color, diffuse_color); \
1631                                 } (void)0
1632
1633                                 for (i = 0; i < buffers->totface; i++) {
1634                                         MFace *f = buffers->mface + buffers->face_indices[i];
1635
1636                                         UPDATE_VERTEX(i, f->v1, 0, diffuse_color);
1637                                         UPDATE_VERTEX(i, f->v2, 1, diffuse_color);
1638                                         UPDATE_VERTEX(i, f->v3, 2, diffuse_color);
1639                                         if (f->v4)
1640                                                 UPDATE_VERTEX(i, f->v4, 3, diffuse_color);
1641                                 }
1642 #undef UPDATE_VERTEX
1643                         }
1644                         else {
1645                                 for (i = 0; i < buffers->totface; ++i) {
1646                                         const MFace *f = &buffers->mface[buffers->face_indices[i]];
1647                                         const unsigned int *fv = &f->v1;
1648                                         const int vi[2][3] = {{0, 1, 2}, {3, 0, 2}};
1649                                         float fno[3];
1650                                         short no[3];
1651
1652                                         float fmask;
1653
1654                                         if (paint_is_face_hidden(f, mvert))
1655                                                 continue;
1656
1657                                         /* Face normal and mask */
1658                                         if (f->v4) {
1659                                                 normal_quad_v3(fno,
1660                                                                            mvert[fv[0]].co,
1661                                                                            mvert[fv[1]].co,
1662                                                                            mvert[fv[2]].co,
1663                                                                            mvert[fv[3]].co);
1664                                                 if (vmask) {
1665                                                         fmask = (vmask[fv[0]] +
1666                                                                          vmask[fv[1]] +
1667                                                                          vmask[fv[2]] +
1668                                                                          vmask[fv[3]]) * 0.25f;
1669                                                 }
1670                                         }
1671                                         else {
1672                                                 normal_tri_v3(fno,
1673                                                                           mvert[fv[0]].co,
1674                                                                           mvert[fv[1]].co,
1675                                                                           mvert[fv[2]].co);
1676                                                 if (vmask) {
1677                                                         fmask = (vmask[fv[0]] +
1678                                                                          vmask[fv[1]] +
1679                                                                          vmask[fv[2]]) / 3.0f;
1680                                                 }
1681                                         }
1682                                         normal_float_to_short_v3(no, fno);
1683
1684                                         for (j = 0; j < (f->v4 ? 2 : 1); j++) {
1685                                                 for (k = 0; k < 3; k++) {
1686                                                         const MVert *v = &mvert[fv[vi[j][k]]];
1687                                                         VertexBufferFormat *out = vert_data;
1688
1689                                                         copy_v3_v3(out->co, v->co);
1690                                                         memcpy(out->no, no, sizeof(short) * 3);
1691
1692                                                         if (vmask)
1693                                                                 gpu_color_from_mask_copy(fmask, diffuse_color, out->color);
1694                                                         else
1695                                                                 rgb_float_to_uchar(out->color, diffuse_color);
1696
1697                                                         vert_data++;
1698                                                 }
1699                                         }
1700                                 }
1701                         }
1702
1703                         glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
1704                 }
1705                 else {
1706                         glDeleteBuffersARB(1, &buffers->vert_buf);
1707                         buffers->vert_buf = 0;
1708                 }
1709
1710                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1711         }
1712
1713         buffers->mvert = mvert;
1714 }
1715
1716 GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(int (*face_vert_indices)[4],
1717                                     MFace *mface, MVert *mvert,
1718                                     int *face_indices,
1719                                     int totface)
1720 {
1721         GPU_PBVH_Buffers *buffers;
1722         unsigned short *tri_data;
1723         int i, j, k, tottri;
1724
1725         buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
1726         buffers->index_type = GL_UNSIGNED_SHORT;
1727         buffers->smooth = mface[face_indices[0]].flag & ME_SMOOTH;
1728
1729         buffers->show_diffuse_color = false;
1730         buffers->use_matcaps = false;
1731
1732         /* Count the number of visible triangles */
1733         for (i = 0, tottri = 0; i < totface; ++i) {
1734                 const MFace *f = &mface[face_indices[i]];
1735                 if (!paint_is_face_hidden(f, mvert))
1736                         tottri += f->v4 ? 2 : 1;
1737         }
1738
1739         if (tottri == 0) {
1740                 buffers->tot_tri = 0;
1741
1742                 buffers->mface = mface;
1743                 buffers->face_indices = face_indices;
1744                 buffers->totface = 0;
1745
1746                 return buffers;
1747         }
1748
1749         /* An element index buffer is used for smooth shading, but flat
1750          * shading requires separate vertex normals so an index buffer is
1751          * can't be used there. */
1752         if (gpu_vbo_enabled() && buffers->smooth)
1753                 glGenBuffersARB(1, &buffers->index_buf);
1754
1755         if (buffers->index_buf) {
1756                 /* Generate index buffer object */
1757                 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
1758                 glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
1759                                 sizeof(unsigned short) * tottri * 3, NULL, GL_STATIC_DRAW_ARB);
1760
1761                 /* Fill the triangle buffer */
1762                 tri_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
1763                 if (tri_data) {
1764                         for (i = 0; i < totface; ++i) {
1765                                 const MFace *f = mface + face_indices[i];
1766                                 int v[3];
1767
1768                                 /* Skip hidden faces */
1769                                 if (paint_is_face_hidden(f, mvert))
1770                                         continue;
1771
1772                                 v[0] = 0;
1773                                 v[1] = 1;
1774                                 v[2] = 2;
1775
1776                                 for (j = 0; j < (f->v4 ? 2 : 1); ++j) {
1777                                         for (k = 0; k < 3; ++k) {
1778                                                 *tri_data = face_vert_indices[i][v[k]];
1779                                                 tri_data++;
1780                                         }
1781                                         v[0] = 3;
1782                                         v[1] = 0;
1783                                         v[2] = 2;
1784                                 }
1785                         }
1786                         glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
1787                 }
1788                 else {
1789                         glDeleteBuffersARB(1, &buffers->index_buf);
1790                         buffers->index_buf = 0;
1791                 }
1792
1793                 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
1794         }
1795
1796         if (gpu_vbo_enabled() && (buffers->index_buf || !buffers->smooth))
1797                 glGenBuffersARB(1, &buffers->vert_buf);
1798
1799         buffers->tot_tri = tottri;
1800
1801         buffers->mface = mface;
1802         buffers->face_indices = face_indices;
1803         buffers->totface = totface;
1804
1805         return buffers;
1806 }
1807
1808 void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
1809                              const DMFlagMat *grid_flag_mats, int *grid_indices,
1810                              int totgrid, const CCGKey *key, bool show_diffuse_color)
1811 {
1812         VertexBufferFormat *vert_data;
1813         int i, j, k, x, y;
1814
1815         buffers->show_diffuse_color = show_diffuse_color;
1816         buffers->use_matcaps = GPU_material_use_matcaps_get();
1817
1818         /* Build VBO */
1819         if (buffers->vert_buf) {
1820                 int totvert = key->grid_area * totgrid;
1821                 int smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
1822                 const int has_mask = key->has_mask;
1823                 float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
1824
1825                 if (buffers->use_matcaps)
1826                         diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
1827                 else if (show_diffuse_color) {
1828                         const DMFlagMat *flags = &grid_flag_mats[grid_indices[0]];
1829
1830                         GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
1831                 }
1832
1833                 copy_v4_v4(buffers->diffuse_color, diffuse_color);
1834
1835                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
1836                 glBufferDataARB(GL_ARRAY_BUFFER_ARB,
1837                                 sizeof(VertexBufferFormat) * totvert,
1838                                 NULL, GL_STATIC_DRAW_ARB);
1839                 vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
1840                 if (vert_data) {
1841                         for (i = 0; i < totgrid; ++i) {
1842                                 VertexBufferFormat *vd = vert_data;
1843                                 CCGElem *grid = grids[grid_indices[i]];
1844
1845                                 for (y = 0; y < key->grid_size; y++) {
1846                                         for (x = 0; x < key->grid_size; x++) {
1847                                                 CCGElem *elem = CCG_grid_elem(key, grid, x, y);
1848                                                 
1849                                                 copy_v3_v3(vd->co, CCG_elem_co(key, elem));
1850                                                 if (smooth) {
1851                                                         normal_float_to_short_v3(vd->no, CCG_elem_no(key, elem));
1852
1853                                                         if (has_mask) {
1854                                                                 gpu_color_from_mask_copy(*CCG_elem_mask(key, elem),
1855                                                                                          diffuse_color, vd->color);
1856                                                         }
1857                                                 }
1858                                                 vd++;
1859                                         }
1860                                 }
1861                                 
1862                                 if (!smooth) {
1863                                         /* for flat shading, recalc normals and set the last vertex of
1864                                          * each triangle in the index buffer to have the flat normal as
1865                                          * that is what opengl will use */
1866                                         for (j = 0; j < key->grid_size - 1; j++) {
1867                                                 for (k = 0; k < key->grid_size - 1; k++) {
1868                                                         CCGElem *elems[4] = {
1869                                                                 CCG_grid_elem(key, grid, k, j + 1),
1870                                                                 CCG_grid_elem(key, grid, k + 1, j + 1),
1871                                                                 CCG_grid_elem(key, grid, k + 1, j),
1872                                                                 CCG_grid_elem(key, grid, k, j)
1873                                                         };
1874                                                         float fno[3];
1875
1876                                                         normal_quad_v3(fno,
1877                                                                        CCG_elem_co(key, elems[0]),
1878                                                                        CCG_elem_co(key, elems[1]),
1879                                                                        CCG_elem_co(key, elems[2]),
1880                                                                        CCG_elem_co(key, elems[3]));
1881
1882                                                         vd = vert_data + (j + 1) * key->grid_size + k;
1883                                                         normal_float_to_short_v3(vd->no, fno);
1884
1885                                                         if (has_mask) {
1886                                                                 gpu_color_from_mask_quad_copy(key,
1887                                                                                               elems[0],
1888                                                                                               elems[1],
1889                                                                                               elems[2],
1890                                                                                               elems[3],
1891                                                                                               diffuse_color,
1892                                                                                               vd->color);
1893                                                         }
1894                                                 }
1895                                         }
1896                                 }
1897
1898                                 vert_data += key->grid_area;
1899                         }
1900                         glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
1901                 }
1902                 else {
1903                         glDeleteBuffersARB(1, &buffers->vert_buf);
1904                         buffers->vert_buf = 0;
1905                 }
1906                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
1907         }
1908
1909         buffers->grids = grids;
1910         buffers->grid_indices = grid_indices;
1911         buffers->totgrid = totgrid;
1912         buffers->grid_flag_mats = grid_flag_mats;
1913         buffers->gridkey = *key;
1914
1915         buffers->smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
1916
1917         //printf("node updated %p\n", buffers);
1918 }
1919
1920 /* Build the element array buffer of grid indices using either
1921  * unsigned shorts or unsigned ints. */
1922 #define FILL_QUAD_BUFFER(type_, tot_quad_, buffer_)                     \
1923         {                                                                   \
1924                 type_ *tri_data;                                               \
1925                 int offset = 0;                                                 \
1926                 int i, j, k;                                                    \
1927                                                                                 \
1928                 glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,                    \
1929                                                 sizeof(type_) * (tot_quad_) * 6, NULL,          \
1930                                 GL_STATIC_DRAW_ARB);                            \
1931                                                                                 \
1932                 /* Fill the buffer */                                      \
1933                 tri_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,         \
1934                                            GL_WRITE_ONLY_ARB);                  \
1935                 if (tri_data) {                                                \
1936                         for (i = 0; i < totgrid; ++i) {                             \
1937                                 BLI_bitmap *gh = NULL;                                  \
1938                                 if (grid_hidden)                                        \
1939                                         gh = grid_hidden[(grid_indices)[i]];                \
1940                                                                                                                                                 \
1941                                 for (j = 0; j < gridsize - 1; ++j) {                    \
1942                                         for (k = 0; k < gridsize - 1; ++k) {                \
1943                                                 /* Skip hidden grid face */                     \
1944                                                 if (gh &&                                       \
1945                                                     paint_is_grid_face_hidden(gh,               \
1946                                                                               gridsize, k, j))  \
1947                                                         continue;                                   \
1948                                                                                                                                                 \
1949                                                 *(tri_data++) = offset + j * gridsize + k + 1; \
1950                                                 *(tri_data++) = offset + j * gridsize + k;     \
1951                                                 *(tri_data++) = offset + (j + 1) * gridsize + k; \
1952                                                                                                                                                 \
1953                                                 *(tri_data++) = offset + (j + 1) * gridsize + k + 1; \
1954                                                 *(tri_data++) = offset + j * gridsize + k + 1; \
1955                                                 *(tri_data++) = offset + (j + 1) * gridsize + k; \
1956                                         }                                                   \
1957                                 }                                                       \
1958                                                                                                                                                 \
1959                                 offset += gridsize * gridsize;                          \
1960                         }                                                           \
1961                         glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);              \
1962                 }                                                               \
1963                 else {                                                          \
1964                         glDeleteBuffersARB(1, &(buffer_));                          \
1965                         (buffer_) = 0;                                              \
1966                 }                                                               \
1967         } (void)0
1968 /* end FILL_QUAD_BUFFER */
1969
1970 static GLuint gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *totquad)
1971 {
1972         static int prev_gridsize = -1;
1973         static GLenum prev_index_type = 0;
1974         static GLuint buffer = 0;
1975         static unsigned prev_totquad;
1976
1977         /* used in the FILL_QUAD_BUFFER macro */
1978         BLI_bitmap * const *grid_hidden = NULL;
1979         const int *grid_indices = NULL;
1980         int totgrid = 1;
1981
1982         /* VBO is disabled; delete the previous buffer (if it exists) and
1983          * return an invalid handle */
1984         if (!gpu_vbo_enabled()) {
1985                 if (buffer)
1986                         glDeleteBuffersARB(1, &buffer);
1987                 return 0;
1988         }
1989
1990         /* VBO is already built */
1991         if (buffer && prev_gridsize == gridsize) {
1992                 *index_type = prev_index_type;
1993                 *totquad = prev_totquad;
1994                 return buffer;
1995         }
1996
1997         /* Build new VBO */
1998         glGenBuffersARB(1, &buffer);
1999         if (buffer) {
2000                 *totquad = (gridsize - 1) * (gridsize - 1);
2001
2002                 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffer);
2003
2004                 if (gridsize * gridsize < USHRT_MAX) {
2005                         *index_type = GL_UNSIGNED_SHORT;
2006                         FILL_QUAD_BUFFER(unsigned short, *totquad, buffer);
2007                 }
2008                 else {
2009                         *index_type = GL_UNSIGNED_INT;
2010                         FILL_QUAD_BUFFER(unsigned int, *totquad, buffer);
2011                 }
2012
2013                 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
2014         }
2015
2016         prev_gridsize = gridsize;
2017         prev_index_type = *index_type;
2018         prev_totquad = *totquad;
2019         return buffer;
2020 }
2021
2022 GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(int *grid_indices, int totgrid,
2023                                                                                           BLI_bitmap **grid_hidden, int gridsize)
2024 {
2025         GPU_PBVH_Buffers *buffers;
2026         int totquad;
2027         int fully_visible_totquad = (gridsize - 1) * (gridsize - 1) * totgrid;
2028
2029         buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
2030         buffers->grid_hidden = grid_hidden;
2031         buffers->totgrid = totgrid;
2032
2033         buffers->show_diffuse_color = false;
2034         buffers->use_matcaps = false;
2035
2036         /* Count the number of quads */
2037         totquad = BKE_pbvh_count_grid_quads(grid_hidden, grid_indices, totgrid, gridsize);
2038
2039         /* totally hidden node, return here to avoid BufferData with zero below. */
2040         if (totquad == 0)
2041                 return buffers;
2042
2043         if (totquad == fully_visible_totquad) {
2044                 buffers->index_buf = gpu_get_grid_buffer(gridsize, &buffers->index_type, &buffers->tot_quad);
2045                 buffers->has_hidden = 0;
2046         }
2047         else if (GLEW_ARB_vertex_buffer_object && !(U.gameflags & USER_DISABLE_VBO)) {
2048                 /* Build new VBO */
2049                 glGenBuffersARB(1, &buffers->index_buf);
2050                 if (buffers->index_buf) {
2051                         buffers->tot_quad = totquad;
2052
2053                         glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
2054
2055                         if (totgrid * gridsize * gridsize < USHRT_MAX) {
2056                                 buffers->index_type = GL_UNSIGNED_SHORT;
2057                                 FILL_QUAD_BUFFER(unsigned short, totquad, buffers->index_buf);
2058                         }
2059                         else {
2060                                 buffers->index_type = GL_UNSIGNED_INT;
2061                                 FILL_QUAD_BUFFER(unsigned int, totquad, buffers->index_buf);
2062                         }
2063
2064                         glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
2065                 }
2066
2067                 buffers->has_hidden = 1;
2068         }
2069
2070         /* Build coord/normal VBO */
2071         if (buffers->index_buf)
2072                 glGenBuffersARB(1, &buffers->vert_buf);
2073
2074         return buffers;
2075 }
2076
2077 #undef FILL_QUAD_BUFFER
2078
2079 /* Output a BMVert into a VertexBufferFormat array
2080  *
2081  * The vertex is skipped if hidden, otherwise the output goes into
2082  * index '*v_index' in the 'vert_data' array and '*v_index' is
2083  * incremented.
2084  */
2085 static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
2086                                           VertexBufferFormat *vert_data,
2087                                           int *v_index,
2088                                           const float fno[3],
2089                                           const float *fmask,
2090                                           const int cd_vert_mask_offset,
2091                                           const float diffuse_color[4])
2092 {
2093         if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
2094                 VertexBufferFormat *vd = &vert_data[*v_index];
2095
2096                 /* Set coord, normal, and mask */
2097                 copy_v3_v3(vd->co, v->co);
2098                 normal_float_to_short_v3(vd->no, fno ? fno : v->no);
2099
2100                 gpu_color_from_mask_copy(
2101                         fmask ? *fmask :
2102                                 BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset),
2103                         diffuse_color,
2104                         vd->color);
2105                 
2106
2107                 /* Assign index for use in the triangle index buffer */
2108                 /* note: caller must set:  bm->elem_index_dirty |= BM_VERT; */
2109                 BM_elem_index_set(v, (*v_index)); /* set_dirty! */
2110
2111                 (*v_index)++;
2112         }
2113 }
2114
2115 /* Return the total number of vertices that don't have BM_ELEM_HIDDEN set */
2116 static int gpu_bmesh_vert_visible_count(GSet *bm_unique_verts,
2117                                         GSet *bm_other_verts)
2118 {
2119         GSetIterator gs_iter;
2120         int totvert = 0;
2121
2122         GSET_ITER (gs_iter, bm_unique_verts) {
2123                 BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
2124                 if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN))
2125                         totvert++;
2126         }
2127         GSET_ITER (gs_iter, bm_other_verts) {
2128                 BMVert *v = BLI_gsetIterator_getKey(&gs_iter);
2129                 if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN))
2130                         totvert++;
2131         }
2132
2133         return totvert;
2134 }
2135
2136 /* Return the total number of visible faces */
2137 static int gpu_bmesh_face_visible_count(GSet *bm_faces)
2138 {
2139         GSetIterator gh_iter;
2140         int totface = 0;
2141
2142         GSET_ITER (gh_iter, bm_faces) {
2143                 BMFace *f = BLI_gsetIterator_getKey(&gh_iter);
2144
2145                 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN))
2146                         totface++;
2147         }
2148
2149         return totface;
2150 }
2151
2152 /* Creates a vertex buffer (coordinate, normal, color) and, if smooth
2153  * shading, an element index buffer. */
2154 void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
2155                               BMesh *bm,
2156                               GSet *bm_faces,
2157                               GSet *bm_unique_verts,
2158                               GSet *bm_other_verts,
2159                               bool show_diffuse_color)
2160 {
2161         VertexBufferFormat *vert_data;
2162         void *tri_data;
2163         int tottri, totvert, maxvert = 0;
2164         float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
2165
2166         /* TODO, make mask layer optional for bmesh buffer */
2167         const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
2168
2169         buffers->show_diffuse_color = show_diffuse_color;
2170         buffers->use_matcaps = GPU_material_use_matcaps_get();
2171
2172         if (!buffers->vert_buf || (buffers->smooth && !buffers->index_buf))
2173                 return;
2174
2175         /* Count visible triangles */
2176         tottri = gpu_bmesh_face_visible_count(bm_faces);
2177
2178         if (buffers->smooth) {
2179                 /* Count visible vertices */
2180                 totvert = gpu_bmesh_vert_visible_count(bm_unique_verts, bm_other_verts);
2181         }
2182         else
2183                 totvert = tottri * 3;
2184
2185         if (!tottri) {
2186                 buffers->tot_tri = 0;
2187                 return;
2188         }
2189
2190         if (buffers->use_matcaps)
2191                 diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
2192         else if (show_diffuse_color) {
2193                 /* due to dynamic nature of dyntopo, only get first material */
2194                 GSetIterator gs_iter;
2195                 BMFace *f;
2196                 BLI_gsetIterator_init(&gs_iter, bm_faces);
2197                 f = BLI_gsetIterator_getKey(&gs_iter);
2198                 GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
2199         }
2200
2201         copy_v4_v4(buffers->diffuse_color, diffuse_color);
2202
2203         /* Initialize vertex buffer */
2204         glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
2205         glBufferDataARB(GL_ARRAY_BUFFER_ARB,
2206                                         sizeof(VertexBufferFormat) * totvert,
2207                                         NULL, GL_STATIC_DRAW_ARB);
2208
2209         /* Fill vertex buffer */
2210         vert_data = glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
2211         if (vert_data) {
2212                 int v_index = 0;
2213
2214                 if (buffers->smooth) {
2215                         GSetIterator gs_iter;
2216
2217                         /* Vertices get an index assigned for use in the triangle
2218                          * index buffer */
2219                         bm->elem_index_dirty |= BM_VERT;
2220
2221                         GSET_ITER (gs_iter, bm_unique_verts) {
2222                                 gpu_bmesh_vert_to_buffer_copy(BLI_gsetIterator_getKey(&gs_iter),
2223                                                               vert_data, &v_index, NULL, NULL,
2224                                                               cd_vert_mask_offset, diffuse_color);
2225                         }
2226
2227                         GSET_ITER (gs_iter, bm_other_verts) {
2228                                 gpu_bmesh_vert_to_buffer_copy(BLI_gsetIterator_getKey(&gs_iter),
2229                                                               vert_data, &v_index, NULL, NULL,
2230                                                               cd_vert_mask_offset, diffuse_color);
2231                         }
2232
2233                         maxvert = v_index;
2234                 }
2235                 else {
2236                         GSetIterator gs_iter;
2237
2238                         GSET_ITER (gs_iter, bm_faces) {
2239                                 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
2240
2241                                 BLI_assert(f->len == 3);
2242
2243                                 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
2244                                         BMVert *v[3];
2245                                         float fmask = 0;
2246                                         int i;
2247
2248                                         // BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void**)v, 3);
2249                                         BM_face_as_array_vert_tri(f, v);
2250
2251                                         /* Average mask value */
2252                                         for (i = 0; i < 3; i++) {
2253                                                 fmask += BM_ELEM_CD_GET_FLOAT(v[i], cd_vert_mask_offset);
2254                                         }
2255                                         fmask /= 3.0f;
2256                                         
2257                                         for (i = 0; i < 3; i++) {
2258                                                 gpu_bmesh_vert_to_buffer_copy(v[i], vert_data,
2259                                                                               &v_index, f->no, &fmask,
2260                                                                               cd_vert_mask_offset, diffuse_color);
2261                                         }
2262                                 }
2263                         }
2264
2265                         buffers->tot_tri = tottri;
2266                 }
2267
2268                 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
2269
2270                 /* gpu_bmesh_vert_to_buffer_copy sets dirty index values */
2271                 bm->elem_index_dirty |= BM_VERT;
2272         }
2273         else {
2274                 /* Memory map failed */
2275                 glDeleteBuffersARB(1, &buffers->vert_buf);
2276                 buffers->vert_buf = 0;
2277                 return;
2278         }
2279
2280         if (buffers->smooth) {
2281                 const int use_short = (maxvert < USHRT_MAX);
2282
2283                 /* Initialize triangle index buffer */
2284                 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
2285                 glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
2286                                                 (use_short ?
2287                                                  sizeof(unsigned short) :
2288                                                  sizeof(unsigned int)) * 3 * tottri,
2289                                                 NULL, GL_STATIC_DRAW_ARB);
2290
2291                 /* Fill triangle index buffer */
2292                 tri_data = glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
2293                 if (tri_data) {
2294                         GSetIterator gs_iter;
2295
2296                         GSET_ITER (gs_iter, bm_faces) {
2297                                 BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
2298
2299                                 if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
2300                                         BMLoop *l_iter;
2301                                         BMLoop *l_first;
2302
2303                                         l_iter = l_first = BM_FACE_FIRST_LOOP(f);
2304                                         do {
2305                                                 BMVert *v = l_iter->v;
2306                                                 if (use_short) {
2307                                                         unsigned short *elem = tri_data;
2308                                                         (*elem) = BM_elem_index_get(v);
2309                                                         elem++;
2310                                                         tri_data = elem;
2311                                                 }
2312                                                 else {
2313                                                         unsigned int *elem = tri_data;
2314                                                         (*elem) = BM_elem_index_get(v);
2315                                                         elem++;
2316                                                         tri_data = elem;
2317                                                 }
2318                                         } while ((l_iter = l_iter->next) != l_first);
2319                                 }
2320                         }
2321
2322                         glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
2323
2324                         buffers->tot_tri = tottri;
2325                         buffers->index_type = (use_short ?
2326                                                                    GL_UNSIGNED_SHORT :
2327                                                                    GL_UNSIGNED_INT);
2328                 }
2329                 else {
2330                         /* Memory map failed */
2331                         glDeleteBuffersARB(1, &buffers->index_buf);
2332                         buffers->index_buf = 0;
2333                 }
2334         }
2335 }
2336
2337 GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(int smooth_shading)
2338 {
2339         GPU_PBVH_Buffers *buffers;
2340
2341         buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
2342         if (smooth_shading)
2343                 glGenBuffersARB(1, &buffers->index_buf);
2344         glGenBuffersARB(1, &buffers->vert_buf);
2345         buffers->use_bmesh = true;
2346         buffers->smooth = smooth_shading;
2347         buffers->show_diffuse_color = false;
2348         buffers->use_matcaps = false;
2349
2350         return buffers;
2351 }
2352
2353 static void gpu_draw_buffers_legacy_mesh(GPU_PBVH_Buffers *buffers)
2354 {
2355         const MVert *mvert = buffers->mvert;
2356         int i, j;
2357         const int has_mask = (buffers->vmask != NULL);
2358         const MFace *face = &buffers->mface[buffers->face_indices[0]];
2359         float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
2360
2361         if (buffers->use_matcaps)
2362                 diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
2363         else if (buffers->show_diffuse_color)
2364                 GPU_material_diffuse_get(face->mat_nr + 1, diffuse_color);
2365
2366         if (has_mask) {
2367                 gpu_colors_enable(VBO_DISABLED);
2368         }
2369
2370         for (i = 0; i < buffers->totface; ++i) {
2371                 MFace *f = buffers->mface + buffers->face_indices[i];
2372                 int S = f->v4 ? 4 : 3;
2373                 unsigned int *fv = &f->v1;
2374
2375                 if (paint_is_face_hidden(f, buffers->mvert))
2376                         continue;
2377
2378                 glBegin((f->v4) ? GL_QUADS : GL_TRIANGLES);
2379
2380                 if (buffers->smooth) {
2381                         for (j = 0; j < S; j++) {
2382                                 if (has_mask) {
2383                                         gpu_color_from_mask_set(buffers->vmask[fv[j]], diffuse_color);
2384                                 }
2385                                 glNormal3sv(mvert[fv[j]].no);
2386                                 glVertex3fv(mvert[fv[j]].co);
2387                         }
2388                 }
2389                 else {
2390                         float fno[3];
2391
2392                         /* calculate face normal */
2393                         if (f->v4) {
2394                                 normal_quad_v3(fno, mvert[fv[0]].co, mvert[fv[1]].co,
2395                                                mvert[fv[2]].co, mvert[fv[3]].co);
2396                         }
2397                         else
2398                                 normal_tri_v3(fno, mvert[fv[0]].co, mvert[fv[1]].co, mvert[fv[2]].co);
2399                         glNormal3fv(fno);
2400
2401                         if (has_mask) {
2402                                 float fmask;
2403
2404                                 /* calculate face mask color */
2405                                 fmask = (buffers->vmask[fv[0]] +
2406                                          buffers->vmask[fv[1]] +
2407                                          buffers->vmask[fv[2]]);
2408                                 if (f->v4)
2409                                         fmask = (fmask + buffers->vmask[fv[3]]) * 0.25f;
2410                                 else
2411                                         fmask /= 3.0f;
2412                                 gpu_color_from_mask_set(fmask, diffuse_color);
2413                         }
2414                         
2415                         for (j = 0; j < S; j++)
2416                                 glVertex3fv(mvert[fv[j]].co);
2417                 }
2418                 
2419                 glEnd();
2420         }
2421
2422         if (has_mask) {
2423                 gpu_colors_disable(VBO_DISABLED);
2424         }
2425 }
2426
2427 static void gpu_draw_buffers_legacy_grids(GPU_PBVH_Buffers *buffers)
2428 {
2429         const CCGKey *key = &buffers->gridkey;
2430         int i, j, x, y, gridsize = buffers->gridkey.grid_size;
2431         const int has_mask = key->has_mask;
2432         const DMFlagMat *flags = &buffers->grid_flag_mats[buffers->grid_indices[0]];
2433         float diffuse_color[4] = {0.8f, 0.8f, 0.8f, 1.0f};
2434
2435         if (buffers->use_matcaps)
2436                 diffuse_color[0] = diffuse_color[1] = diffuse_color[2] = 1.0;
2437         else if (buffers->show_diffuse_color)
2438                 GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
2439
2440         if (has_mask) {
2441                 gpu_colors_enable(VBO_DISABLED);
2442         }
2443
2444         for (i = 0; i < buffers->totgrid; ++i) {
2445                 int g = buffers->grid_indices[i];
2446                 CCGElem *grid = buffers->grids[g];
2447                 BLI_bitmap *gh = buffers->grid_hidden[g];
2448
2449                 /* TODO: could use strips with hiding as well */
2450
2451                 if (gh) {
2452                         glBegin(GL_QUADS);
2453                         
2454                         for (y = 0; y < gridsize - 1; y++) {
2455                                 for (x = 0; x < gridsize - 1; x++) {
2456                                         CCGElem *e[4] = {
2457                                                 CCG_grid_elem(key, grid, x + 1, y + 1),
2458                                                 CCG_grid_elem(key, grid, x + 1, y),
2459                                                 CCG_grid_elem(key, grid, x, y),
2460                                                 CCG_grid_elem(key, grid, x, y + 1)
2461                                         };
2462
2463                                         /* skip face if any of its corners are hidden */
2464                                         if (paint_is_grid_face_hidden(gh, gridsize, x, y))
2465                                                 continue;
2466
2467                                         if (buffers->smooth) {
2468                                                 for (j = 0; j < 4; j++) {
2469                                                         if (has_mask) {
2470                                                                 gpu_color_from_mask_set(*CCG_elem_mask(key, e[j]), diffuse_color);
2471                                                         }
2472                                                         glNormal3fv(CCG_elem_no(key, e[j]));
2473                                                         glVertex3fv(CCG_elem_co(key, e[j]));
2474                                                 }
2475                                         }
2476                                         else {
2477                                                 float fno[3];
2478                                                 normal_quad_v3(fno,
2479                                                                CCG_elem_co(key, e[0]),
2480                                                                CCG_elem_co(key, e[1]),
2481                                                                CCG_elem_co(key, e[2]),
2482                                                                CCG_elem_co(key, e[3]));
2483                                                 glNormal3fv(fno);
2484
2485                                                 if (has_mask) {
2486                                                         gpu_color_from_mask_quad_set(key, e[0], e[1], e[2], e[3], diffuse_color);
2487                                                 }
2488
2489                                                 for (j = 0; j < 4; j++)
2490                                                         glVertex3fv(CCG_elem_co(key, e[j]));
2491                                         }
2492                                 }
2493                         }
2494
2495                         glEnd();
2496                 }
2497                 else if (buffers->smooth) {
2498                         for (y = 0; y < gridsize - 1; y++) {
2499                                 glBegin(GL_QUAD_STRIP);
2500                                 for (x = 0; x < gridsize; x++) {
2501                                         CCGElem *a = CCG_grid_elem(key, grid, x, y);
2502                                         CCGElem *b = CCG_grid_elem(key, grid, x, y + 1);
2503
2504                                         if (has_mask) {
2505                                                 gpu_color_from_mask_set(*CCG_elem_mask(key, a), diffuse_color);
2506                                         }
2507                                         glNormal3fv(CCG_elem_no(key, a));
2508                                         glVertex3fv(CCG_elem_co(key, a));
2509                                         if (has_mask) {
2510                                                 gpu_color_from_mask_set(*CCG_elem_mask(key, b), diffuse_color);
2511                                         }
2512                                         glNormal3fv(CCG_elem_no(key, b));
2513                                         glVertex3fv(CCG_elem_co(key, b));
2514                                 }
2515                                 glEnd();
2516                         }
2517                 }
2518                 else {
2519                         for (y = 0; y < gridsize - 1; y++) {
2520                                 glBegin(GL_QUAD_STRIP);
2521                                 for (x = 0; x < gridsize; x++) {
2522                                         CCGElem *a = CCG_grid_elem(key, grid, x, y);
2523                                         CCGElem *b = CCG_grid_elem(key, grid, x, y + 1);
2524
2525                                         if (x > 0) {
2526                                                 CCGElem *c = CCG_grid_elem(key, grid, x - 1, y);
2527                                                 CCGElem *d = CCG_grid_elem(key, grid, x - 1, y + 1);
2528
2529                                                 float fno[3];
2530                                                 normal_quad_v3(fno,
2531                                                                CCG_elem_co(key, d),
2532                                                                CCG_elem_co(key, b),
2533                                                                CCG_elem_co(key, a),
2534                                                                CCG_elem_co(key, c));
2535                                                 glNormal3fv(fno);
2536
2537                                                 if (has_mask) {
2538                                                         gpu_color_from_mask_quad_set(key, a, b, c, d, diffuse_color);
2539                                                 }
2540                                         }
2541
2542                                         glVertex3fv(CCG_elem_co(key, a));
2543                                         glVertex3fv(CCG_elem_co(key, b));
2544                                 }
2545                                 glEnd();
2546                         }
2547                 }
2548         }
2549
2550         if (has_mask) {
2551                 gpu_colors_disable(VBO_DISABLED);
2552         }
2553 }
2554
2555 void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
2556                            bool wireframe)
2557 {
2558         /* sets material from the first face, to solve properly face would need to
2559          * be sorted in buckets by materials */
2560         if (setMaterial) {
2561                 if (buffers->totface) {
2562                         const MFace *f = &buffers->mface[buffers->face_indices[0]];
2563                         if (!setMaterial(f->mat_nr + 1, NULL))
2564                                 return;
2565                 }
2566                 else if (buffers->totgrid) {
2567                         const DMFlagMat *f = &buffers->grid_flag_mats[buffers->grid_indices[0]];
2568                         if (!setMaterial(f->mat_nr + 1, NULL))
2569                                 return;
2570                 }
2571                 else {
2572                         if (!setMaterial(1, NULL))
2573                                 return;
2574                 }
2575         }
2576
2577         glShadeModel((buffers->smooth || buffers->totface) ? GL_SMOOTH : GL_FLAT);
2578
2579         if (buffers->vert_buf) {
2580                 glEnableClientState(GL_VERTEX_ARRAY);
2581                 if (!wireframe) {
2582                         glEnableClientState(GL_NORMAL_ARRAY);
2583                         gpu_colors_enable(VBO_ENABLED);
2584                 }
2585
2586                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
2587
2588                 if (buffers->index_buf)
2589                         glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
2590
2591                 if (wireframe)
2592                         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
2593
2594                 if (buffers->tot_quad) {
2595                         const char *offset = 0;
2596                         int i, last = buffers->has_hidden ? 1 : buffers->totgrid;
2597                         for (i = 0; i < last; i++) {
2598                                 glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
2599                                                 offset + offsetof(VertexBufferFormat, co));
2600                                 glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
2601                                                 offset + offsetof(VertexBufferFormat, no));
2602                                 glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
2603                                                offset + offsetof(VertexBufferFormat, color));
2604                                 
2605                                 glDrawElements(GL_TRIANGLES, buffers->tot_quad * 6, buffers->index_type, 0);
2606
2607                                 offset += buffers->gridkey.grid_area * sizeof(VertexBufferFormat);
2608                         }
2609                 }
2610                 else if (buffers->tot_tri) {
2611                         int totelem = buffers->tot_tri * 3;
2612
2613                         glVertexPointer(3, GL_FLOAT, sizeof(VertexBufferFormat),
2614                                         (void *)offsetof(VertexBufferFormat, co));
2615                         glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
2616                                         (void *)offsetof(VertexBufferFormat, no));
2617                         glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
2618                                        (void *)offsetof(VertexBufferFormat, color));
2619
2620                         if (buffers->index_buf)
2621                                 glDrawElements(GL_TRIANGLES, totelem, buffers->index_type, 0);
2622                         else
2623                                 glDrawArrays(GL_TRIANGLES, 0, totelem);
2624                 }
2625
2626                 if (wireframe)
2627                         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
2628
2629                 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
2630                 if (buffers->index_buf)
2631                         glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
2632
2633                 glDisableClientState(GL_VERTEX_ARRAY);
2634                 if (!wireframe) {
2635                         glDisableClientState(GL_NORMAL_ARRAY);
2636                         gpu_colors_disable(VBO_ENABLED);
2637                 }
2638         }
2639         /* fallbacks if we are out of memory or VBO is disabled */
2640         else if (buffers->totface) {
2641                 gpu_draw_buffers_legacy_mesh(buffers);
2642         }
2643         else if (buffers->totgrid) {
2644                 gpu_draw_buffers_legacy_grids(buffers);
2645         }
2646 }
2647
2648 bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces, bool show_diffuse_color)
2649 {
2650         float diffuse_color[4];
2651         bool use_matcaps = GPU_material_use_matcaps_get();
2652
2653         if (buffers->show_diffuse_color != show_diffuse_color)
2654                 return true;
2655
2656         if (buffers->use_matcaps != use_matcaps)
2657                 return true;
2658
2659         if ((buffers->show_diffuse_color == false) || use_matcaps)
2660                 return false;
2661
2662         if (buffers->mface) {
2663                 MFace *f = buffers->mface + buffers->face_indices[0];
2664
2665                 GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
2666         }
2667         else if (buffers->use_bmesh) {
2668                 /* due to dynamc nature of dyntopo, only get first material */
2669                 if (BLI_gset_size(bm_faces) > 0) {
2670                         GSetIterator gs_iter;
2671                         BMFace *f;
2672
2673                         BLI_gsetIterator_init(&gs_iter, bm_faces);
2674                         f = BLI_gsetIterator_getKey(&gs_iter);
2675                         GPU_material_diffuse_get(f->mat_nr + 1, diffuse_color);
2676                 }
2677                 else {
2678                         return false;
2679                 }
2680         }
2681         else {
2682                 const DMFlagMat *flags = &buffers->grid_flag_mats[buffers->grid_indices[0]];
2683
2684                 GPU_material_diffuse_get(flags->mat_nr + 1, diffuse_color);
2685         }
2686
2687         return !equals_v3v3(diffuse_color, buffers->diffuse_color);
2688 }
2689
2690 /* release a GPU_PBVH_Buffers id;
2691  *
2692  * Thread-unsafe version for internal usage only.
2693  */
2694 static void gpu_pbvh_buffer_free_intern(GLuint id)
2695 {
2696         GPUBufferPool *pool;
2697
2698         /* zero id is vertex buffers off */
2699         if (!id)
2700                 return;
2701
2702         pool = gpu_get_global_buffer_pool();
2703
2704         /* free the buffers immediately if we are on main thread */
2705         if (BLI_thread_is_main()) {
2706                 glDeleteBuffersARB(1, &id);
2707
2708                 if (pool->totpbvhbufids > 0) {
2709                         glDeleteBuffersARB(pool->totpbvhbufids, pool->pbvhbufids);
2710                         pool->totpbvhbufids = 0;
2711                 }
2712                 return;
2713         }
2714         /* outside of main thread, can't safely delete the
2715          * buffer, so increase pool size */
2716         if (pool->maxpbvhsize == pool->totpbvhbufids) {
2717                 pool->maxpbvhsize += MAX_FREE_GPU_BUFF_IDS;
2718                 pool->pbvhbufids = MEM_reallocN(pool->pbvhbufids,
2719                                                                                 sizeof(*pool->pbvhbufids) * pool->maxpbvhsize);
2720         }
2721
2722         /* insert the buffer into the beginning of the pool */
2723         pool->pbvhbufids[pool->totpbvhbufids++] = id;
2724 }
2725
2726
2727 void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers)
2728 {
2729         if (buffers) {
2730                 if (buffers->vert_buf)
2731                         gpu_pbvh_buffer_free_intern(buffers->vert_buf);
2732                 if (buffers->index_buf && (buffers->tot_tri || buffers->has_hidden))
2733                         gpu_pbvh_buffer_free_intern(buffers->index_buf);
2734
2735                 MEM_freeN(buffers);
2736         }
2737 }
2738
2739
2740 /* debug function, draws the pbvh BB */
2741 void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf)
2742 {
2743         const float quads[4][4][3] = {
2744             {
2745                 {min[0], min[1], min[2]},
2746                 {max[0], min[1], min[2]},
2747                 {max[0], min[1], max[2]},
2748                 {min[0], min[1], max[2]}
2749             },
2750
2751             {
2752                 {min[0], min[1], min[2]},
2753                 {min[0], max[1], min[2]},
2754                 {min[0], max[1], max[2]},
2755                 {min[0], min[1], max[2]}
2756             },
2757
2758             {
2759                 {max[0], max[1], min[2]},
2760                 {max[0], min[1], min[2]},
2761                 {max[0], min[1], max[2]},
2762                 {max[0], max[1], max[2]}
2763             },
2764
2765             {
2766                 {max[0], max[1], min[2]},
2767                 {min[0], max[1], min[2]},
2768                 {min[0], max[1], max[2]},
2769                 {max[0], max[1], max[2]}
2770             },
2771         };
2772
2773         if (leaf)
2774                 glColor4f(0.0, 1.0, 0.0, 0.5);
2775         else
2776                 glColor4f(1.0, 0.0, 0.0, 0.5);
2777
2778         glVertexPointer(3, GL_FLOAT, 0, &quads[0][0][0]);
2779         glDrawArrays(GL_QUADS, 0, 16);
2780 }
2781
2782 void GPU_init_draw_pbvh_BB(void)
2783 {
2784         glPushAttrib(GL_ENABLE_BIT);
2785         glDisable(GL_CULL_FACE);
2786         glEnableClientState(GL_VERTEX_ARRAY);
2787         glDisableClientState(GL_COLOR_ARRAY);
2788         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
2789         glDisable(GL_LIGHTING);
2790         glDisable(GL_COLOR_MATERIAL);
2791         glEnable(GL_BLEND);
2792         glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
2793 }
2794
2795 void GPU_end_draw_pbvh_BB(void)
2796 {
2797         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
2798         glPopAttrib();
2799 }