intel_swapbuffers.h File Reference

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void intelDisplaySurface (__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, const drm_clip_rect_t *rect)
 Display a colorbuffer surface in an X window.
void intelSwapBuffers (__DRIdrawablePrivate *dPriv)
void intelCopySubBuffer (__DRIdrawablePrivate *dPriv, int x, int y, int w, int h)
 Called via glXCopySubBufferMESA() to copy a subrect of the back buffer to the front buffer/screen.
void intelUpdateWindowSize (__DRIdrawablePrivate *dPriv)
 This will be called whenever the currently bound window is moved/resized.


Function Documentation

void intelCopySubBuffer ( __DRIdrawablePrivate *  dPriv,
int  x,
int  y,
int  w,
int  h 
)

Called via glXCopySubBufferMESA() to copy a subrect of the back buffer to the front buffer/screen.

Definition at line 240 of file intel_swapbuffers.c.

References assert, intel_framebuffer(), intelDisplaySurface(), st_get_framebuffer_surface(), st_notify_swapbuffers(), ST_SURFACE_BACK_LEFT, and intel_framebuffer::stfb.

00241 {
00242    struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv);
00243    struct pipe_surface *back_surf;
00244 
00245    assert(intel_fb);
00246    assert(intel_fb->stfb);
00247 
00248    back_surf = st_get_framebuffer_surface(intel_fb->stfb,
00249                                           ST_SURFACE_BACK_LEFT);
00250    if (back_surf) {
00251       drm_clip_rect_t rect;
00252       rect.x1 = x;
00253       rect.y1 = y;
00254       rect.x2 = w;
00255       rect.y2 = h;
00256 
00257       st_notify_swapbuffers(intel_fb->stfb);
00258       intelDisplaySurface(dPriv, back_surf, &rect);
00259    }
00260 }

void intelDisplaySurface ( __DRIdrawablePrivate *  dPriv,
struct pipe_surface surf,
const drm_clip_rect_t *  rect 
)

Display a colorbuffer surface in an X window.

Used for SwapBuffers and flushing front buffer rendering.

Parameters:
dPriv the window/drawable to display into
surf the surface to display
rect optional subrect of surface to display (may be NULL).

Definition at line 51 of file intel_swapbuffers.c.

References assert, ASSERT, intel_context::base, intel_be_context::batch, BEGIN_BATCH, BR13(), intel_screen::buffer, pipe_surface::buffer, intel_screen::cpp, DBG, dri_bo(), driFenceFinish(), driFenceUnReference(), intel_context::driScreen, intel_screen::dummyContext, intel_context::first_swap_fence, intel_screen::front, intel_screen::height, pipe_surface::height, intel_be_batchbuffer_flush(), intel_context(), intel_screen(), intelUpdateWindowSize(), intel_context::last_swap_fence, intel_context::lastStamp, LOCK_HARDWARE(), OUT_BATCH, OUT_RELOC, intel_screen::pitch, pipe_surface::stride, TRUE, UNLOCK_HARDWARE(), intel_screen::width, pipe_surface::width, XY_SRC_COPY_BLT_CMD, XY_SRC_COPY_BLT_WRITE_ALPHA, and XY_SRC_COPY_BLT_WRITE_RGB.

00054 {
00055    struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv);
00056    struct intel_context *intel = intelScreen->dummyContext;
00057 
00058    DBG(SWAP, "%s\n", __FUNCTION__);
00059 
00060    if (!intel) {
00061       /* XXX this is where some kind of extra/meta context could be useful */
00062       return;
00063    }
00064 
00065    if (intel->last_swap_fence) {
00066       driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE);
00067       driFenceUnReference(&intel->last_swap_fence);
00068       intel->last_swap_fence = NULL;
00069    }
00070    intel->last_swap_fence = intel->first_swap_fence;
00071    intel->first_swap_fence = NULL;
00072 
00073    /* The LOCK_HARDWARE is required for the cliprects.  Buffer offsets
00074     * should work regardless.
00075     */
00076    LOCK_HARDWARE(intel);
00077    /* if this drawable isn't currently bound the LOCK_HARDWARE done on the
00078     * current context (which is what intelScreenContext should return) might
00079     * not get a contended lock and thus cliprects not updated (tests/manywin)
00080     */
00081    if (intel_context(dPriv->driContextPriv) != intel)
00082       DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv);
00083 
00084 
00085    if (dPriv && dPriv->numClipRects) {
00086       const int srcWidth = surf->width;
00087       const int srcHeight = surf->height;
00088       const int nbox = dPriv->numClipRects;
00089       const drm_clip_rect_t *pbox = dPriv->pClipRects;
00090       const int pitch = intelScreen->front.pitch / intelScreen->front.cpp;
00091       const int cpp = intelScreen->front.cpp;
00092       const int srcpitch = surf->stride / cpp;
00093       int BR13, CMD;
00094       int i;
00095 
00096       ASSERT(surf->buffer);
00097 
00098       DBG(SWAP, "screen pitch %d  src surface pitch %d\n",
00099           pitch, surf->stride);
00100 
00101       if (cpp == 2) {
00102          BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
00103          CMD = XY_SRC_COPY_BLT_CMD;
00104       }
00105       else {
00106          BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
00107          CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
00108                 XY_SRC_COPY_BLT_WRITE_RGB);
00109       }
00110 
00111       for (i = 0; i < nbox; i++, pbox++) {
00112          drm_clip_rect_t box;
00113          drm_clip_rect_t sbox;
00114 
00115          if (pbox->x1 > pbox->x2 ||
00116              pbox->y1 > pbox->y2 ||
00117              pbox->x2 > intelScreen->front.width ||
00118              pbox->y2 > intelScreen->front.height) {
00119             /* invalid cliprect, skip it */
00120             continue;
00121          }
00122 
00123          box = *pbox;
00124 
00125          if (rect) {
00126             /* intersect cliprect with user-provided src rect */
00127             drm_clip_rect_t rrect;
00128 
00129             rrect.x1 = dPriv->x + rect->x1;
00130             rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y;
00131             rrect.x2 = rect->x2 + rrect.x1;
00132             rrect.y2 = rect->y2 + rrect.y1;
00133             if (rrect.x1 > box.x1)
00134                box.x1 = rrect.x1;
00135             if (rrect.y1 > box.y1)
00136                box.y1 = rrect.y1;
00137             if (rrect.x2 < box.x2)
00138                box.x2 = rrect.x2;
00139             if (rrect.y2 < box.y2)
00140                box.y2 = rrect.y2;
00141 
00142             if (box.x1 > box.x2 || box.y1 > box.y2)
00143                continue;
00144          }
00145 
00146          /* restrict blit to size of actually rendered area */
00147          if (box.x2 - box.x1 > srcWidth)
00148             box.x2 = srcWidth + box.x1;
00149          if (box.y2 - box.y1 > srcHeight)
00150             box.y2 = srcHeight + box.y1;
00151 
00152          DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n",
00153              box.x1, box.x2, box.y1, box.y2);
00154 
00155          sbox.x1 = box.x1 - dPriv->x;
00156          sbox.y1 = box.y1 - dPriv->y;
00157 
00158          assert(box.x1 < box.x2);
00159          assert(box.y1 < box.y2);
00160 
00161          /* XXX this could be done with pipe->surface_copy() */
00162          /* XXX should have its own batch buffer */
00163          if (!BEGIN_BATCH(8, 2)) {
00164             /*
00165              * Since we share this batch buffer with a context
00166              * we can't flush it since that risks a GPU lockup
00167              */
00168             assert(0);
00169             continue;
00170          }
00171 
00172          OUT_BATCH(CMD);
00173          OUT_BATCH(BR13);
00174          OUT_BATCH((box.y1 << 16) | box.x1);
00175          OUT_BATCH((box.y2 << 16) | box.x2);
00176 
00177          OUT_RELOC(intelScreen->front.buffer,
00178                    DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
00179                    DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
00180          OUT_BATCH((sbox.y1 << 16) | sbox.x1);
00181          OUT_BATCH((srcpitch * cpp) & 0xffff);
00182          OUT_RELOC(dri_bo(surf->buffer),
00183                    DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
00184                    DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
00185 
00186       }
00187 
00188       if (intel->first_swap_fence)
00189          driFenceUnReference(&intel->first_swap_fence);
00190       intel->first_swap_fence = intel_be_batchbuffer_flush(intel->base.batch);
00191    }
00192 
00193    UNLOCK_HARDWARE(intel);
00194 
00195    if (intel->lastStamp != dPriv->lastStamp) {
00196       intelUpdateWindowSize(dPriv);
00197       intel->lastStamp = dPriv->lastStamp;
00198    }
00199 }

void intelSwapBuffers ( __DRIdrawablePrivate *  dPriv  ) 

Definition at line 217 of file intel_swapbuffers.c.

References assert, intel_framebuffer(), intelDisplaySurface(), st_get_framebuffer_surface(), st_notify_swapbuffers(), st_notify_swapbuffers_complete(), ST_SURFACE_BACK_LEFT, and intel_framebuffer::stfb.

00218 {
00219    struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv);
00220    struct pipe_surface *back_surf;
00221 
00222    assert(intel_fb);
00223    assert(intel_fb->stfb);
00224 
00225    back_surf = st_get_framebuffer_surface(intel_fb->stfb,
00226                                           ST_SURFACE_BACK_LEFT);
00227    if (back_surf) {
00228       st_notify_swapbuffers(intel_fb->stfb);
00229       intelDisplaySurface(dPriv, back_surf, NULL);
00230       st_notify_swapbuffers_complete(intel_fb->stfb);
00231    }
00232 }

void intelUpdateWindowSize ( __DRIdrawablePrivate *  dPriv  ) 

This will be called whenever the currently bound window is moved/resized.

Definition at line 207 of file intel_swapbuffers.c.

References assert, intel_framebuffer(), st_resize_framebuffer(), and intel_framebuffer::stfb.

00208 {
00209    struct intel_framebuffer *intelfb = intel_framebuffer(dPriv);
00210    assert(intelfb->stfb);
00211    st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h);
00212 }


Generated on Tue Sep 29 06:25:46 2009 for Gallium3D by  doxygen 1.5.4