From 0edaded06363016fd175bc3b4fbf505eb146ba1f Mon Sep 17 00:00:00 2001 From: Andri Yngvason Date: Thu, 25 Jun 2020 21:28:30 +0000 Subject: [PATCH] Remove dead code --- include/damage.h | 40 --- include/dmabuf.h | 59 ---- include/render.h | 82 ----- meson.build | 9 - src/damage.c | 180 ---------- src/dmabuf.c | 243 -------------- src/main.c | 143 +------- src/render.c | 795 --------------------------------------------- src/screencopy.c | 11 +- test/meson.build | 15 - test/test-damage.c | 104 ------ 11 files changed, 9 insertions(+), 1672 deletions(-) delete mode 100644 include/damage.h delete mode 100644 include/dmabuf.h delete mode 100644 include/render.h delete mode 100644 src/damage.c delete mode 100644 src/dmabuf.c delete mode 100644 src/render.c delete mode 100644 test/meson.build delete mode 100644 test/test-damage.c diff --git a/include/damage.h b/include/damage.h deleted file mode 100644 index f614fd5..0000000 --- a/include/damage.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2020 Andri Yngvason - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#pragma once - -#include -#include - -struct pixman_region16; -struct pixman_box16; - -void damage_check_row(uint8_t* dst, const uint8_t* src, uint32_t width); - -void damage_check_tile_row(struct pixman_region16* damage, - uint8_t* row_buffer, const uint8_t* buffer, - uint32_t y_start, uint32_t width, uint32_t height); - -void damage_check(struct pixman_region16* damage, const uint8_t* buffer, - uint32_t width, uint32_t height, struct pixman_box16* hint); - -int damage_check_async(uint8_t* buffer, uint32_t width, uint32_t height, - struct pixman_box16* hint, - void (*on_done)(struct pixman_region16*, void*), - void* userdata); - -void damage_dump(FILE* stream, struct pixman_region16* damage, - uint32_t width, uint32_t height, uint32_t tile_size); diff --git a/include/dmabuf.h b/include/dmabuf.h deleted file mode 100644 index e3c320f..0000000 --- a/include/dmabuf.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2019 - 2020 Andri Yngvason - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#pragma once - -#include -#include -#include -#include "frame-capture.h" - -struct zwlr_export_dmabuf_manager_v1; -struct zwlr_export_dmabuf_frame_v1; -struct wl_output; -struct aml_timer; - -struct dmabuf_plane { - int fd; - uint32_t offset; - uint32_t size; - uint32_t pitch; - uint64_t modifier; -}; - -struct dmabuf_frame { - uint32_t width; - uint32_t height; - uint32_t format; - - uint32_t n_planes; - struct dmabuf_plane plane[4]; -}; - -struct dmabuf_capture { - struct frame_capture fc; - - struct zwlr_export_dmabuf_manager_v1* manager; - struct zwlr_export_dmabuf_frame_v1* zwlr_frame; - struct dmabuf_frame frame; - uint64_t render_finish_time; - uint64_t start_time; - - struct aml_timer* timer; -}; - -void dmabuf_capture_init(struct dmabuf_capture* self); -void dmabuf_capture_destroy(struct dmabuf_capture* self); diff --git a/include/render.h b/include/render.h deleted file mode 100644 index f11d18e..0000000 --- a/include/render.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2019 Andri Yngvason - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#pragma once - -#include -#include -#include -#include - -struct dmabuf_frame; -struct output; - -enum renderer_input_type { - RENDERER_INPUT_FB, - RENDERER_INPUT_DMABUF, -}; - -struct renderer_fbo { - GLuint rbo; - GLuint fbo; - GLuint tex; -}; - -struct renderer { - EGLDisplay display; - EGLContext context; - - const struct output* output; - - GLint read_format; - GLint read_type; - - struct renderer_fbo frame_fbo[2]; - int frame_index; - - struct renderer_fbo damage_fbo; - - struct { - GLuint program; - GLint u_tex0; - GLint u_proj; - } frame_shader; - - struct { - GLuint program; - GLint u_tex0; - GLint u_tex1; - } damage_shader; -}; - -int renderer_init(struct renderer* self, const struct output* output, - enum renderer_input_type input_type); -void renderer_destroy(struct renderer* self); - -int render_dmabuf(struct renderer* self, struct dmabuf_frame* frame); -int render_framebuffer(struct renderer* self, const void* addr, uint32_t format, - uint32_t width, uint32_t height, uint32_t stride); - -/* Copy a horizontal stripe from the GL frame into a pixel buffer */ -void renderer_read_frame(struct renderer* self, void* dst, uint32_t y, - uint32_t height); - -void renderer_read_damage(struct renderer* self, void* dst, uint32_t y, - uint32_t height); - -void renderer_swap_textures(struct renderer* self); - -void render_damage(struct renderer* self); diff --git a/meson.build b/meson.build index ae669c8..26db574 100644 --- a/meson.build +++ b/meson.build @@ -28,8 +28,6 @@ libm = cc.find_library('m', required: false) librt = cc.find_library('rt', required: false) pixman = dependency('pixman-1') -egl = dependency('egl') -glesv2 = dependency('glesv2') gbm = dependency('gbm') drm = dependency('libdrm') xkbcommon = dependency('xkbcommon') @@ -59,8 +57,6 @@ subdir('protocols') sources = [ 'src/main.c', - 'src/render.c', - 'src/dmabuf.c', 'src/strlcpy.c', 'src/shm.c', 'src/screencopy.c', @@ -71,7 +67,6 @@ sources = [ 'src/smooth.c', 'src/cfg.c', 'src/intset.c', - 'src/damage.c', 'src/buffer.c', 'src/pixels.c', 'src/pixman-renderer.c', @@ -85,8 +80,6 @@ dependencies = [ librt, pixman, aml, - egl, - glesv2, gbm, drm, wayland_client, @@ -124,5 +117,3 @@ executable( include_directories: inc, install: true, ) - -subdir('test') diff --git a/src/damage.c b/src/damage.c deleted file mode 100644 index 87e5a65..0000000 --- a/src/damage.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2020 Andri Yngvason - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define UDIV_UP(a, b) (((a) + (b) - 1) / (b)) - -struct damage_work { - void (*on_done)(struct pixman_region16*, void*); - void* userdata; - uint8_t* buffer; - uint32_t width, height; - struct pixman_region16 damage; -}; - -struct damage_work* damage_work_new(void) -{ - struct damage_work* work = calloc(1, sizeof(*work)); - if (!work) - return NULL; - - pixman_region_init(&work->damage); - - return work; -} - -void damage_work_free(void* ud) -{ - struct damage_work* work = ud; - free(work->buffer); - pixman_region_fini(&work->damage); - free(work); -} - -bool damage_check_32_byte_block(const void* block) -{ - const uint64_t* a = block; - return a[0] || a[1] || a[2] || a[3]; -} - -void damage_check_row(uint8_t* dst, const uint8_t* src, uint32_t width) -{ - uint32_t aligned_width = (width / 32) * 32; - - for (uint32_t x = 0; x < aligned_width; x += 32) - dst[x / 32] |= damage_check_32_byte_block(&src[x]); - - for (uint32_t x = aligned_width; x < width; ++x) - dst[x / 32] |= src[x]; -} - -void damage_check_tile_row(struct pixman_region16* damage, - uint8_t* row_buffer, const uint8_t* buffer, - uint32_t y_start, uint32_t width, uint32_t height) -{ - uint32_t tiled_width = UDIV_UP(width, 32); - - memset(row_buffer, 0, tiled_width); - - for (uint32_t y = y_start; y < y_start + height; ++y) - damage_check_row(row_buffer, buffer + y * width, width); - - for (uint32_t x = 0; x < tiled_width; ++x) - if (row_buffer[x]) - pixman_region_union_rect(damage, damage, - x * 32, y_start, 32, 32); -} - -void damage_check(struct pixman_region16* damage, const uint8_t* buffer, - uint32_t width, uint32_t height, struct pixman_box16* hint) -{ - uint32_t tiled_width = UDIV_UP(width, 32); - uint8_t* row_buffer = malloc(tiled_width); - assert(row_buffer); - - for (uint32_t y = 0; y < height; y += 32) { - uint32_t current_height = MIN(32, height - y); - damage_check_tile_row(damage, row_buffer, buffer, y, width, - current_height); - } - - pixman_region_intersect_rect(damage, damage, 0, 0, width, height); - - free(row_buffer); -} - -static void do_damage_check(void* aml_obj) -{ - struct damage_work* priv = aml_get_userdata(aml_obj); - damage_check(&priv->damage, priv->buffer, priv->width, priv->height, NULL); -} - -static void on_damage_check_done(void* aml_obj) -{ - struct damage_work* priv = aml_get_userdata(aml_obj); - priv->on_done(&priv->damage, priv->userdata); -} - -// TODO: Use the hint -// TODO: Split rows between jobs -// XXX: This takes ownership of the damage buffer -int damage_check_async(uint8_t* buffer, uint32_t width, uint32_t height, - struct pixman_box16* hint, - void (*on_done)(struct pixman_region16*, void*), - void* userdata) -{ - struct damage_work* priv = damage_work_new(); - if (!priv) - return -1; - - priv->buffer = buffer; - priv->width = width; - priv->height = height; - priv->on_done = on_done; - priv->userdata = userdata; - - struct aml_work* work; - work = aml_work_new(do_damage_check, on_damage_check_done, priv, - damage_work_free); - if (!work) - goto oom; - - int rc = aml_start(aml_get_default(), work); - aml_unref(work); - - return rc; - -oom: - damage_work_free(priv); - return -1; -} - -void damage_dump(FILE* stream, struct pixman_region16* damage, - uint32_t width, uint32_t height, uint32_t tile_size) -{ - uint32_t tiled_width = UDIV_UP(width, tile_size); - uint32_t tiled_height = UDIV_UP(height, tile_size); - - fprintf(stream, "\033[2J"); - - for (uint32_t y = 0; y < tiled_height; ++y) { - for (uint32_t x = 0; x < tiled_width; ++x) { - struct pixman_box16 box = { - .x1 = x * tile_size, - .x2 = ((x + 1) * tile_size) - 1, - .y1 = y * tile_size, - .y2 = ((y + 1) * tile_size) - 1, - }; - - pixman_region_overlap_t overlap = - pixman_region_contains_rectangle(damage, &box); - - putc(overlap == PIXMAN_REGION_IN ? 'x' : ' ', stream); - } - putc('\n', stream); - } -} diff --git a/src/dmabuf.c b/src/dmabuf.c deleted file mode 100644 index 9ffd76a..0000000 --- a/src/dmabuf.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2019 - 2020 Andri Yngvason - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "frame-capture.h" -#include "logging.h" -#include "dmabuf.h" -#include "wlr-export-dmabuf-unstable-v1.h" -#include "render.h" -#include "usdt.h" - -#define RATE_LIMIT 30.0 -#define MIN_PERIOD ((uint64_t)(1000.0 / RATE_LIMIT)) - -#define PROCESSING_DURATION_LIMIT 16 /* ms */ - -static int dmabuf_capture_start_now(struct frame_capture* fc, - enum frame_capture_options options); - -static void dmabuf_close_fds(struct dmabuf_capture* self) -{ - for (size_t i = 0; i < self->frame.n_planes; ++i) - close(self->frame.plane[i].fd); - - self->frame.n_planes = 0; -} - -static void dmabuf_capture_stop(struct frame_capture* fc) -{ - struct dmabuf_capture* self = (void*)fc; - - aml_stop(aml_get_default(), self->timer); - - fc->status = CAPTURE_STOPPED; - - if (self->zwlr_frame) { - zwlr_export_dmabuf_frame_v1_destroy(self->zwlr_frame); - self->zwlr_frame = NULL; - } -} - -static void dmabuf_frame_start(void* data, - struct zwlr_export_dmabuf_frame_v1* frame, - uint32_t width, uint32_t height, - uint32_t offset_x, uint32_t offset_y, - uint32_t buffer_flags, uint32_t flags, - uint32_t format, - uint32_t mod_high, uint32_t mod_low, - uint32_t num_objects) -{ - struct dmabuf_capture* self = data; - struct frame_capture* fc = data; - - dmabuf_close_fds(self); - - uint64_t mod = ((uint64_t)mod_high << 32) | (uint64_t)mod_low; - - self->frame.width = width; - self->frame.height = height; - self->frame.n_planes = num_objects; - self->frame.format = format; - - self->frame.plane[0].modifier = mod; - self->frame.plane[1].modifier = mod; - self->frame.plane[2].modifier = mod; - self->frame.plane[3].modifier = mod; - - fc->damage_hint.x = 0; - fc->damage_hint.y = 0; - fc->damage_hint.width = width; - fc->damage_hint.height = height; -} - -static void dmabuf_frame_object(void* data, - struct zwlr_export_dmabuf_frame_v1* frame, - uint32_t index, int32_t fd, uint32_t size, - uint32_t offset, uint32_t stride, - uint32_t plane_index) -{ - struct dmabuf_capture* self = data; - - self->frame.plane[plane_index].fd = fd; - self->frame.plane[plane_index].size = size; - self->frame.plane[plane_index].offset = offset; - self->frame.plane[plane_index].pitch = stride; -} - -static void dmabuf_frame_ready(void* data, - struct zwlr_export_dmabuf_frame_v1* frame, - uint32_t tv_sec_hi, uint32_t tv_sec_lo, - uint32_t tv_nsec) -{ - struct dmabuf_capture* self = data; - struct frame_capture* fc = data; - - struct timespec ts = { - .tv_sec = ((uint64_t)tv_sec_hi << 32) | tv_sec_lo, - .tv_nsec = tv_nsec - }; - - uint64_t precommit_time = timespec_to_ms(&ts); - - DTRACE_PROBE2(wayvnc, dmabuf_frame_ready, self, precommit_time); - - dmabuf_capture_stop(fc); - - fc->status = CAPTURE_DONE; - fc->on_done(fc); - - dmabuf_close_fds(self); - - uint64_t processing_duration = - self->render_finish_time - precommit_time; - - DTRACE_PROBE3(wayvnc, dmabuf_frame_release, self, - self->render_finish_time, processing_duration); - - if (processing_duration > PROCESSING_DURATION_LIMIT) - log_debug("Processing dmabuf took %"PRIu64" ms.\n", - processing_duration); -} - -static void dmabuf_frame_cancel(void* data, - struct zwlr_export_dmabuf_frame_v1* frame, - uint32_t reason) -{ - struct dmabuf_capture* self = data; - struct frame_capture* fc = data; - - DTRACE_PROBE1(wayvnc, dmabuf_frame_cancel, self); - - dmabuf_capture_stop(fc); - fc->status = reason == ZWLR_EXPORT_DMABUF_FRAME_V1_CANCEL_REASON_PERMANENT - ? CAPTURE_FATAL : CAPTURE_FAILED; - - fc->on_done(fc); - - dmabuf_close_fds(self); -} - -static void dmabuf__poll(void* obj) -{ - struct dmabuf_capture* self = aml_get_userdata(obj); - struct frame_capture* fc = (struct frame_capture*)self; - - dmabuf_capture_start_now(fc, 0); -} - -static int dmabuf_capture_start(struct frame_capture* fc, - enum frame_capture_options options) -{ - struct dmabuf_capture* self = (void*)fc; - - if (fc->status == CAPTURE_IN_PROGRESS) - return -1; - - uint64_t now = gettime_ms(); - uint64_t dt = now - self->start_time; - - fc->status = CAPTURE_IN_PROGRESS; - - if (dt < MIN_PERIOD) { - uint64_t time_left = MIN_PERIOD - dt; - aml_set_duration(self->timer, time_left); - return aml_start(aml_get_default(), self->timer); - } - - return dmabuf_capture_start_now(fc, options); -} - -static int dmabuf_capture_start_now(struct frame_capture* fc, - enum frame_capture_options options) -{ - struct dmabuf_capture* self = (void*)fc; - - static const struct zwlr_export_dmabuf_frame_v1_listener - dmabuf_frame_listener = { - .frame = dmabuf_frame_start, - .object = dmabuf_frame_object, - .ready = dmabuf_frame_ready, - .cancel = dmabuf_frame_cancel, - }; - - DTRACE_PROBE1(wayvnc, dmabuf_capture_start, self); - - self->zwlr_frame = - zwlr_export_dmabuf_manager_v1_capture_output(self->manager, - fc->overlay_cursor, - fc->wl_output); - if (!self->zwlr_frame) - return -1; - - self->start_time = gettime_ms(); - - zwlr_export_dmabuf_frame_v1_add_listener(self->zwlr_frame, - &dmabuf_frame_listener, self); - - return 0; -} - -static void dmabuf_capture_render(struct frame_capture* fc, - struct renderer* render, struct nvnc_fb* fb) -{ - struct dmabuf_capture* self = (void*)fc; - render_dmabuf(render, &self->frame); - self->render_finish_time = gettime_ms(); -} - -void dmabuf_capture_init(struct dmabuf_capture* self) -{ - self->timer = aml_timer_new(0, dmabuf__poll, self, NULL); - assert(self->timer); - - self->fc.backend.start = dmabuf_capture_start; - self->fc.backend.stop = dmabuf_capture_stop; - self->fc.backend.render = dmabuf_capture_render; -} - -void dmabuf_capture_destroy(struct dmabuf_capture* self) -{ - aml_stop(aml_get_default(), self->timer); - aml_unref(self->timer); -} diff --git a/src/main.c b/src/main.c index 493ec5e..9a77234 100644 --- a/src/main.c +++ b/src/main.c @@ -28,10 +28,7 @@ #include #include #include -#include #include -#include -#include #include #include #include @@ -41,14 +38,11 @@ #include #include "frame-capture.h" -#include "wlr-export-dmabuf-unstable-v1.h" #include "wlr-screencopy-unstable-v1.h" #include "wlr-virtual-pointer-unstable-v1.h" #include "virtual-keyboard-unstable-v1.h" #include "xdg-output-unstable-v1.h" #include "linux-dmabuf-unstable-v1.h" -#include "render.h" -#include "dmabuf.h" #include "screencopy.h" #include "strlcpy.h" #include "logging.h" @@ -57,7 +51,6 @@ #include "keyboard.h" #include "seat.h" #include "cfg.h" -#include "damage.h" #include "pixman-renderer.h" #include "transform-util.h" #include "damage-refinery.h" @@ -68,12 +61,6 @@ #define UDIV_UP(a, b) (((a) + (b) - 1) / (b)) #define ALIGN_UP(n, a) (UDIV_UP(n, a) * a) -enum frame_capture_backend_type { - FRAME_CAPTURE_BACKEND_NONE = 0, - FRAME_CAPTURE_BACKEND_SCREENCOPY, - FRAME_CAPTURE_BACKEND_DMABUF, -}; - struct wayvnc { bool do_exit; @@ -89,11 +76,9 @@ struct wayvnc { int pointer_manager_version; - struct renderer renderer; const struct output* selected_output; const struct seat* selected_seat; - struct dmabuf_capture dmabuf_backend; struct screencopy screencopy_backend; struct frame_capture* capture_backend; struct pointer pointer_backend; @@ -120,18 +105,6 @@ struct wl_shm* wl_shm = NULL; struct zwp_linux_dmabuf_v1* zwp_linux_dmabuf = NULL; struct gbm_device* gbm_device = NULL; -static enum frame_capture_backend_type -frame_capture_backend_from_string(const char* str) -{ - if (strcmp(str, "screencopy") == 0) - return FRAME_CAPTURE_BACKEND_SCREENCOPY; - - if (strcmp(str, "dmabuf") == 0) - return FRAME_CAPTURE_BACKEND_DMABUF; - - return FRAME_CAPTURE_BACKEND_NONE; -} - static void registry_add(void* data, struct wl_registry* registry, uint32_t id, const char* interface, uint32_t version) @@ -165,14 +138,6 @@ static void registry_add(void* data, struct wl_registry* registry, return; } - if (strcmp(interface, zwlr_export_dmabuf_manager_v1_interface.name) == 0) { - self->dmabuf_backend.manager = - wl_registry_bind(registry, id, - &zwlr_export_dmabuf_manager_v1_interface, - 1); - return; - } - if (strcmp(interface, zwlr_screencopy_manager_v1_interface.name) == 0) { self->screencopy_backend.manager = wl_registry_bind(registry, id, @@ -292,9 +257,6 @@ void wayvnc_destroy(struct wayvnc* self) if (self->screencopy_backend.manager) zwlr_screencopy_manager_v1_destroy(self->screencopy_backend.manager); - if (self->dmabuf_backend.manager) - zwlr_export_dmabuf_manager_v1_destroy(self->dmabuf_backend.manager); - wl_display_disconnect(self->display); } @@ -348,14 +310,11 @@ static int init_wayland(struct wayvnc* self) wl_display_dispatch(self->display); wl_display_roundtrip(self->display); - if (!self->dmabuf_backend.manager && !self->screencopy_backend.manager) { - log_error("Compositor supports neither screencopy nor export-dmabuf! Exiting.\n"); + if (!self->screencopy_backend.manager) { + log_error("Compositor doesn't support screencopy! Exiting.\n"); goto failure; } - self->dmabuf_backend.fc.on_done = on_capture_done; - self->dmabuf_backend.fc.userdata = self; - self->screencopy_backend.frame_capture.on_done = on_capture_done; self->screencopy_backend.frame_capture.userdata = self; @@ -425,16 +384,6 @@ int init_main_loop(struct wayvnc* self) return 0; } -uint32_t fourcc_from_gl_format(uint32_t format) -{ - switch (format) { - case GL_BGRA_EXT: return DRM_FORMAT_XRGB8888; - case GL_RGBA: return DRM_FORMAT_XBGR8888; - } - - return DRM_FORMAT_INVALID; -} - static void on_pointer_event(struct nvnc_client* client, uint16_t x, uint16_t y, enum nvnc_button_mask button_mask) { @@ -534,35 +483,10 @@ static void wayvnc_damage_region(struct wayvnc* self, nvnc_display_damage_region(self->nvnc_display, damage); } -static void wayvnc_damage_whole(struct wayvnc* self) -{ - uint16_t width = nvnc_fb_get_width(self->buffer); - uint16_t height = nvnc_fb_get_height(self->buffer); - - struct pixman_region16 damage; - pixman_region_init_rect(&damage, 0, 0, width, height); - wayvnc_damage_region(self, &damage); - pixman_region_fini(&damage); -} - -static void on_damage_check_done(struct pixman_region16* damage, void* userdata) -{ - struct wayvnc* self = userdata; - - wayvnc_damage_region(self, damage); - - if (wayvnc_start_capture(self, 0) < 0) { - log_error("Failed to start capture. Exiting...\n"); - wayvnc_exit(self); - } -} - void wayvnc_process_frame(struct wayvnc* self) { -// uint32_t format = fourcc_from_gl_format(self->renderer.read_format); uint32_t width = output_get_transformed_width(self->selected_output); uint32_t height = output_get_transformed_height(self->selected_output); - bool is_first_frame = false; if (!self->buffer) { self->buffer = nvnc_fb_new(width, height, DRM_FORMAT_XBGR8888); @@ -571,8 +495,6 @@ void wayvnc_process_frame(struct wayvnc* self) damage_refinery_init(&self->damage_refinery, self->screencopy_backend.back->width, self->screencopy_backend.back->height); - - is_first_frame = true; } else { // TODO: Reallocate assert(width == nvnc_fb_get_width(self->buffer)); @@ -637,7 +559,6 @@ int wayvnc_usage(FILE* stream, int rc) "Usage: wayvnc [options] [address [port]]\n" "\n" " -C,--config= Select a config file.\n" -" -c,--frame-capturing=screencopy|dmabuf Select frame capturing backend.\n" " -o,--output= Select output to capture.\n" " -k,--keyboard= Select keyboard layout.\n" " -s,--seat= Select seat by name.\n" @@ -696,7 +617,6 @@ int main(int argc, char* argv[]) int port = 0; const char* output_name = NULL; - enum frame_capture_backend_type fcbackend = FRAME_CAPTURE_BACKEND_NONE; const char* seat_name = NULL; bool overlay_cursor = false; @@ -706,7 +626,6 @@ int main(int argc, char* argv[]) static const struct option longopts[] = { { "config", required_argument, NULL, 'C' }, - { "frame-capturing", required_argument, NULL, 'c' }, { "output", required_argument, NULL, 'o' }, { "keyboard", required_argument, NULL, 'k' }, { "seat", required_argument, NULL, 's' }, @@ -724,15 +643,6 @@ int main(int argc, char* argv[]) case 'C': cfg_file = optarg; break; - case 'c': - fcbackend = frame_capture_backend_from_string(optarg); - if (fcbackend == FRAME_CAPTURE_BACKEND_NONE) { - fprintf(stderr, "Invalid backend: %s\n\n", - optarg); - - return wayvnc_usage(stderr, 1); - } - break; case 'o': output_name = optarg; break; @@ -821,7 +731,6 @@ int main(int argc, char* argv[]) self.selected_output = out; self.selected_seat = seat; - self.dmabuf_backend.fc.wl_output = out->wl_output; self.screencopy_backend.frame_capture.wl_output = out->wl_output; self.keyboard_backend.virtual_keyboard = @@ -854,16 +763,7 @@ int main(int argc, char* argv[]) if (!gbm_device) goto failure; - enum renderer_input_type renderer_input_type = - fcbackend == FRAME_CAPTURE_BACKEND_DMABUF ? - RENDERER_INPUT_DMABUF : RENDERER_INPUT_FB; - if (renderer_init(&self.renderer, self.selected_output, - renderer_input_type) < 0) { - log_error("Failed to initialise renderer\n"); - goto failure; - } - - struct aml* aml = aml_new(); + struct aml* aml = aml_new(NULL, 0); if (!aml) goto main_loop_failure; @@ -878,36 +778,13 @@ int main(int argc, char* argv[]) if (self.screencopy_backend.manager) screencopy_init(&self.screencopy_backend); - if (self.dmabuf_backend.manager) - dmabuf_capture_init(&self.dmabuf_backend); - - switch (fcbackend) { - case FRAME_CAPTURE_BACKEND_SCREENCOPY: - if (!self.screencopy_backend.manager) { - log_error("screencopy is not supported by compositor\n"); - goto capture_failure; - } - - self.capture_backend = &self.screencopy_backend.frame_capture; - break; - case FRAME_CAPTURE_BACKEND_DMABUF: - if (!self.screencopy_backend.manager) { - log_error("export-dmabuf is not supported by compositor\n"); - goto capture_failure; - } - - self.capture_backend = &self.dmabuf_backend.fc; - break; - case FRAME_CAPTURE_BACKEND_NONE: - if (self.screencopy_backend.manager) - self.capture_backend = &self.screencopy_backend.frame_capture; - else if (self.dmabuf_backend.manager) - self.capture_backend = &self.dmabuf_backend.fc; - else - goto capture_failure; - break; + if (!self.screencopy_backend.manager) { + log_error("screencopy is not supported by compositor\n"); + goto capture_failure; } + self.capture_backend = &self.screencopy_backend.frame_capture; + pixman_region_init(&self.current_damage); self.capture_backend->overlay_cursor = overlay_cursor; @@ -931,13 +808,10 @@ int main(int argc, char* argv[]) nvnc_display_unref(self.nvnc_display); nvnc_close(self.nvnc); - renderer_destroy(&self.renderer); if (zwp_linux_dmabuf) zwp_linux_dmabuf_v1_destroy(zwp_linux_dmabuf); if (self.screencopy_backend.manager) screencopy_destroy(&self.screencopy_backend); - if (self.dmabuf_backend.manager) - dmabuf_capture_destroy(&self.dmabuf_backend); wayvnc_destroy(&self); aml_unref(aml); @@ -948,7 +822,6 @@ capture_failure: nvnc_close(self.nvnc); nvnc_failure: main_loop_failure: - renderer_destroy(&self.renderer); failure: gbm_device_destroy(gbm_device); if (drm_fd >= 0) diff --git a/src/render.c b/src/render.c deleted file mode 100644 index 4fe73e6..0000000 --- a/src/render.c +++ /dev/null @@ -1,795 +0,0 @@ -/* - * Copyright (c) 2019 - 2020 Andri Yngvason - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "logging.h" -#include "render.h" -#include "dmabuf.h" -#include "output.h" -#include "config.h" -#include "usdt.h" - -#define MAYBE_UNUSED __attribute__((unused)) - -#define SHADER_PATH PREFIX "/share/wayvnc/shaders" - -enum { - ATTR_INDEX_POS = 0, - ATTR_INDEX_TEXTURE, -}; - -#define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0])) - -#define XSTR(s) STR(s) -#define STR(s) #s - -#define X_GL_EARLY_EXTENSIONS \ - X(PFNEGLGETPLATFORMDISPLAYEXTPROC, eglGetPlatformDisplayEXT) \ - X(PFNEGLDEBUGMESSAGECONTROLKHRPROC, eglDebugMessageControlKHR) \ - X(PFNGLDEBUGMESSAGECALLBACKKHRPROC, glDebugMessageCallbackKHR) \ - -#define X_GL_LATE_EXTENSIONS \ - X(PFNEGLCREATEIMAGEKHRPROC, eglCreateImageKHR) \ - X(PFNEGLDESTROYIMAGEKHRPROC, eglDestroyImageKHR) \ - X(PFNGLEGLIMAGETARGETTEXTURE2DOESPROC, glEGLImageTargetTexture2DOES) \ - -#define X_GL_EXTENSIONS \ - X_GL_EARLY_EXTENSIONS \ - X_GL_LATE_EXTENSIONS \ - -#define X(type, name) type name; - X_GL_EXTENSIONS -#undef X - -static const float transforms[][4] = { - [WL_OUTPUT_TRANSFORM_NORMAL] = { - 1.0f, 0.0f, - 0.0f, 1.0f, - }, - [WL_OUTPUT_TRANSFORM_90] = { - 0.0f, 1.0f, - -1.0f, 0.0f, - }, - [WL_OUTPUT_TRANSFORM_180] = { - -1.0f, 0.0f, - 0.0f, -1.0f, - }, - [WL_OUTPUT_TRANSFORM_270] = { - 0.0f, -1.0f, - 1.0f, 0.0f, - }, - [WL_OUTPUT_TRANSFORM_FLIPPED] = { - -1.0f, 0.0f, - 0.0f, 1.0f, - }, - [WL_OUTPUT_TRANSFORM_FLIPPED_90] = { - 0.0f, 1.0f, - 1.0f, 0.0f, - }, - [WL_OUTPUT_TRANSFORM_FLIPPED_180] = { - 1.0f, 0.0f, - 0.0f, -1.0f, - }, - [WL_OUTPUT_TRANSFORM_FLIPPED_270] = { - 0.0f, -1.0f, - -1.0f, 0.0f, - }, -}; - -int gl_format_from_fourcc(GLenum* result, uint32_t format) -{ - switch (format) { - case DRM_FORMAT_XRGB8888: - case DRM_FORMAT_ARGB8888: - *result = GL_BGRA_EXT; - return 0; - case DRM_FORMAT_XBGR8888: - case DRM_FORMAT_ABGR8888: - *result = GL_RGBA; - return 0; - } - - return -1; -} - -static inline void* gl_load_single_extension(const char* name) -{ - void* ext = eglGetProcAddress(name); - if (!ext) - log_debug("GL: Failed to load procedure: %s\n", name); - - return ext; -} - -static int gl_load_early_extensions(void) -{ -#define X(type, name) \ - name = gl_load_single_extension(XSTR(name)); \ - if (!name) \ - return -1; - - X_GL_EARLY_EXTENSIONS -#undef X - - return 0; -} - -static int gl_load_late_extensions(void) -{ -#define X(type, name) \ - name = gl_load_single_extension(XSTR(name)); \ - if (!name) \ - return -1; - - X_GL_LATE_EXTENSIONS -#undef X - - return 0; -} - -MAYBE_UNUSED -static void egl_log(EGLenum error, const char* command, EGLint msg_type, - EGLLabelKHR thread, EGLLabelKHR obj, const char *msg) -{ - (void)error; - (void)msg_type; - (void)thread; - (void)obj; - - log_debug("EGL: %s: %s\n", command, msg); -} - -MAYBE_UNUSED -static void gles2_log(GLenum src, GLenum type, GLuint id, GLenum severity, - GLsizei len, const GLchar *msg, const void *user) -{ - (void)src; - (void)type; - (void)id; - (void)severity; - (void)len; - (void)user; - - log_debug("GLES2: %s\n", msg); -} - -static void gl_debug_init() -{ -#ifndef NDEBUG - static const EGLAttrib debug_attribs[] = { - EGL_DEBUG_MSG_CRITICAL_KHR, EGL_TRUE, - EGL_DEBUG_MSG_ERROR_KHR, EGL_TRUE, - EGL_DEBUG_MSG_WARN_KHR, EGL_TRUE, - EGL_DEBUG_MSG_INFO_KHR, EGL_TRUE, - EGL_NONE, - }; - eglDebugMessageControlKHR(egl_log, debug_attribs); - - glEnable(GL_DEBUG_OUTPUT_KHR); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR); - glDebugMessageCallbackKHR(gles2_log, NULL); -#endif -} - -static void gl_shader_log(GLuint shader) -{ - GLint len = 0; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len); - - char* log = malloc(len); - assert(log); - - glGetShaderInfoLog(shader, len, &len, log); - - fwrite(log, 1, len, stderr); - - free(log); -} - -static int gl_load_shader(GLuint* dst, const char* path, const char* source, - GLenum type) -{ - GLuint shader = glCreateShader(type); - - glShaderSource(shader, 1, &source, NULL); - glCompileShader(shader); - - GLint is_compiled = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &is_compiled); - - if (!is_compiled) { - log_error("Failed to compile shader: %s\n", path); - gl_shader_log(shader); - glDeleteShader(shader); - return -1; - } - - *dst = shader; - return 0; -} - -static char* read_file(const char* path) -{ - FILE* stream = fopen(path, "r"); - if (!stream) - return NULL; - - size_t size = 4096; - size_t rsize = 0; - - char* contents = malloc(size); - if (!contents) - goto alloc_failure; - - while (1) { - rsize += fread(contents + rsize, 1, size - rsize, stream); - if (rsize < size) - break; - - size *= 2; - contents = realloc(contents, size); - if (!contents) - goto read_failure; - } - - if (ferror(stream)) - goto read_failure; - - if (rsize == size) { - contents = realloc(contents, size + 1); - if (!contents) - goto read_failure; - } - - contents[rsize] = '\0'; - - fclose(stream); - return contents; - -read_failure: - free(contents); -alloc_failure: - fclose(stream); - return NULL; -} - -static char* read_file_at_path(const char* prefix, const char* file) -{ - char path[256]; - - snprintf(path, sizeof(path), "%s/%s", prefix, file); - path[sizeof(path) - 1] = '\0'; - - return read_file(path); -} - -static int gl_load_shader_from_file(GLuint* dst, const char* file, GLenum type) -{ - char* source = read_file_at_path("shaders", file); - if (!source) - source = read_file_at_path(SHADER_PATH, file); - - if (!source) - return -1; - - int rc = gl_load_shader(dst, file, source, type); - - free(source); - return rc; -} - -static int gl_compile_shader_program(GLuint* dst, const char* vertex_path, - const char* fragment_path) -{ - int rc = -1; - GLuint vertex, fragment; - - if (gl_load_shader_from_file(&vertex, vertex_path, GL_VERTEX_SHADER) < 0) - return -1; - - if (gl_load_shader_from_file(&fragment, fragment_path, - GL_FRAGMENT_SHADER) < 0) - goto fragment_failure; - - GLuint program = glCreateProgram(); - - glAttachShader(program, vertex); - glAttachShader(program, fragment); - - glBindAttribLocation(program, ATTR_INDEX_POS, "pos"); - glBindAttribLocation(program, ATTR_INDEX_TEXTURE, "texture"); - - glLinkProgram(program); - - glDeleteShader(vertex); - glDeleteShader(fragment); - - GLint is_linked = 0; - glGetProgramiv(program, GL_LINK_STATUS, &is_linked); - if (!is_linked) { - log_error("Failed to link shaders %s and %s\n", vertex_path, - fragment_path); - gl_shader_log(program); - glDeleteProgram(program); - goto program_failure; - } - - *dst = program; - rc = 0; -program_failure: - glDeleteShader(fragment); -fragment_failure: - glDeleteShader(vertex); - return rc; -} - -void gl_clear(void) -{ - glClearColor(0.0, 0.0, 0.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT); -} - -void gl_draw(void) -{ - static const GLfloat s_vertices[4][2] = { - { -1.0, 1.0 }, - { 1.0, 1.0 }, - { -1.0, -1.0 }, - { 1.0, -1.0 }, - }; - - static const GLfloat s_positions[4][2] = { - { 0, 0 }, - { 1, 0 }, - { 0, 1 }, - { 1, 1 }, - }; - - gl_clear(); - - glVertexAttribPointer(ATTR_INDEX_POS, 2, GL_FLOAT, GL_FALSE, 0, - s_vertices); - glVertexAttribPointer(ATTR_INDEX_TEXTURE, 2, GL_FLOAT, GL_FALSE, 0, - s_positions); - - glEnableVertexAttribArray(ATTR_INDEX_POS); - glEnableVertexAttribArray(ATTR_INDEX_TEXTURE); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - glDisableVertexAttribArray(ATTR_INDEX_TEXTURE); - glDisableVertexAttribArray(ATTR_INDEX_POS); -} - -void renderer_swap(struct renderer* self) -{ - self->frame_index ^= 1; -} - -void render_frame(struct renderer* self) -{ - renderer_swap(self); - - glBindFramebuffer(GL_FRAMEBUFFER, self->frame_fbo[self->frame_index].fbo); - - glUseProgram(self->frame_shader.program); - - glUniform1i(self->frame_shader.u_tex0, 0); - - const float* proj = transforms[self->output->transform]; - glUniformMatrix2fv(self->frame_shader.u_proj, 1, GL_FALSE, proj); - - gl_draw(); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); -} - -void render_damage(struct renderer* self) -{ - glBindFramebuffer(GL_FRAMEBUFFER, self->damage_fbo.fbo); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, self->frame_fbo[self->frame_index].tex); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, self->frame_fbo[!self->frame_index].tex); - - glUseProgram(self->damage_shader.program); - - glUniform1i(self->damage_shader.u_tex0, 0); - glUniform1i(self->damage_shader.u_tex1, 1); - - gl_draw(); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); -} - -void destroy_fbo(struct renderer_fbo* fbo) -{ - glDeleteFramebuffers(1, &fbo->fbo); - glDeleteRenderbuffers(1, &fbo->rbo); - if (fbo->tex) - glDeleteTextures(1, &fbo->tex); -} - -int create_fbo(struct renderer_fbo* dst, GLint format, uint32_t width, - uint32_t height) -{ - GLuint rbo = 0; - glGenRenderbuffers(1, &rbo); - glBindRenderbuffer(GL_RENDERBUFFER, rbo); - glRenderbufferStorage(GL_RENDERBUFFER, format, width, height); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - - GLuint fbo = 0; - glGenFramebuffers(1, &fbo); - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_RENDERBUFFER, rbo); - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - if (status != GL_FRAMEBUFFER_COMPLETE) { - log_error("Framebuffer incomplete\n"); - return -1; - } - - dst->fbo = fbo; - dst->rbo = rbo; - dst->tex = 0; - - return 0; -} - -int create_textured_fbo(struct renderer_fbo* dst, GLint format, uint32_t width, - uint32_t height) -{ - GLuint tex = 0; - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, - GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glBindTexture(GL_TEXTURE_2D, 0); - - GLuint fbo = 0; - glGenFramebuffers(1, &fbo); - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, tex, 0); - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - if (status != GL_FRAMEBUFFER_COMPLETE) { - log_error("Framebuffer incomplete\n"); - return -1; - } - - dst->fbo = fbo; - dst->rbo = 0; - dst->tex = tex; - - return 0; -} - -void renderer_destroy(struct renderer* self) -{ - glDeleteProgram(self->frame_shader.program); - eglMakeCurrent(self->display, EGL_NO_SURFACE, EGL_NO_SURFACE, - EGL_NO_CONTEXT); - destroy_fbo(&self->frame_fbo[1]); - destroy_fbo(&self->frame_fbo[0]); - eglDestroyContext(self->display, self->context); - eglTerminate(self->display); -} - -int renderer_init(struct renderer* self, const struct output* output, - enum renderer_input_type input_type) -{ - if (!eglBindAPI(EGL_OPENGL_ES_API)) { - log_error("Failed to bind EGL API\n"); - return -1; - } - - if (gl_load_early_extensions() < 0) { - log_error("Failed to load early GL extensions\n"); - return -1; - } - - gl_debug_init(); - - self->display = - eglGetPlatformDisplayEXT(EGL_PLATFORM_SURFACELESS_MESA, - EGL_DEFAULT_DISPLAY, NULL); - if (!self->display) { - log_error("Failed to get EGL display\n"); - return -1; - } - - if (!eglInitialize(self->display, NULL, NULL)) { - log_error("Failed to get initialize EGL\n"); - return -1; - } - - static const EGLint cfg_attr[] = { - EGL_SURFACE_TYPE, 0, - EGL_ALPHA_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_RED_SIZE, 8, - EGL_NONE - }; - - EGLConfig cfg; - EGLint cfg_count; - - if (!eglChooseConfig(self->display, cfg_attr, &cfg, 1, &cfg_count)) { - log_error("Could not choose EGL config\n"); - return -1; - } - - static const EGLint ctx_attr[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE - }; - - self->context = eglCreateContext(self->display, cfg, EGL_NO_CONTEXT, - ctx_attr); - if (!self->context) { - log_error("Failed to create EGL context\n"); - return -1; - } - - if (!eglMakeCurrent(self->display, EGL_NO_SURFACE, EGL_NO_SURFACE, - self->context)) { - log_error("Failed to make EGL context current\n"); - goto make_current_failure; - } - - log_debug("%s\n", glGetString(GL_VERSION)); - - if (gl_load_late_extensions() < 0) { - log_error("Failed to load late GL extensions\n"); - goto late_extension_failure; - } - - uint32_t tf_width = output_get_transformed_width(output); - uint32_t tf_height = output_get_transformed_height(output); - - if (create_textured_fbo(&self->frame_fbo[0], GL_RGBA, tf_width, - tf_height) < 0) { - log_error("Failed to create frame FBO 0\n"); - goto frame_fbo_failure_0; - } - - if (create_textured_fbo(&self->frame_fbo[1], GL_RGBA, tf_width, - tf_height) < 0) { - log_error("Failed to create frame FBO 1\n"); - goto frame_fbo_failure_1; - } - - if (create_fbo(&self->damage_fbo, GL_R8_EXT, tf_width, tf_height) < 0) { - log_error("Failed to create damage FBO\n"); - goto damage_fbo_failure; - } - - glBindFramebuffer(GL_FRAMEBUFFER, self->frame_fbo[0].fbo); - - switch (input_type) { - case RENDERER_INPUT_DMABUF: - if (gl_compile_shader_program(&self->frame_shader.program, - "dmabuf-vertex.glsl", - "dmabuf-fragment.glsl") < 0) - goto frame_shader_failure; - break; - case RENDERER_INPUT_FB: - if (gl_compile_shader_program(&self->frame_shader.program, - "texture-vertex.glsl", - "texture-fragment.glsl") < 0) - goto frame_shader_failure; - break; - } - - if (gl_compile_shader_program(&self->damage_shader.program, - "damage-vertex.glsl", - "damage-fragment.glsl") < 0) - goto damage_shader_failure; - - self->frame_shader.u_tex0 = - glGetUniformLocation(self->frame_shader.program, "u_tex0"); - self->frame_shader.u_proj = - glGetUniformLocation(self->frame_shader.program, "u_proj"); - - self->damage_shader.u_tex0 = - glGetUniformLocation(self->damage_shader.program, "u_tex0"); - self->damage_shader.u_tex1 = - glGetUniformLocation(self->damage_shader.program, "u_tex1"); - - self->output = output; - glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &self->read_format); - glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &self->read_type); - - glViewport(0, 0, - output_get_transformed_width(output), - output_get_transformed_height(output)); - - gl_clear(); - - return 0; - -damage_shader_failure: - glDeleteShader(self->frame_shader.program); -frame_shader_failure: - destroy_fbo(&self->damage_fbo); -damage_fbo_failure: - destroy_fbo(&self->frame_fbo[1]); -frame_fbo_failure_1: - destroy_fbo(&self->frame_fbo[0]); -frame_fbo_failure_0: -late_extension_failure: -make_current_failure: - eglDestroyContext(self->display, self->context); - return -1; -} - -static inline void append_attr(EGLint* dst, int* i, EGLint name, EGLint value) -{ - dst[*i] = name; - i[0] += 1; - dst[*i] = value; - i[0] += 1; -} - -static void dmabuf_attr_append_planes(EGLint* dst, int* i, - struct dmabuf_frame* frame) -{ -#define APPEND_PLANE_ATTR(n) \ - if (frame->n_planes <= n) \ - return; \ -\ - append_attr(dst, i, EGL_DMA_BUF_PLANE##n##_FD_EXT, frame->plane[n].fd); \ - append_attr(dst, i, EGL_DMA_BUF_PLANE##n##_OFFSET_EXT, frame->plane[n].offset); \ - append_attr(dst, i, EGL_DMA_BUF_PLANE##n##_PITCH_EXT, frame->plane[n].pitch); \ - append_attr(dst, i, EGL_DMA_BUF_PLANE##n##_MODIFIER_LO_EXT, frame->plane[n].modifier); \ - append_attr(dst, i, EGL_DMA_BUF_PLANE##n##_MODIFIER_HI_EXT, frame->plane[n].modifier >> 32); \ - - APPEND_PLANE_ATTR(0); - APPEND_PLANE_ATTR(1); - APPEND_PLANE_ATTR(2); - APPEND_PLANE_ATTR(3); -#undef APPEND_PLANE_ATTR -} - -int render_dmabuf(struct renderer* self, struct dmabuf_frame* frame) -{ - DTRACE_PROBE1(wayvnc, render_dmabuf_start, self); - - int index = 0; - EGLint attr[6 + 10 * 4 + 1]; - - if (frame->n_planes == 0) - return -1; - - append_attr(attr, &index, EGL_WIDTH, frame->width); - append_attr(attr, &index, EGL_HEIGHT, frame->height); - append_attr(attr, &index, EGL_LINUX_DRM_FOURCC_EXT, frame->format); - dmabuf_attr_append_planes(attr, &index, frame); - attr[index++] = EGL_NONE; - - EGLImageKHR image = - eglCreateImageKHR(self->display, EGL_NO_CONTEXT, - EGL_LINUX_DMA_BUF_EXT, NULL, attr); - if (!image) - return -1; - - GLuint tex = 0; - glGenTextures(1, &tex); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex); - - glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image); - eglDestroyImageKHR(self->display, image); - - render_frame(self); - glFinish(); - - glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); - glDeleteTextures(1, &tex); - - DTRACE_PROBE(wayvnc, render_dmabuf_end); - return 0; -} - -int render_framebuffer(struct renderer* self, const void* addr, uint32_t format, - uint32_t width, uint32_t height, uint32_t stride) -{ - DTRACE_PROBE1(wayvnc, render_framebuffer_start, self); - - GLuint tex = 0; - glGenTextures(1, &tex); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tex); - - GLenum gl_format; - if (gl_format_from_fourcc(&gl_format, format) < 0) - return -1; - - glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride / 4); - glTexImage2D(GL_TEXTURE_2D, 0, self->read_format, width, height, 0, - gl_format, GL_UNSIGNED_BYTE, addr); - glGenerateMipmap(GL_TEXTURE_2D); - glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0); - - render_frame(self); - - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &tex); - - DTRACE_PROBE(wayvnc, render_framebuffer_end); - return 0; -} - -void renderer_read_pixels(struct renderer* self, void* dst, uint32_t y, - uint32_t height) -{ - assert(y + height <= output_get_transformed_height(self->output)); - - uint32_t width = output_get_transformed_width(self->output); - - GLint read_format, read_type; - glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &read_format); - glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &read_type); - - glFinish(); - - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(0, y, width, height, read_format, read_type, dst); -} - -void renderer_read_frame(struct renderer* self, void* dst, uint32_t y, - uint32_t height) -{ - DTRACE_PROBE3(wayvnc, render_read_frame_start, self, y, height); - glBindFramebuffer(GL_FRAMEBUFFER, self->frame_fbo[self->frame_index].fbo); - renderer_read_pixels(self, dst, y, height); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - DTRACE_PROBE(wayvnc, render_read_frame_end); -} - -void renderer_read_damage(struct renderer* self, void* dst, uint32_t y, - uint32_t height) -{ - DTRACE_PROBE1(wayvnc, render_read_damage_start, self); - glBindFramebuffer(GL_FRAMEBUFFER, self->damage_fbo.fbo); - renderer_read_pixels(self, dst, y, height); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - DTRACE_PROBE(wayvnc, render_read_damage_end); -} diff --git a/src/screencopy.c b/src/screencopy.c index cd59c0f..a906503 100644 --- a/src/screencopy.c +++ b/src/screencopy.c @@ -31,7 +31,6 @@ #include "screencopy.h" #include "smooth.h" #include "time-util.h" -#include "render.h" #include "usdt.h" #define RATE_LIMIT 20.0 // Hz @@ -133,9 +132,9 @@ static void screencopy_flags(void* data, struct zwlr_screencopy_frame_v1* frame, uint32_t flags) { - struct screencopy* self = data; (void)frame; + // TODO // self->buffer->y_inverted = !!(flags & ZWLR_SCREENCOPY_FRAME_V1_FLAGS_Y_INVERT); } @@ -271,14 +270,6 @@ static int screencopy_start(struct frame_capture* fc, static void screencopy_render(struct frame_capture* fc, struct renderer* renderer, struct nvnc_fb* fb) { - /* - uint32_t width = fc->frame_info.width; - uint32_t height = fc->frame_info.height; - uint32_t stride = fc->frame_info.stride; - uint32_t format = fc->frame_info.fourcc_format; - - render_framebuffer(renderer, self->pixels, format, width, height, stride); - */ } void screencopy_init(struct screencopy* self) diff --git a/test/meson.build b/test/meson.build deleted file mode 100644 index 1d44281..0000000 --- a/test/meson.build +++ /dev/null @@ -1,15 +0,0 @@ -test_inc = include_directories('../include') - -test('damage', - executable('test-damage', - [ - 'test-damage.c', - '../src/damage.c', - ], - include_directories: test_inc, - dependencies: [ - pixman, - aml, - ] - ) -) diff --git a/test/test-damage.c b/test/test-damage.c deleted file mode 100644 index 941e89d..0000000 --- a/test/test-damage.c +++ /dev/null @@ -1,104 +0,0 @@ -#include "damage.h" -#include "tst.h" - -#include - -static int test_damage_check_row_aligned(void) -{ - uint32_t width = 32; - uint8_t row[width]; - uint8_t r = 0; - - memset(row, 0, width); - damage_check_row(&r, row, width); - - ASSERT_FALSE(r); - - row[0] = 1; - r = 0; - damage_check_row(&r, row, width); - - ASSERT_TRUE(r); - - return 0; -} - -static int test_damage_check_row_unaligned(void) -{ - uint32_t width = 33; - uint8_t row[width]; - uint8_t r[2] = { 0 }; - - memset(row, 0, width); - damage_check_row(r, row, width); - - ASSERT_FALSE(r[0]); - ASSERT_FALSE(r[1]); - - row[32] = 1; - r[0] = 0; - r[1] = 0; - damage_check_row(r, row, width); - - ASSERT_FALSE(r[0]); - ASSERT_TRUE(r[1]); - - return 0; -} - -static int test_damage_check_tile_row_aligned(void) -{ - uint32_t width = 32; - uint32_t height = 32; - uint8_t tile[width * height]; - struct pixman_region16 damage; - uint8_t row = 0; - pixman_region_init(&damage); - - memset(tile, 0, sizeof(tile)); - damage_check_tile_row(&damage, &row, tile, 0, width, height); - ASSERT_FALSE(pixman_region_not_empty(&damage)); - - row = 0; - pixman_region_clear(&damage); - tile[0] = 1; - damage_check_tile_row(&damage, &row, tile, 0, width, height); - ASSERT_TRUE(pixman_region_not_empty(&damage)); - - pixman_region_fini(&damage); - return 0; -} - -static int test_damage_check_tile_row_unaligned(void) -{ - uint32_t width = 33; - uint32_t height = 32; - uint8_t tile[width * height]; - struct pixman_region16 damage; - uint8_t row[2] = { 0 }; - pixman_region_init(&damage); - - memset(tile, 0, sizeof(tile)); - damage_check_tile_row(&damage, row, tile, 0, width, height); - ASSERT_FALSE(pixman_region_not_empty(&damage)); - - row[0] = 0; - row[1] = 0; - pixman_region_clear(&damage); - tile[32] = 1; - damage_check_tile_row(&damage, row, tile, 0, width, height); - ASSERT_TRUE(pixman_region_not_empty(&damage)); - - pixman_region_fini(&damage); - return 0; -} - -int main() -{ - int r = 0; - RUN_TEST(test_damage_check_row_aligned); - RUN_TEST(test_damage_check_row_unaligned); - RUN_TEST(test_damage_check_tile_row_aligned); - RUN_TEST(test_damage_check_tile_row_unaligned); - return r; -}