//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// RenderTargetCache:
// The RenderTargetCache pattern is used in the D3D9, D3D11 and Vulkan back-ends. It is a
// cache of the various back-end objects (RenderTargets) associated with each Framebuffer
// attachment, be they Textures, Renderbuffers, or Surfaces. The cache is updated in Framebuffer's
// syncState method.
//

#ifndef LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_
#define LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_

#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"

namespace rx
{

template <typename RenderTargetT>
class RenderTargetCache final : angle::NonCopyable
{
  public:
    RenderTargetCache();
    ~RenderTargetCache();

    // Update all RenderTargets from the dirty bits.
    angle::Result update(const gl::Context *context,
                         const gl::FramebufferState &state,
                         const gl::Framebuffer::DirtyBits &dirtyBits);

    // Update individual RenderTargets.
    angle::Result updateReadColorRenderTarget(const gl::Context *context,
                                              const gl::FramebufferState &state);
    angle::Result updateColorRenderTarget(const gl::Context *context,
                                          const gl::FramebufferState &state,
                                          size_t colorIndex);
    angle::Result updateDepthStencilRenderTarget(const gl::Context *context,
                                                 const gl::FramebufferState &state);

    using RenderTargetArray = gl::AttachmentArray<RenderTargetT *>;

    const RenderTargetArray &getColors() const;
    RenderTargetT *getDepthStencil(bool allowFeedbackLoop) const;

    RenderTargetT *getColorDraw(const gl::FramebufferState &state, size_t colorIndex) const;
    RenderTargetT *getColorRead(const gl::FramebufferState &state) const;

  private:
    angle::Result updateCachedRenderTarget(const gl::Context *context,
                                           const gl::FramebufferAttachment *attachment,
                                           RenderTargetT **cachedRenderTarget);

    RenderTargetT *mReadRenderTarget                         = nullptr;
    gl::AttachmentArray<RenderTargetT *> mColorRenderTargets = {};
    // We only support a single Depth/Stencil RenderTarget currently.
    bool mDepthStencilFeedbackLoop           = false;
    RenderTargetT *mDepthStencilRenderTarget = nullptr;
};

template <typename RenderTargetT>
RenderTargetCache<RenderTargetT>::RenderTargetCache() = default;

template <typename RenderTargetT>
RenderTargetCache<RenderTargetT>::~RenderTargetCache() = default;

template <typename RenderTargetT>
angle::Result RenderTargetCache<RenderTargetT>::update(const gl::Context *context,
                                                       const gl::FramebufferState &state,
                                                       const gl::Framebuffer::DirtyBits &dirtyBits)
{
    for (auto dirtyBit : dirtyBits)
    {
        switch (dirtyBit)
        {
            case gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT:
            case gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT:
                ANGLE_TRY(updateDepthStencilRenderTarget(context, state));
                break;
            case gl::Framebuffer::DIRTY_BIT_READ_BUFFER:
                ANGLE_TRY(updateReadColorRenderTarget(context, state));
                break;
            case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
            case gl::Framebuffer::DIRTY_BIT_DEFAULT_WIDTH:
            case gl::Framebuffer::DIRTY_BIT_DEFAULT_HEIGHT:
            case gl::Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES:
            case gl::Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS:
                break;
            default:
            {
                static_assert(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0, "FB dirty bits");
                if (dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX)
                {
                    size_t colorIndex = static_cast<size_t>(
                        dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
                    ANGLE_TRY(updateColorRenderTarget(context, state, colorIndex));
                }
                break;
            }
        }
    }

    return angle::Result::Continue;
}

template <typename RenderTargetT>
const gl::AttachmentArray<RenderTargetT *> &RenderTargetCache<RenderTargetT>::getColors() const
{
    return mColorRenderTargets;
}

template <typename RenderTargetT>
RenderTargetT *RenderTargetCache<RenderTargetT>::getDepthStencil(bool allowFeedbackLoop) const
{
    return (allowFeedbackLoop || !mDepthStencilFeedbackLoop) ? mDepthStencilRenderTarget : nullptr;
}

template <typename RenderTargetT>
angle::Result RenderTargetCache<RenderTargetT>::updateReadColorRenderTarget(
    const gl::Context *context,
    const gl::FramebufferState &state)
{
    return updateCachedRenderTarget(context, state.getReadAttachment(), &mReadRenderTarget);
}

template <typename RenderTargetT>
angle::Result RenderTargetCache<RenderTargetT>::updateColorRenderTarget(
    const gl::Context *context,
    const gl::FramebufferState &state,
    size_t colorIndex)
{
    // If the color render target we're updating is also the read buffer, make sure we update the
    // read render target also so it's not stale.
    if (state.getReadBufferState() != GL_NONE && state.getReadIndex() == colorIndex)
    {
        ANGLE_TRY(updateReadColorRenderTarget(context, state));
    }

    return updateCachedRenderTarget(context, state.getColorAttachment(colorIndex),
                                    &mColorRenderTargets[colorIndex]);
}

template <typename RenderTargetT>
angle::Result RenderTargetCache<RenderTargetT>::updateDepthStencilRenderTarget(
    const gl::Context *context,
    const gl::FramebufferState &state)
{
    mDepthStencilFeedbackLoop = state.hasDepthStencilFeedbackLoop();
    return updateCachedRenderTarget(context, state.getDepthOrStencilAttachment(),
                                    &mDepthStencilRenderTarget);
}

template <typename RenderTargetT>
angle::Result RenderTargetCache<RenderTargetT>::updateCachedRenderTarget(
    const gl::Context *context,
    const gl::FramebufferAttachment *attachment,
    RenderTargetT **cachedRenderTarget)
{
    RenderTargetT *newRenderTarget = nullptr;
    if (attachment)
    {
        ASSERT(attachment->isAttached());
        ANGLE_TRY(attachment->getRenderTarget(context, attachment->getRenderToTextureSamples(),
                                              &newRenderTarget));
    }
    *cachedRenderTarget = newRenderTarget;
    return angle::Result::Continue;
}

template <typename RenderTargetT>
RenderTargetT *RenderTargetCache<RenderTargetT>::getColorDraw(const gl::FramebufferState &state,
                                                              size_t colorIndex) const
{
    return mColorRenderTargets[colorIndex];
}

template <typename RenderTargetT>
RenderTargetT *RenderTargetCache<RenderTargetT>::getColorRead(
    const gl::FramebufferState &state) const
{
    return mReadRenderTarget;
}

}  // namespace rx

#endif  // LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_
