From patchwork Wed Jan 27 14:44:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 60633 Delivered-To: patch@linaro.org Received: by 10.112.130.2 with SMTP id oa2csp2623878lbb; Wed, 27 Jan 2016 06:45:23 -0800 (PST) X-Received: by 10.98.13.7 with SMTP id v7mr42621433pfi.150.1453905905529; Wed, 27 Jan 2016 06:45:05 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q63si5237604pfi.141.2016.01.27.06.45.05; Wed, 27 Jan 2016 06:45:05 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-samsung-soc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-samsung-soc-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-samsung-soc-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933012AbcA0OpE (ORCPT + 4 others); Wed, 27 Jan 2016 09:45:04 -0500 Received: from mailout4.w1.samsung.com ([210.118.77.14]:30032 "EHLO mailout4.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932725AbcA0OpB (ORCPT ); Wed, 27 Jan 2016 09:45:01 -0500 MIME-version: 1.0 Content-type: text/plain; charset=UTF-8 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout4.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0O1M00ADF8YWB810@mailout4.w1.samsung.com> for linux-samsung-soc@vger.kernel.org; Wed, 27 Jan 2016 14:44:57 +0000 (GMT) X-AuditID: cbfec7f5-f79b16d000005389-34-56a8d7e8897a Received: from eusync1.samsung.com ( [203.254.199.211]) by eucpsbgm2.samsung.com (EUCPMTA) with SMTP id 77.4B.21385.8E7D8A65; Wed, 27 Jan 2016 14:44:56 +0000 (GMT) Content-transfer-encoding: 8BIT Received: from amdc1339.digital.local ([106.116.147.30]) by eusync1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0O1M00IVT8YO6E70@eusync1.samsung.com>; Wed, 27 Jan 2016 14:44:56 +0000 (GMT) From: Marek Szyprowski To: dri-devel@lists.freedesktop.org, linux-samsung-soc@vger.kernel.org Cc: Marek Szyprowski , Inki Dae , Daniel Vetter , =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , Joonyoung Shim , Seung-Woo Kim , Andrzej Hajda , Krzysztof Kozlowski , Bartlomiej Zolnierkiewicz , Tobias Jakobi , Gustavo Padovan , Benjamin Gaignard , vincent.abriou@st.com, fabien.dessenne@st.com Subject: [PATCH v5 4/5] drm: add generic blending related properties Date: Wed, 27 Jan 2016 15:44:42 +0100 Message-id: <1453905883-6807-5-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.2 In-reply-to: <1453905883-6807-1-git-send-email-m.szyprowski@samsung.com> References: <1453905883-6807-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprBIsWRmVeSWpSXmKPExsVy+t/xy7ovrq8IM3jyyMTi1rpzrBYbZ6xn tWg6dIrN4v+2icwWV76+Z7M4tm47o8XOB7vYLSbdn8Bi8eLeRRaL1y8MLWac38dksfbIXXaL GZNfslm0rf7AavH930ImizNXD7A4CHjs/baAxePOtT1sHvNOBnrc7z7O5PHvGLvHzkl7mTz6 tqxi9Hj6Yy+zx+dNcgGcUVw2Kak5mWWpRfp2CVwZU778ZC3YWFsxf+l/lgbG5RldjBwcEgIm ElsmS3cxcgKZYhIX7q1n62Lk4hASWMoosfPQWVaQBK+AoMSPyfdYQOqZBeQljlzKBgkzC6hL TJq3iBmivolJon3qdjaQBJuAoUTX2y4wW0TATaLp8ExWkCJmgfssElc/H2AHSQgLuEhcvvuX EcRmEVCVmLl1IdQyd4m9U/tYIC6Sk/j/cgUTiM0p4CFxc+Z6sHohoJp7F6ewTmAUmIXkvlkI 981Cct8CRuZVjKKppckFxUnpuUZ6xYm5xaV56XrJ+bmbGCHx9XUH49JjVocYBTgYlXh4b+xf HibEmlhWXJl7iFGCg1lJhJf10oowId6UxMqq1KL8+KLSnNTiQ4zSHCxK4rwzd70PERJITyxJ zU5NLUgtgskycXBKNTAWHH0i7OTem70kLpZbSNvBZdNMv8wVJRMmn21hnljUc1xD88YyheeM XN63L6a8X3Gm/PTrZ9l5SxenGUwunG/qW3bANidOsmL5miqWg29sTMtDRBq9vLJW7/q846rt fWHZxhSWD6ZtEU/t5HXX1c+snavYGdq5sXihz+5zZRcv3dZ66M7eLKPEUpyRaKjFXFScCACe NhayqwIAAA== Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org This patch adds code and documentation for the following blending related properties: 'alpha', 'blending' and 'alpha_premult'. 'alpha' property defines plane's transparency used for some blending modes. 'alpha_premult' property defines if RGB pixel data in the framebuffer contains values pre-multiplied by its alpha value or full range RGB values (0-255), which needs to be multiplied by pixel alpha value for blending operation. 'blending' property selects blending mode - by selecting one of the predefined values, user can select a pair of factors, which will be used in the generic blending equation. For more information, see the kerneldoc for the added code. Signed-off-by: Marek Szyprowski --- Documentation/DocBook/gpu.tmpl | 47 +++++++++++++++++- drivers/gpu/drm/drm_atomic.c | 12 +++++ drivers/gpu/drm/drm_blend.c | 110 +++++++++++++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 15 ++++++ include/uapi/drm/drm_mode.h | 101 +++++++++++++++++++++++++++++++++++++ 5 files changed, 283 insertions(+), 2 deletions(-) -- 1.9.2 -- To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index ae7d913adf60..e5197368e68f 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -1110,6 +1110,22 @@ int max_width, max_height; + + + + Plane blending + + + Plane Blending Overview +!Pinclude/uapi/drm/drm_mode.h Generic plane blending operation + + + Blending Function Reference +!Iinclude/uapi/drm/drm_mode.h +!Edrivers/gpu/drm/drm_blend.c + + + @@ -1816,7 +1832,7 @@ void intel_crt_init(struct drm_device *dev) Description/Restrictions - DRM + DRM Generic “rotation” BITMASK @@ -2068,7 +2084,7 @@ void intel_crt_init(struct drm_device *dev) property to suggest an Y offset for a connector - Optional + Optional “scaling mode” ENUM { "None", "Full", "Center", "Full aspect" } @@ -2102,6 +2118,33 @@ void intel_crt_init(struct drm_device *dev) planes' order. Exact value range is driver dependent. + "alpha" + RANGE + Min=0, Max= driver dependent + Plane + Plane's alpha value (transparency) for blending operation. Used in some blending modes. + + + "alpha_premult" + BOOL + Min=0, Max=1 + Plane + Indicates the range of the RGB data of the framebuffer attached to the given plane. + When enabled, RGB values fits the range from 0 to pixel's alpha value. When disabled, RGB + values are from 0 to 255 range and during blending operations they will be multiplied by + the pixel's alpha value first before computing result of blending equations. Value of this + property is used in some blending modes and only when user attaches framebuffer with pixel + format, which contains non-binary alpha channel. + + + "blending" + ENUM + { "disabled", "pixel-alpha", "const-alpha" "pixel-const-alpha" } + Plane + Selects algorithm used in plane blending operation. For more information, see + DRM_BLEND_* symbolic constant documentation. + + i915 Generic "Broadcast RGB" diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index a19201efb7d1..a85da144fd95 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -632,6 +632,12 @@ int drm_atomic_plane_set_property(struct drm_plane *plane, state->rotation = val; } else if (property == config->zpos_property) { state->zpos = val; + } else if (property == config->alpha_property) { + state->alpha = val; + } else if (property == config->alpha_premult_property) { + state->alpha_premult = val; + } else if (property == config->blending_property) { + state->blending = val; } else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val); @@ -690,6 +696,12 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->rotation; } else if (property == config->zpos_property) { *val = state->zpos; + } else if (property == config->alpha_property) { + *val = state->alpha; + } else if (property == config->alpha_premult_property) { + *val = state->alpha_premult; + } else if (property == config->blending_property) { + *val = state->blending; } else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else { diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c index cdcb647c8ed9..eb7996a848df 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c @@ -99,6 +99,116 @@ int drm_mode_create_zpos_immutable_property(struct drm_device *dev, } EXPORT_SYMBOL(drm_mode_create_zpos_immutable_property); +/** + * drm_mode_create_blending_property - create generic blending property + * @dev: DRM device + * @supported_blendings: array of supported blending modes + * @supported_blendings_count: size of @supported_blendings array + * + * This function initializes generic blending property to selected subset + * of supported blending modes. Drivers can then attach this property to + * planes to let userspace to configure different blending modes. For more + * information on blending modes, see DRM_BLEND_* defines. + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_mode_create_blending_property(struct drm_device *dev, + unsigned int *supported_blendings, + unsigned int supported_blendings_count) +{ + struct drm_property *prop; + static const struct drm_prop_enum_list all_values[] = { + { DRM_BLEND_DISABLED, "disabled" }, + { DRM_BLEND_PIXEL_ALPHA, "pixel-alpha" }, + { DRM_BLEND_CONST_ALPHA, "const-alpha" }, + { DRM_BLEND_PIXEL_CONST_ALPHA, "pixel-const-alpha" }, + }; + struct drm_prop_enum_list *values; + int i, j; + + values = kmalloc(supported_blendings_count * sizeof(*values), + GFP_KERNEL); + if (!values) + return -ENOMEM; + + for (i = 0; i < supported_blendings_count; i++) { + for (j = 0; j < ARRAY_SIZE(all_values); j++) { + if (all_values[j].type == supported_blendings[i]) { + values[i].type = supported_blendings[i]; + values[i].name = all_values[j].name; + break; + } + } + } + + prop = drm_property_create_enum(dev, 0, "blending", values, + supported_blendings_count); + kfree(values); + + if (!prop) + return -ENOMEM; + + dev->mode_config.blending_property = prop; + return 0; +} +EXPORT_SYMBOL(drm_mode_create_blending_property); + +/** + * drm_mode_create_alpha_property - create plane alpha property + * @dev: DRM device + * @max: maximal possible value of alpha property + * + * This function initializes generic plane's alpha property. It's value is used + * for blending operations, depending on selected blending mode. For more + * information, see DRM_BLEND_* modes and its documentation. Maximum alpha value + * is determined by the driver. + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_mode_create_alpha_property(struct drm_device *dev, unsigned int max) +{ + struct drm_property *prop; + + prop = drm_property_create_range(dev, 0, "alpha", 0, max); + if (!prop) + return -ENOMEM; + + dev->mode_config.alpha_property = prop; + return 0; +} +EXPORT_SYMBOL(drm_mode_create_alpha_property); + +/** + * drm_mode_create_alpha_premult_property - create muttable zpos property + * @dev: DRM device + * + * This function initializes generic plane's alpha pre-multiplication property. + * This property indicates the range of the RGB data of the framebuffer attached + * to the given plane. When enabled, RGB values fits the range from 0 to pixel's + * alpha value. When disabled, RGB values are from 0 to 255 range and during + * blending operations they will be multiplied by the pixel's alpha value first + * before computing result of blending equations. Value of this property is used + * only when user attaches framebuffer with pixel format, which contains + * non-binary alpha channel (for example: DRM_FORMAT_ARGB8888). + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_mode_create_alpha_premult_property(struct drm_device *dev) +{ + struct drm_property *prop; + + prop = drm_property_create_bool(dev, 0, "alpha_premult"); + if (!prop) + return -ENOMEM; + + dev->mode_config.alpha_premult_property = prop; + return 0; +} +EXPORT_SYMBOL(drm_mode_create_alpha_premult_property); + static int drm_atomic_state_zpos_cmp(const void *a, const void *b) { const struct drm_plane_state *sa = *(struct drm_plane_state **)a; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 702f4f28f580..47ae79483a19 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1276,6 +1276,11 @@ struct drm_plane_state { unsigned int zpos; unsigned int normalized_zpos; + /* Plane blending */ + unsigned int blending; + unsigned int alpha; + bool alpha_premult; + struct drm_atomic_state *state; }; @@ -2098,6 +2103,9 @@ struct drm_mode_config { struct drm_property *rotation_property; struct drm_property *zpos_property; struct drm_property *zpos_immutable_property; + struct drm_property *blending_property; + struct drm_property *alpha_property; + struct drm_property *alpha_premult_property; struct drm_property *prop_src_x; struct drm_property *prop_src_y; struct drm_property *prop_src_w; @@ -2505,6 +2513,13 @@ extern int drm_mode_create_zpos_immutable_property(struct drm_device *dev, unsigned int min, unsigned int max); +extern int drm_mode_create_blending_property(struct drm_device *dev, + unsigned int *supported_blendings, + unsigned int supported_blendings_count); +extern int drm_mode_create_alpha_property(struct drm_device *dev, + unsigned int max); +extern int drm_mode_create_alpha_premult_property(struct drm_device *dev); + /* Helpers */ static inline struct drm_plane *drm_plane_find(struct drm_device *dev, diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 50adb46204c2..6da7076a3856 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -596,4 +596,105 @@ struct drm_mode_destroy_blob { __u32 blob_id; }; +/** + * DOC: Generic plane blending operation + * + * Planes attached to one CRTC are blended by the hardware to produce the final + * result on the display. The order of planes during blending operation is + * determined by 'zpos' property. When order of plane for blending operation is + * determined, then framebuffers of all planes are placed on the display area + * according to the configured position and target size. + * + * Then one of the selected blending procedure is applied to each pixel on the + * display area to compute the final result of the blending. The blending + * procedure is similar to the well known glBlendFunc() API. + * + * The generic equation for blending is: + * outputRGB = sF * sRGB + dF * dRGB + * + * @sRGB: are RGB values of blended plane + * + * @dRGB: are RGB values of plane's background (result of previous blending or + * RGB pixel values of deeper planes). + * + * @sF and @dF: are one of DRM_FACTOR_* symbolic constants. + * + * Blending mode then defined as DRM_BLEND(sF, dF), which selects respective + * factors for the above equation. For more information, see drm_blend_mode + * enum. + */ + +/** + * enum drm_blend_factor - factors for defining plane blending formula + * @DRM_FACTOR_ZERO: constant zero + * @DRM_FACTOR_ONE: constant one + * @DRM_FACTOR_SRC_ALPHA: pixel alpha value + * @DRM_FACTOR_ONE_MINUS_SRC_ALPHA: 1 - DRM_FACTOR_SRC_ALPHA + * @DRM_FACTOR_CONST_ALPHA: constant alpha (plane's property) + * @DRM_FACTOR_ONE_MINUS_CONST_ALPHA: 1 - DRM_FACTOR_CONST_ALPHA + * @DRM_FACTOR_SRC_CONST_ALPHA: pixel alpha value multiplied by plane's + * constant alpha + * @DRM_FACTOR_ONE_MINUS_SRC_CONST_ALPHA: 1 - DRM_FACTOR_SRC_CONST_ALPHA + * + * Values of this enum are used to define plane blending formula. Two factors + * have to be selected - one for source plane and one for destination + * (background). + */ +enum drm_blend_factor { + DRM_FACTOR_ZERO, + DRM_FACTOR_ONE, + DRM_FACTOR_SRC_ALPHA, + DRM_FACTOR_ONE_MINUS_SRC_ALPHA, + DRM_FACTOR_CONST_ALPHA, + DRM_FACTOR_ONE_MINUS_CONST_ALPHA, + DRM_FACTOR_SRC_CONST_ALPHA, + DRM_FACTOR_ONE_MINUS_SRC_CONST_ALPHA, +}; + +#define DRM_BLEND(s, d) ((d << 16) | (s)) + +/** + * enum drm_blend_mode - predefined blending modes + * @DRM_BLEND_S_ONE_D_ZERO: no transparency; per-pixel and plane's alpha is + * ignored regardless of the selected pixel format. + * @DRM_BLEND_S_SRC_ALPHA_D_ONE_MINUS_SRC_ALPHA: blending with per-pixel alpha; + * plane's alpha is ignored, aplies only when pixel format defines alpha + * channel, otherwise same as @DRM_BLEND_DISABLED and + * @DRM_BLEND_S_ONE_D_ZERO. + * @DRM_BLEND_S_CONST_ALPHA_D_ONE_MINUS_CONST_ALPHA: blending with constant + * alpha; per-pixel alpha is ignored regardless of the selected pixel + * format. + * @DRM_BLEND_S_SRC_CONST_ALPHA_D_ONE_MINUS_SRC_CONST_ALPHA: blending with both + * per-pixel and plane's alpha; aplies only when pixel format defines alpha + * channel, otherwise same as @DRM_BLEND_CONST_ALPHA and + * @DRM_BLEND_S_CONST_ALPHA_D_ONE_MINUS_CONST_ALPHA + * @DRM_BLEND_DISABLED: same as @DRM_BLEND_S_ONE_D_ZERO + * @DRM_BLEND_PIXEL_ALPHA: same as @DRM_BLEND_S_SRC_ALPHA_D_ONE_MINUS_SRC_ALPHA, + * @DRM_BLEND_CONST_ALPHA: same as + * @DRM_BLEND_S_CONST_ALPHA_D_ONE_MINUS_CONST_ALPHA, + * @DRM_BLEND_PIXEL_CONST_ALPHA: same as + * @DRM_BLEND_S_SRC_CONST_ALPHA_D_ONE_MINUS_SRC_CONST_ALPHA, + * + * Values of this enum can be set to 'blend' plane's property. The actual + * value of each blending mode consists of two drm_blend_factor values + * encoded on lower 16 bits for source plane and higher 16 bits for destiantion + * (background). + */ +enum drm_blend_mode { + DRM_BLEND_S_ONE_D_ZERO = DRM_BLEND(DRM_FACTOR_ONE, DRM_FACTOR_ZERO), + DRM_BLEND_S_SRC_ALPHA_D_ONE_MINUS_SRC_ALPHA = + DRM_BLEND(DRM_FACTOR_SRC_ALPHA, + DRM_FACTOR_ONE_MINUS_SRC_ALPHA), + DRM_BLEND_S_CONST_ALPHA_D_ONE_MINUS_CONST_ALPHA = + DRM_BLEND(DRM_FACTOR_CONST_ALPHA, + DRM_FACTOR_ONE_MINUS_CONST_ALPHA), + DRM_BLEND_S_SRC_CONST_ALPHA_D_ONE_MINUS_SRC_CONST_ALPHA = + DRM_BLEND(DRM_FACTOR_SRC_CONST_ALPHA, + DRM_FACTOR_ONE_MINUS_SRC_CONST_ALPHA), + DRM_BLEND_DISABLED = DRM_BLEND_S_ONE_D_ZERO, + DRM_BLEND_PIXEL_ALPHA = DRM_BLEND_S_SRC_ALPHA_D_ONE_MINUS_SRC_ALPHA, + DRM_BLEND_CONST_ALPHA = DRM_BLEND_S_CONST_ALPHA_D_ONE_MINUS_CONST_ALPHA, + DRM_BLEND_PIXEL_CONST_ALPHA = DRM_BLEND_S_SRC_CONST_ALPHA_D_ONE_MINUS_SRC_CONST_ALPHA, +}; + #endif