static EGLBoolean droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy); const struct { int format; unsigned int rgba_masks[4]; } visuals[] = { { HAL_PIXEL_FORMAT_RGBA_8888, { 0xff, 0xff00, 0xff0000, 0xff000000 } }, { HAL_PIXEL_FORMAT_RGBX_8888, { 0xff, 0xff00, 0xff0000, 0x0 } }, { HAL_PIXEL_FORMAT_RGB_888, { 0xff, 0xff00, 0xff0000, 0x0 } }, { HAL_PIXEL_FORMAT_RGB_565, { 0xf800, 0x7e0, 0x1f, 0x0 } }, { HAL_PIXEL_FORMAT_BGRA_8888, { 0xff0000, 0xff00, 0xff, 0xff000000 } }, { 0, 0, { 0, 0, 0, 0 } } }; int count, i, j; count = 0; for (i = 0; visuals[i].format; i++) { int format_count = 0; for (j = 0; dri2_dpy->driver_configs[j]; j++) { const EGLint surface_type = EGL_WINDOW_BIT | EGL_PBUFFER_BIT; struct dri2_egl_config *dri2_conf; unsigned int double_buffered = 0; dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[j], __DRI_ATTRIB_DOUBLE_BUFFER, &double_buffered); /* support only double buffered configs */ if (!double_buffered) continue; dri2_conf = dri2_add_config(dpy, dri2_dpy->driver_configs[j], count + 1, surface_type, NULL, visuals[i].rgba_masks); if (dri2_conf) { dri2_conf->base.NativeVisualID = visuals[i].format; dri2_conf->base.NativeVisualType = visuals[i].format; count++; format_count++; } } if (!format_count) { _eglLog(_EGL_DEBUG, "No DRI config supports native format 0x%x", visuals[i].format); } } /* post-process configs */ for (i = 0; i < dpy->Configs->Size; i++) { struct dri2_egl_config *dri2_conf = dri2_egl_config(dpy->Configs->Elements[i]); /* there is no front buffer so no OpenGL */ dri2_conf->base.RenderableType &= ~EGL_OPENGL_BIT; dri2_conf->base.Conformant &= ~EGL_OPENGL_BIT; } return (count != 0); }
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; }
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 * 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; }
/** * 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; }