Home | History | Annotate | Download | only in glx
      1 /**************************************************************************
      2 
      3 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
      4 Copyright 2000 VA Linux Systems, Inc.
      5 All Rights Reserved.
      6 
      7 Permission is hereby granted, free of charge, to any person obtaining a
      8 copy of this software and associated documentation files (the
      9 "Software"), to deal in the Software without restriction, including
     10 without limitation the rights to use, copy, modify, merge, publish,
     11 distribute, sub license, and/or sell copies of the Software, and to
     12 permit persons to whom the Software is furnished to do so, subject to
     13 the following conditions:
     14 
     15 The above copyright notice and this permission notice (including the
     16 next paragraph) shall be included in all copies or substantial portions
     17 of the Software.
     18 
     19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     20 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     22 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
     23 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     24 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     25 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     26 
     27 **************************************************************************/
     28 
     29 /*
     30  * Authors:
     31  *   Kevin E. Martin <martin (at) valinux.com>
     32  *   Jens Owen <jowen (at) vmware.com>
     33  *   Rickard E. (Rik) Faith <faith (at) valinux.com>
     34  *
     35  */
     36 
     37 /* THIS IS NOT AN X CONSORTIUM STANDARD */
     38 
     39 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
     40 
     41 #include <X11/Xlibint.h>
     42 #include <X11/Xfuncproto.h>
     43 #include <X11/extensions/Xext.h>
     44 #include <X11/extensions/extutil.h>
     45 #include "xf86dristr.h"
     46 #include <limits.h>
     47 
     48 static XExtensionInfo _xf86dri_info_data;
     49 static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
     50 static char xf86dri_extension_name[] = XF86DRINAME;
     51 
     52 #define XF86DRICheckExtension(dpy,i,val) \
     53   XextCheckExtension (dpy, i, xf86dri_extension_name, val)
     54 
     55 /*****************************************************************************
     56  *                                                                           *
     57  *			   private utility routines                          *
     58  *                                                                           *
     59  *****************************************************************************/
     60 
     61 static int close_display(Display * dpy, XExtCodes * extCodes);
     62 static /* const */ XExtensionHooks xf86dri_extension_hooks = {
     63    NULL,                        /* create_gc */
     64    NULL,                        /* copy_gc */
     65    NULL,                        /* flush_gc */
     66    NULL,                        /* free_gc */
     67    NULL,                        /* create_font */
     68    NULL,                        /* free_font */
     69    close_display,               /* close_display */
     70    NULL,                        /* wire_to_event */
     71    NULL,                        /* event_to_wire */
     72    NULL,                        /* error */
     73    NULL,                        /* error_string */
     74 };
     75 
     76 static
     77 XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info,
     78                            xf86dri_extension_name,
     79                            &xf86dri_extension_hooks, 0, NULL)
     80 
     81 static
     82 XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info)
     83 
     84 
     85 /*****************************************************************************
     86  *                                                                           *
     87  *		    public XFree86-DRI Extension routines                    *
     88  *                                                                           *
     89  *****************************************************************************/
     90 #if 0
     91 #include <stdio.h>
     92 #define TRACE(msg)  fprintf(stderr,"XF86DRI%s\n", msg);
     93 #else
     94 #define TRACE(msg)
     95 #endif
     96 
     97 Bool
     98 XF86DRIQueryExtension(Display * dpy, int *event_basep,
     99                       int *error_basep)
    100 {
    101    XExtDisplayInfo *info = find_display(dpy);
    102 
    103    TRACE("QueryExtension...");
    104    if (XextHasExtension(info)) {
    105       *event_basep = info->codes->first_event;
    106       *error_basep = info->codes->first_error;
    107       TRACE("QueryExtension... return True");
    108       return True;
    109    }
    110    else {
    111       TRACE("QueryExtension... return False");
    112       return False;
    113    }
    114 }
    115 
    116 Bool
    117 XF86DRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion,
    118                     int *patchVersion)
    119 {
    120    XExtDisplayInfo *info = find_display(dpy);
    121    xXF86DRIQueryVersionReply rep;
    122    xXF86DRIQueryVersionReq *req;
    123 
    124    TRACE("QueryVersion...");
    125    XF86DRICheckExtension(dpy, info, False);
    126 
    127    LockDisplay(dpy);
    128    GetReq(XF86DRIQueryVersion, req);
    129    req->reqType = info->codes->major_opcode;
    130    req->driReqType = X_XF86DRIQueryVersion;
    131    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
    132       UnlockDisplay(dpy);
    133       SyncHandle();
    134       TRACE("QueryVersion... return False");
    135       return False;
    136    }
    137    *majorVersion = rep.majorVersion;
    138    *minorVersion = rep.minorVersion;
    139    *patchVersion = rep.patchVersion;
    140    UnlockDisplay(dpy);
    141    SyncHandle();
    142    TRACE("QueryVersion... return True");
    143    return True;
    144 }
    145 
    146 Bool
    147 XF86DRIQueryDirectRenderingCapable(Display * dpy, int screen,
    148                                    Bool * isCapable)
    149 {
    150    XExtDisplayInfo *info = find_display(dpy);
    151    xXF86DRIQueryDirectRenderingCapableReply rep;
    152    xXF86DRIQueryDirectRenderingCapableReq *req;
    153 
    154    TRACE("QueryDirectRenderingCapable...");
    155    XF86DRICheckExtension(dpy, info, False);
    156 
    157    LockDisplay(dpy);
    158    GetReq(XF86DRIQueryDirectRenderingCapable, req);
    159    req->reqType = info->codes->major_opcode;
    160    req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
    161    req->screen = screen;
    162    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
    163       UnlockDisplay(dpy);
    164       SyncHandle();
    165       TRACE("QueryDirectRenderingCapable... return False");
    166       return False;
    167    }
    168    *isCapable = rep.isCapable;
    169    UnlockDisplay(dpy);
    170    SyncHandle();
    171    TRACE("QueryDirectRenderingCapable... return True");
    172    return True;
    173 }
    174 
    175 Bool
    176 XF86DRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA,
    177                       char **busIdString)
    178 {
    179    XExtDisplayInfo *info = find_display(dpy);
    180    xXF86DRIOpenConnectionReply rep;
    181    xXF86DRIOpenConnectionReq *req;
    182 
    183    TRACE("OpenConnection...");
    184    XF86DRICheckExtension(dpy, info, False);
    185 
    186    LockDisplay(dpy);
    187    GetReq(XF86DRIOpenConnection, req);
    188    req->reqType = info->codes->major_opcode;
    189    req->driReqType = X_XF86DRIOpenConnection;
    190    req->screen = screen;
    191    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
    192       UnlockDisplay(dpy);
    193       SyncHandle();
    194       TRACE("OpenConnection... return False");
    195       return False;
    196    }
    197 
    198    *hSAREA = rep.hSAREALow;
    199    if (sizeof(drm_handle_t) == 8) {
    200       int shift = 32;           /* var to prevent warning on next line */
    201       *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
    202    }
    203 
    204    if (rep.length) {
    205       if (rep.busIdStringLength < INT_MAX)
    206          *busIdString = calloc(rep.busIdStringLength + 1, 1);
    207       else
    208          *busIdString = NULL;
    209       if (*busIdString == NULL) {
    210          _XEatData(dpy, ((rep.busIdStringLength + 3) & ~3));
    211          UnlockDisplay(dpy);
    212          SyncHandle();
    213          TRACE("OpenConnection... return False");
    214          return False;
    215       }
    216       _XReadPad(dpy, *busIdString, rep.busIdStringLength);
    217    }
    218    else {
    219       *busIdString = NULL;
    220    }
    221    UnlockDisplay(dpy);
    222    SyncHandle();
    223    TRACE("OpenConnection... return True");
    224    return True;
    225 }
    226 
    227 Bool
    228 XF86DRIAuthConnection(Display * dpy, int screen, drm_magic_t magic)
    229 {
    230    XExtDisplayInfo *info = find_display(dpy);
    231    xXF86DRIAuthConnectionReq *req;
    232    xXF86DRIAuthConnectionReply rep;
    233 
    234    TRACE("AuthConnection...");
    235    XF86DRICheckExtension(dpy, info, False);
    236 
    237    LockDisplay(dpy);
    238    GetReq(XF86DRIAuthConnection, req);
    239    req->reqType = info->codes->major_opcode;
    240    req->driReqType = X_XF86DRIAuthConnection;
    241    req->screen = screen;
    242    req->magic = magic;
    243    rep.authenticated = 0;
    244    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) {
    245       UnlockDisplay(dpy);
    246       SyncHandle();
    247       TRACE("AuthConnection... return False");
    248       return False;
    249    }
    250    UnlockDisplay(dpy);
    251    SyncHandle();
    252    TRACE("AuthConnection... return True");
    253    return True;
    254 }
    255 
    256 Bool
    257 XF86DRICloseConnection(Display * dpy, int screen)
    258 {
    259    XExtDisplayInfo *info = find_display(dpy);
    260    xXF86DRICloseConnectionReq *req;
    261 
    262    TRACE("CloseConnection...");
    263 
    264    XF86DRICheckExtension(dpy, info, False);
    265 
    266    LockDisplay(dpy);
    267    GetReq(XF86DRICloseConnection, req);
    268    req->reqType = info->codes->major_opcode;
    269    req->driReqType = X_XF86DRICloseConnection;
    270    req->screen = screen;
    271    UnlockDisplay(dpy);
    272    SyncHandle();
    273    TRACE("CloseConnection... return True");
    274    return True;
    275 }
    276 
    277 Bool
    278 XF86DRIGetClientDriverName(Display * dpy, int screen,
    279                            int *ddxDriverMajorVersion,
    280                            int *ddxDriverMinorVersion,
    281                            int *ddxDriverPatchVersion,
    282                            char **clientDriverName)
    283 {
    284    XExtDisplayInfo *info = find_display(dpy);
    285    xXF86DRIGetClientDriverNameReply rep;
    286    xXF86DRIGetClientDriverNameReq *req;
    287 
    288    TRACE("GetClientDriverName...");
    289    XF86DRICheckExtension(dpy, info, False);
    290 
    291    LockDisplay(dpy);
    292    GetReq(XF86DRIGetClientDriverName, req);
    293    req->reqType = info->codes->major_opcode;
    294    req->driReqType = X_XF86DRIGetClientDriverName;
    295    req->screen = screen;
    296    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
    297       UnlockDisplay(dpy);
    298       SyncHandle();
    299       TRACE("GetClientDriverName... return False");
    300       return False;
    301    }
    302 
    303    *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
    304    *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
    305    *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
    306 
    307    if (rep.length) {
    308       if (rep.clientDriverNameLength < INT_MAX)
    309          *clientDriverName = calloc(rep.clientDriverNameLength + 1, 1);
    310       else
    311          *clientDriverName = NULL;
    312       if (*clientDriverName == NULL) {
    313          _XEatData(dpy, ((rep.clientDriverNameLength + 3) & ~3));
    314          UnlockDisplay(dpy);
    315          SyncHandle();
    316          TRACE("GetClientDriverName... return False");
    317          return False;
    318       }
    319       _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
    320    }
    321    else {
    322       *clientDriverName = NULL;
    323    }
    324    UnlockDisplay(dpy);
    325    SyncHandle();
    326    TRACE("GetClientDriverName... return True");
    327    return True;
    328 }
    329 
    330 Bool
    331 XF86DRICreateContextWithConfig(Display * dpy, int screen, int configID,
    332                                XID * context, drm_context_t * hHWContext)
    333 {
    334    XExtDisplayInfo *info = find_display(dpy);
    335    xXF86DRICreateContextReply rep;
    336    xXF86DRICreateContextReq *req;
    337 
    338    TRACE("CreateContext...");
    339    XF86DRICheckExtension(dpy, info, False);
    340 
    341    LockDisplay(dpy);
    342    GetReq(XF86DRICreateContext, req);
    343    req->reqType = info->codes->major_opcode;
    344    req->driReqType = X_XF86DRICreateContext;
    345    req->visual = configID;
    346    req->screen = screen;
    347    *context = XAllocID(dpy);
    348    req->context = *context;
    349    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
    350       UnlockDisplay(dpy);
    351       SyncHandle();
    352       TRACE("CreateContext... return False");
    353       return False;
    354    }
    355    *hHWContext = rep.hHWContext;
    356    UnlockDisplay(dpy);
    357    SyncHandle();
    358    TRACE("CreateContext... return True");
    359    return True;
    360 }
    361 
    362 Bool
    363 XF86DRICreateContext(Display * dpy, int screen, Visual * visual,
    364                      XID * context, drm_context_t * hHWContext)
    365 {
    366    return XF86DRICreateContextWithConfig(dpy, screen, visual->visualid,
    367                                          context, hHWContext);
    368 }
    369 
    370 Bool
    371 XF86DRIDestroyContext(Display * dpy, int screen, XID context)
    372 {
    373    XExtDisplayInfo *info = find_display(dpy);
    374    xXF86DRIDestroyContextReq *req;
    375 
    376    TRACE("DestroyContext...");
    377    XF86DRICheckExtension(dpy, info, False);
    378 
    379    LockDisplay(dpy);
    380    GetReq(XF86DRIDestroyContext, req);
    381    req->reqType = info->codes->major_opcode;
    382    req->driReqType = X_XF86DRIDestroyContext;
    383    req->screen = screen;
    384    req->context = context;
    385    UnlockDisplay(dpy);
    386    SyncHandle();
    387    TRACE("DestroyContext... return True");
    388    return True;
    389 }
    390 
    391 Bool
    392 XF86DRICreateDrawable(Display * dpy, int screen,
    393                       XID drawable, drm_drawable_t * hHWDrawable)
    394 {
    395    XExtDisplayInfo *info = find_display(dpy);
    396    xXF86DRICreateDrawableReply rep;
    397    xXF86DRICreateDrawableReq *req;
    398 
    399    TRACE("CreateDrawable...");
    400    XF86DRICheckExtension(dpy, info, False);
    401 
    402    LockDisplay(dpy);
    403    GetReq(XF86DRICreateDrawable, req);
    404    req->reqType = info->codes->major_opcode;
    405    req->driReqType = X_XF86DRICreateDrawable;
    406    req->screen = screen;
    407    req->drawable = drawable;
    408    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
    409       UnlockDisplay(dpy);
    410       SyncHandle();
    411       TRACE("CreateDrawable... return False");
    412       return False;
    413    }
    414    *hHWDrawable = rep.hHWDrawable;
    415    UnlockDisplay(dpy);
    416    SyncHandle();
    417    TRACE("CreateDrawable... return True");
    418    return True;
    419 }
    420 
    421 static int
    422 noopErrorHandler(Display * dpy, XErrorEvent * xerr)
    423 {
    424    return 0;
    425 }
    426 
    427 Bool
    428 XF86DRIDestroyDrawable(Display * dpy, int screen, XID drawable)
    429 {
    430    XExtDisplayInfo *info = find_display(dpy);
    431    xXF86DRIDestroyDrawableReq *req;
    432    int (*oldXErrorHandler) (Display *, XErrorEvent *);
    433 
    434    TRACE("DestroyDrawable...");
    435    XF86DRICheckExtension(dpy, info, False);
    436 
    437    /* This is called from the DRI driver, which used call it like this
    438     *
    439     *   if (windowExists(drawable))
    440     *     destroyDrawable(drawable);
    441     *
    442     * which is a textbook race condition - the window may disappear
    443     * from the server between checking for its existence and
    444     * destroying it.  Instead we change the semantics of
    445     * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if
    446     * the windows is gone, by wrapping the destroy call in an error
    447     * handler. */
    448 
    449    XSync(dpy, False);
    450    oldXErrorHandler = XSetErrorHandler(noopErrorHandler);
    451 
    452    LockDisplay(dpy);
    453    GetReq(XF86DRIDestroyDrawable, req);
    454    req->reqType = info->codes->major_opcode;
    455    req->driReqType = X_XF86DRIDestroyDrawable;
    456    req->screen = screen;
    457    req->drawable = drawable;
    458    UnlockDisplay(dpy);
    459    SyncHandle();
    460 
    461    XSetErrorHandler(oldXErrorHandler);
    462 
    463    TRACE("DestroyDrawable... return True");
    464    return True;
    465 }
    466 
    467 Bool
    468 XF86DRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
    469                        unsigned int *index, unsigned int *stamp,
    470                        int *X, int *Y, int *W, int *H,
    471                        int *numClipRects, drm_clip_rect_t ** pClipRects,
    472                        int *backX, int *backY,
    473                        int *numBackClipRects,
    474                        drm_clip_rect_t ** pBackClipRects)
    475 {
    476    XExtDisplayInfo *info = find_display(dpy);
    477    xXF86DRIGetDrawableInfoReply rep;
    478    xXF86DRIGetDrawableInfoReq *req;
    479    int total_rects;
    480 
    481    TRACE("GetDrawableInfo...");
    482    XF86DRICheckExtension(dpy, info, False);
    483 
    484    LockDisplay(dpy);
    485    GetReq(XF86DRIGetDrawableInfo, req);
    486    req->reqType = info->codes->major_opcode;
    487    req->driReqType = X_XF86DRIGetDrawableInfo;
    488    req->screen = screen;
    489    req->drawable = drawable;
    490 
    491    if (!_XReply(dpy, (xReply *) & rep, 1, xFalse)) {
    492       UnlockDisplay(dpy);
    493       SyncHandle();
    494       TRACE("GetDrawableInfo... return False");
    495       return False;
    496    }
    497    *index = rep.drawableTableIndex;
    498    *stamp = rep.drawableTableStamp;
    499    *X = (int) rep.drawableX;
    500    *Y = (int) rep.drawableY;
    501    *W = (int) rep.drawableWidth;
    502    *H = (int) rep.drawableHeight;
    503    *numClipRects = rep.numClipRects;
    504    total_rects = *numClipRects;
    505 
    506    *backX = rep.backX;
    507    *backY = rep.backY;
    508    *numBackClipRects = rep.numBackClipRects;
    509    total_rects += *numBackClipRects;
    510 
    511 #if 0
    512    /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
    513     * backwards compatibility (Because of the >> 2 shift) but the fix
    514     * enables multi-threaded apps to work.
    515     */
    516    if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
    517                          SIZEOF(xGenericReply) +
    518                          total_rects * sizeof(drm_clip_rect_t)) +
    519                         3) & ~3) >> 2)) {
    520       _XEatData(dpy, rep.length);
    521       UnlockDisplay(dpy);
    522       SyncHandle();
    523       TRACE("GetDrawableInfo... return False");
    524       return False;
    525    }
    526 #endif
    527 
    528    if (*numClipRects) {
    529       int len = sizeof(drm_clip_rect_t) * (*numClipRects);
    530 
    531       *pClipRects = calloc(len, 1);
    532       if (*pClipRects)
    533          _XRead(dpy, (char *) *pClipRects, len);
    534    }
    535    else {
    536       *pClipRects = NULL;
    537    }
    538 
    539    if (*numBackClipRects) {
    540       int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
    541 
    542       *pBackClipRects = calloc(len, 1);
    543       if (*pBackClipRects)
    544          _XRead(dpy, (char *) *pBackClipRects, len);
    545    }
    546    else {
    547       *pBackClipRects = NULL;
    548    }
    549 
    550    UnlockDisplay(dpy);
    551    SyncHandle();
    552    TRACE("GetDrawableInfo... return True");
    553    return True;
    554 }
    555 
    556 Bool
    557 XF86DRIGetDeviceInfo(Display * dpy, int screen, drm_handle_t * hFrameBuffer,
    558                      int *fbOrigin, int *fbSize, int *fbStride,
    559                      int *devPrivateSize, void **pDevPrivate)
    560 {
    561    XExtDisplayInfo *info = find_display(dpy);
    562    xXF86DRIGetDeviceInfoReply rep;
    563    xXF86DRIGetDeviceInfoReq *req;
    564 
    565    TRACE("GetDeviceInfo...");
    566    XF86DRICheckExtension(dpy, info, False);
    567 
    568    LockDisplay(dpy);
    569    GetReq(XF86DRIGetDeviceInfo, req);
    570    req->reqType = info->codes->major_opcode;
    571    req->driReqType = X_XF86DRIGetDeviceInfo;
    572    req->screen = screen;
    573    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
    574       UnlockDisplay(dpy);
    575       SyncHandle();
    576       TRACE("GetDeviceInfo... return False");
    577       return False;
    578    }
    579 
    580    *hFrameBuffer = rep.hFrameBufferLow;
    581    if (sizeof(drm_handle_t) == 8) {
    582       int shift = 32;           /* var to prevent warning on next line */
    583       *hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift;
    584    }
    585 
    586    *fbOrigin = rep.framebufferOrigin;
    587    *fbSize = rep.framebufferSize;
    588    *fbStride = rep.framebufferStride;
    589    *devPrivateSize = rep.devPrivateSize;
    590 
    591    if (rep.length) {
    592       if (!(*pDevPrivate = calloc(rep.devPrivateSize, 1))) {
    593          _XEatData(dpy, ((rep.devPrivateSize + 3) & ~3));
    594          UnlockDisplay(dpy);
    595          SyncHandle();
    596          TRACE("GetDeviceInfo... return False");
    597          return False;
    598       }
    599       _XRead(dpy, (char *) *pDevPrivate, rep.devPrivateSize);
    600    }
    601    else {
    602       *pDevPrivate = NULL;
    603    }
    604 
    605    UnlockDisplay(dpy);
    606    SyncHandle();
    607    TRACE("GetDeviceInfo... return True");
    608    return True;
    609 }
    610 
    611 Bool
    612 XF86DRIOpenFullScreen(Display * dpy, int screen, Drawable drawable)
    613 {
    614    /* This function and the underlying X protocol are deprecated.
    615     */
    616    (void) dpy;
    617    (void) screen;
    618    (void) drawable;
    619    return False;
    620 }
    621 
    622 Bool
    623 XF86DRICloseFullScreen(Display * dpy, int screen, Drawable drawable)
    624 {
    625    /* This function and the underlying X protocol are deprecated.
    626     */
    627    (void) dpy;
    628    (void) screen;
    629    (void) drawable;
    630    return True;
    631 }
    632 
    633 #endif /* GLX_DIRECT_RENDERING */
    634