uterm: share drm_mode between dumb and drm backend

The dumb and drm backends use the same mode structure so share the code as
drm_shared module.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann 2013-01-11 17:28:29 +01:00
parent 464fbe7fef
commit b6087af25e
6 changed files with 197 additions and 96 deletions

View File

@ -298,6 +298,18 @@ libuterm_la_LIBADD += \
$(GLES2_LIBS)
endif
# add shared sources only once
UTERM_DRM_SHARED_SRC = \
src/uterm_drm_shared_internal.h \
src/uterm_drm_shared.c
if BUILD_ENABLE_VIDEO_DUMB
libuterm_la_SOURCES += $(UTERM_DRM_SHARED_SRC)
else
if BUILD_ENABLE_VIDEO_DRM
libuterm_la_SOURCES += $(UTERM_DRM_SHARED_SRC)
endif
endif
#
# Shaders
# As there is no need to modify shaders at run-time, we statically compile them

95
src/uterm_drm_shared.c Normal file
View File

@ -0,0 +1,95 @@
/*
* uterm - Linux User-Space Terminal
*
* Copyright (c) 2011-2013 David Herrmann <dh.herrmann@googlemail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* DRM shared functions
*/
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include "log.h"
#include "uterm_drm_shared_internal.h"
#include "uterm_video.h"
#include "uterm_video_internal.h"
#define LOG_SUBSYSTEM "drm_shared"
int uterm_drm_mode_init(struct uterm_mode *mode)
{
struct uterm_drm_mode *m;
m = malloc(sizeof(*m));
if (!m)
return -ENOMEM;
memset(m, 0, sizeof(*m));
mode->data = m;
return 0;
}
void uterm_drm_mode_destroy(struct uterm_mode *mode)
{
free(mode->data);
}
const char *uterm_drm_mode_get_name(const struct uterm_mode *mode)
{
struct uterm_drm_mode *m = mode->data;
return m->info.name;
}
unsigned int uterm_drm_mode_get_width(const struct uterm_mode *mode)
{
struct uterm_drm_mode *m = mode->data;
return m->info.hdisplay;
}
unsigned int uterm_drm_mode_get_height(const struct uterm_mode *mode)
{
struct uterm_drm_mode *m = mode->data;
return m->info.vdisplay;
}
void uterm_drm_mode_set(struct uterm_mode *mode, drmModeModeInfo *info)
{
struct uterm_drm_mode *m = mode->data;
m->info = *info;
}
const struct mode_ops uterm_drm_mode_ops = {
.init = uterm_drm_mode_init,
.destroy = uterm_drm_mode_destroy,
.get_name = uterm_drm_mode_get_name,
.get_width = uterm_drm_mode_get_width,
.get_height = uterm_drm_mode_get_height,
};

View File

@ -0,0 +1,57 @@
/*
* uterm - Linux User-Space Terminal
*
* Copyright (c) 2011-2013 David Herrmann <dh.herrmann@googlemail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* Internal definitions */
#ifndef UTERM_DRM_SHARED_INTERNAL_H
#define UTERM_DRM_SHARED_INTERNAL_H
#include <stdlib.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include "uterm_video.h"
#include "uterm_video_internal.h"
struct uterm_drm_mode {
drmModeModeInfo info;
};
int uterm_drm_mode_init(struct uterm_mode *mode);
void uterm_drm_mode_destroy(struct uterm_mode *mode);
const char *uterm_drm_mode_get_name(const struct uterm_mode *mode);
unsigned int uterm_drm_mode_get_width(const struct uterm_mode *mode);
unsigned int uterm_drm_mode_get_height(const struct uterm_mode *mode);
void uterm_drm_mode_set(struct uterm_mode *mode, drmModeModeInfo *info);
static inline drmModeModeInfo *uterm_drm_mode_get_info(struct uterm_mode *m)
{
struct uterm_drm_mode *mode = m->data;
return &mode->info;
}
extern const struct mode_ops uterm_drm_mode_ops;
#endif /* UTERM_DRM_SHARED_INTERNAL_H */

View File

@ -46,34 +46,12 @@
#include <xf86drmMode.h>
#include "eloop.h"
#include "log.h"
#include "uterm_drm_shared_internal.h"
#include "uterm_video.h"
#include "uterm_video_internal.h"
#define LOG_SUBSYSTEM "video_drm"
static const char *mode_get_name(const struct uterm_mode *mode)
{
return mode->drm.info.name;
}
static unsigned int mode_get_width(const struct uterm_mode *mode)
{
return mode->drm.info.hdisplay;
}
static unsigned int mode_get_height(const struct uterm_mode *mode)
{
return mode->drm.info.vdisplay;
}
static const struct mode_ops drm_mode_ops = {
.init = NULL,
.destroy = NULL,
.get_name = mode_get_name,
.get_width = mode_get_width,
.get_height = mode_get_height,
};
static void bo_destroy_event(struct gbm_bo *bo, void *data)
{
struct drm_rb *rb = data;
@ -154,14 +132,16 @@ static int display_activate(struct uterm_display *disp, struct uterm_mode *mode)
drmModeConnector *conn;
drmModeEncoder *enc;
struct gbm_bo *bo;
drmModeModeInfo *minfo;
if (!video || !video_is_awake(video) || !mode)
return -EINVAL;
if (display_is_online(disp))
return -EINVAL;
minfo = uterm_drm_mode_get_info(mode);
log_info("activating display %p to %ux%u", disp,
mode->drm.info.hdisplay, mode->drm.info.vdisplay);
minfo->hdisplay, minfo->vdisplay);
res = drmModeGetResources(video->drm.fd);
if (!res) {
@ -202,8 +182,7 @@ static int display_activate(struct uterm_display *disp, struct uterm_mode *mode)
disp->drm.crtc_id);
disp->drm.gbm = gbm_surface_create(video->drm.gbm,
mode->drm.info.hdisplay,
mode->drm.info.vdisplay,
minfo->hdisplay, minfo->vdisplay,
GBM_FORMAT_XRGB8888,
GBM_BO_USE_SCANOUT |
GBM_BO_USE_RENDERING);
@ -254,7 +233,7 @@ static int display_activate(struct uterm_display *disp, struct uterm_mode *mode)
ret = drmModeSetCrtc(video->drm.fd, disp->drm.crtc_id,
disp->drm.current->fb, 0, 0, &disp->drm.conn_id, 1,
&disp->current_mode->drm.info);
minfo);
if (ret) {
log_err("cannot set drm-crtc");
ret = -EFAULT;
@ -471,7 +450,7 @@ static int swap_display(struct uterm_display *disp, bool immediate)
if (immediate) {
ret = drmModeSetCrtc(disp->video->drm.fd, disp->drm.crtc_id,
rb->fb, 0, 0, &disp->drm.conn_id, 1,
&disp->current_mode->drm.info);
uterm_drm_mode_get_info(disp->current_mode));
if (ret) {
log_err("cannot set drm-crtc");
gbm_surface_release_buffer(disp->drm.gbm, bo);
@ -619,8 +598,8 @@ static int display_blit(struct uterm_display *disp,
if (ret)
return ret;
sw = disp->current_mode->drm.info.hdisplay;
sh = disp->current_mode->drm.info.vdisplay;
sw = uterm_drm_mode_get_width(disp->current_mode);
sh = uterm_drm_mode_get_height(disp->current_mode);
vertices[0] = -1.0;
vertices[1] = -1.0;
@ -750,8 +729,8 @@ static int display_blend(struct uterm_display *disp,
if (ret)
return ret;
sw = disp->current_mode->drm.info.hdisplay;
sh = disp->current_mode->drm.info.vdisplay;
sw = uterm_drm_mode_get_width(disp->current_mode);
sh = uterm_drm_mode_get_height(disp->current_mode);
vertices[0] = -1.0;
vertices[1] = -1.0;
@ -911,8 +890,8 @@ static int display_fill(struct uterm_display *disp,
if (ret)
return ret;
sw = disp->current_mode->drm.info.hdisplay;
sh = disp->current_mode->drm.info.vdisplay;
sw = uterm_drm_mode_get_width(disp->current_mode);
sh = uterm_drm_mode_get_height(disp->current_mode);
for (i = 0; i < 6; ++i) {
colors[i * 4 + 0] = r / 255.0;
@ -1056,10 +1035,10 @@ static void bind_display(struct uterm_video *video, drmModeRes *res,
return;
for (i = 0; i < conn->count_modes; ++i) {
ret = mode_new(&mode, &drm_mode_ops);
ret = mode_new(&mode, &uterm_drm_mode_ops);
if (ret)
continue;
mode->drm.info = conn->modes[i];
uterm_drm_mode_set(mode, &conn->modes[i]);
mode->next = disp->modes;
disp->modes = mode;

View File

@ -39,34 +39,12 @@
#include <xf86drmMode.h>
#include "eloop.h"
#include "log.h"
#include "uterm_drm_shared_internal.h"
#include "uterm_video.h"
#include "uterm_video_internal.h"
#define LOG_SUBSYSTEM "video_dumb"
static const char *mode_get_name(const struct uterm_mode *mode)
{
return mode->dumb.info.name;
}
static unsigned int mode_get_width(const struct uterm_mode *mode)
{
return mode->dumb.info.hdisplay;
}
static unsigned int mode_get_height(const struct uterm_mode *mode)
{
return mode->dumb.info.vdisplay;
}
static const struct mode_ops dumb_mode_ops = {
.init = NULL,
.destroy = NULL,
.get_name = mode_get_name,
.get_width = mode_get_width,
.get_height = mode_get_height,
};
static int init_rb(struct uterm_display *disp, struct dumb_rb *rb)
{
int ret;
@ -76,8 +54,8 @@ static int init_rb(struct uterm_display *disp, struct dumb_rb *rb)
struct drm_mode_map_dumb mreq;
memset(&req, 0, sizeof(req));
req.width = disp->current_mode->dumb.info.hdisplay;
req.height = disp->current_mode->dumb.info.vdisplay;
req.width = uterm_drm_mode_get_width(disp->current_mode);
req.height = uterm_drm_mode_get_height(disp->current_mode);
req.bpp = 32;
req.flags = 0;
@ -91,10 +69,8 @@ static int init_rb(struct uterm_display *disp, struct dumb_rb *rb)
rb->stride = req.pitch;
rb->size = req.size;
ret = drmModeAddFB(video->dumb.fd,
disp->current_mode->dumb.info.hdisplay,
disp->current_mode->dumb.info.vdisplay,
24, 32, rb->stride, rb->handle, &rb->fb);
ret = drmModeAddFB(video->dumb.fd, req.width, req.height,
24, 32, rb->stride, rb->handle, &rb->fb);
if (ret) {
log_err("cannot add drm-fb");
ret = -EFAULT;
@ -179,14 +155,16 @@ static int display_activate(struct uterm_display *disp, struct uterm_mode *mode)
drmModeRes *res;
drmModeConnector *conn;
drmModeEncoder *enc;
drmModeModeInfo *minfo;
if (!video || !video_is_awake(video) || !mode)
return -EINVAL;
if (display_is_online(disp))
return -EINVAL;
minfo = uterm_drm_mode_get_info(mode);;
log_info("activating display %p to %ux%u", disp,
mode->dumb.info.hdisplay, mode->dumb.info.vdisplay);
minfo->hdisplay, minfo->vdisplay);
res = drmModeGetResources(video->dumb.fd);
if (!res) {
@ -235,7 +213,7 @@ static int display_activate(struct uterm_display *disp, struct uterm_mode *mode)
ret = drmModeSetCrtc(video->dumb.fd, disp->dumb.crtc_id,
disp->dumb.rb[0].fb, 0, 0, &disp->dumb.conn_id, 1,
&disp->current_mode->dumb.info);
minfo);
if (ret) {
log_err("cannot set drm-crtc");
ret = -EFAULT;
@ -394,8 +372,8 @@ static int display_blit(struct uterm_display *disp,
return -EINVAL;
rb = &disp->dumb.rb[disp->dumb.current_rb ^ 1];
sw = disp->current_mode->dumb.info.hdisplay;
sh = disp->current_mode->dumb.info.vdisplay;
sw = uterm_drm_mode_get_width(disp->current_mode);
sh = uterm_drm_mode_get_height(disp->current_mode);
tmp = x + buf->width;
if (tmp < x || x >= sw)
@ -443,8 +421,8 @@ static int display_fake_blendv(struct uterm_display *disp,
return -EINVAL;
rb = &disp->dumb.rb[disp->dumb.current_rb ^ 1];
sw = disp->current_mode->dumb.info.hdisplay;
sh = disp->current_mode->dumb.info.vdisplay;
sw = uterm_drm_mode_get_width(disp->current_mode);
sh = uterm_drm_mode_get_height(disp->current_mode);
for (j = 0; j < num; ++j, ++req) {
if (!req->buf)
@ -524,8 +502,8 @@ static int display_fill(struct uterm_display *disp,
return -EINVAL;
rb = &disp->dumb.rb[disp->dumb.current_rb ^ 1];
sw = disp->current_mode->dumb.info.hdisplay;
sh = disp->current_mode->dumb.info.vdisplay;
sw = uterm_drm_mode_get_width(disp->current_mode);
sh = uterm_drm_mode_get_height(disp->current_mode);
tmp = x + width;
if (tmp < x || x >= sw)
@ -582,7 +560,7 @@ static void show_displays(struct uterm_video *video)
memset(rb->map, 0, rb->size);
ret = drmModeSetCrtc(video->dumb.fd, iter->dumb.crtc_id,
rb->fb, 0, 0, &iter->dumb.conn_id, 1,
&iter->current_mode->dumb.info);
uterm_drm_mode_get_info(iter->current_mode));
if (ret) {
log_err("cannot set drm-crtc on display %p", iter);
continue;
@ -641,10 +619,10 @@ static void bind_display(struct uterm_video *video, drmModeRes *res,
return;
for (i = 0; i < conn->count_modes; ++i) {
ret = mode_new(&mode, &dumb_mode_ops);
ret = mode_new(&mode, &uterm_drm_mode_ops);
if (ret)
continue;
mode->dumb.info = conn->modes[i];
uterm_drm_mode_set(mode, &conn->modes[i]);
mode->next = disp->modes;
disp->modes = mode;

View File

@ -94,10 +94,6 @@ struct uterm_video_module {
#include <xf86drmMode.h>
#include "static_gl.h"
struct drm_mode {
drmModeModeInfo info;
};
struct drm_rb {
struct uterm_display *disp;
struct gbm_bo *bo;
@ -144,10 +140,6 @@ struct drm_video {
#else /* !BUILD_ENABLE_VIDEO_DRM */
struct drm_mode {
int unused;
};
struct drm_display {
int unused;
};
@ -165,10 +157,6 @@ struct drm_video {
#include <xf86drm.h>
#include <xf86drmMode.h>
struct dumb_mode {
drmModeModeInfo info;
};
struct dumb_rb {
uint32_t fb;
uint32_t handle;
@ -194,10 +182,6 @@ struct dumb_video {
#else /* !BUILD_ENABLE_VIDEO_DUMB */
struct dumb_mode {
int unused;
};
struct dumb_display {
int unused;
};
@ -216,10 +200,6 @@ struct uterm_mode {
const struct mode_ops *ops;
void *data;
union {
struct drm_mode drm;
struct dumb_mode dumb;
};
};
int mode_new(struct uterm_mode **out, const struct mode_ops *ops);