| 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" | |
| 17 #include "SkMatrix.h" | 16 #include "SkMatrix.h" |
| 18 #include "SkRect.h" | 17 #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 |
| 48 static void generate_aa_fill_rect_geometry(intptr_t verts, | 77 static void generate_aa_fill_rect_geometry(intptr_t verts, |
| 49 size_t vertexStride, | 78 size_t vertexStride, |
| 50 GrColor color, | 79 GrColor color, |
| 51 const SkMatrix& viewMatrix, | 80 const SkMatrix& viewMatrix, |
| 52 const SkRect& rect, | 81 const SkRect& rect, |
| 53 const SkRect& devRect, | 82 const SkRect& devRect, |
| 54 const GrXPOverridesForBatch& override
s, | 83 const GrXPOverridesForBatch& override
s, |
| 55 const SkMatrix* localMatrix) { | 84 const SkMatrix* localMatrix) { |
| 56 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); | 85 SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts); |
| 57 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); | 86 SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1]; | 130 *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1]; |
| 102 // TR | 131 // TR |
| 103 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) = | 132 *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) = |
| 104 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1
]; | 133 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1
]; |
| 105 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1]; | 134 *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1]; |
| 106 } | 135 } |
| 107 | 136 |
| 108 if (localMatrix) { | 137 if (localMatrix) { |
| 109 SkMatrix invViewMatrix; | 138 SkMatrix invViewMatrix; |
| 110 if (!viewMatrix.invert(&invViewMatrix)) { | 139 if (!viewMatrix.invert(&invViewMatrix)) { |
| 111 SkDebugf("View matrix is non-invertible, local coords will be wrong.
"); | 140 SkASSERT(false); |
| 112 invViewMatrix = SkMatrix::I(); | 141 invViewMatrix = SkMatrix::I(); |
| 113 } | 142 } |
| 114 SkMatrix localCoordMatrix; | 143 SkMatrix localCoordMatrix; |
| 115 localCoordMatrix.setConcat(*localMatrix, invViewMatrix); | 144 localCoordMatrix.setConcat(*localMatrix, invViewMatrix); |
| 116 SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(verts + sizeof(SkPoint) +
sizeof(GrColor)); | 145 SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(verts + sizeof(SkPoint) +
sizeof(GrColor)); |
| 117 localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8); | 146 localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8); |
| 118 } | 147 } |
| 119 | 148 |
| 120 bool tweakAlphaForCoverage = overrides.canTweakAlphaForCoverage(); | 149 bool tweakAlphaForCoverage = overrides.canTweakAlphaForCoverage(); |
| 121 | 150 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 150 for (int i = 0; i < 4; ++i) { | 179 for (int i = 0; i < 4; ++i) { |
| 151 if (tweakAlphaForCoverage) { | 180 if (tweakAlphaForCoverage) { |
| 152 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; | 181 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; |
| 153 } else { | 182 } else { |
| 154 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; | 183 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
| 155 *reinterpret_cast<float*>(verts + i * vertexStride + | 184 *reinterpret_cast<float*>(verts + i * vertexStride + |
| 156 coverageOffset) = innerCoverage; | 185 coverageOffset) = innerCoverage; |
| 157 } | 186 } |
| 158 } | 187 } |
| 159 } | 188 } |
| 160 class AAFillRectBatch : public GrVertexBatch { | 189 |
| 190 class AAFillRectNoLocalMatrixBatch : public GrVertexBatch { |
| 161 public: | 191 public: |
| 162 DEFINE_BATCH_CLASS_ID | 192 DEFINE_BATCH_CLASS_ID |
| 163 | 193 AAFillRectNoLocalMatrixBatch(GrColor color, |
| 164 AAFillRectBatch(GrColor color, | 194 const SkMatrix& viewMatrix, |
| 165 const SkMatrix& viewMatrix, | 195 const SkRect& rect, |
| 166 const SkRect& rect, | 196 const SkRect& devRect) : INHERITED(ClassID()) { |
| 167 const SkRect& devRect, | 197 fRects.emplace_back(RectInfo{color, viewMatrix, rect, 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 } | |
| 176 fBounds = devRect; | 198 fBounds = devRect; |
| 177 fRectCnt = 1; | |
| 178 } | 199 } |
| 179 | 200 |
| 180 const char* name() const override { return "AAFillRectBatch"; } | 201 const char* name() const override { return "AAFillRectBatchNoLocalMatrix"; } |
| 181 | 202 |
| 182 SkString dumpInfo() const override { | 203 SkString dumpInfo() const override { |
| 183 SkString str; | 204 SkString str; |
| 184 str.appendf("# batched: %d\n", fRectCnt); | 205 str.appendf("# batched: %d\n", fRects.count()); |
| 185 const RectInfo* info = this->first(); | 206 for (int i = 0; i < fRects.count(); ++i) { |
| 186 for (int i = 0; i < fRectCnt; ++i) { | 207 const RectInfo& info = fRects[i]; |
| 187 const SkRect& rect = info->rect(); | |
| 188 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", | 208 str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B:
%.2f]\n", |
| 189 i, info->color(), rect.fLeft, rect.fTop, rect.fRight, re
ct.fBottom); | 209 i, info.fColor, |
| 190 info = this->next(info); | 210 info.fRect.fLeft, info.fRect.fTop, info.fRect.fRight, in
fo.fRect.fBottom); |
| 191 } | 211 } |
| 192 str.append(INHERITED::dumpInfo()); | 212 str.append(INHERITED::dumpInfo()); |
| 193 return str; | 213 return str; |
| 194 } | 214 } |
| 195 | 215 |
| 196 void computePipelineOptimizations(GrInitInvariantOutput* color, | 216 void computePipelineOptimizations(GrInitInvariantOutput* color, |
| 197 GrInitInvariantOutput* coverage, | 217 GrInitInvariantOutput* coverage, |
| 198 GrBatchToXPOverrides* overrides) const ove
rride { | 218 GrBatchToXPOverrides* overrides) const ove
rride { |
| 199 // When this is called on a batch, there is only one rect | 219 // When this is called on a batch, there is only one rect |
| 200 color->setKnownFourComponents(this->first()->color()); | 220 color->setKnownFourComponents(fRects[0].fColor); |
| 201 coverage->setUnknownSingleComponent(); | 221 coverage->setUnknownSingleComponent(); |
| 202 } | 222 } |
| 203 | 223 |
| 204 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | 224 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { |
| 205 GrColor color; | 225 overrides.getOverrideColorIfSet(&fRects[0].fColor); |
| 206 if (overrides.getOverrideColorIfSet(&color)) { | |
| 207 this->first()->setColor(color); | |
| 208 } | |
| 209 fOverrides = overrides; | 226 fOverrides = overrides; |
| 210 } | 227 } |
| 211 | 228 |
| 212 private: | 229 private: |
| 230 AAFillRectNoLocalMatrixBatch() : INHERITED(ClassID()) {} |
| 231 |
| 213 void onPrepareDraws(Target* target) const override { | 232 void onPrepareDraws(Target* target) const override { |
| 214 bool needLocalCoords = fOverrides.readsLocalCoords(); | 233 sk_sp<GrGeometryProcessor> gp = |
| 215 using namespace GrDefaultGeoProcFactory; | 234 create_fill_rect_gp(fRects[0].fViewMatrix, fOverrides, |
| 216 | 235 GrDefaultGeoProcFactory::LocalCoords::kUsePo
sition_Type); |
| 217 Color color(Color::kAttribute_Type); | |
| 218 Coverage::Type coverageType; | |
| 219 if (fOverrides.canTweakAlphaForCoverage()) { | |
| 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()); | |
| 229 if (!gp) { | 236 if (!gp) { |
| 230 SkDebugf("Couldn't create GrGeometryProcessor\n"); | 237 SkDebugf("Couldn't create GrGeometryProcessor\n"); |
| 231 return; | 238 return; |
| 232 } | 239 } |
| 240 SkASSERT(fOverrides.canTweakAlphaForCoverage() ? |
| 241 gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::Po
sitionColorAttr) : |
| 242 gp->getVertexStride() == |
| 243 sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAt
tr)); |
| 233 | 244 |
| 234 size_t vertexStride = gp->getVertexStride(); | 245 size_t vertexStride = gp->getVertexStride(); |
| 235 | 246 |
| 236 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour
ceProvider())); | 247 SkAutoTUnref<const GrBuffer> indexBuffer(get_index_buffer(target->resour
ceProvider())); |
| 237 InstancedHelper helper; | 248 InstancedHelper helper; |
| 238 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, | 249 void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexS
tride, |
| 239 indexBuffer, kVertsPerAAFillRect, | 250 indexBuffer, kVertsPerAAFillRect, |
| 240 kIndicesPerAAFillRect, fRectCnt); | 251 kIndicesPerAAFillRect, fRects.count()); |
| 241 if (!vertices || !indexBuffer) { | 252 if (!vertices || !indexBuffer) { |
| 242 SkDebugf("Could not allocate vertices\n"); | 253 SkDebugf("Could not allocate vertices\n"); |
| 243 return; | 254 return; |
| 244 } | 255 } |
| 245 | 256 |
| 246 const RectInfo* info = this->first(); | 257 for (int i = 0; i < fRects.count(); i++) { |
| 247 const SkMatrix* localMatrix = nullptr; | |
| 248 for (int i = 0; i < fRectCnt; i++) { | |
| 249 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + | 258 intptr_t verts = reinterpret_cast<intptr_t>(vertices) + |
| 250 i * kVertsPerAAFillRect * vertexStride; | 259 i * kVertsPerAAFillRect * vertexStride; |
| 251 if (needLocalCoords) { | 260 generate_aa_fill_rect_geometry(verts, vertexStride, |
| 252 if (info->hasLocalMatrix()) { | 261 fRects[i].fColor, fRects[i].fViewMatr
ix, |
| 253 localMatrix = &static_cast<const RectWithLocalMatrixInfo*>(i
nfo)->localMatrix(); | 262 fRects[i].fRect, fRects[i].fDevRect,
fOverrides, |
| 254 } else { | 263 nullptr); |
| 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); | |
| 262 } | 264 } |
| 263 helper.recordDraw(target, gp.get()); | 265 helper.recordDraw(target, gp.get()); |
| 264 } | 266 } |
| 265 | 267 |
| 266 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 268 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
| 267 AAFillRectBatch* that = t->cast<AAFillRectBatch>(); | 269 AAFillRectNoLocalMatrixBatch* that = t->cast<AAFillRectNoLocalMatrixBatc
h>(); |
| 268 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | 270 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
| 269 that->bounds(), caps)) { | 271 that->bounds(), caps)) { |
| 270 return false; | 272 return false; |
| 271 } | 273 } |
| 272 | 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 |
| 273 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to | 283 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to |
| 274 // not tweaking | 284 // not tweaking |
| 275 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { | 285 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { |
| 276 fOverrides = that->fOverrides; | 286 fOverrides = that->fOverrides; |
| 277 } | 287 } |
| 278 | 288 |
| 279 fRectData.push_back_n(that->fRectData.count(), that->fRectData.begin()); | 289 fRects.push_back_n(that->fRects.count(), that->fRects.begin()); |
| 280 fRectCnt += that->fRectCnt; | |
| 281 this->joinBounds(that->bounds()); | 290 this->joinBounds(that->bounds()); |
| 282 return true; | 291 return true; |
| 283 } | 292 } |
| 284 | 293 |
| 285 struct RectInfo { | 294 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; | |
| 309 GrColor fColor; | 295 GrColor fColor; |
| 310 SkMatrix fViewMatrix; | 296 SkMatrix fViewMatrix; |
| 311 SkRect fRect; | 297 SkRect fRect; |
| 312 SkRect fDevRect; | 298 SkRect fDevRect; |
| 313 }; | 299 }; |
| 314 | 300 |
| 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 | |
| 335 GrXPOverridesForBatch fOverrides; | 301 GrXPOverridesForBatch fOverrides; |
| 336 SkSTArray<4 * sizeof(RectWithLocalMatrixInfo), uint8_t, true> fRectData; | 302 SkSTArray<1, RectInfo, true> fRects; |
| 337 int fRectCnt; | |
| 338 | 303 |
| 339 typedef GrVertexBatch INHERITED; | 304 typedef GrVertexBatch INHERITED; |
| 340 }; | 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(), |
| 391 that->bounds(), caps)) { |
| 392 return false; |
| 393 } |
| 394 |
| 395 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to |
| 396 // not tweaking |
| 397 if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakA
lphaForCoverage()) { |
| 398 fOverrides = that->fOverrides; |
| 399 } |
| 400 |
| 401 fRects.push_back_n(that->fRects.count(), that->fRects.begin()); |
| 402 this->joinBounds(that->bounds()); |
| 403 return true; |
| 404 } |
| 405 |
| 406 struct RectInfo { |
| 407 GrColor fColor; |
| 408 SkMatrix fViewMatrix; |
| 409 SkMatrix fLocalMatrix; |
| 410 SkRect fRect; |
| 411 SkRect fDevRect; |
| 412 }; |
| 413 |
| 414 GrXPOverridesForBatch fOverrides; |
| 415 SkSTArray<1, RectInfo, true> fRects; |
| 416 |
| 417 typedef GrVertexBatch INHERITED; |
| 418 }; |
| 341 | 419 |
| 342 namespace GrAAFillRectBatch { | 420 namespace GrAAFillRectBatch { |
| 343 | 421 |
| 344 GrDrawBatch* Create(GrColor color, | 422 GrDrawBatch* Create(GrColor color, |
| 345 const SkMatrix& viewMatrix, | 423 const SkMatrix& viewMatrix, |
| 346 const SkRect& rect, | 424 const SkRect& rect, |
| 347 const SkRect& devRect) { | 425 const SkRect& devRect) { |
| 348 return new AAFillRectBatch(color, viewMatrix, rect, devRect, nullptr); | 426 return new AAFillRectNoLocalMatrixBatch(color, viewMatrix, rect, devRect); |
| 349 } | 427 } |
| 350 | 428 |
| 351 GrDrawBatch* Create(GrColor color, | 429 GrDrawBatch* Create(GrColor color, |
| 352 const SkMatrix& viewMatrix, | 430 const SkMatrix& viewMatrix, |
| 353 const SkMatrix& localMatrix, | 431 const SkMatrix& localMatrix, |
| 354 const SkRect& rect, | 432 const SkRect& rect, |
| 355 const SkRect& devRect) { | 433 const SkRect& devRect) { |
| 356 return new AAFillRectBatch(color, viewMatrix, rect, devRect, &localMatrix); | 434 return new AAFillRectLocalMatrixBatch(color, viewMatrix, localMatrix, rect,
devRect); |
| 357 } | 435 } |
| 358 | 436 |
| 359 GrDrawBatch* Create(GrColor color, | 437 GrDrawBatch* Create(GrColor color, |
| 360 const SkMatrix& viewMatrix, | 438 const SkMatrix& viewMatrix, |
| 361 const SkMatrix& localMatrix, | 439 const SkMatrix& localMatrix, |
| 362 const SkRect& rect) { | 440 const SkRect& rect) { |
| 363 SkRect devRect; | 441 SkRect devRect; |
| 364 viewMatrix.mapRect(&devRect, rect); | 442 viewMatrix.mapRect(&devRect, rect); |
| 365 return Create(color, viewMatrix, localMatrix, rect, devRect); | 443 return Create(color, viewMatrix, localMatrix, rect, devRect); |
| 366 } | 444 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 397 DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) { | 475 DRAW_BATCH_TEST_DEFINE(AAFillRectBatchLocalMatrix) { |
| 398 GrColor color = GrRandomColor(random); | 476 GrColor color = GrRandomColor(random); |
| 399 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); | 477 SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); |
| 400 SkMatrix localMatrix = GrTest::TestMatrix(random); | 478 SkMatrix localMatrix = GrTest::TestMatrix(random); |
| 401 SkRect rect = GrTest::TestRect(random); | 479 SkRect rect = GrTest::TestRect(random); |
| 402 SkRect devRect = GrTest::TestRect(random); | 480 SkRect devRect = GrTest::TestRect(random); |
| 403 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRe
ct); | 481 return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRe
ct); |
| 404 } | 482 } |
| 405 | 483 |
| 406 #endif | 484 #endif |
| OLD | NEW |