Bug 215150

Summary: IOSurface not being recycled after ImageBuffer is destroyed
Product: WebKit Reporter: frankhome61
Component: CSSAssignee: frankhome61
Status: RESOLVED CONFIGURATION CHANGED    
Severity: Normal CC: ahmad.saleem792, frankhome61, peng.liu6, sabouhallawa, simon.fraser, thorton, webkit-bug-importer, youennf
Priority: P2 Keywords: InRadar
Version: Other   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Patch frankhome61: review?

frankhome61
Reported 2020-08-04 17:33:29 PDT
When investigating the code of another project, I realized that whenever we use an AcceleratedImageBuffer (IOSurface backend), the IOSurface was always destroyed with the destruction of ImageBuffer. However, I do believe it makes more sense to put the IOSurface back to surface pool once an ImageBuffer is destroyed. There is actually an existing function, IOSurface::moveToPool implemented, but never used in ImageBuffers. I propose an idea that, we move the IOSurface back to the surface pool in the destructor of ImageBufferIOSurfaceBackend. I am not sure if this change is sufficient, but the current code definitely didn't use IOSurface pool for recycling.
Attachments
Patch (1.52 KB, patch)
2020-08-04 17:34 PDT, frankhome61
frankhome61: review?
frankhome61
Comment 1 2020-08-04 17:34:48 PDT
Said Abou-Hallawa
Comment 2 2020-08-04 21:07:49 PDT
Why do we need to do this for ImageBuffer? IOSurface::moveToPool() is called from a single place which is RemoteLayerBackingStore::Buffer::discard(). The RenderLayers are backed by IOSurfaces. While scrolling many RenderLayers are invalidated and painted. I think some of them are destroyed but many of them are recycled. The good thing about about RenderLayers is their sizes are almost always the same 512x512, I think. So it makes sense to recycle their IOSurfaces because a match will be found with a high probability. But I am not sure about the canvas and filters. Do we have the same pattern: 1. Create an IOSurface with size = s 2. Use the IOSurface 3. Destroy the IOSurface 4. Create another IOSurface with size = s We need to prove this case happens so often and we need to get measurements for how much this lazy destroying can affect the memory allocation.
frankhome61
Comment 3 2020-08-05 08:52:30 PDT
(In reply to Said Abou-Hallawa from comment #2) > Why do we need to do this for ImageBuffer? > > IOSurface::moveToPool() is called from a single place which is > RemoteLayerBackingStore::Buffer::discard(). The RenderLayers are backed by > IOSurfaces. While scrolling many RenderLayers are invalidated and painted. I > think some of them are destroyed but many of them are recycled. The good > thing about about RenderLayers is their sizes are almost always the same > 512x512, I think. So it makes sense to recycle their IOSurfaces because a > match will be found with a high probability. > > But I am not sure about the canvas and filters. Do we have the same pattern: > 1. Create an IOSurface with size = s > 2. Use the IOSurface > 3. Destroy the IOSurface > 4. Create another IOSurface with size = s > > We need to prove this case happens so often and we need to get measurements > for how much this lazy destroying can affect the memory allocation. The scenario I was thinking of is CSS/SVG filter rendering with Accelerated rendering mode plus animation. In accelerated rendering mode where we use ImageBufferIOSurfaceBackend, when animating the filters, since CSS filter will be destroyed and recreated on each new draw, the ImageBuffer will have same life cycle as CSS filters, so does the IOSurface. That's why I was thinking doing so makes sense.
youenn fablet
Comment 4 2020-08-06 01:35:45 PDT
Comment on attachment 405965 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=405965&action=review > Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp:110 > + IOSurface::moveToPool(WTFMove(m_surface)); Is there any guarantee m_surface is not null? ImageBufferIOSurfaceBackend::sinkIntoNativeImage() seems to move m_surface for instance
Radar WebKit Bug Importer
Comment 5 2020-08-11 17:34:17 PDT
frankhome61
Comment 6 2020-08-11 17:35:27 PDT
(In reply to youenn fablet from comment #4) > Comment on attachment 405965 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=405965&action=review > > > Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp:110 > > + IOSurface::moveToPool(WTFMove(m_surface)); > > Is there any guarantee m_surface is not null? > ImageBufferIOSurfaceBackend::sinkIntoNativeImage() seems to move m_surface > for instance I guess we can check before throwing an IOSurface back to the pool. We only do so when m_surface is non-null.
youenn fablet
Comment 7 2020-08-13 05:44:49 PDT
(In reply to guowei_yang from comment #6) > (In reply to youenn fablet from comment #4) > > Comment on attachment 405965 [details] > > Patch > > > > View in context: > > https://bugs.webkit.org/attachment.cgi?id=405965&action=review > > > > > Source/WebCore/platform/graphics/cg/ImageBufferIOSurfaceBackend.cpp:110 > > > + IOSurface::moveToPool(WTFMove(m_surface)); > > > > Is there any guarantee m_surface is not null? > > ImageBufferIOSurfaceBackend::sinkIntoNativeImage() seems to move m_surface > > for instance > > I guess we can check before throwing an IOSurface back to the pool. We only > do so when m_surface is non-null. Sounds good
Peng Liu
Comment 8 2020-08-19 11:33:57 PDT
Comment on attachment 405965 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=405965&action=review > Source/WebCore/ChangeLog:8 > + No new tests (OOPS!). This line needs to be removed (Or add some tests).
Ahmad Saleem
Comment 10 2024-12-08 16:03:35 PST
Marking this as `RESOLVED CONFIGURATION CHANGED`, please reopen, if something else is needed.
Note You need to log in before you can comment on or make changes to this bug.