void STATE_APIENTRY crStatePolygonStipple (PCRStateTracker pState, const GLubyte *p) 
{
    CRContext *g = GetCurrentContext(pState);
    CRPolygonState *poly = &(g->polygon);
        CRStateBits *sb = GetCurrentBits(pState);
    CRPolygonBits *pb = &(sb->polygon);

    if (g->current.inBeginEnd) 
    {
        crStateError(pState, __LINE__, __FILE__, GL_INVALID_OPERATION,
                "glPolygonStipple called in begin/end");
        return;
    }

    FLUSH();

    if (!p && !crStateIsBufferBound(pState, GL_PIXEL_UNPACK_BUFFER_ARB))
    {
        crDebug("Void pointer passed to PolygonStipple");
        return;
    }

    /** @todo track mask if buffer is bound?*/
    if (!crStateIsBufferBound(pState, GL_PIXEL_UNPACK_BUFFER_ARB))
    {
        crMemcpy((char*)poly->stipple, (char*)p, 128);
    }

    DIRTY(pb->dirty, g->neg_bitid);
    DIRTY(pb->stipple, g->neg_bitid);
}
void PACK_APIENTRY crPackPolygonStipple( const GLubyte *mask )
{
    CR_GET_PACKER_CONTEXT(pc);
    unsigned char *data_ptr;
    int nodata = crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB);
    int packet_length = sizeof(int);

    if (nodata)
        packet_length += sizeof(GLint);
    else
        packet_length += 32*32/8;

    CR_GET_BUFFERED_POINTER(pc, packet_length );
    WRITE_DATA_AI(int, nodata);
    if (nodata)
    {
        WRITE_DATA_AI(GLint, (GLint)(uintptr_t)mask);
    }
    else
    {
       crMemcpy( data_ptr, mask, 32*32/8 );
    }
    WRITE_OPCODE( pc, CR_POLYGONSTIPPLE_OPCODE );
    CR_UNLOCK_PACKER_CONTEXT(pc);
}
static unsigned char * __gl_HandlePixelMapData(GLenum map, GLsizei mapsize, int size_of_value, const GLvoid *values)
{
    int nodata = (values == NULL) || crStateIsBufferBound(g_pStateTracker, GL_PIXEL_UNPACK_BUFFER_ARB);
    int packet_length = 
        sizeof( map ) + 
        sizeof( mapsize ) + sizeof(int) + sizeof(GLint);
    unsigned char *data_ptr;

    if (!nodata)
    {
        packet_length += mapsize*size_of_value;
    }

    data_ptr = (unsigned char *) crPackAlloc( packet_length );

    WRITE_DATA( 0, GLenum, map );
    WRITE_DATA( 4, GLsizei, mapsize );
    WRITE_DATA( 8, int, nodata);
    WRITE_DATA( 12, GLint, (GLint)(uintptr_t)values);

    if (!nodata)
    {
        crMemcpy( data_ptr + 16, values, mapsize*size_of_value );
    }

    return data_ptr;
}
void PACK_APIENTRY crPackDrawPixels(GLsizei width, GLsizei height, 
                                    GLenum format, GLenum type,
                                    const GLvoid *pixels,
                                    const CRPixelPackState *unpackstate )
{
    unsigned char *data_ptr;
    int packet_length, imagesize;
    int noimagedata = (pixels == NULL) || crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB);

    packet_length = 
        sizeof( width ) +
        sizeof( height ) +
        sizeof( format ) +
        sizeof( type ) + sizeof(int) + sizeof(GLint);

    if (!noimagedata)
    {
        imagesize = crImageSize( format, type, width, height );

        if (imagesize<=0)
        {
            crDebug("crPackDrawPixels: 0 image size, ignoring");
            return;
        }
        packet_length += imagesize;
    }

    data_ptr = (unsigned char *) crPackAlloc( packet_length );
    WRITE_DATA( 0, GLsizei, width );
    WRITE_DATA( 4, GLsizei, height );
    WRITE_DATA( 8, GLenum, format );
    WRITE_DATA( 12, GLenum, type );
    WRITE_DATA( 16, GLint, noimagedata );
    WRITE_DATA( 20, GLint, (GLint) (uintptr_t) pixels );

    if (!noimagedata)
    {
        crPixelCopy2D(width, height,
                      (void *) (data_ptr + 24), format, type, NULL, /* dst */
                      pixels, format, type, unpackstate);  /* src */
    }

    crHugePacket( CR_DRAWPIXELS_OPCODE, data_ptr );
    crPackFree( data_ptr );
}
void crUnpackBitmap(PCrUnpackerState pState)
{
    CHECK_BUFFER_SIZE_STATIC_LAST(pState, sizeof(int) + 28, GLint);

    GLsizei width   = READ_DATA(pState, sizeof( int ) + 0, GLsizei );
    GLsizei height  = READ_DATA(pState,sizeof( int ) + 4, GLsizei );
    GLfloat xorig   = READ_DATA(pState, sizeof( int ) + 8, GLfloat );
    GLfloat yorig   = READ_DATA(pState, sizeof( int ) + 12, GLfloat );
    GLfloat xmove   = READ_DATA(pState, sizeof( int ) + 16, GLfloat );
    GLfloat ymove   = READ_DATA(pState, sizeof( int ) + 20, GLfloat );
    GLuint noimagedata = READ_DATA(pState, sizeof( int ) + 24, GLuint );
    GLubyte *bitmap;

    if (noimagedata && !crStateIsBufferBound(pState->pStateTracker, GL_PIXEL_UNPACK_BUFFER_ARB))
        return;

    if (noimagedata)
        bitmap = (GLubyte *) (uintptr_t) READ_DATA(pState,sizeof(int) + 28, GLint);
    else
    {
        /* Each pixel is one bit => 8 pixels per byte. */
        size_t cbImg = crImageSize(GL_COLOR_INDEX, GL_BITMAP, width, height);
        if (RT_UNLIKELY(cbImg == 0))
        {
            pState->rcUnpack = VERR_INVALID_PARAMETER;
            return;
        }

        bitmap = DATA_POINTER(pState, sizeof(int) + 32, GLubyte );
        CHECK_ARRAY_SIZE_FROM_PTR_UPDATE_LAST(pState, bitmap, cbImg, GLubyte);
    }

    pState->pDispatchTbl->PixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
    pState->pDispatchTbl->PixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
    pState->pDispatchTbl->PixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
    pState->pDispatchTbl->PixelStorei( GL_UNPACK_ALIGNMENT, 1 );

    pState->pDispatchTbl->Bitmap( width, height, xorig, yorig, xmove, ymove, bitmap );

    INCR_VAR_PTR(pState);
}
void PACK_APIENTRY crPackBitmap(GLsizei width, GLsizei height, 
                                GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
                                const GLubyte *bitmap, const CRPixelPackState *unpack )
{
    const int noimagedata = (bitmap == NULL) || crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB);
    unsigned char *data_ptr;
    int data_length = 0;
    GLubyte *destBitmap = NULL;
    int packet_length = 
        sizeof( width ) + 
        sizeof( height ) +
        sizeof( xorig ) + 
        sizeof( yorig ) + 
        sizeof( xmove ) + 
        sizeof( ymove ) +
        sizeof( GLuint ) + sizeof(GLint);

    if (!noimagedata)
    {
        data_length = CEIL8(width) * height / 8;
        packet_length += data_length;
    }

    data_ptr = (unsigned char *) crPackAlloc( packet_length );

    WRITE_DATA( 0, GLsizei, width );
    WRITE_DATA( 4, GLsizei, height );
    WRITE_DATA( 8, GLfloat, xorig );
    WRITE_DATA( 12, GLfloat, yorig );
    WRITE_DATA( 16, GLfloat, xmove );
    WRITE_DATA( 20, GLfloat, ymove );
    WRITE_DATA( 24, GLuint, noimagedata );
    WRITE_DATA( 28, GLint, (GLint) (uintptr_t) bitmap);

    if (!noimagedata)
        crBitmapCopy(width, height, (GLubyte *)(data_ptr + 32), bitmap, unpack);

    crHugePacket( CR_BITMAP_OPCODE, data_ptr );
    crPackFree( data_ptr );
}
Beispiel #7
0
void PACKSPU_APIENTRY packspu_GetPixelMapusv( GLenum map, GLushort * values )
{
    GET_THREAD(thread);
    int writeback = 1;

    if (pack_spu.swap)
    {
        crPackGetPixelMapusvSWAP( map, values, &writeback );
    }
    else
    {
        crPackGetPixelMapusv( map, values, &writeback );
    }

#ifdef CR_ARB_pixel_buffer_object
    if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
#endif
    {
        packspuFlush( (void *) thread );
        CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
    }
}
Beispiel #8
0
void PACKSPU_APIENTRY packspu_GetPolygonStipple( GLubyte * mask )
{
    GET_THREAD(thread);
    int writeback = 1;

    if (pack_spu.swap)
    {
        crPackGetPolygonStippleSWAP( mask, &writeback );
    }
    else
    {
        crPackGetPolygonStipple( mask, &writeback );
    }

#ifdef CR_ARB_pixel_buffer_object
    if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
#endif
    {
        packspuFlush( (void *) thread );
        CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
    }
}
void crUnpackDrawPixels(PCrUnpackerState pState)
{
    CHECK_BUFFER_SIZE_STATIC_LAST(pState, sizeof(int) + 20, GLint);

    GLsizei width  = READ_DATA(pState, sizeof( int ) + 0, GLsizei );
    GLsizei height = READ_DATA(pState, sizeof( int ) + 4, GLsizei );
    GLenum format  = READ_DATA(pState, sizeof( int ) + 8, GLenum );
    GLenum type    = READ_DATA(pState, sizeof( int ) + 12, GLenum );
    GLint noimagedata = READ_DATA(pState, sizeof( int ) + 16, GLint );
    GLvoid *pixels;

    if (noimagedata && !crStateIsBufferBound(pState->pStateTracker, GL_PIXEL_UNPACK_BUFFER_ARB))
        return;

    if (noimagedata)
        pixels = (void*) (uintptr_t) READ_DATA(pState, sizeof( int ) + 20, GLint);
    else
    {
        size_t cbImg = crImageSize( format, type, width, height );
        if (RT_UNLIKELY(cbImg == 0))
        {
            pState->rcUnpack = VERR_INVALID_PARAMETER;
            return;
        }

        pixels = DATA_POINTER(pState, sizeof( int ) + 24, GLvoid );
        CHECK_ARRAY_SIZE_FROM_PTR_UPDATE_LAST(pState, pixels, cbImg, GLubyte);
    }

    pState->pDispatchTbl->PixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
    pState->pDispatchTbl->PixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
    pState->pDispatchTbl->PixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
    pState->pDispatchTbl->PixelStorei( GL_UNPACK_ALIGNMENT, 1 );

    pState->pDispatchTbl->DrawPixels( width, height, format, type, pixels );

    INCR_VAR_PTR(pState);
}
Beispiel #10
0
void PACKSPU_APIENTRY packspu_GetPixelMapfv( GLenum map, GLfloat * values )
{
    GET_THREAD(thread);
    int writeback = 1;

    if (pack_spu.swap)
    {
        crPackGetPixelMapfvSWAP( map, values, &writeback );
    }
    else
    {
        crPackGetPixelMapfv( map, values, &writeback );
    }

#ifdef CR_ARB_pixel_buffer_object
    if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
#endif
    {
        packspuFlush( (void *) thread );
        while (writeback)
            crNetRecv();
    }
}
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);
        }
    }
}
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);
    }
}