void GrResourceIOProcessor::TextureSampler::reset(GrResourceProvider* resourceProvider, sk_sp<GrTextureProxy> proxy, const GrSamplerParams& params, GrShaderFlags visibility) { // For now, end the deferral at this time. Once all the TextureSamplers are swapped over // to taking a GrSurfaceProxy just use the IORefs on the proxy GrTexture* texture = proxy->instantiate(resourceProvider); SkASSERT(texture); fTexture.set(SkRef(texture), kRead_GrIOType); fParams = params; fParams.setFilterMode(SkTMin(params.filterMode(), texture->texturePriv().highestFilterMode())); fVisibility = visibility; }
sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext( sk_sp<GrRenderTargetProxy> rtp, sk_sp<SkColorSpace> colorSpace, const SkSurfaceProps* surfaceProps) { if (this->wasAbandoned()) { return nullptr; } // SkSurface catches bad color space usage at creation. This check handles anything that slips // by, including internal usage. We allow a null color space here, for read/write pixels and // other special code paths. If a color space is provided, though, enforce all other rules. if (colorSpace && !SkSurface_Gpu::Valid(fContext, rtp->config(), colorSpace.get())) { SkDEBUGFAIL("Invalid config and colorspace combination"); return nullptr; } bool useDIF = false; if (surfaceProps) { useDIF = surfaceProps->isUseDeviceIndependentFonts(); } if (useDIF && fContext->caps()->shaderCaps()->pathRenderingSupport() && rtp->isStencilBufferMultisampled()) { // TODO: defer stencil buffer attachment for PathRenderingDrawContext sk_sp<GrRenderTarget> rt(sk_ref_sp(rtp->instantiate(fContext->textureProvider()))); GrStencilAttachment* sb = fContext->resourceProvider()->attachStencilAttachment(rt.get()); if (sb) { return sk_sp<GrRenderTargetContext>(new GrPathRenderingRenderTargetContext( fContext, this, std::move(rtp), std::move(colorSpace), surfaceProps, fContext->getAuditTrail(), fSingleOwner)); } } return sk_sp<GrRenderTargetContext>(new GrRenderTargetContext(fContext, this, std::move(rtp), std::move(colorSpace), surfaceProps, fContext->getAuditTrail(), fSingleOwner)); }
// This tests the basic capabilities of the uniquely keyed texture proxies. Does assigning // and looking them up work, etc. static void basic_test(GrContext* context, skiatest::Reporter* reporter, sk_sp<GrTextureProxy> proxy) { static int id = 1; GrResourceProvider* resourceProvider = context->priv().resourceProvider(); GrProxyProvider* proxyProvider = context->priv().proxyProvider(); GrResourceCache* cache = context->priv().getResourceCache(); int startCacheCount = cache->getResourceCount(); GrUniqueKey key; if (proxy->getUniqueKey().isValid()) { key = proxy->getUniqueKey(); } else { GrMakeKeyFromImageID(&key, id, SkIRect::MakeWH(64, 64)); ++id; // Assigning the uniqueKey adds the proxy to the hash but doesn't force instantiation REPORTER_ASSERT(reporter, !proxyProvider->numUniqueKeyProxies_TestOnly()); SkAssertResult(proxyProvider->assignUniqueKeyToProxy(key, proxy.get())); } REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly()); REPORTER_ASSERT(reporter, startCacheCount == cache->getResourceCount()); // setUniqueKey had better stick REPORTER_ASSERT(reporter, key == proxy->getUniqueKey()); // We just added it, surely we can find it REPORTER_ASSERT(reporter, proxyProvider->findOrCreateProxyByUniqueKey( key, kBottomLeft_GrSurfaceOrigin)); REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly()); int expectedCacheCount = startCacheCount + (proxy->isInstantiated() ? 0 : 1); // Once instantiated, the backing resource should have the same key SkAssertResult(proxy->instantiate(resourceProvider)); const GrUniqueKey texKey = proxy->peekSurface()->getUniqueKey(); REPORTER_ASSERT(reporter, texKey.isValid()); REPORTER_ASSERT(reporter, key == texKey); // An Unbudgeted-cacheable resource will not get purged when a proxy with the same key is // deleted. bool expectResourceToOutliveProxy = proxy->peekSurface()->resourcePriv().budgetedType() == GrBudgetedType::kUnbudgetedCacheable; // An Unbudgeted-uncacheable resource is never kept alive if it's ref cnt reaches zero even if // it has a key. bool expectDeletingProxyToDeleteResource = proxy->peekSurface()->resourcePriv().budgetedType() == GrBudgetedType::kUnbudgetedUncacheable; // deleting the proxy should delete it from the hash but not the cache proxy = nullptr; if (expectDeletingProxyToDeleteResource) { expectedCacheCount -= 1; } REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly()); REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount()); // If the proxy was cached refinding it should bring it back to life proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin); REPORTER_ASSERT(reporter, proxy); REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly()); REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount()); // Mega-purging it should remove it from both the hash and the cache proxy = nullptr; cache->purgeAllUnlocked(); if (!expectResourceToOutliveProxy) { expectedCacheCount--; } REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount()); // If the texture was deleted then the proxy should no longer be findable. Otherwise, it should // be. proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin); REPORTER_ASSERT(reporter, expectResourceToOutliveProxy ? (bool)proxy : !proxy); REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount()); if (expectResourceToOutliveProxy) { proxy.reset(); GrUniqueKeyInvalidatedMessage msg(texKey, context->priv().contextID()); SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(msg); cache->purgeAsNeeded(); expectedCacheCount--; proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin); REPORTER_ASSERT(reporter, !proxy); REPORTER_ASSERT(reporter, expectedCacheCount == cache->getResourceCount()); } }