blob: 60fc97814c8a6d446c0f196129c0dc086f4fc5c8 [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
8#ifndef GrSurfaceContext_DEFINED
9#define GrSurfaceContext_DEFINED
10
Brian Salomone9ad9982019-07-22 16:17:41 -040011#include "include/core/SkFilterQuality.h"
Brian Salomon63a0a752020-06-26 13:32:09 -040012#include "include/core/SkImage.h"
Brian Salomone9ad9982019-07-22 16:17:41 -040013#include "include/core/SkRect.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "include/core/SkRefCnt.h"
Brian Salomone9ad9982019-07-22 16:17:41 -040015#include "include/core/SkSurface.h"
Brian Salomon63a0a752020-06-26 13:32:09 -040016#include "src/gpu/GrClientMappedBufferManager.h"
Brian Salomon4bc0c1f2019-09-30 15:12:27 -040017#include "src/gpu/GrColorInfo.h"
Brian Salomon1d435302019-07-01 13:05:28 -040018#include "src/gpu/GrDataUtils.h"
Brian Salomon6aa65052020-01-28 12:16:53 -050019#include "src/gpu/GrImageInfo.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040020#include "src/gpu/GrSurfaceProxy.h"
Greg Daniel901b98e2019-10-22 09:54:02 -040021#include "src/gpu/GrSurfaceProxyView.h"
Brian Osman45580d32016-11-23 09:37:01 -050022
23class GrAuditTrail;
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;
Brian Salomon590f5672020-12-16 11:44:47 -050029class GrSurfaceDrawContext;
30class GrSurfaceFillContext;
Robert Phillips27341362016-12-14 08:46:47 -050031class GrSurfaceProxy;
32class GrTextureProxy;
Brian Osman45580d32016-11-23 09:37:01 -050033struct SkIPoint;
34struct SkIRect;
35
36/**
37 * A helper object to orchestrate commands for a particular surface
38 */
Brian Salomon57f211b2019-08-21 15:21:09 -040039class GrSurfaceContext {
Brian Osman45580d32016-11-23 09:37:01 -050040public:
Brian Salomoneebe7352020-12-09 16:37:04 -050041 // If the passed in GrSurfaceProxy is renderable this will return a GrSurfaceDrawContext,
Greg Danielbfa19c42019-12-19 16:41:40 -050042 // otherwise it will return a GrSurfaceContext.
Greg Daniel3912a4b2020-01-14 09:56:04 -050043 static std::unique_ptr<GrSurfaceContext> Make(GrRecordingContext*,
44 GrSurfaceProxyView readView,
Brian Salomon14f99fc2020-12-07 12:19:47 -050045 const GrColorInfo&);
Greg Danielbfa19c42019-12-19 16:41:40 -050046
Brian Salomon590f5672020-12-16 11:44:47 -050047 // Makes either a GrSurfaceContext, GrFillDrawContext, or a GrSurfaceDrawContext, depending on
48 // GrRenderable and the GrImageInfo.
Brian Salomon14f99fc2020-12-07 12:19:47 -050049 static std::unique_ptr<GrSurfaceContext> Make(GrRecordingContext*,
50 const GrImageInfo&,
51 const GrBackendFormat&,
52 SkBackingFit = SkBackingFit::kExact,
53 GrSurfaceOrigin = kTopLeft_GrSurfaceOrigin,
54 GrRenderable = GrRenderable::kNo,
55 int renderTargetSampleCnt = 1,
56 GrMipmapped = GrMipmapped::kNo,
57 GrProtected = GrProtected::kNo,
58 SkBudgeted = SkBudgeted::kYes);
59
Brian Salomon590f5672020-12-16 11:44:47 -050060 // Same as the above but chooses the texture format using the default format for the color type.
Brian Salomon14f99fc2020-12-07 12:19:47 -050061 static std::unique_ptr<GrSurfaceContext> Make(GrRecordingContext*,
62 const GrImageInfo&,
63 SkBackingFit = SkBackingFit::kExact,
64 GrSurfaceOrigin = kTopLeft_GrSurfaceOrigin,
65 GrRenderable = GrRenderable::kNo,
66 int renderTargetSampleCnt = 1,
67 GrMipmapped = GrMipmapped::kNo,
68 GrProtected = GrProtected::kNo,
69 SkBudgeted = SkBudgeted::kYes);
Greg Danielbfa19c42019-12-19 16:41:40 -050070
71 // If it is known that the GrSurfaceProxy is not renderable, you can directly call the the ctor
72 // here to make a GrSurfaceContext on the stack.
Brian Salomon14f99fc2020-12-07 12:19:47 -050073 GrSurfaceContext(GrRecordingContext*, GrSurfaceProxyView readView, const GrColorInfo&);
Greg Danielbfa19c42019-12-19 16:41:40 -050074
Brian Salomonbf6b9792019-08-21 09:38:10 -040075 virtual ~GrSurfaceContext() = default;
Brian Osman45580d32016-11-23 09:37:01 -050076
Brian Salomon70fe17e2020-11-30 14:33:58 -050077 GrRecordingContext* recordingContext() { return fContext; }
78
Brian Salomon4bc0c1f2019-09-30 15:12:27 -040079 const GrColorInfo& colorInfo() const { return fColorInfo; }
Brian Salomon6aa65052020-01-28 12:16:53 -050080 GrImageInfo imageInfo() const { return {fColorInfo, fReadView.proxy()->dimensions()}; }
81
Greg Daniel3912a4b2020-01-14 09:56:04 -050082 GrSurfaceOrigin origin() const { return fReadView.origin(); }
83 GrSwizzle readSwizzle() const { return fReadView.swizzle(); }
84 // TODO: See if it makes sense for this to return a const& instead and require the callers to
85 // make a copy (which refs the proxy) if needed.
86 GrSurfaceProxyView readSurfaceView() { return fReadView; }
Robert Phillips2c862492017-01-18 10:08:39 -050087
Brian Salomonc5243782020-04-02 12:50:34 -040088 SkISize dimensions() const { return fReadView.dimensions(); }
Greg Daniel3912a4b2020-01-14 09:56:04 -050089 int width() const { return fReadView.proxy()->width(); }
90 int height() const { return fReadView.proxy()->height(); }
Robert Phillipsd46697a2017-01-25 12:10:37 -050091
Brian Salomon4d2d6f42019-07-26 14:15:11 -040092 const GrCaps* caps() const;
93
Robert Phillips2c862492017-01-18 10:08:39 -050094 /**
95 * Reads a rectangle of pixels from the render target context.
Adlai Hollerc95b5892020-08-11 12:02:22 -040096 * @param dContext The direct context to use
Robert Phillips2c862492017-01-18 10:08:39 -050097 * @param dstInfo image info for the destination
Brian Salomon1d435302019-07-01 13:05:28 -040098 * @param dst destination pixels for the read
99 * @param rowBytes bytes in a row of 'dst'
100 * @param srcPt offset w/in the surface context from which to read
Brian Salomon1d435302019-07-01 13:05:28 -0400101 * is a GrDirectContext and fail otherwise.
Robert Phillips2c862492017-01-18 10:08:39 -0500102 */
Adlai Hollerc95b5892020-08-11 12:02:22 -0400103 bool readPixels(GrDirectContext* dContext,
104 const GrImageInfo& dstInfo,
105 void* dst,
106 size_t rowBytes,
107 SkIPoint srcPt);
Robert Phillips2c862492017-01-18 10:08:39 -0500108
Brian Salomon63a0a752020-06-26 13:32:09 -0400109 using ReadPixelsCallback = SkImage::ReadPixelsCallback;
110 using ReadPixelsContext = SkImage::ReadPixelsContext;
111 using RescaleGamma = SkImage::RescaleGamma;
112
113 // GPU implementation for SkImage:: and SkSurface::asyncRescaleAndReadPixels.
Adlai Hollerc95b5892020-08-11 12:02:22 -0400114 void asyncRescaleAndReadPixels(GrDirectContext*,
115 const SkImageInfo& info,
Brian Salomon63a0a752020-06-26 13:32:09 -0400116 const SkIRect& srcRect,
117 RescaleGamma rescaleGamma,
118 SkFilterQuality rescaleQuality,
119 ReadPixelsCallback callback,
Adlai Hollerc95b5892020-08-11 12:02:22 -0400120 ReadPixelsContext callbackContext);
Brian Salomon63a0a752020-06-26 13:32:09 -0400121
122 // GPU implementation for SkImage:: and SkSurface::asyncRescaleAndReadPixelsYUV420.
Adlai Hollerc95b5892020-08-11 12:02:22 -0400123 void asyncRescaleAndReadPixelsYUV420(GrDirectContext*,
124 SkYUVColorSpace yuvColorSpace,
Brian Salomon63a0a752020-06-26 13:32:09 -0400125 sk_sp<SkColorSpace> dstColorSpace,
126 const SkIRect& srcRect,
127 SkISize dstSize,
128 RescaleGamma rescaleGamma,
129 SkFilterQuality rescaleQuality,
130 ReadPixelsCallback callback,
131 ReadPixelsContext context);
132
Robert Phillips2c862492017-01-18 10:08:39 -0500133 /**
Robert Phillipsb726d582017-03-09 16:36:32 -0500134 * Writes a rectangle of pixels [srcInfo, srcBuffer, srcRowbytes] into the
Brian Salomon1aa1f5f2020-12-11 17:25:17 -0500135 * surfaceDrawContext at the specified position.
Adlai Hollerc95b5892020-08-11 12:02:22 -0400136 * @param dContext The direct context to use
Robert Phillips2c862492017-01-18 10:08:39 -0500137 * @param srcInfo image info for the source pixels
Brian Salomon1d435302019-07-01 13:05:28 -0400138 * @param src source for the write
139 * @param rowBytes bytes in a row of 'src'
140 * @param dstPt offset w/in the surface context at which to write
Robert Phillips2c862492017-01-18 10:08:39 -0500141 */
Adlai Hollerc95b5892020-08-11 12:02:22 -0400142 bool writePixels(GrDirectContext* dContext,
143 const GrImageInfo& srcInfo,
144 const void* src,
145 size_t rowBytes,
146 SkIPoint dstPt);
Greg Daniel6eb8c242019-06-05 10:22:24 -0400147
Greg Daniel3912a4b2020-01-14 09:56:04 -0500148 GrSurfaceProxy* asSurfaceProxy() { return fReadView.proxy(); }
149 const GrSurfaceProxy* asSurfaceProxy() const { return fReadView.proxy(); }
Greg Danielc61d7e32020-02-04 14:27:45 -0500150 sk_sp<GrSurfaceProxy> asSurfaceProxyRef() { return fReadView.refProxy(); }
Robert Phillipsf200a902017-01-30 13:27:37 -0500151
Greg Daniel3912a4b2020-01-14 09:56:04 -0500152 GrTextureProxy* asTextureProxy() { return fReadView.asTextureProxy(); }
153 const GrTextureProxy* asTextureProxy() const { return fReadView.asTextureProxy(); }
154 sk_sp<GrTextureProxy> asTextureProxyRef() { return fReadView.asTextureProxyRef(); }
Robert Phillipsf200a902017-01-30 13:27:37 -0500155
Greg Daniel3912a4b2020-01-14 09:56:04 -0500156 GrRenderTargetProxy* asRenderTargetProxy() { return fReadView.asRenderTargetProxy(); }
Greg Daniel46e366a2019-12-16 14:38:36 -0500157 const GrRenderTargetProxy* asRenderTargetProxy() const {
Greg Daniel3912a4b2020-01-14 09:56:04 -0500158 return fReadView.asRenderTargetProxy();
Greg Daniel46e366a2019-12-16 14:38:36 -0500159 }
160 sk_sp<GrRenderTargetProxy> asRenderTargetProxyRef() {
Greg Daniel3912a4b2020-01-14 09:56:04 -0500161 return fReadView.asRenderTargetProxyRef();
Greg Daniel46e366a2019-12-16 14:38:36 -0500162 }
Robert Phillips27341362016-12-14 08:46:47 -0500163
Brian Salomoneebe7352020-12-09 16:37:04 -0500164 virtual GrSurfaceDrawContext* asRenderTargetContext() { return nullptr; }
Brian Salomon590f5672020-12-16 11:44:47 -0500165 virtual GrSurfaceFillContext* asFillContext() { return nullptr; }
Robert Phillipsd46697a2017-01-25 12:10:37 -0500166
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400167 /**
168 * Rescales the contents of srcRect. The gamma in which the rescaling occurs is controlled by
169 * RescaleGamma. It is always in the original gamut. The result is converted to the color type
170 * and color space of info after rescaling. Note: this currently requires that the info have a
171 * different size than srcRect. Though, it could be relaxed to allow non-scaling color
172 * conversions.
173 */
Brian Salomoneebe7352020-12-09 16:37:04 -0500174 std::unique_ptr<GrSurfaceDrawContext> rescale(const GrImageInfo& info,
175 GrSurfaceOrigin,
176 SkIRect srcRect,
177 SkImage::RescaleGamma,
178 SkFilterQuality);
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400179
Brian Salomon1c86b632020-12-11 12:36:01 -0500180 /**
181 * Like the above but allows the caller ot specify a destination render target context and
182 * rect within that context. The dst rect must be contained by the dst or this will fail.
183 */
184 bool rescaleInto(GrSurfaceDrawContext* dst,
185 SkIRect dstRect,
186 SkIRect srcRect,
187 SkImage::RescaleGamma,
188 SkFilterQuality);
189
Robert Phillips0d075de2019-03-04 11:08:13 -0500190 GrAuditTrail* auditTrail();
Brian Osman45580d32016-11-23 09:37:01 -0500191
Greg Daniel46cfbc62019-06-07 11:43:30 -0400192#if GR_TEST_UTILS
Brian Salomonc5243782020-04-02 12:50:34 -0400193 bool testCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) {
194 return this->copy(src, srcRect, dstPoint);
Greg Daniel46cfbc62019-06-07 11:43:30 -0400195 }
196
Brian Salomonc5243782020-04-02 12:50:34 -0400197 bool testCopy(GrSurfaceProxy* src) {
198 return this->copy(src, SkIRect::MakeSize(src->dimensions()), {0, 0});
Greg Daniel46cfbc62019-06-07 11:43:30 -0400199 }
200#endif
201
Brian Osman45580d32016-11-23 09:37:01 -0500202protected:
Robert Phillips0d075de2019-03-04 11:08:13 -0500203 GrDrawingManager* drawingManager();
204 const GrDrawingManager* drawingManager() const;
Brian Osman45580d32016-11-23 09:37:01 -0500205
Greg Daniel46e366a2019-12-16 14:38:36 -0500206 SkDEBUGCODE(void validate() const;)
Robert Phillips2de8cfa2017-06-28 10:33:41 -0400207
Brian Salomon70fe17e2020-11-30 14:33:58 -0500208 SkDEBUGCODE(GrSingleOwner* singleOwner() const;)
Brian Osman45580d32016-11-23 09:37:01 -0500209
Robert Phillips69893702019-02-22 11:16:30 -0500210 GrRecordingContext* fContext;
Brian Osman45580d32016-11-23 09:37:01 -0500211
Greg Daniel3912a4b2020-01-14 09:56:04 -0500212 GrSurfaceProxyView fReadView;
Greg Daniel901b98e2019-10-22 09:54:02 -0400213
Brian Salomon4d2d6f42019-07-26 14:15:11 -0400214 // Inserts a transfer, part of the implementation of asyncReadPixels and
215 // asyncRescaleAndReadPixelsYUV420().
216 struct PixelTransferResult {
217 using ConversionFn = void(void* dst, const void* mappedBuffer);
218 // If null then the transfer could not be performed. Otherwise this buffer will contain
219 // the pixel data when the transfer is complete.
220 sk_sp<GrGpuBuffer> fTransferBuffer;
221 // If this is null then the transfer buffer will contain the data in the requested
222 // color type. Otherwise, when the transfer is done this must be called to convert
223 // from the transfer buffer's color type to the requested color type.
224 std::function<ConversionFn> fPixelConverter;
225 };
226 PixelTransferResult transferPixels(GrColorType colorType, const SkIRect& rect);
227
Brian Salomon63a0a752020-06-26 13:32:09 -0400228 // The async read step of asyncRescaleAndReadPixels()
Adlai Hollerc95b5892020-08-11 12:02:22 -0400229 void asyncReadPixels(GrDirectContext*,
230 const SkIRect& srcRect,
231 SkColorType,
232 ReadPixelsCallback,
233 ReadPixelsContext);
Brian Salomon63a0a752020-06-26 13:32:09 -0400234
Robert Phillipse305cc1f2016-12-14 12:19:05 -0500235private:
Greg Daniel46cfbc62019-06-07 11:43:30 -0400236 friend class GrSurfaceProxy; // for copy
237
Greg Daniel46e366a2019-12-16 14:38:36 -0500238 SkDEBUGCODE(virtual void onValidate() const {})
239
Greg Daniel46cfbc62019-06-07 11:43:30 -0400240 /**
241 * Copy 'src' into the proxy backing this context. This call will not do any draw fallback.
242 * Currently only writePixels and replaceRenderTarget call this directly. All other copies
243 * should go through GrSurfaceProxy::Copy.
244 * @param src src of pixels
Greg Daniel46cfbc62019-06-07 11:43:30 -0400245 * @param dstPoint the origin of the 'srcRect' in the destination coordinate space
246 * @return true if the copy succeeded; false otherwise
247 *
248 * Note: Notionally, 'srcRect' is clipped to 'src's extent with 'dstPoint' being adjusted.
249 * Then the 'srcRect' offset by 'dstPoint' is clipped against the dst's extent.
250 * The end result is only valid src pixels and dst pixels will be touched but the copied
251 * regions will not be shifted. The 'src' must have the same origin as the backing proxy
252 * of fSurfaceContext.
253 */
Brian Salomonc5243782020-04-02 12:50:34 -0400254 bool copy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint);
Greg Daniel46cfbc62019-06-07 11:43:30 -0400255
Brian Salomon63a0a752020-06-26 13:32:09 -0400256 class AsyncReadResult;
257
Brian Salomon4bc0c1f2019-09-30 15:12:27 -0400258 GrColorInfo fColorInfo;
Brian Salomonf3569f02017-10-24 12:52:33 -0400259
John Stiles7571f9e2020-09-02 22:42:33 -0400260 using INHERITED = SkRefCnt;
Brian Osman45580d32016-11-23 09:37:01 -0500261};
262
263#endif