some renderer improvements
This commit is contained in:
parent
3b6336f54b
commit
3c5fee04da
@ -1,18 +0,0 @@
|
||||
Xwayland depends on these Wayland interfaces:
|
||||
1. wl_display (libwayland builtin)
|
||||
2. wl_registry (libwayland builtin)
|
||||
3. wl_shm (libwayland builtin)
|
||||
4. wl_shm_pool (libwayland builtin)
|
||||
5. wl_compositor
|
||||
6. wl_shell
|
||||
7. wl_region
|
||||
8. wl_surface
|
||||
9. wl_shell_surface
|
||||
10. wl_seat
|
||||
11. wl_pointer
|
||||
12. wl_keyboard
|
||||
13. wl_drm (glamor only)
|
||||
14. xdg_surface
|
||||
15. xdg_shell
|
||||
16. zwp_relative_pointer_manager_v1
|
||||
17. zwp_pointer_constraints_v1
|
34
log.h
Normal file
34
log.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
|
||||
#ifndef LOG_TAG
|
||||
#define LOG_TAG "XLorie"
|
||||
#endif
|
||||
|
||||
#define LOG(prio, ...) __android_log_print(prio, LOG_TAG, __VA_ARGS__)
|
||||
|
||||
#define LOGI(...) LOG(ANDROID_LOG_INFO, __VA_ARGS__)
|
||||
#define LOGW(...) LOG(ANDROID_LOG_WARN, __VA_ARGS__)
|
||||
#define LOGD(...) LOG(ANDROID_LOG_DEBUG, __VA_ARGS__)
|
||||
#define LOGV(...) LOG(ANDROID_LOG_VERBOSE, __VA_ARGS__)
|
||||
#define LOGE(...) LOG(ANDROID_LOG_ERROR, __VA_ARGS__)
|
||||
#define LOGF(...) LOG(ANDROID_LOG_FATAL, __VA_ARGS__)
|
||||
|
||||
#else
|
||||
#include <stdio.h>
|
||||
|
||||
#define LOG(prio, ...) { printf(prio __VA_ARGS__); printf("\n"); }
|
||||
|
||||
#define LOGI(...) LOG("I: " , __VA_ARGS__)
|
||||
#define LOGW(...) LOG("W: " , __VA_ARGS__)
|
||||
#define LOGD(...) LOG("D: " , __VA_ARGS__)
|
||||
#define LOGV(...) LOG("V: " , __VA_ARGS__)
|
||||
#define LOGE(...) LOG("E: " , __VA_ARGS__)
|
||||
#define LOGF(...) LOG("F: " , __VA_ARGS__)
|
||||
|
||||
#endif
|
||||
#ifdef DBG
|
||||
#undef DBG
|
||||
#endif
|
||||
|
||||
#define DBG LOGD("Here! %s %d", __FILE__, __LINE__)
|
150
main.c
150
main.c
@ -13,10 +13,31 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/time.h>
|
||||
#include <wayland-server.h>
|
||||
#include <dlfcn.h>
|
||||
#include "backend.h"
|
||||
#include "renderer.h"
|
||||
#include "log.h"
|
||||
|
||||
#define static
|
||||
bool trace_funcs = false;
|
||||
|
||||
void __attribute__((no_instrument_function))
|
||||
__cyg_profile_func_enter (void *func, void *caller) {
|
||||
if (!trace_funcs) return;
|
||||
Dl_info info;
|
||||
if (dladdr(func, &info))
|
||||
LOGD ("enter %p [%s] %s\n", func, (info.dli_fname) ? info.dli_fname : "?", info.dli_sname ? info.dli_sname : "?");
|
||||
}
|
||||
void __attribute__((no_instrument_function))
|
||||
__cyg_profile_func_exit (void *func, void *caller) {
|
||||
if (!trace_funcs) return;
|
||||
Dl_info info;
|
||||
if (dladdr(func, &info))
|
||||
LOGD ("leave %p [%s] %s\n", func, (info.dli_fname) ? info.dli_fname : "?", info.dli_sname ? info.dli_sname : "?");
|
||||
}
|
||||
|
||||
#define static // backtrace do not report static function names
|
||||
|
||||
void handler(int sig) {
|
||||
void *array[10];
|
||||
@ -33,7 +54,7 @@ void handler(int sig) {
|
||||
|
||||
#define BINDFUNC(interface, version, implementation) \
|
||||
static void interface##_bind (struct wl_client *client, void *data, uint32_t _version, uint32_t id) { \
|
||||
printf ("bind: " #interface "\n"); \
|
||||
LOGD("bind: " #interface); \
|
||||
struct wl_resource *resource = wl_resource_create (client, &interface##_interface, version, id); \
|
||||
if (resource == NULL) { \
|
||||
wl_client_post_no_memory(client); \
|
||||
@ -44,6 +65,7 @@ void handler(int sig) {
|
||||
|
||||
struct lorie_composiror {
|
||||
struct wl_display *display;
|
||||
struct wl_resource *wl_output;
|
||||
struct wl_list clients;
|
||||
struct wl_list surfaces;
|
||||
struct wl_list shell_surfaces;
|
||||
@ -56,6 +78,8 @@ struct lorie_composiror {
|
||||
bool redraw_needed;
|
||||
|
||||
uint32_t width, height;
|
||||
|
||||
struct renderer* renderer;
|
||||
} c = {0};
|
||||
|
||||
struct client {
|
||||
@ -82,10 +106,11 @@ struct surface {
|
||||
struct wl_resource *buffer;
|
||||
struct wl_resource *frame_callback;
|
||||
//int x, y;
|
||||
//struct texture texture;
|
||||
struct texture *texture;
|
||||
struct client *client;
|
||||
struct shell_surface *shell_surface;
|
||||
struct wl_list link;
|
||||
uint32_t width, height;
|
||||
bool entered;
|
||||
};
|
||||
|
||||
@ -115,11 +140,34 @@ void *null = NULL;
|
||||
static void surface_attach (struct wl_client *client, struct wl_resource *resource, struct wl_resource *buffer, int32_t x, int32_t y) {
|
||||
struct surface *surface = wl_resource_get_user_data (resource);
|
||||
surface->buffer = buffer;
|
||||
//c.toplevel = surface;
|
||||
|
||||
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
|
||||
if (shm_buffer == NULL) {
|
||||
surface->width = surface->height = 0;
|
||||
return;
|
||||
}
|
||||
surface->width = wl_shm_buffer_get_width (shm_buffer);
|
||||
surface->height = wl_shm_buffer_get_height (shm_buffer);
|
||||
|
||||
if (!surface->texture ||
|
||||
surface->texture->width != surface->width ||
|
||||
surface->texture->height != surface->height) {
|
||||
texture_destroy(&surface->texture);
|
||||
surface->texture = texture_create(surface->width, surface->height);
|
||||
}
|
||||
}
|
||||
|
||||
static void surface_damage (struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) {
|
||||
printf("Surface damage\n");
|
||||
c.redraw_needed = true;
|
||||
struct surface *surface = wl_resource_get_user_data (resource);
|
||||
struct texture* texture;
|
||||
if (!surface || !surface->texture) {
|
||||
texture = surface->texture;
|
||||
texture->damage.x = min(texture->damage.x, x);
|
||||
texture->damage.y = min(texture->damage.y, y);
|
||||
texture->damage.width = max(texture->damage.width, width);
|
||||
texture->damage.height = max(texture->damage.height, height);
|
||||
}
|
||||
}
|
||||
static void surface_frame (struct wl_client *client, struct wl_resource *resource, uint32_t callback) {
|
||||
struct surface *surface = wl_resource_get_user_data (resource);
|
||||
@ -128,7 +176,22 @@ static void surface_frame (struct wl_client *client, struct wl_resource *resourc
|
||||
/*No op*/ static void surface_set_opaque_region (struct wl_client *client, struct wl_resource *resource, struct wl_resource *region) {}
|
||||
/*No op*/ static void surface_set_input_region (struct wl_client *client, struct wl_resource *resource, struct wl_resource *region) {}
|
||||
static void surface_commit (struct wl_client *client, struct wl_resource *resource) {
|
||||
printf("Surface commit\n");
|
||||
struct surface *surface = wl_resource_get_user_data (resource);
|
||||
if (!surface || !surface->buffer) return;
|
||||
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (surface->buffer);
|
||||
if (surface->texture && shm_buffer) {
|
||||
void *data = wl_shm_buffer_get_data (shm_buffer);
|
||||
if (data) {
|
||||
texture_upload(surface->texture, data);
|
||||
}
|
||||
}
|
||||
wl_buffer_send_release (surface->buffer);
|
||||
|
||||
if (surface->frame_callback) {
|
||||
wl_callback_send_done (surface->frame_callback, backend_get_timestamp());
|
||||
wl_resource_destroy (surface->frame_callback);
|
||||
surface->frame_callback = NULL;
|
||||
}
|
||||
}
|
||||
/*No op*/ static void surface_set_buffer_transform (struct wl_client *client, struct wl_resource *resource, int32_t transform) {}
|
||||
/*No op*/ static void surface_set_buffer_scale (struct wl_client *client, struct wl_resource *resource, int32_t scale) {}
|
||||
@ -136,6 +199,7 @@ static void surface_delete (struct wl_resource *resource) {
|
||||
struct surface *surface = wl_resource_get_user_data (resource);
|
||||
if (c.toplevel == surface) c.toplevel = NULL;
|
||||
wl_list_remove (&surface->link);
|
||||
texture_destroy(&surface->texture);
|
||||
free (surface);
|
||||
}
|
||||
static struct wl_surface_interface surface_interface = {&surface_destroy, &surface_attach, &surface_damage, &surface_frame, &surface_set_opaque_region, &surface_set_input_region, &surface_commit, &surface_set_buffer_transform, &surface_set_buffer_scale};
|
||||
@ -215,7 +279,7 @@ static void seat_get_keyboard (struct wl_client *client, struct wl_resource *res
|
||||
/*No op*/ static void seat_get_touch (struct wl_client *client, struct wl_resource *resource, uint32_t id) {}
|
||||
static struct wl_seat_interface seat_interface = {&seat_get_pointer, &seat_get_keyboard, &seat_get_touch};
|
||||
static void wl_seat_bind (struct wl_client *client, void *data, uint32_t version, uint32_t id) {
|
||||
printf ("bind: wl_seat\n");
|
||||
LOGD("bind: wl_seat");
|
||||
struct wl_resource *seat = wl_resource_create (client, &wl_seat_interface, 7, id);
|
||||
wl_resource_set_implementation (seat, &seat_interface, NULL, NULL);
|
||||
wl_seat_send_capabilities (seat, WL_SEAT_CAPABILITY_POINTER|WL_SEAT_CAPABILITY_KEYBOARD);
|
||||
@ -230,6 +294,12 @@ static const struct wl_output_interface output_interface = {
|
||||
output_release,
|
||||
};
|
||||
|
||||
static void
|
||||
wl_output_unbind (struct wl_resource *resource) {
|
||||
if (c.wl_output == resource)
|
||||
c.wl_output = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
wl_output_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
|
||||
{
|
||||
@ -240,7 +310,7 @@ wl_output_bind(struct wl_client *client, void *data, uint32_t version, uint32_t
|
||||
return;
|
||||
}
|
||||
|
||||
wl_resource_set_implementation(resource, &output_interface, NULL, NULL);
|
||||
wl_resource_set_implementation(resource, &output_interface, NULL, &wl_output_unbind);
|
||||
|
||||
int mm_width = c.width/DPI*25*2;
|
||||
int mm_height = c.height/DPI*25*2;
|
||||
@ -251,10 +321,29 @@ wl_output_bind(struct wl_client *client, void *data, uint32_t version, uint32_t
|
||||
|
||||
if (version >= WL_OUTPUT_DONE_SINCE_VERSION)
|
||||
wl_output_send_done(resource);
|
||||
|
||||
c.wl_output = resource;
|
||||
}
|
||||
|
||||
// backend callbacks
|
||||
/*No op*/ static void handle_resize_event (int width, int height) {}
|
||||
static void handle_resize_event (int width, int height) {
|
||||
//glViewport(0, 0, width, height);
|
||||
c.width = width;
|
||||
c.height = height;
|
||||
if (c.wl_output) {
|
||||
wl_output_send_mode(c.wl_output, 3, width, height, 60000);
|
||||
wl_output_send_done(c.wl_output);
|
||||
if (c.toplevel && c.toplevel->client->pointer) {
|
||||
wl_pointer_send_leave(c.toplevel->client->pointer, 0, c.toplevel->surface);
|
||||
wl_pointer_send_enter (c.toplevel->client->pointer, 0, c.toplevel->surface, 0, 0);
|
||||
}
|
||||
|
||||
if (c.toplevel && c.toplevel->shell_surface) {
|
||||
wl_shell_surface_send_configure(c.toplevel->shell_surface->shell_surface, 0, width, height);
|
||||
wl_shell_surface_send_ping(c.toplevel->shell_surface->shell_surface, 33231);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void handle_draw_event (void) {
|
||||
c.redraw_needed = true;
|
||||
}
|
||||
@ -296,46 +385,24 @@ static void handle_terminate() {
|
||||
}
|
||||
static struct callbacks callbacks = {&handle_resize_event, &handle_draw_event, &handle_mouse_motion_event, &handle_mouse_button_event, &handle_key_event, &handle_modifiers_changed, &handle_terminate};
|
||||
|
||||
void glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * data);
|
||||
|
||||
static void draw_surface(struct surface *surface) {
|
||||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (surface->buffer);
|
||||
if (shm_buffer == NULL) return;
|
||||
uint32_t width = wl_shm_buffer_get_width (shm_buffer);
|
||||
uint32_t height = wl_shm_buffer_get_height (shm_buffer);
|
||||
void *data = wl_shm_buffer_get_data (shm_buffer);
|
||||
if (data) {
|
||||
glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
wl_buffer_send_release (surface->buffer);
|
||||
}
|
||||
|
||||
if (surface->frame_callback) {
|
||||
wl_callback_send_done (surface->frame_callback, backend_get_timestamp());
|
||||
wl_resource_destroy (surface->frame_callback);
|
||||
surface->frame_callback = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void draw (void) {
|
||||
glClearColor (1, 1, 0, 1);
|
||||
glClearColor (0, 0, 0, 0);
|
||||
glClear (GL_COLOR_BUFFER_BIT);
|
||||
//glLoadIdentity();
|
||||
|
||||
draw_surface(c.toplevel);
|
||||
if (c.renderer && c.toplevel && c.toplevel->texture)
|
||||
texture_draw(c.renderer, c.toplevel->texture, -1.0, -1.0, 1.0, 1.0);
|
||||
|
||||
glFlush ();
|
||||
backend_swap_buffers ();
|
||||
c.redraw_needed = false;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
printf("Starting lorie server\n");
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc == 2 && !strcmp("-f", argv[1])) trace_funcs = true;
|
||||
LOGV("Starting lorie server");
|
||||
signal(SIGSEGV, handler);
|
||||
backend_init (&callbacks);
|
||||
setenv("WAYLAND_DEBUG", "1", 1);
|
||||
//setenv("WAYLAND_DEBUG", "1", 1);
|
||||
memset(&c, 0, sizeof(c));
|
||||
wl_list_init (&c.clients);
|
||||
wl_list_init (&c.surfaces);
|
||||
@ -352,19 +419,22 @@ int main(void) {
|
||||
wl_global_create (c.display, &wl_output_interface, 3, NULL, &wl_output_bind);
|
||||
wl_display_init_shm (c.display);
|
||||
|
||||
c.renderer = renderer_create();
|
||||
|
||||
struct wl_event_loop *event_loop = wl_display_get_event_loop (c.display);
|
||||
int wayland_fd = wl_event_loop_get_fd (event_loop);
|
||||
while (c.running) {
|
||||
wl_event_loop_dispatch (event_loop, 0);
|
||||
backend_dispatch_nonblocking ();
|
||||
wl_display_flush_clients (c.display);
|
||||
if (c.redraw_needed)
|
||||
if (c.redraw_needed) {
|
||||
draw ();
|
||||
}
|
||||
// usleep(50000);
|
||||
|
||||
backend_wait_for_events (wayland_fd);
|
||||
}
|
||||
|
||||
|
||||
wl_display_destroy (c.display);
|
||||
return 0;
|
||||
}
|
||||
|
@ -30,10 +30,12 @@ proxy_srcs = [
|
||||
'renderer.c'
|
||||
]
|
||||
|
||||
add_global_arguments('-finstrument-functions', language : 'c')
|
||||
|
||||
proxy = executable(
|
||||
'proxy',
|
||||
sources: proxy_srcs,
|
||||
include_directories: incdirs,
|
||||
dependencies: [egl, glesv2, libx11, libx11_xcb, wayland_server, libxkbcommon, libxkbcommon_x11],
|
||||
link_args: ['-lm', '-g', '-rdynamic']
|
||||
link_args: ['-O0', '-lm', '-ldl', '-g', '-rdynamic', '-finstrument-functions']
|
||||
)
|
||||
|
209
renderer.c
209
renderer.c
@ -1,17 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#define LOGI(...) (printf("(I): " __VA_ARGS__))
|
||||
#define LOGW(...) (printf("(W): " __VA_ARGS__))
|
||||
#define LOGE(...) (printf("(E): " __VA_ARGS__))
|
||||
|
||||
static GLuint gTextureProgram;
|
||||
static GLuint gvTexturePositionHandle;
|
||||
static GLuint gvTextureTexCoordsHandle;
|
||||
static GLuint gvTextureSamplerHandle;
|
||||
#include "renderer.h"
|
||||
#include "log.h"
|
||||
|
||||
static const char gSimpleVS[] =
|
||||
"attribute vec4 position;\n"
|
||||
@ -31,12 +20,27 @@ static const char gSimpleFS[] =
|
||||
//" gl_FragColor = vec4(outTexCoords.x/outTexCoords.y,outTexCoords.y/outTexCoords.x, 0.0, 0.0);\n"
|
||||
"}\n\n";
|
||||
|
||||
static void checkGlError(const char* op) {
|
||||
static void checkGlError(const char* op, int line) {
|
||||
GLint error;
|
||||
char *desc = NULL;
|
||||
for (error = glGetError(); error; error = glGetError()) {
|
||||
LOGE("after %s() glError (0x%x)\n", op, error);
|
||||
switch (error) {
|
||||
#define E(code) case code: desc = #code; break;
|
||||
E(GL_INVALID_ENUM);
|
||||
E(GL_INVALID_VALUE);
|
||||
E(GL_INVALID_OPERATION);
|
||||
E(GL_STACK_OVERFLOW_KHR);
|
||||
E(GL_STACK_UNDERFLOW_KHR);
|
||||
E(GL_OUT_OF_MEMORY);
|
||||
E(GL_INVALID_FRAMEBUFFER_OPERATION);
|
||||
E(GL_CONTEXT_LOST_KHR);
|
||||
#undef E
|
||||
}
|
||||
LOGE("GL: %s after %s() (line %d)", desc, op, line);
|
||||
}
|
||||
}
|
||||
|
||||
#define checkGlError(op) checkGlError(op, __LINE__)
|
||||
static GLuint loadShader(GLenum shaderType, const char* pSource) {
|
||||
GLuint shader = glCreateShader(shaderType);
|
||||
if (shader) {
|
||||
@ -51,8 +55,7 @@ static GLuint loadShader(GLenum shaderType, const char* pSource) {
|
||||
char* buf = (char*) malloc(infoLen);
|
||||
if (buf) {
|
||||
glGetShaderInfoLog(shader, infoLen, NULL, buf);
|
||||
LOGE("Could not compile shader %d:\n%s\n",
|
||||
shaderType, buf);
|
||||
LOGE("Could not compile shader %d:\n%s\n", shaderType, buf);
|
||||
free(buf);
|
||||
}
|
||||
glDeleteShader(shader);
|
||||
@ -63,7 +66,7 @@ static GLuint loadShader(GLenum shaderType, const char* pSource) {
|
||||
return shader;
|
||||
}
|
||||
|
||||
GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
|
||||
static GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
|
||||
GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
|
||||
if (!vertexShader) {
|
||||
return 0;
|
||||
@ -101,88 +104,108 @@ GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
|
||||
return program;
|
||||
}
|
||||
|
||||
bool setupGraphics(void) {
|
||||
|
||||
gTextureProgram = createProgram(gSimpleVS, gSimpleFS);
|
||||
if (!gTextureProgram) {
|
||||
return false;
|
||||
}
|
||||
gvTexturePositionHandle = glGetAttribLocation(gTextureProgram, "position"); checkGlError("glGetAttribLocation");
|
||||
gvTextureTexCoordsHandle = glGetAttribLocation(gTextureProgram, "texCoords"); checkGlError("glGetAttribLocation");
|
||||
gvTextureSamplerHandle = glGetUniformLocation(gTextureProgram, "texture"); checkGlError("glGetAttribLocation");
|
||||
|
||||
return true;
|
||||
struct renderer *renderer_create(void) {
|
||||
struct renderer* r = calloc(1, sizeof(struct renderer));
|
||||
if (r == NULL) {
|
||||
LOGE("Failed to allocate renderer\n");
|
||||
return NULL;
|
||||
}
|
||||
r->gTextureProgram = createProgram(gSimpleVS, gSimpleFS); checkGlError("glCreateProgram");
|
||||
if (!r->gTextureProgram) {
|
||||
LOGE("GLESv2: Unable to create shader program");
|
||||
renderer_destroy(&r);
|
||||
return NULL;
|
||||
}
|
||||
r->gvPos = (GLuint) glGetAttribLocation(r->gTextureProgram, "position"); checkGlError("glGetAttribLocation");
|
||||
r->gvCoords = (GLuint) glGetAttribLocation(r->gTextureProgram, "texCoords"); checkGlError("glGetAttribLocation");
|
||||
r->gvTextureSamplerHandle = (GLuint) glGetUniformLocation(r->gTextureProgram, "texture"); checkGlError("glGetAttribLocation");
|
||||
return r;
|
||||
}
|
||||
|
||||
const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
|
||||
0.5f, -0.5f };
|
||||
|
||||
#define FLOAT_SIZE_BYTES 4;
|
||||
const GLint TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
|
||||
const GLfloat gTriangleVerticesData[] = {
|
||||
// X, Y, Z, U, V
|
||||
-1.0f, 1.0f, 0, 0.f, 0.f,
|
||||
1.0f, 1.0f, 0, 1.f, 0.f,
|
||||
-1.0f, -1.0f, 0, 0.f, 1.f,
|
||||
1.0f, -1.0f, 0, 1.f, 1.f,
|
||||
};
|
||||
|
||||
void glDrawTex(void) {
|
||||
if (!gTextureProgram) {
|
||||
if(!setupGraphics()) {
|
||||
LOGE("Could not set up graphics.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
glUseProgram(gTextureProgram); checkGlError("glUseProgram");
|
||||
|
||||
glVertexAttribPointer(gvTexturePositionHandle, 3, GL_FLOAT, GL_FALSE,
|
||||
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, gTriangleVerticesData);
|
||||
checkGlError("glVertexAttribPointer");
|
||||
glVertexAttribPointer(gvTextureTexCoordsHandle, 2, GL_FLOAT, GL_FALSE,
|
||||
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, &gTriangleVerticesData[3]);
|
||||
checkGlError("glVertexAttribPointer");
|
||||
glEnableVertexAttribArray(gvTexturePositionHandle);
|
||||
glEnableVertexAttribArray(gvTextureTexCoordsHandle);
|
||||
checkGlError("glEnableVertexAttribArray");
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
checkGlError("glDrawArrays");
|
||||
|
||||
glUseProgram(0); checkGlError("glUseProgram");
|
||||
void renderer_destroy(struct renderer** renderer) {
|
||||
if (!renderer || !(*renderer)) return;
|
||||
|
||||
glUseProgram(0);
|
||||
glDeleteProgram((*renderer)->gTextureProgram);
|
||||
free(*renderer);
|
||||
*renderer = NULL;
|
||||
}
|
||||
|
||||
static void glDrawTexCoords(float x0, float y0, float x1, float y1) {
|
||||
float coords[20] = {
|
||||
x0, -y0, 0.f, 0.f, 0.f,
|
||||
x1, -y0, 0.f, 1.f, 0.f,
|
||||
x0, -y1, 0.f, 0.f, 1.f,
|
||||
x1, -y1, 0.f, 1.f, 1.f
|
||||
};
|
||||
|
||||
glUseProgram(gTextureProgram); checkGlError("glUseProgram");
|
||||
|
||||
glVertexAttribPointer(gvTexturePositionHandle, 3, GL_FLOAT, GL_FALSE, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, coords); checkGlError("glVertexAttribPointer");
|
||||
glVertexAttribPointer(gvTextureTexCoordsHandle, 2, GL_FLOAT, GL_FALSE, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, &coords[3]); checkGlError("glVertexAttribPointer");
|
||||
glEnableVertexAttribArray(gvTexturePositionHandle); checkGlError("glEnableVertexAttribArray");
|
||||
glEnableVertexAttribArray(gvTextureTexCoordsHandle); checkGlError("glEnableVertexAttribArray");
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); checkGlError("glDrawArrays");
|
||||
|
||||
glUseProgram(0); checkGlError("glUseProgram");
|
||||
}
|
||||
|
||||
static GLuint gPixelsTexture;
|
||||
|
||||
void glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * data){
|
||||
if(!gPixelsTexture) glGenTextures(1, &gPixelsTexture);
|
||||
struct texture *texture_create(int width, int height) {
|
||||
if (width <= 0 || height <= 0) return NULL;
|
||||
struct texture* texture = calloc(1, sizeof(struct texture));
|
||||
if (texture == NULL) {
|
||||
LOGE("Failed to allocate renderer\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//LOGD("Creating %dx%d texture", width, height);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, gPixelsTexture);
|
||||
glGenTextures(1, &texture->id);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, GL_RGBA, type, data);
|
||||
glDrawTex();
|
||||
//glDrawTexCoords(-1.0, -1.0, 1.0, 1.0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
texture->width = width;
|
||||
texture->height = height;
|
||||
return texture;
|
||||
}
|
||||
|
||||
void texture_upload(struct texture *texture, void *data) {
|
||||
if (!texture || !data) return;
|
||||
|
||||
//LOGD("Texture uploading");
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
|
||||
#if 1
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->width, texture->height, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
#else
|
||||
int h;
|
||||
for (h=texture->damage.y; h<(texture->damage.y+texture->damage.height); h++) {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, texture->damage.y, texture->width, texture->damage.height, GL_RGBA, GL_UNSIGNED_BYTE, &data[texture->damage.y * texture->width * 4]);
|
||||
texture->damage.x =
|
||||
texture->damage.y =
|
||||
texture->damage.width =
|
||||
texture->damage.height = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void texture_draw(struct renderer* renderer, struct texture *texture, float x0, float y0, float x1, float y1) {
|
||||
if (!renderer || !texture) return;
|
||||
//LOGD("Texture drawing");
|
||||
float coords[20] = {
|
||||
x0, -y0, 0.f, 0.f, 0.f,
|
||||
x1, -y0, 0.f, 1.f, 0.f,
|
||||
x0, -y1, 0.f, 0.f, 1.f,
|
||||
x1, -y1, 0.f, 1.f, 1.f,
|
||||
};
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glUseProgram(renderer->gTextureProgram); checkGlError("glUseProgram");
|
||||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
|
||||
glVertexAttribPointer(renderer->gvPos, 3, GL_FLOAT, GL_FALSE, 20, coords); checkGlError("glVertexAttribPointer");
|
||||
glVertexAttribPointer(renderer->gvCoords, 2, GL_FLOAT, GL_FALSE, 20, &coords[3]); checkGlError("glVertexAttribPointer");
|
||||
glEnableVertexAttribArray(renderer->gvPos); checkGlError("glEnableVertexAttribArray");
|
||||
glEnableVertexAttribArray(renderer->gvCoords); checkGlError("glEnableVertexAttribArray");
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); checkGlError("glDrawArrays");
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glUseProgram(0); checkGlError("glUseProgram");
|
||||
}
|
||||
|
||||
void texture_destroy(struct texture** texture) {
|
||||
if (!texture || !(*texture)) return;
|
||||
//LOGD("Texture destroying");
|
||||
|
||||
glDeleteTextures(1, &(*texture)->id);
|
||||
|
||||
free(*texture);
|
||||
*texture = NULL;
|
||||
}
|
||||
|
29
renderer.h
Normal file
29
renderer.h
Normal file
@ -0,0 +1,29 @@
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h> // GLES error descriotions
|
||||
#include <stdint.h>
|
||||
|
||||
#define min(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
||||
|
||||
struct renderer {
|
||||
GLuint gTextureProgram;
|
||||
GLuint gvPos;
|
||||
GLuint gvCoords;
|
||||
GLuint gvTextureSamplerHandle;
|
||||
};
|
||||
|
||||
struct texture {
|
||||
GLuint id;
|
||||
int width, height;
|
||||
struct {
|
||||
int32_t x, y, width, height;
|
||||
} damage;
|
||||
};
|
||||
|
||||
struct renderer *renderer_create(void);
|
||||
void renderer_destroy(struct renderer** renderer);
|
||||
|
||||
struct texture *texture_create(int width, int height);
|
||||
void texture_upload(struct texture *texture, void *data);
|
||||
void texture_draw(struct renderer* renderer, struct texture *texture, float x0, float y0, float x1, float y1);
|
||||
void texture_destroy(struct texture** texture);
|
@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
export WAYLAND_DEBUG=1
|
||||
export DISPLAY=:1
|
||||
Xwayland $DISPLAY &
|
||||
Xwayland $DISPLAY -shm &
|
||||
sleep 0.3
|
||||
openbox &
|
||||
sleep 0.3
|
||||
|
Loading…
Reference in New Issue
Block a user