Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2015 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "GrStrokeInfo.h"
      9 #include "GrResourceKey.h"
     10 #include "SkDashPathPriv.h"
     11 
     12 bool all_dash_intervals_zero(const SkScalar* intervals, int count) {
     13     for (int i = 0 ; i < count; ++i) {
     14         if (intervals[i] != 0) {
     15             return false;
     16         }
     17     }
     18     return true;
     19 }
     20 
     21 bool GrStrokeInfo::applyDashToPath(SkPath* dst, GrStrokeInfo* dstStrokeInfo,
     22                                    const SkPath& src) const {
     23     if (this->isDashed()) {
     24         SkPathEffect::DashInfo info;
     25         info.fIntervals = fIntervals.get();
     26         info.fCount = fIntervals.count();
     27         info.fPhase = fDashPhase;
     28         GrStrokeInfo filteredStroke(*this, false);
     29         // Handle the case where all intervals are 0 and we simply drop the dash effect
     30         if (all_dash_intervals_zero(fIntervals.get(), fIntervals.count())) {
     31             *dstStrokeInfo = filteredStroke;
     32             *dst = src;
     33             return true;
     34         }
     35         // See if we can filter the dash into a path on cpu
     36         if (SkDashPath::FilterDashPath(dst, src, &filteredStroke, nullptr, info)) {
     37             *dstStrokeInfo = filteredStroke;
     38             return true;
     39         }
     40     }
     41     return false;
     42 }
     43 
     44 void GrStrokeInfo::asUniqueKeyFragment(uint32_t* data) const {
     45     const int kSkScalarData32Cnt = sizeof(SkScalar) / sizeof(uint32_t);
     46     enum {
     47         kStyleBits = 2,
     48         kJoinBits = 2,
     49         kCapBits = 32 - kStyleBits - kJoinBits,
     50 
     51         kJoinShift = kStyleBits,
     52         kCapShift = kJoinShift + kJoinBits,
     53     };
     54 
     55     static_assert(SkStrokeRec::kStyleCount <= (1 << kStyleBits), "style_shift_will_be_wrong");
     56     static_assert(SkPaint::kJoinCount <= (1 << kJoinBits), "cap_shift_will_be_wrong");
     57     static_assert(SkPaint::kCapCount <= (1 << kCapBits), "cap_does_not_fit");
     58     uint32_t styleKey = this->getStyle();
     59     if (this->needToApply()) {
     60         styleKey |= this->getJoin() << kJoinShift;
     61         styleKey |= this->getCap() << kCapShift;
     62     }
     63     int i = 0;
     64     data[i++] = styleKey;
     65 
     66     // Memcpy the scalar fields. Does not "reinterpret_cast<SkScalar&>(data[i]) = ..." due to
     67     // scalars having more strict alignment requirements than what data can guarantee. The
     68     // compiler should optimize memcpys to assignments.
     69     SkScalar scalar;
     70     scalar = this->getMiter();
     71     memcpy(&data[i], &scalar, sizeof(scalar));
     72     i += kSkScalarData32Cnt;
     73 
     74     scalar = this->getWidth();
     75     memcpy(&data[i], &scalar, sizeof(scalar));
     76     i += kSkScalarData32Cnt;
     77 
     78     if (this->isDashed()) {
     79         SkScalar phase = this->getDashPhase();
     80         memcpy(&data[i], &phase, sizeof(phase));
     81         i += kSkScalarData32Cnt;
     82 
     83         int32_t count = this->getDashCount() & static_cast<int32_t>(~1);
     84         SkASSERT(count == this->getDashCount());
     85         const SkScalar* intervals = this->getDashIntervals();
     86         int intervalByteCnt = count * sizeof(SkScalar);
     87         memcpy(&data[i], intervals, intervalByteCnt);
     88         // Enable the line below if fields are added after dashing.
     89         SkDEBUGCODE(i += kSkScalarData32Cnt * count);
     90     }
     91 
     92     SkASSERT(this->computeUniqueKeyFragmentData32Cnt() == i);
     93 }
     94 
     95