Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2015 Google Inc. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license that can be | |
| 5 * found in the LICENSE file. | |
| 6 */ | |
| 7 | |
| 8 #include "GrDrawRect.h" | |
| 9 | |
| 10 #include "GrContext.h" | |
| 11 #include "GrClip.h" | |
| 12 #include "GrDrawTarget.h" | |
| 13 #include "GrRenderTarget.h" | |
| 14 #include "GrStrokeInfo.h" | |
| 15 #include "SkColorFilter.h" | |
| 16 #include "SkImageFilter.h" | |
| 17 #include "SkGr.h" | |
| 18 #include "SkMatrix.h" | |
| 19 #include "SkMaskFilter.h" | |
| 20 #include "SkPaint.h" | |
| 21 #include "SkRect.h" | |
| 22 #include "SkShader.h" | |
| 23 #include "SkXfermode.h" | |
| 24 #include "batches/GrRectBatchFactory.h" | |
| 25 | |
|
robertphillips
2015/09/25 12:48:49
AAStroke
AAFill
BWStroke
BWFill
?
joshualitt
2015/09/25 18:17:13
Brian doesn't like BW
robertphillips
2015/09/25 20:00:35
I proposing a reordering not a renaming.
| |
| 26 enum RectBatchType { | |
| 27 kAAStroke_RectBatchType, | |
| 28 kAAFill_RectBatchType, | |
| 29 kNonAAFill_RectBatchType, | |
| 30 kNonAAStroke_RectBatchType, | |
| 31 }; | |
| 32 | |
| 33 class GrDrawRectSnap : public GrDrawSnap { | |
| 34 public: | |
| 35 GrDrawRectSnap(const SkPaint& paint, | |
| 36 const GrClip& clip, | |
| 37 RectBatchType type, | |
| 38 bool snapToPixelCenter) | |
| 39 : fShader(SkSafeRef(paint.getShader())) | |
| 40 , fMaskFilter(SkSafeRef(paint.getMaskFilter())) | |
|
bsalomon
2015/09/23 13:49:38
Maybe just punt if the originating paint has a IM,
joshualitt
2015/09/25 18:17:13
Acknowledged.
| |
| 41 , fImageFilter(SkSafeRef(paint.getImageFilter())) | |
| 42 , fColorFilter(SkSafeRef(paint.getColorFilter())) | |
| 43 , fClipGenID(clip.clipType() != GrClip::kClipStack_ClipType ? | |
| 44 -1 : | |
| 45 clip.clipStack()->getTopmostGenID()) | |
| 46 , fType(type) | |
| 47 , fSnapToPixelCenters(snapToPixelCenter) | |
| 48 , fIsDither(paint.isDither()) { | |
| 49 fClassID = GrDrawRect::ClassID(); | |
| 50 } | |
| 51 | |
| 52 bool canBatch(const SkPaint& paint, | |
| 53 const GrClip& clip, | |
| 54 RectBatchType type, | |
| 55 bool snapToPixelCenters) const { | |
| 56 return paint.getShader() == fShader && | |
| 57 paint.getMaskFilter() == fMaskFilter && | |
| 58 paint.getImageFilter() == fImageFilter && | |
| 59 paint.getColorFilter() == fColorFilter && | |
| 60 paint.isDither() == fIsDither && | |
| 61 fClipGenID != -1 && clip.clipType() == GrClip::kClipStack_ClipTyp e && | |
| 62 fClipGenID == clip.clipStack()->getTopmostGenID() && | |
| 63 fType == type && | |
| 64 fSnapToPixelCenters == snapToPixelCenters; | |
| 65 } | |
| 66 | |
| 67 // we only bother fast pathing kSrcOver_Mode, though we could do quite a bit more | |
| 68 static bool CanSnap(const SkPaint& paint) { | |
|
bsalomon
2015/09/23 13:49:38
kSrcOver_Mode is always a nullptr for paint.getXfe
joshualitt
2015/09/25 18:17:13
Acknowledged.
| |
| 69 return SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode ); | |
| 70 } | |
| 71 | |
| 72 private: | |
| 73 SkAutoTUnref<SkShader> fShader; | |
| 74 SkAutoTUnref<SkMaskFilter> fMaskFilter; | |
| 75 SkAutoTUnref<SkImageFilter> fImageFilter; | |
| 76 SkAutoTUnref<SkColorFilter> fColorFilter; | |
| 77 int32_t fClipGenID; | |
| 78 RectBatchType fType; | |
| 79 bool fSnapToPixelCenters; | |
| 80 bool fIsDither; | |
| 81 | |
| 82 typedef GrDrawSnap INHERITED; | |
| 83 }; | |
| 84 | |
| 85 inline static RectBatchType compute_rect_batch_type(bool useAA, SkScalar width) { | |
| 86 if (useAA) { | |
| 87 if (width >= 0) { | |
| 88 return kAAStroke_RectBatchType; | |
| 89 } else { | |
| 90 return kAAFill_RectBatchType; | |
| 91 } | |
| 92 } else if (width >= 0) { | |
| 93 return kNonAAStroke_RectBatchType; | |
| 94 } else { | |
| 95 return kNonAAFill_RectBatchType; | |
| 96 } | |
| 97 } | |
| 98 | |
| 99 inline static bool can_fastpath(GrDrawTarget* drawTarget, | |
| 100 const SkPaint& paint, | |
| 101 const GrClip& clip, | |
| 102 GrColor color, | |
| 103 const SkMatrix& viewMatrix, | |
| 104 const SkRect& rect, | |
| 105 const GrStrokeInfo& strokeInfo, | |
| 106 RectBatchType batchType, | |
| 107 bool snapToPixelCenters) { | |
| 108 GrBatch* lastBatch = drawTarget->lastBatch(); | |
| 109 if (!lastBatch) { | |
| 110 return false; | |
| 111 } | |
| 112 | |
|
robertphillips
2015/09/25 12:48:49
drawSnap -> getLastSnap ?
calling drawSnap here s
joshualitt
2015/09/25 18:17:13
Acknowledged.
| |
| 113 const GrDrawSnap* lastSnap = lastBatch->drawSnap(); | |
| 114 if (!lastSnap) { | |
| 115 return false; | |
| 116 } | |
| 117 | |
| 118 if (lastSnap->classID() != GrDrawRect::ClassID()) { | |
| 119 return false; | |
| 120 } | |
| 121 | |
| 122 const GrDrawRectSnap* lastSnapCast = static_cast<const GrDrawRectSnap*>(last Snap); | |
| 123 if (lastSnapCast->canBatch(paint, clip, batchType, snapToPixelCenters)) { | |
| 124 switch (batchType) { | |
| 125 case kAAStroke_RectBatchType: | |
|
bsalomon
2015/09/23 13:49:38
Would it make sense to store an Append()/Create()
robertphillips
2015/09/25 12:48:49
We would still have to deal with all the different
joshualitt
2015/09/25 18:17:13
yea, I think in the short term this is the best wa
| |
| 126 if (GrAAStrokeRectBatch::Append(lastBatch, color, viewMatrix, re ct, | |
| 127 strokeInfo)) { | |
| 128 return true; | |
| 129 } | |
| 130 break; | |
| 131 case kAAFill_RectBatchType: | |
| 132 GrAAFillRectBatch::Append(lastBatch, color, viewMatrix, rect); | |
| 133 return true; | |
| 134 case kNonAAFill_RectBatchType: | |
| 135 if (GrNonAAFillRectBatch::Append(lastBatch, color, viewMatrix, r ect, | |
| 136 nullptr, nullptr)) { | |
| 137 return true; | |
| 138 } | |
| 139 break; | |
| 140 case kNonAAStroke_RectBatchType: | |
| 141 // GrNonAAStrokeRectBatch doesn't batch yet | |
| 142 break; | |
| 143 } | |
| 144 } | |
| 145 | |
| 146 return false; | |
| 147 } | |
| 148 | |
| 149 void GrDrawRect::execute(GrDrawTarget* drawTarget) const { | |
| 150 const SkPaint& paint = *fPaint; | |
| 151 const GrClip& clip = *fClip; | |
| 152 const SkMatrix& viewMatrix = *fViewMatrix; | |
| 153 const SkRect& rect = *fRect; | |
| 154 | |
|
robertphillips
2015/09/25 12:48:49
Didn't we pull all the info for fStrokeInfo out of
joshualitt
2015/09/25 18:17:13
yes, but why pull it out again if we don't have to
| |
| 155 SkScalar width = nullptr == fStrokeInfo ? -1 : fStrokeInfo->getWidth(); | |
| 156 | |
| 157 bool needAA = fPaint->isAntiAlias() && !fRenderTarget->isUnifiedMultisampled (); | |
| 158 | |
| 159 // The fill path can handle rotation but not skew | |
| 160 // The stroke path needs the rect to remain axis aligned (no rotation or ske w) | |
| 161 // None of our AA draw rect calls can handle perspective yet | |
| 162 bool canApplyAA = width >= 0 ? viewMatrix.rectStaysRect() : viewMatrix.prese rvesRightAngles(); | |
| 163 bool useAA = needAA && canApplyAA; | |
| 164 | |
| 165 // Non-AA hairlines are snapped to pixel centers to make which pixels are hi t deterministic | |
| 166 bool snapToPixelCenters = !useAA && (0 == width && !fRenderTarget->isUnified Multisampled()); | |
| 167 | |
| 168 // TODO we also do this on the paint, do we need to? | |
|
bsalomon
2015/09/23 13:49:38
I'd just punt on CF. I'm also changing how CF work
joshualitt
2015/09/25 18:17:13
I need to handle the color here either way unfortu
| |
| 169 SkColor paintColor = paint.getColor(); | |
| 170 if (fPaint->getColorFilter() && !paint.getShader()) { | |
| 171 paintColor = paint.getColorFilter()->filterColor(paintColor); | |
| 172 } | |
| 173 GrColor color = SkColor2GrColor(paintColor); | |
| 174 | |
| 175 RectBatchType batchType = compute_rect_batch_type(useAA, width); | |
|
robertphillips
2015/09/25 12:48:49
can_fastpath -> attempt_fastpath ?
joshualitt
2015/09/25 18:17:13
Acknowledged.
| |
| 176 if (can_fastpath(drawTarget, *fPaint, clip, color, viewMatrix, rect, *fStrok eInfo, batchType, | |
| 177 snapToPixelCenters)) { | |
| 178 return; | |
| 179 } | |
| 180 | |
| 181 SkAutoTUnref<GrDrawBatch> batch; | |
| 182 switch (batchType) { | |
| 183 case kAAStroke_RectBatchType: | |
| 184 batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, re ct, *fStrokeInfo)); | |
| 185 break; | |
| 186 case kAAFill_RectBatchType: | |
| 187 batch.reset(GrRectBatchFactory::CreateAAFill(color, viewMatrix, rect )); | |
| 188 break; | |
| 189 case kNonAAFill_RectBatchType: | |
| 190 batch.reset(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, r ect, nullptr, | |
| 191 nullptr)); | |
| 192 break; | |
| 193 case kNonAAStroke_RectBatchType: | |
| 194 batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix, rect, width, | |
| 195 snapToPixelCenters )); | |
| 196 break; | |
| 197 } | |
| 198 | |
| 199 GrPaint grPaint; | |
| 200 if (!SkPaint2GrPaint(fContext, paint, viewMatrix, true, &grPaint)) { | |
| 201 return; | |
| 202 } | |
| 203 | |
| 204 GrPipelineBuilder pipelineBuilder(grPaint, fRenderTarget, clip); | |
| 205 | |
| 206 // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of | |
| 207 // hairline rects. We jam all the vertices to pixel centers to avoid this, b ut not when MSAA | |
| 208 // is enabled because it can cause ugly artifacts. | |
| 209 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag , | |
| 210 snapToPixelCenters); | |
| 211 drawTarget->drawBatch(pipelineBuilder, batch); | |
|
robertphillips
2015/09/25 12:48:49
So if we can't snap we just don't draw ?
joshualitt
2015/09/25 18:17:13
If we can't snap, we *do* draw(drawTarget->drawBat
| |
| 212 if (GrDrawRectSnap::CanSnap(paint)) { | |
| 213 GrDrawRectSnap* drawRectSnap = batch->getSnapStorage<GrDrawRectSnap>(); | |
| 214 new (drawRectSnap) GrDrawRectSnap(paint, clip, batchType, snapToPixelCen ters); | |
| 215 } | |
| 216 } | |
| OLD | NEW |