SkSpotShadowMaskFilter.cpp revision 4a24da5ceccbbd5eb91c75ce680c42191a5342d0
13c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth/* 23c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth * Copyright 2016 Google Inc. 33c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth * 43c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth * Use of this source code is governed by a BSD-style license that can be 53c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth * found in the LICENSE file. 63c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth */ 73c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 83c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "SkShadowMaskFilter.h" 93c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "SkReadBuffer.h" 103c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "SkStringUtils.h" 113c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "SkWriteBuffer.h" 123c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 133c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#if SK_SUPPORT_GPU 143c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "GrContext.h" 153c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "GrRenderTargetContext.h" 163c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "GrFragmentProcessor.h" 173c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "GrInvariantOutput.h" 183c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "GrStyle.h" 193c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "GrTexture.h" 204a24da5ceccbbd5eb91c75ce680c42191a5342d0Robert Phillips#include "GrTextureProxy.h" 213c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "glsl/GrGLSLFragmentProcessor.h" 223c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "glsl/GrGLSLFragmentShaderBuilder.h" 233c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "glsl/GrGLSLProgramDataManager.h" 243c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "glsl/GrGLSLUniformHandler.h" 253c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#include "SkStrokeRec.h" 263c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#endif 273c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 283c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verthclass SkShadowMaskFilterImpl : public SkMaskFilter { 293c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verthpublic: 303c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkShadowMaskFilterImpl(SkScalar occluderHeight, const SkPoint3& lightPos, SkScalar lightRadius, 313c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar ambientAlpha, SkScalar spotAlpha, uint32_t flags); 323c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 333c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // overrides from SkMaskFilter 343c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkMask::Format getFormat() const override; 353c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, 363c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkIPoint* margin) const override; 373c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 383c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#if SK_SUPPORT_GPU 393c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth bool canFilterMaskGPU(const SkRRect& devRRect, 403c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkIRect& clipBounds, 413c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkMatrix& ctm, 423c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkRect* maskRect) const override; 433c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth bool directFilterMaskGPU(GrTextureProvider* texProvider, 443c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth GrRenderTargetContext* drawContext, 453c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth GrPaint* grp, 463c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const GrClip&, 473c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkMatrix& viewMatrix, 483c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkStrokeRec& strokeRec, 493c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkPath& path) const override; 503c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth bool directFilterRRectMaskGPU(GrContext*, 513c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth GrRenderTargetContext* drawContext, 523c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth GrPaint* grp, 533c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const GrClip&, 543c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkMatrix& viewMatrix, 553c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkStrokeRec& strokeRec, 563c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkRRect& rrect, 573c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkRRect& devRRect) const override; 584a24da5ceccbbd5eb91c75ce680c42191a5342d0Robert Phillips sk_sp<GrTextureProxy> filterMaskGPU(GrContext*, 594a24da5ceccbbd5eb91c75ce680c42191a5342d0Robert Phillips sk_sp<GrTextureProxy> srcProxy, 604a24da5ceccbbd5eb91c75ce680c42191a5342d0Robert Phillips const SkMatrix& ctm, 614a24da5ceccbbd5eb91c75ce680c42191a5342d0Robert Phillips const SkIRect& maskRect) const override; 623c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#endif 633c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 643c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth void computeFastBounds(const SkRect&, SkRect*) const override; 653c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 663c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SK_TO_STRING_OVERRIDE() 673c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkShadowMaskFilterImpl) 683c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 693c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verthprivate: 703c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar fOccluderHeight; 713c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkPoint3 fLightPos; 723c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar fLightRadius; 733c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar fAmbientAlpha; 743c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar fSpotAlpha; 753c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth uint32_t fFlags; 763c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 773c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkShadowMaskFilterImpl(SkReadBuffer&); 783c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth void flatten(SkWriteBuffer&) const override; 793c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 803c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth friend class SkShadowMaskFilter; 813c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 823c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth typedef SkMaskFilter INHERITED; 833c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth}; 843c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 853c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verthsk_sp<SkMaskFilter> SkShadowMaskFilter::Make(SkScalar occluderHeight, const SkPoint3& lightPos, 863c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar lightRadius, SkScalar ambientAlpha, 873c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar spotAlpha, uint32_t flags) { 883c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // add some param checks here for early exit 893c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 903c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth return sk_sp<SkMaskFilter>(new SkShadowMaskFilterImpl(occluderHeight, lightPos, lightRadius, 913c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth ambientAlpha, spotAlpha, flags)); 923c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth} 933c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 943c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth/////////////////////////////////////////////////////////////////////////////////////////////////// 953c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 963c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van VerthSkShadowMaskFilterImpl::SkShadowMaskFilterImpl(SkScalar occluderHeight, const SkPoint3& lightPos, 973c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar lightRadius, SkScalar ambientAlpha, 983c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar spotAlpha, uint32_t flags) 993c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth : fOccluderHeight(occluderHeight) 1003c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth , fLightPos(lightPos) 1013c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth , fLightRadius(lightRadius) 1023c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth , fAmbientAlpha(ambientAlpha) 1033c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth , fSpotAlpha(spotAlpha) 1043c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth , fFlags(flags) { 1053c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkASSERT(fOccluderHeight > 0); 1063c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkASSERT(fLightPos.z() > 0 && fLightPos.z() > fOccluderHeight); 1073c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkASSERT(fLightRadius > 0); 1083c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkASSERT(fAmbientAlpha >= 0); 1093c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkASSERT(fSpotAlpha >= 0); 1103c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth} 1113c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 1123c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van VerthSkMask::Format SkShadowMaskFilterImpl::getFormat() const { 1133c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth return SkMask::kA8_Format; 1143c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth} 1153c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 1163c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verthbool SkShadowMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src, 1173c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkMatrix& matrix, 1183c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkIPoint* margin) const { 1193c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // TODO something 1203c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth return false; 1213c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth} 1223c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 1233c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verthvoid SkShadowMaskFilterImpl::computeFastBounds(const SkRect& src, SkRect* dst) const { 1243c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // TODO compute based on ambient + spot data 1253c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth dst->set(src.fLeft, src.fTop, src.fRight, src.fBottom); 1263c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth} 1273c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 1283c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verthsk_sp<SkFlattenable> SkShadowMaskFilterImpl::CreateProc(SkReadBuffer& buffer) { 1293c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkScalar occluderHeight = buffer.readScalar(); 1303c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkScalar lightX = buffer.readScalar(); 1313c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkScalar lightY = buffer.readScalar(); 1323c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkScalar lightZ = buffer.readScalar(); 1333c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkPoint3 lightPos = SkPoint3::Make(lightX, lightY, lightZ); 1343c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkScalar lightRadius = buffer.readScalar(); 1353c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkScalar ambientAlpha = buffer.readScalar(); 1363c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkScalar spotAlpha = buffer.readScalar(); 1373c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const uint32_t flags = buffer.readUInt(); 1383c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 1393c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth return SkShadowMaskFilter::Make(occluderHeight, lightPos, lightRadius, 1403c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth ambientAlpha, spotAlpha, flags); 1413c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth} 1423c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 1433c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verthvoid SkShadowMaskFilterImpl::flatten(SkWriteBuffer& buffer) const { 1443c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth buffer.writeScalar(fOccluderHeight); 1453c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth buffer.writeScalar(fLightPos.fX); 1463c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth buffer.writeScalar(fLightPos.fY); 1473c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth buffer.writeScalar(fLightPos.fZ); 1483c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth buffer.writeScalar(fLightRadius); 1493c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth buffer.writeScalar(fAmbientAlpha); 1503c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth buffer.writeScalar(fSpotAlpha); 1513c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth buffer.writeUInt(fFlags); 1523c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth} 1533c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 1543c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#if SK_SUPPORT_GPU 1553c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 1563c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth/////////////////////////////////////////////////////////////////////////////////////////////////// 1573c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 1583c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verthbool SkShadowMaskFilterImpl::canFilterMaskGPU(const SkRRect& devRRect, 1593c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkIRect& clipBounds, 1603c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkMatrix& ctm, 1613c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkRect* maskRect) const { 1623c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // TODO 1633c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth *maskRect = devRRect.rect(); 1643c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth return true; 1653c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth} 1663c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 1673c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verthbool SkShadowMaskFilterImpl::directFilterMaskGPU(GrTextureProvider* texProvider, 1683c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth GrRenderTargetContext* drawContext, 1693c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth GrPaint* grp, 1703c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const GrClip& clip, 1713c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkMatrix& viewMatrix, 1723c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkStrokeRec& strokeRec, 1733c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkPath& path) const { 1743c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkASSERT(drawContext); 1753c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // TODO: this will not handle local coordinates properly 1763c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 1773c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // if circle 1783c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // TODO: switch to SkScalarNearlyEqual when either oval renderer is updated or we 1793c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // have our own GeometryProc. 1803c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth if (path.isOval(nullptr) && path.getBounds().width() == path.getBounds().height()) { 1813c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkRRect rrect = SkRRect::MakeOval(path.getBounds()); 1823c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth return this->directFilterRRectMaskGPU(nullptr, drawContext, grp, clip, SkMatrix::I(), 1833c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth strokeRec, rrect, rrect); 1843c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } else if (path.isRect(nullptr)) { 1853c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkRRect rrect = SkRRect::MakeRect(path.getBounds()); 1863c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth return this->directFilterRRectMaskGPU(nullptr, drawContext, grp, clip, SkMatrix::I(), 1873c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth strokeRec, rrect, rrect); 1883c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } 1893c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 1903c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // TODO 1913c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth return false; 1923c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth} 1933c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 1943c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verthbool SkShadowMaskFilterImpl::directFilterRRectMaskGPU(GrContext*, 195c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth GrRenderTargetContext* renderTargetContext, 1963c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth GrPaint* grp, 1973c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const GrClip& clip, 1983c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkMatrix& viewMatrix, 1993c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkStrokeRec& strokeRec, 2003c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkRRect& rrect, 2013c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkRRect& devRRect) const { 2023c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // It's likely the caller has already done these checks, but we have to be sure. 2033c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // TODO: support analytic blurring of general rrect 2043c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2053c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // Fast path only supports filled rrects for now. 2063c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // TODO: fill and stroke as well. 2073c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth if (SkStrokeRec::kFill_Style != strokeRec.getStyle()) { 2083c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth return false; 2093c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } 2103c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // Fast path only supports simple rrects with circular corners. 2113c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkASSERT(devRRect.allCornersCircular()); 2123c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth if (!rrect.isRect() && !rrect.isOval() && !rrect.isSimple()) { 2133c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth return false; 2143c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } 2153c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // Fast path only supports uniform scale. 2163c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar scaleFactors[2]; 2173c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth if (!viewMatrix.getMinMaxScales(scaleFactors)) { 2183c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // matrix is degenerate 2193c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth return false; 2203c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } 2213c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth if (scaleFactors[0] != scaleFactors[1]) { 2223c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth return false; 2233c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } 2243c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar scaleFactor = scaleFactors[0]; 2253c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2263c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // For all of these, we need to ensure we have a rrect with radius >= 0.5f in device space 2273c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkScalar minRadius = 0.5f / scaleFactor; 2283c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth bool isRect = rrect.getSimpleRadii().fX <= minRadius; 2293c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2303c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // TODO: take flags into account when generating shadow data 2313c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2323c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth if (fAmbientAlpha > 0.0f) { 2333c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth static const float kHeightFactor = 1.0f / 128.0f; 2343c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth static const float kGeomFactor = 64.0f; 2353c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2363c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar srcSpaceAmbientRadius = fOccluderHeight * kHeightFactor * kGeomFactor; 2373c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const float umbraAlpha = 1.0f / (1.0f + SkTMax(fOccluderHeight * kHeightFactor, 0.0f)); 2383c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkScalar ambientOffset = srcSpaceAmbientRadius * umbraAlpha; 2393c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2403c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // For the ambient rrect, we inset the offset rect by half the srcSpaceAmbientRadius 2413c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // to get our stroke shape. 2423c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar ambientPathOutset = SkTMax(ambientOffset - srcSpaceAmbientRadius * 0.5f, 2433c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth minRadius); 2443c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2453c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkRRect ambientRRect; 2463c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth if (isRect) { 2473c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkRect temp = rrect.rect().makeOutset(ambientPathOutset, ambientPathOutset); 2483c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth ambientRRect = SkRRect::MakeRectXY(temp, ambientPathOutset, ambientPathOutset); 2493c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } else { 2503c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth rrect.outset(ambientPathOutset, ambientPathOutset, &ambientRRect); 2513c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } 2523c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2533c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkScalar devSpaceAmbientRadius = srcSpaceAmbientRadius * scaleFactor; 2543c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2553c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth GrPaint newPaint(*grp); 256c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth GrColor4f color = newPaint.getColor4f(); 257c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth color.fRGBA[3] *= fAmbientAlpha; 258c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth newPaint.setColor4f(color); 2593c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkStrokeRec ambientStrokeRec(SkStrokeRec::kHairline_InitStyle); 260c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth ambientStrokeRec.setStrokeStyle(srcSpaceAmbientRadius, false); 261c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth 262c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth renderTargetContext->drawShadowRRect(clip, newPaint, viewMatrix, ambientRRect, 263c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth devSpaceAmbientRadius, 264c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth GrStyle(ambientStrokeRec, nullptr)); 2653c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } 2663c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2673c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth if (fSpotAlpha > 0.0f) { 2683c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth float zRatio = SkTPin(fOccluderHeight / (fLightPos.fZ - fOccluderHeight), 0.0f, 0.95f); 2693c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2703c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar srcSpaceSpotRadius = 2.0f * fLightRadius * zRatio; 2713c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2723c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkRRect spotRRect; 2733c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth if (isRect) { 2743c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth spotRRect = SkRRect::MakeRectXY(rrect.rect(), minRadius, minRadius); 2753c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } else { 2763c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth spotRRect = rrect; 2773c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } 2783c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2793c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkRRect spotShadowRRect; 2803c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // Compute the scale and translation for the spot shadow. 2813c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkScalar scale = fLightPos.fZ / (fLightPos.fZ - fOccluderHeight); 2823c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth spotRRect.transform(SkMatrix::MakeScale(scale, scale), &spotShadowRRect); 2833c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2843c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkPoint center = SkPoint::Make(spotShadowRRect.rect().centerX(), 2853c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth spotShadowRRect.rect().centerY()); 2863c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkMatrix ctmInverse; 2873c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth if (!viewMatrix.invert(&ctmInverse)) { 2883c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkDebugf("Matrix is degenerate. Will not render spot shadow!\n"); 2893c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth //**** TODO: this is not good 2903c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth return true; 2913c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } 2923c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkPoint lightPos2D = SkPoint::Make(fLightPos.fX, fLightPos.fY); 2933c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth ctmInverse.mapPoints(&lightPos2D, 1); 2943c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkPoint spotOffset = SkPoint::Make(zRatio*(center.fX - lightPos2D.fX), 2953c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth zRatio*(center.fY - lightPos2D.fY)); 2963c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 2973c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // We want to extend the stroked area in so that it meets up with the caster 2983c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // geometry. The stroked geometry will, by definition already be inset half the 2993c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // stroke width but we also have to account for the scaling. 3003c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar scaleOffset = (scale - 1.0f) * SkTMax(SkTMax(SkTAbs(rrect.rect().fLeft), 3013c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkTAbs(rrect.rect().fRight)), 3023c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkTMax(SkTAbs(rrect.rect().fTop), 3033c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkTAbs(rrect.rect().fBottom))); 304c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth SkScalar insetAmount = spotOffset.length() - (0.5f * srcSpaceSpotRadius) + scaleOffset; 3053c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 3063c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // Compute area 3073c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar strokeWidth = srcSpaceSpotRadius + insetAmount; 3083c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar strokedArea = 2.0f*strokeWidth * 3093c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth (spotShadowRRect.width() + spotShadowRRect.height()); 3103c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar filledArea = (spotShadowRRect.height() + srcSpaceSpotRadius) * 3113c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth (spotShadowRRect.width() + srcSpaceSpotRadius); 3123c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 3133c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth GrPaint newPaint(*grp); 314c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth GrColor4f color = newPaint.getColor4f(); 315c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth color.fRGBA[3] *= fSpotAlpha; 316c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth newPaint.setColor4f(color); 317c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth 3183c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkStrokeRec spotStrokeRec(SkStrokeRec::kFill_InitStyle); 3193c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // If the area of the stroked geometry is larger than the fill geometry, 3203c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // or if the caster is transparent, just fill it. 3213c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth if (strokedArea > filledArea || 3223c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth fFlags & SkShadowMaskFilter::kTransparentOccluder_ShadowFlag) { 3233c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth spotStrokeRec.setStrokeStyle(srcSpaceSpotRadius, true); 3243c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } else { 3253c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // Since we can't have unequal strokes, inset the shadow rect so the inner 3263c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // and outer edges of the stroke will land where we want. 3273c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkRect insetRect = spotShadowRRect.rect().makeInset(insetAmount / 2.0f, 3283c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth insetAmount / 2.0f); 3293c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkScalar insetRad = SkTMax(spotShadowRRect.getSimpleRadii().fX - insetAmount / 2.0f, 3303c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth minRadius); 3313c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth spotShadowRRect = SkRRect::MakeRectXY(insetRect, insetRad, insetRad); 3323c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth spotStrokeRec.setStrokeStyle(strokeWidth, false); 3333c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } 3343c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 3353c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth // handle scale of radius and pad due to CTM 3363c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth const SkScalar devSpaceSpotRadius = srcSpaceSpotRadius * scaleFactor; 3373c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 338c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth spotShadowRRect.offset(spotOffset.fX, spotOffset.fY); 3393c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 340c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth renderTargetContext->drawShadowRRect(clip, newPaint, viewMatrix, spotShadowRRect, 341c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth devSpaceSpotRadius, 342c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth GrStyle(spotStrokeRec, nullptr)); 3433c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } 3443c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 3453c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth return true; 3463c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth} 3473c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 3484a24da5ceccbbd5eb91c75ce680c42191a5342d0Robert Phillipssk_sp<GrTextureProxy> SkShadowMaskFilterImpl::filterMaskGPU(GrContext*, 3494a24da5ceccbbd5eb91c75ce680c42191a5342d0Robert Phillips sk_sp<GrTextureProxy> srcProxy, 3504a24da5ceccbbd5eb91c75ce680c42191a5342d0Robert Phillips const SkMatrix& ctm, 3514a24da5ceccbbd5eb91c75ce680c42191a5342d0Robert Phillips const SkIRect& maskRect) const { 3524a24da5ceccbbd5eb91c75ce680c42191a5342d0Robert Phillips // This filter it generative and doesn't operate on pre-existing masks 3534a24da5ceccbbd5eb91c75ce680c42191a5342d0Robert Phillips return nullptr; 3543c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth} 3553c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 3563c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#endif 3573c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 3583c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#ifndef SK_IGNORE_TO_STRING 3593c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verthvoid SkShadowMaskFilterImpl::toString(SkString* str) const { 3603c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append("SkShadowMaskFilterImpl: ("); 3613c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 3623c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append("occluderHeight: "); 3633c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->appendScalar(fOccluderHeight); 3643c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append(" "); 3653c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 3663c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append("lightPos: ("); 3673c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->appendScalar(fLightPos.fX); 3683c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append(", "); 3693c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->appendScalar(fLightPos.fY); 3703c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append(", "); 3713c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->appendScalar(fLightPos.fZ); 3723c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append(") "); 3733c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 3743c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append("lightRadius: "); 3753c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->appendScalar(fLightRadius); 3763c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append(" "); 3773c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 3783c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append("ambientAlpha: "); 3793c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->appendScalar(fAmbientAlpha); 3803c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append(" "); 3813c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 3823c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append("spotAlpha: "); 3833c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->appendScalar(fSpotAlpha); 3843c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append(" "); 3853c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 3863c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append("flags: ("); 3873c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth if (fFlags) { 3883c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth bool needSeparator = false; 3893c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkAddFlagToString(str, 3903c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkToBool(fFlags & SkShadowMaskFilter::kTransparentOccluder_ShadowFlag), 3913c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth "TransparentOccluder", &needSeparator); 3923c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkAddFlagToString(str, 3933c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkToBool(fFlags & SkShadowMaskFilter::kGaussianEdge_ShadowFlag), 3943c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth "GaussianEdge", &needSeparator); 3953c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkAddFlagToString(str, 3963c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth SkToBool(fFlags & SkShadowMaskFilter::kLargerUmbra_ShadowFlag), 3973c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth "LargerUmbra", &needSeparator); 3983c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } else { 3993c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append("None"); 4003c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth } 4013c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth str->append("))"); 4023c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth} 4033c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth#endif 4043c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van Verth 4053c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van VerthSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShadowMaskFilter) 4063c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van VerthSK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkShadowMaskFilterImpl) 4073c1b7db2432d136df0fc50c2e3ee0b3792b01dd6Jim Van VerthSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 408