1 #ifndef __GLX_packrender_h__ 2 #define __GLX_packrender_h__ 3 4 /* 5 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 6 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. 7 * 8 * SPDX-License-Identifier: SGI-B-2.0 9 */ 10 11 #include "glxclient.h" 12 13 /* 14 ** The macros in this header convert the client machine's native data types to 15 ** wire protocol data types. The header is part of the porting layer of the 16 ** client library, and it is intended that hardware vendors will rewrite this 17 ** header to suit their own machines. 18 */ 19 20 /* 21 ** Pad a count of bytes to the nearest multiple of 4. The X protocol 22 ** transfers data in 4 byte quantities, so this macro is used to 23 ** insure the right amount of data being sent. 24 */ 25 #define __GLX_PAD(a) (((a)+3) & ~3) 26 27 /* 28 ** Network size parameters 29 */ 30 #define sz_double 8 31 32 /* Setup for all commands */ 33 #define __GLX_DECLARE_VARIABLES() \ 34 struct glx_context *gc; \ 35 GLubyte *pc, *pixelHeaderPC; \ 36 GLuint compsize, cmdlen 37 38 #define __GLX_LOAD_VARIABLES() \ 39 gc = __glXGetCurrentContext(); \ 40 pc = gc->pc; \ 41 /* Muffle compilers */ \ 42 cmdlen = 0; (void)cmdlen; \ 43 compsize = 0; (void)compsize; \ 44 pixelHeaderPC = NULL; (void)pixelHeaderPC 45 46 /* 47 ** Variable sized command support macro. This macro is used by calls 48 ** that are potentially larger than __GLX_SMALL_RENDER_CMD_SIZE. 49 ** Because of their size, they may not automatically fit in the buffer. 50 ** If the buffer can't hold the command then it is flushed so that 51 ** the command will fit in the next buffer. 52 */ 53 #define __GLX_BEGIN_VARIABLE(opcode,size) \ 54 if (pc + (size) > gc->bufEnd) { \ 55 pc = __glXFlushRenderBuffer(gc, pc); \ 56 } \ 57 __GLX_PUT_SHORT(0,size); \ 58 __GLX_PUT_SHORT(2,opcode) 59 60 #define __GLX_BEGIN_VARIABLE_LARGE(opcode,size) \ 61 pc = __glXFlushRenderBuffer(gc, pc); \ 62 __GLX_PUT_LONG(0,size); \ 63 __GLX_PUT_LONG(4,opcode) 64 65 #define __GLX_BEGIN_VARIABLE_WITH_PIXEL(opcode,size) \ 66 if (pc + (size) > gc->bufEnd) { \ 67 pc = __glXFlushRenderBuffer(gc, pc); \ 68 } \ 69 __GLX_PUT_SHORT(0,size); \ 70 __GLX_PUT_SHORT(2,opcode); \ 71 pc += __GLX_RENDER_HDR_SIZE; \ 72 pixelHeaderPC = pc; \ 73 pc += __GLX_PIXEL_HDR_SIZE 74 75 #define __GLX_BEGIN_VARIABLE_LARGE_WITH_PIXEL(opcode,size) \ 76 pc = __glXFlushRenderBuffer(gc, pc); \ 77 __GLX_PUT_LONG(0,size); \ 78 __GLX_PUT_LONG(4,opcode); \ 79 pc += __GLX_RENDER_LARGE_HDR_SIZE; \ 80 pixelHeaderPC = pc; \ 81 pc += __GLX_PIXEL_HDR_SIZE 82 83 #define __GLX_BEGIN_VARIABLE_WITH_PIXEL_3D(opcode,size) \ 84 if (pc + (size) > gc->bufEnd) { \ 85 pc = __glXFlushRenderBuffer(gc, pc); \ 86 } \ 87 __GLX_PUT_SHORT(0,size); \ 88 __GLX_PUT_SHORT(2,opcode); \ 89 pc += __GLX_RENDER_HDR_SIZE; \ 90 pixelHeaderPC = pc; \ 91 pc += __GLX_PIXEL_3D_HDR_SIZE 92 93 #define __GLX_BEGIN_VARIABLE_LARGE_WITH_PIXEL_3D(opcode,size) \ 94 pc = __glXFlushRenderBuffer(gc, pc); \ 95 __GLX_PUT_LONG(0,size); \ 96 __GLX_PUT_LONG(4,opcode); \ 97 pc += __GLX_RENDER_LARGE_HDR_SIZE; \ 98 pixelHeaderPC = pc; \ 99 pc += __GLX_PIXEL_3D_HDR_SIZE 100 101 /* 102 ** Fixed size command support macro. This macro is used by calls that 103 ** are never larger than __GLX_SMALL_RENDER_CMD_SIZE. Because they 104 ** always fit in the buffer, and because the buffer promises to 105 ** maintain enough room for them, we don't need to check for space 106 ** before doing the storage work. 107 */ 108 #define __GLX_BEGIN(opcode,size) \ 109 __GLX_PUT_SHORT(0,size); \ 110 __GLX_PUT_SHORT(2,opcode) 111 112 /* 113 ** Finish a rendering command by advancing the pc. If the pc is now past 114 ** the limit pointer then there is no longer room for a 115 ** __GLX_SMALL_RENDER_CMD_SIZE sized command, which will break the 116 ** assumptions present in the __GLX_BEGIN macro. In this case the 117 ** rendering buffer is flushed out into the X protocol stream (which may 118 ** or may not do I/O). 119 */ 120 #define __GLX_END(size) \ 121 pc += size; \ 122 if (pc > gc->limit) { \ 123 (void) __glXFlushRenderBuffer(gc, pc); \ 124 } else { \ 125 gc->pc = pc; \ 126 } 127 128 /* Array copy macros */ 129 #define __GLX_MEM_COPY(dest,src,bytes) \ 130 if (src && dest) \ 131 memcpy(dest, src, bytes) 132 133 /* Single item copy macros */ 134 #define __GLX_PUT_CHAR(offset,a) \ 135 do { \ 136 int8_t __tmp = (a); \ 137 memcpy((pc + (offset)), &__tmp, 1); \ 138 } while (0) 139 140 #define __GLX_PUT_SHORT(offset,a) \ 141 do { \ 142 int16_t __tmp = (a); \ 143 memcpy((pc + (offset)), &__tmp, 2); \ 144 } while (0) 145 146 #define __GLX_PUT_LONG(offset,a) \ 147 do { \ 148 int32_t __tmp = (a); \ 149 memcpy((pc + (offset)), &__tmp, 4); \ 150 } while (0) 151 152 #define __GLX_PUT_FLOAT(offset,a) \ 153 do { \ 154 float __tmp = (a); \ 155 memcpy((pc + (offset)), &__tmp, 4); \ 156 } while (0) 157 158 #define __GLX_PUT_DOUBLE(offset,a) \ 159 do { \ 160 double __tmp = (a); \ 161 memcpy((pc + (offset)), &__tmp, 8); \ 162 } while (0) 163 164 #define __GLX_PUT_CHAR_ARRAY(offset,a,alen) \ 165 __GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_INT8) 166 167 #define __GLX_PUT_SHORT_ARRAY(offset,a,alen) \ 168 __GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_INT16) 169 170 #define __GLX_PUT_LONG_ARRAY(offset,a,alen) \ 171 __GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_INT32) 172 173 #define __GLX_PUT_FLOAT_ARRAY(offset,a,alen) \ 174 __GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_FLOAT32) 175 176 #define __GLX_PUT_DOUBLE_ARRAY(offset,a,alen) \ 177 __GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_FLOAT64) 178 179 180 #endif /* !__GLX_packrender_h__ */ 181