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