blob: e73d22a02249f77fcfd9d9809b6f3db609448328 [file] [log] [blame]
/*
* Copyright (C) 2021 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);
}
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 });
}
WebCore::Font* getFont(WebCore::RenderingResourceIdentifier renderingResourceIdentifier) const final
{
return get<WebCore::Font>({ 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);
}
WebCore::Font* getFont(QualifiedRenderingResourceIdentifier renderingResourceIdentifier) const
{
return get<WebCore::Font>(renderingResourceIdentifier);
}
bool hasImageBuffer() const
{
checkInvariants();
return m_imageBufferCount;
}
bool hasNativeImage() const
{
checkInvariants();
return m_nativeImageCount;
}
bool hasFont() const
{
checkInvariants();
return m_fontCount;
}
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);
}
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;
ASSERT(std::holds_alternative<Ref<T>>(iterator->value));
return std::get<Ref<T>>(iterator->value).ptr();
}
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;
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;
});
}
ASSERT(imageBufferCount == m_imageBufferCount);
ASSERT(nativeImageCount == m_nativeImageCount);
ASSERT(fontCount == m_fontCount);
ASSERT(m_resources.size() == m_imageBufferCount + m_nativeImageCount + m_fontCount);
#endif
}
using Resource = std::variant<std::monostate, Ref<WebCore::ImageBuffer>, Ref<WebCore::NativeImage>, Ref<WebCore::Font>>;
HashMap<QualifiedRenderingResourceIdentifier, Resource> m_resources;
WebCore::ProcessIdentifier m_webProcessIdentifier;
unsigned m_imageBufferCount { 0 };
unsigned m_nativeImageCount { 0 };
unsigned m_fontCount { 0 };
};
} // namespace WebKit
#endif