diff options
| -rw-r--r-- | src/gallium/winsys/egl_drm/intel/intel_egl.c | 81 | 
1 files changed, 71 insertions, 10 deletions
| diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c index a476490b90..55f4d92afb 100644 --- a/src/gallium/winsys/egl_drm/intel/intel_egl.c +++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c @@ -24,6 +24,8 @@  #include "state_tracker/st_public.h" +#define MAX_SCREENS 16 +  static void  drm_get_device_id(struct egl_drm_device *device)  { @@ -66,11 +68,17 @@ egl_drm_create_device(int drmFD)  __GLcontextModes* _gl_context_modes_create( unsigned count, size_t minimum_size ); +struct drm_screen; +  struct drm_driver  {  	_EGLDriver base;  /* base class/object */  	drmModeResPtr res; + +	struct drm_screen *screens[MAX_SCREENS]; +	size_t count_screens; +  	struct egl_drm_device *device;  }; @@ -92,17 +100,26 @@ struct drm_screen  {  	_EGLScreen base; -	/* backing buffer and crtc */ +	/* currently only support one connector */ +	drmModeConnectorPtr connector; +	uint32_t connectorID; + +	/* Has this screen been shown */ +	int shown; + +	/* Surface that is currently attached to this screen */ +	struct drm_surface *surf; + +	/* backing buffer */  	drmBO buffer; + +	/* framebuffer */  	drmModeFBPtr fb;  	uint32_t fbID; -	drmModeCrtcPtr crtc; -	/* currently only support one connector */ -	drmModeConnectorPtr connector; -	drmModeEncoderPtr encoder; -	uint32_t connectorID; -	uint32_t encoderID; +	/* crtc and mode used */ +	drmModeCrtcPtr crtc; +	uint32_t crtcID;  	struct drm_mode_modeinfo *mode; @@ -139,6 +156,7 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)  	drmModeConnectorPtr connector = NULL;  	drmModeResPtr res = NULL;  	unsigned count_connectors = 0; +	int num_screens = 0;  	EGLint i;  	int fd; @@ -159,13 +177,13 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)  	if (res)  		count_connectors = res->count_connectors; -	for(i = 0; i < count_connectors; i++) { +	for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) {  		connector = drmModeGetConnector(fd, res->connectors[i]);  		if (!connector)  			continue; -		if (connector->connection == DRM_MODE_DISCONNECTED) { +		if (connector->connection != DRM_MODE_CONNECTED) {  			drmModeFreeConnector(connector);  			continue;  		} @@ -177,7 +195,9 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)  		_eglInitScreen(&screen->base);  		_eglAddScreen(disp, &screen->base);  		drm_add_modes_from_connector(&screen->base, connector); +		drm_drv->screens[num_screens++] = screen;  	} +	drm_drv->count_screens = num_screens;  	/* for now we only have one config */  	_EGLConfig *config = calloc(1, sizeof(*config)); @@ -201,15 +221,52 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)  	return EGL_TRUE;  } +static void +drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen) +{ +	struct drm_driver *drm_drv = (struct drm_driver *)drv; + +	intel_bind_frontbuffer(screen->surf->drawable, NULL); +	screen->surf = NULL; + +	drmModeSetCrtc( +		drm_drv->device->drmFD, +		drm_drv->res->crtcs[1], +		0, // FD +		0, 0, +		NULL, 0, // List of output ids +		NULL); + +	drmModeRmFB(drm_drv->device->drmFD, screen->fbID); +	drmModeFreeFB(screen->fb); +	screen->fb = NULL; + +	drmBOUnreference(drm_drv->device->drmFD, &screen->buffer); + +	screen->shown = 0; +}  static EGLBoolean  drm_terminate(_EGLDriver *drv, EGLDisplay dpy)  {  	struct drm_driver *drm_drv = (struct drm_driver *)drv; +	struct drm_screen *screen; +	int i = 0;  	intel_destroy_device(drm_drv->device);  	drmFreeVersion(drm_drv->device->version); +	for (i = 0; i < drm_drv->count_screens; i++) { +		screen = drm_drv->screens[i]; + +		if (screen->shown) +			drm_takedown_shown_screen(drv, screen); + +		drmModeFreeConnector(screen->connector); +		_eglDestroyScreen(&screen->base); +		drm_drv->screens[i] = NULL; +	} +  	drmClose(drm_drv->device->drmFD);  	free(drm_drv->device); @@ -507,7 +564,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,  	size_t size = mode->Height * pitch;  	int ret; -	/* TODO if allready shown take down */ +	if (scrn->shown) +		drm_takedown_shown_screen(drv, scrn);  	ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0,  		DRM_BO_FLAG_READ | @@ -552,8 +610,11 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,  	scrn->front.width = mode->Width;  	scrn->front.height = mode->Height; +	scrn->surf = surf;  	intel_bind_frontbuffer(surf->drawable, &scrn->front); +	scrn->shown = 1; +  	return EGL_TRUE;  err_fb: | 
