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; | |
robertphillips
2015/08/07 13:36:37
Can we remove 'fIndices' ?
jvanverth1
2015/08/07 15:55:17
Done.
| |
702 SkTDArray<uint16_t> fIndices; | |
703 SkTDArray<GrColor> fColors; | |
704 SkTDArray<SkPoint> fLocalCoords; | |
705 }; | |
706 | |
707 static GrBatch* Create(const Geometry& geometry, GrPrimitiveType primitiveTy pe, | |
708 const SkMatrix& viewMatrix, | |
709 const SkPoint* positions, int vertexCount, | |
710 const GrColor* colors, const SkPoint* localCoords, | |
711 const SkRect& bounds) { | |
712 return SkNEW_ARGS(DrawAtlasBatch, (geometry, primitiveType, viewMatrix, positions, | |
713 vertexCount, colors, localCoords, bou nds)); | |
714 } | |
715 | |
716 const char* name() const override { return "DrawAtlasBatch"; } | |
717 | |
718 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | |
719 // When this is called on a batch, there is only one geometry bundle | |
720 if (this->hasColors()) { | |
721 out->setUnknownFourComponents(); | |
722 } else { | |
723 out->setKnownFourComponents(fGeoData[0].fColor); | |
724 } | |
725 } | |
726 | |
727 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { | |
728 out->setKnownSingleComponent(0xff); | |
729 } | |
730 | |
731 void initBatchTracker(const GrPipelineInfo& init) override { | |
732 // Handle any color overrides | |
733 if (!init.readsColor()) { | |
734 fGeoData[0].fColor = GrColor_ILLEGAL; | |
735 } | |
736 init.getOverrideColorIfSet(&fGeoData[0].fColor); | |
737 | |
738 // setup batch properties | |
739 fBatch.fColorIgnored = !init.readsColor(); | |
740 fBatch.fColor = fGeoData[0].fColor; | |
741 fBatch.fUsesLocalCoords = init.readsLocalCoords(); | |
742 fBatch.fCoverageIgnored = !init.readsCoverage(); | |
743 } | |
744 | |
745 void generateGeometry(GrBatchTarget* batchTarget) override { | |
746 int colorOffset = -1, texOffset = -1; | |
747 // Setup geometry processor | |
748 SkAutoTUnref<const GrGeometryProcessor> gp( | |
749 set_vertex_attributes(true, this->hasColors(), & colorOffset, | |
750 &texOffset, this->color(), this->viewMatrix(), | |
751 this->coverageIgnored())); | |
752 | |
753 batchTarget->initDraw(gp, this->pipeline()); | |
754 | |
755 int instanceCount = fGeoData.count(); | |
756 size_t vertexStride = gp->getVertexStride(); | |
757 SkASSERT(vertexStride == sizeof(SkPoint) + sizeof(SkPoint) | |
758 + (this->hasColors() ? sizeof(GrColor) : 0)); | |
759 | |
760 QuadHelper helper; | |
761 int numQuads = this->vertexCount()/4; | |
762 void* verts = helper.init(batchTarget, vertexStride, numQuads); | |
763 if (!verts) { | |
764 SkDebugf("Could not allocate vertices\n"); | |
765 return; | |
766 } | |
767 | |
768 int vertexOffset = 0; | |
769 for (int i = 0; i < instanceCount; i++) { | |
770 const Geometry& args = fGeoData[i]; | |
771 | |
772 for (int j = 0; j < args.fPositions.count(); ++j) { | |
773 *((SkPoint*)verts) = args.fPositions[j]; | |
774 if (this->hasColors()) { | |
775 *(GrColor*)((intptr_t)verts + colorOffset) = args.fColors[j] ; | |
776 } | |
777 *(SkPoint*)((intptr_t)verts + texOffset) = args.fLocalCoords[j]; | |
778 verts = (void*)((intptr_t)verts + vertexStride); | |
779 vertexOffset++; | |
780 } | |
781 } | |
782 helper.issueDraw(batchTarget); | |
783 } | |
784 | |
785 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | |
786 | |
787 private: | |
788 DrawAtlasBatch(const Geometry& geometry, GrPrimitiveType primitiveType, | |
789 const SkMatrix& viewMatrix, | |
790 const SkPoint* positions, int vertexCount, | |
791 const GrColor* colors, const SkPoint* localCoords, const SkRe ct& bounds) { | |
792 this->initClassID<DrawVerticesBatch>(); | |
793 SkASSERT(positions); | |
794 SkASSERT(localCoords); | |
795 | |
796 fBatch.fViewMatrix = viewMatrix; | |
797 Geometry& installedGeo = fGeoData.push_back(geometry); | |
798 | |
799 installedGeo.fPositions.append(vertexCount, positions); | |
800 | |
801 if (colors) { | |
802 installedGeo.fColors.append(vertexCount, colors); | |
803 fBatch.fHasColors = true; | |
804 } else { | |
805 fBatch.fHasColors = false; | |
806 } | |
807 | |
808 installedGeo.fLocalCoords.append(vertexCount, localCoords); | |
809 fBatch.fVertexCount = vertexCount; | |
810 fBatch.fPrimitiveType = primitiveType; | |
811 | |
812 this->setBounds(bounds); | |
813 } | |
814 | |
815 GrPrimitiveType primitiveType() const { return fBatch.fPrimitiveType; } | |
816 bool batchablePrimitiveType() const { | |
robertphillips
2015/08/07 13:36:38
Don't we always know fPrimitiveType will be kTrian
jvanverth1
2015/08/07 15:55:17
Done.
| |
817 return kTriangles_GrPrimitiveType == fBatch.fPrimitiveType || | |
robertphillips
2015/08/07 13:36:37
tab these over ?
jvanverth1
2015/08/07 15:55:17
Removed.
| |
818 kLines_GrPrimitiveType == fBatch.fPrimitiveType || | |
819 kPoints_GrPrimitiveType == fBatch.fPrimitiveType; | |
820 } | |
821 GrColor color() const { return fBatch.fColor; } | |
robertphillips
2015/08/07 13:36:38
Can we just return true from 'usesLocalCoords' ?
jvanverth1
2015/08/07 15:55:17
Removed.
| |
822 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | |
823 bool colorIgnored() const { return fBatch.fColorIgnored; } | |
824 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } | |
825 bool hasColors() const { return fBatch.fHasColors; } | |
826 int vertexCount() const { return fBatch.fVertexCount; } | |
827 bool coverageIgnored() const { return fBatch.fCoverageIgnored; } | |
828 | |
829 bool onCombineIfPossible(GrBatch* t) override { | |
830 if (!this->pipeline()->isEqual(*t->pipeline())) { | |
831 return false; | |
832 } | |
833 | |
834 DrawAtlasBatch* that = t->cast<DrawAtlasBatch>(); | |
835 | |
robertphillips
2015/08/07 13:36:37
Can we skip this check ?
jvanverth1
2015/08/07 15:55:17
Done.
| |
836 if (!this->batchablePrimitiveType() || this->primitiveType() != that->pr imitiveType()) { | |
837 return false; | |
838 } | |
839 | |
840 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); | |
841 | |
842 // We currently use a uniform viewmatrix for this batch | |
843 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { | |
844 return false; | |
845 } | |
846 | |
robertphillips
2015/08/07 13:36:37
We could, in theory, generate white vertex colors
jvanverth1
2015/08/07 15:55:17
It's possible, though, so for now I think I'll lea
| |
847 if (this->hasColors() != that->hasColors()) { | |
848 return false; | |
849 } | |
850 | |
851 if (!this->hasColors() && this->color() != that->color()) { | |
852 return false; | |
853 } | |
854 | |
855 if (this->color() != that->color()) { | |
856 fBatch.fColor = GrColor_ILLEGAL; | |
857 } | |
858 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()) ; | |
859 fBatch.fVertexCount += that->vertexCount(); | |
860 | |
861 this->joinBounds(that->bounds()); | |
862 return true; | |
863 } | |
864 | |
865 struct BatchTracker { | |
866 GrPrimitiveType fPrimitiveType; | |
867 SkMatrix fViewMatrix; | |
868 GrColor fColor; | |
869 bool fUsesLocalCoords; | |
870 bool fColorIgnored; | |
871 bool fCoverageIgnored; | |
872 bool fHasColors; | |
873 int fVertexCount; | |
874 }; | |
875 | |
876 BatchTracker fBatch; | |
877 SkSTArray<1, Geometry, true> fGeoData; | |
878 }; | |
879 | |
880 void GrDrawContext::drawAtlas(GrRenderTarget* rt, | |
881 const GrClip& clip, | |
882 const GrPaint& paint, | |
883 const SkMatrix& viewMatrix, | |
884 int spriteCount, | |
885 const SkRSXform xform[], | |
886 const SkRect texRect[], | |
887 const SkColor colors[]) { | |
888 RETURN_IF_ABANDONED | |
889 AutoCheckFlush acf(fContext); | |
890 if (!this->prepareToDraw(rt)) { | |
891 return; | |
892 } | |
893 | |
894 GrPipelineBuilder pipelineBuilder(paint, rt, clip); | |
895 | |
896 // TODO clients should give us bounds | |
897 SkRect bounds; | |
robertphillips
2015/08/07 13:36:38
Hmmm ... I think you have to transform each texRec
jvanverth1
2015/08/07 15:55:17
Done. Moved to after we build the vertex locations
| |
898 if (!bounds.setBoundsCheck(reinterpret_cast<const SkPoint*>(texRect), 2*spri teCount)) { | |
899 SkDebugf("drawAtlas call empty bounds\n"); | |
900 return; | |
901 } | |
902 | |
903 viewMatrix.mapRect(&bounds); | |
904 | |
905 // If we don't have AA then we outset for a half pixel in each direction to account for | |
906 // snapping | |
907 if (!paint.isAntiAlias()) { | |
908 bounds.outset(0.5f, 0.5f); | |
909 } | |
910 | |
robertphillips
2015/08/07 13:36:38
Is the plan to interleave here ?
jvanverth1
2015/08/07 15:55:17
The plan is that the interleaving will happen when
| |
911 // now build the renderable geometry | |
912 const int vertCount = spriteCount * 4; | |
913 SkAutoTMalloc<SkPoint> vertStorage(vertCount * 2); | |
914 SkPoint* verts = vertStorage.get(); | |
915 SkPoint* texs = verts + vertCount; | |
916 | |
917 for (int i = 0; i < spriteCount; ++i) { | |
918 xform[i].toQuad(texRect[i].width(), texRect[i].height(), verts); | |
919 texRect[i].toQuad(texs); | |
920 verts += 4; | |
921 texs += 4; | |
922 } | |
923 | |
924 SkAutoTMalloc<GrColor> colorStorage; | |
925 GrColor* vertCols = NULL; | |
926 if (colors) { | |
927 colorStorage.reset(vertCount); | |
928 vertCols = colorStorage.get(); | |
929 | |
930 int paintAlpha = GrColorUnpackA(paint.getColor()); | |
931 | |
932 // need to convert byte order and from non-PM to PM | |
933 for (int i = 0; i < spriteCount; ++i) { | |
934 SkColor color = colors[i]; | |
935 if (paintAlpha != 255) { | |
936 color = SkColorSetA(color, SkMulDiv255Round(SkColorGetA(color), paintAlpha)); | |
937 } | |
938 GrColor grColor = SkColor2GrColor(color); | |
939 | |
robertphillips
2015/08/07 13:36:37
:(
jvanverth1
2015/08/07 15:55:17
Acknowledged.
| |
940 vertCols[0] = vertCols[1] = vertCols[2] = vertCols[3] = grColor; | |
941 vertCols += 4; | |
942 } | |
943 } | |
944 | |
945 verts = vertStorage.get(); | |
946 texs = verts + vertCount; | |
947 vertCols = colorStorage.get(); | |
948 | |
949 DrawAtlasBatch::Geometry geometry; | |
950 geometry.fColor = paint.getColor(); | |
951 SkAutoTUnref<GrBatch> batch(DrawAtlasBatch::Create(geometry, kTriangles_GrPr imitiveType, | |
952 viewMatrix, verts, vertCo unt, vertCols, texs, | |
953 bounds)); | |
954 | |
955 fDrawTarget->drawBatch(pipelineBuilder, batch); | |
956 } | |
957 | |
958 /////////////////////////////////////////////////////////////////////////////// | |
959 | |
693 void GrDrawContext::drawRRect(GrRenderTarget*rt, | 960 void GrDrawContext::drawRRect(GrRenderTarget*rt, |
694 const GrClip& clip, | 961 const GrClip& clip, |
695 const GrPaint& paint, | 962 const GrPaint& paint, |
696 const SkMatrix& viewMatrix, | 963 const SkMatrix& viewMatrix, |
697 const SkRRect& rrect, | 964 const SkRRect& rrect, |
698 const GrStrokeInfo& strokeInfo) { | 965 const GrStrokeInfo& strokeInfo) { |
699 RETURN_IF_ABANDONED | 966 RETURN_IF_ABANDONED |
700 if (rrect.isEmpty()) { | 967 if (rrect.isEmpty()) { |
701 return; | 968 return; |
702 } | 969 } |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1134 return DrawVerticesBatch::Create(geometry, type, viewMatrix, | 1401 return DrawVerticesBatch::Create(geometry, type, viewMatrix, |
1135 positions.begin(), vertexCount, | 1402 positions.begin(), vertexCount, |
1136 indices.begin(), hasIndices ? vertexCount : 0, | 1403 indices.begin(), hasIndices ? vertexCount : 0, |
1137 colors.begin(), | 1404 colors.begin(), |
1138 texCoords.begin(), | 1405 texCoords.begin(), |
1139 bounds); | 1406 bounds); |
1140 } | 1407 } |
1141 | 1408 |
1142 #endif | 1409 #endif |
1143 | 1410 |
OLD | NEW |