blob: a82f3c1131cc68499f2343436ce9926a04c01f78 [file] [log] [blame]
/*
* Copyright (C) 2021-2022 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#if ENABLE(GPU_PROCESS)
#include "QualifiedRenderingResourceIdentifier.h"
#include <WebCore/DisplayListResourceHeap.h>
#include <WebCore/Font.h>
#include <WebCore/ImageBuffer.h>
#include <WebCore/NativeImage.h>
#include <WebCore/ProcessIdentifier.h>
#include <wtf/HashMap.h>
namespace WebKit {
class QualifiedResourceHeap : public WebCore::DisplayList::ResourceHeap {
public:
QualifiedResourceHeap(WebCore::ProcessIdentifier webProcessIdentifier)
: m_webProcessIdentifier(webProcessIdentifier)
{
}
void add(QualifiedRenderingResourceIdentifier renderingResourceIdentifier, Ref<WebCore::ImageBuffer>&& imageBuffer)
{
add(renderingResourceIdentifier, WTFMove(imageBuffer), m_imageBufferCount);
}
void add(QualifiedRenderingResourceIdentifier renderingResourceIdentifier, Ref<WebCore::NativeImage>&& image)
{
add(renderingResourceIdentifier, WTFMove(image), m_nativeImageCount);
}
void add(QualifiedRenderingResourceIdentifier renderingResourceIdentifier, Ref<WebCore::Font>&& font)
{
add(renderingResourceIdentifier, WTFMove(font), m_fontCount);
}
void add(QualifiedRenderingResourceIdentifier renderingResourceIdentifier, Ref<WebCore::DecomposedGlyphs>&& decomposedGlyphs)
{
add(renderingResourceIdentifier, WTFMove(decomposedGlyphs), m_decomposedGlyphsCount);
}
WebCore::ImageBuffer* getImageBuffer(WebCore::RenderingResourceIdentifier renderingResourceIdentifier) const final
{
return get<WebCore::ImageBuffer>({ renderingResourceIdentifier, m_webProcessIdentifier });
}
WebCore::NativeImage* getNativeImage(WebCore::RenderingResourceIdentifier renderingResourceIdentifier) const final
{
return get<WebCore::NativeImage>({ renderingResourceIdentifier, m_webProcessIdentifier });
}
std::optional<WebCore::SourceImage> getSourceImage(WebCore::RenderingResourceIdentifier renderingResourceIdentifier) const final
{
return getSourceImage({ renderingResourceIdentifier, m_webProcessIdentifier });
}
WebCore::Font* getFont(WebCore::RenderingResourceIdentifier renderingResourceIdentifier) const final
{
return get<WebCore::Font>({ renderingResourceIdentifier, m_webProcessIdentifier });
}
WebCore::DecomposedGlyphs* getDecomposedGlyphs(WebCore::RenderingResourceIdentifier renderingResourceIdentifier) const final
{
return get<WebCore::DecomposedGlyphs>({ renderingResourceIdentifier, m_webProcessIdentifier });
}
WebCore::ImageBuffer* getImageBuffer(QualifiedRenderingResourceIdentifier renderingResourceIdentifier) const
{
return get<WebCore::ImageBuffer>(renderingResourceIdentifier);
}
WebCore::NativeImage* getNativeImage(QualifiedRenderingResourceIdentifier renderingResourceIdentifier) const
{
return get<WebCore::NativeImage>(renderingResourceIdentifier);
}
std::optional<WebCore::SourceImage> getSourceImage(QualifiedRenderingResourceIdentifier renderingResourceIdentifier) const
{
if (!renderingResourceIdentifier)
return std::nullopt;
if (auto nativeImage = getNativeImage(renderingResourceIdentifier))
return { { *nativeImage } };
if (auto imageBuffer = getImageBuffer(renderingResourceIdentifier))
return { { *imageBuffer } };
return std::nullopt;
}
WebCore::Font* getFont(QualifiedRenderingResourceIdentifier renderingResourceIdentifier) const
{
return get<WebCore::Font>(renderingResourceIdentifier);
}
WebCore::DecomposedGlyphs* getDecomposedGlyphs(QualifiedRenderingResourceIdentifier renderingResourceIdentifier) const
{
return get<WebCore::DecomposedGlyphs>(renderingResourceIdentifier);
}
bool removeImageBuffer(QualifiedRenderingResourceIdentifier renderingResourceIdentifier)
{
return remove<WebCore::ImageBuffer>(renderingResourceIdentifier, m_imageBufferCount);
}
bool removeNativeImage(QualifiedRenderingResourceIdentifier renderingResourceIdentifier)
{
return remove<WebCore::NativeImage>(renderingResourceIdentifier, m_nativeImageCount);
}
bool removeFont(QualifiedRenderingResourceIdentifier renderingResourceIdentifier)
{
return remove<WebCore::Font>(renderingResourceIdentifier, m_fontCount);
}
bool removeDecomposedGlyphs(QualifiedRenderingResourceIdentifier renderingResourceIdentifier)
{
return remove<WebCore::DecomposedGlyphs>(renderingResourceIdentifier, m_decomposedGlyphsCount);
}
void deleteAllFonts()
{
checkInvariants();
if (!m_fontCount)
return;
m_resources.removeIf([] (const auto& resource) {
return std::holds_alternative<Ref<WebCore::Font>>(resource.value);
});
m_fontCount = 0;
checkInvariants();
}
private:
template <typename T>
void add(QualifiedRenderingResourceIdentifier renderingResourceIdentifier, Ref<T>&& object, unsigned& counter)
{
checkInvariants();
ASSERT(renderingResourceIdentifier.processIdentifier() == m_webProcessIdentifier);
if (m_resources.add(renderingResourceIdentifier, WTFMove(object)).isNewEntry)
++counter;
checkInvariants();
}
template <typename T>
T* get(QualifiedRenderingResourceIdentifier renderingResourceIdentifier) const
{
checkInvariants();
auto iterator = m_resources.find(renderingResourceIdentifier);
if (iterator == m_resources.end())
return nullptr;
auto value = std::get_if<Ref<T>>(&iterator->value);
return value ? value->ptr() : nullptr;
}
template <typename T>
bool remove(QualifiedRenderingResourceIdentifier renderingResourceIdentifier, unsigned& counter)
{
checkInvariants();
if (!counter)
return false;
auto iterator = m_resources.find(renderingResourceIdentifier);
if (iterator == m_resources.end())
return false;
if (!std::holds_alternative<Ref<T>>(iterator->value))
return false;
auto result = m_resources.remove(iterator);
ASSERT(result);
--counter;
checkInvariants();
return result;
}
void checkInvariants() const
{
#if ASSERT_ENABLED
unsigned imageBufferCount = 0;
unsigned nativeImageCount = 0;
unsigned fontCount = 0;
unsigned decomposedGlyphsCount = 0;
for (const auto& pair : m_resources) {
WTF::switchOn(pair.value, [&] (std::monostate) {
ASSERT_NOT_REACHED();
}, [&] (const Ref<WebCore::ImageBuffer>&) {
++imageBufferCount;
}, [&] (const Ref<WebCore::NativeImage>&) {
++nativeImageCount;
}, [&] (const Ref<WebCore::Font>&) {
++fontCount;
}, [&] (const Ref<WebCore::DecomposedGlyphs>&) {
++decomposedGlyphsCount;
});
}
ASSERT(imageBufferCount == m_imageBufferCount);
ASSERT(nativeImageCount == m_nativeImageCount);
ASSERT(fontCount == m_fontCount);
ASSERT(decomposedGlyphsCount == m_decomposedGlyphsCount);
ASSERT(m_resources.size() == m_imageBufferCount + m_nativeImageCount + m_fontCount + m_decomposedGlyphsCount);
#endif
}
using Resource = std::variant<std::monostate, Ref<WebCore::ImageBuffer>, Ref<WebCore::NativeImage>, Ref<WebCore::Font>, Ref<WebCore::DecomposedGlyphs>>;
HashMap<QualifiedRenderingResourceIdentifier, Resource> m_resources;
WebCore::ProcessIdentifier m_webProcessIdentifier;
unsigned m_imageBufferCount { 0 };
unsigned m_nativeImageCount { 0 };
unsigned m_fontCount { 0 };
unsigned m_decomposedGlyphsCount { 0 };
};
} // namespace WebKit
#endif