Пример #1
0
/*
 * Called via unpacker module.
 * Note: when there's a tilesort SPU upstream, the viewport dimensions
 * will typically match the mural size.  That is, the viewport dimensions
 * probably won't be the same values that the application issues.
 */
void SERVER_DISPATCH_APIENTRY crServerDispatchViewport( GLint x, GLint y, GLsizei width, GLsizei height )
{
	CRMuralInfo *mural = cr_server.curClient->currentMural;
	CRContext *ctx = crStateGetCurrent();

	if (ctx->viewport.viewportX != x ||
			ctx->viewport.viewportY != y ||
			ctx->viewport.viewportW != width ||
			ctx->viewport.viewportH != height) {
		 /* Note -- If there are tiles, this will be overridden in the 
			* process of decoding the BoundsInfo packet, so no worries. */
		 crStateViewport( x, y, width, height );

		 mural->viewportValidated = GL_FALSE;
	}

	if (mural->numExtents == 0) {
		/* non-tiling arrangment */
		cr_server.head_spu->dispatch_table.Viewport(x, y, width, height);
	}
	else {
		if (!mural->viewportValidated) {
			CRViewportState *vp = &(cr_server.curClient->currentCtx->viewport);
			crServerComputeViewportBounds(vp, mural);
			crServerSetOutputBounds(mural, 0);
		}
	}
}
Пример #2
0
static SPUFunctions *feedbackSPUInit( int id, SPU *child, SPU *self,
		unsigned int context_id,
		unsigned int num_contexts )
{
	CRContext *ctx;
	(void) context_id;
	(void) num_contexts;

	feedback_spu.id = id;
	feedback_spu.has_child = 0;
	if (child)
	{
		crSPUInitDispatchTable( &(feedback_spu.child) );
		crSPUCopyDispatchTable( &(feedback_spu.child), &(child->dispatch_table) );
		feedback_spu.has_child = 1;
	}
	crSPUInitDispatchTable( &(feedback_spu.super) );
	crSPUCopyDispatchTable( &(feedback_spu.super), &(self->superSPU->dispatch_table) );
	feedbackspuGatherConfiguration();

	/* create/init default state tracker */
	crStateInit();
	ctx = crStateGetCurrent();
	CRASSERT(ctx);
	crStateSetCurrentPointers(ctx, &feedback_spu.current);

	return &feedback_functions;
}
Пример #3
0
void crUnpackExtendLockArraysEXT(void)
{
    GLint first    = READ_DATA(sizeof(int) + 4, GLint);
    GLint count    = READ_DATA(sizeof(int) + 8, GLint);
    int numenabled = READ_DATA(sizeof(int) + 12, int);

    CRContext *g = crStateGetCurrent();
    CRClientState *c = &g->client;
    CRClientPointer *cp;
    int i, index, offset;
    unsigned char *data;
    
    offset = 2*sizeof(int)+12;

    /*crDebug("crUnpackExtendLockArraysEXT(%i, %i) ne=%i", first, count, numenabled);*/

    for (i=0; i<numenabled; ++i)
    {
        index = READ_DATA(offset, int);
        offset += sizeof(int);
        cp = crStateGetClientPointerByIndex(index, &c->array);
        CRASSERT(cp && cp->enabled && (!cp->buffer || !cp->buffer->id));
        data = crAlloc((first+count)*cp->bytesPerIndex);
        crMemcpy(data+first*cp->bytesPerIndex, DATA_POINTER(offset, GLvoid), count*cp->bytesPerIndex);
        offset += count*cp->bytesPerIndex;
        /*crDebug("crUnpackExtendLockArraysEXT: old cp(%i): en/l=%i(%i) p=%p size=%i type=0x%x n=%i str=%i pp=%p pstr=%i",
                index, cp->enabled, cp->locked, cp->p, cp->size, cp->type, cp->normalized, cp->stride, cp->prevPtr, cp->prevStride);*/
        crUnpackSetClientPointerByIndex(index, cp->size, cp->type, cp->normalized, 0, data, c);
        /*crDebug("crUnpackExtendLockArraysEXT: new cp(%i): en/l=%i(%i) p=%p size=%i type=0x%x n=%i str=%i pp=%p pstr=%i",
                index, cp->enabled, cp->locked, cp->p, cp->size, cp->type, cp->normalized, cp->stride, cp->prevPtr, cp->prevStride);*/
    }
    cr_unpackDispatch.LockArraysEXT(first, count);
}
Пример #4
0
void PACK_APIENTRY crPackLockArraysEXT(GLint first, GLint count)
{
    CRContext *g = crStateGetCurrent();
    CRClientState *c = &g->client;
    unsigned char *data_ptr, *start_ptr;
    int packet_length = sizeof(int); /*extopcode*/
    int vertex_size, i, numenabled;

    packet_length += sizeof(first) + sizeof(count); /*params*/
    numenabled = crPack_GetNumEnabledArrays(c, &vertex_size);
    packet_length += sizeof(int) + numenabled*sizeof(int); /*numenabled + indices*/
    packet_length += vertex_size * count; /*vertices data*/

    start_ptr = data_ptr = (unsigned char *) crPackAlloc(packet_length);
    WRITE_DATA_AI(GLenum, CR_LOCKARRAYSEXT_EXTEND_OPCODE );
    WRITE_DATA_AI(GLint, first);
    WRITE_DATA_AI(GLint, count);
    WRITE_DATA_AI(int, numenabled);
    for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
    {
        crPackLockClientPointer(first, count, &data_ptr, i, c);
    }
    crHugePacket(CR_EXTEND_OPCODE, start_ptr);
    crPackFree(start_ptr);
}
Пример #5
0
static void ARRAYSPU_APIENTRY arrayspu_Disable(GLenum cap)
{
     if (cap == GL_VERTEX_PROGRAM_NV) {
            crStateGetCurrent()->program.vpEnabled = GL_FALSE;
     }
     array_spu.child.Disable(cap);
}
Пример #6
0
void crServerRedirMuralFBO(CRMuralInfo *mural, GLboolean redir)
{
    if (redir)
    {
        if (!crServerSupportRedirMuralFBO())
        {
            crWarning("FBO not supported, can't redirect window output");
            return;
        }

        cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, GL_FALSE);

        if (mural->idFBO==0)
        {
            crServerCreateMuralFBO(mural);
        }

        if (!crStateGetCurrent()->framebufferobject.drawFB)
        {
            cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, mural->idFBO);
        }
        if (!crStateGetCurrent()->framebufferobject.readFB)
        {
            cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, mural->idFBO);
        }

        if (cr_server.curClient && cr_server.curClient->currentMural == mural)
        {
            crStateGetCurrent()->buffer.width = 0;
            crStateGetCurrent()->buffer.height = 0;
        }
    }
    else
    {
        cr_server.head_spu->dispatch_table.WindowShow(mural->spuWindow, mural->bVisible);

        if (mural->bUseFBO && crServerSupportRedirMuralFBO())
        {
            if (!crStateGetCurrent()->framebufferobject.drawFB)
            {
                cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
            }
            if (!crStateGetCurrent()->framebufferobject.readFB)
            {
                cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
            }
        }

        if (cr_server.curClient && cr_server.curClient->currentMural == mural)
        {
            crStateGetCurrent()->buffer.width = mural->width;
            crStateGetCurrent()->buffer.height = mural->height;
        }
    }

    mural->bUseFBO = redir;
}
Пример #7
0
void SERVER_DISPATCH_APIENTRY
crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context )
{
    CRMuralInfo *mural;
    CRContextInfo *ctxInfo = NULL;

    if (context >= 0 && window >= 0) {
        mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
        if (!mural)
        {
            crWarning("CRServer: invalid window %d passed to crServerDispatchMakeCurrent()", window);
            return;
        }

        /* Update the state tracker's current context */
        ctxInfo = (CRContextInfo *) crHashtableSearch(cr_server.contextTable, context);
        if (!ctxInfo) {
            crWarning("CRserver: NULL context in MakeCurrent %d", context);
            return;
        }
    }
    else {
#if 0
        oldMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, cr_server.currentWindow);
        if (oldMural && oldMural->bUseFBO && crServerSupportRedirMuralFBO())
        {
            if (!crStateGetCurrent()->framebufferobject.drawFB)
            {
                cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
            }
            if (!crStateGetCurrent()->framebufferobject.readFB)
            {
                cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
            }
        }

        ctxInfo = &cr_server.MainContextInfo;
        window = -1;
        mural = NULL;
#endif
        cr_server.bForceMakeCurrentOnClientSwitch = GL_TRUE;
        return;
    }

    crServerPerformMakeCurrent( mural, ctxInfo );
}
Пример #8
0
void PACK_APIENTRY
crPackDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
                                                GLenum type, const GLvoid *indices)
{
    unsigned char *data_ptr, *start_ptr;
    int packet_length = sizeof(int) + sizeof(mode) + sizeof(start)
        + sizeof(end) + sizeof(count) + sizeof(type) + sizeof(GLuint);
    GLsizei indexsize;

#ifdef CR_ARB_vertex_buffer_object
    CRBufferObject *elementsBuffer = crStateGetCurrent()->bufferobject.elementsBuffer;
    packet_length += sizeof(GLint);
    if (elementsBuffer && elementsBuffer->id)
    {
        /*@todo not sure it's possible, and not sure what to do*/
        if (!elementsBuffer->data)
        {
            crWarning("crPackDrawElements: trying to use bound but empty elements buffer, ignoring.");
            return;
        }
        indexsize = 0;
    }
    else
#endif
    {
      indexsize = crPackElementsIndexSize(type);
    }

    packet_length += count * indexsize;

    start_ptr = data_ptr = (unsigned char *) crPackAlloc(packet_length);
    WRITE_DATA_AI(GLenum, CR_DRAWRANGEELEMENTS_EXTEND_OPCODE);
    WRITE_DATA_AI(GLenum, mode);
    WRITE_DATA_AI(GLuint, start);
    WRITE_DATA_AI(GLuint, end);
    WRITE_DATA_AI(GLsizei, count);
    WRITE_DATA_AI(GLenum, type);
    WRITE_DATA_AI(GLuint, (GLuint) ((uintptr_t) indices));
#ifdef CR_ARB_vertex_buffer_object
    WRITE_DATA_AI(GLint, (GLint) (indexsize>0));
#endif
    if (indexsize>0)
    {
        crMemcpy(data_ptr, indices, count * indexsize);
    }
    crHugePacket(CR_EXTEND_OPCODE, start_ptr);
    crPackFree(start_ptr);
}
Пример #9
0
void SERVER_DISPATCH_APIENTRY
crServerDispatchFinish(void)
{
    CRContext *ctx = crStateGetCurrent();

    cr_server.head_spu->dispatch_table.Finish();

    if (cr_server.curClient->currentMural->bFbDraw && crServerIsRedirectedToFBO())
    {
        crServerPresentFBO(cr_server.curClient->currentMural);
    }

    if (ctx->framebufferobject.drawFB
            || (ctx->buffer.drawBuffer != GL_FRONT && ctx->buffer.drawBuffer != GL_FRONT_LEFT))
        cr_server.curClient->currentMural->bFbDraw = GL_FALSE;
}
Пример #10
0
/*
 * Called via unpacker module.
 * Note: when there's a tilesort SPU upstream, the viewport dimensions
 * will typically match the mural size.  That is, the viewport dimensions
 * probably won't be the same values that the application issues.
 */
void SERVER_DISPATCH_APIENTRY crServerDispatchViewport( GLint x, GLint y, GLsizei width, GLsizei height )
{
	CRMuralInfo *mural = cr_server.curClient->currentMural;
	CRContext *ctx = crStateGetCurrent();

	if (ctx->viewport.viewportX != x ||
			ctx->viewport.viewportY != y ||
			ctx->viewport.viewportW != width ||
			ctx->viewport.viewportH != height) {
		 /* Note -- If there are tiles, this will be overridden in the 
			* process of decoding the BoundsInfo packet, so no worries. */
		 crStateViewport( x, y, width, height );
	}

	/* always dispatch to be safe */
	cr_server.head_spu->dispatch_table.Viewport( x, y, width, height );
}
Пример #11
0
void PACKSPU_APIENTRY packspu_LinkProgram(GLuint program)
{
#ifdef VBOX_WITH_CRPACKSPU_DUMPER
    GLint linkStatus = 0;
#endif

    crStateLinkProgram(program);
    crPackLinkProgram(program);

#ifdef VBOX_WITH_CRPACKSPU_DUMPER
    pack_spu.self.GetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &linkStatus);
    Assert(linkStatus);
    if (!linkStatus)
    {
        CRContext *ctx = crStateGetCurrent();
        packspu_RecCheckInitRec();
        crRecDumpProgram(&pack_spu.Recorder, ctx, program, program);
    }
#endif
}
Пример #12
0
void PACKSPU_APIENTRY packspu_CompileShader(GLuint shader)
{
#ifdef VBOX_WITH_CRPACKSPU_DUMPER
    GLint compileStatus = 0;
#endif

//    crStateCompileShader(shader);
    crPackCompileShader(shader);

#ifdef VBOX_WITH_CRPACKSPU_DUMPER
    pack_spu.self.GetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compileStatus);
    Assert(compileStatus);
    if (!compileStatus)
    {
        CRContext *ctx = crStateGetCurrent();
        packspu_RecCheckInitRec();
        crRecDumpShader(&pack_spu.Recorder, ctx, shader, shader);
    }
#endif
}
Пример #13
0
void crUnpackExtendUnlockArraysEXT(void)
{
    int i;
    CRContext *g = crStateGetCurrent();
    CRClientState *c = &g->client;
    CRClientPointer *cp;

    /*crDebug("crUnpackExtendUnlockArraysEXT");*/

    cr_unpackDispatch.UnlockArraysEXT();

    for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
    {
        cp = crStateGetClientPointerByIndex(i, &c->array);
        if (cp->enabled)
        {
            /*crDebug("crUnpackExtendUnlockArraysEXT: old cp(%i): en/l=%i(%i) p=%p size=%i type=0x%x n=%i str=%i pp=%p pstr=%i",
                    i, cp->enabled, cp->locked, cp->p, cp->size, cp->type, cp->normalized, cp->stride, cp->prevPtr, cp->prevStride);*/
            crUnpackSetClientPointerByIndex(i, cp->size, cp->type, cp->normalized, cp->prevStride, cp->prevPtr, c);
            /*crDebug("crUnpackExtendUnlockArraysEXT: new cp(%i): en/l=%i(%i) p=%p size=%i type=0x%x n=%i str=%i pp=%p pstr=%i",
                    i, cp->enabled, cp->locked, cp->p, cp->size, cp->type, cp->normalized, cp->stride, cp->prevPtr, cp->prevStride);*/
        }
    }
}
Пример #14
0
void PACKSPU_APIENTRY
packspu_DrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices )
{
    GLboolean serverArrays = GL_FALSE;

#if CR_ARB_vertex_buffer_object
    GET_CONTEXT(ctx);
    GLboolean lockedArrays = GL_FALSE;
    CRBufferObject *elementsBuffer = crStateGetCurrent()->bufferobject.elementsBuffer;
    /*crDebug("DrawElements count=%d, indices=%p", count, indices);*/
    if (ctx->clientState->extensions.ARB_vertex_buffer_object)
        serverArrays = crStateUseServerArrays();

# ifdef CR_USE_LOCKARRAYS
    if (!serverArrays && !ctx->clientState->client.array.locked && (count>3)
        && (!elementsBuffer || !elementsBuffer->id))
    {
        GLuint min, max;
        GLsizei i;

        switch (type)
        {
            case GL_UNSIGNED_BYTE:
            {
                GLubyte *pIdx = (GLubyte *)indices;
                min = max = pIdx[0];
                for (i=0; i<count; ++i)
                {
                    if (pIdx[i]<min) min = pIdx[i];
                    else if (pIdx[i]>max) max = pIdx[i];
                }
                break;
            }
            case GL_UNSIGNED_SHORT:
            {
                GLushort *pIdx = (GLushort *)indices;
                min = max = pIdx[0];
                for (i=0; i<count; ++i)
                {
                    if (pIdx[i]<min) min = pIdx[i];
                    else if (pIdx[i]>max) max = pIdx[i];
                }
                break;
            }
            case GL_UNSIGNED_INT:
            {
                GLuint *pIdx = (GLuint *)indices;
                min = max = pIdx[0];
                for (i=0; i<count; ++i)
                {
                    if (pIdx[i]<min) min = pIdx[i];
                    else if (pIdx[i]>max) max = pIdx[i];
                }
                break;
            }
            default: crError("Unknown type 0x%x", type);
        }

        if ((max-min)<(GLuint)(2*count))
        {
            crStateLockArraysEXT(min, max-min+1);

            serverArrays = crStateUseServerArrays();
            if (serverArrays)
            {
                lockedArrays = GL_TRUE;
            }
            else
            {
                crStateUnlockArraysEXT();
            }
        }
    }
# endif
#endif

    if (serverArrays) {
        GET_CONTEXT(ctx);
        CRClientState *clientState = &(ctx->clientState->client);

        /*Note the comment in packspu_LockArraysEXT*/
        if (clientState->array.locked && !clientState->array.synced)
        {
            crPackLockArraysEXT(clientState->array.lockFirst, clientState->array.lockCount);
            clientState->array.synced = GL_TRUE;
        }
        /* Send the DrawArrays command over the wire */
        if (pack_spu.swap)
            crPackDrawElementsSWAP( mode, count, type, indices );
        else
            crPackDrawElements( mode, count, type, indices );
    }
    else {
        /* evaluate locally */
        GET_CONTEXT(ctx);
        CRClientState *clientState = &(ctx->clientState->client);
        if (pack_spu.swap)
            crPackExpandDrawElementsSWAP( mode, count, type, indices, clientState );
        else
        {
            //packspu_Begin(mode);
            crPackExpandDrawElements( mode, count, type, indices, clientState );
            //packspu_End();
        }
    }

#if CR_ARB_vertex_buffer_object
    if (lockedArrays)
    {
        packspu_UnlockArraysEXT();
    }
#endif
}
Пример #15
0
/**
 * Expand glDrawElements into crPackBegin/Vertex/End, etc commands.
 * Note: if mode==999, don't call glBegin/glEnd.
 */
void
crPackExpandDrawElements(GLenum mode, GLsizei count, GLenum type,
                                                 const GLvoid *indices, CRClientState *c)
{
    int i;
    GLubyte *p = (GLubyte *)indices;
#ifdef CR_ARB_vertex_buffer_object
    CRBufferObject *elementsBuffer = crStateGetCurrent()->bufferobject.elementsBuffer;
#endif

    if (count < 0)
    {
        __PackError(__LINE__, __FILE__, GL_INVALID_VALUE,
                                "crPackDrawElements(negative count)");
        return;
    }

    if (mode > GL_POLYGON && mode != 999)
    {
        __PackError(__LINE__, __FILE__, GL_INVALID_ENUM,
                                "crPackDrawElements(bad mode)");
        return;
    }

    if (type != GL_UNSIGNED_BYTE &&
            type != GL_UNSIGNED_SHORT &&
            type != GL_UNSIGNED_INT)
    {
        __PackError(__LINE__, __FILE__, GL_INVALID_ENUM,
                                "crPackDrawElements(bad type)");
        return;
    }

#ifdef CR_ARB_vertex_buffer_object
    if (elementsBuffer && elementsBuffer->data)
    {
        p = (unsigned char *)(elementsBuffer->data) + (unsigned long)p;
    }
#endif

    if (mode != 999)
        crPackBegin(mode);

    //crDebug("crPackExpandDrawElements mode:0x%x, count:%d, type:0x%x", mode, count, type);

    switch (type)
    {
        case GL_UNSIGNED_BYTE:
            for (i=0; i<count; i++)
            {
                crPackExpandArrayElement((GLint) *p++, c);
            }
            break;
        case GL_UNSIGNED_SHORT:
            for (i=0; i<count; i++)
            {
                crPackExpandArrayElement((GLint) * (GLushort *) p, c);
                p+=sizeof (GLushort);
            }
            break;
        case GL_UNSIGNED_INT:
            for (i=0; i<count; i++)
            {
                crPackExpandArrayElement((GLint) * (GLuint *) p, c);
                p+=sizeof (GLuint);
            }
            break;
        default:
            crError( "this can't happen: array_spu.self.DrawElements" );
            break;
    }

    if (mode != 999)
        crPackEnd();
}
Пример #16
0
void SERVER_DISPATCH_APIENTRY crServerDispatchBindFramebufferEXT(GLenum target, GLuint framebuffer)
{
#ifdef DEBUG_misha
    GLint rfb = 0, dfb = 0;
#endif
	crStateBindFramebufferEXT(target, framebuffer);

    if (0==framebuffer)
    {
        CRContext *ctx = crStateGetCurrent();
        if (ctx->buffer.drawBuffer == GL_FRONT || ctx->buffer.drawBuffer == GL_FRONT_LEFT || ctx->buffer.drawBuffer == GL_FRONT_RIGHT)
            cr_server.curClient->currentMural->bFbDraw = GL_TRUE;
    }

    if (0==framebuffer && crServerIsRedirectedToFBO())
    {
        if (target == GL_FRAMEBUFFER)
        {
            GLuint idDrawFBO = cr_server.curClient->currentMural->aidFBOs[cr_server.curClient->currentMural->iCurDrawBuffer];
            GLuint idReadFBO = cr_server.curClient->currentMural->aidFBOs[cr_server.curClient->currentMural->iCurReadBuffer];
            if (idDrawFBO == idReadFBO)
                cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_FRAMEBUFFER, idDrawFBO);
            else
            {
                cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, idReadFBO);
                cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, idDrawFBO);
            }
        }
        else if (target == GL_READ_FRAMEBUFFER)
        {
            GLuint idReadFBO = cr_server.curClient->currentMural->aidFBOs[cr_server.curClient->currentMural->iCurReadBuffer];
            cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, idReadFBO);
        }
        else if (target == GL_DRAW_FRAMEBUFFER)
        {
            GLuint idDrawFBO = cr_server.curClient->currentMural->aidFBOs[cr_server.curClient->currentMural->iCurDrawBuffer];
            cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, idDrawFBO);
        }
        else
        {
            crWarning("unknown target %d", target);
        }
#ifdef DEBUG_misha
        cr_server.head_spu->dispatch_table.GetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &rfb);
        cr_server.head_spu->dispatch_table.GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &dfb);
        if (GL_FRAMEBUFFER_EXT == target)
        {
            Assert(rfb == cr_server.curClient->currentMural->aidFBOs[cr_server.curClient->currentMural->iCurReadBuffer]);
            Assert(dfb == cr_server.curClient->currentMural->aidFBOs[cr_server.curClient->currentMural->iCurDrawBuffer]);
        }
        else if (GL_READ_FRAMEBUFFER_EXT == target)
        {
            Assert(rfb == cr_server.curClient->currentMural->aidFBOs[cr_server.curClient->currentMural->iCurReadBuffer]);
        }
        else if (GL_DRAW_FRAMEBUFFER_EXT == target)
        {
            Assert(dfb == cr_server.curClient->currentMural->aidFBOs[cr_server.curClient->currentMural->iCurDrawBuffer]);
        }
        else
        {
            Assert(0);
        }
#endif
    }
    else
    {
        cr_server.head_spu->dispatch_table.BindFramebufferEXT(target, crStateGetFramebufferHWID(framebuffer));
#ifdef DEBUG_misha
        cr_server.head_spu->dispatch_table.GetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &rfb);
        cr_server.head_spu->dispatch_table.GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &dfb);
        if (GL_FRAMEBUFFER_EXT == target)
        {
            Assert(rfb == crStateGetFramebufferHWID(framebuffer));
            Assert(dfb == crStateGetFramebufferHWID(framebuffer));
        }
        else if (GL_READ_FRAMEBUFFER_EXT == target)
        {
            Assert(rfb == crStateGetFramebufferHWID(framebuffer));
        }
        else if (GL_DRAW_FRAMEBUFFER_EXT == target)
        {
            Assert(dfb == crStateGetFramebufferHWID(framebuffer));
        }
        else
        {
            Assert(0);
        }
#endif
    }
}
Пример #17
0
/*
 * Expand glArrayElement into crPackVertex/Color/Normal/etc.
 */
void
crPackExpandArrayElement(GLint index, CRClientState *c)
{
    unsigned char *p;
    unsigned int unit, attr;
    const CRVertexArrays *array = &(c->array);
    const GLboolean vpEnabled = crStateGetCurrent()->program.vpEnabled;

    /*crDebug("crPackExpandArrayElement(%i)", index);*/

    if (array->n.enabled && !(vpEnabled && array->a[VERT_ATTRIB_NORMAL].enabled))
    {
        p = array->n.p + index * array->n.stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->n.buffer && array->n.buffer->data)
        {
            p = (unsigned char *)(array->n.buffer->data) + (unsigned long)p;
        }
#endif

        switch (array->n.type)
        {
            case GL_BYTE: crPackNormal3bv((GLbyte *)p); break;
            case GL_SHORT: crPackNormal3sv((GLshort *)p); break;
            case GL_INT: crPackNormal3iv((GLint *)p); break;
            case GL_FLOAT: crPackNormal3fv((GLfloat *)p); break;
            case GL_DOUBLE: crPackNormal3dv((GLdouble *)p); break;
            default:
                crWarning("Unhandled: crPackExpandArrayElement, array->n.type 0x%x", array->n.type);
        }
    }

    if (array->c.enabled && !(vpEnabled && array->a[VERT_ATTRIB_COLOR0].enabled))
    {
        p = array->c.p + index * array->c.stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->c.buffer && array->c.buffer->data)
        {
            p = (unsigned char *)(array->c.buffer->data) + (unsigned long)p;
        }
#endif

        switch (array->c.type)
        {
            case GL_BYTE:
                switch (c->array.c.size)
                {
                    case 3: crPackColor3bv((GLbyte *)p); break;
                    case 4: crPackColor4bv((GLbyte *)p); break;
                }
                break;
            case GL_UNSIGNED_BYTE:
                switch (c->array.c.size)
                {
                    case 3: crPackColor3ubv((GLubyte *)p); break;
                    case 4: crPackColor4ubv((GLubyte *)p); break;
                }
                break;
            case GL_SHORT:
                switch (c->array.c.size)
                {
                    case 3: crPackColor3sv((GLshort *)p); break;
                    case 4: crPackColor4sv((GLshort *)p); break;
                }
                break;
            case GL_UNSIGNED_SHORT:
                switch (c->array.c.size)
                {
                    case 3: crPackColor3usv((GLushort *)p); break;
                    case 4: crPackColor4usv((GLushort *)p); break;
                }
                break;
            case GL_INT:
                switch (c->array.c.size)
                {
                    case 3: crPackColor3iv((GLint *)p); break;
                    case 4: crPackColor4iv((GLint *)p); break;
                }
                break;
            case GL_UNSIGNED_INT:
                switch (c->array.c.size)
                {
                    case 3: crPackColor3uiv((GLuint *)p); break;
                    case 4: crPackColor4uiv((GLuint *)p); break;
                }
                break;
            case GL_FLOAT:
                switch (c->array.c.size)
                {
                    case 3: crPackColor3fv((GLfloat *)p); break;
                    case 4: crPackColor4fv((GLfloat *)p); break;
                }
                break;
            case GL_DOUBLE:
                switch (c->array.c.size)
                {
                    case 3: crPackColor3dv((GLdouble *)p); break;
                    case 4: crPackColor4dv((GLdouble *)p); break;
                }
                break;
            default:
                crWarning("Unhandled: crPackExpandArrayElement, array->c.type 0x%x", array->c.type);
        }
    }

#ifdef CR_EXT_secondary_color
    if (array->s.enabled && !(vpEnabled && array->a[VERT_ATTRIB_COLOR1].enabled))
    {
        p = array->s.p + index * array->s.stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->s.buffer && array->s.buffer->data)
        {
            p = (unsigned char *)(array->s.buffer->data) + (unsigned long)p;
        }
#endif

        switch (array->s.type)
        {
            case GL_BYTE:
                crPackSecondaryColor3bvEXT((GLbyte *)p); break;
            case GL_UNSIGNED_BYTE:
                crPackSecondaryColor3ubvEXT((GLubyte *)p); break;
            case GL_SHORT:
                crPackSecondaryColor3svEXT((GLshort *)p); break;
            case GL_UNSIGNED_SHORT:
                crPackSecondaryColor3usvEXT((GLushort *)p); break;
            case GL_INT:
                crPackSecondaryColor3ivEXT((GLint *)p); break;
            case GL_UNSIGNED_INT:
                crPackSecondaryColor3uivEXT((GLuint *)p); break;
            case GL_FLOAT:
                crPackSecondaryColor3fvEXT((GLfloat *)p); break;
            case GL_DOUBLE:
                crPackSecondaryColor3dvEXT((GLdouble *)p); break;
            default:
                crWarning("Unhandled: crPackExpandArrayElement, array->s.type 0x%x", array->s.type);
        }
    }
#endif // CR_EXT_secondary_color


#ifdef CR_EXT_fog_coord
    if (array->f.enabled && !(vpEnabled && array->a[VERT_ATTRIB_FOG].enabled))
    {
        p = array->f.p + index * array->f.stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->f.buffer && array->f.buffer->data)
        {
            p = (unsigned char *)(array->f.buffer->data) + (unsigned long)p;
        }
#endif
        crPackFogCoordfEXT( *((GLfloat *) p) );
    }
#endif // CR_EXT_fog_coord

    for (unit = 0 ; unit < CR_MAX_TEXTURE_UNITS ; unit++)
    {
        if (array->t[unit].enabled && !(vpEnabled && array->a[VERT_ATTRIB_TEX0+unit].enabled))
        {
            p = array->t[unit].p + index * array->t[unit].stride;

#ifdef CR_ARB_vertex_buffer_object
            if (array->t[unit].buffer && array->t[unit].buffer->data)
            {
                p = (unsigned char *)(array->t[unit].buffer->data) + (unsigned long)p;
            }
#endif

            switch (array->t[unit].type)
            {
                case GL_SHORT:
                    switch (array->t[unit].size)
                    {
                        case 1: crPackMultiTexCoord1svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
                        case 2: crPackMultiTexCoord2svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
                        case 3: crPackMultiTexCoord3svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
                        case 4: crPackMultiTexCoord4svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
                    }
                    break;
                case GL_INT:
                    switch (array->t[unit].size)
                    {
                        case 1: crPackMultiTexCoord1ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
                        case 2: crPackMultiTexCoord2ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
                        case 3: crPackMultiTexCoord3ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
                        case 4: crPackMultiTexCoord4ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
                    }
                    break;
                case GL_FLOAT:
                    switch (array->t[unit].size)
                    {
                        case 1: crPackMultiTexCoord1fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
                        case 2: crPackMultiTexCoord2fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
                        case 3: crPackMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
                        case 4: crPackMultiTexCoord4fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
                    }
                    break;
                case GL_DOUBLE:
                    switch (array->t[unit].size)
                    {
                        case 1: crPackMultiTexCoord1dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
                        case 2: crPackMultiTexCoord2dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
                        case 3: crPackMultiTexCoord3dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
                        case 4: crPackMultiTexCoord4dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
                    }
                    break;
                default:
                    crWarning("Unhandled: crPackExpandArrayElement, array->t[%i].type 0x%x", unit, array->t[unit].type);
            }
        }
    }

    if (array->i.enabled)
    {
        p = array->i.p + index * array->i.stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->i.buffer && array->i.buffer->data)
        {
            p = (unsigned char *)(array->i.buffer->data) + (unsigned long)p;
        }
#endif

        switch (array->i.type)
        {
            case GL_SHORT: crPackIndexsv((GLshort *)p); break;
            case GL_INT: crPackIndexiv((GLint *)p); break;
            case GL_FLOAT: crPackIndexfv((GLfloat *)p); break;
            case GL_DOUBLE: crPackIndexdv((GLdouble *)p); break;
            default:
                crWarning("Unhandled: crPackExpandArrayElement, array->i.type 0x%x", array->i.type);
        }
    }

    if (array->e.enabled)
    {
        p = array->e.p + index * array->e.stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->e.buffer && array->e.buffer->data)
        {
            p = (unsigned char *)(array->e.buffer->data) + (unsigned long)p;
        }
#endif

        crPackEdgeFlagv(p);
    }

    for (attr = 1; attr < VERT_ATTRIB_MAX; attr++)
    {
        if (array->a[attr].enabled)
        {
            crPackVertexAttrib(array, attr, index);
        }
    }

    if (array->a[VERT_ATTRIB_POS].enabled)
    {
        crPackVertexAttrib(array, VERT_ATTRIB_POS, index);
    }
    else if (array->v.enabled)
    {
        p = array->v.p + index * array->v.stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->v.buffer && array->v.buffer->data)
        {
            p = (unsigned char *)(array->v.buffer->data) + (unsigned long)p;
        }
#endif
        switch (array->v.type)
        {
            case GL_SHORT:
                switch (c->array.v.size)
                {
                    case 2: crPackVertex2sv((GLshort *)p); break;
                    case 3: crPackVertex3sv((GLshort *)p); break;
                    case 4: crPackVertex4sv((GLshort *)p); break;
                }
                break;
            case GL_INT:
                switch (c->array.v.size)
                {
                    case 2: crPackVertex2iv((GLint *)p); break;
                    case 3: crPackVertex3iv((GLint *)p); break;
                    case 4: crPackVertex4iv((GLint *)p); break;
                }
                break;
            case GL_FLOAT:
                switch (c->array.v.size)
                {
                    case 2: crPackVertex2fv((GLfloat *)p); break;
                    case 3: crPackVertex3fv((GLfloat *)p); break;
                    case 4: crPackVertex4fv((GLfloat *)p); break;
                }
                break;
            case GL_DOUBLE:
                switch (c->array.v.size)
                {
                    case 2: crPackVertex2dv((GLdouble *)p); break;
                    case 3: crPackVertex3dv((GLdouble *)p); break;
                    case 4: crPackVertex4dv((GLdouble *)p); break;
                }
                break;
            default:
                crWarning("Unhandled: crPackExpandArrayElement, array->v.type 0x%x", array->v.type);
        }
    }
}
Пример #18
0
void crServerPerformMakeCurrent( CRMuralInfo *mural, CRContextInfo *ctxInfo )
{
    CRMuralInfo *oldMural;
    CRContext *ctx, *oldCtx = NULL;
    GLuint idDrawFBO, idReadFBO;
    GLint context = ctxInfo->CreateInfo.externalID;
    GLint window = mural->CreateInfo.externalID;

    cr_server.bForceMakeCurrentOnClientSwitch = GL_FALSE;

    ctx = ctxInfo->pContext;
    CRASSERT(ctx);

    oldMural = cr_server.currentMural;

    /* Ubuntu 11.04 hosts misbehave if context window switch is
     * done with non-default framebuffer object settings.
     * crStateSwitchPrepare & crStateSwitchPostprocess are supposed to work around this problem
     * crStateSwitchPrepare restores the FBO state to its default values before the context window switch,
     * while crStateSwitchPostprocess restores it back to the original values */
    oldCtx = crStateGetCurrent();
    if (oldMural && oldMural->fRedirected && crServerSupportRedirMuralFBO())
    {
        idDrawFBO = CR_SERVER_FBO_FOR_IDX(oldMural, oldMural->iCurDrawBuffer);
        idReadFBO = CR_SERVER_FBO_FOR_IDX(oldMural, oldMural->iCurReadBuffer);
    }
    else
    {
        idDrawFBO = 0;
        idReadFBO = 0;
    }
    crStateSwitchPrepare(cr_server.bUseMultipleContexts ? NULL : ctx, oldCtx, idDrawFBO, idReadFBO);

    if (cr_server.curClient)
    {
        /*
        crDebug("**** %s client %d  curCtx=%d curWin=%d", __func__,
                        cr_server.curClient->number, ctxPos, window);
        */
        cr_server.curClient->currentContextNumber = context;
        cr_server.curClient->currentCtxInfo = ctxInfo;
        cr_server.curClient->currentMural = mural;
        cr_server.curClient->currentWindow = window;

        CRASSERT(cr_server.curClient->currentCtxInfo);
        CRASSERT(cr_server.curClient->currentCtxInfo->pContext);
    }

    /* This is a hack to force updating the 'current' attribs */
    crStateUpdateColorBits();

    if (ctx)
        crStateSetCurrentPointers( ctx, &(cr_server.current) );

    /* check if being made current for first time, update viewport */
#if 0
    if (ctx) {
        /* initialize the viewport */
        if (ctx->viewport.viewportW == 0) {
            ctx->viewport.viewportW = mural->width;
            ctx->viewport.viewportH = mural->height;
            ctx->viewport.scissorW = mural->width;
            ctx->viewport.scissorH = mural->height;
        }
    }
#endif

    /*
    crDebug("**** %s  currentWindow %d  newWindow %d", __func__,
                    cr_server.currentWindow, window);
    */

    if (1/*cr_server.firstCallMakeCurrent ||
            cr_server.currentWindow != window ||
            cr_server.currentNativeWindow != nativeWindow*/) {
        /* Since the cr server serialized all incoming contexts/clients into
         * one output stream of GL commands, we only need to call the head
         * SPU's MakeCurrent() function once.
         * BUT, if we're rendering to multiple windows, we do have to issue
         * MakeCurrent() calls sometimes.  The same GL context will always be
         * used though.
         */
        cr_server.head_spu->dispatch_table.MakeCurrent( mural->spuWindow,
                                                        0,
                                                        ctxInfo->SpuContext >= 0
                                                            ? ctxInfo->SpuContext
                                                              : cr_server.MainContextInfo.SpuContext);

        CR_STATE_SHAREDOBJ_USAGE_SET(mural, ctx);
        if (cr_server.currentCtxInfo)
            cr_server.currentCtxInfo->currentMural = NULL;
        ctxInfo->currentMural = mural;

        cr_server.firstCallMakeCurrent = GL_FALSE;
        cr_server.currentCtxInfo = ctxInfo;
        cr_server.currentWindow = window;
        cr_server.currentNativeWindow = 0;
        cr_server.currentMural = mural;
    }

    /* This used to be earlier, after crStateUpdateColorBits() call */
    crStateMakeCurrent( ctx );

    if (mural && mural->fRedirected  && crServerSupportRedirMuralFBO())
    {
        GLuint id = crServerMuralFBOIdxFromBufferName(mural, ctx->buffer.drawBuffer);
        if (id != mural->iCurDrawBuffer)
        {
            crDebug("DBO draw buffer changed on make current");
            mural->iCurDrawBuffer = id;
        }

        id = crServerMuralFBOIdxFromBufferName(mural, ctx->buffer.readBuffer);
        if (id != mural->iCurReadBuffer)
        {
            crDebug("DBO read buffer changed on make current");
            mural->iCurReadBuffer = id;
        }

        idDrawFBO = CR_SERVER_FBO_FOR_IDX(mural, mural->iCurDrawBuffer);
        idReadFBO = CR_SERVER_FBO_FOR_IDX(mural, mural->iCurReadBuffer);
    }
    else
    {
        idDrawFBO = 0;
        idReadFBO = 0;
    }
    crStateSwitchPostprocess(ctx, cr_server.bUseMultipleContexts ? NULL : oldCtx, idDrawFBO, idReadFBO);

    if (!ctx->framebufferobject.drawFB
            && (ctx->buffer.drawBuffer == GL_FRONT || ctx->buffer.drawBuffer == GL_FRONT_LEFT)
            && cr_server.curClient)
        cr_server.curClient->currentMural->bFbDraw = GL_TRUE;

    if (!mural->fRedirected)
    {
        ctx->buffer.width = mural->width;
        ctx->buffer.height = mural->height;
    }
    else
    {
        ctx->buffer.width = 0;
        ctx->buffer.height = 0;
    }
}
Пример #19
0
void crServerPresentFBO(CRMuralInfo *mural)
{
    char *pixels=NULL, *tmppixels;
    GLuint uid;
    int i, j;
    CRrecti rect, rectwr, sectr;
    GLboolean bUsePBO;
    CRContext *ctx = crStateGetCurrent();

    CRASSERT(cr_server.pfnPresentFBO);

    if (!mural->bVisible)
    {
        return;
    }

    if (!mural->width || !mural->height)
    {
        return;
    }

    if (cr_server.bUsePBOForReadback && !mural->idPBO)
    {
        crWarning("Mural doesn't have PBO even though bUsePBOForReadback is set!");
    }

    bUsePBO = cr_server.bUsePBOForReadback && mural->idPBO;

    cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, mural->idColorTex);

    if (bUsePBO)
    {
        CRASSERT(mural->idPBO);
        cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, mural->idPBO);
    }
    else
    {
        if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
        {
            cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
        }

        pixels = crAlloc(4*mural->fboWidth*mural->fboHeight);
        if (!pixels)
        {
            crWarning("Out of memory in crServerPresentFBO");
            return;
        }
    }

    /*read the texture, note pixels are NULL for PBO case as it's offset in the buffer*/    
    cr_server.head_spu->dispatch_table.GetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);

    /*restore gl state*/
    uid = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid;
    cr_server.head_spu->dispatch_table.BindTexture(GL_TEXTURE_2D, uid);

    if (bUsePBO)
    {
        pixels = cr_server.head_spu->dispatch_table.MapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
        if (!pixels)
        {
            crWarning("Failed to MapBuffer in crServerPresentFBO");
            return;
        }
    }

    for (i=0; i<cr_server.screenCount; ++i)
    {
        if (crServerIntersectScreen(mural, i, &rect))
        {
            /* rect in window relative coords */
            crServerTransformRect(&rectwr, &rect, -mural->gX, -mural->gY);

            if (!mural->pVisibleRects)
            {
                /*we don't get any rects info for guest compiz windows, so we treat windows as visible unless explicitly received 0 visible rects*/
                if (!mural->bReceivedRects)
                {
                    tmppixels = crAlloc(4*(rect.x2-rect.x1)*(rect.y2-rect.y1));
                    if (!tmppixels)
                    {
                        crWarning("Out of memory in crServerPresentFBO");
                        crFree(pixels);
                        return;
                    }

                    crServerCopySubImage(tmppixels, pixels, &rectwr, mural->fboWidth, mural->fboHeight);
                    /*Note: pfnPresentFBO would free tmppixels*/
                    cr_server.pfnPresentFBO(tmppixels, i, rect.x1-cr_server.screen[i].x, rect.y1-cr_server.screen[i].y, rect.x2-rect.x1, rect.y2-rect.y1);
                }
            }
            else
            {
                for (j=0; j<mural->cVisibleRects; ++j)
                {
                    if (crServerIntersectRect(&rectwr, (CRrecti*) &mural->pVisibleRects[4*j], &sectr))
                    {
                        tmppixels = crAlloc(4*(sectr.x2-sectr.x1)*(sectr.y2-sectr.y1));
                        if (!tmppixels)
                        {
                            crWarning("Out of memory in crServerPresentFBO");
                            crFree(pixels);
                            return;
                        }

                        crServerCopySubImage(tmppixels, pixels, &sectr, mural->fboWidth, mural->fboHeight);
                        /*Note: pfnPresentFBO would free tmppixels*/
                        cr_server.pfnPresentFBO(tmppixels, i,
                                                sectr.x1+mural->gX-cr_server.screen[i].x,
                                                sectr.y1+mural->gY-cr_server.screen[i].y,
                                                sectr.x2-sectr.x1, sectr.y2-sectr.y1);
                    }
                }
            }
        }
    }

    if (mural->pvOutputRedirectInstance)
    {
        /* @todo find out why presentfbo is not called but crorframe is called. */
        cr_server.outputRedirect.CRORFrame(mural->pvOutputRedirectInstance,
                                           pixels,
                                           4 * mural->fboWidth * mural->fboHeight);
    }

    if (bUsePBO)
    {
        cr_server.head_spu->dispatch_table.UnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB);
        cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
    }
    else
    {
        crFree(pixels);
        if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
        {
            cr_server.head_spu->dispatch_table.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
        }
    }
}
Пример #20
0
void crServerCreateMuralFBO(CRMuralInfo *mural)
{
    CRContext *ctx = crStateGetCurrent();
    GLuint uid;
    GLenum status;
    SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
    CRContextInfo *pMuralContextInfo;
    int RestoreSpuWindow = -1;
    int RestoreSpuContext = -1;

    CRASSERT(mural->idFBO==0);

    pMuralContextInfo = cr_server.currentCtxInfo;
    if (!pMuralContextInfo)
    {
        /* happens on saved state load */
        CRASSERT(cr_server.MainContextInfo.SpuContext);
        pMuralContextInfo = &cr_server.MainContextInfo;
        cr_server.head_spu->dispatch_table.MakeCurrent(mural->spuWindow, 0, cr_server.MainContextInfo.SpuContext);
        RestoreSpuWindow = 0;
        RestoreSpuContext = 0;
    }

    /*Color texture*/
    gl->GenTextures(1, &mural->idColorTex);
    gl->BindTexture(GL_TEXTURE_2D, mural->idColorTex);
    gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
    {
        gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
    }
    gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mural->width, mural->height,
                   0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);

    /*Depth&Stencil*/
    gl->GenRenderbuffersEXT(1, &mural->idDepthStencilRB);
    gl->BindRenderbufferEXT(GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);
    gl->RenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT,
                               mural->width, mural->height);

    /*FBO*/
    gl->GenFramebuffersEXT(1, &mural->idFBO);
    gl->BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mural->idFBO);

    gl->FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                                GL_TEXTURE_2D, mural->idColorTex, 0);
    gl->FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
                                   GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);
    gl->FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
                                   GL_RENDERBUFFER_EXT, mural->idDepthStencilRB);

    status = gl->CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    if (status!=GL_FRAMEBUFFER_COMPLETE_EXT)
    {
        crWarning("FBO status(0x%x) isn't complete", status);
    }

    mural->fboWidth = mural->width;
    mural->fboHeight = mural->height;

    /*PBO*/
    if (cr_server.bUsePBOForReadback)
    {
        gl->GenBuffersARB(1, &mural->idPBO);
        gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, mural->idPBO);
        gl->BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, mural->width*mural->height*4, 0, GL_STREAM_READ_ARB);
        gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);

        if (!mural->idPBO)
        {
            crWarning("PBO create failed");
        }
    }

    /*Restore gl state*/
    uid = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid;
    gl->BindTexture(GL_TEXTURE_2D, uid);

    uid = ctx->framebufferobject.renderbuffer ? ctx->framebufferobject.renderbuffer->hwid:0;
    gl->BindRenderbufferEXT(GL_RENDERBUFFER_EXT, uid);

    uid = ctx->framebufferobject.drawFB ? ctx->framebufferobject.drawFB->hwid:0;
    gl->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, uid);

    uid = ctx->framebufferobject.readFB ? ctx->framebufferobject.readFB->hwid:0;
    gl->BindFramebufferEXT(GL_READ_FRAMEBUFFER, uid);

    if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
    {
        gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, ctx->bufferobject.unpackBuffer->hwid);
    }

    if (RestoreSpuWindow >= 0 && RestoreSpuContext >= 0)
    {
        cr_server.head_spu->dispatch_table.MakeCurrent(RestoreSpuWindow, 0, RestoreSpuContext);
    }
}
Пример #21
0
/**
 * Do CRServer initializations.  After this, we can begin servicing clients.
 */
GLboolean crVBoxServerInit(void)
{
    CRMuralInfo *defaultMural;

#if DEBUG_FP_EXCEPTIONS
    {
        fpu_control_t mask;
        _FPU_GETCW(mask);
        mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM
                            | _FPU_MASK_OM | _FPU_MASK_UM);
        _FPU_SETCW(mask);
    }
#endif

    crNetInit(crServerRecv, crServerClose);

    cr_server.firstCallCreateContext = GL_TRUE;
    cr_server.firstCallMakeCurrent = GL_TRUE;

    cr_server.bIsInLoadingState = GL_FALSE;
    cr_server.bIsInSavingState  = GL_FALSE;

    cr_server.pCleanupClient = NULL;

    /*
     * Create default mural info and hash table.
     */
    cr_server.muralTable = crAllocHashtable();
    defaultMural = (CRMuralInfo *) crCalloc(sizeof(CRMuralInfo));
    crHashtableAdd(cr_server.muralTable, 0, defaultMural);

    cr_server.programTable = crAllocHashtable();

    crStateInit();

    crStateLimitsInit( &(cr_server.limits) );

    cr_server.barriers = crAllocHashtable();
    cr_server.semaphores = crAllocHashtable();

    crUnpackSetReturnPointer( &(cr_server.return_ptr) );
    crUnpackSetWritebackPointer( &(cr_server.writeback_ptr) );

    /*
     * Default context
     */
    cr_server.contextTable = crAllocHashtable();
    cr_server.DummyContext = crStateCreateContext( &cr_server.limits,
                                                   CR_RGB_BIT | CR_DEPTH_BIT, NULL );
    cr_server.pContextCreateInfoTable = crAllocHashtable();
    cr_server.pWindowCreateInfoTable = crAllocHashtable();

    crServerSetVBoxConfigurationHGCM();

    if (!cr_server.head_spu)
        return GL_FALSE;

    crServerInitDispatch();
    crStateDiffAPI( &(cr_server.head_spu->dispatch_table) );

    /*Check for PBO support*/
    if (crStateGetCurrent()->extensions.ARB_pixel_buffer_object)
    {
        cr_server.bUsePBOForReadback=GL_TRUE;
    }

    return GL_TRUE;
}
Пример #22
0
/*@todo: it's a hack, as GLSL shouldn't blindly reuse this bit from nv_vertex_program*/
static void ARRAYSPU_APIENTRY arrayspu_UseProgram(GLuint program)
{
    crStateGetCurrent()->program.vpEnabled = program>0;
    array_spu.child.UseProgram(program);
}
Пример #23
0
static void ARRAYSPU_APIENTRY arrayspu_ArrayElement( GLint index )
{
    const CRClientState *c = &(crStateGetCurrent()->client);
    const CRVertexArrays *array = &(c->array);
    const GLboolean vpEnabled = crStateGetCurrent()->program.vpEnabled;
    unsigned char *p;
    unsigned int unit, attr;

    if (array->e.enabled)
    {
        p = array->e.p + index * array->e.stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->e.buffer && array->e.buffer->data)
        {
            p = (unsigned char *)(array->e.buffer->data) + (unsigned long)p;
        }
#endif

        array_spu.self.EdgeFlagv(p);
    }

    /*
     * Vertex attribute arrays (GL_NV_vertex_program) have priority over
     * the conventional vertex arrays.
     */
    if (vpEnabled)
    {
        for (attr = 1; attr < VERT_ATTRIB_MAX; attr++)
        {
            if (array->a[attr].enabled)
            {
                GLint *iPtr;
                p = array->a[attr].p + index * array->a[attr].stride;

#ifdef CR_ARB_vertex_buffer_object
                if (array->a[attr].buffer && array->a[attr].buffer->data)
                {
                    p = (unsigned char *)(array->a[attr].buffer->data) + (unsigned long)p;
                }
#endif

                switch (array->a[attr].type)
                {
                    case GL_SHORT:
                        switch (array->a[attr].size)
                        {
                            case 1: array_spu.self.VertexAttrib1svARB(attr, (GLshort *)p); break;
                            case 2: array_spu.self.VertexAttrib2svARB(attr, (GLshort *)p); break;
                            case 3: array_spu.self.VertexAttrib3svARB(attr, (GLshort *)p); break;
                            case 4: array_spu.self.VertexAttrib4svARB(attr, (GLshort *)p); break;
                        }
                        break;
                    case GL_INT:
                        iPtr = (GLint *) p;
                        switch (array->a[attr].size)
                        {
                            case 1: array_spu.self.VertexAttrib1fARB(attr, p[0]); break;
                            case 2: array_spu.self.VertexAttrib2fARB(attr, p[0], p[1]); break;
                            case 3: array_spu.self.VertexAttrib3fARB(attr, p[0], p[1], p[2]); break;
                            case 4: array_spu.self.VertexAttrib4fARB(attr, p[0], p[1], p[2], p[3]); break;
                        }
                        break;
                    case GL_FLOAT:
                        switch (array->a[attr].size)
                        {
                            case 1: array_spu.self.VertexAttrib1fvARB(attr, (GLfloat *)p); break;
                            case 2: array_spu.self.VertexAttrib2fvARB(attr, (GLfloat *)p); break;
                            case 3: array_spu.self.VertexAttrib3fvARB(attr, (GLfloat *)p); break;
                            case 4: array_spu.self.VertexAttrib4fvARB(attr, (GLfloat *)p); break;
                        }
                        break;
                    case GL_DOUBLE:
                        switch (array->a[attr].size)
                        {
                            case 1: array_spu.self.VertexAttrib1dvARB(attr, (GLdouble *)p); break;
                            case 2: array_spu.self.VertexAttrib2dvARB(attr, (GLdouble *)p); break;
                            case 3: array_spu.self.VertexAttrib3dvARB(attr, (GLdouble *)p); break;
                            case 4: array_spu.self.VertexAttrib4dvARB(attr, (GLdouble *)p); break;
                        }
                        break;
                    default:
                        crWarning("Bad datatype for vertex attribute [%d] array: 0x%x\n",
                                            attr, array->a[attr].type);
                }
            }
        }
    }

    /* Now do conventional arrays, unless overridden by generic arrays above */
    for (unit = 0 ; unit < crStateGetCurrent()->limits.maxTextureUnits ; unit++)
    {
        if (array->t[unit].enabled && !(vpEnabled && array->a[VERT_ATTRIB_TEX0+unit].enabled))
        {
            p = array->t[unit].p + index * array->t[unit].stride;

#ifdef CR_ARB_vertex_buffer_object
            if (array->t[unit].buffer && array->t[unit].buffer->data)
            {
                p = (unsigned char *)(array->t[unit].buffer->data) + (unsigned long)p;
            }
#endif

            switch (array->t[unit].type)
            {
                case GL_SHORT:
                    switch (array->t[unit].size)
                    {
                        case 1: array_spu.self.MultiTexCoord1svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
                        case 2: array_spu.self.MultiTexCoord2svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
                        case 3: array_spu.self.MultiTexCoord3svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
                        case 4: array_spu.self.MultiTexCoord4svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
                    }
                    break;
                case GL_INT:
                    switch (array->t[unit].size)
                    {
                        case 1: array_spu.self.MultiTexCoord1ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
                        case 2: array_spu.self.MultiTexCoord2ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
                        case 3: array_spu.self.MultiTexCoord3ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
                        case 4: array_spu.self.MultiTexCoord4ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
                    }
                    break;
                case GL_FLOAT:
                    switch (array->t[unit].size)
                    {
                        case 1: array_spu.self.MultiTexCoord1fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
                        case 2: array_spu.self.MultiTexCoord2fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
                        case 3: array_spu.self.MultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
                        case 4: array_spu.self.MultiTexCoord4fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
                    }
                    break;
                case GL_DOUBLE:
                    switch (array->t[unit].size)
                    {
                        case 1: array_spu.self.MultiTexCoord1dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
                        case 2: array_spu.self.MultiTexCoord2dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
                        case 3: array_spu.self.MultiTexCoord3dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
                        case 4: array_spu.self.MultiTexCoord4dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
                    }
                    break;
            }
        }
    }
    if (array->i.enabled)
    {
        p = array->i.p + index * array->i.stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->i.buffer && array->i.buffer->data)
        {
            p = (unsigned char *)(array->i.buffer->data) + (unsigned long)p;
        }
#endif

        switch (array->i.type)
        {
            case GL_SHORT: array_spu.self.Indexsv((GLshort *)p); break;
            case GL_INT: array_spu.self.Indexiv((GLint *)p); break;
            case GL_FLOAT: array_spu.self.Indexfv((GLfloat *)p); break;
            case GL_DOUBLE: array_spu.self.Indexdv((GLdouble *)p); break;
        }
    }
    if (array->c.enabled && !(vpEnabled && array->a[VERT_ATTRIB_COLOR0].enabled))
    {
        p = array->c.p + index * array->c.stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->c.buffer && array->c.buffer->data)
        {
            p = (unsigned char *)(array->c.buffer->data) + (unsigned long)p;
        }
#endif

        switch (array->c.type)
        {
            case GL_BYTE:
                switch (array->c.size)
                {
                    case 3: array_spu.self.Color3bv((GLbyte *)p); break;
                    case 4: array_spu.self.Color4bv((GLbyte *)p); break;
                }
                break;
            case GL_UNSIGNED_BYTE:
                switch (array->c.size)
                {
                    case 3: array_spu.self.Color3ubv((GLubyte *)p); break;
                    case 4: array_spu.self.Color4ubv((GLubyte *)p); break;
                }
                break;
            case GL_SHORT:
                switch (array->c.size)
                {
                    case 3: array_spu.self.Color3sv((GLshort *)p); break;
                    case 4: array_spu.self.Color4sv((GLshort *)p); break;
                }
                break;
            case GL_UNSIGNED_SHORT:
                switch (array->c.size)
                {
                    case 3: array_spu.self.Color3usv((GLushort *)p); break;
                    case 4: array_spu.self.Color4usv((GLushort *)p); break;
                }
                break;
            case GL_INT:
                switch (array->c.size)
                {
                    case 3: array_spu.self.Color3iv((GLint *)p); break;
                    case 4: array_spu.self.Color4iv((GLint *)p); break;
                }
                break;
            case GL_UNSIGNED_INT:
                switch (array->c.size)
                {
                    case 3: array_spu.self.Color3uiv((GLuint *)p); break;
                    case 4: array_spu.self.Color4uiv((GLuint *)p); break;
                }
                break;
            case GL_FLOAT:
                switch (array->c.size)
                {
                    case 3: array_spu.self.Color3fv((GLfloat *)p); break;
                    case 4: array_spu.self.Color4fv((GLfloat *)p); break;
                }
                break;
            case GL_DOUBLE:
                switch (array->c.size)
                {
                    case 3: array_spu.self.Color3dv((GLdouble *)p); break;
                    case 4: array_spu.self.Color4dv((GLdouble *)p); break;
                }
                break;
        }
    }
    if (array->n.enabled && !(vpEnabled && array->a[VERT_ATTRIB_NORMAL].enabled))
    {
        p = array->n.p + index * array->n.stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->n.buffer && array->n.buffer->data)
        {
            p = (unsigned char *)(array->n.buffer->data) + (unsigned long)p;
        }
#endif

        switch (array->n.type)
        {
            case GL_BYTE: array_spu.self.Normal3bv((GLbyte *)p); break;
            case GL_SHORT: array_spu.self.Normal3sv((GLshort *)p); break;
            case GL_INT: array_spu.self.Normal3iv((GLint *)p); break;
            case GL_FLOAT: array_spu.self.Normal3fv((GLfloat *)p); break;
            case GL_DOUBLE: array_spu.self.Normal3dv((GLdouble *)p); break;
        }
    }
#ifdef CR_EXT_secondary_color
    if (array->s.enabled && !(vpEnabled && array->a[VERT_ATTRIB_COLOR1].enabled))
    {
        p = array->s.p + index * array->s.stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->s.buffer && array->s.buffer->data)
        {
            p = (unsigned char *)(array->s.buffer->data) + (unsigned long)p;
        }
#endif

        switch (array->s.type)
        {
            case GL_BYTE:
                array_spu.self.SecondaryColor3bvEXT((GLbyte *)p); break;
            case GL_UNSIGNED_BYTE:
                array_spu.self.SecondaryColor3ubvEXT((GLubyte *)p); break;
            case GL_SHORT:
                array_spu.self.SecondaryColor3svEXT((GLshort *)p); break;
            case GL_UNSIGNED_SHORT:
                array_spu.self.SecondaryColor3usvEXT((GLushort *)p); break;
            case GL_INT:
                array_spu.self.SecondaryColor3ivEXT((GLint *)p); break;
            case GL_UNSIGNED_INT:
                array_spu.self.SecondaryColor3uivEXT((GLuint *)p); break;
            case GL_FLOAT:
                array_spu.self.SecondaryColor3fvEXT((GLfloat *)p); break;
            case GL_DOUBLE:
                array_spu.self.SecondaryColor3dvEXT((GLdouble *)p); break;
        }
    }
#endif // CR_EXT_secondary_color
#ifdef CR_EXT_fog_coord
    if (array->f.enabled && !(vpEnabled && array->a[VERT_ATTRIB_FOG].enabled))
    {
        p = array->f.p + index * array->f.stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->f.buffer && array->f.buffer->data)
        {
            p = (unsigned char *)(array->f.buffer->data) + (unsigned long)p;
        }
#endif

        array_spu.self.FogCoordfEXT( *((GLfloat *) p) );
    }
#endif // CR_EXT_fog_coord

    /* Need to do attrib[0] / vertex position last */
    if (array->a[VERT_ATTRIB_POS].enabled) {
        GLint *iPtr;
        p = array->a[VERT_ATTRIB_POS].p + index * array->a[VERT_ATTRIB_POS].stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->a[VERT_ATTRIB_POS].buffer && array->a[VERT_ATTRIB_POS].buffer->data)
        {
            p = (unsigned char *)(array->a[VERT_ATTRIB_POS].buffer->data) + (unsigned long)p;
        }
#endif

        switch (array->a[VERT_ATTRIB_POS].type)
        {
            case GL_SHORT:
                switch (array->a[VERT_ATTRIB_POS].size)
                {
                    case 1: array_spu.self.VertexAttrib1svARB(0, (GLshort *)p); break;
                    case 2: array_spu.self.VertexAttrib2svARB(0, (GLshort *)p); break;
                    case 3: array_spu.self.VertexAttrib3svARB(0, (GLshort *)p); break;
                    case 4: array_spu.self.VertexAttrib4svARB(0, (GLshort *)p); break;
                }
                break;
            case GL_INT:
                iPtr = (GLint *) p;
                switch (array->a[VERT_ATTRIB_POS].size)
                {
                    case 1: array_spu.self.VertexAttrib1fARB(0, p[0]); break;
                    case 2: array_spu.self.VertexAttrib2fARB(0, p[0], p[1]); break;
                    case 3: array_spu.self.VertexAttrib3fARB(0, p[0], p[1], p[2]); break;
                    case 4: array_spu.self.VertexAttrib4fARB(0, p[0], p[1], p[2], p[3]); break;
                }
                break;
            case GL_FLOAT:
                switch (array->a[VERT_ATTRIB_POS].size)
                {
                    case 1: array_spu.self.VertexAttrib1fvARB(0, (GLfloat *)p); break;
                    case 2: array_spu.self.VertexAttrib2fvARB(0, (GLfloat *)p); break;
                    case 3: array_spu.self.VertexAttrib3fvARB(0, (GLfloat *)p); break;
                    case 4: array_spu.self.VertexAttrib4fvARB(0, (GLfloat *)p); break;
                }
                break;
            case GL_DOUBLE:
                switch (array->a[VERT_ATTRIB_POS].size)
                {
                    case 1: array_spu.self.VertexAttrib1dvARB(0, (GLdouble *)p); break;
                    case 2: array_spu.self.VertexAttrib2dvARB(0, (GLdouble *)p); break;
                    case 3: array_spu.self.VertexAttrib3dvARB(0, (GLdouble *)p); break;
                    case 4: array_spu.self.VertexAttrib4dvARB(0, (GLdouble *)p); break;
                }
                break;
            default:
                crWarning("Bad datatype for vertex attribute [0] array: 0x%x\n", array->a[0].type);
        }
    }
    else if (array->v.enabled)
    {
        p = array->v.p + index * array->v.stride;

#ifdef CR_ARB_vertex_buffer_object
        if (array->v.buffer && array->v.buffer->data)
        {
            p = (unsigned char *)(array->v.buffer->data) + (unsigned long)p;
        }
#endif

        switch (array->v.type)
        {
            case GL_SHORT:
                switch (array->v.size)
                {
                    case 2: array_spu.self.Vertex2sv((GLshort *)p); break;
                    case 3: array_spu.self.Vertex3sv((GLshort *)p); break;
                    case 4: array_spu.self.Vertex4sv((GLshort *)p); break;
                }
                break;
            case GL_INT:
                switch (array->v.size)
                {
                    case 2: array_spu.self.Vertex2iv((GLint *)p); break;
                    case 3: array_spu.self.Vertex3iv((GLint *)p); break;
                    case 4: array_spu.self.Vertex4iv((GLint *)p); break;
                }
                break;
            case GL_FLOAT:
                switch (array->v.size)
                {
                    case 2: array_spu.self.Vertex2fv((GLfloat *)p); break;
                    case 3: array_spu.self.Vertex3fv((GLfloat *)p); break;
                    case 4: array_spu.self.Vertex4fv((GLfloat *)p); break;
                }
                break;
            case GL_DOUBLE:
                switch (array->v.size)
                {
                    case 2: array_spu.self.Vertex2dv((GLdouble *)p); break;
                    case 3: array_spu.self.Vertex3dv((GLdouble *)p); break;
                    case 4: array_spu.self.Vertex4dv((GLdouble *)p); break;
                }
                break;
            default:
                crWarning("Bad datatype for vertex array: 0x%x\n", array->v.type);
        }
    }
}
Пример #24
0
void SERVER_DISPATCH_APIENTRY
crServerDispatchMakeCurrent( GLint window, GLint nativeWindow, GLint context )
{
    CRMuralInfo *mural, *oldMural;
    CRContextInfo *ctxInfo = NULL;
    CRContext *ctx, *oldCtx = NULL;

    if (context >= 0 && window >= 0) {
        mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
        if (!mural)
        {
            crWarning("CRServer: invalid window %d passed to crServerDispatchMakeCurrent()", window);
            return;
        }

        /* Update the state tracker's current context */
        ctxInfo = (CRContextInfo *) crHashtableSearch(cr_server.contextTable, context);
        if (!ctxInfo) {
            crWarning("CRserver: NULL context in MakeCurrent %d", context);
            return;
        }
    }
    else {
#if 0
        oldMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, cr_server.currentWindow);
        if (oldMural && oldMural->bUseFBO && crServerSupportRedirMuralFBO())
        {
            if (!crStateGetCurrent()->framebufferobject.drawFB)
            {
                cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
            }
            if (!crStateGetCurrent()->framebufferobject.readFB)
            {
                cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
            }
        }

        ctxInfo = &cr_server.MainContextInfo;
        window = -1;
        mural = NULL;
#endif
        cr_server.bForceMakeCurrentOnClientSwitch = GL_TRUE;
        return;
    }

    cr_server.bForceMakeCurrentOnClientSwitch = GL_FALSE;

    ctx = ctxInfo->pContext;
    CRASSERT(ctx);

    oldMural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, cr_server.currentWindow);

    /* Ubuntu 11.04 hosts misbehave if context window switch is
     * done with non-default framebuffer object settings.
     * crStateSwichPrepare & crStateSwichPostprocess are supposed to work around this problem
     * crStateSwichPrepare restores the FBO state to its default values before the context window switch,
     * while crStateSwichPostprocess restores it back to the original values */
    oldCtx = crStateSwichPrepare(ctx, cr_server.bUseMultipleContexts, oldMural && oldMural->bUseFBO && crServerSupportRedirMuralFBO() ? oldMural->idFBO : 0);

    /*
    crDebug("**** %s client %d  curCtx=%d curWin=%d", __func__,
                    cr_server.curClient->number, ctxPos, window);
    */
    cr_server.curClient->currentContextNumber = context;
    cr_server.curClient->currentCtxInfo = ctxInfo;
    cr_server.curClient->currentMural = mural;
    cr_server.curClient->currentWindow = window;

    CRASSERT(cr_server.curClient->currentCtxInfo);
    CRASSERT(cr_server.curClient->currentCtxInfo->pContext);

    /* This is a hack to force updating the 'current' attribs */
    crStateUpdateColorBits();

    if (ctx)
        crStateSetCurrentPointers( ctx, &(cr_server.current) );

    /* check if being made current for first time, update viewport */
#if 0
    if (ctx) {
        /* initialize the viewport */
        if (ctx->viewport.viewportW == 0) {
            ctx->viewport.viewportW = mural->width;
            ctx->viewport.viewportH = mural->height;
            ctx->viewport.scissorW = mural->width;
            ctx->viewport.scissorH = mural->height;
        }
    }
#endif

    /*
    crDebug("**** %s  currentWindow %d  newWindow %d", __func__,
                    cr_server.currentWindow, window);
    */

    if (1/*cr_server.firstCallMakeCurrent ||
            cr_server.currentWindow != window ||
            cr_server.currentNativeWindow != nativeWindow*/) {
        /* Since the cr server serialized all incoming contexts/clients into
         * one output stream of GL commands, we only need to call the head
         * SPU's MakeCurrent() function once.
         * BUT, if we're rendering to multiple windows, we do have to issue
         * MakeCurrent() calls sometimes.  The same GL context will always be
         * used though.
         */
        cr_server.head_spu->dispatch_table.MakeCurrent( mural->spuWindow,
                                                        nativeWindow,
                                                        ctxInfo->SpuContext >= 0
                                                            ? ctxInfo->SpuContext
                                                              : cr_server.MainContextInfo.SpuContext);
        cr_server.firstCallMakeCurrent = GL_FALSE;
        cr_server.currentCtxInfo = ctxInfo;
        cr_server.currentWindow = window;
        cr_server.currentNativeWindow = nativeWindow;
    }

    /* This used to be earlier, after crStateUpdateColorBits() call */
    crStateMakeCurrent( ctx );

    crStateSwichPostprocess(oldCtx, cr_server.bUseMultipleContexts, mural->bUseFBO && crServerSupportRedirMuralFBO() ? mural->idFBO : 0);

    if (!ctx->framebufferobject.drawFB
            && (ctx->buffer.drawBuffer == GL_FRONT || ctx->buffer.drawBuffer == GL_FRONT_LEFT))
        cr_server.curClient->currentMural->bFbDraw = GL_TRUE;

    if (!mural->bUseFBO)
    {
        ctx->buffer.width = mural->width;
        ctx->buffer.height = mural->height;
    }
    else
    {
        ctx->buffer.width = 0;
        ctx->buffer.height = 0;
    }
}
Пример #25
0
static void ARRAYSPU_APIENTRY arrayspu_DrawElements(GLenum mode, GLsizei count,
                                                    GLenum type, const GLvoid *indices)
{
    int i;
    GLubyte *p = (GLubyte *)indices;
#ifdef CR_ARB_vertex_buffer_object
    CRBufferObject *elementsBuffer = crStateGetCurrent()->bufferobject.elementsBuffer;
#endif

    if (count < 0)
    {
        crError("array_spu.self.DrawElements passed negative count: %d", count);
    }

    if (mode > GL_POLYGON)
    {
        crError("array_spu.self.DrawElements called with invalid mode: %d", mode);
    }

    if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT && type != GL_UNSIGNED_INT)
    {
        crError("array_spu.self.DrawElements called with invalid type: %d", type);
    }

#ifdef CR_ARB_vertex_buffer_object
    if (elementsBuffer && elementsBuffer->data)
    {
        p = (unsigned char *)(elementsBuffer->data) + (unsigned long)p;
    }
#endif
    //crDebug("arrayspu_DrawElements mode:0x%x, count:%d, type:0x%x", mode, count, type);
    

    array_spu.self.Begin(mode);
    switch (type)
    {
        case GL_UNSIGNED_BYTE:
            for (i=0; i<count; i++)
            {
                array_spu.self.ArrayElement((GLint) *p++);
            }
            break;
        case GL_UNSIGNED_SHORT:
            for (i=0; i<count; i++)
            {
                array_spu.self.ArrayElement((GLint) * (GLushort *) p);
                p+=sizeof (GLushort);
            }
            break;
        case GL_UNSIGNED_INT:
            for (i=0; i<count; i++)
            {
                array_spu.self.ArrayElement((GLint) * (GLuint *) p);
                p+=sizeof (GLuint);
            }
            break;
        default:
            crError( "this can't happen: array_spu.self.DrawElements" );
            break;
    }
    array_spu.self.End();
}
Пример #26
0
void SERVER_DISPATCH_APIENTRY
crServerDispatchSwapBuffers( GLint window, GLint flags )
{
  CRMuralInfo *mural;
  CRContext *ctx;

#ifdef VBOXCR_LOGFPS
  static VBOXCRFPS Fps;
  static bool bFpsInited = false;

  if (!bFpsInited)
  {
      vboxCrFpsInit(&Fps, 64 /* cPeriods */);
      bFpsInited = true;
  }
  vboxCrFpsReportFrame(&Fps);
  if(!(vboxCrFpsGetNumFrames(&Fps) % 31))
  {
      double fps = vboxCrFpsGetFps(&Fps);
      double bps = vboxCrFpsGetBps(&Fps);
      double bpsSent = vboxCrFpsGetBpsSent(&Fps);
      double cps = vboxCrFpsGetCps(&Fps);
      double ops = vboxCrFpsGetOps(&Fps);
      double tup = vboxCrFpsGetTimeProcPercent(&Fps);
      crDebug("fps: %f, rec Mbps: %.1f, send Mbps: %.1f, cps: %.1f, ops: %.0f, host %.1f%%", 
              fps, bps/(1024.0*1024.0), bpsSent/(1024.0*1024.0), cps, ops, tup);
  }
#endif
	mural = (CRMuralInfo *) crHashtableSearch(cr_server.muralTable, window);
	if (!mural) {
		 return;
	}


	if (cr_server.only_swap_once)
	{
		/* NOTE: we only do the clear for the _last_ client in the list.
		 * This is because in multi-threaded apps the zeroeth client may
		 * be idle and never call glClear at all.  See threadtest.c
		 * It's pretty likely that the last client will be active.
		 */
		if (cr_server.curClient != cr_server.clients[cr_server.numClients - 1])
		{
			return;
		}
	}

#if 0
	if (cr_server.overlapBlending)
	{
		int a;
		CRPoly *p;
		GLboolean lighting, fog, blend, cull, tex[3];
		GLenum mm, blendSrc, blendDst;
		GLcolorf col;
		CRContext *ctx = crStateGetCurrent();
		const CRmatrix *baseProj;

		/* 
		 * I've probably missed some state here, or it
	 	 * might be easier just to push/pop it....
		 */
		lighting = ctx->lighting.lighting;
		fog		 = ctx->fog.enable;
		tex[0] = 0;
		for (a=0; a<CR_MAX_TEXTURE_UNITS; a++)
		{
			if (!ctx->texture.unit[a].enabled1D) continue;
	
			tex[0] 	 = 1;
			break;
		}
		tex[1] = 0;
		for	(a=0; a<CR_MAX_TEXTURE_UNITS; a++)
		{
			if (!ctx->texture.unit[a].enabled2D) continue;

			tex[1] 	 = 1;
			break;
		}
		tex[2] = 0;
		for (a=0; a<CR_MAX_TEXTURE_UNITS; a++)
		{	
			if (!ctx->texture.unit[a].enabled3D) continue;
	
			tex[2] 	 = 1;
			break;
		}

		cull	 = ctx->polygon.cullFace;
		blend	 = ctx->buffer.blend;
		blendSrc = ctx->buffer.blendSrcRGB;
		blendDst = ctx->buffer.blendDstRGB;
		mm = ctx->transform.matrixMode;
		col.r = ctx->current.vertexAttrib[VERT_ATTRIB_COLOR0][0];
		col.g = ctx->current.vertexAttrib[VERT_ATTRIB_COLOR0][1];
		col.b = ctx->current.vertexAttrib[VERT_ATTRIB_COLOR0][2];
		col.a = ctx->current.vertexAttrib[VERT_ATTRIB_COLOR0][3];

		baseProj = &(cr_server.curClient->currentMural->extents[0].baseProjection);
	
		switch(mm)
		{
				case GL_PROJECTION:
					cr_server.head_spu->dispatch_table.PushMatrix();
					cr_server.head_spu->dispatch_table.LoadMatrixf((GLfloat *) baseProj);
					cr_server.head_spu->dispatch_table.MultMatrixf(cr_server.unnormalized_alignment_matrix);
					cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
					cr_server.head_spu->dispatch_table.PushMatrix();
					cr_server.head_spu->dispatch_table.LoadIdentity();
					break;
				
				default:
					cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
					/* fall through */
	
				case GL_MODELVIEW:
					cr_server.head_spu->dispatch_table.PushMatrix();
					cr_server.head_spu->dispatch_table.LoadIdentity();
					cr_server.head_spu->dispatch_table.MatrixMode(GL_PROJECTION);
					cr_server.head_spu->dispatch_table.PushMatrix();
					cr_server.head_spu->dispatch_table.LoadMatrixf((GLfloat *) baseProj);
					cr_server.head_spu->dispatch_table.MultMatrixf(cr_server.unnormalized_alignment_matrix);
					break;	
		}
	
		/* fix state */
		if (lighting)
			cr_server.head_spu->dispatch_table.Disable(GL_LIGHTING);
		if (fog)
			cr_server.head_spu->dispatch_table.Disable(GL_FOG);
		if (tex[0])
			cr_server.head_spu->dispatch_table.Disable(GL_TEXTURE_1D);
		if (tex[1])
			cr_server.head_spu->dispatch_table.Disable(GL_TEXTURE_2D);
		if (tex[2])
			cr_server.head_spu->dispatch_table.Disable(GL_TEXTURE_3D);
		if (cull)
			cr_server.head_spu->dispatch_table.Disable(GL_CULL_FACE);

		/* Regular Blending */
		if (cr_server.overlapBlending == 1)
		{
			if (!blend)
				cr_server.head_spu->dispatch_table.Enable(GL_BLEND);
			if ((blendSrc != GL_ZERO) && (blendDst != GL_SRC_ALPHA))
				cr_server.head_spu->dispatch_table.BlendFunc(GL_ZERO, GL_SRC_ALPHA);

			/* draw the blends */
			for (a=1; a<cr_server.num_overlap_levels; a++)
			{
				if (a-1 < cr_server.num_overlap_intens)
				{
					cr_server.head_spu->dispatch_table.Color4f(0, 0, 0, 
											cr_server.overlap_intens[a-1]);
				}
				else
				{
					cr_server.head_spu->dispatch_table.Color4f(0, 0, 0, 1);
				}
		
				p = cr_server.overlap_geom[a];
				while (p)
				{
					/* hopefully this isnt concave... */
					__draw_poly(p);
					p = p->next;
				}	
			}

			if (!blend)
				cr_server.head_spu->dispatch_table.Disable(GL_BLEND);
			if ((blendSrc != GL_ZERO) && (blendDst != GL_SRC_ALPHA))
				cr_server.head_spu->dispatch_table.BlendFunc(blendSrc, blendDst);
		}
		else
		/* Knockout Blending */
		{
			cr_server.head_spu->dispatch_table.Color4f(0, 0, 0, 1);

			if (blend)
				cr_server.head_spu->dispatch_table.Disable(GL_BLEND);
			p = cr_server.overlap_knockout;
			while (p)
			{
				__draw_poly(p);
				p = p->next;
			}	
			if (blend)
				cr_server.head_spu->dispatch_table.Enable(GL_BLEND);
		}


		/* return things to normal */
		switch (mm)
		{
			case GL_PROJECTION:
				cr_server.head_spu->dispatch_table.PopMatrix();
				cr_server.head_spu->dispatch_table.MatrixMode(GL_PROJECTION);
				cr_server.head_spu->dispatch_table.PopMatrix();
				break;
			case GL_MODELVIEW:
				cr_server.head_spu->dispatch_table.PopMatrix();
				cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
				cr_server.head_spu->dispatch_table.PopMatrix();
				break;
			default:
				cr_server.head_spu->dispatch_table.PopMatrix();
				cr_server.head_spu->dispatch_table.MatrixMode(GL_MODELVIEW);
				cr_server.head_spu->dispatch_table.PopMatrix();
				cr_server.head_spu->dispatch_table.MatrixMode(mm);
				break;
		}

		if (lighting)
			cr_server.head_spu->dispatch_table.Enable(GL_LIGHTING);
		if (fog)
			cr_server.head_spu->dispatch_table.Enable(GL_FOG);
		if (tex[0])
			cr_server.head_spu->dispatch_table.Enable(GL_TEXTURE_1D);
		if (tex[1])
			cr_server.head_spu->dispatch_table.Enable(GL_TEXTURE_2D);
		if (tex[2])
			cr_server.head_spu->dispatch_table.Enable(GL_TEXTURE_3D);
		if (cull)
			cr_server.head_spu->dispatch_table.Enable(GL_CULL_FACE);
	
		cr_server.head_spu->dispatch_table.Color4f(col.r, col.g, col.b, col.a);
	}
#endif

	/* Check if using a file network */
	if (!cr_server.clients[0]->conn->actual_network && window == MAGIC_OFFSET)
		window = 0;

	ctx = crStateGetCurrent();

    if (ctx->framebufferobject.drawFB
            || (ctx->buffer.drawBuffer != GL_FRONT && ctx->buffer.drawBuffer != GL_FRONT_LEFT))
        cr_server.curClient->currentMural->bFbDraw = GL_FALSE;

    if (crServerIsRedirectedToFBO())
    {
        crServerMuralFBOSwapBuffers(mural);
        crServerPresentFBO(mural);
    }
    else
    {
        cr_server.head_spu->dispatch_table.SwapBuffers( mural->spuWindow, flags );
    }
}