Changeset 49185 in webkit
- Timestamp:
- Oct 6, 2009 7:14:10 AM (15 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 2 added
- 1 deleted
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r49183 r49185 1 2009-10-05 Holger Hans Peter Freyther <zecke@selfish.org> 2 3 Reviewed by Simon Hausmann. 4 5 [Qt] Make use of RGBA32Buffer in ImageDecoderQt 6 https://bugs.webkit.org/show_bug.cgi?id=27538 7 8 Use the RGBA32Buffer instead of the internal ImageData 9 to be able to use support of the base class, optionally 10 support WebCore decoders for Qt and most importantly 11 separate metadata and image data for better cache control. 12 13 Remove ImageSourceQt as everything is now shared with 14 the normal ImageSource. 15 16 Change the ownership of the NativeImagePtr/QPixmap in 17 ImageQt.cpp to delete the m_frame to be subject to cache 18 control. 19 20 * WebCore.pro: 21 * platform/graphics/ImageSource.cpp: 22 * platform/graphics/qt/ImageDecoderQt.cpp: 23 (WebCore::ImageDecoderQt::ReadContext::ReadContext): 24 (WebCore::ImageDecoderQt::ReadContext::read): 25 (WebCore::ImageDecoderQt::ReadContext::readImageLines): 26 (WebCore::ImageDecoderQt::ImageDecoderQt): 27 (WebCore::ImageDecoderQt::setData): 28 (WebCore::ImageDecoderQt::frameCount): 29 (WebCore::ImageDecoderQt::frameBufferAtIndex): 30 (WebCore::ImageDecoderQt::clearFrameBufferCache): 31 * platform/graphics/qt/ImageDecoderQt.h: 32 * platform/graphics/qt/ImageSourceQt.cpp: Removed. 33 * platform/image-decoders/ImageDecoder.h: 34 (WebCore::RGBA32Buffer::decodedImage): 35 (WebCore::RGBA32Buffer::getAddr): 36 * platform/image-decoders/qt/RGBA32BufferQt.cpp: Added. 37 (WebCore::RGBA32Buffer::RGBA32Buffer): 38 (WebCore::RGBA32Buffer::setDecodedImage): 39 (WebCore::RGBA32Buffer::clear): 40 (WebCore::RGBA32Buffer::zeroFill): 41 (WebCore::RGBA32Buffer::copyBitmapData): 42 (WebCore::RGBA32Buffer::setSize): 43 (WebCore::RGBA32Buffer::asNewNativeImage): 44 (WebCore::RGBA32Buffer::hasAlpha): 45 (WebCore::RGBA32Buffer::setHasAlpha): 46 (WebCore::RGBA32Buffer::setStatus): 47 (WebCore::RGBA32Buffer::operator=): 48 (WebCore::RGBA32Buffer::width): 49 (WebCore::RGBA32Buffer::height): 50 1 51 2009-10-05 Holger Hans Peter Freyther <zecke@selfish.org> 2 52 -
trunk/WebCore/WebCore.pro
r49114 r49185 1176 1176 platform/FileChooser.cpp \ 1177 1177 platform/GeolocationService.cpp \ 1178 platform/image-decoders/qt/RGBA32BufferQt.cpp \ 1178 1179 platform/graphics/FontDescription.cpp \ 1179 1180 platform/graphics/FontFamily.cpp \ … … 1852 1853 platform/FileChooser.h \ 1853 1854 platform/GeolocationService.h \ 1855 platform/image-decoders/ImageDecoder.h \ 1854 1856 platform/mock/GeolocationServiceMock.h \ 1855 1857 platform/graphics/BitmapImage.h \ … … 2335 2337 platform/graphics/qt/ImageDecoderQt.cpp \ 2336 2338 platform/graphics/qt/ImageQt.cpp \ 2337 platform/graphics/qt/ImageSourceQt.cpp \2338 2339 platform/graphics/qt/IntPointQt.cpp \ 2339 2340 platform/graphics/qt/IntRectQt.cpp \ -
trunk/WebCore/platform/graphics/ImageSource.cpp
r47936 r49185 121 121 } 122 122 123 #if !PLATFORM(QT)124 125 123 NativeImagePtr ImageSource::createFrameAtIndex(size_t index) 126 124 { … … 181 179 } 182 180 183 #endif184 185 181 } -
trunk/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
r49183 r49185 56 56 } 57 57 58 ImageDecoderQt::ImageData::ImageData(const QImage& image, int duration)59 : m_image(image)60 , m_duration(duration)61 {62 }63 64 58 // Context, maintains IODevice on a data buffer. 65 59 class ImageDecoderQt::ReadContext { 66 60 public: 67 61 68 ReadContext(SharedBuffer* data, ImageList &target);62 ReadContext(SharedBuffer* data, Vector<RGBA32Buffer>& target); 69 63 bool read(); 70 64 … … 74 68 enum IncrementalReadResult { IncrementalReadFailed, IncrementalReadPartial, IncrementalReadComplete }; 75 69 // Incrementally read an image 76 IncrementalReadResult readImageLines( ImageData&);70 IncrementalReadResult readImageLines(RGBA32Buffer&); 77 71 78 72 QByteArray m_data; … … 80 74 QImageReader m_reader; 81 75 82 ImageList &m_target; 83 84 // Detected data format of the stream 85 enum QImage::Format m_dataFormat; 86 QSize m_size; 87 76 Vector<RGBA32Buffer> &m_target; 88 77 }; 89 78 90 ImageDecoderQt::ReadContext::ReadContext(SharedBuffer* data, ImageList&target)79 ImageDecoderQt::ReadContext::ReadContext(SharedBuffer* data, Vector<RGBA32Buffer> &target) 91 80 : m_data(data->data(), data->size()) 92 81 , m_buffer(&m_data) 93 82 , m_reader(&m_buffer) 94 83 , m_target(target) 95 , m_dataFormat(QImage::Format_Invalid)96 84 { 97 85 m_buffer.open(QIODevice::ReadOnly); … … 104 92 bool completed = false; 105 93 while (true) { 106 if (m_target. empty() || completed) {94 if (m_target.isEmpty() || completed) { 107 95 // Start a new image. 108 96 if (!m_reader.canRead()) 109 97 return true; 110 98 111 // Attempt to construct an empty image of the matching size and format 112 // for efficient reading 113 QImage newImage = m_dataFormat != QImage::Format_Invalid ? 114 QImage(m_size, m_dataFormat) : QImage(); 115 m_target.push_back(ImageData(newImage)); 99 m_target.append(RGBA32Buffer()); 116 100 completed = false; 117 101 } 118 102 119 103 // read chunks 120 switch (readImageLines(m_target. back())) {104 switch (readImageLines(m_target.last())) { 121 105 case IncrementalReadFailed: 122 m_target. pop_back();106 m_target.removeLast(); 123 107 return false; 124 108 case IncrementalReadPartial: … … 127 111 completed = true; 128 112 //store for next 129 m_dataFormat = m_target.back().m_image.format();130 m_size = m_target.back().m_image.size();131 113 const bool supportsAnimation = m_reader.supportsAnimation(); 132 114 … … 144 126 145 127 ImageDecoderQt::ReadContext::IncrementalReadResult 146 ImageDecoderQt::ReadContext::readImageLines( ImageData &imageData)128 ImageDecoderQt::ReadContext::readImageLines(RGBA32Buffer& buffer) 147 129 { 148 130 // TODO: Implement incremental reading here, … … 150 132 // For now, we read the whole image. 151 133 134 152 135 const qint64 startPos = m_buffer.pos(); 136 QImage img; 153 137 // Oops, failed. Rewind. 154 if (!m_reader.read(&im ageData.m_image)) {138 if (!m_reader.read(&img)) { 155 139 m_buffer.seek(startPos); 156 const bool gotHeader = imageData.m_image.size().width();157 158 // [Experimental] Did we manage to read the header?159 if (gotHeader)160 return IncrementalReadPartial;161 140 return IncrementalReadFailed; 162 141 } 163 imageData.m_duration = m_reader.nextImageDelay(); 142 143 buffer.setDuration(m_reader.nextImageDelay()); 144 buffer.setDecodedImage(img); 145 buffer.setStatus(RGBA32Buffer::FrameComplete); 164 146 return IncrementalReadComplete; 165 147 } 166 148 167 149 ImageDecoderQt::ImageDecoderQt(const QByteArray& imageFormat) 168 : m_hasAlphaChannel(false) 169 , m_imageFormat(imageFormat.constData()) 150 : m_imageFormat(imageFormat.constData()) 170 151 { 171 152 } … … 173 154 ImageDecoderQt::~ImageDecoderQt() 174 155 { 175 }176 177 bool ImageDecoderQt::hasFirstImageHeader() const178 {179 return !m_imageList.empty();180 156 } 181 157 … … 192 168 return; 193 169 194 ReadContext readContext(data, m_ imageList);170 ReadContext readContext(data, m_frameBufferCache); 195 171 196 172 const bool result = readContext.read(); 197 198 if (hasFirstImageHeader())199 m_hasAlphaChannel = m_imageList[0].m_image.hasAlphaChannel();200 173 201 174 if (!result) 202 175 setFailed(); 203 else if ( hasFirstImageHeader()) {204 QSize imgSize = m_ imageList[0].m_image.size();176 else if (!m_frameBufferCache.isEmpty()) { 177 QSize imgSize = m_frameBufferCache[0].decodedImage().size(); 205 178 setSize(imgSize.width(), imgSize.height()); 206 179 … … 222 195 size_t ImageDecoderQt::frameCount() 223 196 { 224 return m_ imageList.size();197 return m_frameBufferCache.size(); 225 198 } 226 199 … … 228 201 { 229 202 return m_loopCount; 230 }231 232 bool ImageDecoderQt::supportsAlpha() const233 {234 return m_hasAlphaChannel;235 }236 237 int ImageDecoderQt::duration(size_t index) const238 {239 if (index >= static_cast<size_t>(m_imageList.size()))240 return 0;241 return m_imageList[index].m_duration;242 203 } 243 204 … … 247 208 }; 248 209 249 RGBA32Buffer* ImageDecoderQt::frameBufferAtIndex(size_t) 250 { 251 Q_ASSERT("use imageAtIndex instead"); 252 return 0; 253 } 254 255 QPixmap* ImageDecoderQt::imageAtIndex(size_t index) const 256 { 257 if (index >= static_cast<size_t>(m_imageList.size())) 210 RGBA32Buffer* ImageDecoderQt::frameBufferAtIndex(size_t index) 211 { 212 if (index >= m_frameBufferCache.size()) 258 213 return 0; 259 214 260 if (!m_pixmapCache.contains(index)) { 261 m_pixmapCache.insert(index, 262 QPixmap::fromImage(m_imageList[index].m_image)); 263 264 // store null image since the converted pixmap is already in pixmap cache 265 Q_ASSERT(m_imageList[index].m_imageState == ImageComplete); 266 m_imageList[index].m_image = QImage(); 267 } 268 return &m_pixmapCache[index]; 269 } 270 271 void ImageDecoderQt::clearFrame(size_t index) 272 { 273 if (m_imageList.size() < (int)index) 274 m_imageList[index].m_image = QImage(); 275 m_pixmapCache.take(index); 215 return &m_frameBufferCache[index]; 216 } 217 218 void ImageDecoderQt::clearFrameBufferCache(size_t index) 219 { 220 // Currently QImageReader will be asked to read everything. This 221 // might change when we read gif images on demand. For now we 222 // can have a rather simple implementation. 223 if (index > m_frameBufferCache.size()) 224 return; 225 226 for (size_t i = 0; i < index; ++index) 227 m_frameBufferCache[index].setDecodedImage(QImage()); 276 228 } 277 229 -
trunk/WebCore/platform/graphics/qt/ImageDecoderQt.h
r49183 r49185 49 49 virtual RGBA32Buffer* frameBufferAtIndex(size_t index); 50 50 51 QPixmap* imageAtIndex(size_t index) const;52 virtual bool supportsAlpha() const;53 int duration(size_t index) const;54 51 virtual String filenameExtension() const; 55 52 56 v oid clearFrame(size_t index);53 virtual void clearFrameBufferCache(size_t clearBeforeFrame); 57 54 58 55 private: … … 61 58 62 59 class ReadContext; 63 bool hasFirstImageHeader() const;64 60 65 66 // TODO: Replace usage of ImageData with RGBBuffer3267 struct ImageData {68 ImageData(const QImage& image, int duration=0);69 QImage m_image;70 int m_duration;71 };72 73 bool m_hasAlphaChannel;74 typedef QList<ImageData> ImageList;75 mutable ImageList m_imageList;76 mutable QHash<int, QPixmap> m_pixmapCache;77 61 int m_loopCount; 78 62 String m_imageFormat; -
trunk/WebCore/platform/graphics/qt/ImageQt.cpp
r46170 r49185 77 77 78 78 if (m_frame) { 79 delete m_frame; 79 80 m_frame = 0; 80 81 return true; -
trunk/WebCore/platform/image-decoders/ImageDecoder.h
r47868 r49185 2 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 3 3 * Copyright (C) 2008-2009 Torch Mobile, Inc. 4 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) 4 5 * 5 6 * Redistribution and use in source and binary forms, with or without … … 38 39 #if PLATFORM(SKIA) 39 40 #include "NativeImageSkia.h" 41 #elif PLATFORM(QT) 42 #include <QImage> 40 43 #endif 41 44 … … 55 58 DisposeOverwritePrevious, // Clear frame to previous framebuffer contents 56 59 }; 57 #if PLATFORM(SKIA) 60 #if PLATFORM(SKIA) || PLATFORM(QT) 58 61 typedef uint32_t PixelData; 59 62 #else … … 127 130 } 128 131 132 #if PLATFORM(QT) 133 void setDecodedImage(const QImage& image); 134 QImage decodedImage() const { return m_image; } 135 #endif 136 129 137 private: 130 138 RGBA32Buffer& operator=(const RGBA32Buffer& other); … … 137 145 #if PLATFORM(SKIA) 138 146 return m_bitmap.getAddr32(x, y); 147 #elif PLATFORM(QT) 148 return reinterpret_cast<QRgb*>(m_image.scanLine(y)) + x; 139 149 #else 140 150 return m_bytes.data() + (y * width()) + x; … … 160 170 #if PLATFORM(SKIA) 161 171 NativeImageSkia m_bitmap; 172 #elif PLATFORM(QT) 173 QImage m_image; 174 bool m_hasAlpha; 175 IntSize m_size; 162 176 #else 163 177 Vector<PixelData> m_bytes;
Note: See TracChangeset
for help on using the changeset viewer.