From patchwork Mon Jul 6 22:22:40 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 27254 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 7069FC3308 for ; Mon, 6 Jul 2026 22:23:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0BFA466056; Tue, 7 Jul 2026 00:23:00 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="zgRpm7+z"; dkim-atps=neutral Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B5B0B6604D for ; Tue, 7 Jul 2026 00:22:57 +0200 (CEST) Received: by mail-wr1-x431.google.com with SMTP id ffacd0b85a97d-47de0093c42so1610832f8f.3 for ; Mon, 06 Jul 2026 15:22:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1783376577; x=1783981377; 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:content-type; bh=s3J/NrfJsMXq4eaqAQimcvyIokeKF2MgvnNr4M7DXMo=; b=zgRpm7+zwetMaazuYHbLWQoElIuVqI6ivjc0Y2IeaRgzZ8q7CGImQlvhO+r6B4Ovgy HBJ0/5ZqbPuqSQdZks6vAxSUSKc3MSDDm8Va0gSu7ftCTeatJnL4FtBdDpPrHqpIhrgw Ofl9xD/TEDOG8MMFeTVyuR0etMErq3uunec57Na1milvc9hOBVh8fczvQBXDSudGGTyU y8UpSheas46QdN4cjwVmzGNn2Fp0L5AVWhbRv8cpop2dkkX9JXZrhRoylAQtogiWXwI5 zkGnhCB/ySu5+VvJOibP/X10687aPANfd4ZwnqUXrpo2G/JHIXTlWaoQOtpDAWuFLdcz lJyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783376577; x=1783981377; 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:content-type; bh=s3J/NrfJsMXq4eaqAQimcvyIokeKF2MgvnNr4M7DXMo=; b=ZfuF1HhgqtEAEJWG+zLXcQzYvBongDalthZpaFqjqXFt2taDRndIvaJidQMyT29UzL 2hVk7jk/rw868hafNEbDO+ty8sWDVTSa+10WTUvxFGaQQdbLi80DY1y5eoqNBPSzzKFI uoqiiPqUmTtfDSPkq3NjFQ8yAMUqA507cBwGDHGz4CKa7Wk9L5wfQ3IXVxNGeiq5q6hr C/5oLoFk0C3VFYiGb9Wmbs1dhKfLi/BdGwjz7FcnsodG5g4UY+nmFutD4hdRP/QHwJ3K jGO52YJAQIUIBHQsn1ft+sPahBFqPXBZeRGvvpO/rSpauCnLJPfMTvcu8F8q1/qlHfoD e94w== X-Gm-Message-State: AOJu0Yyr7aodW1O1vOFZ7tKuWmQGmEiwigXaycsOG09SnPd5J/fUMYS4 Xb1lb+XuUzxLRZ2MOmvr8YLcSJ+4RMkZ8ItzOUiPoPEharajnstA+dGToDF0x9wCZ6CXrWaA2CI eCrgP X-Gm-Gg: AfdE7cnY46BvmcBT8d5goABu9hbwhtOq4H/U8SqG0+UQWVeyN8eTWx3H6VK6cVJqYKk 7biKYMlblrhL2Vb+euxTwF2mvnMqWcbAjo36r0bo8JEwTrf4ngp0p6E0Au/PVMA31DDuVe6m1D5 2EQKkWhwQIPKhTzVfaD9fMkEMSePr0oYHbJp6jm1VSBhY89fAyicv/duR83WB9IjQNBBuLLEh0L JduXwbC1YdKqp5uFQ17hcRw5EuEMkwUV7q5JpNpJdmfLDqpIwXUUJj7jjw4kjZXa1bcE7MnAyLB snIWJ/69nKA7us2DgDtB1owusI7oDz7OtLyRN1nqz7YAl7PFf/DjXaQ8jJQacnBuru8dYhb+veD Llymg+Euv/n3ExnRD5sBu+s+6LTzky34nKMC8ob1+phBPIAOB5Q0iwnjp01rtUUz1NR5IX1AY7i gXNpn/dN436sUVEcI3Kk2fTEWoosl8 X-Received: by 2002:adf:f9cd:0:b0:474:9991:60d0 with SMTP id ffacd0b85a97d-47de6689bc8mr1669724f8f.12.1783376577296; Mon, 06 Jul 2026 15:22:57 -0700 (PDT) Received: from inspiron14p-linux ([109.77.44.220]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47aa039ad21sm27916413f8f.20.2026.07.06.15.22.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jul 2026 15:22:56 -0700 (PDT) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: bryan.odonoghue@linaro.org, pavel@ucw.cz, Robert Mader , Milan Zamazal Subject: [PATCH v6 1/6] libcamera: software_isp: debayer_egl: Pass eglImage as parameter to setShaderVariables Date: Mon, 6 Jul 2026 23:22:40 +0100 Message-ID: <20260706222245.247396-2-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260706222245.247396-1-bryan.odonoghue@linaro.org> References: <20260706222245.247396-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" We will create a cache of textures and eGLImages which means the value assigned to the shader texture unit will come from one of those now cached eGLImage objects. Pass eGLImage as a parameter to facilitate future differentiation. Reviewed-by: Robert Mader Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- src/libcamera/software_isp/debayer_egl.cpp | 6 +++--- src/libcamera/software_isp/debayer_egl.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp index 56545816e..c3a7b7952 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -388,7 +388,7 @@ uint32_t DebayerEGL::preferredInputStride(const PixelFormat &inputFormat, const return info.stride(size.width, 0, 256); } -void DebayerEGL::setShaderVariableValues(const DebayerParams ¶ms) +void DebayerEGL::setShaderVariableValues(eGLImage &eglImageIn, const DebayerParams ¶ms) { /* * Raw Bayer 8-bit, and packed raw Bayer 10-bit/12-bit formats @@ -444,7 +444,7 @@ void DebayerEGL::setShaderVariableValues(const DebayerParams ¶ms) * To simultaneously sample multiple textures we need to use multiple * texture units */ - glUniform1i(textureUniformBayerDataIn_, eglImageBayerIn_->texture_unit_uniform_id_); + glUniform1i(textureUniformBayerDataIn_, eglImageIn.texture_unit_uniform_id_); /* * These values are: @@ -533,7 +533,7 @@ int DebayerEGL::debayerGPU(FrameBuffer *input, FrameBuffer *output, const Debaye /* Generate the output render framebuffer as render to texture */ egl_.createOutputDMABufTexture2D(*eglImageBayerOut_, output->planes()[0].fd.get()); - setShaderVariableValues(params); + setShaderVariableValues(*eglImageBayerIn_, params); glViewport(0, 0, width_, height_); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLE_FAN, 0, DEBAYER_OPENGL_COORDS); diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h index 4c7c86472..348d7305b 100644 --- a/src/libcamera/software_isp/debayer_egl.h +++ b/src/libcamera/software_isp/debayer_egl.h @@ -65,7 +65,7 @@ private: static int getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &config); int initBayerShaders(PixelFormat inputFormat, PixelFormat outputFormat); int getShaderVariableLocations(); - void setShaderVariableValues(const DebayerParams ¶ms); + void setShaderVariableValues(eGLImage &eGLImageIn, const DebayerParams ¶ms); int debayerGPU(FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms, std::optional *mappedInputBuffer, std::optional *inputBufferDmaSyncer); /* Shader program identifiers */ From patchwork Mon Jul 6 22:22:41 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 27255 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 3B8F8C3308 for ; Mon, 6 Jul 2026 22:23:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CF7D76605E; Tue, 7 Jul 2026 00:23:01 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="QTsGj0c/"; dkim-atps=neutral Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id ED7D16604F for ; Tue, 7 Jul 2026 00:22:58 +0200 (CEST) Received: by mail-wr1-x42c.google.com with SMTP id ffacd0b85a97d-45fd464d51fso1814859f8f.3 for ; Mon, 06 Jul 2026 15:22:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1783376578; x=1783981378; 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:content-type; bh=sCherSufb0on4kaTY2CKoIjTcZ+GTv1qK3dt1yZ0ysg=; b=QTsGj0c/FYjGwuBw5jh8YjYIPAhBbfZ2MdTXqwxo54pAnopT3oHh7e9VD7PLAiJ4Dh Soiin1HvN1PU0AlGv4bwxoxi9hEvRu6uTfpCibqADOfWcOP4fxxPgZMiCjZRqFn5qHvj xsZlBlpv0dSYpFgsyl+LGsyJcBtWPdGYigdEFPKrEXR9GIp+75BTzCCUbg0E2l2iht7s ne7QUizdAOqyv+OgCDdKuZ7b6dCx002IxoCMQkVCLtN4W80Z2LEZuMh2F3+UTJ+mByOI G9WWxioJT5bwXD+3769oOOma2AcCg8FCvXg5pXwJY6d6GXgsTi9129sjr+fFxSpvdOMu gwMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783376578; x=1783981378; 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:content-type; bh=sCherSufb0on4kaTY2CKoIjTcZ+GTv1qK3dt1yZ0ysg=; b=CHHjh3Mg14vSUN2Q1AstsfbwDFaT88XI5QeHlLAE/0OfzXhqbdi19026B9sU+asHt/ JAxB7f89dL0DmZ7QIT8yUzwgnTXEMG9aqBOZCBdjrESS+iUQFH8ayR6tT3KR2S4zq2g4 kqY3oe8jIFixB8PTMY8RVP/Uuy50sPirqun7byMCRABxi+GjhxamYelzC0oAlG5mqC33 60VrAcljXHGviwa/wkcRpMDMrCAFmCbQwUvA1BlH8Ib5hMvPCD+1mBNvXVHGC8WPoiBU k7CD8fYqPv0+rijtPzUu7s01ibzyQqR5+GlRSZA5Fl0Agkzg9IgAaLc/xhBt9jx7U9uT jsrQ== X-Gm-Message-State: AOJu0YynCowIxGaeBIaIVMkx4A5ufY3IzOOfM5TwBvqAiB0y5iRwr/jS zgJ3vU+FSMn0OO4CuPshUY7+Ox8IMjOPN1qCgOSNCjoljBg4siiPlDrTlWf8hoAkktDOds8jI0T kj8FN X-Gm-Gg: AfdE7cmUfP0sTaMSN3TNGT41mlaslRDZo13/1lvgUJLsB5PiQNnQEomeC/IoMVYEa5s 8KFfBlqKtIixs8l51ylmowUtjwFKoTXFGWsut9z6FeAGjuVRGXR8Jzf+fxUXKXNymV8lV36qfbt GYafRPqm3uGFHf0+Q8gOjSObc8NfWRkLmiNUGsYVafsKdBlfWzE7glEYefAX/COujxrgpOoSYfI jeyKM/2P8R7MdKQGrb6IWGzYfnDpF/CaJSWXhkrJNL1TA/asX75Jqo2hLW1WqtuTOmHpu9Kgs/V JtJAQUG6TSqFQLKJTj/g24brmXMJ1X1jJAxb5W7xlZyCLFFZiBm2MegOT9F3vIw9J2sGDqXRfPx fYYU8dHQrjCjilyFymJpr9ggsLWHtIj2P/NuyGwNYbuygcMtORQJNdYOFAooDwavbMQjxEvRl+C jUn8EYXuHqxVHa5+BbWzZT9SFEBHIHbLJ0oFRIWcY= X-Received: by 2002:adf:f390:0:b0:473:fe94:9bf1 with SMTP id ffacd0b85a97d-47de66693b9mr1854859f8f.26.1783376578276; Mon, 06 Jul 2026 15:22:58 -0700 (PDT) Received: from inspiron14p-linux ([109.77.44.220]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47aa039ad21sm27916413f8f.20.2026.07.06.15.22.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jul 2026 15:22:57 -0700 (PDT) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: bryan.odonoghue@linaro.org, pavel@ucw.cz, Robert Mader , Milan Zamazal Subject: [PATCH v6 2/6] libcamera: egl: Add new helper attachTextureToFBO Date: Mon, 6 Jul 2026 23:22:41 +0100 Message-ID: <20260706222245.247396-3-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260706222245.247396-1-bryan.odonoghue@linaro.org> References: <20260706222245.247396-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" This method does what it says on the tin. It attaches a texture to a framebuffer object, splitting existing code into a helper function which we will use in subsequent patches. Reviewed-by: Robert Mader Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- include/libcamera/internal/egl.h | 2 ++ src/libcamera/egl.cpp | 42 +++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h index 523a62aa8..085a371f3 100644 --- a/include/libcamera/internal/egl.h +++ b/include/libcamera/internal/egl.h @@ -109,6 +109,8 @@ public: int createOutputDMABufTexture2D(eGLImage &eglImage, int fd); void createTexture2D(eGLImage &eglImage, void *data); + int attachTextureToFBO(eGLImage &eglImage); + void pushEnv(std::vector &shaderEnv, const char *str); void makeCurrent(); diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp index b5a5dc60b..ed67aca7b 100644 --- a/src/libcamera/egl.cpp +++ b/src/libcamera/egl.cpp @@ -112,6 +112,32 @@ void eGL::flushOutput() glFlush(); } +/** + * \brief Attach a texture to a frame-buffer-object + * + * \param[in,out] eglImage EGL image containing texture to attach to FBO + * + * Helper function to make attachment of texture to FBO easy to reuse. + * + * \return 0 on success, or -ENODEV on failure + */ +int eGL::attachTextureToFBO(eGLImage &eglImage) +{ + int ret = 0; + + // Generate a framebuffer from our texture direct to dma-buf handle buffer + glBindFramebuffer(GL_FRAMEBUFFER, eglImage.fbo_); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, eglImage.texture_, 0); + + GLenum err = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (err != GL_FRAMEBUFFER_COMPLETE) { + LOG(eGL, Error) << "glFrameBufferTexture2D error " << err; + ret = -ENODEV; + } + + return ret; +} + /** * \brief Create a DMA-BUF backed 2D texture * \param[in,out] eglImage EGL image to associate with the DMA-BUF @@ -127,6 +153,7 @@ void eGL::flushOutput() int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output) { EGLint drm_format; + int ret = 0; ASSERT(tid_ == Thread::currentId()); @@ -186,19 +213,10 @@ int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (output) { - // Generate a framebuffer from our texture direct to dma-buf handle buffer - glBindFramebuffer(GL_FRAMEBUFFER, eglImage.fbo_); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, eglImage.texture_, 0); + if (output) + ret = attachTextureToFBO(eglImage); - GLenum err = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (err != GL_FRAMEBUFFER_COMPLETE) { - LOG(eGL, Error) << "glFrameBufferTexture2D error " << err; - return -ENODEV; - } - } - - return 0; + return ret; } /** From patchwork Mon Jul 6 22:22:42 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 27256 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 53051C3308 for ; Mon, 6 Jul 2026 22:23:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 180186605B; Tue, 7 Jul 2026 00:23:05 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="OHuVteHy"; dkim-atps=neutral Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 577C16605C for ; Tue, 7 Jul 2026 00:23:00 +0200 (CEST) Received: by mail-wr1-x430.google.com with SMTP id ffacd0b85a97d-476d8e647e9so2903213f8f.0 for ; Mon, 06 Jul 2026 15:23:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1783376580; x=1783981380; 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=39/wg15FASnXwYPaNXZRuMgZsbEtqLQEwRNrqEYsJnk=; b=OHuVteHydBBS5ekNpCdhJumVVcRnckUvAUM9Ny0m1mxGn3SjCmOXNexJ+CUlH4GMrD 6iB9WyYnsznAwAqcJwGSFh6fh6mSYGEGyVDTngwBzqY3WniBq0NyQ7naH/9/RW4fVCum /07GQtGOrkPaH/3mYDiqQPow92hZ7EBj+R4GPMlpdHNPsg42I5SUpJPvIGvgpC4wMeyt L2N89JgtexvA7XOWjvwLX3w8dL/TXIZD3uP+pvqEOQj3zocQU5KcFpjmMQQcbZa8wcSY /KnvD5LA4kqIdzISLF3suo+XC1t/KBjvFHFZWJGvO0eJMchH6gxl9hsbgpSjWsls/Uq2 s5lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783376580; x=1783981380; 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=39/wg15FASnXwYPaNXZRuMgZsbEtqLQEwRNrqEYsJnk=; b=FCtdzvyMuOSA+3ZmLIWJFUYrFKQ6XO+PpLJnYk30mqu8t3P4/UnYdR2BWfqk/vUlIw obH0STBv0mEq6pKghmld19k5SwCuHQkhyCTg4PLv0cu6Kfxf/wZiFVTjSXNR5PROqgXF fnXl0r2UWkT2jnMz9JyRLILooC3Q/szi0EAxhmAOL779/SaUP7wkSUrKj1RBErmYvuki a3rJ7bOfcFO/tli9ZgEs9tiskTl1UBkoQzNuxcJKHd3hH2azD+9HVF0uajWXdTWEYCpw gTOImI17auTtmeRAgRZ3qMoURsDkzHCa0GXzQvnsNboY2CE54qnswGnRvfzXuKngwtjm 20vQ== X-Gm-Message-State: AOJu0YwQlGRcK1Fc3srvPuk3a6t6jWiFD8A/5cPMvLiRx3r8Z7RFYxW5 +Y3ZOF6+jcELtuRoki0TUp3+PlDKJEIYQUMRUYQl57ljfMYlCfBTxN3f+NcZkD0mCUp2itjddbe LdFfx X-Gm-Gg: AfdE7clu9WwC9jD+Q12pVuaiLrGLGlaBcoRXSw50SUaWlx1cte8ndpO9SjI94l2zfMK /qxEghXuIL/9WTj1FYbNmjQQEe0al2AeHkshd3Mst/MI43Ki5fofI4sAntDUMaqlRmdkP0YyIoE Nlr31fdpVZtmT+7+VMG2OjTfIRhevcDDgJNyy0Jd+ZHC/gjbQIPt4DVJv2t8ehps97i2qZTOeXk VPksRxRXzuoGOOUvicLX+5q7FnY7t+B+4N5p8o7Dp+r2Xn61UDxqvB7snH9rW7tTRNgKAoF1hql rpLce3YxbT2QMa+YMGSDEHKzka3st+zRaj8ft+6jDwpfCZ6/8WfZilelnkPzR3qUkDpg0QPl5EJ hxoZwKlF9N5VP9I6I2f30K4hwJAyf3TODlbNLzAph99Ec03rT3JgawEeY+XChGtOgAcpC2v+r78 gOdn+ZSIP0mjP1S+1I+9Z+eq7xuFZT X-Received: by 2002:a05:6000:604:b0:473:506a:e47c with SMTP id ffacd0b85a97d-47de661f7e1mr2308962f8f.26.1783376579791; Mon, 06 Jul 2026 15:22:59 -0700 (PDT) Received: from inspiron14p-linux ([109.77.44.220]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47aa039ad21sm27916413f8f.20.2026.07.06.15.22.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jul 2026 15:22:58 -0700 (PDT) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: bryan.odonoghue@linaro.org, pavel@ucw.cz, Milan Zamazal Subject: [PATCH v6 3/6] libcamera: egl: Add createOutputTexture2D Date: Mon, 6 Jul 2026 23:22:42 +0100 Message-ID: <20260706222245.247396-4-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260706222245.247396-1-bryan.odonoghue@linaro.org> References: <20260706222245.247396-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" Creates a non-dmabuf texture attached to a frame-buffer-object FBO, which allows for render-to-texture. Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- include/libcamera/internal/egl.h | 1 + src/libcamera/egl.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h index 085a371f3..1955d09c5 100644 --- a/include/libcamera/internal/egl.h +++ b/include/libcamera/internal/egl.h @@ -108,6 +108,7 @@ public: int createInputDMABufTexture2D(eGLImage &eglImage, int fd); int createOutputDMABufTexture2D(eGLImage &eglImage, int fd); void createTexture2D(eGLImage &eglImage, void *data); + void createOutputTexture2D(eGLImage &eglImage); int attachTextureToFBO(eGLImage &eglImage); diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp index ed67aca7b..c1b5514b6 100644 --- a/src/libcamera/egl.cpp +++ b/src/libcamera/egl.cpp @@ -329,6 +329,19 @@ bool eGL::isAvailable() return true; } +/** + * \brief Create a 2D texture attached to an FBO for render-to-texture + * \param[in,out] eglImage EGL image to associate with the texture + * + * Creates a 2D texture in VRAM. Subsequetly attach the texture to the + * texture unit specified in the eGLImage object. + */ +void eGL::createOutputTexture2D(eGLImage &eglImage) +{ + createTexture2D(eglImage, NULL); + attachTextureToFBO(eglImage); +} + /** * \brief Initialise the EGL context * From patchwork Mon Jul 6 22:22:43 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 27257 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 A4B60C3308 for ; Mon, 6 Jul 2026 22:23:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D66DA6606D; Tue, 7 Jul 2026 00:23:05 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="w9MAXx16"; dkim-atps=neutral Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B68B466054 for ; Tue, 7 Jul 2026 00:23:01 +0200 (CEST) Received: by mail-wr1-x430.google.com with SMTP id ffacd0b85a97d-45fd464d51fso1814869f8f.3 for ; Mon, 06 Jul 2026 15:23:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1783376581; x=1783981381; 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:content-type; bh=hvwKB7CQKp8AngpWiJmPSQs7XuQyPTLQJEhfb8AHvCw=; b=w9MAXx16IUTiD3cUdtk0UUyoc6qo9MMydvOOx72mxckmBNrfppvLn/KOuwu12BLCgd EnP+v8hTh7WuwWV1/+4mFX9yUiVs0vwmrycsBYi6Eb5NwEzTctqiZLW15TTfGL4fctbs Byeech4BU07nh2oQi2kGwscTBZr2qXsGZPhtW7rfQcmjrCYncyiTS/eTYh9nscVR77ql ZwevjzRLoZjN7IS0xdETJAtPjeZkwLh2vH7aAmyxnyLMYXJYeCI92A/sYJPw2XEHRJyw mMBvscmNSWcPMwAAgqfNfsdNm5+MV1cCmvhpwHuKBfESN0HtMRcCHWOzN5Ooa3Vs7n5/ +frQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783376581; x=1783981381; 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:content-type; bh=hvwKB7CQKp8AngpWiJmPSQs7XuQyPTLQJEhfb8AHvCw=; b=mSnkQhOOFxlMOEzMpKsLyfwBkaiGVpS5r03L7Xr5FOdA+EgQd6NPH+L10OH0bqOJJi KwF9u7wNgJ0s/lTf3q1gYy5aA9Dcl8Gq54P+W+YFuQ1BaOiFiLWsDYSFewk2T3tc1+Hh mprRmaGB9vjlGY3A7f2pp+U9sQ7kPibGlv1neMywb+XjCf9ZxivbAngmBFDY4KHbCrM2 lqL/6AOxotqMr30U78e0pxCESlydFwY/MRnpv2CBztETo9LBwN8VQGJRLlWh6hb4fiyB 4MLU/CaT0b/UxY5kxtTHGNnxSPcwjDWoJqRv6ToH1hXa5VvFSlmOoxhnXkyXbRI/4olx R2gw== X-Gm-Message-State: AOJu0YyLYAUqeBI49A7imub2/SY8snH7+b3emkyoZ+yVGKGXEBkWxNFY wzvcbWhVrOF2VB/Eo+1BHjvzof9ABRT6e8V97dPetkLS9oo62TrHVTFasES62rjPDoT+WAFRrBD h8KN5 X-Gm-Gg: AfdE7cm/IEiBk32lve+NPdhIwLs3bv+WiLgWgZDV4HMUsNxaT61K/1TnBBammnvIEzf 3LRdnFTxG4baB2nzMbDwRXJgclc+zKoSclz7QVHzZBVuTtLwxwMpt8E2AKxSfXnG9rJRz1GXQDb pZWvLcjycD0rhgoQho8Ft7sZgWMWjCjFzxaYW1ogtqgkYUKVLwDe3d74/SbiT/wNlePoDXH4mbs a6QzFT6Wfo3oObaqmKAxpK1YLlzx62ZXV6huygynhE11MhRSMLL8ehQLWLRA39yWP3kBGWCETON akJsd2O9sm4DvU7s56Gj8ZzPrzYFNmQahIGB73pldEAf4fJEj3AxRTRJydHNH0lYnvv/2IDXnuV 6nK8CrfPQdL05mWC7wQRLB546q2QVQtRONjQ1Fqsyvmhal8a2duzUJXgNRAIkMPVgUtaKobev9d j3gOKnKu/FEN2MxsGb4NbmyNH2VDPI0ECwNeQrqV4= X-Received: by 2002:a5d:4ecd:0:b0:46f:7d90:8125 with SMTP id ffacd0b85a97d-47de665b2ecmr1530441f8f.15.1783376581282; Mon, 06 Jul 2026 15:23:01 -0700 (PDT) Received: from inspiron14p-linux ([109.77.44.220]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47aa039ad21sm27916413f8f.20.2026.07.06.15.22.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jul 2026 15:23:00 -0700 (PDT) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: bryan.odonoghue@linaro.org, pavel@ucw.cz, Robert Mader , Milan Zamazal Subject: [PATCH v6 4/6] libcamera: egl: Add activateBindTexture Date: Mon, 6 Jul 2026 23:22:43 +0100 Message-ID: <20260706222245.247396-5-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260706222245.247396-1-bryan.odonoghue@linaro.org> References: <20260706222245.247396-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" When operating from a texture cache on dma-buf inputs we will no longer create new textures nor attach those textures for dma-buf handles we have already encountered. This means we will use the texture id associated with a given texture unit to switch between one texture and another. The pages associated with the texture will have been populated with new data by the CSI2 receiver. All we will do is say to the GPU "reuse this texture id" aka zero-copy. However we must also activate and bind that texture for each loop. This cost is small but necessary for zero-copy. Reviewed-by: Robert Mader Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- include/libcamera/internal/egl.h | 1 + src/libcamera/egl.cpp | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h index 1955d09c5..64196213a 100644 --- a/include/libcamera/internal/egl.h +++ b/include/libcamera/internal/egl.h @@ -111,6 +111,7 @@ public: void createOutputTexture2D(eGLImage &eglImage); int attachTextureToFBO(eGLImage &eglImage); + void activateBindTexture(eGLImage &eglImage); void pushEnv(std::vector &shaderEnv, const char *str); void makeCurrent(); diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp index c1b5514b6..0726b63f2 100644 --- a/src/libcamera/egl.cpp +++ b/src/libcamera/egl.cpp @@ -138,6 +138,23 @@ int eGL::attachTextureToFBO(eGLImage &eglImage) return ret; } +/** + * \brief Activate a texture unit and bind a texture to that unit + * \param[in,out] eglImage EGL image containing data related to unit and texture id + * + * When we create a texture we will bind a texture unit and texture id so + * we can set filters. For the case where a texture already exists though + * we need to activate and bind an existing texture. This helper function + * facilitates both cases. + * + */ +void eGL::activateBindTexture(eGLImage &eglImage) +{ + // Bind texture unit and texture + glActiveTexture(eglImage.texture_unit_); + glBindTexture(GL_TEXTURE_2D, eglImage.texture_); +} + /** * \brief Create a DMA-BUF backed 2D texture * \param[in,out] eglImage EGL image to associate with the DMA-BUF @@ -197,9 +214,7 @@ int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output) return -ENODEV; } - // Bind texture unit and texture - glActiveTexture(eglImage.texture_unit_); - glBindTexture(GL_TEXTURE_2D, eglImage.texture_); + activateBindTexture(eglImage); // Generate texture with filter semantics glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); @@ -270,8 +285,7 @@ void eGL::createTexture2D(eGLImage &eglImage, void *data) { ASSERT(tid_ == Thread::currentId()); - glActiveTexture(eglImage.texture_unit_); - glBindTexture(GL_TEXTURE_2D, eglImage.texture_); + activateBindTexture(eglImage); // Generate texture, bind, associate image to texture, configure, unbind glTexImage2D(GL_TEXTURE_2D, 0, eglImage.format_, eglImage.width_, eglImage.height_, 0, eglImage.format_, GL_UNSIGNED_BYTE, data); From patchwork Mon Jul 6 22:22:44 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 27258 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 328CAC3308 for ; Mon, 6 Jul 2026 22:23:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BB83F6605B; Tue, 7 Jul 2026 00:23:07 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="KttMJ/q5"; dkim-atps=neutral Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8278F6604F for ; Tue, 7 Jul 2026 00:23:02 +0200 (CEST) Received: by mail-wm1-x333.google.com with SMTP id 5b1f17b1804b1-490cf322ed0so22524115e9.1 for ; Mon, 06 Jul 2026 15:23:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1783376582; x=1783981382; 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:content-type; bh=/B6GIAyW48ah9/xcsZgbpJ85k5AYURJJX6RMJWKLdbo=; b=KttMJ/q54CQS+UqWtZ3729Cuc74I1UkdmwqUz6yvdvOqFDjJ0biZ8PfWNfbGo8Zf2O lOOgi6wYtFznRUAjSxK7T4RV6lxXdmAak143t47pjeVzNk2ysHsXWkQtEv6xfwLa+C9n 4+QTXhroia7kTWs6bJzhh7vHtkMAyykYOEYuinXt+38Ks0SaRVgcsiQbfbSmuU7VbREu Zk5Gd+RO//qNNjPQFlj/I8a6BZ66bWcroJ3KfZxwaaXWBtuf+qOxKYtx9CUd0IS4h5Lo OSREU3c1ALAaYjKIROJlTGeVSA2ZmkOOw7AYuHz/v8pYSdgBCKZ3OAJRcz30qt1xufP+ TqNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783376582; x=1783981382; 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:content-type; bh=/B6GIAyW48ah9/xcsZgbpJ85k5AYURJJX6RMJWKLdbo=; b=N7fQpVHgMP86lWhFAGXgXY4PrYrHWOVA5i+BbPolYj/RdERcrEsN3qvYwdZbYAIdek KTX68a5XcrdTXY/zQ9fZ1ZWSatVvDiE+D9PjHviZ8uxI9R7cPjsQEgykG5oJpKpIPHMB UIR7o8tw0h6Y1C5blXErVqJme1Wdll5/Kzp48ir2/FqnsKqZ6VGkvCaeTNAJE4kJ9ULt FywULVDNaflVxHJ4d8sJZXwK1uzIyng/d+t3+s+3G1Oq+FHYUx/9U9Y13krP9vdCf/fW ei+C3xVIYfrEuV2+aqOzsXh0skV4GJQvg9W2lUEz9uxlMIvMJNkE2ozBjEPe/z1F4P1v zuzg== X-Gm-Message-State: AOJu0Yyw4h8KJl7UMsIKA/M9jipribJKNJROomiat0I75oLbS+PtcZVn sw2CCz4Ur0eUtE1+A70kCVzNAkEVQ1JKpfWdVIsf2wvyIygyEsRVN1soKO10N81CARv96lkRHAr FxoY8 X-Gm-Gg: AfdE7clL9F4kAcpmpwFxDYDZESikNuLRRSvtBYvZMOHHK8X34W96XIELs9xkhoUG6VF jqRixKoa2DuQg6yHaeZic60E5zMovIwjUyNE/xC1VEbvPAZvTQza4tD844l2U1b3STXzkcgjdDZ IYiOUaMjuT7icIB967qQunO+dsWSR+yCP7yo+n/QmX/T5sgGlYEBkavnQ8tJnCvGtYorOYIor3D S+M1QbeUaroxd9voKwCTYim5fXVTnK3/QmBrwP6NCq6ECD7XUSS/ocw5yyhiP68Kf8dEZqZSLBl PCfkOKqv2wP2HuN0JFVtrZBf7PHphbPOM1uddY6MdjDDq044PaklRGRtwefGvPXuZMMcujkwSIP j5RVEepQPiM+op5wCrcY3aABWM81IzKne37F/BEtd37ZJms7z7YxZMCq6CCOCXPgygSjsnbdPqV BhK+wmiYqfevXCNLBCxLJU9sz8225+ X-Received: by 2002:a05:600c:8283:b0:493:b8cd:2555 with SMTP id 5b1f17b1804b1-493df066947mr24762605e9.3.1783376582063; Mon, 06 Jul 2026 15:23:02 -0700 (PDT) Received: from inspiron14p-linux ([109.77.44.220]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47aa039ad21sm27916413f8f.20.2026.07.06.15.23.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jul 2026 15:23:01 -0700 (PDT) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: bryan.odonoghue@linaro.org, pavel@ucw.cz, Robert Mader , Milan Zamazal Subject: [PATCH v6 5/6] libcamera: egl: Add updateTexture2D Date: Mon, 6 Jul 2026 23:22:44 +0100 Message-ID: <20260706222245.247396-6-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260706222245.247396-1-bryan.odonoghue@linaro.org> References: <20260706222245.247396-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" The internet box tells me that glTextSubImage2D lets us update a texture's data only, instead of recreating the texture and uploading data. This is a smallish optimisation but we are hunting for every possible cycle and watt so add the routine as precursor to using it in-place of createTexture2D on every upload cycle. Reviewed-by: Robert Mader Reviewed-by: Milan Zamazal Signed-off-by: Bryan O'Donoghue --- include/libcamera/internal/egl.h | 1 + src/libcamera/egl.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h index 64196213a..1e31d490b 100644 --- a/include/libcamera/internal/egl.h +++ b/include/libcamera/internal/egl.h @@ -108,6 +108,7 @@ public: int createInputDMABufTexture2D(eGLImage &eglImage, int fd); int createOutputDMABufTexture2D(eGLImage &eglImage, int fd); void createTexture2D(eGLImage &eglImage, void *data); + void updateTexture2D(eGLImage &eglImage, void *data); void createOutputTexture2D(eGLImage &eglImage); int attachTextureToFBO(eGLImage &eglImage); diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp index 0726b63f2..7ec7a654d 100644 --- a/src/libcamera/egl.cpp +++ b/src/libcamera/egl.cpp @@ -343,6 +343,23 @@ bool eGL::isAvailable() return true; } +/** + * \brief Update a 2D texture already created + * \param[in,out] eglImage EGL image to associate with the texture + * \param[data] Data to update the texture with + * + * Updates a 2D texture in VRAM. + */ +void eGL::updateTexture2D(eGLImage &eglImage, void *data) +{ + ASSERT(tid_ == Thread::currentId()); + + activateBindTexture(eglImage); + + // Update an already existing texture + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, eglImage.width_, eglImage.height_, eglImage.format_, GL_UNSIGNED_BYTE, data); +} + /** * \brief Create a 2D texture attached to an FBO for render-to-texture * \param[in,out] eglImage EGL image to associate with the texture From patchwork Mon Jul 6 22:22:45 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 27259 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 83314C3308 for ; Mon, 6 Jul 2026 22:23:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 91B0666063; Tue, 7 Jul 2026 00:23:08 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="iPF+/l4T"; dkim-atps=neutral Received: from mail-wm1-x336.google.com (mail-wm1-x336.google.com [IPv6:2a00:1450:4864:20::336]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5D12E6605B for ; Tue, 7 Jul 2026 00:23:03 +0200 (CEST) Received: by mail-wm1-x336.google.com with SMTP id 5b1f17b1804b1-493bab44440so207565e9.0 for ; Mon, 06 Jul 2026 15:23:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1783376583; x=1783981383; 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=SslCStkiHkFC7e1FQGIriVH2RTlbB3ja2yOPPwrhQ6k=; b=iPF+/l4TGt/PV5R9y09GPcKjeTDVNbNNfIz2CaSPPI3KU7nT4u1+CprXsuaZo/fN34 5vonCZWKpbn5LO7L7KzbFKVjdIEB7CwktNFegV/r7WKXyHcIVapMfZyC4/K7F/agPSFM zjfW7Nlc82N66YwmD/nsqQfYhNI4/aClgCVv08G7l+6HESSt8jMoLw5/T6Ke9eKxdCAr 6bzHXyEOK8T/LXJDsN/UMPl1TxNvjIcw13r8hK3d8k0n7lJBWIv02u0VPlJSnO6B55wT +axHadLN5ejfAl9aRMeEL/Tbq8Kcetf0Doo2C8Y6Zyz8eX6tyALibGLS1OIUVuPLhdJ9 NvAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783376583; x=1783981383; 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=SslCStkiHkFC7e1FQGIriVH2RTlbB3ja2yOPPwrhQ6k=; b=Ka9Xl2DXpLQFv8XH3MXxwngpXeAibRzpQ86EmSCSTMmjaOIDgJMotlInwXkySDzKfu tY0sZsC9lKIuIO1mSpPZ5TspOEbWLCla6jFEzxGXgRYpYu+AhOdvTTypgYOdFr6oDYx+ P0tJqzValw1Rs5trAQX27BzEy1uPCfmYCchX/80YQgb76/bw4MLNaoeWT65qPxfzNHTL l/h9eTbjKIaXDfXieXV788NjNE01cBNfTqRVRAMZTrMP5F0GcMMeKsqoitWt1oKua8GU 7OtIqTfCzbSkRiTym58k2S7b/lHxSrnzEGhCBpl7VM8opg4yGpMK5d0vOeXjL5ggjvWC qicg== X-Gm-Message-State: AOJu0Yz+RrfK/CMYAwOAXY3kPS69B1Q/AGAjU0IXDZtwN9ZbIj7xX9u6 JdlOr/OBzfZpAd0s/8R0gNmGjg3vSoHx4QysyrubqAhRZmvEFF39BqcPSyDIN16tzvs+9XcykNt 5Ixtg X-Gm-Gg: AfdE7cnr/N7hwd/Nq6Zo+bH8U/8cfpPLETdkhwuG196TWyhxEfH1s8vFaDtp+2z8jos wcp5Qyl7852QKXexVuq6g/dI2EGWUTLgPMn9G3vyW3Oi2wM4Q8W+inCqkZpKXvT2vIgIFLk/xYz PQuLozjEjR1Ys4SI/uCIdjfc1DYSvV42meeiJ/j/5RDWi5AZl8Q1B6O5MU+FS1UoiChDbesn4YA e1QJbo9saXIM2wLNLtJBJcE0zxky9jGL8tCIZKAwJUrqpjOuGLpFx1NYSAp748/ZR9NYu2Q3Ilf J5JAZ5e5EF57JET1+f0X7l4GGOieJ8kWfQN0i1ooINXN8ibjZH8JMTi1bw/Dmg/mx8vwOnq2DOE u//fcwu6d3+XnYHg6U9XmlVDxqg4D1Hu4A+8Ltjjk+EvLt9jxeygQXCHNeLDEwBZdOeI295TFHT tSSUGhYPQZFFPTO6RfEtXxLIq3+a+N X-Received: by 2002:a05:600c:1f84:b0:492:7025:13fd with SMTP id 5b1f17b1804b1-493e0f7a2b7mr1946195e9.0.1783376582805; Mon, 06 Jul 2026 15:23:02 -0700 (PDT) Received: from inspiron14p-linux ([109.77.44.220]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47aa039ad21sm27916413f8f.20.2026.07.06.15.23.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jul 2026 15:23:02 -0700 (PDT) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: bryan.odonoghue@linaro.org, pavel@ucw.cz Subject: [PATCH v6 6/6] libcamera: software_isp: debayer_egl: Implement input/output frame caching mechanism Date: Mon, 6 Jul 2026 23:22:45 +0100 Message-ID: <20260706222245.247396-7-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260706222245.247396-1-bryan.odonoghue@linaro.org> References: <20260706222245.247396-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" Implement a texture caching mechanism for both input and output frames and for both types of input frame. The before/after on a Qualcomm x1e is: 9.737ms per frame 5.691ms per frame The before/after on a Qualcomm sm8250 is: 21.710ms per frame 17.336ms per frame for i in {1..20} do cam -c /base/soc@0/cci@ac16000/i2c-bus@1/camera@10 -s width=1920,height=1080 --capture=60 Interestingly there appears to be an absolute ~ 4.x ms per frame uplift as opposed to what intuition might suggest a proportional. Signed-off-by: Bryan O'Donoghue --- src/libcamera/software_isp/debayer_egl.cpp | 125 ++++++++++++++++----- src/libcamera/software_isp/debayer_egl.h | 10 +- 2 files changed, 104 insertions(+), 31 deletions(-) diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp index c3a7b7952..a7cca5dde 100644 --- a/src/libcamera/software_isp/debayer_egl.cpp +++ b/src/libcamera/software_isp/debayer_egl.cpp @@ -345,6 +345,9 @@ int DebayerEGL::configure(const StreamConfiguration &inputCfg, */ stats_->setWindow(Rectangle(window_.size())); + inputBufferCount_ = inputCfg.bufferCount; + outputBufferCount_ = outputCfg.bufferCount; + return 0; } @@ -504,36 +507,106 @@ void DebayerEGL::setShaderVariableValues(eGLImage &eglImageIn, const DebayerPara return; } -int DebayerEGL::debayerGPU(FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms, std::optional *inMapped, std::optional *inDmaSyncer) +eGLImage *DebayerEGL::getCachedInputFrameBuffer(FrameBuffer *input, std::optional *inMapped, std::optional *inDmaSyncer) { - bool dmabuf_import_succeeded = false; + const SharedFD &fd = input->planes()[0].fd; + bool cache_miss = true; + eGLImage *eglImageIn; + + for (auto &[ifd, img] : eglImageInCache_) { + if (ifd == fd) { + eglImageIn = img.get(); + cache_miss = false; + break; + } + } - /* eGL context switch */ - egl_.makeCurrent(); + if (cache_miss) { + if (eglImageInCache_.size() >= inputBufferCount_) { + eglImageInCache_.pop_front(); + LOG(Debayer, Debug) << "Input cache " << inputBufferCount_ << " exceeded evicted entry"; + } + + eglImageInCache_.emplace_back(fd, std::make_unique(glFormat_, inputConfig_.stride / bytesPerPixel_, height_, inputConfig_.stride, GL_TEXTURE0, 0)); + eglImageIn = eglImageInCache_.back().second.get(); + + if (egl_.createInputDMABufTexture2D(*eglImageIn, input->planes()[0].fd.get()) == 0) + return eglImageIn; + + } else if (!eglImageIn->dmabuf_import_failed_) { + egl_.activateBindTexture(*eglImageIn); + return eglImageIn; + } + + /* DMA mode fail create/update an existing texture using the slow path */ + inDmaSyncer->emplace(input->planes()[0].fd, DmaSyncer::SyncType::Read); + inMapped->emplace(input, MappedFrameBuffer::MapFlag::Read); + if (!inMapped->value().isValid()) { + LOG(Debayer, Error) << "mmap-ing buffer(s) failed"; + if (cache_miss) { + eglImageInCache_.pop_back(); + } + return nullptr; + } + if (cache_miss) + egl_.createTexture2D(*eglImageIn, inMapped->value().planes()[0].data()); + else + egl_.updateTexture2D(*eglImageIn, inMapped->value().planes()[0].data()); + + return eglImageIn; +} - /* Try to create texture for input buffer via dmabuf import */ - if (!eglImageBayerIn_->dmabuf_import_failed_) { - if (egl_.createInputDMABufTexture2D(*eglImageBayerIn_, input->planes()[0].fd.get()) == 0) - dmabuf_import_succeeded = true; - else - LOG(Debayer, Info) << "Importing input buffer with DMABuf import failed, falling back to upload"; +eGLImage *DebayerEGL::getCachedOutputFrameBuffer(FrameBuffer *output) +{ + const SharedFD &fd = output->planes()[0].fd; + bool cache_miss = true; + eGLImage *eglImageOut; + + for (auto &[ifd, img] : eglImageOutCache_) { + if (ifd == fd) { + eglImageOut = img.get(); + cache_miss = false; + break; + } } - /* Otherwise create texture for input buffer via upload from CPU */ - if (!dmabuf_import_succeeded) { - inDmaSyncer->emplace(input->planes()[0].fd, DmaSyncer::SyncType::Read); - inMapped->emplace(input, MappedFrameBuffer::MapFlag::Read); - if (!inMapped->value().isValid()) { - LOG(Debayer, Error) << "mmap-ing buffer(s) failed"; - return -ENODEV; + if (cache_miss) { + if (eglImageOutCache_.size() >= outputBufferCount_) { + eglImageOutCache_.pop_front(); + LOG(Debayer, Debug) << "Output cache " << outputBufferCount_ << " exceeded evicted entry"; + } + + eglImageOutCache_.emplace_back(fd, std::make_unique(GL_RGBA, outputSize_.width, + outputSize_.height, outputConfig_.stride, GL_TEXTURE1, 1)); + eglImageOut = eglImageOutCache_.back().second.get(); + + if (egl_.createOutputDMABufTexture2D(*eglImageOut, output->planes()[0].fd.get())) { + eglImageOutCache_.pop_back(); + return nullptr; } - egl_.createTexture2D(*eglImageBayerIn_, inMapped->value().planes()[0].data()); } - /* Generate the output render framebuffer as render to texture */ - egl_.createOutputDMABufTexture2D(*eglImageBayerOut_, output->planes()[0].fd.get()); + return eglImageOut; +} + +int DebayerEGL::debayerGPU(FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms, std::optional *inMapped, std::optional *inDmaSyncer) +{ + eGLImage *eglImageIn; + eGLImage *eglImageOut; + + /* eGL context switch */ + egl_.makeCurrent(); + + eglImageIn = getCachedInputFrameBuffer(input, inMapped, inDmaSyncer); + if (!eglImageIn) + return -ENOMEM; + eglImageOut = getCachedOutputFrameBuffer(output); + if (!eglImageOut) + return -ENOMEM; + + egl_.attachTextureToFBO(*eglImageOut); + setShaderVariableValues(*eglImageIn, params); - setShaderVariableValues(*eglImageBayerIn_, params); glViewport(0, 0, width_, height_); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLE_FAN, 0, DEBAYER_OPENGL_COORDS); @@ -615,19 +688,13 @@ int DebayerEGL::start() if (initBayerShaders(inputPixelFormat_, outputPixelFormat_)) return -EINVAL; - /* Raw bayer input as texture */ - eglImageBayerIn_ = std::make_unique(glFormat_, inputConfig_.stride / bytesPerPixel_, height_, inputConfig_.stride, GL_TEXTURE0, 0); - - /* Texture we will render to */ - eglImageBayerOut_ = std::make_unique(GL_RGBA, outputSize_.width, outputSize_.height, outputConfig_.stride, GL_TEXTURE1, 1); - return 0; } void DebayerEGL::stop() { - eglImageBayerOut_.reset(); - eglImageBayerIn_.reset(); + eglImageOutCache_.clear(); + eglImageInCache_.clear(); if (programId_) glDeleteProgram(programId_); diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h index 348d7305b..d6223f3a9 100644 --- a/src/libcamera/software_isp/debayer_egl.h +++ b/src/libcamera/software_isp/debayer_egl.h @@ -9,6 +9,7 @@ #pragma once +#include #include #include #include @@ -68,14 +69,19 @@ private: void setShaderVariableValues(eGLImage &eGLImageIn, const DebayerParams ¶ms); int debayerGPU(FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms, std::optional *mappedInputBuffer, std::optional *inputBufferDmaSyncer); + eGLImage *getCachedInputFrameBuffer(FrameBuffer *input, std::optional *inMapped, std::optional *inDmaSyncer); + eGLImage *getCachedOutputFrameBuffer(FrameBuffer *output); + /* Shader program identifiers */ GLuint vertexShaderId_ = 0; GLuint fragmentShaderId_ = 0; GLuint programId_ = 0; /* Pointer to object representing input texture */ - std::unique_ptr eglImageBayerIn_; - std::unique_ptr eglImageBayerOut_; + std::deque>> eglImageInCache_; + std::deque>> eglImageOutCache_; + unsigned int inputBufferCount_; + unsigned int outputBufferCount_; /* Shader parameters */ float firstRed_x_;