blob: fb02f3487af6042f571c34765aec864c793fb0e1 [file] [log] [blame]
Jim Van Verthf49262d2018-10-02 12:07:20 -04001/*
2 * Copyright 2018 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 <cstddef>
9#include <cstring>
10#include <type_traits>
11
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/core/SkYUVASizeInfo.h"
13#include "include/gpu/GrContext.h"
14#include "include/gpu/GrTexture.h"
15#include "include/private/GrRecordingContext.h"
16#include "src/core/SkAutoPixmapStorage.h"
17#include "src/core/SkMipMap.h"
18#include "src/core/SkScopeExit.h"
19#include "src/gpu/GrClip.h"
20#include "src/gpu/GrContextPriv.h"
21#include "src/gpu/GrGpu.h"
22#include "src/gpu/GrRecordingContextPriv.h"
23#include "src/gpu/GrRenderTargetContext.h"
24#include "src/gpu/GrTextureProducer.h"
25#include "src/gpu/SkGr.h"
26#include "src/gpu/effects/GrYUVtoRGBEffect.h"
27#include "src/image/SkImage_Gpu.h"
28#include "src/image/SkImage_GpuYUVA.h"
Jim Van Verthf49262d2018-10-02 12:07:20 -040029
Brian Salomon5ad6fd32019-03-21 15:30:08 -040030static constexpr auto kAssumedColorType = kRGBA_8888_SkColorType;
31
Jim Van Verthcea39022018-10-12 16:15:34 -040032SkImage_GpuYUVA::SkImage_GpuYUVA(sk_sp<GrContext> context, int width, int height, uint32_t uniqueID,
Jim Van Verthf49262d2018-10-02 12:07:20 -040033 SkYUVColorSpace colorSpace, sk_sp<GrTextureProxy> proxies[],
Jim Van Verth0e671942018-11-09 12:03:57 -050034 int numProxies, const SkYUVAIndex yuvaIndices[4],
Brian Salomonf05e6d32018-12-20 08:41:41 -050035 GrSurfaceOrigin origin, sk_sp<SkColorSpace> imageColorSpace)
Brian Salomon5ad6fd32019-03-21 15:30:08 -040036 : INHERITED(std::move(context), width, height, uniqueID, kAssumedColorType,
Jim Van Verth8026ccc2018-10-04 13:10:39 -040037 // If an alpha channel is present we always switch to kPremul. This is because,
38 // although the planar data is always un-premul, the final interleaved RGB image
39 // is/would-be premul.
Brian Salomon5ad6fd32019-03-21 15:30:08 -040040 GetAlphaTypeFromYUVAIndices(yuvaIndices), std::move(imageColorSpace))
Jim Van Verth0e671942018-11-09 12:03:57 -050041 , fNumProxies(numProxies)
Jim Van Verth8026ccc2018-10-04 13:10:39 -040042 , fYUVColorSpace(colorSpace)
43 , fOrigin(origin) {
Jim Van Verth0e671942018-11-09 12:03:57 -050044 // The caller should have done this work, just verifying
45 SkDEBUGCODE(int textureCount;)
46 SkASSERT(SkYUVAIndex::AreValidIndices(yuvaIndices, &textureCount));
47 SkASSERT(textureCount == fNumProxies);
48
49 for (int i = 0; i < numProxies; ++i) {
Jim Van Verthf49262d2018-10-02 12:07:20 -040050 fProxies[i] = std::move(proxies[i]);
51 }
52 memcpy(fYUVAIndices, yuvaIndices, 4*sizeof(SkYUVAIndex));
Jim Van Verthf49262d2018-10-02 12:07:20 -040053}
54
Jim Van Verth3e4c2f32019-01-11 13:32:45 -050055// For onMakeColorSpace()
56SkImage_GpuYUVA::SkImage_GpuYUVA(const SkImage_GpuYUVA* image, sk_sp<SkColorSpace> targetCS)
Brian Salomon5ad6fd32019-03-21 15:30:08 -040057 : INHERITED(image->fContext, image->width(), image->height(), kNeedNewImageUniqueID,
58 kAssumedColorType,
59 // If an alpha channel is present we always switch to kPremul. This is because,
60 // although the planar data is always un-premul, the final interleaved RGB image
61 // is/would-be premul.
62 GetAlphaTypeFromYUVAIndices(image->fYUVAIndices), std::move(targetCS))
63 , fNumProxies(image->fNumProxies)
64 , fYUVColorSpace(image->fYUVColorSpace)
65 , fOrigin(image->fOrigin)
66 // Since null fFromColorSpace means no GrColorSpaceXform, we turn a null
67 // image->refColorSpace() into an explicit SRGB.
68 , fFromColorSpace(image->colorSpace() ? image->refColorSpace() : SkColorSpace::MakeSRGB()) {
69 // The caller should have done this work, just verifying
Jim Van Verth3e4c2f32019-01-11 13:32:45 -050070 SkDEBUGCODE(int textureCount;)
71 SkASSERT(SkYUVAIndex::AreValidIndices(image->fYUVAIndices, &textureCount));
72 SkASSERT(textureCount == fNumProxies);
73
Brian Salomonad8efda2019-05-10 09:22:49 -040074 if (image->fRGBProxy) {
75 fRGBProxy = image->fRGBProxy; // we ref in this case, not move
76 } else {
77 for (int i = 0; i < fNumProxies; ++i) {
78 fProxies[i] = image->fProxies[i]; // we ref in this case, not move
79 }
Jim Van Verth3e4c2f32019-01-11 13:32:45 -050080 }
81 memcpy(fYUVAIndices, image->fYUVAIndices, 4 * sizeof(SkYUVAIndex));
82}
83
Jim Van Verthf49262d2018-10-02 12:07:20 -040084SkImage_GpuYUVA::~SkImage_GpuYUVA() {}
85
Robert Phillips8defcc12019-03-05 15:58:59 -050086bool SkImage_GpuYUVA::setupMipmapsForPlanes(GrRecordingContext* context) const {
Brian Salomonad8efda2019-05-10 09:22:49 -040087 // We shouldn't get here if the planes were already flattened to RGBA.
88 SkASSERT(fProxies[0] && !fRGBProxy);
Robert Phillips8defcc12019-03-05 15:58:59 -050089 if (!context || !fContext->priv().matches(context)) {
90 return false;
91 }
92
Jim Van Verth0e671942018-11-09 12:03:57 -050093 for (int i = 0; i < fNumProxies; ++i) {
Jim Van Verth30e0d7f2018-11-02 13:36:42 -040094 GrTextureProducer::CopyParams copyParams;
95 int mipCount = SkMipMap::ComputeLevelCount(fProxies[i]->width(), fProxies[i]->height());
Robert Phillips9da87e02019-02-04 13:26:26 -050096 if (mipCount && GrGpu::IsACopyNeededForMips(fContext->priv().caps(),
Jim Van Verth30e0d7f2018-11-02 13:36:42 -040097 fProxies[i].get(),
98 GrSamplerState::Filter::kMipMap,
99 &copyParams)) {
Robert Phillips8defcc12019-03-05 15:58:59 -0500100 auto mippedProxy = GrCopyBaseMipMapToTextureProxy(context, fProxies[i].get());
Jim Van Verthf542cab2018-11-07 12:08:21 -0500101 if (!mippedProxy) {
102 return false;
103 }
104 fProxies[i] = mippedProxy;
Jim Van Verth30e0d7f2018-11-02 13:36:42 -0400105 }
106 }
107 return true;
108}
109
Jim Van Verthf49262d2018-10-02 12:07:20 -0400110//////////////////////////////////////////////////////////////////////////////////////////////////
Jim Van Verthf49262d2018-10-02 12:07:20 -0400111
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400112GrSemaphoresSubmitted SkImage_GpuYUVA::onFlush(GrContext* context, const GrFlushInfo& info) {
113 if (!context || !fContext->priv().matches(context) || fContext->abandoned()) {
114 return GrSemaphoresSubmitted::kNo;
115 }
116
Brian Salomonad8efda2019-05-10 09:22:49 -0400117 GrSurfaceProxy* proxies[4] = {fProxies[0].get(), fProxies[1].get(),
118 fProxies[2].get(), fProxies[3].get()};
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400119 int numProxies = fNumProxies;
120 if (fRGBProxy) {
Brian Salomonad8efda2019-05-10 09:22:49 -0400121 // Either we've already flushed the flattening draw or the flattening is unflushed. In the
122 // latter case it should still be ok to just pass fRGBProxy because it in turn depends on
123 // the planar proxies and will cause all of their work to flush as well.
124 proxies[0] = fRGBProxy.get();
125 numProxies = 1;
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400126 }
127 return context->priv().flushSurfaces(proxies, numProxies, info);
128}
129
Robert Phillips193c4212019-03-04 12:18:53 -0500130GrTextureProxy* SkImage_GpuYUVA::peekProxy() const {
131 return fRGBProxy.get();
132}
133
Robert Phillips6603a172019-03-05 12:35:44 -0500134sk_sp<GrTextureProxy> SkImage_GpuYUVA::asTextureProxyRef(GrRecordingContext* context) const {
135 if (fRGBProxy) {
136 return fRGBProxy;
Jim Van Verthf49262d2018-10-02 12:07:20 -0400137 }
138
Robert Phillips6603a172019-03-05 12:35:44 -0500139 if (!context || !fContext->priv().matches(context)) {
140 return nullptr;
141 }
142
143 const GrBackendFormat format =
Brian Salomon5ad6fd32019-03-21 15:30:08 -0400144 fContext->priv().caps()->getBackendFormatFromColorType(kAssumedColorType);
Robert Phillips6603a172019-03-05 12:35:44 -0500145
146 // Needs to create a render target in order to draw to it for the yuv->rgb conversion.
147 sk_sp<GrRenderTargetContext> renderTargetContext(
Brian Salomon5ad6fd32019-03-21 15:30:08 -0400148 context->priv().makeDeferredRenderTargetContext(
149 format, SkBackingFit::kExact, this->width(), this->height(),
150 kRGBA_8888_GrPixelConfig, this->refColorSpace(), 1, GrMipMapped::kNo, fOrigin));
Robert Phillips6603a172019-03-05 12:35:44 -0500151 if (!renderTargetContext) {
152 return nullptr;
153 }
154
Brian Salomon5ad6fd32019-03-21 15:30:08 -0400155 sk_sp<GrColorSpaceXform> colorSpaceXform;
156 if (fFromColorSpace) {
157 colorSpaceXform = GrColorSpaceXform::Make(fFromColorSpace.get(), this->alphaType(),
158 this->colorSpace(), this->alphaType());
159 }
Robert Phillips6603a172019-03-05 12:35:44 -0500160 const SkRect rect = SkRect::MakeIWH(this->width(), this->height());
161 if (!RenderYUVAToRGBA(fContext.get(), renderTargetContext.get(), rect, fYUVColorSpace,
162 std::move(colorSpaceXform), fProxies, fYUVAIndices)) {
163 return nullptr;
164 }
165
166 fRGBProxy = renderTargetContext->asTextureProxyRef();
Brian Salomonad8efda2019-05-10 09:22:49 -0400167 for (auto& p : fProxies) {
168 p.reset();
169 }
Jim Van Verthf49262d2018-10-02 12:07:20 -0400170 return fRGBProxy;
171}
172
Robert Phillips6603a172019-03-05 12:35:44 -0500173sk_sp<GrTextureProxy> SkImage_GpuYUVA::asMippedTextureProxyRef(GrRecordingContext* context) const {
174 if (!context || !fContext->priv().matches(context)) {
175 return nullptr;
176 }
177
Jim Van Verth803a5022018-11-05 15:55:53 -0500178 // if invalid or already has miplevels
Robert Phillips6603a172019-03-05 12:35:44 -0500179 auto proxy = this->asTextureProxyRef(context);
Jim Van Verth803a5022018-11-05 15:55:53 -0500180 if (!proxy || GrMipMapped::kYes == fRGBProxy->mipMapped()) {
181 return proxy;
182 }
183
184 // need to generate mips for the proxy
Robert Phillips8defcc12019-03-05 15:58:59 -0500185 if (auto mippedProxy = GrCopyBaseMipMapToTextureProxy(context, proxy.get())) {
Jim Van Verth803a5022018-11-05 15:55:53 -0500186 fRGBProxy = mippedProxy;
187 return mippedProxy;
188 }
189
190 // failed to generate mips
191 return nullptr;
192}
193
Jim Van Verth9bf81202018-10-30 15:53:36 -0400194//////////////////////////////////////////////////////////////////////////////////////////////////
195
Robert Phillips6603a172019-03-05 12:35:44 -0500196sk_sp<SkImage> SkImage_GpuYUVA::onMakeColorTypeAndColorSpace(GrRecordingContext*,
197 SkColorType,
Brian Osmanf48c9962019-01-14 11:15:50 -0500198 sk_sp<SkColorSpace> targetCS) const {
199 // We explicitly ignore color type changes, for now.
200
Jim Van Verth3e4c2f32019-01-11 13:32:45 -0500201 // we may need a mutex here but for now we expect usage to be in a single thread
202 if (fOnMakeColorSpaceTarget &&
Brian Osmanf48c9962019-01-14 11:15:50 -0500203 SkColorSpace::Equals(targetCS.get(), fOnMakeColorSpaceTarget.get())) {
Jim Van Verth3e4c2f32019-01-11 13:32:45 -0500204 return fOnMakeColorSpaceResult;
205 }
Brian Osmanf48c9962019-01-14 11:15:50 -0500206 sk_sp<SkImage> result = sk_sp<SkImage>(new SkImage_GpuYUVA(this, targetCS));
Jim Van Verth3e4c2f32019-01-11 13:32:45 -0500207 if (result) {
Brian Osmanf48c9962019-01-14 11:15:50 -0500208 fOnMakeColorSpaceTarget = targetCS;
Jim Van Verth3e4c2f32019-01-11 13:32:45 -0500209 fOnMakeColorSpaceResult = result;
210 }
211 return result;
212}
213
214//////////////////////////////////////////////////////////////////////////////////////////////////
215
Jim Van Verth9bf81202018-10-30 15:53:36 -0400216sk_sp<SkImage> SkImage::MakeFromYUVATextures(GrContext* ctx,
217 SkYUVColorSpace colorSpace,
218 const GrBackendTexture yuvaTextures[],
219 const SkYUVAIndex yuvaIndices[4],
220 SkISize imageSize,
221 GrSurfaceOrigin imageOrigin,
222 sk_sp<SkColorSpace> imageColorSpace) {
Jim Van Verth0e671942018-11-09 12:03:57 -0500223 int numTextures;
224 if (!SkYUVAIndex::AreValidIndices(yuvaIndices, &numTextures)) {
225 return nullptr;
Jim Van Verth9bf81202018-10-30 15:53:36 -0400226 }
227
Jim Van Verth0e671942018-11-09 12:03:57 -0500228 sk_sp<GrTextureProxy> tempTextureProxies[4];
Jim Van Verth53275362018-11-09 15:42:35 -0500229 if (!SkImage_GpuBase::MakeTempTextureProxies(ctx, yuvaTextures, numTextures, yuvaIndices,
230 imageOrigin, tempTextureProxies)) {
Jim Van Verth0e671942018-11-09 12:03:57 -0500231 return nullptr;
Jim Van Verth9bf81202018-10-30 15:53:36 -0400232 }
233
234 return sk_make_sp<SkImage_GpuYUVA>(sk_ref_sp(ctx), imageSize.width(), imageSize.height(),
235 kNeedNewImageUniqueID, colorSpace, tempTextureProxies,
Brian Salomonf05e6d32018-12-20 08:41:41 -0500236 numTextures, yuvaIndices, imageOrigin, imageColorSpace);
Jim Van Verth9bf81202018-10-30 15:53:36 -0400237}
Jim Van Verthc8429ad2018-11-20 11:12:37 -0500238
239sk_sp<SkImage> SkImage::MakeFromYUVAPixmaps(
240 GrContext* context, SkYUVColorSpace yuvColorSpace, const SkPixmap yuvaPixmaps[],
241 const SkYUVAIndex yuvaIndices[4], SkISize imageSize, GrSurfaceOrigin imageOrigin,
242 bool buildMips, bool limitToMaxTextureSize, sk_sp<SkColorSpace> imageColorSpace) {
Mike Reed6a5f7e22019-05-23 15:30:07 -0400243 if (!context) {
244 return nullptr; // until we impl this for raster backend
245 }
246
Jim Van Verthc8429ad2018-11-20 11:12:37 -0500247 int numPixmaps;
248 if (!SkYUVAIndex::AreValidIndices(yuvaIndices, &numPixmaps)) {
249 return nullptr;
250 }
251
Brian Osman7dcc6162019-03-25 10:12:57 -0400252 if (!context->priv().caps()->mipMapSupport()) {
253 buildMips = false;
254 }
255
Jim Van Verthc8429ad2018-11-20 11:12:37 -0500256 // Make proxies
Robert Phillips9da87e02019-02-04 13:26:26 -0500257 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
Jim Van Verthc8429ad2018-11-20 11:12:37 -0500258 sk_sp<GrTextureProxy> tempTextureProxies[4];
259 for (int i = 0; i < numPixmaps; ++i) {
260 const SkPixmap* pixmap = &yuvaPixmaps[i];
261 SkAutoPixmapStorage resized;
Robert Phillips9da87e02019-02-04 13:26:26 -0500262 int maxTextureSize = context->priv().caps()->maxTextureSize();
Jim Van Verthc8429ad2018-11-20 11:12:37 -0500263 int maxDim = SkTMax(yuvaPixmaps[i].width(), yuvaPixmaps[i].height());
264 if (limitToMaxTextureSize && maxDim > maxTextureSize) {
265 float scale = static_cast<float>(maxTextureSize) / maxDim;
266 int newWidth = SkTMin(static_cast<int>(yuvaPixmaps[i].width() * scale),
267 maxTextureSize);
268 int newHeight = SkTMin(static_cast<int>(yuvaPixmaps[i].height() * scale),
269 maxTextureSize);
270 SkImageInfo info = yuvaPixmaps[i].info().makeWH(newWidth, newHeight);
271 if (!resized.tryAlloc(info) ||
272 !yuvaPixmaps[i].scalePixels(resized, kLow_SkFilterQuality)) {
273 return nullptr;
274 }
275 pixmap = &resized;
276 }
277 // Turn the pixmap into a GrTextureProxy
Brian Osman7dcc6162019-03-25 10:12:57 -0400278 SkBitmap bmp;
279 bmp.installPixels(*pixmap);
280 GrMipMapped mipMapped = buildMips ? GrMipMapped::kYes : GrMipMapped::kNo;
281 tempTextureProxies[i] = proxyProvider->createProxyFromBitmap(bmp, mipMapped);
Jim Van Verthc8429ad2018-11-20 11:12:37 -0500282 if (!tempTextureProxies[i]) {
283 return nullptr;
284 }
285 }
286
287 return sk_make_sp<SkImage_GpuYUVA>(sk_ref_sp(context), imageSize.width(), imageSize.height(),
288 kNeedNewImageUniqueID, yuvColorSpace, tempTextureProxies,
Brian Salomonf05e6d32018-12-20 08:41:41 -0500289 numPixmaps, yuvaIndices, imageOrigin, imageColorSpace);
Jim Van Verthc8429ad2018-11-20 11:12:37 -0500290}
291
292
Jim Van Verth8bbce0e2018-10-08 14:34:52 -0400293/////////////////////////////////////////////////////////////////////////////////////////////////
Brian Salomoncdd8a0a2019-01-10 12:09:52 -0500294sk_sp<SkImage> SkImage_GpuYUVA::MakePromiseYUVATexture(
295 GrContext* context,
296 SkYUVColorSpace yuvColorSpace,
297 const GrBackendFormat yuvaFormats[],
298 const SkISize yuvaSizes[],
299 const SkYUVAIndex yuvaIndices[4],
300 int imageWidth,
301 int imageHeight,
302 GrSurfaceOrigin imageOrigin,
303 sk_sp<SkColorSpace> imageColorSpace,
304 PromiseImageTextureFulfillProc textureFulfillProc,
305 PromiseImageTextureReleaseProc textureReleaseProc,
306 PromiseImageTextureDoneProc promiseDoneProc,
Brian Salomon0cc57542019-03-08 13:28:46 -0500307 PromiseImageTextureContext textureContexts[],
308 PromiseImageApiVersion version) {
Jim Van Verthf00b1622018-10-10 13:03:23 -0400309 int numTextures;
310 bool valid = SkYUVAIndex::AreValidIndices(yuvaIndices, &numTextures);
311
Brian Salomonbe5a0932018-12-10 10:03:26 -0500312 // The contract here is that if 'promiseDoneProc' is passed in it should always be called,
313 // even if creation of the SkImage fails. Once we call MakePromiseImageLazyProxy it takes
314 // responsibility for calling the done proc.
315 if (!promiseDoneProc) {
316 return nullptr;
Jim Van Verthf00b1622018-10-10 13:03:23 -0400317 }
Brian Salomonbe5a0932018-12-10 10:03:26 -0500318 int proxiesCreated = 0;
319 SkScopeExit callDone([promiseDoneProc, textureContexts, numTextures, &proxiesCreated]() {
320 for (int i = proxiesCreated; i < numTextures; ++i) {
321 promiseDoneProc(textureContexts[i]);
322 }
323 });
Jim Van Verthf00b1622018-10-10 13:03:23 -0400324
325 if (!valid) {
326 return nullptr;
327 }
Robert Phillipsef85d192018-10-09 11:24:09 -0400328
Jim Van Verth8bbce0e2018-10-08 14:34:52 -0400329 if (!context) {
330 return nullptr;
331 }
332
Greg Kaiser9a2169e2019-02-10 17:29:46 -0800333 if (imageWidth <= 0 || imageHeight <= 0) {
Jim Van Verth8bbce0e2018-10-08 14:34:52 -0400334 return nullptr;
335 }
336
Jim Van Verth8bbce0e2018-10-08 14:34:52 -0400337 SkAlphaType at = (-1 != yuvaIndices[SkYUVAIndex::kA_Index].fIndex) ? kPremul_SkAlphaType
338 : kOpaque_SkAlphaType;
Brian Salomon5ad6fd32019-03-21 15:30:08 -0400339 SkImageInfo info = SkImageInfo::Make(imageWidth, imageHeight, kAssumedColorType,
Jim Van Verth8bbce0e2018-10-08 14:34:52 -0400340 at, imageColorSpace);
341 if (!SkImageInfoIsValid(info)) {
342 return nullptr;
343 }
344
Jim Van Verthf9f07352018-10-24 10:32:20 -0400345 // verify sizes with expected texture count
Jim Van Verth8f11e432018-10-18 14:36:59 -0400346 for (int i = 0; i < numTextures; ++i) {
Jim Van Verthf9f07352018-10-24 10:32:20 -0400347 if (yuvaSizes[i].isEmpty()) {
Jim Van Verth8f11e432018-10-18 14:36:59 -0400348 return nullptr;
Jim Van Verth8bbce0e2018-10-08 14:34:52 -0400349 }
350 }
Jim Van Verthe24b5872018-10-29 16:26:02 -0400351 for (int i = numTextures; i < SkYUVASizeInfo::kMaxCount; ++i) {
Jim Van Verthf9f07352018-10-24 10:32:20 -0400352 if (!yuvaSizes[i].isEmpty()) {
Jim Van Verth8f11e432018-10-18 14:36:59 -0400353 return nullptr;
354 }
Jim Van Verthf99a6742018-10-18 16:13:18 +0000355 }
Jim Van Verth8bbce0e2018-10-08 14:34:52 -0400356
357 // Get lazy proxies
Jim Van Verth8bbce0e2018-10-08 14:34:52 -0400358 sk_sp<GrTextureProxy> proxies[4];
Jim Van Verthf00b1622018-10-10 13:03:23 -0400359 for (int texIdx = 0; texIdx < numTextures; ++texIdx) {
Brian Salomonf391d0f2018-12-14 09:18:50 -0500360 GrPixelConfig config =
Robert Phillips9da87e02019-02-04 13:26:26 -0500361 context->priv().caps()->getYUVAConfigFromBackendFormat(yuvaFormats[texIdx]);
Brian Salomonf391d0f2018-12-14 09:18:50 -0500362 if (config == kUnknown_GrPixelConfig) {
Jim Van Verthf00b1622018-10-10 13:03:23 -0400363 return nullptr;
364 }
Brian Salomonbe5a0932018-12-10 10:03:26 -0500365 proxies[texIdx] = MakePromiseImageLazyProxy(
366 context, yuvaSizes[texIdx].width(), yuvaSizes[texIdx].height(), imageOrigin, config,
367 yuvaFormats[texIdx], GrMipMapped::kNo, textureFulfillProc, textureReleaseProc,
Brian Salomon0cc57542019-03-08 13:28:46 -0500368 promiseDoneProc, textureContexts[texIdx], version);
Brian Salomonbe5a0932018-12-10 10:03:26 -0500369 ++proxiesCreated;
Jim Van Verthf00b1622018-10-10 13:03:23 -0400370 if (!proxies[texIdx]) {
371 return nullptr;
Jim Van Verth8bbce0e2018-10-08 14:34:52 -0400372 }
373 }
374
Jim Van Verthcea39022018-10-12 16:15:34 -0400375 return sk_make_sp<SkImage_GpuYUVA>(sk_ref_sp(context), imageWidth, imageHeight,
Jim Van Verth0e671942018-11-09 12:03:57 -0500376 kNeedNewImageUniqueID, yuvColorSpace, proxies, numTextures,
Brian Salomonf05e6d32018-12-20 08:41:41 -0500377 yuvaIndices, imageOrigin, std::move(imageColorSpace));
Jim Van Verth8bbce0e2018-10-08 14:34:52 -0400378}