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

Side by Side Diff: src/gpu/GrClipMaskManager.cpp

Issue 1393553002: Insert clip fragment processor outside GrCMM (Closed) Base URL: https://skia.googlesource.com/skia.git@byebye
Patch Set: add class to friends 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/GrClipMaskManager.h ('k') | src/gpu/GrDrawTarget.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 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 "GrClipMaskManager.h" 8 #include "GrClipMaskManager.h"
9 #include "GrCaps.h" 9 #include "GrCaps.h"
10 #include "GrDrawContext.h" 10 #include "GrDrawContext.h"
11 #include "GrDrawTarget.h" 11 #include "GrDrawTarget.h"
12 #include "GrGpuResourcePriv.h" 12 #include "GrGpuResourcePriv.h"
13 #include "GrPaint.h" 13 #include "GrPaint.h"
14 #include "GrPathRenderer.h" 14 #include "GrPathRenderer.h"
15 #include "GrRenderTarget.h" 15 #include "GrRenderTarget.h"
16 #include "GrRenderTargetPriv.h" 16 #include "GrRenderTargetPriv.h"
17 #include "GrResourceProvider.h" 17 #include "GrResourceProvider.h"
18 #include "GrStencilAttachment.h" 18 #include "GrStencilAttachment.h"
19 #include "GrSWMaskHelper.h" 19 #include "GrSWMaskHelper.h"
20 #include "SkRasterClip.h" 20 #include "SkRasterClip.h"
21 #include "SkTLazy.h" 21 #include "SkTLazy.h"
22 #include "effects/GrConvexPolyEffect.h" 22 #include "effects/GrConvexPolyEffect.h"
23 #include "effects/GrPorterDuffXferProcessor.h" 23 #include "effects/GrPorterDuffXferProcessor.h"
24 #include "effects/GrRRectEffect.h" 24 #include "effects/GrRRectEffect.h"
25 #include "effects/GrTextureDomain.h" 25 #include "effects/GrTextureDomain.h"
26 26
27 typedef SkClipStack::Element Element; 27 typedef SkClipStack::Element Element;
28 28
29 //////////////////////////////////////////////////////////////////////////////// 29 ////////////////////////////////////////////////////////////////////////////////
30 namespace {
31 // set up the draw state to enable the aa clipping mask. Besides setting up the 30 // set up the draw state to enable the aa clipping mask. Besides setting up the
32 // stage matrix this also alters the vertex layout 31 // stage matrix this also alters the vertex layout
33 void setup_drawstate_aaclip(const GrPipelineBuilder& pipelineBuilder, 32 static const GrFragmentProcessor* create_fp_for_mask(GrTexture* result, const Sk IRect &devBound) {
34 GrTexture* result,
35 GrPipelineBuilder::AutoRestoreFragmentProcessorState * arfps,
36 const SkIRect &devBound) {
37 SkASSERT(arfps);
38 arfps->set(&pipelineBuilder);
39
40 SkMatrix mat; 33 SkMatrix mat;
41 // We use device coords to compute the texture coordinates. We set our matri x to be a 34 // We use device coords to compute the texture coordinates. We set our matri x to be a
42 // translation to the devBound, and then a scaling matrix to normalized coor ds. 35 // translation to the devBound, and then a scaling matrix to normalized coor ds.
43 mat.setIDiv(result->width(), result->height()); 36 mat.setIDiv(result->width(), result->height());
44 mat.preTranslate(SkIntToScalar(-devBound.fLeft), 37 mat.preTranslate(SkIntToScalar(-devBound.fLeft),
45 SkIntToScalar(-devBound.fTop)); 38 SkIntToScalar(-devBound.fTop));
46 39
47 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); 40 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height());
48 // This could be a long-lived effect that is cached with the alpha-mask. 41 return GrTextureDomainEffect::Create(result,
49 arfps->addCoverageFragmentProcessor( 42 mat,
50 GrTextureDomainEffect::Create(result, 43 GrTextureDomain::MakeTexelDomain(result , domainTexels),
51 mat, 44 GrTextureDomain::kDecal_Mode,
52 GrTextureDomain::MakeTexelDomain(result, d omainTexels), 45 GrTextureParams::kNone_FilterMode,
53 GrTextureDomain::kDecal_Mode, 46 kDevice_GrCoordSet);
54 GrTextureParams::kNone_FilterMode,
55 kDevice_GrCoordSet))->unref();
56 } 47 }
57 48
58 bool path_needs_SW_renderer(GrContext* context, 49 static bool path_needs_SW_renderer(GrContext* context,
59 const GrDrawTarget* gpu, 50 const GrDrawTarget* gpu,
60 const GrPipelineBuilder& pipelineBuilder, 51 const GrPipelineBuilder& pipelineBuilder,
61 const SkMatrix& viewMatrix, 52 const SkMatrix& viewMatrix,
62 const SkPath& origPath, 53 const SkPath& origPath,
63 const GrStrokeInfo& stroke, 54 const GrStrokeInfo& stroke,
64 bool doAA) { 55 bool doAA) {
65 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b uffer 56 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b uffer
66 SkTCopyOnFirstWrite<SkPath> path(origPath); 57 SkTCopyOnFirstWrite<SkPath> path(origPath);
67 if (path->isInverseFillType()) { 58 if (path->isInverseFillType()) {
68 path.writable()->toggleInverseFillType(); 59 path.writable()->toggleInverseFillType();
69 } 60 }
70 // last (false) parameter disallows use of the SW path renderer 61 // last (false) parameter disallows use of the SW path renderer
71 GrPathRendererChain::DrawType type = doAA ? 62 GrPathRendererChain::DrawType type = doAA ?
72 GrPathRendererChain::kColorAntiAlias_Dr awType : 63 GrPathRendererChain::kColorAntiAlias_Dr awType :
73 GrPathRendererChain::kColor_DrawType; 64 GrPathRendererChain::kColor_DrawType;
74 65
75 return nullptr == context->getPathRenderer(gpu, &pipelineBuilder, viewMatrix , *path, stroke, 66 return nullptr == context->getPathRenderer(gpu, &pipelineBuilder, viewMatrix , *path, stroke,
76 false, type); 67 false, type);
77 } 68 }
78 }
79 69
80 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget) 70 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget)
81 : fCurrClipMaskType(kNone_ClipMaskType) 71 : fCurrClipMaskType(kNone_ClipMaskType)
82 , fDrawTarget(drawTarget) 72 , fDrawTarget(drawTarget)
83 , fClipMode(kIgnoreClip_StencilClipMode) { 73 , fClipMode(kIgnoreClip_StencilClipMode) {
84 } 74 }
85 75
86 GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().con text(); } 76 GrContext* GrClipMaskManager::getContext() { return fDrawTarget->cmmAccess().con text(); }
87 77
88 /* 78 /*
(...skipping 23 matching lines...) Expand all
112 element->asPath(&path); 102 element->asPath(&path);
113 if (path_needs_SW_renderer(this->getContext(), fDrawTarget, pipeline Builder, translate, 103 if (path_needs_SW_renderer(this->getContext(), fDrawTarget, pipeline Builder, translate,
114 path, stroke, element->isAA())) { 104 path, stroke, element->isAA())) {
115 return true; 105 return true;
116 } 106 }
117 } 107 }
118 } 108 }
119 return false; 109 return false;
120 } 110 }
121 111
122 bool GrClipMaskManager::installClipEffects( 112 const GrFragmentProcessor* GrClipMaskManager::getAnalyticClipProcessor(
123 const GrPipelineBuilder& pipelineBuilder, 113 const GrReducedClip::Ele mentList& elements,
124 GrPipelineBuilder::AutoRestoreFragmentProcessorState* arfps, 114 const SkVector& clipToRT Offset,
125 const GrReducedClip::ElementList& elements, 115 const SkRect* drawBounds ) {
126 const SkVector& clipToRTOffset,
127 const SkRect* drawBounds) {
128 SkRect boundsInClipSpace; 116 SkRect boundsInClipSpace;
129 if (drawBounds) { 117 if (drawBounds) {
130 boundsInClipSpace = *drawBounds; 118 boundsInClipSpace = *drawBounds;
131 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); 119 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY);
132 } 120 }
133 121 SkASSERT(elements.count() <= kMaxAnalyticElements);
134 arfps->set(&pipelineBuilder); 122 const GrFragmentProcessor* fps[kMaxAnalyticElements];
135 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); 123 for (int i = 0; i < kMaxAnalyticElements; ++i) {
124 fps[i] = nullptr;
125 }
126 int fpCnt = 0;
136 GrReducedClip::ElementList::Iter iter(elements); 127 GrReducedClip::ElementList::Iter iter(elements);
137 bool failed = false; 128 bool failed = false;
138 while (iter.get()) { 129 while (iter.get()) {
139 SkRegion::Op op = iter.get()->getOp(); 130 SkRegion::Op op = iter.get()->getOp();
140 bool invert; 131 bool invert;
141 bool skip = false; 132 bool skip = false;
142 switch (op) { 133 switch (op) {
143 case SkRegion::kReplace_Op: 134 case SkRegion::kReplace_Op:
144 SkASSERT(iter.get() == elements.head()); 135 SkASSERT(iter.get() == elements.head());
145 // Fallthrough, handled same as intersect. 136 // Fallthrough, handled same as intersect.
(...skipping 12 matching lines...) Expand all
158 failed = true; 149 failed = true;
159 break; 150 break;
160 } 151 }
161 if (failed) { 152 if (failed) {
162 break; 153 break;
163 } 154 }
164 155
165 if (!skip) { 156 if (!skip) {
166 GrPrimitiveEdgeType edgeType; 157 GrPrimitiveEdgeType edgeType;
167 if (iter.get()->isAA()) { 158 if (iter.get()->isAA()) {
168 if (rt->isUnifiedMultisampled()) {
169 // Coverage based AA clips don't place nicely with MSAA.
170 failed = true;
171 break;
172 }
173 edgeType = 159 edgeType =
174 invert ? kInverseFillAA_GrProcessorEdgeType : kFillAA_Gr ProcessorEdgeType; 160 invert ? kInverseFillAA_GrProcessorEdgeType : kFillAA_GrProc essorEdgeType;
175 } else { 161 } else {
176 edgeType = invert ? kInverseFillBW_GrProcessorEdgeType : 162 edgeType =
177 kFillBW_GrProcessorEdgeType; 163 invert ? kInverseFillBW_GrProcessorEdgeType : kFillBW_GrProc essorEdgeType;
178 } 164 }
179 SkAutoTUnref<GrFragmentProcessor> fp;
180 switch (iter.get()->getType()) { 165 switch (iter.get()->getType()) {
181 case SkClipStack::Element::kPath_Type: 166 case SkClipStack::Element::kPath_Type:
182 fp.reset(GrConvexPolyEffect::Create(edgeType, iter.get()->ge tPath(), 167 fps[fpCnt] = GrConvexPolyEffect::Create(edgeType, iter.get() ->getPath(),
183 &clipToRTOffset)); 168 &clipToRTOffset);
184 break; 169 break;
185 case SkClipStack::Element::kRRect_Type: { 170 case SkClipStack::Element::kRRect_Type: {
186 SkRRect rrect = iter.get()->getRRect(); 171 SkRRect rrect = iter.get()->getRRect();
187 rrect.offset(clipToRTOffset.fX, clipToRTOffset.fY); 172 rrect.offset(clipToRTOffset.fX, clipToRTOffset.fY);
188 fp.reset(GrRRectEffect::Create(edgeType, rrect)); 173 fps[fpCnt] = GrRRectEffect::Create(edgeType, rrect);
189 break; 174 break;
190 } 175 }
191 case SkClipStack::Element::kRect_Type: { 176 case SkClipStack::Element::kRect_Type: {
192 SkRect rect = iter.get()->getRect(); 177 SkRect rect = iter.get()->getRect();
193 rect.offset(clipToRTOffset.fX, clipToRTOffset.fY); 178 rect.offset(clipToRTOffset.fX, clipToRTOffset.fY);
194 fp.reset(GrConvexPolyEffect::Create(edgeType, rect)); 179 fps[fpCnt] = GrConvexPolyEffect::Create(edgeType, rect);
195 break; 180 break;
196 } 181 }
197 default: 182 default:
198 break; 183 break;
199 } 184 }
200 if (fp) { 185 if (!fps[fpCnt]) {
201 arfps->addCoverageFragmentProcessor(fp);
202 } else {
203 failed = true; 186 failed = true;
204 break; 187 break;
205 } 188 }
189 fpCnt++;
206 } 190 }
207 iter.next(); 191 iter.next();
208 } 192 }
209 193
210 if (failed) { 194 const GrFragmentProcessor* resultFP = nullptr;
211 arfps->set(nullptr); 195 if (!failed) {
196 resultFP = GrFragmentProcessor::RunInSeries(fps, fpCnt);
212 } 197 }
213 return !failed; 198 for (int i = 0; i < fpCnt; ++i) {
199 fps[i]->unref();
200 }
201 return resultFP;
214 } 202 }
215 203
216 //////////////////////////////////////////////////////////////////////////////// 204 ////////////////////////////////////////////////////////////////////////////////
217 // sort out what kind of clip mask needs to be created: alpha, stencil, 205 // sort out what kind of clip mask needs to be created: alpha, stencil,
218 // scissor, or entirely software 206 // scissor, or entirely software
219 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, 207 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
220 GrPipelineBuilder::AutoRestoreFragmentProc essorState* arfps,
221 GrPipelineBuilder::AutoRestoreStencil* ars , 208 GrPipelineBuilder::AutoRestoreStencil* ars ,
222 GrScissorState* scissorState, 209 GrScissorState* scissorState,
223 const SkRect* devBounds) { 210 const SkRect* devBounds,
211 GrAppliedClip* out) {
224 fCurrClipMaskType = kNone_ClipMaskType; 212 fCurrClipMaskType = kNone_ClipMaskType;
225 if (kRespectClip_StencilClipMode == fClipMode) { 213 if (kRespectClip_StencilClipMode == fClipMode) {
226 fClipMode = kIgnoreClip_StencilClipMode; 214 fClipMode = kIgnoreClip_StencilClipMode;
227 } 215 }
228 216
229 GrReducedClip::ElementList elements(16); 217 GrReducedClip::ElementList elements(16);
230 int32_t genID = 0; 218 int32_t genID = 0;
231 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat e; 219 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat e;
232 SkIRect clipSpaceIBounds; 220 SkIRect clipSpaceIBounds;
233 bool requiresAA = false; 221 bool requiresAA = false;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 } 269 }
282 270
283 // An element count of 4 was chosen because of the common pattern in Blink o f: 271 // An element count of 4 was chosen because of the common pattern in Blink o f:
284 // isect RR 272 // isect RR
285 // diff RR 273 // diff RR
286 // isect convex_poly 274 // isect convex_poly
287 // isect convex_poly 275 // isect convex_poly
288 // when drawing rounded div borders. This could probably be tuned based on a 276 // when drawing rounded div borders. This could probably be tuned based on a
289 // configuration's relative costs of switching RTs to generate a mask vs 277 // configuration's relative costs of switching RTs to generate a mask vs
290 // longer shaders. 278 // longer shaders.
291 if (elements.count() <= 4) { 279 if (elements.count() <= kMaxAnalyticElements) {
292 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX), 280 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX),
293 SkIntToScalar(-clip.origin().fY) }; 281 SkIntToScalar(-clip.origin().fY) };
282 // When there are multiple color samples we want to do per-sample clippi ng, not compute
283 // a fractional pixel coverage.
284 bool disallowAnalyticAA = pipelineBuilder.getRenderTarget()->isUnifiedMu ltisampled();
285 const GrFragmentProcessor* clipFP = nullptr;
294 if (elements.isEmpty() || 286 if (elements.isEmpty() ||
295 (requiresAA && this->installClipEffects(pipelineBuilder, arfps, elem ents, clipToRTOffset, 287 (requiresAA && !disallowAnalyticAA &&
296 devBounds))) { 288 SkToBool(clipFP = this->getAnalyticClipProcessor(elements, clipToRT Offset, devBounds)))) {
297 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 289 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
298 scissorSpaceIBounds.offset(-clip.origin()); 290 scissorSpaceIBounds.offset(-clip.origin());
299 if (nullptr == devBounds || 291 if (nullptr == devBounds ||
300 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { 292 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
301 scissorState->set(scissorSpaceIBounds); 293 scissorState->set(scissorSpaceIBounds);
302 } 294 }
303 this->setPipelineBuilderStencil(pipelineBuilder, ars); 295 this->setPipelineBuilderStencil(pipelineBuilder, ars);
296 out->fClipCoverageFP.reset(clipFP);
304 return true; 297 return true;
305 } 298 }
306 } 299 }
307 300
308 // If MSAA is enabled we can do everything in the stencil buffer. 301 // If MSAA is enabled we can do everything in the stencil buffer.
309 if (0 == rt->numStencilSamples() && requiresAA) { 302 if (0 == rt->numStencilSamples() && requiresAA) {
310 SkAutoTUnref<GrTexture> result; 303 SkAutoTUnref<GrTexture> result;
311 304
312 // The top-left of the mask corresponds to the top-left corner of the bo unds. 305 // The top-left of the mask corresponds to the top-left corner of the bo unds.
313 SkVector clipToMaskOffset = { 306 SkVector clipToMaskOffset = {
(...skipping 11 matching lines...) Expand all
325 clipSpaceIBounds)); 318 clipSpaceIBounds));
326 } else { 319 } else {
327 result.reset(this->createAlphaClipMask(genID, 320 result.reset(this->createAlphaClipMask(genID,
328 initialState, 321 initialState,
329 elements, 322 elements,
330 clipToMaskOffset, 323 clipToMaskOffset,
331 clipSpaceIBounds)); 324 clipSpaceIBounds));
332 } 325 }
333 326
334 if (result) { 327 if (result) {
335 arfps->set(&pipelineBuilder);
336 // The mask's top left coord should be pinned to the rounded-out top left corner of 328 // The mask's top left coord should be pinned to the rounded-out top left corner of
337 // clipSpace bounds. We determine the mask's position WRT to the ren der target here. 329 // clipSpace bounds. We determine the mask's position WRT to the ren der target here.
338 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; 330 SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
339 rtSpaceMaskBounds.offset(-clip.origin()); 331 rtSpaceMaskBounds.offset(-clip.origin());
340 setup_drawstate_aaclip(pipelineBuilder, result, arfps, rtSpaceMaskBo unds); 332 out->fClipCoverageFP.reset(create_fp_for_mask(result, rtSpaceMaskBou nds));
341 this->setPipelineBuilderStencil(pipelineBuilder, ars); 333 this->setPipelineBuilderStencil(pipelineBuilder, ars);
342 return true; 334 return true;
343 } 335 }
344 // if alpha clip mask creation fails fall through to the non-AA code pat hs 336 // if alpha clip mask creation fails fall through to the non-AA code pat hs
345 } 337 }
346 338
347 // use the stencil clip if we can't represent the clip as a rectangle. 339 // use the stencil clip if we can't represent the clip as a rectangle.
348 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin(); 340 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin();
349 this->createStencilClipMask(rt, 341 this->createStencilClipMask(rt,
350 genID, 342 genID,
(...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 1124
1133 //////////////////////////////////////////////////////////////////////////////// 1125 ////////////////////////////////////////////////////////////////////////////////
1134 1126
1135 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc ilAttachment, 1127 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc ilAttachment,
1136 GrStencilSettings* settings) { 1128 GrStencilSettings* settings) {
1137 if (stencilAttachment) { 1129 if (stencilAttachment) {
1138 int stencilBits = stencilAttachment->bits(); 1130 int stencilBits = stencilAttachment->bits();
1139 this->adjustStencilParams(settings, fClipMode, stencilBits); 1131 this->adjustStencilParams(settings, fClipMode, stencilBits);
1140 } 1132 }
1141 } 1133 }
OLDNEW
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrDrawTarget.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698