noreceive
___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: Smart comparing of wl_display_interfaces
On Wed, 15 Oct 2014 22:44:25 +0400 Dmitry Cherkassov dcherkas...@gmail.com wrote: Hi list! The definition of wl_display_interface symbol can come from libwayland-server.so or libwayland-client.so. There is a code in closed source EGL implementation that does interfaces comparison via pointers, yielding negative results when addresses are different (one address is saved by QtWayland, the other one is from wl_display_interface in EGL source code). Is there a smarter way to compare wl_display_interface's? There is this function: wl_interface_equal(const struct wl_interface *a, const struct wl_interface *b) { return a == b || strcmp(a-name, b-name) == 0; } But as you can see it's not safe to use it alone because in case of bad pointer we will get undefined results. Currently struct wl_interface is the following: struct wl_interface { const char *name; int version; int method_count; const struct wl_message *methods; int event_count; const struct wl_message *events; }; Since there is no magic field at the beginning it is not possible to see whether a pointer points to the valid wl_interface structure. So my question is: how can we compare wl_interfaces in more clever and safer way? Hmm, why would you ever have a bad pointer? Bad pointers in general tend to cause crashes and stuff, so you shouldn't be having a bad one in the first place. What is the background for your question/problem? Thanks, pq ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH wayland] wl_strtol and wl_strtoul utility functions are added (inlined patch)
Here are my comments: Giulio Camuffo: if we copy-paste the same code to weston as well, means we have to write tests etc for two functions in weston as well; and it will come with maintenance overhead without any benefit of hiding the APIs in wayland (I can take the responsibility of maintaining these two APIs :) Thiago: I can look into strtol_l functions.. Bryce: I will incorporate your changes and also update the test cases. There are cases when it is used other than thr base 10 as well; let me check if there is something that can be done for locale-specific numbers.. I will push the updated patch after the changes.. On Thu, Oct 16, 2014 at 4:05 AM, Bryce Harrington br...@osg.samsung.com wrote: On Wed, Oct 15, 2014 at 04:18:59PM +0300, Imran Zaman wrote: Hi The patch is used to replace strtol and strtoul with wl_strtol and wl_strtoul with inputs and result checks. The utility functions are used extensively in wayland and weston so added These utility... appropriate input and output checks; test cases are also updated; will push the patch for weston as well. Looks like this'll be a nice cleanup. diff --git a/src/scanner.c b/src/scanner.c index 809130b..3e30fe7 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -315,7 +315,6 @@ start_element(void *data, const char *element_name, const char **atts) struct description *description; const char *name, *type, *interface_name, *value, *summary, *since; const char *allow_null; - char *end; int i, version; ctx-loc.line_number = XML_GetCurrentLineNumber(ctx-parser); @@ -404,9 +403,7 @@ start_element(void *data, const char *element_name, const char **atts) message-destructor = 0; if (since != NULL) { - errno = 0; - version = strtol(since, end, 0); - if (errno == EINVAL || end == since || *end != '\0') + if (!wl_strtol(since, NULL, 0, version)) fail(ctx-loc, invalid integer (%s)\n, since); } else { diff --git a/src/wayland-client.c b/src/wayland-client.c index b0f77b9..1229b5f 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -824,13 +824,12 @@ wl_display_connect_to_fd(int fd) WL_EXPORT struct wl_display * wl_display_connect(const char *name) { - char *connection, *end; + char *connection; int flags, fd; connection = getenv(WAYLAND_SOCKET); if (connection) { - fd = strtol(connection, end, 0); - if (*end != '\0') + if (!wl_strtol(connection, NULL, 0, fd)) return NULL; flags = fcntl(fd, F_GETFD); diff --git a/src/wayland-util.c b/src/wayland-util.c index b099882..f8267f3 100644 --- a/src/wayland-util.c +++ b/src/wayland-util.c @@ -26,6 +26,9 @@ #include stdio.h #include string.h #include stdarg.h +#include errno.h +#include limits.h +#include stdlib.h Looks like stdlib.h is already included in wayland-util.c #include wayland-util.h #include wayland-private.h @@ -361,6 +364,42 @@ wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data) for_each_helper(map-server_entries, func, data); } +WL_EXPORT int +wl_strtol(const char *str, char **endptr, int base, int32_t *val) For consistency with strtol shouldn't the final arg be type long? +{ + char *end = NULL; + long v; + + if (!str || !val) return 0; + if (!endptr) endptr = end; + + errno = 0; + v = strtol(str, endptr, base); + if (errno != 0 || *endptr == str || **endptr != '\0') + return 0; + + *val = v; Here's a type conversion between long and int32_t. (Which are both the same thing, but not guaranteed...) + return 1; +} Following the recent return type discussions, maybe consider returning bool (true|false) rather than int. Looks like this function needn't return anything other than 0/1 so a bool would make it unambiguous. + +WL_EXPORT int +wl_strtoul(const char *str, char **endptr, int base, uint32_t *val) +{ + char *end = NULL; + unsigned long v; + + if (!str || !val) return 0; + if (!endptr) endptr = end; + + errno = 0; + v = strtoul(str, endptr, base); + if (errno != 0 || *endptr == str || **endptr != '\0') + return 0; + + *val = v; + return 1; +} + Ditto previous comments. static void wl_log_stderr_handler(const char *fmt, va_list arg) { diff --git a/src/wayland-util.h b/src/wayland-util.h index fd32826..b77d4e3 100644 --- a/src/wayland-util.h +++ b/src/wayland-util.h @@ -243,6 +243,9 @@ static inline wl_fixed_t wl_fixed_from_int(int i) return i * 256; } +int wl_strtol(const char *str, char **endptr, int base, int32_t *val); +int wl_strtoul(const char *str, char **endptr, int base, uint32_t *val); + /** * \brief A union representing all of the basic data types that can be passed * along the wayland wire format. diff --git a/tests/fixed-test.c b/tests/fixed-test.c index 739a3b1..349cc48 100644 --- a/tests/fixed-test.c +++ b/tests/fixed-test.c @@ -88,3 +88,61 @@ TEST(fixed_int_conversions) i = wl_fixed_to_int(f); assert(i == -0x50); } Thanks for including
[PATCH weston v2 02/20] gl-renderer: Call glViewport after the context is made current
From: Jason Ekstrand ja...@jlekstrand.net --- src/gl-renderer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gl-renderer.c b/src/gl-renderer.c index 076c242..d54928b 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -867,15 +867,15 @@ gl_renderer_repaint_output(struct weston_output *output, pixman_region32_t buffer_damage, total_damage; enum gl_border_status border_damage = BORDER_STATUS_CLEAN; + if (use_output(output) 0) + return; + /* Calculate the viewport */ glViewport(go-borders[GL_RENDERER_BORDER_LEFT].width, go-borders[GL_RENDERER_BORDER_BOTTOM].height, output-current_mode-width, output-current_mode-height); - if (use_output(output) 0) - return; - /* if debugging, redraw everything outside the damage to clean up * debug lines from the previous draw on this buffer: */ -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston v2 00/20] Replace existing transformation code with matrix operations
This is also available at https://github.com/ManMower/weston/commits/transforms The goal of this patch set is to remove much of the bulky switch statement based transform code and replace it with matrix multiplication. Hopefully this will result in a more maintainable pixman renderer due to the removal of all the special cases for each screen transform. Major changes since the last revision: - remove full matrix transform decomposition routines: replace it with weston_matrix_needs_filtering based on matrix inspection and weston_matrix_to_transform that does a simpler decompose - changes to how compositor-drm checks for plane viability - addition of weston_view_to_output_matrix() to create the end to end matrix Derek Foreman (14): compositor: Move weston_matrix_transform_region to compositor.c and export it compositor: add weston_matrix_transform_rect() and use it where appropriate compositor: use matrix transforms for surface_to_buffer functions compositor: use weston_matrix_transform_region for overlay setup compositor: Remove weston_transformed_region compositor: Add a function to test if images transformed by a matrix should be bilinearly filtered renderers: use weston_matrix_needs_filtering to choose filter parameters in gl and pixman renderers compositor-drm: use weston_surface_to_buffer_rect instead of weston_transformed_rect compositor: Remove weston_transformed_rect() and weston_transformed_coord() compositor: use weston_matrix_transform for weston_output_transform_coordinate compositor: Add weston_matrix_to_transform function compositor: add weston_view_to_output_matrix() renderers: use weston_view_to_output_matrix() in renderers compositor-drm: use weston_view_to_output_matrix() to test plane viability Jason Ekstrand (6): weston_surface: Add surface-to-buffer and buffer-to-surface matrices gl-renderer: Call glViewport after the context is made current Use pixel coordinates for weston_output.matrix zoom: Use pixels instead of GL coordinates pixman-renderer: Add a weston_matrix_to_pixman_transform function and simplify the buffer-to-output matrix computation pixman-renderer: Use output-matrix for region transformations and enable output zoom src/compositor-drm.c | 85 +++ src/compositor-wayland.c | 8 +- src/compositor-x11.c | 8 +- src/compositor.c | 589 ++- src/compositor.h | 41 ++-- src/gl-renderer.c| 35 ++- src/pixman-renderer.c| 173 ++ src/screen-share.c | 8 +- src/screenshooter.c | 7 +- src/zoom.c | 38 ++- 10 files changed, 402 insertions(+), 590 deletions(-) -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston v2 17/20] compositor: Add weston_matrix_to_transform function
This function examines a matrix to see if it can be built with simple scale + translate + wl_output_transform enum. --- src/compositor.c | 57 src/compositor.h | 5 + 2 files changed, 62 insertions(+) diff --git a/src/compositor.c b/src/compositor.c index ba9f886..d629bd7 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -754,6 +754,63 @@ weston_matrix_needs_filtering(struct weston_matrix *matrix) return false; } +WL_EXPORT bool +weston_matrix_to_transform(const struct weston_matrix *mat, + enum wl_output_transform *transform, + float *sx, float *sy, + float *tx, float *ty) +{ + if (!near_zero(mat-d[2]) || !near_zero(mat-d[3]) || + !near_zero(mat-d[6]) || !near_zero(mat-d[7]) || + !near_zero(mat-d[8]) || !near_zero(mat-d[9]) || + !near_zero(mat-d[11])) + return false; + + if (!near_zero(mat-d[10] - 1.0) || !near_zero(mat-d[15] - 1.0)) + return false; + + if (near_zero(mat-d[0])) { + if (!near_zero(mat-d[5])) + return false; + + if (mat-d[4] 0) { + if (mat-d[1] 0) + *transform = WL_OUTPUT_TRANSFORM_FLIPPED_270; + else + *transform = WL_OUTPUT_TRANSFORM_270; + } else { + if (mat-d[1] 0) + *transform = WL_OUTPUT_TRANSFORM_90; + else + *transform = WL_OUTPUT_TRANSFORM_FLIPPED_90; + } + *sx = fabs(mat-d[1]); + *sy = fabs(mat-d[4]); + } else if (near_zero(mat-d[1])) { + if (!near_zero(mat-d[4])) + return false; + + if (mat-d[0] 0) { + if (mat-d[5] 0) + *transform = WL_OUTPUT_TRANSFORM_NORMAL; + else + *transform = WL_OUTPUT_TRANSFORM_FLIPPED_180; + } else { + if (mat-d[5] 0) + *transform = WL_OUTPUT_TRANSFORM_FLIPPED; + else + *transform = WL_OUTPUT_TRANSFORM_180; + } + *sx = fabs(mat-d[0]); + *sy = fabs(mat-d[5]); + } else return false; + + *tx = mat-d[12]; + *ty = mat-d[13]; + + return true; +} + WL_EXPORT void weston_surface_to_buffer_float(struct weston_surface *surface, float sx, float sy, float *bx, float *by) diff --git a/src/compositor.h b/src/compositor.h index 8d98306..8e2cf47 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -991,6 +991,11 @@ weston_view_from_global_fixed(struct weston_view *view, bool weston_matrix_needs_filtering(struct weston_matrix *matrix); +bool +weston_matrix_to_transform(const struct weston_matrix *mat, + enum wl_output_transform *transform, + float *sx, float *sy, + float *tx, float *ty); void weston_surface_to_buffer_float(struct weston_surface *surface, float x, float y, float *bx, float *by); -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston v2 03/20] Use pixel coordinates for weston_output.matrix
From: Jason Ekstrand ja...@jlekstrand.net Previously, weston_output.matrix was in GL coordinates and therefore only really useful for the GL backend. --- src/compositor.c | 106 -- src/gl-renderer.c | 14 +++- 2 files changed, 52 insertions(+), 68 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index c85cf2e..5d8bd5e 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -3480,88 +3480,60 @@ weston_output_destroy(struct weston_output *output) wl_global_destroy(output-global); } -static void -weston_output_compute_transform(struct weston_output *output) -{ - struct weston_matrix transform; - int flip; - - weston_matrix_init(transform); - transform.type = WESTON_MATRIX_TRANSFORM_ROTATE; - - switch(output-transform) { - case WL_OUTPUT_TRANSFORM_FLIPPED: - case WL_OUTPUT_TRANSFORM_FLIPPED_90: - case WL_OUTPUT_TRANSFORM_FLIPPED_180: - case WL_OUTPUT_TRANSFORM_FLIPPED_270: - transform.type |= WESTON_MATRIX_TRANSFORM_OTHER; - flip = -1; - break; - default: - flip = 1; - break; - } - -switch(output-transform) { -case WL_OUTPUT_TRANSFORM_NORMAL: -case WL_OUTPUT_TRANSFORM_FLIPPED: -transform.d[0] = flip; -transform.d[1] = 0; -transform.d[4] = 0; -transform.d[5] = 1; -break; -case WL_OUTPUT_TRANSFORM_90: -case WL_OUTPUT_TRANSFORM_FLIPPED_90: -transform.d[0] = 0; -transform.d[1] = -flip; -transform.d[4] = 1; -transform.d[5] = 0; -break; -case WL_OUTPUT_TRANSFORM_180: -case WL_OUTPUT_TRANSFORM_FLIPPED_180: -transform.d[0] = -flip; -transform.d[1] = 0; -transform.d[4] = 0; -transform.d[5] = -1; -break; -case WL_OUTPUT_TRANSFORM_270: -case WL_OUTPUT_TRANSFORM_FLIPPED_270: -transform.d[0] = 0; -transform.d[1] = flip; -transform.d[4] = -1; -transform.d[5] = 0; -break; -default: -break; -} - - weston_matrix_multiply(output-matrix, transform); -} - WL_EXPORT void weston_output_update_matrix(struct weston_output *output) { float magnification; weston_matrix_init(output-matrix); - weston_matrix_translate(output-matrix, - -(output-x + output-width / 2.0), - -(output-y + output-height / 2.0), 0); - - weston_matrix_scale(output-matrix, - 2.0 / output-width, - -2.0 / output-height, 1); + weston_matrix_translate(output-matrix, -output-x, -output-y, 0); if (output-zoom.active) { magnification = 1 / (1 - output-zoom.spring_z.current); weston_output_update_zoom(output); weston_matrix_translate(output-matrix, -output-zoom.trans_x, - output-zoom.trans_y, 0); + -output-zoom.trans_y, 0); weston_matrix_scale(output-matrix, magnification, magnification, 1.0); } - weston_output_compute_transform(output); + switch (output-transform) { + case WL_OUTPUT_TRANSFORM_FLIPPED: + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + weston_matrix_translate(output-matrix, -output-width, 0, 0); + weston_matrix_scale(output-matrix, -1, 1, 1); + break; + } + + switch (output-transform) { + default: + case WL_OUTPUT_TRANSFORM_NORMAL: + case WL_OUTPUT_TRANSFORM_FLIPPED: + break; + case WL_OUTPUT_TRANSFORM_90: + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + weston_matrix_translate(output-matrix, 0, -output-height, 0); + weston_matrix_rotate_xy(output-matrix, 0, 1); + break; + case WL_OUTPUT_TRANSFORM_180: + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + weston_matrix_translate(output-matrix, + -output-width, -output-height, 0); + weston_matrix_rotate_xy(output-matrix, -1, 0); + break; + case WL_OUTPUT_TRANSFORM_270: + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + weston_matrix_translate(output-matrix, -output-width, 0, 0); + weston_matrix_rotate_xy(output-matrix, 0, -1); + break; + } + + if (output-current_scale != 1) + weston_matrix_scale(output-matrix, +
[PATCH weston v2 08/20] compositor: add weston_matrix_transform_rect() and use it where appropriate
New function that transforms a pixman_box32_t rectangle by a matrix. Since pixman rectangles are represented by 2 corners, non-90 degree rotations can't be properly represented. This function gives the axis aligned rectangle that encloses the rotated rectangle. We use this for matrix_transform_region() and weston_matrix_transform_rect(), simplifying them and allowing them to work for non 90 degree rotations. --- src/compositor.c | 96 src/compositor.h | 4 +++ 2 files changed, 52 insertions(+), 48 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index e45dd62..7c0f050 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -654,6 +654,50 @@ weston_view_to_global_float(struct weston_view *view, } } +WL_EXPORT pixman_box32_t +weston_matrix_transform_rect(struct weston_matrix *matrix, +pixman_box32_t rect) +{ + int i; + pixman_box32_t out; + + /* since pixman regions are defined by two corners we have +* to be careful with rotations that aren't multiples of 90. +* We need to take all four corners of the region and rotate +* them, then construct the largest possible two corner +* rectangle from the result. +*/ + struct weston_vector corners[4] = { + {{rect.x1, rect.y1, 0, 1}}, + {{rect.x2, rect.y1, 0, 1}}, + {{rect.x1, rect.y2, 0, 1}}, + {{rect.x2, rect.y2, 0, 1}}, + }; + + for (i = 0; i 4; i++) { + weston_matrix_transform(matrix, corners[i]); + corners[i].f[0] /= corners[i].f[3]; + corners[i].f[1] /= corners[i].f[3]; + } + + out.x1 = floor(corners[0].f[0]); + out.y1 = floor(corners[0].f[1]); + out.x2 = ceil(corners[0].f[0]); + out.y2 = ceil(corners[0].f[1]); + + for (i = 1; i 4; i++) { + if (floor(corners[i].f[0]) out.x1) + out.x1 = floor(corners[i].f[0]); + if (floor(corners[i].f[1]) out.y1) + out.y1 = floor(corners[i].f[1]); + if (ceil(corners[i].f[0]) out.x2) + out.x2 = ceil(corners[i].f[0]); + if (ceil(corners[i].f[1]) out.y2) + out.y2 = ceil(corners[i].f[1]); + } + return out; +} + WL_EXPORT void weston_transformed_coord(int width, int height, enum wl_output_transform transform, @@ -747,38 +791,8 @@ weston_matrix_transform_region(pixman_region32_t *dest, if (!dest_rects) return; - for (i = 0; i nrects; i++) { - struct weston_vector vec1 = {{ - src_rects[i].x1, src_rects[i].y1, 0, 1 - }}; - weston_matrix_transform(matrix, vec1); - vec1.f[0] /= vec1.f[3]; - vec1.f[1] /= vec1.f[3]; - - struct weston_vector vec2 = {{ - src_rects[i].x2, src_rects[i].y2, 0, 1 - }}; - weston_matrix_transform(matrix, vec2); - vec2.f[0] /= vec2.f[3]; - vec2.f[1] /= vec2.f[3]; - - if (vec1.f[0] vec2.f[0]) { - dest_rects[i].x1 = floor(vec1.f[0]); - dest_rects[i].x2 = ceil(vec2.f[0]); - } else { - dest_rects[i].x1 = floor(vec2.f[0]); - dest_rects[i].x2 = ceil(vec1.f[0]); - } - - - if (vec1.f[1] vec2.f[1]) { - dest_rects[i].y1 = floor(vec1.f[1]); - dest_rects[i].y2 = ceil(vec2.f[1]); - } else { - dest_rects[i].y1 = floor(vec2.f[1]); - dest_rects[i].y2 = ceil(vec1.f[1]); - } - } + for (i = 0; i nrects; i++) + dest_rects[i] = weston_matrix_transform_rect(matrix, src_rects[i]); pixman_region32_clear(dest); pixman_region32_init_rects(dest, dest_rects, nrects); @@ -939,22 +953,8 @@ WL_EXPORT pixman_box32_t weston_surface_to_buffer_rect(struct weston_surface *surface, pixman_box32_t rect) { - struct weston_buffer_viewport *vp = surface-buffer_viewport; - float xf, yf; - - /* first transform box coordinates if the scaler is set */ - scaler_surface_to_buffer(surface, rect.x1, rect.y1, xf, yf); - rect.x1 = floorf(xf); - rect.y1 = floorf(yf); - - scaler_surface_to_buffer(surface, rect.x2, rect.y2, xf, yf); - rect.x2 = floorf(xf); - rect.y2 = floorf(yf); - - return weston_transformed_rect(surface-width_from_buffer, - surface-height_from_buffer, - vp-buffer.transform, vp-buffer.scale, - rect); + return
[PATCH weston v2 12/20] compositor: Add a function to test if images transformed by a matrix should be bilinearly filtered
If a transformation matrix causes a scale, a rotation not a multiple of 90 degrees or a non-integer translation then textures rendered with it would benefit from bilinear filtering. This test is done in a lazy fashion by examining elements of the matrix to check for a simple pattern that indicates these conditions are met. --- src/compositor.c | 35 +++ src/compositor.h | 4 2 files changed, 39 insertions(+) diff --git a/src/compositor.c b/src/compositor.c index 68fbd71..00d404d 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -799,6 +799,41 @@ weston_matrix_transform_region(pixman_region32_t *dest, free(dest_rects); } +static bool near_zero(float a) +{ + if (fabs(a) 0.0001) + return false; + + return true; +} + +WL_EXPORT bool +weston_matrix_needs_filtering(struct weston_matrix *matrix) +{ + /* check for non-integral x/y translation */ + if ((nearbyintf(matrix-d[12]) != matrix-d[12]) || + (nearbyintf(matrix-d[13]) != matrix-d[13])) + return true; + + if (!near_zero(matrix-d[3]) || !near_zero(matrix-d[7]) || + !near_zero(matrix-d[15] - 1.0)) + return true; + + if (near_zero(matrix-d[0])) { + if (!near_zero(matrix-d[5]) || + !near_zero(fabsf(matrix-d[1]) - 1.0) || + !near_zero(fabsf(matrix-d[4]) - 1.0)) + return true; + } else { + if (!near_zero(matrix-d[1]) || !near_zero(matrix-d[4]) || + !near_zero(fabsf(matrix-d[0]) - 1.0) || + !near_zero(fabsf(matrix-d[5]) - 1.0)) + return true; + } + + return false; +} + WL_EXPORT void weston_surface_to_buffer_float(struct weston_surface *surface, float sx, float sy, float *bx, float *by) diff --git a/src/compositor.h b/src/compositor.h index 4fdf4dc..bc22026 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -28,6 +28,7 @@ extern C { #endif +#include stdbool.h #include time.h #include pixman.h #include xkbcommon/xkbcommon.h @@ -987,6 +988,9 @@ weston_view_from_global_fixed(struct weston_view *view, wl_fixed_t x, wl_fixed_t y, wl_fixed_t *vx, wl_fixed_t *vy); +bool +weston_matrix_needs_filtering(struct weston_matrix *matrix); + void weston_surface_to_buffer_float(struct weston_surface *surface, float x, float y, float *bx, float *by); -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston v2 18/20] compositor: add weston_view_to_output_matrix()
New function that creates a matrix that can transform buffer co-ordinates to output co-ordinates (or the inverse of that matrix). --- src/compositor.c | 19 +++ src/compositor.h | 6 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/compositor.c b/src/compositor.c index d629bd7..36fd7cc 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -845,6 +845,25 @@ weston_surface_to_buffer_rect(struct weston_surface *surface, } WL_EXPORT void +weston_view_to_output_matrix(struct weston_view *view, +struct weston_output *op, +bool inverse, +struct weston_matrix *matrix) +{ + *matrix = view-surface-buffer_to_surface_matrix; + if (view-transform.enabled) + weston_matrix_multiply(matrix, view-transform.matrix); + else + weston_matrix_translate(matrix, + view-geometry.x, + view-geometry.y, 0); + weston_matrix_multiply(matrix, op-matrix); + + if (inverse) + weston_matrix_invert(matrix, matrix); +} + +WL_EXPORT void weston_view_move_to_plane(struct weston_view *view, struct weston_plane *plane) { diff --git a/src/compositor.h b/src/compositor.h index 8e2cf47..b375262 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -1005,7 +1005,11 @@ weston_surface_to_buffer(struct weston_surface *surface, pixman_box32_t weston_surface_to_buffer_rect(struct weston_surface *surface, pixman_box32_t rect); - +void +weston_view_to_output_matrix(struct weston_view *view, +struct weston_output *op, +bool inverse, +struct weston_matrix *matrix); void weston_spring_init(struct weston_spring *spring, double k, double current, double target); -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston v2 14/20] compositor-drm: use weston_surface_to_buffer_rect instead of weston_transformed_rect
The weston_transformed_rect() call should have the same result as weston_surface_to_buffer_rect(). Also, this mix of fixed, float, and int is difficult to follow and I don't trust it, so just convert to fixed for the plane API at the end of the calculation. --- src/compositor-drm.c | 34 -- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index c997c26..c0f451e 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -844,7 +844,7 @@ drm_output_prepare_overlay_view(struct weston_output *output_base, pixman_region32_t dest_rect, src_rect; pixman_box32_t *box, tbox; uint32_t format; - wl_fixed_t sx1, sy1, sx2, sy2; + int32_t sx1, sy1, sx2, sy2; if (c-gbm == NULL) return NULL; @@ -933,39 +933,29 @@ drm_output_prepare_overlay_view(struct weston_output *output_base, output_base-region); box = pixman_region32_extents(src_rect); - weston_view_from_global_fixed(ev, - wl_fixed_from_int(box-x1), - wl_fixed_from_int(box-y1), - sx1, sy1); - weston_view_from_global_fixed(ev, - wl_fixed_from_int(box-x2), - wl_fixed_from_int(box-y2), - sx2, sy2); + weston_view_from_global(ev, box-x1, box-y1, sx1, sy1); + weston_view_from_global(ev, box-x2, box-y2, sx2, sy2); if (sx1 0) sx1 = 0; if (sy1 0) sy1 = 0; - if (sx2 wl_fixed_from_int(ev-surface-width)) - sx2 = wl_fixed_from_int(ev-surface-width); - if (sy2 wl_fixed_from_int(ev-surface-height)) - sy2 = wl_fixed_from_int(ev-surface-height); + if (sx2 ev-surface-width) + sx2 = ev-surface-width; + if (sy2 ev-surface-height) + sy2 = ev-surface-height; tbox.x1 = sx1; tbox.y1 = sy1; tbox.x2 = sx2; tbox.y2 = sy2; - tbox = weston_transformed_rect(wl_fixed_from_int(ev-surface-width), - wl_fixed_from_int(ev-surface-height), - viewport-buffer.transform, - viewport-buffer.scale, - tbox); + tbox = weston_surface_to_buffer_rect(ev-surface, tbox); - s-src_x = tbox.x1 8; - s-src_y = tbox.y1 8; - s-src_w = (tbox.x2 - tbox.x1) 8; - s-src_h = (tbox.y2 - tbox.y1) 8; + s-src_x = wl_fixed_from_int(tbox.x1); + s-src_y = wl_fixed_from_int(tbox.y1); + s-src_w = wl_fixed_from_int(tbox.x2 - tbox.x1); + s-src_h = wl_fixed_from_int(tbox.y2 - tbox.y1); pixman_region32_fini(src_rect); return s-plane; -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston v2 15/20] compositor: Remove weston_transformed_rect() and weston_transformed_coord()
The last caller of weston_transformed_rect() has been replaced so we can remove weston_transformed_rect() - since it was the last caller of weston_transformed_coord() we can get rid of that too. --- src/compositor.c | 80 src/compositor.h | 10 --- 2 files changed, 90 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 00d404d..aef3246 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -699,86 +699,6 @@ weston_matrix_transform_rect(struct weston_matrix *matrix, } WL_EXPORT void -weston_transformed_coord(int width, int height, -enum wl_output_transform transform, -int32_t scale, -float sx, float sy, float *bx, float *by) -{ - switch (transform) { - case WL_OUTPUT_TRANSFORM_NORMAL: - default: - *bx = sx; - *by = sy; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED: - *bx = width - sx; - *by = sy; - break; - case WL_OUTPUT_TRANSFORM_90: - *bx = height - sy; - *by = sx; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED_90: - *bx = height - sy; - *by = width - sx; - break; - case WL_OUTPUT_TRANSFORM_180: - *bx = width - sx; - *by = height - sy; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED_180: - *bx = sx; - *by = height - sy; - break; - case WL_OUTPUT_TRANSFORM_270: - *bx = sy; - *by = width - sx; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED_270: - *bx = sy; - *by = sx; - break; - } - - *bx *= scale; - *by *= scale; -} - -WL_EXPORT pixman_box32_t -weston_transformed_rect(int width, int height, - enum wl_output_transform transform, - int32_t scale, - pixman_box32_t rect) -{ - float x1, x2, y1, y2; - - pixman_box32_t ret; - - weston_transformed_coord(width, height, transform, scale, -rect.x1, rect.y1, x1, y1); - weston_transformed_coord(width, height, transform, scale, -rect.x2, rect.y2, x2, y2); - - if (x1 = x2) { - ret.x1 = x1; - ret.x2 = x2; - } else { - ret.x1 = x2; - ret.x2 = x1; - } - - if (y1 = y2) { - ret.y1 = y1; - ret.y2 = y2; - } else { - ret.y1 = y2; - ret.y2 = y1; - } - - return ret; -} - -WL_EXPORT void weston_matrix_transform_region(pixman_region32_t *dest, struct weston_matrix *matrix, pixman_region32_t *src) diff --git a/src/compositor.h b/src/compositor.h index bc22026..8d98306 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -1462,16 +1462,6 @@ weston_matrix_transform_rect(struct weston_matrix *matrix, pixman_box32_t rect); void -weston_transformed_coord(int width, int height, -enum wl_output_transform transform, -int32_t scale, -float sx, float sy, float *bx, float *by); -pixman_box32_t -weston_transformed_rect(int width, int height, - enum wl_output_transform transform, - int32_t scale, - pixman_box32_t rect); -void weston_matrix_transform_region(pixman_region32_t *dest, struct weston_matrix *matrix, pixman_region32_t *src); -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston v2 05/20] pixman-renderer: Add a weston_matrix_to_pixman_transform function and simplify the buffer-to-output matrix computation
From: Jason Ekstrand ja...@jlekstrand.net Now that we have a buffer-to-surface matrix and the global-to-output matrix is in pixels, we can remove a large chunk of confusing code from the pixman renderer. Hopefully, having this stuff in weston core will keep the pixman renderer from gettin broken quite as often. --- src/pixman-renderer.c | 155 +++--- 1 file changed, 20 insertions(+), 135 deletions(-) diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c index 2c26c3a..18b6476 100644 --- a/src/pixman-renderer.c +++ b/src/pixman-renderer.c @@ -139,32 +139,20 @@ region_global_to_output(struct weston_output *output, pixman_region32_t *region) #define D2F(v) pixman_double_to_fixed((double)v) static void -transform_apply_viewport(pixman_transform_t *transform, -struct weston_surface *surface) +weston_matrix_to_pixman_transform(pixman_transform_t *pt, + const struct weston_matrix *wm) { - struct weston_buffer_viewport *vp = surface-buffer_viewport; - double src_width, src_height; - double src_x, src_y; - - if (vp-buffer.src_width == wl_fixed_from_int(-1)) { - if (vp-surface.width == -1) - return; - - src_x = 0.0; - src_y = 0.0; - src_width = surface-width_from_buffer; - src_height = surface-height_from_buffer; - } else { - src_x = wl_fixed_to_double(vp-buffer.src_x); - src_y = wl_fixed_to_double(vp-buffer.src_y); - src_width = wl_fixed_to_double(vp-buffer.src_width); - src_height = wl_fixed_to_double(vp-buffer.src_height); - } - - pixman_transform_scale(transform, NULL, - D2F(src_width / surface-width), - D2F(src_height / surface-height)); - pixman_transform_translate(transform, NULL, D2F(src_x), D2F(src_y)); + /* Pixman supports only 2D transform matrix, but Weston uses 3D, * +* so we're omitting Z coordinate here. */ + pt-matrix[0][0] = pixman_double_to_fixed(wm-d[0]); + pt-matrix[0][1] = pixman_double_to_fixed(wm-d[4]); + pt-matrix[0][2] = pixman_double_to_fixed(wm-d[12]); + pt-matrix[1][0] = pixman_double_to_fixed(wm-d[1]); + pt-matrix[1][1] = pixman_double_to_fixed(wm-d[5]); + pt-matrix[1][2] = pixman_double_to_fixed(wm-d[13]); + pt-matrix[2][0] = pixman_double_to_fixed(wm-d[3]); + pt-matrix[2][1] = pixman_double_to_fixed(wm-d[7]); + pt-matrix[2][2] = pixman_double_to_fixed(wm-d[15]); } static void @@ -180,7 +168,7 @@ repaint_region(struct weston_view *ev, struct weston_output *output, pixman_region32_t final_region; float view_x, view_y; pixman_transform_t transform; - pixman_fixed_t fw, fh; + struct weston_matrix matrix; pixman_image_t *mask_image; pixman_color_t mask = { 0, }; @@ -217,121 +205,18 @@ repaint_region(struct weston_view *ev, struct weston_output *output, /* Set up the source transformation based on the surface position, the output position/transform/scale and the client specified buffer transform/scale */ - pixman_transform_init_identity(transform); - pixman_transform_scale(transform, NULL, - pixman_double_to_fixed ((double)1.0/output-current_scale), - pixman_double_to_fixed ((double)1.0/output-current_scale)); - - fw = pixman_int_to_fixed(output-width); - fh = pixman_int_to_fixed(output-height); - switch (output-transform) { - default: - case WL_OUTPUT_TRANSFORM_NORMAL: - case WL_OUTPUT_TRANSFORM_FLIPPED: - break; - case WL_OUTPUT_TRANSFORM_90: - case WL_OUTPUT_TRANSFORM_FLIPPED_90: - pixman_transform_rotate(transform, NULL, 0, -pixman_fixed_1); - pixman_transform_translate(transform, NULL, 0, fh); - break; - case WL_OUTPUT_TRANSFORM_180: - case WL_OUTPUT_TRANSFORM_FLIPPED_180: - pixman_transform_rotate(transform, NULL, -pixman_fixed_1, 0); - pixman_transform_translate(transform, NULL, fw, fh); - break; - case WL_OUTPUT_TRANSFORM_270: - case WL_OUTPUT_TRANSFORM_FLIPPED_270: - pixman_transform_rotate(transform, NULL, 0, pixman_fixed_1); - pixman_transform_translate(transform, NULL, fw, 0); - break; - } - - switch (output-transform) { - case WL_OUTPUT_TRANSFORM_FLIPPED: - case WL_OUTPUT_TRANSFORM_FLIPPED_90: - case WL_OUTPUT_TRANSFORM_FLIPPED_180: - case WL_OUTPUT_TRANSFORM_FLIPPED_270: - pixman_transform_scale(transform, NULL, - pixman_int_to_fixed (-1), -
[PATCH weston v2 09/20] compositor: use matrix transforms for surface_to_buffer functions
Now that we have weston_matrix_transform and appropriate matrices we can use that instead of weston_transformed_coord + scaler_surface_to_buffer. scaler_surface_to_buffer no longer has users, so remove it. --- src/compositor.c | 41 - 1 file changed, 4 insertions(+), 37 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 7c0f050..b2b10dd 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -891,49 +891,16 @@ weston_transformed_region(int width, int height, free(dest_rects); } -static void -scaler_surface_to_buffer(struct weston_surface *surface, -float sx, float sy, float *bx, float *by) -{ - struct weston_buffer_viewport *vp = surface-buffer_viewport; - double src_width, src_height; - double src_x, src_y; - - if (vp-buffer.src_width == wl_fixed_from_int(-1)) { - if (vp-surface.width == -1) { - *bx = sx; - *by = sy; - return; - } - - src_x = 0.0; - src_y = 0.0; - src_width = surface-width_from_buffer; - src_height = surface-height_from_buffer; - } else { - src_x = wl_fixed_to_double(vp-buffer.src_x); - src_y = wl_fixed_to_double(vp-buffer.src_y); - src_width = wl_fixed_to_double(vp-buffer.src_width); - src_height = wl_fixed_to_double(vp-buffer.src_height); - } - - *bx = sx * src_width / surface-width + src_x; - *by = sy * src_height / surface-height + src_y; -} - WL_EXPORT void weston_surface_to_buffer_float(struct weston_surface *surface, float sx, float sy, float *bx, float *by) { - struct weston_buffer_viewport *vp = surface-buffer_viewport; + struct weston_vector v = {{sx, sy, 0.0, 1.0}}; - /* first transform coordinates if the scaler is set */ - scaler_surface_to_buffer(surface, sx, sy, bx, by); + weston_matrix_transform(surface-surface_to_buffer_matrix, v); - weston_transformed_coord(surface-width_from_buffer, -surface-height_from_buffer, -vp-buffer.transform, vp-buffer.scale, -*bx, *by, bx, by); + *bx = v.f[0] / v.f[3]; + *by = v.f[1] / v.f[3]; } WL_EXPORT void -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston v2 11/20] compositor: Remove weston_transformed_region
Replace all uses of weston_transform_region with weston_matrix_transform_region, then remove the function completely. --- src/compositor-wayland.c | 8 ++--- src/compositor-x11.c | 8 + src/compositor.c | 92 src/compositor.h | 6 src/gl-renderer.c| 11 +++--- src/pixman-renderer.c| 10 +- src/screen-share.c | 8 ++--- src/screenshooter.c | 7 ++-- 8 files changed, 19 insertions(+), 131 deletions(-) diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c index bf71a76..f571910 100644 --- a/src/compositor-wayland.c +++ b/src/compositor-wayland.c @@ -502,11 +502,9 @@ wayland_shm_buffer_attach(struct wayland_shm_buffer *sb) int i, n; pixman_region32_init(damage); - weston_transformed_region(sb-output-base.width, - sb-output-base.height, - sb-output-base.transform, - sb-output-base.current_scale, - sb-damage, damage); + pixman_region32_copy(damage, sb-damage); + pixman_region32_translate(damage, sb-output-base.x, sb-output-base.y); + weston_matrix_transform_region(damage, sb-output-base.matrix, damage); if (sb-output-frame) { frame_interior(sb-output-frame, ix, iy, iwidth, iheight); diff --git a/src/compositor-x11.c b/src/compositor-x11.c index 1baee29..971c718 100644 --- a/src/compositor-x11.c +++ b/src/compositor-x11.c @@ -374,13 +374,7 @@ set_clip_for_output(struct weston_output *output_base, pixman_region32_t *region xcb_generic_error_t *err; pixman_region32_init(transformed_region); - pixman_region32_copy(transformed_region, region); - pixman_region32_translate(transformed_region, - -output_base-x, -output_base-y); - weston_transformed_region(output_base-width, output_base-height, - output_base-transform, - output_base-current_scale, - transformed_region, transformed_region); + weston_matrix_transform_region(transformed_region, output_base-matrix, region); rects = pixman_region32_rectangles(transformed_region, nrects); output_rects = calloc(nrects, sizeof(xcb_rectangle_t)); diff --git a/src/compositor.c b/src/compositor.c index b2b10dd..68fbd71 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -800,98 +800,6 @@ weston_matrix_transform_region(pixman_region32_t *dest, } WL_EXPORT void -weston_transformed_region(int width, int height, - enum wl_output_transform transform, - int32_t scale, - pixman_region32_t *src, pixman_region32_t *dest) -{ - pixman_box32_t *src_rects, *dest_rects; - int nrects, i; - - if (transform == WL_OUTPUT_TRANSFORM_NORMAL scale == 1) { - if (src != dest) - pixman_region32_copy(dest, src); - return; - } - - src_rects = pixman_region32_rectangles(src, nrects); - dest_rects = malloc(nrects * sizeof(*dest_rects)); - if (!dest_rects) - return; - - if (transform == WL_OUTPUT_TRANSFORM_NORMAL) { - memcpy(dest_rects, src_rects, nrects * sizeof(*dest_rects)); - } else { - for (i = 0; i nrects; i++) { - switch (transform) { - default: - case WL_OUTPUT_TRANSFORM_NORMAL: - dest_rects[i].x1 = src_rects[i].x1; - dest_rects[i].y1 = src_rects[i].y1; - dest_rects[i].x2 = src_rects[i].x2; - dest_rects[i].y2 = src_rects[i].y2; - break; - case WL_OUTPUT_TRANSFORM_90: - dest_rects[i].x1 = height - src_rects[i].y2; - dest_rects[i].y1 = src_rects[i].x1; - dest_rects[i].x2 = height - src_rects[i].y1; - dest_rects[i].y2 = src_rects[i].x2; - break; - case WL_OUTPUT_TRANSFORM_180: - dest_rects[i].x1 = width - src_rects[i].x2; - dest_rects[i].y1 = height - src_rects[i].y2; - dest_rects[i].x2 = width - src_rects[i].x1; - dest_rects[i].y2 = height - src_rects[i].y1; - break; - case WL_OUTPUT_TRANSFORM_270: - dest_rects[i].x1 = src_rects[i].y1; - dest_rects[i].y1 = width - src_rects[i].x2; - dest_rects[i].x2 = src_rects[i].y2; -
[PATCH weston v2 13/20] renderers: use weston_matrix_needs_filtering to choose filter parameters in gl and pixman renderers
Note: This causes a performance drop when zoomed under pixman. Also, pixman has clever optimization algorithms to switch from BILINEAR to NEAREST automatically when it detects they'll have the same result - we still do our own test here because the pixman check misses a few opportunities when the display is flipped. --- src/gl-renderer.c | 11 +-- src/pixman-renderer.c | 3 +-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/gl-renderer.c b/src/gl-renderer.c index cfc1e88..e1ad5ca 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -528,6 +528,7 @@ static void draw_view(struct weston_view *ev, struct weston_output *output, pixman_region32_t *damage) /* in global coordinates */ { + struct weston_matrix transform; struct weston_compositor *ec = ev-surface-compositor; struct gl_renderer *gr = get_renderer(ec); struct gl_surface_state *gs = get_surface_state(ev-surface); @@ -561,9 +562,15 @@ draw_view(struct weston_view *ev, struct weston_output *output, use_shader(gr, gs-shader); shader_uniforms(gs-shader, ev, output); + transform = ev-surface-buffer_to_surface_matrix; + if (ev-transform.enabled) + weston_matrix_multiply(transform, ev-transform.matrix); + else + weston_matrix_translate(transform, + ev-geometry.x, ev-geometry.y, 0); + weston_matrix_multiply(transform, output-matrix); - if (ev-transform.enabled || output-zoom.active || - output-current_scale != ev-surface-buffer_viewport.buffer.scale) + if (weston_matrix_needs_filtering(transform)) filter = GL_LINEAR; else filter = GL_NEAREST; diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c index 2f54a64..f6fe3c7 100644 --- a/src/pixman-renderer.c +++ b/src/pixman-renderer.c @@ -161,7 +161,6 @@ repaint_region(struct weston_view *ev, struct weston_output *output, (struct pixman_renderer *) output-compositor-renderer; struct pixman_surface_state *ps = get_surface_state(ev-surface); struct pixman_output_state *po = get_output_state(output); - struct weston_buffer_viewport *vp = ev-surface-buffer_viewport; pixman_region32_t final_region; float view_x, view_y; pixman_transform_t transform; @@ -216,7 +215,7 @@ repaint_region(struct weston_view *ev, struct weston_output *output, weston_matrix_to_pixman_transform(transform, matrix); pixman_image_set_transform(ps-image, transform); - if (ev-transform.enabled || output-current_scale != vp-buffer.scale) + if (weston_matrix_needs_filtering(matrix)) pixman_image_set_filter(ps-image, PIXMAN_FILTER_BILINEAR, NULL, 0); else pixman_image_set_filter(ps-image, PIXMAN_FILTER_NEAREST, NULL, 0); -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston v2 07/20] compositor: Move weston_matrix_transform_region to compositor.c and export it
We're going to use this to replace much of the other transform code so it's no longer just relevant to pixman-renderer.c --- src/compositor.c | 51 +++ src/compositor.h | 4 src/pixman-renderer.c | 51 --- 3 files changed, 55 insertions(+), 51 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index 5d8bd5e..e45dd62 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -735,6 +735,57 @@ weston_transformed_rect(int width, int height, } WL_EXPORT void +weston_matrix_transform_region(pixman_region32_t *dest, + struct weston_matrix *matrix, + pixman_region32_t *src) +{ + pixman_box32_t *src_rects, *dest_rects; + int nrects, i; + + src_rects = pixman_region32_rectangles(src, nrects); + dest_rects = malloc(nrects * sizeof(*dest_rects)); + if (!dest_rects) + return; + + for (i = 0; i nrects; i++) { + struct weston_vector vec1 = {{ + src_rects[i].x1, src_rects[i].y1, 0, 1 + }}; + weston_matrix_transform(matrix, vec1); + vec1.f[0] /= vec1.f[3]; + vec1.f[1] /= vec1.f[3]; + + struct weston_vector vec2 = {{ + src_rects[i].x2, src_rects[i].y2, 0, 1 + }}; + weston_matrix_transform(matrix, vec2); + vec2.f[0] /= vec2.f[3]; + vec2.f[1] /= vec2.f[3]; + + if (vec1.f[0] vec2.f[0]) { + dest_rects[i].x1 = floor(vec1.f[0]); + dest_rects[i].x2 = ceil(vec2.f[0]); + } else { + dest_rects[i].x1 = floor(vec2.f[0]); + dest_rects[i].x2 = ceil(vec1.f[0]); + } + + + if (vec1.f[1] vec2.f[1]) { + dest_rects[i].y1 = floor(vec1.f[1]); + dest_rects[i].y2 = ceil(vec2.f[1]); + } else { + dest_rects[i].y1 = floor(vec2.f[1]); + dest_rects[i].y2 = ceil(vec1.f[1]); + } + } + + pixman_region32_clear(dest); + pixman_region32_init_rects(dest, dest_rects, nrects); + free(dest_rects); +} + +WL_EXPORT void weston_transformed_region(int width, int height, enum wl_output_transform transform, int32_t scale, diff --git a/src/compositor.h b/src/compositor.h index 95900ed..b15eb01 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -1464,6 +1464,10 @@ weston_transformed_rect(int width, int height, int32_t scale, pixman_box32_t rect); void +weston_matrix_transform_region(pixman_region32_t *dest, + struct weston_matrix *matrix, + pixman_region32_t *src); +void weston_transformed_region(int width, int height, enum wl_output_transform transform, int32_t scale, diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c index d3650d1..9494142 100644 --- a/src/pixman-renderer.c +++ b/src/pixman-renderer.c @@ -128,57 +128,6 @@ pixman_renderer_read_pixels(struct weston_output *output, } static void -weston_matrix_transform_region(pixman_region32_t *dest, - struct weston_matrix *matrix, - pixman_region32_t *src) -{ - pixman_box32_t *src_rects, *dest_rects; - int nrects, i; - - src_rects = pixman_region32_rectangles(src, nrects); - dest_rects = malloc(nrects * sizeof(*dest_rects)); - if (!dest_rects) - return; - - for (i = 0; i nrects; i++) { - struct weston_vector vec1 = {{ - src_rects[i].x1, src_rects[i].y1, 0, 1 - }}; - weston_matrix_transform(matrix, vec1); - vec1.f[0] /= vec1.f[3]; - vec1.f[1] /= vec1.f[3]; - - struct weston_vector vec2 = {{ - src_rects[i].x2, src_rects[i].y2, 0, 1 - }}; - weston_matrix_transform(matrix, vec2); - vec2.f[0] /= vec2.f[3]; - vec2.f[1] /= vec2.f[3]; - - if (vec1.f[0] vec2.f[0]) { - dest_rects[i].x1 = floor(vec1.f[0]); - dest_rects[i].x2 = ceil(vec2.f[0]); - } else { - dest_rects[i].x1 = floor(vec2.f[0]); - dest_rects[i].x2 = ceil(vec1.f[0]); - } - - - if (vec1.f[1] vec2.f[1]) { - dest_rects[i].y1 = floor(vec1.f[1]); - dest_rects[i].y2 = ceil(vec2.f[1]); - } else { - dest_rects[i].y1 = floor(vec2.f[1]); -
[PATCH weston v2 19/20] renderers: use weston_view_to_output_matrix() in renderers
We now use this function in the gl renderer to determine if linear filtering is required, and in the pixman renderer to set up the image transformation. --- src/gl-renderer.c | 9 ++--- src/pixman-renderer.c | 14 +- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/src/gl-renderer.c b/src/gl-renderer.c index e1ad5ca..5b2f267 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -562,13 +562,8 @@ draw_view(struct weston_view *ev, struct weston_output *output, use_shader(gr, gs-shader); shader_uniforms(gs-shader, ev, output); - transform = ev-surface-buffer_to_surface_matrix; - if (ev-transform.enabled) - weston_matrix_multiply(transform, ev-transform.matrix); - else - weston_matrix_translate(transform, - ev-geometry.x, ev-geometry.y, 0); - weston_matrix_multiply(transform, output-matrix); + + weston_view_to_output_matrix(ev, output, false, transform); if (weston_matrix_needs_filtering(transform)) filter = GL_LINEAR; diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c index f6fe3c7..b682639 100644 --- a/src/pixman-renderer.c +++ b/src/pixman-renderer.c @@ -198,19 +198,7 @@ repaint_region(struct weston_view *ev, struct weston_output *output, /* And clip to it */ pixman_image_set_clip_region32 (po-shadow_image, final_region); - /* Set up the source transformation based on the surface - position, the output position/transform/scale and the client - specified buffer transform/scale */ - weston_matrix_invert(matrix, output-matrix); - - if (ev-transform.enabled) { - weston_matrix_multiply(matrix, ev-transform.inverse); - } else { - weston_matrix_translate(matrix, - -ev-geometry.x, -ev-geometry.y, 0); - } - - weston_matrix_multiply(matrix, ev-surface-surface_to_buffer_matrix); + weston_view_to_output_matrix(ev, output, true, matrix); weston_matrix_to_pixman_transform(transform, matrix); pixman_image_set_transform(ps-image, transform); -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston v2 06/20] pixman-renderer: Use output-matrix for region transformations and enable output zoom
From: Jason Ekstrand ja...@jlekstrand.net --- src/pixman-renderer.c | 70 +++ 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c index 18b6476..d3650d1 100644 --- a/src/pixman-renderer.c +++ b/src/pixman-renderer.c @@ -128,12 +128,68 @@ pixman_renderer_read_pixels(struct weston_output *output, } static void +weston_matrix_transform_region(pixman_region32_t *dest, + struct weston_matrix *matrix, + pixman_region32_t *src) +{ + pixman_box32_t *src_rects, *dest_rects; + int nrects, i; + + src_rects = pixman_region32_rectangles(src, nrects); + dest_rects = malloc(nrects * sizeof(*dest_rects)); + if (!dest_rects) + return; + + for (i = 0; i nrects; i++) { + struct weston_vector vec1 = {{ + src_rects[i].x1, src_rects[i].y1, 0, 1 + }}; + weston_matrix_transform(matrix, vec1); + vec1.f[0] /= vec1.f[3]; + vec1.f[1] /= vec1.f[3]; + + struct weston_vector vec2 = {{ + src_rects[i].x2, src_rects[i].y2, 0, 1 + }}; + weston_matrix_transform(matrix, vec2); + vec2.f[0] /= vec2.f[3]; + vec2.f[1] /= vec2.f[3]; + + if (vec1.f[0] vec2.f[0]) { + dest_rects[i].x1 = floor(vec1.f[0]); + dest_rects[i].x2 = ceil(vec2.f[0]); + } else { + dest_rects[i].x1 = floor(vec2.f[0]); + dest_rects[i].x2 = ceil(vec1.f[0]); + } + + + if (vec1.f[1] vec2.f[1]) { + dest_rects[i].y1 = floor(vec1.f[1]); + dest_rects[i].y2 = ceil(vec2.f[1]); + } else { + dest_rects[i].y1 = floor(vec2.f[1]); + dest_rects[i].y2 = ceil(vec1.f[1]); + } + } + + pixman_region32_clear(dest); + pixman_region32_init_rects(dest, dest_rects, nrects); + free(dest_rects); +} + +static void region_global_to_output(struct weston_output *output, pixman_region32_t *region) { - pixman_region32_translate(region, -output-x, -output-y); - weston_transformed_region(output-width, output-height, - output-transform, output-current_scale, - region, region); + if (output-zoom.active) { + weston_matrix_transform_region(region, output-matrix, region); + } else { + pixman_region32_translate(region, -output-x, -output-y); + weston_transformed_region(output-width, output-height, + output-transform, + output-current_scale, + region, region); + } } #define D2F(v) pixman_double_to_fixed((double)v) @@ -270,7 +326,6 @@ static void draw_view(struct weston_view *ev, struct weston_output *output, pixman_region32_t *damage) /* in global coordinates */ { - static int zoom_logged = 0; struct pixman_surface_state *ps = get_surface_state(ev-surface); /* repaint bounding region in global coordinates: */ pixman_region32_t repaint; @@ -289,11 +344,6 @@ draw_view(struct weston_view *ev, struct weston_output *output, if (!pixman_region32_not_empty(repaint)) goto out; - if (output-zoom.active !zoom_logged) { - weston_log(pixman renderer does not support zoom\n); - zoom_logged = 1; - } - /* TODO: Implement repaint_region_complex() using pixman_composite_trapezoids() */ if (ev-alpha != 1.0 || (ev-transform.enabled -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston v2 20/20] compositor-drm: use weston_view_to_output_matrix() to test plane viability
Instead of comparing buffer transforms to output transforms we now use weston_view_to_output_matrix() and weston_matrix_to_transform() to test if we can use a drm plane. We no longer test scaling, since the drm plane api supports scaling. Unfortunately the drmSetPlane() call is far from the viability test and has no reasonable fallback, so scaling will need to be revisited in the future when atomic mode setting is viable and sprites_are_broken stops being universally true... --- src/compositor-drm.c | 41 ++--- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index c0f451e..7d81983 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -824,37 +824,26 @@ drm_output_check_sprite_format(struct drm_sprite *s, return 0; } -static int -drm_view_transform_supported(struct weston_view *ev) -{ - return !ev-transform.enabled || - (ev-transform.matrix.type WESTON_MATRIX_TRANSFORM_ROTATE); -} - static struct weston_plane * drm_output_prepare_overlay_view(struct weston_output *output_base, struct weston_view *ev) { struct weston_compositor *ec = output_base-compositor; struct drm_compositor *c =(struct drm_compositor *) ec; - struct weston_buffer_viewport *viewport = ev-surface-buffer_viewport; + struct weston_matrix matrix; struct drm_sprite *s; int found = 0; struct gbm_bo *bo; pixman_region32_t dest_rect, src_rect; pixman_box32_t *box, tbox; + enum wl_output_transform transform; uint32_t format; + float scalex, scaley, transx, transy; int32_t sx1, sy1, sx2, sy2; if (c-gbm == NULL) return NULL; - if (viewport-buffer.transform != output_base-transform) - return NULL; - - if (viewport-buffer.scale != output_base-current_scale) - return NULL; - if (c-sprites_are_broken) return NULL; @@ -870,7 +859,14 @@ drm_output_prepare_overlay_view(struct weston_output *output_base, if (wl_shm_buffer_get(ev-surface-buffer_ref.buffer-resource)) return NULL; - if (!drm_view_transform_supported(ev)) + weston_view_to_output_matrix(ev, output_base, false, matrix); + + if (!weston_matrix_to_transform(matrix, transform, + scalex, scaley, + transx, transy)) + return NULL; + + if (transform != WL_OUTPUT_TRANSFORM_NORMAL) return NULL; wl_list_for_each(s, c-sprite_list, link) { @@ -936,14 +932,13 @@ drm_output_prepare_overlay_view(struct weston_output *output_base, weston_view_from_global(ev, box-x1, box-y1, sx1, sy1); weston_view_from_global(ev, box-x2, box-y2, sx2, sy2); - if (sx1 0) - sx1 = 0; - if (sy1 0) - sy1 = 0; - if (sx2 ev-surface-width) - sx2 = ev-surface-width; - if (sy2 ev-surface-height) - sy2 = ev-surface-height; + + /* Previously we clamped to the surface edge here, but that will +* result in incorrect scaling, so we just bail. +*/ + if (sx1 0 || sy1 0 || + sx2 ev-surface-width || sy2 ev-surface-height) + return NULL; tbox.x1 = sx1; tbox.y1 = sy1; -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston v2 10/20] compositor: use weston_matrix_transform_region for overlay setup
--- src/compositor-drm.c | 16 ++-- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 07b83a7..c997c26 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -919,17 +919,13 @@ drm_output_prepare_overlay_view(struct weston_output *output_base, pixman_region32_init(dest_rect); pixman_region32_intersect(dest_rect, ev-transform.boundingbox, output_base-region); - pixman_region32_translate(dest_rect, -output_base-x, -output_base-y); + weston_matrix_transform_region(dest_rect, output_base-matrix, dest_rect); box = pixman_region32_extents(dest_rect); - tbox = weston_transformed_rect(output_base-width, - output_base-height, - output_base-transform, - output_base-current_scale, - *box); - s-dest_x = tbox.x1; - s-dest_y = tbox.y1; - s-dest_w = tbox.x2 - tbox.x1; - s-dest_h = tbox.y2 - tbox.y1; + + s-dest_x = box-x1; + s-dest_y = box-y1; + s-dest_w = box-x2 - box-x1; + s-dest_h = box-y2 - box-y1; pixman_region32_fini(dest_rect); pixman_region32_init(src_rect); -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston v2 16/20] compositor: use weston_matrix_transform for weston_output_transform_coordinate
We can greatly simplify weston_output_transform_coordinate now by simply multiplying by the output matrix and converting the result to fixed point. --- src/compositor.c | 62 1 file changed, 4 insertions(+), 58 deletions(-) diff --git a/src/compositor.c b/src/compositor.c index aef3246..ba9f886 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -3539,66 +3539,12 @@ weston_output_transform_coordinate(struct weston_output *output, wl_fixed_t device_x, wl_fixed_t device_y, wl_fixed_t *x, wl_fixed_t *y) { - wl_fixed_t tx, ty; - wl_fixed_t width, height; - float zoom_scale, zx, zy; + struct weston_vector p = {{wl_fixed_to_double(device_x), wl_fixed_to_double(device_y), 0.0, 1.0}}; - width = wl_fixed_from_int(output-width * output-current_scale - 1); - height = wl_fixed_from_int(output-height * output-current_scale - 1); + weston_matrix_transform(output-matrix, p); - switch(output-transform) { - case WL_OUTPUT_TRANSFORM_NORMAL: - default: - tx = device_x; - ty = device_y; - break; - case WL_OUTPUT_TRANSFORM_90: - tx = device_y; - ty = height - device_x; - break; - case WL_OUTPUT_TRANSFORM_180: - tx = width - device_x; - ty = height - device_y; - break; - case WL_OUTPUT_TRANSFORM_270: - tx = width - device_y; - ty = device_x; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED: - tx = width - device_x; - ty = device_y; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED_90: - tx = width - device_y; - ty = height - device_x; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED_180: - tx = device_x; - ty = height - device_y; - break; - case WL_OUTPUT_TRANSFORM_FLIPPED_270: - tx = device_y; - ty = device_x; - break; - } - - tx /= output-current_scale; - ty /= output-current_scale; - - if (output-zoom.active) { - zoom_scale = output-zoom.spring_z.current; - zx = (wl_fixed_to_double(tx) * (1.0f - zoom_scale) + - output-width / 2.0f * - (zoom_scale + output-zoom.trans_x)); - zy = (wl_fixed_to_double(ty) * (1.0f - zoom_scale) + - output-height / 2.0f * - (zoom_scale + output-zoom.trans_y)); - tx = wl_fixed_from_double(zx); - ty = wl_fixed_from_double(zy); - } - - *x = tx + wl_fixed_from_int(output-x); - *y = ty + wl_fixed_from_int(output-y); + *x = wl_fixed_from_double(p.f[0]/p.f[3]); + *y = wl_fixed_from_double(p.f[1]/p.f[3]); } static void -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH v2] wayland-util: added wl_strtol/wl_strtoul utility functions
strtol/strtoul utility functions are used extensively in weston/wayland, and are not bug-free in their current form. To avoid definition in weston and wayland, its wrapped in functions with appropriate input and output checks. Test cases are also updated. Signed-off-by: Imran Zaman imran.za...@gmail.com --- src/scanner.c| 5 +-- src/wayland-client.c | 5 +-- src/wayland-util.c | 38 src/wayland-util.h | 4 ++ tests/fixed-test.c | 122 +++ 5 files changed, 167 insertions(+), 7 deletions(-) diff --git a/src/scanner.c b/src/scanner.c index 809130b..165b12b 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -315,7 +315,6 @@ start_element(void *data, const char *element_name, const char **atts) struct description *description; const char *name, *type, *interface_name, *value, *summary, *since; const char *allow_null; - char *end; int i, version; ctx-loc.line_number = XML_GetCurrentLineNumber(ctx-parser); @@ -404,9 +403,7 @@ start_element(void *data, const char *element_name, const char **atts) message-destructor = 0; if (since != NULL) { - errno = 0; - version = strtol(since, end, 0); - if (errno == EINVAL || end == since || *end != '\0') + if (!wl_strtol(since, NULL, 0, (long *)version)) fail(ctx-loc, invalid integer (%s)\n, since); } else { diff --git a/src/wayland-client.c b/src/wayland-client.c index b0f77b9..fd98705 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -824,13 +824,12 @@ wl_display_connect_to_fd(int fd) WL_EXPORT struct wl_display * wl_display_connect(const char *name) { - char *connection, *end; + char *connection; int flags, fd; connection = getenv(WAYLAND_SOCKET); if (connection) { - fd = strtol(connection, end, 0); - if (*end != '\0') + if (!wl_strtol(connection, NULL, 0, (long *)fd)) return NULL; flags = fcntl(fd, F_GETFD); diff --git a/src/wayland-util.c b/src/wayland-util.c index b099882..dfd2eb1 100644 --- a/src/wayland-util.c +++ b/src/wayland-util.c @@ -26,6 +26,8 @@ #include stdio.h #include string.h #include stdarg.h +#include errno.h +#include limits.h #include wayland-util.h #include wayland-private.h @@ -361,6 +363,42 @@ wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data) for_each_helper(map-server_entries, func, data); } +WL_EXPORT bool +wl_strtol(const char *str, char **endptr, int base, long *val) +{ + char *end = NULL; + long v; + + if (!str || !val) return false; + if (!endptr) endptr = end; + + errno = 0; + v = strtol(str, endptr, base); + if (errno != 0 || *endptr == str || **endptr != '\0') + return false; + + *val = v; + return true; +} + +WL_EXPORT bool +wl_strtoul(const char *str, char **endptr, int base, unsigned long *val) +{ + char *end = NULL; + unsigned long v; + + if (!str || !val) return false; + if (!endptr) endptr = end; + + errno = 0; + v = strtoul(str, endptr, base); + if (errno != 0 || *endptr == str || **endptr != '\0') + return false; + + *val = v; + return true; +} + static void wl_log_stderr_handler(const char *fmt, va_list arg) { diff --git a/src/wayland-util.h b/src/wayland-util.h index fd32826..c66cc41 100644 --- a/src/wayland-util.h +++ b/src/wayland-util.h @@ -36,6 +36,7 @@ extern C { #include stddef.h #include inttypes.h #include stdarg.h +#include stdbool.h /* GCC visibility */ #if defined(__GNUC__) __GNUC__ = 4 @@ -243,6 +244,9 @@ static inline wl_fixed_t wl_fixed_from_int(int i) return i * 256; } +bool wl_strtol(const char *str, char **endptr, int base, long *val); +bool wl_strtoul(const char *str, char **endptr, int base, unsigned long *val); + /** * \brief A union representing all of the basic data types that can be passed * along the wayland wire format. diff --git a/tests/fixed-test.c b/tests/fixed-test.c index 739a3b1..aa0340c 100644 --- a/tests/fixed-test.c +++ b/tests/fixed-test.c @@ -88,3 +88,125 @@ TEST(fixed_int_conversions) i = wl_fixed_to_int(f); assert(i == -0x50); } + +TEST(strtol_conversions) +{ + bool ret; + long val = -1; + char *end = NULL; + + ret = wl_strtol(NULL, NULL, 10, val); + assert(ret == false); + assert(val == -1); + + ret = wl_strtol(NULL, NULL, 10, NULL); + assert(ret == false); + + char *str = 12; + ret = wl_strtol(str, NULL, 10, val); + assert(ret == true); + assert(val == 12); + + ret = wl_strtol(str, end, 10, val); + assert(end
[PATCH 1/2] Support specifying custom directories for the client and server sockets through environment variables.
This is in order to support nested compositor architectures where system compositor using drm-backend is shared among multiple child compositors using wayland-backend. Signed-off-by: Imran Zaman imran.za...@gmail.com --- src/wayland-client.c | 5 - src/wayland-server.c | 5 - 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/wayland-client.c b/src/wayland-client.c index b0f77b9..07db370 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -700,7 +700,9 @@ connect_to_socket(const char *name) const char *runtime_dir; int name_size, fd; - runtime_dir = getenv(XDG_RUNTIME_DIR); + runtime_dir = getenv(WAYLAND_CLIENT_DIR); + if (runtime_dir == NULL) + runtime_dir = getenv(XDG_RUNTIME_DIR); if (!runtime_dir) { wl_log(error: XDG_RUNTIME_DIR not set in the environment.\n); /* to prevent programs reporting @@ -723,6 +725,7 @@ connect_to_socket(const char *name) name_size = snprintf(addr.sun_path, sizeof addr.sun_path, %s/%s, runtime_dir, name) + 1; + unsetenv(WAYLAND_CLIENT_DIR); assert(name_size 0); if (name_size (int)sizeof addr.sun_path) { diff --git a/src/wayland-server.c b/src/wayland-server.c index 674aeca..09e8903 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -1080,7 +1080,9 @@ wl_socket_init_for_display_name(struct wl_socket *s, const char *name) int name_size; const char *runtime_dir; - runtime_dir = getenv(XDG_RUNTIME_DIR); + runtime_dir = getenv(WAYLAND_SERVER_DIR); + if (runtime_dir == NULL) + runtime_dir = getenv(XDG_RUNTIME_DIR); if (!runtime_dir) { wl_log(error: XDG_RUNTIME_DIR not set in the environment\n); @@ -1093,6 +1095,7 @@ wl_socket_init_for_display_name(struct wl_socket *s, const char *name) s-addr.sun_family = AF_LOCAL; name_size = snprintf(s-addr.sun_path, sizeof s-addr.sun_path, %s/%s, runtime_dir, name) + 1; + unsetenv(WAYLAND_SERVER_DIR); s-display_name = (s-addr.sun_path + name_size - 1) - strlen(name); -- 1.9.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH 2/2] Support for adjusting socket access rights to allow group of users to connect to the socket.
This is used for nested compositor architectures. Signed-off-by: Imran Zaman imran.za...@gmail.com --- src/wayland-server.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/src/wayland-server.c b/src/wayland-server.c index 09e8903..721fabe 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -39,6 +39,8 @@ #include fcntl.h #include sys/file.h #include sys/stat.h +#include sys/types.h +#include grp.h #include ffi.h #include wayland-private.h @@ -1117,6 +1119,10 @@ static int _wl_display_add_socket(struct wl_display *display, struct wl_socket *s) { socklen_t size; + const char *socket_mode_str; + const char *socket_group_str; + const struct group *socket_group; + unsigned socket_mode; s-fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0); if (s-fd 0) { @@ -1134,6 +1140,27 @@ _wl_display_add_socket(struct wl_display *display, struct wl_socket *s) return -1; } + socket_group_str = getenv(WAYLAND_SERVER_GROUP); + if (socket_group_str != NULL) { + socket_group = getgrnam(socket_group_str); + if (socket_group != NULL) { + if (chown(s-addr.sun_path, + -1, socket_group-gr_gid) != 0) + wl_log(chown(\%s\) failed: %s, + s-addr.sun_path, + strerror(errno)); + } + } + socket_mode_str = getenv(WAYLAND_SERVER_MODE); + if (socket_mode_str != NULL) { + if (sscanf(socket_mode_str, %o, socket_mode) 0) + if (chmod(s-addr.sun_path, socket_mode) != 0) { + wl_log(chmod(\%s\) failed: %s, + s-addr.sun_path, + strerror(errno)); + } + } + s-source = wl_event_loop_add_fd(display-loop, s-fd, WL_EVENT_READABLE, socket_data, display); -- 1.9.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston v5 2/3] Implement data_device interface destructor
I apologize in advance for only commenting on the whitespace :) On 13/10/14 12:05 AM, kabeer khan wrote: window : compare version and call appropriate destructor Signed-off-by: kabeer khan kabeer.k...@samsung.com --- clients/window.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/clients/window.c b/clients/window.c index 139c7f9..12851ba 100644 --- a/clients/window.c +++ b/clients/window.c @@ -133,6 +133,7 @@ struct display { int has_rgb565; int seat_version; + int data_device_manager_version; }; struct window_output { @@ -5148,9 +5149,12 @@ input_destroy(struct input *input) if (input-selection_offer) data_offer_destroy(input-selection_offer); - if (input-data_device) - wl_data_device_destroy(input-data_device); - + if (input-data_device) { + if(input-display-data_device_manager_version = 2) + wl_data_device_release(input-data_device); + else + wl_data_device_destroy(input-data_device); These last two lines ^ should use tabs exclusively... instead of spaces followed by tabs. + } if (input-display-seat_version = 3) { if (input-pointer) wl_pointer_release(input-pointer); @@ -5234,9 +5238,10 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, d-shm = wl_registry_bind(registry, id, wl_shm_interface, 1); wl_shm_add_listener(d-shm, shm_listener, d); } else if (strcmp(interface, wl_data_device_manager) == 0) { + d-data_device_manager_version = MIN(version, 2); Same here ^ d-data_device_manager = - wl_registry_bind(registry, id, - wl_data_device_manager_interface, 1); + wl_registry_bind(registry, id, + wl_data_device_manager_interface, d-data_device_manager_version); } else if (strcmp(interface, xdg_shell) == 0) { d-xdg_shell = wl_registry_bind(registry, id, xdg_shell_interface, 1); ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston v5 3/3 1/2] Implement data_device interface destructor
On 13/10/14 12:06 AM, kabeer khan wrote: data_device : change version while initializing data_device_manager interface and data_device interface Signed-off-by: kabeer khan kabeer.k...@samsung.com --- src/data-device.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/data-device.c b/src/data-device.c index 75fc60c..68be39f 100644 --- a/src/data-device.c +++ b/src/data-device.c @@ -761,10 +761,16 @@ data_device_set_selection(struct wl_client *client, wl_resource_get_user_data(source_resource), serial); } +static void +data_device_release(struct wl_client *client, struct wl_resource *resource) +{ + wl_resource_destroy(resource); Should be a tab ^ +} static const struct wl_data_device_interface data_device_interface = { data_device_start_drag, data_device_set_selection, + data_device_release }; static void @@ -844,7 +850,7 @@ get_data_device(struct wl_client *client, struct wl_resource *resource; resource = wl_resource_create(client, - wl_data_device_interface, 1, id); + wl_data_device_interface, wl_resource_get_version(manager_resource), id); if (resource == NULL) { wl_resource_post_no_memory(manager_resource); return; @@ -867,9 +873,8 @@ bind_manager(struct wl_client *client, { struct wl_resource *resource; - resource = - wl_resource_create(client, -wl_data_device_manager_interface, 1, id); + resource = wl_resource_create(client, + wl_data_device_manager_interface, MIN(version,2), id); if (resource == NULL) { wl_client_post_no_memory(client); return; @@ -909,7 +914,7 @@ WL_EXPORT int wl_data_device_manager_init(struct wl_display *display) { if (wl_global_create(display, - wl_data_device_manager_interface, 1, + wl_data_device_manager_interface, 2, NULL, bind_manager) == NULL) return -1; ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
[PATCH weston] gl-renderer: compress pixman bands to simplify geometry
Pixman uses y-x banded rectangles to represent regions. We use these y-x banded rectangles to generate triangle fans, resulting in more geometry than strictly necessary to draw the screen. This patch combines the bands to reduce geometry for complex scenes. --- src/gl-renderer.c | 67 --- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/src/gl-renderer.c b/src/gl-renderer.c index 076c242..40447c7 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -25,6 +25,7 @@ #include GLES2/gl2.h #include GLES2/gl2ext.h +#include stdbool.h #include stdlib.h #include string.h #include ctype.h @@ -296,6 +297,55 @@ calculate_edges(struct weston_view *ev, pixman_box32_t *rect, return n; } +static bool +merge_down(pixman_box32_t *a, pixman_box32_t *b, pixman_box32_t *merge) +{ + if (a-x1 == b-x1 a-x2 == b-x2 a-y1 == b-y2) { + merge-x1 = a-x1; + merge-x2 = a-x2; + merge-y1 = b-y1; + merge-y2 = a-y2; + return true; + } + return false; +} + +static int +compress_bands(pixman_box32_t *inrects, int nrects, + pixman_box32_t **outrects) +{ + bool merged; + pixman_box32_t *out, merge_rect; + int i, j, nout; + + if (!nrects) { + *outrects = NULL; + return 0; + } + + /* nrects is an upper bound - we're not too worried about +* allocating a little extra +*/ + out = malloc(sizeof(pixman_box32_t) * nrects); + out[0] = inrects[0]; + nout = 1; + for (i = 1; i nrects; i++) { + for (j = 0; j nout; j++) { + merged = merge_down(inrects[i], out[j], merge_rect); + if (merged) { + out[j] = merge_rect; + break; + } + } + if (!merged) { + out[nout] = inrects[i]; + nout++; + } + } + *outrects = out; + return nout; +} + static int texture_region(struct weston_view *ev, pixman_region32_t *region, pixman_region32_t *surf_region) @@ -306,11 +356,20 @@ texture_region(struct weston_view *ev, pixman_region32_t *region, GLfloat *v, inv_width, inv_height; unsigned int *vtxcnt, nvtx = 0; pixman_box32_t *rects, *surf_rects; - int i, j, k, nrects, nsurf; - - rects = pixman_region32_rectangles(region, nrects); + pixman_box32_t *raw_rects; + int i, j, k, nrects, nsurf, raw_nrects; + bool used_band_compression; + raw_rects = pixman_region32_rectangles(region, raw_nrects); surf_rects = pixman_region32_rectangles(surf_region, nsurf); + if (raw_nrects 4) { + used_band_compression = false; + nrects = raw_nrects; + rects = raw_rects; + } else { + nrects = compress_bands(raw_rects, raw_nrects, rects); + used_band_compression = true; + } /* worst case we can have 8 vertices per rect (ie. clipped into * an octagon): */ @@ -369,6 +428,8 @@ texture_region(struct weston_view *ev, pixman_region32_t *region, } } + if (used_band_compression) + free(rects); return nvtx; } -- 2.1.1 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston] smoke: Don't commit an xdg_surface with a NULL buffer
On Tue, Oct 14, 2014 at 2:45 AM, Giulio Camuffo giuliocamu...@gmail.com wrote: 2014-10-13 4:57 GMT+03:00 Jasper St. Pierre jstpie...@mecheye.net: Committing to an xdg_surface with a NULL buffer is currently illegal in the mutter implementation, so this simply causes the client to error and exit. The patch looks good to me. However, this leaves me wondering how does a client hide a surface. Does it have to destroy the xdg_surface? I'd expect a compositor to show a window at the same position it was when hidden, but destroying the xdg_surface loses all the state When combined with map / unmap animations, I think we have to decide that show means the window is presented in a compositor-chosen place. As such, I chose to make attaching a NULL buffer against the rules. Are there any use cases for hiding a window while keeping it in the same place? We couldn't think of any on IRC. -- Giulio It seems the reason the client did this was so it could add its own frame callback, but toytoolkit actually provides accurate everything we need. Just use its functions instead to get the time and schedule a redraw. --- clients/smoke.c | 24 ++-- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/clients/smoke.c b/clients/smoke.c index 65b6e03..7f0d5e5 100644 --- a/clients/smoke.c +++ b/clients/smoke.c @@ -39,7 +39,6 @@ struct smoke { struct widget *widget; int width, height; int current; - uint32_t time; struct { float *d, *u, *v; } b[2]; }; @@ -171,27 +170,10 @@ static void render(struct smoke *smoke, cairo_surface_t *surface) } static void -frame_callback(void *data, struct wl_callback *callback, uint32_t time) -{ - struct smoke *smoke = data; - - window_schedule_redraw(smoke-window); - smoke-time = time; - - if (callback) - wl_callback_destroy(callback); -} - -static const struct wl_callback_listener listener = { - frame_callback, -}; - -static void redraw_handler(struct widget *widget, void *data) { struct smoke *smoke = data; - uint32_t time = smoke-time; - struct wl_callback *callback; + uint32_t time = widget_get_last_time(smoke-widget); cairo_surface_t *surface; diffuse(smoke, time / 30, smoke-b[0].u, smoke-b[1].u); @@ -222,9 +204,7 @@ redraw_handler(struct widget *widget, void *data) cairo_surface_destroy(surface); - callback = wl_surface_frame(window_get_wl_surface(smoke-window)); - wl_callback_add_listener(callback, listener, smoke); - wl_surface_commit(window_get_wl_surface(smoke-window)); + widget_schedule_redraw(smoke-widget); } static void -- 2.1.0 ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel -- Jasper ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston] smoke: Don't commit an xdg_surface with a NULL buffer
On 10/16/2014 08:03 PM, Jasper St. Pierre wrote: Are there any use cases for hiding a window while keeping it in the same place? We couldn't think of any on IRC. There may be a desire to do that with child windows. If a client has a button that turns a child window on/off, and the user moves the child, then toggles the button on/off it probably should reappear where it was. But I think it is ok if the user moves the parent window while the children are hidden, the children reappear moved the same amount. I think currently the client can control where the child first appears, and could make it reappear in the same location (relative to the parent window) but not where the user moved it. But the fix would probably be to add an event so the client knows where the window was moved relative to the parent. ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel
Re: [PATCH weston] smoke: Don't commit an xdg_surface with a NULL buffer
Wayland does not have child windows. On Oct 16, 2014 8:22 PM, Bill Spitzak spit...@gmail.com wrote: On 10/16/2014 08:03 PM, Jasper St. Pierre wrote: Are there any use cases for hiding a window while keeping it in the same place? We couldn't think of any on IRC. There may be a desire to do that with child windows. If a client has a button that turns a child window on/off, and the user moves the child, then toggles the button on/off it probably should reappear where it was. But I think it is ok if the user moves the parent window while the children are hidden, the children reappear moved the same amount. I think currently the client can control where the child first appears, and could make it reappear in the same location (relative to the parent window) but not where the user moved it. But the fix would probably be to add an event so the client knows where the window was moved relative to the parent. ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel ___ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel