| OLD | NEW |
| 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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 | 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 | 116 // been lost. Garbage collection might be triggered in the middle of this fu
nction, for |
| 117 // example, printWarningToConsole() causes an upcall to JavaScript. | 117 // example, printWarningToConsole() causes an upcall to JavaScript. |
| 118 // Must make sure that the context is not deleted until the call stack unwin
ds. | 118 // Must make sure that the context is not deleted until the call stack unwin
ds. |
| 119 RefPtrWillBeRawPtr<WebGLRenderingContextBase> protect(candidate); | 119 RefPtrWillBeRawPtr<WebGLRenderingContextBase> protect(candidate); |
| 120 | 120 |
| 121 activeContexts().remove(candidateID); | |
| 122 | |
| 123 candidate->printWarningToConsole(reason); | 121 candidate->printWarningToConsole(reason); |
| 124 InspectorInstrumentation::didFireWebGLWarning(candidate->canvas()); | 122 InspectorInstrumentation::didFireWebGLWarning(candidate->canvas()); |
| 125 | 123 |
| 126 // This will call deactivateContext once the context has actually been lost. | 124 // This will call deactivateContext once the context has actually been lost. |
| 127 candidate->forceLostContext(WebGLRenderingContextBase::SyntheticLostContext)
; | 125 candidate->forceLostContext(WebGLRenderingContextBase::SyntheticLostContext)
; |
| 128 } | 126 } |
| 129 | 127 |
| 130 size_t WebGLRenderingContextBase::oldestContextIndex() | 128 size_t WebGLRenderingContextBase::oldestContextIndex() |
| 131 { | 129 { |
| 132 if (!activeContexts().size()) | 130 if (!activeContexts().size()) |
| 133 return maxGLActiveContexts; | 131 return maxGLActiveContexts; |
| 134 | 132 |
| 135 WebGLRenderingContextBase* candidate = activeContexts().first(); | 133 WebGLRenderingContextBase* candidate = activeContexts().first(); |
| 136 blink::WebGraphicsContext3D* candidateWGC3D = candidate->isContextLost() ? 0
: candidate->webContext(); | 134 ASSERT(!candidate->isContextLost()); |
| 137 size_t candidateID = 0; | 135 size_t candidateID = 0; |
| 138 for (size_t ii = 1; ii < activeContexts().size(); ++ii) { | 136 for (size_t ii = 1; ii < activeContexts().size(); ++ii) { |
| 139 WebGLRenderingContextBase* context = activeContexts()[ii]; | 137 WebGLRenderingContextBase* context = activeContexts()[ii]; |
| 140 blink::WebGraphicsContext3D* contextWGC3D = context->isContextLost() ? 0
: context->webContext(); | 138 ASSERT(!context->isContextLost()); |
| 141 if (contextWGC3D && candidateWGC3D && contextWGC3D->lastFlushID() < cand
idateWGC3D->lastFlushID()) { | 139 if (context->webContext()->lastFlushID() < candidate->webContext()->last
FlushID()) { |
| 142 candidate = context; | 140 candidate = context; |
| 143 candidateID = ii; | 141 candidateID = ii; |
| 144 } | 142 } |
| 145 } | 143 } |
| 146 | 144 |
| 147 return candidateID; | 145 return candidateID; |
| 148 } | 146 } |
| 149 | 147 |
| 150 IntSize WebGLRenderingContextBase::oldestContextSize() | 148 IntSize WebGLRenderingContextBase::oldestContextSize() |
| 151 { | 149 { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 162 } | 160 } |
| 163 | 161 |
| 164 void WebGLRenderingContextBase::activateContext(WebGLRenderingContextBase* conte
xt) | 162 void WebGLRenderingContextBase::activateContext(WebGLRenderingContextBase* conte
xt) |
| 165 { | 163 { |
| 166 unsigned removedContexts = 0; | 164 unsigned removedContexts = 0; |
| 167 while (activeContexts().size() >= maxGLActiveContexts && removedContexts < m
axGLActiveContexts) { | 165 while (activeContexts().size() >= maxGLActiveContexts && removedContexts < m
axGLActiveContexts) { |
| 168 forciblyLoseOldestContext("WARNING: Too many active WebGL contexts. Olde
st context will be lost."); | 166 forciblyLoseOldestContext("WARNING: Too many active WebGL contexts. Olde
st context will be lost."); |
| 169 removedContexts++; | 167 removedContexts++; |
| 170 } | 168 } |
| 171 | 169 |
| 170 ASSERT(!context->isContextLost()); |
| 172 if (!activeContexts().contains(context)) | 171 if (!activeContexts().contains(context)) |
| 173 activeContexts().append(context); | 172 activeContexts().append(context); |
| 174 } | 173 } |
| 175 | 174 |
| 176 void WebGLRenderingContextBase::deactivateContext(WebGLRenderingContextBase* con
text, bool addToEvictedList) | 175 void WebGLRenderingContextBase::deactivateContext(WebGLRenderingContextBase* con
text) |
| 177 { | 176 { |
| 178 size_t position = activeContexts().find(context); | 177 size_t position = activeContexts().find(context); |
| 179 if (position != WTF::kNotFound) | 178 if (position != WTF::kNotFound) |
| 180 activeContexts().remove(position); | 179 activeContexts().remove(position); |
| 180 } |
| 181 | 181 |
| 182 if (addToEvictedList && !forciblyEvictedContexts().contains(context)) | 182 void WebGLRenderingContextBase::addToEvictedList(WebGLRenderingContextBase* cont
ext) |
| 183 { |
| 184 ASSERT(context->m_restoreAllowed); |
| 185 if (!forciblyEvictedContexts().contains(context)) |
| 183 forciblyEvictedContexts().append(context); | 186 forciblyEvictedContexts().append(context); |
| 184 } | 187 } |
| 185 | 188 |
| 186 void WebGLRenderingContextBase::willDestroyContext(WebGLRenderingContextBase* co
ntext) | 189 void WebGLRenderingContextBase::willDestroyContext(WebGLRenderingContextBase* co
ntext) |
| 187 { | 190 { |
| 188 size_t position = forciblyEvictedContexts().find(context); | 191 size_t position = forciblyEvictedContexts().find(context); |
| 189 if (position != WTF::kNotFound) | 192 if (position != WTF::kNotFound) |
| 190 forciblyEvictedContexts().remove(position); | 193 forciblyEvictedContexts().remove(position); |
| 191 | 194 |
| 192 deactivateContext(context, false); | 195 deactivateContext(context); |
| 193 | 196 |
| 194 // Try to re-enable the oldest inactive contexts. | 197 // Try to re-enable the oldest inactive contexts. |
| 195 while(activeContexts().size() < maxGLActiveContexts && forciblyEvictedContex
ts().size()) { | 198 while(activeContexts().size() < maxGLActiveContexts && forciblyEvictedContex
ts().size()) { |
| 196 WebGLRenderingContextBase* evictedContext = forciblyEvictedContexts().fi
rst(); | 199 WebGLRenderingContextBase* evictedContext = forciblyEvictedContexts().fi
rst(); |
| 197 if (!evictedContext->m_restoreAllowed) { | 200 ASSERT(evictedContext->m_restoreAllowed); |
| 198 forciblyEvictedContexts().remove(0); | |
| 199 continue; | |
| 200 } | |
| 201 | |
| 202 IntSize desiredSize = DrawingBuffer::adjustSize(evictedContext->clampedC
anvasSize(), IntSize(), evictedContext->m_maxTextureSize); | 201 IntSize desiredSize = DrawingBuffer::adjustSize(evictedContext->clampedC
anvasSize(), IntSize(), evictedContext->m_maxTextureSize); |
| 203 | 202 |
| 204 // If there's room in the pixel budget for this context, restore it. | 203 // If there's room in the pixel budget for this context, restore it. |
| 205 if (!desiredSize.isEmpty()) { | 204 if (!desiredSize.isEmpty()) { |
| 206 forciblyEvictedContexts().remove(0); | 205 forciblyEvictedContexts().remove(0); |
| 207 evictedContext->forceRestoreContext(); | 206 evictedContext->forceRestoreContext(); |
| 208 activeContexts().append(evictedContext); | |
| 209 } | 207 } |
| 210 break; | 208 break; |
| 211 } | 209 } |
| 212 } | 210 } |
| 213 | 211 |
| 214 class WebGLRenderingContextEvictionManager : public ContextEvictionManager { | 212 class WebGLRenderingContextEvictionManager : public ContextEvictionManager { |
| 215 public: | 213 public: |
| 216 void forciblyLoseOldestContext(const String& reason) { | 214 void forciblyLoseOldestContext(const String& reason) { |
| 217 WebGLRenderingContextBase::forciblyLoseOldestContext(reason); | 215 WebGLRenderingContextBase::forciblyLoseOldestContext(reason); |
| 218 }; | 216 }; |
| (...skipping 4002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4221 | 4219 |
| 4222 if (mode != RealLostContext) | 4220 if (mode != RealLostContext) |
| 4223 destroyContext(); | 4221 destroyContext(); |
| 4224 | 4222 |
| 4225 ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInCons
ole: DontDisplayInConsole; | 4223 ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInCons
ole: DontDisplayInConsole; |
| 4226 synthesizeGLError(GC3D_CONTEXT_LOST_WEBGL, "loseContext", "context lost", di
splay); | 4224 synthesizeGLError(GC3D_CONTEXT_LOST_WEBGL, "loseContext", "context lost", di
splay); |
| 4227 | 4225 |
| 4228 // Don't allow restoration unless the context lost event has both been | 4226 // Don't allow restoration unless the context lost event has both been |
| 4229 // dispatched and its default behavior prevented. | 4227 // dispatched and its default behavior prevented. |
| 4230 m_restoreAllowed = false; | 4228 m_restoreAllowed = false; |
| 4229 deactivateContext(this); |
| 4231 | 4230 |
| 4232 // Always defer the dispatch of the context lost event, to implement | 4231 // Always defer the dispatch of the context lost event, to implement |
| 4233 // the spec behavior of queueing a task. | 4232 // the spec behavior of queueing a task. |
| 4234 m_dispatchContextLostEventTimer.startOneShot(0, FROM_HERE); | 4233 m_dispatchContextLostEventTimer.startOneShot(0, FROM_HERE); |
| 4235 } | 4234 } |
| 4236 | 4235 |
| 4237 void WebGLRenderingContextBase::forceRestoreContext() | 4236 void WebGLRenderingContextBase::forceRestoreContext() |
| 4238 { | 4237 { |
| 4239 if (!isContextLost()) { | 4238 if (!isContextLost()) { |
| 4240 synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context not l
ost"); | 4239 synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context not l
ost"); |
| (...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5437 attribValue.initValue(); | 5436 attribValue.initValue(); |
| 5438 for (int ii = 0; ii < expectedSize; ++ii) | 5437 for (int ii = 0; ii < expectedSize; ++ii) |
| 5439 attribValue.value[ii] = v[ii]; | 5438 attribValue.value[ii] = v[ii]; |
| 5440 } | 5439 } |
| 5441 | 5440 |
| 5442 void WebGLRenderingContextBase::dispatchContextLostEvent(Timer<WebGLRenderingCon
textBase>*) | 5441 void WebGLRenderingContextBase::dispatchContextLostEvent(Timer<WebGLRenderingCon
textBase>*) |
| 5443 { | 5442 { |
| 5444 RefPtrWillBeRawPtr<WebGLContextEvent> event = WebGLContextEvent::create(Even
tTypeNames::webglcontextlost, false, true, ""); | 5443 RefPtrWillBeRawPtr<WebGLContextEvent> event = WebGLContextEvent::create(Even
tTypeNames::webglcontextlost, false, true, ""); |
| 5445 canvas()->dispatchEvent(event); | 5444 canvas()->dispatchEvent(event); |
| 5446 m_restoreAllowed = event->defaultPrevented(); | 5445 m_restoreAllowed = event->defaultPrevented(); |
| 5447 deactivateContext(this, m_contextLostMode != RealLostContext && m_restoreAll
owed); | 5446 if (m_restoreAllowed) { |
| 5448 if ((m_contextLostMode == RealLostContext || m_contextLostMode == AutoRecove
rSyntheticLostContext) && m_restoreAllowed) | 5447 if ((m_contextLostMode == RealLostContext || m_contextLostMode == AutoRe
coverSyntheticLostContext)) { |
| 5449 m_restoreTimer.startOneShot(0, FROM_HERE); | 5448 m_restoreTimer.startOneShot(0, FROM_HERE); |
| 5449 } else { |
| 5450 addToEvictedList(this); |
| 5451 } |
| 5452 } |
| 5450 } | 5453 } |
| 5451 | 5454 |
| 5452 void WebGLRenderingContextBase::maybeRestoreContext(Timer<WebGLRenderingContextB
ase>*) | 5455 void WebGLRenderingContextBase::maybeRestoreContext(Timer<WebGLRenderingContextB
ase>*) |
| 5453 { | 5456 { |
| 5454 ASSERT(isContextLost()); | 5457 ASSERT(isContextLost()); |
| 5455 | 5458 |
| 5456 // The rendering context is not restored unless the default behavior of the | 5459 // The rendering context is not restored unless the default behavior of the |
| 5457 // webglcontextlost event was prevented earlier. | 5460 // webglcontextlost event was prevented earlier. |
| 5458 // | 5461 // |
| 5459 // Because of the way m_restoreTimer is set up for real vs. synthetic lost | 5462 // Because of the way m_restoreTimer is set up for real vs. synthetic lost |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5694 if (m_textureUnits[i].m_texture2DBinding | 5697 if (m_textureUnits[i].m_texture2DBinding |
| 5695 || m_textureUnits[i].m_textureCubeMapBinding) { | 5698 || m_textureUnits[i].m_textureCubeMapBinding) { |
| 5696 m_onePlusMaxNonDefaultTextureUnit = i + 1; | 5699 m_onePlusMaxNonDefaultTextureUnit = i + 1; |
| 5697 return; | 5700 return; |
| 5698 } | 5701 } |
| 5699 } | 5702 } |
| 5700 m_onePlusMaxNonDefaultTextureUnit = 0; | 5703 m_onePlusMaxNonDefaultTextureUnit = 0; |
| 5701 } | 5704 } |
| 5702 | 5705 |
| 5703 } // namespace WebCore | 5706 } // namespace WebCore |
| OLD | NEW |