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