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 |