13dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips/*
23dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips * Copyright 2015 Google Inc.
33dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips *
43dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips * Use of this source code is governed by a BSD-style license that can be
53dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips * found in the LICENSE file.
63dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips */
73dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
85eb41fdf94187d6cc22702444622ed7897c8039absalomon#include "GrDrawingManager.h"
9b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon
10b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon#include "GrContext.h"
11646e4293f06d9de6d44dbfa3c32cdc15a6f5906eRobert Phillips#include "GrGpu.h"
12fbcef6eb8abad142daf45418516550f7635b4a52Robert Phillips#include "GrOnFlushResourceProvider.h"
131105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman#include "GrRenderTargetContext.h"
141105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman#include "GrPathRenderingRenderTargetContext.h"
15c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips#include "GrRenderTargetProxy.h"
163dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips#include "GrResourceProvider.h"
17687378229aecefc0ab7e639181593774ec8a4290robertphillips#include "GrSoftwarePathRenderer.h"
186a2b1941c1da272f704439e417f212932eed2004bsalomon#include "GrSurfacePriv.h"
197ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips#include "GrSurfaceProxyPriv.h"
2045580d3e3024c1536e8e1b2017b704805442b634Brian Osman#include "GrTextureContext.h"
2145580d3e3024c1536e8e1b2017b704805442b634Brian Osman#include "GrTextureOpList.h"
220e22eb8e6efc7d7ab7a601ba555947916d139906brianosman#include "SkSurface_Gpu.h"
233dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips#include "SkTTopoSort.h"
243dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
25dcbb9d90db0e07b7a3625bcdab3af11ab44c4cfeBrian Salomon#include "GrTracing.h"
26e804292e805917002cc3d7baa7f967fb20d2c7cbjoshualitt#include "text/GrAtlasTextContext.h"
27e804292e805917002cc3d7baa7f967fb20d2c7cbjoshualitt#include "text/GrStencilAndCoverTextContext.h"
28498d7ac86bfb45bdfc8f9aa7424f7236235987b5robertphillips
293dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillipsvoid GrDrawingManager::cleanup() {
30f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
31ee683655a9a9d57487ab8d4b0b01bb9bc2def144Robert Phillips        // no opList should receive a new command after this
32ee683655a9a9d57487ab8d4b0b01bb9bc2def144Robert Phillips        fOpLists[i]->makeClosed(*fContext->caps());
330dfa62c97707ac9b0fc0bdba7acfc8405db5c836robertphillips
34f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips        // We shouldn't need to do this, but it turns out some clients still hold onto opLists
356cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips        // after a cleanup.
366cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips        // MDB TODO: is this still true?
37f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips        fOpLists[i]->reset();
383dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    }
393dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
40f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    fOpLists.reset();
413dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
4213391dd97209f36c71bc18cc75084f74c2f6af15robertphillips    delete fPathRendererChain;
4313391dd97209f36c71bc18cc75084f74c2f6af15robertphillips    fPathRendererChain = nullptr;
44687378229aecefc0ab7e639181593774ec8a4290robertphillips    SkSafeSetNull(fSoftwarePathRenderer);
453dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips}
463dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
473dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillipsGrDrawingManager::~GrDrawingManager() {
483dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    this->cleanup();
493dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips}
503dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
513dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillipsvoid GrDrawingManager::abandon() {
523dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    fAbandoned = true;
53f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
54f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips        fOpLists[i]->abandonGpuResources();
55a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
563dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    this->cleanup();
573dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips}
583dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
59687378229aecefc0ab7e639181593774ec8a4290robertphillipsvoid GrDrawingManager::freeGpuResources() {
60687378229aecefc0ab7e639181593774ec8a4290robertphillips    // a path renderer may be holding onto resources
6113391dd97209f36c71bc18cc75084f74c2f6af15robertphillips    delete fPathRendererChain;
6213391dd97209f36c71bc18cc75084f74c2f6af15robertphillips    fPathRendererChain = nullptr;
63687378229aecefc0ab7e639181593774ec8a4290robertphillips    SkSafeSetNull(fSoftwarePathRenderer);
64f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
65f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips        fOpLists[i]->freeGpuResources();
66a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
67687378229aecefc0ab7e639181593774ec8a4290robertphillips}
68687378229aecefc0ab7e639181593774ec8a4290robertphillips
693dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillipsvoid GrDrawingManager::reset() {
70f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
71f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips        fOpLists[i]->reset();
723dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    }
73a13e202563979fd5076936606dcc1d660da8c632robertphillips    fFlushState.reset();
743dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips}
753dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
76e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillipsgr_instanced::OpAllocator* GrDrawingManager::instancingAllocator() {
77e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips    if (fInstancingAllocator) {
78e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips        return fInstancingAllocator.get();
79e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips    }
80e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips
81e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips    fInstancingAllocator = fContext->getGpu()->createInstancedRenderingAllocator();
82e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips    return fInstancingAllocator.get();
83e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips}
84e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips
857ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips// MDB TODO: make use of the 'proxy' parameter.
867ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillipsvoid GrDrawingManager::internalFlush(GrSurfaceProxy*, GrResourceCache::FlushType type) {
87dcbb9d90db0e07b7a3625bcdab3af11ab44c4cfeBrian Salomon    GR_CREATE_TRACE_MARKER_CONTEXT("GrDrawingManager", "internalFlush", fContext);
88dcbb9d90db0e07b7a3625bcdab3af11ab44c4cfeBrian Salomon
897761d61876ea479dd9672b684fd5c7601932a767robertphillips    if (fFlushing || this->wasAbandoned()) {
90b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon        return;
91b8918c42b7a4a603e880f9db994f993ca0052ed2joshualitt    }
92b8918c42b7a4a603e880f9db994f993ca0052ed2joshualitt    fFlushing = true;
93dc43898bbbd06202562514ae785116e0cc40f825bsalomon    bool flushed = false;
94eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
95eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
96eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        // Semi-usually the GrOpLists are already closed at this point, but sometimes Ganesh
97eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        // needs to flush mid-draw. In that case, the SkGpuDevice's GrOpLists won't be closed
98eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        // but need to be flushed anyway. Closing such GrOpLists here will mean new
99eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        // GrOpLists will be created to replace them if the SkGpuDevice(s) write to them again.
100ee683655a9a9d57487ab8d4b0b01bb9bc2def144Robert Phillips        fOpLists[i]->makeClosed(*fContext->caps());
101eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips    }
102eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
103a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips#ifdef SK_DEBUG
104a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips    // This block checks for any unnecessary splits in the opLists. If two sequential opLists
105a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips    // share the same backing GrSurfaceProxy it means the opList was artificially split.
106a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips    if (fOpLists.count()) {
107a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips        GrRenderTargetOpList* prevOpList = fOpLists[0]->asRenderTargetOpList();
108a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips        for (int i = 1; i < fOpLists.count(); ++i) {
109a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips            GrRenderTargetOpList* curOpList = fOpLists[i]->asRenderTargetOpList();
110a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips
111a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips            if (prevOpList && curOpList) {
112a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips                SkASSERT(prevOpList->fTarget.get() != curOpList->fTarget.get());
113a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips            }
114a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips
115a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips            prevOpList = curOpList;
116a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips        }
117a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips    }
118a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips#endif
119a4c93ac535d3b0ed979c7bf666f09aa7dbf1f0ebRobert Phillips
120f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips#ifdef ENABLE_MDB
1219d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary    SkDEBUGCODE(bool result =)
122f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips                        SkTTopoSort<GrOpList, GrOpList::TopoSortTraits>(&fOpLists);
1233dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    SkASSERT(result);
124f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips#endif
1253dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
126fe199b7d512a7cfc56deaaa134260e1d47a1e7e0Chris Dalton    GrOnFlushResourceProvider onFlushProvider(this);
127eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
128fe199b7d512a7cfc56deaaa134260e1d47a1e7e0Chris Dalton    if (!fOnFlushCBObjects.empty()) {
129eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        // MDB TODO: pre-MDB '1' is the correct pre-allocated size. Post-MDB it will need
130eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        // to be larger.
131eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        SkAutoSTArray<1, uint32_t> opListIds(fOpLists.count());
132eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        for (int i = 0; i < fOpLists.count(); ++i) {
133eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips            opListIds[i] = fOpLists[i]->uniqueID();
134eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        }
135eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
136eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        SkSTArray<1, sk_sp<GrRenderTargetContext>> renderTargetContexts;
137fe199b7d512a7cfc56deaaa134260e1d47a1e7e0Chris Dalton        for (GrOnFlushCallbackObject* onFlushCBObject : fOnFlushCBObjects) {
138fe199b7d512a7cfc56deaaa134260e1d47a1e7e0Chris Dalton            onFlushCBObject->preFlush(&onFlushProvider,
139fe199b7d512a7cfc56deaaa134260e1d47a1e7e0Chris Dalton                                      opListIds.get(), opListIds.count(),
140fe199b7d512a7cfc56deaaa134260e1d47a1e7e0Chris Dalton                                      &renderTargetContexts);
141eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips            if (!renderTargetContexts.count()) {
142eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                continue;       // This is fine. No atlases of this type are required for this flush
143eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips            }
144eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
145eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips            for (int j = 0; j < renderTargetContexts.count(); ++j) {
1462de8cfadc34cd92a6f99659fa565c137b386fa5fRobert Phillips                GrOpList* opList = renderTargetContexts[j]->getOpList();
147eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                if (!opList) {
148eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                    continue;   // Odd - but not a big deal
149eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                }
150b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillips                opList->makeClosed(*fContext->caps());
151eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                opList->prepareOps(&fFlushState);
152eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                if (!opList->executeOps(&fFlushState)) {
153eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                    continue;         // This is bad
154eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                }
155eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips            }
156eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips            renderTargetContexts.reset();
157eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        }
158eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips    }
159eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
160a13e202563979fd5076936606dcc1d660da8c632robertphillips#if 0
16109d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomon    // Enable this to print out verbose GrOp information
162f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
163f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips        SkDEBUGCODE(fOpLists[i]->dump();)
164a13e202563979fd5076936606dcc1d660da8c632robertphillips    }
165a13e202563979fd5076936606dcc1d660da8c632robertphillips#endif
166a13e202563979fd5076936606dcc1d660da8c632robertphillips
167318c419d3e373487a8bb28f56ea921ed850e61acRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
168318c419d3e373487a8bb28f56ea921ed850e61acRobert Phillips        if (!fOpLists[i]->instantiate(fContext->resourceProvider())) {
169318c419d3e373487a8bb28f56ea921ed850e61acRobert Phillips            fOpLists[i] = nullptr;
170318c419d3e373487a8bb28f56ea921ed850e61acRobert Phillips            continue;
171318c419d3e373487a8bb28f56ea921ed850e61acRobert Phillips        }
172318c419d3e373487a8bb28f56ea921ed850e61acRobert Phillips
173318c419d3e373487a8bb28f56ea921ed850e61acRobert Phillips        fOpLists[i]->prepareOps(&fFlushState);
174318c419d3e373487a8bb28f56ea921ed850e61acRobert Phillips    }
175318c419d3e373487a8bb28f56ea921ed850e61acRobert Phillips
176a13e202563979fd5076936606dcc1d660da8c632robertphillips    // Upload all data to the GPU
177a13e202563979fd5076936606dcc1d660da8c632robertphillips    fFlushState.preIssueDraws();
178a13e202563979fd5076936606dcc1d660da8c632robertphillips
179f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
180318c419d3e373487a8bb28f56ea921ed850e61acRobert Phillips        if (!fOpLists[i]) {
181318c419d3e373487a8bb28f56ea921ed850e61acRobert Phillips            continue;
182318c419d3e373487a8bb28f56ea921ed850e61acRobert Phillips        }
183318c419d3e373487a8bb28f56ea921ed850e61acRobert Phillips
1841e41f4a111e5b19e55d688033e7b857caef658e6Brian Salomon        if (fOpLists[i]->executeOps(&fFlushState)) {
185dc43898bbbd06202562514ae785116e0cc40f825bsalomon            flushed = true;
186dc43898bbbd06202562514ae785116e0cc40f825bsalomon        }
18718e9484ad5b5755757dc6badb986017a088a9c6bRobert Phillips        fOpLists[i]->reset();
188a13e202563979fd5076936606dcc1d660da8c632robertphillips    }
18918e9484ad5b5755757dc6badb986017a088a9c6bRobert Phillips    fOpLists.reset();
190a13e202563979fd5076936606dcc1d660da8c632robertphillips
191342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon    SkASSERT(fFlushState.nextDrawToken() == fFlushState.nextTokenToFlush());
192a13e202563979fd5076936606dcc1d660da8c632robertphillips
19318e9484ad5b5755757dc6badb986017a088a9c6bRobert Phillips    fContext->getGpu()->finishFlush();
194a13e202563979fd5076936606dcc1d660da8c632robertphillips
195a13e202563979fd5076936606dcc1d660da8c632robertphillips    fFlushState.reset();
196ee843b2ae4d75748d8bc323287f0c310fad548a7robertphillips    // We always have to notify the cache when it requested a flush so it can reset its state.
197ee843b2ae4d75748d8bc323287f0c310fad548a7robertphillips    if (flushed || type == GrResourceCache::FlushType::kCacheRequested) {
198b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon        fContext->getResourceCache()->notifyFlushOccurred(type);
199b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon    }
200fe199b7d512a7cfc56deaaa134260e1d47a1e7e0Chris Dalton    for (GrOnFlushCallbackObject* onFlushCBObject : fOnFlushCBObjects) {
201fe199b7d512a7cfc56deaaa134260e1d47a1e7e0Chris Dalton        onFlushCBObject->postFlush();
202fe199b7d512a7cfc56deaaa134260e1d47a1e7e0Chris Dalton    }
203b8918c42b7a4a603e880f9db994f993ca0052ed2joshualitt    fFlushing = false;
2043dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips}
2053dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
2067ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillipsvoid GrDrawingManager::prepareSurfaceForExternalIO(GrSurfaceProxy* proxy) {
2076a2b1941c1da272f704439e417f212932eed2004bsalomon    if (this->wasAbandoned()) {
2086a2b1941c1da272f704439e417f212932eed2004bsalomon        return;
2096a2b1941c1da272f704439e417f212932eed2004bsalomon    }
2107ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips    SkASSERT(proxy);
2116a2b1941c1da272f704439e417f212932eed2004bsalomon
2127ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips    if (proxy->priv().hasPendingIO()) {
2137ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        this->flush(proxy);
2146a2b1941c1da272f704439e417f212932eed2004bsalomon    }
2156a2b1941c1da272f704439e417f212932eed2004bsalomon
216eee4d6e4e8cc5c4c79f065abcc3ce609f71238f9Robert Phillips    if (!proxy->instantiate(fContext->resourceProvider())) {
2177ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        return;
2187ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips    }
2197ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips
220eee4d6e4e8cc5c4c79f065abcc3ce609f71238f9Robert Phillips    GrSurface* surface = proxy->priv().peekSurface();
221eee4d6e4e8cc5c4c79f065abcc3ce609f71238f9Robert Phillips
2227ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips    if (fContext->getGpu() && surface->asRenderTarget()) {
2237ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        fContext->getGpu()->resolveRenderTarget(surface->asRenderTarget());
2246a2b1941c1da272f704439e417f212932eed2004bsalomon    }
2256a2b1941c1da272f704439e417f212932eed2004bsalomon}
2266a2b1941c1da272f704439e417f212932eed2004bsalomon
227fe199b7d512a7cfc56deaaa134260e1d47a1e7e0Chris Daltonvoid GrDrawingManager::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
228fe199b7d512a7cfc56deaaa134260e1d47a1e7e0Chris Dalton    fOnFlushCBObjects.push_back(onFlushCBObject);
229eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips}
230eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
231941d1446e0247b3af5d607def3ae87ee66031381Robert Phillipssk_sp<GrRenderTargetOpList> GrDrawingManager::newRTOpList(GrRenderTargetProxy* rtp,
232941d1446e0247b3af5d607def3ae87ee66031381Robert Phillips                                                          bool managedOpList) {
2333dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    SkASSERT(fContext);
2343dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
2356cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips    // This is  a temporary fix for the partial-MDB world. In that world we're not reordering
2366cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips    // so ops that (in the single opList world) would've just glommed onto the end of the single
2376cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips    // opList but referred to a far earlier RT need to appear in their own opList.
2386cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips    if (!fOpLists.empty()) {
2396cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips        fOpLists.back()->makeClosed(*fContext->caps());
2403dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    }
2413dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
242f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips    sk_sp<GrRenderTargetOpList> opList(new GrRenderTargetOpList(rtp,
243f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips                                                                fContext->getGpu(),
2448185f59335e8055961ea63502e74c6a186e3a546Robert Phillips                                                                fContext->getAuditTrail()));
245f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips    SkASSERT(rtp->getLastOpList() == opList.get());
2463dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
247941d1446e0247b3af5d607def3ae87ee66031381Robert Phillips    if (managedOpList) {
248941d1446e0247b3af5d607def3ae87ee66031381Robert Phillips        fOpLists.push_back() = opList;
249941d1446e0247b3af5d607def3ae87ee66031381Robert Phillips    }
2503dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
251f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips    return opList;
2523dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips}
2533dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
254b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillipssk_sp<GrTextureOpList> GrDrawingManager::newTextureOpList(GrTextureProxy* textureProxy) {
25545580d3e3024c1536e8e1b2017b704805442b634Brian Osman    SkASSERT(fContext);
25645580d3e3024c1536e8e1b2017b704805442b634Brian Osman
2576cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips    // This is  a temporary fix for the partial-MDB world. In that world we're not reordering
2586cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips    // so ops that (in the single opList world) would've just glommed onto the end of the single
2596cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips    // opList but referred to a far earlier RT need to appear in their own opList.
2606cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips    if (!fOpLists.empty()) {
2616cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips        fOpLists.back()->makeClosed(*fContext->caps());
2626cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips    }
2636cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips
2645efd5ea4e146c47394d16c8b6f876264822a0beeRobert Phillips    sk_sp<GrTextureOpList> opList(new GrTextureOpList(fContext->resourceProvider(),
2655efd5ea4e146c47394d16c8b6f876264822a0beeRobert Phillips                                                      textureProxy,
2665efd5ea4e146c47394d16c8b6f876264822a0beeRobert Phillips                                                      fContext->getAuditTrail()));
26745580d3e3024c1536e8e1b2017b704805442b634Brian Osman
2686cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips    SkASSERT(textureProxy->getLastOpList() == opList.get());
2696cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips
2706cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips    fOpLists.push_back() = opList;
27145580d3e3024c1536e8e1b2017b704805442b634Brian Osman
272dc83b892a0ae431c5fe123a7e6873d63264bd64cRobert Phillips    return opList;
27345580d3e3024c1536e8e1b2017b704805442b634Brian Osman}
27445580d3e3024c1536e8e1b2017b704805442b634Brian Osman
27586e7626f080028edd58f4b326e0ba9fa83c4208ebrianosmanGrAtlasTextContext* GrDrawingManager::getAtlasTextContext() {
27686e7626f080028edd58f4b326e0ba9fa83c4208ebrianosman    if (!fAtlasTextContext) {
27786e7626f080028edd58f4b326e0ba9fa83c4208ebrianosman        fAtlasTextContext.reset(GrAtlasTextContext::Create());
27886e7626f080028edd58f4b326e0ba9fa83c4208ebrianosman    }
27986e7626f080028edd58f4b326e0ba9fa83c4208ebrianosman
28086e7626f080028edd58f4b326e0ba9fa83c4208ebrianosman    return fAtlasTextContext.get();
28186e7626f080028edd58f4b326e0ba9fa83c4208ebrianosman}
28286e7626f080028edd58f4b326e0ba9fa83c4208ebrianosman
283687378229aecefc0ab7e639181593774ec8a4290robertphillips/*
284687378229aecefc0ab7e639181593774ec8a4290robertphillips * This method finds a path renderer that can draw the specified path on
285687378229aecefc0ab7e639181593774ec8a4290robertphillips * the provided target.
286687378229aecefc0ab7e639181593774ec8a4290robertphillips * Due to its expense, the software path renderer has split out so it can
287687378229aecefc0ab7e639181593774ec8a4290robertphillips * can be individually allowed/disallowed via the "allowSW" boolean.
288687378229aecefc0ab7e639181593774ec8a4290robertphillips */
289687378229aecefc0ab7e639181593774ec8a4290robertphillipsGrPathRenderer* GrDrawingManager::getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
290687378229aecefc0ab7e639181593774ec8a4290robertphillips                                                  bool allowSW,
291687378229aecefc0ab7e639181593774ec8a4290robertphillips                                                  GrPathRendererChain::DrawType drawType,
292687378229aecefc0ab7e639181593774ec8a4290robertphillips                                                  GrPathRenderer::StencilSupport* stencilSupport) {
293687378229aecefc0ab7e639181593774ec8a4290robertphillips
294687378229aecefc0ab7e639181593774ec8a4290robertphillips    if (!fPathRendererChain) {
2956b2552f10983d1b6d33303e3e9965ae71944c1d5bsalomon        fPathRendererChain = new GrPathRendererChain(fContext, fOptionsForPathRendererChain);
296687378229aecefc0ab7e639181593774ec8a4290robertphillips    }
297687378229aecefc0ab7e639181593774ec8a4290robertphillips
298687378229aecefc0ab7e639181593774ec8a4290robertphillips    GrPathRenderer* pr = fPathRendererChain->getPathRenderer(args, drawType, stencilSupport);
299687378229aecefc0ab7e639181593774ec8a4290robertphillips    if (!pr && allowSW) {
300687378229aecefc0ab7e639181593774ec8a4290robertphillips        if (!fSoftwarePathRenderer) {
30139ef7fb885d7be648b9f0ecd027bc400d1213cecbsalomon            fSoftwarePathRenderer =
30232342f032e1dfd133040324f851f0365f9d4cb51Brian Osman                    new GrSoftwarePathRenderer(fContext->resourceProvider(),
30339ef7fb885d7be648b9f0ecd027bc400d1213cecbsalomon                                               fOptionsForPathRendererChain.fAllowPathMaskCaching);
304687378229aecefc0ab7e639181593774ec8a4290robertphillips        }
3050e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon        if (fSoftwarePathRenderer->canDrawPath(args)) {
3060e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon            pr = fSoftwarePathRenderer;
3070e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon        }
308687378229aecefc0ab7e639181593774ec8a4290robertphillips    }
309687378229aecefc0ab7e639181593774ec8a4290robertphillips
310687378229aecefc0ab7e639181593774ec8a4290robertphillips    return pr;
311687378229aecefc0ab7e639181593774ec8a4290robertphillips}
312687378229aecefc0ab7e639181593774ec8a4290robertphillips
3131105224f9701e57ec5ce0354d6a380b664f5c638Brian Osmansk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext(
3143743013f755d23c215d852af7d829c3cd74f34a2Robert Phillips                                                            sk_sp<GrSurfaceProxy> sProxy,
315c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                            sk_sp<SkColorSpace> colorSpace,
316941d1446e0247b3af5d607def3ae87ee66031381Robert Phillips                                                            const SkSurfaceProps* surfaceProps,
317941d1446e0247b3af5d607def3ae87ee66031381Robert Phillips                                                            bool managedOpList) {
3183743013f755d23c215d852af7d829c3cd74f34a2Robert Phillips    if (this->wasAbandoned() || !sProxy->asRenderTargetProxy()) {
3193dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips        return nullptr;
3203dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    }
3213dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
3220e22eb8e6efc7d7ab7a601ba555947916d139906brianosman    // SkSurface catches bad color space usage at creation. This check handles anything that slips
3230e22eb8e6efc7d7ab7a601ba555947916d139906brianosman    // by, including internal usage. We allow a null color space here, for read/write pixels and
3240e22eb8e6efc7d7ab7a601ba555947916d139906brianosman    // other special code paths. If a color space is provided, though, enforce all other rules.
3252c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    if (colorSpace && !SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) {
326a9c3c6aea5f7ade5aa2d112a221c458cd759222abrianosman        SkDEBUGFAIL("Invalid config and colorspace combination");
3270e22eb8e6efc7d7ab7a601ba555947916d139906brianosman        return nullptr;
3280e22eb8e6efc7d7ab7a601ba555947916d139906brianosman    }
32996880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt
3302c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    sk_sp<GrRenderTargetProxy> rtp(sk_ref_sp(sProxy->asRenderTargetProxy()));
3312c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips
33296880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt    bool useDIF = false;
33396880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt    if (surfaceProps) {
33496880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt        useDIF = surfaceProps->isUseDeviceIndependentFonts();
33596880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt    }
33696880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt
33796880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt    if (useDIF && fContext->caps()->shaderCaps()->pathRenderingSupport() &&
3387c8460e10135c05a42d0744b84838bbc24398ac2Brian Salomon        GrFSAAType::kNone != rtp->fsaaType()) {
339c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips        // TODO: defer stencil buffer attachment for PathRenderingDrawContext
340eee4d6e4e8cc5c4c79f065abcc3ce609f71238f9Robert Phillips        if (!rtp->instantiate(fContext->resourceProvider())) {
341e60ad620fe236ce4c1e85a31bd53ed0c848da8c3Robert Phillips            return nullptr;
342e60ad620fe236ce4c1e85a31bd53ed0c848da8c3Robert Phillips        }
343eee4d6e4e8cc5c4c79f065abcc3ce609f71238f9Robert Phillips        GrRenderTarget* rt = rtp->priv().peekRenderTarget();
344eee4d6e4e8cc5c4c79f065abcc3ce609f71238f9Robert Phillips
345eee4d6e4e8cc5c4c79f065abcc3ce609f71238f9Robert Phillips        GrStencilAttachment* sb = fContext->resourceProvider()->attachStencilAttachment(rt);
34696880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt        if (sb) {
3471105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman            return sk_sp<GrRenderTargetContext>(new GrPathRenderingRenderTargetContext(
348c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                        fContext, this, std::move(rtp),
349dfe4f2e4fe5b162d4adb4486fe751f1e3b30bea7brianosman                                                        std::move(colorSpace), surfaceProps,
3506c7e325236b7fbb9c9b14ebb4715f88a59718695robertphillips                                                        fContext->getAuditTrail(), fSingleOwner));
35196880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt        }
35296880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt    }
35396880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt
354c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    return sk_sp<GrRenderTargetContext>(new GrRenderTargetContext(fContext, this, std::move(rtp),
3551105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                  std::move(colorSpace),
3561105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                  surfaceProps,
3571105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                  fContext->getAuditTrail(),
358941d1446e0247b3af5d607def3ae87ee66031381Robert Phillips                                                                  fSingleOwner, managedOpList));
3593dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips}
36045580d3e3024c1536e8e1b2017b704805442b634Brian Osman
3612c86249465c28a532c8be55b6ba497021e3110ecRobert Phillipssk_sp<GrTextureContext> GrDrawingManager::makeTextureContext(sk_sp<GrSurfaceProxy> sProxy,
3622c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips                                                             sk_sp<SkColorSpace> colorSpace) {
36345580d3e3024c1536e8e1b2017b704805442b634Brian Osman    if (this->wasAbandoned() || !sProxy->asTextureProxy()) {
36445580d3e3024c1536e8e1b2017b704805442b634Brian Osman        return nullptr;
36545580d3e3024c1536e8e1b2017b704805442b634Brian Osman    }
36645580d3e3024c1536e8e1b2017b704805442b634Brian Osman
3672c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    // SkSurface catches bad color space usage at creation. This check handles anything that slips
3682c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    // by, including internal usage. We allow a null color space here, for read/write pixels and
3692c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    // other special code paths. If a color space is provided, though, enforce all other rules.
3702c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    if (colorSpace && !SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) {
3712c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips        SkDEBUGFAIL("Invalid config and colorspace combination");
3722c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips        return nullptr;
3732c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    }
3742c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips
37545580d3e3024c1536e8e1b2017b704805442b634Brian Osman    // GrTextureRenderTargets should always be using GrRenderTargetContext
37645580d3e3024c1536e8e1b2017b704805442b634Brian Osman    SkASSERT(!sProxy->asRenderTargetProxy());
37745580d3e3024c1536e8e1b2017b704805442b634Brian Osman
37845580d3e3024c1536e8e1b2017b704805442b634Brian Osman    sk_sp<GrTextureProxy> textureProxy(sk_ref_sp(sProxy->asTextureProxy()));
37945580d3e3024c1536e8e1b2017b704805442b634Brian Osman
38045580d3e3024c1536e8e1b2017b704805442b634Brian Osman    return sk_sp<GrTextureContext>(new GrTextureContext(fContext, this, std::move(textureProxy),
3812c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips                                                        std::move(colorSpace),
3822c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips                                                        fContext->getAuditTrail(),
3832c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips                                                        fSingleOwner));
38445580d3e3024c1536e8e1b2017b704805442b634Brian Osman}
385