/* Copyright (c) 2001, Stanford University
* All rights reserved
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#include "packer.h"
#include "cr_pixeldata.h"
#include "cr_error.h"
#include "cr_mem.h"
#include "cr_version.h"
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 PACK_APIENTRY crPackReadPixels(GLint x, GLint y, GLsizei width,
GLsizei height, GLenum format,
GLenum type, GLvoid *pixels,
const CRPixelPackState *packstate,
int *writeback)
{
CR_GET_PACKER_CONTEXT(pc);
unsigned char *data_ptr;
GLint stride = 0;
GLint bytes_per_row;
int bytes_per_pixel;
*writeback = 0;
bytes_per_pixel = crPixelSize(format, type);
if (bytes_per_pixel <= 0) {
char string[80];
sprintf(string, "crPackReadPixels(format 0x%x or type 0x%x)", format, type);
__PackError(__LINE__, __FILE__, GL_INVALID_ENUM, string);
return;
}
/* default bytes_per_row so crserver can allocate memory */
bytes_per_row = width * bytes_per_pixel;
stride = bytes_per_row;
if (packstate->alignment != 1) {
GLint remainder = bytes_per_row % packstate->alignment;
if (remainder)
stride = bytes_per_row + (packstate->alignment - remainder);
}
CR_GET_BUFFERED_POINTER(pc, 48 + sizeof(CRNetworkPointer) );
WRITE_DATA( 0, GLint, x );
WRITE_DATA( 4, GLint, y );
WRITE_DATA( 8, GLsizei, width );
WRITE_DATA( 12, GLsizei, height );
WRITE_DATA( 16, GLenum, format );
WRITE_DATA( 20, GLenum, type );
WRITE_DATA( 24, GLint, stride ); /* XXX not really used! */
WRITE_DATA( 28, GLint, packstate->alignment );
WRITE_DATA( 32, GLint, packstate->skipRows );
WRITE_DATA( 36, GLint, packstate->skipPixels );
WRITE_DATA( 40, GLint, bytes_per_row );
WRITE_DATA( 44, GLint, packstate->rowLength );
WRITE_NETWORK_POINTER( 48, (char *) pixels );
WRITE_OPCODE( pc, CR_READPIXELS_OPCODE );
CR_CMDBLOCK_CHECK_FLUSH(pc);
CR_UNLOCK_PACKER_CONTEXT(pc);
}
/* Round N up to the next multiple of 8 */
#define CEIL8(N) (((N) + 7) & ~0x7)
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 );
}
/*
ZPix - compressed DrawPixels
*/
void PACK_APIENTRY crPackZPixCR( GLsizei width, GLsizei height,
GLenum format, GLenum type,
GLenum ztype, GLint zparm, GLint length,
const GLvoid *pixels,
const CRPixelPackState *unpackstate )
{
unsigned char *data_ptr;
int packet_length;
(void)unpackstate;
if (pixels == NULL)
{
return;
}
packet_length =
sizeof( int ) + /* packet size */
sizeof( GLenum ) + /* extended opcode */
sizeof( width ) +
sizeof( height ) +
sizeof( format ) +
sizeof( type ) +
sizeof( ztype ) +
sizeof( zparm ) +
sizeof( length );
packet_length += length;
/* XXX JAG
crDebug("PackZPixCR: fb %d x %d, state %d, zlen = %d, plen = %d",
width, height, ztype, length, packet_length);
*/
data_ptr = (unsigned char *) crPackAlloc( packet_length );
WRITE_DATA( 0, GLenum , CR_ZPIXCR_EXTEND_OPCODE );
WRITE_DATA( 4, GLsizei, width );
WRITE_DATA( 8, GLsizei, height );
WRITE_DATA( 12, GLenum, format );
WRITE_DATA( 16, GLenum, type );
WRITE_DATA( 20, GLenum, ztype );
WRITE_DATA( 24, GLint, zparm );
WRITE_DATA( 28, GLint, length );
crMemcpy((void *) (data_ptr+32), pixels, length);
crHugePacket( CR_EXTEND_OPCODE, data_ptr );
crPackFree( data_ptr );
}
void PACK_APIENTRY
crPackGetTexImage( GLenum target, GLint level, GLenum format, GLenum type,
GLvoid * pixels, const CRPixelPackState * packstate,
int * writeback )
{
CR_GET_PACKER_CONTEXT(pc);
unsigned char *data_ptr;
(void) pc;
CR_GET_BUFFERED_POINTER( pc, 40 );
WRITE_DATA( 0, GLint, 40 );
WRITE_DATA( 4, GLenum, CR_GETTEXIMAGE_EXTEND_OPCODE );
WRITE_DATA( 8, GLenum, target );
WRITE_DATA( 12, GLint, level );
WRITE_DATA( 16, GLenum, format );
WRITE_DATA( 20, GLenum, type );
WRITE_NETWORK_POINTER( 24, (void *) pixels );
WRITE_NETWORK_POINTER( 32, (void *) writeback );
WRITE_OPCODE( pc, CR_EXTEND_OPCODE );
CR_CMDBLOCK_CHECK_FLUSH(pc);
CR_UNLOCK_PACKER_CONTEXT(pc);
}