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; }
static void glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, int x, int y, int w, int h, int left_pad, int image_format, char *bits) { ScreenPtr screen = drawable->pScreen; PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); float fg[4], bg[4]; GLuint tex; unsigned int stride = PixmapBytePad(1, w + left_pad); RegionPtr clip; BoxPtr box; int nbox; float dest_coords[8]; const float bitmap_coords[8] = { 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, }; GLfloat xscale, yscale; glamor_pixmap_private *pixmap_priv; pixmap_priv = glamor_get_pixmap_private(pixmap); pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); glamor_set_normalize_vcoords(xscale, yscale, x, y, x + w, y + h, glamor_priv->yInverted, dest_coords); glamor_fallback("glamor_put_image_xybitmap: disabled\n"); goto fail; if (glamor_priv->put_image_xybitmap_prog == 0) { ErrorF("no program for xybitmap putimage\n"); goto fail; } glamor_set_alu(gc->alu); if (!glamor_set_planemask(pixmap, gc->planemask)) goto fail; dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog); glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg); dispatch->glUniform4fv (glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg); glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg); dispatch->glUniform4fv (glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg); dispatch->glGenTextures(1, &tex); dispatch->glActiveTexture(GL_TEXTURE0); dispatch->glBindTexture(GL_TEXTURE_2D, tex); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8); dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad); dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits); dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); /* Now that we've set up our bitmap texture and the shader, shove * the destination rectangle through the cliprects and run the * shader on the resulting fragments. */ dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords); dispatch->glEnableClientState(GL_VERTEX_ARRAY); dispatch->glClientActiveTexture(GL_TEXTURE0); dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords); dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY); dispatch->glEnable(GL_SCISSOR_TEST); clip = fbGetCompositeClip(gc); for (nbox = REGION_NUM_RECTS(clip), box = REGION_RECTS(clip); nbox--; box++) { int x1 = x; int y1 = y; int x2 = x + w; int y2 = y + h; if (x1 < box->x1) x1 = box->x1; if (y1 < box->y1) y1 = box->y1; if (x2 > box->x2) x2 = box->x2; if (y2 > box->y2) y2 = box->y2; if (x1 >= x2 || y1 >= y2) continue; dispatch->glScissor(box->x1, y_flip(pixmap, box->y1), box->x2 - box->x1, box->y2 - box->y1); dispatch->glDrawArrays(GL_QUADS, 0, 4); } dispatch->glDisable(GL_SCISSOR_TEST); glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); dispatch->glDeleteTextures(1, &tex); dispatch->glDisableClientState(GL_VERTEX_ARRAY); dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY); return; glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); glamor_fallback(": to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); fail: if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && glamor_prepare_access_gc(gc)) { fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits); } glamor_finish_access_gc(gc); glamor_finish_access(drawable); }
static void _glamor_tile(PixmapPtr pixmap, PixmapPtr tile, int x, int y, int width, int height, int tile_x, int tile_y) { ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); int x1 = x; int x2 = x + width; int y1 = y; int y2 = y + height; int tile_x1 = tile_x; int tile_x2 = tile_x + width; int tile_y1 = tile_y; int tile_y2 = tile_y + height; float vertices[8]; float source_texcoords[8]; GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale; glamor_pixmap_private *src_pixmap_priv; glamor_pixmap_private *dst_pixmap_priv; float wh[4]; src_pixmap_priv = glamor_get_pixmap_private(tile); dst_pixmap_priv = glamor_get_pixmap_private(pixmap); glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); glamor_make_current(glamor_priv); glUseProgram(glamor_priv->tile_prog); glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv); glUniform2fv(glamor_priv->tile_wh, 1, wh); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glamor_set_repeat_normalize_tcoords (src_pixmap_priv, RepeatNormal, src_xscale, src_yscale, tile_x1, tile_y1, tile_x2, tile_y2, glamor_priv->yInverted, source_texcoords); glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), source_texcoords); glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale, dst_yscale, x1, y1, x2, y2, glamor_priv->yInverted, vertices); glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); glEnableVertexAttribArray(GLAMOR_VERTEX_POS); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); glDisableVertexAttribArray(GLAMOR_VERTEX_POS); glamor_priv->state = RENDER_STATE; glamor_priv->render_idle_cnt = 0; }
static Bool glamor_copy_n_to_n_textured(DrawablePtr src, DrawablePtr dst, GCPtr gc, BoxPtr box, int nbox, int dx, int dy) { glamor_screen_private *glamor_priv = glamor_get_screen_private(dst->pScreen); glamor_gl_dispatch *dispatch; PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src); PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst); int i; float vertices[8], texcoords[8]; glamor_pixmap_private *src_pixmap_priv; glamor_pixmap_private *dst_pixmap_priv; int src_x_off, src_y_off, dst_x_off, dst_y_off; GLfloat dst_xscale, dst_yscale, src_xscale, src_yscale; src_pixmap_priv = glamor_get_pixmap_private(src_pixmap); dst_pixmap_priv = glamor_get_pixmap_private(dst_pixmap); glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off); glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off); if (!src_pixmap_priv->base.gl_fbo) { /* Optimize when the source doesn't have an FBO, just upload the data directly to the dest FBO */ int src_stride = src_pixmap->devKind; int bpp = src_pixmap->drawable.bitsPerPixel; void *src_data = NULL; if (src->bitsPerPixel != dst->bitsPerPixel) { DEBUGF("Non-matching bpp\n"); return FALSE; } if (src->bitsPerPixel < 8) { DEBUGF("bpp < 8\n"); return FALSE; } if (gc && !(gc->alu == GXcopy && glamor_pm_is_solid(src, gc->planemask))) { DEBUGF("non gxcopy and solid\n"); return FALSE; } for (i = 0; i < nbox; i++) { int x = box[i].x1 + dst_x_off; int y = box[i].y1 + dst_y_off; int w = box[i].x2 - box[i].x1; int h = box[i].y2 - box[i].y1; src_data = (char *)src_pixmap->devPrivate.ptr + (box[i].y1 + dy + src_y_off) * src_stride + (box[i].x1 + dx + src_x_off) * (bpp / 8); if (!glamor_upload_sub_pixmap_to_texture(dst_pixmap, x, y, w, h, src_stride, src_data, 0)) { ErrorF("Failed to upload the sub pixmap to dst\n"); return FALSE; } } return TRUE; } pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale); pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale); dispatch = glamor_get_dispatch(glamor_priv); glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv); dispatch->glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), vertices); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_POS); dx += src_x_off; dy += src_y_off; dispatch->glActiveTexture(GL_TEXTURE0); dispatch->glBindTexture(GL_TEXTURE_2D, src_pixmap_priv->base.fbo->tex); #ifndef GLAMOR_GLES2 dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); #endif dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); dispatch->glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), texcoords); dispatch->glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE); dispatch->glUseProgram(glamor_priv->finish_access_prog[0]); dispatch->glUniform1i(glamor_priv->finish_access_revert[0], REVERT_NONE); dispatch->glUniform1i(glamor_priv->finish_access_swap_rb[0], SWAP_NONE_UPLOADING); for (i = 0; i < nbox; i++) { glamor_set_normalize_vcoords(dst_pixmap_priv, dst_xscale, dst_yscale, box[i].x1 + dst_x_off, box[i].y1 + dst_y_off, box[i].x2 + dst_x_off, box[i].y2 + dst_y_off, glamor_priv->yInverted, vertices); glamor_set_normalize_tcoords(src_pixmap_priv, src_xscale, src_yscale, box[i].x1 + dx, box[i].y1 + dy, box[i].x2 + dx, box[i].y2 + dy, glamor_priv->yInverted, texcoords); dispatch->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS); dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE); /* The source texture is bound to a fbo, we have to flush it here. */ glamor_put_dispatch(glamor_priv); glamor_priv->state = RENDER_STATE; glamor_priv->render_idle_cnt = 0; return TRUE; }