VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_bufferobject.c@ 22832

最後變更 在這個檔案從22832是 22832,由 vboxsync 提交於 15 年 前

crOpenGL: only check for diff_api on host side

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 24.6 KB
 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "state.h"
8#include "state/cr_statetypes.h"
9#include "state/cr_statefuncs.h"
10#include "state_internals.h"
11#include "cr_mem.h"
12#include "cr_string.h"
13
14
15static CRBufferObject *AllocBufferObject(GLuint name)
16{
17 CRBufferObject *b = crCalloc(sizeof(CRBufferObject));
18 if (b) {
19 b->refCount = 1;
20 b->name = name;
21 b->usage = GL_STATIC_DRAW_ARB;
22 b->access = GL_READ_WRITE_ARB;
23 }
24 return b;
25}
26
27
28void crStateBufferObjectInit (CRContext *ctx)
29{
30 CRStateBits *sb = GetCurrentBits();
31 CRBufferObjectBits *bb = &sb->bufferobject;
32 CRBufferObjectState *b = &ctx->bufferobject;
33
34 RESET(bb->dirty, ctx->bitid);
35 RESET(bb->arrayBinding, ctx->bitid);
36 RESET(bb->elementsBinding, ctx->bitid);
37
38#ifdef IN_GUEST
39 b->retainBufferData = GL_TRUE;
40#else
41 b->retainBufferData = GL_FALSE;
42#endif
43
44 b->nullBuffer = AllocBufferObject(0);
45 b->arrayBuffer = b->nullBuffer;
46 b->elementsBuffer = b->nullBuffer;
47 b->nullBuffer->refCount = 3;
48
49 b->buffers = crAllocHashtable();
50}
51
52
53static void crStateFreeBufferObject(void *data)
54{
55 CRBufferObject *pObj = (CRBufferObject *)data;
56 if (pObj->data) crFree(pObj->data);
57
58#ifndef IN_GUEST
59 if (diff_api.DeleteBuffersARB)
60 {
61 diff_api.DeleteBuffersARB(1, &pObj->name);
62 }
63#endif
64
65 crFree(pObj);
66}
67
68void crStateBufferObjectDestroy (CRContext *ctx)
69{
70 CRBufferObjectState *b = &ctx->bufferobject;
71 crFreeHashtable(b->buffers, crStateFreeBufferObject);
72 crFree(b->nullBuffer);
73}
74
75
76void STATE_APIENTRY
77crStateBindBufferARB (GLenum target, GLuint buffer)
78{
79 CRContext *g = GetCurrentContext();
80 CRBufferObjectState *b = &(g->bufferobject);
81 CRStateBits *sb = GetCurrentBits();
82 CRBufferObjectBits *bb = &(sb->bufferobject);
83 CRBufferObject *oldObj, *newObj;
84
85 if (g->current.inBeginEnd) {
86 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
87 "glBindBufferARB called in begin/end");
88 return;
89 }
90
91 FLUSH();
92
93 if (target == GL_ARRAY_BUFFER_ARB) {
94 oldObj = b->arrayBuffer;
95 }
96 else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
97 oldObj = b->elementsBuffer;
98 }
99 else {
100 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
101 "glBindBufferARB(target)");
102 return;
103 }
104
105 if (buffer == 0) {
106 newObj = b->nullBuffer;
107 }
108 else {
109 newObj = (CRBufferObject *) crHashtableSearch(b->buffers, buffer);
110 if (!newObj) {
111 newObj = AllocBufferObject(buffer);
112 if (!newObj) {
113 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "glBindBuffer");
114 return;
115 }
116 crHashtableAdd( b->buffers, buffer, newObj );
117 }
118 }
119
120 newObj->refCount++;
121 oldObj->refCount--;
122
123 if (target == GL_ARRAY_BUFFER_ARB) {
124 b->arrayBuffer = newObj;
125 DIRTY(bb->dirty, g->neg_bitid);
126 DIRTY(bb->arrayBinding, g->neg_bitid);
127 }
128 else {
129 CRASSERT(target == GL_ELEMENT_ARRAY_BUFFER_ARB);
130 b->elementsBuffer = newObj;
131 DIRTY(bb->dirty, g->neg_bitid);
132 DIRTY(bb->elementsBinding, g->neg_bitid);
133 }
134
135 if (oldObj->refCount <= 0) {
136 /*we shouldn't reach this point*/
137 CRASSERT(false);
138 crHashtableDelete(b->buffers, (unsigned long) oldObj->name, crStateFreeBufferObject);
139 }
140}
141
142void STATE_APIENTRY
143crStateDeleteBuffersARB(GLsizei n, const GLuint *buffers)
144{
145 CRContext *g = GetCurrentContext();
146 CRBufferObjectState *b = &(g->bufferobject);
147 CRStateBits *sb = GetCurrentBits();
148 CRBufferObjectBits *bb = &(sb->bufferobject);
149 int i;
150
151 FLUSH();
152
153 if (g->current.inBeginEnd) {
154 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
155 "glDeleteBuffersARB called in Begin/End");
156 return;
157 }
158
159 if (n < 0) {
160 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
161 "glDeleteBuffersARB(n < 0)");
162 return;
163 }
164
165 for (i = 0; i < n; i++) {
166 if (buffers[i]) {
167 CRBufferObject *obj = (CRBufferObject *)
168 crHashtableSearch(b->buffers, buffers[i]);
169 if (obj) {
170 if (obj == b->arrayBuffer) {
171 b->arrayBuffer = b->nullBuffer;
172 b->arrayBuffer->refCount++;
173 DIRTY(bb->dirty, g->neg_bitid);
174 DIRTY(bb->arrayBinding, g->neg_bitid);
175 }
176 if (obj == b->elementsBuffer) {
177 b->elementsBuffer = b->nullBuffer;
178 b->elementsBuffer->refCount++;
179 DIRTY(bb->dirty, g->neg_bitid);
180 DIRTY(bb->elementsBinding, g->neg_bitid);
181 }
182 /* @todo check bindings with the vertex arrays */
183
184 crHashtableDelete(b->buffers, buffers[i], crStateFreeBufferObject);
185 }
186 }
187 }
188}
189
190
191void STATE_APIENTRY
192crStateGenBuffersARB(GLsizei n, GLuint * buffers)
193{
194 CRContext *g = GetCurrentContext();
195 CRBufferObjectState *b = &(g->bufferobject);
196 GLint start;
197
198 FLUSH();
199
200 if (g->current.inBeginEnd) {
201 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
202 "glGenBuffersARB called in Begin/End");
203 return;
204 }
205
206 if (n < 0) {
207 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
208 "glGenBuffersARB(n < 0)");
209 return;
210 }
211
212 start = crHashtableAllocKeys(b->buffers, n);
213 if (start) {
214 GLint i;
215 for (i = 0; i < n; i++)
216 buffers[i] = (GLuint) (start + i);
217 }
218 else {
219 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "glGenBuffersARB");
220 }
221}
222
223
224GLboolean STATE_APIENTRY
225crStateIsBufferARB(GLuint buffer)
226{
227 CRContext *g = GetCurrentContext();
228 CRBufferObjectState *b = &g->bufferobject;
229
230 FLUSH();
231
232 if (g->current.inBeginEnd) {
233 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
234 "glIsBufferARB called in begin/end");
235 return GL_FALSE;
236 }
237
238 if (buffer && crHashtableSearch(b->buffers, buffer))
239 return GL_TRUE;
240 else
241 return GL_FALSE;
242}
243
244
245void STATE_APIENTRY
246crStateBufferDataARB(GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage)
247{
248 CRContext *g = GetCurrentContext();
249 CRBufferObjectState *b = &g->bufferobject;
250 CRBufferObject *obj;
251 CRStateBits *sb = GetCurrentBits();
252 CRBufferObjectBits *bb = &sb->bufferobject;
253
254 FLUSH();
255
256 if (g->current.inBeginEnd) {
257 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
258 "glBufferDataARB called in begin/end");
259 return;
260 }
261
262 if (size < 0) {
263 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
264 "glBufferDataARB(size < 0)");
265 return;
266 }
267
268 switch (usage) {
269 case GL_STREAM_DRAW_ARB:
270 case GL_STREAM_READ_ARB:
271 case GL_STREAM_COPY_ARB:
272 case GL_STATIC_DRAW_ARB:
273 case GL_STATIC_READ_ARB:
274 case GL_STATIC_COPY_ARB:
275 case GL_DYNAMIC_DRAW_ARB:
276 case GL_DYNAMIC_READ_ARB:
277 case GL_DYNAMIC_COPY_ARB:
278 /* OK */
279 break;
280 default:
281 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
282 "glBufferDataARB(usage)");
283 return;
284 }
285
286 if (target == GL_ARRAY_BUFFER_ARB) {
287 obj = b->arrayBuffer;
288 }
289 else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
290 obj = b->elementsBuffer;
291 }
292 else {
293 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
294 "glBufferDataARB(target)");
295 return;
296 }
297
298 if (obj->name == 0) {
299 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glBufferDataARB");
300 return;
301 }
302
303 if (obj->pointer) {
304 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
305 "glBufferDataARB(buffer is mapped)");
306 return;
307 }
308
309 obj->usage = usage;
310 obj->size = size;
311
312 /* The user of the state tracker should set the retainBufferData field
313 * during context initialization, if needed.
314 */
315 if (b->retainBufferData) {
316 if (obj->data) {
317 crFree(obj->data);
318 }
319
320 obj->data = crAlloc(size);
321 if (!obj->data) {
322 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "glBufferDataARB");
323 return;
324 }
325 if (data)
326 crMemcpy(obj->data, data, size);
327 }
328
329 DIRTY(bb->dirty, g->neg_bitid);
330 DIRTY(obj->dirty, g->neg_bitid);
331 obj->dirtyStart = 0;
332 obj->dirtyLength = size;
333}
334
335
336void STATE_APIENTRY
337crStateBufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data)
338{
339 CRContext *g = GetCurrentContext();
340 CRBufferObjectState *b = &g->bufferobject;
341 CRBufferObject *obj;
342 CRStateBits *sb = GetCurrentBits();
343 CRBufferObjectBits *bb = &sb->bufferobject;
344
345 FLUSH();
346
347 if (g->current.inBeginEnd) {
348 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
349 "glBufferSubDataARB called in begin/end");
350 return;
351 }
352
353 if (target == GL_ARRAY_BUFFER_ARB) {
354 obj = b->arrayBuffer;
355 }
356 else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
357 obj = b->elementsBuffer;
358 }
359 else {
360 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
361 "glBufferSubDataARB(target)");
362 return;
363 }
364
365 if (obj->name == 0) {
366 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
367 "glBufferSubDataARB");
368 return;
369 }
370
371 if (obj->pointer) {
372 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
373 "glBufferSubDataARB(buffer is mapped)");
374 return;
375 }
376
377 if (size < 0 || offset < 0 || (unsigned int)offset + size > obj->size) {
378 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
379 "glBufferSubDataARB(bad offset and/or size)");
380 return;
381 }
382
383 if (b->retainBufferData && obj->data) {
384 crMemcpy((char *) obj->data + offset, data, size);
385 }
386
387 DIRTY(bb->dirty, g->neg_bitid);
388 DIRTY(obj->dirty, g->neg_bitid);
389 /* grow dirty region */
390 if (offset + size > obj->dirtyStart + obj->dirtyLength)
391 obj->dirtyLength = offset + size;
392 if (offset < obj->dirtyStart)
393 obj->dirtyStart = offset;
394}
395
396
397void STATE_APIENTRY
398crStateGetBufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, void * data)
399{
400 CRContext *g = GetCurrentContext();
401 CRBufferObjectState *b = &g->bufferobject;
402 CRBufferObject *obj;
403
404 FLUSH();
405
406 if (g->current.inBeginEnd) {
407 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
408 "glGetBufferSubDataARB called in begin/end");
409 return;
410 }
411
412 if (target == GL_ARRAY_BUFFER_ARB) {
413 obj = b->arrayBuffer;
414 }
415 else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
416 obj = b->elementsBuffer;
417 }
418 else {
419 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
420 "glGetBufferSubDataARB(target)");
421 return;
422 }
423
424 if (obj->name == 0) {
425 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
426 "glGetBufferSubDataARB");
427 return;
428 }
429
430 if (obj->pointer) {
431 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
432 "glGetBufferSubDataARB(buffer is mapped)");
433 return;
434 }
435
436 if (size < 0 || offset < 0 || (unsigned int)offset + size > obj->size) {
437 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
438 "glGetBufferSubDataARB(bad offset and/or size)");
439 return;
440 }
441
442 if (b->retainBufferData && obj->data) {
443 crMemcpy(data, (char *) obj->data + offset, size);
444 }
445}
446
447
448void * STATE_APIENTRY
449crStateMapBufferARB(GLenum target, GLenum access)
450{
451 CRContext *g = GetCurrentContext();
452 CRBufferObjectState *b = &g->bufferobject;
453 CRBufferObject *obj;
454
455 FLUSH();
456
457 if (g->current.inBeginEnd) {
458 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
459 "glMapBufferARB called in begin/end");
460 return NULL;
461 }
462
463 if (target == GL_ARRAY_BUFFER_ARB) {
464 obj = b->arrayBuffer;
465 }
466 else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
467 obj = b->elementsBuffer;
468 }
469 else {
470 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
471 "glMapBufferARB(target)");
472 return NULL;
473 }
474
475 if (obj->name == 0) {
476 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glMapBufferARB");
477 return GL_FALSE;
478 }
479
480 switch (access) {
481 case GL_READ_ONLY_ARB:
482 case GL_WRITE_ONLY_ARB:
483 case GL_READ_WRITE_ARB:
484 obj->access = access;
485 break;
486 default:
487 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
488 "glMapBufferARB(access)");
489 return NULL;
490 }
491
492 if (b->retainBufferData && obj->data)
493 obj->pointer = obj->data;
494
495 return obj->pointer;
496}
497
498
499GLboolean STATE_APIENTRY
500crStateUnmapBufferARB(GLenum target)
501{
502 CRContext *g = GetCurrentContext();
503 CRBufferObjectState *b = &g->bufferobject;
504 CRBufferObject *obj;
505 CRStateBits *sb = GetCurrentBits();
506 CRBufferObjectBits *bb = &sb->bufferobject;
507
508 FLUSH();
509
510 if (g->current.inBeginEnd) {
511 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
512 "glUnmapBufferARB called in begin/end");
513 return GL_FALSE;
514 }
515
516 if (target == GL_ARRAY_BUFFER_ARB) {
517 obj = b->arrayBuffer;
518 }
519 else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
520 obj = b->elementsBuffer;
521 }
522 else {
523 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
524 "glUnmapBufferARB(target)");
525 return GL_FALSE;
526 }
527
528 if (obj->name == 0) {
529 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glUnmapBufferARB");
530 return GL_FALSE;
531 }
532
533 if (!obj->pointer) {
534 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glUnmapBufferARB");
535 return GL_FALSE;
536 }
537
538 obj->pointer = NULL;
539
540 if (obj->access != GL_READ_ONLY_ARB) {
541 /* the data was most likely modified */
542 DIRTY(bb->dirty, g->neg_bitid);
543 DIRTY(obj->dirty, g->neg_bitid);
544 obj->dirtyStart = 0;
545 obj->dirtyLength = obj->size;
546 }
547
548 return GL_TRUE;
549}
550
551
552void STATE_APIENTRY
553crStateGetBufferParameterivARB(GLenum target, GLenum pname, GLint *params)
554{
555 CRContext *g = GetCurrentContext();
556 CRBufferObjectState *b = &g->bufferobject;
557 CRBufferObject *obj;
558
559 FLUSH();
560
561 if (g->current.inBeginEnd) {
562 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
563 "glGetBufferParameterivARB called in begin/end");
564 return;
565 }
566
567 if (target == GL_ARRAY_BUFFER_ARB) {
568 obj = b->arrayBuffer;
569 }
570 else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
571 obj = b->elementsBuffer;
572 }
573 else {
574 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
575 "glGetBufferParameterivARB(target)");
576 return;
577 }
578
579 switch (pname) {
580 case GL_BUFFER_SIZE_ARB:
581 *params = obj->size;
582 break;
583 case GL_BUFFER_USAGE_ARB:
584 *params = obj->usage;
585 break;
586 case GL_BUFFER_ACCESS_ARB:
587 *params = obj->access;
588 break;
589 case GL_BUFFER_MAPPED_ARB:
590 *params = (obj->pointer != NULL);
591 break;
592 default:
593 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
594 "glGetBufferParameterivARB(pname)");
595 return;
596 }
597}
598
599
600void STATE_APIENTRY
601crStateGetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params)
602{
603 CRContext *g = GetCurrentContext();
604 CRBufferObjectState *b = &g->bufferobject;
605 CRBufferObject *obj;
606
607 FLUSH();
608
609 if (g->current.inBeginEnd) {
610 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
611 "glGetBufferPointervARB called in begin/end");
612 return;
613 }
614
615 if (target == GL_ARRAY_BUFFER_ARB) {
616 obj = b->arrayBuffer;
617 }
618 else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
619 obj = b->elementsBuffer;
620 }
621 else {
622 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
623 "glGetBufferPointervARB(target)");
624 return;
625 }
626
627 if (pname != GL_BUFFER_MAP_POINTER_ARB) {
628 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
629 "glGetBufferPointervARB(pname)");
630 return;
631 }
632
633 *params = obj->pointer;
634}
635
636
637/**
638 * We need to check if the GL_EXT_vertex/pixel_buffer_object extensions
639 * are supported before calling any of the diff_api functions.
640 * This flag indidcates if the extensions is available (1), not available (0)
641 * or needs to be tested for (-1).
642 * If we don't do this, we can segfault inside OpenGL.
643 * Ideally, the render SPU should no-op unsupported GL functions, but
644 * that's a bit complicated.
645 */
646static GLboolean
647HaveBufferObjectExtension(void)
648{
649 static GLint haveBufferObjectExt = -1;
650
651 if (haveBufferObjectExt == -1) {
652 const char *ext;
653 /* XXX this check is temporary. We need to make the tilesort SPU plug
654 * GetString into the diff'ing table in order for this to really work.
655 */
656 if (!diff_api.GetString) {
657 haveBufferObjectExt = 0;
658 return 0;
659 }
660 CRASSERT(diff_api.GetString);
661 ext = (const char *) diff_api.GetString(GL_EXTENSIONS);
662 if (crStrstr(ext, "GL_ARB_vertex_buffer_object") ||
663 crStrstr(ext, "GL_ARB_pixel_buffer_object")) {
664 haveBufferObjectExt = 1;
665 }
666 else {
667 haveBufferObjectExt = 0;
668 }
669 }
670 return haveBufferObjectExt;
671}
672
673
674void crStateBufferObjectDiff(CRBufferObjectBits *bb, CRbitvalue *bitID,
675 CRContext *fromCtx, CRContext *toCtx)
676{
677 CRBufferObjectState *from = &(fromCtx->bufferobject);
678 const CRBufferObjectState *to = &(toCtx->bufferobject);
679
680 if (!HaveBufferObjectExtension())
681 return;
682
683 /* ARRAY_BUFFER binding */
684 if (CHECKDIRTY(bb->arrayBinding, bitID)) {
685 if (from->arrayBuffer != to->arrayBuffer) {
686 GLuint bufferID = to->arrayBuffer ? to->arrayBuffer->name : 0;
687 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, bufferID);
688 CLEARDIRTY2(bb->arrayBinding, bitID);
689 from->arrayBuffer = to->arrayBuffer;
690 }
691 }
692
693 if (to->arrayBuffer && CHECKDIRTY(to->arrayBuffer->dirty, bitID)) {
694 /* update array buffer data */
695 CRBufferObject *bufObj = to->arrayBuffer;
696 CRASSERT(bufObj);
697 if (bufObj->dirtyStart == 0 && bufObj->dirtyLength == (int) bufObj->size) {
698 /* update whole buffer */
699 diff_api.BufferDataARB(GL_ARRAY_BUFFER_ARB, bufObj->size,
700 bufObj->data, bufObj->usage);
701 }
702 else {
703 /* update sub buffer */
704 diff_api.BufferSubDataARB(GL_ARRAY_BUFFER_ARB,
705 bufObj->dirtyStart,
706 bufObj->dirtyLength,
707 (char *) bufObj->data
708 + bufObj->dirtyStart);
709 }
710 CLEARDIRTY2(bufObj->dirty, bitID);
711#if 0
712 bufObj->dirtyStart = 0;
713 bufObj->dirtyLength = 0;
714#endif
715 }
716
717 /* ELEMENTS_BUFFER binding */
718 if (CHECKDIRTY(bb->elementsBinding, bitID)) {
719 if (from->elementsBuffer != to->elementsBuffer) {
720 GLuint bufferID = to->elementsBuffer ? to->elementsBuffer->name : 0;
721 diff_api.BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, bufferID);
722 CLEARDIRTY2(bb->elementsBinding, bitID);
723 from->elementsBuffer = to->elementsBuffer;
724 }
725 }
726
727 if (to->elementsBuffer && CHECKDIRTY(to->elementsBuffer->dirty, bitID)) {
728 /* update element buffer data */
729 CRBufferObject *bufObj = to->elementsBuffer;
730 CRASSERT(bufObj);
731 if (bufObj->dirtyStart == 0 && bufObj->dirtyLength == (int) bufObj->size) {
732 /* update whole buffer */
733 diff_api.BufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, bufObj->size,
734 bufObj->data, bufObj->usage);
735 }
736 else {
737 /* update sub buffer */
738 diff_api.BufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
739 bufObj->dirtyStart,
740 bufObj->dirtyLength,
741 (char *) bufObj->data
742 + bufObj->dirtyStart);
743 }
744 CLEARDIRTY2(bufObj->dirty, bitID);
745#if 0
746 bufObj->dirtyStart = 0;
747 bufObj->dirtyLength = 0;
748#endif
749 }
750}
751
752
753/*
754 * XXX this function might need some testing/fixing.
755 */
756void crStateBufferObjectSwitch(CRBufferObjectBits *bb, CRbitvalue *bitID,
757 CRContext *fromCtx, CRContext *toCtx)
758{
759 const CRBufferObjectState *from = &(fromCtx->bufferobject);
760 const CRBufferObjectState *to = &(toCtx->bufferobject);
761
762 if (!HaveBufferObjectExtension())
763 return;
764
765 /* ARRAY_BUFFER binding */
766 if (CHECKDIRTY(bb->arrayBinding, bitID)) {
767 if (from->arrayBuffer != to->arrayBuffer) {
768 GLuint bufferID = to->arrayBuffer ? to->arrayBuffer->name : 0;
769 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, bufferID);
770 FILLDIRTY(bb->arrayBinding);
771 }
772 CLEARDIRTY2(bb->arrayBinding, bitID);
773 }
774
775 if (to->arrayBuffer && CHECKDIRTY(to->arrayBuffer->dirty, bitID)) {
776 /* update array buffer data */
777 CRBufferObject *bufObj = to->arrayBuffer;
778 CRASSERT(bufObj);
779 if (bufObj->dirtyStart == 0 && bufObj->dirtyLength == (int) bufObj->size) {
780 /* update whole buffer */
781 diff_api.BufferDataARB(GL_ARRAY_BUFFER_ARB, bufObj->size,
782 bufObj->data, bufObj->usage);
783 }
784 else {
785 /* update sub buffer */
786 diff_api.BufferSubDataARB(GL_ARRAY_BUFFER_ARB,
787 bufObj->dirtyStart,
788 bufObj->dirtyLength,
789 (char *) bufObj->data
790 + bufObj->dirtyStart);
791 }
792 FILLDIRTY(bufObj->dirty);
793 CLEARDIRTY2(bufObj->dirty, bitID);
794#if 0
795 bufObj->dirtyStart = 0;
796 bufObj->dirtyLength = 0;
797#endif
798 }
799
800 /* ELEMENTS_BUFFER binding */
801 if (CHECKDIRTY(bb->elementsBinding, bitID)) {
802 if (from->elementsBuffer != to->elementsBuffer) {
803 GLuint bufferID = to->elementsBuffer ? to->elementsBuffer->name : 0;
804 diff_api.BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, bufferID);
805 FILLDIRTY(bb->elementsBinding);
806 }
807 CLEARDIRTY2(bb->elementsBinding, bitID);
808 }
809
810 if (to->elementsBuffer && CHECKDIRTY(to->elementsBuffer->dirty, bitID)) {
811 /* update element buffer data */
812 CRBufferObject *bufObj = to->elementsBuffer;
813 CRASSERT(bufObj);
814 if (bufObj->dirtyStart == 0 && bufObj->dirtyLength == (int) bufObj->size) {
815 /* update whole buffer */
816 diff_api.BufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, bufObj->size,
817 bufObj->data, bufObj->usage);
818 }
819 else {
820 /* update sub buffer */
821 diff_api.BufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
822 bufObj->dirtyStart,
823 bufObj->dirtyLength,
824 (char *) bufObj->data
825 + bufObj->dirtyStart);
826 }
827 FILLDIRTY(bufObj->dirty);
828 CLEARDIRTY2(bufObj->dirty, bitID);
829#if 0
830 bufObj->dirtyStart = 0;
831 bufObj->dirtyLength = 0;
832#endif
833 }
834}
835
836
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette