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 |