OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrNinePatch.h" | 8 #include "GrNinePatch.h" |
9 | 9 |
10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 LocalCoords localCoords(LocalCoords::kHasExplicit_Type); | 22 LocalCoords localCoords(LocalCoords::kHasExplicit_Type); |
23 return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, SkMatrix:
:I()); | 23 return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, SkMatrix:
:I()); |
24 } | 24 } |
25 | 25 |
26 class GrNonAANinePatchBatch : public GrVertexBatch { | 26 class GrNonAANinePatchBatch : public GrVertexBatch { |
27 public: | 27 public: |
28 DEFINE_BATCH_CLASS_ID | 28 DEFINE_BATCH_CLASS_ID |
29 | 29 |
30 static const int kVertsPerRect = 4; | 30 static const int kVertsPerRect = 4; |
31 static const int kIndicesPerRect = 6; | 31 static const int kIndicesPerRect = 6; |
| 32 static const int kRectsPerInstance = 9; // We could skip empty rects |
32 | 33 |
33 GrNonAANinePatchBatch(GrColor color, const SkMatrix& viewMatrix, int imageWi
dth, | 34 GrNonAANinePatchBatch(GrColor color, const SkMatrix& viewMatrix, int imageWi
dth, |
34 int imageHeight, std::unique_ptr<SkLatticeIter> iter,
const SkRect &dst) | 35 int imageHeight, const SkIRect& center, const SkRect &
dst) |
35 : INHERITED(ClassID()) { | 36 : INHERITED(ClassID()) { |
36 Patch& patch = fPatches.push_back(); | 37 Patch& patch = fPatches.push_back(); |
37 patch.fViewMatrix = viewMatrix; | 38 patch.fViewMatrix = viewMatrix; |
38 patch.fColor = color; | 39 patch.fColor = color; |
39 patch.fIter = std::move(iter); | 40 patch.fCenter = center; |
40 patch.fDst = dst; | 41 patch.fDst = dst; |
41 | 42 |
42 fImageWidth = imageWidth; | 43 fImageWidth = imageWidth; |
43 fImageHeight = imageHeight; | 44 fImageHeight = imageHeight; |
44 | 45 |
45 // setup bounds | 46 // setup bounds |
46 this->setTransformedBounds(patch.fDst, viewMatrix, HasAABloat::kNo, IsZe
roArea::kNo); | 47 this->setTransformedBounds(patch.fDst, viewMatrix, HasAABloat::kNo, IsZe
roArea::kNo); |
47 } | 48 } |
48 | 49 |
49 const char* name() const override { return "NonAANinePatchBatch"; } | 50 const char* name() const override { return "NonAANinePatchBatch"; } |
50 | 51 |
51 SkString dumpInfo() const override { | 52 SkString dumpInfo() const override { |
52 SkString str; | 53 SkString str; |
53 | 54 |
54 for (int i = 0; i < fPatches.count(); ++i) { | 55 for (int i = 0; i < fPatches.count(); ++i) { |
55 str.appendf("%d: Color: 0x%08x Dst [L: %.2f, T: %.2f, R: %.2f, B: %.
2f]\n", | 56 str.appendf("%d: Color: 0x%08x Center [L: %d, T: %d, R: %d, B: %d],
" |
| 57 "Dst [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", |
56 i, | 58 i, |
57 fPatches[i].fColor, | 59 fPatches[i].fColor, |
| 60 fPatches[i].fCenter.fLeft, fPatches[i].fCenter.fTop, |
| 61 fPatches[i].fCenter.fRight, fPatches[i].fCenter.fBottom, |
58 fPatches[i].fDst.fLeft, fPatches[i].fDst.fTop, | 62 fPatches[i].fDst.fLeft, fPatches[i].fDst.fTop, |
59 fPatches[i].fDst.fRight, fPatches[i].fDst.fBottom); | 63 fPatches[i].fDst.fRight, fPatches[i].fDst.fBottom); |
60 } | 64 } |
61 | 65 |
62 str.append(INHERITED::dumpInfo()); | 66 str.append(INHERITED::dumpInfo()); |
63 return str; | 67 return str; |
64 } | 68 } |
65 | 69 |
66 void computePipelineOptimizations(GrInitInvariantOutput* color, | 70 void computePipelineOptimizations(GrInitInvariantOutput* color, |
67 GrInitInvariantOutput* coverage, | 71 GrInitInvariantOutput* coverage, |
68 GrBatchToXPOverrides* overrides) const ove
rride { | 72 GrBatchToXPOverrides* overrides) const ove
rride { |
69 color->setUnknownFourComponents(); | 73 color->setUnknownFourComponents(); |
70 coverage->setKnownSingleComponent(0xff); | 74 coverage->setKnownSingleComponent(0xff); |
71 } | 75 } |
72 | 76 |
73 private: | 77 private: |
74 void onPrepareDraws(Target* target) const override { | 78 void onPrepareDraws(Target* target) const override { |
75 sk_sp<GrGeometryProcessor> gp(create_gp(fOverrides.readsCoverage())); | 79 sk_sp<GrGeometryProcessor> gp(create_gp(fOverrides.readsCoverage())); |
76 if (!gp) { | 80 if (!gp) { |
77 SkDebugf("Couldn't create GrGeometryProcessor\n"); | 81 SkDebugf("Couldn't create GrGeometryProcessor\n"); |
78 return; | 82 return; |
79 } | 83 } |
80 | 84 |
81 size_t vertexStride = gp->getVertexStride(); | 85 size_t vertexStride = gp->getVertexStride(); |
82 int patchCnt = fPatches.count(); | 86 int patchCnt = fPatches.count(); |
83 int numRects = 0; | |
84 for (int i = 0; i < patchCnt; i++) { | |
85 numRects += fPatches[i].fIter->numRects(); | |
86 } | |
87 | 87 |
88 SkAutoTUnref<const GrBuffer> indexBuffer( | 88 SkAutoTUnref<const GrBuffer> indexBuffer( |
89 target->resourceProvider()->refQuadIndexBuffer()); | 89 target->resourceProvider()->refQuadIndexBuffer()); |
90 InstancedHelper helper; | 90 InstancedHelper helper; |
91 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, | 91 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, |
92 indexBuffer, kVertsPerRect, | 92 indexBuffer, kVertsPerRect, |
93 kIndicesPerRect, patchCnt * numRects); | 93 kIndicesPerRect, patchCnt * kRectsPerInstan
ce); |
94 if (!vertices || !indexBuffer) { | 94 if (!vertices || !indexBuffer) { |
95 SkDebugf("Could not allocate vertices\n"); | 95 SkDebugf("Could not allocate vertices\n"); |
96 return; | 96 return; |
97 } | 97 } |
98 | 98 |
99 intptr_t verts = reinterpret_cast<intptr_t>(vertices); | |
100 for (int i = 0; i < patchCnt; i++) { | 99 for (int i = 0; i < patchCnt; i++) { |
| 100 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + |
| 101 i * kRectsPerInstance * kVertsPerRect * vertexStrid
e; |
| 102 |
101 const Patch& patch = fPatches[i]; | 103 const Patch& patch = fPatches[i]; |
102 | 104 SkLatticeIter iter(fImageWidth, fImageHeight, patch.fCenter, patch.f
Dst); |
103 // Apply the view matrix here if it is scale-translate. Otherwise,
we need to | |
104 // wait until we've created the dst rects. | |
105 bool isScaleTranslate = patch.fViewMatrix.isScaleTranslate(); | |
106 if (isScaleTranslate) { | |
107 patch.fIter->mapDstScaleTranslate(patch.fViewMatrix); | |
108 } | |
109 | 105 |
110 SkRect srcR, dstR; | 106 SkRect srcR, dstR; |
111 intptr_t patchVerts = verts; | 107 while (iter.next(&srcR, &dstR)) { |
112 while (patch.fIter->next(&srcR, &dstR)) { | |
113 SkPoint* positions = reinterpret_cast<SkPoint*>(verts); | 108 SkPoint* positions = reinterpret_cast<SkPoint*>(verts); |
| 109 |
114 positions->setRectFan(dstR.fLeft, dstR.fTop, | 110 positions->setRectFan(dstR.fLeft, dstR.fTop, |
115 dstR.fRight, dstR.fBottom, vertexStride); | 111 dstR.fRight, dstR.fBottom, vertexStride); |
116 | 112 |
| 113 SkASSERT(!patch.fViewMatrix.hasPerspective()); |
| 114 patch.fViewMatrix.mapPointsWithStride(positions, vertexStride, k
VertsPerRect); |
| 115 |
117 // Setup local coords | 116 // Setup local coords |
118 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor
); | 117 static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor
); |
119 SkPoint* coords = reinterpret_cast<SkPoint*>(verts + kLocalOffse
t); | 118 SkPoint* coords = reinterpret_cast<SkPoint*>(verts + kLocalOffse
t); |
120 coords->setRectFan(srcR.fLeft, srcR.fTop, srcR.fRight, srcR.fBot
tom, vertexStride); | 119 coords->setRectFan(srcR.fLeft, srcR.fTop, srcR.fRight, srcR.fBot
tom, vertexStride); |
121 | 120 |
122 static const int kColorOffset = sizeof(SkPoint); | 121 static const int kColorOffset = sizeof(SkPoint); |
123 GrColor* vertColor = reinterpret_cast<GrColor*>(verts + kColorOf
fset); | 122 GrColor* vertColor = reinterpret_cast<GrColor*>(verts + kColorOf
fset); |
124 for (int j = 0; j < 4; ++j) { | 123 for (int j = 0; j < 4; ++j) { |
125 *vertColor = patch.fColor; | 124 *vertColor = patch.fColor; |
126 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride)
; | 125 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride)
; |
127 } | 126 } |
128 verts += kVertsPerRect * vertexStride; | 127 verts += kVertsPerRect * vertexStride; |
129 } | 128 } |
130 | |
131 // If we didn't handle it above, apply the matrix here. | |
132 if (!isScaleTranslate) { | |
133 SkPoint* positions = reinterpret_cast<SkPoint*>(patchVerts); | |
134 patch.fViewMatrix.mapPointsWithStride(positions, vertexStride, | |
135 kVertsPerRect * patch.fIte
r->numRects()); | |
136 } | |
137 } | 129 } |
138 helper.recordDraw(target, gp.get()); | 130 helper.recordDraw(target, gp.get()); |
139 } | 131 } |
140 | 132 |
141 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | 133 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
142 overrides.getOverrideColorIfSet(&fPatches[0].fColor); | 134 overrides.getOverrideColorIfSet(&fPatches[0].fColor); |
143 fOverrides = overrides; | 135 fOverrides = overrides; |
144 } | 136 } |
145 | 137 |
146 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 138 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
147 GrNonAANinePatchBatch* that = t->cast<GrNonAANinePatchBatch>(); | 139 GrNonAANinePatchBatch* that = t->cast<GrNonAANinePatchBatch>(); |
148 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | 140 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
149 that->bounds(), caps)) { | 141 that->bounds(), caps)) { |
150 return false; | 142 return false; |
151 } | 143 } |
152 | 144 |
153 SkASSERT(this->fImageWidth == that->fImageWidth && | 145 SkASSERT(this->fImageWidth == that->fImageWidth && |
154 this->fImageHeight == that->fImageHeight); | 146 this->fImageHeight == that->fImageHeight); |
155 | 147 |
156 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to | 148 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to |
157 // not tweaking | 149 // not tweaking |
158 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { | 150 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { |
159 fOverrides = that->fOverrides; | 151 fOverrides = that->fOverrides; |
160 } | 152 } |
161 | 153 |
162 fPatches.move_back_n(that->fPatches.count(), that->fPatches.begin()); | 154 fPatches.push_back_n(that->fPatches.count(), that->fPatches.begin()); |
163 this->joinBounds(*that); | 155 this->joinBounds(*that); |
164 return true; | 156 return true; |
165 } | 157 } |
166 | 158 |
167 struct Patch { | 159 struct Patch { |
168 SkMatrix fViewMatrix; | 160 SkMatrix fViewMatrix; |
169 std::unique_ptr<SkLatticeIter> fIter; | 161 SkIRect fCenter; |
170 SkRect fDst; | 162 SkRect fDst; |
171 GrColor fColor; | 163 GrColor fColor; |
172 }; | 164 }; |
173 | 165 |
174 GrXPOverridesForBatch fOverrides; | 166 GrXPOverridesForBatch fOverrides; |
175 int fImageWidth; | 167 int fImageWidth; |
176 int fImageHeight; | 168 int fImageHeight; |
177 SkSTArray<1, Patch, true> fPatches; | 169 SkSTArray<1, Patch, true> fPatches; |
178 | 170 |
179 typedef GrVertexBatch INHERITED; | 171 typedef GrVertexBatch INHERITED; |
180 }; | 172 }; |
181 | 173 |
182 namespace GrNinePatch { | 174 namespace GrNinePatch { |
183 GrDrawBatch* CreateNonAA(GrColor color, const SkMatrix& viewMatrix, int imageWid
th, int imageHeight, | 175 GrDrawBatch* CreateNonAA(GrColor color, const SkMatrix& viewMatrix, int imageWid
th, int imageHeight, |
184 std::unique_ptr<SkLatticeIter> iter, const SkRect& dst)
{ | 176 const SkIRect& center, const SkRect& dst) { |
185 return new GrNonAANinePatchBatch(color, viewMatrix, imageWidth, imageHeight,
std::move(iter), | 177 return new GrNonAANinePatchBatch(color, viewMatrix, imageWidth, imageHeight,
center, dst); |
186 dst); | |
187 } | 178 } |
188 }; | 179 }; |
OLD | NEW |