aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl/GrGLRenderTarget.h
blob: b298676a47847bdd48dc91c3db1de583f53dd1c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * 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 GrGLRenderTarget_DEFINED
#define GrGLRenderTarget_DEFINED

#include "GrGpu.h"
#include "GrGLIRect.h"
#include "GrRenderTarget.h"
#include "SkScalar.h"

class GrGLGpu;
class GrGLStencilAttachment;

class GrGLRenderTarget : public GrRenderTarget {
public:
    // set fTexFBOID to this value to indicate that it is multisampled but
    // Gr doesn't know how to resolve it.
    enum { kUnresolvableFBOID = 0 };

    struct IDDesc {
        GrGLuint                     fRTFBOID;
        GrGLuint                     fTexFBOID;
        GrGLuint                     fMSColorRenderbufferID;
        GrGpuResource::LifeCycle     fLifeCycle;
        GrRenderTarget::SampleConfig fSampleConfig;
    };

    static GrGLRenderTarget* CreateWrapped(GrGLGpu*,
                                           const GrSurfaceDesc&,
                                           const IDDesc&,
                                           int stencilBits);

    void setViewport(const GrGLIRect& rect) { fViewport = rect; }
    const GrGLIRect& getViewport() const { return fViewport; }

    // The following two functions return the same ID when a
    // texture/render target is multisampled, and different IDs when
    // it is.
    // FBO ID used to render into
    GrGLuint renderFBOID() const { return fRTFBOID; }
    // FBO ID that has texture ID attached.
    GrGLuint textureFBOID() const { return fTexFBOID; }

    // override of GrRenderTarget
    ResolveType getResolveType() const override {
        if (!this->isUnifiedMultisampled() ||
            fRTFBOID == fTexFBOID) {
            // catches FBO 0 and non MSAA case
            return kAutoResolves_ResolveType;
        } else if (kUnresolvableFBOID == fTexFBOID) {
            return kCantResolve_ResolveType;
        } else {
            return kCanResolve_ResolveType;
        }
    }

    GrBackendObject getRenderTargetHandle() const override { return fRTFBOID; }

    /** When we don't own the FBO ID we don't attempt to modify its attachments. */
    bool canAttemptStencilAttachment() const override {
        return kCached_LifeCycle == fRTLifecycle || kUncached_LifeCycle == fRTLifecycle;
    }

    // GrGLRenderTarget overrides dumpMemoryStatistics so it can log its texture and renderbuffer
    // components seperately.
    void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const override;

    bool getCachedCoCenteredSamplesState(GrGpu::ResetTimestamp* stamp) const {
        *stamp = fHasCoCenteredSamplesTimestamp;
        return fHasCoCenteredSamples;
    }

    void setCachedCoCenteredSamplesState(bool hasCoCenteredSamples, GrGpu::ResetTimestamp stamp) {
        fHasCoCenteredSamples = hasCoCenteredSamples;
        fHasCoCenteredSamplesTimestamp = stamp;
    }

protected:
    // The public constructor registers this object with the cache. However, only the most derived
    // class should register with the cache. This constructor does not do the registration and
    // rather moves that burden onto the derived class.
    enum Derived { kDerived };
    GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, Derived);

    void init(const GrSurfaceDesc&, const IDDesc&);

    void onAbandon() override;
    void onRelease() override;

    // In protected because subclass GrGLTextureRenderTarget calls this version.
    size_t onGpuMemorySize() const override;

private:
    // This ctor is used only for creating wrapped render targets and is only called for the static
    // create function CreateWrapped(...).
    GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, GrGLStencilAttachment*);

    GrGLGpu* getGLGpu() const;
    bool completeStencilAttachment() override;

    // The total size of the resource (including all pixels) for a single sample.
    size_t totalBytesPerSample() const;
    int msaaSamples() const;
    // The number total number of samples, including both MSAA and resolve texture samples.
    int totalSamples() const;

    GrGLuint                fRTFBOID;
    GrGLuint                fTexFBOID;
    GrGLuint                fMSColorRenderbufferID;
    bool                    fHasCoCenteredSamples;
    GrGpu::ResetTimestamp   fHasCoCenteredSamplesTimestamp;

    // We track this separately from GrGpuResource because this may be both a texture and a render
    // target, and the texture may be wrapped while the render target is not.
    LifeCycle               fRTLifecycle;

    // when we switch to this render target we want to set the viewport to
    // only render to content area (as opposed to the whole allocation) and
    // we want the rendering to be at top left (GL has origin in bottom left)
    GrGLIRect               fViewport;

    // onGpuMemorySize() needs to know the VRAM footprint of the FBO(s). However, abandon and
    // release zero out the IDs and the cache needs to know the size even after those actions.
    size_t                  fGpuMemorySize;

    typedef GrRenderTarget INHERITED;
};

#endif