glamor_image.c revision 35c4bbdf
1/* 2 * Copyright © 2014 Keith Packard 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that copyright 7 * notice and this permission notice appear in supporting documentation, and 8 * that the name of the copyright holders not be used in advertising or 9 * publicity pertaining to distribution of the software without specific, 10 * written prior permission. The copyright holders make no representations 11 * about the suitability of this software for any purpose. It is provided "as 12 * is" without express or implied warranty. 13 * 14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 * OF THIS SOFTWARE. 21 */ 22 23#include "glamor_priv.h" 24#include "glamor_transfer.h" 25#include "glamor_transform.h" 26 27/* 28 * PutImage. Only does ZPixmap right now as other formats are quite a bit harder 29 */ 30 31static Bool 32glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, 33 int w, int h, int leftPad, int format, char *bits) 34{ 35 ScreenPtr screen = drawable->pScreen; 36 glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); 37 PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); 38 glamor_pixmap_private *pixmap_priv; 39 uint32_t byte_stride = PixmapBytePad(w, drawable->depth); 40 RegionRec region; 41 BoxRec box; 42 int off_x, off_y; 43 44 pixmap_priv = glamor_get_pixmap_private(pixmap); 45 46 if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) 47 return FALSE; 48 49 if (gc->alu != GXcopy) 50 goto bail; 51 52 if (!glamor_pm_is_solid(gc->depth, gc->planemask)) 53 goto bail; 54 55 if (format == XYPixmap && drawable->depth == 1 && leftPad == 0) 56 format = ZPixmap; 57 58 if (format != ZPixmap) 59 goto bail; 60 61 x += drawable->x; 62 y += drawable->y; 63 box.x1 = x; 64 box.y1 = y; 65 box.x2 = box.x1 + w; 66 box.y2 = box.y1 + h; 67 RegionInit(®ion, &box, 1); 68 RegionIntersect(®ion, ®ion, gc->pCompositeClip); 69 70 glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); 71 if (off_x || off_y) { 72 x += off_x; 73 y += off_y; 74 RegionTranslate(®ion, off_x, off_y); 75 } 76 77 glamor_make_current(glamor_priv); 78 79 glamor_upload_region(pixmap, ®ion, x, y, (uint8_t *) bits, byte_stride); 80 81 RegionUninit(®ion); 82 return TRUE; 83bail: 84 return FALSE; 85} 86 87static void 88glamor_put_image_bail(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, 89 int w, int h, int leftPad, int format, char *bits) 90{ 91 if (glamor_prepare_access_box(drawable, GLAMOR_ACCESS_RW, x, y, w, h)) 92 fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits); 93 glamor_finish_access(drawable); 94} 95 96void 97glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, 98 int w, int h, int leftPad, int format, char *bits) 99{ 100 if (glamor_put_image_gl(drawable, gc, depth, x, y, w, h, leftPad, format, bits)) 101 return; 102 glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits); 103} 104 105static Bool 106glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h, 107 unsigned int format, unsigned long plane_mask, char *d) 108{ 109 PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); 110 glamor_pixmap_private *pixmap_priv; 111 uint32_t byte_stride = PixmapBytePad(w, drawable->depth); 112 BoxRec box; 113 int off_x, off_y; 114 115 pixmap_priv = glamor_get_pixmap_private(pixmap); 116 if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) 117 goto bail; 118 119 if (format != ZPixmap || !glamor_pm_is_solid(drawable->depth, plane_mask)) 120 goto bail; 121 122 glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y); 123 box.x1 = x; 124 box.x2 = x + w; 125 box.y1 = y; 126 box.y2 = y + h; 127 glamor_download_boxes(pixmap, &box, 1, 128 drawable->x + off_x, drawable->y + off_y, 129 -x, -y, 130 (uint8_t *) d, byte_stride); 131 return TRUE; 132bail: 133 return FALSE; 134} 135 136static void 137glamor_get_image_bail(DrawablePtr drawable, int x, int y, int w, int h, 138 unsigned int format, unsigned long plane_mask, char *d) 139{ 140 if (glamor_prepare_access_box(drawable, GLAMOR_ACCESS_RO, x, y, w, h)) 141 fbGetImage(drawable, x, y, w, h, format, plane_mask, d); 142 glamor_finish_access(drawable); 143} 144 145void 146glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h, 147 unsigned int format, unsigned long plane_mask, char *d) 148{ 149 if (glamor_get_image_gl(drawable, x, y, w, h, format, plane_mask, d)) 150 return; 151 glamor_get_image_bail(drawable, x, y, w, h, format, plane_mask, d); 152} 153