/*
 * Copyright (C) 2016-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. 
 */

#include "config.h"
#include "DisplayListReplayer.h"

#include "DisplayListItems.h"
#include "DisplayListIterator.h"
#include "DisplayListResourceHeap.h"
#include "GraphicsContext.h"
#include "InMemoryDisplayList.h"
#include "Logging.h"
#include <wtf/text/TextStream.h>

namespace WebCore {
namespace DisplayList {

Replayer::Replayer(GraphicsContext& context, const DisplayList& displayList, const ResourceHeap* resourceHeap, ImageBuffer* maskImageBuffer, Delegate* delegate)
    : m_context(context)
    , m_maskImageBuffer(maskImageBuffer)
    , m_displayList(displayList)
    , m_resourceHeap(resourceHeap ? *resourceHeap : m_displayList.resourceHeap())
    , m_delegate(delegate)
{
}

Replayer::~Replayer() = default;

GraphicsContext& Replayer::context() const
{
    return m_maskImageBuffer ? m_maskImageBuffer->context() : m_context;
}

template<class T>
inline static std::optional<RenderingResourceIdentifier> applyImageBufferItem(GraphicsContext& context, const ResourceHeap& resourceHeap, ItemHandle item, Replayer::Delegate* delegate)
{
    auto& imageBufferItem = item.get<T>();
    auto resourceIdentifier = imageBufferItem.imageBufferIdentifier();
    if (auto* imageBuffer = resourceHeap.getImageBuffer(resourceIdentifier)) {
        imageBufferItem.apply(context, *imageBuffer);
        if (delegate)
            delegate->recordResourceUse(resourceIdentifier);
        return std::nullopt;
    }
    return resourceIdentifier;
}

template<class T>
inline static std::optional<RenderingResourceIdentifier> applyNativeImageItem(GraphicsContext& context, const ResourceHeap& resourceHeap, ItemHandle item, Replayer::Delegate* delegate)
{
    auto& nativeImageItem = item.get<T>();
    auto resourceIdentifier = nativeImageItem.imageIdentifier();
    if (auto* image = resourceHeap.getNativeImage(resourceIdentifier)) {
        nativeImageItem.apply(context, *image);
        if (delegate)
            delegate->recordResourceUse(resourceIdentifier);
        return std::nullopt;
    }
    return resourceIdentifier;
}

inline static std::optional<RenderingResourceIdentifier> applySetStateItem(GraphicsContext& context, const ResourceHeap& resourceHeap, ItemHandle item, Replayer::Delegate* delegate)
{
    auto& setStateItem = item.get<SetState>();

    RenderingResourceIdentifier strokePatternRenderingResourceIdentifier;
    NativeImage* strokePatternImage = nullptr;
    RenderingResourceIdentifier fillPatternRenderingResourceIdentifier;
    NativeImage* fillPatternImage = nullptr;

    if ((strokePatternRenderingResourceIdentifier = setStateItem.strokePatternImageIdentifier())) {
        strokePatternImage = resourceHeap.getNativeImage(strokePatternRenderingResourceIdentifier);
        if (!strokePatternImage)
            return strokePatternRenderingResourceIdentifier;
    }

    if ((fillPatternRenderingResourceIdentifier = setStateItem.fillPatternImageIdentifier())) {
        fillPatternImage = resourceHeap.getNativeImage(fillPatternRenderingResourceIdentifier);
        if (!fillPatternImage)
            return fillPatternRenderingResourceIdentifier;
    }

    setStateItem.apply(context, strokePatternImage, fillPatternImage);

    if (!delegate)
        return std::nullopt;

    if (strokePatternRenderingResourceIdentifier)
        delegate->recordResourceUse(strokePatternRenderingResourceIdentifier);
    if (fillPatternRenderingResourceIdentifier)
        delegate->recordResourceUse(fillPatternRenderingResourceIdentifier);
    return std::nullopt;
}

template<class T>
inline static std::optional<RenderingResourceIdentifier> applyFontItem(GraphicsContext& context, const ResourceHeap& resourceHeap, ItemHandle item, Replayer::Delegate* delegate)
{
    auto& fontItem = item.get<T>();
    auto resourceIdentifier = fontItem.fontIdentifier();
    if (auto* font = resourceHeap.getFont(resourceIdentifier)) {
        fontItem.apply(context, *font);
        if (delegate)
            delegate->recordResourceUse(resourceIdentifier);
        return std::nullopt;
    }
    return resourceIdentifier;
}

std::pair<std::optional<StopReplayReason>, std::optional<RenderingResourceIdentifier>> Replayer::applyItem(ItemHandle item)
{
    if (m_delegate && m_delegate->apply(item, context()))
        return { std::nullopt, std::nullopt };

    if (item.is<DrawImageBuffer>()) {
        if (auto missingCachedResourceIdentifier = applyImageBufferItem<DrawImageBuffer>(context(), m_resourceHeap, item, m_delegate))
            return { StopReplayReason::MissingCachedResource, WTFMove(missingCachedResourceIdentifier) };
        return { std::nullopt, std::nullopt };
    }

    if (item.is<ClipToImageBuffer>()) {
        if (auto missingCachedResourceIdentifier = applyImageBufferItem<ClipToImageBuffer>(context(), m_resourceHeap, item, m_delegate))
            return { StopReplayReason::MissingCachedResource, WTFMove(missingCachedResourceIdentifier) };
        return { std::nullopt, std::nullopt };
    }

    if (item.is<DrawNativeImage>()) {
        if (auto missingCachedResourceIdentifier = applyNativeImageItem<DrawNativeImage>(context(), m_resourceHeap, item, m_delegate))
            return { StopReplayReason::MissingCachedResource, WTFMove(missingCachedResourceIdentifier) };
        return { std::nullopt, std::nullopt };
    }

    if (item.is<DrawGlyphs>()) {
        if (auto missingCachedResourceIdentifier = applyFontItem<DrawGlyphs>(context(), m_resourceHeap, item, m_delegate))
            return { StopReplayReason::MissingCachedResource, WTFMove(missingCachedResourceIdentifier) };
        return { std::nullopt, std::nullopt };
    }

    if (item.is<DrawPattern>()) {
        if (auto missingCachedResourceIdentifier = applyNativeImageItem<DrawPattern>(context(), m_resourceHeap, item, m_delegate))
            return { StopReplayReason::MissingCachedResource, WTFMove(missingCachedResourceIdentifier) };
        return { std::nullopt, std::nullopt };
    }

    if (item.is<SetState>()) {
        if (auto missingCachedResourceIdentifier = applySetStateItem(context(), m_resourceHeap, item, m_delegate))
            return { StopReplayReason::MissingCachedResource, WTFMove(missingCachedResourceIdentifier) };
        return { std::nullopt, std::nullopt };
    }

    if (item.is<BeginClipToDrawingCommands>()) {
        if (m_maskImageBuffer)
            return { StopReplayReason::InvalidItemOrExtent, std::nullopt };
        auto& clipItem = item.get<BeginClipToDrawingCommands>();
        m_maskImageBuffer = ImageBuffer::createCompatibleBuffer(clipItem.destination().size(), clipItem.colorSpace(), m_context);
        if (!m_maskImageBuffer)
            return { StopReplayReason::OutOfMemory, std::nullopt };
        if (m_delegate)
            m_delegate->didCreateMaskImageBuffer(*m_maskImageBuffer);
        return { std::nullopt, std::nullopt };
    }

    if (item.is<EndClipToDrawingCommands>()) {
        if (!m_maskImageBuffer)
            return { StopReplayReason::InvalidItemOrExtent, std::nullopt };
        auto& clipItem = item.get<EndClipToDrawingCommands>();
        m_context.clipToImageBuffer(*m_maskImageBuffer, clipItem.destination());
        m_maskImageBuffer = nullptr;
        if (m_delegate)
            m_delegate->didResetMaskImageBuffer();
        return { std::nullopt, std::nullopt };
    }

    item.apply(context());
    return { std::nullopt, std::nullopt };
}

ReplayResult Replayer::replay(const FloatRect& initialClip, bool trackReplayList)
{
    LOG_WITH_STREAM(DisplayLists, stream << "\nReplaying with clip " << initialClip);
    UNUSED_PARAM(initialClip);

    std::unique_ptr<InMemoryDisplayList> replayList;
    if (UNLIKELY(trackReplayList))
        replayList = makeUnique<InMemoryDisplayList>();

#if !LOG_DISABLED
    size_t i = 0;
#endif
    ReplayResult result;
    for (auto displayListItem : m_displayList) {
        if (!displayListItem) {
            result.reasonForStopping = StopReplayReason::InvalidItemOrExtent;
            break;
        }

        auto [item, extent, itemSizeInBuffer] = displayListItem.value();

        if (!initialClip.isZero() && extent && !extent->intersects(initialClip)) {
            LOG_WITH_STREAM(DisplayLists, stream << "skipping " << i++ << " " << item);
            result.numberOfBytesRead += itemSizeInBuffer;
            continue;
        }

        LOG_WITH_STREAM(DisplayLists, stream << "applying " << i++ << " " << item);

        if (auto [reasonForStopping, missingCachedResourceIdentifier] = applyItem(item); reasonForStopping) {
            result.reasonForStopping = *reasonForStopping;
            result.missingCachedResourceIdentifier = WTFMove(missingCachedResourceIdentifier);
            break;
        }

        result.numberOfBytesRead += itemSizeInBuffer;

        if (UNLIKELY(trackReplayList)) {
            replayList->append(item);
            if (item.isDrawingItem())
                replayList->addDrawingItemExtent(WTFMove(extent));
        }
    }

    result.trackedDisplayList = WTFMove(replayList);
    return result;
}

} // namespace DisplayList
} // namespace WebCore
