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 214f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel GrPixelConfig config = SkImageInfo2GrPixelConfig(as_IB(srcImage)->onImageInfo(), 215f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel *this->caps()); 216f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel 2170a7aa14bf36cbb444b84902a37591d7a9c84fbd0Greg Daniel if (kUnknown_GrPixelConfig == config) { 2180a7aa14bf36cbb444b84902a37591d7a9c84fbd0Greg Daniel return nullptr; 2190a7aa14bf36cbb444b84902a37591d7a9c84fbd0Greg Daniel } 2200a7aa14bf36cbb444b84902a37591d7a9c84fbd0Greg Daniel 221f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel if (SkToBool(flags & kRenderTarget_GrSurfaceFlag)) { 222f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, config); 223f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel if (!sampleCnt) { 224f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel return nullptr; 225f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel } 226f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel } 227f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel 2282a30390ce6130b27c18152edf75d48616adeb934Greg Daniel GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone; 2292a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (SkToBool(flags & kRenderTarget_GrSurfaceFlag)) { 2302a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (fCaps->usesMixedSamples() && sampleCnt > 1) { 2312a30390ce6130b27c18152edf75d48616adeb934Greg Daniel renderTargetFlags |= GrRenderTargetFlags::kMixedSampled; 2322a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 2332a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (fCaps->maxWindowRectangles() > 0) { 2342a30390ce6130b27c18152edf75d48616adeb934Greg Daniel renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport; 2352a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 2362a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 2372a30390ce6130b27c18152edf75d48616adeb934Greg Daniel 2389d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel GrSurfaceDesc desc; 2399d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel desc.fWidth = srcImage->width(); 2409d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel desc.fHeight = srcImage->height(); 2419d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel desc.fFlags = flags; 2429d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel desc.fOrigin = origin; 2439d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel desc.fSampleCnt = sampleCnt; 244f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel desc.fConfig = config; 2459d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel 2469d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel sk_sp<GrTextureProxy> proxy = this->createLazyProxy( 247fb3abcd8c335132b6ad8434a171516102bbf4495Greg Daniel [desc, budgeted, srcImage, fit] 248ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips (GrResourceProvider* resourceProvider) { 2499d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel if (!resourceProvider) { 2500a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel // Nothing to clean up here. Once the proxy (and thus lambda) is deleted the ref 2510a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel // on srcImage will be released. 2529d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel return sk_sp<GrTexture>(); 2539d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel } 2549d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel SkPixmap pixMap; 2559d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel SkAssertResult(srcImage->peekPixels(&pixMap)); 2569d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel GrMipLevel mipLevel = { pixMap.addr(), pixMap.rowBytes() }; 2579d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel 258fb3abcd8c335132b6ad8434a171516102bbf4495Greg Daniel return resourceProvider->createTexture(desc, budgeted, fit, mipLevel); 2592a30390ce6130b27c18152edf75d48616adeb934Greg Daniel }, desc, GrMipMapped::kNo, renderTargetFlags, fit, budgeted); 2609d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel 2619d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel if (fResourceProvider) { 2629d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however 2639d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel // we're better off instantiating the proxy immediately here. 2649d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel if (!proxy->priv().doLazyInstantiation(fResourceProvider)) { 2659d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel return nullptr; 2669d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel } 2679d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel } 2689d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel return proxy; 2699d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel} 2709d86f1d11d1b7a43eb65aed90c437100c2f78f11Greg Daniel 271308150821517a4dc73e43db1022d3e8bd589d2dbGreg Danielsk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxy(const GrSurfaceDesc& desc, 272308150821517a4dc73e43db1022d3e8bd589d2dbGreg Daniel SkBudgeted budgeted) { 273579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips ASSERT_SINGLE_OWNER 274579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips 275579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips if (this->isAbandoned()) { 276579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips return nullptr; 277579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips } 278579f094f1259931c30dfd1623e8e22d74b4a7531Robert Phillips 279f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel return this->createProxy(desc, GrMipMapped::kYes, SkBackingFit::kExact, budgeted, 0); 2801afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 2811afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 282a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Danielsk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxyFromBitmap(const SkBitmap& bitmap, 283a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel SkColorSpace* dstColorSpace) { 284a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel SkDestinationSurfaceColorMode mipColorMode = dstColorSpace 285a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware 286a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel : SkDestinationSurfaceColorMode::kLegacy; 287a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 288a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (!SkImageInfoIsValid(bitmap.info(), mipColorMode)) { 289a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return nullptr; 290a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 291a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 292a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel SkPixmap pixmap; 293a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (!bitmap.peekPixels(&pixmap)) { 294a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return nullptr; 295a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 296a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 297a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel ATRACE_ANDROID_FRAMEWORK("Upload MipMap Texture [%ux%u]", pixmap.width(), pixmap.height()); 298a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel sk_sp<SkMipMap> mipmaps(SkMipMap::Build(pixmap, mipColorMode, nullptr)); 299a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (!mipmaps) { 300a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return nullptr; 301a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 302a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 303a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (mipmaps->countLevels() < 0) { 304a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return nullptr; 305a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 306a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 307a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel // In non-ddl we will always instantiate right away. Thus we never want to copy the SkBitmap 308a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel // even if its mutable. In ddl, if the bitmap is mutable then we must make a copy since the 309a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel // upload of the data to the gpu can happen at anytime and the bitmap may change by then. 3107e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel SkCopyPixelsMode copyMode = this->mutableBitmapsNeedCopy() ? kIfMutable_SkCopyPixelsMode 3117e1912a8ab48134eb3a631f188ad8aa262e8eaa0Greg Daniel : kNever_SkCopyPixelsMode; 312a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel sk_sp<SkImage> baseLevel = SkMakeImageFromRasterBitmap(bitmap, copyMode); 313a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 314a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (!baseLevel) { 315a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return nullptr; 316a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 317a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 318a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *this->caps()); 319a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 320a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (0 == mipmaps->countLevels()) { 321a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return this->createTextureProxy(baseLevel, kNone_GrSurfaceFlags, kTopLeft_GrSurfaceOrigin, 322a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 1, SkBudgeted::kYes, SkBackingFit::kExact); 323a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 324a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 325a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 326a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel sk_sp<GrTextureProxy> proxy = this->createLazyProxy( 327a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel [desc, baseLevel, mipmaps, mipColorMode] 328ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips (GrResourceProvider* resourceProvider) { 329a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (!resourceProvider) { 330a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return sk_sp<GrTexture>(); 331a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 332a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 333a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel const int mipLevelCount = mipmaps->countLevels() + 1; 334a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]); 335a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 336a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel SkPixmap pixmap; 337a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel SkAssertResult(baseLevel->peekPixels(&pixmap)); 338a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 339a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel // DDL TODO: Instead of copying all this info into GrMipLevels we should just plumb 340a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel // the use of SkMipMap down through Ganesh. 341a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel texels[0].fPixels = pixmap.addr(); 342a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel texels[0].fRowBytes = pixmap.rowBytes(); 343a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 344a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel for (int i = 1; i < mipLevelCount; ++i) { 345a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel SkMipMap::Level generatedMipLevel; 346a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel mipmaps->getLevel(i - 1, &generatedMipLevel); 347a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel texels[i].fPixels = generatedMipLevel.fPixmap.addr(); 348a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel texels[i].fRowBytes = generatedMipLevel.fPixmap.rowBytes(); 349a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel SkASSERT(texels[i].fPixels); 350a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 351a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 352a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return resourceProvider->createTexture(desc, SkBudgeted::kYes, texels.get(), 353a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel mipLevelCount, mipColorMode); 354a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel }, desc, GrMipMapped::kYes, SkBackingFit::kExact, SkBudgeted::kYes); 355a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 356a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (fResourceProvider) { 357a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however 358a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel // we're better off instantiating the proxy immediately here. 359a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel if (!proxy->priv().doLazyInstantiation(fResourceProvider)) { 360a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return nullptr; 361a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 362a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel } 363a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel return proxy; 364a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel} 365a4ead65e2c80b6e649f31e28e8fa116aca83fad4Greg Daniel 3660bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillipssk_sp<GrTextureProxy> GrProxyProvider::createProxy(const GrSurfaceDesc& desc, 367f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel GrMipMapped mipMapped, 3680bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips SkBackingFit fit, 3690bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips SkBudgeted budgeted, 3700bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips uint32_t flags) { 3710bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips SkASSERT(0 == flags || GrResourceProvider::kNoPendingIO_Flag == flags); 3720bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 373f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel if (GrMipMapped::kYes == mipMapped) { 374f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel // SkMipMap doesn't include the base level in the level count so we have to add 1 375f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel int mipCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1; 376f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel if (1 == mipCount) { 377f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel mipMapped = GrMipMapped::kNo; 378f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel } 379f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel } 380f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel 381f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel if (!this->caps()->validateSurfaceDesc(desc, mipMapped)) { 3823a2cc2c2ec124de36d2544b2a523ef1dd317ca32Brian Salomon return nullptr; 3835bb82cbecd740d21b92e8d2944280ab6eb6af7a6Brian Salomon } 3843a2cc2c2ec124de36d2544b2a523ef1dd317ca32Brian Salomon GrSurfaceDesc copyDesc = desc; 385bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon if (desc.fFlags & kRenderTarget_GrSurfaceFlag) { 386bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon copyDesc.fSampleCnt = 387bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon this->caps()->getRenderTargetSampleCount(desc.fSampleCnt, desc.fConfig); 388bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon } 3893a2cc2c2ec124de36d2544b2a523ef1dd317ca32Brian Salomon 390bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon if (copyDesc.fFlags & kRenderTarget_GrSurfaceFlag) { 3910bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips // We know anything we instantiate later from this deferred path will be 3920bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips // both texturable and renderable 393bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon return sk_sp<GrTextureProxy>( 394f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel new GrTextureRenderTargetProxy(*this->caps(), copyDesc, mipMapped, fit, budgeted, 395f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel flags)); 3960bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips } 3970bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 398f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel return sk_sp<GrTextureProxy>(new GrTextureProxy(copyDesc, mipMapped, fit, budgeted, nullptr, 0, 399f6f7b67ac230b14a725fbdabe951c70ea5b4428fGreg Daniel flags)); 4000bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips} 4010bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 402adbe1328789071d1f742023edd93b6948eed9470Robert Phillipssk_sp<GrTextureProxy> GrProxyProvider::createWrappedTextureProxy( 403adbe1328789071d1f742023edd93b6948eed9470Robert Phillips const GrBackendTexture& backendTex, 404adbe1328789071d1f742023edd93b6948eed9470Robert Phillips GrSurfaceOrigin origin, 405adbe1328789071d1f742023edd93b6948eed9470Robert Phillips GrWrapOwnership ownership, 406adbe1328789071d1f742023edd93b6948eed9470Robert Phillips ReleaseProc releaseProc, 407adbe1328789071d1f742023edd93b6948eed9470Robert Phillips ReleaseContext releaseCtx) { 408f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips if (this->isAbandoned()) { 409f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips return nullptr; 410f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips } 411f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips 412f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel GrSurfaceDesc desc; 413f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel desc.fOrigin = origin; 414f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel desc.fWidth = backendTex.width(); 415f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel desc.fHeight = backendTex.height(); 416f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel desc.fConfig = backendTex.config(); 417f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel GrMipMapped mipMapped = backendTex.hasMipMaps() ? GrMipMapped::kYes : GrMipMapped::kNo; 418f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel 4196a0176bf033c780bb92396220db8140f30948345Greg Daniel sk_sp<GrReleaseProcHelper> releaseHelper; 4206a0176bf033c780bb92396220db8140f30948345Greg Daniel if (releaseProc) { 4216a0176bf033c780bb92396220db8140f30948345Greg Daniel releaseHelper.reset(new GrReleaseProcHelper(releaseProc, releaseCtx)); 4226a0176bf033c780bb92396220db8140f30948345Greg Daniel } 4236a0176bf033c780bb92396220db8140f30948345Greg Daniel 424f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel sk_sp<GrTextureProxy> proxy = this->createLazyProxy( 4256a0176bf033c780bb92396220db8140f30948345Greg Daniel [backendTex, ownership, releaseHelper] 426ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips (GrResourceProvider* resourceProvider) { 427f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel if (!resourceProvider) { 4280a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel // If this had a releaseHelper it will get unrefed when we delete this lambda 4290a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel // and will call the release proc so that the client knows they can free the 4300a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel // underlying backend object. 431f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel return sk_sp<GrTexture>(); 432f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel } 433f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel 434f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel sk_sp<GrTexture> tex = resourceProvider->wrapBackendTexture(backendTex, 435f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel ownership); 436f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel if (!tex) { 437f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel return sk_sp<GrTexture>(); 438f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel } 4396a0176bf033c780bb92396220db8140f30948345Greg Daniel if (releaseHelper) { 4400a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel // This gives the texture a ref on the releaseHelper 4410a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel tex->setRelease(releaseHelper); 442f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel } 443f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel SkASSERT(!tex->asRenderTarget()); // Strictly a GrTexture 444f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel // Make sure we match how we created the proxy with SkBudgeted::kNo 445f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel SkASSERT(SkBudgeted::kNo == tex->resourcePriv().isBudgeted()); 446f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel 447f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel return tex; 448f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel }, desc, mipMapped, SkBackingFit::kExact, SkBudgeted::kNo); 449f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel 450f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel if (fResourceProvider) { 451f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however, 452f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel // we're better off instantiating the proxy immediately here. 453bddcc95383250940fce5491576a1636f3087cba9Greg Daniel if (!proxy->priv().doLazyInstantiation(fResourceProvider)) { 454bddcc95383250940fce5491576a1636f3087cba9Greg Daniel return nullptr; 455bddcc95383250940fce5491576a1636f3087cba9Greg Daniel } 456f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel } 457f2336e4500769bc0ff6a208289d757581b0ea91aGreg Daniel return proxy; 4580bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips} 4590bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 4606abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Danielsk_sp<GrTextureProxy> GrProxyProvider::createWrappedTextureProxy(const GrBackendTexture& backendTex, 4610bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips GrSurfaceOrigin origin, 4620bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips int sampleCnt) { 463f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips if (this->isAbandoned()) { 464f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips return nullptr; 465f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips } 466f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips 4676abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config()); 468f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel if (!sampleCnt) { 469f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel return nullptr; 470f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel } 4716abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel 4726abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel GrSurfaceDesc desc; 4736abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel desc.fOrigin = origin; 4746abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel desc.fWidth = backendTex.width(); 4756abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel desc.fHeight = backendTex.height(); 4766abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel desc.fConfig = backendTex.config(); 4776abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel desc.fFlags = kRenderTarget_GrSurfaceFlag; 4786abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel desc.fSampleCnt = sampleCnt; 4796abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel GrMipMapped mipMapped = backendTex.hasMipMaps() ? GrMipMapped::kYes : GrMipMapped::kNo; 4806abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel 4812a30390ce6130b27c18152edf75d48616adeb934Greg Daniel GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone; 4822a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (fCaps->usesMixedSamples() && sampleCnt > 1) { 4832a30390ce6130b27c18152edf75d48616adeb934Greg Daniel renderTargetFlags |= GrRenderTargetFlags::kMixedSampled; 4842a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 4852a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (fCaps->maxWindowRectangles() > 0) { 4862a30390ce6130b27c18152edf75d48616adeb934Greg Daniel renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport; 4872a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 4882a30390ce6130b27c18152edf75d48616adeb934Greg Daniel 4896abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel sk_sp<GrTextureProxy> proxy = this->createLazyProxy( 4906abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel [backendTex, sampleCnt] (GrResourceProvider* resourceProvider) { 4916abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel if (!resourceProvider) { 4926abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel return sk_sp<GrTexture>(); 4936abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel } 4946abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel 4956abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel sk_sp<GrTexture> tex = resourceProvider->wrapRenderableBackendTexture(backendTex, 4966abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel sampleCnt); 4976abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel if (!tex) { 4986abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel return sk_sp<GrTexture>(); 4996abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel } 5006abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel SkASSERT(tex->asRenderTarget()); // A GrTextureRenderTarget 5016abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel // Make sure we match how we created the proxy with SkBudgeted::kNo 5026abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel SkASSERT(SkBudgeted::kNo == tex->resourcePriv().isBudgeted()); 5036abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel 5046abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel return tex; 5052a30390ce6130b27c18152edf75d48616adeb934Greg Daniel }, desc, mipMapped, renderTargetFlags, SkBackingFit::kExact, SkBudgeted::kNo); 5060bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 5076abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel if (fResourceProvider) { 5086abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however, 5096abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel // we're better off instantiating the proxy immediately here. 5106abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel if (!proxy->priv().doLazyInstantiation(fResourceProvider)) { 5116abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel return nullptr; 5126abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel } 5136abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel } 5146abda4357ce694a692b5e697b7ac49ec3676b5ebGreg Daniel return proxy; 5150bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips} 5160bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 5170bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillipssk_sp<GrSurfaceProxy> GrProxyProvider::createWrappedRenderTargetProxy( 5180bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips const GrBackendRenderTarget& backendRT, 5190bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips GrSurfaceOrigin origin) { 520f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips if (this->isAbandoned()) { 521f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips return nullptr; 522f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips } 523f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips 5242a30390ce6130b27c18152edf75d48616adeb934Greg Daniel GrSurfaceDesc desc; 5252a30390ce6130b27c18152edf75d48616adeb934Greg Daniel desc.fOrigin = origin; 5262a30390ce6130b27c18152edf75d48616adeb934Greg Daniel desc.fWidth = backendRT.width(); 5272a30390ce6130b27c18152edf75d48616adeb934Greg Daniel desc.fHeight = backendRT.height(); 5282a30390ce6130b27c18152edf75d48616adeb934Greg Daniel desc.fConfig = backendRT.config(); 5292a30390ce6130b27c18152edf75d48616adeb934Greg Daniel desc.fFlags = kRenderTarget_GrSurfaceFlag; 5302a30390ce6130b27c18152edf75d48616adeb934Greg Daniel desc.fSampleCnt = backendRT.sampleCnt(); 5312a30390ce6130b27c18152edf75d48616adeb934Greg Daniel 5322a30390ce6130b27c18152edf75d48616adeb934Greg Daniel GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone; 5332a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (fCaps->isMixedSamplesSupportedForRT(backendRT) && backendRT.sampleCnt() > 1) { 5342a30390ce6130b27c18152edf75d48616adeb934Greg Daniel renderTargetFlags |= GrRenderTargetFlags::kMixedSampled; 5352a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 5362a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (fCaps->isWindowRectanglesSupportedForRT(backendRT)) { 5372a30390ce6130b27c18152edf75d48616adeb934Greg Daniel renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport; 5380bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips } 5390bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 5402a30390ce6130b27c18152edf75d48616adeb934Greg Daniel sk_sp<GrRenderTargetProxy> proxy = this->createLazyRenderTargetProxy( 5412a30390ce6130b27c18152edf75d48616adeb934Greg Daniel [backendRT] (GrResourceProvider* resourceProvider) { 5422a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (!resourceProvider) { 5432a30390ce6130b27c18152edf75d48616adeb934Greg Daniel return sk_sp<GrRenderTarget>(); 5442a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 5452a30390ce6130b27c18152edf75d48616adeb934Greg Daniel 5462a30390ce6130b27c18152edf75d48616adeb934Greg Daniel sk_sp<GrRenderTarget> rt = resourceProvider->wrapBackendRenderTarget(backendRT); 5472a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (!rt) { 5482a30390ce6130b27c18152edf75d48616adeb934Greg Daniel return sk_sp<GrRenderTarget>(); 5492a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 5502a30390ce6130b27c18152edf75d48616adeb934Greg Daniel SkASSERT(!rt->asTexture()); // A GrRenderTarget that's not textureable 5512a30390ce6130b27c18152edf75d48616adeb934Greg Daniel SkASSERT(!rt->getUniqueKey().isValid()); 5522a30390ce6130b27c18152edf75d48616adeb934Greg Daniel // Make sure we match how we created the proxy with SkBudgeted::kNo 5532a30390ce6130b27c18152edf75d48616adeb934Greg Daniel SkASSERT(SkBudgeted::kNo == rt->resourcePriv().isBudgeted()); 5542a30390ce6130b27c18152edf75d48616adeb934Greg Daniel 5552a30390ce6130b27c18152edf75d48616adeb934Greg Daniel return rt; 5562a30390ce6130b27c18152edf75d48616adeb934Greg Daniel }, desc, renderTargetFlags, Textureable::kNo, GrMipMapped::kNo, SkBackingFit::kExact, 5572a30390ce6130b27c18152edf75d48616adeb934Greg Daniel SkBudgeted::kNo); 5582a30390ce6130b27c18152edf75d48616adeb934Greg Daniel 5592a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (fResourceProvider) { 5602a30390ce6130b27c18152edf75d48616adeb934Greg Daniel // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however, 5612a30390ce6130b27c18152edf75d48616adeb934Greg Daniel // we're better off instantiating the proxy immediately here. 5622a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (!proxy->priv().doLazyInstantiation(fResourceProvider)) { 5632a30390ce6130b27c18152edf75d48616adeb934Greg Daniel return nullptr; 5642a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 5652a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 5662a30390ce6130b27c18152edf75d48616adeb934Greg Daniel return proxy; 5670bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips} 5680bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 569f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Danielsk_sp<GrSurfaceProxy> GrProxyProvider::createWrappedRenderTargetProxy( 570f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel const GrBackendTexture& backendTex, 571f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel GrSurfaceOrigin origin, 572f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel int sampleCnt) { 573f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips if (this->isAbandoned()) { 574f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips return nullptr; 575f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips } 576f9bec208cd1a708b603340369530cf6eacfda244Robert Phillips 577f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config()); 578f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel if (!sampleCnt) { 5790bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips return nullptr; 5800bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips } 5810bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 582f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel GrSurfaceDesc desc; 583f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel desc.fOrigin = origin; 584f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel desc.fWidth = backendTex.width(); 585f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel desc.fHeight = backendTex.height(); 586f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel desc.fConfig = backendTex.config(); 587f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel desc.fFlags = kRenderTarget_GrSurfaceFlag; 588f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel desc.fSampleCnt = sampleCnt; 589f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel 590f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone; 591f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel if (fCaps->usesMixedSamples() && sampleCnt > 1) { 592f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel renderTargetFlags |= GrRenderTargetFlags::kMixedSampled; 593f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel } 594f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel if (fCaps->maxWindowRectangles() > 0) { 595f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport; 596f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel } 597f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel 598f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel sk_sp<GrRenderTargetProxy> proxy = this->createLazyRenderTargetProxy( 599f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel [backendTex, sampleCnt] (GrResourceProvider* resourceProvider) { 600f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel if (!resourceProvider) { 601f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel return sk_sp<GrRenderTarget>(); 602f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel } 603f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel 604f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel sk_sp<GrRenderTarget> rt = resourceProvider->wrapBackendTextureAsRenderTarget( 605f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel backendTex, sampleCnt); 606f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel if (!rt) { 607f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel return sk_sp<GrRenderTarget>(); 608f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel } 609f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel SkASSERT(!rt->asTexture()); // A GrRenderTarget that's not textureable 610f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel SkASSERT(!rt->getUniqueKey().isValid()); 611f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel // Make sure we match how we created the proxy with SkBudgeted::kNo 612f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel SkASSERT(SkBudgeted::kNo == rt->resourcePriv().isBudgeted()); 613f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel 614f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel return rt; 615f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel }, desc, renderTargetFlags, Textureable::kNo, GrMipMapped::kNo, SkBackingFit::kExact, 616f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel SkBudgeted::kNo); 617f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel 618f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel if (fResourceProvider) { 619f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however, 620f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel // we're better off instantiating the proxy immediately here. 621f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel if (!proxy->priv().doLazyInstantiation(fResourceProvider)) { 622f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel return nullptr; 623f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel } 624f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel } 625f87651e7b8c54569ace96ce9bf1671d5401eb91cGreg Daniel return proxy; 6260bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips} 6270bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips 628777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillipssk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback, 629777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips const GrSurfaceDesc& desc, 630777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips GrMipMapped mipMapped, 631777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips SkBackingFit fit, SkBudgeted budgeted) { 6322a30390ce6130b27c18152edf75d48616adeb934Greg Daniel return this->createLazyProxy(std::move(callback), desc, mipMapped, GrRenderTargetFlags::kNone, 6332a30390ce6130b27c18152edf75d48616adeb934Greg Daniel fit, budgeted); 6342a30390ce6130b27c18152edf75d48616adeb934Greg Daniel} 6352a30390ce6130b27c18152edf75d48616adeb934Greg Daniel 6362a30390ce6130b27c18152edf75d48616adeb934Greg Danielsk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback, 6372a30390ce6130b27c18152edf75d48616adeb934Greg Daniel const GrSurfaceDesc& desc, 6382a30390ce6130b27c18152edf75d48616adeb934Greg Daniel GrMipMapped mipMapped, 6392a30390ce6130b27c18152edf75d48616adeb934Greg Daniel GrRenderTargetFlags renderTargetFlags, 6402a30390ce6130b27c18152edf75d48616adeb934Greg Daniel SkBackingFit fit, SkBudgeted budgeted) { 641777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) || 642777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips (desc.fWidth > 0 && desc.fHeight > 0)); 643777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips uint32_t flags = GrResourceProvider::kNoPendingIO_Flag; 644457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel 6452a30390ce6130b27c18152edf75d48616adeb934Greg Daniel#ifdef SK_DEBUG 6462a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags)) { 6472a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (SkToBool(renderTargetFlags & GrRenderTargetFlags::kMixedSampled)) { 6482a30390ce6130b27c18152edf75d48616adeb934Greg Daniel SkASSERT(fCaps->usesMixedSamples() && desc.fSampleCnt > 1); 6492a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 6502a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (SkToBool(renderTargetFlags & GrRenderTargetFlags::kWindowRectsSupport)) { 6512a30390ce6130b27c18152edf75d48616adeb934Greg Daniel SkASSERT(fCaps->maxWindowRectangles() > 0); 6522a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 6532a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 6542a30390ce6130b27c18152edf75d48616adeb934Greg Daniel#endif 6552a30390ce6130b27c18152edf75d48616adeb934Greg Daniel 656457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType; 657457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel // For non-ddl draws always make lazy proxy's single use. 658457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel LazyInstantiationType lazyType = fResourceProvider ? LazyInstantiationType::kSingleUse 659457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel : LazyInstantiationType::kMultipleUse; 660457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel 661777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips return sk_sp<GrTextureProxy>(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags) ? 662457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel new GrTextureRenderTargetProxy(std::move(callback), lazyType, desc, 6632a30390ce6130b27c18152edf75d48616adeb934Greg Daniel mipMapped, fit, budgeted, flags, 6642a30390ce6130b27c18152edf75d48616adeb934Greg Daniel renderTargetFlags) : 665457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel new GrTextureProxy(std::move(callback), lazyType, desc, mipMapped, 666457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel fit, budgeted, flags)); 667777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips} 668777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips 669e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillipssk_sp<GrRenderTargetProxy> GrProxyProvider::createLazyRenderTargetProxy( 670e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips LazyInstantiateCallback&& callback, 671e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips const GrSurfaceDesc& desc, 6722a30390ce6130b27c18152edf75d48616adeb934Greg Daniel GrRenderTargetFlags renderTargetFlags, 673e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips Textureable textureable, 674e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips GrMipMapped mipMapped, 675e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips SkBackingFit fit, SkBudgeted budgeted) { 676e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) || 677e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips (desc.fWidth > 0 && desc.fHeight > 0)); 6782a30390ce6130b27c18152edf75d48616adeb934Greg Daniel SkASSERT(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags)); 679e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips uint32_t flags = GrResourceProvider::kNoPendingIO_Flag; 680457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel 6812a30390ce6130b27c18152edf75d48616adeb934Greg Daniel#ifdef SK_DEBUG 6822a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (SkToBool(renderTargetFlags & GrRenderTargetFlags::kMixedSampled)) { 6832a30390ce6130b27c18152edf75d48616adeb934Greg Daniel SkASSERT(fCaps->usesMixedSamples() && desc.fSampleCnt > 1); 6842a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 6852a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (SkToBool(renderTargetFlags & GrRenderTargetFlags::kWindowRectsSupport)) { 6862a30390ce6130b27c18152edf75d48616adeb934Greg Daniel SkASSERT(fCaps->maxWindowRectangles() > 0); 6872a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 6882a30390ce6130b27c18152edf75d48616adeb934Greg Daniel#endif 6892a30390ce6130b27c18152edf75d48616adeb934Greg Daniel 690457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType; 691457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel // For non-ddl draws always make lazy proxy's single use. 692457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel LazyInstantiationType lazyType = fResourceProvider ? LazyInstantiationType::kSingleUse 693457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel : LazyInstantiationType::kMultipleUse; 694457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel 695e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips if (Textureable::kYes == textureable) { 696457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel return sk_sp<GrRenderTargetProxy>(new GrTextureRenderTargetProxy(std::move(callback), 697457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel lazyType, desc, mipMapped, 6982a30390ce6130b27c18152edf75d48616adeb934Greg Daniel fit, budgeted, flags, 6992a30390ce6130b27c18152edf75d48616adeb934Greg Daniel renderTargetFlags)); 700e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips } 701e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips 702457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(std::move(callback), lazyType, desc, 7032a30390ce6130b27c18152edf75d48616adeb934Greg Daniel fit, budgeted, flags, 7042a30390ce6130b27c18152edf75d48616adeb934Greg Daniel renderTargetFlags)); 705e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips} 706e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips 707777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillipssk_sp<GrTextureProxy> GrProxyProvider::createFullyLazyProxy(LazyInstantiateCallback&& callback, 708777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips Renderable renderable, 709ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips GrSurfaceOrigin origin, 710777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips GrPixelConfig config) { 711777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips GrSurfaceDesc desc; 7122a30390ce6130b27c18152edf75d48616adeb934Greg Daniel GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone; 713777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips if (Renderable::kYes == renderable) { 714777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips desc.fFlags = kRenderTarget_GrSurfaceFlag; 7152a30390ce6130b27c18152edf75d48616adeb934Greg Daniel if (fCaps->maxWindowRectangles() > 0) { 7162a30390ce6130b27c18152edf75d48616adeb934Greg Daniel renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport; 7172a30390ce6130b27c18152edf75d48616adeb934Greg Daniel } 718777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips } 719ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips desc.fOrigin = origin; 720777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips desc.fWidth = -1; 721777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips desc.fHeight = -1; 722777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips desc.fConfig = config; 723bdecacfbe47bc7211336bb847bb33c00ef85ea3eBrian Salomon desc.fSampleCnt = 1; 724777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips 7252a30390ce6130b27c18152edf75d48616adeb934Greg Daniel return this->createLazyProxy(std::move(callback), desc, GrMipMapped::kNo, renderTargetFlags, 726777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips SkBackingFit::kApprox, SkBudgeted::kYes); 727777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips 728777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips} 729777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips 7301afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipsbool GrProxyProvider::IsFunctionallyExact(GrSurfaceProxy* proxy) { 7311afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips return proxy->priv().isExact() || (SkIsPow2(proxy->width()) && SkIsPow2(proxy->height())); 7321afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 7331afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 7341afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipsvoid GrProxyProvider::processInvalidProxyUniqueKey(const GrUniqueKey& key) { 7351afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips // Note: this method is called for the whole variety of GrGpuResources so often 'key' 7361afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips // will not be in 'fUniquelyKeyedProxies'. 7371afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips GrTextureProxy* proxy = fUniquelyKeyedProxies.find(key); 7381afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips if (proxy) { 7391afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips this->processInvalidProxyUniqueKey(key, proxy, false); 7401afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 7411afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 7421afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 7431afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipsvoid GrProxyProvider::processInvalidProxyUniqueKey(const GrUniqueKey& key, GrTextureProxy* proxy, 7441afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips bool invalidateSurface) { 7451afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(proxy); 7461afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(proxy->getUniqueKey().isValid()); 7471afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(proxy->getUniqueKey() == key); 7481afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 7491afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips fUniquelyKeyedProxies.remove(key); 7501afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips proxy->cacheAccess().clearUniqueKey(); 7511afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 7521afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips if (invalidateSurface && proxy->priv().isInstantiated()) { 7531afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips GrSurface* surface = proxy->priv().peekSurface(); 7541afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips if (surface) { 7551afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips surface->resourcePriv().removeUniqueKey(); 7561afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 7571afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 7581afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 7591afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 7601afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipsvoid GrProxyProvider::removeAllUniqueKeys() { 7611afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips UniquelyKeyedProxyHash::Iter iter(&fUniquelyKeyedProxies); 7621afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips for (UniquelyKeyedProxyHash::Iter iter(&fUniquelyKeyedProxies); !iter.done(); ++iter) { 7631afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips GrTextureProxy& tmp = *iter; 7641afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips 7651afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips this->processInvalidProxyUniqueKey(tmp.getUniqueKey(), &tmp, false); 7661afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips } 7671afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips SkASSERT(!fUniquelyKeyedProxies.count()); 7681afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips} 769