void glw_stencil_quad(glw_root_t *gr, const glw_rctx_t *rc) { glw_backend_root_t *gbr = &gr->gr_be; glw_program_t *gp = gbr->gbr_renderer_flat; glStencilFunc(GL_NEVER, rc->rc_zindex, 0xFF); glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); glStencilMask(0xff); glUseProgram(gp->gp_program); glUniformMatrix4fv(gp->gp_uniform_modelview, 1, 0, glw_mtx_get(rc->rc_mtx)); glBindBuffer(GL_ARRAY_BUFFER, 0); glFrontFace(GL_CCW); const float *vertices = &stencilquad[0][0]; glVertexAttribPointer(0, 4, GL_FLOAT, 0, sizeof(float) * VERTEX_SIZE, vertices); glVertexAttribPointer(1, 4, GL_FLOAT, 0, sizeof(float) * VERTEX_SIZE, vertices + 4); glVertexAttribPointer(2, 4, GL_FLOAT, 0, sizeof(float) * VERTEX_SIZE, vertices + 8); glDrawArrays(GL_TRIANGLES, 0, 6); glUseProgram(0); gbr->gbr_current = NULL; }
void glw_wirebox(glw_root_t *gr, const glw_rctx_t *rc) { glw_backend_root_t *gbr = &gr->gr_be; if(gbr->gbr_delayed_rendering) return; glw_load_program(gbr, NULL); glMatrixMode(GL_PROJECTION); glLoadMatrixf(projection); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(glw_mtx_get(rc->rc_mtx)); glDisable(GL_TEXTURE_2D); glBegin(GL_LINE_LOOP); glColor4f(1,1,1,1); glVertex3f(-1.0, -1.0, 0.0); glVertex3f( 1.0, -1.0, 0.0); glVertex3f( 1.0, 1.0, 0.0); glVertex3f(-1.0, 1.0, 0.0); glEnd(); glEnable(GL_TEXTURE_2D); }
static void hw_set_clip_conf(const struct glw_rctx *rc, int which, const Vec4 v) { double plane[4]; plane[0] = glw_vec4_extract(v, 0); plane[1] = glw_vec4_extract(v, 1); plane[2] = glw_vec4_extract(v, 2); plane[3] = glw_vec4_extract(v, 3); glLoadMatrixf(glw_mtx_get(rc->rc_mtx)); glClipPlane(GL_CLIP_PLANE0 + which, plane); glEnable(GL_CLIP_PLANE0 + which); }
void glw_program_set_modelview(glw_backend_root_t *gbr, const glw_rctx_t *rc) { const float *m = rc ? glw_mtx_get(rc->rc_mtx) : glw_identitymtx; glUniformMatrix4fv(gbr->gbr_current->gp_uniform_modelview, 1, 0, m); }
static void render_unlocked(glw_root_t *gr) { glw_backend_root_t *gbr = &gr->gr_be; render_state_t rs = {0}; int64_t ts = arch_get_ts(); int current_blendmode = GLW_BLEND_NORMAL; glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE); const float *vertices = gr->gr_vertex_buffer; glBindBuffer(GL_ARRAY_BUFFER, gbr->gbr_vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * VERTEX_SIZE * gr->gr_vertex_offset, vertices, GL_STATIC_DRAW); int current_frontface = GLW_CCW; glFrontFace(GL_CCW); vertices = NULL; glVertexAttribPointer(0, 4, GL_FLOAT, 0, sizeof(float) * VERTEX_SIZE, vertices); glVertexAttribPointer(1, 4, GL_FLOAT, 0, sizeof(float) * VERTEX_SIZE, vertices + 4); glVertexAttribPointer(2, 4, GL_FLOAT, 0, sizeof(float) * VERTEX_SIZE, vertices + 8); for(int j = 0; j < gr->gr_num_render_jobs; j++) { const glw_render_order_t *ro = gr->gr_render_order + j; const glw_render_job_t *rj = ro->job; if(unlikely(rj->num_vertices == 0)) continue; const struct glw_backend_texture *t0 = rj->t0; glw_program_t *gp = load_program(gr, t0, rj->t1, rj->blur, rj->flags, rj->gpa, &rs, rj); if(gbr->gbr_use_stencil_buffer) glStencilFunc(GL_GEQUAL, ro->zindex, 0xFF); if(unlikely(gp == NULL)) { #if ENABLE_GLW_BACKEND_OPENGL if(rj->eyespace) { glLoadMatrixf(glw_identitymtx); } else { glLoadMatrixf(glw_mtx_get(rj->m)); } glBegin(GL_QUADS); if(t0 != NULL) glTexCoord2i(0, t0->height); glVertex3i(-1, -1, 0); if(t0 != NULL) glTexCoord2i(t0->width, t0->height); glVertex3i(1, -1, 0); if(t0 != NULL) glTexCoord2i(t0->width, 0); glVertex3i(1, 1, 0); if(t0 != NULL) glTexCoord2i(0, 0); glVertex3i(-1, 1, 0); glEnd(); glDisable(t0->gltype); #endif continue; } else { glUniform4f(gp->gp_uniform_color_offset, rj->rgb_off.r, rj->rgb_off.g, rj->rgb_off.b, 0); glUniform4f(gbr->gbr_current->gp_uniform_color, rj->rgb_mul.r, rj->rgb_mul.g, rj->rgb_mul.b, rj->alpha); if(gp->gp_uniform_time != -1) glUniform1f(gp->gp_uniform_time, gr->gr_time_sec); if(gp->gp_uniform_resolution != -1) glUniform2f(gp->gp_uniform_resolution, rj->width, rj->height); if(gp->gp_uniform_blur != -1 && t0 != NULL) glUniform3f(gp->gp_uniform_blur, rj->blur, 1.5 / t0->width, 1.5 / t0->height); if(rj->eyespace) { glUniformMatrix4fv(gp->gp_uniform_modelview, 1, 0, glw_identitymtx); } else { glUniformMatrix4fv(gp->gp_uniform_modelview, 1, 0, glw_mtx_get(rj->m)); } } if(unlikely(current_blendmode != rj->blendmode)) { current_blendmode = rj->blendmode; switch(current_blendmode) { case GLW_BLEND_NORMAL: glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE); break; case GLW_BLEND_ADDITIVE: glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE, GL_ONE_MINUS_DST_ALPHA, GL_ONE); break; } } if(unlikely(current_frontface != rj->frontface)) { current_frontface = rj->frontface; glFrontFace(current_frontface == GLW_CW ? GL_CW : GL_CCW); } glDrawArrays(rj->primitive_type, rj->vertex_offset, rj->num_vertices); } if(current_blendmode != GLW_BLEND_NORMAL) { glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE, GL_ONE_MINUS_DST_ALPHA, GL_ONE); } ts = arch_get_ts() - ts; static int hold; hold++; if(hold < 20) return; #if 0 static int cnt; static int64_t tssum; tssum += ts; cnt++; printf("%16d (%d) %d saved texloads\n", (int)ts, (int)(tssum/cnt), rs.texload_skips); #endif }
static void vdpau_render(glw_video_t *gv, glw_rctx_t *rc) { glw_root_t *gr = gv->w.glw_root; vdpau_dev_t *vd = gr->gr_be.gbr_vdpau_dev; glw_backend_root_t *gbr = &gv->w.glw_root->gr_be; if(!gv->gv_vdpau_running) return; glDisable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_RECTANGLE_ARB); if(gv->gv_vdpau_texture == 0) { glGenTextures(1, &gv->gv_vdpau_texture); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, gv->gv_vdpau_texture); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { glBindTexture(GL_TEXTURE_RECTANGLE_ARB, gv->gv_vdpau_texture); } gr->gr_be.gbr_bind_tex_image(vd->vd_dpy, gv->gv_glx_pixmap, GLX_FRONT_LEFT_EXT, NULL); #if 0 int w = gv->gv_rwidth - 1; int h = gv->gv_rheight - 1; #else int w = gv->gv_fwidth - 1; int h = gv->gv_fheight - 1; #endif glMatrixMode(GL_PROJECTION); glLoadMatrixf(projmtx); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(glw_mtx_get(rc->rc_mtx)); glw_load_program(gbr, NULL); glColor4f(1,1,1,1); glBegin(GL_QUADS); glTexCoord2f(0, h); glVertex3f(-1.0, -1.0, 0.0); glTexCoord2f(w, h); glVertex3f( 1.0, -1.0, 0.0); glTexCoord2f(w, 0); glVertex3f( 1.0, 1.0, 0.0); glTexCoord2f(0, 0); glVertex3f(-1.0, 1.0, 0.0); glEnd(); gr->gr_be.gbr_release_tex_image(vd->vd_dpy, gv->gv_glx_pixmap, GLX_FRONT_LEFT_EXT); glDisable(GL_TEXTURE_RECTANGLE_ARB); glEnable(GL_TEXTURE_2D); }
static void render_unlocked(glw_root_t *gr) { glw_backend_root_t *gbr = &gr->gr_be; int i; struct render_job *rj = gbr->gbr_render_jobs; int64_t ts = showtime_get_ts(); int current_blendmode = GLW_BLEND_NORMAL; glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); int program_switches = 0; const float *vertices = gbr->gbr_vertex_buffer; glBindBuffer(GL_ARRAY_BUFFER, gbr->gbr_vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * VERTEX_SIZE * gbr->gbr_vertex_offset, vertices, GL_STATIC_DRAW); vertices = NULL; glVertexAttribPointer(0, 4, GL_FLOAT, 0, sizeof(float) * VERTEX_SIZE, vertices); glVertexAttribPointer(1, 4, GL_FLOAT, 0, sizeof(float) * VERTEX_SIZE, vertices + 4); glVertexAttribPointer(2, 4, GL_FLOAT, 0, sizeof(float) * VERTEX_SIZE, vertices + 8); for(i = 0; i < gbr->gbr_num_render_jobs; i++, rj++) { const struct glw_backend_texture *t0 = rj->t0; glw_program_t *gp = get_program(gbr, t0, rj->t1, rj->blur, rj->flags, rj->up); if(gp == NULL) continue; if(glw_load_program(gbr, gp)) { program_switches++; } glUniform4f(gp->gp_uniform_color_offset, rj->rgb_off.r, rj->rgb_off.g, rj->rgb_off.b, 0); glw_program_set_uniform_color(gbr, rj->rgb_mul.r, rj->rgb_mul.g, rj->rgb_mul.b, rj->alpha); if(gp->gp_uniform_time != -1) glUniform1f(gp->gp_uniform_time, gr->gr_time_sec); if(gp->gp_uniform_resolution != -1) glUniform2f(gp->gp_uniform_resolution, rj->width, rj->height); if(gp->gp_uniform_blur != -1 && t0 != NULL) glUniform3f(gp->gp_uniform_blur, rj->blur, 1.5 / t0->width, 1.5 / t0->height); if(rj->eyespace) { glUniformMatrix4fv(gp->gp_uniform_modelview, 1, 0, glw_identitymtx); } else { glUniformMatrix4fv(gp->gp_uniform_modelview, 1, 0, glw_mtx_get(rj->m)); } if(current_blendmode != rj->blendmode) { current_blendmode = rj->blendmode; switch(current_blendmode) { case GLW_BLEND_NORMAL: glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); break; case GLW_BLEND_ADDITIVE: glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE, GL_ONE, GL_ONE); break; } } glDrawArrays(GL_TRIANGLES, rj->vertex_offset, rj->num_vertices); } if(current_blendmode != GLW_BLEND_NORMAL) { glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE, GL_ONE, GL_ONE); } ts = showtime_get_ts() - ts; static int hold; hold++; if(hold < 20) return; static int cnt; static int64_t tssum; tssum += ts; cnt++; // printf("%16d (%d) %d switches\n", (int)ts, (int)(tssum/cnt), program_switches); }
static void render_unlocked(glw_root_t *gr) { glw_backend_root_t *gbr = &gr->gr_be; render_state_t rs = {0}; int64_t ts = arch_get_ts(); int uni_calls = 0; int saved_calls = 0; int current_blendmode = GLW_BLEND_NORMAL; glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE); const float *vertices = gr->gr_vertex_buffer; glBindBuffer(GL_ARRAY_BUFFER, gbr->gbr_vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * VERTEX_SIZE * gr->gr_vertex_offset, vertices, GL_STATIC_DRAW); int current_frontface = GLW_CCW; glFrontFace(GL_CCW); vertices = NULL; glVertexAttribPointer(0, 4, GL_FLOAT, 0, sizeof(float) * VERTEX_SIZE, vertices); glVertexAttribPointer(1, 4, GL_FLOAT, 0, sizeof(float) * VERTEX_SIZE, vertices + 4); glVertexAttribPointer(2, 4, GL_FLOAT, 0, sizeof(float) * VERTEX_SIZE, vertices + 8); for(int j = 0; j < gr->gr_num_render_jobs; j++) { const glw_render_order_t *ro = gr->gr_render_order + j; const glw_render_job_t *rj = ro->job; if(unlikely(rj->num_vertices == 0)) continue; const struct glw_backend_texture *t0 = rj->t0; glw_program_t *gp = load_program(gr, t0, rj->t1, rj->blur, rj->flags, rj->gpa, &rs, rj); if(gbr->gbr_use_stencil_buffer) glStencilFunc(GL_GEQUAL, ro->zindex, 0xFF); if(unlikely(gp == NULL)) { #if ENABLE_GLW_BACKEND_OPENGL if(rj->eyespace) { glLoadMatrixf(glw_identitymtx); } else { glLoadMatrixf(glw_mtx_get(rj->m)); } glBegin(GL_QUADS); if(t0 != NULL) glTexCoord2i(0, t0->height); glVertex3i(-1, -1, 0); if(t0 != NULL) glTexCoord2i(t0->width, t0->height); glVertex3i(1, -1, 0); if(t0 != NULL) glTexCoord2i(t0->width, 0); glVertex3i(1, 1, 0); if(t0 != NULL) glTexCoord2i(0, 0); glVertex3i(-1, 1, 0); glEnd(); glDisable(t0->gltype); #endif continue; } else { if(!glw_rgb_cmp(&gp->gp_current_color_offset, &rj->rgb_off)) { glw_rgb_cpy(&gp->gp_current_color_offset, &rj->rgb_off); glUniform4f(gp->gp_uniform_color_offset, rj->rgb_off.r, rj->rgb_off.g, rj->rgb_off.b, 0); uni_calls++; } else { saved_calls++; } if(!glw_rgb_cmp(&gp->gp_current_color_mul, &rj->rgb_mul) || gp->gp_current_alpha != rj->alpha) { glw_rgb_cpy(&gp->gp_current_color_mul, &rj->rgb_mul); gp->gp_current_alpha = rj->alpha; glUniform4f(gbr->gbr_current->gp_uniform_color, rj->rgb_mul.r, rj->rgb_mul.g, rj->rgb_mul.b, rj->alpha); uni_calls++; } else { saved_calls++; } if(gp->gp_uniform_time != -1) { glUniform1f(gp->gp_uniform_time, gr->gr_time_sec); uni_calls++; } if(gp->gp_uniform_resolution != -1) { glUniform3f(gp->gp_uniform_resolution, rj->width, rj->height, 1); uni_calls++; } if(gp->gp_uniform_blur != -1 && t0 != NULL) { glUniform3f(gp->gp_uniform_blur, rj->blur, 1.5 / t0->width, 1.5 / t0->height); uni_calls++; } if(rj->eyespace) { if(!gp->gp_identity_mvm) { glUniformMatrix4fv(gp->gp_uniform_modelview, 1, 0, glw_identitymtx); gp->gp_identity_mvm = 1; uni_calls++; } else { saved_calls++; } } else { gp->gp_identity_mvm = 0; glUniformMatrix4fv(gp->gp_uniform_modelview, 1, 0, glw_mtx_get(rj->m)); uni_calls++; } } if(unlikely(current_blendmode != rj->blendmode)) { current_blendmode = rj->blendmode; switch(current_blendmode) { case GLW_BLEND_NORMAL: glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE); break; case GLW_BLEND_ADDITIVE: glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE, GL_ONE_MINUS_DST_ALPHA, GL_ONE); break; } } if(unlikely(current_frontface != rj->frontface)) { current_frontface = rj->frontface; glFrontFace(current_frontface == GLW_CW ? GL_CW : GL_CCW); } glDrawElements(rj->primitive_type, rj->num_indices, GL_UNSIGNED_SHORT, gr->gr_index_buffer + rj->index_offset); } if(current_blendmode != GLW_BLEND_NORMAL) { glBlendFuncSeparate(GL_SRC_COLOR, GL_ONE, GL_ONE_MINUS_DST_ALPHA, GL_ONE); } int64_t tse = arch_get_ts(); ts = tse - ts; static int hold; hold++; if(hold < 20) return; #if 0 static int cnt; static int avg; static int acc[16]; avg -= acc[cnt & 0xf]; acc[cnt & 0xf] = ts; avg += acc[cnt & 0xf]; cnt++; int t = avg/16; printf("tt:%-5d jobs:%-4d vertices:%-4d ps:%-3d uniforms:%-4d (%-4d) tpv:%2.2f\n", t, gr->gr_num_render_jobs, gr->gr_vertex_offset, rs.program_switches, uni_calls, saved_calls, (float)t / gr->gr_vertex_offset); #endif }