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;
}
Esempio n. 3
0
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
}