1
0
mirror of https://github.com/jojo61/vdr-plugin-softhdcuvid.git synced 2023-10-10 13:37:41 +02:00
vdr-plugin-softhdcuvid/openglosd.h

541 lines
16 KiB
C
Raw Normal View History

2018-09-05 20:39:12 +02:00
#ifndef __SOFTHDDEVICE_OPENGLOSD_H
#define __SOFTHDDEVICE_OPENGLOSD_H
// clang-format off
2018-09-05 20:39:12 +02:00
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/gl.h>
#define GLM_FORCE_RADIANS
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <math.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_LCD_FILTER_H
#include FT_STROKER_H
#undef __FTERRORS_H__
#define FT_ERRORDEF( e, v, s ) { e, s },
#define FT_ERROR_START_LIST {
#define FT_ERROR_END_LIST { 0, 0 } };
const struct
{
int code;
const char *message;
2018-09-05 20:39:12 +02:00
} FT_Errors[] =
#include FT_ERRORS_H
#include <memory>
#include <queue>
#include <vdr/plugin.h>
#include <vdr/osd.h>
#include <vdr/thread.h>
#include "softhddev.h"
extern "C"
{
#include <stdint.h>
#include <libavcodec/avcodec.h>
#include "audio.h"
#include "video.h"
#include "codec.h"
}
// clang-format on
2018-09-05 20:39:12 +02:00
extern "C" pthread_mutex_t OSDMutex;
struct sOglImage {
2018-09-05 20:39:12 +02:00
GLuint texture;
GLint width;
GLint height;
bool used;
};
/****************************************************************************************
* Helpers
****************************************************************************************/
2018-09-05 20:39:12 +02:00
void ConvertColor(const GLint &colARGB, glm::vec4 &col);
2018-09-05 20:39:12 +02:00
/****************************************************************************************
* cShader
****************************************************************************************/
enum eShaderType { stRect, stTexture, stText, stCount };
2018-09-05 20:39:12 +02:00
class cShader {
private:
2018-09-05 20:39:12 +02:00
eShaderType type;
GLuint id;
bool Compile(const char *vertexCode, const char *fragmentCode);
bool CheckCompileErrors(GLuint object, bool program = false);
public:
cShader(void){};
virtual ~cShader(void){};
2018-09-05 20:39:12 +02:00
bool Load(eShaderType type);
void Use(void);
void SetFloat(const GLchar *name, GLfloat value);
void SetInteger(const GLchar *name, GLint value);
void SetVector2f(const GLchar *name, GLfloat x, GLfloat y);
void SetVector3f(const GLchar *name, GLfloat x, GLfloat y, GLfloat z);
void SetVector4f(const GLchar *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void SetMatrix4(const GLchar *name, const glm::mat4 &matrix);
2018-09-05 20:39:12 +02:00
};
/****************************************************************************************
* cOglGlyph
****************************************************************************************/
class cOglGlyph : public cListObject {
private:
struct tKerning {
public:
2020-03-02 16:06:27 +01:00
tKerning(FT_ULong prevSym, GLfloat kerning = 0.0f) {
this->prevSym = prevSym;
this->kerning = kerning;
}
2020-03-02 16:06:27 +01:00
FT_ULong prevSym;
GLfloat kerning;
2018-09-05 20:39:12 +02:00
};
2020-02-26 16:52:48 +01:00
FT_ULong charCode;
2018-09-05 20:39:12 +02:00
int bearingLeft;
int bearingTop;
int width;
int height;
int advanceX;
cVector<tKerning> kerningCache;
2018-09-05 20:39:12 +02:00
GLuint texture;
void LoadTexture(FT_BitmapGlyph ftGlyph);
public:
2020-02-26 16:52:48 +01:00
cOglGlyph(FT_ULong charCode, FT_BitmapGlyph ftGlyph);
virtual ~cOglGlyph();
FT_ULong CharCode(void) { return charCode; }
int AdvanceX(void) { return advanceX; }
int BearingLeft(void) const { return bearingLeft; }
int BearingTop(void) const { return bearingTop; }
int Width(void) const { return width; }
int Height(void) const { return height; }
2020-03-02 16:06:27 +01:00
int GetKerningCache(FT_ULong prevSym);
void SetKerningCache(FT_ULong prevSym, int kerning);
2018-09-05 20:39:12 +02:00
void BindTexture(void);
};
/****************************************************************************************
* cOglFont
****************************************************************************************/
class cOglFont : public cListObject {
private:
2018-09-05 20:39:12 +02:00
static bool initiated;
cString name;
int size;
int height;
int bottom;
static FT_Library ftLib;
FT_Face face;
static cList<cOglFont> *fonts;
mutable cList<cOglGlyph> glyphCache;
cOglFont(const char *fontName, int charHeight);
2018-09-05 20:39:12 +02:00
static void Init(void);
public:
virtual ~cOglFont(void);
2018-09-05 20:39:12 +02:00
static cOglFont *Get(const char *name, int charHeight);
static void Cleanup(void);
const char *Name(void) { return *name; };
int Size(void) { return size; };
int Bottom(void) { return bottom; };
int Height(void) { return height; };
2020-02-26 16:52:48 +01:00
cOglGlyph *Glyph(FT_ULong charCode) const;
int Kerning(cOglGlyph *glyph, FT_ULong prevSym) const;
2018-09-05 20:39:12 +02:00
};
/****************************************************************************************
* cOglFb
* Framebuffer Object - OpenGL part of a Pixmap
****************************************************************************************/
class cOglFb {
protected:
2018-09-05 20:39:12 +02:00
bool initiated;
2019-10-28 21:43:37 +01:00
// GLuint fb;
// GLuint texture;
2018-09-05 20:39:12 +02:00
GLint width, height;
GLint viewPortWidth, viewPortHeight;
bool scrollable;
public:
GLuint fb;
GLuint texture;
cOglFb(GLint width, GLint height, GLint viewPortWidth, GLint viewPortHeight);
virtual ~cOglFb(void);
bool Initiated(void) { return initiated; }
2018-09-05 20:39:12 +02:00
virtual bool Init(void);
void Bind(void);
void BindRead(void);
virtual void BindWrite(void);
virtual void Unbind(void);
bool BindTexture(void);
void Blit(GLint destX1, GLint destY1, GLint destX2, GLint destY2);
GLint Width(void) { return width; };
GLint Height(void) { return height; };
bool Scrollable(void) { return scrollable; };
GLint ViewportWidth(void) { return viewPortWidth; };
GLint ViewportHeight(void) { return viewPortHeight; };
2018-09-05 20:39:12 +02:00
};
/****************************************************************************************
* cOglOutputFb
* Output Framebuffer Object - holds Vdpau Output Surface which is our "output
*framebuffer"
****************************************************************************************/
class cOglOutputFb : public cOglFb {
protected:
2018-10-12 12:51:52 +02:00
bool initiated;
private:
GLvdpauSurfaceNV surface;
public:
GLuint fb;
GLuint texture;
cOglOutputFb(GLint width, GLint height);
virtual ~cOglOutputFb(void);
2018-09-05 20:39:12 +02:00
virtual bool Init(void);
virtual void BindWrite(void);
virtual void Unbind(void);
};
/****************************************************************************************
* cOglVb
* Vertex Buffer - OpenGl Vertices for the different drawing commands
****************************************************************************************/
enum eVertexBufferType { vbRect, vbEllipse, vbSlope, vbTexture, vbText, vbCount };
2018-09-05 20:39:12 +02:00
class cOglVb {
private:
2018-09-05 20:39:12 +02:00
eVertexBufferType type;
eShaderType shader;
GLuint vao;
GLuint vbo;
int sizeVertex1;
int sizeVertex2;
int numVertices;
GLuint drawMode;
public:
cOglVb(int type);
virtual ~cOglVb(void);
2018-09-05 20:39:12 +02:00
bool Init(void);
void Bind(void);
void Unbind(void);
void ActivateShader(void);
void EnableBlending(void);
void DisableBlending(void);
void SetShaderColor(GLint color);
void SetShaderAlpha(GLint alpha);
void SetShaderProjectionMatrix(GLint width, GLint height);
void SetVertexData(GLfloat *vertices, int count = 0);
2018-09-05 20:39:12 +02:00
void DrawArrays(int count = 0);
};
/****************************************************************************************
* cOpenGLCmd
****************************************************************************************/
class cOglCmd {
protected:
cOglFb *fb;
public:
cOglCmd(cOglFb *fb) { this->fb = fb; };
virtual ~cOglCmd(void){};
virtual const char *Description(void) = 0;
2018-09-05 20:39:12 +02:00
virtual bool Execute(void) = 0;
};
class cOglCmdInitOutputFb : public cOglCmd {
private:
cOglOutputFb *oFb;
public:
cOglCmdInitOutputFb(cOglOutputFb *oFb);
virtual ~cOglCmdInitOutputFb(void){};
virtual const char *Description(void) { return "InitOutputFramebuffer"; }
2018-09-05 20:39:12 +02:00
virtual bool Execute(void);
};
class cOglCmdInitFb : public cOglCmd {
private:
cCondWait *wait;
public:
cOglCmdInitFb(cOglFb *fb, cCondWait *wait = NULL);
virtual ~cOglCmdInitFb(void){};
virtual const char *Description(void) { return "InitFramebuffer"; }
2018-09-05 20:39:12 +02:00
virtual bool Execute(void);
};
class cOglCmdDeleteFb : public cOglCmd {
public:
cOglCmdDeleteFb(cOglFb *fb);
virtual ~cOglCmdDeleteFb(void){};
virtual const char *Description(void) { return "DeleteFramebuffer"; }
2018-09-05 20:39:12 +02:00
virtual bool Execute(void);
};
class cOglCmdRenderFbToBufferFb : public cOglCmd {
private:
cOglFb *buffer;
2018-09-05 20:39:12 +02:00
GLfloat x, y;
GLfloat drawPortX, drawPortY;
GLint transparency;
public:
cOglCmdRenderFbToBufferFb(cOglFb *fb, cOglFb *buffer, GLint x, GLint y, GLint transparency, GLint drawPortX,
GLint drawPortY);
virtual ~cOglCmdRenderFbToBufferFb(void){};
virtual const char *Description(void) { return "Render Framebuffer to Buffer"; }
2018-09-05 20:39:12 +02:00
virtual bool Execute(void);
};
class cOglCmdCopyBufferToOutputFb : public cOglCmd {
private:
cOglOutputFb *oFb;
2018-09-05 20:39:12 +02:00
GLint x, y;
public:
cOglCmdCopyBufferToOutputFb(cOglFb *fb, cOglOutputFb *oFb, GLint x, GLint y);
virtual ~cOglCmdCopyBufferToOutputFb(void){};
virtual const char *Description(void) { return "Copy buffer to OutputFramebuffer"; }
2018-09-05 20:39:12 +02:00
virtual bool Execute(void);
};
class cOglCmdFill : public cOglCmd {
private:
2018-09-05 20:39:12 +02:00
GLint color;
public:
cOglCmdFill(cOglFb *fb, GLint color);
virtual ~cOglCmdFill(void){};
virtual const char *Description(void) { return "Fill"; }
2018-09-05 20:39:12 +02:00
virtual bool Execute(void);
};
class cOglCmdDrawRectangle : public cOglCmd {
private:
2018-09-05 20:39:12 +02:00
GLint x, y;
GLint width, height;
GLint color;
public:
cOglCmdDrawRectangle(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color);
virtual ~cOglCmdDrawRectangle(void){};
virtual const char *Description(void) { return "DrawRectangle"; }
2018-09-05 20:39:12 +02:00
virtual bool Execute(void);
};
class cOglCmdDrawEllipse : public cOglCmd {
private:
2018-09-05 20:39:12 +02:00
GLint x, y;
GLint width, height;
GLint color;
GLint quadrants;
GLfloat *CreateVerticesFull(int &numVertices);
GLfloat *CreateVerticesQuadrant(int &numVertices);
GLfloat *CreateVerticesHalf(int &numVertices);
public:
cOglCmdDrawEllipse(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint quadrants);
virtual ~cOglCmdDrawEllipse(void){};
virtual const char *Description(void) { return "DrawEllipse"; }
2018-09-05 20:39:12 +02:00
virtual bool Execute(void);
};
class cOglCmdDrawSlope : public cOglCmd {
private:
2018-09-05 20:39:12 +02:00
GLint x, y;
GLint width, height;
GLint color;
GLint type;
public:
cOglCmdDrawSlope(cOglFb *fb, GLint x, GLint y, GLint width, GLint height, GLint color, GLint type);
virtual ~cOglCmdDrawSlope(void){};
virtual const char *Description(void) { return "DrawSlope"; }
2018-09-05 20:39:12 +02:00
virtual bool Execute(void);
};
class cOglCmdDrawText : public cOglCmd {
private:
2018-09-05 20:39:12 +02:00
GLint x, y;
GLint limitX;
GLint colorText;
cString fontName;
int fontSize;
unsigned int *symbols;
public:
cOglCmdDrawText(cOglFb *fb, GLint x, GLint y, unsigned int *symbols, GLint limitX, const char *name, int fontSize,
tColor colorText);
virtual ~cOglCmdDrawText(void);
virtual const char *Description(void) { return "DrawText"; }
2018-09-05 20:39:12 +02:00
virtual bool Execute(void);
};
class cOglCmdDrawImage : public cOglCmd {
private:
tColor *argb;
2018-09-05 20:39:12 +02:00
GLint x, y, width, height;
bool overlay;
GLfloat scaleX, scaleY;
public:
cOglCmdDrawImage(cOglFb *fb, tColor *argb, GLint width, GLint height, GLint x, GLint y, bool overlay = true,
double scaleX = 1.0f, double scaleY = 1.0f);
virtual ~cOglCmdDrawImage(void);
virtual const char *Description(void) { return "Draw Image"; }
2018-09-05 20:39:12 +02:00
virtual bool Execute(void);
};
class cOglCmdDrawTexture : public cOglCmd {
private:
sOglImage *imageRef;
2018-09-05 20:39:12 +02:00
GLint x, y;
public:
cOglCmdDrawTexture(cOglFb *fb, sOglImage *imageRef, GLint x, GLint y);
virtual ~cOglCmdDrawTexture(void){};
virtual const char *Description(void) { return "Draw Texture"; }
2018-09-05 20:39:12 +02:00
virtual bool Execute(void);
};
class cOglCmdStoreImage : public cOglCmd {
private:
sOglImage *imageRef;
2018-09-05 20:39:12 +02:00
tColor *data;
public:
cOglCmdStoreImage(sOglImage *imageRef, tColor *argb);
virtual ~cOglCmdStoreImage(void);
virtual const char *Description(void) { return "Store Image"; }
2018-09-05 20:39:12 +02:00
virtual bool Execute(void);
};
class cOglCmdDropImage : public cOglCmd {
private:
sOglImage *imageRef;
2018-09-05 20:39:12 +02:00
cCondWait *wait;
public:
cOglCmdDropImage(sOglImage *imageRef, cCondWait *wait);
virtual ~cOglCmdDropImage(void){};
virtual const char *Description(void) { return "Drop Image"; }
2018-09-05 20:39:12 +02:00
virtual bool Execute(void);
};
/******************************************************************************
* cOglThread
******************************************************************************/
2018-09-05 20:39:12 +02:00
#define OGL_MAX_OSDIMAGES 256
#define OGL_CMDQUEUE_SIZE 100
class cOglThread : public cThread {
private:
cCondWait *startWait;
2018-09-05 20:39:12 +02:00
cCondWait *wait;
bool stalled;
std::queue<cOglCmd *> commands;
2018-09-05 20:39:12 +02:00
GLint maxTextureSize;
sOglImage imageCache[OGL_MAX_OSDIMAGES];
long memCached;
long maxCacheSize;
bool InitOpenGL(void);
bool InitShaders(void);
void DeleteShaders(void);
bool InitVdpauInterop(void);
bool InitVertexBuffers(void);
void DeleteVertexBuffers(void);
void Cleanup(void);
int GetFreeSlot(void);
void ClearSlot(int slot);
protected:
virtual void Action(void);
public:
cOglThread(cCondWait *startWait, int maxCacheSize);
virtual ~cOglThread();
2018-09-05 20:39:12 +02:00
void Stop(void);
void DoCmd(cOglCmd *cmd);
int StoreImage(const cImage &image);
2018-09-05 20:39:12 +02:00
void DropImageData(int imageHandle);
sOglImage *GetImageRef(int slot);
int MaxTextureSize(void) { return maxTextureSize; };
2018-09-05 20:39:12 +02:00
};
/****************************************************************************************
* cOglPixmap
****************************************************************************************/
class cOglPixmap : public cPixmap {
private:
cOglFb *fb;
std::shared_ptr<cOglThread> oglThread;
2018-09-05 20:39:12 +02:00
bool dirty;
public:
cOglPixmap(std::shared_ptr<cOglThread> oglThread, int Layer, const cRect &ViewPort,
const cRect &DrawPort = cRect::Null);
virtual ~cOglPixmap(void);
cOglFb *Fb(void) { return fb; };
int X(void) { return ViewPort().X(); };
int Y(void) { return ViewPort().Y(); };
virtual bool IsDirty(void) { return dirty; }
virtual void SetDirty(bool dirty = true) { this->dirty = dirty; }
2018-09-05 20:39:12 +02:00
virtual void SetAlpha(int Alpha);
virtual void SetTile(bool Tile);
virtual void SetViewPort(const cRect &Rect);
virtual void SetDrawPortPoint(const cPoint &Point, bool Dirty = true);
2018-09-05 20:39:12 +02:00
virtual void Clear(void);
virtual void Fill(tColor Color);
virtual void DrawImage(const cPoint &Point, const cImage &Image);
virtual void DrawImage(const cPoint &Point, int ImageHandle);
virtual void DrawPixel(const cPoint &Point, tColor Color);
virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0,
bool Overlay = false);
virtual void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font,
int Width = 0, int Height = 0, int Alignment = taDefault);
virtual void DrawRectangle(const cRect &Rect, tColor Color);
virtual void DrawEllipse(const cRect &Rect, tColor Color, int Quadrants = 0);
virtual void DrawSlope(const cRect &Rect, tColor Color, int Type);
virtual void Render(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest);
virtual void Copy(const cPixmap *Pixmap, const cRect &Source, const cPoint &Dest);
virtual void Scroll(const cPoint &Dest, const cRect &Source = cRect::Null);
virtual void Pan(const cPoint &Dest, const cRect &Source = cRect::Null);
2018-09-05 20:39:12 +02:00
};
/******************************************************************************
* cOglOsd
******************************************************************************/
class cOglOsd : public cOsd {
private:
cOglFb *bFb;
std::shared_ptr<cOglThread> oglThread;
cVector<cOglPixmap *> oglPixmaps;
2018-09-05 20:39:12 +02:00
bool isSubtitleOsd;
protected:
public:
cOglOsd(int Left, int Top, uint Level, std::shared_ptr<cOglThread> oglThread);
virtual ~cOglOsd();
virtual eOsdError SetAreas(const tArea *Areas, int NumAreas);
virtual cPixmap *CreatePixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null);
virtual void DestroyPixmap(cPixmap *Pixmap);
2018-09-05 20:39:12 +02:00
virtual void Flush(void);
virtual void DrawScaledBitmap(int x, int y, const cBitmap &Bitmap, double FactorX, double FactorY,
bool AntiAlias = false);
2018-09-05 20:39:12 +02:00
static cOglOutputFb *oFb;
};
#endif //__SOFTHDDEVICE_OPENGLOSD_H