|
27 | 27 | #ifndef _DRM_MODE_H |
28 | 28 | #define _DRM_MODE_H |
29 | 29 |
|
| 30 | +#include <linux/bits.h> |
| 31 | +#include <linux/const.h> |
| 32 | + |
30 | 33 | #include "drm.h" |
31 | 34 |
|
32 | 35 | #if defined(__cplusplus) |
@@ -1546,6 +1549,83 @@ struct drm_mode_closefb { |
1546 | 1549 | __u32 pad; |
1547 | 1550 | }; |
1548 | 1551 |
|
| 1552 | +/* |
| 1553 | + * Put 16-bit ARGB values into a standard 64-bit representation that can be |
| 1554 | + * used for ioctl parameters, inter-driver communication, etc. |
| 1555 | + * |
| 1556 | + * If the component values being provided contain less than 16 bits of |
| 1557 | + * precision, use a conversion ratio to get a better color approximation. |
| 1558 | + * The ratio is computed as (2^16 - 1) / (2^bpc - 1), where bpc and 16 are |
| 1559 | + * the input and output precision, respectively. |
| 1560 | + * Also note bpc must be greater than 0. |
| 1561 | + */ |
| 1562 | +#define __DRM_ARGB64_PREP(c, shift) \ |
| 1563 | + (((__u64)(c) & __GENMASK(15, 0)) << (shift)) |
| 1564 | + |
| 1565 | +#define __DRM_ARGB64_PREP_BPC(c, shift, bpc) \ |
| 1566 | +({ \ |
| 1567 | + __u16 mask = __GENMASK((bpc) - 1, 0); \ |
| 1568 | + __u16 conv = __KERNEL_DIV_ROUND_CLOSEST((mask & (c)) * \ |
| 1569 | + __GENMASK(15, 0), mask);\ |
| 1570 | + __DRM_ARGB64_PREP(conv, shift); \ |
| 1571 | +}) |
| 1572 | + |
| 1573 | +#define DRM_ARGB64_PREP(alpha, red, green, blue) \ |
| 1574 | +( \ |
| 1575 | + __DRM_ARGB64_PREP(alpha, 48) | \ |
| 1576 | + __DRM_ARGB64_PREP(red, 32) | \ |
| 1577 | + __DRM_ARGB64_PREP(green, 16) | \ |
| 1578 | + __DRM_ARGB64_PREP(blue, 0) \ |
| 1579 | +) |
| 1580 | + |
| 1581 | +#define DRM_ARGB64_PREP_BPC(alpha, red, green, blue, bpc) \ |
| 1582 | +({ \ |
| 1583 | + __typeof__(bpc) __bpc = bpc; \ |
| 1584 | + __DRM_ARGB64_PREP_BPC(alpha, 48, __bpc) | \ |
| 1585 | + __DRM_ARGB64_PREP_BPC(red, 32, __bpc) | \ |
| 1586 | + __DRM_ARGB64_PREP_BPC(green, 16, __bpc) | \ |
| 1587 | + __DRM_ARGB64_PREP_BPC(blue, 0, __bpc); \ |
| 1588 | +}) |
| 1589 | + |
| 1590 | +/* |
| 1591 | + * Extract the specified color component from a standard 64-bit ARGB value. |
| 1592 | + * |
| 1593 | + * If the requested precision is less than 16 bits, make use of a conversion |
| 1594 | + * ratio calculated as (2^bpc - 1) / (2^16 - 1), where bpc and 16 are the |
| 1595 | + * output and input precision, respectively. |
| 1596 | + * |
| 1597 | + * If speed is more important than accuracy, use DRM_ARGB64_GET*_BPCS() |
| 1598 | + * instead of DRM_ARGB64_GET*_BPC() in order to replace the expensive |
| 1599 | + * division with a simple bit right-shift operation. |
| 1600 | + */ |
| 1601 | +#define __DRM_ARGB64_GET(c, shift) \ |
| 1602 | + ((__u16)(((__u64)(c) >> (shift)) & __GENMASK(15, 0))) |
| 1603 | + |
| 1604 | +#define __DRM_ARGB64_GET_BPC(c, shift, bpc) \ |
| 1605 | +({ \ |
| 1606 | + __u16 comp = __DRM_ARGB64_GET(c, shift); \ |
| 1607 | + __KERNEL_DIV_ROUND_CLOSEST(comp * __GENMASK((bpc) - 1, 0), \ |
| 1608 | + __GENMASK(15, 0)); \ |
| 1609 | +}) |
| 1610 | + |
| 1611 | +#define __DRM_ARGB64_GET_BPCS(c, shift, bpc) \ |
| 1612 | + (__DRM_ARGB64_GET(c, shift) >> (16 - (bpc))) |
| 1613 | + |
| 1614 | +#define DRM_ARGB64_GETA(c) __DRM_ARGB64_GET(c, 48) |
| 1615 | +#define DRM_ARGB64_GETR(c) __DRM_ARGB64_GET(c, 32) |
| 1616 | +#define DRM_ARGB64_GETG(c) __DRM_ARGB64_GET(c, 16) |
| 1617 | +#define DRM_ARGB64_GETB(c) __DRM_ARGB64_GET(c, 0) |
| 1618 | + |
| 1619 | +#define DRM_ARGB64_GETA_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 48, bpc) |
| 1620 | +#define DRM_ARGB64_GETR_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 32, bpc) |
| 1621 | +#define DRM_ARGB64_GETG_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 16, bpc) |
| 1622 | +#define DRM_ARGB64_GETB_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 0, bpc) |
| 1623 | + |
| 1624 | +#define DRM_ARGB64_GETA_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 48, bpc) |
| 1625 | +#define DRM_ARGB64_GETR_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 32, bpc) |
| 1626 | +#define DRM_ARGB64_GETG_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 16, bpc) |
| 1627 | +#define DRM_ARGB64_GETB_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 0, bpc) |
| 1628 | + |
1549 | 1629 | #if defined(__cplusplus) |
1550 | 1630 | } |
1551 | 1631 | #endif |
|
0 commit comments