 Chromium Code Reviews
 Chromium Code Reviews Issue 2126893002:
  Hide NonAAStrokeRectBatch Geometry class and cleanup class.  (Closed) 
  Base URL: https://chromium.googlesource.com/skia.git@aastrokerectbatch
    
  
    Issue 2126893002:
  Hide NonAAStrokeRectBatch Geometry class and cleanup class.  (Closed) 
  Base URL: https://chromium.googlesource.com/skia.git@aastrokerectbatch| 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 "GrNonAAStrokeRectBatch.h" | 8 #include "GrNonAAStrokeRectBatch.h" | 
| 9 | 9 | 
| 10 #include "GrBatchTest.h" | 10 #include "GrBatchTest.h" | 
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 verts[2].set(rect.fRight - rad, rect.fTop + rad); | 30 verts[2].set(rect.fRight - rad, rect.fTop + rad); | 
| 31 verts[3].set(rect.fRight + rad, rect.fTop - rad); | 31 verts[3].set(rect.fRight + rad, rect.fTop - rad); | 
| 32 verts[4].set(rect.fRight - rad, rect.fBottom - rad); | 32 verts[4].set(rect.fRight - rad, rect.fBottom - rad); | 
| 33 verts[5].set(rect.fRight + rad, rect.fBottom + rad); | 33 verts[5].set(rect.fRight + rad, rect.fBottom + rad); | 
| 34 verts[6].set(rect.fLeft + rad, rect.fBottom - rad); | 34 verts[6].set(rect.fLeft + rad, rect.fBottom - rad); | 
| 35 verts[7].set(rect.fLeft - rad, rect.fBottom + rad); | 35 verts[7].set(rect.fLeft - rad, rect.fBottom + rad); | 
| 36 verts[8] = verts[0]; | 36 verts[8] = verts[0]; | 
| 37 verts[9] = verts[1]; | 37 verts[9] = verts[1]; | 
| 38 } | 38 } | 
| 39 | 39 | 
| 40 // Allow all hairlines and all miters, so long as the miter limit doesn't produc e beveled corners. | |
| 41 inline static bool allowed_stroke(const SkStrokeRec& stroke) { | |
| 42 SkASSERT(stroke.getStyle() == SkStrokeRec::kStroke_Style || | |
| 43 stroke.getStyle() == SkStrokeRec::kHairline_Style); | |
| 44 return !stroke.getWidth() || | |
| 45 (stroke.getJoin() == SkPaint::kMiter_Join && stroke.getMiter() > SK_S calarSqrt2); | |
| 46 } | |
| 47 | |
| 40 class NonAAStrokeRectBatch : public GrVertexBatch { | 48 class NonAAStrokeRectBatch : public GrVertexBatch { | 
| 41 public: | 49 public: | 
| 42 DEFINE_BATCH_CLASS_ID | 50 DEFINE_BATCH_CLASS_ID | 
| 43 | 51 | 
| 44 struct Geometry { | 52 const char* name() const override { return "NonAAStrokeRectBatch"; } | 
| 45 SkMatrix fViewMatrix; | |
| 46 SkRect fRect; | |
| 47 SkScalar fStrokeWidth; | |
| 48 GrColor fColor; | |
| 49 }; | |
| 50 | |
| 51 static NonAAStrokeRectBatch* Create() { | |
| 52 return new NonAAStrokeRectBatch; | |
| 53 } | |
| 54 | |
| 55 const char* name() const override { return "GrStrokeRectBatch"; } | |
| 56 | 53 | 
| 57 void computePipelineOptimizations(GrInitInvariantOutput* color, | 54 void computePipelineOptimizations(GrInitInvariantOutput* color, | 
| 58 GrInitInvariantOutput* coverage, | 55 GrInitInvariantOutput* coverage, | 
| 59 GrBatchToXPOverrides* overrides) const ove rride { | 56 GrBatchToXPOverrides* overrides) const ove rride { | 
| 60 // When this is called on a batch, there is only one geometry bundle | 57 // When this is called on a batch, there is only one geometry bundle | 
| 61 color->setKnownFourComponents(fGeoData[0].fColor); | 58 color->setKnownFourComponents(fColor); | 
| 62 coverage->setKnownSingleComponent(0xff); | 59 coverage->setKnownSingleComponent(0xff); | 
| 63 } | 60 } | 
| 64 | 61 | 
| 65 void append(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, | 62 static GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, | 
| 66 SkScalar strokeWidth) { | 63 const SkStrokeRec& stroke, bool snapToPixelCenter s) { | 
| 67 Geometry& geometry = fGeoData.push_back(); | 64 if (!allowed_stroke(stroke)) { | 
| 68 geometry.fViewMatrix = viewMatrix; | 65 return nullptr; | 
| 69 geometry.fRect = rect; | 66 } | 
| 70 geometry.fStrokeWidth = strokeWidth; | 67 NonAAStrokeRectBatch* batch = new NonAAStrokeRectBatch(); | 
| 71 geometry.fColor = color; | 68 batch->fColor = color; | 
| 69 batch->fViewMatrix = viewMatrix; | |
| 70 batch->fRect = rect; | |
| 71 // Sort the rect for hairlines | |
| 72 batch->fRect.sort(); | |
| 73 batch->fStrokeWidth = stroke.getWidth(); | |
| 72 | 74 | 
| 73 // Sort the rect for hairlines | 75 batch->fBounds = batch->fRect; | 
| 74 geometry.fRect.sort(); | 76 SkScalar rad = SkScalarHalf(batch->fStrokeWidth); | 
| 75 } | 77 batch->fBounds.outset(rad, rad); | 
| 78 batch->fViewMatrix.mapRect(&batch->fBounds); | |
| 76 | 79 | 
| 77 void appendAndUpdateBounds(GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, | 80 // If our caller snaps to pixel centers then we have to round out the bo unds | 
| 78 SkScalar strokeWidth, bool snapToPixelCenters) { | 81 if (snapToPixelCenters) { | 
| 
robertphillips
2016/07/06 20:44:06
Greg just posted a CL that changes this code: http
 | |
| 79 this->append(color, viewMatrix, rect, strokeWidth); | 82 batch->fBounds.roundOut(); | 
| 80 | 83 } | 
| 81 SkRect bounds; | 84 return batch; | 
| 82 this->setupBounds(&bounds, fGeoData.back(), snapToPixelCenters); | |
| 83 this->joinBounds(bounds); | |
| 84 } | |
| 85 | |
| 86 void init(bool snapToPixelCenters) { | |
| 87 const Geometry& geo = fGeoData[0]; | |
| 88 fBatch.fHairline = geo.fStrokeWidth == 0; | |
| 89 | |
| 90 // setup bounds | |
| 91 this->setupBounds(&fBounds, geo, snapToPixelCenters); | |
| 92 } | 85 } | 
| 93 | 86 | 
| 94 private: | 87 private: | 
| 95 void setupBounds(SkRect* bounds, const Geometry& geo, bool snapToPixelCenter s) { | 88 NonAAStrokeRectBatch() : INHERITED(ClassID()) {} | 
| 96 *bounds = geo.fRect; | |
| 97 SkScalar rad = SkScalarHalf(geo.fStrokeWidth); | |
| 98 bounds->outset(rad, rad); | |
| 99 geo.fViewMatrix.mapRect(&fBounds); | |
| 100 | |
| 101 // If our caller snaps to pixel centers then we have to round out the bo unds | |
| 102 if (snapToPixelCenters) { | |
| 103 bounds->roundOut(); | |
| 104 } | |
| 105 } | |
| 106 | 89 | 
| 107 void onPrepareDraws(Target* target) const override { | 90 void onPrepareDraws(Target* target) const override { | 
| 108 sk_sp<GrGeometryProcessor> gp; | 91 sk_sp<GrGeometryProcessor> gp; | 
| 109 { | 92 { | 
| 110 using namespace GrDefaultGeoProcFactory; | 93 using namespace GrDefaultGeoProcFactory; | 
| 111 Color color(this->color()); | 94 Color color(fColor); | 
| 112 Coverage coverage(this->coverageIgnored() ? Coverage::kSolid_Type : | 95 Coverage coverage(fOverrides.readsCoverage() ? Coverage::kSolid_Type | 
| 113 Coverage::kNone_Type); | 96 : Coverage::kNone_Type) ; | 
| 114 LocalCoords localCoords(this->usesLocalCoords() ? LocalCoords::kUseP osition_Type : | 97 LocalCoords localCoords(fOverrides.readsLocalCoords() ? LocalCoords: :kUsePosition_Type : | 
| 115 LocalCoords::kUnus ed_Type); | 98 LocalCoords: :kUnused_Type); | 
| 116 gp = GrDefaultGeoProcFactory::Make(color, coverage, localCoords, thi s->viewMatrix()); | 99 gp = GrDefaultGeoProcFactory::Make(color, coverage, localCoords, fVi ewMatrix); | 
| 117 } | 100 } | 
| 118 | 101 | 
| 119 size_t vertexStride = gp->getVertexStride(); | 102 size_t vertexStride = gp->getVertexStride(); | 
| 120 | 103 | 
| 121 SkASSERT(vertexStride == sizeof(GrDefaultGeoProcFactory::PositionAttr)); | 104 SkASSERT(vertexStride == sizeof(GrDefaultGeoProcFactory::PositionAttr)); | 
| 122 | 105 | 
| 123 const Geometry& args = fGeoData[0]; | |
| 124 | |
| 125 int vertexCount = kVertsPerHairlineRect; | 106 int vertexCount = kVertsPerHairlineRect; | 
| 126 if (args.fStrokeWidth > 0) { | 107 if (fStrokeWidth > 0) { | 
| 127 vertexCount = kVertsPerStrokeRect; | 108 vertexCount = kVertsPerStrokeRect; | 
| 128 } | 109 } | 
| 129 | 110 | 
| 130 const GrBuffer* vertexBuffer; | 111 const GrBuffer* vertexBuffer; | 
| 131 int firstVertex; | 112 int firstVertex; | 
| 132 | 113 | 
| 133 void* verts = target->makeVertexSpace(vertexStride, vertexCount, &vertex Buffer, | 114 void* verts = target->makeVertexSpace(vertexStride, vertexCount, &vertex Buffer, | 
| 134 &firstVertex); | 115 &firstVertex); | 
| 135 | 116 | 
| 136 if (!verts) { | 117 if (!verts) { | 
| 137 SkDebugf("Could not allocate vertices\n"); | 118 SkDebugf("Could not allocate vertices\n"); | 
| 138 return; | 119 return; | 
| 139 } | 120 } | 
| 140 | 121 | 
| 141 SkPoint* vertex = reinterpret_cast<SkPoint*>(verts); | 122 SkPoint* vertex = reinterpret_cast<SkPoint*>(verts); | 
| 142 | 123 | 
| 143 GrPrimitiveType primType; | 124 GrPrimitiveType primType; | 
| 144 if (args.fStrokeWidth > 0) { | 125 if (fStrokeWidth > 0) { | 
| 145 primType = kTriangleStrip_GrPrimitiveType; | 126 primType = kTriangleStrip_GrPrimitiveType; | 
| 146 init_stroke_rect_strip(vertex, args.fRect, args.fStrokeWidth); | 127 init_stroke_rect_strip(vertex, fRect, fStrokeWidth); | 
| 147 } else { | 128 } else { | 
| 148 // hairline | 129 // hairline | 
| 149 primType = kLineStrip_GrPrimitiveType; | 130 primType = kLineStrip_GrPrimitiveType; | 
| 150 vertex[0].set(args.fRect.fLeft, args.fRect.fTop); | 131 vertex[0].set(fRect.fLeft, fRect.fTop); | 
| 151 vertex[1].set(args.fRect.fRight, args.fRect.fTop); | 132 vertex[1].set(fRect.fRight, fRect.fTop); | 
| 152 vertex[2].set(args.fRect.fRight, args.fRect.fBottom); | 133 vertex[2].set(fRect.fRight, fRect.fBottom); | 
| 153 vertex[3].set(args.fRect.fLeft, args.fRect.fBottom); | 134 vertex[3].set(fRect.fLeft, fRect.fBottom); | 
| 154 vertex[4].set(args.fRect.fLeft, args.fRect.fTop); | 135 vertex[4].set(fRect.fLeft, fRect.fTop); | 
| 155 } | 136 } | 
| 156 | 137 | 
| 157 GrMesh mesh; | 138 GrMesh mesh; | 
| 158 mesh.init(primType, vertexBuffer, firstVertex, vertexCount); | 139 mesh.init(primType, vertexBuffer, firstVertex, vertexCount); | 
| 159 target->draw(gp.get(), mesh); | 140 target->draw(gp.get(), mesh); | 
| 160 } | 141 } | 
| 161 | 142 | 
| 162 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | 143 void initBatchTracker(const GrXPOverridesForBatch& overrides) override { | 
| 163 // Handle any color overrides | 144 overrides.getOverrideColorIfSet(&fColor); | 
| 164 if (!overrides.readsColor()) { | 145 fOverrides = overrides; | 
| 165 fGeoData[0].fColor = GrColor_ILLEGAL; | |
| 166 } | |
| 167 overrides.getOverrideColorIfSet(&fGeoData[0].fColor); | |
| 168 | |
| 169 // setup batch properties | |
| 170 fBatch.fColorIgnored = !overrides.readsColor(); | |
| 171 fBatch.fColor = fGeoData[0].fColor; | |
| 172 fBatch.fUsesLocalCoords = overrides.readsLocalCoords(); | |
| 173 fBatch.fCoverageIgnored = !overrides.readsCoverage(); | |
| 174 } | 146 } | 
| 175 | 147 | 
| 176 NonAAStrokeRectBatch() : INHERITED(ClassID()) {} | |
| 177 | |
| 178 GrColor color() const { return fBatch.fColor; } | |
| 179 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | |
| 180 bool colorIgnored() const { return fBatch.fColorIgnored; } | |
| 181 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } | |
| 182 bool hairline() const { return fBatch.fHairline; } | |
| 183 bool coverageIgnored() const { return fBatch.fCoverageIgnored; } | |
| 184 | |
| 185 bool onCombineIfPossible(GrBatch* t, const GrCaps&) override { | 148 bool onCombineIfPossible(GrBatch* t, const GrCaps&) override { | 
| 186 // if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *t->pi peline(), | |
| 187 // t->bounds(), caps)) { | |
| 188 // return false; | |
| 189 // } | |
| 190 // GrStrokeRectBatch* that = t->cast<StrokeRectBatch>(); | |
| 191 | |
| 192 // NonAA stroke rects cannot batch right now | 149 // NonAA stroke rects cannot batch right now | 
| 193 // TODO make these batchable | 150 // TODO make these batchable | 
| 194 return false; | 151 return false; | 
| 195 } | 152 } | 
| 196 | 153 | 
| 197 struct BatchTracker { | 154 GrColor fColor; | 
| 198 GrColor fColor; | 155 SkMatrix fViewMatrix; | 
| 199 bool fUsesLocalCoords; | 156 SkRect fRect; | 
| 200 bool fColorIgnored; | 157 SkScalar fStrokeWidth; | 
| 201 bool fCoverageIgnored; | 158 | 
| 202 bool fHairline; | 159 GrXPOverridesForBatch fOverrides; | 
| 203 }; | |
| 204 | 160 | 
| 205 const static int kVertsPerHairlineRect = 5; | 161 const static int kVertsPerHairlineRect = 5; | 
| 206 const static int kVertsPerStrokeRect = 10; | 162 const static int kVertsPerStrokeRect = 10; | 
| 207 | 163 | 
| 208 BatchTracker fBatch; | |
| 209 SkSTArray<1, Geometry, true> fGeoData; | |
| 210 | 164 | 
| 211 typedef GrVertexBatch INHERITED; | 165 typedef GrVertexBatch INHERITED; | 
| 212 }; | 166 }; | 
| 213 | 167 | 
| 214 // Allow all hairlines and all miters, so long as the miter limit doesn't produc e beveled corners. | |
| 215 inline static bool allowed_stroke(const SkStrokeRec& stroke) { | |
| 216 SkASSERT(stroke.getStyle() == SkStrokeRec::kStroke_Style || | |
| 217 stroke.getStyle() == SkStrokeRec::kHairline_Style); | |
| 218 return !stroke.getWidth() || | |
| 219 (stroke.getJoin() == SkPaint::kMiter_Join && stroke.getMiter() > SK_ ScalarSqrt2); | |
| 220 } | |
| 221 | |
| 222 namespace GrNonAAStrokeRectBatch { | 168 namespace GrNonAAStrokeRectBatch { | 
| 223 | 169 | 
| 224 GrDrawBatch* Create(GrColor color, | 170 GrDrawBatch* Create(GrColor color, | 
| 225 const SkMatrix& viewMatrix, | 171 const SkMatrix& viewMatrix, | 
| 226 const SkRect& rect, | 172 const SkRect& rect, | 
| 227 const SkStrokeRec& stroke, | 173 const SkStrokeRec& stroke, | 
| 228 bool snapToPixelCenters) { | 174 bool snapToPixelCenters) { | 
| 229 if (!allowed_stroke(stroke)) { | 175 return NonAAStrokeRectBatch::Create(color, viewMatrix, rect, stroke, snapToP ixelCenters); | 
| 230 return nullptr; | |
| 231 } | |
| 232 NonAAStrokeRectBatch* batch = NonAAStrokeRectBatch::Create(); | |
| 233 batch->append(color, viewMatrix, rect, stroke.getWidth()); | |
| 234 batch->init(snapToPixelCenters); | |
| 235 return batch; | |
| 236 } | 176 } | 
| 237 | 177 | 
| 238 }; | 178 } | 
| 239 | 179 | 
| 240 #ifdef GR_TEST_UTILS | 180 #ifdef GR_TEST_UTILS | 
| 241 | 181 | 
| 242 DRAW_BATCH_TEST_DEFINE(NonAAStrokeRectBatch) { | 182 DRAW_BATCH_TEST_DEFINE(NonAAStrokeRectBatch) { | 
| 243 SkMatrix viewMatrix = GrTest::TestMatrix(random); | 183 SkMatrix viewMatrix = GrTest::TestMatrix(random); | 
| 244 GrColor color = GrRandomColor(random); | 184 GrColor color = GrRandomColor(random); | 
| 245 SkRect rect = GrTest::TestRect(random); | 185 SkRect rect = GrTest::TestRect(random); | 
| 246 SkScalar strokeWidth = random->nextBool() ? 0.0f : 2.0f; | 186 SkScalar strokeWidth = random->nextBool() ? 0.0f : 2.0f; | 
| 247 SkPaint paint; | 187 SkPaint paint; | 
| 248 paint.setStrokeWidth(strokeWidth); | 188 paint.setStrokeWidth(strokeWidth); | 
| 249 paint.setStyle(SkPaint::kStroke_Style); | 189 paint.setStyle(SkPaint::kStroke_Style); | 
| 250 paint.setStrokeJoin(SkPaint::kMiter_Join); | 190 paint.setStrokeJoin(SkPaint::kMiter_Join); | 
| 251 SkStrokeRec strokeRec(paint); | 191 SkStrokeRec strokeRec(paint); | 
| 252 return GrNonAAStrokeRectBatch::Create(color, viewMatrix, rect, strokeRec, ra ndom->nextBool()); | 192 return GrNonAAStrokeRectBatch::Create(color, viewMatrix, rect, strokeRec, ra ndom->nextBool()); | 
| 253 } | 193 } | 
| 254 | 194 | 
| 255 #endif | 195 #endif | 
| OLD | NEW |