Changeset 234377 in webkit
- Timestamp:
- Jul 30, 2018, 12:52:51 PM (7 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r234376 r234377 1 2018-07-30 Justin Fan <justin_fan@apple.com> 2 3 Match GraphicsContext3D with correct virtual screen using registryID 4 https://bugs.webkit.org/show_bug.cgi?id=188072 5 <rdar://problem/42634940> 6 7 Reviewed by Dean Jackson. 8 9 Follow up to https://bugs.webkit.org/show_bug.cgi?id=187750. Rather than matching rendererIDs, 10 which can vary between processes, match GPU to display using registryID that is unique to a GPU, 11 which was added to CGL in MacOS 10.13. 12 13 No new tests. Manually tested on MacBookPro13,3 and iMacPro1,1 with Apple DisplayPort Cinema Display 14 and RX 580 external GPU. 15 16 * platform/PlatformScreen.h: 17 * platform/ScreenProperties.h: 18 (WebCore::ScreenData::encode const): 19 (WebCore::ScreenData::decode): 20 * platform/graphics/cocoa/GraphicsContext3DCocoa.mm: 21 (WebCore::setGPUByRegistryID): 22 (WebCore::setGPUByDisplayMask): 23 (WebCore::GraphicsContext3D::GraphicsContext3D): 24 (WebCore::GraphicsContext3D::screenDidChange): 25 (WebCore::identifyAndSetCurrentGPU): Deleted. 26 * platform/mac/PlatformScreenMac.mm: 27 (WebCore::collectScreenProperties): 28 (WebCore::primaryRegistryID): 29 (WebCore::registryIDForDisplay): 30 (WebCore::registryIDForDisplayMask): 31 (WebCore::rendererIDForDisplayMask): Deleted. 32 (WebCore::rendererIDForDisplay): Deleted. 33 (WebCore::primaryRendererID): Deleted. 34 1 35 2018-07-30 Rob Buis <rbuis@igalia.com> 2 36 -
trunk/Source/WebCore/platform/PlatformScreen.h
r234074 r234377 59 59 60 60 using PlatformDisplayID = uint32_t; 61 using IORegistryGPUID = int64_t; // Global IOKit I/O registryID that can match a GPU across process boundaries. 61 62 62 63 int screenDepth(Widget*); … … 101 102 uint32_t primaryOpenGLDisplayMask(); 102 103 uint32_t displayMaskForDisplay(PlatformDisplayID); 103 int32_t rendererIDForDisplay(PlatformDisplayID); 104 int32_t primaryRendererID(); 104 105 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 106 IORegistryGPUID primaryGPUID(); 107 IORegistryGPUID gpuIDForDisplay(PlatformDisplayID); 108 IORegistryGPUID gpuIDForDisplayMask(uint32_t); 105 109 #endif 110 111 #endif // !PLATFORM(MAC) 106 112 107 113 #if PLATFORM(IOS) -
trunk/Source/WebCore/platform/ScreenProperties.h
r234074 r234377 47 47 bool screenIsMonochrome { false }; 48 48 uint32_t displayMask { 0 }; 49 int32_t rendererID { 0 };49 IORegistryGPUID gpuID { 0 }; 50 50 51 51 enum EncodedColorSpaceDataType { … … 95 95 void ScreenData::encode(Encoder& encoder) const 96 96 { 97 encoder << screenAvailableRect << screenRect << screenDepth << screenDepthPerComponent << screenSupportsExtendedColor << screenHasInvertedColors << screenIsMonochrome << displayMask << rendererID;97 encoder << screenAvailableRect << screenRect << screenDepth << screenDepthPerComponent << screenSupportsExtendedColor << screenHasInvertedColors << screenIsMonochrome << displayMask << gpuID; 98 98 99 99 if (colorSpace) { … … 164 164 return std::nullopt; 165 165 166 std::optional< int32_t> rendererID;167 decoder >> rendererID;168 if (! rendererID)166 std::optional<IORegistryGPUID> gpuID; 167 decoder >> gpuID; 168 if (!gpuID) 169 169 return std::nullopt; 170 170 … … 204 204 } 205 205 206 return { { WTFMove(*screenAvailableRect), WTFMove(*screenRect), WTFMove(cgColorSpace), WTFMove(*screenDepth), WTFMove(*screenDepthPerComponent), WTFMove(*screenSupportsExtendedColor), WTFMove(*screenHasInvertedColors), WTFMove(*screenIsMonochrome), WTFMove(*displayMask), WTFMove(* rendererID) } };206 return { { WTFMove(*screenAvailableRect), WTFMove(*screenRect), WTFMove(cgColorSpace), WTFMove(*screenDepth), WTFMove(*screenDepthPerComponent), WTFMove(*screenSupportsExtendedColor), WTFMove(*screenHasInvertedColors), WTFMove(*screenIsMonochrome), WTFMove(*displayMask), WTFMove(*gpuID) } }; 207 207 } 208 208 -
trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContext3DCocoa.mm
r234117 r234377 163 163 164 164 #if PLATFORM(MAC) 165 static void identifyAndSetCurrentGPU(PlatformGraphicsContext3D contextObj, CGLPixelFormatObj pixelFormatObj, GLint preferredRendererID) 166 { 167 // When the WebProcess does not have access to the WindowServer, there is no way for OpenGL to tell which GPU/renderer is connected to a display. 168 // Find the virtual screen that corresponds to the preferred renderer. 165 166 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 167 static void setGPUByRegistryID(PlatformGraphicsContext3D contextObj, CGLPixelFormatObj pixelFormatObj, IORegistryGPUID preferredGPUID) 168 { 169 // When the WebProcess does not have access to the WindowServer, there is no way for OpenGL to tell which GPU is connected to a display. 170 // On 10.13+, find the virtual screen that corresponds to the preferred GPU by its registryID. 169 171 // CGLSetVirtualScreen can then be used to tell OpenGL which GPU it should be using. 170 172 171 if (!contextObj || !preferred RendererID)173 if (!contextObj || !preferredGPUID) 172 174 return; 173 175 … … 179 181 180 182 for (GLint virtualScreen = 0; virtualScreen < virtualScreenCount; ++virtualScreen) { 181 GLint rendererID= 0;182 error = CGLDescribePixelFormat(pixelFormatObj, virtualScreen, kCGLPFA RendererID, &rendererID);183 GLint displayMask = 0; 184 error = CGLDescribePixelFormat(pixelFormatObj, virtualScreen, kCGLPFADisplayMask, &displayMask); 183 185 ASSERT(error == kCGLNoError); 184 if (error != kCGLNoError) 185 continue;186 187 if ( rendererID == preferredRendererID) {186 187 auto gpuID = gpuIDForDisplayMask(displayMask); 188 189 if (gpuID == preferredGPUID) { 188 190 error = CGLSetVirtualScreen(contextObj, virtualScreen); 189 191 ASSERT(error == kCGLNoError); 190 LOG(WebGL, "Context (%p) set to GPU renderer (%d).", contextObj, rendererID);192 LOG(WebGL, "Context (%p) set to GPU with ID: (%lld).", contextObj, gpuID); 191 193 return; 192 194 } … … 201 203 } 202 204 203 // No re nderermatch found; set to first hardware-accelerated virtual screen.205 // No registryID match found; set to first hardware-accelerated virtual screen. 204 206 if (firstAcceleratedScreen >= 0) { 205 207 error = CGLSetVirtualScreen(contextObj, firstAcceleratedScreen); 206 208 ASSERT(error == kCGLNoError); 207 LOG(WebGL, "Renderer (%d) not matched; Context (%p) set to virtual screen (%d).", preferredRendererID, contextObj, firstAcceleratedScreen); 208 } 209 } 210 #endif 209 LOG(WebGL, "RegistryID (%lld) not matched; Context (%p) set to virtual screen (%d).", preferredGPUID, contextObj, firstAcceleratedScreen); 210 } 211 } 212 #else // __MAC_OS_X_VERSION_MIN_REQUIRED < 101300 213 static void setGPUByDisplayMask(PlatformGraphicsContext3D contextObj, CGLPixelFormatObj pixelFormatObj, uint32_t preferredDisplayMask) 214 { 215 // A common case for multiple GPUs, external GPUs, is not supported before macOS 10.13.4. 216 // In the rarer case where there are still multiple displays plugged into multiple GPUs, this should still work. 217 // See code example at https://developer.apple.com/library/content/technotes/tn2229/_index.html#//apple_ref/doc/uid/DTS40008924-CH1-SUBSECTION7 218 // FIXME: Window server is not blocked before 10.14. There might be a more straightforward way to detect the correct GPU. 219 220 if (!contextObj || !preferredDisplayMask) 221 return; 222 223 GLint virtualScreenCount = 0; 224 CGLError error = CGLDescribePixelFormat(pixelFormatObj, 0, kCGLPFAVirtualScreenCount, &virtualScreenCount); 225 ASSERT(error == kCGLNoError); 226 227 for (GLint virtualScreen = 0; virtualScreen < virtualScreenCount; ++virtualScreen) { 228 GLint displayMask = 0; 229 error = CGLDescribePixelFormat(pixelFormatObj, virtualScreen, kCGLPFADisplayMask, &displayMask); 230 ASSERT(error == kCGLNoError); 231 if (error != kCGLNoError) 232 continue; 233 234 if (displayMask & preferredDisplayMask) { 235 error = CGLSetVirtualScreen(contextObj, virtualScreen); 236 ASSERT(error == kCGLNoError); 237 return; 238 } 239 } 240 } 241 #endif 242 243 #endif // !PLATFORM(MAC) 211 244 212 245 GraphicsContext3D::GraphicsContext3D(GraphicsContext3DAttributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle, GraphicsContext3D* sharedContext) … … 279 312 280 313 #if PLATFORM(MAC) 281 GLint rendererID = (hostWindow && hostWindow->displayID()) ? rendererIDForDisplay(hostWindow->displayID()) : primaryRendererID(); 282 identifyAndSetCurrentGPU(m_contextObj, pixelFormatObj, rendererID); 314 315 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 316 auto gpuID = (hostWindow && hostWindow->displayID()) ? gpuIDForDisplay(hostWindow->displayID()) : primaryGPUID(); 317 setGPUByRegistryID(m_contextObj, pixelFormatObj, gpuID); 318 #else 319 if (auto displayMask = primaryOpenGLDisplayMask()) { 320 if (hostWindow && hostWindow->displayID()) 321 displayMask = displayMaskForDisplay(hostWindow->displayID()); 322 setGPUByDisplayMask(m_contextObj, pixelFormatObj, displayMask); 323 } 324 #endif 325 283 326 #else 284 327 UNUSED_PARAM(hostWindow); 285 #endif 328 #endif // !PLATFORM(MAC) 286 329 287 330 CGLDestroyPixelFormat(pixelFormatObj); … … 604 647 if (!m_contextObj) 605 648 return; 606 607 identifyAndSetCurrentGPU(m_contextObj, CGLGetPixelFormat(m_contextObj), rendererIDForDisplay(displayID)); 608 } 609 #endif 649 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 650 setGPUByRegistryID(m_contextObj, CGLGetPixelFormat(m_contextObj), gpuIDForDisplay(displayID)); 651 #else 652 setGPUByDisplayMask(m_contextObj, CGLGetPixelFormat(m_contextObj), displayMaskForDisplay(displayID)); 653 #endif 654 } 655 #endif // !PLATFORM(MAC) 610 656 611 657 } -
trunk/Source/WebCore/platform/mac/PlatformScreenMac.mm
r234224 r234377 108 108 } 109 109 110 static GLint rendererIDForDisplayMask(GLuint displayMask)111 {112 GLint numRenderers;113 CGLRendererInfoObj rendererInfo;114 CGLError error = CGLQueryRendererInfo(displayMask, &rendererInfo, &numRenderers);115 ASSERT(error == kCGLNoError);116 117 GLint rendererID;118 error = CGLDescribeRenderer(rendererInfo, 0, kCGLRPRendererID, &rendererID);119 ASSERT(error == kCGLNoError);120 121 // The 0th renderer should not be the software renderer.122 GLint isAccelerated;123 error = CGLDescribeRenderer(rendererInfo, 0, kCGLRPAccelerated, &isAccelerated);124 ASSERT(error == kCGLNoError);125 ASSERT(isAccelerated);126 127 return rendererID;128 }129 130 110 ScreenProperties collectScreenProperties() 131 111 { … … 148 128 bool screenIsMonochrome = CGDisplayUsesForceToGray(); 149 129 uint32_t displayMask = CGDisplayIDToOpenGLDisplayMask(displayID); 150 GLint rendererID = rendererIDForDisplayMask(displayMask); 151 152 screenProperties.screenDataMap.set(displayID, ScreenData { screenAvailableRect, screenRect, colorSpace, screenDepth, screenDepthPerComponent, screenSupportsExtendedColor, screenHasInvertedColors, screenIsMonochrome, displayMask, rendererID }); 130 IORegistryGPUID gpuID = 0; 131 132 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 133 gpuID = gpuIDForDisplayMask(displayMask); 134 #endif 135 136 screenProperties.screenDataMap.set(displayID, ScreenData { screenAvailableRect, screenRect, colorSpace, screenDepth, screenDepthPerComponent, screenSupportsExtendedColor, screenHasInvertedColors, screenIsMonochrome, displayMask, gpuID }); 153 137 154 138 if (!screenProperties.primaryDisplayID) … … 197 181 } 198 182 199 GLint rendererIDForDisplay(PlatformDisplayID displayID) 183 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 184 IORegistryGPUID primaryGPUID() 185 { 186 return gpuIDForDisplay(screenProperties().primaryDisplayID); 187 } 188 189 IORegistryGPUID gpuIDForDisplay(PlatformDisplayID displayID) 200 190 { 201 191 #if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING) 202 192 if (!screenProperties().screenDataMap.isEmpty()) 203 return screenData(displayID). rendererID;193 return screenData(displayID).gpuID; 204 194 #else 205 return rendererIDForDisplayMask(CGDisplayIDToOpenGLDisplayMask(displayID));195 return gpuIDForDisplayMask(CGDisplayIDToOpenGLDisplayMask(displayID)); 206 196 #endif 207 197 return 0; 208 198 } 209 199 210 GLint primaryRendererID() 211 { 212 return rendererIDForDisplay(screenProperties().primaryDisplayID); 213 } 200 IORegistryGPUID gpuIDForDisplayMask(GLuint displayMask) 201 { 202 GLint numRenderers; 203 CGLRendererInfoObj rendererInfo; 204 CGLError error = CGLQueryRendererInfo(displayMask, &rendererInfo, &numRenderers); 205 ASSERT(error == kCGLNoError); 206 207 // The 0th renderer should not be the software renderer. 208 GLint isAccelerated; 209 error = CGLDescribeRenderer(rendererInfo, 0, kCGLRPAccelerated, &isAccelerated); 210 ASSERT(error == kCGLNoError); 211 ASSERT(isAccelerated); 212 213 GLint gpuIDLow; 214 GLint gpuIDHigh; 215 216 error = CGLDescribeRenderer(rendererInfo, 0, kCGLRPRegistryIDLow, &gpuIDLow); 217 ASSERT(error == kCGLNoError); 218 error = CGLDescribeRenderer(rendererInfo, 0, kCGLRPRegistryIDHigh, &gpuIDHigh); 219 ASSERT(error == kCGLNoError); 220 221 return (IORegistryGPUID) gpuIDHigh << 32 | gpuIDLow; 222 } 223 #endif // !__MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 214 224 215 225 static ScreenData getScreenProperties(Widget* widget)
Note:
See TracChangeset
for help on using the changeset viewer.