@@ -290,34 +290,60 @@ static void update_cursor(AppleGFXState *s)
static void set_mode(AppleGFXState *s, uint32_t width, uint32_t height)
{
- void *vram = g_malloc0(width * height * 4);
+ void *vram = NULL;
void *old_vram = s->vram;
DisplaySurface *surface;
MTLTextureDescriptor *textureDescriptor;
- id<MTLTexture> old_texture = s->texture;
+ id<MTLTexture> old_texture = nil;
+ id<MTLTexture> texture = nil;
+ bool locking_required = false;
+ locking_required = !bql_locked();
+ if (locking_required) {
+ bql_lock();
+ }
if (s->surface &&
width == surface_width(s->surface) &&
height == surface_height(s->surface)) {
+ if (locking_required) {
+ bql_unlock();
+ }
return;
}
+ if (locking_required) {
+ bql_unlock();
+ }
+
+ vram = g_malloc0(width * height * 4);
surface = qemu_create_displaysurface_from(width, height, PIXMAN_LE_a8r8g8b8,
width * 4, vram);
- s->surface = surface;
- dpy_gfx_replace_surface(s->con, surface);
- s->vram = vram;
- g_free(old_vram);
- textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
- width:width
- height:height
- mipmapped:NO];
- textureDescriptor.usage = s->pgdisp.minimumTextureUsage;
- s->texture = [s->mtl newTextureWithDescriptor:textureDescriptor];
+ @autoreleasepool {
+ textureDescriptor =
+ [MTLTextureDescriptor
+ texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
+ width:width
+ height:height
+ mipmapped:NO];
+ textureDescriptor.usage = s->pgdisp.minimumTextureUsage;
+ texture = [s->mtl newTextureWithDescriptor:textureDescriptor];
+ }
- if (old_texture) {
- [old_texture release];
+ if (locking_required) {
+ bql_lock();
+ }
+ old_vram = s->vram;
+ s->vram = vram;
+ s->surface = surface;
+ dpy_gfx_replace_surface(s->con, surface);
+ old_texture = s->texture;
+ s->texture = texture;
+ if (locking_required) {
+ bql_unlock();
}
+
+ g_free(old_vram);
+ [old_texture release];
}
static void create_fb(AppleGFXState *s)
When the set_mode callback was invoked outside of the BQL, there could be a race condition swapping out the resized render target texture and VRAM. set_mode may be called inside or out of the BQL depending on context (reentrant from a MMIO write or not) so we need to check locking state first. Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu> --- hw/display/apple-gfx.m | 54 +++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 14 deletions(-)