Coverage Report

Created: 2024-05-20 07:14

/src/skia/src/gpu/ganesh/SurfaceContext.h
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
#ifndef SurfaceContext_DEFINED
9
#define SurfaceContext_DEFINED
10
11
#include "include/core/SkImage.h"
12
#include "include/core/SkRect.h"
13
#include "include/core/SkRefCnt.h"
14
#include "include/core/SkSamplingOptions.h"
15
#include "include/core/SkSurface.h"
16
#include "src/gpu/ganesh/GrColorInfo.h"
17
#include "src/gpu/ganesh/GrDataUtils.h"
18
#include "src/gpu/ganesh/GrImageInfo.h"
19
#include "src/gpu/ganesh/GrPixmap.h"
20
#include "src/gpu/ganesh/GrRenderTargetProxy.h"
21
#include "src/gpu/ganesh/GrRenderTask.h"
22
#include "src/gpu/ganesh/GrSurfaceProxy.h"
23
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
24
25
class GrDrawingManager;
26
class GrRecordingContext;
27
class GrRenderTargetProxy;
28
class GrSurface;
29
class GrSurfaceProxy;
30
class GrTextureProxy;
31
struct SkIPoint;
32
struct SkIRect;
33
34
namespace skgpu {
35
class SingleOwner;
36
}
37
38
namespace skgpu::ganesh {
39
40
class SurfaceFillContext;
41
42
class SurfaceContext {
43
public:
44
    // If it is known that the GrSurfaceProxy is not renderable, you can directly call the ctor
45
    // here to make a SurfaceContext on the stack.
46
    SurfaceContext(GrRecordingContext*, GrSurfaceProxyView readView, const GrColorInfo&);
47
48
106k
    virtual ~SurfaceContext() = default;
49
50
112k
    GrRecordingContext* recordingContext() const { return fContext; }
51
52
700k
    const GrColorInfo& colorInfo() const { return fColorInfo; }
53
0
    GrImageInfo imageInfo() const { return {fColorInfo, fReadView.proxy()->dimensions()}; }
54
55
103k
    GrSurfaceOrigin origin() const { return fReadView.origin(); }
56
17.9k
    skgpu::Swizzle readSwizzle() const { return fReadView.swizzle(); }
57
    // TODO: See if it makes sense for this to return a const& instead and require the callers to
58
    // make a copy (which refs the proxy) if needed.
59
122k
    GrSurfaceProxyView readSurfaceView() { return fReadView; }
60
61
386k
    SkISize dimensions() const { return fReadView.dimensions(); }
62
33.7k
    int width() const { return fReadView.proxy()->width(); }
63
33.7k
    int height() const { return fReadView.proxy()->height(); }
64
65
0
    skgpu::Mipmapped mipmapped() const { return fReadView.mipmapped(); }
66
67
    const GrCaps* caps() const;
68
69
    /**
70
     * Reads a rectangle of pixels from the surface context.
71
     * @param dContext      The direct context to use
72
     * @param dst           destination pixels for the read
73
     * @param srcPt         offset w/in the surface context from which to read
74
     *                      is a GrDirectContext and fail otherwise.
75
     */
76
    bool readPixels(GrDirectContext* dContext, GrPixmap dst, SkIPoint srcPt);
77
78
    using ReadPixelsCallback = SkImage::ReadPixelsCallback;
79
    using ReadPixelsContext  = SkImage::ReadPixelsContext;
80
    using RescaleGamma       = SkImage::RescaleGamma;
81
    using RescaleMode        = SkImage::RescaleMode;
82
83
    // GPU implementation for SkImage:: and SkSurface::asyncRescaleAndReadPixels.
84
    void asyncRescaleAndReadPixels(GrDirectContext*,
85
                                   const SkImageInfo& info,
86
                                   const SkIRect& srcRect,
87
                                   RescaleGamma rescaleGamma,
88
                                   RescaleMode,
89
                                   ReadPixelsCallback callback,
90
                                   ReadPixelsContext callbackContext);
91
92
    // GPU implementation for SkImage:: and SkSurface::asyncRescaleAndReadPixelsYUV420.
93
    void asyncRescaleAndReadPixelsYUV420(GrDirectContext*,
94
                                         SkYUVColorSpace yuvColorSpace,
95
                                         bool readAlpha,
96
                                         sk_sp<SkColorSpace> dstColorSpace,
97
                                         const SkIRect& srcRect,
98
                                         SkISize dstSize,
99
                                         RescaleGamma rescaleGamma,
100
                                         RescaleMode,
101
                                         ReadPixelsCallback callback,
102
                                         ReadPixelsContext context);
103
104
    /**
105
     * Writes a rectangle of pixels from src into the surfaceDrawContext at the specified position.
106
     * @param dContext         The direct context to use
107
     * @param src              source for the write
108
     * @param dstPt            offset w/in the surface context at which to write
109
     */
110
    bool writePixels(GrDirectContext* dContext,
111
                     GrCPixmap src,
112
                     SkIPoint dstPt);
113
114
    /**
115
     * Fully populates either the base level or all MIP levels of the GrSurface with pixel data.
116
     * @param dContext         The direct context to use
117
     * @param src              Array of pixmaps
118
     * @param numLevels        Number of pixmaps in src. To succeed this must be 1 or the total
119
     *                         number of MIP levels.
120
     */
121
    bool writePixels(GrDirectContext* dContext,
122
                     const GrCPixmap src[],
123
                     int numLevels);
124
125
727k
    GrSurfaceProxy* asSurfaceProxy() { return fReadView.proxy(); }
126
0
    const GrSurfaceProxy* asSurfaceProxy() const { return fReadView.proxy(); }
127
74.5k
    sk_sp<GrSurfaceProxy> asSurfaceProxyRef() { return fReadView.refProxy(); }
128
129
10.7k
    GrTextureProxy* asTextureProxy() { return fReadView.asTextureProxy(); }
130
0
    const GrTextureProxy* asTextureProxy() const { return fReadView.asTextureProxy(); }
131
0
    sk_sp<GrTextureProxy> asTextureProxyRef() { return fReadView.asTextureProxyRef(); }
132
133
111k
    GrRenderTargetProxy* asRenderTargetProxy() { return fReadView.asRenderTargetProxy(); }
134
272k
    const GrRenderTargetProxy* asRenderTargetProxy() const {
135
272k
        return fReadView.asRenderTargetProxy();
136
272k
    }
137
0
    sk_sp<GrRenderTargetProxy> asRenderTargetProxyRef() {
138
0
        return fReadView.asRenderTargetProxyRef();
139
0
    }
140
141
0
    virtual SurfaceFillContext* asFillContext() { return nullptr; }
142
143
    /**
144
     * Rescales the contents of srcRect. The gamma in which the rescaling occurs is controlled by
145
     * RescaleGamma. It is always in the original gamut. The result is converted to the color type
146
     * and color space of info after rescaling. Note: this currently requires that the info have a
147
     * different size than srcRect. Though, it could be relaxed to allow non-scaling color
148
     * conversions.
149
     */
150
    std::unique_ptr<SurfaceFillContext> rescale(const GrImageInfo& info,
151
                                                GrSurfaceOrigin,
152
                                                SkIRect srcRect,
153
                                                SkImage::RescaleGamma,
154
                                                SkImage::RescaleMode);
155
156
    /**
157
     * Like the above but allows the caller ot specify a destination fill context and
158
     * rect within that context. The dst rect must be contained by the dst or this will fail.
159
     */
160
    bool rescaleInto(SurfaceFillContext* dst,
161
                     SkIRect dstRect,
162
                     SkIRect srcRect,
163
                     SkImage::RescaleGamma,
164
                     SkImage::RescaleMode);
165
166
#if defined(GR_TEST_UTILS)
167
0
    bool testCopy(sk_sp<GrSurfaceProxy> src, const SkIRect& srcRect, const SkIPoint& dstPoint) {
168
0
        return this->copy(std::move(src), srcRect, dstPoint) != nullptr;
169
0
    }
170
171
0
    bool testCopy(sk_sp<GrSurfaceProxy> src) {
172
0
        auto rect = SkIRect::MakeSize(src->dimensions());
173
0
        return this->copy(std::move(src), rect, {0, 0}) != nullptr;
174
0
    }
175
#endif
176
177
protected:
178
    GrDrawingManager* drawingManager();
179
    const GrDrawingManager* drawingManager() const;
180
181
    SkDEBUGCODE(void validate() const;)
182
183
    SkDEBUGCODE(skgpu::SingleOwner* singleOwner() const;)
184
185
    GrRecordingContext* fContext;
186
187
    GrSurfaceProxyView fReadView;
188
189
    // Inserts a transfer, part of the implementation of asyncReadPixels and
190
    // asyncRescaleAndReadPixelsYUV420().
191
    struct PixelTransferResult {
192
        using ConversionFn = void(void* dst, const void* mappedBuffer);
193
        // If null then the transfer could not be performed. Otherwise this buffer will contain
194
        // the pixel data when the transfer is complete.
195
        sk_sp<GrGpuBuffer> fTransferBuffer;
196
        // RowBytes for transfer buffer data
197
        size_t fRowBytes;
198
        // If this is null then the transfer buffer will contain the data in the requested
199
        // color type. Otherwise, when the transfer is done this must be called to convert
200
        // from the transfer buffer's color type to the requested color type.
201
        std::function<ConversionFn> fPixelConverter;
202
    };
203
    PixelTransferResult transferPixels(GrColorType colorType, const SkIRect& rect);
204
205
    // The async read step of asyncRescaleAndReadPixels()
206
    void asyncReadPixels(GrDirectContext*,
207
                         const SkIRect& srcRect,
208
                         SkColorType,
209
                         ReadPixelsCallback,
210
                         ReadPixelsContext);
211
212
private:
213
    friend class ::GrRecordingContextPriv; // for validate
214
    friend class ::GrSurfaceProxy; // for copy
215
216
    SkDEBUGCODE(virtual void onValidate() const {})
217
218
    /**
219
     * Copy 'src' into the proxy backing this context. This call will not do any draw fallback.
220
     * Currently only writePixels and replaceRenderTarget call this directly. All other copies
221
     * should go through GrSurfaceProxy::Copy.
222
     * @param src       src of pixels
223
     * @param dstPoint  the origin of the 'srcRect' in the destination coordinate space
224
     * @return          a task (that may be skippable by calling canSkip) if successful and
225
     *                  null otherwise.
226
     *
227
     * Note: Notionally, 'srcRect' is clipped to 'src's extent with 'dstPoint' being adjusted.
228
     *       Then the 'srcRect' offset by 'dstPoint' is clipped against the dst's extent.
229
     *       The end result is only valid src pixels and dst pixels will be touched but the copied
230
     *       regions will not be shifted. The 'src' must have the same origin as the backing proxy
231
     *       of fSurfaceContext.
232
     */
233
    sk_sp<GrRenderTask> copy(sk_sp<GrSurfaceProxy> src, SkIRect srcRect, SkIPoint dstPoint);
234
235
    /**
236
     * Copy and scale 'src' into the proxy backing this context. This call will not do any draw
237
     * fallback. Currently only rescaleInto() calls this directly, which handles drawing fallback
238
     * automatically.
239
     *
240
     * @param src        src of pixels
241
     * @param srcRect    the subset of src that is copied to this proxy
242
     * @param dstRect    the subset of dst that receives the copied data, possibly with different
243
     *                   dimensions than 'srcRect'.
244
     * @param filterMode the filter mode to apply when scaling src
245
     * @return           a task (that may be skippable by calling canSkip) if successful and
246
     *                   null otherwise.
247
     *
248
     * Note: Unlike copy(rect,point), 'srcRect' and 'dstRect' are not adjusted to fit within the
249
     * surfaces. If they are not contained, then nullptr is returned. The 'src' must have the same
250
     * origin as the backing proxy of this context.
251
     */
252
    sk_sp<GrRenderTask> copyScaled(sk_sp<GrSurfaceProxy> src, SkIRect srcRect, SkIRect dstRect,
253
                                   GrSamplerState::Filter filterMode);
254
255
    bool internalWritePixels(GrDirectContext* dContext,
256
                             const GrCPixmap src[],
257
                             int numLevels,
258
                             SkIPoint);
259
260
    GrColorInfo fColorInfo;
261
262
    using INHERITED = SkRefCnt;
263
};
264
265
}  // namespace skgpu::ganesh
266
267
#endif // SurfaceContext_DEFINED