Home | History | Annotate | Download | only in ops
      1 /*
      2  * Copyright 2014 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 #ifndef GrSmallPathRenderer_DEFINED
      9 #define GrSmallPathRenderer_DEFINED
     10 
     11 #include "GrDrawOpAtlas.h"
     12 #include "GrOnFlushResourceProvider.h"
     13 #include "GrPathRenderer.h"
     14 #include "GrRect.h"
     15 #include "GrShape.h"
     16 
     17 #include "SkOpts.h"
     18 #include "SkTDynamicHash.h"
     19 
     20 class GrContext;
     21 
     22 class GrSmallPathRenderer : public GrPathRenderer, public GrOnFlushCallbackObject {
     23 public:
     24     GrSmallPathRenderer();
     25     ~GrSmallPathRenderer() override;
     26 
     27     class SmallPathOp;
     28     struct PathTestStruct;
     29 
     30     // GrOnFlushCallbackObject overrides
     31     //
     32     // Note: because this class is associated with a path renderer we want it to be removed from
     33     // the list of active OnFlushBackkbackObjects in an freeGpuResources call (i.e., we accept the
     34     // default retainOnFreeGpuResources implementation).
     35 
     36     void preFlush(GrOnFlushResourceProvider* onFlushResourceProvider, const uint32_t*, int,
     37                   SkTArray<sk_sp<GrRenderTargetContext>>*) override {
     38         if (fAtlas) {
     39             fAtlas->instantiate(onFlushResourceProvider);
     40         }
     41     }
     42 
     43     void postFlush(GrDeferredUploadToken startTokenForNextFlush,
     44                    const uint32_t* opListIDs, int numOpListIDs) override {
     45         if (fAtlas) {
     46             fAtlas->compact(startTokenForNextFlush);
     47         }
     48     }
     49 
     50 private:
     51     StencilSupport onGetStencilSupport(const GrShape&) const override {
     52         return GrPathRenderer::kNoSupport_StencilSupport;
     53     }
     54 
     55     CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override;
     56 
     57     bool onDrawPath(const DrawPathArgs&) override;
     58 
     59     struct ShapeData {
     60         class Key {
     61         public:
     62             Key() {}
     63             Key(const Key& that) { *this = that; }
     64             Key(const GrShape& shape, uint32_t dim) { this->set(shape, dim); }
     65             Key(const GrShape& shape, const SkMatrix& ctm) { this->set(shape, ctm); }
     66 
     67             Key& operator=(const Key& that) {
     68                 fKey.reset(that.fKey.count());
     69                 memcpy(fKey.get(), that.fKey.get(), fKey.count() * sizeof(uint32_t));
     70                 return *this;
     71             }
     72 
     73             // for SDF paths
     74             void set(const GrShape& shape, uint32_t dim) {
     75                 // Shapes' keys are for their pre-style geometry, but by now we shouldn't have any
     76                 // relevant styling information.
     77                 SkASSERT(shape.style().isSimpleFill());
     78                 SkASSERT(shape.hasUnstyledKey());
     79                 int shapeKeySize = shape.unstyledKeySize();
     80                 fKey.reset(1 + shapeKeySize);
     81                 fKey[0] = dim;
     82                 shape.writeUnstyledKey(&fKey[1]);
     83             }
     84 
     85             // for bitmap paths
     86             void set(const GrShape& shape, const SkMatrix& ctm) {
     87                 // Shapes' keys are for their pre-style geometry, but by now we shouldn't have any
     88                 // relevant styling information.
     89                 SkASSERT(shape.style().isSimpleFill());
     90                 SkASSERT(shape.hasUnstyledKey());
     91                 // We require the upper left 2x2 of the matrix to match exactly for a cache hit.
     92                 SkScalar sx = ctm.get(SkMatrix::kMScaleX);
     93                 SkScalar sy = ctm.get(SkMatrix::kMScaleY);
     94                 SkScalar kx = ctm.get(SkMatrix::kMSkewX);
     95                 SkScalar ky = ctm.get(SkMatrix::kMSkewY);
     96                 SkScalar tx = ctm.get(SkMatrix::kMTransX);
     97                 SkScalar ty = ctm.get(SkMatrix::kMTransY);
     98                 // Allow 8 bits each in x and y of subpixel positioning.
     99                 SkFixed fracX = SkScalarToFixed(SkScalarFraction(tx)) & 0x0000FF00;
    100                 SkFixed fracY = SkScalarToFixed(SkScalarFraction(ty)) & 0x0000FF00;
    101                 int shapeKeySize = shape.unstyledKeySize();
    102                 fKey.reset(5 + shapeKeySize);
    103                 fKey[0] = SkFloat2Bits(sx);
    104                 fKey[1] = SkFloat2Bits(sy);
    105                 fKey[2] = SkFloat2Bits(kx);
    106                 fKey[3] = SkFloat2Bits(ky);
    107                 fKey[4] = fracX | (fracY >> 8);
    108                 shape.writeUnstyledKey(&fKey[5]);
    109             }
    110 
    111             bool operator==(const Key& that) const {
    112                 return fKey.count() == that.fKey.count() &&
    113                         0 == memcmp(fKey.get(), that.fKey.get(), sizeof(uint32_t) * fKey.count());
    114             }
    115 
    116             int count32() const { return fKey.count(); }
    117             const uint32_t* data() const { return fKey.get(); }
    118 
    119         private:
    120             // The key is composed of the GrShape's key, and either the dimensions of the DF
    121             // generated for the path (32x32 max, 64x64 max, 128x128 max) if an SDF image or
    122             // the matrix for the path with only fractional translation.
    123             SkAutoSTArray<24, uint32_t> fKey;
    124         };
    125         Key                    fKey;
    126         GrDrawOpAtlas::AtlasID fID;
    127         SkRect                 fBounds;
    128         GrIRect16              fTextureCoords;
    129         SK_DECLARE_INTERNAL_LLIST_INTERFACE(ShapeData);
    130 
    131         static inline const Key& GetKey(const ShapeData& data) {
    132             return data.fKey;
    133         }
    134 
    135         static inline uint32_t Hash(Key key) {
    136             return SkOpts::hash(key.data(), sizeof(uint32_t) * key.count32());
    137         }
    138     };
    139 
    140     static void HandleEviction(GrDrawOpAtlas::AtlasID, void*);
    141 
    142     typedef SkTDynamicHash<ShapeData, ShapeData::Key> ShapeCache;
    143     typedef SkTInternalLList<ShapeData> ShapeDataList;
    144 
    145     std::unique_ptr<GrDrawOpAtlas> fAtlas;
    146     ShapeCache fShapeCache;
    147     ShapeDataList fShapeList;
    148 
    149     typedef GrPathRenderer INHERITED;
    150 };
    151 
    152 #endif
    153