libcamera: software_isp: egl: Introduce an eGL base helper class

Introduce an eGL base helper class which provides an eGL context based on a
passed width and height.

The initGLContext function could be overloaded to provide an interface to a
real display.

A set of helper functions is provided to compile and link GLSL shaders.
linkShaderProgram currently compiles vertex/fragment pairs but could be
overloaded or passed a parameter to link a compute shader instead.

Breaking the eGL interface away from debayering - allows to use the eGL
context inside of a dma-buf heap cleanly, reuse that context inside of a
debayer layer and conceivably reuse the context in a multi-stage shader
pass.

Small note the image_attrs[] array doesn't pass checkstyle.py however the
elements of the array are in pairs.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
This commit is contained in:
Bryan O'Donoghue 2024-02-25 16:23:26 +00:00
parent 234849b2b9
commit 94f30456aa
3 changed files with 502 additions and 0 deletions

View file

@ -0,0 +1,110 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2024, Linaro Ltd.
*
* Authors:
* Bryan O'Donoghue <bryan.odonoghue@linaro.org>
*
* egl_context.cpp - Helper class for managing eGL interactions.
*/
#pragma once
#include <unistd.h>
#include <libcamera/base/log.h>
#include "libcamera/internal/gbm.h"
#define EGL_EGLEXT_PROTOTYPES
#include <EGL/egl.h>
#include <EGL/eglext.h>
#define GL_GLEXT_PROTOTYPES
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
namespace libcamera {
LOG_DECLARE_CATEGORY(eGL)
class eGLImage
{
public:
eGLImage(uint32_t width, uint32_t height, uint32_t bpp, GLenum texture_unit, uint32_t texture_unit_uniform_id)
{
image_ = EGL_NO_IMAGE_KHR;
width_ = width;
height_ = height;
bpp_ = bpp;
stride_ = width_ * bpp_ / 4;
framesize_ = stride_ * height_;
texture_unit_ = texture_unit;
texture_unit_uniform_id_ = texture_unit_uniform_id;
glGenTextures(1, &texture_);
}
~eGLImage()
{
glDeleteTextures(1, &texture_);
}
uint32_t width_;
uint32_t height_;
uint32_t stride_;
uint32_t offset_;
uint32_t framesize_;
uint32_t bpp_;
uint32_t texture_unit_uniform_id_;
GLenum texture_unit_;
GLuint texture_;
EGLImageKHR image_;
};
class eGL
{
public:
eGL();
~eGL();
int initEGLContext(GBM *gbmContext);
int createDMABufTexture2D(eGLImage *eglImage, int fd);
void destroyDMABufTexture(eGLImage *eglImage);
void createTexture2D(eGLImage *eglImage, GLint format, uint32_t width, uint32_t height, void *data);
void createTexture1D(eGLImage *eglImage, GLint format, uint32_t width, void *data);
void pushEnv(std::vector<std::string> &shaderEnv, const char *str);
void makeCurrent();
void swapBuffers();
int compileVertexShader(GLuint &shaderId, unsigned char *shaderData,
unsigned int shaderDataLen,
std::vector<std::string> shaderEnv);
int compileFragmentShader(GLuint &shaderId, unsigned char *shaderData,
unsigned int shaderDataLen,
std::vector<std::string> shaderEnv);
int linkProgram(GLuint &programIdd, GLuint fragmentshaderId, GLuint vertexshaderId);
void dumpShaderSource(GLuint shaderId);
void useProgram(GLuint programId);
private:
int fd_;
EGLDisplay display_;
EGLContext context_;
EGLSurface surface_;
int compileShader(int shaderType, GLuint &shaderId, unsigned char *shaderData,
unsigned int shaderDataLen,
std::vector<std::string> shaderEnv);
PFNEGLEXPORTDMABUFIMAGEMESAPROC eglExportDMABUFImageMESA;
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR;
PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR;
PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncKHR;
PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR;
};
} //namespace libcamera