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

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

Issue 251373005: WebGL: Refactor active context management. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: rebase to ToT 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
« no previous file with comments | « Source/core/html/canvas/WebGLRenderingContextBase.h ('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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW
« no previous file with comments | « Source/core/html/canvas/WebGLRenderingContextBase.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698