Lines Matching +full:pre +full:- +full:blending

1 // SPDX-License-Identifier: GPL-2.0+
20 new_color = (src * 0xffff + dst * (0xffff - alpha)); in pre_mul_blend_channel()
26 * pre_mul_alpha_blend - alpha blending equation
36 * pre-multiplied with the alpha channel values. See more
43 struct pixel_argb_u16 *out = &output_buffer->pixels[x_start]; in pre_mul_alpha_blend()
44 const struct pixel_argb_u16 *in = &stage_buffer->pixels[x_start]; in pre_mul_alpha_blend()
58 for (size_t i = 0; i < output_buffer->n_pixels; i++) in fill_background()
59 output_buffer->pixels[i] = *background_color; in fill_background()
62 // lerp(a, b, t) = a + (b - a) * t
68 s64 delta = drm_fixp_mul(b_fp - a_fp, t); in lerp_u16()
77 return drm_fixp_mul(color_channel_fp, lut->channel_value2index_ratio); in get_lut_index()
104 floor_lut_value = (__u16 *)&lut->base[drm_fixp2int(lut_index)]; in apply_lut_to_channel_value()
105 if (drm_fixp2int(lut_index) == (lut->lut_length - 1)) in apply_lut_to_channel_value()
109 ceil_lut_value = (__u16 *)&lut->base[drm_fixp2int_ceil(lut_index)]; in apply_lut_to_channel_value()
120 if (!crtc_state->gamma_lut.base) in apply_lut()
123 if (!crtc_state->gamma_lut.lut_length) in apply_lut()
126 for (size_t x = 0; x < output_buffer->n_pixels; x++) { in apply_lut()
127 struct pixel_argb_u16 *pixel = &output_buffer->pixels[x]; in apply_lut()
129 pixel->r = apply_lut_to_channel_value(&crtc_state->gamma_lut, pixel->r, LUT_RED); in apply_lut()
130 pixel->g = apply_lut_to_channel_value(&crtc_state->gamma_lut, pixel->g, LUT_GREEN); in apply_lut()
131 pixel->b = apply_lut_to_channel_value(&crtc_state->gamma_lut, pixel->b, LUT_BLUE); in apply_lut()
136 * direction_for_rotation() - Get the correct reading direction for a given rotation
151 * Points A and B are depicted as zero-size rectangles on the CRTC. in direction_for_rotation()
153 * is discovered by inverse-transforming A and B. in direction_for_rotation()
154 * The reading direction is computed by rotating the vector AB (top-left to top-right) in a in direction_for_rotation()
163 x = tmp_b.x1 - tmp_a.x1; in direction_for_rotation()
164 y = tmp_b.y1 - tmp_a.y1; in direction_for_rotation()
168 else if (x == -1 && y == 0) in direction_for_rotation()
172 else if (y == -1 && x == 0) in direction_for_rotation()
180 * clamp_line_coordinates() - Compute and clamp the coordinate to read and write during the blend
185 * @src_line: source line of the reading. Only the top-left coordinate is used. This rectangle
203 *src_x_start = src_line->x1; in clamp_line_coordinates()
204 *src_y_start = src_line->y1; in clamp_line_coordinates()
205 *dst_x_start = current_plane->frame_info->dst.x1; in clamp_line_coordinates()
230 *dst_x_start -= *src_x_start; in clamp_line_coordinates()
233 if (*src_x_start + *pixel_count > current_plane->frame_info->fb->width) in clamp_line_coordinates()
234 *pixel_count = max(0, (int)current_plane->frame_info->fb->width - in clamp_line_coordinates()
241 *dst_x_start -= *src_y_start; in clamp_line_coordinates()
244 if (*src_y_start + *pixel_count > current_plane->frame_info->fb->height) in clamp_line_coordinates()
245 *pixel_count = max(0, (int)current_plane->frame_info->fb->height - in clamp_line_coordinates()
252 * blend_line() - Blend a line from a plane to the output buffer
268 if (y < current_plane->frame_info->dst.y1 || in blend_line()
269 y >= current_plane->frame_info->dst.y2) in blend_line()
277 dst_line = DRM_RECT_INIT(current_plane->frame_info->dst.x1, y, in blend_line()
278 drm_rect_width(&current_plane->frame_info->dst), in blend_line()
281 drm_rect_fp_to_int(&tmp_src, &current_plane->frame_info->src); in blend_line()
299 * - Cancel the offset of the dst buffer. in blend_line()
300 * - Invert the rotation. This assumes that in blend_line()
303 * - Apply the offset of the source rectangle to the coordinate. in blend_line()
305 drm_rect_translate(&src_line, -current_plane->frame_info->dst.x1, in blend_line()
306 -current_plane->frame_info->dst.y1); in blend_line()
309 current_plane->frame_info->rotation); in blend_line()
315 direction_for_rotation(current_plane->frame_info->rotation); in blend_line()
329 * src_line is the top-left corner, so when reading READ_RIGHT_TO_LEFT or in blend_line()
330 * READ_BOTTOM_TO_TOP, it must be changed to the top-right/bottom-left in blend_line()
335 src_x_start += pixel_count - 1; in blend_line()
338 src_y_start += pixel_count - 1; in blend_line()
342 * Perform the conversion and the blending in blend_line()
348 current_plane->pixel_read_line(current_plane, src_x_start, src_y_start, direction, in blend_line()
349 pixel_count, &stage_buffer->pixels[dst_x_start]); in blend_line()
356 * blend - blend the pixels from all planes and compute crc
373 struct vkms_plane_state **plane = crtc_state->active_planes; in blend()
374 u32 n_active_planes = crtc_state->num_active_planes; in blend()
378 int crtc_y_limit = crtc_state->base.mode.vdisplay; in blend()
379 int crtc_x_limit = crtc_state->base.mode.hdisplay; in blend()
382 * The planes are composed line-by-line to avoid heavy memory usage. It is a necessary in blend()
383 * complexity to avoid poor blending performance. in blend()
391 /* The active planes are composed associatively in z-order. */ in blend()
398 *crc32 = crc32_le(*crc32, (void *)output_buffer->pixels, row_size); in blend()
408 struct vkms_plane_state **planes = crtc_state->active_planes; in check_format_funcs()
409 u32 n_active_planes = crtc_state->num_active_planes; in check_format_funcs()
412 if (!planes[i]->pixel_read_line) in check_format_funcs()
413 return -1; in check_format_funcs()
415 if (active_wb && !active_wb->pixel_write) in check_format_funcs()
416 return -1; in check_format_funcs()
423 struct vkms_plane_state **plane_state = crtc_state->active_planes; in check_iosys_map()
424 u32 n_active_planes = crtc_state->num_active_planes; in check_iosys_map()
427 if (iosys_map_is_null(&plane_state[i]->frame_info->map[0])) in check_iosys_map()
428 return -1; in check_iosys_map()
450 return -EINVAL; in compose_active_planes()
453 return -EINVAL; in compose_active_planes()
455 line_width = crtc_state->base.mode.hdisplay; in compose_active_planes()
462 return -ENOMEM; in compose_active_planes()
468 ret = -ENOMEM; in compose_active_planes()
483 * vkms_composer_worker - ordered work_struct to compute CRC
496 struct drm_crtc *crtc = crtc_state->base.crtc; in vkms_composer_worker()
497 struct vkms_writeback_job *active_wb = crtc_state->active_writeback; in vkms_composer_worker()
504 spin_lock_irq(&out->composer_lock); in vkms_composer_worker()
505 frame_start = crtc_state->frame_start; in vkms_composer_worker()
506 frame_end = crtc_state->frame_end; in vkms_composer_worker()
507 crc_pending = crtc_state->crc_pending; in vkms_composer_worker()
508 wb_pending = crtc_state->wb_pending; in vkms_composer_worker()
509 crtc_state->frame_start = 0; in vkms_composer_worker()
510 crtc_state->frame_end = 0; in vkms_composer_worker()
511 crtc_state->crc_pending = false; in vkms_composer_worker()
513 if (crtc->state->gamma_lut) { in vkms_composer_worker()
517 crtc_state->gamma_lut.base = (struct drm_color_lut *)crtc->state->gamma_lut->data; in vkms_composer_worker()
518 crtc_state->gamma_lut.lut_length = in vkms_composer_worker()
519 crtc->state->gamma_lut->length / sizeof(struct drm_color_lut); in vkms_composer_worker()
520 max_lut_index_fp = drm_int2fixp(crtc_state->gamma_lut.lut_length - 1); in vkms_composer_worker()
521 crtc_state->gamma_lut.channel_value2index_ratio = drm_fixp_div(max_lut_index_fp, in vkms_composer_worker()
525 crtc_state->gamma_lut.base = NULL; in vkms_composer_worker()
528 spin_unlock_irq(&out->composer_lock); in vkms_composer_worker()
546 drm_writeback_signal_completion(&out->wb_connector, 0); in vkms_composer_worker()
547 spin_lock_irq(&out->composer_lock); in vkms_composer_worker()
548 crtc_state->wb_pending = false; in vkms_composer_worker()
549 spin_unlock_irq(&out->composer_lock); in vkms_composer_worker()
578 ret = -EINVAL; in vkms_crc_parse_source()
591 return -EINVAL; in vkms_verify_crc_source()
604 drm_crtc_vblank_get(&out->crtc); in vkms_set_composer()
606 spin_lock_irq(&out->lock); in vkms_set_composer()
607 old_enabled = out->composer_enabled; in vkms_set_composer()
608 out->composer_enabled = enabled; in vkms_set_composer()
609 spin_unlock_irq(&out->lock); in vkms_set_composer()
612 drm_crtc_vblank_put(&out->crtc); in vkms_set_composer()