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

Side by Side Diff: third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2D.cpp

Issue 2057283002: Fix canvas-related crash caused by bad object teardown sequence (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix test crash Created 4 years, 6 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 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) 3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies)
4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 4 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> 5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> 6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org>
7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. 7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
8 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved. 8 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved.
9 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. 9 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
10 * 10 *
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 void CanvasRenderingContext2D::unwindStateStack() 134 void CanvasRenderingContext2D::unwindStateStack()
135 { 135 {
136 if (size_t stackSize = m_stateStack.size()) { 136 if (size_t stackSize = m_stateStack.size()) {
137 if (SkCanvas* skCanvas = canvas()->existingDrawingCanvas()) { 137 if (SkCanvas* skCanvas = canvas()->existingDrawingCanvas()) {
138 while (--stackSize) 138 while (--stackSize)
139 skCanvas->restore(); 139 skCanvas->restore();
140 } 140 }
141 } 141 }
142 } 142 }
143 143
144 CanvasRenderingContext2D::~CanvasRenderingContext2D() 144 CanvasRenderingContext2D::~CanvasRenderingContext2D() { }
145 {
146 }
147 145
148 void CanvasRenderingContext2D::dispose() 146 void CanvasRenderingContext2D::dispose()
149 { 147 {
150 if (m_pruneLocalFontCacheScheduled) 148 if (m_pruneLocalFontCacheScheduled)
151 Platform::current()->currentThread()->removeTaskObserver(this); 149 Platform::current()->currentThread()->removeTaskObserver(this);
152 } 150 }
153 151
154 void CanvasRenderingContext2D::validateStateStack() 152 void CanvasRenderingContext2D::validateStateStack()
155 { 153 {
156 #if ENABLE(ASSERT) 154 #if ENABLE(ASSERT)
(...skipping 22 matching lines...) Expand all
179 bool CanvasRenderingContext2D::isContextLost() const 177 bool CanvasRenderingContext2D::isContextLost() const
180 { 178 {
181 return m_contextLostMode != NotLostContext; 179 return m_contextLostMode != NotLostContext;
182 } 180 }
183 181
184 void CanvasRenderingContext2D::loseContext(LostContextMode lostMode) 182 void CanvasRenderingContext2D::loseContext(LostContextMode lostMode)
185 { 183 {
186 if (m_contextLostMode != NotLostContext) 184 if (m_contextLostMode != NotLostContext)
187 return; 185 return;
188 m_contextLostMode = lostMode; 186 m_contextLostMode = lostMode;
189 if (m_contextLostMode == SyntheticLostContext) { 187 if (m_contextLostMode == SyntheticLostContext && canvas()) {
190 canvas()->discardImageBuffer(); 188 canvas()->discardImageBuffer();
191 } 189 }
192 m_dispatchContextLostEventTimer.startOneShot(0, BLINK_FROM_HERE); 190 m_dispatchContextLostEventTimer.startOneShot(0, BLINK_FROM_HERE);
193 } 191 }
194 192
195 void CanvasRenderingContext2D::didSetSurfaceSize() 193 void CanvasRenderingContext2D::didSetSurfaceSize()
196 { 194 {
197 if (!m_contextRestorable) 195 if (!m_contextRestorable)
198 return; 196 return;
199 // This code path is for restoring from an eviction 197 // This code path is for restoring from an eviction
(...skipping 14 matching lines...) Expand all
214 DEFINE_TRACE(CanvasRenderingContext2D) 212 DEFINE_TRACE(CanvasRenderingContext2D)
215 { 213 {
216 visitor->trace(m_hitRegionManager); 214 visitor->trace(m_hitRegionManager);
217 CanvasRenderingContext::trace(visitor); 215 CanvasRenderingContext::trace(visitor);
218 BaseRenderingContext2D::trace(visitor); 216 BaseRenderingContext2D::trace(visitor);
219 SVGResourceClient::trace(visitor); 217 SVGResourceClient::trace(visitor);
220 } 218 }
221 219
222 void CanvasRenderingContext2D::dispatchContextLostEvent(Timer<CanvasRenderingCon text2D>*) 220 void CanvasRenderingContext2D::dispatchContextLostEvent(Timer<CanvasRenderingCon text2D>*)
223 { 221 {
224 if (contextLostRestoredEventsEnabled()) { 222 if (canvas() && contextLostRestoredEventsEnabled()) {
225 Event* event = Event::createCancelable(EventTypeNames::contextlost); 223 Event* event = Event::createCancelable(EventTypeNames::contextlost);
226 canvas()->dispatchEvent(event); 224 canvas()->dispatchEvent(event);
227 if (event->defaultPrevented()) { 225 if (event->defaultPrevented()) {
228 m_contextRestorable = false; 226 m_contextRestorable = false;
229 } 227 }
230 } 228 }
231 229
232 // If RealLostContext, it means the context was not lost due to surface fail ure 230 // If RealLostContext, it means the context was not lost due to surface fail ure
233 // but rather due to a an eviction, which means image buffer exists. 231 // but rather due to a an eviction, which means image buffer exists.
234 if (m_contextRestorable && m_contextLostMode == RealLostContext) { 232 if (m_contextRestorable && m_contextLostMode == RealLostContext) {
235 m_tryRestoreContextAttemptCount = 0; 233 m_tryRestoreContextAttemptCount = 0;
236 m_tryRestoreContextEventTimer.startRepeating(TryRestoreContextInterval, BLINK_FROM_HERE); 234 m_tryRestoreContextEventTimer.startRepeating(TryRestoreContextInterval, BLINK_FROM_HERE);
237 } 235 }
238 } 236 }
239 237
240 void CanvasRenderingContext2D::tryRestoreContextEvent(Timer<CanvasRenderingConte xt2D>* timer) 238 void CanvasRenderingContext2D::tryRestoreContextEvent(Timer<CanvasRenderingConte xt2D>* timer)
241 { 239 {
242 if (m_contextLostMode == NotLostContext) { 240 if (m_contextLostMode == NotLostContext) {
243 // Canvas was already restored (possibly thanks to a resize), so stop tr ying. 241 // Canvas was already restored (possibly thanks to a resize), so stop tr ying.
244 m_tryRestoreContextEventTimer.stop(); 242 m_tryRestoreContextEventTimer.stop();
245 return; 243 return;
246 } 244 }
247 245
248 ASSERT(m_contextLostMode == RealLostContext); 246 DCHECK(m_contextLostMode == RealLostContext);
249 if (canvas()->hasImageBuffer() && canvas()->buffer()->restoreSurface()) { 247 if (canvas()->hasImageBuffer() && canvas()->buffer()->restoreSurface()) {
250 m_tryRestoreContextEventTimer.stop(); 248 m_tryRestoreContextEventTimer.stop();
251 dispatchContextRestoredEvent(nullptr); 249 dispatchContextRestoredEvent(nullptr);
252 } 250 }
253 251
254 if (++m_tryRestoreContextAttemptCount > MaxTryRestoreContextAttempts) { 252 if (++m_tryRestoreContextAttemptCount > MaxTryRestoreContextAttempts) {
255 // final attempt: allocate a brand new image buffer instead of restoring 253 // final attempt: allocate a brand new image buffer instead of restoring
256 canvas()->discardImageBuffer(); 254 canvas()->discardImageBuffer();
257 m_tryRestoreContextEventTimer.stop(); 255 m_tryRestoreContextEventTimer.stop();
258 if (canvas()->buffer()) 256 if (canvas()->buffer())
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 void CanvasRenderingContext2D::schedulePruneLocalFontCacheIfNeeded() 503 void CanvasRenderingContext2D::schedulePruneLocalFontCacheIfNeeded()
506 { 504 {
507 if (m_pruneLocalFontCacheScheduled) 505 if (m_pruneLocalFontCacheScheduled)
508 return; 506 return;
509 m_pruneLocalFontCacheScheduled = true; 507 m_pruneLocalFontCacheScheduled = true;
510 Platform::current()->currentThread()->addTaskObserver(this); 508 Platform::current()->currentThread()->addTaskObserver(this);
511 } 509 }
512 510
513 void CanvasRenderingContext2D::didProcessTask() 511 void CanvasRenderingContext2D::didProcessTask()
514 { 512 {
513 Platform::current()->currentThread()->removeTaskObserver(this);
514
515 // This should be the only place where canvas() needs to be checked for null ness
516 // because the circular refence with HTMLCanvasElement mean the canvas and t he
517 // context keep each other alive as long as the pair is referenced the task
518 // observer is the only persisten refernce to this object that is not traced ,
519 // so didProcessTask() may be call at a time when the canvas has been garbag e
520 // collected but not the context.
521 if (!canvas())
522 return;
523
515 // The rendering surface needs to be prepared now because it will be too lat e 524 // The rendering surface needs to be prepared now because it will be too lat e
516 // to create a layer once we are in the paint invalidation phase. 525 // to create a layer once we are in the paint invalidation phase.
517 canvas()->prepareSurfaceForPaintingIfNeeded(); 526 canvas()->prepareSurfaceForPaintingIfNeeded();
518 527
519 pruneLocalFontCache(canvas()->document().canvasFontCache()->maxFonts()); 528 pruneLocalFontCache(canvas()->document().canvasFontCache()->maxFonts());
520 m_pruneLocalFontCacheScheduled = false; 529 m_pruneLocalFontCacheScheduled = false;
521 Platform::current()->currentThread()->removeTaskObserver(this);
522 } 530 }
523 531
524 void CanvasRenderingContext2D::pruneLocalFontCache(size_t targetSize) 532 void CanvasRenderingContext2D::pruneLocalFontCache(size_t targetSize)
525 { 533 {
526 if (targetSize == 0) { 534 if (targetSize == 0) {
527 // Short cut: LRU does not matter when evicting everything 535 // Short cut: LRU does not matter when evicting everything
528 m_fontLRUList.clear(); 536 m_fontLRUList.clear();
529 m_fontsResolvedUsingCurrentStyle.clear(); 537 m_fontsResolvedUsingCurrentStyle.clear();
530 return; 538 return;
531 } 539 }
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 1058
1051 unsigned CanvasRenderingContext2D::hitRegionsCount() const 1059 unsigned CanvasRenderingContext2D::hitRegionsCount() const
1052 { 1060 {
1053 if (m_hitRegionManager) 1061 if (m_hitRegionManager)
1054 return m_hitRegionManager->getHitRegionsCount(); 1062 return m_hitRegionManager->getHitRegionsCount();
1055 1063
1056 return 0; 1064 return 0;
1057 } 1065 }
1058 1066
1059 } // namespace blink 1067 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698