DRI2: Drop sarea, implement swap buffers in the X server.
[mesa.git] / src / mesa / drivers / dri / common / dri_util.c
index 58702089e5f291452b4fafb7ef8a0b09f2d6c332..ce540624a520d55626c3dfe7b1f32d1cf1a1514d 100644 (file)
@@ -152,7 +152,6 @@ static int driUnbindContext(__DRIcontext *pcp)
     return GL_TRUE;
 }
 
-
 /**
  * This function takes both a read buffer and a draw buffer.  This is needed
  * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
@@ -186,10 +185,7 @@ static int driBindContext(__DRIcontext *pcp,
     ** initialize the drawable information if has not been done before.
     */
 
-    if (psp->dri2.enabled) {
-       __driParseEvents(pcp, pdp);
-       __driParseEvents(pcp, prp);
-    } else {
+    if (!psp->dri2.enabled) {
        if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) {
            DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
            __driUtilUpdateDrawableInfo(pdp);
@@ -277,139 +273,6 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
        pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp);
 
     DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
-
-}
-
-int
-__driParseEvents(__DRIcontextPrivate *pcp, __DRIdrawablePrivate *pdp)
-{
-    __DRIscreenPrivate *psp = pcp->driScreenPriv;
-    __DRIDrawableConfigEvent *dc, *last_dc;
-    __DRIBufferAttachEvent *ba, *last_ba;
-    unsigned int tail, mask, *p, end, total, size, changed;
-    unsigned char *data;
-    size_t rect_size;
-
-    /* Check for wraparound. */
-    if (psp->dri2.buffer->prealloc - pdp->dri2.tail > psp->dri2.buffer->size) {
-       /* If prealloc overlaps into what we just parsed, the
-       * server overwrote it and we have to reset our tail
-       * pointer. */
-       DRM_UNLOCK(psp->fd, psp->lock, pcp->hHWContext);
-       (*psp->dri2.loader->reemitDrawableInfo)(pdp, &pdp->dri2.tail,
-                                               pdp->loaderPrivate);
-       DRM_LIGHT_LOCK(psp->fd, psp->lock, pcp->hHWContext);
-    }
-
-    total = psp->dri2.buffer->head - pdp->dri2.tail;
-    mask = psp->dri2.buffer->size - 1;
-    end = psp->dri2.buffer->head;
-    data = psp->dri2.buffer->data;
-
-    changed = 0;
-    last_dc = NULL;
-    last_ba = NULL;
-
-    for (tail = pdp->dri2.tail; tail != end; tail += size) {
-       p = (unsigned int *) (data + (tail & mask));
-       size = DRI2_EVENT_SIZE(*p);
-       if (size > total || (tail & mask) + size > psp->dri2.buffer->size) {
-         /* illegal data, bail out. */
-         fprintf(stderr, "illegal event size\n");
-         break;
-       }
-
-       switch (DRI2_EVENT_TYPE(*p)) {
-       case DRI2_EVENT_DRAWABLE_CONFIG:
-         dc = (__DRIDrawableConfigEvent *) p;
-         if (dc->drawable == pdp->dri2.drawable_id)
-            last_dc = dc;
-         break;
-
-       case DRI2_EVENT_BUFFER_ATTACH:
-         ba = (__DRIBufferAttachEvent *) p;
-         if (ba->drawable == pdp->dri2.drawable_id && 
-             ba->buffer.attachment == DRI_DRAWABLE_BUFFER_FRONT_LEFT)
-            last_ba = ba;
-         break;
-       }
-    }
-         
-    if (last_dc) {
-       if (pdp->w != last_dc->width || pdp->h != last_dc->height)
-         changed = 1;
-
-       pdp->x = last_dc->x;
-       pdp->y = last_dc->y;
-       pdp->w = last_dc->width;
-       pdp->h = last_dc->height;
-
-       pdp->backX = 0;
-       pdp->backY = 0;
-       pdp->numBackClipRects = 1;
-       pdp->pBackClipRects[0].x1 = 0;
-       pdp->pBackClipRects[0].y1 = 0;
-       pdp->pBackClipRects[0].x2 = pdp->w;
-       pdp->pBackClipRects[0].y2 = pdp->h;
-
-       pdp->numClipRects = last_dc->num_rects;
-       _mesa_free(pdp->pClipRects);
-       rect_size = last_dc->num_rects * sizeof last_dc->rects[0];
-       pdp->pClipRects = _mesa_malloc(rect_size);
-       memcpy(pdp->pClipRects, last_dc->rects, rect_size);
-    }
-
-    /* We only care about the most recent drawable config. */
-    if (last_dc && changed)
-       (*psp->DriverAPI.HandleDrawableConfig)(pdp, pcp, last_dc);
-
-    /* Front buffer attachments are special, they typically mean that
-     * we're rendering to a redirected window (or a child window of a
-     * redirected window) and that it got resized.  Resizing the root
-     * window on randr events is a special case of this.  Other causes
-     * may be a window transitioning between redirected and
-     * non-redirected, or a window getting reparented between parents
-     * with different window pixmaps (eg two redirected windows).
-     * These events are special in that the X server allocates the
-     * buffer and that the buffer may be shared by other child
-     * windows.  When our window share the window pixmap with its
-     * parent, drawable config events doesn't affect the front buffer.
-     * We only care about the last such event in the buffer; in fact,
-     * older events will refer to invalid buffer objects.*/
-    if (last_ba)
-       (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, last_ba);
-
-    /* If there was a drawable config event in the buffer and it
-     * changed the size of the window, all buffer auxillary buffer
-     * attachments prior to that are invalid (as opposed to the front
-     * buffer case discussed above).  In that case we can start
-     * looking for buffer attachment after the last drawable config
-     * event.  If there is no drawable config event in this batch of
-     * events, we have to assume that the last batch might have had
-     * one and process all buffer attach events.*/
-    if (last_dc && changed)
-       tail = (unsigned char *) last_dc - data;
-    else
-       tail = pdp->dri2.tail;
-
-    for ( ; tail != end; tail += size) {
-       ba = (__DRIBufferAttachEvent *) (data + (tail & mask));
-       size = DRI2_EVENT_SIZE(ba->event_header);
-
-       if (DRI2_EVENT_TYPE(ba->event_header) != DRI2_EVENT_BUFFER_ATTACH)
-         continue;
-       if (ba->drawable != pdp->dri2.drawable_id)
-         continue;
-       if (last_ba == ba)
-         continue;
-
-       (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, ba);
-       changed = 1;
-    }
-
-    pdp->dri2.tail = tail;
-
-    return changed || last_ba;
 }
 
 /*@}*/
@@ -425,12 +288,7 @@ static void driReportDamage(__DRIdrawable *pdp,
     __DRIscreen *psp = pdp->driScreenPriv;
 
     /* Check that we actually have the new damage report method */
-    if (psp->dri2.enabled) {
-       (*psp->dri2.loader->postDamage)(pdp,
-                                       pClipRects,
-                                       numClipRects,
-                                       pdp->loaderPrivate);
-    } else if (psp->damage) {
+    if (psp->damage) {
        /* Report the damage.  Currently, all our drivers draw
         * directly to the front buffer, so we report the damage there
         * rather than to the backing storein (if any).
@@ -471,6 +329,7 @@ static int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv,
     return sPriv->DriverAPI.GetDrawableMSC(sPriv, dPriv, msc);
 }
 
+
 static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
                         int64_t divisor, int64_t remainder,
                         int64_t * msc, int64_t * sbc)
@@ -478,7 +337,6 @@ static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
     __DRIswapInfo  sInfo;
     int  status;
 
-
     status = dPriv->driScreenPriv->DriverAPI.WaitForMSC( dPriv, target_msc,
                                                          divisor, remainder,
                                                          msc );
@@ -496,24 +354,26 @@ static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
     return status;
 }
 
+
 const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = {
     { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION },
     driWaitForMSC,
     driDrawableGetMSC,
 };
 
+
 static void driCopySubBuffer(__DRIdrawable *dPriv,
                              int x, int y, int w, int h)
 {
     drm_clip_rect_t rect;
 
-    dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
-
     rect.x1 = x;
-    rect.y1 = y;
+    rect.y1 = dPriv->h - y - h;
     rect.x2 = x + w;
-    rect.y2 = y + w;
+    rect.y2 = rect.y1 + h;
     driReportDamage(dPriv, &rect, 1);
+
+    dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
 }
 
 const __DRIcopySubBufferExtension driCopySubBufferExtension = {
@@ -595,16 +455,19 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
     return pdp;
 }
 
+
 static __DRIdrawable *
-dri2CreateNewDrawable(__DRIscreen *screen, const __DRIconfig *config,
-                     unsigned int drawable_id, unsigned int head, void *data)
+dri2CreateNewDrawable(__DRIscreen *screen,
+                     const __DRIconfig *config,
+                     void *loaderPrivate)
 {
     __DRIdrawable *pdraw;
 
-    pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, data);
+    pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, loaderPrivate);
+    if (!pdraw)
+       return NULL;
 
-    pdraw->dri2.drawable_id = drawable_id;
-    pdraw->dri2.tail = head;
+    pdraw->pClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
     pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
 
     return pdraw;
@@ -642,8 +505,6 @@ driDestroyDrawable(__DRIdrawable *pdp)
 /**
  * Destroy the per-context private information.
  * 
- * \param contextPrivate opaque pointer to the per-drawable private info.
- *
  * \internal
  * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
  * drmDestroyContext(), and finally frees \p contextPrivate.
@@ -661,13 +522,9 @@ driDestroyContext(__DRIcontext *pcp)
 /**
  * Create the per-drawable private driver information.
  * 
- * \param dpy           The display handle.
- * \param modes         Mode used to create the new context.
  * \param render_type   Type of rendering target.  \c GLX_RGBA is the only
  *                      type likely to ever be supported for direct-rendering.
- * \param shared        The shared context dependent methods or \c NULL if
- *                      non-existent.
- * \param pctx          DRI context to receive the context dependent methods.
+ * \param shared        Context with which to share textures, etc. or NULL
  *
  * \returns An opaque pointer to the per-context private information on
  *          success, or \c NULL on failure.
@@ -716,24 +573,15 @@ driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
     return pcp;
 }
 
+
 static __DRIcontext *
 dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
                      __DRIcontext *shared, void *data)
 {
-    drm_context_t hwContext;
-    DRM_CAS_RESULT(ret);
-
-    /* DRI2 doesn't use kernel with context IDs, we just need an ID that's
-     * different from the kernel context ID to make drmLock() happy. */
-
-    do {
-       hwContext = screen->dri2.lock->next_id;
-       DRM_CAS(&screen->dri2.lock->next_id, hwContext, hwContext + 1, ret);
-    } while (ret);
-
-    return driCreateNewContext(screen, config, 0, shared, hwContext, data);
+    return driCreateNewContext(screen, config, 0, shared, 0, data);
 }
 
+
 static int
 driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
 {
@@ -751,10 +599,6 @@ driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
 /**
  * Destroy the per-screen private information.
  * 
- * \param dpy the display handle.
- * \param scrn the screen number.
- * \param screenPrivate opaque pointer to the per-screen private information.
- *
  * \internal
  * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
  * drmClose(), and finally frees \p screenPrivate.
@@ -770,10 +614,7 @@ static void driDestroyScreen(__DRIscreen *psp)
        if (psp->DriverAPI.DestroyScreen)
            (*psp->DriverAPI.DestroyScreen)(psp);
 
-       if (psp->dri2.enabled) {
-           drmBOUnmap(psp->fd, &psp->dri2.sareaBO);
-           drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
-       } else {
+       if (!psp->dri2.enabled) {
           (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
           (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
           (void)drmCloseOnce(psp->fd);
@@ -796,8 +637,8 @@ setupLoaderExtensions(__DRIscreen *psp,
            psp->damage = (__DRIdamageExtension *) extensions[i];
        if (strcmp(extensions[i]->name, __DRI_SYSTEM_TIME) == 0)
            psp->systemTime = (__DRIsystemTimeExtension *) extensions[i];
-       if (strcmp(extensions[i]->name, __DRI_LOADER) == 0)
-           psp->dri2.loader = (__DRIloaderExtension *) extensions[i];
+       if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0)
+           psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i];
     }
 }
 
@@ -807,15 +648,10 @@ setupLoaderExtensions(__DRIscreen *psp,
  * This routine also fills in the linked list pointed to by \c driver_modes
  * with the \c __GLcontextModes that the driver can support for windows or
  * pbuffers.
+ *
+ * For legacy DRI.
  * 
  * \param scrn  Index of the screen
- * \param psc   DRI screen data (not driver private)
- * \param modes Linked list of known display modes.  This list is, at a
- *              minimum, a list of modes based on the current display mode.
- *              These roughly match the set of available X11 visuals, but it
- *              need not be limited to X11!  The calling libGL should create
- *              a list that will inform the driver of the current display
- *              mode (i.e., color buffer depth, depth buffer depth, etc.).
  * \param ddx_version Version of the 2D DDX.  This may not be meaningful for
  *                    all drivers.
  * \param dri_version Version of the "server-side" DRI.
@@ -824,9 +660,9 @@ setupLoaderExtensions(__DRIscreen *psp,
  *                     framebuffer.
  * \param pSAREA       Pointer the the SAREA.
  * \param fd           Device handle for the DRM.
- * \param internal_api_version  Version of the internal interface between the
- *                              driver and libGL.
- * \param driverAPI Driver API functions used by other routines in dri_util.c.
+ * \param extensions   ??
+ * \param driver_modes  Returns modes suppoted by the driver
+ * \param loaderPrivate  ??
  * 
  * \note There is no need to check the minimum API version in this
  * function.  Since the name of this function is versioned, it is
@@ -898,15 +734,16 @@ driCreateNewScreen(int scrn,
     return psp;
 }
 
-
+/**
+ * DRI2
+ */
 static __DRIscreen *
-dri2CreateNewScreen(int scrn, int fd, unsigned int sarea_handle,
+dri2CreateNewScreen(int scrn, int fd,
                    const __DRIextension **extensions,
                    const __DRIconfig ***driver_configs, void *data)
 {
     static const __DRIextension *emptyExtensionList[] = { NULL };
     __DRIscreen *psp;
-    unsigned int *p;
     drmVersionPtr version;
 
     if (driDriverAPI.InitScreen2 == NULL)
@@ -931,39 +768,9 @@ dri2CreateNewScreen(int scrn, int fd, unsigned int sarea_handle,
     psp->myNum = scrn;
     psp->dri2.enabled = GL_TRUE;
 
-    if (drmBOReference(psp->fd, sarea_handle, &psp->dri2.sareaBO)) {
-       fprintf(stderr, "Failed to reference DRI2 sarea BO\n");
-       _mesa_free(psp);
-       return NULL;
-    }
-
-    if (drmBOMap(psp->fd, &psp->dri2.sareaBO,
-                DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &psp->dri2.sarea)) {
-       drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
-       _mesa_free(psp);
-       return NULL;
-    }
-
-    p = psp->dri2.sarea;
-    while (DRI2_SAREA_BLOCK_TYPE(*p)) {
-       switch (DRI2_SAREA_BLOCK_TYPE(*p)) {
-       case DRI2_SAREA_BLOCK_LOCK:
-           psp->dri2.lock = (__DRILock *) p;
-           break;
-       case DRI2_SAREA_BLOCK_EVENT_BUFFER:
-           psp->dri2.buffer = (__DRIEventBuffer *) p;
-           break;
-       }
-       p = DRI2_SAREA_BLOCK_NEXT(p);
-    }
-
-    psp->lock = (drmLock *) &psp->dri2.lock->lock;
-
     psp->DriverAPI = driDriverAPI;
     *driver_configs = driDriverAPI.InitScreen2(psp);
     if (*driver_configs == NULL) {
-       drmBOUnmap(psp->fd, &psp->dri2.sareaBO);
-       drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
        _mesa_free(psp);
        return NULL;
     }
@@ -978,34 +785,45 @@ static const __DRIextension **driGetExtensions(__DRIscreen *psp)
     return psp->extensions;
 }
 
-const __DRIlegacyExtension driLegacyExtension = {
-    { __DRI_LEGACY, __DRI_LEGACY_VERSION },
-    driCreateNewScreen,
-    driCreateNewDrawable,
-    driCreateNewContext
-};
-
+/** Core interface */
 const __DRIcoreExtension driCoreExtension = {
     { __DRI_CORE, __DRI_CORE_VERSION },
-    dri2CreateNewScreen,
+    NULL,
     driDestroyScreen,
     driGetExtensions,
     driGetConfigAttrib,
     driIndexConfigAttrib,
-    dri2CreateNewDrawable,
+    NULL,
     driDestroyDrawable,
     driSwapBuffers,
-    dri2CreateNewContext,
+    NULL,
     driCopyContext,
     driDestroyContext,
     driBindContext,
     driUnbindContext
 };
 
+/** Legacy DRI interface */
+const __DRIlegacyExtension driLegacyExtension = {
+    { __DRI_LEGACY, __DRI_LEGACY_VERSION },
+    driCreateNewScreen,
+    driCreateNewDrawable,
+    driCreateNewContext,
+};
+
+/** Legacy DRI interface */
+const __DRIdri2Extension driDRI2Extension = {
+    { __DRI_DRI2, __DRI_DRI2_VERSION },
+    dri2CreateNewScreen,
+    dri2CreateNewDrawable,
+    dri2CreateNewContext,
+};
+
 /* This is the table of extensions that the loader will dlsym() for. */
 PUBLIC const __DRIextension *__driDriverExtensions[] = {
     &driCoreExtension.base,
     &driLegacyExtension.base,
+    &driDRI2Extension.base,
     NULL
 };