From nobody Sat Feb 5 20:50:41 2022 X-Original-To: freebsd-hackers@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 8C17019AF05C for ; Sat, 5 Feb 2022 20:50:45 +0000 (UTC) (envelope-from sg2342@googlemail.com) Received: from mail-ej1-x633.google.com (mail-ej1-x633.google.com [IPv6:2a00:1450:4864:20::633]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "smtp.gmail.com", Issuer "GTS CA 1D4" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Jrl1069Vfz4gNT for ; Sat, 5 Feb 2022 20:50:44 +0000 (UTC) (envelope-from sg2342@googlemail.com) Received: by mail-ej1-x633.google.com with SMTP id s13so30136332ejy.3 for ; Sat, 05 Feb 2022 12:50:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20210112; h=date:from:to:subject:message-id:mime-version:content-disposition; bh=Cnvfs33YrvaCNpCw5WbR7ajbu4OdzFMyHMP050aM36s=; b=ZpCbcarTMA5NhDXEBtpx0D1+varRmu+xSmMMiDDSkKWH8VReB/cMyLTnJaWauQn/3T B5LTYdO4yiye8ChwZxs/KuYNGWl2gj25mfINzjBR2zGEtbqylBuR1E3lOj2AOYiDMA/D ZcL1tnB6uHVPJiyAi4ULf6FjZLFCbwp83Xw+0wrBrUlvewLmE/Peps7StqZ++ITgFJAc q9E4SVGZRmZdd31hLgG1N2h3NlAhduv2SJ1zw5p1e0QD/aZONR4MtxHtbSbznC4bfjRF JY8t4z29XBY/t5zY69n0eVSw1bfh6ms6BOchxmPzp2seLrGhMXGusXaKMeapN4WlTozr jyCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition; bh=Cnvfs33YrvaCNpCw5WbR7ajbu4OdzFMyHMP050aM36s=; b=y2mT2tQtcEN1dKif6NYt2RXqJ5CWP0aqh6heEkeD+kfCys4Dg246XY2+b5m/HWIBAI lCaVOlxywtFIg1lsDNKpl38dTSQmmB6xyZ6uPJdtC2y6Fr8ZPrLD2Oh3qb9I7VNyML1V L45UGfR6w6h5Vt+kU1FwlsqDdYD+Zral5unnOrZv9R++afTbTDLoJevApSogUGjw7vqK Sb2rjey2DkU/ijP30qnK40QzVihQPkjQxc/t6MHPoVBblCnHdBbkN2kr5sIEoQQ2Tl68 HqCIWdYuYv80wrUFpA5x6m1aEQbNlKZzNDDKiLZd34JVwrLSqQW4sk3xKTQNOjc03sy+ vwkg== X-Gm-Message-State: AOAM530dkZayfxvBuqtng3YMMp/kbmADrj3qTb6Mz8qQQcZXfUC3odW6 KliFPqwKwsCLNAHgtZQHaEPzcNwID3c+zZ+H X-Google-Smtp-Source: ABdhPJzBVgJ+hN6F5Uw/c2ILnS4vp6sjrRdinMXsvisQrtbV/lmQHH+H8Bl/K589hjFUs5P5SMHQ1Q== X-Received: by 2002:a17:907:d8d:: with SMTP id go13mr4159553ejc.440.1644094243738; Sat, 05 Feb 2022 12:50:43 -0800 (PST) Received: from sahu.ennead.xyz (44-102-142-46.pool.kielnet.net. [46.142.102.44]) by smtp.googlemail.com with ESMTPSA id qw28sm777009ejb.0.2022.02.05.12.50.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 05 Feb 2022 12:50:43 -0800 (PST) Date: Sat, 5 Feb 2022 20:50:41 +0000 From: Stefan Grundmann To: freebsd-hackers@freebsd.org Subject: Rotating (efi) framebuffer console Message-ID: List-Id: Technical discussions relating to FreeBSD List-Archive: https://lists.freebsd.org/archives/freebsd-hackers List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-freebsd-hackers@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Rspamd-Queue-Id: 4Jrl1069Vfz4gNT X-Spamd-Bar: - Authentication-Results: mx1.freebsd.org; dkim=pass header.d=googlemail.com header.s=20210112 header.b=ZpCbcarT; dmarc=pass (policy=quarantine) header.from=googlemail.com; spf=pass (mx1.freebsd.org: domain of sg2342@googlemail.com designates 2a00:1450:4864:20::633 as permitted sender) smtp.mailfrom=sg2342@googlemail.com X-Spamd-Result: default: False [-1.56 / 15.00]; RCVD_VIA_SMTP_AUTH(0.00)[]; FREEMAIL_FROM(0.00)[googlemail.com]; R_SPF_ALLOW(-0.20)[+ip6:2a00:1450:4000::/36]; TO_DN_NONE(0.00)[]; RCVD_COUNT_THREE(0.00)[3]; DKIM_TRACE(0.00)[googlemail.com:+]; DMARC_POLICY_ALLOW(-0.50)[googlemail.com,quarantine]; RECEIVED_SPAMHAUS_PBL(0.00)[46.142.102.44:received]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+]; FREEMAIL_ENVFROM(0.00)[googlemail.com]; ASN(0.00)[asn:15169, ipnet:2a00:1450::/32, country:US]; DWL_DNSWL_NONE(0.00)[googlemail.com:dkim]; ARC_NA(0.00)[]; NEURAL_HAM_MEDIUM(-0.53)[-0.528]; R_DKIM_ALLOW(-0.20)[googlemail.com:s=20210112]; FROM_HAS_DN(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000]; MIME_GOOD(-0.10)[text/plain]; PREVIOUSLY_DELIVERED(0.00)[freebsd-hackers@freebsd.org]; RCPT_COUNT_ONE(0.00)[1]; NEURAL_SPAM_SHORT(0.97)[0.967]; RCVD_IN_DNSWL_NONE(0.00)[2a00:1450:4864:20::633:from]; MLMMJ_DEST(0.00)[freebsd-hackers]; RCVD_TLS_ALL(0.00)[] X-ThisMailContainsUnwantedMimeParts: N Hi, the screen of my brand new GPD Pocket 3 (tiger lake) laptop is in portrait mode and reports a resolution of 1200x1920. I have another older device with the same issue (a GPD Pocket 1). In 2019 johalun@FreeBSD.org wrote on the freebsd-current about an Lenovo Ideapad with a portrait mode screen and raised the question if it would be good to support rotation of the vt_fb console. Since the new GPD Pocket 3 is a nice device and rather well supported in FreeBSD, i thought "how hard can it be" (OpenBSD has fb console rotation and Linux has fbcon=rotate..) The patch (against stable/13, at the end of this mail) works for me(tm): Whenever the width of a frambuffer device is smaller than it's height; a portrait mode screen is assumed and the screen is rotated by 90 degrees clockwise. I write this here for two reasons: 1. give others with similar hardware a chance to avoid the neck-craning issue and 2. offer to work on something that can be reviewed and merged e.g. - implement the rest of the transformations (180 degrees, 270 degrees) - boot-time variable to select behavior - vt(4) man page update For 2. i would like to know if vt_fb.c is even the right place to do this. The framebuffer code in the loader could also get this feature. best regards Stefan Grundmann diff --git a/sys/dev/vt/hw/fb/vt_fb.c b/sys/dev/vt/hw/fb/vt_fb.c index c535d1b753c..19ab5999d89 100644 --- a/sys/dev/vt/hw/fb/vt_fb.c +++ b/sys/dev/vt/hw/fb/vt_fb.c @@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$"); #include #include +#define FB_FLAG_ROTATE 2147483648 + static struct vt_driver vt_fb_driver = { .vd_name = "fb", .vd_init = vt_fb_init, @@ -167,7 +169,13 @@ vt_fb_setpixel(struct vt_device *vd, int x, int y, term_color_t color) info = vd->vd_softc; c = info->fb_cmap[color]; - o = info->fb_stride * y + x * FBTYPE_GET_BYTESPP(info); + + if (info->fb_flags & FB_FLAG_ROTATE) { + o = info->fb_stride * x + + (info->fb_width - (y + 1)) * FBTYPE_GET_BYTESPP(info); + } else { + o = info->fb_stride * y + x * FBTYPE_GET_BYTESPP(info); + } if (info->fb_flags & FB_FLAG_NOWRITE) return; @@ -300,7 +308,13 @@ vt_fb_bitblt_bitmap(struct vt_device *vd, const struct vt_window *vw, /* Skip pixel write, if mask bit not set. */ if (mask != NULL && (mask[byte] & bit) == 0) continue; - o = (y + yi) * info->fb_stride + (x + xi) * bpp; + if (info->fb_flags & FB_FLAG_ROTATE) { + o = (x + xi) * info->fb_stride + + (info->fb_width - (y + yi + 1)) * bpp; + } else { + o = (y + yi) * info->fb_stride + (x + xi) * bpp; + } + o += vd->vd_transpose; cc = pattern[byte] & bit ? fgc : bgc; @@ -464,12 +478,22 @@ vt_fb_init(struct vt_device *vd) term_color_t c; info = vd->vd_softc; - vd->vd_height = MIN(VT_FB_MAX_HEIGHT, info->fb_height); - margin = (info->fb_height - vd->vd_height) >> 1; - vd->vd_transpose = margin * info->fb_stride; - vd->vd_width = MIN(VT_FB_MAX_WIDTH, info->fb_width); - margin = (info->fb_width - vd->vd_width) >> 1; - vd->vd_transpose += margin * (info->fb_bpp / NBBY); + if (info->fb_height > info->fb_width) { /*assume 90 degrees clockwise rotation*/ + info->fb_flags |= FB_FLAG_ROTATE; + vd->vd_height = MIN(VT_FB_MAX_HEIGHT, info->fb_width); + vd->vd_width = MIN(VT_FB_MAX_WIDTH, info->fb_height); + margin = (info->fb_height - vd->vd_width) >> 1; + vd->vd_transpose = margin * info->fb_stride; + margin = (info->fb_width - vd->vd_height) >> 1; + vd->vd_transpose += margin * (info->fb_bpp / NBBY); + } else { + vd->vd_height = MIN(VT_FB_MAX_HEIGHT, info->fb_height); + margin = (info->fb_height - vd->vd_height) >> 1; + vd->vd_transpose = margin * info->fb_stride; + vd->vd_width = MIN(VT_FB_MAX_WIDTH, info->fb_width); + margin = (info->fb_width - vd->vd_width) >> 1; + vd->vd_transpose += margin * (info->fb_bpp / NBBY); + } vd->vd_video_dev = info->fb_video_dev; if (info->fb_size == 0)