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 GrSurfaceContext_DEFINED
9#define GrSurfaceContext_DEFINED
10
11#include "include/core/SkFilterQuality.h"
12#include "include/core/SkRect.h"
13#include "include/core/SkRefCnt.h"
14#include "include/core/SkSurface.h"
15#include "src/gpu/GrColorInfo.h"
16#include "src/gpu/GrDataUtils.h"
17#include "src/gpu/GrImageInfo.h"
18#include "src/gpu/GrSurfaceProxy.h"
19#include "src/gpu/GrSurfaceProxyView.h"
20
21class GrAuditTrail;
22class GrDrawingManager;
23class GrRecordingContext;
24class GrRenderTargetContext;
25class GrRenderTargetProxy;
26class GrSingleOwner;
27class GrSurface;
28class GrSurfaceContextPriv;
29class GrSurfaceProxy;
30class GrTextureProxy;
31struct SkIPoint;
32struct SkIRect;
33
34/**
35 * A helper object to orchestrate commands for a particular surface
36 */
37class GrSurfaceContext {
38public:
39 // If the passed in GrSurfaceProxy is renderable this will return a GrRenderTargetContext,
40 // otherwise it will return a GrSurfaceContext.
41 static std::unique_ptr<GrSurfaceContext> Make(GrRecordingContext*,
42 GrSurfaceProxyView readView,
43 GrColorType, SkAlphaType, sk_sp<SkColorSpace>);
44
45 static std::unique_ptr<GrSurfaceContext> Make(GrRecordingContext*, SkISize dimensions,
46 const GrBackendFormat&, GrRenderable,
47 int renderTargetSampleCnt, GrMipMapped,
48 GrProtected, GrSurfaceOrigin, GrColorType,
49 SkAlphaType, sk_sp<SkColorSpace>, SkBackingFit,
50 SkBudgeted);
51
52 // If it is known that the GrSurfaceProxy is not renderable, you can directly call the the ctor
53 // here to make a GrSurfaceContext on the stack.
54 GrSurfaceContext(GrRecordingContext*, GrSurfaceProxyView readView, GrColorType, SkAlphaType,
55 sk_sp<SkColorSpace>);
56
57 virtual ~GrSurfaceContext() = default;
58
59 const GrColorInfo& colorInfo() const { return fColorInfo; }
60 GrImageInfo imageInfo() const { return {fColorInfo, fReadView.proxy()->dimensions()}; }
61
62 GrSurfaceOrigin origin() const { return fReadView.origin(); }
63 GrSwizzle readSwizzle() const { return fReadView.swizzle(); }
64 // TODO: See if it makes sense for this to return a const& instead and require the callers to
65 // make a copy (which refs the proxy) if needed.
66 GrSurfaceProxyView readSurfaceView() { return fReadView; }
67
68 SkISize dimensions() const { return fReadView.dimensions(); }
69 int width() const { return fReadView.proxy()->width(); }
70 int height() const { return fReadView.proxy()->height(); }
71
72 const GrCaps* caps() const;
73
74 /**
75 * Reads a rectangle of pixels from the render target context.
76 * @param dstInfo image info for the destination
77 * @param dst destination pixels for the read
78 * @param rowBytes bytes in a row of 'dst'
79 * @param srcPt offset w/in the surface context from which to read
80 * @param direct The direct context to use. If null will use our GrRecordingContext if it
81 * is a GrDirectContext and fail otherwise.
82 */
83 bool readPixels(const GrImageInfo& dstInfo, void* dst, size_t rowBytes, SkIPoint srcPt,
84 GrContext* direct = nullptr);
85
86 /**
87 * Writes a rectangle of pixels [srcInfo, srcBuffer, srcRowbytes] into the
88 * renderTargetContext at the specified position.
89 * @param srcInfo image info for the source pixels
90 * @param src source for the write
91 * @param rowBytes bytes in a row of 'src'
92 * @param dstPt offset w/in the surface context at which to write
93 * @param direct The direct context to use. If null will use our GrRecordingContext if it
94 * is a GrDirectContext and fail otherwise.
95 */
96 bool writePixels(const GrImageInfo& srcInfo, const void* src, size_t rowBytes, SkIPoint dstPt,
97 GrContext* direct = nullptr);
98
99 GrSurfaceProxy* asSurfaceProxy() { return fReadView.proxy(); }
100 const GrSurfaceProxy* asSurfaceProxy() const { return fReadView.proxy(); }
101 sk_sp<GrSurfaceProxy> asSurfaceProxyRef() { return fReadView.refProxy(); }
102
103 GrTextureProxy* asTextureProxy() { return fReadView.asTextureProxy(); }
104 const GrTextureProxy* asTextureProxy() const { return fReadView.asTextureProxy(); }
105 sk_sp<GrTextureProxy> asTextureProxyRef() { return fReadView.asTextureProxyRef(); }
106
107 GrRenderTargetProxy* asRenderTargetProxy() { return fReadView.asRenderTargetProxy(); }
108 const GrRenderTargetProxy* asRenderTargetProxy() const {
109 return fReadView.asRenderTargetProxy();
110 }
111 sk_sp<GrRenderTargetProxy> asRenderTargetProxyRef() {
112 return fReadView.asRenderTargetProxyRef();
113 }
114
115 virtual GrRenderTargetContext* asRenderTargetContext() { return nullptr; }
116
117 GrAuditTrail* auditTrail();
118
119 // Provides access to functions that aren't part of the public API.
120 GrSurfaceContextPriv surfPriv();
121 const GrSurfaceContextPriv surfPriv() const;
122
123#if GR_TEST_UTILS
124 bool testCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) {
125 return this->copy(src, srcRect, dstPoint);
126 }
127
128 bool testCopy(GrSurfaceProxy* src) {
129 return this->copy(src, SkIRect::MakeSize(src->dimensions()), {0, 0});
130 }
131#endif
132
133protected:
134 friend class GrSurfaceContextPriv;
135
136 GrDrawingManager* drawingManager();
137 const GrDrawingManager* drawingManager() const;
138
139 SkDEBUGCODE(void validate() const;)
140
141 SkDEBUGCODE(GrSingleOwner* singleOwner();)
142
143 GrRecordingContext* fContext;
144
145 GrSurfaceProxyView fReadView;
146
147 // The rescaling step of asyncRescaleAndReadPixels[YUV420]().
148 std::unique_ptr<GrRenderTargetContext> rescale(const SkImageInfo& info, const SkIRect& srcRect,
149 SkSurface::RescaleGamma rescaleGamma,
150 SkFilterQuality rescaleQuality);
151
152 // Inserts a transfer, part of the implementation of asyncReadPixels and
153 // asyncRescaleAndReadPixelsYUV420().
154 struct PixelTransferResult {
155 using ConversionFn = void(void* dst, const void* mappedBuffer);
156 // If null then the transfer could not be performed. Otherwise this buffer will contain
157 // the pixel data when the transfer is complete.
158 sk_sp<GrGpuBuffer> fTransferBuffer;
159 // If this is null then the transfer buffer will contain the data in the requested
160 // color type. Otherwise, when the transfer is done this must be called to convert
161 // from the transfer buffer's color type to the requested color type.
162 std::function<ConversionFn> fPixelConverter;
163 };
164 PixelTransferResult transferPixels(GrColorType colorType, const SkIRect& rect);
165
166private:
167 friend class GrSurfaceProxy; // for copy
168
169 SkDEBUGCODE(virtual void onValidate() const {})
170
171 /**
172 * Copy 'src' into the proxy backing this context. This call will not do any draw fallback.
173 * Currently only writePixels and replaceRenderTarget call this directly. All other copies
174 * should go through GrSurfaceProxy::Copy.
175 * @param src src of pixels
176 * @param dstPoint the origin of the 'srcRect' in the destination coordinate space
177 * @return true if the copy succeeded; false otherwise
178 *
179 * Note: Notionally, 'srcRect' is clipped to 'src's extent with 'dstPoint' being adjusted.
180 * Then the 'srcRect' offset by 'dstPoint' is clipped against the dst's extent.
181 * The end result is only valid src pixels and dst pixels will be touched but the copied
182 * regions will not be shifted. The 'src' must have the same origin as the backing proxy
183 * of fSurfaceContext.
184 */
185 bool copy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint);
186
187 GrColorInfo fColorInfo;
188
189 typedef SkRefCnt INHERITED;
190};
191
192#endif
193