Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
2011-03-11 Anders Carlsson <andersca@apple.com>
        Reviewed by Sam Weinig.

        Add a shared memory cache to the web process
        https://bugs.webkit.org/show_bug.cgi?id=56232

        Add a very simple shared memory cache to the web process, so that we don't have to allocate and
        free memory over and over when painting.

        * Shared/ShareableBitmap.cpp:
        (WebKit::ShareableBitmap::create):
        (WebKit::ShareableBitmap::createShareable):
        (WebKit::ShareableBitmap::resize):
        * Shared/ShareableBitmap.h:
        (WebKit::ShareableBitmap::numBytesNeededForBitmapSize):
        (WebKit::ShareableBitmap::sizeInBytes):
        Rename numBytesForSize to numBytesNeededForBitmapSize.

        * UIProcess/DrawingAreaProxyImpl.cpp:
        (WebKit::DrawingAreaProxyImpl::update):
        Always send back a DidUpdate message, even if we didn't use the update info.
        This is needed so that the web process knows when the UI process is done with the shared memory inside
        the update info struct.

        * WebKit2.xcodeproj/project.pbxproj:
        Add new files.

        * WebProcess/WebPage/DrawingArea.h:
        (WebKit::DrawingArea::didUpdate):
        * WebProcess/WebPage/DrawingArea.messages.in:
        DidUpdate now takes a boolean.

        * WebProcess/WebPage/DrawingAreaImpl.cpp:
        (WebKit::sharedMemoryCache):
        Add shared memory cache.

        (WebKit::DrawingAreaImpl::~DrawingAreaImpl):
        Return the shared memory to the cache.

        (WebKit::DrawingAreaImpl::sendDidUpdateBackingStoreState):
        display now takes an extra boolean.

        (WebKit::DrawingAreaImpl::didUpdate):
        Return the shared memory to the cache.

        (WebKit::DrawingAreaImpl::display):
        If useSharedMemoryCache is true, get shared memory from the cache.

        * WebProcess/WebPage/SharedMemoryCache.cpp: Added.
        (WebKit::SharedMemoryCache::acquireSharedMemory):
        If the memory we currently hold on to is big enough, return it.

        (WebKit::SharedMemoryCache::releaseSharedMemory):
        If we're already holding on to shared memory, evict it if the returned
        shared memory object is bigger than the one we currently hold.

        (WebKit::SharedMemoryCache::clearCacheTimerFired):
        Null out the shared memory object.


Canonical link: https://commits.webkit.org/70784@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@80899 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Anders Carlsson committed Mar 12, 2011
1 parent 56b7521 commit cc1bbe0
Show file tree
Hide file tree
Showing 11 changed files with 254 additions and 19 deletions.
60 changes: 60 additions & 0 deletions Source/WebKit2/ChangeLog
@@ -1,3 +1,63 @@
2011-03-11 Anders Carlsson <andersca@apple.com>

Reviewed by Sam Weinig.

Add a shared memory cache to the web process
https://bugs.webkit.org/show_bug.cgi?id=56232

Add a very simple shared memory cache to the web process, so that we don't have to allocate and
free memory over and over when painting.

* Shared/ShareableBitmap.cpp:
(WebKit::ShareableBitmap::create):
(WebKit::ShareableBitmap::createShareable):
(WebKit::ShareableBitmap::resize):
* Shared/ShareableBitmap.h:
(WebKit::ShareableBitmap::numBytesNeededForBitmapSize):
(WebKit::ShareableBitmap::sizeInBytes):
Rename numBytesForSize to numBytesNeededForBitmapSize.

* UIProcess/DrawingAreaProxyImpl.cpp:
(WebKit::DrawingAreaProxyImpl::update):
Always send back a DidUpdate message, even if we didn't use the update info.
This is needed so that the web process knows when the UI process is done with the shared memory inside
the update info struct.

* WebKit2.xcodeproj/project.pbxproj:
Add new files.

* WebProcess/WebPage/DrawingArea.h:
(WebKit::DrawingArea::didUpdate):
* WebProcess/WebPage/DrawingArea.messages.in:
DidUpdate now takes a boolean.

* WebProcess/WebPage/DrawingAreaImpl.cpp:
(WebKit::sharedMemoryCache):
Add shared memory cache.

(WebKit::DrawingAreaImpl::~DrawingAreaImpl):
Return the shared memory to the cache.

(WebKit::DrawingAreaImpl::sendDidUpdateBackingStoreState):
display now takes an extra boolean.

(WebKit::DrawingAreaImpl::didUpdate):
Return the shared memory to the cache.

(WebKit::DrawingAreaImpl::display):
If useSharedMemoryCache is true, get shared memory from the cache.

* WebProcess/WebPage/SharedMemoryCache.cpp: Added.
(WebKit::SharedMemoryCache::acquireSharedMemory):
If the memory we currently hold on to is big enough, return it.

(WebKit::SharedMemoryCache::releaseSharedMemory):
If we're already holding on to shared memory, evict it if the returned
shared memory object is bigger than the one we currently hold.

(WebKit::SharedMemoryCache::clearCacheTimerFired):
Null out the shared memory object.

2011-03-11 Jessie Berlin <jberlin@apple.com>

Reviewed by Adam Roben.
Expand Down
8 changes: 4 additions & 4 deletions Source/WebKit2/Shared/ShareableBitmap.cpp
Expand Up @@ -35,7 +35,7 @@ namespace WebKit {

PassRefPtr<ShareableBitmap> ShareableBitmap::create(const WebCore::IntSize& size)
{
size_t numBytes = numBytesForSize(size);
size_t numBytes = numBytesNeededForBitmapSize(size);

void* data = 0;
if (!tryFastMalloc(numBytes).getValue(data))
Expand All @@ -46,7 +46,7 @@ PassRefPtr<ShareableBitmap> ShareableBitmap::create(const WebCore::IntSize& size

PassRefPtr<ShareableBitmap> ShareableBitmap::createShareable(const IntSize& size)
{
size_t numBytes = numBytesForSize(size);
size_t numBytes = numBytesNeededForBitmapSize(size);

RefPtr<SharedMemory> sharedMemory = SharedMemory::create(numBytes);
if (!sharedMemory)
Expand All @@ -59,7 +59,7 @@ PassRefPtr<ShareableBitmap> ShareableBitmap::create(const WebCore::IntSize& size
{
ASSERT(sharedMemory);

size_t numBytes = numBytesForSize(size);
size_t numBytes = numBytesNeededForBitmapSize(size);
ASSERT_UNUSED(numBytes, sharedMemory->size() >= numBytes);

return adoptRef(new ShareableBitmap(size, sharedMemory));
Expand Down Expand Up @@ -109,7 +109,7 @@ bool ShareableBitmap::resize(const IntSize& size)
if (size == m_size)
return true;

size_t newNumBytes = numBytesForSize(size);
size_t newNumBytes = numBytesNeededForBitmapSize(size);

// Try to resize.
char* newData = 0;
Expand Down
6 changes: 3 additions & 3 deletions Source/WebKit2/Shared/ShareableBitmap.h
Expand Up @@ -58,6 +58,8 @@ class ShareableBitmap : public RefCounted<ShareableBitmap> {

~ShareableBitmap();

static size_t numBytesNeededForBitmapSize(const WebCore::IntSize& size) { return size.width() * size.height() * 4; }

const WebCore::IntSize& size() const { return m_size; }
WebCore::IntRect bounds() const { return WebCore::IntRect(WebCore::IntPoint(), size()); }

Expand All @@ -75,12 +77,10 @@ class ShareableBitmap : public RefCounted<ShareableBitmap> {
ShareableBitmap(const WebCore::IntSize&, void*);
ShareableBitmap(const WebCore::IntSize&, PassRefPtr<SharedMemory>);

static size_t numBytesForSize(const WebCore::IntSize& size) { return size.width() * size.height() * 4; }

static void releaseData(void* typelessBitmap, void* typelessData);

void* data() const;
size_t sizeInBytes() const { return numBytesForSize(m_size); }
size_t sizeInBytes() const { return numBytesNeededForBitmapSize(m_size); }

WebCore::IntSize m_size;

Expand Down
7 changes: 5 additions & 2 deletions Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp
Expand Up @@ -144,13 +144,16 @@ void DrawingAreaProxyImpl::setPageIsVisible(bool)
void DrawingAreaProxyImpl::update(uint64_t backingStoreStateID, const UpdateInfo& updateInfo)
{
ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_currentBackingStoreStateID);
if (backingStoreStateID < m_currentBackingStoreStateID)
if (backingStoreStateID < m_currentBackingStoreStateID) {
// We still want to send back a message so that the web process knows that it can reuse the shared memory used for the update info.
m_webPageProxy->process()->send(Messages::DrawingArea::DidUpdate(false), m_webPageProxy->pageID());
return;
}

// FIXME: Handle the case where the view is hidden.

incorporateUpdate(updateInfo);
m_webPageProxy->process()->send(Messages::DrawingArea::DidUpdate(), m_webPageProxy->pageID());
m_webPageProxy->process()->send(Messages::DrawingArea::DidUpdate(true), m_webPageProxy->pageID());
}

void DrawingAreaProxyImpl::didUpdateBackingStoreState(uint64_t backingStoreStateID, const UpdateInfo& updateInfo, const LayerTreeContext& layerTreeContext)
Expand Down
8 changes: 8 additions & 0 deletions Source/WebKit2/WebKit2.xcodeproj/project.pbxproj
Expand Up @@ -75,6 +75,8 @@
1A24B5F311F531E800C38269 /* MachUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A24B5F111F531E800C38269 /* MachUtilities.h */; };
1A24BED5120894D100FBB059 /* SharedMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A24BED3120894D100FBB059 /* SharedMemory.h */; };
1A24BF3A120896A600FBB059 /* SharedMemoryMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A24BF39120896A600FBB059 /* SharedMemoryMac.cpp */; };
1A27A5C8132AC86A001138FB /* SharedMemoryCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A27A5C6132AC86A001138FB /* SharedMemoryCache.cpp */; };
1A27A5C9132AC86A001138FB /* SharedMemoryCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A27A5C7132AC86A001138FB /* SharedMemoryCache.h */; };
1A2C307112D555450063DAA2 /* ContextMenuState.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A2C306F12D555450063DAA2 /* ContextMenuState.h */; };
1A2D82A4127F4EAB001EB962 /* NPObjectMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A1FA35C127A45BF0050E709 /* NPObjectMessageReceiver.cpp */; };
1A2D82A5127F4EAB001EB962 /* NPObjectMessageReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A1FA35B127A45BF0050E709 /* NPObjectMessageReceiver.h */; };
Expand Down Expand Up @@ -900,6 +902,8 @@
1A24B5F111F531E800C38269 /* MachUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MachUtilities.h; sourceTree = "<group>"; };
1A24BED3120894D100FBB059 /* SharedMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedMemory.h; sourceTree = "<group>"; };
1A24BF39120896A600FBB059 /* SharedMemoryMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedMemoryMac.cpp; sourceTree = "<group>"; };
1A27A5C6132AC86A001138FB /* SharedMemoryCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedMemoryCache.cpp; sourceTree = "<group>"; };
1A27A5C7132AC86A001138FB /* SharedMemoryCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedMemoryCache.h; sourceTree = "<group>"; };
1A2C306F12D555450063DAA2 /* ContextMenuState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContextMenuState.h; sourceTree = "<group>"; };
1A2D8411127F64E8001EB962 /* NPObjectMessageReceiver.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = NPObjectMessageReceiver.messages.in; sourceTree = "<group>"; };
1A2D8437127F65D5001EB962 /* NPObjectMessageReceiverMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NPObjectMessageReceiverMessageReceiver.cpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2323,6 +2327,8 @@
1A186EE812EF7618008E5F37 /* LayerTreeHost.h */,
1A90C23612650717003E44D4 /* PageOverlay.cpp */,
1A90C23512650717003E44D4 /* PageOverlay.h */,
1A27A5C6132AC86A001138FB /* SharedMemoryCache.cpp */,
1A27A5C7132AC86A001138FB /* SharedMemoryCache.h */,
BC72B9F811E6476B001EB4EA /* WebBackForwardListProxy.cpp */,
BC72B9F911E6476B001EB4EA /* WebBackForwardListProxy.h */,
51871B59127CB89D00F76232 /* WebContextMenu.cpp */,
Expand Down Expand Up @@ -3455,6 +3461,7 @@
37C4E9F6131C6E7E0029BD5A /* config.h in Headers */,
E1BB16A413201B9B00F49431 /* FullKeyboardAccessWatcher.h in Headers */,
33AA1067131F060000D4A575 /* WebCookieManagerProxyClient.h in Headers */,
1A27A5C9132AC86A001138FB /* SharedMemoryCache.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -4059,6 +4066,7 @@
CD73BA4E131ACDB700EEDED2 /* WebFullScreenManagerMessageReceiver.cpp in Sources */,
CD73BA53131B645B00EEDED2 /* WebFullScreenManager.cpp in Sources */,
CD6F75F4131B66D000D6B21E /* WebFullScreenManagerProxy.cpp in Sources */,
1A27A5C8132AC86A001138FB /* SharedMemoryCache.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
2 changes: 1 addition & 1 deletion Source/WebKit2/WebProcess/WebPage/DrawingArea.h
Expand Up @@ -86,7 +86,7 @@ class DrawingArea {
// CoreIPC message handlers.
// FIXME: These should be pure virtual.
virtual void updateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, const WebCore::IntSize& size, const WebCore::IntSize& scrollOffset) { }
virtual void didUpdate() { }
virtual void didUpdate(bool didIncorporateBackingStore) { }
virtual void suspendPainting() { }
virtual void resumePainting() { }
};
Expand Down
2 changes: 1 addition & 1 deletion Source/WebKit2/WebProcess/WebPage/DrawingArea.messages.in
Expand Up @@ -22,7 +22,7 @@

messages -> DrawingArea {
UpdateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, WebCore::IntSize size, WebCore::IntSize scrollOffset)
DidUpdate()
DidUpdate(bool didIncorporateBackingStore)
SuspendPainting()
ResumePainting()
}
41 changes: 35 additions & 6 deletions Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.cpp
Expand Up @@ -29,6 +29,7 @@
#include "DrawingAreaProxyMessages.h"
#include "LayerTreeContext.h"
#include "ShareableBitmap.h"
#include "SharedMemoryCache.h"
#include "UpdateInfo.h"
#include "WebPage.h"
#include "WebPageCreationParameters.h"
Expand All @@ -45,13 +46,23 @@ using namespace WebCore;

namespace WebKit {

static SharedMemoryCache& sharedMemoryCache()
{
DEFINE_STATIC_LOCAL(SharedMemoryCache, sharedMemoryCache, ());

return sharedMemoryCache;
}

PassOwnPtr<DrawingAreaImpl> DrawingAreaImpl::create(WebPage* webPage, const WebPageCreationParameters& parameters)
{
return adoptPtr(new DrawingAreaImpl(webPage, parameters));
}

DrawingAreaImpl::~DrawingAreaImpl()
{
if (m_sharedMemoryUsedForLastUpdate)
sharedMemoryCache().releaseSharedMemory(m_sharedMemoryUsedForLastUpdate.release());

if (m_layerTreeHost)
m_layerTreeHost->invalidate();
}
Expand Down Expand Up @@ -296,7 +307,7 @@ void DrawingAreaImpl::sendDidUpdateBackingStoreState()
UpdateInfo updateInfo;

if (!m_isPaintingSuspended && !m_layerTreeHost)
display(updateInfo);
display(updateInfo, false);

#if USE(ACCELERATED_COMPOSITING)
LayerTreeContext layerTreeContext;
Expand All @@ -319,8 +330,14 @@ void DrawingAreaImpl::sendDidUpdateBackingStoreState()
#endif
}

void DrawingAreaImpl::didUpdate()
void DrawingAreaImpl::didUpdate(bool didIncorporateBackingStore)
{
ASSERT(m_sharedMemoryUsedForLastUpdate);
sharedMemoryCache().releaseSharedMemory(m_sharedMemoryUsedForLastUpdate.release());

if (!didIncorporateBackingStore)
return;

// We might get didUpdate messages from the UI process even after we've
// entered accelerated compositing mode. Ignore them.
if (m_layerTreeHost)
Expand Down Expand Up @@ -395,7 +412,7 @@ void DrawingAreaImpl::exitAcceleratedCompositingMode()
if (m_isPaintingSuspended)
updateInfo.viewSize = m_webPage->size();
else
display(updateInfo);
display(updateInfo, false);

#if USE(ACCELERATED_COMPOSITING)
// Send along a complete update of the page so we can paint the contents right after we exit the
Expand Down Expand Up @@ -462,7 +479,7 @@ void DrawingAreaImpl::display()
}

UpdateInfo updateInfo;
display(updateInfo);
display(updateInfo, true);

if (m_layerTreeHost) {
// The call to update caused layout which turned on accelerated compositing.
Expand Down Expand Up @@ -495,7 +512,7 @@ static bool shouldPaintBoundsRect(const IntRect& bounds, const Vector<IntRect>&
return wastedSpace <= wastedSpaceThreshold;
}

void DrawingAreaImpl::display(UpdateInfo& updateInfo)
void DrawingAreaImpl::display(UpdateInfo& updateInfo, bool useSharedMemoryCache)
{
ASSERT(!m_isPaintingSuspended);
ASSERT(!m_layerTreeHost);
Expand All @@ -515,7 +532,19 @@ void DrawingAreaImpl::display(UpdateInfo& updateInfo)
IntRect bounds = m_dirtyRegion.bounds();
ASSERT(m_webPage->bounds().contains(bounds));

RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(bounds.size());
RefPtr<ShareableBitmap> bitmap;
if (useSharedMemoryCache) {
size_t size = ShareableBitmap::numBytesNeededForBitmapSize(bounds.size());

ASSERT(!m_sharedMemoryUsedForLastUpdate);

m_sharedMemoryUsedForLastUpdate = sharedMemoryCache().acquireSharedMemory(size);
bitmap = ShareableBitmap::create(bounds.size(), m_sharedMemoryUsedForLastUpdate);
} else {
// Just create a new shareable bitmap.
bitmap = ShareableBitmap::createShareable(bounds.size());
}

if (!bitmap->createHandle(updateInfo.bitmapHandle))
return;

Expand Down
11 changes: 9 additions & 2 deletions Source/WebKit2/WebProcess/WebPage/DrawingAreaImpl.h
Expand Up @@ -33,6 +33,7 @@

namespace WebKit {

class SharedMemory;
class UpdateInfo;

class DrawingAreaImpl : public DrawingArea {
Expand Down Expand Up @@ -61,7 +62,7 @@ class DrawingAreaImpl : public DrawingArea {

// CoreIPC message handlers.
virtual void updateBackingStoreState(uint64_t backingStoreStateID, bool respondImmediately, const WebCore::IntSize&, const WebCore::IntSize& scrollOffset);
virtual void didUpdate();
virtual void didUpdate(bool didIncorporateBackingStore);
virtual void suspendPainting();
virtual void resumePainting();

Expand All @@ -74,7 +75,7 @@ class DrawingAreaImpl : public DrawingArea {
void scheduleDisplay();
void displayTimerFired();
void display();
void display(UpdateInfo&);
void display(UpdateInfo&, bool useSharedMemoryCache);

uint64_t m_backingStoreStateID;

Expand Down Expand Up @@ -105,6 +106,12 @@ class DrawingAreaImpl : public DrawingArea {

// The layer tree host that handles accelerated compositing.
RefPtr<LayerTreeHost> m_layerTreeHost;

// The shared memory we used for the last update. If possible, we'll try
// to reuse it for subsequent paints to avoid allocating/freeeing shared memory
// for every paint.
RefPtr<SharedMemory> m_sharedMemoryUsedForLastUpdate;

};

} // namespace WebKit
Expand Down

0 comments on commit cc1bbe0

Please sign in to comment.