diff options
author | marha <marha@users.sourceforge.net> | 2014-04-13 14:24:56 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2014-04-13 14:24:56 +0200 |
commit | d2ad10d03be8e6d4b150bbdf2a28ea3d5a18a2ed (patch) | |
tree | 2a860c9d687826b3cb48facfa21c616e14e69347 /xorg-server/glamor/glamor_transfer.c | |
parent | edb5b380994125bf33929ef7dc5a3c456dfbe93b (diff) | |
download | vcxsrv-d2ad10d03be8e6d4b150bbdf2a28ea3d5a18a2ed.tar.gz vcxsrv-d2ad10d03be8e6d4b150bbdf2a28ea3d5a18a2ed.tar.bz2 vcxsrv-d2ad10d03be8e6d4b150bbdf2a28ea3d5a18a2ed.zip |
fontconfig libxcb mesa xserver xcb-proto git update 13 Apr 2014
xserver commit 3028ae6c9aa37168e249e0d847b29f8e3efb05b2
libxcb commit 29e419c5840a1eeda3336a0802686ee723dcaab3
libxcb/xcb-proto commit 70fea02b7d90d86e9d3b0dc5b61406bf4c910999
pixman commit 4b76bbfda670f9ede67d0449f3640605e1fc4df0
fontconfig commit f44157c809d280e2a0ce87fb078fc4b278d24a67
mesa commit 936dda08ee6d7b2be2b016bc06780e401088ec13
Diffstat (limited to 'xorg-server/glamor/glamor_transfer.c')
-rw-r--r-- | xorg-server/glamor/glamor_transfer.c | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/xorg-server/glamor/glamor_transfer.c b/xorg-server/glamor/glamor_transfer.c new file mode 100644 index 000000000..0378bb076 --- /dev/null +++ b/xorg-server/glamor/glamor_transfer.c @@ -0,0 +1,264 @@ +/* + * Copyright © 2014 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include "glamor_priv.h" +#include "glamor_transfer.h" + +/* XXX a kludge for now */ +void +glamor_format_for_pixmap(PixmapPtr pixmap, GLenum *format, GLenum *type) +{ + switch (pixmap->drawable.depth) { + case 24: + case 32: + *format = GL_BGRA; + *type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + case 16: + *format = GL_RGB; + *type = GL_UNSIGNED_SHORT_5_6_5; + break; + case 15: + *format = GL_BGRA; + *type = GL_UNSIGNED_SHORT_1_5_5_5_REV; + break; + case 8: + *format = GL_ALPHA; + *type = GL_UNSIGNED_BYTE; + break; + default: + FatalError("Invalid pixmap depth %d\n", pixmap->drawable.depth); + break; + } +} + +/* + * Write a region of bits into a pixmap + */ +void +glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, + int dx_src, int dy_src, + int dx_dst, int dy_dst, + uint8_t *bits, uint32_t byte_stride) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); + int box_x, box_y; + int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3; + GLenum type; + GLenum format; + + glamor_format_for_pixmap(pixmap, &format, &type); + + glamor_get_context(glamor_priv); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glPixelStorei(GL_UNPACK_ROW_LENGTH, byte_stride / bytes_per_pixel); + + glamor_pixmap_loop(priv, box_x, box_y) { + BoxPtr box = glamor_pixmap_box_at(priv, box_x, box_y); + glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_x, box_y); + BoxPtr boxes = in_boxes; + int nbox = in_nbox; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, fbo->tex); + + while (nbox--) { + + /* compute drawable coordinates */ + int x1 = boxes->x1 + dx_dst; + int x2 = boxes->x2 + dx_dst; + int y1 = boxes->y1 + dy_dst; + int y2 = boxes->y2 + dy_dst; + + boxes++; + + if (x1 < box->x1) + x1 = box->x1; + if (box->x2 < x2) + x2 = box->x2; + + if (x2 <= x1) + continue; + + if (y1 < box->y1) + y1 = box->y1; + if (box->y2 < y2) + y2 = box->y2; + + if (y2 <= y1) + continue; + + glPixelStorei(GL_UNPACK_SKIP_ROWS, y1 - dy_dst + dy_src); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1 - dx_dst + dx_src); + + glTexSubImage2D(GL_TEXTURE_2D, 0, + x1 - box->x1, y1 - box->y1, + x2 - x1, y2 - y1, + format, type, + bits); + } + } + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glamor_put_context(glamor_priv); +} + +/* + * Upload a region of data + */ + +void +glamor_upload_region(PixmapPtr pixmap, RegionPtr region, + int region_x, int region_y, + uint8_t *bits, uint32_t byte_stride) +{ + glamor_upload_boxes(pixmap, RegionRects(region), RegionNumRects(region), + -region_x, -region_y, + 0, 0, + bits, byte_stride); +} + +/* + * Take the data in the pixmap and stuff it back into the FBO + */ +void +glamor_upload_pixmap(PixmapPtr pixmap) +{ + BoxRec box; + + box.x1 = 0; + box.x2 = pixmap->drawable.width; + box.y1 = 0; + box.y2 = pixmap->drawable.height; + glamor_upload_boxes(pixmap, &box, 1, 0, 0, 0, 0, + pixmap->devPrivate.ptr, pixmap->devKind); +} + +/* + * Read stuff from the pixmap FBOs and write to memory + */ +void +glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox, + int dx_src, int dy_src, + int dx_dst, int dy_dst, + uint8_t *bits, uint32_t byte_stride) +{ + ScreenPtr screen = pixmap->drawable.pScreen; + glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); + glamor_pixmap_private *priv = glamor_get_pixmap_private(pixmap); + int box_x, box_y; + int bytes_per_pixel = pixmap->drawable.bitsPerPixel >> 3; + GLenum type; + GLenum format; + + glamor_format_for_pixmap(pixmap, &format, &type); + + glamor_get_context(glamor_priv); + + glPixelStorei(GL_PACK_ALIGNMENT, 4); + glPixelStorei(GL_PACK_ROW_LENGTH, byte_stride / bytes_per_pixel); + + glamor_pixmap_loop(priv, box_x, box_y) { + BoxPtr box = glamor_pixmap_box_at(priv, box_x, box_y); + glamor_pixmap_fbo *fbo = glamor_pixmap_fbo_at(priv, box_x, box_y); + BoxPtr boxes = in_boxes; + int nbox = in_nbox; + + glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->fb); + + while (nbox--) { + + /* compute drawable coordinates */ + int x1 = boxes->x1 + dx_src; + int x2 = boxes->x2 + dx_src; + int y1 = boxes->y1 + dy_src; + int y2 = boxes->y2 + dy_src; + + boxes++; + + if (x1 < box->x1) + x1 = box->x1; + if (box->x2 < x2) + x2 = box->x2; + + if (y1 < box->y1) + y1 = box->y1; + if (box->y2 < y2) + y2 = box->y2; + + if (x2 <= x1) + continue; + if (y2 <= y1) + continue; + + glPixelStorei(GL_PACK_SKIP_PIXELS, x1 - dx_src + dx_dst); + glPixelStorei(GL_PACK_SKIP_ROWS, y1 - dy_src + dy_dst); + glReadPixels(x1 - box->x1, y1 - box->y1, x2 - x1, y2 - y1, format, type, bits); + } + } + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + glPixelStorei(GL_PACK_SKIP_ROWS, 0); + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + glamor_put_context(glamor_priv); +} + +/* + * Read data from the pixmap FBO + */ +void +glamor_download_rect(PixmapPtr pixmap, int x, int y, int w, int h, uint8_t *bits) +{ + BoxRec box; + + box.x1 = x; + box.x2 = x + w; + box.y1 = y; + box.y2 = y + h; + + glamor_download_boxes(pixmap, &box, 1, 0, 0, -x, -y, + bits, PixmapBytePad(w, pixmap->drawable.depth)); +} + +/* + * Pull the data from the FBO down to the pixmap + */ +void +glamor_download_pixmap(PixmapPtr pixmap) +{ + BoxRec box; + + box.x1 = 0; + box.x2 = pixmap->drawable.width; + box.y1 = 0; + box.y2 = pixmap->drawable.height; + + glamor_download_boxes(pixmap, &box, 1, 0, 0, 0, 0, + pixmap->devPrivate.ptr, pixmap->devKind); +} |