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

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

Issue 1277933003: First pass at drawAtlas batching. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix comment 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 | « include/gpu/GrDrawContext.h ('k') | src/gpu/SkGpuDevice.cpp » ('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 "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
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
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
OLDNEW
« no previous file with comments | « include/gpu/GrDrawContext.h ('k') | src/gpu/SkGpuDevice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698