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. |
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.
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 }