blob: 4730194e896136d61ebe02799e1b2a5446018a97 [file] [log] [blame]
reed@google.com5d4ba882012-07-31 15:45:27 +00001/*
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
cblume33e0cb52016-08-30 12:09:23 -07008#include <cstddef>
9#include <cstring>
10#include <type_traits>
11
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/core/SkCanvas.h"
13#include "include/gpu/GrBackendSurface.h"
14#include "include/gpu/GrContext.h"
15#include "include/gpu/GrTexture.h"
16#include "include/private/GrRecordingContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "include/private/SkImageInfoPriv.h"
18#include "src/core/SkAutoPixmapStorage.h"
19#include "src/core/SkBitmapCache.h"
20#include "src/core/SkMipMap.h"
21#include "src/core/SkScopeExit.h"
22#include "src/core/SkTraceEvent.h"
23#include "src/gpu/GrAHardwareBufferImageGenerator.h"
24#include "src/gpu/GrAHardwareBufferUtils.h"
25#include "src/gpu/GrBackendTextureImageGenerator.h"
26#include "src/gpu/GrBitmapTextureMaker.h"
27#include "src/gpu/GrCaps.h"
28#include "src/gpu/GrClip.h"
29#include "src/gpu/GrColorSpaceXform.h"
30#include "src/gpu/GrContextPriv.h"
31#include "src/gpu/GrDrawingManager.h"
32#include "src/gpu/GrGpu.h"
33#include "src/gpu/GrImageTextureMaker.h"
34#include "src/gpu/GrProxyProvider.h"
35#include "src/gpu/GrRecordingContextPriv.h"
36#include "src/gpu/GrRenderTargetContext.h"
37#include "src/gpu/GrResourceProvider.h"
38#include "src/gpu/GrResourceProviderPriv.h"
39#include "src/gpu/GrSemaphore.h"
40#include "src/gpu/GrSurfacePriv.h"
41#include "src/gpu/GrTextureAdjuster.h"
42#include "src/gpu/GrTextureContext.h"
43#include "src/gpu/GrTexturePriv.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040044#include "src/gpu/GrTextureProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050045#include "src/gpu/GrTextureProxyPriv.h"
46#include "src/gpu/SkGr.h"
47#include "src/gpu/effects/GrYUVtoRGBEffect.h"
48#include "src/gpu/gl/GrGLTexture.h"
49#include "src/image/SkImage_Gpu.h"
bsalomon993a4212015-05-29 11:37:25 -070050
Brian Salomon5ad6fd32019-03-21 15:30:08 -040051static SkColorType proxy_color_type(GrTextureProxy* proxy) {
52 SkColorType colorType;
53 if (!GrPixelConfigToColorType(proxy->config(), &colorType)) {
54 colorType = kUnknown_SkColorType;
55 }
56 return colorType;
57}
58
Brian Salomon8a8dd332018-05-24 14:08:31 -040059SkImage_Gpu::SkImage_Gpu(sk_sp<GrContext> context, uint32_t uniqueID, SkAlphaType at,
Brian Salomonf05e6d32018-12-20 08:41:41 -050060 sk_sp<GrTextureProxy> proxy, sk_sp<SkColorSpace> colorSpace)
Jim Van Verth8026ccc2018-10-04 13:10:39 -040061 : INHERITED(std::move(context), proxy->worstCaseWidth(), proxy->worstCaseHeight(), uniqueID,
Brian Salomon5ad6fd32019-03-21 15:30:08 -040062 proxy_color_type(proxy.get()), at, colorSpace)
Jim Van Verth8026ccc2018-10-04 13:10:39 -040063 , fProxy(std::move(proxy)) {}
piotaixrcef04f82014-07-14 07:48:04 -070064
Mike Reed30301c42018-07-19 09:39:21 -040065SkImage_Gpu::~SkImage_Gpu() {}
reed6f1216a2015-08-04 08:10:13 -070066
Brian Salomonf9a1fdf2019-05-09 10:30:12 -040067GrSemaphoresSubmitted SkImage_Gpu::onFlush(GrContext* context, const GrFlushInfo& info) {
68 if (!context || !fContext->priv().matches(context) || fContext->abandoned()) {
69 return GrSemaphoresSubmitted::kNo;
70 }
71
72 GrSurfaceProxy* p[1] = {fProxy.get()};
73 return context->priv().flushSurfaces(p, 1, info);
74}
75
Robert Phillips6603a172019-03-05 12:35:44 -050076sk_sp<SkImage> SkImage_Gpu::onMakeColorTypeAndColorSpace(GrRecordingContext* context,
77 SkColorType targetCT,
Brian Osmanf48c9962019-01-14 11:15:50 -050078 sk_sp<SkColorSpace> targetCS) const {
Robert Phillips6603a172019-03-05 12:35:44 -050079 if (!context || !fContext->priv().matches(context)) {
80 return nullptr;
81 }
82
Brian Salomon5ad6fd32019-03-21 15:30:08 -040083 auto xform = GrColorSpaceXformEffect::Make(this->colorSpace(), this->alphaType(),
84 targetCS.get(), this->alphaType());
Brian Osmanf48c9962019-01-14 11:15:50 -050085 SkASSERT(xform || targetCT != this->colorType());
Jim Van Verth3e4c2f32019-01-11 13:32:45 -050086
Robert Phillips6603a172019-03-05 12:35:44 -050087 sk_sp<GrTextureProxy> proxy = this->asTextureProxyRef(context);
Jim Van Verth3e4c2f32019-01-11 13:32:45 -050088
Brian Salomonbf6b9792019-08-21 09:38:10 -040089 auto renderTargetContext = context->priv().makeDeferredRenderTargetContextWithFallback(
90 SkBackingFit::kExact, this->width(), this->height(), SkColorTypeToGrColorType(targetCT),
91 nullptr);
Jim Van Verth3e4c2f32019-01-11 13:32:45 -050092 if (!renderTargetContext) {
93 return nullptr;
94 }
95
96 GrPaint paint;
97 paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
98 paint.addColorTextureProcessor(std::move(proxy), SkMatrix::I());
Brian Osmanf48c9962019-01-14 11:15:50 -050099 if (xform) {
100 paint.addColorFragmentProcessor(std::move(xform));
101 }
Jim Van Verth3e4c2f32019-01-11 13:32:45 -0500102
103 renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
104 SkRect::MakeIWH(this->width(), this->height()));
105 if (!renderTargetContext->asTextureProxy()) {
106 return nullptr;
107 }
108
109 // MDB: this call is okay bc we know 'renderTargetContext' was exact
Brian Salomon5ad6fd32019-03-21 15:30:08 -0400110 return sk_make_sp<SkImage_Gpu>(fContext, kNeedNewImageUniqueID, this->alphaType(),
Brian Osmanf48c9962019-01-14 11:15:50 -0500111 renderTargetContext->asTextureProxyRef(), std::move(targetCS));
Jim Van Verth3e4c2f32019-01-11 13:32:45 -0500112}
113
Brian Osmand5148372019-08-14 16:14:51 -0400114sk_sp<SkImage> SkImage_Gpu::onReinterpretColorSpace(sk_sp<SkColorSpace> newCS) const {
115 return sk_make_sp<SkImage_Gpu>(fContext, kNeedNewImageUniqueID, this->alphaType(), fProxy,
116 std::move(newCS));
117}
118
reed8b26b992015-05-07 15:36:17 -0700119///////////////////////////////////////////////////////////////////////////////////////////////////
120
Greg Daniel7ef28f32017-04-20 16:41:55 +0000121static sk_sp<SkImage> new_wrapped_texture_common(GrContext* ctx,
122 const GrBackendTexture& backendTex,
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400123 GrColorType colorType, GrSurfaceOrigin origin,
brianosmandddbe382016-07-20 13:55:39 -0700124 SkAlphaType at, sk_sp<SkColorSpace> colorSpace,
125 GrWrapOwnership ownership,
reed7fb4f8b2016-03-11 04:33:52 -0800126 SkImage::TextureReleaseProc releaseProc,
127 SkImage::ReleaseContext releaseCtx) {
Greg Daniel66aebf32018-04-09 09:15:56 -0400128 if (!backendTex.isValid() || backendTex.width() <= 0 || backendTex.height() <= 0) {
halcanary96fcdcc2015-08-27 07:41:13 -0700129 return nullptr;
reed8b26b992015-05-07 15:36:17 -0700130 }
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400131
Robert Phillips9da87e02019-02-04 13:26:26 -0500132 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
Brian Salomonaa6ca0a2019-01-24 16:03:07 -0500133 sk_sp<GrTextureProxy> proxy =
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400134 proxyProvider->wrapBackendTexture(backendTex, colorType, origin, ownership,
135 GrWrapCacheable::kNo, kRead_GrIOType,
136 releaseProc, releaseCtx);
Robert Phillipsadbe1322018-01-17 13:35:46 -0500137 if (!proxy) {
Robert Phillipse201ebc2018-01-17 18:12:50 +0000138 return nullptr;
139 }
Brian Salomon8a8dd332018-05-24 14:08:31 -0400140 return sk_make_sp<SkImage_Gpu>(sk_ref_sp(ctx), kNeedNewImageUniqueID, at, std::move(proxy),
Brian Salomonf05e6d32018-12-20 08:41:41 -0500141 std::move(colorSpace));
bsalomon6dc6f5f2015-06-18 09:12:16 -0700142}
143
Greg Danielf5d87582017-12-18 14:48:15 -0500144sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx,
145 const GrBackendTexture& tex, GrSurfaceOrigin origin,
146 SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs,
147 TextureReleaseProc releaseP, ReleaseContext releaseC) {
Greg Danielfaa095e2017-12-19 13:15:02 -0500148 if (!ctx) {
149 return nullptr;
150 }
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400151
Robert Phillips62221e72019-07-24 15:07:38 -0400152 const GrCaps* caps = ctx->priv().caps();
153
154 GrColorType grColorType = SkColorTypeAndFormatToGrColorType(caps, ct, tex.getBackendFormat());
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400155 if (GrColorType::kUnknown == grColorType) {
Robert Phillips97256382019-07-17 15:26:36 -0400156 return nullptr;
157 }
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400158
Robert Phillips62221e72019-07-24 15:07:38 -0400159 if (!SkImage_GpuBase::ValidateBackendTexture(caps, tex, grColorType, ct, at, cs)) {
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400160 return nullptr;
161 }
162
Robert Phillips62221e72019-07-24 15:07:38 -0400163 return new_wrapped_texture_common(ctx, tex, grColorType, origin, at, std::move(cs),
Brian Salomonbfd27492018-03-19 14:08:51 -0400164 kBorrow_GrWrapOwnership, releaseP, releaseC);
Greg Danielf5d87582017-12-18 14:48:15 -0500165}
166
Greg Daniel94403452017-04-18 15:52:36 -0400167sk_sp<SkImage> SkImage::MakeFromAdoptedTexture(GrContext* ctx,
168 const GrBackendTexture& tex, GrSurfaceOrigin origin,
Brian Salomon42409c22018-03-20 13:48:41 -0400169 SkColorType ct, SkAlphaType at,
170 sk_sp<SkColorSpace> cs) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500171 if (!ctx || !ctx->priv().resourceProvider()) {
Greg Danielf2336e42018-01-23 16:38:14 -0500172 // We have a DDL context and we don't support adopted textures for them.
173 return nullptr;
174 }
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400175
Robert Phillips62221e72019-07-24 15:07:38 -0400176 const GrCaps* caps = ctx->priv().caps();
177
178 GrColorType grColorType = SkColorTypeAndFormatToGrColorType(caps, ct, tex.getBackendFormat());
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400179 if (GrColorType::kUnknown == grColorType) {
Robert Phillips97256382019-07-17 15:26:36 -0400180 return nullptr;
181 }
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400182
Robert Phillips62221e72019-07-24 15:07:38 -0400183 if (!SkImage_GpuBase::ValidateBackendTexture(caps, tex, grColorType, ct, at, cs)) {
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400184 return nullptr;
185 }
186
Robert Phillips62221e72019-07-24 15:07:38 -0400187 return new_wrapped_texture_common(ctx, tex, grColorType, origin, at, std::move(cs),
Brian Salomon42409c22018-03-20 13:48:41 -0400188 kAdopt_GrWrapOwnership, nullptr, nullptr);
Greg Danielf5d87582017-12-18 14:48:15 -0500189}
190
Jim Van Verthee06b332019-01-18 10:36:32 -0500191sk_sp<SkImage> SkImage::MakeFromCompressed(GrContext* context, sk_sp<SkData> data,
192 int width, int height, CompressionType type) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500193 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
Brian Salomonbb8dde82019-06-27 10:52:13 -0400194 sk_sp<GrTextureProxy> proxy = proxyProvider->createCompressedTextureProxy(
195 width, height, SkBudgeted::kYes, type, std::move(data));
Jim Van Verthee06b332019-01-18 10:36:32 -0500196
197 if (!proxy) {
198 return nullptr;
199 }
200
201 return sk_make_sp<SkImage_Gpu>(sk_ref_sp(context), kNeedNewImageUniqueID, kOpaque_SkAlphaType,
202 std::move(proxy), nullptr);
203}
204
Brian Salomonf05e6d32018-12-20 08:41:41 -0500205sk_sp<SkImage> SkImage_Gpu::ConvertYUVATexturesToRGB(GrContext* ctx, SkYUVColorSpace yuvColorSpace,
206 const GrBackendTexture yuvaTextures[],
207 const SkYUVAIndex yuvaIndices[4], SkISize size,
208 GrSurfaceOrigin origin,
209 GrRenderTargetContext* renderTargetContext) {
Brian Salomond2fcfb52018-09-17 21:57:11 -0400210 SkASSERT(renderTargetContext);
211
Jim Van Verth0e671942018-11-09 12:03:57 -0500212 int numTextures;
213 if (!SkYUVAIndex::AreValidIndices(yuvaIndices, &numTextures)) {
Robert Phillipse60ad622016-11-17 10:22:48 -0500214 return nullptr;
215 }
Robert Phillipsba5c4392018-07-25 12:37:14 -0400216
Jim Van Verth0e671942018-11-09 12:03:57 -0500217 sk_sp<GrTextureProxy> tempTextureProxies[4];
Jim Van Verth53275362018-11-09 15:42:35 -0500218 if (!SkImage_GpuBase::MakeTempTextureProxies(ctx, yuvaTextures, numTextures, yuvaIndices,
219 origin, tempTextureProxies)) {
Jim Van Verth0e671942018-11-09 12:03:57 -0500220 return nullptr;
221 }
222
223 const SkRect rect = SkRect::MakeIWH(size.width(), size.height());
Brian Osmane9560492019-02-05 17:00:03 -0500224 if (!RenderYUVAToRGBA(ctx, renderTargetContext, rect, yuvColorSpace, nullptr,
Jim Van Verth0e671942018-11-09 12:03:57 -0500225 tempTextureProxies, yuvaIndices)) {
226 return nullptr;
227 }
Robert Phillipsb726d582017-03-09 16:36:32 -0500228
Jim Van Verth53275362018-11-09 15:42:35 -0500229 SkAlphaType at = GetAlphaTypeFromYUVAIndices(yuvaIndices);
Robert Phillipsb726d582017-03-09 16:36:32 -0500230 // MDB: this call is okay bc we know 'renderTargetContext' was exact
Jim Van Verth53275362018-11-09 15:42:35 -0500231 return sk_make_sp<SkImage_Gpu>(sk_ref_sp(ctx), kNeedNewImageUniqueID, at,
Brian Salomonf3569f02017-10-24 12:52:33 -0400232 renderTargetContext->asTextureProxyRef(),
Brian Salomonf05e6d32018-12-20 08:41:41 -0500233 renderTargetContext->colorSpaceInfo().refColorSpace());
Brian Salomond2fcfb52018-09-17 21:57:11 -0400234}
235
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400236sk_sp<SkImage> SkImage::MakeFromYUVATexturesCopy(GrContext* ctx,
237 SkYUVColorSpace yuvColorSpace,
238 const GrBackendTexture yuvaTextures[],
239 const SkYUVAIndex yuvaIndices[4],
240 SkISize imageSize,
241 GrSurfaceOrigin imageOrigin,
242 sk_sp<SkColorSpace> imageColorSpace) {
243 const int width = imageSize.width();
244 const int height = imageSize.height();
Brian Salomond2fcfb52018-09-17 21:57:11 -0400245
246 // Needs to create a render target in order to draw to it for the yuv->rgb conversion.
Brian Salomonbf6b9792019-08-21 09:38:10 -0400247 auto renderTargetContext = ctx->priv().makeDeferredRenderTargetContext(
Brian Salomon27ae52c2019-07-03 11:27:44 -0400248 SkBackingFit::kExact, width, height, GrColorType::kRGBA_8888,
Brian Salomonbf6b9792019-08-21 09:38:10 -0400249 std::move(imageColorSpace), 1, GrMipMapped::kNo, imageOrigin);
Brian Salomond2fcfb52018-09-17 21:57:11 -0400250 if (!renderTargetContext) {
251 return nullptr;
252 }
253
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400254 return SkImage_Gpu::ConvertYUVATexturesToRGB(ctx, yuvColorSpace, yuvaTextures, yuvaIndices,
Brian Salomonf05e6d32018-12-20 08:41:41 -0500255 imageSize, imageOrigin, renderTargetContext.get());
Brian Salomond2fcfb52018-09-17 21:57:11 -0400256}
257
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400258sk_sp<SkImage> SkImage::MakeFromYUVATexturesCopyWithExternalBackend(
Brian Salomond2fcfb52018-09-17 21:57:11 -0400259 GrContext* ctx,
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400260 SkYUVColorSpace yuvColorSpace,
Brian Salomond2fcfb52018-09-17 21:57:11 -0400261 const GrBackendTexture yuvaTextures[],
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400262 const SkYUVAIndex yuvaIndices[4],
263 SkISize imageSize,
264 GrSurfaceOrigin imageOrigin,
265 const GrBackendTexture& backendTexture,
Robert Phillipseb3eb982019-08-19 13:35:48 -0400266 sk_sp<SkColorSpace> imageColorSpace,
267 TextureReleaseProc textureReleaseProc,
268 ReleaseContext releaseContext) {
Robert Phillips62221e72019-07-24 15:07:38 -0400269 const GrCaps* caps = ctx->priv().caps();
Robert Phillipsdd399802019-07-18 12:28:00 +0000270
Robert Phillips62221e72019-07-24 15:07:38 -0400271 GrColorType grColorType = SkColorTypeAndFormatToGrColorType(caps, kRGBA_8888_SkColorType,
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400272 backendTexture.getBackendFormat());
273 if (GrColorType::kUnknown == grColorType) {
274 return nullptr;
275 }
276
Jim Van Verth53275362018-11-09 15:42:35 -0500277 SkAlphaType at = SkImage_GpuBase::GetAlphaTypeFromYUVAIndices(yuvaIndices);
Robert Phillips62221e72019-07-24 15:07:38 -0400278 if (!SkImage_Gpu::ValidateBackendTexture(caps, backendTexture, grColorType,
279 kRGBA_8888_SkColorType, at, nullptr)) {
Brian Salomond2fcfb52018-09-17 21:57:11 -0400280 return nullptr;
281 }
282
283 // Needs to create a render target with external texture
284 // in order to draw to it for the yuv->rgb conversion.
Brian Salomonbf6b9792019-08-21 09:38:10 -0400285 auto renderTargetContext = ctx->priv().makeBackendTextureRenderTargetContext(
286 backendTexture, imageOrigin, 1, grColorType, std::move(imageColorSpace), nullptr,
287 textureReleaseProc, releaseContext);
Brian Salomond2fcfb52018-09-17 21:57:11 -0400288 if (!renderTargetContext) {
289 return nullptr;
290 }
291
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400292 return SkImage_Gpu::ConvertYUVATexturesToRGB(ctx, yuvColorSpace, yuvaTextures, yuvaIndices,
Brian Salomonf05e6d32018-12-20 08:41:41 -0500293 imageSize, imageOrigin, renderTargetContext.get());
Robert Phillipsc25db632017-12-13 09:22:45 -0500294}
295
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400296sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx, SkYUVColorSpace yuvColorSpace,
Brian Salomon6a426c12018-03-15 12:16:02 -0400297 const GrBackendTexture yuvTextures[3],
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400298 GrSurfaceOrigin imageOrigin,
Brian Salomon6a426c12018-03-15 12:16:02 -0400299 sk_sp<SkColorSpace> imageColorSpace) {
Weiliang Chenbed9d5e2018-05-22 18:44:02 -0400300 // TODO: SkImageSourceChannel input is being ingored right now. Setup correctly in the future.
301 SkYUVAIndex yuvaIndices[4] = {
Robert Phillips94ade752018-10-09 12:32:31 -0400302 SkYUVAIndex{0, SkColorChannel::kR},
303 SkYUVAIndex{1, SkColorChannel::kR},
304 SkYUVAIndex{2, SkColorChannel::kR},
Robert Phillips66a97342018-10-04 09:10:29 -0400305 SkYUVAIndex{-1, SkColorChannel::kA}};
Weiliang Chenbed9d5e2018-05-22 18:44:02 -0400306 SkISize size{yuvTextures[0].width(), yuvTextures[0].height()};
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400307 return SkImage_Gpu::MakeFromYUVATexturesCopy(ctx, yuvColorSpace, yuvTextures, yuvaIndices,
308 size, imageOrigin, std::move(imageColorSpace));
bsalomon993a4212015-05-29 11:37:25 -0700309}
reed56179002015-07-07 06:11:19 -0700310
Brian Salomond2fcfb52018-09-17 21:57:11 -0400311sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopyWithExternalBackend(
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400312 GrContext* ctx, SkYUVColorSpace yuvColorSpace, const GrBackendTexture yuvTextures[3],
313 GrSurfaceOrigin imageOrigin, const GrBackendTexture& backendTexture,
Brian Salomond2fcfb52018-09-17 21:57:11 -0400314 sk_sp<SkColorSpace> imageColorSpace) {
315 SkYUVAIndex yuvaIndices[4] = {
Robert Phillips94ade752018-10-09 12:32:31 -0400316 SkYUVAIndex{0, SkColorChannel::kR},
317 SkYUVAIndex{1, SkColorChannel::kR},
318 SkYUVAIndex{2, SkColorChannel::kR},
Robert Phillips66a97342018-10-04 09:10:29 -0400319 SkYUVAIndex{-1, SkColorChannel::kA}};
Brian Salomond2fcfb52018-09-17 21:57:11 -0400320 SkISize size{yuvTextures[0].width(), yuvTextures[0].height()};
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400321 return SkImage_Gpu::MakeFromYUVATexturesCopyWithExternalBackend(
322 ctx, yuvColorSpace, yuvTextures, yuvaIndices, size, imageOrigin, backendTexture,
Robert Phillipseb3eb982019-08-19 13:35:48 -0400323 std::move(imageColorSpace), nullptr, nullptr);
Brian Salomond2fcfb52018-09-17 21:57:11 -0400324}
325
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400326sk_sp<SkImage> SkImage::MakeFromNV12TexturesCopy(GrContext* ctx, SkYUVColorSpace yuvColorSpace,
Brian Salomon6a426c12018-03-15 12:16:02 -0400327 const GrBackendTexture nv12Textures[2],
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400328 GrSurfaceOrigin imageOrigin,
brianosmandddbe382016-07-20 13:55:39 -0700329 sk_sp<SkColorSpace> imageColorSpace) {
Weiliang Chenbed9d5e2018-05-22 18:44:02 -0400330 // TODO: SkImageSourceChannel input is being ingored right now. Setup correctly in the future.
331 SkYUVAIndex yuvaIndices[4] = {
Robert Phillips94ade752018-10-09 12:32:31 -0400332 SkYUVAIndex{0, SkColorChannel::kR},
333 SkYUVAIndex{1, SkColorChannel::kR},
334 SkYUVAIndex{1, SkColorChannel::kG},
Robert Phillips66a97342018-10-04 09:10:29 -0400335 SkYUVAIndex{-1, SkColorChannel::kA}};
Weiliang Chenbed9d5e2018-05-22 18:44:02 -0400336 SkISize size{nv12Textures[0].width(), nv12Textures[0].height()};
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400337 return SkImage_Gpu::MakeFromYUVATexturesCopy(ctx, yuvColorSpace, nv12Textures, yuvaIndices,
338 size, imageOrigin, std::move(imageColorSpace));
Robert Phillipsc25db632017-12-13 09:22:45 -0500339}
340
Brian Salomond2fcfb52018-09-17 21:57:11 -0400341sk_sp<SkImage> SkImage::MakeFromNV12TexturesCopyWithExternalBackend(
342 GrContext* ctx,
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400343 SkYUVColorSpace yuvColorSpace,
Brian Salomond2fcfb52018-09-17 21:57:11 -0400344 const GrBackendTexture nv12Textures[2],
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400345 GrSurfaceOrigin imageOrigin,
346 const GrBackendTexture& backendTexture,
Robert Phillipseb3eb982019-08-19 13:35:48 -0400347 sk_sp<SkColorSpace> imageColorSpace,
348 TextureReleaseProc textureReleaseProc,
349 ReleaseContext releaseContext) {
Brian Salomond2fcfb52018-09-17 21:57:11 -0400350 SkYUVAIndex yuvaIndices[4] = {
Robert Phillips94ade752018-10-09 12:32:31 -0400351 SkYUVAIndex{0, SkColorChannel::kR},
352 SkYUVAIndex{1, SkColorChannel::kR},
353 SkYUVAIndex{1, SkColorChannel::kG},
Robert Phillips66a97342018-10-04 09:10:29 -0400354 SkYUVAIndex{-1, SkColorChannel::kA}};
Brian Salomond2fcfb52018-09-17 21:57:11 -0400355 SkISize size{nv12Textures[0].width(), nv12Textures[0].height()};
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400356 return SkImage_Gpu::MakeFromYUVATexturesCopyWithExternalBackend(
357 ctx, yuvColorSpace, nv12Textures, yuvaIndices, size, imageOrigin, backendTexture,
Robert Phillipseb3eb982019-08-19 13:35:48 -0400358 std::move(imageColorSpace), textureReleaseProc, releaseContext);
Brian Salomond2fcfb52018-09-17 21:57:11 -0400359}
360
Greg Daniel5f4b09d2018-06-12 16:39:59 -0400361static sk_sp<SkImage> create_image_from_producer(GrContext* context, GrTextureProducer* producer,
362 SkAlphaType at, uint32_t id,
Greg Daniel5f4b09d2018-06-12 16:39:59 -0400363 GrMipMapped mipMapped) {
Brian Osman6064e1c2018-10-19 14:27:54 -0400364 sk_sp<GrTextureProxy> proxy(producer->refTextureProxy(mipMapped));
Robert Phillips3798c862017-03-27 11:08:16 -0400365 if (!proxy) {
Brian Osman041f7df2017-02-07 11:23:28 -0500366 return nullptr;
367 }
Brian Salomon8a8dd332018-05-24 14:08:31 -0400368 return sk_make_sp<SkImage_Gpu>(sk_ref_sp(context), id, at, std::move(proxy),
Brian Salomonf05e6d32018-12-20 08:41:41 -0500369 sk_ref_sp(producer->colorSpace()));
Brian Osman041f7df2017-02-07 11:23:28 -0500370}
371
Brian Osmand566e2e2019-08-14 13:19:04 -0400372sk_sp<SkImage> SkImage::makeTextureImage(GrContext* context, GrMipMapped mipMapped) const {
Brian Osman041f7df2017-02-07 11:23:28 -0500373 if (!context) {
374 return nullptr;
375 }
Robert Phillipsfe0963c2019-02-07 13:25:07 -0500376
377 if (this->isTextureBacked()) {
378 if (!as_IB(this)->context()->priv().matches(context)) {
Greg Daniel5f4b09d2018-06-12 16:39:59 -0400379 return nullptr;
380 }
Robert Phillipsfe0963c2019-02-07 13:25:07 -0500381
Robert Phillips6603a172019-03-05 12:35:44 -0500382 sk_sp<GrTextureProxy> proxy = as_IB(this)->asTextureProxyRef(context);
Greg Daniel5f4b09d2018-06-12 16:39:59 -0400383 SkASSERT(proxy);
384 if (GrMipMapped::kNo == mipMapped || proxy->mipMapped() == mipMapped) {
385 return sk_ref_sp(const_cast<SkImage*>(this));
386 }
Brian Salomond6287472019-06-24 15:50:07 -0400387 GrTextureAdjuster adjuster(context, std::move(proxy),
388 SkColorTypeToGrColorType(this->colorType()), this->alphaType(),
Greg Daniel5f4b09d2018-06-12 16:39:59 -0400389 this->uniqueID(), this->colorSpace());
390 return create_image_from_producer(context, &adjuster, this->alphaType(),
Brian Osmane7fd8c32018-10-19 13:30:39 -0400391 this->uniqueID(), mipMapped);
Brian Osman041f7df2017-02-07 11:23:28 -0500392 }
393
Brian Osmandf7e0752017-04-26 16:20:28 -0400394 if (this->isLazyGenerated()) {
395 GrImageTextureMaker maker(context, this, kDisallow_CachingHint);
Greg Daniel5f4b09d2018-06-12 16:39:59 -0400396 return create_image_from_producer(context, &maker, this->alphaType(),
Brian Osmane7fd8c32018-10-19 13:30:39 -0400397 this->uniqueID(), mipMapped);
Brian Osman041f7df2017-02-07 11:23:28 -0500398 }
399
400 if (const SkBitmap* bmp = as_IB(this)->onPeekBitmap()) {
401 GrBitmapTextureMaker maker(context, *bmp);
Greg Daniel5f4b09d2018-06-12 16:39:59 -0400402 return create_image_from_producer(context, &maker, this->alphaType(),
Brian Osmane7fd8c32018-10-19 13:30:39 -0400403 this->uniqueID(), mipMapped);
Brian Osman041f7df2017-02-07 11:23:28 -0500404 }
405 return nullptr;
406}
407
Greg Daniel7278d682018-03-16 14:57:21 -0400408///////////////////////////////////////////////////////////////////////////////////////////////////
409
Greg Daniela8d92112018-03-09 12:05:04 -0500410sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
411 const GrBackendFormat& backendFormat,
412 int width,
413 int height,
414 GrMipMapped mipMapped,
415 GrSurfaceOrigin origin,
416 SkColorType colorType,
417 SkAlphaType alphaType,
418 sk_sp<SkColorSpace> colorSpace,
Brian Salomoncdd8a0a2019-01-10 12:09:52 -0500419 PromiseImageTextureFulfillProc textureFulfillProc,
420 PromiseImageTextureReleaseProc textureReleaseProc,
Brian Salomonf55e8d52019-01-30 17:28:20 -0500421 PromiseImageTextureDoneProc textureDoneProc,
Brian Salomon0cc57542019-03-08 13:28:46 -0500422 PromiseImageTextureContext textureContext,
423 PromiseImageApiVersion version) {
Robert Phillipsef85d192018-10-09 11:24:09 -0400424 // The contract here is that if 'promiseDoneProc' is passed in it should always be called,
Brian Salomonbe5a0932018-12-10 10:03:26 -0500425 // even if creation of the SkImage fails. Once we call MakePromiseImageLazyProxy it takes
426 // responsibility for calling the done proc.
Brian Salomonf55e8d52019-01-30 17:28:20 -0500427 if (!textureDoneProc) {
Robert Phillipsef85d192018-10-09 11:24:09 -0400428 return nullptr;
429 }
Brian Salomonf55e8d52019-01-30 17:28:20 -0500430 SkScopeExit callDone([textureDoneProc, textureContext]() { textureDoneProc(textureContext); });
Robert Phillipsef85d192018-10-09 11:24:09 -0400431
Brian Salomonbe5a0932018-12-10 10:03:26 -0500432 SkImageInfo info = SkImageInfo::Make(width, height, colorType, alphaType, colorSpace);
433 if (!SkImageInfoIsValid(info)) {
434 return nullptr;
435 }
Robert Phillipsef85d192018-10-09 11:24:09 -0400436
Greg Daniela8d92112018-03-09 12:05:04 -0500437 if (!context) {
438 return nullptr;
439 }
440
441 if (width <= 0 || height <= 0) {
442 return nullptr;
443 }
444
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400445 GrColorType grColorType = SkColorTypeAndFormatToGrColorType(context->priv().caps(),
446 colorType,
447 backendFormat);
448 if (GrColorType::kUnknown == grColorType) {
Greg Daniela8d92112018-03-09 12:05:04 -0500449 return nullptr;
450 }
451
Brian Salomonbe5a0932018-12-10 10:03:26 -0500452 callDone.clear();
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400453 auto proxy = MakePromiseImageLazyProxy(context, width, height, origin,
454 grColorType, backendFormat,
Brian Salomonbe5a0932018-12-10 10:03:26 -0500455 mipMapped, textureFulfillProc, textureReleaseProc,
Brian Salomon0cc57542019-03-08 13:28:46 -0500456 textureDoneProc, textureContext, version);
Greg Daniela8d92112018-03-09 12:05:04 -0500457 if (!proxy) {
458 return nullptr;
459 }
Brian Salomon8a8dd332018-05-24 14:08:31 -0400460 return sk_make_sp<SkImage_Gpu>(sk_ref_sp(context), kNeedNewImageUniqueID, alphaType,
Brian Salomonf05e6d32018-12-20 08:41:41 -0500461 std::move(proxy), std::move(colorSpace));
Greg Daniela8d92112018-03-09 12:05:04 -0500462}
463
Greg Daniel7278d682018-03-16 14:57:21 -0400464///////////////////////////////////////////////////////////////////////////////////////////////////
465
Brian Osman584b5012018-04-13 15:48:26 -0400466sk_sp<SkImage> SkImage::MakeCrossContextFromPixmap(GrContext* context,
467 const SkPixmap& originalPixmap, bool buildMips,
Brian Osman584b5012018-04-13 15:48:26 -0400468 bool limitToMaxTextureSize) {
Brian Osman63bc48d2017-11-07 10:37:00 -0500469 // Some backends or drivers don't support (safely) moving resources between contexts
Robert Phillips9da87e02019-02-04 13:26:26 -0500470 if (!context || !context->priv().caps()->crossContextTextureSupport()) {
Brian Osman584b5012018-04-13 15:48:26 -0400471 return SkImage::MakeRasterCopy(originalPixmap);
Brian Osman63bc48d2017-11-07 10:37:00 -0500472 }
473
Greg Daniel9e788112018-02-08 14:29:37 -0500474 // If we don't have access to the resource provider and gpu (i.e. in a DDL context) we will not
475 // be able to make everything needed for a GPU CrossContext image. Thus return a raster copy
476 // instead.
Robert Phillips9da87e02019-02-04 13:26:26 -0500477 if (!context->priv().resourceProvider()) {
Brian Osman584b5012018-04-13 15:48:26 -0400478 return SkImage::MakeRasterCopy(originalPixmap);
Greg Daniel9e788112018-02-08 14:29:37 -0500479 }
480
Brian Osman0471a932019-02-07 13:36:56 -0500481 // If non-power-of-two mipmapping isn't supported, ignore the client's request
482 if (!context->priv().caps()->mipMapSupport()) {
483 buildMips = false;
484 }
485
Brian Osman584b5012018-04-13 15:48:26 -0400486 const SkPixmap* pixmap = &originalPixmap;
487 SkAutoPixmapStorage resized;
Robert Phillips9da87e02019-02-04 13:26:26 -0500488 int maxTextureSize = context->priv().caps()->maxTextureSize();
Brian Osman584b5012018-04-13 15:48:26 -0400489 int maxDim = SkTMax(originalPixmap.width(), originalPixmap.height());
490 if (limitToMaxTextureSize && maxDim > maxTextureSize) {
491 float scale = static_cast<float>(maxTextureSize) / maxDim;
492 int newWidth = SkTMin(static_cast<int>(originalPixmap.width() * scale), maxTextureSize);
493 int newHeight = SkTMin(static_cast<int>(originalPixmap.height() * scale), maxTextureSize);
494 SkImageInfo info = originalPixmap.info().makeWH(newWidth, newHeight);
495 if (!resized.tryAlloc(info) || !originalPixmap.scalePixels(resized, kLow_SkFilterQuality)) {
496 return nullptr;
497 }
498 pixmap = &resized;
499 }
Robert Phillips9da87e02019-02-04 13:26:26 -0500500 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
Brian Osman63bc48d2017-11-07 10:37:00 -0500501 // Turn the pixmap into a GrTextureProxy
Brian Osman7dcc6162019-03-25 10:12:57 -0400502 SkBitmap bmp;
503 bmp.installPixels(*pixmap);
504 GrMipMapped mipMapped = buildMips ? GrMipMapped::kYes : GrMipMapped::kNo;
505 sk_sp<GrTextureProxy> proxy = proxyProvider->createProxyFromBitmap(bmp, mipMapped);
Brian Osman63bc48d2017-11-07 10:37:00 -0500506 if (!proxy) {
Brian Osman584b5012018-04-13 15:48:26 -0400507 return SkImage::MakeRasterCopy(*pixmap);
Brian Osman63bc48d2017-11-07 10:37:00 -0500508 }
509
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400510 sk_sp<GrTexture> texture = sk_ref_sp(proxy->peekTexture());
Brian Osman63bc48d2017-11-07 10:37:00 -0500511
512 // Flush any writes or uploads
Greg Daniel4aa13e72019-04-15 14:42:20 -0400513 context->priv().flushSurface(proxy.get());
Robert Phillips9da87e02019-02-04 13:26:26 -0500514 GrGpu* gpu = context->priv().getGpu();
Brian Osman63bc48d2017-11-07 10:37:00 -0500515
Robert Phillipsf35fd8d2018-01-22 10:48:15 -0500516 sk_sp<GrSemaphore> sema = gpu->prepareTextureForCrossContextUsage(texture.get());
Brian Osman63bc48d2017-11-07 10:37:00 -0500517
518 auto gen = GrBackendTextureImageGenerator::Make(std::move(texture), proxy->origin(),
Brian Osman584b5012018-04-13 15:48:26 -0400519 std::move(sema), pixmap->colorType(),
520 pixmap->alphaType(),
521 pixmap->info().refColorSpace());
Brian Osman63bc48d2017-11-07 10:37:00 -0500522 return SkImage::MakeFromGenerator(std::move(gen));
523}
524
Derek Sollenberger7a869872017-06-27 15:37:25 -0400525#if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
Stan Iliev7e910df2017-06-02 10:29:21 -0400526sk_sp<SkImage> SkImage::MakeFromAHardwareBuffer(AHardwareBuffer* graphicBuffer, SkAlphaType at,
Stan Iliev505dd572018-09-13 14:20:03 -0400527 sk_sp<SkColorSpace> cs,
528 GrSurfaceOrigin surfaceOrigin) {
529 auto gen = GrAHardwareBufferImageGenerator::Make(graphicBuffer, at, cs, surfaceOrigin);
Stan Iliev7e910df2017-06-02 10:29:21 -0400530 return SkImage::MakeFromGenerator(std::move(gen));
531}
Greg Danielb6c15ba2019-03-04 13:08:25 -0500532
533sk_sp<SkImage> SkImage::MakeFromAHardwareBufferWithData(GrContext* context,
534 const SkPixmap& pixmap,
535 AHardwareBuffer* hardwareBuffer,
536 GrSurfaceOrigin surfaceOrigin) {
537 AHardwareBuffer_Desc bufferDesc;
538 AHardwareBuffer_describe(hardwareBuffer, &bufferDesc);
539
540 if (!SkToBool(bufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE)) {
541 return nullptr;
542 }
543
544 GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat(context,
545 hardwareBuffer,
546 bufferDesc.format,
547 true);
548
549 if (!backendFormat.isValid()) {
550 return nullptr;
551 }
552
553 GrAHardwareBufferUtils::DeleteImageProc deleteImageProc = nullptr;
Stan Ilieva56b04a2019-08-01 14:22:34 -0400554 GrAHardwareBufferUtils::UpdateImageProc updateImageProc = nullptr;
555 GrAHardwareBufferUtils::TexImageCtx deleteImageCtx = nullptr;
Greg Danielb6c15ba2019-03-04 13:08:25 -0500556
557 GrBackendTexture backendTexture =
558 GrAHardwareBufferUtils::MakeBackendTexture(context, hardwareBuffer,
559 bufferDesc.width, bufferDesc.height,
Stan Ilieva56b04a2019-08-01 14:22:34 -0400560 &deleteImageProc, &updateImageProc,
561 &deleteImageCtx, false, backendFormat, true);
Greg Danielb6c15ba2019-03-04 13:08:25 -0500562 if (!backendTexture.isValid()) {
563 return nullptr;
564 }
565 SkASSERT(deleteImageProc);
566
567 SkColorType colorType =
568 GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(bufferDesc.format);
569
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400570 GrColorType grColorType = SkColorTypeToGrColorType(colorType);
Greg Danielb6c15ba2019-03-04 13:08:25 -0500571
572 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
573 if (!proxyProvider) {
574 deleteImageProc(deleteImageCtx);
575 return nullptr;
576 }
577
578 sk_sp<GrTextureProxy> proxy =
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400579 proxyProvider->wrapBackendTexture(backendTexture, grColorType, surfaceOrigin,
Greg Danielb6c15ba2019-03-04 13:08:25 -0500580 kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
581 kRW_GrIOType, deleteImageProc, deleteImageCtx);
582 if (!proxy) {
583 deleteImageProc(deleteImageCtx);
584 return nullptr;
585 }
586
587 sk_sp<SkColorSpace> cs = pixmap.refColorSpace();
588 SkAlphaType at = pixmap.alphaType();
589
590 sk_sp<SkImage> image = sk_make_sp<SkImage_Gpu>(sk_ref_sp(context), kNeedNewImageUniqueID, at,
591 proxy, cs);
592 if (!image) {
593 return nullptr;
594 }
595
596 GrDrawingManager* drawingManager = context->priv().drawingManager();
597 if (!drawingManager) {
598 return nullptr;
599 }
600
Brian Salomonbf6b9792019-08-21 09:38:10 -0400601 auto texContext =
Brian Salomond6287472019-06-24 15:50:07 -0400602 drawingManager->makeTextureContext(proxy, SkColorTypeToGrColorType(pixmap.colorType()),
603 pixmap.alphaType(), cs);
Greg Danielb6c15ba2019-03-04 13:08:25 -0500604 if (!texContext) {
605 return nullptr;
606 }
607
608 SkImageInfo srcInfo = SkImageInfo::Make(bufferDesc.width, bufferDesc.height, colorType, at,
609 std::move(cs));
Brian Salomon1d435302019-07-01 13:05:28 -0400610 texContext->writePixels(srcInfo, pixmap.addr(0, 0), pixmap.rowBytes(), {0, 0});
Greg Danielb6c15ba2019-03-04 13:08:25 -0500611
Greg Daniele6bfb7d2019-04-17 15:26:11 -0400612 GrFlushInfo info;
613 info.fFlags = kSyncCpu_GrFlushFlag;
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400614 GrSurfaceProxy* p[1] = {proxy.get()};
Greg Daniel797efca2019-05-09 14:04:20 -0400615 drawingManager->flush(p, 1, SkSurface::BackendSurfaceAccess::kNoAccess, info,
616 GrPrepareForExternalIORequests());
Greg Danielb6c15ba2019-03-04 13:08:25 -0500617
618 return image;
619}
Stan Iliev7e910df2017-06-02 10:29:21 -0400620#endif
621
reed56179002015-07-07 06:11:19 -0700622///////////////////////////////////////////////////////////////////////////////////////////////////
623
Eric Karl914a36b2017-10-12 12:44:50 -0700624bool SkImage::MakeBackendTextureFromSkImage(GrContext* ctx,
625 sk_sp<SkImage> image,
626 GrBackendTexture* backendTexture,
627 BackendTextureReleaseProc* releaseProc) {
628 if (!image || !ctx || !backendTexture || !releaseProc) {
629 return false;
630 }
631
632 // Ensure we have a texture backed image.
633 if (!image->isTextureBacked()) {
Brian Osmand566e2e2019-08-14 13:19:04 -0400634 image = image->makeTextureImage(ctx);
Eric Karl914a36b2017-10-12 12:44:50 -0700635 if (!image) {
636 return false;
637 }
638 }
639 GrTexture* texture = image->getTexture();
Eric Karl36591e52018-01-19 13:45:02 -0800640 if (!texture) {
641 // In context-loss cases, we may not have a texture.
642 return false;
643 }
Eric Karl914a36b2017-10-12 12:44:50 -0700644
645 // If the image's context doesn't match the provided context, fail.
646 if (texture->getContext() != ctx) {
647 return false;
648 }
649
650 // Flush any pending IO on the texture.
Greg Daniel4aa13e72019-04-15 14:42:20 -0400651 ctx->priv().flushSurface(as_IB(image)->peekProxy());
Eric Karl914a36b2017-10-12 12:44:50 -0700652
653 // We must make a copy of the image if the image is not unique, if the GrTexture owned by the
654 // image is not unique, or if the texture wraps an external object.
Robert Phillipsaee18c92019-09-06 11:48:27 -0400655 if (!image->unique() || !texture->unique() ||
Eric Karl914a36b2017-10-12 12:44:50 -0700656 texture->resourcePriv().refsWrappedObjects()) {
657 // onMakeSubset will always copy the image.
Robert Phillips6603a172019-03-05 12:35:44 -0500658 image = as_IB(image)->onMakeSubset(ctx, image->bounds());
Eric Karl914a36b2017-10-12 12:44:50 -0700659 if (!image) {
660 return false;
661 }
662
663 texture = image->getTexture();
Eric Karl36591e52018-01-19 13:45:02 -0800664 if (!texture) {
665 return false;
666 }
Eric Karl914a36b2017-10-12 12:44:50 -0700667
668 // Flush to ensure that the copy is completed before we return the texture.
Greg Daniel4aa13e72019-04-15 14:42:20 -0400669 ctx->priv().flushSurface(as_IB(image)->peekProxy());
Eric Karl914a36b2017-10-12 12:44:50 -0700670 }
671
672 SkASSERT(!texture->resourcePriv().refsWrappedObjects());
Robert Phillipsaee18c92019-09-06 11:48:27 -0400673 SkASSERT(texture->unique());
Eric Karl914a36b2017-10-12 12:44:50 -0700674 SkASSERT(image->unique());
675
676 // Take a reference to the GrTexture and release the image.
677 sk_sp<GrTexture> textureRef(SkSafeRef(texture));
678 image = nullptr;
679
680 // Steal the backend texture from the GrTexture, releasing the GrTexture in the process.
681 return GrTexture::StealBackendTexture(std::move(textureRef), backendTexture, releaseProc);
682}