LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/gpu - GrDrawingManager.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 161 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2015 Google Inc.
       3             :  *
       4             :  * Use of this source code is governed by a BSD-style license that can be
       5             :  * found in the LICENSE file.
       6             :  */
       7             : 
       8             : #include "GrDrawingManager.h"
       9             : 
      10             : #include "GrContext.h"
      11             : #include "GrRenderTargetContext.h"
      12             : #include "GrPathRenderingRenderTargetContext.h"
      13             : #include "GrRenderTargetProxy.h"
      14             : #include "GrResourceProvider.h"
      15             : #include "GrSoftwarePathRenderer.h"
      16             : #include "GrSurfacePriv.h"
      17             : #include "GrSurfaceProxyPriv.h"
      18             : #include "GrTextureContext.h"
      19             : #include "GrTextureOpList.h"
      20             : #include "SkSurface_Gpu.h"
      21             : #include "SkTTopoSort.h"
      22             : 
      23             : #include "text/GrAtlasTextContext.h"
      24             : #include "text/GrStencilAndCoverTextContext.h"
      25             : 
      26           0 : void GrDrawingManager::cleanup() {
      27           0 :     for (int i = 0; i < fOpLists.count(); ++i) {
      28           0 :         fOpLists[i]->makeClosed();  // no opList should receive a new command after this
      29           0 :         fOpLists[i]->clearTarget();
      30             : 
      31             :         // We shouldn't need to do this, but it turns out some clients still hold onto opLists
      32             :         // after a cleanup
      33           0 :         fOpLists[i]->reset();
      34           0 :         fOpLists[i]->unref();
      35             :     }
      36             : 
      37           0 :     fOpLists.reset();
      38             : 
      39           0 :     delete fPathRendererChain;
      40           0 :     fPathRendererChain = nullptr;
      41           0 :     SkSafeSetNull(fSoftwarePathRenderer);
      42           0 : }
      43             : 
      44           0 : GrDrawingManager::~GrDrawingManager() {
      45           0 :     this->cleanup();
      46           0 : }
      47             : 
      48           0 : void GrDrawingManager::abandon() {
      49           0 :     fAbandoned = true;
      50           0 :     for (int i = 0; i < fOpLists.count(); ++i) {
      51           0 :         fOpLists[i]->abandonGpuResources();
      52             :     }
      53           0 :     this->cleanup();
      54           0 : }
      55             : 
      56           0 : void GrDrawingManager::freeGpuResources() {
      57             :     // a path renderer may be holding onto resources
      58           0 :     delete fPathRendererChain;
      59           0 :     fPathRendererChain = nullptr;
      60           0 :     SkSafeSetNull(fSoftwarePathRenderer);
      61           0 :     for (int i = 0; i < fOpLists.count(); ++i) {
      62           0 :         fOpLists[i]->freeGpuResources();
      63             :     }
      64           0 : }
      65             : 
      66           0 : void GrDrawingManager::reset() {
      67           0 :     for (int i = 0; i < fOpLists.count(); ++i) {
      68           0 :         fOpLists[i]->reset();
      69             :     }
      70           0 :     fFlushState.reset();
      71           0 : }
      72             : 
      73             : // MDB TODO: make use of the 'proxy' parameter.
      74           0 : void GrDrawingManager::internalFlush(GrSurfaceProxy*, GrResourceCache::FlushType type) {
      75           0 :     if (fFlushing || this->wasAbandoned()) {
      76           0 :         return;
      77             :     }
      78           0 :     fFlushing = true;
      79           0 :     bool flushed = false;
      80             : 
      81           0 :     for (int i = 0; i < fOpLists.count(); ++i) {
      82             :         // Semi-usually the GrOpLists are already closed at this point, but sometimes Ganesh
      83             :         // needs to flush mid-draw. In that case, the SkGpuDevice's GrOpLists won't be closed
      84             :         // but need to be flushed anyway. Closing such GrOpLists here will mean new
      85             :         // GrOpLists will be created to replace them if the SkGpuDevice(s) write to them again.
      86           0 :         fOpLists[i]->makeClosed();
      87             :     }
      88             : 
      89             :     SkDEBUGCODE(bool result =)
      90           0 :                         SkTTopoSort<GrOpList, GrOpList::TopoSortTraits>(&fOpLists);
      91           0 :     SkASSERT(result);
      92             : 
      93           0 :     GrPreFlushResourceProvider preFlushProvider(this);
      94             : 
      95           0 :     if (fPreFlushCBObjects.count()) {
      96             :         // MDB TODO: pre-MDB '1' is the correct pre-allocated size. Post-MDB it will need
      97             :         // to be larger.
      98           0 :         SkAutoSTArray<1, uint32_t> opListIds(fOpLists.count());
      99           0 :         for (int i = 0; i < fOpLists.count(); ++i) {
     100           0 :             opListIds[i] = fOpLists[i]->uniqueID();
     101             :         }
     102             : 
     103           0 :         SkSTArray<1, sk_sp<GrRenderTargetContext>> renderTargetContexts;
     104           0 :         for (int i = 0; i < fPreFlushCBObjects.count(); ++i) {
     105           0 :             fPreFlushCBObjects[i]->preFlush(&preFlushProvider,
     106           0 :                                             opListIds.get(), opListIds.count(),
     107           0 :                                             &renderTargetContexts);
     108           0 :             if (!renderTargetContexts.count()) {
     109           0 :                 continue;       // This is fine. No atlases of this type are required for this flush
     110             :             }
     111             : 
     112           0 :             for (int j = 0; j < renderTargetContexts.count(); ++j) {
     113           0 :                 GrRenderTargetOpList* opList = renderTargetContexts[j]->getOpList();
     114           0 :                 if (!opList) {
     115           0 :                     continue;   // Odd - but not a big deal
     116             :                 }
     117           0 :                 SkDEBUGCODE(opList->validateTargetsSingleRenderTarget());
     118           0 :                 opList->prepareOps(&fFlushState);
     119           0 :                 if (!opList->executeOps(&fFlushState)) {
     120           0 :                     continue;         // This is bad
     121             :                 }
     122             :             }
     123           0 :             renderTargetContexts.reset();
     124             :         }
     125             :     }
     126             : 
     127           0 :     for (int i = 0; i < fOpLists.count(); ++i) {
     128           0 :         fOpLists[i]->prepareOps(&fFlushState);
     129             :     }
     130             : 
     131             : #if 0
     132             :     // Enable this to print out verbose GrOp information
     133             :     for (int i = 0; i < fOpLists.count(); ++i) {
     134             :         SkDEBUGCODE(fOpLists[i]->dump();)
     135             :     }
     136             : #endif
     137             : 
     138             :     // Upload all data to the GPU
     139           0 :     fFlushState.preIssueDraws();
     140             : 
     141           0 :     for (int i = 0; i < fOpLists.count(); ++i) {
     142           0 :         if (fOpLists[i]->executeOps(&fFlushState)) {
     143           0 :             flushed = true;
     144             :         }
     145             :     }
     146             : 
     147           0 :     SkASSERT(fFlushState.nextDrawToken() == fFlushState.nextTokenToFlush());
     148             : 
     149           0 :     for (int i = 0; i < fOpLists.count(); ++i) {
     150           0 :         fOpLists[i]->reset();
     151             : #ifdef ENABLE_MDB
     152             :         fOpLists[i]->unref();
     153             : #endif
     154             :     }
     155             : 
     156             : #ifndef ENABLE_MDB
     157             :     // When MDB is disabled we keep reusing the same GrOpList
     158           0 :     if (fOpLists.count()) {
     159           0 :         SkASSERT(fOpLists.count() == 1);
     160             :         // Clear out this flag so the topological sort's SkTTopoSort_CheckAllUnmarked check
     161             :         // won't bark
     162           0 :         fOpLists[0]->resetFlag(GrOpList::kWasOutput_Flag);
     163             :     }
     164             : #else
     165             :     fOpLists.reset();
     166             : #endif
     167             : 
     168           0 :     fFlushState.reset();
     169             :     // We always have to notify the cache when it requested a flush so it can reset its state.
     170           0 :     if (flushed || type == GrResourceCache::FlushType::kCacheRequested) {
     171           0 :         fContext->getResourceCache()->notifyFlushOccurred(type);
     172             :     }
     173           0 :     fFlushing = false;
     174             : }
     175             : 
     176           0 : void GrDrawingManager::prepareSurfaceForExternalIO(GrSurfaceProxy* proxy) {
     177           0 :     if (this->wasAbandoned()) {
     178           0 :         return;
     179             :     }
     180           0 :     SkASSERT(proxy);
     181             : 
     182           0 :     if (proxy->priv().hasPendingIO()) {
     183           0 :         this->flush(proxy);
     184             :     }
     185             : 
     186           0 :     GrSurface* surface = proxy->instantiate(fContext->resourceProvider());
     187           0 :     if (!surface) {
     188           0 :         return;
     189             :     }
     190             : 
     191           0 :     if (fContext->getGpu() && surface->asRenderTarget()) {
     192           0 :         fContext->getGpu()->resolveRenderTarget(surface->asRenderTarget());
     193             :     }
     194             : }
     195             : 
     196           0 : void GrDrawingManager::addPreFlushCallbackObject(sk_sp<GrPreFlushCallbackObject> preFlushCBObject) {
     197           0 :     fPreFlushCBObjects.push_back(preFlushCBObject);
     198           0 : }
     199             : 
     200           0 : GrRenderTargetOpList* GrDrawingManager::newOpList(GrRenderTargetProxy* rtp) {
     201           0 :     SkASSERT(fContext);
     202             : 
     203             : #ifndef ENABLE_MDB
     204             :     // When MDB is disabled we always just return the single GrOpList
     205           0 :     if (fOpLists.count()) {
     206           0 :         SkASSERT(fOpLists.count() == 1);
     207             :         // In the non-MDB-world the same GrOpList gets reused for multiple render targets.
     208             :         // Update this pointer so all the asserts are happy
     209           0 :         rtp->setLastOpList(fOpLists[0]);
     210             :         // DrawingManager gets the creation ref - this ref is for the caller
     211             : 
     212             :         // TODO: although this is true right now it isn't cool
     213           0 :         return SkRef((GrRenderTargetOpList*) fOpLists[0]);
     214             :     }
     215             : #endif
     216             : 
     217             :     GrRenderTargetOpList* opList = new GrRenderTargetOpList(rtp,
     218           0 :                                                             fContext->getGpu(),
     219           0 :                                                             fContext->resourceProvider(),
     220           0 :                                                             fContext->getAuditTrail(),
     221           0 :                                                             fOptionsForOpLists);
     222             : 
     223           0 :     *fOpLists.append() = opList;
     224             : 
     225             :     // DrawingManager gets the creation ref - this ref is for the caller
     226           0 :     return SkRef(opList);
     227             : }
     228             : 
     229           0 : GrTextureOpList* GrDrawingManager::newOpList(GrTextureProxy* textureProxy) {
     230           0 :     SkASSERT(fContext);
     231             : 
     232           0 :     GrTextureOpList* opList = new GrTextureOpList(textureProxy, fContext->getGpu(),
     233           0 :                                                   fContext->getAuditTrail());
     234             : 
     235             : #ifndef ENABLE_MDB
     236             :     // When MDB is disabled we still create a new GrOpList, but don't store or ref it - we rely
     237             :     // on the caller to immediately execute and free it.
     238           0 :     return opList;
     239             : #else
     240             :     *fOpLists.append() = opList;
     241             : 
     242             :     // Drawing manager gets the creation ref - this ref is for the caller
     243             :     return SkRef(opList);
     244             : #endif
     245             : }
     246             : 
     247           0 : GrAtlasTextContext* GrDrawingManager::getAtlasTextContext() {
     248           0 :     if (!fAtlasTextContext) {
     249           0 :         fAtlasTextContext.reset(GrAtlasTextContext::Create());
     250             :     }
     251             : 
     252           0 :     return fAtlasTextContext.get();
     253             : }
     254             : 
     255             : /*
     256             :  * This method finds a path renderer that can draw the specified path on
     257             :  * the provided target.
     258             :  * Due to its expense, the software path renderer has split out so it can
     259             :  * can be individually allowed/disallowed via the "allowSW" boolean.
     260             :  */
     261           0 : GrPathRenderer* GrDrawingManager::getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
     262             :                                                   bool allowSW,
     263             :                                                   GrPathRendererChain::DrawType drawType,
     264             :                                                   GrPathRenderer::StencilSupport* stencilSupport) {
     265             : 
     266           0 :     if (!fPathRendererChain) {
     267           0 :         fPathRendererChain = new GrPathRendererChain(fContext, fOptionsForPathRendererChain);
     268             :     }
     269             : 
     270           0 :     GrPathRenderer* pr = fPathRendererChain->getPathRenderer(args, drawType, stencilSupport);
     271           0 :     if (!pr && allowSW) {
     272           0 :         if (!fSoftwarePathRenderer) {
     273           0 :             fSoftwarePathRenderer =
     274           0 :                     new GrSoftwarePathRenderer(fContext->resourceProvider(),
     275           0 :                                                fOptionsForPathRendererChain.fAllowPathMaskCaching);
     276             :         }
     277           0 :         if (fSoftwarePathRenderer->canDrawPath(args)) {
     278           0 :             pr = fSoftwarePathRenderer;
     279             :         }
     280             :     }
     281             : 
     282           0 :     return pr;
     283             : }
     284             : 
     285           0 : sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext(
     286             :                                                             sk_sp<GrSurfaceProxy> sProxy,
     287             :                                                             sk_sp<SkColorSpace> colorSpace,
     288             :                                                             const SkSurfaceProps* surfaceProps) {
     289           0 :     if (this->wasAbandoned() || !sProxy->asRenderTargetProxy()) {
     290           0 :         return nullptr;
     291             :     }
     292             : 
     293             :     // SkSurface catches bad color space usage at creation. This check handles anything that slips
     294             :     // by, including internal usage. We allow a null color space here, for read/write pixels and
     295             :     // other special code paths. If a color space is provided, though, enforce all other rules.
     296           0 :     if (colorSpace && !SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) {
     297           0 :         SkDEBUGFAIL("Invalid config and colorspace combination");
     298           0 :         return nullptr;
     299             :     }
     300             : 
     301           0 :     sk_sp<GrRenderTargetProxy> rtp(sk_ref_sp(sProxy->asRenderTargetProxy()));
     302             : 
     303           0 :     bool useDIF = false;
     304           0 :     if (surfaceProps) {
     305           0 :         useDIF = surfaceProps->isUseDeviceIndependentFonts();
     306             :     }
     307             : 
     308           0 :     if (useDIF && fContext->caps()->shaderCaps()->pathRenderingSupport() &&
     309           0 :         rtp->isStencilBufferMultisampled()) {
     310             :         // TODO: defer stencil buffer attachment for PathRenderingDrawContext
     311           0 :         sk_sp<GrRenderTarget> rt(sk_ref_sp(rtp->instantiate(fContext->resourceProvider())));
     312           0 :         if (!rt) {
     313           0 :             return nullptr;
     314             :         }
     315           0 :         GrStencilAttachment* sb = fContext->resourceProvider()->attachStencilAttachment(rt.get());
     316           0 :         if (sb) {
     317             :             return sk_sp<GrRenderTargetContext>(new GrPathRenderingRenderTargetContext(
     318           0 :                                                         fContext, this, std::move(rtp),
     319           0 :                                                         std::move(colorSpace), surfaceProps,
     320           0 :                                                         fContext->getAuditTrail(), fSingleOwner));
     321             :         }
     322             :     }
     323             : 
     324           0 :     return sk_sp<GrRenderTargetContext>(new GrRenderTargetContext(fContext, this, std::move(rtp),
     325           0 :                                                                   std::move(colorSpace),
     326             :                                                                   surfaceProps,
     327           0 :                                                                   fContext->getAuditTrail(),
     328           0 :                                                                   fSingleOwner));
     329             : }
     330             : 
     331           0 : sk_sp<GrTextureContext> GrDrawingManager::makeTextureContext(sk_sp<GrSurfaceProxy> sProxy,
     332             :                                                              sk_sp<SkColorSpace> colorSpace) {
     333           0 :     if (this->wasAbandoned() || !sProxy->asTextureProxy()) {
     334           0 :         return nullptr;
     335             :     }
     336             : 
     337             :     // SkSurface catches bad color space usage at creation. This check handles anything that slips
     338             :     // by, including internal usage. We allow a null color space here, for read/write pixels and
     339             :     // other special code paths. If a color space is provided, though, enforce all other rules.
     340           0 :     if (colorSpace && !SkSurface_Gpu::Valid(fContext, sProxy->config(), colorSpace.get())) {
     341           0 :         SkDEBUGFAIL("Invalid config and colorspace combination");
     342           0 :         return nullptr;
     343             :     }
     344             : 
     345             :     // GrTextureRenderTargets should always be using GrRenderTargetContext
     346           0 :     SkASSERT(!sProxy->asRenderTargetProxy());
     347             : 
     348           0 :     sk_sp<GrTextureProxy> textureProxy(sk_ref_sp(sProxy->asTextureProxy()));
     349             : 
     350           0 :     return sk_sp<GrTextureContext>(new GrTextureContext(fContext, this, std::move(textureProxy),
     351           0 :                                                         std::move(colorSpace),
     352           0 :                                                         fContext->getAuditTrail(),
     353           0 :                                                         fSingleOwner));
     354             : }

Generated by: LCOV version 1.13