/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrRenderTarget_DEFINED
#define GrRenderTarget_DEFINED

#include "GrSurface.h"
#include "SkRect.h"

class GrCaps;
class GrDrawTarget;
class GrStencilAttachment;
class GrRenderTargetPriv;

/**
 * GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
 * A context's render target is set by setRenderTarget(). Render targets are
 * created by a createTexture with the kRenderTarget_SurfaceFlag flag.
 * Additionally, GrContext provides methods for creating GrRenderTargets
 * that wrap externally created render targets.
 */
class GrRenderTarget : virtual public GrSurface {
public:
    // GrSurface overrides
    GrRenderTarget* asRenderTarget() override { return this; }
    const GrRenderTarget* asRenderTarget() const  override { return this; }

    // GrRenderTarget
    /**
     * On some hardware it is possible for a render target to have multisampling
     * only in certain buffers.
     * Enforce only two legal sample configs.
     * kUnified_SampleConfig signifies multisampling in both color and stencil
     * buffers and is available across all hardware.
     * kStencil_SampleConfig means multisampling is present in stencil buffer
     * only; this config requires hardware support of
     * NV_framebuffer_mixed_samples.
    */
    enum SampleConfig {
        kUnified_SampleConfig = 0,
        kStencil_SampleConfig = 1
    };

    /**
     * @return true if the surface is multisampled in all buffers,
     *         false otherwise
     */
    bool isUnifiedMultisampled() const {
        if (fSampleConfig != kUnified_SampleConfig) {
            return false;
        }
        return 0 != fDesc.fSampleCnt;
    }

    /**
     * @return true if the surface is multisampled in the stencil buffer,
     *         false otherwise
     */
    bool isStencilBufferMultisampled() const {
        return 0 != fDesc.fSampleCnt;
    }

    /**
     * @return the number of color samples-per-pixel, or zero if non-MSAA or
     *         multisampled in the stencil buffer only.
     */
    int numColorSamples() const {
        if (fSampleConfig == kUnified_SampleConfig) {
            return fDesc.fSampleCnt;
        }
        return 0;
    }

    /**
     * @return the number of stencil samples-per-pixel, or zero if non-MSAA.
     */
    int numStencilSamples() const {
        return fDesc.fSampleCnt;
    }

    /**
     * @return true if the surface is mixed sampled, false otherwise.
     */
    bool hasMixedSamples() const {
        SkASSERT(kStencil_SampleConfig != fSampleConfig ||
                 this->isStencilBufferMultisampled());
        return kStencil_SampleConfig == fSampleConfig;
    }

    /**
     * Call to indicate the multisample contents were modified such that the
     * render target needs to be resolved before it can be used as texture. Gr
     * tracks this for its own drawing and thus this only needs to be called
     * when the render target has been modified outside of Gr. This has no
     * effect on wrapped backend render targets.
     *
     * @param rect  a rect bounding the area needing resolve. NULL indicates
     *              the whole RT needs resolving.
     */
    void flagAsNeedingResolve(const SkIRect* rect = NULL);

    /**
     * Call to override the region that needs to be resolved.
     */
    void overrideResolveRect(const SkIRect rect);

    /**
     * Call to indicate that GrRenderTarget was externally resolved. This may
     * allow Gr to skip a redundant resolve step.
     */
    void flagAsResolved() { fResolveRect.setLargestInverted(); }

    /**
     * @return true if the GrRenderTarget requires MSAA resolving
     */
    bool needsResolve() const { return !fResolveRect.isEmpty(); }

    /**
     * Returns a rect bounding the region needing resolving.
     */
    const SkIRect& getResolveRect() const { return fResolveRect; }

    /**
     * Provide a performance hint that the render target's contents are allowed
     * to become undefined.
     */
    void discard();

    // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
    // 0 in GL), or be unresolvable because the client didn't give us the
    // resolve destination.
    enum ResolveType {
        kCanResolve_ResolveType,
        kAutoResolves_ResolveType,
        kCantResolve_ResolveType,
    };
    virtual ResolveType getResolveType() const = 0;

    /**
     *  Return the native ID or handle to the rendertarget, depending on the
     *  platform. e.g. on OpenGL, return the FBO ID.
     */
    virtual GrBackendObject getRenderTargetHandle() const = 0;

    // Checked when this object is asked to attach a stencil buffer.
    virtual bool canAttemptStencilAttachment() const = 0;

    // Provides access to functions that aren't part of the public API.
    GrRenderTargetPriv renderTargetPriv();
    const GrRenderTargetPriv renderTargetPriv() const;

    void setLastDrawTarget(GrDrawTarget* dt);
    GrDrawTarget* getLastDrawTarget() { return fLastDrawTarget; }

    static SampleConfig ComputeSampleConfig(const GrCaps& caps, int sampleCnt);

protected:
    GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc,
                   SampleConfig sampleConfig, GrStencilAttachment* stencil = nullptr)
        : INHERITED(gpu, desc)
        , fStencilAttachment(stencil)
        , fMultisampleSpecsID(0)
        , fSampleConfig(sampleConfig)
        , fLastDrawTarget(nullptr) {
        fResolveRect.setLargestInverted();
    }

    ~GrRenderTarget() override;

    // override of GrResource
    void onAbandon() override;
    void onRelease() override;

private:
    // Allows the backends to perform any additional work that is required for attaching a
    // GrStencilAttachment. When this is called, the GrStencilAttachment has already been put onto
    // the GrRenderTarget. This function must return false if any failures occur when completing the
    // stencil attachment.
    virtual bool completeStencilAttachment() = 0;

    friend class GrRenderTargetPriv;

    GrStencilAttachment*  fStencilAttachment;
    uint8_t               fMultisampleSpecsID;
    SampleConfig          fSampleConfig;

    SkIRect               fResolveRect;

    // The last drawTarget that wrote to or is currently going to write to this renderTarget
    // The drawTarget can be closed (e.g., no draw context is currently bound
    // to this renderTarget).
    // This back-pointer is required so that we can add a dependancy between
    // the drawTarget used to create the current contents of this renderTarget
    // and the drawTarget of a destination renderTarget to which this one is being drawn.
    GrDrawTarget* fLastDrawTarget;

    typedef GrSurface INHERITED;
};


#endif
