1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrRenderTarget_DEFINED
9#define GrRenderTarget_DEFINED
10
11#include "GrSurface.h"
12#include "SkRect.h"
13
14class GrStencilAttachment;
15class GrRenderTargetPriv;
16
17/**
18 * GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
19 * A context's render target is set by setRenderTarget(). Render targets are
20 * created by a createTexture with the kRenderTarget_SurfaceFlag flag.
21 * Additionally, GrContext provides methods for creating GrRenderTargets
22 * that wrap externally created render targets.
23 */
24class GrRenderTarget : virtual public GrSurface {
25public:
26    SK_DECLARE_INST_COUNT(GrRenderTarget)
27
28    // GrSurface overrides
29    GrRenderTarget* asRenderTarget() override { return this; }
30    const GrRenderTarget* asRenderTarget() const  override { return this; }
31
32    // GrRenderTarget
33    /**
34     * @return true if the surface is multisampled, false otherwise
35     */
36    bool isMultisampled() const { return 0 != fDesc.fSampleCnt; }
37
38    /**
39     * @return the number of samples-per-pixel or zero if non-MSAA.
40     */
41    int numSamples() const { return fDesc.fSampleCnt; }
42
43    /**
44     * Call to indicate the multisample contents were modified such that the
45     * render target needs to be resolved before it can be used as texture. Gr
46     * tracks this for its own drawing and thus this only needs to be called
47     * when the render target has been modified outside of Gr. This has no
48     * effect on wrapped backend render targets.
49     *
50     * @param rect  a rect bounding the area needing resolve. NULL indicates
51     *              the whole RT needs resolving.
52     */
53    void flagAsNeedingResolve(const SkIRect* rect = NULL);
54
55    /**
56     * Call to override the region that needs to be resolved.
57     */
58    void overrideResolveRect(const SkIRect rect);
59
60    /**
61     * Call to indicate that GrRenderTarget was externally resolved. This may
62     * allow Gr to skip a redundant resolve step.
63     */
64    void flagAsResolved() { fResolveRect.setLargestInverted(); }
65
66    /**
67     * @return true if the GrRenderTarget requires MSAA resolving
68     */
69    bool needsResolve() const { return !fResolveRect.isEmpty(); }
70
71    /**
72     * Returns a rect bounding the region needing resolving.
73     */
74    const SkIRect& getResolveRect() const { return fResolveRect; }
75
76    /**
77     * Provide a performance hint that the render target's contents are allowed
78     * to become undefined.
79     */
80    void discard();
81
82    // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
83    // 0 in GL), or be unresolvable because the client didn't give us the
84    // resolve destination.
85    enum ResolveType {
86        kCanResolve_ResolveType,
87        kAutoResolves_ResolveType,
88        kCantResolve_ResolveType,
89    };
90    virtual ResolveType getResolveType() const = 0;
91
92    // Provides access to functions that aren't part of the public API.
93    GrRenderTargetPriv renderTargetPriv();
94    const GrRenderTargetPriv renderTargetPriv() const;
95
96protected:
97    GrRenderTarget(GrGpu* gpu, LifeCycle lifeCycle, const GrSurfaceDesc& desc)
98        : INHERITED(gpu, lifeCycle, desc)
99        , fStencilAttachment(NULL) {
100        fResolveRect.setLargestInverted();
101    }
102
103    // override of GrResource
104    void onAbandon() override;
105    void onRelease() override;
106
107private:
108    // Checked when this object is asked to attach a stencil buffer.
109    virtual bool canAttemptStencilAttachment() const = 0;
110
111    friend class GrRenderTargetPriv;
112
113    GrStencilAttachment*  fStencilAttachment;
114
115    SkIRect               fResolveRect;
116
117    typedef GrSurface INHERITED;
118};
119
120#endif
121