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