diff options
Diffstat (limited to 'drivers/gpu/drm/qxl/qxl_draw.c')
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_draw.c | 263 |
1 files changed, 180 insertions, 83 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_draw.c b/drivers/gpu/drm/qxl/qxl_draw.c index 3c8c3dbf9378..56e1d633875e 100644 --- a/drivers/gpu/drm/qxl/qxl_draw.c +++ b/drivers/gpu/drm/qxl/qxl_draw.c | |||
@@ -23,25 +23,29 @@ | |||
23 | #include "qxl_drv.h" | 23 | #include "qxl_drv.h" |
24 | #include "qxl_object.h" | 24 | #include "qxl_object.h" |
25 | 25 | ||
26 | static int alloc_clips(struct qxl_device *qdev, | ||
27 | struct qxl_release *release, | ||
28 | unsigned num_clips, | ||
29 | struct qxl_bo **clips_bo) | ||
30 | { | ||
31 | int size = sizeof(struct qxl_clip_rects) + sizeof(struct qxl_rect) * num_clips; | ||
32 | |||
33 | return qxl_alloc_bo_reserved(qdev, release, size, clips_bo); | ||
34 | } | ||
35 | |||
26 | /* returns a pointer to the already allocated qxl_rect array inside | 36 | /* returns a pointer to the already allocated qxl_rect array inside |
27 | * the qxl_clip_rects. This is *not* the same as the memory allocated | 37 | * the qxl_clip_rects. This is *not* the same as the memory allocated |
28 | * on the device, it is offset to qxl_clip_rects.chunk.data */ | 38 | * on the device, it is offset to qxl_clip_rects.chunk.data */ |
29 | static struct qxl_rect *drawable_set_clipping(struct qxl_device *qdev, | 39 | static struct qxl_rect *drawable_set_clipping(struct qxl_device *qdev, |
30 | struct qxl_drawable *drawable, | 40 | struct qxl_drawable *drawable, |
31 | unsigned num_clips, | 41 | unsigned num_clips, |
32 | struct qxl_bo **clips_bo, | 42 | struct qxl_bo *clips_bo) |
33 | struct qxl_release *release) | ||
34 | { | 43 | { |
35 | struct qxl_clip_rects *dev_clips; | 44 | struct qxl_clip_rects *dev_clips; |
36 | int ret; | 45 | int ret; |
37 | int size = sizeof(*dev_clips) + sizeof(struct qxl_rect) * num_clips; | ||
38 | ret = qxl_alloc_bo_reserved(qdev, size, clips_bo); | ||
39 | if (ret) | ||
40 | return NULL; | ||
41 | 46 | ||
42 | ret = qxl_bo_kmap(*clips_bo, (void **)&dev_clips); | 47 | ret = qxl_bo_kmap(clips_bo, (void **)&dev_clips); |
43 | if (ret) { | 48 | if (ret) { |
44 | qxl_bo_unref(clips_bo); | ||
45 | return NULL; | 49 | return NULL; |
46 | } | 50 | } |
47 | dev_clips->num_rects = num_clips; | 51 | dev_clips->num_rects = num_clips; |
@@ -52,20 +56,34 @@ static struct qxl_rect *drawable_set_clipping(struct qxl_device *qdev, | |||
52 | } | 56 | } |
53 | 57 | ||
54 | static int | 58 | static int |
59 | alloc_drawable(struct qxl_device *qdev, struct qxl_release **release) | ||
60 | { | ||
61 | int ret; | ||
62 | ret = qxl_alloc_release_reserved(qdev, sizeof(struct qxl_drawable), | ||
63 | QXL_RELEASE_DRAWABLE, release, | ||
64 | NULL); | ||
65 | return ret; | ||
66 | } | ||
67 | |||
68 | static void | ||
69 | free_drawable(struct qxl_device *qdev, struct qxl_release *release) | ||
70 | { | ||
71 | qxl_release_free(qdev, release); | ||
72 | } | ||
73 | |||
74 | /* release needs to be reserved at this point */ | ||
75 | static int | ||
55 | make_drawable(struct qxl_device *qdev, int surface, uint8_t type, | 76 | make_drawable(struct qxl_device *qdev, int surface, uint8_t type, |
56 | const struct qxl_rect *rect, | 77 | const struct qxl_rect *rect, |
57 | struct qxl_release **release) | 78 | struct qxl_release *release) |
58 | { | 79 | { |
59 | struct qxl_drawable *drawable; | 80 | struct qxl_drawable *drawable; |
60 | int i, ret; | 81 | int i; |
61 | 82 | ||
62 | ret = qxl_alloc_release_reserved(qdev, sizeof(*drawable), | 83 | drawable = (struct qxl_drawable *)qxl_release_map(qdev, release); |
63 | QXL_RELEASE_DRAWABLE, release, | 84 | if (!drawable) |
64 | NULL); | 85 | return -ENOMEM; |
65 | if (ret) | ||
66 | return ret; | ||
67 | 86 | ||
68 | drawable = (struct qxl_drawable *)qxl_release_map(qdev, *release); | ||
69 | drawable->type = type; | 87 | drawable->type = type; |
70 | 88 | ||
71 | drawable->surface_id = surface; /* Only primary for now */ | 89 | drawable->surface_id = surface; /* Only primary for now */ |
@@ -91,14 +109,23 @@ make_drawable(struct qxl_device *qdev, int surface, uint8_t type, | |||
91 | drawable->bbox = *rect; | 109 | drawable->bbox = *rect; |
92 | 110 | ||
93 | drawable->mm_time = qdev->rom->mm_clock; | 111 | drawable->mm_time = qdev->rom->mm_clock; |
94 | qxl_release_unmap(qdev, *release, &drawable->release_info); | 112 | qxl_release_unmap(qdev, release, &drawable->release_info); |
95 | return 0; | 113 | return 0; |
96 | } | 114 | } |
97 | 115 | ||
98 | static int qxl_palette_create_1bit(struct qxl_bo **palette_bo, | 116 | static int alloc_palette_object(struct qxl_device *qdev, |
117 | struct qxl_release *release, | ||
118 | struct qxl_bo **palette_bo) | ||
119 | { | ||
120 | return qxl_alloc_bo_reserved(qdev, release, | ||
121 | sizeof(struct qxl_palette) + sizeof(uint32_t) * 2, | ||
122 | palette_bo); | ||
123 | } | ||
124 | |||
125 | static int qxl_palette_create_1bit(struct qxl_bo *palette_bo, | ||
126 | struct qxl_release *release, | ||
99 | const struct qxl_fb_image *qxl_fb_image) | 127 | const struct qxl_fb_image *qxl_fb_image) |
100 | { | 128 | { |
101 | struct qxl_device *qdev = qxl_fb_image->qdev; | ||
102 | const struct fb_image *fb_image = &qxl_fb_image->fb_image; | 129 | const struct fb_image *fb_image = &qxl_fb_image->fb_image; |
103 | uint32_t visual = qxl_fb_image->visual; | 130 | uint32_t visual = qxl_fb_image->visual; |
104 | const uint32_t *pseudo_palette = qxl_fb_image->pseudo_palette; | 131 | const uint32_t *pseudo_palette = qxl_fb_image->pseudo_palette; |
@@ -108,12 +135,7 @@ static int qxl_palette_create_1bit(struct qxl_bo **palette_bo, | |||
108 | static uint64_t unique; /* we make no attempt to actually set this | 135 | static uint64_t unique; /* we make no attempt to actually set this |
109 | * correctly globaly, since that would require | 136 | * correctly globaly, since that would require |
110 | * tracking all of our palettes. */ | 137 | * tracking all of our palettes. */ |
111 | 138 | ret = qxl_bo_kmap(palette_bo, (void **)&pal); | |
112 | ret = qxl_alloc_bo_reserved(qdev, | ||
113 | sizeof(struct qxl_palette) + sizeof(uint32_t) * 2, | ||
114 | palette_bo); | ||
115 | |||
116 | ret = qxl_bo_kmap(*palette_bo, (void **)&pal); | ||
117 | pal->num_ents = 2; | 139 | pal->num_ents = 2; |
118 | pal->unique = unique++; | 140 | pal->unique = unique++; |
119 | if (visual == FB_VISUAL_TRUECOLOR || visual == FB_VISUAL_DIRECTCOLOR) { | 141 | if (visual == FB_VISUAL_TRUECOLOR || visual == FB_VISUAL_DIRECTCOLOR) { |
@@ -126,7 +148,7 @@ static int qxl_palette_create_1bit(struct qxl_bo **palette_bo, | |||
126 | } | 148 | } |
127 | pal->ents[0] = bgcolor; | 149 | pal->ents[0] = bgcolor; |
128 | pal->ents[1] = fgcolor; | 150 | pal->ents[1] = fgcolor; |
129 | qxl_bo_kunmap(*palette_bo); | 151 | qxl_bo_kunmap(palette_bo); |
130 | return 0; | 152 | return 0; |
131 | } | 153 | } |
132 | 154 | ||
@@ -144,44 +166,63 @@ void qxl_draw_opaque_fb(const struct qxl_fb_image *qxl_fb_image, | |||
144 | const char *src = fb_image->data; | 166 | const char *src = fb_image->data; |
145 | int depth = fb_image->depth; | 167 | int depth = fb_image->depth; |
146 | struct qxl_release *release; | 168 | struct qxl_release *release; |
147 | struct qxl_bo *image_bo; | ||
148 | struct qxl_image *image; | 169 | struct qxl_image *image; |
149 | int ret; | 170 | int ret; |
150 | 171 | struct qxl_drm_image *dimage; | |
172 | struct qxl_bo *palette_bo = NULL; | ||
151 | if (stride == 0) | 173 | if (stride == 0) |
152 | stride = depth * width / 8; | 174 | stride = depth * width / 8; |
153 | 175 | ||
176 | ret = alloc_drawable(qdev, &release); | ||
177 | if (ret) | ||
178 | return; | ||
179 | |||
180 | ret = qxl_image_alloc_objects(qdev, release, | ||
181 | &dimage, | ||
182 | height, stride); | ||
183 | if (ret) | ||
184 | goto out_free_drawable; | ||
185 | |||
186 | if (depth == 1) { | ||
187 | ret = alloc_palette_object(qdev, release, &palette_bo); | ||
188 | if (ret) | ||
189 | goto out_free_image; | ||
190 | } | ||
191 | |||
192 | /* do a reservation run over all the objects we just allocated */ | ||
193 | ret = qxl_release_reserve_list(release, true); | ||
194 | if (ret) | ||
195 | goto out_free_palette; | ||
196 | |||
154 | rect.left = x; | 197 | rect.left = x; |
155 | rect.right = x + width; | 198 | rect.right = x + width; |
156 | rect.top = y; | 199 | rect.top = y; |
157 | rect.bottom = y + height; | 200 | rect.bottom = y + height; |
158 | 201 | ||
159 | ret = make_drawable(qdev, 0, QXL_DRAW_COPY, &rect, &release); | 202 | ret = make_drawable(qdev, 0, QXL_DRAW_COPY, &rect, release); |
160 | if (ret) | 203 | if (ret) { |
161 | return; | 204 | qxl_release_backoff_reserve_list(release); |
205 | goto out_free_palette; | ||
206 | } | ||
162 | 207 | ||
163 | ret = qxl_image_create(qdev, release, &image_bo, | 208 | ret = qxl_image_init(qdev, release, dimage, |
164 | (const uint8_t *)src, 0, 0, | 209 | (const uint8_t *)src, 0, 0, |
165 | width, height, depth, stride); | 210 | width, height, depth, stride); |
166 | if (ret) { | 211 | if (ret) { |
167 | qxl_release_unreserve(qdev, release); | 212 | qxl_release_backoff_reserve_list(release); |
168 | qxl_release_free(qdev, release); | 213 | qxl_release_free(qdev, release); |
169 | return; | 214 | return; |
170 | } | 215 | } |
171 | 216 | ||
172 | if (depth == 1) { | 217 | if (depth == 1) { |
173 | struct qxl_bo *palette_bo; | ||
174 | void *ptr; | 218 | void *ptr; |
175 | ret = qxl_palette_create_1bit(&palette_bo, qxl_fb_image); | 219 | ret = qxl_palette_create_1bit(palette_bo, release, qxl_fb_image); |
176 | qxl_release_add_res(qdev, release, palette_bo); | ||
177 | 220 | ||
178 | ptr = qxl_bo_kmap_atomic_page(qdev, image_bo, 0); | 221 | ptr = qxl_bo_kmap_atomic_page(qdev, dimage->bo, 0); |
179 | image = ptr; | 222 | image = ptr; |
180 | image->u.bitmap.palette = | 223 | image->u.bitmap.palette = |
181 | qxl_bo_physical_address(qdev, palette_bo, 0); | 224 | qxl_bo_physical_address(qdev, palette_bo, 0); |
182 | qxl_bo_kunmap_atomic_page(qdev, image_bo, ptr); | 225 | qxl_bo_kunmap_atomic_page(qdev, dimage->bo, ptr); |
183 | qxl_bo_unreserve(palette_bo); | ||
184 | qxl_bo_unref(&palette_bo); | ||
185 | } | 226 | } |
186 | 227 | ||
187 | drawable = (struct qxl_drawable *)qxl_release_map(qdev, release); | 228 | drawable = (struct qxl_drawable *)qxl_release_map(qdev, release); |
@@ -199,16 +240,20 @@ void qxl_draw_opaque_fb(const struct qxl_fb_image *qxl_fb_image, | |||
199 | drawable->u.copy.mask.bitmap = 0; | 240 | drawable->u.copy.mask.bitmap = 0; |
200 | 241 | ||
201 | drawable->u.copy.src_bitmap = | 242 | drawable->u.copy.src_bitmap = |
202 | qxl_bo_physical_address(qdev, image_bo, 0); | 243 | qxl_bo_physical_address(qdev, dimage->bo, 0); |
203 | qxl_release_unmap(qdev, release, &drawable->release_info); | 244 | qxl_release_unmap(qdev, release, &drawable->release_info); |
204 | 245 | ||
205 | qxl_release_add_res(qdev, release, image_bo); | ||
206 | qxl_bo_unreserve(image_bo); | ||
207 | qxl_bo_unref(&image_bo); | ||
208 | |||
209 | qxl_fence_releaseable(qdev, release); | ||
210 | qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); | 246 | qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); |
211 | qxl_release_unreserve(qdev, release); | 247 | qxl_release_fence_buffer_objects(release); |
248 | |||
249 | out_free_palette: | ||
250 | if (palette_bo) | ||
251 | qxl_bo_unref(&palette_bo); | ||
252 | out_free_image: | ||
253 | qxl_image_free_objects(qdev, dimage); | ||
254 | out_free_drawable: | ||
255 | if (ret) | ||
256 | free_drawable(qdev, release); | ||
212 | } | 257 | } |
213 | 258 | ||
214 | /* push a draw command using the given clipping rectangles as | 259 | /* push a draw command using the given clipping rectangles as |
@@ -243,10 +288,14 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, | |||
243 | int depth = qxl_fb->base.bits_per_pixel; | 288 | int depth = qxl_fb->base.bits_per_pixel; |
244 | uint8_t *surface_base; | 289 | uint8_t *surface_base; |
245 | struct qxl_release *release; | 290 | struct qxl_release *release; |
246 | struct qxl_bo *image_bo; | ||
247 | struct qxl_bo *clips_bo; | 291 | struct qxl_bo *clips_bo; |
292 | struct qxl_drm_image *dimage; | ||
248 | int ret; | 293 | int ret; |
249 | 294 | ||
295 | ret = alloc_drawable(qdev, &release); | ||
296 | if (ret) | ||
297 | return; | ||
298 | |||
250 | left = clips->x1; | 299 | left = clips->x1; |
251 | right = clips->x2; | 300 | right = clips->x2; |
252 | top = clips->y1; | 301 | top = clips->y1; |
@@ -263,36 +312,52 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, | |||
263 | 312 | ||
264 | width = right - left; | 313 | width = right - left; |
265 | height = bottom - top; | 314 | height = bottom - top; |
315 | |||
316 | ret = alloc_clips(qdev, release, num_clips, &clips_bo); | ||
317 | if (ret) | ||
318 | goto out_free_drawable; | ||
319 | |||
320 | ret = qxl_image_alloc_objects(qdev, release, | ||
321 | &dimage, | ||
322 | height, stride); | ||
323 | if (ret) | ||
324 | goto out_free_clips; | ||
325 | |||
326 | /* do a reservation run over all the objects we just allocated */ | ||
327 | ret = qxl_release_reserve_list(release, true); | ||
328 | if (ret) | ||
329 | goto out_free_image; | ||
330 | |||
266 | drawable_rect.left = left; | 331 | drawable_rect.left = left; |
267 | drawable_rect.right = right; | 332 | drawable_rect.right = right; |
268 | drawable_rect.top = top; | 333 | drawable_rect.top = top; |
269 | drawable_rect.bottom = bottom; | 334 | drawable_rect.bottom = bottom; |
335 | |||
270 | ret = make_drawable(qdev, 0, QXL_DRAW_COPY, &drawable_rect, | 336 | ret = make_drawable(qdev, 0, QXL_DRAW_COPY, &drawable_rect, |
271 | &release); | 337 | release); |
272 | if (ret) | 338 | if (ret) |
273 | return; | 339 | goto out_release_backoff; |
274 | 340 | ||
275 | ret = qxl_bo_kmap(bo, (void **)&surface_base); | 341 | ret = qxl_bo_kmap(bo, (void **)&surface_base); |
276 | if (ret) | 342 | if (ret) |
277 | goto out_unref; | 343 | goto out_release_backoff; |
278 | 344 | ||
279 | ret = qxl_image_create(qdev, release, &image_bo, surface_base, | 345 | |
280 | left, top, width, height, depth, stride); | 346 | ret = qxl_image_init(qdev, release, dimage, surface_base, |
347 | left, top, width, height, depth, stride); | ||
281 | qxl_bo_kunmap(bo); | 348 | qxl_bo_kunmap(bo); |
282 | if (ret) | 349 | if (ret) |
283 | goto out_unref; | 350 | goto out_release_backoff; |
351 | |||
352 | rects = drawable_set_clipping(qdev, drawable, num_clips, clips_bo); | ||
353 | if (!rects) | ||
354 | goto out_release_backoff; | ||
284 | 355 | ||
285 | rects = drawable_set_clipping(qdev, drawable, num_clips, &clips_bo, release); | ||
286 | if (!rects) { | ||
287 | qxl_bo_unref(&image_bo); | ||
288 | goto out_unref; | ||
289 | } | ||
290 | drawable = (struct qxl_drawable *)qxl_release_map(qdev, release); | 356 | drawable = (struct qxl_drawable *)qxl_release_map(qdev, release); |
291 | 357 | ||
292 | drawable->clip.type = SPICE_CLIP_TYPE_RECTS; | 358 | drawable->clip.type = SPICE_CLIP_TYPE_RECTS; |
293 | drawable->clip.data = qxl_bo_physical_address(qdev, | 359 | drawable->clip.data = qxl_bo_physical_address(qdev, |
294 | clips_bo, 0); | 360 | clips_bo, 0); |
295 | qxl_release_add_res(qdev, release, clips_bo); | ||
296 | 361 | ||
297 | drawable->u.copy.src_area.top = 0; | 362 | drawable->u.copy.src_area.top = 0; |
298 | drawable->u.copy.src_area.bottom = height; | 363 | drawable->u.copy.src_area.bottom = height; |
@@ -306,11 +371,9 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, | |||
306 | drawable->u.copy.mask.pos.y = 0; | 371 | drawable->u.copy.mask.pos.y = 0; |
307 | drawable->u.copy.mask.bitmap = 0; | 372 | drawable->u.copy.mask.bitmap = 0; |
308 | 373 | ||
309 | drawable->u.copy.src_bitmap = qxl_bo_physical_address(qdev, image_bo, 0); | 374 | drawable->u.copy.src_bitmap = qxl_bo_physical_address(qdev, dimage->bo, 0); |
310 | qxl_release_unmap(qdev, release, &drawable->release_info); | 375 | qxl_release_unmap(qdev, release, &drawable->release_info); |
311 | qxl_release_add_res(qdev, release, image_bo); | 376 | |
312 | qxl_bo_unreserve(image_bo); | ||
313 | qxl_bo_unref(&image_bo); | ||
314 | clips_ptr = clips; | 377 | clips_ptr = clips; |
315 | for (i = 0; i < num_clips; i++, clips_ptr += inc) { | 378 | for (i = 0; i < num_clips; i++, clips_ptr += inc) { |
316 | rects[i].left = clips_ptr->x1; | 379 | rects[i].left = clips_ptr->x1; |
@@ -319,17 +382,22 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, | |||
319 | rects[i].bottom = clips_ptr->y2; | 382 | rects[i].bottom = clips_ptr->y2; |
320 | } | 383 | } |
321 | qxl_bo_kunmap(clips_bo); | 384 | qxl_bo_kunmap(clips_bo); |
322 | qxl_bo_unreserve(clips_bo); | ||
323 | qxl_bo_unref(&clips_bo); | ||
324 | 385 | ||
325 | qxl_fence_releaseable(qdev, release); | ||
326 | qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); | 386 | qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); |
327 | qxl_release_unreserve(qdev, release); | 387 | qxl_release_fence_buffer_objects(release); |
328 | return; | 388 | |
389 | out_release_backoff: | ||
390 | if (ret) | ||
391 | qxl_release_backoff_reserve_list(release); | ||
392 | out_free_image: | ||
393 | qxl_image_free_objects(qdev, dimage); | ||
394 | out_free_clips: | ||
395 | qxl_bo_unref(&clips_bo); | ||
396 | out_free_drawable: | ||
397 | /* only free drawable on error */ | ||
398 | if (ret) | ||
399 | free_drawable(qdev, release); | ||
329 | 400 | ||
330 | out_unref: | ||
331 | qxl_release_unreserve(qdev, release); | ||
332 | qxl_release_free(qdev, release); | ||
333 | } | 401 | } |
334 | 402 | ||
335 | void qxl_draw_copyarea(struct qxl_device *qdev, | 403 | void qxl_draw_copyarea(struct qxl_device *qdev, |
@@ -342,22 +410,36 @@ void qxl_draw_copyarea(struct qxl_device *qdev, | |||
342 | struct qxl_release *release; | 410 | struct qxl_release *release; |
343 | int ret; | 411 | int ret; |
344 | 412 | ||
413 | ret = alloc_drawable(qdev, &release); | ||
414 | if (ret) | ||
415 | return; | ||
416 | |||
417 | /* do a reservation run over all the objects we just allocated */ | ||
418 | ret = qxl_release_reserve_list(release, true); | ||
419 | if (ret) | ||
420 | goto out_free_release; | ||
421 | |||
345 | rect.left = dx; | 422 | rect.left = dx; |
346 | rect.top = dy; | 423 | rect.top = dy; |
347 | rect.right = dx + width; | 424 | rect.right = dx + width; |
348 | rect.bottom = dy + height; | 425 | rect.bottom = dy + height; |
349 | ret = make_drawable(qdev, 0, QXL_COPY_BITS, &rect, &release); | 426 | ret = make_drawable(qdev, 0, QXL_COPY_BITS, &rect, release); |
350 | if (ret) | 427 | if (ret) { |
351 | return; | 428 | qxl_release_backoff_reserve_list(release); |
429 | goto out_free_release; | ||
430 | } | ||
352 | 431 | ||
353 | drawable = (struct qxl_drawable *)qxl_release_map(qdev, release); | 432 | drawable = (struct qxl_drawable *)qxl_release_map(qdev, release); |
354 | drawable->u.copy_bits.src_pos.x = sx; | 433 | drawable->u.copy_bits.src_pos.x = sx; |
355 | drawable->u.copy_bits.src_pos.y = sy; | 434 | drawable->u.copy_bits.src_pos.y = sy; |
356 | |||
357 | qxl_release_unmap(qdev, release, &drawable->release_info); | 435 | qxl_release_unmap(qdev, release, &drawable->release_info); |
358 | qxl_fence_releaseable(qdev, release); | 436 | |
359 | qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); | 437 | qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); |
360 | qxl_release_unreserve(qdev, release); | 438 | qxl_release_fence_buffer_objects(release); |
439 | |||
440 | out_free_release: | ||
441 | if (ret) | ||
442 | free_drawable(qdev, release); | ||
361 | } | 443 | } |
362 | 444 | ||
363 | void qxl_draw_fill(struct qxl_draw_fill *qxl_draw_fill_rec) | 445 | void qxl_draw_fill(struct qxl_draw_fill *qxl_draw_fill_rec) |
@@ -370,10 +452,21 @@ void qxl_draw_fill(struct qxl_draw_fill *qxl_draw_fill_rec) | |||
370 | struct qxl_release *release; | 452 | struct qxl_release *release; |
371 | int ret; | 453 | int ret; |
372 | 454 | ||
373 | ret = make_drawable(qdev, 0, QXL_DRAW_FILL, &rect, &release); | 455 | ret = alloc_drawable(qdev, &release); |
374 | if (ret) | 456 | if (ret) |
375 | return; | 457 | return; |
376 | 458 | ||
459 | /* do a reservation run over all the objects we just allocated */ | ||
460 | ret = qxl_release_reserve_list(release, true); | ||
461 | if (ret) | ||
462 | goto out_free_release; | ||
463 | |||
464 | ret = make_drawable(qdev, 0, QXL_DRAW_FILL, &rect, release); | ||
465 | if (ret) { | ||
466 | qxl_release_backoff_reserve_list(release); | ||
467 | goto out_free_release; | ||
468 | } | ||
469 | |||
377 | drawable = (struct qxl_drawable *)qxl_release_map(qdev, release); | 470 | drawable = (struct qxl_drawable *)qxl_release_map(qdev, release); |
378 | drawable->u.fill.brush.type = SPICE_BRUSH_TYPE_SOLID; | 471 | drawable->u.fill.brush.type = SPICE_BRUSH_TYPE_SOLID; |
379 | drawable->u.fill.brush.u.color = color; | 472 | drawable->u.fill.brush.u.color = color; |
@@ -384,7 +477,11 @@ void qxl_draw_fill(struct qxl_draw_fill *qxl_draw_fill_rec) | |||
384 | drawable->u.fill.mask.bitmap = 0; | 477 | drawable->u.fill.mask.bitmap = 0; |
385 | 478 | ||
386 | qxl_release_unmap(qdev, release, &drawable->release_info); | 479 | qxl_release_unmap(qdev, release, &drawable->release_info); |
387 | qxl_fence_releaseable(qdev, release); | 480 | |
388 | qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); | 481 | qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); |
389 | qxl_release_unreserve(qdev, release); | 482 | qxl_release_fence_buffer_objects(release); |
483 | |||
484 | out_free_release: | ||
485 | if (ret) | ||
486 | free_drawable(qdev, release); | ||
390 | } | 487 | } |