| 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 "GrAAFillRectBatch.h" | 8 #include "GrAAFillRectBatch.h" |
| 9 | 9 |
| 10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
| 11 #include "GrColor.h" | 11 #include "GrColor.h" |
| 12 #include "GrDefaultGeoProcFactory.h" | 12 #include "GrDefaultGeoProcFactory.h" |
| 13 #include "GrResourceKey.h" | 13 #include "GrResourceKey.h" |
| 14 #include "GrResourceProvider.h" | 14 #include "GrResourceProvider.h" |
| 15 #include "GrTypes.h" | 15 #include "GrTypes.h" |
| 16 #include "GrVertexBatch.h" |
| 16 #include "SkMatrix.h" | 17 #include "SkMatrix.h" |
| 17 #include "SkRect.h" | 18 #include "SkRect.h" |
| 18 #include "GrVertexBatch.h" | |
| 19 | 19 |
| 20 GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); | 20 GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); |
| 21 | 21 |
| 22 static void set_inset_fan(SkPoint* pts, size_t stride, | 22 static void set_inset_fan(SkPoint* pts, size_t stride, |
| 23 const SkRect& r, SkScalar dx, SkScalar dy) { | 23 const SkRect& r, SkScalar dx, SkScalar dy) { |
| 24 pts->setRectFan(r.fLeft + dx, r.fTop + dy, | 24 pts->setRectFan(r.fLeft + dx, r.fTop + dy, |
| 25 r.fRight - dx, r.fBottom - dy, stride); | 25 r.fRight - dx, r.fBottom - dy, stride); |
| 26 } | 26 } |
| 27 | 27 |
| 28 static const int kNumAAFillRectsInIndexBuffer = 256; | 28 static const int kNumAAFillRectsInIndexBuffer = 256; |
| 29 static const int kVertsPerAAFillRect = 8; | 29 static const int kVertsPerAAFillRect = 8; |
| 30 static const int kIndicesPerAAFillRect = 30; | 30 static const int kIndicesPerAAFillRect = 30; |
| 31 | 31 |
| 32 const GrBuffer* get_index_buffer(GrResourceProvider* resourceProvider) { | 32 const GrBuffer* get_index_buffer(GrResourceProvider* resourceProvider) { |
| 33 GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); | 33 GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); |
| 34 | 34 |
| 35 static const uint16_t gFillAARectIdx[] = { | 35 static const uint16_t gFillAARectIdx[] = { |
| 36 0, 1, 5, 5, 4, 0, | 36 0, 1, 5, 5, 4, 0, |
| 37 1, 2, 6, 6, 5, 1, | 37 1, 2, 6, 6, 5, 1, |
| 38 2, 3, 7, 7, 6, 2, | 38 2, 3, 7, 7, 6, 2, |
| 39 3, 0, 4, 4, 7, 3, | 39 3, 0, 4, 4, 7, 3, |
| 40 4, 5, 6, 6, 7, 4, | 40 4, 5, 6, 6, 7, 4, |
| 41 }; | 41 }; |
| 42 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFillAARectIdx) == kIndicesPerAAFillRect); | 42 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFillAARectIdx) == kIndicesPerAAFillRect); |
| 43 return resourceProvider->findOrCreateInstancedIndexBuffer(gFillAARectIdx, | 43 return resourceProvider->findOrCreateInstancedIndexBuffer(gFillAARectIdx, |
| 44 kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer, kVertsPerAAFillRect
, | 44 kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer, kVertsPerAAFillRect
, |
| 45 gAAFillRectIndexBufferKey); | 45 gAAFillRectIndexBufferKey); |
| 46 } | 46 } |
| 47 | 47 |
| 48 static sk_sp<GrGeometryProcessor> create_fill_rect_gp( | |
| 49 const SkMatrix& viewMatrix, | |
| 50 const GrXPOverridesForBatch& overrides, | |
| 51 GrDefaultGeoProcFactory::LocalCoords::Typ
e localCoordsType) { | |
| 52 using namespace GrDefaultGeoProcFactory; | |
| 53 | |
| 54 Color color(Color::kAttribute_Type); | |
| 55 Coverage::Type coverageType; | |
| 56 // TODO remove coverage if coverage is ignored | |
| 57 /*if (coverageIgnored) { | |
| 58 coverageType = Coverage::kNone_Type; | |
| 59 } else*/ if (overrides.canTweakAlphaForCoverage()) { | |
| 60 coverageType = Coverage::kSolid_Type; | |
| 61 } else { | |
| 62 coverageType = Coverage::kAttribute_Type; | |
| 63 } | |
| 64 Coverage coverage(coverageType); | |
| 65 | |
| 66 // We assume the caller has inverted the viewmatrix | |
| 67 if (LocalCoords::kHasExplicit_Type == localCoordsType) { | |
| 68 LocalCoords localCoords(localCoordsType); | |
| 69 return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, SkMat
rix::I()); | |
| 70 } else { | |
| 71 LocalCoords localCoords(overrides.readsLocalCoords() ? localCoordsType : | |
| 72 LocalCoords::kUnu
sed_Type); | |
| 73 return MakeForDeviceSpace(color, coverage, localCoords, viewMatrix); | |
| 74 } | |
| 75 } | |
| 76 | |
| 77 static void generate_aa_fill_rect_geometry(intptr_t verts, | 48 static void generate_aa_fill_rect_geometry(intptr_t verts, |
| 78 size_t vertexStride, | 49 size_t vertexStride, |
| 79 GrColor color, | 50 GrColor color, |
| 80 const SkMatrix& viewMatrix, | 51 const SkMatrix& viewMatrix, |
| 81 const SkRect& rect, | 52 const SkRect& rect, |
| 82 const SkRect& devRect, | 53 const SkRect& devRect, |
| 83 const GrXPOverridesForBatch& override
s, | 54 const GrXPOverridesForBatch& override
s, |
| 84 const SkMatrix* localMatrix) { | 55 const SkMatrix* localMatrix) { |
| 85 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); | 56 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); |
| 86 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); | 57 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1]; | 101 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1]; |
| 131 // TR | 102 // TR |
| 132 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) = | 103 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) = |
| 133 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1
]; | 104 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1
]; |
| 134 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1]; | 105 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1]; |
| 135 } | 106 } |
| 136 | 107 |
| 137 if (localMatrix) { | 108 if (localMatrix) { |
| 138 SkMatrix invViewMatrix; | 109 SkMatrix invViewMatrix; |
| 139 if (!viewMatrix.invert(&invViewMatrix)) { | 110 if (!viewMatrix.invert(&invViewMatrix)) { |
| 140 SkASSERT(false); | 111 SkDebugf("View matrix is non-invertible, local coords will be wrong.
"); |
| 141 invViewMatrix = SkMatrix::I(); | 112 invViewMatrix = SkMatrix::I(); |
| 142 } | 113 } |
| 143 SkMatrix localCoordMatrix; | 114 SkMatrix localCoordMatrix; |
| 144 localCoordMatrix.setConcat(*localMatrix, invViewMatrix); | 115 localCoordMatrix.setConcat(*localMatrix, invViewMatrix); |
| 145 SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(verts + sizeof(SkPoint) +
sizeof(GrColor)); | 116 SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(verts + sizeof(SkPoint) +
sizeof(GrColor)); |
| 146 localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8); | 117 localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8); |
| 147 } | 118 } |
| 148 | 119 |
| 149 bool tweakAlphaForCoverage = overrides.canTweakAlphaForCoverage(); | 120 bool tweakAlphaForCoverage = overrides.canTweakAlphaForCoverage(); |
| 150 | 121 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 179 for (int i = 0; i < 4; ++i) { | 150 for (int i = 0; i < 4; ++i) { |
| 180 if (tweakAlphaForCoverage) { | 151 if (tweakAlphaForCoverage) { |
| 181 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; | 152 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; |
| 182 } else { | 153 } else { |
| 183 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; | 154 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
| 184 *reinterpret_cast<float*>(verts + i * vertexStride + | 155 *reinterpret_cast<float*>(verts + i * vertexStride + |
| 185 coverageOffset) = innerCoverage; | 156 coverageOffset) = innerCoverage; |
| 186 } | 157 } |
| 187 } | 158 } |
| 188 } | 159 } |
| 189 | 160 class AAFillRectBatch : public GrVertexBatch { |
| 190 class AAFillRectNoLocalMatrixBatch : public GrVertexBatch { | |
| 191 public: | 161 public: |
| 192 DEFINE_BATCH_CLASS_ID | 162 DEFINE_BATCH_CLASS_ID |
| 193 AAFillRectNoLocalMatrixBatch(GrColor color, | 163 |
| 194 const SkMatrix& viewMatrix, | 164 AAFillRectBatch(GrColor color, |
| 195 const SkRect& rect, | 165 const SkMatrix& viewMatrix, |
| 196 const SkRect& devRect) : INHERITED(ClassID()) { | 166 const SkRect& rect, |
| 197 fRects.emplace_back(RectInfo{color, viewMatrix, rect, devRect}); | 167 const SkRect& devRect, |
| 168 const SkMatrix* localMatrix) : INHERITED(ClassID()) { |
| 169 if (localMatrix) { |
| 170 void* mem = fRectData.push_back_n(sizeof(RectWithLocalMatrixInfo)); |
| 171 new (mem) RectWithLocalMatrixInfo(color, viewMatrix, rect, devRect,
*localMatrix); |
| 172 } else { |
| 173 void* mem = fRectData.push_back_n(sizeof(RectInfo)); |
| 174 new (mem) RectInfo(color, viewMatrix, rect, devRect); |
| 175 } |
| 198 fBounds = devRect; | 176 fBounds = devRect; |
| 177 fRectCnt = 1; |
| 199 } | 178 } |
| 200 | 179 |
| 201 const char* name() const override { return "AAFillRectBatchNoLocalMatrix"; } | 180 const char* name() const override { return "AAFillRectBatch"; } |
| 202 | 181 |
| 203 SkString dumpInfo() const override { | 182 SkString dumpInfo() const override { |
| 204 SkString str; | 183 SkString str; |
| 205 str.appendf("# batched: %d\n", fRects.count()); | 184 str.appendf("# batched: %d\n", fRectCnt); |
| 206 for (int i = 0; i < fRects.count(); ++i) { | 185 const RectInfo* info = this->first(); |
| 207 const RectInfo& info = fRects[i]; | 186 for (int i = 0; i < fRectCnt; ++i) { |
| 187 const SkRect& rect = info->rect(); |
| 208 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", | 188 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", |
| 209 i, info.fColor, | 189 i, info->color(), rect.fLeft, rect.fTop, rect.fRight, re
ct.fBottom); |
| 210 info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight, in
fo.fRect.fBottom); | 190 info = this->next(info); |
| 211 } | 191 } |
| 212 str.append(INHERITED::dumpInfo()); | 192 str.append(INHERITED::dumpInfo()); |
| 213 return str; | 193 return str; |
| 214 } | 194 } |
| 215 | 195 |
| 216 void computePipelineOptimizations(GrInitInvariantOutput* color, | 196 void computePipelineOptimizations(GrInitInvariantOutput* color, |
| 217 GrInitInvariantOutput* coverage, | 197 GrInitInvariantOutput* coverage, |
| 218 GrBatchToXPOverrides* overrides) const ove
rride { | 198 GrBatchToXPOverrides* overrides) const ove
rride { |
| 219 // When this is called on a batch, there is only one rect | 199 // When this is called on a batch, there is only one rect |
| 220 color->setKnownFourComponents(fRects[0].fColor); | 200 color->setKnownFourComponents(this->first()->color()); |
| 221 coverage->setUnknownSingleComponent(); | 201 coverage->setUnknownSingleComponent(); |
| 222 } | 202 } |
| 223 | 203 |
| 224 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | 204 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
| 225 overrides.getOverrideColorIfSet(&fRects[0].fColor); | 205 GrColor color; |
| 206 if (overrides.getOverrideColorIfSet(&color)) { |
| 207 this->first()->setColor(color); |
| 208 } |
| 226 fOverrides = overrides; | 209 fOverrides = overrides; |
| 227 } | 210 } |
| 228 | 211 |
| 229 private: | 212 private: |
| 230 AAFillRectNoLocalMatrixBatch() : INHERITED(ClassID()) {} | 213 void onPrepareDraws(Target* target) const override { |
| 214 bool needLocalCoords = fOverrides.readsLocalCoords(); |
| 215 using namespace GrDefaultGeoProcFactory; |
| 231 | 216 |
| 232 void onPrepareDraws(Target* target) const override { | 217 Color color(Color::kAttribute_Type); |
| 233 sk_sp<GrGeometryProcessor> gp = | 218 Coverage::Type coverageType; |
| 234 create_fill_rect_gp(fRects[0].fViewMatrix, fOverrides, | 219 if (fOverrides.canTweakAlphaForCoverage()) { |
| 235 GrDefaultGeoProcFactory::LocalCoords::kUsePo
sition_Type); | 220 coverageType = Coverage::kSolid_Type; |
| 221 } else { |
| 222 coverageType = Coverage::kAttribute_Type; |
| 223 } |
| 224 Coverage coverage(coverageType); |
| 225 LocalCoords lc = needLocalCoords ? LocalCoords::kHasExplicit_Type |
| 226 : LocalCoords::kUnused_Type; |
| 227 sk_sp<GrGeometryProcessor> gp = GrDefaultGeoProcFactory::Make(color, cov
erage, lc, |
| 228 SkMatrix::
I()); |
| 236 if (!gp) { | 229 if (!gp) { |
| 237 SkDebugf("Couldn't create GrGeometryProcessor\n"); | 230 SkDebugf("Couldn't create GrGeometryProcessor\n"); |
| 238 return; | 231 return; |
| 239 } | 232 } |
| 240 SkASSERT(fOverrides.canTweakAlphaForCoverage() ? | |
| 241 gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::Po
sitionColorAttr) : | |
| 242 gp->getVertexStride() == | |
| 243 sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAt
tr)); | |
| 244 | 233 |
| 245 size_t vertexStride = gp->getVertexStride(); | 234 size_t vertexStride = gp->getVertexStride(); |
| 246 | 235 |
| 247 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour
ceProvider())); | 236 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour
ceProvider())); |
| 248 InstancedHelper helper; | 237 InstancedHelper helper; |
| 249 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, | 238 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, |
| 250 indexBuffer, kVertsPerAAFillRect, | 239 indexBuffer, kVertsPerAAFillRect, |
| 251 kIndicesPerAAFillRect, fRects.count()); | 240 kIndicesPerAAFillRect, fRectCnt); |
| 252 if (!vertices || !indexBuffer) { | 241 if (!vertices || !indexBuffer) { |
| 253 SkDebugf("Could not allocate vertices\n"); | 242 SkDebugf("Could not allocate vertices\n"); |
| 254 return; | 243 return; |
| 255 } | 244 } |
| 256 | 245 |
| 257 for (int i = 0; i < fRects.count(); i++) { | 246 const RectInfo* info = this->first(); |
| 247 const SkMatrix* localMatrix = nullptr; |
| 248 for (int i = 0; i < fRectCnt; i++) { |
| 258 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + | 249 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + |
| 259 i * kVertsPerAAFillRect * vertexStride; | 250 i * kVertsPerAAFillRect * vertexStride; |
| 260 generate_aa_fill_rect_geometry(verts, vertexStride, | 251 if (needLocalCoords) { |
| 261 fRects[i].fColor, fRects[i].fViewMatr
ix, | 252 if (info->hasLocalMatrix()) { |
| 262 fRects[i].fRect, fRects[i].fDevRect,
fOverrides, | 253 localMatrix = &static_cast<const RectWithLocalMatrixInfo*>(i
nfo)->localMatrix(); |
| 263 nullptr); | 254 } else { |
| 255 localMatrix = &SkMatrix::I(); |
| 256 } |
| 257 } |
| 258 generate_aa_fill_rect_geometry(verts, vertexStride, info->color(), |
| 259 info->viewMatrix(), info->rect(), |
| 260 info->devRect(), fOverrides, localMat
rix); |
| 261 info = this->next(info); |
| 264 } | 262 } |
| 265 helper.recordDraw(target, gp.get()); | 263 helper.recordDraw(target, gp.get()); |
| 266 } | 264 } |
| 267 | 265 |
| 268 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 266 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
| 269 AAFillRectNoLocalMatrixBatch* that = t->cast<AAFillRectNoLocalMatrixBatc
h>(); | 267 AAFillRectBatch* that = t->cast<AAFillRectBatch>(); |
| 270 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | |
| 271 that->bounds(), caps)) { | |
| 272 return false; | |
| 273 } | |
| 274 | |
| 275 // We apply the viewmatrix to the rect points on the cpu. However, if t
he pipeline uses | |
| 276 // local coords then we won't be able to batch. We could actually uploa
d the viewmatrix | |
| 277 // using vertex attributes in these cases, but haven't investigated that | |
| 278 if (fOverrides.readsLocalCoords() && | |
| 279 !fRects[0].fViewMatrix.cheapEqualTo(that->fRects[0].fViewMatrix)) { | |
| 280 return false; | |
| 281 } | |
| 282 | |
| 283 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to | |
| 284 // not tweaking | |
| 285 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { | |
| 286 fOverrides = that->fOverrides; | |
| 287 } | |
| 288 | |
| 289 fRects.push_back_n(that->fRects.count(), that->fRects.begin()); | |
| 290 this->joinBounds(that->bounds()); | |
| 291 return true; | |
| 292 } | |
| 293 | |
| 294 struct RectInfo { | |
| 295 GrColor fColor; | |
| 296 SkMatrix fViewMatrix; | |
| 297 SkRect fRect; | |
| 298 SkRect fDevRect; | |
| 299 }; | |
| 300 | |
| 301 GrXPOverridesForBatch fOverrides; | |
| 302 SkSTArray<1, RectInfo, true> fRects; | |
| 303 | |
| 304 typedef GrVertexBatch INHERITED; | |
| 305 }; | |
| 306 | |
| 307 class AAFillRectLocalMatrixBatch : public GrVertexBatch { | |
| 308 public: | |
| 309 DEFINE_BATCH_CLASS_ID | |
| 310 | |
| 311 AAFillRectLocalMatrixBatch(GrColor color, | |
| 312 const SkMatrix& viewMatrix, | |
| 313 const SkMatrix& localMatrix, | |
| 314 const SkRect& rect, | |
| 315 const SkRect& devRect) : INHERITED(ClassID()) { | |
| 316 fRects.emplace_back(RectInfo{color, viewMatrix, localMatrix, rect, devRe
ct}); | |
| 317 fBounds = devRect; | |
| 318 } | |
| 319 | |
| 320 const char* name() const override { return "AAFillRectBatchLocalMatrix"; } | |
| 321 | |
| 322 SkString dumpInfo() const override { | |
| 323 SkString str; | |
| 324 str.appendf("# batched: %d\n", fRects.count()); | |
| 325 for (int i = 0; i < fRects.count(); ++i) { | |
| 326 const RectInfo& info = fRects[i]; | |
| 327 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", | |
| 328 i, info.fColor, | |
| 329 info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight, in
fo.fRect.fBottom); | |
| 330 } | |
| 331 str.append(INHERITED::dumpInfo()); | |
| 332 return str; | |
| 333 } | |
| 334 | |
| 335 void computePipelineOptimizations(GrInitInvariantOutput* color, | |
| 336 GrInitInvariantOutput* coverage, | |
| 337 GrBatchToXPOverrides* overrides) const ove
rride { | |
| 338 // When this is called on a batch, there is only one rect | |
| 339 color->setKnownFourComponents(fRects[0].fColor); | |
| 340 coverage->setUnknownSingleComponent(); | |
| 341 } | |
| 342 | |
| 343 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | |
| 344 overrides.getOverrideColorIfSet(&fRects[0].fColor); | |
| 345 fOverrides = overrides; | |
| 346 } | |
| 347 | |
| 348 private: | |
| 349 AAFillRectLocalMatrixBatch() : INHERITED(ClassID()) {} | |
| 350 | |
| 351 void onPrepareDraws(Target* target) const override { | |
| 352 sk_sp<GrGeometryProcessor> gp = | |
| 353 create_fill_rect_gp(fRects[0].fViewMatrix, fOverrides, | |
| 354 GrDefaultGeoProcFactory::LocalCoords::kHasEx
plicit_Type); | |
| 355 if (!gp) { | |
| 356 SkDebugf("Couldn't create GrGeometryProcessor\n"); | |
| 357 return; | |
| 358 } | |
| 359 SkASSERT(fOverrides.canTweakAlphaForCoverage() ? | |
| 360 gp->getVertexStride() == | |
| 361 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) : | |
| 362 gp->getVertexStride() == | |
| 363 sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordCoverage
)); | |
| 364 | |
| 365 size_t vertexStride = gp->getVertexStride(); | |
| 366 | |
| 367 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour
ceProvider())); | |
| 368 InstancedHelper helper; | |
| 369 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, | |
| 370 indexBuffer, kVertsPerAAFillRect, | |
| 371 kIndicesPerAAFillRect, fRects.count()); | |
| 372 if (!vertices || !indexBuffer) { | |
| 373 SkDebugf("Could not allocate vertices\n"); | |
| 374 return; | |
| 375 } | |
| 376 | |
| 377 for (int i = 0; i < fRects.count(); i++) { | |
| 378 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + | |
| 379 i * kVertsPerAAFillRect * vertexStride; | |
| 380 generate_aa_fill_rect_geometry(verts, vertexStride, fRects[i].fColor
, | |
| 381 fRects[i].fViewMatrix, fRects[i].fRec
t, | |
| 382 fRects[i].fDevRect, fOverrides, | |
| 383 &fRects[i].fLocalMatrix); | |
| 384 } | |
| 385 helper.recordDraw(target, gp.get()); | |
| 386 } | |
| 387 | |
| 388 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | |
| 389 AAFillRectLocalMatrixBatch* that = t->cast<AAFillRectLocalMatrixBatch>()
; | |
| 390 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | 268 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
| 391 that->bounds(), caps)) { | 269 that->bounds(), caps)) { |
| 392 return false; | 270 return false; |
| 393 } | 271 } |
| 394 | 272 |
| 395 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to | 273 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to |
| 396 // not tweaking | 274 // not tweaking |
| 397 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { | 275 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { |
| 398 fOverrides = that->fOverrides; | 276 fOverrides = that->fOverrides; |
| 399 } | 277 } |
| 400 | 278 |
| 401 fRects.push_back_n(that->fRects.count(), that->fRects.begin()); | 279 fRectData.push_back_n(that->fRectData.count(), that->fRectData.begin()); |
| 280 fRectCnt += that->fRectCnt; |
| 402 this->joinBounds(that->bounds()); | 281 this->joinBounds(that->bounds()); |
| 403 return true; | 282 return true; |
| 404 } | 283 } |
| 405 | 284 |
| 406 struct RectInfo { | 285 struct RectInfo { |
| 286 public: |
| 287 RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, |
| 288 const SkRect& devRect) |
| 289 : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kNo) {} |
| 290 bool hasLocalMatrix() const { return HasLocalMatrix::kYes == fHasLocalMa
trix; } |
| 291 GrColor color() const { return fColor; } |
| 292 const SkMatrix& viewMatrix() const { return fViewMatrix; } |
| 293 const SkRect& rect() const { return fRect; } |
| 294 const SkRect& devRect() const { return fDevRect; } |
| 295 |
| 296 void setColor(GrColor color) { fColor = color; } |
| 297 protected: |
| 298 enum class HasLocalMatrix : uint32_t { kNo, kYes }; |
| 299 |
| 300 RectInfo(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, |
| 301 const SkRect& devRect, HasLocalMatrix hasLM) |
| 302 : fHasLocalMatrix(hasLM) |
| 303 , fColor(color) |
| 304 , fViewMatrix(viewMatrix) |
| 305 , fRect(rect) |
| 306 , fDevRect(devRect) {} |
| 307 |
| 308 HasLocalMatrix fHasLocalMatrix; |
| 407 GrColor fColor; | 309 GrColor fColor; |
| 408 SkMatrix fViewMatrix; | 310 SkMatrix fViewMatrix; |
| 409 SkMatrix fLocalMatrix; | |
| 410 SkRect fRect; | 311 SkRect fRect; |
| 411 SkRect fDevRect; | 312 SkRect fDevRect; |
| 412 }; | 313 }; |
| 413 | 314 |
| 315 struct RectWithLocalMatrixInfo : public RectInfo { |
| 316 public: |
| 317 RectWithLocalMatrixInfo(GrColor color, const SkMatrix& viewMatrix, const
SkRect& rect, |
| 318 const SkRect& devRect, const SkMatrix& localMatr
ix) |
| 319 : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kYes) |
| 320 , fLocalMatrix(localMatrix) {} |
| 321 const SkMatrix& localMatrix() const { return fLocalMatrix; } |
| 322 private: |
| 323 SkMatrix fLocalMatrix; |
| 324 }; |
| 325 |
| 326 RectInfo* first() { return reinterpret_cast<RectInfo*>(fRectData.begin()); } |
| 327 const RectInfo* first() const { return reinterpret_cast<const RectInfo*>(fRe
ctData.begin()); } |
| 328 const RectInfo* next(const RectInfo* prev) const { |
| 329 intptr_t next = reinterpret_cast<intptr_t>(prev) + |
| 330 (prev->hasLocalMatrix() ? sizeof(RectWithLocalMatrixInfo) |
| 331 : sizeof(RectInfo)); |
| 332 return reinterpret_cast<const RectInfo*>(next); |
| 333 } |
| 334 |
| 414 GrXPOverridesForBatch fOverrides; | 335 GrXPOverridesForBatch fOverrides; |
| 415 SkSTArray<1, RectInfo, true> fRects; | 336 SkSTArray<4 * sizeof(RectWithLocalMatrixInfo), uint8_t, true> fRectData; |
| 337 int fRectCnt; |
| 416 | 338 |
| 417 typedef GrVertexBatch INHERITED; | 339 typedef GrVertexBatch INHERITED; |
| 418 }; | 340 }; |
| 419 | 341 |
| 420 namespace GrAAFillRectBatch { | 342 namespace GrAAFillRectBatch { |
| 421 | 343 |
| 422 GrDrawBatch* Create(GrColor color, | 344 GrDrawBatch* Create(GrColor color, |
| 423 const SkMatrix& viewMatrix, | 345 const SkMatrix& viewMatrix, |
| 424 const SkRect& rect, | 346 const SkRect& rect, |
| 425 const SkRect& devRect) { | 347 const SkRect& devRect) { |
| 426 return new AAFillRectNoLocalMatrixBatch(color, viewMatrix, rect, devRect); | 348 return new AAFillRectBatch(color, viewMatrix, rect, devRect, nullptr); |
| 427 } | 349 } |
| 428 | 350 |
| 429 GrDrawBatch* Create(GrColor color, | 351 GrDrawBatch* Create(GrColor color, |
| 430 const SkMatrix& viewMatrix, | 352 const SkMatrix& viewMatrix, |
| 431 const SkMatrix& localMatrix, | 353 const SkMatrix& localMatrix, |
| 432 const SkRect& rect, | 354 const SkRect& rect, |
| 433 const SkRect& devRect) { | 355 const SkRect& devRect) { |
| 434 return new AAFillRectLocalMatrixBatch(color, viewMatrix, localMatrix, rect,
devRect); | 356 return new AAFillRectBatch(color, viewMatrix, rect, devRect, &localMatrix); |
| 435 } | 357 } |
| 436 | 358 |
| 437 GrDrawBatch* Create(GrColor color, | 359 GrDrawBatch* Create(GrColor color, |
| 438 const SkMatrix& viewMatrix, | 360 const SkMatrix& viewMatrix, |
| 439 const SkMatrix& localMatrix, | 361 const SkMatrix& localMatrix, |
| 440 const SkRect& rect) { | 362 const SkRect& rect) { |
| 441 SkRect devRect; | 363 SkRect devRect; |
| 442 viewMatrix.mapRect(&devRect, rect); | 364 viewMatrix.mapRect(&devRect, rect); |
| 443 return Create(color, viewMatrix, localMatrix, rect, devRect); | 365 return Create(color, viewMatrix, localMatrix, rect, devRect); |
| 444 } | 366 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 475 DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) { | 397 DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) { |
| 476 GrColor color = GrRandomColor(random); | 398 GrColor color = GrRandomColor(random); |
| 477 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); | 399 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); |
| 478 SkMatrix localMatrix = GrTest::TestMatrix(random); | 400 SkMatrix localMatrix = GrTest::TestMatrix(random); |
| 479 SkRect rect = GrTest::TestRect(random); | 401 SkRect rect = GrTest::TestRect(random); |
| 480 SkRect devRect = GrTest::TestRect(random); | 402 SkRect devRect = GrTest::TestRect(random); |
| 481 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRe
ct); | 403 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRe
ct); |
| 482 } | 404 } |
| 483 | 405 |
| 484 #endif | 406 #endif |
| OLD | NEW |