|
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) |
@@ -1364,6 +1367,83 @@ struct drm_mode_closefb { |
1364 | 1367 | __u32 pad; |
1365 | 1368 | }; |
1366 | 1369 |
|
| 1370 | +/* |
| 1371 | + * Put 16-bit ARGB values into a standard 64-bit representation that can be |
| 1372 | + * used for ioctl parameters, inter-driver communication, etc. |
| 1373 | + * |
| 1374 | + * If the component values being provided contain less than 16 bits of |
| 1375 | + * precision, use a conversion ratio to get a better color approximation. |
| 1376 | + * The ratio is computed as (2^16 - 1) / (2^bpc - 1), where bpc and 16 are |
| 1377 | + * the input and output precision, respectively. |
| 1378 | + * Also note bpc must be greater than 0. |
| 1379 | + */ |
| 1380 | +#define __DRM_ARGB64_PREP(c, shift) \ |
| 1381 | + (((__u64)(c) & __GENMASK(15, 0)) << (shift)) |
| 1382 | + |
| 1383 | +#define __DRM_ARGB64_PREP_BPC(c, shift, bpc) \ |
| 1384 | +({ \ |
| 1385 | + __u16 mask = __GENMASK((bpc) - 1, 0); \ |
| 1386 | + __u16 conv = __KERNEL_DIV_ROUND_CLOSEST((mask & (c)) * \ |
| 1387 | + __GENMASK(15, 0), mask);\ |
| 1388 | + __DRM_ARGB64_PREP(conv, shift); \ |
| 1389 | +}) |
| 1390 | + |
| 1391 | +#define DRM_ARGB64_PREP(alpha, red, green, blue) \ |
| 1392 | +( \ |
| 1393 | + __DRM_ARGB64_PREP(alpha, 48) | \ |
| 1394 | + __DRM_ARGB64_PREP(red, 32) | \ |
| 1395 | + __DRM_ARGB64_PREP(green, 16) | \ |
| 1396 | + __DRM_ARGB64_PREP(blue, 0) \ |
| 1397 | +) |
| 1398 | + |
| 1399 | +#define DRM_ARGB64_PREP_BPC(alpha, red, green, blue, bpc) \ |
| 1400 | +({ \ |
| 1401 | + __typeof__(bpc) __bpc = bpc; \ |
| 1402 | + __DRM_ARGB64_PREP_BPC(alpha, 48, __bpc) | \ |
| 1403 | + __DRM_ARGB64_PREP_BPC(red, 32, __bpc) | \ |
| 1404 | + __DRM_ARGB64_PREP_BPC(green, 16, __bpc) | \ |
| 1405 | + __DRM_ARGB64_PREP_BPC(blue, 0, __bpc); \ |
| 1406 | +}) |
| 1407 | + |
| 1408 | +/* |
| 1409 | + * Extract the specified color component from a standard 64-bit ARGB value. |
| 1410 | + * |
| 1411 | + * If the requested precision is less than 16 bits, make use of a conversion |
| 1412 | + * ratio calculated as (2^bpc - 1) / (2^16 - 1), where bpc and 16 are the |
| 1413 | + * output and input precision, respectively. |
| 1414 | + * |
| 1415 | + * If speed is more important than accuracy, use DRM_ARGB64_GET*_BPCS() |
| 1416 | + * instead of DRM_ARGB64_GET*_BPC() in order to replace the expensive |
| 1417 | + * division with a simple bit right-shift operation. |
| 1418 | + */ |
| 1419 | +#define __DRM_ARGB64_GET(c, shift) \ |
| 1420 | + ((__u16)(((__u64)(c) >> (shift)) & __GENMASK(15, 0))) |
| 1421 | + |
| 1422 | +#define __DRM_ARGB64_GET_BPC(c, shift, bpc) \ |
| 1423 | +({ \ |
| 1424 | + __u16 comp = __DRM_ARGB64_GET(c, shift); \ |
| 1425 | + __KERNEL_DIV_ROUND_CLOSEST(comp * __GENMASK((bpc) - 1, 0), \ |
| 1426 | + __GENMASK(15, 0)); \ |
| 1427 | +}) |
| 1428 | + |
| 1429 | +#define __DRM_ARGB64_GET_BPCS(c, shift, bpc) \ |
| 1430 | + (__DRM_ARGB64_GET(c, shift) >> (16 - (bpc))) |
| 1431 | + |
| 1432 | +#define DRM_ARGB64_GETA(c) __DRM_ARGB64_GET(c, 48) |
| 1433 | +#define DRM_ARGB64_GETR(c) __DRM_ARGB64_GET(c, 32) |
| 1434 | +#define DRM_ARGB64_GETG(c) __DRM_ARGB64_GET(c, 16) |
| 1435 | +#define DRM_ARGB64_GETB(c) __DRM_ARGB64_GET(c, 0) |
| 1436 | + |
| 1437 | +#define DRM_ARGB64_GETA_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 48, bpc) |
| 1438 | +#define DRM_ARGB64_GETR_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 32, bpc) |
| 1439 | +#define DRM_ARGB64_GETG_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 16, bpc) |
| 1440 | +#define DRM_ARGB64_GETB_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 0, bpc) |
| 1441 | + |
| 1442 | +#define DRM_ARGB64_GETA_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 48, bpc) |
| 1443 | +#define DRM_ARGB64_GETR_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 32, bpc) |
| 1444 | +#define DRM_ARGB64_GETG_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 16, bpc) |
| 1445 | +#define DRM_ARGB64_GETB_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 0, bpc) |
| 1446 | + |
1367 | 1447 | #if defined(__cplusplus) |
1368 | 1448 | } |
1369 | 1449 | #endif |
|
0 commit comments