xref: /third_party/skia/src/core/SkPictureCommon.h (revision cb93a386)
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#ifndef SkPictureCommon_DEFINED
9#define SkPictureCommon_DEFINED
10
11// Some shared code used by both SkBigPicture and SkMiniPicture.
12//   SkTextHunter   -- SkRecord visitor that returns true when the op draws text.
13//   SkPathCounter  -- SkRecord visitor that counts paths that draw slowly on the GPU.
14
15#include "include/core/SkPathEffect.h"
16#include "include/core/SkShader.h"
17#include "include/private/SkTLogic.h"
18#include "src/core/SkRecords.h"
19
20// TODO: might be nicer to have operator() return an int (the number of slow paths) ?
21struct SkPathCounter {
22    // Some ops have a paint, some have an optional paint.  Either way, get back a pointer.
23    static const SkPaint* AsPtr(const SkPaint& p) { return &p; }
24    static const SkPaint* AsPtr(const SkRecords::Optional<SkPaint>& p) { return p; }
25
26    SkPathCounter() : fNumSlowPathsAndDashEffects(0) {}
27
28    void checkPaint(const SkPaint* paint) {
29        if (paint && paint->getPathEffect()) {
30            // Initially assume it's slow.
31            fNumSlowPathsAndDashEffects++;
32        }
33    }
34
35    void operator()(const SkRecords::DrawPoints& op) {
36        this->checkPaint(&op.paint);
37        const SkPathEffect* effect = op.paint.getPathEffect();
38        if (effect) {
39            SkPathEffect::DashInfo info;
40            SkPathEffect::DashType dashType = effect->asADash(&info);
41            if (2 == op.count && SkPaint::kRound_Cap != op.paint.getStrokeCap() &&
42                SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) {
43                fNumSlowPathsAndDashEffects--;
44            }
45        }
46    }
47
48    void operator()(const SkRecords::DrawPath& op) {
49        this->checkPaint(&op.paint);
50        if (op.paint.isAntiAlias() && !op.path.isConvex()) {
51            SkPaint::Style paintStyle = op.paint.getStyle();
52            const SkRect& pathBounds = op.path.getBounds();
53            if (SkPaint::kStroke_Style == paintStyle &&
54                0 == op.paint.getStrokeWidth()) {
55                // AA hairline concave path is not slow.
56            } else if (SkPaint::kFill_Style == paintStyle && pathBounds.width() < 64.f &&
57                       pathBounds.height() < 64.f && !op.path.isVolatile()) {
58                // AADF eligible concave path is not slow.
59            } else {
60                fNumSlowPathsAndDashEffects++;
61            }
62        }
63    }
64
65    void operator()(const SkRecords::ClipPath& op) {
66        // TODO: does the SkRegion op matter?
67        if (op.opAA.aa() && !op.path.isConvex()) {
68            fNumSlowPathsAndDashEffects++;
69        }
70    }
71
72    void operator()(const SkRecords::SaveLayer& op) {
73        this->checkPaint(AsPtr(op.paint));
74    }
75
76    template <typename T>
77    std::enable_if_t<T::kTags & SkRecords::kHasPaint_Tag, void> operator()(const T& op) {
78        this->checkPaint(AsPtr(op.paint));
79    }
80
81    template <typename T>
82    std::enable_if_t<!(T::kTags & SkRecords::kHasPaint_Tag), void>
83      operator()(const T& op) { /* do nothing */ }
84
85    int fNumSlowPathsAndDashEffects;
86};
87
88sk_sp<SkImage> ImageDeserializer_SkDeserialImageProc(const void*, size_t, void* imagedeserializer);
89
90bool SkPicture_StreamIsSKP(SkStream*, SkPictInfo*);
91
92#endif  // SkPictureCommon_DEFINED
93