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