@@ -207,8 +207,6 @@ _gl_average_texture_color(backend_t *base, GLuint source_texture, GLuint destina
207207 const int to_width = from_width > max_width ? from_width / 2 : from_width ;
208208 const int to_height = from_height > max_height ? from_height / 2 : from_height ;
209209
210- glViewport (0 , 0 , width , height );
211-
212210 // Prepare coordinates
213211 GLint coord [] = {
214212 // top left
@@ -238,6 +236,7 @@ _gl_average_texture_color(backend_t *base, GLuint source_texture, GLuint destina
238236 glBindTexture (GL_TEXTURE_2D , source_texture );
239237
240238 // Render into framebuffer
239+ glViewport (0 , 0 , width , height );
241240 glDrawElements (GL_TRIANGLES , 6 , GL_UNSIGNED_INT , NULL );
242241
243242 // Have we downscaled enough?
@@ -395,7 +394,6 @@ static void _gl_compose(backend_t *base, struct gl_image *img, GLuint target,
395394 // x, y, width, height, dx, dy, ptex->width, ptex->height, z);
396395
397396 // Bind texture
398- glViewport (0 , 0 , gd -> width , gd -> height );
399397 glActiveTexture (GL_TEXTURE1 );
400398 glBindTexture (GL_TEXTURE_2D , brightness );
401399 glActiveTexture (GL_TEXTURE0 );
@@ -419,6 +417,7 @@ static void _gl_compose(backend_t *base, struct gl_image *img, GLuint target,
419417 glVertexAttribPointer (vert_in_texcoord_loc , 2 , GL_INT , GL_FALSE ,
420418 sizeof (GLint ) * 4 , (void * )(sizeof (GLint ) * 2 ));
421419 glBindFramebuffer (GL_DRAW_FRAMEBUFFER , target );
420+ glViewport (0 , 0 , gd -> vp_width , gd -> vp_height );
422421 glDrawElements (GL_TRIANGLES , nrects * 6 , GL_UNSIGNED_INT , NULL );
423422 glDisableVertexAttribArray (vert_coord_loc );
424423 glDisableVertexAttribArray (vert_in_texcoord_loc );
@@ -556,33 +555,6 @@ bool gl_blur(backend_t *base, double opacity, void *ctx, const region_t *reg_blu
556555 glBindTexture (GL_TEXTURE_2D , bctx -> blur_texture [1 ]);
557556 glTexImage2D (GL_TEXTURE_2D , 0 , GL_RGBA8 , bctx -> texture_width ,
558557 bctx -> texture_height , 0 , GL_BGRA , GL_UNSIGNED_BYTE , NULL );
559-
560- // XXX: do we need projection matrix for blur at all?
561- // Note: OpenGL matrices are column major
562- GLfloat projection_matrix [4 ][4 ] = {
563- {2.0f / (GLfloat )bctx -> texture_width , 0 , 0 , 0 },
564- {0 , 2.0f / (GLfloat )bctx -> texture_height , 0 , 0 },
565- {0 , 0 , 0 , 0 },
566- {-1 , -1 , 0 , 1 }};
567-
568- // Update projection matrices in the blur shaders
569- for (int i = 0 ; i < bctx -> npasses - 1 ; i ++ ) {
570- assert (bctx -> blur_shader [i ].prog );
571- glUseProgram (bctx -> blur_shader [i ].prog );
572- int pml = glGetUniformLocationChecked (bctx -> blur_shader [i ].prog ,
573- "projection" );
574- glUniformMatrix4fv (pml , 1 , false, projection_matrix [0 ]);
575- }
576-
577- GLfloat projection_matrix2 [4 ][4 ] = {{2.0f / (GLfloat )gd -> width , 0 , 0 , 0 },
578- {0 , 2.0f / (GLfloat )gd -> height , 0 , 0 },
579- {0 , 0 , 0 , 0 },
580- {-1 , -1 , 0 , 1 }};
581- assert (bctx -> blur_shader [bctx -> npasses - 1 ].prog );
582- glUseProgram (bctx -> blur_shader [bctx -> npasses - 1 ].prog );
583- int pml = glGetUniformLocationChecked (
584- bctx -> blur_shader [bctx -> npasses - 1 ].prog , "projection" );
585- glUniformMatrix4fv (pml , 1 , false, projection_matrix2 [0 ]);
586558 }
587559
588560 // Remainder: regions are in Xorg coordinates
@@ -689,18 +661,17 @@ bool gl_blur(backend_t *base, double opacity, void *ctx, const region_t *reg_blu
689661 // translate the render origin so we don't need a big texture
690662 glUniform2f (p -> orig_loc , - (GLfloat )extent_resized -> x1 ,
691663 - (GLfloat )dst_y_resized_fb_coord );
692- glViewport (0 , 0 , bctx -> texture_width , bctx -> texture_height );
693664 } else {
694665 // last pass, draw directly into the back buffer, with origin
695666 // regions
696667 glBindVertexArray (vao [0 ]);
697668 glBindFramebuffer (GL_FRAMEBUFFER , gd -> back_fbo );
698669 glUniform1f (p -> unifm_opacity , (float )opacity );
699670 glUniform2f (p -> orig_loc , 0 , 0 );
700- glViewport (0 , 0 , gd -> width , gd -> height );
701671 }
702672
703673 glUniform2f (p -> texorig_loc , (GLfloat )texorig_x , (GLfloat )texorig_y );
674+ glViewport (0 , 0 , gd -> vp_width , gd -> vp_height );
704675 glDrawElements (GL_TRIANGLES , nrects * 6 , GL_UNSIGNED_INT , NULL );
705676
706677 // XXX use multiple draw calls is probably going to be slow than
@@ -782,29 +753,8 @@ void gl_resize(struct gl_data *gd, int width, int height) {
782753 gd -> height = height ;
783754 gd -> width = width ;
784755
785- // XXX: do we need projection matrix at all?
786- // Note: OpenGL matrices are column major
787- GLfloat projection_matrix [4 ][4 ] = {{2.0f / (GLfloat )width , 0 , 0 , 0 },
788- {0 , 2.0f / (GLfloat )height , 0 , 0 },
789- {0 , 0 , 0 , 0 },
790- {-1 , -1 , 0 , 1 }};
791-
792- // Update projection matrix in the win shader
793- glUseProgram (gd -> win_shader .prog );
794- int pml = glGetUniformLocationChecked (gd -> win_shader .prog , "projection" );
795- glUniformMatrix4fv (pml , 1 , false, projection_matrix [0 ]);
796-
797- glUseProgram (gd -> fill_shader .prog );
798- pml = glGetUniformLocationChecked (gd -> fill_shader .prog , "projection" );
799- glUniformMatrix4fv (pml , 1 , false, projection_matrix [0 ]);
800-
801- glUseProgram (gd -> present_prog );
802- pml = glGetUniformLocationChecked (gd -> present_prog , "projection" );
803- glUniformMatrix4fv (pml , 1 , false, projection_matrix [0 ]);
804-
805- glUseProgram (gd -> brightness_shader .prog );
806- pml = glGetUniformLocationChecked (gd -> brightness_shader .prog , "projection" );
807- glUniformMatrix4fv (pml , 1 , false, projection_matrix [0 ]);
756+ assert (gd -> vp_width >= gd -> width );
757+ assert (gd -> vp_height >= gd -> height );
808758
809759 glBindTexture (GL_TEXTURE_2D , gd -> back_texture );
810760 glTexImage2D (GL_TEXTURE_2D , 0 , GL_RGB8 , width , height , 0 , GL_BGR ,
@@ -903,7 +853,10 @@ static void _gl_fill(backend_t *base, struct color c, const region_t *clip, GLui
903853 glVertexAttribPointer (fill_vert_in_coord_loc , 2 , GL_INT , GL_FALSE ,
904854 sizeof (* coord ) * 2 , (void * )0 );
905855 glBindFramebuffer (GL_DRAW_FRAMEBUFFER , target );
856+
857+ glViewport (0 , 0 , gd -> vp_width , gd -> vp_height );
906858 glDrawElements (GL_TRIANGLES , nrects * 6 , GL_UNSIGNED_INT , NULL );
859+
907860 glBindFramebuffer (GL_DRAW_FRAMEBUFFER , 0 );
908861 glBindBuffer (GL_ARRAY_BUFFER , 0 );
909862 glBindBuffer (GL_ELEMENT_ARRAY_BUFFER , 0 );
@@ -1004,6 +957,14 @@ void *gl_create_blur_context(backend_t *base, enum blur_method method, void *arg
1004957 return ctx ;
1005958 }
1006959
960+ // Set projection matrix to gl viewport dimensions so we can use screen
961+ // coordinates for all vertices
962+ // Note: OpenGL matrices are column major
963+ GLfloat projection_matrix [4 ][4 ] = {{2.0f / (GLfloat )gd -> vp_width , 0 , 0 , 0 },
964+ {0 , 2.0f / (GLfloat )gd -> vp_height , 0 , 0 },
965+ {0 , 0 , 0 , 0 },
966+ {-1 , -1 , 0 , 1 }};
967+
1007968 ctx -> blur_shader = ccalloc (max2 (2 , nkernels ), gl_blur_shader_t );
1008969
1009970 char * lc_numeric_old = strdup (setlocale (LC_NUMERIC , NULL ));
@@ -1083,6 +1044,13 @@ void *gl_create_blur_context(backend_t *base, enum blur_method method, void *arg
10831044 pass -> unifm_opacity = glGetUniformLocationChecked (pass -> prog , "opacity" );
10841045 pass -> orig_loc = glGetUniformLocationChecked (pass -> prog , "orig" );
10851046 pass -> texorig_loc = glGetUniformLocationChecked (pass -> prog , "texorig" );
1047+
1048+ // Setup projection matrix
1049+ glUseProgram (pass -> prog );
1050+ int pml = glGetUniformLocationChecked (pass -> prog , "projection" );
1051+ glUniformMatrix4fv (pml , 1 , false, projection_matrix [0 ]);
1052+ glUseProgram (0 );
1053+
10861054 ctx -> resize_width += kern -> w / 2 ;
10871055 ctx -> resize_height += kern -> h / 2 ;
10881056 }
@@ -1095,6 +1063,13 @@ void *gl_create_blur_context(backend_t *base, enum blur_method method, void *arg
10951063 pass -> unifm_opacity = -1 ;
10961064 pass -> orig_loc = glGetUniformLocationChecked (pass -> prog , "orig" );
10971065 pass -> texorig_loc = glGetUniformLocationChecked (pass -> prog , "texorig" );
1066+
1067+ // Setup projection matrix
1068+ glUseProgram (pass -> prog );
1069+ int pml = glGetUniformLocationChecked (pass -> prog , "projection" );
1070+ glUniformMatrix4fv (pml , 1 , false, projection_matrix [0 ]);
1071+ glUseProgram (0 );
1072+
10981073 ctx -> npasses = 2 ;
10991074 } else {
11001075 ctx -> npasses = nkernels ;
@@ -1200,7 +1175,17 @@ bool gl_init(struct gl_data *gd, session_t *ps) {
12001175 glStencilMask (0x1 );
12011176 glStencilFunc (GL_EQUAL , 0x1 , 0x1 );
12021177
1178+ // Set gl viewport to the maximum supported size so we won't have to worry about
1179+ // it later on when the screen is resized. The corresponding projection matrix can
1180+ // be set now and won't have to be updated. Since fragments outside the target
1181+ // buffer are skipped anyways, this should have no impact on performance.
1182+ GLint viewport_dimensions [2 ];
1183+ glGetIntegerv (GL_MAX_VIEWPORT_DIMS , viewport_dimensions );
1184+ gd -> vp_height = viewport_dimensions [0 ];
1185+ gd -> vp_width = viewport_dimensions [1 ];
1186+
12031187 // Clear screen
1188+ glViewport (0 , 0 , gd -> vp_height , gd -> vp_width );
12041189 glClearColor (0.0f , 0.0f , 0.0f , 1.0f );
12051190 glClear (GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
12061191
@@ -1216,17 +1201,37 @@ bool gl_init(struct gl_data *gd, session_t *ps) {
12161201 glTexParameteri (GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST );
12171202 glBindTexture (GL_TEXTURE_2D , 0 );
12181203
1204+ // Set projection matrix to gl viewport dimensions so we can use screen
1205+ // coordinates for all vertices
1206+ // Note: OpenGL matrices are column major
1207+ GLfloat projection_matrix [4 ][4 ] = {{2.0f / (GLfloat )gd -> vp_width , 0 , 0 , 0 },
1208+ {0 , 2.0f / (GLfloat )gd -> vp_height , 0 , 0 },
1209+ {0 , 0 , 0 , 0 },
1210+ {-1 , -1 , 0 , 1 }};
1211+
1212+ // Initialize shaders
12191213 gl_win_shader_from_string (vertex_shader , win_shader_glsl , & gd -> win_shader );
1214+ int pml = glGetUniformLocationChecked (gd -> win_shader .prog , "projection" );
1215+ glUseProgram (gd -> win_shader .prog );
1216+ glUniformMatrix4fv (pml , 1 , false, projection_matrix [0 ]);
1217+ glUseProgram (0 );
1218+
12201219 gd -> fill_shader .prog = gl_create_program_from_str (fill_vert , fill_frag );
12211220 gd -> fill_shader .color_loc = glGetUniformLocation (gd -> fill_shader .prog , "color" );
1221+ pml = glGetUniformLocationChecked (gd -> fill_shader .prog , "projection" );
1222+ glUseProgram (gd -> fill_shader .prog );
1223+ glUniformMatrix4fv (pml , 1 , false, projection_matrix [0 ]);
1224+ glUseProgram (0 );
12221225
12231226 gd -> present_prog = gl_create_program_from_str (present_vertex_shader , dummy_frag );
12241227 if (!gd -> present_prog ) {
12251228 log_error ("Failed to create the present shader" );
12261229 return false;
12271230 }
1231+ pml = glGetUniformLocationChecked (gd -> present_prog , "projection" );
12281232 glUseProgram (gd -> present_prog );
12291233 glUniform1i (glGetUniformLocationChecked (gd -> present_prog , "tex" ), 0 );
1234+ glUniformMatrix4fv (pml , 1 , false, projection_matrix [0 ]);
12301235 glUseProgram (0 );
12311236
12321237 gd -> brightness_shader .prog =
@@ -1235,12 +1240,13 @@ bool gl_init(struct gl_data *gd, session_t *ps) {
12351240 log_error ("Failed to create the brightness shader" );
12361241 return false;
12371242 }
1243+ pml = glGetUniformLocationChecked (gd -> brightness_shader .prog , "projection" );
12381244 glUseProgram (gd -> brightness_shader .prog );
12391245 glUniform1i (glGetUniformLocationChecked (gd -> brightness_shader .prog , "tex" ), 0 );
1246+ glUniformMatrix4fv (pml , 1 , false, projection_matrix [0 ]);
12401247 glUseProgram (0 );
12411248
1242- // Set up the size of the viewport. We do this last because it expects the blur
1243- // textures are already set up.
1249+ // Set up the size of the back texture
12441250 gl_resize (gd , ps -> root_width , ps -> root_height );
12451251
12461252 glBindFramebuffer (GL_DRAW_FRAMEBUFFER , gd -> back_fbo );
@@ -1320,6 +1326,8 @@ static inline void gl_image_decouple(backend_t *base, struct gl_image *img) {
13201326 glFramebufferTexture2D (GL_DRAW_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D ,
13211327 new_tex -> texture , 0 );
13221328 glDrawBuffer (GL_COLOR_ATTACHMENT0 );
1329+
1330+ glViewport (0 , 0 , gd -> vp_height , gd -> vp_width );
13231331 glClearColor (0 , 0 , 0 , 0 );
13241332 glClear (GL_COLOR_BUFFER_BIT );
13251333
@@ -1395,7 +1403,6 @@ void gl_present(backend_t *base, const region_t *region) {
13951403 sizeof (GLuint ) * 6 );
13961404 }
13971405
1398- glViewport (0 , 0 , gd -> width , gd -> height );
13991406 glUseProgram (gd -> present_prog );
14001407 glBindTexture (GL_TEXTURE_2D , gd -> back_texture );
14011408
@@ -1413,6 +1420,7 @@ void gl_present(backend_t *base, const region_t *region) {
14131420 GL_STREAM_DRAW );
14141421
14151422 glVertexAttribPointer (vert_coord_loc , 2 , GL_INT , GL_FALSE , sizeof (GLint ) * 2 , NULL );
1423+ glViewport (0 , 0 , gd -> vp_width , gd -> vp_height );
14161424 glDrawElements (GL_TRIANGLES , nrects * 6 , GL_UNSIGNED_INT , NULL );
14171425
14181426 glBindBuffer (GL_ARRAY_BUFFER , 0 );
0 commit comments