Coverage Report

Created: 2024-05-20 07:14

/src/skia/src/gpu/ganesh/GrRenderTargetProxy.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2016 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
#include "src/gpu/ganesh/GrRenderTargetProxy.h"
9
10
#include "include/core/SkSize.h"
11
#include "include/gpu/GpuTypes.h"
12
#include "include/gpu/GrBackendSurface.h"
13
#include "include/gpu/GrTypes.h"
14
#include "include/private/base/SkTo.h"
15
#include "src/gpu/SkBackingFit.h"
16
#include "src/gpu/ganesh/GrCaps.h"
17
#include "src/gpu/ganesh/GrGpuResourcePriv.h"
18
#include "src/gpu/ganesh/GrRenderTarget.h"
19
#include "src/gpu/ganesh/GrSurface.h"
20
#include "src/gpu/ganesh/GrSurfaceProxyPriv.h"
21
22
#include <utility>
23
24
#ifdef SK_DEBUG
25
#include "include/gpu/GrDirectContext.h"
26
#include "src/gpu/ganesh/GrDirectContextPriv.h"
27
#endif
28
29
// Deferred version
30
// TODO: we can probably munge the 'desc' in both the wrapped and deferred
31
// cases to make the sampleConfig/numSamples stuff more rational.
32
GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps,
33
                                         const GrBackendFormat& format,
34
                                         SkISize dimensions,
35
                                         int sampleCount,
36
                                         SkBackingFit fit,
37
                                         skgpu::Budgeted budgeted,
38
                                         GrProtected isProtected,
39
                                         GrInternalSurfaceFlags surfaceFlags,
40
                                         UseAllocator useAllocator,
41
                                         std::string_view label)
42
        : INHERITED(
43
                  format, dimensions, fit, budgeted, isProtected, surfaceFlags, useAllocator, label)
44
        , fSampleCnt(sampleCount)
45
84.7k
        , fWrapsVkSecondaryCB(WrapsVkSecondaryCB::kNo) {}
GrRenderTargetProxy::GrRenderTargetProxy(GrCaps const&, GrBackendFormat const&, SkISize, int, SkBackingFit, skgpu::Budgeted, skgpu::Protected, GrInternalSurfaceFlags, GrSurfaceProxy::UseAllocator, std::__1::basic_string_view<char, std::__1::char_traits<char> >)
Line
Count
Source
45
84.7k
        , fWrapsVkSecondaryCB(WrapsVkSecondaryCB::kNo) {}
Unexecuted instantiation: GrRenderTargetProxy::GrRenderTargetProxy(GrCaps const&, GrBackendFormat const&, SkISize, int, SkBackingFit, skgpu::Budgeted, skgpu::Protected, GrInternalSurfaceFlags, GrSurfaceProxy::UseAllocator, std::__1::basic_string_view<char, std::__1::char_traits<char> >)
46
47
// Lazy-callback version
48
GrRenderTargetProxy::GrRenderTargetProxy(LazyInstantiateCallback&& callback,
49
                                         const GrBackendFormat& format,
50
                                         SkISize dimensions,
51
                                         int sampleCount,
52
                                         SkBackingFit fit,
53
                                         skgpu::Budgeted budgeted,
54
                                         GrProtected isProtected,
55
                                         GrInternalSurfaceFlags surfaceFlags,
56
                                         UseAllocator useAllocator,
57
                                         WrapsVkSecondaryCB wrapsVkSecondaryCB,
58
                                         std::string_view label)
59
        : INHERITED(std::move(callback),
60
                    format,
61
                    dimensions,
62
                    fit,
63
                    budgeted,
64
                    isProtected,
65
                    surfaceFlags,
66
                    useAllocator,
67
                    label)
68
        , fSampleCnt(sampleCount)
69
285
        , fWrapsVkSecondaryCB(wrapsVkSecondaryCB) {}
GrRenderTargetProxy::GrRenderTargetProxy(std::__1::function<GrSurfaceProxy::LazyCallbackResult (GrResourceProvider*, GrSurfaceProxy::LazySurfaceDesc const&)>&&, GrBackendFormat const&, SkISize, int, SkBackingFit, skgpu::Budgeted, skgpu::Protected, GrInternalSurfaceFlags, GrSurfaceProxy::UseAllocator, GrRenderTargetProxy::WrapsVkSecondaryCB, std::__1::basic_string_view<char, std::__1::char_traits<char> >)
Line
Count
Source
69
285
        , fWrapsVkSecondaryCB(wrapsVkSecondaryCB) {}
Unexecuted instantiation: GrRenderTargetProxy::GrRenderTargetProxy(std::__1::function<GrSurfaceProxy::LazyCallbackResult (GrResourceProvider*, GrSurfaceProxy::LazySurfaceDesc const&)>&&, GrBackendFormat const&, SkISize, int, SkBackingFit, skgpu::Budgeted, skgpu::Protected, GrInternalSurfaceFlags, GrSurfaceProxy::UseAllocator, GrRenderTargetProxy::WrapsVkSecondaryCB, std::__1::basic_string_view<char, std::__1::char_traits<char> >)
70
71
// Wrapped version
72
GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface> surf,
73
                                         UseAllocator useAllocator,
74
                                         WrapsVkSecondaryCB wrapsVkSecondaryCB)
75
        : INHERITED(std::move(surf), SkBackingFit::kExact, useAllocator)
76
        , fSampleCnt(fTarget->asRenderTarget()->numSamples())
77
0
        , fWrapsVkSecondaryCB(wrapsVkSecondaryCB) {
78
    // The kRequiresManualMSAAResolve flag better not be set if we are not multisampled or if
79
    // MSAA resolve should happen automatically.
80
    //
81
    // From the other side, we don't know enough about the wrapped surface to assert when
82
    // kRequiresManualMSAAResolve *should* be set. e.g., The caller might be wrapping a backend
83
    // texture as a render target at this point but we wouldn't know it.
84
0
    SkASSERT(!(this->numSamples() <= 1 ||
85
0
               fTarget->getContext()->priv().caps()->msaaResolvesAutomatically()) ||
86
0
             !this->requiresManualMSAAResolve());
87
0
}
Unexecuted instantiation: GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceProxy::UseAllocator, GrRenderTargetProxy::WrapsVkSecondaryCB)
Unexecuted instantiation: GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceProxy::UseAllocator, GrRenderTargetProxy::WrapsVkSecondaryCB)
Unexecuted instantiation: GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceProxy::UseAllocator, GrRenderTargetProxy::WrapsVkSecondaryCB)
Unexecuted instantiation: GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceProxy::UseAllocator, GrRenderTargetProxy::WrapsVkSecondaryCB)
88
89
9.78k
int GrRenderTargetProxy::maxWindowRectangles(const GrCaps& caps) const {
90
9.78k
    return this->glRTFBOIDIs0() ? 0 : caps.maxWindowRectangles();
91
9.78k
}
92
93
0
bool GrRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) {
94
0
    if (this->isLazy()) {
95
0
        return false;
96
0
    }
97
0
    if (!this->instantiateImpl(resourceProvider, fSampleCnt, GrRenderable::kYes,
98
0
                               skgpu::Mipmapped::kNo, nullptr)) {
99
0
        return false;
100
0
    }
101
102
0
    SkASSERT(this->peekRenderTarget());
103
0
    SkASSERT(!this->peekTexture());
104
0
    return true;
105
0
}
Unexecuted instantiation: GrRenderTargetProxy::instantiate(GrResourceProvider*)
Unexecuted instantiation: GrRenderTargetProxy::instantiate(GrResourceProvider*)
106
107
13.7k
bool GrRenderTargetProxy::canUseStencil(const GrCaps& caps) const {
108
13.7k
    if (caps.avoidStencilBuffers() || this->wrapsVkSecondaryCB()) {
109
0
        return false;
110
0
    }
111
13.7k
    if (!this->isInstantiated()) {
112
13.2k
        if (this->isLazy() && this->backendFormat().backend() == GrBackendApi::kOpenGL) {
113
            // It's possible for wrapped GL render targets to not have stencil. We don't currently
114
            // have an exact way of knowing whether the target will be able to use stencil, so we do
115
            // the best we can: if a lazy GL proxy doesn't have a texture, then it might be a
116
            // wrapped target without stencil, so we conservatively block stencil.
117
            // FIXME: skbug.com/11943: GrSurfaceCharacterization needs a "canUseStencil" flag.
118
0
            return SkToBool(this->asTextureProxy());
119
13.2k
        } else {
120
            // Otherwise the target will definitely not be wrapped. Ganesh is free to attach
121
            // stencils on internal render targets.
122
13.2k
            return true;
123
13.2k
        }
124
13.2k
    }
125
    // Just ask the actual target if we can use stencil.
126
489
    GrRenderTarget* rt = this->peekRenderTarget();
127
    // The dmsaa attachment (if any) always supports stencil. The real question is whether the
128
    // non-dmsaa attachment supports stencil.
129
489
    bool useMSAASurface = rt->numSamples() > 1;
130
489
    return rt->getStencilAttachment(useMSAASurface) ||
131
489
           rt->canAttemptStencilAttachment(useMSAASurface);
132
13.7k
}
133
134
0
sk_sp<GrSurface> GrRenderTargetProxy::createSurface(GrResourceProvider* resourceProvider) const {
135
0
    sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, fSampleCnt,
136
0
                                                       GrRenderable::kYes, skgpu::Mipmapped::kNo);
137
0
    if (!surface) {
138
0
        return nullptr;
139
0
    }
140
0
    SkASSERT(surface->asRenderTarget());
141
0
    SkASSERT(!surface->asTexture());
142
0
    return surface;
143
0
}
Unexecuted instantiation: GrRenderTargetProxy::createSurface(GrResourceProvider*) const
Unexecuted instantiation: GrRenderTargetProxy::createSurface(GrResourceProvider*) const
144
145
0
size_t GrRenderTargetProxy::onUninstantiatedGpuMemorySize() const {
146
0
    int colorSamplesPerPixel = this->numSamples();
147
0
    if (colorSamplesPerPixel > 1) {
148
        // Add one for the resolve buffer.
149
0
        ++colorSamplesPerPixel;
150
0
    }
151
152
    // TODO: do we have enough information to improve this worst case estimate?
153
0
    return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
154
0
                                  colorSamplesPerPixel, skgpu::Mipmapped::kNo,
155
0
                                  !this->priv().isExact());
156
0
}
157
158
29
bool GrRenderTargetProxy::refsWrappedObjects() const {
159
29
    if (!this->isInstantiated()) {
160
29
        return false;
161
29
    }
162
163
0
    GrSurface* surface = this->peekSurface();
164
0
    return surface->resourcePriv().refsWrappedObjects();
165
29
}
166
167
0
GrSurfaceProxy::LazySurfaceDesc GrRenderTargetProxy::callbackDesc() const {
168
    // We only expect exactly sized lazy RT proxies.
169
0
    SkASSERT(!this->isFullyLazy());
170
0
    SkASSERT(this->isFunctionallyExact());
171
0
    return {
172
0
            this->dimensions(),
173
0
            SkBackingFit::kExact,
174
0
            GrRenderable::kYes,
175
0
            skgpu::Mipmapped::kNo,
176
0
            this->numSamples(),
177
0
            this->backendFormat(),
178
0
            GrTextureType::kNone,
179
0
            this->isProtected(),
180
0
            this->isBudgeted(),
181
0
            this->getLabel(),
182
0
    };
183
0
}
Unexecuted instantiation: GrRenderTargetProxy::callbackDesc() const
Unexecuted instantiation: GrRenderTargetProxy::callbackDesc() const
184
185
#ifdef SK_DEBUG
186
0
void GrRenderTargetProxy::onValidateSurface(const GrSurface* surface) {
187
    // We do not check that surface->asTexture returns null since, when replaying DDLs we
188
    // can fulfill a renderTarget-only proxy w/ a textureRenderTarget.
189
190
    // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version
191
0
    SkASSERT(surface->asRenderTarget());
192
0
    SkASSERT(surface->asRenderTarget()->numSamples() == this->numSamples());
193
194
0
    GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
195
0
    GrInternalSurfaceFlags surfaceFlags = surface->flags();
196
0
    if (proxyFlags & GrInternalSurfaceFlags::kGLRTFBOIDIs0 && this->numSamples() == 1) {
197
        // Ganesh never internally creates FBO0 proxies or surfaces so this must be a wrapped
198
        // proxy. In this case, with no MSAA, rendering to FBO0 is strictly more limited than
199
        // rendering to an arbitrary surface so we allow a non-FBO0 surface to be matched with
200
        // the proxy.
201
0
        surfaceFlags |= GrInternalSurfaceFlags::kGLRTFBOIDIs0;
202
0
    }
203
0
    SkASSERT(((int)proxyFlags & kGrInternalRenderTargetFlagsMask) ==
204
0
             ((int)surfaceFlags & kGrInternalRenderTargetFlagsMask));
205
206
    // We manually check the kVkRTSupportsInputAttachment since we only require it on the surface if
207
    // the proxy has it set. If the proxy doesn't have the flag it is legal for the surface to
208
    // have the flag.
209
0
    if (proxyFlags & GrInternalSurfaceFlags::kVkRTSupportsInputAttachment) {
210
0
        SkASSERT(surfaceFlags & GrInternalSurfaceFlags::kVkRTSupportsInputAttachment);
211
0
    }
212
0
}
213
#endif