1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2014 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrGLPathRange.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrGLPath.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrGLPathRendering.h" 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrGLGpu.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrGLPathRange::GrGLPathRange(GrGLGpu* gpu, PathGenerator* pathGenerator, const GrStyle& style) 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(gpu, pathGenerator), 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fStyle(style), 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBasePathID(gpu->glPathRendering()->genPaths(this->getNumPaths())), 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fGpuMemorySize(0) { 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->init(); 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->registerWithCache(SkBudgeted::kYes); 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrGLPathRange::GrGLPathRange(GrGLGpu* gpu, 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLuint basePathID, 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int numPaths, 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t gpuMemorySize, 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrStyle& style) 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : INHERITED(gpu, numPaths), 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fStyle(style), 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBasePathID(basePathID), 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fGpuMemorySize(gpuMemorySize) { 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->init(); 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->registerWithCache(SkBudgeted::kYes); 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrGLPathRange::init() { 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkStrokeRec& stroke = fStyle.strokeRec(); 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Must force fill: 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // * dashing: NVPR stroke dashing is different to Skia. 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // * end caps: NVPR stroking degenerate contours with end caps is different to Skia. 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool forceFill = fStyle.pathEffect() || 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot (stroke.needToApply() && stroke.getCap() != SkPaint::kButt_Cap); 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (forceFill) { 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fShouldStroke = false; 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fShouldFill = true; 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fShouldStroke = stroke.needToApply(); 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fShouldFill = stroke.isFillStyle() || 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style; 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrGLPathRange::onInitPath(int index, const SkPath& origSkPath) const { 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLGpu* gpu = static_cast<GrGLGpu*>(this->getGpu()); 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (nullptr == gpu) { 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Make sure the path at this index hasn't been initted already. 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGCODE( 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLboolean isPath; 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GR_GL_CALL_RET(gpu->glInterface(), isPath, IsPath(fBasePathID + index))); 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(GR_GL_FALSE == isPath); 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (origSkPath.isEmpty()) { 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLPath::InitPathObjectEmptyPath(gpu, fBasePathID + index); 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else if (fShouldStroke) { 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLPath::InitPathObjectPathData(gpu, fBasePathID + index, origSkPath); 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLPath::InitPathObjectStroke(gpu, fBasePathID + index, fStyle.strokeRec()); 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPath* skPath = &origSkPath; 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTLazy<SkPath> tmpPath; 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!fStyle.isSimpleFill()) { 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkStrokeRec::InitStyle fill; 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The path effect must be applied to the path. However, if a path effect is present, 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // we must convert all the paths to fills. The path effect application may leave 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // simple paths as strokes but converts other paths to fills. 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Thus we must stroke the strokes here, so that all paths in the 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // path range are using the same style. 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!fStyle.applyToPath(tmpPath.init(), &fill, *skPath, SK_Scalar1)) { 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We shouldn't have allowed hairlines or arbitrary path effect styles to get here 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // so after application we better have a filled path. 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(SkStrokeRec::kFill_InitStyle == fill); 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot skPath = tmpPath.get(); 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGLPath::InitPathObjectPathData(gpu, fBasePathID + index, *skPath); 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // TODO: Use a better approximation for the individual path sizes. 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fGpuMemorySize += 100; 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrGLPathRange::onRelease() { 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(this->getGpu()); 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (0 != fBasePathID) { 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static_cast<GrGLGpu*>(this->getGpu())->glPathRendering()->deletePaths(fBasePathID, 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->getNumPaths()); 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBasePathID = 0; 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot INHERITED::onRelease(); 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrGLPathRange::onAbandon() { 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBasePathID = 0; 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot INHERITED::onAbandon(); 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 111