blob: fc73e57f2f5596848a4a8d74647e1f7ae19c1852 [file] [log] [blame]
Brian Osman45580d32016-11-23 09:37:01 -05001/*
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
Robert Phillips53eaa642021-08-10 13:49:51 -04008#ifndef SurfaceContext_DEFINED
9#define SurfaceContext_DEFINED
Brian Osman45580d32016-11-23 09:37:01 -050010
Brian Salomon63a0a752020-06-26 13:32:09 -040011#include "include/core/SkImage.h"
Brian Salomone9ad9982019-07-22 16:17:41 -040012#include "include/core/SkRect.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "include/core/SkRefCnt.h"
Mike Reed1efa14d2021-01-02 21:44:59 -050014#include "include/core/SkSamplingOptions.h"
Brian Salomone9ad9982019-07-22 16:17:41 -040015#include "include/core/SkSurface.h"
Brian Salomon4bc0c1f2019-09-30 15:12:27 -040016#include "src/gpu/GrColorInfo.h"
Brian Salomon1d435302019-07-01 13:05:28 -040017#include "src/gpu/GrDataUtils.h"
Brian Salomon6aa65052020-01-28 12:16:53 -050018#include "src/gpu/GrImageInfo.h"
Brian Salomondd4087d2020-12-23 20:36:44 -050019#include "src/gpu/GrPixmap.h"
Brian Salomond63638b2021-03-05 14:00:07 -050020#include "src/gpu/GrRenderTask.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040021#include "src/gpu/GrSurfaceProxy.h"
Greg Daniel901b98e2019-10-22 09:54:02 -040022#include "src/gpu/GrSurfaceProxyView.h"
Brian Osman45580d32016-11-23 09:37:01 -050023
Robert Phillips72152832017-01-25 17:31:35 -050024class GrDrawingManager;
Robert Phillips69893702019-02-22 11:16:30 -050025class GrRecordingContext;
Robert Phillips27341362016-12-14 08:46:47 -050026class GrRenderTargetProxy;
Brian Osman45580d32016-11-23 09:37:01 -050027class GrSingleOwner;
28class GrSurface;
Robert Phillips27341362016-12-14 08:46:47 -050029class GrSurfaceProxy;
30class GrTextureProxy;
Brian Osman45580d32016-11-23 09:37:01 -050031struct SkIPoint;
32struct SkIRect;
33
Robert Phillips53eaa642021-08-10 13:49:51 -040034namespace skgpu {
35
36class SurfaceFillContext;
37
Brian Osman45580d32016-11-23 09:37:01 -050038/**
39 * A helper object to orchestrate commands for a particular surface
Robert Phillips53eaa642021-08-10 13:49:51 -040040 *
41 * SurfaceContext
42 * |
43 * SurfaceFillContext
44 * / \
45 * v1::SFC v2::SFC
46 * | |
47 * | |
48 * | |
49 * v1::SDC v2::SDC
50 *
Brian Osman45580d32016-11-23 09:37:01 -050051 */
Robert Phillips53eaa642021-08-10 13:49:51 -040052class SurfaceContext {
Brian Osman45580d32016-11-23 09:37:01 -050053public:
Robert Phillips53eaa642021-08-10 13:49:51 -040054 // Makes either a SurfaceContext, SurfaceFillContext, or a SurfaceDrawContext, depending on
Brian Salomon590f5672020-12-16 11:44:47 -050055 // GrRenderable and the GrImageInfo.
Robert Phillips53eaa642021-08-10 13:49:51 -040056 static std::unique_ptr<SurfaceContext> Make(GrRecordingContext*,
57 const GrImageInfo&,
58 const GrBackendFormat&,
59 SkBackingFit = SkBackingFit::kExact,
60 GrSurfaceOrigin = kTopLeft_GrSurfaceOrigin,
61 GrRenderable = GrRenderable::kNo,
62 int renderTargetSampleCnt = 1,
63 GrMipmapped = GrMipmapped::kNo,
64 GrProtected = GrProtected::kNo,
65 SkBudgeted = SkBudgeted::kYes);
Brian Salomon14f99fc2020-12-07 12:19:47 -050066
Brian Salomon590f5672020-12-16 11:44:47 -050067 // Same as the above but chooses the texture format using the default format for the color type.
Robert Phillips53eaa642021-08-10 13:49:51 -040068 static std::unique_ptr<SurfaceContext> Make(GrRecordingContext*,
69 const GrImageInfo&,
70 SkBackingFit = SkBackingFit::kExact,
71 GrSurfaceOrigin = kTopLeft_GrSurfaceOrigin,
72 GrRenderable = GrRenderable::kNo,
73 int renderTargetSampleCnt = 1,
74 GrMipmapped = GrMipmapped::kNo,
75 GrProtected = GrProtected::kNo,
76 SkBudgeted = SkBudgeted::kYes);
Greg Danielbfa19c42019-12-19 16:41:40 -050077
Robert Phillips53eaa642021-08-10 13:49:51 -040078 // If it is known that the GrSurfaceProxy is not renderable, you can directly call the ctor
79 // here to make a SurfaceContext on the stack.
80 SurfaceContext(GrRecordingContext*, GrSurfaceProxyView readView, const GrColorInfo&);
Greg Danielbfa19c42019-12-19 16:41:40 -050081
Robert Phillips53eaa642021-08-10 13:49:51 -040082 virtual ~SurfaceContext() = default;
Brian Osman45580d32016-11-23 09:37:01 -050083
Chris Dalton66deeb22021-07-23 13:57:03 -060084 GrRecordingContext* recordingContext() const { return fContext; }
Brian Salomon70fe17e2020-11-30 14:33:58 -050085
Brian Salomon4bc0c1f2019-09-30 15:12:27 -040086 const GrColorInfo& colorInfo() const { return fColorInfo; }
Brian Salomon6aa65052020-01-28 12:16:53 -050087 GrImageInfo imageInfo() const { return {fColorInfo, fReadView.proxy()->dimensions()}; }
88
Greg Daniel3912a4b2020-01-14 09:56:04 -050089 GrSurfaceOrigin origin() const { return fReadView.origin(); }
90 GrSwizzle readSwizzle() const { return fReadView.swizzle(); }
91 // TODO: See if it makes sense for this to return a const& instead and require the callers to
92 // make a copy (which refs the proxy) if needed.
93 GrSurfaceProxyView readSurfaceView() { return fReadView; }
Robert Phillips2c862492017-01-18 10:08:39 -050094
Brian Salomonc5243782020-04-02 12:50:34 -040095 SkISize dimensions() const { return fReadView.dimensions(); }
Greg Daniel3912a4b2020-01-14 09:56:04 -050096 int width() const { return fReadView.proxy()->width(); }
97 int height() const { return fReadView.proxy()->height(); }
Robert Phillipsd46697a2017-01-25 12:10:37 -050098
Robert Phillips9af0bca2021-05-27 19:17:55 -040099 GrMipmapped mipmapped() const { return fReadView.mipmapped(); }
100
Brian Salomon4d2d6f42019-07-26 14:15:11 -0400101 const GrCaps* caps() const;
102
Robert Phillips2c862492017-01-18 10:08:39 -0500103 /**
Brian Salomondd4087d2020-12-23 20:36:44 -0500104 * Reads a rectangle of pixels from the surface context.
Adlai Hollerc95b5892020-08-11 12:02:22 -0400105 * @param dContext The direct context to use
Brian Salomon1d435302019-07-01 13:05:28 -0400106 * @param dst destination pixels for the read
Brian Salomon1d435302019-07-01 13:05:28 -0400107 * @param srcPt offset w/in the surface context from which to read
Brian Salomon1d435302019-07-01 13:05:28 -0400108 * is a GrDirectContext and fail otherwise.
Robert Phillips2c862492017-01-18 10:08:39 -0500109 */
Brian Salomondd4087d2020-12-23 20:36:44 -0500110 bool readPixels(GrDirectContext* dContext, GrPixmap dst, SkIPoint srcPt);
Robert Phillips2c862492017-01-18 10:08:39 -0500111
Brian Salomon63a0a752020-06-26 13:32:09 -0400112 using ReadPixelsCallback = SkImage::ReadPixelsCallback;
113 using ReadPixelsContext = SkImage::ReadPixelsContext;
114 using RescaleGamma = SkImage::RescaleGamma;
Mike Reed1efa14d2021-01-02 21:44:59 -0500115 using RescaleMode = SkImage::RescaleMode;
Brian Salomon63a0a752020-06-26 13:32:09 -0400116
117 // GPU implementation for SkImage:: and SkSurface::asyncRescaleAndReadPixels.
Adlai Hollerc95b5892020-08-11 12:02:22 -0400118 void asyncRescaleAndReadPixels(GrDirectContext*,
119 const SkImageInfo& info,
Brian Salomon63a0a752020-06-26 13:32:09 -0400120 const SkIRect& srcRect,
121 RescaleGamma rescaleGamma,
Mike Reed1efa14d2021-01-02 21:44:59 -0500122 RescaleMode,
Brian Salomon63a0a752020-06-26 13:32:09 -0400123 ReadPixelsCallback callback,
Adlai Hollerc95b5892020-08-11 12:02:22 -0400124 ReadPixelsContext callbackContext);
Brian Salomon63a0a752020-06-26 13:32:09 -0400125
126 // GPU implementation for SkImage:: and SkSurface::asyncRescaleAndReadPixelsYUV420.
Adlai Hollerc95b5892020-08-11 12:02:22 -0400127 void asyncRescaleAndReadPixelsYUV420(GrDirectContext*,
128 SkYUVColorSpace yuvColorSpace,
Brian Salomon63a0a752020-06-26 13:32:09 -0400129 sk_sp<SkColorSpace> dstColorSpace,
130 const SkIRect& srcRect,
131 SkISize dstSize,
132 RescaleGamma rescaleGamma,
Mike Reed1efa14d2021-01-02 21:44:59 -0500133 RescaleMode,
Brian Salomon63a0a752020-06-26 13:32:09 -0400134 ReadPixelsCallback callback,
135 ReadPixelsContext context);
136
Robert Phillips2c862492017-01-18 10:08:39 -0500137 /**
Brian Salomon2c673402021-04-02 14:36:58 -0400138 * Writes a rectangle of pixels from src into the surfaceDrawContext at the specified position.
139 * @param dContext The direct context to use
140 * @param src source for the write
141 * @param dstPt offset w/in the surface context at which to write
Robert Phillips2c862492017-01-18 10:08:39 -0500142 */
Brian Salomonea1d39b2021-04-01 17:06:52 -0400143 bool writePixels(GrDirectContext* dContext,
144 GrCPixmap src,
Brian Salomon75ee7372021-04-06 15:04:35 -0400145 SkIPoint dstPt);
Greg Daniel6eb8c242019-06-05 10:22:24 -0400146
Brian Salomon2c673402021-04-02 14:36:58 -0400147 /**
148 * Fully populates either the base level or all MIP levels of the GrSurface with pixel data.
149 * @param dContext The direct context to use
150 * @param src Array of pixmaps
151 * @param numLevels Number of pixmaps in src. To succeed this must be 1 or the total
152 * number of MIP levels.
153 */
Brian Salomonea1d39b2021-04-01 17:06:52 -0400154 bool writePixels(GrDirectContext* dContext,
155 const GrCPixmap src[],
Brian Salomon75ee7372021-04-06 15:04:35 -0400156 int numLevels);
Brian Salomon2c673402021-04-02 14:36:58 -0400157
Greg Daniel3912a4b2020-01-14 09:56:04 -0500158 GrSurfaceProxy* asSurfaceProxy() { return fReadView.proxy(); }
159 const GrSurfaceProxy* asSurfaceProxy() const { return fReadView.proxy(); }
Greg Danielc61d7e32020-02-04 14:27:45 -0500160 sk_sp<GrSurfaceProxy> asSurfaceProxyRef() { return fReadView.refProxy(); }
Robert Phillipsf200a902017-01-30 13:27:37 -0500161
Greg Daniel3912a4b2020-01-14 09:56:04 -0500162 GrTextureProxy* asTextureProxy() { return fReadView.asTextureProxy(); }
163 const GrTextureProxy* asTextureProxy() const { return fReadView.asTextureProxy(); }
164 sk_sp<GrTextureProxy> asTextureProxyRef() { return fReadView.asTextureProxyRef(); }
Robert Phillipsf200a902017-01-30 13:27:37 -0500165
Greg Daniel3912a4b2020-01-14 09:56:04 -0500166 GrRenderTargetProxy* asRenderTargetProxy() { return fReadView.asRenderTargetProxy(); }
Greg Daniel46e366a2019-12-16 14:38:36 -0500167 const GrRenderTargetProxy* asRenderTargetProxy() const {
Greg Daniel3912a4b2020-01-14 09:56:04 -0500168 return fReadView.asRenderTargetProxy();
Greg Daniel46e366a2019-12-16 14:38:36 -0500169 }
170 sk_sp<GrRenderTargetProxy> asRenderTargetProxyRef() {
Greg Daniel3912a4b2020-01-14 09:56:04 -0500171 return fReadView.asRenderTargetProxyRef();
Greg Daniel46e366a2019-12-16 14:38:36 -0500172 }
Robert Phillips27341362016-12-14 08:46:47 -0500173
Robert Phillips53eaa642021-08-10 13:49:51 -0400174 virtual SurfaceFillContext* asFillContext() { return nullptr; }
Robert Phillipsd46697a2017-01-25 12:10:37 -0500175
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400176 /**
177 * Rescales the contents of srcRect. The gamma in which the rescaling occurs is controlled by
178 * RescaleGamma. It is always in the original gamut. The result is converted to the color type
179 * and color space of info after rescaling. Note: this currently requires that the info have a
180 * different size than srcRect. Though, it could be relaxed to allow non-scaling color
181 * conversions.
182 */
Robert Phillipsf3868622021-08-04 13:27:43 -0400183 std::unique_ptr<skgpu::SurfaceFillContext> rescale(const GrImageInfo& info,
184 GrSurfaceOrigin,
185 SkIRect srcRect,
186 SkImage::RescaleGamma,
187 SkImage::RescaleMode);
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400188
Brian Salomon1c86b632020-12-11 12:36:01 -0500189 /**
Brian Salomonbacbb922021-01-21 19:48:00 -0500190 * Like the above but allows the caller ot specify a destination fill context and
Brian Salomon1c86b632020-12-11 12:36:01 -0500191 * rect within that context. The dst rect must be contained by the dst or this will fail.
192 */
Robert Phillips53eaa642021-08-10 13:49:51 -0400193 bool rescaleInto(SurfaceFillContext* dst,
Brian Salomon1c86b632020-12-11 12:36:01 -0500194 SkIRect dstRect,
195 SkIRect srcRect,
196 SkImage::RescaleGamma,
Mike Reed1efa14d2021-01-02 21:44:59 -0500197 SkImage::RescaleMode);
Brian Salomon1c86b632020-12-11 12:36:01 -0500198
Greg Daniel46cfbc62019-06-07 11:43:30 -0400199#if GR_TEST_UTILS
Brian Salomon982127b2021-01-21 10:43:35 -0500200 bool testCopy(sk_sp<GrSurfaceProxy> src, const SkIRect& srcRect, const SkIPoint& dstPoint) {
Brian Salomond63638b2021-03-05 14:00:07 -0500201 return this->copy(std::move(src), srcRect, dstPoint) != nullptr;
Greg Daniel46cfbc62019-06-07 11:43:30 -0400202 }
203
Brian Salomon982127b2021-01-21 10:43:35 -0500204 bool testCopy(sk_sp<GrSurfaceProxy> src) {
205 auto rect = SkIRect::MakeSize(src->dimensions());
Brian Salomond63638b2021-03-05 14:00:07 -0500206 return this->copy(std::move(src), rect, {0, 0}) != nullptr;
Greg Daniel46cfbc62019-06-07 11:43:30 -0400207 }
208#endif
209
Brian Osman45580d32016-11-23 09:37:01 -0500210protected:
Robert Phillips0d075de2019-03-04 11:08:13 -0500211 GrDrawingManager* drawingManager();
212 const GrDrawingManager* drawingManager() const;
Brian Osman45580d32016-11-23 09:37:01 -0500213
Greg Daniel46e366a2019-12-16 14:38:36 -0500214 SkDEBUGCODE(void validate() const;)
Robert Phillips2de8cfa2017-06-28 10:33:41 -0400215
Brian Salomon70fe17e2020-11-30 14:33:58 -0500216 SkDEBUGCODE(GrSingleOwner* singleOwner() const;)
Brian Osman45580d32016-11-23 09:37:01 -0500217
Robert Phillips69893702019-02-22 11:16:30 -0500218 GrRecordingContext* fContext;
Brian Osman45580d32016-11-23 09:37:01 -0500219
Greg Daniel3912a4b2020-01-14 09:56:04 -0500220 GrSurfaceProxyView fReadView;
Greg Daniel901b98e2019-10-22 09:54:02 -0400221
Brian Salomon4d2d6f42019-07-26 14:15:11 -0400222 // Inserts a transfer, part of the implementation of asyncReadPixels and
223 // asyncRescaleAndReadPixelsYUV420().
224 struct PixelTransferResult {
225 using ConversionFn = void(void* dst, const void* mappedBuffer);
226 // If null then the transfer could not be performed. Otherwise this buffer will contain
227 // the pixel data when the transfer is complete.
228 sk_sp<GrGpuBuffer> fTransferBuffer;
229 // If this is null then the transfer buffer will contain the data in the requested
230 // color type. Otherwise, when the transfer is done this must be called to convert
231 // from the transfer buffer's color type to the requested color type.
232 std::function<ConversionFn> fPixelConverter;
233 };
234 PixelTransferResult transferPixels(GrColorType colorType, const SkIRect& rect);
235
Brian Salomon63a0a752020-06-26 13:32:09 -0400236 // The async read step of asyncRescaleAndReadPixels()
Adlai Hollerc95b5892020-08-11 12:02:22 -0400237 void asyncReadPixels(GrDirectContext*,
238 const SkIRect& srcRect,
239 SkColorType,
240 ReadPixelsCallback,
241 ReadPixelsContext);
Brian Salomon63a0a752020-06-26 13:32:09 -0400242
Robert Phillipse305cc1f2016-12-14 12:19:05 -0500243private:
Robert Phillips53eaa642021-08-10 13:49:51 -0400244 friend class ::GrRecordingContextPriv; // for validate
245 friend class ::GrSurfaceProxy; // for copy
Greg Daniel46cfbc62019-06-07 11:43:30 -0400246
Greg Daniel46e366a2019-12-16 14:38:36 -0500247 SkDEBUGCODE(virtual void onValidate() const {})
248
Greg Daniel46cfbc62019-06-07 11:43:30 -0400249 /**
250 * Copy 'src' into the proxy backing this context. This call will not do any draw fallback.
251 * Currently only writePixels and replaceRenderTarget call this directly. All other copies
252 * should go through GrSurfaceProxy::Copy.
253 * @param src src of pixels
Greg Daniel46cfbc62019-06-07 11:43:30 -0400254 * @param dstPoint the origin of the 'srcRect' in the destination coordinate space
Brian Salomond63638b2021-03-05 14:00:07 -0500255 * @return a task (that may be skippable by calling canSkip) if successful and
256 * null otherwise.
Greg Daniel46cfbc62019-06-07 11:43:30 -0400257 *
258 * Note: Notionally, 'srcRect' is clipped to 'src's extent with 'dstPoint' being adjusted.
259 * Then the 'srcRect' offset by 'dstPoint' is clipped against the dst's extent.
260 * The end result is only valid src pixels and dst pixels will be touched but the copied
261 * regions will not be shifted. The 'src' must have the same origin as the backing proxy
262 * of fSurfaceContext.
263 */
Brian Salomond63638b2021-03-05 14:00:07 -0500264 sk_sp<GrRenderTask> copy(sk_sp<GrSurfaceProxy> src, SkIRect srcRect, SkIPoint dstPoint);
Greg Daniel46cfbc62019-06-07 11:43:30 -0400265
Brian Salomon2c673402021-04-02 14:36:58 -0400266 bool internalWritePixels(GrDirectContext* dContext,
267 const GrCPixmap src[],
268 int numLevels,
Brian Salomon75ee7372021-04-06 15:04:35 -0400269 SkIPoint);
Brian Salomon2c673402021-04-02 14:36:58 -0400270
Brian Salomon63a0a752020-06-26 13:32:09 -0400271 class AsyncReadResult;
272
Brian Salomon4bc0c1f2019-09-30 15:12:27 -0400273 GrColorInfo fColorInfo;
Brian Salomonf3569f02017-10-24 12:52:33 -0400274
John Stiles7571f9e2020-09-02 22:42:33 -0400275 using INHERITED = SkRefCnt;
Brian Osman45580d32016-11-23 09:37:01 -0500276};
277
Robert Phillips53eaa642021-08-10 13:49:51 -0400278} // namespace skgpu
279
280#endif // SurfaceContext_DEFINED