Changeset 167342 in webkit


Ignore:
Timestamp:
Apr 15, 2014 8:45:28 PM (10 years ago)
Author:
commit-queue@webkit.org
Message:

[EFL] Fix problems with the pixel dump.
https://bugs.webkit.org/show_bug.cgi?id=131265

Patch by Hyowon Kim <hw1008.kim@samsung.com> on 2014-04-15
Reviewed by Gyuyoung Kim.

Painting and compositing paths of WebKit-EFL were totally modified from r166768.
However pixel dump codes still call deprecated functions like ewk_view_paint(),
which causes that nothing is drawn.

This patch adds new member functions to AcceleratedCompositingContext to support pixel dump.
One of new functions is AcceleratedCompositingContext::extractImageData(),
which replaces deprecated function calls. Besides the extractImageData() is invoked by
ewk_view_screenshot_contents_get() in order to take the visible content displayed on the EFL webview.

Source/WebCore:

  • platform/graphics/cairo/CairoUtilities.cpp:

(WebCore::flipImageSurfaceVertically): Flip pixel data of given cairo_surface_t vertically up/down.
Whereas Cairo uses the top-left corner as being 0,0 of the coordinate system,
OpenGL uses the bottom-left corner being 0,0.
So we need to vertically flip resultant images taken by glReadPixels().

  • platform/graphics/cairo/CairoUtilities.h:

Source/WebKit/efl:

  • WebCoreSupport/AcceleratedCompositingContextEfl.cpp:

(WebCore::AcceleratedCompositingContext::AcceleratedCompositingContext):
Create TextureMapper with a proper backend.
(WebCore::AcceleratedCompositingContext::flushPendingLayerChanges):
Revise a null check for m_rootLayer.
(WebCore::AcceleratedCompositingContext::paintToGraphicsContext):
Remove a creation check for TextureMapperGL.
(WebCore::AcceleratedCompositingContext::paintToCurrentGLContext):
Ditto.
(WebCore::AcceleratedCompositingContext::extractImageData):
Extract image data from the view and copy it to given Evas_Object.
(WebCore::AcceleratedCompositingContext::getImageData):
Get image data from the view and return it as cairo_surface_t on software mode.
(WebCore::AcceleratedCompositingContext::getImageDataGL):
Get image data from the view and return it as cairo_surface_t on GL mode.

  • WebCoreSupport/AcceleratedCompositingContextEfl.h:
  • WebCoreSupport/DumpRenderTreeSupportEfl.cpp:

(DumpRenderTreeSupportEfl::forcePaint): Repaint the entire webview before pixel dump.

  • WebCoreSupport/DumpRenderTreeSupportEfl.h:
  • ewk/ewk_view.cpp:

(ewk_view_mark_for_sync): Remove an unnecessary line.
(ewk_view_force_paint): Call flushAndRenderLayers().
(ewk_view_screenshot_contents_get): Remove 'scale' parameter and replace ewk_view_paint()
with AcceleratedCompositingContext::extractImageData().

  • ewk/ewk_view.h:
  • ewk/ewk_view_private.h:
  • tests/test_ewk_view.cpp:

(TEST_F):

Tools:

  • DumpRenderTree/efl/PixelDumpSupportEfl.cpp:

(createBitmapContextFromWebView): Add to call DumpRenderTreeSupportEfl::forcePaint().

Location:
trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r167340 r167342  
     12014-04-15  Hyowon Kim  <hw1008.kim@samsung.com>
     2
     3        [EFL] Fix problems with the pixel dump.
     4        https://bugs.webkit.org/show_bug.cgi?id=131265
     5
     6        Reviewed by Gyuyoung Kim.
     7
     8        Painting and compositing paths of WebKit-EFL were totally modified from r166768.
     9        However pixel dump codes still call deprecated functions like ewk_view_paint(),
     10        which causes that nothing is drawn.
     11
     12        This patch adds new member functions to AcceleratedCompositingContext to support pixel dump.
     13        One of new functions is AcceleratedCompositingContext::extractImageData(),
     14        which replaces deprecated function calls. Besides the extractImageData() is invoked by
     15        ewk_view_screenshot_contents_get() in order to take the visible content displayed on the EFL webview.
     16
     17        * platform/graphics/cairo/CairoUtilities.cpp:
     18        (WebCore::flipImageSurfaceVertically): Flip pixel data of given cairo_surface_t vertically up/down.
     19        Whereas Cairo uses the top-left corner as being 0,0 of the coordinate system,
     20        OpenGL uses the bottom-left corner being 0,0.
     21        So we need to vertically flip resultant images taken by glReadPixels().
     22        * platform/graphics/cairo/CairoUtilities.h:
     23
    1242014-04-15  Hyowon Kim  <hw1008.kim@samsung.com>
    225
  • trunk/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp

    r167195 r167342  
    260260}
    261261
     262void flipImageSurfaceVertically(cairo_surface_t* surface)
     263{
     264    ASSERT(cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_IMAGE);
     265
     266    IntSize size = cairoSurfaceSize(surface);
     267    ASSERT(!size.isEmpty());
     268
     269    int stride = cairo_image_surface_get_stride(surface);
     270    int halfHeight = size.height() / 2;
     271
     272    uint8_t* source = static_cast<uint8_t*>(cairo_image_surface_get_data(surface));
     273    std::unique_ptr<uint8_t[]> tmp = std::make_unique<uint8_t[]>(stride);
     274
     275    for (int i = 0; i < halfHeight; ++i) {
     276        uint8_t* top = source + (i * stride);
     277        uint8_t* bottom = source + ((size.height()-i-1) * stride);
     278
     279        memcpy(tmp.get(), top, stride);
     280        memcpy(top, bottom, stride);
     281        memcpy(bottom, tmp.get(), stride);
     282    }
     283}
     284
    262285} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/cairo/CairoUtilities.h

    r167195 r167342  
    5757
    5858IntSize cairoSurfaceSize(cairo_surface_t*);
     59void flipImageSurfaceVertically(cairo_surface_t*);
    5960
    6061} // namespace WebCore
  • trunk/Source/WebKit/efl/ChangeLog

    r167185 r167342  
     12014-04-15  Hyowon Kim  <hw1008.kim@samsung.com>
     2
     3        [EFL] Fix problems with the pixel dump.
     4        https://bugs.webkit.org/show_bug.cgi?id=131265
     5
     6        Reviewed by Gyuyoung Kim.
     7
     8        Painting and compositing paths of WebKit-EFL were totally modified from r166768.
     9        However pixel dump codes still call deprecated functions like ewk_view_paint(),
     10        which causes that nothing is drawn.
     11
     12        This patch adds new member functions to AcceleratedCompositingContext to support pixel dump.
     13        One of new functions is AcceleratedCompositingContext::extractImageData(),
     14        which replaces deprecated function calls. Besides the extractImageData() is invoked by
     15        ewk_view_screenshot_contents_get() in order to take the visible content displayed on the EFL webview.
     16
     17        * WebCoreSupport/AcceleratedCompositingContextEfl.cpp:
     18        (WebCore::AcceleratedCompositingContext::AcceleratedCompositingContext):
     19        Create TextureMapper with a proper backend.
     20        (WebCore::AcceleratedCompositingContext::flushPendingLayerChanges):
     21        Revise a null check for m_rootLayer.
     22        (WebCore::AcceleratedCompositingContext::paintToGraphicsContext):
     23        Remove a creation check for TextureMapperGL.
     24        (WebCore::AcceleratedCompositingContext::paintToCurrentGLContext):
     25        Ditto.
     26        (WebCore::AcceleratedCompositingContext::extractImageData):
     27        Extract image data from the view and copy it to given Evas_Object.
     28        (WebCore::AcceleratedCompositingContext::getImageData):
     29        Get image data from the view and return it as cairo_surface_t on software mode.
     30        (WebCore::AcceleratedCompositingContext::getImageDataGL):
     31        Get image data from the view and return it as cairo_surface_t on GL mode.
     32        * WebCoreSupport/AcceleratedCompositingContextEfl.h:
     33        * WebCoreSupport/DumpRenderTreeSupportEfl.cpp:
     34        (DumpRenderTreeSupportEfl::forcePaint): Repaint the entire webview before pixel dump.
     35        * WebCoreSupport/DumpRenderTreeSupportEfl.h:
     36        * ewk/ewk_view.cpp:
     37        (ewk_view_mark_for_sync): Remove an unnecessary line.
     38        (ewk_view_force_paint): Call flushAndRenderLayers().
     39        (ewk_view_screenshot_contents_get): Remove 'scale' parameter and replace ewk_view_paint()
     40        with AcceleratedCompositingContext::extractImageData().
     41        * ewk/ewk_view.h:
     42        * ewk/ewk_view_private.h:
     43        * tests/test_ewk_view.cpp:
     44        (TEST_F):
     45
    1462014-04-12  Youenn Fablet  <youenn.fablet@crf.canon.fr>
    247
  • trunk/Source/WebKit/efl/WebCoreSupport/AcceleratedCompositingContextEfl.cpp

    r166768 r167342  
    2323
    2424#include "AcceleratedCompositingContextEfl.h"
     25#include "CairoUtilities.h"
    2526#include "CairoUtilitiesEfl.h"
    2627#include "GraphicsLayerTextureMapper.h"
     
    5455    }
    5556
    56     if (!m_evasGLContext)
     57    if (m_evasGLContext) {
     58        m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
     59        static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true);
     60    } else {
     61        m_textureMapper = TextureMapper::create(TextureMapper::SoftwareMode);
    5762        m_isAccelerated = false;
     63    }
    5864}
    5965
     
    123129bool AcceleratedCompositingContext::flushPendingLayerChanges()
    124130{
    125     if (!m_rootLayer)
    126         return false;
    127 
    128     m_rootLayer->flushCompositingStateForThisLayerOnly();
     131    if (m_rootLayer)
     132        m_rootLayer->flushCompositingStateForThisLayerOnly();
    129133    return EWKPrivate::corePage(m_view)->mainFrame().view()->flushCompositingStateIncludingSubframes();
    130134}
     
    132136void AcceleratedCompositingContext::paintToGraphicsContext()
    133137{
    134     if (!m_textureMapper)
    135         m_textureMapper = TextureMapper::create(TextureMapper::SoftwareMode);
    136 
    137138    RefPtr<cairo_surface_t> surface = createSurfaceForImage(m_compositingObject);
    138139    if (!surface)
     
    148149void AcceleratedCompositingContext::paintToCurrentGLContext()
    149150{
    150     if (!m_textureMapper) {
    151         m_textureMapper = TextureMapper::create(TextureMapper::OpenGLMode);
    152         static_cast<TextureMapperGL*>(m_textureMapper.get())->setEnableEdgeDistanceAntialiasing(true);
    153     }
    154 
    155151    if (!evas_gl_make_current(m_evasGL.get(), m_evasGLSurface->surface(), m_evasGLContext->context()))
    156152        return;
     
    190186}
    191187
     188void AcceleratedCompositingContext::extractImageData(Evas_Object* buffer, const IntRect& rect)
     189{
     190    ASSERT(buffer);
     191
     192    Evas_Coord width, height;
     193    evas_object_image_size_get(buffer, &width, &height);
     194
     195    ASSERT(rect.width() == width);
     196    ASSERT(rect.height() == height);
     197
     198    RefPtr<cairo_surface_t> imageData;
     199    if (m_isAccelerated) {
     200        imageData = getImageDataGL(rect);
     201        flipImageSurfaceVertically(imageData.get());
     202    } else
     203        imageData = getImageData(rect);
     204
     205    evas_object_image_data_copy_set(buffer, static_cast<void*>(cairo_image_surface_get_data(imageData.get())));
     206}
     207
     208PassRefPtr<cairo_surface_t> AcceleratedCompositingContext::getImageData(const IntRect& rect)
     209{
     210    RefPtr<cairo_surface_t> source = createSurfaceForImage(m_compositingObject);
     211    evas_object_image_data_set(m_compositingObject, static_cast<void*>(cairo_image_surface_get_data(source.get())));
     212
     213    if (m_viewSize == rect.size())
     214        return source.release();
     215
     216    RefPtr<cairo_surface_t> destination = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rect.width(), rect.height()));
     217    copyRectFromOneSurfaceToAnother(source.get(), destination.get(), -IntSize(rect.x(), rect.y()), IntRect(IntPoint(), rect.size()), IntSize(), CAIRO_OPERATOR_SOURCE);
     218    return destination.release();
     219}
     220
     221PassRefPtr<cairo_surface_t> AcceleratedCompositingContext::getImageDataGL(const IntRect& rect)
     222{
     223    if (!evas_gl_make_current(m_evasGL.get(), m_evasGLSurface->surface(), m_evasGLContext->context()))
     224        return nullptr;
     225
     226    RefPtr<cairo_surface_t> source = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rect.width(), rect.height()));
     227    uint8_t* sourcePtr = static_cast<uint8_t*>(cairo_image_surface_get_data(source.get()));
     228
     229    GraphicsContext3D* context3D = static_cast<TextureMapperGL*>(m_textureMapper.get())->graphicsContext3D();
     230    context3D->readPixels(rect.x(), rect.y(), rect.width(), rect.height(), GraphicsContext3D::BGRA, GraphicsContext3D::UNSIGNED_BYTE, sourcePtr);
     231    return source.release();
     232}
     233
    192234} // namespace WebCore
    193235
  • trunk/Source/WebKit/efl/WebCoreSupport/AcceleratedCompositingContextEfl.h

    r166889 r167342  
    4646    void flushAndRenderLayers();
    4747
     48    void extractImageData(Evas_Object*, const IntRect&);
     49
    4850private:
    4951    void paintToGraphicsContext();
     
    5355    bool flushPendingLayerChanges();
    5456    void syncLayers(Timer<AcceleratedCompositingContext>*);
     57
     58    PassRefPtr<cairo_surface_t> getImageData(const IntRect&);
     59    PassRefPtr<cairo_surface_t> getImageDataGL(const IntRect&);
    5560
    5661    Evas_Object* m_view;
  • trunk/Source/WebKit/efl/WebCoreSupport/DumpRenderTreeSupportEfl.cpp

    r165545 r167342  
    350350}
    351351
     352void DumpRenderTreeSupportEfl::forcePaint(Evas_Object* ewkView)
     353{
     354    ewk_view_force_paint(ewkView);
     355}
     356
    352357void DumpRenderTreeSupportEfl::setTracksRepaints(Evas_Object* ewkFrame, bool enabled)
    353358{
  • trunk/Source/WebKit/efl/WebCoreSupport/DumpRenderTreeSupportEfl.h

    r166149 r167342  
    8484
    8585    static void forceLayout(Evas_Object* ewkFrame);
     86    static void forcePaint(Evas_Object* ewkFrame);
    8687    static void setTracksRepaints(Evas_Object* ewkFrame, bool enabled);
    8788    static void resetTrackedRepaints(Evas_Object* ewkFrame);
  • trunk/Source/WebKit/efl/ewk/ewk_view.cpp

    r166915 r167342  
    44134413{
    44144414    EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
    4415     EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
    44164415
    44174416    // Mark the image as "dirty" meaning it needs an update next time evas renders.
    44184417    // It will call the pixel get callback then.
    44194418    evas_object_image_pixels_dirty_set(smartData->image, true);
     4419}
     4420
     4421void ewk_view_force_paint(Evas_Object* ewkView)
     4422{
     4423    EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData);
     4424    EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv);
     4425
     4426    priv->acceleratedCompositingContext->flushAndRenderLayers();
    44204427}
    44214428
     
    45444551}
    45454552
    4546 Evas_Object* ewk_view_screenshot_contents_get(const Evas_Object* ewkView, const Eina_Rectangle* area, float scale)
     4553Evas_Object* ewk_view_screenshot_contents_get(const Evas_Object* ewkView, const Eina_Rectangle* area)
    45474554{
    45484555    if (!area || !area->w || !area->h) {
     
    45514558    }
    45524559
    4553     if (scale < std::numeric_limits<float>::epsilon()) {
    4554         ERR("scale factor should be bigger than zero");
    4555         return 0;
    4556     }
    4557 
    45584560    EWK_VIEW_SD_GET_OR_RETURN(ewkView, smartData, 0);
    45594561    EWK_VIEW_PRIV_GET_OR_RETURN(smartData, priv, 0);
     
    45634565
    45644566    Evas_Object* screenshotImage = evas_object_image_add(canvas);
    4565     int surfaceWidth = area->w * scale;
    4566     int surfaceHeight = area->h * scale;
    4567     evas_object_image_size_set(screenshotImage, surfaceWidth, surfaceHeight);
    4568     evas_object_image_fill_set(screenshotImage, 0, 0, surfaceWidth, surfaceHeight);
    4569     evas_object_resize(screenshotImage, surfaceWidth, surfaceHeight);
     4567    evas_object_image_size_set(screenshotImage, area->w, area->h);
     4568    evas_object_image_fill_set(screenshotImage, 0, 0, area->w, area->h);
     4569    evas_object_resize(screenshotImage, area->w, area->h);
    45704570    evas_object_image_colorspace_set(screenshotImage, EVAS_COLORSPACE_ARGB8888);
    4571     evas_object_image_smooth_scale_set(screenshotImage, true);
    4572 
    4573     Ewk_Paint_Context* context = ewk_paint_context_from_image_new(screenshotImage);
    4574     ewk_paint_context_save(context);
    4575     ewk_paint_context_scale(context, scale, scale);
    4576     ewk_paint_context_translate(context, -1 * area->x, -1 * area->y);
    4577 
    4578     ewk_view_paint(priv, context, area);
    4579 
    4580     ewk_paint_context_restore(context);
    4581     ewk_paint_context_free(context);
     4571
     4572    priv->acceleratedCompositingContext->extractImageData(screenshotImage, WebCore::IntRect(*area));
    45824573
    45834574    return screenshotImage;
  • trunk/Source/WebKit/efl/ewk/ewk_view.h

    r166637 r167342  
    24872487
    24882488/**
    2489  * Gets the image object of the specified area of the page
     2489 * Gets the image object of the specified area of the view.
    24902490 *
    24912491 * The returned image object @b should be freed after use.
    24922492 *
    24932493 * @param o view object to be captured
    2494  * @param area The area of the page will be captured.
    2495  * @param scale scale factor of captured object.
     2494 * @param area The area of the view will be captured.
    24962495 *
    24972496 * @return newly allocated image object on sucess or @c NULL on failure.
    24982497 */
    2499 EAPI Evas_Object *ewk_view_screenshot_contents_get(const Evas_Object *o, const Eina_Rectangle *area, float scale);
     2498EAPI Evas_Object *ewk_view_screenshot_contents_get(const Evas_Object *o, const Eina_Rectangle *area);
    25002499
    25012500#ifdef __cplusplus
  • trunk/Source/WebKit/efl/ewk/ewk_view_private.h

    r165428 r167342  
    153153void ewk_view_mark_for_sync(Evas_Object* ewkView);
    154154
     155void ewk_view_force_paint(Evas_Object* ewkView);
     156
    155157#if ENABLE(FULLSCREEN_API)
    156158void ewk_view_fullscreen_enter(const Evas_Object* ewkView);
  • trunk/Source/WebKit/efl/tests/test_ewk_view.cpp

    r164168 r167342  
    133133    Evas_Coord width, height;
    134134
    135     float scale = 2;
    136135    Eina_Rectangle area;
    137136    area.x = 10;
     
    139138    area.w = 20;
    140139    area.h = 30;
    141     Evas_Object* screenshot = ewk_view_screenshot_contents_get(webView(), &area, scale);
     140    Evas_Object* screenshot = ewk_view_screenshot_contents_get(webView(), &area);
    142141    evas_object_geometry_get(screenshot, 0, 0, &width, &height);
    143     ASSERT_EQ(area.w * scale, width);
    144     ASSERT_EQ(area.h * scale, height);
     142    ASSERT_EQ(area.w, width);
     143    ASSERT_EQ(area.h, height);
    145144    evas_object_del(screenshot);
    146145
    147     screenshot = ewk_view_screenshot_contents_get(webView(), &area, 0);
    148     ASSERT_FALSE(screenshot);
    149 
    150     screenshot = ewk_view_screenshot_contents_get(webView(), 0, 1);
     146    screenshot = ewk_view_screenshot_contents_get(webView(), 0);
    151147    ASSERT_FALSE(screenshot);
    152148
    153149    area.w = 0;
    154150    area.h = 0;
    155     screenshot = ewk_view_screenshot_contents_get(webView(), &area, scale);
     151    screenshot = ewk_view_screenshot_contents_get(webView(), &area);
    156152    ASSERT_FALSE(screenshot);
    157153}
  • trunk/Tools/ChangeLog

    r167334 r167342  
     12014-04-15  Hyowon Kim  <hw1008.kim@samsung.com>
     2
     3        [EFL] Fix problems with the pixel dump.
     4        https://bugs.webkit.org/show_bug.cgi?id=131265
     5
     6        Reviewed by Gyuyoung Kim.
     7
     8        Painting and compositing paths of WebKit-EFL were totally modified from r166768.
     9        However pixel dump codes still call deprecated functions like ewk_view_paint(),
     10        which causes that nothing is drawn.
     11
     12        This patch adds new member functions to AcceleratedCompositingContext to support pixel dump.
     13        One of new functions is AcceleratedCompositingContext::extractImageData(),
     14        which replaces deprecated function calls. Besides the extractImageData() is invoked by
     15        ewk_view_screenshot_contents_get() in order to take the visible content displayed on the EFL webview.
     16
     17        * DumpRenderTree/efl/PixelDumpSupportEfl.cpp:
     18        (createBitmapContextFromWebView): Add to call DumpRenderTreeSupportEfl::forcePaint().
     19
    1202014-04-15  Filip Pizlo  <fpizlo@apple.com>
    221
  • trunk/Tools/DumpRenderTree/efl/PixelDumpSupportEfl.cpp

    r165676 r167342  
    4848    const Evas_Object* mainFrame = browser->mainFrame();
    4949
     50    DumpRenderTreeSupportEfl::forcePaint(browser->mainView());
     51
    5052    int x, y, width, height;
    5153    evas_object_geometry_get(browser->mainFrame(), &x, &y, &width, &height);
     
    5557    RefPtr<cairo_t> context = adoptRef(cairo_create(surface.get()));
    5658
    57     RefPtr<Evas_Object> screenshot = ewk_view_screenshot_contents_get(browser->mainView(), &rect, 1);
     59    RefPtr<Evas_Object> screenshot = ewk_view_screenshot_contents_get(browser->mainView(), &rect);
    5860    if (!screenshot)
    5961        return 0;
Note: See TracChangeset for help on using the changeset viewer.