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

Side by Side Diff: src/gpu/GrDefaultPathRenderer.cpp

Issue 884013010: Default path renderer batch (Closed) Base URL: https://skia.googlesource.com/skia.git@strokerect
Patch Set: windows warnings Created 5 years, 10 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/GrAARectRenderer.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 2011 Google Inc. 2 * Copyright 2011 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 "GrDefaultPathRenderer.h" 8 #include "GrDefaultPathRenderer.h"
9 9
10 #include "GrBatch.h"
11 #include "GrBatchTarget.h"
12 #include "GrBufferAllocPool.h"
10 #include "GrContext.h" 13 #include "GrContext.h"
11 #include "GrDefaultGeoProcFactory.h" 14 #include "GrDefaultGeoProcFactory.h"
12 #include "GrPathUtils.h" 15 #include "GrPathUtils.h"
13 #include "GrPipelineBuilder.h" 16 #include "GrPipelineBuilder.h"
14 #include "SkGeometry.h" 17 #include "SkGeometry.h"
15 #include "SkString.h" 18 #include "SkString.h"
16 #include "SkStrokeRec.h" 19 #include "SkStrokeRec.h"
17 #include "SkTLazy.h" 20 #include "SkTLazy.h"
18 #include "SkTraceEvent.h" 21 #include "SkTraceEvent.h"
19 22
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 // drawing triangle fans around fanCenterIdx. 187 // drawing triangle fans around fanCenterIdx.
185 if (!hairLine) { 188 if (!hairLine) {
186 *((*indices)++) = fanCenterIdx; 189 *((*indices)++) = fanCenterIdx;
187 } 190 }
188 *((*indices)++) = edgeV0Idx; 191 *((*indices)++) = edgeV0Idx;
189 *((*indices)++) = edgeV0Idx + 1; 192 *((*indices)++) = edgeV0Idx + 1;
190 } 193 }
191 194
192 static inline void add_quad(SkPoint** vert, const SkPoint* base, const SkPoint p ts[], 195 static inline void add_quad(SkPoint** vert, const SkPoint* base, const SkPoint p ts[],
193 SkScalar srcSpaceTolSqd, SkScalar srcSpaceTol, bool indexed, 196 SkScalar srcSpaceTolSqd, SkScalar srcSpaceTol, bool indexed,
194 bool isHairline, uint16_t subpathIdxStart, uint16_t* * idx) { 197 bool isHairline, uint16_t subpathIdxStart, int offse t, uint16_t** idx) {
195 // first pt of quad is the pt we ended on in previous step 198 // first pt of quad is the pt we ended on in previous step
196 uint16_t firstQPtIdx = (uint16_t)(*vert - base) - 1; 199 uint16_t firstQPtIdx = (uint16_t)(*vert - base) - 1 + offset;
197 uint16_t numPts = (uint16_t) 200 uint16_t numPts = (uint16_t)
198 GrPathUtils::generateQuadraticPoints( 201 GrPathUtils::generateQuadraticPoints(
199 pts[0], pts[1], pts[2], 202 pts[0], pts[1], pts[2],
200 srcSpaceTolSqd, vert, 203 srcSpaceTolSqd, vert,
201 GrPathUtils::quadraticPointCount(pts, srcSpaceTol)); 204 GrPathUtils::quadraticPointCount(pts, srcSpaceTol));
202 if (indexed) { 205 if (indexed) {
203 for (uint16_t i = 0; i < numPts; ++i) { 206 for (uint16_t i = 0; i < numPts; ++i) {
204 append_countour_edge_indices(isHairline, subpathIdxStart, 207 append_countour_edge_indices(isHairline, subpathIdxStart,
205 firstQPtIdx + i, idx); 208 firstQPtIdx + i, idx);
206 } 209 }
207 } 210 }
208 } 211 }
209 212
210 bool GrDefaultPathRenderer::createGeom(GrDrawTarget* target, 213 class DefaultPathBatch : public GrBatch {
211 GrPipelineBuilder* pipelineBuilder, 214 public:
212 GrPrimitiveType* primType, 215 struct Geometry {
213 int* vertexCnt, 216 GrColor fColor;
214 int* indexCnt, 217 SkPath fPath;
215 GrDrawTarget::AutoReleaseGeometry* arg, 218 SkScalar fTolerance;
216 const SkPath& path, 219 SkDEBUGCODE(SkRect fDevBounds;)
217 const SkStrokeRec& stroke, 220 };
218 SkScalar srcSpaceTol) { 221
219 { 222 static GrBatch* Create(const Geometry& geometry, uint8_t coverage, const SkM atrix& viewMatrix,
220 SkScalar srcSpaceTolSqd = SkScalarMul(srcSpaceTol, srcSpaceTol); 223 bool isHairline) {
221 int contourCnt; 224 return SkNEW_ARGS(DefaultPathBatch, (geometry, coverage, viewMatrix, isH airline));
222 int maxPts = GrPathUtils::worstCasePointCount(path, &contourCnt, 225 }
223 srcSpaceTol); 226
224 227 const char* name() const SK_OVERRIDE { return "DefaultPathBatch"; }
225 if (maxPts <= 0) { 228
226 return false; 229 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE {
227 } 230 // When this is called on a batch, there is only one geometry bundle
228 if (maxPts > ((int)SK_MaxU16 + 1)) { 231 out->setKnownFourComponents(fGeoData[0].fColor);
229 SkDebugf("Path not rendered, too many verts (%d)\n", maxPts); 232 }
230 return false; 233 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRID E {
231 } 234 out->setUnknownSingleComponent();
232 235 }
233 bool indexed = contourCnt > 1; 236
234 237 void initBatchTracker(const GrPipelineInfo& init) SK_OVERRIDE {
235 const bool isHairline = stroke.isHairlineStyle(); 238 // Handle any color overrides
236 239 if (init.fColorIgnored) {
237 int maxIdxs = 0; 240 fGeoData[0].fColor = GrColor_ILLEGAL;
238 if (isHairline) { 241 } else if (GrColor_ILLEGAL != init.fOverrideColor) {
239 if (indexed) { 242 fGeoData[0].fColor = init.fOverrideColor;
240 maxIdxs = 2 * maxPts; 243 }
241 *primType = kLines_GrPrimitiveType; 244
245 // setup batch properties
246 fBatch.fColorIgnored = init.fColorIgnored;
247 fBatch.fColor = fGeoData[0].fColor;
248 fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
249 fBatch.fCoverageIgnored = init.fCoverageIgnored;
250 }
251
252 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline ) SK_OVERRIDE {
253 SkAutoTUnref<const GrGeometryProcessor> gp(
254 GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPositi on_GPType,
255 this->color(),
256 this->viewMatrix(),
257 SkMatrix::I(),
258 false,
259 this->coverage()));
260
261 size_t vertexStride = gp->getVertexStride();
262 SkASSERT(vertexStride == sizeof(SkPoint));
263
264 batchTarget->initDraw(gp, pipeline);
265
266 // TODO this is hacky, but the only way we have to initialize the GP is to use the
267 // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch
268 // everywhere we can remove this nastiness
269 GrPipelineInfo init;
270 init.fColorIgnored = fBatch.fColorIgnored;
271 init.fOverrideColor = GrColor_ILLEGAL;
272 init.fCoverageIgnored = fBatch.fCoverageIgnored;
273 init.fUsesLocalCoords = this->usesLocalCoords();
274 gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
275
276 int instanceCount = fGeoData.count();
277
278 // compute number of vertices
279 int maxVertices = 0;
280
281 // We will use index buffers if we have multiple paths or one path with multiple contours
282 bool isIndexed = instanceCount > 1;
283 for (int i = 0; i < instanceCount; i++) {
284 Geometry& args = fGeoData[i];
285
286 int contourCount;
287 maxVertices += GrPathUtils::worstCasePointCount(args.fPath, &contour Count,
288 args.fTolerance);
289
290 isIndexed = isIndexed || contourCount > 1;
291 }
292
293 // determine primitiveType
294 int maxIndices = 0;
295 GrPrimitiveType primitiveType;
296 if (this->isHairline()) {
297 if (isIndexed) {
298 maxIndices = 2 * maxVertices;
299 primitiveType = kLines_GrPrimitiveType;
300 } else {
301 primitiveType = kLineStrip_GrPrimitiveType;
302 }
242 } else { 303 } else {
243 *primType = kLineStrip_GrPrimitiveType; 304 if (isIndexed) {
244 } 305 maxIndices = 3 * maxVertices;
245 } else { 306 primitiveType = kTriangles_GrPrimitiveType;
246 if (indexed) { 307 } else {
247 maxIdxs = 3 * maxPts; 308 primitiveType = kTriangleFan_GrPrimitiveType;
248 *primType = kTriangles_GrPrimitiveType; 309 }
310 }
311
312 // allocate vertex / index buffers
313 const GrVertexBuffer* vertexBuffer;
314 int firstVertex;
315
316 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
317 maxVertices,
318 &vertexBuffer,
319 &firstVertex);
320
321 const GrIndexBuffer* indexBuffer;
322 int firstIndex;
323
324 void* indices = NULL;
325 if (isIndexed) {
326 indices = batchTarget->indexPool()->makeSpace(maxIndices,
327 &indexBuffer,
328 &firstIndex);
329 }
330
331 // fill buffers
332 int vertexOffset = 0;
333 int indexOffset = 0;
334 for (int i = 0; i < instanceCount; i++) {
335 Geometry& args = fGeoData[i];
336
337 int vertexCnt = 0;
338 int indexCnt = 0;
339 if (!this->createGeom(vertices,
340 vertexOffset,
341 indices,
342 indexOffset,
343 &vertexCnt,
344 &indexCnt,
345 args.fPath,
346 args.fTolerance,
347 isIndexed)) {
348 return;
349 }
350
351 vertexOffset += vertexCnt;
352 indexOffset += indexCnt;
353 SkASSERT(vertexOffset <= maxVertices && indexOffset <= maxIndices);
354 }
355
356 GrDrawTarget::DrawInfo drawInfo;
357 drawInfo.setPrimitiveType(primitiveType);
358 drawInfo.setVertexBuffer(vertexBuffer);
359 drawInfo.setStartVertex(firstVertex);
360 drawInfo.setVertexCount(vertexOffset);
361 if (isIndexed) {
362 drawInfo.setIndexBuffer(indexBuffer);
363 drawInfo.setStartIndex(firstIndex);
364 drawInfo.setIndexCount(indexOffset);
249 } else { 365 } else {
250 *primType = kTriangleFan_GrPrimitiveType; 366 drawInfo.setStartIndex(0);
251 } 367 drawInfo.setIndexCount(0);
252 } 368 }
253 369 batchTarget->draw(drawInfo);
254 if (!arg->set(target, maxPts, GrDefaultGeoProcFactory::DefaultVertexStride() , maxIdxs)) { 370 }
255 return false; 371
256 } 372 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
257 SkASSERT(GrDefaultGeoProcFactory::DefaultVertexStride() == sizeof(SkPoint)); 373
258 374 private:
259 uint16_t* idxBase = reinterpret_cast<uint16_t*>(arg->indices()); 375 DefaultPathBatch(const Geometry& geometry, uint8_t coverage, const SkMatrix& viewMatrix,
260 uint16_t* idx = idxBase; 376 bool isHairline) {
261 uint16_t subpathIdxStart = 0; 377 this->initClassID<DefaultPathBatch>();
262 378 fBatch.fCoverage = coverage;
263 SkPoint* base = reinterpret_cast<SkPoint*>(arg->vertices()); 379 fBatch.fIsHairline = isHairline;
264 SkASSERT(base); 380 fBatch.fViewMatrix = viewMatrix;
265 SkPoint* vert = base; 381 fGeoData.push_back(geometry);
266 382 }
267 SkPoint pts[4]; 383
268 384 bool onCombineIfPossible(GrBatch* t) SK_OVERRIDE {
269 bool first = true; 385 DefaultPathBatch* that = t->cast<DefaultPathBatch>();
270 int subpath = 0; 386
271 387 if (this->color() != that->color()) {
272 SkPath::Iter iter(path, false); 388 return false;
273 389 }
274 for (;;) { 390
275 SkPath::Verb verb = iter.next(pts); 391 if (this->coverage() != that->coverage()) {
276 switch (verb) { 392 return false;
277 case SkPath::kMove_Verb: 393 }
278 if (!first) { 394
279 uint16_t currIdx = (uint16_t) (vert - base); 395 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
280 subpathIdxStart = currIdx; 396 return false;
281 ++subpath; 397 }
398
399 if (this->isHairline() != that->isHairline()) {
400 return false;
401 }
402
403 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ;
404 return true;
405 }
406
407 bool createGeom(void* vertices,
408 size_t vertexOffset,
409 void* indices,
410 size_t indexOffset,
411 int* vertexCnt,
412 int* indexCnt,
413 const SkPath& path,
414 SkScalar srcSpaceTol,
415 bool isIndexed) {
416 {
417 SkScalar srcSpaceTolSqd = SkScalarMul(srcSpaceTol, srcSpaceTol);
418
419 uint16_t indexOffsetU16 = (uint16_t)indexOffset;
420 uint16_t vertexOffsetU16 = (uint16_t)vertexOffset;
421
422 uint16_t* idxBase = reinterpret_cast<uint16_t*>(indices) + indexOffs etU16;
423 uint16_t* idx = idxBase;
424 uint16_t subpathIdxStart = vertexOffsetU16;
425
426 SkPoint* base = reinterpret_cast<SkPoint*>(vertices) + vertexOffset;
427 SkPoint* vert = base;
428
429 SkPoint pts[4];
430
431 bool first = true;
432 int subpath = 0;
433
434 SkPath::Iter iter(path, false);
435
436 bool done = false;
437 while (!done) {
438 SkPath::Verb verb = iter.next(pts);
439 switch (verb) {
440 case SkPath::kMove_Verb:
441 if (!first) {
442 uint16_t currIdx = (uint16_t) (vert - base) + vertex OffsetU16;
443 subpathIdxStart = currIdx;
444 ++subpath;
445 }
446 *vert = pts[0];
447 vert++;
448 break;
449 case SkPath::kLine_Verb:
450 if (isIndexed) {
451 uint16_t prevIdx = (uint16_t)(vert - base) - 1 + ver texOffsetU16;
452 append_countour_edge_indices(this->isHairline(), sub pathIdxStart,
453 prevIdx, &idx);
454 }
455 *(vert++) = pts[1];
456 break;
457 case SkPath::kConic_Verb: {
458 SkScalar weight = iter.conicWeight();
459 SkAutoConicToQuads converter;
460 // Converting in src-space, hance the finer tolerance (0 .25)
461 // TODO: find a way to do this in dev-space so the toler ance means something
462 const SkPoint* quadPts = converter.computeQuads(pts, wei ght, 0.25f);
463 for (int i = 0; i < converter.countQuads(); ++i) {
464 add_quad(&vert, base, quadPts + i*2, srcSpaceTolSqd, srcSpaceTol,
465 isIndexed, this->isHairline(), subpathIdxSt art,
466 (int)vertexOffset, &idx);
467 }
468 break;
469 }
470 case SkPath::kQuad_Verb:
471 add_quad(&vert, base, pts, srcSpaceTolSqd, srcSpaceTol, isIndexed,
472 this->isHairline(), subpathIdxStart, (int)verte xOffset, &idx);
473 break;
474 case SkPath::kCubic_Verb: {
475 // first pt of cubic is the pt we ended on in previous s tep
476 uint16_t firstCPtIdx = (uint16_t)(vert - base) - 1 + ver texOffsetU16;
477 uint16_t numPts = (uint16_t) GrPathUtils::generateCubicP oints(
478 pts[0], pts[1], pts[2], pts[3],
479 srcSpaceTolSqd, &vert,
480 GrPathUtils::cubicPointCount(pts, srcSpa ceTol));
481 if (isIndexed) {
482 for (uint16_t i = 0; i < numPts; ++i) {
483 append_countour_edge_indices(this->isHairline(), subpathIdxStart,
484 firstCPtIdx + i, &i dx);
485 }
486 }
487 break;
488 }
489 case SkPath::kClose_Verb:
490 break;
491 case SkPath::kDone_Verb:
492 done = true;
282 } 493 }
283 *vert = pts[0]; 494 first = false;
284 vert++;
285 break;
286 case SkPath::kLine_Verb:
287 if (indexed) {
288 uint16_t prevIdx = (uint16_t)(vert - base) - 1;
289 append_countour_edge_indices(isHairline, subpathIdxStart,
290 prevIdx, &idx);
291 }
292 *(vert++) = pts[1];
293 break;
294 case SkPath::kConic_Verb: {
295 SkScalar weight = iter.conicWeight();
296 SkAutoConicToQuads converter;
297 // Converting in src-space, hance the finer tolerance (0.25)
298 // TODO: find a way to do this in dev-space so the tolerance mea ns something
299 const SkPoint* quadPts = converter.computeQuads(pts, weight, 0.2 5f);
300 for (int i = 0; i < converter.countQuads(); ++i) {
301 add_quad(&vert, base, quadPts + i*2, srcSpaceTolSqd, srcSpac eTol, indexed,
302 isHairline, subpathIdxStart, &idx);
303 }
304 break;
305 } 495 }
306 case SkPath::kQuad_Verb: 496
307 add_quad(&vert, base, pts, srcSpaceTolSqd, srcSpaceTol, indexed, 497 *vertexCnt = static_cast<int>(vert - base);
308 isHairline, subpathIdxStart, &idx); 498 *indexCnt = static_cast<int>(idx - idxBase);
309 break; 499
310 case SkPath::kCubic_Verb: { 500 }
311 // first pt of cubic is the pt we ended on in previous step 501 return true;
312 uint16_t firstCPtIdx = (uint16_t)(vert - base) - 1; 502 }
313 uint16_t numPts = (uint16_t) GrPathUtils::generateCubicPoints( 503
314 pts[0], pts[1], pts[2], pts[3], 504 GrColor color() const { return fBatch.fColor; }
315 srcSpaceTolSqd, &vert, 505 uint8_t coverage() const { return fBatch.fCoverage; }
316 GrPathUtils::cubicPointCount(pts, srcSpaceTol)); 506 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
317 if (indexed) { 507 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; }
318 for (uint16_t i = 0; i < numPts; ++i) { 508 bool isHairline() const { return fBatch.fIsHairline; }
319 append_countour_edge_indices(isHairline, subpathIdxStart , 509
320 firstCPtIdx + i, &idx); 510 struct BatchTracker {
321 } 511 GrColor fColor;
322 } 512 uint8_t fCoverage;
323 break; 513 SkMatrix fViewMatrix;
324 } 514 bool fUsesLocalCoords;
325 case SkPath::kClose_Verb: 515 bool fColorIgnored;
326 break; 516 bool fCoverageIgnored;
327 case SkPath::kDone_Verb: 517 bool fIsHairline;
328 // uint16_t currIdx = (uint16_t) (vert - base); 518 };
329 goto FINISHED; 519
330 } 520 BatchTracker fBatch;
331 first = false; 521 SkSTArray<1, Geometry, true> fGeoData;
332 } 522 };
333 FINISHED:
334 SkASSERT((vert - base) <= maxPts);
335 SkASSERT((idx - idxBase) <= maxIdxs);
336
337 *vertexCnt = static_cast<int>(vert - base);
338 *indexCnt = static_cast<int>(idx - idxBase);
339
340 }
341 return true;
342 }
343 523
344 bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target, 524 bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
345 GrPipelineBuilder* pipelineBuilder, 525 GrPipelineBuilder* pipelineBuilder,
346 GrColor color, 526 GrColor color,
347 const SkMatrix& viewMatrix, 527 const SkMatrix& viewMatrix,
348 const SkPath& path, 528 const SkPath& path,
349 const SkStrokeRec& origStroke, 529 const SkStrokeRec& origStroke,
350 bool stencilOnly) { 530 bool stencilOnly) {
351 SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke); 531 SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke);
352 532
353 SkScalar hairlineCoverage; 533 SkScalar hairlineCoverage;
354 uint8_t newCoverage = 0xff; 534 uint8_t newCoverage = 0xff;
355 if (IsStrokeHairlineOrEquivalent(*stroke, viewMatrix, &hairlineCoverage)) { 535 if (IsStrokeHairlineOrEquivalent(*stroke, viewMatrix, &hairlineCoverage)) {
356 newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff); 536 newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff);
357 537
358 if (!stroke->isHairlineStyle()) { 538 if (!stroke->isHairlineStyle()) {
359 stroke.writable()->setHairlineStyle(); 539 stroke.writable()->setHairlineStyle();
360 } 540 }
361 } 541 }
362 542
363 SkScalar tol = SK_Scalar1; 543 const bool isHairline = stroke->isHairlineStyle();
364 tol = GrPathUtils::scaleToleranceToSrc(tol, viewMatrix, path.getBounds());
365 544
366 int vertexCnt;
367 int indexCnt;
368 GrPrimitiveType primType;
369 GrDrawTarget::AutoReleaseGeometry arg;
370 if (!this->createGeom(target,
371 pipelineBuilder,
372 &primType,
373 &vertexCnt,
374 &indexCnt,
375 &arg,
376 path,
377 *stroke,
378 tol)) {
379 return false;
380 }
381 // Save the current xp on the draw state so we can reset it if needed 545 // Save the current xp on the draw state so we can reset it if needed
382 SkAutoTUnref<const GrXPFactory> backupXPFactory(SkRef(pipelineBuilder->getXP Factory())); 546 SkAutoTUnref<const GrXPFactory> backupXPFactory(SkRef(pipelineBuilder->getXP Factory()));
383 // face culling doesn't make sense here 547 // face culling doesn't make sense here
384 SkASSERT(GrPipelineBuilder::kBoth_DrawFace == pipelineBuilder->getDrawFace() ); 548 SkASSERT(GrPipelineBuilder::kBoth_DrawFace == pipelineBuilder->getDrawFace() );
385 549
386 int passCount = 0; 550 int passCount = 0;
387 const GrStencilSettings* passes[3]; 551 const GrStencilSettings* passes[3];
388 GrPipelineBuilder::DrawFace drawFace[3]; 552 GrPipelineBuilder::DrawFace drawFace[3];
389 bool reverse = false; 553 bool reverse = false;
390 bool lastPassIsBounds; 554 bool lastPassIsBounds;
391 555
392 if (stroke->isHairlineStyle()) { 556 if (isHairline) {
393 passCount = 1; 557 passCount = 1;
394 if (stencilOnly) { 558 if (stencilOnly) {
395 passes[0] = &gDirectToStencil; 559 passes[0] = &gDirectToStencil;
396 } else { 560 } else {
397 passes[0] = NULL; 561 passes[0] = NULL;
398 } 562 }
399 lastPassIsBounds = false; 563 lastPassIsBounds = false;
400 drawFace[0] = GrPipelineBuilder::kBoth_DrawFace; 564 drawFace[0] = GrPipelineBuilder::kBoth_DrawFace;
401 } else { 565 } else {
402 if (single_pass_path(path, *stroke)) { 566 if (single_pass_path(path, *stroke)) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 } 632 }
469 } 633 }
470 break; 634 break;
471 default: 635 default:
472 SkDEBUGFAIL("Unknown path fFill!"); 636 SkDEBUGFAIL("Unknown path fFill!");
473 return false; 637 return false;
474 } 638 }
475 } 639 }
476 } 640 }
477 641
642 SkScalar tol = SK_Scalar1;
643 SkScalar srcSpaceTol = GrPathUtils::scaleToleranceToSrc(tol, viewMatrix, pat h.getBounds());
644
478 SkRect devBounds; 645 SkRect devBounds;
479 GetPathDevBounds(path, pipelineBuilder->getRenderTarget(), viewMatrix, &devB ounds); 646 GetPathDevBounds(path, pipelineBuilder->getRenderTarget(), viewMatrix, &devB ounds);
480 647
481 for (int p = 0; p < passCount; ++p) { 648 for (int p = 0; p < passCount; ++p) {
482 pipelineBuilder->setDrawFace(drawFace[p]); 649 pipelineBuilder->setDrawFace(drawFace[p]);
483 if (passes[p]) { 650 if (passes[p]) {
484 *pipelineBuilder->stencil() = *passes[p]; 651 *pipelineBuilder->stencil() = *passes[p];
485 } 652 }
486 653
487 if (lastPassIsBounds && (p == passCount-1)) { 654 if (lastPassIsBounds && (p == passCount-1)) {
(...skipping 18 matching lines...) Expand all
506 bounds = path.getBounds(); 673 bounds = path.getBounds();
507 } 674 }
508 GrDrawTarget::AutoGeometryPush agp(target); 675 GrDrawTarget::AutoGeometryPush agp(target);
509 const SkMatrix& viewM = (reverse && viewMatrix.hasPerspective()) ? S kMatrix::I() : 676 const SkMatrix& viewM = (reverse && viewMatrix.hasPerspective()) ? S kMatrix::I() :
510 v iewMatrix; 677 v iewMatrix;
511 target->drawRect(pipelineBuilder, color, viewM, bounds, NULL, &local Matrix); 678 target->drawRect(pipelineBuilder, color, viewM, bounds, NULL, &local Matrix);
512 } else { 679 } else {
513 if (passCount > 1) { 680 if (passCount > 1) {
514 pipelineBuilder->setDisableColorXPFactory(); 681 pipelineBuilder->setDisableColorXPFactory();
515 } 682 }
516 GrPipelineBuilder::AutoRestoreEffects are(pipelineBuilder); 683
517 SkAutoTUnref<const GrGeometryProcessor> gp( 684 DefaultPathBatch::Geometry geometry;
518 GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPo sition_GPType, 685 geometry.fColor = color;
519 color, 686 geometry.fPath = path;
520 viewMatrix, 687 geometry.fTolerance = srcSpaceTol;
521 SkMatrix::I(), 688 SkDEBUGCODE(geometry.fDevBounds = devBounds;)
522 false, 689
523 newCoverage)); 690 SkAutoTUnref<GrBatch> batch(DefaultPathBatch::Create(geometry, newCo verage, viewMatrix,
524 if (indexCnt) { 691 isHairline));
525 target->drawIndexed(pipelineBuilder, 692
526 gp, 693 target->drawBatch(pipelineBuilder, batch, &devBounds);
527 primType,
528 0,
529 0,
530 vertexCnt,
531 indexCnt,
532 &devBounds);
533 } else {
534 target->drawNonIndexed(pipelineBuilder, gp, primType, 0, vertexC nt, &devBounds);
535 }
536 } 694 }
537 } 695 }
538 return true; 696 return true;
539 } 697 }
540 698
541 bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget* target, 699 bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget* target,
542 const GrPipelineBuilder* pipelineBuilder , 700 const GrPipelineBuilder* pipelineBuilder ,
543 const SkMatrix& viewMatrix, 701 const SkMatrix& viewMatrix,
544 const SkPath& path, 702 const SkPath& path,
545 const SkStrokeRec& stroke, 703 const SkStrokeRec& stroke,
(...skipping 22 matching lines...) Expand all
568 726
569 void GrDefaultPathRenderer::onStencilPath(GrDrawTarget* target, 727 void GrDefaultPathRenderer::onStencilPath(GrDrawTarget* target,
570 GrPipelineBuilder* pipelineBuilder, 728 GrPipelineBuilder* pipelineBuilder,
571 const SkMatrix& viewMatrix, 729 const SkMatrix& viewMatrix,
572 const SkPath& path, 730 const SkPath& path,
573 const SkStrokeRec& stroke) { 731 const SkStrokeRec& stroke) {
574 SkASSERT(SkPath::kInverseEvenOdd_FillType != path.getFillType()); 732 SkASSERT(SkPath::kInverseEvenOdd_FillType != path.getFillType());
575 SkASSERT(SkPath::kInverseWinding_FillType != path.getFillType()); 733 SkASSERT(SkPath::kInverseWinding_FillType != path.getFillType());
576 this->internalDrawPath(target, pipelineBuilder, GrColor_WHITE, viewMatrix, p ath, stroke, true); 734 this->internalDrawPath(target, pipelineBuilder, GrColor_WHITE, viewMatrix, p ath, stroke, true);
577 } 735 }
OLDNEW
« no previous file with comments | « src/gpu/GrAARectRenderer.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698