static sk_sp<GrSurfaceProxy> make_backend(GrContext* context, const ProxyParams& p, GrBackendTexture* backendTex) { GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider(); GrGpu* gpu = context->contextPriv().getGpu(); *backendTex = gpu->createTestingOnlyBackendTexture(nullptr, p.fSize, p.fSize, p.fConfig, false, GrMipMapped::kNo); return proxyProvider->createWrappedTextureProxy(*backendTex, p.fOrigin); }
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PromiseImageTest, reporter, ctxInfo) { const int kWidth = 10; const int kHeight = 10; GrContext* ctx = ctxInfo.grContext(); GrGpu* gpu = ctx->contextPriv().getGpu(); for (bool releaseImageEarly : {true, false}) { GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture( nullptr, kWidth, kHeight, kRGBA_8888_GrPixelConfig, true, GrMipMapped::kNo); REPORTER_ASSERT(reporter, backendTex.isValid()); GrBackendFormat backendFormat = backendTex.format(); REPORTER_ASSERT(reporter, backendFormat.isValid()); PromiseTextureChecker promiseChecker(backendTex); GrSurfaceOrigin texOrigin = kTopLeft_GrSurfaceOrigin; sk_sp<SkImage> refImg( SkImage_Gpu::MakePromiseTexture(ctx, backendFormat, kWidth, kHeight, GrMipMapped::kNo, texOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr, PromiseTextureChecker::Fulfill, PromiseTextureChecker::Release, PromiseTextureChecker::Done, &promiseChecker)); SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight); sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info); SkCanvas* canvas = surface->getCanvas(); int expectedFulfillCnt = 0; int expectedReleaseCnt = 0; int expectedDoneCnt = 0; canvas->drawImage(refImg, 0, 0); REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker, true, expectedFulfillCnt, expectedReleaseCnt, true, expectedDoneCnt, reporter)); bool isVulkan = kVulkan_GrBackend == ctx->contextPriv().getBackend(); canvas->flush(); expectedFulfillCnt++; expectedReleaseCnt++; REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker, !isVulkan, expectedFulfillCnt, expectedReleaseCnt, !isVulkan, expectedDoneCnt, reporter)); gpu->testingOnly_flushGpuAndSync(); REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker, true, expectedFulfillCnt, expectedReleaseCnt, true, expectedDoneCnt, reporter)); canvas->drawImage(refImg, 0, 0); canvas->drawImage(refImg, 0, 0); canvas->flush(); expectedFulfillCnt++; expectedReleaseCnt++; gpu->testingOnly_flushGpuAndSync(); REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker, true, expectedFulfillCnt, expectedReleaseCnt, true, expectedDoneCnt, reporter)); // Now test code path on Vulkan where we released the texture, but the GPU isn't done with // resource yet and we do another draw. We should only call fulfill on the first draw and // use the cached GrBackendTexture on the second. Release should only be called after the // second draw is finished. canvas->drawImage(refImg, 0, 0); canvas->flush(); expectedFulfillCnt++; expectedReleaseCnt++; REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker, !isVulkan, expectedFulfillCnt, expectedReleaseCnt, !isVulkan, expectedDoneCnt, reporter)); canvas->drawImage(refImg, 0, 0); if (releaseImageEarly) { refImg.reset(); } REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker, !isVulkan, expectedFulfillCnt, expectedReleaseCnt, !isVulkan, expectedDoneCnt, reporter)); canvas->flush(); expectedFulfillCnt++; gpu->testingOnly_flushGpuAndSync(); expectedReleaseCnt++; if (releaseImageEarly) { expectedDoneCnt++; } REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker, true, expectedFulfillCnt, expectedReleaseCnt, !isVulkan, expectedDoneCnt, reporter)); expectedFulfillCnt = promiseChecker.fFulfillCount; expectedReleaseCnt = promiseChecker.fReleaseCount; if (!releaseImageEarly) { refImg.reset(); expectedDoneCnt++; } REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker, true, expectedFulfillCnt, expectedReleaseCnt, true, expectedDoneCnt, reporter)); gpu->deleteTestingOnlyBackendTexture(backendTex); } }