Changeset 86174 in webkit


Ignore:
Timestamp:
May 10, 2011 11:32:09 AM (13 years ago)
Author:
Martin Robinson
Message:

2011-05-05 Brent Fulgham <bfulgham@webkit.org> and Martin Robinson <mrobinson@igalia.com>

Reviewed by Anders Carlsson.

[Cairo][WebKit2] Add an implementation of ShareableBitmap for Cairo
https://bugs.webkit.org/show_bug.cgi?id=60293

No new tests. This is covered by current pixel tests.

  • platform/graphics/cairo/CairoUtilities.cpp: (WebCore::copyCairoImageSurface): Abstract the code from WebCore::ImageBuffer::copyImage into this helper which creates a deep copy of a Cairo image surface.
  • platform/graphics/cairo/CairoUtilities.h: Added declaration.
  • platform/graphics/cairo/ImageBufferCairo.cpp: (WebCore::ImageBuffer::copyImage): Use the new helper.
  • platform/graphics/cairo/ImageCairo.cpp: Abstract some of this logic into the new drawSurfaceToContext method on PlatformContextCairo. (WebCore::BitmapImage::draw):
  • platform/graphics/cairo/PlatformContextCairo.cpp: (WebCore::drawPatternToCairoContext): Added. (WebCore::PlatformContextCairo::drawSurfaceToContext): Added.
  • platform/graphics/cairo/PlatformContextCairo.h: Added declarations.

2011-05-05 Brent Fulgham <bfulgham@webkit.org> and Martin Robinson <mrobinson@igalia.com>

Reviewed by Anders Carlsson.

[Cairo][WebKit2] Add an implementation of ShareableBitmap for Cairo
https://bugs.webkit.org/show_bug.cgi?id=60293

  • GNUmakefile.am: Remove ShareableBitmapGtk in favor of ShareableBitmapCairo.
  • Shared/ShareableBitmap.h: Added a couple Cairo-specific declarations.
  • Shared/cairo/ShareableBitmapCairo.cpp: (WebKit::ShareableBitmap::createGraphicsContext): Added. (WebKit::ShareableBitmap::paint): Added. (WebKit::ShareableBitmap::createCairoSurface): Added. (WebKit::ShareableBitmap::releaseSurfaceData): Added.
Location:
trunk/Source
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r86172 r86174  
     12011-05-05  Brent Fulgham  <bfulgham@webkit.org> and Martin Robinson  <mrobinson@igalia.com>
     2
     3        Reviewed by Anders Carlsson.
     4
     5        [Cairo][WebKit2] Add an implementation of ShareableBitmap for Cairo
     6        https://bugs.webkit.org/show_bug.cgi?id=60293
     7
     8        No new tests. This is covered by current pixel tests.
     9
     10        * platform/graphics/cairo/CairoUtilities.cpp:
     11        (WebCore::copyCairoImageSurface): Abstract the code from WebCore::ImageBuffer::copyImage
     12        into this helper which creates a deep copy of a Cairo image surface.
     13        * platform/graphics/cairo/CairoUtilities.h: Added declaration.
     14        * platform/graphics/cairo/ImageBufferCairo.cpp:
     15        (WebCore::ImageBuffer::copyImage): Use the new helper.
     16        * platform/graphics/cairo/ImageCairo.cpp: Abstract some of this logic
     17        into the new drawSurfaceToContext method on PlatformContextCairo.
     18        (WebCore::BitmapImage::draw):
     19        * platform/graphics/cairo/PlatformContextCairo.cpp:
     20        (WebCore::drawPatternToCairoContext): Added.
     21        (WebCore::PlatformContextCairo::drawSurfaceToContext): Added.
     22        * platform/graphics/cairo/PlatformContextCairo.h: Added declarations.
     23
    1242011-05-10  Anders Carlsson  <andersca@apple.com>
    225
  • trunk/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp

    r85405 r86174  
    160160}
    161161
     162PassRefPtr<cairo_surface_t> copyCairoImageSurface(cairo_surface_t* originalSurface)
     163{
     164    // Cairo doesn't provide a way to copy a cairo_surface_t.
     165    // See http://lists.cairographics.org/archives/cairo/2007-June/010877.html
     166    // Once cairo provides the way, use the function instead of this.
     167    RefPtr<cairo_surface_t> newSurface = adoptRef(cairo_image_surface_create(cairo_image_surface_get_format(originalSurface),
     168                                                                             cairo_image_surface_get_width(originalSurface),
     169                                                                             cairo_image_surface_get_height(originalSurface)));
     170
     171    RefPtr<cairo_t> cr = adoptRef(cairo_create(newSurface.get()));
     172    cairo_set_source_surface(cr.get(), originalSurface, 0, 0);
     173    cairo_set_operator(cr.get(), CAIRO_OPERATOR_SOURCE);
     174    cairo_paint(cr.get());
     175    return newSurface.release();
     176}
     177
    162178} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/cairo/CairoUtilities.h

    r69015 r86174  
    4646void drawPatternToCairoContext(cairo_t* cr, cairo_surface_t* image, const IntSize& imageSize, const FloatRect& tileRect,
    4747                               const AffineTransform& patternTransform, const FloatPoint& phase, cairo_operator_t op, const FloatRect& destRect);
     48PassRefPtr<cairo_surface_t> copyCairoImageSurface(cairo_surface_t*);
    4849
    4950} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp

    r85405 r86174  
    3232#include "Base64.h"
    3333#include "BitmapImage.h"
     34#include "CairoUtilities.h"
    3435#include "Color.h"
    3536#include "GraphicsContext.h"
     
    4647using namespace std;
    4748
    48 // Cairo doesn't provide a way to copy a cairo_surface_t.
    49 // See http://lists.cairographics.org/archives/cairo/2007-June/010877.html
    50 // Once cairo provides the way, use the function instead of this.
    51 static inline cairo_surface_t* copySurface(cairo_surface_t* surface)
    52 {
    53     cairo_format_t format = cairo_image_surface_get_format(surface);
    54     int width = cairo_image_surface_get_width(surface);
    55     int height = cairo_image_surface_get_height(surface);
    56     cairo_surface_t* newsurface = cairo_image_surface_create(format, width, height);
    57 
    58     RefPtr<cairo_t> cr = adoptRef(cairo_create(newsurface));
    59     cairo_set_source_surface(cr.get(), surface, 0, 0);
    60     cairo_set_operator(cr.get(), CAIRO_OPERATOR_SOURCE);
    61     cairo_paint(cr.get());
    62 
    63     return newsurface;
    64 }
    65 
    6649namespace WebCore {
    6750
     
    11295{
    11396    // BitmapImage will release the passed in surface on destruction
    114     return BitmapImage::create(copySurface(m_data.m_surface));
     97    return BitmapImage::create(copyCairoImageSurface(m_data.m_surface).leakRef());
    11598}
    11699
  • trunk/Source/WebCore/platform/graphics/cairo/ImageCairo.cpp

    r84088 r86174  
    114114    }
    115115
    116     IntSize selfSize = size();
    117 
    118     cairo_t* cr = context->platformContext()->cr();
    119116    context->save();
    120117
     
    124121    else
    125122        context->setCompositeOperation(op);
    126 
    127     // If we're drawing a sub portion of the image or scaling then create
    128     // a pattern transformation on the image and draw the transformed pattern.
    129     // Test using example site at http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html
    130     cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image);
    131 
    132     cairo_pattern_set_extend(pattern, CAIRO_EXTEND_PAD);
    133 
    134     float scaleX = srcRect.width() / dstRect.width();
    135     float scaleY = srcRect.height() / dstRect.height();
    136     cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, srcRect.x(), srcRect.y() };
    137     cairo_pattern_set_matrix(pattern, &matrix);
    138 
    139     ContextShadow* shadow = context->contextShadow();
    140     ASSERT(shadow);
    141     if (shadow->m_type != ContextShadow::NoShadow) {
    142         cairo_t* shadowContext = shadow->beginShadowLayer(context, dstRect);
    143         if (shadowContext) {
    144             cairo_translate(shadowContext, dstRect.x(), dstRect.y());
    145             cairo_set_source(shadowContext, pattern);
    146             cairo_rectangle(shadowContext, 0, 0, dstRect.width(), dstRect.height());
    147             cairo_fill(shadowContext);
    148             shadow->endShadowLayer(context);
    149         }
    150     }
    151 
    152     // Draw the image.
    153     cairo_translate(cr, dstRect.x(), dstRect.y());
    154     cairo_set_source(cr, pattern);
    155     cairo_pattern_destroy(pattern);
    156     cairo_rectangle(cr, 0, 0, dstRect.width(), dstRect.height());
    157     cairo_clip(cr);
    158     cairo_paint_with_alpha(cr, context->getAlpha());
     123    context->platformContext()->drawSurfaceToContext(image, dstRect, srcRect, context);
    159124
    160125    context->restore();
  • trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp

    r83048 r86174  
    2727#include "PlatformContextCairo.h"
    2828
     29#include "GraphicsContext.h"
    2930#include <cairo.h>
    3031
     
    8283}
    8384
     85static void drawPatternToCairoContext(cairo_t* cr, cairo_pattern_t* pattern, const FloatRect& destRect, float alpha)
     86{
     87    cairo_translate(cr, destRect.x(), destRect.y());
     88    cairo_set_source(cr, pattern);
     89    cairo_rectangle(cr, 0, 0, destRect.width(), destRect.height());
     90    cairo_clip(cr);
     91    cairo_paint_with_alpha(cr, alpha);
     92}
     93
     94void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& srcRect, GraphicsContext* context)
     95{
     96    // If we're drawing a sub portion of the image or scaling then create
     97    // a pattern transformation on the image and draw the transformed pattern.
     98    // Test using example site at http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html
     99    RefPtr<cairo_pattern_t> pattern = adoptRef(cairo_pattern_create_for_surface(surface));
     100    cairo_pattern_set_extend(pattern.get(), CAIRO_EXTEND_PAD);
     101
     102    float scaleX = srcRect.width() / destRect.width();
     103    float scaleY = srcRect.height() / destRect.height();
     104    cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, srcRect.x(), srcRect.y() };
     105    cairo_pattern_set_matrix(pattern.get(), &matrix);
     106
     107    ContextShadow* shadow = context->contextShadow();
     108    if (shadow && shadow->m_type != ContextShadow::NoShadow) {
     109        if (cairo_t* shadowContext = shadow->beginShadowLayer(context, destRect)) {
     110            drawPatternToCairoContext(shadowContext, pattern.get(), destRect, 1);
     111            shadow->endShadowLayer(context);
     112        }
     113    }
     114
     115    cairo_save(m_cr.get());
     116    drawPatternToCairoContext(m_cr.get(), pattern.get(), destRect, context->getAlpha());
     117    cairo_restore(m_cr.get());
     118}
     119
    84120
    85121} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h

    r83044 r86174  
    6767    void restore();
    6868    void pushImageMask(cairo_surface_t*, const FloatRect&);
     69    void drawSurfaceToContext(cairo_surface_t*, const FloatRect& destRect, const FloatRect& srcRect, GraphicsContext*);
    6970
    7071private:
  • trunk/Source/WebKit2/ChangeLog

    r86169 r86174  
     12011-05-05  Brent Fulgham  <bfulgham@webkit.org> and Martin Robinson  <mrobinson@igalia.com>
     2
     3        Reviewed by Anders Carlsson.
     4
     5        [Cairo][WebKit2] Add an implementation of ShareableBitmap for Cairo
     6        https://bugs.webkit.org/show_bug.cgi?id=60293
     7
     8        * GNUmakefile.am: Remove ShareableBitmapGtk in favor of ShareableBitmapCairo.
     9        * Shared/ShareableBitmap.h: Added a couple Cairo-specific declarations.
     10        * Shared/cairo/ShareableBitmapCairo.cpp:
     11        (WebKit::ShareableBitmap::createGraphicsContext): Added.
     12        (WebKit::ShareableBitmap::paint): Added.
     13        (WebKit::ShareableBitmap::createCairoSurface): Added.
     14        (WebKit::ShareableBitmap::releaseSurfaceData): Added.
     15
    1162011-05-10  Anders Carlsson  <andersca@apple.com>
    217
  • trunk/Source/WebKit2/GNUmakefile.am

    r85951 r86174  
    183183        Source/WebKit2/Shared/EditorState.h \
    184184        Source/WebKit2/Shared/FontSmoothingLevel.h \
    185         Source/WebKit2/Shared/gtk/ShareableBitmapGtk.cpp \
     185        Source/WebKit2/Shared/cairo/ShareableBitmapCairo.cpp \
    186186        Source/WebKit2/Shared/gtk/NativeWebKeyboardEventGtk.cpp \
    187187        Source/WebKit2/Shared/gtk/NativeWebMouseEventGtk.cpp \
  • trunk/Source/WebKit2/Shared/ShareableBitmap.h

    r85754 r86174  
    3636#if USE(CG)
    3737#include <wtf/RetainPtr.h>
     38#elif PLATFORM(CAIRO)
     39typedef struct _cairo_surface cairo_surface_t;
    3840#endif
    3941
     
    106108    // This is only safe to use when we know that the contents of the shareable bitmap won't change.
    107109    RetainPtr<CGImageRef> makeCGImage();
     110#elif USE(CAIRO)
     111    // This creates a BitmapImage that directly references the shared bitmap data.
     112    // This is only safe to use when we know that the contents of the shareable bitmap won't change.
     113    PassRefPtr<cairo_surface_t> createCairoSurface();
    108114#endif
    109115
     
    118124    static void releaseBitmapContextData(void* typelessBitmap, void* typelessData);
    119125    static void releaseDataProviderData(void* typelessBitmap, const void* typelessData, size_t);
     126#endif
     127
     128#if USE(CAIRO)
     129    static void releaseSurfaceData(void* typelessBitmap);
    120130#endif
    121131
  • trunk/Source/WebKit2/Shared/cairo/ShareableBitmapCairo.cpp

    r79335 r86174  
    11/*
    22 * Copyright (C) 2010 Apple Inc. All rights reserved.
     3 * Copyright (C) 2011 Brent Fulgham <bfulgham@webkit.org>
     4 * Copyright (C) 2011 Igalia S.L.
    35 *
    46 * Redistribution and use in source and binary forms, with or without
     
    2729#include "ShareableBitmap.h"
    2830
     31#include <WebCore/CairoUtilities.h>
    2932#include <WebCore/GraphicsContext.h>
    3033#include <WebCore/NotImplemented.h>
     34#include <WebCore/PlatformContextCairo.h>
    3135
    3236using namespace WebCore;
     
    3640PassOwnPtr<GraphicsContext> ShareableBitmap::createGraphicsContext()
    3741{
    38     notImplemented();
    39     return 0;
     42    RefPtr<cairo_surface_t> image = createCairoSurface();
     43    RefPtr<cairo_t> bitmapContext = adoptRef(cairo_create(image.get()));
     44    return adoptPtr(new GraphicsContext(bitmapContext.get()));
    4045}
    4146
    42 void ShareableBitmap::paint(GraphicsContext&, const IntPoint&, const IntRect&)
     47void ShareableBitmap::paint(GraphicsContext& context, const IntPoint& dstPoint, const IntRect& srcRect)
    4348{
    44     notImplemented();
     49    RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create_for_data(static_cast<unsigned char*>(data()),
     50                                                                                   CAIRO_FORMAT_ARGB32,
     51                                                                                   m_size.width(), m_size.height(),
     52                                                                                   m_size.width() * 4));
     53
     54    // This copy is not copy-on-write, so this is probably sub-optimal.
     55    RefPtr<cairo_surface_t> surfaceCopy = copyCairoImageSurface(surface.get());
     56    FloatRect destRect(dstPoint, srcRect.size());
     57    context.platformContext()->drawSurfaceToContext(surfaceCopy.get(), destRect, srcRect, &context);
    4558}
    46        
     59
     60PassRefPtr<cairo_surface_t> ShareableBitmap::createCairoSurface()
     61{
     62    RefPtr<cairo_surface_t> image = adoptRef(cairo_image_surface_create_for_data(static_cast<unsigned char*>(data()),
     63                                                                                 CAIRO_FORMAT_ARGB32,
     64                                                                                 m_size.width(), m_size.height(),
     65                                                                                 m_size.width() * 4));
     66
     67    ref(); // Balanced by deref in releaseSurfaceData.
     68    static cairo_user_data_key_t dataKey;
     69    cairo_surface_set_user_data(image.get(), &dataKey, this, releaseSurfaceData);
     70    return image.release();
     71}
     72
     73void ShareableBitmap::releaseSurfaceData(void* typelessBitmap)
     74{
     75    static_cast<ShareableBitmap*>(typelessBitmap)->deref(); // Balanced by ref in createCairoSurface.
     76}
     77
    4778} // namespace WebKit
Note: See TracChangeset for help on using the changeset viewer.