diff options
Diffstat (limited to 'drivers/gpu/drm/drm_blend.c')
| -rw-r--r-- | drivers/gpu/drm/drm_blend.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c index a16a74d7e15e..0c78ca386cbe 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c | |||
| @@ -101,12 +101,80 @@ | |||
| 101 | * Without this property the rectangle is only scaled, but not rotated or | 101 | * Without this property the rectangle is only scaled, but not rotated or |
| 102 | * reflected. | 102 | * reflected. |
| 103 | * | 103 | * |
| 104 | * Possbile values: | ||
| 105 | * | ||
| 106 | * "rotate-<degrees>": | ||
| 107 | * Signals that a drm plane is rotated <degrees> degrees in counter | ||
| 108 | * clockwise direction. | ||
| 109 | * | ||
| 110 | * "reflect-<axis>": | ||
| 111 | * Signals that the contents of a drm plane is reflected along the | ||
| 112 | * <axis> axis, in the same way as mirroring. | ||
| 113 | * | ||
| 114 | * reflect-x:: | ||
| 115 | * | ||
| 116 | * |o | | o| | ||
| 117 | * | | -> | | | ||
| 118 | * | v| |v | | ||
| 119 | * | ||
| 120 | * reflect-y:: | ||
| 121 | * | ||
| 122 | * |o | | ^| | ||
| 123 | * | | -> | | | ||
| 124 | * | v| |o | | ||
| 125 | * | ||
| 104 | * zpos: | 126 | * zpos: |
| 105 | * Z position is set up with drm_plane_create_zpos_immutable_property() and | 127 | * Z position is set up with drm_plane_create_zpos_immutable_property() and |
| 106 | * drm_plane_create_zpos_property(). It controls the visibility of overlapping | 128 | * drm_plane_create_zpos_property(). It controls the visibility of overlapping |
| 107 | * planes. Without this property the primary plane is always below the cursor | 129 | * planes. Without this property the primary plane is always below the cursor |
| 108 | * plane, and ordering between all other planes is undefined. | 130 | * plane, and ordering between all other planes is undefined. |
| 109 | * | 131 | * |
| 132 | * pixel blend mode: | ||
| 133 | * Pixel blend mode is set up with drm_plane_create_blend_mode_property(). | ||
| 134 | * It adds a blend mode for alpha blending equation selection, describing | ||
| 135 | * how the pixels from the current plane are composited with the | ||
| 136 | * background. | ||
| 137 | * | ||
| 138 | * Three alpha blending equations are defined: | ||
| 139 | * | ||
| 140 | * "None": | ||
| 141 | * Blend formula that ignores the pixel alpha:: | ||
| 142 | * | ||
| 143 | * out.rgb = plane_alpha * fg.rgb + | ||
| 144 | * (1 - plane_alpha) * bg.rgb | ||
| 145 | * | ||
| 146 | * "Pre-multiplied": | ||
| 147 | * Blend formula that assumes the pixel color values | ||
| 148 | * have been already pre-multiplied with the alpha | ||
| 149 | * channel values:: | ||
| 150 | * | ||
| 151 | * out.rgb = plane_alpha * fg.rgb + | ||
| 152 | * (1 - (plane_alpha * fg.alpha)) * bg.rgb | ||
| 153 | * | ||
| 154 | * "Coverage": | ||
| 155 | * Blend formula that assumes the pixel color values have not | ||
| 156 | * been pre-multiplied and will do so when blending them to the | ||
| 157 | * background color values:: | ||
| 158 | * | ||
| 159 | * out.rgb = plane_alpha * fg.alpha * fg.rgb + | ||
| 160 | * (1 - (plane_alpha * fg.alpha)) * bg.rgb | ||
| 161 | * | ||
| 162 | * Using the following symbols: | ||
| 163 | * | ||
| 164 | * "fg.rgb": | ||
| 165 | * Each of the RGB component values from the plane's pixel | ||
| 166 | * "fg.alpha": | ||
| 167 | * Alpha component value from the plane's pixel. If the plane's | ||
| 168 | * pixel format has no alpha component, then this is assumed to be | ||
| 169 | * 1.0. In these cases, this property has no effect, as all three | ||
| 170 | * equations become equivalent. | ||
| 171 | * "bg.rgb": | ||
| 172 | * Each of the RGB component values from the background | ||
| 173 | * "plane_alpha": | ||
| 174 | * Plane alpha value set by the plane "alpha" property. If the | ||
| 175 | * plane does not expose the "alpha" property, then this is | ||
| 176 | * assumed to be 1.0 | ||
| 177 | * | ||
| 110 | * Note that all the property extensions described here apply either to the | 178 | * Note that all the property extensions described here apply either to the |
| 111 | * plane or the CRTC (e.g. for the background color, which currently is not | 179 | * plane or the CRTC (e.g. for the background color, which currently is not |
| 112 | * exposed and assumed to be black). | 180 | * exposed and assumed to be black). |
| @@ -448,3 +516,80 @@ int drm_atomic_normalize_zpos(struct drm_device *dev, | |||
| 448 | return 0; | 516 | return 0; |
| 449 | } | 517 | } |
| 450 | EXPORT_SYMBOL(drm_atomic_normalize_zpos); | 518 | EXPORT_SYMBOL(drm_atomic_normalize_zpos); |
| 519 | |||
| 520 | /** | ||
| 521 | * drm_plane_create_blend_mode_property - create a new blend mode property | ||
| 522 | * @plane: drm plane | ||
| 523 | * @supported_modes: bitmask of supported modes, must include | ||
| 524 | * BIT(DRM_MODE_BLEND_PREMULTI). Current DRM assumption is | ||
| 525 | * that alpha is premultiplied, and old userspace can break if | ||
| 526 | * the property defaults to anything else. | ||
| 527 | * | ||
| 528 | * This creates a new property describing the blend mode. | ||
| 529 | * | ||
| 530 | * The property exposed to userspace is an enumeration property (see | ||
| 531 | * drm_property_create_enum()) called "pixel blend mode" and has the | ||
| 532 | * following enumeration values: | ||
| 533 | * | ||
| 534 | * "None": | ||
| 535 | * Blend formula that ignores the pixel alpha. | ||
| 536 | * | ||
| 537 | * "Pre-multiplied": | ||
| 538 | * Blend formula that assumes the pixel color values have been already | ||
| 539 | * pre-multiplied with the alpha channel values. | ||
| 540 | * | ||
| 541 | * "Coverage": | ||
| 542 | * Blend formula that assumes the pixel color values have not been | ||
| 543 | * pre-multiplied and will do so when blending them to the background color | ||
| 544 | * values. | ||
| 545 | * | ||
| 546 | * RETURNS: | ||
| 547 | * Zero for success or -errno | ||
| 548 | */ | ||
| 549 | int drm_plane_create_blend_mode_property(struct drm_plane *plane, | ||
| 550 | unsigned int supported_modes) | ||
| 551 | { | ||
| 552 | struct drm_device *dev = plane->dev; | ||
| 553 | struct drm_property *prop; | ||
| 554 | static const struct drm_prop_enum_list props[] = { | ||
| 555 | { DRM_MODE_BLEND_PIXEL_NONE, "None" }, | ||
| 556 | { DRM_MODE_BLEND_PREMULTI, "Pre-multiplied" }, | ||
| 557 | { DRM_MODE_BLEND_COVERAGE, "Coverage" }, | ||
| 558 | }; | ||
| 559 | unsigned int valid_mode_mask = BIT(DRM_MODE_BLEND_PIXEL_NONE) | | ||
| 560 | BIT(DRM_MODE_BLEND_PREMULTI) | | ||
| 561 | BIT(DRM_MODE_BLEND_COVERAGE); | ||
| 562 | int i; | ||
| 563 | |||
| 564 | if (WARN_ON((supported_modes & ~valid_mode_mask) || | ||
| 565 | ((supported_modes & BIT(DRM_MODE_BLEND_PREMULTI)) == 0))) | ||
| 566 | return -EINVAL; | ||
| 567 | |||
| 568 | prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, | ||
| 569 | "pixel blend mode", | ||
| 570 | hweight32(supported_modes)); | ||
| 571 | if (!prop) | ||
| 572 | return -ENOMEM; | ||
| 573 | |||
| 574 | for (i = 0; i < ARRAY_SIZE(props); i++) { | ||
| 575 | int ret; | ||
| 576 | |||
| 577 | if (!(BIT(props[i].type) & supported_modes)) | ||
| 578 | continue; | ||
| 579 | |||
| 580 | ret = drm_property_add_enum(prop, props[i].type, | ||
| 581 | props[i].name); | ||
| 582 | |||
| 583 | if (ret) { | ||
| 584 | drm_property_destroy(dev, prop); | ||
| 585 | |||
| 586 | return ret; | ||
| 587 | } | ||
| 588 | } | ||
| 589 | |||
| 590 | drm_object_attach_property(&plane->base, prop, DRM_MODE_BLEND_PREMULTI); | ||
| 591 | plane->blend_mode_property = prop; | ||
| 592 | |||
| 593 | return 0; | ||
| 594 | } | ||
| 595 | EXPORT_SYMBOL(drm_plane_create_blend_mode_property); | ||
