Chromium Code Reviews| 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |