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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurface.cpp

Issue 1609343004: Add display list fallback reason histograms for 2D canvas (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: git cl web Created 4 years, 10 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "platform/graphics/RecordingImageBufferSurface.h" 5 #include "platform/graphics/RecordingImageBufferSurface.h"
6 6
7 #include "platform/graphics/CanvasMetrics.h" 7 #include "platform/graphics/CanvasMetrics.h"
8 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" 8 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h"
9 #include "platform/graphics/GraphicsContext.h" 9 #include "platform/graphics/GraphicsContext.h"
10 #include "platform/graphics/ImageBuffer.h" 10 #include "platform/graphics/ImageBuffer.h"
(...skipping 15 matching lines...) Expand all
26 , m_currentFrameHasExpensiveOp(false) 26 , m_currentFrameHasExpensiveOp(false)
27 , m_previousFrameHasExpensiveOp(false) 27 , m_previousFrameHasExpensiveOp(false)
28 , m_fallbackFactory(std::move(fallbackFactory)) 28 , m_fallbackFactory(std::move(fallbackFactory))
29 { 29 {
30 initializeCurrentFrame(); 30 initializeCurrentFrame();
31 } 31 }
32 32
33 RecordingImageBufferSurface::~RecordingImageBufferSurface() 33 RecordingImageBufferSurface::~RecordingImageBufferSurface()
34 { } 34 { }
35 35
36 bool RecordingImageBufferSurface::initializeCurrentFrame() 36 void RecordingImageBufferSurface::initializeCurrentFrame()
37 { 37 {
38 static SkRTreeFactory rTreeFactory; 38 static SkRTreeFactory rTreeFactory;
39 m_currentFrame = adoptPtr(new SkPictureRecorder); 39 m_currentFrame = adoptPtr(new SkPictureRecorder);
40 m_currentFrame->beginRecording(size().width(), size().height(), &rTreeFactor y); 40 m_currentFrame->beginRecording(size().width(), size().height(), &rTreeFactor y);
41 if (m_imageBuffer) { 41 if (m_imageBuffer) {
42 m_imageBuffer->resetCanvas(m_currentFrame->getRecordingCanvas()); 42 m_imageBuffer->resetCanvas(m_currentFrame->getRecordingCanvas());
43 } 43 }
44 m_didRecordDrawCommandsInCurrentFrame = false; 44 m_didRecordDrawCommandsInCurrentFrame = false;
45 m_currentFrameHasExpensiveOp = false; 45 m_currentFrameHasExpensiveOp = false;
46 m_currentFramePixelCount = 0; 46 m_currentFramePixelCount = 0;
47 return true;
48 } 47 }
49 48
50 void RecordingImageBufferSurface::setImageBuffer(ImageBuffer* imageBuffer) 49 void RecordingImageBufferSurface::setImageBuffer(ImageBuffer* imageBuffer)
51 { 50 {
52 m_imageBuffer = imageBuffer; 51 m_imageBuffer = imageBuffer;
53 if (m_currentFrame && m_imageBuffer) { 52 if (m_currentFrame && m_imageBuffer) {
54 m_imageBuffer->resetCanvas(m_currentFrame->getRecordingCanvas()); 53 m_imageBuffer->resetCanvas(m_currentFrame->getRecordingCanvas());
55 } 54 }
56 if (m_fallbackSurface) { 55 if (m_fallbackSurface) {
57 m_fallbackSurface->setImageBuffer(imageBuffer); 56 m_fallbackSurface->setImageBuffer(imageBuffer);
58 } 57 }
59 } 58 }
60 59
61 bool RecordingImageBufferSurface::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, int x, int y) 60 bool RecordingImageBufferSurface::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, int x, int y)
62 { 61 {
63 if (!m_fallbackSurface) { 62 if (!m_fallbackSurface) {
64 if (x <= 0 && y <= 0 && x + origInfo.width() >= size().width() && y + or igInfo.height() >= size().height()) { 63 if (x <= 0 && y <= 0 && x + origInfo.width() >= size().width() && y + or igInfo.height() >= size().height()) {
65 willOverwriteCanvas(); 64 willOverwriteCanvas();
66 } 65 }
67 fallBackToRasterCanvas(); 66 fallBackToRasterCanvas(FallbackReasonWritePixels);
68 } 67 }
69 return m_fallbackSurface->writePixels(origInfo, pixels, rowBytes, x, y); 68 return m_fallbackSurface->writePixels(origInfo, pixels, rowBytes, x, y);
70 } 69 }
71 70
72 void RecordingImageBufferSurface::fallBackToRasterCanvas() 71 void RecordingImageBufferSurface::fallBackToRasterCanvas(FallbackReason reason)
73 { 72 {
74 if (m_fallbackSurface) { 73 if (m_fallbackSurface) {
75 ASSERT(!m_currentFrame); 74 ASSERT(!m_currentFrame);
76 return; 75 return;
77 } 76 }
78 77
78 Platform::current()->histogramEnumeration("Canvas.DisplayListFallbackReason" , reason, FallbackReasonCount);
79
79 m_fallbackSurface = m_fallbackFactory->createSurface(size(), opacityMode()); 80 m_fallbackSurface = m_fallbackFactory->createSurface(size(), opacityMode());
80 m_fallbackSurface->setImageBuffer(m_imageBuffer); 81 m_fallbackSurface->setImageBuffer(m_imageBuffer);
81 82
82 if (m_previousFrame) { 83 if (m_previousFrame) {
83 m_previousFrame->playback(m_fallbackSurface->canvas()); 84 m_previousFrame->playback(m_fallbackSurface->canvas());
84 m_previousFrame.clear(); 85 m_previousFrame.clear();
85 } 86 }
86 87
87 if (m_currentFrame) { 88 if (m_currentFrame) {
88 RefPtr<SkPicture> currentPicture = adoptRef(m_currentFrame->endRecording ()); 89 RefPtr<SkPicture> currentPicture = adoptRef(m_currentFrame->endRecording ());
89 currentPicture->playback(m_fallbackSurface->canvas()); 90 currentPicture->playback(m_fallbackSurface->canvas());
90 m_currentFrame.clear(); 91 m_currentFrame.clear();
91 } 92 }
92 93
93 if (m_imageBuffer) { 94 if (m_imageBuffer) {
94 m_imageBuffer->resetCanvas(m_fallbackSurface->canvas()); 95 m_imageBuffer->resetCanvas(m_fallbackSurface->canvas());
95 } 96 }
96 97
97 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::DisplayList2DCanvasFal lbackToRaster); 98 CanvasMetrics::countCanvasContextUsage(CanvasMetrics::DisplayList2DCanvasFal lbackToRaster);
98 } 99 }
99 100
100 PassRefPtr<SkImage> RecordingImageBufferSurface::newImageSnapshot(AccelerationHi nt hint) 101 static RecordingImageBufferSurface::FallbackReason snapshotReasonToFallbackReaso n(SnapshotReason reason)
102 {
103 switch (reason) {
104 case SnapshotReasonUnknown:
105 return RecordingImageBufferSurface::FallbackReasonUnknown;
106 case SnapshotReasonGetImageData:
107 return RecordingImageBufferSurface::FallbackReasonSnapshotForGetImageDat a;
108 case SnapshotReasonCopyToWebGLTexture:
109 return RecordingImageBufferSurface::FallbackReasonSnapshotForCopyToWebGL Texture;
110 case SnapshotReasonPaint:
111 return RecordingImageBufferSurface::FallbackReasonSnapshotForPaint;
112 case SnapshotReasonToDataURL:
113 return RecordingImageBufferSurface::FallbackReasonSnapshotForToDataURL;
114 case SnapshotReasonToBlob:
115 return RecordingImageBufferSurface::FallbackReasonSnapshotForToBlob;
116 case SnapshotReasonCanvasListenerCapture:
117 return RecordingImageBufferSurface::FallbackReasonSnapshotForCanvasListe nerCapture;
118 case SnapshotReasonDrawImage:
119 return RecordingImageBufferSurface::FallbackReasonSnapshotForDrawImage;
120 case SnapshotReasonCreatePattern:
121 return RecordingImageBufferSurface::FallbackReasonSnapshotForCreatePatte rn;
122 }
123 ASSERT_NOT_REACHED();
124 return RecordingImageBufferSurface::FallbackReasonUnknown;
125 }
126
127 PassRefPtr<SkImage> RecordingImageBufferSurface::newImageSnapshot(AccelerationHi nt hint, SnapshotReason reason)
101 { 128 {
102 if (!m_fallbackSurface) 129 if (!m_fallbackSurface)
103 fallBackToRasterCanvas(); 130 fallBackToRasterCanvas(snapshotReasonToFallbackReason(reason));
104 return m_fallbackSurface->newImageSnapshot(hint); 131 return m_fallbackSurface->newImageSnapshot(hint, reason);
105 } 132 }
106 133
107 SkCanvas* RecordingImageBufferSurface::canvas() 134 SkCanvas* RecordingImageBufferSurface::canvas()
108 { 135 {
109 if (m_fallbackSurface) 136 if (m_fallbackSurface)
110 return m_fallbackSurface->canvas(); 137 return m_fallbackSurface->canvas();
111 138
112 ASSERT(m_currentFrame->getRecordingCanvas()); 139 ASSERT(m_currentFrame->getRecordingCanvas());
113 return m_currentFrame->getRecordingCanvas(); 140 return m_currentFrame->getRecordingCanvas();
114 } 141 }
115 142
116 void RecordingImageBufferSurface::disableDeferral() 143 static RecordingImageBufferSurface::FallbackReason disableDeferralReasonToFallba ckReason(DisableDeferralReason reason)
144 {
145 switch (reason) {
146 case DisableDeferralReasonUnknown:
147 return RecordingImageBufferSurface::FallbackReasonUnknown;
148 case DisableDeferralReasonExpensiveOverdrawHeuristic:
149 return RecordingImageBufferSurface::FallbackReasonExpensiveOverdrawHeuri stic;
150 case DisableDeferralReasonUsingTextureBackedPattern:
151 return RecordingImageBufferSurface::FallbackReasonTextureBackedPattern;
152 case DisableDeferralReasonDrawImageOfVideo:
153 return RecordingImageBufferSurface::FallbackReasonDrawImageOfVideo;
154 case DisableDeferralReasonDrawImageOfAnimated2dCanvas:
155 return RecordingImageBufferSurface::FallbackReasonDrawImageOfAnimated2dC anvas;
156 case DisableDeferralReasonSubPixelTextAntiAliasingSupport:
157 return RecordingImageBufferSurface::FallbackReasonSubPixelTextAntiAliasi ngSupport;
158 case DisableDeferralReasonCount:
159 ASSERT_NOT_REACHED();
160 break;
161 }
162 ASSERT_NOT_REACHED();
163 return RecordingImageBufferSurface::FallbackReasonUnknown;
164 }
165
166 void RecordingImageBufferSurface::disableDeferral(DisableDeferralReason reason)
117 { 167 {
118 if (!m_fallbackSurface) 168 if (!m_fallbackSurface)
119 fallBackToRasterCanvas(); 169 fallBackToRasterCanvas(disableDeferralReasonToFallbackReason(reason));
120 } 170 }
121 171
122 PassRefPtr<SkPicture> RecordingImageBufferSurface::getPicture() 172 PassRefPtr<SkPicture> RecordingImageBufferSurface::getPicture()
123 { 173 {
124 if (m_fallbackSurface) 174 if (m_fallbackSurface)
125 return nullptr; 175 return nullptr;
126 176
127 bool canUsePicture = finalizeFrameInternal(); 177 FallbackReason fallbackReason = FallbackReasonUnknown;
178 bool canUsePicture = finalizeFrameInternal(&fallbackReason);
128 m_imageBuffer->didFinalizeFrame(); 179 m_imageBuffer->didFinalizeFrame();
129 180
130 if (canUsePicture) { 181 if (canUsePicture) {
131 return m_previousFrame; 182 return m_previousFrame;
132 } 183 }
133 184
134 if (!m_fallbackSurface) 185 if (!m_fallbackSurface)
135 fallBackToRasterCanvas(); 186 fallBackToRasterCanvas(fallbackReason);
136 return nullptr; 187 return nullptr;
137 } 188 }
138 189
139 void RecordingImageBufferSurface::finalizeFrame(const FloatRect &dirtyRect) 190 void RecordingImageBufferSurface::finalizeFrame(const FloatRect &dirtyRect)
140 { 191 {
141 if (m_fallbackSurface) { 192 if (m_fallbackSurface) {
142 m_fallbackSurface->finalizeFrame(dirtyRect); 193 m_fallbackSurface->finalizeFrame(dirtyRect);
143 return; 194 return;
144 } 195 }
145 196
146 if (!finalizeFrameInternal()) 197 FallbackReason fallbackReason = FallbackReasonUnknown;
147 fallBackToRasterCanvas(); 198 if (!finalizeFrameInternal(&fallbackReason))
199 fallBackToRasterCanvas(fallbackReason);
148 } 200 }
149 201
150 void RecordingImageBufferSurface::flush() 202 static RecordingImageBufferSurface::FallbackReason flushReasonToFallbackReason(F lushReason reason)
203 {
204 switch (reason) {
205 case FlushReasonUnknown:
206 return RecordingImageBufferSurface::FallbackReasonUnknown;
207 case FlushReasonInitialClear:
208 return RecordingImageBufferSurface::FallbackReasonFlushInitialClear;
209 case FlushReasonDrawImageOfWebGL:
210 return RecordingImageBufferSurface::FallbackReasonFlushForDrawImageOfWeb GL;
211 }
212 ASSERT_NOT_REACHED();
213 return RecordingImageBufferSurface::FallbackReasonUnknown;
214 }
215
216 void RecordingImageBufferSurface::flush(FlushReason reason)
151 { 217 {
152 if (!m_fallbackSurface) 218 if (!m_fallbackSurface)
153 fallBackToRasterCanvas(); 219 fallBackToRasterCanvas(flushReasonToFallbackReason(reason));
154 m_fallbackSurface->flush(); 220 m_fallbackSurface->flush(reason);
155 } 221 }
156 222
157 void RecordingImageBufferSurface::willOverwriteCanvas() 223 void RecordingImageBufferSurface::willOverwriteCanvas()
158 { 224 {
159 m_frameWasCleared = true; 225 m_frameWasCleared = true;
160 m_previousFrame.clear(); 226 m_previousFrame.clear();
161 m_previousFrameHasExpensiveOp = false; 227 m_previousFrameHasExpensiveOp = false;
162 m_previousFramePixelCount = 0; 228 m_previousFramePixelCount = 0;
163 if (m_didRecordDrawCommandsInCurrentFrame) { 229 if (m_didRecordDrawCommandsInCurrentFrame) {
164 // Discard previous draw commands 230 // Discard previous draw commands
165 adoptRef(m_currentFrame->endRecording()); 231 adoptRef(m_currentFrame->endRecording());
166 initializeCurrentFrame(); 232 initializeCurrentFrame();
167 } 233 }
168 } 234 }
169 235
170 void RecordingImageBufferSurface::didDraw(const FloatRect& rect) 236 void RecordingImageBufferSurface::didDraw(const FloatRect& rect)
171 { 237 {
172 m_didRecordDrawCommandsInCurrentFrame = true; 238 m_didRecordDrawCommandsInCurrentFrame = true;
173 IntRect pixelBounds = enclosingIntRect(rect); 239 IntRect pixelBounds = enclosingIntRect(rect);
174 m_currentFramePixelCount += pixelBounds.width() * pixelBounds.height(); 240 m_currentFramePixelCount += pixelBounds.width() * pixelBounds.height();
175 } 241 }
176 242
177 bool RecordingImageBufferSurface::finalizeFrameInternal() 243 bool RecordingImageBufferSurface::finalizeFrameInternal(FallbackReason* fallback Reason)
178 { 244 {
179 ASSERT(!m_fallbackSurface); 245 ASSERT(!m_fallbackSurface);
180 ASSERT(m_currentFrame); 246 ASSERT(m_currentFrame);
181 ASSERT(m_currentFrame->getRecordingCanvas()); 247 ASSERT(m_currentFrame->getRecordingCanvas());
248 ASSERT(fallbackReason);
249 ASSERT(*fallbackReason == FallbackReasonUnknown);
182 250
183 if (!m_imageBuffer->isDirty()) { 251 if (!m_imageBuffer->isDirty()) {
184 if (!m_previousFrame) { 252 if (!m_previousFrame) {
185 // Create an initial blank frame 253 // Create an initial blank frame
186 m_previousFrame = adoptRef(m_currentFrame->endRecording()); 254 m_previousFrame = adoptRef(m_currentFrame->endRecording());
187 initializeCurrentFrame(); 255 initializeCurrentFrame();
188 } 256 }
189 return m_currentFrame; 257 return m_currentFrame;
190 } 258 }
191 259
192 if (!m_frameWasCleared || m_currentFrame->getRecordingCanvas()->getSaveCount () > ExpensiveCanvasHeuristicParameters::ExpensiveRecordingStackDepth) { 260 if (!m_frameWasCleared) {
261 *fallbackReason = FallbackReasonCanvasNotClearedBetweenFrames;
262 return false;
263 }
264
265 if (m_currentFrame->getRecordingCanvas()->getSaveCount() > ExpensiveCanvasHe uristicParameters::ExpensiveRecordingStackDepth) {
266 *fallbackReason = FallbackReasonRunawayStateStack;
193 return false; 267 return false;
194 } 268 }
195 269
196 m_previousFrame = adoptRef(m_currentFrame->endRecording()); 270 m_previousFrame = adoptRef(m_currentFrame->endRecording());
197 m_previousFrameHasExpensiveOp = m_currentFrameHasExpensiveOp; 271 m_previousFrameHasExpensiveOp = m_currentFrameHasExpensiveOp;
198 m_previousFramePixelCount = m_currentFramePixelCount; 272 m_previousFramePixelCount = m_currentFramePixelCount;
199 if (!initializeCurrentFrame()) 273 initializeCurrentFrame();
200 return false;
201 274
202 m_frameWasCleared = false; 275 m_frameWasCleared = false;
203 return true; 276 return true;
204 } 277 }
205 278
206 void RecordingImageBufferSurface::draw(GraphicsContext& context, const FloatRect & destRect, const FloatRect& srcRect, SkXfermode::Mode op) 279 void RecordingImageBufferSurface::draw(GraphicsContext& context, const FloatRect & destRect, const FloatRect& srcRect, SkXfermode::Mode op)
207 { 280 {
208 if (m_fallbackSurface) { 281 if (m_fallbackSurface) {
209 m_fallbackSurface->draw(context, destRect, srcRect, op); 282 m_fallbackSurface->draw(context, destRect, srcRect, op);
210 return; 283 return;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 343
271 void RecordingImageBufferSurface::setIsHidden(bool hidden) 344 void RecordingImageBufferSurface::setIsHidden(bool hidden)
272 { 345 {
273 if (m_fallbackSurface) 346 if (m_fallbackSurface)
274 m_fallbackSurface->setIsHidden(hidden); 347 m_fallbackSurface->setIsHidden(hidden);
275 else 348 else
276 ImageBufferSurface::setIsHidden(hidden); 349 ImageBufferSurface::setIsHidden(hidden);
277 } 350 }
278 351
279 } // namespace blink 352 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698