-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Fix CustomLayer context retain count #10765
Conversation
…ayer instead of a separate array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just took a cursory glance at this PR; @akitchen, would you take a deeper look in my stead? Thanks!
@@ -77,7 +77,6 @@ @interface MGLStyle() | |||
@property (nonatomic, readonly, weak) MGLMapView *mapView; | |||
@property (nonatomic, readonly) mbgl::style::Style *rawStyle; | |||
@property (readonly, copy, nullable) NSURL *URL; | |||
@property (nonatomic, readwrite, strong) NS_MUTABLE_DICTIONARY_OF(NSString *, MGLOpenGLStyleLayer *) *openGLLayers; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this dictionary wound up unused after #8626. The original purpose of this dictionary was to allow -layerWithIdentifier:
to return a fully initialized MGLOpenGLStyleLayer object that still had its callback implementations intact. As long as that’s still working correctly, this change looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@1ec5 verified
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@1ec5 [MGLStlye layerFromMBGLLayer]
already takes care of this for all layer types.
@1ec5 yep - darwin changes look good to me; @asheemmamoowala and I were also looking at this together yesterday. I'm currently testing with a local test case I have set up. |
_style = style; | ||
_style.openGLLayers[self.identifier] = self; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only place where this dictionary was being used @1ec5 ; transferring the ownership is a better solution (and fixes the crash)
Local test case / manual verification passed. I'm toying with some automated testing strategies for this but nothing that should block the merge. |
@@ -101,7 +101,7 @@ - (instancetype)initWithIdentifier:(NSString *)identifier { | |||
MGLPrepareCustomStyleLayer, | |||
MGLDrawCustomStyleLayer, | |||
MGLFinishCustomStyleLayer, | |||
(__bridge void *)self); | |||
(__bridge_retained void *)self); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a corner case, but: this will leak a MGLOpenGLStyleLayer
that's init
'd but never added to a map.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😞 I knew I was missing something! Moved to : #10771
Revert this commit to see integration test fail.
Revert this commit to see integration test fail.
Revert this commit to see integration test fail.
Revert this commit to see integration test fail.
Revert this commit to see integration test fail.
Revert this commit to see integration test fail.
Fixes #10755
In core, with style diffing a
RenderCustomLayer
instance is reused if the new style has aCustomLayer
with the same identifier as the previous style. This was not handled correctly inRenderCustomLayer
. When theimpl
orcontext
for the layer is changed, it should invoke theCustomLayerDeinitializeFunction
callback.Changes to core GL for asynchronous rendering changed when the
mbgl::style::CustomLayer
'sCustomLayerDeinitializeFunction
callback method is invoked. This resulted in theMGLOpenGLStyleLayer
releasing itself early when removed from the owning style:mapbox-gl-native/platform/darwin/src/MGLOpenGLStyleLayer.mm
Lines 114 to 121 in 920057c
When
MGLFinishCustomStyleLayer
is called on a subsequent frame, it is left holding on to a dangling pointer to the layer.To remedy this, the layer retention needs to match the lifecycle required by the async renderer. Using
__bridge_retain
implicitly retains the bridged pointer passed to core. This should be the correct behavior since we are not using a weak pointer. WhenMGLFinishCustomStyleLayer
takes back ownership of the pointer from core and uses__bridge_transfer
.Apple docs for Toll-Free Bridged Types
//cc @lilykaiser @jmkiley @jfirebaugh @1ec5