xserver

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

glxdriswrast.c (15029B)


      1 /*
      2  * Copyright © 2008 George Sapountzis <gsap7@yahoo.gr>
      3  * Copyright © 2008 Red Hat, Inc
      4  *
      5  * Permission to use, copy, modify, distribute, and sell this software
      6  * and its documentation for any purpose is hereby granted without
      7  * fee, provided that the above copyright notice appear in all copies
      8  * and that both that copyright notice and this permission notice
      9  * appear in supporting documentation, and that the name of the
     10  * copyright holders not be used in advertising or publicity
     11  * pertaining to distribution of the software without specific,
     12  * written prior permission.  The copyright holders make no
     13  * representations about the suitability of this software for any
     14  * purpose.  It is provided "as is" without express or implied
     15  * warranty.
     16  *
     17  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
     18  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
     19  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
     20  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     21  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
     22  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
     23  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
     24  * SOFTWARE.
     25  */
     26 
     27 #ifdef HAVE_DIX_CONFIG_H
     28 #include <dix-config.h>
     29 #endif
     30 
     31 #include <stdint.h>
     32 #include <stdio.h>
     33 #include <string.h>
     34 #include <errno.h>
     35 #include <sys/time.h>
     36 #include <dlfcn.h>
     37 
     38 #include <GL/gl.h>
     39 #include <GL/internal/dri_interface.h>
     40 #include <GL/glxtokens.h>
     41 
     42 #include "scrnintstr.h"
     43 #include "pixmapstr.h"
     44 #include "gcstruct.h"
     45 #include "os.h"
     46 
     47 #include "glxserver.h"
     48 #include "glxutil.h"
     49 #include "glxdricommon.h"
     50 
     51 #include "extension_string.h"
     52 
     53 /* RTLD_LOCAL is not defined on Cygwin */
     54 #ifdef __CYGWIN__
     55 #ifndef RTLD_LOCAL
     56 #define RTLD_LOCAL 0
     57 #endif
     58 #endif
     59 
     60 typedef struct __GLXDRIscreen __GLXDRIscreen;
     61 typedef struct __GLXDRIcontext __GLXDRIcontext;
     62 typedef struct __GLXDRIdrawable __GLXDRIdrawable;
     63 
     64 struct __GLXDRIscreen {
     65     __GLXscreen base;
     66     __DRIscreen *driScreen;
     67     void *driver;
     68 
     69     const __DRIcoreExtension *core;
     70     const __DRIswrastExtension *swrast;
     71     const __DRIcopySubBufferExtension *copySubBuffer;
     72     const __DRItexBufferExtension *texBuffer;
     73     const __DRIconfig **driConfigs;
     74 };
     75 
     76 struct __GLXDRIcontext {
     77     __GLXcontext base;
     78     __DRIcontext *driContext;
     79 };
     80 
     81 struct __GLXDRIdrawable {
     82     __GLXdrawable base;
     83     __DRIdrawable *driDrawable;
     84     __GLXDRIscreen *screen;
     85 };
     86 
     87 /* white lie */
     88 extern glx_func_ptr glXGetProcAddressARB(const char *);
     89 
     90 static void
     91 __glXDRIdrawableDestroy(__GLXdrawable * drawable)
     92 {
     93     __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
     94     const __DRIcoreExtension *core = private->screen->core;
     95 
     96     (*core->destroyDrawable) (private->driDrawable);
     97 
     98     __glXDrawableRelease(drawable);
     99 
    100     free(private);
    101 }
    102 
    103 static GLboolean
    104 __glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable * drawable)
    105 {
    106     __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
    107     const __DRIcoreExtension *core = private->screen->core;
    108 
    109     (*core->swapBuffers) (private->driDrawable);
    110 
    111     return TRUE;
    112 }
    113 
    114 static void
    115 __glXDRIdrawableCopySubBuffer(__GLXdrawable * basePrivate,
    116                               int x, int y, int w, int h)
    117 {
    118     __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
    119     const __DRIcopySubBufferExtension *copySubBuffer =
    120         private->screen->copySubBuffer;
    121 
    122     if (copySubBuffer)
    123         (*copySubBuffer->copySubBuffer) (private->driDrawable, x, y, w, h);
    124 }
    125 
    126 static void
    127 __glXDRIcontextDestroy(__GLXcontext * baseContext)
    128 {
    129     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
    130     __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
    131 
    132     (*screen->core->destroyContext) (context->driContext);
    133     __glXContextDestroy(&context->base);
    134     free(context);
    135 }
    136 
    137 static int
    138 __glXDRIcontextMakeCurrent(__GLXcontext * baseContext)
    139 {
    140     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
    141     __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
    142     __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
    143     __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
    144 
    145     return (*screen->core->bindContext) (context->driContext,
    146                                          draw->driDrawable, read->driDrawable);
    147 }
    148 
    149 static int
    150 __glXDRIcontextLoseCurrent(__GLXcontext * baseContext)
    151 {
    152     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
    153     __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
    154 
    155     return (*screen->core->unbindContext) (context->driContext);
    156 }
    157 
    158 static int
    159 __glXDRIcontextCopy(__GLXcontext * baseDst, __GLXcontext * baseSrc,
    160                     unsigned long mask)
    161 {
    162     __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
    163     __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
    164     __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen;
    165 
    166     return (*screen->core->copyContext) (dst->driContext,
    167                                          src->driContext, mask);
    168 }
    169 
    170 static int
    171 __glXDRIbindTexImage(__GLXcontext * baseContext,
    172                      int buffer, __GLXdrawable * glxPixmap)
    173 {
    174     __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap;
    175     const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer;
    176     __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
    177 
    178     if (texBuffer == NULL)
    179         return Success;
    180 
    181 #if __DRI_TEX_BUFFER_VERSION >= 2
    182     if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) {
    183         (*texBuffer->setTexBuffer2) (context->driContext,
    184                                      glxPixmap->target,
    185                                      glxPixmap->format, drawable->driDrawable);
    186     }
    187     else
    188 #endif
    189         texBuffer->setTexBuffer(context->driContext,
    190                                 glxPixmap->target, drawable->driDrawable);
    191 
    192     return Success;
    193 }
    194 
    195 static int
    196 __glXDRIreleaseTexImage(__GLXcontext * baseContext,
    197                         int buffer, __GLXdrawable * pixmap)
    198 {
    199     /* FIXME: Just unbind the texture? */
    200     return Success;
    201 }
    202 
    203 static __GLXcontext *
    204 __glXDRIscreenCreateContext(__GLXscreen * baseScreen,
    205                             __GLXconfig * glxConfig,
    206                             __GLXcontext * baseShareContext,
    207                             unsigned num_attribs,
    208                             const uint32_t *attribs,
    209                             int *error)
    210 {
    211     __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
    212     __GLXDRIcontext *context, *shareContext;
    213     __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
    214     const __DRIconfig *driConfig = config ? config->driConfig : NULL;
    215     const __DRIcoreExtension *core = screen->core;
    216     __DRIcontext *driShare;
    217 
    218     /* DRISWRAST won't support createContextAttribs, so these parameters will
    219      * never be used.
    220      */
    221     (void) num_attribs;
    222     (void) attribs;
    223     (void) error;
    224 
    225     shareContext = (__GLXDRIcontext *) baseShareContext;
    226     if (shareContext)
    227         driShare = shareContext->driContext;
    228     else
    229         driShare = NULL;
    230 
    231     context = calloc(1, sizeof *context);
    232     if (context == NULL)
    233         return NULL;
    234 
    235     context->base.config = glxConfig;
    236     context->base.destroy = __glXDRIcontextDestroy;
    237     context->base.makeCurrent = __glXDRIcontextMakeCurrent;
    238     context->base.loseCurrent = __glXDRIcontextLoseCurrent;
    239     context->base.copy = __glXDRIcontextCopy;
    240     context->base.bindTexImage = __glXDRIbindTexImage;
    241     context->base.releaseTexImage = __glXDRIreleaseTexImage;
    242 
    243     context->driContext =
    244         (*core->createNewContext) (screen->driScreen, driConfig, driShare,
    245                                    context);
    246 
    247     return &context->base;
    248 }
    249 
    250 static __GLXdrawable *
    251 __glXDRIscreenCreateDrawable(ClientPtr client,
    252                              __GLXscreen * screen,
    253                              DrawablePtr pDraw,
    254                              XID drawId,
    255                              int type, XID glxDrawId, __GLXconfig * glxConfig)
    256 {
    257     __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
    258     __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
    259     __GLXDRIdrawable *private;
    260 
    261     private = calloc(1, sizeof *private);
    262     if (private == NULL)
    263         return NULL;
    264 
    265     private->screen = driScreen;
    266     if (!__glXDrawableInit(&private->base, screen,
    267                            pDraw, type, glxDrawId, glxConfig)) {
    268         free(private);
    269         return NULL;
    270     }
    271 
    272     private->base.destroy = __glXDRIdrawableDestroy;
    273     private->base.swapBuffers = __glXDRIdrawableSwapBuffers;
    274     private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
    275 
    276     private->driDrawable =
    277         (*driScreen->swrast->createNewDrawable) (driScreen->driScreen,
    278                                                  config->driConfig, private);
    279 
    280     return &private->base;
    281 }
    282 
    283 static void
    284 swrastGetDrawableInfo(__DRIdrawable * draw,
    285                       int *x, int *y, int *w, int *h, void *loaderPrivate)
    286 {
    287     __GLXDRIdrawable *drawable = loaderPrivate;
    288     DrawablePtr pDraw = drawable->base.pDraw;
    289 
    290     *x = pDraw->x;
    291     *y = pDraw->y;
    292     *w = pDraw->width;
    293     *h = pDraw->height;
    294 }
    295 
    296 static void
    297 swrastPutImage(__DRIdrawable * draw, int op,
    298                int x, int y, int w, int h, char *data, void *loaderPrivate)
    299 {
    300     __GLXDRIdrawable *drawable = loaderPrivate;
    301     DrawablePtr pDraw = drawable->base.pDraw;
    302     GCPtr gc;
    303     __GLXcontext *cx = lastGLContext;
    304 
    305     if ((gc = GetScratchGC(pDraw->depth, pDraw->pScreen))) {
    306         ValidateGC(pDraw, gc);
    307         gc->ops->PutImage(pDraw, gc, pDraw->depth, x, y, w, h, 0, ZPixmap,
    308                           data);
    309         FreeScratchGC(gc);
    310     }
    311 
    312     if (cx != lastGLContext) {
    313         lastGLContext = cx;
    314         cx->makeCurrent(cx);
    315     }
    316 }
    317 
    318 static void
    319 swrastGetImage(__DRIdrawable * draw,
    320                int x, int y, int w, int h, char *data, void *loaderPrivate)
    321 {
    322     __GLXDRIdrawable *drawable = loaderPrivate;
    323     DrawablePtr pDraw = drawable->base.pDraw;
    324     ScreenPtr pScreen = pDraw->pScreen;
    325     __GLXcontext *cx = lastGLContext;
    326 
    327     pScreen->SourceValidate(pDraw, x, y, w, h, IncludeInferiors);
    328     pScreen->GetImage(pDraw, x, y, w, h, ZPixmap, ~0L, data);
    329     if (cx != lastGLContext) {
    330         lastGLContext = cx;
    331         cx->makeCurrent(cx);
    332     }
    333 }
    334 
    335 static const __DRIswrastLoaderExtension swrastLoaderExtension = {
    336     {__DRI_SWRAST_LOADER, 1},
    337     swrastGetDrawableInfo,
    338     swrastPutImage,
    339     swrastGetImage
    340 };
    341 
    342 static const __DRIextension *loader_extensions[] = {
    343     &swrastLoaderExtension.base,
    344     NULL
    345 };
    346 
    347 static void
    348 initializeExtensions(__GLXscreen * screen)
    349 {
    350     const __DRIextension **extensions;
    351     __GLXDRIscreen *dri = (__GLXDRIscreen *)screen;
    352     int i;
    353 
    354     __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
    355     __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_no_config_context");
    356 
    357     if (dri->swrast->base.version >= 3) {
    358         __glXEnableExtension(screen->glx_enable_bits,
    359                              "GLX_ARB_create_context");
    360         __glXEnableExtension(screen->glx_enable_bits,
    361                              "GLX_ARB_create_context_no_error");
    362         __glXEnableExtension(screen->glx_enable_bits,
    363                              "GLX_ARB_create_context_profile");
    364         __glXEnableExtension(screen->glx_enable_bits,
    365                              "GLX_EXT_create_context_es_profile");
    366         __glXEnableExtension(screen->glx_enable_bits,
    367                              "GLX_EXT_create_context_es2_profile");
    368     }
    369 
    370     /* these are harmless to enable unconditionally */
    371     __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_framebuffer_sRGB");
    372     __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_fbconfig_float");
    373     __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_fbconfig_packed_float");
    374     __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_texture_from_pixmap");
    375 
    376     extensions = dri->core->getExtensions(dri->driScreen);
    377 
    378     for (i = 0; extensions[i]; i++) {
    379         if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
    380             dri->copySubBuffer =
    381                 (const __DRIcopySubBufferExtension *) extensions[i];
    382         }
    383 
    384         if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
    385             dri->texBuffer = (const __DRItexBufferExtension *) extensions[i];
    386         }
    387 
    388 #ifdef __DRI2_FLUSH_CONTROL
    389         if (strcmp(extensions[i]->name, __DRI2_FLUSH_CONTROL) == 0) {
    390             __glXEnableExtension(screen->glx_enable_bits,
    391                                  "GLX_ARB_context_flush_control");
    392         }
    393 #endif
    394 
    395     }
    396 }
    397 
    398 static void
    399 __glXDRIscreenDestroy(__GLXscreen * baseScreen)
    400 {
    401     int i;
    402 
    403     __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
    404 
    405     (*screen->core->destroyScreen) (screen->driScreen);
    406 
    407     dlclose(screen->driver);
    408 
    409     __glXScreenDestroy(baseScreen);
    410 
    411     if (screen->driConfigs) {
    412         for (i = 0; screen->driConfigs[i] != NULL; i++)
    413             free((__DRIconfig **) screen->driConfigs[i]);
    414         free(screen->driConfigs);
    415     }
    416 
    417     free(screen);
    418 }
    419 
    420 static __GLXscreen *
    421 __glXDRIscreenProbe(ScreenPtr pScreen)
    422 {
    423     const char *driverName = "swrast";
    424     __GLXDRIscreen *screen;
    425 
    426     screen = calloc(1, sizeof *screen);
    427     if (screen == NULL)
    428         return NULL;
    429 
    430     screen->base.destroy = __glXDRIscreenDestroy;
    431     screen->base.createContext = __glXDRIscreenCreateContext;
    432     screen->base.createDrawable = __glXDRIscreenCreateDrawable;
    433     screen->base.swapInterval = NULL;
    434     screen->base.pScreen = pScreen;
    435 
    436     __glXInitExtensionEnableBits(screen->base.glx_enable_bits);
    437 
    438     screen->driver = glxProbeDriver(driverName,
    439                                     (void **) &screen->core,
    440                                     __DRI_CORE, 1,
    441                                     (void **) &screen->swrast,
    442                                     __DRI_SWRAST, 1);
    443     if (screen->driver == NULL) {
    444         goto handle_error;
    445     }
    446 
    447     screen->driScreen =
    448         (*screen->swrast->createNewScreen) (pScreen->myNum,
    449                                             loader_extensions,
    450                                             &screen->driConfigs, screen);
    451 
    452     if (screen->driScreen == NULL) {
    453         LogMessage(X_ERROR, "IGLX error: Calling driver entry point failed\n");
    454         goto handle_error;
    455     }
    456 
    457     initializeExtensions(&screen->base);
    458 
    459     screen->base.fbconfigs = glxConvertConfigs(screen->core,
    460                                                screen->driConfigs);
    461 
    462 #if !defined(XQUARTZ) && !defined(WIN32)
    463     screen->base.glvnd = strdup("mesa");
    464 #endif
    465     __glXScreenInit(&screen->base, pScreen);
    466 
    467     __glXsetGetProcAddress(glXGetProcAddressARB);
    468 
    469     LogMessage(X_INFO, "IGLX: Loaded and initialized %s\n", driverName);
    470 
    471     return &screen->base;
    472 
    473  handle_error:
    474     if (screen->driver)
    475         dlclose(screen->driver);
    476 
    477     free(screen);
    478 
    479     LogMessage(X_ERROR, "GLX: could not load software renderer\n");
    480 
    481     return NULL;
    482 }
    483 
    484 __GLXprovider __glXDRISWRastProvider = {
    485     __glXDRIscreenProbe,
    486     "DRISWRAST",
    487     NULL
    488 };