OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "platform/graphics/gpu/SharedGpuContext.h" |
| 6 |
| 7 #include "gpu/command_buffer/client/gles2_interface.h" |
| 8 #include "platform/CrossThreadFunctional.h" |
| 9 #include "platform/WaitableEvent.h" |
| 10 #include "public/platform/Platform.h" |
| 11 #include "public/platform/WebGraphicsContext3DProvider.h" |
| 12 #include "public/platform/WebTaskRunner.h" |
| 13 |
| 14 namespace blink { |
| 15 |
| 16 SharedGpuContext* SharedGpuContext::getInstanceForCurrentThread() |
| 17 { |
| 18 DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<SharedGpuContext>, threadSpec
ificInstance, new ThreadSpecific<SharedGpuContext>); |
| 19 return threadSpecificInstance; |
| 20 } |
| 21 |
| 22 SharedGpuContext::SharedGpuContext() |
| 23 : m_contextId(kNoSharedContext) |
| 24 { |
| 25 createContextProvider(); |
| 26 } |
| 27 |
| 28 void SharedGpuContext::createContextProviderOnMainThread(WaitableEvent* waitable
Event) |
| 29 { |
| 30 DCHECK(isMainThread()); |
| 31 Platform::ContextAttributes contextAttributes; |
| 32 contextAttributes.webGLVersion = 1; // GLES2 |
| 33 Platform::GraphicsInfo graphicsInfo; |
| 34 m_contextProvider = wrapUnique(Platform::current()->createOffscreenGraphicsC
ontext3DProvider( |
| 35 contextAttributes, WebURL(), nullptr, &graphicsInfo)); |
| 36 if (waitableEvent) |
| 37 waitableEvent->signal(); |
| 38 } |
| 39 |
| 40 void SharedGpuContext::createContextProvider() |
| 41 { |
| 42 std::unique_ptr<WebGraphicsContext3DProvider> oldContextProvider = std::move
(m_contextProvider); |
| 43 if (isMainThread()) { |
| 44 m_contextProvider = wrapUnique(blink::Platform::current()->createSharedO
ffscreenGraphicsContext3DProvider()); |
| 45 } else { |
| 46 // 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. |
| 48 WaitableEvent waitableEvent; |
| 49 WebTaskRunner* taskRunner = Platform::current()->mainThread()->getWebTas
kRunner(); |
| 50 taskRunner->postTask(BLINK_FROM_HERE, crossThreadBind(&SharedGpuCont
ext::createContextProviderOnMainThread, crossThreadUnretained(this), crossThread
Unretained(&waitableEvent))); |
| 51 waitableEvent.wait(); |
| 52 if (m_contextProvider && !m_contextProvider->bindToCurrentThread()) |
| 53 m_contextProvider = nullptr; |
| 54 } |
| 55 |
| 56 if (m_contextProvider) { |
| 57 m_contextId++; |
| 58 // In the unlikely event of an overflow... |
| 59 if (m_contextId == kNoSharedContext) |
| 60 m_contextId++; |
| 61 } else { |
| 62 m_contextProvider = std::move(oldContextProvider); |
| 63 } |
| 64 } |
| 65 |
| 66 unsigned SharedGpuContext::contextId() |
| 67 { |
| 68 SharedGpuContext* thisPtr = getInstanceForCurrentThread(); |
| 69 return thisPtr->m_contextId; |
| 70 } |
| 71 |
| 72 gpu::gles2::GLES2Interface* SharedGpuContext::gl() |
| 73 { |
| 74 SharedGpuContext* thisPtr = getInstanceForCurrentThread(); |
| 75 if (thisPtr->m_contextProvider) |
| 76 return thisPtr->m_contextProvider->contextGL(); |
| 77 return nullptr; |
| 78 } |
| 79 |
| 80 GrContext* SharedGpuContext::gr() |
| 81 { |
| 82 SharedGpuContext* thisPtr = getInstanceForCurrentThread(); |
| 83 if (thisPtr->m_contextProvider) |
| 84 return thisPtr->m_contextProvider->grContext(); |
| 85 return nullptr; |
| 86 } |
| 87 |
| 88 bool SharedGpuContext::isValid() |
| 89 { |
| 90 SharedGpuContext* thisPtr = getInstanceForCurrentThread(); |
| 91 if (!thisPtr->m_contextProvider) |
| 92 return false; |
| 93 return thisPtr->m_contextProvider->contextGL()->GetGraphicsResetStatusKHR()
== GL_NO_ERROR; |
| 94 } |
| 95 |
| 96 bool SharedGpuContext::restore() |
| 97 { |
| 98 if (!isValid()) |
| 99 getInstanceForCurrentThread()->createContextProvider(); |
| 100 return isValid(); |
| 101 } |
| 102 |
| 103 } // blink |
OLD | NEW |