Changeset 218253 in webkit
- Timestamp:
- Jun 14, 2017 4:23:25 AM (7 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r218248 r218253 1 2017-06-14 Miguel Gomez <magomez@igalia.com> 2 3 REGRESSION(r216901): ImageDecoders: rendering of large images is broken since r216901 4 https://bugs.webkit.org/show_bug.cgi?id=172502 5 6 Reviewed by Carlos Garcia Campos. 7 8 When using GTK and WPE image decoders, the decoded frames are stored inside a Vector of 9 ImageFrames inside the decoders. These ImageFrames have and ImageBackingStore with the 10 pixels. When a NativeImagePtr is requested, a cairo surface is created from the data 11 in those ImageBackingStores, but the data keeps being owned by the backing stores. Due 12 to this, if the decoder that created the image gets destroyed, the backing stores for 13 the decoded frames get destroyed as well, causing the cairo surfaces that were using 14 that data to contain garbage (and potentially cause a crash). 15 16 To fix this, we change ImageBackingStore so the pixels are stored in a SharedBuffer. The 17 buffer will be reffed everytime a cairo surface is created with it, and the cairo surfaces 18 will unref the buffer when they are destroyed. This way, the pixel data won't be freed 19 while there are cairo surfaces using it. 20 21 No new tests, no behaviour change. 22 23 * platform/graphics/ImageBackingStore.h: 24 (WebCore::ImageBackingStore::setSize): 25 (WebCore::ImageBackingStore::ImageBackingStore): 26 * platform/image-decoders/cairo/ImageBackingStoreCairo.cpp: 27 (WebCore::ImageBackingStore::image): 28 1 29 2017-06-14 Zan Dobersek <zdobersek@igalia.com> 2 30 -
trunk/Source/WebCore/platform/graphics/ImageBackingStore.h
r215172 r218253 30 30 #include "IntSize.h" 31 31 #include "NativeImage.h" 32 33 #include <wtf/Vector.h> 32 #include "SharedBuffer.h" 34 33 35 34 namespace WebCore { … … 55 54 return false; 56 55 57 unsigned area = size.area().unsafeGet(); 58 if (!m_pixels.tryReserveCapacity(area)) 56 Vector<char> buffer; 57 size_t bufferSize = size.area().unsafeGet() * sizeof(RGBA32); 58 59 if (!buffer.tryReserveCapacity(bufferSize)) 59 60 return false; 60 61 61 m_pixels.resize(area); 62 m_pixelsPtr = m_pixels.data(); 62 buffer.resize(bufferSize); 63 m_pixels = SharedBuffer::create(WTFMove(buffer)); 64 m_pixelsPtr = reinterpret_cast<RGBA32*>(const_cast<char*>(m_pixels->data())); 63 65 m_size = size; 64 66 m_frameRect = IntRect(IntPoint(), m_size); … … 184 186 185 187 ImageBackingStore(const ImageBackingStore& other) 186 : m_pixels(other.m_pixels) 187 , m_size(other.m_size) 188 : m_size(other.m_size) 188 189 , m_premultiplyAlpha(other.m_premultiplyAlpha) 189 190 { 190 191 ASSERT(!m_size.isEmpty() && !isOverSize(m_size)); 191 m_pixelsPtr = m_pixels.data(); 192 m_pixels = other.m_pixels->copy(); 193 m_pixelsPtr = reinterpret_cast<RGBA32*>(const_cast<char*>(m_pixels->data())); 192 194 } 193 195 … … 213 215 } 214 216 215 Vector<RGBA32> m_pixels;217 RefPtr<SharedBuffer> m_pixels; 216 218 RGBA32* m_pixelsPtr { nullptr }; 217 219 IntSize m_size; -
trunk/Source/WebCore/platform/image-decoders/cairo/ImageBackingStoreCairo.cpp
r205841 r218253 33 33 NativeImagePtr ImageBackingStore::image() const 34 34 { 35 return adoptRef(cairo_image_surface_create_for_data( 35 m_pixels->ref(); 36 RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create_for_data( 36 37 reinterpret_cast<unsigned char*>(const_cast<RGBA32*>(m_pixelsPtr)), 37 38 CAIRO_FORMAT_ARGB32, size().width(), size().height(), size().width() * sizeof(RGBA32))); 39 static cairo_user_data_key_t s_surfaceDataKey; 40 cairo_surface_set_user_data(surface.get(), &s_surfaceDataKey, m_pixels.get(), [](void* data) { static_cast<SharedBuffer*>(data)->deref(); }); 41 42 return surface; 38 43 } 39 44
Note: See TracChangeset
for help on using the changeset viewer.