Changeset 59619 in webkit


Ignore:
Timestamp:
May 17, 2010 12:09:24 PM (14 years ago)
Author:
jpetsovits@rim.com
Message:

2010-05-17 Jakob Petsovits <jpetsovits@rim.com>

Reviewed by George Staikos.

[OpenVG] Add support for decoding and drawing images
https://bugs.webkit.org/show_bug.cgi?id=36072

OpenVG has a maximum image size (how large is
specific to the OpenVG implementation), so this
requires us to store them as separate image tiles.

Image decoding and initial drawing code by
Adam Treat <atreat@rim.com>. Image decoder
downsampling support by Yong Li <yoli@rim.com>.

  • platform/graphics/ImageSource.h:
  • platform/graphics/openvg/ImageOpenVG.cpp: Added. (WebCore::FrameData::clear): (WebCore::BitmapImage::BitmapImage): (WebCore::BitmapImage::checkForSolidColor): (WebCore::BitmapImage::initPlatformData): (WebCore::BitmapImage::invalidatePlatformData): (WebCore::adjustSourceRectForDownSampling): (WebCore::BitmapImage::draw): (WebCore::Image::drawPattern): (WebCore::Image::loadPlatformResource):
  • platform/graphics/openvg/PainterOpenVG.cpp: (WebCore::PainterOpenVG::drawImage): (WebCore::PainterOpenVG::asNewNativeImage):
  • platform/graphics/openvg/PainterOpenVG.h:
  • platform/graphics/openvg/TiledImageOpenVG.cpp: Added. (WebCore::TiledImageOpenVG::TiledImageOpenVG): (WebCore::TiledImageOpenVG::operator=): (WebCore::TiledImageOpenVG::~TiledImageOpenVG): (WebCore::TiledImageOpenVG::numTiles): (WebCore::TiledImageOpenVG::numColumns): (WebCore::TiledImageOpenVG::numRows): (WebCore::TiledImageOpenVG::setTile): (WebCore::TiledImageOpenVG::tilesInRect): (WebCore::TiledImageOpenVG::tile): (WebCore::TiledImageOpenVG::tileRect): (WebCore::TiledImageOpenVG::detachTiles): (WebCore::TiledImageOpenVG::destroyTiles):
  • platform/graphics/openvg/TiledImageOpenVG.h: Added. (WebCore::TiledImageOpenVG::size): (WebCore::TiledImageOpenVG::maxTileSize):
  • platform/graphics/openvg/VGUtils.cpp: (WebCore::VGUtils::bytesForImage): (WebCore::VGUtils::bytesForImageScanline): (WebCore::VGUtils::imageFormatBitsPerPixel): (WebCore::VGUtils::endianAwareImageFormat):
  • platform/graphics/openvg/VGUtils.h:
  • platform/image-decoders/openvg/ImageDecoderOpenVG.cpp: Added. (WebCore::RGBA32Buffer::asNewNativeImage):
Location:
trunk/WebCore
Files:
3 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r59618 r59619  
     12010-05-17  Jakob Petsovits  <jpetsovits@rim.com>
     2
     3        Reviewed by George Staikos.
     4
     5        [OpenVG] Add support for decoding and drawing images
     6        https://bugs.webkit.org/show_bug.cgi?id=36072
     7
     8        OpenVG has a maximum image size (how large is
     9        specific to the OpenVG implementation), so this
     10        requires us to store them as separate image tiles.
     11
     12        Image decoding and initial drawing code by
     13        Adam Treat <atreat@rim.com>. Image decoder
     14        downsampling support by Yong Li <yoli@rim.com>.
     15
     16        * platform/graphics/ImageSource.h:
     17        * platform/graphics/openvg/ImageOpenVG.cpp: Added.
     18        (WebCore::FrameData::clear):
     19        (WebCore::BitmapImage::BitmapImage):
     20        (WebCore::BitmapImage::checkForSolidColor):
     21        (WebCore::BitmapImage::initPlatformData):
     22        (WebCore::BitmapImage::invalidatePlatformData):
     23        (WebCore::adjustSourceRectForDownSampling):
     24        (WebCore::BitmapImage::draw):
     25        (WebCore::Image::drawPattern):
     26        (WebCore::Image::loadPlatformResource):
     27        * platform/graphics/openvg/PainterOpenVG.cpp:
     28        (WebCore::PainterOpenVG::drawImage):
     29        (WebCore::PainterOpenVG::asNewNativeImage):
     30        * platform/graphics/openvg/PainterOpenVG.h:
     31        * platform/graphics/openvg/TiledImageOpenVG.cpp: Added.
     32        (WebCore::TiledImageOpenVG::TiledImageOpenVG):
     33        (WebCore::TiledImageOpenVG::operator=):
     34        (WebCore::TiledImageOpenVG::~TiledImageOpenVG):
     35        (WebCore::TiledImageOpenVG::numTiles):
     36        (WebCore::TiledImageOpenVG::numColumns):
     37        (WebCore::TiledImageOpenVG::numRows):
     38        (WebCore::TiledImageOpenVG::setTile):
     39        (WebCore::TiledImageOpenVG::tilesInRect):
     40        (WebCore::TiledImageOpenVG::tile):
     41        (WebCore::TiledImageOpenVG::tileRect):
     42        (WebCore::TiledImageOpenVG::detachTiles):
     43        (WebCore::TiledImageOpenVG::destroyTiles):
     44        * platform/graphics/openvg/TiledImageOpenVG.h: Added.
     45        (WebCore::TiledImageOpenVG::size):
     46        (WebCore::TiledImageOpenVG::maxTileSize):
     47        * platform/graphics/openvg/VGUtils.cpp:
     48        (WebCore::VGUtils::bytesForImage):
     49        (WebCore::VGUtils::bytesForImageScanline):
     50        (WebCore::VGUtils::imageFormatBitsPerPixel):
     51        (WebCore::VGUtils::endianAwareImageFormat):
     52        * platform/graphics/openvg/VGUtils.h:
     53        * platform/image-decoders/openvg/ImageDecoderOpenVG.cpp: Added.
     54        (WebCore::RGBA32Buffer::asNewNativeImage):
     55
    1562010-05-17  Yaar Schnitman  <yaar@chromium.org>
    257
  • trunk/WebCore/platform/graphics/ImageSource.h

    r52791 r59619  
    6363typedef CGImageSourceRef NativeImageSourcePtr;
    6464typedef CGImageRef NativeImagePtr;
     65#elif PLATFORM(OPENVG)
     66class ImageDecoder;
     67class TiledImageOpenVG;
     68typedef ImageDecoder* NativeImageSourcePtr;
     69typedef TiledImageOpenVG* NativeImagePtr;
    6570#elif PLATFORM(QT)
    6671class ImageDecoderQt;
  • trunk/WebCore/platform/graphics/openvg/PainterOpenVG.cpp

    r55923 r59619  
    3232#include "PlatformPathOpenVG.h"
    3333#include "SurfaceOpenVG.h"
     34#include "TiledImageOpenVG.h"
    3435#include "VGUtils.h"
    3536
     
    10861087}
    10871088
     1089void PainterOpenVG::drawImage(TiledImageOpenVG* tiledImage, const FloatRect& dst, const FloatRect& src)
     1090{
     1091    ASSERT(m_state);
     1092    m_surface->makeCurrent();
     1093
     1094    // If buffers can be larger than the maximum OpenVG image sizes,
     1095    // we split them into tiles.
     1096    IntRect drawnTiles = tiledImage->tilesInRect(src);
     1097    AffineTransform srcToDstTransformation = makeMapBetweenRects(
     1098        FloatRect(FloatPoint(0.0, 0.0), src.size()), dst);
     1099    srcToDstTransformation.translate(-src.x(), -src.y());
     1100
     1101    for (int yIndex = drawnTiles.y(); yIndex < drawnTiles.bottom(); ++yIndex) {
     1102        for (int xIndex = drawnTiles.x(); xIndex < drawnTiles.right(); ++xIndex) {
     1103            // The srcTile rectangle is an aligned tile cropped by the src rectangle.
     1104            FloatRect tile(tiledImage->tileRect(xIndex, yIndex));
     1105            FloatRect srcTile = intersection(src, tile);
     1106
     1107            save();
     1108
     1109            // If the image is drawn in full, all we need is the proper transformation
     1110            // in order to get it drawn at the right spot on the surface.
     1111            concatTransformation(AffineTransform(srcToDstTransformation).translate(tile.x(), tile.y()));
     1112
     1113            // If only a part of the tile is drawn, we also need to clip the surface.
     1114            if (srcTile != tile) {
     1115                // Put boundaries relative to tile origin, as we already
     1116                // translated to (x, y) with the transformation matrix.
     1117                srcTile.move(-tile.x(), -tile.y());
     1118                intersectClipRect(srcTile);
     1119            }
     1120
     1121            VGImage image = tiledImage->tile(xIndex, yIndex);
     1122            if (image != VG_INVALID_HANDLE) {
     1123                vgDrawImage(image);
     1124                ASSERT_VG_NO_ERROR();
     1125            }
     1126
     1127            restore();
     1128        }
     1129    }
     1130}
     1131
    10881132#ifdef OPENVG_VERSION_1_1
    10891133void PainterOpenVG::drawText(VGFont vgFont, Vector<VGuint>& characters, VGfloat* adjustmentsX, VGfloat* adjustmentsY, const FloatPoint& point)
     
    11371181}
    11381182#endif
     1183
     1184TiledImageOpenVG* PainterOpenVG::asNewNativeImage(const IntRect& src, VGImageFormat format)
     1185{
     1186    ASSERT(m_state);
     1187    m_surface->sharedSurface()->makeCurrent();
     1188
     1189    const IntSize vgMaxImageSize(vgGeti(VG_MAX_IMAGE_WIDTH), vgGeti(VG_MAX_IMAGE_HEIGHT));
     1190    ASSERT_VG_NO_ERROR();
     1191
     1192    const IntRect rect = intersection(src, IntRect(0, 0, m_surface->width(), m_surface->height()));
     1193    TiledImageOpenVG* tiledImage = new TiledImageOpenVG(rect.size(), vgMaxImageSize);
     1194
     1195    const int numColumns = tiledImage->numColumns();
     1196    const int numRows = tiledImage->numRows();
     1197
     1198    // Create the images as resources of the shared surface/context.
     1199    for (int yIndex = 0; yIndex < numRows; ++yIndex) {
     1200        for (int xIndex = 0; xIndex < numColumns; ++xIndex) {
     1201            IntRect tileRect = tiledImage->tileRect(xIndex, yIndex);
     1202            VGImage image = vgCreateImage(format, tileRect.width(), tileRect.height(), VG_IMAGE_QUALITY_FASTER);
     1203            ASSERT_VG_NO_ERROR();
     1204
     1205            tiledImage->setTile(xIndex, yIndex, image);
     1206        }
     1207    }
     1208
     1209    // Fill the image contents with our own surface/context being current.
     1210    m_surface->makeCurrent();
     1211
     1212    for (int yIndex = 0; yIndex < numRows; ++yIndex) {
     1213        for (int xIndex = 0; xIndex < numColumns; ++xIndex) {
     1214            IntRect tileRect = tiledImage->tileRect(xIndex, yIndex);
     1215
     1216            vgGetPixels(tiledImage->tile(xIndex, yIndex), 0, 0,
     1217                rect.x() + tileRect.x(), rect.y() + tileRect.y(),
     1218                tileRect.width(), tileRect.height());
     1219            ASSERT_VG_NO_ERROR();
     1220        }
     1221    }
     1222
     1223    return tiledImage;
     1224}
    11391225
    11401226void PainterOpenVG::save(PainterOpenVG::SaveMode saveMode)
  • trunk/WebCore/platform/graphics/openvg/PainterOpenVG.h

    r55923 r59619  
    3838class Path;
    3939class SurfaceOpenVG;
     40class TiledImageOpenVG;
    4041
    4142struct PlatformPainterState;
     
    102103    void drawEllipse(const IntRect& bounds, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
    103104    void drawPolygon(size_t numPoints, const FloatPoint* points, VGbitfield paintModes = (VG_STROKE_PATH | VG_FILL_PATH));
     105    void drawImage(TiledImageOpenVG*, const FloatRect& dst, const FloatRect& src);
    104106#ifdef OPENVG_VERSION_1_1
    105107    void drawText(VGFont, Vector<VGuint>& characters, VGfloat* adjustmentsX, VGfloat* adjustmentsY, const FloatPoint&);
     
    117119    void intersectClipRect(const FloatRect&);
    118120    void clipPath(const Path&, PainterOpenVG::ClipOperation, WindRule clipRule = RULE_NONZERO);
     121
     122    TiledImageOpenVG* asNewNativeImage(const IntRect& src, VGImageFormat);
    119123
    120124    void save(PainterOpenVG::SaveMode saveMode = CreateNewState);
  • trunk/WebCore/platform/graphics/openvg/VGUtils.cpp

    r55369 r59619  
    121121}
    122122
    123 }
     123int VGUtils::bytesForImage(VGImageFormat format, VGint width, VGint height)
     124{
     125    return width * height * imageFormatBitsPerPixel(format) / 8;
     126}
     127
     128int VGUtils::bytesForImageScanline(VGImageFormat format, VGint width)
     129{
     130    int bits = width * imageFormatBitsPerPixel(format);
     131    if (bits % 8 > 1) // If unaligned, round up to the next byte.
     132        bits += 8 - (bits % 8);
     133
     134    return bits / 8;
     135}
     136
     137int VGUtils::imageFormatBitsPerPixel(VGImageFormat format)
     138{
     139    switch (format) {
     140    case VG_sRGBX_8888:
     141    case VG_sRGBA_8888:
     142    case VG_sRGBA_8888_PRE:
     143    case VG_lRGBX_8888:
     144    case VG_lRGBA_8888:
     145    case VG_lRGBA_8888_PRE:
     146    case VG_sXRGB_8888:
     147    case VG_sARGB_8888:
     148    case VG_sARGB_8888_PRE:
     149    case VG_lXRGB_8888:
     150    case VG_lARGB_8888:
     151    case VG_lARGB_8888_PRE:
     152    case VG_sBGRX_8888:
     153    case VG_sBGRA_8888:
     154    case VG_sBGRA_8888_PRE:
     155    case VG_lBGRX_8888:
     156    case VG_lBGRA_8888:
     157    case VG_lBGRA_8888_PRE:
     158    case VG_sXBGR_8888:
     159    case VG_sABGR_8888:
     160    case VG_sABGR_8888_PRE:
     161    case VG_lXBGR_8888:
     162    case VG_lABGR_8888:
     163    case VG_lABGR_8888_PRE:
     164        return 32;
     165
     166    case VG_sRGB_565:
     167    case VG_sRGBA_5551:
     168    case VG_sRGBA_4444:
     169    case VG_sARGB_1555:
     170    case VG_sARGB_4444:
     171    case VG_sBGR_565:
     172    case VG_sBGRA_5551:
     173    case VG_sBGRA_4444:
     174    case VG_sABGR_1555:
     175    case VG_sABGR_4444:
     176        return 16;
     177
     178    case VG_sL_8:
     179    case VG_lL_8:
     180    case VG_A_8:
     181        return 8;
     182
     183    case VG_A_4:
     184        return 4;
     185
     186    case VG_BW_1:
     187    case VG_A_1:
     188        return 1;
     189
     190    default: // Will only happen when OpenVG extends the enum and we don't.
     191        ASSERT(false);
     192        return 0;
     193    }
     194}
     195
     196#ifndef WTF_PLATFORM_BIG_ENDIAN
     197VGImageFormat VGUtils::endianAwareImageFormat(VGImageFormat bigEndianFormat)
     198{
     199    switch (bigEndianFormat) {
     200    case VG_sRGBX_8888:     return VG_sXBGR_8888;
     201    case VG_sRGBA_8888:     return VG_sABGR_8888;
     202    case VG_sRGBA_8888_PRE: return VG_sABGR_8888_PRE;
     203    case VG_lRGBX_8888:     return VG_lXBGR_8888;
     204    case VG_lRGBA_8888:     return VG_lABGR_8888;
     205    case VG_lRGBA_8888_PRE: return VG_lABGR_8888_PRE;
     206    case VG_sXRGB_8888:     return VG_sBGRX_8888;
     207    case VG_sARGB_8888:     return VG_sBGRA_8888;
     208    case VG_sARGB_8888_PRE: return VG_sBGRA_8888_PRE;
     209    case VG_lXRGB_8888:     return VG_lBGRX_8888;
     210    case VG_lARGB_8888:     return VG_lBGRA_8888;
     211    case VG_lARGB_8888_PRE: return VG_lBGRA_8888_PRE;
     212    case VG_sBGRX_8888:     return VG_sXRGB_8888;
     213    case VG_sBGRA_8888:     return VG_sARGB_8888;
     214    case VG_sBGRA_8888_PRE: return VG_sARGB_8888_PRE;
     215    case VG_lBGRX_8888:     return VG_lXRGB_8888;
     216    case VG_lBGRA_8888:     return VG_lARGB_8888;
     217    case VG_lBGRA_8888_PRE: return VG_lARGB_8888_PRE;
     218    case VG_sXBGR_8888:     return VG_sRGBX_8888;
     219    case VG_sABGR_8888:     return VG_sRGBA_8888;
     220    case VG_sABGR_8888_PRE: return VG_sRGBA_8888_PRE;
     221    case VG_lXBGR_8888:     return VG_lRGBX_8888;
     222    case VG_lABGR_8888:     return VG_lRGBA_8888;
     223    case VG_lABGR_8888_PRE: return VG_lRGBA_8888_PRE;
     224    default:                ASSERT(false);
     225                            return (VGImageFormat) 0;
     226    }
     227}
     228#else
     229VGImageFormat VGUtils::endianAwareImageFormat(VGImageFormat bigEndianFormat)
     230{
     231    return bigEndianFormat;
     232}
     233#endif
     234
     235}
  • trunk/WebCore/platform/graphics/openvg/VGUtils.h

    r55369 r59619  
    8686};
    8787
     88class VGUtils {
     89public:
     90    static int bytesForImage(VGImageFormat, VGint width, VGint height);
     91    static int bytesForImageScanline(VGImageFormat, VGint width);
     92    static int imageFormatBitsPerPixel(VGImageFormat);
     93
     94    /**
     95     * Return a flipped VGImageFormat if the platform is little endian
     96     * (e.g. VG_ABGR_8888 for a given VG_RGBA_8888), or return the image format
     97     * as is if the platform is big endian.
     98     *
     99     * OpenVG itself is indifferent to endianness, it will always work on a
     100     * single machine word with the bytes going from left to right as specified
     101     * in the image format, no matter which one of the bytes is most or least
     102     * significant.
     103     *
     104     * However, if you interface with vgImageSubData()/vgGetImageSubData()
     105     * using a byte array then you want to make sure the byte order is
     106     * appropriate for the given platform (otherwise the byte indexes need
     107     * to be swapped depending on endianness). So, use this function when
     108     * interfacing with byte arrays, and don't use it otherwise.
     109     */
     110    static VGImageFormat endianAwareImageFormat(VGImageFormat bigEndianFormat);
     111};
     112
    88113}
    89114
Note: See TracChangeset for help on using the changeset viewer.