avs_mtk_voice/meta/meta-mediatek/recipes-graphics/wayland/weston/0015-weston-screenshooter-a...

933 lines
27 KiB
Diff
Raw Normal View History

2022-05-13 08:02:31 +00:00
From ea4a86445a00c475c38a04c9b1cf71633ea5fa3c Mon Sep 17 00:00:00 2001
From: mtk13576 <yr.yang@mediatek.com>
Date: Thu, 9 Nov 2017 10:53:24 +0800
Subject: [PATCH 4/4] weston screenshooter: add weston screen shooter
support multi-screen dump
add screen-shooter feature to dump the screen data.
use the command: weston-simple-screenshooter-mtk -m/s
Test: ok
Change-Id: Ia05d1fac7f8355dcb69d9b682b747b073efed4ff
Signed-off-by: mtk13576 <yr.yang@mediatek.com>
CR-Id: AUTO00000252
---
Makefile.am | 18 +++
clients/simple-screenshooter-mtk.c | 259 ++++++++++++++++++++++++++++++
protocol/weston-configure-mtk.xml | 9 ++
src/compositor-drm.c | 314 ++++++++++++++++++++++++++++++++++---
src/compositor.h | 2 +
src/weston-screenshooter-mtk.c | 129 +++++++++++++++
6 files changed, 707 insertions(+), 24 deletions(-)
create mode 100644 clients/simple-screenshooter-mtk.c
create mode 100644 src/weston-screenshooter-mtk.c
diff --git a/Makefile.am b/Makefile.am
index d9cf059..acf2bb3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -103,6 +103,7 @@ weston_SOURCES = \
shared/platform.h \
src/weston-egl-ext.h \
src/notification-backend-mtk.c \
+ src/weston-screenshooter-mtk.c \
src/weston-configure-mtk.c \
src/weston-configure-mtk.h \
src/performance-panel-ivi-mtk.c
@@ -621,6 +622,23 @@ weston_simple_configure_mtk_LDADD = $(EGL_LIBS) libtoytoolkit.la
BUILT_SOURCES += protocol/linux-dmabuf-unstable-v1-client-protocol.h
endif
+if BUILD_SIMPLE_CONFIGURE_MTK_CLIENT
+demo_clients += weston-simple-screenshooter-mtk
+weston_simple_screenshooter_mtk_SOURCES = clients/simple-screenshooter-mtk.c
+nodist_weston_simple_screenshooter_mtk_SOURCES = \
+ protocol/xdg-shell-unstable-v5-protocol.c \
+ protocol/xdg-shell-unstable-v5-client-protocol.h \
+ protocol/fullscreen-shell-unstable-v1-protocol.c \
+ protocol/fullscreen-shell-unstable-v1-client-protocol.h \
+ protocol/linux-dmabuf-unstable-v1-protocol.c \
+ protocol/linux-dmabuf-unstable-v1-client-protocol.h \
+ protocol/weston-configure-mtk-protocol.c \
+ protocol/weston-configure-mtk-client-protocol.h
+weston_simple_screenshooter_mtk_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
+weston_simple_screenshooter_mtk_LDADD = $(EGL_LIBS) libtoytoolkit.la
+BUILT_SOURCES += protocol/linux-dmabuf-unstable-v1-client-protocol.h
+endif
+
noinst_LTLIBRARIES += libtoytoolkit.la
libtoytoolkit_la_SOURCES = \
diff --git a/clients/simple-screenshooter-mtk.c b/clients/simple-screenshooter-mtk.c
new file mode 100644
index 0000000..cbca18b
--- /dev/null
+++ b/clients/simple-screenshooter-mtk.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright © 2008 Kristian Høgsberg
+ *
+ * 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 <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <cairo.h>
+
+#include <wayland-client.h>
+#include "weston-configure-mtk-client-protocol.h"
+#include "shared/os-compatibility.h"
+#include "shared/xalloc.h"
+
+/* The screenshooter is a good example of a custom object exposed by
+ * the compositor and serves as a test bed for implementing client
+ * side marshalling outside libwayland.so */
+
+static struct wl_shm *shm;
+static struct weston_screenshooter_mtk *mtk_screenshooter;
+static struct wl_list output_list;
+int min_x, min_y, max_x, max_y;
+int buffer_copy_done;
+
+struct screenshooter_output {
+ struct wl_output *output;
+ struct wl_buffer *buffer;
+ int width, height, offset_x, offset_y;
+ void *data;
+ struct wl_list link;
+};
+
+static void
+display_handle_geometry(void *data,
+ struct wl_output *wl_output,
+ int x,
+ int y,
+ int physical_width,
+ int physical_height,
+ int subpixel,
+ const char *make,
+ const char *model,
+ int transform)
+{
+ struct screenshooter_output *output;
+
+ output = wl_output_get_user_data(wl_output);
+
+ if (wl_output == output->output) {
+ output->offset_x = x;
+ output->offset_y = y;
+ }
+}
+
+static void
+display_handle_mode(void *data,
+ struct wl_output *wl_output,
+ uint32_t flags,
+ int width,
+ int height,
+ int refresh)
+{
+ struct screenshooter_output *output;
+
+ output = wl_output_get_user_data(wl_output);
+
+ if (wl_output == output->output && (flags & WL_OUTPUT_MODE_CURRENT)) {
+ output->width = width;
+ output->height = height;
+ }
+}
+
+static const struct wl_output_listener output_listener = {
+ display_handle_geometry,
+ display_handle_mode
+};
+
+static void
+screenshooter_done(void *data, struct weston_screenshooter_mtk *mtk_screenshooter)
+{
+ fprintf(stderr, "screenshooter_done\n");
+ buffer_copy_done = 1;
+}
+
+static const struct weston_screenshooter_mtk_listener screenshooter_mtk_listener =
+{
+ screenshooter_done
+};
+
+static void
+handle_global(void *data, struct wl_registry *registry,
+ uint32_t name, const char *interface, uint32_t version)
+{
+ static struct screenshooter_output *output;
+
+ if (strcmp(interface, "wl_output") == 0) {
+ output = xmalloc(sizeof *output);
+ output->output = wl_registry_bind(registry, name,
+ &wl_output_interface, 1);
+ wl_list_insert(&output_list, &output->link);
+ wl_output_add_listener(output->output, &output_listener, output);
+ } else if (strcmp(interface, "wl_shm") == 0) {
+ shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
+ } else if (strcmp(interface, "weston_screenshooter_mtk") == 0) {
+ mtk_screenshooter = wl_registry_bind(registry, name,
+ &weston_screenshooter_mtk_interface,
+ 1);
+ }
+}
+
+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 struct wl_buffer *
+create_shm_buffer(int width, int height, void **data_out)
+{
+ struct wl_shm_pool *pool;
+ struct wl_buffer *buffer;
+ int fd, size, stride;
+ void *data;
+
+ stride = width * 4;
+ size = stride * height;
+
+ fd = os_create_anonymous_file(size);
+ if (fd < 0) {
+ fprintf(stderr, "creating a buffer file for %d B failed: %m\n",
+ size);
+ return NULL;
+ }
+
+ data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (data == MAP_FAILED) {
+ fprintf(stderr, "mmap failed: %m\n");
+ close(fd);
+ return NULL;
+ }
+
+ pool = wl_shm_create_pool(shm, fd, size);
+ close(fd);
+ buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride,
+ WL_SHM_FORMAT_XRGB8888);
+ wl_shm_pool_destroy(pool);
+
+ *data_out = data;
+ fprintf(stderr,"create_shm_buffer\n");
+ return buffer;
+}
+
+static void
+usage(int error_code)
+{
+ fprintf(stderr, "Usage: simple-screenshooter-mtk [OPTIONS]\n\n"
+ " -m dump mainscreen\n"
+ " -s dump subscreen\n"
+ " -h This help text! default dump all screens\n\n");
+
+ exit(error_code);
+}
+
+int main(int argc, char *argv[])
+{
+ struct wl_display *display;
+ struct wl_registry *registry;
+ struct screenshooter_output *output;
+ int i, width, height;
+ int mainscreen=0;
+ int subscreen=0;
+ for (i = 1; i < argc; i++) {
+ if (strcmp("-m", argv[i]) == 0)
+ mainscreen = 1;
+ else if (strcmp("-s", argv[i]) == 0)
+ subscreen = 1;
+ else if (strcmp("-h", argv[i]) == 0)
+ usage(EXIT_SUCCESS);
+ else
+ usage(EXIT_SUCCESS);
+ }
+
+ display = wl_display_connect(NULL);
+ if (display == NULL) {
+ fprintf(stderr, "failed to create display: %m\n");
+ return -1;
+ }
+
+ wl_list_init(&output_list);
+ registry = wl_display_get_registry(display);
+ wl_registry_add_listener(registry, &registry_listener, NULL);
+ wl_display_dispatch(display);
+ wl_display_roundtrip(display);
+ if (mtk_screenshooter == NULL) {
+ fprintf(stderr, "display doesn't support screenshooter\n");
+ return -1;
+ }
+
+ weston_screenshooter_mtk_add_listener(mtk_screenshooter,
+ &screenshooter_mtk_listener,
+ NULL);
+
+ wl_list_for_each_reverse(output, &output_list, link) {
+ if(mainscreen == 1) {
+ output->buffer = create_shm_buffer(1920, 1080, &output->data);
+ weston_screenshooter_mtk_shoot(mtk_screenshooter,output->output,output->buffer);
+ buffer_copy_done = 0;
+ while (!buffer_copy_done)
+ wl_display_roundtrip(display);
+
+ break;
+ }
+ else if(subscreen == 1) {
+ subscreen = 0;
+ }
+ else {
+ output->buffer = create_shm_buffer(1920, 1080, &output->data);
+ weston_screenshooter_mtk_shoot(mtk_screenshooter,output->output,output->buffer);
+ buffer_copy_done = 0;
+ while (!buffer_copy_done)
+ wl_display_roundtrip(display);
+ }
+ }
+ fprintf(stderr,"end!!!!!\n");
+ return 0;
+}
diff --git a/protocol/weston-configure-mtk.xml b/protocol/weston-configure-mtk.xml
index 33f1c3b..c3f7144 100644
--- a/protocol/weston-configure-mtk.xml
+++ b/protocol/weston-configure-mtk.xml
@@ -145,5 +145,14 @@
</interface>
+ <interface name="weston_screenshooter_mtk" version="1">
+ <request name="shoot">
+ <arg name="output" type="object" interface="wl_output"/>
+ <arg name="buffer" type="object" interface="wl_buffer"/>
+ </request>
+ <event name="done">
+ </event>
+ </interface>
+
</protocol>
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 3ed1fcd..729b907 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -80,6 +80,10 @@
#define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64
#endif
+#define DRM_ALIGN(X,bit) ((X + bit-1) & (~(bit-1)))
+
+#define MTK_MAX_PLANE 4
+
/**
* Possible values for the WDRM_PLANE_TYPE property.
*/
@@ -195,6 +199,7 @@ struct drm_backend {
int num_crtcs;
uint32_t crtc_allocator;
uint32_t connector_allocator;
+ uint32_t writeback_connectors;
struct wl_listener session_listener;
uint32_t gbm_format;
@@ -345,6 +350,8 @@ struct drm_output {
int pipe;
uint32_t connector_id;
+ uint32_t wb_connector_id;
+ uint32_t wb_prop_id;
struct drm_edid edid;
drmModePropertyPtr dpms_prop;
uint32_t gbm_format;
@@ -375,6 +382,7 @@ struct drm_output {
struct wl_listener recorder_frame_listener;
struct wl_list plane_flip_list; /* drm_plane::flip_link */
+ struct raw_texture* raw_data;
};
struct drm_fourcc_info {
@@ -406,10 +414,192 @@ static struct drm_fourcc_info fourcc_tbl[] = {
{0, 0, 0},
};
+struct raw_texture {
+ /* input */
+ int width;
+ int height;
+ int fourcc;
+ int bpp;
+ int plane_nums;
+
+ unsigned int pitch[MTK_MAX_PLANE];
+ unsigned int offset[MTK_MAX_PLANE];
+ int fds[MTK_MAX_PLANE];
+ unsigned int handle[MTK_MAX_PLANE];
+
+ void *texbuf;
+ int size;
+
+ unsigned int fb_id;
+ int index;
+};
+
static struct gl_renderer_interface *gl_renderer;
static const char default_seat[] = "seat0";
+int drm_alloc_gem_test(int fd, int width, int height, int fourcc, struct raw_texture * raw_data)
+{
+ void *map = NULL;
+ struct drm_mode_create_dumb create_arg;
+ struct drm_mode_map_dumb map_arg;
+ struct drm_prime_handle prime_arg;
+ int i, ret;
+ unsigned int alloc_size;
+
+ memset(&create_arg, 0, sizeof(create_arg));
+ memset(&map_arg, 0, sizeof(map_arg));
+ memset(&prime_arg, 0, sizeof(prime_arg));
+
+ raw_data->width = width;
+ raw_data->height = height;
+ raw_data->fourcc = fourcc;
+
+ for(i = 0; i < MTK_MAX_PLANE; i ++ )
+ raw_data->fds[i] = -1;
+
+ switch (raw_data->fourcc) {
+ case DRM_FORMAT_NV12:
+ raw_data->bpp = 12;
+ raw_data->plane_nums = 2;
+ break;
+
+ case DRM_FORMAT_NV16:
+ raw_data->bpp = 16;
+ raw_data->plane_nums = 2;
+ break;
+
+ case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_YUYV:
+ case DRM_FORMAT_UYVY:
+ raw_data->bpp = 16;
+ raw_data->plane_nums = 1;
+ break;
+
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_XRGB8888:
+ raw_data->bpp = 32;
+ raw_data->plane_nums = 1;
+ break;
+ case DRM_FORMAT_RGB888:
+ case DRM_FORMAT_BGR888:
+ raw_data->bpp = 24;
+ raw_data->plane_nums = 1;
+ break;
+ case DRM_FORMAT_YUV420:
+ case DRM_FORMAT_YVU420:
+ raw_data->bpp = 12;
+ raw_data->plane_nums = 3;
+ break;
+
+ default:
+ fprintf(stderr, "unsupported format 0x%08x\n", raw_data->fourcc);
+ return -1;
+ }
+
+ if (raw_data->plane_nums == 3) {
+ if (raw_data->bpp == 12) {
+ raw_data->pitch[0] = DRM_ALIGN(raw_data->width, 16);
+ raw_data->pitch[1] = raw_data->pitch[0] / 2;
+ raw_data->pitch[2] = raw_data->pitch[0] / 2;
+ raw_data->offset[0] = 0;
+ raw_data->offset[1] = raw_data->pitch[0] * raw_data->height;
+ raw_data->offset[2] = raw_data->offset[1] + raw_data->pitch[1] * raw_data->height / 2;
+ alloc_size = raw_data->offset[2] + raw_data->pitch[2] * raw_data->height / 2;
+ } else {
+ fprintf(stderr,"debug: please add new format 0x%x\n", raw_data->fourcc);
+ return -1;
+ }
+ } else if (raw_data->plane_nums == 2) {
+ raw_data->pitch[0] = DRM_ALIGN(raw_data->width, 16);
+ raw_data->offset[0] = 0;
+ if (raw_data->bpp == 16) {
+ raw_data->pitch[1] = raw_data->pitch[0];
+ raw_data->offset[1] = raw_data->pitch[0] * raw_data->height;
+ alloc_size = raw_data->offset[1] + raw_data->pitch[1] * raw_data->height;
+ fprintf(stderr,"debug: %s %d alloc_size = %d o/p [%d %d]\n",
+ __FUNCTION__, __LINE__, alloc_size, raw_data->offset[1], raw_data->pitch[1]);
+ }
+ else if (raw_data->bpp == 12) {
+ raw_data->pitch[1] = raw_data->pitch[0];
+ raw_data->offset[1] = raw_data->pitch[0] * raw_data->height;
+ alloc_size = raw_data->offset[1] + raw_data->pitch[1] * raw_data->height;
+ } else {
+ fprintf(stderr,"debug: please add new format 0x%x\n", raw_data->fourcc);
+ return -1;
+ }
+ } else {
+ raw_data->pitch[0] = DRM_ALIGN(raw_data->width * raw_data->bpp / 8, 16);
+ raw_data->offset[0] = 0;
+ alloc_size = raw_data->pitch[0] * raw_data->height;
+ }
+
+ create_arg.bpp = raw_data->bpp;
+ create_arg.width = raw_data->width;
+ create_arg.height = raw_data->height;
+
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg);
+ if (ret) {
+ fprintf(stderr,"error: drmIoctl %d DRM_IOCTL_MODE_CREATE_DUMB fail %d", fd, ret);
+ return -1;
+ }
+
+ for (i = 0; i < raw_data->plane_nums; i++) {
+ raw_data->fds[i] = fd;
+ raw_data->handle[i] = create_arg.handle;
+ }
+
+ if (drmModeAddFB2(fd, raw_data->width, raw_data->height,
+ raw_data->fourcc, raw_data->handle,
+ raw_data->pitch, raw_data->offset,
+ &raw_data->fb_id, 0)) {
+ weston_log("failed to add raw_data fb\n");
+ return -1;
+ }
+
+ map_arg.handle = create_arg.handle;
+
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &map_arg);
+ if (ret) {
+ fprintf(stderr,"error: drmIoctl DRM_IOCTL_MODE_MAP_DUMB fail %d", ret);
+ return -1;
+ }
+
+ map = mmap(0, create_arg.size, PROT_WRITE|PROT_READ , MAP_SHARED, fd, map_arg.offset);
+ if (map == MAP_FAILED) {
+ fprintf(stderr,"error: mmap fail : 0x%p", map);
+ return -1;
+ }
+
+ raw_data->texbuf = map;
+ raw_data->size = create_arg.size;
+
+ return 0;
+}
+
+static int
+_write_file(void *buf, int len, const char *file_name)
+{
+ int ret, nwrite = 0;
+
+ FILE *fp = fopen(file_name, "wb");
+ if (!fp)
+ {
+ fprintf(stderr,"debug: file %s open failed\n", file_name);
+ return -1;
+ }
+
+ while (nwrite < len) {
+ ret = fwrite(buf + nwrite, 1, len - nwrite, fp);
+ if (!ret)
+ break;
+ nwrite += ret;
+ }
+
+ fclose(fp);
+ return 0;
+}
+
static struct drm_fourcc_info *
get_drm_format_info(unsigned int format)
{
@@ -620,6 +810,41 @@ drm_properties_get_from_obj(struct drm_backend *b,
return valid_mask;
}
+static uint64_t
+drm_properties_get_writeback_fb_value(struct drm_backend *b,
+ uint32_t obj_id, uint32_t obj_type)
+{
+ drmModeObjectProperties *props;
+ drmModePropertyRes *prop;
+ unsigned i;
+ uint64_t value;
+
+ props = drmModeObjectGetProperties(b->drm.fd, obj_id, obj_type);
+ if (!props) {
+ weston_log("DRM error : get properties for object %u "
+ "of type %#x '%s' failed.\n", obj_id, obj_type,
+ drm_object_type_str(obj_type));
+ return -1;
+ }
+
+ for (i = 0; i < props->count_props; i++) {
+ prop = drmModeGetProperty(b->drm.fd, props->props[i]);
+ if (!prop)
+ continue;
+
+ if (strcmp(prop->name, "WRITEBACK_FB_ID") == 0)
+ break;
+ }
+
+
+ value = prop->prop_id;
+
+ drmModeFreeObjectProperties(props);
+
+ return value;
+}
+
+
/**
* Frees an array of property_items
*
@@ -1659,6 +1884,17 @@ drm_output_populate_atomic_modeset(struct drm_output *output,
ret |= atomic_connector_add(req, output, WDRM_CONNECTOR_CRTC_ID,
enable ? output->ddp_crtc.crtc_id : 0);
+ if(output->wb_connector_id) {
+ if (drmModeAtomicAddProperty(req, output->wb_connector_id,
+ output->props_conn.item[WDRM_CONNECTOR_CRTC_ID].id,
+ output->ddp_crtc.crtc_id) < 0)
+ return -1;
+
+ }
+// if (drmModeAtomicAddProperty(req, output->wb_connector_id,
+// writeback_fb_value_id, output->raw_data->fb_id) < 0)
+// return -1;
+
ret |= atomic_crtc_add(req, output, WDRM_CRTC_MODE_ID,
enable ? mode->blob_id : 0);
ret |= atomic_crtc_add(req, output, WDRM_CRTC_ACTIVE, enable);
@@ -1920,6 +2156,13 @@ drm_output_repaint_atomic(struct weston_output *output_base,
wl_list_insert(&output->plane_flip_list, &plane->flip_link);
}
+ if(output->base.screenshoot_needed == 1 && output->wb_connector_id) {
+ ret = drmModeAtomicAddProperty(req, output->wb_connector_id,
+ output->wb_prop_id,
+ output->raw_data->fb_id);
+ output->base.screenshoot_dump = 1;
+ }
+
flags = DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT;
errno_save = 0;
ret = drmModeAtomicCommit(backend->drm.fd, req, flags, output);
@@ -2183,9 +2426,18 @@ page_flip_handler(int fd, unsigned int frame,
(struct drm_backend *) output->base.compositor->backend;
struct drm_plane *plane, *plane_tmp;
struct timespec ts;
+ char filename[64];
uint32_t flags = WP_PRESENTATION_FEEDBACK_KIND_VSYNC |
WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION |
WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK;
+ if(output->base.screenshoot_dump == 1 && output->wb_connector_id) {
+ snprintf(filename, 64, "/tmp/screen_dump_%u",
+ weston_compositor_get_time());
+ _write_file(output->raw_data->texbuf, output->raw_data->size, filename);
+ output->base.screenshoot_needed = 0;
+ output->base.screenshoot_dump = 0;
+ }
+
drm_output_update_msc(output, frame);
@@ -2315,7 +2567,7 @@ drm_plane_need_mdp_process(struct drm_plane *s,
return 1;
//crop check
if ((crop_x != 0) ||(crop_y != 0) ||
- (crop_w != buf_w) || (crop_h != buf_w))
+ (crop_w != buf_w) || (crop_h != buf_h))
return 1;
//format check
if (drm_format_check(format) < 0)
@@ -4252,6 +4504,7 @@ create_output_for_connector(struct drm_backend *b,
drmModeModeInfo crtc_mode;
int i;
+ int ret;
enum weston_drm_backend_output_mode mode;
struct weston_drm_backend_output_config config = {{ 0 }};
@@ -4393,6 +4646,29 @@ create_output_for_connector(struct drm_backend *b,
/* Set native_ fields, so weston_output_mode_switch_to_native() works */
output->base.native_mode = output->base.current_mode;
output->base.native_scale = output->base.current_scale;
+ output->base.screenshoot_needed = 0;
+ output->base.screenshoot_dump = 0;
+ output->wb_connector_id = 0;
+ if(b->writeback_connectors) {
+ for(i=0; ;i++) {
+ if(b->writeback_connectors & (1 << i))
+ break;
+ }
+ output->wb_connector_id = resources->connectors[i];
+ output->wb_prop_id = drm_properties_get_writeback_fb_value(b,
+ resources->connectors[i],
+ DRM_MODE_OBJECT_CONNECTOR);
+ b->writeback_connectors &= ~(1 << i);
+ weston_log("YR output->wb_connector_id=%d,output->wb_prop_id=%d,output->connector_id=%d\n",output->wb_connector_id,output->wb_prop_id,output->connector_id);
+ weston_log("b->writeback_connectors=%d",b->writeback_connectors);
+ }
+ output->raw_data = (struct raw_texture*)malloc(sizeof(struct raw_texture));
+ ret = drm_alloc_gem_test(b->drm.fd,1920, 1080,
+ DRM_FORMAT_RGB888, output->raw_data);
+ if (ret != 0) {
+ weston_log("drm_alloc_gem_test failed\n");
+ return -1;
+ }
return 0;
@@ -4418,29 +4694,6 @@ err_free:
return -1;
}
-static int
-_write_file(void *buf, int len, const char *file_name)
-{
- int ret, nwrite = 0;
-
- FILE *fp = fopen(file_name, "wb");
- if (!fp)
- {
- fprintf(stderr,"debug: file %s open failed\n", file_name);
- return -1;
- }
-
- while (nwrite < len) {
- ret = fwrite(buf + nwrite, 1, len - nwrite, fp);
- if (!ret)
- break;
- nwrite += ret;
- }
-
- fclose(fp);
- return 0;
-}
-
static int32_t
drm_dump_single_plane_buffer(struct drm_plane *s, int32_t *done)
{
@@ -4737,6 +4990,7 @@ create_outputs(struct drm_backend *b, uint32_t option_connector,
drmModeRes *resources;
int i;
int x = 0, y = 0;
+ b->writeback_connectors = 0;
resources = drmModeGetResources(b->drm.fd);
if (!resources) {
@@ -4764,6 +5018,17 @@ create_outputs(struct drm_backend *b, uint32_t option_connector,
if (connector == NULL)
continue;
+ if (connector->connection == DRM_MODE_DISCONNECTED) {
+ b->writeback_connectors |= 1 << i;
+ }
+ }
+
+ for (i = 0; i < resources->count_connectors; i++) {
+ connector = drmModeGetConnector(b->drm.fd,
+ resources->connectors[i]);
+ if (connector == NULL)
+ continue;
+
if (connector->connection == DRM_MODE_CONNECTED &&
(option_connector == 0 ||
connector->connector_id == option_connector)) {
@@ -5478,6 +5743,7 @@ backend_init(struct weston_compositor *compositor,
return -1;
config_dump_global_create(compositor);
+ screenshooter_mtk_create(compositor);
compositor->dump_plane = drm_dump_plane_buffer;
diff --git a/src/compositor.h b/src/compositor.h
index 3f1948f..22bb5e2 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -257,6 +257,8 @@ struct weston_output {
pixman_region32_t previous_damage;
int repaint_needed;
int repaint_scheduled;
+ int screenshoot_needed;
+ int screenshoot_dump;
struct wl_event_source *repaint_timer;
struct weston_output_zoom zoom;
int dirty;
diff --git a/src/weston-screenshooter-mtk.c b/src/weston-screenshooter-mtk.c
new file mode 100644
index 0000000..eb90275
--- /dev/null
+++ b/src/weston-screenshooter-mtk.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ *
+ * 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 <stdio.h>
+#include <string.h>
+#include <linux/input.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/uio.h>
+
+#include "compositor.h"
+#include "weston-configure-mtk-server-protocol.h"
+#include "shared/helpers.h"
+
+#include "wcap/wcap-decode.h"
+
+struct screenshooter {
+ struct weston_compositor *ec;
+ struct wl_global *global;
+ struct wl_client *client;
+ struct weston_process process;
+ struct wl_listener destroy_listener;
+};
+
+struct screenshooter_frame_listener {
+ struct wl_listener listener;
+ struct weston_buffer *buffer;
+ weston_screenshooter_done_func_t done;
+ void *data;
+};
+
+static void
+weston_screenshooter_mtk_shoot(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *output_resource,
+ struct wl_resource *buffer_resource)
+{
+ struct weston_output *output =
+ wl_resource_get_user_data(output_resource);
+ struct weston_buffer *buffer =
+ weston_buffer_from_resource(buffer_resource);
+ weston_log("weston_screenshooter_mtk_shoot.\n");
+ output->screenshoot_needed = 1;
+ weston_output_schedule_repaint(output);
+ if (buffer == NULL) {
+ wl_resource_post_no_memory(resource);
+ return;
+ }
+
+ weston_screenshooter_mtk_send_done(resource);
+}
+
+static const struct weston_screenshooter_mtk_interface screenshooter_mtk_implementation = {
+ weston_screenshooter_mtk_shoot
+};
+
+static void
+bind_screenshooter_mtk(struct wl_client *client,
+ void *data, uint32_t version, uint32_t id)
+{
+ struct screenshooter *shooter = data;
+ struct wl_resource *resource;
+
+ resource = wl_resource_create(client,
+ &weston_screenshooter_mtk_interface, 1, id);
+
+ if (resource == NULL) {
+ wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
+ "screenshooter failed: permission denied");
+ wl_client_post_no_memory(client);
+ return;
+ }
+
+ wl_resource_set_implementation(resource, &screenshooter_mtk_implementation,
+ data, NULL);
+}
+
+static void
+screenshooter_destroy(struct wl_listener *listener, void *data)
+{
+ struct screenshooter *shooter =
+ container_of(listener, struct screenshooter, destroy_listener);
+
+ wl_global_destroy(shooter->global);
+ free(shooter);
+}
+
+WL_EXPORT void
+screenshooter_mtk_create(struct weston_compositor *ec)
+{
+ struct screenshooter *shooter;
+
+ shooter = malloc(sizeof *shooter);
+ if (shooter == NULL)
+ return;
+
+ shooter->ec = ec;
+ shooter->global = wl_global_create(ec->wl_display,
+ &weston_screenshooter_mtk_interface, 1,
+ shooter, bind_screenshooter_mtk);
+
+ shooter->destroy_listener.notify = screenshooter_destroy;
+ wl_signal_add(&ec->destroy_signal, &shooter->destroy_listener);
+}
--
1.9.1