Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: src/gpu/draws/GrDrawRect.cpp

Issue 1355353002: Create GrDraw and start fast pathing src over rects (Closed) Base URL: https://skia.googlesource.com/skia.git@strokerect2
Patch Set: tweaks Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/draws/GrDrawRect.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 "GrDrawContext.h"
12 #include "GrClip.h"
13 #include "GrDrawTarget.h"
14 #include "GrRenderTarget.h"
15 #include "GrStrokeInfo.h"
16 #include "SkColorFilter.h"
17 #include "SkImageFilter.h"
18 #include "SkGr.h"
19 #include "SkMatrix.h"
20 #include "SkMaskFilter.h"
21 #include "SkPaint.h"
22 #include "SkRect.h"
23 #include "SkShader.h"
24 #include "SkXfermode.h"
25 #include "batches/GrRectBatchFactory.h"
26
27 enum RectBatchType {
28 kAAStroke_RectBatchType,
29 kAAFill_RectBatchType,
30 kNonAAFill_RectBatchType,
31 kNonAAStroke_RectBatchType,
32 };
33
34 /*
35 * GrDrawRectSnap rules:
36 * 1) We don't handle mask filters, because they can be multiple draws, though w e could handle
37 * a subset
38 * 2) We don't handle image filters for the same reason
39 * 3) We don't handle color filters, because they aren't very common, and they d on't always multiply
40 * As a result we can end up doing optimizations which can't be trivially rec onstructed in the
41 * fast path
42 * 5) We only handle shaders which have the same pointer, though we can and shou ld do a little bit
43 * more analysis here
44 * TODO compute short shader keys for the cases we care about
45 * 6) We don't bother looking at the clip, aside from wide open or same clip gen eration
46 * 7) We only handle src over, we might be able to handle other blend modes, but we have to be
47 * careful about not breaking things, especially re: optimizations
48 *
49 * TODO don't try to snap if we got an override color
50 */
51 class GrDrawRectSnap : public GrDrawSnap {
52 public:
53 GrDrawRectSnap(const SkPaint& paint,
54 const GrClip& clip,
55 RectBatchType type,
56 bool snapToPixelCenter)
57 : fShader(SkSafeRef(paint.getShader()))
58 , fType(type)
59 , fClipType(clip.clipType())
60 , fClipGenID(fClipType == GrClip::kClipStack_ClipType ?
61 clip.clipStack()->getTopmostGenID() :
62 -1)
63 , fSnapToPixelCenters(snapToPixelCenter)
64 , fIsDither(paint.isDither()) {
65 fClassID = GrDrawRect::ClassID();
66 }
67
68 bool canBatch(const SkPaint& paint,
69 const GrClip& clip,
70 RectBatchType type,
71 bool snapToPixelCenters) const {
72 return fType == type &&
73 !paint.getXfermode() &&
74 !paint.getImageFilter() &&
75 !paint.getMaskFilter() &&
76 !paint.getColorFilter() &&
77 paint.getShader() == fShader &&
78 paint.isDither() == fIsDither &&
79 fClipType == clip.clipType() &&
80 (fClipType == GrClip::kWideOpen_ClipType ||
81 (fClipType == GrClip::kClipStack_ClipType &&
82 fClipGenID == clip.clipStack()->getTopmostGenID())) &&
83 fSnapToPixelCenters == snapToPixelCenters;
84 }
85
86 // we only bother fast pathing kSrcOver_Mode, though we could do quite a bit more
87 static bool CanSnap(const SkPaint& paint) {
88 return !paint.getXfermode() &&
89 !paint.getColorFilter() &&
90 !paint.getMaskFilter() &&
91 !paint.getImageFilter();
92 }
93
94 private:
95 SkAutoTUnref<SkShader> fShader;
96 RectBatchType fType;
97 GrClip::ClipType fClipType;
98 int32_t fClipGenID;
99 bool fSnapToPixelCenters;
100 bool fIsDither;
101
102 typedef GrDrawSnap INHERITED;
103 };
104
105 inline static RectBatchType compute_rect_batch_type(bool useAA, SkScalar width) {
106 if (useAA) {
107 if (width >= 0) {
108 return kAAStroke_RectBatchType;
109 } else {
110 return kAAFill_RectBatchType;
111 }
112 } else if (width >= 0) {
113 return kNonAAStroke_RectBatchType;
114 } else {
115 return kNonAAFill_RectBatchType;
116 }
117 }
118
119 inline static bool attempt_fastpath(GrDrawContext* drawContext,
120 const SkPaint& paint,
121 const GrClip& clip,
122 GrColor color,
123 const SkMatrix& viewMatrix,
124 const SkRect& rect,
125 const GrStrokeInfo& strokeInfo,
126 RectBatchType batchType,
127 bool snapToPixelCenters,
128 const GrRenderTarget* rt) {
129 GrBatch* lastBatch = drawContext->lastBatch();
130 if (!lastBatch) {
131 return false;
132 }
133
134 const GrDrawSnap* lastSnap = lastBatch->getDrawSnap();
135 if (!lastSnap) {
136 return false;
137 }
138
139 if (lastSnap->classID() != GrDrawRect::ClassID()) {
140 return false;
141 }
142
143 // TODO remove this and the RT arg when we have multidrawbuffer
144 // This downcast is safe because we only have drawbatches
145 const GrDrawBatch* drawBatch = reinterpret_cast<const GrDrawBatch*>(lastBatc h);
146 if (rt != drawBatch->pipeline()->getRenderTarget()) {
147 return false;
148 }
149
150 const GrDrawRectSnap* lastSnapCast = static_cast<const GrDrawRectSnap*>(last Snap);
151 if (lastSnapCast->canBatch(paint, clip, batchType, snapToPixelCenters)) {
152 switch (batchType) {
153 case kAAStroke_RectBatchType:
154 if (GrAAStrokeRectBatch::Append(lastBatch, color, viewMatrix, re ct,
155 strokeInfo)) {
156 return true;
157 }
158 break;
159 case kAAFill_RectBatchType:
160 if (GrAAFillRectBatch::Append(lastBatch, color, viewMatrix, rect )) {
161 return true;
162 }
163 break;
164 case kNonAAFill_RectBatchType:
165 if (GrNonAAFillRectBatch::Append(lastBatch, color, viewMatrix, r ect,
166 nullptr, nullptr)) {
167 return true;
168 }
169 break;
170 case kNonAAStroke_RectBatchType:
171 // GrNonAAStrokeRectBatch doesn't batch yet
172 break;
173 }
174 }
175
176 return false;
177 }
178
179 void GrDrawRect::execute(GrDrawContext* drawContext) const {
180 const SkPaint& paint = *fPaint;
181 const GrClip& clip = *fClip;
182 const SkMatrix& viewMatrix = *fViewMatrix;
183 const SkRect& rect = *fRect;
184
185 SkScalar width = nullptr == fStrokeInfo ? -1 : fStrokeInfo->getWidth();
186
187 bool needAA = fPaint->isAntiAlias() && !fRenderTarget->isUnifiedMultisampled ();
188
189 // The fill path can handle rotation but not skew
190 // The stroke path needs the rect to remain axis aligned (no rotation or ske w)
191 // None of our AA draw rect calls can handle perspective yet
192 bool canApplyAA = width >= 0 ? viewMatrix.rectStaysRect() : viewMatrix.prese rvesRightAngles();
193 bool useAA = needAA && canApplyAA;
194
195 // Non-AA hairlines are snapped to pixel centers to make which pixels are hi t deterministic
196 bool snapToPixelCenters = !useAA && (0 == width && !fRenderTarget->isUnified Multisampled());
197
198 // TODO we also do this on the paint, do we need to?
199 SkColor paintColor = paint.getColor();
200 if (fPaint->getColorFilter() && !paint.getShader()) {
201 paintColor = paint.getColorFilter()->filterColor(paintColor);
202 }
203 GrColor color = SkColor2GrColor(paintColor);
204
205 RectBatchType batchType = compute_rect_batch_type(useAA, width);
206 if (attempt_fastpath(drawContext, *fPaint, clip, color, viewMatrix, rect, *f StrokeInfo,
207 batchType, snapToPixelCenters, fRenderTarget)) {
208 return;
209 }
210
211 SkAutoTUnref<GrDrawBatch> batch;
212 switch (batchType) {
213 case kAAStroke_RectBatchType:
214 batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, re ct, *fStrokeInfo));
215 break;
216 case kAAFill_RectBatchType:
217 batch.reset(GrRectBatchFactory::CreateAAFill(color, viewMatrix, rect ));
218 break;
219 case kNonAAFill_RectBatchType:
220 batch.reset(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, r ect, nullptr,
221 nullptr));
222 break;
223 case kNonAAStroke_RectBatchType:
224 batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix, rect, width,
225 snapToPixelCenters ));
226 break;
227 }
228
229 GrPaint grPaint;
230 if (!SkPaint2GrPaint(fContext, paint, viewMatrix, true, &grPaint)) {
231 return;
232 }
233
234 GrPipelineBuilder pipelineBuilder(grPaint, fRenderTarget, clip);
235
236 // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of
237 // hairline rects. We jam all the vertices to pixel centers to avoid this, b ut not when MSAA
238 // is enabled because it can cause ugly artifacts.
239 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag ,
240 snapToPixelCenters);
241 drawContext->drawBatch(pipelineBuilder, batch);
242 if (GrDrawRectSnap::CanSnap(paint)) {
243 batch->initSnapStorage<GrDrawRectSnap>(paint, clip, batchType, snapToPix elCenters);
244 }
245 }
OLDNEW
« no previous file with comments | « src/gpu/draws/GrDrawRect.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698