drawsAsynchronously doesn't update correctly + related crash?

Hi there, on our macOS app we're using NSView.layer.drawsAsynchronously=YES to draw the content of a NSView:


    self.wantsLayer = true;
    self.layer.drawsAsynchronously = true;


Where self is a NSView.


Before macOS Catalina the app worked great, but after Catalina I started noticing that sometimes some parts are not completelly redraw/updated in the view. Not sure if something has changed in the middle about this drawsAsynchronously flag (without the flag there are no issues, but the performance drops as we are doing some heavy color space conversions).


Anyway today we got a crash report, but this case is from Mac OS X 10.14.6 (18G103), not sure if it's related or already fixed in Catalina (maybe some recommendation to give to this specific user would be to update to macOS 10.15):


Thread 13 Crashed:: Dispatch queue: CA::CG::Queue
0   com.apple.CoreFoundation      0x00007fff53a60019 CFEqual + 49
1   com.apple.CoreFoundation      0x00007fff53a5d93e CFBasicHashFindBucket + 1218
2   com.apple.CoreFoundation      0x00007fff53a5d456 CFDictionaryGetValue + 90
3   com.apple.driver.AppleIntelBDWGraphicsMTLDriver 0x00007fff4b510648 -[MTLIGAccelDevice newTextureWithDescriptor:iosurface:plane:] + 217
4   com.apple.QuartzCore          0x00007fff5e67efc0 CA::OGL::MetalContext::update_surface(CA::OGL::MetalImage*, CA::Render::Surface*, unsigned int, char const*) + 2986
5   com.apple.QuartzCore          0x00007fff5e541a8b CA::OGL::MetalContext::bind_image_impl(unsigned int, CA::Render::Texture*, unsigned int, CA::OGL::TextureFilter, CA::OGL::TextureFilter, float, CA::OGL::TextureEdgeMode, float*, char const*) + 559
6   com.apple.QuartzCore          0x00007fff5e541018 CA::OGL::Context::bind_image(unsigned int, CA::Render::Texture*, unsigned int, CA::OGL::TextureFilter, CA::OGL::TextureFilter, float, CA::OGL::TextureEdgeMode, CA::OGL::ContentsGeometry const*, float*, char const*) + 1046
7   com.apple.QuartzCore          0x00007fff5e5470ce CA::CG::fill_image(CA::CG::Renderer&, CGImage*, CA::Rect const&, CA::Mat2 const&, bool, bool, CGInterpolationQuality, CA::Bounds const*) + 4823
8   com.apple.QuartzCore          0x00007fff5e545dd8 CA::CG::DrawImage::draw_image(CA::CG::Renderer&, bool) const + 194
9   com.apple.QuartzCore          0x00007fff5e532919 CA::CG::DrawOp::render(CA::CG::Renderer&) const + 1919
10  com.apple.QuartzCore          0x00007fff5e52dfc1 CA::CG::Queue::render_callback(void*) + 1351
11  libdispatch.dylib              0x00007fff7f99963d _dispatch_client_callout + 8
12  libdispatch.dylib              0x00007fff7f99fa17 _dispatch_lane_serial_drain + 913
13  libdispatch.dylib              0x00007fff7f9a0396 _dispatch_lane_invoke + 385
14  libdispatch.dylib              0x00007fff7f9a86ed _dispatch_workloop_worker_thread + 598
15  libsystem_pthread.dylib        0x00007fff7fbd9611 _pthread_wqthread + 421
16  libsystem_pthread.dylib        0x00007fff7fbd93fd start_wqthread + 13


For reference:


In case that you want the full .crash file please send me an email address where I can send it privately.

Answered by dacap in 628291022
Just in case if someone is using a NSView with a drawsAsynchronously layer:

Code Block objc
self.wantsLayer = true;
self.layer.drawsAsynchronously = true;

And some rectangles are not painted (there are black areas in the NSView from time to time), this might happen because we use setNeedsDisplayInRect and then displayIfNeeded immediately. The solution is removing the displayIfNeeded call:

Code Block objc
NSView* view = window.contentView;
[view setNeedsDisplayInRect: ...];
//[view displayIfNeeded] <-- Cannot be used because the view might not be painted yet (and a black area is displayed)

Accepted Answer
Just in case if someone is using a NSView with a drawsAsynchronously layer:

Code Block objc
self.wantsLayer = true;
self.layer.drawsAsynchronously = true;

And some rectangles are not painted (there are black areas in the NSView from time to time), this might happen because we use setNeedsDisplayInRect and then displayIfNeeded immediately. The solution is removing the displayIfNeeded call:

Code Block objc
NSView* view = window.contentView;
[view setNeedsDisplayInRect: ...];
//[view displayIfNeeded] <-- Cannot be used because the view might not be painted yet (and a black area is displayed)

drawsAsynchronously doesn't update correctly + related crash?
 
 
Q