Lines Matching refs:plane

41  * A plane represents an image source that can be blended with or overlaid on
43 * &drm_framebuffer object. The plane itself specifies the cropping and scaling
45 * pipeline, represented by &drm_crtc. A plane can also have additional
51 * which are not covered by a plane will be black, and alpha blending of any
54 * To create a plane, a KMS drivers allocates and zeroes an instances of
58 * Each plane has a type, see enum drm_plane_type. A plane can be compatible
61 * Each CRTC must have a unique primary plane userspace can attach to enable
63 * primary plane to each CRTC at the same time. Primary planes can still be
68 * relies on the driver to set the primary and optionally the cursor plane used
70 * drivers must provide one primary plane per CRTC to avoid surprising legacy
75 * DOC: standard plane properties
80 * Immutable property describing the type of the plane.
83 * the plane type is just a hint and is mostly superseded by atomic
85 * easily with a plane configuration accepted by the driver.
90 * To light up a CRTC, attaching a primary plane is the most likely to
94 * Drivers may support more features for the primary plane, user-space
100 * plane (e.g. through an atomic commit) with these legacy IOCTLs.
103 * To enable this plane, using a framebuffer configured without scaling
111 * a linear layout. Otherwise, use the IN_FORMATS plane property.
113 * Drivers may support more features for the cursor plane, user-space
119 * plane (e.g. through an atomic commit) with these legacy IOCTLs.
121 * Some drivers may support cursors even if no cursor plane is exposed.
133 * pairs supported by this plane. The blob is a struct
134 * drm_format_modifier_blob. Without this property the plane doesn't
139 * plane will have the IN_FORMATS property, even when it only supports
142 * flag and per-plane properties.
169 static int create_in_format_blob(struct drm_device *dev, struct drm_plane *plane)
178 formats_size = sizeof(__u32) * plane->format_count;
185 sizeof(struct drm_format_modifier) * plane->modifier_count;
201 blob_data->count_formats = plane->format_count;
203 blob_data->count_modifiers = plane->modifier_count;
208 memcpy(formats_ptr(blob_data), plane->format_types, formats_size);
211 for (i = 0; i < plane->modifier_count; i++) {
212 for (j = 0; j < plane->format_count; j++) {
213 if (!plane->funcs->format_mod_supported ||
214 plane->funcs->format_mod_supported(plane,
215 plane->format_types[j],
216 plane->modifiers[i])) {
221 mod->modifier = plane->modifiers[i];
227 drm_object_attach_property(&plane->base, config->modifiers_property,
235 struct drm_plane *plane,
251 /* plane index is used with 32bit bitmasks */
266 ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
270 drm_modeset_lock_init(&plane->mutex);
272 plane->base.properties = &plane->properties;
273 plane->dev = dev;
274 plane->funcs = funcs;
275 plane->format_types = kmalloc_array(format_count, sizeof(uint32_t),
277 if (!plane->format_types) {
278 DRM_DEBUG_KMS("out of memory when allocating plane\n");
279 drm_mode_object_unregister(dev, &plane->base);
299 plane->modifier_count = format_modifier_count;
300 plane->modifiers = kmalloc_array(format_modifier_count,
304 if (format_modifier_count && !plane->modifiers) {
305 DRM_DEBUG_KMS("out of memory when allocating plane\n");
306 kfree(plane->format_types);
307 drm_mode_object_unregister(dev, &plane->base);
312 plane->name = kvasprintf(GFP_KERNEL, name, ap);
314 plane->name = kasprintf(GFP_KERNEL, "plane-%d",
317 if (!plane->name) {
318 kfree(plane->format_types);
319 kfree(plane->modifiers);
320 drm_mode_object_unregister(dev, &plane->base);
324 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
325 plane->format_count = format_count;
326 memcpy(plane->modifiers, format_modifiers,
328 plane->possible_crtcs = possible_crtcs;
329 plane->type = type;
331 list_add_tail(&plane->head, &config->plane_list);
332 plane->index = config->num_total_plane++;
334 drm_object_attach_property(&plane->base,
336 plane->type);
339 drm_object_attach_property(&plane->base, config->prop_fb_id, 0);
340 drm_object_attach_property(&plane->base, config->prop_in_fence_fd, -1);
341 drm_object_attach_property(&plane->base, config->prop_crtc_id, 0);
342 drm_object_attach_property(&plane->base, config->prop_crtc_x, 0);
343 drm_object_attach_property(&plane->base, config->prop_crtc_y, 0);
344 drm_object_attach_property(&plane->base, config->prop_crtc_w, 0);
345 drm_object_attach_property(&plane->base, config->prop_crtc_h, 0);
346 drm_object_attach_property(&plane->base, config->prop_src_x, 0);
347 drm_object_attach_property(&plane->base, config->prop_src_y, 0);
348 drm_object_attach_property(&plane->base, config->prop_src_w, 0);
349 drm_object_attach_property(&plane->base, config->prop_src_h, 0);
353 create_in_format_blob(dev, plane);
359 * drm_universal_plane_init - Initialize a new universal plane object
361 * @plane: plane object to init
363 * @funcs: callbacks for the new plane
368 * @type: type of plane (overlay, primary, cursor)
369 * @name: printf style format string for the plane name, or NULL for default name
371 * Initializes a plane object of type @type. The &drm_plane_funcs.destroy hook
372 * should call drm_plane_cleanup() and kfree() the plane structure. The plane
380 * @format_modifiers to NULL. The plane will advertise the linear modifier.
385 int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
399 ret = __drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
409 struct drm_plane *plane = ptr;
411 if (WARN_ON(!plane->dev))
414 drm_plane_cleanup(plane);
426 struct drm_plane *plane;
437 plane = container + offset;
440 ret = __drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
448 plane);
465 struct drm_plane *plane;
476 plane = container + offset;
479 ret = __drm_universal_plane_init(dev, plane, possible_crtcs, funcs,
498 struct drm_plane *plane;
501 drm_for_each_plane(plane, dev) {
502 if (plane->funcs->late_register)
503 ret = plane->funcs->late_register(plane);
507 if (plane->zpos_property)
520 struct drm_plane *plane;
522 drm_for_each_plane(plane, dev) {
523 if (plane->funcs->early_unregister)
524 plane->funcs->early_unregister(plane);
529 * drm_plane_cleanup - Clean up the core plane usage
530 * @plane: plane to cleanup
532 * This function cleans up @plane and removes it from the DRM mode setting
533 * core. Note that the function does *not* free the plane structure itself,
536 void drm_plane_cleanup(struct drm_plane *plane)
538 struct drm_device *dev = plane->dev;
540 drm_modeset_lock_fini(&plane->mutex);
542 kfree(plane->format_types);
543 kfree(plane->modifiers);
544 drm_mode_object_unregister(dev, &plane->base);
546 BUG_ON(list_empty(&plane->head));
553 list_del(&plane->head);
556 WARN_ON(plane->state && !plane->funcs->atomic_destroy_state);
557 if (plane->state && plane->funcs->atomic_destroy_state)
558 plane->funcs->atomic_destroy_state(plane, plane->state);
560 kfree(plane->name);
562 memset(plane, 0, sizeof(*plane));
567 * drm_plane_from_index - find the registered plane at an index
569 * @idx: index of registered plane to find for
571 * Given a plane index, return the registered plane from DRM device's
577 struct drm_plane *plane;
579 drm_for_each_plane(plane, dev)
580 if (idx == plane->index)
581 return plane;
588 * drm_plane_force_disable - Forcibly disable a plane
589 * @plane: plane to disable
591 * Forces the plane to be disabled.
593 * Used when the plane's current framebuffer is destroyed,
602 void drm_plane_force_disable(struct drm_plane *plane)
606 if (!plane->fb)
609 WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
611 plane->old_fb = plane->fb;
612 ret = plane->funcs->disable_plane(plane, NULL);
614 DRM_ERROR("failed to disable plane with busy fb\n");
615 plane->old_fb = NULL;
618 /* disconnect the plane from the fb and crtc: */
619 drm_framebuffer_put(plane->old_fb);
620 plane->old_fb = NULL;
621 plane->fb = NULL;
622 plane->crtc = NULL;
628 * @plane: drm plane object to set property value for
632 * This functions sets a given property on a given plane object. This function
639 int drm_mode_plane_set_obj_prop(struct drm_plane *plane,
644 struct drm_mode_object *obj = &plane->base;
646 if (plane->funcs->set_property)
647 ret = plane->funcs->set_property(plane, property, value);
659 struct drm_plane *plane;
672 drm_for_each_plane(plane, dev) {
677 if (plane->type != DRM_PLANE_TYPE_OVERLAY &&
684 * virtualized cursor plane, disable cursor planes
688 if (plane->type == DRM_PLANE_TYPE_CURSOR &&
694 if (drm_lease_held(file_priv, plane->base.id)) {
696 put_user(plane->base.id, plane_ptr + count))
710 struct drm_plane *plane;
716 plane = drm_plane_find(dev, file_priv, plane_resp->plane_id);
717 if (!plane)
720 drm_modeset_lock(&plane->mutex, NULL);
721 if (plane->state && plane->state->crtc && drm_lease_held(file_priv, plane->state->crtc->base.id))
722 plane_resp->crtc_id = plane->state->crtc->base.id;
723 else if (!plane->state && plane->crtc && drm_lease_held(file_priv, plane->crtc->base.id))
724 plane_resp->crtc_id = plane->crtc->base.id;
728 if (plane->state && plane->state->fb)
729 plane_resp->fb_id = plane->state->fb->base.id;
730 else if (!plane->state && plane->fb)
731 plane_resp->fb_id = plane->fb->base.id;
734 drm_modeset_unlock(&plane->mutex);
736 plane_resp->plane_id = plane->base.id;
738 plane->possible_crtcs);
746 if (plane->format_count &&
747 (plane_resp->count_format_types >= plane->format_count)) {
750 plane->format_types,
751 sizeof(uint32_t) * plane->format_count)) {
755 plane_resp->count_format_types = plane->format_count;
760 int drm_plane_check_pixel_format(struct drm_plane *plane,
765 for (i = 0; i < plane->format_count; i++) {
766 if (format == plane->format_types[i])
769 if (i == plane->format_count)
772 if (plane->funcs->format_mod_supported) {
773 if (!plane->funcs->format_mod_supported(plane, format, modifier))
776 if (!plane->modifier_count)
779 for (i = 0; i < plane->modifier_count; i++) {
780 if (modifier == plane->modifiers[i])
783 if (i == plane->modifier_count)
790 static int __setplane_check(struct drm_plane *plane,
800 /* Check whether this plane is usable on this CRTC */
801 if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
802 DRM_DEBUG_KMS("Invalid crtc for plane\n");
806 /* Check whether this plane supports the fb pixel format. */
807 ret = drm_plane_check_pixel_format(plane, fb->format->format,
833 * drm_any_plane_has_format - Check whether any plane supports this format and modifier combination
839 * Whether at least one plane supports the specified format and modifier combination.
844 struct drm_plane *plane;
846 drm_for_each_plane(plane, dev) {
847 if (drm_plane_check_pixel_format(plane, format, modifier) == 0)
858 * This function will take a reference on the new fb for the plane
863 static int __setplane_internal(struct drm_plane *plane,
875 WARN_ON(drm_drv_uses_atomic_modeset(plane->dev));
879 plane->old_fb = plane->fb;
880 ret = plane->funcs->disable_plane(plane, ctx);
882 plane->crtc = NULL;
883 plane->fb = NULL;
885 plane->old_fb = NULL;
890 ret = __setplane_check(plane, crtc, fb,
896 plane->old_fb = plane->fb;
897 ret = plane->funcs->update_plane(plane, crtc, fb,
901 plane->crtc = crtc;
902 plane->fb = fb;
903 drm_framebuffer_get(plane->fb);
905 plane->old_fb = NULL;
909 if (plane->old_fb)
910 drm_framebuffer_put(plane->old_fb);
911 plane->old_fb = NULL;
916 static int __setplane_atomic(struct drm_plane *plane,
927 WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev));
931 return plane->funcs->disable_plane(plane, ctx);
940 ret = __setplane_check(plane, crtc, fb,
946 return plane->funcs->update_plane(plane, crtc, fb,
951 static int setplane_internal(struct drm_plane *plane,
963 DRM_MODESET_LOCK_ALL_BEGIN(plane->dev, ctx,
966 if (drm_drv_uses_atomic_modeset(plane->dev))
967 ret = __setplane_atomic(plane, crtc, fb,
971 ret = __setplane_internal(plane, crtc, fb,
975 DRM_MODESET_LOCK_ALL_END(plane->dev, ctx, ret);
984 struct drm_plane *plane;
993 * First, find the plane, crtc, and fb objects. If not available,
996 plane = drm_plane_find(dev, file_priv, plane_req->plane_id);
997 if (!plane) {
998 DRM_DEBUG_KMS("Unknown plane ID %d\n",
1020 ret = setplane_internal(plane, crtc, fb,
1038 struct drm_plane *plane = crtc->cursor;
1052 BUG_ON(!plane);
1053 WARN_ON(plane->crtc != crtc && plane->crtc != NULL);
1058 * the reference if the plane update fails.
1074 if (plane->state)
1075 fb = plane->state->fb;
1077 fb = plane->fb;
1099 ret = __setplane_atomic(plane, crtc, fb,
1103 ret = __setplane_internal(plane, crtc, fb,
1145 * If this crtc has a universal cursor plane, call that plane's update
1229 struct drm_plane *plane;
1258 plane = crtc->primary;
1260 if (!drm_lease_held(file_priv, plane->base.id))
1307 ret = drm_modeset_lock(&plane->mutex, &ctx);
1311 if (plane->state)
1312 old_fb = plane->state->fb;
1314 old_fb = plane->fb;
1331 if (plane->state) {
1332 const struct drm_plane_state *state = plane->state;
1379 plane->old_fb = plane->fb;
1392 plane->old_fb = NULL;
1394 if (!plane->state) {
1395 plane->fb = fb;
1404 if (plane->old_fb)
1405 drm_framebuffer_put(plane->old_fb);
1406 plane->old_fb = NULL;
1426 * FB_DAMAGE_CLIPS is an optional plane property which provides a means to
1427 * specify a list of damage rectangles on a plane in framebuffer coordinates of
1428 * the framebuffer attached to the plane. In current context damage is the area
1429 * of plane framebuffer that has changed since last plane update (also called
1431 * framebuffer attached during last plane update or not.
1438 * ignore damage clips property and in that case driver will do a full plane
1440 * inside damage clips will be updated to plane. For efficiency driver can do
1445 * framebuffer (since last plane update) can result in incorrect rendering.
1448 * array of &drm_mode_rect. Unlike plane &drm_plane_state.src coordinates,
1449 * damage clips are not in 16.16 fixed point. Similar to plane src in
1454 * Drivers that are interested in damage interface for plane should enable
1462 * drm_plane_enable_fb_damage_clips - Enables plane fb damage clips property.
1463 * @plane: Plane on which to enable damage clips property.
1465 * This function lets driver to enable the damage clips property on a plane.
1467 void drm_plane_enable_fb_damage_clips(struct drm_plane *plane)
1469 struct drm_device *dev = plane->dev;
1472 drm_object_attach_property(&plane->base, config->prop_fb_damage_clips,
1482 * during plane update.
1484 * Return: Number of clips in plane fb_damage_clips blob property.
1510 * Return: Damage clips in plane fb_damage_clips blob property.
1515 struct drm_device *dev = state->plane->dev;
1519 if (!drm_mode_obj_find_prop_id(&state->plane->base,
1573 * @plane: drm plane
1578 * plane.
1583 int drm_plane_create_scaling_filter_property(struct drm_plane *plane,
1587 drm_create_scaling_filter_prop(plane->dev, supported_filters);
1592 drm_object_attach_property(&plane->base, prop,
1594 plane->scaling_filter_property = prop;