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