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

Side by Side Diff: Source/WebCore/html/canvas/WebGLRenderingContext.cpp

Issue 14217005: Limit the number of WebGL contexts that are active at any given time (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 8 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
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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 #include <wtf/OwnArrayPtr.h> 77 #include <wtf/OwnArrayPtr.h>
78 #include <wtf/PassOwnArrayPtr.h> 78 #include <wtf/PassOwnArrayPtr.h>
79 #include <wtf/Uint16Array.h> 79 #include <wtf/Uint16Array.h>
80 #include <wtf/Uint32Array.h> 80 #include <wtf/Uint32Array.h>
81 #include <wtf/text/StringBuilder.h> 81 #include <wtf/text/StringBuilder.h>
82 82
83 namespace WebCore { 83 namespace WebCore {
84 84
85 const double secondsBetweenRestoreAttempts = 1.0; 85 const double secondsBetweenRestoreAttempts = 1.0;
86 const int maxGLErrorsAllowedToConsole = 256; 86 const int maxGLErrorsAllowedToConsole = 256;
87 const int maxGLActiveContexts = 16;
88
89 Vector<WebGLRenderingContext*>& WebGLRenderingContext::activeContexts()
90 {
91 DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContext*>, activeContexts, ());
92 return activeContexts;
93 }
94
95 Vector<WebGLRenderingContext*>& WebGLRenderingContext::inactiveContexts()
96 {
97 DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContext*>, inactiveContexts, ());
98 return inactiveContexts;
99 }
100
101 void WebGLRenderingContext::forceLostOldestContext()
102 {
103 if(activeContexts().size()) {
Ken Russell (switch to Gerrit) 2013/04/16 02:57:52 Add space between if and ( everywhere please.
104 WebGLRenderingContext* oldestActiveContext = activeContexts().first();
105 activeContexts().remove(0);
Ken Russell (switch to Gerrit) 2013/04/16 02:57:52 The implicit assumption here is that contexts' age
106
107 // This will call deactivateContext once the context has actually been l ost
108 oldestActiveContext->forceLostContext(WebGLRenderingContext::SyntheticLo stContext);
109 }
110 }
111
112 void WebGLRenderingContext::activateContext(WebGLRenderingContext* context)
113 {
114 if(!activeContexts().contains(context))
115 activeContexts().append(context);
116
117 if(activeContexts().size() > maxGLActiveContexts)
118 forceLostOldestContext();
119 }
120
121 void WebGLRenderingContext::deactivateContext(WebGLRenderingContext* context, bo ol addToInactiveList)
122 {
123 size_t position = activeContexts().find(context);
124 if(position != WTF::notFound)
125 activeContexts().remove(position);
126
127 if(addToInactiveList && !inactiveContexts().contains(context))
128 inactiveContexts().append(context);
129 }
130
131 void WebGLRenderingContext::removeContext(WebGLRenderingContext* context)
132 {
133 size_t position = inactiveContexts().find(context);
134 if(position != WTF::notFound)
135 inactiveContexts().remove(position);
136
137 deactivateContext(context, false);
138
139 // Try to re-enable the oldest inactive contexts
140 while(activeContexts().size() < maxGLActiveContexts && inactiveContexts().si ze() > 0) {
141 WebGLRenderingContext* oldestInactiveContext = inactiveContexts().first( );
142 inactiveContexts().remove(0);
143
144 if(oldestInactiveContext->m_restoreAllowed) {
Ken Russell (switch to Gerrit) 2013/04/16 02:57:52 If restoration isn't allowed, we lose track of old
145 oldestInactiveContext->forceRestoreContext();
146 activeContexts().append(oldestInactiveContext);
147 }
148 }
149 }
87 150
88 namespace { 151 namespace {
89 152
90 class ScopedDrawingBufferBinder { 153 class ScopedDrawingBufferBinder {
91 public: 154 public:
92 ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer * framebufferBinding) 155 ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer * framebufferBinding)
93 : m_drawingBuffer(drawingBuffer) 156 : m_drawingBuffer(drawingBuffer)
94 , m_framebufferBinding(framebufferBinding) 157 , m_framebufferBinding(framebufferBinding)
95 { 158 {
96 // Commit DrawingBuffer if needed (e.g., for multisampling) 159 // Commit DrawingBuffer if needed (e.g., for multisampling)
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 }; 463 };
401 464
402 PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen t* canvas, WebGLContextAttributes* attrs) 465 PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen t* canvas, WebGLContextAttributes* attrs)
403 { 466 {
404 Document* document = canvas->document(); 467 Document* document = canvas->document();
405 Frame* frame = document->frame(); 468 Frame* frame = document->frame();
406 if (!frame) 469 if (!frame)
407 return nullptr; 470 return nullptr;
408 Settings* settings = frame->settings(); 471 Settings* settings = frame->settings();
409 472
410 // The FrameLoaderClient might creation of a new WebGL context despite the p age settings; in 473 // The FrameLoaderClient might block creation of a new WebGL context despite the page settings; in
411 // particular, if WebGL contexts were lost one or more times via the GL_ARB_ robustness extension. 474 // particular, if WebGL contexts were lost one or more times via the GL_ARB_ robustness extension.
412 if (!frame->loader()->client()->allowWebGL(settings && settings->webGLEnable d())) { 475 if (!frame->loader()->client()->allowWebGL(settings && settings->webGLEnable d())) {
413 canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontex tcreationerrorEvent, false, true, "Web page was not allowed to create a WebGL co ntext.")); 476 canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontex tcreationerrorEvent, false, true, "Web page was not allowed to create a WebGL co ntext."));
414 return nullptr; 477 return nullptr;
415 } 478 }
416 479
417 HostWindow* hostWindow = document->view()->root()->hostWindow(); 480 HostWindow* hostWindow = document->view()->root()->hostWindow();
418 GraphicsContext3D::Attributes attributes = attrs ? attrs->attributes() : Gra phicsContext3D::Attributes(); 481 GraphicsContext3D::Attributes attributes = attrs ? attrs->attributes() : Gra phicsContext3D::Attributes();
419 482
420 if (attributes.antialias) { 483 if (attributes.antialias) {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 IntSize canvasSize = clampedCanvasSize(); 621 IntSize canvasSize = clampedCanvasSize();
559 if (m_drawingBuffer) 622 if (m_drawingBuffer)
560 m_drawingBuffer->reset(canvasSize); 623 m_drawingBuffer->reset(canvasSize);
561 624
562 m_context->reshape(canvasSize.width(), canvasSize.height()); 625 m_context->reshape(canvasSize.width(), canvasSize.height());
563 m_context->viewport(0, 0, canvasSize.width(), canvasSize.height()); 626 m_context->viewport(0, 0, canvasSize.width(), canvasSize.height());
564 m_context->scissor(0, 0, canvasSize.width(), canvasSize.height()); 627 m_context->scissor(0, 0, canvasSize.width(), canvasSize.height());
565 628
566 m_context->setContextLostCallback(adoptPtr(new WebGLRenderingContextLostCall back(this))); 629 m_context->setContextLostCallback(adoptPtr(new WebGLRenderingContextLostCall back(this)));
567 m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMe ssageCallback(this))); 630 m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMe ssageCallback(this)));
631
632 activateContext(this);
568 } 633 }
569 634
570 void WebGLRenderingContext::setupFlags() 635 void WebGLRenderingContext::setupFlags()
571 { 636 {
572 ASSERT(m_context); 637 ASSERT(m_context);
573 638
574 Page* p = canvas()->document()->page(); 639 Page* p = canvas()->document()->page();
575 if (p) 640 if (p)
576 m_synthesizedErrorsToConsole = p->settings()->webGLErrorsToConsoleEnable d(); 641 m_synthesizedErrorsToConsole = p->settings()->webGLErrorsToConsoleEnable d();
577 642
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 m_textureUnits[i].m_texture2DBinding = 0; 683 m_textureUnits[i].m_texture2DBinding = 0;
619 m_textureUnits[i].m_textureCubeMapBinding = 0; 684 m_textureUnits[i].m_textureCubeMapBinding = 0;
620 } 685 }
621 686
622 m_blackTexture2D = 0; 687 m_blackTexture2D = 0;
623 m_blackTextureCubeMap = 0; 688 m_blackTextureCubeMap = 0;
624 689
625 detachAndRemoveAllObjects(); 690 detachAndRemoveAllObjects();
626 destroyGraphicsContext3D(); 691 destroyGraphicsContext3D();
627 m_contextGroup->removeContext(this); 692 m_contextGroup->removeContext(this);
693
694 removeContext(this);
628 } 695 }
629 696
630 void WebGLRenderingContext::destroyGraphicsContext3D() 697 void WebGLRenderingContext::destroyGraphicsContext3D()
631 { 698 {
632 // The drawing buffer holds a context reference. It must also be destroyed 699 // The drawing buffer holds a context reference. It must also be destroyed
633 // in order for the context to be released. 700 // in order for the context to be released.
634 if (m_drawingBuffer) 701 if (m_drawingBuffer)
635 m_drawingBuffer.clear(); 702 m_drawingBuffer.clear();
636 703
637 if (m_context) { 704 if (m_context) {
(...skipping 3986 matching lines...) Expand 10 before | Expand all | Expand 10 after
4624 frame->loader()->client()->didLoseWebGLContext(m_context->getExt ensions()->getGraphicsResetStatusARB()); 4691 frame->loader()->client()->didLoseWebGLContext(m_context->getExt ensions()->getGraphicsResetStatusARB());
4625 } 4692 }
4626 } 4693 }
4627 4694
4628 detachAndRemoveAllObjects(); 4695 detachAndRemoveAllObjects();
4629 4696
4630 if (m_drawingBuffer) { 4697 if (m_drawingBuffer) {
4631 // Make absolutely sure we do not refer to an already-deleted texture or framebuffer. 4698 // Make absolutely sure we do not refer to an already-deleted texture or framebuffer.
4632 m_drawingBuffer->setTexture2DBinding(0); 4699 m_drawingBuffer->setTexture2DBinding(0);
4633 m_drawingBuffer->setFramebufferBinding(0); 4700 m_drawingBuffer->setFramebufferBinding(0);
4701 m_drawingBuffer->clear();
4634 } 4702 }
4635 4703
4636 // There is no direct way to clear errors from a GL implementation and 4704 // There is no direct way to clear errors from a GL implementation and
4637 // looping until getError() becomes NO_ERROR might cause an infinite loop if 4705 // looping until getError() becomes NO_ERROR might cause an infinite loop if
4638 // the driver or context implementation had a bug. So, loop a reasonably 4706 // the driver or context implementation had a bug. So, loop a reasonably
4639 // large number of times to clear any existing errors. 4707 // large number of times to clear any existing errors.
4640 for (int i = 0; i < 100; ++i) { 4708 for (int i = 0; i < 100; ++i) {
4641 if (m_context->getError() == GraphicsContext3D::NO_ERROR) 4709 if (m_context->getError() == GraphicsContext3D::NO_ERROR)
4642 break; 4710 break;
4643 } 4711 }
(...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after
5787 m_context->vertexAttribPointer(0, state.size, state.type, state.normaliz ed, state.originalStride, state.offset); 5855 m_context->vertexAttribPointer(0, state.size, state.type, state.normaliz ed, state.originalStride, state.offset);
5788 } 5856 }
5789 m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(m_boundA rrayBuffer.get())); 5857 m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(m_boundA rrayBuffer.get()));
5790 } 5858 }
5791 5859
5792 void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext >*) 5860 void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext >*)
5793 { 5861 {
5794 RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().web glcontextlostEvent, false, true, ""); 5862 RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().web glcontextlostEvent, false, true, "");
5795 canvas()->dispatchEvent(event); 5863 canvas()->dispatchEvent(event);
5796 m_restoreAllowed = event->defaultPrevented(); 5864 m_restoreAllowed = event->defaultPrevented();
5865 deactivateContext(this, m_restoreAllowed);
Ken Russell (switch to Gerrit) 2013/04/16 02:57:52 This doesn't seem right. If a context receives a R
5797 if (m_contextLostMode == RealLostContext && m_restoreAllowed) 5866 if (m_contextLostMode == RealLostContext && m_restoreAllowed)
5798 m_restoreTimer.startOneShot(0); 5867 m_restoreTimer.startOneShot(0);
5799 } 5868 }
5800 5869
5801 void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*) 5870 void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*)
5802 { 5871 {
5803 ASSERT(m_contextLost); 5872 ASSERT(m_contextLost);
5804 if (!m_contextLost) 5873 if (!m_contextLost)
5805 return; 5874 return;
5806 5875
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
5955 6024
5956 void WebGLRenderingContext::synthesizeGLError(GC3Denum error, const char* functi onName, const char* description, ConsoleDisplayPreference display) 6025 void WebGLRenderingContext::synthesizeGLError(GC3Denum error, const char* functi onName, const char* description, ConsoleDisplayPreference display)
5957 { 6026 {
5958 if (m_synthesizedErrorsToConsole && display == DisplayInConsole) { 6027 if (m_synthesizedErrorsToConsole && display == DisplayInConsole) {
5959 String str = String("WebGL: ") + GetErrorString(error) + ": " + String(fu nctionName) + ": " + String(description); 6028 String str = String("WebGL: ") + GetErrorString(error) + ": " + String(fu nctionName) + ": " + String(description);
5960 printGLErrorToConsole(str); 6029 printGLErrorToConsole(str);
5961 } 6030 }
5962 m_context->synthesizeGLError(error); 6031 m_context->synthesizeGLError(error);
5963 } 6032 }
5964 6033
5965
5966 void WebGLRenderingContext::printGLWarningToConsole(const char* functionName, co nst char* description) 6034 void WebGLRenderingContext::printGLWarningToConsole(const char* functionName, co nst char* description)
5967 { 6035 {
5968 if (m_synthesizedErrorsToConsole) { 6036 if (m_synthesizedErrorsToConsole) {
5969 String str = String("WebGL: ") + String(functionName) + ": " + String(de scription); 6037 String str = String("WebGL: ") + String(functionName) + ": " + String(de scription);
5970 printGLErrorToConsole(str); 6038 printGLErrorToConsole(str);
5971 } 6039 }
5972 } 6040 }
5973 6041
5974 void WebGLRenderingContext::applyStencilTest() 6042 void WebGLRenderingContext::applyStencilTest()
5975 { 6043 {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
6040 bool WebGLRenderingContext::supportsDrawBuffers() 6108 bool WebGLRenderingContext::supportsDrawBuffers()
6041 { 6109 {
6042 if (!m_drawBuffersWebGLRequirementsChecked) { 6110 if (!m_drawBuffersWebGLRequirementsChecked) {
6043 m_drawBuffersWebGLRequirementsChecked = true; 6111 m_drawBuffersWebGLRequirementsChecked = true;
6044 m_drawBuffersSupported = EXTDrawBuffers::supported(this); 6112 m_drawBuffersSupported = EXTDrawBuffers::supported(this);
6045 } 6113 }
6046 return m_drawBuffersSupported; 6114 return m_drawBuffersSupported;
6047 } 6115 }
6048 6116
6049 } // namespace WebCore 6117 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698