OLD | NEW |
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 "GrBatch.h" | 11 #include "GrBatch.h" |
12 #include "GrBatchTest.h" | 12 #include "GrBatchTest.h" |
| 13 #include "GrColor.h" |
13 #include "GrDefaultGeoProcFactory.h" | 14 #include "GrDefaultGeoProcFactory.h" |
14 #include "GrDrawContext.h" | 15 #include "GrDrawContext.h" |
15 #include "GrOvalRenderer.h" | 16 #include "GrOvalRenderer.h" |
16 #include "GrPathRenderer.h" | 17 #include "GrPathRenderer.h" |
17 #include "GrRenderTarget.h" | 18 #include "GrRenderTarget.h" |
18 #include "GrRenderTargetPriv.h" | 19 #include "GrRenderTargetPriv.h" |
19 #include "GrStrokeRectBatch.h" | 20 #include "GrStrokeRectBatch.h" |
20 #include "GrStencilAndCoverTextContext.h" | 21 #include "GrStencilAndCoverTextContext.h" |
21 | 22 |
| 23 #include "SkGr.h" |
| 24 #include "SkRSXform.h" |
| 25 |
22 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fContext) | 26 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fContext) |
23 #define RETURN_IF_ABANDONED if (!fDrawTarget) { return; } | 27 #define RETURN_IF_ABANDONED if (!fDrawTarget) { return; } |
24 #define RETURN_FALSE_IF_ABANDONED if (!fDrawTarget) { return false; } | 28 #define RETURN_FALSE_IF_ABANDONED if (!fDrawTarget) { return false; } |
25 #define RETURN_NULL_IF_ABANDONED if (!fDrawTarget) { return NULL; } | 29 #define RETURN_NULL_IF_ABANDONED if (!fDrawTarget) { return NULL; } |
26 | 30 |
27 class AutoCheckFlush { | 31 class AutoCheckFlush { |
28 public: | 32 public: |
29 AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context);
} | 33 AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context);
} |
30 ~AutoCheckFlush() { fContext->flushIfNecessary(); } | 34 ~AutoCheckFlush() { fContext->flushIfNecessary(); } |
31 | 35 |
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 SkAutoTUnref<GrBatch> batch(DrawVerticesBatch::Create(geometry, primitiveTyp
e, viewMatrix, | 687 SkAutoTUnref<GrBatch> batch(DrawVerticesBatch::Create(geometry, primitiveTyp
e, viewMatrix, |
684 positions, vertexCount
, indices, | 688 positions, vertexCount
, indices, |
685 indexCount, colors, te
xCoords, | 689 indexCount, colors, te
xCoords, |
686 bounds)); | 690 bounds)); |
687 | 691 |
688 fDrawTarget->drawBatch(pipelineBuilder, batch); | 692 fDrawTarget->drawBatch(pipelineBuilder, batch); |
689 } | 693 } |
690 | 694 |
691 /////////////////////////////////////////////////////////////////////////////// | 695 /////////////////////////////////////////////////////////////////////////////// |
692 | 696 |
| 697 class DrawAtlasBatch : public GrBatch { |
| 698 public: |
| 699 struct Geometry { |
| 700 GrColor fColor; |
| 701 SkTDArray<SkPoint> fPositions; |
| 702 SkTDArray<GrColor> fColors; |
| 703 SkTDArray<SkPoint> fLocalCoords; |
| 704 }; |
| 705 |
| 706 static GrBatch* Create(const Geometry& geometry, const SkMatrix& viewMatrix, |
| 707 const SkPoint* positions, int vertexCount, |
| 708 const GrColor* colors, const SkPoint* localCoords, |
| 709 const SkRect& bounds) { |
| 710 return SkNEW_ARGS(DrawAtlasBatch, (geometry, viewMatrix, positions, |
| 711 vertexCount, colors, localCoords, bou
nds)); |
| 712 } |
| 713 |
| 714 const char* name() const override { return "DrawAtlasBatch"; } |
| 715 |
| 716 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
| 717 // When this is called on a batch, there is only one geometry bundle |
| 718 if (this->hasColors()) { |
| 719 out->setUnknownFourComponents(); |
| 720 } else { |
| 721 out->setKnownFourComponents(fGeoData[0].fColor); |
| 722 } |
| 723 } |
| 724 |
| 725 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
| 726 out->setKnownSingleComponent(0xff); |
| 727 } |
| 728 |
| 729 void initBatchTracker(const GrPipelineInfo& init) override { |
| 730 // Handle any color overrides |
| 731 if (!init.readsColor()) { |
| 732 fGeoData[0].fColor = GrColor_ILLEGAL; |
| 733 } |
| 734 init.getOverrideColorIfSet(&fGeoData[0].fColor); |
| 735 |
| 736 // setup batch properties |
| 737 fColorIgnored = !init.readsColor(); |
| 738 fColor = fGeoData[0].fColor; |
| 739 SkASSERT(init.readsLocalCoords()); |
| 740 fCoverageIgnored = !init.readsCoverage(); |
| 741 } |
| 742 |
| 743 void generateGeometry(GrBatchTarget* batchTarget) override { |
| 744 int colorOffset = -1, texOffset = -1; |
| 745 // Setup geometry processor |
| 746 SkAutoTUnref<const GrGeometryProcessor> gp( |
| 747 set_vertex_attributes(true, this->hasColors(), &
colorOffset, |
| 748 &texOffset, this->color(),
this->viewMatrix(), |
| 749 this->coverageIgnored())); |
| 750 |
| 751 batchTarget->initDraw(gp, this->pipeline()); |
| 752 |
| 753 int instanceCount = fGeoData.count(); |
| 754 size_t vertexStride = gp->getVertexStride(); |
| 755 SkASSERT(vertexStride == sizeof(SkPoint) + sizeof(SkPoint) |
| 756 + (this->hasColors() ? sizeof(GrColor) : 0)); |
| 757 |
| 758 QuadHelper helper; |
| 759 int numQuads = this->vertexCount()/4; |
| 760 void* verts = helper.init(batchTarget, vertexStride, numQuads); |
| 761 if (!verts) { |
| 762 SkDebugf("Could not allocate vertices\n"); |
| 763 return; |
| 764 } |
| 765 |
| 766 int vertexOffset = 0; |
| 767 for (int i = 0; i < instanceCount; i++) { |
| 768 const Geometry& args = fGeoData[i]; |
| 769 |
| 770 for (int j = 0; j < args.fPositions.count(); ++j) { |
| 771 *((SkPoint*)verts) = args.fPositions[j]; |
| 772 if (this->hasColors()) { |
| 773 *(GrColor*)((intptr_t)verts + colorOffset) = args.fColors[j]
; |
| 774 } |
| 775 *(SkPoint*)((intptr_t)verts + texOffset) = args.fLocalCoords[j]; |
| 776 verts = (void*)((intptr_t)verts + vertexStride); |
| 777 vertexOffset++; |
| 778 } |
| 779 } |
| 780 helper.issueDraw(batchTarget); |
| 781 } |
| 782 |
| 783 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
| 784 |
| 785 private: |
| 786 DrawAtlasBatch(const Geometry& geometry, const SkMatrix& viewMatrix, |
| 787 const SkPoint* positions, int vertexCount, |
| 788 const GrColor* colors, const SkPoint* localCoords, const SkRe
ct& bounds) { |
| 789 this->initClassID<DrawVerticesBatch>(); |
| 790 SkASSERT(positions); |
| 791 SkASSERT(localCoords); |
| 792 |
| 793 fViewMatrix = viewMatrix; |
| 794 Geometry& installedGeo = fGeoData.push_back(geometry); |
| 795 |
| 796 installedGeo.fPositions.append(vertexCount, positions); |
| 797 |
| 798 if (colors) { |
| 799 installedGeo.fColors.append(vertexCount, colors); |
| 800 fHasColors = true; |
| 801 } else { |
| 802 fHasColors = false; |
| 803 } |
| 804 |
| 805 installedGeo.fLocalCoords.append(vertexCount, localCoords); |
| 806 fVertexCount = vertexCount; |
| 807 |
| 808 this->setBounds(bounds); |
| 809 } |
| 810 |
| 811 GrColor color() const { return fColor; } |
| 812 bool colorIgnored() const { return fColorIgnored; } |
| 813 const SkMatrix& viewMatrix() const { return fViewMatrix; } |
| 814 bool hasColors() const { return fHasColors; } |
| 815 int vertexCount() const { return fVertexCount; } |
| 816 bool coverageIgnored() const { return fCoverageIgnored; } |
| 817 |
| 818 bool onCombineIfPossible(GrBatch* t) override { |
| 819 if (!this->pipeline()->isEqual(*t->pipeline())) { |
| 820 return false; |
| 821 } |
| 822 |
| 823 DrawAtlasBatch* that = t->cast<DrawAtlasBatch>(); |
| 824 |
| 825 // We currently use a uniform viewmatrix for this batch |
| 826 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { |
| 827 return false; |
| 828 } |
| 829 |
| 830 if (this->hasColors() != that->hasColors()) { |
| 831 return false; |
| 832 } |
| 833 |
| 834 if (!this->hasColors() && this->color() != that->color()) { |
| 835 return false; |
| 836 } |
| 837 |
| 838 if (this->color() != that->color()) { |
| 839 fColor = GrColor_ILLEGAL; |
| 840 } |
| 841 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; |
| 842 fVertexCount += that->vertexCount(); |
| 843 |
| 844 this->joinBounds(that->bounds()); |
| 845 return true; |
| 846 } |
| 847 |
| 848 SkSTArray<1, Geometry, true> fGeoData; |
| 849 |
| 850 SkMatrix fViewMatrix; |
| 851 GrColor fColor; |
| 852 int fVertexCount; |
| 853 bool fColorIgnored; |
| 854 bool fCoverageIgnored; |
| 855 bool fHasColors; |
| 856 }; |
| 857 |
| 858 void GrDrawContext::drawAtlas(GrRenderTarget* rt, |
| 859 const GrClip& clip, |
| 860 const GrPaint& paint, |
| 861 const SkMatrix& viewMatrix, |
| 862 int spriteCount, |
| 863 const SkRSXform xform[], |
| 864 const SkRect texRect[], |
| 865 const SkColor colors[]) { |
| 866 RETURN_IF_ABANDONED |
| 867 AutoCheckFlush acf(fContext); |
| 868 if (!this->prepareToDraw(rt)) { |
| 869 return; |
| 870 } |
| 871 |
| 872 GrPipelineBuilder pipelineBuilder(paint, rt, clip); |
| 873 |
| 874 // now build the renderable geometry |
| 875 const int vertCount = spriteCount * 4; |
| 876 SkAutoTMalloc<SkPoint> vertStorage(vertCount * 2); |
| 877 SkPoint* verts = vertStorage.get(); |
| 878 SkPoint* texs = verts + vertCount; |
| 879 |
| 880 for (int i = 0; i < spriteCount; ++i) { |
| 881 xform[i].toQuad(texRect[i].width(), texRect[i].height(), verts); |
| 882 texRect[i].toQuad(texs); |
| 883 verts += 4; |
| 884 texs += 4; |
| 885 } |
| 886 |
| 887 // TODO clients should give us bounds |
| 888 SkRect bounds; |
| 889 if (!bounds.setBoundsCheck(vertStorage.get(), vertCount)) { |
| 890 SkDebugf("drawAtlas call empty bounds\n"); |
| 891 return; |
| 892 } |
| 893 |
| 894 viewMatrix.mapRect(&bounds); |
| 895 |
| 896 // If we don't have AA then we outset for a half pixel in each direction to
account for |
| 897 // snapping |
| 898 if (!paint.isAntiAlias()) { |
| 899 bounds.outset(0.5f, 0.5f); |
| 900 } |
| 901 |
| 902 SkAutoTMalloc<GrColor> colorStorage; |
| 903 GrColor* vertCols = NULL; |
| 904 if (colors) { |
| 905 colorStorage.reset(vertCount); |
| 906 vertCols = colorStorage.get(); |
| 907 |
| 908 int paintAlpha = GrColorUnpackA(paint.getColor()); |
| 909 |
| 910 // need to convert byte order and from non-PM to PM |
| 911 for (int i = 0; i < spriteCount; ++i) { |
| 912 SkColor color = colors[i]; |
| 913 if (paintAlpha != 255) { |
| 914 color = SkColorSetA(color, SkMulDiv255Round(SkColorGetA(color),
paintAlpha)); |
| 915 } |
| 916 GrColor grColor = SkColor2GrColor(color); |
| 917 |
| 918 vertCols[0] = vertCols[1] = vertCols[2] = vertCols[3] = grColor; |
| 919 vertCols += 4; |
| 920 } |
| 921 } |
| 922 |
| 923 verts = vertStorage.get(); |
| 924 texs = verts + vertCount; |
| 925 vertCols = colorStorage.get(); |
| 926 |
| 927 DrawAtlasBatch::Geometry geometry; |
| 928 geometry.fColor = paint.getColor(); |
| 929 SkAutoTUnref<GrBatch> batch(DrawAtlasBatch::Create(geometry, viewMatrix, ver
ts, vertCount, |
| 930 vertCols, texs, bounds)); |
| 931 |
| 932 fDrawTarget->drawBatch(pipelineBuilder, batch); |
| 933 } |
| 934 |
| 935 /////////////////////////////////////////////////////////////////////////////// |
| 936 |
693 void GrDrawContext::drawRRect(GrRenderTarget*rt, | 937 void GrDrawContext::drawRRect(GrRenderTarget*rt, |
694 const GrClip& clip, | 938 const GrClip& clip, |
695 const GrPaint& paint, | 939 const GrPaint& paint, |
696 const SkMatrix& viewMatrix, | 940 const SkMatrix& viewMatrix, |
697 const SkRRect& rrect, | 941 const SkRRect& rrect, |
698 const GrStrokeInfo& strokeInfo) { | 942 const GrStrokeInfo& strokeInfo) { |
699 RETURN_IF_ABANDONED | 943 RETURN_IF_ABANDONED |
700 if (rrect.isEmpty()) { | 944 if (rrect.isEmpty()) { |
701 return; | 945 return; |
702 } | 946 } |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 return DrawVerticesBatch::Create(geometry, type, viewMatrix, | 1378 return DrawVerticesBatch::Create(geometry, type, viewMatrix, |
1135 positions.begin(), vertexCount, | 1379 positions.begin(), vertexCount, |
1136 indices.begin(), hasIndices ? vertexCount :
0, | 1380 indices.begin(), hasIndices ? vertexCount :
0, |
1137 colors.begin(), | 1381 colors.begin(), |
1138 texCoords.begin(), | 1382 texCoords.begin(), |
1139 bounds); | 1383 bounds); |
1140 } | 1384 } |
1141 | 1385 |
1142 #endif | 1386 #endif |
1143 | 1387 |
OLD | NEW |