glamor_putimage.c 3.32 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*
 * Copyright © 2009 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 * Authors:
 *    Eric Anholt <eric@anholt.net>
 *
 */


/** @file glamor_putaimge.c
 *
 * XPutImage implementation
 */
#include "glamor_priv.h"

void
glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
		 int w, int h, int left_pad, int image_format, char *bits)
{
    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
    GLenum type, format;
    RegionPtr clip;
    BoxPtr pbox;
    int nbox;
    int bpp = drawable->bitsPerPixel;
    int src_stride = PixmapBytePad(w, drawable->depth);

47
48
49
50
    if (!glamor_set_destination_pixmap(pixmap)) {
	fbPutImage(drawable, gc, depth, x, y, w, h, left_pad,
		   image_format, bits);
	return;
51
    }
52

53
    if (!glamor_set_planemask(pixmap, gc->planemask))
54
55
56
57
58
59
60
	goto fail;
    if (image_format != ZPixmap) {
	ErrorF("putimage: non-ZPixmap\n");
	goto fail;
    }
    if (bpp < 8) {
	ErrorF("putimage: bad bpp: %d\n", bpp);
61
	goto fail;
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
    }

    switch (drawable->depth) {
    case 8:
	format = GL_ALPHA;
	type = GL_UNSIGNED_BYTE;
	break;
    case 24:
	format = GL_RGB;
	type = GL_UNSIGNED_BYTE;
	break;
    case 32:
	format = GL_BGRA;
	type = GL_UNSIGNED_INT_8_8_8_8_REV;
	break;
    default:
	ErrorF("stub put_image depth %d\n", drawable->depth);
	goto fail;
	break;
    }

83
    glamor_set_alu(gc->alu);
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

    x += drawable->x;
    y += drawable->y;

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glPixelStorei(GL_UNPACK_ROW_LENGTH, src_stride / (bpp / 8));
    clip = fbGetCompositeClip(gc);
    for (nbox = REGION_NUM_RECTS(clip),
	 pbox = REGION_RECTS(clip);
	 nbox--;
	 pbox++)
    {
	int x1 = x;
	int y1 = y;
	int x2 = x + w;
	int y2 = y + h;
	char *src;

	if (x1 < pbox->x1)
	    x1 = pbox->x1;
	if (y1 < pbox->y1)
	    y1 = pbox->y1;
	if (x2 > pbox->x2)
	    x2 = pbox->x2;
	if (y2 > pbox->y2)
	    y2 = pbox->y2;
	if (x1 >= x2 || y1 >= y2)
	    continue;

	src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
114
	glRasterPos2i(x1 - pixmap->screen_x, y1 - pixmap->screen_y);
115
116
117
118
119
120
	glDrawPixels(x2 - x1,
		     y2 - y1,
		     format, type,
		     src);
    }
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
121
    glamor_set_alu(GXcopy);
122
    glamor_set_planemask(pixmap, ~0);
123
124
125
    return;

fail:
126
    glamor_set_planemask(pixmap, ~0);
127
128
    glamor_solid_fail_region(pixmap, x, y, w, h);
}