Chromium Code Reviews| Index: third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp |
| diff --git a/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp b/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..8294d3c910c581bc9a835ca2c4dbed3bd27c771f |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp |
| @@ -0,0 +1,103 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "platform/graphics/gpu/SharedGpuContext.h" |
| + |
| +#include "gpu/command_buffer/client/gles2_interface.h" |
| +#include "platform/CrossThreadFunctional.h" |
| +#include "platform/WaitableEvent.h" |
| +#include "public/platform/Platform.h" |
| +#include "public/platform/WebGraphicsContext3DProvider.h" |
| +#include "public/platform/WebTaskRunner.h" |
| + |
| +namespace blink { |
| + |
| +SharedGpuContext* SharedGpuContext::getInstanceForCurrentThread() |
| +{ |
| + DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<SharedGpuContext>, threadSpecificInstance, new ThreadSpecific<SharedGpuContext>); |
|
Stephen White
2016/09/01 15:43:54
As discussed, it might be nice to move this into s
haraken
2016/09/01 17:33:05
Yeah, agreed. We want to avoid this kind of thread
|
| + return threadSpecificInstance; |
| +} |
| + |
| +SharedGpuContext::SharedGpuContext() |
| + : m_contextId(kNoSharedContext) |
| +{ |
| + createContextProvider(); |
| +} |
| + |
| +void SharedGpuContext::createContextProviderOnMainThread(WaitableEvent* waitableEvent) |
| +{ |
| + DCHECK(isMainThread()); |
| + Platform::ContextAttributes contextAttributes; |
| + contextAttributes.webGLVersion = 1; // GLES2 |
| + Platform::GraphicsInfo graphicsInfo; |
| + m_contextProvider = wrapUnique(Platform::current()->createOffscreenGraphicsContext3DProvider( |
| + contextAttributes, WebURL(), nullptr, &graphicsInfo)); |
| + if (waitableEvent) |
| + waitableEvent->signal(); |
| +} |
| + |
| +void SharedGpuContext::createContextProvider() |
| +{ |
| + std::unique_ptr<WebGraphicsContext3DProvider> oldContextProvider = std::move(m_contextProvider); |
| + if (isMainThread()) { |
| + m_contextProvider = wrapUnique(blink::Platform::current()->createSharedOffscreenGraphicsContext3DProvider()); |
| + } else { |
| + // This synchronous round-trip to the main thread is the reason why SharedGpuContext |
| + // encasulates the context provider: so we only have to do this once per thread. |
| + WaitableEvent waitableEvent; |
| + WebTaskRunner* taskRunner = Platform::current()->mainThread()->getWebTaskRunner(); |
| + taskRunner->postTask(BLINK_FROM_HERE, crossThreadBind(&SharedGpuContext::createContextProviderOnMainThread, crossThreadUnretained(this), crossThreadUnretained(&waitableEvent))); |
| + waitableEvent.wait(); |
| + if (m_contextProvider && !m_contextProvider->bindToCurrentThread()) |
| + m_contextProvider = nullptr; |
| + } |
| + |
| + if (m_contextProvider) { |
| + m_contextId++; |
| + // In the unlikely event of an overflow... |
| + if (m_contextId == kNoSharedContext) |
| + m_contextId++; |
| + } else { |
| + m_contextProvider = std::move(oldContextProvider); |
| + } |
| +} |
| + |
| +unsigned SharedGpuContext::contextId() |
| +{ |
| + SharedGpuContext* thisPtr = getInstanceForCurrentThread(); |
| + return thisPtr->m_contextId; |
| +} |
| + |
| +gpu::gles2::GLES2Interface* SharedGpuContext::gl() |
| +{ |
| + SharedGpuContext* thisPtr = getInstanceForCurrentThread(); |
| + if (thisPtr->m_contextProvider) |
| + return thisPtr->m_contextProvider->contextGL(); |
| + return nullptr; |
| +} |
| + |
| +GrContext* SharedGpuContext::gr() |
| +{ |
| + SharedGpuContext* thisPtr = getInstanceForCurrentThread(); |
| + if (thisPtr->m_contextProvider) |
| + return thisPtr->m_contextProvider->grContext(); |
| + return nullptr; |
| +} |
| + |
| +bool SharedGpuContext::isValid() |
| +{ |
| + SharedGpuContext* thisPtr = getInstanceForCurrentThread(); |
| + if (!thisPtr->m_contextProvider) |
| + return false; |
| + return thisPtr->m_contextProvider->contextGL()->GetGraphicsResetStatusKHR() == GL_NO_ERROR; |
| +} |
| + |
| +bool SharedGpuContext::restore() |
| +{ |
| + if (!isValid()) |
| + getInstanceForCurrentThread()->createContextProvider(); |
| + return isValid(); |
| +} |
| + |
| +} // blink |