Home | History | Annotate | Download | only in glx
      1 /*
      2  * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
      3  * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice including the dates of first publication and
     13  * either this permission notice or a reference to
     14  * http://oss.sgi.com/projects/FreeB/
     15  * shall be included in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     20  * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     21  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     22  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     23  * SOFTWARE.
     24  *
     25  * Except as contained in this notice, the name of Silicon Graphics, Inc.
     26  * shall not be used in advertising or otherwise to promote the sale, use or
     27  * other dealings in this Software without prior written authorization from
     28  * Silicon Graphics, Inc.
     29  */
     30 
     31 #include "packrender.h"
     32 #include "indirect.h"
     33 #include "indirect_size.h"
     34 
     35 /*
     36 ** This file contains routines that might need to be transported as
     37 ** GLXRender or GLXRenderLarge commands, and these commands don't
     38 ** use the pixel header.  See renderpix.c for those routines.
     39 */
     40 
     41 void
     42 __indirect_glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
     43                    GLint order, const GLdouble * pnts)
     44 {
     45    __GLX_DECLARE_VARIABLES();
     46    GLint k;
     47 
     48    __GLX_LOAD_VARIABLES();
     49    k = __glMap1d_size(target);
     50    if (k == 0) {
     51       __glXSetError(gc, GL_INVALID_ENUM);
     52       return;
     53    }
     54    else if (stride < k || order <= 0) {
     55       __glXSetError(gc, GL_INVALID_VALUE);
     56       return;
     57    }
     58    compsize = k * order * __GLX_SIZE_FLOAT64;
     59    cmdlen = 28 + compsize;
     60    if (!gc->currentDpy)
     61       return;
     62 
     63    if (cmdlen <= gc->maxSmallRenderCommandSize) {
     64       /* Use GLXRender protocol to send small command */
     65       __GLX_BEGIN_VARIABLE(X_GLrop_Map1d, cmdlen);
     66       __GLX_PUT_DOUBLE(4, u1);
     67       __GLX_PUT_DOUBLE(12, u2);
     68       __GLX_PUT_LONG(20, target);
     69       __GLX_PUT_LONG(24, order);
     70       /*
     71        ** NOTE: the doubles that follow are not aligned because of 3
     72        ** longs preceeding
     73        */
     74       __glFillMap1d(k, order, stride, pnts, (pc + 28));
     75       __GLX_END(cmdlen);
     76    }
     77    else {
     78       /* Use GLXRenderLarge protocol to send command */
     79       __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map1d, cmdlen + 4);
     80       __GLX_PUT_DOUBLE(8, u1);
     81       __GLX_PUT_DOUBLE(16, u2);
     82       __GLX_PUT_LONG(24, target);
     83       __GLX_PUT_LONG(28, order);
     84 
     85       /*
     86        ** NOTE: the doubles that follow are not aligned because of 3
     87        ** longs preceeding
     88        */
     89       if (stride != k) {
     90          GLubyte *buf;
     91 
     92          buf = (GLubyte *) Xmalloc(compsize);
     93          if (!buf) {
     94             __glXSetError(gc, GL_OUT_OF_MEMORY);
     95             return;
     96          }
     97          __glFillMap1d(k, order, stride, pnts, buf);
     98          __glXSendLargeCommand(gc, pc, 32, buf, compsize);
     99          Xfree((char *) buf);
    100       }
    101       else {
    102          /* Data is already packed.  Just send it out */
    103          __glXSendLargeCommand(gc, pc, 32, pnts, compsize);
    104       }
    105    }
    106 }
    107 
    108 void
    109 __indirect_glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
    110                    GLint order, const GLfloat * pnts)
    111 {
    112    __GLX_DECLARE_VARIABLES();
    113    GLint k;
    114 
    115    __GLX_LOAD_VARIABLES();
    116    k = __glMap1f_size(target);
    117    if (k == 0) {
    118       __glXSetError(gc, GL_INVALID_ENUM);
    119       return;
    120    }
    121    else if (stride < k || order <= 0) {
    122       __glXSetError(gc, GL_INVALID_VALUE);
    123       return;
    124    }
    125    compsize = k * order * __GLX_SIZE_FLOAT32;
    126    cmdlen = 20 + compsize;
    127    if (!gc->currentDpy)
    128       return;
    129 
    130    /*
    131     ** The order that arguments are packed is different from the order
    132     ** for glMap1d.
    133     */
    134    if (cmdlen <= gc->maxSmallRenderCommandSize) {
    135       /* Use GLXRender protocol to send small command */
    136       __GLX_BEGIN_VARIABLE(X_GLrop_Map1f, cmdlen);
    137       __GLX_PUT_LONG(4, target);
    138       __GLX_PUT_FLOAT(8, u1);
    139       __GLX_PUT_FLOAT(12, u2);
    140       __GLX_PUT_LONG(16, order);
    141       __glFillMap1f(k, order, stride, pnts, (GLubyte *) (pc + 20));
    142       __GLX_END(cmdlen);
    143    }
    144    else {
    145       /* Use GLXRenderLarge protocol to send command */
    146       __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map1f, cmdlen + 4);
    147       __GLX_PUT_LONG(8, target);
    148       __GLX_PUT_FLOAT(12, u1);
    149       __GLX_PUT_FLOAT(16, u2);
    150       __GLX_PUT_LONG(20, order);
    151 
    152       if (stride != k) {
    153          GLubyte *buf;
    154 
    155          buf = (GLubyte *) Xmalloc(compsize);
    156          if (!buf) {
    157             __glXSetError(gc, GL_OUT_OF_MEMORY);
    158             return;
    159          }
    160          __glFillMap1f(k, order, stride, pnts, buf);
    161          __glXSendLargeCommand(gc, pc, 24, buf, compsize);
    162          Xfree((char *) buf);
    163       }
    164       else {
    165          /* Data is already packed.  Just send it out */
    166          __glXSendLargeCommand(gc, pc, 24, pnts, compsize);
    167       }
    168    }
    169 }
    170 
    171 void
    172 __indirect_glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustr,
    173                    GLint uord, GLdouble v1, GLdouble v2, GLint vstr,
    174                    GLint vord, const GLdouble * pnts)
    175 {
    176    __GLX_DECLARE_VARIABLES();
    177    GLint k;
    178 
    179    __GLX_LOAD_VARIABLES();
    180    k = __glMap2d_size(target);
    181    if (k == 0) {
    182       __glXSetError(gc, GL_INVALID_ENUM);
    183       return;
    184    }
    185    else if (vstr < k || ustr < k || vord <= 0 || uord <= 0) {
    186       __glXSetError(gc, GL_INVALID_VALUE);
    187       return;
    188    }
    189    compsize = k * uord * vord * __GLX_SIZE_FLOAT64;
    190    cmdlen = 48 + compsize;
    191    if (!gc->currentDpy)
    192       return;
    193 
    194    if (cmdlen <= gc->maxSmallRenderCommandSize) {
    195       /* Use GLXRender protocol to send small command */
    196       __GLX_BEGIN_VARIABLE(X_GLrop_Map2d, cmdlen);
    197       __GLX_PUT_DOUBLE(4, u1);
    198       __GLX_PUT_DOUBLE(12, u2);
    199       __GLX_PUT_DOUBLE(20, v1);
    200       __GLX_PUT_DOUBLE(28, v2);
    201       __GLX_PUT_LONG(36, target);
    202       __GLX_PUT_LONG(40, uord);
    203       __GLX_PUT_LONG(44, vord);
    204       /*
    205        ** Pack into a u-major ordering.
    206        ** NOTE: the doubles that follow are not aligned because of 5
    207        ** longs preceeding
    208        */
    209       __glFillMap2d(k, uord, vord, ustr, vstr, pnts, (GLdouble *) (pc + 48));
    210       __GLX_END(cmdlen);
    211    }
    212    else {
    213       /* Use GLXRenderLarge protocol to send command */
    214       __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map2d, cmdlen + 4);
    215       __GLX_PUT_DOUBLE(8, u1);
    216       __GLX_PUT_DOUBLE(16, u2);
    217       __GLX_PUT_DOUBLE(24, v1);
    218       __GLX_PUT_DOUBLE(32, v2);
    219       __GLX_PUT_LONG(40, target);
    220       __GLX_PUT_LONG(44, uord);
    221       __GLX_PUT_LONG(48, vord);
    222 
    223       /*
    224        ** NOTE: the doubles that follow are not aligned because of 5
    225        ** longs preceeding
    226        */
    227       if ((vstr != k) || (ustr != k * vord)) {
    228          GLdouble *buf;
    229 
    230          buf = (GLdouble *) Xmalloc(compsize);
    231          if (!buf) {
    232             __glXSetError(gc, GL_OUT_OF_MEMORY);
    233             return;
    234          }
    235          /*
    236           ** Pack into a u-major ordering.
    237           */
    238          __glFillMap2d(k, uord, vord, ustr, vstr, pnts, buf);
    239          __glXSendLargeCommand(gc, pc, 52, buf, compsize);
    240          Xfree((char *) buf);
    241       }
    242       else {
    243          /* Data is already packed.  Just send it out */
    244          __glXSendLargeCommand(gc, pc, 52, pnts, compsize);
    245       }
    246    }
    247 }
    248 
    249 void
    250 __indirect_glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustr,
    251                    GLint uord, GLfloat v1, GLfloat v2, GLint vstr, GLint vord,
    252                    const GLfloat * pnts)
    253 {
    254    __GLX_DECLARE_VARIABLES();
    255    GLint k;
    256 
    257    __GLX_LOAD_VARIABLES();
    258    k = __glMap2f_size(target);
    259    if (k == 0) {
    260       __glXSetError(gc, GL_INVALID_ENUM);
    261       return;
    262    }
    263    else if (vstr < k || ustr < k || vord <= 0 || uord <= 0) {
    264       __glXSetError(gc, GL_INVALID_VALUE);
    265       return;
    266    }
    267    compsize = k * uord * vord * __GLX_SIZE_FLOAT32;
    268    cmdlen = 32 + compsize;
    269    if (!gc->currentDpy)
    270       return;
    271 
    272    /*
    273     ** The order that arguments are packed is different from the order
    274     ** for glMap2d.
    275     */
    276    if (cmdlen <= gc->maxSmallRenderCommandSize) {
    277       /* Use GLXRender protocol to send small command */
    278       __GLX_BEGIN_VARIABLE(X_GLrop_Map2f, cmdlen);
    279       __GLX_PUT_LONG(4, target);
    280       __GLX_PUT_FLOAT(8, u1);
    281       __GLX_PUT_FLOAT(12, u2);
    282       __GLX_PUT_LONG(16, uord);
    283       __GLX_PUT_FLOAT(20, v1);
    284       __GLX_PUT_FLOAT(24, v2);
    285       __GLX_PUT_LONG(28, vord);
    286       /*
    287        ** Pack into a u-major ordering.
    288        */
    289       __glFillMap2f(k, uord, vord, ustr, vstr, pnts, (GLfloat *) (pc + 32));
    290       __GLX_END(cmdlen);
    291    }
    292    else {
    293       /* Use GLXRenderLarge protocol to send command */
    294       __GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map2f, cmdlen + 4);
    295       __GLX_PUT_LONG(8, target);
    296       __GLX_PUT_FLOAT(12, u1);
    297       __GLX_PUT_FLOAT(16, u2);
    298       __GLX_PUT_LONG(20, uord);
    299       __GLX_PUT_FLOAT(24, v1);
    300       __GLX_PUT_FLOAT(28, v2);
    301       __GLX_PUT_LONG(32, vord);
    302 
    303       if ((vstr != k) || (ustr != k * vord)) {
    304          GLfloat *buf;
    305 
    306          buf = (GLfloat *) Xmalloc(compsize);
    307          if (!buf) {
    308             __glXSetError(gc, GL_OUT_OF_MEMORY);
    309             return;
    310          }
    311          /*
    312           ** Pack into a u-major ordering.
    313           */
    314          __glFillMap2f(k, uord, vord, ustr, vstr, pnts, buf);
    315          __glXSendLargeCommand(gc, pc, 36, buf, compsize);
    316          Xfree((char *) buf);
    317       }
    318       else {
    319          /* Data is already packed.  Just send it out */
    320          __glXSendLargeCommand(gc, pc, 36, pnts, compsize);
    321       }
    322    }
    323 }
    324 
    325 void
    326 __indirect_glEnable(GLenum cap)
    327 {
    328    __GLX_DECLARE_VARIABLES();
    329 
    330    __GLX_LOAD_VARIABLES();
    331    if (!gc->currentDpy)
    332       return;
    333 
    334    switch (cap) {
    335    case GL_COLOR_ARRAY:
    336    case GL_EDGE_FLAG_ARRAY:
    337    case GL_INDEX_ARRAY:
    338    case GL_NORMAL_ARRAY:
    339    case GL_TEXTURE_COORD_ARRAY:
    340    case GL_VERTEX_ARRAY:
    341    case GL_SECONDARY_COLOR_ARRAY:
    342    case GL_FOG_COORD_ARRAY:
    343       __indirect_glEnableClientState(cap);
    344       return;
    345    default:
    346       break;
    347    }
    348 
    349    __GLX_BEGIN(X_GLrop_Enable, 8);
    350    __GLX_PUT_LONG(4, cap);
    351    __GLX_END(8);
    352 }
    353 
    354 void
    355 __indirect_glDisable(GLenum cap)
    356 {
    357    __GLX_DECLARE_VARIABLES();
    358 
    359    __GLX_LOAD_VARIABLES();
    360    if (!gc->currentDpy)
    361       return;
    362 
    363    switch (cap) {
    364    case GL_COLOR_ARRAY:
    365    case GL_EDGE_FLAG_ARRAY:
    366    case GL_INDEX_ARRAY:
    367    case GL_NORMAL_ARRAY:
    368    case GL_TEXTURE_COORD_ARRAY:
    369    case GL_VERTEX_ARRAY:
    370    case GL_SECONDARY_COLOR_ARRAY:
    371    case GL_FOG_COORD_ARRAY:
    372       __indirect_glDisableClientState(cap);
    373       return;
    374    default:
    375       break;
    376    }
    377 
    378    __GLX_BEGIN(X_GLrop_Disable, 8);
    379    __GLX_PUT_LONG(4, cap);
    380    __GLX_END(8);
    381 }
    382