DECLEXPORT(void) STATE_APIENTRY crStateDeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers) { CRContext *g = GetCurrentContext(); CRFramebufferObjectState *fbo = &g->framebufferobject; int i; CRSTATE_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end"); CRSTATE_CHECKERR(n<0, GL_INVALID_OPERATION, "n<0"); for (i = 0; i < n; i++) { if (renderbuffers[i]) { CRRenderbufferObject *rbo; rbo = (CRRenderbufferObject*) crHashtableSearch(g->shared->rbTable, renderbuffers[i]); if (rbo) { int j; ctStateRenderbufferRefsCleanup(g, renderbuffers[i], rbo); CR_STATE_SHAREDOBJ_USAGE_FOREACH_USED_IDX(rbo, j) { /* saved state version <= SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS does not have usage bits info, * so on restore, we set mark bits as used. * This is why g_pAvailableContexts[j] could be NULL * also g_pAvailableContexts[0] will hold default context, which we should discard */ CRContext *ctx = g_pAvailableContexts[j]; if (j && ctx) { CRFramebufferObjectState *ctxFbo; CRASSERT(ctx); ctxFbo = &ctx->framebufferobject; if (ctxFbo->renderbuffer==rbo) crWarning("deleting RBO being used by another context %d", ctx->id); ctStateRenderbufferRefsCleanup(ctx, renderbuffers[i], rbo); } else CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX(rbo, j); } crHashtableDelete(g->shared->rbTable, renderbuffers[i], crStateFreeRBO); } } }
DECLEXPORT(void) STATE_APIENTRY crStateBindRenderbufferEXT(GLenum target, GLuint renderbuffer) { CRContext *g = GetCurrentContext(); CRFramebufferObjectState *fbo = &g->framebufferobject; CRSTATE_CHECKERR(g->current.inBeginEnd, GL_INVALID_OPERATION, "called in begin/end"); CRSTATE_CHECKERR(target!=GL_RENDERBUFFER_EXT, GL_INVALID_ENUM, "invalid target"); if (renderbuffer) { fbo->renderbuffer = (CRRenderbufferObject*) crHashtableSearch(g->shared->rbTable, renderbuffer); if (!fbo->renderbuffer) { CRSTATE_CHECKERR(!crHashtableIsKeyUsed(g->shared->rbTable, renderbuffer), GL_INVALID_OPERATION, "name is not a renderbuffer"); fbo->renderbuffer = crStateRenderbufferAllocate(g, renderbuffer); } CR_STATE_SHAREDOBJ_USAGE_SET(fbo->renderbuffer, g); } else fbo->renderbuffer = NULL; }
void STATE_APIENTRY crStateBindBufferARB (GLenum target, GLuint buffer) { CRContext *g = GetCurrentContext(); CRBufferObjectState *b = &(g->bufferobject); CRStateBits *sb = GetCurrentBits(); CRBufferObjectBits *bb = &(sb->bufferobject); CRBufferObject *oldObj, *newObj; if (g->current.inBeginEnd) { crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glBindBufferARB called in begin/end"); return; } FLUSH(); oldObj = crStateGetBoundBufferObject(target, b); if (!oldObj) { crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glBindBufferARB(target)"); return; } if (buffer == 0) { newObj = b->nullBuffer; } else { newObj = (CRBufferObject *) crHashtableSearch(g->shared->buffersTable, buffer); if (!newObj) { CRSTATE_CHECKERR(!crHashtableIsKeyUsed(g->shared->buffersTable, buffer), GL_INVALID_OPERATION, "name is not a buffer object"); newObj = AllocBufferObject(buffer); CRSTATE_CHECKERR(!newObj, GL_OUT_OF_MEMORY, "glBindBuffer"); #ifndef IN_GUEST diff_api.GenBuffersARB(1, &newObj->hwid); if (!newObj->hwid) { crWarning("GenBuffersARB failed!"); crFree(newObj); return; } #endif crHashtableAdd( g->shared->buffersTable, buffer, newObj ); } CR_STATE_SHAREDOBJ_USAGE_SET(newObj, g); } newObj->refCount++; oldObj->refCount--; switch (target) { case GL_ARRAY_BUFFER_ARB: b->arrayBuffer = newObj; DIRTY(bb->dirty, g->neg_bitid); DIRTY(bb->arrayBinding, g->neg_bitid); break; case GL_ELEMENT_ARRAY_BUFFER_ARB: b->elementsBuffer = newObj; DIRTY(bb->dirty, g->neg_bitid); DIRTY(bb->elementsBinding, g->neg_bitid); break; #ifdef CR_ARB_pixel_buffer_object case GL_PIXEL_PACK_BUFFER_ARB: b->packBuffer = newObj; DIRTY(bb->dirty, g->neg_bitid); DIRTY(bb->packBinding, g->neg_bitid); break; case GL_PIXEL_UNPACK_BUFFER_ARB: b->unpackBuffer = newObj; DIRTY(bb->dirty, g->neg_bitid); DIRTY(bb->unpackBinding, g->neg_bitid); break; #endif default: /*can't get here*/ CRASSERT(false); return; } if (oldObj->refCount <= 0) { /*we shouldn't reach this point*/ CRASSERT(false); crHashtableDelete(g->shared->buffersTable, (unsigned long) oldObj->id, crStateFreeBufferObject); } #ifdef IN_GUEST if (target == GL_PIXEL_PACK_BUFFER_ARB) { newObj->bResyncOnRead = GL_TRUE; } #endif }