• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2010-2011 Intel Corporation
3  * Copyright © 2008-2011 Kristian Høgsberg
4  * Copyright © 2012-2018 Collabora, Ltd.
5  * Copyright © 2017, 2018 General Electric Company
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice (including the
16  * next paragraph) shall be included in all copies or substantial
17  * portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
23  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26  * SOFTWARE.
27  */
28 
29 #include "config.h"
30 
31 #include <fcntl.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <stdint.h>
36 #include <limits.h>
37 #include <stdarg.h>
38 #include <assert.h>
39 #include <sys/ioctl.h>
40 #include <sys/mman.h>
41 #include <sys/wait.h>
42 #include <sys/socket.h>
43 #include <sys/utsname.h>
44 #include <sys/stat.h>
45 #include <unistd.h>
46 #include <math.h>
47 #include <linux/input.h>
48 #include <dlfcn.h>
49 #include <signal.h>
50 #include <setjmp.h>
51 #include <sys/time.h>
52 #include <time.h>
53 #include <errno.h>
54 #include <inttypes.h>
55 
56 // OHOS remove timeline
57 //#include "timeline.h"
58 
59 #include <libweston/libweston.h>
60 #include <libweston/weston-log.h>
61 #include "linux-dmabuf.h"
62 #include "viewporter-server-protocol.h"
63 #include "presentation-time-server-protocol.h"
64 #include "xdg-output-unstable-v1-server-protocol.h"
65 #include "linux-explicit-synchronization-unstable-v1-server-protocol.h"
66 #include "linux-explicit-synchronization.h"
67 #include "shared/fd-util.h"
68 #include "shared/helpers.h"
69 #include "shared/os-compatibility.h"
70 #include "shared/string-helpers.h"
71 #include "shared/timespec-util.h"
72 #include "git-version.h"
73 #include <libweston/version.h>
74 #include <libweston/plugin-registry.h>
75 #include "pixel-formats.h"
76 #include "backend.h"
77 #include "libweston-internal.h"
78 
79 #include "libweston/trace.h"
80 DEFINE_LOG_LABEL("Compositor");
81 
82 // OHOS remove logger
83 //#include "weston-log-internal.h"
84 
85 /**
86  * \defgroup head Head
87  * \defgroup output Output
88  * \defgroup compositor Compositor
89  */
90 
91 #define DEFAULT_REPAINT_WINDOW 7 /* milliseconds */
92 
93 static void
94 weston_output_update_matrix(struct weston_output *output);
95 
96 static void
97 weston_output_transform_scale_init(struct weston_output *output,
98 				   uint32_t transform, uint32_t scale);
99 
100 static void
101 weston_compositor_build_view_list(struct weston_compositor *compositor);
102 
103 static char *
104 weston_output_create_heads_string(struct weston_output *output);
105 
106 /** Send wl_output events for mode and scale changes
107  *
108  * \param head Send on all resources bound to this head.
109  * \param mode_changed If true, send the current mode.
110  * \param scale_changed If true, send the current scale.
111  */
112 static void
weston_mode_switch_send_events(struct weston_head * head,bool mode_changed,bool scale_changed)113 weston_mode_switch_send_events(struct weston_head *head,
114 			       bool mode_changed, bool scale_changed)
115 {
116 	struct weston_output *output = head->output;
117 	struct wl_resource *resource;
118 	int version;
119 
120 	wl_resource_for_each(resource, &head->resource_list) {
121 		if (mode_changed) {
122 			wl_output_send_mode(resource,
123 					    output->current_mode->flags,
124 					    output->current_mode->width,
125 					    output->current_mode->height,
126 					    output->current_mode->refresh);
127 		}
128 
129 		version = wl_resource_get_version(resource);
130 		if (version >= WL_OUTPUT_SCALE_SINCE_VERSION && scale_changed)
131 			wl_output_send_scale(resource, output->current_scale);
132 
133 		if (version >= WL_OUTPUT_DONE_SINCE_VERSION)
134 			wl_output_send_done(resource);
135 	}
136 	wl_resource_for_each(resource, &head->xdg_output_resource_list) {
137 		zxdg_output_v1_send_logical_position(resource,
138 						     output->x,
139 						     output->y);
140 		zxdg_output_v1_send_logical_size(resource,
141 						 output->width,
142 						 output->height);
143 		zxdg_output_v1_send_done(resource);
144 	}
145 }
146 
147 static void
weston_mode_switch_finish(struct weston_output * output,int mode_changed,int scale_changed)148 weston_mode_switch_finish(struct weston_output *output,
149 			  int mode_changed, int scale_changed)
150 {
151 	struct weston_seat *seat;
152 	struct weston_head *head;
153 	pixman_region32_t old_output_region;
154 
155 	pixman_region32_init(&old_output_region);
156 	pixman_region32_copy(&old_output_region, &output->region);
157 
158 	/* Update output region and transformation matrix */
159 	weston_output_transform_scale_init(output, output->transform, output->current_scale);
160 
161 	pixman_region32_init_rect(&output->region, output->x, output->y,
162 				  output->width, output->height);
163 
164 	weston_output_update_matrix(output);
165 
166 	/* If a pointer falls outside the outputs new geometry, move it to its
167 	 * lower-right corner */
168 	wl_list_for_each(seat, &output->compositor->seat_list, link) {
169 		struct weston_pointer *pointer = weston_seat_get_pointer(seat);
170 		int32_t x, y;
171 
172 		if (!pointer)
173 			continue;
174 
175 		x = wl_fixed_to_int(pointer->x);
176 		y = wl_fixed_to_int(pointer->y);
177 
178 		if (!pixman_region32_contains_point(&old_output_region,
179 						    x, y, NULL) ||
180 		    pixman_region32_contains_point(&output->region,
181 						   x, y, NULL))
182 			continue;
183 
184 		if (x >= output->x + output->width)
185 			x = output->x + output->width - 1;
186 		if (y >= output->y + output->height)
187 			y = output->y + output->height - 1;
188 
189 		pointer->x = wl_fixed_from_int(x);
190 		pointer->y = wl_fixed_from_int(y);
191 	}
192 
193 	pixman_region32_fini(&old_output_region);
194 
195 	if (!mode_changed && !scale_changed)
196 		return;
197 
198 	/* notify clients of the changes */
199 	wl_list_for_each(head, &output->head_list, output_link)
200 		weston_mode_switch_send_events(head,
201 					       mode_changed, scale_changed);
202 }
203 
204 static void
205 weston_compositor_reflow_outputs(struct weston_compositor *compositor,
206 				struct weston_output *resized_output, int delta_width);
207 
208 /**
209  * \ingroup output
210  */
211 WL_EXPORT int
weston_output_mode_set_native(struct weston_output * output,struct weston_mode * mode,int32_t scale)212 weston_output_mode_set_native(struct weston_output *output,
213 			      struct weston_mode *mode,
214 			      int32_t scale)
215 {
216 	int ret;
217 	int mode_changed = 0, scale_changed = 0;
218 	int32_t old_width;
219 
220 	if (!output->switch_mode)
221 		return -1;
222 
223 	if (!output->original_mode) {
224 		mode_changed = 1;
225 		ret = output->switch_mode(output, mode);
226 		if (ret < 0)
227 			return ret;
228 		if (output->current_scale != scale) {
229 			scale_changed = 1;
230 			output->current_scale = scale;
231 		}
232 	}
233 
234 	old_width = output->width;
235 	output->native_mode = mode;
236 	output->native_scale = scale;
237 
238 	weston_mode_switch_finish(output, mode_changed, scale_changed);
239 
240 	if (mode_changed || scale_changed) {
241 		weston_compositor_reflow_outputs(output->compositor, output, output->width - old_width);
242 
243 		wl_signal_emit(&output->compositor->output_resized_signal, output);
244 	}
245 	return 0;
246 }
247 
248 /**
249  * \ingroup output
250  */
251 WL_EXPORT int
weston_output_mode_switch_to_native(struct weston_output * output)252 weston_output_mode_switch_to_native(struct weston_output *output)
253 {
254 	int ret;
255 	int mode_changed = 0, scale_changed = 0;
256 
257 	if (!output->switch_mode)
258 		return -1;
259 
260 	if (!output->original_mode) {
261 		weston_log("already in the native mode\n");
262 		return -1;
263 	}
264 	/* the non fullscreen clients haven't seen a mode set since we
265 	 * switched into a temporary, so we need to notify them if the
266 	 * mode at that time is different from the native mode now.
267 	 */
268 	mode_changed = (output->original_mode != output->native_mode);
269 	scale_changed = (output->original_scale != output->native_scale);
270 
271 	ret = output->switch_mode(output, output->native_mode);
272 	if (ret < 0)
273 		return ret;
274 
275 	output->current_scale = output->native_scale;
276 
277 	output->original_mode = NULL;
278 	output->original_scale = 0;
279 
280 	weston_mode_switch_finish(output, mode_changed, scale_changed);
281 
282 	return 0;
283 }
284 
285 /**
286  * \ingroup output
287  */
288 WL_EXPORT int
weston_output_mode_switch_to_temporary(struct weston_output * output,struct weston_mode * mode,int32_t scale)289 weston_output_mode_switch_to_temporary(struct weston_output *output,
290 				       struct weston_mode *mode,
291 				       int32_t scale)
292 {
293 	int ret;
294 
295 	if (!output->switch_mode)
296 		return -1;
297 
298 	/* original_mode is the last mode non full screen clients have seen,
299 	 * so we shouldn't change it if we already have one set.
300 	 */
301 	if (!output->original_mode) {
302 		output->original_mode = output->native_mode;
303 		output->original_scale = output->native_scale;
304 	}
305 	ret = output->switch_mode(output, mode);
306 	if (ret < 0)
307 		return ret;
308 
309 	output->current_scale = scale;
310 
311 	weston_mode_switch_finish(output, 0, 0);
312 
313 	return 0;
314 }
315 
316 static void
region_init_infinite(pixman_region32_t * region)317 region_init_infinite(pixman_region32_t *region)
318 {
319 	pixman_region32_init_rect(region, INT32_MIN, INT32_MIN,
320 				  UINT32_MAX, UINT32_MAX);
321 }
322 
323 static struct weston_subsurface *
324 weston_surface_to_subsurface(struct weston_surface *surface);
325 
326 WL_EXPORT struct weston_view *
weston_view_create(struct weston_surface * surface)327 weston_view_create(struct weston_surface *surface)
328 {
329 	struct weston_view *view;
330 
331 	view = zalloc(sizeof *view);
332 	if (view == NULL)
333 		return NULL;
334 
335 	view->surface = surface;
336 	view->plane = &surface->compositor->primary_plane;
337 
338 	/* Assign to surface */
339 	wl_list_insert(&surface->views, &view->surface_link);
340 
341 	wl_signal_init(&view->destroy_signal);
342 	wl_list_init(&view->link);
343 	wl_list_init(&view->layer_link.link);
344 
345 	pixman_region32_init(&view->clip);
346 
347 	view->alpha = 1.0;
348 	pixman_region32_init(&view->transform.opaque);
349 
350 	wl_list_init(&view->geometry.transformation_list);
351 	wl_list_insert(&view->geometry.transformation_list,
352 		       &view->transform.position.link);
353 	weston_matrix_init(&view->transform.position.matrix);
354 	wl_list_init(&view->geometry.child_list);
355 	pixman_region32_init(&view->geometry.scissor);
356 	pixman_region32_init(&view->transform.boundingbox);
357 	view->transform.dirty = 1;
358 
359 	return view;
360 }
361 
362 struct weston_frame_callback {
363 	struct wl_resource *resource;
364 	struct wl_list link;
365 };
366 
367 struct weston_presentation_feedback {
368 	struct wl_resource *resource;
369 
370 	/* XXX: could use just wl_resource_get_link() instead */
371 	struct wl_list link;
372 
373 	/* The per-surface feedback flags */
374 	uint32_t psf_flags;
375 };
376 
377 static void
weston_presentation_feedback_discard(struct weston_presentation_feedback * feedback)378 weston_presentation_feedback_discard(
379 		struct weston_presentation_feedback *feedback)
380 {
381 	wp_presentation_feedback_send_discarded(feedback->resource);
382 	wl_resource_destroy(feedback->resource);
383 }
384 
385 static void
weston_presentation_feedback_discard_list(struct wl_list * list)386 weston_presentation_feedback_discard_list(struct wl_list *list)
387 {
388 	struct weston_presentation_feedback *feedback, *tmp;
389 
390 	wl_list_for_each_safe(feedback, tmp, list, link)
391 		weston_presentation_feedback_discard(feedback);
392 }
393 
394 static void
weston_presentation_feedback_present(struct weston_presentation_feedback * feedback,struct weston_output * output,uint32_t refresh_nsec,const struct timespec * ts,uint64_t seq,uint32_t flags)395 weston_presentation_feedback_present(
396 		struct weston_presentation_feedback *feedback,
397 		struct weston_output *output,
398 		uint32_t refresh_nsec,
399 		const struct timespec *ts,
400 		uint64_t seq,
401 		uint32_t flags)
402 {
403 	struct wl_client *client = wl_resource_get_client(feedback->resource);
404 	struct weston_head *head;
405 	struct wl_resource *o;
406 	uint32_t tv_sec_hi;
407 	uint32_t tv_sec_lo;
408 	uint32_t tv_nsec;
409 	bool done = false;
410 
411 	wl_list_for_each(head, &output->head_list, output_link) {
412 		wl_resource_for_each(o, &head->resource_list) {
413 			if (wl_resource_get_client(o) != client)
414 				continue;
415 
416 			wp_presentation_feedback_send_sync_output(feedback->resource, o);
417 			done = true;
418 		}
419 
420 		/* For clone mode, send it for just one wl_output global,
421 		 * they are all equivalent anyway.
422 		 */
423 		if (done)
424 			break;
425 	}
426 
427 	timespec_to_proto(ts, &tv_sec_hi, &tv_sec_lo, &tv_nsec);
428 	wp_presentation_feedback_send_presented(feedback->resource,
429 						tv_sec_hi, tv_sec_lo, tv_nsec,
430 						refresh_nsec,
431 						seq >> 32, seq & 0xffffffff,
432 						flags | feedback->psf_flags);
433 	wl_resource_destroy(feedback->resource);
434 }
435 
436 static void
weston_presentation_feedback_present_list(struct wl_list * list,struct weston_output * output,uint32_t refresh_nsec,const struct timespec * ts,uint64_t seq,uint32_t flags)437 weston_presentation_feedback_present_list(struct wl_list *list,
438 					  struct weston_output *output,
439 					  uint32_t refresh_nsec,
440 					  const struct timespec *ts,
441 					  uint64_t seq,
442 					  uint32_t flags)
443 {
444 	struct weston_presentation_feedback *feedback, *tmp;
445 
446 	assert(!(flags & WP_PRESENTATION_FEEDBACK_INVALID) ||
447 	       wl_list_empty(list));
448 
449 	wl_list_for_each_safe(feedback, tmp, list, link)
450 		weston_presentation_feedback_present(feedback, output,
451 						     refresh_nsec, ts, seq,
452 						     flags);
453 }
454 
455 static void
surface_state_handle_buffer_destroy(struct wl_listener * listener,void * data)456 surface_state_handle_buffer_destroy(struct wl_listener *listener, void *data)
457 {
458 	struct weston_surface_state *state =
459 		container_of(listener, struct weston_surface_state,
460 			     buffer_destroy_listener);
461 
462 	state->buffer = NULL;
463 }
464 
465 static void
weston_surface_state_init(struct weston_surface_state * state)466 weston_surface_state_init(struct weston_surface_state *state)
467 {
468 	state->newly_attached = 0;
469 	state->buffer = NULL;
470 	state->buffer_destroy_listener.notify =
471 		surface_state_handle_buffer_destroy;
472 	state->sx = 0;
473 	state->sy = 0;
474 
475 	pixman_region32_init(&state->damage_surface);
476 	pixman_region32_init(&state->damage_buffer);
477 	pixman_region32_init(&state->opaque);
478 	region_init_infinite(&state->input);
479 
480 	wl_list_init(&state->frame_callback_list);
481 	wl_list_init(&state->feedback_list);
482 
483 	state->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
484 	state->buffer_viewport.buffer.scale = 1;
485 	state->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
486 	state->buffer_viewport.surface.width = -1;
487 	state->buffer_viewport.changed = 0;
488 
489 	state->acquire_fence_fd = -1;
490 
491 	state->desired_protection = WESTON_HDCP_DISABLE;
492 	state->protection_mode = WESTON_SURFACE_PROTECTION_MODE_RELAXED;
493 }
494 
495 static void
weston_surface_state_fini(struct weston_surface_state * state)496 weston_surface_state_fini(struct weston_surface_state *state)
497 {
498 	struct weston_frame_callback *cb, *next;
499 
500 	wl_list_for_each_safe(cb, next,
501 			      &state->frame_callback_list, link)
502 		wl_resource_destroy(cb->resource);
503 
504 	weston_presentation_feedback_discard_list(&state->feedback_list);
505 
506 	pixman_region32_fini(&state->input);
507 	pixman_region32_fini(&state->opaque);
508 	pixman_region32_fini(&state->damage_surface);
509 	pixman_region32_fini(&state->damage_buffer);
510 
511 	if (state->buffer)
512 		wl_list_remove(&state->buffer_destroy_listener.link);
513 	state->buffer = NULL;
514 
515 	fd_clear(&state->acquire_fence_fd);
516 	weston_buffer_release_reference(&state->buffer_release_ref, NULL);
517 }
518 
519 static void
weston_surface_state_set_buffer(struct weston_surface_state * state,struct weston_buffer * buffer)520 weston_surface_state_set_buffer(struct weston_surface_state *state,
521 				struct weston_buffer *buffer)
522 {
523 	if (state->buffer == buffer)
524 		return;
525 
526 	if (state->buffer)
527 		wl_list_remove(&state->buffer_destroy_listener.link);
528 	state->buffer = buffer;
529 	if (state->buffer)
530 		wl_signal_add(&state->buffer->destroy_signal,
531 			      &state->buffer_destroy_listener);
532 }
533 
534 WL_EXPORT struct weston_surface *
weston_surface_create(struct weston_compositor * compositor)535 weston_surface_create(struct weston_compositor *compositor)
536 {
537 	struct weston_surface *surface;
538 
539 	surface = zalloc(sizeof *surface);
540 	if (surface == NULL)
541 		return NULL;
542 
543 	wl_signal_init(&surface->destroy_signal);
544 	wl_signal_init(&surface->commit_signal);
545 
546 	surface->compositor = compositor;
547 	surface->ref_count = 1;
548 
549 	surface->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
550 	surface->buffer_viewport.buffer.scale = 1;
551 	surface->buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
552 	surface->buffer_viewport.surface.width = -1;
553 
554 	weston_surface_state_init(&surface->pending);
555 
556 	pixman_region32_init(&surface->damage);
557 	pixman_region32_init(&surface->opaque);
558 	region_init_infinite(&surface->input);
559 
560 	wl_list_init(&surface->views);
561 
562 	wl_list_init(&surface->frame_callback_list);
563 	wl_list_init(&surface->feedback_list);
564 
565 	wl_list_init(&surface->subsurface_list);
566 	wl_list_init(&surface->subsurface_list_pending);
567 
568 	weston_matrix_init(&surface->buffer_to_surface_matrix);
569 	weston_matrix_init(&surface->surface_to_buffer_matrix);
570 
571 	wl_list_init(&surface->pointer_constraints);
572 
573 	surface->acquire_fence_fd = -1;
574 
575 	surface->desired_protection = WESTON_HDCP_DISABLE;
576 	surface->current_protection = WESTON_HDCP_DISABLE;
577 	surface->protection_mode = WESTON_SURFACE_PROTECTION_MODE_RELAXED;
578 
579 	return surface;
580 }
581 
582 WL_EXPORT void
weston_surface_set_color(struct weston_surface * surface,float red,float green,float blue,float alpha)583 weston_surface_set_color(struct weston_surface *surface,
584 		 float red, float green, float blue, float alpha)
585 {
586 	surface->compositor->renderer->surface_set_color(surface, red, green, blue, alpha);
587 	surface->is_opaque = !(alpha < 1.0);
588 }
589 
590 WL_EXPORT void
weston_view_to_global_float(struct weston_view * view,float sx,float sy,float * x,float * y)591 weston_view_to_global_float(struct weston_view *view,
592 			    float sx, float sy, float *x, float *y)
593 {
594 	if (view->transform.enabled) {
595 		struct weston_vector v = { { sx, sy, 0.0f, 1.0f } };
596 
597 		weston_matrix_transform(&view->transform.matrix, &v);
598 
599 		if (fabsf(v.f[3]) < 1e-6) {
600 			weston_log("warning: numerical instability in "
601 				"%s(), divisor = %g\n", __func__,
602 				v.f[3]);
603 			*x = 0;
604 			*y = 0;
605 			return;
606 		}
607 
608 		*x = v.f[0] / v.f[3];
609 		*y = v.f[1] / v.f[3];
610 	} else {
611 		*x = sx + view->geometry.x;
612 		*y = sy + view->geometry.y;
613 	}
614 }
615 
616 /** Transform a point to buffer coordinates
617  *
618  * \param width Surface width.
619  * \param height Surface height.
620  * \param transform Buffer transform.
621  * \param scale Buffer scale.
622  * \param sx Surface x coordinate of a point.
623  * \param sy Surface y coordinate of a point.
624  * \param[out] bx Buffer x coordinate of the point.
625  * \param[out] by Buffer Y coordinate of the point.
626  *
627  * Converts the given surface-local coordinates to buffer coordinates
628  * according to the given buffer transform and scale.
629  * This ignores wp_viewport.
630  *
631  * The given width and height must be the result of inverse scaled and
632  * inverse transformed buffer size.
633  */
634 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)635 weston_transformed_coord(int width, int height,
636 			 enum wl_output_transform transform,
637 			 int32_t scale,
638 			 float sx, float sy, float *bx, float *by)
639 {
640 	switch (transform) {
641 	case WL_OUTPUT_TRANSFORM_NORMAL:
642 	default:
643 		*bx = sx;
644 		*by = sy;
645 		break;
646 	case WL_OUTPUT_TRANSFORM_FLIPPED:
647 		*bx = width - sx;
648 		*by = sy;
649 		break;
650 	case WL_OUTPUT_TRANSFORM_90:
651 		*bx = sy;
652 		*by = width - sx;
653 		break;
654 	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
655 		*bx = sy;
656 		*by = sx;
657 		break;
658 	case WL_OUTPUT_TRANSFORM_180:
659 		*bx = width - sx;
660 		*by = height - sy;
661 		break;
662 	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
663 		*bx = sx;
664 		*by = height - sy;
665 		break;
666 	case WL_OUTPUT_TRANSFORM_270:
667 		*bx = height - sy;
668 		*by = sx;
669 		break;
670 	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
671 		*bx = height - sy;
672 		*by = width - sx;
673 		break;
674 	}
675 
676 	*bx *= scale;
677 	*by *= scale;
678 }
679 
680 /** Transform a rectangle to buffer coordinates
681  *
682  * \param width Surface width.
683  * \param height Surface height.
684  * \param transform Buffer transform.
685  * \param scale Buffer scale.
686  * \param rect Rectangle in surface coordinates.
687  * \return Rectangle in buffer coordinates.
688  *
689  * Converts the given surface-local rectangle to buffer coordinates
690  * according to the given buffer transform and scale. The resulting
691  * rectangle is guaranteed to be well-formed.
692  * This ignores wp_viewport.
693  *
694  * The given width and height must be the result of inverse scaled and
695  * inverse transformed buffer size.
696  */
697 WL_EXPORT pixman_box32_t
weston_transformed_rect(int width,int height,enum wl_output_transform transform,int32_t scale,pixman_box32_t rect)698 weston_transformed_rect(int width, int height,
699 			enum wl_output_transform transform,
700 			int32_t scale,
701 			pixman_box32_t rect)
702 {
703 	float x1, x2, y1, y2;
704 
705 	pixman_box32_t ret;
706 
707 	weston_transformed_coord(width, height, transform, scale,
708 				 rect.x1, rect.y1, &x1, &y1);
709 	weston_transformed_coord(width, height, transform, scale,
710 				 rect.x2, rect.y2, &x2, &y2);
711 
712 	if (x1 <= x2) {
713 		ret.x1 = x1;
714 		ret.x2 = x2;
715 	} else {
716 		ret.x1 = x2;
717 		ret.x2 = x1;
718 	}
719 
720 	if (y1 <= y2) {
721 		ret.y1 = y1;
722 		ret.y2 = y2;
723 	} else {
724 		ret.y1 = y2;
725 		ret.y2 = y1;
726 	}
727 
728 	return ret;
729 }
730 
731 /** Transform a region by a matrix, restricted to axis-aligned transformations
732  *
733  * Warning: This function does not work for projective, affine, or matrices
734  * that encode arbitrary rotations. Only 90-degree step rotations are
735  * supported.
736  */
737 WL_EXPORT void
weston_matrix_transform_region(pixman_region32_t * dest,struct weston_matrix * matrix,pixman_region32_t * src)738 weston_matrix_transform_region(pixman_region32_t *dest,
739 			       struct weston_matrix *matrix,
740 			       pixman_region32_t *src)
741 {
742 	pixman_box32_t *src_rects, *dest_rects;
743 	int nrects, i;
744 
745 	src_rects = pixman_region32_rectangles(src, &nrects);
746 	dest_rects = malloc(nrects * sizeof(*dest_rects));
747 	if (!dest_rects)
748 		return;
749 
750 	for (i = 0; i < nrects; i++) {
751 		struct weston_vector vec1 = {{
752 			src_rects[i].x1, src_rects[i].y1, 0, 1
753 		}};
754 		weston_matrix_transform(matrix, &vec1);
755 		vec1.f[0] /= vec1.f[3];
756 		vec1.f[1] /= vec1.f[3];
757 
758 		struct weston_vector vec2 = {{
759 			src_rects[i].x2, src_rects[i].y2, 0, 1
760 		}};
761 		weston_matrix_transform(matrix, &vec2);
762 		vec2.f[0] /= vec2.f[3];
763 		vec2.f[1] /= vec2.f[3];
764 
765 		if (vec1.f[0] < vec2.f[0]) {
766 			dest_rects[i].x1 = floor(vec1.f[0]);
767 			dest_rects[i].x2 = ceil(vec2.f[0]);
768 		} else {
769 			dest_rects[i].x1 = floor(vec2.f[0]);
770 			dest_rects[i].x2 = ceil(vec1.f[0]);
771 		}
772 
773 		if (vec1.f[1] < vec2.f[1]) {
774 			dest_rects[i].y1 = floor(vec1.f[1]);
775 			dest_rects[i].y2 = ceil(vec2.f[1]);
776 		} else {
777 			dest_rects[i].y1 = floor(vec2.f[1]);
778 			dest_rects[i].y2 = ceil(vec1.f[1]);
779 		}
780 	}
781 
782 	pixman_region32_clear(dest);
783 	pixman_region32_init_rects(dest, dest_rects, nrects);
784 	free(dest_rects);
785 }
786 
787 /** Transform a region to buffer coordinates
788  *
789  * \param width Surface width.
790  * \param height Surface height.
791  * \param transform Buffer transform.
792  * \param scale Buffer scale.
793  * \param[in] src Region in surface coordinates.
794  * \param[out] dest Resulting region in buffer coordinates.
795  *
796  * Converts the given surface-local region to buffer coordinates
797  * according to the given buffer transform and scale.
798  * This ignores wp_viewport.
799  *
800  * The given width and height must be the result of inverse scaled and
801  * inverse transformed buffer size.
802  *
803  * src and dest are allowed to point to the same memory for in-place conversion.
804  */
805 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)806 weston_transformed_region(int width, int height,
807 			  enum wl_output_transform transform,
808 			  int32_t scale,
809 			  pixman_region32_t *src, pixman_region32_t *dest)
810 {
811 	pixman_box32_t *src_rects, *dest_rects;
812 	int nrects, i;
813 
814 	if (transform == WL_OUTPUT_TRANSFORM_NORMAL && scale == 1) {
815 		if (src != dest)
816 			pixman_region32_copy(dest, src);
817 		return;
818 	}
819 
820 	src_rects = pixman_region32_rectangles(src, &nrects);
821 	dest_rects = malloc(nrects * sizeof(*dest_rects));
822 	if (!dest_rects)
823 		return;
824 
825 	if (transform == WL_OUTPUT_TRANSFORM_NORMAL) {
826 		memcpy(dest_rects, src_rects, nrects * sizeof(*dest_rects));
827 	} else {
828 		for (i = 0; i < nrects; i++) {
829 			switch (transform) {
830 			default:
831 			case WL_OUTPUT_TRANSFORM_NORMAL:
832 				dest_rects[i].x1 = src_rects[i].x1;
833 				dest_rects[i].y1 = src_rects[i].y1;
834 				dest_rects[i].x2 = src_rects[i].x2;
835 				dest_rects[i].y2 = src_rects[i].y2;
836 				break;
837 			case WL_OUTPUT_TRANSFORM_90:
838 				dest_rects[i].x1 = src_rects[i].y1;
839 				dest_rects[i].y1 = width - src_rects[i].x2;
840 				dest_rects[i].x2 = src_rects[i].y2;
841 				dest_rects[i].y2 = width - src_rects[i].x1;
842 				break;
843 			case WL_OUTPUT_TRANSFORM_180:
844 				dest_rects[i].x1 = width - src_rects[i].x2;
845 				dest_rects[i].y1 = height - src_rects[i].y2;
846 				dest_rects[i].x2 = width - src_rects[i].x1;
847 				dest_rects[i].y2 = height - src_rects[i].y1;
848 				break;
849 			case WL_OUTPUT_TRANSFORM_270:
850 				dest_rects[i].x1 = height - src_rects[i].y2;
851 				dest_rects[i].y1 = src_rects[i].x1;
852 				dest_rects[i].x2 = height - src_rects[i].y1;
853 				dest_rects[i].y2 = src_rects[i].x2;
854 				break;
855 			case WL_OUTPUT_TRANSFORM_FLIPPED:
856 				dest_rects[i].x1 = width - src_rects[i].x2;
857 				dest_rects[i].y1 = src_rects[i].y1;
858 				dest_rects[i].x2 = width - src_rects[i].x1;
859 				dest_rects[i].y2 = src_rects[i].y2;
860 				break;
861 			case WL_OUTPUT_TRANSFORM_FLIPPED_90:
862 				dest_rects[i].x1 = src_rects[i].y1;
863 				dest_rects[i].y1 = src_rects[i].x1;
864 				dest_rects[i].x2 = src_rects[i].y2;
865 				dest_rects[i].y2 = src_rects[i].x2;
866 				break;
867 			case WL_OUTPUT_TRANSFORM_FLIPPED_180:
868 				dest_rects[i].x1 = src_rects[i].x1;
869 				dest_rects[i].y1 = height - src_rects[i].y2;
870 				dest_rects[i].x2 = src_rects[i].x2;
871 				dest_rects[i].y2 = height - src_rects[i].y1;
872 				break;
873 			case WL_OUTPUT_TRANSFORM_FLIPPED_270:
874 				dest_rects[i].x1 = height - src_rects[i].y2;
875 				dest_rects[i].y1 = width - src_rects[i].x2;
876 				dest_rects[i].x2 = height - src_rects[i].y1;
877 				dest_rects[i].y2 = width - src_rects[i].x1;
878 				break;
879 			}
880 		}
881 	}
882 
883 	if (scale != 1) {
884 		for (i = 0; i < nrects; i++) {
885 			dest_rects[i].x1 *= scale;
886 			dest_rects[i].x2 *= scale;
887 			dest_rects[i].y1 *= scale;
888 			dest_rects[i].y2 *= scale;
889 		}
890 	}
891 
892 	pixman_region32_clear(dest);
893 	pixman_region32_init_rects(dest, dest_rects, nrects);
894 	free(dest_rects);
895 }
896 
897 static void
viewport_surface_to_buffer(struct weston_surface * surface,float sx,float sy,float * bx,float * by)898 viewport_surface_to_buffer(struct weston_surface *surface,
899 			   float sx, float sy, float *bx, float *by)
900 {
901 	struct weston_buffer_viewport *vp = &surface->buffer_viewport;
902 	double src_width, src_height;
903 	double src_x, src_y;
904 
905 	if (vp->buffer.src_width == wl_fixed_from_int(-1)) {
906 		if (vp->surface.width == -1) {
907 			*bx = sx;
908 			*by = sy;
909 			return;
910 		}
911 
912 		src_x = 0.0;
913 		src_y = 0.0;
914 		src_width = surface->width_from_buffer;
915 		src_height = surface->height_from_buffer;
916 	} else {
917 		src_x = wl_fixed_to_double(vp->buffer.src_x);
918 		src_y = wl_fixed_to_double(vp->buffer.src_y);
919 		src_width = wl_fixed_to_double(vp->buffer.src_width);
920 		src_height = wl_fixed_to_double(vp->buffer.src_height);
921 	}
922 
923 	*bx = sx * src_width / surface->width + src_x;
924 	*by = sy * src_height / surface->height + src_y;
925 }
926 
927 WL_EXPORT void
weston_surface_to_buffer_float(struct weston_surface * surface,float sx,float sy,float * bx,float * by)928 weston_surface_to_buffer_float(struct weston_surface *surface,
929 			       float sx, float sy, float *bx, float *by)
930 {
931 	struct weston_buffer_viewport *vp = &surface->buffer_viewport;
932 
933 	/* first transform coordinates if the viewport is set */
934 	viewport_surface_to_buffer(surface, sx, sy, bx, by);
935 
936 	weston_transformed_coord(surface->width_from_buffer,
937 				 surface->height_from_buffer,
938 				 vp->buffer.transform, vp->buffer.scale,
939 				 *bx, *by, bx, by);
940 }
941 
942 /** Transform a rectangle from surface coordinates to buffer coordinates
943  *
944  * \param surface The surface to fetch wp_viewport and buffer transformation
945  * from.
946  * \param rect The rectangle to transform.
947  * \return The transformed rectangle.
948  *
949  * Viewport and buffer transformations can only do translation, scaling,
950  * and rotations in 90-degree steps. Therefore the only loss in the
951  * conversion is coordinate rounding.
952  *
953  * However, some coordinate rounding takes place as an intermediate
954  * step before the buffer scale factor is applied, so the rectangle
955  * boundary may not be exactly as expected.
956  *
957  * This is OK for damage tracking since a little extra coverage is
958  * not a problem.
959  */
960 WL_EXPORT pixman_box32_t
weston_surface_to_buffer_rect(struct weston_surface * surface,pixman_box32_t rect)961 weston_surface_to_buffer_rect(struct weston_surface *surface,
962 			      pixman_box32_t rect)
963 {
964 	struct weston_buffer_viewport *vp = &surface->buffer_viewport;
965 	float xf, yf;
966 
967 	/* first transform box coordinates if the viewport is set */
968 	viewport_surface_to_buffer(surface, rect.x1, rect.y1, &xf, &yf);
969 	rect.x1 = floorf(xf);
970 	rect.y1 = floorf(yf);
971 
972 	viewport_surface_to_buffer(surface, rect.x2, rect.y2, &xf, &yf);
973 	rect.x2 = ceilf(xf);
974 	rect.y2 = ceilf(yf);
975 
976 	return weston_transformed_rect(surface->width_from_buffer,
977 				       surface->height_from_buffer,
978 				       vp->buffer.transform, vp->buffer.scale,
979 				       rect);
980 }
981 
982 /** Transform a region from surface coordinates to buffer coordinates
983  *
984  * \param surface The surface to fetch wp_viewport and buffer transformation
985  * from.
986  * \param[in] surface_region The region in surface coordinates.
987  * \param[out] buffer_region The region converted to buffer coordinates.
988  *
989  * Buffer_region must be init'd, but will be completely overwritten.
990  *
991  * Viewport and buffer transformations can only do translation, scaling,
992  * and rotations in 90-degree steps. Therefore the only loss in the
993  * conversion is from the coordinate rounding that takes place in
994  * \ref weston_surface_to_buffer_rect.
995  *
996  */
997 WL_EXPORT void
weston_surface_to_buffer_region(struct weston_surface * surface,pixman_region32_t * surface_region,pixman_region32_t * buffer_region)998 weston_surface_to_buffer_region(struct weston_surface *surface,
999 				pixman_region32_t *surface_region,
1000 				pixman_region32_t *buffer_region)
1001 {
1002 	pixman_box32_t *src_rects, *dest_rects;
1003 	int nrects, i;
1004 
1005 	src_rects = pixman_region32_rectangles(surface_region, &nrects);
1006 	dest_rects = malloc(nrects * sizeof(*dest_rects));
1007 	if (!dest_rects)
1008 		return;
1009 
1010 	for (i = 0; i < nrects; i++) {
1011 		dest_rects[i] = weston_surface_to_buffer_rect(surface,
1012 							      src_rects[i]);
1013 	}
1014 
1015 	pixman_region32_fini(buffer_region);
1016 	pixman_region32_init_rects(buffer_region, dest_rects, nrects);
1017 	free(dest_rects);
1018 }
1019 
1020 WL_EXPORT void
weston_view_move_to_plane(struct weston_view * view,struct weston_plane * plane)1021 weston_view_move_to_plane(struct weston_view *view,
1022 			     struct weston_plane *plane)
1023 {
1024 	if (view->plane == plane)
1025 		return;
1026 
1027 	weston_view_damage_below(view);
1028 	view->plane = plane;
1029 	weston_surface_damage(view->surface);
1030 }
1031 
1032 /** Inflict damage on the plane where the view is visible.
1033  *
1034  * \param view The view that causes the damage.
1035  *
1036  * If the view is currently on a plane (including the primary plane),
1037  * take the view's boundingbox, subtract all the opaque views that cover it,
1038  * and add the remaining region as damage to the plane. This corresponds
1039  * to the damage inflicted to the plane if this view disappeared.
1040  *
1041  * A repaint is scheduled for this view.
1042  *
1043  * The region of all opaque views covering this view is stored in
1044  * weston_view::clip and updated by view_accumulate_damage() during
1045  * weston_output_repaint(). Specifically, that region matches the
1046  * scenegraph as it was last painted.
1047  */
1048 WL_EXPORT void
weston_view_damage_below(struct weston_view * view)1049 weston_view_damage_below(struct weston_view *view)
1050 {
1051 	pixman_region32_t damage;
1052 
1053 	pixman_region32_init(&damage);
1054 	pixman_region32_subtract(&damage, &view->transform.boundingbox,
1055 				 &view->clip);
1056 	if (view->plane)
1057 		pixman_region32_union(&view->plane->damage,
1058 				      &view->plane->damage, &damage);
1059 	pixman_region32_fini(&damage);
1060 	weston_view_schedule_repaint(view);
1061 }
1062 
1063 /** Send wl_surface.enter/leave events
1064  *
1065  * \param surface The surface.
1066  * \param head A head of the entered/left output.
1067  * \param enter True if entered.
1068  * \param leave True if left.
1069  *
1070  * Send the enter/leave events for all protocol objects bound to the given
1071  * output by the client owning the surface.
1072  */
1073 static void
weston_surface_send_enter_leave(struct weston_surface * surface,struct weston_head * head,bool enter,bool leave)1074 weston_surface_send_enter_leave(struct weston_surface *surface,
1075 				struct weston_head *head,
1076 				bool enter,
1077 				bool leave)
1078 {
1079 	struct wl_resource *wloutput;
1080 	struct wl_client *client;
1081 
1082 	assert(enter != leave);
1083 
1084 	client = wl_resource_get_client(surface->resource);
1085 	wl_resource_for_each(wloutput, &head->resource_list) {
1086 		if (wl_resource_get_client(wloutput) != client)
1087 			continue;
1088 
1089 		if (enter)
1090 			wl_surface_send_enter(surface->resource, wloutput);
1091 		if (leave)
1092 			wl_surface_send_leave(surface->resource, wloutput);
1093 	}
1094 }
1095 
1096 static void
weston_surface_compute_protection(struct protected_surface * psurface)1097 weston_surface_compute_protection(struct protected_surface *psurface)
1098 {
1099 	enum weston_hdcp_protection min_protection;
1100 	bool min_protection_valid = false;
1101 	struct weston_surface *surface = psurface->surface;
1102 	struct weston_output *output;
1103 
1104 	wl_list_for_each(output, &surface->compositor->output_list, link)
1105 		if (surface->output_mask & (1u << output->id)) {
1106 			/*
1107 			 * If the content-protection is enabled with protection
1108 			 * mode as RELAXED for a surface, and if
1109 			 * content-recording features like: screen-shooter,
1110 			 * recorder, screen-sharing, etc are on, then notify the
1111 			 * client, that the protection is disabled.
1112 			 *
1113 			 * Note: If the protection mode is ENFORCED then there
1114 			 * is no need to bother the client as the renderer takes
1115 			 * care of censoring the visibility of the protected
1116 			 * content.
1117 			 */
1118 
1119 			if (output->disable_planes > 0 &&
1120 			    surface->protection_mode == WESTON_SURFACE_PROTECTION_MODE_RELAXED) {
1121 				min_protection = WESTON_HDCP_DISABLE;
1122 				min_protection_valid = true;
1123 				break;
1124 			}
1125 			if (!min_protection_valid) {
1126 				min_protection = output->current_protection;
1127 				min_protection_valid = true;
1128 			}
1129 			if (output->current_protection < min_protection)
1130 				min_protection = output->current_protection;
1131 		}
1132 	if (!min_protection_valid)
1133 		min_protection = WESTON_HDCP_DISABLE;
1134 
1135 	surface->current_protection = min_protection;
1136 
1137 	weston_protected_surface_send_event(psurface, surface->current_protection);
1138 }
1139 
1140 static void
notify_surface_protection_change(void * data)1141 notify_surface_protection_change(void *data)
1142 {
1143 	struct weston_compositor *compositor = data;
1144 	struct content_protection *cp;
1145 	struct protected_surface *psurface;
1146 
1147 	cp = compositor->content_protection;
1148 	cp->surface_protection_update = NULL;
1149 
1150 	/* Notify the clients, whose surfaces are changed */
1151 	wl_list_for_each(psurface, &cp->protected_list, link)
1152 		if (psurface && psurface->surface)
1153 			weston_surface_compute_protection(psurface);
1154 }
1155 
1156 /**
1157  * \param compositor weston_compositor
1158  *
1159  * Schedule an idle task to notify surface about the update in protection,
1160  * if not already scheduled.
1161  */
1162 static void
weston_schedule_surface_protection_update(struct weston_compositor * compositor)1163 weston_schedule_surface_protection_update(struct weston_compositor *compositor)
1164 {
1165 	struct content_protection *cp = compositor->content_protection;
1166 	struct wl_event_loop *loop;
1167 
1168 	if (!cp || cp->surface_protection_update)
1169 		return;
1170 	loop = wl_display_get_event_loop(compositor->wl_display);
1171 	cp->surface_protection_update = wl_event_loop_add_idle(loop,
1172 					       notify_surface_protection_change,
1173 					       compositor);
1174 }
1175 
1176 /**
1177  * \param es    The surface
1178  * \param mask  The new set of outputs for the surface
1179  *
1180  * Sets the surface's set of outputs to the ones specified by
1181  * the new output mask provided.  Identifies the outputs that
1182  * have changed, the posts enter and leave events for these
1183  * outputs as appropriate.
1184  */
1185 static void
weston_surface_update_output_mask(struct weston_surface * es,uint32_t mask)1186 weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask)
1187 {
1188     LOG_INFO("update surface %p output mask %x", es, mask);
1189 	uint32_t different = es->output_mask ^ mask;
1190 	uint32_t entered = mask & different;
1191 	uint32_t left = es->output_mask & different;
1192 	uint32_t output_bit;
1193 	struct weston_output *output;
1194 	struct weston_head *head;
1195 
1196 	es->output_mask = mask;
1197 	if (es->resource == NULL)
1198 		return;
1199 	if (different == 0)
1200 		return;
1201 
1202 	wl_list_for_each(output, &es->compositor->output_list, link) {
1203 		output_bit = 1u << output->id;
1204 		if (!(output_bit & different))
1205 			continue;
1206 
1207 		wl_list_for_each(head, &output->head_list, output_link) {
1208 			weston_surface_send_enter_leave(es, head,
1209 							output_bit & entered,
1210 							output_bit & left);
1211 		}
1212 	}
1213 	/*
1214 	 * Change in surfaces' output mask might trigger a change in its
1215 	 * protection.
1216 	 */
1217 	weston_schedule_surface_protection_update(es->compositor);
1218 }
1219 
1220 static void
notify_view_output_destroy(struct wl_listener * listener,void * data)1221 notify_view_output_destroy(struct wl_listener *listener, void *data)
1222 {
1223 	struct weston_view *view =
1224 		container_of(listener,
1225 		     struct weston_view, output_destroy_listener);
1226 
1227 	view->output = NULL;
1228 	view->output_destroy_listener.notify = NULL;
1229 }
1230 
1231 /** Set the primary output of the view
1232  *
1233  * \param view The view whose primary output to set
1234  * \param output The new primary output for the view
1235  *
1236  * Set \a output to be the primary output of the \a view.
1237  *
1238  * Notice that the assignment may be temporary; the primary output could be
1239  * automatically changed. Hence, one cannot rely on the value persisting.
1240  *
1241  * Passing NULL as /a output will set the primary output to NULL.
1242  */
1243 WL_EXPORT void
weston_view_set_output(struct weston_view * view,struct weston_output * output)1244 weston_view_set_output(struct weston_view *view, struct weston_output *output)
1245 {
1246 	if (view->output_destroy_listener.notify) {
1247 		wl_list_remove(&view->output_destroy_listener.link);
1248 		view->output_destroy_listener.notify = NULL;
1249 	}
1250 	view->output = output;
1251 	if (output) {
1252 		view->output_destroy_listener.notify =
1253 			notify_view_output_destroy;
1254 		wl_signal_add(&output->destroy_signal,
1255 			      &view->output_destroy_listener);
1256 	}
1257 }
1258 
1259 /** Recalculate which output(s) the surface has views displayed on
1260  *
1261  * \param es  The surface to remap to outputs
1262  *
1263  * Finds the output that is showing the largest amount of one
1264  * of the surface's various views.  This output becomes the
1265  * surface's primary output for vsync and frame callback purposes.
1266  *
1267  * Also notes all outputs of all of the surface's views
1268  * in the output_mask for the surface.
1269  */
1270 static void
weston_surface_assign_output(struct weston_surface * es)1271 weston_surface_assign_output(struct weston_surface *es)
1272 {
1273     LOG_ENTER();
1274 	struct weston_output *new_output;
1275 	struct weston_view *view;
1276 	pixman_region32_t region;
1277 	uint32_t max, area, mask;
1278 	pixman_box32_t *e;
1279 
1280 	new_output = NULL;
1281 	max = 0;
1282 	mask = 0;
1283 	pixman_region32_init(&region);
1284 	wl_list_for_each(view, &es->views, surface_link) {
1285 		if (!view->output)
1286 			continue;
1287 
1288 		pixman_region32_intersect(&region, &view->transform.boundingbox,
1289 					  &view->output->region);
1290 
1291 		e = pixman_region32_extents(&region);
1292 		area = (e->x2 - e->x1) * (e->y2 - e->y1);
1293 
1294 		mask |= view->output_mask;
1295 
1296 		if (area >= max) {
1297 			new_output = view->output;
1298 			max = area;
1299 		}
1300 	}
1301 	pixman_region32_fini(&region);
1302 
1303 	es->output = new_output;
1304 	weston_surface_update_output_mask(es, mask);
1305     LOG_EXIT();
1306 }
1307 
1308 /** Recalculate which output(s) the view is displayed on
1309  *
1310  * \param ev  The view to remap to outputs
1311  *
1312  * Identifies the set of outputs that the view is visible on,
1313  * noting them into the output_mask.  The output that the view
1314  * is most visible on is set as the view's primary output.
1315  *
1316  * Also does the same for the view's surface.  See
1317  * weston_surface_assign_output().
1318  */
1319 static void
weston_view_assign_output(struct weston_view * ev)1320 weston_view_assign_output(struct weston_view *ev)
1321 {
1322     LOG_ENTER();
1323 	struct weston_compositor *ec = ev->surface->compositor;
1324 	struct weston_output *output, *new_output;
1325 	pixman_region32_t region;
1326 	uint32_t max, area, mask;
1327 	pixman_box32_t *e;
1328 
1329 	new_output = NULL;
1330 	max = 0;
1331 	mask = 0;
1332 	pixman_region32_init(&region);
1333 	wl_list_for_each(output, &ec->output_list, link) {
1334 		if (output->destroying)
1335 			continue;
1336 
1337 		pixman_region32_intersect(&region, &ev->transform.boundingbox,
1338 					  &output->region);
1339 
1340 		e = pixman_region32_extents(&region);
1341 		area = (e->x2 - e->x1) * (e->y2 - e->y1);
1342 
1343 		if (area > 0)
1344 			mask |= 1u << output->id;
1345 
1346 		if (area >= max) {
1347 			new_output = output;
1348 			max = area;
1349 		}
1350 	}
1351 	pixman_region32_fini(&region);
1352 
1353 	weston_view_set_output(ev, new_output);
1354 	ev->output_mask = mask;
1355 
1356 	weston_surface_assign_output(ev->surface);
1357     LOG_EXIT();
1358 }
1359 
1360 static void
weston_view_to_view_map(struct weston_view * from,struct weston_view * to,int from_x,int from_y,int * to_x,int * to_y)1361 weston_view_to_view_map(struct weston_view *from, struct weston_view *to,
1362 			int from_x, int from_y, int *to_x, int *to_y)
1363 {
1364 	float x, y;
1365 
1366 	weston_view_to_global_float(from, from_x, from_y, &x, &y);
1367 	weston_view_from_global_float(to, x, y, &x, &y);
1368 
1369 	*to_x = round(x);
1370 	*to_y = round(y);
1371 }
1372 
1373 static void
weston_view_transfer_scissor(struct weston_view * from,struct weston_view * to)1374 weston_view_transfer_scissor(struct weston_view *from, struct weston_view *to)
1375 {
1376 	pixman_box32_t *a;
1377 	pixman_box32_t b;
1378 
1379 	a = pixman_region32_extents(&from->geometry.scissor);
1380 
1381 	weston_view_to_view_map(from, to, a->x1, a->y1, &b.x1, &b.y1);
1382 	weston_view_to_view_map(from, to, a->x2, a->y2, &b.x2, &b.y2);
1383 
1384 	pixman_region32_fini(&to->geometry.scissor);
1385 	pixman_region32_init_with_extents(&to->geometry.scissor, &b);
1386 }
1387 
1388 static void
view_compute_bbox(struct weston_view * view,const pixman_box32_t * inbox,pixman_region32_t * bbox)1389 view_compute_bbox(struct weston_view *view, const pixman_box32_t *inbox,
1390 		  pixman_region32_t *bbox)
1391 {
1392 	float min_x = HUGE_VALF,  min_y = HUGE_VALF;
1393 	float max_x = -HUGE_VALF, max_y = -HUGE_VALF;
1394 	int32_t s[4][2] = {
1395 		{ inbox->x1, inbox->y1 },
1396 		{ inbox->x1, inbox->y2 },
1397 		{ inbox->x2, inbox->y1 },
1398 		{ inbox->x2, inbox->y2 },
1399 	};
1400 	float int_x, int_y;
1401 	int i;
1402 
1403 	if (inbox->x1 == inbox->x2 || inbox->y1 == inbox->y2) {
1404 		/* avoid rounding empty bbox to 1x1 */
1405 		pixman_region32_init(bbox);
1406 		return;
1407 	}
1408 
1409 	for (i = 0; i < 4; ++i) {
1410 		float x, y;
1411 		weston_view_to_global_float(view, s[i][0], s[i][1], &x, &y);
1412 		if (x < min_x)
1413 			min_x = x;
1414 		if (x > max_x)
1415 			max_x = x;
1416 		if (y < min_y)
1417 			min_y = y;
1418 		if (y > max_y)
1419 			max_y = y;
1420 	}
1421 
1422 	int_x = floorf(min_x);
1423 	int_y = floorf(min_y);
1424 	pixman_region32_init_rect(bbox, int_x, int_y,
1425 				  ceilf(max_x) - int_x, ceilf(max_y) - int_y);
1426 }
1427 
1428 static void
weston_view_update_transform_disable(struct weston_view * view)1429 weston_view_update_transform_disable(struct weston_view *view)
1430 {
1431 	view->transform.enabled = 0;
1432 
1433 	/* round off fractions when not transformed */
1434 	view->geometry.x = roundf(view->geometry.x);
1435 	view->geometry.y = roundf(view->geometry.y);
1436 
1437 	/* Otherwise identity matrix, but with x and y translation. */
1438 	view->transform.position.matrix.type = WESTON_MATRIX_TRANSFORM_TRANSLATE;
1439 	view->transform.position.matrix.d[12] = view->geometry.x;
1440 	view->transform.position.matrix.d[13] = view->geometry.y;
1441 
1442 	view->transform.matrix = view->transform.position.matrix;
1443 
1444 	view->transform.inverse = view->transform.position.matrix;
1445 	view->transform.inverse.d[12] = -view->geometry.x;
1446 	view->transform.inverse.d[13] = -view->geometry.y;
1447 
1448 	pixman_region32_init_rect(&view->transform.boundingbox,
1449 				  0, 0,
1450 				  view->surface->width,
1451 				  view->surface->height);
1452 	if (view->geometry.scissor_enabled)
1453 		pixman_region32_intersect(&view->transform.boundingbox,
1454 					  &view->transform.boundingbox,
1455 					  &view->geometry.scissor);
1456 
1457 	pixman_region32_translate(&view->transform.boundingbox,
1458 				  view->geometry.x, view->geometry.y);
1459 
1460 	if (view->alpha == 1.0) {
1461 		pixman_region32_copy(&view->transform.opaque,
1462 				     &view->surface->opaque);
1463 		pixman_region32_translate(&view->transform.opaque,
1464 					  view->geometry.x,
1465 					  view->geometry.y);
1466 	}
1467 }
1468 
1469 static int
weston_view_update_transform_enable(struct weston_view * view)1470 weston_view_update_transform_enable(struct weston_view *view)
1471 {
1472 	struct weston_view *parent = view->geometry.parent;
1473 	struct weston_matrix *matrix = &view->transform.matrix;
1474 	struct weston_matrix *inverse = &view->transform.inverse;
1475 	struct weston_transform *tform;
1476 	pixman_region32_t surfregion;
1477 	const pixman_box32_t *surfbox;
1478 
1479 	view->transform.enabled = 1;
1480 
1481 	/* Otherwise identity matrix, but with x and y translation. */
1482 	view->transform.position.matrix.type = WESTON_MATRIX_TRANSFORM_TRANSLATE;
1483 	view->transform.position.matrix.d[12] = view->geometry.x;
1484 	view->transform.position.matrix.d[13] = view->geometry.y;
1485 
1486 	weston_matrix_init(matrix);
1487 	wl_list_for_each(tform, &view->geometry.transformation_list, link)
1488 		weston_matrix_multiply(matrix, &tform->matrix);
1489 
1490 	if (parent)
1491 		weston_matrix_multiply(matrix, &parent->transform.matrix);
1492 
1493 	if (weston_matrix_invert(inverse, matrix) < 0) {
1494 		/* Oops, bad total transformation, not invertible */
1495 		weston_log("error: weston_view %p"
1496 			" transformation not invertible.\n", view);
1497 		return -1;
1498 	}
1499 
1500 	if (view->alpha == 1.0 &&
1501 	    matrix->type == WESTON_MATRIX_TRANSFORM_TRANSLATE) {
1502 		pixman_region32_copy(&view->transform.opaque,
1503 				     &view->surface->opaque);
1504 		pixman_region32_translate(&view->transform.opaque,
1505 					  matrix->d[12],
1506 					  matrix->d[13]);
1507 	}
1508 
1509 	pixman_region32_init_rect(&surfregion, 0, 0,
1510 				  view->surface->width, view->surface->height);
1511 	if (view->geometry.scissor_enabled)
1512 		pixman_region32_intersect(&surfregion, &surfregion,
1513 					  &view->geometry.scissor);
1514 	surfbox = pixman_region32_extents(&surfregion);
1515 
1516 	view_compute_bbox(view, surfbox, &view->transform.boundingbox);
1517 	pixman_region32_fini(&surfregion);
1518 
1519 	return 0;
1520 }
1521 
1522 static struct weston_layer *
get_view_layer(struct weston_view * view)1523 get_view_layer(struct weston_view *view)
1524 {
1525 	if (view->parent_view)
1526 		return get_view_layer(view->parent_view);
1527 	return view->layer_link.layer;
1528 }
1529 
1530 WL_EXPORT void
weston_view_update_transform(struct weston_view * view)1531 weston_view_update_transform(struct weston_view *view)
1532 {
1533     LOG_ENTER();
1534 	struct weston_view *parent = view->geometry.parent;
1535 	struct weston_layer *layer;
1536 	pixman_region32_t mask;
1537 
1538 	if (!view->transform.dirty) {
1539         LOG_EXIT();
1540 		return;
1541     }
1542 
1543 	if (parent)
1544 		weston_view_update_transform(parent);
1545 
1546 	view->transform.dirty = 0;
1547 
1548 	weston_view_damage_below(view);
1549 
1550 	pixman_region32_fini(&view->transform.boundingbox);
1551 	pixman_region32_fini(&view->transform.opaque);
1552 	pixman_region32_init(&view->transform.opaque);
1553 
1554 	/* transform.position is always in transformation_list */
1555 	if (view->geometry.transformation_list.next ==
1556 	    &view->transform.position.link &&
1557 	    view->geometry.transformation_list.prev ==
1558 	    &view->transform.position.link &&
1559 	    !parent) {
1560 		weston_view_update_transform_disable(view);
1561 	} else {
1562 		if (weston_view_update_transform_enable(view) < 0)
1563 			weston_view_update_transform_disable(view);
1564 	}
1565 
1566 	layer = get_view_layer(view);
1567 	if (layer) {
1568 		pixman_region32_init_with_extents(&mask, &layer->mask);
1569 		pixman_region32_intersect(&view->transform.boundingbox,
1570 					  &view->transform.boundingbox, &mask);
1571 		pixman_region32_intersect(&view->transform.opaque,
1572 					  &view->transform.opaque, &mask);
1573 		pixman_region32_fini(&mask);
1574 	}
1575 
1576 	if (parent) {
1577 		if (parent->geometry.scissor_enabled) {
1578 			view->geometry.scissor_enabled = true;
1579 			weston_view_transfer_scissor(parent, view);
1580 		} else {
1581 			view->geometry.scissor_enabled = false;
1582 		}
1583 	}
1584 
1585 	weston_view_damage_below(view);
1586 
1587 	weston_view_assign_output(view);
1588 
1589 	wl_signal_emit(&view->surface->compositor->transform_signal,
1590 		       view->surface);
1591     LOG_EXIT();
1592 }
1593 
1594 WL_EXPORT void
weston_view_geometry_dirty(struct weston_view * view)1595 weston_view_geometry_dirty(struct weston_view *view)
1596 {
1597 	struct weston_view *child;
1598 
1599 	/*
1600 	 * The invariant: if view->geometry.dirty, then all views
1601 	 * in view->geometry.child_list have geometry.dirty too.
1602 	 * Corollary: if not parent->geometry.dirty, then all ancestors
1603 	 * are not dirty.
1604 	 */
1605 
1606 	if (view->transform.dirty)
1607 		return;
1608 
1609 	view->transform.dirty = 1;
1610 
1611 	wl_list_for_each(child, &view->geometry.child_list,
1612 			 geometry.parent_link)
1613 		weston_view_geometry_dirty(child);
1614 }
1615 
1616 WL_EXPORT void
weston_view_to_global_fixed(struct weston_view * view,wl_fixed_t vx,wl_fixed_t vy,wl_fixed_t * x,wl_fixed_t * y)1617 weston_view_to_global_fixed(struct weston_view *view,
1618 			    wl_fixed_t vx, wl_fixed_t vy,
1619 			    wl_fixed_t *x, wl_fixed_t *y)
1620 {
1621 	float xf, yf;
1622 
1623 	weston_view_to_global_float(view,
1624 				    wl_fixed_to_double(vx),
1625 				    wl_fixed_to_double(vy),
1626 				    &xf, &yf);
1627 	*x = wl_fixed_from_double(xf);
1628 	*y = wl_fixed_from_double(yf);
1629 }
1630 
1631 WL_EXPORT void
weston_view_from_global_float(struct weston_view * view,float x,float y,float * vx,float * vy)1632 weston_view_from_global_float(struct weston_view *view,
1633 			      float x, float y, float *vx, float *vy)
1634 {
1635 	if (view->transform.enabled) {
1636 		struct weston_vector v = { { x, y, 0.0f, 1.0f } };
1637 
1638 		weston_matrix_transform(&view->transform.inverse, &v);
1639 
1640 		if (fabsf(v.f[3]) < 1e-6) {
1641 			weston_log("warning: numerical instability in "
1642 				"weston_view_from_global(), divisor = %g\n",
1643 				v.f[3]);
1644 			*vx = 0;
1645 			*vy = 0;
1646 			return;
1647 		}
1648 
1649 		*vx = v.f[0] / v.f[3];
1650 		*vy = v.f[1] / v.f[3];
1651 	} else {
1652 		*vx = x - view->geometry.x;
1653 		*vy = y - view->geometry.y;
1654 	}
1655 }
1656 
1657 WL_EXPORT void
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)1658 weston_view_from_global_fixed(struct weston_view *view,
1659 			      wl_fixed_t x, wl_fixed_t y,
1660 			      wl_fixed_t *vx, wl_fixed_t *vy)
1661 {
1662 	float vxf, vyf;
1663 
1664 	weston_view_from_global_float(view,
1665 				      wl_fixed_to_double(x),
1666 				      wl_fixed_to_double(y),
1667 				      &vxf, &vyf);
1668 	*vx = wl_fixed_from_double(vxf);
1669 	*vy = wl_fixed_from_double(vyf);
1670 }
1671 
1672 WL_EXPORT void
weston_view_from_global(struct weston_view * view,int32_t x,int32_t y,int32_t * vx,int32_t * vy)1673 weston_view_from_global(struct weston_view *view,
1674 			int32_t x, int32_t y, int32_t *vx, int32_t *vy)
1675 {
1676 	float vxf, vyf;
1677 
1678 	weston_view_from_global_float(view, x, y, &vxf, &vyf);
1679 	*vx = floorf(vxf);
1680 	*vy = floorf(vyf);
1681 }
1682 
1683 /**
1684  * \param surface  The surface to be repainted
1685  *
1686  * Marks the output(s) that the surface is shown on as needing to be
1687  * repainted.  See weston_output_schedule_repaint().
1688  */
1689 WL_EXPORT void
weston_surface_schedule_repaint(struct weston_surface * surface)1690 weston_surface_schedule_repaint(struct weston_surface *surface)
1691 {
1692     LOG_INFO("surface schedule repaint");
1693 	struct weston_output *output;
1694 
1695 	wl_list_for_each(output, &surface->compositor->output_list, link)
1696 		if (surface->output_mask & (1u << output->id))
1697 			weston_output_schedule_repaint(output);
1698 }
1699 
1700 /**
1701  * \param view  The view to be repainted
1702  *
1703  * Marks the output(s) that the view is shown on as needing to be
1704  * repainted.  See weston_output_schedule_repaint().
1705  */
1706 WL_EXPORT void
weston_view_schedule_repaint(struct weston_view * view)1707 weston_view_schedule_repaint(struct weston_view *view)
1708 {
1709     LOG_INFO("view schedule repaint");
1710 	struct weston_output *output;
1711 
1712 	wl_list_for_each(output, &view->surface->compositor->output_list, link)
1713 		if (view->output_mask & (1u << output->id))
1714 			weston_output_schedule_repaint(output);
1715 }
1716 
1717 /**
1718  * XXX: This function does it the wrong way.
1719  * surface->damage is the damage from the client, and causes
1720  * surface_flush_damage() to copy pixels. No window management action can
1721  * cause damage to the client-provided content, warranting re-upload!
1722  *
1723  * Instead of surface->damage, this function should record the damage
1724  * with all the views for this surface to avoid extraneous texture
1725  * uploads.
1726  */
1727 WL_EXPORT void
weston_surface_damage(struct weston_surface * surface)1728 weston_surface_damage(struct weston_surface *surface)
1729 {
1730 	pixman_region32_union_rect(&surface->damage, &surface->damage,
1731 				   0, 0, surface->width,
1732 				   surface->height);
1733 
1734 	weston_surface_schedule_repaint(surface);
1735 }
1736 
1737 WL_EXPORT void
weston_view_set_position(struct weston_view * view,float x,float y)1738 weston_view_set_position(struct weston_view *view, float x, float y)
1739 {
1740 	if (view->geometry.x == x && view->geometry.y == y)
1741 		return;
1742 
1743 	view->geometry.x = x;
1744 	view->geometry.y = y;
1745 	weston_view_geometry_dirty(view);
1746 }
1747 
1748 static void
transform_parent_handle_parent_destroy(struct wl_listener * listener,void * data)1749 transform_parent_handle_parent_destroy(struct wl_listener *listener,
1750 				       void *data)
1751 {
1752 	struct weston_view *view =
1753 		container_of(listener, struct weston_view,
1754 			     geometry.parent_destroy_listener);
1755 
1756 	weston_view_set_transform_parent(view, NULL);
1757 }
1758 
1759 WL_EXPORT void
weston_view_set_transform_parent(struct weston_view * view,struct weston_view * parent)1760 weston_view_set_transform_parent(struct weston_view *view,
1761 				 struct weston_view *parent)
1762 {
1763 	if (view->geometry.parent) {
1764 		wl_list_remove(&view->geometry.parent_destroy_listener.link);
1765 		wl_list_remove(&view->geometry.parent_link);
1766 
1767 		if (!parent)
1768 			view->geometry.scissor_enabled = false;
1769 	}
1770 
1771 	view->geometry.parent = parent;
1772 
1773 	view->geometry.parent_destroy_listener.notify =
1774 		transform_parent_handle_parent_destroy;
1775 	if (parent) {
1776 		wl_signal_add(&parent->destroy_signal,
1777 			      &view->geometry.parent_destroy_listener);
1778 		wl_list_insert(&parent->geometry.child_list,
1779 			       &view->geometry.parent_link);
1780 	}
1781 
1782 	weston_view_geometry_dirty(view);
1783 }
1784 
1785 /** Set a clip mask rectangle on a view
1786  *
1787  * \param view The view to set the clip mask on.
1788  * \param x Top-left corner X coordinate of the clip rectangle.
1789  * \param y Top-left corner Y coordinate of the clip rectangle.
1790  * \param width Width of the clip rectangle, non-negative.
1791  * \param height Height of the clip rectangle, non-negative.
1792  *
1793  * A shell may set a clip mask rectangle on a view. Everything outside
1794  * the rectangle is cut away for input and output purposes: it is
1795  * not drawn and cannot be hit by hit-test based input like pointer
1796  * motion or touch-downs. Everything inside the rectangle will behave
1797  * normally. Clients are unaware of clipping.
1798  *
1799  * The rectangle is set in surface-local coordinates. Setting a clip
1800  * mask rectangle does not affect the view position, the view is positioned
1801  * as it would be without a clip. The clip also does not change
1802  * weston_surface::width,height.
1803  *
1804  * The clip mask rectangle is part of transformation inheritance
1805  * (weston_view_set_transform_parent()). A clip set in the root of the
1806  * transformation inheritance tree will affect all views in the tree.
1807  * A clip can be set only on the root view. Attempting to set a clip
1808  * on view that has a transformation parent will fail. Assigning a parent
1809  * to a view that has a clip set will cause the clip to be forgotten.
1810  *
1811  * Because the clip mask is an axis-aligned rectangle, it poses restrictions
1812  * on the additional transformations in the child views. These transformations
1813  * may not rotate the coordinate axes, i.e., only translation and scaling
1814  * are allowed. Violating this restriction causes the clipping to malfunction.
1815  * Furthermore, using scaling may cause rounding errors in child clipping.
1816  *
1817  * The clip mask rectangle is not automatically adjusted based on
1818  * wl_surface.attach dx and dy arguments.
1819  *
1820  * A clip mask rectangle can be set only if the compositor capability
1821  * WESTON_CAP_VIEW_CLIP_MASK is present.
1822  *
1823  * This function sets the clip mask rectangle and schedules a repaint for
1824  * the view.
1825  */
1826 WL_EXPORT void
weston_view_set_mask(struct weston_view * view,int x,int y,int width,int height)1827 weston_view_set_mask(struct weston_view *view,
1828 		     int x, int y, int width, int height)
1829 {
1830 	struct weston_compositor *compositor = view->surface->compositor;
1831 
1832 	if (!(compositor->capabilities & WESTON_CAP_VIEW_CLIP_MASK)) {
1833 		weston_log("%s not allowed without capability!\n", __func__);
1834 		return;
1835 	}
1836 
1837 	if (view->geometry.parent) {
1838 		weston_log("view %p has a parent, clip forbidden!\n", view);
1839 		return;
1840 	}
1841 
1842 	if (width < 0 || height < 0) {
1843 		weston_log("%s: illegal args %d, %d, %d, %d\n", __func__,
1844 			   x, y, width, height);
1845 		return;
1846 	}
1847 
1848 	pixman_region32_fini(&view->geometry.scissor);
1849 	pixman_region32_init_rect(&view->geometry.scissor, x, y, width, height);
1850 	view->geometry.scissor_enabled = true;
1851 	weston_view_geometry_dirty(view);
1852 	weston_view_schedule_repaint(view);
1853 }
1854 
1855 /** Remove the clip mask from a view
1856  *
1857  * \param view The view to remove the clip mask from.
1858  *
1859  * Removed the clip mask rectangle and schedules a repaint.
1860  *
1861  * \sa weston_view_set_mask
1862  */
1863 WL_EXPORT void
weston_view_set_mask_infinite(struct weston_view * view)1864 weston_view_set_mask_infinite(struct weston_view *view)
1865 {
1866 	view->geometry.scissor_enabled = false;
1867 	weston_view_geometry_dirty(view);
1868 	weston_view_schedule_repaint(view);
1869 }
1870 
1871 /* Check if view should be displayed
1872  *
1873  * The indicator is set manually when assigning
1874  * a view to a surface.
1875  *
1876  * This needs reworking. See the thread starting at:
1877  *
1878  * https://lists.freedesktop.org/archives/wayland-devel/2016-June/029656.html
1879  */
1880 WL_EXPORT bool
weston_view_is_mapped(struct weston_view * view)1881 weston_view_is_mapped(struct weston_view *view)
1882 {
1883 	return view->is_mapped;
1884 }
1885 
1886 /* Check if view is opaque in specified region
1887  *
1888  * \param view The view to check for opacity.
1889  * \param region The region to check for opacity, in view coordinates.
1890  *
1891  * Returns true if the view is opaque in the specified region, because view
1892  * alpha is 1.0 and either the opaque region set by the client contains the
1893  * specified region, or the buffer pixel format or solid color is opaque.
1894  */
1895 WL_EXPORT bool
weston_view_is_opaque(struct weston_view * ev,pixman_region32_t * region)1896 weston_view_is_opaque(struct weston_view *ev, pixman_region32_t *region)
1897 {
1898 	pixman_region32_t r;
1899 	bool ret = false;
1900 
1901 	if (ev->alpha < 1.0)
1902 		return false;
1903 
1904 	if (ev->surface->is_opaque)
1905 		return true;
1906 
1907 	if (ev->transform.dirty)
1908 		return false;
1909 
1910 	pixman_region32_init(&r);
1911 	pixman_region32_subtract(&r, region, &ev->transform.opaque);
1912 
1913 	if (!pixman_region32_not_empty(&r))
1914 		ret = true;
1915 
1916 	pixman_region32_fini(&r);
1917 
1918 	return ret;
1919 }
1920 
1921 /** Check if the view has a valid buffer available
1922  *
1923  * @param ev The view to check if it has a valid buffer.
1924  *
1925  * Returns true if the view has a valid buffer or false otherwise.
1926  */
1927 WL_EXPORT bool
weston_view_has_valid_buffer(struct weston_view * ev)1928 weston_view_has_valid_buffer(struct weston_view *ev)
1929 {
1930 	return ev->surface->buffer_ref.buffer != NULL;
1931 }
1932 
1933 /** Check if the view matches the entire output
1934  *
1935  * @param ev The view to check.
1936  * @param output The output to check against.
1937  *
1938  * Returns true if the view does indeed matches the entire output.
1939  */
1940 WL_EXPORT bool
weston_view_matches_output_entirely(struct weston_view * ev,struct weston_output * output)1941 weston_view_matches_output_entirely(struct weston_view *ev,
1942 				    struct weston_output *output)
1943 {
1944 	pixman_box32_t *extents =
1945 		pixman_region32_extents(&ev->transform.boundingbox);
1946 
1947 	if (extents->x1 != output->x ||
1948 	    extents->y1 != output->y ||
1949 	    extents->x2 != output->x + output->width ||
1950 	    extents->y2 != output->y + output->height)
1951 		return false;
1952 
1953 	return true;
1954 }
1955 
1956 /* Check if a surface has a view assigned to it
1957  *
1958  * The indicator is set manually when mapping
1959  * a surface and creating a view for it.
1960  *
1961  * This needs to go. See the thread starting at:
1962  *
1963  * https://lists.freedesktop.org/archives/wayland-devel/2016-June/029656.html
1964  *
1965  */
1966 WL_EXPORT bool
weston_surface_is_mapped(struct weston_surface * surface)1967 weston_surface_is_mapped(struct weston_surface *surface)
1968 {
1969 	return surface->is_mapped;
1970 }
1971 
1972 static void
surface_set_size(struct weston_surface * surface,int32_t width,int32_t height)1973 surface_set_size(struct weston_surface *surface, int32_t width, int32_t height)
1974 {
1975     LOG_INFO("set width = %d, height = %d", width, height);
1976 	struct weston_view *view;
1977 
1978 	if (surface->width == width && surface->height == height)
1979 		return;
1980 
1981 	surface->width = width;
1982 	surface->height = height;
1983 
1984 	wl_list_for_each(view, &surface->views, surface_link)
1985 		weston_view_geometry_dirty(view);
1986 }
1987 
1988 WL_EXPORT void
weston_surface_set_size(struct weston_surface * surface,int32_t width,int32_t height)1989 weston_surface_set_size(struct weston_surface *surface,
1990 			int32_t width, int32_t height)
1991 {
1992 	assert(!surface->resource);
1993 	surface_set_size(surface, width, height);
1994 }
1995 
1996 static int
fixed_round_up_to_int(wl_fixed_t f)1997 fixed_round_up_to_int(wl_fixed_t f)
1998 {
1999 	return wl_fixed_to_int(wl_fixed_from_int(1) - 1 + f);
2000 }
2001 
2002 static void
convert_size_by_transform_scale(int32_t * width_out,int32_t * height_out,int32_t width,int32_t height,uint32_t transform,int32_t scale)2003 convert_size_by_transform_scale(int32_t *width_out, int32_t *height_out,
2004 				int32_t width, int32_t height,
2005 				uint32_t transform,
2006 				int32_t scale)
2007 {
2008 	assert(scale > 0);
2009 
2010 	switch (transform) {
2011 	case WL_OUTPUT_TRANSFORM_NORMAL:
2012 	case WL_OUTPUT_TRANSFORM_180:
2013 	case WL_OUTPUT_TRANSFORM_FLIPPED:
2014 	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
2015 		*width_out = width / scale;
2016 		*height_out = height / scale;
2017 		break;
2018 	case WL_OUTPUT_TRANSFORM_90:
2019 	case WL_OUTPUT_TRANSFORM_270:
2020 	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
2021 	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
2022 		*width_out = height / scale;
2023 		*height_out = width / scale;
2024 		break;
2025 	default:
2026 		assert(0 && "invalid transform");
2027 	}
2028 }
2029 
2030 static void
weston_surface_calculate_size_from_buffer(struct weston_surface * surface)2031 weston_surface_calculate_size_from_buffer(struct weston_surface *surface)
2032 {
2033 	struct weston_buffer_viewport *vp = &surface->buffer_viewport;
2034 
2035 	if (!surface->buffer_ref.buffer) {
2036 		surface->width_from_buffer = 0;
2037 		surface->height_from_buffer = 0;
2038 		return;
2039 	}
2040 
2041 	convert_size_by_transform_scale(&surface->width_from_buffer,
2042 					&surface->height_from_buffer,
2043 					surface->buffer_ref.buffer->width,
2044 					surface->buffer_ref.buffer->height,
2045 					vp->buffer.transform,
2046 					vp->buffer.scale);
2047 }
2048 
2049 static void
weston_surface_update_size(struct weston_surface * surface)2050 weston_surface_update_size(struct weston_surface *surface)
2051 {
2052 	struct weston_buffer_viewport *vp = &surface->buffer_viewport;
2053 	int32_t width, height;
2054 
2055     LOG_INFO("from buffer, width = %d, height = %d",
2056              surface->width_from_buffer, surface->height_from_buffer);
2057 
2058     LOG_INFO("vp->surface, width = %d, height = %d",
2059              vp->surface.width, vp->surface.height);
2060 
2061 	width = surface->width_from_buffer;
2062 	height = surface->height_from_buffer;
2063 
2064 	if (width != 0 && vp->surface.width != -1) {
2065 		surface_set_size(surface,
2066 				 vp->surface.width, vp->surface.height);
2067 		return;
2068 	}
2069 
2070 	if (width != 0 && vp->buffer.src_width != wl_fixed_from_int(-1)) {
2071 		int32_t w = fixed_round_up_to_int(vp->buffer.src_width);
2072 		int32_t h = fixed_round_up_to_int(vp->buffer.src_height);
2073 
2074 		surface_set_size(surface, w ?: 1, h ?: 1);
2075 		return;
2076 	}
2077 
2078 	surface_set_size(surface, width, height);
2079 }
2080 
2081 /** weston_compositor_get_time
2082  * \ingroup compositor
2083  */
2084 WL_EXPORT void
weston_compositor_get_time(struct timespec * time)2085 weston_compositor_get_time(struct timespec *time)
2086 {
2087 	clock_gettime(CLOCK_REALTIME, time);
2088 }
2089 
2090 /** weston_compositor_pick_view
2091  * \ingroup compositor
2092  */
2093 WL_EXPORT struct weston_view *
weston_compositor_pick_view(struct weston_compositor * compositor,wl_fixed_t x,wl_fixed_t y,wl_fixed_t * vx,wl_fixed_t * vy)2094 weston_compositor_pick_view(struct weston_compositor *compositor,
2095 			    wl_fixed_t x, wl_fixed_t y,
2096 			    wl_fixed_t *vx, wl_fixed_t *vy)
2097 {
2098 	struct weston_view *view;
2099 	wl_fixed_t view_x, view_y;
2100 	int view_ix, view_iy;
2101 	int ix = wl_fixed_to_int(x);
2102 	int iy = wl_fixed_to_int(y);
2103 
2104 	wl_list_for_each(view, &compositor->view_list, link) {
2105 		if (!pixman_region32_contains_point(
2106 				&view->transform.boundingbox, ix, iy, NULL))
2107 			continue;
2108 
2109 		weston_view_from_global_fixed(view, x, y, &view_x, &view_y);
2110 		view_ix = wl_fixed_to_int(view_x);
2111 		view_iy = wl_fixed_to_int(view_y);
2112 
2113 		if (!pixman_region32_contains_point(&view->surface->input,
2114 						    view_ix, view_iy, NULL))
2115 			continue;
2116 
2117 		if (view->geometry.scissor_enabled &&
2118 		    !pixman_region32_contains_point(&view->geometry.scissor,
2119 						    view_ix, view_iy, NULL))
2120 			continue;
2121 
2122 		*vx = view_x;
2123 		*vy = view_y;
2124 		return view;
2125 	}
2126 
2127 	*vx = wl_fixed_from_int(-1000000);
2128 	*vy = wl_fixed_from_int(-1000000);
2129 	return NULL;
2130 }
2131 
2132 static void
weston_compositor_repick(struct weston_compositor * compositor)2133 weston_compositor_repick(struct weston_compositor *compositor)
2134 {
2135 	struct weston_seat *seat;
2136 
2137 	if (!compositor->session_active)
2138 		return;
2139 
2140 	wl_list_for_each(seat, &compositor->seat_list, link)
2141 		weston_seat_repick(seat);
2142 }
2143 
2144 WL_EXPORT void
weston_view_unmap(struct weston_view * view)2145 weston_view_unmap(struct weston_view *view)
2146 {
2147 	struct weston_seat *seat;
2148 
2149 	if (!weston_view_is_mapped(view))
2150 		return;
2151 
2152 	weston_view_damage_below(view);
2153 	weston_view_set_output(view, NULL);
2154 	view->plane = NULL;
2155 	view->is_mapped = false;
2156 	weston_layer_entry_remove(&view->layer_link);
2157 	wl_list_remove(&view->link);
2158 	wl_list_init(&view->link);
2159 	view->output_mask = 0;
2160 	weston_surface_assign_output(view->surface);
2161 
2162 	if (weston_surface_is_mapped(view->surface))
2163 		return;
2164 
2165 	wl_list_for_each(seat, &view->surface->compositor->seat_list, link) {
2166 		struct weston_touch *touch = weston_seat_get_touch(seat);
2167 		struct weston_pointer *pointer = weston_seat_get_pointer(seat);
2168 		struct weston_keyboard *keyboard =
2169 			weston_seat_get_keyboard(seat);
2170 
2171 		if (keyboard && keyboard->focus == view->surface)
2172 			weston_keyboard_set_focus(keyboard, NULL);
2173 		if (pointer && pointer->focus == view)
2174 			weston_pointer_clear_focus(pointer);
2175 		if (touch && touch->focus == view)
2176 			weston_touch_set_focus(touch, NULL);
2177 	}
2178 }
2179 
2180 WL_EXPORT void
weston_surface_unmap(struct weston_surface * surface)2181 weston_surface_unmap(struct weston_surface *surface)
2182 {
2183 	struct weston_view *view;
2184 
2185 	surface->is_mapped = false;
2186 	wl_list_for_each(view, &surface->views, surface_link)
2187 		weston_view_unmap(view);
2188 	surface->output = NULL;
2189 }
2190 
2191 static void
weston_surface_reset_pending_buffer(struct weston_surface * surface)2192 weston_surface_reset_pending_buffer(struct weston_surface *surface)
2193 {
2194 	weston_surface_state_set_buffer(&surface->pending, NULL);
2195 	surface->pending.sx = 0;
2196 	surface->pending.sy = 0;
2197 	surface->pending.newly_attached = 0;
2198 	surface->pending.buffer_viewport.changed = 0;
2199 }
2200 
2201 WL_EXPORT void
weston_view_destroy(struct weston_view * view)2202 weston_view_destroy(struct weston_view *view)
2203 {
2204 	wl_signal_emit(&view->destroy_signal, view);
2205 
2206 	assert(wl_list_empty(&view->geometry.child_list));
2207 
2208 	if (weston_view_is_mapped(view)) {
2209 		weston_view_unmap(view);
2210 		weston_compositor_build_view_list(view->surface->compositor);
2211 	}
2212 
2213 	wl_list_remove(&view->link);
2214 	weston_layer_entry_remove(&view->layer_link);
2215 
2216 	pixman_region32_fini(&view->clip);
2217 	pixman_region32_fini(&view->geometry.scissor);
2218 	pixman_region32_fini(&view->transform.boundingbox);
2219 	pixman_region32_fini(&view->transform.opaque);
2220 
2221 	weston_view_set_transform_parent(view, NULL);
2222 	weston_view_set_output(view, NULL);
2223 
2224 	wl_list_remove(&view->surface_link);
2225 
2226 	free(view);
2227 }
2228 
2229 WL_EXPORT void
weston_surface_destroy(struct weston_surface * surface)2230 weston_surface_destroy(struct weston_surface *surface)
2231 {
2232 	struct weston_frame_callback *cb, *next;
2233 	struct weston_view *ev, *nv;
2234 	struct weston_pointer_constraint *constraint, *next_constraint;
2235 
2236 	if (--surface->ref_count > 0)
2237 		return;
2238 
2239 	assert(surface->resource == NULL);
2240 
2241 	wl_signal_emit(&surface->destroy_signal, surface);
2242 
2243 	assert(wl_list_empty(&surface->subsurface_list_pending));
2244 	assert(wl_list_empty(&surface->subsurface_list));
2245 
2246 	wl_list_for_each_safe(ev, nv, &surface->views, surface_link)
2247 		weston_view_destroy(ev);
2248 
2249 	weston_surface_state_fini(&surface->pending);
2250 
2251 	weston_buffer_reference(&surface->buffer_ref, NULL);
2252 	weston_buffer_release_reference(&surface->buffer_release_ref, NULL);
2253 
2254 	pixman_region32_fini(&surface->damage);
2255 	pixman_region32_fini(&surface->opaque);
2256 	pixman_region32_fini(&surface->input);
2257 
2258 	wl_list_for_each_safe(cb, next, &surface->frame_callback_list, link)
2259 		wl_resource_destroy(cb->resource);
2260 
2261 	weston_presentation_feedback_discard_list(&surface->feedback_list);
2262 
2263 	wl_list_for_each_safe(constraint, next_constraint,
2264 			      &surface->pointer_constraints,
2265 			      link)
2266 		weston_pointer_constraint_destroy(constraint);
2267 
2268 	fd_clear(&surface->acquire_fence_fd);
2269 
2270 	free(surface);
2271 }
2272 
2273 static void
destroy_surface(struct wl_resource * resource)2274 destroy_surface(struct wl_resource *resource)
2275 {
2276 	struct weston_surface *surface = wl_resource_get_user_data(resource);
2277 
2278 	assert(surface);
2279 
2280 	/* Set the resource to NULL, since we don't want to leave a
2281 	 * dangling pointer if the surface was refcounted and survives
2282 	 * the weston_surface_destroy() call. */
2283 	surface->resource = NULL;
2284 
2285 	if (surface->viewport_resource)
2286 		wl_resource_set_user_data(surface->viewport_resource, NULL);
2287 
2288 	if (surface->synchronization_resource) {
2289 		wl_resource_set_user_data(surface->synchronization_resource,
2290 					  NULL);
2291 	}
2292 
2293 	weston_surface_destroy(surface);
2294 }
2295 
2296 static void
weston_buffer_destroy_handler(struct wl_listener * listener,void * data)2297 weston_buffer_destroy_handler(struct wl_listener *listener, void *data)
2298 {
2299 	struct weston_buffer *buffer =
2300 		container_of(listener, struct weston_buffer, destroy_listener);
2301 
2302 	wl_signal_emit(&buffer->destroy_signal, buffer);
2303 	free(buffer);
2304 }
2305 
2306 WL_EXPORT struct weston_buffer *
weston_buffer_from_resource(struct wl_resource * resource)2307 weston_buffer_from_resource(struct wl_resource *resource)
2308 {
2309 	struct weston_buffer *buffer;
2310 	struct wl_listener *listener;
2311 
2312 	listener = wl_resource_get_destroy_listener(resource,
2313 						    weston_buffer_destroy_handler);
2314 
2315 	if (listener)
2316 		return container_of(listener, struct weston_buffer,
2317 				    destroy_listener);
2318 
2319 	buffer = zalloc(sizeof *buffer);
2320 	if (buffer == NULL)
2321 		return NULL;
2322 
2323 	buffer->resource = resource;
2324 	wl_signal_init(&buffer->destroy_signal);
2325 	buffer->destroy_listener.notify = weston_buffer_destroy_handler;
2326 	buffer->y_inverted = 1;
2327 	wl_resource_add_destroy_listener(resource, &buffer->destroy_listener);
2328 
2329 	return buffer;
2330 }
2331 
2332 static void
weston_buffer_reference_handle_destroy(struct wl_listener * listener,void * data)2333 weston_buffer_reference_handle_destroy(struct wl_listener *listener,
2334 				       void *data)
2335 {
2336 	struct weston_buffer_reference *ref =
2337 		container_of(listener, struct weston_buffer_reference,
2338 			     destroy_listener);
2339 
2340 	assert((struct weston_buffer *)data == ref->buffer);
2341 	ref->buffer = NULL;
2342 }
2343 
2344 WL_EXPORT void
weston_buffer_reference(struct weston_buffer_reference * ref,struct weston_buffer * buffer)2345 weston_buffer_reference(struct weston_buffer_reference *ref,
2346 			struct weston_buffer *buffer)
2347 {
2348 	if (ref->buffer && buffer != ref->buffer) {
2349 		ref->buffer->busy_count--;
2350 		if (ref->buffer->busy_count == 0) {
2351 			assert(wl_resource_get_client(ref->buffer->resource));
2352 			wl_buffer_send_release(ref->buffer->resource);
2353 		}
2354 		wl_list_remove(&ref->destroy_listener.link);
2355 	}
2356 
2357 	if (buffer && buffer != ref->buffer) {
2358 		buffer->busy_count++;
2359 		wl_signal_add(&buffer->destroy_signal,
2360 			      &ref->destroy_listener);
2361 	}
2362 
2363 	ref->buffer = buffer;
2364 	ref->destroy_listener.notify = weston_buffer_reference_handle_destroy;
2365 }
2366 
2367 static void
weston_buffer_release_reference_handle_destroy(struct wl_listener * listener,void * data)2368 weston_buffer_release_reference_handle_destroy(struct wl_listener *listener,
2369 					       void *data)
2370 {
2371 	struct weston_buffer_release_reference *ref =
2372 		container_of(listener, struct weston_buffer_release_reference,
2373 			     destroy_listener);
2374 
2375 	assert((struct wl_resource *)data == ref->buffer_release->resource);
2376 	ref->buffer_release = NULL;
2377 }
2378 
2379 static void
weston_buffer_release_destroy(struct weston_buffer_release * buffer_release)2380 weston_buffer_release_destroy(struct weston_buffer_release *buffer_release)
2381 {
2382 	struct wl_resource *resource = buffer_release->resource;
2383 	int release_fence_fd = buffer_release->fence_fd;
2384 
2385 	if (release_fence_fd >= 0) {
2386 		zwp_linux_buffer_release_v1_send_fenced_release(
2387 			resource, release_fence_fd);
2388 	} else {
2389 		zwp_linux_buffer_release_v1_send_immediate_release(
2390 			resource);
2391 	}
2392 
2393 	wl_resource_destroy(resource);
2394 }
2395 
2396 WL_EXPORT void
weston_buffer_release_reference(struct weston_buffer_release_reference * ref,struct weston_buffer_release * buffer_release)2397 weston_buffer_release_reference(struct weston_buffer_release_reference *ref,
2398 				struct weston_buffer_release *buffer_release)
2399 {
2400 	if (buffer_release == ref->buffer_release)
2401 		return;
2402 
2403 	if (ref->buffer_release) {
2404 		ref->buffer_release->ref_count--;
2405 		wl_list_remove(&ref->destroy_listener.link);
2406 		if (ref->buffer_release->ref_count == 0)
2407 			weston_buffer_release_destroy(ref->buffer_release);
2408 	}
2409 
2410 	if (buffer_release) {
2411 		buffer_release->ref_count++;
2412 		wl_resource_add_destroy_listener(buffer_release->resource,
2413 						 &ref->destroy_listener);
2414 	}
2415 
2416 	ref->buffer_release = buffer_release;
2417 	ref->destroy_listener.notify =
2418 		weston_buffer_release_reference_handle_destroy;
2419 }
2420 
2421 WL_EXPORT void
weston_buffer_release_move(struct weston_buffer_release_reference * dest,struct weston_buffer_release_reference * src)2422 weston_buffer_release_move(struct weston_buffer_release_reference *dest,
2423 			   struct weston_buffer_release_reference *src)
2424 {
2425 	weston_buffer_release_reference(dest, src->buffer_release);
2426 	weston_buffer_release_reference(src, NULL);
2427 }
2428 
2429 static void
weston_surface_attach(struct weston_surface * surface,struct weston_buffer * buffer)2430 weston_surface_attach(struct weston_surface *surface,
2431 		      struct weston_buffer *buffer)
2432 {
2433 	weston_buffer_reference(&surface->buffer_ref, buffer);
2434 
2435 	if (!buffer) {
2436 		if (weston_surface_is_mapped(surface))
2437 			weston_surface_unmap(surface);
2438 	}
2439 
2440 	surface->compositor->renderer->attach(surface, buffer);
2441 
2442 	weston_surface_calculate_size_from_buffer(surface);
2443 	weston_presentation_feedback_discard_list(&surface->feedback_list);
2444 }
2445 
2446 /** weston_compositor_damage_all
2447  * \ingroup compositor
2448  */
2449 WL_EXPORT void
weston_compositor_damage_all(struct weston_compositor * compositor)2450 weston_compositor_damage_all(struct weston_compositor *compositor)
2451 {
2452 	struct weston_output *output;
2453 
2454 	wl_list_for_each(output, &compositor->output_list, link)
2455 		weston_output_damage(output);
2456 }
2457 
2458 /**
2459  * \ingroup output
2460  */
2461 WL_EXPORT void
weston_output_damage(struct weston_output * output)2462 weston_output_damage(struct weston_output *output)
2463 {
2464 	struct weston_compositor *compositor = output->compositor;
2465 
2466 	pixman_region32_union(&compositor->primary_plane.damage,
2467 			      &compositor->primary_plane.damage,
2468 			      &output->region);
2469 	weston_output_schedule_repaint(output);
2470 }
2471 
2472 static void
surface_flush_damage(struct weston_surface * surface)2473 surface_flush_damage(struct weston_surface *surface)
2474 {
2475 	if (surface->buffer_ref.buffer &&
2476 	    wl_shm_buffer_get(surface->buffer_ref.buffer->resource))
2477 		surface->compositor->renderer->flush_damage(surface);
2478 
2479 // OHOS remove timeline
2480 //	if (pixman_region32_not_empty(&surface->damage))
2481 //		TL_POINT(surface->compositor, "core_flush_damage", TLP_SURFACE(surface),
2482 //			 TLP_OUTPUT(surface->output), TLP_END);
2483 
2484 	pixman_region32_clear(&surface->damage);
2485 }
2486 
2487 static void
view_accumulate_damage(struct weston_view * view,pixman_region32_t * opaque)2488 view_accumulate_damage(struct weston_view *view,
2489 		       pixman_region32_t *opaque)
2490 {
2491 	pixman_region32_t damage;
2492 
2493 	pixman_region32_init(&damage);
2494 	if (view->transform.enabled) {
2495 		pixman_box32_t *extents;
2496 
2497 		extents = pixman_region32_extents(&view->surface->damage);
2498 		view_compute_bbox(view, extents, &damage);
2499 	} else {
2500 		pixman_region32_copy(&damage, &view->surface->damage);
2501 		pixman_region32_translate(&damage,
2502 					  view->geometry.x, view->geometry.y);
2503 	}
2504 
2505 	pixman_region32_intersect(&damage, &damage,
2506 				  &view->transform.boundingbox);
2507 	pixman_region32_subtract(&damage, &damage, opaque);
2508 	pixman_region32_union(&view->plane->damage,
2509 			      &view->plane->damage, &damage);
2510 	pixman_region32_fini(&damage);
2511 	pixman_region32_copy(&view->clip, opaque);
2512 	pixman_region32_union(opaque, opaque, &view->transform.opaque);
2513 }
2514 
2515 static void
output_accumulate_damage(struct weston_output * output)2516 output_accumulate_damage(struct weston_output *output)
2517 {
2518 	struct weston_compositor *ec = output->compositor;
2519 	struct weston_plane *plane;
2520 	struct weston_view *ev;
2521 	pixman_region32_t opaque, clip;
2522 
2523 	pixman_region32_init(&clip);
2524 
2525 	wl_list_for_each(plane, &ec->plane_list, link) {
2526 		pixman_region32_copy(&plane->clip, &clip);
2527 
2528 		pixman_region32_init(&opaque);
2529 
2530 		wl_list_for_each(ev, &ec->view_list, link) {
2531 			if (ev->plane != plane)
2532 				continue;
2533 
2534 			view_accumulate_damage(ev, &opaque);
2535 		}
2536 
2537 		pixman_region32_union(&clip, &clip, &opaque);
2538 		pixman_region32_fini(&opaque);
2539 	}
2540 
2541 	pixman_region32_fini(&clip);
2542 
2543 	wl_list_for_each(ev, &ec->view_list, link)
2544 		ev->surface->touched = false;
2545 
2546 	wl_list_for_each(ev, &ec->view_list, link) {
2547 		/* Ignore views not visible on the current output */
2548 		if (!(ev->output_mask & (1u << output->id)))
2549 			continue;
2550 		if (ev->surface->touched)
2551 			continue;
2552 		ev->surface->touched = true;
2553 
2554 		surface_flush_damage(ev->surface);
2555 
2556 		/* Both the renderer and the backend have seen the buffer
2557 		 * by now. If renderer needs the buffer, it has its own
2558 		 * reference set. If the backend wants to keep the buffer
2559 		 * around for migrating the surface into a non-primary plane
2560 		 * later, keep_buffer is true. Otherwise, drop the core
2561 		 * reference now, and allow early buffer release. This enables
2562 		 * clients to use single-buffering.
2563 		 */
2564 		if (!ev->surface->keep_buffer) {
2565 			weston_buffer_reference(&ev->surface->buffer_ref, NULL);
2566 			weston_buffer_release_reference(
2567 				&ev->surface->buffer_release_ref, NULL);
2568 		}
2569 	}
2570 }
2571 
2572 static void
surface_stash_subsurface_views(struct weston_surface * surface)2573 surface_stash_subsurface_views(struct weston_surface *surface)
2574 {
2575 	struct weston_subsurface *sub;
2576 
2577 	wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
2578 		if (sub->surface == surface)
2579 			continue;
2580 
2581 		wl_list_insert_list(&sub->unused_views, &sub->surface->views);
2582 		wl_list_init(&sub->surface->views);
2583 
2584 		surface_stash_subsurface_views(sub->surface);
2585 	}
2586 }
2587 
2588 static void
surface_free_unused_subsurface_views(struct weston_surface * surface)2589 surface_free_unused_subsurface_views(struct weston_surface *surface)
2590 {
2591 	struct weston_subsurface *sub;
2592 	struct weston_view *view, *nv;
2593 
2594 	wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
2595 		if (sub->surface == surface)
2596 			continue;
2597 
2598 		wl_list_for_each_safe(view, nv, &sub->unused_views, surface_link) {
2599 			weston_view_unmap (view);
2600 			weston_view_destroy(view);
2601 		}
2602 
2603 		surface_free_unused_subsurface_views(sub->surface);
2604 	}
2605 }
2606 
2607 static void
view_list_add_subsurface_view(struct weston_compositor * compositor,struct weston_subsurface * sub,struct weston_view * parent)2608 view_list_add_subsurface_view(struct weston_compositor *compositor,
2609 			      struct weston_subsurface *sub,
2610 			      struct weston_view *parent)
2611 {
2612 	struct weston_subsurface *child;
2613 	struct weston_view *view = NULL, *iv;
2614 
2615 	if (!weston_surface_is_mapped(sub->surface))
2616 		return;
2617 
2618 	wl_list_for_each(iv, &sub->unused_views, surface_link) {
2619 		if (iv->geometry.parent == parent) {
2620 			view = iv;
2621 			break;
2622 		}
2623 	}
2624 
2625 	if (view) {
2626 		/* Put it back in the surface's list of views */
2627 		wl_list_remove(&view->surface_link);
2628 		wl_list_insert(&sub->surface->views, &view->surface_link);
2629 	} else {
2630 		view = weston_view_create(sub->surface);
2631 		weston_view_set_position(view,
2632 					 sub->position.x,
2633 					 sub->position.y);
2634 		weston_view_set_transform_parent(view, parent);
2635 	}
2636 
2637 	view->parent_view = parent;
2638 	weston_view_update_transform(view);
2639 	view->is_mapped = true;
2640 
2641 	if (wl_list_empty(&sub->surface->subsurface_list)) {
2642 		wl_list_insert(compositor->view_list.prev, &view->link);
2643 		return;
2644 	}
2645 
2646 	wl_list_for_each(child, &sub->surface->subsurface_list, parent_link) {
2647 		if (child->surface == sub->surface)
2648 			wl_list_insert(compositor->view_list.prev, &view->link);
2649 		else
2650 			view_list_add_subsurface_view(compositor, child, view);
2651 	}
2652 }
2653 
2654 /* This recursively adds the sub-surfaces for a view, relying on the
2655  * sub-surface order. Thus, if a client restacks the sub-surfaces, that
2656  * change first happens to the sub-surface list, and then automatically
2657  * propagates here. See weston_surface_damage_subsurfaces() for how the
2658  * sub-surfaces receive damage when the client changes the state.
2659  */
2660 static void
view_list_add(struct weston_compositor * compositor,struct weston_view * view)2661 view_list_add(struct weston_compositor *compositor,
2662 	      struct weston_view *view)
2663 {
2664 	struct weston_subsurface *sub;
2665 
2666 	weston_view_update_transform(view);
2667 
2668 	if (wl_list_empty(&view->surface->subsurface_list)) {
2669 		wl_list_insert(compositor->view_list.prev, &view->link);
2670 		return;
2671 	}
2672 
2673 	wl_list_for_each(sub, &view->surface->subsurface_list, parent_link) {
2674 		if (sub->surface == view->surface)
2675 			wl_list_insert(compositor->view_list.prev, &view->link);
2676 		else
2677 			view_list_add_subsurface_view(compositor, sub, view);
2678 	}
2679 }
2680 
2681 static void
weston_compositor_build_view_list(struct weston_compositor * compositor)2682 weston_compositor_build_view_list(struct weston_compositor *compositor)
2683 {
2684     LOG_ENTER();
2685 	struct weston_view *view, *tmp;
2686 	struct weston_layer *layer;
2687 
2688 	wl_list_for_each(layer, &compositor->layer_list, link)
2689 		wl_list_for_each(view, &layer->view_list.link, layer_link.link)
2690 			surface_stash_subsurface_views(view->surface);
2691 
2692 	wl_list_for_each_safe(view, tmp, &compositor->view_list, link)
2693 		wl_list_init(&view->link);
2694 	wl_list_init(&compositor->view_list);
2695 
2696 	wl_list_for_each(layer, &compositor->layer_list, link) {
2697 		wl_list_for_each(view, &layer->view_list.link, layer_link.link) {
2698 			view_list_add(compositor, view);
2699 		}
2700 	}
2701 
2702 	wl_list_for_each(layer, &compositor->layer_list, link)
2703 		wl_list_for_each(view, &layer->view_list.link, layer_link.link)
2704 			surface_free_unused_subsurface_views(view->surface);
2705     LOG_EXIT();
2706 }
2707 
2708 static void
weston_output_take_feedback_list(struct weston_output * output,struct weston_surface * surface)2709 weston_output_take_feedback_list(struct weston_output *output,
2710 				 struct weston_surface *surface)
2711 {
2712 	struct weston_view *view;
2713 	struct weston_presentation_feedback *feedback;
2714 	uint32_t flags = 0xffffffff;
2715 
2716 	if (wl_list_empty(&surface->feedback_list))
2717 		return;
2718 
2719 	/* All views must have the flag for the flag to survive. */
2720 	wl_list_for_each(view, &surface->views, surface_link) {
2721 		/* ignore views that are not on this output at all */
2722 		if (view->output_mask & (1u << output->id))
2723 			flags &= view->psf_flags;
2724 	}
2725 
2726 	wl_list_for_each(feedback, &surface->feedback_list, link)
2727 		feedback->psf_flags = flags;
2728 
2729 	wl_list_insert_list(&output->feedback_list, &surface->feedback_list);
2730 	wl_list_init(&surface->feedback_list);
2731 }
2732 
2733 static int
weston_output_repaint(struct weston_output * output,void * repaint_data)2734 weston_output_repaint(struct weston_output *output, void *repaint_data)
2735 {
2736     LOG_ENTER();
2737 	struct weston_compositor *ec = output->compositor;
2738 	struct weston_view *ev;
2739 	struct weston_animation *animation, *next;
2740 	struct weston_frame_callback *cb, *cnext;
2741 	struct wl_list frame_callback_list;
2742 	pixman_region32_t output_damage;
2743 	int r;
2744 	uint32_t frame_time_msec;
2745 	enum weston_hdcp_protection highest_requested = WESTON_HDCP_DISABLE;
2746 
2747 	if (output->destroying) {
2748         LOG_EXIT();
2749 		return 0;
2750     }
2751 
2752 // OHOS remove timeline
2753 //	TL_POINT(ec, "core_repaint_begin", TLP_OUTPUT(output), TLP_END);
2754 
2755 	/* Rebuild the surface list and update surface transforms up front. */
2756 	weston_compositor_build_view_list(ec);
2757 
2758 	/* Find the highest protection desired for an output */
2759 	wl_list_for_each(ev, &ec->view_list, link) {
2760 		if (ev->surface->output_mask & (1u << output->id)) {
2761 			/*
2762 			 * The desired_protection of the output should be the
2763 			 * maximum of the desired_protection of the surfaces,
2764 			 * that are displayed on that output, to avoid
2765 			 * reducing the protection for existing surfaces.
2766 			 */
2767 			if (ev->surface->desired_protection > highest_requested)
2768 				highest_requested =
2769 						ev->surface->desired_protection;
2770 		}
2771 	}
2772 
2773 	output->desired_protection = highest_requested;
2774 
2775 	if (output->assign_planes && !output->disable_planes) {
2776 		output->assign_planes(output, repaint_data);
2777 	} else {
2778 		wl_list_for_each(ev, &ec->view_list, link) {
2779 			weston_view_move_to_plane(ev, &ec->primary_plane);
2780 			ev->psf_flags = 0;
2781 		}
2782 	}
2783 
2784 	wl_list_init(&frame_callback_list);
2785 	wl_list_for_each(ev, &ec->view_list, link) {
2786 		/* Note: This operation is safe to do multiple times on the
2787 		 * same surface.
2788 		 */
2789 		if (ev->surface->output == output) {
2790 			wl_list_insert_list(&frame_callback_list,
2791 					    &ev->surface->frame_callback_list);
2792 			wl_list_init(&ev->surface->frame_callback_list);
2793 
2794 			weston_output_take_feedback_list(output, ev->surface);
2795 		}
2796 	}
2797 
2798 	output_accumulate_damage(output);
2799 
2800 	pixman_region32_init(&output_damage);
2801 	pixman_region32_intersect(&output_damage,
2802 				  &ec->primary_plane.damage, &output->region);
2803 	pixman_region32_subtract(&output_damage,
2804 				 &output_damage, &ec->primary_plane.clip);
2805 
2806 	if (output->dirty)
2807 		weston_output_update_matrix(output);
2808 
2809 	r = output->repaint(output, &output_damage, repaint_data);
2810 
2811 	pixman_region32_fini(&output_damage);
2812 
2813 	output->repaint_needed = false;
2814 	if (r == 0)
2815 		output->repaint_status = REPAINT_AWAITING_COMPLETION;
2816 
2817 	weston_compositor_repick(ec);
2818 
2819 	frame_time_msec = timespec_to_msec(&output->frame_time);
2820 
2821 	wl_list_for_each_safe(cb, cnext, &frame_callback_list, link) {
2822 		wl_callback_send_done(cb->resource, frame_time_msec);
2823 		wl_resource_destroy(cb->resource);
2824 	}
2825 
2826 	wl_list_for_each_safe(animation, next, &output->animation_list, link) {
2827 		animation->frame_counter++;
2828 		animation->frame(animation, output, &output->frame_time);
2829 	}
2830 
2831 // OHOS remove timeline
2832 //	TL_POINT(ec, "core_repaint_posted", TLP_OUTPUT(output), TLP_END);
2833 
2834     LOG_EXIT();
2835 	return r;
2836 }
2837 
2838 static void
weston_output_schedule_repaint_reset(struct weston_output * output)2839 weston_output_schedule_repaint_reset(struct weston_output *output)
2840 {
2841 	output->repaint_status = REPAINT_NOT_SCHEDULED;
2842 // OHOS remove timeline
2843 //	TL_POINT(output->compositor, "core_repaint_exit_loop",
2844 //		 TLP_OUTPUT(output), TLP_END);
2845 }
2846 
2847 static int
weston_output_maybe_repaint(struct weston_output * output,struct timespec * now,void * repaint_data)2848 weston_output_maybe_repaint(struct weston_output *output, struct timespec *now,
2849 			    void *repaint_data)
2850 {
2851 	struct weston_compositor *compositor = output->compositor;
2852 	int ret = 0;
2853 	int64_t msec_to_repaint;
2854 
2855 	/* We're not ready yet; come back to make a decision later. */
2856 	if (output->repaint_status != REPAINT_SCHEDULED) {
2857         LOG_EXIT();
2858 		return ret;
2859     }
2860 
2861 	msec_to_repaint = timespec_sub_to_msec(&output->next_repaint, now);
2862 	if (msec_to_repaint > 1) {
2863         LOG_EXIT();
2864 		return ret;
2865     }
2866 
2867     LOG_INFO("1");
2868 	/* If we're sleeping, drop the repaint machinery entirely; we will
2869 	 * explicitly repaint all outputs when we come back. */
2870 	if (compositor->state == WESTON_COMPOSITOR_SLEEPING ||
2871 	    compositor->state == WESTON_COMPOSITOR_OFFSCREEN)
2872 		goto err;
2873 
2874     LOG_INFO("2");
2875 	/* We don't actually need to repaint this output; drop it from
2876 	 * repaint until something causes damage. */
2877 	if (!output->repaint_needed)
2878 		goto err;
2879 
2880     LOG_INFO("3");
2881 	/* If repaint fails, we aren't going to get weston_output_finish_frame
2882 	 * to trigger a new repaint, so drop it from repaint and hope
2883 	 * something schedules a successful repaint later. As repainting may
2884 	 * take some time, re-read our clock as a courtesy to the next
2885 	 * output. */
2886 	ret = weston_output_repaint(output, repaint_data);
2887 	weston_compositor_read_presentation_clock(compositor, now);
2888 	if (ret != 0)
2889 		goto err;
2890 
2891 	output->repainted = true;
2892 	return ret;
2893 
2894 err:
2895 	weston_output_schedule_repaint_reset(output);
2896 	return ret;
2897 }
2898 
2899 static void
output_repaint_timer_arm(struct weston_compositor * compositor)2900 output_repaint_timer_arm(struct weston_compositor *compositor)
2901 {
2902 	struct weston_output *output;
2903 	bool any_should_repaint = false;
2904 	struct timespec now;
2905 	int64_t msec_to_next = INT64_MAX;
2906 
2907 	weston_compositor_read_presentation_clock(compositor, &now);
2908 
2909 	wl_list_for_each(output, &compositor->output_list, link) {
2910 		int64_t msec_to_this;
2911 
2912 		if (output->repaint_status != REPAINT_SCHEDULED)
2913 			continue;
2914 
2915 		msec_to_this = timespec_sub_to_msec(&output->next_repaint,
2916 						    &now);
2917 		if (!any_should_repaint || msec_to_this < msec_to_next)
2918 			msec_to_next = msec_to_this;
2919 
2920 		any_should_repaint = true;
2921 	}
2922 
2923 	if (!any_should_repaint)
2924 		return;
2925 
2926 	/* Even if we should repaint immediately, add the minimum 1 ms delay.
2927 	 * This is a workaround to allow coalescing multiple output repaints
2928 	 * particularly from weston_output_finish_frame()
2929 	 * into the same call, which would not happen if we called
2930 	 * output_repaint_timer_handler() directly.
2931 	 */
2932 	if (msec_to_next < 1)
2933 		msec_to_next = 1;
2934 
2935 	wl_event_source_timer_update(compositor->repaint_timer, msec_to_next);
2936 }
2937 
2938 static int
output_repaint_timer_handler(void * data)2939 output_repaint_timer_handler(void *data)
2940 {
2941     LOG_ENTERS("core: repaint");
2942 	struct weston_compositor *compositor = data;
2943 	struct weston_output *output;
2944 	struct timespec now;
2945 	void *repaint_data = NULL;
2946 	int ret = 0;
2947 
2948 	weston_compositor_read_presentation_clock(compositor, &now);
2949 
2950 	if (compositor->backend->repaint_begin)
2951 		repaint_data = compositor->backend->repaint_begin(compositor);
2952 
2953 	wl_list_for_each(output, &compositor->output_list, link) {
2954 		ret = weston_output_maybe_repaint(output, &now, repaint_data);
2955 		if (ret)
2956 			break;
2957 	}
2958 
2959 	if (ret == 0) {
2960 		if (compositor->backend->repaint_flush)
2961 			ret = compositor->backend->repaint_flush(compositor,
2962 							 repaint_data);
2963 	} else {
2964 		if (compositor->backend->repaint_cancel)
2965 			compositor->backend->repaint_cancel(compositor,
2966 							    repaint_data);
2967 	}
2968 
2969 	if (ret != 0) {
2970 		wl_list_for_each(output, &compositor->output_list, link) {
2971 			if (output->repainted)
2972 				weston_output_schedule_repaint_reset(output);
2973 		}
2974 	}
2975 
2976 	wl_list_for_each(output, &compositor->output_list, link)
2977 		output->repainted = false;
2978 
2979 	output_repaint_timer_arm(compositor);
2980 
2981     LOG_EXITS("end core: repaint");
2982 	return 0;
2983 }
2984 
2985 /** Convert a presentation timestamp to another clock domain
2986  *
2987  * \param compositor The compositor defines the presentation clock domain.
2988  * \param presentation_stamp The timestamp in presentation clock domain.
2989  * \param presentation_now Current time in presentation clock domain.
2990  * \param target_clock Defines the target clock domain.
2991  *
2992  * This approximation relies on presentation_stamp to be close to current time.
2993  * The further it is from current time and the bigger the speed difference
2994  * between the two clock domains, the bigger the conversion error.
2995  *
2996  * Conversion error due to system load is biased and unbounded.
2997  */
2998 static struct timespec
convert_presentation_time_now(struct weston_compositor * compositor,const struct timespec * presentation_stamp,const struct timespec * presentation_now,clockid_t target_clock)2999 convert_presentation_time_now(struct weston_compositor *compositor,
3000 			      const struct timespec *presentation_stamp,
3001 			      const struct timespec *presentation_now,
3002 			      clockid_t target_clock)
3003 {
3004 	struct timespec target_now = {};
3005 	struct timespec target_stamp;
3006 	int64_t delta_ns;
3007 
3008 	if (compositor->presentation_clock == target_clock)
3009 		return *presentation_stamp;
3010 
3011 	clock_gettime(target_clock, &target_now);
3012 	delta_ns = timespec_sub_to_nsec(presentation_stamp, presentation_now);
3013 	timespec_add_nsec(&target_stamp, &target_now, delta_ns);
3014 
3015 	return target_stamp;
3016 }
3017 
3018 /**
3019  * \ingroup output
3020  */
3021 WL_EXPORT void
weston_output_finish_frame(struct weston_output * output,const struct timespec * stamp,uint32_t presented_flags)3022 weston_output_finish_frame(struct weston_output *output,
3023 			   const struct timespec *stamp,
3024 			   uint32_t presented_flags)
3025 {
3026 	struct weston_compositor *compositor = output->compositor;
3027 	int32_t refresh_nsec;
3028 	struct timespec now;
3029 	struct timespec vblank_monotonic;
3030 	int64_t msec_rel;
3031 
3032 	assert(output->repaint_status == REPAINT_AWAITING_COMPLETION);
3033 	assert(stamp || (presented_flags & WP_PRESENTATION_FEEDBACK_INVALID));
3034 
3035 	weston_compositor_read_presentation_clock(compositor, &now);
3036 
3037 	/* If we haven't been supplied any timestamp at all, we don't have a
3038 	 * timebase to work against, so any delay just wastes time. Push a
3039 	 * repaint as soon as possible so we can get on with it. */
3040 	if (!stamp) {
3041 		output->next_repaint = now;
3042 		goto out;
3043 	}
3044 
3045 	vblank_monotonic = convert_presentation_time_now(compositor,
3046 							 stamp, &now,
3047 							 CLOCK_MONOTONIC);
3048 // OHOS remove timeline
3049 //	TL_POINT(compositor, "core_repaint_finished", TLP_OUTPUT(output),
3050 //		 TLP_VBLANK(&vblank_monotonic), TLP_END);
3051 
3052 	refresh_nsec = millihz_to_nsec(output->current_mode->refresh);
3053 	weston_presentation_feedback_present_list(&output->feedback_list,
3054 						  output, refresh_nsec, stamp,
3055 						  output->msc,
3056 						  presented_flags);
3057 
3058 	output->frame_time = *stamp;
3059 
3060 	timespec_add_nsec(&output->next_repaint, stamp, refresh_nsec);
3061 	timespec_add_msec(&output->next_repaint, &output->next_repaint,
3062 			  -compositor->repaint_msec);
3063 	msec_rel = timespec_sub_to_msec(&output->next_repaint, &now);
3064 
3065 	if (msec_rel < -1000 || msec_rel > 1000) {
3066 		static bool warned;
3067 
3068 		if (!warned)
3069 			weston_log("Warning: computed repaint delay is "
3070 				   "insane: %lld msec\n", (long long) msec_rel);
3071 		warned = true;
3072 
3073 		output->next_repaint = now;
3074 	}
3075 
3076 	/* Called from restart_repaint_loop and restart happens already after
3077 	 * the deadline given by repaint_msec? In that case we delay until
3078 	 * the deadline of the next frame, to give clients a more predictable
3079 	 * timing of the repaint cycle to lock on. */
3080 	if (presented_flags == WP_PRESENTATION_FEEDBACK_INVALID &&
3081 	    msec_rel < 0) {
3082 		while (timespec_sub_to_nsec(&output->next_repaint, &now) < 0) {
3083 			timespec_add_nsec(&output->next_repaint,
3084 					  &output->next_repaint,
3085 					  refresh_nsec);
3086 		}
3087 	}
3088 
3089 out:
3090 	output->repaint_status = REPAINT_SCHEDULED;
3091     LOG_INFO("arm");
3092 	output_repaint_timer_arm(compositor);
3093 }
3094 
3095 static void
idle_repaint(void * data)3096 idle_repaint(void *data)
3097 {
3098     LOG_ENTERS("core: idle_repaint");
3099 	struct weston_output *output = data;
3100 	int ret;
3101 
3102 	assert(output->repaint_status == REPAINT_BEGIN_FROM_IDLE);
3103 	output->repaint_status = REPAINT_AWAITING_COMPLETION;
3104 	output->idle_repaint_source = NULL;
3105 	ret = output->start_repaint_loop(output);
3106 	if (ret != 0)
3107 		weston_output_schedule_repaint_reset(output);
3108     LOG_EXITS("end core: idle_repaint");
3109 }
3110 
3111 WL_EXPORT void
weston_layer_entry_insert(struct weston_layer_entry * list,struct weston_layer_entry * entry)3112 weston_layer_entry_insert(struct weston_layer_entry *list,
3113 			  struct weston_layer_entry *entry)
3114 {
3115 	wl_list_insert(&list->link, &entry->link);
3116 	entry->layer = list->layer;
3117 }
3118 
3119 WL_EXPORT void
weston_layer_entry_remove(struct weston_layer_entry * entry)3120 weston_layer_entry_remove(struct weston_layer_entry *entry)
3121 {
3122 	wl_list_remove(&entry->link);
3123 	wl_list_init(&entry->link);
3124 	entry->layer = NULL;
3125 }
3126 
3127 
3128 /** Initialize the weston_layer struct.
3129  *
3130  * \param compositor The compositor instance
3131  * \param layer The layer to initialize
3132  */
3133 WL_EXPORT void
weston_layer_init(struct weston_layer * layer,struct weston_compositor * compositor)3134 weston_layer_init(struct weston_layer *layer,
3135 		  struct weston_compositor *compositor)
3136 {
3137 	layer->compositor = compositor;
3138 	wl_list_init(&layer->link);
3139 	wl_list_init(&layer->view_list.link);
3140 	layer->view_list.layer = layer;
3141 	weston_layer_set_mask_infinite(layer);
3142 }
3143 
3144 /** Sets the position of the layer in the layer list. The layer will be placed
3145  * below any layer with the same position value, if any.
3146  * This function is safe to call if the layer is already on the list, but the
3147  * layer may be moved below other layers at the same position, if any.
3148  *
3149  * \param layer The layer to modify
3150  * \param position The position the layer will be placed at
3151  */
3152 WL_EXPORT void
weston_layer_set_position(struct weston_layer * layer,enum weston_layer_position position)3153 weston_layer_set_position(struct weston_layer *layer,
3154 			  enum weston_layer_position position)
3155 {
3156 	struct weston_layer *below;
3157 
3158 	wl_list_remove(&layer->link);
3159 
3160 	/* layer_list is ordered from top to bottom, the last layer being the
3161 	 * background with the smallest position value */
3162 
3163 	layer->position = position;
3164 	wl_list_for_each_reverse(below, &layer->compositor->layer_list, link) {
3165 		if (below->position >= layer->position) {
3166 			wl_list_insert(&below->link, &layer->link);
3167 			return;
3168 		}
3169 	}
3170 	wl_list_insert(&layer->compositor->layer_list, &layer->link);
3171 }
3172 
3173 /** Hide a layer by taking it off the layer list.
3174  * This function is safe to call if the layer is not on the list.
3175  *
3176  * \param layer The layer to hide
3177  */
3178 WL_EXPORT void
weston_layer_unset_position(struct weston_layer * layer)3179 weston_layer_unset_position(struct weston_layer *layer)
3180 {
3181 	wl_list_remove(&layer->link);
3182 	wl_list_init(&layer->link);
3183 }
3184 
3185 WL_EXPORT void
weston_layer_set_mask(struct weston_layer * layer,int x,int y,int width,int height)3186 weston_layer_set_mask(struct weston_layer *layer,
3187 		      int x, int y, int width, int height)
3188 {
3189 	struct weston_view *view;
3190 
3191 	layer->mask.x1 = x;
3192 	layer->mask.x2 = x + width;
3193 	layer->mask.y1 = y;
3194 	layer->mask.y2 = y + height;
3195 
3196 	wl_list_for_each(view, &layer->view_list.link, layer_link.link) {
3197 		weston_view_geometry_dirty(view);
3198 	}
3199 }
3200 
3201 WL_EXPORT void
weston_layer_set_mask_infinite(struct weston_layer * layer)3202 weston_layer_set_mask_infinite(struct weston_layer *layer)
3203 {
3204 	struct weston_view *view;
3205 
3206 	layer->mask.x1 = INT32_MIN;
3207 	layer->mask.x2 = INT32_MAX;
3208 	layer->mask.y1 = INT32_MIN;
3209 	layer->mask.y2 = INT32_MAX;
3210 
3211 	wl_list_for_each(view, &layer->view_list.link, layer_link.link) {
3212 		weston_view_geometry_dirty(view);
3213 	}
3214 }
3215 
3216 WL_EXPORT bool
weston_layer_mask_is_infinite(struct weston_layer * layer)3217 weston_layer_mask_is_infinite(struct weston_layer *layer)
3218 {
3219 	return layer->mask.x1 == INT32_MIN &&
3220 	       layer->mask.y1 == INT32_MIN &&
3221 	       layer->mask.x2 == INT32_MAX &&
3222 	       layer->mask.y2 == INT32_MAX;
3223 }
3224 
3225 /**
3226  * \ingroup output
3227  */
3228 WL_EXPORT void
weston_output_schedule_repaint(struct weston_output * output)3229 weston_output_schedule_repaint(struct weston_output *output)
3230 {
3231     LOG_INFO("output schedule repaint");
3232 	struct weston_compositor *compositor = output->compositor;
3233 	struct wl_event_loop *loop;
3234 
3235 	if (compositor->state == WESTON_COMPOSITOR_SLEEPING ||
3236 	    compositor->state == WESTON_COMPOSITOR_OFFSCREEN) {
3237         LOG_ERROR("no need idle_repaint");
3238 		return;
3239     }
3240 
3241 // OHOS remove timeline
3242 //	if (!output->repaint_needed)
3243 //		TL_POINT(compositor, "core_repaint_req", TLP_OUTPUT(output), TLP_END);
3244 
3245 	loop = wl_display_get_event_loop(compositor->wl_display);
3246 	output->repaint_needed = true;
3247 
3248 	/* If we already have a repaint scheduled for our idle handler,
3249 	 * no need to set it again. If the repaint has been called but
3250 	 * not finished, then weston_output_finish_frame() will notice
3251 	 * that a repaint is needed and schedule one. */
3252 	if (output->repaint_status != REPAINT_NOT_SCHEDULED) {
3253         LOG_ERROR("no need idle_repaint");
3254 		return;
3255     }
3256 
3257 	output->repaint_status = REPAINT_BEGIN_FROM_IDLE;
3258 	assert(!output->idle_repaint_source);
3259 	output->idle_repaint_source = wl_event_loop_add_idle(loop, idle_repaint,
3260 							     output);
3261     LOG_INFO("core: add idle_repaint source");
3262 // OHOS remove timeline
3263 //	TL_POINT(compositor, "core_repaint_enter_loop", TLP_OUTPUT(output), TLP_END);
3264 }
3265 
3266 /** weston_compositor_schedule_repaint
3267  *  \ingroup compositor
3268  */
3269 WL_EXPORT void
weston_compositor_schedule_repaint(struct weston_compositor * compositor)3270 weston_compositor_schedule_repaint(struct weston_compositor *compositor)
3271 {
3272     LOG_INFO("compositor schedule repaint");
3273 	struct weston_output *output;
3274 
3275 	wl_list_for_each(output, &compositor->output_list, link)
3276 		weston_output_schedule_repaint(output);
3277 }
3278 
3279 static void
surface_destroy(struct wl_client * client,struct wl_resource * resource)3280 surface_destroy(struct wl_client *client, struct wl_resource *resource)
3281 {
3282 	wl_resource_destroy(resource);
3283 }
3284 
3285 static void
surface_attach(struct wl_client * client,struct wl_resource * resource,struct wl_resource * buffer_resource,int32_t sx,int32_t sy)3286 surface_attach(struct wl_client *client,
3287 	       struct wl_resource *resource,
3288 	       struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
3289 {
3290     LOG_ENTER();
3291 	struct weston_surface *surface = wl_resource_get_user_data(resource);
3292 	struct weston_buffer *buffer = NULL;
3293 
3294 	if (buffer_resource) {
3295 		buffer = weston_buffer_from_resource(buffer_resource);
3296 		if (buffer == NULL) {
3297 			wl_client_post_no_memory(client);
3298             LOG_EXIT();
3299 			return;
3300 		}
3301 	}
3302 
3303 	/* Attach, attach, without commit in between does not send
3304 	 * wl_buffer.release. */
3305 	weston_surface_state_set_buffer(&surface->pending, buffer);
3306 
3307 	surface->pending.sx = sx;
3308 	surface->pending.sy = sy;
3309 	surface->pending.newly_attached = 1;
3310     LOG_EXIT();
3311 }
3312 
3313 static void
surface_damage(struct wl_client * client,struct wl_resource * resource,int32_t x,int32_t y,int32_t width,int32_t height)3314 surface_damage(struct wl_client *client,
3315 	       struct wl_resource *resource,
3316 	       int32_t x, int32_t y, int32_t width, int32_t height)
3317 {
3318 	struct weston_surface *surface = wl_resource_get_user_data(resource);
3319 
3320 	if (width <= 0 || height <= 0)
3321 		return;
3322 
3323 	pixman_region32_union_rect(&surface->pending.damage_surface,
3324 				   &surface->pending.damage_surface,
3325 				   x, y, width, height);
3326 }
3327 
3328 static void
surface_damage_buffer(struct wl_client * client,struct wl_resource * resource,int32_t x,int32_t y,int32_t width,int32_t height)3329 surface_damage_buffer(struct wl_client *client,
3330 		      struct wl_resource *resource,
3331 		      int32_t x, int32_t y, int32_t width, int32_t height)
3332 {
3333 	struct weston_surface *surface = wl_resource_get_user_data(resource);
3334 
3335 	if (width <= 0 || height <= 0)
3336 		return;
3337 
3338 	pixman_region32_union_rect(&surface->pending.damage_buffer,
3339 				   &surface->pending.damage_buffer,
3340 				   x, y, width, height);
3341 }
3342 
3343 // OHOS surface type
3344 static void
surface_set_surface_type(struct wl_client * client,struct wl_resource * resource,int32_t type)3345 surface_set_surface_type(struct wl_client *client,
3346 		         struct wl_resource *resource, int32_t type)
3347 {
3348 	struct weston_surface *surface = wl_resource_get_user_data(resource);
3349 	surface->type = type;
3350 }
3351 
3352 static void
destroy_frame_callback(struct wl_resource * resource)3353 destroy_frame_callback(struct wl_resource *resource)
3354 {
3355 	struct weston_frame_callback *cb = wl_resource_get_user_data(resource);
3356 
3357 	wl_list_remove(&cb->link);
3358 	free(cb);
3359 }
3360 
3361 static void
surface_frame(struct wl_client * client,struct wl_resource * resource,uint32_t callback)3362 surface_frame(struct wl_client *client,
3363 	      struct wl_resource *resource, uint32_t callback)
3364 {
3365 	struct weston_frame_callback *cb;
3366 	struct weston_surface *surface = wl_resource_get_user_data(resource);
3367 
3368 	cb = malloc(sizeof *cb);
3369 	if (cb == NULL) {
3370 		wl_resource_post_no_memory(resource);
3371 		return;
3372 	}
3373 
3374 	cb->resource = wl_resource_create(client, &wl_callback_interface, 1,
3375 					  callback);
3376 	if (cb->resource == NULL) {
3377 		free(cb);
3378 		wl_resource_post_no_memory(resource);
3379 		return;
3380 	}
3381 
3382 	wl_resource_set_implementation(cb->resource, NULL, cb,
3383 				       destroy_frame_callback);
3384 
3385 	wl_list_insert(surface->pending.frame_callback_list.prev, &cb->link);
3386 }
3387 
3388 static void
surface_set_opaque_region(struct wl_client * client,struct wl_resource * resource,struct wl_resource * region_resource)3389 surface_set_opaque_region(struct wl_client *client,
3390 			  struct wl_resource *resource,
3391 			  struct wl_resource *region_resource)
3392 {
3393 	struct weston_surface *surface = wl_resource_get_user_data(resource);
3394 	struct weston_region *region;
3395 
3396 	if (region_resource) {
3397 		region = wl_resource_get_user_data(region_resource);
3398 		pixman_region32_copy(&surface->pending.opaque,
3399 				     &region->region);
3400 	} else {
3401 		pixman_region32_clear(&surface->pending.opaque);
3402 	}
3403 }
3404 
3405 static void
surface_set_input_region(struct wl_client * client,struct wl_resource * resource,struct wl_resource * region_resource)3406 surface_set_input_region(struct wl_client *client,
3407 			 struct wl_resource *resource,
3408 			 struct wl_resource *region_resource)
3409 {
3410 	struct weston_surface *surface = wl_resource_get_user_data(resource);
3411 	struct weston_region *region;
3412 
3413 	if (region_resource) {
3414 		region = wl_resource_get_user_data(region_resource);
3415 		pixman_region32_copy(&surface->pending.input,
3416 				     &region->region);
3417 	} else {
3418 		pixman_region32_fini(&surface->pending.input);
3419 		region_init_infinite(&surface->pending.input);
3420 	}
3421 }
3422 
3423 /* Cause damage to this sub-surface and all its children.
3424  *
3425  * This is useful when there are state changes that need an implicit
3426  * damage, e.g. a z-order change.
3427  */
3428 static void
weston_surface_damage_subsurfaces(struct weston_subsurface * sub)3429 weston_surface_damage_subsurfaces(struct weston_subsurface *sub)
3430 {
3431 	struct weston_subsurface *child;
3432 
3433 	weston_surface_damage(sub->surface);
3434 	sub->reordered = false;
3435 
3436 	wl_list_for_each(child, &sub->surface->subsurface_list, parent_link)
3437 		if (child != sub)
3438 			weston_surface_damage_subsurfaces(child);
3439 }
3440 
3441 static void
weston_surface_commit_subsurface_order(struct weston_surface * surface)3442 weston_surface_commit_subsurface_order(struct weston_surface *surface)
3443 {
3444 	struct weston_subsurface *sub;
3445 
3446 	wl_list_for_each_reverse(sub, &surface->subsurface_list_pending,
3447 				 parent_link_pending) {
3448 		wl_list_remove(&sub->parent_link);
3449 		wl_list_insert(&surface->subsurface_list, &sub->parent_link);
3450 
3451 		if (sub->reordered)
3452 			weston_surface_damage_subsurfaces(sub);
3453 	}
3454 }
3455 
3456 static void
weston_surface_build_buffer_matrix(const struct weston_surface * surface,struct weston_matrix * matrix)3457 weston_surface_build_buffer_matrix(const struct weston_surface *surface,
3458 				   struct weston_matrix *matrix)
3459 {
3460 	const struct weston_buffer_viewport *vp = &surface->buffer_viewport;
3461 	double src_width, src_height, dest_width, dest_height;
3462 
3463 	weston_matrix_init(matrix);
3464 
3465 	if (vp->buffer.src_width == wl_fixed_from_int(-1)) {
3466 		src_width = surface->width_from_buffer;
3467 		src_height = surface->height_from_buffer;
3468 	} else {
3469 		src_width = wl_fixed_to_double(vp->buffer.src_width);
3470 		src_height = wl_fixed_to_double(vp->buffer.src_height);
3471 	}
3472 
3473 	if (vp->surface.width == -1) {
3474 		dest_width = src_width;
3475 		dest_height = src_height;
3476 	} else {
3477 		dest_width = vp->surface.width;
3478 		dest_height = vp->surface.height;
3479 	}
3480 
3481 	if (src_width != dest_width || src_height != dest_height)
3482 		weston_matrix_scale(matrix,
3483 				    src_width / dest_width,
3484 				    src_height / dest_height, 1);
3485 
3486 	if (vp->buffer.src_width != wl_fixed_from_int(-1))
3487 		weston_matrix_translate(matrix,
3488 					wl_fixed_to_double(vp->buffer.src_x),
3489 					wl_fixed_to_double(vp->buffer.src_y),
3490 					0);
3491 
3492 	switch (vp->buffer.transform) {
3493 	case WL_OUTPUT_TRANSFORM_FLIPPED:
3494 	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
3495 	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
3496 	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
3497 		weston_matrix_scale(matrix, -1, 1, 1);
3498 		weston_matrix_translate(matrix,
3499 					surface->width_from_buffer, 0, 0);
3500 		break;
3501 	}
3502 
3503 	switch (vp->buffer.transform) {
3504 	default:
3505 	case WL_OUTPUT_TRANSFORM_NORMAL:
3506 	case WL_OUTPUT_TRANSFORM_FLIPPED:
3507 		break;
3508 	case WL_OUTPUT_TRANSFORM_90:
3509 	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
3510 		weston_matrix_rotate_xy(matrix, 0, -1);
3511 		weston_matrix_translate(matrix,
3512 					0, surface->width_from_buffer, 0);
3513 		break;
3514 	case WL_OUTPUT_TRANSFORM_180:
3515 	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
3516 		weston_matrix_rotate_xy(matrix, -1, 0);
3517 		weston_matrix_translate(matrix,
3518 					surface->width_from_buffer,
3519 					surface->height_from_buffer, 0);
3520 		break;
3521 	case WL_OUTPUT_TRANSFORM_270:
3522 	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
3523 		weston_matrix_rotate_xy(matrix, 0, 1);
3524 		weston_matrix_translate(matrix,
3525 					surface->height_from_buffer, 0, 0);
3526 		break;
3527 	}
3528 
3529 	weston_matrix_scale(matrix, vp->buffer.scale, vp->buffer.scale, 1);
3530 }
3531 
3532 /**
3533  * Compute a + b > c while being safe to overflows.
3534  */
3535 static bool
fixed_sum_gt(wl_fixed_t a,wl_fixed_t b,wl_fixed_t c)3536 fixed_sum_gt(wl_fixed_t a, wl_fixed_t b, wl_fixed_t c)
3537 {
3538 	return (int64_t)a + (int64_t)b > (int64_t)c;
3539 }
3540 
3541 static bool
weston_surface_is_pending_viewport_source_valid(const struct weston_surface * surface)3542 weston_surface_is_pending_viewport_source_valid(
3543 	const struct weston_surface *surface)
3544 {
3545 	const struct weston_surface_state *pend = &surface->pending;
3546 	const struct weston_buffer_viewport *vp = &pend->buffer_viewport;
3547 	int width_from_buffer = 0;
3548 	int height_from_buffer = 0;
3549 	wl_fixed_t w;
3550 	wl_fixed_t h;
3551 
3552 	/* If viewport source rect is not set, it is always ok. */
3553 	if (vp->buffer.src_width == wl_fixed_from_int(-1))
3554 		return true;
3555 
3556 	if (pend->newly_attached) {
3557 		if (pend->buffer) {
3558 			convert_size_by_transform_scale(&width_from_buffer,
3559 							&height_from_buffer,
3560 							pend->buffer->width,
3561 							pend->buffer->height,
3562 							vp->buffer.transform,
3563 							vp->buffer.scale);
3564 		} else {
3565 			/* No buffer: viewport is irrelevant. */
3566 			return true;
3567 		}
3568 	} else {
3569 		width_from_buffer = surface->width_from_buffer;
3570 		height_from_buffer = surface->height_from_buffer;
3571 	}
3572 
3573 	assert((width_from_buffer == 0) == (height_from_buffer == 0));
3574 	assert(width_from_buffer >= 0 && height_from_buffer >= 0);
3575 
3576 	/* No buffer: viewport is irrelevant. */
3577 	if (width_from_buffer == 0 || height_from_buffer == 0)
3578 		return true;
3579 
3580 	/* overflow checks for wl_fixed_from_int() */
3581 	if (width_from_buffer > wl_fixed_to_int(INT32_MAX))
3582 		return false;
3583 	if (height_from_buffer > wl_fixed_to_int(INT32_MAX))
3584 		return false;
3585 
3586 	w = wl_fixed_from_int(width_from_buffer);
3587 	h = wl_fixed_from_int(height_from_buffer);
3588 
3589 	if (fixed_sum_gt(vp->buffer.src_x, vp->buffer.src_width, w))
3590 		return false;
3591 	if (fixed_sum_gt(vp->buffer.src_y, vp->buffer.src_height, h))
3592 		return false;
3593 
3594 	return true;
3595 }
3596 
3597 static bool
fixed_is_integer(wl_fixed_t v)3598 fixed_is_integer(wl_fixed_t v)
3599 {
3600 	return (v & 0xff) == 0;
3601 }
3602 
3603 static bool
weston_surface_is_pending_viewport_dst_size_int(const struct weston_surface * surface)3604 weston_surface_is_pending_viewport_dst_size_int(
3605 	const struct weston_surface *surface)
3606 {
3607 	const struct weston_buffer_viewport *vp =
3608 		&surface->pending.buffer_viewport;
3609 
3610 	if (vp->surface.width != -1) {
3611 		assert(vp->surface.width > 0 && vp->surface.height > 0);
3612 		return true;
3613 	}
3614 
3615 	return fixed_is_integer(vp->buffer.src_width) &&
3616 	       fixed_is_integer(vp->buffer.src_height);
3617 }
3618 
3619 /* Translate pending damage in buffer co-ordinates to surface
3620  * co-ordinates and union it with a pixman_region32_t.
3621  * This should only be called after the buffer is attached.
3622  */
3623 static void
apply_damage_buffer(pixman_region32_t * dest,struct weston_surface * surface,struct weston_surface_state * state)3624 apply_damage_buffer(pixman_region32_t *dest,
3625 		    struct weston_surface *surface,
3626 		    struct weston_surface_state *state)
3627 {
3628 	struct weston_buffer *buffer = surface->buffer_ref.buffer;
3629 
3630 	/* wl_surface.damage_buffer needs to be clipped to the buffer,
3631 	 * translated into surface co-ordinates and unioned with
3632 	 * any other surface damage.
3633 	 * None of this makes sense if there is no buffer though.
3634 	 */
3635 	if (buffer && pixman_region32_not_empty(&state->damage_buffer)) {
3636 		pixman_region32_t buffer_damage;
3637 
3638 		pixman_region32_intersect_rect(&state->damage_buffer,
3639 					       &state->damage_buffer,
3640 					       0, 0, buffer->width,
3641 					       buffer->height);
3642 		pixman_region32_init(&buffer_damage);
3643 		weston_matrix_transform_region(&buffer_damage,
3644 					       &surface->buffer_to_surface_matrix,
3645 					       &state->damage_buffer);
3646 		pixman_region32_union(dest, dest, &buffer_damage);
3647 		pixman_region32_fini(&buffer_damage);
3648 	}
3649 	/* We should clear this on commit even if there was no buffer */
3650 	pixman_region32_clear(&state->damage_buffer);
3651 }
3652 
3653 static void
weston_surface_set_desired_protection(struct weston_surface * surface,enum weston_hdcp_protection protection)3654 weston_surface_set_desired_protection(struct weston_surface *surface,
3655 				      enum weston_hdcp_protection protection)
3656 {
3657 	if (surface->desired_protection == protection)
3658 		return;
3659 	surface->desired_protection = protection;
3660 	weston_surface_damage(surface);
3661 }
3662 
3663 static void
weston_surface_set_protection_mode(struct weston_surface * surface,enum weston_surface_protection_mode p_mode)3664 weston_surface_set_protection_mode(struct weston_surface *surface,
3665 				   enum weston_surface_protection_mode p_mode)
3666 {
3667 	struct content_protection *cp = surface->compositor->content_protection;
3668 	struct protected_surface *psurface;
3669 
3670 	surface->protection_mode = p_mode;
3671 	wl_list_for_each(psurface, &cp->protected_list, link) {
3672 		if (!psurface || psurface->surface != surface)
3673 			continue;
3674 		weston_protected_surface_send_event(psurface,
3675 						    surface->current_protection);
3676 	}
3677 }
3678 
3679 static void
weston_surface_commit_state(struct weston_surface * surface,struct weston_surface_state * state)3680 weston_surface_commit_state(struct weston_surface *surface,
3681 			    struct weston_surface_state *state)
3682 {
3683 	struct weston_view *view;
3684 	pixman_region32_t opaque;
3685 
3686 	/* wl_surface.set_buffer_transform */
3687 	/* wl_surface.set_buffer_scale */
3688 	/* wp_viewport.set_source */
3689 	/* wp_viewport.set_destination */
3690 	surface->buffer_viewport = state->buffer_viewport;
3691 
3692 	/* wl_surface.attach */
3693 	if (state->newly_attached) {
3694 		/* zwp_surface_synchronization_v1.set_acquire_fence */
3695 		fd_move(&surface->acquire_fence_fd,
3696 			&state->acquire_fence_fd);
3697 		/* zwp_surface_synchronization_v1.get_release */
3698 		weston_buffer_release_move(&surface->buffer_release_ref,
3699 					   &state->buffer_release_ref);
3700 		weston_surface_attach(surface, state->buffer);
3701 	}
3702 	weston_surface_state_set_buffer(state, NULL);
3703 	assert(state->acquire_fence_fd == -1);
3704 	assert(state->buffer_release_ref.buffer_release == NULL);
3705 
3706 	weston_surface_build_buffer_matrix(surface,
3707 					   &surface->surface_to_buffer_matrix);
3708 	weston_matrix_invert(&surface->buffer_to_surface_matrix,
3709 			     &surface->surface_to_buffer_matrix);
3710 
3711 	if (state->newly_attached || state->buffer_viewport.changed) {
3712 		weston_surface_update_size(surface);
3713         LOG_INFO("surface->committed: %p", surface->committed);
3714         LOG_ENTERS("surface->committed");
3715 		if (surface->committed)
3716 			surface->committed(surface, state->sx, state->sy);
3717         LOG_EXITS("surface->committed");
3718 	}
3719 
3720 	state->sx = 0;
3721 	state->sy = 0;
3722 	state->newly_attached = 0;
3723 	state->buffer_viewport.changed = 0;
3724 
3725 // OHOS remove timeline
3726 //	/* wl_surface.damage and wl_surface.damage_buffer */
3727 //	if (pixman_region32_not_empty(&state->damage_surface) ||
3728 //	     pixman_region32_not_empty(&state->damage_buffer))
3729 //		TL_POINT(surface->compositor, "core_commit_damage", TLP_SURFACE(surface), TLP_END);
3730 
3731 	pixman_region32_union(&surface->damage, &surface->damage,
3732 			      &state->damage_surface);
3733 
3734 	apply_damage_buffer(&surface->damage, surface, state);
3735 
3736 	pixman_region32_intersect_rect(&surface->damage, &surface->damage,
3737 				       0, 0, surface->width, surface->height);
3738 	pixman_region32_clear(&state->damage_surface);
3739 
3740 	/* wl_surface.set_opaque_region */
3741 	pixman_region32_init(&opaque);
3742 	pixman_region32_intersect_rect(&opaque, &state->opaque,
3743 				       0, 0, surface->width, surface->height);
3744 
3745 	if (!pixman_region32_equal(&opaque, &surface->opaque)) {
3746 		pixman_region32_copy(&surface->opaque, &opaque);
3747 		wl_list_for_each(view, &surface->views, surface_link)
3748 			weston_view_geometry_dirty(view);
3749 	}
3750 
3751 	pixman_region32_fini(&opaque);
3752 
3753 	/* wl_surface.set_input_region */
3754 	pixman_region32_intersect_rect(&surface->input, &state->input,
3755 				       0, 0, surface->width, surface->height);
3756 
3757 	/* wl_surface.frame */
3758 	wl_list_insert_list(&surface->frame_callback_list,
3759 			    &state->frame_callback_list);
3760 	wl_list_init(&state->frame_callback_list);
3761 
3762 	/* XXX:
3763 	 * What should happen with a feedback request, if there
3764 	 * is no wl_buffer attached for this commit?
3765 	 */
3766 
3767 	/* presentation.feedback */
3768 	wl_list_insert_list(&surface->feedback_list,
3769 			    &state->feedback_list);
3770 	wl_list_init(&state->feedback_list);
3771 
3772 	/* weston_protected_surface.enforced/relaxed */
3773 	if (surface->protection_mode != state->protection_mode)
3774 		weston_surface_set_protection_mode(surface,
3775 						   state->protection_mode);
3776 
3777 	/* weston_protected_surface.set_type */
3778 	weston_surface_set_desired_protection(surface, state->desired_protection);
3779 
3780 	wl_signal_emit(&surface->commit_signal, surface);
3781 }
3782 
3783 static void
weston_surface_commit(struct weston_surface * surface)3784 weston_surface_commit(struct weston_surface *surface)
3785 {
3786     LOG_ENTER();
3787 	weston_surface_commit_state(surface, &surface->pending);
3788 
3789 	weston_surface_commit_subsurface_order(surface);
3790 
3791 	weston_surface_schedule_repaint(surface);
3792     LOG_EXIT();
3793 }
3794 
3795 static void
3796 weston_subsurface_commit(struct weston_subsurface *sub);
3797 
3798 static void
3799 weston_subsurface_parent_commit(struct weston_subsurface *sub,
3800 				int parent_is_synchronized);
3801 
3802 static void
surface_commit(struct wl_client * client,struct wl_resource * resource)3803 surface_commit(struct wl_client *client, struct wl_resource *resource)
3804 {
3805     LOG_ENTER();
3806 	struct weston_surface *surface = wl_resource_get_user_data(resource);
3807 	struct weston_subsurface *sub = weston_surface_to_subsurface(surface);
3808 
3809 	if (!weston_surface_is_pending_viewport_source_valid(surface)) {
3810 		assert(surface->viewport_resource);
3811 
3812 		wl_resource_post_error(surface->viewport_resource,
3813 			WP_VIEWPORT_ERROR_OUT_OF_BUFFER,
3814 			"wl_surface@%d has viewport source outside buffer",
3815 			wl_resource_get_id(resource));
3816         LOG_EXIT();
3817 		return;
3818 	}
3819 
3820 	if (!weston_surface_is_pending_viewport_dst_size_int(surface)) {
3821 		assert(surface->viewport_resource);
3822 
3823 		wl_resource_post_error(surface->viewport_resource,
3824 			WP_VIEWPORT_ERROR_BAD_SIZE,
3825 			"wl_surface@%d viewport dst size not integer",
3826 			wl_resource_get_id(resource));
3827         LOG_EXIT();
3828 		return;
3829 	}
3830 
3831 	if (surface->pending.acquire_fence_fd >= 0) {
3832 		assert(surface->synchronization_resource);
3833 
3834 		if (!surface->pending.buffer) {
3835 			fd_clear(&surface->pending.acquire_fence_fd);
3836 			wl_resource_post_error(surface->synchronization_resource,
3837 				ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_NO_BUFFER,
3838 				"wl_surface@%"PRIu32" no buffer for synchronization",
3839 				wl_resource_get_id(resource));
3840             LOG_EXIT();
3841 			return;
3842 		}
3843 
3844 		/* We support fences for both wp_linux_dmabuf and opaque EGL
3845 		 * buffers, as mandated by minor version 2 of the
3846 		 * zwp_linux_explicit_synchronization_v1 protocol. Since
3847 		 * renderers that support fences currently only support these
3848 		 * two buffer types plus SHM buffers, we can just check for the
3849 		 * SHM buffer case here.
3850 		 */
3851 		if (wl_shm_buffer_get(surface->pending.buffer->resource)) {
3852 			fd_clear(&surface->pending.acquire_fence_fd);
3853 			wl_resource_post_error(surface->synchronization_resource,
3854 				ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_UNSUPPORTED_BUFFER,
3855 				"wl_surface@%"PRIu32" unsupported buffer for synchronization",
3856 				wl_resource_get_id(resource));
3857             LOG_EXIT();
3858 			return;
3859 		}
3860 	}
3861 
3862 	if (surface->pending.buffer_release_ref.buffer_release &&
3863 	    !surface->pending.buffer) {
3864 		assert(surface->synchronization_resource);
3865 
3866 		wl_resource_post_error(surface->synchronization_resource,
3867 			ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_NO_BUFFER,
3868 			"wl_surface@%"PRIu32" no buffer for synchronization",
3869 			wl_resource_get_id(resource));
3870         LOG_EXIT();
3871 		return;
3872 	}
3873 
3874 	if (sub) {
3875 		weston_subsurface_commit(sub);
3876         LOG_EXIT();
3877 		return;
3878 	}
3879 
3880 	weston_surface_commit(surface);
3881 
3882 	wl_list_for_each(sub, &surface->subsurface_list, parent_link) {
3883 		if (sub->surface != surface)
3884 			weston_subsurface_parent_commit(sub, 0);
3885 	}
3886     LOG_EXIT();
3887 }
3888 
3889 static void
surface_set_buffer_transform(struct wl_client * client,struct wl_resource * resource,int transform)3890 surface_set_buffer_transform(struct wl_client *client,
3891 			     struct wl_resource *resource, int transform)
3892 {
3893 	struct weston_surface *surface = wl_resource_get_user_data(resource);
3894 
3895 	/* if wl_output.transform grows more members this will need to be updated. */
3896 	if (transform < 0 ||
3897 	    transform > WL_OUTPUT_TRANSFORM_FLIPPED_270) {
3898 		wl_resource_post_error(resource,
3899 			WL_SURFACE_ERROR_INVALID_TRANSFORM,
3900 			"buffer transform must be a valid transform "
3901 			"('%d' specified)", transform);
3902 		return;
3903 	}
3904 
3905 	surface->pending.buffer_viewport.buffer.transform = transform;
3906 	surface->pending.buffer_viewport.changed = 1;
3907 }
3908 
3909 static void
surface_set_buffer_scale(struct wl_client * client,struct wl_resource * resource,int32_t scale)3910 surface_set_buffer_scale(struct wl_client *client,
3911 			 struct wl_resource *resource,
3912 			 int32_t scale)
3913 {
3914 	struct weston_surface *surface = wl_resource_get_user_data(resource);
3915 
3916 	if (scale < 1) {
3917 		wl_resource_post_error(resource,
3918 			WL_SURFACE_ERROR_INVALID_SCALE,
3919 			"buffer scale must be at least one "
3920 			"('%d' specified)", scale);
3921 		return;
3922 	}
3923 
3924 	surface->pending.buffer_viewport.buffer.scale = scale;
3925 	surface->pending.buffer_viewport.changed = 1;
3926 }
3927 
3928 static const struct wl_surface_interface surface_interface = {
3929 	surface_destroy,
3930 	surface_attach,
3931 	surface_damage,
3932 	surface_frame,
3933 	surface_set_opaque_region,
3934 	surface_set_input_region,
3935 	surface_commit,
3936 	surface_set_buffer_transform,
3937 	surface_set_buffer_scale,
3938 	surface_damage_buffer,
3939 	surface_set_surface_type // OHOS surface type
3940 };
3941 
3942 static void
compositor_create_surface(struct wl_client * client,struct wl_resource * resource,uint32_t id)3943 compositor_create_surface(struct wl_client *client,
3944 			  struct wl_resource *resource, uint32_t id)
3945 {
3946 	struct weston_compositor *ec = wl_resource_get_user_data(resource);
3947 	struct weston_surface *surface;
3948 
3949 	surface = weston_surface_create(ec);
3950 	if (surface == NULL) {
3951 		wl_resource_post_no_memory(resource);
3952 		return;
3953 	}
3954 
3955 	surface->resource =
3956 		wl_resource_create(client, &wl_surface_interface,
3957 				   wl_resource_get_version(resource), id);
3958 	if (surface->resource == NULL) {
3959 		weston_surface_destroy(surface);
3960 		wl_resource_post_no_memory(resource);
3961 		return;
3962 	}
3963 	wl_resource_set_implementation(surface->resource, &surface_interface,
3964 				       surface, destroy_surface);
3965 
3966 	wl_signal_emit(&ec->create_surface_signal, surface);
3967 }
3968 
3969 static void
destroy_region(struct wl_resource * resource)3970 destroy_region(struct wl_resource *resource)
3971 {
3972 	struct weston_region *region = wl_resource_get_user_data(resource);
3973 
3974 	pixman_region32_fini(&region->region);
3975 	free(region);
3976 }
3977 
3978 static void
region_destroy(struct wl_client * client,struct wl_resource * resource)3979 region_destroy(struct wl_client *client, struct wl_resource *resource)
3980 {
3981 	wl_resource_destroy(resource);
3982 }
3983 
3984 static void
region_add(struct wl_client * client,struct wl_resource * resource,int32_t x,int32_t y,int32_t width,int32_t height)3985 region_add(struct wl_client *client, struct wl_resource *resource,
3986 	   int32_t x, int32_t y, int32_t width, int32_t height)
3987 {
3988 	struct weston_region *region = wl_resource_get_user_data(resource);
3989 
3990 	pixman_region32_union_rect(&region->region, &region->region,
3991 				   x, y, width, height);
3992 }
3993 
3994 static void
region_subtract(struct wl_client * client,struct wl_resource * resource,int32_t x,int32_t y,int32_t width,int32_t height)3995 region_subtract(struct wl_client *client, struct wl_resource *resource,
3996 		int32_t x, int32_t y, int32_t width, int32_t height)
3997 {
3998 	struct weston_region *region = wl_resource_get_user_data(resource);
3999 	pixman_region32_t rect;
4000 
4001 	pixman_region32_init_rect(&rect, x, y, width, height);
4002 	pixman_region32_subtract(&region->region, &region->region, &rect);
4003 	pixman_region32_fini(&rect);
4004 }
4005 
4006 static const struct wl_region_interface region_interface = {
4007 	region_destroy,
4008 	region_add,
4009 	region_subtract
4010 };
4011 
4012 static void
compositor_create_region(struct wl_client * client,struct wl_resource * resource,uint32_t id)4013 compositor_create_region(struct wl_client *client,
4014 			 struct wl_resource *resource, uint32_t id)
4015 {
4016 	struct weston_region *region;
4017 
4018 	region = malloc(sizeof *region);
4019 	if (region == NULL) {
4020 		wl_resource_post_no_memory(resource);
4021 		return;
4022 	}
4023 
4024 	pixman_region32_init(&region->region);
4025 
4026 	region->resource =
4027 		wl_resource_create(client, &wl_region_interface, 1, id);
4028 	if (region->resource == NULL) {
4029 		free(region);
4030 		wl_resource_post_no_memory(resource);
4031 		return;
4032 	}
4033 	wl_resource_set_implementation(region->resource, &region_interface,
4034 				       region, destroy_region);
4035 }
4036 
4037 static const struct wl_compositor_interface compositor_interface = {
4038 	compositor_create_surface,
4039 	compositor_create_region
4040 };
4041 
4042 static void
weston_subsurface_commit_from_cache(struct weston_subsurface * sub)4043 weston_subsurface_commit_from_cache(struct weston_subsurface *sub)
4044 {
4045 	struct weston_surface *surface = sub->surface;
4046 
4047 	weston_surface_commit_state(surface, &sub->cached);
4048 	weston_buffer_reference(&sub->cached_buffer_ref, NULL);
4049 
4050 	weston_surface_commit_subsurface_order(surface);
4051 
4052 	weston_surface_schedule_repaint(surface);
4053 
4054 	sub->has_cached_data = 0;
4055 }
4056 
4057 static void
weston_subsurface_commit_to_cache(struct weston_subsurface * sub)4058 weston_subsurface_commit_to_cache(struct weston_subsurface *sub)
4059 {
4060 	struct weston_surface *surface = sub->surface;
4061 
4062 	/*
4063 	 * If this commit would cause the surface to move by the
4064 	 * attach(dx, dy) parameters, the old damage region must be
4065 	 * translated to correspond to the new surface coordinate system
4066 	 * origin.
4067 	 */
4068 	pixman_region32_translate(&sub->cached.damage_surface,
4069 				  -surface->pending.sx, -surface->pending.sy);
4070 	pixman_region32_union(&sub->cached.damage_surface,
4071 			      &sub->cached.damage_surface,
4072 			      &surface->pending.damage_surface);
4073 	pixman_region32_clear(&surface->pending.damage_surface);
4074 
4075 	if (surface->pending.newly_attached) {
4076 		sub->cached.newly_attached = 1;
4077 		weston_surface_state_set_buffer(&sub->cached,
4078 						surface->pending.buffer);
4079 		weston_buffer_reference(&sub->cached_buffer_ref,
4080 					surface->pending.buffer);
4081 		weston_presentation_feedback_discard_list(
4082 					&sub->cached.feedback_list);
4083 		/* zwp_surface_synchronization_v1.set_acquire_fence */
4084 		fd_move(&sub->cached.acquire_fence_fd,
4085 			&surface->pending.acquire_fence_fd);
4086 		/* zwp_surface_synchronization_v1.get_release */
4087 		weston_buffer_release_move(&sub->cached.buffer_release_ref,
4088 					   &surface->pending.buffer_release_ref);
4089 	}
4090 	sub->cached.desired_protection = surface->pending.desired_protection;
4091 	sub->cached.protection_mode = surface->pending.protection_mode;
4092 	assert(surface->pending.acquire_fence_fd == -1);
4093 	assert(surface->pending.buffer_release_ref.buffer_release == NULL);
4094 	sub->cached.sx += surface->pending.sx;
4095 	sub->cached.sy += surface->pending.sy;
4096 
4097 	apply_damage_buffer(&sub->cached.damage_surface, surface, &surface->pending);
4098 
4099 	sub->cached.buffer_viewport.changed |=
4100 		surface->pending.buffer_viewport.changed;
4101 	sub->cached.buffer_viewport.buffer =
4102 		surface->pending.buffer_viewport.buffer;
4103 	sub->cached.buffer_viewport.surface =
4104 		surface->pending.buffer_viewport.surface;
4105 
4106 	weston_surface_reset_pending_buffer(surface);
4107 
4108 	pixman_region32_copy(&sub->cached.opaque, &surface->pending.opaque);
4109 
4110 	pixman_region32_copy(&sub->cached.input, &surface->pending.input);
4111 
4112 	wl_list_insert_list(&sub->cached.frame_callback_list,
4113 			    &surface->pending.frame_callback_list);
4114 	wl_list_init(&surface->pending.frame_callback_list);
4115 
4116 	wl_list_insert_list(&sub->cached.feedback_list,
4117 			    &surface->pending.feedback_list);
4118 	wl_list_init(&surface->pending.feedback_list);
4119 
4120 	sub->has_cached_data = 1;
4121 }
4122 
4123 static bool
weston_subsurface_is_synchronized(struct weston_subsurface * sub)4124 weston_subsurface_is_synchronized(struct weston_subsurface *sub)
4125 {
4126 	while (sub) {
4127 		if (sub->synchronized)
4128 			return true;
4129 
4130 		if (!sub->parent)
4131 			return false;
4132 
4133 		sub = weston_surface_to_subsurface(sub->parent);
4134 	}
4135 
4136 	return false;
4137 }
4138 
4139 static void
weston_subsurface_commit(struct weston_subsurface * sub)4140 weston_subsurface_commit(struct weston_subsurface *sub)
4141 {
4142 	struct weston_surface *surface = sub->surface;
4143 	struct weston_subsurface *tmp;
4144 
4145 	/* Recursive check for effectively synchronized. */
4146 	if (weston_subsurface_is_synchronized(sub)) {
4147 		weston_subsurface_commit_to_cache(sub);
4148 	} else {
4149 		if (sub->has_cached_data) {
4150 			/* flush accumulated state from cache */
4151 			weston_subsurface_commit_to_cache(sub);
4152 			weston_subsurface_commit_from_cache(sub);
4153 		} else {
4154 			weston_surface_commit(surface);
4155 		}
4156 
4157 		wl_list_for_each(tmp, &surface->subsurface_list, parent_link) {
4158 			if (tmp->surface != surface)
4159 				weston_subsurface_parent_commit(tmp, 0);
4160 		}
4161 	}
4162 }
4163 
4164 static void
weston_subsurface_synchronized_commit(struct weston_subsurface * sub)4165 weston_subsurface_synchronized_commit(struct weston_subsurface *sub)
4166 {
4167 	struct weston_surface *surface = sub->surface;
4168 	struct weston_subsurface *tmp;
4169 
4170 	/* From now on, commit_from_cache the whole sub-tree, regardless of
4171 	 * the synchronized mode of each child. This sub-surface or some
4172 	 * of its ancestors were synchronized, so we are synchronized
4173 	 * all the way down.
4174 	 */
4175 
4176 	if (sub->has_cached_data)
4177 		weston_subsurface_commit_from_cache(sub);
4178 
4179 	wl_list_for_each(tmp, &surface->subsurface_list, parent_link) {
4180 		if (tmp->surface != surface)
4181 			weston_subsurface_parent_commit(tmp, 1);
4182 	}
4183 }
4184 
4185 static void
weston_subsurface_parent_commit(struct weston_subsurface * sub,int parent_is_synchronized)4186 weston_subsurface_parent_commit(struct weston_subsurface *sub,
4187 				int parent_is_synchronized)
4188 {
4189 	struct weston_view *view;
4190 	if (sub->position.set) {
4191 		wl_list_for_each(view, &sub->surface->views, surface_link)
4192 			weston_view_set_position(view,
4193 						 sub->position.x,
4194 						 sub->position.y);
4195 
4196 		sub->position.set = 0;
4197 	}
4198 
4199 	if (parent_is_synchronized || sub->synchronized)
4200 		weston_subsurface_synchronized_commit(sub);
4201 }
4202 
4203 static int
subsurface_get_label(struct weston_surface * surface,char * buf,size_t len)4204 subsurface_get_label(struct weston_surface *surface, char *buf, size_t len)
4205 {
4206 	return snprintf(buf, len, "sub-surface");
4207 }
4208 
4209 static void
subsurface_committed(struct weston_surface * surface,int32_t dx,int32_t dy)4210 subsurface_committed(struct weston_surface *surface, int32_t dx, int32_t dy)
4211 {
4212 	struct weston_view *view;
4213 
4214 	wl_list_for_each(view, &surface->views, surface_link)
4215 		weston_view_set_position(view,
4216 					 view->geometry.x + dx,
4217 					 view->geometry.y + dy);
4218 
4219 	/* No need to check parent mappedness, because if parent is not
4220 	 * mapped, parent is not in a visible layer, so this sub-surface
4221 	 * will not be drawn either.
4222 	 */
4223 
4224 	if (!weston_surface_is_mapped(surface)) {
4225 		surface->is_mapped = true;
4226 
4227 		/* Cannot call weston_view_update_transform(),
4228 		 * because that would call it also for the parent surface,
4229 		 * which might not be mapped yet. That would lead to
4230 		 * inconsistent state, where the window could never be
4231 		 * mapped.
4232 		 *
4233 		 * Instead just force the is_mapped flag on, to make
4234 		 * weston_surface_is_mapped() return true, so that when the
4235 		 * parent surface does get mapped, this one will get
4236 		 * included, too. See view_list_add().
4237 		 */
4238 	}
4239 }
4240 
4241 static struct weston_subsurface *
weston_surface_to_subsurface(struct weston_surface * surface)4242 weston_surface_to_subsurface(struct weston_surface *surface)
4243 {
4244 	if (surface->committed == subsurface_committed)
4245 		return surface->committed_private;
4246 
4247 	return NULL;
4248 }
4249 
4250 WL_EXPORT struct weston_surface *
weston_surface_get_main_surface(struct weston_surface * surface)4251 weston_surface_get_main_surface(struct weston_surface *surface)
4252 {
4253 	struct weston_subsurface *sub;
4254 
4255 	while (surface && (sub = weston_surface_to_subsurface(surface)))
4256 		surface = sub->parent;
4257 
4258 	return surface;
4259 }
4260 
4261 WL_EXPORT int
weston_surface_set_role(struct weston_surface * surface,const char * role_name,struct wl_resource * error_resource,uint32_t error_code)4262 weston_surface_set_role(struct weston_surface *surface,
4263 			const char *role_name,
4264 			struct wl_resource *error_resource,
4265 			uint32_t error_code)
4266 {
4267 	assert(role_name);
4268 
4269 	if (surface->role_name == NULL ||
4270 	    surface->role_name == role_name ||
4271 	    strcmp(surface->role_name, role_name) == 0) {
4272 		surface->role_name = role_name;
4273 
4274 		return 0;
4275 	}
4276 
4277 	wl_resource_post_error(error_resource, error_code,
4278 			       "Cannot assign role %s to wl_surface@%d,"
4279 			       " already has role %s\n",
4280 			       role_name,
4281 			       wl_resource_get_id(surface->resource),
4282 			       surface->role_name);
4283 	return -1;
4284 }
4285 
4286 WL_EXPORT const char *
weston_surface_get_role(struct weston_surface * surface)4287 weston_surface_get_role(struct weston_surface *surface)
4288 {
4289 	return surface->role_name;
4290 }
4291 
4292 WL_EXPORT void
weston_surface_set_label_func(struct weston_surface * surface,int (* desc)(struct weston_surface *,char *,size_t))4293 weston_surface_set_label_func(struct weston_surface *surface,
4294 			      int (*desc)(struct weston_surface *,
4295 					  char *, size_t))
4296 {
4297 	surface->get_label = desc;
4298 // OHOS remove timeline
4299 //	weston_timeline_refresh_subscription_objects(surface->compositor,
4300 //						     surface);
4301 }
4302 
4303 /** Get the size of surface contents
4304  *
4305  * \param surface The surface to query.
4306  * \param width Returns the width of raw contents.
4307  * \param height Returns the height of raw contents.
4308  *
4309  * Retrieves the raw surface content size in pixels for the given surface.
4310  * This is the whole content size in buffer pixels. If the surface
4311  * has no content or the renderer does not implement this feature,
4312  * zeroes are returned.
4313  *
4314  * This function is used to determine the buffer size needed for
4315  * a weston_surface_copy_content() call.
4316  */
4317 WL_EXPORT void
weston_surface_get_content_size(struct weston_surface * surface,int * width,int * height)4318 weston_surface_get_content_size(struct weston_surface *surface,
4319 				int *width, int *height)
4320 {
4321 	struct weston_renderer *rer = surface->compositor->renderer;
4322 
4323 	if (!rer->surface_get_content_size) {
4324 		*width = 0;
4325 		*height = 0;
4326 		return;
4327 	}
4328 
4329 	rer->surface_get_content_size(surface, width, height);
4330 }
4331 
4332 /** Get the bounding box of a surface and its subsurfaces
4333  *
4334  * \param surface The surface to query.
4335  * \return The bounding box relative to the surface origin.
4336  *
4337  */
4338 WL_EXPORT struct weston_geometry
weston_surface_get_bounding_box(struct weston_surface * surface)4339 weston_surface_get_bounding_box(struct weston_surface *surface)
4340 {
4341 	pixman_region32_t region;
4342 	pixman_box32_t *box;
4343 	struct weston_subsurface *subsurface;
4344 
4345 	pixman_region32_init_rect(&region,
4346 				  0, 0,
4347 				  surface->width, surface->height);
4348 
4349 	wl_list_for_each(subsurface, &surface->subsurface_list, parent_link)
4350 		pixman_region32_union_rect(&region, &region,
4351 					   subsurface->position.x,
4352 					   subsurface->position.y,
4353 					   subsurface->surface->width,
4354 					   subsurface->surface->height);
4355 
4356 	box = pixman_region32_extents(&region);
4357 	struct weston_geometry geometry = {
4358 		.x = box->x1,
4359 		.y = box->y1,
4360 		.width = box->x2 - box->x1,
4361 		.height = box->y2 - box->y1,
4362 	};
4363 
4364 	pixman_region32_fini(&region);
4365 
4366 	return geometry;
4367 }
4368 
4369 /** Copy surface contents to system memory.
4370  *
4371  * \param surface The surface to copy from.
4372  * \param target Pointer to the target memory buffer.
4373  * \param size Size of the target buffer in bytes.
4374  * \param src_x X location on contents to copy from.
4375  * \param src_y Y location on contents to copy from.
4376  * \param width Width in pixels of the area to copy.
4377  * \param height Height in pixels of the area to copy.
4378  * \return 0 for success, -1 for failure.
4379  *
4380  * Surface contents are maintained by the renderer. They can be in a
4381  * reserved weston_buffer or as a copy, e.g. a GL texture, or something
4382  * else.
4383  *
4384  * Surface contents are copied into memory pointed to by target,
4385  * which has size bytes of space available. The target memory
4386  * may be larger than needed, but being smaller returns an error.
4387  * The extra bytes in target may or may not be written; their content is
4388  * unspecified. Size must be large enough to hold the image.
4389  *
4390  * The image in the target memory will be arranged in rows from
4391  * top to bottom, and pixels on a row from left to right. The pixel
4392  * format is PIXMAN_a8b8g8r8, 4 bytes per pixel, and stride is exactly
4393  * width * 4.
4394  *
4395  * Parameters src_x and src_y define the upper-left corner in buffer
4396  * coordinates (pixels) to copy from. Parameters width and height
4397  * define the size of the area to copy in pixels.
4398  *
4399  * The rectangle defined by src_x, src_y, width, height must fit in
4400  * the surface contents. Otherwise an error is returned.
4401  *
4402  * Use weston_surface_get_content_size to determine the content size; the
4403  * needed target buffer size and rectangle limits.
4404  *
4405  * CURRENT IMPLEMENTATION RESTRICTIONS:
4406  * - the machine must be little-endian due to Pixman formats.
4407  *
4408  * NOTE: Pixman formats are premultiplied.
4409  */
4410 WL_EXPORT int
weston_surface_copy_content(struct weston_surface * surface,void * target,size_t size,int src_x,int src_y,int width,int height)4411 weston_surface_copy_content(struct weston_surface *surface,
4412 			    void *target, size_t size,
4413 			    int src_x, int src_y,
4414 			    int width, int height)
4415 {
4416 	struct weston_renderer *rer = surface->compositor->renderer;
4417 	int cw, ch;
4418 	const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */
4419 
4420 	if (!rer->surface_copy_content)
4421 		return -1;
4422 
4423 	weston_surface_get_content_size(surface, &cw, &ch);
4424 
4425 	if (src_x < 0 || src_y < 0)
4426 		return -1;
4427 
4428 	if (width <= 0 || height <= 0)
4429 		return -1;
4430 
4431 	if (src_x + width > cw || src_y + height > ch)
4432 		return -1;
4433 
4434 	if (width * bytespp * height > size)
4435 		return -1;
4436 
4437 	return rer->surface_copy_content(surface, target, size,
4438 					 src_x, src_y, width, height);
4439 }
4440 
4441 static void
subsurface_set_position(struct wl_client * client,struct wl_resource * resource,int32_t x,int32_t y)4442 subsurface_set_position(struct wl_client *client,
4443 			struct wl_resource *resource, int32_t x, int32_t y)
4444 {
4445 	struct weston_subsurface *sub = wl_resource_get_user_data(resource);
4446 
4447 	if (!sub)
4448 		return;
4449 
4450 	sub->position.x = x;
4451 	sub->position.y = y;
4452 	sub->position.set = 1;
4453 }
4454 
4455 static struct weston_subsurface *
subsurface_find_sibling(struct weston_subsurface * sub,struct weston_surface * surface)4456 subsurface_find_sibling(struct weston_subsurface *sub,
4457 		       struct weston_surface *surface)
4458 {
4459 	struct weston_surface *parent = sub->parent;
4460 	struct weston_subsurface *sibling;
4461 
4462 	wl_list_for_each(sibling, &parent->subsurface_list, parent_link) {
4463 		if (sibling->surface == surface && sibling != sub)
4464 			return sibling;
4465 	}
4466 
4467 	return NULL;
4468 }
4469 
4470 static struct weston_subsurface *
subsurface_sibling_check(struct weston_subsurface * sub,struct weston_surface * surface,const char * request)4471 subsurface_sibling_check(struct weston_subsurface *sub,
4472 			 struct weston_surface *surface,
4473 			 const char *request)
4474 {
4475 	struct weston_subsurface *sibling;
4476 
4477 	sibling = subsurface_find_sibling(sub, surface);
4478 	if (!sibling) {
4479 		wl_resource_post_error(sub->resource,
4480 			WL_SUBSURFACE_ERROR_BAD_SURFACE,
4481 			"%s: wl_surface@%d is not a parent or sibling",
4482 			request, wl_resource_get_id(surface->resource));
4483 		return NULL;
4484 	}
4485 
4486 	assert(sibling->parent == sub->parent);
4487 
4488 	return sibling;
4489 }
4490 
4491 static void
subsurface_place_above(struct wl_client * client,struct wl_resource * resource,struct wl_resource * sibling_resource)4492 subsurface_place_above(struct wl_client *client,
4493 		       struct wl_resource *resource,
4494 		       struct wl_resource *sibling_resource)
4495 {
4496 	struct weston_subsurface *sub = wl_resource_get_user_data(resource);
4497 	struct weston_surface *surface =
4498 		wl_resource_get_user_data(sibling_resource);
4499 	struct weston_subsurface *sibling;
4500 
4501 	if (!sub)
4502 		return;
4503 
4504 	sibling = subsurface_sibling_check(sub, surface, "place_above");
4505 	if (!sibling)
4506 		return;
4507 
4508 	wl_list_remove(&sub->parent_link_pending);
4509 	wl_list_insert(sibling->parent_link_pending.prev,
4510 		       &sub->parent_link_pending);
4511 
4512 	sub->reordered = true;
4513 }
4514 
4515 static void
subsurface_place_below(struct wl_client * client,struct wl_resource * resource,struct wl_resource * sibling_resource)4516 subsurface_place_below(struct wl_client *client,
4517 		       struct wl_resource *resource,
4518 		       struct wl_resource *sibling_resource)
4519 {
4520 	struct weston_subsurface *sub = wl_resource_get_user_data(resource);
4521 	struct weston_surface *surface =
4522 		wl_resource_get_user_data(sibling_resource);
4523 	struct weston_subsurface *sibling;
4524 
4525 	if (!sub)
4526 		return;
4527 
4528 	sibling = subsurface_sibling_check(sub, surface, "place_below");
4529 	if (!sibling)
4530 		return;
4531 
4532 	wl_list_remove(&sub->parent_link_pending);
4533 	wl_list_insert(&sibling->parent_link_pending,
4534 		       &sub->parent_link_pending);
4535 
4536 	sub->reordered = true;
4537 }
4538 
4539 static void
subsurface_set_sync(struct wl_client * client,struct wl_resource * resource)4540 subsurface_set_sync(struct wl_client *client, struct wl_resource *resource)
4541 {
4542 	struct weston_subsurface *sub = wl_resource_get_user_data(resource);
4543 
4544 	if (sub)
4545 		sub->synchronized = 1;
4546 }
4547 
4548 static void
subsurface_set_desync(struct wl_client * client,struct wl_resource * resource)4549 subsurface_set_desync(struct wl_client *client, struct wl_resource *resource)
4550 {
4551 	struct weston_subsurface *sub = wl_resource_get_user_data(resource);
4552 
4553 	if (sub && sub->synchronized) {
4554 		sub->synchronized = 0;
4555 
4556 		/* If sub became effectively desynchronized, flush. */
4557 		if (!weston_subsurface_is_synchronized(sub))
4558 			weston_subsurface_synchronized_commit(sub);
4559 	}
4560 }
4561 
4562 static void
weston_subsurface_unlink_parent(struct weston_subsurface * sub)4563 weston_subsurface_unlink_parent(struct weston_subsurface *sub)
4564 {
4565 	wl_list_remove(&sub->parent_link);
4566 	wl_list_remove(&sub->parent_link_pending);
4567 	wl_list_remove(&sub->parent_destroy_listener.link);
4568 	sub->parent = NULL;
4569 }
4570 
4571 static void
4572 weston_subsurface_destroy(struct weston_subsurface *sub);
4573 
4574 static void
subsurface_handle_surface_destroy(struct wl_listener * listener,void * data)4575 subsurface_handle_surface_destroy(struct wl_listener *listener, void *data)
4576 {
4577 	struct weston_subsurface *sub =
4578 		container_of(listener, struct weston_subsurface,
4579 			     surface_destroy_listener);
4580 	assert(data == sub->surface);
4581 
4582 	/* The protocol object (wl_resource) is left inert. */
4583 	if (sub->resource)
4584 		wl_resource_set_user_data(sub->resource, NULL);
4585 
4586 	weston_subsurface_destroy(sub);
4587 }
4588 
4589 static void
subsurface_handle_parent_destroy(struct wl_listener * listener,void * data)4590 subsurface_handle_parent_destroy(struct wl_listener *listener, void *data)
4591 {
4592 	struct weston_subsurface *sub =
4593 		container_of(listener, struct weston_subsurface,
4594 			     parent_destroy_listener);
4595 	assert(data == sub->parent);
4596 	assert(sub->surface != sub->parent);
4597 
4598 	if (weston_surface_is_mapped(sub->surface))
4599 		weston_surface_unmap(sub->surface);
4600 
4601 	weston_subsurface_unlink_parent(sub);
4602 }
4603 
4604 static void
subsurface_resource_destroy(struct wl_resource * resource)4605 subsurface_resource_destroy(struct wl_resource *resource)
4606 {
4607 	struct weston_subsurface *sub = wl_resource_get_user_data(resource);
4608 
4609 	if (sub)
4610 		weston_subsurface_destroy(sub);
4611 }
4612 
4613 static void
subsurface_destroy(struct wl_client * client,struct wl_resource * resource)4614 subsurface_destroy(struct wl_client *client, struct wl_resource *resource)
4615 {
4616 	wl_resource_destroy(resource);
4617 }
4618 
4619 static void
weston_subsurface_link_parent(struct weston_subsurface * sub,struct weston_surface * parent)4620 weston_subsurface_link_parent(struct weston_subsurface *sub,
4621 			      struct weston_surface *parent)
4622 {
4623 	sub->parent = parent;
4624 	sub->parent_destroy_listener.notify = subsurface_handle_parent_destroy;
4625 	wl_signal_add(&parent->destroy_signal,
4626 		      &sub->parent_destroy_listener);
4627 
4628 	wl_list_insert(&parent->subsurface_list, &sub->parent_link);
4629 	wl_list_insert(&parent->subsurface_list_pending,
4630 		       &sub->parent_link_pending);
4631 }
4632 
4633 static void
weston_subsurface_link_surface(struct weston_subsurface * sub,struct weston_surface * surface)4634 weston_subsurface_link_surface(struct weston_subsurface *sub,
4635 			       struct weston_surface *surface)
4636 {
4637 	sub->surface = surface;
4638 	sub->surface_destroy_listener.notify =
4639 		subsurface_handle_surface_destroy;
4640 	wl_signal_add(&surface->destroy_signal,
4641 		      &sub->surface_destroy_listener);
4642 }
4643 
4644 static void
weston_subsurface_destroy(struct weston_subsurface * sub)4645 weston_subsurface_destroy(struct weston_subsurface *sub)
4646 {
4647 	struct weston_view *view, *next;
4648 
4649 	assert(sub->surface);
4650 
4651 	if (sub->resource) {
4652 		assert(weston_surface_to_subsurface(sub->surface) == sub);
4653 		assert(sub->parent_destroy_listener.notify ==
4654 		       subsurface_handle_parent_destroy);
4655 
4656 		wl_list_for_each_safe(view, next, &sub->surface->views, surface_link) {
4657 			weston_view_unmap(view);
4658 			weston_view_destroy(view);
4659 		}
4660 
4661 		if (sub->parent)
4662 			weston_subsurface_unlink_parent(sub);
4663 
4664 		weston_surface_state_fini(&sub->cached);
4665 		weston_buffer_reference(&sub->cached_buffer_ref, NULL);
4666 
4667 		sub->surface->committed = NULL;
4668 		sub->surface->committed_private = NULL;
4669 		weston_surface_set_label_func(sub->surface, NULL);
4670 	} else {
4671 		/* the dummy weston_subsurface for the parent itself */
4672 		assert(sub->parent_destroy_listener.notify == NULL);
4673 		wl_list_remove(&sub->parent_link);
4674 		wl_list_remove(&sub->parent_link_pending);
4675 	}
4676 
4677 	wl_list_remove(&sub->surface_destroy_listener.link);
4678 	free(sub);
4679 }
4680 
4681 static const struct wl_subsurface_interface subsurface_implementation = {
4682 	subsurface_destroy,
4683 	subsurface_set_position,
4684 	subsurface_place_above,
4685 	subsurface_place_below,
4686 	subsurface_set_sync,
4687 	subsurface_set_desync
4688 };
4689 
4690 static struct weston_subsurface *
weston_subsurface_create(uint32_t id,struct weston_surface * surface,struct weston_surface * parent)4691 weston_subsurface_create(uint32_t id, struct weston_surface *surface,
4692 			 struct weston_surface *parent)
4693 {
4694 	struct weston_subsurface *sub;
4695 	struct wl_client *client = wl_resource_get_client(surface->resource);
4696 
4697 	sub = zalloc(sizeof *sub);
4698 	if (sub == NULL)
4699 		return NULL;
4700 
4701 	wl_list_init(&sub->unused_views);
4702 
4703 	sub->resource =
4704 		wl_resource_create(client, &wl_subsurface_interface, 1, id);
4705 	if (!sub->resource) {
4706 		free(sub);
4707 		return NULL;
4708 	}
4709 
4710 	wl_resource_set_implementation(sub->resource,
4711 				       &subsurface_implementation,
4712 				       sub, subsurface_resource_destroy);
4713 	weston_subsurface_link_surface(sub, surface);
4714 	weston_subsurface_link_parent(sub, parent);
4715 	weston_surface_state_init(&sub->cached);
4716 	sub->cached_buffer_ref.buffer = NULL;
4717 	sub->synchronized = 1;
4718 
4719 	return sub;
4720 }
4721 
4722 /* Create a dummy subsurface for having the parent itself in its
4723  * sub-surface lists. Makes stacking order manipulation easy.
4724  */
4725 static struct weston_subsurface *
weston_subsurface_create_for_parent(struct weston_surface * parent)4726 weston_subsurface_create_for_parent(struct weston_surface *parent)
4727 {
4728 	struct weston_subsurface *sub;
4729 
4730 	sub = zalloc(sizeof *sub);
4731 	if (sub == NULL)
4732 		return NULL;
4733 
4734 	weston_subsurface_link_surface(sub, parent);
4735 	sub->parent = parent;
4736 	wl_list_insert(&parent->subsurface_list, &sub->parent_link);
4737 	wl_list_insert(&parent->subsurface_list_pending,
4738 		       &sub->parent_link_pending);
4739 
4740 	return sub;
4741 }
4742 
4743 static void
subcompositor_get_subsurface(struct wl_client * client,struct wl_resource * resource,uint32_t id,struct wl_resource * surface_resource,struct wl_resource * parent_resource)4744 subcompositor_get_subsurface(struct wl_client *client,
4745 			     struct wl_resource *resource,
4746 			     uint32_t id,
4747 			     struct wl_resource *surface_resource,
4748 			     struct wl_resource *parent_resource)
4749 {
4750 	struct weston_surface *surface =
4751 		wl_resource_get_user_data(surface_resource);
4752 	struct weston_surface *parent =
4753 		wl_resource_get_user_data(parent_resource);
4754 	struct weston_subsurface *sub;
4755 	static const char where[] = "get_subsurface: wl_subsurface@";
4756 
4757 	if (surface == parent) {
4758 		wl_resource_post_error(resource,
4759 			WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
4760 			"%s%d: wl_surface@%d cannot be its own parent",
4761 			where, id, wl_resource_get_id(surface_resource));
4762 		return;
4763 	}
4764 
4765 	if (weston_surface_to_subsurface(surface)) {
4766 		wl_resource_post_error(resource,
4767 			WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
4768 			"%s%d: wl_surface@%d is already a sub-surface",
4769 			where, id, wl_resource_get_id(surface_resource));
4770 		return;
4771 	}
4772 
4773 	if (weston_surface_set_role(surface, "wl_subsurface", resource,
4774 				    WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE) < 0)
4775 		return;
4776 
4777 	if (weston_surface_get_main_surface(parent) == surface) {
4778 		wl_resource_post_error(resource,
4779 			WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
4780 			"%s%d: wl_surface@%d is an ancestor of parent",
4781 			where, id, wl_resource_get_id(surface_resource));
4782 		return;
4783 	}
4784 
4785 	/* make sure the parent is in its own list */
4786 	if (wl_list_empty(&parent->subsurface_list)) {
4787 		if (!weston_subsurface_create_for_parent(parent)) {
4788 			wl_resource_post_no_memory(resource);
4789 			return;
4790 		}
4791 	}
4792 
4793 	sub = weston_subsurface_create(id, surface, parent);
4794 	if (!sub) {
4795 		wl_resource_post_no_memory(resource);
4796 		return;
4797 	}
4798 
4799 	surface->committed = subsurface_committed;
4800 	surface->committed_private = sub;
4801 	weston_surface_set_label_func(surface, subsurface_get_label);
4802 }
4803 
4804 static void
subcompositor_destroy(struct wl_client * client,struct wl_resource * resource)4805 subcompositor_destroy(struct wl_client *client, struct wl_resource *resource)
4806 {
4807 	wl_resource_destroy(resource);
4808 }
4809 
4810 static const struct wl_subcompositor_interface subcompositor_interface = {
4811 	subcompositor_destroy,
4812 	subcompositor_get_subsurface
4813 };
4814 
4815 static void
bind_subcompositor(struct wl_client * client,void * data,uint32_t version,uint32_t id)4816 bind_subcompositor(struct wl_client *client,
4817 		   void *data, uint32_t version, uint32_t id)
4818 {
4819 	struct weston_compositor *compositor = data;
4820 	struct wl_resource *resource;
4821 
4822 	resource =
4823 		wl_resource_create(client, &wl_subcompositor_interface, 1, id);
4824 	if (resource == NULL) {
4825 		wl_client_post_no_memory(client);
4826 		return;
4827 	}
4828 	wl_resource_set_implementation(resource, &subcompositor_interface,
4829 				       compositor, NULL);
4830 }
4831 
4832 /** Set a DPMS mode on all of the compositor's outputs
4833  *
4834  * \param compositor The compositor instance
4835  * \param state The DPMS state the outputs will be set to
4836  */
4837 static void
weston_compositor_dpms(struct weston_compositor * compositor,enum dpms_enum state)4838 weston_compositor_dpms(struct weston_compositor *compositor,
4839 		       enum dpms_enum state)
4840 {
4841         struct weston_output *output;
4842 
4843         wl_list_for_each(output, &compositor->output_list, link)
4844 		if (output->set_dpms)
4845 			output->set_dpms(output, state);
4846 }
4847 
4848 /** Restores the compositor to active status
4849  *
4850  * \param compositor The compositor instance
4851  *
4852  * If the compositor was in a sleeping mode, all outputs are powered
4853  * back on via DPMS.  Otherwise if the compositor was inactive
4854  * (idle/locked, offscreen, or sleeping) then the compositor's wake
4855  * signal will fire.
4856  *
4857  * Restarts the idle timer.
4858  * \ingroup compositor
4859  */
4860 WL_EXPORT void
weston_compositor_wake(struct weston_compositor * compositor)4861 weston_compositor_wake(struct weston_compositor *compositor)
4862 {
4863 	uint32_t old_state = compositor->state;
4864 
4865 	/* The state needs to be changed before emitting the wake
4866 	 * signal because that may try to schedule a repaint which
4867 	 * will not work if the compositor is still sleeping */
4868 	compositor->state = WESTON_COMPOSITOR_ACTIVE;
4869 
4870 	switch (old_state) {
4871 	case WESTON_COMPOSITOR_SLEEPING:
4872 	case WESTON_COMPOSITOR_IDLE:
4873 	case WESTON_COMPOSITOR_OFFSCREEN:
4874 		weston_compositor_dpms(compositor, WESTON_DPMS_ON);
4875 		wl_signal_emit(&compositor->wake_signal, compositor);
4876 		/* fall through */
4877 	default:
4878 		wl_event_source_timer_update(compositor->idle_source,
4879 					     compositor->idle_time * 1000);
4880 	}
4881 }
4882 
4883 /** Turns off rendering and frame events for the compositor.
4884  *
4885  * \param compositor The compositor instance
4886  *
4887  * This is used for example to prevent further rendering while the
4888  * compositor is shutting down.
4889  *
4890  * Stops the idle timer.
4891  *
4892  * \ingroup compositor
4893  */
4894 WL_EXPORT void
weston_compositor_offscreen(struct weston_compositor * compositor)4895 weston_compositor_offscreen(struct weston_compositor *compositor)
4896 {
4897 	switch (compositor->state) {
4898 	case WESTON_COMPOSITOR_OFFSCREEN:
4899 		return;
4900 	case WESTON_COMPOSITOR_SLEEPING:
4901 	default:
4902 		compositor->state = WESTON_COMPOSITOR_OFFSCREEN;
4903 		wl_event_source_timer_update(compositor->idle_source, 0);
4904 	}
4905 }
4906 
4907 /** Powers down all attached output devices
4908  *
4909  * \param compositor The compositor instance
4910  *
4911  * Causes rendering to the outputs to cease, and no frame events to be
4912  * sent.  Only powers down the outputs if the compositor is not already
4913  * in sleep mode.
4914  *
4915  * Stops the idle timer.
4916  *
4917  * \ingroup compositor
4918  */
4919 WL_EXPORT void
weston_compositor_sleep(struct weston_compositor * compositor)4920 weston_compositor_sleep(struct weston_compositor *compositor)
4921 {
4922 	if (compositor->state == WESTON_COMPOSITOR_SLEEPING)
4923 		return;
4924 
4925 	wl_event_source_timer_update(compositor->idle_source, 0);
4926 	compositor->state = WESTON_COMPOSITOR_SLEEPING;
4927 	weston_compositor_dpms(compositor, WESTON_DPMS_OFF);
4928 }
4929 
4930 /** Sets compositor to idle mode
4931  *
4932  * \param data The compositor instance
4933  *
4934  * This is called when the idle timer fires.  Once the compositor is in
4935  * idle mode it requires a wake action (e.g. via
4936  * weston_compositor_wake()) to restore it.  The compositor's
4937  * idle_signal will be triggered when the idle event occurs.
4938  *
4939  * Idleness can be inhibited by setting the compositor's idle_inhibit
4940  * property.
4941  */
4942 static int
idle_handler(void * data)4943 idle_handler(void *data)
4944 {
4945 	struct weston_compositor *compositor = data;
4946 
4947 	if (compositor->idle_inhibit)
4948 		return 1;
4949 
4950 	compositor->state = WESTON_COMPOSITOR_IDLE;
4951 	wl_signal_emit(&compositor->idle_signal, compositor);
4952 
4953 	return 1;
4954 }
4955 
4956 WL_EXPORT void
weston_plane_init(struct weston_plane * plane,struct weston_compositor * ec,int32_t x,int32_t y)4957 weston_plane_init(struct weston_plane *plane,
4958 			struct weston_compositor *ec,
4959 			int32_t x, int32_t y)
4960 {
4961 	pixman_region32_init(&plane->damage);
4962 	pixman_region32_init(&plane->clip);
4963 	plane->x = x;
4964 	plane->y = y;
4965 	plane->compositor = ec;
4966 
4967 	/* Init the link so that the call to wl_list_remove() when releasing
4968 	 * the plane without ever stacking doesn't lead to a crash */
4969 	wl_list_init(&plane->link);
4970 }
4971 
4972 WL_EXPORT void
weston_plane_release(struct weston_plane * plane)4973 weston_plane_release(struct weston_plane *plane)
4974 {
4975 	struct weston_view *view;
4976 
4977 	pixman_region32_fini(&plane->damage);
4978 	pixman_region32_fini(&plane->clip);
4979 
4980 	wl_list_for_each(view, &plane->compositor->view_list, link) {
4981 		if (view->plane == plane)
4982 			view->plane = NULL;
4983 	}
4984 
4985 	wl_list_remove(&plane->link);
4986 }
4987 
4988 /** weston_compositor_stack_plane
4989  * \ingroup compositor
4990  */
4991 WL_EXPORT void
weston_compositor_stack_plane(struct weston_compositor * ec,struct weston_plane * plane,struct weston_plane * above)4992 weston_compositor_stack_plane(struct weston_compositor *ec,
4993 			      struct weston_plane *plane,
4994 			      struct weston_plane *above)
4995 {
4996 	if (above)
4997 		wl_list_insert(above->link.prev, &plane->link);
4998 	else
4999 		wl_list_insert(&ec->plane_list, &plane->link);
5000 }
5001 
5002 static void
output_release(struct wl_client * client,struct wl_resource * resource)5003 output_release(struct wl_client *client, struct wl_resource *resource)
5004 {
5005 	wl_resource_destroy(resource);
5006 }
5007 
5008 static const struct wl_output_interface output_interface = {
5009 	output_release,
5010 };
5011 
5012 
unbind_resource(struct wl_resource * resource)5013 static void unbind_resource(struct wl_resource *resource)
5014 {
5015 	wl_list_remove(wl_resource_get_link(resource));
5016 }
5017 
5018 static void
bind_output(struct wl_client * client,void * data,uint32_t version,uint32_t id)5019 bind_output(struct wl_client *client,
5020 	    void *data, uint32_t version, uint32_t id)
5021 {
5022 	struct weston_head *head = data;
5023 	struct weston_output *output = head->output;
5024 	struct weston_mode *mode;
5025 	struct wl_resource *resource;
5026 
5027 	resource = wl_resource_create(client, &wl_output_interface,
5028 				      version, id);
5029 	if (resource == NULL) {
5030 		wl_client_post_no_memory(client);
5031 		return;
5032 	}
5033 
5034 	wl_list_insert(&head->resource_list, wl_resource_get_link(resource));
5035 	wl_resource_set_implementation(resource, &output_interface, head,
5036 				       unbind_resource);
5037 
5038 	assert(output);
5039 	wl_output_send_geometry(resource,
5040 				output->x,
5041 				output->y,
5042 				head->mm_width,
5043 				head->mm_height,
5044 				head->subpixel,
5045 				head->make, head->model,
5046 				output->transform);
5047 	if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
5048 		wl_output_send_scale(resource,
5049 				     output->current_scale);
5050 
5051 	wl_list_for_each (mode, &output->mode_list, link) {
5052 		wl_output_send_mode(resource,
5053 				    mode->flags,
5054 				    mode->width,
5055 				    mode->height,
5056 				    mode->refresh);
5057 	}
5058 
5059 	if (version >= WL_OUTPUT_DONE_SINCE_VERSION)
5060 		wl_output_send_done(resource);
5061 }
5062 
5063 static void
weston_head_add_global(struct weston_head * head)5064 weston_head_add_global(struct weston_head *head)
5065 {
5066 	head->global = wl_global_create(head->compositor->wl_display,
5067 					&wl_output_interface, 3,
5068 					head, bind_output);
5069 }
5070 
5071 /** Remove the global wl_output protocol object
5072  *
5073  * \param head The head whose global to remove.
5074  *
5075  * Also orphans the wl_resources for this head (wl_output).
5076  */
5077 static void
weston_head_remove_global(struct weston_head * head)5078 weston_head_remove_global(struct weston_head *head)
5079 {
5080 	struct wl_resource *resource, *tmp;
5081 
5082 	if (head->global)
5083 		wl_global_destroy(head->global);
5084 	head->global = NULL;
5085 
5086 	wl_resource_for_each_safe(resource, tmp, &head->resource_list) {
5087 		unbind_resource(resource);
5088 		wl_resource_set_destructor(resource, NULL);
5089 		wl_resource_set_user_data(resource, NULL);
5090 	}
5091 
5092 	wl_resource_for_each(resource, &head->xdg_output_resource_list) {
5093 		/* It's sufficient to unset the destructor, then the list elements
5094 		 * won't be accessed.
5095 		 */
5096 		wl_resource_set_destructor(resource, NULL);
5097 	}
5098 	wl_list_init(&head->xdg_output_resource_list);
5099 }
5100 
5101 /** Get the backing object of wl_output
5102  *
5103  * \param resource A wl_output protocol object.
5104  * \return The backing object (user data) of a wl_resource representing a
5105  * wl_output protocol object.
5106  *
5107  * \ingroup head
5108  */
5109 WL_EXPORT struct weston_head *
weston_head_from_resource(struct wl_resource * resource)5110 weston_head_from_resource(struct wl_resource *resource)
5111 {
5112 	assert(wl_resource_instance_of(resource, &wl_output_interface,
5113 				       &output_interface));
5114 
5115 	return wl_resource_get_user_data(resource);
5116 }
5117 
5118 /** Initialize a pre-allocated weston_head
5119  *
5120  * \param head The head to initialize.
5121  * \param name The head name, e.g. the connector name or equivalent.
5122  *
5123  * The head will be safe to attach, detach and release.
5124  *
5125  * The name is used in logs, and can be used by compositors as a configuration
5126  * identifier.
5127  *
5128  * \ingroup head
5129  * \internal
5130  */
5131 WL_EXPORT void
weston_head_init(struct weston_head * head,const char * name)5132 weston_head_init(struct weston_head *head, const char *name)
5133 {
5134 	/* Add some (in)sane defaults which can be used
5135 	 * for checking if an output was properly configured
5136 	 */
5137 	memset(head, 0, sizeof *head);
5138 
5139 	wl_list_init(&head->compositor_link);
5140 	wl_signal_init(&head->destroy_signal);
5141 	wl_list_init(&head->output_link);
5142 	wl_list_init(&head->resource_list);
5143 	wl_list_init(&head->xdg_output_resource_list);
5144 	head->name = strdup(name);
5145 	head->current_protection = WESTON_HDCP_DISABLE;
5146 }
5147 
5148 /** Send output heads changed signal
5149  *
5150  * \param output The output that changed.
5151  *
5152  * Notify that the enabled output gained and/or lost heads, or that the
5153  * associated heads may have changed their connection status. This does not
5154  * include cases where the output becomes enabled or disabled. The registered
5155  * callbacks are called after the change has successfully happened.
5156  *
5157  * If connection status change causes the compositor to attach or detach a head
5158  * to an enabled output, the registered callbacks may be called multiple times.
5159  *
5160  * \ingroup output
5161  */
5162 static void
weston_output_emit_heads_changed(struct weston_output * output)5163 weston_output_emit_heads_changed(struct weston_output *output)
5164 {
5165 	wl_signal_emit(&output->compositor->output_heads_changed_signal,
5166 		       output);
5167 }
5168 
5169 /** Idle task for emitting heads_changed_signal */
5170 static void
weston_compositor_call_heads_changed(void * data)5171 weston_compositor_call_heads_changed(void *data)
5172 {
5173 	struct weston_compositor *compositor = data;
5174 	struct weston_head *head;
5175 
5176 	compositor->heads_changed_source = NULL;
5177 
5178 	wl_signal_emit(&compositor->heads_changed_signal, compositor);
5179 
5180 	wl_list_for_each(head, &compositor->head_list, compositor_link) {
5181 		if (head->output && head->output->enabled)
5182 			weston_output_emit_heads_changed(head->output);
5183 	}
5184 }
5185 
5186 /** Schedule a call on idle to heads_changed callback
5187  *
5188  * \param compositor The Compositor.
5189  *
5190  * \ingroup compositor
5191  * \internal
5192  */
5193 static void
weston_compositor_schedule_heads_changed(struct weston_compositor * compositor)5194 weston_compositor_schedule_heads_changed(struct weston_compositor *compositor)
5195 {
5196 	struct wl_event_loop *loop;
5197 
5198 	if (compositor->heads_changed_source)
5199 		return;
5200 
5201 	loop = wl_display_get_event_loop(compositor->wl_display);
5202 	compositor->heads_changed_source = wl_event_loop_add_idle(loop,
5203 			weston_compositor_call_heads_changed, compositor);
5204 }
5205 
5206 /** Register a new head
5207  *
5208  * \param compositor The compositor.
5209  * \param head The head to register, must not be already registered.
5210  *
5211  * This signals the core that a new head has become available, leading to
5212  * heads_changed hook being called later.
5213  *
5214  * \ingroup compositor
5215  * \internal
5216  */
5217 WL_EXPORT void
weston_compositor_add_head(struct weston_compositor * compositor,struct weston_head * head)5218 weston_compositor_add_head(struct weston_compositor *compositor,
5219 			   struct weston_head *head)
5220 {
5221 	assert(wl_list_empty(&head->compositor_link));
5222 	assert(head->name);
5223 
5224 	wl_list_insert(compositor->head_list.prev, &head->compositor_link);
5225 	head->compositor = compositor;
5226 	weston_compositor_schedule_heads_changed(compositor);
5227 }
5228 
5229 /** Adds a listener to be called when heads change
5230  *
5231  * \param compositor The compositor.
5232  * \param listener The listener to add.
5233  *
5234  * The listener notify function argument is weston_compositor.
5235  *
5236  * The listener function will be called after heads are added or their
5237  * connection status has changed. Several changes may be accumulated into a
5238  * single call. The user is expected to iterate over the existing heads and
5239  * check their statuses to find out what changed.
5240  *
5241  * \sa weston_compositor_iterate_heads, weston_head_is_connected,
5242  * weston_head_is_enabled
5243  * \ingroup compositor
5244  */
5245 WL_EXPORT void
weston_compositor_add_heads_changed_listener(struct weston_compositor * compositor,struct wl_listener * listener)5246 weston_compositor_add_heads_changed_listener(struct weston_compositor *compositor,
5247 					     struct wl_listener *listener)
5248 {
5249 	wl_signal_add(&compositor->heads_changed_signal, listener);
5250 }
5251 
5252 /** Iterate over available heads
5253  *
5254  * \param compositor The compositor.
5255  * \param iter The iterator, or NULL for start.
5256  * \return The next available head in the list.
5257  *
5258  * Returns all available heads, regardless of being connected or enabled.
5259  *
5260  * You can iterate over all heads as follows:
5261  * \code
5262  * struct weston_head *head = NULL;
5263  *
5264  * while ((head = weston_compositor_iterate_heads(compositor, head))) {
5265  * 	...
5266  * }
5267  * \endcode
5268  *
5269  *  If you cause \c iter to be removed from the list, you cannot use it to
5270  * continue iterating. Removing any other item is safe.
5271  *
5272  * \ingroup compositor
5273  */
5274 WL_EXPORT struct weston_head *
weston_compositor_iterate_heads(struct weston_compositor * compositor,struct weston_head * iter)5275 weston_compositor_iterate_heads(struct weston_compositor *compositor,
5276 				struct weston_head *iter)
5277 {
5278 	struct wl_list *list = &compositor->head_list;
5279 	struct wl_list *node;
5280 
5281 	assert(compositor);
5282 	assert(!iter || iter->compositor == compositor);
5283 
5284 	if (iter)
5285 		node = iter->compositor_link.next;
5286 	else
5287 		node = list->next;
5288 
5289 	assert(node);
5290 	assert(!iter || node != &iter->compositor_link);
5291 
5292 	if (node == list)
5293 		return NULL;
5294 
5295 	return container_of(node, struct weston_head, compositor_link);
5296 }
5297 
5298 /** Iterate over attached heads
5299  *
5300  * \param output The output whose heads to iterate.
5301  * \param iter The iterator, or NULL for start.
5302  * \return The next attached head in the list.
5303  *
5304  * Returns all heads currently attached to the output.
5305  *
5306  * You can iterate over all heads as follows:
5307  * \code
5308  * struct weston_head *head = NULL;
5309  *
5310  * while ((head = weston_output_iterate_heads(output, head))) {
5311  * 	...
5312  * }
5313  * \endcode
5314  *
5315  *  If you cause \c iter to be removed from the list, you cannot use it to
5316  * continue iterating. Removing any other item is safe.
5317  *
5318  * \ingroup ouput
5319  */
5320 WL_EXPORT struct weston_head *
weston_output_iterate_heads(struct weston_output * output,struct weston_head * iter)5321 weston_output_iterate_heads(struct weston_output *output,
5322 			    struct weston_head *iter)
5323 {
5324 	struct wl_list *list = &output->head_list;
5325 	struct wl_list *node;
5326 
5327 	assert(output);
5328 	assert(!iter || iter->output == output);
5329 
5330 	if (iter)
5331 		node = iter->output_link.next;
5332 	else
5333 		node = list->next;
5334 
5335 	assert(node);
5336 	assert(!iter || node != &iter->output_link);
5337 
5338 	if (node == list)
5339 		return NULL;
5340 
5341 	return container_of(node, struct weston_head, output_link);
5342 }
5343 
5344 /** Attach a head to an output
5345  *
5346  * \param output The output to attach to.
5347  * \param head The head that is not yet attached.
5348  * \return 0 on success, -1 on failure.
5349  *
5350  * Attaches the given head to the output. All heads of an output are clones
5351  * and share the resolution and timings.
5352  *
5353  * Cloning heads this way uses less resources than creating an output for
5354  * each head, but is not always possible due to environment, driver and hardware
5355  * limitations.
5356  *
5357  * On failure, the head remains unattached. Success of this function does not
5358  * guarantee the output configuration is actually valid. The final checks are
5359  * made on weston_output_enable() unless the output was already enabled.
5360  *
5361  * \ingroup output
5362  */
5363 WL_EXPORT int
weston_output_attach_head(struct weston_output * output,struct weston_head * head)5364 weston_output_attach_head(struct weston_output *output,
5365 			  struct weston_head *head)
5366 {
5367     LOG_ENTER();
5368 	char *head_names;
5369 
5370 	if (!wl_list_empty(&head->output_link)) {
5371         LOG_ERROR("head already have output");
5372         LOG_EXIT();
5373 		return -1;
5374     }
5375 
5376 	if (output->attach_head) {
5377 		if (output->attach_head(output, head) < 0) {
5378             LOG_ERROR("this->attach_head(head) failed");
5379             LOG_EXIT();
5380 			return -1;
5381         }
5382 	} else if (!wl_list_empty(&output->head_list)) {
5383 		/* No support for clones in the legacy path. */
5384         LOG_ERROR("output already have head");
5385         LOG_EXIT();
5386 		return -1;
5387 	}
5388 
5389 	head->output = output;
5390     LOG_INFO("this->head_list.push_back(head)");
5391 	wl_list_insert(output->head_list.prev, &head->output_link);
5392 
5393 	if (output->enabled) {
5394 		weston_head_add_global(head);
5395 
5396 		head_names = weston_output_create_heads_string(output);
5397 		weston_log("Output '%s' updated to have head(s) %s\n",
5398 			   output->name, head_names);
5399 		free(head_names);
5400 
5401 		weston_output_emit_heads_changed(output);
5402 	}
5403 
5404     LOG_EXIT();
5405 	return 0;
5406 }
5407 
5408 /** Detach a head from its output
5409  *
5410  * \param head The head to detach.
5411  *
5412  * It is safe to detach a non-attached head.
5413  *
5414  * If the head is attached to an enabled output and the output will be left
5415  * with no heads, the output will be disabled.
5416  *
5417  * \ingroup head
5418  * \sa weston_output_disable
5419  */
5420 WL_EXPORT void
weston_head_detach(struct weston_head * head)5421 weston_head_detach(struct weston_head *head)
5422 {
5423 	struct weston_output *output = head->output;
5424 	char *head_names;
5425 
5426 	wl_list_remove(&head->output_link);
5427 	wl_list_init(&head->output_link);
5428 	head->output = NULL;
5429 
5430 	if (!output)
5431 		return;
5432 
5433 	if (output->detach_head)
5434 		output->detach_head(output, head);
5435 
5436 	if (output->enabled) {
5437 		weston_head_remove_global(head);
5438 
5439 		if (wl_list_empty(&output->head_list)) {
5440 			weston_log("Output '%s' no heads left, disabling.\n",
5441 				   output->name);
5442 			weston_output_disable(output);
5443 		} else {
5444 			head_names = weston_output_create_heads_string(output);
5445 			weston_log("Output '%s' updated to have head(s) %s\n",
5446 				   output->name, head_names);
5447 			free(head_names);
5448 
5449 			weston_output_emit_heads_changed(output);
5450 		}
5451 	}
5452 }
5453 
5454 /** Destroy a head
5455  *
5456  * \param head The head to be released.
5457  *
5458  * Destroys the head. The caller is responsible for freeing the memory pointed
5459  * to by \c head.
5460  *
5461  * \ingroup head
5462  * \internal
5463  */
5464 WL_EXPORT void
weston_head_release(struct weston_head * head)5465 weston_head_release(struct weston_head *head)
5466 {
5467 	wl_signal_emit(&head->destroy_signal, head);
5468 
5469 	weston_head_detach(head);
5470 
5471 	free(head->make);
5472 	free(head->model);
5473 	free(head->serial_number);
5474 	free(head->name);
5475 
5476 	wl_list_remove(&head->compositor_link);
5477 }
5478 
5479 static void
weston_head_set_device_changed(struct weston_head * head)5480 weston_head_set_device_changed(struct weston_head *head)
5481 {
5482 	head->device_changed = true;
5483 
5484 	if (head->compositor)
5485 		weston_compositor_schedule_heads_changed(head->compositor);
5486 }
5487 
5488 /** String equal comparison with NULLs being equal */
5489 static bool
str_null_eq(const char * a,const char * b)5490 str_null_eq(const char *a, const char *b)
5491 {
5492 	if (!a && !b)
5493 		return true;
5494 
5495 	if (!!a != !!b)
5496 		return false;
5497 
5498 	return strcmp(a, b) == 0;
5499 }
5500 
5501 /** Store monitor make, model and serial number
5502  *
5503  * \param head The head to modify.
5504  * \param make The monitor make. If EDID is available, the PNP ID. Otherwise
5505  * any string, or NULL for none.
5506  * \param model The monitor model or name, or a made-up string, or NULL for
5507  * none.
5508  * \param serialno The monitor serial number, a made-up string, or NULL for
5509  * none.
5510  *
5511  * This may set the device_changed flag.
5512  *
5513  * \ingroup head
5514  * \internal
5515  */
5516 WL_EXPORT void
weston_head_set_monitor_strings(struct weston_head * head,const char * make,const char * model,const char * serialno)5517 weston_head_set_monitor_strings(struct weston_head *head,
5518 				const char *make,
5519 				const char *model,
5520 				const char *serialno)
5521 {
5522 	if (str_null_eq(head->make, make) &&
5523 	    str_null_eq(head->model, model) &&
5524 	    str_null_eq(head->serial_number, serialno))
5525 		return;
5526 
5527 	free(head->make);
5528 	free(head->model);
5529 	free(head->serial_number);
5530 
5531 	head->make = make ? strdup(make) : NULL;
5532 	head->model = model ? strdup(model) : NULL;
5533 	head->serial_number = serialno ? strdup(serialno) : NULL;
5534 
5535 	weston_head_set_device_changed(head);
5536 }
5537 
5538 /** Store display non-desktop status
5539  *
5540  * \param head The head to modify.
5541  * \param non_desktop Whether the head connects to a non-desktop display.
5542  *
5543  * \ingroup head
5544  * \internal
5545  */
5546 WL_EXPORT void
weston_head_set_non_desktop(struct weston_head * head,bool non_desktop)5547 weston_head_set_non_desktop(struct weston_head *head, bool non_desktop)
5548 {
5549 	if (head->non_desktop == non_desktop)
5550 		return;
5551 
5552 	head->non_desktop = non_desktop;
5553 
5554 	weston_head_set_device_changed(head);
5555 }
5556 
5557 /** Store display transformation
5558  *
5559  * \param head The head to modify.
5560  * \param transform The transformation to apply for this head
5561  *
5562  * This may set the device_changed flag.
5563  *
5564  * \ingroup head
5565  * \internal
5566  */
5567 WL_EXPORT void
weston_head_set_transform(struct weston_head * head,uint32_t transform)5568 weston_head_set_transform(struct weston_head *head, uint32_t transform)
5569 {
5570 	if (head->transform == transform)
5571 		return;
5572 
5573 	head->transform = transform;
5574 
5575 	weston_head_set_device_changed(head);
5576 }
5577 
5578 
5579 /** Store physical image size
5580  *
5581  * \param head The head to modify.
5582  * \param mm_width Image area width in millimeters.
5583  * \param mm_height Image area height in millimeters.
5584  *
5585  * This may set the device_changed flag.
5586  *
5587  * \ingroup head
5588  * \internal
5589  */
5590 WL_EXPORT void
weston_head_set_physical_size(struct weston_head * head,int32_t mm_width,int32_t mm_height)5591 weston_head_set_physical_size(struct weston_head *head,
5592 			      int32_t mm_width, int32_t mm_height)
5593 {
5594 	if (head->mm_width == mm_width &&
5595 	    head->mm_height == mm_height)
5596 		return;
5597 
5598 	head->mm_width = mm_width;
5599 	head->mm_height = mm_height;
5600 
5601 	weston_head_set_device_changed(head);
5602 }
5603 
5604 /** Store monitor sub-pixel layout
5605  *
5606  * \param head The head to modify.
5607  * \param sp Sub-pixel layout. The possible values are:
5608  * - WL_OUTPUT_SUBPIXEL_UNKNOWN,
5609  * - WL_OUTPUT_SUBPIXEL_NONE,
5610  * - WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB,
5611  * - WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR,
5612  * - WL_OUTPUT_SUBPIXEL_VERTICAL_RGB,
5613  * - WL_OUTPUT_SUBPIXEL_VERTICAL_BGR
5614  *
5615  * This may set the device_changed flag.
5616  *
5617  * \ingroup head
5618  * \internal
5619  */
5620 WL_EXPORT void
weston_head_set_subpixel(struct weston_head * head,enum wl_output_subpixel sp)5621 weston_head_set_subpixel(struct weston_head *head,
5622 			 enum wl_output_subpixel sp)
5623 {
5624 	if (head->subpixel == sp)
5625 		return;
5626 
5627 	head->subpixel = sp;
5628 
5629 	weston_head_set_device_changed(head);
5630 }
5631 
5632 /** Mark the monitor as internal
5633  *
5634  * This is used for embedded screens, like laptop panels.
5635  *
5636  * \param head The head to mark as internal.
5637  *
5638  * By default a head is external. The type is often inferred from the physical
5639  * connector type.
5640  *
5641  * \ingroup head
5642  * \internal
5643  */
5644 WL_EXPORT void
weston_head_set_internal(struct weston_head * head)5645 weston_head_set_internal(struct weston_head *head)
5646 {
5647 	head->connection_internal = true;
5648 }
5649 
5650 /** Store connector status
5651  *
5652  * \param head The head to modify.
5653  * \param connected Whether the head is connected.
5654  *
5655  * Connectors are created as disconnected. This function can be used to
5656  * set the connector status.
5657  *
5658  * The status should be set to true when a physical connector is connected to
5659  * a video sink device like a monitor and to false when the connector is
5660  * disconnected. For nested backends, the connection status should reflect the
5661  * connection to the parent display server.
5662  *
5663  * When the connection status changes, it schedules a call to the heads_changed
5664  * hook and sets the device_changed flag.
5665  *
5666  * \sa weston_compositor_set_heads_changed_cb
5667  * \ingroup head
5668  * \internal
5669  */
5670 WL_EXPORT void
weston_head_set_connection_status(struct weston_head * head,bool connected)5671 weston_head_set_connection_status(struct weston_head *head, bool connected)
5672 {
5673 	if (head->connected == connected)
5674 		return;
5675 
5676 	head->connected = connected;
5677 
5678 	weston_head_set_device_changed(head);
5679 }
5680 
5681 static void
weston_output_compute_protection(struct weston_output * output)5682 weston_output_compute_protection(struct weston_output *output)
5683 {
5684 	struct weston_head *head;
5685 	enum weston_hdcp_protection op_protection;
5686 	bool op_protection_valid = false;
5687 	struct weston_compositor *wc = output->compositor;
5688 
5689 	wl_list_for_each(head, &output->head_list, output_link) {
5690 		if (!op_protection_valid) {
5691 			op_protection = head->current_protection;
5692 			op_protection_valid = true;
5693 		}
5694 		if (head->current_protection < op_protection)
5695 			op_protection = head->current_protection;
5696 	}
5697 
5698 	if (!op_protection_valid)
5699 		op_protection = WESTON_HDCP_DISABLE;
5700 
5701 	if (output->current_protection != op_protection) {
5702 		output->current_protection = op_protection;
5703 		weston_output_damage(output);
5704 		weston_schedule_surface_protection_update(wc);
5705 	}
5706 }
5707 
5708 WL_EXPORT void
weston_head_set_content_protection_status(struct weston_head * head,enum weston_hdcp_protection status)5709 weston_head_set_content_protection_status(struct weston_head *head,
5710 					  enum weston_hdcp_protection status)
5711 {
5712 	head->current_protection = status;
5713 	if (head->output)
5714 		weston_output_compute_protection(head->output);
5715 }
5716 
5717 /** Is the head currently connected?
5718  *
5719  * \param head The head to query.
5720  * \return Connection status.
5721  *
5722  * Returns true if the head is physically connected to a monitor, or in
5723  * case of a nested backend returns true when there is a connection to the
5724  * parent display server.
5725  *
5726  * This is independent from the head being enabled.
5727  *
5728  * \sa weston_head_is_enabled
5729  * \ingroup head
5730  */
5731 WL_EXPORT bool
weston_head_is_connected(struct weston_head * head)5732 weston_head_is_connected(struct weston_head *head)
5733 {
5734 	return head->connected;
5735 }
5736 
5737 /** Is the head currently enabled?
5738  *
5739  * \param head The head to query.
5740  * \return Video status.
5741  *
5742  * Returns true if the head is currently transmitting a video stream.
5743  *
5744  * This is independent of the head being connected.
5745  *
5746  * \sa weston_head_is_connected
5747  * \ingroup head
5748  */
5749 WL_EXPORT bool
weston_head_is_enabled(struct weston_head * head)5750 weston_head_is_enabled(struct weston_head *head)
5751 {
5752 	if (!head->output)
5753 		return false;
5754 
5755 	return head->output->enabled;
5756 }
5757 
5758 /** Has the device information changed?
5759  *
5760  * \param head The head to query.
5761  * \return True if the device information has changed since last reset.
5762  *
5763  * The information about the connected display device, e.g. a monitor, may
5764  * change without being disconnected in between. Changing information
5765  * causes a call to the heads_changed hook.
5766  *
5767  * The information includes make, model, serial number, physical size,
5768  * and sub-pixel type. The connection status is also included.
5769  *
5770  * \sa weston_head_reset_device_changed, weston_compositor_set_heads_changed_cb
5771  * \ingroup head
5772  */
5773 WL_EXPORT bool
weston_head_is_device_changed(struct weston_head * head)5774 weston_head_is_device_changed(struct weston_head *head)
5775 {
5776 	return head->device_changed;
5777 }
5778 
5779 /** Does the head represent a non-desktop display?
5780  *
5781  * \param head The head to query.
5782  * \return True if the device is a non-desktop display.
5783  *
5784  * Non-desktop heads are not attached to outputs by default.
5785  * This stops weston from extending the desktop onto head mounted displays.
5786  *
5787  * \ingroup head
5788  */
5789 WL_EXPORT bool
weston_head_is_non_desktop(struct weston_head * head)5790 weston_head_is_non_desktop(struct weston_head *head)
5791 {
5792 	return head->non_desktop;
5793 }
5794 
5795 /** Acknowledge device information change
5796  *
5797  * \param head The head to acknowledge.
5798  *
5799  * Clears the device changed flag on this head. When a compositor has processed
5800  * device information, it should call this to be able to notice further
5801  * changes.
5802  *
5803  * \sa weston_head_is_device_changed
5804  * \ingroup head
5805  */
5806 WL_EXPORT void
weston_head_reset_device_changed(struct weston_head * head)5807 weston_head_reset_device_changed(struct weston_head *head)
5808 {
5809 	head->device_changed = false;
5810 }
5811 
5812 /** Get the name of a head
5813  *
5814  * \param head The head to query.
5815  * \return The head's name, not NULL.
5816  *
5817  * The name depends on the backend. The DRM backend uses connector names,
5818  * other backends may use hardcoded names or user-given names.
5819  *
5820  * \ingroup head
5821  */
5822 WL_EXPORT const char *
weston_head_get_name(struct weston_head * head)5823 weston_head_get_name(struct weston_head *head)
5824 {
5825 	return head->name;
5826 }
5827 
5828 /** Get the output the head is attached to
5829  *
5830  * \param head The head to query.
5831  * \return The output the head is attached to, or NULL if detached.
5832  * \ingroup head
5833  */
5834 WL_EXPORT struct weston_output *
weston_head_get_output(struct weston_head * head)5835 weston_head_get_output(struct weston_head *head)
5836 {
5837 	return head->output;
5838 }
5839 
5840 /** Get the head's native transformation
5841  *
5842  * \param head The head to query.
5843  * \return The head's native transform, as a WL_OUTPUT_TRANSFORM_* value
5844  *
5845  * A weston_head may have a 'native' transform provided by the backend.
5846  * Examples include panels which are physically rotated, where the rotation
5847  * is recorded and described as part of the system configuration. This call
5848  * will return any known native transform for the head.
5849  *
5850  * \ingroup head
5851  */
5852 WL_EXPORT uint32_t
weston_head_get_transform(struct weston_head * head)5853 weston_head_get_transform(struct weston_head *head)
5854 {
5855 	return head->transform;
5856 }
5857 
5858 /** Add destroy callback for a head
5859  *
5860  * \param head The head to watch for.
5861  * \param listener The listener to add. The \c notify member must be set.
5862  *
5863  * Heads may get destroyed for various reasons by the backends. If a head is
5864  * attached to an output, the compositor should listen for head destruction
5865  * and reconfigure or destroy the output if necessary.
5866  *
5867  * The destroy callbacks will be called on weston_head destruction before any
5868  * automatic detaching from an associated weston_output and before any
5869  * weston_head information is lost.
5870  *
5871  * The \c data argument to the notify callback is the weston_head being
5872  * destroyed.
5873  *
5874  * \ingroup head
5875  */
5876 WL_EXPORT void
weston_head_add_destroy_listener(struct weston_head * head,struct wl_listener * listener)5877 weston_head_add_destroy_listener(struct weston_head *head,
5878 				 struct wl_listener *listener)
5879 {
5880 	wl_signal_add(&head->destroy_signal, listener);
5881 }
5882 
5883 /** Look up destroy listener for a head
5884  *
5885  * \param head The head to query.
5886  * \param notify The notify function used used for the added destroy listener.
5887  * \return The listener, or NULL if not found.
5888  *
5889  * This looks up the previously added destroy listener struct based on the
5890  * notify function it has. The listener can be used to access user data
5891  * through \c container_of().
5892  *
5893  * \sa wl_signal_get()
5894  * \ingroup head
5895  */
5896 WL_EXPORT struct wl_listener *
weston_head_get_destroy_listener(struct weston_head * head,wl_notify_func_t notify)5897 weston_head_get_destroy_listener(struct weston_head *head,
5898 				 wl_notify_func_t notify)
5899 {
5900 	return wl_signal_get(&head->destroy_signal, notify);
5901 }
5902 
5903 /* Move other outputs when one is resized so the space remains contiguous. */
5904 static void
weston_compositor_reflow_outputs(struct weston_compositor * compositor,struct weston_output * resized_output,int delta_width)5905 weston_compositor_reflow_outputs(struct weston_compositor *compositor,
5906 				struct weston_output *resized_output, int delta_width)
5907 {
5908 	struct weston_output *output;
5909 	bool start_resizing = false;
5910 
5911 	if (!delta_width)
5912 		return;
5913 
5914 	wl_list_for_each(output, &compositor->output_list, link) {
5915 		if (output == resized_output) {
5916 			start_resizing = true;
5917 			continue;
5918 		}
5919 
5920 		if (start_resizing) {
5921 			weston_output_move(output, output->x + delta_width, output->y);
5922 			output->dirty = 1;
5923 		}
5924 	}
5925 }
5926 
5927 static void
weston_output_update_matrix(struct weston_output * output)5928 weston_output_update_matrix(struct weston_output *output)
5929 {
5930 	float magnification;
5931 
5932 	weston_matrix_init(&output->matrix);
5933 	weston_matrix_translate(&output->matrix, -output->x, -output->y, 0);
5934 
5935 	if (output->zoom.active) {
5936 		magnification = 1 / (1 - output->zoom.spring_z.current);
5937 		weston_output_update_zoom(output);
5938 		weston_matrix_translate(&output->matrix, -output->zoom.trans_x,
5939 					-output->zoom.trans_y, 0);
5940 		weston_matrix_scale(&output->matrix, magnification,
5941 				    magnification, 1.0);
5942 	}
5943 
5944 	switch (output->transform) {
5945 	case WL_OUTPUT_TRANSFORM_FLIPPED:
5946 	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
5947 	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
5948 	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
5949 		weston_matrix_translate(&output->matrix, -output->width, 0, 0);
5950 		weston_matrix_scale(&output->matrix, -1, 1, 1);
5951 		break;
5952 	}
5953 
5954 	switch (output->transform) {
5955 	default:
5956 	case WL_OUTPUT_TRANSFORM_NORMAL:
5957 	case WL_OUTPUT_TRANSFORM_FLIPPED:
5958 		break;
5959 	case WL_OUTPUT_TRANSFORM_90:
5960 	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
5961 		weston_matrix_translate(&output->matrix, -output->width, 0, 0);
5962 		weston_matrix_rotate_xy(&output->matrix, 0, -1);
5963 		break;
5964 	case WL_OUTPUT_TRANSFORM_180:
5965 	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
5966 		weston_matrix_translate(&output->matrix,
5967 					-output->width, -output->height, 0);
5968 		weston_matrix_rotate_xy(&output->matrix, -1, 0);
5969 		break;
5970 	case WL_OUTPUT_TRANSFORM_270:
5971 	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
5972 		weston_matrix_translate(&output->matrix, 0, -output->height, 0);
5973 		weston_matrix_rotate_xy(&output->matrix, 0, 1);
5974 		break;
5975 	}
5976 
5977 	if (output->current_scale != 1)
5978 		weston_matrix_scale(&output->matrix,
5979 				    output->current_scale,
5980 				    output->current_scale, 1);
5981 
5982 	output->dirty = 0;
5983 
5984 	weston_matrix_invert(&output->inverse_matrix, &output->matrix);
5985 }
5986 
5987 static void
weston_output_transform_scale_init(struct weston_output * output,uint32_t transform,uint32_t scale)5988 weston_output_transform_scale_init(struct weston_output *output, uint32_t transform, uint32_t scale)
5989 {
5990 	output->transform = transform;
5991 	output->native_scale = scale;
5992 	output->current_scale = scale;
5993 
5994 	convert_size_by_transform_scale(&output->width, &output->height,
5995 					output->current_mode->width,
5996 					output->current_mode->height,
5997 					transform, scale);
5998 }
5999 
6000 static void
weston_output_init_geometry(struct weston_output * output,int x,int y)6001 weston_output_init_geometry(struct weston_output *output, int x, int y)
6002 {
6003 	output->x = x;
6004 	output->y = y;
6005 
6006 	pixman_region32_fini(&output->region);
6007 	pixman_region32_init_rect(&output->region, x, y,
6008 				  output->width,
6009 				  output->height);
6010 }
6011 
6012 /**
6013  * \ingroup output
6014  */
6015 WL_EXPORT void
weston_output_move(struct weston_output * output,int x,int y)6016 weston_output_move(struct weston_output *output, int x, int y)
6017 {
6018 	struct weston_head *head;
6019 	struct wl_resource *resource;
6020 	int ver;
6021 
6022 	output->move_x = x - output->x;
6023 	output->move_y = y - output->y;
6024 
6025 	if (output->move_x == 0 && output->move_y == 0)
6026 		return;
6027 
6028 	weston_output_init_geometry(output, x, y);
6029 
6030 	output->dirty = 1;
6031 
6032 	/* Move views on this output. */
6033 	wl_signal_emit(&output->compositor->output_moved_signal, output);
6034 
6035 	/* Notify clients of the change for output position. */
6036 	wl_list_for_each(head, &output->head_list, output_link) {
6037 		wl_resource_for_each(resource, &head->resource_list) {
6038 			wl_output_send_geometry(resource,
6039 						output->x,
6040 						output->y,
6041 						head->mm_width,
6042 						head->mm_height,
6043 						head->subpixel,
6044 						head->make,
6045 						head->model,
6046 						output->transform);
6047 
6048 			ver = wl_resource_get_version(resource);
6049 			if (ver >= WL_OUTPUT_DONE_SINCE_VERSION)
6050 				wl_output_send_done(resource);
6051 		}
6052 
6053 		wl_resource_for_each(resource, &head->xdg_output_resource_list) {
6054 			zxdg_output_v1_send_logical_position(resource,
6055 							     output->x,
6056 							     output->y);
6057 			zxdg_output_v1_send_done(resource);
6058 		}
6059 	}
6060 }
6061 
6062 /** Signal that a pending output is taken into use.
6063  *
6064  * Removes the output from the pending list and adds it to the compositor's
6065  * list of enabled outputs. The output created signal is emitted.
6066  *
6067  * The output gets an internal ID assigned, and the wl_output global is
6068  * created.
6069  *
6070  * \param compositor The compositor instance.
6071  * \param output The output to be added.
6072  *
6073  * \internal
6074  * \ingroup compositor
6075  */
6076 static void
weston_compositor_add_output(struct weston_compositor * compositor,struct weston_output * output)6077 weston_compositor_add_output(struct weston_compositor *compositor,
6078                              struct weston_output *output)
6079 {
6080 	struct weston_view *view, *next;
6081 	struct weston_head *head;
6082 
6083 	assert(!output->enabled);
6084 
6085 	/* Verify we haven't reached the limit of 32 available output IDs */
6086 	assert(ffs(~compositor->output_id_pool) > 0);
6087 
6088 	/* Invert the output id pool and look for the lowest numbered
6089 	 * switch (the least significant bit).  Take that bit's position
6090 	 * as our ID, and mark it used in the compositor's output_id_pool.
6091 	 */
6092 	output->id = ffs(~compositor->output_id_pool) - 1;
6093 	compositor->output_id_pool |= 1u << output->id;
6094 
6095 	wl_list_remove(&output->link);
6096 	wl_list_insert(compositor->output_list.prev, &output->link);
6097 	output->enabled = true;
6098 
6099 	wl_list_for_each(head, &output->head_list, output_link)
6100 		weston_head_add_global(head);
6101 
6102 	wl_signal_emit(&compositor->output_created_signal, output);
6103 
6104 	wl_list_for_each_safe(view, next, &compositor->view_list, link)
6105 		weston_view_geometry_dirty(view);
6106 }
6107 
6108 /** Transform device coordinates into global coordinates
6109  *
6110  * \param output the weston_output object
6111  * \param[in] device_x X coordinate in device units.
6112  * \param[in] device_y Y coordinate in device units.
6113  * \param[out] x X coordinate in the global space.
6114  * \param[out] y Y coordinate in the global space.
6115  *
6116  * Transforms coordinates from the device coordinate space (physical pixel
6117  * units) to the global coordinate space (logical pixel units).  This takes
6118  * into account output transform and scale.
6119  *
6120  * \ingroup output
6121  * \internal
6122  */
6123 WL_EXPORT void
weston_output_transform_coordinate(struct weston_output * output,double device_x,double device_y,double * x,double * y)6124 weston_output_transform_coordinate(struct weston_output *output,
6125 				   double device_x, double device_y,
6126 				   double *x, double *y)
6127 {
6128 	struct weston_vector p = { {
6129 		device_x,
6130 		device_y,
6131 		0.0,
6132 		1.0 } };
6133 
6134 	weston_matrix_transform(&output->inverse_matrix, &p);
6135 
6136 	*x = p.f[0] / p.f[3];
6137 	*y = p.f[1] / p.f[3];
6138 }
6139 
6140 /** Removes output from compositor's list of enabled outputs
6141  *
6142  * \param output The weston_output object that is being removed.
6143  *
6144  * The following happens:
6145  *
6146  * - The output assignments of all views in the current scenegraph are
6147  *   recomputed.
6148  *
6149  * - Presentation feedback is discarded.
6150  *
6151  * - Compositor is notified that outputs were changed and
6152  *   applies the necessary changes to re-layout outputs.
6153  *
6154  * - The output is put back in the pending outputs list.
6155  *
6156  * - Signal is emitted to notify all users of the weston_output
6157  *   object that the output is being destroyed.
6158  *
6159  * - wl_output protocol objects referencing this weston_output
6160  *   are made inert, and the wl_output global is removed.
6161  *
6162  * - The output's internal ID is released.
6163  *
6164  * \ingroup compositor
6165  * \internal
6166  */
6167 static void
weston_compositor_remove_output(struct weston_output * output)6168 weston_compositor_remove_output(struct weston_output *output)
6169 {
6170 	struct weston_compositor *compositor = output->compositor;
6171 	struct weston_view *view;
6172 	struct weston_head *head;
6173 
6174 	assert(output->destroying);
6175 	assert(output->enabled);
6176 
6177 	wl_list_for_each(view, &compositor->view_list, link) {
6178 		if (view->output_mask & (1u << output->id))
6179 			weston_view_assign_output(view);
6180 	}
6181 
6182 	weston_presentation_feedback_discard_list(&output->feedback_list);
6183 
6184 	weston_compositor_reflow_outputs(compositor, output, -output->width);
6185 
6186 	wl_list_remove(&output->link);
6187 	wl_list_insert(compositor->pending_output_list.prev, &output->link);
6188 	output->enabled = false;
6189 
6190 	wl_signal_emit(&compositor->output_destroyed_signal, output);
6191 	wl_signal_emit(&output->destroy_signal, output);
6192 
6193 	wl_list_for_each(head, &output->head_list, output_link)
6194 		weston_head_remove_global(head);
6195 
6196 	compositor->output_id_pool &= ~(1u << output->id);
6197 	output->id = 0xffffffff; /* invalid */
6198 }
6199 
6200 /** Sets the output scale for a given output.
6201  *
6202  * \param output The weston_output object that the scale is set for.
6203  * \param scale  Scale factor for the given output.
6204  *
6205  * It only supports setting scale for an output that
6206  * is not enabled and it can only be ran once.
6207  *
6208  * \ingroup ouput
6209  */
6210 WL_EXPORT void
weston_output_set_scale(struct weston_output * output,int32_t scale)6211 weston_output_set_scale(struct weston_output *output,
6212 			int32_t scale)
6213 {
6214 	/* We can only set scale on a disabled output */
6215 	assert(!output->enabled);
6216 
6217 	/* We only want to set scale once */
6218 	assert(!output->scale);
6219 
6220 	output->scale = scale;
6221 }
6222 
6223 /** Sets the output transform for a given output.
6224  *
6225  * \param output    The weston_output object that the transform is set for.
6226  * \param transform Transform value for the given output.
6227  *
6228  * Refer to wl_output::transform section located at
6229  * https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_output
6230  * for list of values that can be passed to this function.
6231  *
6232  * \ingroup output
6233  */
6234 WL_EXPORT void
weston_output_set_transform(struct weston_output * output,uint32_t transform)6235 weston_output_set_transform(struct weston_output *output,
6236 			    uint32_t transform)
6237 {
6238 	struct weston_pointer_motion_event ev;
6239 	struct wl_resource *resource;
6240 	struct weston_seat *seat;
6241 	pixman_region32_t old_region;
6242 	int mid_x, mid_y;
6243 	struct weston_head *head;
6244 	int ver;
6245 
6246 	if (!output->enabled && output->transform == UINT32_MAX) {
6247 		output->transform = transform;
6248 		return;
6249 	}
6250 
6251 	weston_output_transform_scale_init(output, transform, output->scale);
6252 
6253 	pixman_region32_init(&old_region);
6254 	pixman_region32_copy(&old_region, &output->region);
6255 
6256 	weston_output_init_geometry(output, output->x, output->y);
6257 
6258 	output->dirty = 1;
6259 
6260 	/* Notify clients of the change for output transform. */
6261 	wl_list_for_each(head, &output->head_list, output_link) {
6262 		wl_resource_for_each(resource, &head->resource_list) {
6263 			wl_output_send_geometry(resource,
6264 						output->x,
6265 						output->y,
6266 						head->mm_width,
6267 						head->mm_height,
6268 						head->subpixel,
6269 						head->make,
6270 						head->model,
6271 						output->transform);
6272 
6273 			ver = wl_resource_get_version(resource);
6274 			if (ver >= WL_OUTPUT_DONE_SINCE_VERSION)
6275 				wl_output_send_done(resource);
6276 		}
6277 		wl_resource_for_each(resource, &head->xdg_output_resource_list) {
6278 			zxdg_output_v1_send_logical_position(resource,
6279 							     output->x,
6280 							     output->y);
6281 			zxdg_output_v1_send_logical_size(resource,
6282 							 output->width,
6283 							 output->height);
6284 			zxdg_output_v1_send_done(resource);
6285 		}
6286 	}
6287 
6288 	/* we must ensure that pointers are inside output, otherwise they disappear */
6289 	mid_x = output->x + output->width / 2;
6290 	mid_y = output->y + output->height / 2;
6291 
6292 	ev.mask = WESTON_POINTER_MOTION_ABS;
6293 	ev.x = wl_fixed_to_double(wl_fixed_from_int(mid_x));
6294 	ev.y = wl_fixed_to_double(wl_fixed_from_int(mid_y));
6295 
6296 	wl_list_for_each(seat, &output->compositor->seat_list, link) {
6297 		struct weston_pointer *pointer = weston_seat_get_pointer(seat);
6298 
6299 		if (pointer && pixman_region32_contains_point(&old_region,
6300 							      wl_fixed_to_int(pointer->x),
6301 							      wl_fixed_to_int(pointer->y),
6302 							      NULL))
6303 			weston_pointer_move(pointer, &ev);
6304 	}
6305 }
6306 
6307 /** Initializes a weston_output object with enough data so
6308  ** an output can be configured.
6309  *
6310  * \param output     The weston_output object to initialize
6311  * \param compositor The compositor instance.
6312  * \param name       Name for the output (the string is copied).
6313  *
6314  * Sets initial values for fields that are expected to be
6315  * configured either by compositors or backends.
6316  *
6317  * The name is used in logs, and can be used by compositors as a configuration
6318  * identifier.
6319  *
6320  * \ingroup output
6321  * \internal
6322  */
6323 WL_EXPORT void
weston_output_init(struct weston_output * output,struct weston_compositor * compositor,const char * name)6324 weston_output_init(struct weston_output *output,
6325 		   struct weston_compositor *compositor,
6326 		   const char *name)
6327 {
6328 	output->compositor = compositor;
6329 	output->destroying = 0;
6330 	output->name = strdup(name);
6331 	wl_list_init(&output->link);
6332 	wl_signal_init(&output->user_destroy_signal);
6333 	output->enabled = false;
6334 	output->desired_protection = WESTON_HDCP_DISABLE;
6335 	output->allow_protection = true;
6336 
6337     LOG_INFO("this->head_list.clear()");
6338 	wl_list_init(&output->head_list);
6339 
6340 	/* Add some (in)sane defaults which can be used
6341 	 * for checking if an output was properly configured
6342 	 */
6343 	output->scale = 0;
6344 	/* Can't use -1 on uint32_t and 0 is valid enum value */
6345 	output->transform = UINT32_MAX;
6346 
6347 	pixman_region32_init(&output->region);
6348 	wl_list_init(&output->mode_list);
6349 }
6350 
6351 /** Adds weston_output object to pending output list.
6352  *
6353  * \param output     The weston_output object to add
6354  * \param compositor The compositor instance.
6355  *
6356  * The opposite of this operation is built into weston_output_release().
6357  *
6358  * \ingroup compositor
6359  * \internal
6360  */
6361 WL_EXPORT void
weston_compositor_add_pending_output(struct weston_output * output,struct weston_compositor * compositor)6362 weston_compositor_add_pending_output(struct weston_output *output,
6363 				     struct weston_compositor *compositor)
6364 {
6365 	assert(output->disable);
6366 	assert(output->enable);
6367 
6368 	wl_list_remove(&output->link);
6369 	wl_list_insert(compositor->pending_output_list.prev, &output->link);
6370 }
6371 
6372 /** Create a string with the attached heads' names.
6373  *
6374  * The string must be free()'d.
6375  *
6376  * \ingroup output
6377  */
6378 static char *
weston_output_create_heads_string(struct weston_output * output)6379 weston_output_create_heads_string(struct weston_output *output)
6380 {
6381 	FILE *fp;
6382 	char *str = NULL;
6383 	size_t size = 0;
6384 	struct weston_head *head;
6385 	const char *sep = "";
6386 
6387 	fp = open_memstream(&str, &size);
6388 	if (!fp)
6389 		return NULL;
6390 
6391 	wl_list_for_each(head, &output->head_list, output_link) {
6392 		fprintf(fp, "%s%s", sep, head->name);
6393 		sep = ", ";
6394 	}
6395 	fclose(fp);
6396 
6397 	return str;
6398 }
6399 
6400 /** Constructs a weston_output object that can be used by the compositor.
6401  *
6402  * \param output The weston_output object that needs to be enabled. Must not
6403  * be enabled already. Must have at least one head attached.
6404  *
6405  * Output coordinates are calculated and each new output is by default
6406  * assigned to the right of previous one.
6407  *
6408  * Sets up the transformation, zoom, and geometry of the output using
6409  * the properties that need to be configured by the compositor.
6410  *
6411  * Establishes a repaint timer for the output with the relevant display
6412  * object's event loop. See output_repaint_timer_handler().
6413  *
6414  * The output is assigned an ID. Weston can support up to 32 distinct
6415  * outputs, with IDs numbered from 0-31; the compositor's output_id_pool
6416  * is referred to and used to find the first available ID number, and
6417  * then this ID is marked as used in output_id_pool.
6418  *
6419  * The output is also assigned a Wayland global with the wl_output
6420  * external interface.
6421  *
6422  * Backend specific function is called to set up the output output.
6423  *
6424  * Output is added to the compositor's output list
6425  *
6426  * If the backend specific function fails, the weston_output object
6427  * is returned to a state it was before calling this function and
6428  * is added to the compositor's pending_output_list in case it needs
6429  * to be reconfigured or just so it can be destroyed at shutdown.
6430  *
6431  * 0 is returned on success, -1 on failure.
6432  *
6433  * \ingroup output
6434  */
6435 WL_EXPORT int
weston_output_enable(struct weston_output * output)6436 weston_output_enable(struct weston_output *output)
6437 {
6438 	struct weston_compositor *c = output->compositor;
6439 	struct weston_output *iterator;
6440 	struct weston_head *head;
6441 	char *head_names;
6442 	int x = 0, y = 0;
6443 
6444 	if (output->enabled) {
6445 		weston_log("Error: attempt to enable an enabled output '%s'\n",
6446 			   output->name);
6447 		return -1;
6448 	}
6449 
6450 	if (wl_list_empty(&output->head_list)) {
6451 		weston_log("Error: cannot enable output '%s' without heads.\n",
6452 			   output->name);
6453 		return -1;
6454 	}
6455 
6456 	if (wl_list_empty(&output->mode_list) || !output->current_mode) {
6457 		weston_log("Error: no video mode for output '%s'.\n",
6458 			   output->name);
6459 		return -1;
6460 	}
6461 
6462 	wl_list_for_each(head, &output->head_list, output_link) {
6463 		assert(head->make);
6464 		assert(head->model);
6465 	}
6466 
6467 	iterator = container_of(c->output_list.prev,
6468 				struct weston_output, link);
6469 
6470 	if (!wl_list_empty(&c->output_list))
6471 		x = iterator->x + iterator->width;
6472 
6473 	/* Make sure the scale is set up */
6474 	assert(output->scale);
6475 
6476 	/* Make sure we have a transform set */
6477 	assert(output->transform != UINT32_MAX);
6478 
6479 	output->x = x;
6480 	output->y = y;
6481 	output->dirty = 1;
6482 	output->original_scale = output->scale;
6483 
6484 	wl_signal_init(&output->frame_signal);
6485 	wl_signal_init(&output->destroy_signal);
6486 
6487 	weston_output_transform_scale_init(output, output->transform, output->scale);
6488 	weston_output_init_zoom(output);
6489 
6490 	weston_output_init_geometry(output, x, y);
6491 	weston_output_damage(output);
6492 
6493 	wl_list_init(&output->animation_list);
6494 	wl_list_init(&output->feedback_list);
6495 
6496 	/* Enable the output (set up the crtc or create a
6497 	 * window representing the output, set up the
6498 	 * renderer, etc)
6499 	 */
6500 	if (output->enable(output) < 0) {
6501 		weston_log("Enabling output \"%{public}s\" failed.\n", output->name);
6502 		return -1;
6503 	}
6504 
6505 	weston_compositor_add_output(output->compositor, output);
6506 
6507 	head_names = weston_output_create_heads_string(output);
6508 	weston_log("Output '%s' enabled with head(s) %s\n",
6509 		   output->name, head_names);
6510 	free(head_names);
6511 
6512 	return 0;
6513 }
6514 
6515 /** Converts a weston_output object to a pending output state, so it
6516  ** can be configured again or destroyed.
6517  *
6518  * \param output The weston_output object that needs to be disabled.
6519  *
6520  * Calls a backend specific function to disable an output, in case
6521  * such function exists.
6522  *
6523  * The backend specific disable function may choose to postpone the disabling
6524  * by returning a negative value, in which case this function returns early.
6525  * In that case the backend will guarantee the output will be disabled soon
6526  * by the backend calling this function again. One must not attempt to re-enable
6527  * the output until that happens.
6528  *
6529  * Otherwise, if the output is being used by the compositor, it is removed
6530  * from weston's output_list (see weston_compositor_remove_output())
6531  * and is returned to a state it was before weston_output_enable()
6532  * was ran (see weston_output_enable_undo()).
6533  *
6534  * See weston_output_init() for more information on the
6535  * state output is returned to.
6536  *
6537  * If the output has never been enabled yet, this function can still be
6538  * called to ensure that the output is actually turned off rather than left
6539  * in the state it was discovered in.
6540  *
6541  * \ingroup output
6542  */
6543 WL_EXPORT void
weston_output_disable(struct weston_output * output)6544 weston_output_disable(struct weston_output *output)
6545 {
6546 	/* Should we rename this? */
6547 	output->destroying = 1;
6548 
6549 	/* Disable is called unconditionally also for not-enabled outputs,
6550 	 * because at compositor start-up, if there is an output that is
6551 	 * already on but the compositor wants to turn it off, we have to
6552 	 * forward the turn-off to the backend so it knows to do it.
6553 	 * The backend cannot initially turn off everything, because it
6554 	 * would cause unnecessary mode-sets for all outputs the compositor
6555 	 * wants to be on.
6556 	 */
6557 	if (output->disable(output) < 0)
6558 		return;
6559 
6560 	if (output->enabled)
6561 		weston_compositor_remove_output(output);
6562 
6563 	output->destroying = 0;
6564 }
6565 
6566 /** Forces a synchronous call to heads_changed hook
6567  *
6568  * \param compositor The compositor instance
6569  *
6570  * If there are new or changed heads, calls the heads_changed hook and
6571  * returns after the hook returns.
6572  *
6573  * \ingroup compositor
6574  */
6575 WL_EXPORT void
weston_compositor_flush_heads_changed(struct weston_compositor * compositor)6576 weston_compositor_flush_heads_changed(struct weston_compositor *compositor)
6577 {
6578 	if (compositor->heads_changed_source) {
6579 		wl_event_source_remove(compositor->heads_changed_source);
6580 		weston_compositor_call_heads_changed(compositor);
6581 	}
6582 }
6583 
6584 /** Add destroy callback for an output
6585  *
6586  * \param output The output to watch.
6587  * \param listener The listener to add. The \c notify member must be set.
6588  *
6589  * The listener callback will be called when user destroys an output. This
6590  * may be delayed by a backend in some cases. The main purpose of the
6591  * listener is to allow hooking up custom data to the output. The custom data
6592  * can be fetched via weston_output_get_destroy_listener() followed by
6593  * container_of().
6594  *
6595  * The \c data argument to the notify callback is the weston_output being
6596  * destroyed.
6597  *
6598  * @note This is for the final destruction of an output, not when it gets
6599  * disabled. If you want to keep track of enabled outputs, this is not it.
6600  *
6601  * \ingroup ouput
6602  */
6603 WL_EXPORT void
weston_output_add_destroy_listener(struct weston_output * output,struct wl_listener * listener)6604 weston_output_add_destroy_listener(struct weston_output *output,
6605 				   struct wl_listener *listener)
6606 {
6607 	wl_signal_add(&output->user_destroy_signal, listener);
6608 }
6609 
6610 /** Look up destroy listener for an output
6611  *
6612  * \param output The output to query.
6613  * \param notify The notify function used used for the added destroy listener.
6614  * \return The listener, or NULL if not found.
6615  *
6616  * This looks up the previously added destroy listener struct based on the
6617  * notify function it has. The listener can be used to access user data
6618  * through \c container_of().
6619  *
6620  * \sa wl_signal_get() weston_output_add_destroy_listener()
6621  * \ingroup output
6622  */
6623 WL_EXPORT struct wl_listener *
weston_output_get_destroy_listener(struct weston_output * output,wl_notify_func_t notify)6624 weston_output_get_destroy_listener(struct weston_output *output,
6625 				   wl_notify_func_t notify)
6626 {
6627 	return wl_signal_get(&output->user_destroy_signal, notify);
6628 }
6629 
6630 /** Uninitialize an output
6631  *
6632  * Removes the output from the list of enabled outputs if necessary, but
6633  * does not call the backend's output disable function. The output will no
6634  * longer be in the list of pending outputs either.
6635  *
6636  * All fields of weston_output become uninitialized, i.e. should not be used
6637  * anymore. The caller can free the memory after this.
6638  *
6639  * \ingroup ouput
6640  * \internal
6641  */
6642 WL_EXPORT void
weston_output_release(struct weston_output * output)6643 weston_output_release(struct weston_output *output)
6644 {
6645 	struct weston_head *head, *tmp;
6646 
6647 	output->destroying = 1;
6648 
6649 	wl_signal_emit(&output->user_destroy_signal, output);
6650 
6651 	if (output->idle_repaint_source)
6652 		wl_event_source_remove(output->idle_repaint_source);
6653 
6654 	if (output->enabled)
6655 		weston_compositor_remove_output(output);
6656 
6657 	pixman_region32_fini(&output->region);
6658 	wl_list_remove(&output->link);
6659 
6660 	wl_list_for_each_safe(head, tmp, &output->head_list, output_link)
6661 		weston_head_detach(head);
6662 
6663 	free(output->name);
6664 }
6665 
6666 /** Find an output by its given name
6667  *
6668  * \param compositor The compositor to search in.
6669  * \param name The output name to search for.
6670  * \return An existing output with the given name, or NULL if not found.
6671  *
6672  * \ingroup compositor
6673  */
6674 WL_EXPORT struct weston_output *
weston_compositor_find_output_by_name(struct weston_compositor * compositor,const char * name)6675 weston_compositor_find_output_by_name(struct weston_compositor *compositor,
6676 				      const char *name)
6677 {
6678 	struct weston_output *output;
6679 
6680 	wl_list_for_each(output, &compositor->output_list, link)
6681 		if (strcmp(output->name, name) == 0)
6682 			return output;
6683 
6684 	wl_list_for_each(output, &compositor->pending_output_list, link)
6685 		if (strcmp(output->name, name) == 0)
6686 			return output;
6687 
6688 	return NULL;
6689 }
6690 
6691 /** Create a named output
6692  *
6693  * \param compositor The compositor.
6694  * \param name The name for the output.
6695  * \return A new \c weston_output, or NULL on failure.
6696  *
6697  * This creates a new weston_output that starts with no heads attached.
6698  *
6699  * An output must be configured and it must have at least one head before
6700  * it can be enabled.
6701  *
6702  * \ingroup compositor
6703  */
6704 WL_EXPORT struct weston_output *
weston_compositor_create_output(struct weston_compositor * compositor,const char * name)6705 weston_compositor_create_output(struct weston_compositor *compositor,
6706 				const char *name)
6707 {
6708 	assert(compositor->backend->create_output);
6709 
6710 	if (weston_compositor_find_output_by_name(compositor, name)) {
6711 		weston_log("Warning: attempted to create an output with a "
6712 			   "duplicate name '%s'.\n", name);
6713 		return NULL;
6714 	}
6715 
6716 	return compositor->backend->create_output(compositor, name);
6717 }
6718 
6719 /** Create an output for an unused head
6720  *
6721  * \param compositor The compositor.
6722  * \param head The head to attach to the output.
6723  * \return A new \c weston_output, or NULL on failure.
6724  *
6725  * This creates a new weston_output that starts with the given head attached.
6726  * The output inherits the name of the head. The head must not be already
6727  * attached to another output.
6728  *
6729  * An output must be configured before it can be enabled.
6730  *
6731  * \ingroup compositor
6732  */
6733 WL_EXPORT struct weston_output *
weston_compositor_create_output_with_head(struct weston_compositor * compositor,struct weston_head * head)6734 weston_compositor_create_output_with_head(struct weston_compositor *compositor,
6735 					  struct weston_head *head)
6736 {
6737 	struct weston_output *output;
6738 
6739 	output = weston_compositor_create_output(compositor, head->name);
6740 	if (!output)
6741 		return NULL;
6742 
6743 	if (weston_output_attach_head(output, head) < 0) {
6744 		weston_output_destroy(output);
6745 		return NULL;
6746 	}
6747 
6748 	return output;
6749 }
6750 
6751 /** Destroy an output
6752  *
6753  * \param output The output to destroy.
6754  *
6755  * The heads attached to the given output are detached and become unused again.
6756  *
6757  * It is not necessary to explicitly destroy all outputs at compositor exit.
6758  * weston_compositor_destroy() will automatically destroy any remaining
6759  * outputs.
6760  *
6761  * \ingroup ouput
6762  */
6763 WL_EXPORT void
weston_output_destroy(struct weston_output * output)6764 weston_output_destroy(struct weston_output *output)
6765 {
6766 	output->destroy(output);
6767 }
6768 
6769 /** When you need a head...
6770  *
6771  * This function is a hack, used until all code has been converted to become
6772  * multi-head aware.
6773  *
6774  * \param output The weston_output whose head to get.
6775  * \return The first head in the output's list.
6776  *
6777  * \ingroup ouput
6778  */
6779 WL_EXPORT struct weston_head *
weston_output_get_first_head(struct weston_output * output)6780 weston_output_get_first_head(struct weston_output *output)
6781 {
6782 	if (wl_list_empty(&output->head_list))
6783 		return NULL;
6784 
6785 	return container_of(output->head_list.next,
6786 			    struct weston_head, output_link);
6787 }
6788 
6789 /** Allow/Disallow content-protection support for an output
6790  *
6791  * This function sets the allow_protection member for an output. Setting of
6792  * this field will allow the compositor to attempt content-protection for this
6793  * output, for a backend that supports the content-protection protocol.
6794  *
6795  * \param output The weston_output for whom the content-protection is to be
6796  * allowed.
6797  * \param allow_protection The bool value which is to be set.
6798  */
6799 WL_EXPORT void
weston_output_allow_protection(struct weston_output * output,bool allow_protection)6800 weston_output_allow_protection(struct weston_output *output,
6801 			       bool allow_protection)
6802 {
6803 	output->allow_protection = allow_protection;
6804 }
6805 
6806 static void
xdg_output_unlist(struct wl_resource * resource)6807 xdg_output_unlist(struct wl_resource *resource)
6808 {
6809 	wl_list_remove(wl_resource_get_link(resource));
6810 }
6811 
6812 static void
xdg_output_destroy(struct wl_client * client,struct wl_resource * resource)6813 xdg_output_destroy(struct wl_client *client, struct wl_resource *resource)
6814 {
6815 	wl_resource_destroy(resource);
6816 }
6817 
6818 static const struct zxdg_output_v1_interface xdg_output_interface = {
6819 	xdg_output_destroy
6820 };
6821 
6822 static void
xdg_output_manager_destroy(struct wl_client * client,struct wl_resource * resource)6823 xdg_output_manager_destroy(struct wl_client *client,
6824                            struct wl_resource *resource)
6825 {
6826 	wl_resource_destroy(resource);
6827 }
6828 
6829 static void
xdg_output_manager_get_xdg_output(struct wl_client * client,struct wl_resource * manager,uint32_t id,struct wl_resource * output_resource)6830 xdg_output_manager_get_xdg_output(struct wl_client *client,
6831 				  struct wl_resource *manager,
6832 				  uint32_t id,
6833 				  struct wl_resource *output_resource)
6834 {
6835 	int version = wl_resource_get_version(manager);
6836 	struct weston_head *head = wl_resource_get_user_data(output_resource);
6837 	struct weston_output *output = head->output;
6838 	struct wl_resource *resource;
6839 
6840 	resource = wl_resource_create(client, &zxdg_output_v1_interface,
6841 				      version, id);
6842 	if (resource == NULL) {
6843 		wl_client_post_no_memory(client);
6844 		return;
6845 	}
6846 
6847 	wl_list_insert(&head->xdg_output_resource_list,
6848 		       wl_resource_get_link(resource));
6849 
6850 	wl_resource_set_implementation(resource, &xdg_output_interface,
6851 				       NULL, xdg_output_unlist);
6852 
6853 	zxdg_output_v1_send_logical_position(resource, output->x, output->y);
6854 	zxdg_output_v1_send_logical_size(resource,
6855 					 output->width,
6856 					 output->height);
6857 	if (version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION)
6858 		zxdg_output_v1_send_name(resource, head->name);
6859 
6860 	zxdg_output_v1_send_done(resource);
6861 }
6862 
6863 static const struct zxdg_output_manager_v1_interface xdg_output_manager_interface = {
6864 	xdg_output_manager_destroy,
6865 	xdg_output_manager_get_xdg_output
6866 };
6867 
6868 static void
bind_xdg_output_manager(struct wl_client * client,void * data,uint32_t version,uint32_t id)6869 bind_xdg_output_manager(struct wl_client *client,
6870 			void *data, uint32_t version, uint32_t id)
6871 {
6872 	struct wl_resource *resource;
6873 
6874 	resource = wl_resource_create(client, &zxdg_output_manager_v1_interface,
6875 				      version, id);
6876 	if (resource == NULL) {
6877 		wl_client_post_no_memory(client);
6878 		return;
6879 	}
6880 
6881 	wl_resource_set_implementation(resource, &xdg_output_manager_interface,
6882 				       NULL, NULL);
6883 }
6884 
6885 static void
destroy_viewport(struct wl_resource * resource)6886 destroy_viewport(struct wl_resource *resource)
6887 {
6888 	struct weston_surface *surface =
6889 		wl_resource_get_user_data(resource);
6890 
6891 	if (!surface)
6892 		return;
6893 
6894 	surface->viewport_resource = NULL;
6895 	surface->pending.buffer_viewport.buffer.src_width =
6896 		wl_fixed_from_int(-1);
6897 	surface->pending.buffer_viewport.surface.width = -1;
6898 	surface->pending.buffer_viewport.changed = 1;
6899 }
6900 
6901 static void
viewport_destroy(struct wl_client * client,struct wl_resource * resource)6902 viewport_destroy(struct wl_client *client,
6903 		 struct wl_resource *resource)
6904 {
6905 	wl_resource_destroy(resource);
6906 }
6907 
6908 static void
viewport_set_source(struct wl_client * client,struct wl_resource * resource,wl_fixed_t src_x,wl_fixed_t src_y,wl_fixed_t src_width,wl_fixed_t src_height)6909 viewport_set_source(struct wl_client *client,
6910 		    struct wl_resource *resource,
6911 		    wl_fixed_t src_x,
6912 		    wl_fixed_t src_y,
6913 		    wl_fixed_t src_width,
6914 		    wl_fixed_t src_height)
6915 {
6916 	struct weston_surface *surface =
6917 		wl_resource_get_user_data(resource);
6918 
6919 	if (!surface) {
6920 		wl_resource_post_error(resource,
6921 			WP_VIEWPORT_ERROR_NO_SURFACE,
6922 			"wl_surface for this viewport is no longer exists");
6923 		return;
6924 	}
6925 
6926 	assert(surface->viewport_resource == resource);
6927 	assert(surface->resource);
6928 
6929 	if (src_width == wl_fixed_from_int(-1) &&
6930 	    src_height == wl_fixed_from_int(-1) &&
6931 	    src_x == wl_fixed_from_int(-1) &&
6932 	    src_y == wl_fixed_from_int(-1)) {
6933 		/* unset source rect */
6934 		surface->pending.buffer_viewport.buffer.src_width =
6935 			wl_fixed_from_int(-1);
6936 		surface->pending.buffer_viewport.changed = 1;
6937 		return;
6938 	}
6939 
6940 	if (src_width <= 0 || src_height <= 0 || src_x < 0 || src_y < 0) {
6941 		wl_resource_post_error(resource,
6942 			WP_VIEWPORT_ERROR_BAD_VALUE,
6943 			"wl_surface@%d viewport source "
6944 			"w=%f <= 0, h=%f <= 0, x=%f < 0, or y=%f < 0",
6945 			wl_resource_get_id(surface->resource),
6946 			wl_fixed_to_double(src_width),
6947 			wl_fixed_to_double(src_height),
6948 			wl_fixed_to_double(src_x),
6949 			wl_fixed_to_double(src_y));
6950 		return;
6951 	}
6952 
6953 	surface->pending.buffer_viewport.buffer.src_x = src_x;
6954 	surface->pending.buffer_viewport.buffer.src_y = src_y;
6955 	surface->pending.buffer_viewport.buffer.src_width = src_width;
6956 	surface->pending.buffer_viewport.buffer.src_height = src_height;
6957 	surface->pending.buffer_viewport.changed = 1;
6958 }
6959 
6960 static void
viewport_set_destination(struct wl_client * client,struct wl_resource * resource,int32_t dst_width,int32_t dst_height)6961 viewport_set_destination(struct wl_client *client,
6962 			 struct wl_resource *resource,
6963 			 int32_t dst_width,
6964 			 int32_t dst_height)
6965 {
6966 	struct weston_surface *surface =
6967 		wl_resource_get_user_data(resource);
6968 
6969 	if (!surface) {
6970 		wl_resource_post_error(resource,
6971 			WP_VIEWPORT_ERROR_NO_SURFACE,
6972 			"wl_surface for this viewport no longer exists");
6973 		return;
6974 	}
6975 
6976 	assert(surface->viewport_resource == resource);
6977 
6978 	if (dst_width == -1 && dst_height == -1) {
6979 		/* unset destination size */
6980 		surface->pending.buffer_viewport.surface.width = -1;
6981 		surface->pending.buffer_viewport.changed = 1;
6982 		return;
6983 	}
6984 
6985 	if (dst_width <= 0 || dst_height <= 0) {
6986 		wl_resource_post_error(resource,
6987 			WP_VIEWPORT_ERROR_BAD_VALUE,
6988 			"destination size must be positive (%dx%d)",
6989 			dst_width, dst_height);
6990 		return;
6991 	}
6992 
6993 	surface->pending.buffer_viewport.surface.width = dst_width;
6994 	surface->pending.buffer_viewport.surface.height = dst_height;
6995 	surface->pending.buffer_viewport.changed = 1;
6996 }
6997 
6998 static const struct wp_viewport_interface viewport_interface = {
6999 	viewport_destroy,
7000 	viewport_set_source,
7001 	viewport_set_destination
7002 };
7003 
7004 static void
viewporter_destroy(struct wl_client * client,struct wl_resource * resource)7005 viewporter_destroy(struct wl_client *client,
7006 		   struct wl_resource *resource)
7007 {
7008 	wl_resource_destroy(resource);
7009 }
7010 
7011 static void
viewporter_get_viewport(struct wl_client * client,struct wl_resource * viewporter,uint32_t id,struct wl_resource * surface_resource)7012 viewporter_get_viewport(struct wl_client *client,
7013 			struct wl_resource *viewporter,
7014 			uint32_t id,
7015 			struct wl_resource *surface_resource)
7016 {
7017 	int version = wl_resource_get_version(viewporter);
7018 	struct weston_surface *surface =
7019 		wl_resource_get_user_data(surface_resource);
7020 	struct wl_resource *resource;
7021 
7022 	if (surface->viewport_resource) {
7023 		wl_resource_post_error(viewporter,
7024 			WP_VIEWPORTER_ERROR_VIEWPORT_EXISTS,
7025 			"a viewport for that surface already exists");
7026 		return;
7027 	}
7028 
7029 	resource = wl_resource_create(client, &wp_viewport_interface,
7030 				      version, id);
7031 	if (resource == NULL) {
7032 		wl_client_post_no_memory(client);
7033 		return;
7034 	}
7035 
7036 	wl_resource_set_implementation(resource, &viewport_interface,
7037 				       surface, destroy_viewport);
7038 
7039 	surface->viewport_resource = resource;
7040 }
7041 
7042 static const struct wp_viewporter_interface viewporter_interface = {
7043 	viewporter_destroy,
7044 	viewporter_get_viewport
7045 };
7046 
7047 static void
bind_viewporter(struct wl_client * client,void * data,uint32_t version,uint32_t id)7048 bind_viewporter(struct wl_client *client,
7049 		void *data, uint32_t version, uint32_t id)
7050 {
7051 	struct wl_resource *resource;
7052 
7053 	resource = wl_resource_create(client, &wp_viewporter_interface,
7054 				      version, id);
7055 	if (resource == NULL) {
7056 		wl_client_post_no_memory(client);
7057 		return;
7058 	}
7059 
7060 	wl_resource_set_implementation(resource, &viewporter_interface,
7061 				       NULL, NULL);
7062 }
7063 
7064 static void
destroy_presentation_feedback(struct wl_resource * feedback_resource)7065 destroy_presentation_feedback(struct wl_resource *feedback_resource)
7066 {
7067 	struct weston_presentation_feedback *feedback;
7068 
7069 	feedback = wl_resource_get_user_data(feedback_resource);
7070 
7071 	wl_list_remove(&feedback->link);
7072 	free(feedback);
7073 }
7074 
7075 static void
presentation_destroy(struct wl_client * client,struct wl_resource * resource)7076 presentation_destroy(struct wl_client *client, struct wl_resource *resource)
7077 {
7078 	wl_resource_destroy(resource);
7079 }
7080 
7081 static void
presentation_feedback(struct wl_client * client,struct wl_resource * presentation_resource,struct wl_resource * surface_resource,uint32_t callback)7082 presentation_feedback(struct wl_client *client,
7083 		      struct wl_resource *presentation_resource,
7084 		      struct wl_resource *surface_resource,
7085 		      uint32_t callback)
7086 {
7087 	struct weston_surface *surface;
7088 	struct weston_presentation_feedback *feedback;
7089 
7090 	surface = wl_resource_get_user_data(surface_resource);
7091 
7092 	feedback = zalloc(sizeof *feedback);
7093 	if (feedback == NULL)
7094 		goto err_calloc;
7095 
7096 	feedback->resource = wl_resource_create(client,
7097 					&wp_presentation_feedback_interface,
7098 					1, callback);
7099 	if (!feedback->resource)
7100 		goto err_create;
7101 
7102 	wl_resource_set_implementation(feedback->resource, NULL, feedback,
7103 				       destroy_presentation_feedback);
7104 
7105 	wl_list_insert(&surface->pending.feedback_list, &feedback->link);
7106 
7107 	return;
7108 
7109 err_create:
7110 	free(feedback);
7111 
7112 err_calloc:
7113 	wl_client_post_no_memory(client);
7114 }
7115 
7116 static const struct wp_presentation_interface presentation_implementation = {
7117 	presentation_destroy,
7118 	presentation_feedback
7119 };
7120 
7121 static void
bind_presentation(struct wl_client * client,void * data,uint32_t version,uint32_t id)7122 bind_presentation(struct wl_client *client,
7123 		  void *data, uint32_t version, uint32_t id)
7124 {
7125 	struct weston_compositor *compositor = data;
7126 	struct wl_resource *resource;
7127 
7128 	resource = wl_resource_create(client, &wp_presentation_interface,
7129 				      version, id);
7130 	if (resource == NULL) {
7131 		wl_client_post_no_memory(client);
7132 		return;
7133 	}
7134 
7135 	wl_resource_set_implementation(resource, &presentation_implementation,
7136 				       compositor, NULL);
7137 	wp_presentation_send_clock_id(resource, compositor->presentation_clock);
7138 }
7139 
7140 static void
compositor_bind(struct wl_client * client,void * data,uint32_t version,uint32_t id)7141 compositor_bind(struct wl_client *client,
7142 		void *data, uint32_t version, uint32_t id)
7143 {
7144 	struct weston_compositor *compositor = data;
7145 	struct wl_resource *resource;
7146 
7147 	resource = wl_resource_create(client, &wl_compositor_interface,
7148 				      version, id);
7149 	if (resource == NULL) {
7150 		wl_client_post_no_memory(client);
7151 		return;
7152 	}
7153 
7154 	wl_resource_set_implementation(resource, &compositor_interface,
7155 				       compositor, NULL);
7156 }
7157 
7158 // OHOS remove logger
7159 //static const char *
7160 //output_repaint_status_text(struct weston_output *output)
7161 //{
7162 //	switch (output->repaint_status) {
7163 //	case REPAINT_NOT_SCHEDULED:
7164 //		return "no repaint";
7165 //	case REPAINT_BEGIN_FROM_IDLE:
7166 //		return "start_repaint_loop scheduled";
7167 //	case REPAINT_SCHEDULED:
7168 //		return "repaint scheduled";
7169 //	case REPAINT_AWAITING_COMPLETION:
7170 //		return "awaiting completion";
7171 //	}
7172 //
7173 //	assert(!"output_repaint_status_text missing enum");
7174 //	return NULL;
7175 //}
7176 //
7177 //static void
7178 //debug_scene_view_print_buffer(FILE *fp, struct weston_view *view)
7179 //{
7180 //	struct weston_buffer *buffer = view->surface->buffer_ref.buffer;
7181 //	struct wl_shm_buffer *shm;
7182 //	struct linux_dmabuf_buffer *dmabuf;
7183 //	const struct pixel_format_info *pixel_info = NULL;
7184 //
7185 //	if (!buffer) {
7186 //		fprintf(fp, "\t\t[buffer not available]\n");
7187 //		return;
7188 //	}
7189 //
7190 //	shm = wl_shm_buffer_get(buffer->resource);
7191 //	if (shm) {
7192 //		uint32_t _format = wl_shm_buffer_get_format(shm);
7193 //		pixel_info = pixel_format_get_info_shm(_format);
7194 //		fprintf(fp, "\t\tSHM buffer\n");
7195 //		fprintf(fp, "\t\t\tformat: 0x%lx %s\n",
7196 //			(unsigned long) _format,
7197 //			pixel_info ? pixel_info->drm_format_name : "UNKNOWN");
7198 //		return;
7199 //	}
7200 //
7201 //	dmabuf = linux_dmabuf_buffer_get(buffer->resource);
7202 //	if (dmabuf) {
7203 //		pixel_info = pixel_format_get_info(dmabuf->attributes.format);
7204 //		fprintf(fp, "\t\tdmabuf buffer\n");
7205 //		fprintf(fp, "\t\t\tformat: 0x%lx %s\n",
7206 //			(unsigned long) dmabuf->attributes.format,
7207 //			pixel_info ? pixel_info->drm_format_name : "UNKNOWN");
7208 //		fprintf(fp, "\t\t\tmodifier: 0x%llx\n",
7209 //			(unsigned long long) dmabuf->attributes.modifier[0]);
7210 //		return;
7211 //	}
7212 //
7213 //	fprintf(fp, "\t\tEGL buffer\n");
7214 //}
7215 //
7216 //static void
7217 //debug_scene_view_print(FILE *fp, struct weston_view *view, int view_idx)
7218 //{
7219 //	struct weston_compositor *ec = view->surface->compositor;
7220 //	struct weston_output *output;
7221 //	char desc[512];
7222 //	pixman_box32_t *box;
7223 //	uint32_t surface_id = 0;
7224 //	pid_t pid = 0;
7225 //
7226 //	if (view->surface->resource) {
7227 //		struct wl_resource *resource = view->surface->resource;
7228 //		wl_client_get_credentials(wl_resource_get_client(resource),
7229 //				  	  &pid, NULL, NULL);
7230 //		surface_id = wl_resource_get_id(view->surface->resource);
7231 //	}
7232 //
7233 //	if (!view->surface->get_label ||
7234 //	    view->surface->get_label(view->surface, desc, sizeof(desc)) < 0) {
7235 //		strcpy(desc, "[no description available]");
7236 //	}
7237 //	fprintf(fp, "\tView %d (role %s, PID %d, surface ID %u, %s, %p):\n",
7238 //		view_idx, view->surface->role_name, pid, surface_id,
7239 //		desc, view);
7240 //
7241 //	box = pixman_region32_extents(&view->transform.boundingbox);
7242 //	fprintf(fp, "\t\tposition: (%d, %d) -> (%d, %d)\n",
7243 //		box->x1, box->y1, box->x2, box->y2);
7244 //	box = pixman_region32_extents(&view->transform.opaque);
7245 //
7246 //	if (weston_view_is_opaque(view, &view->transform.boundingbox)) {
7247 //		fprintf(fp, "\t\t[fully opaque]\n");
7248 //	} else if (!pixman_region32_not_empty(&view->transform.opaque)) {
7249 //		fprintf(fp, "\t\t[not opaque]\n");
7250 //	} else {
7251 //		fprintf(fp, "\t\t[opaque: (%d, %d) -> (%d, %d)]\n",
7252 //			box->x1, box->y1, box->x2, box->y2);
7253 //	}
7254 //
7255 //	if (view->alpha < 1.0)
7256 //		fprintf(fp, "\t\talpha: %f\n", view->alpha);
7257 //
7258 //	if (view->output_mask != 0) {
7259 //		bool first_output = true;
7260 //		fprintf(fp, "\t\toutputs: ");
7261 //		wl_list_for_each(output, &ec->output_list, link) {
7262 //			if (!(view->output_mask & (1 << output->id)))
7263 //				continue;
7264 //			fprintf(fp, "%s%d (%s)%s",
7265 //				(first_output) ? "" : ", ",
7266 //				output->id, output->name,
7267 //				(view->output == output) ? " (primary)" : "");
7268 //			first_output = false;
7269 //		}
7270 //	} else {
7271 //		fprintf(fp, "\t\t[no outputs]");
7272 //	}
7273 //
7274 //	fprintf(fp, "\n");
7275 //
7276 //	debug_scene_view_print_buffer(fp, view);
7277 //}
7278 //
7279 //static void
7280 //debug_scene_view_print_tree(struct weston_view *view,
7281 //			    FILE *fp, int *view_idx)
7282 //{
7283 //	struct weston_subsurface *sub;
7284 //	struct weston_view *ev;
7285 //
7286 //	/*
7287 //	 * print the view first, then we recursively go on printing
7288 //	 * sub-surfaces. We bail out once no more sub-surfaces are available.
7289 //	 */
7290 //	debug_scene_view_print(fp, view, *view_idx);
7291 //
7292 //	/* no more sub-surfaces */
7293 //	if (wl_list_empty(&view->surface->subsurface_list))
7294 //		return;
7295 //
7296 //	wl_list_for_each(sub, &view->surface->subsurface_list, parent_link) {
7297 //		wl_list_for_each(ev, &sub->surface->views, surface_link) {
7298 //			/* only print the child views of the current view */
7299 //			if (ev->parent_view != view)
7300 //				continue;
7301 //
7302 //			(*view_idx)++;
7303 //			debug_scene_view_print_tree(ev, fp, view_idx);
7304 //		}
7305 //	}
7306 //}
7307 
7308 /**
7309  * Output information on how libweston is currently composing the scene
7310  * graph.
7311  *
7312  * \ingroup compositor
7313  */
7314 // OHOS remove logger
7315 //WL_EXPORT char *
7316 //weston_compositor_print_scene_graph(struct weston_compositor *ec)
7317 //{
7318 //	struct weston_output *output;
7319 //	struct weston_layer *layer;
7320 //	struct timespec now;
7321 //	int layer_idx = 0;
7322 //	FILE *fp;
7323 //	char *ret;
7324 //	size_t len;
7325 //	int err;
7326 //
7327 //	fp = open_memstream(&ret, &len);
7328 //	assert(fp);
7329 //
7330 //	weston_compositor_read_presentation_clock(ec, &now);
7331 //	fprintf(fp, "Weston scene graph at %ld.%09ld:\n\n",
7332 //		now.tv_sec, now.tv_nsec);
7333 //
7334 //	wl_list_for_each(output, &ec->output_list, link) {
7335 //		struct weston_head *head;
7336 //		int head_idx = 0;
7337 //
7338 //		fprintf(fp, "Output %d (%s):\n", output->id, output->name);
7339 //		assert(output->enabled);
7340 //
7341 //		fprintf(fp, "\tposition: (%d, %d) -> (%d, %d)\n",
7342 //			output->x, output->y,
7343 //			output->x + output->width,
7344 //			output->y + output->height);
7345 //		fprintf(fp, "\tmode: %dx%d@%.3fHz\n",
7346 //			output->current_mode->width,
7347 //			output->current_mode->height,
7348 //			output->current_mode->refresh / 1000.0);
7349 //		fprintf(fp, "\tscale: %d\n", output->scale);
7350 //
7351 //		fprintf(fp, "\trepaint status: %s\n",
7352 //			output_repaint_status_text(output));
7353 //		if (output->repaint_status == REPAINT_SCHEDULED)
7354 //			fprintf(fp, "\tnext repaint: %ld.%09ld\n",
7355 //				output->next_repaint.tv_sec,
7356 //				output->next_repaint.tv_nsec);
7357 //
7358 //		wl_list_for_each(head, &output->head_list, output_link) {
7359 //			fprintf(fp, "\tHead %d (%s): %sconnected\n",
7360 //				head_idx++, head->name,
7361 //				(head->connected) ? "" : "not ");
7362 //		}
7363 //	}
7364 //
7365 //	fprintf(fp, "\n");
7366 //
7367 //	wl_list_for_each(layer, &ec->layer_list, link) {
7368 //		struct weston_view *view;
7369 //		int view_idx = 0;
7370 //
7371 //		fprintf(fp, "Layer %d (pos 0x%lx):\n", layer_idx++,
7372 //			(unsigned long) layer->position);
7373 //
7374 //		if (!weston_layer_mask_is_infinite(layer)) {
7375 //			fprintf(fp, "\t[mask: (%d, %d) -> (%d,%d)]\n\n",
7376 //				layer->mask.x1, layer->mask.y1,
7377 //				layer->mask.x2, layer->mask.y2);
7378 //		}
7379 //
7380 //		wl_list_for_each(view, &layer->view_list.link, layer_link.link) {
7381 //			debug_scene_view_print_tree(view, fp, &view_idx);
7382 //			view_idx++;
7383 //		}
7384 //
7385 //		if (wl_list_empty(&layer->view_list.link))
7386 //			fprintf(fp, "\t[no views]\n");
7387 //
7388 //		fprintf(fp, "\n");
7389 //	}
7390 //
7391 //	err = fclose(fp);
7392 //	assert(err == 0);
7393 //
7394 //	return ret;
7395 //}
7396 
7397 /**
7398  * Called when the 'scene-graph' debug scope is bound by a client. This
7399  * one-shot weston-debug scope prints the current scene graph when bound,
7400  * and then terminates the stream.
7401  */
7402 // OHOS remove logger
7403 //static void
7404 //debug_scene_graph_cb(struct weston_log_subscription *sub, void *data)
7405 //{
7406 //	struct weston_compositor *ec = data;
7407 //	char *str = weston_compositor_print_scene_graph(ec);
7408 //
7409 //	weston_log_subscription_printf(sub, "%s", str);
7410 //	free(str);
7411 //	weston_log_subscription_complete(sub);
7412 //}
7413 
7414 /** Create the compositor.
7415  *
7416  * This functions creates and initializes a compositor instance.
7417  *
7418  * \param display The Wayland display to be used.
7419  * \param user_data A pointer to an object that can later be retrieved
7420  * \param log_ctx A pointer to weston_debug_compositor
7421  * using the \ref weston_compositor_get_user_data function.
7422  * \return The compositor instance on success or NULL on failure.
7423  *
7424  * \ingroup compositor
7425  */
7426 WL_EXPORT struct weston_compositor *
weston_compositor_create(struct wl_display * display,void * user_data)7427 weston_compositor_create(struct wl_display *display,
7428 // OHOS remove logger
7429 //			 struct weston_log_context *log_ctx,
7430 			 void *user_data)
7431 {
7432     LOG_ENTER();
7433 	struct weston_compositor *ec;
7434 	struct wl_event_loop *loop;
7435 
7436 // OHOS remove logger
7437 //	if (!log_ctx)
7438 //		return NULL;
7439 
7440 	ec = zalloc(sizeof *ec);
7441 	if (!ec) {
7442         LOG_EXIT();
7443 		return NULL;
7444     }
7445 
7446 // OHOS remove logger
7447 //	ec->weston_log_ctx = log_ctx;
7448 	ec->wl_display = display;
7449 	ec->user_data = user_data;
7450 	wl_signal_init(&ec->destroy_signal);
7451 	wl_signal_init(&ec->create_surface_signal);
7452 	wl_signal_init(&ec->activate_signal);
7453 	wl_signal_init(&ec->transform_signal);
7454 	wl_signal_init(&ec->kill_signal);
7455 	wl_signal_init(&ec->idle_signal);
7456 	wl_signal_init(&ec->wake_signal);
7457 	wl_signal_init(&ec->show_input_panel_signal);
7458 	wl_signal_init(&ec->hide_input_panel_signal);
7459 	wl_signal_init(&ec->update_input_panel_signal);
7460 	wl_signal_init(&ec->seat_created_signal);
7461 	wl_signal_init(&ec->output_created_signal);
7462 	wl_signal_init(&ec->output_destroyed_signal);
7463 	wl_signal_init(&ec->output_moved_signal);
7464 	wl_signal_init(&ec->output_resized_signal);
7465 	wl_signal_init(&ec->heads_changed_signal);
7466 	wl_signal_init(&ec->output_heads_changed_signal);
7467 	wl_signal_init(&ec->session_signal);
7468 	ec->session_active = true;
7469 
7470 	ec->output_id_pool = 0;
7471 	ec->repaint_msec = DEFAULT_REPAINT_WINDOW;
7472 
7473 	ec->activate_serial = 1;
7474 
7475 	ec->touch_mode = WESTON_TOUCH_MODE_NORMAL;
7476 
7477 	ec->content_protection = NULL;
7478 
7479 	if (!wl_global_create(ec->wl_display, &wl_compositor_interface, 4,
7480 			      ec, compositor_bind))
7481 		goto fail;
7482 
7483 	if (!wl_global_create(ec->wl_display, &wl_subcompositor_interface, 1,
7484 			      ec, bind_subcompositor))
7485 		goto fail;
7486 
7487 	if (!wl_global_create(ec->wl_display, &wp_viewporter_interface, 1,
7488 			      ec, bind_viewporter))
7489 		goto fail;
7490 
7491 	if (!wl_global_create(ec->wl_display, &zxdg_output_manager_v1_interface, 2,
7492 			      ec, bind_xdg_output_manager))
7493 		goto fail;
7494 
7495 	if (!wl_global_create(ec->wl_display, &wp_presentation_interface, 1,
7496 			      ec, bind_presentation))
7497 		goto fail;
7498 
7499 	if (weston_input_init(ec) != 0)
7500 		goto fail;
7501 
7502 	wl_list_init(&ec->view_list);
7503 	wl_list_init(&ec->plane_list);
7504 	wl_list_init(&ec->layer_list);
7505 	wl_list_init(&ec->seat_list);
7506 	wl_list_init(&ec->pending_output_list);
7507 	wl_list_init(&ec->output_list);
7508 	wl_list_init(&ec->head_list);
7509 	wl_list_init(&ec->key_binding_list);
7510 	wl_list_init(&ec->modifier_binding_list);
7511 	wl_list_init(&ec->button_binding_list);
7512 	wl_list_init(&ec->touch_binding_list);
7513 	wl_list_init(&ec->axis_binding_list);
7514 	wl_list_init(&ec->debug_binding_list);
7515 
7516 	wl_list_init(&ec->plugin_api_list);
7517 
7518 	weston_plane_init(&ec->primary_plane, ec, 0, 0);
7519 	weston_compositor_stack_plane(ec, &ec->primary_plane, NULL);
7520 
7521 	wl_data_device_manager_init(ec->wl_display);
7522 
7523 	wl_display_init_shm(ec->wl_display);
7524 
7525 	loop = wl_display_get_event_loop(ec->wl_display);
7526 	ec->idle_source = wl_event_loop_add_timer(loop, idle_handler, ec);
7527 	ec->repaint_timer =
7528 		wl_event_loop_add_timer(loop, output_repaint_timer_handler,
7529 					ec);
7530 
7531 	weston_layer_init(&ec->fade_layer, ec);
7532 	weston_layer_init(&ec->cursor_layer, ec);
7533 
7534 	weston_layer_set_position(&ec->fade_layer, WESTON_LAYER_POSITION_FADE);
7535 	weston_layer_set_position(&ec->cursor_layer,
7536 				  WESTON_LAYER_POSITION_CURSOR);
7537 
7538 // OHOS remove debugger
7539 //	ec->debug_scene =
7540 //		weston_compositor_add_log_scope(ec, "scene-graph",
7541 //						"Scene graph details\n",
7542 //						debug_scene_graph_cb, NULL,
7543 //						ec);
7544 //
7545 //	ec->timeline =
7546 //		weston_compositor_add_log_scope(ec, "timeline",
7547 //						"Timeline event points\n",
7548 //						weston_timeline_create_subscription,
7549 //						weston_timeline_destroy_subscription,
7550 //						ec);
7551     LOG_EXIT();
7552 	return ec;
7553 
7554 fail:
7555 	free(ec);
7556     LOG_EXIT();
7557 	return NULL;
7558 }
7559 
7560 /** weston_compositor_shutdown
7561  * \ingroup compositor
7562  */
7563 WL_EXPORT void
weston_compositor_shutdown(struct weston_compositor * ec)7564 weston_compositor_shutdown(struct weston_compositor *ec)
7565 {
7566 	struct weston_output *output, *next;
7567 
7568 	wl_event_source_remove(ec->idle_source);
7569 
7570 	/* Destroy all outputs associated with this compositor */
7571 	wl_list_for_each_safe(output, next, &ec->output_list, link)
7572 		output->destroy(output);
7573 
7574 	/* Destroy all pending outputs associated with this compositor */
7575 	wl_list_for_each_safe(output, next, &ec->pending_output_list, link)
7576 		output->destroy(output);
7577 
7578 	if (ec->renderer)
7579 		ec->renderer->destroy(ec);
7580 
7581 	weston_binding_list_destroy_all(&ec->key_binding_list);
7582 	weston_binding_list_destroy_all(&ec->modifier_binding_list);
7583 	weston_binding_list_destroy_all(&ec->button_binding_list);
7584 	weston_binding_list_destroy_all(&ec->touch_binding_list);
7585 	weston_binding_list_destroy_all(&ec->axis_binding_list);
7586 	weston_binding_list_destroy_all(&ec->debug_binding_list);
7587 
7588 	weston_plane_release(&ec->primary_plane);
7589 }
7590 
7591 /** weston_compositor_exit_with_code
7592  * \ingroup compositor
7593  */
7594 WL_EXPORT void
weston_compositor_exit_with_code(struct weston_compositor * compositor,int exit_code)7595 weston_compositor_exit_with_code(struct weston_compositor *compositor,
7596 				 int exit_code)
7597 {
7598 	if (compositor->exit_code == EXIT_SUCCESS)
7599 		compositor->exit_code = exit_code;
7600 
7601 	weston_compositor_exit(compositor);
7602 }
7603 
7604 /** weston_compositor_set_default_pointer_grab
7605  * \ingroup compositor
7606  */
7607 WL_EXPORT void
weston_compositor_set_default_pointer_grab(struct weston_compositor * ec,const struct weston_pointer_grab_interface * interface)7608 weston_compositor_set_default_pointer_grab(struct weston_compositor *ec,
7609 			const struct weston_pointer_grab_interface *interface)
7610 {
7611 	struct weston_seat *seat;
7612 
7613 	ec->default_pointer_grab = interface;
7614 	wl_list_for_each(seat, &ec->seat_list, link) {
7615 		struct weston_pointer *pointer = weston_seat_get_pointer(seat);
7616 
7617 		if (pointer)
7618 			weston_pointer_set_default_grab(pointer, interface);
7619 	}
7620 }
7621 
7622 /** weston_compositor_set_presentation_clock
7623  * \ingroup compositor
7624  */
7625 WL_EXPORT int
weston_compositor_set_presentation_clock(struct weston_compositor * compositor,clockid_t clk_id)7626 weston_compositor_set_presentation_clock(struct weston_compositor *compositor,
7627 					 clockid_t clk_id)
7628 {
7629 	struct timespec ts;
7630 
7631 	if (clock_gettime(clk_id, &ts) < 0)
7632 		return -1;
7633 
7634 	compositor->presentation_clock = clk_id;
7635 
7636 	return 0;
7637 }
7638 
7639 /** For choosing the software clock, when the display hardware or API
7640  * does not expose a compatible presentation timestamp.
7641  *
7642  * \ingroup compositor
7643  */
7644 WL_EXPORT int
weston_compositor_set_presentation_clock_software(struct weston_compositor * compositor)7645 weston_compositor_set_presentation_clock_software(
7646 					struct weston_compositor *compositor)
7647 {
7648 	/* In order of preference */
7649 	static const clockid_t clocks[] = {
7650 		CLOCK_MONOTONIC_RAW,	/* no jumps, no crawling */
7651 		CLOCK_MONOTONIC_COARSE,	/* no jumps, may crawl, fast & coarse */
7652 		CLOCK_MONOTONIC,	/* no jumps, may crawl */
7653 		CLOCK_REALTIME_COARSE,	/* may jump and crawl, fast & coarse */
7654 		CLOCK_REALTIME		/* may jump and crawl */
7655 	};
7656 	unsigned i;
7657 
7658 	for (i = 0; i < ARRAY_LENGTH(clocks); i++)
7659 		if (weston_compositor_set_presentation_clock(compositor,
7660 							     clocks[i]) == 0)
7661 			return 0;
7662 
7663 	weston_log("Error: no suitable presentation clock available.\n");
7664 
7665 	return -1;
7666 }
7667 
7668 /** Read the current time from the Presentation clock
7669  *
7670  * \param compositor
7671  * \param[out] ts The current time.
7672  *
7673  * \note Reading the current time in user space is always imprecise to some
7674  * degree.
7675  *
7676  * This function is never meant to fail. If reading the clock does fail,
7677  * an error message is logged and a zero time is returned. Callers are not
7678  * supposed to detect or react to failures.
7679  *
7680  * \ingroup compositor
7681  */
7682 WL_EXPORT void
weston_compositor_read_presentation_clock(const struct weston_compositor * compositor,struct timespec * ts)7683 weston_compositor_read_presentation_clock(
7684 			const struct weston_compositor *compositor,
7685 			struct timespec *ts)
7686 {
7687 	static bool warned;
7688 	int ret;
7689 
7690 	ret = clock_gettime(compositor->presentation_clock, ts);
7691 	if (ret < 0) {
7692 		ts->tv_sec = 0;
7693 		ts->tv_nsec = 0;
7694 
7695 		if (!warned)
7696 			weston_log("Error: failure to read "
7697 				   "the presentation clock %#x: '%s' (%d)\n",
7698 				   compositor->presentation_clock,
7699 				   strerror(errno), errno);
7700 		warned = true;
7701 	}
7702 }
7703 
7704 /** Import dmabuf buffer into current renderer
7705  *
7706  * \param compositor
7707  * \param buffer the dmabuf buffer to import
7708  * \return true on usable buffers, false otherwise
7709  *
7710  * This function tests that the linux_dmabuf_buffer is usable
7711  * for the current renderer. Returns false on unusable buffers. Usually
7712  * usability is tested by importing the dmabufs for composition.
7713  *
7714  * This hook is also used for detecting if the renderer supports
7715  * dmabufs at all. If the renderer hook is NULL, dmabufs are not
7716  * supported.
7717  *
7718  * \ingroup compositor
7719  */
7720 WL_EXPORT bool
weston_compositor_import_dmabuf(struct weston_compositor * compositor,struct linux_dmabuf_buffer * buffer)7721 weston_compositor_import_dmabuf(struct weston_compositor *compositor,
7722 				struct linux_dmabuf_buffer *buffer)
7723 {
7724 	struct weston_renderer *renderer;
7725 
7726 	renderer = compositor->renderer;
7727 
7728 	if (renderer->import_dmabuf == NULL)
7729 		return false;
7730 
7731 	return renderer->import_dmabuf(compositor, buffer);
7732 }
7733 
7734 WL_EXPORT bool
weston_compositor_dmabuf_can_scanout(struct weston_compositor * compositor,struct linux_dmabuf_buffer * buffer)7735 weston_compositor_dmabuf_can_scanout(struct weston_compositor *compositor,
7736 		struct linux_dmabuf_buffer *buffer)
7737 {
7738 	struct weston_backend *backend = compositor->backend;
7739 
7740 	if (backend->can_scanout_dmabuf == NULL)
7741 		return false;
7742 
7743 	return backend->can_scanout_dmabuf(compositor, buffer);
7744 }
7745 
7746 WL_EXPORT void
weston_version(int * major,int * minor,int * micro)7747 weston_version(int *major, int *minor, int *micro)
7748 {
7749 	*major = WESTON_VERSION_MAJOR;
7750 	*minor = WESTON_VERSION_MINOR;
7751 	*micro = WESTON_VERSION_MICRO;
7752 }
7753 
7754 /**
7755  * Attempts to find a module path from the module map specified in the
7756  * environment. If found, writes the full path into the path variable.
7757  *
7758  * The module map is a string in environment variable WESTON_MODULE_MAP, where
7759  * each entry is of the form "name=path" and entries are separated by
7760  * semicolons. Whitespace is significant.
7761  *
7762  * \param name The name to search for.
7763  * \param path Where the path is written to if found.
7764  * \param path_len Allocated bytes at \c path .
7765  * \returns The length of the string written to path on success, or 0 if the
7766  * module was not specified in the environment map or path_len was too small.
7767  */
7768 WL_EXPORT size_t
weston_module_path_from_env(const char * name,char * path,size_t path_len)7769 weston_module_path_from_env(const char *name, char *path, size_t path_len)
7770 {
7771 	const char *mapping = getenv("WESTON_MODULE_MAP");
7772 	const char *end;
7773 	const int name_len = strlen(name);
7774 
7775 	if (!mapping)
7776 		return 0;
7777 
7778 	end = mapping + strlen(mapping);
7779 	while (mapping < end && *mapping) {
7780 		const char *filename, *next;
7781 
7782 		/* early out: impossibly short string */
7783 		if (end - mapping < name_len + 1)
7784 			return 0;
7785 
7786 		filename = &mapping[name_len + 1];
7787 		next = strchrnul(mapping, ';');
7788 
7789 		if (strncmp(mapping, name, name_len) == 0 &&
7790 		    mapping[name_len] == '=') {
7791 			size_t file_len = next - filename; /* no trailing NUL */
7792 			if (file_len >= path_len)
7793 				return 0;
7794 			strncpy(path, filename, file_len);
7795 			path[file_len] = '\0';
7796 			return file_len;
7797 		}
7798 
7799 		mapping = next + 1;
7800 	}
7801 
7802 	return 0;
7803 }
7804 
7805 WL_EXPORT void *
weston_load_module(const char * name,const char * entrypoint)7806 weston_load_module(const char *name, const char *entrypoint)
7807 {
7808 	char path[PATH_MAX];
7809 	void *module, *init;
7810 	size_t len;
7811 
7812 	if (name == NULL)
7813 		return NULL;
7814 
7815 	if (name[0] != '/') {
7816 		len = weston_module_path_from_env(name, path, sizeof path);
7817 		if (len == 0)
7818 			len = snprintf(path, sizeof path, "%s/%s",
7819 				       LIBWESTON_MODULEDIR, name);
7820 	} else {
7821 		len = snprintf(path, sizeof path, "%s", name);
7822 	}
7823 
7824 	/* snprintf returns the length of the string it would've written,
7825 	 * _excluding_ the NUL byte. So even being equal to the size of
7826 	 * our buffer is an error here. */
7827 	if (len >= sizeof path)
7828 		return NULL;
7829 
7830 	module = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
7831 	if (module) {
7832 		weston_log("Module '%s' already loaded\n", path);
7833 	} else {
7834 		weston_log("Loading module '%{public}s'\n", path);
7835 		module = dlopen(path, RTLD_NOW);
7836 		if (!module) {
7837 			weston_log("Failed to load module: %{public}s\n", dlerror());
7838 			return NULL;
7839 		}
7840 	}
7841 
7842 	init = dlsym(module, entrypoint);
7843 	if (!init) {
7844 		weston_log("Failed to lookup init function: %s\n", dlerror());
7845 		dlclose(module);
7846 		return NULL;
7847 	}
7848 
7849 	return init;
7850 }
7851 
7852 /** Add a compositor destroy listener only once
7853  *
7854  * \param compositor The compositor whose destroy to watch for.
7855  * \param listener The listener struct to initialize.
7856  * \param destroy_handler The callback when compositor is destroyed.
7857  * \return True if listener is added, or false if there already is a listener
7858  * with the given \c destroy_handler.
7859  *
7860  * This function does nothing and returns false if the given callback function
7861  * is already present in the weston_compositor destroy callbacks list.
7862  * Otherwise, this function initializes the given listener with the given
7863  * callback pointer and adds it to the compositor's destroy callbacks list.
7864  *
7865  * This can be used to ensure that plugin initialization is done only once
7866  * in case the same plugin is loaded multiple times. If this function returns
7867  * false, the plugin should be already initialized successfully.
7868  *
7869  * All plugins should register a destroy listener for cleaning up. Note, that
7870  * the plugin destruction order is not guaranteed: plugins that depend on other
7871  * plugins must be able to be torn down in arbitrary order.
7872  *
7873  * \sa weston_compositor_destroy
7874  */
7875 WL_EXPORT bool
weston_compositor_add_destroy_listener_once(struct weston_compositor * compositor,struct wl_listener * listener,wl_notify_func_t destroy_handler)7876 weston_compositor_add_destroy_listener_once(struct weston_compositor *compositor,
7877 					    struct wl_listener *listener,
7878 					    wl_notify_func_t destroy_handler)
7879 {
7880 	if (wl_signal_get(&compositor->destroy_signal, destroy_handler))
7881 		return false;
7882 
7883 	listener->notify = destroy_handler;
7884 	wl_signal_add(&compositor->destroy_signal, listener);
7885 	return true;
7886 }
7887 
7888 /** Destroys the compositor.
7889  *
7890  * This function cleans up the compositor state and then destroys it.
7891  *
7892  * @param compositor The compositor to be destroyed.
7893  *
7894  * @ingroup compositor
7895  */
7896 WL_EXPORT void
weston_compositor_destroy(struct weston_compositor * compositor)7897 weston_compositor_destroy(struct weston_compositor *compositor)
7898 {
7899 	/* prevent further rendering while shutting down */
7900 	compositor->state = WESTON_COMPOSITOR_OFFSCREEN;
7901 
7902 	wl_signal_emit(&compositor->destroy_signal, compositor);
7903 
7904 	weston_compositor_xkb_destroy(compositor);
7905 
7906 	if (compositor->backend)
7907 		compositor->backend->destroy(compositor);
7908 
7909 	/* The backend is responsible for destroying the heads. */
7910 	assert(wl_list_empty(&compositor->head_list));
7911 
7912 	weston_plugin_api_destroy_list(compositor);
7913 
7914 	if (compositor->heads_changed_source)
7915 		wl_event_source_remove(compositor->heads_changed_source);
7916 
7917 // OHOS remove logger
7918 //	weston_log_scope_destroy(compositor->debug_scene);
7919 //	compositor->debug_scene = NULL;
7920 //
7921 //	weston_log_scope_destroy(compositor->timeline);
7922 //	compositor->timeline = NULL;
7923 
7924 	free(compositor);
7925 }
7926 
7927 /** Instruct the compositor to exit.
7928  *
7929  * This functions does not directly destroy the compositor object, it merely
7930  * command it to start the tear down process. It is not guaranteed that the
7931  * tear down will happen immediately.
7932  *
7933  * \param compositor The compositor to tear down.
7934  *
7935  * \ingroup compositor
7936  */
7937 WL_EXPORT void
weston_compositor_exit(struct weston_compositor * compositor)7938 weston_compositor_exit(struct weston_compositor *compositor)
7939 {
7940 	compositor->exit(compositor);
7941 }
7942 
7943 /** Return the user data stored in the compositor.
7944  *
7945  * This function returns the user data pointer set with user_data parameter
7946  * to the \ref weston_compositor_create function.
7947  *
7948  * \ingroup compositor
7949  */
7950 WL_EXPORT void *
weston_compositor_get_user_data(struct weston_compositor * compositor)7951 weston_compositor_get_user_data(struct weston_compositor *compositor)
7952 {
7953 	return compositor->user_data;
7954 }
7955 
7956 static const char * const backend_map[] = {
7957 	[WESTON_BACKEND_DRM] =		"drm-backend.so",
7958 	[WESTON_BACKEND_FBDEV] =	"fbdev-backend.so",
7959 	[WESTON_BACKEND_HEADLESS] =	"headless-backend.so",
7960 	[WESTON_BACKEND_RDP] =		"rdp-backend.so",
7961 	[WESTON_BACKEND_WAYLAND] =	"wayland-backend.so",
7962 	[WESTON_BACKEND_X11] =		"x11-backend.so",
7963 	[WESTON_BACKEND_HDI] =	"hdi-backend.so",
7964 };
7965 
7966 /** Load a backend into a weston_compositor
7967  *
7968  * A backend must be loaded to make a weston_compositor work. A backend
7969  * provides input and output capabilities, and determines the renderer to use.
7970  *
7971  * \param compositor A compositor that has not had a backend loaded yet.
7972  * \param backend Name of the backend file.
7973  * \param config_base A pointer to a backend-specific configuration
7974  * structure's 'base' member.
7975  *
7976  * \return 0 on success, or -1 on error.
7977  *
7978  * \ingroup compositor
7979  */
7980 WL_EXPORT int
weston_compositor_load_backend(struct weston_compositor * compositor,enum weston_compositor_backend backend,struct weston_backend_config * config_base)7981 weston_compositor_load_backend(struct weston_compositor *compositor,
7982 			       enum weston_compositor_backend backend,
7983 			       struct weston_backend_config *config_base)
7984 {
7985 	int (*backend_init)(struct weston_compositor *c,
7986 			    struct weston_backend_config *config_base);
7987 
7988 	if (compositor->backend) {
7989 		weston_log("Error: attempt to load a backend when one is already loaded\n");
7990 		return -1;
7991 	}
7992 
7993 	if (backend >= ARRAY_LENGTH(backend_map))
7994 		return -1;
7995 
7996 	backend_init = weston_load_module(backend_map[backend], "weston_backend_init");
7997 	if (!backend_init)
7998 		return -1;
7999 
8000 	if (backend_init(compositor, config_base) < 0) {
8001 		compositor->backend = NULL;
8002 		return -1;
8003 	}
8004 
8005 	return 0;
8006 }
8007 
8008 /** weston_compositor_load_xwayland
8009  * \ingroup compositor
8010  */
8011 WL_EXPORT int
weston_compositor_load_xwayland(struct weston_compositor * compositor)8012 weston_compositor_load_xwayland(struct weston_compositor *compositor)
8013 {
8014 	int (*module_init)(struct weston_compositor *ec);
8015 
8016 	module_init = weston_load_module("xwayland.so", "weston_module_init");
8017 	if (!module_init)
8018 		return -1;
8019 	if (module_init(compositor) < 0)
8020 		return -1;
8021 	return 0;
8022 }
8023 
8024 /** Resolve an internal compositor error by disconnecting the client.
8025  *
8026  * This function is used in cases when the wl_buffer turns out
8027  * unusable and there is no fallback path.
8028  *
8029  * It is possible the fault is caused by a compositor bug, the underlying
8030  * graphics stack bug or normal behaviour, or perhaps a client mistake.
8031  * In any case, the options are to either composite garbage or nothing,
8032  * or disconnect the client. This is a helper function for the latter.
8033  *
8034  * The error is sent as an INVALID_OBJECT error on the client's wl_display.
8035  *
8036  * \param buffer The weston buffer that is unusable.
8037  * \param msg A custom error message attached to the protocol error.
8038  */
8039 WL_EXPORT void
weston_buffer_send_server_error(struct weston_buffer * buffer,const char * msg)8040 weston_buffer_send_server_error(struct weston_buffer *buffer,
8041 				      const char *msg)
8042 {
8043 	struct wl_client *client;
8044 	struct wl_resource *display_resource;
8045 	uint32_t id;
8046 
8047 	assert(buffer->resource);
8048 	id = wl_resource_get_id(buffer->resource);
8049 	client = wl_resource_get_client(buffer->resource);
8050 	display_resource = wl_client_get_object(client, 1);
8051 
8052 	assert(display_resource);
8053 	wl_resource_post_error(display_resource,
8054 			       WL_DISPLAY_ERROR_INVALID_OBJECT,
8055 			       "server error with "
8056 			       "wl_buffer@%u: %s", id, msg);
8057 }
8058 
8059 WL_EXPORT void
weston_output_disable_planes_incr(struct weston_output * output)8060 weston_output_disable_planes_incr(struct weston_output *output)
8061 {
8062 	output->disable_planes++;
8063 	/*
8064 	 * If disable_planes changes from 0 to non-zero, it means some type of
8065 	 * recording of content has started, and therefore protection level of
8066 	 * the protected surfaces must be updated to avoid the recording of
8067 	 * the protected content.
8068 	 */
8069 	if (output->disable_planes == 1)
8070 		weston_schedule_surface_protection_update(output->compositor);
8071 }
8072 
8073 WL_EXPORT void
weston_output_disable_planes_decr(struct weston_output * output)8074 weston_output_disable_planes_decr(struct weston_output *output)
8075 {
8076 	output->disable_planes--;
8077 	/*
8078 	 * If disable_planes changes from non-zero to 0, it means no content
8079 	 * recording is going on any more, and the protected and surfaces can be
8080 	 * shown without any apprehensions about content being recorded.
8081 	 */
8082 	if (output->disable_planes == 0)
8083 		weston_schedule_surface_protection_update(output->compositor);
8084 
8085 }
8086