1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */
727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
81fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com#include "GrContext.h"
9c65aec97619682b2c0191554f44ddf35f618a94dBrian Salomon#include "GrClip.h"
10682c269a1511200322916af83053e26004c0ec40bsalomon#include "GrContextOptions.h"
11c65aec97619682b2c0191554f44ddf35f618a94dBrian Salomon#include "GrContextPriv.h"
1277a2e52c7d5c77de73ecab5fec79072ee4460706robertphillips#include "GrDrawingManager.h"
131105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman#include "GrRenderTargetContext.h"
14c65aec97619682b2c0191554f44ddf35f618a94dBrian Salomon#include "GrRenderTargetProxy.h"
150ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon#include "GrResourceCache.h"
16d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon#include "GrResourceProvider.h"
17d85f97d6968c9a287a27d6ba10da8fff3b0230e2Greg Daniel#include "GrSemaphore.h"
1872176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com#include "GrSoftwarePathRenderer.h"
1945580d3e3024c1536e8e1b2017b704805442b634Brian Osman#include "GrSurfaceContext.h"
20afbf2d6273cd22c683f20a7e5773843876af3085bsalomon#include "GrSurfacePriv.h"
21757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips#include "GrSurfaceProxyPriv.h"
2245580d3e3024c1536e8e1b2017b704805442b634Brian Osman#include "GrTextureContext.h"
23485c499a2797c1eb0e750fa4aaec57192799b424Matt Sarett#include "SkConvertPixels.h"
243b65598bceb65736486db27ed49a56d787032747Brian Osman#include "SkGr.h"
25c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett#include "SkUnPreMultiplyPriv.h"
265478d427c6e67c986a3390162c8fec77c466058ajoshualitt#include "effects/GrConfigConversionEffect.h"
27e804292e805917002cc3d7baa7f967fb20d2c7cbjoshualitt#include "text/GrTextBlobCache.h"
285478d427c6e67c986a3390162c8fec77c466058ajoshualitt
29f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this)
301de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt#define ASSERT_SINGLE_OWNER \
311de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(&fSingleOwner);)
324fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips#define ASSERT_SINGLE_OWNER_PRIV \
334fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips    SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(&fContext->fSingleOwner);)
347761d61876ea479dd9672b684fd5c7601932a767robertphillips#define RETURN_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return; }
357761d61876ea479dd9672b684fd5c7601932a767robertphillips#define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return false; }
367761d61876ea479dd9672b684fd5c7601932a767robertphillips#define RETURN_NULL_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return nullptr; }
37bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com
38ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips////////////////////////////////////////////////////////////////////////////////
39f21dab95405979a4aff9f6a741c818304a67f220bsalomon
40682c269a1511200322916af83053e26004c0ec40bsalomonGrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) {
41682c269a1511200322916af83053e26004c0ec40bsalomon    GrContextOptions defaultOptions;
42682c269a1511200322916af83053e26004c0ec40bsalomon    return Create(backend, backendContext, defaultOptions);
43682c269a1511200322916af83053e26004c0ec40bsalomon}
44682c269a1511200322916af83053e26004c0ec40bsalomon
459c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevskiGrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext,
46682c269a1511200322916af83053e26004c0ec40bsalomon                             const GrContextOptions& options) {
47385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    GrContext* context = new GrContext;
489c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski
49682c269a1511200322916af83053e26004c0ec40bsalomon    if (context->init(backend, backendContext, options)) {
506e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        return context;
516e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    } else {
526e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        context->unref();
5396fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
5427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
5527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
5627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
570acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualittstatic int32_t gNextID = 1;
580acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualittstatic int32_t next_id() {
590acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt    int32_t id;
600acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt    do {
610acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt        id = sk_atomic_inc(&gNextID);
620acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt    } while (id == SK_InvalidGenID);
630acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt    return id;
640acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt}
650acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt
66682c269a1511200322916af83053e26004c0ec40bsalomonGrContext::GrContext() : fUniqueID(next_id()) {
6796fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fGpu = nullptr;
6896fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fCaps = nullptr;
6996fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fResourceCache = nullptr;
7096fcdcc219d2a0d3579719b84b28bede76efba64halcanary    fResourceProvider = nullptr;
71f856fd1ccdd839646159767f6aa9a2f2a1b97f04Brian Salomon    fAtlasGlyphCache = nullptr;
726e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com}
736e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
74682c269a1511200322916af83053e26004c0ec40bsalomonbool GrContext::init(GrBackend backend, GrBackendContext backendContext,
75682c269a1511200322916af83053e26004c0ec40bsalomon                     const GrContextOptions& options) {
761de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
77ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips    SkASSERT(!fGpu);
786e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
79682c269a1511200322916af83053e26004c0ec40bsalomon    fGpu = GrGpu::Create(backend, backendContext, options, this);
80ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips    if (!fGpu) {
816e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        return false;
826e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    }
8369cfe95b7be386cf7d349b61388e93ea7c3cd386bsalomon    this->initCommon(options);
84334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon    return true;
85334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon}
866e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
8769cfe95b7be386cf7d349b61388e93ea7c3cd386bsalomonvoid GrContext::initCommon(const GrContextOptions& options) {
881de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
891de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt
90762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon    fCaps = SkRef(fGpu->caps());
91385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    fResourceCache = new GrResourceCache(fCaps);
926d0872d9bd97de5301214a258e141dd5fbeecffcjoshualitt    fResourceProvider = new GrResourceProvider(fGpu, fResourceCache, &fSingleOwner);
931836d337a85b82689287231091823f404d8cab43commit-bot@chromium.org
9446da1cc9f20c277f7789355038d426931195aa65Brian Osman    fDisableGpuYUVConversion = options.fDisableGpuYUVConversion;
956e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    fDidTestPMConversions = false;
966e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
97f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    GrRenderTargetOpList::Options rtOpListOptions;
9809d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomon    rtOpListOptions.fMaxOpCombineLookback = options.fMaxOpCombineLookback;
9909d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomon    rtOpListOptions.fMaxOpCombineLookahead = options.fMaxOpCombineLookahead;
1006b2552f10983d1b6d33303e3e9965ae71944c1d5bsalomon    GrPathRendererChain::Options prcOptions;
10139ef7fb885d7be648b9f0ecd027bc400d1213cecbsalomon    prcOptions.fAllowPathMaskCaching = options.fAllowPathMaskCaching;
102008b9d80ab9adbf2656eceaf54d11cd15e4dda05csmartdalton    prcOptions.fGpuPathRenderers = options.fGpuPathRenderers;
103f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    fDrawingManager.reset(new GrDrawingManager(this, rtOpListOptions, prcOptions,
104f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips                                               options.fImmediateMode, &fSingleOwner));
1057c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt
106f856fd1ccdd839646159767f6aa9a2f2a1b97f04Brian Salomon    fAtlasGlyphCache = new GrAtlasGlyphCache(this);
107b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt
108385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB, this));
109c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com}
110c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com
11127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrContext::~GrContext() {
1121de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
1131de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt
114ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips    if (!fGpu) {
115762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon        SkASSERT(!fCaps);
116733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com        return;
117733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com    }
118733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com
1198fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    this->flush();
1205acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com
12177a2e52c7d5c77de73ecab5fec79072ee4460706robertphillips    fDrawingManager->cleanup();
1222334fb655f8d4ef5915770d32bf845c88d3627f4robertphillips
123950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com    for (int i = 0; i < fCleanUpData.count(); ++i) {
124950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com        (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo);
125950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com    }
126950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com
127385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    delete fResourceProvider;
128385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    delete fResourceCache;
129f856fd1ccdd839646159767f6aa9a2f2a1b97f04Brian Salomon    delete fAtlasGlyphCache;
130f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com
131205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    fGpu->unref();
132762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon    fCaps->unref();
13327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
13427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
1356bd5284415bd983b0628c4941dff5def40018f5abungemansk_sp<GrContextThreadSafeProxy> GrContext::threadSafeProxy() {
13641b952c296e343eeabb07d52b6a55ba7565a286bbsalomon    if (!fThreadSafeProxy) {
1376bd5284415bd983b0628c4941dff5def40018f5abungeman        fThreadSafeProxy.reset(new GrContextThreadSafeProxy(sk_ref_sp(fCaps), this->uniqueID()));
13841b952c296e343eeabb07d52b6a55ba7565a286bbsalomon    }
1396bd5284415bd983b0628c4941dff5def40018f5abungeman    return fThreadSafeProxy;
14041b952c296e343eeabb07d52b6a55ba7565a286bbsalomon}
14141b952c296e343eeabb07d52b6a55ba7565a286bbsalomon
1422354f8432a7205571f04f9638a0018fb0b1fb282bsalomonvoid GrContext::abandonContext() {
1431de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
1441de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt
145d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    fResourceProvider->abandon();
1460dfa62c97707ac9b0fc0bdba7acfc8405db5c836robertphillips
1470dfa62c97707ac9b0fc0bdba7acfc8405db5c836robertphillips    // Need to abandon the drawing manager first so all the render targets
1480dfa62c97707ac9b0fc0bdba7acfc8405db5c836robertphillips    // will be released/forgotten before they too are abandoned.
1490dfa62c97707ac9b0fc0bdba7acfc8405db5c836robertphillips    fDrawingManager->abandon();
1500dfa62c97707ac9b0fc0bdba7acfc8405db5c836robertphillips
151205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    // abandon first to so destructors
152205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    // don't try to free the resources in the API.
1530ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    fResourceCache->abandonAll();
154c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon
1556e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    fGpu->disconnect(GrGpu::DisconnectType::kAbandon);
1566e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon
157f856fd1ccdd839646159767f6aa9a2f2a1b97f04Brian Salomon    fAtlasGlyphCache->freeAll();
1586e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    fTextBlobCache->freeAll();
1596e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon}
1606e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon
1616e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomonvoid GrContext::releaseResourcesAndAbandonContext() {
1626e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    ASSERT_SINGLE_OWNER
1636e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon
1646e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    fResourceProvider->abandon();
1656e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon
1666e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    // Need to abandon the drawing manager first so all the render targets
1676e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    // will be released/forgotten before they too are abandoned.
1686e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    fDrawingManager->abandon();
1696e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon
1706e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    // Release all resources in the backend 3D API.
1716e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    fResourceCache->releaseAll();
1726e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon
1736e2aad4e9f6280aa2b710e7324458fdc6d699ec5bsalomon    fGpu->disconnect(GrGpu::DisconnectType::kCleanup);
174205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
175f856fd1ccdd839646159767f6aa9a2f2a1b97f04Brian Salomon    fAtlasGlyphCache->freeAll();
17626ffc00bfa09fe85c22ddcbeb0fc54c0eacb7859joshualitt    fTextBlobCache->freeAll();
1778fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com}
1788fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
1790a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.comvoid GrContext::resetContext(uint32_t state) {
1801de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
1810a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    fGpu->markContextDirty(state);
1828fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com}
1838fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
1848fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::freeGpuResources() {
1851de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
1861de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt
1878fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    this->flush();
188fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
189f856fd1ccdd839646159767f6aa9a2f2a1b97f04Brian Salomon    fAtlasGlyphCache->freeAll();
190687378229aecefc0ab7e639181593774ec8a4290robertphillips
191687378229aecefc0ab7e639181593774ec8a4290robertphillips    fDrawingManager->freeGpuResources();
1923033b9faac476fc22e264950764d3551a32e4db7bsalomon
1933033b9faac476fc22e264950764d3551a32e4db7bsalomon    fResourceCache->purgeAllUnlocked();
19427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
19527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
1965e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomonvoid GrContext::purgeResourcesNotUsedInMs(std::chrono::milliseconds ms) {
1975e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon    ASSERT_SINGLE_OWNER
1985e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon    fResourceCache->purgeResourcesNotUsedSince(GrStdSteadyClock::now() - ms);
1995e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon}
2005e150851d0dd5ddb161449b44edf1bf52d18ac5aBrian Salomon
20195c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.orgvoid GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const {
2021de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
2031de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt
20471cb0c241e439b6ed746b90294d0b6916644a644bsalomon    if (resourceCount) {
2050ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        *resourceCount = fResourceCache->getBudgetedResourceCount();
20671cb0c241e439b6ed746b90294d0b6916644a644bsalomon    }
20771cb0c241e439b6ed746b90294d0b6916644a644bsalomon    if (resourceBytes) {
2080ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        *resourceBytes = fResourceCache->getBudgetedResourceBytes();
20971cb0c241e439b6ed746b90294d0b6916644a644bsalomon    }
210d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org}
211d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org
212fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
213fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com
2140db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualittvoid GrContext::TextBlobCacheOverBudgetCB(void* data) {
2150db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt    SkASSERT(data);
2161105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    // TextBlobs are drawn at the SkGpuDevice level, therefore they cannot rely on
2171105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    // GrRenderTargetContext to perform a necessary flush.  The solution is to move drawText calls
2181105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    // to below the GrContext level, but this is not trivial because they call drawPath on
2191105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    // SkGpuDevice.
2200db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt    GrContext* context = reinterpret_cast<GrContext*>(data);
2210db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt    context->flush();
2220db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt}
2230db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt
22427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com////////////////////////////////////////////////////////////////////////////////
22527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
226b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomonvoid GrContext::flush() {
2271de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
228ea4615034498aca2f9ca1753fb9a1ef10508d8ccrobertphillips    RETURN_IF_ABANDONED
229b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon    fDrawingManager->flush();
23027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
23127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
23281beccc4fb1396fe94af15bfce26e68b82b93809bsalomonbool sw_convert_to_premul(GrPixelConfig srcConfig, int width, int height, size_t inRowBytes,
23381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                          const void* inPixels, size_t outRowBytes, void* outPixels) {
234c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett    SkColorType colorType;
235c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett    if (!GrPixelConfigToColorType(srcConfig, &colorType) ||
236c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett        4 != SkColorTypeBytesPerPixel(colorType))
237c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett    {
23881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        return false;
23981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    }
24081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon
241c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett    for (int y = 0; y < height; y++) {
242c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett        SkOpts::RGBA_to_rgbA((uint32_t*) outPixels, inPixels, width);
243c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett        outPixels = SkTAddOffset<void>(outPixels, outRowBytes);
244c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett        inPixels = SkTAddOffset<const void>(inPixels, inRowBytes);
245c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett    }
24681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon
247c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett    return true;
24881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon}
24981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon
250ce425510a07632f14b7b779ec3864f719cb4326bBrian Osmanstatic bool valid_unpremul_config(GrPixelConfig config) {
251ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman    return GrPixelConfigIs8888Unorm(config) || kRGBA_half_GrPixelConfig == config;
252ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman}
253ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman
254b62ea2240ffbc28bdf2469464e232f674f59584bBrian Osmanbool GrContext::writeSurfacePixels(GrSurface* surface, SkColorSpace* dstColorSpace,
2550342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com                                   int left, int top, int width, int height,
256b62ea2240ffbc28bdf2469464e232f674f59584bBrian Osman                                   GrPixelConfig srcConfig, SkColorSpace* srcColorSpace,
257b62ea2240ffbc28bdf2469464e232f674f59584bBrian Osman                                   const void* buffer, size_t rowBytes, uint32_t pixelOpsFlags) {
258b62ea2240ffbc28bdf2469464e232f674f59584bBrian Osman    // TODO: Color space conversion
259b62ea2240ffbc28bdf2469464e232f674f59584bBrian Osman
2601de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
2615f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_FALSE_IF_ABANDONED
2626c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon    ASSERT_OWNED_RESOURCE(surface);
2636c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon    SkASSERT(surface);
264bc90735170b5d85a19b24df0baa865f7cf87d348joshualitt    GR_AUDIT_TRAIL_AUTO_FRAME(&fAuditTrail, "GrContext::writeSurfacePixels");
2656c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon
2666c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon    this->testPMConversionsIfNecessary(pixelOpsFlags);
2679c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com
268e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon    // Trim the params here so that if we wind up making a temporary surface it can be as small as
269f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    // necessary and because GrGpu::getWritePixelsInfo requires it.
270e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon    if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height(),
271e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon                                               GrBytesPerPixel(srcConfig), &left, &top, &width,
272e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon                                               &height, &buffer, &rowBytes)) {
273e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon        return false;
274e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon    }
275e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon
276ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman    bool applyPremulToSrc = SkToBool(kUnpremul_PixelOpsFlag & pixelOpsFlags);
277ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman    if (applyPremulToSrc && !valid_unpremul_config(srcConfig)) {
278ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman        return false;
279f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    }
280bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // We don't allow conversion between integer configs and float/fixed configs.
281bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    if (GrPixelConfigIsSint(surface->config()) != GrPixelConfigIsSint(srcConfig)) {
282bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        return false;
283bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
284636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon
285636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon    GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference;
286636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon    // Don't prefer to draw for the conversion (and thereby access a texture from the cache) when
287636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon    // we've already determined that there isn't a roundtrip preserving conversion processor pair.
288de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman    if (applyPremulToSrc && this->validPMUPMConversionExists(srcConfig)) {
289636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon        drawPreference = GrGpu::kCallerPrefersDraw_DrawPreference;
290636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon    }
291636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon
292f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    GrGpu::WritePixelTempDrawInfo tempDrawInfo;
293ed828001da75f4a3a5d31d9f1c1935e3595ce920cblume    if (!fGpu->getWritePixelsInfo(surface, width, height, srcConfig, &drawPreference,
294f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                                  &tempDrawInfo)) {
29581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        return false;
2960342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com    }
2976f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com
298f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && surface->surfacePriv().hasPendingIO()) {
299f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon        this->flush();
30081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    }
301f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon
3022f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips    sk_sp<GrTextureProxy> tempProxy;
303f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    if (GrGpu::kNoDraw_DrawPreference != drawPreference) {
30432342f032e1dfd133040324f851f0365f9d4cb51Brian Osman        tempProxy = GrSurfaceProxy::MakeDeferred(this->resourceProvider(),
3052f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips                                                 tempDrawInfo.fTempSurfaceDesc,
3062f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips                                                 SkBackingFit::kApprox,
3072f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips                                                 SkBudgeted::kYes);
3082f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips        if (!tempProxy && GrGpu::kRequireDraw_DrawPreference == drawPreference) {
309f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            return false;
310f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon        }
31181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    }
3126f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com
313f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    // temp buffer for doing sw premul conversion, if needed.
314c3fb74693e25cf6dffc8add8669c54c4b7ace3a2bsalomon    SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0);
3152f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips    if (tempProxy) {
31606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        sk_sp<GrFragmentProcessor> fp;
317f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon        if (applyPremulToSrc) {
318ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman            fp = this->createUPMToPMEffect(tempProxy, SkMatrix::I());
319ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman            fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle);
320f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            // If premultiplying was the only reason for the draw, fall back to a straight write.
321f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            if (!fp) {
322f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference) {
3232f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips                    tempProxy.reset(nullptr);
324f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                }
325f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            } else {
326f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                applyPremulToSrc = false;
327f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            }
328f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon        }
3292f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips        if (tempProxy) {
330f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            if (!fp) {
331ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman                fp = GrSimpleTextureEffect::Make(this->resourceProvider(), tempProxy, nullptr,
332ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman                                                 SkMatrix::I());
333ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman                fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle);
334ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman
335f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                if (!fp) {
336f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                    return false;
337f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                }
338f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            }
33932342f032e1dfd133040324f851f0365f9d4cb51Brian Osman            GrTexture* texture = tempProxy->instantiate(this->resourceProvider());
340757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips            if (!texture) {
341757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips                return false;
342757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips            }
343757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips            if (texture->surfacePriv().hasPendingIO()) {
344f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                this->flush();
345f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            }
346f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            if (applyPremulToSrc) {
347f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                size_t tmpRowBytes = 4 * width;
348f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                tmpPixels.reset(width * height);
349f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes,
350f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                                          tmpPixels.get())) {
351f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                    return false;
352f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                }
353f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                rowBytes = tmpRowBytes;
354f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                buffer = tmpPixels.get();
355f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                applyPremulToSrc = false;
356f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            }
357757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips            if (!fGpu->writePixels(texture, 0, 0, width, height,
3586c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon                                   tempDrawInfo.fWriteConfig, buffer,
3596cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon                                   rowBytes)) {
360f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                return false;
361f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            }
362f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            SkMatrix matrix;
363f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
364dfe4f2e4fe5b162d4adb4486fe751f1e3b30bea7brianosman            // TODO: Need to decide the semantics of this function for color spaces. Do we support
365dfe4f2e4fe5b162d4adb4486fe751f1e3b30bea7brianosman            // conversion from a passed-in color space? For now, specifying nullptr means that this
366dfe4f2e4fe5b162d4adb4486fe751f1e3b30bea7brianosman            // path will do no conversion, so it will match the behavior of the non-draw path.
367757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips            GrRenderTarget* renderTarget = surface->asRenderTarget();
368757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips            SkASSERT(renderTarget);
3691105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman            sk_sp<GrRenderTargetContext> renderTargetContext(
3701105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                this->contextPriv().makeWrappedRenderTargetContext(sk_ref_sp(renderTarget),
3711105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                   nullptr));
3721105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman            if (!renderTargetContext) {
373f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                return false;
374f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            }
375c4b72720e75313079212e69e46a5ef7c474b2305egdaniel            GrPaint paint;
37606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            paint.addColorFragmentProcessor(std::move(fp));
377374772bd61951f01bf84fe17bf53d8867681c9aereed            paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
378a167e74b4bb78cfbbec3d8768e5853cd0b9314abbrianosman            paint.setAllowSRGBInputs(true);
379f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
38082f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon            renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, matrix, rect,
38182f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                                          nullptr);
382c3fb74693e25cf6dffc8add8669c54c4b7ace3a2bsalomon
383f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            if (kFlushWrites_PixelOp & pixelOpsFlags) {
384f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon                this->flushSurfaceWrites(surface);
385f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            }
38681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        }
387f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon    }
3882f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips    if (!tempProxy) {
389f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon        if (applyPremulToSrc) {
39081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            size_t tmpRowBytes = 4 * width;
39181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            tmpPixels.reset(width * height);
39281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes,
39381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                                      tmpPixels.get())) {
39481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                return false;
39581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            }
39681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            rowBytes = tmpRowBytes;
39781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            buffer = tmpPixels.get();
398f0674516cb18f6b13e34f404ff5793d9b9ebb56cbsalomon            applyPremulToSrc = false;
3993f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org        }
4006cb3cbe8e67db5fb94ba7d98f60833229b008544bsalomon        return fGpu->writePixels(surface, left, top, width, height, srcConfig, buffer, rowBytes);
40181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    }
40281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    return true;
40381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon}
404a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com
405b62ea2240ffbc28bdf2469464e232f674f59584bBrian Osmanbool GrContext::readSurfacePixels(GrSurface* src, SkColorSpace* srcColorSpace,
406e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon                                  int left, int top, int width, int height,
407b62ea2240ffbc28bdf2469464e232f674f59584bBrian Osman                                  GrPixelConfig dstConfig, SkColorSpace* dstColorSpace,
408b62ea2240ffbc28bdf2469464e232f674f59584bBrian Osman                                  void* buffer, size_t rowBytes, uint32_t flags) {
409b62ea2240ffbc28bdf2469464e232f674f59584bBrian Osman    // TODO: Color space conversion
410b62ea2240ffbc28bdf2469464e232f674f59584bBrian Osman
4111de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
4125f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_FALSE_IF_ABANDONED
413e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon    ASSERT_OWNED_RESOURCE(src);
414e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon    SkASSERT(src);
415bc90735170b5d85a19b24df0baa865f7cf87d348joshualitt    GR_AUDIT_TRAIL_AUTO_FRAME(&fAuditTrail, "GrContext::readSurfacePixels");
41632ab260ee18ab53611bcd2eefde535b6e31f9d8dbsalomon
4176c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon    this->testPMConversionsIfNecessary(flags);
4186c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon
419e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon    // Adjust the params so that if we wind up using an intermediate surface we've already done
420e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon    // all the trimming and the temporary can be the min size required.
421e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon    if (!GrSurfacePriv::AdjustReadPixelParams(src->width(), src->height(),
422e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon                                              GrBytesPerPixel(dstConfig), &left,
423e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon                                              &top, &width, &height, &buffer, &rowBytes)) {
424e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon        return false;
425e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon    }
426669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com
427e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon    if (!(kDontFlush_PixelOpsFlag & flags) && src->surfacePriv().hasPendingWrite()) {
4286f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com        this->flush();
4296f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    }
430c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com
431e8d21e8f24aa676765d0ff8f433228665c75cdc2bsalomon    bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags);
432ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman    if (unpremul && !valid_unpremul_config(dstConfig)) {
433de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman        // The unpremul flag is only allowed for 8888 and F16 configs.
4340a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com        return false;
4350a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com    }
436bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // We don't allow conversion between integer configs and float/fixed configs.
437bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    if (GrPixelConfigIsSint(src->config()) != GrPixelConfigIsSint(dstConfig)) {
438bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        return false;
439bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
440a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com
441636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon    GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference;
442636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon    // Don't prefer to draw for the conversion (and thereby access a texture from the cache) when
443636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon    // we've already determined that there isn't a roundtrip preserving conversion processor pair.
444de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman    if (unpremul && this->validPMUPMConversionExists(src->config())) {
445636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon        drawPreference = GrGpu::kCallerPrefersDraw_DrawPreference;
446636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon    }
447636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon
448398260262f8508687614ec496a23b8152bcdc967bsalomon    GrGpu::ReadPixelTempDrawInfo tempDrawInfo;
449398260262f8508687614ec496a23b8152bcdc967bsalomon    if (!fGpu->getReadPixelsInfo(src, width, height, rowBytes, dstConfig, &drawPreference,
450398260262f8508687614ec496a23b8152bcdc967bsalomon                                 &tempDrawInfo)) {
451398260262f8508687614ec496a23b8152bcdc967bsalomon        return false;
452398260262f8508687614ec496a23b8152bcdc967bsalomon    }
453398260262f8508687614ec496a23b8152bcdc967bsalomon
454144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary    sk_sp<GrSurface> surfaceToRead(SkRef(src));
455398260262f8508687614ec496a23b8152bcdc967bsalomon    bool didTempDraw = false;
456398260262f8508687614ec496a23b8152bcdc967bsalomon    if (GrGpu::kNoDraw_DrawPreference != drawPreference) {
457b117ff194ff888ef9107a4797aad053b0d76be30bsalomon        if (SkBackingFit::kExact == tempDrawInfo.fTempSurfaceFit) {
458398260262f8508687614ec496a23b8152bcdc967bsalomon            // We only respect this when the entire src is being read. Otherwise we can trigger too
459398260262f8508687614ec496a23b8152bcdc967bsalomon            // many odd ball texture sizes and trash the cache.
460eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon            if (width != src->width() || height != src->height()) {
461b117ff194ff888ef9107a4797aad053b0d76be30bsalomon                tempDrawInfo.fTempSurfaceFit= SkBackingFit::kApprox;
462398260262f8508687614ec496a23b8152bcdc967bsalomon            }
46356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        }
464dfe4f2e4fe5b162d4adb4486fe751f1e3b30bea7brianosman        // TODO: Need to decide the semantics of this function for color spaces. Do we support
465dfe4f2e4fe5b162d4adb4486fe751f1e3b30bea7brianosman        // conversion to a passed-in color space? For now, specifying nullptr means that this
466dfe4f2e4fe5b162d4adb4486fe751f1e3b30bea7brianosman        // path will do no conversion, so it will match the behavior of the non-draw path.
467693a540272a771c6b0830094c461397cb77543b1Brian Osman        sk_sp<GrRenderTargetContext> tempRTC = this->makeRenderTargetContext(
4681105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                           tempDrawInfo.fTempSurfaceFit,
469b117ff194ff888ef9107a4797aad053b0d76be30bsalomon                                                           tempDrawInfo.fTempSurfaceDesc.fWidth,
470b117ff194ff888ef9107a4797aad053b0d76be30bsalomon                                                           tempDrawInfo.fTempSurfaceDesc.fHeight,
471b117ff194ff888ef9107a4797aad053b0d76be30bsalomon                                                           tempDrawInfo.fTempSurfaceDesc.fConfig,
472dfe4f2e4fe5b162d4adb4486fe751f1e3b30bea7brianosman                                                           nullptr,
473b117ff194ff888ef9107a4797aad053b0d76be30bsalomon                                                           tempDrawInfo.fTempSurfaceDesc.fSampleCnt,
474b117ff194ff888ef9107a4797aad053b0d76be30bsalomon                                                           tempDrawInfo.fTempSurfaceDesc.fOrigin);
475693a540272a771c6b0830094c461397cb77543b1Brian Osman        if (tempRTC) {
47667c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips            SkMatrix textureMatrix = SkMatrix::MakeTrans(SkIntToScalar(left), SkIntToScalar(top));
47706ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman            sk_sp<GrFragmentProcessor> fp;
478a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com            if (unpremul) {
479ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman                fp = this->createPMToUPMEffect(src->asTexture(), textureMatrix);
480ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman                fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle);
481b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                if (fp) {
4829c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com                    unpremul = false; // we no longer need to do this on CPU after the read back.
483398260262f8508687614ec496a23b8152bcdc967bsalomon                } else if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference) {
484398260262f8508687614ec496a23b8152bcdc967bsalomon                    // We only wanted to do the draw in order to perform the unpremul so don't
485398260262f8508687614ec496a23b8152bcdc967bsalomon                    // bother.
486693a540272a771c6b0830094c461397cb77543b1Brian Osman                    tempRTC.reset(nullptr);
487d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com                }
488a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com            }
489693a540272a771c6b0830094c461397cb77543b1Brian Osman            if (!fp && tempRTC) {
490ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman                fp = GrSimpleTextureEffect::Make(src->asTexture(), nullptr, textureMatrix);
491ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman                fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), tempDrawInfo.fSwizzle);
492398260262f8508687614ec496a23b8152bcdc967bsalomon            }
493398260262f8508687614ec496a23b8152bcdc967bsalomon            if (fp) {
494c4b72720e75313079212e69e46a5ef7c474b2305egdaniel                GrPaint paint;
49506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman                paint.addColorFragmentProcessor(std::move(fp));
496374772bd61951f01bf84fe17bf53d8867681c9aereed                paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
497a167e74b4bb78cfbbec3d8768e5853cd0b9314abbrianosman                paint.setAllowSRGBInputs(true);
498398260262f8508687614ec496a23b8152bcdc967bsalomon                SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
49982f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                tempRTC->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect,
50082f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon                                  nullptr);
501693a540272a771c6b0830094c461397cb77543b1Brian Osman                surfaceToRead.reset(tempRTC->asTexture().release());
502398260262f8508687614ec496a23b8152bcdc967bsalomon                left = 0;
503398260262f8508687614ec496a23b8152bcdc967bsalomon                top = 0;
504398260262f8508687614ec496a23b8152bcdc967bsalomon                didTempDraw = true;
505a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com            }
506c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        }
507a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    }
5085c55fef032d1de01fed6b40ac39081aea9544a75joshualitt
509833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips    if (!surfaceToRead) {
510833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips        return false;
511833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips    }
512833dcf48844dd053ddf7ecea20e3e1c2b6b47e01Robert Phillips
513398260262f8508687614ec496a23b8152bcdc967bsalomon    if (GrGpu::kRequireDraw_DrawPreference == drawPreference && !didTempDraw) {
514a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com        return false;
515a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    }
516398260262f8508687614ec496a23b8152bcdc967bsalomon    GrPixelConfig configToRead = dstConfig;
517398260262f8508687614ec496a23b8152bcdc967bsalomon    if (didTempDraw) {
518144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary        this->flushSurfaceWrites(surfaceToRead.get());
5196c9cd55f00beeba3ded3f28bcbdd6ef030c4dac7bsalomon        configToRead = tempDrawInfo.fReadConfig;
520398260262f8508687614ec496a23b8152bcdc967bsalomon    }
521144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary    if (!fGpu->readPixels(surfaceToRead.get(), left, top, width, height, configToRead, buffer,
522144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary                          rowBytes)) {
523398260262f8508687614ec496a23b8152bcdc967bsalomon        return false;
524398260262f8508687614ec496a23b8152bcdc967bsalomon    }
525398260262f8508687614ec496a23b8152bcdc967bsalomon
526398260262f8508687614ec496a23b8152bcdc967bsalomon    // Perform umpremul conversion if we weren't able to perform it as a draw.
527398260262f8508687614ec496a23b8152bcdc967bsalomon    if (unpremul) {
528c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett        SkColorType colorType;
529c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett        if (!GrPixelConfigToColorType(dstConfig, &colorType) ||
530c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett            4 != SkColorTypeBytesPerPixel(colorType))
531c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett        {
5327111d463cee893a479280c7af41757e709e33ef5reed@google.com            return false;
5337111d463cee893a479280c7af41757e709e33ef5reed@google.com        }
534be41d38f1c076c9e4dc595a6e1a4eb5ccdbd307bskia.committer@gmail.com
535c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett        for (int y = 0; y < height; y++) {
536c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett            SkUnpremultiplyRow<false>((uint32_t*) buffer, (const uint32_t*) buffer, width);
537c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett            buffer = SkTAddOffset<void>(buffer, rowBytes);
538c7b29089475772a51541323a93a15baad2a5feaaMatt Sarett        }
539c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com    }
540a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    return true;
54127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
54227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
543c49e8682ab0614e1b6816dadd00f65d770ab6999bsalomonvoid GrContext::prepareSurfaceForExternalIO(GrSurface* surface) {
5441de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
5455f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
54687a94eb1632d06eeeb89490a91565e786440d6d0bsalomon    SkASSERT(surface);
54787a94eb1632d06eeeb89490a91565e786440d6d0bsalomon    ASSERT_OWNED_RESOURCE(surface);
5486a2b1941c1da272f704439e417f212932eed2004bsalomon    fDrawingManager->prepareSurfaceForExternalIO(surface);
54975f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com}
55075f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com
551f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomonvoid GrContext::flushSurfaceWrites(GrSurface* surface) {
5521de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
5535f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
554f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon    if (surface->surfacePriv().hasPendingWrite()) {
555f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon        this->flush();
556f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon    }
557f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon}
558f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon
55995243ebb68cae9ff4821ea57b9a32a194f2a87cfajumavoid GrContext::flushSurfaceIO(GrSurface* surface) {
56095243ebb68cae9ff4821ea57b9a32a194f2a87cfajuma    ASSERT_SINGLE_OWNER
56195243ebb68cae9ff4821ea57b9a32a194f2a87cfajuma    RETURN_IF_ABANDONED
56295243ebb68cae9ff4821ea57b9a32a194f2a87cfajuma    if (surface->surfacePriv().hasPendingIO()) {
56395243ebb68cae9ff4821ea57b9a32a194f2a87cfajuma        this->flush();
56495243ebb68cae9ff4821ea57b9a32a194f2a87cfajuma    }
56595243ebb68cae9ff4821ea57b9a32a194f2a87cfajuma}
56695243ebb68cae9ff4821ea57b9a32a194f2a87cfajuma
56727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com////////////////////////////////////////////////////////////////////////////////
568b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.orgint GrContext::getRecommendedSampleCount(GrPixelConfig config,
569b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org                                         SkScalar dpi) const {
5701de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
5711de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt
572762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon    if (!this->caps()->isConfigRenderable(config, true)) {
573b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org        return 0;
574b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org    }
575b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org    int chosenSampleCount = 0;
576e9c0fc616d2a1632c285885b9b656b68ca8d4f24jvanverth    if (fGpu->caps()->shaderCaps()->pathRenderingSupport()) {
577b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org        if (dpi >= 250.0f) {
578b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org            chosenSampleCount = 4;
579b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org        } else {
580b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org            chosenSampleCount = 16;
581b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org        }
582b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org    }
583eed519e6a2d0e61b0733a388de9320af897ed197egdaniel    return chosenSampleCount <= fGpu->caps()->maxSampleCount() ? chosenSampleCount : 0;
584b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org}
585b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org
5861105224f9701e57ec5ce0354d6a380b664f5c638Brian Osmansk_sp<GrRenderTargetContext> GrContextPriv::makeWrappedRenderTargetContext(
5871105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                               sk_sp<GrRenderTarget> rt,
5881105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                               sk_sp<SkColorSpace> colorSpace,
5891105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                               const SkSurfaceProps* surfaceProps) {
5904fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips    ASSERT_SINGLE_OWNER_PRIV
591c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
5923743013f755d23c215d852af7d829c3cd74f34a2Robert Phillips    sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(rt)));
59377b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips    if (!proxy) {
59477b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips        return nullptr;
59577b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips    }
596c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
5973743013f755d23c215d852af7d829c3cd74f34a2Robert Phillips    return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
598c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                           std::move(colorSpace),
5991105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                           surfaceProps);
6004fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips}
60177a2e52c7d5c77de73ecab5fec79072ee4460706robertphillips
6022c86249465c28a532c8be55b6ba497021e3110ecRobert Phillipssk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy,
6032c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips                                                                 sk_sp<SkColorSpace> colorSpace) {
60445580d3e3024c1536e8e1b2017b704805442b634Brian Osman    ASSERT_SINGLE_OWNER_PRIV
60545580d3e3024c1536e8e1b2017b704805442b634Brian Osman
60645580d3e3024c1536e8e1b2017b704805442b634Brian Osman    if (proxy->asRenderTargetProxy()) {
6072c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips        return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
6082c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips                                                               std::move(colorSpace), nullptr);
60945580d3e3024c1536e8e1b2017b704805442b634Brian Osman    } else {
61045580d3e3024c1536e8e1b2017b704805442b634Brian Osman        SkASSERT(proxy->asTextureProxy());
6112c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips        return this->drawingManager()->makeTextureContext(std::move(proxy), std::move(colorSpace));
61245580d3e3024c1536e8e1b2017b704805442b634Brian Osman    }
61345580d3e3024c1536e8e1b2017b704805442b634Brian Osman}
61445580d3e3024c1536e8e1b2017b704805442b634Brian Osman
61531c2608e859b1f1c25eeea429f5ab2fee1529facRobert Phillipssk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurface> surface) {
61631c2608e859b1f1c25eeea429f5ab2fee1529facRobert Phillips    ASSERT_SINGLE_OWNER_PRIV
61731c2608e859b1f1c25eeea429f5ab2fee1529facRobert Phillips
61831c2608e859b1f1c25eeea429f5ab2fee1529facRobert Phillips    sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(surface)));
61977b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips    if (!proxy) {
62077b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips        return nullptr;
62177b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips    }
62231c2608e859b1f1c25eeea429f5ab2fee1529facRobert Phillips
6232c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    return this->makeWrappedSurfaceContext(std::move(proxy), nullptr);
62431c2608e859b1f1c25eeea429f5ab2fee1529facRobert Phillips}
62531c2608e859b1f1c25eeea429f5ab2fee1529facRobert Phillips
626e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillipssk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc,
627e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips                                                                  SkBackingFit fit,
628e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips                                                                  SkBudgeted isDstBudgeted) {
629e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
63032342f032e1dfd133040324f851f0365f9d4cb51Brian Osman    sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferred(fContext->resourceProvider(),
63126c90e04797e15c37ec00e0f836292b8a207d294Robert Phillips                                                               dstDesc, fit, isDstBudgeted);
63277b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips    if (!proxy) {
63377b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips        return nullptr;
63477b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips    }
635e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
6362c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    return this->makeWrappedSurfaceContext(std::move(proxy), nullptr);
637e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips}
638e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
63926caf898f1db66bc6923b61ef902132bbdff51ddRobert Phillipssk_sp<GrSurfaceContext> GrContextPriv::makeBackendSurfaceContext(const GrBackendTextureDesc& desc,
640c1e37059a84044db2db5ae90fa0dd7c7278d9f66Brian Osman                                                                 sk_sp<SkColorSpace> colorSpace) {
64126caf898f1db66bc6923b61ef902132bbdff51ddRobert Phillips    ASSERT_SINGLE_OWNER_PRIV
64226caf898f1db66bc6923b61ef902132bbdff51ddRobert Phillips
643c1e37059a84044db2db5ae90fa0dd7c7278d9f66Brian Osman    sk_sp<GrSurface> surface(fContext->resourceProvider()->wrapBackendTexture(desc));
64426caf898f1db66bc6923b61ef902132bbdff51ddRobert Phillips    if (!surface) {
64526caf898f1db66bc6923b61ef902132bbdff51ddRobert Phillips        return nullptr;
64626caf898f1db66bc6923b61ef902132bbdff51ddRobert Phillips    }
64726caf898f1db66bc6923b61ef902132bbdff51ddRobert Phillips
64826caf898f1db66bc6923b61ef902132bbdff51ddRobert Phillips    sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(surface)));
64977b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips    if (!proxy) {
65077b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips        return nullptr;
65177b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips    }
65226caf898f1db66bc6923b61ef902132bbdff51ddRobert Phillips
65326caf898f1db66bc6923b61ef902132bbdff51ddRobert Phillips    return this->makeWrappedSurfaceContext(std::move(proxy), std::move(colorSpace));
65426caf898f1db66bc6923b61ef902132bbdff51ddRobert Phillips}
65526caf898f1db66bc6923b61ef902132bbdff51ddRobert Phillips
6561105224f9701e57ec5ce0354d6a380b664f5c638Brian Osmansk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureRenderTargetContext(
657e305cc1f2a44e47d6a0dcc0ff34e2692349aed5dRobert Phillips                                                                   const GrBackendTextureDesc& desc,
6581105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                   sk_sp<SkColorSpace> colorSpace,
659c1e37059a84044db2db5ae90fa0dd7c7278d9f66Brian Osman                                                                   const SkSurfaceProps* props) {
6604fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips    ASSERT_SINGLE_OWNER_PRIV
6614fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips    SkASSERT(desc.fFlags & kRenderTarget_GrBackendTextureFlag);
6624fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips
663c1e37059a84044db2db5ae90fa0dd7c7278d9f66Brian Osman    sk_sp<GrSurface> surface(fContext->resourceProvider()->wrapBackendTexture(desc));
6644fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips    if (!surface) {
6654fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips        return nullptr;
6664fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips    }
6674fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips
6683743013f755d23c215d852af7d829c3cd74f34a2Robert Phillips    sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(surface)));
66977b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips    if (!proxy) {
67077b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips        return nullptr;
67177b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips    }
672c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
6733743013f755d23c215d852af7d829c3cd74f34a2Robert Phillips    return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
6741105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                           std::move(colorSpace), props);
6754fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips}
6764fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips
6771105224f9701e57ec5ce0354d6a380b664f5c638Brian Osmansk_sp<GrRenderTargetContext> GrContextPriv::makeBackendRenderTargetRenderTargetContext(
6784fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips                                                const GrBackendRenderTargetDesc& desc,
6794fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips                                                sk_sp<SkColorSpace> colorSpace,
6804fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips                                                const SkSurfaceProps* surfaceProps) {
6814fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips    ASSERT_SINGLE_OWNER_PRIV
6824fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips
68332342f032e1dfd133040324f851f0365f9d4cb51Brian Osman    sk_sp<GrRenderTarget> rt(fContext->resourceProvider()->wrapBackendRenderTarget(desc));
6844fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips    if (!rt) {
6854fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips        return nullptr;
6864fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips    }
6874fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips
6883743013f755d23c215d852af7d829c3cd74f34a2Robert Phillips    sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(rt)));
68977b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips    if (!proxy) {
69077b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips        return nullptr;
69177b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips    }
692c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
6933743013f755d23c215d852af7d829c3cd74f34a2Robert Phillips    return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
694c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                           std::move(colorSpace),
6951105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                           surfaceProps);
6964fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips}
6974fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips
6981105224f9701e57ec5ce0354d6a380b664f5c638Brian Osmansk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureAsRenderTargetRenderTargetContext(
699a95d46b4ac8e41c9beb2b750cd389b1c6ebaf0a7egdaniel                                                     const GrBackendTextureDesc& desc,
7004fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips                                                     sk_sp<SkColorSpace> colorSpace,
7014fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips                                                     const SkSurfaceProps* surfaceProps) {
7024fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips    ASSERT_SINGLE_OWNER_PRIV
7034fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips    SkASSERT(desc.fFlags & kRenderTarget_GrBackendTextureFlag);
7044fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips
7054fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips    sk_sp<GrSurface> surface(fContext->resourceProvider()->wrapBackendTextureAsRenderTarget(desc));
7064fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips    if (!surface) {
7074fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips        return nullptr;
7084fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips    }
7094fd74aec9f6c68c66483bcc6735793440b1ba184robertphillips
7103743013f755d23c215d852af7d829c3cd74f34a2Robert Phillips    sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(surface)));
71177b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips    if (!proxy) {
71277b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips        return nullptr;
71377b3f32936dd069fa6a27f870b3b30035733d940Robert Phillips    }
714c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
7153743013f755d23c215d852af7d829c3cd74f34a2Robert Phillips    return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
716c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                           std::move(colorSpace),
717c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                           surfaceProps);
71877a2e52c7d5c77de73ecab5fec79072ee4460706robertphillips}
71977a2e52c7d5c77de73ecab5fec79072ee4460706robertphillips
720eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillipsvoid GrContextPriv::addPreFlushCallbackObject(sk_sp<GrPreFlushCallbackObject> preFlushCBObject) {
721eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips    fContext->fDrawingManager->addPreFlushCallbackObject(std::move(preFlushCBObject));
722eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips}
723eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
724eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
72548fde9c4127860ca5851b88ba123169b9889445crobertphillipsstatic inline GrPixelConfig GrPixelConfigFallback(GrPixelConfig config) {
72678f20e0e97472c39377bcb610d845ae6ef5d6aceBrian Osman    switch (config) {
72778f20e0e97472c39377bcb610d845ae6ef5d6aceBrian Osman        case kAlpha_8_GrPixelConfig:
72878f20e0e97472c39377bcb610d845ae6ef5d6aceBrian Osman        case kRGB_565_GrPixelConfig:
72978f20e0e97472c39377bcb610d845ae6ef5d6aceBrian Osman        case kRGBA_4444_GrPixelConfig:
73078f20e0e97472c39377bcb610d845ae6ef5d6aceBrian Osman        case kBGRA_8888_GrPixelConfig:
73178f20e0e97472c39377bcb610d845ae6ef5d6aceBrian Osman            return kRGBA_8888_GrPixelConfig;
73278f20e0e97472c39377bcb610d845ae6ef5d6aceBrian Osman        case kSBGRA_8888_GrPixelConfig:
73378f20e0e97472c39377bcb610d845ae6ef5d6aceBrian Osman            return kSRGBA_8888_GrPixelConfig;
73478f20e0e97472c39377bcb610d845ae6ef5d6aceBrian Osman        case kAlpha_half_GrPixelConfig:
73578f20e0e97472c39377bcb610d845ae6ef5d6aceBrian Osman            return kRGBA_half_GrPixelConfig;
73678f20e0e97472c39377bcb610d845ae6ef5d6aceBrian Osman        default:
73778f20e0e97472c39377bcb610d845ae6ef5d6aceBrian Osman            return kUnknown_GrPixelConfig;
73878f20e0e97472c39377bcb610d845ae6ef5d6aceBrian Osman    }
73948fde9c4127860ca5851b88ba123169b9889445crobertphillips}
74048fde9c4127860ca5851b88ba123169b9889445crobertphillips
7411105224f9701e57ec5ce0354d6a380b664f5c638Brian Osmansk_sp<GrRenderTargetContext> GrContext::makeRenderTargetContextWithFallback(
7421105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                 SkBackingFit fit,
7431105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                 int width, int height,
7441105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                 GrPixelConfig config,
7451105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                 sk_sp<SkColorSpace> colorSpace,
7461105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                 int sampleCnt,
7471105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                 GrSurfaceOrigin origin,
7481105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                 const SkSurfaceProps* surfaceProps,
7491105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                 SkBudgeted budgeted) {
75048fde9c4127860ca5851b88ba123169b9889445crobertphillips    if (!this->caps()->isConfigRenderable(config, sampleCnt > 0)) {
75148fde9c4127860ca5851b88ba123169b9889445crobertphillips        config = GrPixelConfigFallback(config);
75248fde9c4127860ca5851b88ba123169b9889445crobertphillips    }
75348fde9c4127860ca5851b88ba123169b9889445crobertphillips
7541105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    return this->makeRenderTargetContext(fit, width, height, config, std::move(colorSpace),
7551105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                         sampleCnt, origin, surfaceProps, budgeted);
75648fde9c4127860ca5851b88ba123169b9889445crobertphillips}
75748fde9c4127860ca5851b88ba123169b9889445crobertphillips
758d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillipssk_sp<GrRenderTargetContext> GrContext::makeDeferredRenderTargetContextWithFallback(
759d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips                                                                 SkBackingFit fit,
760d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips                                                                 int width, int height,
761d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips                                                                 GrPixelConfig config,
762d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips                                                                 sk_sp<SkColorSpace> colorSpace,
763d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips                                                                 int sampleCnt,
764d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips                                                                 GrSurfaceOrigin origin,
765d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips                                                                 const SkSurfaceProps* surfaceProps,
766d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips                                                                 SkBudgeted budgeted) {
767d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips    if (!this->caps()->isConfigRenderable(config, sampleCnt > 0)) {
768d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips        config = GrPixelConfigFallback(config);
769d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips    }
770d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips
771d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips    return this->makeDeferredRenderTargetContext(fit, width, height, config, std::move(colorSpace),
772d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips                                                 sampleCnt, origin, surfaceProps, budgeted);
773d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips}
774d728f0c1a94fe926b59d8ebc9ae174019ccd3606robertphillips
7751105224f9701e57ec5ce0354d6a380b664f5c638Brian Osmansk_sp<GrRenderTargetContext> GrContext::makeRenderTargetContext(SkBackingFit fit,
7761105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                int width, int height,
7771105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                GrPixelConfig config,
7781105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                sk_sp<SkColorSpace> colorSpace,
7791105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                int sampleCnt,
7801105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                GrSurfaceOrigin origin,
7811105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                const SkSurfaceProps* surfaceProps,
7821105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                SkBudgeted budgeted) {
78348fde9c4127860ca5851b88ba123169b9889445crobertphillips    if (!this->caps()->isConfigRenderable(config, sampleCnt > 0)) {
78448fde9c4127860ca5851b88ba123169b9889445crobertphillips        return nullptr;
78548fde9c4127860ca5851b88ba123169b9889445crobertphillips    }
78648fde9c4127860ca5851b88ba123169b9889445crobertphillips
787d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips    GrSurfaceDesc desc;
788d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips    desc.fFlags = kRenderTarget_GrSurfaceFlag;
789d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips    desc.fOrigin = origin;
790d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips    desc.fWidth = width;
791d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips    desc.fHeight = height;
792d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips    desc.fConfig = config;
793d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips    desc.fSampleCnt = sampleCnt;
794d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips
795d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips    sk_sp<GrTexture> tex;
79676948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips    if (SkBackingFit::kExact == fit) {
79732342f032e1dfd133040324f851f0365f9d4cb51Brian Osman        tex.reset(this->resourceProvider()->createTexture(desc, budgeted));
798d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips    } else {
79932342f032e1dfd133040324f851f0365f9d4cb51Brian Osman        tex.reset(this->resourceProvider()->createApproxTexture(desc, 0));
800d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips    }
801d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips    if (!tex) {
802d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips        return nullptr;
803d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips    }
804d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips
8051105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    sk_sp<GrRenderTargetContext> renderTargetContext(
8061105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman        this->contextPriv().makeWrappedRenderTargetContext(sk_ref_sp(tex->asRenderTarget()),
8076738c702423226619ee0172c12a3a007c5f68e57robertphillips                                                           std::move(colorSpace), surfaceProps));
8081105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    if (!renderTargetContext) {
809d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips        return nullptr;
810d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips    }
811d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips
8121105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman    return renderTargetContext;
813d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips}
814d4c741e3d0e0fa633399691c47f76b6c7841ee83robertphillips
815c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillipssk_sp<GrRenderTargetContext> GrContext::makeDeferredRenderTargetContext(
816c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                        SkBackingFit fit,
817c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                        int width, int height,
818c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                        GrPixelConfig config,
819c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                        sk_sp<SkColorSpace> colorSpace,
820c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                        int sampleCnt,
821c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                        GrSurfaceOrigin origin,
822c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                        const SkSurfaceProps* surfaceProps,
823c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                        SkBudgeted budgeted) {
824c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    GrSurfaceDesc desc;
825c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    desc.fFlags = kRenderTarget_GrSurfaceFlag;
826c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    desc.fOrigin = origin;
827c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    desc.fWidth = width;
828c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    desc.fHeight = height;
829c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    desc.fConfig = config;
830c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    desc.fSampleCnt = sampleCnt;
831c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
83232342f032e1dfd133040324f851f0365f9d4cb51Brian Osman    sk_sp<GrTextureProxy> rtp = GrSurfaceProxy::MakeDeferred(this->resourceProvider(),
83326c90e04797e15c37ec00e0f836292b8a207d294Robert Phillips                                                             desc, fit, budgeted);
83408c5ec71303aa58d6f081914f3e868fa5cce9f4cRobert Phillips    if (!rtp) {
83508c5ec71303aa58d6f081914f3e868fa5cce9f4cRobert Phillips        return nullptr;
83608c5ec71303aa58d6f081914f3e868fa5cce9f4cRobert Phillips    }
837c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
838c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    return fDrawingManager->makeRenderTargetContext(std::move(rtp),
839c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                    std::move(colorSpace),
840c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                    surfaceProps);
841c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips}
842c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
8431de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualittbool GrContext::abandoned() const {
8441de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
8457761d61876ea479dd9672b684fd5c7601932a767robertphillips    return fDrawingManager->wasAbandoned();
84677a2e52c7d5c77de73ecab5fec79072ee4460706robertphillips}
84777a2e52c7d5c77de73ecab5fec79072ee4460706robertphillips
848a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comnamespace {
849a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comvoid test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) {
850a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    GrConfigConversionEffect::PMConversion pmToUPM;
851a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    GrConfigConversionEffect::PMConversion upmToPM;
852a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upmToPM);
853a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    *pmToUPMValue = pmToUPM;
854a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    *upmToPMValue = upmToPM;
855a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com}
856a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com}
857a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com
8586c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomonvoid GrContext::testPMConversionsIfNecessary(uint32_t flags) {
8591de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
8606c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon    if (SkToBool(kUnpremul_PixelOpsFlag & flags)) {
8616c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon        if (!fDidTestPMConversions) {
8626c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon            test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
8636c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon            fDidTestPMConversions = true;
8646c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon        }
8656c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon    }
8666c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon}
8676c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon
86806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrFragmentProcessor> GrContext::createPMToUPMEffect(GrTexture* texture,
869757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips                                                          const SkMatrix& matrix) {
8701de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
8716c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon    // We should have already called this->testPMConversionsIfNecessary().
8726c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon    SkASSERT(fDidTestPMConversions);
87331f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman    if (kRGBA_half_GrPixelConfig == texture->config()) {
87431f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman        return GrFragmentProcessor::UnpremulOutput(
87531f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman                GrSimpleTextureEffect::Make(texture, nullptr, matrix));
87631f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman    } else {
877de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman        GrConfigConversionEffect::PMConversion pmToUPM =
878de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman            static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
879ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman        if (GrConfigConversionEffect::kPMConversionCnt != pmToUPM) {
88031f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman            return GrConfigConversionEffect::Make(texture, pmToUPM, matrix);
88131f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman        } else {
88231f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman            return nullptr;
883de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman        }
884a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    }
885a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com}
886a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com
887757914d26b337b04cf270875bce28d7d1e2407deRobert Phillipssk_sp<GrFragmentProcessor> GrContext::createPMToUPMEffect(sk_sp<GrTextureProxy> proxy,
888757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips                                                          const SkMatrix& matrix) {
889757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips    ASSERT_SINGLE_OWNER
890757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips    // We should have already called this->testPMConversionsIfNecessary().
891757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips    SkASSERT(fDidTestPMConversions);
89231f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman    if (kRGBA_half_GrPixelConfig == proxy->config()) {
89331f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman        return GrFragmentProcessor::UnpremulOutput(
89431f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman                GrSimpleTextureEffect::Make(this->resourceProvider(), std::move(proxy),
89531f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman                                            nullptr, matrix));
89631f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman    } else {
897de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman        GrConfigConversionEffect::PMConversion pmToUPM =
898de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman            static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
899ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman        if (GrConfigConversionEffect::kPMConversionCnt != pmToUPM) {
90031f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman            return GrConfigConversionEffect::Make(this->resourceProvider(), std::move(proxy),
90131f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman                                                  pmToUPM, matrix);
90231f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman        } else {
90331f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman            return nullptr;
904de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman        }
905757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips    }
906757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips}
907757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips
908757914d26b337b04cf270875bce28d7d1e2407deRobert Phillipssk_sp<GrFragmentProcessor> GrContext::createUPMToPMEffect(sk_sp<GrTextureProxy> proxy,
909757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips                                                          const SkMatrix& matrix) {
9101de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
9116c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon    // We should have already called this->testPMConversionsIfNecessary().
9126c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon    SkASSERT(fDidTestPMConversions);
91331f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman    if (kRGBA_half_GrPixelConfig == proxy->config()) {
91431f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman        return GrFragmentProcessor::PremulOutput(
91531f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman                GrSimpleTextureEffect::Make(this->resourceProvider(), std::move(proxy),
91631f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman                                            nullptr, matrix));
91731f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman    } else {
918de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman        GrConfigConversionEffect::PMConversion upmToPM =
919de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman            static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion);
920ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman        if (GrConfigConversionEffect::kPMConversionCnt != upmToPM) {
92131f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman            return GrConfigConversionEffect::Make(this->resourceProvider(), std::move(proxy),
92231f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman                                                  upmToPM, matrix);
92331f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman        } else {
92431f96a68af509f41ed0ffb2145f355229ae9aaf0Brian Osman            return nullptr;
925de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman        }
926a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    }
927a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com}
928a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com
929de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osmanbool GrContext::validPMUPMConversionExists(GrPixelConfig config) const {
9301de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
9316c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon    // We should have already called this->testPMConversionsIfNecessary().
9326c6f65885ba20ba9e8d8c36039f1c9eff4cc814bbsalomon    SkASSERT(fDidTestPMConversions);
933636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon    // The PM<->UPM tests fail or succeed together so we only need to check one.
934de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman    // For F16, we always allow PM/UPM conversion on the GPU, even if it doesn't round-trip.
935ce425510a07632f14b7b779ec3864f719cb4326bBrian Osman    return GrConfigConversionEffect::kPMConversionCnt != fPMToUPMConversion ||
936de1a60534648ca8a6eb3ae32e06a7a9e9c0591f3Brian Osman           kRGBA_half_GrPixelConfig == config;
937636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon}
938636e8024f8df8df7b89813c8b2b1ea04d7481497bsalomon
93937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon//////////////////////////////////////////////////////////////////////////////
94037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
94137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonvoid GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes) const {
9421de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
94337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (maxTextures) {
9440ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        *maxTextures = fResourceCache->getMaxResourceCount();
94537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
94637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (maxTextureBytes) {
9470ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        *maxTextureBytes = fResourceCache->getMaxResourceBytes();
94837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
94937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
95037f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
95137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonvoid GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) {
9521de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
9530ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    fResourceCache->setLimits(maxTextures, maxTextureBytes);
95437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
95537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
9560a5fa484fd58d27088f8696bdc11c8cc8f2b4866ericrk//////////////////////////////////////////////////////////////////////////////
9570a5fa484fd58d27088f8696bdc11c8cc8f2b4866ericrk
9580a5fa484fd58d27088f8696bdc11c8cc8f2b4866ericrkvoid GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
9591de610a5287cf61d4f3a1fdc7413bd74827a8b6ajoshualitt    ASSERT_SINGLE_OWNER
9600a5fa484fd58d27088f8696bdc11c8cc8f2b4866ericrk    fResourceCache->dumpMemoryStatistics(traceMemoryDump);
9610a5fa484fd58d27088f8696bdc11c8cc8f2b4866ericrk}
962