int evdi_handle_damage(struct evdi_framebuffer *fb, int x, int y, int width, int height) { const struct drm_clip_rect dirty_rect = { x, y, x + width, y + height }; const struct drm_clip_rect rect = evdi_framebuffer_sanitize_rect(fb, &dirty_rect); struct drm_device *dev = fb->base.dev; struct evdi_device *evdi = dev->dev_private; EVDI_CHECKPT(); if (!fb->active) return 0; evdi_set_new_scanout_buffer(evdi, fb); evdi_flip_scanout_buffer(evdi); evdi_painter_mark_dirty(evdi, &rect); return 0; }
void evdi_painter_mark_dirty(struct evdi_device *evdi, const struct drm_clip_rect *dirty_rect) { struct drm_clip_rect rect; struct evdi_framebuffer *efb = NULL; struct evdi_painter *painter = evdi->painter; painter_lock(evdi->painter); efb = evdi->painter->scanout_fb; if (!efb) { EVDI_WARN("Skip clip rect. Scanout buffer not set.\n"); goto unlock; } rect = evdi_framebuffer_sanitize_rect(efb, dirty_rect); EVDI_VERBOSE("(dev=%d) %d,%d-%d,%d\n", evdi->dev_index, rect.x1, rect.y1, rect.x2, rect.y2); if (painter->num_dirts == MAX_DIRTS) merge_dirty_rects(&painter->dirty_rects[0], &painter->num_dirts); if (painter->num_dirts == MAX_DIRTS) collapse_dirty_rects(&painter->dirty_rects[0], &painter->num_dirts); memcpy(&painter->dirty_rects[painter->num_dirts], &rect, sizeof(rect)); painter->num_dirts++; if (painter->was_update_requested) { evdi_painter_send_update_ready(painter); painter->was_update_requested = false; } unlock: painter_unlock(evdi->painter); }