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