WDRM_PLANE_CRTC_ID,
WDRM_PLANE_IN_FORMATS,
WDRM_PLANE_IN_FENCE_FD,
+ WDRM_PLANE_FB_DAMAGE_CLIPS,
WDRM_PLANE__COUNT
};
[WDRM_PLANE_CRTC_ID] = { .name = "CRTC_ID", },
[WDRM_PLANE_IN_FORMATS] = { .name = "IN_FORMATS" },
[WDRM_PLANE_IN_FENCE_FD] = { .name = "IN_FENCE_FD" },
+ [WDRM_PLANE_FB_DAMAGE_CLIPS] = { .name = "FB_DAMAGE_CLIPS" },
};
/**
/* We don't own the fd, so we shouldn't close it */
int in_fence_fd;
+ pixman_region32_t damage; /* damage to kernel */
+
struct wl_list link; /* drm_output_state::plane_list */
};
state->output_state = state_output;
state->plane = plane;
state->in_fence_fd = -1;
+ pixman_region32_init(&state->damage);
/* Here we only add the plane state to the desired link, and not
* set the member. Having an output pointer set means that the
wl_list_init(&state->link);
state->output_state = NULL;
state->in_fence_fd = -1;
+ pixman_region32_fini(&state->damage);
if (force || state != state->plane->state_cur) {
drm_fb_unref(state->fb);
if (src->fb)
dst->fb = drm_fb_ref(src->fb);
dst->output_state = state_output;
+ pixman_region32_init(&dst->damage);
dst->complete = false;
return dst;
return ret;
}
+static int
+plane_add_damage(drmModeAtomicReq *req, struct drm_backend *backend,
+ struct drm_plane_state *plane_state)
+{
+ struct drm_plane *plane = plane_state->plane;
+ struct drm_property_info *info =
+ &plane->props[WDRM_PLANE_FB_DAMAGE_CLIPS];
+ pixman_box32_t *rects;
+ uint32_t blob_id;
+ int n_rects;
+ int ret;
+
+ if (!pixman_region32_not_empty(&plane_state->damage))
+ return 0;
+
+ /*
+ * If a plane doesn't support fb damage blob property, kernel will
+ * perform full plane update.
+ */
+ if (info->prop_id == 0)
+ return 0;
+
+ rects = pixman_region32_rectangles(&plane_state->damage, &n_rects);
+
+ ret = drmModeCreatePropertyBlob(backend->drm.fd, rects,
+ sizeof(*rects) * n_rects, &blob_id);
+ if (ret != 0)
+ return ret;
+
+ ret = plane_add_prop(req, plane, WDRM_PLANE_FB_DAMAGE_CLIPS, blob_id);
+ if (ret != 0)
+ return ret;
+
+ return 0;
+}
+
static int
drm_output_apply_state_atomic(struct drm_output_state *state,
drmModeAtomicReq *req,
plane_state->dest_w);
ret |= plane_add_prop(req, plane, WDRM_PLANE_CRTC_H,
plane_state->dest_h);
+ ret |= plane_add_damage(req, b, plane_state);
if (plane_state->fb && plane_state->fb->format)
pinfo = plane_state->fb->format;