GrProxyProvider.cpp revision f6f7b67ac230b14a725fbdabe951c70ea5b4428f
11afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips/* 21afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips * Copyright 2018 Google Inc. 31afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips * 41afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips * Use of this source code is governed by a BSD-style license that can be 51afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips * found in the LICENSE file. 61afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips */ 71afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 81afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips#include "GrProxyProvider.h" 91afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 101afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips#include "GrCaps.h" 110bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips#include "GrRenderTarget.h" 121afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips#include "GrResourceKey.h" 131afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips#include "GrResourceProvider.h" 141afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips#include "GrSurfaceProxy.h" 151afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips#include "GrSurfaceProxyPriv.h" 161afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips#include "GrTexture.h" 171afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips#include "GrTextureProxyCacheAccess.h" 180bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips#include "GrTextureRenderTargetProxy.h" 191afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips#include "../private/GrSingleOwner.h" 20a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel#include "SkBitmap.h" 219d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel#include "SkGr.h" 229d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel#include "SkImage.h" 239d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel#include "SkImage_Base.h" 24a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel#include "SkImageInfoPriv.h" 25a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel#include "SkImagePriv.h" 260bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips#include "SkMipMap.h" 27a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel#include "SkTraceEvent.h" 281afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 291afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips#define ASSERT_SINGLE_OWNER \ 301afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);) 311afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 321afd4cdb0800e2e395b465da24eb71e0e834dafaRobert PhillipsGrProxyProvider::GrProxyProvider(GrResourceProvider* resourceProvider, 331afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips GrResourceCache* resourceCache, 341afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips sk_sp<const GrCaps> caps, 351afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips GrSingleOwner* owner) 361afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips : fResourceProvider(resourceProvider) 371afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips , fResourceCache(resourceCache) 384d12051d351a0a210d62b2d7fcf2de33c712a468Robert Phillips , fAbandoned(false) 391afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips , fCaps(caps) 401afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips#ifdef SK_DEBUG 411afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips , fSingleOwner(owner) 421afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips#endif 431afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips{ 441afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 451afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 461afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 471afd4cdb0800e2e395b465da24eb71e0e834dafaRobert PhillipsGrProxyProvider::~GrProxyProvider() { 481afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(!fUniquelyKeyedProxies.count()); 491afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 501afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 51adbe1328789071d1f742023edd93b6948eed9470Robert Phillipsbool GrProxyProvider::assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextureProxy* proxy) { 521afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips ASSERT_SINGLE_OWNER 531afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(key.isValid()); 541afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips if (this->isAbandoned() || !proxy) { 55adbe1328789071d1f742023edd93b6948eed9470Robert Phillips return false; 561afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 571afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 581afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips // If there is already a GrResource with this key then the caller has violated the normal 591afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips // usage pattern of uniquely keyed resources (e.g., they have created one w/o first seeing 601afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips // if it already existed in the cache). 61d5f9cdd4b3a6ab0e49bb1a56f2e52e2f40edd0faRobert Phillips SkASSERT(!fResourceCache || !fResourceCache->findAndRefUniqueResource(key)); 621afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 631afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips // Uncached resources can never have a unique key, unless they're wrapped resources. Wrapped 641afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips // resources are a special case: the unique keys give us a weak ref so that we can reuse the 651afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips // same resource (rather than re-wrapping). When a wrapped resource is no longer referenced, 661afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips // it will always be released - it is never converted to a scratch resource. 671afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips if (SkBudgeted::kNo == proxy->isBudgeted() && 681afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips (!proxy->priv().isInstantiated() || 691afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips !proxy->priv().peekSurface()->resourcePriv().refsWrappedObjects())) { 70adbe1328789071d1f742023edd93b6948eed9470Robert Phillips return false; 711afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 721afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 731afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(!fUniquelyKeyedProxies.find(key)); // multiple proxies can't get the same key 741afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 751afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips proxy->cacheAccess().setUniqueKey(this, key); 761afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(proxy->getUniqueKey() == key); 771afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips fUniquelyKeyedProxies.add(proxy); 78adbe1328789071d1f742023edd93b6948eed9470Robert Phillips return true; 791afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 801afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 811afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipsvoid GrProxyProvider::adoptUniqueKeyFromSurface(GrTextureProxy* proxy, const GrSurface* surf) { 821afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(surf->getUniqueKey().isValid()); 831afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips proxy->cacheAccess().setUniqueKey(this, surf->getUniqueKey()); 841afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(proxy->getUniqueKey() == surf->getUniqueKey()); 851afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips // multiple proxies can't get the same key 861afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(!fUniquelyKeyedProxies.find(surf->getUniqueKey())); 871afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips fUniquelyKeyedProxies.add(proxy); 881afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 891afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 901afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipsvoid GrProxyProvider::removeUniqueKeyFromProxy(const GrUniqueKey& key, GrTextureProxy* proxy) { 911afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips ASSERT_SINGLE_OWNER 921afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips if (this->isAbandoned() || !proxy) { 931afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips return; 941afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 951afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips this->processInvalidProxyUniqueKey(key, proxy, true); 961afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 971afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 981afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipssk_sp<GrTextureProxy> GrProxyProvider::findProxyByUniqueKey(const GrUniqueKey& key, 991afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips GrSurfaceOrigin origin) { 1001afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips ASSERT_SINGLE_OWNER 1011afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 1021afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips if (this->isAbandoned()) { 1031afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips return nullptr; 1041afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 1051afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 1061afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips sk_sp<GrTextureProxy> result = sk_ref_sp(fUniquelyKeyedProxies.find(key)); 1071afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips if (result) { 1081afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(result->origin() == origin); 1091afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 1101afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips return result; 1111afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 1121afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 113adbe1328789071d1f742023edd93b6948eed9470Robert Phillipssk_sp<GrTextureProxy> GrProxyProvider::createWrapped(sk_sp<GrTexture> tex, GrSurfaceOrigin origin) { 114adbe1328789071d1f742023edd93b6948eed9470Robert Phillips#ifdef SK_DEBUG 115adbe1328789071d1f742023edd93b6948eed9470Robert Phillips if (tex->getUniqueKey().isValid()) { 116adbe1328789071d1f742023edd93b6948eed9470Robert Phillips SkASSERT(!this->findProxyByUniqueKey(tex->getUniqueKey(), origin)); 117adbe1328789071d1f742023edd93b6948eed9470Robert Phillips } 118adbe1328789071d1f742023edd93b6948eed9470Robert Phillips#endif 119adbe1328789071d1f742023edd93b6948eed9470Robert Phillips 120adbe1328789071d1f742023edd93b6948eed9470Robert Phillips if (tex->asRenderTarget()) { 121adbe1328789071d1f742023edd93b6948eed9470Robert Phillips return sk_sp<GrTextureProxy>(new GrTextureRenderTargetProxy(std::move(tex), origin)); 122adbe1328789071d1f742023edd93b6948eed9470Robert Phillips } else { 123adbe1328789071d1f742023edd93b6948eed9470Robert Phillips return sk_sp<GrTextureProxy>(new GrTextureProxy(std::move(tex), origin)); 124adbe1328789071d1f742023edd93b6948eed9470Robert Phillips } 125adbe1328789071d1f742023edd93b6948eed9470Robert Phillips} 126adbe1328789071d1f742023edd93b6948eed9470Robert Phillips 1271afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipssk_sp<GrTextureProxy> GrProxyProvider::findOrCreateProxyByUniqueKey(const GrUniqueKey& key, 1281afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips GrSurfaceOrigin origin) { 1291afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips ASSERT_SINGLE_OWNER 1301afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 1311afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips if (this->isAbandoned()) { 1321afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips return nullptr; 1331afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 1341afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 1351afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips sk_sp<GrTextureProxy> result = this->findProxyByUniqueKey(key, origin); 1361afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips if (result) { 1371afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips return result; 1381afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 1391afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 140d5f9cdd4b3a6ab0e49bb1a56f2e52e2f40edd0faRobert Phillips if (!fResourceCache) { 141d5f9cdd4b3a6ab0e49bb1a56f2e52e2f40edd0faRobert Phillips return nullptr; 142d5f9cdd4b3a6ab0e49bb1a56f2e52e2f40edd0faRobert Phillips } 143d5f9cdd4b3a6ab0e49bb1a56f2e52e2f40edd0faRobert Phillips 1441afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips GrGpuResource* resource = fResourceCache->findAndRefUniqueResource(key); 1451afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips if (!resource) { 1461afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips return nullptr; 1471afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 1481afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 1491afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips sk_sp<GrTexture> texture(static_cast<GrSurface*>(resource)->asTexture()); 1501afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(texture); 1511afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 152adbe1328789071d1f742023edd93b6948eed9470Robert Phillips result = this->createWrapped(std::move(texture), origin); 1531afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(result->getUniqueKey() == key); 154adbe1328789071d1f742023edd93b6948eed9470Robert Phillips // createWrapped should've added this for us 1551afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(fUniquelyKeyedProxies.find(key)); 1561afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips return result; 1571afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 1581afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 1590bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillipssk_sp<GrTextureProxy> GrProxyProvider::createInstantiatedProxy(const GrSurfaceDesc& desc, 1600bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips SkBackingFit fit, 1610bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips SkBudgeted budgeted, 1620bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips uint32_t flags) { 1630bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips sk_sp<GrTexture> tex; 1640bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 1650bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips if (SkBackingFit::kApprox == fit) { 1660bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips tex = fResourceProvider->createApproxTexture(desc, flags); 1670bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips } else { 1680bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips tex = fResourceProvider->createTexture(desc, budgeted, flags); 1690bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips } 1700bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips if (!tex) { 1710bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips return nullptr; 1720bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips } 1730bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 174adbe1328789071d1f742023edd93b6948eed9470Robert Phillips return this->createWrapped(std::move(tex), desc.fOrigin); 1750bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips} 1760bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 1771afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipssk_sp<GrTextureProxy> GrProxyProvider::createTextureProxy(const GrSurfaceDesc& desc, 1781afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkBudgeted budgeted, 1790bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips const void* srcData, size_t rowBytes) { 1801afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips ASSERT_SINGLE_OWNER 1811afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 182579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips if (this->isAbandoned()) { 183579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips return nullptr; 184579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips } 185579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips 1860bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips if (srcData) { 1870bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips GrMipLevel mipLevel = { srcData, rowBytes }; 1880bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 189fb3abcd8c335132b6ad8434a171516102bbf4495Greg Daniel sk_sp<GrTexture> tex = fResourceProvider->createTexture(desc, budgeted, 190fb3abcd8c335132b6ad8434a171516102bbf4495Greg Daniel SkBackingFit::kExact, mipLevel); 1910bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips if (!tex) { 1920bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips return nullptr; 1930bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips } 1940bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 195adbe1328789071d1f742023edd93b6948eed9470Robert Phillips return this->createWrapped(std::move(tex), desc.fOrigin); 1961afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 1971afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 1980bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips return this->createProxy(desc, SkBackingFit::kExact, budgeted); 1991afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 2001afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 2019d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Danielsk_sp<GrTextureProxy> GrProxyProvider::createTextureProxy(sk_sp<SkImage> srcImage, 2029d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel GrSurfaceFlags flags, 2039d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel GrSurfaceOrigin origin, 2049d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel int sampleCnt, 205fb3abcd8c335132b6ad8434a171516102bbf4495Greg Daniel SkBudgeted budgeted, 206fb3abcd8c335132b6ad8434a171516102bbf4495Greg Daniel SkBackingFit fit) { 2079d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel ASSERT_SINGLE_OWNER 2089d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel SkASSERT(srcImage); 2099d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel 2109d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel if (this->isAbandoned()) { 2119d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel return nullptr; 2129d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel } 2139d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel 2149d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel GrSurfaceDesc desc; 2159d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel desc.fWidth = srcImage->width(); 2169d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel desc.fHeight = srcImage->height(); 2179d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel desc.fFlags = flags; 2189d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel desc.fOrigin = origin; 2199d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel desc.fSampleCnt = sampleCnt; 2209d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel desc.fConfig = SkImageInfo2GrPixelConfig(as_IB(srcImage)->onImageInfo(), *this->caps()); 2219d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel 2229d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel sk_sp<GrTextureProxy> proxy = this->createLazyProxy( 223fb3abcd8c335132b6ad8434a171516102bbf4495Greg Daniel [desc, budgeted, srcImage, fit] 224ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips (GrResourceProvider* resourceProvider) { 2259d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel if (!resourceProvider) { 2260a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel // Nothing to clean up here. Once the proxy (and thus lambda) is deleted the ref 2270a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel // on srcImage will be released. 2289d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel return sk_sp<GrTexture>(); 2299d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel } 2309d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel SkPixmap pixMap; 2319d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel SkAssertResult(srcImage->peekPixels(&pixMap)); 2329d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel GrMipLevel mipLevel = { pixMap.addr(), pixMap.rowBytes() }; 2339d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel 234fb3abcd8c335132b6ad8434a171516102bbf4495Greg Daniel return resourceProvider->createTexture(desc, budgeted, fit, mipLevel); 235fb3abcd8c335132b6ad8434a171516102bbf4495Greg Daniel }, desc, GrMipMapped::kNo, fit, budgeted); 2369d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel 2379d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel if (fResourceProvider) { 2389d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however 2399d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel // we're better off instantiating the proxy immediately here. 2409d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel if (!proxy->priv().doLazyInstantiation(fResourceProvider)) { 2419d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel return nullptr; 2429d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel } 2439d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel } 2449d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel return proxy; 2459d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel} 2469d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel 247308150821517a4dc73e43db1022d3e8bd589d2dbGreg Danielsk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxy(const GrSurfaceDesc& desc, 248308150821517a4dc73e43db1022d3e8bd589d2dbGreg Daniel SkBudgeted budgeted) { 249579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips ASSERT_SINGLE_OWNER 250579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips 251579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips if (this->isAbandoned()) { 252579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips return nullptr; 253579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips } 254579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips 255f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel return this->createProxy(desc, GrMipMapped::kYes, SkBackingFit::kExact, budgeted, 0); 2561afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 2571afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 258a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Danielsk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxyFromBitmap(const SkBitmap& bitmap, 259a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel SkColorSpace* dstColorSpace) { 260a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel SkDestinationSurfaceColorMode mipColorMode = dstColorSpace 261a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware 262a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel : SkDestinationSurfaceColorMode::kLegacy; 263a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 264a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (!SkImageInfoIsValid(bitmap.info(), mipColorMode)) { 265a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return nullptr; 266a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 267a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 268a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel SkPixmap pixmap; 269a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (!bitmap.peekPixels(&pixmap)) { 270a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return nullptr; 271a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 272a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 273a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel ATRACE_ANDROID_FRAMEWORK("Upload MipMap Texture [%ux%u]", pixmap.width(), pixmap.height()); 274a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel sk_sp<SkMipMap> mipmaps(SkMipMap::Build(pixmap, mipColorMode, nullptr)); 275a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (!mipmaps) { 276a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return nullptr; 277a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 278a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 279a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (mipmaps->countLevels() < 0) { 280a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return nullptr; 281a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 282a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 283a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel // In non-ddl we will always instantiate right away. Thus we never want to copy the SkBitmap 284a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel // even if its mutable. In ddl, if the bitmap is mutable then we must make a copy since the 285a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel // upload of the data to the gpu can happen at anytime and the bitmap may change by then. 2867e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel SkCopyPixelsMode copyMode = this->mutableBitmapsNeedCopy() ? kIfMutable_SkCopyPixelsMode 2877e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel : kNever_SkCopyPixelsMode; 288a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel sk_sp<SkImage> baseLevel = SkMakeImageFromRasterBitmap(bitmap, copyMode); 289a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 290a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (!baseLevel) { 291a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return nullptr; 292a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 293a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 294a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *this->caps()); 295a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 296a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (0 == mipmaps->countLevels()) { 297a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return this->createTextureProxy(baseLevel, kNone_GrSurfaceFlags, kTopLeft_GrSurfaceOrigin, 298a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 1, SkBudgeted::kYes, SkBackingFit::kExact); 299a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 300a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 301a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 302a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel sk_sp<GrTextureProxy> proxy = this->createLazyProxy( 303a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel [desc, baseLevel, mipmaps, mipColorMode] 304ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips (GrResourceProvider* resourceProvider) { 305a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (!resourceProvider) { 306a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return sk_sp<GrTexture>(); 307a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 308a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 309a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel const int mipLevelCount = mipmaps->countLevels() + 1; 310a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]); 311a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 312a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel SkPixmap pixmap; 313a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel SkAssertResult(baseLevel->peekPixels(&pixmap)); 314a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 315a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel // DDL TODO: Instead of copying all this info into GrMipLevels we should just plumb 316a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel // the use of SkMipMap down through Ganesh. 317a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel texels[0].fPixels = pixmap.addr(); 318a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel texels[0].fRowBytes = pixmap.rowBytes(); 319a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 320a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel for (int i = 1; i < mipLevelCount; ++i) { 321a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel SkMipMap::Level generatedMipLevel; 322a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel mipmaps->getLevel(i - 1, &generatedMipLevel); 323a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel texels[i].fPixels = generatedMipLevel.fPixmap.addr(); 324a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel texels[i].fRowBytes = generatedMipLevel.fPixmap.rowBytes(); 325a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel SkASSERT(texels[i].fPixels); 326a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 327a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 328a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return resourceProvider->createTexture(desc, SkBudgeted::kYes, texels.get(), 329a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel mipLevelCount, mipColorMode); 330a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel }, desc, GrMipMapped::kYes, SkBackingFit::kExact, SkBudgeted::kYes); 331a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 332a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (fResourceProvider) { 333a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however 334a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel // we're better off instantiating the proxy immediately here. 335a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (!proxy->priv().doLazyInstantiation(fResourceProvider)) { 336a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return nullptr; 337a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 338a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 339a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return proxy; 340a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel} 341a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 3420bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillipssk_sp<GrTextureProxy> GrProxyProvider::createProxy(const GrSurfaceDesc& desc, 343f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel GrMipMapped mipMapped, 3440bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips SkBackingFit fit, 3450bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips SkBudgeted budgeted, 3460bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips uint32_t flags) { 3470bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips SkASSERT(0 == flags || GrResourceProvider::kNoPendingIO_Flag == flags); 3480bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 349f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel if (GrMipMapped::kYes == mipMapped) { 350f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel // SkMipMap doesn't include the base level in the level count so we have to add 1 351f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel int mipCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1; 352f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel if (1 == mipCount) { 353f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel mipMapped = GrMipMapped::kNo; 354f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel } 355f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel } 356f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel 357f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel if (!this->caps()->validateSurfaceDesc(desc, mipMapped)) { 3583a2cc2c2ec124de36d2544b2a523ef1dd317ca32Brian Salomon return nullptr; 3595bb82cbecd740d21b92e8d2944280ab6eb6af7a6Brian Salomon } 3603a2cc2c2ec124de36d2544b2a523ef1dd317ca32Brian Salomon GrSurfaceDesc copyDesc = desc; 361bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon if (desc.fFlags & kRenderTarget_GrSurfaceFlag) { 362bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon copyDesc.fSampleCnt = 363bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon this->caps()->getRenderTargetSampleCount(desc.fSampleCnt, desc.fConfig); 364bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon } 3653a2cc2c2ec124de36d2544b2a523ef1dd317ca32Brian Salomon 366bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon if (copyDesc.fFlags & kRenderTarget_GrSurfaceFlag) { 3670bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips // We know anything we instantiate later from this deferred path will be 3680bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips // both texturable and renderable 369bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon return sk_sp<GrTextureProxy>( 370f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel new GrTextureRenderTargetProxy(*this->caps(), copyDesc, mipMapped, fit, budgeted, 371f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel flags)); 3720bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips } 3730bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 374f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel return sk_sp<GrTextureProxy>(new GrTextureProxy(copyDesc, mipMapped, fit, budgeted, nullptr, 0, 375f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel flags)); 3760bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips} 3770bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 378adbe1328789071d1f742023edd93b6948eed9470Robert Phillipssk_sp<GrTextureProxy> GrProxyProvider::createWrappedTextureProxy( 379adbe1328789071d1f742023edd93b6948eed9470Robert Phillips const GrBackendTexture& backendTex, 380adbe1328789071d1f742023edd93b6948eed9470Robert Phillips GrSurfaceOrigin origin, 381adbe1328789071d1f742023edd93b6948eed9470Robert Phillips GrWrapOwnership ownership, 382adbe1328789071d1f742023edd93b6948eed9470Robert Phillips ReleaseProc releaseProc, 383adbe1328789071d1f742023edd93b6948eed9470Robert Phillips ReleaseContext releaseCtx) { 384f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips if (this->isAbandoned()) { 385f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips return nullptr; 386f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips } 387f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips 388f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel GrSurfaceDesc desc; 389f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel desc.fOrigin = origin; 390f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel desc.fWidth = backendTex.width(); 391f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel desc.fHeight = backendTex.height(); 392f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel desc.fConfig = backendTex.config(); 393f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel GrMipMapped mipMapped = backendTex.hasMipMaps() ? GrMipMapped::kYes : GrMipMapped::kNo; 394f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel 3956a0176bf033c780bb92396220db8140f30948345Greg Daniel sk_sp<GrReleaseProcHelper> releaseHelper; 3966a0176bf033c780bb92396220db8140f30948345Greg Daniel if (releaseProc) { 3976a0176bf033c780bb92396220db8140f30948345Greg Daniel releaseHelper.reset(new GrReleaseProcHelper(releaseProc, releaseCtx)); 3986a0176bf033c780bb92396220db8140f30948345Greg Daniel } 3996a0176bf033c780bb92396220db8140f30948345Greg Daniel 400f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel sk_sp<GrTextureProxy> proxy = this->createLazyProxy( 4016a0176bf033c780bb92396220db8140f30948345Greg Daniel [backendTex, ownership, releaseHelper] 402ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips (GrResourceProvider* resourceProvider) { 403f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel if (!resourceProvider) { 4040a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel // If this had a releaseHelper it will get unrefed when we delete this lambda 4050a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel // and will call the release proc so that the client knows they can free the 4060a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel // underlying backend object. 407f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel return sk_sp<GrTexture>(); 408f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel } 409f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel 410f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel sk_sp<GrTexture> tex = resourceProvider->wrapBackendTexture(backendTex, 411f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel ownership); 412f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel if (!tex) { 413f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel return sk_sp<GrTexture>(); 414f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel } 4156a0176bf033c780bb92396220db8140f30948345Greg Daniel if (releaseHelper) { 4160a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel // This gives the texture a ref on the releaseHelper 4170a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel tex->setRelease(releaseHelper); 418f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel } 419f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel SkASSERT(!tex->asRenderTarget()); // Strictly a GrTexture 420f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel // Make sure we match how we created the proxy with SkBudgeted::kNo 421f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel SkASSERT(SkBudgeted::kNo == tex->resourcePriv().isBudgeted()); 422f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel 423f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel return tex; 424f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel }, desc, mipMapped, SkBackingFit::kExact, SkBudgeted::kNo); 425f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel 426f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel if (fResourceProvider) { 427f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however, 428f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel // we're better off instantiating the proxy immediately here. 429bddcc95383250940fce5491576a1636f3087cba9Greg Daniel if (!proxy->priv().doLazyInstantiation(fResourceProvider)) { 430bddcc95383250940fce5491576a1636f3087cba9Greg Daniel return nullptr; 431bddcc95383250940fce5491576a1636f3087cba9Greg Daniel } 432f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel } 433f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel return proxy; 4340bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips} 4350bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 4360bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillipssk_sp<GrTextureProxy> GrProxyProvider::createWrappedTextureProxy(const GrBackendTexture& tex, 4370bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips GrSurfaceOrigin origin, 4380bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips int sampleCnt) { 439f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips if (this->isAbandoned()) { 440f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips return nullptr; 441f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips } 442f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips 4430bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips sk_sp<GrTexture> texture(fResourceProvider->wrapRenderableBackendTexture(tex, sampleCnt)); 4440bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips if (!texture) { 4450bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips return nullptr; 4460bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips } 4470bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips SkASSERT(texture->asRenderTarget()); // A GrTextureRenderTarget 4480bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 449adbe1328789071d1f742023edd93b6948eed9470Robert Phillips return this->createWrapped(std::move(texture), origin); 4500bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips} 4510bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 4520bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillipssk_sp<GrSurfaceProxy> GrProxyProvider::createWrappedRenderTargetProxy( 4530bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips const GrBackendRenderTarget& backendRT, 4540bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips GrSurfaceOrigin origin) { 455f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips if (this->isAbandoned()) { 456f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips return nullptr; 457f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips } 458f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips 4590bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips sk_sp<GrRenderTarget> rt(fResourceProvider->wrapBackendRenderTarget(backendRT)); 4600bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips if (!rt) { 4610bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips return nullptr; 4620bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips } 4630bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips SkASSERT(!rt->asTexture()); // Strictly a GrRenderTarget 4640bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips SkASSERT(!rt->getUniqueKey().isValid()); 4650bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 4660bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips return sk_sp<GrSurfaceProxy>(new GrRenderTargetProxy(std::move(rt), origin)); 4670bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips} 4680bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 4690bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillipssk_sp<GrSurfaceProxy> GrProxyProvider::createWrappedRenderTargetProxy(const GrBackendTexture& tex, 4700bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips GrSurfaceOrigin origin, 4710bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips int sampleCnt) { 472f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips if (this->isAbandoned()) { 473f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips return nullptr; 474f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips } 475f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips 4760bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips sk_sp<GrRenderTarget> rt(fResourceProvider->wrapBackendTextureAsRenderTarget(tex, sampleCnt)); 4770bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips if (!rt) { 4780bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips return nullptr; 4790bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips } 4800bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips SkASSERT(!rt->asTexture()); // Strictly a GrRenderTarget 4810bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips SkASSERT(!rt->getUniqueKey().isValid()); 4820bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 4830bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips return sk_sp<GrSurfaceProxy>(new GrRenderTargetProxy(std::move(rt), origin)); 4840bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips} 4850bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 486777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillipssk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback, 487777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips const GrSurfaceDesc& desc, 488777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips GrMipMapped mipMapped, 489777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips SkBackingFit fit, SkBudgeted budgeted) { 490777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) || 491777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips (desc.fWidth > 0 && desc.fHeight > 0)); 492777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips uint32_t flags = GrResourceProvider::kNoPendingIO_Flag; 493457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel 494457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType; 495457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel // For non-ddl draws always make lazy proxy's single use. 496457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel LazyInstantiationType lazyType = fResourceProvider ? LazyInstantiationType::kSingleUse 497457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel : LazyInstantiationType::kMultipleUse; 498457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel 499777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips return sk_sp<GrTextureProxy>(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags) ? 500457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel new GrTextureRenderTargetProxy(std::move(callback), lazyType, desc, 501777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips mipMapped, fit, budgeted, flags) : 502457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel new GrTextureProxy(std::move(callback), lazyType, desc, mipMapped, 503457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel fit, budgeted, flags)); 504777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips} 505777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips 506e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillipssk_sp<GrRenderTargetProxy> GrProxyProvider::createLazyRenderTargetProxy( 507e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips LazyInstantiateCallback&& callback, 508e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips const GrSurfaceDesc& desc, 509e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips Textureable textureable, 510e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips GrMipMapped mipMapped, 511e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips SkBackingFit fit, SkBudgeted budgeted) { 512e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) || 513e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips (desc.fWidth > 0 && desc.fHeight > 0)); 514e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips uint32_t flags = GrResourceProvider::kNoPendingIO_Flag; 515457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel 516457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType; 517457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel // For non-ddl draws always make lazy proxy's single use. 518457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel LazyInstantiationType lazyType = fResourceProvider ? LazyInstantiationType::kSingleUse 519457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel : LazyInstantiationType::kMultipleUse; 520457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel 521e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips if (Textureable::kYes == textureable) { 522457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel return sk_sp<GrRenderTargetProxy>(new GrTextureRenderTargetProxy(std::move(callback), 523457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel lazyType, desc, mipMapped, 524457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel fit, budgeted, flags)); 525e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips } 526e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips 527457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(std::move(callback), lazyType, desc, 528e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips fit, budgeted, flags)); 529e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips} 530e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips 531777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillipssk_sp<GrTextureProxy> GrProxyProvider::createFullyLazyProxy(LazyInstantiateCallback&& callback, 532777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips Renderable renderable, 533ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips GrSurfaceOrigin origin, 534777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips GrPixelConfig config) { 535777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips GrSurfaceDesc desc; 536777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips if (Renderable::kYes == renderable) { 537777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips desc.fFlags = kRenderTarget_GrSurfaceFlag; 538777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips } 539ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips desc.fOrigin = origin; 540777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips desc.fWidth = -1; 541777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips desc.fHeight = -1; 542777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips desc.fConfig = config; 543bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon desc.fSampleCnt = 1; 544777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips 545777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips return this->createLazyProxy(std::move(callback), desc, GrMipMapped::kNo, 546777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips SkBackingFit::kApprox, SkBudgeted::kYes); 547777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips 548777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips} 549777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips 5501afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipsbool GrProxyProvider::IsFunctionallyExact(GrSurfaceProxy* proxy) { 5511afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips return proxy->priv().isExact() || (SkIsPow2(proxy->width()) && SkIsPow2(proxy->height())); 5521afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 5531afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 5541afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipsvoid GrProxyProvider::processInvalidProxyUniqueKey(const GrUniqueKey& key) { 5551afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips // Note: this method is called for the whole variety of GrGpuResources so often 'key' 5561afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips // will not be in 'fUniquelyKeyedProxies'. 5571afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips GrTextureProxy* proxy = fUniquelyKeyedProxies.find(key); 5581afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips if (proxy) { 5591afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips this->processInvalidProxyUniqueKey(key, proxy, false); 5601afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 5611afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 5621afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 5631afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipsvoid GrProxyProvider::processInvalidProxyUniqueKey(const GrUniqueKey& key, GrTextureProxy* proxy, 5641afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips bool invalidateSurface) { 5651afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(proxy); 5661afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(proxy->getUniqueKey().isValid()); 5671afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(proxy->getUniqueKey() == key); 5681afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 5691afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips fUniquelyKeyedProxies.remove(key); 5701afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips proxy->cacheAccess().clearUniqueKey(); 5711afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 5721afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips if (invalidateSurface && proxy->priv().isInstantiated()) { 5731afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips GrSurface* surface = proxy->priv().peekSurface(); 5741afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips if (surface) { 5751afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips surface->resourcePriv().removeUniqueKey(); 5761afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 5771afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 5781afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 5791afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 5801afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipsvoid GrProxyProvider::removeAllUniqueKeys() { 5811afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips UniquelyKeyedProxyHash::Iter iter(&fUniquelyKeyedProxies); 5821afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips for (UniquelyKeyedProxyHash::Iter iter(&fUniquelyKeyedProxies); !iter.done(); ++iter) { 5831afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips GrTextureProxy& tmp = *iter; 5841afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 5851afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips this->processInvalidProxyUniqueKey(tmp.getUniqueKey(), &tmp, false); 5861afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 5871afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(!fUniquelyKeyedProxies.count()); 5881afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 589