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

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

Issue 1276333004: GrDrawVertices to batches (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix Created 5 years, 4 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 | « gyp/gpu.gypi ('k') | src/gpu/GrTestBatch.h » ('j') | 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 /* 2 /*
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "GrAARectRenderer.h" 9 #include "GrAARectRenderer.h"
10 #include "GrAtlasTextContext.h" 10 #include "GrAtlasTextContext.h"
11 #include "GrBatchTest.h" 11 #include "GrBatchTest.h"
12 #include "GrColor.h" 12 #include "GrColor.h"
13 #include "GrDefaultGeoProcFactory.h"
14 #include "GrDrawContext.h" 13 #include "GrDrawContext.h"
15 #include "GrOvalRenderer.h" 14 #include "GrOvalRenderer.h"
16 #include "GrPathRenderer.h" 15 #include "GrPathRenderer.h"
17 #include "GrRenderTarget.h" 16 #include "GrRenderTarget.h"
18 #include "GrRenderTargetPriv.h" 17 #include "GrRenderTargetPriv.h"
19 #include "GrStencilAndCoverTextContext.h" 18 #include "GrStencilAndCoverTextContext.h"
20 19
21 #include "batches/GrBatch.h" 20 #include "batches/GrBatch.h"
22 #include "batches/GrDrawAtlasBatch.h" 21 #include "batches/GrDrawAtlasBatch.h"
22 #include "batches/GrDrawVerticesBatch.h"
23 #include "batches/GrStrokeRectBatch.h" 23 #include "batches/GrStrokeRectBatch.h"
24 24
25 #include "SkGr.h" 25 #include "SkGr.h"
26 #include "SkRSXform.h" 26 #include "SkRSXform.h"
27 27
28 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fContext) 28 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fContext)
29 #define RETURN_IF_ABANDONED if (!fDrawTarget) { return; } 29 #define RETURN_IF_ABANDONED if (!fDrawTarget) { return; }
30 #define RETURN_FALSE_IF_ABANDONED if (!fDrawTarget) { return false; } 30 #define RETURN_FALSE_IF_ABANDONED if (!fDrawTarget) { return false; }
31 #define RETURN_NULL_IF_ABANDONED if (!fDrawTarget) { return NULL; } 31 #define RETURN_NULL_IF_ABANDONED if (!fDrawTarget) { return NULL; }
32 32
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 366
367 GrPipelineBuilder pipelineBuilder(paint, rt, clip); 367 GrPipelineBuilder pipelineBuilder(paint, rt, clip);
368 fDrawTarget->drawBWRect(pipelineBuilder, 368 fDrawTarget->drawBWRect(pipelineBuilder,
369 paint.getColor(), 369 paint.getColor(),
370 viewMatrix, 370 viewMatrix,
371 rectToDraw, 371 rectToDraw,
372 &localRect, 372 &localRect,
373 localMatrix); 373 localMatrix);
374 } 374 }
375 375
376 static const GrGeometryProcessor* set_vertex_attributes(bool hasLocalCoords,
377 bool hasColors,
378 int* colorOffset,
379 int* texOffset,
380 GrColor color,
381 const SkMatrix& viewMatr ix,
382 bool coverageIgnored) {
383 using namespace GrDefaultGeoProcFactory;
384 *texOffset = -1;
385 *colorOffset = -1;
386 Color gpColor(color);
387 if (hasColors) {
388 gpColor.fType = Color::kAttribute_Type;
389 }
390
391 Coverage coverage(coverageIgnored ? Coverage::kNone_Type : Coverage::kSolid_ Type);
392 LocalCoords localCoords(hasLocalCoords ? LocalCoords::kHasExplicit_Type :
393 LocalCoords::kUsePosition_Type);
394 if (hasLocalCoords && hasColors) {
395 *colorOffset = sizeof(SkPoint);
396 *texOffset = sizeof(SkPoint) + sizeof(GrColor);
397 } else if (hasLocalCoords) {
398 *texOffset = sizeof(SkPoint);
399 } else if (hasColors) {
400 *colorOffset = sizeof(SkPoint);
401 }
402 return GrDefaultGeoProcFactory::Create(gpColor, coverage, localCoords, viewM atrix);
403 }
404
405 class DrawVerticesBatch : public GrBatch {
406 public:
407 struct Geometry {
408 GrColor fColor;
409 SkTDArray<SkPoint> fPositions;
410 SkTDArray<uint16_t> fIndices;
411 SkTDArray<GrColor> fColors;
412 SkTDArray<SkPoint> fLocalCoords;
413 };
414
415 static GrBatch* Create(const Geometry& geometry, GrPrimitiveType primitiveTy pe,
416 const SkMatrix& viewMatrix,
417 const SkPoint* positions, int vertexCount,
418 const uint16_t* indices, int indexCount,
419 const GrColor* colors, const SkPoint* localCoords,
420 const SkRect& bounds) {
421 return SkNEW_ARGS(DrawVerticesBatch, (geometry, primitiveType, viewMatri x, positions,
422 vertexCount, indices, indexCount, colors,
423 localCoords, bounds));
424 }
425
426 const char* name() const override { return "DrawVerticesBatch"; }
427
428 void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
429 // When this is called on a batch, there is only one geometry bundle
430 if (this->hasColors()) {
431 out->setUnknownFourComponents();
432 } else {
433 out->setKnownFourComponents(fGeoData[0].fColor);
434 }
435 }
436
437 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
438 out->setKnownSingleComponent(0xff);
439 }
440
441 void initBatchTracker(const GrPipelineInfo& init) override {
442 // Handle any color overrides
443 if (!init.readsColor()) {
444 fGeoData[0].fColor = GrColor_ILLEGAL;
445 }
446 init.getOverrideColorIfSet(&fGeoData[0].fColor);
447
448 // setup batch properties
449 fBatch.fColorIgnored = !init.readsColor();
450 fBatch.fColor = fGeoData[0].fColor;
451 fBatch.fUsesLocalCoords = init.readsLocalCoords();
452 fBatch.fCoverageIgnored = !init.readsCoverage();
453 }
454
455 void generateGeometry(GrBatchTarget* batchTarget) override {
456 int colorOffset = -1, texOffset = -1;
457 SkAutoTUnref<const GrGeometryProcessor> gp(
458 set_vertex_attributes(this->hasLocalCoords(), this->hasColors(), &colorOffset,
459 &texOffset, this->color(), this->viewMatri x(),
460 this->coverageIgnored()));
461
462 batchTarget->initDraw(gp, this->pipeline());
463
464 size_t vertexStride = gp->getVertexStride();
465
466 SkASSERT(vertexStride == sizeof(SkPoint) + (this->hasLocalCoords() ? siz eof(SkPoint) : 0)
467 + (this->hasColors() ? sizeof(G rColor) : 0));
468
469 int instanceCount = fGeoData.count();
470
471 const GrVertexBuffer* vertexBuffer;
472 int firstVertex;
473
474 void* verts = batchTarget->makeVertSpace(vertexStride, this->vertexCount (),
475 &vertexBuffer, &firstVertex);
476
477 if (!verts) {
478 SkDebugf("Could not allocate vertices\n");
479 return;
480 }
481
482 const GrIndexBuffer* indexBuffer = NULL;
483 int firstIndex = 0;
484
485 uint16_t* indices = NULL;
486 if (this->hasIndices()) {
487 indices = batchTarget->makeIndexSpace(this->indexCount(), &indexBuff er, &firstIndex);
488
489 if (!indices) {
490 SkDebugf("Could not allocate indices\n");
491 return;
492 }
493 }
494
495 int indexOffset = 0;
496 int vertexOffset = 0;
497 for (int i = 0; i < instanceCount; i++) {
498 const Geometry& args = fGeoData[i];
499
500 // TODO we can actually cache this interleaved and then just memcopy
501 if (this->hasIndices()) {
502 for (int j = 0; j < args.fIndices.count(); ++j, ++indexOffset) {
503 *(indices + indexOffset) = args.fIndices[j] + vertexOffset;
504 }
505 }
506
507 for (int j = 0; j < args.fPositions.count(); ++j) {
508 *((SkPoint*)verts) = args.fPositions[j];
509 if (this->hasColors()) {
510 *(GrColor*)((intptr_t)verts + colorOffset) = args.fColors[j] ;
511 }
512 if (this->hasLocalCoords()) {
513 *(SkPoint*)((intptr_t)verts + texOffset) = args.fLocalCoords [j];
514 }
515 verts = (void*)((intptr_t)verts + vertexStride);
516 vertexOffset++;
517 }
518 }
519
520 GrVertices vertices;
521 if (this->hasIndices()) {
522 vertices.initIndexed(this->primitiveType(), vertexBuffer, indexBuffe r, firstVertex,
523 firstIndex, this->vertexCount(), this->indexCou nt());
524
525 } else {
526 vertices.init(this->primitiveType(), vertexBuffer, firstVertex, this ->vertexCount());
527 }
528 batchTarget->draw(vertices);
529 }
530
531 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
532
533 private:
534 DrawVerticesBatch(const Geometry& geometry, GrPrimitiveType primitiveType,
535 const SkMatrix& viewMatrix,
536 const SkPoint* positions, int vertexCount,
537 const uint16_t* indices, int indexCount,
538 const GrColor* colors, const SkPoint* localCoords, const S kRect& bounds) {
539 this->initClassID<DrawVerticesBatch>();
540 SkASSERT(positions);
541
542 fBatch.fViewMatrix = viewMatrix;
543 Geometry& installedGeo = fGeoData.push_back(geometry);
544
545 installedGeo.fPositions.append(vertexCount, positions);
546 if (indices) {
547 installedGeo.fIndices.append(indexCount, indices);
548 fBatch.fHasIndices = true;
549 } else {
550 fBatch.fHasIndices = false;
551 }
552
553 if (colors) {
554 installedGeo.fColors.append(vertexCount, colors);
555 fBatch.fHasColors = true;
556 } else {
557 fBatch.fHasColors = false;
558 }
559
560 if (localCoords) {
561 installedGeo.fLocalCoords.append(vertexCount, localCoords);
562 fBatch.fHasLocalCoords = true;
563 } else {
564 fBatch.fHasLocalCoords = false;
565 }
566 fBatch.fVertexCount = vertexCount;
567 fBatch.fIndexCount = indexCount;
568 fBatch.fPrimitiveType = primitiveType;
569
570 this->setBounds(bounds);
571 }
572
573 GrPrimitiveType primitiveType() const { return fBatch.fPrimitiveType; }
574 bool batchablePrimitiveType() const {
575 return kTriangles_GrPrimitiveType == fBatch.fPrimitiveType ||
576 kLines_GrPrimitiveType == fBatch.fPrimitiveType ||
577 kPoints_GrPrimitiveType == fBatch.fPrimitiveType;
578 }
579 GrColor color() const { return fBatch.fColor; }
580 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
581 bool colorIgnored() const { return fBatch.fColorIgnored; }
582 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; }
583 bool hasColors() const { return fBatch.fHasColors; }
584 bool hasIndices() const { return fBatch.fHasIndices; }
585 bool hasLocalCoords() const { return fBatch.fHasLocalCoords; }
586 int vertexCount() const { return fBatch.fVertexCount; }
587 int indexCount() const { return fBatch.fIndexCount; }
588 bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
589
590 bool onCombineIfPossible(GrBatch* t) override {
591 if (!this->pipeline()->isEqual(*t->pipeline())) {
592 return false;
593 }
594
595 DrawVerticesBatch* that = t->cast<DrawVerticesBatch>();
596
597 if (!this->batchablePrimitiveType() || this->primitiveType() != that->pr imitiveType()) {
598 return false;
599 }
600
601 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
602
603 // We currently use a uniform viewmatrix for this batch
604 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
605 return false;
606 }
607
608 if (this->hasColors() != that->hasColors()) {
609 return false;
610 }
611
612 if (this->hasIndices() != that->hasIndices()) {
613 return false;
614 }
615
616 if (this->hasLocalCoords() != that->hasLocalCoords()) {
617 return false;
618 }
619
620 if (!this->hasColors() && this->color() != that->color()) {
621 return false;
622 }
623
624 if (this->color() != that->color()) {
625 fBatch.fColor = GrColor_ILLEGAL;
626 }
627 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ;
628 fBatch.fVertexCount += that->vertexCount();
629 fBatch.fIndexCount += that->indexCount();
630
631 this->joinBounds(that->bounds());
632 return true;
633 }
634
635 struct BatchTracker {
636 GrPrimitiveType fPrimitiveType;
637 SkMatrix fViewMatrix;
638 GrColor fColor;
639 bool fUsesLocalCoords;
640 bool fColorIgnored;
641 bool fCoverageIgnored;
642 bool fHasColors;
643 bool fHasIndices;
644 bool fHasLocalCoords;
645 int fVertexCount;
646 int fIndexCount;
647 };
648
649 BatchTracker fBatch;
650 SkSTArray<1, Geometry, true> fGeoData;
651 };
652
653 void GrDrawContext::drawVertices(GrRenderTarget* rt, 376 void GrDrawContext::drawVertices(GrRenderTarget* rt,
654 const GrClip& clip, 377 const GrClip& clip,
655 const GrPaint& paint, 378 const GrPaint& paint,
656 const SkMatrix& viewMatrix, 379 const SkMatrix& viewMatrix,
657 GrPrimitiveType primitiveType, 380 GrPrimitiveType primitiveType,
658 int vertexCount, 381 int vertexCount,
659 const SkPoint positions[], 382 const SkPoint positions[],
660 const SkPoint texCoords[], 383 const SkPoint texCoords[],
661 const GrColor colors[], 384 const GrColor colors[],
662 const uint16_t indices[], 385 const uint16_t indices[],
(...skipping 14 matching lines...) Expand all
677 } 400 }
678 401
679 viewMatrix.mapRect(&bounds); 402 viewMatrix.mapRect(&bounds);
680 403
681 // If we don't have AA then we outset for a half pixel in each direction to account for 404 // If we don't have AA then we outset for a half pixel in each direction to account for
682 // snapping 405 // snapping
683 if (!paint.isAntiAlias()) { 406 if (!paint.isAntiAlias()) {
684 bounds.outset(0.5f, 0.5f); 407 bounds.outset(0.5f, 0.5f);
685 } 408 }
686 409
687 DrawVerticesBatch::Geometry geometry; 410 GrDrawVerticesBatch::Geometry geometry;
688 geometry.fColor = paint.getColor(); 411 geometry.fColor = paint.getColor();
689 SkAutoTUnref<GrBatch> batch(DrawVerticesBatch::Create(geometry, primitiveTyp e, viewMatrix, 412 SkAutoTUnref<GrBatch> batch(GrDrawVerticesBatch::Create(geometry, primitiveT ype, viewMatrix,
690 positions, vertexCount , indices, 413 positions, vertexCou nt, indices,
691 indexCount, colors, te xCoords, 414 indexCount, colors, texCoords,
692 bounds)); 415 bounds));
693 416
694 fDrawTarget->drawBatch(pipelineBuilder, batch); 417 fDrawTarget->drawBatch(pipelineBuilder, batch);
695 } 418 }
696 419
697 /////////////////////////////////////////////////////////////////////////////// 420 ///////////////////////////////////////////////////////////////////////////////
698 421
699 void GrDrawContext::drawAtlas(GrRenderTarget* rt, 422 void GrDrawContext::drawAtlas(GrRenderTarget* rt,
700 const GrClip& clip, 423 const GrClip& clip,
701 const GrPaint& paint, 424 const GrPaint& paint,
702 const SkMatrix& viewMatrix, 425 const SkMatrix& viewMatrix,
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 RETURN_FALSE_IF_ABANDONED 824 RETURN_FALSE_IF_ABANDONED
1102 825
1103 ASSERT_OWNED_RESOURCE(rt); 826 ASSERT_OWNED_RESOURCE(rt);
1104 SkASSERT(rt); 827 SkASSERT(rt);
1105 return true; 828 return true;
1106 } 829 }
1107 830
1108 void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrBatch* batch ) { 831 void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrBatch* batch ) {
1109 fDrawTarget->drawBatch(*pipelineBuilder, batch); 832 fDrawTarget->drawBatch(*pipelineBuilder, batch);
1110 } 833 }
1111
1112 //////////////////////////////////////////////////////////////////////////////// ///////////////////
1113
1114 #ifdef GR_TEST_UTILS
1115
1116 static uint32_t seed_vertices(GrPrimitiveType type) {
1117 switch (type) {
1118 case kTriangles_GrPrimitiveType:
1119 case kTriangleStrip_GrPrimitiveType:
1120 case kTriangleFan_GrPrimitiveType:
1121 return 3;
1122 case kPoints_GrPrimitiveType:
1123 return 1;
1124 case kLines_GrPrimitiveType:
1125 case kLineStrip_GrPrimitiveType:
1126 return 2;
1127 }
1128 SkFAIL("Incomplete switch\n");
1129 return 0;
1130 }
1131
1132 static uint32_t primitive_vertices(GrPrimitiveType type) {
1133 switch (type) {
1134 case kTriangles_GrPrimitiveType:
1135 return 3;
1136 case kLines_GrPrimitiveType:
1137 return 2;
1138 case kTriangleStrip_GrPrimitiveType:
1139 case kTriangleFan_GrPrimitiveType:
1140 case kPoints_GrPrimitiveType:
1141 case kLineStrip_GrPrimitiveType:
1142 return 1;
1143 }
1144 SkFAIL("Incomplete switch\n");
1145 return 0;
1146 }
1147
1148 static SkPoint random_point(SkRandom* random, SkScalar min, SkScalar max) {
1149 SkPoint p;
1150 p.fX = random->nextRangeScalar(min, max);
1151 p.fY = random->nextRangeScalar(min, max);
1152 return p;
1153 }
1154
1155 static void randomize_params(size_t count, size_t maxVertex, SkScalar min, SkSca lar max,
1156 SkRandom* random,
1157 SkTArray<SkPoint>* positions,
1158 SkTArray<SkPoint>* texCoords, bool hasTexCoords,
1159 SkTArray<GrColor>* colors, bool hasColors,
1160 SkTArray<uint16_t>* indices, bool hasIndices) {
1161 for (uint32_t v = 0; v < count; v++) {
1162 positions->push_back(random_point(random, min, max));
1163 if (hasTexCoords) {
1164 texCoords->push_back(random_point(random, min, max));
1165 }
1166 if (hasColors) {
1167 colors->push_back(GrRandomColor(random));
1168 }
1169 if (hasIndices) {
1170 SkASSERT(maxVertex <= SK_MaxU16);
1171 indices->push_back(random->nextULessThan((uint16_t)maxVertex));
1172 }
1173 }
1174 }
1175
1176 BATCH_TEST_DEFINE(VerticesBatch) {
1177 GrPrimitiveType type = GrPrimitiveType(random->nextULessThan(kLast_GrPrimiti veType + 1));
1178 uint32_t primitiveCount = random->nextRangeU(1, 100);
1179
1180 // TODO make 'sensible' indexbuffers
1181 SkTArray<SkPoint> positions;
1182 SkTArray<SkPoint> texCoords;
1183 SkTArray<GrColor> colors;
1184 SkTArray<uint16_t> indices;
1185
1186 bool hasTexCoords = random->nextBool();
1187 bool hasIndices = random->nextBool();
1188 bool hasColors = random->nextBool();
1189
1190 uint32_t vertexCount = seed_vertices(type) + (primitiveCount - 1) * primitiv e_vertices(type);
1191
1192 static const SkScalar kMinVertExtent = -100.f;
1193 static const SkScalar kMaxVertExtent = 100.f;
1194 randomize_params(seed_vertices(type), vertexCount, kMinVertExtent, kMaxVertE xtent,
1195 random,
1196 &positions,
1197 &texCoords, hasTexCoords,
1198 &colors, hasColors,
1199 &indices, hasIndices);
1200
1201 for (uint32_t i = 1; i < primitiveCount; i++) {
1202 randomize_params(primitive_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent,
1203 random,
1204 &positions,
1205 &texCoords, hasTexCoords,
1206 &colors, hasColors,
1207 &indices, hasIndices);
1208 }
1209
1210 SkMatrix viewMatrix = GrTest::TestMatrix(random);
1211 SkRect bounds;
1212 SkDEBUGCODE(bool result = ) bounds.setBoundsCheck(positions.begin(), vertexC ount);
1213 SkASSERT(result);
1214
1215 viewMatrix.mapRect(&bounds);
1216
1217 DrawVerticesBatch::Geometry geometry;
1218 geometry.fColor = GrRandomColor(random);
1219 return DrawVerticesBatch::Create(geometry, type, viewMatrix,
1220 positions.begin(), vertexCount,
1221 indices.begin(), hasIndices ? vertexCount : 0,
1222 colors.begin(),
1223 texCoords.begin(),
1224 bounds);
1225 }
1226
1227 #endif
1228
OLDNEW
« no previous file with comments | « gyp/gpu.gypi ('k') | src/gpu/GrTestBatch.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698