[06/10] libcamera: egl: Add updateInputTexture2D
diff mbox series

Message ID 20260624085849.873784-7-bryan.odonoghue@linaro.org
State New
Headers show
Series
  • libcamera: software_isp: gpu: Add go faster stripes
Related show

Commit Message

Bryan O'Donoghue June 24, 2026, 8:58 a.m. UTC
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.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 include/libcamera/internal/egl.h           |  1 +
 src/libcamera/egl.cpp                      | 34 ++++++++++++++++++++++
 src/libcamera/software_isp/debayer_egl.cpp |  2 +-
 3 files changed, 36 insertions(+), 1 deletion(-)

Comments

Robert Mader June 24, 2026, 12:14 p.m. UTC | #1
On 24.06.26 10:58, Bryan O'Donoghue wrote:
> 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.
>
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>   include/libcamera/internal/egl.h           |  1 +
>   src/libcamera/egl.cpp                      | 34 ++++++++++++++++++++++
>   src/libcamera/software_isp/debayer_egl.cpp |  2 +-
>   3 files changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h
> index b992baf25..f1fa75d96 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 createInputTexture2D(eGLImage &eglImage, void *data);
> +	void updateInputTexture2D(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 123653b58..6134b05f9 100644
> --- a/src/libcamera/egl.cpp
> +++ b/src/libcamera/egl.cpp
> @@ -345,6 +345,40 @@ 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::updateInputTexture2D(eGLImage &eglImage, void *data)
> +{
> +	GLenum format;
> +	GLenum type = GL_UNSIGNED_BYTE;
> +
> +	ASSERT(tid_ == Thread::currentId());
> +
> +	glActiveTexture(eglImage.texture_unit_);
> +	glBindTexture(GL_TEXTURE_2D, eglImage.texture_);
This one looks like it should get replaced in the next commit but 
doesn't. Might want to switch those commits around and use 
activateBindTexture() here.
> +
> +	switch (eglImage.format_) {
> +	case GL_R16F:
> +		format = GL_RED;
> +		type = GL_HALF_FLOAT;
As mentioned previously I'd kinda prefer to keep the float parts to the 
mult-pass series.
> +		break;
> +	case GL_RG8:
> +		format = GL_RG;
> +		break;
> +	case GL_LUMINANCE:
> +		format = GL_LUMINANCE;
> +		break;
> +	}
> +
> +	// Update an already exsiting texture
> +	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, eglImage.width_, eglImage.height_, format, type, data);
Yep, that seems to match what Weston and Mutter do AFAICT.
> +}
> +
>   /**
>    * \brief Create a 2D texture attached to an FBO for render-to-texture
>    * \param[in,out] eglImage EGL image to associate with the texture
> diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp
> index 0ec2a98cf..cdceacf96 100644
> --- a/src/libcamera/software_isp/debayer_egl.cpp
> +++ b/src/libcamera/software_isp/debayer_egl.cpp
> @@ -536,7 +536,7 @@ int DebayerEGL::debayerGPU(FrameBuffer *input, FrameBuffer *output, const Debaye
>   			LOG(Debayer, Error) << "mmap-ing buffer(s) failed";
>   			return -ENODEV;
>   		}
> -		egl_.createTexture2D(*eglImageBayerIn_, inMapped->value().planes()[0].data());
> +		egl_.createInputTexture2D(*eglImageBayerIn_, inMapped->value().planes()[0].data());

This looks like it went to the wrong commit.

With at least this one fixed:

Reviewed-by: Robert Mader <robert.mader@collabora.com>

>   	}
>   
>   	/* Generate the output render framebuffer as render to texture */

Patch
diff mbox series

diff --git a/include/libcamera/internal/egl.h b/include/libcamera/internal/egl.h
index b992baf25..f1fa75d96 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 createInputTexture2D(eGLImage &eglImage, void *data);
+	void updateInputTexture2D(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 123653b58..6134b05f9 100644
--- a/src/libcamera/egl.cpp
+++ b/src/libcamera/egl.cpp
@@ -345,6 +345,40 @@  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::updateInputTexture2D(eGLImage &eglImage, void *data)
+{
+	GLenum format;
+	GLenum type = GL_UNSIGNED_BYTE;
+
+	ASSERT(tid_ == Thread::currentId());
+
+	glActiveTexture(eglImage.texture_unit_);
+	glBindTexture(GL_TEXTURE_2D, eglImage.texture_);
+
+	switch (eglImage.format_) {
+	case GL_R16F:
+		format = GL_RED;
+		type = GL_HALF_FLOAT;
+		break;
+	case GL_RG8:
+		format = GL_RG;
+		break;
+	case GL_LUMINANCE:
+		format = GL_LUMINANCE;
+		break;
+	}
+
+	// Update an already exsiting texture
+	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, eglImage.width_, eglImage.height_, format, type, 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
diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp
index 0ec2a98cf..cdceacf96 100644
--- a/src/libcamera/software_isp/debayer_egl.cpp
+++ b/src/libcamera/software_isp/debayer_egl.cpp
@@ -536,7 +536,7 @@  int DebayerEGL::debayerGPU(FrameBuffer *input, FrameBuffer *output, const Debaye
 			LOG(Debayer, Error) << "mmap-ing buffer(s) failed";
 			return -ENODEV;
 		}
-		egl_.createTexture2D(*eglImageBayerIn_, inMapped->value().planes()[0].data());
+		egl_.createInputTexture2D(*eglImageBayerIn_, inMapped->value().planes()[0].data());
 	}
 
 	/* Generate the output render framebuffer as render to texture */