static void ply_renderer_head_free (ply_renderer_head_t *head) { ply_trace ("freeing %ldx%ld renderer head", head->area.width, head->area.height); ply_pixel_buffer_free (head->pixel_buffer); drmModeFreeConnector (head->connector); free (head); }
static void ply_throbber_remove_frames (ply_throbber_t *throbber) { int i; ply_pixel_buffer_t **frames; frames = (ply_pixel_buffer_t **) ply_array_steal_pointer_elements (throbber->frames); for (i = 0; frames[i] != NULL; i++) ply_pixel_buffer_free (frames[i]); free (frames); }
void ply_image_free (ply_image_t *image) { if (image == NULL) return; assert (image->filename != NULL); ply_pixel_buffer_free (image->buffer); free (image->filename); free (image); }
void ply_progress_animation_draw (ply_progress_animation_t *progress_animation) { int number_of_frames; int frame_number; ply_image_t * const * frames; uint32_t *previous_frame_data, *frame_data; if (progress_animation->is_hidden) return; number_of_frames = ply_array_get_size (progress_animation->frames); if (number_of_frames == 0) return; frame_number = progress_animation->percent_done * (number_of_frames - 1); if (progress_animation->previous_frame_number != frame_number && progress_animation->transition != PLY_PROGRESS_ANIMATION_TRANSITION_NONE && progress_animation->transition_duration > 0.0) { progress_animation->is_transitioning = true; progress_animation->transition_start_time = ply_get_timestamp (); } frames = (ply_image_t * const *) ply_array_get_elements (progress_animation->frames); progress_animation->frame_area.x = progress_animation->area.x; progress_animation->frame_area.y = progress_animation->area.y; frame_data = ply_image_get_data (frames[frame_number]); if (progress_animation->is_transitioning) { double now; double fade_percentage; double fade_out_opacity; int width, height; uint32_t* faded_data; now = ply_get_timestamp (); fade_percentage = (now - progress_animation->transition_start_time) / progress_animation->transition_duration; if (fade_percentage >= 1.0) progress_animation->is_transitioning = false; fade_percentage = CLAMP (fade_percentage, 0.0, 1.0); if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_MERGE_FADE) { width = MAX(ply_image_get_width (frames[frame_number]), ply_image_get_width (frames[frame_number - 1])); height = MAX(ply_image_get_height (frames[frame_number]), ply_image_get_width (frames[frame_number - 1])); progress_animation->frame_area.width = width; progress_animation->frame_area.height = height; ply_pixel_buffer_free (progress_animation->last_rendered_frame); progress_animation->last_rendered_frame = ply_pixel_buffer_new (width, height); faded_data = ply_pixel_buffer_get_argb32_data (progress_animation->last_rendered_frame); image_fade_merge (frames[frame_number - 1], frames[frame_number], fade_percentage, width, height, faded_data); ply_pixel_display_draw_area (progress_animation->display, progress_animation->frame_area.x, progress_animation->frame_area.y, progress_animation->frame_area.width, progress_animation->frame_area.height); } else { ply_rectangle_t fill_area; previous_frame_data = ply_image_get_data (frames[frame_number - 1]); if (progress_animation->transition == PLY_PROGRESS_ANIMATION_TRANSITION_FADE_OVER) { ply_pixel_buffer_free (progress_animation->last_rendered_frame); progress_animation->frame_area.width = ply_image_get_width (frames[frame_number - 1]); progress_animation->frame_area.height = ply_image_get_height (frames[frame_number - 1]); progress_animation->last_rendered_frame = ply_pixel_buffer_new (progress_animation->frame_area.width, progress_animation->frame_area.height); fill_area.x = 0; fill_area.y = 0; fill_area.width = progress_animation->frame_area.width; fill_area.height = progress_animation->frame_area.height; ply_pixel_buffer_fill_with_argb32_data (progress_animation->last_rendered_frame, &fill_area, 0, 0, previous_frame_data); } else { fade_out_opacity = 1.0 - fade_percentage; progress_animation->frame_area.width = ply_image_get_width (frames[frame_number - 1]); progress_animation->frame_area.height = ply_image_get_height (frames[frame_number - 1]); fill_area.x = 0; fill_area.y = 0; fill_area.width = progress_animation->frame_area.width; fill_area.height = progress_animation->frame_area.height; ply_pixel_buffer_fill_with_argb32_data_at_opacity (progress_animation->last_rendered_frame, &fill_area, 0, 0, previous_frame_data, fade_out_opacity); } progress_animation->frame_area.width = ply_image_get_width (frames[frame_number]); progress_animation->frame_area.height = ply_image_get_height (frames[frame_number]); fill_area.x = 0; fill_area.y = 0; fill_area.width = progress_animation->frame_area.width; fill_area.height = progress_animation->frame_area.height; ply_pixel_buffer_fill_with_argb32_data_at_opacity (progress_animation->last_rendered_frame, &fill_area, 0, 0, frame_data, fade_percentage); width = MAX(ply_image_get_width (frames[frame_number]), ply_image_get_width (frames[frame_number - 1])); height = MAX(ply_image_get_height (frames[frame_number]), ply_image_get_width (frames[frame_number - 1])); progress_animation->frame_area.width = width; progress_animation->frame_area.height = height; } } else { ply_rectangle_t fill_area; ply_pixel_buffer_free (progress_animation->last_rendered_frame); progress_animation->frame_area.width = ply_image_get_width (frames[frame_number]); progress_animation->frame_area.height = ply_image_get_height (frames[frame_number]); progress_animation->last_rendered_frame = ply_pixel_buffer_new (progress_animation->frame_area.width, progress_animation->frame_area.height); fill_area.x = 0; fill_area.y = 0; fill_area.width = progress_animation->frame_area.width; fill_area.height = progress_animation->frame_area.height; ply_pixel_buffer_fill_with_argb32_data (progress_animation->last_rendered_frame, &fill_area, 0, 0, frame_data); } progress_animation->previous_frame_number = frame_number; ply_pixel_display_draw_area (progress_animation->display, progress_animation->frame_area.x, progress_animation->frame_area.y, progress_animation->frame_area.width, progress_animation->frame_area.height); }
static bool ply_renderer_head_set_scan_out_buffer_to_console (ply_renderer_backend_t *backend, ply_renderer_head_t *head, bool should_set_to_black) { unsigned long width; unsigned long height; unsigned long row_stride; uint32_t *shadow_buffer; ply_pixel_buffer_t *pixel_buffer; char *map_address; ply_rectangle_t area; if (!backend->driver_interface->fetch_buffer (backend->driver, head->console_buffer_id, &width, &height, &row_stride)) return false; if (!backend->driver_interface->map_buffer (backend->driver, head->console_buffer_id)) { backend->driver_interface->destroy_buffer (backend->driver, head->console_buffer_id); return false; } if (head->area.width != width || head->area.height != height) { /* Force black if the fb console resolution doesn't match our resolution */ area.x = 0; area.y = 0; area.width = width; area.height = height; should_set_to_black = true; ply_trace ("Console fb is %ldx%ld and screen contents are %ldx%ld. " "They aren't the same dimensions; forcing black", width, height, head->area.width, head->area.height); } else area = head->area; if (should_set_to_black) { pixel_buffer = ply_pixel_buffer_new (width, height); shadow_buffer = ply_pixel_buffer_get_argb32_data (pixel_buffer); } else { pixel_buffer = NULL; shadow_buffer = ply_pixel_buffer_get_argb32_data (head->pixel_buffer); } ply_trace ("Drawing %s to console fb", should_set_to_black? "black" : "screen contents"); map_address = backend->driver_interface->begin_flush (backend->driver, head->console_buffer_id); flush_area ((char *) shadow_buffer, area.width * 4, map_address, row_stride, &area); backend->driver_interface->end_flush (backend->driver, head->console_buffer_id); backend->driver_interface->unmap_buffer (backend->driver, head->console_buffer_id); ply_trace ("Setting scan out hardware to console fb"); ply_renderer_head_set_scan_out_buffer (backend, head, head->console_buffer_id); backend->driver_interface->destroy_buffer (backend->driver, head->console_buffer_id); if (pixel_buffer != NULL) ply_pixel_buffer_free (pixel_buffer); return true; }