/** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ static _EGLSurface * haiku_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, void *native_window, const EGLint *attrib_list) { CALLED(); struct haiku_egl_surface* surface; surface = (struct haiku_egl_surface*) calloc(1, sizeof (*surface)); if (!surface) { _eglError(EGL_BAD_ALLOC, "haiku_create_window_surface"); return NULL; } if (!_eglInitSurface(&surface->surf, disp, EGL_WINDOW_BIT, conf, attrib_list)) { free(surface); return NULL; } (&surface->surf)->SwapInterval = 1; TRACE("Creating window\n"); BWindow* win = (BWindow*)native_window; TRACE("Creating GL view\n"); surface->gl = new BGLView(win->Bounds(), "OpenGL", B_FOLLOW_ALL_SIDES, 0, BGL_RGB | BGL_DOUBLE | BGL_ALPHA); TRACE("Adding GL\n"); win->AddChild(surface->gl); TRACE("Showing window\n"); win->Show(); return &surface->surf; }
static struct egl_g3d_surface * create_pbuffer_surface(_EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attribs, const char *func) { struct egl_g3d_config *gconf = egl_g3d_config(conf); struct egl_g3d_surface *gsurf; gsurf = CALLOC_STRUCT(egl_g3d_surface); if (!gsurf) { _eglError(EGL_BAD_ALLOC, func); return NULL; } if (!_eglInitSurface(&gsurf->base, dpy, EGL_PBUFFER_BIT, conf, attribs)) { FREE(gsurf); return NULL; } gsurf->stvis = gconf->stvis; gsurf->stfbi = egl_g3d_create_st_framebuffer(&gsurf->base); if (!gsurf->stfbi) { FREE(gsurf); return NULL; } return gsurf; }
static _EGLSurface * droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, EGLNativeWindowType window, const EGLint *attrib_list) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); struct dri2_egl_surface *dri2_surf; dri2_surf = calloc(1, sizeof *dri2_surf); if (!dri2_surf) { _eglError(EGL_BAD_ALLOC, "droid_create_surface"); return NULL; } if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surface; if (type == EGL_WINDOW_BIT) { int format; if (!window || window->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) { _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface"); goto cleanup_surface; } if (window->query(window, NATIVE_WINDOW_FORMAT, &format)) { _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface"); goto cleanup_surface; } if (format != dri2_conf->base.NativeVisualID) { _eglLog(_EGL_WARNING, "Native format mismatch: 0x%x != 0x%x", format, dri2_conf->base.NativeVisualID); } window->query(window, NATIVE_WINDOW_WIDTH, &dri2_surf->base.Width); window->query(window, NATIVE_WINDOW_HEIGHT, &dri2_surf->base.Height); } dri2_surf->dri_drawable = (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, dri2_conf->dri_double_config, dri2_surf); if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); goto cleanup_surface; } if (window) { window->common.incRef(&window->common); dri2_surf->window = window; } return &dri2_surf->base; cleanup_surface: free(dri2_surf); return NULL; }
static _EGLSurface * dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, EGLNativeWindowType window, const EGLint *attrib_list) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); struct dri2_egl_surface *dri2_surf; struct gbm_dri_surface *surf; (void) drv; dri2_surf = malloc(sizeof *dri2_surf); if (!dri2_surf) { _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); return NULL; } memset(dri2_surf, 0, sizeof *dri2_surf); if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surf; switch (type) { case EGL_WINDOW_BIT: if (!window) return NULL; surf = gbm_dri_surface((struct gbm_surface *) window); dri2_surf->gbm_surf = surf; dri2_surf->base.Width = surf->base.width; dri2_surf->base.Height = surf->base.height; surf->dri_private = dri2_surf; break; default: goto cleanup_surf; } dri2_surf->dri_drawable = (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen, dri2_conf->dri_double_config, dri2_surf->gbm_surf); if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); goto cleanup_surf; } return &dri2_surf->base; cleanup_surf: free(dri2_surf); return NULL; }
/** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ static EGLSurface xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) { struct xlib_egl_driver *xdrv = xlib_egl_driver(drv); _EGLDisplay *disp = _eglLookupDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); struct xlib_egl_surface *surf; __GLcontextModes visual; uint width, height; surf = CALLOC_STRUCT(xlib_egl_surface); if (!surf) return EGL_NO_SURFACE; /* Let EGL lib init the common stuff */ if (!_eglInitSurface(drv, dpy, &surf->Base, EGL_WINDOW_BIT, config, attrib_list)) { free(surf); return EGL_NO_SURFACE; } _eglSaveSurface(&surf->Base); /* * Now init the Xlib and gallium stuff */ surf->Win = (Window) window; /* The X window ID */ surf->Dpy = disp->Xdpy; /* The X display */ surf->Gc = XCreateGC(surf->Dpy, surf->Win, 0, NULL); surf->winsys = xdrv->winsys; _eglConfigToContextModesRec(conf, &visual); get_drawable_size(surf->Dpy, surf->Win, &width, &height); get_drawable_visual_info(surf->Dpy, surf->Win, &surf->VisInfo); surf->Base.Width = width; surf->Base.Height = height; /* Create GL statetracker framebuffer */ surf->Framebuffer = st_create_framebuffer(&visual, choose_color_format(&visual), choose_depth_format(&visual), choose_stencil_format(&visual), width, height, (void *) surf); st_resize_framebuffer(surf->Framebuffer, width, height); return _eglGetSurfaceHandle(&surf->Base); }
static _EGLSurface * dri2_surfaceless_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, const EGLint *attrib_list) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); struct dri2_egl_surface *dri2_surf; const __DRIconfig *config; /* Make sure to calloc so all pointers * are originally NULL. */ dri2_surf = calloc(1, sizeof *dri2_surf); if (!dri2_surf) { _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface"); return NULL; } if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surface; config = dri2_get_dri_config(dri2_conf, type, dri2_surf->base.GLColorspace); if (!config) goto cleanup_surface; dri2_surf->dri_drawable = (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config, dri2_surf); if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); goto cleanup_surface; } if (conf->RedSize == 5) dri2_surf->visual = __DRI_IMAGE_FORMAT_RGB565; else if (conf->AlphaSize == 0) dri2_surf->visual = __DRI_IMAGE_FORMAT_XRGB8888; else dri2_surf->visual = __DRI_IMAGE_FORMAT_ARGB8888; return &dri2_surf->base; cleanup_surface: free(dri2_surf); return NULL; }
/** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ static _EGLSurface * xdri_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list) { struct xdri_egl_display *xdri_dpy = lookup_display(dpy); struct xdri_egl_config *xdri_config = lookup_config(conf); struct xdri_egl_surface *xdri_surf; uint width, height; xdri_surf = CALLOC_STRUCT(xdri_egl_surface); if (!xdri_surf) { _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface"); return NULL; } if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_WINDOW_BIT, &xdri_config->Base, attrib_list)) { free(xdri_surf); return NULL; } xdri_surf->driDrawable = xdri_dpy->psc->driScreen->createDrawable(xdri_dpy->psc, (XID) window, (GLXDrawable) window, xdri_config->mode); if (!xdri_surf->driDrawable) { free(xdri_surf); return NULL; } xdri_surf->drawable = (Drawable) window; get_drawable_size(xdri_dpy->dpy, window, &width, &height); xdri_surf->Base.Width = width; xdri_surf->Base.Height = height; return &xdri_surf->Base; }
/** * Example function - drivers should do a proper implementation. */ EGLSurface _eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { #if 0 /* THIS IS JUST EXAMPLE CODE */ _EGLSurface *surf; surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface)); if (!surf) return EGL_NO_SURFACE; if (!_eglInitSurface(drv, dpy, surf, EGL_SCREEN_BIT_MESA, config, attrib_list)) { free(surf); return EGL_NO_SURFACE; } _eglSaveSurface(surf); return surf->Handle; #endif return EGL_NO_SURFACE; }
/** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ static _EGLSurface * haiku_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, void *native_window, const EGLint *attrib_list) { struct haiku_egl_surface* surface; surface = (struct haiku_egl_surface*)calloc(1,sizeof (*surface)); _eglInitSurface(&surface->surf, disp, EGL_WINDOW_BIT, conf, attrib_list); (&surface->surf)->SwapInterval = 1; _eglLog(_EGL_DEBUG, "Creating window"); BWindow* win = (BWindow*)native_window; _eglLog(_EGL_DEBUG, "Creating GL view"); surface->gl = new BGLView(win->Bounds(), "OpenGL", B_FOLLOW_ALL_SIDES, 0, BGL_RGB | BGL_DOUBLE | BGL_ALPHA); _eglLog(_EGL_DEBUG, "Adding GL"); win->AddChild(surface->gl); _eglLog(_EGL_DEBUG, "Showing window"); win->Show(); return &surface->surf; }
/** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ static _EGLSurface * dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, EGLNativeWindowType native_window, const EGLint *attrib_list) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); struct dri2_egl_surface *dri2_surf; xcb_get_geometry_cookie_t cookie; xcb_get_geometry_reply_t *reply; xcb_screen_iterator_t s; xcb_generic_error_t *error; xcb_drawable_t window = (uintptr_t )native_window; (void) drv; dri2_surf = malloc(sizeof *dri2_surf); if (!dri2_surf) { _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); return NULL; } if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surf; dri2_surf->region = XCB_NONE; if (type == EGL_PBUFFER_BIT) { dri2_surf->drawable = xcb_generate_id(dri2_dpy->conn); s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); xcb_create_pixmap(dri2_dpy->conn, conf->BufferSize, dri2_surf->drawable, s.data->root, dri2_surf->base.Width, dri2_surf->base.Height); } else { dri2_surf->drawable = window; } if (dri2_dpy->dri2) { dri2_surf->dri_drawable = (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen, type == EGL_WINDOW_BIT ? dri2_conf->dri_double_config : dri2_conf->dri_single_config, dri2_surf); } else { assert(dri2_dpy->swrast); dri2_surf->dri_drawable = (*dri2_dpy->swrast->createNewDrawable) (dri2_dpy->dri_screen, dri2_conf->dri_double_config, dri2_surf); } if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); goto cleanup_pixmap; } if (dri2_dpy->dri2) { xcb_dri2_create_drawable (dri2_dpy->conn, dri2_surf->drawable); } else { swrastCreateDrawable(dri2_dpy, dri2_surf, _eglGetConfigKey(conf, EGL_BUFFER_SIZE)); } if (type != EGL_PBUFFER_BIT) { cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable); reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error); if (reply == NULL || error != NULL) { _eglError(EGL_BAD_ALLOC, "xcb_get_geometry"); free(error); goto cleanup_dri_drawable; } dri2_surf->base.Width = reply->width; dri2_surf->base.Height = reply->height; free(reply); } /* we always copy the back buffer to front */ dri2_surf->base.PostSubBufferSupportedNV = EGL_TRUE; return &dri2_surf->base; cleanup_dri_drawable: dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); cleanup_pixmap: if (type == EGL_PBUFFER_BIT) xcb_free_pixmap(dri2_dpy->conn, dri2_surf->drawable); cleanup_surf: free(dri2_surf); return NULL; }
/** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ static _EGLSurface * dri2_x11_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, void *native_surface, const EGLint *attrib_list) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); struct dri2_egl_surface *dri2_surf; xcb_get_geometry_cookie_t cookie; xcb_get_geometry_reply_t *reply; xcb_screen_iterator_t s; xcb_generic_error_t *error; xcb_drawable_t drawable; xcb_screen_t *screen; const __DRIconfig *config; STATIC_ASSERT(sizeof(uintptr_t) == sizeof(native_surface)); drawable = (uintptr_t) native_surface; (void) drv; dri2_surf = malloc(sizeof *dri2_surf); if (!dri2_surf) { _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); return NULL; } if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surf; dri2_surf->region = XCB_NONE; if (type == EGL_PBUFFER_BIT) { s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); screen = get_xcb_screen(s, dri2_dpy->screen); if (!screen) { _eglError(EGL_BAD_ALLOC, "failed to get xcb screen"); goto cleanup_surf; } dri2_surf->drawable = xcb_generate_id(dri2_dpy->conn); xcb_create_pixmap(dri2_dpy->conn, conf->BufferSize, dri2_surf->drawable, screen->root, dri2_surf->base.Width, dri2_surf->base.Height); } else { if (!drawable) { if (type == EGL_WINDOW_BIT) _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_create_surface"); else _eglError(EGL_BAD_NATIVE_PIXMAP, "dri2_create_surface"); goto cleanup_surf; } dri2_surf->drawable = drawable; } config = dri2_get_dri_config(dri2_conf, type, dri2_surf->base.GLColorspace); if (dri2_dpy->dri2) { dri2_surf->dri_drawable = (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config, dri2_surf); } else { assert(dri2_dpy->swrast); dri2_surf->dri_drawable = (*dri2_dpy->swrast->createNewDrawable)(dri2_dpy->dri_screen, config, dri2_surf); } if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); goto cleanup_pixmap; } if (type != EGL_PBUFFER_BIT) { cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable); reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error); if (error != NULL) { if (error->error_code == BadAlloc) _eglError(EGL_BAD_ALLOC, "xcb_get_geometry"); else if (type == EGL_WINDOW_BIT) _eglError(EGL_BAD_NATIVE_WINDOW, "xcb_get_geometry"); else _eglError(EGL_BAD_NATIVE_PIXMAP, "xcb_get_geometry"); free(error); goto cleanup_dri_drawable; } else if (reply == NULL) { _eglError(EGL_BAD_ALLOC, "xcb_get_geometry"); goto cleanup_dri_drawable; } dri2_surf->base.Width = reply->width; dri2_surf->base.Height = reply->height; dri2_surf->depth = reply->depth; free(reply); } if (dri2_dpy->dri2) { xcb_void_cookie_t cookie; int conn_error; cookie = xcb_dri2_create_drawable_checked(dri2_dpy->conn, dri2_surf->drawable); error = xcb_request_check(dri2_dpy->conn, cookie); conn_error = xcb_connection_has_error(dri2_dpy->conn); if (conn_error || error != NULL) { if (type == EGL_PBUFFER_BIT || conn_error || error->error_code == BadAlloc) _eglError(EGL_BAD_ALLOC, "xcb_dri2_create_drawable_checked"); else if (type == EGL_WINDOW_BIT) _eglError(EGL_BAD_NATIVE_WINDOW, "xcb_dri2_create_drawable_checked"); else _eglError(EGL_BAD_NATIVE_PIXMAP, "xcb_dri2_create_drawable_checked"); free(error); goto cleanup_dri_drawable; } } else { if (type == EGL_PBUFFER_BIT) { dri2_surf->depth = _eglGetConfigKey(conf, EGL_BUFFER_SIZE); } swrastCreateDrawable(dri2_dpy, dri2_surf); } /* we always copy the back buffer to front */ dri2_surf->base.PostSubBufferSupportedNV = EGL_TRUE; return &dri2_surf->base; cleanup_dri_drawable: dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); cleanup_pixmap: if (type == EGL_PBUFFER_BIT) xcb_free_pixmap(dri2_dpy->conn, dri2_surf->drawable); cleanup_surf: free(dri2_surf); return NULL; }
static _EGLSurface * dri2_drm_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, void *native_window, const EGLint *attrib_list) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); struct dri2_egl_surface *dri2_surf; struct gbm_surface *window = native_window; struct gbm_dri_surface *surf; const __DRIconfig *config; (void) drv; dri2_surf = calloc(1, sizeof *dri2_surf); if (!dri2_surf) { _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); return NULL; } if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surf; switch (type) { case EGL_WINDOW_BIT: if (!window) { _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_create_surface"); goto cleanup_surf; } surf = gbm_dri_surface(window); dri2_surf->gbm_surf = surf; dri2_surf->base.Width = surf->base.width; dri2_surf->base.Height = surf->base.height; surf->dri_private = dri2_surf; break; default: goto cleanup_surf; } config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT, dri2_surf->base.GLColorspace); if (dri2_dpy->dri2) { dri2_surf->dri_drawable = (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config, dri2_surf->gbm_surf); } else { assert(dri2_dpy->swrast != NULL); dri2_surf->dri_drawable = (*dri2_dpy->swrast->createNewDrawable)(dri2_dpy->dri_screen, config, dri2_surf->gbm_surf); } if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "createNewDrawable()"); goto cleanup_surf; } return &dri2_surf->base; cleanup_surf: free(dri2_surf); return NULL; }
static _EGLSurface * egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, struct egl_g3d_create_surface_arg *arg, const EGLint *attribs) { struct egl_g3d_display *gdpy = egl_g3d_display(dpy); struct egl_g3d_config *gconf = egl_g3d_config(conf); struct egl_g3d_surface *gsurf; struct native_surface *nsurf; const char *err; switch (arg->type) { case EGL_WINDOW_BIT: err = "eglCreateWindowSurface"; break; case EGL_PIXMAP_BIT: err = "eglCreatePixmapSurface"; break; #ifdef EGL_MESA_screen_surface case EGL_SCREEN_BIT_MESA: err = "eglCreateScreenSurface"; break; #endif default: err = "eglCreateUnknownSurface"; break; } gsurf = CALLOC_STRUCT(egl_g3d_surface); if (!gsurf) { _eglError(EGL_BAD_ALLOC, err); return NULL; } if (!_eglInitSurface(&gsurf->base, dpy, arg->type, conf, attribs)) { FREE(gsurf); return NULL; } /* create the native surface */ switch (arg->type) { case EGL_WINDOW_BIT: nsurf = gdpy->native->create_window_surface(gdpy->native, arg->u.win, gconf->native); break; case EGL_PIXMAP_BIT: nsurf = gdpy->native->create_pixmap_surface(gdpy->native, arg->u.pix, gconf->native); break; #ifdef EGL_MESA_screen_surface case EGL_SCREEN_BIT_MESA: /* prefer back buffer (move to _eglInitSurface?) */ gsurf->base.RenderBuffer = EGL_BACK_BUFFER; nsurf = gdpy->native->modeset->create_scanout_surface(gdpy->native, gconf->native, gsurf->base.Width, gsurf->base.Height); break; #endif default: nsurf = NULL; break; } if (!nsurf) { FREE(gsurf); return NULL; } /* initialize the geometry */ if (!nsurf->validate(nsurf, 0x0, &gsurf->sequence_number, NULL, &gsurf->base.Width, &gsurf->base.Height)) { nsurf->destroy(nsurf); FREE(gsurf); return NULL; } gsurf->stvis = gconf->stvis; if (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER && gconf->stvis.buffer_mask & ST_ATTACHMENT_FRONT_LEFT_MASK) gsurf->stvis.render_buffer = ST_ATTACHMENT_FRONT_LEFT; /* surfaces can always be posted when the display supports it */ if (dpy->Extensions.NV_post_sub_buffer) gsurf->base.PostSubBufferSupportedNV = EGL_TRUE; gsurf->stfbi = egl_g3d_create_st_framebuffer(&gsurf->base); if (!gsurf->stfbi) { nsurf->destroy(nsurf); FREE(gsurf); return NULL; } nsurf->user_data = &gsurf->base; gsurf->native = nsurf; return &gsurf->base; }
/** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ static _EGLSurface * dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, EGLNativeWindowType window, const EGLint *attrib_list) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); struct dri2_egl_surface *dri2_surf; struct dri2_egl_buffer *dri2_buf; int i; (void) drv; dri2_surf = malloc(sizeof *dri2_surf); if (!dri2_surf) { _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); return NULL; } if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surf; for (i = 0; i < WL_BUFFER_COUNT; ++i) { dri2_surf->wl_drm_buffer[i] = NULL; dri2_surf->wl_buffer_lock[i] = 0; } for (i = 0; i < __DRI_BUFFER_COUNT; ++i) dri2_surf->dri_buffers[i] = NULL; dri2_surf->pending_buffer = NULL; dri2_surf->third_buffer = NULL; dri2_surf->block_swap_buffers = EGL_FALSE; if (conf->AlphaSize == 0) dri2_surf->format = WL_DRM_FORMAT_XRGB32; else if (dri2_surf->base.VGAlphaFormat == EGL_VG_ALPHA_FORMAT_PRE) dri2_surf->format = WL_DRM_FORMAT_PREMULTIPLIED_ARGB32; else dri2_surf->format = WL_DRM_FORMAT_ARGB32; switch (type) { case EGL_WINDOW_BIT: dri2_surf->wl_win = (struct wl_egl_window *) window; dri2_surf->base.Width = -1; dri2_surf->base.Height = -1; break; case EGL_PIXMAP_BIT: dri2_surf->wl_pix = (struct wl_egl_pixmap *) window; dri2_surf->base.Width = dri2_surf->wl_pix->width; dri2_surf->base.Height = dri2_surf->wl_pix->height; if (dri2_surf->wl_pix->driver_private) { dri2_buf = dri2_surf->wl_pix->driver_private; dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] = dri2_buf->dri_buffer; } break; default: goto cleanup_surf; } dri2_surf->dri_drawable = (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen, type == EGL_WINDOW_BIT ? dri2_conf->dri_double_config : dri2_conf->dri_single_config, dri2_surf); if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); goto cleanup_dri_drawable; } return &dri2_surf->base; cleanup_dri_drawable: dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable); cleanup_surf: free(dri2_surf); return NULL; }
static _EGLSurface * dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, EGLNativeWindowType window, const EGLint *attrib_list) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); struct dri2_egl_surface *dri2_surf; struct gbm_dri_surface *surf; struct gbm_bo *bo; _EGLImage *img; EGLint attr[10]; (void) drv; dri2_surf = calloc(1, sizeof *dri2_surf); if (!dri2_surf) { _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); return NULL; } if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surf; switch (type) { case EGL_WINDOW_BIT: if (!window) return NULL; surf = gbm_dri_surface((struct gbm_surface *) window); dri2_surf->gbm_surf = surf; dri2_surf->base.Width = surf->base.width; dri2_surf->base.Height = surf->base.height; surf->dri_private = dri2_surf; break; default: goto cleanup_surf; } attr[0] = EGL_WIDTH; attr[1] = surf->base.width; attr[2] = EGL_HEIGHT; attr[3] = surf->base.height; attr[4] = EGL_DRM_BUFFER_FORMAT_MESA; attr[5] = EGL_DRM_BUFFER_FORMAT_ARGB32_MESA; attr[6] = EGL_DRM_BUFFER_USE_MESA; attr[7] = EGL_DRM_BUFFER_USE_SHARE_MESA; attr[8] = EGL_NONE; img = drv->API.CreateDRMImageMESA(drv, disp, attr); dri2_surf->egl_front = img; dri2_surf->khr_front = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR; bo = gbm_bo_import(&dri2_dpy->gbm_dri->base.base, GBM_BO_IMPORT_EGL_IMAGE, dri2_surf->khr_front, 0); if( bo == NULL){ _eglError(EGL_BAD_ALLOC, "gbm_bo_create front buffer"); goto cleanup_surf; } dri2_surf->color_buffers[1].bo = bo; img = drv->API.CreateDRMImageMESA(drv, disp, attr); dri2_surf->egl_back = img; dri2_surf->khr_back = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR; bo = gbm_bo_import(&dri2_dpy->gbm_dri->base.base, GBM_BO_IMPORT_EGL_IMAGE, dri2_surf->khr_back, 0); if( bo == NULL){ _eglError(EGL_BAD_ALLOC, "gbm_bo_create back buffer"); goto cleanup_surf; } dri2_surf->color_buffers[2].bo = bo; dri2_surf->dri_drawable = (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen, dri2_conf->dri_double_config, dri2_surf->gbm_surf); if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); goto cleanup_surf; } return &dri2_surf->base; cleanup_surf: free(dri2_surf); return NULL; }