OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 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 "InstancedRendering.h" | 8 #include "InstancedRendering.h" |
9 | 9 |
10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 } | 116 } |
117 | 117 |
118 Batch* batch = this->createBatch(); | 118 Batch* batch = this->createBatch(); |
119 batch->fInfo.fAntialiasMode = antialiasMode; | 119 batch->fInfo.fAntialiasMode = antialiasMode; |
120 batch->fInfo.fShapeTypes = GetShapeFlag(type); | 120 batch->fInfo.fShapeTypes = GetShapeFlag(type); |
121 batch->fInfo.fCannotDiscard = !info.fCanDiscard; | 121 batch->fInfo.fCannotDiscard = !info.fCanDiscard; |
122 | 122 |
123 Instance& instance = batch->getSingleInstance(); | 123 Instance& instance = batch->getSingleInstance(); |
124 instance.fInfo = (int)type << kShapeType_InfoBit; | 124 instance.fInfo = (int)type << kShapeType_InfoBit; |
125 | 125 |
| 126 Batch::HasAABloat aaBloat = (antialiasMode == AntialiasMode::kCoverage) |
| 127 ? Batch::HasAABloat::kYes |
| 128 : Batch::HasAABloat::kNo; |
| 129 Batch::IsZeroArea zeroArea = (bounds.isEmpty()) ? Batch::IsZeroArea::kYes |
| 130 : Batch::IsZeroArea::kNo; |
| 131 |
126 // The instanced shape renderer draws rectangles of [-1, -1, +1, +1], so we
find the matrix that | 132 // The instanced shape renderer draws rectangles of [-1, -1, +1, +1], so we
find the matrix that |
127 // will map this rectangle to the same device coordinates as "viewMatrix * b
ounds". | 133 // will map this rectangle to the same device coordinates as "viewMatrix * b
ounds". |
128 float sx = 0.5f * bounds.width(); | 134 float sx = 0.5f * bounds.width(); |
129 float sy = 0.5f * bounds.height(); | 135 float sy = 0.5f * bounds.height(); |
130 float tx = sx + bounds.fLeft; | 136 float tx = sx + bounds.fLeft; |
131 float ty = sy + bounds.fTop; | 137 float ty = sy + bounds.fTop; |
132 if (!viewMatrix.hasPerspective()) { | 138 if (!viewMatrix.hasPerspective()) { |
133 float* m = instance.fShapeMatrix2x3; | 139 float* m = instance.fShapeMatrix2x3; |
134 m[0] = viewMatrix.getScaleX() * sx; | 140 m[0] = viewMatrix.getScaleX() * sx; |
135 m[1] = viewMatrix.getSkewX() * sy; | 141 m[1] = viewMatrix.getSkewX() * sy; |
136 m[2] = viewMatrix.getTranslateX() + | 142 m[2] = viewMatrix.getTranslateX() + |
137 viewMatrix.getScaleX() * tx + viewMatrix.getSkewX() * ty; | 143 viewMatrix.getScaleX() * tx + viewMatrix.getSkewX() * ty; |
138 | 144 |
139 m[3] = viewMatrix.getSkewY() * sx; | 145 m[3] = viewMatrix.getSkewY() * sx; |
140 m[4] = viewMatrix.getScaleY() * sy; | 146 m[4] = viewMatrix.getScaleY() * sy; |
141 m[5] = viewMatrix.getTranslateY() + | 147 m[5] = viewMatrix.getTranslateY() + |
142 viewMatrix.getSkewY() * tx + viewMatrix.getScaleY() * ty; | 148 viewMatrix.getSkewY() * tx + viewMatrix.getScaleY() * ty; |
143 | 149 |
144 // Since 'm' is a 2x3 matrix that maps the rect [-1, +1] into the shape'
s device-space quad, | 150 // Since 'm' is a 2x3 matrix that maps the rect [-1, +1] into the shape'
s device-space quad, |
145 // it's quite simple to find the bounding rectangle: | 151 // it's quite simple to find the bounding rectangle: |
146 float devBoundsHalfWidth = fabsf(m[0]) + fabsf(m[1]); | 152 float devBoundsHalfWidth = fabsf(m[0]) + fabsf(m[1]); |
147 float devBoundsHalfHeight = fabsf(m[3]) + fabsf(m[4]); | 153 float devBoundsHalfHeight = fabsf(m[3]) + fabsf(m[4]); |
148 batch->fBounds.fLeft = m[2] - devBoundsHalfWidth; | 154 SkRect batchBounds; |
149 batch->fBounds.fRight = m[2] + devBoundsHalfWidth; | 155 batchBounds.fLeft = m[2] - devBoundsHalfWidth; |
150 batch->fBounds.fTop = m[5] - devBoundsHalfHeight; | 156 batchBounds.fRight = m[2] + devBoundsHalfWidth; |
151 batch->fBounds.fBottom = m[5] + devBoundsHalfHeight; | 157 batchBounds.fTop = m[5] - devBoundsHalfHeight; |
| 158 batchBounds.fBottom = m[5] + devBoundsHalfHeight; |
| 159 batch->setBounds(batchBounds, aaBloat, zeroArea); |
152 | 160 |
153 // TODO: Is this worth the CPU overhead? | 161 // TODO: Is this worth the CPU overhead? |
154 batch->fInfo.fNonSquare = | 162 batch->fInfo.fNonSquare = |
155 fabsf(devBoundsHalfHeight - devBoundsHalfWidth) > 0.5f || // Early o
ut. | 163 fabsf(devBoundsHalfHeight - devBoundsHalfWidth) > 0.5f || // Early o
ut. |
156 fabs(m[0] * m[3] + m[1] * m[4]) > 1e-3f || // Skew? | 164 fabs(m[0] * m[3] + m[1] * m[4]) > 1e-3f || // Skew? |
157 fabs(m[0] * m[0] + m[1] * m[1] - m[3] * m[3] - m[4] * m[4]) > 1e-2f;
// Diff. lengths? | 165 fabs(m[0] * m[0] + m[1] * m[1] - m[3] * m[3] - m[4] * m[4]) > 1e-2f;
// Diff. lengths? |
158 } else { | 166 } else { |
159 SkMatrix shapeMatrix(viewMatrix); | 167 SkMatrix shapeMatrix(viewMatrix); |
160 shapeMatrix.preTranslate(tx, ty); | 168 shapeMatrix.preTranslate(tx, ty); |
161 shapeMatrix.preScale(sx, sy); | 169 shapeMatrix.preScale(sx, sy); |
162 instance.fInfo |= kPerspective_InfoFlag; | 170 instance.fInfo |= kPerspective_InfoFlag; |
163 | 171 |
164 float* m = instance.fShapeMatrix2x3; | 172 float* m = instance.fShapeMatrix2x3; |
165 m[0] = SkScalarToFloat(shapeMatrix.getScaleX()); | 173 m[0] = SkScalarToFloat(shapeMatrix.getScaleX()); |
166 m[1] = SkScalarToFloat(shapeMatrix.getSkewX()); | 174 m[1] = SkScalarToFloat(shapeMatrix.getSkewX()); |
167 m[2] = SkScalarToFloat(shapeMatrix.getTranslateX()); | 175 m[2] = SkScalarToFloat(shapeMatrix.getTranslateX()); |
168 m[3] = SkScalarToFloat(shapeMatrix.getSkewY()); | 176 m[3] = SkScalarToFloat(shapeMatrix.getSkewY()); |
169 m[4] = SkScalarToFloat(shapeMatrix.getScaleY()); | 177 m[4] = SkScalarToFloat(shapeMatrix.getScaleY()); |
170 m[5] = SkScalarToFloat(shapeMatrix.getTranslateY()); | 178 m[5] = SkScalarToFloat(shapeMatrix.getTranslateY()); |
171 | 179 |
172 // Send the perspective column as a param. | 180 // Send the perspective column as a param. |
173 batch->appendParamsTexel(shapeMatrix[SkMatrix::kMPersp0], shapeMatrix[Sk
Matrix::kMPersp1], | 181 batch->appendParamsTexel(shapeMatrix[SkMatrix::kMPersp0], shapeMatrix[Sk
Matrix::kMPersp1], |
174 shapeMatrix[SkMatrix::kMPersp2]); | 182 shapeMatrix[SkMatrix::kMPersp2]); |
175 batch->fInfo.fHasPerspective = true; | 183 batch->fInfo.fHasPerspective = true; |
176 | 184 |
177 viewMatrix.mapRect(&batch->fBounds, bounds); | 185 batch->setBounds(bounds, aaBloat, zeroArea); |
178 | |
179 batch->fInfo.fNonSquare = true; | 186 batch->fInfo.fNonSquare = true; |
180 } | 187 } |
181 | 188 |
182 instance.fColor = color; | 189 instance.fColor = color; |
183 | 190 |
184 const float* rectAsFloats = localRect.asScalars(); // Ensure SkScalar == flo
at. | 191 const float* rectAsFloats = localRect.asScalars(); // Ensure SkScalar == flo
at. |
185 memcpy(&instance.fLocalRect, rectAsFloats, 4 * sizeof(float)); | 192 memcpy(&instance.fLocalRect, rectAsFloats, 4 * sizeof(float)); |
186 | 193 |
187 batch->fPixelLoad = batch->fBounds.height() * batch->fBounds.width(); | 194 batch->fPixelLoad = batch->bounds().height() * batch->bounds().width(); |
188 return batch; | 195 return batch; |
189 } | 196 } |
190 | 197 |
191 inline bool InstancedRendering::selectAntialiasMode(const SkMatrix& viewMatrix,
bool antialias, | 198 inline bool InstancedRendering::selectAntialiasMode(const SkMatrix& viewMatrix,
bool antialias, |
192 const GrInstancedPipelineInf
o& info, | 199 const GrInstancedPipelineInf
o& info, |
193 bool* useHWAA, AntialiasMode
* antialiasMode) { | 200 bool* useHWAA, AntialiasMode
* antialiasMode) { |
194 SkASSERT(!info.fColorDisabled || info.fDrawingShapeToStencil); | 201 SkASSERT(!info.fColorDisabled || info.fDrawingShapeToStencil); |
195 SkASSERT(!info.fIsMixedSampled || info.fIsMultisampled); | 202 SkASSERT(!info.fIsMixedSampled || info.fIsMultisampled); |
196 | 203 |
197 if (!info.fIsMultisampled || fGpu->caps()->multisampleDisableSupport()) { | 204 if (!info.fIsMultisampled || fGpu->caps()->multisampleDisableSupport()) { |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 | 352 |
346 void InstancedRendering::Batch::initBatchTracker(const GrXPOverridesForBatch& ov
errides) { | 353 void InstancedRendering::Batch::initBatchTracker(const GrXPOverridesForBatch& ov
errides) { |
347 Draw& draw = this->getSingleDraw(); // This will assert if we have > 1 comma
nd. | 354 Draw& draw = this->getSingleDraw(); // This will assert if we have > 1 comma
nd. |
348 SkASSERT(draw.fGeometry.isEmpty()); | 355 SkASSERT(draw.fGeometry.isEmpty()); |
349 SkASSERT(SkIsPow2(fInfo.fShapeTypes)); | 356 SkASSERT(SkIsPow2(fInfo.fShapeTypes)); |
350 SkASSERT(!fIsTracked); | 357 SkASSERT(!fIsTracked); |
351 | 358 |
352 if (kRect_ShapeFlag == fInfo.fShapeTypes) { | 359 if (kRect_ShapeFlag == fInfo.fShapeTypes) { |
353 draw.fGeometry = InstanceProcessor::GetIndexRangeForRect(fInfo.fAntialia
sMode); | 360 draw.fGeometry = InstanceProcessor::GetIndexRangeForRect(fInfo.fAntialia
sMode); |
354 } else if (kOval_ShapeFlag == fInfo.fShapeTypes) { | 361 } else if (kOval_ShapeFlag == fInfo.fShapeTypes) { |
355 draw.fGeometry = InstanceProcessor::GetIndexRangeForOval(fInfo.fAntialia
sMode, fBounds); | 362 draw.fGeometry = InstanceProcessor::GetIndexRangeForOval(fInfo.fAntialia
sMode, |
| 363 this->bounds())
; |
356 } else { | 364 } else { |
357 draw.fGeometry = InstanceProcessor::GetIndexRangeForRRect(fInfo.fAntiali
asMode); | 365 draw.fGeometry = InstanceProcessor::GetIndexRangeForRRect(fInfo.fAntiali
asMode); |
358 } | 366 } |
359 | 367 |
360 if (!fParams.empty()) { | 368 if (!fParams.empty()) { |
361 SkASSERT(fInstancedRendering->fParams.count() < (int)kParamsIdx_InfoMask
); // TODO: cleaner. | 369 SkASSERT(fInstancedRendering->fParams.count() < (int)kParamsIdx_InfoMask
); // TODO: cleaner. |
362 this->getSingleInstance().fInfo |= fInstancedRendering->fParams.count(); | 370 this->getSingleInstance().fInfo |= fInstancedRendering->fParams.count(); |
363 fInstancedRendering->fParams.push_back_n(fParams.count(), fParams.begin(
)); | 371 fInstancedRendering->fParams.push_back_n(fParams.count(), fParams.begin(
)); |
364 } | 372 } |
365 | 373 |
(...skipping 28 matching lines...) Expand all Loading... |
394 // is that the itty bitty rects combine with other shapes and the giant
ones don't. | 402 // is that the itty bitty rects combine with other shapes and the giant
ones don't. |
395 constexpr SkScalar kMaxPixelsToGeneralizeRects = 256 * 256; | 403 constexpr SkScalar kMaxPixelsToGeneralizeRects = 256 * 256; |
396 if (fInfo.isSimpleRects() && fPixelLoad > kMaxPixelsToGeneralizeRects) { | 404 if (fInfo.isSimpleRects() && fPixelLoad > kMaxPixelsToGeneralizeRects) { |
397 return false; | 405 return false; |
398 } | 406 } |
399 if (that->fInfo.isSimpleRects() && that->fPixelLoad > kMaxPixelsToGenera
lizeRects) { | 407 if (that->fInfo.isSimpleRects() && that->fPixelLoad > kMaxPixelsToGenera
lizeRects) { |
400 return false; | 408 return false; |
401 } | 409 } |
402 } | 410 } |
403 | 411 |
404 fBounds.join(that->fBounds); | 412 this->joinBounds(*that); |
405 fInfo = combinedInfo; | 413 fInfo = combinedInfo; |
406 fPixelLoad += that->fPixelLoad; | 414 fPixelLoad += that->fPixelLoad; |
407 | 415 |
408 // Adopt the other batch's draws. | 416 // Adopt the other batch's draws. |
409 fNumDraws += that->fNumDraws; | 417 fNumDraws += that->fNumDraws; |
410 fNumChangesInGeometry += that->fNumChangesInGeometry; | 418 fNumChangesInGeometry += that->fNumChangesInGeometry; |
411 if (fTailDraw->fGeometry != that->fHeadDraw->fGeometry) { | 419 if (fTailDraw->fGeometry != that->fHeadDraw->fGeometry) { |
412 ++fNumChangesInGeometry; | 420 ++fNumChangesInGeometry; |
413 } | 421 } |
414 fTailDraw->fNext = that->fHeadDraw; | 422 fTailDraw->fNext = that->fHeadDraw; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 } | 487 } |
480 | 488 |
481 void InstancedRendering::resetGpuResources(ResetType resetType) { | 489 void InstancedRendering::resetGpuResources(ResetType resetType) { |
482 fVertexBuffer.reset(); | 490 fVertexBuffer.reset(); |
483 fIndexBuffer.reset(); | 491 fIndexBuffer.reset(); |
484 fParamsBuffer.reset(); | 492 fParamsBuffer.reset(); |
485 this->onResetGpuResources(resetType); | 493 this->onResetGpuResources(resetType); |
486 } | 494 } |
487 | 495 |
488 } | 496 } |
OLD | NEW |