From patchwork Wed Apr 11 15:22:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandru-Cosmin Gheorghe X-Patchwork-Id: 10335713 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C09B760365 for ; Wed, 11 Apr 2018 15:24:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B39322897C for ; Wed, 11 Apr 2018 15:24:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A7BAC28980; Wed, 11 Apr 2018 15:24:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.1 required=2.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C0CE82897C for ; Wed, 11 Apr 2018 15:24:31 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E00716E6B4; Wed, 11 Apr 2018 15:23:43 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from EUR02-VE1-obe.outbound.protection.outlook.com (mail-ve1eur02on0606.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe06::606]) by gabe.freedesktop.org (Postfix) with ESMTPS id ED7E26E5A8 for ; Wed, 11 Apr 2018 15:23:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector1-arm-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=SzXNev6aIdAkcsrg4SH1D5h0lvObYB/HEIHg7qwlK7w=; b=sBAIYmyiWCGnMfkEVRs9irAfYDAxK8ibqzg2PL0yl8VVR63iviyX0Uu/NwtSek3s9qzVXza7vfad89AEIx44GdZkSMJpTOydhbooaj0ILiBjDdKcnCFlUjrOMlKAmqU922a/SZUEm2dAc/UKtAHnzGkO4191CK9oD7xoasvl2OQ= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Alexandru-Cosmin.Gheorghe@arm.com; Received: from e114479-lin.cambridge.arm.com (217.140.96.140) by AM5PR0801MB1249.eurprd08.prod.outlook.com (2603:10a6:203:1e::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.675.10; Wed, 11 Apr 2018 15:23:39 +0000 From: Alexandru Gheorghe To: dri-devel@lists.freedesktop.org, liviu.dudau@arm.com, brian.starkey@arm.com, ayan.halder@arm.com, seanpaul@chromium.org Subject: [PATCH hwc v2 17/18] drm_hwcomposer: Flatten scene synchronously Date: Wed, 11 Apr 2018 16:22:28 +0100 Message-Id: <1523460149-1740-18-git-send-email-alexandru-cosmin.gheorghe@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1523460149-1740-1-git-send-email-alexandru-cosmin.gheorghe@arm.com> References: <1523460149-1740-1-git-send-email-alexandru-cosmin.gheorghe@arm.com> MIME-Version: 1.0 X-Originating-IP: [217.140.96.140] X-ClientProxiedBy: VI1PR0701CA0066.eurprd07.prod.outlook.com (2603:10a6:800:5f::28) To AM5PR0801MB1249.eurprd08.prod.outlook.com (2603:10a6:203:1e::8) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4534165)(4627221)(201703031133081)(201702281549075)(48565401081)(2017052603328)(7153060)(7193020); SRVR:AM5PR0801MB1249; X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1249; 3:D7jB6h/vdvLP6bf+5GwAT1d/Q8wxGsPOWnO/4X6l6WG9MTwPYomn5jblR0EjiqwKuwea5qDf2dqRQQF0S0CMBW4mX2RtBsqcOk2/F/Fu+tHQGQA02m+sIjEIa9UnXWiZCw6KTZoRSWlcUw1SQhep4SwvCITE5jZUtPHObEoAE/aOzY0qeMPJvTF2aYRWbO5YY1PbB31UJwqglBgt8U+iRn20WXWVBXRLecb+ZBuLmaF8DKeHbh812zA3L+BK9JzX; 25:4CQXFGWqov86qazUQ97RJz4qlN9DqUol9hnAbwREFaOm2w3nYGeD1Xu+gfCDXyCAl/KoyyqE3YZ2uvwOayyYhN9Xz+7gwklk5VWGIa4tB4Re5PitaYtEO1HRYQqRa8PkMkH9F+rq3OXsUPL7YJ7OEwSq3N2aVM+Bj5sQ8IfmCIMq+G7GbnS5NkUncfT3I1ttFJytsYmY7B6TfczOLvHC7VQ74fyxlfW424OkbI6oaY6JcpUC5PdxH6G01/jD7dqHzkFUtl8laeKQ6wNONscPOO1ICw0AdDHYgVE4k9z+/XAG82s6etoDzAaZnmbRm1KNU7JP/6XXe/siKlawUc518w==; 31:KaZXuJooPIePpi6m88V6EOXZDVuUf0aWcHVDRKnmOnTotpKPAK7O3l9gkIEi6EkU7W32ZbULS7NtYK8V3fxAYMzfkhGKCB+otIxJ1TbwtJ+rkZD79Ijq18w12kpY7cBmt5E0G7MSLjao2vhFkdG1OrzwWFiOdtPbxrTH3BJkUjHR7qD+qRDLrEsPTrBKAhm80eJwrw4AHYUTIO5zpaoX5C3mSSu2d1SfnFezXjg+hI0= X-MS-TrafficTypeDiagnostic: AM5PR0801MB1249: NoDisclaimer: True X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1249; 20:3h4MUqyJ9WijH2k/Q5YKunUGH4nXZ7dKIrAZ4GLyOUy9YnQNIjn088Ept7ZyNqEjZq7HoAjBmBpyfCieMPu+Sww2r7rX7uW9KSfD+q/8G0meWFNAk5xasRwMUi8hdKLL+7WBNPCLZblR96dN190DWrwQc98o6dt9YgzwIgkk37Q=; 4:R0CyfTVTYhETsbqQEcONn3aL+b8+yeF9G8PE2DtZRr+aG/SzKfPMSi/pwcTdiR67RWfEKnN4diCHTk2PkjRUv+E6c8u4KC8RTpBeNNj7rKEc7XlPor94UAnqiosvwsFm6QQvHA7we6H7wvrRxFlGIqNNQuVWSdJ7BodC7K6ZemG1vLSkFageseYIyOn37Q2iW9YFC/fv7LUpgdJT4dP+hHb03PmKvkUUDfM1qlRR2vs57gsoICDQGOUiMAOE9fFwRfoPbut1BmfKaVwUQ49RfQvFWUKojgGGjNl3vgVqUThe+QOo1Wxwx93iiIhrN+/3 X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(180628864354917); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3002001)(10201501046)(93006095)(93001095)(3231221)(944501327)(52105095)(6055026)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(6072148)(201708071742011); SRVR:AM5PR0801MB1249; BCL:0; PCL:0; RULEID:; SRVR:AM5PR0801MB1249; X-Forefront-PRVS: 0639027A9E X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(39380400002)(346002)(396003)(376002)(366004)(39860400002)(189003)(199004)(16526019)(478600001)(305945005)(50226002)(16586007)(68736007)(7736002)(86362001)(81156014)(8676002)(316002)(81166006)(4326008)(25786009)(2906002)(50466002)(5890100001)(8936002)(6486002)(105586002)(48376002)(186003)(956004)(5660300001)(6666003)(72206003)(106356001)(476003)(53936002)(3846002)(76176011)(51416003)(52116002)(47776003)(7696005)(36756003)(66066001)(11346002)(446003)(386003)(97736004)(59450400001)(6116002)(2616005)(26005)(486006); DIR:OUT; SFP:1101; SCL:1; SRVR:AM5PR0801MB1249; H:e114479-lin.cambridge.arm.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; Received-SPF: None (protection.outlook.com: arm.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; AM5PR0801MB1249; 23:g8R0Djoq2++W/urXypbyTIMczYYqxGg9CUwy8Cv?= =?us-ascii?Q?IIhPcqrO8tB5DxevrzlHZ4GrEjCOCi/nuGFgiduXAMS1RJ4vyxpuk4a4xgYQ?= =?us-ascii?Q?F/H0SKwSC6PKm4x+0EUXb+jgXfGmRdZwQKijlMcUNeLF9o+sjO3OHTWqq3nO?= =?us-ascii?Q?RNo7yW7co2Cjz+VgWIcTssvcW2Gz1nBpJCwmuFLPKBsEDnv1RFPrnKKgayq7?= =?us-ascii?Q?zYOGpSMEaNMopnRHUtlFEOXEUZdSk1j75x1p/XYowY5My0M0VCnbkiw+jKC/?= =?us-ascii?Q?ECDvSkN4/9Hp2PVFdLtE9t6hAxTWR//KVOTEbeVj5TfMp7SpaeRG9qO7DFyO?= =?us-ascii?Q?ZPvEf8ctatqAjKnFVD+tYPv3fsFeomedeexjGI/j1VGn1p6AHp5gD3coy54+?= =?us-ascii?Q?tqoFP5hJdnnFU0MK7xwy2XDeZMxj+N1KfMskQIcJbsy45Vi39OMY3UVmS9Vv?= =?us-ascii?Q?7lo465Mu1lW/mjS/FKxi7/3p5X8KZO1xIQusfbJiVHuugf2trA2Y8rc+xReb?= =?us-ascii?Q?LRPgsF1/E1tyzBun2TPuUWkkheUCszP3dFbTnGQoNTFUTTYAMDfRT1uyYkAB?= =?us-ascii?Q?fEBTCOnnMMwsfUp6/CA9c9CB4KLuWzw8qnMzhElimy2v/c4lmd0BDpSQ+UjF?= =?us-ascii?Q?EMtAso2Q7cLdBx8bSAGnCnPho3BLabpMoCkvo3908bmbutu2p3CmoJuI076+?= =?us-ascii?Q?rEPYR9LBVAKAvV7LJwxnqCf3hXVIhKL/2yhLQ0wRQaFvoK2mKouk9QnjhK0g?= =?us-ascii?Q?YmiACHkJEA7+UG6IOTa2CfDJ21umU1IPmC95cW+NjqbsYOsIvkR4nf5iKLOz?= =?us-ascii?Q?hxU5hke/8SZi0xQ+ev+wb8C2zgQoG0ksQ+BUHq0gdbEPbqV1M3oXuOSVc5LT?= =?us-ascii?Q?uXA0XghsKONd8Jo86wj52JUZJ/jYbGP6BFmT6BI4UXBZqvfSkoKUhNV+RGnA?= =?us-ascii?Q?fzPXgcNQWzikTHuPHQIHg971OJxU6SAKApG6jYaODlQYxatXSgtuCnja/2j7?= =?us-ascii?Q?eIp1oeuzT/DwyA7v5Y0+DdC409spiJW4tb/3L4dyj9gLsSIc7oACqNQhrF0D?= =?us-ascii?Q?BMGCUojKW51CcM/ivuAYM+62zzFb3U5ARRmJGcCwqkf4N8+MIVGiW0lXR9Va?= =?us-ascii?Q?JcRBTUcl+lPUVl+ldpwgk92WbXZtQob9HBXQe4MKpVbQ7KTCL09U65gu6D3q?= =?us-ascii?Q?pw+ZGtG0iXe3rrpwCcxioT7FNX01E319KoKGr?= X-Microsoft-Antispam-Message-Info: W+HI6mePhE8pyUEp7kbsLM8qHeDKRuSNyjeU6QJX7KS8KKIU7rfrzH2P2SozQhuHi1BU1qFpYDaHpvToRVMQqUjdJBTasvDjtsO8mnGp9tFehCog+jG+5IeP6HKpibwcfiMF0dXLbf5TOJHsKdX2cgFU6YpYC/SerdFmsR90dJMY0OabO/4Cf+H9F2eFHaF2 X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1249; 6:1T+phrLd/JWsWxNpQ+5ZiCcI1lQgJpknM1cMXRQkMtl1uiMQtGIZe1sVrGolhGpegdxdwvgwZ81pwqghNsDn+bz2CNhtMJe+ff7QlwCmlSOxh6lIYg1fI86f1qycwMM1GxDZD2GSz0sa0HkNRmktc9T9UFjBfCma5Ru329x8K66tJDcSoyhirvumhPtXPG5a/No08JXj9fYH6GTyfFZqt3U8C5ytT02GIRUO5TLZx1gQv55PCX5ErYsjQ91kKbVHyC8au4aiP6PsObXFR4m9d7poqIuJ7WxKELTwmfLiMumRGUOQdCZI/aYuT8EFIzmvYnroMcwbJUu3DwVMMOos+w3B2Lz3tWsFRZx81atPNbWX4xtEnWU9DoyMm4fPfUr5VxdKzNPnKHyqoWxY3dz3bpJ0UJ1SwP3G8wGxJ+P65fN7PFhdxSo/HTW8G8l6AIqD5iaRra+wVMJojwjn+DhkpQ==; 5:Zyfhmc0PwiyI9U1anIIVtrOGFrAcz5/LVjOhmOuUxvyDVLKhEO8E090kf+0sUmsbMis8R8GX+KT5cL4EF9HCLdO3YjxeDF80B1CXWKZ+rjmedQU2uMp6Iw6FtDAlq5glaoFbR6eKPmTvshtJAYrcu9hH5ldnFkVaJ+jG2Q0PKNM=; 24:WuhHX9+u8EhCJsBQWvubh7Jtd4j4CkkcTQO5eMTNS3bsOd5x5I0a/GjcQHjXHX45DvrZcuCA7chOGd2mMlm7lgolZuHQVLRboZN+cMGNHt0= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM5PR0801MB1249; 7:t7flPEYxxh4GfnQ5jjc5GRkoGQ+exW+H6cnrBVQDjGx3WX4ppkk5vVsany6btvu3HMls1noWA4fEX4h1tBrgx0E9vaaQfT9QPFUya4mgjosKatzMBxUVhQBBSMallvG/kAA1dZpGH7wQyxDOtNzNeh1PWCvO8hrXMFmoe7dFvam6tb2ERFdCCZ4TMiXb1xvJdmlmgoCXbGOLaRlMQ+sgAetlw4Y5d7xkSiTSoeM4+r1W4UKqJ3nTFTs5fxeoN84q X-MS-Office365-Filtering-Correlation-Id: 9482b1c1-9697-42bd-94b0-08d59fc03416 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Apr 2018 15:23:39.4301 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 9482b1c1-9697-42bd-94b0-08d59fc03416 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0801MB1249 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: nd@arm.com, Alexandru Gheorghe Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Flatten scene on the same CRTC as the one driving the display. The active composition is played back to the display with a buffer attached to the writeback connector. Then we build a composition that has only one plane enabled and that uses the result of the writeback as the input. Signed-off-by: Alexandru Gheorghe --- drmdisplaycompositor.cpp | 203 +++++++++++++++++++++++++++++++++++++++++++++-- drmdisplaycompositor.h | 7 +- 2 files changed, 204 insertions(+), 6 deletions(-) diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp index e535e8a..cb670e6 100644 --- a/drmdisplaycompositor.cpp +++ b/drmdisplaycompositor.cpp @@ -36,6 +36,7 @@ #include "drmplane.h" #include "drmresources.h" #include "glworker.h" +static const uint32_t kWaitWritebackFence = 100; // ms namespace android { @@ -523,7 +524,9 @@ int DrmDisplayCompositor::PrepareFrame(DrmDisplayComposition *display_comp) { } int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, - bool test_only) { + bool test_only, + DrmDisplayComposition *writeback_comp, + DrmConnector *writeback_conn) { ATRACE_CALL(); int ret = 0; @@ -532,6 +535,7 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, std::vector &comp_planes = display_comp->composition_planes(); uint64_t out_fences[drm_->crtcs().size()]; + int writeback_fence = -1; DrmConnector *connector = drm_->GetConnectorForDisplay(display_); if (!connector) { @@ -550,9 +554,37 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, return -ENOMEM; } + if (writeback_comp != NULL) { + if (writeback_conn == NULL) + return -EINVAL; + if (writeback_conn->writeback_fb_id().id() == 0 || + writeback_conn->writeback_out_fence().id() == 0) { + ALOGE("Writeback properties don't exit"); + return -EINVAL; + } + if (writeback_comp->layers().size() != 1) { + ALOGE("Invalid number of layers for writeback composition"); + return -EINVAL; + } + ret = drmModeAtomicAddProperty( + pset, writeback_conn->id(), writeback_conn->writeback_fb_id().id(), + writeback_comp->layers().back().buffer->fb_id); + if (ret < 0) { + ALOGE("Failed to add writeback_fb_id"); + return ret; + } + ret = drmModeAtomicAddProperty(pset, writeback_conn->id(), + writeback_conn->writeback_out_fence().id(), + (uint64_t)&writeback_fence); + if (ret < 0) { + ALOGE("Failed to add writeback_out_fence"); + return ret; + } + } if (crtc->out_fence_ptr_property().id() != 0) { - ret = drmModeAtomicAddProperty(pset, crtc->id(), crtc->out_fence_ptr_property().id(), - (uint64_t) &out_fences[crtc->pipe()]); + ret = drmModeAtomicAddProperty(pset, crtc->id(), + crtc->out_fence_ptr_property().id(), + (uint64_t)&out_fences[crtc->pipe()]); if (ret < 0) { ALOGE("Failed to add OUT_FENCE_PTR property to pset: %d", ret); drmModeAtomicFree(pset); @@ -580,6 +612,15 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, } } + if (writeback_conn != NULL) { + ret = drmModeAtomicAddProperty(pset, writeback_conn->id(), + writeback_conn->crtc_id_property().id(), + crtc->id()); + if (ret < 0) { + ALOGE("Failed to attach writeback"); + } + } + for (DrmCompositionPlane &comp_plane : comp_planes) { DrmPlane *plane = comp_plane.plane(); DrmCrtc *crtc = comp_plane.crtc(); @@ -729,8 +770,18 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, if (!ret) { uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET; - if (test_only) + if (test_only) { flags |= DRM_MODE_ATOMIC_TEST_ONLY; + } else { + if (writeback_comp != NULL) { + if (!CountdownExpired() && active_composition_) { + ALOGE("Writeback composition not needed, abort commit"); + drmModeAtomicFree(pset); + return -EINVAL; + }; + flags |= DRM_MODE_ATOMIC_NONBLOCK; + } + } ret = drmModeAtomicCommit(drm_->fd(), pset, flags, drm_); if (ret) { @@ -769,6 +820,13 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, if (crtc->out_fence_ptr_property().id()) { display_comp->set_out_fence((int) out_fences[crtc->pipe()]); } + if (writeback_fence >= 0) { + if (writeback_comp->layers().size() != 1) { + ALOGE("Invalid numbers of layer for writeback_comp"); + return -EINVAL; + } + writeback_comp->layers()[0].acquire_fence.Set(writeback_fence); + } return ret; } @@ -837,6 +895,8 @@ void DrmDisplayCompositor::ApplyFrame( if (active_composition_) active_composition_->SignalCompositionDone(); active_composition_.swap(composition); + flatten_countdown_ = FLATTEN_COUNTDOWN_INIT; + vsync_worker_.VSyncControl(!writeback); } } @@ -913,8 +973,141 @@ int DrmDisplayCompositor::ApplyComposition( return ret; } +int DrmDisplayCompositor::WritebackComposite(DrmDisplayComposition *src, + DrmDisplayComposition *dst, + DrmConnector *writeback_conn) { + int ret = 0; + if (src == NULL || dst == NULL) + return -EINVAL; + std::vector &src_planes = src->composition_planes(); + DrmCompositionPlane squashed_comp(DrmCompositionPlane::Type::kPrecomp, NULL, + src->crtc()); + for (DrmCompositionPlane &comp_plane : src_planes) { + if (comp_plane.plane() == NULL) { + ALOGE("Skipping squash all because of NULL plane"); + ret = -EINVAL; + } + if (!squashed_comp.plane() && + comp_plane.plane()->type() == DRM_PLANE_TYPE_PRIMARY) + squashed_comp.set_plane(comp_plane.plane()); + else + dst->AddPlaneDisable(comp_plane.plane()); + } + + DrmFramebuffer *writeback_fb = NULL; + AutoLock lock(&lock_, __FUNCTION__); + if ((ret = lock.Lock())) + return ret; + writeback_fb = &framebuffers_[framebuffer_index_]; + framebuffer_index_ = (framebuffer_index_ + 1) % DRM_DISPLAY_BUFFERS; + ret = PrepareFramebuffer(*writeback_fb, dst, mode_.mode.h_display(), + mode_.mode.v_display()); + if (ret) { + ALOGE("Failed to prepare destination buffer"); + return ret; + } + lock.Unlock(); + ret = CommitFrame(src, true, dst, writeback_conn); + if (ret) { + ALOGE("Atomic check failed"); + return ret; + } + if ((ret = lock.Lock())) + return ret; + if (!CountdownExpired() && active_composition_) { + ALOGE("Writeback composition not needed abort"); + return -EINVAL; + } + ret = CommitFrame(src, false, dst, writeback_conn); + lock.Unlock(); + if (ret || dst->layers().size() != 1) { + ALOGE("Failed to flatten scene using writeback"); + return -EINVAL; + } + squashed_comp.source_layers().push_back(0); + ret = + sync_wait(dst->layers()[0].acquire_fence.Release(), kWaitWritebackFence); + if (ret) { + ALOGE("Failed to wait on writeback fence"); + return ret; + } + ret = dst->AddPlaneComposition(std::move(squashed_comp)); + if (ret) { + ALOGE("Failed to add flatten scene"); + return ret; + } + ret = dst->FinalizeComposition(); + if (ret) { + ALOGE("Failed to finalize composition"); + return ret; + } + return 0; +} + +int DrmDisplayCompositor::FlattenSynchronously(DrmConnector *writeback_conn) { + if (writeback_conn->display() != display_) { + ALOGE("Cannot flatten synchronously on different display"); + return -EINVAL; + } + ALOGI("FlattenSynchronously using the same display"); + int ret = 0; + /* Flattened composition with only one layer that is built + * using the writeback connector + */ + std::unique_ptr writeback_comp = + CreateInitializedComposition(); + /* Copy of the active_composition_, we need a copy because + * if we use the active composition we have to hold the lock + * for the entire sequence of flattening. + */ + std::unique_ptr copy_comp = + CreateInitializedComposition(); + + if (!copy_comp || !writeback_comp) + return -EINVAL; + AutoLock lock(&lock_, __FUNCTION__); + if ((ret = lock.Lock())) + return ret; + if (CountdownExpired()) { + ret = copy_comp->CopyLayers(active_composition_.get()); + if (ret) + return ret; + copy_comp->CopyCompPlanes(active_composition_.get()); + } else { + return -EINVAL; + } + lock.Unlock(); + ret = + WritebackComposite(copy_comp.get(), writeback_comp.get(), writeback_conn); + if (ret) { + ALOGE("Failed to prepare writebackScene"); + return ret; + } + + ApplyFrame(std::move(writeback_comp), 0, true); + return 0; +} + int DrmDisplayCompositor::FlattenScene() { - return -EINVAL; + DrmConnector *writeback_conn = + drm_->resource_manager()->AvailableWritebackConnector(display_); + if (!active_composition_ || !writeback_conn) + return -EINVAL; + std::vector &src_planes = + active_composition_->composition_planes(); + size_t src_planes_with_layer = std::count_if( + src_planes.begin(), src_planes.end(), [](DrmCompositionPlane &p) { + return p.type() != DrmCompositionPlane::Type::kDisable; + }); + + if (src_planes_with_layer <= 1) + return -EALREADY; + + if (writeback_conn->display() == display_) { + return FlattenSynchronously(writeback_conn); + } + + return 0; } int DrmDisplayCompositor::SquashAll() { diff --git a/drmdisplaycompositor.h b/drmdisplaycompositor.h index 26201b9..4cc4a5e 100644 --- a/drmdisplaycompositor.h +++ b/drmdisplaycompositor.h @@ -125,7 +125,9 @@ class DrmDisplayCompositor { int ApplySquash(DrmDisplayComposition *display_comp); int ApplyPreComposite(DrmDisplayComposition *display_comp); int PrepareFrame(DrmDisplayComposition *display_comp); - int CommitFrame(DrmDisplayComposition *display_comp, bool test_only); + int CommitFrame(DrmDisplayComposition *display_comp, bool test_only, + DrmDisplayComposition *writeback_comp = NULL, + DrmConnector *writeback_conn = NULL); int SquashFrame(DrmDisplayComposition *src, DrmDisplayComposition *dst); int ApplyDpms(DrmDisplayComposition *display_comp); int DisablePlanes(DrmDisplayComposition *display_comp); @@ -134,7 +136,10 @@ class DrmDisplayCompositor { void ApplyFrame(std::unique_ptr composition, int status, bool writeback = false); int FlattenScene(); + int FlattenSynchronously(DrmConnector *writeback_conn); + int WritebackComposite(DrmDisplayComposition *src, DrmDisplayComposition *dst, + DrmConnector *writeback_conn); bool CountdownExpired() const; std::tuple CreateModeBlob(const DrmMode &mode);