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

Side by Side Diff: Source/core/html/canvas/WebGLRenderingContextBase.cpp

Issue 363443002: Prevent garbage collection from deleting a context during its eviction. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « LayoutTests/TestExpectations ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 } 105 }
106 106
107 void WebGLRenderingContextBase::forciblyLoseOldestContext(const String& reason) 107 void WebGLRenderingContextBase::forciblyLoseOldestContext(const String& reason)
108 { 108 {
109 size_t candidateID = oldestContextIndex(); 109 size_t candidateID = oldestContextIndex();
110 if (candidateID >= activeContexts().size()) 110 if (candidateID >= activeContexts().size())
111 return; 111 return;
112 112
113 WebGLRenderingContextBase* candidate = activeContexts()[candidateID]; 113 WebGLRenderingContextBase* candidate = activeContexts()[candidateID];
114 114
115 // This context could belong to a dead page and the last JavaScript referenc e has already
116 // been lost. Garbage collection might be triggered in the middle of this fu nction, for
117 // example, printWarningToConsol() causes an upcall to JavaScript.
Ken Russell (switch to Gerrit) 2014/06/30 18:28:57 typo: printWarningToConsole
Zhenyao Mo 2014/07/02 22:45:23 Done.
118 // Must make sure that the context is not deleted until the call stack unwin ds.
119 RefPtr<WebGLRenderingContextBase> protect(candidate);
120
115 activeContexts().remove(candidateID); 121 activeContexts().remove(candidateID);
116 122
117 candidate->printWarningToConsole(reason); 123 candidate->printWarningToConsole(reason);
118 InspectorInstrumentation::didFireWebGLWarning(candidate->canvas()); 124 InspectorInstrumentation::didFireWebGLWarning(candidate->canvas());
119 125
120 // This will call deactivateContext once the context has actually been lost. 126 // This will call deactivateContext once the context has actually been lost.
121 candidate->forceLostContext(WebGLRenderingContextBase::SyntheticLostContext) ; 127 candidate->forceLostContext(WebGLRenderingContextBase::SyntheticLostContext) ;
122 } 128 }
123 129
124 size_t WebGLRenderingContextBase::oldestContextIndex() 130 size_t WebGLRenderingContextBase::oldestContextIndex()
(...skipping 4051 matching lines...) Expand 10 before | Expand all | Expand 10 after
4176 if (isContextLost()) { 4182 if (isContextLost()) {
4177 synthesizeGLError(GL_INVALID_OPERATION, "loseContext", "context already lost"); 4183 synthesizeGLError(GL_INVALID_OPERATION, "loseContext", "context already lost");
4178 return; 4184 return;
4179 } 4185 }
4180 4186
4181 m_contextGroup->loseContextGroup(mode); 4187 m_contextGroup->loseContextGroup(mode);
4182 } 4188 }
4183 4189
4184 void WebGLRenderingContextBase::loseContextImpl(WebGLRenderingContextBase::LostC ontextMode mode) 4190 void WebGLRenderingContextBase::loseContextImpl(WebGLRenderingContextBase::LostC ontextMode mode)
4185 { 4191 {
4186 #ifndef NDEBUG
4187 printWarningToConsole("loseContextImpl(): begin");
4188 #endif
4189
4190 if (isContextLost()) 4192 if (isContextLost())
4191 return; 4193 return;
4192 4194
4193 m_contextLost = true; 4195 m_contextLost = true;
4194 m_contextLostMode = mode; 4196 m_contextLostMode = mode;
4195 4197
4196 if (mode == RealLostContext) { 4198 if (mode == RealLostContext) {
4197 // Inform the embedder that a lost context was received. In response, th e embedder might 4199 // Inform the embedder that a lost context was received. In response, th e embedder might
4198 // decide to take action such as asking the user for permission to use W ebGL again. 4200 // decide to take action such as asking the user for permission to use W ebGL again.
4199 if (LocalFrame* frame = canvas()->document().frame()) 4201 if (LocalFrame* frame = canvas()->document().frame())
4200 frame->loader().client()->didLoseWebGLContext(webContext()->getGraph icsResetStatusARB()); 4202 frame->loader().client()->didLoseWebGLContext(webContext()->getGraph icsResetStatusARB());
4201 } 4203 }
4202 4204
4203 // Make absolutely sure we do not refer to an already-deleted texture or fra mebuffer. 4205 // Make absolutely sure we do not refer to an already-deleted texture or fra mebuffer.
4204 m_drawingBuffer->setTexture2DBinding(0); 4206 m_drawingBuffer->setTexture2DBinding(0);
4205 m_drawingBuffer->setFramebufferBinding(0); 4207 m_drawingBuffer->setFramebufferBinding(0);
4206 4208
4207 detachAndRemoveAllObjects(); 4209 detachAndRemoveAllObjects();
4208 4210
4209 #ifndef NDEBUG
4210 printWarningToConsole("loseContextImpl(): after detachAndRemoveAllObjects()" );
4211 #endif
4212
4213 // Lose all the extensions. 4211 // Lose all the extensions.
4214 for (size_t i = 0; i < m_extensions.size(); ++i) { 4212 for (size_t i = 0; i < m_extensions.size(); ++i) {
4215 ExtensionTracker* tracker = m_extensions[i]; 4213 ExtensionTracker* tracker = m_extensions[i];
4216 tracker->loseExtension(); 4214 tracker->loseExtension();
4217 } 4215 }
4218 4216
4219 for (size_t i = 0; i < WebGLExtensionNameCount; ++i) 4217 for (size_t i = 0; i < WebGLExtensionNameCount; ++i)
4220 m_extensionEnabled[i] = false; 4218 m_extensionEnabled[i] = false;
4221 4219
4222 removeAllCompressedTextureFormats(); 4220 removeAllCompressedTextureFormats();
4223 4221
4224 if (mode != RealLostContext) 4222 if (mode != RealLostContext)
4225 destroyContext(); 4223 destroyContext();
4226 4224
4227 #ifndef NDEBUG
4228 printWarningToConsole("loseContextImpl(): after destroyContext()");
4229 #endif
4230
4231 ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInCons ole: DontDisplayInConsole; 4225 ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInCons ole: DontDisplayInConsole;
4232 synthesizeGLError(GC3D_CONTEXT_LOST_WEBGL, "loseContext", "context lost", di splay); 4226 synthesizeGLError(GC3D_CONTEXT_LOST_WEBGL, "loseContext", "context lost", di splay);
4233 4227
4234 // Don't allow restoration unless the context lost event has both been 4228 // Don't allow restoration unless the context lost event has both been
4235 // dispatched and its default behavior prevented. 4229 // dispatched and its default behavior prevented.
4236 m_restoreAllowed = false; 4230 m_restoreAllowed = false;
4237 4231
4238 // Always defer the dispatch of the context lost event, to implement 4232 // Always defer the dispatch of the context lost event, to implement
4239 // the spec behavior of queueing a task. 4233 // the spec behavior of queueing a task.
4240 m_dispatchContextLostEventTimer.startOneShot(0, FROM_HERE); 4234 m_dispatchContextLostEventTimer.startOneShot(0, FROM_HERE);
4241
4242 #ifndef NDEBUG
4243 printWarningToConsole("loseContextImpl(): end");
4244 #endif
4245 } 4235 }
4246 4236
4247 void WebGLRenderingContextBase::forceRestoreContext() 4237 void WebGLRenderingContextBase::forceRestoreContext()
4248 { 4238 {
4249 if (!isContextLost()) { 4239 if (!isContextLost()) {
4250 synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context not l ost"); 4240 synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context not l ost");
4251 return; 4241 return;
4252 } 4242 }
4253 4243
4254 if (!m_restoreAllowed) { 4244 if (!m_restoreAllowed) {
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after
5454 RefPtrWillBeRawPtr<WebGLContextEvent> event = WebGLContextEvent::create(Even tTypeNames::webglcontextlost, false, true, ""); 5444 RefPtrWillBeRawPtr<WebGLContextEvent> event = WebGLContextEvent::create(Even tTypeNames::webglcontextlost, false, true, "");
5455 canvas()->dispatchEvent(event); 5445 canvas()->dispatchEvent(event);
5456 m_restoreAllowed = event->defaultPrevented(); 5446 m_restoreAllowed = event->defaultPrevented();
5457 deactivateContext(this, m_contextLostMode != RealLostContext && m_restoreAll owed); 5447 deactivateContext(this, m_contextLostMode != RealLostContext && m_restoreAll owed);
5458 if ((m_contextLostMode == RealLostContext || m_contextLostMode == AutoRecove rSyntheticLostContext) && m_restoreAllowed) 5448 if ((m_contextLostMode == RealLostContext || m_contextLostMode == AutoRecove rSyntheticLostContext) && m_restoreAllowed)
5459 m_restoreTimer.startOneShot(0, FROM_HERE); 5449 m_restoreTimer.startOneShot(0, FROM_HERE);
5460 } 5450 }
5461 5451
5462 void WebGLRenderingContextBase::maybeRestoreContext(Timer<WebGLRenderingContextB ase>*) 5452 void WebGLRenderingContextBase::maybeRestoreContext(Timer<WebGLRenderingContextB ase>*)
5463 { 5453 {
5464 #ifndef NDEBUG
5465 printWarningToConsole("maybeRestoreContext(): begin");
5466 #endif
5467 ASSERT(isContextLost()); 5454 ASSERT(isContextLost());
5468 5455
5469 // The rendering context is not restored unless the default behavior of the 5456 // The rendering context is not restored unless the default behavior of the
5470 // webglcontextlost event was prevented earlier. 5457 // webglcontextlost event was prevented earlier.
5471 // 5458 //
5472 // Because of the way m_restoreTimer is set up for real vs. synthetic lost 5459 // Because of the way m_restoreTimer is set up for real vs. synthetic lost
5473 // context events, we don't have to worry about this test short-circuiting 5460 // context events, we don't have to worry about this test short-circuiting
5474 // the retry loop for real context lost events. 5461 // the retry loop for real context lost events.
5475 if (!m_restoreAllowed) 5462 if (!m_restoreAllowed)
5476 return; 5463 return;
5477 5464
5478 LocalFrame* frame = canvas()->document().frame(); 5465 LocalFrame* frame = canvas()->document().frame();
5479 if (!frame) 5466 if (!frame)
5480 return; 5467 return;
5481 5468
5482 Settings* settings = frame->settings(); 5469 Settings* settings = frame->settings();
5483 5470
5484 if (!frame->loader().client()->allowWebGL(settings && settings->webGLEnabled ())) 5471 if (!frame->loader().client()->allowWebGL(settings && settings->webGLEnabled ()))
5485 return; 5472 return;
5486 5473
5487 // If the context was lost due to RealLostContext, we need to destroy the ol d DrawingBuffer before creating new DrawingBuffer to ensure resource budget enou gh. 5474 // If the context was lost due to RealLostContext, we need to destroy the ol d DrawingBuffer before creating new DrawingBuffer to ensure resource budget enou gh.
5488 if (m_drawingBuffer) { 5475 if (m_drawingBuffer) {
5489 m_drawingBuffer->beginDestruction(); 5476 m_drawingBuffer->beginDestruction();
5490 m_drawingBuffer.clear(); 5477 m_drawingBuffer.clear();
5491 } 5478 }
5492 #ifndef NDEBUG
5493 printWarningToConsole("maybeRestoreContext(): destroyed old DrawingBuffer");
5494 #endif
5495 5479
5496 blink::WebGraphicsContext3D::Attributes attributes = m_requestedAttributes-> attributes(canvas()->document().topDocument().url().string(), settings); 5480 blink::WebGraphicsContext3D::Attributes attributes = m_requestedAttributes-> attributes(canvas()->document().topDocument().url().string(), settings);
5497 OwnPtr<blink::WebGraphicsContext3D> context = adoptPtr(blink::Platform::curr ent()->createOffscreenGraphicsContext3D(attributes, 0)); 5481 OwnPtr<blink::WebGraphicsContext3D> context = adoptPtr(blink::Platform::curr ent()->createOffscreenGraphicsContext3D(attributes, 0));
5498 RefPtr<DrawingBuffer> drawingBuffer; 5482 RefPtr<DrawingBuffer> drawingBuffer;
5499 // Even if a non-null WebGraphicsContext3D is created, until it's made curre nt, it isn't known whether the context is still lost. 5483 // Even if a non-null WebGraphicsContext3D is created, until it's made curre nt, it isn't known whether the context is still lost.
5500 if (context) { 5484 if (context) {
5501 // Construct a new drawing buffer with the new WebGraphicsContext3D. 5485 // Construct a new drawing buffer with the new WebGraphicsContext3D.
5502 drawingBuffer = createDrawingBuffer(context.release()); 5486 drawingBuffer = createDrawingBuffer(context.release());
5503 // If DrawingBuffer::create() fails to allocate a fbo, |drawingBuffer| i s set to null. 5487 // If DrawingBuffer::create() fails to allocate a fbo, |drawingBuffer| i s set to null.
5504 } 5488 }
5505 if (!drawingBuffer) { 5489 if (!drawingBuffer) {
5506 if (m_contextLostMode == RealLostContext) { 5490 if (m_contextLostMode == RealLostContext) {
5507 m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts, FROM_HERE ); 5491 m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts, FROM_HERE );
5508 } else { 5492 } else {
5509 // This likely shouldn't happen but is the best way to report it to the WebGL app. 5493 // This likely shouldn't happen but is the best way to report it to the WebGL app.
5510 synthesizeGLError(GL_INVALID_OPERATION, "", "error restoring context "); 5494 synthesizeGLError(GL_INVALID_OPERATION, "", "error restoring context ");
5511 } 5495 }
5512 return; 5496 return;
5513 } 5497 }
5514 #ifndef NDEBUG
5515 printWarningToConsole("maybeRestoreContext(): created new DrawingBuffer");
5516 #endif
5517 5498
5518 m_drawingBuffer = drawingBuffer.release(); 5499 m_drawingBuffer = drawingBuffer.release();
5519 m_drawingBuffer->bind(); 5500 m_drawingBuffer->bind();
5520 m_lostContextErrors.clear(); 5501 m_lostContextErrors.clear();
5521 m_contextLost = false; 5502 m_contextLost = false;
5522 5503
5523 setupFlags(); 5504 setupFlags();
5524 initializeNewContext(); 5505 initializeNewContext();
5525 markContextChanged(CanvasContextChanged); 5506 markContextChanged(CanvasContextChanged);
5526 #ifndef NDEBUG
5527 printWarningToConsole("maybeRestoreContext(): before dispatchEvent");
5528 #endif
5529 canvas()->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglconte xtrestored, false, true, "")); 5507 canvas()->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglconte xtrestored, false, true, ""));
5530 #ifndef NDEBUG
5531 printWarningToConsole("maybeRestoreContext(): end");
5532 #endif
5533 } 5508 }
5534 5509
5535 String WebGLRenderingContextBase::ensureNotNull(const String& text) const 5510 String WebGLRenderingContextBase::ensureNotNull(const String& text) const
5536 { 5511 {
5537 if (text.isNull()) 5512 if (text.isNull())
5538 return WTF::emptyString(); 5513 return WTF::emptyString();
5539 return text; 5514 return text;
5540 } 5515 }
5541 5516
5542 WebGLRenderingContextBase::LRUImageBufferCache::LRUImageBufferCache(int capacity ) 5517 WebGLRenderingContextBase::LRUImageBufferCache::LRUImageBufferCache(int capacity )
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
5719 if (m_textureUnits[i].m_texture2DBinding 5694 if (m_textureUnits[i].m_texture2DBinding
5720 || m_textureUnits[i].m_textureCubeMapBinding) { 5695 || m_textureUnits[i].m_textureCubeMapBinding) {
5721 m_onePlusMaxNonDefaultTextureUnit = i + 1; 5696 m_onePlusMaxNonDefaultTextureUnit = i + 1;
5722 return; 5697 return;
5723 } 5698 }
5724 } 5699 }
5725 m_onePlusMaxNonDefaultTextureUnit = 0; 5700 m_onePlusMaxNonDefaultTextureUnit = 0;
5726 } 5701 }
5727 5702
5728 } // namespace WebCore 5703 } // namespace WebCore
OLDNEW
« no previous file with comments | « LayoutTests/TestExpectations ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698