1b85a0aab6905af8b329539b7573a7555b727d5e5cdalton/* 2b85a0aab6905af8b329539b7573a7555b727d5e5cdalton * Copyright 2014 Google Inc. 3b85a0aab6905af8b329539b7573a7555b727d5e5cdalton * 4b85a0aab6905af8b329539b7573a7555b727d5e5cdalton * Use of this source code is governed by a BSD-style license that can be 5b85a0aab6905af8b329539b7573a7555b727d5e5cdalton * found in the LICENSE file. 6b85a0aab6905af8b329539b7573a7555b727d5e5cdalton */ 7b85a0aab6905af8b329539b7573a7555b727d5e5cdalton 8b85a0aab6905af8b329539b7573a7555b727d5e5cdalton#include "GrGLPathRange.h" 9b85a0aab6905af8b329539b7573a7555b727d5e5cdalton#include "GrGLPath.h" 10c7103a104fdc7150b4e3c0d3efc42735ad359616cdalton#include "GrGLPathRendering.h" 1139edf7664f50b6c890b933b5bbed67a8735b349bjvanverth#include "GrGLGpu.h" 12b85a0aab6905af8b329539b7573a7555b727d5e5cdalton 136663acff010ce752e4bf778da81fa97448c9db31bsalomonGrGLPathRange::GrGLPathRange(GrGLGpu* gpu, PathGenerator* pathGenerator, const GrStyle& style) 1450b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen : INHERITED(gpu, pathGenerator), 156663acff010ce752e4bf778da81fa97448c9db31bsalomon fStyle(style), 16855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton fBasePathID(gpu->glPathRendering()->genPaths(this->getNumPaths())), 17855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton fGpuMemorySize(0) { 1850b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen this->init(); 192e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen this->registerWithCache(SkBudgeted::kYes); 20855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton} 21855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton 22861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonGrGLPathRange::GrGLPathRange(GrGLGpu* gpu, 23855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton GrGLuint basePathID, 24855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton int numPaths, 25855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton size_t gpuMemorySize, 266663acff010ce752e4bf778da81fa97448c9db31bsalomon const GrStyle& style) 2750b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen : INHERITED(gpu, numPaths), 286663acff010ce752e4bf778da81fa97448c9db31bsalomon fStyle(style), 29855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton fBasePathID(basePathID), 30855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton fGpuMemorySize(gpuMemorySize) { 3150b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen this->init(); 322e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen this->registerWithCache(SkBudgeted::kYes); 33b85a0aab6905af8b329539b7573a7555b727d5e5cdalton} 34b85a0aab6905af8b329539b7573a7555b727d5e5cdalton 3550b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunenvoid GrGLPathRange::init() { 366663acff010ce752e4bf778da81fa97448c9db31bsalomon const SkStrokeRec& stroke = fStyle.strokeRec(); 371e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen // Must force fill: 381e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen // * dashing: NVPR stroke dashing is different to Skia. 391e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen // * end caps: NVPR stroking degenerate contours with end caps is different to Skia. 406663acff010ce752e4bf778da81fa97448c9db31bsalomon bool forceFill = fStyle.pathEffect() || 416663acff010ce752e4bf778da81fa97448c9db31bsalomon (stroke.needToApply() && stroke.getCap() != SkPaint::kButt_Cap); 421e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen 431e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen if (forceFill) { 4450b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen fShouldStroke = false; 4550b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen fShouldFill = true; 4650b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen } else { 476663acff010ce752e4bf778da81fa97448c9db31bsalomon fShouldStroke = stroke.needToApply(); 486663acff010ce752e4bf778da81fa97448c9db31bsalomon fShouldFill = stroke.isFillStyle() || 496663acff010ce752e4bf778da81fa97448c9db31bsalomon stroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style; 5050b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen } 5150b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen} 5250b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen 5350b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunenvoid GrGLPathRange::onInitPath(int index, const SkPath& origSkPath) const { 54861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomon GrGLGpu* gpu = static_cast<GrGLGpu*>(this->getGpu()); 5596fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == gpu) { 56b85a0aab6905af8b329539b7573a7555b727d5e5cdalton return; 57b85a0aab6905af8b329539b7573a7555b727d5e5cdalton } 58b85a0aab6905af8b329539b7573a7555b727d5e5cdalton // Make sure the path at this index hasn't been initted already. 595b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen SkDEBUGCODE( 605b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GrGLboolean isPath; 615b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen GR_GL_CALL_RET(gpu->glInterface(), isPath, IsPath(fBasePathID + index))); 625b653577994fe298e08e5f7a5c1fa39fe53c9203kkinnunen SkASSERT(GR_GL_FALSE == isPath); 63b85a0aab6905af8b329539b7573a7555b727d5e5cdalton 641e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen if (origSkPath.isEmpty()) { 651e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen GrGLPath::InitPathObjectEmptyPath(gpu, fBasePathID + index); 661e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen } else if (fShouldStroke) { 671e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen GrGLPath::InitPathObjectPathData(gpu, fBasePathID + index, origSkPath); 686663acff010ce752e4bf778da81fa97448c9db31bsalomon GrGLPath::InitPathObjectStroke(gpu, fBasePathID + index, fStyle.strokeRec()); 691e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen } else { 701e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen const SkPath* skPath = &origSkPath; 711e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen SkTLazy<SkPath> tmpPath; 726663acff010ce752e4bf778da81fa97448c9db31bsalomon if (!fStyle.isSimpleFill()) { 736663acff010ce752e4bf778da81fa97448c9db31bsalomon SkStrokeRec::InitStyle fill; 746663acff010ce752e4bf778da81fa97448c9db31bsalomon // The path effect must be applied to the path. However, if a path effect is present, 756663acff010ce752e4bf778da81fa97448c9db31bsalomon // we must convert all the paths to fills. The path effect application may leave 766663acff010ce752e4bf778da81fa97448c9db31bsalomon // simple paths as strokes but converts other paths to fills. 776663acff010ce752e4bf778da81fa97448c9db31bsalomon // Thus we must stroke the strokes here, so that all paths in the 786663acff010ce752e4bf778da81fa97448c9db31bsalomon // path range are using the same style. 796663acff010ce752e4bf778da81fa97448c9db31bsalomon if (!fStyle.applyToPath(tmpPath.init(), &fill, *skPath, SK_Scalar1)) { 801e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen return; 811e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen } 826663acff010ce752e4bf778da81fa97448c9db31bsalomon // We shouldn't have allowed hairlines or arbitrary path effect styles to get here 836663acff010ce752e4bf778da81fa97448c9db31bsalomon // so after application we better have a filled path. 846663acff010ce752e4bf778da81fa97448c9db31bsalomon SkASSERT(SkStrokeRec::kFill_InitStyle == fill); 851e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen skPath = tmpPath.get(); 866663acff010ce752e4bf778da81fa97448c9db31bsalomon 8750b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen } 881e2913e7cb8c8122151cabd0aa6c77011253e95bkkinnunen GrGLPath::InitPathObjectPathData(gpu, fBasePathID + index, *skPath); 8950b58e6fbcc50785ceffacb2c51b22c6e67a7ab7kkinnunen } 90855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton // TODO: Use a better approximation for the individual path sizes. 91855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton fGpuMemorySize += 100; 92b85a0aab6905af8b329539b7573a7555b727d5e5cdalton} 93b85a0aab6905af8b329539b7573a7555b727d5e5cdalton 94b85a0aab6905af8b329539b7573a7555b727d5e5cdaltonvoid GrGLPathRange::onRelease() { 9549f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(this->getGpu()); 96b85a0aab6905af8b329539b7573a7555b727d5e5cdalton 972e6055b3ea14a04fcde1ac1974a70bf00b1e295bkkinnunen if (0 != fBasePathID) { 98861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomon static_cast<GrGLGpu*>(this->getGpu())->glPathRendering()->deletePaths(fBasePathID, 99855d83ff79c6c822b2ad653f2f890178ad0f637bcdalton this->getNumPaths()); 100b85a0aab6905af8b329539b7573a7555b727d5e5cdalton fBasePathID = 0; 101b85a0aab6905af8b329539b7573a7555b727d5e5cdalton } 102b85a0aab6905af8b329539b7573a7555b727d5e5cdalton 103b85a0aab6905af8b329539b7573a7555b727d5e5cdalton INHERITED::onRelease(); 104b85a0aab6905af8b329539b7573a7555b727d5e5cdalton} 105b85a0aab6905af8b329539b7573a7555b727d5e5cdalton 106b85a0aab6905af8b329539b7573a7555b727d5e5cdaltonvoid GrGLPathRange::onAbandon() { 107b85a0aab6905af8b329539b7573a7555b727d5e5cdalton fBasePathID = 0; 108b85a0aab6905af8b329539b7573a7555b727d5e5cdalton 109b85a0aab6905af8b329539b7573a7555b727d5e5cdalton INHERITED::onAbandon(); 110b85a0aab6905af8b329539b7573a7555b727d5e5cdalton} 111