summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekka Paalanen <pekka.paalanen@collabora.co.uk>2016-06-01 11:22:51 +0300
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>2016-06-03 10:23:52 +0300
commitca52b31d3f867d9a14b2a3b9fcd4f21aa5fb0a3d (patch)
tree0f62c82235cd2079198b975716b689e2ee76e0cb
parente57056f55c5659eba28c69c31ac89bc9b1e0240e (diff)
Remove Raspberry Pi backend and renderer
This patch completely removes the Raspberry Pi backend and the renderer. The backend and the renderer were written to use the proprietary DispmanX API available only on the Raspberry Pi, to demonstrate what the tiny computer is capable of graphics wise. They were also used to demonstrate how Wayland and Weston in particular could leverage hardware compositing capabilities that are not OpenGL. The backend was first added in e8de35c922871bc5b15fbf0436efa233a6db8e41, in 2012. Since then, the major point has been proven. Over time, support for the rpi-backend diminished, it started to deteriorate and hinder Weston development. On May 11, I tried to ask if anyone actually cared about the rpi-backend, but did not get any votes for keeping it: https://lists.freedesktop.org/archives/wayland-devel/2016-May/028764.html The rpi-backend is a good example of how using an API that is only available for specific hardware, even more so as it is only available with a proprietary driver stack, is not maintainable in the long run. Most developers working on Weston either just cannot, or cannot bother to test things also on the RPi. Breakage creeps in without anyone noticing. If someone actually notices it, fixing it will require a very specific environment to be able to test. Also the quality of the proprietary implementation fluctuated. There are reports that RPi firmware updates randomly broke Weston, and that nowadays it is very hard to find a RPi firmware version that you could expect to work with Weston if Weston itself was not broken. We are not even sure what is broken nowadays. This removal does not leave Raspberry Pi users cold (for long), though. There is serious work going on in implementing a FOSS driver stack for Raspberry Pi, including modern kernel DRM drivers and Mesa drivers. It might not be fully there yet, but the plan is to be able to use the standard DRM-backend of Weston on the RPis. See: http://dri.freedesktop.org/wiki/VC4/ The rpi-backend had its moments. Now, it needs to go. Good riddance! Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Derek Foreman <derekf@osg.samsung.com> Acked-by: Bryce Harrington <bryce@osg.samsung.com> Acked-by: Jonas Ådahl <jadahl@gmail.com> Acked-by: Daniel Stone <daniels@collabora.com>
-rw-r--r--Makefile.am34
-rw-r--r--README2
-rw-r--r--configure.ac18
-rw-r--r--man/weston.ini.man1
-rw-r--r--src/compositor-rpi.c575
-rw-r--r--src/main.c19
-rw-r--r--src/rpi-bcm-stubs.h327
-rw-r--r--src/rpi-renderer.c1830
-rw-r--r--src/rpi-renderer.h52
9 files changed, 0 insertions, 2858 deletions
diff --git a/Makefile.am b/Makefile.am
index 00b74e5d..8ee9c8d6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -328,40 +328,6 @@ nodist_wayland_backend_la_SOURCES = \
protocol/fullscreen-shell-unstable-v1-client-protocol.h
endif
-if ENABLE_RPI_COMPOSITOR
-if INSTALL_RPI_COMPOSITOR
-module_LTLIBRARIES += rpi-backend.la
-else
-noinst_LTLIBRARIES += rpi-backend.la
-endif
-
-rpi_backend_la_LDFLAGS = -module -avoid-version
-rpi_backend_la_LIBADD = $(COMPOSITOR_LIBS) \
- $(RPI_COMPOSITOR_LIBS) \
- $(RPI_BCM_HOST_LIBS) \
- $(INPUT_BACKEND_LIBS) \
- libsession-helper.la \
- libshared.la
-rpi_backend_la_CFLAGS = \
- $(AM_CFLAGS) \
- $(COMPOSITOR_CFLAGS) \
- $(RPI_COMPOSITOR_CFLAGS) \
- $(RPI_BCM_HOST_CFLAGS)
-rpi_backend_la_SOURCES = \
- src/compositor-rpi.c \
- src/rpi-renderer.c \
- src/rpi-renderer.h \
- src/rpi-bcm-stubs.h \
- shared/helpers.h \
- $(INPUT_BACKEND_SOURCES)
-
-if ENABLE_EGL
-rpi_backend_la_LIBADD += $(EGL_LIBS)
-rpi_backend_la_CFLAGS += $(EGL_CFLAGS)
-endif
-
-endif
-
if ENABLE_HEADLESS_COMPOSITOR
module_LTLIBRARIES += headless-backend.la
headless_backend_la_LDFLAGS = -module -avoid-version
diff --git a/README b/README
index 3fdfb37f..110a14bb 100644
--- a/README
+++ b/README
@@ -138,8 +138,6 @@ would be roughly like this:
- xwayland (depends on X11/xcb libs)
-- rpi-backend (depends on DispmanX, libudev, ...)
-
- fbdev-backend (depends on libudev...)
- rdp-backend (depends on freerdp)
diff --git a/configure.ac b/configure.ac
index 87e67fed..525810f1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -208,23 +208,6 @@ if test x$enable_headless_compositor = xyes; then
fi
-AC_ARG_ENABLE(rpi-compositor,
- AS_HELP_STRING([--disable-rpi-compositor],
- [do not build the Raspberry Pi backend]),,
- enable_rpi_compositor=yes)
-AM_CONDITIONAL(ENABLE_RPI_COMPOSITOR, test "x$enable_rpi_compositor" = "xyes")
-have_bcm_host="no"
-if test "x$enable_rpi_compositor" = "xyes"; then
- AC_DEFINE([BUILD_RPI_COMPOSITOR], [1], [Build the compositor for Raspberry Pi])
- PKG_CHECK_MODULES(RPI_COMPOSITOR, [libudev >= 136 mtdev >= 1.1.0])
- PKG_CHECK_MODULES(RPI_BCM_HOST, [bcm_host],
- [have_bcm_host="yes"
- AC_DEFINE([HAVE_BCM_HOST], [1], [have Raspberry Pi BCM headers])],
- [AC_MSG_WARN([Raspberry Pi BCM host libraries not found, will use stubs instead.])])
-fi
-AM_CONDITIONAL(INSTALL_RPI_COMPOSITOR, test "x$have_bcm_host" = "xyes")
-
-
AC_ARG_ENABLE([fbdev-compositor], [ --enable-fbdev-compositor],,
enable_fbdev_compositor=yes)
AM_CONDITIONAL([ENABLE_FBDEV_COMPOSITOR],
@@ -678,7 +661,6 @@ AC_MSG_RESULT([
X11 Compositor ${enable_x11_compositor}
Wayland Compositor ${enable_wayland_compositor}
Headless Compositor ${enable_headless_compositor}
- RPI Compositor ${enable_rpi_compositor}
FBDEV Compositor ${enable_fbdev_compositor}
RDP Compositor ${enable_rdp_compositor}
Screen Sharing ${enable_screen_sharing}
diff --git a/man/weston.ini.man b/man/weston.ini.man
index d7c4a6fe..7aa78105 100644
--- a/man/weston.ini.man
+++ b/man/weston.ini.man
@@ -130,7 +130,6 @@ directory are:
.BR fbdev-backend.so
.BR headless-backend.so
.BR rdp-backend.so
-.BR rpi-backend.so
.BR wayland-backend.so
.BR x11-backend.so
.fi
diff --git a/src/compositor-rpi.c b/src/compositor-rpi.c
deleted file mode 100644
index 75b808ea..00000000
--- a/src/compositor-rpi.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/*
- * Copyright © 2008-2011 Kristian Høgsberg
- * Copyright © 2011 Intel Corporation
- * Copyright © 2012-2013 Raspberry Pi Foundation
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "config.h"
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <libudev.h>
-
-#ifdef HAVE_BCM_HOST
-# include <bcm_host.h>
-#else
-# include "rpi-bcm-stubs.h"
-#endif
-
-#include "shared/helpers.h"
-#include "compositor.h"
-#include "rpi-renderer.h"
-#include "launcher-util.h"
-#include "libinput-seat.h"
-#include "presentation-time-server-protocol.h"
-
-#if 0
-#define DBG(...) \
- weston_log(__VA_ARGS__)
-#else
-#define DBG(...) do {} while (0)
-#endif
-
-struct rpi_backend;
-struct rpi_output;
-
-struct rpi_flippipe {
- int readfd;
- int writefd;
- clockid_t clk_id;
- struct wl_event_source *source;
-};
-
-struct rpi_output {
- struct rpi_backend *backend;
- struct weston_output base;
- int single_buffer;
-
- struct weston_mode mode;
- struct rpi_flippipe flippipe;
-
- DISPMANX_DISPLAY_HANDLE_T display;
-};
-
-struct rpi_seat {
- struct weston_seat base;
- struct wl_list devices_list;
-
- struct udev_monitor *udev_monitor;
- struct wl_event_source *udev_monitor_source;
- char *seat_id;
-};
-
-struct rpi_backend {
- struct weston_backend base;
- struct weston_compositor *compositor;
- uint32_t prev_state;
-
- struct udev *udev;
- struct udev_input input;
- struct wl_listener session_listener;
-
- int single_buffer;
-};
-
-static inline struct rpi_output *
-to_rpi_output(struct weston_output *base)
-{
- return container_of(base, struct rpi_output, base);
-}
-
-static inline struct rpi_seat *
-to_rpi_seat(struct weston_seat *base)
-{
- return container_of(base, struct rpi_seat, base);
-}
-
-static inline struct rpi_backend *
-to_rpi_backend(struct weston_compositor *c)
-{
- return container_of(c->backend, struct rpi_backend, base);
-}
-
-static void
-rpi_flippipe_update_complete(DISPMANX_UPDATE_HANDLE_T update, void *data)
-{
- /* This function runs in a different thread. */
- struct rpi_flippipe *flippipe = data;
- struct timespec ts;
- ssize_t ret;
-
- /* manufacture flip completion timestamp */
- clock_gettime(flippipe->clk_id, &ts);
-
- ret = write(flippipe->writefd, &ts, sizeof ts);
- if (ret != sizeof ts)
- weston_log("ERROR: %s failed to write, ret %zd, errno %d\n",
- __func__, ret, errno);
-}
-
-static int
-rpi_dispmanx_update_submit(DISPMANX_UPDATE_HANDLE_T update,
- struct rpi_output *output)
-{
- /*
- * The callback registered here will eventually be called
- * in a different thread context. Therefore we cannot call
- * the usual functions from rpi_flippipe_update_complete().
- * Instead, we have a pipe for passing the message from the
- * thread, waking up the Weston main event loop, calling
- * rpi_flippipe_handler(), and then ending up in
- * rpi_output_update_complete() in the main thread context,
- * where we can do the frame finishing work.
- */
- return vc_dispmanx_update_submit(update, rpi_flippipe_update_complete,
- &output->flippipe);
-}
-
-static void
-rpi_output_update_complete(struct rpi_output *output,
- const struct timespec *stamp);
-
-static int
-rpi_flippipe_handler(int fd, uint32_t mask, void *data)
-{
- struct rpi_output *output = data;
- ssize_t ret;
- struct timespec ts;
-
- if (mask != WL_EVENT_READABLE)
- weston_log("ERROR: unexpected mask 0x%x in %s\n",
- mask, __func__);
-
- ret = read(fd, &ts, sizeof ts);
- if (ret != sizeof ts) {
- weston_log("ERROR: %s failed to read, ret %zd, errno %d\n",
- __func__, ret, errno);
- }
-
- rpi_output_update_complete(output, &ts);
-
- return 1;
-}
-
-static int
-rpi_flippipe_init(struct rpi_flippipe *flippipe, struct rpi_output *output)
-{
- struct weston_compositor *compositor = output->backend->compositor;
- struct wl_event_loop *loop;
- int fd[2];
-
- if (pipe2(fd, O_CLOEXEC) == -1)
- return -1;
-
- flippipe->readfd = fd[0];
- flippipe->writefd = fd[1];
- flippipe->clk_id = compositor->presentation_clock;
-
- loop = wl_display_get_event_loop(compositor->wl_display);
- flippipe->source = wl_event_loop_add_fd(loop, flippipe->readfd,
- WL_EVENT_READABLE,
- rpi_flippipe_handler, output);
-
- if (!flippipe->source) {
- close(flippipe->readfd);
- close(flippipe->writefd);
- return -1;
- }
-
- return 0;
-}
-
-static void
-rpi_flippipe_release(struct rpi_flippipe *flippipe)
-{
- wl_event_source_remove(flippipe->source);
- close(flippipe->readfd);
- close(flippipe->writefd);
-}
-
-static void
-rpi_output_start_repaint_loop(struct weston_output *output)
-{
- struct timespec ts;
-
- /* XXX: do a phony dispmanx update and trigger on its completion? */
- weston_compositor_read_presentation_clock(output->compositor, &ts);
- weston_output_finish_frame(output, &ts, WP_PRESENTATION_FEEDBACK_INVALID);
-}
-
-static int
-rpi_output_repaint(struct weston_output *base, pixman_region32_t *damage)
-{
- struct rpi_output *output = to_rpi_output(base);
- struct weston_compositor *compositor = output->backend->compositor;
- struct weston_plane *primary_plane = &compositor->primary_plane;
- DISPMANX_UPDATE_HANDLE_T update;
-
- DBG("frame update start\n");
-
- /* Update priority higher than in rpi-renderer's
- * output destroy function, see rpi_output_destroy().
- */
- update = vc_dispmanx_update_start(1);
-
- rpi_renderer_set_update_handle(&output->base, update);
- compositor->renderer->repaint_output(&output->base, damage);
-
- pixman_region32_subtract(&primary_plane->damage,
- &primary_plane->damage, damage);
-
- /* schedule callback to rpi_output_update_complete() */
- rpi_dispmanx_update_submit(update, output);
- DBG("frame update submitted\n");
- return 0;
-}
-
-static void
-rpi_output_update_complete(struct rpi_output *output,
- const struct timespec *stamp)
-{
- uint32_t flags = WP_PRESENTATION_FEEDBACK_KIND_VSYNC |
- WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION;
-
- DBG("frame update complete(%ld.%09ld)\n",
- (long)stamp->tv_sec, (long)stamp->tv_nsec);
- rpi_renderer_finish_frame(&output->base);
- weston_output_finish_frame(&output->base, stamp, flags);
-}
-
-static void
-rpi_output_destroy(struct weston_output *base)
-{
- struct rpi_output *output = to_rpi_output(base);
-
- DBG("%s\n", __func__);
-
- rpi_renderer_output_destroy(base);
-
- /* rpi_renderer_output_destroy() will schedule a removal of
- * all Dispmanx Elements, and wait for the update to complete.
- * Assuming updates are sequential, the wait should guarantee,
- * that any pending rpi_flippipe_update_complete() callbacks
- * have happened already. Therefore we can destroy the flippipe
- * now.
- */
- rpi_flippipe_release(&output->flippipe);
-
- weston_output_destroy(&output->base);
-
- vc_dispmanx_display_close(output->display);
-
- free(output);
-}
-
-static int
-rpi_output_create(struct rpi_backend *backend, uint32_t transform)
-{
- struct rpi_output *output;
- DISPMANX_MODEINFO_T modeinfo;
- int ret;
- float mm_width, mm_height;
-
- output = zalloc(sizeof *output);
- if (output == NULL)
- return -1;
-
- output->backend = backend;
- output->single_buffer = backend->single_buffer;
-
- if (rpi_flippipe_init(&output->flippipe, output) < 0) {
- weston_log("Creating message pipe failed.\n");
- goto out_free;
- }
-
- output->display = vc_dispmanx_display_open(DISPMANX_ID_HDMI);
- if (!output->display) {
- weston_log("Failed to open dispmanx HDMI display.\n");
- goto out_pipe;
- }
-
- ret = vc_dispmanx_display_get_info(output->display, &modeinfo);
- if (ret < 0) {
- weston_log("Failed to get display mode information.\n");
- goto out_dmx_close;
- }
-
- output->base.start_repaint_loop = rpi_output_start_repaint_loop;
- output->base.repaint = rpi_output_repaint;
- output->base.destroy = rpi_output_destroy;
- output->base.assign_planes = NULL;
- output->base.set_backlight = NULL;
- output->base.set_dpms = NULL;
- output->base.switch_mode = NULL;
-
- /* XXX: use tvservice to get information from and control the
- * HDMI and SDTV outputs. See:
- * /opt/vc/include/interface/vmcs_host/vc_tvservice.h
- */
-
- /* only one static mode in list */
- output->mode.flags =
- WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
- output->mode.width = modeinfo.width;
- output->mode.height = modeinfo.height;
- output->mode.refresh = 60000;
- wl_list_init(&output->base.mode_list);
- wl_list_insert(&output->base.mode_list, &output->mode.link);
-
- output->base.current_mode = &output->mode;
- output->base.subpixel = WL_OUTPUT_SUBPIXEL_UNKNOWN;
- output->base.make = "unknown";
- output->base.model = "unknown";
- output->base.name = strdup("rpi");
-
- /* guess 96 dpi */
- mm_width = modeinfo.width * (25.4f / 96.0f);
- mm_height = modeinfo.height * (25.4f / 96.0f);
-
- weston_output_init(&output->base, backend->compositor,
- 0, 0, round(mm_width), round(mm_height),
- transform, 1);
-
- if (rpi_renderer_output_create(&output->base, output->display) < 0)
- goto out_output;
-
- weston_compositor_add_output(backend->compositor, &output->base);
-
- weston_log("Raspberry Pi HDMI output %dx%d px\n",
- output->mode.width, output->mode.height);
- weston_log_continue(STAMP_SPACE "guessing %d Hz and 96 dpi\n",
- output->mode.refresh / 1000);
- weston_log_continue(STAMP_SPACE "orientation: %s\n",
- weston_transform_to_string(output->base.transform));
-
- if (!strncmp(weston_transform_to_string(output->base.transform),
- "flipped", 7))
- weston_log("warning: flipped output transforms may not work\n");
-
- return 0;
-
-out_output:
- weston_output_destroy(&output->base);
-
-out_dmx_close:
- vc_dispmanx_display_close(output->display);
-
-out_pipe:
- rpi_flippipe_release(&output->flippipe);
-
-out_free:
- free(output);
- return -1;
-}
-
-static void
-rpi_backend_destroy(struct weston_compositor *base)
-{
- struct rpi_backend *backend = to_rpi_backend(base);
-
- udev_input_destroy(&backend->input);
-
- /* destroys outputs, too */
- weston_compositor_shutdown(base);
-
- weston_launcher_destroy(base->launcher);
-
- bcm_host_deinit();
- free(backend);
-}
-
-static void
-session_notify(struct wl_listener *listener, void *data)
-{
- struct weston_compositor *compositor = data;
- struct rpi_backend *backend = to_rpi_backend(compositor);
- struct weston_output *output;
-
- if (compositor->session_active) {
- weston_log("activating session\n");
- compositor->state = backend->prev_state;
- weston_compositor_damage_all(compositor);
- udev_input_enable(&backend->input);
- } else {
- weston_log("deactivating session\n");
- udev_input_disable(&backend->input);
-
- backend->prev_state = compositor->state;
- weston_compositor_offscreen(compositor);
-
- /* If we have a repaint scheduled (either from a
- * pending pageflip or the idle handler), make sure we
- * cancel that so we don't try to pageflip when we're
- * vt switched away. The OFFSCREEN state will prevent
- * further attemps at repainting. When we switch
- * back, we schedule a repaint, which will process
- * pending frame callbacks. */
-
- wl_list_for_each(output,
- &compositor->output_list, link) {
- output->repaint_needed = 0;
- }
- };
-}
-
-static void
-rpi_restore(struct weston_compositor *compositor)
-{
- weston_launcher_restore(compositor->launcher);
-}
-
-struct rpi_parameters {
- int tty;
- struct rpi_renderer_parameters renderer;
- uint32_t output_transform;
-};
-
-static struct rpi_backend *
-rpi_backend_create(struct weston_compositor *compositor,
- struct rpi_parameters *param)
-{
- struct rpi_backend *backend;
-
- weston_log("initializing Raspberry Pi backend\n");
-
- backend = zalloc(sizeof *backend);
- if (backend == NULL)
- return NULL;
-
- if (weston_compositor_set_presentation_clock_software(
- compositor) < 0)
- goto out_compositor;
-
- backend->udev = udev_new();
- if (backend->udev == NULL) {
- weston_log("Failed to initialize udev context.\n");
- goto out_compositor;
- }
-
- backend->session_listener.notify = session_notify;
- wl_signal_add(&compositor->session_signal,
- &backend->session_listener);
- compositor->launcher =
- weston_launcher_connect(compositor, param->tty, "seat0", false);
- if (!compositor->launcher) {
- weston_log("Failed to initialize tty.\n");
- goto out_udev;
- }
-
- backend->base.destroy = rpi_backend_destroy;
- backend->base.restore = rpi_restore;
-
- backend->compositor = compositor;
- backend->prev_state = WESTON_COMPOSITOR_ACTIVE;
- backend->single_buffer = param->renderer.single_buffer;
-
- weston_log("Dispmanx planes are %s buffered.\n",
- backend->single_buffer ? "single" : "double");
-
- weston_setup_vt_switch_bindings(compositor);
-
- /*
- * bcm_host_init() creates threads.
- * Therefore we must have all signal handlers set and signals blocked
- * before calling it. Otherwise the signals may end in the bcm
- * threads and cause the default behaviour there. For instance,
- * SIGUSR1 used for VT switching caused Weston to terminate there.
- */
- bcm_host_init();
-
- if (rpi_renderer_create(compositor, &param->renderer) < 0)
- goto out_launcher;
-
- if (rpi_output_create(backend, param->output_transform) < 0)
- goto out_launcher;
-
- if (udev_input_init(&backend->input,
- compositor,
- backend->udev, "seat0") != 0) {
- weston_log("Failed to initialize udev input.\n");
- goto out_launcher;
- }
-
- compositor->backend = &backend->base;
-
- return backend;
-
-out_launcher:
- weston_launcher_destroy(compositor->launcher);
-
-out_udev:
- udev_unref(backend->udev);
-
-out_compositor:
- weston_compositor_shutdown(compositor);
-
- bcm_host_deinit();
- free(backend);
-
- return NULL;
-}
-
-WL_EXPORT int
-backend_init(struct weston_compositor *compositor,
- int *argc, char *argv[],
- struct weston_config *config,
- struct weston_backend_config *config_base)
-{
- const char *transform = "normal";
- struct rpi_backend *b;
-
- struct rpi_parameters param = {
- .tty = 0, /* default to current tty */
- .renderer.single_buffer = 0,
- .output_transform = WL_OUTPUT_TRANSFORM_NORMAL,
- .renderer.opaque_regions = 0,
- };
-
- const struct weston_option rpi_options[] = {
- { WESTON_OPTION_INTEGER, "tty", 0, &param.tty },
- { WESTON_OPTION_BOOLEAN, "single-buffer", 0,
- &param.renderer.single_buffer },
- { WESTON_OPTION_STRING, "transform", 0, &transform },
- { WESTON_OPTION_BOOLEAN, "opaque-regions", 0,
- &param.renderer.opaque_regions },
- };
-
- parse_options(rpi_options, ARRAY_LENGTH(rpi_options), argc, argv);
-
- if (weston_parse_transform(transform, &param.output_transform) < 0)
- weston_log("invalid transform \"%s\"\n", transform);
-
- b = rpi_backend_create(compositor, &param);
- if (b == NULL)
- return -1;
- return 0;
-}
diff --git a/src/main.c b/src/main.c
index 3279ac6a..475c1d0f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -252,9 +252,6 @@ usage(int error_code)
#if defined(BUILD_RDP_COMPOSITOR)
"\t\t\t\trdp-backend.so\n"
#endif
-#if defined(BUILD_RPI_COMPOSITOR) && defined(HAVE_BCM_HOST)
- "\t\t\t\trpi-backend.so\n"
-#endif
#if defined(BUILD_WAYLAND_COMPOSITOR)
"\t\t\t\twayland-backend.so\n"
#endif
@@ -313,18 +310,6 @@ usage(int error_code)
"\n");
#endif
-#if defined(BUILD_RPI_COMPOSITOR) && defined(HAVE_BCM_HOST)
- fprintf(stderr,
- "Options for rpi-backend.so:\n\n"
- " --tty=TTY\t\tThe tty to use\n"
- " --single-buffer\tUse single-buffered Dispmanx elements.\n"
- " --transform=TR\tThe output transformation, TR is one of:\n"
- "\tnormal 90 180 270 flipped flipped-90 flipped-180 flipped-270\n"
- " --opaque-regions\tEnable support for opaque regions, can be "
- "very slow without support in the GPU firmware.\n"
- "\n");
-#endif
-
#if defined(BUILD_WAYLAND_COMPOSITOR)
fprintf(stderr,
"Options for wayland-backend.so:\n\n"
@@ -1264,10 +1249,6 @@ load_backend(struct weston_compositor *compositor, const char *backend,
return load_x11_backend(compositor, backend, argc, argv, config);
else if (strstr(backend, "wayland-backend.so"))
return load_wayland_backend(compositor, backend, argc, argv, config);
-#if 0
- else if (strstr(backend, "rpi-backend.so"))
- return load_rpi_backend(compositor, backend, argc, argv, config);
-#endif
return load_backend_old(compositor, backend, argc, argv, config);
}
diff --git a/src/rpi-bcm-stubs.h b/src/rpi-bcm-stubs.h
deleted file mode 100644
index fa30570d..00000000
--- a/src/rpi-bcm-stubs.h
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
-Copyright (c) 2012, Broadcom Europe Ltd
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the copyright holder nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/*
- * This file provides just enough types and stubs, so that the rpi-backend
- * can be built without the real headers and libraries of the Raspberry Pi.
- *
- * This file CANNOT be used to build a working rpi-backend, it is intended
- * only for build-testing, when the proper headers are not available.
- */
-
-#ifndef RPI_BCM_STUBS
-#define RPI_BCM_STUBS
-
-#include <stdint.h>
-
-/* from /opt/vc/include/bcm_host.h */
-
-static inline void bcm_host_init(void) {}
-static inline void bcm_host_deinit(void) {}
-
-
-/* from /opt/vc/include/interface/vmcs_host/vc_dispservice_defs.h */
-
-#define TRANSFORM_HFLIP (1<<0)
-#define TRANSFORM_VFLIP (1<<1)
-#define TRANSFORM_TRANSPOSE (1<<2)
-
-
-/* from /opt/vc/include/interface/vctypes/vc_display_types.h */
-
-typedef enum
-{
- VCOS_DISPLAY_INPUT_FORMAT_INVALID = 0,
-} DISPLAY_INPUT_FORMAT_T;
-
-/* from /opt/vc/include/interface/vctypes/vc_image_types.h */
-
-typedef struct tag_VC_RECT_T {
- int32_t x;
- int32_t y;
- int32_t width;
- int32_t height;
-} VC_RECT_T;
-
-typedef enum {
- VC_IMAGE_ROT0,
- /* these are not the right values: */
- VC_IMAGE_ROT90,
- VC_IMAGE_ROT180,
- VC_IMAGE_ROT270,
- VC_IMAGE_MIRROR_ROT0,
- VC_IMAGE_MIRROR_ROT90,
- VC_IMAGE_MIRROR_ROT180,
- VC_IMAGE_MIRROR_ROT270,
-} VC_IMAGE_TRANSFORM_T;
-
-typedef enum
-{
- VC_IMAGE_MIN = 0,
- /* these are not the right values: */
- VC_IMAGE_ARGB8888,
- VC_IMAGE_XRGB8888,
- VC_IMAGE_RGB565,
-} VC_IMAGE_TYPE_T;
-
-/* from /opt/vc/include/interface/vmcs_host/vc_dispmanx_types.h */
-
-typedef uint32_t DISPMANX_DISPLAY_HANDLE_T;
-typedef uint32_t DISPMANX_UPDATE_HANDLE_T;
-typedef uint32_t DISPMANX_ELEMENT_HANDLE_T;
-typedef uint32_t DISPMANX_RESOURCE_HANDLE_T;
-typedef uint32_t DISPMANX_PROTECTION_T;
-
-#define DISPMANX_NO_HANDLE 0
-#define DISPMANX_PROTECTION_NONE 0
-#define DISPMANX_ID_HDMI 2
-
-typedef enum {
- /* Bottom 2 bits sets the alpha mode */
- DISPMANX_FLAGS_ALPHA_FROM_SOURCE = 0,
- DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS = 1,
- DISPMANX_FLAGS_ALPHA_FIXED_NON_ZERO = 2,
- DISPMANX_FLAGS_ALPHA_FIXED_EXCEED_0X07 = 3,
-
- DISPMANX_FLAGS_ALPHA_PREMULT = 1 << 16,
- DISPMANX_FLAGS_ALPHA_MIX = 1 << 17
-} DISPMANX_FLAGS_ALPHA_T;
-
-typedef struct {
- DISPMANX_FLAGS_ALPHA_T flags;
- uint32_t opacity;
- DISPMANX_RESOURCE_HANDLE_T mask;
-} VC_DISPMANX_ALPHA_T;
-
-typedef struct {
- int32_t width;
- int32_t height;
- VC_IMAGE_TRANSFORM_T transform;
- DISPLAY_INPUT_FORMAT_T input_format;
-} DISPMANX_MODEINFO_T;
-
-typedef enum {
- DISPMANX_NO_ROTATE = 0,
- DISPMANX_ROTATE_90 = 1,
- DISPMANX_ROTATE_180 = 2,
- DISPMANX_ROTATE_270 = 3,
-
- DISPMANX_FLIP_HRIZ = 1 << 16,
- DISPMANX_FLIP_VERT = 1 << 17
-} DISPMANX_TRANSFORM_T;
-
-typedef struct {
- uint32_t dummy;
-} DISPMANX_CLAMP_T;
-
-typedef void (*DISPMANX_CALLBACK_FUNC_T)(DISPMANX_UPDATE_HANDLE_T u,
- void *arg);
-
-/* from /opt/vc/include/interface/vmcs_host/vc_dispmanx.h */
-
-static inline int
-vc_dispmanx_rect_set(VC_RECT_T *rect, uint32_t x_offset, uint32_t y_offset,
- uint32_t width, uint32_t height)
-{
- rect->x = x_offset;
- rect->y = y_offset;
- rect->width = width;
- rect->height = height;
- return 0;
-}
-
-static inline DISPMANX_RESOURCE_HANDLE_T
-vc_dispmanx_resource_create(VC_IMAGE_TYPE_T type, uint32_t width,
- uint32_t height, uint32_t *native_image_handle)
-{
- return DISPMANX_NO_HANDLE;
-}
-
-static inline int
-vc_dispmanx_resource_write_data(DISPMANX_RESOURCE_HANDLE_T res,
- VC_IMAGE_TYPE_T src_type,
- int src_pitch,
- void *src_address,
- const VC_RECT_T *rect)
-{
- return -1;
-}
-
-static inline int
-vc_dispmanx_resource_write_data_rect(DISPMANX_RESOURCE_HANDLE_T handle,
- VC_IMAGE_TYPE_T src_type,
- int src_pitch,
- void *src_address,
- const VC_RECT_T *src_rect,
- uint32_t dst_x,
- uint32_t dst_y)
-{
- return -1;
-}
-
-static inline int
-vc_dispmanx_resource_read_data(DISPMANX_RESOURCE_HANDLE_T handle,
- const VC_RECT_T *p_rect,
- void *dst_address,
- uint32_t dst_pitch)
-{
- return -1;
-}
-
-static inline int
-vc_dispmanx_resource_delete(DISPMANX_RESOURCE_HANDLE_T res)
-{
- return -1;
-}
-
-static inline DISPMANX_DISPLAY_HANDLE_T
-vc_dispmanx_display_open(uint32_t device)
-{
- return DISPMANX_NO_HANDLE;
-}
-
-static inline int
-vc_dispmanx_display_close(DISPMANX_DISPLAY_HANDLE_T display)
-{
- return -1;
-}
-
-static inline int
-vc_dispmanx_display_get_info(DISPMANX_DISPLAY_HANDLE_T display,
- DISPMANX_MODEINFO_T *pinfo)
-{
- return -1;
-}
-
-static inline DISPMANX_UPDATE_HANDLE_T
-vc_dispmanx_update_start(int32_t priority)
-{
- return DISPMANX_NO_HANDLE;
-}
-
-static inline DISPMANX_ELEMENT_HANDLE_T
-vc_dispmanx_element_add(DISPMANX_UPDATE_HANDLE_T update,
- DISPMANX_DISPLAY_HANDLE_T display,
- int32_t layer,
- const VC_RECT_T *dest_rect,
- DISPMANX_RESOURCE_HANDLE_T src,
- const VC_RECT_T *src_rect,
- DISPMANX_PROTECTION_T protection,
- VC_DISPMANX_ALPHA_T *alpha,
- DISPMANX_CLAMP_T *clamp,
- DISPMANX_TRANSFORM_T transform)
-{
- return DISPMANX_NO_HANDLE;
-}
-
-static inline int
-vc_dispmanx_element_change_source(DISPMANX_UPDATE_HANDLE_T update,
- DISPMANX_ELEMENT_HANDLE_T element,
- DISPMANX_RESOURCE_HANDLE_T src)
-{
- return -1;
-}
-
-static inline int
-vc_dispmanx_element_modified(DISPMANX_UPDATE_HANDLE_T update,
- DISPMANX_ELEMENT_HANDLE_T element,
- const VC_RECT_T *rect)
-{
- return -1;
-}
-
-static inline int
-vc_dispmanx_element_remove(DISPMANX_UPDATE_HANDLE_T update,
- DISPMANX_ELEMENT_HANDLE_T element)
-{
- return -1;
-}
-
-static inline int
-vc_dispmanx_update_submit(DISPMANX_UPDATE_HANDLE_T update,
- DISPMANX_CALLBACK_FUNC_T cb_func, void *cb_arg)
-{
- return -1;
-}
-
-static inline int
-vc_dispmanx_update_submit_sync(DISPMANX_UPDATE_HANDLE_T update)
-{
- return -1;
-}
-
-static inline int
-vc_dispmanx_element_change_attributes(DISPMANX_UPDATE_HANDLE_T update,
- DISPMANX_ELEMENT_HANDLE_T element,
- uint32_t change_flags,
- int32_t layer,
- uint8_t opacity,
- const VC_RECT_T *dest_rect,
- const VC_RECT_T *src_rect,
- DISPMANX_RESOURCE_HANDLE_T mask,
- VC_IMAGE_TRANSFORM_T transform)
-{
- return -1;
-}
-
-static inline int
-vc_dispmanx_snapshot(DISPMANX_DISPLAY_HANDLE_T display,
- DISPMANX_RESOURCE_HANDLE_T snapshot_resource,
- VC_IMAGE_TRANSFORM_T transform)
-{
- return -1;
-}
-
-struct wl_resource;
-static inline DISPMANX_RESOURCE_HANDLE_T
-vc_dispmanx_get_handle_from_wl_buffer(struct wl_resource *_buffer)
-{
- return DISPMANX_NO_HANDLE;
-}
-
-static inline void
-vc_dispmanx_set_wl_buffer_in_use(struct wl_resource *_buffer, int in_use)
-{
-}
-
-static inline int
-vc_dispmanx_element_set_opaque_rect(DISPMANX_UPDATE_HANDLE_T update,
- DISPMANX_ELEMENT_HANDLE_T element,
- const VC_RECT_T *opaque_rect)
-{
- return -1;
-}
-
-/* from /opt/vc/include/EGL/eglplatform.h */
-
-typedef struct {
- DISPMANX_ELEMENT_HANDLE_T element;
- int width;
- int height;
-} EGL_DISPMANX_WINDOW_T;
-
-#endif /* RPI_BCM_STUBS */
diff --git a/src/rpi-renderer.c b/src/rpi-renderer.c
deleted file mode 100644
index 33eb67cc..00000000
--- a/src/rpi-renderer.c
+++ /dev/null
@@ -1,1830 +0,0 @@
-/*
- * Copyright © 2012-2013 Raspberry Pi Foundation
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-#ifdef HAVE_BCM_HOST
-# include <bcm_host.h>
-#else
-# include "rpi-bcm-stubs.h"
-#endif
-
-#include "compositor.h"
-#include "rpi-renderer.h"
-#include "shared/helpers.h"
-
-#ifdef ENABLE_EGL
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include "weston-egl-ext.h"
-#endif
-
-/*
- * Dispmanx API offers alpha-blended overlays for hardware compositing.
- * The final composite consists of dispmanx elements, and their contents:
- * the dispmanx resource assigned to the element. The elements may be
- * scanned out directly, or composited to a temporary surface, depending on
- * how the firmware decides to handle the scene. Updates to multiple elements
- * may be queued in a single dispmanx update object, resulting in atomic and
- * vblank synchronized display updates.
- *
- * To avoid tearing and display artifacts, the current dispmanx resource in a
- * dispmanx element must not be touched. Therefore each element must be
- * double-buffered, using two resources, the front and the back. While a
- * dispmanx update is running, the both resources must be considered in use.
- *
- * A resource may be destroyed only, when the update removing the element has
- * completed. Otherwise you risk showing an incomplete composition.
- */
-
-#ifndef ELEMENT_CHANGE_LAYER
-/* copied from interface/vmcs_host/vc_vchi_dispmanx.h of userland.git */
-#define ELEMENT_CHANGE_LAYER (1<<0)
-#define ELEMENT_CHANGE_OPACITY (1<<1)
-#define ELEMENT_CHANGE_DEST_RECT (1<<2)
-#define ELEMENT_CHANGE_SRC_RECT (1<<3)
-#define ELEMENT_CHANGE_MASK_RESOURCE (1<<4)
-#define ELEMENT_CHANGE_TRANSFORM (1<<5)
-#endif
-
-#if 0
-#define DBG(...) \
- weston_log(__VA_ARGS__)
-#else
-#define DBG(...) do {} while (0)
-#endif
-
-/* If we had a fully featured vc_dispmanx_resource_write_data()... */
-/*#define HAVE_RESOURCE_WRITE_DATA_RECT 1*/
-
-/* If we had a vc_dispmanx_element_set_opaque_rect()... */
-/*#define HAVE_ELEMENT_SET_OPAQUE_RECT 1*/
-
-struct rpi_resource {
- DISPMANX_RESOURCE_HANDLE_T handle;
- int width;
- int height; /* height of the image (valid pixel data) */
- int stride; /* bytes */
- int buffer_height; /* height of the buffer */
- int enable_opaque_regions;
- VC_IMAGE_TYPE_T ifmt;
-};
-
-struct rpir_output;
-
-struct rpir_egl_buffer {
- struct weston_buffer_reference buffer_ref;
- DISPMANX_RESOURCE_HANDLE_T resource_handle;
-};
-
-enum buffer_type {
- BUFFER_TYPE_NULL,
- BUFFER_TYPE_SHM,
- BUFFER_TYPE_EGL
-};
-
-struct rpir_surface {
- struct weston_surface *surface;
-
- struct wl_list views;
- int visible_views;
- int need_swap;
- int single_buffer;
- int enable_opaque_regions;
-
- struct rpi_resource resources[2];
- struct rpi_resource *front;
- struct rpi_resource *back;
- pixman_region32_t prev_damage;
-
- struct rpir_egl_buffer *egl_front;
- struct rpir_egl_buffer *egl_back;
- struct rpir_egl_buffer *egl_old_front;
-
- struct weston_buffer_reference buffer_ref;
- enum buffer_type buffer_type;
-
- struct wl_listener surface_destroy_listener;
-};
-
-struct rpir_view {
- struct rpir_surface *surface;
- struct wl_list surface_link;
- struct weston_view *view;
-
- /* If link is empty, the view is guaranteed to not be on screen,
- * i.e. updates removing Elements have completed.
- */
- struct wl_list link;
-
- DISPMANX_ELEMENT_HANDLE_T handle;
- int layer;
-
- struct wl_listener view_destroy_listener;
-};
-
-struct rpir_output {
- DISPMANX_DISPLAY_HANDLE_T display;
-
- DISPMANX_UPDATE_HANDLE_T update;
-
- /* all Elements currently on screen */
- struct wl_list view_list; /* struct rpir_surface::link */
-
- /* Elements just removed, waiting for update completion */
- struct wl_list view_cleanup_list; /* struct rpir_surface::link */
-
- struct rpi_resource capture_buffer;
- uint8_t *capture_data;
-};
-
-struct rpi_renderer {
- struct weston_renderer base;
-
- int single_buffer;
- int enable_opaque_regions;
-
-#ifdef ENABLE_EGL
- EGLDisplay egl_display;
-
- PFNEGLBINDWAYLANDDISPLAYWL bind_display;
- PFNEGLUNBINDWAYLANDDISPLAYWL unbind_display;
- PFNEGLQUERYWAYLANDBUFFERWL query_buffer;
-#endif
- int has_bind_display;
-};
-
-static int
-rpi_renderer_create_surface(struct weston_surface *base);
-
-static int
-rpi_renderer_create_view(struct weston_view *base);
-
-static void
-rpir_view_handle_view_destroy(struct wl_listener *listener, void *data);
-
-static inline struct rpir_surface *
-to_rpir_surface(struct weston_surface *surface)
-{
- if (!surface->renderer_state)
- rpi_renderer_create_surface(surface);
-
- return surface->renderer_state;
-}
-
-static inline struct rpir_view *
-to_rpir_view(struct weston_view *view)
-{
- if (!view->renderer_state)
- rpi_renderer_create_view(view);
-
- return view->renderer_state;
-}
-
-static inline struct rpir_output *
-to_rpir_output(struct weston_output *output)
-{
- return output->renderer_state;
-}
-
-static inline struct rpi_renderer *
-to_rpi_renderer(struct weston_compositor *compositor)
-{
- return container_of(compositor->renderer, struct rpi_renderer, base);
-}
-
-static inline int
-int_max(int a, int b)
-{
- return a > b ? a : b;
-}
-
-static inline void
-int_swap(int *a, int *b)
-{
- int tmp = *a;
- *a = *b;
- *b = tmp;
-}
-
-static uint8_t
-float2uint8(float f)
-{
- int v = roundf(f * 255.0f);
-
- return v < 0 ? 0 : (v > 255 ? 255 : v);
-}
-
-static void
-rpi_resource_init(struct rpi_resource *resource)
-{
- resource->handle = DISPMANX_NO_HANDLE;
-}
-
-static void
-rpi_resource_release(struct rpi_resource *resource)
-{
- if (resource->handle == DISPMANX_NO_HANDLE)
- return;
-
- vc_dispmanx_resource_delete(resource->handle);
- DBG("resource %p release\n", resource);
- resource->handle = DISPMANX_NO_HANDLE;
-}
-
-static int
-rpi_resource_realloc(struct rpi_resource *resource, VC_IMAGE_TYPE_T ifmt,
- int width, int height, int stride, int buffer_height)
-{
- uint32_t dummy;
-
- if (resource->handle != DISPMANX_NO_HANDLE &&
- resource->width == width &&
- resource->height == height &&
- resource->stride == stride &&
- resource->buffer_height == buffer_height &&
- resource->ifmt == ifmt)
- return 0;
-
- rpi_resource_release(resource);
-
- /* NOTE: if stride is not a multiple of 16 pixels in bytes,
- * the vc_image_* functions may break. Dispmanx elements
- * should be fine, though. Buffer_height probably has similar
- * constraints, too.
- */
- resource->handle =
- vc_dispmanx_resource_create(ifmt,
- width | (stride << 16),
- height | (buffer_height << 16),
- &dummy);
- if (resource->handle == DISPMANX_NO_HANDLE)
- return -1;
-
- resource->width = width;
- resource->height = height;
- resource->stride = stride;
- resource->buffer_height = buffer_height;
- resource->ifmt = ifmt;
- DBG("resource %p alloc\n", resource);
- return 1;
-}
-
-/* A firmware workaround for broken ALPHA_PREMULT + ALPHA_MIX hardware. */
-#define PREMULT_ALPHA_FLAG (1 << 31)
-
-static VC_IMAGE_TYPE_T
-shm_buffer_get_vc_format(struct wl_shm_buffer *buffer)
-{
- switch (wl_shm_buffer_get_format(buffer)) {
- case WL_SHM_FORMAT_XRGB8888:
- return VC_IMAGE_XRGB8888;
- case WL_SHM_FORMAT_ARGB8888:
- return VC_IMAGE_ARGB8888 | PREMULT_ALPHA_FLAG;
- case WL_SHM_FORMAT_RGB565:
- return VC_IMAGE_RGB565;
- default:
- /* invalid format */
- return VC_IMAGE_MIN;
- }
-}
-
-#ifndef HAVE_ELEMENT_SET_OPAQUE_RECT
-static uint32_t *
-apply_opaque_region(struct wl_shm_buffer *buffer,
- pixman_region32_t *opaque_region)
-{
- uint32_t *src, *dst;
- int width;
- int height;
- int stride;
- int x, y;
-
- width = wl_shm_buffer_get_width(buffer);
- height = wl_shm_buffer_get_height(buffer);
- stride = wl_shm_buffer_get_stride(buffer);
- src = wl_shm_buffer_get_data(buffer);
-
- dst = malloc(height * stride);
- if (dst == NULL) {
- weston_log("rpi-renderer error: out of memory\n");
- return NULL;
- }
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- int i = y * stride / 4 + x;
- if (pixman_region32_contains_point (opaque_region, x, y, NULL)) {
- dst[i] = src[i] | 0xff000000;
- } else {
- dst[i] = src[i];
- }
- }
- }
-
- return dst;
-}
-#endif
-
-static int
-rpi_resource_update(struct rpi_resource *resource, struct weston_buffer *buffer,
- pixman_region32_t *region, pixman_region32_t *opaque_region)
-{
- pixman_region32_t write_region;
- pixman_box32_t *r;
- VC_RECT_T rect;
- VC_IMAGE_TYPE_T ifmt;
- uint32_t *pixels;
- int width;
- int height;
- int stride;
- int ret;
- int applied_opaque_region = 0;
-#ifdef HAVE_RESOURCE_WRITE_DATA_RECT
- int n;
-#endif
-
- if (!buffer)
- return -1;
-
- ifmt = shm_buffer_get_vc_format(buffer->shm_buffer);
- width = wl_shm_buffer_get_width(buffer->shm_buffer);
- height = wl_shm_buffer_get_height(buffer->shm_buffer);
- stride = wl_shm_buffer_get_stride(buffer->shm_buffer);
- pixels = wl_shm_buffer_get_data(buffer->shm_buffer);
-
-#ifndef HAVE_ELEMENT_SET_OPAQUE_RECT
- if (pixman_region32_not_empty(opaque_region) &&
- wl_shm_buffer_get_format(buffer->shm_buffer) == WL_SHM_FORMAT_ARGB8888 &&
- resource->enable_opaque_regions) {
- pixels = apply_opaque_region(buffer->shm_buffer, opaque_region);
-
- if (!pixels)
- return -1;
-
- applied_opaque_region = 1;
- }
-#endif
-
- ret = rpi_resource_realloc(resource, ifmt & ~PREMULT_ALPHA_FLAG,
- width, height, stride, height);
- if (ret < 0) {
- if (applied_opaque_region)
- free(pixels);
- return -1;
- }
-
- pixman_region32_init_rect(&write_region, 0, 0, width, height);
- if (ret == 0)
- pixman_region32_intersect(&write_region,
- &write_region, region);
-
- wl_shm_buffer_begin_access(buffer->shm_buffer);
-
-#ifdef HAVE_RESOURCE_WRITE_DATA_RECT
- /* XXX: Can this do a format conversion, so that scanout does not have to? */
- r = pixman_region32_rectangles(&write_region, &n);
- while (n--) {
- vc_dispmanx_rect_set(&rect, r[n].x1, r[n].y1,
- r[n].x2 - r[n].x1, r[n].y2 - r[n].y1);
-
- ret = vc_dispmanx_resource_write_data_rect(resource->handle,
- ifmt, stride,
- pixels, &rect,
- rect.x, rect.y);
- DBG("%s: %p %ux%u@%u,%u, ret %d\n", __func__, resource,
- rect.width, rect.height, rect.x, rect.y, ret);
- if (ret)
- break;
- }
-#else
- /* vc_dispmanx_resource_write_data() ignores ifmt,
- * rect.x, rect.width, and uses stride only for computing
- * the size of the transfer as rect.height * stride.
- * Therefore we can only write rows starting at x=0.
- * To be able to write more than one scanline at a time,
- * the resource must have been created with the same stride
- * as used here, and we must write full scanlines.
- */
-
- r = pixman_region32_extents(&write_region);
- vc_dispmanx_rect_set(&rect, 0, r->y1, width, r->y2 - r->y1);
- ret = vc_dispmanx_resource_write_data(resource->handle,
- ifmt, stride, pixels, &rect);
- DBG("%s: %p %ux%u@%u,%u, ret %d\n", __func__, resource,
- width, r->y2 - r->y1, 0, r->y1, ret);
-#endif
-
- wl_shm_buffer_end_access(buffer->shm_buffer);
-
- pixman_region32_fini(&write_region);
-
- if (applied_opaque_region)
- free(pixels);
-
- return ret ? -1 : 0;
-}
-
-static inline void
-rpi_buffer_egl_lock(struct weston_buffer *buffer)
-{
-#ifdef ENABLE_EGL
- vc_dispmanx_set_wl_buffer_in_use(buffer->resource, 1);
-#endif
-}
-
-static inline void
-rpi_buffer_egl_unlock(struct weston_buffer *buffer)
-{
-#ifdef ENABLE_EGL
- vc_dispmanx_set_wl_buffer_in_use(buffer->resource, 0);
-#endif
-}
-
-static void
-rpir_egl_buffer_destroy(struct rpir_egl_buffer *egl_buffer)
-{
- struct weston_buffer *buffer;
-
- if (egl_buffer == NULL)
- return;
-
- buffer = egl_buffer->buffer_ref.buffer;
- if (buffer == NULL) {
- /* The client has already destroyed the wl_buffer, the
- * compositor has the responsibility to delete the resource.
- */
- vc_dispmanx_resource_delete(egl_buffer->resource_handle);
- } else {
- rpi_buffer_egl_unlock(buffer);
- weston_buffer_reference(&egl_buffer->buffer_ref, NULL);
- }
-
- free(egl_buffer);
-}
-
-static struct rpir_surface *
-rpir_surface_create(struct rpi_renderer *renderer)
-{
- struct rpir_surface *surface;
-
- surface = zalloc(sizeof *surface);
- if (surface == NULL)
- return NULL;
-
- wl_list_init(&surface->views);
- surface->single_buffer = renderer->single_buffer;
- surface->enable_opaque_regions = renderer->enable_opaque_regions;
- rpi_resource_init(&surface->resources[0]);
- rpi_resource_init(&surface->resources[1]);
- surface->front = &surface->resources[0];
- if (surface->single_buffer)
- surface->back = &surface->resources[0];
- else
- surface->back = &surface->resources[1];
-
- surface->front->enable_opaque_regions = renderer->enable_opaque_regions;
- surface->back->enable_opaque_regions = renderer->enable_opaque_regions;
-
- surface->buffer_type = BUFFER_TYPE_NULL;
-
- pixman_region32_init(&surface->prev_damage);
-
- return surface;
-}
-
-static void
-rpir_surface_destroy(struct rpir_surface *surface)
-{
- if (surface->visible_views)
- weston_log("ERROR rpi: destroying on-screen element\n");
-
- assert(wl_list_empty(&surface->views));
-
- if (surface->surface)
- surface->surface->renderer_state = NULL;
-
- pixman_region32_fini(&surface->prev_damage);
- rpi_resource_release(&surface->resources[0]);
- rpi_resource_release(&surface->resources[1]);
- DBG("rpir_surface %p destroyed (%u)\n", surface, surface->visible_views);
-
- rpir_egl_buffer_destroy(surface->egl_back);
- rpir_egl_buffer_destroy(surface->egl_front);
- rpir_egl_buffer_destroy(surface->egl_old_front);
-
- free(surface);
-}
-
-static int
-rpir_surface_damage(struct rpir_surface *surface, struct weston_buffer *buffer,
- pixman_region32_t *damage)
-{
- pixman_region32_t upload;
- int ret;
-
- if (!pixman_region32_not_empty(damage))
- return 0;
-
- DBG("rpir_surface %p update resource %p\n", surface, surface->back);
-
- /* XXX: todo: if no surface->handle, update front buffer directly
- * to avoid creating a new back buffer */
- if (surface->single_buffer) {
- ret = rpi_resource_update(surface->front, buffer, damage,
- &surface->surface->opaque);
- } else {
- pixman_region32_init(&upload);
- pixman_region32_union(&upload, &surface->prev_damage, damage);
- ret = rpi_resource_update(surface->back, buffer, &upload,
- &surface->surface->opaque);
- pixman_region32_fini(&upload);
- }
-
- pixman_region32_copy(&surface->prev_damage, damage);
- surface->need_swap = 1;
-
- return ret;
-}
-
-static struct rpir_view *
-rpir_view_create(struct rpir_surface *surface)
-{
- struct rpir_view *view;
-
- view = zalloc(sizeof *view);
- if (view == NULL)
- return NULL;
-
- view->surface = surface;
- wl_list_insert(&surface->views, &view->surface_link);
-
- wl_list_init(&view->link);
- view->handle = DISPMANX_NO_HANDLE;
-
- return view;
-}
-
-static void
-rpir_view_destroy(struct rpir_view *view)
-{
- wl_list_remove(&view->link);
-
- if (view->handle != DISPMANX_NO_HANDLE) {
- view->surface->visible_views--;
- weston_log("ERROR rpi: destroying on-screen element\n");
- }
-
- if (view->view)
- view->view->renderer_state = NULL;
-
- wl_list_remove(&view->surface_link);
- if (wl_list_empty(&view->surface->views) && view->surface->surface == NULL)
- rpir_surface_destroy(view->surface);
-
- DBG("rpir_view %p destroyed (%d)\n", view, view->handle);
-
- free(view);
-}
-
-static void
-matrix_type_str(struct weston_matrix *matrix, char *buf, int len)
-{
- static const char types[33] = "TSRO";
- unsigned mask = matrix->type;
- int i = 0;
-
- while (mask && i < len - 1) {
- if (mask & (1u << i))
- *buf++ = types[i];
- mask &= ~(1u << i);
- i++;
- }
- *buf = '\0';
-}
-
-static void
-log_print_matrix(struct weston_matrix *matrix)
-{
- char typestr[6];
- float *d = matrix->d;
-
- matrix_type_str(matrix, typestr, sizeof typestr);
- weston_log_continue("%14.6e %14.6e %14.6e %14.6e\n",
- d[0], d[4], d[8], d[12]);
- weston_log_continue("%14.6e %14.6e %14.6e %14.6e\n",
- d[1], d[5], d[9], d[13]);
- weston_log_continue("%14.6e %14.6e %14.6e %14.6e\n",
- d[2], d[6], d[10], d[14]);
- weston_log_continue("%14.6e %14.6e %14.6e %14.6e type: %s\n",
- d[3], d[7], d[11], d[15], typestr);
-}
-
-static void
-warn_bad_matrix(struct weston_matrix *total, struct weston_matrix *output,
- struct weston_matrix *surface)
-{
- static int n_warn;
- char typestr[6];
-
- if (n_warn++ == 10)
- weston_log("%s: not showing more warnings\n", __func__);
-
- if (n_warn > 10)
- return;
-
- weston_log("%s: warning: total transformation is not renderable:\n",
- __func__);
- log_print_matrix(total);
-
- matrix_type_str(surface, typestr, sizeof typestr);
- weston_log_continue("surface matrix type: %s\n", typestr);
- matrix_type_str(output, typestr, sizeof typestr);
- weston_log_continue("output matrix type: %s\n", typestr);
-}
-
-/*#define SURFACE_TRANSFORM */
-
-static int
-rpir_view_compute_rects(struct rpir_view *view,
- VC_RECT_T *src_rect, VC_RECT_T *dst_rect,
- VC_IMAGE_TRANSFORM_T *flipmask)
-{
- struct weston_output *output_base = view->view->surface->output;
- struct weston_matrix matrix = view->view->transform.matrix;
- VC_IMAGE_TRANSFORM_T flipt = 0;
- int src_x, src_y;
- int dst_x, dst_y;
- int src_width, src_height;
- int dst_width, dst_height;
- struct weston_vector p1 = {{ 0.0f, 0.0f, 0.0f, 1.0f }};
- struct weston_vector p2 = {{ 0.0f, 0.0f, 0.0f, 1.0f }};
- int t;
- int over;
-
- /* XXX: take buffer transform into account */
-
- /* src is in 16.16, dst is in 32.0 fixed point.
- * Negative values are not allowed in VC_RECT_T.
- * Clip size to output boundaries, firmware ignores
- * huge elements like 8192x8192.
- */
-
- src_x = 0 << 16;
- src_y = 0 << 16;
-
- if (view->surface->buffer_type == BUFFER_TYPE_EGL) {
- struct weston_buffer *buffer =
- view->surface->egl_front->buffer_ref.buffer;
-
- if (!buffer)
- return -1;
-
- src_width = buffer->width << 16;
- src_height = buffer->height << 16;
- } else {
- src_width = view->surface->front->width << 16;
- src_height = view->surface->front->height << 16;
- }
-
- weston_matrix_multiply(&matrix, &output_base->matrix);
-
-#ifdef SURFACE_TRANSFORM
- if (matrix.type >= WESTON_MATRIX_TRANSFORM_OTHER) {
-#else
- if (matrix.type >= WESTON_MATRIX_TRANSFORM_ROTATE) {
-#endif
- warn_bad_matrix(&matrix, &output_base->matrix,
- &view->view->transform.matrix);
- } else {
- if (matrix.type & WESTON_MATRIX_TRANSFORM_ROTATE) {
- if (fabsf(matrix.d[0]) < 1e-4f &&
- fabsf(matrix.d[5]) < 1e-4f) {
- flipt |= TRANSFORM_TRANSPOSE;
- } else if (fabsf(matrix.d[1]) < 1e-4 &&
- fabsf(matrix.d[4]) < 1e-4) {
- /* no transpose */
- } else {
- warn_bad_matrix(&matrix, &output_base->matrix,
- &view->view->transform.matrix);
- }
- }
- }
-
- p2.f[0] = view->view->surface->width;
- p2.f[1] = view->view->surface->height;
-
- /* transform top-left and bot-right corner into screen coordinates */
- weston_matrix_transform(&matrix, &p1);
- weston_matrix_transform(&matrix, &p2);
-
- /* Compute the destination rectangle on screen, converting
- * negative dimensions to flips.
- */
-
- dst_width = round(p2.f[0] - p1.f[0]);
- if (dst_width < 0) {
- dst_x = round(p2.f[0]);
- dst_width = -dst_width;
-
- if (!(flipt & TRANSFORM_TRANSPOSE))
- flipt |= TRANSFORM_HFLIP;
- else
- flipt |= TRANSFORM_VFLIP;
- } else {
- dst_x = round(p1.f[0]);
- }
-
- dst_height = round(p2.f[1] - p1.f[1]);
- if (dst_height < 0) {
- dst_y = round(p2.f[1]);
- dst_height = -dst_height;
-
- if (!(flipt & TRANSFORM_TRANSPOSE))
- flipt |= TRANSFORM_VFLIP;
- else
- flipt |= TRANSFORM_HFLIP;
- } else {
- dst_y = round(p1.f[1]);
- }
-
- if (dst_width == 0 || dst_height == 0) {
- DBG("ignored, zero surface area before clipping\n");
- return -1;
- }
-
-#ifdef SURFACE_TRANSFORM
- /* Dispmanx works as if you flipped the whole screen, when
- * you flip an element. But, we want to flip an element in place.
- * XXX: fixme
- */
- if (flipt & TRANSFORM_HFLIP)
- dst_x = output_base->width - dst_x;
- if (flipt & TRANSFORM_VFLIP)
- dst_y = output_base->height - dst_y;
- if (flipt & TRANSFORM_TRANSPOSE) {
- int_swap(&dst_x, &dst_y);
- int_swap(&dst_width, &dst_height);
- }
-#else
- switch (output_base->transform) {
- case WL_OUTPUT_TRANSFORM_FLIPPED:
- flipt = TRANSFORM_HFLIP;
- break;
- case WL_OUTPUT_TRANSFORM_NORMAL:
- flipt = 0;
- break;
-
- case WL_OUTPUT_TRANSFORM_FLIPPED_90:
- flipt = TRANSFORM_HFLIP | TRANSFORM_VFLIP | TRANSFORM_TRANSPOSE;
- break;
- case WL_OUTPUT_TRANSFORM_90:
- flipt = TRANSFORM_VFLIP | TRANSFORM_TRANSPOSE;
- break;
- case WL_OUTPUT_TRANSFORM_FLIPPED_180:
- flipt = TRANSFORM_VFLIP;
- break;
- case WL_OUTPUT_TRANSFORM_180:
- flipt = TRANSFORM_HFLIP | TRANSFORM_VFLIP;
- break;
-
- case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- flipt = TRANSFORM_TRANSPOSE;
- break;
- case WL_OUTPUT_TRANSFORM_270:
- flipt = TRANSFORM_HFLIP | TRANSFORM_TRANSPOSE;
- break;
- default:
- break;
- }
-#endif
-
- /* clip destination rectangle to screen dimensions */
-
- if (dst_x < 0) {
- t = (int64_t)dst_x * src_width / dst_width;
- src_width += t;
- dst_width += dst_x;
- src_x -= t;
- dst_x = 0;
- }
-
- if (dst_y < 0) {
- t = (int64_t)dst_y * src_height / dst_height;
- src_height += t;
- dst_height += dst_y;
- src_y -= t;
- dst_y = 0;
- }
-
- over = dst_x + dst_width - output_base->width;
- if (over > 0) {
- t = (int64_t)over * src_width / dst_width;
- src_width -= t;
- dst_width -= over;
- }
-
- over = dst_y + dst_height - output_base->height;
- if (over > 0) {
- t = (int64_t)over * src_height / dst_height;
- src_height -= t;
- dst_height -= over;
- }
-
- src_width = int_max(src_width, 0);
- src_height = int_max(src_height, 0);
-
- DBG("rpir_view %p %dx%d: p1 %f, %f; p2 %f, %f\n", view,
- view->view->surface->width,
- view->view->surface->height,
- p1.f[0], p1.f[1], p2.f[0], p2.f[1]);
- DBG("src rect %d;%d, %d;%d, %d;%dx%d;%d\n",
- src_x >> 16, src_x & 0xffff,
- src_y >> 16, src_y & 0xffff,
- src_width >> 16, src_width & 0xffff,
- src_height >> 16, src_height & 0xffff);
- DBG("dest rect %d, %d, %dx%d%s%s%s\n",
- dst_x, dst_y, dst_width, dst_height,
- (flipt & TRANSFORM_HFLIP) ? " hflip" : "",
- (flipt & TRANSFORM_VFLIP) ? " vflip" : "",
- (flipt & TRANSFORM_TRANSPOSE) ? " transp" : "");
-
- assert(src_x >= 0);
- assert(src_y >= 0);
- assert(dst_x >= 0);
- assert(dst_y >= 0);
-
- if (dst_width < 1 || dst_height < 1) {
- DBG("ignored, zero surface area after clipping\n");
- return -1;
- }
-
- /* EGL buffers will be upside-down related to what DispmanX expects */
- if (view->surface->buffer_type == BUFFER_TYPE_EGL)
- flipt ^= TRANSFORM_VFLIP;
-
- vc_dispmanx_rect_set(src_rect, src_x, src_y, src_width, src_height);
- vc_dispmanx_rect_set(dst_rect, dst_x, dst_y, dst_width, dst_height);
- *flipmask = flipt;
-
- return 0;
-}
-
-static DISPMANX_TRANSFORM_T
-vc_image2dispmanx_transform(VC_IMAGE_TRANSFORM_T t)
-{
- /* XXX: uhh, are these right? */
- switch (t) {
- case VC_IMAGE_ROT0:
- return DISPMANX_NO_ROTATE;
- case VC_IMAGE_MIRROR_ROT0:
- return DISPMANX_FLIP_HRIZ;
- case VC_IMAGE_MIRROR_ROT180:
- return DISPMANX_FLIP_VERT;
- case VC_IMAGE_ROT180:
- return DISPMANX_ROTATE_180;
- case VC_IMAGE_MIRROR_ROT90:
- return DISPMANX_ROTATE_90 | DISPMANX_FLIP_HRIZ;
- case VC_IMAGE_ROT270:
- return DISPMANX_ROTATE_270;
- case VC_IMAGE_ROT90:
- return DISPMANX_ROTATE_90;
- case VC_IMAGE_MIRROR_ROT270:
- return DISPMANX_ROTATE_270 | DISPMANX_FLIP_VERT;
- default:
- assert(0 && "bad VC_IMAGE_TRANSFORM_T");
- return DISPMANX_NO_ROTATE;
- }
-}
-
-static DISPMANX_RESOURCE_HANDLE_T
-rpir_surface_get_resource(struct rpir_surface *surface)
-{
- switch (surface->buffer_type) {
- case BUFFER_TYPE_SHM:
- case BUFFER_TYPE_NULL:
- return surface->front->handle;
- case BUFFER_TYPE_EGL:
- if (surface->egl_front != NULL)
- return surface->egl_front->resource_handle;
- default:
- return DISPMANX_NO_HANDLE;
- }
-}
-
-#ifdef HAVE_ELEMENT_SET_OPAQUE_RECT
-static int
-rpir_surface_set_opaque_rect(struct rpir_surface *surface,
- DISPMANX_UPDATE_HANDLE_T update)
-{
- int ret;
-
- if (pixman_region32_not_empty(&surface->surface->opaque) &&
- surface->opaque_regions) {
- pixman_box32_t *box;
- VC_RECT_T opaque_rect;
-
- box = pixman_region32_extents(&surface->surface->opaque);
- opaque_rect.x = box->x1;
- opaque_rect.y = box->y1;
- opaque_rect.width = box->x2 - box->x1;
- opaque_rect.height = box->y2 - box->y1;
-
- ret = vc_dispmanx_element_set_opaque_rect(update,
- surface->handle,
- &opaque_rect);
- if (ret) {
- weston_log("vc_dispmanx_element_set_opaque_rect failed\n");
- return -1;
- }
- }
-
- return 0;
-}
-#endif
-
-static int
-rpir_view_dmx_add(struct rpir_view *view, struct rpir_output *output,
- DISPMANX_UPDATE_HANDLE_T update, int layer)
-{
- /* Do not use DISPMANX_FLAGS_ALPHA_PREMULT here.
- * If you define PREMULT and ALPHA_MIX, the hardware will not
- * multiply the source color with the element alpha, leading to
- * bad colors. Instead, we define PREMULT during pixel data upload.
- */
- VC_DISPMANX_ALPHA_T alphasetup = {
- DISPMANX_FLAGS_ALPHA_FROM_SOURCE |
- DISPMANX_FLAGS_ALPHA_MIX,
- float2uint8(view->view->alpha), /* opacity 0-255 */
- 0 /* mask resource handle */
- };
- VC_RECT_T dst_rect;
- VC_RECT_T src_rect;
- VC_IMAGE_TRANSFORM_T flipmask;
- int ret;
- DISPMANX_RESOURCE_HANDLE_T resource_handle;
-
- resource_handle = rpir_surface_get_resource(view->surface);
- if (resource_handle == DISPMANX_NO_HANDLE) {
- weston_log("%s: no buffer yet, aborting\n", __func__);
- return 0;
- }
-
- ret = rpir_view_compute_rects(view, &src_rect, &dst_rect, &flipmask);
- if (ret < 0)
- return 0;
-
- view->handle = vc_dispmanx_element_add(
- update,
- output->display,
- layer,
- &dst_rect,
- resource_handle,
- &src_rect,
- DISPMANX_PROTECTION_NONE,
- &alphasetup,
- NULL /* clamp */,
- vc_image2dispmanx_transform(flipmask));
- DBG("rpir_surface %p add %u, alpha %f resource %d\n", view,
- view->handle, view->view->alpha, resource_handle);
-
- if (view->handle == DISPMANX_NO_HANDLE)
- return -1;
-
-#ifdef HAVE_ELEMENT_SET_OPAQUE_RECT
- ret = rpir_surface_set_opaque_rect(surface, update);
- if (ret < 0)
- return -1;
-#endif
-
- view->surface->visible_views++;
-
- return 1;
-}
-
-static void
-rpir_view_dmx_swap(struct rpir_view *view,
- DISPMANX_UPDATE_HANDLE_T update)
-{
- VC_RECT_T rect;
- pixman_box32_t *r;
-
- /* XXX: skip, iff resource was not reallocated, and single-buffering */
- vc_dispmanx_element_change_source(update, view->handle,
- view->surface->front->handle);
-
- /* This is current damage now, after rpir_surface_damage() */
- r = pixman_region32_extents(&view->surface->prev_damage);
-
- vc_dispmanx_rect_set(&rect, r->x1, r->y1,
- r->x2 - r->x1, r->y2 - r->y1);
- vc_dispmanx_element_modified(update, view->handle, &rect);
- DBG("rpir_view %p swap\n", view);
-}
-
-static int
-rpir_view_dmx_move(struct rpir_view *view,
- DISPMANX_UPDATE_HANDLE_T update, int layer)
-{
- uint8_t alpha = float2uint8(view->view->alpha);
- VC_RECT_T dst_rect;
- VC_RECT_T src_rect;
- VC_IMAGE_TRANSFORM_T flipmask;
- int ret;
-
- /* XXX: return early, if all attributes stay the same */
-
- if (view->surface->buffer_type == BUFFER_TYPE_EGL) {
- DISPMANX_RESOURCE_HANDLE_T resource_handle;
-
- resource_handle = rpir_surface_get_resource(view->surface);
- if (resource_handle == DISPMANX_NO_HANDLE) {
- weston_log("%s: no buffer yet, aborting\n", __func__);
- return 0;
- }
-
- vc_dispmanx_element_change_source(update,
- view->handle,
- resource_handle);
- }
-
- ret = rpir_view_compute_rects(view, &src_rect, &dst_rect, &flipmask);
- if (ret < 0)
- return 0;
-
- ret = vc_dispmanx_element_change_attributes(
- update,
- view->handle,
- ELEMENT_CHANGE_LAYER |
- ELEMENT_CHANGE_OPACITY |
- ELEMENT_CHANGE_TRANSFORM |
- ELEMENT_CHANGE_DEST_RECT |
- ELEMENT_CHANGE_SRC_RECT,
- layer,
- alpha,
- &dst_rect,
- &src_rect,
- DISPMANX_NO_HANDLE,
- /* This really is DISPMANX_TRANSFORM_T, no matter
- * what the header says. */
- vc_image2dispmanx_transform(flipmask));
- DBG("rpir_view %p move\n", view);
-
- if (ret)
- return -1;
-
-#ifdef HAVE_ELEMENT_SET_OPAQUE_RECT
- ret = rpir_surface_set_opaque_rect(surface, update);
- if (ret < 0)
- return -1;
-#endif
-
- return 1;
-}
-
-static void
-rpir_view_dmx_remove(struct rpir_view *view,
- DISPMANX_UPDATE_HANDLE_T update)
-{
- if (view->handle == DISPMANX_NO_HANDLE)
- return;
-
- vc_dispmanx_element_remove(update, view->handle);
- DBG("rpir_view %p remove %u\n", view, view->handle);
- view->handle = DISPMANX_NO_HANDLE;
- view->surface->visible_views--;
-}
-
-static void
-rpir_surface_swap_pointers(struct rpir_surface *surface)
-{
- struct rpi_resource *tmp;
-
- if (surface->buffer_type == BUFFER_TYPE_EGL) {
- if (surface->egl_back != NULL) {
- assert(surface->egl_old_front == NULL);
- surface->egl_old_front = surface->egl_front;
- surface->egl_front = surface->egl_back;
- surface->egl_back = NULL;
- DBG("new front %d\n", surface->egl_front->resource_handle);
- }
- } else {
- tmp = surface->front;
- surface->front = surface->back;
- surface->back = tmp;
- DBG("new back %p, new front %p\n", surface->back, surface->front);
- }
-}
-
-static int
-is_view_not_visible(struct weston_view *view)
-{
- /* Return true, if surface is guaranteed to be totally obscured. */
- int ret;
- pixman_region32_t unocc;
-
- pixman_region32_init(&unocc);
- pixman_region32_subtract(&unocc, &view->transform.boundingbox,
- &view->clip);
- ret = !pixman_region32_not_empty(&unocc);
- pixman_region32_fini(&unocc);
-
- return ret;
-}
-
-static void
-rpir_view_update(struct rpir_view *view, struct rpir_output *output,
- DISPMANX_UPDATE_HANDLE_T update, int layer)
-{
- int ret;
- int obscured;
-
- obscured = is_view_not_visible(view->view);
- if (obscured) {
- DBG("rpir_view %p totally obscured.\n", view);
-
- wl_list_remove(&view->link);
- if (view->handle == DISPMANX_NO_HANDLE) {
- wl_list_init(&view->link);
- } else {
- rpir_view_dmx_remove(view, update);
- wl_list_insert(&output->view_cleanup_list,
- &view->link);
- }
-
- goto out;
- }
-
- if (view->handle == DISPMANX_NO_HANDLE) {
- ret = rpir_view_dmx_add(view, output, update, layer);
- if (ret == 0) {
- wl_list_remove(&view->link);
- wl_list_init(&view->link);
- } else if (ret < 0) {
- weston_log("ERROR rpir_view_dmx_add() failed.\n");
- }
- } else {
- if (view->surface->need_swap)
- rpir_view_dmx_swap(view, update);
-
- ret = rpir_view_dmx_move(view, update, layer);
- if (ret == 0) {
- rpir_view_dmx_remove(view, update);
-
- wl_list_remove(&view->link);
- wl_list_insert(&output->view_cleanup_list,
- &view->link);
- } else if (ret < 0) {
- weston_log("ERROR rpir_view_dmx_move() failed.\n");
- }
- }
-
-out:
- view->layer = layer;
-}
-
-static int
-rpi_renderer_read_pixels(struct weston_output *base,
- pixman_format_code_t format, void *pixels,
- uint32_t x, uint32_t y,
- uint32_t width, uint32_t height)
-{
- struct rpir_output *output = to_rpir_output(base);
- struct rpi_resource *buffer = &output->capture_buffer;
- VC_RECT_T rect;
- uint32_t fb_width, fb_height;
- uint32_t dst_pitch;
- uint32_t i;
- int ret;
-
- fb_width = base->current_mode->width;
- fb_height = base->current_mode->height;
-
- DBG("%s(%u, %u, %u, %u), resource %p\n", __func__,
- x, y, width, height, buffer);
-
- if (format != PIXMAN_a8r8g8b8) {
- weston_log("rpi-renderer error: bad read_format\n");
- return -1;
- }
-
- dst_pitch = fb_width * 4;
-
- if (buffer->handle == DISPMANX_NO_HANDLE) {
- free(output->capture_data);
- output->capture_data = NULL;
-
- ret = rpi_resource_realloc(buffer, VC_IMAGE_ARGB8888,
- fb_width, fb_height,
- dst_pitch, fb_height);
- if (ret < 0) {
- weston_log("rpi-renderer error: "
- "allocating read buffer failed\n");
- return -1;
- }
-
- ret = vc_dispmanx_snapshot(output->display, buffer->handle,
- VC_IMAGE_ROT0);
- if (ret) {
- weston_log("rpi-renderer error: "
- "vc_dispmanx_snapshot returned %d\n", ret);
- return -1;
- }
- DBG("%s: snapshot done.\n", __func__);
- }
-
- /*
- * If vc_dispmanx_resource_read_data was able to read sub-rectangles,
- * we could read directly into 'pixels'. But it cannot, it does not
- * use rect.x or rect.width, and does this:
- * host_start = (uint8_t *)dst_address + (dst_pitch * p_rect->y);
- * In other words, it is only good for reading the full buffer in
- * one go.
- */
- vc_dispmanx_rect_set(&rect, 0, 0, fb_width, fb_height);
-
- if (x == 0 && y == 0 && width == fb_width && height == fb_height) {
- ret = vc_dispmanx_resource_read_data(buffer->handle, &rect,
- pixels, dst_pitch);
- if (ret) {
- weston_log("rpi-renderer error: "
- "resource_read_data returned %d\n", ret);
- return -1;
- }
- DBG("%s: full frame done.\n", __func__);
- return 0;
- }
-
- if (!output->capture_data) {
- output->capture_data = malloc(fb_height * dst_pitch);
- if (!output->capture_data) {
- weston_log("rpi-renderer error: "
- "out of memory\n");
- return -1;
- }
-
- ret = vc_dispmanx_resource_read_data(buffer->handle, &rect,
- output->capture_data,
- dst_pitch);
- if (ret) {
- weston_log("rpi-renderer error: "
- "resource_read_data returned %d\n", ret);
- return -1;
- }
- }
-
- for (i = 0; i < height; i++) {
- uint8_t *src = output->capture_data +
- (y + i) * dst_pitch + x * 4;
- uint8_t *dst = (uint8_t *)pixels + i * width * 4;
- memcpy(dst, src, width * 4);
- }
-
- return 0;
-}
-
-static void
-rpir_output_dmx_remove_all(struct rpir_output *output,
- DISPMANX_UPDATE_HANDLE_T update)
-{
- struct rpir_view *view;
-
- while (!wl_list_empty(&output->view_list)) {
- view = container_of(output->view_list.next,
- struct rpir_view, link);
- rpir_view_dmx_remove(view, update);
-
- wl_list_remove(&view->link);
- wl_list_insert(&output->view_cleanup_list, &view->link);
- }
-}
-
-/* Note: this won't work right for multiple outputs. A DispmanX Element
- * is tied to one DispmanX Display, i.e. output.
- */
-static void
-rpi_renderer_repaint_output(struct weston_output *base,
- pixman_region32_t *output_damage)
-{
- struct weston_compositor *compositor = base->compositor;
- struct rpir_output *output = to_rpir_output(base);
- struct weston_view *wv;
- struct rpir_view *view;
- struct wl_list done_list;
- int layer = 1;
-
- assert(output->update != DISPMANX_NO_HANDLE);
-
- rpi_resource_release(&output->capture_buffer);
- free(output->capture_data);
- output->capture_data = NULL;
-
- /* Swap resources on surfaces as needed */
- wl_list_for_each_reverse(wv, &compositor->view_list, link)
- wv->surface->touched = false;
-
- wl_list_for_each_reverse(wv, &compositor->view_list, link) {
- view = to_rpir_view(wv);
-
- if (!wv->surface->touched) {
- wv->surface->touched = true;
-
- if (view->surface->buffer_type == BUFFER_TYPE_EGL ||
- view->surface->need_swap)
- rpir_surface_swap_pointers(view->surface);
- }
-
- if (view->surface->buffer_type == BUFFER_TYPE_EGL) {
- struct weston_buffer *buffer;
- buffer = view->surface->egl_front->buffer_ref.buffer;
- if (buffer != NULL) {
- rpi_buffer_egl_lock(buffer);
- } else {
- weston_log("warning: client destroyed current front buffer\n");
-
- wl_list_remove(&view->link);
- if (view->handle == DISPMANX_NO_HANDLE) {
- wl_list_init(&view->link);
- } else {
- rpir_view_dmx_remove(view, output->update);
- wl_list_insert(&output->view_cleanup_list,
- &view->link);
- }
- }
- }
- }
-
- /* update all renderable surfaces */
- wl_list_init(&done_list);
- wl_list_for_each_reverse(wv, &compositor->view_list, link) {
- if (wv->plane != &compositor->primary_plane)
- continue;
-
- view = to_rpir_view(wv);
- assert(!wl_list_empty(&view->link) ||
- view->handle == DISPMANX_NO_HANDLE);
-
- wl_list_remove(&view->link);
- wl_list_insert(&done_list, &view->link);
- rpir_view_update(view, output, output->update, layer++);
- }
-
- /* Mark all surfaces as swapped */
- wl_list_for_each_reverse(wv, &compositor->view_list, link)
- to_rpir_surface(wv->surface)->need_swap = 0;
-
- /* Remove all surfaces that are still on screen, but were
- * not rendered this time.
- */
- rpir_output_dmx_remove_all(output, output->update);
-
- wl_list_insert_list(&output->view_list, &done_list);
- output->update = DISPMANX_NO_HANDLE;
-
- /* The frame_signal is emitted in rpi_renderer_finish_frame(),
- * so that the firmware can capture the up-to-date contents.
- */
- pixman_region32_copy(&base->previous_damage, output_damage);
-}
-
-static void
-rpi_renderer_flush_damage(struct weston_surface *base)
-{
- /* Called for every surface just before repainting it, if
- * having an shm buffer.
- */
- struct rpir_surface *surface = to_rpir_surface(base);
- struct weston_buffer *buffer = surface->buffer_ref.buffer;
- int ret;
-
- assert(buffer);
- assert(wl_shm_buffer_get(buffer->resource));
-
- ret = rpir_surface_damage(surface, buffer, &base->damage);
- if (ret)
- weston_log("%s error: updating Dispmanx resource failed.\n",
- __func__);
-
- weston_buffer_reference(&surface->buffer_ref, NULL);
-}
-
-static void
-rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer)
-{
- /* Called every time a client commits an attach. */
- struct rpir_surface *surface = to_rpir_surface(base);
-
- assert(surface);
- if (!surface)
- return;
-
- if (surface->buffer_type == BUFFER_TYPE_SHM) {
- if (!surface->single_buffer)
- /* XXX: need to check if in middle of update */
- rpi_resource_release(surface->back);
-
- if (!surface->visible_views)
- /* XXX: cannot do this, if middle of an update */
- rpi_resource_release(surface->front);
-
- weston_buffer_reference(&surface->buffer_ref, NULL);
- }
-
- /* If buffer is NULL, Weston core unmaps the surface, the surface
- * will not appear in repaint list, and so rpi_renderer_repaint_output
- * will remove the DispmanX element. Later, for SHM, also the front
- * buffer will be released in the cleanup_list processing.
- */
- if (!buffer)
- return;
-
- if (wl_shm_buffer_get(buffer->resource)) {
- surface->buffer_type = BUFFER_TYPE_SHM;
- buffer->shm_buffer = wl_shm_buffer_get(buffer->resource);
- buffer->width = wl_shm_buffer_get_width(buffer->shm_buffer);
- buffer->height = wl_shm_buffer_get_height(buffer->shm_buffer);
-
- weston_buffer_reference(&surface->buffer_ref, buffer);
- } else {
-#if ENABLE_EGL
- struct rpi_renderer *renderer = to_rpi_renderer(base->compositor);
- struct wl_resource *wl_resource = buffer->resource;
-
- if (!renderer->has_bind_display ||
- !renderer->query_buffer(renderer->egl_display,
- wl_resource,
- EGL_WIDTH, &buffer->width)) {
- weston_log("unhandled buffer type!\n");
- weston_buffer_reference(&surface->buffer_ref, NULL);
- surface->buffer_type = BUFFER_TYPE_NULL;
- }
-
- renderer->query_buffer(renderer->egl_display,
- wl_resource,
- EGL_HEIGHT, &buffer->height);
-
- surface->buffer_type = BUFFER_TYPE_EGL;
-
- if (surface->egl_back == NULL)
- surface->egl_back = zalloc(sizeof *surface->egl_back);
-
- weston_buffer_reference(&surface->egl_back->buffer_ref, buffer);
- surface->egl_back->resource_handle =
- vc_dispmanx_get_handle_from_wl_buffer(wl_resource);
-#else
- weston_log("unhandled buffer type!\n");
- weston_buffer_reference(&surface->buffer_ref, NULL);
- surface->buffer_type = BUFFER_TYPE_NULL;
-#endif
- }
-}
-
-static void
-rpir_surface_handle_surface_destroy(struct wl_listener *listener, void *data)
-{
- struct rpir_surface *surface;
- struct weston_surface *base = data;
-
- surface = container_of(listener, struct rpir_surface,
- surface_destroy_listener);
-
- assert(surface);
- assert(surface->surface == base);
- if (!surface)
- return;
-
- surface->surface = NULL;
- base->renderer_state = NULL;
-
- if (wl_list_empty(&surface->views))
- rpir_surface_destroy(surface);
-}
-
-static int
-rpi_renderer_create_surface(struct weston_surface *base)
-{
- struct rpi_renderer *renderer = to_rpi_renderer(base->compositor);
- struct rpir_surface *surface;
-
- assert(base->renderer_state == NULL);
-
- surface = rpir_surface_create(renderer);
- if (!surface)
- return -1;
-
- surface->surface = base;
- base->renderer_state = surface;
-
- surface->surface_destroy_listener.notify =
- rpir_surface_handle_surface_destroy;
- wl_signal_add(&base->destroy_signal,
- &surface->surface_destroy_listener);
-
- return 0;
-}
-
-static int
-rpi_renderer_create_view(struct weston_view *base)
-{
- struct rpir_surface *surface = to_rpir_surface(base->surface);
- struct rpir_view *view;
-
- assert(base->renderer_state == NULL);
-
- view = rpir_view_create(surface);
- if (!view)
- return -1;
-
- view->view = base;
- base->renderer_state = view;
-
- view->view_destroy_listener.notify =
- rpir_view_handle_view_destroy;
- wl_signal_add(&base->destroy_signal,
- &view->view_destroy_listener);
-
- return 0;
-}
-
-static void
-rpi_renderer_surface_set_color(struct weston_surface *base,
- float red, float green, float blue, float alpha)
-{
- struct rpir_surface *surface = to_rpir_surface(base);
- uint8_t color[4];
- VC_RECT_T rect;
- int ret;
-
- assert(surface);
-
- ret = rpi_resource_realloc(surface->back, VC_IMAGE_ARGB8888,
- 1, 1, 4, 1);
- if (ret < 0) {
- weston_log("Error: %s: rpi_resource_realloc failed.\n",
- __func__);
- return;
- }
-
- color[0] = float2uint8(blue);
- color[1] = float2uint8(green);
- color[2] = float2uint8(red);
- color[3] = float2uint8(alpha);
-
- vc_dispmanx_rect_set(&rect, 0, 0, 1, 1);
- ret = vc_dispmanx_resource_write_data(surface->back->handle,
- VC_IMAGE_ARGB8888,
- 4, color, &rect);
- if (ret) {
- weston_log("Error: %s: resource_write_data failed.\n",
- __func__);
- return;
- }
-
- DBG("%s: resource %p solid color BGRA %u,%u,%u,%u\n", __func__,
- surface->back, color[0], color[1], color[2], color[3]);
-
- /*pixman_region32_copy(&surface->prev_damage, damage);*/
- surface->need_swap = 1;
-}
-
-static void
-rpir_view_handle_view_destroy(struct wl_listener *listener, void *data)
-{
- struct rpir_view *view;
- struct weston_view *base = data;
-
- view = container_of(listener, struct rpir_view, view_destroy_listener);
-
- assert(view);
- assert(view->view == base);
- if (!view)
- return;
-
- view->view = NULL;
- base->renderer_state = NULL;
-
- /* If guaranteed to not be on screen, just destroy it. */
- if (wl_list_empty(&view->link))
- rpir_view_destroy(view);
-
- /* Otherwise, the view is either on screen and needs
- * to be removed by a repaint update, or it is in the
- * view_cleanup_list, and will be destroyed by
- * rpi_renderer_finish_frame().
- */
-}
-
-static void
-rpi_renderer_destroy(struct weston_compositor *compositor)
-{
- struct rpi_renderer *renderer = to_rpi_renderer(compositor);
-
-#if ENABLE_EGL
- if (renderer->has_bind_display)
- renderer->unbind_display(renderer->egl_display,
- compositor->wl_display);
-#endif
-
- free(renderer);
- compositor->renderer = NULL;
-}
-
-WL_EXPORT int
-rpi_renderer_create(struct weston_compositor *compositor,
- const struct rpi_renderer_parameters *params)
-{
- struct rpi_renderer *renderer;
-#if ENABLE_EGL
- const char *extensions;
- EGLBoolean ret;
- EGLint major, minor;
-#endif
-
- weston_log("Initializing the DispmanX compositing renderer\n");
-
- renderer = zalloc(sizeof *renderer);
- if (renderer == NULL)
- return -1;
-
- renderer->single_buffer = params->single_buffer;
- renderer->enable_opaque_regions = params->opaque_regions;
-
- renderer->base.read_pixels = rpi_renderer_read_pixels;
- renderer->base.repaint_output = rpi_renderer_repaint_output;
- renderer->base.flush_damage = rpi_renderer_flush_damage;
- renderer->base.attach = rpi_renderer_attach;
- renderer->base.surface_set_color = rpi_renderer_surface_set_color;
- renderer->base.destroy = rpi_renderer_destroy;
-
-#ifdef ENABLE_EGL
- renderer->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (renderer->egl_display == EGL_NO_DISPLAY) {
- weston_log("failed to create EGL display\n");
- free(renderer);
- return -1;
- }
-
- if (!eglInitialize(renderer->egl_display, &major, &minor)) {
- weston_log("failed to initialize EGL display\n");
- free(renderer);
- return -1;
- }
-
- renderer->bind_display =
- (void *) eglGetProcAddress("eglBindWaylandDisplayWL");
- renderer->unbind_display =
- (void *) eglGetProcAddress("eglUnbindWaylandDisplayWL");
- renderer->query_buffer =
- (void *) eglGetProcAddress("eglQueryWaylandBufferWL");
-
- extensions = (const char *) eglQueryString(renderer->egl_display,
- EGL_EXTENSIONS);
- if (!extensions) {
- weston_log("Retrieving EGL extension string failed.\n");
- eglTerminate(renderer->egl_display);
- free(renderer);
- return -1;
- }
-
- if (strstr(extensions, "EGL_WL_bind_wayland_display"))
- renderer->has_bind_display = 1;
-
- if (renderer->has_bind_display) {
- ret = renderer->bind_display(renderer->egl_display,
- compositor->wl_display);
- if (!ret)
- renderer->has_bind_display = 0;
- }
-#endif
-
- compositor->renderer = &renderer->base;
- compositor->read_format = PIXMAN_a8r8g8b8;
- /* WESTON_CAP_ROTATION_ANY not supported */
-
- wl_display_add_shm_format(compositor->wl_display, WL_SHM_FORMAT_RGB565);
-
- return 0;
-}
-
-WL_EXPORT int
-rpi_renderer_output_create(struct weston_output *base,
- DISPMANX_DISPLAY_HANDLE_T display)
-{
- struct rpir_output *output;
-
- assert(base->renderer_state == NULL);
-
- output = zalloc(sizeof *output);
- if (output == NULL)
- return -1;
-
- output->display = display;
- output->update = DISPMANX_NO_HANDLE;
- wl_list_init(&output->view_list);
- wl_list_init(&output->view_cleanup_list);
- rpi_resource_init(&output->capture_buffer);
- base->renderer_state = output;
-
- return 0;
-}
-
-WL_EXPORT void
-rpi_renderer_output_destroy(struct weston_output *base)
-{
- struct rpir_output *output = to_rpir_output(base);
- struct rpir_view *view;
- DISPMANX_UPDATE_HANDLE_T update;
-
- rpi_resource_release(&output->capture_buffer);
- free(output->capture_data);
- output->capture_data = NULL;
-
- update = vc_dispmanx_update_start(0);
- rpir_output_dmx_remove_all(output, update);
- vc_dispmanx_update_submit_sync(update);
-
- while (!wl_list_empty(&output->view_cleanup_list)) {
- view = container_of(output->view_cleanup_list.next,
- struct rpir_view, link);
- rpir_view_destroy(view);
- }
-
- free(output);
- base->renderer_state = NULL;
-}
-
-WL_EXPORT void
-rpi_renderer_set_update_handle(struct weston_output *base,
- DISPMANX_UPDATE_HANDLE_T handle)
-{
- struct rpir_output *output = to_rpir_output(base);
-
- output->update = handle;
-}
-
-WL_EXPORT void
-rpi_renderer_finish_frame(struct weston_output *base)
-{
- struct rpir_output *output = to_rpir_output(base);
- struct weston_compositor *compositor = base->compositor;
- struct weston_view *wv;
- struct rpir_view *view;
-
- while (!wl_list_empty(&output->view_cleanup_list)) {
- view = container_of(output->view_cleanup_list.next,
- struct rpir_view, link);
-
- if (view->view) {
- /* The weston_view still exists, but is
- * temporarily not visible, and hence its Element
- * was removed. The current front buffer contents
- * must be preserved.
- */
- if (!view->surface->visible_views)
- rpi_resource_release(view->surface->back);
-
- wl_list_remove(&view->link);
- wl_list_init(&view->link);
- } else {
- rpir_view_destroy(view);
- }
- }
-
- wl_list_for_each(wv, &compositor->view_list, link) {
- view = to_rpir_view(wv);
-
- if (view->surface->buffer_type != BUFFER_TYPE_EGL)
- continue;
-
- rpir_egl_buffer_destroy(view->surface->egl_old_front);
- view->surface->egl_old_front = NULL;
- }
-
- wl_signal_emit(&base->frame_signal, base);
-}
diff --git a/src/rpi-renderer.h b/src/rpi-renderer.h
deleted file mode 100644
index 63706826..00000000
--- a/src/rpi-renderer.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright © 2013 Raspberry Pi Foundation
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef RPI_RENDERER_H
-#define RPI_RENDERER_H
-
-struct rpi_renderer_parameters {
- int single_buffer;
- int opaque_regions;
-};
-
-int
-rpi_renderer_create(struct weston_compositor *compositor,
- const struct rpi_renderer_parameters *params);
-
-int
-rpi_renderer_output_create(struct weston_output *base,
- DISPMANX_DISPLAY_HANDLE_T display);
-
-void
-rpi_renderer_output_destroy(struct weston_output *base);
-
-void
-rpi_renderer_set_update_handle(struct weston_output *base,
- DISPMANX_UPDATE_HANDLE_T handle);
-
-void
-rpi_renderer_finish_frame(struct weston_output *base);
-
-#endif /* RPI_RENDERER_H */