mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-01-10 22:33:58 +00:00
[client] egl: rework egl to accomodate post-processing filtering
This commit is contained in:
parent
30ad28ffd1
commit
86d6b67337
21 changed files with 793 additions and 183 deletions
|
@ -80,11 +80,11 @@ struct EGL_Cursor
|
||||||
struct EGL_Model * model;
|
struct EGL_Model * model;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool egl_cursor_tex_init(struct CursorTex * t,
|
static bool cursorTexInit(EGL * egl, struct CursorTex * t,
|
||||||
const char * vertex_code , size_t vertex_size,
|
const char * vertex_code , size_t vertex_size,
|
||||||
const char * fragment_code, size_t fragment_size)
|
const char * fragment_code, size_t fragment_size)
|
||||||
{
|
{
|
||||||
if (!egl_textureInit(&t->texture, NULL, EGL_TEXTYPE_BUFFER, false))
|
if (!egl_textureInit(egl, &t->texture, NULL, EGL_TEXTYPE_BUFFER, false))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to initialize the cursor texture");
|
DEBUG_ERROR("Failed to initialize the cursor texture");
|
||||||
return false;
|
return false;
|
||||||
|
@ -110,8 +110,8 @@ static bool egl_cursor_tex_init(struct CursorTex * t,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void egl_cursor_tex_uniforms(EGL_Cursor * cursor, struct CursorTex * t,
|
static inline void setCursorTexUniforms(EGL_Cursor * cursor,
|
||||||
bool mono, float x, float y, float w, float h)
|
struct CursorTex * t, bool mono, float x, float y, float w, float h)
|
||||||
{
|
{
|
||||||
if (mono)
|
if (mono)
|
||||||
{
|
{
|
||||||
|
@ -127,13 +127,13 @@ static inline void egl_cursor_tex_uniforms(EGL_Cursor * cursor, struct CursorTex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void egl_cursor_tex_free(struct CursorTex * t)
|
static void cursorTexFree(struct CursorTex * t)
|
||||||
{
|
{
|
||||||
egl_textureFree(&t->texture);
|
egl_textureFree(&t->texture);
|
||||||
egl_shaderFree (&t->shader );
|
egl_shaderFree (&t->shader );
|
||||||
};
|
};
|
||||||
|
|
||||||
bool egl_cursorInit(EGL_Cursor ** cursor)
|
bool egl_cursorInit(EGL * egl, EGL_Cursor ** cursor)
|
||||||
{
|
{
|
||||||
*cursor = (EGL_Cursor *)malloc(sizeof(EGL_Cursor));
|
*cursor = (EGL_Cursor *)malloc(sizeof(EGL_Cursor));
|
||||||
if (!*cursor)
|
if (!*cursor)
|
||||||
|
@ -145,12 +145,12 @@ bool egl_cursorInit(EGL_Cursor ** cursor)
|
||||||
memset(*cursor, 0, sizeof(EGL_Cursor));
|
memset(*cursor, 0, sizeof(EGL_Cursor));
|
||||||
LG_LOCK_INIT((*cursor)->lock);
|
LG_LOCK_INIT((*cursor)->lock);
|
||||||
|
|
||||||
if (!egl_cursor_tex_init(&(*cursor)->norm,
|
if (!cursorTexInit(egl, &(*cursor)->norm,
|
||||||
b_shader_cursor_vert , b_shader_cursor_vert_size,
|
b_shader_cursor_vert , b_shader_cursor_vert_size,
|
||||||
b_shader_cursor_rgb_frag, b_shader_cursor_rgb_frag_size))
|
b_shader_cursor_rgb_frag, b_shader_cursor_rgb_frag_size))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!egl_cursor_tex_init(&(*cursor)->mono,
|
if (!cursorTexInit(egl, &(*cursor)->mono,
|
||||||
b_shader_cursor_vert , b_shader_cursor_vert_size,
|
b_shader_cursor_vert , b_shader_cursor_vert_size,
|
||||||
b_shader_cursor_mono_frag, b_shader_cursor_mono_frag_size))
|
b_shader_cursor_mono_frag, b_shader_cursor_mono_frag_size))
|
||||||
return false;
|
return false;
|
||||||
|
@ -161,7 +161,7 @@ bool egl_cursorInit(EGL_Cursor ** cursor)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
egl_modelSetDefault((*cursor)->model);
|
egl_modelSetDefault((*cursor)->model, true);
|
||||||
|
|
||||||
(*cursor)->cbMode = option_get_int("egl", "cbMode");
|
(*cursor)->cbMode = option_get_int("egl", "cbMode");
|
||||||
|
|
||||||
|
@ -182,8 +182,8 @@ void egl_cursorFree(EGL_Cursor ** cursor)
|
||||||
if ((*cursor)->data)
|
if ((*cursor)->data)
|
||||||
free((*cursor)->data);
|
free((*cursor)->data);
|
||||||
|
|
||||||
egl_cursor_tex_free(&(*cursor)->norm);
|
cursorTexFree(&(*cursor)->norm);
|
||||||
egl_cursor_tex_free(&(*cursor)->mono);
|
cursorTexFree(&(*cursor)->mono);
|
||||||
egl_modelFree(&(*cursor)->model);
|
egl_modelFree(&(*cursor)->model);
|
||||||
|
|
||||||
free(*cursor);
|
free(*cursor);
|
||||||
|
@ -342,13 +342,13 @@ struct CursorState egl_cursorRender(EGL_Cursor * cursor,
|
||||||
case LG_CURSOR_MONOCHROME:
|
case LG_CURSOR_MONOCHROME:
|
||||||
{
|
{
|
||||||
egl_shaderUse(cursor->norm.shader);
|
egl_shaderUse(cursor->norm.shader);
|
||||||
egl_cursor_tex_uniforms(cursor, &cursor->norm, true, pos.x, pos.y, size.w, size.h);
|
setCursorTexUniforms(cursor, &cursor->norm, true, pos.x, pos.y, size.w, size.h);
|
||||||
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
|
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
|
||||||
egl_modelSetTexture(cursor->model, cursor->norm.texture);
|
egl_modelSetTexture(cursor->model, cursor->norm.texture);
|
||||||
egl_modelRender(cursor->model);
|
egl_modelRender(cursor->model);
|
||||||
|
|
||||||
egl_shaderUse(cursor->mono.shader);
|
egl_shaderUse(cursor->mono.shader);
|
||||||
egl_cursor_tex_uniforms(cursor, &cursor->mono, true, pos.x, pos.y, size.w, size.h);
|
setCursorTexUniforms(cursor, &cursor->mono, true, pos.x, pos.y, size.w, size.h);
|
||||||
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
|
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
|
||||||
egl_modelSetTexture(cursor->model, cursor->mono.texture);
|
egl_modelSetTexture(cursor->model, cursor->mono.texture);
|
||||||
egl_modelRender(cursor->model);
|
egl_modelRender(cursor->model);
|
||||||
|
@ -358,7 +358,7 @@ struct CursorState egl_cursorRender(EGL_Cursor * cursor,
|
||||||
case LG_CURSOR_COLOR:
|
case LG_CURSOR_COLOR:
|
||||||
{
|
{
|
||||||
egl_shaderUse(cursor->norm.shader);
|
egl_shaderUse(cursor->norm.shader);
|
||||||
egl_cursor_tex_uniforms(cursor, &cursor->norm, false, pos.x, pos.y, size.w, size.h);
|
setCursorTexUniforms(cursor, &cursor->norm, false, pos.x, pos.y, size.w, size.h);
|
||||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
egl_modelRender(cursor->model);
|
egl_modelRender(cursor->model);
|
||||||
break;
|
break;
|
||||||
|
@ -367,7 +367,7 @@ struct CursorState egl_cursorRender(EGL_Cursor * cursor,
|
||||||
case LG_CURSOR_MASKED_COLOR:
|
case LG_CURSOR_MASKED_COLOR:
|
||||||
{
|
{
|
||||||
egl_shaderUse(cursor->mono.shader);
|
egl_shaderUse(cursor->mono.shader);
|
||||||
egl_cursor_tex_uniforms(cursor, &cursor->mono, false, pos.x, pos.y, size.w, size.h);
|
setCursorTexUniforms(cursor, &cursor->mono, false, pos.x, pos.y, size.w, size.h);
|
||||||
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
|
glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
|
||||||
egl_modelRender(cursor->model);
|
egl_modelRender(cursor->model);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "egl.h"
|
||||||
#include "interface/renderer.h"
|
#include "interface/renderer.h"
|
||||||
|
|
||||||
typedef struct EGL_Cursor EGL_Cursor;
|
typedef struct EGL_Cursor EGL_Cursor;
|
||||||
|
@ -31,7 +32,7 @@ struct CursorState {
|
||||||
struct Rect rect;
|
struct Rect rect;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool egl_cursorInit(EGL_Cursor ** cursor);
|
bool egl_cursorInit(EGL * egl, EGL_Cursor ** cursor);
|
||||||
void egl_cursorFree(EGL_Cursor ** cursor);
|
void egl_cursorFree(EGL_Cursor ** cursor);
|
||||||
|
|
||||||
bool egl_cursorSetShape(
|
bool egl_cursorSetShape(
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/option.h"
|
#include "common/option.h"
|
||||||
#include "common/locking.h"
|
#include "common/locking.h"
|
||||||
|
#include "common/array.h"
|
||||||
|
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
@ -33,6 +34,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
// these headers are auto generated by cmake
|
// these headers are auto generated by cmake
|
||||||
|
#include "null.vert.h"
|
||||||
|
#include "null.frag.h"
|
||||||
#include "desktop.vert.h"
|
#include "desktop.vert.h"
|
||||||
#include "desktop_rgb.frag.h"
|
#include "desktop_rgb.frag.h"
|
||||||
#include "desktop_rgb.def.h"
|
#include "desktop_rgb.def.h"
|
||||||
|
@ -41,28 +44,26 @@ struct DesktopShader
|
||||||
{
|
{
|
||||||
EGL_Shader * shader;
|
EGL_Shader * shader;
|
||||||
GLint uTransform;
|
GLint uTransform;
|
||||||
GLint uUVScale;
|
|
||||||
GLint uDesktopSize;
|
GLint uDesktopSize;
|
||||||
GLint uScaleAlgo;
|
GLint uScaleAlgo;
|
||||||
GLint uNV, uNVGain;
|
GLint uNVGain;
|
||||||
GLint uCBMode;
|
GLint uCBMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EGL_Desktop
|
struct EGL_Desktop
|
||||||
{
|
{
|
||||||
|
EGL * egl;
|
||||||
EGLDisplay * display;
|
EGLDisplay * display;
|
||||||
|
|
||||||
EGL_Texture * texture;
|
EGL_Texture * texture;
|
||||||
struct DesktopShader * shader; // the active shader
|
struct DesktopShader shader;
|
||||||
EGL_DesktopRects * mesh;
|
EGL_DesktopRects * mesh;
|
||||||
|
CountedBuffer * matrix;
|
||||||
|
|
||||||
// internals
|
// internals
|
||||||
int width, height;
|
int width, height;
|
||||||
LG_RendererRotate rotate;
|
LG_RendererRotate rotate;
|
||||||
|
|
||||||
// shader instances
|
|
||||||
struct DesktopShader shader_generic;
|
|
||||||
|
|
||||||
// scale algorithm
|
// scale algorithm
|
||||||
int scaleAlgo;
|
int scaleAlgo;
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ struct EGL_Desktop
|
||||||
// forwards
|
// forwards
|
||||||
void egl_desktop_toggle_nv(int key, void * opaque);
|
void egl_desktop_toggle_nv(int key, void * opaque);
|
||||||
|
|
||||||
static bool egl_init_desktop_shader(
|
static bool egl_initDesktopShader(
|
||||||
struct DesktopShader * shader,
|
struct DesktopShader * shader,
|
||||||
const char * vertex_code , size_t vertex_size,
|
const char * vertex_code , size_t vertex_size,
|
||||||
const char * fragment_code, size_t fragment_size
|
const char * fragment_code, size_t fragment_size
|
||||||
|
@ -96,40 +97,37 @@ static bool egl_init_desktop_shader(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
egl_shaderAssocTextures(shader->shader, 1);
|
|
||||||
|
|
||||||
shader->uTransform = egl_shaderGetUniform(shader->shader, "transform");
|
shader->uTransform = egl_shaderGetUniform(shader->shader, "transform");
|
||||||
shader->uUVScale = egl_shaderGetUniform(shader->shader, "uvScale" );
|
|
||||||
shader->uDesktopSize = egl_shaderGetUniform(shader->shader, "size" );
|
shader->uDesktopSize = egl_shaderGetUniform(shader->shader, "size" );
|
||||||
shader->uScaleAlgo = egl_shaderGetUniform(shader->shader, "scaleAlgo");
|
shader->uScaleAlgo = egl_shaderGetUniform(shader->shader, "scaleAlgo");
|
||||||
shader->uNV = egl_shaderGetUniform(shader->shader, "nv" );
|
|
||||||
shader->uNVGain = egl_shaderGetUniform(shader->shader, "nvGain" );
|
shader->uNVGain = egl_shaderGetUniform(shader->shader, "nvGain" );
|
||||||
shader->uCBMode = egl_shaderGetUniform(shader->shader, "cbMode" );
|
shader->uCBMode = egl_shaderGetUniform(shader->shader, "cbMode" );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool egl_desktopInit(EGL_Desktop ** desktop, EGLDisplay * display, bool useDMA, int maxRects)
|
bool egl_desktopInit(EGL * egl, EGL_Desktop ** desktop, EGLDisplay * display,
|
||||||
|
bool useDMA, int maxRects)
|
||||||
{
|
{
|
||||||
*desktop = (EGL_Desktop *)malloc(sizeof(EGL_Desktop));
|
*desktop = (EGL_Desktop *)calloc(1, sizeof(EGL_Desktop));
|
||||||
if (!*desktop)
|
if (!*desktop)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to malloc EGL_Desktop");
|
DEBUG_ERROR("Failed to malloc EGL_Desktop");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(*desktop, 0, sizeof(EGL_Desktop));
|
(*desktop)->egl = egl;
|
||||||
(*desktop)->display = display;
|
(*desktop)->display = display;
|
||||||
|
|
||||||
if (!egl_textureInit(&(*desktop)->texture, display,
|
if (!egl_textureInit(egl, &(*desktop)->texture, display,
|
||||||
useDMA ? EGL_TEXTYPE_DMABUF : EGL_TEXTYPE_FRAMEBUFFER, true))
|
useDMA ? EGL_TEXTYPE_DMABUF : EGL_TEXTYPE_FRAMEBUFFER, true))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to initialize the desktop texture");
|
DEBUG_ERROR("Failed to initialize the desktop texture");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!egl_init_desktop_shader(
|
if (!egl_initDesktopShader(
|
||||||
&(*desktop)->shader_generic,
|
&(*desktop)->shader,
|
||||||
b_shader_desktop_vert , b_shader_desktop_vert_size,
|
b_shader_desktop_vert , b_shader_desktop_vert_size,
|
||||||
b_shader_desktop_rgb_frag, b_shader_desktop_rgb_frag_size))
|
b_shader_desktop_rgb_frag, b_shader_desktop_rgb_frag_size))
|
||||||
{
|
{
|
||||||
|
@ -143,6 +141,13 @@ bool egl_desktopInit(EGL_Desktop ** desktop, EGLDisplay * display, bool useDMA,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(*desktop)->matrix = countedBufferNew(6 * sizeof(GLfloat));
|
||||||
|
if (!(*desktop)->matrix)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to allocate the desktop matrix buffer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
app_registerKeybind(KEY_N, egl_desktop_toggle_nv, *desktop, "Toggle night vision mode");
|
app_registerKeybind(KEY_N, egl_desktop_toggle_nv, *desktop, "Toggle night vision mode");
|
||||||
|
|
||||||
(*desktop)->nvMax = option_get_int("egl", "nvGainMax");
|
(*desktop)->nvMax = option_get_int("egl", "nvGainMax");
|
||||||
|
@ -181,9 +186,10 @@ void egl_desktopFree(EGL_Desktop ** desktop)
|
||||||
if (!*desktop)
|
if (!*desktop)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
egl_textureFree (&(*desktop)->texture );
|
egl_textureFree (&(*desktop)->texture );
|
||||||
egl_shaderFree (&(*desktop)->shader_generic.shader);
|
egl_shaderFree (&(*desktop)->shader.shader);
|
||||||
egl_desktopRectsFree(&(*desktop)->mesh );
|
egl_desktopRectsFree(&(*desktop)->mesh );
|
||||||
|
countedBufferRelease(&(*desktop)->matrix );
|
||||||
|
|
||||||
free(*desktop);
|
free(*desktop);
|
||||||
*desktop = NULL;
|
*desktop = NULL;
|
||||||
|
@ -237,22 +243,18 @@ bool egl_desktopSetup(EGL_Desktop * desktop, const LG_RendererFormat format)
|
||||||
{
|
{
|
||||||
case FRAME_TYPE_BGRA:
|
case FRAME_TYPE_BGRA:
|
||||||
pixFmt = EGL_PF_BGRA;
|
pixFmt = EGL_PF_BGRA;
|
||||||
desktop->shader = &desktop->shader_generic;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FRAME_TYPE_RGBA:
|
case FRAME_TYPE_RGBA:
|
||||||
pixFmt = EGL_PF_RGBA;
|
pixFmt = EGL_PF_RGBA;
|
||||||
desktop->shader = &desktop->shader_generic;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FRAME_TYPE_RGBA10:
|
case FRAME_TYPE_RGBA10:
|
||||||
pixFmt = EGL_PF_RGBA10;
|
pixFmt = EGL_PF_RGBA10;
|
||||||
desktop->shader = &desktop->shader_generic;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FRAME_TYPE_RGBA16F:
|
case FRAME_TYPE_RGBA16F:
|
||||||
pixFmt = EGL_PF_RGBA16F;
|
pixFmt = EGL_PF_RGBA16F;
|
||||||
desktop->shader = &desktop->shader_generic;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -290,7 +292,8 @@ bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame, int dm
|
||||||
desktop->useDMA = false;
|
desktop->useDMA = false;
|
||||||
|
|
||||||
egl_textureFree(&desktop->texture);
|
egl_textureFree(&desktop->texture);
|
||||||
if (!egl_textureInit(&desktop->texture, desktop->display, EGL_TEXTYPE_FRAMEBUFFER, true))
|
if (!egl_textureInit(desktop->egl, &desktop->texture, desktop->display,
|
||||||
|
EGL_TEXTYPE_FRAMEBUFFER, true))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to initialize the desktop texture");
|
DEBUG_ERROR("Failed to initialize the desktop texture");
|
||||||
return false;
|
return false;
|
||||||
|
@ -307,9 +310,6 @@ bool egl_desktopRender(EGL_Desktop * desktop, const float x, const float y,
|
||||||
const float scaleX, const float scaleY, enum EGL_DesktopScaleType scaleType,
|
const float scaleX, const float scaleY, enum EGL_DesktopScaleType scaleType,
|
||||||
LG_RendererRotate rotate, const struct DamageRects * rects)
|
LG_RendererRotate rotate, const struct DamageRects * rects)
|
||||||
{
|
{
|
||||||
if (!desktop->shader)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
enum EGL_TexStatus status;
|
enum EGL_TexStatus status;
|
||||||
if ((status = egl_textureProcess(desktop->texture)) != EGL_TEX_STATUS_OK)
|
if ((status = egl_textureProcess(desktop->texture)) != EGL_TEX_STATUS_OK)
|
||||||
{
|
{
|
||||||
|
@ -339,28 +339,45 @@ bool egl_desktopRender(EGL_Desktop * desktop, const float x, const float y,
|
||||||
scaleAlgo = desktop->scaleAlgo;
|
scaleAlgo = desktop->scaleAlgo;
|
||||||
}
|
}
|
||||||
|
|
||||||
float matrix[6];
|
egl_desktopRectsMatrix((float *)desktop->matrix->data,
|
||||||
egl_desktopRectsMatrix(matrix, desktop->width, desktop->height, x, y, scaleX, scaleY, rotate);
|
desktop->width, desktop->height, x, y, scaleX, scaleY, rotate);
|
||||||
egl_desktopRectsUpdate(desktop->mesh, rects, desktop->width, desktop->height);
|
egl_desktopRectsUpdate(desktop->mesh, rects, desktop->width, desktop->height);
|
||||||
|
|
||||||
const struct DesktopShader * shader = desktop->shader;
|
|
||||||
egl_shaderUse(shader->shader);
|
|
||||||
glUniform1i(shader->uScaleAlgo , scaleAlgo);
|
|
||||||
glUniform2f(shader->uDesktopSize, desktop->width, desktop->height);
|
|
||||||
glUniform2f(shader->uUVScale , 1.0f / desktop->width, 1.0f / desktop->height);
|
|
||||||
glUniformMatrix3x2fv(shader->uTransform, 1, GL_FALSE, matrix);
|
|
||||||
|
|
||||||
if (desktop->nvGain)
|
|
||||||
{
|
|
||||||
glUniform1i(shader->uNV, 1);
|
|
||||||
glUniform1f(shader->uNVGain, (float)desktop->nvGain);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
glUniform1i(shader->uNV, 0);
|
|
||||||
|
|
||||||
glUniform1i(shader->uCBMode, desktop->cbMode);
|
|
||||||
|
|
||||||
egl_textureBind(desktop->texture);
|
egl_textureBind(desktop->texture);
|
||||||
|
|
||||||
|
const struct DesktopShader * shader = &desktop->shader;
|
||||||
|
EGL_Uniform uniforms[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.type = EGL_UNIFORM_TYPE_1I,
|
||||||
|
.location = shader->uScaleAlgo,
|
||||||
|
.i = { scaleAlgo },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.type = EGL_UNIFORM_TYPE_2F,
|
||||||
|
.location = shader->uDesktopSize,
|
||||||
|
.f = { desktop->width, desktop->height },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.type = EGL_UNIFORM_TYPE_M3x2FV,
|
||||||
|
.location = shader->uTransform,
|
||||||
|
.m.transpose = GL_FALSE,
|
||||||
|
.m.v = desktop->matrix
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.type = EGL_UNIFORM_TYPE_1F,
|
||||||
|
.location = shader->uNVGain,
|
||||||
|
.f = { (float)desktop->nvGain }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.type = EGL_UNIFORM_TYPE_1I,
|
||||||
|
.location = shader->uCBMode,
|
||||||
|
.f = { desktop->cbMode }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
egl_shaderSetUniforms(shader->shader, uniforms, ARRAY_LENGTH(uniforms));
|
||||||
|
egl_shaderUse(shader->shader);
|
||||||
egl_desktopRectsRender(desktop->mesh);
|
egl_desktopRectsRender(desktop->mesh);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "interface/renderer.h"
|
#include "egl.h"
|
||||||
#include "desktop_rects.h"
|
#include "desktop_rects.h"
|
||||||
|
|
||||||
typedef struct EGL_Desktop EGL_Desktop;
|
typedef struct EGL_Desktop EGL_Desktop;
|
||||||
|
@ -37,7 +37,8 @@ enum EGL_DesktopScaleType
|
||||||
struct Option;
|
struct Option;
|
||||||
bool egl_desktopScaleValidate(struct Option * opt, const char ** error);
|
bool egl_desktopScaleValidate(struct Option * opt, const char ** error);
|
||||||
|
|
||||||
bool egl_desktopInit(EGL_Desktop ** desktop, EGLDisplay * display, bool useDMA, int maxRects);
|
bool egl_desktopInit(EGL * egl, EGL_Desktop ** desktop, EGLDisplay * display,
|
||||||
|
bool useDMA, int maxRects);
|
||||||
void egl_desktopFree(EGL_Desktop ** desktop);
|
void egl_desktopFree(EGL_Desktop ** desktop);
|
||||||
|
|
||||||
void egl_desktopConfigUI(EGL_Desktop * desktop);
|
void egl_desktopConfigUI(EGL_Desktop * desktop);
|
||||||
|
|
|
@ -400,6 +400,11 @@ static void egl_update_scale_type(struct Inst * this)
|
||||||
this->scaleType = EGL_DESKTOP_UPSCALE;
|
this->scaleType = EGL_DESKTOP_UPSCALE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void egl_resetViewport(EGL * this)
|
||||||
|
{
|
||||||
|
glViewport(0, 0, this->width, this->height);
|
||||||
|
}
|
||||||
|
|
||||||
static void egl_onResize(LG_Renderer * renderer, const int width, const int height, const double scale,
|
static void egl_onResize(LG_Renderer * renderer, const int width, const int height, const double scale,
|
||||||
const LG_RendererRect destRect, LG_RendererRotate rotate)
|
const LG_RendererRect destRect, LG_RendererRotate rotate)
|
||||||
{
|
{
|
||||||
|
@ -782,13 +787,13 @@ static bool egl_renderStartup(LG_Renderer * renderer, bool useDMA)
|
||||||
|
|
||||||
eglSwapInterval(this->display, this->opt.vsync ? 1 : 0);
|
eglSwapInterval(this->display, this->opt.vsync ? 1 : 0);
|
||||||
|
|
||||||
if (!egl_desktopInit(&this->desktop, this->display, useDMA, MAX_ACCUMULATED_DAMAGE))
|
if (!egl_desktopInit(this, &this->desktop, this->display, useDMA, MAX_ACCUMULATED_DAMAGE))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to initialize the desktop");
|
DEBUG_ERROR("Failed to initialize the desktop");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!egl_cursorInit(&this->cursor))
|
if (!egl_cursorInit(this, &this->cursor))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to initialize the cursor");
|
DEBUG_ERROR("Failed to initialize the cursor");
|
||||||
return false;
|
return false;
|
||||||
|
|
24
client/renderers/EGL/egl.h
Normal file
24
client/renderers/EGL/egl.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/**
|
||||||
|
* Looking Glass
|
||||||
|
* Copyright © 2017-2021 The Looking Glass Authors
|
||||||
|
* https://looking-glass.io
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||||
|
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct Inst EGL;
|
||||||
|
void egl_resetViewport(EGL * egl);
|
|
@ -93,7 +93,7 @@ void egl_modelFree(EGL_Model ** model)
|
||||||
*model = NULL;
|
*model = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void egl_modelSetDefault(EGL_Model * model)
|
void egl_modelSetDefault(EGL_Model * model, bool flipped)
|
||||||
{
|
{
|
||||||
static const GLfloat square[] =
|
static const GLfloat square[] =
|
||||||
{
|
{
|
||||||
|
@ -103,7 +103,15 @@ void egl_modelSetDefault(EGL_Model * model)
|
||||||
1.0f, 1.0f, 0.0f
|
1.0f, 1.0f, 0.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
static const GLfloat uvs[] =
|
static const GLfloat uvsNormal[] =
|
||||||
|
{
|
||||||
|
0.0f, 0.0f,
|
||||||
|
1.0f, 0.0f,
|
||||||
|
0.0f, 1.0f,
|
||||||
|
1.0f, 1.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
static const GLfloat uvsFlipped[] =
|
||||||
{
|
{
|
||||||
0.0f, 1.0f,
|
0.0f, 1.0f,
|
||||||
1.0f, 1.0f,
|
1.0f, 1.0f,
|
||||||
|
@ -111,7 +119,7 @@ void egl_modelSetDefault(EGL_Model * model)
|
||||||
1.0f, 0.0f
|
1.0f, 0.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
egl_modelAddVerts(model, square, uvs, 4);
|
egl_modelAddVerts(model, square, flipped ? uvsFlipped : uvsNormal, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void egl_modelAddVerts(EGL_Model * model, const GLfloat * verticies, const GLfloat * uvs, const size_t count)
|
void egl_modelAddVerts(EGL_Model * model, const GLfloat * verticies, const GLfloat * uvs, const size_t count)
|
||||||
|
|
|
@ -27,11 +27,12 @@
|
||||||
#include <GLES3/gl3.h>
|
#include <GLES3/gl3.h>
|
||||||
|
|
||||||
typedef struct EGL_Model EGL_Model;
|
typedef struct EGL_Model EGL_Model;
|
||||||
|
typedef struct EGL_Texture EGL_Texture;
|
||||||
|
|
||||||
bool egl_modelInit(EGL_Model ** model);
|
bool egl_modelInit(EGL_Model ** model);
|
||||||
void egl_modelFree(EGL_Model ** model);
|
void egl_modelFree(EGL_Model ** model);
|
||||||
|
|
||||||
void egl_modelSetDefault (EGL_Model * model);
|
void egl_modelSetDefault (EGL_Model * model, bool flipped);
|
||||||
void egl_modelAddVerts(EGL_Model * model, const GLfloat * verticies, const GLfloat * uvs, const size_t count);
|
void egl_modelAddVerts(EGL_Model * model, const GLfloat * verticies, const GLfloat * uvs, const size_t count);
|
||||||
void egl_modelSetShader (EGL_Model * model, EGL_Shader * shader);
|
void egl_modelSetShader (EGL_Model * model, EGL_Shader * shader);
|
||||||
void egl_modelSetTexture (EGL_Model * model, EGL_Texture * texture);
|
void egl_modelSetTexture (EGL_Model * model, EGL_Texture * texture);
|
||||||
|
|
|
@ -30,31 +30,38 @@ struct EGL_Shader
|
||||||
{
|
{
|
||||||
bool hasShader;
|
bool hasShader;
|
||||||
GLuint shader;
|
GLuint shader;
|
||||||
|
|
||||||
|
EGL_Uniform * uniforms;
|
||||||
|
int uniformCount;
|
||||||
|
int uniformUsed;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool egl_shaderInit(EGL_Shader ** this)
|
bool egl_shaderInit(EGL_Shader ** this)
|
||||||
{
|
{
|
||||||
*this = (EGL_Shader *)malloc(sizeof(EGL_Shader));
|
*this = (EGL_Shader *)calloc(1, sizeof(EGL_Shader));
|
||||||
if (!*this)
|
if (!*this)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to malloc EGL_Shader");
|
DEBUG_ERROR("Failed to malloc EGL_Shader");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(*this, 0, sizeof(EGL_Shader));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void egl_shaderFree(EGL_Shader ** this)
|
void egl_shaderFree(EGL_Shader ** shader)
|
||||||
{
|
{
|
||||||
if (!*this)
|
EGL_Shader * this = *shader;
|
||||||
|
if (!this)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((*this)->hasShader)
|
if (this->hasShader)
|
||||||
glDeleteProgram((*this)->shader);
|
glDeleteProgram(this->shader);
|
||||||
|
|
||||||
free(*this);
|
egl_shaderFreeUniforms(this);
|
||||||
*this = NULL;
|
free(this->uniforms);
|
||||||
|
|
||||||
|
free(this);
|
||||||
|
*shader = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool egl_shaderLoad(EGL_Shader * this, const char * vertex_file, const char * fragment_file)
|
bool egl_shaderLoad(EGL_Shader * this, const char * vertex_file, const char * fragment_file)
|
||||||
|
@ -187,12 +194,277 @@ bool egl_shaderCompile(EGL_Shader * this, const char * vertex_code,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void egl_shaderSetUniforms(EGL_Shader * this, EGL_Uniform * uniforms, int count)
|
||||||
|
{
|
||||||
|
egl_shaderFreeUniforms(this);
|
||||||
|
if (count > this->uniformCount)
|
||||||
|
{
|
||||||
|
free(this->uniforms);
|
||||||
|
this->uniforms = malloc(sizeof(*this->uniforms) * count);
|
||||||
|
this->uniformCount = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->uniformUsed = count;
|
||||||
|
memcpy(this->uniforms, uniforms, sizeof(*this->uniforms) * count);
|
||||||
|
|
||||||
|
for(int i = 0; i < this->uniformUsed; ++i)
|
||||||
|
{
|
||||||
|
switch(this->uniforms[i].type)
|
||||||
|
{
|
||||||
|
case EGL_UNIFORM_TYPE_1FV:
|
||||||
|
case EGL_UNIFORM_TYPE_2FV:
|
||||||
|
case EGL_UNIFORM_TYPE_3FV:
|
||||||
|
case EGL_UNIFORM_TYPE_4FV:
|
||||||
|
case EGL_UNIFORM_TYPE_1IV:
|
||||||
|
case EGL_UNIFORM_TYPE_2IV:
|
||||||
|
case EGL_UNIFORM_TYPE_3IV:
|
||||||
|
case EGL_UNIFORM_TYPE_4IV:
|
||||||
|
case EGL_UNIFORM_TYPE_1UIV:
|
||||||
|
case EGL_UNIFORM_TYPE_2UIV:
|
||||||
|
case EGL_UNIFORM_TYPE_3UIV:
|
||||||
|
case EGL_UNIFORM_TYPE_4UIV:
|
||||||
|
countedBufferAddRef(this->uniforms[i].v);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_M2FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M3FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M4FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M2x3FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M3x2FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M2x4FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M4x2FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M3x4FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M4x3FV:
|
||||||
|
countedBufferAddRef(this->uniforms[i].m.v);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void egl_shaderFreeUniforms(EGL_Shader * this)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < this->uniformUsed; ++i)
|
||||||
|
{
|
||||||
|
switch(this->uniforms[i].type)
|
||||||
|
{
|
||||||
|
case EGL_UNIFORM_TYPE_1FV:
|
||||||
|
case EGL_UNIFORM_TYPE_2FV:
|
||||||
|
case EGL_UNIFORM_TYPE_3FV:
|
||||||
|
case EGL_UNIFORM_TYPE_4FV:
|
||||||
|
case EGL_UNIFORM_TYPE_1IV:
|
||||||
|
case EGL_UNIFORM_TYPE_2IV:
|
||||||
|
case EGL_UNIFORM_TYPE_3IV:
|
||||||
|
case EGL_UNIFORM_TYPE_4IV:
|
||||||
|
case EGL_UNIFORM_TYPE_1UIV:
|
||||||
|
case EGL_UNIFORM_TYPE_2UIV:
|
||||||
|
case EGL_UNIFORM_TYPE_3UIV:
|
||||||
|
case EGL_UNIFORM_TYPE_4UIV:
|
||||||
|
countedBufferRelease(&this->uniforms[i].v);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_M2FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M3FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M4FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M2x3FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M3x2FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M2x4FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M4x2FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M3x4FV:
|
||||||
|
case EGL_UNIFORM_TYPE_M4x3FV:
|
||||||
|
countedBufferRelease(&this->uniforms[i].m.v);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->uniformUsed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void egl_shaderUse(EGL_Shader * this)
|
void egl_shaderUse(EGL_Shader * this)
|
||||||
{
|
{
|
||||||
if (this->hasShader)
|
if (this->hasShader)
|
||||||
glUseProgram(this->shader);
|
glUseProgram(this->shader);
|
||||||
else
|
else
|
||||||
DEBUG_ERROR("Shader program has not been compiled");
|
DEBUG_ERROR("Shader program has not been compiled");
|
||||||
|
|
||||||
|
for(int i = 0; i < this->uniformUsed; ++i)
|
||||||
|
{
|
||||||
|
EGL_Uniform * uniform = &this->uniforms[i];
|
||||||
|
switch(uniform->type)
|
||||||
|
{
|
||||||
|
case EGL_UNIFORM_TYPE_1F:
|
||||||
|
glUniform1f(uniform->location, uniform->f[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_2F:
|
||||||
|
glUniform2f(uniform->location, uniform->f[0], uniform->f[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_3F:
|
||||||
|
glUniform3f(uniform->location, uniform->f[0], uniform->f[1],
|
||||||
|
uniform->f[2]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_4F:
|
||||||
|
glUniform4f(uniform->location, uniform->f[0], uniform->f[1],
|
||||||
|
uniform->f[2], uniform->f[3]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_1I:
|
||||||
|
glUniform1i(uniform->location, uniform->i[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_2I:
|
||||||
|
glUniform2i(uniform->location, uniform->i[0], uniform->i[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_3I:
|
||||||
|
glUniform3i(uniform->location, uniform->i[0], uniform->i[1],
|
||||||
|
uniform->i[2]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_4I:
|
||||||
|
glUniform4i(uniform->location, uniform->i[0], uniform->i[1],
|
||||||
|
uniform->i[2], uniform->i[3]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_1UI:
|
||||||
|
glUniform1ui(uniform->location, uniform->ui[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_2UI:
|
||||||
|
glUniform2ui(uniform->location, uniform->ui[0], uniform->ui[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_3UI:
|
||||||
|
glUniform3ui(uniform->location, uniform->ui[0], uniform->ui[1],
|
||||||
|
uniform->ui[2]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_4UI:
|
||||||
|
glUniform4ui(uniform->location, uniform->ui[0], uniform->ui[1],
|
||||||
|
uniform->ui[2], uniform->ui[3]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_1FV:
|
||||||
|
glUniform1fv(uniform->location, uniform->v->size / sizeof(GLfloat),
|
||||||
|
(const GLfloat *)uniform->v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_2FV:
|
||||||
|
glUniform2fv(uniform->location, uniform->v->size / sizeof(GLfloat) / 2,
|
||||||
|
(const GLfloat *)uniform->v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_3FV:
|
||||||
|
glUniform3fv(uniform->location, uniform->v->size / sizeof(GLfloat) / 3,
|
||||||
|
(const GLfloat *)uniform->v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_4FV:
|
||||||
|
glUniform4fv(uniform->location, uniform->v->size / sizeof(GLfloat) / 4,
|
||||||
|
(const GLfloat *)uniform->v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_1IV:
|
||||||
|
glUniform1iv(uniform->location, uniform->v->size / sizeof(GLint),
|
||||||
|
(const GLint *)uniform->v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_2IV:
|
||||||
|
glUniform2iv(uniform->location, uniform->v->size / sizeof(GLint) / 2,
|
||||||
|
(const GLint *)uniform->v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_3IV:
|
||||||
|
glUniform3iv(uniform->location, uniform->v->size / sizeof(GLint) / 3,
|
||||||
|
(const GLint *)uniform->v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_4IV:
|
||||||
|
glUniform4iv(uniform->location, uniform->v->size / sizeof(GLint) / 4,
|
||||||
|
(const GLint *)uniform->v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_1UIV:
|
||||||
|
glUniform1uiv(uniform->location, uniform->v->size / sizeof(GLuint),
|
||||||
|
(const GLuint *)uniform->v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_2UIV:
|
||||||
|
glUniform2uiv(uniform->location, uniform->v->size / sizeof(GLuint) / 2,
|
||||||
|
(const GLuint *)uniform->v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_3UIV:
|
||||||
|
glUniform3uiv(uniform->location, uniform->v->size / sizeof(GLuint) / 3,
|
||||||
|
(const GLuint *)uniform->v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_4UIV:
|
||||||
|
glUniform4uiv(uniform->location, uniform->v->size / sizeof(GLuint) / 4,
|
||||||
|
(const GLuint *)uniform->v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_M2FV:
|
||||||
|
glUniformMatrix2fv(uniform->location,
|
||||||
|
uniform->v->size / sizeof(GLfloat) / 2,
|
||||||
|
uniform->m.transpose, (const GLfloat *)uniform->m.v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_M3FV:
|
||||||
|
glUniformMatrix3fv(uniform->location,
|
||||||
|
uniform->v->size / sizeof(GLfloat) / 3,
|
||||||
|
uniform->m.transpose, (const GLfloat *)uniform->m.v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_M4FV:
|
||||||
|
glUniformMatrix4fv(uniform->location,
|
||||||
|
uniform->v->size / sizeof(GLfloat) / 4,
|
||||||
|
uniform->m.transpose, (const GLfloat *)uniform->m.v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_M2x3FV:
|
||||||
|
glUniformMatrix2x3fv(uniform->location,
|
||||||
|
uniform->v->size / sizeof(GLfloat) / 6,
|
||||||
|
uniform->m.transpose, (const GLfloat *)uniform->m.v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_M3x2FV:
|
||||||
|
glUniformMatrix3x2fv(uniform->location,
|
||||||
|
uniform->v->size / sizeof(GLfloat) / 6,
|
||||||
|
uniform->m.transpose, (const GLfloat *)uniform->m.v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_M2x4FV:
|
||||||
|
glUniformMatrix2x4fv(uniform->location,
|
||||||
|
uniform->v->size / sizeof(GLfloat) / 8,
|
||||||
|
uniform->m.transpose, (const GLfloat *)uniform->m.v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_M4x2FV:
|
||||||
|
glUniformMatrix4x2fv(uniform->location,
|
||||||
|
uniform->v->size / sizeof(GLfloat) / 8,
|
||||||
|
uniform->m.transpose, (const GLfloat *)uniform->m.v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_M3x4FV:
|
||||||
|
glUniformMatrix3x4fv(uniform->location,
|
||||||
|
uniform->v->size / sizeof(GLfloat) / 12,
|
||||||
|
uniform->m.transpose, (const GLfloat *)uniform->m.v->data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGL_UNIFORM_TYPE_M4x3FV:
|
||||||
|
glUniformMatrix4x3fv(uniform->location,
|
||||||
|
uniform->v->size / sizeof(GLfloat) / 12,
|
||||||
|
uniform->m.transpose, (const GLfloat *)uniform->m.v->data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void egl_shaderAssocTextures(EGL_Shader * this, const int count)
|
void egl_shaderAssocTextures(EGL_Shader * this, const int count)
|
||||||
|
|
|
@ -25,8 +25,74 @@
|
||||||
|
|
||||||
#include <GLES3/gl3.h>
|
#include <GLES3/gl3.h>
|
||||||
|
|
||||||
|
#include "common/countedbuffer.h"
|
||||||
|
|
||||||
typedef struct EGL_Shader EGL_Shader;
|
typedef struct EGL_Shader EGL_Shader;
|
||||||
|
|
||||||
|
enum EGL_UniformType
|
||||||
|
{
|
||||||
|
EGL_UNIFORM_TYPE_1F,
|
||||||
|
EGL_UNIFORM_TYPE_2F,
|
||||||
|
EGL_UNIFORM_TYPE_3F,
|
||||||
|
EGL_UNIFORM_TYPE_4F,
|
||||||
|
EGL_UNIFORM_TYPE_1I,
|
||||||
|
EGL_UNIFORM_TYPE_2I,
|
||||||
|
EGL_UNIFORM_TYPE_3I,
|
||||||
|
EGL_UNIFORM_TYPE_4I,
|
||||||
|
EGL_UNIFORM_TYPE_1UI,
|
||||||
|
EGL_UNIFORM_TYPE_2UI,
|
||||||
|
EGL_UNIFORM_TYPE_3UI,
|
||||||
|
EGL_UNIFORM_TYPE_4UI,
|
||||||
|
|
||||||
|
// vectors
|
||||||
|
EGL_UNIFORM_TYPE_1FV,
|
||||||
|
EGL_UNIFORM_TYPE_2FV,
|
||||||
|
EGL_UNIFORM_TYPE_3FV,
|
||||||
|
EGL_UNIFORM_TYPE_4FV,
|
||||||
|
EGL_UNIFORM_TYPE_1IV,
|
||||||
|
EGL_UNIFORM_TYPE_2IV,
|
||||||
|
EGL_UNIFORM_TYPE_3IV,
|
||||||
|
EGL_UNIFORM_TYPE_4IV,
|
||||||
|
EGL_UNIFORM_TYPE_1UIV,
|
||||||
|
EGL_UNIFORM_TYPE_2UIV,
|
||||||
|
EGL_UNIFORM_TYPE_3UIV,
|
||||||
|
EGL_UNIFORM_TYPE_4UIV,
|
||||||
|
|
||||||
|
// matrices
|
||||||
|
EGL_UNIFORM_TYPE_M2FV,
|
||||||
|
EGL_UNIFORM_TYPE_M3FV,
|
||||||
|
EGL_UNIFORM_TYPE_M4FV,
|
||||||
|
EGL_UNIFORM_TYPE_M2x3FV,
|
||||||
|
EGL_UNIFORM_TYPE_M3x2FV,
|
||||||
|
EGL_UNIFORM_TYPE_M2x4FV,
|
||||||
|
EGL_UNIFORM_TYPE_M4x2FV,
|
||||||
|
EGL_UNIFORM_TYPE_M3x4FV,
|
||||||
|
EGL_UNIFORM_TYPE_M4x3FV
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct EGL_Uniform
|
||||||
|
{
|
||||||
|
enum EGL_UniformType type;
|
||||||
|
GLint location;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
GLfloat f [4];
|
||||||
|
GLint i [4];
|
||||||
|
GLuint ui[4];
|
||||||
|
|
||||||
|
CountedBuffer * v;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
CountedBuffer * v;
|
||||||
|
GLboolean transpose;
|
||||||
|
}
|
||||||
|
m;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
EGL_Uniform;
|
||||||
|
|
||||||
bool egl_shaderInit(EGL_Shader ** shader);
|
bool egl_shaderInit(EGL_Shader ** shader);
|
||||||
void egl_shaderFree(EGL_Shader ** shader);
|
void egl_shaderFree(EGL_Shader ** shader);
|
||||||
|
|
||||||
|
@ -36,6 +102,10 @@ bool egl_shaderLoad(EGL_Shader * model, const char * vertex_file,
|
||||||
bool egl_shaderCompile(EGL_Shader * model, const char * vertex_code,
|
bool egl_shaderCompile(EGL_Shader * model, const char * vertex_code,
|
||||||
size_t vertex_size, const char * fragment_code, size_t fragment_size);
|
size_t vertex_size, const char * fragment_code, size_t fragment_size);
|
||||||
|
|
||||||
|
void egl_shaderSetUniforms(EGL_Shader * shader, EGL_Uniform * uniforms,
|
||||||
|
int count);
|
||||||
|
void egl_shaderFreeUniforms(EGL_Shader * shader);
|
||||||
|
|
||||||
void egl_shaderUse(EGL_Shader * shader);
|
void egl_shaderUse(EGL_Shader * shader);
|
||||||
|
|
||||||
void egl_shaderAssocTextures(EGL_Shader * shader, const int count);
|
void egl_shaderAssocTextures(EGL_Shader * shader, const int count);
|
||||||
|
|
|
@ -3,11 +3,15 @@
|
||||||
layout(location = 0) in vec2 vertex;
|
layout(location = 0) in vec2 vertex;
|
||||||
out highp vec2 uv;
|
out highp vec2 uv;
|
||||||
|
|
||||||
uniform highp vec2 uvScale;
|
uniform highp vec2 size;
|
||||||
uniform mat3x2 transform;
|
uniform mat3x2 transform;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
highp vec2 uvScale;
|
||||||
|
|
||||||
gl_Position = vec4(transform * vec3(vertex, 1.0), 0.0, 1.0);
|
gl_Position = vec4(transform * vec3(vertex, 1.0), 0.0, 1.0);
|
||||||
|
uvScale.x = 1.0 / size.x;
|
||||||
|
uvScale.y = 1.0 / size.y;
|
||||||
uv = vertex * uvScale;
|
uv = vertex * uvScale;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ uniform sampler2D sampler1;
|
||||||
uniform int scaleAlgo;
|
uniform int scaleAlgo;
|
||||||
uniform highp vec2 size;
|
uniform highp vec2 size;
|
||||||
|
|
||||||
uniform int nv;
|
|
||||||
uniform highp float nvGain;
|
uniform highp float nvGain;
|
||||||
uniform int cbMode;
|
uniform int cbMode;
|
||||||
|
|
||||||
|
@ -67,7 +66,7 @@ void main()
|
||||||
color.b += (error.r * 0.7) + (error.b * 1.0);
|
color.b += (error.r * 0.7) + (error.b * 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nv == 1)
|
if (nvGain > 0.0)
|
||||||
{
|
{
|
||||||
highp float lumi = 1.0 - (0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b);
|
highp float lumi = 1.0 - (0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b);
|
||||||
color *= 1.0 + lumi;
|
color *= 1.0 + lumi;
|
||||||
|
|
|
@ -80,7 +80,7 @@ bool egl_splashInit(EGL_Splash ** splash)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
egl_modelSetDefault((*splash)->bg);
|
egl_modelSetDefault((*splash)->bg, false);
|
||||||
|
|
||||||
if (!egl_shaderInit(&(*splash)->logoShader))
|
if (!egl_shaderInit(&(*splash)->logoShader))
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "common/framebuffer.h"
|
#include "common/framebuffer.h"
|
||||||
|
#include "common/debug.h"
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <EGL/eglext.h>
|
#include <EGL/eglext.h>
|
||||||
|
@ -36,8 +37,16 @@ extern const EGL_TextureOps EGL_TextureBufferStream;
|
||||||
extern const EGL_TextureOps EGL_TextureFrameBuffer;
|
extern const EGL_TextureOps EGL_TextureFrameBuffer;
|
||||||
extern const EGL_TextureOps EGL_TextureDMABUF;
|
extern const EGL_TextureOps EGL_TextureDMABUF;
|
||||||
|
|
||||||
bool egl_textureInit(EGL_Texture ** texture, EGLDisplay * display,
|
typedef struct RenderStep
|
||||||
EGL_TexType type, bool streaming)
|
{
|
||||||
|
GLuint fb;
|
||||||
|
GLuint tex;
|
||||||
|
EGL_Shader * shader;
|
||||||
|
}
|
||||||
|
RenderStep;
|
||||||
|
|
||||||
|
bool egl_textureInit(EGL * egl, EGL_Texture ** texture_,
|
||||||
|
EGLDisplay * display, EGL_TexType type, bool streaming)
|
||||||
{
|
{
|
||||||
const EGL_TextureOps * ops;
|
const EGL_TextureOps * ops;
|
||||||
|
|
||||||
|
@ -61,21 +70,71 @@ bool egl_textureInit(EGL_Texture ** texture, EGLDisplay * display,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*texture = NULL;
|
*texture_ = NULL;
|
||||||
if (!ops->init(texture, display))
|
if (!ops->init(texture_, display))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
memcpy(&(*texture)->ops, ops, sizeof(*ops));
|
EGL_Texture * this = *texture_;
|
||||||
|
memcpy(&this->ops, ops, sizeof(*ops));
|
||||||
|
this->egl = egl;
|
||||||
|
|
||||||
|
glGenSamplers(1, &this->sampler);
|
||||||
|
glSamplerParameteri(this->sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glSamplerParameteri(this->sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glSamplerParameteri(this->sampler, GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE);
|
||||||
|
glSamplerParameteri(this->sampler, GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
|
this->textures = ringbuffer_new(8, sizeof(GLuint));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void egl_textureFree(EGL_Texture ** tex)
|
void egl_textureFree(EGL_Texture ** tex)
|
||||||
{
|
{
|
||||||
(*tex)->ops.free(*tex);
|
EGL_Texture * this = *tex;
|
||||||
|
|
||||||
|
if (this->render)
|
||||||
|
{
|
||||||
|
RenderStep * step;
|
||||||
|
while(ll_shift(this->render, (void **)&step))
|
||||||
|
{
|
||||||
|
if (step->fb)
|
||||||
|
glDeleteFramebuffers(1, &step->fb);
|
||||||
|
|
||||||
|
glDeleteTextures(1, &step->tex);
|
||||||
|
free(step);
|
||||||
|
}
|
||||||
|
ll_free(this->render);
|
||||||
|
egl_modelFree(&this->model);
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteSamplers(1, &this->sampler);
|
||||||
|
ringbuffer_free(&this->textures);
|
||||||
|
|
||||||
|
this->ops.free(this);
|
||||||
*tex = NULL;
|
*tex = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool egl_textureSetup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt,
|
bool setupRenderStep(EGL_Texture * this, RenderStep * step)
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, step->tex);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
this->format.intFormat,
|
||||||
|
this->format.width,
|
||||||
|
this->format.height,
|
||||||
|
0,
|
||||||
|
this->format.format,
|
||||||
|
this->format.dataType,
|
||||||
|
NULL);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool egl_textureSetup(EGL_Texture * this, enum EGL_PixelFormat pixFmt,
|
||||||
size_t width, size_t height, size_t stride)
|
size_t width, size_t height, size_t stride)
|
||||||
{
|
{
|
||||||
const struct EGL_TexSetup setup =
|
const struct EGL_TexSetup setup =
|
||||||
|
@ -85,21 +144,43 @@ bool egl_textureSetup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt,
|
||||||
.height = height,
|
.height = height,
|
||||||
.stride = stride
|
.stride = stride
|
||||||
};
|
};
|
||||||
texture->size = height * stride;
|
this->size = height * stride;
|
||||||
return texture->ops.setup(texture, &setup);
|
|
||||||
|
if (!egl_texUtilGetFormat(&setup, &this->format))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
this->formatValid = true;
|
||||||
|
|
||||||
|
/* reconfigure any intermediate render steps */
|
||||||
|
if (this->render)
|
||||||
|
{
|
||||||
|
RenderStep * step;
|
||||||
|
for(ll_reset(this->render); ll_walk(this->render, (void **)&step); )
|
||||||
|
if (!setupRenderStep(this, step))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->ops.setup(this, &setup);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool egl_textureUpdate(EGL_Texture * texture, const uint8_t * buffer)
|
bool egl_textureUpdate(EGL_Texture * this, const uint8_t * buffer)
|
||||||
{
|
{
|
||||||
const struct EGL_TexUpdate update =
|
const struct EGL_TexUpdate update =
|
||||||
{
|
{
|
||||||
.type = EGL_TEXTYPE_BUFFER,
|
.type = EGL_TEXTYPE_BUFFER,
|
||||||
.buffer = buffer
|
.buffer = buffer
|
||||||
};
|
};
|
||||||
return texture->ops.update(texture, &update);
|
|
||||||
|
if (this->ops.update(this, &update))
|
||||||
|
{
|
||||||
|
atomic_store(&this->updated, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool egl_textureUpdateFromFrame(EGL_Texture * texture,
|
bool egl_textureUpdateFromFrame(EGL_Texture * this,
|
||||||
const FrameBuffer * frame, const FrameDamageRect * damageRects,
|
const FrameBuffer * frame, const FrameDamageRect * damageRects,
|
||||||
int damageRectsCount)
|
int damageRectsCount)
|
||||||
{
|
{
|
||||||
|
@ -110,10 +191,17 @@ bool egl_textureUpdateFromFrame(EGL_Texture * texture,
|
||||||
.rects = damageRects,
|
.rects = damageRects,
|
||||||
.rectCount = damageRectsCount,
|
.rectCount = damageRectsCount,
|
||||||
};
|
};
|
||||||
return texture->ops.update(texture, &update);
|
|
||||||
|
if (this->ops.update(this, &update))
|
||||||
|
{
|
||||||
|
atomic_store(&this->updated, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool egl_textureUpdateFromDMA(EGL_Texture * texture,
|
bool egl_textureUpdateFromDMA(EGL_Texture * this,
|
||||||
const FrameBuffer * frame, const int dmaFd)
|
const FrameBuffer * frame, const int dmaFd)
|
||||||
{
|
{
|
||||||
const struct EGL_TexUpdate update =
|
const struct EGL_TexUpdate update =
|
||||||
|
@ -123,17 +211,135 @@ bool egl_textureUpdateFromDMA(EGL_Texture * texture,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* wait for completion */
|
/* wait for completion */
|
||||||
framebuffer_wait(frame, texture->size);
|
framebuffer_wait(frame, this->size);
|
||||||
|
|
||||||
return texture->ops.update(texture, &update);
|
if (this->ops.update(this, &update))
|
||||||
|
{
|
||||||
|
atomic_store(&this->updated, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum EGL_TexStatus egl_textureProcess(EGL_Texture * texture)
|
enum EGL_TexStatus egl_textureProcess(EGL_Texture * this)
|
||||||
{
|
{
|
||||||
return texture->ops.process(texture);
|
EGL_TexStatus status;
|
||||||
|
if ((status = this->ops.process(this)) == EGL_TEX_STATUS_OK)
|
||||||
|
{
|
||||||
|
if (atomic_exchange(&this->updated, false))
|
||||||
|
this->postProcessed = false;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum EGL_TexStatus egl_textureBind(EGL_Texture * texture)
|
static bool rbBindTexture(int index, void * value, void * udata)
|
||||||
{
|
{
|
||||||
return texture->ops.bind(texture);
|
GLuint * tex = (GLuint *)value;
|
||||||
|
EGL_Texture * this = (EGL_Texture *)udata;
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0 + index);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, *tex);
|
||||||
|
glBindSampler(0, this->sampler);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum EGL_TexStatus egl_textureBind(EGL_Texture * this)
|
||||||
|
{
|
||||||
|
GLuint tex;
|
||||||
|
EGL_TexStatus status;
|
||||||
|
|
||||||
|
if (!this->render)
|
||||||
|
{
|
||||||
|
if ((status = this->ops.get(this, &tex)) != EGL_TEX_STATUS_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
|
glBindSampler(0, this->sampler);
|
||||||
|
return EGL_TEX_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderStep * step;
|
||||||
|
ringbuffer_reset(this->textures);
|
||||||
|
|
||||||
|
/* if the postProcessing has not yet been done */
|
||||||
|
if (!this->postProcessed)
|
||||||
|
{
|
||||||
|
if ((status = this->ops.get(this, &tex)) != EGL_TEX_STATUS_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
ringbuffer_push(this->textures, &tex);
|
||||||
|
ringbuffer_forEach(this->textures, rbBindTexture, this, true);
|
||||||
|
|
||||||
|
for(ll_reset(this->render); ll_walk(this->render, (void **)&step); )
|
||||||
|
{
|
||||||
|
/* create the framebuffer here as it must be in the same gl context as
|
||||||
|
* it's usage */
|
||||||
|
if (!step->fb)
|
||||||
|
{
|
||||||
|
glGenFramebuffers(1, &step->fb);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, step->fb);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
|
GL_TEXTURE_2D, step->tex, 0);
|
||||||
|
glDrawBuffers(1, &(GLenum){GL_COLOR_ATTACHMENT0});
|
||||||
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to setup the shader framebuffer");
|
||||||
|
return EGL_TEX_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, step->fb);
|
||||||
|
|
||||||
|
glViewport(0, 0, this->format.width, this->format.height);
|
||||||
|
egl_shaderUse(step->shader);
|
||||||
|
egl_modelRender(this->model);
|
||||||
|
|
||||||
|
ringbuffer_push(this->textures, &step->tex);
|
||||||
|
ringbuffer_forEach(this->textures, rbBindTexture, this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restore the state and the viewport */
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
glUseProgram(0);
|
||||||
|
egl_resetViewport(this->egl);
|
||||||
|
|
||||||
|
this->postProcessed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* bind the last texture */
|
||||||
|
ll_peek_tail(this->render, (void **)&step);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, step->tex);
|
||||||
|
glBindSampler(0, this->sampler);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EGL_TEX_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum EGL_TexStatus egl_textureAddShader(EGL_Texture * this, EGL_Shader * shader)
|
||||||
|
{
|
||||||
|
if (!this->render)
|
||||||
|
{
|
||||||
|
this->render = ll_new();
|
||||||
|
egl_modelInit(&this->model);
|
||||||
|
egl_modelSetDefault(this->model, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderStep * step = calloc(1, sizeof(*step));
|
||||||
|
glGenTextures(1, &step->tex);
|
||||||
|
step->shader = shader;
|
||||||
|
|
||||||
|
if (this->formatValid)
|
||||||
|
if (!setupRenderStep(this, step))
|
||||||
|
{
|
||||||
|
glDeleteTextures(1, &step->tex);
|
||||||
|
free(step);
|
||||||
|
return EGL_TEX_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ll_push(this->render, step);
|
||||||
|
return EGL_TEX_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,14 +21,22 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "egl.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
|
#include "model.h"
|
||||||
#include "common/framebuffer.h"
|
#include "common/framebuffer.h"
|
||||||
|
#include "common/ringbuffer.h"
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "ll.h"
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <EGL/eglext.h>
|
#include <EGL/eglext.h>
|
||||||
|
|
||||||
|
#include "texture_util.h"
|
||||||
|
|
||||||
|
typedef struct EGL_Model EGL_Model;
|
||||||
|
|
||||||
typedef enum EGL_TexType
|
typedef enum EGL_TexType
|
||||||
{
|
{
|
||||||
EGL_TEXTYPE_BUFFER,
|
EGL_TEXTYPE_BUFFER,
|
||||||
|
@ -113,20 +121,32 @@ typedef struct EGL_TextureOps
|
||||||
/* called from a background job to prepare the texture for use before bind */
|
/* called from a background job to prepare the texture for use before bind */
|
||||||
enum EGL_TexStatus (*process)(EGL_Texture * texture);
|
enum EGL_TexStatus (*process)(EGL_Texture * texture);
|
||||||
|
|
||||||
/* bind the texture for use */
|
/* get the texture for use */
|
||||||
enum EGL_TexStatus (*bind)(EGL_Texture * texture);
|
enum EGL_TexStatus (*get)(EGL_Texture * texture, GLuint * tex);
|
||||||
}
|
}
|
||||||
EGL_TextureOps;
|
EGL_TextureOps;
|
||||||
|
|
||||||
struct EGL_Texture
|
struct EGL_Texture
|
||||||
{
|
{
|
||||||
struct EGL_TextureOps ops;
|
struct EGL_TextureOps ops;
|
||||||
|
EGL * egl;
|
||||||
|
GLuint sampler;
|
||||||
|
RingBuffer textures;
|
||||||
|
|
||||||
|
EGL_TexFormat format;
|
||||||
|
bool formatValid;
|
||||||
|
|
||||||
// needed for dmabuf
|
// needed for dmabuf
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
|
// for applying shaders
|
||||||
|
struct ll * render;
|
||||||
|
_Atomic(bool) updated;
|
||||||
|
bool postProcessed;
|
||||||
|
EGL_Model * model;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool egl_textureInit(EGL_Texture ** texture, EGLDisplay * display,
|
bool egl_textureInit(EGL * egl, EGL_Texture ** texture, EGLDisplay * display,
|
||||||
EGL_TexType type, bool streaming);
|
EGL_TexType type, bool streaming);
|
||||||
void egl_textureFree(EGL_Texture ** tex);
|
void egl_textureFree(EGL_Texture ** tex);
|
||||||
|
|
||||||
|
@ -145,3 +165,5 @@ bool egl_textureUpdateFromDMA(EGL_Texture * texture,
|
||||||
enum EGL_TexStatus egl_textureProcess(EGL_Texture * texture);
|
enum EGL_TexStatus egl_textureProcess(EGL_Texture * texture);
|
||||||
|
|
||||||
enum EGL_TexStatus egl_textureBind(EGL_Texture * texture);
|
enum EGL_TexStatus egl_textureBind(EGL_Texture * texture);
|
||||||
|
|
||||||
|
enum EGL_TexStatus egl_textureAddShader(EGL_Texture * texture, EGL_Shader * shader);
|
||||||
|
|
|
@ -38,9 +38,6 @@ static void egl_texBuffer_cleanup(TextureBuffer * this)
|
||||||
if (this->tex[0])
|
if (this->tex[0])
|
||||||
glDeleteTextures(this->texCount, this->tex);
|
glDeleteTextures(this->texCount, this->tex);
|
||||||
|
|
||||||
if (this->sampler)
|
|
||||||
glDeleteSamplers(1, &this->sampler);
|
|
||||||
|
|
||||||
if (this->sync)
|
if (this->sync)
|
||||||
{
|
{
|
||||||
glDeleteSync(this->sync);
|
glDeleteSync(this->sync);
|
||||||
|
@ -88,27 +85,18 @@ bool egl_texBufferSetup(EGL_Texture * texture, const EGL_TexSetup * setup)
|
||||||
|
|
||||||
egl_texBuffer_cleanup(this);
|
egl_texBuffer_cleanup(this);
|
||||||
|
|
||||||
if (!egl_texUtilGetFormat(setup, &this->format))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
glGenSamplers(1, &this->sampler);
|
|
||||||
glSamplerParameteri(this->sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glSamplerParameteri(this->sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glSamplerParameteri(this->sampler, GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE);
|
|
||||||
glSamplerParameteri(this->sampler, GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE);
|
|
||||||
|
|
||||||
glGenTextures(this->texCount, this->tex);
|
glGenTextures(this->texCount, this->tex);
|
||||||
for(int i = 0; i < this->texCount; ++i)
|
for(int i = 0; i < this->texCount; ++i)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_2D, this->tex[i]);
|
glBindTexture(GL_TEXTURE_2D, this->tex[i]);
|
||||||
glTexImage2D(GL_TEXTURE_2D,
|
glTexImage2D(GL_TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
this->format.intFormat,
|
texture->format.intFormat,
|
||||||
this->format.width,
|
texture->format.width,
|
||||||
this->format.height,
|
texture->format.height,
|
||||||
0,
|
0,
|
||||||
this->format.format,
|
texture->format.format,
|
||||||
this->format.dataType,
|
texture->format.dataType,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,19 +106,19 @@ bool egl_texBufferSetup(EGL_Texture * texture, const EGL_TexSetup * setup)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool egl_texBuffer_update(EGL_Texture * texture, const EGL_TexUpdate * update)
|
static bool egl_texBufferUpdate(EGL_Texture * texture, const EGL_TexUpdate * update)
|
||||||
{
|
{
|
||||||
TextureBuffer * this = UPCAST(TextureBuffer, texture);
|
TextureBuffer * this = UPCAST(TextureBuffer, texture);
|
||||||
assert(update->type == EGL_TEXTYPE_BUFFER);
|
assert(update->type == EGL_TEXTYPE_BUFFER);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, this->tex[0]);
|
glBindTexture(GL_TEXTURE_2D, this->tex[0]);
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, this->format.pitch);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->format.pitch);
|
||||||
glTexSubImage2D(GL_TEXTURE_2D,
|
glTexSubImage2D(GL_TEXTURE_2D,
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
this->format.width,
|
texture->format.width,
|
||||||
this->format.height,
|
texture->format.height,
|
||||||
this->format.format,
|
texture->format.format,
|
||||||
this->format.dataType,
|
texture->format.dataType,
|
||||||
update->buffer);
|
update->buffer);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
@ -142,15 +130,11 @@ EGL_TexStatus egl_texBufferProcess(EGL_Texture * texture)
|
||||||
return EGL_TEX_STATUS_OK;
|
return EGL_TEX_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGL_TexStatus egl_texBufferBind(EGL_Texture * texture)
|
EGL_TexStatus egl_texBufferGet(EGL_Texture * texture, GLuint * tex)
|
||||||
{
|
{
|
||||||
TextureBuffer * this = UPCAST(TextureBuffer, texture);
|
TextureBuffer * this = UPCAST(TextureBuffer, texture);
|
||||||
|
*tex = this->tex[0];
|
||||||
glActiveTexture(GL_TEXTURE0);
|
return EGL_TEX_STATUS_OK;
|
||||||
glBindTexture(GL_TEXTURE_2D, this->tex[0]);
|
|
||||||
glBindSampler(0, this->sampler);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// streaming functions
|
// streaming functions
|
||||||
|
@ -173,7 +157,7 @@ bool egl_texBufferStreamSetup(EGL_Texture * texture, const EGL_TexSetup * setup)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
TextureBuffer * this = UPCAST(TextureBuffer, texture);
|
TextureBuffer * this = UPCAST(TextureBuffer, texture);
|
||||||
return egl_texUtilGenBuffers(&this->format, this->buf, this->texCount);
|
return egl_texUtilGenBuffers(&texture->format, this->buf, this->texCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool egl_texBufferStreamUpdate(EGL_Texture * texture,
|
static bool egl_texBufferStreamUpdate(EGL_Texture * texture,
|
||||||
|
@ -184,7 +168,7 @@ static bool egl_texBufferStreamUpdate(EGL_Texture * texture,
|
||||||
|
|
||||||
LG_LOCK(this->copyLock);
|
LG_LOCK(this->copyLock);
|
||||||
memcpy(this->buf[this->bufIndex].map, update->buffer,
|
memcpy(this->buf[this->bufIndex].map, update->buffer,
|
||||||
this->format.bufferSize);
|
texture->format.bufferSize);
|
||||||
this->buf[this->bufIndex].updated = true;
|
this->buf[this->bufIndex].updated = true;
|
||||||
LG_UNLOCK(this->copyLock);
|
LG_UNLOCK(this->copyLock);
|
||||||
|
|
||||||
|
@ -215,13 +199,13 @@ EGL_TexStatus egl_texBufferStreamProcess(EGL_Texture * texture)
|
||||||
|
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer->pbo);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer->pbo);
|
||||||
glBindTexture(GL_TEXTURE_2D, tex);
|
glBindTexture(GL_TEXTURE_2D, tex);
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, this->format.pitch);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->format.pitch);
|
||||||
glTexSubImage2D(GL_TEXTURE_2D,
|
glTexSubImage2D(GL_TEXTURE_2D,
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
this->format.width,
|
texture->format.width,
|
||||||
this->format.height,
|
texture->format.height,
|
||||||
this->format.format,
|
texture->format.format,
|
||||||
this->format.dataType,
|
texture->format.dataType,
|
||||||
(const void *)0);
|
(const void *)0);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
|
@ -233,7 +217,7 @@ EGL_TexStatus egl_texBufferStreamProcess(EGL_Texture * texture)
|
||||||
return EGL_TEX_STATUS_OK;
|
return EGL_TEX_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGL_TexStatus egl_texBufferStreamBind(EGL_Texture * texture)
|
EGL_TexStatus egl_texBufferStreamGet(EGL_Texture * texture, GLuint * tex)
|
||||||
{
|
{
|
||||||
TextureBuffer * this = UPCAST(TextureBuffer, texture);
|
TextureBuffer * this = UPCAST(TextureBuffer, texture);
|
||||||
|
|
||||||
|
@ -262,10 +246,7 @@ EGL_TexStatus egl_texBufferStreamBind(EGL_Texture * texture)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
*tex = this->tex[this->rIndex];
|
||||||
glBindTexture(GL_TEXTURE_2D, this->tex[this->rIndex]);
|
|
||||||
glBindSampler(0, this->sampler);
|
|
||||||
|
|
||||||
return EGL_TEX_STATUS_OK;
|
return EGL_TEX_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,9 +255,9 @@ const EGL_TextureOps EGL_TextureBuffer =
|
||||||
.init = egl_texBufferInit,
|
.init = egl_texBufferInit,
|
||||||
.free = egl_texBufferFree,
|
.free = egl_texBufferFree,
|
||||||
.setup = egl_texBufferSetup,
|
.setup = egl_texBufferSetup,
|
||||||
.update = egl_texBuffer_update,
|
.update = egl_texBufferUpdate,
|
||||||
.process = egl_texBufferProcess,
|
.process = egl_texBufferProcess,
|
||||||
.bind = egl_texBufferBind
|
.get = egl_texBufferGet
|
||||||
};
|
};
|
||||||
|
|
||||||
const EGL_TextureOps EGL_TextureBufferStream =
|
const EGL_TextureOps EGL_TextureBufferStream =
|
||||||
|
@ -286,5 +267,5 @@ const EGL_TextureOps EGL_TextureBufferStream =
|
||||||
.setup = egl_texBufferStreamSetup,
|
.setup = egl_texBufferStreamSetup,
|
||||||
.update = egl_texBufferStreamUpdate,
|
.update = egl_texBufferStreamUpdate,
|
||||||
.process = egl_texBufferStreamProcess,
|
.process = egl_texBufferStreamProcess,
|
||||||
.bind = egl_texBufferStreamBind
|
.get = egl_texBufferStreamGet
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,7 +31,6 @@ typedef struct TextureBuffer
|
||||||
EGL_Texture base;
|
EGL_Texture base;
|
||||||
bool free;
|
bool free;
|
||||||
|
|
||||||
EGL_TexFormat format;
|
|
||||||
int texCount;
|
int texCount;
|
||||||
GLuint tex[EGL_TEX_BUFFER_MAX];
|
GLuint tex[EGL_TEX_BUFFER_MAX];
|
||||||
GLuint sampler;
|
GLuint sampler;
|
||||||
|
@ -48,10 +47,10 @@ bool egl_texBufferInit(EGL_Texture ** texture_, EGLDisplay * display);
|
||||||
void egl_texBufferFree(EGL_Texture * texture_);
|
void egl_texBufferFree(EGL_Texture * texture_);
|
||||||
bool egl_texBufferSetup(EGL_Texture * texture_, const EGL_TexSetup * setup);
|
bool egl_texBufferSetup(EGL_Texture * texture_, const EGL_TexSetup * setup);
|
||||||
EGL_TexStatus egl_texBufferProcess(EGL_Texture * texture_);
|
EGL_TexStatus egl_texBufferProcess(EGL_Texture * texture_);
|
||||||
EGL_TexStatus egl_texBufferBind(EGL_Texture * texture_);
|
EGL_TexStatus egl_texBufferGet(EGL_Texture * texture_, GLuint * tex);
|
||||||
|
|
||||||
bool egl_texBufferStreamInit(EGL_Texture ** texture_, EGLDisplay * display);
|
bool egl_texBufferStreamInit(EGL_Texture ** texture_, EGLDisplay * display);
|
||||||
bool egl_texBufferStreamSetup(EGL_Texture * texture_,
|
bool egl_texBufferStreamSetup(EGL_Texture * texture_,
|
||||||
const EGL_TexSetup * setup);
|
const EGL_TexSetup * setup);
|
||||||
EGL_TexStatus egl_texBufferStreamProcess(EGL_Texture * texture_);
|
EGL_TexStatus egl_texBufferStreamProcess(EGL_Texture * texture_);
|
||||||
EGL_TexStatus egl_texBufferStreamBind(EGL_Texture * texture_);
|
EGL_TexStatus egl_texBufferStreamGet(EGL_Texture * texture_, GLuint * tex);
|
||||||
|
|
|
@ -99,12 +99,12 @@ static bool egl_texDMABUFSetup(EGL_Texture * texture, const EGL_TexSetup * setup
|
||||||
glBindTexture(GL_TEXTURE_2D, parent->tex[0]);
|
glBindTexture(GL_TEXTURE_2D, parent->tex[0]);
|
||||||
glTexImage2D(GL_TEXTURE_2D,
|
glTexImage2D(GL_TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
parent->format.intFormat,
|
texture->format.intFormat,
|
||||||
parent->format.width,
|
texture->format.width,
|
||||||
parent->format.height,
|
texture->format.height,
|
||||||
0,
|
0,
|
||||||
parent->format.format,
|
texture->format.format,
|
||||||
parent->format.dataType,
|
texture->format.dataType,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -130,12 +130,12 @@ static bool egl_texDMABUFUpdate(EGL_Texture * texture,
|
||||||
{
|
{
|
||||||
EGLAttrib const attribs[] =
|
EGLAttrib const attribs[] =
|
||||||
{
|
{
|
||||||
EGL_WIDTH , parent->format.width,
|
EGL_WIDTH , texture->format.width,
|
||||||
EGL_HEIGHT , parent->format.height,
|
EGL_HEIGHT , texture->format.height,
|
||||||
EGL_LINUX_DRM_FOURCC_EXT , parent->format.fourcc,
|
EGL_LINUX_DRM_FOURCC_EXT , texture->format.fourcc,
|
||||||
EGL_DMA_BUF_PLANE0_FD_EXT , update->dmaFD,
|
EGL_DMA_BUF_PLANE0_FD_EXT , update->dmaFD,
|
||||||
EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
|
EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
|
||||||
EGL_DMA_BUF_PLANE0_PITCH_EXT , parent->format.stride,
|
EGL_DMA_BUF_PLANE0_PITCH_EXT , texture->format.stride,
|
||||||
EGL_NONE , EGL_NONE
|
EGL_NONE , EGL_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -182,14 +182,11 @@ static EGL_TexStatus egl_texDMABUFProcess(EGL_Texture * texture)
|
||||||
return EGL_TEX_STATUS_OK;
|
return EGL_TEX_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EGL_TexStatus egl_texDMABUFBind(EGL_Texture * texture)
|
static EGL_TexStatus egl_texDMABUFGet(EGL_Texture * texture, GLuint * tex)
|
||||||
{
|
{
|
||||||
TextureBuffer * parent = UPCAST(TextureBuffer, texture);
|
TextureBuffer * parent = UPCAST(TextureBuffer, texture);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
*tex = parent->tex[0];
|
||||||
glBindTexture(GL_TEXTURE_2D, parent->tex[0]);
|
|
||||||
glBindSampler(0, parent->sampler);
|
|
||||||
|
|
||||||
return EGL_TEX_STATUS_OK;
|
return EGL_TEX_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,5 +197,5 @@ EGL_TextureOps EGL_TextureDMABUF =
|
||||||
.setup = egl_texDMABUFSetup,
|
.setup = egl_texDMABUFSetup,
|
||||||
.update = egl_texDMABUFUpdate,
|
.update = egl_texDMABUFUpdate,
|
||||||
.process = egl_texDMABUFProcess,
|
.process = egl_texDMABUFProcess,
|
||||||
.bind = egl_texDMABUFBind
|
.get = egl_texDMABUFGet
|
||||||
};
|
};
|
||||||
|
|
|
@ -85,11 +85,11 @@ static bool egl_texFBUpdate(EGL_Texture * texture, const EGL_TexUpdate * update)
|
||||||
framebuffer_read(
|
framebuffer_read(
|
||||||
update->frame,
|
update->frame,
|
||||||
parent->buf[parent->bufIndex].map,
|
parent->buf[parent->bufIndex].map,
|
||||||
parent->format.stride,
|
texture->format.stride,
|
||||||
parent->format.height,
|
texture->format.height,
|
||||||
parent->format.width,
|
texture->format.width,
|
||||||
parent->format.bpp,
|
texture->format.bpp,
|
||||||
parent->format.stride
|
texture->format.stride
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -100,10 +100,10 @@ static bool egl_texFBUpdate(EGL_Texture * texture, const EGL_TexUpdate * update)
|
||||||
damage->rects,
|
damage->rects,
|
||||||
damage->count,
|
damage->count,
|
||||||
parent->buf[parent->bufIndex].map,
|
parent->buf[parent->bufIndex].map,
|
||||||
parent->format.stride,
|
texture->format.stride,
|
||||||
parent->format.height,
|
texture->format.height,
|
||||||
update->frame,
|
update->frame,
|
||||||
parent->format.stride
|
texture->format.stride
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,10 +132,10 @@ static bool egl_texFBUpdate(EGL_Texture * texture, const EGL_TexUpdate * update)
|
||||||
|
|
||||||
EGL_TextureOps EGL_TextureFrameBuffer =
|
EGL_TextureOps EGL_TextureFrameBuffer =
|
||||||
{
|
{
|
||||||
.init = egl_texFBInit,
|
.init = egl_texFBInit,
|
||||||
.free = egl_texFBFree,
|
.free = egl_texFBFree,
|
||||||
.setup = egl_texBufferStreamSetup,
|
.setup = egl_texBufferStreamSetup,
|
||||||
.update = egl_texFBUpdate,
|
.update = egl_texFBUpdate,
|
||||||
.process = egl_texBufferStreamProcess,
|
.process = egl_texBufferStreamProcess,
|
||||||
.bind = egl_texBufferStreamBind
|
.get = egl_texBufferStreamGet
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "texture.h"
|
||||||
#include "texture_util.h"
|
#include "texture_util.h"
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
|
typedef struct EGL_TexSetup EGL_TexSetup;
|
||||||
|
|
||||||
typedef struct EGL_TexFormat
|
typedef struct EGL_TexFormat
|
||||||
{
|
{
|
||||||
size_t bpp;
|
size_t bpp;
|
||||||
|
|
Loading…
Reference in a new issue