/* Swap the contents of a drawable to the screen */ static WSEGLError wseglSwapDrawable (WSEGLDrawableHandle _drawable, unsigned long data) { struct wl_egl_window *drawable = (struct wl_egl_window *) _drawable; struct wl_callback *callback; if (drawable->numFlipBuffers) { PVR2DPresentFlip(drawable->display->context, drawable->flipChain, drawable->backBuffers[drawable->currentBackBuffer], 0); } else if (drawable->display->display) { while (drawable->block_swap_buffers == 1) wl_display_iterate(drawable->display->display, WL_DISPLAY_READABLE); drawable->block_swap_buffers = 1; callback = wl_display_sync(drawable->display->display); wl_callback_add_listener(callback, &sync_listener, drawable); wl_buffer_damage(drawable->drmbuffers[drawable->currentBackBuffer], 0, 0, drawable->width, drawable->height); wl_surface_attach(drawable->surface, drawable->drmbuffers[drawable->currentBackBuffer], 0, 0); wl_surface_damage(drawable->surface, 0, 0, drawable->width, drawable->height); } else { PVR2DBLTINFO blit; memset(&blit, 0, sizeof(blit)); blit.CopyCode = PVR2DROPcopy; blit.BlitFlags = PVR2D_BLIT_DISABLE_ALL; blit.pSrcMemInfo = drawable->backBuffers[drawable->currentBackBuffer]; blit.SrcStride = drawable->strideBytes; blit.SrcX = 0; blit.SrcY = 0; blit.SizeX = drawable->width; blit.SizeY = drawable->height; blit.SrcFormat = wsegl2pvr2dformat(drawable->format); blit.pDstMemInfo = drawable->frontBufferPVRMEM; blit.DstStride = drawable->strideBytes; blit.DstX = 0; blit.DstY = 0; blit.DSizeX = drawable->width; blit.DSizeY = drawable->height; blit.DstFormat = wsegl2pvr2dformat(drawable->format); PVR2DBlt(drawable->display->context, &blit); PVR2DQueryBlitsComplete (drawable->display->context, drawable->frontBufferPVRMEM, 1); } drawable->currentBackBuffer = (drawable->currentBackBuffer + 1) % WAYLANDWSEGL_MAX_BACK_BUFFERS; return WSEGL_SUCCESS; }
/* * Wait for the blitter to be idle. * * This function is called before memory that has been written to by the * hardware is about to be accessed by the CPU (software driver) or another * hardware entity like video encoder (by Flip()). It can also be called by * applications explicitly, e.g. at the end of a benchmark loop to include * execution time of queued commands in the measurement. */ DFBResult pvr2dEngineSync(void *drv, void *dev) { PVR2DDriverData *gdrv = drv; D_DEBUG_AT(PVR2D__2D, "%s()\n", __FUNCTION__); if (gdrv->bltinfo.pDstMemInfo) { PVR2DERROR ePVR2DStatus; ePVR2DStatus = PVR2DQueryBlitsComplete( gdrv->hPVR2DContext, gdrv->bltinfo.pDstMemInfo, PVR2D_TRUE ); if (ePVR2DStatus) { D_ERROR( "DirectFB/PVR2D: PVR2DQueryBlitsComplete() failed! (status %d)\n", ePVR2DStatus ); return false; } } return DFB_OK; }
/* Copy color data from a drawable to a native pixmap */ static WSEGLError wseglCopyFromDrawable (WSEGLDrawableHandle _drawable, NativePixmapType nativePixmap) { PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable; PvrQwsDrawable *pixmap = (PvrQwsDrawable *)nativePixmap; PVR2DBLTINFO blit; if (!drawable || !drawable->backBuffersValid) return WSEGL_BAD_NATIVE_WINDOW; if (!pixmap || !pixmap->backBuffersValid) return WSEGL_BAD_NATIVE_PIXMAP; memset(&blit, 0, sizeof(blit)); blit.CopyCode = PVR2DROPcopy; blit.BlitFlags = PVR2D_BLIT_DISABLE_ALL; blit.pSrcMemInfo = drawable->backBuffers[drawable->currentBackBuffer]; blit.SrcStride = drawable->strideBytes; blit.SrcX = 0; blit.SrcY = 0; blit.SizeX = drawable->rect.width; blit.SizeY = drawable->rect.height; blit.SrcFormat = drawable->pixelFormat; blit.pDstMemInfo = pixmap->backBuffers[pixmap->currentBackBuffer]; blit.DstStride = pixmap->strideBytes; blit.DstX = 0; blit.DstY = 0; blit.DSizeX = pixmap->rect.width; blit.DSizeY = pixmap->rect.height; blit.DstFormat = pixmap->pixelFormat; PVR2DBlt(pvrQwsDisplay.context, &blit); PVR2DQueryBlitsComplete (pvrQwsDisplay.context, pixmap->backBuffers[pixmap->currentBackBuffer], 1); return WSEGL_SUCCESS; }
int pvrQwsSwapBuffers(PvrQwsDrawable *drawable, int repaintOnly) { PVR2DMEMINFO *buffer; PvrQwsRect *rect; int index; /* Bail out if the back buffers have been invalidated */ if (!drawable->backBuffersValid) return 0; /* If there is a swap function, then use that instead */ if (drawable->swapFunction) { (*(drawable->swapFunction))(drawable, drawable->userData, repaintOnly); if (!repaintOnly) { drawable->currentBackBuffer = (drawable->currentBackBuffer + 1) % PVRQWS_MAX_BACK_BUFFERS; } return 1; } /* Iterate through the visible rectangles and blit them to the screen */ if (!repaintOnly) { index = drawable->currentBackBuffer; } else { index = (drawable->currentBackBuffer + PVRQWS_MAX_BACK_BUFFERS - 1) % PVRQWS_MAX_BACK_BUFFERS; } buffer = drawable->backBuffers[index]; rect = drawable->visibleRects; if (drawable->usingFlipBuffers) { PVR2DPresentFlip(pvrQwsDisplay.context, pvrQwsDisplay.flipChain, buffer, 0); } else if (pvrQwsDisplay.usePresentBlit && drawable->numVisibleRects > 0) { PVR2DRECT pvrRects[PVRQWS_MAX_VISIBLE_RECTS]; for (index = 0; index < drawable->numVisibleRects; ++index, ++rect) { pvrRects[index].left = rect->x; pvrRects[index].top = rect->y; pvrRects[index].right = rect->x + rect->width; pvrRects[index].bottom = rect->y + rect->height; } for (index = 0; index < drawable->numVisibleRects; index += 4) { int numClip = drawable->numVisibleRects - index; if (numClip > 4) /* No more than 4 clip rects at a time */ numClip = 4; PVR2DSetPresentBltProperties (pvrQwsDisplay.context, PVR2D_PRESENT_PROPERTY_SRCSTRIDE | PVR2D_PRESENT_PROPERTY_DSTSIZE | PVR2D_PRESENT_PROPERTY_DSTPOS | PVR2D_PRESENT_PROPERTY_CLIPRECTS, drawable->strideBytes, drawable->rect.width, drawable->rect.height, drawable->rect.x, drawable->rect.y, numClip, pvrRects + index, 0); PVR2DPresentBlt(pvrQwsDisplay.context, buffer, 0); } PVR2DQueryBlitsComplete(pvrQwsDisplay.context, buffer, 1); } else { /* TODO: use PVR2DBltClipped for faster transfers of clipped windows */ PVR2DBLTINFO blit; for (index = 0; index < drawable->numVisibleRects; ++index, ++rect) { memset(&blit, 0, sizeof(blit)); blit.CopyCode = PVR2DROPcopy; blit.BlitFlags = PVR2D_BLIT_DISABLE_ALL; blit.pSrcMemInfo = buffer; blit.SrcStride = drawable->strideBytes; blit.SrcX = rect->x - drawable->rect.x; blit.SrcY = rect->y - drawable->rect.y; blit.SizeX = rect->width; blit.SizeY = rect->height; blit.SrcFormat = drawable->pixelFormat; blit.pDstMemInfo = pvrQwsDisplay.screens[drawable->screen].frameBuffer; blit.DstStride = pvrQwsDisplay.screens[drawable->screen].screenStride; blit.DstX = rect->x; blit.DstY = rect->y; blit.DSizeX = rect->width; blit.DSizeY = rect->height; blit.DstFormat = pvrQwsDisplay.screens[drawable->screen].pixelFormat; PVR2DBlt(pvrQwsDisplay.context, &blit); } } /* Swap the buffers */ if (!repaintOnly) { drawable->currentBackBuffer = (drawable->currentBackBuffer + 1) % PVRQWS_MAX_BACK_BUFFERS; } return 1; }
/* Swap the contents of a drawable to the screen */ static WSEGLError wseglSwapDrawable (WSEGLDrawableHandle _drawable, unsigned long data) { struct wl_egl_window *drawable = (struct wl_egl_window *) _drawable; struct wl_callback *callback; if (drawable->numFlipBuffers) { // wsegl_info("PRESENT FLIP"); PVR2DPresentFlip(drawable->display->context, drawable->flipChain, drawable->backBuffers[drawable->currentBackBuffer], 0); } else if (drawable->display->display) { //wsegl_info("wseglSwapDrawable for wayland, %d %p", drawable->currentBackBuffer, drawable->drmbuffers[drawable->currentBackBuffer]); int ret = 0; while (drawable->display->frame_callback && ret != -1) ret = wl_display_dispatch_queue(drawable->display->display, drawable->display->queue); drawable->display->frame_callback = wl_surface_frame(drawable->surface); wl_callback_add_listener(drawable->display->frame_callback, &frame_listener, drawable); wl_proxy_set_queue((struct wl_proxy *)drawable->display->frame_callback, drawable->display->queue); if (!drawable->drmbuffers[drawable->currentBackBuffer]) { int32_t handle; struct wl_resource *wlbuf; handle = drawable->exporthandles[drawable->currentBackBuffer]; wlbuf = sgx_wlegl_create_buffer(drawable->display->sgx_wlegl, drawable->width, drawable->height, drawable->strideBytes, drawable->format, handle); drawable->drmbuffers[drawable->currentBackBuffer] = wlbuf; wsegl_info("sgx_wlegl_create_buffer for %d", drawable->currentBackBuffer); wsegl_info("Add listener for %p with %p (buf %d) inside", drawable, wlbuf, drawable->currentBackBuffer); // TODO: listen for release wl_proxy_set_queue((struct wl_proxy *)wlbuf, drawable->display->queue); } struct wl_resource *wlbuf = drawable->drmbuffers[drawable->currentBackBuffer]; wl_surface_attach(drawable->surface, wlbuf, 0, 0); wl_surface_damage(drawable->surface, 0, 0, drawable->width, drawable->height); wl_surface_commit(drawable->surface); } else { PVR2DBLTINFO blit; memset(&blit, 0, sizeof(blit)); blit.CopyCode = PVR2DROPcopy; blit.BlitFlags = PVR2D_BLIT_DISABLE_ALL; blit.pSrcMemInfo = drawable->backBuffers[drawable->currentBackBuffer]; blit.SrcStride = drawable->strideBytes; blit.SrcX = 0; blit.SrcY = 0; blit.SizeX = drawable->width; blit.SizeY = drawable->height; blit.SrcFormat = wsegl2pvr2dformat(drawable->format); blit.pDstMemInfo = drawable->frontBufferPVRMEM; blit.DstStride = drawable->strideBytes; blit.DstX = 0; blit.DstY = 0; blit.DSizeX = drawable->width; blit.DSizeY = drawable->height; blit.DstFormat = wsegl2pvr2dformat(drawable->format); PVR2DBlt(drawable->display->context, &blit); PVR2DQueryBlitsComplete (drawable->display->context, drawable->frontBufferPVRMEM, 1); assert (drawable->display->fd >= 0); struct omapfb_update_window update_window; update_window.x = update_window.out_x = 0; update_window.y = update_window.out_y = 0; update_window.width = update_window.out_width = drawable->width; update_window.height = update_window.out_height = drawable->height; update_window.format = 0; assert(ioctl(drawable->display->fd, OMAPFB_UPDATE_WINDOW, &update_window) == 0); } drawable->currentBackBuffer = (drawable->currentBackBuffer + 1) % WAYLANDWSEGL_MAX_BACK_BUFFERS; return WSEGL_SUCCESS; }