OLD | NEW |
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" |
(...skipping 13 matching lines...) Expand all Loading... |
24 #include "effects/GrConvexPolyEffect.h" | 24 #include "effects/GrConvexPolyEffect.h" |
25 #include "effects/GrPorterDuffXferProcessor.h" | 25 #include "effects/GrPorterDuffXferProcessor.h" |
26 #include "effects/GrRRectEffect.h" | 26 #include "effects/GrRRectEffect.h" |
27 #include "effects/GrTextureDomain.h" | 27 #include "effects/GrTextureDomain.h" |
28 | 28 |
29 typedef SkClipStack::Element Element; | 29 typedef SkClipStack::Element Element; |
30 | 30 |
31 //////////////////////////////////////////////////////////////////////////////// | 31 //////////////////////////////////////////////////////////////////////////////// |
32 // set up the draw state to enable the aa clipping mask. Besides setting up the | 32 // set up the draw state to enable the aa clipping mask. Besides setting up the |
33 // stage matrix this also alters the vertex layout | 33 // stage matrix this also alters the vertex layout |
34 static const GrFragmentProcessor* create_fp_for_mask(GrTexture* result, const Sk
IRect &devBound) { | 34 static sk_sp<const GrFragmentProcessor> create_fp_for_mask(GrTexture* result, |
| 35 const SkIRect &devBou
nd) { |
35 SkMatrix mat; | 36 SkMatrix mat; |
36 // We use device coords to compute the texture coordinates. We set our matri
x to be a | 37 // We use device coords to compute the texture coordinates. We set our matri
x to be a |
37 // translation to the devBound, and then a scaling matrix to normalized coor
ds. | 38 // translation to the devBound, and then a scaling matrix to normalized coor
ds. |
38 mat.setIDiv(result->width(), result->height()); | 39 mat.setIDiv(result->width(), result->height()); |
39 mat.preTranslate(SkIntToScalar(-devBound.fLeft), | 40 mat.preTranslate(SkIntToScalar(-devBound.fLeft), |
40 SkIntToScalar(-devBound.fTop)); | 41 SkIntToScalar(-devBound.fTop)); |
41 | 42 |
42 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); | 43 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); |
43 return GrTextureDomainEffect::Create(result, | 44 return sk_sp<const GrFragmentProcessor>(GrTextureDomainEffect::Create( |
| 45 result, |
44 mat, | 46 mat, |
45 GrTextureDomain::MakeTexelDomain(result
, domainTexels), | 47 GrTextureDomain::MakeTexelDomain(result
, domainTexels), |
46 GrTextureDomain::kDecal_Mode, | 48 GrTextureDomain::kDecal_Mode, |
47 GrTextureParams::kNone_FilterMode, | 49 GrTextureParams::kNone_FilterMode, |
48 kDevice_GrCoordSet); | 50 kDevice_GrCoordSet)); |
49 } | 51 } |
50 | 52 |
51 static void draw_non_aa_rect(GrDrawTarget* drawTarget, | 53 static void draw_non_aa_rect(GrDrawTarget* drawTarget, |
52 const GrPipelineBuilder& pipelineBuilder, | 54 const GrPipelineBuilder& pipelineBuilder, |
53 const GrClip& clip, | 55 const GrClip& clip, |
54 GrColor color, | 56 GrColor color, |
55 const SkMatrix& viewMatrix, | 57 const SkMatrix& viewMatrix, |
56 const SkRect& rect) { | 58 const SkRect& rect) { |
57 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, v
iewMatrix, rect, | 59 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, v
iewMatrix, rect, |
58 nullptr,
nullptr)); | 60 nullptr,
nullptr)); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 return true; | 181 return true; |
180 } | 182 } |
181 } | 183 } |
182 return false; | 184 return false; |
183 } | 185 } |
184 | 186 |
185 bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis
t& elements, | 187 bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis
t& elements, |
186 bool abortIfAA, | 188 bool abortIfAA, |
187 SkVector& clipToRTOffset, | 189 SkVector& clipToRTOffset, |
188 const SkRect* drawBounds, | 190 const SkRect* drawBounds, |
189 const GrFragmentProcessor** res
ultFP) { | 191 sk_sp<const GrFragmentProcessor
>* resultFP) { |
190 SkRect boundsInClipSpace; | 192 SkRect boundsInClipSpace; |
191 if (drawBounds) { | 193 if (drawBounds) { |
192 boundsInClipSpace = *drawBounds; | 194 boundsInClipSpace = *drawBounds; |
193 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); | 195 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); |
194 } | 196 } |
195 SkASSERT(elements.count() <= kMaxAnalyticElements); | 197 SkASSERT(elements.count() <= kMaxAnalyticElements); |
196 const GrFragmentProcessor* fps[kMaxAnalyticElements]; | 198 const GrFragmentProcessor* fps[kMaxAnalyticElements]; |
197 for (int i = 0; i < kMaxAnalyticElements; ++i) { | 199 for (int i = 0; i < kMaxAnalyticElements; ++i) { |
198 fps[i] = nullptr; | 200 fps[i] = nullptr; |
199 } | 201 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 failed = true; | 266 failed = true; |
265 break; | 267 break; |
266 } | 268 } |
267 fpCnt++; | 269 fpCnt++; |
268 } | 270 } |
269 iter.next(); | 271 iter.next(); |
270 } | 272 } |
271 | 273 |
272 *resultFP = nullptr; | 274 *resultFP = nullptr; |
273 if (!failed && fpCnt) { | 275 if (!failed && fpCnt) { |
274 *resultFP = GrFragmentProcessor::RunInSeries(fps, fpCnt); | 276 resultFP->reset(GrFragmentProcessor::RunInSeries(fps, fpCnt)); |
275 } | 277 } |
276 for (int i = 0; i < fpCnt; ++i) { | 278 for (int i = 0; i < fpCnt; ++i) { |
277 fps[i]->unref(); | 279 fps[i]->unref(); |
278 } | 280 } |
279 return !failed; | 281 return !failed; |
280 } | 282 } |
281 | 283 |
282 //////////////////////////////////////////////////////////////////////////////// | 284 //////////////////////////////////////////////////////////////////////////////// |
283 // sort out what kind of clip mask needs to be created: alpha, stencil, | 285 // sort out what kind of clip mask needs to be created: alpha, stencil, |
284 // scissor, or entirely software | 286 // scissor, or entirely software |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 // When there are multiple samples we want to do per-sample clipping, no
t compute a | 347 // When there are multiple samples we want to do per-sample clipping, no
t compute a |
346 // fractional pixel coverage. | 348 // fractional pixel coverage. |
347 bool disallowAnalyticAA = rt->isStencilBufferMultisampled(); | 349 bool disallowAnalyticAA = rt->isStencilBufferMultisampled(); |
348 if (disallowAnalyticAA && !rt->numColorSamples()) { | 350 if (disallowAnalyticAA && !rt->numColorSamples()) { |
349 // With a single color sample, any coverage info is lost from color
once it hits the | 351 // With a single color sample, any coverage info is lost from color
once it hits the |
350 // color buffer anyway, so we may as well use coverage AA if nothing
else in the pipe | 352 // color buffer anyway, so we may as well use coverage AA if nothing
else in the pipe |
351 // is multisampled. | 353 // is multisampled. |
352 disallowAnalyticAA = pipelineBuilder.isHWAntialias() || | 354 disallowAnalyticAA = pipelineBuilder.isHWAntialias() || |
353 pipelineBuilder.hasUserStencilSettings(); | 355 pipelineBuilder.hasUserStencilSettings(); |
354 } | 356 } |
355 const GrFragmentProcessor* clipFP = nullptr; | 357 sk_sp<const GrFragmentProcessor> clipFP; |
356 if (elements.isEmpty() || | 358 if (elements.isEmpty() || |
357 (requiresAA && | 359 (requiresAA && |
358 this->getAnalyticClipProcessor(elements, disallowAnalyticAA, clipTo
RTOffset, devBounds, | 360 this->getAnalyticClipProcessor(elements, disallowAnalyticAA, clipTo
RTOffset, devBounds, |
359 &clipFP))) { | 361 &clipFP))) { |
360 SkIRect scissorSpaceIBounds(clipSpaceIBounds); | 362 SkIRect scissorSpaceIBounds(clipSpaceIBounds); |
361 scissorSpaceIBounds.offset(-clip.origin()); | 363 scissorSpaceIBounds.offset(-clip.origin()); |
362 if (nullptr == devBounds || | 364 if (nullptr == devBounds || |
363 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { | 365 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { |
364 out->fScissorState.set(scissorSpaceIBounds); | 366 out->makeScissoredFPBased(clipFP, scissorSpaceIBounds); |
| 367 return true; |
365 } | 368 } |
366 out->fClipCoverageFP.reset(clipFP); | 369 out->makeFPBased(clipFP); |
367 return true; | 370 return true; |
368 } | 371 } |
369 } | 372 } |
370 | 373 |
371 // If the stencil buffer is multisampled we can use it to do everything. | 374 // If the stencil buffer is multisampled we can use it to do everything. |
372 if (!rt->isStencilBufferMultisampled() && requiresAA) { | 375 if (!rt->isStencilBufferMultisampled() && requiresAA) { |
373 sk_sp<GrTexture> result; | 376 sk_sp<GrTexture> result; |
374 | 377 |
375 // The top-left of the mask corresponds to the top-left corner of the bo
unds. | 378 // The top-left of the mask corresponds to the top-left corner of the bo
unds. |
376 SkVector clipToMaskOffset = { | 379 SkVector clipToMaskOffset = { |
(...skipping 19 matching lines...) Expand all Loading... |
396 clipSpaceIBounds); | 399 clipSpaceIBounds); |
397 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug | 400 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug |
398 SkASSERT(result); | 401 SkASSERT(result); |
399 } | 402 } |
400 | 403 |
401 if (result) { | 404 if (result) { |
402 // The mask's top left coord should be pinned to the rounded-out top
left corner of | 405 // The mask's top left coord should be pinned to the rounded-out top
left corner of |
403 // clipSpace bounds. We determine the mask's position WRT to the ren
der target here. | 406 // clipSpace bounds. We determine the mask's position WRT to the ren
der target here. |
404 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; | 407 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; |
405 rtSpaceMaskBounds.offset(-clip.origin()); | 408 rtSpaceMaskBounds.offset(-clip.origin()); |
406 out->fClipCoverageFP.reset(create_fp_for_mask(result.get(), rtSpaceM
askBounds)); | 409 out->makeFPBased(create_fp_for_mask(result.get(), rtSpaceMaskBounds)
); |
407 return true; | 410 return true; |
408 } | 411 } |
409 // if alpha clip mask creation fails fall through to the non-AA code pat
hs | 412 // if alpha clip mask creation fails fall through to the non-AA code pat
hs |
410 } | 413 } |
411 | 414 |
412 // use the stencil clip if we can't represent the clip as a rectangle. | 415 // use the stencil clip if we can't represent the clip as a rectangle. |
413 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin(); | 416 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin(); |
414 this->createStencilClipMask(rt, | 417 this->createStencilClipMask(rt, |
415 genID, | 418 genID, |
416 initialState, | 419 initialState, |
417 elements, | 420 elements, |
418 clipSpaceIBounds, | 421 clipSpaceIBounds, |
419 clipSpaceToStencilSpaceOffset); | 422 clipSpaceToStencilSpaceOffset); |
420 | 423 |
421 // This must occur after createStencilClipMask. That function may change the
scissor. Also, it | 424 // This must occur after createStencilClipMask. That function may change the
scissor. Also, it |
422 // only guarantees that the stencil mask is correct within the bounds it was
passed, so we must | 425 // only guarantees that the stencil mask is correct within the bounds it was
passed, so we must |
423 // use both stencil and scissor test to the bounds for the final draw. | 426 // use both stencil and scissor test to the bounds for the final draw. |
424 SkIRect scissorSpaceIBounds(clipSpaceIBounds); | 427 SkIRect scissorSpaceIBounds(clipSpaceIBounds); |
425 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); | 428 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); |
426 out->fScissorState.set(scissorSpaceIBounds); | 429 out->makeScissoredStencil(true, scissorSpaceIBounds); |
427 out->fHasStencilClip = true; | |
428 return true; | 430 return true; |
429 } | 431 } |
430 | 432 |
431 static bool stencil_element(GrDrawContext* dc, | 433 static bool stencil_element(GrDrawContext* dc, |
432 const GrFixedClip& clip, | 434 const GrFixedClip& clip, |
433 const GrUserStencilSettings* ss, | 435 const GrUserStencilSettings* ss, |
434 const SkMatrix& viewMatrix, | 436 const SkMatrix& viewMatrix, |
435 const SkClipStack::Element* element) { | 437 const SkClipStack::Element* element) { |
436 | 438 |
437 // TODO: Draw rrects directly here. | 439 // TODO: Draw rrects directly here. |
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 sk_sp<GrTexture> result(context->resourceProvider()->createApproxTexture(des
c, 0)); | 860 sk_sp<GrTexture> result(context->resourceProvider()->createApproxTexture(des
c, 0)); |
859 if (!result) { | 861 if (!result) { |
860 return nullptr; | 862 return nullptr; |
861 } | 863 } |
862 result->resourcePriv().setUniqueKey(key); | 864 result->resourcePriv().setUniqueKey(key); |
863 | 865 |
864 helper.toTexture(result.get()); | 866 helper.toTexture(result.get()); |
865 | 867 |
866 return result; | 868 return result; |
867 } | 869 } |
OLD | NEW |