/* * Blit a rectangle using the current hardware state. */ bool pvr2dBlit(void *drv, void *dev, DFBRectangle *srect, int dx, int dy) { PVR2DDriverData *gdrv = drv; D_DEBUG_AT(PVR2D__2D, "%s(%4d,%4d-%4dx%4d <- %4d,%4d)\n", __FUNCTION__, dx, dy, srect->w, srect->h, srect->x, srect->y); PVR2DERROR ePVR2DStatus; gdrv->bltinfo.DstX = dx; gdrv->bltinfo.DstY = dy; gdrv->bltinfo.DSizeX = srect->w; gdrv->bltinfo.DSizeY = srect->h; gdrv->bltinfo.SrcX = srect->x; gdrv->bltinfo.SrcY = srect->y; gdrv->bltinfo.SizeX = srect->w; gdrv->bltinfo.SizeY = srect->h; gdrv->bltinfo.CopyCode = 0xcc; ePVR2DStatus = PVR2DBlt( gdrv->hPVR2DContext, &gdrv->bltinfo ); if (ePVR2DStatus) { D_ERROR( "DirectFB/PVR2D: PVR2DBlt() failed! (status %d)\n", ePVR2DStatus ); return false; } return true; }
/* * Render a filled rectangle using the current hardware state. */ bool pvr2dFillRectangle(void *drv, void *dev, DFBRectangle *rect) { PVR2DDriverData *gdrv = drv; D_DEBUG_AT(PVR2D__2D, "%s(%4d,%4d-%4dx%4d)\n", __FUNCTION__, DFB_RECTANGLE_VALS(rect)); PVR2DERROR ePVR2DStatus; gdrv->bltinfo.DstX = rect->x; gdrv->bltinfo.DstY = rect->y; gdrv->bltinfo.DSizeX = rect->w; gdrv->bltinfo.DSizeY = rect->h; gdrv->bltinfo.SrcX = rect->x; gdrv->bltinfo.SrcY = rect->y; gdrv->bltinfo.SizeX = rect->w; gdrv->bltinfo.SizeY = rect->h; gdrv->bltinfo.CopyCode = 0xF0; ePVR2DStatus = PVR2DBlt( gdrv->hPVR2DContext, &gdrv->bltinfo ); if (ePVR2DStatus) { D_ERROR( "DirectFB/PVR2D: PVR2DBlt() failed! (status %d)\n", ePVR2DStatus ); return false; } return true; }
/* 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; }
/* 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; }
/* We are called with the x_lock taken */ static void gst_pvrvideosink_pvrfill_rectangle (GstPVRVideoSink * pvrvideosink, GstVideoRectangle rect) { PVR2DERROR pvr_error; PPVR2DBLTINFO p_blt2d_info = 0; GstDrawContext *dcontext = pvrvideosink->dcontext; GST_DEBUG_OBJECT (pvrvideosink, "begin"); p_blt2d_info = dcontext->p_blt2d_info; p_blt2d_info->pDstMemInfo = &dcontext->dst_mem; p_blt2d_info->BlitFlags = PVR2D_BLIT_DISABLE_ALL; p_blt2d_info->DstOffset = 0; p_blt2d_info->CopyCode = PVR2DROPclear; p_blt2d_info->DstStride = 4 * pvrvideosink->render_params.ui32Stride; p_blt2d_info->DstFormat = PVR2D_ARGB8888; p_blt2d_info->DstSurfWidth = pvrvideosink->xwindow->width; p_blt2d_info->DstSurfHeight = pvrvideosink->xwindow->height; p_blt2d_info->DstX = rect.x; p_blt2d_info->DstY = rect.y; p_blt2d_info->DSizeX = rect.w; p_blt2d_info->DSizeY = rect.h; pvr_error = PVR2DBlt (pvrvideosink->dcontext->pvr_context, p_blt2d_info); if (pvr_error != PVR2D_OK) { GST_ERROR_OBJECT (pvrvideosink, "Failed to blit. Error : %s", gst_pvr2d_error_get_string (pvr_error)); goto done; } dcontext->wsegl_table->pfnWSEGL_SwapDrawable (dcontext->drawable_handle, 1); done: GST_DEBUG_OBJECT (pvrvideosink, "end"); }
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; }