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 ); }
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); } }
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); }
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], §r)) { 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, §r, 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); } }