/* Copyright (c) 2001, Stanford University * All rights reserved * * See the file LICENSE.txt for information on redistributing this software. */ #include "cr_spu.h" #include "chromium.h" #include "cr_error.h" #include "cr_mem.h" #include "cr_net.h" #include "cr_pixeldata.h" #include "cr_unpack.h" #include "server_dispatch.h" #include "server.h" void SERVER_DISPATCH_APIENTRY crServerDispatchReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) { CRMessageReadPixels *rp; const GLint stride = READ_DATA( 24, GLint ); const GLint alignment = READ_DATA( 28, GLint ); const GLint skipRows = READ_DATA( 32, GLint ); const GLint skipPixels = READ_DATA( 36, GLint ); const GLint bytes_per_row = READ_DATA( 40, GLint ); const GLint rowLength = READ_DATA( 44, GLint ); const int msg_len = sizeof(*rp) + bytes_per_row * height; CRASSERT(bytes_per_row > 0); #ifdef CR_ARB_pixel_buffer_object if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB)) { GLvoid *pbo_offset; /*pixels are actualy a pointer to location of 8byte network pointer in hgcm buffer regarless of guest/host bitness we're using only 4lower bytes as there're no pbo>4gb (yet?) */ pbo_offset = (GLvoid*) ((uintptr_t) *((GLint*)pixels)); cr_server.head_spu->dispatch_table.ReadPixels(x, y, width, height, format, type, pbo_offset); } else #endif { rp = (CRMessageReadPixels *) crAlloc( msg_len ); /* Note: the ReadPixels data gets densely packed into the buffer * (no skip pixels, skip rows, etc. It's up to the receiver (pack spu, * tilesort spu, etc) to apply the real PixelStore packing parameters. */ cr_server.head_spu->dispatch_table.ReadPixels(x, y, width, height, format, type, rp + 1); rp->header.type = CR_MESSAGE_READ_PIXELS; rp->width = width; rp->height = height; rp->bytes_per_row = bytes_per_row; rp->stride = stride; rp->format = format; rp->type = type; rp->alignment = alignment; rp->skipRows = skipRows; rp->skipPixels = skipPixels; rp->rowLength = rowLength; /* points to the 8-byte network pointer */ crMemcpy( &rp->pixels, pixels, sizeof(rp->pixels) ); crNetSend( cr_server.curClient->conn, NULL, rp, msg_len ); crFree( rp ); } }