uterm: drm: rename to drm3d
This renames the video-drm backend to drm3d (which was already used internally). This is a pure rename, the code-logic stays the same. This also puts the drm3d backend into a module so we can more easily load it during runtime. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
parent
f289349ef9
commit
0f206cc5b5
@ -282,9 +282,11 @@ libuterm_la_CPPFLAGS += $(DRM_CFLAGS)
|
||||
libuterm_la_LIBADD += $(DRM_LIBS)
|
||||
endif
|
||||
|
||||
if BUILD_ENABLE_VIDEO_DRM
|
||||
if BUILD_ENABLE_VIDEO_DRM3D
|
||||
libuterm_la_SOURCES += \
|
||||
src/uterm_video_drm.c \
|
||||
src/uterm_drm3d_internal.h \
|
||||
src/uterm_drm3d_video.c \
|
||||
src/uterm_drm3d_render.c \
|
||||
src/static_gl.h \
|
||||
src/static_gl_math.c \
|
||||
src/static_gl_shader.c
|
||||
@ -309,7 +311,7 @@ UTERM_DRM_SHARED_SRC = \
|
||||
if BUILD_ENABLE_VIDEO_DRM2D
|
||||
libuterm_la_SOURCES += $(UTERM_DRM_SHARED_SRC)
|
||||
else
|
||||
if BUILD_ENABLE_VIDEO_DRM
|
||||
if BUILD_ENABLE_VIDEO_DRM3D
|
||||
libuterm_la_SOURCES += $(UTERM_DRM_SHARED_SRC)
|
||||
endif
|
||||
endif
|
||||
|
76
configure.ac
76
configure.ac
@ -228,12 +228,12 @@ AC_ARG_WITH([video],
|
||||
[specify list of optional video backends])])
|
||||
enable_video_fbdev="no"
|
||||
enable_video_drm2d="no"
|
||||
enable_video_drm="no"
|
||||
enable_video_drm3d="no"
|
||||
if test "x$with_video" = "x" ; then
|
||||
enable_video_fbdev="yes (default)"
|
||||
enable_video_drm2d="yes (default)"
|
||||
enable_video_drm="yes (default)"
|
||||
with_video="fbdev,drm2d,drm (default)"
|
||||
enable_video_drm3d="yes (default)"
|
||||
with_video="fbdev,drm2d,drm3d (default)"
|
||||
else
|
||||
SAVEIFS="$IFS"
|
||||
IFS=","
|
||||
@ -242,8 +242,8 @@ else
|
||||
enable_video_fbdev="yes"
|
||||
elif test "x$i" = "xdrm2d" ; then
|
||||
enable_video_drm2d="yes"
|
||||
elif test "x$i" = "xdrm" ; then
|
||||
enable_video_drm="yes"
|
||||
elif test "x$i" = "xdrm3d" ; then
|
||||
enable_video_drm3d="yes"
|
||||
else
|
||||
IFS="$SAVEIFS"
|
||||
AC_ERROR([Invalid video backend $i])
|
||||
@ -439,9 +439,9 @@ video_drm2d_avail=no
|
||||
video_drm2d_missing=""
|
||||
if test ! "x$enable_video_drm2d" = "xno" ; then
|
||||
video_drm2d_avail=yes
|
||||
if test "x$have_drm" = "xno" ; then
|
||||
if test "x$have_drm3d" = "xno" ; then
|
||||
video_drm2d_avail=no
|
||||
video_drm2d_missing="libdrm"
|
||||
video_drm2d_missing="libdrm3d"
|
||||
fi
|
||||
|
||||
if test "x$video_drm2d_avail" = "xno" ; then
|
||||
@ -453,35 +453,35 @@ else
|
||||
video_drm2d_missing="enable-video-drm2d"
|
||||
fi
|
||||
|
||||
# video drm
|
||||
video_drm_avail=no
|
||||
video_drm_missing=""
|
||||
if test ! "x$enable_video_drm" = "xno" ; then
|
||||
video_drm_avail=yes
|
||||
if test "x$have_drm" = "xno" ; then
|
||||
video_drm_avail=no
|
||||
video_drm_missing="libdrm,$video_drm_missing"
|
||||
# video drm3d
|
||||
video_drm3d_avail=no
|
||||
video_drm3d_missing=""
|
||||
if test ! "x$enable_video_drm3d" = "xno" ; then
|
||||
video_drm3d_avail=yes
|
||||
if test "x$have_drm3d" = "xno" ; then
|
||||
video_drm3d_avail=no
|
||||
video_drm3d_missing="libdrm3d,$video_drm3d_missing"
|
||||
fi
|
||||
if test "x$have_gbm" = "xno" ; then
|
||||
video_drm_avail=no
|
||||
video_drm_missing="libgbm,$video_drm_missing"
|
||||
video_drm3d_avail=no
|
||||
video_drm3d_missing="libgbm,$video_drm3d_missing"
|
||||
fi
|
||||
if test "x$have_egl" = "xno" ; then
|
||||
video_drm_avail=no
|
||||
video_drm_missing="libegl,$video_drm_missing"
|
||||
video_drm3d_avail=no
|
||||
video_drm3d_missing="libegl,$video_drm3d_missing"
|
||||
fi
|
||||
if test "x$have_gles2" = "xno" ; then
|
||||
video_drm_avail=no
|
||||
video_drm_missing="libgles2,$video_drm_missing"
|
||||
video_drm3d_avail=no
|
||||
video_drm3d_missing="libgles2,$video_drm3d_missing"
|
||||
fi
|
||||
|
||||
if test "x$video_drm_avail" = "xno" ; then
|
||||
if test "x$enable_video_drm" = "xyes" ; then
|
||||
AC_ERROR([missing for drm video backend: $video_drm_missing])
|
||||
if test "x$video_drm3d_avail" = "xno" ; then
|
||||
if test "x$enable_video_drm3d" = "xyes" ; then
|
||||
AC_ERROR([missing for drm3d video backend: $video_drm3d_missing])
|
||||
fi
|
||||
fi
|
||||
else
|
||||
video_drm_missing="enable-video-drm"
|
||||
video_drm3d_missing="enable-video-drm3d"
|
||||
fi
|
||||
|
||||
# uterm
|
||||
@ -887,11 +887,11 @@ if test "x$uterm_avail" = "xyes" ; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# video drm
|
||||
video_drm_enabled=no
|
||||
if test "x$video_drm_avail" = "xyes" ; then
|
||||
if test "x${enable_video_drm% *}" = "xyes" ; then
|
||||
video_drm_enabled=yes
|
||||
# video drm3d
|
||||
video_drm3d_enabled=no
|
||||
if test "x$video_drm3d_avail" = "xyes" ; then
|
||||
if test "x${enable_video_drm3d% *}" = "xyes" ; then
|
||||
video_drm3d_enabled=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -997,20 +997,20 @@ AM_CONDITIONAL([BUILD_ENABLE_VIDEO_FBDEV],
|
||||
# video drm2d
|
||||
if test "x$video_drm2d_enabled" = "xyes" ; then
|
||||
AC_DEFINE([BUILD_ENABLE_VIDEO_DRM2D], [1],
|
||||
[Build uterm drm2d drm video backend])
|
||||
[Build uterm drm2d drm3d video backend])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([BUILD_ENABLE_VIDEO_DRM2D],
|
||||
[test "x$video_drm2d_enabled" = "xyes"])
|
||||
|
||||
# video drm
|
||||
if test "x$video_drm_enabled" = "xyes" ; then
|
||||
AC_DEFINE([BUILD_ENABLE_VIDEO_DRM], [1],
|
||||
[Build uterm drm video backend])
|
||||
# video drm3d
|
||||
if test "x$video_drm3d_enabled" = "xyes" ; then
|
||||
AC_DEFINE([BUILD_ENABLE_VIDEO_DRM3D], [1],
|
||||
[Build uterm drm3d video backend])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([BUILD_ENABLE_VIDEO_DRM],
|
||||
[test "x$video_drm_enabled" = "xyes"])
|
||||
AM_CONDITIONAL([BUILD_ENABLE_VIDEO_DRM3D],
|
||||
[test "x$video_drm3d_enabled" = "xyes"])
|
||||
|
||||
# uterm
|
||||
AM_CONDITIONAL([BUILD_ENABLE_UTERM],
|
||||
@ -1229,7 +1229,7 @@ AC_MSG_NOTICE([Build configuration:
|
||||
Video Backends:
|
||||
fbdev: $video_fbdev_enabled ($video_fbdev_avail: $video_fbdev_missing)
|
||||
drm2d: $video_drm2d_enabled ($video_drm2d_avail: $video_drm2d_missing)
|
||||
drm: $video_drm_enabled ($video_drm_avail: $video_drm_missing)
|
||||
drm3d: $video_drm3d_enabled ($video_drm3d_avail: $video_drm3d_missing)
|
||||
|
||||
Font Backends:
|
||||
unifont: $font_unifont_enabled ($font_unifont_avail: $font_unifont_missing)
|
||||
|
@ -447,7 +447,7 @@ static int aftercheck_drm(struct conf_option *opt, int argc, char **argv,
|
||||
* enabled but will still correctly use fbdev devices so we can then
|
||||
* remove this check. */
|
||||
if (conf->drm) {
|
||||
if (!uterm_video_available(UTERM_VIDEO_DRM) &&
|
||||
if (!uterm_video_available(UTERM_VIDEO_DRM3D) &&
|
||||
!uterm_video_available(UTERM_VIDEO_DRM2D)) {
|
||||
log_info("no DRM runtime support available; disabling --drm");
|
||||
conf->drm = false;
|
||||
|
@ -355,7 +355,7 @@ static int app_seat_add_video(struct app_seat *seat,
|
||||
|
||||
if (type == UTERM_MONITOR_DRM) {
|
||||
if (seat->conf->hwaccel)
|
||||
mode = UTERM_VIDEO_DRM;
|
||||
mode = UTERM_VIDEO_DRM3D;
|
||||
else
|
||||
mode = UTERM_VIDEO_DRM2D;
|
||||
} else {
|
||||
@ -364,8 +364,8 @@ static int app_seat_add_video(struct app_seat *seat,
|
||||
|
||||
ret = uterm_video_new(&vid->video, seat->app->eloop, node, mode);
|
||||
if (ret) {
|
||||
if (mode == UTERM_VIDEO_DRM) {
|
||||
log_info("cannot create drm device %s on seat %s (%d); trying drm2d mode",
|
||||
if (mode == UTERM_VIDEO_DRM3D) {
|
||||
log_info("cannot create drm3d device %s on seat %s (%d); trying drm2d mode",
|
||||
vid->node, seat->name, ret);
|
||||
ret = uterm_video_new(&vid->video, seat->app->eloop,
|
||||
node, UTERM_VIDEO_DRM2D);
|
||||
|
100
src/uterm_drm3d_internal.h
Normal file
100
src/uterm_drm3d_internal.h
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* uterm - Linux User-Space Terminal drm3d module
|
||||
*
|
||||
* 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_DRM3D_INTERNAL_H
|
||||
#define UTERM_DRM3D_INTERNAL_H
|
||||
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <gbm.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include "uterm_video.h"
|
||||
|
||||
struct uterm_drm3d_rb {
|
||||
struct uterm_display *disp;
|
||||
struct gbm_bo *bo;
|
||||
uint32_t fb;
|
||||
};
|
||||
|
||||
struct uterm_drm3d_display {
|
||||
struct gbm_surface *gbm;
|
||||
EGLSurface surface;
|
||||
struct uterm_drm3d_rb *current;
|
||||
struct uterm_drm3d_rb *next;
|
||||
};
|
||||
|
||||
struct uterm_drm3d_video {
|
||||
struct gbm_device *gbm;
|
||||
EGLDisplay disp;
|
||||
EGLConfig conf;
|
||||
EGLContext ctx;
|
||||
|
||||
unsigned int sinit;
|
||||
bool supports_rowlen;
|
||||
GLuint tex;
|
||||
|
||||
struct gl_shader *fill_shader;
|
||||
GLuint uni_fill_proj;
|
||||
|
||||
struct gl_shader *blend_shader;
|
||||
GLuint uni_blend_proj;
|
||||
GLuint uni_blend_tex;
|
||||
GLuint uni_blend_fgcol;
|
||||
GLuint uni_blend_bgcol;
|
||||
|
||||
struct gl_shader *blit_shader;
|
||||
GLuint uni_blit_proj;
|
||||
GLuint uni_blit_tex;
|
||||
};
|
||||
|
||||
int uterm_drm3d_display_use(struct uterm_display *disp, bool *opengl);
|
||||
void uterm_drm3d_deinit_shaders(struct uterm_video *video);
|
||||
int uterm_drm3d_display_blit(struct uterm_display *disp,
|
||||
const struct uterm_video_buffer *buf,
|
||||
unsigned int x, unsigned int y);
|
||||
int uterm_drm3d_display_fake_blendv(struct uterm_display *disp,
|
||||
const struct uterm_video_blend_req *req,
|
||||
size_t num);
|
||||
int uterm_drm3d_display_fill(struct uterm_display *disp,
|
||||
uint8_t r, uint8_t g, uint8_t b,
|
||||
unsigned int x, unsigned int y,
|
||||
unsigned int width, unsigned int height);
|
||||
|
||||
#endif /* UTERM_DRM3D_INTERNAL_H */
|
495
src/uterm_drm3d_render.c
Normal file
495
src/uterm_drm3d_render.c
Normal file
@ -0,0 +1,495 @@
|
||||
/*
|
||||
* 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 Video backend
|
||||
*/
|
||||
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <gbm.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include "eloop.h"
|
||||
#include "log.h"
|
||||
#include "static_gl.h"
|
||||
#include "uterm_drm_shared_internal.h"
|
||||
#include "uterm_drm3d_internal.h"
|
||||
#include "uterm_video.h"
|
||||
#include "uterm_video_internal.h"
|
||||
|
||||
#define LOG_SUBSYSTEM "uterm_drm3d_render"
|
||||
|
||||
extern const char *gl_static_fill_vert;
|
||||
extern const char *gl_static_fill_frag;
|
||||
extern const char *gl_static_blend_vert;
|
||||
extern const char *gl_static_blend_frag;
|
||||
extern const char *gl_static_blit_vert;
|
||||
extern const char *gl_static_blit_frag;
|
||||
|
||||
static int init_shaders(struct uterm_video *video)
|
||||
{
|
||||
struct uterm_drm3d_video *v3d = uterm_drm_video_get_data(video);
|
||||
int ret;
|
||||
char *fill_attr[] = { "position", "color" };
|
||||
char *blend_attr[] = { "position", "texture_position" };
|
||||
char *blit_attr[] = { "position", "texture_position" };
|
||||
|
||||
if (v3d->sinit == 1)
|
||||
return -EFAULT;
|
||||
else if (v3d->sinit == 2)
|
||||
return 0;
|
||||
|
||||
v3d->sinit = 1;
|
||||
|
||||
ret = gl_shader_new(&v3d->fill_shader, gl_static_fill_vert,
|
||||
gl_static_fill_frag, fill_attr, 2, log_llog);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
v3d->uni_fill_proj = gl_shader_get_uniform(v3d->fill_shader,
|
||||
"projection");
|
||||
|
||||
ret = gl_shader_new(&v3d->blend_shader, gl_static_blend_vert,
|
||||
gl_static_blend_frag, blend_attr, 2, log_llog);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
v3d->uni_blend_proj = gl_shader_get_uniform(v3d->blend_shader,
|
||||
"projection");
|
||||
v3d->uni_blend_tex = gl_shader_get_uniform(v3d->blend_shader,
|
||||
"texture");
|
||||
v3d->uni_blend_fgcol = gl_shader_get_uniform(v3d->blend_shader,
|
||||
"fgcolor");
|
||||
v3d->uni_blend_bgcol = gl_shader_get_uniform(v3d->blend_shader,
|
||||
"bgcolor");
|
||||
|
||||
ret = gl_shader_new(&v3d->blit_shader, gl_static_blit_vert,
|
||||
gl_static_blit_frag, blit_attr, 2, log_llog);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
v3d->uni_blit_proj = gl_shader_get_uniform(v3d->blit_shader,
|
||||
"projection");
|
||||
v3d->uni_blit_tex = gl_shader_get_uniform(v3d->blit_shader,
|
||||
"texture");
|
||||
|
||||
gl_tex_new(&v3d->tex, 1);
|
||||
v3d->sinit = 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uterm_drm3d_deinit_shaders(struct uterm_video *video)
|
||||
{
|
||||
struct uterm_drm3d_video *v3d = uterm_drm_video_get_data(video);
|
||||
|
||||
if (v3d->sinit == 0)
|
||||
return;
|
||||
|
||||
v3d->sinit = 0;
|
||||
gl_tex_free(&v3d->tex, 1);
|
||||
gl_shader_unref(v3d->blit_shader);
|
||||
gl_shader_unref(v3d->blend_shader);
|
||||
gl_shader_unref(v3d->fill_shader);
|
||||
}
|
||||
|
||||
int uterm_drm3d_display_blit(struct uterm_display *disp,
|
||||
const struct uterm_video_buffer *buf,
|
||||
unsigned int x, unsigned int y)
|
||||
{
|
||||
struct uterm_drm3d_video *v3d;
|
||||
unsigned int sw, sh, tmp, width, height, i;
|
||||
float mat[16];
|
||||
float vertices[6 * 2], texpos[6 * 2];
|
||||
int ret;
|
||||
uint8_t *packed, *src, *dst;
|
||||
|
||||
if (!buf || buf->format != UTERM_FORMAT_XRGB32)
|
||||
return -EINVAL;
|
||||
|
||||
v3d = uterm_drm_video_get_data(disp->video);
|
||||
ret = uterm_drm3d_display_use(disp, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = init_shaders(disp->video);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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;
|
||||
vertices[2] = -1.0;
|
||||
vertices[3] = +1.0;
|
||||
vertices[4] = +1.0;
|
||||
vertices[5] = +1.0;
|
||||
|
||||
vertices[6] = -1.0;
|
||||
vertices[7] = -1.0;
|
||||
vertices[8] = +1.0;
|
||||
vertices[9] = +1.0;
|
||||
vertices[10] = +1.0;
|
||||
vertices[11] = -1.0;
|
||||
|
||||
texpos[0] = 0.0;
|
||||
texpos[1] = 1.0;
|
||||
texpos[2] = 0.0;
|
||||
texpos[3] = 0.0;
|
||||
texpos[4] = 1.0;
|
||||
texpos[5] = 0.0;
|
||||
|
||||
texpos[6] = 0.0;
|
||||
texpos[7] = 1.0;
|
||||
texpos[8] = 1.0;
|
||||
texpos[9] = 0.0;
|
||||
texpos[10] = 1.0;
|
||||
texpos[11] = 1.0;
|
||||
|
||||
tmp = x + buf->width;
|
||||
if (tmp < x || x >= sw)
|
||||
return -EINVAL;
|
||||
if (tmp > sw)
|
||||
width = sw - x;
|
||||
else
|
||||
width = buf->width;
|
||||
|
||||
tmp = y + buf->height;
|
||||
if (tmp < y || y >= sh)
|
||||
return -EINVAL;
|
||||
if (tmp > sh)
|
||||
height = sh - y;
|
||||
else
|
||||
height = buf->height;
|
||||
|
||||
glViewport(x, sh - y - height, width, height);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
gl_shader_use(v3d->blit_shader);
|
||||
|
||||
gl_m4_identity(mat);
|
||||
glUniformMatrix4fv(v3d->uni_blit_proj, 1, GL_FALSE, mat);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, v3d->tex);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
if (v3d->supports_rowlen) {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, buf->stride / 4);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, width, height, 0,
|
||||
GL_BGRA_EXT, GL_UNSIGNED_BYTE, buf->data);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
} else if (buf->stride == width) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, width, height, 0,
|
||||
GL_BGRA_EXT, GL_UNSIGNED_BYTE, buf->data);
|
||||
} else {
|
||||
packed = malloc(width * height);
|
||||
if (!packed)
|
||||
return -ENOMEM;
|
||||
|
||||
src = buf->data;
|
||||
dst = packed;
|
||||
for (i = 0; i < height; ++i) {
|
||||
memcpy(dst, src, width * 4);
|
||||
dst += width * 4;
|
||||
src += buf->stride;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, width, height, 0,
|
||||
GL_BGRA_EXT, GL_UNSIGNED_BYTE, packed);
|
||||
|
||||
free(packed);
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glUniform1i(v3d->uni_blit_tex, 0);
|
||||
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, texpos);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
|
||||
if (gl_has_error(v3d->blit_shader)) {
|
||||
log_warning("GL error");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int display_blend(struct uterm_display *disp,
|
||||
const struct uterm_video_buffer *buf,
|
||||
unsigned int x, unsigned int y,
|
||||
uint8_t fr, uint8_t fg, uint8_t fb,
|
||||
uint8_t br, uint8_t bg, uint8_t bb)
|
||||
{
|
||||
struct uterm_drm3d_video *v3d;
|
||||
unsigned int sw, sh, tmp, width, height, i;
|
||||
float mat[16];
|
||||
float vertices[6 * 2], texpos[6 * 2], fgcol[3], bgcol[3];
|
||||
int ret;
|
||||
uint8_t *packed, *src, *dst;
|
||||
|
||||
if (!buf || buf->format != UTERM_FORMAT_GREY)
|
||||
return -EINVAL;
|
||||
|
||||
v3d = uterm_drm_video_get_data(disp->video);
|
||||
ret = uterm_drm3d_display_use(disp, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = init_shaders(disp->video);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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;
|
||||
vertices[2] = -1.0;
|
||||
vertices[3] = +1.0;
|
||||
vertices[4] = +1.0;
|
||||
vertices[5] = +1.0;
|
||||
|
||||
vertices[6] = -1.0;
|
||||
vertices[7] = -1.0;
|
||||
vertices[8] = +1.0;
|
||||
vertices[9] = +1.0;
|
||||
vertices[10] = +1.0;
|
||||
vertices[11] = -1.0;
|
||||
|
||||
texpos[0] = 0.0;
|
||||
texpos[1] = 1.0;
|
||||
texpos[2] = 0.0;
|
||||
texpos[3] = 0.0;
|
||||
texpos[4] = 1.0;
|
||||
texpos[5] = 0.0;
|
||||
|
||||
texpos[6] = 0.0;
|
||||
texpos[7] = 1.0;
|
||||
texpos[8] = 1.0;
|
||||
texpos[9] = 0.0;
|
||||
texpos[10] = 1.0;
|
||||
texpos[11] = 1.0;
|
||||
|
||||
fgcol[0] = fr / 255.0;
|
||||
fgcol[1] = fg / 255.0;
|
||||
fgcol[2] = fb / 255.0;
|
||||
bgcol[0] = br / 255.0;
|
||||
bgcol[1] = bg / 255.0;
|
||||
bgcol[2] = bb / 255.0;
|
||||
|
||||
tmp = x + buf->width;
|
||||
if (tmp < x || x >= sw)
|
||||
return -EINVAL;
|
||||
if (tmp > sw)
|
||||
width = sw - x;
|
||||
else
|
||||
width = buf->width;
|
||||
|
||||
tmp = y + buf->height;
|
||||
if (tmp < y || y >= sh)
|
||||
return -EINVAL;
|
||||
if (tmp > sh)
|
||||
height = sh - y;
|
||||
else
|
||||
height = buf->height;
|
||||
|
||||
glViewport(x, sh - y - height, width, height);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
gl_shader_use(v3d->blend_shader);
|
||||
|
||||
gl_m4_identity(mat);
|
||||
glUniformMatrix4fv(v3d->uni_blend_proj, 1, GL_FALSE, mat);
|
||||
|
||||
glUniform3fv(v3d->uni_blend_fgcol, 1, fgcol);
|
||||
glUniform3fv(v3d->uni_blend_bgcol, 1, bgcol);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, v3d->tex);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
if (v3d->supports_rowlen) {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, buf->stride);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE, buf->data);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
} else if (buf->stride == width) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE, buf->data);
|
||||
} else {
|
||||
packed = malloc(width * height);
|
||||
if (!packed)
|
||||
return -ENOMEM;
|
||||
|
||||
src = buf->data;
|
||||
dst = packed;
|
||||
for (i = 0; i < height; ++i) {
|
||||
memcpy(dst, src, width);
|
||||
dst += width;
|
||||
src += buf->stride;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE, packed);
|
||||
|
||||
free(packed);
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glUniform1i(v3d->uni_blend_tex, 0);
|
||||
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, texpos);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
|
||||
if (gl_has_error(v3d->blend_shader)) {
|
||||
log_warning("GL error");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uterm_drm3d_display_fake_blendv(struct uterm_display *disp,
|
||||
const struct uterm_video_blend_req *req,
|
||||
size_t num)
|
||||
{
|
||||
int ret;
|
||||
unsigned int i;
|
||||
|
||||
if (!disp || !req)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < num; ++i, ++req) {
|
||||
if (!req->buf)
|
||||
continue;
|
||||
|
||||
ret = display_blend(disp, req->buf, req->x, req->y,
|
||||
req->fr, req->fg, req->fb,
|
||||
req->br, req->bg, req->bb);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uterm_drm3d_display_fill(struct uterm_display *disp,
|
||||
uint8_t r, uint8_t g, uint8_t b,
|
||||
unsigned int x, unsigned int y,
|
||||
unsigned int width, unsigned int height)
|
||||
{
|
||||
struct uterm_drm3d_video *v3d;
|
||||
unsigned int sw, sh, tmp, i;
|
||||
float mat[16];
|
||||
float vertices[6 * 2], colors[6 * 4];
|
||||
int ret;
|
||||
|
||||
v3d = uterm_drm_video_get_data(disp->video);
|
||||
ret = uterm_drm3d_display_use(disp, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = init_shaders(disp->video);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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;
|
||||
colors[i * 4 + 1] = g / 255.0;
|
||||
colors[i * 4 + 2] = b / 255.0;
|
||||
colors[i * 4 + 3] = 1.0;
|
||||
}
|
||||
|
||||
vertices[0] = -1.0;
|
||||
vertices[1] = -1.0;
|
||||
vertices[2] = -1.0;
|
||||
vertices[3] = +1.0;
|
||||
vertices[4] = +1.0;
|
||||
vertices[5] = +1.0;
|
||||
|
||||
vertices[6] = -1.0;
|
||||
vertices[7] = -1.0;
|
||||
vertices[8] = +1.0;
|
||||
vertices[9] = +1.0;
|
||||
vertices[10] = +1.0;
|
||||
vertices[11] = -1.0;
|
||||
|
||||
tmp = x + width;
|
||||
if (tmp < x || x >= sw)
|
||||
return -EINVAL;
|
||||
if (tmp > sw)
|
||||
width = sw - x;
|
||||
tmp = y + height;
|
||||
if (tmp < y || y >= sh)
|
||||
return -EINVAL;
|
||||
if (tmp > sh)
|
||||
height = sh - y;
|
||||
|
||||
glViewport(x, y, width, height);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
gl_shader_use(v3d->fill_shader);
|
||||
gl_m4_identity(mat);
|
||||
glUniformMatrix4fv(v3d->uni_fill_proj, 1, GL_FALSE, mat);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
||||
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, colors);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
|
||||
if (gl_has_error(v3d->fill_shader)) {
|
||||
log_warning("GL error");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -48,47 +48,11 @@
|
||||
#include "log.h"
|
||||
#include "static_gl.h"
|
||||
#include "uterm_drm_shared_internal.h"
|
||||
#include "uterm_drm3d_internal.h"
|
||||
#include "uterm_video.h"
|
||||
#include "uterm_video_internal.h"
|
||||
|
||||
#define LOG_SUBSYSTEM "video_drm"
|
||||
|
||||
struct uterm_drm3d_rb {
|
||||
struct uterm_display *disp;
|
||||
struct gbm_bo *bo;
|
||||
uint32_t fb;
|
||||
};
|
||||
|
||||
struct uterm_drm3d_display {
|
||||
struct gbm_surface *gbm;
|
||||
EGLSurface surface;
|
||||
struct uterm_drm3d_rb *current;
|
||||
struct uterm_drm3d_rb *next;
|
||||
};
|
||||
|
||||
struct uterm_drm3d_video {
|
||||
struct gbm_device *gbm;
|
||||
EGLDisplay disp;
|
||||
EGLConfig conf;
|
||||
EGLContext ctx;
|
||||
|
||||
unsigned int sinit;
|
||||
bool supports_rowlen;
|
||||
GLuint tex;
|
||||
|
||||
struct gl_shader *fill_shader;
|
||||
GLuint uni_fill_proj;
|
||||
|
||||
struct gl_shader *blend_shader;
|
||||
GLuint uni_blend_proj;
|
||||
GLuint uni_blend_tex;
|
||||
GLuint uni_blend_fgcol;
|
||||
GLuint uni_blend_bgcol;
|
||||
|
||||
struct gl_shader *blit_shader;
|
||||
GLuint uni_blit_proj;
|
||||
GLuint uni_blit_tex;
|
||||
};
|
||||
#define LOG_SUBSYSTEM "uterm_drm3d_video"
|
||||
|
||||
static int display_init(struct uterm_display *disp)
|
||||
{
|
||||
@ -305,7 +269,7 @@ static void display_deactivate(struct uterm_display *disp)
|
||||
disp->current_mode = NULL;
|
||||
}
|
||||
|
||||
static int display_use(struct uterm_display *disp, bool *opengl)
|
||||
int uterm_drm3d_display_use(struct uterm_display *disp, bool *opengl)
|
||||
{
|
||||
struct uterm_drm3d_display *d3d = uterm_drm_display_get_data(disp);
|
||||
struct uterm_drm3d_video *v3d;
|
||||
@ -376,458 +340,18 @@ static int display_swap(struct uterm_display *disp, bool immediate)
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern const char *gl_static_fill_vert;
|
||||
extern const char *gl_static_fill_frag;
|
||||
extern const char *gl_static_blend_vert;
|
||||
extern const char *gl_static_blend_frag;
|
||||
extern const char *gl_static_blit_vert;
|
||||
extern const char *gl_static_blit_frag;
|
||||
|
||||
static int init_shaders(struct uterm_video *video)
|
||||
{
|
||||
struct uterm_drm3d_video *v3d = uterm_drm_video_get_data(video);
|
||||
int ret;
|
||||
char *fill_attr[] = { "position", "color" };
|
||||
char *blend_attr[] = { "position", "texture_position" };
|
||||
char *blit_attr[] = { "position", "texture_position" };
|
||||
|
||||
if (v3d->sinit == 1)
|
||||
return -EFAULT;
|
||||
else if (v3d->sinit == 2)
|
||||
return 0;
|
||||
|
||||
v3d->sinit = 1;
|
||||
|
||||
ret = gl_shader_new(&v3d->fill_shader, gl_static_fill_vert,
|
||||
gl_static_fill_frag, fill_attr, 2, log_llog);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
v3d->uni_fill_proj = gl_shader_get_uniform(v3d->fill_shader,
|
||||
"projection");
|
||||
|
||||
ret = gl_shader_new(&v3d->blend_shader, gl_static_blend_vert,
|
||||
gl_static_blend_frag, blend_attr, 2, log_llog);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
v3d->uni_blend_proj = gl_shader_get_uniform(v3d->blend_shader,
|
||||
"projection");
|
||||
v3d->uni_blend_tex = gl_shader_get_uniform(v3d->blend_shader,
|
||||
"texture");
|
||||
v3d->uni_blend_fgcol = gl_shader_get_uniform(v3d->blend_shader,
|
||||
"fgcolor");
|
||||
v3d->uni_blend_bgcol = gl_shader_get_uniform(v3d->blend_shader,
|
||||
"bgcolor");
|
||||
|
||||
ret = gl_shader_new(&v3d->blit_shader, gl_static_blit_vert,
|
||||
gl_static_blit_frag, blit_attr, 2, log_llog);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
v3d->uni_blit_proj = gl_shader_get_uniform(v3d->blit_shader,
|
||||
"projection");
|
||||
v3d->uni_blit_tex = gl_shader_get_uniform(v3d->blit_shader,
|
||||
"texture");
|
||||
|
||||
gl_tex_new(&v3d->tex, 1);
|
||||
v3d->sinit = 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void deinit_shaders(struct uterm_video *video)
|
||||
{
|
||||
struct uterm_drm3d_video *v3d = uterm_drm_video_get_data(video);
|
||||
|
||||
if (v3d->sinit == 0)
|
||||
return;
|
||||
|
||||
v3d->sinit = 0;
|
||||
gl_tex_free(&v3d->tex, 1);
|
||||
gl_shader_unref(v3d->blit_shader);
|
||||
gl_shader_unref(v3d->blend_shader);
|
||||
gl_shader_unref(v3d->fill_shader);
|
||||
}
|
||||
|
||||
static int display_blit(struct uterm_display *disp,
|
||||
const struct uterm_video_buffer *buf,
|
||||
unsigned int x, unsigned int y)
|
||||
{
|
||||
struct uterm_drm3d_video *v3d;
|
||||
unsigned int sw, sh, tmp, width, height, i;
|
||||
float mat[16];
|
||||
float vertices[6 * 2], texpos[6 * 2];
|
||||
int ret;
|
||||
uint8_t *packed, *src, *dst;
|
||||
|
||||
if (!buf || buf->format != UTERM_FORMAT_XRGB32)
|
||||
return -EINVAL;
|
||||
|
||||
v3d = uterm_drm_video_get_data(disp->video);
|
||||
ret = display_use(disp, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = init_shaders(disp->video);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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;
|
||||
vertices[2] = -1.0;
|
||||
vertices[3] = +1.0;
|
||||
vertices[4] = +1.0;
|
||||
vertices[5] = +1.0;
|
||||
|
||||
vertices[6] = -1.0;
|
||||
vertices[7] = -1.0;
|
||||
vertices[8] = +1.0;
|
||||
vertices[9] = +1.0;
|
||||
vertices[10] = +1.0;
|
||||
vertices[11] = -1.0;
|
||||
|
||||
texpos[0] = 0.0;
|
||||
texpos[1] = 1.0;
|
||||
texpos[2] = 0.0;
|
||||
texpos[3] = 0.0;
|
||||
texpos[4] = 1.0;
|
||||
texpos[5] = 0.0;
|
||||
|
||||
texpos[6] = 0.0;
|
||||
texpos[7] = 1.0;
|
||||
texpos[8] = 1.0;
|
||||
texpos[9] = 0.0;
|
||||
texpos[10] = 1.0;
|
||||
texpos[11] = 1.0;
|
||||
|
||||
tmp = x + buf->width;
|
||||
if (tmp < x || x >= sw)
|
||||
return -EINVAL;
|
||||
if (tmp > sw)
|
||||
width = sw - x;
|
||||
else
|
||||
width = buf->width;
|
||||
|
||||
tmp = y + buf->height;
|
||||
if (tmp < y || y >= sh)
|
||||
return -EINVAL;
|
||||
if (tmp > sh)
|
||||
height = sh - y;
|
||||
else
|
||||
height = buf->height;
|
||||
|
||||
glViewport(x, sh - y - height, width, height);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
gl_shader_use(v3d->blit_shader);
|
||||
|
||||
gl_m4_identity(mat);
|
||||
glUniformMatrix4fv(v3d->uni_blit_proj, 1, GL_FALSE, mat);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, v3d->tex);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
if (v3d->supports_rowlen) {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, buf->stride / 4);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, width, height, 0,
|
||||
GL_BGRA_EXT, GL_UNSIGNED_BYTE, buf->data);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
} else if (buf->stride == width) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, width, height, 0,
|
||||
GL_BGRA_EXT, GL_UNSIGNED_BYTE, buf->data);
|
||||
} else {
|
||||
packed = malloc(width * height);
|
||||
if (!packed)
|
||||
return -ENOMEM;
|
||||
|
||||
src = buf->data;
|
||||
dst = packed;
|
||||
for (i = 0; i < height; ++i) {
|
||||
memcpy(dst, src, width * 4);
|
||||
dst += width * 4;
|
||||
src += buf->stride;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, width, height, 0,
|
||||
GL_BGRA_EXT, GL_UNSIGNED_BYTE, packed);
|
||||
|
||||
free(packed);
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glUniform1i(v3d->uni_blit_tex, 0);
|
||||
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, texpos);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
|
||||
if (gl_has_error(v3d->blit_shader)) {
|
||||
log_warning("GL error");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int display_blend(struct uterm_display *disp,
|
||||
const struct uterm_video_buffer *buf,
|
||||
unsigned int x, unsigned int y,
|
||||
uint8_t fr, uint8_t fg, uint8_t fb,
|
||||
uint8_t br, uint8_t bg, uint8_t bb)
|
||||
{
|
||||
struct uterm_drm3d_video *v3d;
|
||||
unsigned int sw, sh, tmp, width, height, i;
|
||||
float mat[16];
|
||||
float vertices[6 * 2], texpos[6 * 2], fgcol[3], bgcol[3];
|
||||
int ret;
|
||||
uint8_t *packed, *src, *dst;
|
||||
|
||||
if (!buf || buf->format != UTERM_FORMAT_GREY)
|
||||
return -EINVAL;
|
||||
|
||||
v3d = uterm_drm_video_get_data(disp->video);
|
||||
ret = display_use(disp, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = init_shaders(disp->video);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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;
|
||||
vertices[2] = -1.0;
|
||||
vertices[3] = +1.0;
|
||||
vertices[4] = +1.0;
|
||||
vertices[5] = +1.0;
|
||||
|
||||
vertices[6] = -1.0;
|
||||
vertices[7] = -1.0;
|
||||
vertices[8] = +1.0;
|
||||
vertices[9] = +1.0;
|
||||
vertices[10] = +1.0;
|
||||
vertices[11] = -1.0;
|
||||
|
||||
texpos[0] = 0.0;
|
||||
texpos[1] = 1.0;
|
||||
texpos[2] = 0.0;
|
||||
texpos[3] = 0.0;
|
||||
texpos[4] = 1.0;
|
||||
texpos[5] = 0.0;
|
||||
|
||||
texpos[6] = 0.0;
|
||||
texpos[7] = 1.0;
|
||||
texpos[8] = 1.0;
|
||||
texpos[9] = 0.0;
|
||||
texpos[10] = 1.0;
|
||||
texpos[11] = 1.0;
|
||||
|
||||
fgcol[0] = fr / 255.0;
|
||||
fgcol[1] = fg / 255.0;
|
||||
fgcol[2] = fb / 255.0;
|
||||
bgcol[0] = br / 255.0;
|
||||
bgcol[1] = bg / 255.0;
|
||||
bgcol[2] = bb / 255.0;
|
||||
|
||||
tmp = x + buf->width;
|
||||
if (tmp < x || x >= sw)
|
||||
return -EINVAL;
|
||||
if (tmp > sw)
|
||||
width = sw - x;
|
||||
else
|
||||
width = buf->width;
|
||||
|
||||
tmp = y + buf->height;
|
||||
if (tmp < y || y >= sh)
|
||||
return -EINVAL;
|
||||
if (tmp > sh)
|
||||
height = sh - y;
|
||||
else
|
||||
height = buf->height;
|
||||
|
||||
glViewport(x, sh - y - height, width, height);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
gl_shader_use(v3d->blend_shader);
|
||||
|
||||
gl_m4_identity(mat);
|
||||
glUniformMatrix4fv(v3d->uni_blend_proj, 1, GL_FALSE, mat);
|
||||
|
||||
glUniform3fv(v3d->uni_blend_fgcol, 1, fgcol);
|
||||
glUniform3fv(v3d->uni_blend_bgcol, 1, bgcol);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, v3d->tex);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
if (v3d->supports_rowlen) {
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, buf->stride);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE, buf->data);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
} else if (buf->stride == width) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE, buf->data);
|
||||
} else {
|
||||
packed = malloc(width * height);
|
||||
if (!packed)
|
||||
return -ENOMEM;
|
||||
|
||||
src = buf->data;
|
||||
dst = packed;
|
||||
for (i = 0; i < height; ++i) {
|
||||
memcpy(dst, src, width);
|
||||
dst += width;
|
||||
src += buf->stride;
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE, packed);
|
||||
|
||||
free(packed);
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glUniform1i(v3d->uni_blend_tex, 0);
|
||||
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, texpos);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
|
||||
if (gl_has_error(v3d->blend_shader)) {
|
||||
log_warning("GL error");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int display_fake_blendv(struct uterm_display *disp,
|
||||
const struct uterm_video_blend_req *req,
|
||||
size_t num)
|
||||
{
|
||||
int ret;
|
||||
unsigned int i;
|
||||
|
||||
if (!disp || !req)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < num; ++i, ++req) {
|
||||
if (!req->buf)
|
||||
continue;
|
||||
|
||||
ret = display_blend(disp, req->buf, req->x, req->y,
|
||||
req->fr, req->fg, req->fb,
|
||||
req->br, req->bg, req->bb);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int display_fill(struct uterm_display *disp,
|
||||
uint8_t r, uint8_t g, uint8_t b,
|
||||
unsigned int x, unsigned int y,
|
||||
unsigned int width, unsigned int height)
|
||||
{
|
||||
struct uterm_drm3d_video *v3d;
|
||||
unsigned int sw, sh, tmp, i;
|
||||
float mat[16];
|
||||
float vertices[6 * 2], colors[6 * 4];
|
||||
int ret;
|
||||
|
||||
v3d = uterm_drm_video_get_data(disp->video);
|
||||
ret = display_use(disp, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = init_shaders(disp->video);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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;
|
||||
colors[i * 4 + 1] = g / 255.0;
|
||||
colors[i * 4 + 2] = b / 255.0;
|
||||
colors[i * 4 + 3] = 1.0;
|
||||
}
|
||||
|
||||
vertices[0] = -1.0;
|
||||
vertices[1] = -1.0;
|
||||
vertices[2] = -1.0;
|
||||
vertices[3] = +1.0;
|
||||
vertices[4] = +1.0;
|
||||
vertices[5] = +1.0;
|
||||
|
||||
vertices[6] = -1.0;
|
||||
vertices[7] = -1.0;
|
||||
vertices[8] = +1.0;
|
||||
vertices[9] = +1.0;
|
||||
vertices[10] = +1.0;
|
||||
vertices[11] = -1.0;
|
||||
|
||||
tmp = x + width;
|
||||
if (tmp < x || x >= sw)
|
||||
return -EINVAL;
|
||||
if (tmp > sw)
|
||||
width = sw - x;
|
||||
tmp = y + height;
|
||||
if (tmp < y || y >= sh)
|
||||
return -EINVAL;
|
||||
if (tmp > sh)
|
||||
height = sh - y;
|
||||
|
||||
glViewport(x, y, width, height);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
gl_shader_use(v3d->fill_shader);
|
||||
gl_m4_identity(mat);
|
||||
glUniformMatrix4fv(v3d->uni_fill_proj, 1, GL_FALSE, mat);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
||||
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, colors);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
|
||||
if (gl_has_error(v3d->fill_shader)) {
|
||||
log_warning("GL error");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct display_ops drm_display_ops = {
|
||||
.init = display_init,
|
||||
.destroy = display_destroy,
|
||||
.activate = display_activate,
|
||||
.deactivate = display_deactivate,
|
||||
.set_dpms = uterm_drm_display_set_dpms,
|
||||
.use = display_use,
|
||||
.use = uterm_drm3d_display_use,
|
||||
.get_buffers = NULL,
|
||||
.swap = display_swap,
|
||||
.blit = display_blit,
|
||||
.fake_blendv = display_fake_blendv,
|
||||
.fill = display_fill,
|
||||
.blit = uterm_drm3d_display_blit,
|
||||
.fake_blendv = uterm_drm3d_display_fake_blendv,
|
||||
.fill = uterm_drm3d_display_fill,
|
||||
};
|
||||
|
||||
static void show_displays(struct uterm_video *video)
|
||||
@ -847,7 +371,7 @@ static void show_displays(struct uterm_video *video)
|
||||
if (iter->dpms != UTERM_DPMS_ON)
|
||||
continue;
|
||||
|
||||
ret = display_use(iter, NULL);
|
||||
ret = uterm_drm3d_display_use(iter, NULL);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
@ -998,7 +522,7 @@ static void video_destroy(struct uterm_video *video)
|
||||
if (!eglMakeCurrent(v3d->disp, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
v3d->ctx))
|
||||
log_error("cannot activate GL context during destruction");
|
||||
deinit_shaders(video);
|
||||
uterm_drm3d_deinit_shaders(video);
|
||||
|
||||
eglMakeCurrent(v3d->disp, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
@ -1041,8 +565,8 @@ static const struct video_ops drm_video_ops = {
|
||||
.wake_up = video_wake_up,
|
||||
};
|
||||
|
||||
static const struct uterm_video_module drm_module = {
|
||||
static const struct uterm_video_module drm3d_module = {
|
||||
.ops = &drm_video_ops,
|
||||
};
|
||||
|
||||
const struct uterm_video_module *UTERM_VIDEO_DRM = &drm_module;
|
||||
const struct uterm_video_module *UTERM_VIDEO_DRM3D = &drm3d_module;
|
@ -64,7 +64,7 @@ bool uterm_video_available(const struct uterm_video_module *mod)
|
||||
if (!mod)
|
||||
return false;
|
||||
|
||||
if (mod == UTERM_VIDEO_DRM2D || mod == UTERM_VIDEO_DRM)
|
||||
if (mod == UTERM_VIDEO_DRM2D || mod == UTERM_VIDEO_DRM3D)
|
||||
return video_drm_available();
|
||||
|
||||
return true;
|
||||
|
@ -220,10 +220,10 @@ extern const struct uterm_video_module *UTERM_VIDEO_DRM2D;
|
||||
#define UTERM_VIDEO_DRM2D NULL
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_ENABLE_VIDEO_DRM
|
||||
extern const struct uterm_video_module *UTERM_VIDEO_DRM;
|
||||
#ifdef BUILD_ENABLE_VIDEO_DRM3D
|
||||
extern const struct uterm_video_module *UTERM_VIDEO_DRM3D;
|
||||
#else
|
||||
#define UTERM_VIDEO_DRM NULL
|
||||
#define UTERM_VIDEO_DRM3D NULL
|
||||
#endif
|
||||
|
||||
#endif /* UTERM_UTERM_VIDEO_H */
|
||||
|
@ -180,7 +180,7 @@ static inline bool video_need_hotplug(const struct uterm_video *video)
|
||||
.action = (act), \
|
||||
})
|
||||
|
||||
#if defined(BUILD_ENABLE_VIDEO_DRM) || defined(BUILD_ENABLE_VIDEO_DRM2D)
|
||||
#if defined(BUILD_ENABLE_VIDEO_DRM3D) || defined(BUILD_ENABLE_VIDEO_DRM2D)
|
||||
|
||||
#include <xf86drm.h>
|
||||
|
||||
|
@ -206,7 +206,7 @@ int main(int argc, char **argv)
|
||||
mode = UTERM_VIDEO_FBDEV;
|
||||
node = "/dev/fb0";
|
||||
} else {
|
||||
mode = UTERM_VIDEO_DRM;
|
||||
mode = UTERM_VIDEO_DRM3D;
|
||||
node = "/dev/dri/card0";
|
||||
}
|
||||
|
||||
@ -217,7 +217,7 @@ int main(int argc, char **argv)
|
||||
|
||||
ret = uterm_video_new(&video, eloop, node, mode);
|
||||
if (ret) {
|
||||
if (mode == UTERM_VIDEO_DRM) {
|
||||
if (mode == UTERM_VIDEO_DRM3D) {
|
||||
log_notice("cannot create drm device; trying drm2d mode");
|
||||
ret = uterm_video_new(&video, eloop, node,
|
||||
UTERM_VIDEO_DRM2D);
|
||||
|
Loading…
x
Reference in New Issue
Block a user