| 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 |