Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(385)

Side by Side Diff: src/core/SkBigPicture.cpp

Issue 1112523006: Sketch splitting SkPicture into an interface and SkBigPicture. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: tweaks Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 "SkBBoxHierarchy.h"
9 #include "SkBigPicture.h"
10 #include "SkPathEffect.h"
11 #include "SkRecord.h"
12 #include "SkRecordDraw.h"
13
14 SkBigPicture::SkBigPicture(const SkRect& cull,
15 SkRecord* record,
16 SnapshotArray* drawablePicts,
17 SkBBoxHierarchy* bbh,
18 AccelData* accelData,
19 size_t approxBytesUsedBySubPictures)
20 : fCullRect(cull)
21 , fAnalysis(*record)
22 , fApproxBytesUsedBySubPictures(approxBytesUsedBySubPictures)
23 , fRecord(record) // Take ownership of caller's ref.
24 , fDrawablePicts(drawablePicts) // Take ownership.
25 , fBBH(bbh) // Take ownership of caller's ref.
26 , fAccelData(accelData) // Take ownership of caller's ref.
27 {}
28
29 void SkBigPicture::playback(SkCanvas* canvas, AbortCallback* callback) const {
30 SkASSERT(canvas);
31
32 // If the query contains the whole picture, don't bother with the BBH.
33 SkRect clipBounds = { 0, 0, 0, 0 };
34 (void)canvas->getClipBounds(&clipBounds);
35 const bool useBBH = !clipBounds.contains(this->cullRect());
36
37 SkRecordDraw(*fRecord,
38 canvas,
39 this->drawablePicts(),
40 nullptr,
41 this->drawableCount(),
42 useBBH ? fBBH.get() : nullptr,
43 callback);
44 }
45
46 void SkBigPicture::partialPlayback(SkCanvas* canvas,
47 unsigned start,
48 unsigned stop,
49 const SkMatrix& initialCTM) const {
50 SkASSERT(canvas);
51 SkRecordPartialDraw(*fRecord,
52 canvas,
53 this->drawablePicts(),
54 this->drawableCount(),
55 start,
56 stop,
57 initialCTM);
58 }
59
60 SkRect SkBigPicture::cullRect() const { return fCullRect; }
61 bool SkBigPicture::hasText() const { return fAnalysis.fHasText; }
62 bool SkBigPicture::willPlayBackBitmaps() const { return fAnalysis.fWillPlayba ckBitmaps; }
63 int SkBigPicture::numSlowPaths() const { return fAnalysis.fNumSlowPat hsAndDashEffects; }
64 int SkBigPicture::approximateOpCount() const { return fRecord->count(); }
65 size_t SkBigPicture::approximateBytesUsed() const {
66 size_t bytes = sizeof(*this) + fRecord->bytesUsed() + fApproxBytesUsedBySubP ictures;
67 if (fBBH) { bytes += fBBH->bytesUsed(); }
68 return bytes;
69 }
70 bool SkBigPicture::suitableForGpuRasterization(GrContext*, const char** reason) const {
71 return fAnalysis.suitableForGpuRasterization(reason);
72 }
73
74 int SkBigPicture::drawableCount() const {
75 return fDrawablePicts ? fDrawablePicts->count() : 0;
76 }
77 SkPicture const* const* SkBigPicture::drawablePicts() const {
78 return fDrawablePicts ? fDrawablePicts->begin() : nullptr;
79 }
80
81
82 // Some ops have a paint, some have an optional paint. Either way, get back a p ointer.
83 static const SkPaint* as_ptr(const SkPaint& p) { return &p; }
84 static const SkPaint* as_ptr(const SkRecords::Optional<SkPaint>& p) { return p; }
85
86 struct TextHunter {
87 // Most ops never have text. Some always do. Subpictures know themeselves.
88 template <typename T> bool operator()(const T&) { return false; }
89 bool operator()(const SkRecords::DrawPosText&) { return true; }
90 bool operator()(const SkRecords::DrawPosTextH&) { return true; }
91 bool operator()(const SkRecords::DrawText&) { return true; }
92 bool operator()(const SkRecords::DrawTextBlob&) { return true; }
93 bool operator()(const SkRecords::DrawTextOnPath&) { return true; }
94 bool operator()(const SkRecords::DrawPicture& op) { return op.picture->hasTe xt(); }
95 };
96
97 struct BitmapHunter {
98 // Helpers. These create HasMember_bitmap and HasMember_paint.
99 SK_CREATE_MEMBER_DETECTOR(bitmap);
100 SK_CREATE_MEMBER_DETECTOR(paint);
101
102 // Main entry for visitor:
103 // If the op is a DrawPicture, recurse.
104 // If the op has a bitmap directly, return true.
105 // If the op has a paint and the paint has a bitmap, return true.
106 // Otherwise, return false.
107 bool operator()(const SkRecords::DrawPicture& op) { return op.picture->willP layBackBitmaps(); }
108
109 template <typename T>
110 bool operator()(const T& r) { return CheckBitmap(r); }
111
112 // If the op has a bitmap, of course we're going to play back bitmaps.
113 template <typename T>
114 static SK_WHEN(HasMember_bitmap<T>, bool) CheckBitmap(const T&) { return tru e; }
115
116 // If not, look for one in its paint (if it has a paint).
117 template <typename T>
118 static SK_WHEN(!HasMember_bitmap<T>, bool) CheckBitmap(const T& r) { return CheckPaint(r); }
119
120 // If we have a paint, dig down into the effects looking for a bitmap.
121 template <typename T>
122 static SK_WHEN(HasMember_paint<T>, bool) CheckPaint(const T& r) {
123 const SkPaint* paint = as_ptr(r.paint);
124 if (paint) {
125 const SkShader* shader = paint->getShader();
126 if (shader &&
127 shader->asABitmap(nullptr, nullptr, nullptr) == SkShader::kDefau lt_BitmapType) {
128 return true;
129 }
130 }
131 return false;
132 }
133
134 // If we don't have a paint, that non-paint has no bitmap.
135 template <typename T>
136 static SK_WHEN(!HasMember_paint<T>, bool) CheckPaint(const T&) { return fals e; }
137 };
138
139 struct SkBigPicture::PathCounter {
140 SK_CREATE_MEMBER_DETECTOR(paint);
141
142 PathCounter() : fNumSlowPathsAndDashEffects(0) {}
143
144 // Recurse into nested pictures.
145 void operator()(const SkRecords::DrawPicture& op) {
146 fNumSlowPathsAndDashEffects += op.picture->numSlowPaths();
147 }
148
149 void checkPaint(const SkPaint* paint) {
150 if (paint && paint->getPathEffect()) {
151 // Initially assume it's slow.
152 fNumSlowPathsAndDashEffects++;
153 }
154 }
155
156 void operator()(const SkRecords::DrawPoints& op) {
157 this->checkPaint(&op.paint);
158 const SkPathEffect* effect = op.paint.getPathEffect();
159 if (effect) {
160 SkPathEffect::DashInfo info;
161 SkPathEffect::DashType dashType = effect->asADash(&info);
162 if (2 == op.count && SkPaint::kRound_Cap != op.paint.getStrokeCap() &&
163 SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) {
164 fNumSlowPathsAndDashEffects--;
165 }
166 }
167 }
168
169 void operator()(const SkRecords::DrawPath& op) {
170 this->checkPaint(&op.paint);
171 if (op.paint.isAntiAlias() && !op.path.isConvex()) {
172 SkPaint::Style paintStyle = op.paint.getStyle();
173 const SkRect& pathBounds = op.path.getBounds();
174 if (SkPaint::kStroke_Style == paintStyle &&
175 0 == op.paint.getStrokeWidth()) {
176 // AA hairline concave path is not slow.
177 } else if (SkPaint::kFill_Style == paintStyle && pathBounds.width() < 64.f &&
178 pathBounds.height() < 64.f && !op.path.isVolatile()) {
179 // AADF eligible concave path is not slow.
180 } else {
181 fNumSlowPathsAndDashEffects++;
182 }
183 }
184 }
185
186 template <typename T>
187 SK_WHEN(HasMember_paint<T>, void) operator()(const T& op) {
188 this->checkPaint(as_ptr(op.paint));
189 }
190
191 template <typename T>
192 SK_WHEN(!HasMember_paint<T>, void) operator()(const T& op) { /* do nothing * / }
193
194 int fNumSlowPathsAndDashEffects;
195 };
196
197 SkBigPicture::Analysis::Analysis(const SkRecord& record) {
198 TextHunter text;
199 BitmapHunter bitmap;
200 PathCounter path;
201
202 bool hasText = false, hasBitmap = false;
203 for (unsigned i = 0; i < record.count(); i++) {
204 hasText = hasText || record.visit<bool>(i, text);
205 hasBitmap = hasBitmap || record.visit<bool>(i, bitmap);
206 record.visit<void>(i, path);
207 }
208
209 fHasText = hasText;
210 fWillPlaybackBitmaps = hasBitmap;
211 fNumSlowPathsAndDashEffects = SkTMin<int>(path.fNumSlowPathsAndDashEffects, 255);
212 }
213
214 bool SkBigPicture::Analysis::suitableForGpuRasterization(const char** reason) co nst {
215 if (fNumSlowPathsAndDashEffects > 5) {
216 if (reason) { *reason = "Too many slow paths (either concave or dashed). "; }
217 return false;
218 }
219 return true;
220 }
OLDNEW
« no previous file with comments | « src/core/SkBigPicture.h ('k') | src/core/SkLayerInfo.h » ('j') | src/core/SkMiniRecorder.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698