Edit

kc3-lang/angle/src/libANGLE/renderer/RenderTargetCache.h

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2018-04-27 11:45:04
    Hash : 57d9cbb6
    Message : Sync individual attachments in RenderTargetCache. This allows Framebuffer syncState methods to handle dirty bits themselves. This will be useful for the implementation of masked color clear. Bug: angleproject:2455 Change-Id: I65ad9c61e89e317c820f6be5550edd8185b52afc Reviewed-on: https://chromium-review.googlesource.com/1032856 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Luc Ferron <lucferron@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org>

  • src/libANGLE/renderer/RenderTargetCache.h
  • //
    // 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.
        gl::Error update(const gl::Context *context,
                         const gl::FramebufferState &state,
                         const gl::Framebuffer::DirtyBits &dirtyBits);
    
        // Update individual RenderTargets.
        gl::Error updateColorRenderTarget(const gl::Context *context,
                                          const gl::FramebufferState &state,
                                          size_t colorIndex);
        gl::Error updateDepthStencilRenderTarget(const gl::Context *context,
                                                 const gl::FramebufferState &state);
    
        using RenderTargetArray = gl::AttachmentArray<RenderTargetT *>;
    
        const RenderTargetArray &getColors() const;
        RenderTargetT *getDepthStencil() const;
    
        RenderTargetT *getColorRead(const gl::FramebufferState &state) const;
    
      private:
        gl::Error updateCachedRenderTarget(const gl::Context *context,
                                           const gl::FramebufferAttachment *attachment,
                                           RenderTargetT **cachedRenderTarget);
    
        gl::AttachmentArray<RenderTargetT *> mColorRenderTargets;
        // We only support a single Depth/Stencil RenderTarget currently.
        RenderTargetT *mDepthStencilRenderTarget;
    };
    
    template <typename RenderTargetT>
    RenderTargetCache<RenderTargetT>::RenderTargetCache()
        : mColorRenderTargets{{nullptr}}, mDepthStencilRenderTarget(nullptr)
    {
    }
    
    template <typename RenderTargetT>
    RenderTargetCache<RenderTargetT>::~RenderTargetCache()
    {
    }
    
    template <typename RenderTargetT>
    gl::Error 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_DRAW_BUFFERS:
                case gl::Framebuffer::DIRTY_BIT_READ_BUFFER:
                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:
                {
                    ASSERT(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 &&
                           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 gl::NoError();
    }
    
    template <typename RenderTargetT>
    const gl::AttachmentArray<RenderTargetT *> &RenderTargetCache<RenderTargetT>::getColors() const
    {
        return mColorRenderTargets;
    }
    
    template <typename RenderTargetT>
    RenderTargetT *RenderTargetCache<RenderTargetT>::getDepthStencil() const
    {
        return mDepthStencilRenderTarget;
    }
    
    template <typename RenderTargetT>
    gl::Error RenderTargetCache<RenderTargetT>::updateColorRenderTarget(
        const gl::Context *context,
        const gl::FramebufferState &state,
        size_t colorIndex)
    {
        return updateCachedRenderTarget(context, state.getColorAttachment(colorIndex),
                                        &mColorRenderTargets[colorIndex]);
    }
    
    template <typename RenderTargetT>
    gl::Error RenderTargetCache<RenderTargetT>::updateDepthStencilRenderTarget(
        const gl::Context *context,
        const gl::FramebufferState &state)
    {
        return updateCachedRenderTarget(context, state.getDepthOrStencilAttachment(),
                                        &mDepthStencilRenderTarget);
    }
    
    template <typename RenderTargetT>
    gl::Error 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, &newRenderTarget));
        }
        *cachedRenderTarget = newRenderTarget;
        return gl::NoError();
    }
    
    template <typename RenderTargetT>
    RenderTargetT *RenderTargetCache<RenderTargetT>::getColorRead(
        const gl::FramebufferState &state) const
    {
        ASSERT(mColorRenderTargets[state.getReadIndex()] &&
               state.getReadIndex() < mColorRenderTargets.size());
        return mColorRenderTargets[state.getReadIndex()];
    }
    
    }  // namespace rx
    
    #endif  // LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_