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

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

Issue 913253003: Context batches (Closed) Base URL: https://skia.googlesource.com/skia.git@rect
Patch Set: cleanup Created 5 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 | « no previous file | 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 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 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 "GrContext.h" 9 #include "GrContext.h"
10 10
11 #include "GrAARectRenderer.h" 11 #include "GrAARectRenderer.h"
12 #include "GrBatch.h"
13 #include "GrBatchTarget.h"
12 #include "GrBufferAllocPool.h" 14 #include "GrBufferAllocPool.h"
13 #include "GrDefaultGeoProcFactory.h" 15 #include "GrDefaultGeoProcFactory.h"
14 #include "GrFontCache.h" 16 #include "GrFontCache.h"
15 #include "GrGpuResource.h" 17 #include "GrGpuResource.h"
16 #include "GrGpuResourcePriv.h" 18 #include "GrGpuResourcePriv.h"
17 #include "GrDistanceFieldTextContext.h" 19 #include "GrDistanceFieldTextContext.h"
18 #include "GrDrawTargetCaps.h" 20 #include "GrDrawTargetCaps.h"
19 #include "GrGpu.h" 21 #include "GrGpu.h"
20 #include "GrIndexBuffer.h" 22 #include "GrIndexBuffer.h"
21 #include "GrInOrderDrawBuffer.h" 23 #include "GrInOrderDrawBuffer.h"
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 } 435 }
434 436
435 #ifdef SK_DEVELOPER 437 #ifdef SK_DEVELOPER
436 void GrContext::dumpFontCache() const { 438 void GrContext::dumpFontCache() const {
437 fFontCache->dump(); 439 fFontCache->dump();
438 } 440 }
439 #endif 441 #endif
440 442
441 //////////////////////////////////////////////////////////////////////////////// 443 ////////////////////////////////////////////////////////////////////////////////
442 444
443 /* create a triangle strip that strokes the specified triangle. There are 8
444 unique vertices, but we repreat the last 2 to close up. Alternatively we
445 could use an indices array, and then only send 8 verts, but not sure that
446 would be faster.
447 */
448 static void setStrokeRectStrip(SkPoint verts[10], SkRect rect,
449 SkScalar width) {
450 const SkScalar rad = SkScalarHalf(width);
451 rect.sort();
452
453 verts[0].set(rect.fLeft + rad, rect.fTop + rad);
454 verts[1].set(rect.fLeft - rad, rect.fTop - rad);
455 verts[2].set(rect.fRight - rad, rect.fTop + rad);
456 verts[3].set(rect.fRight + rad, rect.fTop - rad);
457 verts[4].set(rect.fRight - rad, rect.fBottom - rad);
458 verts[5].set(rect.fRight + rad, rect.fBottom + rad);
459 verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
460 verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
461 verts[8] = verts[0];
462 verts[9] = verts[1];
463 }
464
465 static inline bool is_irect(const SkRect& r) { 445 static inline bool is_irect(const SkRect& r) {
466 return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) && 446 return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) &&
467 SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom); 447 SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom);
468 } 448 }
469 449
470 static bool apply_aa_to_rect(GrDrawTarget* target, 450 static bool apply_aa_to_rect(GrDrawTarget* target,
471 GrPipelineBuilder* pipelineBuilder, 451 GrPipelineBuilder* pipelineBuilder,
472 SkRect* devBoundRect, 452 SkRect* devBoundRect,
473 const SkRect& rect, 453 const SkRect& rect,
474 SkScalar strokeWidth, 454 SkScalar strokeWidth,
(...skipping 28 matching lines...) Expand all
503 } 483 }
504 484
505 return true; 485 return true;
506 } 486 }
507 487
508 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po int) { 488 static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& po int) {
509 return point.fX >= rect.fLeft && point.fX <= rect.fRight && 489 return point.fX >= rect.fLeft && point.fX <= rect.fRight &&
510 point.fY >= rect.fTop && point.fY <= rect.fBottom; 490 point.fY >= rect.fTop && point.fY <= rect.fBottom;
511 } 491 }
512 492
493 class StrokeRectBatch : public GrBatch {
494 public:
495 struct Geometry {
496 GrColor fColor;
497 SkMatrix fViewMatrix;
498 SkRect fRect;
499 SkScalar fStrokeWidth;
500 };
501
502 static GrBatch* Create(const Geometry& geometry) {
503 return SkNEW_ARGS(StrokeRectBatch, (geometry));
504 }
505
506 const char* name() const SK_OVERRIDE { return "StrokeRectBatch"; }
507
508 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE {
509 // When this is called on a batch, there is only one geometry bundle
510 out->setKnownFourComponents(fGeoData[0].fColor);
511 }
512
513 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRID E {
514 out->setKnownSingleComponent(0xff);
515 }
516
517 void initBatchTracker(const GrPipelineInfo& init) SK_OVERRIDE {
518 // Handle any color overrides
519 if (init.fColorIgnored) {
520 fGeoData[0].fColor = GrColor_ILLEGAL;
521 } else if (GrColor_ILLEGAL != init.fOverrideColor) {
522 fGeoData[0].fColor = init.fOverrideColor;
523 }
524
525 // setup batch properties
526 fBatch.fColorIgnored = init.fColorIgnored;
527 fBatch.fColor = fGeoData[0].fColor;
528 fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
529 fBatch.fCoverageIgnored = init.fCoverageIgnored;
530 }
531
532 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline ) SK_OVERRIDE {
533 SkAutoTUnref<const GrGeometryProcessor> gp(
534 GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPositi on_GPType,
535 this->color(),
536 this->viewMatrix(),
537 SkMatrix::I()));
538
539 batchTarget->initDraw(gp, pipeline);
540
541 // TODO this is hacky, but the only way we have to initialize the GP is to use the
542 // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch
543 // everywhere we can remove this nastiness
544 GrPipelineInfo init;
545 init.fColorIgnored = fBatch.fColorIgnored;
546 init.fOverrideColor = GrColor_ILLEGAL;
547 init.fCoverageIgnored = fBatch.fCoverageIgnored;
548 init.fUsesLocalCoords = this->usesLocalCoords();
549 gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
550
551 size_t vertexStride = gp->getVertexStride();
552
553 SkASSERT(vertexStride == sizeof(GrDefaultGeoProcFactory::PositionAttr));
554
555 Geometry& args = fGeoData[0];
556
557 int vertexCount = kVertsPerHairlineRect;
558 if (args.fStrokeWidth > 0) {
559 vertexCount = kVertsPerStrokeRect;
560 }
561
562 const GrVertexBuffer* vertexBuffer;
563 int firstVertex;
564
565 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
566 vertexCount,
567 &vertexBuffer,
568 &firstVertex);
569
570 SkPoint* vertex = reinterpret_cast<SkPoint*>(vertices);
571
572 GrPrimitiveType primType;
573
574 if (args.fStrokeWidth > 0) {;
575 primType = kTriangleStrip_GrPrimitiveType;
576 args.fRect.sort();
577 this->setStrokeRectStrip(vertex, args.fRect, args.fStrokeWidth);
578 } else {
579 // hairline
580 primType = kLineStrip_GrPrimitiveType;
581 vertex[0].set(args.fRect.fLeft, args.fRect.fTop);
582 vertex[1].set(args.fRect.fRight, args.fRect.fTop);
583 vertex[2].set(args.fRect.fRight, args.fRect.fBottom);
584 vertex[3].set(args.fRect.fLeft, args.fRect.fBottom);
585 vertex[4].set(args.fRect.fLeft, args.fRect.fTop);
586 }
587
588 GrDrawTarget::DrawInfo drawInfo;
589 drawInfo.setPrimitiveType(primType);
590 drawInfo.setVertexBuffer(vertexBuffer);
591 drawInfo.setStartVertex(firstVertex);
592 drawInfo.setVertexCount(vertexCount);
593 drawInfo.setStartIndex(0);
594 drawInfo.setIndexCount(0);
595 drawInfo.setInstanceCount(0);
596 drawInfo.setVerticesPerInstance(0);
597 drawInfo.setIndicesPerInstance(0);
598 batchTarget->draw(drawInfo);
599 }
600
601 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
602
603 private:
604 StrokeRectBatch(const Geometry& geometry) {
605 this->initClassID<StrokeRectBatch>();
606
607 fBatch.fHairline = geometry.fStrokeWidth == 0;
608
609 fGeoData.push_back(geometry);
610 }
611
612 /* create a triangle strip that strokes the specified rect. There are 8
613 unique vertices, but we repeat the last 2 to close up. Alternatively we
614 could use an indices array, and then only send 8 verts, but not sure that
615 would be faster.
616 */
617 void setStrokeRectStrip(SkPoint verts[10], const SkRect& rect, SkScalar widt h) {
618 const SkScalar rad = SkScalarHalf(width);
619 // TODO we should be able to enable this assert, but we'd have to filter these draws
620 // this is a bug
621 //SkASSERT(rad < rect.width() / 2 && rad < rect.height() / 2);
622
623 verts[0].set(rect.fLeft + rad, rect.fTop + rad);
624 verts[1].set(rect.fLeft - rad, rect.fTop - rad);
625 verts[2].set(rect.fRight - rad, rect.fTop + rad);
626 verts[3].set(rect.fRight + rad, rect.fTop - rad);
627 verts[4].set(rect.fRight - rad, rect.fBottom - rad);
628 verts[5].set(rect.fRight + rad, rect.fBottom + rad);
629 verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
630 verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
631 verts[8] = verts[0];
632 verts[9] = verts[1];
633 }
634
635
636 GrColor color() const { return fBatch.fColor; }
637 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
638 bool colorIgnored() const { return fBatch.fColorIgnored; }
639 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
640 bool hairline() const { return fBatch.fHairline; }
641
642 bool onCombineIfPossible(GrBatch* t) SK_OVERRIDE {
643 // StrokeRectBatch* that = t->cast<StrokeRectBatch>();
644
645 // NonAA stroke rects cannot batch right now
646 // TODO make these batchable
647 return false;
648 }
649
650 struct BatchTracker {
651 GrColor fColor;
652 bool fUsesLocalCoords;
653 bool fColorIgnored;
654 bool fCoverageIgnored;
655 bool fHairline;
656 };
657
658 const static int kVertsPerHairlineRect = 5;
659 const static int kVertsPerStrokeRect = 10;
660
661 BatchTracker fBatch;
662 SkSTArray<1, Geometry, true> fGeoData;
663 };
664
513 void GrContext::drawRect(GrRenderTarget* rt, 665 void GrContext::drawRect(GrRenderTarget* rt,
514 const GrClip& clip, 666 const GrClip& clip,
515 const GrPaint& paint, 667 const GrPaint& paint,
516 const SkMatrix& viewMatrix, 668 const SkMatrix& viewMatrix,
517 const SkRect& rect, 669 const SkRect& rect,
518 const GrStrokeInfo* strokeInfo) { 670 const GrStrokeInfo* strokeInfo) {
519 RETURN_IF_ABANDONED 671 RETURN_IF_ABANDONED
520 if (strokeInfo && strokeInfo->isDashed()) { 672 if (strokeInfo && strokeInfo->isDashed()) {
521 SkPath path; 673 SkPath path;
522 path.addRect(rect); 674 path.addRect(rect);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 &pipelineBuilder, 742 &pipelineBuilder,
591 color, 743 color,
592 viewMatrix, 744 viewMatrix,
593 rect, 745 rect,
594 devBoundRect); 746 devBoundRect);
595 } 747 }
596 return; 748 return;
597 } 749 }
598 750
599 if (width >= 0) { 751 if (width >= 0) {
600 // TODO: consider making static vertex buffers for these cases. 752 StrokeRectBatch::Geometry geometry;
601 // Hairline could be done by just adding closing vertex to 753 geometry.fViewMatrix = viewMatrix;
602 // unitSquareVertexBuffer() 754 geometry.fColor = color;
755 geometry.fRect = rect;
756 geometry.fStrokeWidth = width;
603 757
604 static const int worstCaseVertCount = 10; 758 SkAutoTUnref<GrBatch> batch(StrokeRectBatch::Create(geometry));
605 SkAutoTUnref<const GrGeometryProcessor> gp(
606 GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPositi on_GPType,
607 color,
608 viewMatrix,
609 SkMatrix::I()));
610 GrDrawTarget::AutoReleaseGeometry geo(target,
611 worstCaseVertCount,
612 gp->getVertexStride(),
613 0);
614 SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
615 759
616 if (!geo.succeeded()) { 760 SkRect bounds = rect;
617 SkDebugf("Failed to get space for vertices!\n"); 761 SkScalar rad = SkScalarHalf(width);
618 return; 762 bounds.outset(rad, rad);
619 } 763 viewMatrix.mapRect(&bounds);
620 764 target->drawBatch(&pipelineBuilder, batch, &bounds);
621 GrPrimitiveType primType;
622 int vertCount;
623 SkPoint* vertex = geo.positions();
624
625 if (width > 0) {
626 vertCount = 10;
627 primType = kTriangleStrip_GrPrimitiveType;
628 setStrokeRectStrip(vertex, rect, width);
629 } else {
630 // hairline
631 vertCount = 5;
632 primType = kLineStrip_GrPrimitiveType;
633 vertex[0].set(rect.fLeft, rect.fTop);
634 vertex[1].set(rect.fRight, rect.fTop);
635 vertex[2].set(rect.fRight, rect.fBottom);
636 vertex[3].set(rect.fLeft, rect.fBottom);
637 vertex[4].set(rect.fLeft, rect.fTop);
638 }
639
640 target->drawNonIndexed(&pipelineBuilder, gp, primType, 0, vertCount);
641 } else { 765 } else {
642 // filled BW rect 766 // filled BW rect
643 target->drawSimpleRect(&pipelineBuilder, color, viewMatrix, rect); 767 target->drawSimpleRect(&pipelineBuilder, color, viewMatrix, rect);
644 } 768 }
645 } 769 }
646 770
647 void GrContext::drawNonAARectToRect(GrRenderTarget* rt, 771 void GrContext::drawNonAARectToRect(GrRenderTarget* rt,
648 const GrClip& clip, 772 const GrClip& clip,
649 const GrPaint& paint, 773 const GrPaint& paint,
650 const SkMatrix& viewMatrix, 774 const SkMatrix& viewMatrix,
(...skipping 11 matching lines...) Expand all
662 GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target); 786 GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target);
663 787
664 target->drawRect(&pipelineBuilder, 788 target->drawRect(&pipelineBuilder,
665 paint.getColor(), 789 paint.getColor(),
666 viewMatrix, 790 viewMatrix,
667 rectToDraw, 791 rectToDraw,
668 &localRect, 792 &localRect,
669 localMatrix); 793 localMatrix);
670 } 794 }
671 795
672 static const GrGeometryProcessor* set_vertex_attributes(const SkPoint* texCoords , 796 static const GrGeometryProcessor* set_vertex_attributes(bool hasLocalCoords,
673 const GrColor* colors, 797 bool hasColors,
674 int* colorOffset, 798 int* colorOffset,
675 int* texOffset, 799 int* texOffset,
676 GrColor color, 800 GrColor color,
677 const SkMatrix& viewMatr ix) { 801 const SkMatrix& viewMatr ix) {
678 *texOffset = -1; 802 *texOffset = -1;
679 *colorOffset = -1; 803 *colorOffset = -1;
680 uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType; 804 uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType;
681 if (texCoords && colors) { 805 if (hasLocalCoords && hasColors) {
682 *colorOffset = sizeof(SkPoint); 806 *colorOffset = sizeof(SkPoint);
683 *texOffset = sizeof(SkPoint) + sizeof(GrColor); 807 *texOffset = sizeof(SkPoint) + sizeof(GrColor);
684 flags |= GrDefaultGeoProcFactory::kColor_GPType | 808 flags |= GrDefaultGeoProcFactory::kColor_GPType |
685 GrDefaultGeoProcFactory::kLocalCoord_GPType; 809 GrDefaultGeoProcFactory::kLocalCoord_GPType;
686 } else if (texCoords) { 810 } else if (hasLocalCoords) {
687 *texOffset = sizeof(SkPoint); 811 *texOffset = sizeof(SkPoint);
688 flags |= GrDefaultGeoProcFactory::kLocalCoord_GPType; 812 flags |= GrDefaultGeoProcFactory::kLocalCoord_GPType;
689 } else if (colors) { 813 } else if (hasColors) {
690 *colorOffset = sizeof(SkPoint); 814 *colorOffset = sizeof(SkPoint);
691 flags |= GrDefaultGeoProcFactory::kColor_GPType; 815 flags |= GrDefaultGeoProcFactory::kColor_GPType;
692 } 816 }
693 return GrDefaultGeoProcFactory::Create(flags, color, viewMatrix, SkMatrix::I ()); 817 return GrDefaultGeoProcFactory::Create(flags, color, viewMatrix, SkMatrix::I ());
694 } 818 }
695 819
820 class DrawVerticesBatch : public GrBatch {
821 public:
822 struct Geometry {
823 GrColor fColor;
824 SkTDArray<SkPoint> fPositions;
825 SkTDArray<uint16_t> fIndices;
826 SkTDArray<GrColor> fColors;
827 SkTDArray<SkPoint> fLocalCoords;
828 };
829
830 static GrBatch* Create(const Geometry& geometry, GrPrimitiveType primitiveTy pe,
831 const SkMatrix& viewMatrix,
832 const SkPoint* positions, int vertexCount,
833 const uint16_t* indices, int indexCount,
834 const GrColor* colors, const SkPoint* localCoords) {
835 return SkNEW_ARGS(DrawVerticesBatch, (geometry, primitiveType, viewMatri x, positions,
836 vertexCount, indices, indexCount, colors,
837 localCoords));
838 }
839
840 const char* name() const SK_OVERRIDE { return "DrawVerticesBatch"; }
841
842 void getInvariantOutputColor(GrInitInvariantOutput* out) const SK_OVERRIDE {
843 // When this is called on a batch, there is only one geometry bundle
844 if (this->hasColors()) {
845 out->setUnknownFourComponents();
846 } else {
847 out->setKnownFourComponents(fGeoData[0].fColor);
848 }
849 }
850
851 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const SK_OVERRID E {
852 out->setUnknownSingleComponent();
853 }
854
855 void initBatchTracker(const GrPipelineInfo& init) SK_OVERRIDE {
856 // Handle any color overrides
857 if (init.fColorIgnored) {
858 fGeoData[0].fColor = GrColor_ILLEGAL;
859 } else if (GrColor_ILLEGAL != init.fOverrideColor) {
860 fGeoData[0].fColor = init.fOverrideColor;
861 }
862
863 // setup batch properties
864 fBatch.fColorIgnored = init.fColorIgnored;
865 fBatch.fColor = fGeoData[0].fColor;
866 fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
867 fBatch.fCoverageIgnored = init.fCoverageIgnored;
868 }
869
870 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline ) SK_OVERRIDE {
871 int colorOffset = -1, texOffset = -1;
872 SkAutoTUnref<const GrGeometryProcessor> gp(
873 set_vertex_attributes(this->hasLocalCoords(), this->hasColors(), &colorOffset,
874 &texOffset, this->color(), this->viewMatri x()));
875
876 batchTarget->initDraw(gp, pipeline);
877
878 // TODO this is hacky, but the only way we have to initialize the GP is to use the
879 // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch
880 // everywhere we can remove this nastiness
881 GrPipelineInfo init;
882 init.fColorIgnored = fBatch.fColorIgnored;
883 init.fOverrideColor = GrColor_ILLEGAL;
884 init.fCoverageIgnored = fBatch.fCoverageIgnored;
885 init.fUsesLocalCoords = this->usesLocalCoords();
886 gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
887
888 size_t vertexStride = gp->getVertexStride();
889
890 SkASSERT(vertexStride == sizeof(SkPoint) + (this->hasLocalCoords() ? siz eof(SkPoint) : 0)
891 + (this->hasColors() ? sizeof(G rColor) : 0));
892
893 int instanceCount = fGeoData.count();
894
895 const GrVertexBuffer* vertexBuffer;
896 int firstVertex;
897
898 void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
899 this->vertexCount( ),
900 &vertexBuffer,
901 &firstVertex);
902
903 const GrIndexBuffer* indexBuffer;
904 int firstIndex;
905
906 void* indices = NULL;
907 if (this->hasIndices()) {
908 indices = batchTarget->indexPool()->makeSpace(this->indexCount(),
909 &indexBuffer,
910 &firstIndex);
911 }
912
913 int indexOffset = 0;
914 int vertexOffset = 0;
915 for (int i = 0; i < instanceCount; i++) {
916 const Geometry& args = fGeoData[i];
917
918 // TODO we can actually cache this interleaved and then just memcopy
919 if (this->hasIndices()) {
920 for (int j = 0; j < args.fIndices.count(); ++j, ++indexOffset) {
921 *((uint16_t*)indices + indexOffset) = args.fIndices[j] + ver texOffset;
922 }
923 }
924
925 for (int j = 0; j < args.fPositions.count(); ++j) {
926 *((SkPoint*)vertices) = args.fPositions[j];
927 if (this->hasColors()) {
928 *(GrColor*)((intptr_t)vertices + colorOffset) = args.fColors [j];
929 }
930 if (this->hasLocalCoords()) {
931 *(SkPoint*)((intptr_t)vertices + texOffset) = args.fLocalCoo rds[j];
932 }
933 vertices = (void*)((intptr_t)vertices + vertexStride);
934 vertexOffset++;
935 }
936 }
937
938 GrDrawTarget::DrawInfo drawInfo;
939 drawInfo.setPrimitiveType(this->primitiveType());
940 drawInfo.setVertexBuffer(vertexBuffer);
941 drawInfo.setStartVertex(firstVertex);
942 drawInfo.setVertexCount(this->vertexCount());
943 if (this->hasIndices()) {
944 drawInfo.setIndexBuffer(indexBuffer);
945 drawInfo.setStartIndex(firstIndex);
946 drawInfo.setIndexCount(this->indexCount());
947 } else {
948 drawInfo.setStartIndex(0);
949 drawInfo.setIndexCount(0);
950 }
951 batchTarget->draw(drawInfo);
952 }
953
954 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
955
956 private:
957 DrawVerticesBatch(const Geometry& geometry, GrPrimitiveType primitiveType,
958 const SkMatrix& viewMatrix,
959 const SkPoint* positions, int vertexCount,
960 const uint16_t* indices, int indexCount,
961 const GrColor* colors, const SkPoint* localCoords) {
962 this->initClassID<DrawVerticesBatch>();
963 SkASSERT(positions);
964
965 fBatch.fViewMatrix = viewMatrix;
966 Geometry& installedGeo = fGeoData.push_back(geometry);
967
968 installedGeo.fPositions.append(vertexCount, positions);
969 if (indices) {
970 installedGeo.fIndices.append(indexCount, indices);
971 fBatch.fHasIndices = true;
972 } else {
973 fBatch.fHasIndices = false;
974 }
975
976 if (colors) {
977 installedGeo.fColors.append(vertexCount, colors);
978 fBatch.fHasColors = true;
979 } else {
980 fBatch.fHasColors = false;
981 }
982
983 if (localCoords) {
984 installedGeo.fLocalCoords.append(vertexCount, localCoords);
985 fBatch.fHasLocalCoords = true;
986 } else {
987 fBatch.fHasLocalCoords = false;
988 }
989 fBatch.fVertexCount = vertexCount;
990 fBatch.fIndexCount = indexCount;
991 fBatch.fPrimitiveType = primitiveType;
992 }
993
994 GrPrimitiveType primitiveType() const { return fBatch.fPrimitiveType; }
995 bool batchablePrimitiveType() const {
996 return kTriangles_GrPrimitiveType == fBatch.fPrimitiveType ||
997 kLines_GrPrimitiveType == fBatch.fPrimitiveType ||
998 kPoints_GrPrimitiveType == fBatch.fPrimitiveType;
999 }
1000 GrColor color() const { return fBatch.fColor; }
1001 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
1002 bool colorIgnored() const { return fBatch.fColorIgnored; }
1003 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; }
1004 bool hasColors() const { return fBatch.fHasColors; }
1005 bool hasIndices() const { return fBatch.fHasIndices; }
1006 bool hasLocalCoords() const { return fBatch.fHasLocalCoords; }
1007 int vertexCount() const { return fBatch.fVertexCount; }
1008 int indexCount() const { return fBatch.fIndexCount; }
1009
1010 bool onCombineIfPossible(GrBatch* t) SK_OVERRIDE {
1011 DrawVerticesBatch* that = t->cast<DrawVerticesBatch>();
1012
1013 if (!this->batchablePrimitiveType() || this->primitiveType() != that->pr imitiveType()) {
1014 return false;
1015 }
1016
1017 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
1018
1019 // We currently use a uniform viewmatrix for this batch
1020 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
1021 return false;
1022 }
1023
1024 if (this->hasColors() != that->hasColors()) {
1025 return false;
1026 }
1027
1028 if (this->hasIndices() != that->hasIndices()) {
1029 return false;
1030 }
1031
1032 if (this->hasLocalCoords() != that->hasLocalCoords()) {
1033 return false;
1034 }
1035
1036 if (!this->hasColors() && this->color() != that->color()) {
1037 return false;
1038 }
1039
1040 if (this->color() != that->color()) {
1041 fBatch.fColor = GrColor_ILLEGAL;
1042 }
1043 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ;
1044 fBatch.fVertexCount += that->vertexCount();
1045 fBatch.fIndexCount += that->indexCount();
1046 return true;
1047 }
1048
1049 struct BatchTracker {
1050 GrPrimitiveType fPrimitiveType;
1051 SkMatrix fViewMatrix;
1052 GrColor fColor;
1053 bool fUsesLocalCoords;
1054 bool fColorIgnored;
1055 bool fCoverageIgnored;
1056 bool fHasColors;
1057 bool fHasIndices;
1058 bool fHasLocalCoords;
1059 int fVertexCount;
1060 int fIndexCount;
1061 };
1062
1063 BatchTracker fBatch;
1064 SkSTArray<1, Geometry, true> fGeoData;
1065 };
1066
696 void GrContext::drawVertices(GrRenderTarget* rt, 1067 void GrContext::drawVertices(GrRenderTarget* rt,
697 const GrClip& clip, 1068 const GrClip& clip,
698 const GrPaint& paint, 1069 const GrPaint& paint,
699 const SkMatrix& viewMatrix, 1070 const SkMatrix& viewMatrix,
700 GrPrimitiveType primitiveType, 1071 GrPrimitiveType primitiveType,
701 int vertexCount, 1072 int vertexCount,
702 const SkPoint positions[], 1073 const SkPoint positions[],
703 const SkPoint texCoords[], 1074 const SkPoint texCoords[],
704 const GrColor colors[], 1075 const GrColor colors[],
705 const uint16_t indices[], 1076 const uint16_t indices[],
706 int indexCount) { 1077 int indexCount) {
707 RETURN_IF_ABANDONED 1078 RETURN_IF_ABANDONED
708 AutoCheckFlush acf(this); 1079 AutoCheckFlush acf(this);
709 GrPipelineBuilder pipelineBuilder; 1080 GrPipelineBuilder pipelineBuilder;
710 GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scop e 1081 GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scop e
711 1082
712 GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &pain t, &acf); 1083 GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &pain t, &acf);
713 if (NULL == target) { 1084 if (NULL == target) {
714 return; 1085 return;
715 } 1086 }
716 1087
717 GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target); 1088 GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target);
718 1089
719 int colorOffset = -1, texOffset = -1; 1090 DrawVerticesBatch::Geometry geometry;
720 SkAutoTUnref<const GrGeometryProcessor> gp( 1091 geometry.fColor = paint.getColor();
721 set_vertex_attributes(texCoords, colors, &colorOffset, &texOffset,
722 paint.getColor(), viewMatrix));
723 1092
724 size_t vertexStride = gp->getVertexStride(); 1093 SkAutoTUnref<GrBatch> batch(DrawVerticesBatch::Create(geometry, primitiveTyp e, viewMatrix,
725 SkASSERT(vertexStride == sizeof(SkPoint) + (SkToBool(texCoords) ? sizeof(SkP oint) : 0) 1094 positions, vertexCount , indices,
726 + (SkToBool(colors) ? sizeof(GrColo r) : 0)); 1095 indexCount,colors, tex Coords));
727 if (!geo.set(target, vertexCount, vertexStride, indexCount)) {
728 SkDebugf("Failed to get space for vertices!\n");
729 return;
730 }
731 void* curVertex = geo.vertices();
732 1096
733 for (int i = 0; i < vertexCount; ++i) { 1097 // TODO figure out bounds
734 *((SkPoint*)curVertex) = positions[i]; 1098 target->drawBatch(&pipelineBuilder, batch, NULL);
735
736 if (texOffset >= 0) {
737 *(SkPoint*)((intptr_t)curVertex + texOffset) = texCoords[i];
738 }
739 if (colorOffset >= 0) {
740 *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i];
741 }
742 curVertex = (void*)((intptr_t)curVertex + vertexStride);
743 }
744
745 // we don't currently apply offscreen AA to this path. Need improved
746 // management of GrDrawTarget's geometry to avoid copying points per-tile.
747 if (indices) {
748 uint16_t* curIndex = (uint16_t*)geo.indices();
749 for (int i = 0; i < indexCount; ++i) {
750 curIndex[i] = indices[i];
751 }
752 target->drawIndexed(&pipelineBuilder, gp, primitiveType, 0, 0, vertexCou nt, indexCount);
753 } else {
754 target->drawNonIndexed(&pipelineBuilder, gp, primitiveType, 0, vertexCou nt);
755 }
756 } 1099 }
757 1100
758 /////////////////////////////////////////////////////////////////////////////// 1101 ///////////////////////////////////////////////////////////////////////////////
759 1102
760 void GrContext::drawRRect(GrRenderTarget*rt, 1103 void GrContext::drawRRect(GrRenderTarget*rt,
761 const GrClip& clip, 1104 const GrClip& clip,
762 const GrPaint& paint, 1105 const GrPaint& paint,
763 const SkMatrix& viewMatrix, 1106 const SkMatrix& viewMatrix,
764 const SkRRect& rrect, 1107 const SkRRect& rrect,
765 const GrStrokeInfo& strokeInfo) { 1108 const GrStrokeInfo& strokeInfo) {
(...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after
1639 } 1982 }
1640 } 1983 }
1641 1984
1642 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { 1985 void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
1643 fGpu->removeGpuTraceMarker(marker); 1986 fGpu->removeGpuTraceMarker(marker);
1644 if (fDrawBuffer) { 1987 if (fDrawBuffer) {
1645 fDrawBuffer->removeGpuTraceMarker(marker); 1988 fDrawBuffer->removeGpuTraceMarker(marker);
1646 } 1989 }
1647 } 1990 }
1648 1991
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698