WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
ASSIGNED
226963
DisplayList::ImageBuffer calls virtual function erroneously in destructor
https://bugs.webkit.org/show_bug.cgi?id=226963
Summary
DisplayList::ImageBuffer calls virtual function erroneously in destructor
Kimmo Kinnunen
Reported
2021-06-14 03:23:29 PDT
ConcreteImageBuffer calls virtual function erroneously in destructor Calls flushDrawingContext(). Virtual function call ends up calling the currently destructed class version of the function, not the final overridden function. In case of all ConcreteImageBuffer inheritance chains, this is semi-surprising behavioral difference in case of RemoteImageBufferProxy which overrides flush. The code that is produced is incorrect as per logic. As it stands today, the code doesn't crash as the ~RemoteImageBufferProxy flushes and that causes early-out in ConcreteImageBuffer::flushDrawingContext(). However, if ~RemoteImageBufferProxy does not cause the early out, it appears that the ConcreteImageBuffer::flushDrawingContext() seems to crash in a non-trivial convoluted way. As this is surprising and typically incorrect pattern, it should be mostly not done.
Attachments
Patch
(8.77 KB, patch)
2021-06-14 04:37 PDT
,
Kimmo Kinnunen
ews-feeder
: commit-queue-
Details
Formatted Diff
Diff
View All
Add attachment
proposed patch, testcase, etc.
Kimmo Kinnunen
Comment 1
2021-06-14 03:28:00 PDT
Correction: DisplayList::ImageBuffer, not ConcreteImageBuffer, calls the virtual function.
Kimmo Kinnunen
Comment 2
2021-06-14 04:37:31 PDT
Created
attachment 431309
[details]
Patch
Radar WebKit Bug Importer
Comment 3
2021-06-21 03:24:31 PDT
<
rdar://problem/79554863
>
Said Abou-Hallawa
Comment 4
2021-06-21 14:46:04 PDT
Comment on
attachment 431309
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=431309&action=review
> Source/WebCore/ChangeLog:27 > + Make the destructor public because it'd be surprising that the instances > + are intended to be holdable via `ImageBuffer` reference and via the final class > + references but not via the intermediate class references.
I do not understand what this statement means. Also I think this destructor of DisplayList::ImageBuffer can be protected now.
> Source/WebCore/platform/graphics/PlatformImageBuffer.h:87 > +class DisplayListUnacceleratedImageBuffer final : public DisplayList::ImageBuffer<UnacceleratedImageBufferBackend> { > + using Base = DisplayList::ImageBuffer<UnacceleratedImageBufferBackend>; > + using Base::Base; > +public: > + static auto create(const WebCore::FloatSize& size, float resolutionScale, const WebCore::DestinationColorSpace& colorSpace, WebCore::PixelFormat pixelFormat, const HostWindow* hostWindow = nullptr) > + { > + return Base::create<DisplayListUnacceleratedImageBuffer>(size, resolutionScale, colorSpace, pixelFormat, hostWindow); > + } > + ~DisplayListUnacceleratedImageBuffer() final > + { > + flushDrawingContext(); > + } > +}; > + > +class DisplayListAcceleratedImageBuffer final : public DisplayList::ImageBuffer<AcceleratedImageBufferBackend> { > + using Base = DisplayList::ImageBuffer<AcceleratedImageBufferBackend>; > + using Base::Base; > +public: > + static auto create(const WebCore::FloatSize& size, float resolutionScale, const WebCore::DestinationColorSpace& colorSpace, WebCore::PixelFormat pixelFormat, const HostWindow* hostWindow = nullptr) > + { > + return Base::create<DisplayListAcceleratedImageBuffer>(size, resolutionScale, colorSpace, pixelFormat, hostWindow); > + } > + ~DisplayListAcceleratedImageBuffer() final > + { > + flushDrawingContext(); > + } > +};
This repeated code can be simplified by using templates: // maybe in a new file or in DisplayListImageBuffer.h namespace WebCore { namespace DisplayList { template<typename BackendType> class ConcreteImageBuffer final : public ImageBuffer<BackendType> { using Base = ImageBuffer<BackendType>; using Base::Base; public: static auto create(const WebCore::FloatSize& size, float resolutionScale, const WebCore::DestinationColorSpace& colorSpace, WebCore::PixelFormat pixelFormat, const HostWindow* hostWindow = nullptr) { return Base::template create<ConcreteImageBuffer>(size, resolutionScale, colorSpace, pixelFormat, hostWindow); } ~ConcreteImageBuffer() final { Base::flushDrawingContext(); } }; } // DisplayList } // namespace WebCore // And in this file: using DisplayListUnacceleratedImageBuffer = DisplayList::ConcreteImageBuffer<UnacceleratedImageBufferBackend>; using DisplayListAcceleratedImageBuffer = DisplayList::ConcreteImageBuffer<AcceleratedImageBufferBackend>;
> Source/WebCore/platform/graphics/displaylists/DisplayListImageBuffer.h:63 > - ~ImageBuffer() > + ~ImageBuffer() override
What 'override' adds here? I am not sure what is the webkit coding style for overriding virtual destructor. I found most of the classes add virtual before the overridden destructor, e.g. BitmapImage, RenderLayerModelObject, RenderImage, CachedImage. So following this pattern this code should be: virtual ~ImageBuffer() { ... } I also think this destructor can be protected now.
> Source/WebKit/WebProcess/GPU/graphics/RemoteImageBufferProxy.h:66 > - ~RemoteImageBufferProxy() > + ~RemoteImageBufferProxy() override
I think this should be virtual ~RemoteImageBufferProxy() { ... }
Dean Jackson
Comment 5
2022-02-19 08:16:05 PST
Comment on
attachment 431309
[details]
Patch Clearing old review flag. Please rebase and mark for review if necessary.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug