From patchwork Mon Jun 24 07:10:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?=C5=81ukasz_Spintzyk?= X-Patchwork-Id: 13709107 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 77682C2D0D1 for ; Mon, 24 Jun 2024 07:23:42 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A682210E388; Mon, 24 Jun 2024 07:23:40 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=synaptics.com header.i=@synaptics.com header.b="YWTR11jg"; dkim-atps=neutral Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12on2093.outbound.protection.outlook.com [40.107.237.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8BB8A10E370 for ; Mon, 24 Jun 2024 07:11:19 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=a3yrpWsSe67AFnd61MPQMN+PSoJG+8d2x1BCof1R2zTSJOGiXTzhWZ5gpzrPgfa7AePMNYleRdxDp/6gAvbCun1okGgzn1/YDM+h6P6Ph0iQbr2QOT8KIqEk4/Naj/NAMaMZm5IyWecFUtTBghAFjYZDh697tMznfJwS+NHaIb8jScrbl+YLVs7qcgtGGc8RSmS3SEkPqIxyqT0Wuni6p8L91ORR20nc/O9/hvdLnXVq6G36aVWzN8Xo8sVtZHA6iVU9ux/QneWkHESOjKu6PNWpUUAB+I/rLHHHNHxaLmFPXjc/dUKUAtYLpFy5XaaEjHrJH8OWm0CHNpBlq0s6Vw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=WqRhWxs1wW8N3JeAaUzbhnYoPdQEVTtyEJhNFGBjDk8=; b=fASkQstEdRo8eFSZoG/6olOVXrkyq0x60JTXkMARvnYaeeMOM0KxGjD36opfpd9JPs0jm+vf1twzJycpqIfRvx/3duz+TZtyvf+cZmKG1m7XP6jHyWWcu069BSVtbTrPY5wB0KQyaAtCoWr4T4dh8TSE+c3FfMZ+0Ct9aKA13mf7fO7wsDhEkzhzdtWY6KnXauV2Cn1QZDYFdTGCK6zsqgieYSLg8JtIlW5gXFXo2apYhRnW73COqdCAN5VKcP1Y+vuhCKEuUdSYNBEpzgQWqV1iSBSTUlKPii7Ul3YRTJCaWUwPSVt0pFJoXLB1N4YamSuhFfm1j6vi0y8tOein+g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=synaptics.com; dmarc=pass action=none header.from=synaptics.com; dkim=pass header.d=synaptics.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=synaptics.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=WqRhWxs1wW8N3JeAaUzbhnYoPdQEVTtyEJhNFGBjDk8=; b=YWTR11jgf9E4+5vZp9b6UOps0uMeIg+7ielqG0RefoKAM1/RnZv2ZslB0SFcXpfP9uqx1HjcKAwavbk0R8A2Q74lwB3sSosb8u+O7n38u4VGIvPRjUxXr4iMWGQjhVXmTvVjpnF/qkvNMazxyArqBujQ3p6h8Oe4IoscZcN7g2k= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=synaptics.com; Received: from BN9PR03MB6188.namprd03.prod.outlook.com (2603:10b6:408:101::18) by BY5PR03MB5063.namprd03.prod.outlook.com (2603:10b6:a03:1e4::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7698.29; Mon, 24 Jun 2024 07:11:17 +0000 Received: from BN9PR03MB6188.namprd03.prod.outlook.com ([fe80::7b19:7f50:4645:3990]) by BN9PR03MB6188.namprd03.prod.outlook.com ([fe80::7b19:7f50:4645:3990%4]) with mapi id 15.20.7698.025; Mon, 24 Jun 2024 07:11:17 +0000 From: lukasz.spintzyk@synaptics.com To: dri-devel@lists.freedesktop.org Cc: Dave Airlie , Sean Paul , Thomas Zimmermann , Douglas Anderson , Haixia Shi , Ross Zwisler , Guenter Roeck , =?utf-8?q?=C5=81ukasz_Spintzyk?= Subject: [PATCH 1/4] drm/udl: Port CrOS cursor blending on primary plane in usb transfer Date: Mon, 24 Jun 2024 09:10:38 +0200 Message-Id: <20240624071041.5087-2-lukasz.spintzyk@synaptics.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240624071041.5087-1-lukasz.spintzyk@synaptics.com> References: <20240624071041.5087-1-lukasz.spintzyk@synaptics.com> X-ClientProxiedBy: LO4P265CA0209.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:33a::16) To BN9PR03MB6188.namprd03.prod.outlook.com (2603:10b6:408:101::18) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BN9PR03MB6188:EE_|BY5PR03MB5063:EE_ X-MS-Office365-Filtering-Correlation-Id: d645fe1b-47e3-4d85-d605-08dc941cd732 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230037|376011|1800799021|52116011|366013|38350700011; X-Microsoft-Antispam-Message-Info: =?utf-8?q?SRYuDQhDGZTEyZcPNUt2WwvnFsydESO?= =?utf-8?q?3gBjtKe/he6+aNMLJw92fn51DujPOKGtUuul2SwcYXmvmru4zTlVUalwlRgIMJ/jn?= =?utf-8?q?4nyFZjuZKCYXRHbBuLHfa7bf3zt0SxCAB/S+iDR0EYbIn8LjU6fjs06ZaG5P1R7Yy?= =?utf-8?q?N0YRdwyaH9iUajdpSVrSu61CkYGu8SdQdh3qpaKtOO0q+f2+xPiGh8mw8Ue1BaqFJ?= =?utf-8?q?NFvmC3biA0yYMc9AxUn2jYLMIs3GRTTwpXuWlfpf3qBqBBgBxJrK+tFYm0/tQTI9l?= =?utf-8?q?H+UX6mZF5umhuJaWKiZu6/CZ4FRqFdcPJHKIPq57mYdIyiYzWoZqd1UO7kNXJqCOg?= =?utf-8?q?oFgbUF99VRRG4wi6xyD5T+msZ+NzZNT0WzssY9+ITioVGTlvEYrj3G+CDfLNX8YHi?= =?utf-8?q?Srz2bRLsrngrK9hhMchfiQBFVaJJyzOFJ1v3C7ZHpxRzU2BxXpomHtxt7CFjhoc5g?= =?utf-8?q?FSXxS2ErkocsnLDB5yfjKcQamqltq9qwZ7m0XXellsg48YXqlImW5ln5aIemLOTcJ?= =?utf-8?q?Rxw0iGzLKPfAHGzC18RCpDB2rSaGWXgjrn6TCWgMoOmA62FxZHR3H//bsyRj3cIRT?= =?utf-8?q?HJgmTzCalJUhv8gNMRbKyqWiQqAJ+cjUHWRZjS3fu5omzf7rzhCGG35rofkkuLAVr?= =?utf-8?q?qzZmy0s5k6qb9rcQdR93YZY71wWRWr0ws7xeCLJ1T01yEYmPn/YK9BbUA/WnVQTUG?= =?utf-8?q?6IRIndq3XijHQMIrY6LO4z3tf2ewH9zufnnO8dVP5t1M7NakC6iXRCpgnzvMgsrFa?= =?utf-8?q?PCdNKbcE1ee140ykcjhxC/yagfA3KZZmBrfqP3P2QnTdUt/wRW+h4bbhaO9ypI+0W?= =?utf-8?q?y8FYFtCBBP4mUJ5YQeHwkoafl2WcSrgUp569FaA7DhFlSZbeLgPffBiw9BI6iuPvJ?= =?utf-8?q?yZOP74JBjeD0JJ/6O4P+wqOSvepU8zDRe+IOQZK+9NDdSzB7i7cgD3HWPaZ0lRgMJ?= =?utf-8?q?xQjqay8RUmgcmU31+EM3BKRISYmSrZVs6fLubw/dCBg+UE4W8cCNYj41D6uls98O2?= =?utf-8?q?vbXLAm9vFL5iRSDAL0T/nbi8vv2F6Q/ekC6EXR8APcahEJbwGmk6LHUaCa/PrF9Am?= =?utf-8?q?Gb11rdW5VqwquWLhudQEemsa9SrMVjMj4oRx1U4Mh56kK05JFLnKMxyqWKysLWRvA?= =?utf-8?q?q7lDKh09Th5KRKYieHLp4SJn1YqIyo6aM/AuasUfgYUDYIGL3Fxx38+EViJT0wXfp?= =?utf-8?q?UVVK3vEpy5ZuYo+qqA+p3DeoP7bukgC8FwaJvMtwpd61ul14nmSZI3CaMt8nvfCt3?= =?utf-8?q?XXH6vQqM1CJOx?= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BN9PR03MB6188.namprd03.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230037)(376011)(1800799021)(52116011)(366013)(38350700011); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?DPm89Z+U9+jjmZ3ax8hyQDHMTWR6?= =?utf-8?q?hiKeleKkxUZTGC8l/W98Yd4QcXRLd6OuIPWmeH76iO40FE9XUCYMd4Io2fFgRhUZi?= =?utf-8?q?8a7EaoFPHF8nLdjBYti+rPuCK2JDUrs1NFBEMoSZz/6yFFe9qQMJnJbkNkugQhGg7?= =?utf-8?q?ruYh6tNC6KnnNw2+yE2Me2B+8a7b3m0SVUGYxdgGFR/jNK7ugsNUtYS+tCBnrW867?= =?utf-8?q?isuhADjhvrGbGZN0O4ioXSsnDavOZTVljF78lKvLAp1veGyncZdb/FCIiOlkoZ4TD?= =?utf-8?q?st7aX67ldiTg/HCcJ4DI0IrQaiVyPTZSrcWa8uqk9IjhTi1evZnS6qBZOKwUj5FpH?= =?utf-8?q?b5N2otP+++n6mPveOhjjJwKrD4lt2kHD9BGXEggRWthD42Wz1W0NXCulW0/Z/qcGk?= =?utf-8?q?zwGoXIUHTGSSZZDqzl8gEqIZl1z6TTp6ZCPsE3+8IlUDqV9KOWRCeLkLlt70jtC0m?= =?utf-8?q?QWkKXCdlbOmE2vSeOHkzxAoUVd+EsoT29V8hAGIEDlL7O7KFJ2vv29d8yl2HlRxCk?= =?utf-8?q?tngH+fOYmmkSZR5YBvKLMlfOX9o1eJoac8d6bjkEGLcUNOWLzBvQ3QShOKgJdsgRG?= =?utf-8?q?QbeKZuvMc12VFPw6LJmz7IT+lCm13syWVOw/B47T/kIfxFs1oL/RYuusMre3aWj5F?= =?utf-8?q?fpC9OfUFxf6bdmaUm/eGzkuUvMWWSZGb3vM+pnHMpP+R7lcERIHeA9N3gwgnqhpUP?= =?utf-8?q?gLIJXAiQv0y5Wefe/NFAiqa2zshikPCTAzzIftCQ8nQ9e2Sn/Dt2QP3XfZwMuu58N?= =?utf-8?q?vDY5GfnsHWT+0wTtcCHhxhDcQ/kTaT1PEw7Yyo0nJg51KrvRzuJLr0/5oCFbXjJhw?= =?utf-8?q?3UcDvXSIzHfcXUN3/gtckawI9JtBq0IiSAcwjoUM0PjynBYRXjAA2bCg66kOSmF2v?= =?utf-8?q?ttDVNSav5ifO6fChdhScPRAy10ps4o75pnMEWwMPgx49gFLBKBnZGdpMuzKZ+Qr8l?= =?utf-8?q?ranZfX31W1oiNiNKFcKxlzCGCvQZvYtj4NhZIdRGHYrlwYhyGLGpxZGxKFlGPvZLr?= =?utf-8?q?Dd7cSXII62UkLIizRwTAhCwBXi5QIZq3dgXWCU3/6nsA3S8v1sdYAFNwvfnzDUMi9?= =?utf-8?q?DUxGjRcP+/eeUcdk35DxpT/2p9BM0Z7M1hvLkgH2CeNKYLnjtsTbNuFfiAvlgT7N5?= =?utf-8?q?IV0mACdlr/mHlFWqEL9arh+YF0E+miiWOgtH9Nc2z1pb6PyXZg/dRVw+TAq4JJ88J?= =?utf-8?q?v8q2i8LKGXPymPwBMxTKZ6COSjfFIIdQx8aTRwZnGiXt3A2v/AHYRu1r3GShOQOdm?= =?utf-8?q?3n3IvMbGc2VKT/dVYi0gad5XQINtedKH2hO8OQ96KCi8JF+Db46MSJFwflel2T5zm?= =?utf-8?q?SAAPH+GfqdX3PwTPrr4na57WvNQdTrhe9LiOo6GkA04mLv8FnIU8B8lVdeSnPH95n?= =?utf-8?q?YjtN0SS7PQSrFEnbHLmOAg5K4P7Hl9k2tudD9m5xcHRogHy33fhP0gJDtGDwjyKPV?= =?utf-8?q?gQHPr4ciLgx9mdIs1V5eNZuX+9kyZq/YW0AdXMbCVBqJ3nSiQzFxpfTb1/apoOdpv?= =?utf-8?q?NYWQlXiufSO8?= X-OriginatorOrg: synaptics.com X-MS-Exchange-CrossTenant-Network-Message-Id: d645fe1b-47e3-4d85-d605-08dc941cd732 X-MS-Exchange-CrossTenant-AuthSource: BN9PR03MB6188.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Jun 2024 07:11:17.2698 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 335d1fbc-2124-4173-9863-17e7051a2a0e X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: RKGN90jz+wS4LMReHuetAu5Ms484alQDa9EAO+2Lm3oEx95bV4qoJ5gfRMgO8Sl0cFxktQZIP1kJBJINdiY6+A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY5PR03MB5063 X-Mailman-Approved-At: Mon, 24 Jun 2024 07:22:58 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Douglas Anderson Port applicable parts of CrOS udl cursor implementation from 5.4 CrOS kernel fork. - removed legacy non-atomic udl_cursor_move, udl_cursor_set ioctl's implementation - modified udl_cursor_download to copy cursor content to the buffer from iosys_map - removed unnecessary cursor copy in udl_handle_damage - simplify code by making struct udl_cursor public Cursor was tested on ChromeOS and Ubuntu 22.04 with gnome-wayland. (cherry picked from commit efb4c23afa3e1de185a1a4f8ff5b7ec412aec0fe) ChromiumOS fork at https://chromium.googlesource.com/chromiumos/third_party/kernel) Signed-off-by: Haixia Shi Signed-off-by: Ross Zwisler Signed-off-by: Douglas Anderson Signed-off-by: Guenter Roeck Signed-off-by: Ɓukasz Spintzyk --- drivers/gpu/drm/udl/Makefile | 2 +- drivers/gpu/drm/udl/udl_cursor.c | 78 ++++++++++++++++++++++++++++++ drivers/gpu/drm/udl/udl_cursor.h | 47 ++++++++++++++++++ drivers/gpu/drm/udl/udl_drv.h | 6 ++- drivers/gpu/drm/udl/udl_modeset.c | 9 +++- drivers/gpu/drm/udl/udl_transfer.c | 36 +++++++++++++- 6 files changed, 173 insertions(+), 5 deletions(-) create mode 100644 drivers/gpu/drm/udl/udl_cursor.c create mode 100644 drivers/gpu/drm/udl/udl_cursor.h diff --git a/drivers/gpu/drm/udl/Makefile b/drivers/gpu/drm/udl/Makefile index 3f6db179455d..0abd04b0e829 100644 --- a/drivers/gpu/drm/udl/Makefile +++ b/drivers/gpu/drm/udl/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -udl-y := udl_drv.o udl_modeset.o udl_main.o udl_transfer.o +udl-y := udl_drv.o udl_modeset.o udl_main.o udl_transfer.o udl_cursor.o obj-$(CONFIG_DRM_UDL) := udl.o diff --git a/drivers/gpu/drm/udl/udl_cursor.c b/drivers/gpu/drm/udl/udl_cursor.c new file mode 100644 index 000000000000..594bb3b6b056 --- /dev/null +++ b/drivers/gpu/drm/udl/udl_cursor.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * udl_cursor.c + * + * Copyright (c) 2015 The Chromium OS Authors + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include + +#include "udl_cursor.h" +#include "udl_drv.h" + +void udl_cursor_get_hline(struct udl_cursor *cursor, int x, int y, + struct udl_cursor_hline *hline) +{ + if (!cursor || !cursor->enabled || + x >= cursor->x + UDL_CURSOR_W || + y < cursor->y || y >= cursor->y + UDL_CURSOR_H) { + hline->buffer = NULL; + return; + } + + hline->buffer = &cursor->buffer[UDL_CURSOR_W * (y - cursor->y)]; + hline->width = UDL_CURSOR_W; + hline->offset = x - cursor->x; +} + +/* + * Return pre-computed cursor blend value defined as: + * R: 5 bits (bit 0:4) + * G: 6 bits (bit 5:10) + * B: 5 bits (bit 11:15) + * A: 7 bits (bit 16:22) + */ +static uint32_t cursor_blend_val32(uint32_t pix) +{ + /* range of alpha_scaled is 0..64 */ + uint32_t alpha_scaled = ((pix >> 24) * 65) >> 8; + + return ((pix >> 3) & 0x1f) | + ((pix >> 5) & 0x7e0) | + ((pix >> 8) & 0xf800) | + (alpha_scaled << 16); +} + +int udl_cursor_download(struct udl_cursor *cursor, + const struct iosys_map *map) +{ + uint32_t *src_ptr, *dst_ptr; + size_t i; + + src_ptr = map->vaddr; + dst_ptr = cursor->buffer; + for (i = 0; i < UDL_CURSOR_BUF; ++i) + dst_ptr[i] = cursor_blend_val32(le32_to_cpu(src_ptr[i])); + return 0; +} + + +int udl_cursor_move(struct udl_cursor *cursor, int x, int y) +{ + cursor->x = x; + cursor->y = y; + return 0; +} diff --git a/drivers/gpu/drm/udl/udl_cursor.h b/drivers/gpu/drm/udl/udl_cursor.h new file mode 100644 index 000000000000..6a848accc106 --- /dev/null +++ b/drivers/gpu/drm/udl/udl_cursor.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * + * udl_cursor.h + * + * Copyright (c) 2015 The Chromium OS Authors + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _UDL_CURSOR_H_ +#define _UDL_CURSOR_H_ + +#include +#include + +#define UDL_CURSOR_W 64 +#define UDL_CURSOR_H 64 +#define UDL_CURSOR_BUF (UDL_CURSOR_W * UDL_CURSOR_H) +struct udl_cursor { + uint32_t buffer[UDL_CURSOR_BUF]; + bool enabled; + int x; + int y; +}; +struct udl_cursor_hline { + uint32_t *buffer; + int width; + int offset; +}; + +extern void udl_cursor_get_hline(struct udl_cursor *cursor, int x, int y, + struct udl_cursor_hline *hline); +extern int udl_cursor_move(struct udl_cursor *cursor, int x, int y); +extern int udl_cursor_download(struct udl_cursor *cursor, const struct iosys_map *map); + +#endif diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 282ebd6c02fd..ccd813bec1a9 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -21,6 +21,7 @@ #include #include #include +#include "udl_cursor.h" struct drm_mode_create_dumb; @@ -60,6 +61,7 @@ static inline struct udl_connector *to_udl_connector(struct drm_connector *conne return container_of(connector, struct udl_connector, connector); } +struct udl_cursor_hline; struct udl_device { struct drm_device drm; struct device *dev; @@ -74,6 +76,7 @@ struct udl_device { int sku_pixel_limit; struct urb_list urbs; + struct udl_cursor cursor; }; #define to_udl(x) container_of(x, struct udl_device, drm) @@ -97,7 +100,8 @@ int udl_init(struct udl_device *udl); int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr, const char *front, char **urb_buf_ptr, - u32 byte_offset, u32 device_byte_offset, u32 byte_width); + u32 byte_offset, u32 device_byte_offset, u32 byte_width, + struct udl_cursor_hline *cursor_hline); int udl_drop_usb(struct drm_device *dev); int udl_select_std_channel(struct udl_device *udl); diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index 7702359c90c2..21594144fec5 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -26,6 +26,9 @@ #include "udl_drv.h" #include "udl_proto.h" +#include "udl_cursor.h" + +#define UDL_COLOR_DEPTH_16BPP 0 /* * All DisplayLink bulk operations start with 0xaf (UDL_MSG_BULK), followed by @@ -204,6 +207,7 @@ static int udl_handle_damage(struct drm_framebuffer *fb, const struct drm_rect *clip) { struct drm_device *dev = fb->dev; + struct udl_device *udl = to_udl(dev); void *vaddr = map->vaddr; /* TODO: Use mapping abstraction properly */ int i, ret; char *cmd; @@ -225,9 +229,12 @@ static int udl_handle_damage(struct drm_framebuffer *fb, const int byte_offset = line_offset + (clip->x1 << log_bpp); const int dev_byte_offset = (fb->width * i + clip->x1) << log_bpp; const int byte_width = drm_rect_width(clip) << log_bpp; + struct udl_cursor_hline cursor_hline; + + udl_cursor_get_hline(&udl->cursor, clip->x1, i, &cursor_hline); ret = udl_render_hline(dev, log_bpp, &urb, (char *)vaddr, &cmd, byte_offset, dev_byte_offset, - byte_width); + byte_width, &cursor_hline); if (ret) return ret; } diff --git a/drivers/gpu/drm/udl/udl_transfer.c b/drivers/gpu/drm/udl/udl_transfer.c index 5ff1037a3453..ba3a3ae08943 100644 --- a/drivers/gpu/drm/udl/udl_transfer.c +++ b/drivers/gpu/drm/udl/udl_transfer.c @@ -11,6 +11,7 @@ #include "udl_drv.h" #include "udl_proto.h" +#include "udl_cursor.h" #define MAX_CMD_PIXELS 255 @@ -43,6 +44,19 @@ static inline u16 get_pixel_val16(const uint8_t *pixel, int log_bpp) return pixel_val16; } +static inline u16 blend_alpha(const uint16_t pixel_val16, uint32_t blend_val32) +{ + uint32_t alpha = (blend_val32 >> 16); + uint32_t alpha_inv = 64 - alpha; + + return (((pixel_val16 & 0x1f) * alpha_inv + + (blend_val32 & 0x1f) * alpha) >> 6) | + ((((pixel_val16 & 0x7e0) * alpha_inv + + (blend_val32 & 0x7e0) * alpha) >> 6) & 0x7e0) | + ((((pixel_val16 & 0xf800) * alpha_inv + + (blend_val32 & 0xf800) * alpha) >> 6) & 0xf800); +} + /* * Render a command stream for an encoded horizontal line segment of pixels. * @@ -74,6 +88,7 @@ static void udl_compress_hline16( const u8 **pixel_start_ptr, const u8 *const pixel_end, uint32_t *device_address_ptr, + struct udl_cursor_hline *cursor_hline, uint8_t **command_buffer_ptr, const uint8_t *const cmd_buffer_end, int log_bpp) { @@ -81,6 +96,9 @@ static void udl_compress_hline16( const u8 *pixel = *pixel_start_ptr; uint32_t dev_addr = *device_address_ptr; uint8_t *cmd = *command_buffer_ptr; + const uint32_t *cursor_buf = cursor_hline ? cursor_hline->buffer : NULL; + int cursor_pos = cursor_buf ? cursor_hline->offset : 0; + int cursor_width = cursor_buf ? cursor_hline->width : 0; while ((pixel_end > pixel) && (cmd_buffer_end - MIN_RLX_CMD_BYTES > cmd)) { @@ -107,6 +125,11 @@ static void udl_compress_hline16( (unsigned long)(cmd_buffer_end - 1 - cmd) / 2) << log_bpp); pixel_val16 = get_pixel_val16(pixel, log_bpp); + if (cursor_buf && cursor_pos >= 0 && + cursor_pos < cursor_width) { + pixel_val16 = blend_alpha(pixel_val16, + cursor_buf[cursor_pos]); + } while (pixel < cmd_pixel_end) { const u8 *const start = pixel; @@ -116,12 +139,19 @@ static void udl_compress_hline16( cmd += 2; pixel += bpp; + cursor_pos++; while (pixel < cmd_pixel_end) { pixel_val16 = get_pixel_val16(pixel, log_bpp); + if (cursor_buf && cursor_pos >= 0 && + cursor_pos < cursor_width) { + pixel_val16 = blend_alpha(pixel_val16, + cursor_buf[cursor_pos]); + } if (pixel_val16 != repeating_pixel_val16) break; pixel += bpp; + cursor_pos++; } if (unlikely(pixel > start + bpp)) { @@ -160,6 +190,8 @@ static void udl_compress_hline16( *command_buffer_ptr = cmd; *pixel_start_ptr = pixel; *device_address_ptr = dev_addr; + if (cursor_buf) + cursor_hline->offset = cursor_pos; return; } @@ -173,7 +205,7 @@ static void udl_compress_hline16( int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr, const char *front, char **urb_buf_ptr, u32 byte_offset, u32 device_byte_offset, - u32 byte_width) + u32 byte_width, struct udl_cursor_hline *cursor_hline) { const u8 *line_start, *line_end, *next_pixel; u32 base16 = 0 + (device_byte_offset >> log_bpp) * 2; @@ -194,7 +226,7 @@ int udl_render_hline(struct drm_device *dev, int log_bpp, struct urb **urb_ptr, while (next_pixel < line_end) { udl_compress_hline16(&next_pixel, - line_end, &base16, + line_end, &base16, cursor_hline, (u8 **) &cmd, (u8 *) cmd_end, log_bpp); if (cmd >= cmd_end) {