| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/graphics/gpu/SharedGpuContext.h" | 5 #include "platform/graphics/gpu/SharedGpuContext.h" |
| 6 | 6 |
| 7 #include "gpu/command_buffer/client/gles2_interface.h" | 7 #include "gpu/command_buffer/client/gles2_interface.h" |
| 8 #include "platform/CrossThreadFunctional.h" | 8 #include "platform/CrossThreadFunctional.h" |
| 9 #include "platform/WaitableEvent.h" | 9 #include "platform/WaitableEvent.h" |
| 10 #include "public/platform/Platform.h" | 10 #include "public/platform/Platform.h" |
| 11 #include "public/platform/WebGraphicsContext3DProvider.h" | 11 #include "public/platform/WebGraphicsContext3DProvider.h" |
| 12 #include "public/platform/WebTaskRunner.h" | 12 #include "public/platform/WebTaskRunner.h" |
| 13 | 13 |
| 14 namespace blink { | 14 namespace blink { |
| 15 | 15 |
| 16 SharedGpuContext* SharedGpuContext::getInstanceForCurrentThread() | 16 SharedGpuContext* SharedGpuContext::getInstanceForCurrentThread() |
| 17 { | 17 { |
| 18 DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<SharedGpuContext>, threadSpec
ificInstance, new ThreadSpecific<SharedGpuContext>); | 18 DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<SharedGpuContext>, threadSpec
ificInstance, new ThreadSpecific<SharedGpuContext>); |
| 19 return threadSpecificInstance; | 19 return threadSpecificInstance; |
| 20 } | 20 } |
| 21 | 21 |
| 22 SharedGpuContext::SharedGpuContext() | 22 SharedGpuContext::SharedGpuContext() |
| 23 : m_contextId(kNoSharedContext) | 23 : m_contextId(kNoSharedContext) |
| 24 { | 24 { |
| 25 createContextProvider(); | 25 createContextProviderIfNeeded(); |
| 26 } | 26 } |
| 27 | 27 |
| 28 void SharedGpuContext::createContextProviderOnMainThread(WaitableEvent* waitable
Event) | 28 void SharedGpuContext::createContextProviderOnMainThread(WaitableEvent* waitable
Event) |
| 29 { | 29 { |
| 30 DCHECK(isMainThread()); | 30 DCHECK(isMainThread()); |
| 31 Platform::ContextAttributes contextAttributes; | 31 Platform::ContextAttributes contextAttributes; |
| 32 contextAttributes.webGLVersion = 1; // GLES2 | 32 contextAttributes.webGLVersion = 1; // GLES2 |
| 33 Platform::GraphicsInfo graphicsInfo; | 33 Platform::GraphicsInfo graphicsInfo; |
| 34 m_contextProvider = wrapUnique(Platform::current()->createOffscreenGraphicsC
ontext3DProvider( | 34 m_contextProvider = wrapUnique(Platform::current()->createOffscreenGraphicsC
ontext3DProvider( |
| 35 contextAttributes, WebURL(), nullptr, &graphicsInfo)); | 35 contextAttributes, WebURL(), nullptr, &graphicsInfo)); |
| 36 if (waitableEvent) | 36 if (waitableEvent) |
| 37 waitableEvent->signal(); | 37 waitableEvent->signal(); |
| 38 } | 38 } |
| 39 | 39 |
| 40 void SharedGpuContext::createContextProvider() | 40 void SharedGpuContext::createContextProviderIfNeeded() |
| 41 { | 41 { |
| 42 if (m_contextProvider && m_contextProvider->contextGL()->GetGraphicsResetSta
tusKHR() == GL_NO_ERROR) |
| 43 return; |
| 44 |
| 42 std::unique_ptr<WebGraphicsContext3DProvider> oldContextProvider = std::move
(m_contextProvider); | 45 std::unique_ptr<WebGraphicsContext3DProvider> oldContextProvider = std::move
(m_contextProvider); |
| 43 if (isMainThread()) { | 46 if (m_contextProviderFactory) { |
| 47 // This path should only be used in unit tests |
| 48 m_contextProvider = m_contextProviderFactory(); |
| 49 } else if (isMainThread()) { |
| 44 m_contextProvider = wrapUnique(blink::Platform::current()->createSharedO
ffscreenGraphicsContext3DProvider()); | 50 m_contextProvider = wrapUnique(blink::Platform::current()->createSharedO
ffscreenGraphicsContext3DProvider()); |
| 45 } else { | 51 } else { |
| 46 // This synchronous round-trip to the main thread is the reason why Shar
edGpuContext | 52 // This synchronous round-trip to the main thread is the reason why Shar
edGpuContext |
| 47 // encasulates the context provider: so we only have to do this once per
thread. | 53 // encasulates the context provider: so we only have to do this once per
thread. |
| 48 WaitableEvent waitableEvent; | 54 WaitableEvent waitableEvent; |
| 49 WebTaskRunner* taskRunner = Platform::current()->mainThread()->getWebTas
kRunner(); | 55 WebTaskRunner* taskRunner = Platform::current()->mainThread()->getWebTas
kRunner(); |
| 50 taskRunner->postTask(BLINK_FROM_HERE, crossThreadBind(&SharedGpuCont
ext::createContextProviderOnMainThread, crossThreadUnretained(this), crossThread
Unretained(&waitableEvent))); | 56 taskRunner->postTask(BLINK_FROM_HERE, crossThreadBind(&SharedGpuCont
ext::createContextProviderOnMainThread, crossThreadUnretained(this), crossThread
Unretained(&waitableEvent))); |
| 51 waitableEvent.wait(); | 57 waitableEvent.wait(); |
| 52 if (m_contextProvider && !m_contextProvider->bindToCurrentThread()) | 58 if (m_contextProvider && !m_contextProvider->bindToCurrentThread()) |
| 53 m_contextProvider = nullptr; | 59 m_contextProvider = nullptr; |
| 54 } | 60 } |
| 55 | 61 |
| 56 if (m_contextProvider) { | 62 if (m_contextProvider) { |
| 57 m_contextId++; | 63 m_contextId++; |
| 58 // In the unlikely event of an overflow... | 64 // In the unlikely event of an overflow... |
| 59 if (m_contextId == kNoSharedContext) | 65 if (m_contextId == kNoSharedContext) |
| 60 m_contextId++; | 66 m_contextId++; |
| 61 } else { | 67 } else { |
| 62 m_contextProvider = std::move(oldContextProvider); | 68 m_contextProvider = std::move(oldContextProvider); |
| 63 } | 69 } |
| 64 } | 70 } |
| 65 | 71 |
| 72 void SharedGpuContext::setContextProviderFactoryForTesting(ContextProviderFactor
y factory) |
| 73 { |
| 74 SharedGpuContext* thisPtr = getInstanceForCurrentThread(); |
| 75 thisPtr->m_contextProvider.reset(); |
| 76 thisPtr->m_contextProviderFactory = factory; |
| 77 thisPtr->createContextProviderIfNeeded(); |
| 78 } |
| 79 |
| 66 unsigned SharedGpuContext::contextId() | 80 unsigned SharedGpuContext::contextId() |
| 67 { | 81 { |
| 82 if (!isValid()) |
| 83 return kNoSharedContext; |
| 68 SharedGpuContext* thisPtr = getInstanceForCurrentThread(); | 84 SharedGpuContext* thisPtr = getInstanceForCurrentThread(); |
| 69 return thisPtr->m_contextId; | 85 return thisPtr->m_contextId; |
| 70 } | 86 } |
| 71 | 87 |
| 72 gpu::gles2::GLES2Interface* SharedGpuContext::gl() | 88 gpu::gles2::GLES2Interface* SharedGpuContext::gl() |
| 73 { | 89 { |
| 74 SharedGpuContext* thisPtr = getInstanceForCurrentThread(); | 90 if (isValid()) { |
| 75 if (thisPtr->m_contextProvider) | 91 SharedGpuContext* thisPtr = getInstanceForCurrentThread(); |
| 76 return thisPtr->m_contextProvider->contextGL(); | 92 return thisPtr->m_contextProvider->contextGL(); |
| 93 } |
| 77 return nullptr; | 94 return nullptr; |
| 78 } | 95 } |
| 79 | 96 |
| 80 GrContext* SharedGpuContext::gr() | 97 GrContext* SharedGpuContext::gr() |
| 81 { | 98 { |
| 82 SharedGpuContext* thisPtr = getInstanceForCurrentThread(); | 99 if (isValid()) { |
| 83 if (thisPtr->m_contextProvider) | 100 SharedGpuContext* thisPtr = getInstanceForCurrentThread(); |
| 84 return thisPtr->m_contextProvider->grContext(); | 101 return thisPtr->m_contextProvider->grContext(); |
| 102 } |
| 85 return nullptr; | 103 return nullptr; |
| 86 } | 104 } |
| 87 | 105 |
| 88 bool SharedGpuContext::isValid() | 106 bool SharedGpuContext::isValid() |
| 89 { | 107 { |
| 90 SharedGpuContext* thisPtr = getInstanceForCurrentThread(); | 108 SharedGpuContext* thisPtr = getInstanceForCurrentThread(); |
| 109 thisPtr->createContextProviderIfNeeded(); |
| 110 if (!thisPtr->m_contextProvider) |
| 111 return false; |
| 112 return thisPtr->m_contextProvider->contextGL()->GetGraphicsResetStatusKHR()
== GL_NO_ERROR; |
| 113 } |
| 114 |
| 115 bool SharedGpuContext::isValidWithoutRestoring() |
| 116 { |
| 117 SharedGpuContext* thisPtr = getInstanceForCurrentThread(); |
| 91 if (!thisPtr->m_contextProvider) | 118 if (!thisPtr->m_contextProvider) |
| 92 return false; | 119 return false; |
| 93 return thisPtr->m_contextProvider->contextGL()->GetGraphicsResetStatusKHR()
== GL_NO_ERROR; | 120 return thisPtr->m_contextProvider->contextGL()->GetGraphicsResetStatusKHR()
== GL_NO_ERROR; |
| 94 } | 121 } |
| 95 | 122 |
| 96 bool SharedGpuContext::restore() | |
| 97 { | |
| 98 if (!isValid()) | |
| 99 getInstanceForCurrentThread()->createContextProvider(); | |
| 100 return isValid(); | |
| 101 } | |
| 102 | |
| 103 } // blink | 123 } // blink |
| OLD | NEW |