blob: ad6e4a05fb90cbb60f25a21114849b5c140c5da9 [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"
Brian Salomonf2ebdd92019-09-30 12:15:30 -040033#include "src/gpu/GrImageInfo.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050034#include "src/gpu/GrImageTextureMaker.h"
35#include "src/gpu/GrProxyProvider.h"
36#include "src/gpu/GrRecordingContextPriv.h"
37#include "src/gpu/GrRenderTargetContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050038#include "src/gpu/GrSemaphore.h"
39#include "src/gpu/GrSurfacePriv.h"
40#include "src/gpu/GrTextureAdjuster.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050041#include "src/gpu/GrTexturePriv.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040042#include "src/gpu/GrTextureProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050043#include "src/gpu/GrTextureProxyPriv.h"
44#include "src/gpu/SkGr.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050045#include "src/gpu/gl/GrGLTexture.h"
46#include "src/image/SkImage_Gpu.h"
bsalomon993a4212015-05-29 11:37:25 -070047
Greg Daniel81b98972019-12-13 11:09:43 -050048static SkColorType proxy_color_type(GrSurfaceProxy* proxy) {
Brian Salomon729fc0c2019-09-30 16:33:11 +000049 SkColorType colorType;
50 if (!GrPixelConfigToColorType(proxy->config(), &colorType)) {
51 colorType = kUnknown_SkColorType;
52 }
53 return colorType;
54}
55
56SkImage_Gpu::SkImage_Gpu(sk_sp<GrContext> context, uint32_t uniqueID, SkAlphaType at,
Greg Daniel81b98972019-12-13 11:09:43 -050057 GrSurfaceProxyView view, sk_sp<SkColorSpace> colorSpace)
58 : INHERITED(std::move(context), view.proxy()->backingStoreDimensions(), uniqueID,
59 proxy_color_type(view.proxy()), at, colorSpace)
60 , fView(std::move(view)) {}
piotaixrcef04f82014-07-14 07:48:04 -070061
Brian Salomon729fc0c2019-09-30 16:33:11 +000062SkImage_Gpu::~SkImage_Gpu() {}
63
Brian Salomonf9a1fdf2019-05-09 10:30:12 -040064GrSemaphoresSubmitted SkImage_Gpu::onFlush(GrContext* context, const GrFlushInfo& info) {
65 if (!context || !fContext->priv().matches(context) || fContext->abandoned()) {
66 return GrSemaphoresSubmitted::kNo;
67 }
68
Greg Daniel81b98972019-12-13 11:09:43 -050069 GrSurfaceProxy* p[1] = {fView.proxy()};
Brian Salomonf9a1fdf2019-05-09 10:30:12 -040070 return context->priv().flushSurfaces(p, 1, info);
71}
72
Robert Phillips6603a172019-03-05 12:35:44 -050073sk_sp<SkImage> SkImage_Gpu::onMakeColorTypeAndColorSpace(GrRecordingContext* context,
74 SkColorType targetCT,
Brian Osmanf48c9962019-01-14 11:15:50 -050075 sk_sp<SkColorSpace> targetCS) const {
Robert Phillips6603a172019-03-05 12:35:44 -050076 if (!context || !fContext->priv().matches(context)) {
77 return nullptr;
78 }
79
Brian Salomon5ad6fd32019-03-21 15:30:08 -040080 auto xform = GrColorSpaceXformEffect::Make(this->colorSpace(), this->alphaType(),
81 targetCS.get(), this->alphaType());
Brian Osmanf48c9962019-01-14 11:15:50 -050082 SkASSERT(xform || targetCT != this->colorType());
Jim Van Verth3e4c2f32019-01-11 13:32:45 -050083
Greg Daniele20fcad2020-01-08 11:52:34 -050084 auto renderTargetContext = GrRenderTargetContext::MakeWithFallback(
85 context, SkColorTypeToGrColorType(targetCT), nullptr, SkBackingFit::kExact,
86 this->dimensions());
Jim Van Verth3e4c2f32019-01-11 13:32:45 -050087 if (!renderTargetContext) {
88 return nullptr;
89 }
90
91 GrPaint paint;
92 paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
Greg Daniel81b98972019-12-13 11:09:43 -050093 sk_sp<GrTextureProxy> proxy = this->asTextureProxyRef(context);
Brian Salomonbfb72112020-01-13 10:51:50 -050094 paint.addColorFragmentProcessor(GrTextureEffect::Make(std::move(proxy), this->alphaType()));
Brian Osmanf48c9962019-01-14 11:15:50 -050095 if (xform) {
96 paint.addColorFragmentProcessor(std::move(xform));
97 }
Jim Van Verth3e4c2f32019-01-11 13:32:45 -050098
99 renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
100 SkRect::MakeIWH(this->width(), this->height()));
101 if (!renderTargetContext->asTextureProxy()) {
102 return nullptr;
103 }
104
105 // MDB: this call is okay bc we know 'renderTargetContext' was exact
Brian Salomon729fc0c2019-09-30 16:33:11 +0000106 return sk_make_sp<SkImage_Gpu>(fContext, kNeedNewImageUniqueID, this->alphaType(),
Greg Daniel46e366a2019-12-16 14:38:36 -0500107 renderTargetContext->readSurfaceView(), std::move(targetCS));
Jim Van Verth3e4c2f32019-01-11 13:32:45 -0500108}
109
Brian Osmand5148372019-08-14 16:14:51 -0400110sk_sp<SkImage> SkImage_Gpu::onReinterpretColorSpace(sk_sp<SkColorSpace> newCS) const {
Greg Daniel81b98972019-12-13 11:09:43 -0500111 return sk_make_sp<SkImage_Gpu>(fContext, kNeedNewImageUniqueID, this->alphaType(), fView,
Brian Salomon729fc0c2019-09-30 16:33:11 +0000112 std::move(newCS));
Brian Osmand5148372019-08-14 16:14:51 -0400113}
114
reed8b26b992015-05-07 15:36:17 -0700115///////////////////////////////////////////////////////////////////////////////////////////////////
116
Greg Daniel7ef28f32017-04-20 16:41:55 +0000117static sk_sp<SkImage> new_wrapped_texture_common(GrContext* ctx,
118 const GrBackendTexture& backendTex,
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400119 GrColorType colorType, GrSurfaceOrigin origin,
brianosmandddbe382016-07-20 13:55:39 -0700120 SkAlphaType at, sk_sp<SkColorSpace> colorSpace,
121 GrWrapOwnership ownership,
reed7fb4f8b2016-03-11 04:33:52 -0800122 SkImage::TextureReleaseProc releaseProc,
123 SkImage::ReleaseContext releaseCtx) {
Greg Daniel66aebf32018-04-09 09:15:56 -0400124 if (!backendTex.isValid() || backendTex.width() <= 0 || backendTex.height() <= 0) {
halcanary96fcdcc2015-08-27 07:41:13 -0700125 return nullptr;
reed8b26b992015-05-07 15:36:17 -0700126 }
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400127
Robert Phillips9da87e02019-02-04 13:26:26 -0500128 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
Brian Salomonaa6ca0a2019-01-24 16:03:07 -0500129 sk_sp<GrTextureProxy> proxy =
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400130 proxyProvider->wrapBackendTexture(backendTex, colorType, origin, ownership,
131 GrWrapCacheable::kNo, kRead_GrIOType,
132 releaseProc, releaseCtx);
Robert Phillipsadbe1322018-01-17 13:35:46 -0500133 if (!proxy) {
Robert Phillipse201ebc2018-01-17 18:12:50 +0000134 return nullptr;
135 }
Greg Daniel81b98972019-12-13 11:09:43 -0500136
Greg Daniel14b57212019-12-17 16:18:06 -0500137 GrSwizzle swizzle = ctx->priv().caps()->getReadSwizzle(proxy->backendFormat(), colorType);
Greg Daniel81b98972019-12-13 11:09:43 -0500138 GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
139 return sk_make_sp<SkImage_Gpu>(sk_ref_sp(ctx), kNeedNewImageUniqueID, at, std::move(view),
Brian Salomon729fc0c2019-09-30 16:33:11 +0000140 std::move(colorSpace));
bsalomon6dc6f5f2015-06-18 09:12:16 -0700141}
142
Robert Phillipsb915c942019-12-17 14:44:37 -0500143sk_sp<SkImage> SkImage::MakeFromCompressedTexture(GrContext* ctx,
144 const GrBackendTexture& tex,
145 GrSurfaceOrigin origin,
146 SkAlphaType at,
147 sk_sp<SkColorSpace> cs,
148 TextureReleaseProc releaseP,
149 ReleaseContext releaseC) {
Robert Phillipsead321b2019-12-19 10:16:32 -0500150 if (!ctx) {
151 return nullptr;
152 }
153
154 const GrCaps* caps = ctx->priv().caps();
155
156 if (!SkImage_GpuBase::ValidateCompressedBackendTexture(caps, tex, at)) {
157 return nullptr;
158 }
159
160 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
161 sk_sp<GrTextureProxy> proxy =
162 proxyProvider->wrapCompressedBackendTexture(tex, origin, kBorrow_GrWrapOwnership,
163 GrWrapCacheable::kNo, releaseP, releaseC);
164 if (!proxy) {
165 return nullptr;
166 }
167
168 GrSurfaceProxyView view(std::move(proxy), origin, GrSwizzle::RGBA());
169 return sk_make_sp<SkImage_Gpu>(sk_ref_sp(ctx), kNeedNewImageUniqueID, at, std::move(view),
170 std::move(cs));
Robert Phillipsb915c942019-12-17 14:44:37 -0500171}
172
Greg Danielf5d87582017-12-18 14:48:15 -0500173sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx,
174 const GrBackendTexture& tex, GrSurfaceOrigin origin,
175 SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs,
176 TextureReleaseProc releaseP, ReleaseContext releaseC) {
Greg Danielfaa095e2017-12-19 13:15:02 -0500177 if (!ctx) {
178 return nullptr;
179 }
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400180
Robert Phillips62221e72019-07-24 15:07:38 -0400181 const GrCaps* caps = ctx->priv().caps();
182
183 GrColorType grColorType = SkColorTypeAndFormatToGrColorType(caps, ct, tex.getBackendFormat());
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400184 if (GrColorType::kUnknown == grColorType) {
Robert Phillips97256382019-07-17 15:26:36 -0400185 return nullptr;
186 }
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400187
Robert Phillips62221e72019-07-24 15:07:38 -0400188 if (!SkImage_GpuBase::ValidateBackendTexture(caps, tex, grColorType, ct, at, cs)) {
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400189 return nullptr;
190 }
191
Robert Phillips62221e72019-07-24 15:07:38 -0400192 return new_wrapped_texture_common(ctx, tex, grColorType, origin, at, std::move(cs),
Brian Salomonbfd27492018-03-19 14:08:51 -0400193 kBorrow_GrWrapOwnership, releaseP, releaseC);
Greg Danielf5d87582017-12-18 14:48:15 -0500194}
195
Greg Daniel94403452017-04-18 15:52:36 -0400196sk_sp<SkImage> SkImage::MakeFromAdoptedTexture(GrContext* ctx,
197 const GrBackendTexture& tex, GrSurfaceOrigin origin,
Brian Salomon42409c22018-03-20 13:48:41 -0400198 SkColorType ct, SkAlphaType at,
199 sk_sp<SkColorSpace> cs) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500200 if (!ctx || !ctx->priv().resourceProvider()) {
Greg Danielf2336e42018-01-23 16:38:14 -0500201 // We have a DDL context and we don't support adopted textures for them.
202 return nullptr;
203 }
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400204
Robert Phillips62221e72019-07-24 15:07:38 -0400205 const GrCaps* caps = ctx->priv().caps();
206
207 GrColorType grColorType = SkColorTypeAndFormatToGrColorType(caps, ct, tex.getBackendFormat());
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400208 if (GrColorType::kUnknown == grColorType) {
Robert Phillips97256382019-07-17 15:26:36 -0400209 return nullptr;
210 }
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400211
Robert Phillips62221e72019-07-24 15:07:38 -0400212 if (!SkImage_GpuBase::ValidateBackendTexture(caps, tex, grColorType, ct, at, cs)) {
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400213 return nullptr;
214 }
215
Robert Phillips62221e72019-07-24 15:07:38 -0400216 return new_wrapped_texture_common(ctx, tex, grColorType, origin, at, std::move(cs),
Brian Salomon42409c22018-03-20 13:48:41 -0400217 kAdopt_GrWrapOwnership, nullptr, nullptr);
Greg Danielf5d87582017-12-18 14:48:15 -0500218}
219
Jim Van Verthee06b332019-01-18 10:36:32 -0500220sk_sp<SkImage> SkImage::MakeFromCompressed(GrContext* context, sk_sp<SkData> data,
221 int width, int height, CompressionType type) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500222 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
Brian Salomonbb8dde82019-06-27 10:52:13 -0400223 sk_sp<GrTextureProxy> proxy = proxyProvider->createCompressedTextureProxy(
Robert Phillips9f744f72019-12-19 19:14:33 -0500224 {width, height}, SkBudgeted::kYes, type, std::move(data));
Jim Van Verthee06b332019-01-18 10:36:32 -0500225 if (!proxy) {
226 return nullptr;
227 }
Greg Daniel81b98972019-12-13 11:09:43 -0500228 // TODO: remove asserts when proxy doesn't hold origin or swizzle
229 SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
230 SkASSERT(proxy->textureSwizzle() == GrSwizzle());
231 GrSurfaceProxyView view(std::move(proxy));
Brian Salomon729fc0c2019-09-30 16:33:11 +0000232
233 return sk_make_sp<SkImage_Gpu>(sk_ref_sp(context), kNeedNewImageUniqueID, kOpaque_SkAlphaType,
Greg Daniel81b98972019-12-13 11:09:43 -0500234 std::move(view), nullptr);
Jim Van Verthee06b332019-01-18 10:36:32 -0500235}
236
Brian Salomonf05e6d32018-12-20 08:41:41 -0500237sk_sp<SkImage> SkImage_Gpu::ConvertYUVATexturesToRGB(GrContext* ctx, SkYUVColorSpace yuvColorSpace,
238 const GrBackendTexture yuvaTextures[],
239 const SkYUVAIndex yuvaIndices[4], SkISize size,
240 GrSurfaceOrigin origin,
241 GrRenderTargetContext* renderTargetContext) {
Brian Salomond2fcfb52018-09-17 21:57:11 -0400242 SkASSERT(renderTargetContext);
243
Jim Van Verth0e671942018-11-09 12:03:57 -0500244 int numTextures;
245 if (!SkYUVAIndex::AreValidIndices(yuvaIndices, &numTextures)) {
Robert Phillipse60ad622016-11-17 10:22:48 -0500246 return nullptr;
247 }
Robert Phillipsba5c4392018-07-25 12:37:14 -0400248
Jim Van Verth0e671942018-11-09 12:03:57 -0500249 sk_sp<GrTextureProxy> tempTextureProxies[4];
Jim Van Verth53275362018-11-09 15:42:35 -0500250 if (!SkImage_GpuBase::MakeTempTextureProxies(ctx, yuvaTextures, numTextures, yuvaIndices,
251 origin, tempTextureProxies)) {
Jim Van Verth0e671942018-11-09 12:03:57 -0500252 return nullptr;
253 }
254
255 const SkRect rect = SkRect::MakeIWH(size.width(), size.height());
Brian Osmane9560492019-02-05 17:00:03 -0500256 if (!RenderYUVAToRGBA(ctx, renderTargetContext, rect, yuvColorSpace, nullptr,
Jim Van Verth0e671942018-11-09 12:03:57 -0500257 tempTextureProxies, yuvaIndices)) {
258 return nullptr;
259 }
Robert Phillipsb726d582017-03-09 16:36:32 -0500260
Jim Van Verth53275362018-11-09 15:42:35 -0500261 SkAlphaType at = GetAlphaTypeFromYUVAIndices(yuvaIndices);
Robert Phillipsb726d582017-03-09 16:36:32 -0500262 // MDB: this call is okay bc we know 'renderTargetContext' was exact
Brian Salomon729fc0c2019-09-30 16:33:11 +0000263 return sk_make_sp<SkImage_Gpu>(sk_ref_sp(ctx), kNeedNewImageUniqueID, at,
Greg Daniel46e366a2019-12-16 14:38:36 -0500264 renderTargetContext->readSurfaceView(),
Brian Salomon4bc0c1f2019-09-30 15:12:27 -0400265 renderTargetContext->colorInfo().refColorSpace());
Brian Salomond2fcfb52018-09-17 21:57:11 -0400266}
267
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400268sk_sp<SkImage> SkImage::MakeFromYUVATexturesCopy(GrContext* ctx,
269 SkYUVColorSpace yuvColorSpace,
270 const GrBackendTexture yuvaTextures[],
271 const SkYUVAIndex yuvaIndices[4],
272 SkISize imageSize,
273 GrSurfaceOrigin imageOrigin,
274 sk_sp<SkColorSpace> imageColorSpace) {
Greg Daniele20fcad2020-01-08 11:52:34 -0500275 auto renderTargetContext = GrRenderTargetContext::Make(
276 ctx, GrColorType::kRGBA_8888, std::move(imageColorSpace), SkBackingFit::kExact,
277 imageSize, 1, GrMipMapped::kNo, GrProtected::kNo, imageOrigin);
Brian Salomond2fcfb52018-09-17 21:57:11 -0400278 if (!renderTargetContext) {
279 return nullptr;
280 }
281
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400282 return SkImage_Gpu::ConvertYUVATexturesToRGB(ctx, yuvColorSpace, yuvaTextures, yuvaIndices,
Brian Salomonf05e6d32018-12-20 08:41:41 -0500283 imageSize, imageOrigin, renderTargetContext.get());
Brian Salomond2fcfb52018-09-17 21:57:11 -0400284}
285
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400286sk_sp<SkImage> SkImage::MakeFromYUVATexturesCopyWithExternalBackend(
Brian Salomond2fcfb52018-09-17 21:57:11 -0400287 GrContext* ctx,
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400288 SkYUVColorSpace yuvColorSpace,
Brian Salomond2fcfb52018-09-17 21:57:11 -0400289 const GrBackendTexture yuvaTextures[],
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400290 const SkYUVAIndex yuvaIndices[4],
291 SkISize imageSize,
292 GrSurfaceOrigin imageOrigin,
293 const GrBackendTexture& backendTexture,
Robert Phillipseb3eb982019-08-19 13:35:48 -0400294 sk_sp<SkColorSpace> imageColorSpace,
295 TextureReleaseProc textureReleaseProc,
296 ReleaseContext releaseContext) {
Robert Phillips62221e72019-07-24 15:07:38 -0400297 const GrCaps* caps = ctx->priv().caps();
Robert Phillipsdd399802019-07-18 12:28:00 +0000298
Robert Phillips62221e72019-07-24 15:07:38 -0400299 GrColorType grColorType = SkColorTypeAndFormatToGrColorType(caps, kRGBA_8888_SkColorType,
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400300 backendTexture.getBackendFormat());
301 if (GrColorType::kUnknown == grColorType) {
302 return nullptr;
303 }
304
Jim Van Verth53275362018-11-09 15:42:35 -0500305 SkAlphaType at = SkImage_GpuBase::GetAlphaTypeFromYUVAIndices(yuvaIndices);
Robert Phillips62221e72019-07-24 15:07:38 -0400306 if (!SkImage_Gpu::ValidateBackendTexture(caps, backendTexture, grColorType,
307 kRGBA_8888_SkColorType, at, nullptr)) {
Brian Salomond2fcfb52018-09-17 21:57:11 -0400308 return nullptr;
309 }
310
311 // Needs to create a render target with external texture
312 // in order to draw to it for the yuv->rgb conversion.
Greg Danielba0ff782020-01-07 15:42:57 -0500313 auto renderTargetContext = GrRenderTargetContext::MakeFromBackendTexture(
314 ctx, grColorType, std::move(imageColorSpace), backendTexture, 1, imageOrigin,
315 nullptr, textureReleaseProc, releaseContext);
Brian Salomond2fcfb52018-09-17 21:57:11 -0400316 if (!renderTargetContext) {
317 return nullptr;
318 }
319
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400320 return SkImage_Gpu::ConvertYUVATexturesToRGB(ctx, yuvColorSpace, yuvaTextures, yuvaIndices,
Brian Salomonf05e6d32018-12-20 08:41:41 -0500321 imageSize, imageOrigin, renderTargetContext.get());
Robert Phillipsc25db632017-12-13 09:22:45 -0500322}
323
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400324sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopy(GrContext* ctx, SkYUVColorSpace yuvColorSpace,
Brian Salomon6a426c12018-03-15 12:16:02 -0400325 const GrBackendTexture yuvTextures[3],
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400326 GrSurfaceOrigin imageOrigin,
Brian Salomon6a426c12018-03-15 12:16:02 -0400327 sk_sp<SkColorSpace> imageColorSpace) {
Weiliang Chenbed9d5e2018-05-22 18:44:02 -0400328 // TODO: SkImageSourceChannel input is being ingored right now. Setup correctly in the future.
329 SkYUVAIndex yuvaIndices[4] = {
Robert Phillips94ade752018-10-09 12:32:31 -0400330 SkYUVAIndex{0, SkColorChannel::kR},
331 SkYUVAIndex{1, SkColorChannel::kR},
332 SkYUVAIndex{2, SkColorChannel::kR},
Robert Phillips66a97342018-10-04 09:10:29 -0400333 SkYUVAIndex{-1, SkColorChannel::kA}};
Weiliang Chenbed9d5e2018-05-22 18:44:02 -0400334 SkISize size{yuvTextures[0].width(), yuvTextures[0].height()};
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400335 return SkImage_Gpu::MakeFromYUVATexturesCopy(ctx, yuvColorSpace, yuvTextures, yuvaIndices,
336 size, imageOrigin, std::move(imageColorSpace));
bsalomon993a4212015-05-29 11:37:25 -0700337}
reed56179002015-07-07 06:11:19 -0700338
Brian Salomond2fcfb52018-09-17 21:57:11 -0400339sk_sp<SkImage> SkImage::MakeFromYUVTexturesCopyWithExternalBackend(
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400340 GrContext* ctx, SkYUVColorSpace yuvColorSpace, const GrBackendTexture yuvTextures[3],
341 GrSurfaceOrigin imageOrigin, const GrBackendTexture& backendTexture,
Brian Salomond2fcfb52018-09-17 21:57:11 -0400342 sk_sp<SkColorSpace> imageColorSpace) {
343 SkYUVAIndex yuvaIndices[4] = {
Robert Phillips94ade752018-10-09 12:32:31 -0400344 SkYUVAIndex{0, SkColorChannel::kR},
345 SkYUVAIndex{1, SkColorChannel::kR},
346 SkYUVAIndex{2, SkColorChannel::kR},
Robert Phillips66a97342018-10-04 09:10:29 -0400347 SkYUVAIndex{-1, SkColorChannel::kA}};
Brian Salomond2fcfb52018-09-17 21:57:11 -0400348 SkISize size{yuvTextures[0].width(), yuvTextures[0].height()};
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400349 return SkImage_Gpu::MakeFromYUVATexturesCopyWithExternalBackend(
350 ctx, yuvColorSpace, yuvTextures, yuvaIndices, size, imageOrigin, backendTexture,
Robert Phillipseb3eb982019-08-19 13:35:48 -0400351 std::move(imageColorSpace), nullptr, nullptr);
Brian Salomond2fcfb52018-09-17 21:57:11 -0400352}
353
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400354sk_sp<SkImage> SkImage::MakeFromNV12TexturesCopy(GrContext* ctx, SkYUVColorSpace yuvColorSpace,
Brian Salomon6a426c12018-03-15 12:16:02 -0400355 const GrBackendTexture nv12Textures[2],
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400356 GrSurfaceOrigin imageOrigin,
brianosmandddbe382016-07-20 13:55:39 -0700357 sk_sp<SkColorSpace> imageColorSpace) {
Weiliang Chenbed9d5e2018-05-22 18:44:02 -0400358 // TODO: SkImageSourceChannel input is being ingored right now. Setup correctly in the future.
359 SkYUVAIndex yuvaIndices[4] = {
Robert Phillips94ade752018-10-09 12:32:31 -0400360 SkYUVAIndex{0, SkColorChannel::kR},
361 SkYUVAIndex{1, SkColorChannel::kR},
362 SkYUVAIndex{1, SkColorChannel::kG},
Robert Phillips66a97342018-10-04 09:10:29 -0400363 SkYUVAIndex{-1, SkColorChannel::kA}};
Weiliang Chenbed9d5e2018-05-22 18:44:02 -0400364 SkISize size{nv12Textures[0].width(), nv12Textures[0].height()};
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400365 return SkImage_Gpu::MakeFromYUVATexturesCopy(ctx, yuvColorSpace, nv12Textures, yuvaIndices,
366 size, imageOrigin, std::move(imageColorSpace));
Robert Phillipsc25db632017-12-13 09:22:45 -0500367}
368
Brian Salomond2fcfb52018-09-17 21:57:11 -0400369sk_sp<SkImage> SkImage::MakeFromNV12TexturesCopyWithExternalBackend(
370 GrContext* ctx,
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400371 SkYUVColorSpace yuvColorSpace,
Brian Salomond2fcfb52018-09-17 21:57:11 -0400372 const GrBackendTexture nv12Textures[2],
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400373 GrSurfaceOrigin imageOrigin,
374 const GrBackendTexture& backendTexture,
Robert Phillipseb3eb982019-08-19 13:35:48 -0400375 sk_sp<SkColorSpace> imageColorSpace,
376 TextureReleaseProc textureReleaseProc,
377 ReleaseContext releaseContext) {
Brian Salomond2fcfb52018-09-17 21:57:11 -0400378 SkYUVAIndex yuvaIndices[4] = {
Robert Phillips94ade752018-10-09 12:32:31 -0400379 SkYUVAIndex{0, SkColorChannel::kR},
380 SkYUVAIndex{1, SkColorChannel::kR},
381 SkYUVAIndex{1, SkColorChannel::kG},
Robert Phillips66a97342018-10-04 09:10:29 -0400382 SkYUVAIndex{-1, SkColorChannel::kA}};
Brian Salomond2fcfb52018-09-17 21:57:11 -0400383 SkISize size{nv12Textures[0].width(), nv12Textures[0].height()};
Robert Phillipsb6df1c12018-10-05 10:31:34 -0400384 return SkImage_Gpu::MakeFromYUVATexturesCopyWithExternalBackend(
385 ctx, yuvColorSpace, nv12Textures, yuvaIndices, size, imageOrigin, backendTexture,
Robert Phillipseb3eb982019-08-19 13:35:48 -0400386 std::move(imageColorSpace), textureReleaseProc, releaseContext);
Brian Salomond2fcfb52018-09-17 21:57:11 -0400387}
388
Greg Daniel5f4b09d2018-06-12 16:39:59 -0400389static sk_sp<SkImage> create_image_from_producer(GrContext* context, GrTextureProducer* producer,
390 SkAlphaType at, uint32_t id,
Greg Daniel5f4b09d2018-06-12 16:39:59 -0400391 GrMipMapped mipMapped) {
Greg Daniel81b98972019-12-13 11:09:43 -0500392 // TODO: have texture producer return a GrSurfaceProxyView
Brian Osman6064e1c2018-10-19 14:27:54 -0400393 sk_sp<GrTextureProxy> proxy(producer->refTextureProxy(mipMapped));
Robert Phillips3798c862017-03-27 11:08:16 -0400394 if (!proxy) {
Brian Osman041f7df2017-02-07 11:23:28 -0500395 return nullptr;
396 }
Greg Daniel81b98972019-12-13 11:09:43 -0500397 GrSurfaceOrigin origin = proxy->origin();
398 const GrSwizzle& swizzle = proxy->textureSwizzle();
399 GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
400 return sk_make_sp<SkImage_Gpu>(sk_ref_sp(context), id, at, std::move(view),
Brian Salomon729fc0c2019-09-30 16:33:11 +0000401 sk_ref_sp(producer->colorSpace()));
Brian Osman041f7df2017-02-07 11:23:28 -0500402}
403
Brian Osmand566e2e2019-08-14 13:19:04 -0400404sk_sp<SkImage> SkImage::makeTextureImage(GrContext* context, GrMipMapped mipMapped) const {
Brian Osman041f7df2017-02-07 11:23:28 -0500405 if (!context) {
406 return nullptr;
407 }
Robert Phillipsfe0963c2019-02-07 13:25:07 -0500408
409 if (this->isTextureBacked()) {
410 if (!as_IB(this)->context()->priv().matches(context)) {
Greg Daniel5f4b09d2018-06-12 16:39:59 -0400411 return nullptr;
412 }
Robert Phillipsfe0963c2019-02-07 13:25:07 -0500413
Robert Phillips6603a172019-03-05 12:35:44 -0500414 sk_sp<GrTextureProxy> proxy = as_IB(this)->asTextureProxyRef(context);
Greg Daniel5f4b09d2018-06-12 16:39:59 -0400415 SkASSERT(proxy);
416 if (GrMipMapped::kNo == mipMapped || proxy->mipMapped() == mipMapped) {
417 return sk_ref_sp(const_cast<SkImage*>(this));
418 }
Brian Salomon1a217eb2019-10-24 10:50:36 -0400419 GrTextureAdjuster adjuster(context, std::move(proxy), this->imageInfo().colorInfo(),
420 this->uniqueID());
Greg Daniel5f4b09d2018-06-12 16:39:59 -0400421 return create_image_from_producer(context, &adjuster, this->alphaType(),
Brian Osmane7fd8c32018-10-19 13:30:39 -0400422 this->uniqueID(), mipMapped);
Brian Osman041f7df2017-02-07 11:23:28 -0500423 }
424
Brian Osmandf7e0752017-04-26 16:20:28 -0400425 if (this->isLazyGenerated()) {
426 GrImageTextureMaker maker(context, this, kDisallow_CachingHint);
Greg Daniel5f4b09d2018-06-12 16:39:59 -0400427 return create_image_from_producer(context, &maker, this->alphaType(),
Brian Osmane7fd8c32018-10-19 13:30:39 -0400428 this->uniqueID(), mipMapped);
Brian Osman041f7df2017-02-07 11:23:28 -0500429 }
430
431 if (const SkBitmap* bmp = as_IB(this)->onPeekBitmap()) {
432 GrBitmapTextureMaker maker(context, *bmp);
Greg Daniel5f4b09d2018-06-12 16:39:59 -0400433 return create_image_from_producer(context, &maker, this->alphaType(),
Brian Osmane7fd8c32018-10-19 13:30:39 -0400434 this->uniqueID(), mipMapped);
Brian Osman041f7df2017-02-07 11:23:28 -0500435 }
436 return nullptr;
437}
438
Greg Daniel7278d682018-03-16 14:57:21 -0400439///////////////////////////////////////////////////////////////////////////////////////////////////
440
Greg Daniela8d92112018-03-09 12:05:04 -0500441sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
442 const GrBackendFormat& backendFormat,
443 int width,
444 int height,
445 GrMipMapped mipMapped,
446 GrSurfaceOrigin origin,
447 SkColorType colorType,
448 SkAlphaType alphaType,
449 sk_sp<SkColorSpace> colorSpace,
Brian Salomoncdd8a0a2019-01-10 12:09:52 -0500450 PromiseImageTextureFulfillProc textureFulfillProc,
451 PromiseImageTextureReleaseProc textureReleaseProc,
Brian Salomonf55e8d52019-01-30 17:28:20 -0500452 PromiseImageTextureDoneProc textureDoneProc,
Brian Salomon0cc57542019-03-08 13:28:46 -0500453 PromiseImageTextureContext textureContext,
454 PromiseImageApiVersion version) {
Robert Phillipsef85d192018-10-09 11:24:09 -0400455 // The contract here is that if 'promiseDoneProc' is passed in it should always be called,
Brian Salomonbe5a0932018-12-10 10:03:26 -0500456 // even if creation of the SkImage fails. Once we call MakePromiseImageLazyProxy it takes
457 // responsibility for calling the done proc.
Brian Salomonf55e8d52019-01-30 17:28:20 -0500458 if (!textureDoneProc) {
Robert Phillipsef85d192018-10-09 11:24:09 -0400459 return nullptr;
460 }
Brian Salomonf55e8d52019-01-30 17:28:20 -0500461 SkScopeExit callDone([textureDoneProc, textureContext]() { textureDoneProc(textureContext); });
Robert Phillipsef85d192018-10-09 11:24:09 -0400462
Brian Salomonbe5a0932018-12-10 10:03:26 -0500463 SkImageInfo info = SkImageInfo::Make(width, height, colorType, alphaType, colorSpace);
464 if (!SkImageInfoIsValid(info)) {
465 return nullptr;
466 }
Robert Phillipsef85d192018-10-09 11:24:09 -0400467
Greg Daniela8d92112018-03-09 12:05:04 -0500468 if (!context) {
469 return nullptr;
470 }
471
472 if (width <= 0 || height <= 0) {
473 return nullptr;
474 }
475
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400476 GrColorType grColorType = SkColorTypeAndFormatToGrColorType(context->priv().caps(),
477 colorType,
478 backendFormat);
479 if (GrColorType::kUnknown == grColorType) {
Greg Daniela8d92112018-03-09 12:05:04 -0500480 return nullptr;
481 }
482
Brian Salomonbe5a0932018-12-10 10:03:26 -0500483 callDone.clear();
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400484 auto proxy = MakePromiseImageLazyProxy(context, width, height, origin,
485 grColorType, backendFormat,
Brian Salomonbe5a0932018-12-10 10:03:26 -0500486 mipMapped, textureFulfillProc, textureReleaseProc,
Brian Salomon0cc57542019-03-08 13:28:46 -0500487 textureDoneProc, textureContext, version);
Greg Daniela8d92112018-03-09 12:05:04 -0500488 if (!proxy) {
489 return nullptr;
490 }
Greg Daniel14b57212019-12-17 16:18:06 -0500491 GrSwizzle swizzle = context->priv().caps()->getReadSwizzle(backendFormat, grColorType);
Greg Daniel81b98972019-12-13 11:09:43 -0500492 GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
Brian Salomon729fc0c2019-09-30 16:33:11 +0000493 return sk_make_sp<SkImage_Gpu>(sk_ref_sp(context), kNeedNewImageUniqueID, alphaType,
Greg Daniel81b98972019-12-13 11:09:43 -0500494 std::move(view), std::move(colorSpace));
Greg Daniela8d92112018-03-09 12:05:04 -0500495}
496
Greg Daniel7278d682018-03-16 14:57:21 -0400497///////////////////////////////////////////////////////////////////////////////////////////////////
498
Brian Osman584b5012018-04-13 15:48:26 -0400499sk_sp<SkImage> SkImage::MakeCrossContextFromPixmap(GrContext* context,
500 const SkPixmap& originalPixmap, bool buildMips,
Brian Osman584b5012018-04-13 15:48:26 -0400501 bool limitToMaxTextureSize) {
Brian Osman63bc48d2017-11-07 10:37:00 -0500502 // Some backends or drivers don't support (safely) moving resources between contexts
Robert Phillips9da87e02019-02-04 13:26:26 -0500503 if (!context || !context->priv().caps()->crossContextTextureSupport()) {
Brian Osman584b5012018-04-13 15:48:26 -0400504 return SkImage::MakeRasterCopy(originalPixmap);
Brian Osman63bc48d2017-11-07 10:37:00 -0500505 }
506
Greg Daniel9e788112018-02-08 14:29:37 -0500507 // If we don't have access to the resource provider and gpu (i.e. in a DDL context) we will not
508 // be able to make everything needed for a GPU CrossContext image. Thus return a raster copy
509 // instead.
Robert Phillips9da87e02019-02-04 13:26:26 -0500510 if (!context->priv().resourceProvider()) {
Brian Osman584b5012018-04-13 15:48:26 -0400511 return SkImage::MakeRasterCopy(originalPixmap);
Greg Daniel9e788112018-02-08 14:29:37 -0500512 }
513
Brian Osman0471a932019-02-07 13:36:56 -0500514 // If non-power-of-two mipmapping isn't supported, ignore the client's request
515 if (!context->priv().caps()->mipMapSupport()) {
516 buildMips = false;
517 }
518
Brian Osman584b5012018-04-13 15:48:26 -0400519 const SkPixmap* pixmap = &originalPixmap;
520 SkAutoPixmapStorage resized;
Robert Phillips9da87e02019-02-04 13:26:26 -0500521 int maxTextureSize = context->priv().caps()->maxTextureSize();
Brian Osman584b5012018-04-13 15:48:26 -0400522 int maxDim = SkTMax(originalPixmap.width(), originalPixmap.height());
523 if (limitToMaxTextureSize && maxDim > maxTextureSize) {
524 float scale = static_cast<float>(maxTextureSize) / maxDim;
525 int newWidth = SkTMin(static_cast<int>(originalPixmap.width() * scale), maxTextureSize);
526 int newHeight = SkTMin(static_cast<int>(originalPixmap.height() * scale), maxTextureSize);
527 SkImageInfo info = originalPixmap.info().makeWH(newWidth, newHeight);
528 if (!resized.tryAlloc(info) || !originalPixmap.scalePixels(resized, kLow_SkFilterQuality)) {
529 return nullptr;
530 }
531 pixmap = &resized;
532 }
Robert Phillips9da87e02019-02-04 13:26:26 -0500533 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
Brian Osman63bc48d2017-11-07 10:37:00 -0500534 // Turn the pixmap into a GrTextureProxy
Brian Osman7dcc6162019-03-25 10:12:57 -0400535 SkBitmap bmp;
536 bmp.installPixels(*pixmap);
537 GrMipMapped mipMapped = buildMips ? GrMipMapped::kYes : GrMipMapped::kNo;
538 sk_sp<GrTextureProxy> proxy = proxyProvider->createProxyFromBitmap(bmp, mipMapped);
Brian Osman63bc48d2017-11-07 10:37:00 -0500539 if (!proxy) {
Brian Osman584b5012018-04-13 15:48:26 -0400540 return SkImage::MakeRasterCopy(*pixmap);
Brian Osman63bc48d2017-11-07 10:37:00 -0500541 }
542
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400543 sk_sp<GrTexture> texture = sk_ref_sp(proxy->peekTexture());
Brian Osman63bc48d2017-11-07 10:37:00 -0500544
545 // Flush any writes or uploads
Greg Daniel4aa13e72019-04-15 14:42:20 -0400546 context->priv().flushSurface(proxy.get());
Robert Phillips9da87e02019-02-04 13:26:26 -0500547 GrGpu* gpu = context->priv().getGpu();
Brian Osman63bc48d2017-11-07 10:37:00 -0500548
Greg Daniel301015c2019-11-18 14:06:46 -0500549 std::unique_ptr<GrSemaphore> sema = gpu->prepareTextureForCrossContextUsage(texture.get());
Brian Osman63bc48d2017-11-07 10:37:00 -0500550
551 auto gen = GrBackendTextureImageGenerator::Make(std::move(texture), proxy->origin(),
Brian Osman584b5012018-04-13 15:48:26 -0400552 std::move(sema), pixmap->colorType(),
553 pixmap->alphaType(),
554 pixmap->info().refColorSpace());
Brian Osman63bc48d2017-11-07 10:37:00 -0500555 return SkImage::MakeFromGenerator(std::move(gen));
556}
557
Derek Sollenberger7a869872017-06-27 15:37:25 -0400558#if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
Stan Iliev7e910df2017-06-02 10:29:21 -0400559sk_sp<SkImage> SkImage::MakeFromAHardwareBuffer(AHardwareBuffer* graphicBuffer, SkAlphaType at,
Stan Iliev505dd572018-09-13 14:20:03 -0400560 sk_sp<SkColorSpace> cs,
561 GrSurfaceOrigin surfaceOrigin) {
562 auto gen = GrAHardwareBufferImageGenerator::Make(graphicBuffer, at, cs, surfaceOrigin);
Stan Iliev7e910df2017-06-02 10:29:21 -0400563 return SkImage::MakeFromGenerator(std::move(gen));
564}
Greg Danielb6c15ba2019-03-04 13:08:25 -0500565
566sk_sp<SkImage> SkImage::MakeFromAHardwareBufferWithData(GrContext* context,
567 const SkPixmap& pixmap,
568 AHardwareBuffer* hardwareBuffer,
569 GrSurfaceOrigin surfaceOrigin) {
570 AHardwareBuffer_Desc bufferDesc;
571 AHardwareBuffer_describe(hardwareBuffer, &bufferDesc);
572
573 if (!SkToBool(bufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE)) {
574 return nullptr;
575 }
576
577 GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat(context,
578 hardwareBuffer,
579 bufferDesc.format,
580 true);
581
582 if (!backendFormat.isValid()) {
583 return nullptr;
584 }
585
586 GrAHardwareBufferUtils::DeleteImageProc deleteImageProc = nullptr;
Stan Ilieva56b04a2019-08-01 14:22:34 -0400587 GrAHardwareBufferUtils::UpdateImageProc updateImageProc = nullptr;
588 GrAHardwareBufferUtils::TexImageCtx deleteImageCtx = nullptr;
Greg Danielb6c15ba2019-03-04 13:08:25 -0500589
590 GrBackendTexture backendTexture =
591 GrAHardwareBufferUtils::MakeBackendTexture(context, hardwareBuffer,
592 bufferDesc.width, bufferDesc.height,
Stan Ilieva56b04a2019-08-01 14:22:34 -0400593 &deleteImageProc, &updateImageProc,
594 &deleteImageCtx, false, backendFormat, true);
Greg Danielb6c15ba2019-03-04 13:08:25 -0500595 if (!backendTexture.isValid()) {
596 return nullptr;
597 }
598 SkASSERT(deleteImageProc);
599
600 SkColorType colorType =
601 GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(bufferDesc.format);
602
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400603 GrColorType grColorType = SkColorTypeToGrColorType(colorType);
Greg Danielb6c15ba2019-03-04 13:08:25 -0500604
605 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
606 if (!proxyProvider) {
607 deleteImageProc(deleteImageCtx);
608 return nullptr;
609 }
610
611 sk_sp<GrTextureProxy> proxy =
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400612 proxyProvider->wrapBackendTexture(backendTexture, grColorType, surfaceOrigin,
Greg Danielb6c15ba2019-03-04 13:08:25 -0500613 kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
614 kRW_GrIOType, deleteImageProc, deleteImageCtx);
615 if (!proxy) {
616 deleteImageProc(deleteImageCtx);
617 return nullptr;
618 }
619
620 sk_sp<SkColorSpace> cs = pixmap.refColorSpace();
621 SkAlphaType at = pixmap.alphaType();
622
Greg Daniel14b57212019-12-17 16:18:06 -0500623 GrSwizzle swizzle = context->priv().caps()->getReadSwizzle(backendFormat, grColorType);
Greg Daniel3912a4b2020-01-14 09:56:04 -0500624 GrSurfaceProxyView view(std::move(proxy), surfaceOrigin, swizzle);
Brian Salomon729fc0c2019-09-30 16:33:11 +0000625 sk_sp<SkImage> image = sk_make_sp<SkImage_Gpu>(sk_ref_sp(context), kNeedNewImageUniqueID, at,
Greg Daniel3912a4b2020-01-14 09:56:04 -0500626 view, cs);
Greg Danielb6c15ba2019-03-04 13:08:25 -0500627 if (!image) {
628 return nullptr;
629 }
630
631 GrDrawingManager* drawingManager = context->priv().drawingManager();
632 if (!drawingManager) {
633 return nullptr;
634 }
635
Greg Daniel3912a4b2020-01-14 09:56:04 -0500636 GrSurfaceContext surfaceContext(context, std::move(view),
Greg Danielbfa19c42019-12-19 16:41:40 -0500637 SkColorTypeToGrColorType(pixmap.colorType()),
Greg Daniel3912a4b2020-01-14 09:56:04 -0500638 pixmap.alphaType(), cs);
Greg Danielb6c15ba2019-03-04 13:08:25 -0500639
640 SkImageInfo srcInfo = SkImageInfo::Make(bufferDesc.width, bufferDesc.height, colorType, at,
641 std::move(cs));
Greg Danielbfa19c42019-12-19 16:41:40 -0500642 surfaceContext.writePixels(srcInfo, pixmap.addr(0, 0), pixmap.rowBytes(), {0, 0});
Greg Danielb6c15ba2019-03-04 13:08:25 -0500643
Greg Daniele6bfb7d2019-04-17 15:26:11 -0400644 GrFlushInfo info;
645 info.fFlags = kSyncCpu_GrFlushFlag;
Greg Danielbfa19c42019-12-19 16:41:40 -0500646 GrSurfaceProxy* p[1] = {surfaceContext.asSurfaceProxy()};
Greg Daniel797efca2019-05-09 14:04:20 -0400647 drawingManager->flush(p, 1, SkSurface::BackendSurfaceAccess::kNoAccess, info,
648 GrPrepareForExternalIORequests());
Greg Danielb6c15ba2019-03-04 13:08:25 -0500649
650 return image;
651}
Stan Iliev7e910df2017-06-02 10:29:21 -0400652#endif
653
reed56179002015-07-07 06:11:19 -0700654///////////////////////////////////////////////////////////////////////////////////////////////////
655
Eric Karl914a36b2017-10-12 12:44:50 -0700656bool SkImage::MakeBackendTextureFromSkImage(GrContext* ctx,
657 sk_sp<SkImage> image,
658 GrBackendTexture* backendTexture,
659 BackendTextureReleaseProc* releaseProc) {
660 if (!image || !ctx || !backendTexture || !releaseProc) {
661 return false;
662 }
663
664 // Ensure we have a texture backed image.
665 if (!image->isTextureBacked()) {
Brian Osmand566e2e2019-08-14 13:19:04 -0400666 image = image->makeTextureImage(ctx);
Eric Karl914a36b2017-10-12 12:44:50 -0700667 if (!image) {
668 return false;
669 }
670 }
671 GrTexture* texture = image->getTexture();
Eric Karl36591e52018-01-19 13:45:02 -0800672 if (!texture) {
673 // In context-loss cases, we may not have a texture.
674 return false;
675 }
Eric Karl914a36b2017-10-12 12:44:50 -0700676
677 // If the image's context doesn't match the provided context, fail.
678 if (texture->getContext() != ctx) {
679 return false;
680 }
681
682 // Flush any pending IO on the texture.
Greg Daniel4aa13e72019-04-15 14:42:20 -0400683 ctx->priv().flushSurface(as_IB(image)->peekProxy());
Eric Karl914a36b2017-10-12 12:44:50 -0700684
685 // We must make a copy of the image if the image is not unique, if the GrTexture owned by the
686 // image is not unique, or if the texture wraps an external object.
Robert Phillipsaee18c92019-09-06 11:48:27 -0400687 if (!image->unique() || !texture->unique() ||
Eric Karl914a36b2017-10-12 12:44:50 -0700688 texture->resourcePriv().refsWrappedObjects()) {
689 // onMakeSubset will always copy the image.
Robert Phillips6603a172019-03-05 12:35:44 -0500690 image = as_IB(image)->onMakeSubset(ctx, image->bounds());
Eric Karl914a36b2017-10-12 12:44:50 -0700691 if (!image) {
692 return false;
693 }
694
695 texture = image->getTexture();
Eric Karl36591e52018-01-19 13:45:02 -0800696 if (!texture) {
697 return false;
698 }
Eric Karl914a36b2017-10-12 12:44:50 -0700699
700 // Flush to ensure that the copy is completed before we return the texture.
Greg Daniel4aa13e72019-04-15 14:42:20 -0400701 ctx->priv().flushSurface(as_IB(image)->peekProxy());
Eric Karl914a36b2017-10-12 12:44:50 -0700702 }
703
704 SkASSERT(!texture->resourcePriv().refsWrappedObjects());
Robert Phillipsaee18c92019-09-06 11:48:27 -0400705 SkASSERT(texture->unique());
Eric Karl914a36b2017-10-12 12:44:50 -0700706 SkASSERT(image->unique());
707
708 // Take a reference to the GrTexture and release the image.
709 sk_sp<GrTexture> textureRef(SkSafeRef(texture));
710 image = nullptr;
711
712 // Steal the backend texture from the GrTexture, releasing the GrTexture in the process.
713 return GrTexture::StealBackendTexture(std::move(textureRef), backendTexture, releaseProc);
714}