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 "GrDrawPathBatch.h" | 8 #include "GrDrawPathBatch.h" |
9 | 9 |
| 10 #include "GrRenderTargetPriv.h" |
| 11 |
10 static void pre_translate_transform_values(const float* xforms, | 12 static void pre_translate_transform_values(const float* xforms, |
11 GrPathRendering::PathTransformType ty
pe, int count, | 13 GrPathRendering::PathTransformType ty
pe, int count, |
12 SkScalar x, SkScalar y, float* dst); | 14 SkScalar x, SkScalar y, float* dst); |
13 | 15 |
| 16 void GrDrawPathBatchBase::onPrepare(GrBatchFlushState*) { |
| 17 const GrRenderTargetPriv& rtPriv = this->pipeline()->getRenderTarget()->rend
erTargetPriv(); |
| 18 fStencilPassSettings.reset(GrPathRendering::GetStencilPassSettings(fFillType
), |
| 19 this->pipeline()->hasStencilClip(), rtPriv.numSte
ncilBits()); |
| 20 } |
| 21 |
14 SkString GrDrawPathBatch::dumpInfo() const { | 22 SkString GrDrawPathBatch::dumpInfo() const { |
15 SkString string; | 23 SkString string; |
16 string.printf("PATH: 0x%p", fPath.get()); | 24 string.printf("PATH: 0x%p", fPath.get()); |
17 return string; | 25 return string; |
18 } | 26 } |
19 | 27 |
20 void GrDrawPathBatch::onDraw(GrBatchFlushState* state) { | 28 void GrDrawPathBatch::onDraw(GrBatchFlushState* state) { |
21 GrProgramDesc desc; | 29 GrProgramDesc desc; |
22 | 30 |
23 SkAutoTUnref<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color()
, | 31 SkAutoTUnref<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color()
, |
24 this->overrid
es(), | 32 this->overrid
es(), |
25 this->viewMat
rix())); | 33 this->viewMat
rix())); |
26 state->gpu()->pathRendering()->drawPath(*this->pipeline(), *pathProc, this->
stencilSettings(), | 34 state->gpu()->pathRendering()->drawPath(*this->pipeline(), *pathProc, |
27 fPath.get()); | 35 this->stencilPassSettings(), fPath.g
et()); |
28 } | 36 } |
29 | 37 |
30 SkString GrDrawPathRangeBatch::dumpInfo() const { | 38 SkString GrDrawPathRangeBatch::dumpInfo() const { |
31 SkString string; | 39 SkString string; |
32 string.printf("RANGE: 0x%p COUNTS: [", fPathRange.get()); | 40 string.printf("RANGE: 0x%p COUNTS: [", fPathRange.get()); |
33 for (DrawList::Iter iter(fDraws); iter.get(); iter.next()) { | 41 for (DrawList::Iter iter(fDraws); iter.get(); iter.next()) { |
34 string.appendf("%d, ", iter.get()->fInstanceData->count()); | 42 string.appendf("%d, ", iter.get()->fInstanceData->count()); |
35 } | 43 } |
36 string.remove(string.size() - 2, 2); | 44 string.remove(string.size() - 2, 2); |
37 string.append("]"); | 45 string.append("]"); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 default: break; | 90 default: break; |
83 } | 91 } |
84 // TODO: Check some other things here. (winding, opaque, pathProc color, vm,
...) | 92 // TODO: Check some other things here. (winding, opaque, pathProc color, vm,
...) |
85 // Try to combine this call with the previous DrawPaths. We do this by stenc
iling all the | 93 // Try to combine this call with the previous DrawPaths. We do this by stenc
iling all the |
86 // paths together and then covering them in a single pass. This is not equiv
alent to two | 94 // paths together and then covering them in a single pass. This is not equiv
alent to two |
87 // separate draw calls, so we can only do it if there is no blending (no ove
rlap would also | 95 // separate draw calls, so we can only do it if there is no blending (no ove
rlap would also |
88 // work). Note that it's also possible for overlapping paths to cancel each
other's winding | 96 // work). Note that it's also possible for overlapping paths to cancel each
other's winding |
89 // numbers, and we only partially account for this by not allowing even/odd
paths to be | 97 // numbers, and we only partially account for this by not allowing even/odd
paths to be |
90 // combined. (Glyphs in the same font tend to wind the same direction so it
works out OK.) | 98 // combined. (Glyphs in the same font tend to wind the same direction so it
works out OK.) |
91 if (GrPathRendering::kWinding_FillType != this->fillType() || | 99 if (GrPathRendering::kWinding_FillType != this->fillType() || |
92 this->stencilSettings() != that->stencilSettings() || | 100 GrPathRendering::kWinding_FillType != that->fillType() || |
93 this->overrides().willColorBlendWithDst()) { | 101 this->overrides().willColorBlendWithDst()) { |
94 return false; | 102 return false; |
95 } | 103 } |
96 SkASSERT(!that->overrides().willColorBlendWithDst()); | 104 SkASSERT(!that->overrides().willColorBlendWithDst()); |
97 fTotalPathCount += that->fTotalPathCount; | 105 fTotalPathCount += that->fTotalPathCount; |
98 while (Draw* head = that->fDraws.head()) { | 106 while (Draw* head = that->fDraws.head()) { |
99 Draw* draw = fDraws.addToTail(); | 107 Draw* draw = fDraws.addToTail(); |
100 draw->fInstanceData.reset(head->fInstanceData.release()); | 108 draw->fInstanceData.reset(head->fInstanceData.release()); |
101 draw->fX = head->fX; | 109 draw->fX = head->fX; |
102 draw->fY = head->fY; | 110 draw->fY = head->fY; |
(...skipping 16 matching lines...) Expand all Loading... |
119 | 127 |
120 SkAutoTUnref<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color()
, | 128 SkAutoTUnref<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color()
, |
121 this->overrid
es(), | 129 this->overrid
es(), |
122 drawMatrix, | 130 drawMatrix, |
123 localMatrix))
; | 131 localMatrix))
; |
124 | 132 |
125 if (fDraws.count() == 1) { | 133 if (fDraws.count() == 1) { |
126 const InstanceData& instances = *head.fInstanceData; | 134 const InstanceData& instances = *head.fInstanceData; |
127 state->gpu()->pathRendering()->drawPaths(*this->pipeline(), | 135 state->gpu()->pathRendering()->drawPaths(*this->pipeline(), |
128 *pathProc, | 136 *pathProc, |
129 this->stencilSettings(), | 137 this->stencilPassSettings(), |
130 fPathRange.get(), | 138 fPathRange.get(), |
131 instances.indices(), | 139 instances.indices(), |
132 GrPathRange::kU16_PathIndexType
, | 140 GrPathRange::kU16_PathIndexType
, |
133 instances.transformValues(), | 141 instances.transformValues(), |
134 instances.transformType(), | 142 instances.transformType(), |
135 instances.count()); | 143 instances.count()); |
136 } else { | 144 } else { |
137 int floatsPerTransform = GrPathRendering::PathTransformSize(this->transf
ormType()); | 145 int floatsPerTransform = GrPathRendering::PathTransformSize(this->transf
ormType()); |
138 SkAutoSTMalloc<4096, float> transformStorage(floatsPerTransform * fTotal
PathCount); | 146 SkAutoSTMalloc<4096, float> transformStorage(floatsPerTransform * fTotal
PathCount); |
139 SkAutoSTMalloc<2048, uint16_t> indexStorage(fTotalPathCount); | 147 SkAutoSTMalloc<2048, uint16_t> indexStorage(fTotalPathCount); |
140 int idx = 0; | 148 int idx = 0; |
141 for (DrawList::Iter iter(fDraws); iter.get(); iter.next()) { | 149 for (DrawList::Iter iter(fDraws); iter.get(); iter.next()) { |
142 const Draw& draw = *iter.get(); | 150 const Draw& draw = *iter.get(); |
143 const InstanceData& instances = *draw.fInstanceData; | 151 const InstanceData& instances = *draw.fInstanceData; |
144 memcpy(&indexStorage[idx], instances.indices(), instances.count() *
sizeof(uint16_t)); | 152 memcpy(&indexStorage[idx], instances.indices(), instances.count() *
sizeof(uint16_t)); |
145 pre_translate_transform_values(instances.transformValues(), this->tr
ansformType(), | 153 pre_translate_transform_values(instances.transformValues(), this->tr
ansformType(), |
146 instances.count(), | 154 instances.count(), |
147 draw.fX - head.fX, draw.fY - head.fY, | 155 draw.fX - head.fX, draw.fY - head.fY, |
148 &transformStorage[floatsPerTransform
* idx]); | 156 &transformStorage[floatsPerTransform
* idx]); |
149 idx += instances.count(); | 157 idx += instances.count(); |
150 | 158 |
151 // TODO: Support mismatched transform types if we start using more t
ypes other than 2D. | 159 // TODO: Support mismatched transform types if we start using more t
ypes other than 2D. |
152 SkASSERT(instances.transformType() == this->transformType()); | 160 SkASSERT(instances.transformType() == this->transformType()); |
153 } | 161 } |
154 SkASSERT(idx == fTotalPathCount); | 162 SkASSERT(idx == fTotalPathCount); |
155 | 163 |
156 state->gpu()->pathRendering()->drawPaths(*this->pipeline(), | 164 state->gpu()->pathRendering()->drawPaths(*this->pipeline(), |
157 *pathProc, | 165 *pathProc, |
158 this->stencilSettings(), | 166 this->stencilPassSettings(), |
159 fPathRange.get(), | 167 fPathRange.get(), |
160 indexStorage, | 168 indexStorage, |
161 GrPathRange::kU16_PathIndexType
, | 169 GrPathRange::kU16_PathIndexType
, |
162 transformStorage, | 170 transformStorage, |
163 this->transformType(), | 171 this->transformType(), |
164 fTotalPathCount); | 172 fTotalPathCount); |
165 } | 173 } |
166 } | 174 } |
167 | 175 |
168 inline void pre_translate_transform_values(const float* xforms, | 176 inline void pre_translate_transform_values(const float* xforms, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 dst[i + 3] = xforms[i + 3]; | 210 dst[i + 3] = xforms[i + 3]; |
203 dst[i + 4] = xforms[i + 4]; | 211 dst[i + 4] = xforms[i + 4]; |
204 dst[i + 5] = xforms[i + 3] * x + xforms[i + 4] * y + xforms[i +
5]; | 212 dst[i + 5] = xforms[i + 3] * x + xforms[i + 4] * y + xforms[i +
5]; |
205 } | 213 } |
206 break; | 214 break; |
207 default: | 215 default: |
208 SkFAIL("Unknown transform type."); | 216 SkFAIL("Unknown transform type."); |
209 break; | 217 break; |
210 } | 218 } |
211 } | 219 } |
OLD | NEW |