/* 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; }
static WSEGLError allocateBackBuffers(struct wl_egl_display *egldisplay, NativeWindowType nativeWindow) { int index; if (nativeWindow->numFlipBuffers) { long stride = 0; unsigned long flipId = 0; unsigned long numBuffers; PVR2DERROR ret = PVR2DCreateFlipChain(egldisplay->context, 0, //PVR2D_CREATE_FLIPCHAIN_SHARED | //PVR2D_CREATE_FLIPCHAIN_QUERY, nativeWindow->numFlipBuffers, nativeWindow->width, nativeWindow->height, wsegl2pvr2dformat(nativeWindow->format), &stride, &flipId, &(nativeWindow->flipChain)); assert(ret == PVR2D_OK); PVR2DGetFlipChainBuffers(egldisplay->context, nativeWindow->flipChain, &numBuffers, nativeWindow->flipBuffers); for (index = 0; index < numBuffers; ++index) { nativeWindow->backBuffers[index] = nativeWindow->flipBuffers[index]; } } else { for (index = 0; index < WAYLANDWSEGL_MAX_BACK_BUFFERS; ++index) { if (PVR2DMemAlloc(egldisplay->context, nativeWindow->strideBytes * nativeWindow->height, 128, 0, &(nativeWindow->backBuffers[index])) != PVR2D_OK) { assert(0); while (--index >= 0) PVR2DMemFree(egldisplay->context, nativeWindow->backBuffers[index]); memset(nativeWindow->backBuffers, 0, sizeof(nativeWindow->backBuffers)); nativeWindow->backBuffersValid = 0; return WSEGL_OUT_OF_MEMORY; } } } nativeWindow->backBuffersValid = 1; nativeWindow->currentBackBuffer = 0; return WSEGL_SUCCESS; }
/* 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; }