Changeset 49185 in webkit


Ignore:
Timestamp:
Oct 6, 2009 7:14:10 AM (15 years ago)
Author:
Simon Hausmann
Message:

[Qt] Make use of RGBA32Buffer in ImageDecoderQt

https://bugs.webkit.org/show_bug.cgi?id=27538

Use the RGBA32Buffer instead of the internal ImageData
to be able to use support of the base class, optionally
support WebCore decoders for Qt and most importantly
separate metadata and image data for better cache control.

Remove ImageSourceQt as everything is now shared with
the normal ImageSource.

Change the ownership of the NativeImagePtr/QPixmap in
ImageQt.cpp to delete the m_frame to be subject to cache
control.

  • WebCore.pro:
  • platform/graphics/ImageSource.cpp:
  • platform/graphics/qt/ImageDecoderQt.cpp:

(WebCore::ImageDecoderQt::ReadContext::ReadContext):
(WebCore::ImageDecoderQt::ReadContext::read):
(WebCore::ImageDecoderQt::ReadContext::readImageLines):
(WebCore::ImageDecoderQt::ImageDecoderQt):
(WebCore::ImageDecoderQt::setData):
(WebCore::ImageDecoderQt::frameCount):
(WebCore::ImageDecoderQt::frameBufferAtIndex):
(WebCore::ImageDecoderQt::clearFrameBufferCache):

  • platform/graphics/qt/ImageDecoderQt.h:
  • platform/graphics/qt/ImageSourceQt.cpp: Removed.
  • platform/image-decoders/ImageDecoder.h:

(WebCore::RGBA32Buffer::decodedImage):
(WebCore::RGBA32Buffer::getAddr):

  • platform/image-decoders/qt/RGBA32BufferQt.cpp: Added.

(WebCore::RGBA32Buffer::RGBA32Buffer):
(WebCore::RGBA32Buffer::setDecodedImage):
(WebCore::RGBA32Buffer::clear):
(WebCore::RGBA32Buffer::zeroFill):
(WebCore::RGBA32Buffer::copyBitmapData):
(WebCore::RGBA32Buffer::setSize):
(WebCore::RGBA32Buffer::asNewNativeImage):
(WebCore::RGBA32Buffer::hasAlpha):
(WebCore::RGBA32Buffer::setHasAlpha):
(WebCore::RGBA32Buffer::setStatus):
(WebCore::RGBA32Buffer::operator=):
(WebCore::RGBA32Buffer::width):
(WebCore::RGBA32Buffer::height):

Location:
trunk/WebCore
Files:
2 added
1 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r49183 r49185  
     12009-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
    1512009-10-05  Holger Hans Peter Freyther  <zecke@selfish.org>
    252
  • trunk/WebCore/WebCore.pro

    r49114 r49185  
    11761176    platform/FileChooser.cpp \
    11771177    platform/GeolocationService.cpp \
     1178    platform/image-decoders/qt/RGBA32BufferQt.cpp \
    11781179    platform/graphics/FontDescription.cpp \
    11791180    platform/graphics/FontFamily.cpp \
     
    18521853    platform/FileChooser.h \
    18531854    platform/GeolocationService.h \
     1855    platform/image-decoders/ImageDecoder.h \
    18541856    platform/mock/GeolocationServiceMock.h \
    18551857    platform/graphics/BitmapImage.h \
     
    23352337    platform/graphics/qt/ImageDecoderQt.cpp \
    23362338    platform/graphics/qt/ImageQt.cpp \
    2337     platform/graphics/qt/ImageSourceQt.cpp \
    23382339    platform/graphics/qt/IntPointQt.cpp \
    23392340    platform/graphics/qt/IntRectQt.cpp \
  • trunk/WebCore/platform/graphics/ImageSource.cpp

    r47936 r49185  
    121121}
    122122
    123 #if !PLATFORM(QT)
    124 
    125123NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
    126124{
     
    181179}
    182180
    183 #endif
    184 
    185181}
  • trunk/WebCore/platform/graphics/qt/ImageDecoderQt.cpp

    r49183 r49185  
    5656}
    5757
    58 ImageDecoderQt::ImageData::ImageData(const QImage& image, int duration)
    59     : m_image(image)
    60     , m_duration(duration)
    61 {
    62 }
    63 
    6458// Context, maintains IODevice on a data buffer.
    6559class ImageDecoderQt::ReadContext {
    6660public:
    6761
    68     ReadContext(SharedBuffer* data, ImageList &target);
     62    ReadContext(SharedBuffer* data, Vector<RGBA32Buffer>& target);
    6963    bool read();
    7064
     
    7468    enum IncrementalReadResult { IncrementalReadFailed, IncrementalReadPartial, IncrementalReadComplete };
    7569    // Incrementally read an image
    76     IncrementalReadResult readImageLines(ImageData &);
     70    IncrementalReadResult readImageLines(RGBA32Buffer&);
    7771
    7872    QByteArray m_data;
     
    8074    QImageReader m_reader;
    8175
    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;
    8877};
    8978
    90 ImageDecoderQt::ReadContext::ReadContext(SharedBuffer* data, ImageList &target)
     79ImageDecoderQt::ReadContext::ReadContext(SharedBuffer* data, Vector<RGBA32Buffer> &target)
    9180    : m_data(data->data(), data->size())
    9281    , m_buffer(&m_data)
    9382    , m_reader(&m_buffer)
    9483    , m_target(target)
    95     , m_dataFormat(QImage::Format_Invalid)
    9684{
    9785    m_buffer.open(QIODevice::ReadOnly);
     
    10492    bool completed = false;
    10593    while (true) {
    106         if (m_target.empty() || completed) {
     94        if (m_target.isEmpty() || completed) {
    10795            // Start a new image.
    10896            if (!m_reader.canRead())
    10997                return true;
    11098
    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());
    116100            completed = false;
    117101        }
    118102
    119103        // read chunks
    120         switch (readImageLines(m_target.back())) {
     104        switch (readImageLines(m_target.last())) {
    121105        case IncrementalReadFailed:
    122             m_target.pop_back();
     106            m_target.removeLast();
    123107            return false;
    124108        case IncrementalReadPartial:
     
    127111            completed = true;
    128112            //store for next
    129             m_dataFormat = m_target.back().m_image.format();
    130             m_size = m_target.back().m_image.size();
    131113            const bool supportsAnimation = m_reader.supportsAnimation();
    132114
     
    144126
    145127ImageDecoderQt::ReadContext::IncrementalReadResult
    146         ImageDecoderQt::ReadContext::readImageLines(ImageData &imageData)
     128        ImageDecoderQt::ReadContext::readImageLines(RGBA32Buffer& buffer)
    147129{
    148130    // TODO: Implement incremental reading here,
     
    150132    // For now, we read the whole image.
    151133
     134
    152135    const qint64 startPos = m_buffer.pos();
     136    QImage img;
    153137    // Oops, failed. Rewind.
    154     if (!m_reader.read(&imageData.m_image)) {
     138    if (!m_reader.read(&img)) {
    155139        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;
    161140        return IncrementalReadFailed;
    162141    }
    163     imageData.m_duration = m_reader.nextImageDelay();
     142
     143    buffer.setDuration(m_reader.nextImageDelay());
     144    buffer.setDecodedImage(img);
     145    buffer.setStatus(RGBA32Buffer::FrameComplete);
    164146    return IncrementalReadComplete;
    165147}
    166148
    167149ImageDecoderQt::ImageDecoderQt(const QByteArray& imageFormat)
    168     : m_hasAlphaChannel(false)
    169     , m_imageFormat(imageFormat.constData())
     150    : m_imageFormat(imageFormat.constData())
    170151{
    171152}
     
    173154ImageDecoderQt::~ImageDecoderQt()
    174155{
    175 }
    176 
    177 bool ImageDecoderQt::hasFirstImageHeader() const
    178 {
    179     return  !m_imageList.empty();
    180156}
    181157
     
    192168        return;
    193169
    194     ReadContext readContext(data, m_imageList);
     170    ReadContext readContext(data, m_frameBufferCache);
    195171
    196172    const bool result =  readContext.read();
    197 
    198     if (hasFirstImageHeader())
    199         m_hasAlphaChannel = m_imageList[0].m_image.hasAlphaChannel();
    200173
    201174    if (!result)
    202175        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();
    205178        setSize(imgSize.width(), imgSize.height());
    206179
     
    222195size_t ImageDecoderQt::frameCount()
    223196{
    224     return m_imageList.size();
     197    return m_frameBufferCache.size();
    225198}
    226199
     
    228201{
    229202    return m_loopCount;
    230 }
    231 
    232 bool ImageDecoderQt::supportsAlpha() const
    233 {
    234     return m_hasAlphaChannel;
    235 }
    236 
    237 int ImageDecoderQt::duration(size_t index) const
    238 {
    239     if (index >= static_cast<size_t>(m_imageList.size()))
    240         return 0;
    241     return  m_imageList[index].m_duration;
    242203}
    243204
     
    247208};
    248209
    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()))
     210RGBA32Buffer* ImageDecoderQt::frameBufferAtIndex(size_t index)
     211{
     212    if (index >= m_frameBufferCache.size())
    258213        return 0;
    259214
    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
     218void 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());
    276228}
    277229
  • trunk/WebCore/platform/graphics/qt/ImageDecoderQt.h

    r49183 r49185  
    4949    virtual RGBA32Buffer* frameBufferAtIndex(size_t index);
    5050
    51     QPixmap* imageAtIndex(size_t index) const;
    52     virtual bool supportsAlpha() const;
    53     int duration(size_t index) const;
    5451    virtual String filenameExtension() const;
    5552
    56     void clearFrame(size_t index);
     53    virtual void clearFrameBufferCache(size_t clearBeforeFrame);
    5754
    5855private:
     
    6158
    6259    class ReadContext;
    63     bool hasFirstImageHeader() const;
    6460
    65 
    66     // TODO: Replace usage of ImageData with RGBBuffer32
    67     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;
    7761    int m_loopCount;
    7862    String m_imageFormat;
  • trunk/WebCore/platform/graphics/qt/ImageQt.cpp

    r46170 r49185  
    7777
    7878    if (m_frame) {
     79        delete m_frame;
    7980        m_frame = 0;
    8081        return true;
  • trunk/WebCore/platform/image-decoders/ImageDecoder.h

    r47868 r49185  
    22 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
    33 * Copyright (C) 2008-2009 Torch Mobile, Inc.
     4 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
    45 *
    56 * Redistribution and use in source and binary forms, with or without
     
    3839#if PLATFORM(SKIA)
    3940#include "NativeImageSkia.h"
     41#elif PLATFORM(QT)
     42#include <QImage>
    4043#endif
    4144
     
    5558            DisposeOverwritePrevious,  // Clear frame to previous framebuffer contents
    5659        };
    57 #if PLATFORM(SKIA)
     60#if PLATFORM(SKIA) || PLATFORM(QT)
    5861        typedef uint32_t PixelData;
    5962#else
     
    127130        }
    128131
     132#if PLATFORM(QT)
     133        void setDecodedImage(const QImage& image);
     134        QImage decodedImage() const { return m_image; }
     135#endif
     136
    129137    private:
    130138        RGBA32Buffer& operator=(const RGBA32Buffer& other);
     
    137145#if PLATFORM(SKIA)
    138146            return m_bitmap.getAddr32(x, y);
     147#elif PLATFORM(QT)
     148            return reinterpret_cast<QRgb*>(m_image.scanLine(y)) + x;
    139149#else
    140150            return m_bytes.data() + (y * width()) + x;
     
    160170#if PLATFORM(SKIA)
    161171        NativeImageSkia m_bitmap;
     172#elif PLATFORM(QT)
     173        QImage m_image;
     174        bool m_hasAlpha;
     175        IntSize m_size;
    162176#else
    163177        Vector<PixelData> m_bytes;
Note: See TracChangeset for help on using the changeset viewer.