Skip to content

Commit

Permalink
Merge r221521 - [GTK][Wayland] Use fast malloc to allocate backing st…
Browse files Browse the repository at this point in the history
…ore cairo surfaces data

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

Reviewed by Michael Catanzaro.

Source/WebCore:

It reduces the memory consumption and improves the performance. Also, since performance is better we don't need
to keep the scroll surface allocated all the time, we can create it on demand and keep it allocated only while
scrolling too fast.

* platform/graphics/cairo/BackingStoreBackendCairoImpl.cpp:
(WebCore::createCairoImageSurfaceWithFastMalloc): Helper to create a cairo image surface using fast malloc.
(WebCore::BackingStoreBackendCairoImpl::BackingStoreBackendCairoImpl): Create the main surface, but no the
scroll one. Initialize the hysteresis activity to discard the scroll surface after scrolling.
(WebCore::BackingStoreBackendCairoImpl::scroll): Create the scroll surface only if it's nullptr, and notify the
hysteresis activity.
* platform/graphics/cairo/BackingStoreBackendCairoImpl.h:

Source/WebKit:

Do not create the cairo surface for BackingStoreBackendCairoImpl. When not using X11 we are going to use an
image surface anyway, so we don't really need to use the create similar. This way we only need to pass the size
and device scale factor to BackingStoreBackendCairoImpl that will create the image surface using fast malloc to
allocate the data.

* UIProcess/cairo/BackingStoreCairo.cpp:
(WebKit::BackingStore::createBackend):
  • Loading branch information
carlosgcampos committed Sep 4, 2017
1 parent ca281ce commit 084e3ca
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 31 deletions.
19 changes: 19 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,22 @@
2017-09-02 Carlos Garcia Campos <cgarcia@igalia.com>

[GTK][Wayland] Use fast malloc to allocate backing store cairo surfaces data
https://bugs.webkit.org/show_bug.cgi?id=176226

Reviewed by Michael Catanzaro.

It reduces the memory consumption and improves the performance. Also, since performance is better we don't need
to keep the scroll surface allocated all the time, we can create it on demand and keep it allocated only while
scrolling too fast.

* platform/graphics/cairo/BackingStoreBackendCairoImpl.cpp:
(WebCore::createCairoImageSurfaceWithFastMalloc): Helper to create a cairo image surface using fast malloc.
(WebCore::BackingStoreBackendCairoImpl::BackingStoreBackendCairoImpl): Create the main surface, but no the
scroll one. Initialize the hysteresis activity to discard the scroll surface after scrolling.
(WebCore::BackingStoreBackendCairoImpl::scroll): Create the scroll surface only if it's nullptr, and notify the
hysteresis activity.
* platform/graphics/cairo/BackingStoreBackendCairoImpl.h:

2017-09-01 Emilio Cobos Álvarez <emilio@crisal.io>

Wrong getComputedStyle behavior for pseudo-elements for layout-dependent properties.
Expand Down
Expand Up @@ -26,19 +26,26 @@

namespace WebCore {

BackingStoreBackendCairoImpl::BackingStoreBackendCairoImpl(cairo_surface_t* surface, const IntSize& size)
static const Seconds scrollHysteresisDuration { 300_ms };

static RefPtr<cairo_surface_t> createCairoImageSurfaceWithFastMalloc(const IntSize& size, double deviceScaleFactor)
{
static cairo_user_data_key_t s_surfaceDataKey;
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, size.width());
auto* surfaceData = fastZeroedMalloc(size.height() * stride);
RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create_for_data(static_cast<unsigned char*>(surfaceData), CAIRO_FORMAT_ARGB32, size.width(), size.height(), stride));
cairo_surface_set_user_data(surface.get(), &s_surfaceDataKey, surfaceData, [](void* data) { fastFree(data); });
cairoSurfaceSetDeviceScale(surface.get(), deviceScaleFactor, deviceScaleFactor);
return surface;
}

BackingStoreBackendCairoImpl::BackingStoreBackendCairoImpl(const IntSize& size, float deviceScaleFactor)
: BackingStoreBackendCairo(size)
, m_scrolledHysteresis([this](HysteresisState state) { if (state == HysteresisState::Stopped) m_scrollSurface = nullptr; }, scrollHysteresisDuration)
{
m_surface = surface;

// We keep two copies of the surface here, which will double the memory usage, but increase
// scrolling performance since we do not have to keep reallocating a memory region during
// quick scrolling requests.
double xScale, yScale;
cairoSurfaceGetDeviceScale(m_surface.get(), xScale, yScale);
IntSize scaledSize = size;
scaledSize.scale(xScale, yScale);
m_scrollSurface = adoptRef(cairo_surface_create_similar(surface, CAIRO_CONTENT_COLOR_ALPHA, scaledSize.width(), scaledSize.height()));
IntSize scaledSize = m_size;
scaledSize.scale(deviceScaleFactor);
m_surface = createCairoImageSurfaceWithFastMalloc(scaledSize, deviceScaleFactor);
}

BackingStoreBackendCairoImpl::~BackingStoreBackendCairoImpl()
Expand All @@ -54,8 +61,17 @@ void BackingStoreBackendCairoImpl::scroll(const IntRect& scrollRect, const IntSi
if (targetRect.isEmpty())
return;

if (!m_scrollSurface) {
IntSize size(cairo_image_surface_get_width(m_surface.get()), cairo_image_surface_get_height(m_surface.get()));
double xScale, yScale;
cairoSurfaceGetDeviceScale(m_surface.get(), xScale, yScale);
ASSERT(xScale == yScale);
m_scrollSurface = createCairoImageSurfaceWithFastMalloc(size, xScale);
}
copyRectFromOneSurfaceToAnother(m_surface.get(), m_scrollSurface.get(), scrollOffset, targetRect);
copyRectFromOneSurfaceToAnother(m_scrollSurface.get(), m_surface.get(), IntSize(), targetRect);

m_scrolledHysteresis.impulse();
}

} // namespace WebCore
Expand Down
Expand Up @@ -16,28 +16,26 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef BackingStoreBackendCairoImpl_h
#define BackingStoreBackendCairoImpl_h

#include "BackingStoreBackendCairo.h"
#pragma once

#if USE(CAIRO)
#include "BackingStoreBackendCairo.h"
#include <WebCore/HysteresisActivity.h>

namespace WebCore {

class BackingStoreBackendCairoImpl final : public BackingStoreBackendCairo {
public:
BackingStoreBackendCairoImpl(cairo_surface_t*, const IntSize&);
BackingStoreBackendCairoImpl(const IntSize&, float deviceScaleFactor);
virtual ~BackingStoreBackendCairoImpl();

private:
void scroll(const IntRect&, const IntSize&) override;

private:
RefPtr<cairo_surface_t> m_scrollSurface;
WebCore::HysteresisActivity m_scrolledHysteresis;
};

} // namespace WebCore

#endif // USE(CAIRO)

#endif // BackingStoreBackendCairoImpl_h
15 changes: 15 additions & 0 deletions Source/WebKit/ChangeLog
@@ -1,3 +1,18 @@
2017-09-02 Carlos Garcia Campos <cgarcia@igalia.com>

[GTK][Wayland] Use fast malloc to allocate backing store cairo surfaces data
https://bugs.webkit.org/show_bug.cgi?id=176226

Reviewed by Michael Catanzaro.

Do not create the cairo surface for BackingStoreBackendCairoImpl. When not using X11 we are going to use an
image surface anyway, so we don't really need to use the create similar. This way we only need to pass the size
and device scale factor to BackingStoreBackendCairoImpl that will create the image surface using fast malloc to
allocate the data.

* UIProcess/cairo/BackingStoreCairo.cpp:
(WebKit::BackingStore::createBackend):

2017-09-02 Carlos Garcia Campos <cgarcia@igalia.com>

[GTK][Wayland] Opening FedoraProject's pastebin chews CPU
Expand Down
13 changes: 1 addition & 12 deletions Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp
Expand Up @@ -63,18 +63,7 @@ std::unique_ptr<BackingStoreBackendCairo> BackingStore::createBackend()
}
#endif

IntSize scaledSize = m_size;
scaledSize.scale(m_deviceScaleFactor);

#if PLATFORM(GTK)
RefPtr<cairo_surface_t> surface = adoptRef(gdk_window_create_similar_surface(gtk_widget_get_window(m_webPageProxy.viewWidget()),
CAIRO_CONTENT_COLOR_ALPHA, scaledSize.width(), scaledSize.height()));
#else
RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, scaledSize.width(), scaledSize.height()));
#endif

cairoSurfaceSetDeviceScale(surface.get(), m_deviceScaleFactor, m_deviceScaleFactor);
return std::make_unique<BackingStoreBackendCairoImpl>(surface.get(), m_size);
return std::make_unique<BackingStoreBackendCairoImpl>(m_size, m_deviceScaleFactor);
}

void BackingStore::paint(cairo_t* context, const IntRect& rect)
Expand Down

0 comments on commit 084e3ca

Please sign in to comment.