/* Create the WSEGL drawable version of a native window */ static WSEGLError wseglCreateWindowDrawable (WSEGLDisplayHandle display, WSEGLConfig *config, WSEGLDrawableHandle *drawable, NativeWindowType nativeWindow, WSEGLRotationAngle *rotationAngle) { struct wl_egl_display *egldisplay = (struct wl_egl_display *) display; int index; /* Framebuffer */ if (nativeWindow == NULL) { PVR2DDISPLAYINFO displayInfo; assert(egldisplay->display == NULL); /* Let's create a fake wl_egl_window to simplify code */ nativeWindow = wl_egl_window_create(NULL, egldisplay->var.xres, egldisplay->var.yres); nativeWindow->format = getwseglPixelFormat(egldisplay); nativeWindow->display = egldisplay; assert(PVR2DGetDeviceInfo(egldisplay->context, &displayInfo) == PVR2D_OK); wsegl_debug("ulMaxFlipChains: %lu", displayInfo.ulMaxFlipChains); wsegl_debug("ulMaxBuffersInChain: %lu", displayInfo.ulMaxBuffersInChain); wsegl_debug("eFormat: %d", displayInfo.eFormat); wsegl_debug("ulWidth: %lu", displayInfo.ulWidth); wsegl_debug("ulHeight: %lu", displayInfo.ulHeight); wsegl_debug("lStride: %lu", displayInfo.lStride); wsegl_debug("ulMinFlipInterval: %lu", displayInfo.ulMinFlipInterval); wsegl_debug("ulMaxFlipInterval: %lu", displayInfo.ulMaxFlipInterval); if (displayInfo.ulMaxFlipChains > 0 && displayInfo.ulMaxBuffersInChain > 0) nativeWindow->numFlipBuffers = displayInfo.ulMaxBuffersInChain; if (nativeWindow->numFlipBuffers > WAYLANDWSEGL_MAX_FLIP_BUFFERS) nativeWindow->numFlipBuffers = WAYLANDWSEGL_MAX_FLIP_BUFFERS; /* Workaround for broken devices, seen in debugging */ // if (nativeWindow->numFlipBuffers < 2) nativeWindow->numFlipBuffers = 0; } else { nativeWindow->display = egldisplay; nativeWindow->format = config->ePixelFormat; } /* We can't do empty buffers, so let's make a 8x8 one. */ if (nativeWindow->width == 0 || nativeWindow->height == 0) { nativeWindow->width = nativeWindow->height = 8; } /* If we don't have back buffers allocated already */ if (!(nativeWindow->backBuffers[0] && nativeWindow->backBuffersValid)) { nativeWindow->stridePixels = (nativeWindow->width + 7) & ~7; nativeWindow->strideBytes = nativeWindow->stridePixels * wseglPixelFormatBytesPP(nativeWindow->format); if (allocateBackBuffers(egldisplay, nativeWindow) == WSEGL_OUT_OF_MEMORY) return WSEGL_OUT_OF_MEMORY; /* Wayland window */ if (nativeWindow->display->display != NULL) { for (index = 0; index < WAYLANDWSEGL_MAX_BACK_BUFFERS; index++) { PVR2D_HANDLE name; assert(PVR2DMemExport(egldisplay->context, 0, nativeWindow->backBuffers[index], &name) == PVR2D_OK); nativeWindow->exporthandles[index] = name; // TODO: clear exporthandles up } } /* Framebuffer */ else { /* XXX should assert something about stride etc.. */ assert(PVR2DGetFrameBuffer(egldisplay->context, PVR2D_FB_PRIMARY_SURFACE, &nativeWindow->frontBufferPVRMEM) == PVR2D_OK); // nativeWindow->frontBuffer = (void *) nativeWindow->frontBufferPVRMEM->pBase; } } *drawable = (WSEGLDrawableHandle) nativeWindow; /* Reuse the egldisplay */ *rotationAngle = WSEGL_ROTATE_0; return WSEGL_SUCCESS; }
/* Create the WSEGL drawable version of a native window */ static WSEGLError wseglCreateWindowDrawable (WSEGLDisplayHandle display, WSEGLConfig *config, WSEGLDrawableHandle *drawable, NativeWindowType nativeWindow, WSEGLRotationAngle *rotationAngle) { struct wl_egl_display *egldisplay = (struct wl_egl_display *) display; int index; /* Framebuffer */ if (nativeWindow == NULL) { PVR2DDISPLAYINFO displayInfo; assert(egldisplay->display == NULL); /* Let's create a fake wl_egl_window to simplify code */ nativeWindow = wl_egl_window_create(NULL, egldisplay->var.xres, egldisplay->var.yres); nativeWindow->format = getwseglPixelFormat(egldisplay); nativeWindow->display = egldisplay; assert(PVR2DGetDeviceInfo(egldisplay->context, &displayInfo) == PVR2D_OK); if (displayInfo.ulMaxFlipChains > 0 && displayInfo.ulMaxBuffersInChain > 0) nativeWindow->numFlipBuffers = displayInfo.ulMaxBuffersInChain; if (nativeWindow->numFlipBuffers > WAYLANDWSEGL_MAX_FLIP_BUFFERS) nativeWindow->numFlipBuffers = WAYLANDWSEGL_MAX_FLIP_BUFFERS; /* Workaround for broken devices, seen in debugging */ if (nativeWindow->numFlipBuffers < 2) nativeWindow->numFlipBuffers = 0; } else { nativeWindow->display = egldisplay; nativeWindow->format = WSEGL_PIXELFORMAT_8888; } /* We can't do empty buffers, so let's make a 8x8 one. */ if (nativeWindow->width == 0 || nativeWindow->height == 0) { nativeWindow->width = nativeWindow->height = 8; } /* If we don't have back buffers allocated already */ if (!(nativeWindow->backBuffers[0] && nativeWindow->backBuffersValid)) { nativeWindow->stridePixels = (nativeWindow->width + 7) & ~7; nativeWindow->strideBytes = nativeWindow->stridePixels * wseglPixelFormatBytesPP(nativeWindow->format); if (allocateBackBuffers(egldisplay, nativeWindow) == WSEGL_OUT_OF_MEMORY) return WSEGL_OUT_OF_MEMORY; /* Wayland window */ if (nativeWindow->display->display != NULL) { for (index = 0; index < WAYLANDWSEGL_MAX_BACK_BUFFERS; index++) { PVR2D_HANDLE name; assert(PVR2DMemExport(egldisplay->context, 0, nativeWindow->backBuffers[index], &name) == PVR2D_OK); nativeWindow->drmbuffers[index] = wl_drm_create_buffer(egldisplay->drm, (uint32_t)name, nativeWindow->width, nativeWindow->height, nativeWindow->strideBytes, nativeWindow->format); assert(nativeWindow->drmbuffers[index] != NULL); } } /* Framebuffer */ else { assert(PVR2DGetFrameBuffer(egldisplay->context, PVR2D_FB_PRIMARY_SURFACE, &nativeWindow->frontBufferPVRMEM) == PVR2D_OK); } } *drawable = (WSEGLDrawableHandle) nativeWindow; /* Reuse the egldisplay */ *rotationAngle = WSEGL_ROTATE_0; return WSEGL_SUCCESS; }
/* Initialize a native display for use with WSEGL */ static WSEGLError wseglInitializeDisplay (NativeDisplayType nativeDisplay, WSEGLDisplayHandle *display, const WSEGLCaps **caps, WSEGLConfig **configs) { struct wl_egl_display *egldisplay = wl_egl_display_create((struct wl_display *) nativeDisplay); if (wseglFetchContext(egldisplay) != 1) { wl_egl_display_destroy(egldisplay); return WSEGL_OUT_OF_MEMORY; } /* If it is a framebuffer */ if (egldisplay->display == NULL) { wsegl_info("wayland-wsegl: Initializing framebuffer"); int fd; WSEGLPixelFormat format; /* Open the framebuffer and fetch its properties */ fd = open("/dev/fb0", O_RDWR, 0); if (fd < 0) { perror("/dev/fb0"); wseglReleaseContext(egldisplay); wl_egl_display_destroy(egldisplay); return WSEGL_CANNOT_INITIALISE; } if (ioctl(fd, FBIOGET_VSCREENINFO, &egldisplay->var) < 0) { perror("FBIOGET_VSCREENINFO"); wseglReleaseContext(egldisplay); wl_egl_display_destroy(egldisplay); close(fd); return WSEGL_CANNOT_INITIALISE; } if (ioctl(fd, FBIOGET_FSCREENINFO, &egldisplay->fix) < 0) { perror("FBIOGET_FSCREENINFO"); wseglReleaseContext(egldisplay); wl_egl_display_destroy(egldisplay); close(fd); return WSEGL_CANNOT_INITIALISE; } egldisplay->fd = fd; format = getwseglPixelFormat(egldisplay); egldisplay->wseglDisplayConfigs[0].ePixelFormat = format; egldisplay->wseglDisplayConfigs[1].ePixelFormat = format; } else { egldisplay->queue = wl_display_create_queue(nativeDisplay); egldisplay->frame_callback = NULL; egldisplay->registry = wl_display_get_registry(nativeDisplay); wl_proxy_set_queue(egldisplay->registry, egldisplay->queue); wl_registry_add_listener(egldisplay->registry, ®istry_listener, egldisplay); assert(wayland_roundtrip(egldisplay) >= 0); assert(egldisplay->sgx_wlegl); } *display = (WSEGLDisplayHandle)egldisplay; *caps = wseglDisplayCaps; *configs = egldisplay->wseglDisplayConfigs; return WSEGL_SUCCESS; }
/* Initialize a native display for use with WSEGL */ static WSEGLError wseglInitializeDisplay (NativeDisplayType nativeDisplay, WSEGLDisplayHandle *display, const WSEGLCaps **caps, WSEGLConfig **configs) { struct wl_egl_display *egldisplay = wl_egl_display_create((struct wl_display *) nativeDisplay); if (wseglFetchContext(egldisplay) != 1) { wl_egl_display_destroy(egldisplay); return WSEGL_OUT_OF_MEMORY; } /* If it is a framebuffer */ if (egldisplay->display == NULL) { int fd; WSEGLPixelFormat format; /* Open the framebuffer and fetch its properties */ fd = open("/dev/fb0", O_RDWR, 0); if (fd < 0) { perror("/dev/fb0"); wseglReleaseContext(egldisplay); wl_egl_display_destroy(egldisplay); return WSEGL_CANNOT_INITIALISE; } if (ioctl(fd, FBIOGET_VSCREENINFO, &egldisplay->var) < 0) { perror("FBIOGET_VSCREENINFO"); wseglReleaseContext(egldisplay); wl_egl_display_destroy(egldisplay); close(fd); return WSEGL_CANNOT_INITIALISE; } if (ioctl(fd, FBIOGET_FSCREENINFO, &egldisplay->fix) < 0) { perror("FBIOGET_FSCREENINFO"); wseglReleaseContext(egldisplay); wl_egl_display_destroy(egldisplay); close(fd); return WSEGL_CANNOT_INITIALISE; } format = getwseglPixelFormat(egldisplay); egldisplay->wseglDisplayConfigs[0].ePixelFormat = format; egldisplay->wseglDisplayConfigs[1].ePixelFormat = format; } else { uint32_t id; id = wl_display_get_global(egldisplay->display, "wl_drm", 1); if (id == 0) wl_display_roundtrip(egldisplay->display); id = wl_display_get_global(egldisplay->display, "wl_drm", 1); if (id == 0) return WSEGL_CANNOT_INITIALISE; egldisplay->drm = wl_display_bind(egldisplay->display, id, &wl_drm_interface); if (!egldisplay->drm) return WSEGL_CANNOT_INITIALISE; wl_drm_add_listener(egldisplay->drm, &drm_listener, egldisplay); wl_display_roundtrip(egldisplay->display); } *display = (WSEGLDisplayHandle)egldisplay; *caps = wseglDisplayCaps; *configs = egldisplay->wseglDisplayConfigs; return WSEGL_SUCCESS; }