xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

indirect_util.c (9096B)


      1 /*
      2  * (C) Copyright IBM Corporation 2005
      3  * 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, sub license,
      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 and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
     19  * IBM,
     20  * AND/OR THEIR SUPPLIERS 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 
     26 #ifdef HAVE_DIX_CONFIG_H
     27 #include <dix-config.h>
     28 #endif
     29 
     30 #include <string.h>
     31 
     32 #include <X11/Xmd.h>
     33 #include <GL/gl.h>
     34 #include <GL/glxproto.h>
     35 #include <inttypes.h>
     36 #include "indirect_size.h"
     37 #include "indirect_size_get.h"
     38 #include "indirect_dispatch.h"
     39 #include "glxserver.h"
     40 #include "glxbyteorder.h"
     41 #include "singlesize.h"
     42 #include "glxext.h"
     43 #include "indirect_table.h"
     44 #include "indirect_util.h"
     45 
     46 #define __GLX_PAD(a) (((a)+3)&~3)
     47 
     48 GLint
     49 __glGetBooleanv_variable_size(GLenum e)
     50 {
     51     if (e == GL_COMPRESSED_TEXTURE_FORMATS) {
     52         GLint temp;
     53 
     54         glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &temp);
     55         return temp;
     56     }
     57     else {
     58         return 0;
     59     }
     60 }
     61 
     62 /**
     63  * Get a properly aligned buffer to hold reply data.
     64  *
     65  * \warning
     66  * This function assumes that \c local_buffer is already properly aligned.
     67  * It also assumes that \c alignment is a power of two.
     68  */
     69 void *
     70 __glXGetAnswerBuffer(__GLXclientState * cl, size_t required_size,
     71                      void *local_buffer, size_t local_size, unsigned alignment)
     72 {
     73     void *buffer = local_buffer;
     74     const intptr_t mask = alignment - 1;
     75 
     76     if (local_size < required_size) {
     77         size_t worst_case_size;
     78         intptr_t temp_buf;
     79 
     80         if (required_size < SIZE_MAX - alignment)
     81             worst_case_size = required_size + alignment;
     82         else
     83             return NULL;
     84 
     85         if (cl->returnBufSize < worst_case_size) {
     86             void *temp = realloc(cl->returnBuf, worst_case_size);
     87 
     88             if (temp == NULL) {
     89                 return NULL;
     90             }
     91 
     92             cl->returnBuf = temp;
     93             cl->returnBufSize = worst_case_size;
     94         }
     95 
     96         temp_buf = (intptr_t) cl->returnBuf;
     97         temp_buf = (temp_buf + mask) & ~mask;
     98         buffer = (void *) temp_buf;
     99     }
    100 
    101     return buffer;
    102 }
    103 
    104 /**
    105  * Send a GLX reply to the client.
    106  *
    107  * Technically speaking, there are several different ways to encode a GLX
    108  * reply.  The primary difference is whether or not certain fields (e.g.,
    109  * retval, size, and "pad3") are set.  This function gets around that by
    110  * always setting all of the fields to "reasonable" values.  This does no
    111  * harm to clients, but it does make the server-side code much more compact.
    112  */
    113 void
    114 __glXSendReply(ClientPtr client, const void *data, size_t elements,
    115                size_t element_size, GLboolean always_array, CARD32 retval)
    116 {
    117     size_t reply_ints = 0;
    118     xGLXSingleReply reply = { 0, };
    119 
    120     if (__glXErrorOccured()) {
    121         elements = 0;
    122     }
    123     else if ((elements > 1) || always_array) {
    124         reply_ints = bytes_to_int32(elements * element_size);
    125     }
    126 
    127     reply.length = reply_ints;
    128     reply.type = X_Reply;
    129     reply.sequenceNumber = client->sequence;
    130     reply.size = elements;
    131     reply.retval = retval;
    132 
    133     /* It is faster on almost always every architecture to just copy the 8
    134      * bytes, even when not necessary, than check to see of the value of
    135      * elements requires it.  Copying the data when not needed will do no
    136      * harm.
    137      */
    138 
    139     (void) memcpy(&reply.pad3, data, 8);
    140     WriteToClient(client, sz_xGLXSingleReply, &reply);
    141 
    142     if (reply_ints != 0) {
    143         WriteToClient(client, reply_ints * 4, data);
    144     }
    145 }
    146 
    147 /**
    148  * Send a GLX reply to the client.
    149  *
    150  * Technically speaking, there are several different ways to encode a GLX
    151  * reply.  The primary difference is whether or not certain fields (e.g.,
    152  * retval, size, and "pad3") are set.  This function gets around that by
    153  * always setting all of the fields to "reasonable" values.  This does no
    154  * harm to clients, but it does make the server-side code much more compact.
    155  *
    156  * \warning
    157  * This function assumes that values stored in \c data will be byte-swapped
    158  * by the caller if necessary.
    159  */
    160 void
    161 __glXSendReplySwap(ClientPtr client, const void *data, size_t elements,
    162                    size_t element_size, GLboolean always_array, CARD32 retval)
    163 {
    164     size_t reply_ints = 0;
    165     xGLXSingleReply reply = { 0, };
    166 
    167     if (__glXErrorOccured()) {
    168         elements = 0;
    169     }
    170     else if ((elements > 1) || always_array) {
    171         reply_ints = bytes_to_int32(elements * element_size);
    172     }
    173 
    174     reply.length = bswap_32(reply_ints);
    175     reply.type = X_Reply;
    176     reply.sequenceNumber = bswap_16(client->sequence);
    177     reply.size = bswap_32(elements);
    178     reply.retval = bswap_32(retval);
    179 
    180     /* It is faster on almost always every architecture to just copy the 8
    181      * bytes, even when not necessary, than check to see of the value of
    182      * elements requires it.  Copying the data when not needed will do no
    183      * harm.
    184      */
    185 
    186     (void) memcpy(&reply.pad3, data, 8);
    187     WriteToClient(client, sz_xGLXSingleReply, &reply);
    188 
    189     if (reply_ints != 0) {
    190         WriteToClient(client, reply_ints * 4, data);
    191     }
    192 }
    193 
    194 static int
    195 get_decode_index(const struct __glXDispatchInfo *dispatch_info, unsigned opcode)
    196 {
    197     int remaining_bits;
    198     int next_remain;
    199     const int_fast16_t *const tree = dispatch_info->dispatch_tree;
    200     int_fast16_t index;
    201 
    202     remaining_bits = dispatch_info->bits;
    203     if (opcode >= (1U << remaining_bits)) {
    204         return -1;
    205     }
    206 
    207     index = 0;
    208     for ( /* empty */ ; remaining_bits > 0; remaining_bits = next_remain) {
    209         unsigned mask;
    210         unsigned child_index;
    211 
    212         /* Calculate the slice of bits used by this node.
    213          *
    214          * If remaining_bits = 8 and tree[index] = 3, the mask of just the
    215          * remaining bits is 0x00ff and the mask for the remaining bits after
    216          * this node is 0x001f.  By taking 0x00ff & ~0x001f, we get 0x00e0.
    217          * This masks the 3 bits that we would want for this node.
    218          */
    219 
    220         next_remain = remaining_bits - tree[index];
    221         mask = ((1 << remaining_bits) - 1) & ~((1 << next_remain) - 1);
    222 
    223         /* Using the mask, calculate the index of the opcode in the node.
    224          * With that index, fetch the index of the next node.
    225          */
    226 
    227         child_index = (opcode & mask) >> next_remain;
    228         index = tree[index + 1 + child_index];
    229 
    230         /* If the next node is an empty leaf, the opcode is for a non-existent
    231          * function.  We're done.
    232          *
    233          * If the next node is a non-empty leaf, look up the function pointer
    234          * and return it.
    235          */
    236 
    237         if (index == EMPTY_LEAF) {
    238             return -1;
    239         }
    240         else if (IS_LEAF_INDEX(index)) {
    241             unsigned func_index;
    242 
    243             /* The value stored in the tree for a leaf node is the base of
    244              * the function pointers for that leaf node.  The offset for the
    245              * function for a particular opcode is the remaining bits in the
    246              * opcode.
    247              */
    248 
    249             func_index = -index;
    250             func_index += opcode & ((1 << next_remain) - 1);
    251             return func_index;
    252         }
    253     }
    254 
    255     /* We should *never* get here!!!
    256      */
    257     return -1;
    258 }
    259 
    260 void *
    261 __glXGetProtocolDecodeFunction(const struct __glXDispatchInfo *dispatch_info,
    262                                int opcode, int swapped_version)
    263 {
    264     const int func_index = get_decode_index(dispatch_info, opcode);
    265 
    266     return (func_index < 0)
    267         ? NULL
    268         : (void *) dispatch_info->
    269         dispatch_functions[func_index][swapped_version];
    270 }
    271 
    272 int
    273 __glXGetProtocolSizeData(const struct __glXDispatchInfo *dispatch_info,
    274                          int opcode, __GLXrenderSizeData * data)
    275 {
    276     if (dispatch_info->size_table != NULL) {
    277         const int func_index = get_decode_index(dispatch_info, opcode);
    278 
    279         if ((func_index >= 0)
    280             && (dispatch_info->size_table[func_index][0] != 0)) {
    281             const int var_offset = dispatch_info->size_table[func_index][1];
    282 
    283             data->bytes = dispatch_info->size_table[func_index][0];
    284             data->varsize = (var_offset != ~0)
    285                 ? dispatch_info->size_func_table[var_offset]
    286                 : NULL;
    287 
    288             return 0;
    289         }
    290     }
    291 
    292     return -1;
    293 }