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