GrDrawingManager.cpp revision e3302dfb81865051ad19cd1c91e2ec3a27df3417
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"
111105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman#include "GrRenderTargetContext.h"
121105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman#include "GrPathRenderingRenderTargetContext.h"
13c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips#include "GrRenderTargetProxy.h"
143dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips#include "GrResourceProvider.h"
15687378229aecefc0ab7e639181593774ec8a4290robertphillips#include "GrSoftwarePathRenderer.h"
166a2b1941c1da272f704439e417f212932eed2004bsalomon#include "GrSurfacePriv.h"
177ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips#include "GrSurfaceProxyPriv.h"
1845580d3e3024c1536e8e1b2017b704805442b634Brian Osman#include "GrTextureContext.h"
1945580d3e3024c1536e8e1b2017b704805442b634Brian Osman#include "GrTextureOpList.h"
200e22eb8e6efc7d7ab7a601ba555947916d139906brianosman#include "SkSurface_Gpu.h"
213dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips#include "SkTTopoSort.h"
223dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
23e804292e805917002cc3d7baa7f967fb20d2c7cbjoshualitt#include "text/GrAtlasTextContext.h"
24e804292e805917002cc3d7baa7f967fb20d2c7cbjoshualitt#include "text/GrStencilAndCoverTextContext.h"
25498d7ac86bfb45bdfc8f9aa7424f7236235987b5robertphillips
263dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillipsvoid GrDrawingManager::cleanup() {
27f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
28f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips        fOpLists[i]->makeClosed();  // no opList should receive a new command after this
297ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips        fOpLists[i]->clearTarget();
300dfa62c97707ac9b0fc0bdba7acfc8405db5c836robertphillips
31f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips        // We shouldn't need to do this, but it turns out some clients still hold onto opLists
327ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips        // after a cleanup
33f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips        fOpLists[i]->reset();
343dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    }
353dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
36f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    fOpLists.reset();
373dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
3813391dd97209f36c71bc18cc75084f74c2f6af15robertphillips    delete fPathRendererChain;
3913391dd97209f36c71bc18cc75084f74c2f6af15robertphillips    fPathRendererChain = nullptr;
40687378229aecefc0ab7e639181593774ec8a4290robertphillips    SkSafeSetNull(fSoftwarePathRenderer);
413dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips}
423dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
433dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillipsGrDrawingManager::~GrDrawingManager() {
443dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    this->cleanup();
453dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips}
463dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
473dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillipsvoid GrDrawingManager::abandon() {
483dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    fAbandoned = true;
49f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
50f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips        fOpLists[i]->abandonGpuResources();
51a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
523dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    this->cleanup();
533dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips}
543dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
55687378229aecefc0ab7e639181593774ec8a4290robertphillipsvoid GrDrawingManager::freeGpuResources() {
56687378229aecefc0ab7e639181593774ec8a4290robertphillips    // a path renderer may be holding onto resources
5713391dd97209f36c71bc18cc75084f74c2f6af15robertphillips    delete fPathRendererChain;
5813391dd97209f36c71bc18cc75084f74c2f6af15robertphillips    fPathRendererChain = nullptr;
59687378229aecefc0ab7e639181593774ec8a4290robertphillips    SkSafeSetNull(fSoftwarePathRenderer);
60f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
61f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips        fOpLists[i]->freeGpuResources();
62a7f29640f6ab4eb50962a9d9f12d01ac2ce8b471csmartdalton    }
63687378229aecefc0ab7e639181593774ec8a4290robertphillips}
64687378229aecefc0ab7e639181593774ec8a4290robertphillips
653dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillipsvoid GrDrawingManager::reset() {
66f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
67f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips        fOpLists[i]->reset();
683dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    }
69a13e202563979fd5076936606dcc1d660da8c632robertphillips    fFlushState.reset();
703dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips}
713dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
72e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillipsgr_instanced::OpAllocator* GrDrawingManager::instancingAllocator() {
73e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips    if (fInstancingAllocator) {
74e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips        return fInstancingAllocator.get();
75e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips    }
76e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips
77e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips    fInstancingAllocator = fContext->getGpu()->createInstancedRenderingAllocator();
78e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips    return fInstancingAllocator.get();
79e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips}
80e3302dfb81865051ad19cd1c91e2ec3a27df3417Robert Phillips
817ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips// MDB TODO: make use of the 'proxy' parameter.
827ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillipsvoid GrDrawingManager::internalFlush(GrSurfaceProxy*, GrResourceCache::FlushType type) {
837761d61876ea479dd9672b684fd5c7601932a767robertphillips    if (fFlushing || this->wasAbandoned()) {
84b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon        return;
85b8918c42b7a4a603e880f9db994f993ca0052ed2joshualitt    }
86b8918c42b7a4a603e880f9db994f993ca0052ed2joshualitt    fFlushing = true;
87dc43898bbbd06202562514ae785116e0cc40f825bsalomon    bool flushed = false;
88eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
89eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
90eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        // Semi-usually the GrOpLists are already closed at this point, but sometimes Ganesh
91eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        // needs to flush mid-draw. In that case, the SkGpuDevice's GrOpLists won't be closed
92eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        // but need to be flushed anyway. Closing such GrOpLists here will mean new
93eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        // GrOpLists will be created to replace them if the SkGpuDevice(s) write to them again.
94eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        fOpLists[i]->makeClosed();
95eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips    }
96eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
97f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips#ifdef ENABLE_MDB
989d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary    SkDEBUGCODE(bool result =)
99f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips                        SkTTopoSort<GrOpList, GrOpList::TopoSortTraits>(&fOpLists);
1003dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    SkASSERT(result);
101f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips#endif
1023dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
103eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips    GrPreFlushResourceProvider preFlushProvider(this);
104eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
105eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips    if (fPreFlushCBObjects.count()) {
106eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        // MDB TODO: pre-MDB '1' is the correct pre-allocated size. Post-MDB it will need
107eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        // to be larger.
108eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        SkAutoSTArray<1, uint32_t> opListIds(fOpLists.count());
109eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        for (int i = 0; i < fOpLists.count(); ++i) {
110eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips            opListIds[i] = fOpLists[i]->uniqueID();
111eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        }
112eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
113eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        SkSTArray<1, sk_sp<GrRenderTargetContext>> renderTargetContexts;
114eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        for (int i = 0; i < fPreFlushCBObjects.count(); ++i) {
115eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips            fPreFlushCBObjects[i]->preFlush(&preFlushProvider,
116eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                                            opListIds.get(), opListIds.count(),
117eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                                            &renderTargetContexts);
118eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips            if (!renderTargetContexts.count()) {
119eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                continue;       // This is fine. No atlases of this type are required for this flush
120eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips            }
121eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
122eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips            for (int j = 0; j < renderTargetContexts.count(); ++j) {
123eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                GrRenderTargetOpList* opList = renderTargetContexts[j]->getOpList();
124eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                if (!opList) {
125eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                    continue;   // Odd - but not a big deal
126eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                }
127eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                SkDEBUGCODE(opList->validateTargetsSingleRenderTarget());
128eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                opList->prepareOps(&fFlushState);
129eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                if (!opList->executeOps(&fFlushState)) {
130eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                    continue;         // This is bad
131eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips                }
132eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips            }
133eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips            renderTargetContexts.reset();
134eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips        }
135eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips    }
136eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
137f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
1381e41f4a111e5b19e55d688033e7b857caef658e6Brian Salomon        fOpLists[i]->prepareOps(&fFlushState);
13927fe1f849d2b6f96b49cc919df7d5f6d74598aa1robertphillips    }
14027fe1f849d2b6f96b49cc919df7d5f6d74598aa1robertphillips
141a13e202563979fd5076936606dcc1d660da8c632robertphillips#if 0
14209d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomon    // Enable this to print out verbose GrOp information
143f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
144f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips        SkDEBUGCODE(fOpLists[i]->dump();)
145a13e202563979fd5076936606dcc1d660da8c632robertphillips    }
146a13e202563979fd5076936606dcc1d660da8c632robertphillips#endif
147a13e202563979fd5076936606dcc1d660da8c632robertphillips
148a13e202563979fd5076936606dcc1d660da8c632robertphillips    // Upload all data to the GPU
149a13e202563979fd5076936606dcc1d660da8c632robertphillips    fFlushState.preIssueDraws();
150a13e202563979fd5076936606dcc1d660da8c632robertphillips
151f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
1521e41f4a111e5b19e55d688033e7b857caef658e6Brian Salomon        if (fOpLists[i]->executeOps(&fFlushState)) {
153dc43898bbbd06202562514ae785116e0cc40f825bsalomon            flushed = true;
154dc43898bbbd06202562514ae785116e0cc40f825bsalomon        }
155a13e202563979fd5076936606dcc1d660da8c632robertphillips    }
156a13e202563979fd5076936606dcc1d660da8c632robertphillips
157342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon    SkASSERT(fFlushState.nextDrawToken() == fFlushState.nextTokenToFlush());
158a13e202563979fd5076936606dcc1d660da8c632robertphillips
159f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    for (int i = 0; i < fOpLists.count(); ++i) {
160f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips        fOpLists[i]->reset();
1610dfa62c97707ac9b0fc0bdba7acfc8405db5c836robertphillips    }
1620dfa62c97707ac9b0fc0bdba7acfc8405db5c836robertphillips
1637ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips#ifndef ENABLE_MDB
1647ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips    // When MDB is disabled we keep reusing the same GrOpList
1657ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips    if (fOpLists.count()) {
1667ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips        SkASSERT(fOpLists.count() == 1);
1677ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips        // Clear out this flag so the topological sort's SkTTopoSort_CheckAllUnmarked check
1687ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips        // won't bark
1697ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips        fOpLists[0]->resetFlag(GrOpList::kWasOutput_Flag);
1707ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips    }
1717ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips#else
172f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    fOpLists.reset();
1737ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips#endif
174a13e202563979fd5076936606dcc1d660da8c632robertphillips
175a13e202563979fd5076936606dcc1d660da8c632robertphillips    fFlushState.reset();
176ee843b2ae4d75748d8bc323287f0c310fad548a7robertphillips    // We always have to notify the cache when it requested a flush so it can reset its state.
177ee843b2ae4d75748d8bc323287f0c310fad548a7robertphillips    if (flushed || type == GrResourceCache::FlushType::kCacheRequested) {
178b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon        fContext->getResourceCache()->notifyFlushOccurred(type);
179b77a907c2fb4402b7e70e9fff70eb71482354e67bsalomon    }
180b8918c42b7a4a603e880f9db994f993ca0052ed2joshualitt    fFlushing = false;
1813dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips}
1823dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
1837ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillipsvoid GrDrawingManager::prepareSurfaceForExternalIO(GrSurfaceProxy* proxy) {
1846a2b1941c1da272f704439e417f212932eed2004bsalomon    if (this->wasAbandoned()) {
1856a2b1941c1da272f704439e417f212932eed2004bsalomon        return;
1866a2b1941c1da272f704439e417f212932eed2004bsalomon    }
1877ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips    SkASSERT(proxy);
1886a2b1941c1da272f704439e417f212932eed2004bsalomon
1897ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips    if (proxy->priv().hasPendingIO()) {
1907ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        this->flush(proxy);
1916a2b1941c1da272f704439e417f212932eed2004bsalomon    }
1926a2b1941c1da272f704439e417f212932eed2004bsalomon
1937ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips    GrSurface* surface = proxy->instantiate(fContext->resourceProvider());
1947ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips    if (!surface) {
1957ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        return;
1967ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips    }
1977ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips
1987ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips    if (fContext->getGpu() && surface->asRenderTarget()) {
1997ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        fContext->getGpu()->resolveRenderTarget(surface->asRenderTarget());
2006a2b1941c1da272f704439e417f212932eed2004bsalomon    }
2016a2b1941c1da272f704439e417f212932eed2004bsalomon}
2026a2b1941c1da272f704439e417f212932eed2004bsalomon
203eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillipsvoid GrDrawingManager::addPreFlushCallbackObject(sk_sp<GrPreFlushCallbackObject> preFlushCBObject) {
204eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips    fPreFlushCBObjects.push_back(preFlushCBObject);
205eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips}
206eb35f4dfaa10b9d751abbc9a1406456eb3b1649dRobert Phillips
207dc83b892a0ae431c5fe123a7e6873d63264bd64cRobert Phillipssk_sp<GrRenderTargetOpList> GrDrawingManager::newRTOpList(sk_sp<GrRenderTargetProxy> rtp) {
2083dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    SkASSERT(fContext);
2093dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
2107ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips#ifndef ENABLE_MDB
2117ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips    // When MDB is disabled we always just return the single GrOpList
2127ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips    if (fOpLists.count()) {
2137ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips        SkASSERT(fOpLists.count() == 1);
2147ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips        // In the non-MDB-world the same GrOpList gets reused for multiple render targets.
2157ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips        // Update this pointer so all the asserts are happy
2167ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips        rtp->setLastOpList(fOpLists[0].get());
2177ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips        // DrawingManager gets the creation ref - this ref is for the caller
2187ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips
2197ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips        // TODO: although this is true right now it isn't cool
2207ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips        return sk_ref_sp((GrRenderTargetOpList*) fOpLists[0].get());
2213dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    }
2227ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips#endif
2233dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
224f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips    sk_sp<GrRenderTargetOpList> opList(new GrRenderTargetOpList(rtp,
225f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips                                                                fContext->getGpu(),
226f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips                                                                fContext->resourceProvider(),
227f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips                                                                fContext->getAuditTrail(),
228f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips                                                                fOptionsForOpLists));
229f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips    SkASSERT(rtp->getLastOpList() == opList.get());
2303dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
231f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips    fOpLists.push_back() = opList;
2323dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
233f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips    return opList;
2343dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips}
2353dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
236dc83b892a0ae431c5fe123a7e6873d63264bd64cRobert Phillipssk_sp<GrTextureOpList> GrDrawingManager::newTextureOpList(sk_sp<GrTextureProxy> textureProxy) {
23745580d3e3024c1536e8e1b2017b704805442b634Brian Osman    SkASSERT(fContext);
23845580d3e3024c1536e8e1b2017b704805442b634Brian Osman
2397ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips    sk_sp<GrTextureOpList> opList(new GrTextureOpList(std::move(textureProxy), fContext->getGpu(),
240dc83b892a0ae431c5fe123a7e6873d63264bd64cRobert Phillips                                                      fContext->getAuditTrail()));
24145580d3e3024c1536e8e1b2017b704805442b634Brian Osman
2427ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips#ifndef ENABLE_MDB
2437ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips    // When MDB is disabled we still create a new GrOpList, but don't store or ref it - we rely
2447ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips    // on the caller to immediately execute and free it.
2457ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips    return opList;
2467ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips#else
2477ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips    *fOpLists.append() = opList;
24845580d3e3024c1536e8e1b2017b704805442b634Brian Osman
2497ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips    // Drawing manager gets the creation ref - this ref is for the caller
250dc83b892a0ae431c5fe123a7e6873d63264bd64cRobert Phillips    return opList;
2517ce67db5643eb8ff1149c152ede1253d43e875d4Robert Phillips#endif
25245580d3e3024c1536e8e1b2017b704805442b634Brian Osman}
25345580d3e3024c1536e8e1b2017b704805442b634Brian Osman
25486e7626f080028edd58f4b326e0ba9fa83c4208ebrianosmanGrAtlasTextContext* GrDrawingManager::getAtlasTextContext() {
25586e7626f080028edd58f4b326e0ba9fa83c4208ebrianosman    if (!fAtlasTextContext) {
25686e7626f080028edd58f4b326e0ba9fa83c4208ebrianosman        fAtlasTextContext.reset(GrAtlasTextContext::Create());
25786e7626f080028edd58f4b326e0ba9fa83c4208ebrianosman    }
25886e7626f080028edd58f4b326e0ba9fa83c4208ebrianosman
25986e7626f080028edd58f4b326e0ba9fa83c4208ebrianosman    return fAtlasTextContext.get();
26086e7626f080028edd58f4b326e0ba9fa83c4208ebrianosman}
26186e7626f080028edd58f4b326e0ba9fa83c4208ebrianosman
262687378229aecefc0ab7e639181593774ec8a4290robertphillips/*
263687378229aecefc0ab7e639181593774ec8a4290robertphillips * This method finds a path renderer that can draw the specified path on
264687378229aecefc0ab7e639181593774ec8a4290robertphillips * the provided target.
265687378229aecefc0ab7e639181593774ec8a4290robertphillips * Due to its expense, the software path renderer has split out so it can
266687378229aecefc0ab7e639181593774ec8a4290robertphillips * can be individually allowed/disallowed via the "allowSW" boolean.
267687378229aecefc0ab7e639181593774ec8a4290robertphillips */
268687378229aecefc0ab7e639181593774ec8a4290robertphillipsGrPathRenderer* GrDrawingManager::getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
269687378229aecefc0ab7e639181593774ec8a4290robertphillips                                                  bool allowSW,
270687378229aecefc0ab7e639181593774ec8a4290robertphillips                                                  GrPathRendererChain::DrawType drawType,
271687378229aecefc0ab7e639181593774ec8a4290robertphillips                                                  GrPathRenderer::StencilSupport* stencilSupport) {
272687378229aecefc0ab7e639181593774ec8a4290robertphillips
273687378229aecefc0ab7e639181593774ec8a4290robertphillips    if (!fPathRendererChain) {
2746b2552f10983d1b6d33303e3e9965ae71944c1d5bsalomon        fPathRendererChain = new GrPathRendererChain(fContext, fOptionsForPathRendererChain);
275687378229aecefc0ab7e639181593774ec8a4290robertphillips    }
276687378229aecefc0ab7e639181593774ec8a4290robertphillips
277687378229aecefc0ab7e639181593774ec8a4290robertphillips    GrPathRenderer* pr = fPathRendererChain->getPathRenderer(args, drawType, stencilSupport);
278687378229aecefc0ab7e639181593774ec8a4290robertphillips    if (!pr && allowSW) {
279687378229aecefc0ab7e639181593774ec8a4290robertphillips        if (!fSoftwarePathRenderer) {
28039ef7fb885d7be648b9f0ecd027bc400d1213cecbsalomon            fSoftwarePathRenderer =
28132342f032e1dfd133040324f851f0365f9d4cb51Brian Osman                    new GrSoftwarePathRenderer(fContext->resourceProvider(),
28239ef7fb885d7be648b9f0ecd027bc400d1213cecbsalomon                                               fOptionsForPathRendererChain.fAllowPathMaskCaching);
283687378229aecefc0ab7e639181593774ec8a4290robertphillips        }
2840e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon        if (fSoftwarePathRenderer->canDrawPath(args)) {
2850e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon            pr = fSoftwarePathRenderer;
2860e8fc8b9e6a138cf4a66b421fb824679df717329Brian Salomon        }
287687378229aecefc0ab7e639181593774ec8a4290robertphillips    }
288687378229aecefc0ab7e639181593774ec8a4290robertphillips
289687378229aecefc0ab7e639181593774ec8a4290robertphillips    return pr;
290687378229aecefc0ab7e639181593774ec8a4290robertphillips}
291687378229aecefc0ab7e639181593774ec8a4290robertphillips
2921105224f9701e57ec5ce0354d6a380b664f5c638Brian Osmansk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext(
2933743013f755d23c215d852af7d829c3cd74f34a2Robert Phillips                                                            sk_sp<GrSurfaceProxy> sProxy,
294c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                            sk_sp<SkColorSpace> colorSpace,
295c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                            const SkSurfaceProps* surfaceProps) {
2963743013f755d23c215d852af7d829c3cd74f34a2Robert Phillips    if (this->wasAbandoned() || !sProxy->asRenderTargetProxy()) {
2973dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips        return nullptr;
2983dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips    }
2993dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips
3000e22eb8e6efc7d7ab7a601ba555947916d139906brianosman    // SkSurface catches bad color space usage at creation. This check handles anything that slips
3010e22eb8e6efc7d7ab7a601ba555947916d139906brianosman    // by, including internal usage. We allow a null color space here, for read/write pixels and
3020e22eb8e6efc7d7ab7a601ba555947916d139906brianosman    // other special code paths. If a color space is provided, though, enforce all other rules.
3032c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    if (colorSpace && !SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) {
304a9c3c6aea5f7ade5aa2d112a221c458cd759222abrianosman        SkDEBUGFAIL("Invalid config and colorspace combination");
3050e22eb8e6efc7d7ab7a601ba555947916d139906brianosman        return nullptr;
3060e22eb8e6efc7d7ab7a601ba555947916d139906brianosman    }
30796880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt
3082c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    sk_sp<GrRenderTargetProxy> rtp(sk_ref_sp(sProxy->asRenderTargetProxy()));
3092c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips
31096880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt    bool useDIF = false;
31196880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt    if (surfaceProps) {
31296880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt        useDIF = surfaceProps->isUseDeviceIndependentFonts();
31396880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt    }
31496880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt
31596880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt    if (useDIF && fContext->caps()->shaderCaps()->pathRenderingSupport() &&
316c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips        rtp->isStencilBufferMultisampled()) {
317c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips        // TODO: defer stencil buffer attachment for PathRenderingDrawContext
31832342f032e1dfd133040324f851f0365f9d4cb51Brian Osman        sk_sp<GrRenderTarget> rt(sk_ref_sp(rtp->instantiate(fContext->resourceProvider())));
319e60ad620fe236ce4c1e85a31bd53ed0c848da8c3Robert Phillips        if (!rt) {
320e60ad620fe236ce4c1e85a31bd53ed0c848da8c3Robert Phillips            return nullptr;
321e60ad620fe236ce4c1e85a31bd53ed0c848da8c3Robert Phillips        }
3226c7e325236b7fbb9c9b14ebb4715f88a59718695robertphillips        GrStencilAttachment* sb = fContext->resourceProvider()->attachStencilAttachment(rt.get());
32396880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt        if (sb) {
3241105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman            return sk_sp<GrRenderTargetContext>(new GrPathRenderingRenderTargetContext(
325c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips                                                        fContext, this, std::move(rtp),
326dfe4f2e4fe5b162d4adb4486fe751f1e3b30bea7brianosman                                                        std::move(colorSpace), surfaceProps,
3276c7e325236b7fbb9c9b14ebb4715f88a59718695robertphillips                                                        fContext->getAuditTrail(), fSingleOwner));
32896880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt        }
32996880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt    }
33096880d9e366d58e5960aa0ee6aa67260797679ebjoshualitt
331c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    return sk_sp<GrRenderTargetContext>(new GrRenderTargetContext(fContext, this, std::move(rtp),
3321105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                  std::move(colorSpace),
3331105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                  surfaceProps,
3341105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                  fContext->getAuditTrail(),
3351105224f9701e57ec5ce0354d6a380b664f5c638Brian Osman                                                                  fSingleOwner));
3363dc6ae55ca01025a0d723c87d42ed72f5a4ff6ecrobertphillips}
33745580d3e3024c1536e8e1b2017b704805442b634Brian Osman
3382c86249465c28a532c8be55b6ba497021e3110ecRobert Phillipssk_sp<GrTextureContext> GrDrawingManager::makeTextureContext(sk_sp<GrSurfaceProxy> sProxy,
3392c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips                                                             sk_sp<SkColorSpace> colorSpace) {
34045580d3e3024c1536e8e1b2017b704805442b634Brian Osman    if (this->wasAbandoned() || !sProxy->asTextureProxy()) {
34145580d3e3024c1536e8e1b2017b704805442b634Brian Osman        return nullptr;
34245580d3e3024c1536e8e1b2017b704805442b634Brian Osman    }
34345580d3e3024c1536e8e1b2017b704805442b634Brian Osman
3442c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    // SkSurface catches bad color space usage at creation. This check handles anything that slips
3452c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    // by, including internal usage. We allow a null color space here, for read/write pixels and
3462c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    // other special code paths. If a color space is provided, though, enforce all other rules.
3472c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    if (colorSpace && !SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) {
3482c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips        SkDEBUGFAIL("Invalid config and colorspace combination");
3492c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips        return nullptr;
3502c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips    }
3512c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips
35245580d3e3024c1536e8e1b2017b704805442b634Brian Osman    // GrTextureRenderTargets should always be using GrRenderTargetContext
35345580d3e3024c1536e8e1b2017b704805442b634Brian Osman    SkASSERT(!sProxy->asRenderTargetProxy());
35445580d3e3024c1536e8e1b2017b704805442b634Brian Osman
35545580d3e3024c1536e8e1b2017b704805442b634Brian Osman    sk_sp<GrTextureProxy> textureProxy(sk_ref_sp(sProxy->asTextureProxy()));
35645580d3e3024c1536e8e1b2017b704805442b634Brian Osman
35745580d3e3024c1536e8e1b2017b704805442b634Brian Osman    return sk_sp<GrTextureContext>(new GrTextureContext(fContext, this, std::move(textureProxy),
3582c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips                                                        std::move(colorSpace),
3592c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips                                                        fContext->getAuditTrail(),
3602c86249465c28a532c8be55b6ba497021e3110ecRobert Phillips                                                        fSingleOwner));
36145580d3e3024c1536e8e1b2017b704805442b634Brian Osman}
362