| 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 "GrNonAAFillRectBatch.h" | 8 #include "GrNonAAFillRectBatch.h" |
| 9 | 9 |
| 10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 } else if (hasExplicitLocalCoords) { | 48 } else if (hasExplicitLocalCoords) { |
| 49 LocalCoords localCoords(LocalCoords::kHasExplicit_Type, localMatrix); | 49 LocalCoords localCoords(LocalCoords::kHasExplicit_Type, localMatrix); |
| 50 return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, SkMat
rix::I()); | 50 return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, SkMat
rix::I()); |
| 51 } else { | 51 } else { |
| 52 LocalCoords localCoords(LocalCoords::kUsePosition_Type, localMatrix); | 52 LocalCoords localCoords(LocalCoords::kUsePosition_Type, localMatrix); |
| 53 return GrDefaultGeoProcFactory::MakeForDeviceSpace(color, coverage, loca
lCoords, | 53 return GrDefaultGeoProcFactory::MakeForDeviceSpace(color, coverage, loca
lCoords, |
| 54 viewMatrix); | 54 viewMatrix); |
| 55 } | 55 } |
| 56 } | 56 } |
| 57 | 57 |
| 58 static sk_sp<GrGeometryProcessor> make_gp(bool readsCoverage) { | |
| 59 using namespace GrDefaultGeoProcFactory; | |
| 60 Color color(Color::kAttribute_Type); | |
| 61 Coverage coverage(readsCoverage ? Coverage::kSolid_Type : Coverage::kNone_Ty
pe); | |
| 62 | |
| 63 LocalCoords localCoords(LocalCoords::kHasExplicit_Type); | |
| 64 return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, SkMatrix:
:I()); | |
| 65 } | |
| 66 | |
| 67 static void tesselate(intptr_t vertices, | 58 static void tesselate(intptr_t vertices, |
| 68 size_t vertexStride, | 59 size_t vertexStride, |
| 69 GrColor color, | 60 GrColor color, |
| 70 const SkMatrix* viewMatrix, | 61 const SkMatrix* viewMatrix, |
| 71 const SkRect& rect, | 62 const SkRect& rect, |
| 72 const GrQuad* localQuad) { | 63 const GrQuad* localQuad) { |
| 73 SkPoint* positions = reinterpret_cast<SkPoint*>(vertices); | 64 SkPoint* positions = reinterpret_cast<SkPoint*>(vertices); |
| 74 | 65 |
| 75 positions->setRectFan(rect.fLeft, rect.fTop, | 66 positions->setRectFan(rect.fLeft, rect.fTop, |
| 76 rect.fRight, rect.fBottom, vertexStride); | 67 rect.fRight, rect.fBottom, vertexStride); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 91 } | 82 } |
| 92 | 83 |
| 93 static const int kColorOffset = sizeof(SkPoint); | 84 static const int kColorOffset = sizeof(SkPoint); |
| 94 GrColor* vertColor = reinterpret_cast<GrColor*>(vertices + kColorOffset); | 85 GrColor* vertColor = reinterpret_cast<GrColor*>(vertices + kColorOffset); |
| 95 for (int j = 0; j < 4; ++j) { | 86 for (int j = 0; j < 4; ++j) { |
| 96 *vertColor = color; | 87 *vertColor = color; |
| 97 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride); | 88 vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride); |
| 98 } | 89 } |
| 99 } | 90 } |
| 100 | 91 |
| 101 class NonAAFillRectBatch : public GrVertexBatch { | 92 // We handle perspective in the local matrix or viewmatrix with special batches |
| 93 class GrNonAAFillRectPerspectiveBatch : public GrVertexBatch { |
| 102 public: | 94 public: |
| 103 DEFINE_BATCH_CLASS_ID | 95 DEFINE_BATCH_CLASS_ID |
| 104 | 96 |
| 105 NonAAFillRectBatch(GrColor color, const SkMatrix& viewMatrix, const SkRect&
rect, | 97 GrNonAAFillRectPerspectiveBatch(GrColor color, const SkMatrix& viewMatrix, c
onst SkRect& rect, |
| 106 const SkRect* localRect, const SkMatrix* localMatrix) | 98 const SkRect* localRect, const SkMatrix* loc
alMatrix) |
| 107 : INHERITED(ClassID()) { | |
| 108 SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || | |
| 109 !localMatrix->hasPerspective()
)); | |
| 110 RectInfo& info = fRects.push_back(); | |
| 111 info.fColor = color; | |
| 112 info.fViewMatrix = viewMatrix; | |
| 113 info.fRect = rect; | |
| 114 if (localRect && localMatrix) { | |
| 115 info.fLocalQuad.setFromMappedRect(*localRect, *localMatrix); | |
| 116 } else if (localRect) { | |
| 117 info.fLocalQuad.set(*localRect); | |
| 118 } else if (localMatrix) { | |
| 119 info.fLocalQuad.setFromMappedRect(rect, *localMatrix); | |
| 120 } else { | |
| 121 info.fLocalQuad.set(rect); | |
| 122 } | |
| 123 viewMatrix.mapRect(&fBounds, fRects[0].fRect); | |
| 124 } | |
| 125 | |
| 126 const char* name() const override { return "NonAAFillRectBatch"; } | |
| 127 | |
| 128 SkString dumpInfo() const override { | |
| 129 SkString str; | |
| 130 str.appendf("# batched: %d\n", fRects.count()); | |
| 131 for (int i = 0; i < fRects.count(); ++i) { | |
| 132 const RectInfo& info = fRects[i]; | |
| 133 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", | |
| 134 i, info.fColor, | |
| 135 info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight, in
fo.fRect.fBottom); | |
| 136 } | |
| 137 str.append(INHERITED::dumpInfo()); | |
| 138 return str; | |
| 139 } | |
| 140 | |
| 141 void computePipelineOptimizations(GrInitInvariantOutput* color, | |
| 142 GrInitInvariantOutput* coverage, | |
| 143 GrBatchToXPOverrides* overrides) const ove
rride { | |
| 144 // When this is called on a batch, there is only one geometry bundle | |
| 145 color->setKnownFourComponents(fRects[0].fColor); | |
| 146 coverage->setKnownSingleComponent(0xff); | |
| 147 } | |
| 148 | |
| 149 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | |
| 150 overrides.getOverrideColorIfSet(&fRects[0].fColor); | |
| 151 fOverrides = overrides; | |
| 152 } | |
| 153 | |
| 154 private: | |
| 155 NonAAFillRectBatch() : INHERITED(ClassID()) {} | |
| 156 | |
| 157 void onPrepareDraws(Target* target) const override { | |
| 158 sk_sp<GrGeometryProcessor> gp = make_gp(fOverrides.readsCoverage()); | |
| 159 if (!gp) { | |
| 160 SkDebugf("Couldn't create GrGeometryProcessor\n"); | |
| 161 return; | |
| 162 } | |
| 163 SkASSERT(gp->getVertexStride() == | |
| 164 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)); | |
| 165 | |
| 166 size_t vertexStride = gp->getVertexStride(); | |
| 167 int instanceCount = fRects.count(); | |
| 168 | |
| 169 SkAutoTUnref<const GrBuffer> indexBuffer(target->resourceProvider()->ref
QuadIndexBuffer()); | |
| 170 InstancedHelper helper; | |
| 171 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, | |
| 172 indexBuffer, kVertsPerInstance, | |
| 173 kIndicesPerInstance, instanceCount); | |
| 174 if (!vertices || !indexBuffer) { | |
| 175 SkDebugf("Could not allocate vertices\n"); | |
| 176 return; | |
| 177 } | |
| 178 | |
| 179 for (int i = 0; i < instanceCount; i++) { | |
| 180 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + | |
| 181 i * kVertsPerInstance * vertexStride; | |
| 182 tesselate(verts, vertexStride, fRects[i].fColor, &fRects[i].fViewMat
rix, | |
| 183 fRects[i].fRect, &fRects[i].fLocalQuad); | |
| 184 } | |
| 185 helper.recordDraw(target, gp.get()); | |
| 186 } | |
| 187 | |
| 188 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | |
| 189 NonAAFillRectBatch* that = t->cast<NonAAFillRectBatch>(); | |
| 190 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | |
| 191 that->bounds(), caps)) { | |
| 192 return false; | |
| 193 } | |
| 194 | |
| 195 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to | |
| 196 // not tweaking | |
| 197 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { | |
| 198 fOverrides = that->fOverrides; | |
| 199 } | |
| 200 | |
| 201 fRects.push_back_n(that->fRects.count(), that->fRects.begin()); | |
| 202 this->joinBounds(that->bounds()); | |
| 203 return true; | |
| 204 } | |
| 205 | |
| 206 struct RectInfo { | |
| 207 GrColor fColor; | |
| 208 SkMatrix fViewMatrix; | |
| 209 SkRect fRect; | |
| 210 GrQuad fLocalQuad; | |
| 211 }; | |
| 212 | |
| 213 GrXPOverridesForBatch fOverrides; | |
| 214 SkSTArray<1, RectInfo, true> fRects; | |
| 215 | |
| 216 typedef GrVertexBatch INHERITED; | |
| 217 }; | |
| 218 | |
| 219 // We handle perspective in the local matrix or viewmatrix with special batches | |
| 220 class NonAAFillRectPerspectiveBatch : public GrVertexBatch { | |
| 221 public: | |
| 222 DEFINE_BATCH_CLASS_ID | |
| 223 | |
| 224 NonAAFillRectPerspectiveBatch(GrColor color, const SkMatrix& viewMatrix, con
st SkRect& rect, | |
| 225 const SkRect* localRect, const SkMatrix* local
Matrix) | |
| 226 : INHERITED(ClassID()) | 99 : INHERITED(ClassID()) |
| 227 , fViewMatrix(viewMatrix) { | 100 , fViewMatrix(viewMatrix) { |
| 228 SkASSERT(viewMatrix.hasPerspective() || (localMatrix && | 101 SkASSERT(viewMatrix.hasPerspective() || (localMatrix && |
| 229 localMatrix->hasPerspective()))
; | 102 localMatrix->hasPerspective()))
; |
| 230 RectInfo& info = fRects.push_back(); | 103 RectInfo& info = fRects.push_back(); |
| 231 info.fColor = color; | 104 info.fColor = color; |
| 232 info.fRect = rect; | 105 info.fRect = rect; |
| 233 fHasLocalRect = SkToBool(localRect); | 106 fHasLocalRect = SkToBool(localRect); |
| 234 fHasLocalMatrix = SkToBool(localMatrix); | 107 fHasLocalMatrix = SkToBool(localMatrix); |
| 235 if (fHasLocalMatrix) { | 108 if (fHasLocalMatrix) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 263 color->setKnownFourComponents(fRects[0].fColor); | 136 color->setKnownFourComponents(fRects[0].fColor); |
| 264 coverage->setKnownSingleComponent(0xff); | 137 coverage->setKnownSingleComponent(0xff); |
| 265 } | 138 } |
| 266 | 139 |
| 267 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | 140 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
| 268 overrides.getOverrideColorIfSet(&fRects[0].fColor); | 141 overrides.getOverrideColorIfSet(&fRects[0].fColor); |
| 269 fOverrides = overrides; | 142 fOverrides = overrides; |
| 270 } | 143 } |
| 271 | 144 |
| 272 private: | 145 private: |
| 273 NonAAFillRectPerspectiveBatch() : INHERITED(ClassID()) {} | 146 GrNonAAFillRectPerspectiveBatch() : INHERITED(ClassID()) {} |
| 274 | 147 |
| 275 void onPrepareDraws(Target* target) const override { | 148 void onPrepareDraws(Target* target) const override { |
| 276 sk_sp<GrGeometryProcessor> gp = make_persp_gp(fViewMatrix, | 149 sk_sp<GrGeometryProcessor> gp = make_persp_gp(fViewMatrix, |
| 277 fOverrides.readsCoverage()
, | 150 fOverrides.readsCoverage()
, |
| 278 fHasLocalRect, | 151 fHasLocalRect, |
| 279 fHasLocalMatrix ? &fLocalM
atrix : nullptr); | 152 fHasLocalMatrix ? &fLocalM
atrix : nullptr); |
| 280 if (!gp) { | 153 if (!gp) { |
| 281 SkDebugf("Couldn't create GrGeometryProcessor\n"); | 154 SkDebugf("Couldn't create GrGeometryProcessor\n"); |
| 282 return; | 155 return; |
| 283 } | 156 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 307 GrQuad quad(info.fLocalRect); | 180 GrQuad quad(info.fLocalRect); |
| 308 tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect,
&quad); | 181 tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect,
&quad); |
| 309 } else { | 182 } else { |
| 310 tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect,
nullptr); | 183 tesselate(verts, vertexStride, info.fColor, nullptr, info.fRect,
nullptr); |
| 311 } | 184 } |
| 312 } | 185 } |
| 313 helper.recordDraw(target, gp.get()); | 186 helper.recordDraw(target, gp.get()); |
| 314 } | 187 } |
| 315 | 188 |
| 316 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 189 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
| 317 NonAAFillRectPerspectiveBatch* that = t->cast<NonAAFillRectPerspectiveBa
tch>(); | 190 GrNonAAFillRectPerspectiveBatch* that = t->cast<GrNonAAFillRectPerspecti
veBatch>(); |
| 318 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | 191 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
| 319 that->bounds(), caps)) { | 192 that->bounds(), caps)) { |
| 320 return false; | 193 return false; |
| 321 } | 194 } |
| 322 | 195 |
| 323 // We could batch across perspective vm changes if we really wanted to | 196 // We could batch across perspective vm changes if we really wanted to |
| 324 if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) { | 197 if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) { |
| 325 return false; | 198 return false; |
| 326 } | 199 } |
| 327 if (fHasLocalRect != that->fHasLocalRect) { | 200 if (fHasLocalRect != that->fHasLocalRect) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 353 bool fHasLocalMatrix; | 226 bool fHasLocalMatrix; |
| 354 bool fHasLocalRect; | 227 bool fHasLocalRect; |
| 355 SkMatrix fLocalMatrix; | 228 SkMatrix fLocalMatrix; |
| 356 SkMatrix fViewMatrix; | 229 SkMatrix fViewMatrix; |
| 357 | 230 |
| 358 typedef GrVertexBatch INHERITED; | 231 typedef GrVertexBatch INHERITED; |
| 359 }; | 232 }; |
| 360 | 233 |
| 361 namespace GrNonAAFillRectBatch { | 234 namespace GrNonAAFillRectBatch { |
| 362 | 235 |
| 363 GrDrawBatch* Create(GrColor color, | |
| 364 const SkMatrix& viewMatrix, | |
| 365 const SkRect& rect, | |
| 366 const SkRect* localRect, | |
| 367 const SkMatrix* localMatrix) { | |
| 368 return new NonAAFillRectBatch(color, viewMatrix, rect, localRect, localMatri
x); | |
| 369 } | |
| 370 | |
| 371 GrDrawBatch* CreateWithPerspective(GrColor color, | 236 GrDrawBatch* CreateWithPerspective(GrColor color, |
| 372 const SkMatrix& viewMatrix, | 237 const SkMatrix& viewMatrix, |
| 373 const SkRect& rect, | 238 const SkRect& rect, |
| 374 const SkRect* localRect, | 239 const SkRect* localRect, |
| 375 const SkMatrix* localMatrix) { | 240 const SkMatrix* localMatrix) { |
| 376 return new NonAAFillRectPerspectiveBatch(color, viewMatrix, rect, localRect,
localMatrix); | 241 return new GrNonAAFillRectPerspectiveBatch(color, viewMatrix, rect, localRec
t, localMatrix); |
| 377 } | 242 } |
| 378 | 243 |
| 379 }; | 244 }; |
| 380 | 245 |
| 381 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 246 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 382 | 247 |
| 383 #ifdef GR_TEST_UTILS | 248 #ifdef GR_TEST_UTILS |
| 384 | 249 |
| 385 #include "GrBatchTest.h" | 250 #include "GrBatchTest.h" |
| 386 | 251 |
| 387 DRAW_BATCH_TEST_DEFINE(RectBatch) { | 252 DRAW_BATCH_TEST_DEFINE(PerspRectBatch) { |
| 388 GrColor color = GrRandomColor(random); | 253 GrColor color = GrRandomColor(random); |
| 389 SkRect rect = GrTest::TestRect(random); | 254 SkRect rect = GrTest::TestRect(random); |
| 390 SkRect localRect = GrTest::TestRect(random); | 255 SkRect localRect = GrTest::TestRect(random); |
| 391 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); | 256 SkMatrix viewMatrix = GrTest::TestMatrix(random); |
| 392 SkMatrix localMatrix = GrTest::TestMatrix(random); | 257 bool hasLocalMatrix = random->nextBool(); |
| 258 SkMatrix localMatrix; |
| 259 if (!viewMatrix.hasPerspective()) { |
| 260 localMatrix = GrTest::TestMatrixPerspective(random); |
| 261 hasLocalMatrix = true; |
| 262 } |
| 393 | 263 |
| 394 bool hasLocalRect = random->nextBool(); | 264 bool hasLocalRect = random->nextBool(); |
| 395 bool hasLocalMatrix = random->nextBool(); | 265 return GrNonAAFillRectBatch::CreateWithPerspective(color, viewMatrix, rect, |
| 396 return GrNonAAFillRectBatch::Create(color, viewMatrix, rect, | 266 hasLocalRect ? &localRect
: nullptr, |
| 397 hasLocalRect ? &localRect : nullptr, | 267 hasLocalMatrix ? &localMa
trix : nullptr); |
| 398 hasLocalMatrix ? &localMatrix : nullptr)
; | |
| 399 } | 268 } |
| 400 | 269 |
| 401 #endif | 270 #endif |
| OLD | NEW |