/src/skia/src/image/SkImage_Gpu.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2012 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 | | #include "src/image/SkImage_Gpu.h" |
9 | | |
10 | | #include "include/core/SkCanvas.h" |
11 | | #include "include/gpu/GrBackendSurface.h" |
12 | | #include "include/gpu/GrDirectContext.h" |
13 | | #include "include/gpu/GrRecordingContext.h" |
14 | | #include "include/gpu/GrYUVABackendTextures.h" |
15 | | #include "include/private/SkImageInfoPriv.h" |
16 | | #include "src/core/SkAutoPixmapStorage.h" |
17 | | #include "src/core/SkBitmapCache.h" |
18 | | #include "src/core/SkMipmap.h" |
19 | | #include "src/core/SkScopeExit.h" |
20 | | #include "src/core/SkTraceEvent.h" |
21 | | #include "src/gpu/GrAHardwareBufferImageGenerator.h" |
22 | | #include "src/gpu/GrAHardwareBufferUtils.h" |
23 | | #include "src/gpu/GrBackendTextureImageGenerator.h" |
24 | | #include "src/gpu/GrBackendUtils.h" |
25 | | #include "src/gpu/GrCaps.h" |
26 | | #include "src/gpu/GrColorSpaceXform.h" |
27 | | #include "src/gpu/GrContextThreadSafeProxyPriv.h" |
28 | | #include "src/gpu/GrDirectContextPriv.h" |
29 | | #include "src/gpu/GrDrawingManager.h" |
30 | | #include "src/gpu/GrGpu.h" |
31 | | #include "src/gpu/GrImageContextPriv.h" |
32 | | #include "src/gpu/GrImageInfo.h" |
33 | | #include "src/gpu/GrProxyProvider.h" |
34 | | #include "src/gpu/GrRecordingContextPriv.h" |
35 | | #include "src/gpu/GrSemaphore.h" |
36 | | #include "src/gpu/GrTexture.h" |
37 | | #include "src/gpu/GrTextureProxy.h" |
38 | | #include "src/gpu/GrTextureProxyPriv.h" |
39 | | #include "src/gpu/GrYUVATextureProxies.h" |
40 | | #include "src/gpu/SurfaceFillContext.h" |
41 | | #include "src/gpu/effects/GrTextureEffect.h" |
42 | | #include "src/gpu/gl/GrGLTexture.h" |
43 | | |
44 | | #include <cstddef> |
45 | | #include <cstring> |
46 | | #include <type_traits> |
47 | | |
48 | | inline SkImage_Gpu::ProxyChooser::ProxyChooser(sk_sp<GrSurfaceProxy> stableProxy) |
49 | 14.2k | : fStableProxy(std::move(stableProxy)) { |
50 | 14.2k | SkASSERT(fStableProxy); |
51 | 14.2k | } |
52 | | |
53 | | inline SkImage_Gpu::ProxyChooser::ProxyChooser(sk_sp<GrSurfaceProxy> stableProxy, |
54 | | sk_sp<GrSurfaceProxy> volatileProxy, |
55 | | sk_sp<GrRenderTask> copyTask, |
56 | | int volatileProxyTargetCount) |
57 | | : fStableProxy(std::move(stableProxy)) |
58 | | , fVolatileProxy(std::move(volatileProxy)) |
59 | | , fVolatileToStableCopyTask(std::move(copyTask)) |
60 | 0 | , fVolatileProxyTargetCount(volatileProxyTargetCount) { |
61 | 0 | SkASSERT(fStableProxy); |
62 | 0 | SkASSERT(fVolatileProxy); |
63 | 0 | SkASSERT(fVolatileToStableCopyTask); |
64 | 0 | } Unexecuted instantiation: SkImage_Gpu::ProxyChooser::ProxyChooser(sk_sp<GrSurfaceProxy>, sk_sp<GrSurfaceProxy>, sk_sp<GrRenderTask>, int) Unexecuted instantiation: SkImage_Gpu::ProxyChooser::ProxyChooser(sk_sp<GrSurfaceProxy>, sk_sp<GrSurfaceProxy>, sk_sp<GrRenderTask>, int) |
65 | | |
66 | 14.2k | inline SkImage_Gpu::ProxyChooser::~ProxyChooser() { |
67 | | // The image is being destroyed. If there is a stable copy proxy but we've been able to use |
68 | | // the volatile proxy for all requests then we can skip the copy. |
69 | 14.2k | if (fVolatileToStableCopyTask) { |
70 | 0 | fVolatileToStableCopyTask->makeSkippable(); |
71 | 0 | } |
72 | 14.2k | } |
73 | | |
74 | 14.2k | inline sk_sp<GrSurfaceProxy> SkImage_Gpu::ProxyChooser::chooseProxy(GrRecordingContext* context) { |
75 | 14.2k | SkAutoSpinlock hold(fLock); |
76 | 14.2k | if (fVolatileProxy) { |
77 | 0 | SkASSERT(fVolatileProxyTargetCount <= fVolatileProxy->getTaskTargetCount()); |
78 | | // If this image is used off the direct context it originated on, i.e. on a recording-only |
79 | | // context, we don't know how the recording context's actions are ordered WRT direct context |
80 | | // actions until the recording context's DAG is imported into the direct context. |
81 | 0 | if (context->asDirectContext() && |
82 | 0 | fVolatileProxyTargetCount == fVolatileProxy->getTaskTargetCount()) { |
83 | 0 | return fVolatileProxy; |
84 | 0 | } |
85 | 0 | fVolatileProxy.reset(); |
86 | 0 | fVolatileToStableCopyTask.reset(); |
87 | 0 | return fStableProxy; |
88 | 0 | } |
89 | 14.2k | return fStableProxy; |
90 | 14.2k | } |
91 | | |
92 | 0 | inline sk_sp<GrSurfaceProxy> SkImage_Gpu::ProxyChooser::switchToStableProxy() { |
93 | 0 | SkAutoSpinlock hold(fLock); |
94 | 0 | fVolatileProxy.reset(); |
95 | 0 | fVolatileToStableCopyTask.reset(); |
96 | 0 | return fStableProxy; |
97 | 0 | } |
98 | | |
99 | 15 | inline sk_sp<GrSurfaceProxy> SkImage_Gpu::ProxyChooser::makeVolatileProxyStable() { |
100 | 15 | SkAutoSpinlock hold(fLock); |
101 | 15 | if (fVolatileProxy) { |
102 | 0 | fStableProxy = std::move(fVolatileProxy); |
103 | 0 | fVolatileToStableCopyTask->makeSkippable(); |
104 | 0 | fVolatileToStableCopyTask.reset(); |
105 | 0 | } |
106 | 15 | return fStableProxy; |
107 | 15 | } |
108 | | |
109 | 0 | inline bool SkImage_Gpu::ProxyChooser::surfaceMustCopyOnWrite(GrSurfaceProxy* surfaceProxy) const { |
110 | 0 | SkAutoSpinlock hold(fLock); |
111 | 0 | return surfaceProxy->underlyingUniqueID() == fStableProxy->underlyingUniqueID(); |
112 | 0 | } |
113 | | |
114 | 0 | inline size_t SkImage_Gpu::ProxyChooser::gpuMemorySize() const { |
115 | 0 | SkAutoSpinlock hold(fLock); |
116 | 0 | size_t size = fStableProxy->gpuMemorySize(); |
117 | 0 | if (fVolatileProxy) { |
118 | 0 | SkASSERT(fVolatileProxy->gpuMemorySize() == size); |
119 | 0 | } |
120 | 0 | return size; |
121 | 0 | } Unexecuted instantiation: SkImage_Gpu::ProxyChooser::gpuMemorySize() const Unexecuted instantiation: SkImage_Gpu::ProxyChooser::gpuMemorySize() const |
122 | | |
123 | 0 | inline GrMipmapped SkImage_Gpu::ProxyChooser::mipmapped() const { |
124 | 0 | SkAutoSpinlock hold(fLock); |
125 | 0 | GrMipmapped mipmapped = fStableProxy->asTextureProxy()->mipmapped(); |
126 | 0 | if (fVolatileProxy) { |
127 | 0 | SkASSERT(fVolatileProxy->asTextureProxy()->mipmapped() == mipmapped); |
128 | 0 | } |
129 | 0 | return mipmapped; |
130 | 0 | } Unexecuted instantiation: SkImage_Gpu::ProxyChooser::mipmapped() const Unexecuted instantiation: SkImage_Gpu::ProxyChooser::mipmapped() const |
131 | | |
132 | | #ifdef SK_DEBUG |
133 | 0 | inline GrBackendFormat SkImage_Gpu::ProxyChooser::backendFormat() { |
134 | 0 | SkAutoSpinlock hold(fLock); |
135 | 0 | if (fVolatileProxy) { |
136 | 0 | SkASSERT(fVolatileProxy->backendFormat() == fStableProxy->backendFormat()); |
137 | 0 | } |
138 | 0 | return fStableProxy->backendFormat(); |
139 | 0 | } |
140 | | #endif |
141 | | |
142 | | ////////////////////////////////////////////////////////////////////////////// |
143 | | |
144 | | SkImage_Gpu::SkImage_Gpu(sk_sp<GrImageContext> context, |
145 | | uint32_t uniqueID, |
146 | | GrSurfaceProxyView view, |
147 | | SkColorInfo info) |
148 | | : INHERITED(std::move(context), |
149 | | SkImageInfo::Make(view.proxy()->backingStoreDimensions(), std::move(info)), |
150 | | uniqueID) |
151 | | , fChooser(view.detachProxy()) |
152 | | , fSwizzle(view.swizzle()) |
153 | 14.2k | , fOrigin(view.origin()) { |
154 | | #ifdef SK_DEBUG |
155 | | const GrBackendFormat& format = fChooser.backendFormat(); |
156 | | const GrCaps* caps = this->context()->priv().caps(); |
157 | | GrColorType grCT = SkColorTypeAndFormatToGrColorType(caps, this->colorType(), format); |
158 | | SkASSERT(caps->isFormatCompressed(format) || |
159 | | caps->areColorTypeAndFormatCompatible(grCT, format)); |
160 | | #endif |
161 | 14.2k | } |
162 | | |
163 | | SkImage_Gpu::SkImage_Gpu(sk_sp<GrDirectContext> dContext, |
164 | | GrSurfaceProxyView volatileSrc, |
165 | | sk_sp<GrSurfaceProxy> stableCopy, |
166 | | sk_sp<GrRenderTask> copyTask, |
167 | | int volatileSrcTargetCount, |
168 | | SkColorInfo info) |
169 | | : INHERITED(std::move(dContext), |
170 | | SkImageInfo::Make(volatileSrc.proxy()->backingStoreDimensions(), |
171 | | std::move(info)), |
172 | | kNeedNewImageUniqueID) |
173 | | , fChooser(std::move(stableCopy), |
174 | | volatileSrc.detachProxy(), |
175 | | std::move(copyTask), |
176 | | volatileSrcTargetCount) |
177 | | , fSwizzle(volatileSrc.swizzle()) |
178 | 0 | , fOrigin(volatileSrc.origin()) { |
179 | | #ifdef SK_DEBUG |
180 | | const GrBackendFormat& format = fChooser.backendFormat(); |
181 | | const GrCaps* caps = this->context()->priv().caps(); |
182 | | GrColorType grCT = SkColorTypeAndFormatToGrColorType(caps, this->colorType(), format); |
183 | 0 | SkASSERT(caps->isFormatCompressed(format) || |
184 | | caps->areColorTypeAndFormatCompatible(grCT, format)); |
185 | | #endif |
186 | 0 | } Unexecuted instantiation: SkImage_Gpu::SkImage_Gpu(sk_sp<GrDirectContext>, GrSurfaceProxyView, sk_sp<GrSurfaceProxy>, sk_sp<GrRenderTask>, int, SkColorInfo) Unexecuted instantiation: SkImage_Gpu::SkImage_Gpu(sk_sp<GrDirectContext>, GrSurfaceProxyView, sk_sp<GrSurfaceProxy>, sk_sp<GrRenderTask>, int, SkColorInfo) |
187 | | |
188 | | sk_sp<SkImage> SkImage_Gpu::MakeWithVolatileSrc(sk_sp<GrRecordingContext> rContext, |
189 | | GrSurfaceProxyView volatileSrc, |
190 | 0 | SkColorInfo colorInfo) { |
191 | 0 | SkASSERT(rContext); |
192 | 0 | SkASSERT(volatileSrc); |
193 | 0 | SkASSERT(volatileSrc.proxy()->asTextureProxy()); |
194 | 0 | GrMipmapped mm = volatileSrc.proxy()->asTextureProxy()->mipmapped(); |
195 | 0 | sk_sp<GrRenderTask> copyTask; |
196 | 0 | auto copy = GrSurfaceProxy::Copy(rContext.get(), |
197 | 0 | volatileSrc.refProxy(), |
198 | 0 | volatileSrc.origin(), |
199 | 0 | mm, |
200 | 0 | SkBackingFit::kExact, |
201 | 0 | SkBudgeted::kYes, |
202 | 0 | ©Task); |
203 | 0 | if (!copy) { |
204 | 0 | return nullptr; |
205 | 0 | } |
206 | | // We only attempt to make a dual-proxy image on a direct context. This optimziation requires |
207 | | // knowing how things are ordered and recording-only contexts are not well ordered WRT other |
208 | | // recording contexts. |
209 | 0 | if (auto direct = sk_ref_sp(rContext->asDirectContext())) { |
210 | 0 | int targetCount = volatileSrc.proxy()->getTaskTargetCount(); |
211 | 0 | return sk_sp<SkImage>(new SkImage_Gpu(std::move(direct), |
212 | 0 | std::move(volatileSrc), |
213 | 0 | std::move(copy), |
214 | 0 | std::move(copyTask), |
215 | 0 | targetCount, |
216 | 0 | std::move(colorInfo))); |
217 | 0 | } |
218 | 0 | GrSurfaceProxyView copyView(std::move(copy), volatileSrc.origin(), volatileSrc.swizzle()); |
219 | 0 | return sk_make_sp<SkImage_Gpu>(std::move(rContext), |
220 | 0 | kNeedNewImageUniqueID, |
221 | 0 | std::move(copyView), |
222 | 0 | std::move(colorInfo)); |
223 | 0 | } Unexecuted instantiation: SkImage_Gpu::MakeWithVolatileSrc(sk_sp<GrRecordingContext>, GrSurfaceProxyView, SkColorInfo) Unexecuted instantiation: SkImage_Gpu::MakeWithVolatileSrc(sk_sp<GrRecordingContext>, GrSurfaceProxyView, SkColorInfo) |
224 | | |
225 | 14.2k | SkImage_Gpu::~SkImage_Gpu() = default; |
226 | | |
227 | 0 | bool SkImage_Gpu::surfaceMustCopyOnWrite(GrSurfaceProxy* surfaceProxy) const { |
228 | 0 | return fChooser.surfaceMustCopyOnWrite(surfaceProxy); |
229 | 0 | } |
230 | | |
231 | 0 | bool SkImage_Gpu::onHasMipmaps() const { return fChooser.mipmapped() == GrMipmapped::kYes; } |
232 | | |
233 | 0 | GrSemaphoresSubmitted SkImage_Gpu::onFlush(GrDirectContext* dContext, const GrFlushInfo& info) { |
234 | 0 | if (!fContext->priv().matches(dContext) || dContext->abandoned()) { |
235 | 0 | if (info.fSubmittedProc) { |
236 | 0 | info.fSubmittedProc(info.fSubmittedContext, false); |
237 | 0 | } |
238 | 0 | if (info.fFinishedProc) { |
239 | 0 | info.fFinishedProc(info.fFinishedContext); |
240 | 0 | } |
241 | 0 | return GrSemaphoresSubmitted::kNo; |
242 | 0 | } |
243 | | |
244 | 0 | sk_sp<GrSurfaceProxy> proxy = fChooser.chooseProxy(dContext); |
245 | 0 | return dContext->priv().flushSurface(proxy.get(), |
246 | 0 | SkSurface::BackendSurfaceAccess::kNoAccess, |
247 | 0 | info); |
248 | 0 | } |
249 | | |
250 | | GrBackendTexture SkImage_Gpu::onGetBackendTexture(bool flushPendingGrContextIO, |
251 | 0 | GrSurfaceOrigin* origin) const { |
252 | 0 | auto direct = fContext->asDirectContext(); |
253 | 0 | if (!direct) { |
254 | | // This image was created with a DDL context and cannot be instantiated. |
255 | 0 | return GrBackendTexture(); // invalid |
256 | 0 | } |
257 | 0 | if (direct->abandoned()) { |
258 | 0 | return GrBackendTexture(); // invalid; |
259 | 0 | } |
260 | | |
261 | | // We don't know how client's use of the texture will be ordered WRT Skia's. Ensure the |
262 | | // texture seen by the client won't be mutated by a SkSurface. |
263 | 0 | sk_sp<GrSurfaceProxy> proxy = fChooser.switchToStableProxy(); |
264 | |
|
265 | 0 | if (!proxy->isInstantiated()) { |
266 | 0 | auto resourceProvider = direct->priv().resourceProvider(); |
267 | |
|
268 | 0 | if (!proxy->instantiate(resourceProvider)) { |
269 | 0 | return GrBackendTexture(); // invalid |
270 | 0 | } |
271 | 0 | } |
272 | | |
273 | 0 | GrTexture* texture = proxy->peekTexture(); |
274 | 0 | if (texture) { |
275 | 0 | if (flushPendingGrContextIO) { |
276 | 0 | direct->priv().flushSurface(proxy.get()); |
277 | 0 | } |
278 | 0 | if (origin) { |
279 | 0 | *origin = fOrigin; |
280 | 0 | } |
281 | 0 | return texture->getBackendTexture(); |
282 | 0 | } |
283 | 0 | return GrBackendTexture(); // invalid |
284 | 0 | } |
285 | | |
286 | 0 | size_t SkImage_Gpu::onTextureSize() const { return fChooser.gpuMemorySize(); } |
287 | | |
288 | | sk_sp<SkImage> SkImage_Gpu::onMakeColorTypeAndColorSpace(SkColorType targetCT, |
289 | | sk_sp<SkColorSpace> targetCS, |
290 | 0 | GrDirectContext* dContext) const { |
291 | 0 | SkColorInfo info(targetCT, this->alphaType(), std::move(targetCS)); |
292 | 0 | if (!fContext->priv().matches(dContext)) { |
293 | 0 | return nullptr; |
294 | 0 | } |
295 | | |
296 | 0 | auto sfc = dContext->priv().makeSFCWithFallback(GrImageInfo(info, this->dimensions()), |
297 | 0 | SkBackingFit::kExact); |
298 | 0 | if (!sfc) { |
299 | 0 | return nullptr; |
300 | 0 | } |
301 | | // We respecify info's CT because we called MakeWithFallback. |
302 | 0 | auto ct = GrColorTypeToSkColorType(sfc->colorInfo().colorType()); |
303 | 0 | info = info.makeColorType(ct); |
304 | | |
305 | | // Draw this image's texture into the SFC. |
306 | 0 | auto [view, _] = this->asView(dContext, GrMipmapped(this->hasMipmaps())); |
307 | 0 | auto texFP = GrTextureEffect::Make(std::move(view), this->alphaType()); |
308 | 0 | auto colorFP = GrColorSpaceXformEffect::Make(std::move(texFP), |
309 | 0 | this->imageInfo().colorInfo(), |
310 | 0 | info); |
311 | 0 | sfc->fillWithFP(std::move(colorFP)); |
312 | |
|
313 | 0 | return sk_make_sp<SkImage_Gpu>(sk_ref_sp(dContext), |
314 | 0 | kNeedNewImageUniqueID, |
315 | 0 | sfc->readSurfaceView(), |
316 | 0 | std::move(info)); |
317 | 0 | } |
318 | | |
319 | 0 | sk_sp<SkImage> SkImage_Gpu::onReinterpretColorSpace(sk_sp<SkColorSpace> newCS) const { |
320 | | // It doesn't seem worth the complexity of trying to share the ProxyChooser among multiple |
321 | | // images. Just fall back to the stable copy. |
322 | 0 | GrSurfaceProxyView view(fChooser.switchToStableProxy(), fOrigin, fSwizzle); |
323 | 0 | return sk_make_sp<SkImage_Gpu>(fContext, |
324 | 0 | kNeedNewImageUniqueID, |
325 | 0 | std::move(view), |
326 | 0 | this->imageInfo().colorInfo().makeColorSpace(std::move(newCS))); |
327 | 0 | } |
328 | | |
329 | | void SkImage_Gpu::onAsyncRescaleAndReadPixels(const SkImageInfo& info, |
330 | | const SkIRect& srcRect, |
331 | | RescaleGamma rescaleGamma, |
332 | | RescaleMode rescaleMode, |
333 | | ReadPixelsCallback callback, |
334 | 0 | ReadPixelsContext context) { |
335 | 0 | auto dContext = fContext->asDirectContext(); |
336 | 0 | if (!dContext) { |
337 | | // DDL TODO: buffer up the readback so it occurs when the DDL is drawn? |
338 | 0 | callback(context, nullptr); |
339 | 0 | return; |
340 | 0 | } |
341 | 0 | auto ctx = dContext->priv().makeSC(this->makeView(dContext), this->imageInfo().colorInfo()); |
342 | 0 | if (!ctx) { |
343 | 0 | callback(context, nullptr); |
344 | 0 | return; |
345 | 0 | } |
346 | 0 | ctx->asyncRescaleAndReadPixels(dContext, info, srcRect, rescaleGamma, rescaleMode, |
347 | 0 | callback, context); |
348 | 0 | } |
349 | | |
350 | | void SkImage_Gpu::onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace, |
351 | | sk_sp<SkColorSpace> dstColorSpace, |
352 | | const SkIRect& srcRect, |
353 | | const SkISize& dstSize, |
354 | | RescaleGamma rescaleGamma, |
355 | | RescaleMode rescaleMode, |
356 | | ReadPixelsCallback callback, |
357 | 0 | ReadPixelsContext context) { |
358 | 0 | auto dContext = fContext->asDirectContext(); |
359 | 0 | if (!dContext) { |
360 | | // DDL TODO: buffer up the readback so it occurs when the DDL is drawn? |
361 | 0 | callback(context, nullptr); |
362 | 0 | return; |
363 | 0 | } |
364 | 0 | auto ctx = dContext->priv().makeSC(this->makeView(dContext), this->imageInfo().colorInfo()); |
365 | 0 | if (!ctx) { |
366 | 0 | callback(context, nullptr); |
367 | 0 | return; |
368 | 0 | } |
369 | 0 | ctx->asyncRescaleAndReadPixelsYUV420(dContext, |
370 | 0 | yuvColorSpace, |
371 | 0 | std::move(dstColorSpace), |
372 | 0 | srcRect, |
373 | 0 | dstSize, |
374 | 0 | rescaleGamma, |
375 | 0 | rescaleMode, |
376 | 0 | callback, |
377 | 0 | context); |
378 | 0 | } |
379 | | |
380 | 15 | void SkImage_Gpu::generatingSurfaceIsDeleted() { fChooser.makeVolatileProxyStable(); } |
381 | | |
382 | | /////////////////////////////////////////////////////////////////////////////////////////////////// |
383 | | |
384 | | static sk_sp<SkImage> new_wrapped_texture_common(GrRecordingContext* rContext, |
385 | | const GrBackendTexture& backendTex, |
386 | | GrColorType colorType, |
387 | | GrSurfaceOrigin origin, |
388 | | SkAlphaType at, |
389 | | sk_sp<SkColorSpace> colorSpace, |
390 | | GrWrapOwnership ownership, |
391 | 0 | sk_sp<GrRefCntedCallback> releaseHelper) { |
392 | 0 | if (!backendTex.isValid() || backendTex.width() <= 0 || backendTex.height() <= 0) { |
393 | 0 | return nullptr; |
394 | 0 | } |
395 | | |
396 | 0 | GrProxyProvider* proxyProvider = rContext->priv().proxyProvider(); |
397 | 0 | sk_sp<GrTextureProxy> proxy = proxyProvider->wrapBackendTexture( |
398 | 0 | backendTex, ownership, GrWrapCacheable::kNo, kRead_GrIOType, std::move(releaseHelper)); |
399 | 0 | if (!proxy) { |
400 | 0 | return nullptr; |
401 | 0 | } |
402 | | |
403 | 0 | GrSwizzle swizzle = rContext->priv().caps()->getReadSwizzle(proxy->backendFormat(), colorType); |
404 | 0 | GrSurfaceProxyView view(std::move(proxy), origin, swizzle); |
405 | 0 | SkColorInfo info(GrColorTypeToSkColorType(colorType), at, std::move(colorSpace)); |
406 | 0 | return sk_make_sp<SkImage_Gpu>(sk_ref_sp(rContext), |
407 | 0 | kNeedNewImageUniqueID, |
408 | 0 | std::move(view), |
409 | 0 | std::move(info)); |
410 | 0 | } |
411 | | |
412 | | sk_sp<SkImage> SkImage::MakeFromCompressedTexture(GrRecordingContext* rContext, |
413 | | const GrBackendTexture& tex, |
414 | | GrSurfaceOrigin origin, |
415 | | SkAlphaType at, |
416 | | sk_sp<SkColorSpace> cs, |
417 | | TextureReleaseProc releaseP, |
418 | 0 | ReleaseContext releaseC) { |
419 | 0 | auto releaseHelper = GrRefCntedCallback::Make(releaseP, releaseC); |
420 | |
|
421 | 0 | if (!rContext) { |
422 | 0 | return nullptr; |
423 | 0 | } |
424 | | |
425 | 0 | const GrCaps* caps = rContext->priv().caps(); |
426 | |
|
427 | 0 | if (!SkImage_GpuBase::ValidateCompressedBackendTexture(caps, tex, at)) { |
428 | 0 | return nullptr; |
429 | 0 | } |
430 | | |
431 | 0 | GrProxyProvider* proxyProvider = rContext->priv().proxyProvider(); |
432 | 0 | sk_sp<GrTextureProxy> proxy = proxyProvider->wrapCompressedBackendTexture( |
433 | 0 | tex, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, std::move(releaseHelper)); |
434 | 0 | if (!proxy) { |
435 | 0 | return nullptr; |
436 | 0 | } |
437 | | |
438 | 0 | CompressionType type = GrBackendFormatToCompressionType(tex.getBackendFormat()); |
439 | 0 | SkColorType ct = GrCompressionTypeToSkColorType(type); |
440 | |
|
441 | 0 | GrSurfaceProxyView view(std::move(proxy), origin, GrSwizzle::RGBA()); |
442 | 0 | return sk_make_sp<SkImage_Gpu>(sk_ref_sp(rContext), |
443 | 0 | kNeedNewImageUniqueID, |
444 | 0 | std::move(view), |
445 | 0 | SkColorInfo(ct, at, std::move(cs))); |
446 | 0 | } |
447 | | |
448 | | sk_sp<SkImage> SkImage::MakeFromTexture(GrRecordingContext* rContext, |
449 | | const GrBackendTexture& tex, GrSurfaceOrigin origin, |
450 | | SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs, |
451 | 0 | TextureReleaseProc releaseP, ReleaseContext releaseC) { |
452 | 0 | auto releaseHelper = GrRefCntedCallback::Make(releaseP, releaseC); |
453 | |
|
454 | 0 | if (!rContext) { |
455 | 0 | return nullptr; |
456 | 0 | } |
457 | | |
458 | 0 | const GrCaps* caps = rContext->priv().caps(); |
459 | |
|
460 | 0 | GrColorType grColorType = SkColorTypeAndFormatToGrColorType(caps, ct, tex.getBackendFormat()); |
461 | 0 | if (GrColorType::kUnknown == grColorType) { |
462 | 0 | return nullptr; |
463 | 0 | } |
464 | | |
465 | 0 | if (!SkImage_GpuBase::ValidateBackendTexture(caps, tex, grColorType, ct, at, cs)) { |
466 | 0 | return nullptr; |
467 | 0 | } |
468 | | |
469 | 0 | return new_wrapped_texture_common(rContext, tex, grColorType, origin, at, std::move(cs), |
470 | 0 | kBorrow_GrWrapOwnership, std::move(releaseHelper)); |
471 | 0 | } |
472 | | |
473 | | sk_sp<SkImage> SkImage::MakeFromAdoptedTexture(GrRecordingContext* rContext, |
474 | | const GrBackendTexture& tex, GrSurfaceOrigin origin, |
475 | | SkColorType ct, SkAlphaType at, |
476 | 0 | sk_sp<SkColorSpace> cs) { |
477 | 0 | auto dContext = GrAsDirectContext(rContext); |
478 | 0 | if (!dContext) { |
479 | | // We have a DDL context and we don't support adopted textures for them. |
480 | 0 | return nullptr; |
481 | 0 | } |
482 | | |
483 | 0 | const GrCaps* caps = dContext->priv().caps(); |
484 | |
|
485 | 0 | GrColorType grColorType = SkColorTypeAndFormatToGrColorType(caps, ct, tex.getBackendFormat()); |
486 | 0 | if (GrColorType::kUnknown == grColorType) { |
487 | 0 | return nullptr; |
488 | 0 | } |
489 | | |
490 | 0 | if (!SkImage_GpuBase::ValidateBackendTexture(caps, tex, grColorType, ct, at, cs)) { |
491 | 0 | return nullptr; |
492 | 0 | } |
493 | | |
494 | 0 | return new_wrapped_texture_common(dContext, tex, grColorType, origin, at, std::move(cs), |
495 | 0 | kAdopt_GrWrapOwnership, nullptr); |
496 | 0 | } |
497 | | |
498 | | sk_sp<SkImage> SkImage::MakeTextureFromCompressed(GrDirectContext* direct, sk_sp<SkData> data, |
499 | | int width, int height, CompressionType type, |
500 | | GrMipmapped mipMapped, |
501 | 0 | GrProtected isProtected) { |
502 | 0 | if (!direct || !data) { |
503 | 0 | return nullptr; |
504 | 0 | } |
505 | | |
506 | 0 | GrBackendFormat beFormat = direct->compressedBackendFormat(type); |
507 | 0 | if (!beFormat.isValid()) { |
508 | 0 | sk_sp<SkImage> tmp = MakeRasterFromCompressed(std::move(data), width, height, type); |
509 | 0 | if (!tmp) { |
510 | 0 | return nullptr; |
511 | 0 | } |
512 | 0 | return tmp->makeTextureImage(direct, mipMapped); |
513 | 0 | } |
514 | | |
515 | 0 | GrProxyProvider* proxyProvider = direct->priv().proxyProvider(); |
516 | 0 | sk_sp<GrTextureProxy> proxy = proxyProvider->createCompressedTextureProxy( |
517 | 0 | {width, height}, SkBudgeted::kYes, mipMapped, isProtected, type, std::move(data)); |
518 | 0 | if (!proxy) { |
519 | 0 | return nullptr; |
520 | 0 | } |
521 | 0 | GrSurfaceProxyView view(std::move(proxy)); |
522 | |
|
523 | 0 | SkColorType colorType = GrCompressionTypeToSkColorType(type); |
524 | |
|
525 | 0 | return sk_make_sp<SkImage_Gpu>(sk_ref_sp(direct), |
526 | 0 | kNeedNewImageUniqueID, |
527 | 0 | std::move(view), |
528 | 0 | SkColorInfo(colorType, kOpaque_SkAlphaType, nullptr)); |
529 | 0 | } |
530 | | |
531 | | sk_sp<SkImage> SkImage::makeTextureImage(GrDirectContext* dContext, |
532 | | GrMipmapped mipmapped, |
533 | 0 | SkBudgeted budgeted) const { |
534 | 0 | if (!dContext) { |
535 | 0 | return nullptr; |
536 | 0 | } |
537 | 0 | if (!dContext->priv().caps()->mipmapSupport() || this->dimensions().area() <= 1) { |
538 | 0 | mipmapped = GrMipmapped::kNo; |
539 | 0 | } |
540 | |
|
541 | 0 | if (this->isTextureBacked()) { |
542 | 0 | if (!as_IB(this)->context()->priv().matches(dContext)) { |
543 | 0 | return nullptr; |
544 | 0 | } |
545 | | |
546 | 0 | if (this->isTextureBacked() && (mipmapped == GrMipmapped::kNo || this->hasMipmaps())) { |
547 | 0 | return sk_ref_sp(const_cast<SkImage*>(this)); |
548 | 0 | } |
549 | 0 | } |
550 | 0 | GrImageTexGenPolicy policy = budgeted == SkBudgeted::kYes |
551 | 0 | ? GrImageTexGenPolicy::kNew_Uncached_Budgeted |
552 | 0 | : GrImageTexGenPolicy::kNew_Uncached_Unbudgeted; |
553 | | // TODO: Don't flatten YUVA images here. Add mips to the planes instead. |
554 | 0 | auto [view, ct] = as_IB(this)->asView(dContext, mipmapped, policy); |
555 | 0 | if (!view) { |
556 | 0 | return nullptr; |
557 | 0 | } |
558 | 0 | SkASSERT(view.asTextureProxy()); |
559 | 0 | SkASSERT(mipmapped == GrMipmapped::kNo || |
560 | 0 | view.asTextureProxy()->mipmapped() == GrMipmapped::kYes); |
561 | 0 | SkColorInfo colorInfo(GrColorTypeToSkColorType(ct), this->alphaType(), this->refColorSpace()); |
562 | 0 | return sk_make_sp<SkImage_Gpu>(sk_ref_sp(dContext), |
563 | 0 | this->uniqueID(), |
564 | 0 | std::move(view), |
565 | 0 | std::move(colorInfo)); |
566 | 0 | } Unexecuted instantiation: SkImage::makeTextureImage(GrDirectContext*, GrMipmapped, SkBudgeted) const Unexecuted instantiation: SkImage::makeTextureImage(GrDirectContext*, GrMipmapped, SkBudgeted) const |
567 | | |
568 | | /////////////////////////////////////////////////////////////////////////////////////////////////// |
569 | | |
570 | | sk_sp<SkImage> SkImage::MakePromiseTexture(sk_sp<GrContextThreadSafeProxy> threadSafeProxy, |
571 | | const GrBackendFormat& backendFormat, |
572 | | SkISize dimensions, |
573 | | GrMipmapped mipMapped, |
574 | | GrSurfaceOrigin origin, |
575 | | SkColorType colorType, |
576 | | SkAlphaType alphaType, |
577 | | sk_sp<SkColorSpace> colorSpace, |
578 | | PromiseImageTextureFulfillProc textureFulfillProc, |
579 | | PromiseImageTextureReleaseProc textureReleaseProc, |
580 | 0 | PromiseImageTextureContext textureContext) { |
581 | | // Our contract is that we will always call the release proc even on failure. |
582 | | // We use the helper to convey the context, so we need to ensure make doesn't fail. |
583 | 0 | textureReleaseProc = textureReleaseProc ? textureReleaseProc : [](void*) {}; Unexecuted instantiation: SkImage_Gpu.cpp:SkImage::MakePromiseTexture(sk_sp<GrContextThreadSafeProxy>, GrBackendFormat const&, SkISize, GrMipmapped, GrSurfaceOrigin, SkColorType, SkAlphaType, sk_sp<SkColorSpace>, sk_sp<SkPromiseImageTexture> (*)(void*), void (*)(void*), void*)::$_1::operator()(void*) const Unexecuted instantiation: SkImage_Gpu.cpp:SkImage::MakePromiseTexture(sk_sp<GrContextThreadSafeProxy>, GrBackendFormat const&, SkISize, GrMipmapped, GrSurfaceOrigin, SkColorType, SkAlphaType, sk_sp<SkColorSpace>, sk_sp<SkPromiseImageTexture> (*)(void*), void (*)(void*), void*)::$_8::operator()(void*) const |
584 | 0 | auto releaseHelper = GrRefCntedCallback::Make(textureReleaseProc, textureContext); |
585 | 0 | SkImageInfo info = SkImageInfo::Make(dimensions, colorType, alphaType, colorSpace); |
586 | 0 | if (!SkImageInfoIsValid(info)) { |
587 | 0 | return nullptr; |
588 | 0 | } |
589 | | |
590 | 0 | if (!threadSafeProxy) { |
591 | 0 | return nullptr; |
592 | 0 | } |
593 | | |
594 | 0 | if (dimensions.isEmpty()) { |
595 | 0 | return nullptr; |
596 | 0 | } |
597 | | |
598 | 0 | GrColorType grColorType = SkColorTypeAndFormatToGrColorType(threadSafeProxy->priv().caps(), |
599 | 0 | colorType, |
600 | 0 | backendFormat); |
601 | 0 | if (GrColorType::kUnknown == grColorType) { |
602 | 0 | return nullptr; |
603 | 0 | } |
604 | | |
605 | 0 | if (!threadSafeProxy->priv().caps()->areColorTypeAndFormatCompatible(grColorType, |
606 | 0 | backendFormat)) { |
607 | 0 | return nullptr; |
608 | 0 | } |
609 | | |
610 | 0 | auto proxy = SkImage_GpuBase::MakePromiseImageLazyProxy(threadSafeProxy.get(), |
611 | 0 | dimensions, |
612 | 0 | backendFormat, |
613 | 0 | mipMapped, |
614 | 0 | textureFulfillProc, |
615 | 0 | std::move(releaseHelper)); |
616 | 0 | if (!proxy) { |
617 | 0 | return nullptr; |
618 | 0 | } |
619 | 0 | GrSwizzle swizzle = threadSafeProxy->priv().caps()->getReadSwizzle(backendFormat, grColorType); |
620 | 0 | GrSurfaceProxyView view(std::move(proxy), origin, swizzle); |
621 | 0 | sk_sp<GrImageContext> ctx(GrImageContextPriv::MakeForPromiseImage(std::move(threadSafeProxy))); |
622 | 0 | return sk_make_sp<SkImage_Gpu>(std::move(ctx), |
623 | 0 | kNeedNewImageUniqueID, |
624 | 0 | std::move(view), |
625 | 0 | SkColorInfo(colorType, alphaType, std::move(colorSpace))); |
626 | 0 | } |
627 | | |
628 | | /////////////////////////////////////////////////////////////////////////////////////////////////// |
629 | | |
630 | | sk_sp<SkImage> SkImage::MakeCrossContextFromPixmap(GrDirectContext* dContext, |
631 | | const SkPixmap& originalPixmap, bool buildMips, |
632 | 0 | bool limitToMaxTextureSize) { |
633 | | // Some backends or drivers don't support (safely) moving resources between contexts |
634 | 0 | if (!dContext || !dContext->priv().caps()->crossContextTextureSupport()) { |
635 | 0 | return SkImage::MakeRasterCopy(originalPixmap); |
636 | 0 | } |
637 | | |
638 | | // If non-power-of-two mipmapping isn't supported, ignore the client's request |
639 | 0 | if (!dContext->priv().caps()->mipmapSupport()) { |
640 | 0 | buildMips = false; |
641 | 0 | } |
642 | |
|
643 | 0 | const SkPixmap* pixmap = &originalPixmap; |
644 | 0 | SkAutoPixmapStorage resized; |
645 | 0 | int maxTextureSize = dContext->priv().caps()->maxTextureSize(); |
646 | 0 | int maxDim = std::max(originalPixmap.width(), originalPixmap.height()); |
647 | 0 | if (limitToMaxTextureSize && maxDim > maxTextureSize) { |
648 | 0 | float scale = static_cast<float>(maxTextureSize) / maxDim; |
649 | 0 | int newWidth = std::min(static_cast<int>(originalPixmap.width() * scale), maxTextureSize); |
650 | 0 | int newHeight = std::min(static_cast<int>(originalPixmap.height() * scale), maxTextureSize); |
651 | 0 | SkImageInfo info = originalPixmap.info().makeWH(newWidth, newHeight); |
652 | 0 | SkSamplingOptions sampling(SkFilterMode::kLinear); |
653 | 0 | if (!resized.tryAlloc(info) || !originalPixmap.scalePixels(resized, sampling)) { |
654 | 0 | return nullptr; |
655 | 0 | } |
656 | 0 | pixmap = &resized; |
657 | 0 | } |
658 | | // Turn the pixmap into a GrTextureProxy |
659 | 0 | SkBitmap bmp; |
660 | 0 | bmp.installPixels(*pixmap); |
661 | 0 | GrMipmapped mipmapped = buildMips ? GrMipmapped::kYes : GrMipmapped::kNo; |
662 | 0 | auto [view, ct] = GrMakeUncachedBitmapProxyView(dContext, bmp, mipmapped); |
663 | 0 | if (!view) { |
664 | 0 | return SkImage::MakeRasterCopy(*pixmap); |
665 | 0 | } |
666 | | |
667 | 0 | sk_sp<GrTexture> texture = sk_ref_sp(view.proxy()->peekTexture()); |
668 | | |
669 | | // Flush any writes or uploads |
670 | 0 | dContext->priv().flushSurface(view.proxy()); |
671 | 0 | GrGpu* gpu = dContext->priv().getGpu(); |
672 | |
|
673 | 0 | std::unique_ptr<GrSemaphore> sema = gpu->prepareTextureForCrossContextUsage(texture.get()); |
674 | |
|
675 | 0 | SkColorType skCT = GrColorTypeToSkColorType(ct); |
676 | 0 | auto gen = GrBackendTextureImageGenerator::Make(std::move(texture), view.origin(), |
677 | 0 | std::move(sema), skCT, |
678 | 0 | pixmap->alphaType(), |
679 | 0 | pixmap->info().refColorSpace()); |
680 | 0 | return SkImage::MakeFromGenerator(std::move(gen)); |
681 | 0 | } |
682 | | |
683 | | #if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26 |
684 | | sk_sp<SkImage> SkImage::MakeFromAHardwareBuffer(AHardwareBuffer* graphicBuffer, SkAlphaType at, |
685 | | sk_sp<SkColorSpace> cs, |
686 | | GrSurfaceOrigin surfaceOrigin) { |
687 | | auto gen = GrAHardwareBufferImageGenerator::Make(graphicBuffer, at, cs, surfaceOrigin); |
688 | | return SkImage::MakeFromGenerator(std::move(gen)); |
689 | | } |
690 | | |
691 | | sk_sp<SkImage> SkImage::MakeFromAHardwareBufferWithData(GrDirectContext* dContext, |
692 | | const SkPixmap& pixmap, |
693 | | AHardwareBuffer* hardwareBuffer, |
694 | | GrSurfaceOrigin surfaceOrigin) { |
695 | | AHardwareBuffer_Desc bufferDesc; |
696 | | AHardwareBuffer_describe(hardwareBuffer, &bufferDesc); |
697 | | |
698 | | if (!SkToBool(bufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE)) { |
699 | | return nullptr; |
700 | | } |
701 | | |
702 | | |
703 | | GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat(dContext, |
704 | | hardwareBuffer, |
705 | | bufferDesc.format, |
706 | | true); |
707 | | |
708 | | if (!backendFormat.isValid()) { |
709 | | return nullptr; |
710 | | } |
711 | | |
712 | | GrAHardwareBufferUtils::DeleteImageProc deleteImageProc = nullptr; |
713 | | GrAHardwareBufferUtils::UpdateImageProc updateImageProc = nullptr; |
714 | | GrAHardwareBufferUtils::TexImageCtx deleteImageCtx = nullptr; |
715 | | |
716 | | const bool isRenderable = SkToBool(bufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER); |
717 | | |
718 | | GrBackendTexture backendTexture = |
719 | | GrAHardwareBufferUtils::MakeBackendTexture(dContext, hardwareBuffer, |
720 | | bufferDesc.width, bufferDesc.height, |
721 | | &deleteImageProc, &updateImageProc, |
722 | | &deleteImageCtx, false, backendFormat, |
723 | | isRenderable); |
724 | | if (!backendTexture.isValid()) { |
725 | | return nullptr; |
726 | | } |
727 | | SkASSERT(deleteImageProc); |
728 | | |
729 | | auto releaseHelper = GrRefCntedCallback::Make(deleteImageProc, deleteImageCtx); |
730 | | |
731 | | SkColorType colorType = |
732 | | GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(bufferDesc.format); |
733 | | |
734 | | GrColorType grColorType = SkColorTypeToGrColorType(colorType); |
735 | | |
736 | | GrProxyProvider* proxyProvider = dContext->priv().proxyProvider(); |
737 | | if (!proxyProvider) { |
738 | | return nullptr; |
739 | | } |
740 | | |
741 | | sk_sp<GrTextureProxy> proxy = proxyProvider->wrapBackendTexture( |
742 | | backendTexture, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRW_GrIOType, |
743 | | std::move(releaseHelper)); |
744 | | if (!proxy) { |
745 | | return nullptr; |
746 | | } |
747 | | |
748 | | GrSwizzle swizzle = dContext->priv().caps()->getReadSwizzle(backendFormat, grColorType); |
749 | | GrSurfaceProxyView framebufferView(std::move(proxy), surfaceOrigin, swizzle); |
750 | | SkColorInfo colorInfo = pixmap.info().colorInfo().makeColorType(colorType); |
751 | | sk_sp<SkImage> image = sk_make_sp<SkImage_Gpu>(sk_ref_sp(dContext), |
752 | | kNeedNewImageUniqueID, |
753 | | framebufferView, |
754 | | std::move(colorInfo)); |
755 | | if (!image) { |
756 | | return nullptr; |
757 | | } |
758 | | |
759 | | GrDrawingManager* drawingManager = dContext->priv().drawingManager(); |
760 | | if (!drawingManager) { |
761 | | return nullptr; |
762 | | } |
763 | | |
764 | | skgpu::SurfaceContext surfaceContext( |
765 | | dContext, std::move(framebufferView),image->imageInfo().colorInfo()); |
766 | | |
767 | | surfaceContext.writePixels(dContext, pixmap, {0, 0}); |
768 | | |
769 | | GrSurfaceProxy* p[1] = {surfaceContext.asSurfaceProxy()}; |
770 | | drawingManager->flush(SkMakeSpan(p), SkSurface::BackendSurfaceAccess::kNoAccess, {}, nullptr); |
771 | | |
772 | | return image; |
773 | | } |
774 | | #endif |
775 | | |
776 | | /////////////////////////////////////////////////////////////////////////////////////////////////// |
777 | | |
778 | | bool SkImage::MakeBackendTextureFromSkImage(GrDirectContext* direct, |
779 | | sk_sp<SkImage> image, |
780 | | GrBackendTexture* backendTexture, |
781 | 0 | BackendTextureReleaseProc* releaseProc) { |
782 | 0 | if (!image || !backendTexture || !releaseProc) { |
783 | 0 | return false; |
784 | 0 | } |
785 | | |
786 | 0 | auto [view, ct] = as_IB(image)->asView(direct, GrMipmapped::kNo); |
787 | |
|
788 | 0 | if (!view) { |
789 | 0 | return false; |
790 | 0 | } |
791 | | |
792 | | // Flush any pending IO on the texture. |
793 | 0 | direct->priv().flushSurface(view.proxy()); |
794 | |
|
795 | 0 | GrTexture* texture = view.asTextureProxy()->peekTexture(); |
796 | 0 | if (!texture) { |
797 | 0 | return false; |
798 | 0 | } |
799 | | // We must make a copy of the image if the image is not unique, if the GrTexture owned by the |
800 | | // image is not unique, or if the texture wraps an external object. |
801 | 0 | if (!image->unique() || !texture->unique() || |
802 | 0 | texture->resourcePriv().refsWrappedObjects()) { |
803 | | // onMakeSubset will always copy the image. |
804 | 0 | image = as_IB(image)->onMakeSubset(image->bounds(), direct); |
805 | 0 | if (!image) { |
806 | 0 | return false; |
807 | 0 | } |
808 | 0 | return MakeBackendTextureFromSkImage(direct, std::move(image), backendTexture, releaseProc); |
809 | 0 | } |
810 | | |
811 | 0 | SkASSERT(!texture->resourcePriv().refsWrappedObjects()); |
812 | 0 | SkASSERT(texture->unique()); |
813 | 0 | SkASSERT(image->unique()); |
814 | | |
815 | | // Take a reference to the GrTexture and release the image. |
816 | 0 | sk_sp<GrTexture> textureRef = sk_ref_sp(texture); |
817 | 0 | view.reset(); |
818 | 0 | image = nullptr; |
819 | 0 | SkASSERT(textureRef->unique()); |
820 | | |
821 | | // Steal the backend texture from the GrTexture, releasing the GrTexture in the process. |
822 | 0 | return GrTexture::StealBackendTexture(std::move(textureRef), backendTexture, releaseProc); |
823 | 0 | } Unexecuted instantiation: SkImage::MakeBackendTextureFromSkImage(GrDirectContext*, sk_sp<SkImage>, GrBackendTexture*, std::__1::function<void (GrBackendTexture)>*) Unexecuted instantiation: SkImage::MakeBackendTextureFromSkImage(GrDirectContext*, sk_sp<SkImage>, GrBackendTexture*, std::__1::function<void (GrBackendTexture)>*) |
824 | | |
825 | | std::tuple<GrSurfaceProxyView, GrColorType> SkImage_Gpu::onAsView( |
826 | | GrRecordingContext* recordingContext, |
827 | | GrMipmapped mipmapped, |
828 | 14.2k | GrImageTexGenPolicy policy) const { |
829 | 14.2k | if (!fContext->priv().matches(recordingContext)) { |
830 | 0 | return {}; |
831 | 0 | } |
832 | 14.2k | if (policy != GrImageTexGenPolicy::kDraw) { |
833 | 0 | return {CopyView(recordingContext, this->makeView(recordingContext), mipmapped, policy), |
834 | 0 | SkColorTypeToGrColorType(this->colorType())}; |
835 | 0 | } |
836 | 14.2k | GrSurfaceProxyView view = this->makeView(recordingContext); |
837 | 14.2k | GrColorType ct = SkColorTypeAndFormatToGrColorType(recordingContext->priv().caps(), |
838 | 14.2k | this->colorType(), |
839 | 14.2k | view.proxy()->backendFormat()); |
840 | 14.2k | if (mipmapped == GrMipmapped::kYes) { |
841 | 0 | view = FindOrMakeCachedMipmappedView(recordingContext, std::move(view), this->uniqueID()); |
842 | 0 | } |
843 | 14.2k | return {std::move(view), ct}; |
844 | 14.2k | } |
845 | | |
846 | | std::unique_ptr<GrFragmentProcessor> SkImage_Gpu::onAsFragmentProcessor( |
847 | | GrRecordingContext* rContext, |
848 | | SkSamplingOptions sampling, |
849 | | const SkTileMode tileModes[2], |
850 | | const SkMatrix& m, |
851 | | const SkRect* subset, |
852 | 1.79k | const SkRect* domain) const { |
853 | 1.79k | if (!fContext->priv().matches(rContext)) { |
854 | 0 | return {}; |
855 | 0 | } |
856 | 1.79k | auto mm = sampling.mipmap == SkMipmapMode::kNone ? GrMipmapped::kNo : GrMipmapped::kYes; |
857 | 1.79k | return MakeFragmentProcessorFromView(rContext, |
858 | 1.79k | std::get<0>(this->asView(rContext, mm)), |
859 | 1.79k | this->alphaType(), |
860 | 1.79k | sampling, |
861 | 1.79k | tileModes, |
862 | 1.79k | m, |
863 | 1.79k | subset, |
864 | 1.79k | domain); |
865 | 1.79k | } |
866 | | |
867 | 14.2k | GrSurfaceProxyView SkImage_Gpu::makeView(GrRecordingContext* rContext) const { |
868 | 14.2k | return {fChooser.chooseProxy(rContext), fOrigin, fSwizzle}; |
869 | 14.2k | } |