天天看点

display:agl-compositor

Source code about AGL:https://wiki.automotivelinux.org/agl-distro/source-code

思考:为什么叫agl-compositor而不是agl-shell

本质上差别不大,compositor加载shell。agl独立了自己的一套加载shell等等的compositor.c

https://docs.automotivelinux.org/en/master/#5_Component_Documentation/1_agl-compositor/

display:agl-compositor

https://gerrit.automotivelinux.org/gerrit/gitweb?p=src/agl-compositor.git;a=blob;f=doc/arch_diagram.png;h=88a4381c4ad4d694a193b3105483a0c9ae50ff5a;hb=HEAD

display:agl-compositor

这个agl-compositor有点ivi-shell的味道。就是ivi-shell的升级版,或者说,重构版本

重点,surfacecommit->weston_surface_commit_state->if (surface->committed)  surface->committed(surface, state->sx, state->sy);   ->dekstop.c的desktop_committed->weston_compositor_schedule_repaint


	weston_compositor_schedule_repaint(surface->ivi->compositor);
        wl_list_for_each(output, &compositor->output_list, link)
		    weston_output_schedule_repaint(output);

这里可以看到,在刚刚进入commit逻辑的时候,desktop会主导一次完整的commit逻辑。
	switch (surface->role) {
	case IVI_SURFACE_ROLE_DESKTOP:
	case IVI_SURFACE_ROLE_REMOTE:
		ivi_layout_desktop_committed(surface);
		break;
	case IVI_SURFACE_ROLE_POPUP:
		ivi_layout_popup_committed(surface);
		break;
	case IVI_SURFACE_ROLE_FULLSCREEN:
		ivi_layout_fullscreen_committed(surface);
		break;
	case IVI_SURFACE_ROLE_SPLIT_H:
	case IVI_SURFACE_ROLE_SPLIT_V:
		ivi_layout_split_committed(surface);
		break;
	case IVI_SURFACE_ROLE_NONE:
	case IVI_SURFACE_ROLE_BACKGROUND:
	case IVI_SURFACE_ROLE_PANEL:
	default: /* fall through */
		break;
	
           

 在client做commit的时候,作为desktop,会将

How to clone::
git clone https://gerrit.automotivelinux.org/gerrit/src/agl-compositor.git 

How to build[need have weston build environment  libweston-8]::  
meson builddir/ --prefix=/home/maze/Wayland/install 
ninja -C builddir/ install 

How to run::
./agl-compositor   //Black-screen 
           

agl-shell设置background/panel。设置ready保证所有的surface同时显示。

agl-shell-desktop用app_id激活其他的client。

│   ├── agl-shell-client-protocol.h
        agl_shell_ready
        *告诉服务器这个客户端已经可以显示了。服务器将在启动期间延迟显示,并将显示黑屏,直到所有shell客户端都准备好显示。这使客户端有机会将多个surface设置和配置为一个一致的接口。
        *绑定到这个接口的客户端必须发送这个请求,否则他们可能会阻塞在compositor。
        *如果这个请求在compositor已经完成启动后被调用,没有操作被执行。
        agl_shell_set_background
        agl_shell_set_panel
        agl_shell_activate_app
        *为了窗口管理的目的,要求compositor制作一个toplevel成为当前/聚焦的窗口。


│   ├── agl-shell-desktop-client-protocol.h
        agl_shell_desktop_activate_app
        agl_shell_desktop_set_app_property
        agl_shell_desktop_deactivate_app
│   ├── agl-shell-desktop-protocol.c
│   ├── agl-shell-desktop-server-protocol.h
│   ├── agl-shell-protocol.c
│   ├── agl-shell-server-protocol.h
           

https://gitlab.apertis.org/pkg/maynard 

From 7575569382f2cd90643393b091e2b3d770833dc1 Mon Sep 17 00:00:00 2001
From: maze-BUG <[email protected]>
Date: Tue, 27 Apr 2021 19:47:11 +0800
Subject: [PATCH] Add agl-shm.c

Signed-off-by: maze-BUG <[email protected]>
---
 clients/agl-shm.c   | 331 ++++++++++++++++++++++++++++++++++++++++++++
 clients/meson.build |  15 ++
 2 files changed, 346 insertions(+)
 create mode 100644 clients/agl-shm.c

diff --git a/clients/agl-shm.c b/clients/agl-shm.c
new file mode 100644
index 0000000..2d19959
--- /dev/null
+++ b/clients/agl-shm.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright © 2011 Benjamin Franzke
+ * Copyright © 2010 Intel Corporation
+ *
+ * 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 <stdint.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <sys/mman.h>
+#include <signal.h>
+
+#include <wayland-client.h>
+#include "shared/helpers.h"
+#include "shared/xalloc.h"
+#include "shared/file-util.h"
+#include "shared/os-compatibility.h"
+#include <libweston/zalloc.h>
+#include "agl-shell-client-protocol.h"
+#include "agl-shell-desktop-client-protocol.h"
+
+#define DEBUG_TRACE_ENABLED 1
+
+#if DEBUG_TRACE_ENABLED
+#define DEBUG_TRACE(fmt, args...) \
+    {   \
+                fprintf(stderr, "TRACE [%s][%s][%4d]:"fmt"\n", __FILE__, __func__, __LINE__,  ##args); \
+    }
+#else
+#define DEBUG_TRACE(fmt, args...)
+#endif
+
+
+struct framebuffer {
+    struct wl_surface *surface;
+	struct wl_buffer *buffer;
+
+    int height;
+    int width;
+
+    int ready;
+	void *shm_data;
+};
+
+struct desktop {
+	struct wl_display *display;
+	struct wl_registry *registry;
+
+	struct wl_shm *shm;
+    struct wl_compositor *compositor;
+    struct wl_output *output;
+    struct agl_shell *ashell;
+    struct agl_shell_desktop *ashell_desktop;
+
+    struct framebuffer *background;
+    struct framebuffer *panel;
+    int ready; 
+};
+
+static int running = 1;
+
+static void shell_desktop_application(void *data, struct agl_shell_desktop *agl_shell_desktop,
+                const char *app_id)
+{
+    DEBUG_TRACE("APPLICATION app_id %s", app_id);
+	/* XXX: unimplemented */
+}
+
+static void shell_desktop_state_app(void *data, struct agl_shell_desktop *agl_shell_desktop,
+                const char *app_id,
+                const char *app_data,
+                uint32_t state,
+                uint32_t role)
+{
+    DEBUG_TRACE("APPLICATION STATE app_id %s state %d role %d", app_id, state, role);
+	/* XXX: unimplemented */
+}
+
+static const struct agl_shell_desktop_listener shell_desktop_listener = {
+	.application=shell_desktop_application,
+    .state_app=shell_desktop_state_app,
+};
+
+static void wl_display_error(void *data, struct wl_display *wl_display,
+        void *object_id,
+        uint32_t code,
+        const char *message) 
+{
+    DEBUG_TRACE();
+}
+
+static void wl_display_delete_id(void *data, struct wl_display *wl_display, uint32_t id)
+{
+    DEBUG_TRACE();
+}
+
+struct wl_display_listener display_listener = {
+    wl_display_error,
+    wl_display_delete_id
+};
+
+static void
+shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
+{
+}
+
+struct wl_shm_listener shm_listener = {
+    shm_format
+};
+
+static void
+handle_global(void *data, struct wl_registry *registry,
+	      uint32_t name, const char *interface, uint32_t version)
+{
+	struct desktop *sh_data = data;
+	printf("%s :%s\n",__func__, interface);
+    if (strcmp(interface, "wl_compositor") == 0) {
+	    printf("bind%s :%s\n",__func__, interface);
+        sh_data->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1);
+    } else if (strcmp(interface, "wl_output") == 0) {
+	    printf("bind%s :%s\n",__func__, interface);
+		sh_data->output = wl_registry_bind(registry, name, &wl_output_interface, 1);
+	} else if (strcmp(interface, "agl_shell") == 0) {
+	    printf("bind%s :%s\n",__func__, interface);
+		sh_data->ashell = wl_registry_bind(registry, name, &agl_shell_interface, 1);
+	} else if (strcmp(interface, "agl_shell_desktop") == 0) {
+	    printf("bind%s :%s\n",__func__, interface);
+		sh_data->ashell_desktop =
+                    wl_registry_bind(registry, name, &agl_shell_desktop_interface, 1);
+        agl_shell_desktop_add_listener(sh_data->ashell_desktop,
+                    &shell_desktop_listener, sh_data);
+        agl_shell_desktop_set_user_data(sh_data->ashell_desktop, sh_data);
+    } else if (strcmp(interface, "wl_shm") == 0) {
+	    printf("bind%s :%s\n",__func__, interface);
+        sh_data->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
+        wl_shm_add_listener(sh_data->shm, &shm_listener, sh_data);
+    }
+
+}
+
+static void
+handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
+{
+	/* XXX: unimplemented */
+}
+
+static const struct wl_registry_listener registry_listener = {
+	handle_global,
+	handle_global_remove
+};
+
+static void
+signal_int(int signum)
+{
+    running = 0;
+}
+
+static int create_background(struct desktop *desktop) {
+    printf("%s++\n",__func__);
+    struct wl_shm_pool *pool;
+    int size;
+    int stride;
+    int fd;
+    void *data;
+    int width = 250;
+    int height = 250;
+    desktop->background = malloc(sizeof(struct framebuffer));
+    desktop->background->width = width;
+    desktop->background->height = height;
+
+    stride = desktop->background->width * 4;
+    size = desktop->background->width * desktop->background->height * 4;
+    fd = os_create_anonymous_file(size);
+    data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+    if (data == MAP_FAILED) {
+        fprintf(stderr, "mmap failed: %s\n", strerror(errno));
+        close(fd);
+        return -1;
+    }
+
+    if (desktop->shm == NULL) {
+        fprintf(stderr, "No wl_shm global\n");
+        exit(1);
+    }
+    pool = wl_shm_create_pool(desktop->shm, fd, size);
+    desktop->background->buffer = wl_shm_pool_create_buffer(pool, 0, width, height,
+                                        stride, WL_SHM_FORMAT_XRGB8888);
+    wl_shm_pool_destroy(pool);
+    close(fd);
+    desktop->background->surface = wl_compositor_create_surface(desktop->compositor);
+    desktop->background->shm_data = data;
+
+    memset(desktop->background->shm_data, 0xff, width*height*4);
+    wl_surface_attach(desktop->background->surface, desktop->background->buffer, 0, 0);
+    wl_surface_damage(desktop->background->surface, 0, 0, width, height);
+    wl_surface_commit(desktop->background->surface);
+
+    printf("%s--\n",__func__);
+    return 0;
+}
+
+static int create_panel(struct desktop *desktop) {
+    printf("%s++\n",__func__);
+    struct wl_shm_pool *pool;
+    int size;
+    int stride;
+    int fd;
+    void *data;
+    desktop->panel = malloc(sizeof(struct framebuffer));
+    desktop->panel->width = 200;
+    desktop->panel->height = 200;
+    int width = desktop->panel->width;
+    int height = desktop->panel->height;
+
+    desktop->panel->surface = wl_compositor_create_surface(desktop->compositor);
+    stride = desktop->panel->width * 4;
+    size = desktop->panel->width * desktop->panel->height * 4;
+    fd = os_create_anonymous_file(size);
+    data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+
+    pool = wl_shm_create_pool(desktop->shm, fd, size);
+    desktop->panel->buffer = wl_shm_pool_create_buffer(pool, 0, width, height,
+                                        stride, WL_SHM_FORMAT_XRGB8888);
+    wl_shm_pool_destroy(pool);
+    close(fd);
+    desktop->panel->surface = wl_compositor_create_surface(desktop->compositor);
+    desktop->panel->shm_data = data;
+
+    memset(desktop->panel->shm_data, 0xff, width*height*4);
+    wl_surface_attach(desktop->panel->surface, desktop->panel->buffer, 0, 0);
+    wl_surface_damage(desktop->panel->surface, 0, 0, width, height);
+    wl_surface_commit(desktop->panel->surface);
+
+    printf("%s--\n",__func__);
+    return 0;
+}
+
+static int time_handler(struct desktop *desktop) {
+    printf("%s--\n",__func__);
+//    if (!desktop->background->ready) {
+//        desktop->background->ready = 1;
+        agl_shell_set_background(desktop->ashell, desktop->background->surface, 
+                desktop->output);
+//    }
+//    if (!desktop->panel->ready) {
+//        desktop->panel->ready = 1;
+        agl_shell_set_panel(desktop->ashell, desktop->panel->surface, desktop->output,
+                AGL_SHELL_EDGE_LEFT);
+//        connect_enter_leave_signals(desktop);
+//    }
+        agl_shell_activate_app(desktop->ashell, "simple-shm-id", desktop->output);
+//    if (!desktop->ready) {
+//        desktop->ready = 1;
+        agl_shell_ready(desktop->ashell);
+//    }
+    return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+    struct sigaction sigint;
+	struct wl_display *display;
+	struct wl_registry *registry;
+    int ret = 0;
+
+	struct desktop *agldesktop=malloc(sizeof(struct desktop));
+    memset(agldesktop, 0, sizeof(struct desktop));
+
+	display = wl_display_connect(NULL);
+	if (display == NULL) {
+		fprintf(stderr, "failed to create display: %s\n",
+			strerror(errno));
+		return EXIT_FAILURE;
+	}
+
+    agldesktop->display=display;
+    wl_display_add_listener(agldesktop->display, &display_listener, agldesktop);
+
+	registry = wl_display_get_registry(display);
+    agldesktop->registry=registry;
+	wl_registry_add_listener(registry, &registry_listener, agldesktop);
+
+    sigint.sa_handler = signal_int;
+    sigemptyset(&sigint.sa_mask);
+    sigint.sa_flags = SA_RESETHAND;
+    sigaction(SIGINT, &sigint, NULL);
+
+	wl_display_roundtrip(display);
+	wl_display_roundtrip(display);
+
+    ret = create_background(agldesktop);
+    ret = create_panel(agldesktop);
+
+	//wl_display_dispatch(display);
+
+    while (running && ret != -1) {
+	   // wl_display_dispatch(display);
+        ret = time_handler(agldesktop);
+        sleep(2);
+       // ret = wl_display_dispatch(desktop->display);
+    }
+
+	fprintf(stderr, "agl-shm exiting\n");
+	return 0;
+}
diff --git a/clients/meson.build b/clients/meson.build
index 08b2c08..3df0cc8 100644
--- a/clients/meson.build
+++ b/clients/meson.build
@@ -16,6 +16,21 @@ clients = [
 	'deps_objs' : [ dep_wayland_client ],
 	'deps': [ 'cairo' ],
 },
+{
+	'basename': 'agl-shm',
+	'sources': [
+	  'agl-shm.c',
+	  '../shared/file-util.c',
+	  '../shared/os-compatibility.c',
+	  '../shared/xalloc.c',
+	  agl_shell_client_protocol_h,
+	  agl_shell_protocol_c,
+	  agl_shell_desktop_client_protocol_h,
+	  agl_shell_desktop_protocol_c,
+	],
+	'deps_objs' : [ dep_wayland_client ],
+	'deps': [ 'cairo' ],
+},
 ]
 
 foreach t: clients
-- 
2.25.1

           

panel指的是UI,最上面那一行。