blob: bfb586b8c1c9d2fd3d94f210e98349a714b7594e [file] [log] [blame]
robertphillips3dc6ae52015-10-20 09:54:32 -07001/*
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 "GrAtlasTextContext.h"
9#include "GrDrawContext.h"
10#include "GrDrawingManager.h"
11#include "GrDrawTarget.h"
12#include "GrResourceProvider.h"
robertphillips68737822015-10-29 12:12:21 -070013#include "GrSoftwarePathRenderer.h"
robertphillips3dc6ae52015-10-20 09:54:32 -070014#include "GrStencilAndCoverTextContext.h"
15#include "SkTTopoSort.h"
16
robertphillips498d7ac2015-10-30 10:11:30 -070017//#define ENABLE_MDB 1
18
robertphillips3dc6ae52015-10-20 09:54:32 -070019void GrDrawingManager::cleanup() {
20 for (int i = 0; i < fDrawTargets.count(); ++i) {
21 fDrawTargets[i]->unref();
22 }
23
24 fDrawTargets.reset();
25
26 delete fNVPRTextContext;
27 fNVPRTextContext = nullptr;
28
29 for (int i = 0; i < kNumPixelGeometries; ++i) {
30 delete fTextContexts[i][0];
31 fTextContexts[i][0] = nullptr;
32 delete fTextContexts[i][1];
33 fTextContexts[i][1] = nullptr;
34 }
robertphillips68737822015-10-29 12:12:21 -070035
robertphillips13391dd2015-10-30 05:15:11 -070036 delete fPathRendererChain;
37 fPathRendererChain = nullptr;
robertphillips68737822015-10-29 12:12:21 -070038 SkSafeSetNull(fSoftwarePathRenderer);
robertphillips3dc6ae52015-10-20 09:54:32 -070039}
40
41GrDrawingManager::~GrDrawingManager() {
42 this->cleanup();
43}
44
45void GrDrawingManager::abandon() {
46 fAbandoned = true;
47 this->cleanup();
48}
49
robertphillips68737822015-10-29 12:12:21 -070050void GrDrawingManager::freeGpuResources() {
51 // a path renderer may be holding onto resources
robertphillips13391dd2015-10-30 05:15:11 -070052 delete fPathRendererChain;
53 fPathRendererChain = nullptr;
robertphillips68737822015-10-29 12:12:21 -070054 SkSafeSetNull(fSoftwarePathRenderer);
55}
56
robertphillips3dc6ae52015-10-20 09:54:32 -070057void GrDrawingManager::reset() {
58 for (int i = 0; i < fDrawTargets.count(); ++i) {
59 fDrawTargets[i]->reset();
60 }
61}
62
63void GrDrawingManager::flush() {
64 SkDEBUGCODE(bool result =)
65 SkTTopoSort<GrDrawTarget, GrDrawTarget::TopoSortTraits>(&fDrawTargets);
66 SkASSERT(result);
67
68 for (int i = 0; i < fDrawTargets.count(); ++i) {
69 //SkDEBUGCODE(fDrawTargets[i]->dump();)
70 fDrawTargets[i]->flush();
71 }
72
73#ifndef ENABLE_MDB
74 // When MDB is disabled we keep reusing the same drawTarget
75 if (fDrawTargets.count()) {
76 SkASSERT(fDrawTargets.count() == 1);
77 fDrawTargets[0]->resetFlag(GrDrawTarget::kWasOutput_Flag);
78 }
79#endif
80}
81
82GrTextContext* GrDrawingManager::textContext(const SkSurfaceProps& props,
83 GrRenderTarget* rt) {
84 if (this->abandoned()) {
85 return nullptr;
86 }
87
88 SkASSERT(props.pixelGeometry() < kNumPixelGeometries);
89 bool useDIF = props.isUseDeviceIndependentFonts();
90
91 if (useDIF && fContext->caps()->shaderCaps()->pathRenderingSupport() &&
92 rt->isStencilBufferMultisampled()) {
93 GrStencilAttachment* sb = fContext->resourceProvider()->attachStencilAttachment(rt);
94 if (sb) {
95 if (!fNVPRTextContext) {
96 fNVPRTextContext = GrStencilAndCoverTextContext::Create(fContext, props);
97 }
98
99 return fNVPRTextContext;
100 }
101 }
102
103 if (!fTextContexts[props.pixelGeometry()][useDIF]) {
104 fTextContexts[props.pixelGeometry()][useDIF] = GrAtlasTextContext::Create(fContext, props);
105 }
106
107 return fTextContexts[props.pixelGeometry()][useDIF];
108}
109
110GrDrawTarget* GrDrawingManager::newDrawTarget(GrRenderTarget* rt) {
111 SkASSERT(fContext);
112
113#ifndef ENABLE_MDB
114 // When MDB is disabled we always just return the single drawTarget
115 if (fDrawTargets.count()) {
116 SkASSERT(fDrawTargets.count() == 1);
117 // DrawingManager gets the creation ref - this ref is for the caller
118 return SkRef(fDrawTargets[0]);
119 }
120#endif
121
robertphillips498d7ac2015-10-30 10:11:30 -0700122 GrDrawTarget* dt = new GrDrawTarget(rt, fContext->getGpu(), fContext->resourceProvider(),
bsalomon648c6962015-10-23 09:06:59 -0700123 fOptions);
robertphillips3dc6ae52015-10-20 09:54:32 -0700124
125 *fDrawTargets.append() = dt;
126
127 // DrawingManager gets the creation ref - this ref is for the caller
128 return SkRef(dt);
129}
130
robertphillips68737822015-10-29 12:12:21 -0700131/*
132 * This method finds a path renderer that can draw the specified path on
133 * the provided target.
134 * Due to its expense, the software path renderer has split out so it can
135 * can be individually allowed/disallowed via the "allowSW" boolean.
136 */
137GrPathRenderer* GrDrawingManager::getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args,
138 bool allowSW,
139 GrPathRendererChain::DrawType drawType,
140 GrPathRenderer::StencilSupport* stencilSupport) {
141
142 if (!fPathRendererChain) {
143 fPathRendererChain = new GrPathRendererChain(fContext);
144 }
145
146 GrPathRenderer* pr = fPathRendererChain->getPathRenderer(args, drawType, stencilSupport);
147 if (!pr && allowSW) {
148 if (!fSoftwarePathRenderer) {
149 fSoftwarePathRenderer = new GrSoftwarePathRenderer(fContext);
150 }
151 pr = fSoftwarePathRenderer;
152 }
153
154 return pr;
155}
156
157GrDrawContext* GrDrawingManager::drawContext(GrRenderTarget* rt,
robertphillips3dc6ae52015-10-20 09:54:32 -0700158 const SkSurfaceProps* surfaceProps) {
159 if (this->abandoned()) {
160 return nullptr;
161 }
162
163 return new GrDrawContext(this, rt, surfaceProps);
164}