Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Surface_Graphite.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2021 Google LLC
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
9
25
26namespace skgpu::graphite {
27
29 : SkSurface_Base(device->width(), device->height(), &device->surfaceProps())
30 , fDevice(std::move(device))
31 , fImageView(Image::WrapDevice(fDevice)) {}
32
34 // Mark the device immutable when the Surface is destroyed to flush any pending work to the
35 // recorder and to flag the device so that any linked image views can detach from the Device
36 // when they are next drawn.
37 fDevice->setImmutable();
38}
39
41 return fDevice->imageInfo();
42}
43
44Recorder* Surface::onGetRecorder() const { return fDevice->recorder(); }
45
47 return fDevice->readSurfaceView();
48}
49
50SkCanvas* Surface::onNewCanvas() { return new SkCanvas(fDevice); }
51
53 return SkSurfaces::RenderTarget(fDevice->recorder(), ii, Mipmapped::kNo, &this->props());
54}
55
57 TextureProxyView srcView = fDevice->readSurfaceView();
58 if (!srcView) {
59 return nullptr;
60 }
61
62 return this->makeImageCopy(subset, srcView.mipmapped());
63}
64
66 if (this->hasCachedImage()) {
67 SKGPU_LOG_W("Intermingling makeImageSnapshot and asImage calls may produce "
68 "unexpected results. Please use either the old _or_ new API.");
69 }
70 return fImageView;
71}
72
73sk_sp<Image> Surface::makeImageCopy(const SkIRect* subset, Mipmapped mipmapped) const {
74 if (this->hasCachedImage()) {
75 SKGPU_LOG_W("Intermingling makeImageSnapshot and asImage calls may produce "
76 "unexpected results. Please use either the old _or_ new API.");
77 }
78
79 SkIRect srcRect = subset ? *subset : SkIRect::MakeSize(this->imageInfo().dimensions());
80 // NOTE: Must copy through fDevice and not fImageView if the surface's texture is not sampleable
81 return fDevice->makeImageCopy(srcRect, Budgeted::kNo, mipmapped, SkBackingFit::kExact);
82}
83
84void Surface::onWritePixels(const SkPixmap& pixmap, int x, int y) {
85 fDevice->writePixels(pixmap, x, y);
86}
87
89
91 SkIRect srcRect,
92 RescaleGamma rescaleGamma,
93 RescaleMode rescaleMode,
95 ReadPixelsContext context) {
96 // Not supported for Graphite. Use Context::asyncRescaleAndReadPixels instead.
97 callback(context, nullptr);
98}
99
101 bool readAlpha,
102 sk_sp<SkColorSpace> dstColorSpace,
103 SkIRect srcRect,
104 SkISize dstSize,
105 RescaleGamma rescaleGamma,
106 RescaleMode rescaleMode,
108 ReadPixelsContext context) {
109 // Not supported for Graphite. Use Context::asyncRescaleAndReadPixelsYUV420 instead.
110 callback(context, nullptr);
111}
112
114 return fDevice->recorder()->priv().caps()->capabilities();
115}
116
117TextureProxy* Surface::backingTextureProxy() const { return fDevice->target(); }
118
120 const SkImageInfo& info,
121 Budgeted budgeted,
122 Mipmapped mipmapped,
123 SkBackingFit backingFit,
124 const SkSurfaceProps* props,
125 LoadOp initialLoadOp,
126 bool registerWithRecorder) {
128 info,
129 budgeted,
130 mipmapped,
131 backingFit,
133 initialLoadOp,
134 registerWithRecorder);
135 if (!device) {
136 return nullptr;
137 }
138 // TODO: This instantiation isn't necessary anymore when budgeted == kNo; there are some callers
139 // that pass in kYes that still rely on this instantiation for Surface objects and need to have
140 // their logic updated to work correctly with truly scratch textures.
141 if (!device->target()->instantiate(recorder->priv().resourceProvider())) {
142 return nullptr;
143 }
144 return sk_make_sp<Surface>(std::move(device));
145}
146
148 return Flush(surface.get());
149}
150
152 if (!surface) {
153 return;
154 }
155 auto sb = asSB(surface);
156 if (!sb->isGraphiteBacked()) {
157 return;
158 }
159 auto gs = static_cast<Surface*>(surface);
160 gs->fDevice->flushPendingWorkToRecorder();
161}
162
163} // namespace skgpu::graphite
164
165using namespace skgpu::graphite;
166
167namespace {
168
169bool validate_backend_texture(const Caps* caps,
170 const BackendTexture& texture,
171 const SkColorInfo& info) {
172 if (!texture.isValid() ||
173 texture.dimensions().width() <= 0 ||
174 texture.dimensions().height() <= 0) {
175 return false;
176 }
177
178 if (!SkColorInfoIsValid(info)) {
179 return false;
180 }
181
182 if (!caps->isRenderable(texture.info())) {
183 return false;
184 }
185
186 return caps->areColorTypeAndTextureInfoCompatible(info.colorType(), texture.info());
187}
188
189} // anonymous namespace
190
191namespace SkSurfaces {
193 if (!surface) {
194 return nullptr;
195 }
196 auto sb = asConstSB(surface.get());
197 if (!sb->isGraphiteBacked()) {
198 return nullptr;
199 }
200 auto gs = static_cast<const Surface*>(surface.get());
201 return gs->asImage();
202}
203
205 const SkIRect* subset,
206 skgpu::Mipmapped mipmapped) {
207 if (!surface) {
208 return nullptr;
209 }
210 auto sb = asConstSB(surface.get());
211 if (!sb->isGraphiteBacked()) {
212 return nullptr;
213 }
214 auto gs = static_cast<const Surface*>(surface.get());
215 return gs->makeImageCopy(subset, mipmapped);
216}
217
219 const SkImageInfo& info,
220 skgpu::Mipmapped mipmapped,
221 const SkSurfaceProps* props) {
222 // The client is getting the ref on this surface so it must be unbudgeted.
224 recorder, info, skgpu::Budgeted::kNo, mipmapped, SkBackingFit::kExact, props);
225}
226
228 const BackendTexture& backendTex,
229 SkColorType ct,
231 const SkSurfaceProps* props,
232 TextureReleaseProc releaseP,
233 ReleaseContext releaseC) {
234 auto releaseHelper = skgpu::RefCntedCallback::Make(releaseP, releaseC);
235
236 if (!recorder) {
237 return nullptr;
238 }
239
240 const Caps* caps = recorder->priv().caps();
241
242 SkColorInfo info(ct, kPremul_SkAlphaType, std::move(cs));
243
244 if (!validate_backend_texture(caps, backendTex, info)) {
245 SKGPU_LOG_E("validate_backend_texture failed: backendTex.info = %s; colorType = %d",
246 backendTex.info().toString().c_str(),
247 info.colorType());
248 return nullptr;
249 }
250
252 if (!texture) {
253 return nullptr;
254 }
255 texture->setReleaseCallback(std::move(releaseHelper));
256
258 SkISize deviceSize = proxy->dimensions();
259 // Use kLoad for this device to preserve the existing contents of the wrapped backend texture.
261 std::move(proxy),
262 deviceSize,
263 info,
265 LoadOp::kLoad);
266 return device ? sk_make_sp<Surface>(std::move(device)) : nullptr;
267}
268
269} // namespace SkSurfaces
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
#define SKGPU_LOG_E(fmt,...)
Definition Log.h:38
#define SKGPU_LOG_W(fmt,...)
Definition Log.h:40
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
SkBackingFit
SkColorType
Definition SkColorType.h:19
static bool SkColorInfoIsValid(const SkColorInfo &info)
SkYUVColorSpace
Definition SkImageInfo.h:68
static SkSurfaceProps SkSurfacePropsCopyOrDefault(const SkSurfaceProps *props)
static const SkSurface_Base * asConstSB(const SkSurface *surface)
static SkSurface_Base * asSB(SkSurface *surface)
static bool validate_backend_texture(const GrCaps *caps, const GrBackendTexture &tex, int sampleCnt, GrColorType grCT, bool texturable)
RescaleMode
Definition SkImage.h:587
RescaleGamma
Definition SkImage.h:585
const char * c_str() const
Definition SkString.h:133
friend class SkCanvas
bool hasCachedImage() const
void(ReadPixelsContext, std::unique_ptr< const AsyncReadResult >) ReadPixelsCallback
Definition SkSurface.h:469
const SkSurfaceProps & props() const
Definition SkSurface.h:604
skgpu::graphite::Recorder * recorder() const
void * ReadPixelsContext
Definition SkSurface.h:464
static sk_sp< RefCntedCallback > Make(Callback proc, Context ctx)
const TextureInfo & info() const
virtual bool isRenderable(const TextureInfo &) const =0
bool areColorTypeAndTextureInfoCompatible(SkColorType, const TextureInfo &) const
Definition Caps.cpp:84
static sk_sp< Device > Make(Recorder *recorder, sk_sp< TextureProxy >, SkISize deviceSize, const SkColorInfo &, const SkSurfaceProps &, LoadOp initialLoadOp, bool registerWithRecorder=true)
Definition Device.cpp:268
const Caps * caps() const
ResourceProvider * resourceProvider()
virtual sk_sp< Texture > createWrappedTexture(const BackendTexture &)=0
void onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace, bool readAlpha, sk_sp< SkColorSpace > dstColorSpace, SkIRect srcRect, SkISize dstSize, RescaleGamma rescaleGamma, RescaleMode, ReadPixelsCallback callback, ReadPixelsContext context) override
void onAsyncRescaleAndReadPixels(const SkImageInfo &info, SkIRect srcRect, RescaleGamma rescaleGamma, RescaleMode rescaleMode, ReadPixelsCallback callback, ReadPixelsContext context) override
SkCanvas * onNewCanvas() override
static sk_sp< Surface > Make(Recorder *recorder, const SkImageInfo &info, Budgeted budgeted, Mipmapped mipmapped=Mipmapped::kNo, SkBackingFit backingFit=SkBackingFit::kExact, const SkSurfaceProps *props=nullptr)
sk_sp< Image > makeImageCopy(const SkIRect *subset, Mipmapped) const
sk_sp< SkSurface > onNewSurface(const SkImageInfo &) override
sk_sp< Image > asImage() const
Recorder * onGetRecorder() const override
sk_sp< SkImage > onNewImageSnapshot(const SkIRect *subset) override
bool onCopyOnWrite(ContentChangeMode) override
void onWritePixels(const SkPixmap &, int x, int y) override
SkImageInfo imageInfo() const override
TextureProxyView readSurfaceView() const
sk_sp< const SkCapabilities > onCapabilities() override
TextureProxy * backingTextureProxy() const
skgpu::Mipmapped mipmapped() const
static sk_sp< TextureProxy > Wrap(sk_sp< Texture >)
VkDevice device
Definition main.cc:53
VkSurfaceKHR surface
Definition main.cc:49
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
FlTexture * texture
double y
double x
void * ReleaseContext
SK_API sk_sp< SkImage > AsImage(sk_sp< const SkSurface >)
SK_API sk_sp< SkSurface > WrapBackendTexture(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, int sampleCnt, SkColorType colorType, sk_sp< SkColorSpace > colorSpace, const SkSurfaceProps *surfaceProps, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
void(*)(ReleaseContext) TextureReleaseProc
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
SK_API sk_sp< SkImage > AsImageCopy(sk_sp< const SkSurface >, const SkIRect *subset=nullptr, skgpu::Mipmapped=skgpu::Mipmapped::kNo)
void Flush(sk_sp< SkSurface > surface)
Budgeted
Definition GpuTypes.h:35
Mipmapped
Definition GpuTypes.h:53
Definition ref_ptr.h:256
int32_t height
int32_t width
static constexpr SkIRect MakeSize(const SkISize &size)
Definition SkRect.h:66