| @@ -1,1680 +1,1684 @@ | | | @@ -1,1680 +1,1684 @@ |
1 | /* | | 1 | /* |
2 | * Copyright © 2007 Red Hat, Inc. | | 2 | * Copyright © 2007 Red Hat, Inc. |
3 | * | | 3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | | 4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), | | 5 | * copy of this software and associated documentation files (the "Software"), |
6 | * to deal in the Software without restriction, including without limitation | | 6 | * to deal in the Software without restriction, including without limitation |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | | 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
8 | * and/or sell copies of the Software, and to permit persons to whom the | | 8 | * and/or sell copies of the Software, and to permit persons to whom the |
9 | * Software is furnished to do so, subject to the following conditions: | | 9 | * Software is furnished to do so, subject to the following conditions: |
10 | * | | 10 | * |
11 | * The above copyright notice and this permission notice (including the next | | 11 | * The above copyright notice and this permission notice (including the next |
12 | * paragraph) shall be included in all copies or substantial portions of the | | 12 | * paragraph) shall be included in all copies or substantial portions of the |
13 | * Software. | | 13 | * Software. |
14 | * | | 14 | * |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | | 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | | 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | | 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | | 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | | 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | | 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
21 | * SOFTWARE. | | 21 | * SOFTWARE. |
22 | * | | 22 | * |
23 | * Authors: | | 23 | * Authors: |
24 | * Dave Airlie <airlied@redhat.com> | | 24 | * Dave Airlie <airlied@redhat.com> |
25 | * | | 25 | * |
26 | */ | | 26 | */ |
27 | | | 27 | |
28 | #ifdef HAVE_DIX_CONFIG_H | | 28 | #ifdef HAVE_DIX_CONFIG_H |
29 | #include "dix-config.h" | | 29 | #include "dix-config.h" |
30 | #endif | | 30 | #endif |
31 | | | 31 | |
32 | #include <errno.h> | | 32 | #include <errno.h> |
33 | #include <sys/ioctl.h> | | 33 | #include <sys/ioctl.h> |
34 | #include <sys/mman.h> | | 34 | #include <sys/mman.h> |
35 | #include <unistd.h> | | 35 | #include <unistd.h> |
36 | #include "dumb_bo.h" | | 36 | #include "dumb_bo.h" |
37 | #include "xf86str.h" | | 37 | #include "xf86str.h" |
38 | #include "X11/Xatom.h" | | 38 | #include "X11/Xatom.h" |
39 | #include "micmap.h" | | 39 | #include "micmap.h" |
40 | #include "xf86cmap.h" | | 40 | #include "xf86cmap.h" |
41 | #include "xf86DDC.h" | | 41 | #include "xf86DDC.h" |
42 | | | 42 | |
43 | #include <xf86drm.h> | | 43 | #include <xf86drm.h> |
44 | #include "xf86Crtc.h" | | 44 | #include "xf86Crtc.h" |
45 | #include "drmmode_display.h" | | 45 | #include "drmmode_display.h" |
46 | | | 46 | |
47 | #include <cursorstr.h> | | 47 | #include <cursorstr.h> |
48 | | | 48 | |
49 | #include <X11/extensions/dpmsconst.h> | | 49 | #include <X11/extensions/dpmsconst.h> |
50 | | | 50 | |
51 | #include "driver.h" | | 51 | #include "driver.h" |
52 | | | 52 | |
53 | static Bool drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height); | | 53 | static Bool drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height); |
54 | | | 54 | |
55 | static Bool | | 55 | static Bool |
56 | drmmode_zaphod_string_matches(ScrnInfoPtr scrn, const char *s, char *output_name) | | 56 | drmmode_zaphod_string_matches(ScrnInfoPtr scrn, const char *s, char *output_name) |
57 | { | | 57 | { |
58 | int i = 0; | | 58 | int i = 0; |
59 | char s1[20]; | | 59 | char s1[20]; |
60 | | | 60 | |
61 | do { | | 61 | do { |
62 | switch(*s) { | | 62 | switch(*s) { |
63 | case ',': | | 63 | case ',': |
64 | s1[i] = '\0'; | | 64 | s1[i] = '\0'; |
65 | i = 0; | | 65 | i = 0; |
66 | if (strcmp(s1, output_name) == 0) | | 66 | if (strcmp(s1, output_name) == 0) |
67 | return TRUE; | | 67 | return TRUE; |
68 | break; | | 68 | break; |
69 | case ' ': | | 69 | case ' ': |
70 | case '\t': | | 70 | case '\t': |
71 | case '\n': | | 71 | case '\n': |
72 | case '\r': | | 72 | case '\r': |
73 | break; | | 73 | break; |
74 | default: | | 74 | default: |
75 | s1[i] = *s; | | 75 | s1[i] = *s; |
76 | i++; | | 76 | i++; |
77 | break; | | 77 | break; |
78 | } | | 78 | } |
79 | } while(*s++); | | 79 | } while(*s++); |
80 | | | 80 | |
81 | s1[i] = '\0'; | | 81 | s1[i] = '\0'; |
82 | if (strcmp(s1, output_name) == 0) | | 82 | if (strcmp(s1, output_name) == 0) |
83 | return TRUE; | | 83 | return TRUE; |
84 | | | 84 | |
85 | return FALSE; | | 85 | return FALSE; |
86 | } | | 86 | } |
87 | | | 87 | |
88 | int | | 88 | int |
89 | drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo) | | 89 | drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo) |
90 | { | | 90 | { |
91 | int ret; | | 91 | int ret; |
92 | | | 92 | |
93 | #ifdef GLAMOR_HAS_GBM | | 93 | #ifdef GLAMOR_HAS_GBM |
94 | if (bo->gbm) { | | 94 | if (bo->gbm) { |
95 | gbm_bo_destroy(bo->gbm); | | 95 | gbm_bo_destroy(bo->gbm); |
96 | bo->gbm = NULL; | | 96 | bo->gbm = NULL; |
97 | } | | 97 | } |
98 | #endif | | 98 | #endif |
99 | | | 99 | |
100 | if (bo->dumb) { | | 100 | if (bo->dumb) { |
101 | ret = dumb_bo_destroy(drmmode->fd, bo->dumb); | | 101 | ret = dumb_bo_destroy(drmmode->fd, bo->dumb); |
102 | if (ret == 0) | | 102 | if (ret == 0) |
103 | bo->dumb = NULL; | | 103 | bo->dumb = NULL; |
104 | } | | 104 | } |
105 | | | 105 | |
106 | return 0; | | 106 | return 0; |
107 | } | | 107 | } |
108 | | | 108 | |
109 | uint32_t | | 109 | uint32_t |
110 | drmmode_bo_get_pitch(drmmode_bo *bo) | | 110 | drmmode_bo_get_pitch(drmmode_bo *bo) |
111 | { | | 111 | { |
112 | #ifdef GLAMOR_HAS_GBM | | 112 | #ifdef GLAMOR_HAS_GBM |
113 | if (bo->gbm) | | 113 | if (bo->gbm) |
114 | return gbm_bo_get_stride(bo->gbm); | | 114 | return gbm_bo_get_stride(bo->gbm); |
115 | #endif | | 115 | #endif |
116 | | | 116 | |
117 | return bo->dumb->pitch; | | 117 | return bo->dumb->pitch; |
118 | } | | 118 | } |
119 | | | 119 | |
120 | static Bool | | 120 | static Bool |
121 | drmmode_bo_has_bo(drmmode_bo *bo) | | 121 | drmmode_bo_has_bo(drmmode_bo *bo) |
122 | { | | 122 | { |
123 | #ifdef GLAMOR_HAS_GBM | | 123 | #ifdef GLAMOR_HAS_GBM |
124 | if (bo->gbm) | | 124 | if (bo->gbm) |
125 | return TRUE; | | 125 | return TRUE; |
126 | #endif | | 126 | #endif |
127 | | | 127 | |
128 | return bo->dumb != NULL; | | 128 | return bo->dumb != NULL; |
129 | } | | 129 | } |
130 | | | 130 | |
131 | uint32_t | | 131 | uint32_t |
132 | drmmode_bo_get_handle(drmmode_bo *bo) | | 132 | drmmode_bo_get_handle(drmmode_bo *bo) |
133 | { | | 133 | { |
134 | #ifdef GLAMOR_HAS_GBM | | 134 | #ifdef GLAMOR_HAS_GBM |
135 | if (bo->gbm) | | 135 | if (bo->gbm) |
136 | return gbm_bo_get_handle(bo->gbm).u32; | | 136 | return gbm_bo_get_handle(bo->gbm).u32; |
137 | #endif | | 137 | #endif |
138 | | | 138 | |
139 | return bo->dumb->handle; | | 139 | return bo->dumb->handle; |
140 | } | | 140 | } |
141 | | | 141 | |
142 | static void * | | 142 | static void * |
143 | drmmode_bo_map(drmmode_ptr drmmode, drmmode_bo *bo) | | 143 | drmmode_bo_map(drmmode_ptr drmmode, drmmode_bo *bo) |
144 | { | | 144 | { |
145 | int ret; | | 145 | int ret; |
146 | | | 146 | |
147 | #ifdef GLAMOR_HAS_GBM | | 147 | #ifdef GLAMOR_HAS_GBM |
148 | if (bo->gbm) | | 148 | if (bo->gbm) |
149 | return NULL; | | 149 | return NULL; |
150 | #endif | | 150 | #endif |
151 | | | 151 | |
152 | if (bo->dumb->ptr) | | 152 | if (bo->dumb->ptr) |
153 | return bo->dumb->ptr; | | 153 | return bo->dumb->ptr; |
154 | | | 154 | |
155 | ret = dumb_bo_map(drmmode->fd, bo->dumb); | | 155 | ret = dumb_bo_map(drmmode->fd, bo->dumb); |
156 | if (ret) | | 156 | if (ret) |
157 | return NULL; | | 157 | return NULL; |
158 | | | 158 | |
159 | return bo->dumb->ptr; | | 159 | return bo->dumb->ptr; |
160 | } | | 160 | } |
161 | | | 161 | |
162 | static Bool | | 162 | static Bool |
163 | drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo, | | 163 | drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo, |
164 | unsigned width, unsigned height, unsigned bpp) | | 164 | unsigned width, unsigned height, unsigned bpp) |
165 | { | | 165 | { |
166 | #ifdef GLAMOR_HAS_GBM | | 166 | #ifdef GLAMOR_HAS_GBM |
167 | if (drmmode->glamor) { | | 167 | if (drmmode->glamor) { |
168 | bo->gbm = gbm_bo_create(drmmode->gbm, width, height, | | 168 | bo->gbm = gbm_bo_create(drmmode->gbm, width, height, |
169 | GBM_FORMAT_ARGB8888, | | 169 | GBM_FORMAT_ARGB8888, |
170 | GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT); | | 170 | GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT); |
171 | return bo->gbm != NULL; | | 171 | return bo->gbm != NULL; |
172 | } | | 172 | } |
173 | #endif | | 173 | #endif |
174 | | | 174 | |
175 | bo->dumb = dumb_bo_create(drmmode->fd, width, height, bpp); | | 175 | bo->dumb = dumb_bo_create(drmmode->fd, width, height, bpp); |
176 | return bo->dumb != NULL; | | 176 | return bo->dumb != NULL; |
177 | } | | 177 | } |
178 | | | 178 | |
179 | Bool | | 179 | Bool |
180 | drmmode_bo_for_pixmap(drmmode_ptr drmmode, drmmode_bo *bo, PixmapPtr pixmap) | | 180 | drmmode_bo_for_pixmap(drmmode_ptr drmmode, drmmode_bo *bo, PixmapPtr pixmap) |
181 | { | | 181 | { |
182 | #ifdef GLAMOR | | 182 | #ifdef GLAMOR |
183 | ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn); | | 183 | ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn); |
184 | CARD16 pitch; | | 184 | CARD16 pitch; |
185 | CARD32 size; | | 185 | CARD32 size; |
186 | int fd; | | 186 | int fd; |
187 | | | 187 | |
188 | #ifdef GLAMOR_HAS_GBM | | 188 | #ifdef GLAMOR_HAS_GBM |
189 | if (drmmode->glamor) { | | 189 | if (drmmode->glamor) { |
190 | bo->gbm = glamor_gbm_bo_from_pixmap(screen, pixmap); | | 190 | bo->gbm = glamor_gbm_bo_from_pixmap(screen, pixmap); |
191 | bo->dumb = NULL; | | 191 | bo->dumb = NULL; |
192 | return bo->gbm != NULL; | | 192 | return bo->gbm != NULL; |
193 | } | | 193 | } |
194 | #endif | | 194 | #endif |
195 | | | 195 | |
196 | fd = glamor_fd_from_pixmap(screen, pixmap, &pitch, &size); | | 196 | fd = glamor_fd_from_pixmap(screen, pixmap, &pitch, &size); |
197 | if (fd < 0) { | | 197 | if (fd < 0) { |
198 | xf86DrvMsg(drmmode->scrn->scrnIndex, X_ERROR, | | 198 | xf86DrvMsg(drmmode->scrn->scrnIndex, X_ERROR, |
199 | "Failed to get fd for flip to new front.\n"); | | 199 | "Failed to get fd for flip to new front.\n"); |
200 | return FALSE; | | 200 | return FALSE; |
201 | } | | 201 | } |
202 | bo->dumb = dumb_get_bo_from_fd(drmmode->fd, fd, pitch, size); | | 202 | bo->dumb = dumb_get_bo_from_fd(drmmode->fd, fd, pitch, size); |
203 | close(fd); | | 203 | close(fd); |
204 | #endif | | 204 | #endif |
205 | | | 205 | |
206 | return bo->dumb != NULL; | | 206 | return bo->dumb != NULL; |
207 | } | | 207 | } |
208 | | | 208 | |
209 | Bool | | 209 | Bool |
210 | drmmode_SetSlaveBO(PixmapPtr ppix, | | 210 | drmmode_SetSlaveBO(PixmapPtr ppix, |
211 | drmmode_ptr drmmode, int fd_handle, int pitch, int size) | | 211 | drmmode_ptr drmmode, int fd_handle, int pitch, int size) |
212 | { | | 212 | { |
213 | msPixmapPrivPtr ppriv = msGetPixmapPriv(drmmode, ppix); | | 213 | msPixmapPrivPtr ppriv = msGetPixmapPriv(drmmode, ppix); |
214 | | | 214 | |
215 | ppriv->backing_bo = | | 215 | ppriv->backing_bo = |
216 | dumb_get_bo_from_fd(drmmode->fd, fd_handle, pitch, size); | | 216 | dumb_get_bo_from_fd(drmmode->fd, fd_handle, pitch, size); |
217 | if (!ppriv->backing_bo) | | 217 | if (!ppriv->backing_bo) |
218 | return FALSE; | | 218 | return FALSE; |
219 | | | 219 | |
220 | close(fd_handle); | | 220 | close(fd_handle); |
221 | return TRUE; | | 221 | return TRUE; |
222 | } | | 222 | } |
223 | | | 223 | |
224 | static void | | 224 | static void |
225 | drmmode_ConvertFromKMode(ScrnInfoPtr scrn, | | 225 | drmmode_ConvertFromKMode(ScrnInfoPtr scrn, |
226 | drmModeModeInfo * kmode, DisplayModePtr mode) | | 226 | drmModeModeInfo * kmode, DisplayModePtr mode) |
227 | { | | 227 | { |
228 | memset(mode, 0, sizeof(DisplayModeRec)); | | 228 | memset(mode, 0, sizeof(DisplayModeRec)); |
229 | mode->status = MODE_OK; | | 229 | mode->status = MODE_OK; |
230 | | | 230 | |
231 | mode->Clock = kmode->clock; | | 231 | mode->Clock = kmode->clock; |
232 | | | 232 | |
233 | mode->HDisplay = kmode->hdisplay; | | 233 | mode->HDisplay = kmode->hdisplay; |
234 | mode->HSyncStart = kmode->hsync_start; | | 234 | mode->HSyncStart = kmode->hsync_start; |
235 | mode->HSyncEnd = kmode->hsync_end; | | 235 | mode->HSyncEnd = kmode->hsync_end; |
236 | mode->HTotal = kmode->htotal; | | 236 | mode->HTotal = kmode->htotal; |
237 | mode->HSkew = kmode->hskew; | | 237 | mode->HSkew = kmode->hskew; |
238 | | | 238 | |
239 | mode->VDisplay = kmode->vdisplay; | | 239 | mode->VDisplay = kmode->vdisplay; |
240 | mode->VSyncStart = kmode->vsync_start; | | 240 | mode->VSyncStart = kmode->vsync_start; |
241 | mode->VSyncEnd = kmode->vsync_end; | | 241 | mode->VSyncEnd = kmode->vsync_end; |
242 | mode->VTotal = kmode->vtotal; | | 242 | mode->VTotal = kmode->vtotal; |
243 | mode->VScan = kmode->vscan; | | 243 | mode->VScan = kmode->vscan; |
244 | | | 244 | |
245 | mode->Flags = kmode->flags; //& FLAG_BITS; | | 245 | mode->Flags = kmode->flags; //& FLAG_BITS; |
246 | mode->name = strdup(kmode->name); | | 246 | mode->name = strdup(kmode->name); |
247 | | | 247 | |
248 | if (kmode->type & DRM_MODE_TYPE_DRIVER) | | 248 | if (kmode->type & DRM_MODE_TYPE_DRIVER) |
249 | mode->type = M_T_DRIVER; | | 249 | mode->type = M_T_DRIVER; |
250 | if (kmode->type & DRM_MODE_TYPE_PREFERRED) | | 250 | if (kmode->type & DRM_MODE_TYPE_PREFERRED) |
251 | mode->type |= M_T_PREFERRED; | | 251 | mode->type |= M_T_PREFERRED; |
252 | xf86SetModeCrtc(mode, scrn->adjustFlags); | | 252 | xf86SetModeCrtc(mode, scrn->adjustFlags); |
253 | } | | 253 | } |
254 | | | 254 | |
255 | static void | | 255 | static void |
256 | drmmode_ConvertToKMode(ScrnInfoPtr scrn, | | 256 | drmmode_ConvertToKMode(ScrnInfoPtr scrn, |
257 | drmModeModeInfo * kmode, DisplayModePtr mode) | | 257 | drmModeModeInfo * kmode, DisplayModePtr mode) |
258 | { | | 258 | { |
259 | memset(kmode, 0, sizeof(*kmode)); | | 259 | memset(kmode, 0, sizeof(*kmode)); |
260 | | | 260 | |
261 | kmode->clock = mode->Clock; | | 261 | kmode->clock = mode->Clock; |
262 | kmode->hdisplay = mode->HDisplay; | | 262 | kmode->hdisplay = mode->HDisplay; |
263 | kmode->hsync_start = mode->HSyncStart; | | 263 | kmode->hsync_start = mode->HSyncStart; |
264 | kmode->hsync_end = mode->HSyncEnd; | | 264 | kmode->hsync_end = mode->HSyncEnd; |
265 | kmode->htotal = mode->HTotal; | | 265 | kmode->htotal = mode->HTotal; |
266 | kmode->hskew = mode->HSkew; | | 266 | kmode->hskew = mode->HSkew; |
267 | | | 267 | |
268 | kmode->vdisplay = mode->VDisplay; | | 268 | kmode->vdisplay = mode->VDisplay; |
269 | kmode->vsync_start = mode->VSyncStart; | | 269 | kmode->vsync_start = mode->VSyncStart; |
270 | kmode->vsync_end = mode->VSyncEnd; | | 270 | kmode->vsync_end = mode->VSyncEnd; |
271 | kmode->vtotal = mode->VTotal; | | 271 | kmode->vtotal = mode->VTotal; |
272 | kmode->vscan = mode->VScan; | | 272 | kmode->vscan = mode->VScan; |
273 | | | 273 | |
274 | kmode->flags = mode->Flags; //& FLAG_BITS; | | 274 | kmode->flags = mode->Flags; //& FLAG_BITS; |
275 | if (mode->name) | | 275 | if (mode->name) |
276 | strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN); | | 276 | strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN); |
277 | kmode->name[DRM_DISPLAY_MODE_LEN - 1] = 0; | | 277 | kmode->name[DRM_DISPLAY_MODE_LEN - 1] = 0; |
278 | | | 278 | |
279 | } | | 279 | } |
280 | | | 280 | |
281 | static void | | 281 | static void |
282 | drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) | | 282 | drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode) |
283 | { | | 283 | { |
284 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 284 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
285 | drmmode_crtc->dpms_mode = mode; | | 285 | drmmode_crtc->dpms_mode = mode; |
286 | } | | 286 | } |
287 | | | 287 | |
288 | #if 0 | | 288 | #if 0 |
289 | static PixmapPtr | | 289 | static PixmapPtr |
290 | create_pixmap_for_fbcon(drmmode_ptr drmmode, ScrnInfoPtr pScrn, int crtc_id) | | 290 | create_pixmap_for_fbcon(drmmode_ptr drmmode, ScrnInfoPtr pScrn, int crtc_id) |
291 | { | | 291 | { |
292 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); | | 292 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); |
293 | drmmode_crtc_private_ptr drmmode_crtc; | | 293 | drmmode_crtc_private_ptr drmmode_crtc; |
294 | ScreenPtr pScreen = pScrn->pScreen; | | 294 | ScreenPtr pScreen = pScrn->pScreen; |
295 | PixmapPtr pixmap; | | 295 | PixmapPtr pixmap; |
296 | struct radeon_bo *bo; | | 296 | struct radeon_bo *bo; |
297 | drmModeFBPtr fbcon; | | 297 | drmModeFBPtr fbcon; |
298 | struct drm_gem_flink flink; | | 298 | struct drm_gem_flink flink; |
299 | | | 299 | |
300 | drmmode_crtc = xf86_config->crtc[crtc_id]->driver_private; | | 300 | drmmode_crtc = xf86_config->crtc[crtc_id]->driver_private; |
301 | | | 301 | |
302 | fbcon = drmModeGetFB(drmmode->fd, drmmode_crtc->mode_crtc->buffer_id); | | 302 | fbcon = drmModeGetFB(drmmode->fd, drmmode_crtc->mode_crtc->buffer_id); |
303 | if (fbcon == NULL) | | 303 | if (fbcon == NULL) |
304 | return NULL; | | 304 | return NULL; |
305 | | | 305 | |
306 | flink.handle = fbcon->handle; | | 306 | flink.handle = fbcon->handle; |
307 | if (ioctl(drmmode->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { | | 307 | if (ioctl(drmmode->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { |
308 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't flink fbcon handle\n"); | | 308 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't flink fbcon handle\n"); |
309 | return NULL; | | 309 | return NULL; |
310 | } | | 310 | } |
311 | | | 311 | |
312 | bo = radeon_bo_open(drmmode->bufmgr, flink.name, 0, 0, 0, 0); | | 312 | bo = radeon_bo_open(drmmode->bufmgr, flink.name, 0, 0, 0, 0); |
313 | if (bo == NULL) { | | 313 | if (bo == NULL) { |
314 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, | | 314 | xf86DrvMsg(pScrn->scrnIndex, X_ERROR, |
315 | "Couldn't allocate bo for fbcon handle\n"); | | 315 | "Couldn't allocate bo for fbcon handle\n"); |
316 | return NULL; | | 316 | return NULL; |
317 | } | | 317 | } |
318 | | | 318 | |
319 | pixmap = drmmode_create_bo_pixmap(pScreen, fbcon->width, fbcon->height, | | 319 | pixmap = drmmode_create_bo_pixmap(pScreen, fbcon->width, fbcon->height, |
320 | fbcon->depth, fbcon->bpp, | | 320 | fbcon->depth, fbcon->bpp, |
321 | fbcon->pitch, bo); | | 321 | fbcon->pitch, bo); |
322 | if (!pixmap) | | 322 | if (!pixmap) |
323 | return NULL; | | 323 | return NULL; |
324 | | | 324 | |
325 | radeon_bo_unref(bo); | | 325 | radeon_bo_unref(bo); |
326 | drmModeFreeFB(fbcon); | | 326 | drmModeFreeFB(fbcon); |
327 | return pixmap; | | 327 | return pixmap; |
328 | } | | 328 | } |
329 | | | 329 | |
330 | #endif | | 330 | #endif |
331 | | | 331 | |
332 | static Bool | | 332 | static Bool |
333 | drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, | | 333 | drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, |
334 | Rotation rotation, int x, int y) | | 334 | Rotation rotation, int x, int y) |
335 | { | | 335 | { |
336 | ScrnInfoPtr pScrn = crtc->scrn; | | 336 | ScrnInfoPtr pScrn = crtc->scrn; |
337 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); | | 337 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); |
338 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 338 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
339 | drmmode_ptr drmmode = drmmode_crtc->drmmode; | | 339 | drmmode_ptr drmmode = drmmode_crtc->drmmode; |
340 | int saved_x, saved_y; | | 340 | int saved_x, saved_y; |
341 | Rotation saved_rotation; | | 341 | Rotation saved_rotation; |
342 | DisplayModeRec saved_mode; | | 342 | DisplayModeRec saved_mode; |
343 | uint32_t *output_ids = NULL; | | 343 | uint32_t *output_ids = NULL; |
344 | int output_count = 0; | | 344 | int output_count = 0; |
345 | Bool ret = TRUE; | | 345 | Bool ret = TRUE; |
346 | int i; | | 346 | int i; |
347 | uint32_t fb_id = 0; | | 347 | uint32_t fb_id = 0; |
348 | drmModeModeInfo kmode; | | 348 | drmModeModeInfo kmode; |
349 | | | 349 | |
350 | saved_mode = crtc->mode; | | 350 | saved_mode = crtc->mode; |
351 | saved_x = crtc->x; | | 351 | saved_x = crtc->x; |
352 | saved_y = crtc->y; | | 352 | saved_y = crtc->y; |
353 | saved_rotation = crtc->rotation; | | 353 | saved_rotation = crtc->rotation; |
354 | | | 354 | |
355 | if (mode) { | | 355 | if (mode) { |
356 | crtc->mode = *mode; | | 356 | crtc->mode = *mode; |
357 | crtc->x = x; | | 357 | crtc->x = x; |
358 | crtc->y = y; | | 358 | crtc->y = y; |
359 | crtc->rotation = rotation; | | 359 | crtc->rotation = rotation; |
360 | } | | 360 | } |
361 | | | 361 | |
362 | output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); | | 362 | output_ids = calloc(sizeof(uint32_t), xf86_config->num_output); |
363 | if (!output_ids) { | | 363 | if (!output_ids) { |
364 | ret = FALSE; | | 364 | ret = FALSE; |
365 | goto done; | | 365 | goto done; |
366 | } | | 366 | } |
367 | | | 367 | |
368 | if (mode) { | | 368 | if (mode) { |
369 | for (i = 0; i < xf86_config->num_output; i++) { | | 369 | for (i = 0; i < xf86_config->num_output; i++) { |
370 | xf86OutputPtr output = xf86_config->output[i]; | | 370 | xf86OutputPtr output = xf86_config->output[i]; |
371 | drmmode_output_private_ptr drmmode_output; | | 371 | drmmode_output_private_ptr drmmode_output; |
372 | | | 372 | |
373 | if (output->crtc != crtc) | | 373 | if (output->crtc != crtc) |
374 | continue; | | 374 | continue; |
375 | | | 375 | |
376 | drmmode_output = output->driver_private; | | 376 | drmmode_output = output->driver_private; |
377 | if (drmmode_output->output_id == -1) | | 377 | if (drmmode_output->output_id == -1) |
378 | continue; | | 378 | continue; |
379 | output_ids[output_count] = | | 379 | output_ids[output_count] = |
380 | drmmode_output->mode_output->connector_id; | | 380 | drmmode_output->mode_output->connector_id; |
381 | output_count++; | | 381 | output_count++; |
382 | } | | 382 | } |
383 | | | 383 | |
384 | if (!xf86CrtcRotate(crtc)) { | | 384 | if (!xf86CrtcRotate(crtc)) { |
385 | goto done; | | 385 | goto done; |
386 | } | | 386 | } |
387 | crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, | | 387 | crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, |
388 | crtc->gamma_blue, crtc->gamma_size); | | 388 | crtc->gamma_blue, crtc->gamma_size); |
389 | | | 389 | |
390 | drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); | | 390 | drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); |
391 | | | 391 | |
392 | fb_id = drmmode->fb_id; | | 392 | fb_id = drmmode->fb_id; |
393 | if (crtc->randr_crtc->scanout_pixmap) { | | 393 | if (crtc->randr_crtc->scanout_pixmap) { |
394 | if (!drmmode->reverse_prime_offload_mode) { | | 394 | if (!drmmode->reverse_prime_offload_mode) { |
395 | msPixmapPrivPtr ppriv = | | 395 | msPixmapPrivPtr ppriv = |
396 | msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap); | | 396 | msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap); |
397 | fb_id = ppriv->fb_id; | | 397 | fb_id = ppriv->fb_id; |
398 | x = 0; | | 398 | x = 0; |
399 | } else | | 399 | } else |
400 | x = drmmode_crtc->prime_pixmap_x; | | 400 | x = drmmode_crtc->prime_pixmap_x; |
401 | y = 0; | | 401 | y = 0; |
402 | } | | 402 | } |
403 | else if (drmmode_crtc->rotate_fb_id) { | | 403 | else if (drmmode_crtc->rotate_fb_id) { |
404 | fb_id = drmmode_crtc->rotate_fb_id; | | 404 | fb_id = drmmode_crtc->rotate_fb_id; |
405 | x = y = 0; | | 405 | x = y = 0; |
406 | } | | 406 | } |
407 | | | 407 | |
408 | if (fb_id == 0) { | | 408 | if (fb_id == 0) { |
409 | ret = drmModeAddFB(drmmode->fd, | | 409 | ret = drmModeAddFB(drmmode->fd, |
410 | pScrn->virtualX, pScrn->virtualY, | | 410 | pScrn->virtualX, pScrn->virtualY, |
411 | pScrn->depth, drmmode->kbpp, | | 411 | pScrn->depth, drmmode->kbpp, |
412 | drmmode_bo_get_pitch(&drmmode->front_bo), | | 412 | drmmode_bo_get_pitch(&drmmode->front_bo), |
413 | drmmode_bo_get_handle(&drmmode->front_bo), | | 413 | drmmode_bo_get_handle(&drmmode->front_bo), |
414 | &drmmode->fb_id); | | 414 | &drmmode->fb_id); |
415 | if (ret < 0) { | | 415 | if (ret < 0) { |
416 | ErrorF("failed to add fb %d\n", ret); | | 416 | ErrorF("failed to add fb %d\n", ret); |
417 | ret = FALSE; | | 417 | ret = FALSE; |
418 | goto done; | | 418 | goto done; |
419 | } | | 419 | } |
420 | fb_id = drmmode->fb_id; | | 420 | fb_id = drmmode->fb_id; |
421 | } | | 421 | } |
422 | | | 422 | |
423 | if (drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, | | 423 | if (drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, |
424 | fb_id, x, y, output_ids, output_count, &kmode)) { | | 424 | fb_id, x, y, output_ids, output_count, &kmode)) { |
425 | xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, | | 425 | xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, |
426 | "failed to set mode: %s\n", strerror(errno)); | | 426 | "failed to set mode: %s\n", strerror(errno)); |
427 | ret = FALSE; | | 427 | ret = FALSE; |
428 | goto done; | | 428 | goto done; |
429 | } else | | 429 | } else |
430 | ret = TRUE; | | 430 | ret = TRUE; |
431 | | | 431 | |
432 | if (crtc->scrn->pScreen) | | 432 | if (crtc->scrn->pScreen) |
433 | xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen); | | 433 | xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen); |
434 | | | 434 | |
435 | drmmode_crtc->need_modeset = FALSE; | | 435 | drmmode_crtc->need_modeset = FALSE; |
436 | crtc->funcs->dpms(crtc, DPMSModeOn); | | 436 | crtc->funcs->dpms(crtc, DPMSModeOn); |
437 | | | 437 | |
438 | /* go through all the outputs and force DPMS them back on? */ | | 438 | /* go through all the outputs and force DPMS them back on? */ |
439 | for (i = 0; i < xf86_config->num_output; i++) { | | 439 | for (i = 0; i < xf86_config->num_output; i++) { |
440 | xf86OutputPtr output = xf86_config->output[i]; | | 440 | xf86OutputPtr output = xf86_config->output[i]; |
441 | drmmode_output_private_ptr drmmode_output; | | 441 | drmmode_output_private_ptr drmmode_output; |
442 | | | 442 | |
443 | if (output->crtc != crtc) | | 443 | if (output->crtc != crtc) |
444 | continue; | | 444 | continue; |
445 | | | 445 | |
446 | drmmode_output = output->driver_private; | | 446 | drmmode_output = output->driver_private; |
447 | if (drmmode_output->output_id == -1) | | 447 | if (drmmode_output->output_id == -1) |
448 | continue; | | 448 | continue; |
449 | output->funcs->dpms(output, DPMSModeOn); | | 449 | output->funcs->dpms(output, DPMSModeOn); |
450 | } | | 450 | } |
451 | } | | 451 | } |
452 | | | 452 | |
453 | #if 0 | | 453 | #if 0 |
454 | if (pScrn->pScreen && | | 454 | if (pScrn->pScreen && |
455 | !xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) | | 455 | !xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) |
456 | xf86_reload_cursors(pScrn->pScreen); | | 456 | xf86_reload_cursors(pScrn->pScreen); |
457 | #endif | | 457 | #endif |
458 | done: | | 458 | done: |
459 | if (!ret) { | | 459 | if (!ret) { |
460 | crtc->x = saved_x; | | 460 | crtc->x = saved_x; |
461 | crtc->y = saved_y; | | 461 | crtc->y = saved_y; |
462 | crtc->rotation = saved_rotation; | | 462 | crtc->rotation = saved_rotation; |
463 | crtc->mode = saved_mode; | | 463 | crtc->mode = saved_mode; |
464 | } else | | 464 | } else |
465 | crtc->active = TRUE; | | 465 | crtc->active = TRUE; |
466 | | | 466 | |
467 | free(output_ids); | | 467 | free(output_ids); |
468 | | | 468 | |
469 | return ret; | | 469 | return ret; |
470 | } | | 470 | } |
471 | | | 471 | |
472 | static void | | 472 | static void |
473 | drmmode_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) | | 473 | drmmode_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) |
474 | { | | 474 | { |
475 | | | 475 | |
476 | } | | 476 | } |
477 | | | 477 | |
478 | static void | | 478 | static void |
479 | drmmode_set_cursor_position(xf86CrtcPtr crtc, int x, int y) | | 479 | drmmode_set_cursor_position(xf86CrtcPtr crtc, int x, int y) |
480 | { | | 480 | { |
481 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 481 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
482 | drmmode_ptr drmmode = drmmode_crtc->drmmode; | | 482 | drmmode_ptr drmmode = drmmode_crtc->drmmode; |
483 | | | 483 | |
484 | drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); | | 484 | drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); |
485 | } | | 485 | } |
486 | | | 486 | |
487 | static Bool | | 487 | static Bool |
488 | drmmode_set_cursor(xf86CrtcPtr crtc) | | 488 | drmmode_set_cursor(xf86CrtcPtr crtc) |
489 | { | | 489 | { |
490 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 490 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
491 | drmmode_ptr drmmode = drmmode_crtc->drmmode; | | 491 | drmmode_ptr drmmode = drmmode_crtc->drmmode; |
492 | uint32_t handle = drmmode_crtc->cursor_bo->handle; | | 492 | uint32_t handle = drmmode_crtc->cursor_bo->handle; |
493 | modesettingPtr ms = modesettingPTR(crtc->scrn); | | 493 | modesettingPtr ms = modesettingPTR(crtc->scrn); |
494 | static Bool use_set_cursor2 = TRUE; | | 494 | static Bool use_set_cursor2 = TRUE; |
495 | int ret; | | 495 | int ret; |
496 | | | 496 | |
497 | if (use_set_cursor2) { | | 497 | if (use_set_cursor2) { |
498 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); | | 498 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); |
499 | CursorPtr cursor = xf86_config->cursor; | | 499 | CursorPtr cursor = xf86_config->cursor; |
500 | | | 500 | |
501 | ret = | | 501 | ret = |
502 | drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, | | 502 | drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, |
503 | handle, ms->cursor_width, ms->cursor_height, | | 503 | handle, ms->cursor_width, ms->cursor_height, |
504 | cursor->bits->xhot, cursor->bits->yhot); | | 504 | cursor->bits->xhot, cursor->bits->yhot); |
505 | if (!ret) | | 505 | if (!ret) |
506 | return TRUE; | | 506 | return TRUE; |
507 | | | 507 | |
508 | use_set_cursor2 = FALSE; | | 508 | use_set_cursor2 = FALSE; |
509 | } | | 509 | } |
510 | | | 510 | |
511 | ret = drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, | | 511 | ret = drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, |
512 | ms->cursor_width, ms->cursor_height); | | 512 | ms->cursor_width, ms->cursor_height); |
513 | | | 513 | |
514 | if (ret) { | | 514 | if (ret) { |
515 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); | | 515 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); |
516 | xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; | | 516 | xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; |
517 | | | 517 | |
518 | cursor_info->MaxWidth = cursor_info->MaxHeight = 0; | | 518 | cursor_info->MaxWidth = cursor_info->MaxHeight = 0; |
519 | drmmode_crtc->drmmode->sw_cursor = TRUE; | | 519 | drmmode_crtc->drmmode->sw_cursor = TRUE; |
520 | /* fallback to swcursor */ | | 520 | /* fallback to swcursor */ |
521 | return FALSE; | | 521 | return FALSE; |
522 | } | | 522 | } |
523 | return TRUE; | | 523 | return TRUE; |
524 | } | | 524 | } |
525 | | | 525 | |
526 | static void drmmode_hide_cursor(xf86CrtcPtr crtc); | | 526 | static void drmmode_hide_cursor(xf86CrtcPtr crtc); |
527 | | | 527 | |
528 | /* | | 528 | /* |
529 | * The load_cursor_argb_check driver hook. | | 529 | * The load_cursor_argb_check driver hook. |
530 | * | | 530 | * |
531 | * Sets the hardware cursor by calling the drmModeSetCursor2 ioctl. | | 531 | * Sets the hardware cursor by calling the drmModeSetCursor2 ioctl. |
532 | * On failure, returns FALSE indicating that the X server should fall | | 532 | * On failure, returns FALSE indicating that the X server should fall |
533 | * back to software cursors. | | 533 | * back to software cursors. |
534 | */ | | 534 | */ |
535 | static Bool | | 535 | static Bool |
536 | drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 *image) | | 536 | drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 *image) |
537 | { | | 537 | { |
538 | modesettingPtr ms = modesettingPTR(crtc->scrn); | | 538 | modesettingPtr ms = modesettingPTR(crtc->scrn); |
539 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 539 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
540 | int i; | | 540 | int i; |
541 | uint32_t *ptr; | | 541 | uint32_t *ptr; |
542 | static Bool first_time = TRUE; | | 542 | static Bool first_time = TRUE; |
543 | | | 543 | |
544 | /* cursor should be mapped already */ | | 544 | /* cursor should be mapped already */ |
545 | ptr = (uint32_t *) (drmmode_crtc->cursor_bo->ptr); | | 545 | ptr = (uint32_t *) (drmmode_crtc->cursor_bo->ptr); |
546 | | | 546 | |
547 | for (i = 0; i < ms->cursor_width * ms->cursor_height; i++) | | 547 | for (i = 0; i < ms->cursor_width * ms->cursor_height; i++) |
548 | ptr[i] = image[i]; // cpu_to_le32(image[i]); | | 548 | ptr[i] = image[i]; // cpu_to_le32(image[i]); |
549 | | | 549 | |
550 | if (drmmode_crtc->cursor_up || first_time) { | | 550 | if (drmmode_crtc->cursor_up || first_time) { |
551 | Bool ret = drmmode_set_cursor(crtc); | | 551 | Bool ret = drmmode_set_cursor(crtc); |
552 | if (!drmmode_crtc->cursor_up) | | 552 | if (!drmmode_crtc->cursor_up) |
553 | drmmode_hide_cursor(crtc); | | 553 | drmmode_hide_cursor(crtc); |
554 | first_time = FALSE; | | 554 | first_time = FALSE; |
555 | return ret; | | 555 | return ret; |
556 | } | | 556 | } |
557 | return TRUE; | | 557 | return TRUE; |
558 | } | | 558 | } |
559 | | | 559 | |
560 | static void | | 560 | static void |
561 | drmmode_hide_cursor(xf86CrtcPtr crtc) | | 561 | drmmode_hide_cursor(xf86CrtcPtr crtc) |
562 | { | | 562 | { |
563 | modesettingPtr ms = modesettingPTR(crtc->scrn); | | 563 | modesettingPtr ms = modesettingPTR(crtc->scrn); |
564 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 564 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
565 | drmmode_ptr drmmode = drmmode_crtc->drmmode; | | 565 | drmmode_ptr drmmode = drmmode_crtc->drmmode; |
566 | | | 566 | |
567 | drmmode_crtc->cursor_up = FALSE; | | 567 | drmmode_crtc->cursor_up = FALSE; |
568 | drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, | | 568 | drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, |
569 | ms->cursor_width, ms->cursor_height); | | 569 | ms->cursor_width, ms->cursor_height); |
570 | } | | 570 | } |
571 | | | 571 | |
572 | static void | | 572 | static void |
573 | drmmode_show_cursor(xf86CrtcPtr crtc) | | 573 | drmmode_show_cursor(xf86CrtcPtr crtc) |
574 | { | | 574 | { |
575 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 575 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
576 | drmmode_crtc->cursor_up = TRUE; | | 576 | drmmode_crtc->cursor_up = TRUE; |
577 | drmmode_set_cursor(crtc); | | 577 | drmmode_set_cursor(crtc); |
578 | } | | 578 | } |
579 | | | 579 | |
580 | static void | | 580 | static void |
581 | drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t * red, uint16_t * green, | | 581 | drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t * red, uint16_t * green, |
582 | uint16_t * blue, int size) | | 582 | uint16_t * blue, int size) |
583 | { | | 583 | { |
584 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 584 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
585 | drmmode_ptr drmmode = drmmode_crtc->drmmode; | | 585 | drmmode_ptr drmmode = drmmode_crtc->drmmode; |
586 | | | 586 | |
587 | drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, | | 587 | drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, |
588 | size, red, green, blue); | | 588 | size, red, green, blue); |
589 | } | | 589 | } |
590 | | | 590 | |
591 | static Bool | | 591 | static Bool |
592 | drmmode_set_scanout_pixmap_gpu(xf86CrtcPtr crtc, PixmapPtr ppix) | | 592 | drmmode_set_scanout_pixmap_gpu(xf86CrtcPtr crtc, PixmapPtr ppix) |
593 | { | | 593 | { |
594 | ScreenPtr screen = xf86ScrnToScreen(crtc->scrn); | | 594 | ScreenPtr screen = xf86ScrnToScreen(crtc->scrn); |
595 | PixmapPtr screenpix = screen->GetScreenPixmap(screen); | | 595 | PixmapPtr screenpix = screen->GetScreenPixmap(screen); |
596 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); | | 596 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); |
597 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 597 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
598 | drmmode_ptr drmmode = drmmode_crtc->drmmode; | | 598 | drmmode_ptr drmmode = drmmode_crtc->drmmode; |
599 | int c, total_width = 0, max_height = 0, this_x = 0; | | 599 | int c, total_width = 0, max_height = 0, this_x = 0; |
600 | | | 600 | |
601 | if (!ppix) { | | 601 | if (!ppix) { |
602 | if (crtc->randr_crtc->scanout_pixmap) { | | 602 | if (crtc->randr_crtc->scanout_pixmap) { |
603 | PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap, screenpix); | | 603 | PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap, screenpix); |
604 | if (drmmode->fb_id) { | | 604 | if (drmmode->fb_id) { |
605 | drmModeRmFB(drmmode->fd, drmmode->fb_id); | | 605 | drmModeRmFB(drmmode->fd, drmmode->fb_id); |
606 | drmmode->fb_id = 0; | | 606 | drmmode->fb_id = 0; |
607 | } | | 607 | } |
608 | } | | 608 | } |
609 | drmmode_crtc->prime_pixmap_x = 0; | | 609 | drmmode_crtc->prime_pixmap_x = 0; |
610 | return TRUE; | | 610 | return TRUE; |
611 | } | | 611 | } |
612 | /* iterate over all the attached crtcs to work out the bounding box */ | | 612 | /* iterate over all the attached crtcs to work out the bounding box */ |
613 | for (c = 0; c < xf86_config->num_crtc; c++) { | | 613 | for (c = 0; c < xf86_config->num_crtc; c++) { |
614 | xf86CrtcPtr iter = xf86_config->crtc[c]; | | 614 | xf86CrtcPtr iter = xf86_config->crtc[c]; |
615 | if (!iter->enabled && iter != crtc) | | 615 | if (!iter->enabled && iter != crtc) |
616 | continue; | | 616 | continue; |
617 | if (iter == crtc) { | | 617 | if (iter == crtc) { |
618 | this_x = total_width; | | 618 | this_x = total_width; |
619 | total_width += ppix->drawable.width; | | 619 | total_width += ppix->drawable.width; |
620 | if (max_height < ppix->drawable.height) | | 620 | if (max_height < ppix->drawable.height) |
621 | max_height = ppix->drawable.height; | | 621 | max_height = ppix->drawable.height; |
622 | } else { | | 622 | } else { |
623 | total_width += iter->mode.HDisplay; | | 623 | total_width += iter->mode.HDisplay; |
624 | if (max_height < iter->mode.VDisplay) | | 624 | if (max_height < iter->mode.VDisplay) |
625 | max_height = iter->mode.VDisplay; | | 625 | max_height = iter->mode.VDisplay; |
626 | } | | 626 | } |
627 | } | | 627 | } |
628 | | | 628 | |
629 | if (total_width != screenpix->drawable.width || | | 629 | if (total_width != screenpix->drawable.width || |
630 | max_height != screenpix->drawable.height) { | | 630 | max_height != screenpix->drawable.height) { |
631 | | | 631 | |
632 | if (!drmmode_xf86crtc_resize(crtc->scrn, total_width, max_height)) | | 632 | if (!drmmode_xf86crtc_resize(crtc->scrn, total_width, max_height)) |
633 | return FALSE; | | 633 | return FALSE; |
634 | | | 634 | |
635 | screenpix = screen->GetScreenPixmap(screen); | | 635 | screenpix = screen->GetScreenPixmap(screen); |
636 | screen->width = screenpix->drawable.width = total_width; | | 636 | screen->width = screenpix->drawable.width = total_width; |
637 | screen->height = screenpix->drawable.height = max_height; | | 637 | screen->height = screenpix->drawable.height = max_height; |
638 | } | | 638 | } |
639 | drmmode_crtc->prime_pixmap_x = this_x; | | 639 | drmmode_crtc->prime_pixmap_x = this_x; |
640 | PixmapStartDirtyTracking(ppix, screenpix, 0, 0, this_x, 0, RR_Rotate_0); | | 640 | PixmapStartDirtyTracking(ppix, screenpix, 0, 0, this_x, 0, RR_Rotate_0); |
641 | return TRUE; | | 641 | return TRUE; |
642 | } | | 642 | } |
643 | | | 643 | |
644 | static Bool | | 644 | static Bool |
645 | drmmode_set_scanout_pixmap_cpu(xf86CrtcPtr crtc, PixmapPtr ppix) | | 645 | drmmode_set_scanout_pixmap_cpu(xf86CrtcPtr crtc, PixmapPtr ppix) |
646 | { | | 646 | { |
647 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 647 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
648 | drmmode_ptr drmmode = drmmode_crtc->drmmode; | | 648 | drmmode_ptr drmmode = drmmode_crtc->drmmode; |
649 | msPixmapPrivPtr ppriv; | | 649 | msPixmapPrivPtr ppriv; |
650 | void *ptr; | | 650 | void *ptr; |
651 | | | 651 | |
652 | if (!ppix) { | | 652 | if (!ppix) { |
653 | if (crtc->randr_crtc->scanout_pixmap) { | | 653 | if (crtc->randr_crtc->scanout_pixmap) { |
654 | ppriv = msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap); | | 654 | ppriv = msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap); |
655 | drmModeRmFB(drmmode->fd, ppriv->fb_id); | | 655 | drmModeRmFB(drmmode->fd, ppriv->fb_id); |
656 | } | | 656 | } |
657 | if (drmmode_crtc->slave_damage) { | | 657 | if (drmmode_crtc->slave_damage) { |
658 | DamageUnregister(drmmode_crtc->slave_damage); | | 658 | DamageUnregister(drmmode_crtc->slave_damage); |
659 | drmmode_crtc->slave_damage = NULL; | | 659 | drmmode_crtc->slave_damage = NULL; |
660 | } | | 660 | } |
661 | return TRUE; | | 661 | return TRUE; |
662 | } | | 662 | } |
663 | | | 663 | |
664 | ppriv = msGetPixmapPriv(drmmode, ppix); | | 664 | ppriv = msGetPixmapPriv(drmmode, ppix); |
665 | if (!drmmode_crtc->slave_damage) { | | 665 | if (!drmmode_crtc->slave_damage) { |
666 | drmmode_crtc->slave_damage = DamageCreate(NULL, NULL, | | 666 | drmmode_crtc->slave_damage = DamageCreate(NULL, NULL, |
667 | DamageReportNone, | | 667 | DamageReportNone, |
668 | TRUE, | | 668 | TRUE, |
669 | crtc->randr_crtc->pScreen, | | 669 | crtc->randr_crtc->pScreen, |
670 | NULL); | | 670 | NULL); |
671 | } | | 671 | } |
672 | ptr = drmmode_map_slave_bo(drmmode, ppriv); | | 672 | ptr = drmmode_map_slave_bo(drmmode, ppriv); |
673 | ppix->devPrivate.ptr = ptr; | | 673 | ppix->devPrivate.ptr = ptr; |
674 | DamageRegister(&ppix->drawable, drmmode_crtc->slave_damage); | | 674 | DamageRegister(&ppix->drawable, drmmode_crtc->slave_damage); |
675 | | | 675 | |
676 | if (ppriv->fb_id == 0) { | | 676 | if (ppriv->fb_id == 0) { |
677 | drmModeAddFB(drmmode->fd, ppix->drawable.width, | | 677 | int ret = drmModeAddFB(drmmode->fd, ppix->drawable.width, |
678 | ppix->drawable.height, | | 678 | ppix->drawable.height, |
679 | ppix->drawable.depth, | | 679 | ppix->drawable.depth, |
680 | ppix->drawable.bitsPerPixel, | | 680 | ppix->drawable.bitsPerPixel, |
681 | ppix->devKind, ppriv->backing_bo->handle, &ppriv->fb_id); | | 681 | ppix->devKind, ppriv->backing_bo->handle, &ppriv->fb_id); |
| | | 682 | if (ret) { |
| | | 683 | ErrorF("failed to set scanout pixmap cpu\n"); |
| | | 684 | return FALSE; |
| | | 685 | } |
682 | } | | 686 | } |
683 | return TRUE; | | 687 | return TRUE; |
684 | } | | 688 | } |
685 | | | 689 | |
686 | static Bool | | 690 | static Bool |
687 | drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) | | 691 | drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) |
688 | { | | 692 | { |
689 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 693 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
690 | drmmode_ptr drmmode = drmmode_crtc->drmmode; | | 694 | drmmode_ptr drmmode = drmmode_crtc->drmmode; |
691 | | | 695 | |
692 | if (drmmode->reverse_prime_offload_mode) | | 696 | if (drmmode->reverse_prime_offload_mode) |
693 | return drmmode_set_scanout_pixmap_gpu(crtc, ppix); | | 697 | return drmmode_set_scanout_pixmap_gpu(crtc, ppix); |
694 | else | | 698 | else |
695 | return drmmode_set_scanout_pixmap_cpu(crtc, ppix); | | 699 | return drmmode_set_scanout_pixmap_cpu(crtc, ppix); |
696 | } | | 700 | } |
697 | | | 701 | |
698 | static void * | | 702 | static void * |
699 | drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height) | | 703 | drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height) |
700 | { | | 704 | { |
701 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 705 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
702 | drmmode_ptr drmmode = drmmode_crtc->drmmode; | | 706 | drmmode_ptr drmmode = drmmode_crtc->drmmode; |
703 | int ret; | | 707 | int ret; |
704 | | | 708 | |
705 | if (!drmmode_create_bo(drmmode, &drmmode_crtc->rotate_bo, | | 709 | if (!drmmode_create_bo(drmmode, &drmmode_crtc->rotate_bo, |
706 | width, height, drmmode->kbpp)) { | | 710 | width, height, drmmode->kbpp)) { |
707 | xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, | | 711 | xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, |
708 | "Couldn't allocate shadow memory for rotated CRTC\n"); | | 712 | "Couldn't allocate shadow memory for rotated CRTC\n"); |
709 | return NULL; | | 713 | return NULL; |
710 | } | | 714 | } |
711 | | | 715 | |
712 | ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth, | | 716 | ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth, |
713 | drmmode->kbpp, | | 717 | drmmode->kbpp, |
714 | drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo), | | 718 | drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo), |
715 | drmmode_bo_get_handle(&drmmode_crtc->rotate_bo), | | 719 | drmmode_bo_get_handle(&drmmode_crtc->rotate_bo), |
716 | &drmmode_crtc->rotate_fb_id); | | 720 | &drmmode_crtc->rotate_fb_id); |
717 | | | 721 | |
718 | if (ret) { | | 722 | if (ret) { |
719 | ErrorF("failed to add rotate fb\n"); | | 723 | ErrorF("failed to add rotate fb\n"); |
720 | drmmode_bo_destroy(drmmode, &drmmode_crtc->rotate_bo); | | 724 | drmmode_bo_destroy(drmmode, &drmmode_crtc->rotate_bo); |
721 | return NULL; | | 725 | return NULL; |
722 | } | | 726 | } |
723 | | | 727 | |
724 | #ifdef GLAMOR_HAS_GBM | | 728 | #ifdef GLAMOR_HAS_GBM |
725 | if (drmmode->gbm) | | 729 | if (drmmode->gbm) |
726 | return drmmode_crtc->rotate_bo.gbm; | | 730 | return drmmode_crtc->rotate_bo.gbm; |
727 | #endif | | 731 | #endif |
728 | return drmmode_crtc->rotate_bo.dumb; | | 732 | return drmmode_crtc->rotate_bo.dumb; |
729 | } | | 733 | } |
730 | | | 734 | |
731 | static PixmapPtr | | 735 | static PixmapPtr |
732 | drmmode_create_pixmap_header(ScreenPtr pScreen, int width, int height, | | 736 | drmmode_create_pixmap_header(ScreenPtr pScreen, int width, int height, |
733 | int depth, int bitsPerPixel, int devKind, | | 737 | int depth, int bitsPerPixel, int devKind, |
734 | void *pPixData) | | 738 | void *pPixData) |
735 | { | | 739 | { |
736 | PixmapPtr pixmap; | | 740 | PixmapPtr pixmap; |
737 | | | 741 | |
738 | /* width and height of 0 means don't allocate any pixmap data */ | | 742 | /* width and height of 0 means don't allocate any pixmap data */ |
739 | pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0); | | 743 | pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0); |
740 | | | 744 | |
741 | if (pixmap) { | | 745 | if (pixmap) { |
742 | if ((*pScreen->ModifyPixmapHeader)(pixmap, width, height, depth, | | 746 | if ((*pScreen->ModifyPixmapHeader)(pixmap, width, height, depth, |
743 | bitsPerPixel, devKind, pPixData)) | | 747 | bitsPerPixel, devKind, pPixData)) |
744 | return pixmap; | | 748 | return pixmap; |
745 | (*pScreen->DestroyPixmap)(pixmap); | | 749 | (*pScreen->DestroyPixmap)(pixmap); |
746 | } | | 750 | } |
747 | return NullPixmap; | | 751 | return NullPixmap; |
748 | } | | 752 | } |
749 | | | 753 | |
750 | static Bool | | 754 | static Bool |
751 | drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo); | | 755 | drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo); |
752 | | | 756 | |
753 | static PixmapPtr | | 757 | static PixmapPtr |
754 | drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) | | 758 | drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) |
755 | { | | 759 | { |
756 | ScrnInfoPtr scrn = crtc->scrn; | | 760 | ScrnInfoPtr scrn = crtc->scrn; |
757 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 761 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
758 | drmmode_ptr drmmode = drmmode_crtc->drmmode; | | 762 | drmmode_ptr drmmode = drmmode_crtc->drmmode; |
759 | uint32_t rotate_pitch; | | 763 | uint32_t rotate_pitch; |
760 | PixmapPtr rotate_pixmap; | | 764 | PixmapPtr rotate_pixmap; |
761 | void *pPixData = NULL; | | 765 | void *pPixData = NULL; |
762 | | | 766 | |
763 | if (!data) { | | 767 | if (!data) { |
764 | data = drmmode_shadow_allocate(crtc, width, height); | | 768 | data = drmmode_shadow_allocate(crtc, width, height); |
765 | if (!data) { | | 769 | if (!data) { |
766 | xf86DrvMsg(scrn->scrnIndex, X_ERROR, | | 770 | xf86DrvMsg(scrn->scrnIndex, X_ERROR, |
767 | "Couldn't allocate shadow pixmap for rotated CRTC\n"); | | 771 | "Couldn't allocate shadow pixmap for rotated CRTC\n"); |
768 | return NULL; | | 772 | return NULL; |
769 | } | | 773 | } |
770 | } | | 774 | } |
771 | | | 775 | |
772 | if (!drmmode_bo_has_bo(&drmmode_crtc->rotate_bo)) { | | 776 | if (!drmmode_bo_has_bo(&drmmode_crtc->rotate_bo)) { |
773 | xf86DrvMsg(scrn->scrnIndex, X_ERROR, | | 777 | xf86DrvMsg(scrn->scrnIndex, X_ERROR, |
774 | "Couldn't allocate shadow pixmap for rotated CRTC\n"); | | 778 | "Couldn't allocate shadow pixmap for rotated CRTC\n"); |
775 | return NULL; | | 779 | return NULL; |
776 | } | | 780 | } |
777 | | | 781 | |
778 | pPixData = drmmode_bo_map(drmmode, &drmmode_crtc->rotate_bo); | | 782 | pPixData = drmmode_bo_map(drmmode, &drmmode_crtc->rotate_bo); |
779 | rotate_pitch = drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo), | | 783 | rotate_pitch = drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo), |
780 | | | 784 | |
781 | rotate_pixmap = drmmode_create_pixmap_header(scrn->pScreen, | | 785 | rotate_pixmap = drmmode_create_pixmap_header(scrn->pScreen, |
782 | width, height, | | 786 | width, height, |
783 | scrn->depth, | | 787 | scrn->depth, |
784 | drmmode->kbpp, | | 788 | drmmode->kbpp, |
785 | rotate_pitch, | | 789 | rotate_pitch, |
786 | pPixData); | | 790 | pPixData); |
787 | | | 791 | |
788 | if (rotate_pixmap == NULL) { | | 792 | if (rotate_pixmap == NULL) { |
789 | xf86DrvMsg(scrn->scrnIndex, X_ERROR, | | 793 | xf86DrvMsg(scrn->scrnIndex, X_ERROR, |
790 | "Couldn't allocate shadow pixmap for rotated CRTC\n"); | | 794 | "Couldn't allocate shadow pixmap for rotated CRTC\n"); |
791 | return NULL; | | 795 | return NULL; |
792 | } | | 796 | } |
793 | | | 797 | |
794 | drmmode_set_pixmap_bo(drmmode, rotate_pixmap, &drmmode_crtc->rotate_bo); | | 798 | drmmode_set_pixmap_bo(drmmode, rotate_pixmap, &drmmode_crtc->rotate_bo); |
795 | | | 799 | |
796 | return rotate_pixmap; | | 800 | return rotate_pixmap; |
797 | } | | 801 | } |
798 | | | 802 | |
799 | static void | | 803 | static void |
800 | drmmode_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) | | 804 | drmmode_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) |
801 | { | | 805 | { |
802 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 806 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
803 | drmmode_ptr drmmode = drmmode_crtc->drmmode; | | 807 | drmmode_ptr drmmode = drmmode_crtc->drmmode; |
804 | | | 808 | |
805 | if (rotate_pixmap) { | | 809 | if (rotate_pixmap) { |
806 | drmmode_set_pixmap_bo(drmmode, rotate_pixmap, NULL); | | 810 | drmmode_set_pixmap_bo(drmmode, rotate_pixmap, NULL); |
807 | rotate_pixmap->drawable.pScreen->DestroyPixmap(rotate_pixmap); | | 811 | rotate_pixmap->drawable.pScreen->DestroyPixmap(rotate_pixmap); |
808 | } | | 812 | } |
809 | | | 813 | |
810 | if (data) { | | 814 | if (data) { |
811 | drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id); | | 815 | drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id); |
812 | drmmode_crtc->rotate_fb_id = 0; | | 816 | drmmode_crtc->rotate_fb_id = 0; |
813 | | | 817 | |
814 | drmmode_bo_destroy(drmmode, &drmmode_crtc->rotate_bo); | | 818 | drmmode_bo_destroy(drmmode, &drmmode_crtc->rotate_bo); |
815 | memset(&drmmode_crtc->rotate_bo, 0, sizeof drmmode_crtc->rotate_bo); | | 819 | memset(&drmmode_crtc->rotate_bo, 0, sizeof drmmode_crtc->rotate_bo); |
816 | } | | 820 | } |
817 | } | | 821 | } |
818 | | | 822 | |
819 | static const xf86CrtcFuncsRec drmmode_crtc_funcs = { | | 823 | static const xf86CrtcFuncsRec drmmode_crtc_funcs = { |
820 | .dpms = drmmode_crtc_dpms, | | 824 | .dpms = drmmode_crtc_dpms, |
821 | .set_mode_major = drmmode_set_mode_major, | | 825 | .set_mode_major = drmmode_set_mode_major, |
822 | .set_cursor_colors = drmmode_set_cursor_colors, | | 826 | .set_cursor_colors = drmmode_set_cursor_colors, |
823 | .set_cursor_position = drmmode_set_cursor_position, | | 827 | .set_cursor_position = drmmode_set_cursor_position, |
824 | .show_cursor = drmmode_show_cursor, | | 828 | .show_cursor = drmmode_show_cursor, |
825 | .hide_cursor = drmmode_hide_cursor, | | 829 | .hide_cursor = drmmode_hide_cursor, |
826 | .load_cursor_argb_check = drmmode_load_cursor_argb_check, | | 830 | .load_cursor_argb_check = drmmode_load_cursor_argb_check, |
827 | | | 831 | |
828 | .gamma_set = drmmode_crtc_gamma_set, | | 832 | .gamma_set = drmmode_crtc_gamma_set, |
829 | .destroy = NULL, /* XXX */ | | 833 | .destroy = NULL, /* XXX */ |
830 | .set_scanout_pixmap = drmmode_set_scanout_pixmap, | | 834 | .set_scanout_pixmap = drmmode_set_scanout_pixmap, |
831 | .shadow_allocate = drmmode_shadow_allocate, | | 835 | .shadow_allocate = drmmode_shadow_allocate, |
832 | .shadow_create = drmmode_shadow_create, | | 836 | .shadow_create = drmmode_shadow_create, |
833 | .shadow_destroy = drmmode_shadow_destroy, | | 837 | .shadow_destroy = drmmode_shadow_destroy, |
834 | }; | | 838 | }; |
835 | | | 839 | |
836 | static uint32_t | | 840 | static uint32_t |
837 | drmmode_crtc_vblank_pipe(int crtc_id) | | 841 | drmmode_crtc_vblank_pipe(int crtc_id) |
838 | { | | 842 | { |
839 | if (crtc_id > 1) | | 843 | if (crtc_id > 1) |
840 | return crtc_id << DRM_VBLANK_HIGH_CRTC_SHIFT; | | 844 | return crtc_id << DRM_VBLANK_HIGH_CRTC_SHIFT; |
841 | else if (crtc_id > 0) | | 845 | else if (crtc_id > 0) |
842 | return DRM_VBLANK_SECONDARY; | | 846 | return DRM_VBLANK_SECONDARY; |
843 | else | | 847 | else |
844 | return 0; | | 848 | return 0; |
845 | } | | 849 | } |
846 | | | 850 | |
847 | static unsigned int | | 851 | static unsigned int |
848 | drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num) | | 852 | drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num) |
849 | { | | 853 | { |
850 | xf86CrtcPtr crtc; | | 854 | xf86CrtcPtr crtc; |
851 | drmmode_crtc_private_ptr drmmode_crtc; | | 855 | drmmode_crtc_private_ptr drmmode_crtc; |
852 | modesettingEntPtr ms_ent = ms_ent_priv(pScrn); | | 856 | modesettingEntPtr ms_ent = ms_ent_priv(pScrn); |
853 | | | 857 | |
854 | crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs); | | 858 | crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs); |
855 | if (crtc == NULL) | | 859 | if (crtc == NULL) |
856 | return 0; | | 860 | return 0; |
857 | | | 861 | |
858 | drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); | | 862 | drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); |
859 | drmmode_crtc->mode_crtc = | | 863 | drmmode_crtc->mode_crtc = |
860 | drmModeGetCrtc(drmmode->fd, mode_res->crtcs[num]); | | 864 | drmModeGetCrtc(drmmode->fd, mode_res->crtcs[num]); |
861 | drmmode_crtc->drmmode = drmmode; | | 865 | drmmode_crtc->drmmode = drmmode; |
862 | drmmode_crtc->vblank_pipe = drmmode_crtc_vblank_pipe(num); | | 866 | drmmode_crtc->vblank_pipe = drmmode_crtc_vblank_pipe(num); |
863 | crtc->driver_private = drmmode_crtc; | | 867 | crtc->driver_private = drmmode_crtc; |
864 | | | 868 | |
865 | /* Mark num'th crtc as in use on this device. */ | | 869 | /* Mark num'th crtc as in use on this device. */ |
866 | ms_ent->assigned_crtcs |= (1 << num); | | 870 | ms_ent->assigned_crtcs |= (1 << num); |
867 | xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG, | | 871 | xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG, |
868 | "Allocated crtc nr. %d to this screen.\n", num); | | 872 | "Allocated crtc nr. %d to this screen.\n", num); |
869 | | | 873 | |
870 | return 1; | | 874 | return 1; |
871 | } | | 875 | } |
872 | | | 876 | |
873 | static xf86OutputStatus | | 877 | static xf86OutputStatus |
874 | drmmode_output_detect(xf86OutputPtr output) | | 878 | drmmode_output_detect(xf86OutputPtr output) |
875 | { | | 879 | { |
876 | /* go to the hw and retrieve a new output struct */ | | 880 | /* go to the hw and retrieve a new output struct */ |
877 | drmmode_output_private_ptr drmmode_output = output->driver_private; | | 881 | drmmode_output_private_ptr drmmode_output = output->driver_private; |
878 | drmmode_ptr drmmode = drmmode_output->drmmode; | | 882 | drmmode_ptr drmmode = drmmode_output->drmmode; |
879 | xf86OutputStatus status; | | 883 | xf86OutputStatus status; |
880 | | | 884 | |
881 | if (drmmode_output->output_id == -1) | | 885 | if (drmmode_output->output_id == -1) |
882 | return XF86OutputStatusDisconnected; | | 886 | return XF86OutputStatusDisconnected; |
883 | | | 887 | |
884 | drmModeFreeConnector(drmmode_output->mode_output); | | 888 | drmModeFreeConnector(drmmode_output->mode_output); |
885 | | | 889 | |
886 | drmmode_output->mode_output = | | 890 | drmmode_output->mode_output = |
887 | drmModeGetConnector(drmmode->fd, drmmode_output->output_id); | | 891 | drmModeGetConnector(drmmode->fd, drmmode_output->output_id); |
888 | if (!drmmode_output->mode_output) | | 892 | if (!drmmode_output->mode_output) |
889 | return XF86OutputStatusDisconnected; | | 893 | return XF86OutputStatusDisconnected; |
890 | | | 894 | |
891 | switch (drmmode_output->mode_output->connection) { | | 895 | switch (drmmode_output->mode_output->connection) { |
892 | case DRM_MODE_CONNECTED: | | 896 | case DRM_MODE_CONNECTED: |
893 | status = XF86OutputStatusConnected; | | 897 | status = XF86OutputStatusConnected; |
894 | break; | | 898 | break; |
895 | case DRM_MODE_DISCONNECTED: | | 899 | case DRM_MODE_DISCONNECTED: |
896 | status = XF86OutputStatusDisconnected; | | 900 | status = XF86OutputStatusDisconnected; |
897 | break; | | 901 | break; |
898 | default: | | 902 | default: |
899 | case DRM_MODE_UNKNOWNCONNECTION: | | 903 | case DRM_MODE_UNKNOWNCONNECTION: |
900 | status = XF86OutputStatusUnknown; | | 904 | status = XF86OutputStatusUnknown; |
901 | break; | | 905 | break; |
902 | } | | 906 | } |
903 | return status; | | 907 | return status; |
904 | } | | 908 | } |
905 | | | 909 | |
906 | static Bool | | 910 | static Bool |
907 | drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) | | 911 | drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) |
908 | { | | 912 | { |
909 | return MODE_OK; | | 913 | return MODE_OK; |
910 | } | | 914 | } |
911 | | | 915 | |
912 | static void | | 916 | static void |
913 | drmmode_output_attach_tile(xf86OutputPtr output) | | 917 | drmmode_output_attach_tile(xf86OutputPtr output) |
914 | { | | 918 | { |
915 | drmmode_output_private_ptr drmmode_output = output->driver_private; | | 919 | drmmode_output_private_ptr drmmode_output = output->driver_private; |
916 | drmModeConnectorPtr koutput = drmmode_output->mode_output; | | 920 | drmModeConnectorPtr koutput = drmmode_output->mode_output; |
917 | drmmode_ptr drmmode = drmmode_output->drmmode; | | 921 | drmmode_ptr drmmode = drmmode_output->drmmode; |
918 | int i; | | 922 | int i; |
919 | struct xf86CrtcTileInfo tile_info, *set = NULL; | | 923 | struct xf86CrtcTileInfo tile_info, *set = NULL; |
920 | | | 924 | |
921 | if (!koutput) { | | 925 | if (!koutput) { |
922 | xf86OutputSetTile(output, NULL); | | 926 | xf86OutputSetTile(output, NULL); |
923 | return; | | 927 | return; |
924 | } | | 928 | } |
925 | | | 929 | |
926 | /* look for a TILE property */ | | 930 | /* look for a TILE property */ |
927 | for (i = 0; i < koutput->count_props; i++) { | | 931 | for (i = 0; i < koutput->count_props; i++) { |
928 | drmModePropertyPtr props; | | 932 | drmModePropertyPtr props; |
929 | props = drmModeGetProperty(drmmode->fd, koutput->props[i]); | | 933 | props = drmModeGetProperty(drmmode->fd, koutput->props[i]); |
930 | if (!props) | | 934 | if (!props) |
931 | continue; | | 935 | continue; |
932 | | | 936 | |
933 | if (!(props->flags & DRM_MODE_PROP_BLOB)) { | | 937 | if (!(props->flags & DRM_MODE_PROP_BLOB)) { |
934 | drmModeFreeProperty(props); | | 938 | drmModeFreeProperty(props); |
935 | continue; | | 939 | continue; |
936 | } | | 940 | } |
937 | | | 941 | |
938 | if (!strcmp(props->name, "TILE")) { | | 942 | if (!strcmp(props->name, "TILE")) { |
939 | drmModeFreePropertyBlob(drmmode_output->tile_blob); | | 943 | drmModeFreePropertyBlob(drmmode_output->tile_blob); |
940 | drmmode_output->tile_blob = | | 944 | drmmode_output->tile_blob = |
941 | drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); | | 945 | drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); |
942 | } | | 946 | } |
943 | drmModeFreeProperty(props); | | 947 | drmModeFreeProperty(props); |
944 | } | | 948 | } |
945 | if (drmmode_output->tile_blob) { | | 949 | if (drmmode_output->tile_blob) { |
946 | if (xf86OutputParseKMSTile(drmmode_output->tile_blob->data, drmmode_output->tile_blob->length, &tile_info) == TRUE) | | 950 | if (xf86OutputParseKMSTile(drmmode_output->tile_blob->data, drmmode_output->tile_blob->length, &tile_info) == TRUE) |
947 | set = &tile_info; | | 951 | set = &tile_info; |
948 | } | | 952 | } |
949 | xf86OutputSetTile(output, set); | | 953 | xf86OutputSetTile(output, set); |
950 | } | | 954 | } |
951 | | | 955 | |
952 | static Bool | | 956 | static Bool |
953 | has_panel_fitter(xf86OutputPtr output) | | 957 | has_panel_fitter(xf86OutputPtr output) |
954 | { | | 958 | { |
955 | drmmode_output_private_ptr drmmode_output = output->driver_private; | | 959 | drmmode_output_private_ptr drmmode_output = output->driver_private; |
956 | drmModeConnectorPtr koutput = drmmode_output->mode_output; | | 960 | drmModeConnectorPtr koutput = drmmode_output->mode_output; |
957 | drmmode_ptr drmmode = drmmode_output->drmmode; | | 961 | drmmode_ptr drmmode = drmmode_output->drmmode; |
958 | int i; | | 962 | int i; |
959 | | | 963 | |
960 | /* Presume that if the output supports scaling, then we have a | | 964 | /* Presume that if the output supports scaling, then we have a |
961 | * panel fitter capable of adjust any mode to suit. | | 965 | * panel fitter capable of adjust any mode to suit. |
962 | */ | | 966 | */ |
963 | for (i = 0; i < koutput->count_props; i++) { | | 967 | for (i = 0; i < koutput->count_props; i++) { |
964 | drmModePropertyPtr props; | | 968 | drmModePropertyPtr props; |
965 | Bool found = FALSE; | | 969 | Bool found = FALSE; |
966 | | | 970 | |
967 | props = drmModeGetProperty(drmmode->fd, koutput->props[i]); | | 971 | props = drmModeGetProperty(drmmode->fd, koutput->props[i]); |
968 | if (props) { | | 972 | if (props) { |
969 | found = strcmp(props->name, "scaling mode") == 0; | | 973 | found = strcmp(props->name, "scaling mode") == 0; |
970 | drmModeFreeProperty(props); | | 974 | drmModeFreeProperty(props); |
971 | } | | 975 | } |
972 | | | 976 | |
973 | if (found) | | 977 | if (found) |
974 | return TRUE; | | 978 | return TRUE; |
975 | } | | 979 | } |
976 | | | 980 | |
977 | return FALSE; | | 981 | return FALSE; |
978 | } | | 982 | } |
979 | | | 983 | |
980 | static DisplayModePtr | | 984 | static DisplayModePtr |
981 | drmmode_output_add_gtf_modes(xf86OutputPtr output, DisplayModePtr Modes) | | 985 | drmmode_output_add_gtf_modes(xf86OutputPtr output, DisplayModePtr Modes) |
982 | { | | 986 | { |
983 | xf86MonPtr mon = output->MonInfo; | | 987 | xf86MonPtr mon = output->MonInfo; |
984 | DisplayModePtr i, m, preferred = NULL; | | 988 | DisplayModePtr i, m, preferred = NULL; |
985 | int max_x = 0, max_y = 0; | | 989 | int max_x = 0, max_y = 0; |
986 | float max_vrefresh = 0.0; | | 990 | float max_vrefresh = 0.0; |
987 | | | 991 | |
988 | if (mon && GTF_SUPPORTED(mon->features.msc)) | | 992 | if (mon && GTF_SUPPORTED(mon->features.msc)) |
989 | return Modes; | | 993 | return Modes; |
990 | | | 994 | |
991 | if (!has_panel_fitter(output)) | | 995 | if (!has_panel_fitter(output)) |
992 | return Modes; | | 996 | return Modes; |
993 | | | 997 | |
994 | for (m = Modes; m; m = m->next) { | | 998 | for (m = Modes; m; m = m->next) { |
995 | if (m->type & M_T_PREFERRED) | | 999 | if (m->type & M_T_PREFERRED) |
996 | preferred = m; | | 1000 | preferred = m; |
997 | max_x = max(max_x, m->HDisplay); | | 1001 | max_x = max(max_x, m->HDisplay); |
998 | max_y = max(max_y, m->VDisplay); | | 1002 | max_y = max(max_y, m->VDisplay); |
999 | max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(m)); | | 1003 | max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(m)); |
1000 | } | | 1004 | } |
1001 | | | 1005 | |
1002 | max_vrefresh = max(max_vrefresh, 60.0); | | 1006 | max_vrefresh = max(max_vrefresh, 60.0); |
1003 | max_vrefresh *= (1 + SYNC_TOLERANCE); | | 1007 | max_vrefresh *= (1 + SYNC_TOLERANCE); |
1004 | | | 1008 | |
1005 | m = xf86GetDefaultModes(); | | 1009 | m = xf86GetDefaultModes(); |
1006 | xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0); | | 1010 | xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0); |
1007 | | | 1011 | |
1008 | for (i = m; i; i = i->next) { | | 1012 | for (i = m; i; i = i->next) { |
1009 | if (xf86ModeVRefresh(i) > max_vrefresh) | | 1013 | if (xf86ModeVRefresh(i) > max_vrefresh) |
1010 | i->status = MODE_VSYNC; | | 1014 | i->status = MODE_VSYNC; |
1011 | if (preferred && | | 1015 | if (preferred && |
1012 | i->HDisplay >= preferred->HDisplay && | | 1016 | i->HDisplay >= preferred->HDisplay && |
1013 | i->VDisplay >= preferred->VDisplay && | | 1017 | i->VDisplay >= preferred->VDisplay && |
1014 | xf86ModeVRefresh(i) >= xf86ModeVRefresh(preferred)) | | 1018 | xf86ModeVRefresh(i) >= xf86ModeVRefresh(preferred)) |
1015 | i->status = MODE_VSYNC; | | 1019 | i->status = MODE_VSYNC; |
1016 | } | | 1020 | } |
1017 | | | 1021 | |
1018 | xf86PruneInvalidModes(output->scrn, &m, FALSE); | | 1022 | xf86PruneInvalidModes(output->scrn, &m, FALSE); |
1019 | | | 1023 | |
1020 | return xf86ModesAdd(Modes, m); | | 1024 | return xf86ModesAdd(Modes, m); |
1021 | } | | 1025 | } |
1022 | | | 1026 | |
1023 | static DisplayModePtr | | 1027 | static DisplayModePtr |
1024 | drmmode_output_get_modes(xf86OutputPtr output) | | 1028 | drmmode_output_get_modes(xf86OutputPtr output) |
1025 | { | | 1029 | { |
1026 | drmmode_output_private_ptr drmmode_output = output->driver_private; | | 1030 | drmmode_output_private_ptr drmmode_output = output->driver_private; |
1027 | drmModeConnectorPtr koutput = drmmode_output->mode_output; | | 1031 | drmModeConnectorPtr koutput = drmmode_output->mode_output; |
1028 | drmmode_ptr drmmode = drmmode_output->drmmode; | | 1032 | drmmode_ptr drmmode = drmmode_output->drmmode; |
1029 | int i; | | 1033 | int i; |
1030 | DisplayModePtr Modes = NULL, Mode; | | 1034 | DisplayModePtr Modes = NULL, Mode; |
1031 | drmModePropertyPtr props; | | 1035 | drmModePropertyPtr props; |
1032 | xf86MonPtr mon = NULL; | | 1036 | xf86MonPtr mon = NULL; |
1033 | | | 1037 | |
1034 | if (!koutput) | | 1038 | if (!koutput) |
1035 | return NULL; | | 1039 | return NULL; |
1036 | | | 1040 | |
1037 | /* look for an EDID property */ | | 1041 | /* look for an EDID property */ |
1038 | for (i = 0; i < koutput->count_props; i++) { | | 1042 | for (i = 0; i < koutput->count_props; i++) { |
1039 | props = drmModeGetProperty(drmmode->fd, koutput->props[i]); | | 1043 | props = drmModeGetProperty(drmmode->fd, koutput->props[i]); |
1040 | if (props && (props->flags & DRM_MODE_PROP_BLOB)) { | | 1044 | if (props && (props->flags & DRM_MODE_PROP_BLOB)) { |
1041 | if (!strcmp(props->name, "EDID")) { | | 1045 | if (!strcmp(props->name, "EDID")) { |
1042 | if (drmmode_output->edid_blob) | | 1046 | if (drmmode_output->edid_blob) |
1043 | drmModeFreePropertyBlob(drmmode_output->edid_blob); | | 1047 | drmModeFreePropertyBlob(drmmode_output->edid_blob); |
1044 | drmmode_output->edid_blob = | | 1048 | drmmode_output->edid_blob = |
1045 | drmModeGetPropertyBlob(drmmode->fd, | | 1049 | drmModeGetPropertyBlob(drmmode->fd, |
1046 | koutput->prop_values[i]); | | 1050 | koutput->prop_values[i]); |
1047 | } | | 1051 | } |
1048 | drmModeFreeProperty(props); | | 1052 | drmModeFreeProperty(props); |
1049 | } | | 1053 | } |
1050 | } | | 1054 | } |
1051 | | | 1055 | |
1052 | if (drmmode_output->edid_blob) { | | 1056 | if (drmmode_output->edid_blob) { |
1053 | mon = xf86InterpretEDID(output->scrn->scrnIndex, | | 1057 | mon = xf86InterpretEDID(output->scrn->scrnIndex, |
1054 | drmmode_output->edid_blob->data); | | 1058 | drmmode_output->edid_blob->data); |
1055 | if (mon && drmmode_output->edid_blob->length > 128) | | 1059 | if (mon && drmmode_output->edid_blob->length > 128) |
1056 | mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA; | | 1060 | mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA; |
1057 | } | | 1061 | } |
1058 | xf86OutputSetEDID(output, mon); | | 1062 | xf86OutputSetEDID(output, mon); |
1059 | | | 1063 | |
1060 | drmmode_output_attach_tile(output); | | 1064 | drmmode_output_attach_tile(output); |
1061 | | | 1065 | |
1062 | /* modes should already be available */ | | 1066 | /* modes should already be available */ |
1063 | for (i = 0; i < koutput->count_modes; i++) { | | 1067 | for (i = 0; i < koutput->count_modes; i++) { |
1064 | Mode = xnfalloc(sizeof(DisplayModeRec)); | | 1068 | Mode = xnfalloc(sizeof(DisplayModeRec)); |
1065 | | | 1069 | |
1066 | drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode); | | 1070 | drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode); |
1067 | Modes = xf86ModesAdd(Modes, Mode); | | 1071 | Modes = xf86ModesAdd(Modes, Mode); |
1068 | | | 1072 | |
1069 | } | | 1073 | } |
1070 | | | 1074 | |
1071 | return drmmode_output_add_gtf_modes(output, Modes); | | 1075 | return drmmode_output_add_gtf_modes(output, Modes); |
1072 | } | | 1076 | } |
1073 | | | 1077 | |
1074 | static void | | 1078 | static void |
1075 | drmmode_output_destroy(xf86OutputPtr output) | | 1079 | drmmode_output_destroy(xf86OutputPtr output) |
1076 | { | | 1080 | { |
1077 | drmmode_output_private_ptr drmmode_output = output->driver_private; | | 1081 | drmmode_output_private_ptr drmmode_output = output->driver_private; |
1078 | int i; | | 1082 | int i; |
1079 | | | 1083 | |
1080 | if (drmmode_output->edid_blob) | | 1084 | if (drmmode_output->edid_blob) |
1081 | drmModeFreePropertyBlob(drmmode_output->edid_blob); | | 1085 | drmModeFreePropertyBlob(drmmode_output->edid_blob); |
1082 | for (i = 0; i < drmmode_output->num_props; i++) { | | 1086 | for (i = 0; i < drmmode_output->num_props; i++) { |
1083 | drmModeFreeProperty(drmmode_output->props[i].mode_prop); | | 1087 | drmModeFreeProperty(drmmode_output->props[i].mode_prop); |
1084 | free(drmmode_output->props[i].atoms); | | 1088 | free(drmmode_output->props[i].atoms); |
1085 | } | | 1089 | } |
1086 | free(drmmode_output->props); | | 1090 | free(drmmode_output->props); |
1087 | if (drmmode_output->mode_output) { | | 1091 | if (drmmode_output->mode_output) { |
1088 | for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) { | | 1092 | for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) { |
1089 | drmModeFreeEncoder(drmmode_output->mode_encoders[i]); | | 1093 | drmModeFreeEncoder(drmmode_output->mode_encoders[i]); |
1090 | } | | 1094 | } |
1091 | drmModeFreeConnector(drmmode_output->mode_output); | | 1095 | drmModeFreeConnector(drmmode_output->mode_output); |
1092 | } | | 1096 | } |
1093 | free(drmmode_output->mode_encoders); | | 1097 | free(drmmode_output->mode_encoders); |
1094 | free(drmmode_output); | | 1098 | free(drmmode_output); |
1095 | output->driver_private = NULL; | | 1099 | output->driver_private = NULL; |
1096 | } | | 1100 | } |
1097 | | | 1101 | |
1098 | static void | | 1102 | static void |
1099 | drmmode_output_dpms(xf86OutputPtr output, int mode) | | 1103 | drmmode_output_dpms(xf86OutputPtr output, int mode) |
1100 | { | | 1104 | { |
1101 | drmmode_output_private_ptr drmmode_output = output->driver_private; | | 1105 | drmmode_output_private_ptr drmmode_output = output->driver_private; |
1102 | xf86CrtcPtr crtc = output->crtc; | | 1106 | xf86CrtcPtr crtc = output->crtc; |
1103 | drmModeConnectorPtr koutput = drmmode_output->mode_output; | | 1107 | drmModeConnectorPtr koutput = drmmode_output->mode_output; |
1104 | drmmode_ptr drmmode = drmmode_output->drmmode; | | 1108 | drmmode_ptr drmmode = drmmode_output->drmmode; |
1105 | | | 1109 | |
1106 | if (!koutput) | | 1110 | if (!koutput) |
1107 | return; | | 1111 | return; |
1108 | | | 1112 | |
1109 | drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id, | | 1113 | drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id, |
1110 | drmmode_output->dpms_enum_id, mode); | | 1114 | drmmode_output->dpms_enum_id, mode); |
1111 | | | 1115 | |
1112 | if (mode == DPMSModeOn && crtc) { | | 1116 | if (mode == DPMSModeOn && crtc) { |
1113 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; | | 1117 | drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; |
1114 | if (drmmode_crtc->need_modeset) | | 1118 | if (drmmode_crtc->need_modeset) |
1115 | drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, | | 1119 | drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, |
1116 | crtc->x, crtc->y); | | 1120 | crtc->x, crtc->y); |
1117 | } | | 1121 | } |
1118 | return; | | 1122 | return; |
1119 | } | | 1123 | } |
1120 | | | 1124 | |
1121 | static Bool | | 1125 | static Bool |
1122 | drmmode_property_ignore(drmModePropertyPtr prop) | | 1126 | drmmode_property_ignore(drmModePropertyPtr prop) |
1123 | { | | 1127 | { |
1124 | if (!prop) | | 1128 | if (!prop) |
1125 | return TRUE; | | 1129 | return TRUE; |
1126 | /* ignore blob prop */ | | 1130 | /* ignore blob prop */ |
1127 | if (prop->flags & DRM_MODE_PROP_BLOB) | | 1131 | if (prop->flags & DRM_MODE_PROP_BLOB) |
1128 | return TRUE; | | 1132 | return TRUE; |
1129 | /* ignore standard property */ | | 1133 | /* ignore standard property */ |
1130 | if (!strcmp(prop->name, "EDID") || !strcmp(prop->name, "DPMS")) | | 1134 | if (!strcmp(prop->name, "EDID") || !strcmp(prop->name, "DPMS")) |
1131 | return TRUE; | | 1135 | return TRUE; |
1132 | | | 1136 | |
1133 | return FALSE; | | 1137 | return FALSE; |
1134 | } | | 1138 | } |
1135 | | | 1139 | |
1136 | static void | | 1140 | static void |
1137 | drmmode_output_create_resources(xf86OutputPtr output) | | 1141 | drmmode_output_create_resources(xf86OutputPtr output) |
1138 | { | | 1142 | { |
1139 | drmmode_output_private_ptr drmmode_output = output->driver_private; | | 1143 | drmmode_output_private_ptr drmmode_output = output->driver_private; |
1140 | drmModeConnectorPtr mode_output = drmmode_output->mode_output; | | 1144 | drmModeConnectorPtr mode_output = drmmode_output->mode_output; |
1141 | drmmode_ptr drmmode = drmmode_output->drmmode; | | 1145 | drmmode_ptr drmmode = drmmode_output->drmmode; |
1142 | drmModePropertyPtr drmmode_prop; | | 1146 | drmModePropertyPtr drmmode_prop; |
1143 | int i, j, err; | | 1147 | int i, j, err; |
1144 | | | 1148 | |
1145 | drmmode_output->props = | | 1149 | drmmode_output->props = |
1146 | calloc(mode_output->count_props, sizeof(drmmode_prop_rec)); | | 1150 | calloc(mode_output->count_props, sizeof(drmmode_prop_rec)); |
1147 | if (!drmmode_output->props) | | 1151 | if (!drmmode_output->props) |
1148 | return; | | 1152 | return; |
1149 | | | 1153 | |
1150 | drmmode_output->num_props = 0; | | 1154 | drmmode_output->num_props = 0; |
1151 | for (i = 0, j = 0; i < mode_output->count_props; i++) { | | 1155 | for (i = 0, j = 0; i < mode_output->count_props; i++) { |
1152 | drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]); | | 1156 | drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]); |
1153 | if (drmmode_property_ignore(drmmode_prop)) { | | 1157 | if (drmmode_property_ignore(drmmode_prop)) { |
1154 | drmModeFreeProperty(drmmode_prop); | | 1158 | drmModeFreeProperty(drmmode_prop); |
1155 | continue; | | 1159 | continue; |
1156 | } | | 1160 | } |
1157 | drmmode_output->props[j].mode_prop = drmmode_prop; | | 1161 | drmmode_output->props[j].mode_prop = drmmode_prop; |
1158 | drmmode_output->props[j].value = mode_output->prop_values[i]; | | 1162 | drmmode_output->props[j].value = mode_output->prop_values[i]; |
1159 | drmmode_output->num_props++; | | 1163 | drmmode_output->num_props++; |
1160 | j++; | | 1164 | j++; |
1161 | } | | 1165 | } |
1162 | | | 1166 | |
1163 | for (i = 0; i < drmmode_output->num_props; i++) { | | 1167 | for (i = 0; i < drmmode_output->num_props; i++) { |
1164 | drmmode_prop_ptr p = &drmmode_output->props[i]; | | 1168 | drmmode_prop_ptr p = &drmmode_output->props[i]; |
1165 | | | 1169 | |
1166 | drmmode_prop = p->mode_prop; | | 1170 | drmmode_prop = p->mode_prop; |
1167 | | | 1171 | |
1168 | if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) { | | 1172 | if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) { |
1169 | INT32 prop_range[2]; | | 1173 | INT32 prop_range[2]; |
1170 | INT32 value = p->value; | | 1174 | INT32 value = p->value; |
1171 | | | 1175 | |
1172 | p->num_atoms = 1; | | 1176 | p->num_atoms = 1; |
1173 | p->atoms = calloc(p->num_atoms, sizeof(Atom)); | | 1177 | p->atoms = calloc(p->num_atoms, sizeof(Atom)); |
1174 | if (!p->atoms) | | 1178 | if (!p->atoms) |
1175 | continue; | | 1179 | continue; |
1176 | p->atoms[0] = | | 1180 | p->atoms[0] = |
1177 | MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); | | 1181 | MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); |
1178 | prop_range[0] = drmmode_prop->values[0]; | | 1182 | prop_range[0] = drmmode_prop->values[0]; |
1179 | prop_range[1] = drmmode_prop->values[1]; | | 1183 | prop_range[1] = drmmode_prop->values[1]; |
1180 | err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], | | 1184 | err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], |
1181 | FALSE, TRUE, | | 1185 | FALSE, TRUE, |
1182 | drmmode_prop-> | | 1186 | drmmode_prop-> |
1183 | flags & DRM_MODE_PROP_IMMUTABLE ? | | 1187 | flags & DRM_MODE_PROP_IMMUTABLE ? |
1184 | TRUE : FALSE, 2, prop_range); | | 1188 | TRUE : FALSE, 2, prop_range); |
1185 | if (err != 0) { | | 1189 | if (err != 0) { |
1186 | xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, | | 1190 | xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, |
1187 | "RRConfigureOutputProperty error, %d\n", err); | | 1191 | "RRConfigureOutputProperty error, %d\n", err); |
1188 | } | | 1192 | } |
1189 | err = RRChangeOutputProperty(output->randr_output, p->atoms[0], | | 1193 | err = RRChangeOutputProperty(output->randr_output, p->atoms[0], |
1190 | XA_INTEGER, 32, PropModeReplace, 1, | | 1194 | XA_INTEGER, 32, PropModeReplace, 1, |
1191 | &value, FALSE, TRUE); | | 1195 | &value, FALSE, TRUE); |
1192 | if (err != 0) { | | 1196 | if (err != 0) { |
1193 | xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, | | 1197 | xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, |
1194 | "RRChangeOutputProperty error, %d\n", err); | | 1198 | "RRChangeOutputProperty error, %d\n", err); |
1195 | } | | 1199 | } |
1196 | } | | 1200 | } |
1197 | else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) { | | 1201 | else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) { |
1198 | p->num_atoms = drmmode_prop->count_enums + 1; | | 1202 | p->num_atoms = drmmode_prop->count_enums + 1; |
1199 | p->atoms = calloc(p->num_atoms, sizeof(Atom)); | | 1203 | p->atoms = calloc(p->num_atoms, sizeof(Atom)); |
1200 | if (!p->atoms) | | 1204 | if (!p->atoms) |
1201 | continue; | | 1205 | continue; |
1202 | p->atoms[0] = | | 1206 | p->atoms[0] = |
1203 | MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); | | 1207 | MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); |
1204 | for (j = 1; j <= drmmode_prop->count_enums; j++) { | | 1208 | for (j = 1; j <= drmmode_prop->count_enums; j++) { |
1205 | struct drm_mode_property_enum *e = &drmmode_prop->enums[j - 1]; | | 1209 | struct drm_mode_property_enum *e = &drmmode_prop->enums[j - 1]; |
1206 | | | 1210 | |
1207 | p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE); | | 1211 | p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE); |
1208 | } | | 1212 | } |
1209 | err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], | | 1213 | err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], |
1210 | FALSE, FALSE, | | 1214 | FALSE, FALSE, |
1211 | drmmode_prop-> | | 1215 | drmmode_prop-> |
1212 | flags & DRM_MODE_PROP_IMMUTABLE ? | | 1216 | flags & DRM_MODE_PROP_IMMUTABLE ? |
1213 | TRUE : FALSE, p->num_atoms - 1, | | 1217 | TRUE : FALSE, p->num_atoms - 1, |
1214 | (INT32 *) &p->atoms[1]); | | 1218 | (INT32 *) &p->atoms[1]); |
1215 | if (err != 0) { | | 1219 | if (err != 0) { |
1216 | xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, | | 1220 | xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, |
1217 | "RRConfigureOutputProperty error, %d\n", err); | | 1221 | "RRConfigureOutputProperty error, %d\n", err); |
1218 | } | | 1222 | } |
1219 | for (j = 0; j < drmmode_prop->count_enums; j++) | | 1223 | for (j = 0; j < drmmode_prop->count_enums; j++) |
1220 | if (drmmode_prop->enums[j].value == p->value) | | 1224 | if (drmmode_prop->enums[j].value == p->value) |
1221 | break; | | 1225 | break; |
1222 | /* there's always a matching value */ | | 1226 | /* there's always a matching value */ |
1223 | err = RRChangeOutputProperty(output->randr_output, p->atoms[0], | | 1227 | err = RRChangeOutputProperty(output->randr_output, p->atoms[0], |
1224 | XA_ATOM, 32, PropModeReplace, 1, | | 1228 | XA_ATOM, 32, PropModeReplace, 1, |
1225 | &p->atoms[j + 1], FALSE, TRUE); | | 1229 | &p->atoms[j + 1], FALSE, TRUE); |
1226 | if (err != 0) { | | 1230 | if (err != 0) { |
1227 | xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, | | 1231 | xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, |
1228 | "RRChangeOutputProperty error, %d\n", err); | | 1232 | "RRChangeOutputProperty error, %d\n", err); |
1229 | } | | 1233 | } |
1230 | } | | 1234 | } |
1231 | } | | 1235 | } |
1232 | } | | 1236 | } |
1233 | | | 1237 | |
1234 | static Bool | | 1238 | static Bool |
1235 | drmmode_output_set_property(xf86OutputPtr output, Atom property, | | 1239 | drmmode_output_set_property(xf86OutputPtr output, Atom property, |
1236 | RRPropertyValuePtr value) | | 1240 | RRPropertyValuePtr value) |
1237 | { | | 1241 | { |
1238 | drmmode_output_private_ptr drmmode_output = output->driver_private; | | 1242 | drmmode_output_private_ptr drmmode_output = output->driver_private; |
1239 | drmmode_ptr drmmode = drmmode_output->drmmode; | | 1243 | drmmode_ptr drmmode = drmmode_output->drmmode; |
1240 | int i; | | 1244 | int i; |
1241 | | | 1245 | |
1242 | for (i = 0; i < drmmode_output->num_props; i++) { | | 1246 | for (i = 0; i < drmmode_output->num_props; i++) { |
1243 | drmmode_prop_ptr p = &drmmode_output->props[i]; | | 1247 | drmmode_prop_ptr p = &drmmode_output->props[i]; |
1244 | | | 1248 | |
1245 | if (p->atoms[0] != property) | | 1249 | if (p->atoms[0] != property) |
1246 | continue; | | 1250 | continue; |
1247 | | | 1251 | |
1248 | if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) { | | 1252 | if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) { |
1249 | uint32_t val; | | 1253 | uint32_t val; |
1250 | | | 1254 | |
1251 | if (value->type != XA_INTEGER || value->format != 32 || | | 1255 | if (value->type != XA_INTEGER || value->format != 32 || |
1252 | value->size != 1) | | 1256 | value->size != 1) |
1253 | return FALSE; | | 1257 | return FALSE; |
1254 | val = *(uint32_t *) value->data; | | 1258 | val = *(uint32_t *) value->data; |
1255 | | | 1259 | |
1256 | drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, | | 1260 | drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, |
1257 | p->mode_prop->prop_id, (uint64_t) val); | | 1261 | p->mode_prop->prop_id, (uint64_t) val); |
1258 | return TRUE; | | 1262 | return TRUE; |
1259 | } | | 1263 | } |
1260 | else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) { | | 1264 | else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) { |
1261 | Atom atom; | | 1265 | Atom atom; |
1262 | const char *name; | | 1266 | const char *name; |
1263 | int j; | | 1267 | int j; |
1264 | | | 1268 | |
1265 | if (value->type != XA_ATOM || value->format != 32 || | | 1269 | if (value->type != XA_ATOM || value->format != 32 || |
1266 | value->size != 1) | | 1270 | value->size != 1) |
1267 | return FALSE; | | 1271 | return FALSE; |
1268 | memcpy(&atom, value->data, 4); | | 1272 | memcpy(&atom, value->data, 4); |
1269 | name = NameForAtom(atom); | | 1273 | name = NameForAtom(atom); |
1270 | | | 1274 | |
1271 | /* search for matching name string, then set its value down */ | | 1275 | /* search for matching name string, then set its value down */ |
1272 | for (j = 0; j < p->mode_prop->count_enums; j++) { | | 1276 | for (j = 0; j < p->mode_prop->count_enums; j++) { |
1273 | if (!strcmp(p->mode_prop->enums[j].name, name)) { | | 1277 | if (!strcmp(p->mode_prop->enums[j].name, name)) { |
1274 | drmModeConnectorSetProperty(drmmode->fd, | | 1278 | drmModeConnectorSetProperty(drmmode->fd, |
1275 | drmmode_output->output_id, | | 1279 | drmmode_output->output_id, |
1276 | p->mode_prop->prop_id, | | 1280 | p->mode_prop->prop_id, |
1277 | p->mode_prop->enums[j].value); | | 1281 | p->mode_prop->enums[j].value); |
1278 | return TRUE; | | 1282 | return TRUE; |
1279 | } | | 1283 | } |
1280 | } | | 1284 | } |
1281 | } | | 1285 | } |
1282 | } | | 1286 | } |
1283 | | | 1287 | |
1284 | return TRUE; | | 1288 | return TRUE; |
1285 | } | | 1289 | } |
1286 | | | 1290 | |
1287 | static Bool | | 1291 | static Bool |
1288 | drmmode_output_get_property(xf86OutputPtr output, Atom property) | | 1292 | drmmode_output_get_property(xf86OutputPtr output, Atom property) |
1289 | { | | 1293 | { |
1290 | return TRUE; | | 1294 | return TRUE; |
1291 | } | | 1295 | } |
1292 | | | 1296 | |
1293 | static const xf86OutputFuncsRec drmmode_output_funcs = { | | 1297 | static const xf86OutputFuncsRec drmmode_output_funcs = { |
1294 | .dpms = drmmode_output_dpms, | | 1298 | .dpms = drmmode_output_dpms, |
1295 | .create_resources = drmmode_output_create_resources, | | 1299 | .create_resources = drmmode_output_create_resources, |
1296 | .set_property = drmmode_output_set_property, | | 1300 | .set_property = drmmode_output_set_property, |
1297 | .get_property = drmmode_output_get_property, | | 1301 | .get_property = drmmode_output_get_property, |
1298 | .detect = drmmode_output_detect, | | 1302 | .detect = drmmode_output_detect, |
1299 | .mode_valid = drmmode_output_mode_valid, | | 1303 | .mode_valid = drmmode_output_mode_valid, |
1300 | | | 1304 | |
1301 | .get_modes = drmmode_output_get_modes, | | 1305 | .get_modes = drmmode_output_get_modes, |
1302 | .destroy = drmmode_output_destroy | | 1306 | .destroy = drmmode_output_destroy |
1303 | }; | | 1307 | }; |
1304 | | | 1308 | |
1305 | static int subpixel_conv_table[7] = { | | 1309 | static int subpixel_conv_table[7] = { |
1306 | 0, | | 1310 | 0, |
1307 | SubPixelUnknown, | | 1311 | SubPixelUnknown, |
1308 | SubPixelHorizontalRGB, | | 1312 | SubPixelHorizontalRGB, |
1309 | SubPixelHorizontalBGR, | | 1313 | SubPixelHorizontalBGR, |
1310 | SubPixelVerticalRGB, | | 1314 | SubPixelVerticalRGB, |
1311 | SubPixelVerticalBGR, | | 1315 | SubPixelVerticalBGR, |
1312 | SubPixelNone | | 1316 | SubPixelNone |
1313 | }; | | 1317 | }; |
1314 | | | 1318 | |
1315 | static const char *const output_names[] = { | | 1319 | static const char *const output_names[] = { |
1316 | "None", | | 1320 | "None", |
1317 | "VGA", | | 1321 | "VGA", |
1318 | "DVI-I", | | 1322 | "DVI-I", |
1319 | "DVI-D", | | 1323 | "DVI-D", |
1320 | "DVI-A", | | 1324 | "DVI-A", |
1321 | "Composite", | | 1325 | "Composite", |
1322 | "SVIDEO", | | 1326 | "SVIDEO", |
1323 | "LVDS", | | 1327 | "LVDS", |
1324 | "Component", | | 1328 | "Component", |
1325 | "DIN", | | 1329 | "DIN", |
1326 | "DP", | | 1330 | "DP", |
1327 | "HDMI", | | 1331 | "HDMI", |
1328 | "HDMI-B", | | 1332 | "HDMI-B", |
1329 | "TV", | | 1333 | "TV", |
1330 | "eDP", | | 1334 | "eDP", |
1331 | "Virtual", | | 1335 | "Virtual", |
1332 | "DSI", | | 1336 | "DSI", |
1333 | }; | | 1337 | }; |
1334 | | | 1338 | |
1335 | static xf86OutputPtr find_output(ScrnInfoPtr pScrn, int id) | | 1339 | static xf86OutputPtr find_output(ScrnInfoPtr pScrn, int id) |
1336 | { | | 1340 | { |
1337 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); | | 1341 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); |
1338 | int i; | | 1342 | int i; |
1339 | for (i = 0; i < xf86_config->num_output; i++) { | | 1343 | for (i = 0; i < xf86_config->num_output; i++) { |
1340 | xf86OutputPtr output = xf86_config->output[i]; | | 1344 | xf86OutputPtr output = xf86_config->output[i]; |
1341 | drmmode_output_private_ptr drmmode_output; | | 1345 | drmmode_output_private_ptr drmmode_output; |
1342 | | | 1346 | |
1343 | drmmode_output = output->driver_private; | | 1347 | drmmode_output = output->driver_private; |
1344 | if (drmmode_output->output_id == id) | | 1348 | if (drmmode_output->output_id == id) |
1345 | return output; | | 1349 | return output; |
1346 | } | | 1350 | } |
1347 | return NULL; | | 1351 | return NULL; |
1348 | } | | 1352 | } |
1349 | | | 1353 | |
1350 | static int parse_path_blob(drmModePropertyBlobPtr path_blob, int *conn_base_id, char **path) | | 1354 | static int parse_path_blob(drmModePropertyBlobPtr path_blob, int *conn_base_id, char **path) |
1351 | { | | 1355 | { |
1352 | char *conn; | | 1356 | char *conn; |
1353 | char conn_id[5]; | | 1357 | char conn_id[5]; |
1354 | int id, len; | | 1358 | int id, len; |
1355 | char *blob_data; | | 1359 | char *blob_data; |
1356 | | | 1360 | |
1357 | if (!path_blob) | | 1361 | if (!path_blob) |
1358 | return -1; | | 1362 | return -1; |
1359 | | | 1363 | |
1360 | blob_data = path_blob->data; | | 1364 | blob_data = path_blob->data; |
1361 | /* we only handle MST paths for now */ | | 1365 | /* we only handle MST paths for now */ |
1362 | if (strncmp(blob_data, "mst:", 4)) | | 1366 | if (strncmp(blob_data, "mst:", 4)) |
1363 | return -1; | | 1367 | return -1; |
1364 | | | 1368 | |
1365 | conn = strchr(blob_data + 4, '-'); | | 1369 | conn = strchr(blob_data + 4, '-'); |
1366 | if (!conn) | | 1370 | if (!conn) |
1367 | return -1; | | 1371 | return -1; |
1368 | len = conn - (blob_data + 4); | | 1372 | len = conn - (blob_data + 4); |
1369 | if (len + 1> 5) | | 1373 | if (len + 1> 5) |
1370 | return -1; | | 1374 | return -1; |
1371 | memcpy(conn_id, blob_data + 4, len); | | 1375 | memcpy(conn_id, blob_data + 4, len); |
1372 | conn_id[len + 1] = '\0'; | | 1376 | conn_id[len + 1] = '\0'; |
1373 | id = strtoul(conn_id, NULL, 10); | | 1377 | id = strtoul(conn_id, NULL, 10); |
1374 | | | 1378 | |
1375 | *conn_base_id = id; | | 1379 | *conn_base_id = id; |
1376 | | | 1380 | |
1377 | *path = conn + 1; | | 1381 | *path = conn + 1; |
1378 | return 0; | | 1382 | return 0; |
1379 | } | | 1383 | } |
1380 | | | 1384 | |
1381 | static void | | 1385 | static void |
1382 | drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name, | | 1386 | drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name, |
1383 | drmModePropertyBlobPtr path_blob) | | 1387 | drmModePropertyBlobPtr path_blob) |
1384 | { | | 1388 | { |
1385 | int ret; | | 1389 | int ret; |
1386 | char *extra_path; | | 1390 | char *extra_path; |
1387 | int conn_id; | | 1391 | int conn_id; |
1388 | xf86OutputPtr output; | | 1392 | xf86OutputPtr output; |
1389 | | | 1393 | |
1390 | ret = parse_path_blob(path_blob, &conn_id, &extra_path); | | 1394 | ret = parse_path_blob(path_blob, &conn_id, &extra_path); |
1391 | if (ret == -1) | | 1395 | if (ret == -1) |
1392 | goto fallback; | | 1396 | goto fallback; |
1393 | | | 1397 | |
1394 | output = find_output(pScrn, conn_id); | | 1398 | output = find_output(pScrn, conn_id); |
1395 | if (!output) | | 1399 | if (!output) |
1396 | goto fallback; | | 1400 | goto fallback; |
1397 | | | 1401 | |
1398 | snprintf(name, 32, "%s-%s", output->name, extra_path); | | 1402 | snprintf(name, 32, "%s-%s", output->name, extra_path); |
1399 | return; | | 1403 | return; |
1400 | | | 1404 | |
1401 | fallback: | | 1405 | fallback: |
1402 | if (koutput->connector_type >= MS_ARRAY_SIZE(output_names)) | | 1406 | if (koutput->connector_type >= MS_ARRAY_SIZE(output_names)) |
1403 | snprintf(name, 32, "Unknown%d-%d", koutput->connector_type, koutput->connector_type_id); | | 1407 | snprintf(name, 32, "Unknown%d-%d", koutput->connector_type, koutput->connector_type_id); |
1404 | #ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT | | 1408 | #ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT |
1405 | else if (pScrn->is_gpu) | | 1409 | else if (pScrn->is_gpu) |
1406 | snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type], pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, koutput->connector_type_id); | | 1410 | snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type], pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, koutput->connector_type_id); |
1407 | #endif | | 1411 | #endif |
1408 | else | | 1412 | else |
1409 | snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id); | | 1413 | snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id); |
1410 | } | | 1414 | } |
1411 | | | 1415 | |
1412 | static unsigned int | | 1416 | static unsigned int |
1413 | drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, Bool dynamic, int crtcshift) | | 1417 | drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, Bool dynamic, int crtcshift) |
1414 | { | | 1418 | { |
1415 | xf86OutputPtr output; | | 1419 | xf86OutputPtr output; |
1416 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); | | 1420 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); |
1417 | drmModeConnectorPtr koutput; | | 1421 | drmModeConnectorPtr koutput; |
1418 | drmModeEncoderPtr *kencoders = NULL; | | 1422 | drmModeEncoderPtr *kencoders = NULL; |
1419 | drmmode_output_private_ptr drmmode_output; | | 1423 | drmmode_output_private_ptr drmmode_output; |
1420 | drmModePropertyPtr props; | | 1424 | drmModePropertyPtr props; |
1421 | char name[32]; | | 1425 | char name[32]; |
1422 | int i; | | 1426 | int i; |
1423 | drmModePropertyBlobPtr path_blob = NULL; | | 1427 | drmModePropertyBlobPtr path_blob = NULL; |
1424 | const char *s; | | 1428 | const char *s; |
1425 | koutput = | | 1429 | koutput = |
1426 | drmModeGetConnector(drmmode->fd, mode_res->connectors[num]); | | 1430 | drmModeGetConnector(drmmode->fd, mode_res->connectors[num]); |
1427 | if (!koutput) | | 1431 | if (!koutput) |
1428 | return 0; | | 1432 | return 0; |
1429 | | | 1433 | |
1430 | for (i = 0; i < koutput->count_props; i++) { | | 1434 | for (i = 0; i < koutput->count_props; i++) { |
1431 | props = drmModeGetProperty(drmmode->fd, koutput->props[i]); | | 1435 | props = drmModeGetProperty(drmmode->fd, koutput->props[i]); |
1432 | if (props && (props->flags & DRM_MODE_PROP_BLOB)) { | | 1436 | if (props && (props->flags & DRM_MODE_PROP_BLOB)) { |
1433 | if (!strcmp(props->name, "PATH")) { | | 1437 | if (!strcmp(props->name, "PATH")) { |
1434 | path_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); | | 1438 | path_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); |
1435 | drmModeFreeProperty(props); | | 1439 | drmModeFreeProperty(props); |
1436 | break; | | 1440 | break; |
1437 | } | | 1441 | } |
1438 | drmModeFreeProperty(props); | | 1442 | drmModeFreeProperty(props); |
1439 | } | | 1443 | } |
1440 | } | | 1444 | } |
1441 | | | 1445 | |
1442 | drmmode_create_name(pScrn, koutput, name, path_blob); | | 1446 | drmmode_create_name(pScrn, koutput, name, path_blob); |
1443 | | | 1447 | |
1444 | if (path_blob) | | 1448 | if (path_blob) |
1445 | drmModeFreePropertyBlob(path_blob); | | 1449 | drmModeFreePropertyBlob(path_blob); |
1446 | | | 1450 | |
1447 | if (path_blob && dynamic) { | | 1451 | if (path_blob && dynamic) { |
1448 | /* see if we have an output with this name already | | 1452 | /* see if we have an output with this name already |
1449 | and hook stuff up */ | | 1453 | and hook stuff up */ |
1450 | for (i = 0; i < xf86_config->num_output; i++) { | | 1454 | for (i = 0; i < xf86_config->num_output; i++) { |
1451 | output = xf86_config->output[i]; | | 1455 | output = xf86_config->output[i]; |
1452 | | | 1456 | |
1453 | if (strncmp(output->name, name, 32)) | | 1457 | if (strncmp(output->name, name, 32)) |
1454 | continue; | | 1458 | continue; |
1455 | | | 1459 | |
1456 | drmmode_output = output->driver_private; | | 1460 | drmmode_output = output->driver_private; |
1457 | drmmode_output->output_id = mode_res->connectors[num]; | | 1461 | drmmode_output->output_id = mode_res->connectors[num]; |
1458 | drmmode_output->mode_output = koutput; | | 1462 | drmmode_output->mode_output = koutput; |
1459 | return 1; | | 1463 | return 1; |
1460 | } | | 1464 | } |
1461 | } | | 1465 | } |
1462 | | | 1466 | |
1463 | kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders); | | 1467 | kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders); |
1464 | if (!kencoders) { | | 1468 | if (!kencoders) { |
1465 | goto out_free_encoders; | | 1469 | goto out_free_encoders; |
1466 | } | | 1470 | } |
1467 | | | 1471 | |
1468 | for (i = 0; i < koutput->count_encoders; i++) { | | 1472 | for (i = 0; i < koutput->count_encoders; i++) { |
1469 | kencoders[i] = drmModeGetEncoder(drmmode->fd, koutput->encoders[i]); | | 1473 | kencoders[i] = drmModeGetEncoder(drmmode->fd, koutput->encoders[i]); |
1470 | if (!kencoders[i]) { | | 1474 | if (!kencoders[i]) { |
1471 | goto out_free_encoders; | | 1475 | goto out_free_encoders; |
1472 | } | | 1476 | } |
1473 | } | | 1477 | } |
1474 | | | 1478 | |
1475 | if (xf86IsEntityShared(pScrn->entityList[0])) { | | 1479 | if (xf86IsEntityShared(pScrn->entityList[0])) { |
1476 | if ((s = xf86GetOptValString(drmmode->Options, OPTION_ZAPHOD_HEADS))) { | | 1480 | if ((s = xf86GetOptValString(drmmode->Options, OPTION_ZAPHOD_HEADS))) { |
1477 | if (!drmmode_zaphod_string_matches(pScrn, s, name)) | | 1481 | if (!drmmode_zaphod_string_matches(pScrn, s, name)) |
1478 | goto out_free_encoders; | | 1482 | goto out_free_encoders; |
1479 | } else { | | 1483 | } else { |
1480 | if (!drmmode->is_secondary && (num != 0)) | | 1484 | if (!drmmode->is_secondary && (num != 0)) |
1481 | goto out_free_encoders; | | 1485 | goto out_free_encoders; |
1482 | else if (drmmode->is_secondary && (num != 1)) | | 1486 | else if (drmmode->is_secondary && (num != 1)) |
1483 | goto out_free_encoders; | | 1487 | goto out_free_encoders; |
1484 | } | | 1488 | } |
1485 | } | | 1489 | } |
1486 | | | 1490 | |
1487 | output = xf86OutputCreate(pScrn, &drmmode_output_funcs, name); | | 1491 | output = xf86OutputCreate(pScrn, &drmmode_output_funcs, name); |
1488 | if (!output) { | | 1492 | if (!output) { |
1489 | goto out_free_encoders; | | 1493 | goto out_free_encoders; |
1490 | } | | 1494 | } |
1491 | | | 1495 | |
1492 | drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1); | | 1496 | drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1); |
1493 | if (!drmmode_output) { | | 1497 | if (!drmmode_output) { |
1494 | xf86OutputDestroy(output); | | 1498 | xf86OutputDestroy(output); |
1495 | goto out_free_encoders; | | 1499 | goto out_free_encoders; |
1496 | } | | 1500 | } |
1497 | | | 1501 | |
1498 | drmmode_output->output_id = mode_res->connectors[num]; | | 1502 | drmmode_output->output_id = mode_res->connectors[num]; |
1499 | drmmode_output->mode_output = koutput; | | 1503 | drmmode_output->mode_output = koutput; |
1500 | drmmode_output->mode_encoders = kencoders; | | 1504 | drmmode_output->mode_encoders = kencoders; |
1501 | drmmode_output->drmmode = drmmode; | | 1505 | drmmode_output->drmmode = drmmode; |
1502 | output->mm_width = koutput->mmWidth; | | 1506 | output->mm_width = koutput->mmWidth; |
1503 | output->mm_height = koutput->mmHeight; | | 1507 | output->mm_height = koutput->mmHeight; |
1504 | | | 1508 | |
1505 | output->subpixel_order = subpixel_conv_table[koutput->subpixel]; | | 1509 | output->subpixel_order = subpixel_conv_table[koutput->subpixel]; |
1506 | output->interlaceAllowed = TRUE; | | 1510 | output->interlaceAllowed = TRUE; |
1507 | output->doubleScanAllowed = TRUE; | | 1511 | output->doubleScanAllowed = TRUE; |
1508 | output->driver_private = drmmode_output; | | 1512 | output->driver_private = drmmode_output; |
1509 | | | 1513 | |
1510 | output->possible_crtcs = 0x7f; | | 1514 | output->possible_crtcs = 0x7f; |
1511 | for (i = 0; i < koutput->count_encoders; i++) { | | 1515 | for (i = 0; i < koutput->count_encoders; i++) { |
1512 | output->possible_crtcs &= kencoders[i]->possible_crtcs >> crtcshift; | | 1516 | output->possible_crtcs &= kencoders[i]->possible_crtcs >> crtcshift; |
1513 | } | | 1517 | } |
1514 | /* work out the possible clones later */ | | 1518 | /* work out the possible clones later */ |
1515 | output->possible_clones = 0; | | 1519 | output->possible_clones = 0; |
1516 | | | 1520 | |
1517 | for (i = 0; i < koutput->count_props; i++) { | | 1521 | for (i = 0; i < koutput->count_props; i++) { |
1518 | props = drmModeGetProperty(drmmode->fd, koutput->props[i]); | | 1522 | props = drmModeGetProperty(drmmode->fd, koutput->props[i]); |
1519 | if (props && (props->flags & DRM_MODE_PROP_ENUM)) { | | 1523 | if (props && (props->flags & DRM_MODE_PROP_ENUM)) { |
1520 | if (!strcmp(props->name, "DPMS")) { | | 1524 | if (!strcmp(props->name, "DPMS")) { |
1521 | drmmode_output->dpms_enum_id = koutput->props[i]; | | 1525 | drmmode_output->dpms_enum_id = koutput->props[i]; |
1522 | drmModeFreeProperty(props); | | 1526 | drmModeFreeProperty(props); |
1523 | break; | | 1527 | break; |
1524 | } | | 1528 | } |
1525 | drmModeFreeProperty(props); | | 1529 | drmModeFreeProperty(props); |
1526 | } | | 1530 | } |
1527 | } | | 1531 | } |
1528 | | | 1532 | |
1529 | if (dynamic) | | 1533 | if (dynamic) |
1530 | output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), output->name, strlen(output->name), output); | | 1534 | output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), output->name, strlen(output->name), output); |
1531 | return 1; | | 1535 | return 1; |
1532 | | | 1536 | |
1533 | out_free_encoders: | | 1537 | out_free_encoders: |
1534 | if (kencoders) { | | 1538 | if (kencoders) { |
1535 | for (i = 0; i < koutput->count_encoders; i++) | | 1539 | for (i = 0; i < koutput->count_encoders; i++) |
1536 | drmModeFreeEncoder(kencoders[i]); | | 1540 | drmModeFreeEncoder(kencoders[i]); |
1537 | free(kencoders); | | 1541 | free(kencoders); |
1538 | } | | 1542 | } |
1539 | drmModeFreeConnector(koutput); | | 1543 | drmModeFreeConnector(koutput); |
1540 | | | 1544 | |
1541 | return 0; | | 1545 | return 0; |
1542 | } | | 1546 | } |
1543 | | | 1547 | |
1544 | static uint32_t | | 1548 | static uint32_t |
1545 | find_clones(ScrnInfoPtr scrn, xf86OutputPtr output) | | 1549 | find_clones(ScrnInfoPtr scrn, xf86OutputPtr output) |
1546 | { | | 1550 | { |
1547 | drmmode_output_private_ptr drmmode_output = | | 1551 | drmmode_output_private_ptr drmmode_output = |
1548 | output->driver_private, clone_drmout; | | 1552 | output->driver_private, clone_drmout; |
1549 | int i; | | 1553 | int i; |
1550 | xf86OutputPtr clone_output; | | 1554 | xf86OutputPtr clone_output; |
1551 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); | | 1555 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); |
1552 | int index_mask = 0; | | 1556 | int index_mask = 0; |
1553 | | | 1557 | |
1554 | if (drmmode_output->enc_clone_mask == 0) | | 1558 | if (drmmode_output->enc_clone_mask == 0) |
1555 | return index_mask; | | 1559 | return index_mask; |
1556 | | | 1560 | |
1557 | for (i = 0; i < xf86_config->num_output; i++) { | | 1561 | for (i = 0; i < xf86_config->num_output; i++) { |
1558 | clone_output = xf86_config->output[i]; | | 1562 | clone_output = xf86_config->output[i]; |
1559 | clone_drmout = clone_output->driver_private; | | 1563 | clone_drmout = clone_output->driver_private; |
1560 | if (output == clone_output) | | 1564 | if (output == clone_output) |
1561 | continue; | | 1565 | continue; |
1562 | | | 1566 | |
1563 | if (clone_drmout->enc_mask == 0) | | 1567 | if (clone_drmout->enc_mask == 0) |
1564 | continue; | | 1568 | continue; |
1565 | if (drmmode_output->enc_clone_mask == clone_drmout->enc_mask) | | 1569 | if (drmmode_output->enc_clone_mask == clone_drmout->enc_mask) |
1566 | index_mask |= (1 << i); | | 1570 | index_mask |= (1 << i); |
1567 | } | | 1571 | } |
1568 | return index_mask; | | 1572 | return index_mask; |
1569 | } | | 1573 | } |
1570 | | | 1574 | |
1571 | static void | | 1575 | static void |
1572 | drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, drmModeResPtr mode_res) | | 1576 | drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, drmModeResPtr mode_res) |
1573 | { | | 1577 | { |
1574 | int i, j; | | 1578 | int i, j; |
1575 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); | | 1579 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); |
1576 | | | 1580 | |
1577 | for (i = 0; i < xf86_config->num_output; i++) { | | 1581 | for (i = 0; i < xf86_config->num_output; i++) { |
1578 | xf86OutputPtr output = xf86_config->output[i]; | | 1582 | xf86OutputPtr output = xf86_config->output[i]; |
1579 | drmmode_output_private_ptr drmmode_output; | | 1583 | drmmode_output_private_ptr drmmode_output; |
1580 | | | 1584 | |
1581 | drmmode_output = output->driver_private; | | 1585 | drmmode_output = output->driver_private; |
1582 | drmmode_output->enc_clone_mask = 0xff; | | 1586 | drmmode_output->enc_clone_mask = 0xff; |
1583 | /* and all the possible encoder clones for this output together */ | | 1587 | /* and all the possible encoder clones for this output together */ |
1584 | for (j = 0; j < drmmode_output->mode_output->count_encoders; j++) { | | 1588 | for (j = 0; j < drmmode_output->mode_output->count_encoders; j++) { |
1585 | int k; | | 1589 | int k; |
1586 | | | 1590 | |
1587 | for (k = 0; k < mode_res->count_encoders; k++) { | | 1591 | for (k = 0; k < mode_res->count_encoders; k++) { |
1588 | if (mode_res->encoders[k] == | | 1592 | if (mode_res->encoders[k] == |
1589 | drmmode_output->mode_encoders[j]->encoder_id) | | 1593 | drmmode_output->mode_encoders[j]->encoder_id) |
1590 | drmmode_output->enc_mask |= (1 << k); | | 1594 | drmmode_output->enc_mask |= (1 << k); |
1591 | } | | 1595 | } |
1592 | | | 1596 | |
1593 | drmmode_output->enc_clone_mask &= | | 1597 | drmmode_output->enc_clone_mask &= |
1594 | drmmode_output->mode_encoders[j]->possible_clones; | | 1598 | drmmode_output->mode_encoders[j]->possible_clones; |
1595 | } | | 1599 | } |
1596 | } | | 1600 | } |
1597 | | | 1601 | |
1598 | for (i = 0; i < xf86_config->num_output; i++) { | | 1602 | for (i = 0; i < xf86_config->num_output; i++) { |
1599 | xf86OutputPtr output = xf86_config->output[i]; | | 1603 | xf86OutputPtr output = xf86_config->output[i]; |
1600 | | | 1604 | |
1601 | output->possible_clones = find_clones(scrn, output); | | 1605 | output->possible_clones = find_clones(scrn, output); |
1602 | } | | 1606 | } |
1603 | } | | 1607 | } |
1604 | | | 1608 | |
1605 | static Bool | | 1609 | static Bool |
1606 | drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo) | | 1610 | drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo) |
1607 | { | | 1611 | { |
1608 | #ifdef GLAMOR | | 1612 | #ifdef GLAMOR |
1609 | ScrnInfoPtr scrn = drmmode->scrn; | | 1613 | ScrnInfoPtr scrn = drmmode->scrn; |
1610 | | | 1614 | |
1611 | if (!drmmode->glamor) | | 1615 | if (!drmmode->glamor) |
1612 | return TRUE; | | 1616 | return TRUE; |
1613 | | | 1617 | |
1614 | if (bo == NULL) { | | 1618 | if (bo == NULL) { |
1615 | glamor_egl_destroy_textured_pixmap(pixmap); | | 1619 | glamor_egl_destroy_textured_pixmap(pixmap); |
1616 | return TRUE; | | 1620 | return TRUE; |
1617 | } | | 1621 | } |
1618 | | | 1622 | |
1619 | #ifdef GLAMOR_HAS_GBM | | 1623 | #ifdef GLAMOR_HAS_GBM |
1620 | if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm)) { | | 1624 | if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm)) { |
1621 | xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed"); | | 1625 | xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed"); |
1622 | return FALSE; | | 1626 | return FALSE; |
1623 | } | | 1627 | } |
1624 | #else | | 1628 | #else |
1625 | if (!glamor_egl_create_textured_pixmap(pixmap, | | 1629 | if (!glamor_egl_create_textured_pixmap(pixmap, |
1626 | drmmode_bo_get_handle(&drmmode->front_bo), | | 1630 | drmmode_bo_get_handle(&drmmode->front_bo), |
1627 | scrn->displayWidth * | | 1631 | scrn->displayWidth * |
1628 | scrn->bitsPerPixel / 8)) { | | 1632 | scrn->bitsPerPixel / 8)) { |
1629 | xf86DrvMsg(scrn->scrnIndex, X_ERROR, | | 1633 | xf86DrvMsg(scrn->scrnIndex, X_ERROR, |
1630 | "glamor_egl_create_textured_pixmap() failed\n"); | | 1634 | "glamor_egl_create_textured_pixmap() failed\n"); |
1631 | return FALSE; | | 1635 | return FALSE; |
1632 | } | | 1636 | } |
1633 | #endif | | 1637 | #endif |
1634 | #endif | | 1638 | #endif |
1635 | | | 1639 | |
1636 | return TRUE; | | 1640 | return TRUE; |
1637 | } | | 1641 | } |
1638 | | | 1642 | |
1639 | Bool | | 1643 | Bool |
1640 | drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode) | | 1644 | drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode) |
1641 | { | | 1645 | { |
1642 | ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn); | | 1646 | ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn); |
1643 | PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); | | 1647 | PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); |
1644 | | | 1648 | |
1645 | if (!drmmode_set_pixmap_bo(drmmode, screen_pixmap, &drmmode->front_bo)) | | 1649 | if (!drmmode_set_pixmap_bo(drmmode, screen_pixmap, &drmmode->front_bo)) |
1646 | return FALSE; | | 1650 | return FALSE; |
1647 | | | 1651 | |
1648 | #ifdef GLAMOR | | 1652 | #ifdef GLAMOR |
1649 | if (drmmode->glamor) | | 1653 | if (drmmode->glamor) |
1650 | glamor_set_screen_pixmap(screen_pixmap, NULL); | | 1654 | glamor_set_screen_pixmap(screen_pixmap, NULL); |
1651 | #endif | | 1655 | #endif |
1652 | | | 1656 | |
1653 | return TRUE; | | 1657 | return TRUE; |
1654 | } | | 1658 | } |
1655 | | | 1659 | |
1656 | static Bool | | 1660 | static Bool |
1657 | drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) | | 1661 | drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) |
1658 | { | | 1662 | { |
1659 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); | | 1663 | xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); |
1660 | | | 1664 | |
1661 | drmmode_crtc_private_ptr | | 1665 | drmmode_crtc_private_ptr |
1662 | drmmode_crtc = xf86_config->crtc[0]->driver_private; | | 1666 | drmmode_crtc = xf86_config->crtc[0]->driver_private; |
1663 | drmmode_ptr drmmode = drmmode_crtc->drmmode; | | 1667 | drmmode_ptr drmmode = drmmode_crtc->drmmode; |
1664 | drmmode_bo old_front; | | 1668 | drmmode_bo old_front; |
1665 | Bool ret; | | 1669 | Bool ret; |
1666 | ScreenPtr screen = xf86ScrnToScreen(scrn); | | 1670 | ScreenPtr screen = xf86ScrnToScreen(scrn); |
1667 | uint32_t old_fb_id; | | 1671 | uint32_t old_fb_id; |
1668 | int i, pitch, old_width, old_height, old_pitch; | | 1672 | int i, pitch, old_width, old_height, old_pitch; |
1669 | int cpp = (scrn->bitsPerPixel + 7) / 8; | | 1673 | int cpp = (scrn->bitsPerPixel + 7) / 8; |
1670 | int kcpp = (drmmode->kbpp + 7) / 8; | | 1674 | int kcpp = (drmmode->kbpp + 7) / 8; |
1671 | PixmapPtr ppix = screen->GetScreenPixmap(screen); | | 1675 | PixmapPtr ppix = screen->GetScreenPixmap(screen); |
1672 | void *new_pixels = NULL; | | 1676 | void *new_pixels = NULL; |
1673 | | | 1677 | |
1674 | if (scrn->virtualX == width && scrn->virtualY == height) | | 1678 | if (scrn->virtualX == width && scrn->virtualY == height) |
1675 | return TRUE; | | 1679 | return TRUE; |
1676 | | | 1680 | |
1677 | xf86DrvMsg(scrn->scrnIndex, X_INFO, | | 1681 | xf86DrvMsg(scrn->scrnIndex, X_INFO, |
1678 | "Allocate new frame buffer %dx%d stride\n", width, height); | | 1682 | "Allocate new frame buffer %dx%d stride\n", width, height); |
1679 | | | 1683 | |
1680 | if (drmmode->triple_buffer_pixmap) { | | 1684 | if (drmmode->triple_buffer_pixmap) { |