glamor_pixmap_fbo * glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h, GLenum format, GLenum type, int no_alpha, int revert, int swap_rb) { glamor_pixmap_private *source_priv; glamor_screen_private *glamor_priv; ScreenPtr screen; glamor_pixmap_fbo *temp_fbo; float temp_xscale, temp_yscale, source_xscale, source_yscale; static float vertices[8]; static float texcoords[8]; screen = source->drawable.pScreen; glamor_priv = glamor_get_screen_private(screen); source_priv = glamor_get_pixmap_private(source); temp_fbo = glamor_create_fbo(glamor_priv, w, h, format, 0); if (temp_fbo == NULL) return NULL; glamor_make_current(glamor_priv); temp_xscale = 1.0 / w; temp_yscale = 1.0 / h; glamor_set_normalize_vcoords((struct glamor_pixmap_private *) NULL, temp_xscale, temp_yscale, 0, 0, w, h, vertices); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); pixmap_priv_get_scale(source_priv, &source_xscale, &source_yscale); glamor_set_normalize_tcoords(source_priv, source_xscale, source_yscale, x, y, x + w, y + h, texcoords); glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), texcoords); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, source_priv->base.fbo->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glamor_set_destination_pixmap_fbo(temp_fbo, 0, 0, w, h); glUseProgram(glamor_priv->finish_access_prog[no_alpha]); glUniform1i(glamor_priv->finish_access_revert[no_alpha], revert); glUniform1i(glamor_priv->finish_access_swap_rb[no_alpha], swap_rb); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); return temp_fbo; }
void glamor_set_destination_pixmap_priv_nc(glamor_pixmap_private *pixmap_priv) { int w, h; PIXMAP_PRIV_GET_ACTUAL_SIZE(pixmap_priv, w, h); glamor_set_destination_pixmap_fbo(pixmap_priv->base.fbo, 0, 0, w, h); }
void glamor_set_destination_drawable(DrawablePtr drawable, int box_index, Bool do_drawable_translate, Bool center_offset, GLint matrix_uniform_location, int *p_off_x, int *p_off_y) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); int off_x, off_y; BoxPtr box = glamor_pixmap_box_at(pixmap_priv, box_index); int w = box->x2 - box->x1; int h = box->y2 - box->y1; float scale_x = 2.0f / (float) w; float scale_y = 2.0f / (float) h; float center_adjust = 0.0f; glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); off_x -= box->x1; off_y -= box->y1; if (p_off_x) { *p_off_x = off_x; *p_off_y = off_y; } /* A tricky computation to find the right value for the two linear functions * that transform rendering coordinates to pixmap coordinates * * pixmap_x = render_x + drawable->x + off_x * pixmap_y = render_y + drawable->y + off_y * * gl_x = pixmap_x * 2 / width - 1 * gl_y = pixmap_y * 2 / height - 1 * * gl_x = (render_x + drawable->x + off_x) * 2 / width - 1 * * gl_x = (render_x) * 2 / width + (drawable->x + off_x) * 2 / width - 1 */ if (do_drawable_translate) { off_x += drawable->x; off_y += drawable->y; } /* * To get GL_POINTS drawn in the right spot, we need to adjust the * coordinates by 1/2 a pixel. */ if (center_offset) center_adjust = 0.5f; glUniform4f(matrix_uniform_location, scale_x, (off_x + center_adjust) * scale_x - 1.0f, scale_y, (off_y + center_adjust) * scale_y - 1.0f); glamor_set_destination_pixmap_fbo(glamor_priv, glamor_pixmap_fbo_at(pixmap_priv, box_index), 0, 0, w, h); }