From patchwork Thu Jun 18 12:22:42 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 26962 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id CC6BDC3336 for ; Thu, 18 Jun 2026 12:23:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 33295656D5; Thu, 18 Jun 2026 14:23:41 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="ulN39u/v"; dkim-atps=neutral Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 565D462C79 for ; Thu, 18 Jun 2026 14:23:20 +0200 (CEST) Received: by mail-wm1-x32f.google.com with SMTP id 5b1f17b1804b1-490be29c1c5so7266975e9.2 for ; Thu, 18 Jun 2026 05:23:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1781785400; x=1782390200; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=BSSR9mqCpqCL14/lAv+iQMfbEByDwn/6jQSAQFMK9Uk=; b=ulN39u/vepRrWNuE8EurZwCDWMx+zsS/lvgCxaFMubnBwUcXgfeTjn+qXtXAj5ESWe 5p4/nEP1fnInrdCLwzVDV4Ge1P6ZC+ZpNcopB7nh3BA2ZafQ8R6JOIqxunaRw7ItkyIG FyC2rtseD6NYNWcfZYfhPb8hBpp53Cc7fhTeZQ+fhvIcp817bdDtyQnIfcXH2pSxbate kxg35V3GRU1B3lmwXm5bJGthzwqWKJjTxy0HE/BXXywbPfPN+n02f5NwB2l8d51nEmk1 hH8+bs0KmSWo9ig8Kr5zoAxGaer9D18E6DalWq95HiaRpyKLg4Fmg370V7PnoVCff5L3 kmQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781785400; x=1782390200; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=BSSR9mqCpqCL14/lAv+iQMfbEByDwn/6jQSAQFMK9Uk=; b=ToUvBDiMYNGghmAuWQtMmBWoE++ii/SQmJ7yFaSVF4sOmZx99ZSaJOpMSBvOh0uYwg ILdpmdODOcZyFVh4lp7i8cReJCM29zTXwS5ZN2jmVmu8Wkqs3AH5r0Ht5M4DYKf73lj9 p2WcONx7mghAIYsAq2bDL6NwBevlH/UyGc8LCFvcIVIF08fHNochknhF91GmHrkirQoQ bZKYKGSz+pWZKqNBSYBGfhZ6/gGTHbgrGkkOC9CuDpCfR59aZKZdW6KKls2GY1dx8fT5 HOgM1BqEHItEnJhwa6f72dM5rj82zDKjG0mAP130V/niBuCuguYF0PqQC+r0kLhl6aYR jcLQ== X-Gm-Message-State: AOJu0Yyk0exkg041SkaVAgVktF6xmcmBvUR/wRpQvSDI43ou5CEi5CM7 JQKj1ag8Dskmj2efuZOfxTRqLQD6pDB4wj3RoitIdI8K0g7gLXH0t0Gbgni55b+8EcNSJBGwaP7 d4b8GBS8= X-Gm-Gg: AfdE7cmxL60flH/TpejeMgpr7RHSxIO2vXew8P7VXt3CrjY6thLRYoTQviOtvCutQ7O sixGCX71TXBIGpgrAMSTq8mefCBqJRcnEQ8zhr3yuB7a89FtpxUPU4q+/qQ39pW4RSqj6i62VOE tk/mu6hBa+adubzcBLonNTS2gWJB2Y+xqxxeeZYFffpp/Vv+NHY28ayDHPRk61hHmauqhT5+7nb h+F16wGQai4Srmq1kJPoK/qD6oCpjlCIHjSvOHHF/7WdAgO825uPoOOzQksrL8yQNDH8RBHCS3u Vp+e1Gfs+Jjt5i8gjPSC9zoULno9R81SsAjDiCvpUznyxbi5dn3BUaycVRcy6/Y6GgPnibEXtua yN/1X5s6BxFGbfYShjmVJxHIm3ffHGBQgi8bWRgwfwu4msduhjkHGEriSqEXgkMI2etWkZ6y3U2 4dYNWLPlcQ8VfwgjNh+L9I44Ysk0uL X-Received: by 2002:a05:600c:e54a:10b0:490:e104:7943 with SMTP id 5b1f17b1804b1-492333e294dmr102239425e9.18.1781785399781; Thu, 18 Jun 2026 05:23:19 -0700 (PDT) Received: from inspiron14p-linux ([109.76.144.236]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4922fa3a4easm275198015e9.3.2026.06.18.05.23.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 05:23:19 -0700 (PDT) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: bryan.odonoghue@linaro.org, pavel@ucw.cz Subject: [PATCH 29/30] libcamera: software_isp: gpu: Cache output framebuffers, only recreate when necessary Date: Thu, 18 Jun 2026 13:22:42 +0100 Message-ID: <20260618122245.946138-30-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260618122245.946138-1-bryan.odonoghue@linaro.org> References: <20260618122245.946138-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Once a texture has been created using dma-buf handle, we can switch texture units and ids with our glsl program without re-creating textures. Since we are mapping pages, instead of copying the GPU simply takes the maps it needs and operates on those. Much faster. ➜ libcamera git:(0.7.0-multipass-v4) ✗ grep Bench before.log [15:07:08.009062165] [1195303] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 729270us, 24309 us/frame [15:07:11.686143411] [1195334] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 733995us, 24466 us/frame [15:07:14.980640685] [1195363] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 740157us, 24671 us/frame [15:07:18.163299379] [1195393] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 720094us, 24003 us/frame [15:07:21.366461990] [1195422] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 719166us, 23972 us/frame [15:07:24.718877325] [1195451] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 725425us, 24180 us/frame [15:07:28.924768220] [1195481] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 753400us, 25113 us/frame [15:07:32.336224289] [1195513] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 727160us, 24238 us/frame [15:07:35.638928194] [1195542] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 762408us, 25413 us/frame [15:07:38.868084716] [1195579] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 728991us, 24299 us/frame ➜ libcamera git:(0.7.0-multipass-v4) ✗ grep Bench after.log [16:26:07.109426223] [1202010] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 650120us, 21670 us/frame [16:26:18.925748074] [1202048] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 611062us, 20368 us/frame [16:26:22.712614967] [1202077] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 609333us, 20311 us/frame [16:26:26.551615514] [1202107] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 609791us, 20326 us/frame [16:26:30.085663553] [1202136] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 612838us, 20427 us/frame [16:26:34.945255617] [1202165] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 681918us, 22730 us/frame [16:26:39.031353171] [1202194] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 595551us, 19851 us/frame [16:26:42.610503048] [1202227] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 663929us, 22130 us/frame [16:26:46.100211690] [1202256] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 580685us, 19356 us/frame [16:26:49.394640903] [1202286] INFO Benchmark benchmark.cpp:89 Debayer processed 30 frames in 595072us, 19835 us/frame Signed-off-by: Bryan O'Donoghue --- .../software_isp/software_isp_pipeline_gpu.cpp | 17 ++++++++++------- .../software_isp/software_isp_pipeline_gpu.h | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp b/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp index 2e5c0e40e..bc5d59575 100644 --- a/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp +++ b/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp @@ -263,8 +263,14 @@ int SoftwareIspPipelineGpu::processGPU(FrameBuffer *input, FrameBuffer *output, egl_.updateInputTexture2D(*eglImageBayerIn_, inMapped->value().planes()[0].data()); } - /* Generate the output render framebuffer as render to texture */ - egl_.createOutputDMABufTexture2D(*eglImageRGBAOut_, output->planes()[0].fd.get()); + /* Find an existing eglImage in the cache */ + auto [output_cache, output_miss] = eglImageRGBAOut_.try_emplace(output); + if (output_miss) { + /* Generate the output render framebuffer as render to texture */ + output_cache->second = std::make_unique(GL_RGBA, outputSize_.width, outputSize_.height, outputConfig_.stride, GL_TEXTURE3, 3); + egl_.createOutputDMABufTexture2D(*output_cache->second, output->planes()[0].fd.get()); + } + eGLImage &eglImageRGBAOut = *output_cache->second; pipelineResult = gpuIspShaderPassBlcNormalise_.process(*eglImageBayerIn_, *eglImagePingPong_[0], width_, height_, params); if (pipelineResult) { @@ -272,7 +278,7 @@ int SoftwareIspPipelineGpu::processGPU(FrameBuffer *input, FrameBuffer *output, return pipelineResult; } - pipelineResult = gpuIspShaderPassDemosiac_.process(*eglImagePingPong_[0], *eglImageRGBAOut_, width_, height_, params); + pipelineResult = gpuIspShaderPassDemosiac_.process(*eglImagePingPong_[0], eglImageRGBAOut, width_, height_, params); if (pipelineResult) { LOG(Debayer, Error) << "Demosiac fail"; return pipelineResult; @@ -371,9 +377,6 @@ int SoftwareIspPipelineGpu::start() eglImagePingPong_[0] = std::make_unique(gpuIspShaderPassDemosiac_.glFormat_, width_, height_, outputConfig_.stride, GL_TEXTURE1, 1); eglImagePingPong_[1] = std::make_unique(gpuIspShaderPassDemosiac_.glFormat_, width_, height_, outputConfig_.stride, GL_TEXTURE2, 2); - /* Texture we will render to */ - eglImageRGBAOut_ = std::make_unique(GL_RGBA, outputSize_.width, outputSize_.height, outputConfig_.stride, GL_TEXTURE3, 3); - egl_.createInputTexture2D(*eglImageBayerIn_, NULL); egl_.createOutputTexture2D(*eglImagePingPong_[0]); egl_.createOutputTexture2D(*eglImagePingPong_[1]); @@ -383,7 +386,7 @@ int SoftwareIspPipelineGpu::start() void SoftwareIspPipelineGpu::stop() { - eglImageRGBAOut_.reset(); + eglImageRGBAOut_.clear(); eglImagePingPong_[1].reset(); eglImagePingPong_[0].reset(); eglImageBayerIn_.reset(); diff --git a/src/libcamera/software_isp/software_isp_pipeline_gpu.h b/src/libcamera/software_isp/software_isp_pipeline_gpu.h index b32d4cad3..995e84295 100644 --- a/src/libcamera/software_isp/software_isp_pipeline_gpu.h +++ b/src/libcamera/software_isp/software_isp_pipeline_gpu.h @@ -69,7 +69,7 @@ private: /* Pointer to object representing input texture */ std::unique_ptr eglImageBayerIn_; std::unique_ptr eglImagePingPong_[2]; - std::unique_ptr eglImageRGBAOut_; + std::unordered_map> eglImageRGBAOut_; std::unique_ptr stats_; eGL egl_;