mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-10-29 05:40:12 -04:00 
			
		
		
		
	output: add wlr_output_state_init()
This changes the semantics of wlr_output_state. Instead of having fields with uninitialized memory when missing from the committed bitflag, all fields are always initialized (and maybe NULL/empty), just like we do in wlr_surface_state. This reduces the chances of footguns when reading a field, and removes the need to check for the committed bitfield everywhere. A new wlr_output_state_init() function takes care of initializing the Pixman region.
This commit is contained in:
		
							parent
							
								
									8a5b5e6f28
								
							
						
					
					
						commit
						be05097968
					
				
					 19 changed files with 103 additions and 103 deletions
				
			
		|  | @ -121,22 +121,21 @@ static void handle_session_active(struct wl_listener *listener, void *data) { | ||||||
| 		struct wlr_drm_connector *conn; | 		struct wlr_drm_connector *conn; | ||||||
| 		wl_list_for_each(conn, &drm->connectors, link) { | 		wl_list_for_each(conn, &drm->connectors, link) { | ||||||
| 			struct wlr_output_mode *mode = NULL; | 			struct wlr_output_mode *mode = NULL; | ||||||
| 			uint32_t committed = WLR_OUTPUT_STATE_ENABLED; |  | ||||||
| 			if (conn->status != DRM_MODE_DISCONNECTED && conn->output.enabled | 			if (conn->status != DRM_MODE_DISCONNECTED && conn->output.enabled | ||||||
| 					&& conn->output.current_mode != NULL) { | 					&& conn->output.current_mode != NULL) { | ||||||
| 				committed |= WLR_OUTPUT_STATE_MODE; |  | ||||||
| 				mode = conn->output.current_mode; | 				mode = conn->output.current_mode; | ||||||
| 			} | 			} | ||||||
| 			struct wlr_output_state state = { | 
 | ||||||
| 				.committed = committed, | 			struct wlr_output_state state; | ||||||
| 				.allow_artifacts = true, | 			wlr_output_state_init(&state); | ||||||
| 				.enabled = mode != NULL, | 			wlr_output_state_set_enabled(&state, mode != NULL); | ||||||
| 				.mode_type = WLR_OUTPUT_STATE_MODE_FIXED, | 			if (mode != NULL) { | ||||||
| 				.mode = mode, | 				wlr_output_state_set_mode(&state, mode); | ||||||
| 			}; | 			} | ||||||
| 			if (!drm_connector_commit_state(conn, &state)) { | 			if (!drm_connector_commit_state(conn, &state)) { | ||||||
| 				wlr_drm_conn_log(conn, WLR_ERROR, "Failed to restore state after VT switch"); | 				wlr_drm_conn_log(conn, WLR_ERROR, "Failed to restore state after VT switch"); | ||||||
| 			} | 			} | ||||||
|  | 			wlr_output_state_finish(&state); | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		wlr_log(WLR_INFO, "DRM fd paused"); | 		wlr_log(WLR_INFO, "DRM fd paused"); | ||||||
|  |  | ||||||
|  | @ -1155,16 +1155,15 @@ static void dealloc_crtc(struct wlr_drm_connector *conn) { | ||||||
| 	wlr_drm_conn_log(conn, WLR_DEBUG, "De-allocating CRTC %" PRIu32, | 	wlr_drm_conn_log(conn, WLR_DEBUG, "De-allocating CRTC %" PRIu32, | ||||||
| 		conn->crtc->id); | 		conn->crtc->id); | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_state state = { | 	struct wlr_output_state state; | ||||||
| 		.committed = WLR_OUTPUT_STATE_ENABLED, | 	wlr_output_state_init(&state); | ||||||
| 		.allow_artifacts = true, | 	wlr_output_state_set_enabled(&state, false); | ||||||
| 		.enabled = false, |  | ||||||
| 	}; |  | ||||||
| 	if (!drm_connector_commit_state(conn, &state)) { | 	if (!drm_connector_commit_state(conn, &state)) { | ||||||
| 		// On GPU unplug, disabling the CRTC can fail with EPERM
 | 		// On GPU unplug, disabling the CRTC can fail with EPERM
 | ||||||
| 		wlr_drm_conn_log(conn, WLR_ERROR, "Failed to disable CRTC %"PRIu32, | 		wlr_drm_conn_log(conn, WLR_ERROR, "Failed to disable CRTC %"PRIu32, | ||||||
| 			conn->crtc->id); | 			conn->crtc->id); | ||||||
| 	} | 	} | ||||||
|  | 	wlr_output_state_finish(&state); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void realloc_crtcs(struct wlr_drm_backend *drm, | static void realloc_crtcs(struct wlr_drm_backend *drm, | ||||||
|  |  | ||||||
|  | @ -703,12 +703,11 @@ static void xdg_toplevel_handle_configure(void *data, | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_state state = { | 	struct wlr_output_state state; | ||||||
| 		.committed = WLR_OUTPUT_STATE_MODE, | 	wlr_output_state_init(&state); | ||||||
| 		.mode_type = WLR_OUTPUT_STATE_MODE_CUSTOM, | 	wlr_output_state_set_custom_mode(&state, width, height, 0); | ||||||
| 		.custom_mode = { .width = width, .height = height }, |  | ||||||
| 	}; |  | ||||||
| 	wlr_output_send_request_state(&output->wlr_output, &state); | 	wlr_output_send_request_state(&output->wlr_output, &state); | ||||||
|  | 	wlr_output_state_finish(&state); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void xdg_toplevel_handle_close(void *data, | static void xdg_toplevel_handle_close(void *data, | ||||||
|  |  | ||||||
|  | @ -623,12 +623,11 @@ void handle_x11_configure_notify(struct wlr_x11_output *output, | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_state state = { | 	struct wlr_output_state state; | ||||||
| 		.committed = WLR_OUTPUT_STATE_MODE, | 	wlr_output_state_init(&state); | ||||||
| 		.mode_type = WLR_OUTPUT_STATE_MODE_CUSTOM, | 	wlr_output_state_set_custom_mode(&state, ev->width, ev->height, 0); | ||||||
| 		.custom_mode = { .width = ev->width, .height = ev->height }, |  | ||||||
| 	}; |  | ||||||
| 	wlr_output_send_request_state(&output->wlr_output, &state); | 	wlr_output_send_request_state(&output->wlr_output, &state); | ||||||
|  | 	wlr_output_state_finish(&state); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool wlr_output_is_x11(struct wlr_output *wlr_output) { | bool wlr_output_is_x11(struct wlr_output *wlr_output) { | ||||||
|  |  | ||||||
|  | @ -89,7 +89,8 @@ static void output_handle_frame(struct wl_listener *listener, void *data) { | ||||||
| 	int width, height; | 	int width, height; | ||||||
| 	wlr_output_effective_resolution(output->wlr_output, &width, &height); | 	wlr_output_effective_resolution(output->wlr_output, &width, &height); | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_state state = {0}; | 	struct wlr_output_state state; | ||||||
|  | 	wlr_output_state_init(&state); | ||||||
| 	struct wlr_render_pass *pass = wlr_output_begin_render_pass(output->wlr_output, &state, NULL, | 	struct wlr_render_pass *pass = wlr_output_begin_render_pass(output->wlr_output, &state, NULL, | ||||||
| 		NULL); | 		NULL); | ||||||
| 	if (pass == NULL) { | 	if (pass == NULL) { | ||||||
|  | @ -166,7 +167,8 @@ static void server_handle_new_output(struct wl_listener *listener, void *data) { | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output); | 	struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output); | ||||||
| 	if (mode != NULL) { | 	if (mode != NULL) { | ||||||
| 		struct wlr_output_state state = {0}; | 		struct wlr_output_state state; | ||||||
|  | 		wlr_output_state_init(&state); | ||||||
| 		wlr_output_state_set_mode(&state, mode); | 		wlr_output_state_set_mode(&state, mode); | ||||||
| 		wlr_output_commit_state(wlr_output, &state); | 		wlr_output_commit_state(wlr_output, &state); | ||||||
| 		wlr_output_state_finish(&state); | 		wlr_output_state_finish(&state); | ||||||
|  |  | ||||||
|  | @ -82,7 +82,8 @@ static void output_handle_frame(struct wl_listener *listener, void *data) { | ||||||
| 		}; | 		}; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_state output_state = {0}; | 	struct wlr_output_state output_state; | ||||||
|  | 	wlr_output_state_init(&output_state); | ||||||
| 	wlr_output_state_set_layers(&output_state, layers_arr.data, | 	wlr_output_state_set_layers(&output_state, layers_arr.data, | ||||||
| 		layers_arr.size / sizeof(struct wlr_output_layer_state)); | 		layers_arr.size / sizeof(struct wlr_output_layer_state)); | ||||||
| 
 | 
 | ||||||
|  | @ -175,7 +176,8 @@ static void server_handle_new_output(struct wl_listener *listener, void *data) { | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output); | 	struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output); | ||||||
| 	if (mode != NULL) { | 	if (mode != NULL) { | ||||||
| 		struct wlr_output_state state = {0}; | 		struct wlr_output_state state; | ||||||
|  | 		wlr_output_state_init(&state); | ||||||
| 		wlr_output_state_set_mode(&state, mode); | 		wlr_output_state_set_mode(&state, mode); | ||||||
| 		wlr_output_commit_state(wlr_output, &state); | 		wlr_output_commit_state(wlr_output, &state); | ||||||
| 		wlr_output_state_finish(&state); | 		wlr_output_state_finish(&state); | ||||||
|  |  | ||||||
|  | @ -114,7 +114,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { | ||||||
| 	struct sample_state *sample = output->sample; | 	struct sample_state *sample = output->sample; | ||||||
| 	struct wlr_output *wlr_output = output->output; | 	struct wlr_output *wlr_output = output->output; | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_state output_state = {0}; | 	struct wlr_output_state output_state; | ||||||
|  | 	wlr_output_state_init(&output_state); | ||||||
| 	struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL); | 	struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL); | ||||||
| 
 | 
 | ||||||
| 	wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){ | 	wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){ | ||||||
|  | @ -178,7 +179,8 @@ static void new_output_notify(struct wl_listener *listener, void *data) { | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_mode *mode = wlr_output_preferred_mode(output); | 	struct wlr_output_mode *mode = wlr_output_preferred_mode(output); | ||||||
| 	if (mode != NULL) { | 	if (mode != NULL) { | ||||||
| 		struct wlr_output_state state = {0}; | 		struct wlr_output_state state; | ||||||
|  | 		wlr_output_state_init(&state); | ||||||
| 		wlr_output_state_set_mode(&state, mode); | 		wlr_output_state_set_mode(&state, mode); | ||||||
| 		wlr_output_commit_state(output, &state); | 		wlr_output_commit_state(output, &state); | ||||||
| 		wlr_output_state_finish(&state); | 		wlr_output_state_finish(&state); | ||||||
|  |  | ||||||
|  | @ -101,7 +101,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { | ||||||
| 	struct wlr_renderer *renderer = state->renderer; | 	struct wlr_renderer *renderer = state->renderer; | ||||||
| 	assert(renderer); | 	assert(renderer); | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_state output_state = {0}; | 	struct wlr_output_state output_state; | ||||||
|  | 	wlr_output_state_init(&output_state); | ||||||
| 	struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL); | 	struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL); | ||||||
| 	wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){ | 	wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){ | ||||||
| 		.box = { .width = wlr_output->width, .height = wlr_output->height }, | 		.box = { .width = wlr_output->width, .height = wlr_output->height }, | ||||||
|  | @ -280,7 +281,8 @@ static void new_output_notify(struct wl_listener *listener, void *data) { | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_mode *mode = wlr_output_preferred_mode(output); | 	struct wlr_output_mode *mode = wlr_output_preferred_mode(output); | ||||||
| 	if (mode != NULL) { | 	if (mode != NULL) { | ||||||
| 		struct wlr_output_state state = {0}; | 		struct wlr_output_state state; | ||||||
|  | 		wlr_output_state_init(&state); | ||||||
| 		wlr_output_state_set_mode(&state, mode); | 		wlr_output_state_set_mode(&state, mode); | ||||||
| 		wlr_output_commit_state(output, &state); | 		wlr_output_commit_state(output, &state); | ||||||
| 		wlr_output_state_finish(&state); | 		wlr_output_state_finish(&state); | ||||||
|  |  | ||||||
|  | @ -59,7 +59,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { | ||||||
| 	int32_t width, height; | 	int32_t width, height; | ||||||
| 	wlr_output_effective_resolution(wlr_output, &width, &height); | 	wlr_output_effective_resolution(wlr_output, &width, &height); | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_state output_state = {0}; | 	struct wlr_output_state output_state; | ||||||
|  | 	wlr_output_state_init(&output_state); | ||||||
| 	struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL); | 	struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL); | ||||||
| 
 | 
 | ||||||
| 	wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){ | 	wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){ | ||||||
|  | @ -122,7 +123,8 @@ static void new_output_notify(struct wl_listener *listener, void *data) { | ||||||
| 	sample_output->x_offs = sample_output->y_offs = 0; | 	sample_output->x_offs = sample_output->y_offs = 0; | ||||||
| 	sample_output->x_vel = sample_output->y_vel = 128; | 	sample_output->x_vel = sample_output->y_vel = 128; | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_state state = {0}; | 	struct wlr_output_state state; | ||||||
|  | 	wlr_output_state_init(&state); | ||||||
| 	wlr_output_state_set_transform(&state, sample->transform); | 	wlr_output_state_set_transform(&state, sample->transform); | ||||||
| 
 | 
 | ||||||
| 	sample_output->output = output; | 	sample_output->output = output; | ||||||
|  |  | ||||||
|  | @ -83,7 +83,8 @@ static void server_handle_new_output(struct wl_listener *listener, void *data) { | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output); | 	struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output); | ||||||
| 	if (mode != NULL) { | 	if (mode != NULL) { | ||||||
| 		struct wlr_output_state state = {0}; | 		struct wlr_output_state state; | ||||||
|  | 		wlr_output_state_init(&state); | ||||||
| 		wlr_output_state_set_mode(&state, mode); | 		wlr_output_state_set_mode(&state, mode); | ||||||
| 		wlr_output_commit_state(wlr_output, &state); | 		wlr_output_commit_state(wlr_output, &state); | ||||||
| 		wlr_output_state_finish(&state); | 		wlr_output_state_finish(&state); | ||||||
|  |  | ||||||
|  | @ -62,7 +62,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { | ||||||
| 		sample->dec = inc; | 		sample->dec = inc; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_state state = {0}; | 	struct wlr_output_state state; | ||||||
|  | 	wlr_output_state_init(&state); | ||||||
| 	struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &state, NULL, NULL); | 	struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &state, NULL, NULL); | ||||||
| 	wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){ | 	wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){ | ||||||
| 		.box = { .width = wlr_output->width, .height = wlr_output->height }, | 		.box = { .width = wlr_output->width, .height = wlr_output->height }, | ||||||
|  | @ -107,7 +108,8 @@ static void new_output_notify(struct wl_listener *listener, void *data) { | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_mode *mode = wlr_output_preferred_mode(output); | 	struct wlr_output_mode *mode = wlr_output_preferred_mode(output); | ||||||
| 	if (mode != NULL) { | 	if (mode != NULL) { | ||||||
| 		struct wlr_output_state state = {0}; | 		struct wlr_output_state state; | ||||||
|  | 		wlr_output_state_init(&state); | ||||||
| 		wlr_output_state_set_mode(&state, mode); | 		wlr_output_state_set_mode(&state, mode); | ||||||
| 		wlr_output_commit_state(sample_output->output, &state); | 		wlr_output_commit_state(sample_output->output, &state); | ||||||
| 		wlr_output_state_finish(&state); | 		wlr_output_state_finish(&state); | ||||||
|  |  | ||||||
|  | @ -87,7 +87,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { | ||||||
| 	int32_t width, height; | 	int32_t width, height; | ||||||
| 	wlr_output_effective_resolution(wlr_output, &width, &height); | 	wlr_output_effective_resolution(wlr_output, &width, &height); | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_state output_state = {0}; | 	struct wlr_output_state output_state; | ||||||
|  | 	wlr_output_state_init(&output_state); | ||||||
| 	struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL); | 	struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL); | ||||||
| 
 | 
 | ||||||
| 	wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){ | 	wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){ | ||||||
|  | @ -285,7 +286,8 @@ static void new_output_notify(struct wl_listener *listener, void *data) { | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_mode *mode = wlr_output_preferred_mode(output); | 	struct wlr_output_mode *mode = wlr_output_preferred_mode(output); | ||||||
| 	if (mode != NULL) { | 	if (mode != NULL) { | ||||||
| 		struct wlr_output_state state = {0}; | 		struct wlr_output_state state; | ||||||
|  | 		wlr_output_state_init(&state); | ||||||
| 		wlr_output_state_set_mode(&state, mode); | 		wlr_output_state_set_mode(&state, mode); | ||||||
| 		wlr_output_commit_state(output, &state); | 		wlr_output_commit_state(output, &state); | ||||||
| 		wlr_output_state_finish(&state); | 		wlr_output_state_finish(&state); | ||||||
|  |  | ||||||
|  | @ -76,7 +76,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) { | ||||||
| 	int32_t width, height; | 	int32_t width, height; | ||||||
| 	wlr_output_effective_resolution(wlr_output, &width, &height); | 	wlr_output_effective_resolution(wlr_output, &width, &height); | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_state output_state = {0}; | 	struct wlr_output_state output_state; | ||||||
|  | 	wlr_output_state_init(&output_state); | ||||||
| 	struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL); | 	struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL); | ||||||
| 	wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){ | 	wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){ | ||||||
| 		.box = { .width = width, .height = height }, | 		.box = { .width = width, .height = height }, | ||||||
|  | @ -184,7 +185,8 @@ static void new_output_notify(struct wl_listener *listener, void *data) { | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_mode *mode = wlr_output_preferred_mode(output); | 	struct wlr_output_mode *mode = wlr_output_preferred_mode(output); | ||||||
| 	if (mode != NULL) { | 	if (mode != NULL) { | ||||||
| 		struct wlr_output_state state = {0}; | 		struct wlr_output_state state; | ||||||
|  | 		wlr_output_state_init(&state); | ||||||
| 		wlr_output_state_set_mode(&state, mode); | 		wlr_output_state_set_mode(&state, mode); | ||||||
| 		wlr_output_commit_state(output, &state); | 		wlr_output_commit_state(output, &state); | ||||||
| 		wlr_output_state_finish(&state); | 		wlr_output_state_finish(&state); | ||||||
|  |  | ||||||
|  | @ -88,10 +88,8 @@ struct wlr_output_state { | ||||||
| 	uint32_t render_format; | 	uint32_t render_format; | ||||||
| 	enum wl_output_subpixel subpixel; | 	enum wl_output_subpixel subpixel; | ||||||
| 
 | 
 | ||||||
| 	// only valid if WLR_OUTPUT_STATE_BUFFER
 |  | ||||||
| 	struct wlr_buffer *buffer; | 	struct wlr_buffer *buffer; | ||||||
| 
 | 
 | ||||||
| 	// only valid if WLR_OUTPUT_STATE_MODE
 |  | ||||||
| 	enum wlr_output_state_mode_type mode_type; | 	enum wlr_output_state_mode_type mode_type; | ||||||
| 	struct wlr_output_mode *mode; | 	struct wlr_output_mode *mode; | ||||||
| 	struct { | 	struct { | ||||||
|  | @ -99,11 +97,9 @@ struct wlr_output_state { | ||||||
| 		int32_t refresh; // mHz, may be zero
 | 		int32_t refresh; // mHz, may be zero
 | ||||||
| 	} custom_mode; | 	} custom_mode; | ||||||
| 
 | 
 | ||||||
| 	// only valid if WLR_OUTPUT_STATE_GAMMA_LUT
 |  | ||||||
| 	uint16_t *gamma_lut; | 	uint16_t *gamma_lut; | ||||||
| 	size_t gamma_lut_size; | 	size_t gamma_lut_size; | ||||||
| 
 | 
 | ||||||
| 	// only valid if WLR_OUTPUT_STATE_LAYERS
 |  | ||||||
| 	struct wlr_output_layer_state *layers; | 	struct wlr_output_layer_state *layers; | ||||||
| 	size_t layers_len; | 	size_t layers_len; | ||||||
| }; | }; | ||||||
|  | @ -567,6 +563,10 @@ bool wlr_output_cursor_move(struct wlr_output_cursor *cursor, | ||||||
| 	double x, double y); | 	double x, double y); | ||||||
| void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor); | void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor); | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * Initialize an output state. | ||||||
|  |  */ | ||||||
|  | void wlr_output_state_init(struct wlr_output_state *state); | ||||||
| /**
 | /**
 | ||||||
|  * Releases all resources associated with an output state. |  * Releases all resources associated with an output state. | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  | @ -603,7 +603,8 @@ static void server_new_output(struct wl_listener *listener, void *data) { | ||||||
| 	 * would let the user configure it. */ | 	 * would let the user configure it. */ | ||||||
| 	struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output); | 	struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output); | ||||||
| 	if (mode != NULL) { | 	if (mode != NULL) { | ||||||
| 		struct wlr_output_state state = {0}; | 		struct wlr_output_state state; | ||||||
|  | 		wlr_output_state_init(&state); | ||||||
| 		wlr_output_state_set_mode(&state, mode); | 		wlr_output_state_set_mode(&state, mode); | ||||||
| 		wlr_output_state_set_enabled(&state, true); | 		wlr_output_state_set_enabled(&state, true); | ||||||
| 		if (!wlr_output_commit_state(wlr_output, &state)) { | 		if (!wlr_output_commit_state(wlr_output, &state)) { | ||||||
|  |  | ||||||
|  | @ -319,15 +319,10 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) { | ||||||
| 	wlr_output_destroy_global(output); | 	wlr_output_destroy_global(output); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void output_state_init(struct wlr_output_state *state) { |  | ||||||
| 	memset(state, 0, sizeof(*state)); |  | ||||||
| 	pixman_region32_init(&state->damage); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void output_state_move(struct wlr_output_state *dst, | static void output_state_move(struct wlr_output_state *dst, | ||||||
| 		struct wlr_output_state *src) { | 		struct wlr_output_state *src) { | ||||||
| 	*dst = *src; | 	*dst = *src; | ||||||
| 	output_state_init(src); | 	wlr_output_state_init(src); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, | void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, | ||||||
|  | @ -359,7 +354,7 @@ void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, | ||||||
| 	wl_signal_init(&output->events.description); | 	wl_signal_init(&output->events.description); | ||||||
| 	wl_signal_init(&output->events.request_state); | 	wl_signal_init(&output->events.request_state); | ||||||
| 	wl_signal_init(&output->events.destroy); | 	wl_signal_init(&output->events.destroy); | ||||||
| 	output_state_init(&output->pending); | 	wlr_output_state_init(&output->pending); | ||||||
| 
 | 
 | ||||||
| 	output->software_cursor_locks = env_parse_bool("WLR_NO_HARDWARE_CURSORS"); | 	output->software_cursor_locks = env_parse_bool("WLR_NO_HARDWARE_CURSORS"); | ||||||
| 	if (output->software_cursor_locks) { | 	if (output->software_cursor_locks) { | ||||||
|  |  | ||||||
|  | @ -3,20 +3,19 @@ | ||||||
| #include <wlr/util/log.h> | #include <wlr/util/log.h> | ||||||
| #include "types/wlr_output.h" | #include "types/wlr_output.h" | ||||||
| 
 | 
 | ||||||
|  | void wlr_output_state_init(struct wlr_output_state *state) { | ||||||
|  | 	*state = (struct wlr_output_state){0}; | ||||||
|  | 	pixman_region32_init(&state->damage); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void wlr_output_state_finish(struct wlr_output_state *state) { | void wlr_output_state_finish(struct wlr_output_state *state) { | ||||||
| 	if (state->committed & WLR_OUTPUT_STATE_BUFFER) { | 	wlr_buffer_unlock(state->buffer); | ||||||
| 		wlr_buffer_unlock(state->buffer); | 	// struct wlr_buffer is ref'counted, so the pointer may remain valid after
 | ||||||
| 		// struct wlr_buffer is ref'counted, so the pointer may remain valid after
 | 	// wlr_buffer_unlock(). Reset the field to NULL to ensure nobody mistakenly
 | ||||||
| 		// wlr_buffer_unlock(). Reset the field to NULL to ensure nobody mistakenly
 | 	// reads it after output_state_finish().
 | ||||||
| 		// reads it after output_state_finish().
 | 	state->buffer = NULL; | ||||||
| 		state->buffer = NULL; | 	pixman_region32_fini(&state->damage); | ||||||
| 	} | 	free(state->gamma_lut); | ||||||
| 	if (state->committed & WLR_OUTPUT_STATE_DAMAGE) { |  | ||||||
| 		pixman_region32_fini(&state->damage); |  | ||||||
| 	} |  | ||||||
| 	if (state->committed & WLR_OUTPUT_STATE_GAMMA_LUT) { |  | ||||||
| 		free(state->gamma_lut); |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void wlr_output_state_set_enabled(struct wlr_output_state *state, | void wlr_output_state_set_enabled(struct wlr_output_state *state, | ||||||
|  | @ -75,23 +74,14 @@ void wlr_output_state_set_subpixel(struct wlr_output_state *state, | ||||||
| 
 | 
 | ||||||
| void wlr_output_state_set_buffer(struct wlr_output_state *state, | void wlr_output_state_set_buffer(struct wlr_output_state *state, | ||||||
| 		struct wlr_buffer *buffer) { | 		struct wlr_buffer *buffer) { | ||||||
| 	if (state->committed & WLR_OUTPUT_STATE_BUFFER) { |  | ||||||
| 		wlr_buffer_unlock(state->buffer); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	state->committed |= WLR_OUTPUT_STATE_BUFFER; | 	state->committed |= WLR_OUTPUT_STATE_BUFFER; | ||||||
|  | 	wlr_buffer_unlock(state->buffer); | ||||||
| 	state->buffer = wlr_buffer_lock(buffer); | 	state->buffer = wlr_buffer_lock(buffer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void wlr_output_state_set_damage(struct wlr_output_state *state, | void wlr_output_state_set_damage(struct wlr_output_state *state, | ||||||
| 		const pixman_region32_t *damage) { | 		const pixman_region32_t *damage) { | ||||||
| 	if (state->committed & WLR_OUTPUT_STATE_DAMAGE) { |  | ||||||
| 		pixman_region32_fini(&state->damage); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	state->committed |= WLR_OUTPUT_STATE_DAMAGE; | 	state->committed |= WLR_OUTPUT_STATE_DAMAGE; | ||||||
| 
 |  | ||||||
| 	pixman_region32_init(&state->damage); |  | ||||||
| 	pixman_region32_copy(&state->damage, damage); | 	pixman_region32_copy(&state->damage, damage); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -99,11 +89,7 @@ bool wlr_output_state_set_gamma_lut(struct wlr_output_state *state, | ||||||
| 		size_t ramp_size, const uint16_t *r, const uint16_t *g, const uint16_t *b) { | 		size_t ramp_size, const uint16_t *r, const uint16_t *g, const uint16_t *b) { | ||||||
| 	uint16_t *gamma_lut = NULL; | 	uint16_t *gamma_lut = NULL; | ||||||
| 	if (ramp_size > 0) { | 	if (ramp_size > 0) { | ||||||
| 		if (state->committed & WLR_OUTPUT_STATE_GAMMA_LUT) { | 		gamma_lut = realloc(state->gamma_lut, 3 * ramp_size * sizeof(uint16_t)); | ||||||
| 			gamma_lut = realloc(state->gamma_lut, 3 * ramp_size * sizeof(uint16_t)); |  | ||||||
| 		} else { |  | ||||||
| 			gamma_lut = malloc(3 * ramp_size * sizeof(uint16_t)); |  | ||||||
| 		} |  | ||||||
| 		if (gamma_lut == NULL) { | 		if (gamma_lut == NULL) { | ||||||
| 			wlr_log_errno(WLR_ERROR, "Allocation failed"); | 			wlr_log_errno(WLR_ERROR, "Allocation failed"); | ||||||
| 			return false; | 			return false; | ||||||
|  | @ -112,9 +98,7 @@ bool wlr_output_state_set_gamma_lut(struct wlr_output_state *state, | ||||||
| 		memcpy(gamma_lut + ramp_size, g, ramp_size * sizeof(uint16_t)); | 		memcpy(gamma_lut + ramp_size, g, ramp_size * sizeof(uint16_t)); | ||||||
| 		memcpy(gamma_lut + 2 * ramp_size, b, ramp_size * sizeof(uint16_t)); | 		memcpy(gamma_lut + 2 * ramp_size, b, ramp_size * sizeof(uint16_t)); | ||||||
| 	} else { | 	} else { | ||||||
| 		if (state->committed & WLR_OUTPUT_STATE_GAMMA_LUT) { | 		free(state->gamma_lut); | ||||||
| 			free(state->gamma_lut); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	state->committed |= WLR_OUTPUT_STATE_GAMMA_LUT; | 	state->committed |= WLR_OUTPUT_STATE_GAMMA_LUT; | ||||||
|  | @ -136,6 +120,10 @@ bool wlr_output_state_copy(struct wlr_output_state *dst, | ||||||
| 	copy.committed &= ~(WLR_OUTPUT_STATE_BUFFER | | 	copy.committed &= ~(WLR_OUTPUT_STATE_BUFFER | | ||||||
| 		WLR_OUTPUT_STATE_DAMAGE | | 		WLR_OUTPUT_STATE_DAMAGE | | ||||||
| 		WLR_OUTPUT_STATE_GAMMA_LUT); | 		WLR_OUTPUT_STATE_GAMMA_LUT); | ||||||
|  | 	copy.buffer = NULL; | ||||||
|  | 	pixman_region32_init(©.damage); | ||||||
|  | 	copy.gamma_lut = NULL; | ||||||
|  | 	copy.gamma_lut_size = 0; | ||||||
| 
 | 
 | ||||||
| 	if (src->committed & WLR_OUTPUT_STATE_BUFFER) { | 	if (src->committed & WLR_OUTPUT_STATE_BUFFER) { | ||||||
| 		wlr_output_state_set_buffer(©, src->buffer); | 		wlr_output_state_set_buffer(©, src->buffer); | ||||||
|  | @ -146,21 +134,18 @@ bool wlr_output_state_copy(struct wlr_output_state *dst, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (src->committed & WLR_OUTPUT_STATE_GAMMA_LUT) { | 	if (src->committed & WLR_OUTPUT_STATE_GAMMA_LUT) { | ||||||
| 		size_t gamma_buffer_size = 3 * src->gamma_lut_size * sizeof(uint16_t); | 		const uint16_t *r = src->gamma_lut; | ||||||
| 		copy.gamma_lut = malloc(gamma_buffer_size); | 		const uint16_t *g = src->gamma_lut + src->gamma_lut_size; | ||||||
| 		if (!copy.gamma_lut) { | 		const uint16_t *b = src->gamma_lut + 2 * src->gamma_lut_size; | ||||||
| 			wlr_log_errno(WLR_ERROR, "Allocation failed"); | 		if (!wlr_output_state_set_gamma_lut(©, src->gamma_lut_size, r, g, b)) { | ||||||
| 			goto err; | 			goto err; | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		copy.committed |= WLR_OUTPUT_STATE_GAMMA_LUT; |  | ||||||
| 		memcpy(copy.gamma_lut, src->gamma_lut, gamma_buffer_size); |  | ||||||
| 		copy.gamma_lut_size = src->gamma_lut_size; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	wlr_output_state_finish(dst); | 	wlr_output_state_finish(dst); | ||||||
| 	*dst = copy; | 	*dst = copy; | ||||||
| 	return true; | 	return true; | ||||||
|  | 
 | ||||||
| err: | err: | ||||||
| 	wlr_output_state_finish(©); | 	wlr_output_state_finish(©); | ||||||
| 	return false; | 	return false; | ||||||
|  |  | ||||||
|  | @ -65,8 +65,9 @@ static bool test_swapchain(struct wlr_output *output, | ||||||
| 
 | 
 | ||||||
| bool wlr_output_configure_primary_swapchain(struct wlr_output *output, | bool wlr_output_configure_primary_swapchain(struct wlr_output *output, | ||||||
| 		const struct wlr_output_state *state, struct wlr_swapchain **swapchain_ptr) { | 		const struct wlr_output_state *state, struct wlr_swapchain **swapchain_ptr) { | ||||||
| 	const struct wlr_output_state empty_state = {0}; | 	struct wlr_output_state empty_state; | ||||||
| 	if (state == NULL) { | 	if (state == NULL) { | ||||||
|  | 		wlr_output_state_init(&empty_state); | ||||||
| 		state = &empty_state; | 		state = &empty_state; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1534,7 +1534,8 @@ static bool scene_buffer_can_consider_direct_scanout(struct wlr_scene_buffer *bu | ||||||
| 
 | 
 | ||||||
| static bool scene_buffer_try_direct_scanout(struct wlr_scene_buffer *buffer, | static bool scene_buffer_try_direct_scanout(struct wlr_scene_buffer *buffer, | ||||||
| 		struct wlr_scene_output *scene_output, struct wlr_output_state *state) { | 		struct wlr_scene_output *scene_output, struct wlr_output_state *state) { | ||||||
| 	struct wlr_output_state pending = {0}; | 	struct wlr_output_state pending; | ||||||
|  | 	wlr_output_state_init(&pending); | ||||||
| 	if (!wlr_output_state_copy(&pending, state)) { | 	if (!wlr_output_state_copy(&pending, state)) { | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  | @ -1564,19 +1565,23 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) { | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	struct wlr_output_state state = {0}; | 	bool ok = false; | ||||||
|  | 	struct wlr_output_state state; | ||||||
|  | 	wlr_output_state_init(&state); | ||||||
| 	if (!wlr_scene_output_build_state(scene_output, &state)) { | 	if (!wlr_scene_output_build_state(scene_output, &state)) { | ||||||
| 		return false; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	bool success = wlr_output_commit_state(scene_output->output, &state); | 	ok = wlr_output_commit_state(scene_output->output, &state); | ||||||
|  | 	if (!ok) { | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	wlr_damage_ring_rotate(&scene_output->damage_ring); | ||||||
|  | 
 | ||||||
|  | out: | ||||||
| 	wlr_output_state_finish(&state); | 	wlr_output_state_finish(&state); | ||||||
| 
 | 	return ok; | ||||||
| 	if (success) { |  | ||||||
| 		wlr_damage_ring_rotate(&scene_output->damage_ring); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return success; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output, | bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Simon Ser
						Simon Ser