Port compositor to GLES2
This commit is contained in:
parent
f88ae45e41
commit
27803c6859
291
compositor.c
291
compositor.c
@ -39,7 +39,8 @@
|
|||||||
|
|
||||||
#define GL_GLEXT_PROTOTYPES
|
#define GL_GLEXT_PROTOTYPES
|
||||||
#define EGL_EGLEXT_PROTOTYPES
|
#define EGL_EGLEXT_PROTOTYPES
|
||||||
#include <GL/gl.h>
|
#include <GLES2/gl2.h>
|
||||||
|
#include <GLES2/gl2ext.h>
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <EGL/eglext.h>
|
#include <EGL/eglext.h>
|
||||||
|
|
||||||
@ -51,7 +52,7 @@
|
|||||||
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
|
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
|
||||||
|
|
||||||
struct wlsc_matrix {
|
struct wlsc_matrix {
|
||||||
GLdouble d[16];
|
GLfloat d[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wl_visual {
|
struct wl_visual {
|
||||||
@ -71,6 +72,7 @@ struct wlsc_output {
|
|||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct wlsc_compositor *compositor;
|
struct wlsc_compositor *compositor;
|
||||||
struct wlsc_surface *background;
|
struct wlsc_surface *background;
|
||||||
|
struct wlsc_matrix matrix;
|
||||||
int32_t x, y, width, height;
|
int32_t x, y, width, height;
|
||||||
|
|
||||||
drmModeModeInfo mode;
|
drmModeModeInfo mode;
|
||||||
@ -106,7 +108,8 @@ struct wlsc_compositor {
|
|||||||
EGLDisplay display;
|
EGLDisplay display;
|
||||||
EGLContext context;
|
EGLContext context;
|
||||||
int drm_fd;
|
int drm_fd;
|
||||||
GLuint fbo;
|
GLuint fbo, vbo;
|
||||||
|
GLuint proj_uniform, tex_uniform;
|
||||||
struct wl_display *wl_display;
|
struct wl_display *wl_display;
|
||||||
|
|
||||||
struct wl_list output_list;
|
struct wl_list output_list;
|
||||||
@ -143,7 +146,7 @@ struct wlsc_compositor {
|
|||||||
#define MODIFIER_ALT (1 << 9)
|
#define MODIFIER_ALT (1 << 9)
|
||||||
|
|
||||||
struct wlsc_vector {
|
struct wlsc_vector {
|
||||||
GLdouble x, y, z;
|
GLfloat f[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlsc_surface {
|
struct wlsc_surface {
|
||||||
@ -152,10 +155,10 @@ struct wlsc_surface {
|
|||||||
struct wl_visual *visual;
|
struct wl_visual *visual;
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
EGLImageKHR image;
|
EGLImageKHR image;
|
||||||
struct wl_map map;
|
|
||||||
int width, height;
|
int width, height;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct wlsc_matrix matrix;
|
struct wlsc_matrix matrix;
|
||||||
|
struct wlsc_matrix matrix_inv;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *option_background = "background.jpg";
|
static const char *option_background = "background.jpg";
|
||||||
@ -198,7 +201,6 @@ screenshooter_shoot(struct wl_client *client, struct screenshooter *shooter)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
glReadBuffer(GL_FRONT);
|
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
glReadPixels(0, 0, output->width, output->height,
|
glReadPixels(0, 0, output->width, output->height,
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
@ -262,7 +264,7 @@ static void
|
|||||||
wlsc_matrix_multiply(struct wlsc_matrix *m, const struct wlsc_matrix *n)
|
wlsc_matrix_multiply(struct wlsc_matrix *m, const struct wlsc_matrix *n)
|
||||||
{
|
{
|
||||||
struct wlsc_matrix tmp;
|
struct wlsc_matrix tmp;
|
||||||
const GLdouble *row, *column;
|
const GLfloat *row, *column;
|
||||||
div_t d;
|
div_t d;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
@ -278,7 +280,7 @@ wlsc_matrix_multiply(struct wlsc_matrix *m, const struct wlsc_matrix *n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wlsc_matrix_translate(struct wlsc_matrix *matrix, GLdouble x, GLdouble y, GLdouble z)
|
wlsc_matrix_translate(struct wlsc_matrix *matrix, GLfloat x, GLfloat y, GLfloat z)
|
||||||
{
|
{
|
||||||
struct wlsc_matrix translate = {
|
struct wlsc_matrix translate = {
|
||||||
{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1 }
|
{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1 }
|
||||||
@ -288,7 +290,7 @@ wlsc_matrix_translate(struct wlsc_matrix *matrix, GLdouble x, GLdouble y, GLdoub
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wlsc_matrix_scale(struct wlsc_matrix *matrix, GLdouble x, GLdouble y, GLdouble z)
|
wlsc_matrix_scale(struct wlsc_matrix *matrix, GLfloat x, GLfloat y, GLfloat z)
|
||||||
{
|
{
|
||||||
struct wlsc_matrix scale = {
|
struct wlsc_matrix scale = {
|
||||||
{ x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1 }
|
{ x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1 }
|
||||||
@ -299,10 +301,10 @@ wlsc_matrix_scale(struct wlsc_matrix *matrix, GLdouble x, GLdouble y, GLdouble z
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
wlsc_matrix_rotate(struct wlsc_matrix *matrix,
|
wlsc_matrix_rotate(struct wlsc_matrix *matrix,
|
||||||
GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
|
GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
|
||||||
{
|
{
|
||||||
GLdouble c = cos(angle);
|
GLfloat c = cos(angle);
|
||||||
GLdouble s = sin(angle);
|
GLfloat s = sin(angle);
|
||||||
struct wlsc_matrix rotate = {
|
struct wlsc_matrix rotate = {
|
||||||
{ x * x * (1 - c) + c, y * x * (1 - c) + z * s, x * z * (1 - c) - y * s, 0,
|
{ x * x * (1 - c) + c, y * x * (1 - c) + z * s, x * z * (1 - c) - y * s, 0,
|
||||||
x * y * (1 - c) - z * s, y * y * (1 - c) + c, y * z * (1 - c) + x * s, 0,
|
x * y * (1 - c) - z * s, y * y * (1 - c) + c, y * z * (1 - c) + x * s, 0,
|
||||||
@ -313,6 +315,20 @@ wlsc_matrix_rotate(struct wlsc_matrix *matrix,
|
|||||||
wlsc_matrix_multiply(matrix, &rotate);
|
wlsc_matrix_multiply(matrix, &rotate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wlsc_matrix_transform(struct wlsc_matrix *matrix, struct wlsc_vector *v)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
GLfloat t;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
t = 0;
|
||||||
|
for (j = 0; j < 4; j++)
|
||||||
|
t += v->f[j] * matrix->d[i + j * 4];
|
||||||
|
v->f[i] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wlsc_surface_init(struct wlsc_surface *surface,
|
wlsc_surface_init(struct wlsc_surface *surface,
|
||||||
struct wlsc_compositor *compositor, struct wl_visual *visual,
|
struct wlsc_compositor *compositor, struct wl_visual *visual,
|
||||||
@ -320,12 +336,14 @@ wlsc_surface_init(struct wlsc_surface *surface,
|
|||||||
{
|
{
|
||||||
glGenTextures(1, &surface->texture);
|
glGenTextures(1, &surface->texture);
|
||||||
surface->compositor = compositor;
|
surface->compositor = compositor;
|
||||||
surface->map.x = x;
|
|
||||||
surface->map.y = y;
|
|
||||||
surface->map.width = width;
|
|
||||||
surface->map.height = height;
|
|
||||||
surface->visual = visual;
|
surface->visual = visual;
|
||||||
wlsc_matrix_init(&surface->matrix);
|
wlsc_matrix_init(&surface->matrix);
|
||||||
|
wlsc_matrix_scale(&surface->matrix, width, height, 1);
|
||||||
|
wlsc_matrix_translate(&surface->matrix, x, y, 0);
|
||||||
|
|
||||||
|
wlsc_matrix_init(&surface->matrix_inv);
|
||||||
|
wlsc_matrix_translate(&surface->matrix_inv, -x, -y, 0);
|
||||||
|
wlsc_matrix_scale(&surface->matrix_inv, 1.0 / width, 1.0 / height, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlsc_surface *
|
static struct wlsc_surface *
|
||||||
@ -347,12 +365,12 @@ wlsc_surface_create_from_cairo_surface(struct wlsc_compositor *ec,
|
|||||||
wlsc_surface_init(es, ec, &ec->premultiplied_argb_visual,
|
wlsc_surface_init(es, ec, &ec->premultiplied_argb_visual,
|
||||||
x, y, width, height);
|
x, y, width, height);
|
||||||
glBindTexture(GL_TEXTURE_2D, es->texture);
|
glBindTexture(GL_TEXTURE_2D, es->texture);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
||||||
GL_BGRA, GL_UNSIGNED_BYTE, data);
|
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
|
|
||||||
return es;
|
return es;
|
||||||
}
|
}
|
||||||
@ -456,8 +474,8 @@ background_create(struct wlsc_output *output, const char *filename)
|
|||||||
output->x, output->y, output->width, output->height);
|
output->x, output->y, output->width, output->height);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, background->texture);
|
glBindTexture(GL_TEXTURE_2D, background->texture);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
@ -474,28 +492,15 @@ background_create(struct wlsc_output *output, const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
wlsc_surface_draw(struct wlsc_surface *es)
|
wlsc_surface_draw(struct wlsc_surface *es, struct wlsc_output *output)
|
||||||
{
|
{
|
||||||
struct wlsc_compositor *ec = es->compositor;
|
struct wlsc_compositor *ec = es->compositor;
|
||||||
GLint vertices[12];
|
struct wlsc_matrix tmp;
|
||||||
GLint tex_coords[12] = { 0, 0, 0, 1, 1, 0, 1, 1 };
|
|
||||||
GLuint indices[4] = { 0, 1, 2, 3 };
|
|
||||||
|
|
||||||
vertices[0] = es->map.x;
|
tmp = es->matrix;
|
||||||
vertices[1] = es->map.y;
|
wlsc_matrix_multiply(&tmp, &output->matrix);
|
||||||
vertices[2] = 0;
|
glUniformMatrix4fv(ec->proj_uniform, 1, GL_FALSE, tmp.d);
|
||||||
|
glUniform1i(ec->tex_uniform, 0);
|
||||||
vertices[3] = es->map.x;
|
|
||||||
vertices[4] = es->map.y + es->map.height;
|
|
||||||
vertices[5] = 0;
|
|
||||||
|
|
||||||
vertices[6] = es->map.x + es->map.width;
|
|
||||||
vertices[7] = es->map.y;
|
|
||||||
vertices[8] = 0;
|
|
||||||
|
|
||||||
vertices[9] = es->map.x + es->map.width;
|
|
||||||
vertices[10] = es->map.y + es->map.height;
|
|
||||||
vertices[11] = 0;
|
|
||||||
|
|
||||||
if (es->visual == &ec->argb_visual) {
|
if (es->visual == &ec->argb_visual) {
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
@ -507,16 +512,16 @@ wlsc_surface_draw(struct wlsc_surface *es)
|
|||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
glPushMatrix();
|
|
||||||
//glMultMatrixd(es->matrix.d);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, es->texture);
|
glBindTexture(GL_TEXTURE_2D, es->texture);
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glBindBuffer(GL_ARRAY_BUFFER, ec->vbo);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
|
||||||
glVertexPointer(3, GL_INT, 0, vertices);
|
5 * sizeof(GLfloat), NULL);
|
||||||
glTexCoordPointer(2, GL_INT, 0, tex_coords);
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
|
||||||
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, indices);
|
5 * sizeof(GLfloat), (GLfloat *) 0 + 3);
|
||||||
glPopMatrix();
|
glEnableVertexAttribArray(0);
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -537,30 +542,6 @@ wlsc_surface_lower(struct wlsc_surface *surface)
|
|||||||
wl_list_insert(&compositor->surface_list, &surface->link);
|
wl_list_insert(&compositor->surface_list, &surface->link);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
wlsc_vector_add(struct wlsc_vector *v1, struct wlsc_vector *v2)
|
|
||||||
{
|
|
||||||
v1->x += v2->x;
|
|
||||||
v1->y += v2->y;
|
|
||||||
v1->z += v2->z;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
wlsc_vector_subtract(struct wlsc_vector *v1, struct wlsc_vector *v2)
|
|
||||||
{
|
|
||||||
v1->x -= v2->x;
|
|
||||||
v1->y -= v2->y;
|
|
||||||
v1->z -= v2->z;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
wlsc_vector_scalar(struct wlsc_vector *v1, GLdouble s)
|
|
||||||
{
|
|
||||||
v1->x *= s;
|
|
||||||
v1->y *= s;
|
|
||||||
v1->z *= s;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
page_flip_handler(int fd, unsigned int frame,
|
page_flip_handler(int fd, unsigned int frame,
|
||||||
unsigned int sec, unsigned int usec, void *data)
|
unsigned int sec, unsigned int usec, void *data)
|
||||||
@ -586,35 +567,25 @@ repaint_output(struct wlsc_output *output)
|
|||||||
struct wlsc_compositor *ec = output->compositor;
|
struct wlsc_compositor *ec = output->compositor;
|
||||||
struct wlsc_surface *es;
|
struct wlsc_surface *es;
|
||||||
struct wlsc_input_device *eid;
|
struct wlsc_input_device *eid;
|
||||||
double s = 3000;
|
|
||||||
|
|
||||||
glViewport(0, 0, output->width, output->height);
|
glViewport(0, 0, output->width, output->height);
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glLoadIdentity();
|
|
||||||
glFrustum(-output->width / s, output->width / s,
|
|
||||||
-output->height / s, output->height / s, 1, 2 * s);
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glLoadIdentity();
|
|
||||||
glClearColor(0, 0, 0, 1);
|
|
||||||
|
|
||||||
glTranslatef(-output->width / 2, -output->height / 2, -s / 2);
|
|
||||||
|
|
||||||
if (output->background)
|
if (output->background)
|
||||||
wlsc_surface_draw(output->background);
|
wlsc_surface_draw(output->background, output);
|
||||||
else
|
else
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
wl_list_for_each(es, &ec->surface_list, link)
|
wl_list_for_each(es, &ec->surface_list, link)
|
||||||
wlsc_surface_draw(es);
|
wlsc_surface_draw(es, output);
|
||||||
|
|
||||||
wl_list_for_each(eid, &ec->input_device_list, link)
|
wl_list_for_each(eid, &ec->input_device_list, link)
|
||||||
wlsc_surface_draw(eid->sprite);
|
wlsc_surface_draw(eid->sprite, output);
|
||||||
|
|
||||||
output->current ^= 1;
|
output->current ^= 1;
|
||||||
|
|
||||||
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT,
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
|
||||||
GL_COLOR_ATTACHMENT0_EXT,
|
GL_COLOR_ATTACHMENT0,
|
||||||
GL_RENDERBUFFER_EXT,
|
GL_RENDERBUFFER,
|
||||||
output->rbo[output->current]);
|
output->rbo[output->current]);
|
||||||
drmModePageFlip(ec->drm_fd, output->crtc_id,
|
drmModePageFlip(ec->drm_fd, output->crtc_id,
|
||||||
output->fb_id[output->current ^ 1],
|
output->fb_id[output->current ^ 1],
|
||||||
@ -695,8 +666,8 @@ surface_attach(struct wl_client *client,
|
|||||||
/* FIXME: Smack client with an exception event */;
|
/* FIXME: Smack client with an exception event */;
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, es->texture);
|
glBindTexture(GL_TEXTURE_2D, es->texture);
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
@ -722,10 +693,8 @@ surface_map(struct wl_client *client,
|
|||||||
{
|
{
|
||||||
struct wlsc_surface *es = (struct wlsc_surface *) surface;
|
struct wlsc_surface *es = (struct wlsc_surface *) surface;
|
||||||
|
|
||||||
es->map.x = x;
|
wlsc_matrix_translate(&es->matrix, x, y, 0);
|
||||||
es->map.y = y;
|
wlsc_matrix_scale(&es->matrix, width, height, 1);
|
||||||
es->map.width = width;
|
|
||||||
es->map.height = height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -791,9 +760,11 @@ static void
|
|||||||
wlsc_surface_transform(struct wlsc_surface *surface,
|
wlsc_surface_transform(struct wlsc_surface *surface,
|
||||||
int32_t x, int32_t y, int32_t *sx, int32_t *sy)
|
int32_t x, int32_t y, int32_t *sx, int32_t *sy)
|
||||||
{
|
{
|
||||||
/* Transform to surface coordinates. */
|
struct wlsc_vector v = { { x, y, 0, 1 } };
|
||||||
*sx = (x - surface->map.x) * surface->width / surface->map.width;
|
|
||||||
*sy = (y - surface->map.y) * surface->height / surface->map.height;
|
wlsc_matrix_transform(&surface->matrix_inv, &v);
|
||||||
|
*sx = v.f[0];
|
||||||
|
*sy = v.f[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -850,14 +821,12 @@ pick_surface(struct wlsc_input_device *device, int32_t *sx, int32_t *sy)
|
|||||||
return device->grab_surface;
|
return device->grab_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_list_for_each(es, &ec->surface_list, link)
|
wl_list_for_each(es, &ec->surface_list, link) {
|
||||||
if (es->map.x <= device->x &&
|
wlsc_surface_transform(es, device->x, device->y, sx, sy);
|
||||||
device->x < es->map.x + es->map.width &&
|
if (0 <= *sx && *sx < es->width &&
|
||||||
es->map.y <= device->y &&
|
0 <= *sy && *sy < es->height)
|
||||||
device->y < es->map.y + es->map.height) {
|
|
||||||
wlsc_surface_transform(es, device->x, device->y, sx, sy);
|
|
||||||
return es;
|
return es;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -895,8 +864,10 @@ notify_motion(struct wlsc_input_device *device, int x, int y)
|
|||||||
wl_surface_post_event(&es->base, &device->base,
|
wl_surface_post_event(&es->base, &device->base,
|
||||||
WL_INPUT_MOTION, x, y, sx, sy);
|
WL_INPUT_MOTION, x, y, sx, sy);
|
||||||
|
|
||||||
device->sprite->map.x = x - hotspot_x;
|
wlsc_matrix_init(&device->sprite->matrix);
|
||||||
device->sprite->map.y = y - hotspot_y;
|
wlsc_matrix_scale(&device->sprite->matrix, 64, 64, 1);
|
||||||
|
wlsc_matrix_translate(&device->sprite->matrix,
|
||||||
|
x - hotspot_x, y - hotspot_y, 0);
|
||||||
|
|
||||||
wlsc_compositor_schedule_repaint(device->ec);
|
wlsc_compositor_schedule_repaint(device->ec);
|
||||||
}
|
}
|
||||||
@ -1071,6 +1042,91 @@ on_drm_input(int fd, uint32_t mask, void *data)
|
|||||||
drmHandleEvent(fd, &evctx);
|
drmHandleEvent(fd, &evctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char vertex_shader[] =
|
||||||
|
"uniform mat4 proj;\n"
|
||||||
|
"attribute vec4 position;\n"
|
||||||
|
"attribute vec2 texcoord;\n"
|
||||||
|
"varying vec2 v_texcoord;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" gl_Position = proj * position;\n"
|
||||||
|
" v_texcoord = texcoord;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
static const char fragment_shader[] =
|
||||||
|
/* "precision mediump float;\n" */
|
||||||
|
"varying vec2 v_texcoord;\n"
|
||||||
|
"uniform sampler2D tex;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" gl_FragColor = texture2D(tex, v_texcoord)\n;"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_shaders(struct wlsc_compositor *ec)
|
||||||
|
{
|
||||||
|
GLuint v, f, program;
|
||||||
|
const char *p;
|
||||||
|
char msg[512];
|
||||||
|
GLfloat vertices[4 * 5];
|
||||||
|
|
||||||
|
p = vertex_shader;
|
||||||
|
v = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
glShaderSource(v, 1, &p, NULL);
|
||||||
|
glCompileShader(v);
|
||||||
|
glGetShaderInfoLog(v, sizeof msg, NULL, msg);
|
||||||
|
printf("vertex shader info: %s\n", msg);
|
||||||
|
|
||||||
|
p = fragment_shader;
|
||||||
|
f = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(f, 1, &p, NULL);
|
||||||
|
glCompileShader(f);
|
||||||
|
glGetShaderInfoLog(f, sizeof msg, NULL, msg);
|
||||||
|
printf("fragment shader info: %s\n", msg);
|
||||||
|
|
||||||
|
program = glCreateProgram();
|
||||||
|
glAttachShader(program, v);
|
||||||
|
glAttachShader(program, f);
|
||||||
|
glBindAttribLocation(program, 0, "position");
|
||||||
|
glBindAttribLocation(program, 1, "texcoord");
|
||||||
|
|
||||||
|
glLinkProgram(program);
|
||||||
|
glGetProgramInfoLog(program, sizeof msg, NULL, msg);
|
||||||
|
printf("info: %s\n", msg);
|
||||||
|
|
||||||
|
glUseProgram(program);
|
||||||
|
ec->proj_uniform = glGetUniformLocation(program, "proj");
|
||||||
|
ec->tex_uniform = glGetUniformLocation(program, "tex");
|
||||||
|
|
||||||
|
vertices[ 0] = 0.0;
|
||||||
|
vertices[ 1] = 0.0;
|
||||||
|
vertices[ 2] = 0.0;
|
||||||
|
vertices[ 3] = 0.0;
|
||||||
|
vertices[ 4] = 0.0;
|
||||||
|
|
||||||
|
vertices[ 5] = 0.0;
|
||||||
|
vertices[ 6] = 1.0;
|
||||||
|
vertices[ 7] = 0.0;
|
||||||
|
vertices[ 8] = 0.0;
|
||||||
|
vertices[ 9] = 1.0;
|
||||||
|
|
||||||
|
vertices[10] = 1.0;
|
||||||
|
vertices[11] = 0.0;
|
||||||
|
vertices[12] = 0.0;
|
||||||
|
vertices[13] = 1.0;
|
||||||
|
vertices[14] = 0.0;
|
||||||
|
|
||||||
|
vertices[15] = 1.0;
|
||||||
|
vertices[16] = 1.0;
|
||||||
|
vertices[17] = 0.0;
|
||||||
|
vertices[18] = 1.0;
|
||||||
|
vertices[19] = 1.0;
|
||||||
|
|
||||||
|
glGenBuffers(1, &ec->vbo);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, ec->vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
init_egl(struct wlsc_compositor *ec, struct udev_device *device)
|
init_egl(struct wlsc_compositor *ec, struct udev_device *device)
|
||||||
{
|
{
|
||||||
@ -1132,7 +1188,9 @@ init_egl(struct wlsc_compositor *ec, struct udev_device *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
glGenFramebuffers(1, &ec->fbo);
|
glGenFramebuffers(1, &ec->fbo);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER_EXT, ec->fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, ec->fbo);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
init_shaders(ec);
|
||||||
|
|
||||||
loop = wl_display_get_event_loop(ec->wl_display);
|
loop = wl_display_get_event_loop(ec->wl_display);
|
||||||
ec->drm_source =
|
ec->drm_source =
|
||||||
@ -1201,18 +1259,19 @@ create_output_for_connector(struct wlsc_compositor *ec,
|
|||||||
output->y = 0;
|
output->y = 0;
|
||||||
output->width = mode->hdisplay;
|
output->width = mode->hdisplay;
|
||||||
output->height = mode->vdisplay;
|
output->height = mode->vdisplay;
|
||||||
|
wlsc_matrix_init(&output->matrix);
|
||||||
|
|
||||||
printf("using crtc %d, connector %d and encoder %d, mode %s\n",
|
wlsc_matrix_translate(&output->matrix,
|
||||||
output->crtc_id,
|
-output->x - output->width / 2.0,
|
||||||
output->connector_id,
|
-output->y - output->height / 2.0, 0);
|
||||||
encoder->encoder_id,
|
wlsc_matrix_scale(&output->matrix,
|
||||||
mode->name);
|
2.0 / output->width, 2.0 / output->height, 1);
|
||||||
|
|
||||||
drmModeFreeEncoder(encoder);
|
drmModeFreeEncoder(encoder);
|
||||||
|
|
||||||
glGenRenderbuffers(2, output->rbo);
|
glGenRenderbuffers(2, output->rbo);
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER_EXT, output->rbo[i]);
|
glBindRenderbuffer(GL_RENDERBUFFER, output->rbo[i]);
|
||||||
|
|
||||||
attribs[1] = output->width;
|
attribs[1] = output->width;
|
||||||
attribs[3] = output->height;
|
attribs[3] = output->height;
|
||||||
@ -1229,9 +1288,9 @@ create_output_for_connector(struct wlsc_compositor *ec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
output->current = 0;
|
output->current = 0;
|
||||||
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT,
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
|
||||||
GL_COLOR_ATTACHMENT0_EXT,
|
GL_COLOR_ATTACHMENT0,
|
||||||
GL_RENDERBUFFER_EXT,
|
GL_RENDERBUFFER,
|
||||||
output->rbo[output->current]);
|
output->rbo[output->current]);
|
||||||
ret = drmModeSetCrtc(ec->drm_fd, output->crtc_id,
|
ret = drmModeSetCrtc(ec->drm_fd, output->crtc_id,
|
||||||
output->fb_id[output->current ^ 1], 0, 0,
|
output->fb_id[output->current ^ 1], 0, 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user