Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: src/gpu/batches/GrTessellatingPathRenderer.cpp

Issue 1776003002: GrTessellator: abstract vertex allocation into caller (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: VertexBuffer -> VertexAllocator Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrTessellator.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrTessellatingPathRenderer.h" 8 #include "GrTessellatingPathRenderer.h"
9 9
10 #include "GrBatchFlushState.h" 10 #include "GrBatchFlushState.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 const SkData* data = vertexBuffer->getUniqueKey().getCustomData(); 52 const SkData* data = vertexBuffer->getUniqueKey().getCustomData();
53 SkASSERT(data); 53 SkASSERT(data);
54 const TessInfo* info = static_cast<const TessInfo*>(data->data()); 54 const TessInfo* info = static_cast<const TessInfo*>(data->data());
55 if (info->fTolerance == 0 || info->fTolerance < 3.0f * tol) { 55 if (info->fTolerance == 0 || info->fTolerance < 3.0f * tol) {
56 *actualCount = info->fCount; 56 *actualCount = info->fCount;
57 return true; 57 return true;
58 } 58 }
59 return false; 59 return false;
60 } 60 }
61 61
62 class StaticVertexAllocator : public GrTessellator::VertexAllocator {
63 public:
64 StaticVertexAllocator(SkAutoTUnref<GrVertexBuffer>& vertexBuffer,
65 GrResourceProvider* resourceProvider,
66 bool canMapVB)
67 : fVertexBuffer(vertexBuffer)
68 , fResourceProvider(resourceProvider)
69 , fCanMapVB(canMapVB)
70 , fVertices(nullptr) {
71 }
72 SkPoint* lock(int vertexCount) override {
73 size_t size = vertexCount * sizeof(SkPoint);
74 if (!fVertexBuffer.get() || fVertexBuffer->gpuMemorySize() < size) {
75 fVertexBuffer.reset(fResourceProvider->createVertexBuffer(
76 size, GrResourceProvider::kStatic_BufferUsage, 0));
77 }
78 if (!fVertexBuffer.get()) {
79 return nullptr;
80 }
81 if (fCanMapVB) {
82 fVertices = static_cast<SkPoint*>(fVertexBuffer->map());
83 } else {
84 fVertices = new SkPoint[vertexCount];
85 }
86 return fVertices;
87 }
88 void unlock(int actualCount) override {
89 if (fCanMapVB) {
90 fVertexBuffer->unmap();
91 } else {
92 fVertexBuffer->updateData(fVertices, actualCount * sizeof(SkPoint));
93 delete[] fVertices;
94 }
95 fVertices = nullptr;
96 }
97 private:
98 SkAutoTUnref<GrVertexBuffer>& fVertexBuffer;
99 GrResourceProvider* fResourceProvider;
100 bool fCanMapVB;
101 SkPoint* fVertices;
102 };
103
62 } // namespace 104 } // namespace
63 105
64 GrTessellatingPathRenderer::GrTessellatingPathRenderer() { 106 GrTessellatingPathRenderer::GrTessellatingPathRenderer() {
65 } 107 }
66 108
67 bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons t { 109 bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons t {
68 // This path renderer can draw all fill styles, all stroke styles except hai rlines, but does 110 // This path renderer can draw all fill styles, all stroke styles except hai rlines, but does
69 // not do antialiasing. It can do convex and concave paths, but we'll leave the convex ones to 111 // not do antialiasing. It can do convex and concave paths, but we'll leave the convex ones to
70 // simpler algorithms. 112 // simpler algorithms.
71 return !IsStrokeHairlineOrEquivalent(*args.fStroke, *args.fViewMatrix, nullp tr) && 113 return !IsStrokeHairlineOrEquivalent(*args.fStroke, *args.fViewMatrix, nullp tr) &&
(...skipping 24 matching lines...) Expand all
96 private: 138 private:
97 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { 139 void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
98 // Handle any color overrides 140 // Handle any color overrides
99 if (!overrides.readsColor()) { 141 if (!overrides.readsColor()) {
100 fColor = GrColor_ILLEGAL; 142 fColor = GrColor_ILLEGAL;
101 } 143 }
102 overrides.getOverrideColorIfSet(&fColor); 144 overrides.getOverrideColorIfSet(&fColor);
103 fPipelineInfo = overrides; 145 fPipelineInfo = overrides;
104 } 146 }
105 147
106 int tessellate(GrUniqueKey* key, 148 void draw(Target* target, const GrGeometryProcessor* gp) const {
107 GrResourceProvider* resourceProvider,
108 SkAutoTUnref<GrVertexBuffer>& vertexBuffer,
109 bool canMapVB) const {
110 SkPath path;
111 GrStrokeInfo stroke(fStroke);
112 if (stroke.isDashed()) {
113 if (!stroke.applyDashToPath(&path, &stroke, fPath)) {
114 return 0;
115 }
116 } else {
117 path = fPath;
118 }
119 if (!stroke.isFillStyle()) {
120 stroke.setResScale(SkScalarAbs(fViewMatrix.getMaxScale()));
121 if (!stroke.applyToPath(&path, path)) {
122 return 0;
123 }
124 stroke.setFillStyle();
125 }
126 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
127 SkRect pathBounds = path.getBounds();
128 SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, fViewMat rix, pathBounds);
129
130 bool isLinear;
131 int count = GrTessellator::PathToTriangles(path, tol, fClipBounds, resou rceProvider,
132 vertexBuffer, canMapVB, &isLi near);
133 if (!fPath.isVolatile()) {
134 TessInfo info;
135 info.fTolerance = isLinear ? 0 : tol;
136 info.fCount = count;
137 SkAutoTUnref<SkData> data(SkData::NewWithCopy(&info, sizeof(info)));
138 key->setCustomData(data.get());
139 resourceProvider->assignUniqueKeyToResource(*key, vertexBuffer.get() );
140 SkPathPriv::AddGenIDChangeListener(fPath, new PathInvalidator(*key)) ;
141 }
142 return count;
143 }
144
145 void onPrepareDraws(Target* target) const override {
146 // construct a cache key from the path's genID and the view matrix 149 // construct a cache key from the path's genID and the view matrix
147 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ; 150 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain() ;
148 GrUniqueKey key; 151 GrUniqueKey key;
149 int clipBoundsSize32 = 152 int clipBoundsSize32 =
150 fPath.isInverseFillType() ? sizeof(fClipBounds) / sizeof(uint32_t) : 0; 153 fPath.isInverseFillType() ? sizeof(fClipBounds) / sizeof(uint32_t) : 0;
151 int strokeDataSize32 = fStroke.computeUniqueKeyFragmentData32Cnt(); 154 int strokeDataSize32 = fStroke.computeUniqueKeyFragmentData32Cnt();
152 GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsSize32 + strok eDataSize32); 155 GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsSize32 + strok eDataSize32);
153 builder[0] = fPath.getGenerationID(); 156 builder[0] = fPath.getGenerationID();
154 builder[1] = fPath.getFillType(); 157 builder[1] = fPath.getFillType();
155 // For inverse fills, the tessellation is dependent on clip bounds. 158 // For inverse fills, the tessellation is dependent on clip bounds.
156 if (fPath.isInverseFillType()) { 159 if (fPath.isInverseFillType()) {
157 memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds)); 160 memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds));
158 } 161 }
159 fStroke.asUniqueKeyFragment(&builder[2 + clipBoundsSize32]); 162 fStroke.asUniqueKeyFragment(&builder[2 + clipBoundsSize32]);
160 builder.finish(); 163 builder.finish();
161 GrResourceProvider* rp = target->resourceProvider(); 164 GrResourceProvider* rp = target->resourceProvider();
162 SkAutoTUnref<GrVertexBuffer> vertexBuffer(rp->findAndRefTByUniqueKey<GrV ertexBuffer>(key)); 165 SkAutoTUnref<GrVertexBuffer> vertexBuffer(rp->findAndRefTByUniqueKey<GrV ertexBuffer>(key));
163 int actualCount; 166 int actualCount;
164 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance; 167 SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
165 SkScalar tol = GrPathUtils::scaleToleranceToSrc( 168 SkScalar tol = GrPathUtils::scaleToleranceToSrc(
166 screenSpaceTol, fViewMatrix, fPath.getBounds()); 169 screenSpaceTol, fViewMatrix, fPath.getBounds());
167 if (!cache_match(vertexBuffer.get(), tol, &actualCount)) { 170 if (cache_match(vertexBuffer.get(), tol, &actualCount)) {
168 bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFl ags(); 171 this->drawVertices(target, gp, vertexBuffer.get(), 0, actualCount);
169 actualCount = this->tessellate(&key, rp, vertexBuffer, canMapVB);
170 }
171
172 if (actualCount == 0) {
173 return; 172 return;
174 } 173 }
175 174
175 SkPath path;
176 GrStrokeInfo stroke(fStroke);
177 if (stroke.isDashed()) {
178 if (!stroke.applyDashToPath(&path, &stroke, fPath)) {
179 return;
180 }
181 } else {
182 path = fPath;
183 }
184 if (!stroke.isFillStyle()) {
185 stroke.setResScale(SkScalarAbs(fViewMatrix.getMaxScale()));
186 if (!stroke.applyToPath(&path, path)) {
187 return;
188 }
189 stroke.setFillStyle();
190 }
191 bool isLinear;
192 bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags( );
193 StaticVertexAllocator allocator(vertexBuffer, target->resourceProvider() , canMapVB);
194 int count = GrTessellator::PathToTriangles(path, tol, fClipBounds, &allo cator, &isLinear);
195 if (count == 0) {
196 return;
197 }
198 this->drawVertices(target, gp, vertexBuffer.get(), 0, count);
199 if (!fPath.isVolatile()) {
200 TessInfo info;
201 info.fTolerance = isLinear ? 0 : tol;
202 info.fCount = count;
203 SkAutoTUnref<SkData> data(SkData::NewWithCopy(&info, sizeof(info)));
204 key.setCustomData(data.get());
205 target->resourceProvider()->assignUniqueKeyToResource(key, vertexBuf fer.get());
206 SkPathPriv::AddGenIDChangeListener(fPath, new PathInvalidator(key));
207 }
208 }
209
210 void onPrepareDraws(Target* target) const override {
176 SkAutoTUnref<const GrGeometryProcessor> gp; 211 SkAutoTUnref<const GrGeometryProcessor> gp;
177 { 212 {
178 using namespace GrDefaultGeoProcFactory; 213 using namespace GrDefaultGeoProcFactory;
179 214
180 Color color(fColor); 215 Color color(fColor);
181 LocalCoords localCoords(fPipelineInfo.readsLocalCoords() ? 216 LocalCoords localCoords(fPipelineInfo.readsLocalCoords() ?
182 LocalCoords::kUsePosition_Type : 217 LocalCoords::kUsePosition_Type :
183 LocalCoords::kUnused_Type); 218 LocalCoords::kUnused_Type);
184 Coverage::Type coverageType; 219 Coverage::Type coverageType;
185 if (fPipelineInfo.readsCoverage()) { 220 if (fPipelineInfo.readsCoverage()) {
186 coverageType = Coverage::kSolid_Type; 221 coverageType = Coverage::kSolid_Type;
187 } else { 222 } else {
188 coverageType = Coverage::kNone_Type; 223 coverageType = Coverage::kNone_Type;
189 } 224 }
190 Coverage coverage(coverageType); 225 Coverage coverage(coverageType);
191 gp.reset(GrDefaultGeoProcFactory::Create(color, coverage, localCoord s, 226 gp.reset(GrDefaultGeoProcFactory::Create(color, coverage, localCoord s,
192 fViewMatrix)); 227 fViewMatrix));
193 } 228 }
229 this->draw(target, gp.get());
230 }
194 231
232 void drawVertices(Target* target, const GrGeometryProcessor* gp, const GrVer texBuffer* vb,
233 int firstVertex, int count) const {
195 target->initDraw(gp, this->pipeline()); 234 target->initDraw(gp, this->pipeline());
196 SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); 235 SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
197 236
198 GrPrimitiveType primitiveType = TESSELLATOR_WIREFRAME ? kLines_GrPrimiti veType 237 GrPrimitiveType primitiveType = TESSELLATOR_WIREFRAME ? kLines_GrPrimiti veType
199 : kTriangles_GrPri mitiveType; 238 : kTriangles_GrPri mitiveType;
200 GrVertices vertices; 239 GrVertices vertices;
201 vertices.init(primitiveType, vertexBuffer.get(), 0, actualCount); 240 vertices.init(primitiveType, vb, firstVertex, count);
202 target->draw(vertices); 241 target->draw(vertices);
203 } 242 }
204 243
205 bool onCombineIfPossible(GrBatch*, const GrCaps&) override { return false; } 244 bool onCombineIfPossible(GrBatch*, const GrCaps&) override { return false; }
206 245
207 TessellatingPathBatch(const GrColor& color, 246 TessellatingPathBatch(const GrColor& color,
208 const SkPath& path, 247 const SkPath& path,
209 const GrStrokeInfo& stroke, 248 const GrStrokeInfo& stroke,
210 const SkMatrix& viewMatrix, 249 const SkMatrix& viewMatrix,
211 const SkRect& clipBounds) 250 const SkRect& clipBounds)
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 bool result = viewMatrix.invert(&vmi); 324 bool result = viewMatrix.invert(&vmi);
286 if (!result) { 325 if (!result) {
287 SkFAIL("Cannot invert matrix\n"); 326 SkFAIL("Cannot invert matrix\n");
288 } 327 }
289 vmi.mapRect(&clipBounds); 328 vmi.mapRect(&clipBounds);
290 GrStrokeInfo strokeInfo = GrTest::TestStrokeInfo(random); 329 GrStrokeInfo strokeInfo = GrTest::TestStrokeInfo(random);
291 return TessellatingPathBatch::Create(color, path, strokeInfo, viewMatrix, cl ipBounds); 330 return TessellatingPathBatch::Create(color, path, strokeInfo, viewMatrix, cl ipBounds);
292 } 331 }
293 332
294 #endif 333 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrTessellator.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698