From ab30a03d243becad3f09305333de518af31a669b Mon Sep 17 00:00:00 2001 From: oldosfan Date: Fri, 23 Sep 2022 10:55:29 +0000 Subject: [PATCH] Add support for projective scale transforms to EGL renderer * egl.c (struct _EglBuffer): New field `scale'. Save the projective scale here. (struct _CompositeProgram): New field `scale'. Save the index of new uniform here. (EglCompileCompositeProgram): Fetch location of new uniform. (ApplyTransform): Set scale. (Composite): Apply value of new uniform. (BufferFromDmaBuf, BufferFromShm): Initialize scale to 0. (UpdateBufferForDamage): Scale damage if it and damage are set. * shaders.txt (Composite Rectangle Fragment Shader RGBA) (Composite Rectangle Fragment Shader RGBX) (Composite Rectangle Fragment Shader External): New uniform `scale'. (main): Divide texcoord by scale. --- egl.c | 37 ++++++++++++++++++++++++++++++++++--- shaders.txt | 10 +++++++--- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/egl.c b/egl.c index 157f176..a110247 100644 --- a/egl.c +++ b/egl.c @@ -122,6 +122,9 @@ struct _EglBuffer /* The width and height of the buffer. */ int width, height; + /* The projective scale factor. */ + GLfloat scale; + /* Various different buffers. */ union { /* The type of the buffer. */ @@ -174,6 +177,9 @@ struct _CompositeProgram /* The index of the texture uniform. */ GLuint texture; + + /* The index of the scale uniform. */ + GLuint scale; }; /* All known SHM formats. */ @@ -706,6 +712,8 @@ EglCompileCompositeProgram (CompositeProgram *program, "pos"); program->texture = glGetUniformLocation (program->program, "texture"); + program->scale = glGetUniformLocation (program->program, + "scale"); /* Now delete the shaders. */ glDeleteShader (vertex); @@ -1082,7 +1090,10 @@ ClearRectangle (RenderTarget target, int x, int y, int width, int height) static void ApplyTransform (RenderBuffer buffer, double divisor) { - /* TODO... */ + EglBuffer *egl_buffer; + + egl_buffer = buffer.pointer; + egl_buffer->scale = 1.0f / (GLfloat) divisor; } static CompositeProgram * @@ -1198,6 +1209,7 @@ Composite (RenderBuffer buffer, RenderTarget target, glUseProgram (program->program); glUniform1i (program->texture, 0); + glUniform1f (program->scale, egl_buffer->scale); glVertexAttribPointer (program->position, 2, GL_FLOAT, GL_FALSE, 0, verts); glVertexAttribPointer (program->texcoord, 2, GL_FLOAT, @@ -1348,6 +1360,7 @@ BufferFromDmaBuf (DmaBufAttributes *attributes, Bool *error) buffer->texture = EGL_NO_TEXTURE; buffer->width = attributes->width; buffer->height = attributes->height; + buffer->scale = 1.0f; buffer->u.type = DmaBufBuffer; i = 0; @@ -1492,6 +1505,7 @@ BufferFromShm (SharedMemoryAttributes *attributes, Bool *error) buffer->texture = EGL_NO_TEXTURE; buffer->width = attributes->width; buffer->height = attributes->height; + buffer->scale = 1.0f; buffer->u.type = ShmBuffer; /* Record the buffer data. */ @@ -1955,8 +1969,25 @@ UpdateBuffer (RenderBuffer buffer, pixman_region32_t *damage) static void UpdateBufferForDamage (RenderBuffer buffer, pixman_region32_t *damage) { - /* TODO: handle scaling. */ - UpdateBuffer (buffer, damage); + EglBuffer *egl_buffer; + pixman_region32_t region; + + egl_buffer = buffer.pointer; + + if (egl_buffer->scale != 1.0f && damage) + { + /* Scale the damage, specified in scaled coordinates, down to + texture coordinates. */ + + pixman_region32_init (®ion); + XLScaleRegion (®ion, damage, + 1.0f / egl_buffer->scale, + 1.0f / egl_buffer->scale); + UpdateBuffer (buffer, ®ion); + pixman_region32_fini (®ion); + } + else + UpdateBuffer (buffer, damage); } static BufferFuncs egl_buffer_funcs = diff --git a/shaders.txt b/shaders.txt index 452dd3c..09c511b 100644 --- a/shaders.txt +++ b/shaders.txt @@ -43,24 +43,27 @@ main (void) //== Composite Rectangle Fragment Shader RGBA precision mediump float; uniform sampler2D texture; +uniform float scale; varying vec2 v_texcoord; void main (void) { - gl_FragColor = texture2D (texture, v_texcoord); + gl_FragColor = texture2D (texture, v_texcoord / scale); } //== //== Composite Rectangle Fragment Shader RGBX precision mediump float; uniform sampler2D texture; +uniform float scale; varying vec2 v_texcoord; void main (void) { - gl_FragColor = vec4 (texture2D (texture, v_texcoord).rgb, + gl_FragColor = vec4 (texture2D (texture, + v_texcoord / scale).rgb, 1.0); } //== @@ -70,11 +73,12 @@ main (void) precision mediump float; uniform samplerExternalOES texture; +uniform float scale; varying vec2 v_texcoord; void main (void) { - gl_FragColor = texture2D (texture, v_texcoord); + gl_FragColor = texture2D (texture, v_texcoord / scale); } //==