[BACK]Return to lexec.ls CVS log [TXT][DIR] Up to [Development] / projects / ogl-sample / main / glx / server

File: [Development] / projects / ogl-sample / main / glx / server / lexec.ls (download)

Revision 1.1.1.1 (vendor branch), Wed Jan 26 10:31:13 2000 UTC (17 years, 9 months ago) by ljp
Branch: SGI
CVS Tags: oglsi1_2_1
Changes since 1.1: +0 -0 lines

Imported from P4

##############################################################################
#
# License Applicability. Except to the extent portions of this file are
# made subject to an alternative license as permitted in the SGI Free
# Software License B, Version 1.0 (the "License"), the contents of this
# file are subject only to the provisions of the License. You may not use
# this file except in compliance with the License. You may obtain a copy
# of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
# Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
# 
# http://oss.sgi.com/projects/FreeB
# 
# Note that, as provided in the License, the Software is distributed on an
# "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
# DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
# CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
# PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
# 
# Original Code. The Original Code is: OpenGL Sample Implementation,
# Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
# Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
# Copyright in any portions created by third parties is as indicated
# elsewhere herein. All Rights Reserved.
# 
# Additional Notice Provisions: The application programming interfaces
# established by SGI in conjunction with the Original Code are The
# OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
# April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
# 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
# Window System(R) (Version 1.3), released October 19, 1998. This software
# was created using the OpenGL(R) version 1.2.1 Sample Implementation
# published by SGI, but has not been independently verified as being
# compliant with the OpenGL(R) version 1.2.1 Specification.
#
##############################################################################
#
#   Generate the list execution routines and the GLX server transport routines.
#
#   $Date$ $Revision$
#   $Header: //depot/main/glx/server/lexec.ls#6 $
#
##############################################################################

function initialize() {

    # TYPEMAP should be defined on the command line that invokes libspec
    typeMapFile = TYPEMAP;
    _readWireFile();

    # Functions that will be generated, should be defined on command line.
    funcs = FUNCS;

    # Whether we;re generating byte swapping code.
    genSwap = (SWAP == "yes");

    genListExec = (funcs ~ /listexec/);
    genTransDraw = (funcs ~ /transdraw/);
    genTransGet = (funcs ~ /transget/);
    genTransGLX = (funcs ~ /transglx/);
    genTransSingle = genTransGet || genTransGLX;

    #
    # Try to encapsulate the differences between different output here.
    #
    
    if (genListExec) {
	prefix = "__glle_";
	functionPrefix = "__glim_";
	opcodePrefix = "__glop_";
	macroPrefix = "__GL";
    } else if (genTransDraw) {
	if (genSwap) {
	    prefix = "__glXDispSwap_";
	} else {
	    prefix = "__glXDisp_";
	}
	macroPrefix = "__GLX";
	functionPrefix = "gl";
	opcodePrefix = "X_GLrop_";
	GLXheaders = true;
    } else if (genTransGet) {
	if (genSwap) {
	    prefix = "__glXDispSwap_";
	} else {
	    prefix = "__glXDisp_";
	}
	macroPrefix = "__GLX";
	functionPrefix = "gl";
	opcodePrefix = "X_GLgop_";
	GLXheaders = true;
    } else if (genTransGLX) {
	macroPrefix = "__GLX";
	prefix = "__glXDisp_glX";
	functionPrefix = "glX";
	opcodePrefix = "X_GL_";
	GLXheaders = false;
    }

    #
    # Partial names of macros used to send each wire type.
    #
    cast["enum"] =	"INT"
    cast["boolean"] =	"BYTE"
    cast["bitfield"] =	"INT"
    cast["byte"] =	"BYTE"
    cast["short"] =	"SHORT"
    cast["int"] =	"INT"
    cast["sizei"] =	"INT"
    cast["ubyte"] =	"BYTE"
    cast["ushort"] =	"SHORT"
    cast["uint"] =	"INT"
    cast["float"] =	"FLOAT"
    cast["clampf"] =	"FLOAT"
    cast["double"] =	"DOUBLE"
    cast["clampd"] =	"DOUBLE"
    cast["void"] =      "VOID"

    #
    # Byte sizes of wire types.
    #
    xfer_size["enum"] =		"4"
    xfer_size["boolean"] =	"1"
    xfer_size["bitfield"] =	"4"
    xfer_size["byte"] =		"1"
    xfer_size["short"] =	"2"
    xfer_size["int"] =		"4"
    xfer_size["sizei"] =	"4"
    xfer_size["ubyte"] =	"1"
    xfer_size["ushort"] =	"2"
    xfer_size["uint"] =		"4"
    xfer_size["float"] =	"4"
    xfer_size["clampf"] =	"4"
    xfer_size["double"] =	"8"
    xfer_size["clampd"] =	"8"
    xfer_size["void"] =         "1"		# A lie, but good enough

    #
    # List of GL singles that are pendable (should really be taggeg in gl.spec.
    #
    pend["NewList"] = "True";
    pend["DeleteLists"] = "True";
    pend["FeedbackBuffer"] = "True";
    pend["SelectBuffer"] = "True";
    pend["PixelStoref"] = "True";
    pend["PixelStorei"] = "True";

    #
    # Include header files, declare globals.
    #
    if (genListExec) {
	printf "#include <GL/gl.h>\n";
	printf "#include \"context.h\"\n";
	printf "#include \"global.h\"\n";
	printf "#include \"list.h\"\n";
	printf "#include \"listcomp.h\"\n";
	printf "#include \"immed.h\"\n";
	printf "#include \"g_lexec.h\"\n";
	printf "\n";
    } else if (GLXheaders) {
	printf "#define NEED_REPLIES\n";
	printf "#include \"glxserver.h\"\n";
	printf "#include \"glxext.h\"\n";
	printf "#include <stdio.h>\n";
	printf "#include <string.h>\n";
	printf "#include \"g_disptab.h\"\n";
	printf "#include \"g_disptab_EXT.h\"\n";
	printf "#include \"unpack.h\"\n";
	printf "#include \"impsize.h\"\n";
	printf "#include \"singlesize.h\"\n";
	printf "\n";
    }
}

function main( i, param, cmdlen, AlreadyBeenSwapped) {

    #
    # Filter out unwanted routines.
    #
    if (genTransSingle) {
	if (!(("dlflags", "notlistable") in propListValues) ||
	    (("glxflags", "force-opcode") in propListValues)) return;
	if ((("glxflags", "server-handcode") in propListValues) ||
	    (("glxflags", "client-intercept") in propListValues) ||
	    (("glxflags", "ignore") in propListValues) )
	  return;
    } else if (genTransDraw) {
	if ((("dlflags", "notlistable") in propListValues) &&
	    !(("glxflags", "force-opcode") in propListValues)) return
	if (("glxflags", "server-handcode") in propListValues)
	  return;
    } else if (genListExec) {
	if (("dlflags", "notlistable") in propListValues) return;
	if (("dlflags", "handcode") in propListValues) return;
    }

    genTransVendpriv = ("glxvendorpriv" in propList);
    
    #
    # Routines with vector equivalents get mapped to them before being
    # compiled into a list or written into the transport buffer.
    #
    if ("vectorequiv" in propList) return;
    
    fname = functionName;

    nreturn = 0;

    #
    # Set some flags for each parameter for convenience.
    # This function is in the list utils.
    #
    setPerParamFlags();
    
    #
    # Sort the fixed-size parameters, largest element size first, so that
    # we do not have to word-align them individually.
    # This function is in the list utils.
    #
    sortParams();

    #
    # Compute sizes of all incoming parameters and the total size of the
    # command.
    # (this function is in the list utils)
    #
    computeInCmdSize();
    computeOutCmdSize();
    computeInParamPos();
    
    #
    # Count number of returned values.
    #
    if (returnUnmappedType != "void") nreturn++;
    if (isOutCompSize) nreturn++;

    #
    # If the command has doubles, and is variable-size, we need to compute
    # the total command length; it will be used for alignment code.
    #
    needTotalCommandLength = false;
    for (i=1; i<=paramCount; i++) {
	if (_xfer_size[i] == 8 && isIn[i] && numInVarParams > 0) {
	    needTotalCommandLength = true;
	}
    }
    
    #
    # Function declaration.
    #
    if (genTransSingle) {
	printf "int %s%s(__GLXclientState *cl, GLbyte *pc)\n", prefix, fname
    } else if (genTransDraw) {
	printf "void %s%s(GLbyte *pc)\n", prefix, fname;
    } else if (genListExec) {
	printf "GLint %s%s(GLbyte *pc)\n", prefix, fname;
    }

    printf "{\n";

    #
    # Make empty stubs for list-nop routines.
    #
    if (genListExec && ("dlflags", "nop") in propListValues){
	printf "\t/* This routine is a no-op in a list. */\n", fname;
	printf "\treturn 0;\n";
	printf "}\n\n";
	return;
    }

    #
    # For parameters that are variable-sized arrays, declare some local
    # variables to compute the array sizes.  When a following array is
    # addressed, this size is used to skip over the previous array.
    # Using the locals for sizes makes the generated code a little easier to
    # read.
    #

    #
    # Declare the locals.
    #
    getParamsUsedAsSizes();
    numLocals = 0;

    #
    # These locals depend on parameters in the input buffer.  We can't
    # initialize them yet because the buffer hasn't been byteswapped yet.
    #
    if (needTotalCommandLength || genSwap || genTransSingle ||
	(numOutParamSizeParams > 1) || (numInParamSizeParams > 1)) {
	for (i in paramsUsedAsSizes) {
	    param = paramName[i];
	    dtype = paramDeclaredType[param];
	    printf "\t%s %s;\n", dtype, param;
	    numLocals++;
	}
    }
    if (needTotalCommandLength) {
	printf "\tGLint cmdlen;\n";
	numLocals++;
    }
    if ((hasInCompSizeParam && (needTotalCommandLength || genSwap)) || 
	hasOutCompSizeParam) {
	printf "\tGLint compsize;\n";
	numLocals++;
    }
    
    if (hasReturn) {
	printf "\tGL%s retval;\n", wiretype[returnUnmappedType];
	numLocals++;
    }
    if (genTransGLX) {
	printf "\tGLint status;\n";
	numLocals++;
    }
    if (genTransGet) {
	printf "\t__GLXcontext *cx;\n";
	printf "\tClientPtr client = cl->client;\n";
	printf "\tint error;\n";
	if (numOutFixParams > 0) {
	    i = sortedOutFixParams[1];
	    param = paramName[i]
	    dtype = paramDeclaredType[param]
	    printf "\t%s answerBuffer[200];\n", dtype;
	    printf "\tchar *answer;\n";
	}
	if (numOutVarParams > 0) {
	    i = sortedOutVarParams[1];
	    param = paramName[i]
	    dtype = paramDeclaredType[param]
	    printf "\t%s answerBuffer[200];\n", dtype;
	    printf "\tchar *answer;\n";
	}
	numLocals++;
    }
    if (genSwap) {
	printf "\t__GLX_DECLARE_SWAP_VARIABLES;\n";
	numLocals++;
    }

    infixcmdlen = 0;

    #
    # Some space for clarity.
    #
    if (numLocals > 0) printf "\n";

    #
    # Swap context argument.
    #
    if (genSwap) {
	if (genTransGet) {
	    if (genTransVendpriv) {
		printf "\t__GLX_SWAP_INT(&((xGLXVendorPrivateReq *)pc)->contextTag);\n";
	    } else {
		printf "\t__GLX_SWAP_INT(&((xGLXSingleReq *)pc)->contextTag);\n";
	    }
	}
    }
    
    #
    # Generate a check for a current context.
    #
    if (genTransGet) {
	if (genTransVendpriv) {
	    printf "\tcx = __glXForceCurrent(cl, __GLX_GET_VENDPRIV_CONTEXT_TAG(pc), &error);\n";
	} else {
	    printf "\tcx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error);\n";
	}
	printf "\tif (!cx) {\n";
	printf "\t\treturn error;\n";
	printf "\t}\n";
    }

    #
    # Skip over X header.
    #
    if (genTransGet && paramCount > 0) {
	if (genTransVendpriv) {
	    printf "\tpc += __GLX_VENDPRIV_HDR_SIZE;\n";
	} else {
	    printf "\tpc += __GLX_SINGLE_HDR_SIZE;\n";
	}
    }
    
    if (genSwap) {
    	#
	# Swap parameters used as sizes.
    	#
	for (i in paramsUsedAsSizes) {
	    if (_xfer_size[i] == 1) continue;
	    if (isIn[i] && !isArray[i]) {
		printf "\t__GLX_SWAP_%s(pc + %d);\n", _cast[i], paramPos[i];
		AlreadyBeenSwapped[i] = "Sure has";
	    }
	}
    }

    #
    # Now that the buffer has been (possibly) swapped, set the locals.
    #
    if (needTotalCommandLength || genSwap || genTransSingle ||
	(numOutParamSizeParams > 1) || (numInParamSizeParams > 1)) {
	for (i in paramsUsedAsSizes) {
	    param = paramName[i];
	    dtype = paramDeclaredType[param];
	    printf "\t%s = *(%s *)(pc + %d);\n", param, dtype, paramPos[i];
	}
    }
    if (hasInCompSizeParam && (needTotalCommandLength || genSwap)) {
	printf "\tcompsize = %s;\n", \
	  getCompSizeParamList(inCompSizeParamIndex);
    }
    if (hasOutCompSizeParam) {
	printf "\tcompsize = %s;\n", \
	  	getCompSizeParamList(outCompSizeParamIndex);
    }
    #
    # If the computed size is negative, it is because of a bad enumerant.
    # Just set it to zero and issue the call anyway, so the error code gets
    # set.
    #
    if ((hasInCompSizeParam && (needTotalCommandLength || genSwap)) ||
	hasOutCompSizeParam) {
	printf "\tif (compsize < 0) compsize = 0;\n";
    }

    # Compute cmdlen for variable length commands
    if (needTotalCommandLength) {
	printf "\tcmdlen = %s_PAD(%d%s);\n", macroPrefix, inFixCmdSize,
		inVarCmdSize;
    }

    # Generate alignment code
    if (genTransDraw || genTransGLX) {
	for (i=1; i<=paramCount; i++) {
	    param = paramName[i];
	    dtype = paramDeclaredType[param];
	    dir   = paramDirection[param];

	    if (_xfer_size[i] == 8 && isIn[i]) {
		printf "\n#ifdef __GLX_ALIGN64\n";
		printf "\tif ((unsigned long)(pc) & 7) {\n";
		if (numInVarParams > 0) {
			printf "\t    __GLX_MEM_COPY(pc-4, pc, cmdlen);\n";
		} else {
			printf "\t    __GLX_MEM_COPY(pc-4, pc, %d);\n",
				inFixCmdSize;
		}
		printf "\t    pc -= 4;\n";
		printf "\t}\n";
		printf "#endif\n";
		break;
	    }
        }
    }
    
    if (genSwap) {
    	#
    	# Swap each parameter in the buffer.
    	#
    	for (i=1; i<=paramCount; i++) {
	    param = paramName[i];
	    dtype = paramDeclaredType[param];
	    udtype = paramUnmappedDeclaredType[param];
	    ttype = paramTransferType[param];
	    dir   = paramDirection[param];

	    if (_xfer_size[i] == 1) continue;
	    
 	    #
	    # Incoming scalars.
	    #
	    if (isIn[i] && !isArray[i]) {
		if (AlreadyBeenSwapped[i] != "Sure has") {
		    printf "\t__GLX_SWAP_%s(pc + %d);\n", _cast[i], paramPos[i];
		}
	    }
	    #
	    # Incoming arrays.
	    #
	    if (isIn[i] && isArray[i]) {
	    	arcast = sprintf( "\(%-8s *\)", dtype);
		# Use the array straight out of the X request.
		printf "\t__GLX_SWAP_%s_ARRAY(pc + %s, %s);\n",
			_cast[i], paramPos[i], arrayCount[i];
	    }
	}
    }

    #
    # Some space for clarity.
    #
    if (numLocals > 0) printf "\n";
    
    if (genTransGLX) {
	printf "\tstatus =\n";
    }

    if (genTransGet) {
    	for (i=1; i<=paramCount; i++) {
	    if (!isIn[i] && isArray[i]) {
		printf "\t__GLX_GET_ANSWER_BUFFER(answer,cl,%s,%d);\n",
			arrayBytes[i], _xfer_size[i];
		break;
	    }
	}
    }

    #
    # Call the routine.
    #
    if (numOutCompSizeParams > 0) {
        printf "\t__glXClearErrorOccured();\n";
    }
    if (hasReturn) {
	printf "\tretval =\n";
    }
    printf "\t%s%s( \n", functionPrefix, fname;

    #
    # Locate each parameter in the buffer as we pass it to the routine.
    #
    for (i=1; i<=paramCount; i++) {
	param = paramName[i]
	dtype = paramDeclaredType[param]
	udtype = paramUnmappedDeclaredType[param]
	ttype = paramTransferType[param]
	dir   = paramDirection[param]

 	#
	# Incoming scalars.
	#
	if (isIn[i] && !isArray[i]) {
	    if (ttype == "value") ref = "*";
	    else ref = "";
	    printf "\t\t%s(%-8s *)(pc + %d)", ref, dtype, paramPos[i];
	}
	#
	# Incoming arrays.
	#
	if (isIn[i] && isArray[i]) {
	    arcast = sprintf( "\(%-8s *\)", dtype);
	    printf "\t\t%s(pc + %s)", arcast, paramPos[i];
	}
	
 	#
	# Outgoing scalars.
	#
	if (!isIn[i] && !isArray[i]) {
	    printf "\t\t(%-8s *)&__glXRetScalars[%d].%s", dtype, i, _cast[i];
	}
 	#
	# Outgoing arrays.
	#
	if (!isIn[i] && isArray[i]) {
	    printf "\t\t\(%-8s *\) answer", dtype;
	}

        # Be careful not to put comma after last parameter.
	if (paramCount > 1 && i != paramCount) printf ",";
	if (genTransGLX && paramCount > 0 && i == paramCount) printf ",";

	printf "\n";
    }

    #
    # GLX routines need an extra parameter, the client.
    #
    if (genTransGLX) {
	printf "\t\t";
	printf "client\n";
    }
    printf "\t);\n";

    if (genTransGet) {
        if (pend[fname] == "True") {
            printf "\t__GLX_NOTE_UNFLUSHED_CMDS(cx);\n";
        }
    }

    if (genSwap) {
    	#
    	# Swap each parameter in the buffer.
    	#
    	for (i=1; i<=paramCount; i++) {
	    param = paramName[i];
	    dtype = paramDeclaredType[param];
	    udtype = paramUnmappedDeclaredType[param];
	    ttype = paramTransferType[param];
	    dir   = paramDirection[param];

	    if (_xfer_size[i] == 1) continue;
 	    #
	    # Outgoing scalars.
	    #
	    if (!isIn[i] && !isArray[i]) {
		printf "\t__GLX_SWAP_%s(pc + %d);\n", _cast[i], paramPos[i];
	    }

	    # Outgoing arrays.
	    #
	    if (!isIn[i] && isArray[i]) {
	    	arcast = sprintf( "\(%-8s *\)", dtype);
	    	if ((genTransDraw || genTransGLX) && _xfer_size[i] == 8) {
		    # Use a locally declared, 8-byte aligned buffer.
		    printf "\t__GLX_SWAP_%s_ARRAY((GLbyte *)pc%d);\n", \
		      _cast[i], i, arrayCount[i];
	    	} else {
		    # Swap the array we've allocated.
		    printf "\t__GLX_SWAP_%s_ARRAY(answer, %s);\n", \
		      _cast[i], arrayCount[i];
	    	}
	    }
	}
    }

    # NOTE: dont' return the length, it's never used.
    #
    # Return the total length of the command.
    #
    # if (genTransDraw || genListExec) {
    #	if (numInVarParams > 0) {
    #	    printf "\treturn cmdlen;\n";
    #	} else {
    #	    printf "\treturn %s;\n", inFixCmdSize;
    #	}
    # }

    #
    # Send returned data if needed.
    #
    if (numOutFixParams > 0 || numOutVarParams > 1) {
	printf "ERROR script not able to deal with given returned params\n";
    }

    if (hasReturn || numOutFixParams > 0 || numOutVarParams > 0) {

	if (outFixCmdSize > 0) {
	    replyLength = outFixCmdSize;
	} else {
	    if (numOutVarParams > 0) {
		replyLength = outVarCmdSize;
		sub(/[+]/, "", replyLength);
	    } else {
		replyLength = "0";
	    }
	}

	if (hasReturn) {
	    printf "\t__GLX_PUT_RETVAL(retval);\n";
	    if (genSwap) {
	    	printf "\t__GLX_SWAP_REPLY_RETVAL();\n";
	    }
	}

	if (numOutCompSizeParams > 0) {
            #
            # error occurred; send back zero length data
            #
	    printf "\tif (__glXErrorOccured()) {\n"; 
	    printf "\t    __GLX_BEGIN_REPLY(0);\n";
	    if (genSwap) {
	    	printf "\t    __GLX_SWAP_REPLY_HEADER();\n";
	    }
	    printf "\t    __GLX_PUT_SIZE(0);\n";
	    printf "\t    __GLX_SEND_HEADER();\n";

            #
            # send just one value
            #
            printf "\t} else if (compsize == 1) {\n"; 
	    printf "\t    __GLX_BEGIN_REPLY(0);\n";
	    if (genSwap) {
	    	printf "\t    __GLX_SWAP_REPLY_HEADER();\n";
	    }
	    printf "\t    __GLX_PUT_SIZE(1);\n";
	    if (genSwap) {
	    	printf "\t    __GLX_SWAP_REPLY_SIZE();\n";
	    }
	    printf "\t    __GLX_PUT_%s();\n", _cast[sortedOutVarParams[1]];
	    printf "\t    __GLX_SEND_HEADER();\n";

            #
            # send back an array of values after the 32 byte reply
            #
            printf "\t} else {\n";
	    printf "\t    __GLX_BEGIN_REPLY(%s);\n", replyLength;
	    if (genSwap) {
	    	printf "\t    __GLX_SWAP_REPLY_HEADER();\n";
	    }
	    printf "\t    __GLX_PUT_SIZE(compsize);\n";
	    if (genSwap) {
	    	printf "\t    __GLX_SWAP_REPLY_SIZE();\n";
	    }
	    printf "\t    __GLX_SEND_HEADER();\n";
	    # 
	    # Write variable size params.
    	    #	
	    for (j=1; j <= numOutVarParams; j++) {
		i = sortedOutVarParams[j];
		printf "\t    __GLX_SEND_%s_ARRAY(%s);\n", _cast[i], \
		  arrayCount[i];
	    }
	    printf "\t}\n";

	} else {

	    printf "\t__GLX_BEGIN_REPLY(%s);\n", replyLength;
	    if (genSwap) {
	    	printf "\t__GLX_SWAP_REPLY_HEADER();\n";
	    }
	    printf "\t__GLX_SEND_HEADER();\n";
	    if (numOutFixParams > 0) {
		i = sortedOutFixParams[1];
	    	printf "\t__GLX_SEND_%s_ARRAY(%s);\n", _cast[i], arrayCount[i];
	    } else if (numOutVarParams > 0) {
		i = sortedOutVarParams[1];
	    	printf "\t__GLX_SEND_%s_ARRAY(%s);\n", _cast[i], arrayCount[i];
	    }
        }

    }

    if (genTransGet)
      printf "\treturn Success;\n";
    if (genTransGLX)
      printf "\treturn status;\n";

    printf "}\n\n";
}

function finalize()
{
}