RemoteResourceCacheProxy.cpp [plain text]
#include "config.h"
#include "RemoteResourceCacheProxy.h"
#if ENABLE(GPU_PROCESS)
#include "RemoteRenderingBackendProxy.h"
namespace WebKit {
using namespace WebCore;
RemoteResourceCacheProxy::RemoteResourceCacheProxy(RemoteRenderingBackendProxy& remoteRenderingBackendProxy)
: m_remoteRenderingBackendProxy(remoteRenderingBackendProxy)
{
}
RemoteResourceCacheProxy::~RemoteResourceCacheProxy()
{
for (auto& image : m_nativeImages.values())
image->removeObserver(*this);
}
void RemoteResourceCacheProxy::cacheImageBuffer(WebCore::ImageBuffer& imageBuffer)
{
auto addResult = m_imageBuffers.add(imageBuffer.renderingResourceIdentifier(), makeWeakPtr(imageBuffer));
ASSERT_UNUSED(addResult, addResult.isNewEntry);
}
ImageBuffer* RemoteResourceCacheProxy::cachedImageBuffer(RenderingResourceIdentifier renderingResourceIdentifier)
{
return m_imageBuffers.get(renderingResourceIdentifier).get();
}
void RemoteResourceCacheProxy::releaseImageBuffer(RenderingResourceIdentifier renderingResourceIdentifier)
{
bool found = m_imageBuffers.remove(renderingResourceIdentifier);
ASSERT_UNUSED(found, found);
}
inline static RefPtr<ShareableBitmap> createShareableBitmapFromNativeImage(NativeImage& image)
{
auto imageSize = image.size();
auto bitmap = ShareableBitmap::createShareable(image.size(), { });
if (!bitmap)
return nullptr;
auto context = bitmap->createGraphicsContext();
if (!context)
return nullptr;
context->drawNativeImage(image, imageSize, FloatRect({ }, imageSize), FloatRect({ }, imageSize));
return bitmap;
}
void RemoteResourceCacheProxy::cacheNativeImage(NativeImage& image)
{
if (m_nativeImages.contains(image.renderingResourceIdentifier()))
return;
auto bitmap = createShareableBitmapFromNativeImage(image);
if (!bitmap)
return;
ShareableBitmap::Handle handle;
bitmap->createHandle(handle);
if (handle.isNull())
return;
m_nativeImages.add(image.renderingResourceIdentifier(), makeWeakPtr(image));
image.addObserver(*this);
m_remoteRenderingBackendProxy.cacheNativeImage(handle, image.renderingResourceIdentifier());
}
void RemoteResourceCacheProxy::cacheFont(Font& font)
{
auto result = m_fontIdentifierToLastRenderingUpdateVersionMap.ensure(font.renderingResourceIdentifier(), [&] {
return 0;
});
auto& lastVersion = result.iterator->value;
if (lastVersion != m_currentRenderingUpdateVersion) {
lastVersion = m_currentRenderingUpdateVersion;
++m_numberOfFontsUsedInCurrentRenderingUpdate;
}
if (result.isNewEntry)
m_remoteRenderingBackendProxy.cacheFont(makeRef(font));
}
void RemoteResourceCacheProxy::releaseNativeImage(RenderingResourceIdentifier renderingResourceIdentifier)
{
if (!m_nativeImages.remove(renderingResourceIdentifier))
return;
m_remoteRenderingBackendProxy.releaseRemoteResource(renderingResourceIdentifier);
}
void RemoteResourceCacheProxy::didFinalizeRenderingUpdate()
{
static constexpr unsigned minimumRenderingUpdateCountToKeepFontAlive = 4;
static constexpr double minimumFractionOfUnusedFontCountToTriggerRemoval = 0.25;
static constexpr unsigned maximumUnusedFontCountToSkipRemoval = 0;
unsigned totalFontCount = m_fontIdentifierToLastRenderingUpdateVersionMap.size();
RELEASE_ASSERT(m_numberOfFontsUsedInCurrentRenderingUpdate <= totalFontCount);
unsigned unusedFontCount = totalFontCount - m_numberOfFontsUsedInCurrentRenderingUpdate;
if (unusedFontCount < minimumFractionOfUnusedFontCountToTriggerRemoval * totalFontCount && unusedFontCount <= maximumUnusedFontCountToSkipRemoval)
return;
for (auto& item : m_fontIdentifierToLastRenderingUpdateVersionMap) {
if (m_currentRenderingUpdateVersion - item.value >= minimumRenderingUpdateCountToKeepFontAlive)
m_remoteRenderingBackendProxy.releaseRemoteResource(item.key);
}
++m_currentRenderingUpdateVersion;
m_numberOfFontsUsedInCurrentRenderingUpdate = 0;
}
void RemoteResourceCacheProxy::releaseMemory()
{
m_fontIdentifierToLastRenderingUpdateVersionMap.clear();
m_numberOfFontsUsedInCurrentRenderingUpdate = 0;
m_remoteRenderingBackendProxy.deleteAllFonts();
}
}
#endif // ENABLE(GPU_PROCESS)