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

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

Issue 858343002: Rename GrOptDrawState to GrPipeline and GrDrawState to GrPipelineBuilder (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: more nits Created 5 years, 11 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/GrContext.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 "GrAAConvexPathRenderer.h" 9 #include "GrAAConvexPathRenderer.h"
10 #include "GrAAHairLinePathRenderer.h" 10 #include "GrAAHairLinePathRenderer.h"
(...skipping 13 matching lines...) Expand all
24 #include "effects/GrTextureDomain.h" 24 #include "effects/GrTextureDomain.h"
25 25
26 #define GR_AA_CLIP 1 26 #define GR_AA_CLIP 1
27 typedef SkClipStack::Element Element; 27 typedef SkClipStack::Element Element;
28 28
29 //////////////////////////////////////////////////////////////////////////////// 29 ////////////////////////////////////////////////////////////////////////////////
30 namespace { 30 namespace {
31 // set up the draw state to enable the aa clipping mask. Besides setting up the 31 // set up the draw state to enable the aa clipping mask. Besides setting up the
32 // stage matrix this also alters the vertex layout 32 // stage matrix this also alters the vertex layout
33 void setup_drawstate_aaclip(const SkIRect &devBound, 33 void setup_drawstate_aaclip(const SkIRect &devBound,
34 GrDrawState* drawState, 34 GrPipelineBuilder* pipelineBuilder,
35 GrTexture* result) { 35 GrTexture* result) {
36 SkASSERT(drawState); 36 SkASSERT(pipelineBuilder);
37 37
38 SkMatrix mat; 38 SkMatrix mat;
39 // We use device coords to compute the texture coordinates. We set our matri x to be a 39 // We use device coords to compute the texture coordinates. We set our matri x to be a
40 // translation to the devBound, and then a scaling matrix to normalized coor ds. 40 // translation to the devBound, and then a scaling matrix to normalized coor ds.
41 mat.setIDiv(result->width(), result->height()); 41 mat.setIDiv(result->width(), result->height());
42 mat.preTranslate(SkIntToScalar(-devBound.fLeft), 42 mat.preTranslate(SkIntToScalar(-devBound.fLeft),
43 SkIntToScalar(-devBound.fTop)); 43 SkIntToScalar(-devBound.fTop));
44 44
45 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); 45 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height());
46 // This could be a long-lived effect that is cached with the alpha-mask. 46 // This could be a long-lived effect that is cached with the alpha-mask.
47 drawState->addCoverageProcessor( 47 pipelineBuilder->addCoverageProcessor(
48 GrTextureDomainEffect::Create(result, 48 GrTextureDomainEffect::Create(result,
49 mat, 49 mat,
50 GrTextureDomain::MakeTexelDomain(result, d omainTexels), 50 GrTextureDomain::MakeTexelDomain(result, d omainTexels),
51 GrTextureDomain::kDecal_Mode, 51 GrTextureDomain::kDecal_Mode,
52 GrTextureParams::kNone_FilterMode, 52 GrTextureParams::kNone_FilterMode,
53 kDevice_GrCoordSet))->unref(); 53 kDevice_GrCoordSet))->unref();
54 } 54 }
55 55
56 bool path_needs_SW_renderer(GrContext* context, 56 bool path_needs_SW_renderer(GrContext* context,
57 const GrDrawTarget* gpu, 57 const GrDrawTarget* gpu,
58 const GrDrawState* drawState, 58 const GrPipelineBuilder* pipelineBuilder,
59 const SkMatrix& viewMatrix, 59 const SkMatrix& viewMatrix,
60 const SkPath& origPath, 60 const SkPath& origPath,
61 const SkStrokeRec& stroke, 61 const SkStrokeRec& stroke,
62 bool doAA) { 62 bool doAA) {
63 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b uffer 63 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b uffer
64 SkTCopyOnFirstWrite<SkPath> path(origPath); 64 SkTCopyOnFirstWrite<SkPath> path(origPath);
65 if (path->isInverseFillType()) { 65 if (path->isInverseFillType()) {
66 path.writable()->toggleInverseFillType(); 66 path.writable()->toggleInverseFillType();
67 } 67 }
68 // last (false) parameter disallows use of the SW path renderer 68 // last (false) parameter disallows use of the SW path renderer
69 GrPathRendererChain::DrawType type = doAA ? 69 GrPathRendererChain::DrawType type = doAA ?
70 GrPathRendererChain::kColorAntiAlias_Dr awType : 70 GrPathRendererChain::kColorAntiAlias_Dr awType :
71 GrPathRendererChain::kColor_DrawType; 71 GrPathRendererChain::kColor_DrawType;
72 72
73 return NULL == context->getPathRenderer(gpu, drawState, viewMatrix, *path, s troke, false, type); 73 return NULL == context->getPathRenderer(gpu, pipelineBuilder, viewMatrix, *p ath, stroke,
74 false, type);
74 } 75 }
75 } 76 }
76 77
77 /* 78 /*
78 * This method traverses the clip stack to see if the GrSoftwarePathRenderer 79 * This method traverses the clip stack to see if the GrSoftwarePathRenderer
79 * will be used on any element. If so, it returns true to indicate that the 80 * will be used on any element. If so, it returns true to indicate that the
80 * entire clip should be rendered in SW and then uploaded en masse to the gpu. 81 * entire clip should be rendered in SW and then uploaded en masse to the gpu.
81 */ 82 */
82 bool GrClipMaskManager::useSWOnlyPath(const GrDrawState* drawState, 83 bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder* pipelineBuilder,
83 const SkVector& clipToMaskOffset, 84 const SkVector& clipToMaskOffset,
84 const GrReducedClip::ElementList& elements ) { 85 const GrReducedClip::ElementList& elements ) {
85 // TODO: generalize this function so that when 86 // TODO: generalize this function so that when
86 // a clip gets complex enough it can just be done in SW regardless 87 // a clip gets complex enough it can just be done in SW regardless
87 // of whether it would invoke the GrSoftwarePathRenderer. 88 // of whether it would invoke the GrSoftwarePathRenderer.
88 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 89 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
89 90
90 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip 91 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
91 // space. 92 // space.
92 SkMatrix translate; 93 SkMatrix translate;
93 translate.setTranslate(clipToMaskOffset); 94 translate.setTranslate(clipToMaskOffset);
94 95
95 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { 96 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
96 const Element* element = iter.get(); 97 const Element* element = iter.get();
97 // rects can always be drawn directly w/o using the software path 98 // rects can always be drawn directly w/o using the software path
98 // Skip rrects once we're drawing them directly. 99 // Skip rrects once we're drawing them directly.
99 if (Element::kRect_Type != element->getType()) { 100 if (Element::kRect_Type != element->getType()) {
100 SkPath path; 101 SkPath path;
101 element->asPath(&path); 102 element->asPath(&path);
102 if (path_needs_SW_renderer(this->getContext(), fClipTarget, drawStat e, translate, 103 if (path_needs_SW_renderer(this->getContext(), fClipTarget, pipeline Builder, translate,
103 path, stroke, element->isAA())) { 104 path, stroke, element->isAA())) {
104 return true; 105 return true;
105 } 106 }
106 } 107 }
107 } 108 }
108 return false; 109 return false;
109 } 110 }
110 111
111 bool GrClipMaskManager::installClipEffects(GrDrawState* drawState, 112 bool GrClipMaskManager::installClipEffects(GrPipelineBuilder* pipelineBuilder,
112 GrDrawState::AutoRestoreEffects* are, 113 GrPipelineBuilder::AutoRestoreEffects * are,
113 const GrReducedClip::ElementList& ele ments, 114 const GrReducedClip::ElementList& ele ments,
114 const SkVector& clipToRTOffset, 115 const SkVector& clipToRTOffset,
115 const SkRect* drawBounds) { 116 const SkRect* drawBounds) {
116 SkRect boundsInClipSpace; 117 SkRect boundsInClipSpace;
117 if (drawBounds) { 118 if (drawBounds) {
118 boundsInClipSpace = *drawBounds; 119 boundsInClipSpace = *drawBounds;
119 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); 120 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY);
120 } 121 }
121 122
122 are->set(drawState); 123 are->set(pipelineBuilder);
123 GrRenderTarget* rt = drawState->getRenderTarget(); 124 GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
124 GrReducedClip::ElementList::Iter iter(elements); 125 GrReducedClip::ElementList::Iter iter(elements);
125 bool failed = false; 126 bool failed = false;
126 while (iter.get()) { 127 while (iter.get()) {
127 SkRegion::Op op = iter.get()->getOp(); 128 SkRegion::Op op = iter.get()->getOp();
128 bool invert; 129 bool invert;
129 bool skip = false; 130 bool skip = false;
130 switch (op) { 131 switch (op) {
131 case SkRegion::kReplace_Op: 132 case SkRegion::kReplace_Op:
132 SkASSERT(iter.get() == elements.head()); 133 SkASSERT(iter.get() == elements.head());
133 // Fallthrough, handled same as intersect. 134 // Fallthrough, handled same as intersect.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 case SkClipStack::Element::kRect_Type: { 180 case SkClipStack::Element::kRect_Type: {
180 SkRect rect = iter.get()->getRect(); 181 SkRect rect = iter.get()->getRect();
181 rect.offset(clipToRTOffset.fX, clipToRTOffset.fY); 182 rect.offset(clipToRTOffset.fX, clipToRTOffset.fY);
182 fp.reset(GrConvexPolyEffect::Create(edgeType, rect)); 183 fp.reset(GrConvexPolyEffect::Create(edgeType, rect));
183 break; 184 break;
184 } 185 }
185 default: 186 default:
186 break; 187 break;
187 } 188 }
188 if (fp) { 189 if (fp) {
189 drawState->addCoverageProcessor(fp); 190 pipelineBuilder->addCoverageProcessor(fp);
190 } else { 191 } else {
191 failed = true; 192 failed = true;
192 break; 193 break;
193 } 194 }
194 } 195 }
195 iter.next(); 196 iter.next();
196 } 197 }
197 198
198 if (failed) { 199 if (failed) {
199 are->set(NULL); 200 are->set(NULL);
200 } 201 }
201 return !failed; 202 return !failed;
202 } 203 }
203 204
204 //////////////////////////////////////////////////////////////////////////////// 205 ////////////////////////////////////////////////////////////////////////////////
205 // sort out what kind of clip mask needs to be created: alpha, stencil, 206 // sort out what kind of clip mask needs to be created: alpha, stencil,
206 // scissor, or entirely software 207 // scissor, or entirely software
207 bool GrClipMaskManager::setupClipping(GrDrawState* drawState, 208 bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder,
208 GrDrawState::AutoRestoreEffects* are, 209 GrPipelineBuilder::AutoRestoreEffects* are ,
209 GrDrawState::AutoRestoreStencil* ars, 210 GrPipelineBuilder::AutoRestoreStencil* ars ,
210 GrScissorState* scissorState, 211 GrScissorState* scissorState,
211 const GrClipData* clipDataIn, 212 const GrClipData* clipDataIn,
212 const SkRect* devBounds) { 213 const SkRect* devBounds) {
213 fCurrClipMaskType = kNone_ClipMaskType; 214 fCurrClipMaskType = kNone_ClipMaskType;
214 if (kRespectClip_StencilClipMode == fClipMode) { 215 if (kRespectClip_StencilClipMode == fClipMode) {
215 fClipMode = kIgnoreClip_StencilClipMode; 216 fClipMode = kIgnoreClip_StencilClipMode;
216 } 217 }
217 218
218 GrReducedClip::ElementList elements(16); 219 GrReducedClip::ElementList elements(16);
219 int32_t genID; 220 int32_t genID;
220 GrReducedClip::InitialState initialState; 221 GrReducedClip::InitialState initialState;
221 SkIRect clipSpaceIBounds; 222 SkIRect clipSpaceIBounds;
222 bool requiresAA; 223 bool requiresAA;
223 GrRenderTarget* rt = drawState->getRenderTarget(); 224 GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
224 225
225 // GrDrawTarget should have filtered this for us 226 // GrDrawTarget should have filtered this for us
226 SkASSERT(rt); 227 SkASSERT(rt);
227 228
228 bool ignoreClip = !drawState->isClipState() || clipDataIn->fClipStack->isWid eOpen(); 229 bool ignoreClip = !pipelineBuilder->isClipState() || clipDataIn->fClipStack- >isWideOpen();
229 if (!ignoreClip) { 230 if (!ignoreClip) {
230 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); 231 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
231 clipSpaceRTIBounds.offset(clipDataIn->fOrigin); 232 clipSpaceRTIBounds.offset(clipDataIn->fOrigin);
232 GrReducedClip::ReduceClipStack(*clipDataIn->fClipStack, 233 GrReducedClip::ReduceClipStack(*clipDataIn->fClipStack,
233 clipSpaceRTIBounds, 234 clipSpaceRTIBounds,
234 &elements, 235 &elements,
235 &genID, 236 &genID,
236 &initialState, 237 &initialState,
237 &clipSpaceIBounds, 238 &clipSpaceIBounds,
238 &requiresAA); 239 &requiresAA);
239 if (elements.isEmpty()) { 240 if (elements.isEmpty()) {
240 if (GrReducedClip::kAllIn_InitialState == initialState) { 241 if (GrReducedClip::kAllIn_InitialState == initialState) {
241 ignoreClip = clipSpaceIBounds == clipSpaceRTIBounds; 242 ignoreClip = clipSpaceIBounds == clipSpaceRTIBounds;
242 } else { 243 } else {
243 return false; 244 return false;
244 } 245 }
245 } 246 }
246 } 247 }
247 248
248 if (ignoreClip) { 249 if (ignoreClip) {
249 this->setDrawStateStencil(drawState, ars); 250 this->setPipelineBuilderStencil(pipelineBuilder, ars);
250 return true; 251 return true;
251 } 252 }
252 253
253 // An element count of 4 was chosen because of the common pattern in Blink o f: 254 // An element count of 4 was chosen because of the common pattern in Blink o f:
254 // isect RR 255 // isect RR
255 // diff RR 256 // diff RR
256 // isect convex_poly 257 // isect convex_poly
257 // isect convex_poly 258 // isect convex_poly
258 // when drawing rounded div borders. This could probably be tuned based on a 259 // when drawing rounded div borders. This could probably be tuned based on a
259 // configuration's relative costs of switching RTs to generate a mask vs 260 // configuration's relative costs of switching RTs to generate a mask vs
260 // longer shaders. 261 // longer shaders.
261 if (elements.count() <= 4) { 262 if (elements.count() <= 4) {
262 SkVector clipToRTOffset = { SkIntToScalar(-clipDataIn->fOrigin.fX), 263 SkVector clipToRTOffset = { SkIntToScalar(-clipDataIn->fOrigin.fX),
263 SkIntToScalar(-clipDataIn->fOrigin.fY) }; 264 SkIntToScalar(-clipDataIn->fOrigin.fY) };
264 if (elements.isEmpty() || 265 if (elements.isEmpty() ||
265 (requiresAA && this->installClipEffects(drawState, are, elements, cl ipToRTOffset, 266 (requiresAA && this->installClipEffects(pipelineBuilder, are, elemen ts, clipToRTOffset,
266 devBounds))) { 267 devBounds))) {
267 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 268 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
268 scissorSpaceIBounds.offset(-clipDataIn->fOrigin); 269 scissorSpaceIBounds.offset(-clipDataIn->fOrigin);
269 if (NULL == devBounds || 270 if (NULL == devBounds ||
270 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { 271 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
271 scissorState->set(scissorSpaceIBounds); 272 scissorState->set(scissorSpaceIBounds);
272 } 273 }
273 this->setDrawStateStencil(drawState, ars); 274 this->setPipelineBuilderStencil(pipelineBuilder, ars);
274 return true; 275 return true;
275 } 276 }
276 } 277 }
277 278
278 #if GR_AA_CLIP 279 #if GR_AA_CLIP
279 // If MSAA is enabled we can do everything in the stencil buffer. 280 // If MSAA is enabled we can do everything in the stencil buffer.
280 if (0 == rt->numSamples() && requiresAA) { 281 if (0 == rt->numSamples() && requiresAA) {
281 GrTexture* result = NULL; 282 GrTexture* result = NULL;
282 283
283 // The top-left of the mask corresponds to the top-left corner of the bo unds. 284 // The top-left of the mask corresponds to the top-left corner of the bo unds.
284 SkVector clipToMaskOffset = { 285 SkVector clipToMaskOffset = {
285 SkIntToScalar(-clipSpaceIBounds.fLeft), 286 SkIntToScalar(-clipSpaceIBounds.fLeft),
286 SkIntToScalar(-clipSpaceIBounds.fTop) 287 SkIntToScalar(-clipSpaceIBounds.fTop)
287 }; 288 };
288 289
289 if (this->useSWOnlyPath(drawState, clipToMaskOffset, elements)) { 290 if (this->useSWOnlyPath(pipelineBuilder, clipToMaskOffset, elements)) {
290 // The clip geometry is complex enough that it will be more efficien t to create it 291 // The clip geometry is complex enough that it will be more efficien t to create it
291 // entirely in software 292 // entirely in software
292 result = this->createSoftwareClipMask(genID, 293 result = this->createSoftwareClipMask(genID,
293 initialState, 294 initialState,
294 elements, 295 elements,
295 clipToMaskOffset, 296 clipToMaskOffset,
296 clipSpaceIBounds); 297 clipSpaceIBounds);
297 } else { 298 } else {
298 result = this->createAlphaClipMask(genID, 299 result = this->createAlphaClipMask(genID,
299 initialState, 300 initialState,
300 elements, 301 elements,
301 clipToMaskOffset, 302 clipToMaskOffset,
302 clipSpaceIBounds); 303 clipSpaceIBounds);
303 } 304 }
304 305
305 if (result) { 306 if (result) {
306 // The mask's top left coord should be pinned to the rounded-out top left corner of 307 // The mask's top left coord should be pinned to the rounded-out top left corner of
307 // clipSpace bounds. We determine the mask's position WRT to the ren der target here. 308 // clipSpace bounds. We determine the mask's position WRT to the ren der target here.
308 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; 309 SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
309 rtSpaceMaskBounds.offset(-clipDataIn->fOrigin); 310 rtSpaceMaskBounds.offset(-clipDataIn->fOrigin);
310 setup_drawstate_aaclip(rtSpaceMaskBounds, drawState, result); 311 setup_drawstate_aaclip(rtSpaceMaskBounds, pipelineBuilder, result);
311 this->setDrawStateStencil(drawState, ars); 312 this->setPipelineBuilderStencil(pipelineBuilder, ars);
312 return true; 313 return true;
313 } 314 }
314 // if alpha clip mask creation fails fall through to the non-AA code pat hs 315 // if alpha clip mask creation fails fall through to the non-AA code pat hs
315 } 316 }
316 #endif // GR_AA_CLIP 317 #endif // GR_AA_CLIP
317 318
318 // Either a hard (stencil buffer) clip was explicitly requested or an anti-a liased clip couldn't 319 // Either a hard (stencil buffer) clip was explicitly requested or an anti-a liased clip couldn't
319 // be created. In either case, free up the texture in the anti-aliased mask cache. 320 // be created. In either case, free up the texture in the anti-aliased mask cache.
320 // TODO: this may require more investigation. Ganesh performs a lot of utili ty draws (e.g., 321 // TODO: this may require more investigation. Ganesh performs a lot of utili ty draws (e.g.,
321 // clears, InOrderDrawBuffer playbacks) that hit the stencil buffer path. Th ese may be 322 // clears, InOrderDrawBuffer playbacks) that hit the stencil buffer path. Th ese may be
322 // "incorrectly" clearing the AA cache. 323 // "incorrectly" clearing the AA cache.
323 fAACache.reset(); 324 fAACache.reset();
324 325
325 // use the stencil clip if we can't represent the clip as a rectangle. 326 // use the stencil clip if we can't represent the clip as a rectangle.
326 SkIPoint clipSpaceToStencilSpaceOffset = -clipDataIn->fOrigin; 327 SkIPoint clipSpaceToStencilSpaceOffset = -clipDataIn->fOrigin;
327 this->createStencilClipMask(rt, 328 this->createStencilClipMask(rt,
328 genID, 329 genID,
329 initialState, 330 initialState,
330 elements, 331 elements,
331 clipSpaceIBounds, 332 clipSpaceIBounds,
332 clipSpaceToStencilSpaceOffset); 333 clipSpaceToStencilSpaceOffset);
333 334
334 // This must occur after createStencilClipMask. That function may change the scissor. Also, it 335 // This must occur after createStencilClipMask. That function may change the scissor. Also, it
335 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must 336 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must
336 // use both stencil and scissor test to the bounds for the final draw. 337 // use both stencil and scissor test to the bounds for the final draw.
337 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 338 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
338 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); 339 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
339 scissorState->set(scissorSpaceIBounds); 340 scissorState->set(scissorSpaceIBounds);
340 this->setDrawStateStencil(drawState, ars); 341 this->setPipelineBuilderStencil(pipelineBuilder, ars);
341 return true; 342 return true;
342 } 343 }
343 344
344 namespace { 345 namespace {
345 //////////////////////////////////////////////////////////////////////////////// 346 ////////////////////////////////////////////////////////////////////////////////
346 // Set a coverage drawing XPF on the drawState for the given op and invertCovera ge mode 347 // Set a coverage drawing XPF on the pipelineBuilder for the given op and invert Coverage mode
347 void set_coverage_drawing_xpf(SkRegion::Op op, bool invertCoverage, GrDrawState* drawState) { 348 void set_coverage_drawing_xpf(SkRegion::Op op, bool invertCoverage,
349 GrPipelineBuilder* pipelineBuilder) {
348 SkASSERT(op <= SkRegion::kLastOp); 350 SkASSERT(op <= SkRegion::kLastOp);
349 drawState->setCoverageSetOpXPFactory(op, invertCoverage); 351 pipelineBuilder->setCoverageSetOpXPFactory(op, invertCoverage);
350 } 352 }
351 } 353 }
352 354
353 //////////////////////////////////////////////////////////////////////////////// 355 ////////////////////////////////////////////////////////////////////////////////
354 bool GrClipMaskManager::drawElement(GrDrawState* drawState, 356 bool GrClipMaskManager::drawElement(GrPipelineBuilder* pipelineBuilder,
355 const SkMatrix& viewMatrix, 357 const SkMatrix& viewMatrix,
356 GrTexture* target, 358 GrTexture* target,
357 const SkClipStack::Element* element, 359 const SkClipStack::Element* element,
358 GrPathRenderer* pr) { 360 GrPathRenderer* pr) {
359 GrDrawTarget::AutoGeometryPush agp(fClipTarget); 361 GrDrawTarget::AutoGeometryPush agp(fClipTarget);
360 362
361 drawState->setRenderTarget(target->asRenderTarget()); 363 pipelineBuilder->setRenderTarget(target->asRenderTarget());
362 364
363 // The color we use to draw does not matter since we will always be using a GrCoverageSetOpXP 365 // The color we use to draw does not matter since we will always be using a GrCoverageSetOpXP
364 // which ignores color. 366 // which ignores color.
365 GrColor color = GrColor_WHITE; 367 GrColor color = GrColor_WHITE;
366 368
367 // TODO: Draw rrects directly here. 369 // TODO: Draw rrects directly here.
368 switch (element->getType()) { 370 switch (element->getType()) {
369 case Element::kEmpty_Type: 371 case Element::kEmpty_Type:
370 SkDEBUGFAIL("Should never get here with an empty element."); 372 SkDEBUGFAIL("Should never get here with an empty element.");
371 break; 373 break;
372 case Element::kRect_Type: 374 case Element::kRect_Type:
373 // TODO: Do rects directly to the accumulator using a aa-rect GrProc essor that covers 375 // TODO: Do rects directly to the accumulator using a aa-rect GrProc essor that covers
374 // the entire mask bounds and writes 0 outside the rect. 376 // the entire mask bounds and writes 0 outside the rect.
375 if (element->isAA()) { 377 if (element->isAA()) {
376 SkRect devRect = element->getRect(); 378 SkRect devRect = element->getRect();
377 viewMatrix.mapRect(&devRect); 379 viewMatrix.mapRect(&devRect);
378 this->getContext()->getAARectRenderer()->fillAARect(fClipTarget, 380 this->getContext()->getAARectRenderer()->fillAARect(fClipTarget,
379 drawState, 381 pipelineBuil der,
380 color, 382 color,
381 viewMatrix, 383 viewMatrix,
382 element->get Rect(), 384 element->get Rect(),
383 devRect); 385 devRect);
384 } else { 386 } else {
385 fClipTarget->drawSimpleRect(drawState, color, viewMatrix, elemen t->getRect()); 387 fClipTarget->drawSimpleRect(pipelineBuilder, color, viewMatrix, element->getRect());
386 } 388 }
387 return true; 389 return true;
388 default: { 390 default: {
389 SkPath path; 391 SkPath path;
390 element->asPath(&path); 392 element->asPath(&path);
391 path.setIsVolatile(true); 393 path.setIsVolatile(true);
392 if (path.isInverseFillType()) { 394 if (path.isInverseFillType()) {
393 path.toggleInverseFillType(); 395 path.toggleInverseFillType();
394 } 396 }
395 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 397 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
396 if (NULL == pr) { 398 if (NULL == pr) {
397 GrPathRendererChain::DrawType type; 399 GrPathRendererChain::DrawType type;
398 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr awType : 400 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr awType :
399 GrPathRendererChain::kColor_DrawType; 401 GrPathRendererChain::kColor_DrawType;
400 pr = this->getContext()->getPathRenderer(fClipTarget, drawState, viewMatrix, path, 402 pr = this->getContext()->getPathRenderer(fClipTarget, pipelineBu ilder, viewMatrix,
401 stroke, false, type); 403 path, stroke, false, ty pe);
402 } 404 }
403 if (NULL == pr) { 405 if (NULL == pr) {
404 return false; 406 return false;
405 } 407 }
406 408
407 pr->drawPath(fClipTarget, drawState, color, viewMatrix, path, stroke , element->isAA()); 409 pr->drawPath(fClipTarget, pipelineBuilder, color, viewMatrix, path, stroke,
410 element->isAA());
408 break; 411 break;
409 } 412 }
410 } 413 }
411 return true; 414 return true;
412 } 415 }
413 416
414 bool GrClipMaskManager::canStencilAndDrawElement(GrDrawState* drawState, 417 bool GrClipMaskManager::canStencilAndDrawElement(GrPipelineBuilder* pipelineBuil der,
415 GrTexture* target, 418 GrTexture* target,
416 GrPathRenderer** pr, 419 GrPathRenderer** pr,
417 const SkClipStack::Element* ele ment) { 420 const SkClipStack::Element* ele ment) {
418 drawState->setRenderTarget(target->asRenderTarget()); 421 pipelineBuilder->setRenderTarget(target->asRenderTarget());
419 422
420 if (Element::kRect_Type == element->getType()) { 423 if (Element::kRect_Type == element->getType()) {
421 return true; 424 return true;
422 } else { 425 } else {
423 // We shouldn't get here with an empty clip element. 426 // We shouldn't get here with an empty clip element.
424 SkASSERT(Element::kEmpty_Type != element->getType()); 427 SkASSERT(Element::kEmpty_Type != element->getType());
425 SkPath path; 428 SkPath path;
426 element->asPath(&path); 429 element->asPath(&path);
427 if (path.isInverseFillType()) { 430 if (path.isInverseFillType()) {
428 path.toggleInverseFillType(); 431 path.toggleInverseFillType();
429 } 432 }
430 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 433 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
431 GrPathRendererChain::DrawType type = element->isAA() ? 434 GrPathRendererChain::DrawType type = element->isAA() ?
432 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : 435 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
433 GrPathRendererChain::kStencilAndColor_DrawType; 436 GrPathRendererChain::kStencilAndColor_DrawType;
434 *pr = this->getContext()->getPathRenderer(fClipTarget, drawState, SkMatr ix::I(), path, 437 *pr = this->getContext()->getPathRenderer(fClipTarget, pipelineBuilder, SkMatrix::I(), path,
435 stroke, false, type); 438 stroke, false, type);
436 return SkToBool(*pr); 439 return SkToBool(*pr);
437 } 440 }
438 } 441 }
439 442
440 void GrClipMaskManager::mergeMask(GrDrawState* drawState, 443 void GrClipMaskManager::mergeMask(GrPipelineBuilder* pipelineBuilder,
441 GrTexture* dstMask, 444 GrTexture* dstMask,
442 GrTexture* srcMask, 445 GrTexture* srcMask,
443 SkRegion::Op op, 446 SkRegion::Op op,
444 const SkIRect& dstBound, 447 const SkIRect& dstBound,
445 const SkIRect& srcBound) { 448 const SkIRect& srcBound) {
446 drawState->setRenderTarget(dstMask->asRenderTarget()); 449 pipelineBuilder->setRenderTarget(dstMask->asRenderTarget());
447 450
448 // We want to invert the coverage here 451 // We want to invert the coverage here
449 set_coverage_drawing_xpf(op, false, drawState); 452 set_coverage_drawing_xpf(op, false, pipelineBuilder);
450 453
451 SkMatrix sampleM; 454 SkMatrix sampleM;
452 sampleM.setIDiv(srcMask->width(), srcMask->height()); 455 sampleM.setIDiv(srcMask->width(), srcMask->height());
453 456
454 drawState->addCoverageProcessor( 457 pipelineBuilder->addCoverageProcessor(
455 GrTextureDomainEffect::Create(srcMask, 458 GrTextureDomainEffect::Create(srcMask,
456 sampleM, 459 sampleM,
457 GrTextureDomain::MakeTexelDomain(srcMask, srcBound), 460 GrTextureDomain::MakeTexelDomain(srcMask, srcBound),
458 GrTextureDomain::kDecal_Mode, 461 GrTextureDomain::kDecal_Mode,
459 GrTextureParams::kNone_FilterMode))->unref (); 462 GrTextureParams::kNone_FilterMode))->unref ();
460 // The color passed in here does not matter since the coverageSetOpXP won't read it. 463 // The color passed in here does not matter since the coverageSetOpXP won't read it.
461 fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkMatrix::I(), SkRect: :Make(dstBound)); 464 fClipTarget->drawSimpleRect(pipelineBuilder, GrColor_WHITE, SkMatrix::I(),
465 SkRect::Make(dstBound));
462 } 466 }
463 467
464 GrTexture* GrClipMaskManager::createTempMask(int width, int height) { 468 GrTexture* GrClipMaskManager::createTempMask(int width, int height) {
465 GrSurfaceDesc desc; 469 GrSurfaceDesc desc;
466 desc.fFlags = kRenderTarget_GrSurfaceFlag; 470 desc.fFlags = kRenderTarget_GrSurfaceFlag;
467 desc.fWidth = width; 471 desc.fWidth = width;
468 desc.fHeight = height; 472 desc.fHeight = height;
469 if (this->getContext()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { 473 if (this->getContext()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
470 desc.fConfig = kAlpha_8_GrPixelConfig; 474 desc.fConfig = kAlpha_8_GrPixelConfig;
471 } else { 475 } else {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 // cleared. 560 // cleared.
557 GrDrawTarget::AutoClipRestore acr(fClipTarget, maskSpaceIBounds); 561 GrDrawTarget::AutoClipRestore acr(fClipTarget, maskSpaceIBounds);
558 SkAutoTUnref<GrTexture> temp; 562 SkAutoTUnref<GrTexture> temp;
559 563
560 // walk through each clip element and perform its set op 564 // walk through each clip element and perform its set op
561 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) { 565 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) {
562 const Element* element = iter.get(); 566 const Element* element = iter.get();
563 SkRegion::Op op = element->getOp(); 567 SkRegion::Op op = element->getOp();
564 bool invert = element->isInverseFilled(); 568 bool invert = element->isInverseFilled();
565 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) { 569 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) {
566 GrDrawState drawState; 570 GrPipelineBuilder pipelineBuilder;
567 drawState.enableState(GrDrawState::kClip_StateBit); 571 pipelineBuilder.enableState(GrPipelineBuilder::kClip_StateBit);
568 572
569 GrPathRenderer* pr = NULL; 573 GrPathRenderer* pr = NULL;
570 bool useTemp = !this->canStencilAndDrawElement(&drawState, result, & pr, element); 574 bool useTemp = !this->canStencilAndDrawElement(&pipelineBuilder, res ult, &pr, element);
571 GrTexture* dst; 575 GrTexture* dst;
572 // This is the bounds of the clip element in the space of the alpha- mask. The temporary 576 // This is the bounds of the clip element in the space of the alpha- mask. The temporary
573 // mask buffer can be substantially larger than the actually clip st ack element. We 577 // mask buffer can be substantially larger than the actually clip st ack element. We
574 // touch the minimum number of pixels necessary and use decal mode t o combine it with 578 // touch the minimum number of pixels necessary and use decal mode t o combine it with
575 // the accumulator. 579 // the accumulator.
576 SkIRect maskSpaceElementIBounds; 580 SkIRect maskSpaceElementIBounds;
577 581
578 if (useTemp) { 582 if (useTemp) {
579 if (invert) { 583 if (invert) {
580 maskSpaceElementIBounds = maskSpaceIBounds; 584 maskSpaceElementIBounds = maskSpaceIBounds;
(...skipping 10 matching lines...) Expand all
591 fAACache.reset(); 595 fAACache.reset();
592 return NULL; 596 return NULL;
593 } 597 }
594 } 598 }
595 dst = temp; 599 dst = temp;
596 // clear the temp target and set blend to replace 600 // clear the temp target and set blend to replace
597 fClipTarget->clear(&maskSpaceElementIBounds, 601 fClipTarget->clear(&maskSpaceElementIBounds,
598 invert ? 0xffffffff : 0x00000000, 602 invert ? 0xffffffff : 0x00000000,
599 true, 603 true,
600 dst->asRenderTarget()); 604 dst->asRenderTarget());
601 set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &drawSta te); 605 set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &pipelin eBuilder);
602 } else { 606 } else {
603 // draw directly into the result with the stencil set to make th e pixels affected 607 // draw directly into the result with the stencil set to make th e pixels affected
604 // by the clip shape be non-zero. 608 // by the clip shape be non-zero.
605 dst = result; 609 dst = result;
606 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, 610 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement,
607 kReplace_StencilOp, 611 kReplace_StencilOp,
608 kReplace_StencilOp, 612 kReplace_StencilOp,
609 kAlways_StencilFunc, 613 kAlways_StencilFunc,
610 0xffff, 614 0xffff,
611 0xffff, 615 0xffff,
612 0xffff); 616 0xffff);
613 drawState.setStencil(kStencilInElement); 617 pipelineBuilder.setStencil(kStencilInElement);
614 set_coverage_drawing_xpf(op, invert, &drawState); 618 set_coverage_drawing_xpf(op, invert, &pipelineBuilder);
615 } 619 }
616 620
617 if (!this->drawElement(&drawState, translate, dst, element, pr)) { 621 if (!this->drawElement(&pipelineBuilder, translate, dst, element, pr )) {
618 fAACache.reset(); 622 fAACache.reset();
619 return NULL; 623 return NULL;
620 } 624 }
621 625
622 if (useTemp) { 626 if (useTemp) {
623 GrDrawState backgroundDrawState; 627 GrPipelineBuilder backgroundPipelineBuilder;
624 backgroundDrawState.enableState(GrDrawState::kClip_StateBit); 628 backgroundPipelineBuilder.enableState(GrPipelineBuilder::kClip_S tateBit);
625 backgroundDrawState.setRenderTarget(result->asRenderTarget()); 629 backgroundPipelineBuilder.setRenderTarget(result->asRenderTarget ());
626 630
627 // Now draw into the accumulator using the real operation and th e temp buffer as a 631 // Now draw into the accumulator using the real operation and th e temp buffer as a
628 // texture 632 // texture
629 this->mergeMask(&backgroundDrawState, 633 this->mergeMask(&backgroundPipelineBuilder,
630 result, 634 result,
631 temp, 635 temp,
632 op, 636 op,
633 maskSpaceIBounds, 637 maskSpaceIBounds,
634 maskSpaceElementIBounds); 638 maskSpaceElementIBounds);
635 } else { 639 } else {
636 GrDrawState backgroundDrawState; 640 GrPipelineBuilder backgroundPipelineBuilder;
637 backgroundDrawState.enableState(GrDrawState::kClip_StateBit); 641 backgroundPipelineBuilder.enableState(GrPipelineBuilder::kClip_S tateBit);
638 backgroundDrawState.setRenderTarget(result->asRenderTarget()); 642 backgroundPipelineBuilder.setRenderTarget(result->asRenderTarget ());
639 643
640 set_coverage_drawing_xpf(op, !invert, &backgroundDrawState); 644 set_coverage_drawing_xpf(op, !invert, &backgroundPipelineBuilder );
641 // Draw to the exterior pixels (those with a zero stencil value) . 645 // Draw to the exterior pixels (those with a zero stencil value) .
642 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, 646 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement,
643 kZero_StencilOp, 647 kZero_StencilOp,
644 kZero_StencilOp, 648 kZero_StencilOp,
645 kEqual_StencilFunc, 649 kEqual_StencilFunc,
646 0xffff, 650 0xffff,
647 0x0000, 651 0x0000,
648 0xffff); 652 0xffff);
649 backgroundDrawState.setStencil(kDrawOutsideElement); 653 backgroundPipelineBuilder.setStencil(kDrawOutsideElement);
650 // The color passed in here does not matter since the coverageSe tOpXP won't read it. 654 // The color passed in here does not matter since the coverageSe tOpXP won't read it.
651 fClipTarget->drawSimpleRect(&backgroundDrawState, GrColor_WHITE, translate, 655 fClipTarget->drawSimpleRect(&backgroundPipelineBuilder, GrColor_ WHITE, translate,
652 clipSpaceIBounds); 656 clipSpaceIBounds);
653 } 657 }
654 } else { 658 } else {
655 GrDrawState drawState; 659 GrPipelineBuilder pipelineBuilder;
656 drawState.enableState(GrDrawState::kClip_StateBit); 660 pipelineBuilder.enableState(GrPipelineBuilder::kClip_StateBit);
657 661
658 // all the remaining ops can just be directly draw into the accumula tion buffer 662 // all the remaining ops can just be directly draw into the accumula tion buffer
659 set_coverage_drawing_xpf(op, false, &drawState); 663 set_coverage_drawing_xpf(op, false, &pipelineBuilder);
660 // The color passed in here does not matter since the coverageSetOpX P won't read it. 664 // The color passed in here does not matter since the coverageSetOpX P won't read it.
661 this->drawElement(&drawState, translate, result, element); 665 this->drawElement(&pipelineBuilder, translate, result, element);
662 } 666 }
663 } 667 }
664 668
665 fCurrClipMaskType = kAlpha_ClipMaskType; 669 fCurrClipMaskType = kAlpha_ClipMaskType;
666 return result; 670 return result;
667 } 671 }
668 672
669 //////////////////////////////////////////////////////////////////////////////// 673 ////////////////////////////////////////////////////////////////////////////////
670 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device 674 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
671 // (as opposed to canvas) coordinates 675 // (as opposed to canvas) coordinates
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 709
706 fClipTarget->clearStencilClip(stencilSpaceIBounds, 710 fClipTarget->clearStencilClip(stencilSpaceIBounds,
707 GrReducedClip::kAllIn_InitialState == init ialState, 711 GrReducedClip::kAllIn_InitialState == init ialState,
708 rt); 712 rt);
709 713
710 // walk through each clip element and perform its set op 714 // walk through each clip element and perform its set op
711 // with the existing clip. 715 // with the existing clip.
712 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) { 716 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) {
713 const Element* element = iter.get(); 717 const Element* element = iter.get();
714 718
715 GrDrawState drawState; 719 GrPipelineBuilder pipelineBuilder;
716 drawState.setRenderTarget(rt); 720 pipelineBuilder.setRenderTarget(rt);
717 drawState.enableState(GrDrawState::kClip_StateBit); 721 pipelineBuilder.enableState(GrPipelineBuilder::kClip_StateBit);
718 722
719 drawState.setDisableColorXPFactory(); 723 pipelineBuilder.setDisableColorXPFactory();
720 724
721 // if the target is MSAA then we want MSAA enabled when the clip is soft 725 // if the target is MSAA then we want MSAA enabled when the clip is soft
722 if (rt->isMultisampled()) { 726 if (rt->isMultisampled()) {
723 drawState.setState(GrDrawState::kHWAntialias_StateBit, element-> isAA()); 727 pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_StateBi t, element->isAA());
724 } 728 }
725 729
726 bool fillInverted = false; 730 bool fillInverted = false;
727 // enabled at bottom of loop 731 // enabled at bottom of loop
728 fClipMode = kIgnoreClip_StencilClipMode; 732 fClipMode = kIgnoreClip_StencilClipMode;
729 733
730 // This will be used to determine whether the clip shape can be rend ered into the 734 // This will be used to determine whether the clip shape can be rend ered into the
731 // stencil with arbitrary stencil settings. 735 // stencil with arbitrary stencil settings.
732 GrPathRenderer::StencilSupport stencilSupport; 736 GrPathRenderer::StencilSupport stencilSupport;
733 737
734 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 738 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
735 SkRegion::Op op = element->getOp(); 739 SkRegion::Op op = element->getOp();
736 740
737 GrPathRenderer* pr = NULL; 741 GrPathRenderer* pr = NULL;
738 SkPath clipPath; 742 SkPath clipPath;
739 if (Element::kRect_Type == element->getType()) { 743 if (Element::kRect_Type == element->getType()) {
740 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; 744 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
741 fillInverted = false; 745 fillInverted = false;
742 } else { 746 } else {
743 element->asPath(&clipPath); 747 element->asPath(&clipPath);
744 fillInverted = clipPath.isInverseFillType(); 748 fillInverted = clipPath.isInverseFillType();
745 if (fillInverted) { 749 if (fillInverted) {
746 clipPath.toggleInverseFillType(); 750 clipPath.toggleInverseFillType();
747 } 751 }
748 pr = this->getContext()->getPathRenderer(fClipTarget, 752 pr = this->getContext()->getPathRenderer(fClipTarget,
749 &drawState, 753 &pipelineBuilder,
750 viewMatrix, 754 viewMatrix,
751 clipPath, 755 clipPath,
752 stroke, 756 stroke,
753 false, 757 false,
754 GrPathRendererChain::kS tencilOnly_DrawType, 758 GrPathRendererChain::kS tencilOnly_DrawType,
755 &stencilSupport); 759 &stencilSupport);
756 if (NULL == pr) { 760 if (NULL == pr) {
757 return false; 761 return false;
758 } 762 }
759 } 763 }
(...skipping 17 matching lines...) Expand all
777 // draw the element to the client stencil bits if necessary 781 // draw the element to the client stencil bits if necessary
778 if (!canDrawDirectToClip) { 782 if (!canDrawDirectToClip) {
779 GR_STATIC_CONST_SAME_STENCIL(gDrawToStencil, 783 GR_STATIC_CONST_SAME_STENCIL(gDrawToStencil,
780 kIncClamp_StencilOp, 784 kIncClamp_StencilOp,
781 kIncClamp_StencilOp, 785 kIncClamp_StencilOp,
782 kAlways_StencilFunc, 786 kAlways_StencilFunc,
783 0xffff, 787 0xffff,
784 0x0000, 788 0x0000,
785 0xffff); 789 0xffff);
786 if (Element::kRect_Type == element->getType()) { 790 if (Element::kRect_Type == element->getType()) {
787 *drawState.stencil() = gDrawToStencil; 791 *pipelineBuilder.stencil() = gDrawToStencil;
788 fClipTarget->drawSimpleRect(&drawState, GrColor_WHITE, viewM atrix, 792 fClipTarget->drawSimpleRect(&pipelineBuilder, GrColor_WHITE, viewMatrix,
789 element->getRect()); 793 element->getRect());
790 } else { 794 } else {
791 if (!clipPath.isEmpty()) { 795 if (!clipPath.isEmpty()) {
792 GrDrawTarget::AutoGeometryPush agp(fClipTarget); 796 GrDrawTarget::AutoGeometryPush agp(fClipTarget);
793 if (canRenderDirectToStencil) { 797 if (canRenderDirectToStencil) {
794 *drawState.stencil() = gDrawToStencil; 798 *pipelineBuilder.stencil() = gDrawToStencil;
795 pr->drawPath(fClipTarget, &drawState, GrColor_WHITE, viewMatrix, 799 pr->drawPath(fClipTarget, &pipelineBuilder, GrColor_ WHITE, viewMatrix,
796 clipPath, stroke, false); 800 clipPath, stroke, false);
797 } else { 801 } else {
798 pr->stencilPath(fClipTarget, &drawState, viewMatrix, clipPath, stroke); 802 pr->stencilPath(fClipTarget, &pipelineBuilder, viewM atrix, clipPath,
803 stroke);
799 } 804 }
800 } 805 }
801 } 806 }
802 } 807 }
803 808
804 // now we modify the clip bit by rendering either the clip 809 // now we modify the clip bit by rendering either the clip
805 // element directly or a bounding rect of the entire clip. 810 // element directly or a bounding rect of the entire clip.
806 fClipMode = kModifyClip_StencilClipMode; 811 fClipMode = kModifyClip_StencilClipMode;
807 for (int p = 0; p < passes; ++p) { 812 for (int p = 0; p < passes; ++p) {
808 GrDrawState drawStateCopy(drawState); 813 GrPipelineBuilder pipelineBuilderCopy(pipelineBuilder);
809 *drawStateCopy.stencil() = stencilSettings[p]; 814 *pipelineBuilderCopy.stencil() = stencilSettings[p];
810 815
811 if (canDrawDirectToClip) { 816 if (canDrawDirectToClip) {
812 if (Element::kRect_Type == element->getType()) { 817 if (Element::kRect_Type == element->getType()) {
813 fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHIT E, viewMatrix, 818 fClipTarget->drawSimpleRect(&pipelineBuilderCopy, GrColo r_WHITE, viewMatrix,
814 element->getRect()); 819 element->getRect());
815 } else { 820 } else {
816 GrDrawTarget::AutoGeometryPush agp(fClipTarget); 821 GrDrawTarget::AutoGeometryPush agp(fClipTarget);
817 pr->drawPath(fClipTarget, &drawStateCopy, GrColor_WHITE, viewMatrix, 822 pr->drawPath(fClipTarget, &pipelineBuilderCopy, GrColor_ WHITE, viewMatrix,
818 clipPath, stroke, false); 823 clipPath, stroke, false);
819 } 824 }
820 } else { 825 } else {
821 // The view matrix is setup to do clip space -> stencil spac e translation, so 826 // The view matrix is setup to do clip space -> stencil spac e translation, so
822 // draw rect in clip space. 827 // draw rect in clip space.
823 fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE, v iewMatrix, 828 fClipTarget->drawSimpleRect(&pipelineBuilderCopy, GrColor_WH ITE, viewMatrix,
824 SkRect::Make(clipSpaceIBounds)); 829 SkRect::Make(clipSpaceIBounds));
825 } 830 }
826 } 831 }
827 } 832 }
828 } 833 }
829 // set this last because recursive draws may overwrite it back to kNone. 834 // set this last because recursive draws may overwrite it back to kNone.
830 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); 835 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
831 fCurrClipMaskType = kStencil_ClipMaskType; 836 fCurrClipMaskType = kStencil_ClipMaskType;
832 fClipMode = kRespectClip_StencilClipMode; 837 fClipMode = kRespectClip_StencilClipMode;
833 return true; 838 return true;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 kKeep_StencilOp, 883 kKeep_StencilOp,
879 kKeep_StencilOp, 884 kKeep_StencilOp,
880 kAlwaysIfInClip_StencilFunc, 885 kAlwaysIfInClip_StencilFunc,
881 0x0000, 886 0x0000,
882 0x0000, 887 0x0000,
883 0x0000); 888 0x0000);
884 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); 889 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
885 } 890 }
886 } 891 }
887 892
888 void GrClipMaskManager::setDrawStateStencil(GrDrawState* drawState, 893 void GrClipMaskManager::setPipelineBuilderStencil(GrPipelineBuilder* pipelineBui lder,
889 GrDrawState::AutoRestoreStencil* ars ) { 894 GrPipelineBuilder::AutoRestore Stencil* ars) {
890 // We make two copies of the StencilSettings here (except in the early 895 // We make two copies of the StencilSettings here (except in the early
891 // exit scenario. One copy from draw state to the stack var. Then another 896 // exit scenario. One copy from draw state to the stack var. Then another
892 // from the stack var to the gpu. We could make this class hold a ptr to 897 // from the stack var to the gpu. We could make this class hold a ptr to
893 // GrGpu's fStencilSettings and eliminate the stack copy here. 898 // GrGpu's fStencilSettings and eliminate the stack copy here.
894 899
895 // use stencil for clipping if clipping is enabled and the clip 900 // use stencil for clipping if clipping is enabled and the clip
896 // has been written into the stencil. 901 // has been written into the stencil.
897 GrStencilSettings settings; 902 GrStencilSettings settings;
898 903
899 // The GrGpu client may not be using the stencil buffer but we may need to 904 // The GrGpu client may not be using the stencil buffer but we may need to
900 // enable it in order to respect a stencil clip. 905 // enable it in order to respect a stencil clip.
901 if (drawState->getStencil().isDisabled()) { 906 if (pipelineBuilder->getStencil().isDisabled()) {
902 if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) { 907 if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) {
903 settings = basic_apply_stencil_clip_settings(); 908 settings = basic_apply_stencil_clip_settings();
904 } else { 909 } else {
905 return; 910 return;
906 } 911 }
907 } else { 912 } else {
908 settings = drawState->getStencil(); 913 settings = pipelineBuilder->getStencil();
909 } 914 }
910 915
911 // TODO: dynamically attach a stencil buffer 916 // TODO: dynamically attach a stencil buffer
912 int stencilBits = 0; 917 int stencilBits = 0;
913 GrStencilBuffer* stencilBuffer = drawState->getRenderTarget()->getStencilBuf fer(); 918 GrStencilBuffer* stencilBuffer = pipelineBuilder->getRenderTarget()->getSten cilBuffer();
914 if (stencilBuffer) { 919 if (stencilBuffer) {
915 stencilBits = stencilBuffer->bits(); 920 stencilBits = stencilBuffer->bits();
916 } 921 }
917 922
918 SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapO p()); 923 SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapO p());
919 SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSid ed()); 924 SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSid ed());
920 this->adjustStencilParams(&settings, fClipMode, stencilBits); 925 this->adjustStencilParams(&settings, fClipMode, stencilBits);
921 ars->set(drawState); 926 ars->set(pipelineBuilder);
922 drawState->setStencil(settings); 927 pipelineBuilder->setStencil(settings);
923 } 928 }
924 929
925 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, 930 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings,
926 StencilClipMode mode, 931 StencilClipMode mode,
927 int stencilBitCnt) { 932 int stencilBitCnt) {
928 SkASSERT(stencilBitCnt > 0); 933 SkASSERT(stencilBitCnt > 0);
929 934
930 if (kModifyClip_StencilClipMode == mode) { 935 if (kModifyClip_StencilClipMode == mode) {
931 // We assume that this clip manager itself is drawing to the GrGpu and 936 // We assume that this clip manager itself is drawing to the GrGpu and
932 // has already setup the correct values. 937 // has already setup the correct values.
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 } 1091 }
1087 1092
1088 void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBu ffer, 1093 void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBu ffer,
1089 GrStencilSettings* settings) { 1094 GrStencilSettings* settings) {
1090 // TODO: dynamically attach a stencil buffer 1095 // TODO: dynamically attach a stencil buffer
1091 if (stencilBuffer) { 1096 if (stencilBuffer) {
1092 int stencilBits = stencilBuffer->bits(); 1097 int stencilBits = stencilBuffer->bits();
1093 this->adjustStencilParams(settings, fClipMode, stencilBits); 1098 this->adjustStencilParams(settings, fClipMode, stencilBits);
1094 } 1099 }
1095 } 1100 }
OLDNEW
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698