From d56ce7399f30420c38fb5913fb82ea8f3b5b48cc Mon Sep 17 00:00:00 2001 From: roytam1 Date: Tue, 15 Aug 2023 16:18:14 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1232506: Make dom/devicestorage really work with e10s. r=alchen (7f95105c5e) - Bug 1208944 - Part 1. Dispatch CompositionEvent to Plugin. r=masayuki (85c062b417) - Bug 1208944 - Part 2-a. Handle CompositionEvent on plugin. r=masayuki (ea2cebfca9) - Bug 1208944 - Part 2-b. Workaround for OSX. r=masayuki (ca401cbc04) - Bug 1208944 - Part 3. Allow IME window messages on plugin process. r=jmathies (571fd75010) - Bug 1192844: Accept 0xCC padding in WindowsDllDetourPatcher::CreateTrampoline. r=m_kato (b34b6173d3) - Bug 1201205 part 1: Add an AutoVirtualProtect helper class to make the next patch easier. r=m_kato (b384bd2412) - Bug 1201205 part 2: Restore protection on the nop space separately from the function. r=m_kato (a822b2414b) - Bug 1208944 - Part 4. nsWindowsDllInterceptor supports IMM32 API hook. r=ehsan (9b409ff15a) - Bug 1208944 - Part 5. Send PluginEvent to content process. r=jmathies (4ee0341190) - Bug 1208944 - Part 6. Get vaild TextRangeArray on compositionupdate. r=masayuki (18f184931c) - Bug 1208944 - Part 7. Don't post WM_IME_REQUEST on windowless plugin since we don't convert pointer over process. r=masayuki (6b1a9ce71f) - Bug 1208944 - Part 8. Don't get selection on start compostion when plugin has foucs. r=masayuki (daf400620e) - Add Telemetry for the drawing models that plugins use. (bug 1229961 part 1, r=aklotz,vladan) (c9645a68ec) - Enable direct plugin drawing by default. (bug 1229961 part 2, r=aklotz) (080c9337cb) - Bug 1213845 - enable osk support on windows 8, but hide it behind a preference, r=jaws (fcb8dfb10b) - Bug 1192248 - Fix wchar_t/char16_t mismatch WinIMEHandler.cpp. r=masayuki (13e61f3f0c) - Bug 1226145 - actually check whether the on-screen keyboard is up rather than relying on internal state, r=masayuki (da090b605d) - Bug 1208944 - Part 9. Hook IMM32 APIs on plugin process. r=masayuki (f15d73721f) - Bug 1208944 - Part 10-a. Call CallWindowProc when WidgetPluginEvent isn't handled by plugin. r=masayuki (c54eaa50ed) - Bug 1208944 - Part 10-b. Call DefaultProc When CompositionEvent isn't handled correctly by plugin. r=masayuki (0e77eaa40f) - Bug 1157046 - Remove ARRAY_LENGTH in favor of MOZ_ARRAY_LENGTH; r=Waldo (a7f8ce3684) - Bug 1196834 - Add a test that confirms plugin windows are hidden after switching from a remote to local tab. r=roc (a09d4a32af) - Bug 1208944 - Part 11. Add test. r=jmathies (ed8e4c87d2) - Bug 1231378 - part 1 - Fix uninitialized members of classes in docshell/*, r=smaug (fcd7615d97) - Bug 1231378 - part 2 - Fix uninitialized members of classes in dom/*,r=smaug (40b354438f) - Bug 1231378 - part 3 - Fix uninitialized members of classes in module/libjar and mfbt, r=smaug (ee15d8739a) - Bug 1231378 - part 4 - Fix uninitialized members of classes in netwerk/widget/storage/uriloader/memory/tools, r=smaug (6aec559dd8) - Bug 1238082 - Fix mode lines in dom/ipc. r=baku (a49aa3555b) - Bug 1024149 - Use element size for upload texture when using SVG image. r=jgilbert r=roc (531bdd2406) - Bug 1233922 - Skip Camera preinit for browser elements. r=fabrice (cd8ffbb112) - Bug 1159327 - Enable accessibility more broadly with e10s and add an e10s a11y blacklist for clients with known issues. r=tbsaunde (374f49a942) - Bug 1198459 - Prevent accessibility from initializing in content processes when e10s is running. r=tbsaunde (33bdfccd56) - Bug 1115956 - Improve notice string for when e10s was disabled for accessibility. r=mconley (e5ff276d9e) - Bug 1172491 - Let e10s be enabled in safe mode. r=felipe (bd0a3fbbd5) - Bug 1226487 - Allow e10s to run on Beta. r=mconley (05103c816d) - Bug 634063 - Use gfxPrefs for some layers acceleration prefs. r=nical (9a20bcd8d2) - Bug 1198459 - Add support for disabling e10s if a11y was run in the previous session, or run in a session over the previous week. r=felipe (7154a021bd) - Bug 1171171 - Make sure the graphics preferences are initialized early enough. r=billm (34801701aa) - Bug 1171171: Move nsAppRunner's gfxPrefs #include out of windows-specific section. r=milan a=KWierso (492fa00f99) - Bug 1182048 - Part 1: Allow e10s to be enabled,r=vlad (628949ad83) - Bug 1182048 - Part 2: Implement e10s support for WebVR,r=vlad (a77d280b48) - Bug 1207221 - Do not prevent the system app from vibrating when it is hidden. r=bz r=dhylands (f3d2306f41) - Bug 1233902 - Check the TP list in sendBeacon(). r=gcp (bc279755ab) - Bug 1216207 - Modify navigator.hasFeature method to implement new (9b4571468e) - Bug 1217187 - Modify navigator.hasFeature method to detect new (d9ea58e65c) - Bug 1125477 - Part 1: Modify dom/tv mochitest in order to enable e10s test. r=seanlin (7b535fddaa) - Bug 1125477 - Part 2: Modify permission check of TV Manager API in order to remove dom.testing.tv_enabled_for_hosted_apps. r=seanlin;r=smaug (5719fdf3a7) - Bug 1125477 - Part3: Remove permission removing code. r=seanlin (614de5dfd1) - Bug 1223672 - NSec package cannot use device storage API. r=kchen (f1fc6711ea) - Bug 1224609 - Ensure the primary screen is always returned in RecvScreenForBrowser if all else fails. r=wmccloskey (d562935754) - Bug 1180288 - Use native filepickers for Graphene. r=khuey (0b9c78ce13) - Bug 1201394 - Use cached preferences value in ProcessPriorityManager. r=gsvelto (d211492014) - Bug 1212833 - Delay the MemoryPressure when an application goes to background. r=gsvelto (ce33de4324) - Bug 1186812 (part 1) - Replace nsBaseHashtable::EnumerateRead() calls in dom/{ipc,plugins}/. r=jimm. (c061bb9d1b) - Bug 1212984 - HangMonitorChild should delete its Transport. r=billm (3331593b2d) - Bug 1186812 (part 2) - Replace nsBaseHashtable::EnumerateRead() calls in dom/{ipc,plugins}/. r=jimm. (fdac3f52cb) - Bug 1215239 - Do not set ownApp for a browser element. r=bholley (e3cc250c3f) - Bug 1241278 - Change Notification.requestPermission() to return a promise. r=baku (b0a86eeeb5) - Bug 1249102. Make overrides of WorkerRunnable::PostRun a bit more consistent. r=khuey (a23bf9468f) - Bug 1209812 (part 6) - Convert all gfxImageFormat values to SurfaceFormat equivalents. r=jrmuizel. (9a5da3597f) - Bug 1239225 - Remove unused args from TextureImage's constructor and related functions. r=mattwoodrow. (26ff005ecb) - Bug 1240708 - Various trivial coverity warning fixes. r=kats (74a485c2b8) - Bug 1240708 - Various trivial coverity warning fixes (part 2). r=kats (34bcd568dc) - Bug 1219494 - Part 3 gfx/gl with gfxCrash. r=mchang (268968a3d9) - Bug 1232456 - Create EGL surface through widget; r=snorp (13634bebc6) - Bug 1232456 - Renew EGL surface using existing compositor widget; r=snorp (2649b088d3) - Bug 1187322 - Don't require accelerated OpenGL contexts for BasicCompositor on OS X. r=jrmuizel (87f92af2c8) - Bug 1238753 - Use StartRemoteDrawingInRegion on Mac. r=mattwoodrow (22870ed043) - Bug 1238755 - Avoid a copy when uploading the BasicCompositor result to a texture. r=mattwoodrow (0b6663ab61) - Bug 890156 - patch 0.2 - Remove the (unused) aRect parameter from nsBaseWidget::BaseCreate. r=kats (1120763eef) - Bug 1241983 - Make DOM Identity observe inner-window-destroyed not dom-window-destroyed; r=ferjm (7cf4cf3211) - Bug 1236282 - Clip color layer drawing in BasicCompositor so that unbounded operators don't erase stuff outside the layer. r=Bas (a7e73d1d8d) - Bug 1238753 - Make BasicCompositor respect changes to mInvalidRegion through StartRemoteDrawingWithRegion properly. r=mattwoodrow (36e20bccce) - Bug 1238753 - Don't skip the call to StartRemoteDrawing in from BasicCompositor::BeginFrame if the invalid region is empty. r=mattwoodrow (783b25775f) - Bug 1239137 - Return early from BasicCompositor::DrawQuad if transformBounds is empty. r=mattwoodrow (0815cfc28a) - Bug 1239530 (part 1) - Remove PuppetWidget::Scroll(), which is dead. r=kats. (63ab8c32b6) - Bug 1239530 (part 2) - Use LayoutDevice coordinates in {Start,End}RemoteDrawingInRegion() and related functions. r=kats. (609001767d) - Bug 1239537 - Remove Compositor::GetWidgetSize(), which is unused. r=mattwoodrow. (25732d37b1) - Bug 1242293 - Don't call EndRemoteDrawingInRegion if StartRemoteDrawingInRegion returns a null DrawTarget. r=mstange (8e297c3b84) - import changes from mozilla: Bug 1211642: Whitelist test plugin for async plugin init; r=jimm (f02deaaeb8) (6689ce99c8) --- b2g/app/b2g.js | 1 + b2g/components/B2GComponents.manifest | 2 + docshell/base/SerializedLoadContext.h | 5 + dom/alarm/AlarmHalService.h | 4 + dom/base/ImageEncoder.cpp | 2 +- dom/base/Navigator.cpp | 97 +++-- dom/base/Navigator.h | 5 +- dom/base/WebSocket.cpp | 14 + dom/base/nsDocument.cpp | 14 +- dom/base/nsGlobalWindow.cpp | 19 +- dom/base/nsGlobalWindow.h | 12 +- dom/base/nsIDocument.h | 6 +- dom/base/nsPIDOMWindow.h | 4 +- .../test/test_frameLoader_switchProcess.html | 5 +- dom/base/test/test_getFeature_with_perm.html | 1 + dom/base/test/test_hasFeature.html | 59 ++- .../BroadcastChannelChild.cpp | 3 +- dom/canvas/CanvasRenderingContext2D.cpp | 2 +- dom/canvas/WebGLContext.h | 3 +- dom/datastore/DataStoreService.cpp | 2 + dom/devicestorage/DeviceStorageStatics.cpp | 62 ++- dom/devicestorage/DeviceStorageStatics.h | 9 + dom/events/EventStateManager.cpp | 4 + dom/events/TextComposition.cpp | 37 +- dom/events/TextComposition.h | 16 + dom/fetch/InternalRequest.cpp | 1 - dom/fetch/InternalRequest.h | 2 +- dom/geolocation/nsGeolocationSettings.h | 9 +- dom/identity/nsDOMIdentity.js | 8 +- dom/indexedDB/IDBRequest.cpp | 14 + dom/ipc/Blob.cpp | 3 +- dom/ipc/ContentChild.cpp | 22 +- dom/ipc/ContentChild.h | 9 +- dom/ipc/ContentParent.cpp | 44 +- dom/ipc/ContentParent.h | 8 +- dom/ipc/CrashReporterParent.cpp | 6 +- dom/ipc/PBrowser.ipdl | 12 + dom/ipc/PContent.ipdl | 13 + dom/ipc/ProcessHangMonitor.cpp | 27 +- dom/ipc/ProcessPriorityManager.cpp | 170 ++++++-- dom/ipc/ScreenManagerParent.cpp | 8 +- dom/ipc/TabChild.cpp | 20 +- dom/ipc/TabChild.h | 1 + dom/ipc/TabContext.cpp | 13 +- dom/ipc/TabParent.cpp | 25 ++ dom/ipc/TabParent.h | 8 +- dom/media/android/AndroidMediaReader.cpp | 2 +- .../webrtc/MediaEngineTabVideoSource.cpp | 2 +- dom/messagechannel/MessagePortChild.h | 2 +- .../MobileCallForwardingOptions.h | 10 +- .../ipc/MobileConnectionChild.cpp | 2 + dom/network/UDPSocket.cpp | 2 + dom/notification/Notification.cpp | 61 ++- dom/notification/Notification.h | 7 +- dom/plugins/base/nsPluginHost.cpp | 4 + dom/plugins/base/nsPluginHost.h | 2 + dom/plugins/base/nsPluginInstanceOwner.cpp | 398 +++++++++++++++++- dom/plugins/base/nsPluginInstanceOwner.h | 19 + dom/plugins/base/nsPluginTags.cpp | 1 + dom/plugins/ipc/NPEventWindows.h | 12 + dom/plugins/ipc/PPluginInstance.ipdl | 9 + dom/plugins/ipc/PluginInstanceChild.cpp | 170 +++++++- dom/plugins/ipc/PluginInstanceChild.h | 10 + dom/plugins/ipc/PluginInstanceParent.cpp | 86 +++- dom/plugins/ipc/PluginInstanceParent.h | 18 + dom/plugins/ipc/PluginQuirks.cpp | 7 + dom/plugins/ipc/PluginQuirks.h | 2 + dom/plugins/test/mochitest/browser.ini | 6 + .../test/mochitest/browser_bug1163570.js | 140 ++++++ dom/plugins/test/mochitest/mochitest.ini | 2 + dom/plugins/test/mochitest/plugin_test.html | 10 + .../test/mochitest/test_windowless_ime.html | 46 ++ dom/plugins/test/moz.build | 1 + dom/plugins/test/testplugin/nptest.cpp | 88 +++- dom/plugins/test/testplugin/nptest.h | 2 + dom/plugins/test/testplugin/nptest_platform.h | 7 + .../test/testplugin/nptest_windows.cpp | 64 +++ .../test/testplugin/testplugin.mozbuild | 1 + dom/power/PowerManagerService.h | 4 + .../test_notification_basics.html | 45 +- dom/tv/TVServiceFactory.cpp | 2 +- dom/tv/TVTuner.cpp | 1 + dom/tv/TVTypes.cpp | 5 +- dom/tv/test/mochitest/file_app.sjs | 55 --- .../test/mochitest/file_app.template.webapp | 6 - .../test/mochitest/file_tv_get_channels.html | 60 --- .../file_tv_get_channels_during_scanning.html | 58 --- .../file_tv_get_current_program.html | 68 --- .../test/mochitest/file_tv_get_programs.html | 71 ---- .../test/mochitest/file_tv_get_sources.html | 49 --- dom/tv/test/mochitest/file_tv_get_tuners.html | 38 -- .../mochitest/file_tv_non_permitted_app.html | 17 - .../test/mochitest/file_tv_permitted_app.html | 16 - .../file_tv_scan_channels_completed.html | 68 --- .../file_tv_scan_channels_stopped.html | 66 --- .../file_tv_set_current_channel.html | 70 --- ...v_set_current_channel_during_scanning.html | 58 --- .../mochitest/file_tv_set_current_source.html | 48 --- .../file_tv_set_invalid_current_channel.html | 49 --- .../file_tv_set_invalid_current_source.html | 36 -- dom/tv/test/mochitest/head.js | 118 ++---- dom/tv/test/mochitest/mochitest.ini | 24 +- dom/tv/test/mochitest/test_helpers.js | 17 - .../test/mochitest/test_tv_get_channels.html | 57 ++- .../test_tv_get_channels_during_scanning.html | 54 ++- .../test_tv_get_current_program.html | 64 ++- .../test/mochitest/test_tv_get_programs.html | 68 ++- .../test/mochitest/test_tv_get_sources.html | 47 ++- dom/tv/test/mochitest/test_tv_get_tuners.html | 36 +- .../mochitest/test_tv_non_permitted_app.html | 33 +- .../test/mochitest/test_tv_permitted_app.html | 19 +- .../test_tv_scan_channels_completed.html | 64 ++- .../test_tv_scan_channels_stopped.html | 62 ++- .../test_tv_set_current_channel.html | 66 ++- ...v_set_current_channel_during_scanning.html | 54 ++- .../mochitest/test_tv_set_current_source.html | 44 +- .../test_tv_set_invalid_current_channel.html | 45 +- .../test_tv_set_invalid_current_source.html | 35 +- dom/vr/VRDevice.cpp | 287 ++++++------- dom/vr/VRDevice.h | 85 +++- dom/webidl/Navigator.webidl | 2 +- dom/webidl/Notification.webidl | 2 +- dom/webidl/TVChannel.webidl | 2 +- .../TVCurrentChannelChangedEvent.webidl | 2 +- dom/webidl/TVCurrentSourceChangedEvent.webidl | 2 +- dom/webidl/TVEITBroadcastedEvent.webidl | 2 +- dom/webidl/TVManager.webidl | 2 +- dom/webidl/TVProgram.webidl | 2 +- dom/webidl/TVScanningStateChangedEvent.webidl | 2 +- dom/webidl/TVSource.webidl | 2 +- dom/webidl/TVTuner.webidl | 2 +- dom/workers/ServiceWorkerPrivate.cpp | 2 + dom/workers/WorkerPrivate.cpp | 4 +- dom/workers/WorkerRunnable.cpp | 28 +- dom/workers/WorkerRunnable.h | 5 +- editor/libeditor/SetDocTitleTxn.cpp | 3 +- editor/libeditor/nsHTMLEditRules.cpp | 7 + editor/libeditor/nsHTMLEditor.cpp | 25 ++ editor/libeditor/nsHTMLURIRefObject.cpp | 2 +- editor/libeditor/nsTextEditRules.cpp | 9 + editor/libeditor/nsTextEditRules.h | 21 +- editor/txtsvc/nsFilteredContentIterator.h | 2 +- gfx/2d/Logging.h | 5 +- gfx/2d/Types.h | 3 + gfx/gl/GLBlitHelper.cpp | 2 +- gfx/gl/GLContext.cpp | 6 +- gfx/gl/GLContext.h | 5 +- gfx/gl/GLContextEAGL.h | 3 +- gfx/gl/GLContextEGL.h | 4 +- gfx/gl/GLContextProviderCGL.mm | 27 +- gfx/gl/GLContextProviderEAGL.mm | 2 +- gfx/gl/GLContextProviderEGL.cpp | 52 +-- gfx/gl/GLContextProviderGLX.cpp | 2 +- gfx/gl/GLContextProviderImpl.h | 3 +- gfx/gl/GLContextProviderNull.cpp | 2 +- gfx/gl/GLContextProviderWGL.cpp | 2 +- gfx/gl/GLLibraryEGL.cpp | 7 +- gfx/gl/GLLibraryLoader.cpp | 3 +- gfx/gl/GLReadTexImageHelper.cpp | 6 +- gfx/gl/GLReadTexImageHelper.h | 6 +- gfx/gl/GLScreenBuffer.cpp | 12 +- gfx/gl/GLTextureImage.cpp | 18 +- gfx/gl/GLTextureImage.h | 13 +- gfx/gl/SharedSurface.cpp | 12 +- gfx/gl/SharedSurfaceANGLE.cpp | 6 +- gfx/gl/SharedSurfaceGLX.cpp | 2 +- gfx/gl/TextureImageCGL.h | 6 +- gfx/gl/TextureImageCGL.mm | 12 +- gfx/gl/TextureImageEGL.h | 2 +- gfx/ipc/GfxMessageUtils.h | 12 +- gfx/ipc/SharedDIBSurface.cpp | 2 +- gfx/layers/Compositor.h | 2 - gfx/layers/ImageContainer.cpp | 8 +- gfx/layers/ImageContainer.h | 1 - gfx/layers/ImageDataSerializer.cpp | 1 - gfx/layers/Layers.cpp | 9 +- gfx/layers/Layers.h | 22 +- gfx/layers/apz/src/HitTestingTreeNode.cpp | 5 +- gfx/layers/basic/BasicCompositor.cpp | 63 ++- gfx/layers/basic/BasicCompositor.h | 7 +- gfx/layers/basic/BasicLayerManager.cpp | 4 +- gfx/layers/client/ClientLayerManager.cpp | 2 +- .../client/SingleTiledContentClient.cpp | 2 + gfx/layers/client/TiledContentClient.cpp | 2 + .../composite/ContainerLayerComposite.cpp | 9 +- gfx/layers/d3d11/CompositorD3D11.cpp | 12 +- gfx/layers/d3d11/CompositorD3D11.h | 4 +- gfx/layers/d3d9/CompositorD3D9.cpp | 4 +- gfx/layers/d3d9/CompositorD3D9.h | 7 +- gfx/layers/ipc/CompositorParent.cpp | 18 + gfx/layers/ipc/CompositorParent.h | 4 +- gfx/layers/ipc/LayerTransactionParent.cpp | 12 +- gfx/layers/ipc/LayersMessages.ipdlh | 5 +- gfx/layers/ipc/SharedRGBImage.cpp | 6 +- .../opengl/CompositingRenderTargetOGL.cpp | 2 +- gfx/layers/opengl/CompositorOGL.cpp | 14 +- gfx/layers/opengl/CompositorOGL.h | 7 +- gfx/layers/opengl/TextureHostOGL.cpp | 3 +- gfx/tests/gtest/TestTextures.cpp | 12 +- gfx/tests/gtest/gfxSurfaceRefCountTest.cpp | 2 +- gfx/thebes/gfx2DGlue.h | 20 +- gfx/thebes/gfxASurface.cpp | 34 +- gfx/thebes/gfxAlphaRecovery.cpp | 8 +- gfx/thebes/gfxAlphaRecoverySSE2.cpp | 10 +- gfx/thebes/gfxAndroidPlatform.cpp | 6 +- gfx/thebes/gfxImageSurface.cpp | 31 +- gfx/thebes/gfxPlatform.cpp | 33 +- gfx/thebes/gfxPlatform.h | 13 +- gfx/thebes/gfxPlatformGtk.cpp | 4 +- gfx/thebes/gfxPlatformMac.h | 8 +- gfx/thebes/gfxQPainterSurface.cpp | 2 +- gfx/thebes/gfxQtPlatform.cpp | 4 +- gfx/thebes/gfxQuartzSurface.cpp | 7 +- gfx/thebes/gfxTypes.h | 28 -- gfx/thebes/gfxUtils.cpp | 22 +- gfx/thebes/gfxUtils.h | 4 +- gfx/thebes/gfxWindowsSurface.cpp | 10 +- gfx/thebes/gfxWindowsSurface.h | 4 +- gfx/thebes/gfxXlibNativeRenderer.cpp | 11 +- gfx/thebes/gfxXlibSurface.cpp | 16 +- gfx/vr/VRDeviceProxy.cpp | 153 +++++++ gfx/vr/VRDeviceProxy.h | 57 +++ gfx/vr/VRDeviceProxyOrientationFallBack.cpp | 199 +++++++++ gfx/vr/VRDeviceProxyOrientationFallBack.h | 54 +++ gfx/vr/VRManager.cpp | 221 ++++++++++ gfx/vr/VRManager.h | 65 +++ gfx/vr/gfxVR.cpp | 137 +----- gfx/vr/gfxVR.h | 192 +++++---- gfx/vr/gfxVRCardboard.cpp | 264 +++--------- gfx/vr/gfxVRCardboard.h | 44 +- gfx/vr/gfxVROculus.cpp | 317 ++++++++------ gfx/vr/gfxVROculus.h | 42 +- gfx/vr/gfxVROculus050.cpp | 300 ++++++++----- gfx/vr/gfxVROculus050.h | 49 ++- gfx/vr/ipc/PVRManager.ipdl | 63 +++ gfx/vr/ipc/VRManagerChild.cpp | 186 ++++++++ gfx/vr/ipc/VRManagerChild.h | 60 +++ gfx/vr/ipc/VRManagerParent.cpp | 198 +++++++++ gfx/vr/ipc/VRManagerParent.h | 80 ++++ gfx/vr/ipc/VRMessageUtils.h | 209 +++++++++ gfx/vr/moz.build | 14 + gfx/ycbcr/YCbCrUtils.cpp | 2 +- hal/Hal.cpp | 6 + layout/base/nsDisplayList.cpp | 4 +- layout/base/nsDisplayList.h | 6 +- layout/base/nsLayoutUtils.cpp | 21 +- layout/base/nsLayoutUtils.h | 5 +- layout/generic/nsFrame.cpp | 6 +- layout/style/test/ListCSSProperties.cpp | 14 +- memory/volatile/VolatileBuffer.h | 6 +- mfbt/FastBernoulliTrial.h | 5 +- mfbt/ThreadLocal.h | 4 + modules/libjar/nsJAR.cpp | 2 + modules/libjar/nsJAR.h | 5 +- modules/libjar/nsJARChannel.cpp | 1 + modules/libjar/nsJARInputStream.h | 6 +- modules/libjar/zipwriter/nsZipWriter.cpp | 7 +- modules/libpref/init/all.js | 14 +- modules/libpref/nsPrefBranch.h | 5 +- netwerk/dns/ChildDNSService.cpp | 1 + netwerk/dns/DNS.cpp | 6 + netwerk/dns/DNSRequestParent.cpp | 3 +- netwerk/dns/nsDNSService2.cpp | 4 + netwerk/dns/nsIDNService.cpp | 2 + storage/mozStorageBindingParams.cpp | 1 + storage/mozStorageRow.h | 2 + storage/mozStorageStatementData.h | 1 + storage/mozStorageStatementParams.cpp | 3 +- .../tests/notifications/interfaces.html | 2 +- toolkit/components/telemetry/Histograms.json | 8 + toolkit/xre/nsAppRunner.cpp | 118 +++--- toolkit/xre/test/win/TestDllInterceptor.cpp | 3 + tools/profiler/public/GeckoProfilerImpl.h | 1 + .../prefetch/OfflineCacheUpdateChild.cpp | 1 + uriloader/prefetch/nsOfflineCacheUpdate.cpp | 2 + widget/BasicEvents.h | 2 + widget/ContentCache.cpp | 18 +- widget/MiscEvents.h | 14 + widget/MouseEvents.h | 29 ++ widget/PluginWidgetProxy.cpp | 2 +- widget/PuppetWidget.cpp | 21 +- widget/PuppetWidget.h | 11 +- widget/ScreenProxy.cpp | 6 +- widget/TextEvents.h | 18 + widget/TextRange.h | 20 + widget/cocoa/nsChildView.h | 2 +- widget/cocoa/nsChildView.mm | 46 +- widget/cocoa/nsCocoaWindow.mm | 6 +- widget/cocoa/nsDeviceContextSpecX.mm | 2 +- widget/gonk/nsWindow.cpp | 2 +- widget/gtk/nsWindow.cpp | 22 +- widget/gtk/nsWindow.h | 6 +- widget/nsBaseWidget.cpp | 13 +- widget/nsBaseWidget.h | 7 +- widget/nsDeviceContextSpecProxy.cpp | 2 +- widget/nsFilePickerProxy.cpp | 1 + widget/nsIWidget.h | 38 +- widget/nsShmImage.cpp | 18 +- widget/nsShmImage.h | 11 +- widget/qt/nsWindow.cpp | 2 +- widget/uikit/nsWindow.mm | 4 +- widget/windows/IMMHandler.cpp | 147 ++++--- widget/windows/IMMHandler.h | 24 +- widget/windows/TaskbarPreview.cpp | 2 +- widget/windows/WinIMEHandler.cpp | 91 ++-- widget/windows/WinIMEHandler.h | 19 +- widget/windows/nsWindow.cpp | 37 +- widget/windows/nsWindow.h | 5 + widget/windows/nsWindowBase.h | 8 - widget/windows/nsWindowGfx.cpp | 2 +- widget/xremoteclient/XRemoteClient.cpp | 10 +- xpcom/build/nsWindowsDllInterceptor.h | 208 ++++++--- xpcom/system/nsIXULRuntime.idl | 8 +- 313 files changed, 6036 insertions(+), 3093 deletions(-) create mode 100644 dom/plugins/test/mochitest/browser.ini create mode 100644 dom/plugins/test/mochitest/browser_bug1163570.js create mode 100644 dom/plugins/test/mochitest/plugin_test.html create mode 100644 dom/plugins/test/mochitest/test_windowless_ime.html delete mode 100644 dom/tv/test/mochitest/file_app.sjs delete mode 100644 dom/tv/test/mochitest/file_app.template.webapp delete mode 100644 dom/tv/test/mochitest/file_tv_get_channels.html delete mode 100644 dom/tv/test/mochitest/file_tv_get_channels_during_scanning.html delete mode 100644 dom/tv/test/mochitest/file_tv_get_current_program.html delete mode 100644 dom/tv/test/mochitest/file_tv_get_programs.html delete mode 100644 dom/tv/test/mochitest/file_tv_get_sources.html delete mode 100644 dom/tv/test/mochitest/file_tv_get_tuners.html delete mode 100644 dom/tv/test/mochitest/file_tv_non_permitted_app.html delete mode 100644 dom/tv/test/mochitest/file_tv_permitted_app.html delete mode 100644 dom/tv/test/mochitest/file_tv_scan_channels_completed.html delete mode 100644 dom/tv/test/mochitest/file_tv_scan_channels_stopped.html delete mode 100644 dom/tv/test/mochitest/file_tv_set_current_channel.html delete mode 100644 dom/tv/test/mochitest/file_tv_set_current_channel_during_scanning.html delete mode 100644 dom/tv/test/mochitest/file_tv_set_current_source.html delete mode 100644 dom/tv/test/mochitest/file_tv_set_invalid_current_channel.html delete mode 100644 dom/tv/test/mochitest/file_tv_set_invalid_current_source.html delete mode 100644 dom/tv/test/mochitest/test_helpers.js create mode 100644 gfx/vr/VRDeviceProxy.cpp create mode 100644 gfx/vr/VRDeviceProxy.h create mode 100644 gfx/vr/VRDeviceProxyOrientationFallBack.cpp create mode 100644 gfx/vr/VRDeviceProxyOrientationFallBack.h create mode 100644 gfx/vr/VRManager.cpp create mode 100644 gfx/vr/VRManager.h create mode 100644 gfx/vr/ipc/PVRManager.ipdl create mode 100644 gfx/vr/ipc/VRManagerChild.cpp create mode 100644 gfx/vr/ipc/VRManagerChild.h create mode 100644 gfx/vr/ipc/VRManagerParent.cpp create mode 100644 gfx/vr/ipc/VRManagerParent.h create mode 100644 gfx/vr/ipc/VRMessageUtils.h diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index 093a04a707..27fc5474c1 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -679,6 +679,7 @@ pref("layout.css.scroll-snap.enabled", true); pref("dom.ipc.processPriorityManager.enabled", true); pref("dom.ipc.processPriorityManager.backgroundGracePeriodMS", 1000); pref("dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS", 5000); +pref("dom.ipc.processPriorityManager.memoryPressureGracePeriodMS", 3000); pref("dom.ipc.processPriorityManager.temporaryPriorityLockMS", 5000); // Number of different background/foreground levels for background/foreground diff --git a/b2g/components/B2GComponents.manifest b/b2g/components/B2GComponents.manifest index 1ebe4b4b6c..f8ee912448 100644 --- a/b2g/components/B2GComponents.manifest +++ b/b2g/components/B2GComponents.manifest @@ -75,9 +75,11 @@ component {920400b1-cf8f-4760-a9c4-441417b15134} B2GAboutRedirector.js contract @mozilla.org/network/protocol/about;1?what=certerror {920400b1-cf8f-4760-a9c4-441417b15134} contract @mozilla.org/network/protocol/about;1?what=neterror {920400b1-cf8f-4760-a9c4-441417b15134} +#ifndef MOZ_GRAPHENE # FilePicker.js component {436ff8f9-0acc-4b11-8ec7-e293efba3141} FilePicker.js contract @mozilla.org/filepicker;1 {436ff8f9-0acc-4b11-8ec7-e293efba3141} +#endif # WebappsUpdateTimer.js component {637b0f77-2429-49a0-915f-abf5d0db8b9a} WebappsUpdateTimer.js diff --git a/docshell/base/SerializedLoadContext.h b/docshell/base/SerializedLoadContext.h index 02cb6a72a2..b574b39fbf 100644 --- a/docshell/base/SerializedLoadContext.h +++ b/docshell/base/SerializedLoadContext.h @@ -28,6 +28,11 @@ class SerializedLoadContext { public: SerializedLoadContext() + : mIsNotNull(false) + , mIsPrivateBitValid(false) + , mIsContent(false) + , mUsePrivateBrowsing(false) + , mUseRemoteTabs(false) { Init(nullptr); } diff --git a/dom/alarm/AlarmHalService.h b/dom/alarm/AlarmHalService.h index dcb62e0ccc..4e062b9a78 100644 --- a/dom/alarm/AlarmHalService.h +++ b/dom/alarm/AlarmHalService.h @@ -33,6 +33,10 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSIALARMHALSERVICE + AlarmHalService() + : mAlarmEnabled(false) + {} + void Init(); static already_AddRefed GetInstance(); diff --git a/dom/base/ImageEncoder.cpp b/dom/base/ImageEncoder.cpp index 4942633157..bd8c5b18f1 100644 --- a/dom/base/ImageEncoder.cpp +++ b/dom/base/ImageEncoder.cpp @@ -395,7 +395,7 @@ ImageEncoder::ExtractDataInternal(const nsAString& aType, if (aImage->GetFormat() == ImageFormat::PLANAR_YCBCR) { nsTArray data; layers::PlanarYCbCrImage* ycbcrImage = static_cast (aImage); - gfxImageFormat format = gfxImageFormat::ARGB32; + gfxImageFormat format = SurfaceFormat::A8R8G8B8_UINT32; uint32_t stride = GetAlignedStride<16>(aSize.width * 4); size_t length = BufferSizeFromStrideAndHeight(stride, aSize.height); data.SetCapacity(length); diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index fb3680054b..e2fdd5bdc6 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -211,6 +211,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCachedResolveResults) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeviceStorageAreaListener) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresentation) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRGetDevicesPromises) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END @@ -344,6 +345,8 @@ Navigator::Invalidate() if (mDeviceStorageAreaListener) { mDeviceStorageAreaListener = nullptr; } + + mVRGetDevicesPromises.Clear(); } //***************************************************************************** @@ -769,13 +772,25 @@ NS_IMPL_ISUPPORTS(VibrateWindowListener, nsIDOMEventListener) StaticRefPtr gVibrateWindowListener; +static bool +MayVibrate(nsIDocument* doc) { +#if MOZ_WIDGET_GONK + if (XRE_IsParentProcess()) { + return true; // The system app can always vibrate + } +#endif // MOZ_WIDGET_GONK + + // Hidden documents cannot start or stop a vibration. + return (doc && !doc->Hidden()); +} + NS_IMETHODIMP VibrateWindowListener::HandleEvent(nsIDOMEvent* aEvent) { nsCOMPtr doc = do_QueryInterface(aEvent->InternalDOMEvent()->GetTarget()); - if (!doc || doc->Hidden()) { + if (!MayVibrate(doc)) { // It's important that we call CancelVibrate(), not Vibrate() with an // empty list, because Vibrate() will fail if we're no longer focused, but // CancelVibrate() will succeed, so long as nobody else has started a new @@ -848,12 +863,8 @@ Navigator::Vibrate(const nsTArray& aPattern) } nsCOMPtr doc = mWindow->GetExtantDoc(); - if (!doc) { - return false; - } - if (doc->Hidden()) { - // Hidden documents cannot start or stop a vibration. + if (!MayVibrate(doc)) { return false; } @@ -1187,13 +1198,19 @@ Navigator::SendBeacon(const nsAString& aUrl, return false; } + nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL | + nsIChannel::LOAD_CLASSIFY_URI; + nsCOMPtr channel; rv = NS_NewChannel(getter_AddRefs(channel), uri, doc, nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS | nsILoadInfo::SEC_COOKIES_INCLUDE, - nsIContentPolicy::TYPE_BEACON); + nsIContentPolicy::TYPE_BEACON, + nullptr, // aLoadGroup + nullptr, // aCallbacks + loadFlags); if (NS_FAILED(rv)) { aRv.Throw(rv); @@ -1568,9 +1585,10 @@ Navigator::HasFeature(const nsAString& aName, ErrorResult& aRv) return nullptr; } - // Hardcoded web-extensions feature which is b2g specific. + // Hardcoded extensions features which are b2g specific. #ifdef MOZ_B2G - if (aName.EqualsLiteral("web-extensions")) { + if (aName.EqualsLiteral("web-extensions") || + aName.EqualsLiteral("late-customization")) { p->MaybeResolve(true); return p.forget(); } @@ -1583,6 +1601,7 @@ Navigator::HasFeature(const nsAString& aName, ErrorResult& aRv) #ifdef MOZ_B2G , "manifest.chrome.navigation" , "manifest.precompile" + , "manifest.role.homescreen" #endif }; @@ -1907,16 +1926,35 @@ Navigator::GetVRDevices(ErrorResult& aRv) return nullptr; } + // We pass ourself to RefreshVRDevices, so NotifyVRDevicesUpdated will + // be called asynchronously, resolving the promises in mVRGetDevicesPromises. + if (!VRDevice::RefreshVRDevices(this)) { + p->MaybeReject(NS_ERROR_FAILURE); + return p.forget(); + } + + mVRGetDevicesPromises.AppendElement(p); + return p.forget(); +} + +void +Navigator::NotifyVRDevicesUpdated() +{ + // Synchronize the VR devices and resolve the promises in + // mVRGetDevicesPromises nsGlobalWindow* win = static_cast(mWindow.get()); nsTArray> vrDevs; - if (!win->GetVRDevices(vrDevs)) { - p->MaybeReject(NS_ERROR_FAILURE); + if (win->UpdateVRDevices(vrDevs)) { + for (auto p: mVRGetDevicesPromises) { + p->MaybeResolve(vrDevs); + } } else { - p->MaybeResolve(vrDevs); + for (auto p: mVRGetDevicesPromises) { + p->MaybeReject(NS_ERROR_FAILURE); + } } - - return p.forget(); + mVRGetDevicesPromises.Clear(); } //***************************************************************************** @@ -2549,37 +2587,6 @@ Navigator::HasMobileIdSupport(JSContext* aCx, JSObject* aGlobal) } #endif -/* static */ -bool -Navigator::HasTVSupport(JSContext* aCx, JSObject* aGlobal) -{ - JS::Rooted global(aCx, aGlobal); - - nsCOMPtr win = GetWindowFromGlobal(global); - if (!win) { - return false; - } - - // Just for testing, we can enable TV for any kind of app. - if (Preferences::GetBool("dom.testing.tv_enabled_for_hosted_apps", false)) { - return true; - } - - nsIDocument* doc = win->GetExtantDoc(); - if (!doc || !doc->NodePrincipal()) { - return false; - } - - nsIPrincipal* principal = doc->NodePrincipal(); - uint16_t status; - if (NS_FAILED(principal->GetAppStatus(&status))) { - return false; - } - - // Only support TV Manager API for certified apps for now. - return status == nsIPrincipal::APP_STATUS_CERTIFIED; -} - /* static */ bool Navigator::IsE10sEnabled(JSContext* aCx, JSObject* aGlobal) diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h index 84f69ac876..f7fa6f1449 100644 --- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h @@ -265,6 +265,7 @@ public: void GetGamepads(nsTArray >& aGamepads, ErrorResult& aRv); #endif // MOZ_GAMEPAD already_AddRefed GetVRDevices(ErrorResult& aRv); + void NotifyVRDevicesUpdated(); #ifdef MOZ_B2G_FM FMRadio* GetMozFMRadio(ErrorResult& aRv); #endif @@ -334,8 +335,6 @@ public: static bool HasMobileIdSupport(JSContext* aCx, JSObject* aGlobal); #endif - static bool HasTVSupport(JSContext* aCx, JSObject* aGlobal); - static bool IsE10sEnabled(JSContext* aCx, JSObject* aGlobal); nsPIDOMWindow* GetParentObject() const @@ -402,6 +401,8 @@ private: // we'd need to figure out exactly how to trace that, and that seems to be // rocket science. :( nsInterfaceHashtable mCachedResolveResults; + + nsTArray > mVRGetDevicesPromises; }; } // namespace dom diff --git a/dom/base/WebSocket.cpp b/dom/base/WebSocket.cpp index 5e9d7da500..b548a90b45 100644 --- a/dom/base/WebSocket.cpp +++ b/dom/base/WebSocket.cpp @@ -2552,6 +2552,9 @@ public: bool PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate) { + // We don't call WorkerRunnable::PreDispatch because it would assert the + // wrong thing about which thread we're on. + AssertIsOnMainThread(); return true; } @@ -2559,6 +2562,9 @@ public: PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aDispatchResult) { + // We don't call WorkerRunnable::PostDispatch because it would assert the + // wrong thing about which thread we're on. + AssertIsOnMainThread(); } private: @@ -2723,6 +2729,10 @@ public: bool PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate) { + // We don't call WorkerRunnable::PreDispatch because it would assert the + // wrong thing about which thread we're on. We're on whichever thread the + // channel implementation is running on (probably the main thread or socket + // transport thread). return true; } @@ -2730,6 +2740,10 @@ public: PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aDispatchResult) { + // We don't call WorkerRunnable::PreDispatch because it would assert the + // wrong thing about which thread we're on. We're on whichever thread the + // channel implementation is running on (probably the main thread or socket + // transport thread). } private: diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 0edf189f33..0d59976bf0 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -10970,7 +10970,7 @@ nsIDocument::MozCancelFullScreen() // Element::UnbindFromTree(). class nsSetWindowFullScreen : public nsRunnable { public: - nsSetWindowFullScreen(nsIDocument* aDoc, bool aValue, gfx::VRHMDInfo* aHMD = nullptr) + nsSetWindowFullScreen(nsIDocument* aDoc, bool aValue, gfx::VRDeviceProxy* aHMD = nullptr) : mDoc(aDoc), mValue(aValue), mHMD(aHMD) {} NS_IMETHOD Run() @@ -10984,7 +10984,7 @@ public: private: nsCOMPtr mDoc; bool mValue; - RefPtr mHMD; + RefPtr mHMD; }; static nsIDocument* @@ -11004,7 +11004,7 @@ GetFullscreenRootDocument(nsIDocument* aDoc) } static void -SetWindowFullScreen(nsIDocument* aDoc, bool aValue, gfx::VRHMDInfo *aVRHMD = nullptr) +SetWindowFullScreen(nsIDocument* aDoc, bool aValue, gfx::VRDeviceProxy *aVRHMD = nullptr) { // Maintain list of fullscreen root documents. nsCOMPtr root = GetFullscreenRootDocument(aDoc); @@ -11651,10 +11651,10 @@ nsresult nsDocument::RemoteFrameFullscreenReverted() } static void -ReleaseHMDInfoRef(void *, nsIAtom*, void *aPropertyValue, void *) +ReleaseVRDeviceProxyRef(void *, nsIAtom*, void *aPropertyValue, void *) { if (aPropertyValue) { - static_cast(aPropertyValue)->Release(); + static_cast(aPropertyValue)->Release(); } } @@ -11751,9 +11751,9 @@ nsDocument::RequestFullScreen(Element* aElement, // Process options -- in this case, just HMD if (aOptions.mVRHMDDevice) { - RefPtr hmdRef = aOptions.mVRHMDDevice; + RefPtr hmdRef = aOptions.mVRHMDDevice; aElement->SetProperty(nsGkAtoms::vr_state, hmdRef.forget().take(), - ReleaseHMDInfoRef, + ReleaseVRDeviceProxyRef, true); } diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 31e7527266..f07563b6e8 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -1180,8 +1180,7 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) mCleanedUp(false), mDialogAbuseCount(0), mAreDialogsEnabled(true), - mCanSkipCCGeneration(0), - mVRDevicesInitialized(false) + mCanSkipCCGeneration(0) { AssertIsOnMainThread(); @@ -6284,7 +6283,7 @@ nsGlobalWindow::SetFullScreen(bool aFullScreen) nsresult nsGlobalWindow::SetFullScreenInternal(bool aFullScreen, bool aFullscreenMode, - gfx::VRHMDInfo* aHMD) + gfx::VRDeviceProxy* aHMD) { MOZ_ASSERT(IsOuterWindow()); @@ -13579,19 +13578,11 @@ nsGlobalWindow::SyncGamepadState() #endif // MOZ_GAMEPAD bool -nsGlobalWindow::GetVRDevices(nsTArray>& aDevices) +nsGlobalWindow::UpdateVRDevices(nsTArray>& aDevices) { - FORWARD_TO_INNER(GetVRDevices, (aDevices), false); + FORWARD_TO_INNER(UpdateVRDevices, (aDevices), false); - if (!mVRDevicesInitialized) { - bool ok = mozilla::dom::VRDevice::CreateAllKnownVRDevices(ToSupports(this), mVRDevices); - if (!ok) { - mVRDevices.Clear(); - return false; - } - } - - mVRDevicesInitialized = true; + VRDevice::UpdateVRDevices(mVRDevices, ToSupports(this)); aDevices = mVRDevices; return true; } diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index a61d1b1e67..ac76fbae43 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -129,7 +129,7 @@ class IDBFactory; } // namespace indexedDB } // namespace dom namespace gfx { -class VRHMDInfo; +class VRDeviceProxy; } // namespace gfx } // namespace mozilla @@ -467,7 +467,7 @@ public: // Outer windows only. virtual nsresult SetFullScreenInternal(bool aIsFullscreen, bool aFullscreenMode, - mozilla::gfx::VRHMDInfo *aHMD = nullptr) override; + mozilla::gfx::VRDeviceProxy *aHMD = nullptr) override; bool FullScreen() const; // Inner windows only. @@ -755,8 +755,8 @@ public: void EnableGamepadUpdates(); void DisableGamepadUpdates(); - // Get the VR devices for this window, initializing if necessary - bool GetVRDevices(nsTArray>& aDevices); + // Update the VR devices for this window + bool UpdateVRDevices(nsTArray>& aDevices); #define EVENT(name_, id_, type_, struct_) \ mozilla::dom::EventHandlerNonNull* GetOn##name_() \ @@ -1822,12 +1822,8 @@ protected: // This is the CC generation the last time we called CanSkip. uint32_t mCanSkipCCGeneration; - // Did VR get initialized for this window? - bool mVRDevicesInitialized; // The VRDevies for this window nsTArray> mVRDevices; - // Any attached HMD when fullscreen - RefPtr mVRHMDInfo; friend class nsDOMScriptableHelper; friend class nsDOMWindowUtils; diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 2bd23b255f..f3fc673b09 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -103,10 +103,6 @@ class ImageLoader; class Rule; } // namespace css -namespace gfx { -class VRHMDInfo; -} // namespace gfx - namespace dom { class AnonymousContent; class Attr; @@ -154,7 +150,7 @@ typedef CallbackObjectHolder NodeFilterHolder; struct FullScreenOptions { FullScreenOptions(); - RefPtr mVRHMDDevice; + RefPtr mVRHMDDevice; }; } // namespace dom diff --git a/dom/base/nsPIDOMWindow.h b/dom/base/nsPIDOMWindow.h index f1c889f1af..435757f744 100644 --- a/dom/base/nsPIDOMWindow.h +++ b/dom/base/nsPIDOMWindow.h @@ -41,7 +41,7 @@ class Element; class ServiceWorkerRegistrationMainThread; } // namespace dom namespace gfx { -class VRHMDInfo; +class VRDeviceProxy; } // namespace gfx } // namespace mozilla @@ -500,7 +500,7 @@ public: * Outer windows only. */ virtual nsresult SetFullScreenInternal(bool aIsFullscreen, bool aFullscreenMode, - mozilla::gfx::VRHMDInfo *aHMD = nullptr) = 0; + mozilla::gfx::VRDeviceProxy *aHMD = nullptr) = 0; /** * Call this to check whether some node (this window, its document, diff --git a/dom/base/test/test_frameLoader_switchProcess.html b/dom/base/test/test_frameLoader_switchProcess.html index 92b25cb06f..01de7ff93f 100644 --- a/dom/base/test/test_frameLoader_switchProcess.html +++ b/dom/base/test/test_frameLoader_switchProcess.html @@ -62,10 +62,7 @@ } SpecialPowers.pushPrefEnv( - // XXX Set LRUPoolLevels to 2 to avoid breaking priority tests - { "set": [["dom.ipc.processPriorityManager.BACKGROUND.LRUPoolLevels", 2], - ["dom.ipc.processPriorityManager.BACKGROUND_PERCEIVABLE.LRUPoolLevels", 2], - ["dom.ipc.processPriorityManager.testMode", true], + { "set": [["dom.ipc.processPriorityManager.testMode", true], ["dom.ipc.processPriorityManager.enabled", true], ["dom.ipc.tabs.disabled", false], ["dom.ipc.processCount", 3], diff --git a/dom/base/test/test_getFeature_with_perm.html b/dom/base/test/test_getFeature_with_perm.html index eec8288f06..0c6fb7b370 100644 --- a/dom/base/test/test_getFeature_with_perm.html +++ b/dom/base/test/test_getFeature_with_perm.html @@ -126,6 +126,7 @@ SpecialPowers.pushPermissions([ info("Adding B2G specific tests"); tests.push(createManifestTest("manifest.chrome.navigation")); tests.push(createManifestTest("manifest.precompile")); + tests.push(createManifestTest("manifest.role.homescreen")); } runNextTest(); ok(true, "Test DONE"); diff --git a/dom/base/test/test_hasFeature.html b/dom/base/test/test_hasFeature.html index 3dc7eb9a2a..fcc6ca809b 100644 --- a/dom/base/test/test_hasFeature.html +++ b/dom/base/test/test_hasFeature.html @@ -13,22 +13,17 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1009645 Mozilla Bug 1009645 + + + + + + + + + + + diff --git a/dom/plugins/test/moz.build b/dom/plugins/test/moz.build index 0697391174..00896ed50d 100644 --- a/dom/plugins/test/moz.build +++ b/dom/plugins/test/moz.build @@ -11,4 +11,5 @@ XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini'] if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3', 'cocoa', 'windows'): MOCHITEST_MANIFESTS += ['mochitest/mochitest.ini'] MOCHITEST_CHROME_MANIFESTS += ['mochitest/chrome.ini'] + BROWSER_CHROME_MANIFESTS += ['mochitest/browser.ini'] diff --git a/dom/plugins/test/testplugin/nptest.cpp b/dom/plugins/test/testplugin/nptest.cpp index 3a67b04e27..bff23163be 100644 --- a/dom/plugins/test/testplugin/nptest.cpp +++ b/dom/plugins/test/testplugin/nptest.cpp @@ -36,6 +36,7 @@ #include "nptest_utils.h" #include "nptest_platform.h" +#include "mozilla/ArrayUtils.h" #include "mozilla/IntentionalCrash.h" #include @@ -61,7 +62,6 @@ using namespace std; #define PLUGIN_VERSION "1.0.0.0" -#define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0])) extern const char *sPluginName; extern const char *sPluginDescription; @@ -171,6 +171,8 @@ static bool echoString(NPObject* npobj, const NPVariant* args, uint32_t argCount static bool startAudioPlayback(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); static bool stopAudioPlayback(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); static bool getAudioMuted(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); +static bool nativeWidgetIsVisible(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); +static bool getLastCompositionText(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result); static const NPUTF8* sPluginMethodIdentifierNames[] = { "npnEvaluateTest", @@ -240,8 +242,10 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = { "startAudioPlayback", "stopAudioPlayback", "audioMuted", + "nativeWidgetIsVisible", + "getLastCompositionText", }; -static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)]; +static NPIdentifier sPluginMethodIdentifiers[MOZ_ARRAY_LENGTH(sPluginMethodIdentifierNames)]; static const ScriptableFunction sPluginMethodFunctions[] = { npnEvaluateTest, npnInvokeTest, @@ -310,17 +314,19 @@ static const ScriptableFunction sPluginMethodFunctions[] = { startAudioPlayback, stopAudioPlayback, getAudioMuted, + nativeWidgetIsVisible, + getLastCompositionText, }; -static_assert(ARRAY_LENGTH(sPluginMethodIdentifierNames) == - ARRAY_LENGTH(sPluginMethodFunctions), +static_assert(MOZ_ARRAY_LENGTH(sPluginMethodIdentifierNames) == + MOZ_ARRAY_LENGTH(sPluginMethodFunctions), "Arrays should have the same size"); static const NPUTF8* sPluginPropertyIdentifierNames[] = { "propertyAndMethod" }; -static NPIdentifier sPluginPropertyIdentifiers[ARRAY_LENGTH(sPluginPropertyIdentifierNames)]; -static NPVariant sPluginPropertyValues[ARRAY_LENGTH(sPluginPropertyIdentifierNames)]; +static NPIdentifier sPluginPropertyIdentifiers[MOZ_ARRAY_LENGTH(sPluginPropertyIdentifierNames)]; +static NPVariant sPluginPropertyValues[MOZ_ARRAY_LENGTH(sPluginPropertyIdentifierNames)]; struct URLNotifyData { @@ -397,9 +403,9 @@ static void initializeIdentifiers() { if (!sIdentifiersInitialized) { NPN_GetStringIdentifiers(sPluginMethodIdentifierNames, - ARRAY_LENGTH(sPluginMethodIdentifierNames), sPluginMethodIdentifiers); + MOZ_ARRAY_LENGTH(sPluginMethodIdentifierNames), sPluginMethodIdentifiers); NPN_GetStringIdentifiers(sPluginPropertyIdentifierNames, - ARRAY_LENGTH(sPluginPropertyIdentifierNames), sPluginPropertyIdentifiers); + MOZ_ARRAY_LENGTH(sPluginPropertyIdentifierNames), sPluginPropertyIdentifiers); sIdentifiersInitialized = true; @@ -413,9 +419,9 @@ static void initializeIdentifiers() static void clearIdentifiers() { memset(sPluginMethodIdentifiers, 0, - ARRAY_LENGTH(sPluginMethodIdentifiers) * sizeof(NPIdentifier)); + MOZ_ARRAY_LENGTH(sPluginMethodIdentifiers) * sizeof(NPIdentifier)); memset(sPluginPropertyIdentifiers, 0, - ARRAY_LENGTH(sPluginPropertyIdentifiers) * sizeof(NPIdentifier)); + MOZ_ARRAY_LENGTH(sPluginPropertyIdentifiers) * sizeof(NPIdentifier)); sIdentifiersInitialized = false; } @@ -725,7 +731,7 @@ NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs) initializeIdentifiers(); - for (unsigned int i = 0; i < ARRAY_LENGTH(sPluginPropertyValues); i++) { + for (unsigned int i = 0; i < MOZ_ARRAY_LENGTH(sPluginPropertyValues); i++) { VOID_TO_NPVARIANT(sPluginPropertyValues[i]); } @@ -776,7 +782,7 @@ NPError OSCALL NP_Shutdown() { clearIdentifiers(); - for (unsigned int i = 0; i < ARRAY_LENGTH(sPluginPropertyValues); i++) { + for (unsigned int i = 0; i < MOZ_ARRAY_LENGTH(sPluginPropertyValues); i++) { NPN_ReleaseVariantValue(&sPluginPropertyValues[i]); } @@ -841,6 +847,7 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* instanceData->asyncDrawing = AD_NONE; instanceData->frontBuffer = nullptr; instanceData->backBuffer = nullptr; + instanceData->placeholderWnd = nullptr; instance->pdata = instanceData; TestNPObject* scriptableObject = (TestNPObject*)NPN_CreateObject(instance, &sNPClass); @@ -2012,7 +2019,7 @@ scriptableInvalidate(NPObject* npobj) bool scriptableHasMethod(NPObject* npobj, NPIdentifier name) { - for (int i = 0; i < int(ARRAY_LENGTH(sPluginMethodIdentifiers)); i++) { + for (int i = 0; i < int(MOZ_ARRAY_LENGTH(sPluginMethodIdentifiers)); i++) { if (name == sPluginMethodIdentifiers[i]) return true; } @@ -2038,7 +2045,7 @@ scriptableInvoke(NPObject* npobj, NPIdentifier name, const NPVariant* args, uint return false; } - for (int i = 0; i < int(ARRAY_LENGTH(sPluginMethodIdentifiers)); i++) { + for (int i = 0; i < int(MOZ_ARRAY_LENGTH(sPluginMethodIdentifiers)); i++) { if (name == sPluginMethodIdentifiers[i]) return sPluginMethodFunctions[i](npobj, args, argCount, result); } @@ -2107,7 +2114,7 @@ scriptableHasProperty(NPObject* npobj, NPIdentifier name) Crash(); } } - for (int i = 0; i < int(ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) { + for (int i = 0; i < int(MOZ_ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) { if (name == sPluginPropertyIdentifiers[i]) { return true; } @@ -2118,7 +2125,7 @@ scriptableHasProperty(NPObject* npobj, NPIdentifier name) bool scriptableGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* result) { - for (int i = 0; i < int(ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) { + for (int i = 0; i < int(MOZ_ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) { if (name == sPluginPropertyIdentifiers[i]) { DuplicateNPVariant(*result, sPluginPropertyValues[i]); return true; @@ -2130,7 +2137,7 @@ scriptableGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* result) bool scriptableSetProperty(NPObject* npobj, NPIdentifier name, const NPVariant* value) { - for (int i = 0; i < int(ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) { + for (int i = 0; i < int(MOZ_ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) { if (name == sPluginPropertyIdentifiers[i]) { NPN_ReleaseVariantValue(&sPluginPropertyValues[i]); DuplicateNPVariant(sPluginPropertyValues[i], *value); @@ -2143,7 +2150,7 @@ scriptableSetProperty(NPObject* npobj, NPIdentifier name, const NPVariant* value bool scriptableRemoveProperty(NPObject* npobj, NPIdentifier name) { - for (int i = 0; i < int(ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) { + for (int i = 0; i < int(MOZ_ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) { if (name == sPluginPropertyIdentifiers[i]) { NPN_ReleaseVariantValue(&sPluginPropertyValues[i]); @@ -2159,14 +2166,14 @@ scriptableRemoveProperty(NPObject* npobj, NPIdentifier name) bool scriptableEnumerate(NPObject* npobj, NPIdentifier** identifier, uint32_t* count) { - const int bufsize = sizeof(NPIdentifier) * ARRAY_LENGTH(sPluginMethodIdentifierNames); + const int bufsize = sizeof(NPIdentifier) * MOZ_ARRAY_LENGTH(sPluginMethodIdentifierNames); NPIdentifier* ids = (NPIdentifier*) NPN_MemAlloc(bufsize); if (!ids) return false; memcpy(ids, sPluginMethodIdentifiers, bufsize); *identifier = ids; - *count = ARRAY_LENGTH(sPluginMethodIdentifierNames); + *count = MOZ_ARRAY_LENGTH(sPluginMethodIdentifierNames); return true; } @@ -3470,6 +3477,47 @@ destroySharedGfxStuff(NPObject* npobj, const NPVariant* args, } #endif +#if defined(XP_WIN) +bool +nativeWidgetIsVisible(NPObject* npobj, const NPVariant* args, + uint32_t argCount, NPVariant* result) +{ + NPP npp = static_cast(npobj)->npp; + InstanceData* id = static_cast(npp->pdata); + bool visible = pluginNativeWidgetIsVisible(id); + BOOLEAN_TO_NPVARIANT(visible, *result); + return true; +} +#else +bool +nativeWidgetIsVisible(NPObject* npobj, const NPVariant* args, + uint32_t argCount, NPVariant* result) +{ + // XXX Not implemented! + return false; +} +#endif + +bool +getLastCompositionText(NPObject* npobj, const NPVariant* args, + uint32_t argCount, NPVariant* result) +{ +#ifdef XP_WIN + if (argCount != 0) { + return false; + } + + NPP npp = static_cast(npobj)->npp; + InstanceData* id = static_cast(npp->pdata); + char *outval = NPN_StrDup(id->lastComposition.c_str()); + STRINGZ_TO_NPVARIANT(outval, *result); + return true; +#else + // XXX not implemented + return false; +#endif +} + bool callOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result) { diff --git a/dom/plugins/test/testplugin/nptest.h b/dom/plugins/test/testplugin/nptest.h index 12e427a5e6..2fbc2d4b43 100644 --- a/dom/plugins/test/testplugin/nptest.h +++ b/dom/plugins/test/testplugin/nptest.h @@ -156,6 +156,8 @@ typedef struct InstanceData { AsyncDrawing asyncDrawing; NPAsyncSurface *frontBuffer; NPAsyncSurface *backBuffer; + std::string lastComposition; + void* placeholderWnd; } InstanceData; void notifyDidPaint(InstanceData* instanceData); diff --git a/dom/plugins/test/testplugin/nptest_platform.h b/dom/plugins/test/testplugin/nptest_platform.h index 361fca3de4..3f23121e1d 100644 --- a/dom/plugins/test/testplugin/nptest_platform.h +++ b/dom/plugins/test/testplugin/nptest_platform.h @@ -145,4 +145,11 @@ bool pluginCrashInNestedLoop(InstanceData* instanceData); */ bool pluginDestroySharedGfxStuff(InstanceData* instanceData); +/** + * Checks to see if the native widget is marked as visible. Works + * in e10s and non-e10s. Useful in testing e10s related compositor + * plugin window functionality. Supported on Windows. + */ +bool pluginNativeWidgetIsVisible(InstanceData* instanceData); + #endif // nptest_platform_h_ diff --git a/dom/plugins/test/testplugin/nptest_windows.cpp b/dom/plugins/test/testplugin/nptest_windows.cpp index 5c8a06111c..8b02872e95 100644 --- a/dom/plugins/test/testplugin/nptest_windows.cpp +++ b/dom/plugins/test/testplugin/nptest_windows.cpp @@ -654,6 +654,29 @@ pluginGetClipRegionRectEdge(InstanceData* instanceData, return NPTEST_INT32_ERROR; } +static +void +createDummyWindowForIME(InstanceData* instanceData) +{ + WNDCLASSW wndClass; + wndClass.style = 0; + wndClass.lpfnWndProc = DefWindowProcW; + wndClass.cbClsExtra = 0; + wndClass.cbWndExtra = 0; + wndClass.hInstance = GetModuleHandleW(NULL); + wndClass.hIcon = nullptr; + wndClass.hCursor = nullptr; + wndClass.hbrBackground = (HBRUSH)COLOR_WINDOW; + wndClass.lpszMenuName = NULL; + wndClass.lpszClassName = L"SWFlash_PlaceholderX"; + RegisterClassW(&wndClass); + + instanceData->placeholderWnd = + static_cast(CreateWindowW(L"SWFlash_PlaceholderX", L"", WS_CHILD, 0, + 0, 0, 0, HWND_MESSAGE, NULL, + GetModuleHandleW(NULL), NULL)); +} + /* windowless plugin events */ static bool @@ -725,6 +748,35 @@ handleEventInternal(InstanceData* instanceData, NPEvent* pe, LRESULT* result) return true; } + case WM_IME_STARTCOMPOSITION: + instanceData->lastComposition.erase(); + if (!instanceData->placeholderWnd) { + createDummyWindowForIME(instanceData); + } + return true; + + case WM_IME_ENDCOMPOSITION: + instanceData->lastComposition.erase(); + return true; + + case WM_IME_COMPOSITION: { + if (pe->lParam & GCS_COMPSTR) { + HIMC hIMC = ImmGetContext((HWND)instanceData->placeholderWnd); + if (!hIMC) { + return false; + } + WCHAR compStr[256]; + LONG len = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, compStr, + 256 * sizeof(WCHAR)); + CHAR buffer[256]; + len = ::WideCharToMultiByte(CP_UTF8, 0, compStr, len / sizeof(WCHAR), + buffer, 256, nullptr, nullptr); + instanceData->lastComposition.append(buffer, len); + ::ImmReleaseContext((HWND)instanceData->placeholderWnd, hIMC); + } + return true; + } + default: return false; } @@ -812,3 +864,15 @@ void pluginDoInternalConsistencyCheck(InstanceData* instanceData, string& error) checkEquals(childRect.bottom, childRect.top + CHILD_WIDGET_SIZE, "Child widget height", error); } } + +bool pluginNativeWidgetIsVisible(InstanceData* instanceData) +{ + HWND hWnd = (HWND)instanceData->window.window; + wchar_t className[60]; + if (::GetClassNameW(hWnd, className, sizeof(className) / sizeof(char16_t)) && + !wcsicmp(className, L"GeckoPluginWindow")) { + return ::IsWindowVisible(hWnd); + } + // something isn't right, fail the check + return false; +} diff --git a/dom/plugins/test/testplugin/testplugin.mozbuild b/dom/plugins/test/testplugin/testplugin.mozbuild index d2909bf41a..d450d05ab9 100644 --- a/dom/plugins/test/testplugin/testplugin.mozbuild +++ b/dom/plugins/test/testplugin/testplugin.mozbuild @@ -38,6 +38,7 @@ elif toolkit == 'windows': ] OS_LIBS += [ 'msimg32', + 'imm32' ] # must link statically with the CRT; nptest isn't Gecko code diff --git a/dom/power/PowerManagerService.h b/dom/power/PowerManagerService.h index ccf5ae2d45..d346cc4508 100644 --- a/dom/power/PowerManagerService.h +++ b/dom/power/PowerManagerService.h @@ -31,6 +31,10 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSIPOWERMANAGERSERVICE + PowerManagerService() + : mWatchdogTimeoutSecs(0) + {} + static already_AddRefed GetInstance(); void Init(); diff --git a/dom/tests/mochitest/notification/test_notification_basics.html b/dom/tests/mochitest/notification/test_notification_basics.html index 23888ba755..3d0465c3fe 100644 --- a/dom/tests/mochitest/notification/test_notification_basics.html +++ b/dom/tests/mochitest/notification/test_notification_basics.html @@ -28,38 +28,51 @@ }, function () { - info("Test blank requestPermission"); + info("Test requestPermission without callback"); Notification.requestPermission(); }, function (done) { info("Test requestPermission deny"); - NotificationTest.denyNotifications(); - Notification.requestPermission(function(perm) { + function assertPermissionDenied(perm) { is(perm, "denied", "Permission should be denied."); is(Notification.permission, "denied", "Permission should be denied."); - done(); - }); + } + NotificationTest.denyNotifications(); + Notification.requestPermission() + .then(assertPermissionDenied) + .then(_ => Notification.requestPermission(assertPermissionDenied)) + .catch(err => { + ok(!err, "requestPermission should not reject promise"); + }) + .then(done); }, function (done) { info("Test requestPermission grant"); - NotificationTest.allowNotifications(); - Notification.requestPermission(function (perm) { + function assertPermissionGranted(perm) { is(perm, "granted", "Permission should be granted."); is(Notification.permission, "granted", "Permission should be granted"); - done(); - }); + } + NotificationTest.allowNotifications(); + Notification.requestPermission() + .then(assertPermissionGranted) + .then(_ => Notification.requestPermission(assertPermissionGranted)) + .catch(err => { + ok(!err, "requestPermission should not reject promise"); + }) + .then(done); }, - function () { + function (done) { info("Test invalid requestPermission"); - try { - Notification.requestPermission({}); - ok(false, "Non callable arg to requestPermission should throw"); - } catch (e) { - ok(true, "Non callable arg to requestPermission should throw"); - } + Notification.requestPermission({}) + .then(_ => { + ok(false, "Non callable arg to requestPermission should reject promise"); + }, err => { + ok(true, "Non callable arg to requestPermission should reject promise"); + }) + .then(done); }, function (done) { diff --git a/dom/tv/TVServiceFactory.cpp b/dom/tv/TVServiceFactory.cpp index 49cb4157d8..70979505b3 100644 --- a/dom/tv/TVServiceFactory.cpp +++ b/dom/tv/TVServiceFactory.cpp @@ -28,7 +28,7 @@ TVServiceFactory::AutoCreateTVService() nsresult rv; nsCOMPtr service = do_CreateInstance(TV_SERVICE_CONTRACTID); if (!service) { - if (Preferences::GetBool("dom.testing.tv_enabled_for_hosted_apps", false)) { + if (Preferences::GetBool("dom.ignore_webidl_scope_checks", false)) { // Fallback to the fake service. service = do_CreateInstance(FAKE_TV_SERVICE_CONTRACTID, &rv); } else { diff --git a/dom/tv/TVTuner.cpp b/dom/tv/TVTuner.cpp index 0431156c0b..e358d4f255 100644 --- a/dom/tv/TVTuner.cpp +++ b/dom/tv/TVTuner.cpp @@ -32,6 +32,7 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) TVTuner::TVTuner(nsPIDOMWindow* aWindow) : DOMEventTargetHelper(aWindow) + , mStreamType(0) { } diff --git a/dom/tv/TVTypes.cpp b/dom/tv/TVTypes.cpp index 399feda773..424605e7b4 100644 --- a/dom/tv/TVTypes.cpp +++ b/dom/tv/TVTypes.cpp @@ -20,6 +20,7 @@ NS_IMPL_ISUPPORTS(TVTunerData, nsITVTunerData) TVTunerData::TVTunerData() : mSupportedSourceTypes(nullptr) , mCount(0) + , mStreamType(0) { } @@ -275,7 +276,9 @@ TVChannelData::SetIsFree(bool aIsFree) NS_IMPL_ISUPPORTS(TVProgramData, nsITVProgramData) TVProgramData::TVProgramData() - : mAudioLanguages(nullptr) + : mStartTime(0) + , mDuration(0) + , mAudioLanguages(nullptr) , mAudioLanguageCount(0) , mSubtitleLanguages(nullptr) , mSubtitleLanguageCount(0) diff --git a/dom/tv/test/mochitest/file_app.sjs b/dom/tv/test/mochitest/file_app.sjs deleted file mode 100644 index 506b679f3a..0000000000 --- a/dom/tv/test/mochitest/file_app.sjs +++ /dev/null @@ -1,55 +0,0 @@ -var gBasePath = "tests/dom/tv/test/mochitest/"; - -function handleRequest(request, response) { - var query = getQuery(request); - - var testToken = ''; - if ('testToken' in query) { - testToken = query.testToken; - } - - var template = ''; - if ('template' in query) { - template = query.template; - } - var template = gBasePath + template; - response.setHeader("Content-Type", "application/x-web-app-manifest+json", false); - response.write(readTemplate(template).replace(/TESTTOKEN/g, testToken)); -} - -// Copy-pasted incantations. There ought to be a better way to synchronously read -// a file into a string, but I guess we're trying to discourage that. -function readTemplate(path) { - var file = Components.classes["@mozilla.org/file/directory_service;1"]. - getService(Components.interfaces.nsIProperties). - get("CurWorkD", Components.interfaces.nsILocalFile); - var fis = Components.classes['@mozilla.org/network/file-input-stream;1']. - createInstance(Components.interfaces.nsIFileInputStream); - var cis = Components.classes["@mozilla.org/intl/converter-input-stream;1"]. - createInstance(Components.interfaces.nsIConverterInputStream); - var split = path.split("/"); - for(var i = 0; i < split.length; ++i) { - file.append(split[i]); - } - fis.init(file, -1, -1, false); - cis.init(fis, "UTF-8", 0, 0); - - var data = ""; - let str = {}; - let read = 0; - do { - read = cis.readString(0xffffffff, str); // read as much as we can and put it in str.value - data += str.value; - } while (read != 0); - cis.close(); - return data; -} - -function getQuery(request) { - var query = {}; - request.queryString.split('&').forEach(function (val) { - var [name, value] = val.split('='); - query[name] = unescape(value); - }); - return query; -} diff --git a/dom/tv/test/mochitest/file_app.template.webapp b/dom/tv/test/mochitest/file_app.template.webapp deleted file mode 100644 index 9e087fd80d..0000000000 --- a/dom/tv/test/mochitest/file_app.template.webapp +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "TV Test App (hosted)", - "description": "Hosted TV test app used for mochitest.", - "launch_path": "/tests/dom/tv/test/mochitest/TESTTOKEN", - "icons": { "128": "default_icon" } -} diff --git a/dom/tv/test/mochitest/file_tv_get_channels.html b/dom/tv/test/mochitest/file_tv_get_channels.html deleted file mode 100644 index c0d85be6bb..0000000000 --- a/dom/tv/test/mochitest/file_tv_get_channels.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - Test GetChannels for TV API - - -
- - - - diff --git a/dom/tv/test/mochitest/file_tv_get_channels_during_scanning.html b/dom/tv/test/mochitest/file_tv_get_channels_during_scanning.html deleted file mode 100644 index a0332812e0..0000000000 --- a/dom/tv/test/mochitest/file_tv_get_channels_during_scanning.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - Test an error case for GetChannels during scanning for TV API - - -
- - - - diff --git a/dom/tv/test/mochitest/file_tv_get_current_program.html b/dom/tv/test/mochitest/file_tv_get_current_program.html deleted file mode 100644 index f3a361c596..0000000000 --- a/dom/tv/test/mochitest/file_tv_get_current_program.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - Test GetCurrentProgram for TV API - - -
- - - - diff --git a/dom/tv/test/mochitest/file_tv_get_programs.html b/dom/tv/test/mochitest/file_tv_get_programs.html deleted file mode 100644 index b4585cd3b9..0000000000 --- a/dom/tv/test/mochitest/file_tv_get_programs.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - Test GetPrograms for TV API - - -
- - - - diff --git a/dom/tv/test/mochitest/file_tv_get_sources.html b/dom/tv/test/mochitest/file_tv_get_sources.html deleted file mode 100644 index dd8010b8c9..0000000000 --- a/dom/tv/test/mochitest/file_tv_get_sources.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - Test GetSources for TV API - - -
- - - - diff --git a/dom/tv/test/mochitest/file_tv_get_tuners.html b/dom/tv/test/mochitest/file_tv_get_tuners.html deleted file mode 100644 index 1b10693ab3..0000000000 --- a/dom/tv/test/mochitest/file_tv_get_tuners.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - Test GetTuners for TV API - - -
- - - - diff --git a/dom/tv/test/mochitest/file_tv_non_permitted_app.html b/dom/tv/test/mochitest/file_tv_non_permitted_app.html deleted file mode 100644 index 75e6be982c..0000000000 --- a/dom/tv/test/mochitest/file_tv_non_permitted_app.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - Test the availability of TV Manager API for non-permitted Apps - - -
- - - - diff --git a/dom/tv/test/mochitest/file_tv_permitted_app.html b/dom/tv/test/mochitest/file_tv_permitted_app.html deleted file mode 100644 index c1c924a976..0000000000 --- a/dom/tv/test/mochitest/file_tv_permitted_app.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - Test the availability of TV Manager API for permitted Apps - - -
- - - - diff --git a/dom/tv/test/mochitest/file_tv_scan_channels_completed.html b/dom/tv/test/mochitest/file_tv_scan_channels_completed.html deleted file mode 100644 index a77ad5d7d4..0000000000 --- a/dom/tv/test/mochitest/file_tv_scan_channels_completed.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - Test channel scanning complete for TV API - - -
- - - - diff --git a/dom/tv/test/mochitest/file_tv_scan_channels_stopped.html b/dom/tv/test/mochitest/file_tv_scan_channels_stopped.html deleted file mode 100644 index b8ab6883b8..0000000000 --- a/dom/tv/test/mochitest/file_tv_scan_channels_stopped.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - - Test StartScanning and StopScanning for TV API - - -
- - - - diff --git a/dom/tv/test/mochitest/file_tv_set_current_channel.html b/dom/tv/test/mochitest/file_tv_set_current_channel.html deleted file mode 100644 index 7dc5199a6d..0000000000 --- a/dom/tv/test/mochitest/file_tv_set_current_channel.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - - Test SetCurrentChannel for TV API - - -
- - - - diff --git a/dom/tv/test/mochitest/file_tv_set_current_channel_during_scanning.html b/dom/tv/test/mochitest/file_tv_set_current_channel_during_scanning.html deleted file mode 100644 index 9377fe97fd..0000000000 --- a/dom/tv/test/mochitest/file_tv_set_current_channel_during_scanning.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - Test an error case for SetCurrentChannel during scanning for TV API - - -
- - - - diff --git a/dom/tv/test/mochitest/file_tv_set_current_source.html b/dom/tv/test/mochitest/file_tv_set_current_source.html deleted file mode 100644 index b8307c7bd3..0000000000 --- a/dom/tv/test/mochitest/file_tv_set_current_source.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - Test SetCurrentSource for TV API - - -
- - - - diff --git a/dom/tv/test/mochitest/file_tv_set_invalid_current_channel.html b/dom/tv/test/mochitest/file_tv_set_invalid_current_channel.html deleted file mode 100644 index 60ccae4ff2..0000000000 --- a/dom/tv/test/mochitest/file_tv_set_invalid_current_channel.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - Test an error case for SetCurrentChannel for TV API - - -
- - - - diff --git a/dom/tv/test/mochitest/file_tv_set_invalid_current_source.html b/dom/tv/test/mochitest/file_tv_set_invalid_current_source.html deleted file mode 100644 index a44b867e22..0000000000 --- a/dom/tv/test/mochitest/file_tv_set_invalid_current_source.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - Test an error case for SetCurrentSource for TV API - - -
- - - - diff --git a/dom/tv/test/mochitest/head.js b/dom/tv/test/mochitest/head.js index 78f65a1437..3afe89296c 100644 --- a/dom/tv/test/mochitest/head.js +++ b/dom/tv/test/mochitest/head.js @@ -1,98 +1,28 @@ "use strict"; -var gAppsService = SpecialPowers.Cc["@mozilla.org/AppsService;1"] - .getService(SpecialPowers.Ci.nsIAppsService); - - -var gApp; - -function cbError(e) { - ok(false, "Error callback invoked: " + this.error.name); - SimpleTest.finish(); -} - -function installApp(aTestToken, aTemplate) { - var hostedManifestURL = window.location.origin + - '/tests/dom/tv/test/mochitest/file_app.sjs?testToken=' - + aTestToken + '&template=' + aTemplate; - var request = navigator.mozApps.install(hostedManifestURL); - request.onerror = cbError; - request.onsuccess = function() { - gApp = request.result; - - var appId = gAppsService.getAppLocalIdByManifestURL(gApp.manifestURL); - SpecialPowers.addPermission("tv", true, { url: gApp.origin, - originAttributes: { - appId: appId - }}); - - runTest(); - } -} - -function uninstallApp() { - var request = navigator.mozApps.mgmt.uninstall(gApp); - request.onerror = cbError; - request.onsuccess = function() { - // All done. - info("All done"); - runTest(); - } -} - -function testApp() { - var ifr = document.createElement('iframe'); - ifr.setAttribute('mozbrowser', 'true'); - ifr.setAttribute('mozapp', gApp.manifestURL); - ifr.setAttribute('src', gApp.manifest.launch_path); - var domParent = document.getElementById('content'); - - // Set us up to listen for messages from the app. - var listener = function(e) { - var message = e.detail.message; - if (/^OK/.exec(message)) { - ok(true, "Message from app: " + message); - } else if (/KO/.exec(message)) { - ok(false, "Message from app: " + message); - } else if (/^INFO/.exec(message)) { - info("Message from app: " + message); - } else if (/DONE/.exec(message)) { - ok(true, "Messaging from app complete"); - ifr.removeEventListener('mozbrowsershowmodalprompt', listener); - domParent.removeChild(ifr); - runTest(); - } - } - - // This event is triggered when the app calls "alert". - ifr.addEventListener('mozbrowsershowmodalprompt', listener, false); - domParent.appendChild(ifr); -} - -function runTest() { - if (!tests.length) { - SimpleTest.finish(); - return; - } - - var test = tests.shift(); - test(); -} - -function setupPrefsAndPermissions() { - SpecialPowers.pushPrefEnv({"set": [["dom.tv.enabled", true], - ["dom.testing.tv_enabled_for_hosted_apps", true]]}, function() { - SpecialPowers.pushPermissions( - [{ "type": "browser", "allow": true, "context": document }, - { "type": "embed-apps", "allow": true, "context": document }, - { "type": "webapps-manage", "allow": true, "context": document }], - function() { - SpecialPowers.setAllAppsLaunchable(true); - SpecialPowers.setBoolPref("dom.mozBrowserFramesEnabled", true); - // No confirmation needed when an app is installed and uninstalled. - SpecialPowers.autoConfirmAppInstall(() => { - SpecialPowers.autoConfirmAppUninstall(runTest); - }); - }); +function setupPrefsAndPermissions(callback) { + setupPrefs(function() { + SpecialPowers.pushPermissions([ + {"type":"tv", "allow":1, "context":document} + ], callback); + }); +} + +function setupPrefs(callback) { + SpecialPowers.pushPrefEnv({"set": [["dom.tv.enabled", true], + ["dom.ignore_webidl_scope_checks", true]]}, function() { + callback(); + }); +} + +function removePrefsAndPermissions(callback) { + SpecialPowers.popPrefEnv(function() { + SpecialPowers.popPermissions(callback); + }); +} + +function prepareTest(callback) { + removePrefsAndPermissions(function() { + setupPrefsAndPermissions(callback); }); } diff --git a/dom/tv/test/mochitest/mochitest.ini b/dom/tv/test/mochitest/mochitest.ini index fe32ebfca3..8b58db1f90 100644 --- a/dom/tv/test/mochitest/mochitest.ini +++ b/dom/tv/test/mochitest/mochitest.ini @@ -1,26 +1,6 @@ [DEFAULT] -skip-if = e10s || toolkit == 'gonk' # Bug 1125477 -support-files = - file_app.sjs - file_app.template.webapp - file_tv_non_permitted_app.html - file_tv_permitted_app.html - file_tv_get_tuners.html - file_tv_get_sources.html - file_tv_get_channels.html - file_tv_get_channels_during_scanning.html - file_tv_get_programs.html - file_tv_get_current_program.html - file_tv_set_current_source.html - file_tv_set_invalid_current_source.html - file_tv_set_current_channel.html - file_tv_set_current_channel_during_scanning.html - file_tv_set_invalid_current_channel.html - file_tv_scan_channels_stopped.html - file_tv_scan_channels_completed.html - head.js - test_helpers.js - +support-files = head.js +skip-if = (os == 'mac' && debug) || asan # Bug 1125477 [test_tv_non_permitted_app.html] [test_tv_permitted_app.html] [test_tv_get_tuners.html] diff --git a/dom/tv/test/mochitest/test_helpers.js b/dom/tv/test/mochitest/test_helpers.js deleted file mode 100644 index b08a86e8c7..0000000000 --- a/dom/tv/test/mochitest/test_helpers.js +++ /dev/null @@ -1,17 +0,0 @@ -"use strict"; - -function is(a, b, msg) { - alert((a === b ? 'OK' : 'KO') + ' ' + msg); -} - -function ok(a, msg) { - alert((a ? 'OK' : 'KO')+ ' ' + msg); -} - -function info(msg) { - alert('INFO ' + msg); -} - -function finish() { - alert('DONE'); -} diff --git a/dom/tv/test/mochitest/test_tv_get_channels.html b/dom/tv/test/mochitest/test_tv_get_channels.html index 4c1c5b0226..96b987083d 100644 --- a/dom/tv/test/mochitest/test_tv_get_channels.html +++ b/dom/tv/test/mochitest/test_tv_get_channels.html @@ -12,22 +12,57 @@ diff --git a/dom/tv/test/mochitest/test_tv_get_channels_during_scanning.html b/dom/tv/test/mochitest/test_tv_get_channels_during_scanning.html index 6c810deac3..6d5d31d3c2 100644 --- a/dom/tv/test/mochitest/test_tv_get_channels_during_scanning.html +++ b/dom/tv/test/mochitest/test_tv_get_channels_during_scanning.html @@ -12,22 +12,54 @@ diff --git a/dom/tv/test/mochitest/test_tv_get_current_program.html b/dom/tv/test/mochitest/test_tv_get_current_program.html index fe8343309b..ff82e9fc5b 100644 --- a/dom/tv/test/mochitest/test_tv_get_current_program.html +++ b/dom/tv/test/mochitest/test_tv_get_current_program.html @@ -12,22 +12,64 @@ diff --git a/dom/tv/test/mochitest/test_tv_get_programs.html b/dom/tv/test/mochitest/test_tv_get_programs.html index 9cfd9bfbb0..2754334cf8 100644 --- a/dom/tv/test/mochitest/test_tv_get_programs.html +++ b/dom/tv/test/mochitest/test_tv_get_programs.html @@ -12,22 +12,68 @@ diff --git a/dom/tv/test/mochitest/test_tv_get_sources.html b/dom/tv/test/mochitest/test_tv_get_sources.html index 0af43fd90f..bbf72c196a 100644 --- a/dom/tv/test/mochitest/test_tv_get_sources.html +++ b/dom/tv/test/mochitest/test_tv_get_sources.html @@ -12,24 +12,45 @@ diff --git a/dom/tv/test/mochitest/test_tv_get_tuners.html b/dom/tv/test/mochitest/test_tv_get_tuners.html index e4ea6a1ff1..9287cb4975 100644 --- a/dom/tv/test/mochitest/test_tv_get_tuners.html +++ b/dom/tv/test/mochitest/test_tv_get_tuners.html @@ -12,22 +12,34 @@ diff --git a/dom/tv/test/mochitest/test_tv_non_permitted_app.html b/dom/tv/test/mochitest/test_tv_non_permitted_app.html index 83c489ab53..8c21702777 100644 --- a/dom/tv/test/mochitest/test_tv_non_permitted_app.html +++ b/dom/tv/test/mochitest/test_tv_non_permitted_app.html @@ -12,35 +12,14 @@ diff --git a/dom/tv/test/mochitest/test_tv_permitted_app.html b/dom/tv/test/mochitest/test_tv_permitted_app.html index 58859b795a..24d76c6b06 100644 --- a/dom/tv/test/mochitest/test_tv_permitted_app.html +++ b/dom/tv/test/mochitest/test_tv_permitted_app.html @@ -12,22 +12,13 @@ diff --git a/dom/tv/test/mochitest/test_tv_scan_channels_completed.html b/dom/tv/test/mochitest/test_tv_scan_channels_completed.html index 529f8b3d1d..3e3cdb474a 100644 --- a/dom/tv/test/mochitest/test_tv_scan_channels_completed.html +++ b/dom/tv/test/mochitest/test_tv_scan_channels_completed.html @@ -12,23 +12,65 @@ diff --git a/dom/tv/test/mochitest/test_tv_scan_channels_stopped.html b/dom/tv/test/mochitest/test_tv_scan_channels_stopped.html index 8c5dabb171..186280c0f4 100644 --- a/dom/tv/test/mochitest/test_tv_scan_channels_stopped.html +++ b/dom/tv/test/mochitest/test_tv_scan_channels_stopped.html @@ -12,22 +12,62 @@ diff --git a/dom/tv/test/mochitest/test_tv_set_current_channel.html b/dom/tv/test/mochitest/test_tv_set_current_channel.html index 4fc542ff6b..5dddb2070c 100644 --- a/dom/tv/test/mochitest/test_tv_set_current_channel.html +++ b/dom/tv/test/mochitest/test_tv_set_current_channel.html @@ -12,22 +12,66 @@ diff --git a/dom/tv/test/mochitest/test_tv_set_current_channel_during_scanning.html b/dom/tv/test/mochitest/test_tv_set_current_channel_during_scanning.html index 54a987bfab..999402d5bc 100644 --- a/dom/tv/test/mochitest/test_tv_set_current_channel_during_scanning.html +++ b/dom/tv/test/mochitest/test_tv_set_current_channel_during_scanning.html @@ -12,22 +12,54 @@ diff --git a/dom/tv/test/mochitest/test_tv_set_current_source.html b/dom/tv/test/mochitest/test_tv_set_current_source.html index d5c3922928..ebafc89ad2 100644 --- a/dom/tv/test/mochitest/test_tv_set_current_source.html +++ b/dom/tv/test/mochitest/test_tv_set_current_source.html @@ -12,22 +12,44 @@ diff --git a/dom/tv/test/mochitest/test_tv_set_invalid_current_channel.html b/dom/tv/test/mochitest/test_tv_set_invalid_current_channel.html index eb72424fc8..680354140d 100644 --- a/dom/tv/test/mochitest/test_tv_set_invalid_current_channel.html +++ b/dom/tv/test/mochitest/test_tv_set_invalid_current_channel.html @@ -12,22 +12,45 @@ diff --git a/dom/tv/test/mochitest/test_tv_set_invalid_current_source.html b/dom/tv/test/mochitest/test_tv_set_invalid_current_source.html index 5582b4639b..6836e75ce4 100644 --- a/dom/tv/test/mochitest/test_tv_set_invalid_current_source.html +++ b/dom/tv/test/mochitest/test_tv_set_invalid_current_source.html @@ -12,22 +12,33 @@ diff --git a/dom/vr/VRDevice.cpp b/dom/vr/VRDevice.cpp index 84d21c85ea..2cee57c0b4 100644 --- a/dom/vr/VRDevice.cpp +++ b/dom/vr/VRDevice.cpp @@ -10,7 +10,10 @@ #include "mozilla/dom/VRDeviceBinding.h" #include "mozilla/dom/ElementBinding.h" #include "mozilla/dom/VRDevice.h" +#include "Navigator.h" #include "gfxVR.h" +#include "VRDeviceProxy.h" +#include "VRManagerChild.h" #include "nsIFrame.h" using namespace mozilla::gfx; @@ -18,6 +21,46 @@ using namespace mozilla::gfx; namespace mozilla { namespace dom { +/*static*/ bool +VRDevice::RefreshVRDevices(dom::Navigator* aNavigator) +{ + gfx::VRManagerChild* vm = gfx::VRManagerChild::Get(); + return vm && vm->RefreshVRDevicesWithCallback(aNavigator); +} + +/*static*/ void +VRDevice::UpdateVRDevices(nsTArray>& aDevices, nsISupports* aParent) +{ + nsTArray> devices; + + gfx::VRManagerChild* vm = gfx::VRManagerChild::Get(); + nsTArray> proxyDevices; + if (vm && vm->GetVRDevices(proxyDevices)) { + for (size_t i = 0; i < proxyDevices.Length(); i++) { + RefPtr proxyDevice = proxyDevices[i]; + bool isNewDevice = true; + for (size_t j = 0; j < aDevices.Length(); j++) { + if (aDevices[j]->GetHMD()->GetDeviceInfo() == proxyDevice->GetDeviceInfo()) { + devices.AppendElement(aDevices[j]); + isNewDevice = false; + } + } + + if (isNewDevice) { + gfx::VRStateValidFlags sensorBits = proxyDevice->GetDeviceInfo().GetSupportedSensorStateBits(); + devices.AppendElement(new HMDInfoVRDevice(aParent, proxyDevice)); + if (sensorBits & (gfx::VRStateValidFlags::State_Position | + gfx::VRStateValidFlags::State_Orientation)) + { + devices.AppendElement(new HMDPositionVRDevice(aParent, proxyDevice)); + } + } + } + } + + aDevices = devices; +} + NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRFieldOfViewReadOnly, mParent) NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRFieldOfViewReadOnly, AddRef) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRFieldOfViewReadOnly, Release) @@ -133,11 +176,11 @@ VRPositionState::VRPositionState(nsISupports* aParent, const gfx::VRHMDSensorSta { mTimeStamp = aState.timestamp; - if (aState.flags & gfx::VRHMDInfo::State_Position) { + if (aState.flags & gfx::VRStateValidFlags::State_Position) { mPosition = new DOMPoint(mParent, aState.position[0], aState.position[1], aState.position[2], 0.0); } - if (aState.flags & gfx::VRHMDInfo::State_Orientation) { + if (aState.flags & gfx::VRStateValidFlags::State_Orientation) { mOrientation = new DOMPoint(mParent, aState.orientation[0], aState.orientation[1], aState.orientation[2], aState.orientation[3]); } } @@ -206,158 +249,118 @@ PositionSensorVRDevice::WrapObject(JSContext* aCx, JS::Handle aGivenP return PositionSensorVRDeviceBinding::Wrap(aCx, this, aGivenProto); } -namespace { - -class HMDInfoVRDevice : public HMDVRDevice +HMDInfoVRDevice::HMDInfoVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD) + : HMDVRDevice(aParent, aHMD) { -public: - HMDInfoVRDevice(nsISupports* aParent, gfx::VRHMDInfo* aHMD) - : HMDVRDevice(aParent, aHMD) - { - uint64_t hmdid = aHMD->GetDeviceIndex() << 8; - uint64_t devid = hmdid | 0x00; // we generate a devid with low byte 0 for the HMD, 1 for the position sensor + MOZ_COUNT_CTOR_INHERITED(HMDInfoVRDevice, HMDVRDevice); + uint64_t hmdid = aHMD->GetDeviceInfo().GetDeviceID() << 8; + uint64_t devid = hmdid | 0x00; // we generate a devid with low byte 0 for the HMD, 1 for the position sensor - mHWID.Truncate(); - mHWID.AppendPrintf("0x%llx", hmdid); + mHWID.Truncate(); + mHWID.AppendPrintf("0x%llx", hmdid); - mDeviceId.Truncate(); - mDeviceId.AppendPrintf("0x%llx", devid); + mDeviceId.Truncate(); + mDeviceId.AppendPrintf("0x%llx", devid); - mDeviceName.Truncate(); - mDeviceName.Append(NS_ConvertASCIItoUTF16(aHMD->GetDeviceName())); - mDeviceName.AppendLiteral(" (HMD)"); + mDeviceName.Truncate(); + mDeviceName.Append(NS_ConvertASCIItoUTF16(aHMD->GetDeviceInfo().GetDeviceName())); + mDeviceName.AppendLiteral(" (HMD)"); - mValid = true; - } + mValid = true; +} - virtual ~HMDInfoVRDevice() { } - - /* If a field of view that is set to all 0's is passed in, - * the recommended field of view for that eye is used. - */ - virtual void SetFieldOfView(const VRFieldOfViewInit& aLeftFOV, - const VRFieldOfViewInit& aRightFOV, - double zNear, double zFar) override - { - gfx::VRFieldOfView left = gfx::VRFieldOfView(aLeftFOV.mUpDegrees, aLeftFOV.mRightDegrees, - aLeftFOV.mDownDegrees, aLeftFOV.mLeftDegrees); - gfx::VRFieldOfView right = gfx::VRFieldOfView(aRightFOV.mUpDegrees, aRightFOV.mRightDegrees, - aRightFOV.mDownDegrees, aRightFOV.mLeftDegrees); - - if (left.IsZero()) - left = mHMD->GetRecommendedEyeFOV(VRHMDInfo::Eye_Left); - if (right.IsZero()) - right = mHMD->GetRecommendedEyeFOV(VRHMDInfo::Eye_Right); - - mHMD->SetFOV(left, right, zNear, zFar); - } - - virtual already_AddRefed GetEyeParameters(VREye aEye) override - { - gfx::IntSize sz(mHMD->SuggestedEyeResolution()); - gfx::VRHMDInfo::Eye eye = aEye == VREye::Left ? gfx::VRHMDInfo::Eye_Left : gfx::VRHMDInfo::Eye_Right; - RefPtr params = - new VREyeParameters(mParent, - gfx::VRFieldOfView(15, 15, 15, 15), // XXX min? - mHMD->GetMaximumEyeFOV(eye), - mHMD->GetRecommendedEyeFOV(eye), - mHMD->GetEyeTranslation(eye), - mHMD->GetEyeFOV(eye), - gfx::IntRect((aEye == VREye::Left) ? 0 : sz.width, 0, sz.width, sz.height)); - return params.forget(); - } - -protected: -}; - -class HMDPositionVRDevice : public PositionSensorVRDevice +HMDInfoVRDevice::~HMDInfoVRDevice() { -public: - HMDPositionVRDevice(nsISupports* aParent, gfx::VRHMDInfo* aHMD) - : PositionSensorVRDevice(aParent) - , mHMD(aHMD) - , mTracking(false) - { + MOZ_COUNT_DTOR_INHERITED(HMDInfoVRDevice, HMDVRDevice); +} - uint64_t hmdid = aHMD->GetDeviceIndex() << 8; - uint64_t devid = hmdid | 0x01; // we generate a devid with low byte 0 for the HMD, 1 for the position sensor - - mHWID.Truncate(); - mHWID.AppendPrintf("0x%llx", hmdid); - - mDeviceId.Truncate(); - mDeviceId.AppendPrintf("0x%llx", devid); - - mDeviceName.Truncate(); - mDeviceName.Append(NS_ConvertASCIItoUTF16(aHMD->GetDeviceName())); - mDeviceName.AppendLiteral(" (Sensor)"); - - mValid = true; - } - - ~HMDPositionVRDevice() - { - if (mTracking) { - mHMD->StopSensorTracking(); - } - } - - virtual already_AddRefed GetState() override - { - if (!mTracking) { - mHMD->StartSensorTracking(); - mTracking = true; - } - - gfx::VRHMDSensorState state = mHMD->GetSensorState(); - RefPtr obj = new VRPositionState(mParent, state); - - return obj.forget(); - } - - virtual already_AddRefed GetImmediateState() override - { - if (!mTracking) { - mHMD->StartSensorTracking(); - mTracking = true; - } - - gfx::VRHMDSensorState state = mHMD->GetSensorState(); - RefPtr obj = new VRPositionState(mParent, state); - - return obj.forget(); - } - - virtual void ResetSensor() override - { - mHMD->ZeroSensor(); - } - -protected: - RefPtr mHMD; - bool mTracking; -}; - -} // namespace - -bool -VRDevice::CreateAllKnownVRDevices(nsISupports *aParent, nsTArray>& aDevices) +/* If a field of view that is set to all 0's is passed in, + * the recommended field of view for that eye is used. + */ +void +HMDInfoVRDevice::SetFieldOfView(const VRFieldOfViewInit& aLeftFOV, + const VRFieldOfViewInit& aRightFOV, + double zNear, double zFar) { - nsTArray> hmds; - gfx::VRHMDManager::GetAllHMDs(hmds); + gfx::VRFieldOfView left = gfx::VRFieldOfView(aLeftFOV.mUpDegrees, aLeftFOV.mRightDegrees, + aLeftFOV.mDownDegrees, aLeftFOV.mLeftDegrees); + gfx::VRFieldOfView right = gfx::VRFieldOfView(aRightFOV.mUpDegrees, aRightFOV.mRightDegrees, + aRightFOV.mDownDegrees, aRightFOV.mLeftDegrees); - for (size_t i = 0; i < hmds.Length(); ++i) { - uint32_t sensorBits = hmds[i]->GetSupportedSensorStateBits(); - aDevices.AppendElement(new HMDInfoVRDevice(aParent, hmds[i])); - - if (sensorBits & - (gfx::VRHMDInfo::State_Position | gfx::VRHMDInfo::State_Orientation)) - { - aDevices.AppendElement(new HMDPositionVRDevice(aParent, hmds[i])); - } + if (left.IsZero()) { + left = mHMD->GetDeviceInfo().GetRecommendedEyeFOV(VRDeviceInfo::Eye_Left); } - return true; + if (right.IsZero()) { + right = mHMD->GetDeviceInfo().GetRecommendedEyeFOV(VRDeviceInfo::Eye_Right); + } + + mHMD->SetFOV(left, right, zNear, zFar); +} + +already_AddRefed HMDInfoVRDevice::GetEyeParameters(VREye aEye) +{ + gfx::IntSize sz(mHMD->GetDeviceInfo().SuggestedEyeResolution()); + gfx::VRDeviceInfo::Eye eye = aEye == VREye::Left ? gfx::VRDeviceInfo::Eye_Left : gfx::VRDeviceInfo::Eye_Right; + RefPtr params = + new VREyeParameters(mParent, + gfx::VRFieldOfView(15, 15, 15, 15), // XXX min? + mHMD->GetDeviceInfo().GetMaximumEyeFOV(eye), + mHMD->GetDeviceInfo().GetRecommendedEyeFOV(eye), + mHMD->GetDeviceInfo().GetEyeTranslation(eye), + mHMD->GetDeviceInfo().GetEyeFOV(eye), + gfx::IntRect((aEye == VREye::Left) ? 0 : sz.width, 0, sz.width, sz.height)); + return params.forget(); +} + +HMDPositionVRDevice::HMDPositionVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD) + : PositionSensorVRDevice(aParent, aHMD) +{ + MOZ_COUNT_CTOR_INHERITED(HMDPositionVRDevice, PositionSensorVRDevice); + + uint64_t hmdid = aHMD->GetDeviceInfo().GetDeviceID() << 8; + uint64_t devid = hmdid | 0x01; // we generate a devid with low byte 0 for the HMD, 1 for the position sensor + + mHWID.Truncate(); + mHWID.AppendPrintf("0x%llx", hmdid); + + mDeviceId.Truncate(); + mDeviceId.AppendPrintf("0x%llx", devid); + + mDeviceName.Truncate(); + mDeviceName.Append(NS_ConvertASCIItoUTF16(aHMD->GetDeviceInfo().GetDeviceName())); + mDeviceName.AppendLiteral(" (Sensor)"); + + mValid = true; +} + +HMDPositionVRDevice::~HMDPositionVRDevice() +{ + MOZ_COUNT_DTOR_INHERITED(HMDPositionVRDevice, PositionSensorVRDevice); +} + +already_AddRefed +HMDPositionVRDevice::GetState() +{ + gfx::VRHMDSensorState state = mHMD->GetSensorState(); + RefPtr obj = new VRPositionState(mParent, state); + + return obj.forget(); +} + +already_AddRefed +HMDPositionVRDevice::GetImmediateState() +{ + gfx::VRHMDSensorState state = mHMD->GetSensorState(); + RefPtr obj = new VRPositionState(mParent, state); + + return obj.forget(); +} + +void +HMDPositionVRDevice::ResetSensor() +{ + mHMD->ZeroSensor(); } } // namespace dom diff --git a/dom/vr/VRDevice.h b/dom/vr/VRDevice.h index 5834082a39..afc7eeb052 100644 --- a/dom/vr/VRDevice.h +++ b/dom/vr/VRDevice.h @@ -21,9 +21,11 @@ #include "nsWrapperCache.h" #include "gfxVR.h" +#include "VRDeviceProxy.h" namespace mozilla { namespace dom { +class Navigator; class VRFieldOfViewReadOnly : public nsWrapperCache { @@ -177,10 +179,7 @@ class VRDevice : public nsISupports, public nsWrapperCache { public: - // create new VRDevice objects for all known underlying gfx::vr devices - static bool CreateAllKnownVRDevices(nsISupports *aParent, nsTArray>& aDevices); -public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(VRDevice) @@ -190,8 +189,6 @@ public: bool IsValid() { return mValid; } - virtual void Shutdown() { } - nsISupports* GetParentObject() const { return mParent; @@ -204,22 +201,36 @@ public: VRDeviceType GetType() const { return mType; } + static bool RefreshVRDevices(dom::Navigator* aNavigator); + static void UpdateVRDevices(nsTArray >& aDevices, + nsISupports* aParent); + + gfx::VRDeviceProxy *GetHMD() { + return mHMD; + } + protected: - VRDevice(nsISupports* aParent, VRDeviceType aType) + VRDevice(nsISupports* aParent, + gfx::VRDeviceProxy* aHMD, + VRDeviceType aType) : mParent(aParent) + , mHMD(aHMD) , mType(aType) , mValid(false) { + MOZ_COUNT_CTOR(VRDevice); mHWID.AssignLiteral("uknown"); mDeviceId.AssignLiteral("unknown"); mDeviceName.AssignLiteral("unknown"); } - virtual ~VRDevice() { - Shutdown(); + virtual ~VRDevice() + { + MOZ_COUNT_DTOR(VRDevice); } nsCOMPtr mParent; + RefPtr mHMD; nsString mHWID; nsString mDeviceId; nsString mDeviceName; @@ -240,36 +251,64 @@ public: virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; - gfx::VRHMDInfo *GetHMD() { return mHMD.get(); } - protected: - HMDVRDevice(nsISupports* aParent, gfx::VRHMDInfo* aHMD) - : VRDevice(aParent, VRDevice::HMD) - , mHMD(aHMD) - { } + HMDVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD) + : VRDevice(aParent, aHMD, VRDevice::HMD) + { + MOZ_COUNT_CTOR_INHERITED(HMDVRDevice, VRDevice); + } - virtual ~HMDVRDevice() { } + virtual ~HMDVRDevice() + { + MOZ_COUNT_DTOR_INHERITED(HMDVRDevice, VRDevice); + } +}; - RefPtr mHMD; +class HMDInfoVRDevice : public HMDVRDevice +{ +public: + HMDInfoVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD); + virtual ~HMDInfoVRDevice(); + + /* If a field of view that is set to all 0's is passed in, + * the recommended field of view for that eye is used. + */ + virtual void SetFieldOfView(const VRFieldOfViewInit& aLeftFOV, + const VRFieldOfViewInit& aRightFOV, + double zNear, double zFar) override; + virtual already_AddRefed GetEyeParameters(VREye aEye) override; }; class PositionSensorVRDevice : public VRDevice { public: virtual already_AddRefed GetState() = 0; - virtual already_AddRefed GetImmediateState() = 0; - virtual void ResetSensor() = 0; - virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; protected: - explicit PositionSensorVRDevice(nsISupports* aParent) - : VRDevice(aParent, VRDevice::PositionSensor) - { } + explicit PositionSensorVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD) + : VRDevice(aParent, aHMD, VRDevice::PositionSensor) + { + MOZ_COUNT_CTOR_INHERITED(PositionSensorVRDevice, VRDevice); + } - virtual ~PositionSensorVRDevice() { } + virtual ~PositionSensorVRDevice() + { + MOZ_COUNT_DTOR_INHERITED(PositionSensorVRDevice, VRDevice); + } +}; + +class HMDPositionVRDevice : public PositionSensorVRDevice +{ +public: + HMDPositionVRDevice(nsISupports* aParent, gfx::VRDeviceProxy* aHMD); + ~HMDPositionVRDevice(); + + virtual already_AddRefed GetState() override; + virtual already_AddRefed GetImmediateState() override; + virtual void ResetSensor() override; }; } // namespace dom diff --git a/dom/webidl/Navigator.webidl b/dom/webidl/Navigator.webidl index 66d185e4d3..a52ecfe4ff 100644 --- a/dom/webidl/Navigator.webidl +++ b/dom/webidl/Navigator.webidl @@ -423,7 +423,7 @@ partial interface Navigator { }; partial interface Navigator { - [Pref="dom.tv.enabled", CheckAnyPermissions="tv", Func="Navigator::HasTVSupport"] + [Pref="dom.tv.enabled", CheckAnyPermissions="tv", AvailableIn=CertifiedApps] readonly attribute TVManager? tv; }; diff --git a/dom/webidl/Notification.webidl b/dom/webidl/Notification.webidl index 4bca9812ce..182216c726 100644 --- a/dom/webidl/Notification.webidl +++ b/dom/webidl/Notification.webidl @@ -20,7 +20,7 @@ interface Notification : EventTarget { static readonly attribute NotificationPermission permission; [Throws, Func="mozilla::dom::Notification::RequestPermissionEnabledForScope"] - static void requestPermission(optional NotificationPermissionCallback permissionCallback); + static Promise requestPermission(optional NotificationPermissionCallback permissionCallback); [Throws, Func="mozilla::dom::Notification::IsGetEnabled"] static Promise> get(optional GetNotificationOptions filter); diff --git a/dom/webidl/TVChannel.webidl b/dom/webidl/TVChannel.webidl index 2852982120..c953180374 100644 --- a/dom/webidl/TVChannel.webidl +++ b/dom/webidl/TVChannel.webidl @@ -18,7 +18,7 @@ dictionary TVGetProgramsOptions { unsigned long long duration; }; -[Pref="dom.tv.enabled", CheckAnyPermissions="tv", Func="Navigator::HasTVSupport"] +[Pref="dom.tv.enabled", CheckAnyPermissions="tv", AvailableIn=CertifiedApps] interface TVChannel : EventTarget { [Throws] Promise> getPrograms(optional TVGetProgramsOptions options); diff --git a/dom/webidl/TVCurrentChannelChangedEvent.webidl b/dom/webidl/TVCurrentChannelChangedEvent.webidl index 39aa72184b..1394052316 100644 --- a/dom/webidl/TVCurrentChannelChangedEvent.webidl +++ b/dom/webidl/TVCurrentChannelChangedEvent.webidl @@ -13,7 +13,7 @@ dictionary TVCurrentChannelChangedEventInit : EventInit { [Pref="dom.tv.enabled", CheckAnyPermissions="tv", - Func="Navigator::HasTVSupport", + AvailableIn=CertifiedApps, Constructor(DOMString type, optional TVCurrentChannelChangedEventInit eventInitDict)] interface TVCurrentChannelChangedEvent : Event { readonly attribute TVChannel? channel; diff --git a/dom/webidl/TVCurrentSourceChangedEvent.webidl b/dom/webidl/TVCurrentSourceChangedEvent.webidl index 6386c02ea1..f88a366ba1 100644 --- a/dom/webidl/TVCurrentSourceChangedEvent.webidl +++ b/dom/webidl/TVCurrentSourceChangedEvent.webidl @@ -13,7 +13,7 @@ dictionary TVCurrentSourceChangedEventInit : EventInit { [Pref="dom.tv.enabled", CheckAnyPermissions="tv", - Func="Navigator::HasTVSupport", + AvailableIn=CertifiedApps, Constructor(DOMString type, optional TVCurrentSourceChangedEventInit eventInitDict)] interface TVCurrentSourceChangedEvent : Event { readonly attribute TVSource? source; diff --git a/dom/webidl/TVEITBroadcastedEvent.webidl b/dom/webidl/TVEITBroadcastedEvent.webidl index 72b509d492..6d6c02fd87 100644 --- a/dom/webidl/TVEITBroadcastedEvent.webidl +++ b/dom/webidl/TVEITBroadcastedEvent.webidl @@ -13,7 +13,7 @@ dictionary TVEITBroadcastedEventInit : EventInit { [Pref="dom.tv.enabled", CheckAnyPermissions="tv", - Func="Navigator::HasTVSupport", + AvailableIn=CertifiedApps, Constructor(DOMString type, optional TVEITBroadcastedEventInit eventInitDict)] interface TVEITBroadcastedEvent : Event { [Pure, Cached] readonly attribute sequence programs; diff --git a/dom/webidl/TVManager.webidl b/dom/webidl/TVManager.webidl index 7cafbc700b..587e83cdb5 100644 --- a/dom/webidl/TVManager.webidl +++ b/dom/webidl/TVManager.webidl @@ -7,7 +7,7 @@ * http://seanyhlin.github.io/TV-Manager-API/ */ -[Pref="dom.tv.enabled", CheckAnyPermissions="tv", Func="Navigator::HasTVSupport"] +[Pref="dom.tv.enabled", CheckAnyPermissions="tv", AvailableIn=CertifiedApps] interface TVManager : EventTarget { [Throws] Promise> getTuners(); diff --git a/dom/webidl/TVProgram.webidl b/dom/webidl/TVProgram.webidl index 716c4404e0..7a6adce040 100644 --- a/dom/webidl/TVProgram.webidl +++ b/dom/webidl/TVProgram.webidl @@ -7,7 +7,7 @@ * http://seanyhlin.github.io/TV-Manager-API/ */ -[Pref="dom.tv.enabled", CheckAnyPermissions="tv", Func="Navigator::HasTVSupport"] +[Pref="dom.tv.enabled", CheckAnyPermissions="tv", AvailableIn=CertifiedApps] interface TVProgram { sequence getAudioLanguages(); diff --git a/dom/webidl/TVScanningStateChangedEvent.webidl b/dom/webidl/TVScanningStateChangedEvent.webidl index 5bc06c40fb..bd841f42cd 100644 --- a/dom/webidl/TVScanningStateChangedEvent.webidl +++ b/dom/webidl/TVScanningStateChangedEvent.webidl @@ -21,7 +21,7 @@ dictionary TVScanningStateChangedEventInit : EventInit { [Pref="dom.tv.enabled", CheckAnyPermissions="tv", - Func="Navigator::HasTVSupport", + AvailableIn=CertifiedApps, Constructor(DOMString type, optional TVScanningStateChangedEventInit eventInitDict)] interface TVScanningStateChangedEvent : Event { readonly attribute TVScanningState state; diff --git a/dom/webidl/TVSource.webidl b/dom/webidl/TVSource.webidl index 021e80528c..60ad314001 100644 --- a/dom/webidl/TVSource.webidl +++ b/dom/webidl/TVSource.webidl @@ -33,7 +33,7 @@ dictionary TVStartScanningOptions { boolean isRescanned; }; -[Pref="dom.tv.enabled", CheckAnyPermissions="tv", Func="Navigator::HasTVSupport"] +[Pref="dom.tv.enabled", CheckAnyPermissions="tv", AvailableIn=CertifiedApps] interface TVSource : EventTarget { [Throws] Promise> getChannels(); diff --git a/dom/webidl/TVTuner.webidl b/dom/webidl/TVTuner.webidl index 48dd42ff69..25c8bd43ee 100644 --- a/dom/webidl/TVTuner.webidl +++ b/dom/webidl/TVTuner.webidl @@ -7,7 +7,7 @@ * http://seanyhlin.github.io/TV-Manager-API/ */ -[Pref="dom.tv.enabled", CheckAnyPermissions="tv", Func="Navigator::HasTVSupport"] +[Pref="dom.tv.enabled", CheckAnyPermissions="tv", AvailableIn=CertifiedApps] interface TVTuner : EventTarget { [Throws] sequence getSupportedSourceTypes(); diff --git a/dom/workers/ServiceWorkerPrivate.cpp b/dom/workers/ServiceWorkerPrivate.cpp index 813823d9d8..4827e3176d 100644 --- a/dom/workers/ServiceWorkerPrivate.cpp +++ b/dom/workers/ServiceWorkerPrivate.cpp @@ -318,6 +318,8 @@ public: nsCOMPtr runnable = new RegistrationUpdateRunnable(mRegistration, true /* time check */); NS_DispatchToMainThread(runnable.forget()); + + ExtendableEventWorkerRunnable::PostRun(aCx, aWorkerPrivate, aRunResult); } }; diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index f92b52d1eb..c543112402 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -601,9 +601,7 @@ private: WorkerRunnable::PostRun(aCx, aWorkerPrivate, aRunResult); // Match the busy count increase from NotifyRunnable. - if (!aWorkerPrivate->ModifyBusyCountFromWorker(aCx, false)) { - JS_ReportPendingException(aCx); - } + aWorkerPrivate->ModifyBusyCountFromWorker(aCx, false); aWorkerPrivate->CloseHandlerFinished(); } diff --git a/dom/workers/WorkerRunnable.cpp b/dom/workers/WorkerRunnable.cpp index 6d477629a0..624ec0f5c7 100644 --- a/dom/workers/WorkerRunnable.cpp +++ b/dom/workers/WorkerRunnable.cpp @@ -223,9 +223,7 @@ WorkerRunnable::PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate, #endif if (mBehavior == WorkerThreadModifyBusyCount) { - if (!aWorkerPrivate->ModifyBusyCountFromWorker(aCx, false)) { - aRunResult = false; - } + aWorkerPrivate->ModifyBusyCountFromWorker(aCx, false); } if (!aRunResult) { @@ -610,6 +608,9 @@ bool WorkerSameThreadRunnable::PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate) { + // We don't call WorkerRunnable::PreDispatch, because we're using + // WorkerThreadModifyBusyCount for mBehavior, and WorkerRunnable will assert + // that PreDispatch is on the parent thread in that case. aWorkerPrivate->AssertIsOnWorkerThread(); return true; } @@ -619,6 +620,9 @@ WorkerSameThreadRunnable::PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aDispatchResult) { + // We don't call WorkerRunnable::PostDispatch, because we're using + // WorkerThreadModifyBusyCount for mBehavior, and WorkerRunnable will assert + // that PostDispatch is on the parent thread in that case. aWorkerPrivate->AssertIsOnWorkerThread(); if (aDispatchResult) { DebugOnly willIncrement = aWorkerPrivate->ModifyBusyCountFromWorker(aCx, true); @@ -627,21 +631,3 @@ WorkerSameThreadRunnable::PostDispatch(JSContext* aCx, MOZ_ASSERT(willIncrement); } } - -void -WorkerSameThreadRunnable::PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate, - bool aRunResult) -{ - MOZ_ASSERT(aCx); - MOZ_ASSERT(aWorkerPrivate); - - aWorkerPrivate->AssertIsOnWorkerThread(); - - DebugOnly willDecrement = aWorkerPrivate->ModifyBusyCountFromWorker(aCx, false); - MOZ_ASSERT(willDecrement); - - if (!aRunResult) { - JS_ReportPendingException(aCx); - } -} - diff --git a/dom/workers/WorkerRunnable.h b/dom/workers/WorkerRunnable.h index d56c9a23a0..25dc479eba 100644 --- a/dom/workers/WorkerRunnable.h +++ b/dom/workers/WorkerRunnable.h @@ -386,9 +386,8 @@ protected: PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aDispatchResult) override; - virtual void - PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate, - bool aRunResult) override; + // We just delegate PostRun to WorkerRunnable, since it does exactly + // what we want. }; // Base class for the runnable objects, which makes a synchronous call to diff --git a/editor/libeditor/SetDocTitleTxn.cpp b/editor/libeditor/SetDocTitleTxn.cpp index 68646df4b0..13a1e3295d 100644 --- a/editor/libeditor/SetDocTitleTxn.cpp +++ b/editor/libeditor/SetDocTitleTxn.cpp @@ -25,7 +25,8 @@ using namespace mozilla; // note that aEditor is not refcounted SetDocTitleTxn::SetDocTitleTxn() : EditTxn() -, mIsTransient(false) + , mEditor(nullptr) + , mIsTransient(false) { } diff --git a/editor/libeditor/nsHTMLEditRules.cpp b/editor/libeditor/nsHTMLEditRules.cpp index bdfc9f118c..b4a2b41e0c 100644 --- a/editor/libeditor/nsHTMLEditRules.cpp +++ b/editor/libeditor/nsHTMLEditRules.cpp @@ -170,6 +170,13 @@ class nsEditableTextFunctor : public nsBoolDomIterFunctor ********************************************************/ nsHTMLEditRules::nsHTMLEditRules() + : mHTMLEditor(nullptr) + , mListenerEnabled(false) + , mReturnInEmptyLIKillsList(false) + , mDidDeleteSelection(false) + , mDidRangedDelete(false) + , mRestoreContentEditableCount(false) + , mJoinOffset(0) { InitFields(); } diff --git a/editor/libeditor/nsHTMLEditor.cpp b/editor/libeditor/nsHTMLEditor.cpp index 6d621637bb..1529684ecf 100644 --- a/editor/libeditor/nsHTMLEditor.cpp +++ b/editor/libeditor/nsHTMLEditor.cpp @@ -96,17 +96,42 @@ IsNamedAnchorTag(const nsString& s) nsHTMLEditor::nsHTMLEditor() : nsPlaintextEditor() , mCRInParagraphCreatesParagraph(false) +, mCSSAware(false) , mSelectedCellIndex(0) , mIsObjectResizingEnabled(true) , mIsResizing(false) +, mPreserveRatio(false) +, mResizedObjectIsAnImage(false) , mIsAbsolutelyPositioningEnabled(true) , mResizedObjectIsAbsolutelyPositioned(false) , mGrabberClicked(false) , mIsMoving(false) , mSnapToGridEnabled(false) , mIsInlineTableEditingEnabled(true) +, mOriginalX(0) +, mOriginalY(0) +, mResizedObjectX(0) +, mResizedObjectY(0) +, mResizedObjectWidth(0) +, mResizedObjectHeight(0) +, mResizedObjectMarginLeft(0) +, mResizedObjectMarginTop(0) +, mResizedObjectBorderLeft(0) +, mResizedObjectBorderTop(0) +, mXIncrementFactor(0) +, mYIncrementFactor(0) +, mWidthIncrementFactor(0) +, mHeightIncrementFactor(0) , mInfoXIncrement(20) , mInfoYIncrement(20) +, mPositionedObjectX(0) +, mPositionedObjectY(0) +, mPositionedObjectWidth(0) +, mPositionedObjectHeight(0) +, mPositionedObjectMarginLeft(0) +, mPositionedObjectMarginTop(0) +, mPositionedObjectBorderLeft(0) +, mPositionedObjectBorderTop(0) , mGridSize(0) { } diff --git a/editor/libeditor/nsHTMLURIRefObject.cpp b/editor/libeditor/nsHTMLURIRefObject.cpp index 6aeb28c835..35fbaa4271 100644 --- a/editor/libeditor/nsHTMLURIRefObject.cpp +++ b/editor/libeditor/nsHTMLURIRefObject.cpp @@ -59,8 +59,8 @@ #define MATCHES(tagName, str) tagName.EqualsIgnoreCase(str) nsHTMLURIRefObject::nsHTMLURIRefObject() + : mCurAttrIndex(0), mAttributeCnt(0) { - mCurAttrIndex = mAttributeCnt = 0; } nsHTMLURIRefObject::~nsHTMLURIRefObject() diff --git a/editor/libeditor/nsTextEditRules.cpp b/editor/libeditor/nsTextEditRules.cpp index edd1376bb3..2b63424815 100644 --- a/editor/libeditor/nsTextEditRules.cpp +++ b/editor/libeditor/nsTextEditRules.cpp @@ -57,6 +57,15 @@ using namespace mozilla::dom; ********************************************************/ nsTextEditRules::nsTextEditRules() + : mEditor(nullptr) + , mPasswordIMEIndex(0) + , mCachedSelectionOffset(0) + , mActionNesting(0) + , mLockRulesSniffing(false) + , mDidExplicitlySetInterline(false) + , mDeleteBidiImmediately(false) + , mLastStart(0) + , mLastLength(0) { InitFields(); } diff --git a/editor/libeditor/nsTextEditRules.h b/editor/libeditor/nsTextEditRules.h index 9b951eae1e..c39c489c61 100644 --- a/editor/libeditor/nsTextEditRules.h +++ b/editor/libeditor/nsTextEditRules.h @@ -333,14 +333,25 @@ class nsAutoLockRulesSniffing */ class nsAutoLockListener { - public: +public: + + explicit nsAutoLockListener(bool *enabled) + : mEnabled(enabled), mOldState(false) + { + if (mEnabled) { + mOldState = *mEnabled; + *mEnabled = false; + } + } - explicit nsAutoLockListener(bool *enabled) : mEnabled(enabled) - {if (mEnabled) { mOldState=*mEnabled; *mEnabled = false;}} ~nsAutoLockListener() - {if (mEnabled) *mEnabled = mOldState;} + { + if (mEnabled) { + *mEnabled = mOldState; + } + } - protected: +protected: bool *mEnabled; bool mOldState; }; diff --git a/editor/txtsvc/nsFilteredContentIterator.h b/editor/txtsvc/nsFilteredContentIterator.h index 175f70e3f7..9dde8132fb 100644 --- a/editor/txtsvc/nsFilteredContentIterator.h +++ b/editor/txtsvc/nsFilteredContentIterator.h @@ -45,7 +45,7 @@ public: void ClearDidSkip() { mDidSkip = false; } protected: - nsFilteredContentIterator() { } + nsFilteredContentIterator() : mDidSkip(false), mIsOutOfRange(false) { } virtual ~nsFilteredContentIterator(); diff --git a/gfx/2d/Logging.h b/gfx/2d/Logging.h index f6b1ddaac4..3f1a11c351 100644 --- a/gfx/2d/Logging.h +++ b/gfx/2d/Logging.h @@ -255,7 +255,10 @@ public: // version of that method for different loggers, this is OK. Once we do, // change BasicLogger::ShouldOutputMessage to Logger::ShouldOutputMessage. explicit Log(int aOptions = Log::DefaultOptions(L == LOG_CRITICAL), - LogReason aReason = LogReason::MustBeMoreThanThis) { + LogReason aReason = LogReason::MustBeMoreThanThis) + : mOptions(0) + , mLogIt(false) + { Init(aOptions, BasicLogger::ShouldOutputMessage(L), aReason); } diff --git a/gfx/2d/Types.h b/gfx/2d/Types.h index 2d9fd0ecd7..6bd2eb9e61 100644 --- a/gfx/2d/Types.h +++ b/gfx/2d/Types.h @@ -343,6 +343,9 @@ enum class JobStatus { } // namespace gfx } // namespace mozilla +// XXX: temporary +typedef mozilla::gfx::SurfaceFormat gfxImageFormat; + #if defined(XP_WIN) && defined(MOZ_GFX) #ifdef GFX2D_INTERNAL #define GFX2D_API __declspec(dllexport) diff --git a/gfx/gl/GLBlitHelper.cpp b/gfx/gl/GLBlitHelper.cpp index 905c8fca83..90e1ef8330 100644 --- a/gfx/gl/GLBlitHelper.cpp +++ b/gfx/gl/GLBlitHelper.cpp @@ -955,7 +955,7 @@ GLBlitHelper::DrawBlitTextureToFramebuffer(GLuint srcTex, GLuint destFB, type = BlitTexRect; break; default: - MOZ_CRASH("Fatal Error: Bad `srcTarget`."); + MOZ_CRASH("GFX: Fatal Error: Bad `srcTarget`."); break; } diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index 3962894ebd..85143e5f25 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -406,11 +406,14 @@ GLContext::GLContext(const SurfaceCaps& caps, mMaxCubeMapTextureSize(0), mMaxTextureImageSize(0), mMaxRenderbufferSize(0), + mMaxSamples(0), mNeedsTextureSizeChecks(false), mNeedsFlushBeforeDeleteFB(false), mWorkAroundDriverBugs(true), mHeavyGLCallsSinceLastFlush(false) { + mMaxViewportDims[0] = 0; + mMaxViewportDims[1] = 0; mOwningThreadId = PlatformThread::CurrentId(); } @@ -1717,7 +1720,6 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl) mMaxTextureImageSize = mMaxTextureSize; - mMaxSamples = 0; if (IsSupported(GLFeature::framebuffer_multisample)) { fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&mMaxSamples); } @@ -2773,7 +2775,7 @@ GLContext::Readback(SharedSurface* src, gfx::DataSourceSurface* dest) LOCAL_GL_RENDERBUFFER, src->ProdRenderbuffer()); break; default: - MOZ_CRASH("bad `src->mAttachType`."); + MOZ_CRASH("GFX: bad `src->mAttachType`."); } DebugOnly status = fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 01c34d8222..f2ffc7b27e 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -51,6 +51,8 @@ #include "gfx2DGlue.h" #include "GeckoProfiler.h" +class nsIWidget; + namespace android { class GraphicBuffer; } // namespace android @@ -339,7 +341,6 @@ public: protected: bool mInitialized; bool mIsOffscreen; - bool mIsGlobalSharedContext; bool mContextLost; /** @@ -3330,7 +3331,7 @@ public: virtual GLenum GetPreferredARGB32Format() const { return LOCAL_GL_RGBA; } - virtual bool RenewSurface() { return false; } + virtual bool RenewSurface(nsIWidget* aWidget) { return false; } // Shared code for GL extensions and GLX extensions. static bool ListHasExtension(const GLubyte *extensions, diff --git a/gfx/gl/GLContextEAGL.h b/gfx/gl/GLContextEAGL.h index 83f3687b42..29588781f1 100644 --- a/gfx/gl/GLContextEAGL.h +++ b/gfx/gl/GLContextEAGL.h @@ -60,7 +60,8 @@ public: return mBackbufferFB; } - virtual bool RenewSurface() override { + virtual bool RenewSurface(nsIWidget* aWidget) override { + // FIXME: should use the passed widget instead of the existing one. return RecreateRB(); } diff --git a/gfx/gl/GLContextEGL.h b/gfx/gl/GLContextEGL.h index f6f491c7b9..073340b780 100644 --- a/gfx/gl/GLContextEGL.h +++ b/gfx/gl/GLContextEGL.h @@ -10,8 +10,6 @@ #include "GLContext.h" #include "GLLibraryEGL.h" -class nsIWidget; - namespace mozilla { namespace gl { @@ -81,7 +79,7 @@ public: virtual bool IsCurrent() override; - virtual bool RenewSurface() override; + virtual bool RenewSurface(nsIWidget* aWidget) override; virtual void ReleaseSurface() override; diff --git a/gfx/gl/GLContextProviderCGL.mm b/gfx/gl/GLContextProviderCGL.mm index 38d55864d6..beae43ec13 100644 --- a/gfx/gl/GLContextProviderCGL.mm +++ b/gfx/gl/GLContextProviderCGL.mm @@ -17,6 +17,10 @@ #include +// When running inside a VM, creating an accelerated OpenGL context usually +// fails. Uncomment this line to emulate that behavior. +// #define EMULATE_VM + namespace mozilla { namespace gl { @@ -174,12 +178,23 @@ GLContextProviderCGL::CreateWrappingExisting(void*, void*) } static const NSOpenGLPixelFormatAttribute kAttribs_singleBuffered[] = { + NSOpenGLPFAAllowOfflineRenderers, + 0 +}; + +static const NSOpenGLPixelFormatAttribute kAttribs_singleBuffered_accel[] = { NSOpenGLPFAAccelerated, NSOpenGLPFAAllowOfflineRenderers, 0 }; static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered[] = { + NSOpenGLPFAAllowOfflineRenderers, + NSOpenGLPFADoubleBuffer, + 0 +}; + +static const NSOpenGLPixelFormatAttribute kAttribs_doubleBuffered_accel[] = { NSOpenGLPFAAccelerated, NSOpenGLPFAAllowOfflineRenderers, NSOpenGLPFADoubleBuffer, @@ -227,17 +242,23 @@ CreateWithFormat(const NSOpenGLPixelFormatAttribute* attribs) } already_AddRefed -GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget) +GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget, bool aForceAccelerated) { if (!sCGLLibrary.EnsureInitialized()) { return nullptr; } +#ifdef EMULATE_VM + if (aForceAccelerated) { + return nullptr; + } +#endif + const NSOpenGLPixelFormatAttribute* attribs; if (sCGLLibrary.UseDoubleBufferedWindows()) { - attribs = kAttribs_doubleBuffered; + attribs = aForceAccelerated ? kAttribs_doubleBuffered_accel : kAttribs_doubleBuffered; } else { - attribs = kAttribs_singleBuffered; + attribs = aForceAccelerated ? kAttribs_singleBuffered_accel : kAttribs_singleBuffered; } NSOpenGLContext* context = CreateWithFormat(attribs); if (!context) { diff --git a/gfx/gl/GLContextProviderEAGL.mm b/gfx/gl/GLContextProviderEAGL.mm index 3b80f062e8..efc934c910 100644 --- a/gfx/gl/GLContextProviderEAGL.mm +++ b/gfx/gl/GLContextProviderEAGL.mm @@ -211,7 +211,7 @@ CreateEAGLContext(bool aOffscreen, GLContextEAGL* sharedContext) } already_AddRefed -GLContextProviderEAGL::CreateForWindow(nsIWidget* aWidget) +GLContextProviderEAGL::CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated) { RefPtr glContext = CreateEAGLContext(false, GetGlobalContextEAGL()); if (!glContext) { diff --git a/gfx/gl/GLContextProviderEGL.cpp b/gfx/gl/GLContextProviderEGL.cpp index 4ad216ae3e..97c2607a9e 100644 --- a/gfx/gl/GLContextProviderEGL.cpp +++ b/gfx/gl/GLContextProviderEGL.cpp @@ -21,11 +21,6 @@ #endif #ifdef ANDROID - /* from widget */ - #ifdef MOZ_WIDGET_ANDROID - #include "AndroidBridge.h" - #endif - #include #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args) @@ -172,13 +167,12 @@ static EGLSurface CreateSurfaceForWindow(nsIWidget* widget, const EGLConfig& config) { EGLSurface newSurface = nullptr; + MOZ_ASSERT(widget); #ifdef MOZ_WIDGET_ANDROID - mozilla::AndroidBridge::Bridge()->RegisterCompositor(); - newSurface = mozilla::AndroidBridge::Bridge()->CreateEGLSurfaceForCompositor(); + newSurface = EGLSurface(widget->GetNativeData(NS_NATIVE_NEW_EGL_SURFACE)); #else - MOZ_ASSERT(widget != nullptr); - newSurface = sEGLLibrary.fCreateWindowSurface(EGL_DISPLAY(), config, - GET_NATIVE_WINDOW(widget), 0); + newSurface = sEGLLibrary.fCreateWindowSurface(EGL_DISPLAY(), config, + GET_NATIVE_WINDOW(widget), 0); #endif return newSurface; } @@ -388,22 +382,14 @@ GLContextEGL::IsCurrent() { } bool -GLContextEGL::RenewSurface() { +GLContextEGL::RenewSurface(nsIWidget* aWidget) { if (!mOwnsContext) { return false; } -#ifndef MOZ_WIDGET_ANDROID - MOZ_CRASH("unimplemented"); - // to support this on non-Android platforms, need to keep track of the nsIWidget that - // this GLContext was created for (with CreateForWindow) so that we know what to - // pass again to CreateSurfaceForWindow below. - // The reason why Android doesn't need this is that it delegates EGLSurface creation to - // Java code which is the only thing that knows about our actual widget. -#endif // unconditionally release the surface and create a new one. Don't try to optimize this away. // If we get here, then by definition we know that we want to get a new surface. ReleaseSurface(); - mSurface = mozilla::gl::CreateSurfaceForWindow(nullptr, mConfig); // the nullptr here is where we assume Android. + mSurface = mozilla::gl::CreateSurfaceForWindow(aWidget, mConfig); if (!mSurface) { return false; } @@ -458,19 +444,19 @@ GLContextEGL::HoldSurface(gfxASurface *aSurf) { GLContextEGL::CreateSurfaceForWindow(nsIWidget* aWidget) { if (!sEGLLibrary.EnsureInitialized()) { - MOZ_CRASH("Failed to load EGL library!\n"); + MOZ_CRASH("GFX: Failed to load EGL library!\n"); return nullptr; } EGLConfig config; if (!CreateConfig(&config, aWidget)) { - MOZ_CRASH("Failed to create EGLConfig!\n"); + MOZ_CRASH("GFX: Failed to create EGLConfig!\n"); return nullptr; } EGLSurface surface = mozilla::gl::CreateSurfaceForWindow(aWidget, config); if (!surface) { - MOZ_CRASH("Failed to create EGLSurface for window!\n"); + MOZ_CRASH("GFX: Failed to create EGLSurface for window!\n"); return nullptr; } return surface; @@ -741,7 +727,7 @@ already_AddRefed GLContextProviderEGL::CreateWrappingExisting(void* aContext, void* aSurface) { if (!sEGLLibrary.EnsureInitialized()) { - MOZ_CRASH("Failed to load EGL library!\n"); + MOZ_CRASH("GFX: Failed to load EGL library 2!\n"); return nullptr; } @@ -763,10 +749,10 @@ GLContextProviderEGL::CreateWrappingExisting(void* aContext, void* aSurface) } already_AddRefed -GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget) +GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget, bool aForceAccelerated) { if (!sEGLLibrary.EnsureInitialized()) { - MOZ_CRASH("Failed to load EGL library!\n"); + MOZ_CRASH("GFX: Failed to load EGL library 3!\n"); return nullptr; } @@ -774,13 +760,13 @@ GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget) EGLConfig config; if (!CreateConfig(&config, aWidget)) { - MOZ_CRASH("Failed to create EGLConfig!\n"); + MOZ_CRASH("GFX: Failed to create EGLConfig!\n"); return nullptr; } EGLSurface surface = mozilla::gl::CreateSurfaceForWindow(aWidget, config); if (!surface) { - MOZ_CRASH("Failed to create EGLSurface!\n"); + MOZ_CRASH("GFX: Failed to create EGLSurface!\n"); return nullptr; } @@ -791,7 +777,7 @@ GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget) config, surface); if (!glContext) { - MOZ_CRASH("Failed to create EGLContext!\n"); + MOZ_CRASH("GFX: Failed to create EGLContext!\n"); mozilla::gl::DestroySurface(surface); return nullptr; } @@ -807,12 +793,12 @@ EGLSurface GLContextProviderEGL::CreateEGLSurface(void* aWindow) { if (!sEGLLibrary.EnsureInitialized()) { - MOZ_CRASH("Failed to load EGL library!\n"); + MOZ_CRASH("GFX: Failed to load EGL library 4!\n"); } EGLConfig config; if (!CreateConfig(&config, static_cast(aWindow))) { - MOZ_CRASH("Failed to create EGLConfig!\n"); + MOZ_CRASH("GFX: Failed to create EGLConfig 2!\n"); } MOZ_ASSERT(aWindow); @@ -820,7 +806,7 @@ GLContextProviderEGL::CreateEGLSurface(void* aWindow) EGLSurface surface = sEGLLibrary.fCreateWindowSurface(EGL_DISPLAY(), config, aWindow, 0); if (surface == EGL_NO_SURFACE) { - MOZ_CRASH("Failed to create EGLSurface!\n"); + MOZ_CRASH("GFX: Failed to create EGLSurface 2!\n"); } return surface; @@ -830,7 +816,7 @@ void GLContextProviderEGL::DestroyEGLSurface(EGLSurface surface) { if (!sEGLLibrary.EnsureInitialized()) { - MOZ_CRASH("Failed to load EGL library!\n"); + MOZ_CRASH("GFX: Failed to load EGL library 5!\n"); } sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface); diff --git a/gfx/gl/GLContextProviderGLX.cpp b/gfx/gl/GLContextProviderGLX.cpp index acf7c6b4a5..62fa4cf873 100644 --- a/gfx/gl/GLContextProviderGLX.cpp +++ b/gfx/gl/GLContextProviderGLX.cpp @@ -1050,7 +1050,7 @@ GLContextProviderGLX::CreateWrappingExisting(void* aContext, void* aSurface) } already_AddRefed -GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget) +GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget, bool aForceAccelerated) { if (!sGLXLibrary.EnsureInitialized()) { return nullptr; diff --git a/gfx/gl/GLContextProviderImpl.h b/gfx/gl/GLContextProviderImpl.h index c3bcb5c05d..d2d81edfec 100644 --- a/gfx/gl/GLContextProviderImpl.h +++ b/gfx/gl/GLContextProviderImpl.h @@ -35,11 +35,12 @@ public: * a GL layer manager. * * @param aWidget Widget whose surface to create a context for + * @param aForceAccelerated true if only accelerated contexts are allowed * * @return Context to use for the window */ static already_AddRefed - CreateForWindow(nsIWidget* widget); + CreateForWindow(nsIWidget* widget, bool aForceAccelerated); /** * Create a context for offscreen rendering. The target of this diff --git a/gfx/gl/GLContextProviderNull.cpp b/gfx/gl/GLContextProviderNull.cpp index a8001179aa..5e24ee3d65 100644 --- a/gfx/gl/GLContextProviderNull.cpp +++ b/gfx/gl/GLContextProviderNull.cpp @@ -9,7 +9,7 @@ namespace mozilla { namespace gl { already_AddRefed -GLContextProviderNull::CreateForWindow(nsIWidget*) +GLContextProviderNull::CreateForWindow(nsIWidget*, bool aForceAccelerated) { return nullptr; } diff --git a/gfx/gl/GLContextProviderWGL.cpp b/gfx/gl/GLContextProviderWGL.cpp index a8b59b0403..e9a2bb11ab 100644 --- a/gfx/gl/GLContextProviderWGL.cpp +++ b/gfx/gl/GLContextProviderWGL.cpp @@ -433,7 +433,7 @@ GLContextProviderWGL::CreateWrappingExisting(void*, void*) } already_AddRefed -GLContextProviderWGL::CreateForWindow(nsIWidget *aWidget) +GLContextProviderWGL::CreateForWindow(nsIWidget *aWidget, bool aForceAccelerated) { if (!sWGLLib.EnsureInitialized()) { return nullptr; diff --git a/gfx/gl/GLLibraryEGL.cpp b/gfx/gl/GLLibraryEGL.cpp index 0b44ff622b..585324a3b9 100644 --- a/gfx/gl/GLLibraryEGL.cpp +++ b/gfx/gl/GLLibraryEGL.cpp @@ -8,6 +8,7 @@ #include "gfxUtils.h" #include "mozilla/Preferences.h" #include "mozilla/Assertions.h" +#include "mozilla/unused.h" #include "nsDirectoryServiceDefs.h" #include "nsDirectoryServiceUtils.h" #include "nsIGfxInfo.h" @@ -189,7 +190,7 @@ GLLibraryEGL::EnsureInitialized(bool forceAccel) #ifdef MOZ_B2G if (!sCurrentContext.init()) - MOZ_CRASH("Tls init failed"); + MOZ_CRASH("GFX: Tls init failed"); #endif #ifdef XP_WIN @@ -306,8 +307,8 @@ GLLibraryEGL::EnsureInitialized(bool forceAccel) }; // Do not warn about the failure to load this - see bug 1092191 - GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0], nullptr, nullptr, - false); + Unused << GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0], + nullptr, nullptr, false); #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18 MOZ_RELEASE_ASSERT(mSymbols.fQueryStringImplementationANDROID, diff --git a/gfx/gl/GLLibraryLoader.cpp b/gfx/gl/GLLibraryLoader.cpp index a66bd372b1..1f0eeec2b8 100644 --- a/gfx/gl/GLLibraryLoader.cpp +++ b/gfx/gl/GLLibraryLoader.cpp @@ -95,8 +95,9 @@ GLLibraryLoader::LoadSymbols(PRLibrary *lib, } if (*ss->symPointer == 0) { - if (warnOnFailure) + if (warnOnFailure) { printf_stderr("Can't find symbol '%s'.\n", ss->symNames[0]); + } failCount++; } diff --git a/gfx/gl/GLReadTexImageHelper.cpp b/gfx/gl/GLReadTexImageHelper.cpp index 1c37e326ed..8d4b9f3d00 100644 --- a/gfx/gl/GLReadTexImageHelper.cpp +++ b/gfx/gl/GLReadTexImageHelper.cpp @@ -309,7 +309,7 @@ ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest) destType = LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV; break; default: - MOZ_CRASH("Bad format."); + MOZ_CRASH("GFX: Bad format, read pixels."); } destPixelSize = BytesPerPixel(dest->GetFormat()); MOZ_ASSERT(dest->GetSize().width * destPixelSize <= dest->Stride()); @@ -352,7 +352,7 @@ ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest) break; } default: { - MOZ_CRASH("Bad read format."); + MOZ_CRASH("GFX: Bad read format, read format."); } } @@ -373,7 +373,7 @@ ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest) break; } default: { - MOZ_CRASH("Bad read type."); + MOZ_CRASH("GFX: Bad read type, read type."); } } diff --git a/gfx/gl/GLReadTexImageHelper.h b/gfx/gl/GLReadTexImageHelper.h index 685afcf270..cfd65d8a2f 100644 --- a/gfx/gl/GLReadTexImageHelper.h +++ b/gfx/gl/GLReadTexImageHelper.h @@ -58,10 +58,10 @@ public: /** * Read the image data contained in aTexture, and return it as an ImageSurface. - * If GL_RGBA is given as the format, a gfxImageFormat::ARGB32 surface is returned. + * If GL_RGBA is given as the format, a SurfaceFormat::A8R8G8B8_UINT32 surface is returned. * Not implemented yet: - * If GL_RGB is given as the format, a gfxImageFormat::RGB24 surface is returned. - * If GL_LUMINANCE is given as the format, a gfxImageFormat::A8 surface is returned. + * If GL_RGB is given as the format, a SurfaceFormat::X8R8G8B8_UINT32 surface is returned. + * If GL_LUMINANCE is given as the format, a SurfaceFormat::A8 surface is returned. * * THIS IS EXPENSIVE. It is ridiculously expensive. Only do this * if you absolutely positively must, and never in any performance diff --git a/gfx/gl/GLScreenBuffer.cpp b/gfx/gl/GLScreenBuffer.cpp index f6dbad7c91..4e8d7533da 100755 --- a/gfx/gl/GLScreenBuffer.cpp +++ b/gfx/gl/GLScreenBuffer.cpp @@ -172,7 +172,7 @@ GLScreenBuffer::BindAsFramebuffer(GLContext* const gl, GLenum target) const break; default: - MOZ_CRASH("Bad `target` for BindFramebuffer."); + MOZ_CRASH("GFX: Bad `target` for BindFramebuffer."); } } @@ -443,7 +443,7 @@ GLScreenBuffer::AssureBlitted() } else if (mGL->IsExtensionSupported(GLContext::APPLE_framebuffer_multisample)) { mGL->fResolveMultisampleFramebufferAPPLE(); } else { - MOZ_CRASH("No available blit methods."); + MOZ_CRASH("GFX: No available blit methods."); } // Done! } @@ -657,7 +657,7 @@ GLScreenBuffer::SetDrawBuffer(GLenum mode) break; default: - MOZ_CRASH("Bad value."); + MOZ_CRASH("GFX: Bad value."); } mGL->MakeCurrent(); @@ -895,7 +895,7 @@ ReadBuffer::Create(GLContext* gl, colorRB = surf->ProdRenderbuffer(); break; default: - MOZ_CRASH("Unknown attachment type?"); + MOZ_CRASH("GFX: Unknown attachment type, create?"); } MOZ_ASSERT(colorTex || colorRB); @@ -954,7 +954,7 @@ ReadBuffer::Attach(SharedSurface* surf) colorRB = surf->ProdRenderbuffer(); break; default: - MOZ_CRASH("Unknown attachment type?"); + MOZ_CRASH("GFX: Unknown attachment type, attach?"); } mGL->AttachBuffersToFB(colorTex, colorRB, 0, 0, mFB, target); @@ -991,7 +991,7 @@ ReadBuffer::SetReadBuffer(GLenum userMode) const break; default: - MOZ_CRASH("Bad value."); + MOZ_CRASH("GFX: Bad value."); } mGL->MakeCurrent(); diff --git a/gfx/gl/GLTextureImage.cpp b/gfx/gl/GLTextureImage.cpp index 1dccc262e5..6973231126 100644 --- a/gfx/gl/GLTextureImage.cpp +++ b/gfx/gl/GLTextureImage.cpp @@ -39,7 +39,7 @@ CreateTextureImage(GLContext* gl, case GLContextType::EGL: return CreateTextureImageEGL(gl, aSize, aContentType, aWrapMode, aFlags, aImageFormat); default: - return CreateBasicTextureImage(gl, aSize, aContentType, aWrapMode, aFlags, aImageFormat); + return CreateBasicTextureImage(gl, aSize, aContentType, aWrapMode, aFlags); } } @@ -54,7 +54,7 @@ TileGenFunc(GLContext* gl, switch (gl->GetContextType()) { #ifdef XP_MACOSX case GLContextType::CGL: - return TileGenFuncCGL(gl, aSize, aContentType, aFlags, aImageFormat); + return TileGenFuncCGL(gl, aSize, aContentType, aFlags); #endif case GLContextType::EGL: return TileGenFuncEGL(gl, aSize, aContentType, aFlags, aImageFormat); @@ -266,10 +266,11 @@ gfx::IntSize TextureImage::GetSize() const { TextureImage::TextureImage(const gfx::IntSize& aSize, GLenum aWrapMode, ContentType aContentType, - Flags aFlags, ImageFormat aImageFormat) + Flags aFlags) : mSize(aSize) , mWrapMode(aWrapMode) , mContentType(aContentType) + , mTextureFormat(gfx::SurfaceFormat::UNKNOWN) , mFilter(Filter::GOOD) , mFlags(aFlags) {} @@ -279,9 +280,8 @@ BasicTextureImage::BasicTextureImage(GLuint aTexture, GLenum aWrapMode, ContentType aContentType, GLContext* aContext, - TextureImage::Flags aFlags, - TextureImage::ImageFormat aImageFormat) - : TextureImage(aSize, aWrapMode, aContentType, aFlags, aImageFormat) + TextureImage::Flags aFlags) + : TextureImage(aSize, aWrapMode, aContentType, aFlags) , mTexture(aTexture) , mTextureState(Created) , mGLContext(aContext) @@ -314,6 +314,7 @@ TiledTextureImage::TiledTextureImage(GLContext* aGL, : TextureImage(aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType, aFlags) , mCurrentImage(0) , mIterationCallback(nullptr) + , mIterationCallbackData(nullptr) , mInUpdate(false) , mRows(0) , mColumns(0) @@ -704,8 +705,7 @@ CreateBasicTextureImage(GLContext* aGL, const gfx::IntSize& aSize, TextureImage::ContentType aContentType, GLenum aWrapMode, - TextureImage::Flags aFlags, - TextureImage::ImageFormat aImageFormat) + TextureImage::Flags aFlags) { bool useNearestFilter = aFlags & TextureImage::UseNearestFilter; if (!aGL->MakeCurrent()) { @@ -725,7 +725,7 @@ CreateBasicTextureImage(GLContext* aGL, RefPtr texImage = new BasicTextureImage(texture, aSize, aWrapMode, aContentType, - aGL, aFlags, aImageFormat); + aGL, aFlags); return texImage.forget(); } diff --git a/gfx/gl/GLTextureImage.h b/gfx/gl/GLTextureImage.h index ba87f3f1a9..231f6b6d18 100644 --- a/gfx/gl/GLTextureImage.h +++ b/gfx/gl/GLTextureImage.h @@ -211,8 +211,7 @@ protected: */ TextureImage(const gfx::IntSize& aSize, GLenum aWrapMode, ContentType aContentType, - Flags aFlags = NoFlags, - ImageFormat aImageFormat = gfxImageFormat::Unknown); + Flags aFlags = NoFlags); // Protected destructor, to discourage deletion outside of Release(): virtual ~TextureImage() {} @@ -247,8 +246,7 @@ public: GLenum aWrapMode, ContentType aContentType, GLContext* aContext, - TextureImage::Flags aFlags = TextureImage::NoFlags, - TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown); + TextureImage::Flags aFlags = TextureImage::NoFlags); virtual void BindTexture(GLenum aTextureUnit); @@ -298,7 +296,7 @@ public: gfx::IntSize aSize, TextureImage::ContentType, TextureImage::Flags aFlags = TextureImage::NoFlags, - TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown); + TextureImage::ImageFormat aImageFormat = gfx::SurfaceFormat::UNKNOWN); ~TiledTextureImage(); void DumpDiv(); virtual gfx::DrawTarget* BeginUpdate(nsIntRegion& aRegion); @@ -347,8 +345,7 @@ CreateBasicTextureImage(GLContext* aGL, const gfx::IntSize& aSize, TextureImage::ContentType aContentType, GLenum aWrapMode, - TextureImage::Flags aFlags, - TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown); + TextureImage::Flags aFlags); /** * Return a valid, allocated TextureImage of |aSize| with @@ -373,7 +370,7 @@ CreateTextureImage(GLContext* gl, TextureImage::ContentType aContentType, GLenum aWrapMode, TextureImage::Flags aFlags = TextureImage::NoFlags, - TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown); + TextureImage::ImageFormat aImageFormat = gfx::SurfaceFormat::UNKNOWN); } // namespace gl } // namespace mozilla diff --git a/gfx/gl/SharedSurface.cpp b/gfx/gl/SharedSurface.cpp index e4bb8af60e..bdd9d1cd30 100644 --- a/gfx/gl/SharedSurface.cpp +++ b/gfx/gl/SharedSurface.cpp @@ -78,7 +78,7 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest, dest->mSize, true); } else { - MOZ_CRASH("Unhandled dest->mAttachType."); + MOZ_CRASH("GFX: Unhandled dest->mAttachType 1."); } if (srcNeedsUnlock) @@ -123,7 +123,7 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest, dest->mSize, true); } else { - MOZ_CRASH("Unhandled src->mAttachType."); + MOZ_CRASH("GFX: Unhandled src->mAttachType 2."); } if (destNeedsUnlock) @@ -163,7 +163,7 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest, return; } - MOZ_CRASH("Unhandled dest->mAttachType."); + MOZ_CRASH("GFX: Unhandled dest->mAttachType 3."); } if (src->mAttachType == AttachmentType::GLRenderbuffer) { @@ -190,10 +190,10 @@ SharedSurface::ProdCopy(SharedSurface* src, SharedSurface* dest, return; } - MOZ_CRASH("Unhandled dest->mAttachType."); + MOZ_CRASH("GFX: Unhandled dest->mAttachType 4."); } - MOZ_CRASH("Unhandled src->mAttachType."); + MOZ_CRASH("GFX: Unhandled src->mAttachType 5."); } //////////////////////////////////////////////////////////////////////// @@ -470,7 +470,7 @@ ScopedReadbackFB::ScopedReadbackFB(SharedSurface* src) break; } default: - MOZ_CRASH("Unhandled `mAttachType`."); + MOZ_CRASH("GFX: Unhandled `mAttachType`."); } if (src->NeedsIndirectReads()) { diff --git a/gfx/gl/SharedSurfaceANGLE.cpp b/gfx/gl/SharedSurfaceANGLE.cpp index 2fc7c6d7ce..c2ea412a67 100644 --- a/gfx/gl/SharedSurfaceANGLE.cpp +++ b/gfx/gl/SharedSurfaceANGLE.cpp @@ -158,7 +158,7 @@ SharedSurface_ANGLEShareHandle::ProducerAcquireImpl() if (mKeyedMutex) { HRESULT hr = mKeyedMutex->AcquireSync(0, 10000); if (hr == WAIT_TIMEOUT) { - MOZ_CRASH(); + MOZ_CRASH("GFX: ANGLE share handle timeout"); } } } @@ -214,7 +214,7 @@ SharedSurface_ANGLEShareHandle::ConsumerAcquireImpl() if (mConsumerKeyedMutex) { HRESULT hr = mConsumerKeyedMutex->AcquireSync(0, 10000); if (hr == WAIT_TIMEOUT) { - MOZ_CRASH(); + MOZ_CRASH("GFX: ANGLE consumer mutex timeout"); } } } @@ -289,7 +289,7 @@ public: if (mMutex) { hr = mMutex->AcquireSync(0, 10000); if (hr == WAIT_TIMEOUT) { - MOZ_CRASH(); + MOZ_CRASH("GFX: ANGLE scoped lock timeout"); } if (FAILED(hr)) { diff --git a/gfx/gl/SharedSurfaceGLX.cpp b/gfx/gl/SharedSurfaceGLX.cpp index e91630c22e..51242d5907 100644 --- a/gfx/gl/SharedSurfaceGLX.cpp +++ b/gfx/gl/SharedSurfaceGLX.cpp @@ -29,7 +29,7 @@ SharedSurface_GLXDrawable::Create(GLContext* prodGL, UniquePtr ret; Display* display = DefaultXDisplay(); Screen* screen = XDefaultScreenOfDisplay(display); - Visual* visual = gfxXlibSurface::FindVisual(screen, gfxImageFormat::ARGB32); + Visual* visual = gfxXlibSurface::FindVisual(screen, gfx::SurfaceFormat::A8R8G8B8_UINT32); RefPtr surf = gfxXlibSurface::Create(screen, visual, size); if (!deallocateClient) diff --git a/gfx/gl/TextureImageCGL.h b/gfx/gl/TextureImageCGL.h index a2b489c3a3..c739c0a2b0 100644 --- a/gfx/gl/TextureImageCGL.h +++ b/gfx/gl/TextureImageCGL.h @@ -23,8 +23,7 @@ public: GLenum aWrapMode, ContentType aContentType, GLContext* aContext, - TextureImage::Flags aFlags = TextureImage::NoFlags, - TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown); + TextureImage::Flags aFlags = TextureImage::NoFlags); ~TextureImageCGL(); @@ -51,8 +50,7 @@ already_AddRefed TileGenFuncCGL(GLContext *gl, const gfx::IntSize& aSize, TextureImage::ContentType aContentType, - TextureImage::Flags aFlags, - TextureImage::ImageFormat aImageFormat); + TextureImage::Flags aFlags); } // namespace gl } // namespace mozilla diff --git a/gfx/gl/TextureImageCGL.mm b/gfx/gl/TextureImageCGL.mm index b83d823301..e7a4286e0c 100644 --- a/gfx/gl/TextureImageCGL.mm +++ b/gfx/gl/TextureImageCGL.mm @@ -21,10 +21,9 @@ TextureImageCGL::TextureImageCGL(GLuint aTexture, GLenum aWrapMode, ContentType aContentType, GLContext* aContext, - TextureImage::Flags aFlags, - TextureImage::ImageFormat aImageFormat) + TextureImage::Flags aFlags) : BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, - aContext, aFlags, aImageFormat) + aContext, aFlags) , mPixelBuffer(0) , mBoundPixelBuffer(false) {} @@ -76,15 +75,14 @@ CreateTextureImageCGL(GLContext* gl, } return CreateBasicTextureImage(gl, aSize, aContentType, aWrapMode, - aFlags, aImageFormat); + aFlags); } already_AddRefed TileGenFuncCGL(GLContext *gl, const IntSize& aSize, TextureImage::ContentType aContentType, - TextureImage::Flags aFlags, - TextureImage::ImageFormat aImageFormat) + TextureImage::Flags aFlags) { bool useNearestFilter = aFlags & TextureImage::UseNearestFilter; gl->MakeCurrent(); @@ -103,7 +101,7 @@ TileGenFuncCGL(GLContext *gl, RefPtr teximage (new TextureImageCGL(texture, aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType, - gl, aFlags, aImageFormat)); + gl, aFlags)); return teximage.forget(); } diff --git a/gfx/gl/TextureImageEGL.h b/gfx/gl/TextureImageEGL.h index 472718e2ef..7495728d5b 100644 --- a/gfx/gl/TextureImageEGL.h +++ b/gfx/gl/TextureImageEGL.h @@ -22,7 +22,7 @@ public: GLContext* aContext, Flags aFlags = TextureImage::NoFlags, TextureState aTextureState = Created, - TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown); + TextureImage::ImageFormat aImageFormat = SurfaceFormat::UNKNOWN); virtual ~TextureImageEGL(); diff --git a/gfx/ipc/GfxMessageUtils.h b/gfx/ipc/GfxMessageUtils.h index bd26484119..3807ec067f 100644 --- a/gfx/ipc/GfxMessageUtils.h +++ b/gfx/ipc/GfxMessageUtils.h @@ -229,14 +229,6 @@ struct ParamTraits mozilla::layers::ScaleMode::SENTINEL> {}; -template <> -struct ParamTraits - : public ContiguousEnumSerializer< - gfxImageFormat, - gfxImageFormat::ARGB32, - gfxImageFormat::Unknown> -{}; - template <> struct ParamTraits : public ContiguousEnumSerializer< @@ -287,8 +279,8 @@ struct ParamTraits template <> struct ParamTraits : public EnumSerializer + SurfaceFormat::A8R8G8B8_UINT32, + SurfaceFormat::UNKNOWN> {}; */ diff --git a/gfx/ipc/SharedDIBSurface.cpp b/gfx/ipc/SharedDIBSurface.cpp index 656abab8fa..696bb300cf 100644 --- a/gfx/ipc/SharedDIBSurface.cpp +++ b/gfx/ipc/SharedDIBSurface.cpp @@ -43,7 +43,7 @@ SharedDIBSurface::InitSurface(uint32_t aWidth, uint32_t aHeight, long stride = long(aWidth * SharedDIB::kBytesPerPixel); unsigned char* data = reinterpret_cast(mSharedDIB.GetBits()); - gfxImageFormat format = aTransparent ? gfxImageFormat::ARGB32 : gfxImageFormat::RGB24; + gfxImageFormat format = aTransparent ? SurfaceFormat::A8R8G8B8_UINT32 : SurfaceFormat::X8R8G8B8_UINT32; gfxImageSurface::InitWithData(data, IntSize(aWidth, aHeight), stride, format); diff --git a/gfx/layers/Compositor.h b/gfx/layers/Compositor.h index 7a5b5c0311..1144e06357 100644 --- a/gfx/layers/Compositor.h +++ b/gfx/layers/Compositor.h @@ -532,8 +532,6 @@ protected: ScreenRotation mScreenRotation; - virtual gfx::IntSize GetWidgetSize() const = 0; - RefPtr mTarget; gfx::IntRect mTargetBounds; diff --git a/gfx/layers/ImageContainer.cpp b/gfx/layers/ImageContainer.cpp index 757e185ea7..3c407cc722 100644 --- a/gfx/layers/ImageContainer.cpp +++ b/gfx/layers/ImageContainer.cpp @@ -59,6 +59,10 @@ ImageFactory::CreatePlanarYCbCrImage(const gfx::IntSize& aScaleHint, BufferRecyc BufferRecycleBin::BufferRecycleBin() : mLock("mozilla.layers.BufferRecycleBin.mLock") + // This member is only valid when the bin is not empty and will be properly + // initialized in RecycleBuffer, but initializing it here avoids static analysis + // noise. + , mRecycledBufferSize(0) { } @@ -389,7 +393,7 @@ ImageContainer::NotifyCompositeInternal(const ImageCompositeNotification& aNotif PlanarYCbCrImage::PlanarYCbCrImage() : Image(nullptr, ImageFormat::PLANAR_YCBCR) - , mOffscreenFormat(gfxImageFormat::Unknown) + , mOffscreenFormat(SurfaceFormat::UNKNOWN) , mBufferSize(0) { } @@ -501,7 +505,7 @@ RecyclingPlanarYCbCrImage::SetData(const Data &aData) gfxImageFormat PlanarYCbCrImage::GetOffscreenFormat() { - return mOffscreenFormat == gfxImageFormat::Unknown ? + return mOffscreenFormat == SurfaceFormat::UNKNOWN ? gfxPlatform::GetPlatform()->GetOffscreenFormat() : mOffscreenFormat; } diff --git a/gfx/layers/ImageContainer.h b/gfx/layers/ImageContainer.h index 6a9ef6f960..28d65230c8 100644 --- a/gfx/layers/ImageContainer.h +++ b/gfx/layers/ImageContainer.h @@ -250,7 +250,6 @@ protected: void* mImplData; int32_t mSerial; ImageFormat mFormat; - bool mSent; static mozilla::Atomic sSerialCounter; }; diff --git a/gfx/layers/ImageDataSerializer.cpp b/gfx/layers/ImageDataSerializer.cpp index bdda546715..7e04acd380 100644 --- a/gfx/layers/ImageDataSerializer.cpp +++ b/gfx/layers/ImageDataSerializer.cpp @@ -4,7 +4,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ImageDataSerializer.h" -#include // for memcpy #include "gfx2DGlue.h" // for SurfaceFormatToImageFormat #include "mozilla/gfx/Point.h" // for IntSize #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index 8e932e8b30..be288f7804 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -1117,7 +1117,8 @@ ContainerLayer::ContainerLayer(LayerManager* aManager, void* aImplData) mSupportsComponentAlphaChildren(false), mMayHaveReadbackChild(false), mChildrenChanged(false), - mEventRegionsOverride(EventRegionsOverride::NoOverride) + mEventRegionsOverride(EventRegionsOverride::NoOverride), + mVRDeviceID(0) { MOZ_COUNT_CTOR(ContainerLayer); mContentFlags = 0; // Clear NO_TEXT, NO_TEXT_OVER_TRANSPARENT @@ -1279,7 +1280,7 @@ ContainerLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs) mInheritedXScale, mInheritedYScale, mPresShellResolution, mScaleToResolution, mEventRegionsOverride, - reinterpret_cast(mHMDInfo.get())); + mVRDeviceID); } bool @@ -2143,8 +2144,8 @@ ContainerLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix) if (mEventRegionsOverride & EventRegionsOverride::ForceEmptyHitRegion) { aStream << " [force-ehr]"; } - if (mHMDInfo) { - aStream << nsPrintfCString(" [hmd=%p]", mHMDInfo.get()).get(); + if (mVRDeviceID) { + aStream << nsPrintfCString(" [hmd=%lu]", mVRDeviceID).get(); } } diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index c43a2d701d..4b6a7805b9 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -693,15 +693,17 @@ private: // Stores state and data for frame intervals and paint times recording. // see LayerManager::StartFrameTimeRecording() at Layers.cpp for more details. FramesTimingRecording() - : mIsPaused(true) - , mNextIndex(0) + : mNextIndex(0) + , mLatestStartIndex(0) + , mCurrentRunStartIndex(0) + , mIsPaused(true) {} - bool mIsPaused; - uint32_t mNextIndex; - TimeStamp mLastFrameTime; nsTArray mIntervals; + TimeStamp mLastFrameTime; + uint32_t mNextIndex; uint32_t mLatestStartIndex; uint32_t mCurrentRunStartIndex; + bool mIsPaused; }; FramesTimingRecording mRecording; @@ -2129,8 +2131,12 @@ public: /** * VR */ - void SetVRHMDInfo(gfx::VRHMDInfo* aHMD) { mHMDInfo = aHMD; } - gfx::VRHMDInfo* GetVRHMDInfo() { return mHMDInfo; } + void SetVRDeviceID(uint32_t aVRDeviceID) { + mVRDeviceID = aVRDeviceID; + } + uint32_t GetVRDeviceID() { + return mVRDeviceID; + } /** * Replace the current effective transform with the given one, @@ -2206,7 +2212,7 @@ protected: // the intermediate surface. bool mChildrenChanged; EventRegionsOverride mEventRegionsOverride; - RefPtr mHMDInfo; + uint32_t mVRDeviceID; }; /** diff --git a/gfx/layers/apz/src/HitTestingTreeNode.cpp b/gfx/layers/apz/src/HitTestingTreeNode.cpp index 5aaec75314..b9a7455f3e 100644 --- a/gfx/layers/apz/src/HitTestingTreeNode.cpp +++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp @@ -23,9 +23,12 @@ HitTestingTreeNode::HitTestingTreeNode(AsyncPanZoomController* aApzc, : mApzc(aApzc) , mIsPrimaryApzcHolder(aIsPrimaryHolder) , mLayersId(aLayersId) + , mScrollViewId(FrameMetrics::NULL_SCROLL_ID) + , mScrollDir(Layer::NONE) + , mScrollSize(0) , mOverride(EventRegionsOverride::NoOverride) { - if (mIsPrimaryApzcHolder) { +if (mIsPrimaryApzcHolder) { MOZ_ASSERT(mApzc); } MOZ_ASSERT(!mApzc || mApzc->GetLayersId() == mLayersId); diff --git a/gfx/layers/basic/BasicCompositor.cpp b/gfx/layers/basic/BasicCompositor.cpp index f2fc53ac1f..a3a12c3e92 100644 --- a/gfx/layers/basic/BasicCompositor.cpp +++ b/gfx/layers/basic/BasicCompositor.cpp @@ -11,6 +11,7 @@ #include "gfx2DGlue.h" #include "mozilla/gfx/2D.h" #include "mozilla/gfx/Helpers.h" +#include "mozilla/gfx/Tools.h" #include "gfxUtils.h" #include "YCbCrUtils.h" #include @@ -351,7 +352,6 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect, // |dest| is a temporary surface. RefPtr dest = buffer; - buffer->PushClipRect(aClipRect); AutoRestoreTransform autoRestoreTransform(dest); Matrix newTransform; @@ -374,6 +374,10 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect, transformBounds = aTransform.TransformAndClipBounds(aRect, Rect(offset.x, offset.y, buffer->GetSize().width, buffer->GetSize().height)); transformBounds.RoundOut(); + if (transformBounds.IsEmpty()) { + return; + } + // Propagate the coordinate offset to our 2D draw target. newTransform = Matrix::Translation(transformBounds.x, transformBounds.y); @@ -382,6 +386,8 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect, new3DTransform = Matrix4x4::Translation(aRect.x, aRect.y, 0) * aTransform; } + buffer->PushClipRect(aClipRect); + newTransform.PostTranslate(-offset.x, -offset.y); buffer->SetTransform(newTransform); @@ -406,8 +412,17 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect, EffectSolidColor* effectSolidColor = static_cast(aEffectChain.mPrimaryEffect.get()); + bool unboundedOp = !IsOperatorBoundByMask(blendMode); + if (unboundedOp) { + dest->PushClipRect(aRect); + } + FillRectWithMask(dest, aRect, effectSolidColor->mColor, DrawOptions(aOpacity, blendMode), sourceMask, &maskTransform); + + if (unboundedOp) { + dest->PopClip(); + } break; } case EffectTypes::RGB: { @@ -505,11 +520,10 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion, gfx::Rect *aClipRectOut /* = nullptr */, gfx::Rect *aRenderBoundsOut /* = nullptr */) { - mWidgetSize = mWidget->GetClientSize().ToUnknownSize(); - IntRect intRect = gfx::IntRect(IntPoint(), mWidgetSize); + LayoutDeviceIntRect intRect(LayoutDeviceIntPoint(), mWidget->GetClientSize()); Rect rect = Rect(0, 0, intRect.width, intRect.height); - nsIntRegion invalidRegionSafe; + LayoutDeviceIntRegion invalidRegionSafe; if (mDidExternalComposition) { // We do not know rendered region during external composition, just redraw // whole widget. @@ -517,35 +531,42 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion, mDidExternalComposition = false; } else { // Sometimes the invalid region is larger than we want to draw. - invalidRegionSafe.And(aInvalidRegion, intRect); + invalidRegionSafe.And( + LayoutDeviceIntRegion::FromUnknownRegion(aInvalidRegion), intRect); } - IntRect invalidRect = invalidRegionSafe.GetBounds(); - mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height); mInvalidRegion = invalidRegionSafe; + mInvalidRect = mInvalidRegion.GetBounds(); if (aRenderBoundsOut) { *aRenderBoundsOut = Rect(); } - if (mInvalidRect.width <= 0 || mInvalidRect.height <= 0) { - return; - } - if (mTarget) { // If we have a copy target, then we don't have a widget-provided mDrawTarget (currently). Use a dummy // placeholder so that CreateRenderTarget() works. mDrawTarget = gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget(); } else { + // StartRemoteDrawingInRegion can mutate mInvalidRegion. mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion); + if (!mDrawTarget) { + return; + } + mInvalidRect = mInvalidRegion.GetBounds(); + if (mInvalidRect.IsEmpty()) { + mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion); + return; + } } - if (!mDrawTarget) { + + if (!mDrawTarget || mInvalidRect.IsEmpty()) { return; } // Setup an intermediate render target to buffer all compositing. We will // copy this into mDrawTarget (the widget), and/or mTarget in EndFrame() - RefPtr target = CreateRenderTarget(mInvalidRect, INIT_MODE_CLEAR); + RefPtr target = + CreateRenderTarget(mInvalidRect.ToUnknownRect(), INIT_MODE_CLEAR); if (!target) { if (!mTarget) { mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion); @@ -556,10 +577,11 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion, // We only allocate a surface sized to the invalidated region, so we need to // translate future coordinates. - mRenderTarget->mDrawTarget->SetTransform(Matrix::Translation(-invalidRect.x, - -invalidRect.y)); + mRenderTarget->mDrawTarget->SetTransform(Matrix::Translation(-mInvalidRect.x, + -mInvalidRect.y)); - gfxUtils::ClipToRegion(mRenderTarget->mDrawTarget, invalidRegionSafe); + gfxUtils::ClipToRegion(mRenderTarget->mDrawTarget, + mInvalidRegion.ToUnknownRegion()); if (aRenderBoundsOut) { *aRenderBoundsOut = rect; @@ -586,8 +608,9 @@ BasicCompositor::EndFrame() float g = float(rand()) / RAND_MAX; float b = float(rand()) / RAND_MAX; // We're still clipped to mInvalidRegion, so just fill the bounds. - mRenderTarget->mDrawTarget->FillRect(IntRectToRect(mInvalidRegion.GetBounds()), - ColorPattern(Color(r, g, b, 0.2f))); + mRenderTarget->mDrawTarget->FillRect( + IntRectToRect(mInvalidRegion.GetBounds()).ToUnknownRect(), + ColorPattern(Color(r, g, b, 0.2f))); } // Pop aInvalidregion @@ -603,8 +626,8 @@ BasicCompositor::EndFrame() // The source DrawTarget is clipped to the invalidation region, so we have // to copy the individual rectangles in the region or else we'll draw blank // pixels. - nsIntRegionRectIterator iter(mInvalidRegion); - for (const IntRect *r = iter.Next(); r; r = iter.Next()) { + LayoutDeviceIntRegion::RectIterator iter(mInvalidRegion); + for (const LayoutDeviceIntRect *r = iter.Next(); r; r = iter.Next()) { dest->CopySurface(source, IntRect(r->x - mInvalidRect.x, r->y - mInvalidRect.y, r->width, r->height), IntPoint(r->x - offset.x, r->y - offset.y)); diff --git a/gfx/layers/basic/BasicCompositor.h b/gfx/layers/basic/BasicCompositor.h index ca06d097d6..05e64e2fcb 100644 --- a/gfx/layers/basic/BasicCompositor.h +++ b/gfx/layers/basic/BasicCompositor.h @@ -116,19 +116,16 @@ public: private: - virtual gfx::IntSize GetWidgetSize() const override { return mWidgetSize; } - // Widget associated with this compositor nsIWidget *mWidget; - gfx::IntSize mWidgetSize; // The final destination surface RefPtr mDrawTarget; // The current render target for drawing RefPtr mRenderTarget; - gfx::IntRect mInvalidRect; - nsIntRegion mInvalidRegion; + LayoutDeviceIntRect mInvalidRect; + LayoutDeviceIntRegion mInvalidRegion; bool mDidExternalComposition; uint32_t mMaxTextureSize; diff --git a/gfx/layers/basic/BasicLayerManager.cpp b/gfx/layers/basic/BasicLayerManager.cpp index 94007abd49..76fc883447 100644 --- a/gfx/layers/basic/BasicLayerManager.cpp +++ b/gfx/layers/basic/BasicLayerManager.cpp @@ -775,7 +775,7 @@ Transform(const gfxImageSurface* aDest, gfxPoint aDestOffset) { IntSize destSize = aDest->GetSize(); - pixman_image_t* dest = pixman_image_create_bits(aDest->Format() == gfxImageFormat::ARGB32 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8, + pixman_image_t* dest = pixman_image_create_bits(aDest->Format() == SurfaceFormat::A8R8G8B8_UINT32 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8, destSize.width, destSize.height, (uint32_t*)aDest->Data(), @@ -851,7 +851,7 @@ Transform3D(RefPtr aSource, RefPtr dest = aDest->CurrentSurface(); RefPtr destImage = new gfxImageSurface(IntSize(aDestRect.width, aDestRect.height), - gfxImageFormat::ARGB32); + SurfaceFormat::A8R8G8B8_UINT32); gfxPoint offset = aDestRect.TopLeft(); // Include a translation to the correct origin. diff --git a/gfx/layers/client/ClientLayerManager.cpp b/gfx/layers/client/ClientLayerManager.cpp index bb56aed00b..7549440532 100644 --- a/gfx/layers/client/ClientLayerManager.cpp +++ b/gfx/layers/client/ClientLayerManager.cpp @@ -662,7 +662,7 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite) // PLayer::Send__delete__() and DeallocShmem() mKeepAlive.Clear(); - TabChild* window = mWidget->GetOwningTabChild(); + TabChild* window = mWidget ? mWidget->GetOwningTabChild() : nullptr; if (window) { TimeStamp end = TimeStamp::Now(); window->DidRequestComposite(start, end); diff --git a/gfx/layers/client/SingleTiledContentClient.cpp b/gfx/layers/client/SingleTiledContentClient.cpp index 51f20ff007..1cf1fc54a8 100644 --- a/gfx/layers/client/SingleTiledContentClient.cpp +++ b/gfx/layers/client/SingleTiledContentClient.cpp @@ -58,6 +58,7 @@ ClientSingleTiledLayerBuffer::ClientSingleTiledLayerBuffer(ClientTiledPaintedLay ClientLayerManager* aManager) : ClientTiledLayerBuffer(aPaintedLayer, aCompositableClient) , mManager(aManager) + , mFormat(gfx::SurfaceFormat::UNKNOWN) { } @@ -108,6 +109,7 @@ ClientSingleTiledLayerBuffer::GetSurfaceDescriptorTiles() already_AddRefed ClientSingleTiledLayerBuffer::GetTextureClient() { + MOZ_ASSERT(mFormat != gfx::SurfaceFormat::UNKNOWN); return mCompositableClient->CreateTextureClientForDrawing( gfx::ImageFormatToSurfaceFormat(mFormat), mSize, BackendSelector::Content, TextureFlags::DISALLOW_BIGIMAGE | TextureFlags::IMMEDIATE_UPLOAD); diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index 3366647acf..ce81623faa 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -293,6 +293,8 @@ ClientMultiTiledLayerBuffer::ClientMultiTiledLayerBuffer(ClientTiledPaintedLayer SharedFrameMetricsHelper* aHelper) : ClientTiledLayerBuffer(aPaintedLayer, aCompositableClient) , mManager(aManager) + , mCallback(nullptr) + , mCallbackData(nullptr) , mSharedFrameMetricsHelper(aHelper) { } diff --git a/gfx/layers/composite/ContainerLayerComposite.cpp b/gfx/layers/composite/ContainerLayerComposite.cpp index 9f23b3ca79..c51aeb4472 100755 --- a/gfx/layers/composite/ContainerLayerComposite.cpp +++ b/gfx/layers/composite/ContainerLayerComposite.cpp @@ -32,6 +32,7 @@ #include "nsTArray.h" // for nsAutoTArray #include "TextRenderer.h" // for TextRenderer #include +#include "VRManager.h" // for VRManager #include "GeckoProfiler.h" // for GeckoProfiler #ifdef MOZ_ENABLE_PROFILER_SPS #include "ProfilerMarkers.h" // for ProfilerMarkers @@ -138,7 +139,7 @@ template void ContainerRenderVR(ContainerT* aContainer, LayerManagerComposite* aManager, const gfx::IntRect& aClipRect, - gfx::VRHMDInfo* aHMD) + RefPtr aHMD) { RefPtr surface; @@ -149,7 +150,7 @@ ContainerRenderVR(ContainerT* aContainer, float opacity = aContainer->GetEffectiveOpacity(); // The size of each individual eye surface - gfx::IntSize eyeResolution = aHMD->SuggestedEyeResolution(); + gfx::IntSize eyeResolution = aHMD->GetDeviceInfo().SuggestedEyeResolution(); gfx::IntRect eyeRect[2]; eyeRect[0] = gfx::IntRect(0, 0, eyeResolution.width, eyeResolution.height); eyeRect[1] = gfx::IntRect(eyeResolution.width, 0, eyeResolution.width, eyeResolution.height); @@ -340,7 +341,7 @@ ContainerPrepare(ContainerT* aContainer, aContainer->mPrepared = MakeUnique(); aContainer->mPrepared->mNeedsSurfaceCopy = false; - gfx::VRHMDInfo *hmdInfo = aContainer->GetVRHMDInfo(); + RefPtr hmdInfo = gfx::VRManager::Get()->GetDevice(aContainer->GetVRDeviceID()); if (hmdInfo && hmdInfo->GetConfiguration().IsValid()) { // we're not going to do anything here; instead, we'll do it all in ContainerRender. // XXX fix this; we can win with the same optimizations. Specifically, we @@ -687,7 +688,7 @@ ContainerRender(ContainerT* aContainer, { MOZ_ASSERT(aContainer->mPrepared); - gfx::VRHMDInfo *hmdInfo = aContainer->GetVRHMDInfo(); + RefPtr hmdInfo = gfx::VRManager::Get()->GetDevice(aContainer->GetVRDeviceID()); if (hmdInfo && hmdInfo->GetConfiguration().IsValid()) { ContainerRenderVR(aContainer, aManager, aClipRect, hmdInfo); aContainer->mPrepared = nullptr; diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index 34c99a275c..e9693154c9 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -676,7 +676,7 @@ CompositorD3D11::DrawVRDistortion(const gfx::Rect& aRect, TextureSourceD3D11* source = vrEffect->mTexture->AsSourceD3D11(); VRHMDInfo* hmdInfo = vrEffect->mHMD; - VRHMDType hmdType = hmdInfo->GetType(); + VRHMDType hmdType = hmdInfo->GetDeviceInfo().GetType(); if (!mAttachments->mVRDistortionVS[hmdType] || !mAttachments->mVRDistortionPS[hmdType]) @@ -1037,7 +1037,7 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion, return; } - IntSize oldSize = mSize; + LayoutDeviceIntSize oldSize = mSize; // Failed to create a render target or the view. if (!UpdateRenderTarget() || !mDefaultRT || !mDefaultRT->mRTView || @@ -1053,7 +1053,7 @@ CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion, UINT offset = 0; mContext->IASetVertexBuffers(0, 1, &buffer, &size, &offset); - IntRect intRect = IntRect(IntPoint(0, 0), mSize); + IntRect intRect = IntRect(IntPoint(0, 0), mSize.ToUnknownSize()); // Sometimes the invalid region is larger than we want to draw. nsIntRegion invalidRegionSafe; @@ -1108,7 +1108,7 @@ CompositorD3D11::EndFrame() return; } - IntSize oldSize = mSize; + LayoutDeviceIntSize oldSize = mSize; EnsureSize(); if (mSize.width <= 0 || mSize.height <= 0) { return; @@ -1206,7 +1206,7 @@ CompositorD3D11::EnsureSize() LayoutDeviceIntRect rect; mWidget->GetClientBounds(rect); - mSize = rect.Size().ToUnknownSize(); + mSize = rect.Size(); } bool @@ -1313,7 +1313,7 @@ CompositorD3D11::UpdateRenderTarget() } mDefaultRT = new CompositingRenderTargetD3D11(backBuf, IntPoint(0, 0)); - mDefaultRT->SetSize(mSize); + mDefaultRT->SetSize(mSize.ToUnknownSize()); return true; } diff --git a/gfx/layers/d3d11/CompositorD3D11.h b/gfx/layers/d3d11/CompositorD3D11.h index 3881c7ebe9..a328f47464 100644 --- a/gfx/layers/d3d11/CompositorD3D11.h +++ b/gfx/layers/d3d11/CompositorD3D11.h @@ -171,8 +171,6 @@ private: void SetPSForEffect(Effect *aEffect, MaskType aMaskType, gfx::SurfaceFormat aFormat); void PaintToTarget(); - virtual gfx::IntSize GetWidgetSize() const override { return mSize; } - RefPtr mContext; RefPtr mDevice; RefPtr mSwapChain; @@ -183,7 +181,7 @@ private: nsIWidget* mWidget; - gfx::IntSize mSize; + LayoutDeviceIntSize mSize; HWND mHwnd; diff --git a/gfx/layers/d3d9/CompositorD3D9.cpp b/gfx/layers/d3d9/CompositorD3D9.cpp index 824923ad15..eee154a9f2 100644 --- a/gfx/layers/d3d9/CompositorD3D9.cpp +++ b/gfx/layers/d3d9/CompositorD3D9.cpp @@ -663,7 +663,7 @@ CompositorD3D9::EndFrame() if (mDeviceManager) { device()->EndScene(); - IntSize oldSize = mSize; + LayoutDeviceIntSize oldSize = mSize; EnsureSize(); if (oldSize == mSize) { if (mTarget) { @@ -705,7 +705,7 @@ CompositorD3D9::EnsureSize() LayoutDeviceIntRect rect; mWidget->GetClientBounds(rect); - mSize = rect.Size().ToUnknownSize(); + mSize = rect.Size(); } void diff --git a/gfx/layers/d3d9/CompositorD3D9.h b/gfx/layers/d3d9/CompositorD3D9.h index c050b15447..c23acdeae3 100644 --- a/gfx/layers/d3d9/CompositorD3D9.h +++ b/gfx/layers/d3d9/CompositorD3D9.h @@ -152,11 +152,6 @@ private: void ReportFailure(const nsACString &aMsg, HRESULT aCode); - virtual gfx::IntSize GetWidgetSize() const override - { - return mSize; - } - /* Device manager instance for this compositor */ RefPtr mDeviceManager; @@ -169,7 +164,7 @@ private: RefPtr mDefaultRT; RefPtr mCurrentRT; - gfx::IntSize mSize; + LayoutDeviceIntSize mSize; uint32_t mDeviceResetCount; uint32_t mFailedResetAttempts; diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 484ba4e48e..f46bf292b7 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -28,6 +28,7 @@ #include "mozilla/gfx/2D.h" // for DrawTarget #include "mozilla/gfx/Point.h" // for IntSize #include "mozilla/gfx/Rect.h" // for IntSize +#include "VRManager.h" // for VRManager #include "mozilla/ipc/Transport.h" // for Transport #include "mozilla/layers/APZCTreeManager.h" // for APZCTreeManager #include "mozilla/layers/APZThreadUtils.h" // for APZCTreeManager @@ -79,6 +80,12 @@ #include "LayerScope.h" namespace mozilla { + +namespace gfx { +// See VRManagerChild.cpp +void ReleaseVRManagerParentSingleton(); +} // namespace gfx + namespace layers { using namespace mozilla::ipc; @@ -426,6 +433,7 @@ CompositorVsyncScheduler::Composite(TimeStamp aVsyncTimestamp) } DispatchTouchEvents(aVsyncTimestamp); + DispatchVREvents(aVsyncTimestamp); if (mNeedsComposite || mAsapScheduling) { mNeedsComposite = 0; @@ -497,6 +505,15 @@ CompositorVsyncScheduler::DispatchTouchEvents(TimeStamp aVsyncTimestamp) #endif } +void +CompositorVsyncScheduler::DispatchVREvents(TimeStamp aVsyncTimestamp) +{ + MOZ_ASSERT(CompositorParent::IsInCompositorThread()); + + VRManager* vm = VRManager::Get(); + vm->NotifyVsync(aVsyncTimestamp); +} + void CompositorParent::StartUp() { MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!"); @@ -511,6 +528,7 @@ void CompositorParent::ShutDown() MOZ_ASSERT(sCompositorThreadHolder, "The compositor thread has already been shut down!"); ReleaseImageBridgeParentSingleton(); + ReleaseVRManagerParentSingleton(); MediaSystemResourceService::Shutdown(); sCompositorThreadHolder = nullptr; diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index 4264ac3c01..a1ba2ca602 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -134,6 +134,7 @@ private: void ObserveVsync(); void UnobserveVsync(); void DispatchTouchEvents(TimeStamp aVsyncTimestamp); + void DispatchVREvents(TimeStamp aVsyncTimestamp); void CancelCurrentSetNeedsCompositeTask(); class Observer final : public VsyncObserver @@ -295,7 +296,8 @@ public: /** * Returns the compositor thread's message loop. * - * This message loop is used by CompositorParent and ImageBridgeParent. + * This message loop is used by CompositorParent, ImageBridgeParent, + * and VRManagerParent */ static MessageLoop* CompositorLoop(); diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index 5342a1f6e9..6339e33651 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -49,10 +49,6 @@ typedef std::vector EditReplyVector; using mozilla::layout::RenderFrameParent; namespace mozilla { -namespace gfx { -class VRHMDInfo; -} // namespace gfx - namespace layers { class PGrallocBufferParent; @@ -402,12 +398,8 @@ LayerTransactionParent::RecvUpdate(InfallibleTArray&& cset, attrs.presShellResolution()); containerLayer->SetEventRegionsOverride(attrs.eventRegionsOverride()); - if (attrs.hmdInfo()) { - if (!IsSameProcess()) { - NS_WARNING("VR layers currently not supported with cross-process compositing"); - return false; - } - containerLayer->SetVRHMDInfo(reinterpret_cast(attrs.hmdInfo())); + if (attrs.hmdDeviceID()) { + containerLayer->SetVRDeviceID(attrs.hmdDeviceID()); } break; diff --git a/gfx/layers/ipc/LayersMessages.ipdlh b/gfx/layers/ipc/LayersMessages.ipdlh index 30a249535c..f647c46f8e 100644 --- a/gfx/layers/ipc/LayersMessages.ipdlh +++ b/gfx/layers/ipc/LayersMessages.ipdlh @@ -248,10 +248,7 @@ struct ContainerLayerAttributes { float presShellResolution; bool scaleToResolution; EventRegionsOverride eventRegionsOverride; - // This is a bare pointer; LayerTransactionParent::RecvUpdate prevents this - // from being used when !IsSameProcess(), but we should make this truly - // cross process at some point by passing the HMDConfig - uint64_t hmdInfo; + uint32_t hmdDeviceID; }; struct ColorLayerAttributes { LayerColor color; IntRect bounds; }; struct CanvasLayerAttributes { Filter filter; IntRect bounds; }; diff --git a/gfx/layers/ipc/SharedRGBImage.cpp b/gfx/layers/ipc/SharedRGBImage.cpp index e16210d8c7..0e084951de 100644 --- a/gfx/layers/ipc/SharedRGBImage.cpp +++ b/gfx/layers/ipc/SharedRGBImage.cpp @@ -31,9 +31,9 @@ CreateSharedRGBImage(ImageContainer *aImageContainer, gfx::IntSize aSize, gfxImageFormat aImageFormat) { - NS_ASSERTION(aImageFormat == gfxImageFormat::ARGB32 || - aImageFormat == gfxImageFormat::RGB24 || - aImageFormat == gfxImageFormat::RGB16_565, + NS_ASSERTION(aImageFormat == gfx::SurfaceFormat::A8R8G8B8_UINT32 || + aImageFormat == gfx::SurfaceFormat::X8R8G8B8_UINT32 || + aImageFormat == gfx::SurfaceFormat::R5G6B5_UINT16, "RGB formats supported only"); if (!aImageContainer) { diff --git a/gfx/layers/opengl/CompositingRenderTargetOGL.cpp b/gfx/layers/opengl/CompositingRenderTargetOGL.cpp index ef93b35fad..1d9ad66c1b 100644 --- a/gfx/layers/opengl/CompositingRenderTargetOGL.cpp +++ b/gfx/layers/opengl/CompositingRenderTargetOGL.cpp @@ -51,7 +51,7 @@ CompositingRenderTargetOGL::BindRenderTarget() // The main framebuffer (0) of non-offscreen contexts // might be backed by a EGLSurface that needs to be renewed. if (mFBO == 0 && !mGL->IsOffscreen()) { - mGL->RenewSurface(); + mGL->RenewSurface(mCompositor->GetWidget()); result = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); } if (result != LOCAL_GL_FRAMEBUFFER_COMPLETE) { diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index 55b06a6abe..71bfb1d03d 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -107,7 +107,7 @@ CompositorOGL::CreateContext() #ifdef XP_WIN if (gfxEnv::LayersPreferEGL()) { printf_stderr("Trying GL layers...\n"); - context = gl::GLContextProviderEGL::CreateForWindow(mWidget); + context = gl::GLContextProviderEGL::CreateForWindow(mWidget, false); } #endif @@ -115,14 +115,15 @@ CompositorOGL::CreateContext() if (!context && gfxEnv::LayersPreferOffscreen()) { SurfaceCaps caps = SurfaceCaps::ForRGB(); caps.preserve = false; - caps.bpp16 = gfxPlatform::GetPlatform()->GetOffscreenFormat() == gfxImageFormat::RGB16_565; + caps.bpp16 = gfxPlatform::GetPlatform()->GetOffscreenFormat() == SurfaceFormat::R5G6B5_UINT16; context = GLContextProvider::CreateOffscreen(mSurfaceSize, caps, CreateContextFlags::REQUIRE_COMPAT_PROFILE); } if (!context) { - context = gl::GLContextProvider::CreateForWindow(mWidget); + context = gl::GLContextProvider::CreateForWindow(mWidget, + gfxPlatform::GetPlatform()->RequiresAcceleratedGLContextForCompositorOGL()); } if (!context) { @@ -661,8 +662,9 @@ CompositorOGL::BeginFrame(const nsIntRegion& aInvalidRegion, mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST); // Prefer the native windowing system's provided window size for the viewport. - IntSize viewportSize = mGLContext->GetTargetSize().valueOr(mWidgetSize); - if (viewportSize != mWidgetSize) { + IntSize viewportSize = + mGLContext->GetTargetSize().valueOr(mWidgetSize.ToUnknownSize()); + if (viewportSize != mWidgetSize.ToUnknownSize()) { mGLContext->fScissor(0, 0, viewportSize.width, viewportSize.height); } @@ -1537,7 +1539,7 @@ CompositorOGL::Resume() return false; // RenewSurface internally calls MakeCurrent. - return gl()->RenewSurface(); + return gl()->RenewSurface(GetWidget()); #endif return true; } diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index 5feb9f55a9..3707c65731 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -305,11 +305,6 @@ public: } private: - virtual gfx::IntSize GetWidgetSize() const override - { - return mWidgetSize; - } - bool InitializeVR(); void DestroyVR(GLContext *gl); @@ -323,7 +318,7 @@ private: /** Widget associated with this compositor */ nsIWidget *mWidget; - gfx::IntSize mWidgetSize; + LayoutDeviceIntSize mWidgetSize; RefPtr mGLContext; UniquePtr mBlitTextureImageHelper; gfx::Matrix4x4 mProjMatrix; diff --git a/gfx/layers/opengl/TextureHostOGL.cpp b/gfx/layers/opengl/TextureHostOGL.cpp index be4a729865..2dee2b0f74 100644 --- a/gfx/layers/opengl/TextureHostOGL.cpp +++ b/gfx/layers/opengl/TextureHostOGL.cpp @@ -166,8 +166,7 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface, mTexImage = CreateBasicTextureImage(gl, size, gfx::ContentForFormat(aSurface->GetFormat()), LOCAL_GL_CLAMP_TO_EDGE, - FlagsToGLFlags(mFlags), - SurfaceFormatToImageFormat(aSurface->GetFormat())); + FlagsToGLFlags(mFlags)); } else { // XXX - clarify which size we want to use. IncrementalContentHost will // require the size of the destination surface to be different from diff --git a/gfx/tests/gtest/TestTextures.cpp b/gfx/tests/gtest/TestTextures.cpp index c2cde0c452..61a7def3bc 100644 --- a/gfx/tests/gtest/TestTextures.cpp +++ b/gfx/tests/gtest/TestTextures.cpp @@ -213,9 +213,9 @@ void TestTextureClientYCbCr(TextureClient* client, PlanarYCbCrData& ycbcrData) { TEST(Layers, TextureSerialization) { // the test is run on all the following image formats gfxImageFormat formats[3] = { - gfxImageFormat::ARGB32, - gfxImageFormat::RGB24, - gfxImageFormat::A8, + SurfaceFormat::A8R8G8B8_UINT32, + SurfaceFormat::X8R8G8B8_UINT32, + SurfaceFormat::A8, }; for (int f = 0; f < 3; ++f) { @@ -240,9 +240,9 @@ TEST(Layers, TextureSerialization) { } TEST(Layers, TextureYCbCrSerialization) { - RefPtr ySurface = new gfxImageSurface(IntSize(400,300), gfxImageFormat::A8); - RefPtr cbSurface = new gfxImageSurface(IntSize(200,150), gfxImageFormat::A8); - RefPtr crSurface = new gfxImageSurface(IntSize(200,150), gfxImageFormat::A8); + RefPtr ySurface = new gfxImageSurface(IntSize(400,300), SurfaceFormat::A8); + RefPtr cbSurface = new gfxImageSurface(IntSize(200,150), SurfaceFormat::A8); + RefPtr crSurface = new gfxImageSurface(IntSize(200,150), SurfaceFormat::A8); SetupSurface(ySurface.get()); SetupSurface(cbSurface.get()); SetupSurface(crSurface.get()); diff --git a/gfx/tests/gtest/gfxSurfaceRefCountTest.cpp b/gfx/tests/gtest/gfxSurfaceRefCountTest.cpp index d874584910..0bbd2361d1 100644 --- a/gfx/tests/gtest/gfxSurfaceRefCountTest.cpp +++ b/gfx/tests/gtest/gfxSurfaceRefCountTest.cpp @@ -44,7 +44,7 @@ TestNewSurface () { int failures = 0; int destroyed = 0; - RefPtr s = new gfxImageSurface (mozilla::gfx::IntSize(10, 10), gfxImageFormat::ARGB32); + RefPtr s = new gfxImageSurface (mozilla::gfx::IntSize(10, 10), SurfaceFormat::A8R8G8B8_UINT32); cairo_surface_t *cs = s->CairoSurface(); cairo_surface_set_user_data (cs, &destruction_key, &destroyed, SurfaceDestroyNotifier); diff --git a/gfx/thebes/gfx2DGlue.h b/gfx/thebes/gfx2DGlue.h index d4f8108dc2..fabdb7c38d 100644 --- a/gfx/thebes/gfx2DGlue.h +++ b/gfx/thebes/gfx2DGlue.h @@ -85,31 +85,31 @@ inline gfxImageFormat SurfaceFormatToImageFormat(SurfaceFormat aFormat) { switch (aFormat) { case SurfaceFormat::B8G8R8A8: - return gfxImageFormat::ARGB32; + return SurfaceFormat::A8R8G8B8_UINT32; case SurfaceFormat::B8G8R8X8: - return gfxImageFormat::RGB24; + return SurfaceFormat::X8R8G8B8_UINT32; case SurfaceFormat::R5G6B5_UINT16: - return gfxImageFormat::RGB16_565; + return SurfaceFormat::R5G6B5_UINT16; case SurfaceFormat::A8: - return gfxImageFormat::A8; + return SurfaceFormat::A8; default: - return gfxImageFormat::Unknown; + return SurfaceFormat::UNKNOWN; } } inline SurfaceFormat ImageFormatToSurfaceFormat(gfxImageFormat aFormat) { switch (aFormat) { - case gfxImageFormat::ARGB32: + case SurfaceFormat::A8R8G8B8_UINT32: return SurfaceFormat::B8G8R8A8; - case gfxImageFormat::RGB24: + case SurfaceFormat::X8R8G8B8_UINT32: return SurfaceFormat::B8G8R8X8; - case gfxImageFormat::RGB16_565: + case SurfaceFormat::R5G6B5_UINT16: return SurfaceFormat::R5G6B5_UINT16; - case gfxImageFormat::A8: + case SurfaceFormat::A8: return SurfaceFormat::A8; default: - case gfxImageFormat::Unknown: + case SurfaceFormat::UNKNOWN: return SurfaceFormat::B8G8R8A8; } } diff --git a/gfx/thebes/gfxASurface.cpp b/gfx/thebes/gfxASurface.cpp index a4b7e8d93d..c227e7944b 100644 --- a/gfx/thebes/gfxASurface.cpp +++ b/gfx/thebes/gfxASurface.cpp @@ -343,7 +343,7 @@ already_AddRefed gfxASurface::GetAsReadableARGB32ImageSurface() { RefPtr imgSurface = GetAsImageSurface(); - if (!imgSurface || imgSurface->Format() != gfxImageFormat::ARGB32) { + if (!imgSurface || imgSurface->Format() != SurfaceFormat::A8R8G8B8_UINT32) { imgSurface = CopyToARGB32ImageSurface(); } return imgSurface.forget(); @@ -358,7 +358,7 @@ gfxASurface::CopyToARGB32ImageSurface() const IntSize size = GetSize(); RefPtr imgSurface = - new gfxImageSurface(size, gfxImageFormat::ARGB32); + new gfxImageSurface(size, SurfaceFormat::A8R8G8B8_UINT32); RefPtr dt = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(imgSurface, IntSize(size.width, size.height)); RefPtr source = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, this); @@ -424,7 +424,7 @@ gfxASurface::CheckSurfaceSize(const IntSize& sz, int32_t limit) int32_t gfxASurface::FormatStrideForWidth(gfxImageFormat format, int32_t width) { - cairo_format_t cformat = gfxImageFormatToCairoFormat(format); + cairo_format_t cformat = GfxFormatToCairoFormat(format); return cairo_format_stride_for_width(cformat, (int)width); } @@ -462,15 +462,15 @@ gfxContentType gfxASurface::ContentFromFormat(gfxImageFormat format) { switch (format) { - case gfxImageFormat::ARGB32: + case SurfaceFormat::A8R8G8B8_UINT32: return gfxContentType::COLOR_ALPHA; - case gfxImageFormat::RGB24: - case gfxImageFormat::RGB16_565: + case SurfaceFormat::X8R8G8B8_UINT32: + case SurfaceFormat::R5G6B5_UINT16: return gfxContentType::COLOR; - case gfxImageFormat::A8: + case SurfaceFormat::A8: return gfxContentType::ALPHA; - case gfxImageFormat::Unknown: + case SurfaceFormat::UNKNOWN: default: return gfxContentType::COLOR; } @@ -503,12 +503,12 @@ int32_t gfxASurface::BytePerPixelFromFormat(gfxImageFormat format) { switch (format) { - case gfxImageFormat::ARGB32: - case gfxImageFormat::RGB24: + case SurfaceFormat::A8R8G8B8_UINT32: + case SurfaceFormat::X8R8G8B8_UINT32: return 4; - case gfxImageFormat::RGB16_565: + case SurfaceFormat::R5G6B5_UINT16: return 2; - case gfxImageFormat::A8: + case SurfaceFormat::A8: return 1; default: NS_WARNING("Unknown byte per pixel value for Image format"); @@ -666,15 +666,15 @@ gfxASurface::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const gfxASurface::BytesPerPixel(gfxImageFormat aImageFormat) { switch (aImageFormat) { - case gfxImageFormat::ARGB32: + case SurfaceFormat::A8R8G8B8_UINT32: return 4; - case gfxImageFormat::RGB24: + case SurfaceFormat::X8R8G8B8_UINT32: return 4; - case gfxImageFormat::RGB16_565: + case SurfaceFormat::R5G6B5_UINT16: return 2; - case gfxImageFormat::A8: + case SurfaceFormat::A8: return 1; - case gfxImageFormat::Unknown: + case SurfaceFormat::UNKNOWN: default: NS_NOTREACHED("Not really sure what you want me to say here"); return 0; diff --git a/gfx/thebes/gfxAlphaRecovery.cpp b/gfx/thebes/gfxAlphaRecovery.cpp index 9f2e423004..810fbeffa6 100644 --- a/gfx/thebes/gfxAlphaRecovery.cpp +++ b/gfx/thebes/gfxAlphaRecovery.cpp @@ -17,10 +17,10 @@ gfxAlphaRecovery::RecoverAlpha(gfxImageSurface* blackSurf, mozilla::gfx::IntSize size = blackSurf->GetSize(); if (size != whiteSurf->GetSize() || - (blackSurf->Format() != gfxImageFormat::ARGB32 && - blackSurf->Format() != gfxImageFormat::RGB24) || - (whiteSurf->Format() != gfxImageFormat::ARGB32 && - whiteSurf->Format() != gfxImageFormat::RGB24)) + (blackSurf->Format() != mozilla::gfx::SurfaceFormat::A8R8G8B8_UINT32 && + blackSurf->Format() != mozilla::gfx::SurfaceFormat::X8R8G8B8_UINT32) || + (whiteSurf->Format() != mozilla::gfx::SurfaceFormat::A8R8G8B8_UINT32 && + whiteSurf->Format() != mozilla::gfx::SurfaceFormat::X8R8G8B8_UINT32)) return false; #ifdef MOZILLA_MAY_SUPPORT_SSE2 diff --git a/gfx/thebes/gfxAlphaRecoverySSE2.cpp b/gfx/thebes/gfxAlphaRecoverySSE2.cpp index 5334bafe59..2c8987cbe8 100644 --- a/gfx/thebes/gfxAlphaRecoverySSE2.cpp +++ b/gfx/thebes/gfxAlphaRecoverySSE2.cpp @@ -33,10 +33,10 @@ gfxAlphaRecovery::RecoverAlphaSSE2(gfxImageSurface* blackSurf, mozilla::gfx::IntSize size = blackSurf->GetSize(); if (size != whiteSurf->GetSize() || - (blackSurf->Format() != gfxImageFormat::ARGB32 && - blackSurf->Format() != gfxImageFormat::RGB24) || - (whiteSurf->Format() != gfxImageFormat::ARGB32 && - whiteSurf->Format() != gfxImageFormat::RGB24)) + (blackSurf->Format() != mozilla::gfx::SurfaceFormat::A8R8G8B8_UINT32 && + blackSurf->Format() != mozilla::gfx::SurfaceFormat::X8R8G8B8_UINT32) || + (whiteSurf->Format() != mozilla::gfx::SurfaceFormat::A8R8G8B8_UINT32 && + whiteSurf->Format() != mozilla::gfx::SurfaceFormat::X8R8G8B8_UINT32)) return false; blackSurf->Flush(); @@ -140,7 +140,7 @@ ByteAlignment(int32_t aAlignToLog2, int32_t aX, int32_t aY=0, int32_t aStride=1) gfxAlphaRecovery::AlignRectForSubimageRecovery(const mozilla::gfx::IntRect& aRect, gfxImageSurface* aSurface) { - NS_ASSERTION(gfxImageFormat::ARGB32 == aSurface->Format(), + NS_ASSERTION(mozilla::gfx::SurfaceFormat::A8R8G8B8_UINT32 == aSurface->Format(), "Thebes grew support for non-ARGB32 COLOR_ALPHA?"); static const int32_t kByteAlignLog2 = GoodAlignmentLog2(); static const int32_t bpp = 4; diff --git a/gfx/thebes/gfxAndroidPlatform.cpp b/gfx/thebes/gfxAndroidPlatform.cpp index f4323b02b4..6f7500007b 100644 --- a/gfx/thebes/gfxAndroidPlatform.cpp +++ b/gfx/thebes/gfxAndroidPlatform.cpp @@ -101,11 +101,11 @@ gfxAndroidPlatform::gfxAndroidPlatform() RegisterStrongMemoryReporter(new FreetypeReporter()); mOffscreenFormat = GetScreenDepth() == 16 - ? gfxImageFormat::RGB16_565 - : gfxImageFormat::RGB24; + ? SurfaceFormat::R5G6B5_UINT16 + : SurfaceFormat::X8R8G8B8_UINT32; if (gfxPrefs::AndroidRGB16Force()) { - mOffscreenFormat = gfxImageFormat::RGB16_565; + mOffscreenFormat = SurfaceFormat::R5G6B5_UINT16; } #ifdef MOZ_WIDGET_GONK diff --git a/gfx/thebes/gfxImageSurface.cpp b/gfx/thebes/gfxImageSurface.cpp index b71b6fb301..babb693eb4 100644 --- a/gfx/thebes/gfxImageSurface.cpp +++ b/gfx/thebes/gfxImageSurface.cpp @@ -12,6 +12,7 @@ #include "cairo.h" #include "mozilla/gfx/2D.h" +#include "mozilla/gfx/HelpersCairo.h" #include "gfx2DGlue.h" #include @@ -21,7 +22,7 @@ using namespace mozilla::gfx; gfxImageSurface::gfxImageSurface() : mSize(0, 0), mOwnsData(false), - mFormat(gfxImageFormat::Unknown), + mFormat(SurfaceFormat::UNKNOWN), mStride(0) { } @@ -37,7 +38,7 @@ gfxImageSurface::InitFromSurface(cairo_surface_t *csurf) mSize.width = cairo_image_surface_get_width(csurf); mSize.height = cairo_image_surface_get_height(csurf); mData = cairo_image_surface_get_data(csurf); - mFormat = gfxCairoFormatToImageFormat(cairo_image_surface_get_format(csurf)); + mFormat = CairoFormatToGfxFormat(cairo_image_surface_get_format(csurf)); mOwnsData = false; mStride = cairo_image_surface_get_stride(csurf); @@ -71,7 +72,7 @@ gfxImageSurface::InitWithData(unsigned char *aData, const IntSize& aSize, if (!CheckSurfaceSize(aSize)) MakeInvalid(); - cairo_format_t cformat = gfxImageFormatToCairoFormat(mFormat); + cairo_format_t cformat = GfxFormatToCairoFormat(mFormat); cairo_surface_t *surface = cairo_image_surface_create_for_data((unsigned char*)mData, cformat, @@ -141,7 +142,7 @@ gfxImageSurface::AllocateAndInit(long aStride, int32_t aMinimalAllocation, mOwnsData = true; - cairo_format_t cformat = gfxImageFormatToCairoFormat(mFormat); + cairo_format_t cformat = GfxFormatToCairoFormat(mFormat); cairo_surface_t *surface = cairo_image_surface_create_for_data((unsigned char*)mData, cformat, @@ -169,7 +170,7 @@ gfxImageSurface::gfxImageSurface(cairo_surface_t *csurf) mSize.width = cairo_image_surface_get_width(csurf); mSize.height = cairo_image_surface_get_height(csurf); mData = cairo_image_surface_get_data(csurf); - mFormat = gfxCairoFormatToImageFormat(cairo_image_surface_get_format(csurf)); + mFormat = CairoFormatToGfxFormat(cairo_image_surface_get_format(csurf)); mOwnsData = false; mStride = cairo_image_surface_get_stride(csurf); @@ -187,13 +188,13 @@ gfxImageSurface::ComputeStride(const IntSize& aSize, gfxImageFormat aFormat) { long stride; - if (aFormat == gfxImageFormat::ARGB32) + if (aFormat == SurfaceFormat::A8R8G8B8_UINT32) stride = aSize.width * 4; - else if (aFormat == gfxImageFormat::RGB24) + else if (aFormat == SurfaceFormat::X8R8G8B8_UINT32) stride = aSize.width * 4; - else if (aFormat == gfxImageFormat::RGB16_565) + else if (aFormat == SurfaceFormat::R5G6B5_UINT16) stride = aSize.width * 2; - else if (aFormat == gfxImageFormat::A8) + else if (aFormat == SurfaceFormat::A8) stride = aSize.width; else { NS_WARNING("Unknown format specified to gfxImageSurface!"); @@ -249,10 +250,10 @@ static bool FormatsAreCompatible(gfxImageFormat a1, gfxImageFormat a2) { if (a1 != a2 && - !(a1 == gfxImageFormat::ARGB32 && - a2 == gfxImageFormat::RGB24) && - !(a1 == gfxImageFormat::RGB24 && - a2 == gfxImageFormat::ARGB32)) { + !(a1 == SurfaceFormat::A8R8G8B8_UINT32 && + a2 == SurfaceFormat::X8R8G8B8_UINT32) && + !(a1 == SurfaceFormat::X8R8G8B8_UINT32 && + a2 == SurfaceFormat::A8R8G8B8_UINT32)) { return false; } @@ -348,9 +349,9 @@ gfxImageSurface::GetSubimage(const gfxRect& aRect) (Stride() * (int)r.Y()) + (int)r.X() * gfxASurface::BytePerPixelFromFormat(Format()); - if (format == gfxImageFormat::ARGB32 && + if (format == SurfaceFormat::A8R8G8B8_UINT32 && GetOpaqueRect().Contains(aRect)) { - format = gfxImageFormat::RGB24; + format = SurfaceFormat::X8R8G8B8_UINT32; } RefPtr image = diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index d1fcf7a5b9..9fca8c3178 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -19,7 +19,6 @@ #include "gfxPrefs.h" #include "gfxEnv.h" #include "gfxTextRun.h" -#include "gfxVR.h" #ifdef XP_WIN #include @@ -126,6 +125,8 @@ class mozilla::gl::SkiaGLGlue : public GenericAtomicRefCounted { #include "SoftwareVsyncSource.h" #include "nscore.h" // for NS_FREE_PERMANENT_DATA #include "mozilla/dom/ContentChild.h" +#include "gfxVR.h" +#include "VRManagerChild.h" namespace mozilla { namespace layers { @@ -445,8 +446,7 @@ gfxPlatform::gfxPlatform() contentMask, BackendType::CAIRO); mTotalSystemMemory = mozilla::hal::GetTotalSystemMemory(); - // give HMDs a chance to be initialized very early on - VRHMDManager::ManagerInit(); + VRManager::ManagerInit(); } gfxPlatform* @@ -577,7 +577,7 @@ gfxPlatform::Init() gPlatform->mScreenReferenceSurface = gPlatform->CreateOffscreenSurface(IntSize(1, 1), - gfxImageFormat::ARGB32); + SurfaceFormat::A8R8G8B8_UINT32); if (!gPlatform->mScreenReferenceSurface) { NS_RUNTIMEABORT("Could not initialize mScreenReferenceSurface"); } @@ -739,6 +739,7 @@ gfxPlatform::InitLayersIPC() SharedBufferManagerChild::StartUp(); #endif mozilla::layers::ImageBridgeChild::StartUp(); + gfx::VRManagerChild::StartUpSameProcess(); } } @@ -754,13 +755,16 @@ gfxPlatform::ShutdownLayersIPC() { // This must happen after the shutdown of media and widgets, which // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification. + gfx::VRManagerChild::ShutDown(); layers::ImageBridgeChild::ShutDown(); #ifdef MOZ_WIDGET_GONK layers::SharedBufferManagerChild::ShutDown(); #endif layers::CompositorParent::ShutDown(); - } + } else if (XRE_GetProcessType() == GeckoProcessType_Content) { + gfx::VRManagerChild::ShutDown(); + } } gfxPlatform::~gfxPlatform() @@ -768,9 +772,6 @@ gfxPlatform::~gfxPlatform() mScreenReferenceSurface = nullptr; mScreenReferenceDrawTarget = nullptr; - // Clean up any VR stuff - VRHMDManager::ManagerDestroy(); - // The cairo folks think we should only clean up in debug builds, // but we're generally in the habit of trying to shut down as // cleanly as possible even in production code, so call this @@ -1855,11 +1856,11 @@ gfxPlatform::Optimal2DFormatForContent(gfxContentType aContent) switch (aContent) { case gfxContentType::COLOR: switch (GetOffscreenFormat()) { - case gfxImageFormat::ARGB32: + case SurfaceFormat::A8R8G8B8_UINT32: return mozilla::gfx::SurfaceFormat::B8G8R8A8; - case gfxImageFormat::RGB24: + case SurfaceFormat::X8R8G8B8_UINT32: return mozilla::gfx::SurfaceFormat::B8G8R8X8; - case gfxImageFormat::RGB16_565: + case SurfaceFormat::R5G6B5_UINT16: return mozilla::gfx::SurfaceFormat::R5G6B5_UINT16; default: NS_NOTREACHED("unknown gfxImageFormat for gfxContentType::COLOR"); @@ -1882,12 +1883,12 @@ gfxPlatform::OptimalFormatForContent(gfxContentType aContent) case gfxContentType::COLOR: return GetOffscreenFormat(); case gfxContentType::ALPHA: - return gfxImageFormat::A8; + return SurfaceFormat::A8; case gfxContentType::COLOR_ALPHA: - return gfxImageFormat::ARGB32; + return SurfaceFormat::A8R8G8B8_UINT32; default: NS_NOTREACHED("unknown gfxContentType"); - return gfxImageFormat::ARGB32; + return SurfaceFormat::A8R8G8B8_UINT32; } } @@ -2271,9 +2272,7 @@ gfxPlatform::GetCompositorBackends(bool useAcceleration, nsTArray& aBackends); - // Returns whether or not the basic compositor is supported. - virtual bool SupportsBasicCompositor() const { - return true; - } - /** * Initialise the preferred and fallback canvas backends * aBackendBitmask specifies the backends which are acceptable to the caller. diff --git a/gfx/thebes/gfxPlatformGtk.cpp b/gfx/thebes/gfxPlatformGtk.cpp index 50f672218f..a934e7d718 100644 --- a/gfx/thebes/gfxPlatformGtk.cpp +++ b/gfx/thebes/gfxPlatformGtk.cpp @@ -365,10 +365,10 @@ gfxPlatformGtk::GetOffscreenFormat() // Make sure there is a screen GdkScreen *screen = gdk_screen_get_default(); if (screen && gdk_visual_get_depth(gdk_visual_get_system()) == 16) { - return gfxImageFormat::RGB16_565; + return SurfaceFormat::R5G6B5_UINT16; } - return gfxImageFormat::RGB24; + return SurfaceFormat::X8R8G8B8_UINT32; } void gfxPlatformGtk::FontsPrefsChanged(const char *aPref) diff --git a/gfx/thebes/gfxPlatformMac.h b/gfx/thebes/gfxPlatformMac.h index 9a9120d960..198c9b0fb7 100644 --- a/gfx/thebes/gfxPlatformMac.h +++ b/gfx/thebes/gfxPlatformMac.h @@ -83,9 +83,11 @@ public: return true; } - bool SupportsBasicCompositor() const override { - // At the moment, BasicCompositor is broken on mac. - return false; + bool RequiresAcceleratedGLContextForCompositorOGL() const override { + // On OS X in a VM, unaccelerated CompositorOGL shows black flashes, so we + // require accelerated GL for CompositorOGL but allow unaccelerated GL for + // BasicCompositor. + return true; } bool UseAcceleratedCanvas(); diff --git a/gfx/thebes/gfxQPainterSurface.cpp b/gfx/thebes/gfxQPainterSurface.cpp index de3f804e15..fb0f1349db 100644 --- a/gfx/thebes/gfxQPainterSurface.cpp +++ b/gfx/thebes/gfxQPainterSurface.cpp @@ -21,7 +21,7 @@ gfxQPainterSurface::gfxQPainterSurface(QPainter *painter) gfxQPainterSurface::gfxQPainterSurface(const mozilla::gfx::IntSize& size, gfxImageFormat format) { - cairo_format_t cformat = gfxImageFormatToCairoFormat(format); + cairo_format_t cformat = GfxFormatToCairoFormat(format); cairo_surface_t *csurf = cairo_qt_surface_create_with_qimage(cformat, size.width, size.height); mPainter = cairo_qt_surface_get_qpainter (csurf); diff --git a/gfx/thebes/gfxQtPlatform.cpp b/gfx/thebes/gfxQtPlatform.cpp index 61275adca3..c3290af2d2 100644 --- a/gfx/thebes/gfxQtPlatform.cpp +++ b/gfx/thebes/gfxQtPlatform.cpp @@ -46,7 +46,7 @@ using namespace mozilla::gfx; gfxFontconfigUtils *gfxQtPlatform::sFontconfigUtils = nullptr; -static gfxImageFormat sOffscreenFormat = gfxImageFormat::RGB24; +static gfxImageFormat sOffscreenFormat = SurfaceFormat::X8R8G8B8_UINT32; gfxQtPlatform::gfxQtPlatform() { @@ -55,7 +55,7 @@ gfxQtPlatform::gfxQtPlatform() int32_t depth = GetScreenDepth(); if (depth == 16) { - sOffscreenFormat = gfxImageFormat::RGB16_565; + sOffscreenFormat = SurfaceFormat::R5G6B5_UINT16; } uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO) | BackendTypeBit(BackendType::SKIA); uint32_t contentMask = BackendTypeBit(BackendType::CAIRO) | BackendTypeBit(BackendType::SKIA); diff --git a/gfx/thebes/gfxQuartzSurface.cpp b/gfx/thebes/gfxQuartzSurface.cpp index 9614c68f73..01bb162bcd 100644 --- a/gfx/thebes/gfxQuartzSurface.cpp +++ b/gfx/thebes/gfxQuartzSurface.cpp @@ -6,6 +6,7 @@ #include "gfxQuartzSurface.h" #include "gfxContext.h" #include "gfxImageSurface.h" +#include "mozilla/gfx/HelpersCairo.h" #include "cairo-quartz.h" @@ -26,7 +27,7 @@ gfxQuartzSurface::gfxQuartzSurface(const gfxSize& desiredSize, gfxImageFormat fo unsigned int width = static_cast(mSize.width); unsigned int height = static_cast(mSize.height); - cairo_format_t cformat = gfxImageFormatToCairoFormat(format); + cairo_format_t cformat = GfxFormatToCairoFormat(format); cairo_surface_t *surf = cairo_quartz_surface_create(cformat, width, height); mCGContext = cairo_quartz_surface_get_cg_context (surf); @@ -109,7 +110,7 @@ gfxQuartzSurface::gfxQuartzSurface(unsigned char *data, unsigned int width = static_cast(mSize.width); unsigned int height = static_cast(mSize.height); - cairo_format_t cformat = gfxImageFormatToCairoFormat(format); + cairo_format_t cformat = GfxFormatToCairoFormat(format); cairo_surface_t *surf = cairo_quartz_surface_create_for_data (data, cformat, width, height, stride); @@ -132,7 +133,7 @@ gfxQuartzSurface::gfxQuartzSurface(unsigned char *data, if (!CheckSurfaceSize(aSize)) MakeInvalid(); - cairo_format_t cformat = gfxImageFormatToCairoFormat(format); + cairo_format_t cformat = GfxFormatToCairoFormat(format); cairo_surface_t *surf = cairo_quartz_surface_create_for_data (data, cformat, aSize.width, aSize.height, stride); diff --git a/gfx/thebes/gfxTypes.h b/gfx/thebes/gfxTypes.h index 64ad9e1ef6..e017efbe95 100644 --- a/gfx/thebes/gfxTypes.h +++ b/gfx/thebes/gfxTypes.h @@ -44,34 +44,6 @@ enum class gfxBreakPriority { eNormalBreak }; -/** - * The format for an image surface. For all formats with alpha data, 0 - * means transparent, 1 or 255 means fully opaque. - * - * XXX: it's vital that the values here match the values in cairo_format_t, - * otherwise gfxCairoFormatToImageFormat() and gfxImageFormatToCairoFormat() - * won't work. - */ -enum class gfxImageFormat { - ARGB32 = 0, ///< ARGB data in native endianness, using premultiplied alpha - RGB24 = 1, ///< xRGB data in native endianness - A8 = 2, ///< Only an alpha channel - RGB16_565 = 4, ///< RGB_565 data in native endianness - Unknown -}; - -// XXX: temporary -// This works because the gfxImageFormat enum is defined so as to match the -// cairo_format_t enum. -#define gfxCairoFormatToImageFormat(aFormat) \ - ((gfxImageFormat)aFormat) - -// XXX: temporary -// This works because the gfxImageFormat enum is defined so as to match the -// cairo_format_t enum. -#define gfxImageFormatToCairoFormat(aFormat) \ - ((cairo_format_t)aFormat) - enum class gfxSurfaceType { Image, PDF, diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp index 6425377c27..318e31992f 100644 --- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -785,11 +785,11 @@ gfxUtils::DrawPixelSnapped(gfxContext* aContext, gfxUtils::ImageFormatToDepth(gfxImageFormat aFormat) { switch (aFormat) { - case gfxImageFormat::ARGB32: + case SurfaceFormat::A8R8G8B8_UINT32: return 32; - case gfxImageFormat::RGB24: + case SurfaceFormat::X8R8G8B8_UINT32: return 24; - case gfxImageFormat::RGB16_565: + case SurfaceFormat::R5G6B5_UINT16: return 16; default: break; @@ -981,7 +981,7 @@ gfxUtils::GetYCbCrToRGBDestFormatAndSize(const PlanarYCbCrData& aData, bool prescale = aSuggestedSize.width > 0 && aSuggestedSize.height > 0 && aSuggestedSize != aData.mPicSize; - if (aSuggestedFormat == gfxImageFormat::RGB16_565) { + if (aSuggestedFormat == SurfaceFormat::R5G6B5_UINT16) { #if defined(HAVE_YCBCR_TO_RGB565) if (prescale && !IsScaleYCbCrToRGB565Fast(aData.mPicX, @@ -1001,14 +1001,14 @@ gfxUtils::GetYCbCrToRGBDestFormatAndSize(const PlanarYCbCrData& aData, } #else // yuv2rgb16 function not available - aSuggestedFormat = gfxImageFormat::RGB24; + aSuggestedFormat = SurfaceFormat::X8R8G8B8_UINT32; #endif } - else if (aSuggestedFormat != gfxImageFormat::RGB24) { + else if (aSuggestedFormat != SurfaceFormat::X8R8G8B8_UINT32) { // No other formats are currently supported. - aSuggestedFormat = gfxImageFormat::RGB24; + aSuggestedFormat = SurfaceFormat::X8R8G8B8_UINT32; } - if (aSuggestedFormat == gfxImageFormat::RGB24) { + if (aSuggestedFormat == SurfaceFormat::X8R8G8B8_UINT32) { /* ScaleYCbCrToRGB32 does not support a picture offset, nor 4:4:4 data. See bugs 639415 and 640073. */ if (aData.mPicX != 0 || aData.mPicY != 0 || yuvtype == YV24) @@ -1041,7 +1041,7 @@ gfxUtils::ConvertYCbCrToRGB(const PlanarYCbCrData& aData, // Convert from YCbCr to RGB now, scaling the image if needed. if (aDestSize != aData.mPicSize) { #if defined(HAVE_YCBCR_TO_RGB565) - if (aDestFormat == gfxImageFormat::RGB16_565) { + if (aDestFormat == SurfaceFormat::R5G6B5_UINT16) { ScaleYCbCrToRGB565(aData.mYChannel, aData.mCbChannel, aData.mCrChannel, @@ -1075,7 +1075,7 @@ gfxUtils::ConvertYCbCrToRGB(const PlanarYCbCrData& aData, FILTER_BILINEAR); } else { // no prescale #if defined(HAVE_YCBCR_TO_RGB565) - if (aDestFormat == gfxImageFormat::RGB16_565) { + if (aDestFormat == SurfaceFormat::R5G6B5_UINT16) { ConvertYCbCrToRGB565(aData.mYChannel, aData.mCbChannel, aData.mCrChannel, @@ -1088,7 +1088,7 @@ gfxUtils::ConvertYCbCrToRGB(const PlanarYCbCrData& aData, aData.mCbCrStride, aStride, yuvtype); - } else // aDestFormat != gfxImageFormat::RGB16_565 + } else // aDestFormat != SurfaceFormat::R5G6B5_UINT16 #endif ConvertYCbCrToRGB32(aData.mYChannel, aData.mCbChannel, diff --git a/gfx/thebes/gfxUtils.h b/gfx/thebes/gfxUtils.h index 595678e637..e538081dad 100644 --- a/gfx/thebes/gfxUtils.h +++ b/gfx/thebes/gfxUtils.h @@ -49,7 +49,7 @@ public: * If aDestSurface is given, it must have identical format, dimensions, and * stride as the source. * - * If the source is not gfxImageFormat::ARGB32, no operation is performed. If + * If the source is not SurfaceFormat::A8R8G8B8_UINT32, no operation is performed. If * aDestSurface is given, the data is copied over. */ static bool PremultiplyDataSurface(DataSourceSurface* srcSurf, @@ -137,7 +137,7 @@ public: /** * Helper function for ConvertYCbCrToRGB that finds the * RGB buffer size and format for given YCbCrImage. - * @param aSuggestedFormat will be set to gfxImageFormat::RGB24 + * @param aSuggestedFormat will be set to SurfaceFormat::X8R8G8B8_UINT32 * if the desired format is not supported. * @param aSuggestedSize will be set to the picture size from aData * if either the suggested size was {0,0} diff --git a/gfx/thebes/gfxWindowsSurface.cpp b/gfx/thebes/gfxWindowsSurface.cpp index 6249faf47f..41cb047a21 100644 --- a/gfx/thebes/gfxWindowsSurface.cpp +++ b/gfx/thebes/gfxWindowsSurface.cpp @@ -6,6 +6,7 @@ #include "gfxWindowsSurface.h" #include "gfxContext.h" #include "gfxPlatform.h" +#include "mozilla/gfx/HelpersCairo.h" #include "mozilla/gfx/Logging.h" #include "cairo.h" @@ -59,7 +60,7 @@ gfxWindowsSurface::gfxWindowsSurface(const mozilla::gfx::IntSize& realSize, gfxI if (!CheckSurfaceSize(size)) MakeInvalid(size); - cairo_format_t cformat = gfxImageFormatToCairoFormat(imageFormat); + cairo_format_t cformat = GfxFormatToCairoFormat(imageFormat); cairo_surface_t *surf = cairo_win32_surface_create_with_dib(cformat, size.width, size.height); @@ -80,7 +81,7 @@ gfxWindowsSurface::gfxWindowsSurface(HDC dc, const mozilla::gfx::IntSize& realSi if (!CheckSurfaceSize(size)) MakeInvalid(size); - cairo_format_t cformat = gfxImageFormatToCairoFormat(imageFormat); + cairo_format_t cformat = GfxFormatToCairoFormat(imageFormat); cairo_surface_t *surf = cairo_win32_surface_create_with_ddb(dc, cformat, size.width, size.height); @@ -89,7 +90,8 @@ gfxWindowsSurface::gfxWindowsSurface(HDC dc, const mozilla::gfx::IntSize& realSi if (mSurfaceValid) { // DDBs will generally only use 3 bytes per pixel when RGB24 - int bytesPerPixel = ((imageFormat == gfxImageFormat::RGB24) ? 3 : 4); + int bytesPerPixel = + ((imageFormat == mozilla::gfx::SurfaceFormat::X8R8G8B8_UINT32) ? 3 : 4); RecordMemoryUsed(size.width * size.height * bytesPerPixel + sizeof(gfxWindowsSurface)); } @@ -143,7 +145,7 @@ gfxWindowsSurface::CreateSimilarSurface(gfxContentType aContent, // have a DIB. gfxImageFormat gformat = gfxPlatform::GetPlatform()->OptimalFormatForContent(aContent); - cairo_format_t cformat = gfxImageFormatToCairoFormat(gformat); + cairo_format_t cformat = GfxFormatToCairoFormat(gformat); surface = cairo_win32_surface_create_with_dib(cformat, aSize.width, aSize.height); } else { diff --git a/gfx/thebes/gfxWindowsSurface.h b/gfx/thebes/gfxWindowsSurface.h index 0f5e2f58b9..8600ca567a 100644 --- a/gfx/thebes/gfxWindowsSurface.h +++ b/gfx/thebes/gfxWindowsSurface.h @@ -35,12 +35,12 @@ public: // Create a DIB surface gfxWindowsSurface(const mozilla::gfx::IntSize& size, - gfxImageFormat imageFormat = gfxImageFormat::RGB24); + gfxImageFormat imageFormat = mozilla::gfx::SurfaceFormat::X8R8G8B8_UINT32); // Create a DDB surface; dc may be nullptr to use the screen DC gfxWindowsSurface(HDC dc, const mozilla::gfx::IntSize& size, - gfxImageFormat imageFormat = gfxImageFormat::RGB24); + gfxImageFormat imageFormat = mozilla::gfx::SurfaceFormat::X8R8G8B8_UINT32); gfxWindowsSurface(cairo_surface_t *csurf); diff --git a/gfx/thebes/gfxXlibNativeRenderer.cpp b/gfx/thebes/gfxXlibNativeRenderer.cpp index a5a3feae2f..b686c4b377 100644 --- a/gfx/thebes/gfxXlibNativeRenderer.cpp +++ b/gfx/thebes/gfxXlibNativeRenderer.cpp @@ -13,6 +13,7 @@ #include "cairo-xlib.h" #include "cairo-xlib-xrender.h" #include "mozilla/gfx/BorrowedContext.h" +#include "mozilla/gfx/HelpersCairo.h" #include "gfx2DGlue.h" using namespace mozilla; @@ -352,7 +353,7 @@ CreateTempXlibSurface (cairo_surface_t* cairoTarget, } else if (cairoTargetType == CAIRO_SURFACE_TYPE_IMAGE || drawTarget) { gfxImageFormat imageFormat = drawTarget ? SurfaceFormatToImageFormat(drawTarget->GetFormat()) : - gfxCairoFormatToImageFormat(cairo_image_surface_get_format(cairoTarget)); + CairoFormatToGfxFormat(cairo_image_surface_get_format(cairoTarget)); target_visual = gfxXlibSurface::FindVisual(screen, imageFormat); Display *dpy = DisplayOfScreen(screen); if (target_visual) { @@ -389,7 +390,7 @@ CreateTempXlibSurface (cairo_surface_t* cairoTarget, supportsAlternateScreen ? target_screen : screen; Visual *argbVisual = gfxXlibSurface::FindVisual(visualScreen, - gfxImageFormat::ARGB32); + SurfaceFormat::A8R8G8B8_UINT32); if (argbVisual) { visual = argbVisual; screen = visualScreen; @@ -399,7 +400,7 @@ CreateTempXlibSurface (cairo_surface_t* cairoTarget, // No advantage in using the target screen. Visual *rgb24Visual = gfxXlibSurface::FindVisual(screen, - gfxImageFormat::RGB24); + SurfaceFormat::X8R8G8B8_UINT32); if (rgb24Visual) { visual = rgb24Visual; } @@ -593,7 +594,7 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, IntSize size, } RefPtr blackImage = - CopyXlibSurfaceToImage(tempXlibSurface, size, gfxImageFormat::ARGB32); + CopyXlibSurfaceToImage(tempXlibSurface, size, SurfaceFormat::A8R8G8B8_UINT32); cairo_t* tmpCtx = cairo_create(tempXlibSurface); cairo_set_source_rgba(tmpCtx, 1.0, 1.0, 1.0, 1.0); @@ -602,7 +603,7 @@ gfxXlibNativeRenderer::Draw(gfxContext* ctx, IntSize size, cairo_destroy(tmpCtx); DrawOntoTempSurface(tempXlibSurface, -drawingRect.TopLeft()); RefPtr whiteImage = - CopyXlibSurfaceToImage(tempXlibSurface, size, gfxImageFormat::RGB24); + CopyXlibSurfaceToImage(tempXlibSurface, size, SurfaceFormat::X8R8G8B8_UINT32); if (blackImage->CairoStatus() == CAIRO_STATUS_SUCCESS && whiteImage->CairoStatus() == CAIRO_STATUS_SUCCESS) { diff --git a/gfx/thebes/gfxXlibSurface.cpp b/gfx/thebes/gfxXlibSurface.cpp index f86c030d8a..cdb8db7f8a 100644 --- a/gfx/thebes/gfxXlibSurface.cpp +++ b/gfx/thebes/gfxXlibSurface.cpp @@ -504,25 +504,25 @@ gfxXlibSurface::FindVisual(Screen *screen, gfxImageFormat format) int depth; unsigned long red_mask, green_mask, blue_mask; switch (format) { - case gfxImageFormat::ARGB32: + case gfx::SurfaceFormat::A8R8G8B8_UINT32: depth = 32; red_mask = 0xff0000; green_mask = 0xff00; blue_mask = 0xff; break; - case gfxImageFormat::RGB24: + case gfx::SurfaceFormat::X8R8G8B8_UINT32: depth = 24; red_mask = 0xff0000; green_mask = 0xff00; blue_mask = 0xff; break; - case gfxImageFormat::RGB16_565: + case gfx::SurfaceFormat::R5G6B5_UINT16: depth = 16; red_mask = 0xf800; green_mask = 0x7e0; blue_mask = 0x1f; break; - case gfxImageFormat::A8: + case gfx::SurfaceFormat::A8: default: return nullptr; } @@ -551,11 +551,11 @@ XRenderPictFormat* gfxXlibSurface::FindRenderFormat(Display *dpy, gfxImageFormat format) { switch (format) { - case gfxImageFormat::ARGB32: + case gfx::SurfaceFormat::A8R8G8B8_UINT32: return XRenderFindStandardFormat (dpy, PictStandardARGB32); - case gfxImageFormat::RGB24: + case gfx::SurfaceFormat::X8R8G8B8_UINT32: return XRenderFindStandardFormat (dpy, PictStandardRGB24); - case gfxImageFormat::RGB16_565: { + case gfx::SurfaceFormat::R5G6B5_UINT16: { // PictStandardRGB16_565 is not standard Xrender format // we should try to find related visual // and find xrender format by visual @@ -564,7 +564,7 @@ gfxXlibSurface::FindRenderFormat(Display *dpy, gfxImageFormat format) return nullptr; return XRenderFindVisualFormat(dpy, visual); } - case gfxImageFormat::A8: + case gfx::SurfaceFormat::A8: return XRenderFindStandardFormat (dpy, PictStandardA8); default: break; diff --git a/gfx/vr/VRDeviceProxy.cpp b/gfx/vr/VRDeviceProxy.cpp new file mode 100644 index 0000000000..68db8f3b3f --- /dev/null +++ b/gfx/vr/VRDeviceProxy.cpp @@ -0,0 +1,153 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#include "prlink.h" +#include "prmem.h" +#include "prenv.h" +#include "gfxPrefs.h" +#include "nsString.h" +#include "mozilla/Preferences.h" +#include "mozilla/unused.h" +#include "nsServiceManagerUtils.h" +#include "nsIScreenManager.h" + + +#ifdef XP_WIN +#include "../layers/d3d11/CompositorD3D11.h" +#endif + +#include "VRDeviceProxy.h" +#include "VRManagerChild.h" + +using namespace mozilla; +using namespace mozilla::gfx; + +VRDeviceProxy::VRDeviceProxy(const VRDeviceUpdate& aDeviceUpdate) + : mDeviceInfo(aDeviceUpdate.mDeviceInfo) + , mSensorState(aDeviceUpdate.mSensorState) +{ + MOZ_COUNT_CTOR(VRDeviceProxy); + + if (mDeviceInfo.mScreenRect.width && mDeviceInfo.mScreenRect.height) { + if (mDeviceInfo.mIsFakeScreen) { + mScreen = MakeFakeScreen(mDeviceInfo.mScreenRect); + } else { + nsCOMPtr screenmgr = do_GetService("@mozilla.org/gfx/screenmanager;1"); + if (screenmgr) { + screenmgr->ScreenForRect(mDeviceInfo.mScreenRect.x, mDeviceInfo.mScreenRect.y, + mDeviceInfo.mScreenRect.width, mDeviceInfo.mScreenRect.height, + getter_AddRefs(mScreen)); + } + } +#ifdef DEBUG + printf_stderr("VR DEVICE SCREEN: %d %d %d %d\n", + mDeviceInfo.mScreenRect.x, mDeviceInfo.mScreenRect.y, + mDeviceInfo.mScreenRect.width, mDeviceInfo.mScreenRect.height); +#endif + } +} + +VRDeviceProxy::~VRDeviceProxy() { + MOZ_COUNT_DTOR(VRDeviceProxy); +} + +void +VRDeviceProxy::UpdateDeviceInfo(const VRDeviceUpdate& aDeviceUpdate) +{ + mDeviceInfo = aDeviceUpdate.mDeviceInfo; + mSensorState = aDeviceUpdate.mSensorState; +} + +bool +VRDeviceProxy::SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight, + double zNear, double zFar) +{ + VRManagerChild *vm = VRManagerChild::Get(); + vm->SendSetFOV(mDeviceInfo.mDeviceID, aFOVLeft, aFOVRight, zNear, zFar); + return true; +} + +void +VRDeviceProxy::ZeroSensor() +{ + VRManagerChild *vm = VRManagerChild::Get(); + vm->SendResetSensor(mDeviceInfo.mDeviceID); +} + +VRHMDSensorState +VRDeviceProxy::GetSensorState(double timeOffset) +{ + VRManagerChild *vm = VRManagerChild::Get(); + Unused << vm->SendKeepSensorTracking(mDeviceInfo.mDeviceID); + return mSensorState; +} + +void +VRDeviceProxy::UpdateSensorState(const VRHMDSensorState& aSensorState) +{ + mSensorState = aSensorState; +} + +// Dummy nsIScreen implementation, for when we just need to specify a size +class FakeScreen : public nsIScreen +{ +public: + explicit FakeScreen(const IntRect& aScreenRect) + : mScreenRect(aScreenRect) + { } + + NS_DECL_ISUPPORTS + + NS_IMETHOD GetRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override { + *l = mScreenRect.x; + *t = mScreenRect.y; + *w = mScreenRect.width; + *h = mScreenRect.height; + return NS_OK; + } + NS_IMETHOD GetAvailRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override { + return GetRect(l, t, w, h); + } + NS_IMETHOD GetRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override { + return GetRect(l, t, w, h); + } + NS_IMETHOD GetAvailRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override { + return GetAvailRect(l, t, w, h); + } + + NS_IMETHOD GetId(uint32_t* aId) override { *aId = (uint32_t)-1; return NS_OK; } + NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override { *aPixelDepth = 24; return NS_OK; } + NS_IMETHOD GetColorDepth(int32_t* aColorDepth) override { *aColorDepth = 24; return NS_OK; } + + NS_IMETHOD LockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; } + NS_IMETHOD UnlockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; } + NS_IMETHOD GetRotation(uint32_t* aRotation) override { + *aRotation = nsIScreen::ROTATION_0_DEG; + return NS_OK; + } + NS_IMETHOD SetRotation(uint32_t aRotation) override { return NS_ERROR_NOT_AVAILABLE; } + NS_IMETHOD GetContentsScaleFactor(double* aContentsScaleFactor) override { + *aContentsScaleFactor = 1.0; + return NS_OK; + } + +protected: + virtual ~FakeScreen() {} + + IntRect mScreenRect; +}; + +NS_IMPL_ISUPPORTS(FakeScreen, nsIScreen) + + +/* static */ already_AddRefed +VRDeviceProxy::MakeFakeScreen(const IntRect& aScreenRect) +{ + nsCOMPtr screen = new FakeScreen(aScreenRect); + return screen.forget(); +} + diff --git a/gfx/vr/VRDeviceProxy.h b/gfx/vr/VRDeviceProxy.h new file mode 100644 index 0000000000..440a706c87 --- /dev/null +++ b/gfx/vr/VRDeviceProxy.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef GFX_VR_PROXY_H +#define GFX_VR_PROXY_H + +#include "nsIScreen.h" +#include "nsCOMPtr.h" +#include "mozilla/RefPtr.h" + +#include "gfxVR.h" + +namespace mozilla { +namespace gfx { + +class VRManagerChild; + +class VRDeviceProxy +{ +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRDeviceProxy) + + explicit VRDeviceProxy(const VRDeviceUpdate& aDeviceUpdate); + + void UpdateDeviceInfo(const VRDeviceUpdate& aDeviceUpdate); + void UpdateSensorState(const VRHMDSensorState& aSensorState); + + const VRDeviceInfo& GetDeviceInfo() const { return mDeviceInfo; } + virtual VRHMDSensorState GetSensorState(double timeOffset = 0.0); + + bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight, + double zNear, double zFar); + + virtual void ZeroSensor(); + + + // The nsIScreen that represents this device + nsIScreen* GetScreen() { return mScreen; } + +protected: + virtual ~VRDeviceProxy(); + + VRDeviceInfo mDeviceInfo; + VRHMDSensorState mSensorState; + + nsCOMPtr mScreen; + + static already_AddRefed MakeFakeScreen(const IntRect& aScreenRect); + +}; + +} // namespace gfx +} // namespace mozilla + +#endif /* GFX_VR_PROXY_H */ diff --git a/gfx/vr/VRDeviceProxyOrientationFallBack.cpp b/gfx/vr/VRDeviceProxyOrientationFallBack.cpp new file mode 100644 index 0000000000..89a1962fca --- /dev/null +++ b/gfx/vr/VRDeviceProxyOrientationFallBack.cpp @@ -0,0 +1,199 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include "VRDeviceProxyOrientationFallBack.h" +#include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientationInternal +#include "mozilla/Hal.h" + +using namespace mozilla; +using namespace mozilla::gfx; + +// 1/sqrt(2) (aka sqrt(2)/2) +#ifndef M_SQRT1_2 +# define M_SQRT1_2 0.70710678118654752440 +#endif + +#ifdef ANDROID +#include +#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoVR" , ## args) +#else +#define LOG(...) do { } while(0) +#endif + +namespace { +// some utility functions + +// This remaps axes in the given matrix to a new configuration based on the +// screen orientation. Similar to what Android SensorManager.remapCoordinateSystem +// does, except only for a fixed number of transforms that we need. +Matrix4x4 +RemapMatrixForOrientation(dom::ScreenOrientationInternal screenConfig, const Matrix4x4& aMatrix) +{ + Matrix4x4 out; + const float *in = &aMatrix._11; + float *o = &out._11; + + if (screenConfig == dom::eScreenOrientation_LandscapePrimary) { + // remap X,Y -> Y,-X + o[0] = -in[1]; o[1] = in[0]; o[2] = in[2]; + o[4] = -in[5]; o[5] = in[4]; o[6] = in[6]; + o[8] = -in[9]; o[9] = in[8]; o[10] = in[10]; + } else if (screenConfig == dom::eScreenOrientation_LandscapeSecondary) { + // remap X,Y -> -Y,X + o[0] = in[1]; o[1] = -in[0]; o[2] = in[2]; + o[4] = in[5]; o[5] = -in[4]; o[6] = in[6]; + o[8] = in[9]; o[9] = -in[8]; o[10] = in[10]; + } else if (screenConfig == dom::eScreenOrientation_PortraitPrimary) { + out = aMatrix; + } else if (screenConfig == dom::eScreenOrientation_PortraitSecondary) { + // remap X,Y -> X,-Z + o[0] = in[0]; o[1] = in[2]; o[2] = -in[1]; + o[4] = in[4]; o[5] = in[6]; o[6] = -in[5]; + o[8] = in[8]; o[9] = in[10]; o[10] = -in[9]; + } else { + MOZ_ASSERT(0, "gfxVRCardboard::RemapMatrixForOrientation invalid screenConfig"); + } + + return out; +} + +} // namespace + +namespace mozilla { +namespace gfx { + +VRDeviceProxyOrientationFallBack::VRDeviceProxyOrientationFallBack(const VRDeviceUpdate& aDeviceUpdate) + : VRDeviceProxy(aDeviceUpdate) + , mOrient(dom::eScreenOrientation_PortraitPrimary) + , mTracking(false) +{ + MOZ_COUNT_CTOR_INHERITED(VRDeviceProxyOrientationFallBack, VRDeviceProxy); +} + +VRDeviceProxyOrientationFallBack::~VRDeviceProxyOrientationFallBack() +{ + StopSensorTracking(); + MOZ_COUNT_DTOR_INHERITED(VRDeviceProxyOrientationFallBack, VRDeviceProxy); +} + +void +VRDeviceProxyOrientationFallBack::StartSensorTracking() +{ + if (!mTracking) { + // it's never been started before; initialize observers and + // initial state. + + hal::ScreenConfiguration sconfig; + hal::GetCurrentScreenConfiguration(&sconfig); + this->Notify(sconfig); + + hal::RegisterSensorObserver(hal::SENSOR_GAME_ROTATION_VECTOR, this); + hal::RegisterScreenConfigurationObserver(this); + + mSensorState.Clear(); + + mTracking = true; + } +} + +void +VRDeviceProxyOrientationFallBack::StopSensorTracking() +{ + if (mTracking) { + hal::UnregisterScreenConfigurationObserver(this); + hal::UnregisterSensorObserver(hal::SENSOR_GAME_ROTATION_VECTOR, this); + mTracking = false; + } +} + +// Android sends us events that have a 90-degree rotation about +// the x axis compared to what we want (phone flat vs. phone held in front of the eyes). +// Correct for this by applying a transform to undo this rotation. +void +VRDeviceProxyOrientationFallBack::Notify(const hal::ScreenConfiguration& config) +{ + mOrient = config.orientation(); + + if (mOrient == dom::eScreenOrientation_LandscapePrimary) { + mScreenTransform = Quaternion(-0.5f, 0.5f, 0.5f, 0.5f); + } else if (mOrient == dom::eScreenOrientation_LandscapeSecondary) { + mScreenTransform = Quaternion(-0.5f, -0.5f, -0.5f, 0.5f); + } else if (mOrient == dom::eScreenOrientation_PortraitPrimary) { + mScreenTransform = Quaternion((float) -M_SQRT1_2, 0.f, 0.f, (float) M_SQRT1_2); + } else if (mOrient == dom::eScreenOrientation_PortraitSecondary) { + // Currently, PortraitSecondary event doesn't be triggered. + mScreenTransform = Quaternion((float) M_SQRT1_2, 0.f, 0.f, (float) M_SQRT1_2); + } +} + +void +VRDeviceProxyOrientationFallBack::Notify(const hal::SensorData& data) +{ + if (data.sensor() != hal::SENSOR_GAME_ROTATION_VECTOR) + return; + + const nsTArray& sensorValues = data.values(); + + // This is super chatty + //LOG("HMDInfoCardboard::Notify %f %f %f %f\n", sensorValues[0], sensorValues[1], sensorValues[2], sensorValues[3]); + + mSavedLastSensor.Set(sensorValues[0], sensorValues[1], sensorValues[2], sensorValues[3]); + mSavedLastSensorTime = data.timestamp(); + mNeedsSensorCompute = true; +} + +void +VRDeviceProxyOrientationFallBack::ZeroSensor() +{ + mSensorZeroInverse = mSavedLastSensor; + mSensorZeroInverse.Invert(); +} + +void +VRDeviceProxyOrientationFallBack::ComputeStateFromLastSensor() +{ + if (!mNeedsSensorCompute) + return; + + // apply the zero orientation + Quaternion q = mSensorZeroInverse * mSavedLastSensor; + + // make a matrix from the quat + Matrix4x4 qm; + qm.SetRotationFromQuaternion(q); + + // remap the coordinate space, based on the orientation + Matrix4x4 qmRemapped = RemapMatrixForOrientation(mOrient, qm); + + // turn it back into a quat + q.SetFromRotationMatrix(qmRemapped); + + // apply adjustment based on what's been done to the screen and the original zero + // position of the base coordinate space + q = mScreenTransform * q; + + mSensorState.flags |= VRStateValidFlags::State_Orientation; + mSensorState.orientation[0] = q.x; + mSensorState.orientation[1] = q.y; + mSensorState.orientation[2] = q.z; + mSensorState.orientation[3] = q.w; + + mSensorState.timestamp = mSavedLastSensorTime / 1000000.0; + + mNeedsSensorCompute = false; +} + +VRHMDSensorState +VRDeviceProxyOrientationFallBack::GetSensorState(double timeOffset) +{ + StartSensorTracking(); + ComputeStateFromLastSensor(); + return mSensorState; +} + +} // namespace gfx +} // namespace mozilla + diff --git a/gfx/vr/VRDeviceProxyOrientationFallBack.h b/gfx/vr/VRDeviceProxyOrientationFallBack.h new file mode 100644 index 0000000000..e1fb0d8df9 --- /dev/null +++ b/gfx/vr/VRDeviceProxyOrientationFallBack.h @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef GFX_VR_PROXY_ORIENTATION_FALLBACK_H +#define GFX_VR_PROXY_ORIENTATION_FALLBACK_H + +#include "VRDeviceProxy.h" + +#include "mozilla/HalSensor.h" +#include "mozilla/HalScreenConfiguration.h" + +namespace mozilla { +namespace gfx { + +class VRDeviceProxyOrientationFallBack : public VRDeviceProxy + , public hal::ISensorObserver + , public hal::ScreenConfigurationObserver +{ +public: + + explicit VRDeviceProxyOrientationFallBack(const VRDeviceUpdate& aDeviceUpdate); + + virtual void ZeroSensor() override; + virtual VRHMDSensorState GetSensorState(double timeOffset = 0.0) override; + + // ISensorObserver interface + void Notify(const hal::SensorData& SensorData) override; + // ScreenConfigurationObserver interface + void Notify(const hal::ScreenConfiguration& ScreenConfiguration) override; + + +protected: + virtual ~VRDeviceProxyOrientationFallBack(); + + void StartSensorTracking(); + void StopSensorTracking(); + void ComputeStateFromLastSensor(); + + uint32_t mOrient; + Quaternion mScreenTransform; + Quaternion mSensorZeroInverse; + Quaternion mSavedLastSensor; + double mSavedLastSensorTime; + bool mNeedsSensorCompute; // if we need to compute the state from mSavedLastSensor + + bool mTracking; +}; + +} // namespace gfx +} // namespace mozilla + +#endif /* GFX_VR_PROXY_ORIENTATION_FALLBACK_H */ \ No newline at end of file diff --git a/gfx/vr/VRManager.cpp b/gfx/vr/VRManager.cpp new file mode 100644 index 0000000000..c6817ae49c --- /dev/null +++ b/gfx/vr/VRManager.cpp @@ -0,0 +1,221 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#include "VRManager.h" +#include "VRManagerParent.h" +#include "gfxVR.h" +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/dom/VRDevice.h" +#include "mozilla/unused.h" + +#include "gfxPrefs.h" +#include "gfxVR.h" +#if defined(XP_WIN) +#include "gfxVROculus.h" +#endif +#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX) +#include "gfxVROculus050.h" +#endif +#include "gfxVRCardboard.h" + + +namespace mozilla { +namespace gfx { + +static StaticRefPtr sVRManagerSingleton; + +/*static*/ void +VRManager::ManagerInit() +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (sVRManagerSingleton == nullptr) { + sVRManagerSingleton = new VRManager(); + ClearOnShutdown(&sVRManagerSingleton); + } +} + +VRManager::VRManager() + : mInitialized(false) +{ + MOZ_COUNT_CTOR(VRManager); + MOZ_ASSERT(sVRManagerSingleton == nullptr); + + RefPtr mgr; + + // we'll only load the 0.5.0 oculus runtime if + // the >= 0.6.0 one failed to load; otherwise + // we might initialize oculus twice + bool useOculus050 = true; + Unused << useOculus050; + +#if defined(XP_WIN) + mgr = VRHMDManagerOculus::Create(); + if (mgr) { + useOculus050 = false; + mManagers.AppendElement(mgr); + } +#endif + +#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX) + if (useOculus050) { + mgr = VRHMDManagerOculus050::Create(); + if (mgr) { + mManagers.AppendElement(mgr); + } + } +#endif + + mgr = VRHMDManagerCardboard::Create(); + if (mgr) { + mManagers.AppendElement(mgr); + } +} + +VRManager::~VRManager() +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!mInitialized); + MOZ_COUNT_DTOR(VRManager); +} + +void +VRManager::Destroy() +{ + for (uint32_t i = 0; i < mManagers.Length(); ++i) { + mManagers[i]->Destroy(); + } + mInitialized = false; +} + +void +VRManager::Init() +{ + for (uint32_t i = 0; i < mManagers.Length(); ++i) { + mManagers[i]->Init(); + } + mInitialized = true; +} + +/* static */VRManager* +VRManager::Get() +{ + MOZ_ASSERT(sVRManagerSingleton != nullptr); + + return sVRManagerSingleton; +} + +void +VRManager::AddVRManagerParent(VRManagerParent* aVRManagerParent) +{ + if (mVRManagerParents.IsEmpty()) { + Init(); + } + mVRManagerParents.PutEntry(aVRManagerParent); +} + +void +VRManager::RemoveVRManagerParent(VRManagerParent* aVRManagerParent) +{ + mVRManagerParents.RemoveEntry(aVRManagerParent); + if (mVRManagerParents.IsEmpty()) { + Destroy(); + } +} + +void +VRManager::NotifyVsync(const TimeStamp& aVsyncTimestamp) +{ + for (auto iter = mVRDevices.Iter(); !iter.Done(); iter.Next()) { + gfx::VRHMDInfo* device = iter.UserData(); + device->NotifyVsync(aVsyncTimestamp); + } + DispatchVRDeviceSensorUpdate(); +} + +void +VRManager::RefreshVRDevices() +{ + nsTArray > devices; + + for (uint32_t i = 0; i < mManagers.Length(); ++i) { + mManagers[i]->GetHMDs(devices); + } + + bool deviceInfoChanged = false; + + if (devices.Length() != mVRDevices.Count()) { + deviceInfoChanged = true; + } + + for (const auto& device: devices) { + RefPtr oldDevice = GetDevice(device->GetDeviceInfo().GetDeviceID()); + if (oldDevice == nullptr) { + deviceInfoChanged = true; + break; + } + if (oldDevice->GetDeviceInfo() != device->GetDeviceInfo()) { + deviceInfoChanged = true; + break; + } + } + + if (deviceInfoChanged) { + mVRDevices.Clear(); + for (const auto& device: devices) { + mVRDevices.Put(device->GetDeviceInfo().GetDeviceID(), device); + } + } + + DispatchVRDeviceInfoUpdate(); +} + +void +VRManager::DispatchVRDeviceInfoUpdate() +{ + nsTArray update; + for (auto iter = mVRDevices.Iter(); !iter.Done(); iter.Next()) { + gfx::VRHMDInfo* device = iter.UserData(); + update.AppendElement(VRDeviceUpdate(device->GetDeviceInfo(), + device->GetSensorState())); + } + + for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) { + Unused << iter.Get()->GetKey()->SendUpdateDeviceInfo(update); + } +} + +void +VRManager::DispatchVRDeviceSensorUpdate() +{ + nsTArray update; + + for (auto iter = mVRDevices.Iter(); !iter.Done(); iter.Next()) { + gfx::VRHMDInfo* device = iter.UserData(); + if (!device->GetDeviceInfo().GetUseMainThreadOrientation()) { + update.AppendElement(VRSensorUpdate(device->GetDeviceInfo().GetDeviceID(), + device->GetSensorState())); + } + } + if (update.Length() > 0) { + for (auto iter = mVRManagerParents.Iter(); !iter.Done(); iter.Next()) { + Unused << iter.Get()->GetKey()->SendUpdateDeviceSensors(update); + } + } +} + +RefPtr +VRManager::GetDevice(const uint32_t& aDeviceID) +{ + RefPtr device; + if (mVRDevices.Get(aDeviceID, getter_AddRefs(device))) { + return device; + } + return nullptr; +} + +} // namespace gfx +} // namespace mozilla diff --git a/gfx/vr/VRManager.h b/gfx/vr/VRManager.h new file mode 100644 index 0000000000..a755242d13 --- /dev/null +++ b/gfx/vr/VRManager.h @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef GFX_VR_MANAGER_H +#define GFX_VR_MANAGER_H + +#include "nsAutoPtr.h" +#include "nsRefPtrHashtable.h" +#include "nsTArray.h" +#include "nsTHashtable.h" +#include "mozilla/TimeStamp.h" +#include "gfxVR.h" + +namespace mozilla { +namespace gfx { + +class VRManagerParent; +class VRHMDInfo; + +class VRManager +{ + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::gfx::VRManager) + +public: + static void ManagerInit(); + static VRManager* Get(); + + void AddVRManagerParent(VRManagerParent* aVRManagerParent); + void RemoveVRManagerParent(VRManagerParent* aVRManagerParent); + + void NotifyVsync(const TimeStamp& aVsyncTimestamp); + void RefreshVRDevices(); + RefPtr GetDevice(const uint32_t& aDeviceID); + +protected: + VRManager(); + ~VRManager(); + +private: + + void Init(); + void Destroy(); + + void DispatchVRDeviceInfoUpdate(); + void DispatchVRDeviceSensorUpdate(); + + typedef nsTHashtable> VRManagerParentSet; + VRManagerParentSet mVRManagerParents; + + typedef nsTArray> VRHMDManagerArray; + VRHMDManagerArray mManagers; + + typedef nsRefPtrHashtable VRHMDInfoHashMap; + VRHMDInfoHashMap mVRDevices; + + Atomic mInitialized; + +}; + +} // namespace gfx +} // namespace mozilla + +#endif // GFX_VR_MANAGER_H diff --git a/gfx/vr/gfxVR.cpp b/gfx/vr/gfxVR.cpp index 878f56350a..69b3aad304 100644 --- a/gfx/vr/gfxVR.cpp +++ b/gfx/vr/gfxVR.cpp @@ -20,9 +20,6 @@ #endif #include "gfxVRCardboard.h" -#include "nsServiceManagerUtils.h" -#include "nsIScreenManager.h" - #include "mozilla/unused.h" #include "mozilla/layers/Compositor.h" #include "mozilla/layers/TextureHost.h" @@ -34,145 +31,27 @@ using namespace mozilla; using namespace mozilla::gfx; -// Dummy nsIScreen implementation, for when we just need to specify a size -class FakeScreen : public nsIScreen -{ -public: - explicit FakeScreen(const IntRect& aScreenRect) - : mScreenRect(aScreenRect) - { } - - NS_DECL_ISUPPORTS - - NS_IMETHOD GetRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override { - *l = mScreenRect.x; - *t = mScreenRect.y; - *w = mScreenRect.width; - *h = mScreenRect.height; - return NS_OK; - } - NS_IMETHOD GetAvailRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override { - return GetRect(l, t, w, h); - } - NS_IMETHOD GetRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override { - return GetRect(l, t, w, h); - } - NS_IMETHOD GetAvailRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override { - return GetAvailRect(l, t, w, h); - } - - NS_IMETHOD GetId(uint32_t* aId) override { *aId = (uint32_t)-1; return NS_OK; } - NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override { *aPixelDepth = 24; return NS_OK; } - NS_IMETHOD GetColorDepth(int32_t* aColorDepth) override { *aColorDepth = 24; return NS_OK; } - - NS_IMETHOD LockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; } - NS_IMETHOD UnlockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; } - NS_IMETHOD GetRotation(uint32_t* aRotation) override { - *aRotation = nsIScreen::ROTATION_0_DEG; - return NS_OK; - } - NS_IMETHOD SetRotation(uint32_t aRotation) override { return NS_ERROR_NOT_AVAILABLE; } - NS_IMETHOD GetContentsScaleFactor(double* aContentsScaleFactor) override { - *aContentsScaleFactor = 1.0; - return NS_OK; - } - -protected: - virtual ~FakeScreen() {} - - IntRect mScreenRect; -}; - -NS_IMPL_ISUPPORTS(FakeScreen, nsIScreen) - -VRHMDInfo::VRHMDInfo(VRHMDType aType) - : mType(aType) -{ - MOZ_COUNT_CTOR(VRHMDInfo); - - mDeviceIndex = VRHMDManager::AllocateDeviceIndex(); - mDeviceName.AssignLiteral("Unknown Device"); -} - - -VRHMDManager::VRHMDManagerArray *VRHMDManager::sManagers = nullptr; Atomic VRHMDManager::sDeviceBase(0); -/* static */ void -VRHMDManager::ManagerInit() +VRHMDInfo::VRHMDInfo(VRHMDType aType, bool aUseMainThreadOrientation) { - if (sManagers) - return; - - sManagers = new VRHMDManagerArray(); - - RefPtr mgr; - - // we'll only load the 0.5.0 oculus runtime if - // the >= 0.6.0 one failed to load; otherwise - // we might initialize oculus twice - bool useOculus050 = true; - Unused << useOculus050; - -#if defined(XP_WIN) - mgr = new VRHMDManagerOculus(); - if (mgr->PlatformInit()) { - useOculus050 = false; - sManagers->AppendElement(mgr); - } -#endif - -#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_LINUX) - if (useOculus050) { - mgr = new VRHMDManagerOculus050(); - if (mgr->PlatformInit()) - sManagers->AppendElement(mgr); - } -#endif - - mgr = new VRHMDManagerCardboard(); - if (mgr->PlatformInit()) - sManagers->AppendElement(mgr); + MOZ_COUNT_CTOR(VRHMDInfo); + mDeviceInfo.mType = aType; + mDeviceInfo.mDeviceID = VRHMDManager::AllocateDeviceID(); + mDeviceInfo.mUseMainThreadOrientation = aUseMainThreadOrientation; } -/* static */ void -VRHMDManager::ManagerDestroy() +VRHMDInfo::~VRHMDInfo() { - if (!sManagers) - return; - - for (uint32_t i = 0; i < sManagers->Length(); ++i) { - (*sManagers)[i]->Destroy(); - } - - delete sManagers; - sManagers = nullptr; -} - -/* static */ void -VRHMDManager::GetAllHMDs(nsTArray>& aHMDResult) -{ - if (!sManagers) - return; - - for (uint32_t i = 0; i < sManagers->Length(); ++i) { - (*sManagers)[i]->GetHMDs(aHMDResult); - } + MOZ_COUNT_DTOR(VRHMDInfo); } /* static */ uint32_t -VRHMDManager::AllocateDeviceIndex() +VRHMDManager::AllocateDeviceID() { return ++sDeviceBase; } -/* static */ already_AddRefed -VRHMDManager::MakeFakeScreen(int32_t x, int32_t y, uint32_t width, uint32_t height) -{ - nsCOMPtr screen = new FakeScreen(IntRect(x, y, width, height)); - return screen.forget(); -} - VRHMDRenderingSupport::RenderTargetSet::RenderTargetSet() : currentRenderTarget(0) { diff --git a/gfx/vr/gfxVR.h b/gfx/vr/gfxVR.h index 5938df6428..ca111cb941 100644 --- a/gfx/vr/gfxVR.h +++ b/gfx/vr/gfxVR.h @@ -7,14 +7,15 @@ #define GFX_VR_H #include "nsTArray.h" -#include "nsIScreen.h" #include "nsString.h" #include "nsCOMPtr.h" #include "mozilla/RefPtr.h" #include "mozilla/gfx/2D.h" -#include "mozilla/EnumeratedArray.h" #include "mozilla/Atomics.h" +#include "mozilla/EnumeratedArray.h" +#include "mozilla/TimeStamp.h" +#include "mozilla/TypedEnumBits.h" namespace mozilla { namespace layers { @@ -31,6 +32,15 @@ enum class VRHMDType : uint16_t { NumHMDTypes }; +enum class VRStateValidFlags : uint16_t { + State_None = 0, + State_Position = 1 << 1, + State_Orientation = 1 << 2, + // State_All used for validity checking during IPC serialization + State_All = (1 << 3) - 1 +}; +MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(VRStateValidFlags) + struct VRFieldOfView { VRFieldOfView() {} VRFieldOfView(double up, double right, double down, double left) @@ -63,13 +73,6 @@ struct VRFieldOfView { double leftDegrees; }; -// 12 floats per vertex. Position, tex coordinates -// for each channel, and 4 generic attributes -struct VRDistortionConstants { - float eyeToSourceScaleAndOffset[4]; - float destinationScaleAndOffset[4]; -}; - struct VRDistortionVertex { float values[12]; }; @@ -79,9 +82,86 @@ struct VRDistortionMesh { nsTArray mIndices; }; +// 12 floats per vertex. Position, tex coordinates +// for each channel, and 4 generic attributes +struct VRDistortionConstants { + float eyeToSourceScaleAndOffset[4]; + float destinationScaleAndOffset[4]; +}; + +struct VRDeviceInfo +{ + VRHMDType GetType() const { return mType; } + uint32_t GetDeviceID() const { return mDeviceID; } + const nsCString& GetDeviceName() const { return mDeviceName; } + VRStateValidFlags GetSupportedSensorStateBits() const { return mSupportedSensorBits; } + const VRFieldOfView& GetRecommendedEyeFOV(uint32_t whichEye) const { return mRecommendedEyeFOV[whichEye]; } + const VRFieldOfView& GetMaximumEyeFOV(uint32_t whichEye) const { return mMaximumEyeFOV[whichEye]; } + + const IntSize& SuggestedEyeResolution() const { return mEyeResolution; } + const Point3D& GetEyeTranslation(uint32_t whichEye) const { return mEyeTranslation[whichEye]; } + const Matrix4x4& GetEyeProjectionMatrix(uint32_t whichEye) const { return mEyeProjectionMatrix[whichEye]; } + const VRFieldOfView& GetEyeFOV(uint32_t whichEye) const { return mEyeFOV[whichEye]; } + bool GetUseMainThreadOrientation() const { return mUseMainThreadOrientation; } + + enum Eye { + Eye_Left, + Eye_Right, + NumEyes + }; + + uint32_t mDeviceID; + VRHMDType mType; + nsCString mDeviceName; + VRStateValidFlags mSupportedSensorBits; + VRFieldOfView mMaximumEyeFOV[VRDeviceInfo::NumEyes]; + VRFieldOfView mRecommendedEyeFOV[VRDeviceInfo::NumEyes]; + VRFieldOfView mEyeFOV[VRDeviceInfo::NumEyes]; + Point3D mEyeTranslation[VRDeviceInfo::NumEyes]; + Matrix4x4 mEyeProjectionMatrix[VRDeviceInfo::NumEyes]; + /* Suggested resolution for rendering a single eye. + * Assumption is that left/right rendering will be 2x of this size. + * XXX fix this for vertical displays + */ + IntSize mEyeResolution; + IntRect mScreenRect; + + bool mIsFakeScreen; + bool mUseMainThreadOrientation; + + + + bool operator==(const VRDeviceInfo& other) const { + return mType == other.mType && + mDeviceID == other.mDeviceID && + mDeviceName == other.mDeviceName && + mSupportedSensorBits == other.mSupportedSensorBits && + mEyeResolution == other.mEyeResolution && + mScreenRect == other.mScreenRect && + mIsFakeScreen == other.mIsFakeScreen && + mUseMainThreadOrientation == other.mUseMainThreadOrientation && + mMaximumEyeFOV[0] == other.mMaximumEyeFOV[0] && + mMaximumEyeFOV[1] == other.mMaximumEyeFOV[1] && + mRecommendedEyeFOV[0] == other.mRecommendedEyeFOV[0] && + mRecommendedEyeFOV[1] == other.mRecommendedEyeFOV[1] && + mEyeFOV[0] == other.mEyeFOV[0] && + mEyeFOV[1] == other.mEyeFOV[1] && + mEyeTranslation[0] == other.mEyeTranslation[0] && + mEyeTranslation[1] == other.mEyeTranslation[1] && + mEyeProjectionMatrix[0] == other.mEyeProjectionMatrix[0] && + mEyeProjectionMatrix[1] == other.mEyeProjectionMatrix[1]; + } + + bool operator!=(const VRDeviceInfo& other) const { + return !(*this == other); + } +}; + + + struct VRHMDSensorState { double timestamp; - uint32_t flags; + VRStateValidFlags flags; float orientation[4]; float position[3]; float angularVelocity[3]; @@ -94,6 +174,27 @@ struct VRHMDSensorState { } }; +struct VRSensorUpdate { + VRSensorUpdate() { }; // Required for ipdl binding + VRSensorUpdate(uint32_t aDeviceID, const VRHMDSensorState& aSensorState) + : mDeviceID(aDeviceID) + , mSensorState(aSensorState) { }; + + uint32_t mDeviceID; + VRHMDSensorState mSensorState; +}; + +struct VRDeviceUpdate { + VRDeviceUpdate() { }; // Required for ipdl binding + VRDeviceUpdate(const VRDeviceInfo& aDeviceInfo, + const VRHMDSensorState& aSensorState) + : mDeviceInfo(aDeviceInfo) + , mSensorState(aSensorState) { }; + + VRDeviceInfo mDeviceInfo; + VRHMDSensorState mSensorState; +}; + /* A pure data struct that can be used to see if * the configuration of one HMDInfo matches another; for rendering purposes, * really asking "can the rendering details of this one be used for the other" @@ -149,51 +250,23 @@ protected: }; class VRHMDInfo { -public: - enum Eye { - Eye_Left, - Eye_Right, - NumEyes - }; - - enum StateValidFlags { - State_Position = 1 << 1, - State_Orientation = 1 << 2 - }; public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRHMDInfo) - VRHMDType GetType() const { return mType; } - uint32_t GetDeviceIndex() const { return mDeviceIndex; } - const nsCString& GetDeviceName() const { return mDeviceName; } - - virtual const VRFieldOfView& GetRecommendedEyeFOV(uint32_t whichEye) { return mRecommendedEyeFOV[whichEye]; } - virtual const VRFieldOfView& GetMaximumEyeFOV(uint32_t whichEye) { return mMaximumEyeFOV[whichEye]; } - const VRHMDConfiguration& GetConfiguration() const { return mConfiguration; } + const VRDeviceInfo& GetDeviceInfo() const { return mDeviceInfo; } /* set the FOV for this HMD unit; this triggers a computation of all the remaining bits. Returns false if it fails */ virtual bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight, double zNear, double zFar) = 0; - const VRFieldOfView& GetEyeFOV(uint32_t whichEye) { return mEyeFOV[whichEye]; } - /* Suggested resolution for rendering a single eye. - * Assumption is that left/right rendering will be 2x of this size. - * XXX fix this for vertical displays - */ - const IntSize& SuggestedEyeResolution() const { return mEyeResolution; } - const Point3D& GetEyeTranslation(uint32_t whichEye) const { return mEyeTranslation[whichEye]; } - const Matrix4x4& GetEyeProjectionMatrix(uint32_t whichEye) const { return mEyeProjectionMatrix[whichEye]; } - - virtual uint32_t GetSupportedSensorStateBits() { return mSupportedSensorBits; } - virtual bool StartSensorTracking() = 0; + virtual bool KeepSensorTracking() = 0; + virtual void NotifyVsync(const TimeStamp& aVsyncTimestamp) = 0; virtual VRHMDSensorState GetSensorState(double timeOffset = 0.0) = 0; - virtual void StopSensorTracking() = 0; virtual void ZeroSensor() = 0; - // if rendering is offloaded virtual VRHMDRenderingSupport *GetRenderingSupport() { return nullptr; } @@ -205,50 +278,27 @@ public: const Rect& destRect, // the rectangle within the dest viewport that this should be rendered VRDistortionConstants& values) = 0; - virtual const VRDistortionMesh& GetDistortionMesh(uint32_t whichEye) const { return mDistortionMesh[whichEye]; } - - // The nsIScreen that represents this device - virtual nsIScreen* GetScreen() { return mScreen; } - + const VRDistortionMesh& GetDistortionMesh(uint32_t whichEye) const { return mDistortionMesh[whichEye]; } protected: - explicit VRHMDInfo(VRHMDType aType); - virtual ~VRHMDInfo() { MOZ_COUNT_DTOR(VRHMDInfo); } + explicit VRHMDInfo(VRHMDType aType, bool aUseMainThreadOrientation); + virtual ~VRHMDInfo(); - VRHMDType mType; VRHMDConfiguration mConfiguration; - uint32_t mDeviceIndex; - nsCString mDeviceName; - - VRFieldOfView mEyeFOV[NumEyes]; - IntSize mEyeResolution; - Point3D mEyeTranslation[NumEyes]; - Matrix4x4 mEyeProjectionMatrix[NumEyes]; - VRDistortionMesh mDistortionMesh[NumEyes]; - uint32_t mSupportedSensorBits; - - VRFieldOfView mRecommendedEyeFOV[NumEyes]; - VRFieldOfView mMaximumEyeFOV[NumEyes]; - - nsCOMPtr mScreen; + VRDeviceInfo mDeviceInfo; + VRDistortionMesh mDistortionMesh[VRDeviceInfo::NumEyes]; }; class VRHMDManager { public: - static void ManagerInit(); - static void ManagerDestroy(); - static void GetAllHMDs(nsTArray>& aHMDResult); - static uint32_t AllocateDeviceIndex(); - static already_AddRefed MakeFakeScreen(int32_t x, int32_t y, uint32_t width, uint32_t height); + static uint32_t AllocateDeviceID(); protected: - typedef nsTArray> VRHMDManagerArray; - static VRHMDManagerArray *sManagers; static Atomic sDeviceBase; + public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRHMDManager) - virtual bool PlatformInit() = 0; virtual bool Init() = 0; virtual void Destroy() = 0; virtual void GetHMDs(nsTArray>& aHMDResult) = 0; diff --git a/gfx/vr/gfxVRCardboard.cpp b/gfx/vr/gfxVRCardboard.cpp index ab295ec4ef..3e4d437932 100644 --- a/gfx/vr/gfxVRCardboard.cpp +++ b/gfx/vr/gfxVRCardboard.cpp @@ -10,7 +10,6 @@ #include "prenv.h" #include "gfxPrefs.h" #include "nsString.h" -#include "mozilla/dom/ScreenOrientation.h" #include "mozilla/Preferences.h" #include "mozilla/Hal.h" @@ -19,232 +18,87 @@ #include "nsServiceManagerUtils.h" #include "nsIScreenManager.h" -#ifdef ANDROID -#include -#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoVR" , ## args) -#else -#define LOG(...) do { } while(0) -#endif - -// 1/sqrt(2) (aka sqrt(2)/2) -#ifndef M_SQRT1_2 -# define M_SQRT1_2 0.70710678118654752440 -#endif - using namespace mozilla::dom; using namespace mozilla::gfx; using namespace mozilla::gfx::impl; -namespace { -// some utility functions - -// This remaps axes in the given matrix to a new configuration based on the -// screen orientation. Similar to what Android SensorManager.remapCoordinateSystem -// does, except only for a fixed number of transforms that we need. -Matrix4x4 -RemapMatrixForOrientation(ScreenOrientationInternal screenConfig, const Matrix4x4& aMatrix) -{ - Matrix4x4 out; - const float *in = &aMatrix._11; - float *o = &out._11; - - if (screenConfig == eScreenOrientation_LandscapePrimary) { - // remap X,Y -> Y,-X - o[0] = -in[1]; o[1] = in[0]; o[2] = in[2]; - o[4] = -in[5]; o[5] = in[4]; o[6] = in[6]; - o[8] = -in[9]; o[9] = in[8]; o[10] = in[10]; - } else if (screenConfig == eScreenOrientation_LandscapeSecondary) { - // remap X,Y -> -Y,X - o[0] = in[1]; o[1] = -in[0]; o[2] = in[2]; - o[4] = in[5]; o[5] = -in[4]; o[6] = in[6]; - o[8] = in[9]; o[9] = -in[8]; o[10] = in[10]; - } else if (screenConfig == eScreenOrientation_PortraitPrimary) { - out = aMatrix; - } else if (screenConfig == eScreenOrientation_PortraitSecondary) { - // remap X,Y -> X,-Z - o[0] = in[0]; o[1] = in[2]; o[2] = -in[1]; - o[4] = in[4]; o[5] = in[6]; o[6] = -in[5]; - o[8] = in[8]; o[9] = in[10]; o[10] = -in[9]; - } else { - MOZ_ASSERT(0, "gfxVRCardboard::RemapMatrixForOrientation invalid screenConfig"); - } - - return out; -} - -} // namespace - HMDInfoCardboard::HMDInfoCardboard() - : VRHMDInfo(VRHMDType::Cardboard) - , mStartCount(0) - , mOrient(eScreenOrientation_PortraitPrimary) + : VRHMDInfo(VRHMDType::Cardboard, true) { MOZ_ASSERT(sizeof(HMDInfoCardboard::DistortionVertex) == sizeof(VRDistortionVertex), "HMDInfoCardboard::DistortionVertex must match the size of VRDistortionVertex"); MOZ_COUNT_CTOR_INHERITED(HMDInfoCardboard, VRHMDInfo); - mDeviceName.AssignLiteral("Phone Sensor (Cardboard) HMD"); + mDeviceInfo.mDeviceName.AssignLiteral("Phone Sensor (Cardboard) HMD"); - mSupportedSensorBits = State_Orientation; + mDeviceInfo.mSupportedSensorBits = VRStateValidFlags::State_Orientation; - mRecommendedEyeFOV[Eye_Left] = VRFieldOfView(45.0, 45.0, 45.0, 45.0); - mRecommendedEyeFOV[Eye_Right] = VRFieldOfView(45.0, 45.0, 45.0, 45.0); + mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Left] = gfx::VRFieldOfView(45.0, 45.0, 45.0, 45.0); + mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Right] = gfx::VRFieldOfView(45.0, 45.0, 45.0, 45.0); - mMaximumEyeFOV[Eye_Left] = VRFieldOfView(45.0, 45.0, 45.0, 45.0); - mMaximumEyeFOV[Eye_Right] = VRFieldOfView(45.0, 45.0, 45.0, 45.0); + mDeviceInfo.mMaximumEyeFOV[VRDeviceInfo::Eye_Left] = gfx::VRFieldOfView(45.0, 45.0, 45.0, 45.0); + mDeviceInfo.mMaximumEyeFOV[VRDeviceInfo::Eye_Right] = gfx::VRFieldOfView(45.0, 45.0, 45.0, 45.0); - SetFOV(mRecommendedEyeFOV[Eye_Left], mRecommendedEyeFOV[Eye_Right], 0.01, 10000.0); - -#if 1 - int32_t xcoord = 0; - if (PR_GetEnv("FAKE_CARDBOARD_SCREEN")) { - const char *env = PR_GetEnv("FAKE_CARDBOARD_SCREEN"); - nsresult err; - xcoord = nsCString(env).ToInteger(&err); - if (err != NS_OK) xcoord = 0; - } - mScreen = VRHMDManager::MakeFakeScreen(xcoord, 0, 1920, 1080); -#endif + SetFOV(mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Left], mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Right], 0.01, 10000.0); + mDeviceInfo.mScreenRect.x = 0; + mDeviceInfo.mScreenRect.y = 0; + mDeviceInfo.mScreenRect.width = 1920; + mDeviceInfo.mScreenRect.height = 1080; + mDeviceInfo.mIsFakeScreen = true; } -bool -HMDInfoCardboard::StartSensorTracking() -{ - LOG("HMDInfoCardboard::StartSensorTracking %d\n", mStartCount); - if (mStartCount == 0) { - // it's never been started before; initialize observers and - // initial state. - - mozilla::hal::ScreenConfiguration sconfig; - mozilla::hal::GetCurrentScreenConfiguration(&sconfig); - this->Notify(sconfig); - - mozilla::hal::RegisterSensorObserver(mozilla::hal::SENSOR_GAME_ROTATION_VECTOR, this); - mozilla::hal::RegisterScreenConfigurationObserver(this); - - mLastSensorState.Clear(); - } - - mStartCount++; - return true; -} - -// Android sends us events that have a 90-degree rotation about -// the x axis compared to what we want (phone flat vs. phone held in front of the eyes). -// Correct for this by applying a transform to undo this rotation. -void -HMDInfoCardboard::Notify(const mozilla::hal::ScreenConfiguration& config) -{ - mOrient = config.orientation(); - - if (mOrient == eScreenOrientation_LandscapePrimary) { - mScreenTransform = Quaternion(-0.5f, 0.5f, 0.5f, 0.5f); - } else if (mOrient == eScreenOrientation_LandscapeSecondary) { - mScreenTransform = Quaternion(-0.5f, -0.5f, -0.5f, 0.5f); - } else if (mOrient == eScreenOrientation_PortraitPrimary) { - mScreenTransform = Quaternion((float) -M_SQRT1_2, 0.f, 0.f, (float) M_SQRT1_2); - } else if (mOrient == eScreenOrientation_PortraitSecondary) { - // Currently, PortraitSecondary event doesn't be triggered. - mScreenTransform = Quaternion((float) M_SQRT1_2, 0.f, 0.f, (float) M_SQRT1_2); - } -} - -void -HMDInfoCardboard::Notify(const mozilla::hal::SensorData& data) -{ - if (data.sensor() != mozilla::hal::SENSOR_GAME_ROTATION_VECTOR) - return; - - const nsTArray& sensorValues = data.values(); - - // This is super chatty - //LOG("HMDInfoCardboard::Notify %f %f %f %f\n", sensorValues[0], sensorValues[1], sensorValues[2], sensorValues[3]); - - mSavedLastSensor.Set(sensorValues[0], sensorValues[1], sensorValues[2], sensorValues[3]); - mSavedLastSensorTime = data.timestamp(); - mNeedsSensorCompute = true; -} - -void -HMDInfoCardboard::ComputeStateFromLastSensor() -{ - if (!mNeedsSensorCompute) - return; - - // apply the zero orientation - Quaternion q = mSensorZeroInverse * mSavedLastSensor; - - // make a matrix from the quat - Matrix4x4 qm; - qm.SetRotationFromQuaternion(q); - - // remap the coordinate space, based on the orientation - Matrix4x4 qmRemapped = RemapMatrixForOrientation(mOrient, qm); - - // turn it back into a quat - q.SetFromRotationMatrix(qmRemapped); - - // apply adjustment based on what's been done to the screen and the original zero - // position of the base coordinate space - q = mScreenTransform * q; - - VRHMDSensorState& state = mLastSensorState; - - state.flags |= State_Orientation; - state.orientation[0] = q.x; - state.orientation[1] = q.y; - state.orientation[2] = q.z; - state.orientation[3] = q.w; - - state.timestamp = mSavedLastSensorTime / 1000000.0; - - mNeedsSensorCompute = false; -} VRHMDSensorState HMDInfoCardboard::GetSensorState(double timeOffset) { - ComputeStateFromLastSensor(); - return mLastSensorState; -} - -void -HMDInfoCardboard::StopSensorTracking() -{ - LOG("HMDInfoCardboard::StopSensorTracking, count %d\n", mStartCount); - if (--mStartCount == 0) { - mozilla::hal::UnregisterScreenConfigurationObserver(this); - mozilla::hal::UnregisterSensorObserver(mozilla::hal::SENSOR_GAME_ROTATION_VECTOR, this); - } + // Actual sensor state is calculated on the main thread, + // within VRDeviceProxyOrientationFallBack + VRHMDSensorState result; + result.Clear(); + return result; } void HMDInfoCardboard::ZeroSensor() { - mSensorZeroInverse = mSavedLastSensor; - mSensorZeroInverse.Invert(); + MOZ_ASSERT(0, "HMDInfoCardboard::ZeroSensor not implemented. " + "Should use VRDeviceProxyOrientationFallBack on main thread"); +} + + +void +HMDInfoCardboard::NotifyVsync(const TimeStamp& aVsyncTimestamp) +{ + // Nothing to do here for Cardboard VR } bool -HMDInfoCardboard::SetFOV(const VRFieldOfView& aFOVLeft, - const VRFieldOfView& aFOVRight, +HMDInfoCardboard::KeepSensorTracking() +{ + // Nothing to do here for Cardboard VR + return true; +} + +bool +HMDInfoCardboard::SetFOV(const gfx::VRFieldOfView& aFOVLeft, + const gfx::VRFieldOfView& aFOVRight, double zNear, double zFar) { const float standardIPD = 0.064f; - for (uint32_t eye = 0; eye < NumEyes; eye++) { - mEyeFOV[eye] = eye == Eye_Left ? aFOVLeft : aFOVRight; - mEyeTranslation[eye] = Point3D(standardIPD * (eye == Eye_Left ? -1.0 : 1.0), 0.0, 0.0); - mEyeProjectionMatrix[eye] = mEyeFOV[eye].ConstructProjectionMatrix(zNear, zFar, true); + for (uint32_t eye = 0; eye < VRDeviceInfo::NumEyes; eye++) { + mDeviceInfo.mEyeFOV[eye] = eye == VRDeviceInfo::Eye_Left ? aFOVLeft : aFOVRight; + mDeviceInfo.mEyeTranslation[eye] = Point3D(standardIPD * (eye == VRDeviceInfo::Eye_Left ? -1.0 : 1.0), 0.0, 0.0); + mDeviceInfo.mEyeProjectionMatrix[eye] = mDeviceInfo.mEyeFOV[eye].ConstructProjectionMatrix(zNear, zFar, true); mDistortionMesh[eye].mVertices.SetLength(4); mDistortionMesh[eye].mIndices.SetLength(6); HMDInfoCardboard::DistortionVertex *destv = reinterpret_cast(mDistortionMesh[eye].mVertices.Elements()); - float xoffs = eye == Eye_Left ? 0.0f : 1.0f; - float txoffs = eye == Eye_Left ? 0.0f : 0.5f; + float xoffs = eye == VRDeviceInfo::Eye_Left ? 0.0f : 1.0f; + float txoffs = eye == VRDeviceInfo::Eye_Left ? 0.0f : 0.5f; destv[0].pos[0] = -1.0 + xoffs; destv[0].pos[1] = -1.0; destv[0].texR[0] = destv[0].texG[0] = destv[0].texB[0] = 0.0 + txoffs; @@ -275,16 +129,16 @@ HMDInfoCardboard::SetFOV(const VRFieldOfView& aFOVLeft, } // XXX find out the default screen size and use that - mEyeResolution.width = 1920 / 2; - mEyeResolution.height = 1080; + mDeviceInfo.mEyeResolution.width = 1920 / 2; + mDeviceInfo.mEyeResolution.height = 1080; if (PR_GetEnv("FAKE_CARDBOARD_SCREEN")) { // for testing, make the eye resolution 2x of the screen - mEyeResolution.width *= 2; - mEyeResolution.height *= 2; + mDeviceInfo.mEyeResolution.width *= 2; + mDeviceInfo.mEyeResolution.height *= 2; } - mConfiguration.hmdType = mType; + mConfiguration.hmdType = mDeviceInfo.mType; mConfiguration.value = 0; mConfiguration.fov[0] = aFOVLeft; mConfiguration.fov[1] = aFOVRight; @@ -332,19 +186,26 @@ HMDInfoCardboard::Destroy() { } - - -bool -VRHMDManagerCardboard::PlatformInit() +/*static*/ already_AddRefed +VRHMDManagerCardboard::Create() { - return gfxPrefs::VREnabled() && gfxPrefs::VRCardboardEnabled(); + MOZ_ASSERT(NS_IsMainThread()); + + if (!gfxPrefs::VREnabled() || !gfxPrefs::VRCardboardEnabled()) + { + return nullptr; + } + + RefPtr manager = new VRHMDManagerCardboard(); + return manager.forget(); } bool VRHMDManagerCardboard::Init() { - if (mCardboardInitialized) + if (mCardboardInitialized) { return true; + } RefPtr hmd = new HMDInfoCardboard(); mCardboardHMDs.AppendElement(hmd); @@ -370,7 +231,10 @@ VRHMDManagerCardboard::Destroy() void VRHMDManagerCardboard::GetHMDs(nsTArray>& aHMDResult) { - Init(); + if (!mCardboardInitialized) { + return; + } + for (size_t i = 0; i < mCardboardHMDs.Length(); ++i) { aHMDResult.AppendElement(mCardboardHMDs[i]); } diff --git a/gfx/vr/gfxVRCardboard.h b/gfx/vr/gfxVRCardboard.h index 76065a8d80..822a5b209a 100644 --- a/gfx/vr/gfxVRCardboard.h +++ b/gfx/vr/gfxVRCardboard.h @@ -9,8 +9,6 @@ #include "mozilla/gfx/2D.h" #include "mozilla/gfx/Quaternion.h" #include "mozilla/EnumeratedArray.h" -#include "mozilla/HalSensor.h" -#include "mozilla/HalScreenConfiguration.h" #include "gfxVR.h" @@ -19,9 +17,7 @@ namespace gfx { namespace impl { class HMDInfoCardboard : - public VRHMDInfo, - public hal::ISensorObserver, - public hal::ScreenConfigurationObserver + public VRHMDInfo { public: explicit HMDInfoCardboard(); @@ -29,10 +25,10 @@ public: bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight, double zNear, double zFar) override; - bool StartSensorTracking() override; VRHMDSensorState GetSensorState(double timeOffset) override; - void StopSensorTracking() override; void ZeroSensor() override; + bool KeepSensorTracking() override; + void NotifyVsync(const TimeStamp& aVsyncTimestamp) override; void FillDistortionConstants(uint32_t whichEye, const IntSize& textureSize, const IntRect& eyeViewport, @@ -41,12 +37,12 @@ public: void Destroy(); - // ISensorObserver interface - void Notify(const hal::SensorData& SensorData) override; - // ScreenConfigurationObserver interface - void Notify(const hal::ScreenConfiguration& ScreenConfiguration) override; - protected: + virtual ~HMDInfoCardboard() { + MOZ_COUNT_DTOR_INHERITED(HMDInfoCardboard, VRHMDInfo); + Destroy(); + } + // must match the size of VRDistortionVertex struct DistortionVertex { float pos[2]; @@ -56,21 +52,6 @@ protected: float padding[4]; }; - virtual ~HMDInfoCardboard() { - Destroy(); - } - - void ComputeStateFromLastSensor(); - - uint32_t mStartCount; - VRHMDSensorState mLastSensorState; - uint32_t mOrient; - Quaternion mScreenTransform; - Quaternion mSensorZeroInverse; - - Quaternion mSavedLastSensor; - double mSavedLastSensorTime; - bool mNeedsSensorCompute; // if we need to compute the state from mSavedLastSensor }; } // namespace impl @@ -78,15 +59,14 @@ protected: class VRHMDManagerCardboard : public VRHMDManager { public: - VRHMDManagerCardboard() - : mCardboardInitialized(false) - { } - - virtual bool PlatformInit() override; + static already_AddRefed Create(); virtual bool Init() override; virtual void Destroy() override; virtual void GetHMDs(nsTArray >& aHMDResult) override; protected: + VRHMDManagerCardboard() + : mCardboardInitialized(false) + { } nsTArray> mCardboardHMDs; bool mCardboardInitialized; }; diff --git a/gfx/vr/gfxVROculus.cpp b/gfx/vr/gfxVROculus.cpp index e8b596d7e5..35169aae27 100644 --- a/gfx/vr/gfxVROculus.cpp +++ b/gfx/vr/gfxVROculus.cpp @@ -11,6 +11,7 @@ #include "gfxPrefs.h" #include "nsString.h" #include "mozilla/Preferences.h" +#include "mozilla/TimeStamp.h" #include "mozilla/gfx/Quaternion.h" @@ -20,9 +21,6 @@ #include "gfxVROculus.h" -#include "nsServiceManagerUtils.h" -#include "nsIScreenManager.h" - #ifndef M_PI # define M_PI 3.14159265358979323846 #endif @@ -111,7 +109,7 @@ InitializeOculusCAPI() libSearchPaths.AppendElement(nsCString("/usr/lib")); libName.AppendPrintf("libOVRRT%d_%d.so.%d", BUILD_BITS, OVR_PRODUCT_VERSION, OVR_MAJOR_VERSION); #endif - + // If the pref is present, we override libName nsAdoptingCString prefLibPath = mozilla::Preferences::GetCString("dom.vr.ovr_lib_path"); if (prefLibPath && prefLibPath.get()) { @@ -227,7 +225,7 @@ do_CalcEyePoses(ovrPosef headPose, } ovrFovPort -ToFovPort(const VRFieldOfView& aFOV) +ToFovPort(const gfx::VRFieldOfView& aFOV) { ovrFovPort fovPort; fovPort.LeftTan = tan(aFOV.leftDegrees * M_PI / 180.0); @@ -237,10 +235,10 @@ ToFovPort(const VRFieldOfView& aFOV) return fovPort; } -VRFieldOfView +gfx::VRFieldOfView FromFovPort(const ovrFovPort& aFOV) { - VRFieldOfView fovInfo; + gfx::VRFieldOfView fovInfo; fovInfo.leftDegrees = atan(aFOV.LeftTan) * 180.0 / M_PI; fovInfo.rightDegrees = atan(aFOV.RightTan) * 180.0 / M_PI; fovInfo.upDegrees = atan(aFOV.UpTan) * 180.0 / M_PI; @@ -250,53 +248,66 @@ FromFovPort(const ovrFovPort& aFOV) } // namespace -HMDInfoOculus::HMDInfoOculus(ovrHmd aHMD) - : VRHMDInfo(VRHMDType::Oculus) +HMDInfoOculus::HMDInfoOculus(ovrHmd aHMD, bool aDebug, int aDeviceID) + : VRHMDInfo(VRHMDType::Oculus, false) , mHMD(aHMD) - , mStartCount(0) + , mTracking(false) + , mDebug(aDebug) + , mDeviceID(aDeviceID) + , mSensorTrackingFramesRemaining(0) { MOZ_ASSERT(sizeof(HMDInfoOculus::DistortionVertex) == sizeof(VRDistortionVertex), "HMDInfoOculus::DistortionVertex must match the size of VRDistortionVertex"); MOZ_COUNT_CTOR_INHERITED(HMDInfoOculus, VRHMDInfo); - mDeviceName.AssignLiteral("Oculus VR HMD"); - - mSupportedSensorBits = 0; - if (mHMD->TrackingCaps & ovrTrackingCap_Orientation) - mSupportedSensorBits |= State_Orientation; - if (mHMD->TrackingCaps & ovrTrackingCap_Position) - mSupportedSensorBits |= State_Position; - - mRecommendedEyeFOV[Eye_Left] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Left]); - mRecommendedEyeFOV[Eye_Right] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Right]); - - mMaximumEyeFOV[Eye_Left] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Left]); - mMaximumEyeFOV[Eye_Right] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Right]); - - SetFOV(mRecommendedEyeFOV[Eye_Left], mRecommendedEyeFOV[Eye_Right], 0.01, 10000.0); - -#if 1 - int32_t xcoord = 0; - if (getenv("FAKE_OCULUS_SCREEN")) { - const char *env = getenv("FAKE_OCULUS_SCREEN"); - nsresult err; - xcoord = nsCString(env).ToInteger(&err); - if (err != NS_OK) xcoord = 0; + if (aDebug) { + mDeviceInfo.mDeviceName.AssignLiteral("Oculus VR HMD Debug)"); + } else { + mDeviceInfo.mDeviceName.AssignLiteral("Oculus VR HMD"); } + + mDeviceInfo.mSupportedSensorBits = VRStateValidFlags::State_None; + if (mHMD->TrackingCaps & ovrTrackingCap_Orientation) { + mDeviceInfo.mSupportedSensorBits |= VRStateValidFlags::State_Orientation; + } + if (mHMD->TrackingCaps & ovrTrackingCap_Position) { + mDeviceInfo.mSupportedSensorBits |= VRStateValidFlags::State_Position; + } + + mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Left] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Left]); + mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Right] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Right]); + + mDeviceInfo.mMaximumEyeFOV[VRDeviceInfo::Eye_Left] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Left]); + mDeviceInfo.mMaximumEyeFOV[VRDeviceInfo::Eye_Right] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Right]); + uint32_t w = mHMD->Resolution.w; uint32_t h = mHMD->Resolution.h; - mScreen = VRHMDManager::MakeFakeScreen(xcoord, 0, std::max(w, h), std::min(w, h)); + mDeviceInfo.mScreenRect.x = 0; + mDeviceInfo.mScreenRect.y = 0; + mDeviceInfo.mScreenRect.width = std::max(w, h); + mDeviceInfo.mScreenRect.height = std::min(w, h); + mDeviceInfo.mIsFakeScreen = true; -#ifdef DEBUG - printf_stderr("OCULUS SCREEN: %d %d %d %d\n", xcoord, 0, std::max(w, h), std::min(w, h)); -#endif -#endif + SetFOV(mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Left], mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Right], 0.01, 10000.0); +} + +bool +HMDInfoOculus::GetIsDebug() const +{ + return mDebug; +} + +int +HMDInfoOculus::GetDeviceID() const +{ + return mDeviceID; } void HMDInfoOculus::Destroy() { + StopSensorTracking(); if (mHMD) { ovrHmd_Destroy(mHMD); mHMD = nullptr; @@ -304,33 +315,33 @@ HMDInfoOculus::Destroy() } bool -HMDInfoOculus::SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight, +HMDInfoOculus::SetFOV(const gfx::VRFieldOfView& aFOVLeft, const gfx::VRFieldOfView& aFOVRight, double zNear, double zFar) { float pixelsPerDisplayPixel = 1.0; ovrSizei texSize[2]; // get eye parameters and create the mesh - for (uint32_t eye = 0; eye < NumEyes; eye++) { - mEyeFOV[eye] = eye == 0 ? aFOVLeft : aFOVRight; - mFOVPort[eye] = ToFovPort(mEyeFOV[eye]); + for (uint32_t eye = 0; eye < VRDeviceInfo::NumEyes; eye++) { + mDeviceInfo.mEyeFOV[eye] = eye == 0 ? aFOVLeft : aFOVRight; + mFOVPort[eye] = ToFovPort(mDeviceInfo.mEyeFOV[eye]); ovrEyeRenderDesc renderDesc = ovrHmd_GetRenderDesc(mHMD, (ovrEyeType) eye, mFOVPort[eye]); // As of Oculus 0.6.0, the HmdToEyeViewOffset values are correct and don't need to be negated. - mEyeTranslation[eye] = Point3D(renderDesc.HmdToEyeViewOffset.x, renderDesc.HmdToEyeViewOffset.y, renderDesc.HmdToEyeViewOffset.z); + mDeviceInfo.mEyeTranslation[eye] = Point3D(renderDesc.HmdToEyeViewOffset.x, renderDesc.HmdToEyeViewOffset.y, renderDesc.HmdToEyeViewOffset.z); // note that we are using a right-handed coordinate system here, to match CSS - mEyeProjectionMatrix[eye] = mEyeFOV[eye].ConstructProjectionMatrix(zNear, zFar, true); + mDeviceInfo.mEyeProjectionMatrix[eye] = mDeviceInfo.mEyeFOV[eye].ConstructProjectionMatrix(zNear, zFar, true); texSize[eye] = ovrHmd_GetFovTextureSize(mHMD, (ovrEyeType) eye, mFOVPort[eye], pixelsPerDisplayPixel); } // take the max of both for eye resolution - mEyeResolution.width = std::max(texSize[Eye_Left].w, texSize[Eye_Right].w); - mEyeResolution.height = std::max(texSize[Eye_Left].h, texSize[Eye_Right].h); + mDeviceInfo.mEyeResolution.width = std::max(texSize[VRDeviceInfo::Eye_Left].w, texSize[VRDeviceInfo::Eye_Right].w); + mDeviceInfo.mEyeResolution.height = std::max(texSize[VRDeviceInfo::Eye_Left].h, texSize[VRDeviceInfo::Eye_Right].h); - mConfiguration.hmdType = mType; + mConfiguration.hmdType = mDeviceInfo.mType; mConfiguration.value = 0; mConfiguration.fov[0] = aFOVLeft; mConfiguration.fov[1] = aFOVRight; @@ -349,23 +360,51 @@ HMDInfoOculus::FillDistortionConstants(uint32_t whichEye, } bool -HMDInfoOculus::StartSensorTracking() +HMDInfoOculus::KeepSensorTracking() { - if (mStartCount == 0) { - bool ok = ovrHmd_ConfigureTracking(mHMD, ovrTrackingCap_Orientation | ovrTrackingCap_Position, 0); - if (!ok) - return false; + // Keep sensor tracking alive for short time after the last request for + // tracking state by content. Value conservatively high to accomodate + // potentially high frame rates. + const uint32_t kKeepAliveFrames = 200; + + bool success = true; + if (mSensorTrackingFramesRemaining == 0) { + success = StartSensorTracking(); + } + if (success) { + mSensorTrackingFramesRemaining = kKeepAliveFrames; } - mStartCount++; - return true; + return success; +} + +void +HMDInfoOculus::NotifyVsync(const mozilla::TimeStamp& aVsyncTimestamp) +{ + if (mSensorTrackingFramesRemaining == 1) { + StopSensorTracking(); + } + if (mSensorTrackingFramesRemaining) { + --mSensorTrackingFramesRemaining; + } +} + +bool +HMDInfoOculus::StartSensorTracking() +{ + if (!mTracking) { + mTracking = ovrHmd_ConfigureTracking(mHMD, ovrTrackingCap_Orientation | ovrTrackingCap_Position, 0); + } + + return mTracking; } void HMDInfoOculus::StopSensorTracking() { - if (--mStartCount == 0) { + if (mTracking) { ovrHmd_ConfigureTracking(mHMD, 0, 0); + mTracking = false; } } @@ -389,7 +428,7 @@ HMDInfoOculus::GetSensorState(double timeOffset) result.timestamp = pose.TimeInSeconds; if (state.StatusFlags & ovrStatus_OrientationTracked) { - result.flags |= State_Orientation; + result.flags |= VRStateValidFlags::State_Orientation; result.orientation[0] = pose.ThePose.Orientation.x; result.orientation[1] = pose.ThePose.Orientation.y; @@ -406,7 +445,7 @@ HMDInfoOculus::GetSensorState(double timeOffset) } if (state.StatusFlags & ovrStatus_PositionTracked) { - result.flags |= State_Position; + result.flags |= VRStateValidFlags::State_Position; result.position[0] = pose.ThePose.Position.x; result.position[1] = pose.ThePose.Position.y; @@ -561,8 +600,8 @@ HMDInfoOculus::SubmitFrame(RenderTargetSet *aRTSet) layer.Viewport[1].Size.w = rts->size.width / 2; layer.Viewport[1].Size.h = rts->size.height; - const Point3D& l = rts->hmd->mEyeTranslation[0]; - const Point3D& r = rts->hmd->mEyeTranslation[1]; + const Point3D& l = rts->hmd->mDeviceInfo.mEyeTranslation[0]; + const Point3D& r = rts->hmd->mDeviceInfo.mEyeTranslation[1]; const ovrVector3f hmdToEyeViewOffset[2] = { { l.x, l.y, l.z }, { r.x, r.y, r.z } }; do_CalcEyePoses(rts->hmd->mLastTrackingState.HeadPose.ThePose, hmdToEyeViewOffset, layer.RenderPose); @@ -575,95 +614,127 @@ HMDInfoOculus::SubmitFrame(RenderTargetSet *aRTSet) } } -bool -VRHMDManagerOculus::PlatformInit() +/*static*/ already_AddRefed +VRHMDManagerOculus::Create() { - if (mOculusPlatformInitialized) - return true; + MOZ_ASSERT(NS_IsMainThread()); - if (!gfxPrefs::VREnabled() || - !gfxPrefs::VROculusEnabled()) + if (!gfxPrefs::VREnabled() || !gfxPrefs::VROculusEnabled()) { - return false; + return nullptr; } - if (!InitializeOculusCAPI()) - return false; + if (!InitializeOculusCAPI()) { + return nullptr; + } - ovrInitParams params; - params.Flags = ovrInit_RequestVersion; - params.RequestedMinorVersion = OVR_MINOR_VERSION; - params.LogCallback = nullptr; - params.ConnectionTimeoutMS = 0; - - ovrResult orv = ovr_Initialize(¶ms); - - if (orv != ovrSuccess) - return false; - - mOculusPlatformInitialized = true; - return true; + RefPtr manager = new VRHMDManagerOculus(); + return manager.forget(); } bool VRHMDManagerOculus::Init() { - if (mOculusInitialized) - return true; + if (!mOculusInitialized) { + nsIThread* thread = nullptr; + NS_GetCurrentThread(&thread); + mOculusThread = already_AddRefed(thread); - if (!PlatformInit()) - return false; + ovrInitParams params; + params.Flags = ovrInit_RequestVersion; + params.RequestedMinorVersion = OVR_MINOR_VERSION; + params.LogCallback = nullptr; + params.ConnectionTimeoutMS = 0; + + ovrResult orv = ovr_Initialize(¶ms); + + if (orv == ovrSuccess) { + mOculusInitialized = true; + } + } + + return mOculusInitialized; +} + +void +VRHMDManagerOculus::Destroy() +{ + if(mOculusInitialized) { + MOZ_ASSERT(NS_GetCurrentThread() == mOculusThread); + mOculusThread = nullptr; + + for (size_t i = 0; i < mOculusHMDs.Length(); ++i) { + mOculusHMDs[i]->Destroy(); + } + + mOculusHMDs.Clear(); + + ovr_Shutdown(); + mOculusInitialized = false; + } +} + +void +VRHMDManagerOculus::GetHMDs(nsTArray>& aHMDResult) +{ + if (!mOculusInitialized) { + return; + } + + nsTArray > newHMDs; ovrResult orv; + int count = ovrHmd_Detect(); - - for (int i = 0; i < count; ++i) { - ovrHmd hmd; - orv = ovrHmd_Create(i, &hmd); - if (orv == ovrSuccess) { - RefPtr oc = new HMDInfoOculus(hmd); - mOculusHMDs.AppendElement(oc); + + for (int j = 0; j < count; ++j) { + bool is_new = true; + for (size_t i = 0; i < mOculusHMDs.Length(); ++i) { + if (mOculusHMDs[i]->GetDeviceID() == j) { + newHMDs.AppendElement(mOculusHMDs[i]); + is_new = false; + break; + } + } + + if (is_new) { + ovrHmd hmd; + orv = ovrHmd_Create(j, &hmd); + if (orv == ovrSuccess) { + RefPtr oc = new HMDInfoOculus(hmd, false, j); + newHMDs.AppendElement(oc); + } } } // VRAddTestDevices == 1: add test device only if no real devices present // VRAddTestDevices == 2: add test device always if ((count == 0 && gfxPrefs::VRAddTestDevices() == 1) || - (gfxPrefs::VRAddTestDevices() == 2)) + (gfxPrefs::VRAddTestDevices() == 2)) { - ovrHmd hmd; - orv = ovrHmd_CreateDebug(ovrHmd_DK2, &hmd); - if (orv == ovrSuccess) { - RefPtr oc = new HMDInfoOculus(hmd); - mOculusHMDs.AppendElement(oc); + // Keep existing debug HMD if possible + bool foundDebug = false; + for (size_t i = 0; i < mOculusHMDs.Length(); ++i) { + if (mOculusHMDs[i]->GetIsDebug()) { + newHMDs.AppendElement(mOculusHMDs[i]); + foundDebug = true; + } + } + + // If there isn't already a debug HMD, create one + if (!foundDebug) { + ovrHmd hmd; + orv = ovrHmd_CreateDebug(ovrHmd_DK2, &hmd); + if (orv == ovrSuccess) { + RefPtr oc = new HMDInfoOculus(hmd, true, -1); + newHMDs.AppendElement(oc); + } } } - mOculusInitialized = true; - return true; -} + mOculusHMDs = newHMDs; -void -VRHMDManagerOculus::Destroy() -{ - if (!mOculusInitialized) - return; - - for (size_t i = 0; i < mOculusHMDs.Length(); ++i) { - mOculusHMDs[i]->Destroy(); - } - - mOculusHMDs.Clear(); - - ovr_Shutdown(); - mOculusInitialized = false; -} - -void -VRHMDManagerOculus::GetHMDs(nsTArray>& aHMDResult) -{ - Init(); - for (size_t i = 0; i < mOculusHMDs.Length(); ++i) { - aHMDResult.AppendElement(mOculusHMDs[i]); + for (size_t j = 0; j < mOculusHMDs.Length(); ++j) { + aHMDResult.AppendElement(mOculusHMDs[j]); } } diff --git a/gfx/vr/gfxVROculus.h b/gfx/vr/gfxVROculus.h index a472e7e5c0..775d293ec1 100644 --- a/gfx/vr/gfxVROculus.h +++ b/gfx/vr/gfxVROculus.h @@ -7,8 +7,6 @@ #define GFX_VR_OCULUS_H #include "nsTArray.h" -#include "nsIScreen.h" -#include "nsCOMPtr.h" #include "mozilla/RefPtr.h" #include "mozilla/gfx/2D.h" @@ -25,15 +23,15 @@ namespace impl { class HMDInfoOculus : public VRHMDInfo, public VRHMDRenderingSupport { public: - explicit HMDInfoOculus(ovrHmd aHMD); + explicit HMDInfoOculus(ovrHmd aHMD, bool aDebug, int aDeviceID); bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight, double zNear, double zFar) override; - bool StartSensorTracking() override; VRHMDSensorState GetSensorState(double timeOffset) override; - void StopSensorTracking() override; void ZeroSensor() override; + bool KeepSensorTracking() override; + void NotifyVsync(const TimeStamp& aVsyncTimestamp) override; void FillDistortionConstants(uint32_t whichEye, const IntSize& textureSize, const IntRect& eyeViewport, @@ -50,8 +48,18 @@ public: void SubmitFrame(RenderTargetSet *aRTSet) override; ovrHmd GetOculusHMD() const { return mHMD; } + bool GetIsDebug() const; + int GetDeviceID() const; protected: + virtual ~HMDInfoOculus() { + Destroy(); + MOZ_COUNT_DTOR_INHERITED(HMDInfoOculus, VRHMDInfo); + } + + bool StartSensorTracking(); + void StopSensorTracking(); + // must match the size of VRDistortionVertex struct DistortionVertex { float pos[2]; @@ -61,15 +69,15 @@ protected: float genericAttribs[4]; }; - virtual ~HMDInfoOculus() { - Destroy(); - MOZ_COUNT_DTOR_INHERITED(HMDInfoOculus, VRHMDInfo); - } - ovrHmd mHMD; ovrFovPort mFOVPort[2]; - uint32_t mStartCount; + bool mTracking; ovrTrackingState mLastTrackingState; + + bool mDebug; // True if this is a debug HMD + int mDeviceID; // Index of device passed to ovrHmd_Create + + uint32_t mSensorTrackingFramesRemaining; }; } // namespace impl @@ -77,18 +85,18 @@ protected: class VRHMDManagerOculus : public VRHMDManager { public: - VRHMDManagerOculus() - : mOculusInitialized(false), mOculusPlatformInitialized(false) - { } - - virtual bool PlatformInit() override; + static already_AddRefed Create(); virtual bool Init() override; virtual void Destroy() override; virtual void GetHMDs(nsTArray >& aHMDResult) override; protected: + VRHMDManagerOculus() + : mOculusInitialized(false) + { } + nsTArray> mOculusHMDs; bool mOculusInitialized; - bool mOculusPlatformInitialized; + RefPtr mOculusThread; }; } // namespace gfx diff --git a/gfx/vr/gfxVROculus050.cpp b/gfx/vr/gfxVROculus050.cpp index 9f64458a63..e3542632e7 100644 --- a/gfx/vr/gfxVROculus050.cpp +++ b/gfx/vr/gfxVROculus050.cpp @@ -14,12 +14,10 @@ #include "gfxPrefs.h" #include "nsString.h" #include "mozilla/Preferences.h" +#include "mozilla/TimeStamp.h" #include "gfxVROculus050.h" -#include "nsServiceManagerUtils.h" -#include "nsIScreenManager.h" - #ifndef M_PI # define M_PI 3.14159265358979323846 #endif @@ -240,54 +238,65 @@ FromFovPort(const ovrFovPort& aFOV) } // anonymous namespace -HMDInfoOculus050::HMDInfoOculus050(ovrHmd aHMD) - : VRHMDInfo(VRHMDType::Oculus050) +HMDInfoOculus050::HMDInfoOculus050(ovrHmd aHMD, bool aDebug, int aDeviceID) + : VRHMDInfo(VRHMDType::Oculus050, false) , mHMD(aHMD) - , mStartCount(0) + , mTracking(false) + , mDebug(aDebug) + , mDeviceID(aDeviceID) + , mSensorTrackingFramesRemaining(0) { MOZ_ASSERT(sizeof(HMDInfoOculus050::DistortionVertex) == sizeof(VRDistortionVertex), "HMDInfoOculus050::DistortionVertex must match the size of VRDistortionVertex"); MOZ_COUNT_CTOR_INHERITED(HMDInfoOculus050, VRHMDInfo); - mDeviceName.AssignLiteral("Oculus VR HMD (0.5.0)"); - - mSupportedSensorBits = 0; - if (mHMD->TrackingCaps & ovrTrackingCap_Orientation) - mSupportedSensorBits |= State_Orientation; - if (mHMD->TrackingCaps & ovrTrackingCap_Position) - mSupportedSensorBits |= State_Position; - - mRecommendedEyeFOV[Eye_Left] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Left]); - mRecommendedEyeFOV[Eye_Right] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Right]); - - mMaximumEyeFOV[Eye_Left] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Left]); - mMaximumEyeFOV[Eye_Right] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Right]); - - SetFOV(mRecommendedEyeFOV[Eye_Left], mRecommendedEyeFOV[Eye_Right], 0.01, 10000.0); - - nsCOMPtr screenmgr = do_GetService("@mozilla.org/gfx/screenmanager;1"); - if (screenmgr) { -#if 1 - if (getenv("FAKE_OCULUS_SCREEN")) { - const char *env = getenv("FAKE_OCULUS_SCREEN"); - nsresult err; - int32_t xcoord = nsCString(env).ToInteger(&err); - if (err != NS_OK) xcoord = 0; - mScreen = VRHMDManager::MakeFakeScreen(xcoord, 0, 1920, 1080); - } else -#endif - { - screenmgr->ScreenForRect(mHMD->WindowsPos.x, mHMD->WindowsPos.y, - mHMD->Resolution.w, mHMD->Resolution.h, - getter_AddRefs(mScreen)); - } + if (aDebug) { + mDeviceInfo.mDeviceName.AssignLiteral("Oculus VR HMD (0.5.0 Debug)"); + } else { + mDeviceInfo.mDeviceName.AssignLiteral("Oculus VR HMD (0.5.0)"); } + + mDeviceInfo.mSupportedSensorBits = VRStateValidFlags::State_None; + if (mHMD->TrackingCaps & ovrTrackingCap_Orientation) { + mDeviceInfo.mSupportedSensorBits |= VRStateValidFlags::State_Orientation; + } + if (mHMD->TrackingCaps & ovrTrackingCap_Position) { + mDeviceInfo.mSupportedSensorBits |= VRStateValidFlags::State_Position; + } + + mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Left] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Left]); + mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Right] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Right]); + + mDeviceInfo.mMaximumEyeFOV[VRDeviceInfo::Eye_Left] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Left]); + mDeviceInfo.mMaximumEyeFOV[VRDeviceInfo::Eye_Right] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Right]); + + mDeviceInfo.mScreenRect.x = mHMD->WindowsPos.x; + mDeviceInfo.mScreenRect.y = mHMD->WindowsPos.y; + mDeviceInfo.mScreenRect.width = mHMD->Resolution.w; + mDeviceInfo.mScreenRect.height = mHMD->Resolution.h; + mDeviceInfo.mIsFakeScreen = false; + + SetFOV(mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Left], mDeviceInfo.mRecommendedEyeFOV[VRDeviceInfo::Eye_Right], 0.01, 10000.0); +} + +bool +HMDInfoOculus050::GetIsDebug() const +{ + return mDebug; +} + +int +HMDInfoOculus050::GetDeviceID() const +{ + return mDeviceID; } void HMDInfoOculus050::Destroy() { + StopSensorTracking(); + if (mHMD) { ovrHmd_Destroy(mHMD); mHMD = nullptr; @@ -304,18 +313,18 @@ HMDInfoOculus050::SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFO uint32_t caps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette; // XXX TODO add TimeWarp // get eye parameters and create the mesh - for (uint32_t eye = 0; eye < NumEyes; eye++) { - mEyeFOV[eye] = eye == 0 ? aFOVLeft : aFOVRight; - mFOVPort[eye] = ToFovPort(mEyeFOV[eye]); + for (uint32_t eye = 0; eye < VRDeviceInfo::NumEyes; eye++) { + mDeviceInfo.mEyeFOV[eye] = eye == 0 ? aFOVLeft : aFOVRight; + mFOVPort[eye] = ToFovPort(mDeviceInfo.mEyeFOV[eye]); ovrEyeRenderDesc renderDesc = ovrHmd_GetRenderDesc(mHMD, (ovrEyeType) eye, mFOVPort[eye]); // these values are negated so that content can add the adjustment to its camera position, // instead of subtracting - mEyeTranslation[eye] = Point3D(-renderDesc.HmdToEyeViewOffset.x, -renderDesc.HmdToEyeViewOffset.y, -renderDesc.HmdToEyeViewOffset.z); + mDeviceInfo.mEyeTranslation[eye] = Point3D(-renderDesc.HmdToEyeViewOffset.x, -renderDesc.HmdToEyeViewOffset.y, -renderDesc.HmdToEyeViewOffset.z); // note that we are using a right-handed coordinate system here, to match CSS - mEyeProjectionMatrix[eye] = mEyeFOV[eye].ConstructProjectionMatrix(zNear, zFar, true); + mDeviceInfo.mEyeProjectionMatrix[eye] = mDeviceInfo.mEyeFOV[eye].ConstructProjectionMatrix(zNear, zFar, true); texSize[eye] = ovrHmd_GetFovTextureSize(mHMD, (ovrEyeType) eye, mFOVPort[eye], pixelsPerDisplayPixel); @@ -350,10 +359,10 @@ HMDInfoOculus050::SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFO } // take the max of both for eye resolution - mEyeResolution.width = std::max(texSize[Eye_Left].w, texSize[Eye_Right].w); - mEyeResolution.height = std::max(texSize[Eye_Left].h, texSize[Eye_Right].h); + mDeviceInfo.mEyeResolution.width = std::max(texSize[VRDeviceInfo::Eye_Left].w, texSize[VRDeviceInfo::Eye_Right].w); + mDeviceInfo.mEyeResolution.height = std::max(texSize[VRDeviceInfo::Eye_Left].h, texSize[VRDeviceInfo::Eye_Right].h); - mConfiguration.hmdType = mType; + mConfiguration.hmdType = mDeviceInfo.mType; mConfiguration.value = 0; mConfiguration.fov[0] = aFOVLeft; mConfiguration.fov[1] = aFOVRight; @@ -399,23 +408,51 @@ HMDInfoOculus050::FillDistortionConstants(uint32_t whichEye, } bool -HMDInfoOculus050::StartSensorTracking() +HMDInfoOculus050::KeepSensorTracking() { - if (mStartCount == 0) { - bool ok = ovrHmd_ConfigureTracking(mHMD, ovrTrackingCap_Orientation | ovrTrackingCap_Position, 0); - if (!ok) - return false; + // Keep sensor tracking alive for short time after the last request for + // tracking state by content. Value conservatively high to accomodate + // potentially high frame rates. + const uint32_t kKeepAliveFrames = 200; + + bool success = true; + if (mSensorTrackingFramesRemaining == 0) { + success = StartSensorTracking(); + } + if (success) { + mSensorTrackingFramesRemaining = kKeepAliveFrames; } - mStartCount++; - return true; + return success; +} + +void +HMDInfoOculus050::NotifyVsync(const mozilla::TimeStamp& aVsyncTimestamp) +{ + if (mSensorTrackingFramesRemaining == 1) { + StopSensorTracking(); + } + if (mSensorTrackingFramesRemaining) { + --mSensorTrackingFramesRemaining; + } +} + +bool +HMDInfoOculus050::StartSensorTracking() +{ + if (!mTracking) { + mTracking = ovrHmd_ConfigureTracking(mHMD, ovrTrackingCap_Orientation | ovrTrackingCap_Position, 0); + } + + return mTracking; } void HMDInfoOculus050::StopSensorTracking() { - if (--mStartCount == 0) { + if (mTracking) { ovrHmd_ConfigureTracking(mHMD, 0, 0); + mTracking = false; } } @@ -439,7 +476,7 @@ HMDInfoOculus050::GetSensorState(double timeOffset) result.timestamp = pose.TimeInSeconds; if (state.StatusFlags & ovrStatus_OrientationTracked) { - result.flags |= State_Orientation; + result.flags |= VRStateValidFlags::State_Orientation; result.orientation[0] = pose.ThePose.Orientation.x; result.orientation[1] = pose.ThePose.Orientation.y; @@ -456,7 +493,7 @@ HMDInfoOculus050::GetSensorState(double timeOffset) } if (state.StatusFlags & ovrStatus_PositionTracked) { - result.flags |= State_Position; + result.flags |= VRStateValidFlags::State_Position; result.position[0] = pose.ThePose.Position.x; result.position[1] = pose.ThePose.Position.y; @@ -474,52 +511,93 @@ HMDInfoOculus050::GetSensorState(double timeOffset) return result; } -bool -VRHMDManagerOculus050::PlatformInit() +/*static*/ already_AddRefed +VRHMDManagerOculus050::Create() { - if (mOculusPlatformInitialized) - return true; + MOZ_ASSERT(NS_IsMainThread()); - if (!gfxPrefs::VREnabled() || - !gfxPrefs::VROculus050Enabled()) + if (!gfxPrefs::VREnabled() || !gfxPrefs::VROculus050Enabled()) { - return false; + return nullptr; } - if (!InitializeOculusCAPI()) - return false; + if (!InitializeOculusCAPI()) { + return nullptr; + } - ovrInitParams params; - params.Flags = ovrInit_RequestVersion; - params.RequestedMinorVersion = LIBOVR_MINOR_VERSION; - params.LogCallback = nullptr; - params.ConnectionTimeoutMS = 0; - - bool ok = ovr_Initialize(¶ms); - - if (!ok) - return false; - - mOculusPlatformInitialized = true; - return true; + RefPtr manager = new VRHMDManagerOculus050(); + return manager.forget(); } bool VRHMDManagerOculus050::Init() { - if (mOculusInitialized) - return true; + if (!mOculusInitialized) { + nsIThread* thread = nullptr; + NS_GetCurrentThread(&thread); + mOculusThread = already_AddRefed(thread); - if (!PlatformInit()) - return false; + ovrInitParams params; + params.Flags = ovrInit_RequestVersion; + params.RequestedMinorVersion = LIBOVR_MINOR_VERSION; + params.LogCallback = nullptr; + params.ConnectionTimeoutMS = 0; + + bool ok = ovr_Initialize(¶ms); + + if (ok) { + mOculusInitialized = true; + } + } + return mOculusInitialized; +} + +void +VRHMDManagerOculus050::Destroy() +{ + if (mOculusInitialized) { + MOZ_ASSERT(NS_GetCurrentThread() == mOculusThread); + mOculusThread = nullptr; + + for (size_t i = 0; i < mOculusHMDs.Length(); ++i) { + mOculusHMDs[i]->Destroy(); + } + + mOculusHMDs.Clear(); + + ovr_Shutdown(); + + mOculusInitialized = false; + } +} + +void +VRHMDManagerOculus050::GetHMDs(nsTArray>& aHMDResult) +{ + if (!mOculusInitialized) { + return; + } + + nsTArray > newHMDs; int count = ovrHmd_Detect(); - for (int i = 0; i < count; ++i) { - ovrHmd hmd = ovrHmd_Create(i); - if (hmd) { - RefPtr oc = new HMDInfoOculus050(hmd); - mOculusHMDs.AppendElement(oc); + for (int j = 0; j < count; ++j) { + bool is_new = true; + for (size_t i = 0; i < mOculusHMDs.Length(); ++i) { + if(mOculusHMDs[i]->GetDeviceID() == j) { + newHMDs.AppendElement(mOculusHMDs[i]); + is_new = false; + break; + } + } + + if(is_new) { + ovrHmd hmd = ovrHmd_Create(j); + if (hmd) { + RefPtr oc = new HMDInfoOculus050(hmd, false, j); + newHMDs.AppendElement(oc); + } } } @@ -528,38 +606,28 @@ VRHMDManagerOculus050::Init() if ((count == 0 && gfxPrefs::VRAddTestDevices() == 1) || (gfxPrefs::VRAddTestDevices() == 2)) { - ovrHmd hmd = ovrHmd_CreateDebug(ovrHmd_DK2); - if (hmd) { - RefPtr oc = new HMDInfoOculus050(hmd); - mOculusHMDs.AppendElement(oc); + // Keep existing debug HMD if possible + bool foundDebug = false; + for (size_t i = 0; i < mOculusHMDs.Length(); ++i) { + if (mOculusHMDs[i]->GetIsDebug()) { + newHMDs.AppendElement(mOculusHMDs[i]); + foundDebug = true; + } + } + + // If there isn't already a debug HMD, create one + if (!foundDebug) { + ovrHmd hmd = ovrHmd_CreateDebug(ovrHmd_DK2); + if (hmd) { + RefPtr oc = new HMDInfoOculus050(hmd, true, -1); + newHMDs.AppendElement(oc); + } } } - mOculusInitialized = true; - return true; -} + mOculusHMDs = newHMDs; -void -VRHMDManagerOculus050::Destroy() -{ - if (!mOculusInitialized) - return; - - for (size_t i = 0; i < mOculusHMDs.Length(); ++i) { - mOculusHMDs[i]->Destroy(); - } - - mOculusHMDs.Clear(); - - ovr_Shutdown(); - mOculusInitialized = false; -} - -void -VRHMDManagerOculus050::GetHMDs(nsTArray>& aHMDResult) -{ - Init(); - for (size_t i = 0; i < mOculusHMDs.Length(); ++i) { - aHMDResult.AppendElement(mOculusHMDs[i]); + for (size_t j = 0; j < mOculusHMDs.Length(); ++j) { + aHMDResult.AppendElement(mOculusHMDs[j]); } } diff --git a/gfx/vr/gfxVROculus050.h b/gfx/vr/gfxVROculus050.h index 06d28b6dd6..9005f14640 100644 --- a/gfx/vr/gfxVROculus050.h +++ b/gfx/vr/gfxVROculus050.h @@ -7,12 +7,10 @@ #define GFX_VR_OCULUS_050_H #include "nsTArray.h" -#include "nsIScreen.h" -#include "nsCOMPtr.h" -#include "mozilla/RefPtr.h" - -#include "mozilla/gfx/2D.h" +#include "nsThreadUtils.h" #include "mozilla/EnumeratedArray.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/RefPtr.h" #include "gfxVR.h" #include "ovr_capi_dynamic050.h" @@ -23,15 +21,15 @@ namespace impl { class HMDInfoOculus050 : public VRHMDInfo { public: - explicit HMDInfoOculus050(ovr050::ovrHmd aHMD); + explicit HMDInfoOculus050(ovr050::ovrHmd aHMD, bool aDebug, int aDeviceID); bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight, double zNear, double zFar) override; - bool StartSensorTracking() override; VRHMDSensorState GetSensorState(double timeOffset) override; - void StopSensorTracking() override; void ZeroSensor() override; + bool KeepSensorTracking() override; + void NotifyVsync(const TimeStamp& aVsyncTimestamp) override; void FillDistortionConstants(uint32_t whichEye, const IntSize& textureSize, const IntRect& eyeViewport, @@ -39,8 +37,18 @@ public: VRDistortionConstants& values) override; void Destroy(); + bool GetIsDebug() const; + int GetDeviceID() const; protected: + virtual ~HMDInfoOculus050() { + Destroy(); + MOZ_COUNT_DTOR_INHERITED(HMDInfoOculus050, VRHMDInfo); + } + + bool StartSensorTracking(); + void StopSensorTracking(); + // must match the size of VRDistortionVertex struct DistortionVertex { float pos[2]; @@ -50,14 +58,13 @@ protected: float genericAttribs[4]; }; - virtual ~HMDInfoOculus050() { - Destroy(); - MOZ_COUNT_DTOR_INHERITED(HMDInfoOculus050, VRHMDInfo); - } - ovr050::ovrHmd mHMD; ovr050::ovrFovPort mFOVPort[2]; - uint32_t mStartCount; + uint32_t mTracking; + bool mDebug; // True if this is a debug HMD + int mDeviceID; // ID of device passed to ovrHmd_Create + + uint32_t mSensorTrackingFramesRemaining; }; } // namespace impl @@ -65,18 +72,18 @@ protected: class VRHMDManagerOculus050 : public VRHMDManager { public: - VRHMDManagerOculus050() - : mOculusInitialized(false), mOculusPlatformInitialized(false) - { } - - virtual bool PlatformInit() override; + static already_AddRefed Create(); virtual bool Init() override; virtual void Destroy() override; virtual void GetHMDs(nsTArray >& aHMDResult) override; protected: - nsTArray> mOculusHMDs; + VRHMDManagerOculus050() + : mOculusInitialized(false) + { } + + nsTArray > mOculusHMDs; bool mOculusInitialized; - bool mOculusPlatformInitialized; + RefPtr mOculusThread; }; } // namespace gfx diff --git a/gfx/vr/ipc/PVRManager.ipdl b/gfx/vr/ipc/PVRManager.ipdl new file mode 100644 index 0000000000..0036c168b4 --- /dev/null +++ b/gfx/vr/ipc/PVRManager.ipdl @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: sw=2 ts=8 et : + */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +include "VRMessageUtils.h"; + +using struct mozilla::gfx::VRFieldOfView from "gfxVR.h"; +using struct mozilla::gfx::VRDeviceUpdate from "gfxVR.h"; +using struct mozilla::gfx::VRSensorUpdate from "gfxVR.h"; + +namespace mozilla { +namespace gfx { + +/** + * The PVRManager protocol is used to enable communication of VR device + * enumeration and sensor state between the compositor thread and + * content threads/processes. + */ +sync protocol PVRManager +{ +parent: + // (Re)Enumerate VR Devices. An updated list of VR devices will be returned + // asynchronously to children via UpdateDeviceInfo. + async RefreshDevices(); + + // Reset the sensor of the device identified by aDeviceID so that the current + // sensor state is the "Zero" position. + async ResetSensor(uint32_t aDeviceID); + + // KeepSensorTracking is called continuously by children to indicate their + // interest in receiving sensor data from the device identified by aDeviceID. + // This will activate any physical sensor tracking system requiring + // initialization and guarantee that it will remain active until at least one + // second has passed since the last KeepSensorTracking call has been made. + // Sensor data will be sent asynchronously via UpdateDeviceSensors + async KeepSensorTracking(uint32_t aDeviceID); + + // Set the field of view parameters for an HMD identified by aDeviceID + async SetFOV(uint32_t aDeviceID, VRFieldOfView aFOVLeft, + VRFieldOfView aFOVRight, double zNear, double zFar); + +child: + + // Notify children of updated VR device enumeration and details. This will + // be sent to all children when the parent receives RefreshDevices, even + // if no changes have been detected. This ensures that Promises exposed + // through DOM calls are always resolved. + async UpdateDeviceInfo(VRDeviceUpdate[] aDeviceUpdates); + + // Notify children of updated VR device sensor states. This will be + // sent once per frame for at least one second after the parent receives + // KeepSensorTracking. + async UpdateDeviceSensors(VRSensorUpdate[] aDeviceSensorUpdates); + + async __delete__(); + +}; + +} // gfx +} // mozilla diff --git a/gfx/vr/ipc/VRManagerChild.cpp b/gfx/vr/ipc/VRManagerChild.cpp new file mode 100644 index 0000000000..0663839f54 --- /dev/null +++ b/gfx/vr/ipc/VRManagerChild.cpp @@ -0,0 +1,186 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: sw=2 ts=8 et : + */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "VRManagerChild.h" +#include "VRManagerParent.h" +#include "VRDeviceProxy.h" +#include "VRDeviceProxyOrientationFallBack.h" +#include "mozilla/StaticPtr.h" +#include "mozilla/layers/CompositorParent.h" // for CompositorParent +#include "mozilla/dom/Navigator.h" + +namespace mozilla { +namespace gfx { + +static StaticRefPtr sVRManagerChildSingleton; +static StaticRefPtr sVRManagerParentSingleton; + +void ReleaseVRManagerParentSingleton() { + sVRManagerParentSingleton = nullptr; +} + +VRManagerChild::VRManagerChild() +{ + MOZ_COUNT_CTOR(VRManagerChild); + MOZ_ASSERT(NS_IsMainThread()); +} + +VRManagerChild::~VRManagerChild() +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_COUNT_DTOR(VRManagerChild); + + Transport* trans = GetTransport(); + if (trans) { + MOZ_ASSERT(XRE_GetIOMessageLoop()); + XRE_GetIOMessageLoop()->PostTask(FROM_HERE, + new DeleteTask(trans)); + } +} + +/*static*/ VRManagerChild* +VRManagerChild::Get() +{ + MOZ_ASSERT(sVRManagerChildSingleton); + return sVRManagerChildSingleton; +} + +/*static*/ VRManagerChild* +VRManagerChild::StartUpInChildProcess(Transport* aTransport, ProcessId aOtherPid) +{ + MOZ_ASSERT(NS_IsMainThread()); + + // There's only one VRManager per child process. + MOZ_ASSERT(!sVRManagerChildSingleton); + + RefPtr child(new VRManagerChild()); + if (!child->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ChildSide)) { + NS_RUNTIMEABORT("Couldn't Open() Compositor channel."); + return nullptr; + } + + sVRManagerChildSingleton = child; + + return sVRManagerChildSingleton; +} + +/*static*/ void +VRManagerChild::StartUpSameProcess() +{ + NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!"); + if (sVRManagerChildSingleton == nullptr) { + sVRManagerChildSingleton = new VRManagerChild(); + sVRManagerParentSingleton = VRManagerParent::CreateSameProcess(); + sVRManagerChildSingleton->Open(sVRManagerParentSingleton->GetIPCChannel(), + mozilla::layers::CompositorParent::CompositorLoop(), + mozilla::ipc::ChildSide); + } +} + +/*static*/ void +VRManagerChild::ShutDown() +{ + MOZ_ASSERT(NS_IsMainThread()); + if (sVRManagerChildSingleton) { + sVRManagerChildSingleton->Destroy(); + sVRManagerChildSingleton = nullptr; + } +} + +/*static*/ void +VRManagerChild::DeferredDestroy(RefPtr aVRManagerChild) +{ + aVRManagerChild->Close(); +} + +void +VRManagerChild::Destroy() +{ + // This must not be called from the destructor! + MOZ_ASSERT(mRefCnt != 0); + + // Keep ourselves alive until everything has been shut down + RefPtr selfRef = this; + + // The DeferredDestroyVRManager task takes ownership of + // the VRManagerChild and will release it when it runs. + MessageLoop::current()->PostTask(FROM_HERE, + NewRunnableFunction(DeferredDestroy, selfRef)); +} + +bool +VRManagerChild::RecvUpdateDeviceInfo(nsTArray&& aDeviceUpdates) +{ + // mDevices could be a hashed container for more scalability, but not worth + // it now as we expect < 10 entries. + nsTArray > devices; + for (auto& deviceUpdate: aDeviceUpdates) { + bool isNewDevice = true; + for (auto& device: mDevices) { + if (device->GetDeviceInfo().GetDeviceID() == deviceUpdate.mDeviceInfo.GetDeviceID()) { + device->UpdateDeviceInfo(deviceUpdate); + devices.AppendElement(device); + isNewDevice = false; + break; + } + } + if (isNewDevice) { + if (deviceUpdate.mDeviceInfo.GetUseMainThreadOrientation()) { + devices.AppendElement(new VRDeviceProxyOrientationFallBack(deviceUpdate)); + } else { + devices.AppendElement(new VRDeviceProxy(deviceUpdate)); + } + } + } + + mDevices = devices; + + + for (auto& nav: mNavigatorCallbacks) { + nav->NotifyVRDevicesUpdated(); + } + mNavigatorCallbacks.Clear(); + + return true; +} + +bool +VRManagerChild::RecvUpdateDeviceSensors(nsTArray&& aDeviceSensorUpdates) +{ + // mDevices could be a hashed container for more scalability, but not worth + // it now as we expect < 10 entries. + for (auto& sensorUpdate: aDeviceSensorUpdates) { + for (auto& device: mDevices) { + if (device->GetDeviceInfo().GetDeviceID() == sensorUpdate.mDeviceID) { + device->UpdateSensorState(sensorUpdate.mSensorState); + break; + } + } + } + + return true; +} + +bool +VRManagerChild::GetVRDevices(nsTArray >& aDevices) +{ + aDevices = mDevices; + return true; +} + +bool +VRManagerChild::RefreshVRDevicesWithCallback(dom::Navigator* aNavigator) +{ + bool success = SendRefreshDevices(); + if (success) { + mNavigatorCallbacks.AppendElement(aNavigator); + } + return success; +} + +} // namespace gfx +} // namespace mozilla diff --git a/gfx/vr/ipc/VRManagerChild.h b/gfx/vr/ipc/VRManagerChild.h new file mode 100644 index 0000000000..293f7d783b --- /dev/null +++ b/gfx/vr/ipc/VRManagerChild.h @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: sw=2 ts=8 et : + */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_GFX_VR_VRMANAGERCHILD_H +#define MOZILLA_GFX_VR_VRMANAGERCHILD_H + +#include "mozilla/gfx/PVRManagerChild.h" +#include "ThreadSafeRefcountingWithMainThreadDestruction.h" + +namespace mozilla { +namespace dom { +class Navigator; +class VRDevice; +} // namespace dom +namespace gfx { +class VRDeviceProxy; + + +class VRManagerChild : public PVRManagerChild +{ +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(VRManagerChild) + + bool GetVRDevices(nsTArray >& aDevices); + bool RefreshVRDevicesWithCallback(dom::Navigator* aNavigator); + static VRManagerChild* StartUpInChildProcess(Transport* aTransport, + ProcessId aOtherProcess); + + static void StartUpSameProcess(); + static void ShutDown(); + + + static VRManagerChild* Get(); + +protected: + explicit VRManagerChild(); + ~VRManagerChild(); + void Destroy(); + static void DeferredDestroy(RefPtr aVRManagerChild); + + virtual bool RecvUpdateDeviceInfo(nsTArray&& aDeviceUpdates) override; + virtual bool RecvUpdateDeviceSensors(nsTArray&& aDeviceSensorUpdates) override; + + friend class layers::CompositorChild; + +private: + + nsTArray > mDevices; + nsTArray mNavigatorCallbacks; + +}; + +} // namespace mozilla +} // namespace gfx + +#endif // MOZILLA_GFX_VR_VRMANAGERCHILD_H \ No newline at end of file diff --git a/gfx/vr/ipc/VRManagerParent.cpp b/gfx/vr/ipc/VRManagerParent.cpp new file mode 100644 index 0000000000..56a2b865ec --- /dev/null +++ b/gfx/vr/ipc/VRManagerParent.cpp @@ -0,0 +1,198 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: sw=2 ts=8 et : + */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "VRManagerParent.h" +#include "mozilla/gfx/PVRManagerParent.h" +#include "mozilla/ipc/ProtocolTypes.h" +#include "mozilla/ipc/ProtocolUtils.h" // for IToplevelProtocol +#include "mozilla/TimeStamp.h" // for TimeStamp +#include "mozilla/layers/CompositorParent.h" +#include "mozilla/unused.h" +#include "VRManager.h" + +namespace mozilla { +namespace layers { + +// defined in CompositorParent.cpp +CompositorThreadHolder* GetCompositorThreadHolder(); + +} // namespace layers + +namespace gfx { + +VRManagerParent::VRManagerParent(MessageLoop* aLoop, + Transport* aTransport, + ProcessId aChildProcessId) +{ + MOZ_COUNT_CTOR(VRManagerParent); + MOZ_ASSERT(NS_IsMainThread()); + + SetTransport(aTransport); + SetOtherProcessId(aChildProcessId); +} + +VRManagerParent::~VRManagerParent() +{ + MOZ_ASSERT(NS_IsMainThread()); + + MOZ_ASSERT(!mVRManagerHolder); + + Transport* trans = GetTransport(); + if (trans) { + MOZ_ASSERT(XRE_GetIOMessageLoop()); + XRE_GetIOMessageLoop()->PostTask(FROM_HERE, + new DeleteTask(trans)); + } + MOZ_COUNT_DTOR(VRManagerParent); +} + +void VRManagerParent::RegisterWithManager() +{ + VRManager* vm = VRManager::Get(); + vm->AddVRManagerParent(this); + mVRManagerHolder = vm; +} + +void VRManagerParent::UnregisterFromManager() +{ + VRManager* vm = VRManager::Get(); + vm->RemoveVRManagerParent(this); + mVRManagerHolder = nullptr; +} + +/*static*/ void +VRManagerParent::ConnectVRManagerInParentProcess(VRManagerParent* aVRManager, + ipc::Transport* aTransport, + base::ProcessId aOtherPid) +{ + aVRManager->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ParentSide); + aVRManager->RegisterWithManager(); +} + +/*static*/ VRManagerParent* +VRManagerParent::CreateCrossProcess(Transport* aTransport, ProcessId aChildProcessId) +{ + MessageLoop* loop = mozilla::layers::CompositorParent::CompositorLoop(); + RefPtr vmp = new VRManagerParent(loop, aTransport, aChildProcessId); + vmp->mSelfRef = vmp; + loop->PostTask(FROM_HERE, + NewRunnableFunction(ConnectVRManagerInParentProcess, + vmp.get(), aTransport, aChildProcessId)); + return vmp.get(); +} + +/*static*/ void +VRManagerParent::RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager) +{ + aVRManager->RegisterWithManager(); +} + +/*static*/ VRManagerParent* +VRManagerParent::CreateSameProcess() +{ + MessageLoop* loop = mozilla::layers::CompositorParent::CompositorLoop(); + RefPtr vmp = new VRManagerParent(loop, nullptr, base::GetCurrentProcId()); + vmp->mCompositorThreadHolder = layers::GetCompositorThreadHolder(); + vmp->mSelfRef = vmp; + loop->PostTask(FROM_HERE, + NewRunnableFunction(RegisterVRManagerInCompositorThread, vmp.get())); + return vmp.get(); +} + +void +VRManagerParent::DeferredDestroy() +{ + MOZ_ASSERT(mCompositorThreadHolder); + mCompositorThreadHolder = nullptr; + mSelfRef = nullptr; +} + +void +VRManagerParent::ActorDestroy(ActorDestroyReason why) +{ + UnregisterFromManager(); + MessageLoop::current()->PostTask( + FROM_HERE, + NewRunnableMethod(this, &VRManagerParent::DeferredDestroy)); +} + +mozilla::ipc::IToplevelProtocol* +VRManagerParent::CloneToplevel(const InfallibleTArray& aFds, + base::ProcessHandle aPeerProcess, + mozilla::ipc::ProtocolCloneContext* aCtx) +{ + for (unsigned int i = 0; i < aFds.Length(); i++) { + if (aFds[i].protocolId() == unsigned(GetProtocolId())) { + Transport* transport = OpenDescriptor(aFds[i].fd(), + Transport::MODE_SERVER); + PVRManagerParent* vm = CreateCrossProcess(transport, base::GetProcId(aPeerProcess)); + vm->CloneManagees(this, aCtx); + vm->IToplevelProtocol::SetTransport(transport); + // The reference to the compositor thread is held in OnChannelConnected(). + // We need to do this for cloned actors, too. + vm->OnChannelConnected(base::GetProcId(aPeerProcess)); + return vm; + } + } + return nullptr; +} + +void +VRManagerParent::OnChannelConnected(int32_t aPid) +{ + mCompositorThreadHolder = layers::GetCompositorThreadHolder(); +} + +bool +VRManagerParent::RecvRefreshDevices() +{ + VRManager* vm = VRManager::Get(); + vm->RefreshVRDevices(); + + return true; +} + +bool +VRManagerParent::RecvResetSensor(const uint32_t& aDeviceID) +{ + VRManager* vm = VRManager::Get(); + RefPtr device = vm->GetDevice(aDeviceID); + if (device != nullptr) { + device->ZeroSensor(); + } + + return true; +} + +bool +VRManagerParent::RecvKeepSensorTracking(const uint32_t& aDeviceID) +{ + VRManager* vm = VRManager::Get(); + RefPtr device = vm->GetDevice(aDeviceID); + if (device != nullptr) { + Unused << device->KeepSensorTracking(); + } + return true; +} + +bool +VRManagerParent::RecvSetFOV(const uint32_t& aDeviceID, + const VRFieldOfView& aFOVLeft, + const VRFieldOfView& aFOVRight, + const double& zNear, + const double& zFar) +{ + VRManager* vm = VRManager::Get(); + RefPtr device = vm->GetDevice(aDeviceID); + if (device != nullptr) { + device->SetFOV(aFOVLeft, aFOVRight, zNear, zFar); + } + return true; +} + +} // namespace gfx +} // namespace mozilla diff --git a/gfx/vr/ipc/VRManagerParent.h b/gfx/vr/ipc/VRManagerParent.h new file mode 100644 index 0000000000..d1b24b51db --- /dev/null +++ b/gfx/vr/ipc/VRManagerParent.h @@ -0,0 +1,80 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: sw=2 ts=8 et : + */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_GFX_VR_VRMANAGERPARENT_H +#define MOZILLA_GFX_VR_VRMANAGERPARENT_H + +#include "mozilla/layers/CompositorParent.h" // for CompositorThreadHolder +#include "mozilla/gfx/PVRManagerParent.h" // for PVRManagerParent +#include "mozilla/ipc/ProtocolUtils.h" // for IToplevelProtocol +#include "mozilla/TimeStamp.h" // for TimeStamp +#include "gfxVR.h" // for VRFieldOfView + +namespace mozilla { +namespace gfx { + +class VRManager; + +class VRManagerParent final : public PVRManagerParent +{ + NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(VRManagerParent) +public: + VRManagerParent(MessageLoop* aLoop, Transport* aTransport, ProcessId aChildProcessId); + + static VRManagerParent* CreateCrossProcess(Transport* aTransport, + ProcessId aOtherProcess); + static VRManagerParent* CreateSameProcess(); + + + // Overriden from IToplevelProtocol + ipc::IToplevelProtocol* + CloneToplevel(const InfallibleTArray& aFds, + base::ProcessHandle aPeerProcess, + mozilla::ipc::ProtocolCloneContext* aCtx) override; + +protected: + ~VRManagerParent(); + + virtual void ActorDestroy(ActorDestroyReason why) override; + void OnChannelConnected(int32_t pid) override; + + virtual bool RecvRefreshDevices() override; + virtual bool RecvResetSensor(const uint32_t& aDeviceID) override; + virtual bool RecvKeepSensorTracking(const uint32_t& aDeviceID) override; + virtual bool RecvSetFOV(const uint32_t& aDeviceID, + const VRFieldOfView& aFOVLeft, + const VRFieldOfView& aFOVRight, + const double& zNear, + const double& zFar) override; + +private: + + void RegisterWithManager(); + void UnregisterFromManager(); + + static void RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager); + static void ConnectVRManagerInParentProcess(VRManagerParent* aVRManager, + ipc::Transport* aTransport, + base::ProcessId aOtherPid); + + void DeferredDestroy(); + + // This keeps us alive until ActorDestroy(), at which point we do a + // deferred destruction of ourselves. + RefPtr mSelfRef; + + // Keep the compositor thread alive, until we have destroyed ourselves. + RefPtr mCompositorThreadHolder; + + // Keep the VRManager alive, until we have destroyed ourselves. + RefPtr mVRManagerHolder; +}; + +} // namespace mozilla +} // namespace gfx + +#endif // MOZILLA_GFX_VR_VRMANAGERPARENT_H diff --git a/gfx/vr/ipc/VRMessageUtils.h b/gfx/vr/ipc/VRMessageUtils.h new file mode 100644 index 0000000000..1c17f1eb61 --- /dev/null +++ b/gfx/vr/ipc/VRMessageUtils.h @@ -0,0 +1,209 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 : */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_gfx_vr_VRMessageUtils_h +#define mozilla_gfx_vr_VRMessageUtils_h + +#include "ipc/IPCMessageUtils.h" +#include "mozilla/GfxMessageUtils.h" +#include "VRManager.h" + +#include "gfxVR.h" + +namespace IPC { + +template<> +struct ParamTraits : + public ContiguousEnumSerializer {}; + +template<> +struct ParamTraits : + public BitFlagsEnumSerializer {}; + +template <> +struct ParamTraits +{ + typedef mozilla::gfx::VRDeviceUpdate paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.mDeviceInfo); + WriteParam(aMsg, aParam.mSensorState); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + if (!ReadParam(aMsg, aIter, &(aResult->mDeviceInfo)) || + !ReadParam(aMsg, aIter, &(aResult->mSensorState))) { + return false; + } + return true; + } +}; + +template <> +struct ParamTraits +{ + typedef mozilla::gfx::VRSensorUpdate paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.mDeviceID); + WriteParam(aMsg, aParam.mSensorState); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + if (!ReadParam(aMsg, aIter, &(aResult->mDeviceID)) || + !ReadParam(aMsg, aIter, &(aResult->mSensorState))) { + return false; + } + return true; + } +}; + +template <> +struct ParamTraits +{ + typedef mozilla::gfx::VRDeviceInfo paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.mType); + WriteParam(aMsg, aParam.mDeviceID); + WriteParam(aMsg, aParam.mDeviceName); + WriteParam(aMsg, aParam.mSupportedSensorBits); + WriteParam(aMsg, aParam.mEyeResolution); + WriteParam(aMsg, aParam.mScreenRect); + WriteParam(aMsg, aParam.mIsFakeScreen); + WriteParam(aMsg, aParam.mUseMainThreadOrientation); + for (int i = 0; i < mozilla::gfx::VRDeviceInfo::NumEyes; i++) { + WriteParam(aMsg, aParam.mMaximumEyeFOV[i]); + WriteParam(aMsg, aParam.mRecommendedEyeFOV[i]); + WriteParam(aMsg, aParam.mEyeFOV[i]); + WriteParam(aMsg, aParam.mEyeTranslation[i]); + WriteParam(aMsg, aParam.mEyeProjectionMatrix[i]); + } + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + if (!ReadParam(aMsg, aIter, &(aResult->mType)) || + !ReadParam(aMsg, aIter, &(aResult->mDeviceID)) || + !ReadParam(aMsg, aIter, &(aResult->mDeviceName)) || + !ReadParam(aMsg, aIter, &(aResult->mSupportedSensorBits)) || + !ReadParam(aMsg, aIter, &(aResult->mEyeResolution)) || + !ReadParam(aMsg, aIter, &(aResult->mScreenRect)) || + !ReadParam(aMsg, aIter, &(aResult->mIsFakeScreen)) || + !ReadParam(aMsg, aIter, &(aResult->mUseMainThreadOrientation)) + ) { + return false; + } + for (int i = 0; i < mozilla::gfx::VRDeviceInfo::NumEyes; i++) { + if (!ReadParam(aMsg, aIter, &(aResult->mMaximumEyeFOV[i])) || + !ReadParam(aMsg, aIter, &(aResult->mRecommendedEyeFOV[i])) || + !ReadParam(aMsg, aIter, &(aResult->mEyeFOV[i])) || + !ReadParam(aMsg, aIter, &(aResult->mEyeTranslation[i])) || + !ReadParam(aMsg, aIter, &(aResult->mEyeProjectionMatrix[i]))) { + return false; + } + } + + return true; + } +}; + +template <> +struct ParamTraits +{ + typedef mozilla::gfx::VRHMDSensorState paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.timestamp); + WriteParam(aMsg, aParam.flags); + WriteParam(aMsg, aParam.orientation[0]); + WriteParam(aMsg, aParam.orientation[1]); + WriteParam(aMsg, aParam.orientation[2]); + WriteParam(aMsg, aParam.orientation[3]); + WriteParam(aMsg, aParam.position[0]); + WriteParam(aMsg, aParam.position[1]); + WriteParam(aMsg, aParam.position[2]); + WriteParam(aMsg, aParam.angularVelocity[0]); + WriteParam(aMsg, aParam.angularVelocity[1]); + WriteParam(aMsg, aParam.angularVelocity[2]); + WriteParam(aMsg, aParam.angularAcceleration[0]); + WriteParam(aMsg, aParam.angularAcceleration[1]); + WriteParam(aMsg, aParam.angularAcceleration[2]); + WriteParam(aMsg, aParam.linearVelocity[0]); + WriteParam(aMsg, aParam.linearVelocity[1]); + WriteParam(aMsg, aParam.linearVelocity[2]); + WriteParam(aMsg, aParam.linearAcceleration[0]); + WriteParam(aMsg, aParam.linearAcceleration[1]); + WriteParam(aMsg, aParam.linearAcceleration[2]); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + if (!ReadParam(aMsg, aIter, &(aResult->timestamp)) || + !ReadParam(aMsg, aIter, &(aResult->flags)) || + !ReadParam(aMsg, aIter, &(aResult->orientation[0])) || + !ReadParam(aMsg, aIter, &(aResult->orientation[1])) || + !ReadParam(aMsg, aIter, &(aResult->orientation[2])) || + !ReadParam(aMsg, aIter, &(aResult->orientation[3])) || + !ReadParam(aMsg, aIter, &(aResult->position[0])) || + !ReadParam(aMsg, aIter, &(aResult->position[1])) || + !ReadParam(aMsg, aIter, &(aResult->position[2])) || + !ReadParam(aMsg, aIter, &(aResult->angularVelocity[0])) || + !ReadParam(aMsg, aIter, &(aResult->angularVelocity[1])) || + !ReadParam(aMsg, aIter, &(aResult->angularVelocity[2])) || + !ReadParam(aMsg, aIter, &(aResult->angularAcceleration[0])) || + !ReadParam(aMsg, aIter, &(aResult->angularAcceleration[1])) || + !ReadParam(aMsg, aIter, &(aResult->angularAcceleration[2])) || + !ReadParam(aMsg, aIter, &(aResult->linearVelocity[0])) || + !ReadParam(aMsg, aIter, &(aResult->linearVelocity[1])) || + !ReadParam(aMsg, aIter, &(aResult->linearVelocity[2])) || + !ReadParam(aMsg, aIter, &(aResult->linearAcceleration[0])) || + !ReadParam(aMsg, aIter, &(aResult->linearAcceleration[1])) || + !ReadParam(aMsg, aIter, &(aResult->linearAcceleration[2]))) { + return false; + } + return true; + } +}; + +template <> +struct ParamTraits +{ + typedef mozilla::gfx::VRFieldOfView paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.upDegrees); + WriteParam(aMsg, aParam.rightDegrees); + WriteParam(aMsg, aParam.downDegrees); + WriteParam(aMsg, aParam.leftDegrees); + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + if (!ReadParam(aMsg, aIter, &(aResult->upDegrees)) || + !ReadParam(aMsg, aIter, &(aResult->rightDegrees)) || + !ReadParam(aMsg, aIter, &(aResult->downDegrees)) || + !ReadParam(aMsg, aIter, &(aResult->leftDegrees))) { + return false; + } + + return true; + } +}; + +} // namespace IPC + +#endif // mozilla_gfx_vr_VRMessageUtils_h diff --git a/gfx/vr/moz.build b/gfx/vr/moz.build index 0f084ddc5e..81ac8f7d50 100644 --- a/gfx/vr/moz.build +++ b/gfx/vr/moz.build @@ -6,6 +6,11 @@ EXPORTS += [ 'gfxVR.h', + 'ipc/VRManagerChild.h', + 'ipc/VRManagerParent.h', + 'ipc/VRMessageUtils.h', + 'VRDeviceProxy.h', + 'VRManager.h', ] LOCAL_INCLUDES += [ @@ -16,12 +21,21 @@ UNIFIED_SOURCES += [ 'gfxVR.cpp', 'gfxVRCardboard.cpp', 'gfxVROculus.cpp', + 'ipc/VRManagerChild.cpp', + 'ipc/VRManagerParent.cpp', + 'VRDeviceProxy.cpp', + 'VRDeviceProxyOrientationFallBack.cpp', + 'VRManager.cpp', ] SOURCES += [ 'gfxVROculus050.cpp', ] +IPDL_SOURCES = [ + 'ipc/PVRManager.ipdl', +] + # For building with the real SDK instead of our local hack #SOURCES += [ # 'OVR_CAPI_Util.cpp', diff --git a/gfx/ycbcr/YCbCrUtils.cpp b/gfx/ycbcr/YCbCrUtils.cpp index 024520c788..b4b750af36 100644 --- a/gfx/ycbcr/YCbCrUtils.cpp +++ b/gfx/ycbcr/YCbCrUtils.cpp @@ -135,7 +135,7 @@ ConvertYCbCrToRGB(const layers::PlanarYCbCrData& aData, aData.mCbCrStride, aStride, yuvtype); - } else // aDestFormat != gfxImageFormat::RGB16_565 + } else // aDestFormat != SurfaceFormat::R5G6B5_UINT16 #endif ConvertYCbCrToRGB32(aData.mYChannel, // aData.mCbChannel, diff --git a/hal/Hal.cpp b/hal/Hal.cpp index 3a22abe671..79b439b539 100644 --- a/hal/Hal.cpp +++ b/hal/Hal.cpp @@ -91,6 +91,8 @@ AssertMainProcess() MOZ_ASSERT(GeckoProcessType_Default == XRE_GetProcessType()); } +#if !defined(MOZ_WIDGET_GONK) + bool WindowIsActive(nsIDOMWindow* aWindow) { @@ -103,6 +105,8 @@ WindowIsActive(nsIDOMWindow* aWindow) return !document->Hidden(); } +#endif // !defined(MOZ_WIDGET_GONK) + StaticAutoPtr gLastIDToVibrate; void InitLastIDToVibrate() @@ -124,6 +128,7 @@ Vibrate(const nsTArray& pattern, const WindowIdentifier &id) { AssertMainThread(); +#if !defined(MOZ_WIDGET_GONK) // Only active windows may start vibrations. If |id| hasn't gone // through the IPC layer -- that is, if our caller is the outside // world, not hal_proxy -- check whether the window is active. If @@ -134,6 +139,7 @@ Vibrate(const nsTArray& pattern, const WindowIdentifier &id) HAL_LOG("Vibrate: Window is inactive, dropping vibrate."); return; } +#endif // !defined(MOZ_WIDGET_GONK) if (!InSandbox()) { if (!gLastIDToVibrate) { diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index b861e934f5..eb8092d35f 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -6186,7 +6186,7 @@ nsDisplaySVGEffects::~nsDisplaySVGEffects() #endif nsDisplayVR::nsDisplayVR(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, - nsDisplayList* aList, mozilla::gfx::VRHMDInfo* aHMD) + nsDisplayList* aList, mozilla::gfx::VRDeviceProxy* aHMD) : nsDisplayOwnLayer(aBuilder, aFrame, aList) , mHMD(aHMD) { @@ -6204,7 +6204,7 @@ nsDisplayVR::BuildLayer(nsDisplayListBuilder* aBuilder, BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList, newContainerParameters, nullptr, flags); - container->SetVRHMDInfo(mHMD); + container->SetVRDeviceID(mHMD->GetDeviceInfo().GetDeviceID()); container->SetUserData(nsIFrame::LayerIsPrerenderedDataKey(), /*the value is irrelevant*/nullptr); diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 2aedbd6304..b853d09d90 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -54,7 +54,7 @@ class ImageLayer; class ImageContainer; } // namespace layers namespace gfx { -class VRHMDInfo; +class VRDeviceProxy; } // namespace gfx } // namespace mozilla @@ -4288,7 +4288,7 @@ public: class nsDisplayVR : public nsDisplayOwnLayer { public: nsDisplayVR(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, - nsDisplayList* aList, mozilla::gfx::VRHMDInfo* aHMD); + nsDisplayList* aList, mozilla::gfx::VRDeviceProxy* aHMD); virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, @@ -4302,7 +4302,7 @@ public: const ContainerLayerParameters& aContainerParameters) override; protected: - RefPtr mHMD; + RefPtr mHMD; }; #endif /*NSDISPLAYLIST_H_*/ diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index fcf416ed2a..a7c9c3279c 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -7030,16 +7030,26 @@ nsLayoutUtils::SurfaceFromElement(nsIImageLoadingContent* aElement, } int32_t imgWidth, imgHeight; - rv = imgContainer->GetWidth(&imgWidth); - nsresult rv2 = imgContainer->GetHeight(&imgHeight); - if (NS_FAILED(rv) || NS_FAILED(rv2)) - return result; + nsCOMPtr content = do_QueryInterface(aElement); + HTMLImageElement* element = HTMLImageElement::FromContentOrNull(content); + if (aSurfaceFlags & SFE_USE_ELEMENT_SIZE_IF_VECTOR && + element && + imgContainer->GetType() == imgIContainer::TYPE_VECTOR) { + imgWidth = element->Width(); + imgHeight = element->Height(); + } else { + rv = imgContainer->GetWidth(&imgWidth); + nsresult rv2 = imgContainer->GetHeight(&imgHeight); + if (NS_FAILED(rv) || NS_FAILED(rv2)) + return result; + } + result.mSize = IntSize(imgWidth, imgHeight); if (!noRasterize || imgContainer->GetType() == imgIContainer::TYPE_RASTER) { if (aSurfaceFlags & SFE_WANT_IMAGE_SURFACE) { frameFlags |= imgIContainer::FLAG_WANT_DATA_SURFACE; } - result.mSourceSurface = imgContainer->GetFrame(whichFrame, frameFlags); + result.mSourceSurface = imgContainer->GetFrameAtSize(result.mSize, whichFrame, frameFlags); if (!result.mSourceSurface) { return result; } @@ -7065,7 +7075,6 @@ nsLayoutUtils::SurfaceFromElement(nsIImageLoadingContent* aElement, result.mCORSUsed = (corsmode != imgIRequest::CORS_NONE); } - result.mSize = IntSize(imgWidth, imgHeight); result.mPrincipal = principal.forget(); // no images, including SVG images, can load content from another domain. result.mIsWriteOnly = false; diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 884929cbcd..b6a17f484f 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -2060,7 +2060,10 @@ public: SFE_PREFER_NO_PREMULTIPLY_ALPHA = 1 << 3, /* Whether we should skip getting a surface for vector images and return a DirectDrawInfo containing an imgIContainer instead. */ - SFE_NO_RASTERIZING_VECTORS = 1 << 4 + SFE_NO_RASTERIZING_VECTORS = 1 << 4, + /* If image type is vector, the return surface size will same as + element size, not image's intrinsic size. */ + SFE_USE_ELEMENT_SIZE_IF_VECTOR = 1 << 5 }; struct DirectDrawInfo { diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 359815bfb3..2fc05df730 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -113,7 +113,7 @@ typedef nsAbsoluteContainingBlock::AbsPosReflowFlags AbsPosReflowFlags; namespace mozilla { namespace gfx { -class VRHMDInfo; +class VRDeviceProxy; } // namespace gfx } // namespace mozilla @@ -2058,9 +2058,9 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, nsDisplayListBuilder::AutoBuildingDisplayList buildingDisplayList(aBuilder, this, dirtyRect, true); - mozilla::gfx::VRHMDInfo* vrHMDInfo = nullptr; + mozilla::gfx::VRDeviceProxy* vrHMDInfo = nullptr; if ((GetStateBits() & NS_FRAME_HAS_VR_CONTENT)) { - vrHMDInfo = static_cast(mContent->GetProperty(nsGkAtoms::vr_state)); + vrHMDInfo = static_cast(mContent->GetProperty(nsGkAtoms::vr_state)); } DisplayListClipState::AutoSaveRestore clipState(aBuilder); diff --git a/layout/style/test/ListCSSProperties.cpp b/layout/style/test/ListCSSProperties.cpp index 2f042fc839..b34d24e0a2 100644 --- a/layout/style/test/ListCSSProperties.cpp +++ b/layout/style/test/ListCSSProperties.cpp @@ -8,6 +8,7 @@ #include #include #include +#include "mozilla/ArrayUtils.h" struct PropertyInfo { const char *propName; @@ -97,9 +98,6 @@ const char* gShorthandPropertiesWithDOMProp[] = { }; - -#define ARRAY_LENGTH(a_) (sizeof(a_)/sizeof((a_)[0])) - const char *gInaccessibleProperties[] = { // Don't print the properties that aren't accepted by the parser, per // CSSParserImpl::ParseProperty @@ -122,7 +120,7 @@ const char *gInaccessibleProperties[] = { inline int is_inaccessible(const char* aPropName) { - for (unsigned j = 0; j < ARRAY_LENGTH(gInaccessibleProperties); ++j) { + for (unsigned j = 0; j < MOZ_ARRAY_LENGTH(gInaccessibleProperties); ++j) { if (strcmp(aPropName, gInaccessibleProperties[j]) == 0) return 1; } @@ -183,13 +181,13 @@ main() { print_array("gLonghandProperties", gLonghandProperties, - ARRAY_LENGTH(gLonghandProperties), + MOZ_ARRAY_LENGTH(gLonghandProperties), gLonghandPropertiesWithDOMProp, - ARRAY_LENGTH(gLonghandPropertiesWithDOMProp)); + MOZ_ARRAY_LENGTH(gLonghandPropertiesWithDOMProp)); print_array("gShorthandProperties", gShorthandProperties, - ARRAY_LENGTH(gShorthandProperties), + MOZ_ARRAY_LENGTH(gShorthandProperties), gShorthandPropertiesWithDOMProp, - ARRAY_LENGTH(gShorthandPropertiesWithDOMProp)); + MOZ_ARRAY_LENGTH(gShorthandPropertiesWithDOMProp)); return 0; } diff --git a/memory/volatile/VolatileBuffer.h b/memory/volatile/VolatileBuffer.h index afb075c725..ebb4713320 100644 --- a/memory/volatile/VolatileBuffer.h +++ b/memory/volatile/VolatileBuffer.h @@ -88,7 +88,11 @@ private: class VolatileBufferPtr_base { public: - explicit VolatileBufferPtr_base(VolatileBuffer* vbuf) : mVBuf(vbuf) { + explicit VolatileBufferPtr_base(VolatileBuffer* vbuf) + : mVBuf(vbuf) + , mMapping(nullptr) + , mPurged(false) + { Lock(); } diff --git a/mfbt/FastBernoulliTrial.h b/mfbt/FastBernoulliTrial.h index fbfc34b3ca..7e38b70ab4 100644 --- a/mfbt/FastBernoulliTrial.h +++ b/mfbt/FastBernoulliTrial.h @@ -177,7 +177,10 @@ class FastBernoulliTrial { * random number generator; both may not be zero. */ FastBernoulliTrial(double aProbability, uint64_t aState0, uint64_t aState1) - : mGenerator(aState0, aState1) + : mProbability(0) + , mInvLogNotProbability(0) + , mGenerator(aState0, aState1) + , mSkipCount(0) { setProbability(aProbability); } diff --git a/mfbt/ThreadLocal.h b/mfbt/ThreadLocal.h index 79da298f55..eae84a2144 100644 --- a/mfbt/ThreadLocal.h +++ b/mfbt/ThreadLocal.h @@ -95,6 +95,10 @@ class ThreadLocal }; public: + ThreadLocal() + : mKey(0), mInited(false) + {} + MOZ_WARN_UNUSED_RESULT inline bool init(); inline T get() const; diff --git a/modules/libjar/nsJAR.cpp b/modules/libjar/nsJAR.cpp index 59d80161fe..a642b1f0d9 100644 --- a/modules/libjar/nsJAR.cpp +++ b/modules/libjar/nsJAR.cpp @@ -83,6 +83,7 @@ nsJAR::nsJAR(): mZip(new nsZipArchive()), mReleaseTime(PR_INTERVAL_NO_TIMEOUT), mCache(nullptr), mLock("nsJAR::mLock"), + mMtime(0), mTotalItemsInManifest(0), mOpened(false) { @@ -1064,6 +1065,7 @@ NS_IMPL_ISUPPORTS(nsZipReaderCache, nsIZipReaderCache, nsIObserver, nsISupportsW nsZipReaderCache::nsZipReaderCache() : mLock("nsZipReaderCache.mLock") + , mCacheSize(0) , mZips() #ifdef ZIP_CACHE_HIT_RATE , diff --git a/modules/libjar/nsJAR.h b/modules/libjar/nsJAR.h index d863d3708d..4afac3bcb4 100644 --- a/modules/libjar/nsJAR.h +++ b/modules/libjar/nsJAR.h @@ -104,7 +104,7 @@ class nsJAR final : public nsIZipReader //-- Private data members nsCOMPtr mZipFile; // The zip/jar file on disk nsCString mOuterZipEntry; // The entry in the zip this zip is reading from - RefPtr mZip; // The underlying zip archive + RefPtr mZip; // The underlying zip archive ManifestDataHashtable mManifestData; // Stores metadata for each entry bool mParsedManifest; // True if manifest has been parsed nsCOMPtr mSigningCert; // The entity which signed this file @@ -168,7 +168,8 @@ public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIUTF8STRINGENUMERATOR - explicit nsJAREnumerator(nsZipFind *aFind) : mFind(aFind), mName(nullptr) { + explicit nsJAREnumerator(nsZipFind *aFind) + : mFind(aFind), mName(nullptr), mNameLen(0) { NS_ASSERTION(mFind, "nsJAREnumerator: Missing zipFind."); } diff --git a/modules/libjar/nsJARChannel.cpp b/modules/libjar/nsJARChannel.cpp index 1b3f4a9d58..e82bc6620f 100644 --- a/modules/libjar/nsJARChannel.cpp +++ b/modules/libjar/nsJARChannel.cpp @@ -195,6 +195,7 @@ nsJARInputThunk::IsNonBlocking(bool *nonBlocking) nsJARChannel::nsJARChannel() : mOpened(false) + , mContentDisposition(0) , mAppURI(nullptr) , mContentLength(-1) , mLoadFlags(LOAD_NORMAL) diff --git a/modules/libjar/nsJARInputStream.h b/modules/libjar/nsJARInputStream.h index 959d8b7353..1c396aa102 100644 --- a/modules/libjar/nsJARInputStream.h +++ b/modules/libjar/nsJARInputStream.h @@ -21,8 +21,8 @@ class nsJARInputStream final : public nsIInputStream { public: nsJARInputStream() : - mOutSize(0), mInCrc(0), mOutCrc(0), mCurPos(0), - mMode(MODE_NOTINITED) + mOutSize(0), mInCrc(0), mOutCrc(0), mNameLen(0), + mCurPos(0), mArrPos(0), mMode(MODE_NOTINITED) { memset(&mZs, 0, sizeof(z_stream)); } @@ -47,7 +47,7 @@ class nsJARInputStream final : public nsIInputStream z_stream mZs; // zip data structure /* For directory reading */ - RefPtr mJar; // string reference to zipreader + RefPtr mJar; // string reference to zipreader uint32_t mNameLen; // length of dirname nsCString mBuffer; // storage for generated text of stream uint32_t mCurPos; // Current position in buffer diff --git a/modules/libjar/zipwriter/nsZipWriter.cpp b/modules/libjar/zipwriter/nsZipWriter.cpp index 2490aa33d6..db2591d716 100644 --- a/modules/libjar/zipwriter/nsZipWriter.cpp +++ b/modules/libjar/zipwriter/nsZipWriter.cpp @@ -52,9 +52,10 @@ NS_IMPL_ISUPPORTS(nsZipWriter, nsIZipWriter, nsIRequestObserver) nsZipWriter::nsZipWriter() -{ - mInQueue = false; -} + : mCDSOffset(0) + , mCDSDirty(false) + , mInQueue(false) +{} nsZipWriter::~nsZipWriter() { diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 9f8595e77a..230111a29a 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -2923,7 +2923,7 @@ pref("dom.ipc.plugins.asyncInit.enabled", true); #endif // Allow the AsyncDrawing mode to be used for plugins. -pref("dom.ipc.plugins.asyncdrawing.enabled", false); +pref("dom.ipc.plugins.asyncdrawing.enabled", true); pref("dom.ipc.processCount", 1); @@ -3507,9 +3507,6 @@ pref("plugin.scan.WindowsMediaPlayer", "7.0"); // Which is currently HKLM\Software\MozillaPlugins\xxxPLIDxxx\Path pref("plugin.scan.plid.all", true); -// Allow the new AsyncDrawing mode to be used for plugins. -pref("plugin.allow.asyncdrawing", false); - // Help Windows NT, 2000, and XP dialup a RAS connection // when a network address is unreachable. pref("network.autodial-helper.enabled", true); @@ -3621,9 +3618,9 @@ pref("ui.osk.enabled", true); pref("ui.osk.detect_physical_keyboard", true); // Path to TabTip.exe on local machine. Cached for performance reasons. pref("ui.osk.on_screen_keyboard_path", ""); -// Only show the on-screen keyboard when Windows is in Tablet mode. Setting -// this pref to false will allow the OSK to show in regular non-tablet mode. -pref("ui.osk.require_tablet_mode", true); +// Only try to show the on-screen keyboard on Windows 10 and later. Setting +// this pref to false will allow the OSK to show on Windows 8 and 8.1. +pref("ui.osk.require_win10", false); // This pref stores the "reason" that the on-screen keyboard was either // shown or not shown when focus is moved to an editable text field. It is // used to help debug why the keyboard is either not appearing when expected @@ -4659,9 +4656,6 @@ pref("layers.tiles.edge-padding", true); // use with tests. pref("layers.offmainthreadcomposition.testing.enabled", false); -// whether to allow use of the basic compositor -pref("layers.offmainthreadcomposition.force-basic", false); - // Whether to animate simple opacity and transforms on the compositor #ifdef RELEASE_BUILD pref("layers.offmainthreadcomposition.async-animations", false); diff --git a/modules/libpref/nsPrefBranch.h b/modules/libpref/nsPrefBranch.h index e1123c80c4..79328cbfb7 100644 --- a/modules/libpref/nsPrefBranch.h +++ b/modules/libpref/nsPrefBranch.h @@ -200,7 +200,10 @@ protected: virtual ~nsPrefBranch(); nsPrefBranch() /* disallow use of this constructer */ - { } + : mPrefRootLength(0) + , mIsDefault(false) + , mFreeingObserverList(false) + {} nsresult GetDefaultFromPropertiesFile(const char *aPrefName, char16_t **return_buf); // As SetCharPref, but without any check on the length of |aValue| diff --git a/netwerk/dns/ChildDNSService.cpp b/netwerk/dns/ChildDNSService.cpp index 873a4dfc32..d202c68fce 100644 --- a/netwerk/dns/ChildDNSService.cpp +++ b/netwerk/dns/ChildDNSService.cpp @@ -43,6 +43,7 @@ NS_IMPL_ISUPPORTS(ChildDNSService, ChildDNSService::ChildDNSService() : mFirstTime(true) , mOffline(false) + , mDisablePrefetch(false) , mPendingRequestsLock("DNSPendingRequestsLock") { MOZ_ASSERT(IsNeckoChild()); diff --git a/netwerk/dns/DNS.cpp b/netwerk/dns/DNS.cpp index 981b89ee4e..ae8e40df14 100644 --- a/netwerk/dns/DNS.cpp +++ b/netwerk/dns/DNS.cpp @@ -261,6 +261,9 @@ NetAddrElement::~NetAddrElement() AddrInfo::AddrInfo(const char *host, const PRAddrInfo *prAddrInfo, bool disableIPv4, bool filterNameCollision, const char *cname) + : mHostName(nullptr) + , mCanonicalName(nullptr) + , ttl(NO_TTL_DATA) { MOZ_ASSERT(prAddrInfo, "Cannot construct AddrInfo with a null prAddrInfo pointer!"); const uint32_t nameCollisionAddr = htonl(0x7f003535); // 127.0.53.53 @@ -281,6 +284,9 @@ AddrInfo::AddrInfo(const char *host, const PRAddrInfo *prAddrInfo, } AddrInfo::AddrInfo(const char *host, const char *cname) + : mHostName(nullptr) + , mCanonicalName(nullptr) + , ttl(NO_TTL_DATA) { Init(host, cname); } diff --git a/netwerk/dns/DNSRequestParent.cpp b/netwerk/dns/DNSRequestParent.cpp index 0d650f0a7f..b1b03c992a 100644 --- a/netwerk/dns/DNSRequestParent.cpp +++ b/netwerk/dns/DNSRequestParent.cpp @@ -20,7 +20,8 @@ namespace mozilla { namespace net { DNSRequestParent::DNSRequestParent() - : mIPCClosed(false) + : mFlags(0) + , mIPCClosed(false) { } diff --git a/netwerk/dns/nsDNSService2.cpp b/netwerk/dns/nsDNSService2.cpp index 80447ddcbf..172405da69 100644 --- a/netwerk/dns/nsDNSService2.cpp +++ b/netwerk/dns/nsDNSService2.cpp @@ -480,8 +480,12 @@ private: nsDNSService::nsDNSService() : mLock("nsDNSServer.mLock") + , mDisableIPv6(false) + , mDisablePrefetch(false) , mFirstTime(true) , mOffline(false) + , mNotifyResolution(false) + , mOfflineLocalhost(false) { } diff --git a/netwerk/dns/nsIDNService.cpp b/netwerk/dns/nsIDNService.cpp index b03ba9cf6a..d8e3a8313f 100644 --- a/netwerk/dns/nsIDNService.cpp +++ b/netwerk/dns/nsIDNService.cpp @@ -132,6 +132,8 @@ void nsIDNService::prefsChanged(nsIPrefBranch *prefBranch, const char16_t *pref) } nsIDNService::nsIDNService() + : mShowPunycode(false) + , mIDNUseWhitelist(false) { #ifdef IDNA2008 uint32_t IDNAOptions = UIDNA_CHECK_BIDI | UIDNA_CHECK_CONTEXTJ; diff --git a/storage/mozStorageBindingParams.cpp b/storage/mozStorageBindingParams.cpp index 526f177fe2..9cb12c4bf7 100644 --- a/storage/mozStorageBindingParams.cpp +++ b/storage/mozStorageBindingParams.cpp @@ -108,6 +108,7 @@ BindingParams::BindingParams(mozIStorageBindingParamsArray *aOwningArray, : mLocked(false) , mOwningArray(aOwningArray) , mOwningStatement(aOwningStatement) +, mParamCount(0) { (void)mOwningStatement->GetParameterCount(&mParamCount); mParameters.SetCapacity(mParamCount); diff --git a/storage/mozStorageRow.h b/storage/mozStorageRow.h index 16590d1a0d..9145c40a59 100644 --- a/storage/mozStorageRow.h +++ b/storage/mozStorageRow.h @@ -24,6 +24,8 @@ public: NS_DECL_MOZISTORAGEROW NS_DECL_MOZISTORAGEVALUEARRAY + Row() : mNumCols(0) {} + /** * Initializes the object with the given statement. Copies the values from * the statement. diff --git a/storage/mozStorageStatementData.h b/storage/mozStorageStatementData.h index 97c262f011..b9d6b45c97 100644 --- a/storage/mozStorageStatementData.h +++ b/storage/mozStorageStatementData.h @@ -44,6 +44,7 @@ public: NS_PRECONDITION(mStatementOwner, "Must have a statement owner!"); } StatementData() + : mStatement(nullptr) { } ~StatementData() diff --git a/storage/mozStorageStatementParams.cpp b/storage/mozStorageStatementParams.cpp index ede4e731ba..6815b47da2 100644 --- a/storage/mozStorageStatementParams.cpp +++ b/storage/mozStorageStatementParams.cpp @@ -21,7 +21,8 @@ namespace storage { //// StatementParams StatementParams::StatementParams(mozIStorageStatement *aStatement) : - mStatement(aStatement) + mStatement(aStatement), + mParamCount(0) { NS_ASSERTION(mStatement != nullptr, "mStatement is null"); (void)mStatement->GetParameterCount(&mParamCount); diff --git a/testing/web-platform/tests/notifications/interfaces.html b/testing/web-platform/tests/notifications/interfaces.html index 71232e7124..d52de7eba2 100644 --- a/testing/web-platform/tests/notifications/interfaces.html +++ b/testing/web-platform/tests/notifications/interfaces.html @@ -20,7 +20,7 @@ typedef EventHandlerNonNull? EventHandler; [Constructor(DOMString title, optional NotificationOptions options)] interface Notification : EventTarget { static readonly attribute NotificationPermission permission; - static void requestPermission(optional NotificationPermissionCallback callback); + static Promise requestPermission(optional NotificationPermissionCallback callback); attribute EventHandler onclick; attribute EventHandler onshow; diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 426244270c..432bce16cb 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -9275,5 +9275,13 @@ "expires_in_version": "50", "kind": "count", "description": "Number of origins that have shown a web notification. Excludes system alerts like update reminders and add-ons." + }, + "PLUGIN_DRAWING_MODEL": { + "alert_emails": ["danderson@mozilla.com"], + "expires_in_version": "never", + "kind": "enumerated", + "bug_numbers": [1229961], + "n_values": 12, + "description": "Plugin drawing model. 0 when windowed, otherwise NPDrawingModel + 1." } } diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 0f4282348c..a733117b46 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -49,6 +49,7 @@ #include "prprf.h" #include "prproces.h" #include "prenv.h" +#include "prtime.h" #include "nsIAppShellService.h" #include "nsIAppStartup.h" @@ -90,6 +91,7 @@ #include "nsAppShellCID.h" #include "mozilla/scache/StartupCache.h" #include "nsIGfxInfo.h" +#include "gfxPrefs.h" #include "base/histogram.h" @@ -112,6 +114,9 @@ #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" +#if defined(XP_WIN) +#include "mozilla/a11y/Compatibility.h" +#endif #endif #include "nsCRT.h" @@ -741,9 +746,7 @@ bool gSafeMode = false; * singleton. */ class nsXULAppInfo : public nsIXULAppInfo, -#ifdef E10S_TESTING_ONLY public nsIObserver, -#endif #ifdef XP_WIN public nsIWinAppHelper, #endif @@ -759,9 +762,7 @@ public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIXULAPPINFO NS_DECL_NSIXULRUNTIME -#ifdef E10S_TESTING_ONLY NS_DECL_NSIOBSERVER -#endif #ifdef MOZ_CRASHREPORTER NS_DECL_NSICRASHREPORTER NS_DECL_NSIFINISHDUMPINGCALLBACK @@ -774,9 +775,7 @@ public: NS_INTERFACE_MAP_BEGIN(nsXULAppInfo) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULRuntime) NS_INTERFACE_MAP_ENTRY(nsIXULRuntime) -#ifdef E10S_TESTING_ONLY NS_INTERFACE_MAP_ENTRY(nsIObserver) -#endif #ifdef XP_WIN NS_INTERFACE_MAP_ENTRY(nsIWinAppHelper) #endif @@ -980,7 +979,6 @@ static bool gBrowserTabsRemoteAutostart = false; static nsString gBrowserTabsRemoteDisabledReason; static bool gBrowserTabsRemoteAutostartInitialized = false; -#ifdef E10S_TESTING_ONLY NS_IMETHODIMP nsXULAppInfo::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *aData) { if (!nsCRT::strcmp(aTopic, "getE10SBlocked")) { @@ -994,7 +992,6 @@ nsXULAppInfo::Observe(nsISupports *aSubject, const char *aTopic, const char16_t } return NS_ERROR_FAILURE; } -#endif NS_IMETHODIMP nsXULAppInfo::GetBrowserTabsRemoteAutostart(bool* aResult) @@ -1014,21 +1011,6 @@ nsXULAppInfo::GetAccessibilityEnabled(bool* aResult) return NS_OK; } -NS_IMETHODIMP -nsXULAppInfo::GetAccessibilityIsUIA(bool* aResult) -{ - *aResult = false; -#if defined(ACCESSIBILITY) && defined(XP_WIN) - // This is the same check the a11y service does to identify uia clients. - if (GetAccService() != nullptr && - (::GetModuleHandleW(L"uiautomation") || - ::GetModuleHandleW(L"uiautomationcore"))) { - *aResult = true; - } -#endif - return NS_OK; -} - NS_IMETHODIMP nsXULAppInfo::GetIs64Bit(bool* aResult) { @@ -2125,6 +2107,10 @@ ShowProfileManager(nsIToolkitProfileService* aProfileSvc, rv = xpcom.Initialize(); NS_ENSURE_SUCCESS(rv, rv); + // Initialize the graphics prefs, some of the paths need them before + // any other graphics is initialized (e.g., showing the profile chooser.) + gfxPrefs::GetSingleton(); + rv = xpcom.SetWindowCreator(aNative); NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); @@ -4536,7 +4522,6 @@ XRE_IsContentProcess() return XRE_GetProcessType() == GeckoProcessType_Content; } -#ifdef E10S_TESTING_ONLY static void LogE10sBlockedReason(const char *reason) { gBrowserTabsRemoteDisabledReason.Assign(NS_ConvertASCIItoUTF16(reason)); @@ -4549,17 +4534,27 @@ LogE10sBlockedReason(const char *reason) { console->LogStringMessage(msg.get()); } } -#endif enum { kE10sEnabledByUser = 0, kE10sEnabledByDefault = 1, kE10sDisabledByUser = 2, - kE10sDisabledInSafeMode = 3, + // kE10sDisabledInSafeMode = 3, was removed in bug 1172491. kE10sDisabledForAccessibility = 4, kE10sDisabledForMacGfx = 5, }; +const char* kAccessibilityLastRunDatePref = "accessibility.lastLoadDate"; +const char* kAccessibilityLoadedLastSessionPref = "accessibility.loadedInLastSession"; +const char* kForceEnableE10sPref = "browser.tabs.remote.force-enable"; + +static inline uint32_t +PRTimeToSeconds(PRTime t_usec) +{ + PRTime usec_per_sec = PR_USEC_PER_SEC; + return uint32_t(t_usec /= usec_per_sec); +} + bool mozilla::BrowserTabsRemoteAutostart() { @@ -4567,6 +4562,37 @@ mozilla::BrowserTabsRemoteAutostart() return gBrowserTabsRemoteAutostart; } gBrowserTabsRemoteAutostartInitialized = true; + + bool disabledForA11y = false; +#ifdef XP_WIN + /** + * Avoids enabling e10s if accessibility has recently loaded. Performs the + * following checks: + * 1) Checks a pref indicating if a11y loaded in the last session. This pref + * is set in nsBrowserGlue.js. If a11y was loaded in the last session we + * do not enable e10s in this session. + * 2) Accessibility stores a last run date (PR_IntervalNow) when it is + * initialized (see nsBaseWidget.cpp). We check if this pref exists and + * compare it to now. If a11y hasn't run in an extended period of time or + * if the date pref does not exist we load e10s. + */ + disabledForA11y = Preferences::GetBool(kAccessibilityLoadedLastSessionPref, false); + if (!disabledForA11y && + Preferences::HasUserValue(kAccessibilityLastRunDatePref)) { + #define ONE_WEEK_IN_SECONDS (60*60*24*7) + uint32_t a11yRunDate = Preferences::GetInt(kAccessibilityLastRunDatePref, 0); + MOZ_ASSERT(0 != a11yRunDate); + // If a11y hasn't run for a period of time, clear the pref and load e10s + uint32_t now = PRTimeToSeconds(PR_Now()); + uint32_t difference = now - a11yRunDate; + if (difference > ONE_WEEK_IN_SECONDS || !a11yRunDate) { + Preferences::ClearUser(kAccessibilityLastRunDatePref); + } else { + disabledForA11y = true; + } + } +#endif + bool optInPref = Preferences::GetBool("browser.tabs.remote.autostart", false); bool trialPref = Preferences::GetBool("browser.tabs.remote.autostart.2", false); bool prefEnabled = optInPref || trialPref; @@ -4578,39 +4604,32 @@ mozilla::BrowserTabsRemoteAutostart() } else { status = kE10sDisabledByUser; } -#if !defined(E10S_TESTING_ONLY) - // When running tests with 'layers.offmainthreadcomposition.testing.enabled' and - // autostart set to true, return enabled. These tests must be allowed to run - // remotely. Otherwise remote isn't allowed in non-nightly builds. - bool testPref = Preferences::GetBool("layers.offmainthreadcomposition.testing.enabled", false); - if (testPref && optInPref) { - gBrowserTabsRemoteAutostart = true; - } +#ifdef E10S_TESTING_ONLY + bool e10sAllowed = true; #else - // Nightly builds, update gBrowserTabsRemoteAutostart based on all the - // e10s remote relayed prefs we watch. - bool disabledForA11y = Preferences::GetBool("browser.tabs.remote.autostart.disabled-because-using-a11y", false); + // When running tests with 'layers.offmainthreadcomposition.testing.enabled', e10s must be + // allowed because these tests must be allowed to run remotely. + // We are also allowing e10s to be enabled on Beta (which doesn't have E10S_TESTING_ONLY defined. + bool e10sAllowed = Preferences::GetDefaultCString("app.update.channel").EqualsLiteral("beta") || + gfxPrefs::GetSingleton().LayersOffMainThreadCompositionTestingEnabled(); +#endif - if (prefEnabled) { - if (gSafeMode) { - status = kE10sDisabledInSafeMode; - LogE10sBlockedReason("Safe mode"); - } else if (disabledForA11y) { + if (e10sAllowed && prefEnabled) { + if (disabledForA11y) { status = kE10sDisabledForAccessibility; - LogE10sBlockedReason("An accessibility tool is active"); + LogE10sBlockedReason("An accessibility tool is or was active. See bug 1198459."); } else { gBrowserTabsRemoteAutostart = true; } } -#endif #if defined(XP_MACOSX) // If for any reason we suspect acceleration will be disabled, disabled // e10s auto start on mac. if (gBrowserTabsRemoteAutostart) { // Check prefs - bool accelDisabled = Preferences::GetBool("layers.acceleration.disabled", false) && - !Preferences::GetBool("layers.acceleration.force-enabled", false); + bool accelDisabled = gfxPrefs::GetSingleton().LayersAccelerationDisabled() && + !gfxPrefs::LayersAccelerationForceEnabled(); accelDisabled = accelDisabled || !nsCocoaFeatures::AccelerateByDefault(); @@ -4638,13 +4657,16 @@ mozilla::BrowserTabsRemoteAutostart() gBrowserTabsRemoteAutostart = false; status = kE10sDisabledForMacGfx; -#ifdef E10S_TESTING_ONLY LogE10sBlockedReason("Hardware acceleration is disabled"); -#endif } } #endif // defined(XP_MACOSX) + // Uber override pref for manual testing purposes + if (Preferences::GetBool(kForceEnableE10sPref, false)) { + gBrowserTabsRemoteAutostart = true; + } + mozilla::Telemetry::Accumulate(mozilla::Telemetry::E10S_AUTOSTART, gBrowserTabsRemoteAutostart); mozilla::Telemetry::Accumulate(mozilla::Telemetry::E10S_AUTOSTART_STATUS, status); if (Preferences::GetBool("browser.enabledE10SFromPrompt", false)) { diff --git a/toolkit/xre/test/win/TestDllInterceptor.cpp b/toolkit/xre/test/win/TestDllInterceptor.cpp index 48d17e8e79..8e41c93132 100644 --- a/toolkit/xre/test/win/TestDllInterceptor.cpp +++ b/toolkit/xre/test/win/TestDllInterceptor.cpp @@ -157,6 +157,9 @@ int main() TestHook("gdi32.dll", "CreateDIBSection") && TestHook("kernel32.dll", "CreateFileW") && #endif + TestHook("imm32.dll", "ImmGetContext") && + TestHook("imm32.dll", "ImmGetCompositionStringW") && + TestHook("imm32.dll", "ImmSetCandidateWindow") && TestDetour("ntdll.dll", "LdrLoadDll")) { printf("TEST-PASS | WindowsDllInterceptor | all checks passed\n"); return 0; diff --git a/tools/profiler/public/GeckoProfilerImpl.h b/tools/profiler/public/GeckoProfilerImpl.h index 6616df7074..2b8907f54e 100644 --- a/tools/profiler/public/GeckoProfilerImpl.h +++ b/tools/profiler/public/GeckoProfilerImpl.h @@ -432,6 +432,7 @@ public: // we only copy the strings at save time, so to take multiple parameters we'd need to copy them then. SamplerStackFramePrintfRAII(const char *aInfo, js::ProfileEntry::Category aCategory, uint32_t line, const char *aFormat, ...) + : mHandle(nullptr) { if (profiler_is_active() && !profiler_in_privacy_mode()) { va_list args; diff --git a/uriloader/prefetch/OfflineCacheUpdateChild.cpp b/uriloader/prefetch/OfflineCacheUpdateChild.cpp index 938d81a44c..7a29b27fb0 100644 --- a/uriloader/prefetch/OfflineCacheUpdateChild.cpp +++ b/uriloader/prefetch/OfflineCacheUpdateChild.cpp @@ -76,6 +76,7 @@ NS_IMPL_RELEASE(OfflineCacheUpdateChild) OfflineCacheUpdateChild::OfflineCacheUpdateChild(nsIDOMWindow* aWindow) : mState(STATE_UNINITIALIZED) , mIsUpgrade(false) + , mSucceeded(false) , mAppID(NECKO_NO_APP_ID) , mInBrowser(false) , mWindow(aWindow) diff --git a/uriloader/prefetch/nsOfflineCacheUpdate.cpp b/uriloader/prefetch/nsOfflineCacheUpdate.cpp index b2fccfd0e9..a7d375faca 100644 --- a/uriloader/prefetch/nsOfflineCacheUpdate.cpp +++ b/uriloader/prefetch/nsOfflineCacheUpdate.cpp @@ -689,6 +689,7 @@ nsOfflineManifestItem::nsOfflineManifestItem(nsIURI *aURI, nsIApplicationCache::ITEM_MANIFEST) , mParserState(PARSE_INIT) , mNeedsUpdate(true) + , mStrictFileOriginPolicy(false) , mManifestHashInitialized(false) { ReadStrictFileOriginPolicyPref(); @@ -1171,6 +1172,7 @@ nsOfflineCacheUpdate::nsOfflineCacheUpdate() , mRescheduleCount(0) , mPinnedEntryRetriesCount(0) , mPinned(false) + , mByteProgress(0) { } diff --git a/widget/BasicEvents.h b/widget/BasicEvents.h index 22d5415914..4a3f419b5a 100644 --- a/widget/BasicEvents.h +++ b/widget/BasicEvents.h @@ -190,6 +190,7 @@ protected: } WidgetEvent() + : time(0) { MOZ_COUNT_CTOR(WidgetEvent); } @@ -570,6 +571,7 @@ protected: } WidgetInputEvent() + : modifiers(0) { } diff --git a/widget/ContentCache.cpp b/widget/ContentCache.cpp index fb3767cab9..af4c00c67d 100644 --- a/widget/ContentCache.cpp +++ b/widget/ContentCache.cpp @@ -497,6 +497,17 @@ ContentCacheInParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent, ("ContentCacheInParent: 0x%p HandleQueryContentEvent(" "aEvent={ mMessage=eQuerySelectedText }, aWidget=0x%p)", this, aWidget)); + if (aWidget->PluginHasFocus()) { + MOZ_LOG(sContentCacheLog, LogLevel::Info, + ("ContentCacheInParent: 0x%p HandleQueryContentEvent(), " + "return emtpy selection becasue plugin has focus", + this)); + aEvent.mSucceeded = true; + aEvent.mReply.mOffset = 0; + aEvent.mReply.mReversed = false; + aEvent.mReply.mHasSelection = false; + return true; + } if (NS_WARN_IF(!IsSelectionValid())) { // If content cache hasn't been initialized properly, make the query // failed. @@ -835,7 +846,12 @@ ContentCacheInParent::OnCompositionEvent(const WidgetCompositionEvent& aEvent) // We must be able to simulate the selection because // we might not receive selection updates in time if (!mIsComposing) { - mCompositionStart = mSelection.StartOffset(); + if (aEvent.widget && aEvent.widget->PluginHasFocus()) { + // If focus is on plugin, we cannot get selection range + mCompositionStart = 0; + } else { + mCompositionStart = mSelection.StartOffset(); + } } mIsComposing = !aEvent.CausesDOMCompositionEndEvent(); diff --git a/widget/MiscEvents.h b/widget/MiscEvents.h index 4349dd786b..c2af44b5b5 100644 --- a/widget/MiscEvents.h +++ b/widget/MiscEvents.h @@ -15,6 +15,11 @@ namespace mozilla { +namespace dom { + class PBrowserParent; + class PBrowserChild; +} // namespace dom + /****************************************************************************** * mozilla::WidgetContentCommandEvent ******************************************************************************/ @@ -142,6 +147,10 @@ public: class WidgetPluginEvent : public WidgetGUIEvent { +private: + friend class dom::PBrowserParent; + friend class dom::PBrowserChild; + public: virtual WidgetPluginEvent* AsPluginEvent() override { return this; } @@ -175,6 +184,11 @@ public: retargetToFocusedDocument = aEvent.retargetToFocusedDocument; } + +protected: + WidgetPluginEvent() + { + } }; } // namespace mozilla diff --git a/widget/MouseEvents.h b/widget/MouseEvents.h index f4056c6701..5e4fa709ac 100644 --- a/widget/MouseEvents.h +++ b/widget/MouseEvents.h @@ -74,6 +74,11 @@ private: protected: WidgetMouseEventBase() + : button(0) + , buttons(0) + , pressure(0) + , hitCluster(false) + , inputSource(nsIDOMMouseEvent::MOZ_SOURCE_MOUSE) { } @@ -195,6 +200,9 @@ public: protected: WidgetMouseEvent() + : acceptActivation(false) + , ignoreRootScrollFrame(false) + , clickCount(0) { } @@ -316,6 +324,8 @@ private: friend class mozilla::dom::PBrowserChild; protected: WidgetDragEvent() + : userCancelled(false) + , mDefaultPreventedOnContent(false) { } public: @@ -373,6 +383,8 @@ class WidgetMouseScrollEvent : public WidgetMouseEventBase { private: WidgetMouseScrollEvent() + : delta(0) + , isHorizontal(false) { } @@ -436,6 +448,20 @@ private: friend class mozilla::dom::PBrowserChild; WidgetWheelEvent() + : deltaX(0.0) + , deltaY(0.0) + , deltaZ(0.0) + , deltaMode(nsIDOMWheelEvent::DOM_DELTA_PIXEL) + , customizedByUserPrefs(false) + , isMomentum(false) + , mIsNoLineOrPageDelta(false) + , lineOrPageDeltaX(0) + , lineOrPageDeltaY(0) + , scrollType(SCROLL_DEFAULT) + , overflowDeltaX(0.0) + , overflowDeltaY(0.0) + , mViewPortIsOverscrolled(false) + , mCanTriggerSwipe(false) { } @@ -601,6 +627,9 @@ class WidgetPointerEvent : public WidgetMouseEvent friend class mozilla::dom::PBrowserChild; WidgetPointerEvent() + : width(0) + , height(0) + , isPrimary(true) { } diff --git a/widget/PluginWidgetProxy.cpp b/widget/PluginWidgetProxy.cpp index 73dcfaf0fa..1908e4eae7 100644 --- a/widget/PluginWidgetProxy.cpp +++ b/widget/PluginWidgetProxy.cpp @@ -62,7 +62,7 @@ PluginWidgetProxy::Create(nsIWidget* aParent, return rv; } - BaseCreate(aParent, aRect, aInitData); + BaseCreate(aParent, aInitData); mBounds = aRect.ToUnknownRect(); mEnabled = true; diff --git a/widget/PuppetWidget.cpp b/widget/PuppetWidget.cpp index 5a41c8a13e..679f377f06 100644 --- a/widget/PuppetWidget.cpp +++ b/widget/PuppetWidget.cpp @@ -103,7 +103,7 @@ PuppetWidget::Create(nsIWidget* aParent, { MOZ_ASSERT(!aNativeParent, "got a non-Puppet native parent"); - BaseCreate(nullptr, aRect, aInitData); + BaseCreate(nullptr, aInitData); mBounds = aRect.ToUnknownRect(); mEnabled = true; @@ -685,6 +685,15 @@ PuppetWidget::SetPluginFocused(bool& aFocused) return NS_OK; } +void +PuppetWidget::DefaultProcOfPluginEvent(const WidgetPluginEvent& aEvent) +{ + if (!mTabChild) { + return; + } + mTabChild->SendDefaultProcOfPluginEvent(aEvent); +} + NS_IMETHODIMP_(void) PuppetWidget::SetInputContext(const InputContext& aContext, const InputContextAction& aAction) @@ -1397,5 +1406,15 @@ PuppetWidget::GetCurrentWidgetListener() return mAttachedWidgetListener; } +void +PuppetWidget::SetCandidateWindowForPlugin(int32_t aX, int32_t aY) +{ + if (!mTabChild) { + return; + } + + mTabChild->SendSetCandidateWindowForPlugin(aX, aY); +} + } // namespace widget } // namespace mozilla diff --git a/widget/PuppetWidget.h b/widget/PuppetWidget.h index 931212faf2..3ba9de5fb5 100644 --- a/widget/PuppetWidget.h +++ b/widget/PuppetWidget.h @@ -111,12 +111,6 @@ public: NS_IMETHOD Invalidate(const LayoutDeviceIntRect& aRect) override; - // This API is going away, steer clear. - virtual void Scroll(const nsIntPoint& aDelta, - const nsTArray& aDestRects, - const nsTArray& aReconfigureChildren) - { /* dead man walking */ } - // PuppetWidgets don't have native data, as they're purely nonnative. virtual void* GetNativeData(uint32_t aDataType) override; #if defined(XP_WIN) @@ -220,6 +214,8 @@ public: nsString& aCommitted) override; NS_IMETHOD SetPluginFocused(bool& aFocused) override; + virtual void DefaultProcOfPluginEvent( + const mozilla::WidgetPluginEvent& aEvent) override; virtual nsresult SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout, int32_t aNativeKeyCode, @@ -254,6 +250,9 @@ public: virtual uint32_t GetMaxTouchPoints() const override; virtual void StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics) override; + + virtual void SetCandidateWindowForPlugin(int32_t aX, int32_t aY) override; + protected: virtual nsresult NotifyIMEInternal( const IMENotification& aIMENotification) override; diff --git a/widget/ScreenProxy.cpp b/widget/ScreenProxy.cpp index b139612e4b..cf774a6e9a 100644 --- a/widget/ScreenProxy.cpp +++ b/widget/ScreenProxy.cpp @@ -20,7 +20,11 @@ using namespace mozilla::dom; static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); ScreenProxy::ScreenProxy(nsScreenManagerProxy* aScreenManager, ScreenDetails aDetails) - : mScreenManager(aScreenManager) + : mContentsScaleFactor(0) + , mScreenManager(aScreenManager) + , mId(0) + , mPixelDepth(0) + , mColorDepth(0) , mCacheValid(false) , mCacheWillInvalidate(false) { diff --git a/widget/TextEvents.h b/widget/TextEvents.h index 253f1d97ae..4202bceb1f 100644 --- a/widget/TextEvents.h +++ b/widget/TextEvents.h @@ -82,6 +82,20 @@ private: protected: WidgetKeyboardEvent() + : keyCode(0) + , charCode(0) + , location(nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD) + , isChar(false) + , mIsRepeat(false) + , mIsComposing(false) + , mKeyNameIndex(mozilla::KEY_NAME_INDEX_Unidentified) + , mCodeNameIndex(CODE_NAME_INDEX_UNKNOWN) + , mNativeKeyEvent(nullptr) + , mUniqueId(0) +#ifdef XP_MACOSX + , mNativeKeyCode(0) + , mNativeModifierFlags(0) +#endif { } @@ -470,6 +484,9 @@ private: friend class dom::PBrowserChild; WidgetQueryContentEvent() + : mSucceeded(false) + , mUseNativeLineBreak(true) + , mWithFontRanges(false) { MOZ_CRASH("WidgetQueryContentEvent is created without proper arguments"); } @@ -638,6 +655,7 @@ private: , mReversed(false) , mExpandToClusterBoundary(true) , mSucceeded(false) + , mUseNativeLineBreak(true) { } diff --git a/widget/TextRange.h b/widget/TextRange.h index 122cde91a7..e85a0e5841 100644 --- a/widget/TextRange.h +++ b/widget/TextRange.h @@ -256,6 +256,26 @@ public: ElementAt(i).RemoveCharacter(aOffset); } } + + bool HasCaret() const + { + for (const TextRange& range : *this) { + if (range.mRangeType == NS_TEXTRANGE_CARETPOSITION) { + return true; + } + } + return false; + } + + uint32_t GetCaretPosition() const + { + for (const TextRange& range : *this) { + if (range.mRangeType == NS_TEXTRANGE_CARETPOSITION) { + return range.mStartOffset; + } + } + return UINT32_MAX; + } }; } // namespace mozilla diff --git a/widget/cocoa/nsChildView.h b/widget/cocoa/nsChildView.h index 76217b6bcc..d9be724e51 100644 --- a/widget/cocoa/nsChildView.h +++ b/widget/cocoa/nsChildView.h @@ -537,7 +537,7 @@ public: return nsCocoaUtils::DevPixelsToCocoaPoints(aRect, BackingScaleFactor()); } - already_AddRefed StartRemoteDrawing() override; + already_AddRefed StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) override; void EndRemoteDrawing() override; void CleanupRemoteDrawing() override; bool InitCompositor(mozilla::layers::Compositor* aCompositor) override; diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index ce1c6084d5..48f8e476eb 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -318,6 +318,7 @@ public: protected: RefPtr mUpdateDrawTarget; + UniquePtr mUpdateDrawTargetData; GLContext* mGLContext; LayoutDeviceIntRegion mUpdateRegion; LayoutDeviceIntSize mUsedSize; @@ -336,7 +337,9 @@ class GLPresenter : public GLManager public: static GLPresenter* CreateForWindow(nsIWidget* aWindow) { - RefPtr context = gl::GLContextProvider::CreateForWindow(aWindow); + // Contrary to CompositorOGL, we allow unaccelerated OpenGL contexts to be + // used. BasicCompositor only requires very basic GL functionality. + RefPtr context = gl::GLContextProvider::CreateForWindow(aWindow, false); return context ? new GLPresenter(context) : nullptr; } @@ -498,7 +501,7 @@ nsresult nsChildView::Create(nsIWidget* aParent, // Ensure that the toolkit is created. nsToolkit::GetToolkit(); - BaseCreate(aParent, aRect, aInitData); + BaseCreate(aParent, aInitData); // inherit things from the parent view and create our parallel // NSView in the Cocoa display system @@ -2637,7 +2640,7 @@ nsChildView::SwipeFinished() } already_AddRefed -nsChildView::StartRemoteDrawing() +nsChildView::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) { // should have created the GLPresenter in InitCompositor. MOZ_ASSERT(mGLPresenter); @@ -2649,7 +2652,7 @@ nsChildView::StartRemoteDrawing() } } - LayoutDeviceIntRegion dirtyRegion(LayoutDeviceIntRect::FromUnknownRect(mBounds)); + LayoutDeviceIntRegion dirtyRegion(aInvalidRegion); LayoutDeviceIntSize renderSize = LayoutDeviceIntSize::FromUnknownSize(mBounds.Size()); @@ -2666,6 +2669,8 @@ nsChildView::StartRemoteDrawing() return nullptr; } + aInvalidRegion = mBasicCompositorImage->GetUpdateRegion(); + return drawTarget.forget(); } @@ -2935,9 +2940,15 @@ RectTextureImage::BeginUpdate(const LayoutDeviceIntSize& aNewSize, LayoutDeviceIntSize neededBufferSize = TextureSizeForSize(mUsedSize); if (!mUpdateDrawTarget || mBufferSize != neededBufferSize) { gfx::IntSize size(neededBufferSize.width, neededBufferSize.height); + mUpdateDrawTarget = nullptr; + mUpdateDrawTargetData = nullptr; + gfx::SurfaceFormat format = gfx::SurfaceFormat::B8G8R8A8; + int32_t stride = size.width * gfx::BytesPerPixel(format); + mUpdateDrawTargetData = MakeUnique(stride * size.height); mUpdateDrawTarget = - gfx::Factory::CreateDrawTarget(gfx::BackendType::COREGRAPHICS, size, - gfx::SurfaceFormat::B8G8R8A8); + gfx::Factory::CreateDrawTargetForData(gfx::BackendType::COREGRAPHICS, + mUpdateDrawTargetData.get(), size, + stride, format); mBufferSize = neededBufferSize; } @@ -2976,21 +2987,22 @@ RectTextureImage::EndUpdate(bool aKeepSurface) LayoutDeviceIntRect(LayoutDeviceIntPoint(0, 0), mTextureSize); } - RefPtr snapshot = mUpdateDrawTarget->Snapshot(); - RefPtr dataSnapshot = snapshot->GetDataSurface(); + gfx::IntPoint srcPoint = updateRegion.GetBounds().TopLeft().ToUnknownPoint(); + gfx::SurfaceFormat format = mUpdateDrawTarget->GetFormat(); + int bpp = gfx::BytesPerPixel(format); + int32_t stride = mBufferSize.width * bpp; + unsigned char* data = mUpdateDrawTargetData.get(); + data += srcPoint.y * stride + srcPoint.x * bpp; - UploadSurfaceToTexture(mGLContext, - dataSnapshot, - updateRegion.ToUnknownRegion(), - mTexture, - overwriteTexture, - updateRegion.GetBounds().TopLeft().ToUnknownPoint(), - false, - LOCAL_GL_TEXTURE0, - LOCAL_GL_TEXTURE_RECTANGLE_ARB); + UploadImageDataToTexture(mGLContext, data, stride, format, + updateRegion.ToUnknownRegion(), mTexture, + overwriteTexture, /* aPixelBuffer = */ false, + LOCAL_GL_TEXTURE0, + LOCAL_GL_TEXTURE_RECTANGLE_ARB); if (!aKeepSurface) { mUpdateDrawTarget = nullptr; + mUpdateDrawTargetData = nullptr; } mInUpdate = false; diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index 4a746b9220..68f072b22f 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -269,11 +269,7 @@ nsresult nsCocoaWindow::Create(nsIWidget* aParent, // Ensure that the toolkit is created. nsToolkit::GetToolkit(); - // newBounds is still display (global screen) pixels at this point; - // fortunately, BaseCreate doesn't actually use it so we don't - // need to worry about trying to convert it to device pixels - // when we don't have a window (or dev context, perhaps) yet - Inherited::BaseCreate(aParent, newBounds, aInitData); + Inherited::BaseCreate(aParent, aInitData); mParent = aParent; mAncestorLink = aParent; diff --git a/widget/cocoa/nsDeviceContextSpecX.mm b/widget/cocoa/nsDeviceContextSpecX.mm index 6ac66060c1..39563da0a4 100644 --- a/widget/cocoa/nsDeviceContextSpecX.mm +++ b/widget/cocoa/nsDeviceContextSpecX.mm @@ -157,7 +157,7 @@ NS_IMETHODIMP nsDeviceContextSpecX::GetSurfaceForPrinter(gfxASurface **surface) CGContextScaleCTM(context, 1.0, -1.0); newSurface = new gfxQuartzSurface(context, gfxSize(width, height)); } else { - newSurface = new gfxQuartzSurface(gfxSize((int32_t)width, (int32_t)height), gfxImageFormat::ARGB32); + newSurface = new gfxQuartzSurface(gfxSize((int32_t)width, (int32_t)height), SurfaceFormat::A8R8G8B8_UINT32); } if (!newSurface) diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp index b1e98020d4..35b53e6b95 100644 --- a/widget/gonk/nsWindow.cpp +++ b/widget/gonk/nsWindow.cpp @@ -335,7 +335,7 @@ nsWindow::Create(nsIWidget* aParent, const LayoutDeviceIntRect& aRect, nsWidgetInitData* aInitData) { - BaseCreate(aParent, aRect, aInitData); + BaseCreate(aParent, aInitData); nsCOMPtr screen; diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 4adefa8162..6683c43e11 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -2227,7 +2227,7 @@ nsWindow::OnExposeEvent(cairo_t *cr) return TRUE; } - RefPtr dt = GetDrawTarget(region.ToUnknownRegion()); + RefPtr dt = GetDrawTarget(region); if (!dt) { return FALSE; } @@ -2311,7 +2311,7 @@ nsWindow::OnExposeEvent(cairo_t *cr) # ifdef MOZ_HAVE_SHMIMAGE if (mShmImage && MOZ_LIKELY(!mIsDestroyed)) { - mShmImage->Put(mXDisplay, mXWindow, region.ToUnknownRegion()); + mShmImage->Put(mXDisplay, mXWindow, region); } # endif // MOZ_HAVE_SHMIMAGE #endif // MOZ_X11 @@ -3530,7 +3530,7 @@ nsWindow::Create(nsIWidget* aParent, nsGTKToolkit::GetToolkit(); // initialize all the common bits of this class - BaseCreate(baseParent, aRect, aInitData); + BaseCreate(baseParent, aInitData); // Do we need to listen for resizes? bool listenForResizes = false;; @@ -6314,14 +6314,14 @@ nsWindow::GetSurfaceForGdkDrawable(GdkDrawable* aDrawable, #endif already_AddRefed -nsWindow::GetDrawTarget(const nsIntRegion& aRegion) +nsWindow::GetDrawTarget(const LayoutDeviceIntRegion& aRegion) { if (!mGdkWindow) { return nullptr; } - nsIntRect bounds = aRegion.GetBounds(); - IntSize size(bounds.XMost(), bounds.YMost()); + LayoutDeviceIntRect bounds = aRegion.GetBounds(); + LayoutDeviceIntSize size(bounds.XMost(), bounds.YMost()); if (size.width <= 0 || size.height <= 0) { return nullptr; } @@ -6332,12 +6332,11 @@ nsWindow::GetDrawTarget(const nsIntRegion& aRegion) # ifdef MOZ_HAVE_SHMIMAGE if (nsShmImage::UseShm()) { dt = nsShmImage::EnsureShmImage(size, - mXDisplay, mXVisual, mXDepth, - mShmImage); + mXDisplay, mXVisual, mXDepth, mShmImage); } # endif // MOZ_HAVE_SHMIMAGE if (!dt) { - RefPtr surf = new gfxXlibSurface(mXDisplay, mXWindow, mXVisual, size); + RefPtr surf = new gfxXlibSurface(mXDisplay, mXWindow, mXVisual, size.ToUnknownSize()); if (!surf->CairoStatus()) { dt = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surf.get(), surf->GetSize()); } @@ -6348,13 +6347,14 @@ nsWindow::GetDrawTarget(const nsIntRegion& aRegion) } already_AddRefed -nsWindow::StartRemoteDrawingInRegion(nsIntRegion& aInvalidRegion) +nsWindow::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) { return GetDrawTarget(aInvalidRegion); } void -nsWindow::EndRemoteDrawingInRegion(DrawTarget* aDrawTarget, nsIntRegion& aInvalidRegion) +nsWindow::EndRemoteDrawingInRegion(DrawTarget* aDrawTarget, + LayoutDeviceIntRegion& aInvalidRegion) { #ifdef MOZ_X11 # ifdef MOZ_HAVE_SHMIMAGE diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index e1d2a1ceb4..6aec72d1e0 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -209,9 +209,9 @@ public: #endif virtual already_AddRefed - StartRemoteDrawingInRegion(nsIntRegion& aInvalidRegion) override; + StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) override; virtual void EndRemoteDrawingInRegion(mozilla::gfx::DrawTarget* aDrawTarget, - nsIntRegion& aInvalidRegion) override; + LayoutDeviceIntRegion& aInvalidRegion) override; private: void UpdateAlpha(mozilla::gfx::SourceSurface* aSourceSurface, nsIntRect aBoundsRect); @@ -302,7 +302,7 @@ public: virtual nsresult ConfigureChildren(const nsTArray& aConfigurations) override; nsresult UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect, uint8_t* aAlphas, int32_t aStride); - virtual already_AddRefed GetDrawTarget(const nsIntRegion& aRegion); + virtual already_AddRefed GetDrawTarget(const LayoutDeviceIntRegion& aRegion); #if (MOZ_WIDGET_GTK == 2) static already_AddRefed GetSurfaceForGdkDrawable(GdkDrawable* aDrawable, diff --git a/widget/nsBaseWidget.cpp b/widget/nsBaseWidget.cpp index 69af636507..4feafa3e53 100644 --- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -311,7 +311,6 @@ nsBaseWidget::~nsBaseWidget() // //------------------------------------------------------------------------- void nsBaseWidget::BaseCreate(nsIWidget* aParent, - const LayoutDeviceIntRect& aRect, nsWidgetInitData* aInitData) { static bool gDisableNativeThemeCached = false; @@ -1765,6 +1764,16 @@ nsBaseWidget::GetTextEventDispatcher() #ifdef ACCESSIBILITY +// defined in nsAppRunner.cpp +extern const char* kAccessibilityLastRunDatePref; + +static inline uint32_t +PRTimeToSeconds(PRTime t_usec) +{ + PRTime usec_per_sec = PR_USEC_PER_SEC; + return uint32_t(t_usec /= usec_per_sec); +} + a11y::Accessible* nsBaseWidget::GetRootAccessible() { @@ -1783,6 +1792,8 @@ nsBaseWidget::GetRootAccessible() nsCOMPtr accService = services::GetAccessibilityService(); if (accService) { + uint32_t now = PRTimeToSeconds(PR_Now()); + Preferences::SetInt(kAccessibilityLastRunDatePref, now); return accService->GetRootDocumentAccessible(presShell, nsContentUtils::IsSafeToRunScript()); } diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h index 0e986b0fd0..1a68bbcc8b 100644 --- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -212,6 +212,12 @@ public: { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHOD SetPluginFocused(bool& aFocused) override { return NS_ERROR_NOT_IMPLEMENTED; } + virtual void SetCandidateWindowForPlugin(int32_t aX, + int32_t aY) override + { } + virtual void DefaultProcOfPluginEvent( + const mozilla::WidgetPluginEvent& aEvent) override + { } NS_IMETHOD AttachNativeKeyEvent(mozilla::WidgetKeyboardEvent& aEvent) override { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHOD_(bool) ExecuteNativeKeyBinding( NativeKeyBindingsType aType, @@ -342,7 +348,6 @@ protected: nsIFile **aResult); virtual void OnDestroy(); void BaseCreate(nsIWidget *aParent, - const LayoutDeviceIntRect& aRect, nsWidgetInitData* aInitData); virtual void ConfigureAPZCTreeManager(); diff --git a/widget/nsDeviceContextSpecProxy.cpp b/widget/nsDeviceContextSpecProxy.cpp index 5aa471025f..c7fde06b2f 100644 --- a/widget/nsDeviceContextSpecProxy.cpp +++ b/widget/nsDeviceContextSpecProxy.cpp @@ -79,7 +79,7 @@ nsDeviceContextSpecProxy::GetSurfaceForPrinter(gfxASurface** aSurface) RefPtr surface = gfxPlatform::GetPlatform()-> CreateOffscreenSurface(mozilla::gfx::IntSize(width, height), - gfxImageFormat::ARGB32); + SurfaceFormat::A8R8G8B8_UINT32); surface.forget(aSurface); return NS_OK; diff --git a/widget/nsFilePickerProxy.cpp b/widget/nsFilePickerProxy.cpp index 0b9a5e5cb5..8e6e71e28f 100644 --- a/widget/nsFilePickerProxy.cpp +++ b/widget/nsFilePickerProxy.cpp @@ -16,6 +16,7 @@ using namespace mozilla::dom; NS_IMPL_ISUPPORTS(nsFilePickerProxy, nsIFilePicker) nsFilePickerProxy::nsFilePickerProxy() + : mSelectedType(0) { } diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index e35f4e1ba9..325c3905e5 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -56,15 +56,15 @@ class LayerManager; class LayerManagerComposite; class PLayerTransactionChild; struct ScrollableLayerGuid; -} +} // namespace layers namespace gfx { class DrawTarget; class SourceSurface; -} +} // namespace gfx namespace widget { class TextEventDispatcher; -} -} +} // namespace widget +} // namespace mozilla /** * Callback function that processes events. @@ -127,10 +127,13 @@ typedef void* nsNativeWidget; // set/get nsPluginNativeWindowGtk, e10s specific #define NS_NATIVE_PLUGIN_OBJECT_PTR 104 #endif +#ifdef MOZ_WIDGET_ANDROID +#define NS_NATIVE_NEW_EGL_SURFACE 100 +#endif #define NS_IWIDGET_IID \ -{ 0x7b736a0c, 0x2262, 0x4f37, \ - { 0xbd, 0xed, 0xe5, 0x60, 0x88, 0x1c, 0x36, 0xdd } } +{ 0x73c0a475, 0x450f, 0x4202, \ + { 0xab, 0xb4, 0x62, 0xf8, 0x9d, 0xbe, 0xf7, 0x9a } } /* * Window shadow styles @@ -1225,7 +1228,7 @@ class nsIWidget : public nsISupports { * before each composition. */ virtual already_AddRefed StartRemoteDrawing() = 0; - virtual already_AddRefed StartRemoteDrawingInRegion(nsIntRegion& aInvalidRegion) { + virtual already_AddRefed StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion) { return StartRemoteDrawing(); } @@ -1237,7 +1240,7 @@ class nsIWidget : public nsISupports { * after each composition. */ virtual void EndRemoteDrawing() = 0; - virtual void EndRemoteDrawingInRegion(mozilla::gfx::DrawTarget* aDrawTarget, nsIntRegion& aInvalidRegion) { + virtual void EndRemoteDrawingInRegion(mozilla::gfx::DrawTarget* aDrawTarget, LayoutDeviceIntRegion& aInvalidRegion) { EndRemoteDrawing(); } @@ -1760,6 +1763,25 @@ public: */ NS_IMETHOD SetPluginFocused(bool& aFocused) = 0; + /* + * Tell the plugin has focus. It is unnecessary to use IPC + */ + bool PluginHasFocus() + { + return GetInputContext().mIMEState.mEnabled == IMEState::PLUGIN; + } + + /** + * Set IME candidate window position by windowless plugin. + */ + virtual void SetCandidateWindowForPlugin(int32_t aX, int32_t aY) = 0; + + /** + * Handle default action when PluginEvent isn't handled + */ + virtual void DefaultProcOfPluginEvent( + const mozilla::WidgetPluginEvent& aEvent) = 0; + /* * Notifies the input context changes. */ diff --git a/widget/nsShmImage.cpp b/widget/nsShmImage.cpp index 88571fda82..82a28eeb18 100644 --- a/widget/nsShmImage.cpp +++ b/widget/nsShmImage.cpp @@ -46,7 +46,7 @@ TrapShmError(Display* aDisplay, XErrorEvent* aEvent) #endif already_AddRefed -nsShmImage::Create(const IntSize& aSize, +nsShmImage::Create(const LayoutDeviceIntSize& aSize, Display* aDisplay, Visual* aVisual, unsigned int aDepth) { RefPtr shm = new nsShmImage(); @@ -128,20 +128,22 @@ nsShmImage::CreateDrawTarget() { return gfxPlatform::GetPlatform()->CreateDrawTargetForData( static_cast(mSegment->memory()), - mSize, + mSize.ToUnknownSize(), mImage->bytes_per_line, mFormat); } #ifdef MOZ_WIDGET_GTK void -nsShmImage::Put(Display* aDisplay, Drawable aWindow, const nsIntRegion& aRegion) +nsShmImage::Put(Display* aDisplay, Drawable aWindow, + const LayoutDeviceIntRegion& aRegion) { GC gc = XCreateGC(aDisplay, aWindow, 0, nullptr); - nsIntRegion bounded; - bounded.And(aRegion, nsIntRect(0, 0, mImage->width, mImage->height)); - nsIntRegionRectIterator iter(bounded); - for (const nsIntRect *r = iter.Next(); r; r = iter.Next()) { + LayoutDeviceIntRegion bounded; + bounded.And(aRegion, + LayoutDeviceIntRect(0, 0, mImage->width, mImage->height)); + LayoutDeviceIntRegion::RectIterator iter(bounded); + for (const LayoutDeviceIntRect *r = iter.Next(); r; r = iter.Next()) { XShmPutImage(aDisplay, aWindow, gc, mImage, r->x, r->y, r->x, r->y, @@ -180,7 +182,7 @@ nsShmImage::Put(QWindow* aWindow, QRect& aRect) #endif already_AddRefed -nsShmImage::EnsureShmImage(const IntSize& aSize, +nsShmImage::EnsureShmImage(const LayoutDeviceIntSize& aSize, Display* aDisplay, Visual* aVisual, unsigned int aDepth, RefPtr& aImage) { diff --git a/widget/nsShmImage.h b/widget/nsShmImage.h index b0edd7075b..ae755c8e16 100644 --- a/widget/nsShmImage.h +++ b/widget/nsShmImage.h @@ -38,10 +38,10 @@ class nsShmImage { public: static bool UseShm(); static already_AddRefed - Create(const mozilla::gfx::IntSize& aSize, + Create(const mozilla::LayoutDeviceIntSize& aSize, Display* aDisplay, Visual* aVisual, unsigned int aDepth); static already_AddRefed - EnsureShmImage(const mozilla::gfx::IntSize& aSize, + EnsureShmImage(const mozilla::LayoutDeviceIntSize& aSize, Display* aDisplay, Visual* aVisual, unsigned int aDepth, RefPtr& aImage); @@ -60,12 +60,13 @@ public: already_AddRefed CreateDrawTarget(); #ifdef MOZ_WIDGET_GTK - void Put(Display* aDisplay, Drawable aWindow, const nsIntRegion& aRegion); + void Put(Display* aDisplay, Drawable aWindow, + const LayoutDeviceIntRegion& aRegion); #elif defined(MOZ_WIDGET_QT) void Put(QWindow* aWindow, QRect& aRect); #endif - mozilla::gfx::IntSize Size() const { return mSize; } + mozilla::LayoutDeviceIntSize Size() const { return mSize; } private: nsShmImage() @@ -79,7 +80,7 @@ private: XImage* mImage; Display* mDisplay; XShmSegmentInfo mInfo; - mozilla::gfx::IntSize mSize; + mozilla::LayoutDeviceIntSize mSize; mozilla::gfx::SurfaceFormat mFormat; bool mXAttached; }; diff --git a/widget/qt/nsWindow.cpp b/widget/qt/nsWindow.cpp index 51733e8331..3aa9117342 100644 --- a/widget/qt/nsWindow.cpp +++ b/widget/qt/nsWindow.cpp @@ -143,7 +143,7 @@ nsWindow::Create(nsIWidget* aParent, nsIWidget *baseParent = aParent; // initialize all the common bits of this class - BaseCreate(baseParent, aRect, aInitData); + BaseCreate(baseParent, aInitData); mVisible = true; diff --git a/widget/uikit/nsWindow.mm b/widget/uikit/nsWindow.mm index b8c516a454..7319b6985c 100644 --- a/widget/uikit/nsWindow.mm +++ b/widget/uikit/nsWindow.mm @@ -503,9 +503,7 @@ nsWindow::Create(nsIWidget* aParent, mWindowType = eWindowType_toplevel; mBorderStyle = eBorderStyle_default; - Inherited::BaseCreate(aParent, - LayoutDeviceIntRect::FromUnknownRect(mBounds), - aInitData); + Inherited::BaseCreate(aParent, aInitData); NS_ASSERTION(IsTopLevel() || parent, "non top level window doesn't have a parent!"); diff --git a/widget/windows/IMMHandler.cpp b/widget/windows/IMMHandler.cpp index 1a8e4b4e68..03927dca51 100644 --- a/widget/windows/IMMHandler.cpp +++ b/widget/windows/IMMHandler.cpp @@ -579,7 +579,8 @@ IMMHandler::MaybeAdjustCompositionFont(nsWindow* aWindow, // Like Navi-Bar of ATOK, some IMEs may require proper composition font even // before sending WM_IME_STARTCOMPOSITION. IMEContext context(aWindow); - gIMMHandler->AdjustCompositionFont(context, aWritingMode, aForceUpdate); + gIMMHandler->AdjustCompositionFont(aWindow, context, aWritingMode, + aForceUpdate); } // static @@ -617,10 +618,13 @@ IMMHandler::ProcessMessage(nsWindow* aWindow, // if the new window handle is not focused, probably, we should not start // the composition, however, such case should not be, it's just bad scenario. - // When a plug-in has focus or compsition, we should dispatch the IME events - // to the plug-in. - if (aWindow->PluginHasFocus() || IsComposingOnPlugin()) { - return ProcessMessageForPlugin(aWindow, msg, wParam, lParam, aResult); + // When a plug-in has focus, we should dispatch the IME events to + // the plug-in at first. + if (aWindow->PluginHasFocus()) { + bool ret = false; + if (ProcessMessageForPlugin(aWindow, msg, wParam, lParam, ret, aResult)) { + return ret; + } } aResult.mResult = 0; @@ -665,6 +669,7 @@ IMMHandler::ProcessMessageForPlugin(nsWindow* aWindow, UINT msg, WPARAM& wParam, LPARAM& lParam, + bool& aRet, MSGResult& aResult) { aResult.mResult = 0; @@ -673,38 +678,35 @@ IMMHandler::ProcessMessageForPlugin(nsWindow* aWindow, case WM_INPUTLANGCHANGEREQUEST: case WM_INPUTLANGCHANGE: aWindow->DispatchPluginEvent(msg, wParam, lParam, false); - return ProcessInputLangChangeMessage(aWindow, wParam, lParam, aResult); - case WM_IME_COMPOSITION: - EnsureHandlerInstance(); - return gIMMHandler->OnIMECompositionOnPlugin(aWindow, wParam, lParam, - aResult); - case WM_IME_STARTCOMPOSITION: - EnsureHandlerInstance(); - return gIMMHandler->OnIMEStartCompositionOnPlugin(aWindow, wParam, - lParam, aResult); - case WM_IME_ENDCOMPOSITION: - EnsureHandlerInstance(); - return gIMMHandler->OnIMEEndCompositionOnPlugin(aWindow, wParam, lParam, - aResult); + aRet = ProcessInputLangChangeMessage(aWindow, wParam, lParam, aResult); + return true; case WM_IME_CHAR: EnsureHandlerInstance(); - return gIMMHandler->OnIMECharOnPlugin(aWindow, wParam, lParam, aResult); + aRet = gIMMHandler->OnIMECharOnPlugin(aWindow, wParam, lParam, aResult); + return true; case WM_IME_SETCONTEXT: - return OnIMESetContextOnPlugin(aWindow, wParam, lParam, aResult); + aRet = OnIMESetContextOnPlugin(aWindow, wParam, lParam, aResult); + return true; case WM_CHAR: if (!gIMMHandler) { - return false; + return true; } - return gIMMHandler->OnCharOnPlugin(aWindow, wParam, lParam, aResult); + aRet = gIMMHandler->OnCharOnPlugin(aWindow, wParam, lParam, aResult); + return true; case WM_IME_COMPOSITIONFULL: case WM_IME_CONTROL: case WM_IME_KEYDOWN: case WM_IME_KEYUP: - case WM_IME_REQUEST: case WM_IME_SELECT: aResult.mConsumed = aWindow->DispatchPluginEvent(msg, wParam, lParam, false); + aRet = true; return true; + case WM_IME_REQUEST: + // Our plugin implementation is alwasy OOP. So WM_IME_REQUEST doesn't + // allow that parameter is pointer and shouldn't handle into Gecko. + aRet = false; + return true; } return false; } @@ -766,9 +768,6 @@ IMMHandler::OnIMEComposition(nsWindow* aWindow, GetBoolName(lParam & GCS_COMPATTR), GetBoolName(lParam & GCS_COMPCLAUSE), GetBoolName(lParam & GCS_CURSORPOS))); - MOZ_ASSERT(!aWindow->PluginHasFocus(), - "OnIMEComposition should not be called when a plug-in has focus"); - IMEContext context(aWindow); aResult.mConsumed = HandleComposition(aWindow, context, lParam); return true; @@ -1083,11 +1082,10 @@ IMMHandler::OnChar(nsWindow* aWindow, * message handlers for plug-in ****************************************************************************/ -bool +void IMMHandler::OnIMEStartCompositionOnPlugin(nsWindow* aWindow, WPARAM wParam, - LPARAM lParam, - MSGResult& aResult) + LPARAM lParam) { MOZ_LOG(gIMMLog, LogLevel::Info, ("IMM: OnIMEStartCompositionOnPlugin, hWnd=%08x, mIsComposingOnPlugin=%s", @@ -1098,18 +1096,13 @@ IMMHandler::OnIMEStartCompositionOnPlugin(nsWindow* aWindow, SetIMERelatedWindowsPosOnPlugin(aWindow, context); // On widnowless plugin, we should assume that the focused editor is always // in horizontal writing mode. - AdjustCompositionFont(context, WritingMode()); - aResult.mConsumed = - aWindow->DispatchPluginEvent(WM_IME_STARTCOMPOSITION, wParam, lParam, - false); - return true; + AdjustCompositionFont(aWindow, context, WritingMode()); } -bool +void IMMHandler::OnIMECompositionOnPlugin(nsWindow* aWindow, WPARAM wParam, - LPARAM lParam, - MSGResult& aResult) + LPARAM lParam) { MOZ_LOG(gIMMLog, LogLevel::Info, ("IMM: OnIMECompositionOnPlugin, hWnd=%08x, lParam=%08x, " @@ -1123,6 +1116,7 @@ IMMHandler::OnIMECompositionOnPlugin(nsWindow* aWindow, if (IS_COMMITTING_LPARAM(lParam)) { mIsComposingOnPlugin = false; mComposingWindow = nullptr; + return; } // Continue composition if there is still a string being composed. if (IS_COMPOSING_LPARAM(lParam)) { @@ -1131,16 +1125,12 @@ IMMHandler::OnIMECompositionOnPlugin(nsWindow* aWindow, IMEContext context(aWindow); SetIMERelatedWindowsPosOnPlugin(aWindow, context); } - aResult.mConsumed = - aWindow->DispatchPluginEvent(WM_IME_COMPOSITION, wParam, lParam, true); - return true; } -bool +void IMMHandler::OnIMEEndCompositionOnPlugin(nsWindow* aWindow, WPARAM wParam, - LPARAM lParam, - MSGResult& aResult) + LPARAM lParam) { MOZ_LOG(gIMMLog, LogLevel::Info, ("IMM: OnIMEEndCompositionOnPlugin, hWnd=%08x, mIsComposingOnPlugin=%s", @@ -1153,11 +1143,6 @@ IMMHandler::OnIMEEndCompositionOnPlugin(nsWindow* aWindow, ::DestroyCaret(); mNativeCaretIsCreated = false; } - - aResult.mConsumed = - aWindow->DispatchPluginEvent(WM_IME_ENDCOMPOSITION, wParam, lParam, - false); - return true; } bool @@ -1226,6 +1211,12 @@ IMMHandler::OnCharOnPlugin(nsWindow* aWindow, LPARAM lParam, MSGResult& aResult) { + NS_WARNING("OnCharOnPlugin"); + if (mIsComposing) { + aWindow->NotifyIME(REQUEST_TO_COMMIT_COMPOSITION); + return true; + } + // We should never consume char message on windowless plugin. aResult.mConsumed = false; if (IsIMECharRecordsEmpty()) { @@ -1258,8 +1249,6 @@ IMMHandler::HandleStartComposition(nsWindow* aWindow, { NS_PRECONDITION(!mIsComposing, "HandleStartComposition is called but mIsComposing is TRUE"); - NS_PRECONDITION(!aWindow->PluginHasFocus(), - "HandleStartComposition should not be called when a plug-in has focus"); Selection& selection = GetSelection(); if (!selection.EnsureValidSelection(aWindow)) { @@ -1269,7 +1258,7 @@ IMMHandler::HandleStartComposition(nsWindow* aWindow, return; } - AdjustCompositionFont(aContext, selection.mWritingMode); + AdjustCompositionFont(aWindow, aContext, selection.mWritingMode); mCompositionStart = selection.mOffset; mCursorPosition = NO_IME_CARET; @@ -1292,9 +1281,6 @@ IMMHandler::HandleComposition(nsWindow* aWindow, const IMEContext& aContext, LPARAM lParam) { - NS_PRECONDITION(!aWindow->PluginHasFocus(), - "HandleComposition should not be called when a plug-in has focus"); - // for bug #60050 // MS-IME 95/97/98/2000 may send WM_IME_COMPOSITION with non-conversion // mode before it send WM_IME_STARTCOMPOSITION. @@ -1535,8 +1521,6 @@ IMMHandler::HandleEndComposition(nsWindow* aWindow, { MOZ_ASSERT(mIsComposing, "HandleEndComposition is called but mIsComposing is FALSE"); - MOZ_ASSERT(!aWindow->PluginHasFocus(), - "HandleComposition should not be called when a plug-in has focus"); MOZ_LOG(gIMMLog, LogLevel::Info, ("IMM: HandleEndComposition(aWindow=0x%p, aCommitString=0x%p (\"%s\"))", @@ -1842,9 +1826,8 @@ IMMHandler::CommitCompositionOnPreviousWindow(nsWindow* aWindow) } MOZ_LOG(gIMMLog, LogLevel::Info, - ("IMM: CommitCompositionOnPreviousWindow, mIsComposing=%s, " - "mIsComposingOnPlugin=%s", - GetBoolName(mIsComposing), GetBoolName(mIsComposingOnPlugin))); + ("IMM: CommitCompositionOnPreviousWindow, mIsComposing=%s", + GetBoolName(mIsComposing))); // If we have composition, we should dispatch composition events internally. if (mIsComposing) { @@ -1855,9 +1838,7 @@ IMMHandler::CommitCompositionOnPreviousWindow(nsWindow* aWindow) return true; } - // XXX When plug-in has composition, we should commit composition on the - // plug-in. However, we need some more work for that. - return mIsComposingOnPlugin; + return false; } static uint32_t @@ -2505,7 +2486,8 @@ SetVerticalFontToLogFont(const nsAString& aFontFace, } void -IMMHandler::AdjustCompositionFont(const IMEContext& aContext, +IMMHandler::AdjustCompositionFont(nsWindow* aWindow, + const IMEContext& aContext, const WritingMode& aWritingMode, bool aForceUpdate) { @@ -2591,8 +2573,8 @@ IMMHandler::AdjustCompositionFont(const IMEContext& aContext, logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; logFont.lfPitchAndFamily = DEFAULT_PITCH; - if (!mIsComposingOnPlugin && - aWritingMode.IsVertical() && IsVerticalWritingSupported()) { + if (!aWindow->PluginHasFocus() && + aWritingMode.IsVertical() && IsVerticalWritingSupported()) { SetVerticalFontToLogFont( IsJapanist2003Active() ? sCompositionFontForJapanist2003 : sCompositionFont, logFont); @@ -2733,6 +2715,41 @@ IMMHandler::OnKeyDownEvent(nsWindow* aWindow, } } +// static +void +IMMHandler::SetCandidateWindow(nsWindow* aWindow, CANDIDATEFORM* aForm) +{ + IMEContext context(aWindow); + ImmSetCandidateWindow(context.get(), aForm); +} + +// staitc +void +IMMHandler::DefaultProcOfPluginEvent(nsWindow* aWindow, const NPEvent* aEvent) +{ + switch (aEvent->event) { + case WM_IME_STARTCOMPOSITION: + EnsureHandlerInstance(); + gIMMHandler->OnIMEStartCompositionOnPlugin(aWindow, aEvent->wParam, + aEvent->lParam); + break; + + case WM_IME_COMPOSITION: + if (gIMMHandler) { + gIMMHandler->OnIMECompositionOnPlugin(aWindow, aEvent->wParam, + aEvent->lParam); + } + break; + + case WM_IME_ENDCOMPOSITION: + if (gIMMHandler) { + gIMMHandler->OnIMEEndCompositionOnPlugin(aWindow, aEvent->wParam, + aEvent->lParam); + } + break; + } +} + /****************************************************************************** * IMMHandler::Selection ******************************************************************************/ diff --git a/widget/windows/IMMHandler.h b/widget/windows/IMMHandler.h index b402c280e5..92d35090e9 100644 --- a/widget/windows/IMMHandler.h +++ b/widget/windows/IMMHandler.h @@ -15,6 +15,7 @@ #include "mozilla/EventForwards.h" #include "nsRect.h" #include "WritingModes.h" +#include "npapi.h" class nsWindow; @@ -118,7 +119,7 @@ public: MSGResult& aResult); static bool IsComposing() { - return IsComposingOnOurEditor() || IsComposingOnPlugin(); + return IsComposingOnOurEditor(); } static bool IsComposingOn(nsWindow* aWindow) { @@ -150,6 +151,9 @@ public: // IME. Otherwise, NS_OK. static nsresult OnMouseButtonEvent(nsWindow* aWindow, const IMENotification& aIMENotification); + static void SetCandidateWindow(nsWindow* aWindow, CANDIDATEFORM* aForm); + static void DefaultProcOfPluginEvent(nsWindow* aWindow, + const NPEvent* aEvent); protected: static void EnsureHandlerInstance(); @@ -180,7 +184,7 @@ protected: MSGResult& aResult); static bool ProcessMessageForPlugin(nsWindow* aWindow, UINT msg, WPARAM &wParam, LPARAM &lParam, - MSGResult& aResult); + bool &aRet, MSGResult& aResult); IMMHandler(); ~IMMHandler(); @@ -191,16 +195,15 @@ protected: MSGResult& aResult); bool OnIMEStartComposition(nsWindow* aWindow, MSGResult& aResult); - bool OnIMEStartCompositionOnPlugin(nsWindow* aWindow, - WPARAM wParam, LPARAM lParam, - MSGResult& aResult); + void OnIMEStartCompositionOnPlugin(nsWindow* aWindow, + WPARAM wParam, LPARAM lParam); bool OnIMEComposition(nsWindow* aWindow, WPARAM wParam, LPARAM lParam, MSGResult& aResult); - bool OnIMECompositionOnPlugin(nsWindow* aWindow, WPARAM wParam, LPARAM lParam, - MSGResult& aResult); + void OnIMECompositionOnPlugin(nsWindow* aWindow, WPARAM wParam, + LPARAM lParam); bool OnIMEEndComposition(nsWindow* aWindow, MSGResult& aResult); - bool OnIMEEndCompositionOnPlugin(nsWindow* aWindow, WPARAM wParam, - LPARAM lParam, MSGResult& aResult); + void OnIMEEndCompositionOnPlugin(nsWindow* aWindow, WPARAM wParam, + LPARAM lParam); bool OnIMERequest(nsWindow* aWindow, WPARAM wParam, LPARAM lParam, MSGResult& aResult); bool OnIMECharOnPlugin(nsWindow* aWindow, WPARAM wParam, LPARAM lParam, @@ -326,7 +329,8 @@ protected: * If aForceUpdate is true, it will update composition font even if writing * mode isn't being changed. */ - void AdjustCompositionFont(const IMEContext& aContext, + void AdjustCompositionFont(nsWindow* aWindow, + const IMEContext& aContext, const mozilla::WritingMode& aWritingMode, bool aForceUpdate = false); diff --git a/widget/windows/TaskbarPreview.cpp b/widget/windows/TaskbarPreview.cpp index 7c0e9fc5db..e344da49e7 100644 --- a/widget/windows/TaskbarPreview.cpp +++ b/widget/windows/TaskbarPreview.cpp @@ -357,7 +357,7 @@ TaskbarPreview::UpdateTooltip() { void TaskbarPreview::DrawBitmap(uint32_t width, uint32_t height, bool isPreview) { nsresult rv; - RefPtr surface = new gfxWindowsSurface(gfx::IntSize(width, height), gfxImageFormat::ARGB32); + RefPtr surface = new gfxWindowsSurface(gfx::IntSize(width, height), gfx::SurfaceFormat::A8R8G8B8_UINT32); nsCOMPtr shell = do_QueryReferent(mDocShell); diff --git a/widget/windows/WinIMEHandler.cpp b/widget/windows/WinIMEHandler.cpp index b8ec6b5e32..66cfdb10e0 100644 --- a/widget/windows/WinIMEHandler.cpp +++ b/widget/windows/WinIMEHandler.cpp @@ -28,7 +28,7 @@ const char* kOskPathPrefName = "ui.osk.on_screen_keyboard_path"; const char* kOskEnabled = "ui.osk.enabled"; const char* kOskDetectPhysicalKeyboard = "ui.osk.detect_physical_keyboard"; -const char* kOskRequireTabletMode = "ui.osk.require_tablet_mode"; +const char* kOskRequireWin10 = "ui.osk.require_win10"; const char* kOskDebugReason = "ui.osk.debug.keyboardDisplayReason"; namespace mozilla { @@ -45,7 +45,6 @@ InputContextAction::Cause IMEHandler::sLastContextActionCause = #ifdef NS_ENABLE_TSF bool IMEHandler::sIsInTSFMode = false; bool IMEHandler::sIsIMMEnabled = true; -bool IMEHandler::sShowingOnScreenKeyboard = false; decltype(SetInputScopes)* IMEHandler::sSetInputScopes = nullptr; #endif // #ifdef NS_ENABLE_TSF @@ -548,21 +547,22 @@ void IMEHandler::MaybeShowOnScreenKeyboard() { if (sPluginHasFocus || - !IsWin10OrLater() || + !IsWin8OrLater() || !Preferences::GetBool(kOskEnabled, true) || - sShowingOnScreenKeyboard || + GetOnScreenKeyboardWindow() || IMEHandler::IsKeyboardPresentOnSlate()) { return; } - // Tablet Mode is only supported on Windows 10 and higher. - // When touch-event detection within IME is better supported - // this check may be removed, and ShowOnScreenKeyboard can - // run on Windows 8 and higher (adjusting the IsWin10OrLater - // guard above and within MaybeDismissOnScreenKeyboard). - if (!IsInTabletMode() && - Preferences::GetBool(kOskRequireTabletMode, true) && - !AutoInvokeOnScreenKeyboardInDesktopMode()) { + // On Windows 10 we require tablet mode, unless the user has set the relevant + // Windows setting to enable the on-screen keyboard in desktop mode. + // We might be disabled specifically on Win8(.1), so we check that afterwards. + if (IsWin10OrLater()) { + if (!IsInTabletMode() && !AutoInvokeOnScreenKeyboardInDesktopMode()) { + return; + } + } + else if (Preferences::GetBool(kOskRequireWin10, true)) { return; } @@ -574,8 +574,7 @@ void IMEHandler::MaybeDismissOnScreenKeyboard() { if (sPluginHasFocus || - !IsWin10OrLater() || - !sShowingOnScreenKeyboard) { + !IsWin8OrLater()) { return; } @@ -836,7 +835,7 @@ IMEHandler::ShowOnScreenKeyboard() L"{054AAE20-4BEA-4347-8A35-64A533254A9D}\\LocalServer32"; if (!WinUtils::GetRegistryKey(HKEY_LOCAL_MACHINE, kRegKeyName, - 0, + nullptr, path, sizeof path)) { return; @@ -876,7 +875,8 @@ IMEHandler::ShowOnScreenKeyboard() if (FAILED(hres) || !path) { return; } - commonProgramFilesPath = nsDependentString(path).get(); + commonProgramFilesPath = + static_cast(nsDependentString(path).get()); ::CoTaskMemFree(path); } wstrpath.replace(commonProgramFilesOffset, @@ -888,15 +888,14 @@ IMEHandler::ShowOnScreenKeyboard() Preferences::SetString(kOskPathPrefName, cachedPath); } - LPCWSTR cachedPathPtr; + const char16_t *cachedPathPtr; cachedPath.GetData(&cachedPathPtr); - HINSTANCE ret = ::ShellExecuteW(nullptr, - L"", - cachedPathPtr, - nullptr, - nullptr, - SW_SHOW); - sShowingOnScreenKeyboard = true; + ShellExecuteW(nullptr, + L"", + char16ptr_t(cachedPathPtr), + nullptr, + nullptr, + SW_SHOW); } // Based on DismissVirtualKeyboard() in Chromium's base/win/win_util.cc. @@ -904,16 +903,46 @@ IMEHandler::ShowOnScreenKeyboard() void IMEHandler::DismissOnScreenKeyboard() { - sShowingOnScreenKeyboard = false; - - // Dismiss the virtual keyboard by generating the ESC keystroke - // programmatically. - const wchar_t kOSKClassName[] = L"IPTip_Main_Window"; - HWND osk = ::FindWindowW(kOSKClassName, nullptr); - if (::IsWindow(osk) && ::IsWindowEnabled(osk)) { + // Dismiss the virtual keyboard if it's open + HWND osk = GetOnScreenKeyboardWindow(); + if (osk) { ::PostMessage(osk, WM_SYSCOMMAND, SC_CLOSE, 0); } } +// static +HWND +IMEHandler::GetOnScreenKeyboardWindow() +{ + const wchar_t kOSKClassName[] = L"IPTip_Main_Window"; + HWND osk = ::FindWindowW(kOSKClassName, nullptr); + if (::IsWindow(osk) && ::IsWindowEnabled(osk)) { + return osk; + } + return nullptr; +} + +// static +void +IMEHandler::SetCandidateWindow(nsWindow* aWindow, CANDIDATEFORM* aForm) +{ + if (!sPluginHasFocus) { + return; + } + + IMMHandler::SetCandidateWindow(aWindow, aForm); +} + +// static +void +IMEHandler::DefaultProcOfPluginEvent(nsWindow* aWindow, + const NPEvent* aPluginEvent) +{ + if (!sPluginHasFocus) { + return; + } + IMMHandler::DefaultProcOfPluginEvent(aWindow, aPluginEvent); +} + } // namespace widget } // namespace mozilla diff --git a/widget/windows/WinIMEHandler.h b/widget/windows/WinIMEHandler.h index 3e5a45f2f3..44bc4474a0 100644 --- a/widget/windows/WinIMEHandler.h +++ b/widget/windows/WinIMEHandler.h @@ -8,6 +8,7 @@ #include "nscore.h" #include "nsIWidget.h" +#include "npapi.h" #include #include @@ -103,6 +104,17 @@ public: */ static void InitInputContext(nsWindow* aWindow, InputContext& aInputContext); + /* + * For windowless plugin helper. + */ + static void SetCandidateWindow(nsWindow* aWindow, CANDIDATEFORM* aForm); + + /* + * For WM_IME_*COMPOSITION messages and e10s with windowless plugin + */ + static void DefaultProcOfPluginEvent(nsWindow* aWindow, + const NPEvent* aPluginEvent); + #ifdef DEBUG /** * Returns true when current keyboard layout has IME. Otherwise, false. @@ -123,7 +135,6 @@ private: // If sIMMEnabled is false, any IME messages are not handled in TSF mode. // Additionally, IME context is always disassociated from focused window. static bool sIsIMMEnabled; - static bool sShowingOnScreenKeyboard; static bool IsTSFAvailable() { return (sIsInTSFMode && !sPluginHasFocus); } static bool IsIMMActive(); @@ -147,6 +158,12 @@ private: * Windows 8 and higher. */ static void DismissOnScreenKeyboard(); + + /** + * Get the HWND for the on-screen keyboard, if it's up. Only + * allowed for Windows 8 and higher. + */ + static HWND GetOnScreenKeyboardWindow(); #endif // #ifdef NS_ENABLE_TSF }; diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index a02d6f250b..808b9238db 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -497,7 +497,7 @@ nsWindow::Create(nsIWidget* aParent, // Ensure that the toolkit is created. nsToolkit::GetToolkit(); - BaseCreate(baseParent, aRect, aInitData); + BaseCreate(baseParent, aInitData); HWND parent; if (aParent) { // has a nsIWidget parent @@ -6745,7 +6745,7 @@ void nsWindow::ResizeTranslucentWindow(int32_t aNewWidth, int32_t aNewHeight, bo return; RefPtr newSurface = - new gfxWindowsSurface(IntSize(aNewWidth, aNewHeight), gfxImageFormat::ARGB32); + new gfxWindowsSurface(IntSize(aNewWidth, aNewHeight), SurfaceFormat::A8R8G8B8_UINT32); mTransparentSurface = newSurface; mMemoryDC = newSurface->GetDC(); } @@ -7565,6 +7565,39 @@ nsWindow::ComputeShouldAccelerate() return nsBaseWidget::ComputeShouldAccelerate(); } +void +nsWindow::SetCandidateWindowForPlugin(int32_t aX, int32_t aY) +{ + CANDIDATEFORM form; + form.dwIndex = 0; + form.dwStyle = CFS_CANDIDATEPOS; + form.ptCurrentPos.x = aX; + form.ptCurrentPos.y = aY; + + IMEHandler::SetCandidateWindow(this, &form); +} + +void +nsWindow::DefaultProcOfPluginEvent(const WidgetPluginEvent& aEvent) +{ + const NPEvent* pPluginEvent = + static_cast(aEvent.mPluginEvent); + + if (NS_WARN_IF(!pPluginEvent)) { + return; + } + + if (!mWnd) { + return; + } + + // For WM_IME_*COMPOSITION + IMEHandler::DefaultProcOfPluginEvent(this, pPluginEvent); + + CallWindowProcW(GetPrevWindowProc(), mWnd, pPluginEvent->event, + pPluginEvent->wParam, pPluginEvent->lParam); +} + /************************************************************** ************************************************************** ** diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index c8a34d7506..bc23b23d0e 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -292,6 +292,11 @@ public: const IMEContext& DefaultIMC() const { return mDefaultIMC; } + virtual void SetCandidateWindowForPlugin(int32_t aX, + int32_t aY) override; + virtual void DefaultProcOfPluginEvent( + const mozilla::WidgetPluginEvent& aEvent) override; + protected: virtual ~nsWindow(); diff --git a/widget/windows/nsWindowBase.h b/widget/windows/nsWindowBase.h index ec5f4fc8d6..dfea13d8f3 100644 --- a/widget/windows/nsWindowBase.h +++ b/widget/windows/nsWindowBase.h @@ -77,14 +77,6 @@ public: */ virtual bool DispatchPluginEvent(const MSG& aMsg); - /* - * Returns true if a plugin has focus on this widget. Otherwise, false. - */ - virtual bool PluginHasFocus() const final - { - return (mInputContext.mIMEState.mEnabled == IMEState::PLUGIN); - } - /* * Touch input injection apis */ diff --git a/widget/windows/nsWindowGfx.cpp b/widget/windows/nsWindowGfx.cpp index 56c4159aaa..325a707b88 100644 --- a/widget/windows/nsWindowGfx.cpp +++ b/widget/windows/nsWindowGfx.cpp @@ -354,7 +354,7 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t aNestingLevel) targetSurfaceImage = new gfxImageSurface(sSharedSurfaceData.get(), surfaceSize, surfaceSize.width * 4, - gfxImageFormat::RGB24); + SurfaceFormat::X8R8G8B8_UINT32); if (targetSurfaceImage && !targetSurfaceImage->CairoStatus()) { targetSurfaceImage->SetDeviceOffset(gfxPoint(-ps.rcPaint.left, -ps.rcPaint.top)); diff --git a/widget/xremoteclient/XRemoteClient.cpp b/widget/xremoteclient/XRemoteClient.cpp index 20d15a039d..c993a7a8bc 100644 --- a/widget/xremoteclient/XRemoteClient.cpp +++ b/widget/xremoteclient/XRemoteClient.cpp @@ -6,6 +6,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "mozilla/ArrayUtils.h" #include "XRemoteClient.h" #include "prmem.h" #include "prprf.h" @@ -48,8 +49,6 @@ #endif #endif -#define ARRAY_LENGTH(array_) (sizeof(array_)/sizeof(array_[0])) - using mozilla::LogLevel; static PRLogModuleInfo *sRemoteLm = nullptr; @@ -63,9 +62,12 @@ XRemoteClient::XRemoteClient() mInitialized = false; mMozVersionAtom = 0; mMozLockAtom = 0; + mMozCommandLineAtom = 0; mMozResponseAtom = 0; mMozWMStateAtom = 0; mMozUserAtom = 0; + mMozProfileAtom = 0; + mMozProgramAtom = 0; mLockData = 0; if (!sRemoteLm) sRemoteLm = PR_NewLogModule("XRemoteClient"); @@ -90,7 +92,7 @@ static const char *XAtomNames[] = { MOZILLA_PROGRAM_PROP, MOZILLA_COMMANDLINE_PROP }; -static Atom XAtoms[ARRAY_LENGTH(XAtomNames)]; +static Atom XAtoms[MOZ_ARRAY_LENGTH(XAtomNames)]; nsresult XRemoteClient::Init() @@ -107,7 +109,7 @@ XRemoteClient::Init() // get our atoms XInternAtoms(mDisplay, const_cast(XAtomNames), - ARRAY_LENGTH(XAtomNames), False, XAtoms); + MOZ_ARRAY_LENGTH(XAtomNames), False, XAtoms); int i = 0; mMozVersionAtom = XAtoms[i++]; diff --git a/xpcom/build/nsWindowsDllInterceptor.h b/xpcom/build/nsWindowsDllInterceptor.h index e4d0471a5d..09bcc2c2ca 100644 --- a/xpcom/build/nsWindowsDllInterceptor.h +++ b/xpcom/build/nsWindowsDllInterceptor.h @@ -66,9 +66,40 @@ namespace mozilla { namespace internal { +class AutoVirtualProtect +{ +public: + AutoVirtualProtect(void* aFunc, size_t aSize, DWORD aProtect) + : mFunc(aFunc), mSize(aSize), mNewProtect(aProtect), mOldProtect(0), + mSuccess(false) + {} + + ~AutoVirtualProtect() + { + if (mSuccess) { + VirtualProtectEx(GetCurrentProcess(), mFunc, mSize, mOldProtect, + &mOldProtect); + } + } + + bool Protect() + { + mSuccess = !!VirtualProtectEx(GetCurrentProcess(), mFunc, mSize, + mNewProtect, &mOldProtect); + return mSuccess; + } + +private: + void* const mFunc; + size_t const mSize; + DWORD const mNewProtect; + DWORD mOldProtect; + bool mSuccess; +}; + class WindowsDllNopSpacePatcher { - typedef unsigned char* byteptr_t; + typedef uint8_t* byteptr_t; HMODULE mModule; // Dumb array for remembering the addresses of functions we've patched. @@ -91,8 +122,8 @@ public: byteptr_t fn = mPatchedFns[i]; // Ensure we can write to the code. - DWORD op; - if (!VirtualProtectEx(GetCurrentProcess(), fn, 2, PAGE_EXECUTE_READWRITE, &op)) { + AutoVirtualProtect protect(fn, 2, PAGE_EXECUTE_READWRITE); + if (!protect.Protect()) { // printf("VirtualProtectEx failed! %d\n", GetLastError()); continue; } @@ -100,9 +131,6 @@ public: // mov edi, edi *((uint16_t*)fn) = 0xff8b; - // Restore the old protection. - VirtualProtectEx(GetCurrentProcess(), fn, 2, op, &op); - // I don't think this is actually necessary, but it can't hurt. FlushInstructionCache(GetCurrentProcess(), /* ignored */ nullptr, @@ -141,19 +169,16 @@ public: // Ensure we can read and write starting at fn - 5 (for the long jmp we're // going to write) and ending at fn + 2 (for the short jmp up to the long - // jmp). - DWORD op; - if (!VirtualProtectEx(GetCurrentProcess(), fn - 5, 7, - PAGE_EXECUTE_READWRITE, &op)) { + // jmp). These bytes may span two pages with different protection. + AutoVirtualProtect protectBefore(fn - 5, 5, PAGE_EXECUTE_READWRITE); + AutoVirtualProtect protectAfter(fn, 2, PAGE_EXECUTE_READWRITE); + if (!protectBefore.Protect() || !protectAfter.Protect()) { //printf ("VirtualProtectEx failed! %d\n", GetLastError()); return false; } bool rv = WriteHook(fn, aHookDest, aOrigFunc); - // Re-protect, and we're done. - VirtualProtectEx(GetCurrentProcess(), fn - 5, 7, op, &op); - if (rv) { mPatchedFns[mPatchedFnsLen] = fn; mPatchedFnsLen++; @@ -249,11 +274,11 @@ public: #endif byteptr_t origBytes = (byteptr_t)DecodePointer(*((byteptr_t*)p)); // ensure we can modify the original code - DWORD op; - if (!VirtualProtectEx(GetCurrentProcess(), origBytes, nBytes, - PAGE_EXECUTE_READWRITE, &op)) { + AutoVirtualProtect protect(origBytes, nBytes, PAGE_EXECUTE_READWRITE); + if (!protect.Protect()) { continue; } + // Remove the hook by making the original function jump directly // in the trampoline. intptr_t dest = (intptr_t)(p + sizeof(void*)); @@ -271,8 +296,6 @@ public: #else #error "Unknown processor type" #endif - // restore protection; if this fails we can't really do anything about it - VirtualProtectEx(GetCurrentProcess(), origBytes, nBytes, op, &op); } } @@ -352,6 +375,66 @@ protected: int mMaxHooks; int mCurHooks; +#if defined(_M_X64) + // To patch for JMP and JE + + enum JumpType { + Je, + Jmp + }; + + struct JumpPatch { + JumpPatch() + : mHookOffset(0), mJumpAddress(0), mType(JumpType::Jmp) + { + } + + JumpPatch(size_t aOffset, intptr_t aAddress, JumpType aType = JumpType::Jmp) + : mHookOffset(aOffset), mJumpAddress(aAddress), mType(aType) + { + } + + void AddJumpPatch(size_t aHookOffset, intptr_t aAbsJumpAddress, + JumpType aType = JumpType::Jmp) + { + mHookOffset = aHookOffset; + mJumpAddress = aAbsJumpAddress; + mType = aType; + } + + size_t GenerateJump(uint8_t* aCode) + { + size_t offset = mHookOffset; + if (mType == JumpType::Je) { + // JNE RIP+14 + aCode[offset] = 0x75; + aCode[offset + 1] = 14; + offset += 2; + } + + // JMP [RIP+0] + aCode[offset] = 0xff; + aCode[offset + 1] = 0x25; + *reinterpret_cast(aCode + offset + 2) = 0; + + // Jump table + *reinterpret_cast(aCode + offset + 2 + 4) = mJumpAddress; + + return offset + 2 + 4 + 8; + } + + bool HasJumpPatch() const + { + return !!mJumpAddress; + } + + size_t mHookOffset; + intptr_t mJumpAddress; + JumpType mType; + }; + +#endif + void CreateTrampoline(void* aOrigFunction, intptr_t aDest, void** aOutTramp) { *aOutTramp = nullptr; @@ -364,9 +447,9 @@ protected: byteptr_t origBytes = (byteptr_t)aOrigFunction; int nBytes = 0; - int pJmp32 = -1; #if defined(_M_IX86) + int pJmp32 = -1; while (nBytes < 5) { // Understand some simple instructions that might be found in a // prologue; we might need to extend this as necessary. @@ -428,17 +511,17 @@ protected: } } #elif defined(_M_X64) - byteptr_t directJmpAddr; + JumpPatch jump; while (nBytes < 13) { - // if found JMP 32bit offset, next bytes must be NOP - if (pJmp32 >= 0) { - if (origBytes[nBytes++] != 0x90) { - return; + // if found JMP 32bit offset, next bytes must be NOP or INT3 + if (jump.HasJumpPatch()) { + if (origBytes[nBytes] == 0x90 || origBytes[nBytes] == 0xcc) { + nBytes++; + continue; } - - continue; + return; } if (origBytes[nBytes] == 0x0f) { nBytes++; @@ -454,6 +537,15 @@ protected: } else if (origBytes[nBytes] == 0x05) { // syscall nBytes++; + } else if (origBytes[nBytes] == 0x84) { + // je rel32 + jump.AddJumpPatch(nBytes - 1, + (intptr_t) + origBytes + nBytes + 5 + + *(reinterpret_cast(origBytes + + nBytes + 1)), + JumpType::Je); + nBytes += 5; } else { return; } @@ -497,6 +589,13 @@ protected: (origBytes[nBytes + 1] & 0xf8) == 0x60) { // and [r+d], imm8 nBytes += 5; + } else if (origBytes[nBytes] == 0x85) { + // 85 /r => TEST r/m32, r32 + if ((origBytes[nBytes + 1] & 0xc0) == 0xc0) { + nBytes += 2; + } else { + return; + } } else if ((origBytes[nBytes] & 0xfd) == 0x89) { // MOV r/m64, r64 | MOV r64, r/m64 if ((origBytes[nBytes + 1] & 0xc0) == 0x40) { @@ -527,15 +626,16 @@ protected: return; } } else if (origBytes[nBytes] == 0xff) { - pJmp32 = nBytes - 1; // JMP /4 if ((origBytes[nBytes + 1] & 0xc0) == 0x0 && (origBytes[nBytes + 1] & 0x07) == 0x5) { // [rip+disp32] // convert JMP 32bit offset to JMP 64bit direct - directJmpAddr = - (byteptr_t)*((uint64_t*)(origBytes + nBytes + 6 + - (*((int32_t*)(origBytes + nBytes + 2))))); + jump.AddJumpPatch(nBytes - 1, + *reinterpret_cast( + origBytes + nBytes + 6 + + *reinterpret_cast(origBytes + nBytes + + 2))); nBytes += 6; } else { // not support yet! @@ -557,11 +657,16 @@ protected: } else if (origBytes[nBytes] == 0xc3) { // ret nBytes++; + } else if (origBytes[nBytes] == 0xcc) { + // int 3 + nBytes++; } else if (origBytes[nBytes] == 0xe9) { - pJmp32 = nBytes; - // convert JMP 32bit offset to JMP 64bit direct - directJmpAddr = origBytes + pJmp32 + 5 + (*((int32_t*)(origBytes + pJmp32 + 1))); // jmp 32bit offset + jump.AddJumpPatch(nBytes, + // convert JMP 32bit offset to JMP 64bit direct + (intptr_t) + origBytes + nBytes + 5 + + *(reinterpret_cast(origBytes + nBytes + 1))); nBytes += 5; } else if (origBytes[nBytes] == 0xff) { nBytes++; @@ -606,27 +711,16 @@ protected: (intptr_t)trampDest - (intptr_t)(tramp + nBytes + 5); // target displacement } #elif defined(_M_X64) - // If JMP32 opcode found, we don't insert to trampoline jump - if (pJmp32 >= 0) { - // mov r11, address - tramp[pJmp32] = 0x49; - tramp[pJmp32 + 1] = 0xbb; - *((intptr_t*)(tramp + pJmp32 + 2)) = (intptr_t)directJmpAddr; - - // jmp r11 - tramp[pJmp32 + 10] = 0x41; - tramp[pJmp32 + 11] = 0xff; - tramp[pJmp32 + 12] = 0xe3; + // If JMP/JE opcode found, we don't insert to trampoline jump + if (jump.HasJumpPatch()) { + size_t offset = jump.GenerateJump(tramp); + if (jump.mType != JumpType::Jmp) { + JumpPatch patch(offset, reinterpret_cast(trampDest)); + patch.GenerateJump(tramp); + } } else { - // mov r11, address - tramp[nBytes] = 0x49; - tramp[nBytes + 1] = 0xbb; - *((intptr_t*)(tramp + nBytes + 2)) = (intptr_t)trampDest; - - // jmp r11 - tramp[nBytes + 10] = 0x41; - tramp[nBytes + 11] = 0xff; - tramp[nBytes + 12] = 0xe3; + JumpPatch patch(nBytes, reinterpret_cast(trampDest)); + patch.GenerateJump(tramp); } #endif @@ -634,9 +728,8 @@ protected: *aOutTramp = tramp; // ensure we can modify the original code - DWORD op; - if (!VirtualProtectEx(GetCurrentProcess(), aOrigFunction, nBytes, - PAGE_EXECUTE_READWRITE, &op)) { + AutoVirtualProtect protect(aOrigFunction, nBytes, PAGE_EXECUTE_READWRITE); + if (!protect.Protect()) { //printf ("VirtualProtectEx failed! %d\n", GetLastError()); return; } @@ -658,9 +751,6 @@ protected: origBytes[11] = 0xff; origBytes[12] = 0xe3; #endif - - // restore protection; if this fails we can't really do anything about it - VirtualProtectEx(GetCurrentProcess(), aOrigFunction, nBytes, op, &op); } byteptr_t FindTrampolineSpace() diff --git a/xpcom/system/nsIXULRuntime.idl b/xpcom/system/nsIXULRuntime.idl index 00c8df3fb1..5c9a9a335a 100644 --- a/xpcom/system/nsIXULRuntime.idl +++ b/xpcom/system/nsIXULRuntime.idl @@ -23,7 +23,7 @@ bool BrowserTabsRemoteAutostart(); * stable/frozen, please contact Benjamin Smedberg. */ -[scriptable, uuid(c4cd11c4-6e8e-49da-85a8-dad3b7605bc3)] +[scriptable, uuid(a1b2e167-b748-42bf-ba85-996ec39062b9)] interface nsIXULRuntime : nsISupports { /** @@ -96,12 +96,6 @@ interface nsIXULRuntime : nsISupports */ readonly attribute boolean accessibilityEnabled; - /** - * Indicates if the active accessibility client is UIA. - * DO NOT USE! This is temporary and will be removed. - */ - readonly attribute boolean accessibilityIsUIA; - /** * Indicates whether the current Firefox build is 64-bit. */