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

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

Issue 2035823002: Make GrClipMaskManager stateless and push GrPipelineBuilder construction downstack (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address code review comments Created 4 years, 6 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
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 "GrDrawingManager.h" 10 #include "GrDrawingManager.h"
11 #include "GrDrawContextPriv.h" 11 #include "GrDrawContextPriv.h"
12 #include "GrDrawTarget.h"
13 #include "GrGpuResourcePriv.h" 12 #include "GrGpuResourcePriv.h"
14 #include "GrPaint.h" 13 #include "GrPaint.h"
15 #include "GrPathRenderer.h" 14 #include "GrPathRenderer.h"
16 #include "GrRenderTarget.h" 15 #include "GrRenderTarget.h"
17 #include "GrRenderTargetPriv.h" 16 #include "GrRenderTargetPriv.h"
18 #include "GrResourceProvider.h" 17 #include "GrResourceProvider.h"
19 #include "GrStencilAttachment.h" 18 #include "GrStencilAttachment.h"
20 #include "GrSWMaskHelper.h" 19 #include "GrSWMaskHelper.h"
21 #include "SkRasterClip.h" 20 #include "SkRasterClip.h"
22 #include "SkTLazy.h" 21 #include "SkTLazy.h"
23 #include "batches/GrRectBatchFactory.h" 22 #include "batches/GrRectBatchFactory.h"
24 #include "effects/GrConvexPolyEffect.h" 23 #include "effects/GrConvexPolyEffect.h"
25 #include "effects/GrPorterDuffXferProcessor.h" 24 #include "effects/GrPorterDuffXferProcessor.h"
26 #include "effects/GrRRectEffect.h" 25 #include "effects/GrRRectEffect.h"
27 #include "effects/GrTextureDomain.h" 26 #include "effects/GrTextureDomain.h"
28 27
29 typedef SkClipStack::Element Element; 28 typedef SkClipStack::Element Element;
30 29
30 static const int kMaxAnalyticElements = 4;
31
31 //////////////////////////////////////////////////////////////////////////////// 32 ////////////////////////////////////////////////////////////////////////////////
32 // set up the draw state to enable the aa clipping mask. Besides setting up the 33 // set up the draw state to enable the aa clipping mask. Besides setting up the
33 // stage matrix this also alters the vertex layout 34 // stage matrix this also alters the vertex layout
34 static sk_sp<const GrFragmentProcessor> create_fp_for_mask(GrTexture* result, 35 static sk_sp<const GrFragmentProcessor> create_fp_for_mask(GrTexture* result,
35 const SkIRect &devBou nd) { 36 const SkIRect &devBou nd) {
36 SkMatrix mat; 37 SkMatrix mat;
37 // We use device coords to compute the texture coordinates. We set our matri x to be a 38 // We use device coords to compute the texture coordinates. We set our matri x to be a
38 // translation to the devBound, and then a scaling matrix to normalized coor ds. 39 // translation to the devBound, and then a scaling matrix to normalized coor ds.
39 mat.setIDiv(result->width(), result->height()); 40 mat.setIDiv(result->width(), result->height());
40 mat.preTranslate(SkIntToScalar(-devBound.fLeft), 41 mat.preTranslate(SkIntToScalar(-devBound.fLeft),
41 SkIntToScalar(-devBound.fTop)); 42 SkIntToScalar(-devBound.fTop));
42 43
43 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); 44 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height());
44 return sk_sp<const GrFragmentProcessor>(GrTextureDomainEffect::Create( 45 return sk_sp<const GrFragmentProcessor>(GrTextureDomainEffect::Create(
45 result, 46 result,
46 mat, 47 mat,
47 GrTextureDomain::MakeTexelDomain(result , domainTexels), 48 GrTextureDomain::MakeTexelDomain(result , domainTexels),
48 GrTextureDomain::kDecal_Mode, 49 GrTextureDomain::kDecal_Mode,
49 GrTextureParams::kNone_FilterMode, 50 GrTextureParams::kNone_FilterMode,
50 kDevice_GrCoordSet)); 51 kDevice_GrCoordSet));
51 } 52 }
52 53
53 static void draw_non_aa_rect(GrDrawTarget* drawTarget, 54 void GrClipMaskManager::DrawNonAARect(GrDrawContext* drawContext,
54 const GrPipelineBuilder& pipelineBuilder, 55 const GrFixedClip& clip,
55 const GrClip& clip, 56 const SkMatrix& viewMatrix,
56 GrColor color, 57 const SkRect& rect,
57 const SkMatrix& viewMatrix, 58 bool doAA,
58 const SkRect& rect) { 59 const GrUserStencilSettings* stencilSettin gs) {
59 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, v iewMatrix, rect, 60 drawContext->drawContextPriv().stencilRect(clip, stencilSettings, doAA, view Matrix, rect);
60 nullptr, nullptr));
61 drawTarget->drawBatch(pipelineBuilder, clip, batch);
62 } 61 }
63 62
64 // Does the path in 'element' require SW rendering? If so, return true (and, 63 // Does the path in 'element' require SW rendering? If so, return true (and,
65 // optionally, set 'prOut' to NULL. If not, return false (and, optionally, set 64 // optionally, set 'prOut' to NULL. If not, return false (and, optionally, set
66 // 'prOut' to the non-SW path renderer that will do the job). 65 // 'prOut' to the non-SW path renderer that will do the job).
67 bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context, 66 bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context,
68 bool hasUserStencilSettings, 67 bool hasUserStencilSettings,
69 const GrRenderTarget* rt, 68 const GrDrawContext* drawContext,
70 const SkMatrix& viewMatrix, 69 const SkMatrix& viewMatrix,
71 const Element* element, 70 const Element* element,
72 GrPathRenderer** prOut, 71 GrPathRenderer** prOut,
73 bool needsStencil) { 72 bool needsStencil) {
74 if (Element::kRect_Type == element->getType()) { 73 if (Element::kRect_Type == element->getType()) {
75 // rects can always be drawn directly w/o using the software path 74 // rects can always be drawn directly w/o using the software path
76 // TODO: skip rrects once we're drawing them directly. 75 // TODO: skip rrects once we're drawing them directly.
77 if (prOut) { 76 if (prOut) {
78 *prOut = nullptr; 77 *prOut = nullptr;
79 } 78 }
(...skipping 21 matching lines...) Expand all
101 : GrPathRendererChain::kColor_DrawType; 100 : GrPathRendererChain::kColor_DrawType;
102 } 101 }
103 102
104 GrPathRenderer::CanDrawPathArgs canDrawArgs; 103 GrPathRenderer::CanDrawPathArgs canDrawArgs;
105 canDrawArgs.fShaderCaps = context->caps()->shaderCaps(); 104 canDrawArgs.fShaderCaps = context->caps()->shaderCaps();
106 canDrawArgs.fViewMatrix = &viewMatrix; 105 canDrawArgs.fViewMatrix = &viewMatrix;
107 canDrawArgs.fPath = &path; 106 canDrawArgs.fPath = &path;
108 canDrawArgs.fStyle = &GrStyle::SimpleFill(); 107 canDrawArgs.fStyle = &GrStyle::SimpleFill();
109 canDrawArgs.fAntiAlias = element->isAA(); 108 canDrawArgs.fAntiAlias = element->isAA();
110 canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings; 109 canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
111 canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled(); 110 canDrawArgs.fIsStencilBufferMSAA = drawContext->isStencilBufferMultisamp led();
112 111
113 // the 'false' parameter disallows use of the SW path renderer 112 // the 'false' parameter disallows use of the SW path renderer
114 GrPathRenderer* pr = context->drawingManager()->getPathRenderer(canDrawA rgs, false, type); 113 GrPathRenderer* pr = context->drawingManager()->getPathRenderer(canDrawA rgs, false, type);
115 if (prOut) { 114 if (prOut) {
116 *prOut = pr; 115 *prOut = pr;
117 } 116 }
118 return SkToBool(!pr); 117 return SkToBool(!pr);
119 } 118 }
120 } 119 }
121 120
122 // Determines whether it is possible to draw the element to both the stencil buf fer and the
123 // alpha mask simultaneously. If so and the element is a path a compatible path renderer is
124 // also returned.
125 GrPathRenderer* GrClipMaskManager::GetPathRenderer(GrContext* context,
126 GrTexture* texture,
127 const SkMatrix& viewMatrix,
128 const SkClipStack::Element* e lement) {
129 GrPathRenderer* pr;
130 constexpr bool kNeedsStencil = true;
131 constexpr bool kHasUserStencilSettings = false;
132 PathNeedsSWRenderer(context,
133 kHasUserStencilSettings,
134 texture->asRenderTarget(),
135 viewMatrix,
136 element,
137 &pr,
138 kNeedsStencil);
139 return pr;
140 }
141
142 GrContext* GrClipMaskManager::getContext() {
143 return fDrawTarget->cmmAccess().context();
144 }
145
146 const GrCaps* GrClipMaskManager::caps() const {
147 return fDrawTarget->caps();
148 }
149
150 GrResourceProvider* GrClipMaskManager::resourceProvider() {
151 return fDrawTarget->cmmAccess().resourceProvider();
152 }
153 /* 121 /*
154 * This method traverses the clip stack to see if the GrSoftwarePathRenderer 122 * This method traverses the clip stack to see if the GrSoftwarePathRenderer
155 * will be used on any element. If so, it returns true to indicate that the 123 * will be used on any element. If so, it returns true to indicate that the
156 * entire clip should be rendered in SW and then uploaded en masse to the gpu. 124 * entire clip should be rendered in SW and then uploaded en masse to the gpu.
157 */ 125 */
158 bool GrClipMaskManager::UseSWOnlyPath(GrContext* context, 126 bool GrClipMaskManager::UseSWOnlyPath(GrContext* context,
159 const GrPipelineBuilder& pipelineBuilder, 127 const GrPipelineBuilder& pipelineBuilder,
160 const GrRenderTarget* rt, 128 const GrDrawContext* drawContext,
161 const SkVector& clipToMaskOffset, 129 const SkVector& clipToMaskOffset,
162 const GrReducedClip::ElementList& elements ) { 130 const GrReducedClip::ElementList& elements ) {
163 // TODO: generalize this function so that when 131 // TODO: generalize this function so that when
164 // a clip gets complex enough it can just be done in SW regardless 132 // a clip gets complex enough it can just be done in SW regardless
165 // of whether it would invoke the GrSoftwarePathRenderer. 133 // of whether it would invoke the GrSoftwarePathRenderer.
166 134
167 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip 135 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
168 // space. 136 // space.
169 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY); 137 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY);
170 138
171 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { 139 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
172 const Element* element = iter.get(); 140 const Element* element = iter.get();
173 141
174 SkRegion::Op op = element->getOp(); 142 SkRegion::Op op = element->getOp();
175 bool invert = element->isInverseFilled(); 143 bool invert = element->isInverseFilled();
176 bool needsStencil = invert || 144 bool needsStencil = invert ||
177 SkRegion::kIntersect_Op == op || SkRegion::kReverseD ifference_Op == op; 145 SkRegion::kIntersect_Op == op || SkRegion::kReverseD ifference_Op == op;
178 146
179 if (PathNeedsSWRenderer(context, pipelineBuilder.hasUserStencilSettings( ), 147 if (PathNeedsSWRenderer(context, pipelineBuilder.hasUserStencilSettings( ),
180 rt, translate, element, nullptr, needsStencil)) { 148 drawContext, translate, element, nullptr, needsS tencil)) {
181 return true; 149 return true;
182 } 150 }
183 } 151 }
184 return false; 152 return false;
185 } 153 }
186 154
187 bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis t& elements, 155 static bool get_analytic_clip_processor(const GrReducedClip::ElementList& elemen ts,
188 bool abortIfAA, 156 bool abortIfAA,
189 SkVector& clipToRTOffset, 157 SkVector& clipToRTOffset,
190 const SkRect* drawBounds, 158 const SkRect* drawBounds,
191 sk_sp<const GrFragmentProcessor >* resultFP) { 159 sk_sp<const GrFragmentProcessor>* result FP) {
192 SkRect boundsInClipSpace; 160 SkRect boundsInClipSpace;
193 if (drawBounds) { 161 if (drawBounds) {
194 boundsInClipSpace = *drawBounds; 162 boundsInClipSpace = *drawBounds;
195 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); 163 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY);
196 } 164 }
197 SkASSERT(elements.count() <= kMaxAnalyticElements); 165 SkASSERT(elements.count() <= kMaxAnalyticElements);
198 const GrFragmentProcessor* fps[kMaxAnalyticElements]; 166 const GrFragmentProcessor* fps[kMaxAnalyticElements];
199 for (int i = 0; i < kMaxAnalyticElements; ++i) { 167 for (int i = 0; i < kMaxAnalyticElements; ++i) {
200 fps[i] = nullptr; 168 fps[i] = nullptr;
201 } 169 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 } 245 }
278 for (int i = 0; i < fpCnt; ++i) { 246 for (int i = 0; i < fpCnt; ++i) {
279 fps[i]->unref(); 247 fps[i]->unref();
280 } 248 }
281 return !failed; 249 return !failed;
282 } 250 }
283 251
284 //////////////////////////////////////////////////////////////////////////////// 252 ////////////////////////////////////////////////////////////////////////////////
285 // sort out what kind of clip mask needs to be created: alpha, stencil, 253 // sort out what kind of clip mask needs to be created: alpha, stencil,
286 // scissor, or entirely software 254 // scissor, or entirely software
287 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, 255 bool GrClipMaskManager::SetupClipping(GrContext* context,
256 const GrPipelineBuilder& pipelineBuilder,
257 GrDrawContext* drawContext,
288 const GrClipStackClip& clip, 258 const GrClipStackClip& clip,
289 const SkRect* devBounds, 259 const SkRect* devBounds,
290 GrAppliedClip* out) { 260 GrAppliedClip* out) {
291 if (!clip.clipStack() || clip.clipStack()->isWideOpen()) { 261 if (!clip.clipStack() || clip.clipStack()->isWideOpen()) {
292 return true; 262 return true;
293 } 263 }
294 264
295 GrReducedClip::ElementList elements; 265 GrReducedClip::ElementList elements;
296 int32_t genID = 0; 266 int32_t genID = 0;
297 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat e; 267 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat e;
298 SkIRect clipSpaceIBounds; 268 SkIRect clipSpaceIBounds;
299 bool requiresAA = false; 269 bool requiresAA = false;
300 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
301 270
302 // GrDrawTarget should have filtered this for us 271 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(drawContext->width(), drawConte xt->height());
303 SkASSERT(rt);
304
305 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
306 clipSpaceRTIBounds.offset(clip.origin()); 272 clipSpaceRTIBounds.offset(clip.origin());
307 273
308 SkIRect clipSpaceReduceQueryBounds; 274 SkIRect clipSpaceReduceQueryBounds;
309 #define DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION 0 275 #define DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION 0
310 if (devBounds && !DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION) { 276 if (devBounds && !DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION) {
311 SkIRect devIBounds = devBounds->roundOut(); 277 SkIRect devIBounds = devBounds->roundOut();
312 devIBounds.offset(clip.origin()); 278 devIBounds.offset(clip.origin());
313 if (!clipSpaceReduceQueryBounds.intersect(clipSpaceRTIBounds, devIBounds )) { 279 if (!clipSpaceReduceQueryBounds.intersect(clipSpaceRTIBounds, devIBounds )) {
314 return false; 280 return false;
315 } 281 }
(...skipping 23 matching lines...) Expand all
339 // isect convex_poly 305 // isect convex_poly
340 // isect convex_poly 306 // isect convex_poly
341 // when drawing rounded div borders. This could probably be tuned based on a 307 // when drawing rounded div borders. This could probably be tuned based on a
342 // configuration's relative costs of switching RTs to generate a mask vs 308 // configuration's relative costs of switching RTs to generate a mask vs
343 // longer shaders. 309 // longer shaders.
344 if (elements.count() <= kMaxAnalyticElements) { 310 if (elements.count() <= kMaxAnalyticElements) {
345 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX), 311 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX),
346 SkIntToScalar(-clip.origin().fY) }; 312 SkIntToScalar(-clip.origin().fY) };
347 // When there are multiple samples we want to do per-sample clipping, no t compute a 313 // When there are multiple samples we want to do per-sample clipping, no t compute a
348 // fractional pixel coverage. 314 // fractional pixel coverage.
349 bool disallowAnalyticAA = rt->isStencilBufferMultisampled(); 315 bool disallowAnalyticAA = drawContext->isStencilBufferMultisampled();
350 if (disallowAnalyticAA && !rt->numColorSamples()) { 316 if (disallowAnalyticAA && !drawContext->numColorSamples()) {
351 // With a single color sample, any coverage info is lost from color once it hits the 317 // With a single color sample, any coverage info is lost from color once it hits the
352 // color buffer anyway, so we may as well use coverage AA if nothing else in the pipe 318 // color buffer anyway, so we may as well use coverage AA if nothing else in the pipe
353 // is multisampled. 319 // is multisampled.
354 disallowAnalyticAA = pipelineBuilder.isHWAntialias() || 320 disallowAnalyticAA = pipelineBuilder.isHWAntialias() ||
355 pipelineBuilder.hasUserStencilSettings(); 321 pipelineBuilder.hasUserStencilSettings();
356 } 322 }
357 sk_sp<const GrFragmentProcessor> clipFP; 323 sk_sp<const GrFragmentProcessor> clipFP;
358 if (elements.isEmpty() || 324 if (elements.isEmpty() ||
359 (requiresAA && 325 (requiresAA &&
360 this->getAnalyticClipProcessor(elements, disallowAnalyticAA, clipTo RTOffset, devBounds, 326 get_analytic_clip_processor(elements, disallowAnalyticAA, clipToRTO ffset, devBounds,
361 &clipFP))) { 327 &clipFP))) {
362 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 328 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
363 scissorSpaceIBounds.offset(-clip.origin()); 329 scissorSpaceIBounds.offset(-clip.origin());
364 if (nullptr == devBounds || 330 if (!devBounds || !SkRect::Make(scissorSpaceIBounds).contains(*devBo unds)) {
365 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
366 out->makeScissoredFPBased(clipFP, scissorSpaceIBounds); 331 out->makeScissoredFPBased(clipFP, scissorSpaceIBounds);
367 return true; 332 return true;
368 } 333 }
369 out->makeFPBased(clipFP); 334 out->makeFPBased(clipFP);
370 return true; 335 return true;
371 } 336 }
372 } 337 }
373 338
374 // If the stencil buffer is multisampled we can use it to do everything. 339 // If the stencil buffer is multisampled we can use it to do everything.
375 if (!rt->isStencilBufferMultisampled() && requiresAA) { 340 if (!drawContext->isStencilBufferMultisampled() && requiresAA) {
376 sk_sp<GrTexture> result; 341 sk_sp<GrTexture> result;
377 342
378 // The top-left of the mask corresponds to the top-left corner of the bo unds. 343 // The top-left of the mask corresponds to the top-left corner of the bo unds.
379 SkVector clipToMaskOffset = { 344 SkVector clipToMaskOffset = {
380 SkIntToScalar(-clipSpaceIBounds.fLeft), 345 SkIntToScalar(-clipSpaceIBounds.fLeft),
381 SkIntToScalar(-clipSpaceIBounds.fTop) 346 SkIntToScalar(-clipSpaceIBounds.fTop)
382 }; 347 };
383 348
384 if (UseSWOnlyPath(this->getContext(), pipelineBuilder, rt, clipToMaskOff set, elements)) { 349 if (UseSWOnlyPath(context, pipelineBuilder, drawContext,
350 clipToMaskOffset, elements)) {
385 // The clip geometry is complex enough that it will be more efficien t to create it 351 // The clip geometry is complex enough that it will be more efficien t to create it
386 // entirely in software 352 // entirely in software
387 result = CreateSoftwareClipMask(this->getContext()->textureProvider( ), 353 result = CreateSoftwareClipMask(context->textureProvider(),
388 genID, 354 genID,
389 initialState, 355 initialState,
390 elements, 356 elements,
391 clipToMaskOffset, 357 clipToMaskOffset,
392 clipSpaceIBounds); 358 clipSpaceIBounds);
393 } else { 359 } else {
394 result = CreateAlphaClipMask(this->getContext(), 360 result = CreateAlphaClipMask(context,
395 genID, 361 genID,
396 initialState, 362 initialState,
397 elements, 363 elements,
398 clipToMaskOffset, 364 clipToMaskOffset,
399 clipSpaceIBounds); 365 clipSpaceIBounds);
400 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug 366 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug
401 SkASSERT(result); 367 SkASSERT(result);
402 } 368 }
403 369
404 if (result) { 370 if (result) {
405 // The mask's top left coord should be pinned to the rounded-out top left corner of 371 // The mask's top left coord should be pinned to the rounded-out top left corner of
406 // clipSpace bounds. We determine the mask's position WRT to the ren der target here. 372 // clipSpace bounds. We determine the mask's position WRT to the ren der target here.
407 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; 373 SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
408 rtSpaceMaskBounds.offset(-clip.origin()); 374 rtSpaceMaskBounds.offset(-clip.origin());
409 out->makeFPBased(create_fp_for_mask(result.get(), rtSpaceMaskBounds) ); 375 out->makeFPBased(create_fp_for_mask(result.get(), rtSpaceMaskBounds) );
410 return true; 376 return true;
411 } 377 }
412 // if alpha clip mask creation fails fall through to the non-AA code pat hs 378 // if alpha clip mask creation fails fall through to the non-AA code pat hs
413 } 379 }
414 380
415 // use the stencil clip if we can't represent the clip as a rectangle. 381 // use the stencil clip if we can't represent the clip as a rectangle.
416 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin(); 382 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin();
417 this->createStencilClipMask(rt, 383 CreateStencilClipMask(context,
418 genID, 384 drawContext,
419 initialState, 385 genID,
420 elements, 386 initialState,
421 clipSpaceIBounds, 387 elements,
422 clipSpaceToStencilSpaceOffset); 388 clipSpaceIBounds,
389 clipSpaceToStencilSpaceOffset);
423 390
424 // This must occur after createStencilClipMask. That function may change the scissor. Also, it 391 // This must occur after createStencilClipMask. That function may change the scissor. Also, it
425 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must 392 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must
426 // use both stencil and scissor test to the bounds for the final draw. 393 // use both stencil and scissor test to the bounds for the final draw.
427 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 394 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
428 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); 395 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
429 out->makeScissoredStencil(true, scissorSpaceIBounds); 396 out->makeScissoredStencil(true, scissorSpaceIBounds);
430 return true; 397 return true;
431 } 398 }
432 399
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 569
603 sk_sp<GrTexture> texture(dc->asTexture()); 570 sk_sp<GrTexture> texture(dc->asTexture());
604 SkASSERT(texture); 571 SkASSERT(texture);
605 texture->resourcePriv().setUniqueKey(key); 572 texture->resourcePriv().setUniqueKey(key);
606 return texture; 573 return texture;
607 } 574 }
608 575
609 //////////////////////////////////////////////////////////////////////////////// 576 ////////////////////////////////////////////////////////////////////////////////
610 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device 577 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
611 // (as opposed to canvas) coordinates 578 // (as opposed to canvas) coordinates
612 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, 579 bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
580 GrDrawContext* drawContext,
613 int32_t elementsGenID, 581 int32_t elementsGenID,
614 GrReducedClip::InitialState initia lState, 582 GrReducedClip::InitialState initia lState,
615 const GrReducedClip::ElementList& elements, 583 const GrReducedClip::ElementList& elements,
616 const SkIRect& clipSpaceIBounds, 584 const SkIRect& clipSpaceIBounds,
617 const SkIPoint& clipSpaceToStencil Offset) { 585 const SkIPoint& clipSpaceToStencil Offset) {
618 SkASSERT(rt); 586 SkASSERT(drawContext);
619 587
620 GrStencilAttachment* stencilAttachment = this->resourceProvider()->attachSte ncilAttachment(rt); 588 GrStencilAttachment* stencilAttachment = context->resourceProvider()->attach StencilAttachment(
589 drawContext->accessRenderTar get());
621 if (nullptr == stencilAttachment) { 590 if (nullptr == stencilAttachment) {
622 return false; 591 return false;
623 } 592 }
624 593
594 // TODO: these need to be swapped over to using a StencilAttachmentProxy
625 if (stencilAttachment->mustRenderClip(elementsGenID, clipSpaceIBounds, clipS paceToStencilOffset)) { 595 if (stencilAttachment->mustRenderClip(elementsGenID, clipSpaceIBounds, clipS paceToStencilOffset)) {
626 stencilAttachment->setLastClip(elementsGenID, clipSpaceIBounds, clipSpac eToStencilOffset); 596 stencilAttachment->setLastClip(elementsGenID, clipSpaceIBounds, clipSpac eToStencilOffset);
627 // Set the matrix so that rendered clip elements are transformed from cl ip to stencil space. 597 // Set the matrix so that rendered clip elements are transformed from cl ip to stencil space.
628 SkVector translate = { 598 SkVector translate = {
629 SkIntToScalar(clipSpaceToStencilOffset.fX), 599 SkIntToScalar(clipSpaceToStencilOffset.fX),
630 SkIntToScalar(clipSpaceToStencilOffset.fY) 600 SkIntToScalar(clipSpaceToStencilOffset.fY)
631 }; 601 };
632 SkMatrix viewMatrix; 602 SkMatrix viewMatrix;
633 viewMatrix.setTranslate(translate); 603 viewMatrix.setTranslate(translate);
634 604
635 // We set the current clip to the bounds so that our recursive draws are scissored to them. 605 // We set the current clip to the bounds so that our recursive draws are scissored to them.
636 SkIRect stencilSpaceIBounds(clipSpaceIBounds); 606 SkIRect stencilSpaceIBounds(clipSpaceIBounds);
637 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); 607 stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
638 GrFixedClip clip(stencilSpaceIBounds); 608 GrFixedClip clip(stencilSpaceIBounds);
639 609
640 fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds, 610 drawContext->drawContextPriv().clearStencilClip(
641 GrReducedClip::kAllIn_InitialState == initialState, rt); 611 stencilSpaceIBounds,
612 GrReducedClip::kAllIn_InitialState = = initialState);
642 613
643 // walk through each clip element and perform its set op 614 // walk through each clip element and perform its set op
644 // with the existing clip. 615 // with the existing clip.
645 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) { 616 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) {
646 const Element* element = iter.get(); 617 const Element* element = iter.get();
647 618
648 GrPipelineBuilder pipelineBuilder;
649 pipelineBuilder.setRenderTarget(rt);
650
651 pipelineBuilder.setDisableColorXPFactory();
652
653 // if the target is MSAA then we want MSAA enabled when the clip is soft
654 if (rt->isStencilBufferMultisampled()) {
655 pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, e lement->isAA());
656 }
657
658 bool fillInverted = false; 619 bool fillInverted = false;
659 // enabled at bottom of loop 620 // enabled at bottom of loop
660 clip.enableStencilClip(false); 621 clip.enableStencilClip(false);
661 622
662 // This will be used to determine whether the clip shape can be rend ered into the 623 // This will be used to determine whether the clip shape can be rend ered into the
663 // stencil with arbitrary stencil settings. 624 // stencil with arbitrary stencil settings.
664 GrPathRenderer::StencilSupport stencilSupport; 625 GrPathRenderer::StencilSupport stencilSupport;
665 626
666 SkRegion::Op op = element->getOp(); 627 SkRegion::Op op = element->getOp();
667 628
668 GrPathRenderer* pr = nullptr; 629 GrPathRenderer* pr = nullptr;
669 SkPath clipPath; 630 SkPath clipPath;
670 if (Element::kRect_Type == element->getType()) { 631 if (Element::kRect_Type == element->getType()) {
671 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; 632 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
672 fillInverted = false; 633 fillInverted = false;
673 } else { 634 } else {
674 element->asPath(&clipPath); 635 element->asPath(&clipPath);
675 fillInverted = clipPath.isInverseFillType(); 636 fillInverted = clipPath.isInverseFillType();
676 if (fillInverted) { 637 if (fillInverted) {
677 clipPath.toggleInverseFillType(); 638 clipPath.toggleInverseFillType();
678 } 639 }
679 640
680 SkASSERT(!pipelineBuilder.hasUserStencilSettings());
681
682 GrPathRenderer::CanDrawPathArgs canDrawArgs; 641 GrPathRenderer::CanDrawPathArgs canDrawArgs;
683 canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps (); 642 canDrawArgs.fShaderCaps = context->caps()->shaderCaps();
684 canDrawArgs.fViewMatrix = &viewMatrix; 643 canDrawArgs.fViewMatrix = &viewMatrix;
685 canDrawArgs.fPath = &clipPath; 644 canDrawArgs.fPath = &clipPath;
686 canDrawArgs.fStyle = &GrStyle::SimpleFill(); 645 canDrawArgs.fStyle = &GrStyle::SimpleFill();
687 canDrawArgs.fAntiAlias = false; 646 canDrawArgs.fAntiAlias = false;
688 canDrawArgs.fHasUserStencilSettings = pipelineBuilder.hasUserSte ncilSettings(); 647 canDrawArgs.fHasUserStencilSettings = false;
689 canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampl ed(); 648 canDrawArgs.fIsStencilBufferMSAA = drawContext->isStencilBufferM ultisampled();
690 649
691 pr = this->getContext()->drawingManager()->getPathRenderer(canDr awArgs, false, 650 pr = context->drawingManager()->getPathRenderer(canDrawArgs, fal se,
692 GrPat hRendererChain::kStencilOnly_DrawType, 651 GrPathRendererCh ain::kStencilOnly_DrawType,
693 &sten cilSupport); 652 &stencilSupport) ;
694 if (nullptr == pr) { 653 if (!pr) {
695 return false; 654 return false;
696 } 655 }
697 } 656 }
698 657
699 bool canRenderDirectToStencil = 658 bool canRenderDirectToStencil =
700 GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport; 659 GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport;
701 bool drawDirectToClip; // Given the renderer, the element, 660 bool drawDirectToClip; // Given the renderer, the element,
702 // fill rule, and set operation should 661 // fill rule, and set operation should
703 // we render the element directly to 662 // we render the element directly to
704 // stencil bit used for clipping. 663 // stencil bit used for clipping.
705 GrUserStencilSettings const* const* stencilPasses = 664 GrUserStencilSettings const* const* stencilPasses =
706 GrStencilSettings::GetClipPasses(op, canRenderDirectToStencil, f illInverted, 665 GrStencilSettings::GetClipPasses(op, canRenderDirectToStencil, f illInverted,
707 &drawDirectToClip); 666 &drawDirectToClip);
708 667
709 // draw the element to the client stencil bits if necessary 668 // draw the element to the client stencil bits if necessary
710 if (!drawDirectToClip) { 669 if (!drawDirectToClip) {
711 static constexpr GrUserStencilSettings kDrawToStencil( 670 static constexpr GrUserStencilSettings kDrawToStencil(
712 GrUserStencilSettings::StaticInit< 671 GrUserStencilSettings::StaticInit<
713 0x0000, 672 0x0000,
714 GrUserStencilTest::kAlways, 673 GrUserStencilTest::kAlways,
715 0xffff, 674 0xffff,
716 GrUserStencilOp::kIncMaybeClamp, 675 GrUserStencilOp::kIncMaybeClamp,
717 GrUserStencilOp::kIncMaybeClamp, 676 GrUserStencilOp::kIncMaybeClamp,
718 0xffff>() 677 0xffff>()
719 ); 678 );
720 if (Element::kRect_Type == element->getType()) { 679 if (Element::kRect_Type == element->getType()) {
721 pipelineBuilder.setUserStencil(&kDrawToStencil); 680 DrawNonAARect(drawContext, clip, viewMatrix,
722 681 element->getRect(), element->isAA(), &kDrawToS tencil);
723 draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor _WHITE, viewMatrix,
724 element->getRect());
725 } else { 682 } else {
726 if (!clipPath.isEmpty()) { 683 if (!clipPath.isEmpty()) {
727 if (canRenderDirectToStencil) { 684 if (canRenderDirectToStencil) {
728 pipelineBuilder.setUserStencil(&kDrawToStencil); 685 GrPaint paint;
686 paint.setXPFactory(GrDisableColorXPFactory::Create() );
bungeman-skia 2016/06/03 23:57:03 leak
687 paint.setAntiAlias(element->isAA());
729 688
730 GrPathRenderer::DrawPathArgs args; 689 GrPathRenderer::DrawPathArgs args;
731 args.fTarget = fDrawTarget; 690 args.fResourceProvider = context->resourceProvider() ;
732 args.fResourceProvider = this->getContext()->resourc eProvider(); 691 args.fPaint = &paint;
733 args.fPipelineBuilder = &pipelineBuilder; 692 args.fUserStencilSettings = &kDrawToStencil;
693 args.fDrawContext = drawContext;
734 args.fClip = &clip; 694 args.fClip = &clip;
735 args.fColor = GrColor_WHITE; 695 args.fColor = GrColor_WHITE;
736 args.fViewMatrix = &viewMatrix; 696 args.fViewMatrix = &viewMatrix;
737 args.fPath = &clipPath; 697 args.fPath = &clipPath;
738 args.fStyle = &GrStyle::SimpleFill(); 698 args.fStyle = &GrStyle::SimpleFill();
739 args.fAntiAlias = false; 699 args.fAntiAlias = false;
740 args.fGammaCorrect = false; 700 args.fGammaCorrect = false;
741 pr->drawPath(args); 701 pr->drawPath(args);
742 } else { 702 } else {
743 GrPathRenderer::StencilPathArgs args; 703 GrPathRenderer::StencilPathArgs args;
744 args.fTarget = fDrawTarget; 704 args.fResourceProvider = context->resourceProvider() ;
745 args.fResourceProvider = this->getContext()->resourc eProvider(); 705 args.fDrawContext = drawContext;
746 args.fPipelineBuilder = &pipelineBuilder;
747 args.fClip = &clip; 706 args.fClip = &clip;
748 args.fViewMatrix = &viewMatrix; 707 args.fViewMatrix = &viewMatrix;
749 args.fPath = &clipPath; 708 args.fPath = &clipPath;
709 args.fIsAA = element->isAA();
750 pr->stencilPath(args); 710 pr->stencilPath(args);
751 } 711 }
752 } 712 }
753 } 713 }
754 } 714 }
755 715
756 // now we modify the clip bit by rendering either the clip 716 // now we modify the clip bit by rendering either the clip
757 // element directly or a bounding rect of the entire clip. 717 // element directly or a bounding rect of the entire clip.
758 clip.enableStencilClip(true); 718 clip.enableStencilClip(true);
759 for (GrUserStencilSettings const* const* pass = stencilPasses; *pass ; ++pass) { 719 for (GrUserStencilSettings const* const* pass = stencilPasses; *pass ; ++pass) {
760 pipelineBuilder.setUserStencil(*pass);
761 720
762 if (drawDirectToClip) { 721 if (drawDirectToClip) {
763 if (Element::kRect_Type == element->getType()) { 722 if (Element::kRect_Type == element->getType()) {
764 draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrC olor_WHITE, 723 DrawNonAARect(drawContext, clip,
765 viewMatrix, element->getRect()); 724 viewMatrix, element->getRect(), element->i sAA(), *pass);
766 } else { 725 } else {
726 GrPaint paint;
727 paint.setXPFactory(GrDisableColorXPFactory::Create());
bungeman-skia 2016/06/03 23:57:03 leak
728 paint.setAntiAlias(element->isAA());
729
767 GrPathRenderer::DrawPathArgs args; 730 GrPathRenderer::DrawPathArgs args;
768 args.fTarget = fDrawTarget; 731 args.fResourceProvider = context->resourceProvider();
769 args.fResourceProvider = this->getContext()->resourcePro vider(); 732 args.fPaint = &paint;
770 args.fPipelineBuilder = &pipelineBuilder; 733 args.fUserStencilSettings = *pass;
734 args.fDrawContext = drawContext;
771 args.fClip = &clip; 735 args.fClip = &clip;
772 args.fColor = GrColor_WHITE; 736 args.fColor = GrColor_WHITE;
773 args.fViewMatrix = &viewMatrix; 737 args.fViewMatrix = &viewMatrix;
774 args.fPath = &clipPath; 738 args.fPath = &clipPath;
775 args.fStyle = &GrStyle::SimpleFill(); 739 args.fStyle = &GrStyle::SimpleFill();
776 args.fAntiAlias = false; 740 args.fAntiAlias = false;
777 args.fGammaCorrect = false; 741 args.fGammaCorrect = false;
778 pr->drawPath(args); 742 pr->drawPath(args);
779 } 743 }
780 } else { 744 } else {
781 // The view matrix is setup to do clip space -> stencil spac e translation, so 745 // The view matrix is setup to do clip space -> stencil spac e translation, so
782 // draw rect in clip space. 746 // draw rect in clip space.
783 draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor _WHITE, viewMatrix, 747 DrawNonAARect(drawContext, clip, viewMatrix,
784 SkRect::Make(clipSpaceIBounds)); 748 SkRect::Make(clipSpaceIBounds), false, *pass);
785 } 749 }
786 } 750 }
787 } 751 }
788 } 752 }
789 return true; 753 return true;
790 } 754 }
791 755
792 //////////////////////////////////////////////////////////////////////////////// 756 ////////////////////////////////////////////////////////////////////////////////
793 sk_sp<GrTexture> GrClipMaskManager::CreateSoftwareClipMask( 757 sk_sp<GrTexture> GrClipMaskManager::CreateSoftwareClipMask(
794 GrTextureProvider* texProvid er, 758 GrTextureProvider* texProvid er,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); 823 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc));
860 if (!result) { 824 if (!result) {
861 return nullptr; 825 return nullptr;
862 } 826 }
863 result->resourcePriv().setUniqueKey(key); 827 result->resourcePriv().setUniqueKey(key);
864 828
865 helper.toTexture(result.get()); 829 helper.toTexture(result.get());
866 830
867 return result; 831 return result;
868 } 832 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698