state_bufferobject.c revision 236b6e0fdf652661ff4c655314fe488998c5c17d
/* Copyright (c) 2001, Stanford University
* All rights reserved
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#include "state.h"
#include "state/cr_statetypes.h"
#include "state/cr_statefuncs.h"
#include "state_internals.h"
#include "cr_mem.h"
#include "cr_string.h"
{
if (b) {
b->refCount = 1;
b->usage = GL_STATIC_DRAW_ARB;
b->access = GL_READ_WRITE_ARB;
}
return b;
}
{
#ifdef IN_GUEST
b->retainBufferData = GL_TRUE;
#else
b->retainBufferData = GL_FALSE;
#endif
b->nullBuffer = AllocBufferObject(0);
b->arrayBuffer = b->nullBuffer;
b->elementsBuffer = b->nullBuffer;
b->buffers = crAllocHashtable();
}
static void crStateFreeBufferObject(void *data)
{
}
{
crFree(b->nullBuffer);
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &(g->bufferobject);
if (g->current.inBeginEnd) {
return;
}
FLUSH();
if (target == GL_ARRAY_BUFFER_ARB) {
oldObj = b->arrayBuffer;
}
else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
oldObj = b->elementsBuffer;
}
else {
"glBindBufferARB(target)");
return;
}
if (buffer == 0) {
newObj = b->nullBuffer;
}
else {
if (!newObj) {
if (!newObj) {
return;
}
}
}
if (target == GL_ARRAY_BUFFER_ARB) {
b->arrayBuffer = newObj;
}
else {
b->elementsBuffer = newObj;
}
/*we shouldn't reach this point*/
CRASSERT(false);
}
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &(g->bufferobject);
int i;
FLUSH();
if (g->current.inBeginEnd) {
return;
}
if (n < 0) {
"glDeleteBuffersARB(n < 0)");
return;
}
for (i = 0; i < n; i++) {
if (buffers[i]) {
if (obj) {
if (obj == b->arrayBuffer) {
b->arrayBuffer = b->nullBuffer;
b->arrayBuffer->refCount++;
}
if (obj == b->elementsBuffer) {
b->elementsBuffer = b->nullBuffer;
b->elementsBuffer->refCount++;
}
/* @todo check bindings with the vertex arrays */
}
}
}
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &(g->bufferobject);
FLUSH();
if (g->current.inBeginEnd) {
return;
}
if (n < 0) {
"glGenBuffersARB(n < 0)");
return;
}
if (start) {
GLint i;
for (i = 0; i < n; i++)
}
else {
}
}
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return GL_FALSE;
}
return GL_TRUE;
else
return GL_FALSE;
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return;
}
if (size < 0) {
"glBufferDataARB(size < 0)");
return;
}
switch (usage) {
case GL_STREAM_DRAW_ARB:
case GL_STREAM_READ_ARB:
case GL_STREAM_COPY_ARB:
case GL_STATIC_DRAW_ARB:
case GL_STATIC_READ_ARB:
case GL_STATIC_COPY_ARB:
case GL_DYNAMIC_DRAW_ARB:
case GL_DYNAMIC_READ_ARB:
case GL_DYNAMIC_COPY_ARB:
/* OK */
break;
default:
"glBufferDataARB(usage)");
return;
}
if (target == GL_ARRAY_BUFFER_ARB) {
obj = b->arrayBuffer;
}
else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
obj = b->elementsBuffer;
}
else {
"glBufferDataARB(target)");
return;
}
return;
}
"glBufferDataARB(buffer is mapped)");
return;
}
/* The user of the state tracker should set the retainBufferData field
* during context initialization, if needed.
*/
if (b->retainBufferData) {
}
return;
}
if (data)
}
obj->dirtyStart = 0;
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return;
}
if (target == GL_ARRAY_BUFFER_ARB) {
obj = b->arrayBuffer;
}
else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
obj = b->elementsBuffer;
}
else {
"glBufferSubDataARB(target)");
return;
}
"glBufferSubDataARB");
return;
}
"glBufferSubDataARB(buffer is mapped)");
return;
}
return;
}
}
/* grow dirty region */
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return;
}
if (target == GL_ARRAY_BUFFER_ARB) {
obj = b->arrayBuffer;
}
else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
obj = b->elementsBuffer;
}
else {
"glGetBufferSubDataARB(target)");
return;
}
"glGetBufferSubDataARB");
return;
}
"glGetBufferSubDataARB(buffer is mapped)");
return;
}
return;
}
}
}
void * STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return NULL;
}
if (target == GL_ARRAY_BUFFER_ARB) {
obj = b->arrayBuffer;
}
else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
obj = b->elementsBuffer;
}
else {
"glMapBufferARB(target)");
return NULL;
}
return GL_FALSE;
}
switch (access) {
case GL_READ_ONLY_ARB:
case GL_WRITE_ONLY_ARB:
case GL_READ_WRITE_ARB:
break;
default:
"glMapBufferARB(access)");
return NULL;
}
}
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return GL_FALSE;
}
if (target == GL_ARRAY_BUFFER_ARB) {
obj = b->arrayBuffer;
}
else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
obj = b->elementsBuffer;
}
else {
"glUnmapBufferARB(target)");
return GL_FALSE;
}
return GL_FALSE;
}
return GL_FALSE;
}
/* the data was most likely modified */
obj->dirtyStart = 0;
}
return GL_TRUE;
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return;
}
if (target == GL_ARRAY_BUFFER_ARB) {
obj = b->arrayBuffer;
}
else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
obj = b->elementsBuffer;
}
else {
"glGetBufferParameterivARB(target)");
return;
}
switch (pname) {
case GL_BUFFER_SIZE_ARB:
break;
case GL_BUFFER_USAGE_ARB:
break;
case GL_BUFFER_ACCESS_ARB:
break;
case GL_BUFFER_MAPPED_ARB:
break;
default:
"glGetBufferParameterivARB(pname)");
return;
}
}
void STATE_APIENTRY
{
CRContext *g = GetCurrentContext();
CRBufferObjectState *b = &g->bufferobject;
FLUSH();
if (g->current.inBeginEnd) {
return;
}
if (target == GL_ARRAY_BUFFER_ARB) {
obj = b->arrayBuffer;
}
else if (target == GL_ELEMENT_ARRAY_BUFFER_ARB) {
obj = b->elementsBuffer;
}
else {
"glGetBufferPointervARB(target)");
return;
}
if (pname != GL_BUFFER_MAP_POINTER_ARB) {
"glGetBufferPointervARB(pname)");
return;
}
}
/**
* We need to check if the GL_EXT_vertex/pixel_buffer_object extensions
* are supported before calling any of the diff_api functions.
* This flag indidcates if the extensions is available (1), not available (0)
* or needs to be tested for (-1).
* If we don't do this, we can segfault inside OpenGL.
* Ideally, the render SPU should no-op unsupported GL functions, but
* that's a bit complicated.
*/
static GLboolean
{
if (haveBufferObjectExt == -1) {
const char *ext;
/* XXX this check is temporary. We need to make the tilesort SPU plug
* GetString into the diff'ing table in order for this to really work.
*/
haveBufferObjectExt = 0;
return 0;
}
haveBufferObjectExt = 1;
}
else {
haveBufferObjectExt = 0;
}
}
return haveBufferObjectExt;
}
{
if (!HaveBufferObjectExtension())
return;
/* ARRAY_BUFFER binding */
}
}
/* update array buffer data */
/* update whole buffer */
}
else {
/* update sub buffer */
+ bufObj->dirtyStart);
}
#if 0
bufObj->dirtyStart = 0;
bufObj->dirtyLength = 0;
#endif
}
/* ELEMENTS_BUFFER binding */
}
}
/* update element buffer data */
/* update whole buffer */
}
else {
/* update sub buffer */
+ bufObj->dirtyStart);
}
#if 0
bufObj->dirtyStart = 0;
bufObj->dirtyLength = 0;
#endif
}
}
/*
*/
{
if (!HaveBufferObjectExtension())
return;
/* ARRAY_BUFFER binding */
}
}
/* update array buffer data */
/* update whole buffer */
}
else {
/* update sub buffer */
+ bufObj->dirtyStart);
}
#if 0
bufObj->dirtyStart = 0;
bufObj->dirtyLength = 0;
#endif
}
/* ELEMENTS_BUFFER binding */
}
}
/* update element buffer data */
/* update whole buffer */
}
else {
/* update sub buffer */
+ bufObj->dirtyStart);
}
#if 0
bufObj->dirtyStart = 0;
bufObj->dirtyLength = 0;
#endif
}
}