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 = 20; | |
| 88 | |
| 89 Vector<WebGLRenderingContext*>& WebGLRenderingContext::activeContexts() | |
| 90 { | |
| 91 DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContext*>, activeContexts, ()); | |
| 92 return activeContexts; | |
| 93 } | |
| 94 | |
| 95 Vector<WebGLRenderingContext*>& WebGLRenderingContext::forciblyEvictedContexts() | |
| 96 { | |
| 97 DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContext*>, forciblyEvictedContexts, ()); | |
| 98 return forciblyEvictedContexts; | |
| 99 } | |
| 100 | |
| 101 void WebGLRenderingContext::forciblyLoseOldestContext() | |
| 102 { | |
| 103 if (activeContexts().size()) { | |
| 104 WebGLRenderingContext* oldestActiveContext = activeContexts().first(); | |
| 105 activeContexts().remove(0); | |
| 106 | |
| 107 // This will call deactivateContext once the context has actually been l ost | |
| 108 oldestActiveContext->forceLostContext(WebGLRenderingContext::SyntheticLo stContext); | |
| 109 } | |
| 110 } | |
| 111 | |
| 112 IntSize WebGLRenderingContext::oldestContextSize() | |
| 113 { | |
| 114 IntSize size; | |
| 115 | |
| 116 if (activeContexts().size()) { | |
| 117 WebGLRenderingContext* oldestActiveContext = activeContexts().first(); | |
| 118 size.setWidth(oldestActiveContext->drawingBufferWidth()); | |
| 119 size.setHeight(oldestActiveContext->drawingBufferHeight()); | |
| 120 } | |
| 121 | |
| 122 return size; | |
| 123 } | |
| 124 | |
| 125 void WebGLRenderingContext::activateContext(WebGLRenderingContext* context) | |
| 126 { | |
| 127 if (!activeContexts().contains(context)) | |
| 128 activeContexts().append(context); | |
| 129 | |
| 130 if (activeContexts().size() > maxGLActiveContexts) | |
| 131 forciblyLoseOldestContext(); | |
| 132 } | |
| 133 | |
| 134 void WebGLRenderingContext::deactivateContext(WebGLRenderingContext* context, bo ol addToEvictedList) | |
| 135 { | |
| 136 size_t position = activeContexts().find(context); | |
| 137 if (position != WTF::notFound) | |
| 138 activeContexts().remove(position); | |
| 139 | |
| 140 if (addToEvictedList && !forciblyEvictedContexts().contains(context)) | |
| 141 forciblyEvictedContexts().append(context); | |
| 142 } | |
| 143 | |
| 144 void WebGLRenderingContext::willDestroyContext(WebGLRenderingContext* context) | |
| 145 { | |
| 146 size_t position = forciblyEvictedContexts().find(context); | |
| 147 if (position != WTF::notFound) | |
| 148 forciblyEvictedContexts().remove(position); | |
| 149 | |
| 150 deactivateContext(context, false); | |
| 151 | |
| 152 // Try to re-enable the oldest inactive contexts | |
| 153 while(activeContexts().size() < maxGLActiveContexts && forciblyEvictedContex ts().size()) { | |
| 154 WebGLRenderingContext* evictedContext = forciblyEvictedContexts().first( ); | |
| 155 if (!evictedContext->m_restoreAllowed) { | |
| 156 forciblyEvictedContexts().remove(0); | |
| 157 continue; | |
| 158 } | |
| 159 | |
| 160 IntSize desiredSize = evictedContext->m_drawingBuffer->adjustSize(evicte dContext->clampedCanvasSize()); | |
| 161 | |
| 162 // If there's room in the pixel budget for this context, restore it! | |
| 163 if (!desiredSize.isEmpty()) { | |
| 164 forciblyEvictedContexts().remove(0); | |
| 165 evictedContext->forceRestoreContext(); | |
| 166 activeContexts().append(evictedContext); | |
| 167 } | |
| 168 break; | |
| 169 } | |
| 170 } | |
| 171 | |
| 172 class WebGLRenderingContextEvictionManager : public ContextEvictionManager { | |
| 173 public: | |
| 174 void forciblyLoseOldestContext() { | |
| 175 WebGLRenderingContext::forciblyLoseOldestContext(); | |
| 176 }; | |
| 177 IntSize oldestContextSize() { | |
| 178 return WebGLRenderingContext::oldestContextSize(); | |
| 179 }; | |
| 180 }; | |
| 87 | 181 |
| 88 namespace { | 182 namespace { |
| 89 | 183 |
| 90 class ScopedDrawingBufferBinder { | 184 class ScopedDrawingBufferBinder { |
| 91 public: | 185 public: |
| 92 ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer * framebufferBinding) | 186 ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer * framebufferBinding) |
| 93 : m_drawingBuffer(drawingBuffer) | 187 : m_drawingBuffer(drawingBuffer) |
| 94 , m_framebufferBinding(framebufferBinding) | 188 , m_framebufferBinding(framebufferBinding) |
| 95 { | 189 { |
| 96 // Commit DrawingBuffer if needed (e.g., for multisampling) | 190 // Commit DrawingBuffer if needed (e.g., for multisampling) |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 467 { | 561 { |
| 468 ASSERT(m_context); | 562 ASSERT(m_context); |
| 469 ScriptWrappable::init(this); | 563 ScriptWrappable::init(this); |
| 470 | 564 |
| 471 m_contextGroup = WebGLContextGroup::create(); | 565 m_contextGroup = WebGLContextGroup::create(); |
| 472 m_contextGroup->addContext(this); | 566 m_contextGroup->addContext(this); |
| 473 | 567 |
| 474 m_maxViewportDims[0] = m_maxViewportDims[1] = 0; | 568 m_maxViewportDims[0] = m_maxViewportDims[1] = 0; |
| 475 m_context->getIntegerv(GraphicsContext3D::MAX_VIEWPORT_DIMS, m_maxViewportDi ms); | 569 m_context->getIntegerv(GraphicsContext3D::MAX_VIEWPORT_DIMS, m_maxViewportDi ms); |
| 476 | 570 |
| 571 RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptR ef(new WebGLRenderingContextEvictionManager()); | |
| 572 | |
| 477 // Create the DrawingBuffer and initialize the platform layer. | 573 // Create the DrawingBuffer and initialize the platform layer. |
| 478 DrawingBuffer::PreserveDrawingBuffer preserve = m_attributes.preserveDrawing Buffer ? DrawingBuffer::Preserve : DrawingBuffer::Discard; | 574 DrawingBuffer::PreserveDrawingBuffer preserve = m_attributes.preserveDrawing Buffer ? DrawingBuffer::Preserve : DrawingBuffer::Discard; |
| 479 m_drawingBuffer = DrawingBuffer::create(m_context.get(), clampedCanvasSize() , preserve); | 575 m_drawingBuffer = DrawingBuffer::create(m_context.get(), clampedCanvasSize() , preserve, contextEvictionManager.get()); |
|
Ken Russell (switch to Gerrit)
2013/04/24 01:30:57
Use PassRefPtr in the callee (see the comment else
| |
| 480 | 576 |
| 481 if (!m_drawingBuffer->isZeroSized()) { | 577 if (!m_drawingBuffer->isZeroSized()) { |
| 482 m_drawingBuffer->bind(); | 578 m_drawingBuffer->bind(); |
| 483 setupFlags(); | 579 setupFlags(); |
| 484 initializeNewContext(); | 580 initializeNewContext(); |
| 485 } | 581 } |
| 486 } | 582 } |
| 487 | 583 |
| 488 void WebGLRenderingContext::initializeNewContext() | 584 void WebGLRenderingContext::initializeNewContext() |
| 489 { | 585 { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 | 652 |
| 557 IntSize canvasSize = clampedCanvasSize(); | 653 IntSize canvasSize = clampedCanvasSize(); |
| 558 m_drawingBuffer->reset(canvasSize); | 654 m_drawingBuffer->reset(canvasSize); |
| 559 | 655 |
| 560 m_context->reshape(canvasSize.width(), canvasSize.height()); | 656 m_context->reshape(canvasSize.width(), canvasSize.height()); |
| 561 m_context->viewport(0, 0, canvasSize.width(), canvasSize.height()); | 657 m_context->viewport(0, 0, canvasSize.width(), canvasSize.height()); |
| 562 m_context->scissor(0, 0, canvasSize.width(), canvasSize.height()); | 658 m_context->scissor(0, 0, canvasSize.width(), canvasSize.height()); |
| 563 | 659 |
| 564 m_context->setContextLostCallback(adoptPtr(new WebGLRenderingContextLostCall back(this))); | 660 m_context->setContextLostCallback(adoptPtr(new WebGLRenderingContextLostCall back(this))); |
| 565 m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMe ssageCallback(this))); | 661 m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMe ssageCallback(this))); |
| 662 | |
| 663 activateContext(this); | |
| 566 } | 664 } |
| 567 | 665 |
| 568 void WebGLRenderingContext::setupFlags() | 666 void WebGLRenderingContext::setupFlags() |
| 569 { | 667 { |
| 570 ASSERT(m_context); | 668 ASSERT(m_context); |
| 571 | 669 |
| 572 Page* p = canvas()->document()->page(); | 670 Page* p = canvas()->document()->page(); |
| 573 if (p) | 671 if (p) |
| 574 m_synthesizedErrorsToConsole = p->settings()->webGLErrorsToConsoleEnable d(); | 672 m_synthesizedErrorsToConsole = p->settings()->webGLErrorsToConsoleEnable d(); |
| 575 | 673 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 616 m_textureUnits[i].m_texture2DBinding = 0; | 714 m_textureUnits[i].m_texture2DBinding = 0; |
| 617 m_textureUnits[i].m_textureCubeMapBinding = 0; | 715 m_textureUnits[i].m_textureCubeMapBinding = 0; |
| 618 } | 716 } |
| 619 | 717 |
| 620 m_blackTexture2D = 0; | 718 m_blackTexture2D = 0; |
| 621 m_blackTextureCubeMap = 0; | 719 m_blackTextureCubeMap = 0; |
| 622 | 720 |
| 623 detachAndRemoveAllObjects(); | 721 detachAndRemoveAllObjects(); |
| 624 destroyGraphicsContext3D(); | 722 destroyGraphicsContext3D(); |
| 625 m_contextGroup->removeContext(this); | 723 m_contextGroup->removeContext(this); |
| 724 | |
| 725 willDestroyContext(this); | |
| 626 } | 726 } |
| 627 | 727 |
| 628 void WebGLRenderingContext::destroyGraphicsContext3D() | 728 void WebGLRenderingContext::destroyGraphicsContext3D() |
| 629 { | 729 { |
| 630 // The drawing buffer holds a context reference. It must also be destroyed | 730 // The drawing buffer holds a context reference. It must also be destroyed |
| 631 // in order for the context to be released. | 731 // in order for the context to be released. |
| 632 m_drawingBuffer.clear(); | 732 m_drawingBuffer.clear(); |
| 633 | 733 |
| 634 if (m_context) { | 734 if (m_context) { |
| 635 m_context->setContextLostCallback(nullptr); | 735 m_context->setContextLostCallback(nullptr); |
| (...skipping 5112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5748 m_context->vertexAttribPointer(0, state.size, state.type, state.normaliz ed, state.originalStride, state.offset); | 5848 m_context->vertexAttribPointer(0, state.size, state.type, state.normaliz ed, state.originalStride, state.offset); |
| 5749 } | 5849 } |
| 5750 m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(m_boundA rrayBuffer.get())); | 5850 m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, objectOrZero(m_boundA rrayBuffer.get())); |
| 5751 } | 5851 } |
| 5752 | 5852 |
| 5753 void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext >*) | 5853 void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext >*) |
| 5754 { | 5854 { |
| 5755 RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().web glcontextlostEvent, false, true, ""); | 5855 RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().web glcontextlostEvent, false, true, ""); |
| 5756 canvas()->dispatchEvent(event); | 5856 canvas()->dispatchEvent(event); |
| 5757 m_restoreAllowed = event->defaultPrevented(); | 5857 m_restoreAllowed = event->defaultPrevented(); |
| 5858 deactivateContext(this, m_contextLostMode != RealLostContext && m_restoreAll owed); | |
| 5758 if (m_contextLostMode == RealLostContext && m_restoreAllowed) | 5859 if (m_contextLostMode == RealLostContext && m_restoreAllowed) |
| 5759 m_restoreTimer.startOneShot(0); | 5860 m_restoreTimer.startOneShot(0); |
| 5760 } | 5861 } |
| 5761 | 5862 |
| 5762 void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*) | 5863 void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*) |
| 5763 { | 5864 { |
| 5764 ASSERT(m_contextLost); | 5865 ASSERT(m_contextLost); |
| 5765 if (!m_contextLost) | 5866 if (!m_contextLost) |
| 5766 return; | 5867 return; |
| 5767 | 5868 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5824 RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes, ho stWindow)); | 5925 RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes, ho stWindow)); |
| 5825 if (!context) { | 5926 if (!context) { |
| 5826 if (m_contextLostMode == RealLostContext) | 5927 if (m_contextLostMode == RealLostContext) |
| 5827 m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts); | 5928 m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts); |
| 5828 else | 5929 else |
| 5829 // This likely shouldn't happen but is the best way to report it to the WebGL app. | 5930 // This likely shouldn't happen but is the best way to report it to the WebGL app. |
| 5830 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "", "error r estoring context"); | 5931 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "", "error r estoring context"); |
| 5831 return; | 5932 return; |
| 5832 } | 5933 } |
| 5833 | 5934 |
| 5935 RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptR ef(new WebGLRenderingContextEvictionManager()); | |
| 5936 | |
| 5834 // Construct a new drawing buffer with the new GraphicsContext3D. | 5937 // Construct a new drawing buffer with the new GraphicsContext3D. |
| 5835 m_drawingBuffer->clear(); | 5938 m_drawingBuffer->clear(); |
| 5836 DrawingBuffer::PreserveDrawingBuffer preserve = m_attributes.preserveDrawing Buffer ? DrawingBuffer::Preserve : DrawingBuffer::Discard; | 5939 DrawingBuffer::PreserveDrawingBuffer preserve = m_attributes.preserveDrawing Buffer ? DrawingBuffer::Preserve : DrawingBuffer::Discard; |
| 5837 m_drawingBuffer = DrawingBuffer::create(context.get(), clampedCanvasSize(), preserve); | 5940 m_drawingBuffer = DrawingBuffer::create(context.get(), clampedCanvasSize(), preserve, contextEvictionManager.get()); |
| 5838 | 5941 |
| 5839 if (m_drawingBuffer->isZeroSized()) | 5942 if (m_drawingBuffer->isZeroSized()) |
| 5840 return; | 5943 return; |
| 5841 | 5944 |
| 5842 m_drawingBuffer->bind(); | 5945 m_drawingBuffer->bind(); |
| 5843 | 5946 |
| 5844 m_context = context; | 5947 m_context = context; |
| 5845 m_contextLost = false; | 5948 m_contextLost = false; |
| 5846 setupFlags(); | 5949 setupFlags(); |
| 5847 initializeNewContext(); | 5950 initializeNewContext(); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6002 bool WebGLRenderingContext::supportsDrawBuffers() | 6105 bool WebGLRenderingContext::supportsDrawBuffers() |
| 6003 { | 6106 { |
| 6004 if (!m_drawBuffersWebGLRequirementsChecked) { | 6107 if (!m_drawBuffersWebGLRequirementsChecked) { |
| 6005 m_drawBuffersWebGLRequirementsChecked = true; | 6108 m_drawBuffersWebGLRequirementsChecked = true; |
| 6006 m_drawBuffersSupported = EXTDrawBuffers::supported(this); | 6109 m_drawBuffersSupported = EXTDrawBuffers::supported(this); |
| 6007 } | 6110 } |
| 6008 return m_drawBuffersSupported; | 6111 return m_drawBuffersSupported; |
| 6009 } | 6112 } |
| 6010 | 6113 |
| 6011 } // namespace WebCore | 6114 } // namespace WebCore |
| OLD | NEW |