summaryrefslogtreecommitdiff
path: root/saa/saa_pixmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'saa/saa_pixmap.c')
-rw-r--r--saa/saa_pixmap.c222
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
32PixmapPtr
33saa_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
114Bool
115saa_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
147Bool
148saa_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
185struct saa_pixmap *
186saa_get_saa_pixmap(PixmapPtr pPixmap)
187{
188 return saa_pixmap(pPixmap);
189}
190
191void
192saa_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
212void
213saa_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}