From ea4a86445a00c475c38a04c9b1cf71633ea5fa3c Mon Sep 17 00:00:00 2001 From: mtk13576 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 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#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, ®istry_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 @@ + + + + + + + + + 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 +#include +#include +#include +#include +#include +#include + +#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