diff options
Diffstat (limited to 'saa/saa_pixmap.c')
-rw-r--r-- | saa/saa_pixmap.c | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/saa/saa_pixmap.c b/saa/saa_pixmap.c new file mode 100644 index 0000000..0d63091 --- /dev/null +++ b/saa/saa_pixmap.c | |||
@@ -0,0 +1,222 @@ | |||
1 | /* | ||
2 | * Copyright © 2009 Maarten Maathuis | ||
3 | * Copyright 2011 VMWare, Inc. All Rights Reserved. | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
6 | * copy of this software and associated documentation files (the | ||
7 | * "Software"), to deal in the Software without restriction, including | ||
8 | * without limitation the rights to use, copy, modify, merge, publish, | ||
9 | * distribute, sub license, and/or sell copies of the Software, and to | ||
10 | * permit persons to whom the Software is furnished to do so, subject to | ||
11 | * the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice (including the | ||
14 | * next paragraph) shall be included in all copies or substantial portions | ||
15 | * of the Software. | ||
16 | * | ||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | ||
20 | * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | ||
21 | * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
24 | * | ||
25 | * Author: Based on "exa_driver.c" | ||
26 | * Author: Thomas Hellstrom <thellstrom@vmware.com> | ||
27 | */ | ||
28 | |||
29 | #include "saa_priv.h" | ||
30 | #include "saa.h" | ||
31 | |||
32 | PixmapPtr | ||
33 | saa_create_pixmap(ScreenPtr pScreen, int w, int h, int depth, | ||
34 | unsigned usage_hint) | ||
35 | { | ||
36 | PixmapPtr pPixmap; | ||
37 | struct saa_pixmap *spix; | ||
38 | int bpp; | ||
39 | size_t paddedWidth; | ||
40 | struct saa_screen_priv *sscreen = saa_screen(pScreen); | ||
41 | int new_pitch = 0; | ||
42 | struct saa_driver *driver = sscreen->driver; | ||
43 | |||
44 | if (w > 32767 || h > 32767) | ||
45 | return NullPixmap; | ||
46 | |||
47 | /* | ||
48 | * Create a scratch pixmap without backing storage (w and h are zero) | ||
49 | */ | ||
50 | |||
51 | saa_swap(sscreen, pScreen, CreatePixmap); | ||
52 | pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, usage_hint); | ||
53 | saa_swap(sscreen, pScreen, CreatePixmap); | ||
54 | |||
55 | if (!pPixmap) | ||
56 | goto out_no_pix; | ||
57 | |||
58 | spix = saa_pixmap(pPixmap); | ||
59 | memset(spix, 0, driver->pixmap_size); | ||
60 | REGION_NULL(pScreen, &spix->dirty_shadow); | ||
61 | REGION_NULL(pScreen, &spix->dirty_hw); | ||
62 | REGION_NULL(pScreen, &spix->shadow_damage); | ||
63 | spix->read_access = 0; | ||
64 | spix->write_access = 0; | ||
65 | spix->mapped_access = 0; | ||
66 | spix->addr = NULL; | ||
67 | spix->auth_loc = saa_loc_override; | ||
68 | spix->override = SAA_INVALID_ADDRESS; | ||
69 | spix->pixmap = pPixmap; | ||
70 | bpp = pPixmap->drawable.bitsPerPixel; | ||
71 | |||
72 | if (!driver->create_pixmap(driver, spix, w, h, depth, | ||
73 | usage_hint, bpp, &new_pitch)) | ||
74 | goto out_no_driver_priv; | ||
75 | |||
76 | paddedWidth = new_pitch; | ||
77 | spix->damage = NULL; | ||
78 | |||
79 | /* | ||
80 | * Now set w and h to the correct value. This might allocate | ||
81 | * backing store if w and h are NON-NULL. | ||
82 | */ | ||
83 | |||
84 | if (!(*pScreen->ModifyPixmapHeader) (pPixmap, w, h, 0, 0, | ||
85 | paddedWidth, NULL)) | ||
86 | goto out_no_pixmap_header; | ||
87 | |||
88 | /* | ||
89 | * During a fallback we must prepare access. This hack is initially used | ||
90 | * for pixmaps created during ValidateGC. | ||
91 | */ | ||
92 | |||
93 | spix->fallback_created = FALSE; | ||
94 | if (sscreen->fallback_count) { | ||
95 | if (!saa_prepare_access_pixmap(pPixmap, SAA_ACCESS_W, NULL)) | ||
96 | goto out_no_access; | ||
97 | |||
98 | spix->fallback_created = TRUE; | ||
99 | } | ||
100 | |||
101 | return pPixmap; | ||
102 | out_no_access: | ||
103 | out_no_pixmap_header: | ||
104 | driver->destroy_pixmap(driver, pPixmap); | ||
105 | out_no_driver_priv: | ||
106 | saa_swap(sscreen, pScreen, DestroyPixmap); | ||
107 | pScreen->DestroyPixmap(pPixmap); | ||
108 | saa_swap(sscreen, pScreen, DestroyPixmap); | ||
109 | out_no_pix: | ||
110 | LogMessage(X_ERROR, "Failing pixmap creation.\n"); | ||
111 | return NullPixmap; | ||
112 | } | ||
113 | |||
114 | Bool | ||
115 | saa_destroy_pixmap(PixmapPtr pPixmap) | ||
116 | { | ||
117 | ScreenPtr pScreen = pPixmap->drawable.pScreen; | ||
118 | struct saa_screen_priv *sscreen = saa_screen(pScreen); | ||
119 | Bool ret; | ||
120 | struct saa_driver *driver = sscreen->driver; | ||
121 | |||
122 | if (pPixmap->refcnt == 1) { | ||
123 | struct saa_pixmap *spix = saa_pixmap(pPixmap); | ||
124 | |||
125 | if (spix->fallback_created) { | ||
126 | if (!sscreen->fallback_count) | ||
127 | LogMessage(X_ERROR, "Fallback pixmap destroyed outside " | ||
128 | "fallback.\n"); | ||
129 | |||
130 | saa_finish_access_pixmap(pPixmap, SAA_ACCESS_W); | ||
131 | } | ||
132 | |||
133 | driver->destroy_pixmap(driver, pPixmap); | ||
134 | |||
135 | REGION_UNINIT(pScreen, &spix->dirty_hw); | ||
136 | REGION_UNINIT(pScreen, &spix->dirty_shadow); | ||
137 | spix->damage = NULL; | ||
138 | } | ||
139 | |||
140 | saa_swap(sscreen, pScreen, DestroyPixmap); | ||
141 | ret = pScreen->DestroyPixmap(pPixmap); | ||
142 | saa_swap(sscreen, pScreen, DestroyPixmap); | ||
143 | |||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | Bool | ||
148 | saa_modify_pixmap_header(PixmapPtr pPixmap, int width, int height, int depth, | ||
149 | int bitsPerPixel, int devKind, pointer pPixData) | ||
150 | { | ||
151 | ScreenPtr pScreen; | ||
152 | struct saa_screen_priv *sscreen; | ||
153 | struct saa_pixmap *spix; | ||
154 | struct saa_driver *driver; | ||
155 | Bool ret = TRUE; | ||
156 | |||
157 | if (!pPixmap) | ||
158 | return FALSE; | ||
159 | |||
160 | pScreen = pPixmap->drawable.pScreen; | ||
161 | sscreen = saa_screen(pScreen); | ||
162 | spix = saa_pixmap(pPixmap); | ||
163 | driver = sscreen->driver; | ||
164 | |||
165 | if (spix && driver->modify_pixmap_header && | ||
166 | driver->modify_pixmap_header(pPixmap, width, height, depth, | ||
167 | bitsPerPixel, devKind, pPixData)) { | ||
168 | spix->auth_loc = saa_loc_driver; | ||
169 | spix->override = SAA_INVALID_ADDRESS; | ||
170 | goto out; | ||
171 | } | ||
172 | |||
173 | saa_swap(sscreen, pScreen, ModifyPixmapHeader); | ||
174 | ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth, | ||
175 | bitsPerPixel, devKind, pPixData); | ||
176 | saa_swap(sscreen, pScreen, ModifyPixmapHeader); | ||
177 | spix->override = pPixmap->devPrivate.ptr; | ||
178 | spix->auth_loc = saa_loc_override; | ||
179 | |||
180 | out: | ||
181 | pPixmap->devPrivate.ptr = NULL; | ||
182 | return ret; | ||
183 | } | ||
184 | |||
185 | struct saa_pixmap * | ||
186 | saa_get_saa_pixmap(PixmapPtr pPixmap) | ||
187 | { | ||
188 | return saa_pixmap(pPixmap); | ||
189 | } | ||
190 | |||
191 | void | ||
192 | saa_pixmap_dirty(PixmapPtr pixmap, Bool hw, RegionPtr reg) | ||
193 | { | ||
194 | struct saa_pixmap *spix = saa_pixmap(pixmap); | ||
195 | struct saa_screen_priv *sscreen = saa_screen(pixmap->drawable.pScreen); | ||
196 | |||
197 | if (hw) { | ||
198 | REGION_UNION(pixmap->drawable.pScreen, &spix->dirty_hw, | ||
199 | &spix->dirty_hw, reg); | ||
200 | REGION_SUBTRACT(pixmap->drawable.pScreen, &spix->dirty_shadow, | ||
201 | &spix->dirty_shadow, reg); | ||
202 | } else { | ||
203 | REGION_UNION(pixmap->drawable.pScreen, &spix->dirty_shadow, | ||
204 | &spix->dirty_shadow, reg); | ||
205 | REGION_SUBTRACT(pixmap->drawable.pScreen, &spix->dirty_hw, | ||
206 | &spix->dirty_hw, reg); | ||
207 | } | ||
208 | |||
209 | sscreen->driver->damage(sscreen->driver, pixmap, hw, reg); | ||
210 | } | ||
211 | |||
212 | void | ||
213 | saa_drawable_dirty(DrawablePtr draw, Bool hw, RegionPtr reg) | ||
214 | { | ||
215 | PixmapPtr pixmap; | ||
216 | int x_offset, y_offset; | ||
217 | |||
218 | pixmap = saa_get_pixmap(draw, &x_offset, &y_offset); | ||
219 | REGION_TRANSLATE(draw->pScreen, reg, x_offset, y_offset); | ||
220 | saa_pixmap_dirty(pixmap, hw, reg); | ||
221 | REGION_TRANSLATE(draw->pScreen, reg, -x_offset, -y_offset); | ||
222 | } | ||