import changes from `dev' branch of rmottola/Arctic-Fox:

- remove poisondata stuff (cf5b5d29e5)
- Bug 1218488 - clarify buffer ownership for nsICanvasRenderingContextInternal::GetBuffer; r=Bas,baku (dba4272b73)
- Bug 1167215 - Re-apply CompositeUntil calls when we get a new batch of textures. r=roc (d57a8ac9e9)
- Bug 1220923 - Make nsIntRegion a typedef for IntRegionTyped<UnknownUnits>. r=nical (a5f4e1e283)
- Bug 1220898 - Make nsIntMargin a typedef for mozilla::gfx::IntMargin. r=nical (8bdb2f191a)
- Bug 1205913 - Differentiate YCbCr, NV12 and RGB textures when drawing layer borders. r=nical (ff5d3dc7df)
- Bug 1203376 - Honor filter region settings for lighting filters. r=mstange (8d0565e99a)
- Bug 1220512 - ensure next frame status is updated before notifying MediaDecoder::PlaybackEnded. See bug 1220512 comment 1 for the detail. r=cpearce. (c2f434b5d4)
- Bug 1207964 - Remove workaround from bug 1080461. r=jwwang (19bff98c14)
- Bug 1199904: Only start decoding ahead after explicitly requesting data. r=gerald (8712637b49)
- Bug 1197664: Report the total number of decoded frames. CLOSED TREE r=kentuckyfriedtakahe (422827d1af)
- Bug 1178596: Reset frame size queue after flushing. r=cpearce (dd40ac4e6b)
- Bug 1205911: P1. Cancel pending demux request when searching for next keyframe. r=edwin (8a03e6904f)
- Bug 1188313: P1. Attempt to seek audio near video. r=cpearce (a8b6465d97)
- Bug 1205911: P2. Ensure demuxer is reset before performing a seek. r=edwin (e93534a1d1)
- bit of  Bug 1185886: P2 (c2e89be4a3)
- bit of Bug 1211443 (98fbb4a4a2)
- Bug 1089586: Abort pending seeks. r=jwwang (e81f453204)
- Bug 1195094: P1. Properly detects SPS changes for decoders requiring Annex B. r=cpearce (976febcd7c)
- Bug 1195094: P2. Ensure TrackInfo object passed to constructor is never modified. r=cpearce (d5c15b2368)
- Bug 1218577: Use only Blank PDM if enabled. r=kamidphish (a7e06549cc)
- Bug 1210231 - Enable unencrypted <video> playback using Adobe's GMP for decoding. r=jya (7f80702b89)
- Bug 1214932 - Add media.wmf.enabled pref. r=jya (8c183c0dd1)
- Bug 1213173: Always use FFmpeg regardless of version. r=kentuckyfriedtakahe (e5af2c0c91)
- Bug 1211787 - Improve the accuracy of MediaDecoderStateMachine::GetDecodedAudioDuration(). r=roc. (16d755c555)
- Bug 1193614 - Schedule State Machine when VideoQueue() is low. r=cpearce (fe608da5fd)
- Bug 1219984. Part 1 - remove EventPassMode::Both. In order to support multiple arguments, all arguments must be either moved or copied. r=kinetik. (2ee049008c)
- Bug 1219984. Part 2 - add support for multiple arguments. r=kinetik. (1c70d5d69b)
- Bug 1219974 - Add DisconnectIfExists() to MediaEventListener. r=kinetik. (43f6ae90b0)
- Bug 1192109 - Fix insufficient includes in MediaEventSource.h. r=kinetik. (09eca240a1)
- mData, aData (5e87f70853)
- Bug 1219330 - Handle PlanaYCbCrImage::SetData failure. r=jya, jesup (144f3c266f)
- Bug 1222308. Assume frames that are very old will never be composited. r=nical (1da9be2527)
- space (45b67caa85)
- Bug 1182426 - Set PlanarYCbCrImage's size in VP8TrackEncoder GTest. r=roc (d70a4d20c4)
- Bug 1217080. Move recycling functionality into RecyclingPlanarYCbCrImage. r=nical (e2b2f650d7)
- Bug 1216644 - part 1 - simple s/nsAutoArrayPtr/UniquePtr/ changes in gfx/; r=jrmuizel (d19bc51f94)
- Bug 1216644 - part 2 - make gfxFontEntry::mUVSData a UniquePtr; r=jrmuizel (605a1bc6b1)
- Bug 1216644 - part 3 - make BufferRecycleBin store UniquePtrs; r=jrmuizel (7781281266)
- Add an RAII class to lock and unlock textures. (bug 1222863 part 1, r=nical) (abdec485f3)
- Use RAII for more TextureClient locking cases. (bug 1222863 part 2, r=nical) (b35486ed3d)
- Bug 1212288 - Make ImageContainer::AllocateProducerID callable on all threads; r=roc (fc569b8e48)
- Bug 1140947 - Correct some logging in SourceBufferResource.cpp. r=cajbir (fcbb38056c)
- Bug 1199573: [MSE] Properly handle partial media header received prior a discontinuity. r=gerald (f1cda54fa3)
- Bug 1213726 - Remove AbstractMediaDecoder::HasInitializationData(). r=kinetik. (62f09f816e)
- Bug 1034081 - Never seek before startTime. r=rillian Only adjust seek target up to startTime (44139b20ec)
- Bug 1196353 - Use standard Xiph extradata format to pass headers from demuxers to decoders. r=jya (41f8dee5af)
- Bug 1202332 - XiphExtradataToHeaders miscalculates final header length. r=derf (eec20f90f0)
- Bug 1208799: [webm] Use first track found. r=kinetik (7196355e31)
- Bug 1190472 - part 1 - improve MediaRawDataQueue's reference-counting behavior; r=kinetik (47b066b8e8)
- Bug 1190472 - part 2 - delete unused MediaRawDataQueue::Push method; r=kinetik (f8246efe1b)
- Bug 1190472 - part 3 - optimize pushing an entire queue onto MediaRawDataQueue; r=kinetik (045b389bf8)
- Bug 1213024 - Comment the structured clone reading and writing, r=fitzgen (1b64f9f502)
- Bug 1201620 - Make SavedFrame stacks structured cloneable; r=sfink (87e9b0a04b)
- Bug 1221456 - Avoid C4819 warning spam. r=glandium (3dde3cb10a)
- Bug 1213752 - IonMonkey: MIPS: Enable MIPS64 support. r=glandium (36da4cbd99)
- Bug 1214175 - Make hash table manipulation infallible in Shape::fixupGetterSetterForBarrier() r=terrence (98e5e601ec)
- Bug 1215337 - Cache slotSpan(), r=terrence (3e992f9f06)
- No Bug - Include jswin.h in jsobj.cpp to unbreak windows non-unified bustage. (r=terrence over IRC) (92cba3254f)
- Bug 1052139 - Make prototype-setting first create Object.prototype so that subsequent prototype chain-splicing will work correctly. r=bz (34a8d00d9f)
- Bug 1172076 - Improve js::DumpBacktrace to include raw frame pointers and types. r=jandem (f11eb1763b)
- Bug 1052139 - Change the boolean constant controlling whether the global object prototype chain is immutable, to enable immutable-prototype enforcement generally. r=duh (b7a1124feb)
- Bug 1215363 - Fix a couple of OOM handling issues and make JS_sprintf funcions crash when passed illegal format strings r=terrence (c778891dd3)
- Bug 1211331 - Ensure that GC slices are terminated such that we can safely iterate the heap. r=terrence (440308a333)
- Bug 1224048 - Use stable hashing for the temporary tables in the JSON parser; r=jonco (7d058f44c9)
- Bug 1215678 - Nuke cross compartment wrappers if we fail to add them to the wrapper map r=terrence (8e9e535a11)
- Bug 1200732 - Use stable hashing for AutoCycleDetectorSet; r=jonco (68237bdea4)
- more poisondata removal (6479b20220)
- Bug 1218488 - clarify buffer ownership for nsICanvasRenderingContextInternal::GetBuffer; r=Bas,baku (ae89d929b2)
- Bug 1207378 (Part 1) - Add support for a frame rect to Downscaler. r=tn (234866c32f)
- Bug 1207378 (Part 2) - Use Downscaler to remove first-frame padding when downscaling GIFs. r=tn (5e995bdca2)
- Bug 1207378 - Add FrameRect to non-skia version of BeginFrame. r=seth (939f0510eb)
- Bug 1204394 (part 1) - Using StreamingLexer in the BMP decoder. r=seth. (77eaa1e125)
- Bug 1204394 (part 2) - Add bmpsuite to the BMP reftests. r=seth. (237a902461)
- Bug 1214476 - Remove unused code for encoding BMPv2 files. r=seth. (b8382357d7)
- Bug 1213613 (part 1) - Formatting cleanups for nsBMPEncoder.h. r=seth. (4ee65bc173)
- Bug 1213613 (part 2) - Move some BMP-related structs. r=seth. (15289784ce)
- Bug 1215156 - move SetPixel* functions into nsBMPDecoder.cpp; r=seth (a143c843d4)
- Bug 1215763 - part 1 - remove unnecessary nsAutoPtr.h includes; r=seth (f8a3a1f6b0)
- Bug 1180715 (1/4) - Track image LoadTime to compare with file mtime. review=seth (bdbd25752c)
- Bug 1180715 (2/4) - Provide a nsIFileURL interface for thumbnails. review=ttaubert (24c506569d)
- Bug 1147562 - Update remaining callsites of newChannel before landing the shim in toolkit/ (r=gijs) (f7f2ab798f)
- Bug 1163866 - Set originalURI correctly for moz-page-thumb:// channels. r=adw (3c7c97928e)
- Bug 1180715 (3/4) - Drop parseURI from newChannel2. review=ttaubert (5b409e7d4b)
- Bug 1180715 (4/4) - Use nsIURL methods instead of RegExp. review=ttaubert (1f7a026e06)
- Bug 1209705 - Propagate the DrawResult for temporary surfaces to the caller in ClippedImage. r=tn (c5be1c7df4)
- Bug 1215763 - part 2 - s/nsAutoPtr/UniquePtr/ in image/; r=seth (58c5da3bd2)
- Bug 1215763 - part 3 - s/nsAutoArrayPtr/UniquePtr/ in nsBMPEncoder; r=seth (62bc939286)
- Bug 1213613 (part 3) - Fix color-scaling of 16bpp BMP images. r=seth. (d06d511564)
- Bug 1214072 (part 1) - Read BMP bitfields during metadata decoding. r=seth. (56cc2c02cd)
- Bug 1214072 (part 2) - Implement transparency properly for BMP images. r=seth. (b6b07c2d90)
- Bug 1218823 - use UniquePtr<> in preference to delete[] in image/; r=seth (5cd21f89a2)
- Bug 1215334 (part 1) - Avoid creating a fake header for BMP files in ICO files. r=seth. (67506fc53e)
- Bug 1215334 (part 2) - Avoid creating a fake header for BMP files in ICO files. r=seth. (cf6c3f4553)
- spacing (b91c58ec87)
- Bug 1196494 - part 1: remove unnecessary GetClientBounds call in CompositorParent. r=jrmuziel (685f49ae9c)
- Bug 1180008 - Define gtk_window_get_window_type in mozgtk. r=karlt (e7ca7db4d3)
- Bug 863512 - Fixing xul dnd panels for linux. r=enndeakin (5d0faaf0dc)
- Bug 1195002 - draw to MozContainer window to allow GTK to draw decorations, r=karlt (7a84272fe9)
- Bug 1210249 - don't mess with toplevel widget when client side decorations are enabled. r=karlt (464e9ce3fb)
- bug 1180008 use mGdkWindow instead of finding it from gtk_widget_get_window(mShell) r=acomminos (024f8bd5a7)
- bug 1180008 don't measure size of decorations for override-redirect windows r=acomminos (416ffda363)
- Bug 1026803 part 1 - Factor out a common utility class for converting wrapping native times to TimeStamps; r=karlt (915ecdfc40)
- Bug 1026803 part 2 - Add an assertion that SystemTimeConverter's template parameter is unsigned; r=karlt (68ccf1569d)
- Bug 1026803 part 3 - Make some simplifications to SystemTimeConverter; r=karlt (c38719b7de)
- Bug 1026803 part 4 - Convert GTK native event times to timestamps; r=karlt (74ef903992)
- Bug 1026803 part 5 - Convert CurrentXXXTimeGetter classes from functors to helper classes; r=karlt (06d49e5965)
- Bug 1026803 part 6 - Make SystemTimeConverter detect clock skew; r=karlt (d663ab72b2)
- Bug 1026803 part 7 - Store the CurrentX11TimeGetter as a member object on nsWindow; r=karlt (f6a04e6e9c)
- Bug 1026803 part 8 - Add ability for CurrentX11TimeGetter to perform an asynchronous request of the current time; r=karlt (961dab1d91)
- Bug 1026803 part 8b - Factor out an IsTimeNewerThanTimeStamp method; r=karlt (1afb9f511a)
- Bug 1026803 part 9 - Return DOMHighResTimeStamp objects from Event.timeStamp on Linux for Nightly/Aurora builds; r=karlt (975432dbd8)
- Fix bustage from changeset 5c5dc6f367ac (bug 1026803) r=bustage on CLOSED TREE (c0be358f84)
- fix bustage (e5e97018b6)
- Bug 1196494 - part 2: only update nsWindow client offset when _NET_FRAME_EXTENTS property actually changes. r=eihrul (dd7e913d49)
- Bug 1170342 - Disable XInput2 by default on GTK3. r=karlt (6a52d65a98)
- Bug 1208904 - Fix a condition in nsWindow::SetNonClientMargins; r=roc (fe8c7b3e77)
- Bug 1199892 - "Mouse cursor flickers in Flash object with wmode opaque/transparent". r=roc (6d50037e14)
- Bug 1171101 - Remove pointer events and gesture scrolling dependencies. r=smaug (3aa5c89ea4)
- Bug 978679. Implement touch events for GTK3. r=karlt (adafe58640)
- Bug 1209774 - Transform from GDK coords to layout device pixels before calling DispatchEvent. r=karlt (4c81cf74ea)
- Bug 1191293. Remove harmless assertion that is triggered by GTK3. r=masayuki (e0b9eb2c80)
- Bug 978679. Convert GDK touch event coordinates properly. r=karlt (dfeae08f47)
- restore some XP vs Vista differences, Bug 925599 bits (88ff57f06f)
- Bug 1220392 - use UniquePtr<T[]> instead of nsAutoArrayPtr<T> in widget/; r=roc (35026aa4c9)
- Bug 1214616 - Remove encoding conversion methods from nsPrimitiveHelpers. r=emk. (3a4bdbbc8e)
- Bug 1216611 - add mozilla::MakeUniqueFallible and convert uses throughout the tree; r=Waldo (8672c2e3d9)
- Bug 1216964 - remove nsAutoArrayPtr use from ActorsParent; r=khuey (ddff59241a)
- Bug 1219903 - use UniquePtr<T[]> instead of delete[] calls in layout/generic/; r=dholbert (8b96067a6e)
- Bug 1220190 - use UniquePtr<T[]> instead of delete[] calls in layout/xul/; r=dholbert (065b3c521c)
- Bug 1220714 - use UniquePtr<T[]> instead of nsAutoArrayPtr<T> in layout/; r=dholbert (6a8245751c)
- Bug 1221550 - use UniquePtr<T[]> instead of nsAutoArrayPtr<T> in intl/; r=smontagu (67868889e2)
- Bug 1232374 - remove nsAutoArrayPtr usages from toolkit/; r=froydnj (d65586df26)
- Bug 1170522 - expose whether or not we're in tablet mode to xul/js/css, r=jimm,ted (5cb134a8d4)
- bug 1163872 - Fix a unified build issue in nsXPLookAndFeel.cpp. r=jimm (925e38abed)
- bug 1217602 - remove nsIPKIParamBlock r=Cykesiopka (b5f0fc8dfd)
- missing bit of old bug (fdcb4fe143)
- Bug 1221453 - Use ObjDirPaths for GENERATED_INCLUDES and merge with LOCAL_INCLUDES. r=gps (a0537fff83)
- Bug 1194948 - Build gfx/ipc in unified mode and mark as FAIL_ON_WARNINGS. r=BenWa (c88b356ac8)
- Bug 815952 - Stop clearing clipboard data originating from a private window after closing private windows. r=ehsan (b94fea061d)
- Bug 943296 - widget/gtk/nsDragService.cpp should assume Gtk uses UTF-8. r=karlt. (3613e87354)
- Bug 1186661 - Draw drag and drop alpha pixmap correctly on GTK3. r=karlt (ca884af03b)
- Bug 983843 - Switch to GtkOffscreenWindow for drag source widget, fixing ghost tabs on some GTK versions. r=karlt (ab56f9d764)
- bug 1216916 clean up when InvokeDragSession() fails r=roc (30c811c33e)
- Bug 1198128 - Fix -Wshadow warnings in widget/gtk. r=karlt (06bc60349e)
- Merge branch 'dev' of https://github.com/rmottola/Arctic-Fox into dev (c79378b7c9)
- Bug 1206915 - Move dumping of compositor textures under its own environment variable. r=mattwoodrow (b8ba4f0fbf)
- Bug 1213007 - Part 1. Implementing gfxCrash. r=dvander (e307f9d543)
- Bug 1208661 - Show display list and layer textures in-line in the HTML paint dump. r=BenWa (7047c68964)
- Relax the driver crash guard on nightly and e10s builds. (bug 1200825, r=jgilbert) (1dd81b1257)
- Bug 1214802 - gfxEnv - consolidate environment variables used by the graphics code in one place. r=botond (afb61356c6)
- Bug 1217192 - Use gfxCriticalNote where we're already using the non-default construction parameter. r=mchang (d04ca17de5)
- addback some crash stuff (8a78973a71)
- Fix layers.acceleration.force-enabled not working. (bug 1212659, r=jrmuizel) (5eb85d8f64)
- Bug 1142516 - Improve assertions and logging on the compositor side. r=Bas (cca63735e5)
- Bug 1194335. Use a StackArray for RECTS so we see them in the minidumps. r=mattwoodrow (1a83a134e8)
- Bug 1192058 - For DXGI_PRESENT_PARAMETERS, set pDirtyRects to nullptr if DirtyRectsCount == 0. r=BenWa (f78ff0df24)
- Bug 1204922 - More information about crashes. r=bas (53cbd02c12)
- Bug 1222033 - Rename gfxCrash to gfxDevCrash. r=jrmuizel (32351d0bc7)
- Bug 1209812 (part 1) - Remove casts between cairo_format_t and gfxImageFormat. r=nical. (c1bc5cd74c)
- Bug 1209812 (part 2) - Remove gfxImageFormat::A1. r=nical. (99f665ad80)
- Bug 1182426 - Sort includes in VP8TrackEncoder.cpp alphabetically. r=roc (5f10334ba8)
- Bug 1182426 - Don't try to encode new frames of a size other than the initial in VP8TrackEncoder. r=roc (8fb0b8f0d9)
- Bug 1182426 - Flatten YUV formats conversion code in VP8TrackEncoder. r=roc (0853d098f7)
- Bug 1182426 - Convert non-PlanarYCbCRImages in VP8TrackEncoder. r=roc (d2d78fa94a)
- Bug 1204106 - Use correct alpha blend modes for OVER in CompositorOGL. r=jrmuizel (5cc211b9d6)
- Bug 1207326 - Part 1: Correct projection clipping rectangle,r=matt.woodrow (8329afb6a7)
- Bug 1207326 - Part 2: Add reftest,r=jmuizelaar (d17d6c5d4f)
- Bug 1209446 - Make sure mFrameInProgress flag is set to true only when we actually begin drawing new frame. r=nical (4ff48c4149)
- Disable screen and multiply mix-blend-mode support in the D3D11 and OGL compositors. (bug 1135271, r=mattwoodrow) (9b4c11a289)
- Bug 1210189 - Use nsScreenGonk in nsWindow::StartRemoteDrawing() r=mwu (2653a33972)
- Bug 1210514 - Fix color inversion when BasicCompositor is used on gonk r=nical (141fee3bfb)
- Bug 1209812 (part 3) - Rename SurfaceFormat::R5G6B5 as R5G6B5_UINT16. r=Bas. (915e7eaba3)
- Bug 1209812 (part 4) - Add comments to SurfaceFormat. r=jrmuizel,Bas. (ef1977582f)
- Bug 1209812 (part 5) - Add endian-neutral variants to SurfaceFormat. r=nical,Bas. (93c49df8c5)
- Bug 1171671 - Simplify Boot Animation control r=mwu (94c4f89b45)
- Bug 1210182 - Implement GrallocTextureHostBasic r=nical (4e5ea5b92c)
- Bug 1209812 (follow-up) - Android bustage fix on a CLOSED TREE. r=me. (8b2fa6268d)
- Bug 1178513 - Added RGBA8888 to RGB565 converter. r=mattwoodrow (8ba5dbd3c9)
- Bug 1160689 - thumbnail image corruption on certain videos. r=sotaro (278a2e29f6)
- Bug 1204922: When ResizeBuffers fails, make no attempt to do subsequent paints until it succeeds again. r=milan (0c040d8228)
- Bug 1215027 - Fix EndFrameForExternalComposition() r=nical (bab4690e54)
- Bug 1215364 - Implement BasicCOmpositor::EndFrameForExternalComposition r=nical (c8b9c7bfb9)
- Bug 1213968 - Renew the surface on iOS when resuming the compositor r=kats (73489dc21c)
- Bug 1201318 - Factor out AddFamily. r=jdaggett (3f2556b8b4)
- Bug 1201318 - revise OSX system font handling. r=mstange (f8a8f5f562)
- Bug 1163877 - Part 1: Add storage for other FontFaceSets a FontFace is in. r=jdaggett (ab3a16b597)
- Bug 1163877 - Part 2: Allow FontFaces to be added to multiple FontFaceSets. r=jdaggett (9b2dd7e5c9)
- Bug 1163877 - Part 3: Update state on, and reflow documents for, all FontFaceSets that contain a FontFace whose user font entry updated. r=jdaggett (215db30569)
- Bug 1192986 Fix test_interfaces.html to expect Cache API and font loading to be released. r=ehsan (8db9ef1df8)
- Bug 1193019 - Rename CSSFontFaceLoadEvent to FontFaceSetLoadEvent. r=khuey (53f373c53d)
- Bug 1163877 - Part 4: Tests. r=jdaggett (c6053ca8b4)
- Bug 1180415 - initialize downloadable font pattern from FTFace. r=karlt (04aa59ba79)
- Bug 1163491 - map local fontnames to fontconfig patterns. r=karlt (ad10ebde2a)
- Bug 543715 p1 - distinguish between italic and oblique. r=jfkthame (4c9a0abf64)
- Bug 543715 p2 - italic/oblique reftests. r=jfkthame (90fb927148)
- bug 1178733 - enable APZ for iOS. r=kats (e41702d9cd)
- Bug 1169956. Backout bug 1073209 for tiled image regressions on OS X. r=jrmuizel (a80a29aaa3)
- Bug 1073209 - Eliminate usage of CreateSamplingRestrictedDrawable on d2d backends. r=jrmuizel (9ac8781a52)
- Bug 1204136 - Align DisplayPort on non-tiling platform. r=botond (1d8be17663)
- Bug 1122918 - Put the logical values for 'float' and 'clear' behind a pref, and enable them only on nightly builds and for B2G. r=heycam (a428b34d66)
- Bug 1183484 - Cycle collect FontFaceSetIterator. r=bzbarsky (dc49f3f098)
- Bug 1027579 - Do not load fonts from the cache if LOAD_BYPASS_CACHE is set. r=jfkthame r=bz (6cf20c9119)
- Bug 1201318 - Use nsAutoReleasePool from nsCocoaUtils.h. r=jdaggett (bfe5f05086)
- Bug 1201403 - streamline MacOSFontEntry::HasFontTable implementation. r=jfkthame (da06064b86)
- Bug 1165611 - fix font smoothing under Linux. r=karlt (166a96603b)
- Bug 1160506 - support intra-family font fallback. r=heycam (f56f0507d0)
- Bug 1165693 - Cache the result of calling FcConfigSubstitute for our sentinel font name, to make gfxFcPlatformFontList::FindFamily less expensive. r=jdaggett (09ace74bc1)
- Bug 1165693 - patch 2 - Cache family-name lookups in gfxFcPlatformFontList::FindFamily, to avoid repeating expensive calls to FcConfigSubstitute. r=jdaggett (ab34bf45c0)
- Bug 1174946 - Back out the (incorrectly-implemented) caching of sentinelFirstFamily from bug 1165693, which should be largely overshadowed by the mFcSubstituteCache anyway. r=jdaggett (9b7784b7a6)
- Bug 1165766 - Crash in AddFontSetFamilies() r=jtd (13cba8e6c7)
- Bug 1170421 - return first font suggested by fontconfig as the default font. r=karlt (426c6bd348)
- Bug 1008169 - Font selection and font size dropdowns are reacting very slowly on press up/down,r=jaws (8e395026e1)
- Bug 1166161 - Display available font from font.name-list.{family}.{lang} as fallback default font, instead of empty string. (045855761a)
- Bug 1187680 - Use NSVisualEffectMaterialMenu for menus if it's available. r=smichaud (0cede2f295)
- Bug 1190257. Use the previous vsync timestamp on windows 10. r=jrmuizel (7cf7e2644f)
- Bug 1220699 - Add telemetry probe to measure vsync latency in the parent refresh driver. r=avih (347936dffb)
- Bug 1221674 - Add telemetry probe in the content process to measure the time between refresh driver ticks. r=kats (1d1b885f10)
- Bug 1198362 - Delete PreciseRefreshDriverTimer. r=roc (8fdcca758f)
- Bug 1197898 - Delete vsync refresh driver preference. r=kats (eab85ba8dd)
- Bug 1210250. Fallback to GDI fonts with a skia backend. r=jwatt (8c374b4bd3)
- Bug 1208927 - Initialize queryD3DKMTStatistics so that it can't be accessed uninitialized; r=jrmuizel (69c6781a82)
- Bug 1144946 - Delete PreciseRefreshDriverTimerWindowsDwmVsync refresh driver timer. r=roc (a78ccb3d42)
- Bug 1187784 (part 4) - Replace nsBaseHashtable::EnumerateRead() calls in layout/ with iterators. r=heycam. (6a09016e6d)
- Bug 1187784 (part 3) - Replace nsBaseHashtable::EnumerateRead() calls in layout/ with iterators. r=heycam. (1ce8abd863)
- Bug 1187784 (part 2) - Replace nsBaseHashtable::EnumerateRead() calls in layout/ with iterators. r=heycam. (cd98be2f19)
- Bug 1187784 (part 1) - Replace nsBaseHashtable::EnumerateRead() calls in layout/ with iterators. r=heycam. (09022514a9)
- Bug 1217230 - Set mNeedToRecomputeVisibility true only when style or layout flush. r=seth (8f3edd57c0)
- Bug 1167281 - sort scalable fonts first when resolving generic families under Linux. r=karlt (e2ecb89f31)
- Bug 1186875 - check if FcFontSort returns non-null. r=jtd (087905da51)
- Bug 1218617 - Invalidate whole widget area after external composition r=mattwoodrow (3901f416f5)
- Bug 1153499 - Enable push and sw prefs. r=dougt,ehsan (ca0f3a105d)
- Bug 1141415 - add expire setting of permission to SpecialPowers. r=jmaher (372bc0c930)
- partial Bug 1196665 - Add originAttributes into SpecialPowers. r=bholley (b8407a1bcc)
- Bug 1213151 - Part 1: Add a SpecialPowers API for cleaning up the STS data that works in both e10s and non-e10s modes; r=jdm (04bba17fd3)
- Bug 1213151 - Part 2: Use SpecialPowers.cleanUpSTSData() in a few tests; r=jdm (cce5f23dac)
- Bug 1214593 - Remove service worker periodic updater. r=ehsan (87cfebcd0d)
- fix tests, fix spaces (9cba57e7ff)
- Bug 1207499 - Part 10: Remove use of expression closure from testing/. r=jmaher (652faa8963)
- Bug 1204154 - Clean up jar manifests that needlessly specify the source file. r=dao (f116e33bed)
- Bug 1222943 (part 1) - Change Touch::mRadius from nsIntPoint to LayoutDeviceIntPoint. r=kats. (dcc6c15797)
- Bug 1222943 (part 2) - Remove an unnecessary call to ToUnknownSize(). r=botond. (08f644f194)
- Bug 1220925 - Event::GetScreenCoords should return CSSIntPoint instead of LayoutDevicePoint. r=botond (4e4f54e8e7)
- Bug 943294 - Leave dealing with legacy codepages for clipboard data to Windows itself. r=jmathies. (124ecbfa3e)
- Bug 1243507 - Reimplement non-Unicode clipboard formats as bug 943294 broke drag and drop between some Unicode-unaware apps. r=jimm (02edc31ed9)
- ported Bug 1254980 - Ensure that text/html is still written to the clipboard. r=enndeakin a=sylvestre (9cd4c0e41a)
- nsWindow: build fix (1c3e798a89)
This commit is contained in:
2022-12-16 11:12:33 +08:00
parent a5c500f721
commit 8637eba4b3
691 changed files with 11000 additions and 6651 deletions
+1 -1
View File
@@ -150,7 +150,7 @@ nsCoreUtils::DispatchTouchEvent(EventMessage aMessage, int32_t aX, int32_t aY,
// XXX: Touch has an identifier of -1 to hint that it is synthesized.
RefPtr<dom::Touch> t = new dom::Touch(-1, LayoutDeviceIntPoint(aX, aY),
nsIntPoint(1, 1), 0.0f, 1.0f);
LayoutDeviceIntPoint(1, 1), 0.0f, 1.0f);
t->SetTarget(aContent);
event.touches.AppendElement(t);
nsEventStatus status = nsEventStatus_eIgnore;
+2 -1
View File
@@ -1081,8 +1081,9 @@ pref("gfx.vsync.refreshdriver", true);
pref("dom.activities.developer_mode_only", "import-app");
// mulet apparently loads firefox.js as well as b2g.js, so we have to explicitly
// disable serviceworkers here to get them disabled in mulet.
// disable serviceworkers and push here to get them disabled in mulet.
pref("dom.serviceWorkers.enabled", false);
pref("dom.push.enabled", false);
// Retain at most 10 processes' layers buffers
pref("layers.compositor-lru-size", 10);
+1 -4
View File
@@ -28,11 +28,8 @@ USE_LIBS += [
for var in ('MOZ_APP_NAME', 'MOZ_APP_VERSION', 'MOZ_UPDATER'):
DEFINES[var] = CONFIG[var]
GENERATED_INCLUDES += [
'/build',
]
LOCAL_INCLUDES += [
'!/build',
'/toolkit/xre',
'/xpcom/base',
'/xpcom/build',
+3 -3
View File
@@ -34,7 +34,7 @@
#endif
#ifdef MOZ_WIDGET_GONK
#include "GonkDisplay.h"
#include "BootAnimation.h"
#endif
#include "BinaryPath.h"
@@ -148,8 +148,8 @@ static int do_main(int argc, char* argv[])
}
#ifdef MOZ_WIDGET_GONK
/* Called to start the boot animation */
(void) mozilla::GetGonkDisplay();
/* Start boot animation */
mozilla::StartBootAnimation();
#endif
if (appini) {
+1 -5
View File
@@ -6,7 +6,6 @@
DIRS += ['profile/extensions']
if CONFIG['OS_ARCH'] == 'WINNT' and CONFIG['MOZ_ASAN']:
GeckoProgram(CONFIG['MOZ_APP_NAME'])
else:
@@ -27,11 +26,8 @@ DEFINES['APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
DEFINES['XPCOM_GLUE'] = True
GENERATED_INCLUDES += [
'/build',
]
LOCAL_INCLUDES += [
'!/build',
'/toolkit/xre',
'/xpcom/base',
'/xpcom/build',
+12 -6
View File
@@ -919,8 +919,13 @@ pref("dom.ipc.plugins.enabled.x86_64", true);
pref("dom.ipc.plugins.enabled", true);
#endif
// If decoding-via-gmp is turned on for <video>, default to using
// Adobe's GMP for decoding.
// Decode using Gecko Media Plugins in <video>, if a system decoder is not
// availble and the preferred GMP is available.
pref("media.gmp.decoder.enabled", true);
// If decoding-via-GMP is turned on for <video>, use Adobe's GMP for decoding,
// if it's available. Note: We won't fallback to another GMP if Adobe's is not
// installed.
pref("media.gmp.decoder.aac", 2);
pref("media.gmp.decoder.h264", 2);
@@ -1261,11 +1266,12 @@ pref("browser.display.standalone_images.background_color", "#2E3B41");
pref("view_source.tab", false);
// Enable Service Workers for desktop on non-release builds
#ifndef RELEASE_BUILD
// Enable ServiceWorkers for Push API consumers.
// Interception is still disabled.
pref("dom.serviceWorkers.enabled", true);
pref("dom.serviceWorkers.interception.enabled", true);
#endif
// Enable Push API.
pref("dom.push.enabled", true);
// ****************** domain-specific UAs ******************
@@ -91,7 +91,6 @@ pref("dom.max_script_run_time", 20); //Should be plenty for a page script to do
// ===| Canvas |===============================================================
pref("canvas.poisondata", true); //Enable canvas anti-fingerprinting by default for extra security
// ===| Plugins |==============================================================
+1 -2
View File
@@ -13,8 +13,7 @@ var gContentPane = {
this._rebuildFonts();
var menulist = document.getElementById("defaultFont");
if (menulist.selectedIndex == -1) {
menulist.insertItemAt(0, "", "", "");
menulist.selectedIndex = 0;
menulist.value = FontBuilder.readFontSelection(menulist);
}
},
-35
View File
@@ -63,41 +63,6 @@ var gFontsDialog = {
return undefined;
},
readFontSelection: function (aElement)
{
// Determine the appropriate value to select, for the following cases:
// - there is no setting
// - the font selected by the user is no longer present (e.g. deleted from
// fonts folder)
var preference = document.getElementById(aElement.getAttribute("preference"));
if (preference.value) {
var fontItems = aElement.getElementsByAttribute("value", preference.value);
// There is a setting that actually is in the list. Respect it.
if (fontItems.length > 0)
return undefined;
}
var defaultValue = aElement.firstChild.firstChild.getAttribute("value");
var languagePref = document.getElementById("font.language.group");
preference = document.getElementById("font.name-list." + aElement.id + "." + languagePref.value);
if (!preference || !preference.hasUserValue)
return defaultValue;
var fontNames = preference.value.split(",");
var stripWhitespace = /^\s*(.*)\s*$/;
for (var i = 0; i < fontNames.length; ++i) {
var fontName = fontNames[i].replace(stripWhitespace, "$1");
fontItems = aElement.getElementsByAttribute("value", fontName);
if (fontItems.length)
break;
}
if (fontItems.length)
return fontItems[0].getAttribute("value");
return defaultValue;
},
readUseDocumentFonts: function ()
{
var preference = document.getElementById("browser.display.use_document_fonts");
+8 -8
View File
@@ -107,7 +107,7 @@
accesskey="&sizeProportional.accesskey;"
control="sizeVar"/>
</hbox>
<menulist id="sizeVar">
<menulist id="sizeVar" delayprefsave="true">
<menupopup>
<menuitem value="9" label="9"/>
<menuitem value="10" label="10"/>
@@ -141,30 +141,30 @@
<hbox align="center" pack="end">
<label accesskey="&serif.accesskey;" control="serif">&serif.label;</label>
</hbox>
<menulist id="serif" flex="1" style="width: 0px;"
onsyncfrompreference="return gFontsDialog.readFontSelection(document.getElementById('serif'));"/>
<menulist id="serif" flex="1" style="width: 0px;" delayprefsave="true"
onsyncfrompreference="return FontBuilder.readFontSelection(this);"/>
<spacer/>
</row>
<row align="center">
<hbox align="center" pack="end">
<label accesskey="&sans-serif.accesskey;" control="sans-serif">&sans-serif.label;</label>
</hbox>
<menulist id="sans-serif" flex="1" style="width: 0px;"
onsyncfrompreference="return gFontsDialog.readFontSelection(document.getElementById('sans-serif'));"/>
<menulist id="sans-serif" flex="1" style="width: 0px;" delayprefsave="true"
onsyncfrompreference="return FontBuilder.readFontSelection(this);"/>
<spacer/>
</row>
<row align="center">
<hbox align="center" pack="end">
<label accesskey="&monospace.accesskey;" control="monospace">&monospace.label;</label>
</hbox>
<menulist id="monospace" flex="1" style="width: 0px;" crop="right"
onsyncfrompreference="return gFontsDialog.readFontSelection(document.getElementById('monospace'));"/>
<menulist id="monospace" flex="1" style="width: 0px;" crop="right" delayprefsave="true"
onsyncfrompreference="return FontBuilder.readFontSelection(this);"/>
<hbox align="center" pack="end">
<label value="&size.label;"
accesskey="&sizeMonospace.accesskey;"
control="sizeMono"/>
</hbox>
<menulist id="sizeMono">
<menulist id="sizeMono" delayprefsave="true">
<menupopup>
<menuitem value="9" label="9"/>
<menuitem value="10" label="10"/>
+3
View File
@@ -937,6 +937,9 @@ toolbar[iconsize="small"] #webrtc-status-button {
.urlbar-icon {
cursor: pointer;
padding: 0 3px;
/* 16x16 icon with border-box sizing */
width: 22px;
height: 16px;
}
#urlbar-search-splitter {
+6 -3
View File
@@ -912,7 +912,10 @@ html|*.urlbar-input:-moz-lwtheme::-moz-placeholder,
}
.urlbar-icon {
padding: 0 3px;
padding: 0 3px;
/* 16x16 icon with border-box sizing */
width: 22px;
height: 16px;
}
.searchbar-engine-button,
@@ -1276,8 +1279,8 @@ richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-
/* popup blocker button */
#page-report-button {
list-style-image: url("chrome://browser/skin/urlbar-popup-blocked.png");
-moz-image-region: rect(0, 16px, 16px, 0);
list-style-image: url("chrome://browser/skin/urlbar-popup-blocked.png");
-moz-image-region: rect(0, 16px, 16px, 0);
}
#page-report-button:hover {
+3
View File
@@ -1340,6 +1340,9 @@ html|*.urlbar-input:-moz-lwtheme::-moz-placeholder,
.urlbar-icon {
padding: 0 3px;
/* 16x16 icon with border-box sizing */
width: 22px;
height: 16px;
}
.searchbar-engine-button,
+7
View File
@@ -31,6 +31,13 @@ To ship chrome files in a JAR, an indented line indicates a file to be packaged:
<jarfile>.jar:
path/in/jar/file_name.xul (source/tree/location/file_name.xul)
If the JAR manifest and packaged file live in the same directory, the path and
parenthesis can be omitted. In other words, the following two lines are
equivalent::
path/in/jar/same_place.xhtml (same_place.xhtml)
path/in/jar/same_place.xhtml
The source tree location may also be an *absolute* path (taken from the
top of the source tree::
+1 -1
View File
@@ -2,7 +2,7 @@ _VSPATH="/c/tools/vs2013"
export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x86/Microsoft.VC120.CRT
## includes: win8.1 sdk includes, msvc std library, directx sdk for d3d9 ##
export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/um:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/winrt:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
## libs: win8.1 sdk x86 (32-bit) libs, msvc (32-bit) std library, msvc atl libs, directx sdk (32-bit) for d3d9 ##
export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/Lib/winv6.3/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib
+1 -1
View File
@@ -2,7 +2,7 @@ _VSPATH="/c/tools/vs2013"
export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x64/Microsoft.VC120.CRT
## includes: win8.1 sdk includes, msvc std library, directx sdk for d3d9 ##
export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/um:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/winrt:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
## libs: win8.1 sdk x64 (64-bit) libs, msvc (64-bit) std library, msvc atl libs, directx sdk (64-bit) for d3d9 ##
export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/Lib/winv6.3/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64
+1 -4
View File
@@ -28,11 +28,8 @@ include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
GENERATED_INCLUDES += [
'/xpcom',
]
LOCAL_INCLUDES += [
'!/xpcom',
'/netwerk/base',
'/netwerk/protocol/res',
'/xpcom/components'
@@ -163,11 +163,11 @@ function runTest() {
ok(app, "App is non-null");
is(app.manifestURL, gManifestURL, "App manifest url is correct.");
var context = {"manifestURL": app.manifestURL, "isInBrowserElement": false};
var context = {manifestURL: app.manifestURL};
SpecialPowers.pushPermissions([{"type": "homescreen-webapps-manage",
"allow": 1,
"context": context}], continueTest);
SpecialPowers.pushPermissions([{type: "homescreen-webapps-manage",
allow: 1,
context: context}], continueTest);
yield undefined;
// Launch the app.
+7 -7
View File
@@ -138,7 +138,7 @@ public:
EncodingRunnable(const nsAString& aType,
const nsAString& aOptions,
uint8_t* aImageBuffer,
UniquePtr<uint8_t[]> aImageBuffer,
layers::Image* aImage,
imgIEncoder* aEncoder,
EncodingCompleteEvent* aEncodingCompleteEvent,
@@ -147,7 +147,7 @@ public:
bool aUsingCustomOptions)
: mType(aType)
, mOptions(aOptions)
, mImageBuffer(aImageBuffer)
, mImageBuffer(Move(aImageBuffer))
, mImage(aImage)
, mEncoder(aEncoder)
, mEncodingCompleteEvent(aEncodingCompleteEvent)
@@ -161,7 +161,7 @@ public:
nsCOMPtr<nsIInputStream> stream;
nsresult rv = ImageEncoder::ExtractDataInternal(mType,
mOptions,
mImageBuffer,
mImageBuffer.get(),
mFormat,
mSize,
mImage,
@@ -175,7 +175,7 @@ public:
if (rv == NS_ERROR_INVALID_ARG && mUsingCustomOptions) {
rv = ImageEncoder::ExtractDataInternal(mType,
EmptyString(),
mImageBuffer,
mImageBuffer.get(),
mFormat,
mSize,
mImage,
@@ -220,7 +220,7 @@ public:
private:
nsAutoString mType;
nsAutoString mOptions;
nsAutoArrayPtr<uint8_t> mImageBuffer;
UniquePtr<uint8_t[]> mImageBuffer;
RefPtr<layers::Image> mImage;
nsCOMPtr<imgIEncoder> mEncoder;
RefPtr<EncodingCompleteEvent> mEncodingCompleteEvent;
@@ -287,7 +287,7 @@ nsresult
ImageEncoder::ExtractDataAsync(nsAString& aType,
const nsAString& aOptions,
bool aUsingCustomOptions,
uint8_t* aImageBuffer,
UniquePtr<uint8_t[]> aImageBuffer,
int32_t aFormat,
const nsIntSize aSize,
EncodeCompleteCallback* aEncodeCallback)
@@ -306,7 +306,7 @@ ImageEncoder::ExtractDataAsync(nsAString& aType,
nsCOMPtr<nsIRunnable> event = new EncodingRunnable(aType,
aOptions,
aImageBuffer,
Move(aImageBuffer),
nullptr,
encoder,
completeEvent,
+2 -1
View File
@@ -11,6 +11,7 @@
#include "nsError.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/HTMLCanvasElementBinding.h"
#include "mozilla/UniquePtr.h"
#include "nsLayoutUtils.h"
#include "nsSize.h"
@@ -58,7 +59,7 @@ public:
static nsresult ExtractDataAsync(nsAString& aType,
const nsAString& aOptions,
bool aUsingCustomOptions,
uint8_t* aImageBuffer,
UniquePtr<uint8_t[]> aImageBuffer,
int32_t aFormat,
const nsIntSize aSize,
EncodeCompleteCallback* aEncodeCallback);
-1
View File
@@ -106,7 +106,6 @@ class nsIWindowProvider;
struct JSPropertyDescriptor;
struct JSRuntime;
struct nsIntMargin;
template<class E> class nsCOMArray;
template<class K, class V> class nsDataHashtable;
+1 -4
View File
@@ -21,12 +21,9 @@
0x45f27d10, 0x987b, 0x11d2, \
{0xbd, 0x40, 0x00, 0x10, 0x5a, 0xa4, 0x5e, 0x89} }
#define SERVICEWORKERPERIODICUPDATER_CONTRACTID \
"@mozilla.org/service-worker-periodic-updater;1"
//The dom cannot provide the crypto or pkcs11 classes that
//were used in older days, so if someone wants to provide
//the service they must implement an object and give it
//the service they must implement an object and give it
//this class ID
#define NS_CRYPTO_CONTRACTID "@mozilla.org/security/crypto;1"
#define NS_PKCS11_CONTRACTID "@mozilla.org/security/pkcs11;1"
+8 -5
View File
@@ -983,11 +983,14 @@ nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType,
for (uint32_t i = 0; i < aCount; ++i) {
LayoutDeviceIntPoint pt =
nsContentUtils::ToWidgetPoint(CSSPoint(aXs[i], aYs[i]), offset, presContext);
RefPtr<Touch> t = new Touch(aIdentifiers[i],
pt,
nsIntPoint(aRxs[i], aRys[i]),
aRotationAngles[i],
aForces[i]);
LayoutDeviceIntPoint radius =
LayoutDeviceIntPoint::FromAppUnitsRounded(
CSSPoint::ToAppUnits(CSSPoint(aRxs[i], aRys[i])),
presContext->AppUnitsPerDevPixel());
RefPtr<Touch> t =
new Touch(aIdentifiers[i], pt, radius, aRotationAngles[i], aForces[i]);
event.touches.AppendElement(t);
}
+7 -7
View File
@@ -10591,13 +10591,13 @@ nsIDocument::CreateTouch(nsIDOMWindow* aView,
float aForce)
{
RefPtr<Touch> touch = new Touch(aTarget,
aIdentifier,
aPageX, aPageY,
aScreenX, aScreenY,
aClientX, aClientY,
aRadiusX, aRadiusY,
aRotationAngle,
aForce);
aIdentifier,
aPageX, aPageY,
aScreenX, aScreenY,
aClientX, aClientY,
aRadiusX, aRadiusY,
aRotationAngle,
aForce);
return touch.forget();
}
@@ -32,8 +32,8 @@ function setUp() {
let appId = gAppsService.getAppLocalIdByManifestURL(APP_MANIFEST);
SpecialPowers.addPermission("foobar", true, { url: APP_URL,
appId: appId,
isInBrowserElement: false });
originAttributes: { appId: appId }
});
SpecialPowers.pushPrefEnv({"set":[['dom.mozBrowserFramesEnabled', true],
['dom.ipc.browser_frames.oop_by_default', true]]}, runNextTest);
}
@@ -103,15 +103,17 @@
addEventListener("load", function() {
var principal = SpecialPowers.wrap(document).nodePrincipal;
SpecialPowers.pushPermissions([
{ "type": "browser", "allow": 1, "context": { "url": principal.URI.spec,
"appId": principal.appId,
"isInBrowserElement": false }},
{ "type": "browser", "allow": 1, "context": { "url": principal.URI.spec,
"appId": principal.appId,
"isInBrowserElement": true }}
{ type: "browser", allow: 1, context: { url: principal.URI.spec,
originAttributes: {
appId: principal.appId
}}},
{ type: "browser", allow: 1, context: { url: principal.URI.spec,
originAttributes: {
appId: principal.appId,
inBrowser: true }}}
], () => {
SpecialPowers.pushPrefEnv({
"set": [
set: [
["dom.mozBrowserFramesEnabled", true],
["dom.ipc.browser_frames.oop_by_default", false],
]
+1 -5
View File
@@ -1225,11 +1225,7 @@ function test41()
ok(true, "test 41c close");
// clean up the STS state
const Cc = SpecialPowers.Cc;
const Ci = SpecialPowers.Ci;
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
var thehost = ios.newURI("http://example.com", null, null);
var sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService);
var loadContext = SpecialPowers.wrap(window)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
@@ -1237,7 +1233,7 @@ function test41()
var flags = 0;
if (loadContext.usePrivateBrowsing)
flags |= Ci.nsISocketProvider.NO_PERMANENT_STORAGE;
sss.removeState(Ci.nsISiteSecurityService.HEADER_HSTS, thehost, flags);
SpecialPowers.cleanUpSTSData("http://example.com", flags);
doTest(42);
}
}
+1 -1
View File
@@ -41,8 +41,8 @@ WEBIDL_EXAMPLE_INTERFACES += [
'TestExampleProxyInterface',
]
GENERATED_INCLUDES += ['..']
LOCAL_INCLUDES += [
'!..',
'/dom/bindings',
'/js/xpconnect/src',
'/js/xpconnect/wrappers',
@@ -22,17 +22,16 @@ function runTest() {
document.body.appendChild(iframe);
var context = { 'url': 'http://example.org',
'appId': SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
'isInBrowserElement': true };
var context = {url: 'http://example.org',
originAttributes: {inBrowser: true}};
SpecialPowers.pushPermissions([
{'type': 'browser', 'allow': 1, 'context': context},
{'type': 'embed-apps', 'allow': 1, 'context': context}
{type: 'browser', allow: 1, context: context},
{type: 'embed-apps', allow: 1, context: context}
], function() {
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_AllowEmbedAppsInNestedOOIframe.html';
});
}
addEventListener('testready', () => {
SpecialPowers.pushPrefEnv({"set": [["dom.ipc.tabs.nested.enabled", true]]}, runTest);
SpecialPowers.pushPrefEnv({set: [["dom.ipc.tabs.nested.enabled", true]]}, runTest);
});
@@ -321,13 +321,14 @@ function testCut2(e) {
// Give our origin permission to open browsers, and remove it when the test is complete.
var principal = SpecialPowers.wrap(document).nodePrincipal;
var context = { 'url': SpecialPowers.wrap(principal.URI).spec,
'appId': principal.appId,
'isInBrowserElement': true };
var context = { url: SpecialPowers.wrap(principal.URI).spec,
originAttributes: {
appId: principal.appId,
inBrowser: true }};
addEventListener('testready', function() {
SpecialPowers.pushPermissions([
{'type': 'browser', 'allow': 1, 'context': context}
{type: 'browser', allow: 1, context: context}
], runTest);
});
@@ -28,12 +28,11 @@ function runTest() {
document.body.appendChild(iframe);
var context = { 'url': 'http://example.org',
'appId': SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
'isInBrowserElement': true };
var context = {url: 'http://example.org',
originAttributes: {inBrowser: true}};
SpecialPowers.pushPermissions([
{'type': 'browser', 'allow': 1, 'context': context},
{'type': 'embed-apps', 'allow': 1, 'context': context}
{type: 'browser', allow: 1, context: context},
{type: 'embed-apps', allow: 1, context: context}
], function() {
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_DisallowEmbedAppsInOOP.html';
});
@@ -36,8 +36,7 @@ function runTest() {
allow: true,
context: {
url: imeUrl,
appId: SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
isInBrowserElement: true
originAttributes: {inBrowser: true}
}
}], SimpleTest.waitForFocus.bind(SimpleTest, createFrames));
}
@@ -18,9 +18,11 @@ var iframe;
function runTest() {
var principal = SpecialPowers.wrap(document).nodePrincipal;
SpecialPowers.addPermission("browser", true, { url: SpecialPowers.wrap(principal.URI).spec,
appId: principal.appId,
isInBrowserElement: true });
SpecialPowers.addPermission("browser", true, {url: SpecialPowers.wrap(principal.URI).spec,
originAttributes: {
appId: principal.appId,
inBrowser: true
}});
iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
@@ -75,10 +77,11 @@ function finish() {
iframe.removeEventListener('mozbrowsershowmodalprompt', checkMessage);
var principal = SpecialPowers.wrap(document).nodePrincipal;
SpecialPowers.removePermission("browser", { url: SpecialPowers.wrap(principal.URI).spec,
appId: principal.appId,
isInBrowserElement: true });
SpecialPowers.removePermission("browser", {url: SpecialPowers.wrap(principal.URI).spec,
originAttributes: {
appId: principal.appId,
inBrowser: true
}});
SimpleTest.finish();
}
@@ -12,9 +12,11 @@ browserElementTestHelpers.addPermission();
function runTest() {
var principal = SpecialPowers.wrap(document).nodePrincipal;
SpecialPowers.addPermission("browser", true, { url: SpecialPowers.wrap(principal.URI).spec,
appId: principal.appId,
isInBrowserElement: true });
SpecialPowers.addPermission("browser", true, {url: SpecialPowers.wrap(principal.URI).spec,
originAttributes: {
appId: principal.appId,
inBrowser: true
}});
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
@@ -56,9 +58,11 @@ function runTest() {
function finish() {
var principal = SpecialPowers.wrap(document).nodePrincipal;
SpecialPowers.removePermission("browser", { url: SpecialPowers.wrap(principal.URI).spec,
appId: principal.appId,
isInBrowserElement: true });
SpecialPowers.removePermission("browser", {url: SpecialPowers.wrap(principal.URI).spec,
originAttributes: {
appId: principal.appId,
inBrowser: true
}});
SimpleTest.finish();
}
@@ -22,15 +22,19 @@ SpecialPowers.addPermission("embed-apps", true, document);
// Give our origin permission to open browsers, and remove it when the test is complete.
var principal = SpecialPowers.wrap(document).nodePrincipal;
SpecialPowers.addPermission("browser", true, { url: SpecialPowers.wrap(principal.URI).spec,
appId: principal.appId,
isInBrowserElement: true });
SpecialPowers.addPermission("browser", true, {url: SpecialPowers.wrap(principal.URI).spec,
originAttributes: {
appId: principal.appId,
inBrowser: true
}});
addEventListener('unload', function() {
var principal = SpecialPowers.wrap(document).nodePrincipal;
SpecialPowers.removePermission("browser", { url: SpecialPowers.wrap(principal.URI).spec,
appId: principal.appId,
isInBrowserElement: true });
SpecialPowers.removePermission("browser", {url: SpecialPowers.wrap(principal.URI).spec,
originAttributes: {
appId: principal.appId,
inBrowser: true
}});
});
function runTest() {
@@ -21,15 +21,19 @@ browserElementTestHelpers.enableProcessPriorityManager();
// Give our origin permission to open browsers, and remove it when the test is complete.
var principal = SpecialPowers.wrap(document).nodePrincipal;
SpecialPowers.addPermission("browser", true, { url: SpecialPowers.wrap(principal.URI).spec,
appId: principal.appId,
isInBrowserElement: true });
SpecialPowers.addPermission("browser", true, {url: SpecialPowers.wrap(principal.URI).spec,
originAttributes: {
appId: principal.appId,
inBrowser: true
}});
addEventListener('unload', function() {
var principal = SpecialPowers.wrap(document).nodePrincipal;
SpecialPowers.removePermission("browser", { url: SpecialPowers.wrap(principal.URI).spec,
appId: principal.appId,
isInBrowserElement: true });
SpecialPowers.removePermission("browser", {url: SpecialPowers.wrap(principal.URI).spec,
originAttributes: {
appId: principal.appId,
inBrowser: true
}});
});
function runTest() {
+1 -10
View File
@@ -34,16 +34,7 @@ function runTests(testFile, order) {
// adapted from dom/indexedDB/test/helpers.js
function clearStorage() {
return new Promise(function(resolve, reject) {
var principal = SpecialPowers.wrap(document).nodePrincipal;
var appId, inBrowser;
var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
principal.appId != nsIPrincipal.NO_APP_ID) {
appId = principal.appId;
inBrowser = principal.isInBrowserElement;
}
SpecialPowers.clearStorageForURI(document.documentURI, resolve, appId,
inBrowser);
SpecialPowers.clearStorageForDoc(SpecialPowers.wrap(document), resolve);
});
}
+3 -30
View File
@@ -24,46 +24,19 @@ function setupTestIframe() {
function clearStorage() {
return new Promise(function(resolve, reject) {
var principal = SpecialPowers.wrap(document).nodePrincipal;
var appId, inBrowser;
var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
principal.appId != nsIPrincipal.NO_APP_ID) {
appId = principal.appId;
inBrowser = principal.isInBrowserElement;
}
SpecialPowers.clearStorageForURI(document.documentURI, resolve, appId,
inBrowser);
SpecialPowers.clearStorageForDoc(SpecialPowers.wrap(document), resolve);
});
}
function storageUsage() {
return new Promise(function(resolve, reject) {
var principal = SpecialPowers.wrap(document).nodePrincipal;
var appId, inBrowser;
var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
principal.appId != nsIPrincipal.NO_APP_ID) {
appId = principal.appId;
inBrowser = principal.isInBrowserElement;
}
SpecialPowers.getStorageUsageForURI(document.documentURI, resolve, appId,
inBrowser);
SpecialPowers.getStorageUsageForDoc(SpecialPowers.wrap(document), resolve);
});
}
function resetStorage() {
return new Promise(function(resolve, reject) {
var principal = SpecialPowers.wrap(document).nodePrincipal;
var appId, inBrowser;
var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
principal.appId != nsIPrincipal.NO_APP_ID) {
appId = principal.appId;
inBrowser = principal.isInBrowserElement;
}
SpecialPowers.resetStorageForURI(document.documentURI, resolve, appId,
inBrowser);
SpecialPowers.resetStorageForDoc(SpecialPowers.wrap(document), resolve);
});
}
+3 -30
View File
@@ -24,46 +24,19 @@ function setupTestIframe() {
function clearStorage() {
return new Promise(function(resolve, reject) {
var principal = SpecialPowers.wrap(document).nodePrincipal;
var appId, inBrowser;
var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
principal.appId != nsIPrincipal.NO_APP_ID) {
appId = principal.appId;
inBrowser = principal.isInBrowserElement;
}
SpecialPowers.clearStorageForURI(document.documentURI, resolve, appId,
inBrowser);
SpecialPowers.clearStorageForDoc(SpecialPowers.wrap(document), resolve);
});
}
function storageUsage() {
return new Promise(function(resolve, reject) {
var principal = SpecialPowers.wrap(document).nodePrincipal;
var appId, inBrowser;
var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
principal.appId != nsIPrincipal.NO_APP_ID) {
appId = principal.appId;
inBrowser = principal.isInBrowserElement;
}
SpecialPowers.getStorageUsageForURI(document.documentURI, resolve, appId,
inBrowser);
SpecialPowers.getStorageUsageForDoc(SpecialPowers.wrap(document), resolve);
});
}
function resetStorage() {
return new Promise(function(resolve, reject) {
var principal = SpecialPowers.wrap(document).nodePrincipal;
var appId, inBrowser;
var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
principal.appId != nsIPrincipal.NO_APP_ID) {
appId = principal.appId;
inBrowser = principal.isInBrowserElement;
}
SpecialPowers.resetStorageForURI(document.documentURI, resolve, appId,
inBrowser);
SpecialPowers.resetStorageForDoc(SpecialPowers.wrap(document), resolve);
});
}
+1 -10
View File
@@ -11,16 +11,7 @@
<script class="testbody" type="text/javascript">
function resetStorage() {
return new Promise(function(resolve, reject) {
var principal = SpecialPowers.wrap(document).nodePrincipal;
var appId, inBrowser;
var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
principal.appId != nsIPrincipal.NO_APP_ID) {
appId = principal.appId;
inBrowser = principal.isInBrowserElement;
}
SpecialPowers.resetStorageForURI(document.documentURI, resolve, appId,
inBrowser);
SpecialPowers.resetStorageForDoc(SpecialPowers.wrap(document), resolve);
});
}
+3 -30
View File
@@ -12,46 +12,19 @@
<script class="testbody" type="text/javascript">
function clearStorage() {
return new Promise(function(resolve, reject) {
var principal = SpecialPowers.wrap(document).nodePrincipal;
var appId, inBrowser;
var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
principal.appId != nsIPrincipal.NO_APP_ID) {
appId = principal.appId;
inBrowser = principal.isInBrowserElement;
}
SpecialPowers.clearStorageForURI(document.documentURI, resolve, appId,
inBrowser);
SpecialPowers.clearStorageForDoc(SpecialPowers.wrap(document), resolve);
});
}
function storageUsage() {
return new Promise(function(resolve, reject) {
var principal = SpecialPowers.wrap(document).nodePrincipal;
var appId, inBrowser;
var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
principal.appId != nsIPrincipal.NO_APP_ID) {
appId = principal.appId;
inBrowser = principal.isInBrowserElement;
}
SpecialPowers.getStorageUsageForURI(document.documentURI, resolve, appId,
inBrowser);
SpecialPowers.getStorageUsageForDoc(SpecialPowers.wrap(document), resolve);
});
}
function resetStorage() {
return new Promise(function(resolve, reject) {
var principal = SpecialPowers.wrap(document).nodePrincipal;
var appId, inBrowser;
var nsIPrincipal = SpecialPowers.Components.interfaces.nsIPrincipal;
if (principal.appId != nsIPrincipal.UNKNOWN_APP_ID &&
principal.appId != nsIPrincipal.NO_APP_ID) {
appId = principal.appId;
inBrowser = principal.isInBrowserElement;
}
SpecialPowers.resetStorageForURI(document.documentURI, resolve, appId,
inBrowser);
SpecialPowers.resetStorageForDoc(SpecialPowers.wrap(document), resolve);
});
}
+10 -55
View File
@@ -1648,26 +1648,24 @@ CanvasRenderingContext2D::SetContextOptions(JSContext* aCx,
return NS_OK;
}
void
CanvasRenderingContext2D::GetImageBuffer(uint8_t** aImageBuffer,
int32_t* aFormat)
UniquePtr<uint8_t[]>
CanvasRenderingContext2D::GetImageBuffer(int32_t* aFormat)
{
*aImageBuffer = nullptr;
*aFormat = 0;
EnsureTarget();
RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
if (!snapshot) {
return;
return nullptr;
}
RefPtr<DataSourceSurface> data = snapshot->GetDataSurface();
if (!data || data->GetSize() != IntSize(mWidth, mHeight)) {
return;
return nullptr;
}
*aImageBuffer = SurfaceToPackedBGRA(data);
*aFormat = imgIEncoder::INPUT_FORMAT_HOSTARGB;
return SurfaceToPackedBGRA(data);
}
nsString CanvasRenderingContext2D::GetHitRegion(const mozilla::gfx::Point& aPoint)
@@ -1693,29 +1691,15 @@ CanvasRenderingContext2D::GetInputStream(const char *aMimeType,
return NS_ERROR_FAILURE;
}
nsAutoArrayPtr<uint8_t> imageBuffer;
int32_t format = 0;
GetImageBuffer(getter_Transfers(imageBuffer), &format);
UniquePtr<uint8_t[]> imageBuffer = GetImageBuffer(&format);
if (!imageBuffer) {
return NS_ERROR_FAILURE;
}
bool PoisonData = Preferences::GetBool("canvas.poisondata",false);
if (PoisonData) {
srand(time(nullptr));
// Image buffer is always a packed BGRA array (BGRX -> BGR[FF])
// so always 4-value pixels.
// GetImageBuffer => SurfaceToPackedBGRA [=> ConvertBGRXToBGRA]
int32_t dataSize = mWidth * mHeight * 4;
#pragma omp parallel for
for (int32_t j = 0; j < dataSize; ++j) {
if (imageBuffer[j] !=0 && imageBuffer[j] != 255)
imageBuffer[j] += rand() % 3 - 1;
}
}
return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer, format,
encoder, aEncoderOptions, aStream);
return ImageEncoder::GetInputStream(mWidth, mHeight, imageBuffer.get(),
format, encoder, aEncoderOptions,
aStream);
}
SurfaceFormat
@@ -4496,7 +4480,7 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& image,
if (ok) {
NativeSurface texSurf;
texSurf.mType = NativeSurfaceType::OPENGL_TEXTURE;
texSurf.mFormat = SurfaceFormat::R5G6B5;
texSurf.mFormat = SurfaceFormat::R5G6B5_UINT16;
texSurf.mSize.width = mCurrentVideoSize.width;
texSurf.mSize.height = mCurrentVideoSize.height;
texSurf.mSurface = (void*)((uintptr_t)mVideoTexture);
@@ -5153,14 +5137,6 @@ CanvasRenderingContext2D::GetImageData(JSContext* aCx, double aSx,
return imageData.forget();
}
inline uint8_t PoisonValue(uint8_t v)
{
if (v==0 || v==255)
return v; //don't fuzz edges to prevent overflow/underflow
return v + rand() %3 -1;
}
nsresult
CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
int32_t aX,
@@ -5174,10 +5150,6 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
}
MOZ_ASSERT(aWidth && aHeight);
bool PoisonData = Preferences::GetBool("canvas.poisondata",false);
if (PoisonData)
srand(time(nullptr));
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(aWidth) * aHeight * 4;
if (!len.isValid() || len.value() > INT32_MAX) {
@@ -5253,14 +5225,6 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
g = *src++;
b = *src++;
#endif
// Poison data for trackers if enabled
if (PoisonData) {
PoisonValue(r);
PoisonValue(g);
PoisonValue(b);
}
*dst++ = r;
*dst++ = g;
*dst++ = b;
@@ -5284,15 +5248,6 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
g = *src++;
b = *src++;
#endif
// Poison data for trackers if enabled
if (PoisonData) {
PoisonValue(a);
PoisonValue(r);
PoisonValue(g);
PoisonValue(b);
}
// Convert to non-premultiplied color
*dst++ = gfxUtils::sUnpremultiplyTable[a * 256 + r];
*dst++ = gfxUtils::sUnpremultiplyTable[a * 256 + g];
+2 -1
View File
@@ -20,6 +20,7 @@
#include "mozilla/dom/CanvasPattern.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/UniquePtr.h"
#include "gfx2DGlue.h"
#include "imgIEncoder.h"
#include "nsLayoutUtils.h"
@@ -533,7 +534,7 @@ public:
friend class CanvasRenderingContext2DUserData;
virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat) override;
virtual UniquePtr<uint8_t[]> GetImageBuffer(int32_t* aFormat) override;
// Given a point, return hit region ID if it exists
+4 -3
View File
@@ -7,6 +7,7 @@
#include "ImageEncoder.h"
#include "mozilla/dom/CanvasRenderingContext2D.h"
#include "mozilla/Telemetry.h"
#include "mozilla/UniquePtr.h"
#include "nsContentUtils.h"
#include "nsDOMJSUtils.h"
#include "nsIScriptContext.h"
@@ -49,10 +50,10 @@ CanvasRenderingContextHelper::ToBlob(JSContext* aCx,
}
}
uint8_t* imageBuffer = nullptr;
UniquePtr<uint8_t[]> imageBuffer;
int32_t format = 0;
if (mCurrentContext) {
mCurrentContext->GetImageBuffer(&imageBuffer, &format);
imageBuffer = mCurrentContext->GetImageBuffer(&format);
}
// Encoder callback when encoding is complete.
@@ -99,7 +100,7 @@ CanvasRenderingContextHelper::ToBlob(JSContext* aCx,
aRv = ImageEncoder::ExtractDataAsync(type,
params,
usingCustomParseOptions,
imageBuffer,
Move(imageBuffer),
format,
GetWidthHeight(),
callback);
+6 -6
View File
@@ -1033,25 +1033,25 @@ WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
}
}
void
WebGLContext::GetImageBuffer(uint8_t** out_imageBuffer, int32_t* out_format)
UniquePtr<uint8_t[]>
WebGLContext::GetImageBuffer(int32_t* out_format)
{
*out_imageBuffer = nullptr;
*out_format = 0;
// Use GetSurfaceSnapshot() to make sure that appropriate y-flip gets applied
bool premult;
RefPtr<SourceSurface> snapshot =
GetSurfaceSnapshot(mOptions.premultipliedAlpha ? nullptr : &premult);
if (!snapshot)
return;
if (!snapshot) {
return nullptr;
}
MOZ_ASSERT(mOptions.premultipliedAlpha || !premult, "We must get unpremult when we ask for it!");
RefPtr<DataSourceSurface> dataSurface = snapshot->GetDataSurface();
return gfxUtils::GetImageBuffer(dataSurface, mOptions.premultipliedAlpha,
out_imageBuffer, out_format);
out_format);
}
NS_IMETHODIMP
+1 -2
View File
@@ -234,8 +234,7 @@ public:
return NS_ERROR_NOT_IMPLEMENTED;
}
virtual void GetImageBuffer(uint8_t** out_imageBuffer,
int32_t* out_format) override;
virtual UniquePtr<uint8_t[]> GetImageBuffer(int32_t* out_format) override;
NS_IMETHOD GetInputStream(const char* mimeType,
const char16_t* encoderOptions,
nsIInputStream** out_stream) override;
+2 -1
View File
@@ -7,6 +7,7 @@
#include "GLContext.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/UniquePtrExtensions.h"
#include "WebGLBuffer.h"
#include "WebGLContextUtils.h"
#include "WebGLFramebuffer.h"
@@ -581,7 +582,7 @@ WebGLContext::DoFakeVertexAttrib0(GLuint vertexCount)
GetAndFlushUnderlyingGLErrors();
if (mFakeVertexAttrib0BufferStatus == WebGLVertexAttrib0Status::EmulatedInitializedArray) {
UniquePtr<GLfloat[]> array(new (fallible) GLfloat[4 * vertexCount]);
auto array = MakeUniqueFallible<GLfloat[]>(4 * vertexCount);
if (!array) {
ErrorOutOfMemory("Fake attrib0 array.");
return false;
+3 -2
View File
@@ -51,6 +51,7 @@
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/Endian.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtrExtensions.h"
namespace mozilla {
@@ -1589,7 +1590,7 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
uint32_t subrect_byteLength = (subrect_height-1)*subrect_alignedRowSize + subrect_plainRowSize;
// create subrect buffer, call glReadPixels, copy pixels into destination buffer, delete subrect buffer
UniquePtr<GLubyte> subrect_data(new (fallible) GLubyte[subrect_byteLength]);
auto subrect_data = MakeUniqueFallible<GLubyte[]>(subrect_byteLength);
if (!subrect_data)
return ErrorOutOfMemory("readPixels: subrect_data");
@@ -1936,7 +1937,7 @@ WebGLContext::SurfaceFromElementResultToImageSurface(nsLayoutUtils::SurfaceFromE
case SurfaceFormat::A8:
*format = WebGLTexelFormat::A8;
break;
case SurfaceFormat::R5G6B5:
case SurfaceFormat::R5G6B5_UINT16:
*format = WebGLTexelFormat::RGB565;
break;
default:
@@ -14,6 +14,7 @@
#include "mozilla/dom/HTMLCanvasElement.h"
#include "mozilla/dom/OffscreenCanvas.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
#define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID \
{ 0xb84f2fed, 0x9d4b, 0x430b, \
@@ -96,7 +97,7 @@ public:
NS_IMETHOD InitializeWithSurface(nsIDocShell *docShell, gfxASurface *surface, int32_t width, int32_t height) = 0;
// Creates an image buffer. Returns null on failure.
virtual void GetImageBuffer(uint8_t** imageBuffer, int32_t* format) = 0;
virtual mozilla::UniquePtr<uint8_t[]> GetImageBuffer(int32_t* format) = 0;
// Gives you a stream containing the image represented by this context.
// The format is given in mimeTime, for example "image/png".
+1
View File
@@ -31,6 +31,7 @@
#include "mozilla/dom/FileList.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/OSFileSystem.h"
#include "mozilla/dom/Promise.h"
namespace mozilla {
namespace dom {
+1 -1
View File
@@ -20,7 +20,6 @@
#include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/Promise.h"
class nsINode;
class nsITransferable;
@@ -36,6 +35,7 @@ namespace dom {
class DOMStringList;
class Element;
class FileList;
class Promise;
template<typename T> class Optional;
/**
+18 -11
View File
@@ -898,7 +898,8 @@ Event::Shutdown()
}
}
LayoutDeviceIntPoint
// static
CSSIntPoint
Event::GetScreenCoords(nsPresContext* aPresContext,
WidgetEvent* aEvent,
LayoutDeviceIntPoint aPoint)
@@ -906,8 +907,7 @@ Event::GetScreenCoords(nsPresContext* aPresContext,
if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode() &&
nsContentUtils::ResistFingerprinting()) {
// When resisting fingerprinting, return client coordinates instead.
CSSIntPoint clientCoords = GetClientCoords(aPresContext, aEvent, aPoint, CSSIntPoint(0, 0));
return LayoutDeviceIntPoint(clientCoords.x, clientCoords.y);
return GetClientCoords(aPresContext, aEvent, aPoint, CSSIntPoint(0, 0));
}
if (EventStateManager::sIsPointerLocked) {
@@ -922,19 +922,26 @@ Event::GetScreenCoords(nsPresContext* aPresContext,
aEvent->mClass != eTouchEventClass &&
aEvent->mClass != eDragEventClass &&
aEvent->mClass != eSimpleGestureEventClass)) {
return LayoutDeviceIntPoint(0, 0);
return CSSIntPoint(0, 0);
}
// Doing a straight conversion from LayoutDeviceIntPoint to CSSIntPoint
// seem incorrect, but it is needed to maintain legacy functionality.
if (!aPresContext) {
return CSSIntPoint(aPoint.x, aPoint.y);
}
LayoutDeviceIntPoint offset = aPoint;
WidgetGUIEvent* guiEvent = aEvent->AsGUIEvent();
if (!guiEvent->widget) {
return aPoint;
if (guiEvent && guiEvent->widget) {
offset += guiEvent->widget->WidgetToScreenOffset();
}
LayoutDeviceIntPoint offset = aPoint + guiEvent->widget->WidgetToScreenOffset();
nscoord factor =
aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
return LayoutDeviceIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor),
nsPresContext::AppUnitsToIntCSSPixels(offset.y * factor));
nsPoint pt =
LayoutDevicePixel::ToAppUnits(offset, aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
return CSSPixel::FromAppUnitsRounded(pt);
}
// static
+3 -3
View File
@@ -133,9 +133,9 @@ public:
WidgetEvent* aEvent,
LayoutDeviceIntPoint aPoint,
CSSIntPoint aDefaultPoint);
static LayoutDeviceIntPoint GetScreenCoords(nsPresContext* aPresContext,
WidgetEvent* aEvent,
LayoutDeviceIntPoint aPoint);
static CSSIntPoint GetScreenCoords(nsPresContext* aPresContext,
WidgetEvent* aEvent,
LayoutDeviceIntPoint aPoint);
static CSSIntPoint GetOffsetCoords(nsPresContext* aPresContext,
WidgetEvent* aEvent,
LayoutDeviceIntPoint aPoint,
+3 -3
View File
@@ -270,7 +270,7 @@ EventStateManager* EventStateManager::sActiveESM = nullptr;
nsIDocument* EventStateManager::sMouseOverDocument = nullptr;
nsWeakFrame EventStateManager::sLastDragOverFrame = nullptr;
LayoutDeviceIntPoint EventStateManager::sLastRefPoint = kInvalidRefPoint;
LayoutDeviceIntPoint EventStateManager::sLastScreenPoint = LayoutDeviceIntPoint(0, 0);
CSSIntPoint EventStateManager::sLastScreenPoint = CSSIntPoint(0, 0);
LayoutDeviceIntPoint EventStateManager::sSynthCenteringPoint = kInvalidRefPoint;
CSSIntPoint EventStateManager::sLastClientPoint = CSSIntPoint(0, 0);
bool EventStateManager::sIsPointerLocked = false;
@@ -556,9 +556,9 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
aEvent->mClass == eWheelEventClass) &&
!sIsPointerLocked) {
sLastScreenPoint =
UIEvent::CalculateScreenPoint(aPresContext, aEvent);
Event::GetScreenCoords(aPresContext, aEvent, aEvent->refPoint);
sLastClientPoint =
UIEvent::CalculateClientPoint(aPresContext, aEvent, nullptr);
Event::GetClientCoords(aPresContext, aEvent, aEvent->refPoint, CSSIntPoint(0, 0));
}
*aStatus = nsEventStatus_eIgnore;
+1 -1
View File
@@ -250,7 +250,7 @@ public:
// locked. This is used by dom::Event::GetScreenCoords() to make mouse
// events' screen coord appear frozen at the last mouse position while
// the pointer is locked.
static LayoutDeviceIntPoint sLastScreenPoint;
static CSSIntPoint sLastScreenPoint;
// Holds the point in client coords of the last mouse event. Used by
// dom::Event::GetClientCoords() to make mouse events' client coords appear
+20 -3
View File
@@ -32,7 +32,7 @@ Touch::Touch(EventTarget* aTarget,
mTarget = aTarget;
mIdentifier = aIdentifier;
mPagePoint = CSSIntPoint(aPageX, aPageY);
mScreenPoint = LayoutDeviceIntPoint(aScreenX, aScreenY);
mScreenPoint = CSSIntPoint(aScreenX, aScreenY);
mClientPoint = CSSIntPoint(aClientX, aClientY);
mRefPoint = LayoutDeviceIntPoint(0, 0);
mPointsInitialized = true;
@@ -48,13 +48,13 @@ Touch::Touch(EventTarget* aTarget,
Touch::Touch(int32_t aIdentifier,
LayoutDeviceIntPoint aPoint,
nsIntPoint aRadius,
LayoutDeviceIntPoint aRadius,
float aRotationAngle,
float aForce)
{
mIdentifier = aIdentifier;
mPagePoint = CSSIntPoint(0, 0);
mScreenPoint = LayoutDeviceIntPoint(0, 0);
mScreenPoint = CSSIntPoint(0, 0);
mClientPoint = CSSIntPoint(0, 0);
mRefPoint = aPoint;
mPointsInitialized = false;
@@ -67,6 +67,23 @@ Touch::Touch(int32_t aIdentifier,
nsJSContext::LikelyShortLivingObjectCreated();
}
Touch::Touch(const Touch& aOther)
: mTarget(aOther.mTarget)
, mRefPoint(aOther.mRefPoint)
, mChanged(aOther.mChanged)
, mMessage(aOther.mMessage)
, mIdentifier(aOther.mIdentifier)
, mPagePoint(aOther.mPagePoint)
, mClientPoint(aOther.mClientPoint)
, mScreenPoint(aOther.mScreenPoint)
, mRadius(aOther.mRadius)
, mRotationAngle(aOther.mRotationAngle)
, mForce(aOther.mForce)
, mPointsInitialized(aOther.mPointsInitialized)
{
nsJSContext::LikelyShortLivingObjectCreated();
}
Touch::~Touch()
{
}
+4 -3
View File
@@ -42,9 +42,10 @@ public:
float aForce);
Touch(int32_t aIdentifier,
LayoutDeviceIntPoint aPoint,
nsIntPoint aRadius,
LayoutDeviceIntPoint aRadius,
float aRotationAngle,
float aForce);
Touch(const Touch& aOther);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Touch)
@@ -80,8 +81,8 @@ public:
int32_t mIdentifier;
CSSIntPoint mPagePoint;
CSSIntPoint mClientPoint;
LayoutDeviceIntPoint mScreenPoint;
nsIntPoint mRadius;
CSSIntPoint mScreenPoint;
LayoutDeviceIntPoint mRadius;
float mRotationAngle;
float mForce;
protected:
+2 -2
View File
@@ -181,10 +181,10 @@ TouchEvent::PrefEnabled(JSContext* aCx, JSObject* aGlobal)
int32_t flag = 0;
if (NS_SUCCEEDED(Preferences::GetInt("dom.w3c_touch_events.enabled", &flag))) {
if (flag == 2) {
#ifdef XP_WIN
#if defined(XP_WIN) || MOZ_WIDGET_GTK == 3
static bool sDidCheckTouchDeviceSupport = false;
static bool sIsTouchDeviceSupportPresent = false;
// On Windows we auto-detect based on device support.
// On Windows and GTK3 we auto-detect based on device support.
if (!sDidCheckTouchDeviceSupport) {
sDidCheckTouchDeviceSupport = true;
sIsTouchDeviceSupportPresent = WidgetUtils::IsTouchDeviceSupportPresent();
+4 -2
View File
@@ -342,11 +342,13 @@ UIEvent::DuplicatePrivateData()
mPagePoint =
Event::GetPageCoords(mPresContext, mEvent, mEvent->refPoint, mClientPoint);
// GetScreenPoint converts mEvent->refPoint to right coordinates.
LayoutDeviceIntPoint screenPoint =
CSSIntPoint screenPoint =
Event::GetScreenCoords(mPresContext, mEvent, mEvent->refPoint);
nsresult rv = Event::DuplicatePrivateData();
if (NS_SUCCEEDED(rv)) {
mEvent->refPoint = screenPoint;
CSSToLayoutDeviceScale scale = mPresContext ? mPresContext->CSSToDevPixelScale()
: CSSToLayoutDeviceScale(1);
mEvent->refPoint = RoundedToInt(screenPoint * scale);
}
return rv;
}
-56
View File
@@ -40,62 +40,6 @@ public:
NS_IMETHOD_(void) Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType) override;
NS_IMETHOD_(bool) Deserialize(const IPC::Message* aMsg, void** aIter) override;
static LayoutDeviceIntPoint CalculateScreenPoint(nsPresContext* aPresContext,
WidgetEvent* aEvent)
{
if (!aEvent ||
(aEvent->mClass != eMouseEventClass &&
aEvent->mClass != eMouseScrollEventClass &&
aEvent->mClass != eWheelEventClass &&
aEvent->mClass != eDragEventClass &&
aEvent->mClass != ePointerEventClass &&
aEvent->mClass != eSimpleGestureEventClass)) {
return LayoutDeviceIntPoint(0, 0);
}
WidgetGUIEvent* event = aEvent->AsGUIEvent();
if (!event->widget) {
return aEvent->refPoint;
}
LayoutDeviceIntPoint offset = aEvent->refPoint + event->widget->WidgetToScreenOffset();
nscoord factor =
aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
return LayoutDeviceIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor),
nsPresContext::AppUnitsToIntCSSPixels(offset.y * factor));
}
static CSSIntPoint CalculateClientPoint(nsPresContext* aPresContext,
WidgetEvent* aEvent,
CSSIntPoint* aDefaultClientPoint)
{
if (!aEvent ||
(aEvent->mClass != eMouseEventClass &&
aEvent->mClass != eMouseScrollEventClass &&
aEvent->mClass != eWheelEventClass &&
aEvent->mClass != eDragEventClass &&
aEvent->mClass != ePointerEventClass &&
aEvent->mClass != eSimpleGestureEventClass) ||
!aPresContext ||
!aEvent->AsGUIEvent()->widget) {
return aDefaultClientPoint
? *aDefaultClientPoint
: CSSIntPoint(0, 0);
}
nsIPresShell* shell = aPresContext->GetPresShell();
if (!shell) {
return CSSIntPoint(0, 0);
}
nsIFrame* rootFrame = shell->GetRootFrame();
if (!rootFrame) {
return CSSIntPoint(0, 0);
}
nsPoint pt =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, rootFrame);
return CSSIntPoint::FromAppUnitsRounded(pt);
}
static already_AddRefed<UIEvent> Constructor(const GlobalObject& aGlobal,
const nsAString& aType,
-1
View File
@@ -124,7 +124,6 @@ skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
[test_bug704423.html]
[test_bug741666.html]
skip-if = toolkit == 'android'
[test_bug742376.html]
[test_bug812744.html]
[test_bug855741.html]
@@ -146,10 +146,6 @@ const kEventConstructors = {
return e;
},
},
CSSFontFaceLoadEvent: { create: function (aName, aProps) {
return new CSSFontFaceLoadEvent(aName, aProps);
},
},
CustomEvent: { create: function (aName, aProps) {
return new CustomEvent(aName, aProps);
},
@@ -223,6 +219,10 @@ const kEventConstructors = {
return new FocusEvent(aName, aProps);
},
},
FontFaceSetLoadEvent: { create: function (aName, aProps) {
return new FontFaceSetLoadEvent(aName, aProps);
},
},
GamepadEvent: { create: function (aName, aProps) {
return new GamepadEvent(aName, aProps);
},
+25 -10
View File
@@ -146,11 +146,11 @@ class VersionChangeTransaction;
// If JS_STRUCTURED_CLONE_VERSION changes then we need to update our major
// schema version.
static_assert(JS_STRUCTURED_CLONE_VERSION == 5,
static_assert(JS_STRUCTURED_CLONE_VERSION == 6,
"Need to update the major schema version.");
// Major schema version. Bump for almost everything.
const uint32_t kMajorSchemaVersion = 21;
const uint32_t kMajorSchemaVersion = 22;
// Minor schema version. Should almost always be 0 (maybe bump on release
// branches if we have to).
@@ -1986,21 +1986,21 @@ private:
}
size_t compressedLength = snappy::MaxCompressedLength(uncompressedLength);
nsAutoArrayPtr<char> compressed(new (fallible) char[compressedLength]);
UniqueFreePtr<uint8_t> compressed(
static_cast<uint8_t*>(malloc(compressedLength)));
if (NS_WARN_IF(!compressed)) {
return NS_ERROR_OUT_OF_MEMORY;
}
snappy::RawCompress(reinterpret_cast<const char*>(uncompressed),
uncompressedLength, compressed.get(),
uncompressedLength,
reinterpret_cast<char*>(compressed.get()),
&compressedLength);
std::pair<const void *, int> data(static_cast<void*>(compressed.get()),
int(compressedLength));
std::pair<uint8_t *, int> data(compressed.release(),
int(compressedLength));
// XXX This copies the buffer again... There doesn't appear to be any way to
// preallocate space and write directly to a BlobVariant at the moment.
nsCOMPtr<nsIVariant> result = new mozilla::storage::BlobVariant(data);
nsCOMPtr<nsIVariant> result = new mozilla::storage::AdoptedBlobVariant(data);
result.forget(aResult);
return NS_OK;
@@ -4066,6 +4066,19 @@ UpgradeSchemaFrom20_0To21_0(mozIStorageConnection* aConnection)
return NS_OK;
}
nsresult
UpgradeSchemaFrom21_0To22_0(mozIStorageConnection* aConnection)
{
// The only change between 21 and 22 was a different structured clone format,
// but it's backwards-compatible.
nsresult rv = aConnection->SetSchemaVersion(MakeSchemaVersion(22, 0));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult
GetDatabaseFileURL(nsIFile* aDatabaseFile,
PersistenceType aPersistenceType,
@@ -4558,7 +4571,7 @@ CreateStorageConnection(nsIFile* aDBFile,
}
} else {
// This logic needs to change next time we change the schema!
static_assert(kSQLiteSchemaVersion == int32_t((21 << 4) + 0),
static_assert(kSQLiteSchemaVersion == int32_t((22 << 4) + 0),
"Upgrade function needed due to schema version increase.");
while (schemaVersion != kSQLiteSchemaVersion) {
@@ -4598,6 +4611,8 @@ CreateStorageConnection(nsIFile* aDBFile,
rv = UpgradeSchemaFrom19_0To20_0(aFMDirectory, connection);
} else if (schemaVersion == MakeSchemaVersion(20, 0)) {
rv = UpgradeSchemaFrom20_0To21_0(connection);
} else if (schemaVersion == MakeSchemaVersion(21, 0)) {
rv = UpgradeSchemaFrom21_0To22_0(connection);
} else {
IDB_WARNING("Unable to open IndexedDB database, no upgrade path is "
"available!");
+1 -11
View File
@@ -189,17 +189,7 @@ function grabFileUsageAndContinueHandler(usage, fileUsage)
function getUsage(usageHandler)
{
let principal = SpecialPowers.wrap(document).nodePrincipal;
let appId, inBrowser;
if (principal.appId != Components.interfaces.nsIPrincipal.UNKNOWN_APP_ID &&
principal.appId != Components.interfaces.nsIPrincipal.NO_APP_ID) {
appId = principal.appId;
inBrowser = principal.isInBrowserElement;
}
SpecialPowers.getStorageUsageForURI(window.document.documentURI,
usageHandler,
appId,
inBrowser);
SpecialPowers.getStorageUsageForDoc(SpecialPowers.wrap(document), usageHandler);
}
function getFileId(file)
+2 -9
View File
@@ -34,17 +34,10 @@ function executeSoon(aFun)
}
function clearAllDatabases(callback) {
let principal = SpecialPowers.wrap(document).nodePrincipal;
let appId, inBrowser;
if (principal.appId != Components.interfaces.nsIPrincipal.UNKNOWN_APP_ID &&
principal.appId != Components.interfaces.nsIPrincipal.NO_APP_ID) {
appId = principal.appId;
inBrowser = principal.isInBrowserElement;
}
SpecialPowers.clearStorageForURI(document.documentURI, callback, appId, inBrowser);
SpecialPowers.clearStorageForDoc(SpecialPowers.wrap(document), callback);
}
let testHarnessGenerator = testHarnessSteps();
var testHarnessGenerator = testHarnessSteps();
testHarnessGenerator.next();
function testHarnessSteps() {
@@ -117,11 +117,9 @@ function start()
}
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.addPermission("browser", true, { manifestURL: manifestURL,
isInBrowserElement: false });
SpecialPowers.addPermission("browser", true, { manifestURL: manifestURL });
SpecialPowers.addPermission("embed-apps", true, document);
SpecialPowers.addPermission("indexedDB", true, { manifestURL: manifestURL,
isInBrowserElement: false });
SpecialPowers.addPermission("indexedDB", true, { manifestURL: manifestURL });
SpecialPowers.setAllAppsLaunchable(true);
@@ -91,8 +91,9 @@ function runTest() {
allow: true,
context: {
url: imeUrl,
appId: SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
isInBrowserElement: true
originAttributes: {
inBrowser: true
}
}
}], function() {
keyboardA.src = imeUrl;
@@ -78,8 +78,9 @@ function runTest() {
allow: true,
context: {
url: imeUrl,
appId: SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
isInBrowserElement: true
originAttributes: {
inBrowser: true
}
}
}], function() {
// STEP 2c: Tell Gecko to use this iframe as its keyboard app
@@ -34,7 +34,7 @@ interface nsIServiceWorkerInfo : nsISupports
readonly attribute DOMString waitingCacheName;
};
[scriptable, builtinclass, uuid(8fb9db4f-1d04-402b-9c37-542da06e03b9)]
[scriptable, builtinclass, uuid(10f80c8c-7bf5-479e-a8d8-12ef50c802e8)]
interface nsIServiceWorkerManager : nsISupports
{
/**
@@ -145,8 +145,6 @@ interface nsIServiceWorkerManager : nsISupports
[optional, array, size_is(aDataLength)] in uint8_t aDataBytes);
void sendPushSubscriptionChangeEvent(in ACString aOriginAttributes,
in ACString scope);
void updateAllRegistrations();
};
%{ C++
-11
View File
@@ -78,7 +78,6 @@
#include "nsIMutable.h"
#include "nsIObserverService.h"
#include "nsIScriptSecurityManager.h"
#include "nsIServiceWorkerManager.h"
#include "nsScreenManagerProxy.h"
#include "nsMemoryInfoDumper.h"
#include "nsServiceManagerUtils.h"
@@ -1417,16 +1416,6 @@ ContentChild::RecvBidiKeyboardNotify(const bool& aIsLangRTL)
return true;
}
bool
ContentChild::RecvUpdateServiceWorkerRegistrations()
{
nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager();
if (swm) {
swm->UpdateAllRegistrations();
}
return true;
}
static CancelableTask* sFirstIdleTask;
static void FirstIdle(void)
-2
View File
@@ -320,8 +320,6 @@ public:
virtual bool RecvBidiKeyboardNotify(const bool& isLangRTL) override;
virtual bool RecvUpdateServiceWorkerRegistrations() override;
virtual bool RecvNotifyVisited(const URIParams& aURI) override;
// auto remove when alertfinished is received.
nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);
-2
View File
@@ -511,8 +511,6 @@ child:
*/
async BidiKeyboardNotify(bool isLangRTL);
async UpdateServiceWorkerRegistrations();
async DataStoreNotify(uint32_t aAppId, nsString aName,
nsString aManifestURL);
+8 -6
View File
@@ -955,7 +955,7 @@ TabParent::UpdateDimensions(const nsIntRect& rect, const ScreenIntSize& size)
ViewAs<LayoutDevicePixel>(mRect,
PixelCastJustification::LayoutDeviceIsScreenForTabDims);
LayoutDeviceIntSize devicePixelSize =
ViewAs<LayoutDevicePixel>(mDimensions.ToUnknownSize(),
ViewAs<LayoutDevicePixel>(mDimensions,
PixelCastJustification::LayoutDeviceIsScreenForTabDims);
CSSRect unscaledRect = devicePixelRect / widgetScale;
@@ -2891,11 +2891,13 @@ TabParent::InjectTouchEvent(const nsAString& aType,
CSSPoint::ToAppUnits(CSSPoint(aXs[i], aYs[i])),
presContext->AppUnitsPerDevPixel());
RefPtr<Touch> t = new Touch(aIdentifiers[i],
pt,
nsIntPoint(aRxs[i], aRys[i]),
aRotationAngles[i],
aForces[i]);
LayoutDeviceIntPoint radius =
LayoutDeviceIntPoint::FromAppUnitsRounded(
CSSPoint::ToAppUnits(CSSPoint(aRxs[i], aRys[i])),
presContext->AppUnitsPerDevPixel());
RefPtr<Touch> t =
new Touch(aIdentifiers[i], pt, radius, aRotationAngles[i], aForces[i]);
// Consider all injected touch events as changedTouches. For more details
// about the meaning of changedTouches for each event, see
@@ -33,8 +33,7 @@ var tests = [
function() {
var appId = gAppsService.getAppLocalIdByManifestURL(embedAppHostedManifestURL);
var context = { url: embedApp.origin,
appId: appId,
isInBrowserElement: false };
originAttributes: { appId: appId } };
setupOpenAppPermission(context, runTests);
},
@@ -33,8 +33,7 @@ var tests = [
function() {
var appId = gAppsService.getAppLocalIdByManifestURL(embedAppHostedManifestURL);
var context = { url: embedApp.origin,
appId: appId,
isInBrowserElement: false };
originAttributes: { appId: appId } };
setupOpenAppPermission(context, runTests);
},
+7 -14
View File
@@ -53,8 +53,7 @@ function test1() {
if (!SpecialPowers.hasPermission( PERMISSION_TYPE,
{ url: APP_URL,
appId: appId,
isInBrowserElement: false })) {
originAttributes: { appId: appId }})) {
errorHandler('[test 1] App should have permission: ' + PERMISSION_TYPE);
}
@@ -82,8 +81,7 @@ function test2() {
if (!SpecialPowers.hasPermission( PERMISSION_TYPE,
{ url: APP_URL,
appId: appId,
isInBrowserElement: false })) {
originAttributes: { appId: appId }})) {
errorHandler('[test 2] App should have permission: ' + PERMISSION_TYPE);
}
@@ -111,8 +109,7 @@ function test3() {
if (!SpecialPowers.hasPermission(PERMISSION_TYPE,
{ url: APP_URL,
appId: appId,
isInBrowserElement: false })) {
originAttributes: { appId: appId }})) {
errorHandler('[test 3] App should have permission: ' + PERMISSION_TYPE);
}
}
@@ -148,8 +145,7 @@ function test4() {
if (!SpecialPowers.hasPermission(PERMISSION_TYPE,
{ url: APP_URL,
appId: appId,
isInBrowserElement: false })) {
originAttributes: { appId: appId }})) {
errorHandler('[test 4] App should have permission: ' + PERMISSION_TYPE);
}
}
@@ -174,8 +170,7 @@ function test5() {
if (!SpecialPowers.hasPermission( PERMISSION_TYPE,
{ url: APP_URL,
appId: appId,
isInBrowserElement: false })) {
originAttributes: { appId: appId }})) {
errorHandler('[test 5] App should have permission: ' + PERMISSION_TYPE);
}
@@ -290,8 +285,7 @@ function addPermissionToApp(appURL, manifestURL) {
"expireType":permManager.EXPIRE_SESSION,
"expireTime":now + SESSION_PERSIST_MINUTES*60*1000,
"context": { url: appURL,
appId: appId,
isInBrowserElement:false }
originAttributes: { appId: appId } }
}
], function() {
runTests();
@@ -303,8 +297,7 @@ function runNextIfAppHasPermission(round, expect, appURL, manifestURL) {
var hasPerm = SpecialPowers.hasPermission(PERMISSION_TYPE,
{ url: appURL,
appId: appId,
isInBrowserElement: false });
originAttributes: { appId: appId }});
var result = (expect==hasPerm);
if (result) {
runTests();
@@ -33,8 +33,7 @@ var tests = [
function() {
var appId = gAppsService.getAppLocalIdByManifestURL(embedAppHostedManifestURL);
var context = { url: embedApp.origin,
appId: appId,
isInBrowserElement: false };
originAttributes: { appId: appId } };
setupOpenAppPermission(context, runTests);
},
-4
View File
@@ -116,10 +116,6 @@ public:
// Called from HTMLMediaElement when owner document activity changes
virtual void SetElementVisibility(bool aIsVisible) {}
// Called by some MediaDecoderReader to determine if we can rely
// on the resource length to limit reads.
virtual bool HasInitializationData() { return false; }
// Stack based class to assist in notifying the frame statistics of
// parsed and decoded frames. Use inside video demux & decode functions
// to ensure all parsed and decoded frames are reported on all return paths.
+15 -13
View File
@@ -198,14 +198,14 @@ VideoData::ShallowCopyUpdateTimestampAndDuration(const VideoData* aOther,
}
/* static */
void VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
bool VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
const VideoInfo& aInfo,
const YCbCrBuffer &aBuffer,
const IntRect& aPicture,
bool aCopyData)
{
if (!aVideoImage) {
return;
return false;
}
const YCbCrBuffer::Plane &Y = aBuffer.mPlanes[0];
const YCbCrBuffer::Plane &Cb = aBuffer.mPlanes[1];
@@ -229,9 +229,9 @@ void VideoData::SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
aVideoImage->SetDelayedConversion(true);
if (aCopyData) {
aVideoImage->SetData(data);
return aVideoImage->SetData(data);
} else {
aVideoImage->SetDataNoCopy(data);
return aVideoImage->SetDataNoCopy(data);
}
}
@@ -330,12 +330,10 @@ VideoData::Create(const VideoInfo& aInfo,
"Wrong format?");
PlanarYCbCrImage* videoImage = static_cast<PlanarYCbCrImage*>(v->mImage.get());
if (!aImage) {
VideoData::SetVideoDataToImage(videoImage, aInfo, aBuffer, aPicture,
true /* aCopyData */);
} else {
VideoData::SetVideoDataToImage(videoImage, aInfo, aBuffer, aPicture,
false /* aCopyData */);
bool shouldCopyData = (aImage == nullptr);
if (!VideoData::SetVideoDataToImage(videoImage, aInfo, aBuffer, aPicture,
shouldCopyData)) {
return nullptr;
}
#ifdef MOZ_WIDGET_GONK
@@ -346,8 +344,10 @@ VideoData::Create(const VideoInfo& aInfo,
return nullptr;
}
videoImage = static_cast<PlanarYCbCrImage*>(v->mImage.get());
VideoData::SetVideoDataToImage(videoImage, aInfo, aBuffer, aPicture,
true /* aCopyData */);
if(!VideoData::SetVideoDataToImage(videoImage, aInfo, aBuffer, aPicture,
true /* aCopyData */)) {
return nullptr;
}
}
#endif
return v.forget();
@@ -473,7 +473,9 @@ VideoData::Create(const VideoInfo& aInfo,
data.mPicSize = aPicture.Size();
data.mGraphicBuffer = aBuffer;
videoImage->SetData(data);
if (!videoImage->SetData(data)) {
return nullptr;
}
return v.forget();
}
+2 -1
View File
@@ -283,7 +283,7 @@ public:
// Initialize PlanarYCbCrImage. Only When aCopyData is true,
// video data is copied to PlanarYCbCrImage.
static void SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
static bool SetVideoDataToImage(PlanarYCbCrImage* aVideoImage,
const VideoInfo& aInfo,
const YCbCrBuffer &aBuffer,
const IntRect& aPicture,
@@ -334,6 +334,7 @@ public:
nsTArray<nsCString> mSessionIds;
};
// MediaRawData is a MediaData container used to store demuxed, still compressed
// samples.
// Use MediaRawData::CreateWriter() to obtain a MediaRawDataWriter object that
+20 -18
View File
@@ -412,14 +412,17 @@ bool MediaDecoderStateMachine::HaveNextFrameData()
(!HasVideo() || VideoQueue().GetSize() > 1);
}
int64_t MediaDecoderStateMachine::GetDecodedAudioDuration()
int64_t
MediaDecoderStateMachine::GetDecodedAudioDuration()
{
MOZ_ASSERT(OnTaskQueue());
int64_t audioDecoded = AudioQueue().Duration();
if (mMediaSink->IsStarted()) {
audioDecoded += AudioEndTime() - GetMediaTime();
// |mDecodedAudioEndTime == -1| means no decoded audio at all so the
// returned duration is 0.
return mDecodedAudioEndTime != -1 ? mDecodedAudioEndTime - GetClock() : 0;
}
return audioDecoded;
// MediaSink not started. All audio samples are in the queue.
return AudioQueue().Duration();
}
void MediaDecoderStateMachine::DiscardStreamData()
@@ -884,14 +887,16 @@ MediaDecoderStateMachine::OnVideoDecoded(MediaData* aVideoSample)
StopPrerollingVideo();
}
// Schedule the state machine to send stream data as soon as possible or
// the VideoQueue() is empty before the Push().
// VideoQueue() is empty implies the state machine thread doesn't have
// precise time information about video frames. Once the first video
// frame pushed in the queue, schedule the state machine as soon as
// possible to render the video frame or delay the state machine thread
// accurately.
if (VideoQueue().GetSize() == 1) {
// Schedule the state machine to send stream data as soon as possible if
// the VideoQueue() is empty or contains one frame before the Push().
//
// The state machine threads requires a frame in VideoQueue() that is `in
// the future` to gather precise timing information. The head of
// VideoQueue() is always `in the past`.
//
// Schedule the state machine as soon as possible to render the video
// frame or delay the state machine thread accurately.
if (VideoQueue().GetSize() <= 2) {
ScheduleStateMachine();
}
@@ -1806,12 +1811,6 @@ int64_t MediaDecoderStateMachine::AudioDecodedUsecs()
// already decoded and pushed to the hardware, plus the amount of audio
// data waiting to be pushed to the hardware.
int64_t pushed = mMediaSink->IsStarted() ? (AudioEndTime() - GetMediaTime()) : 0;
// Currently for real time streams, AudioQueue().Duration() produce
// wrong values (Bug 1114434), so we use frame counts to calculate duration.
if (IsRealTime()) {
return pushed + FramesToUsecs(AudioQueue().FrameCount(), mInfo.mAudio.mRate).value();
}
return pushed + AudioQueue().Duration();
}
@@ -2412,6 +2411,9 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
clockTime = std::max(int64_t(0), std::max(clockTime, Duration().ToMicroseconds()));
UpdatePlaybackPosition(clockTime);
// Ensure readyState is updated before firing the 'ended' event.
UpdateNextFrameStatus();
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableMethod(mDecoder, &MediaDecoder::PlaybackEnded);
AbstractThread::MainThread()->Dispatch(event.forget());
+117 -89
View File
@@ -10,11 +10,13 @@
#include "mozilla/AbstractThread.h"
#include "mozilla/Atomics.h"
#include "mozilla/Mutex.h"
#include "mozilla/Tuple.h"
#include "mozilla/TypeTraits.h"
#include "mozilla/UniquePtr.h"
#include "nsISupportsImpl.h"
#include "nsTArray.h"
#include "nsThreadUtils.h"
namespace mozilla {
@@ -129,19 +131,25 @@ class ListenerHelper {
// Define our custom runnable to minimize copy of the event data.
// NS_NewRunnableFunction will result in 2 copies of the event data.
// One is captured by the lambda and the other is the copy of the lambda.
template <typename T>
template <typename... Ts>
class R : public nsRunnable {
typedef typename RemoveCV<typename RemoveReference<T>::Type>::Type ArgType;
public:
template <typename U>
R(RevocableToken* aToken, const Function& aFunction, U&& aEvent)
: mToken(aToken), mFunction(aFunction), mEvent(Forward<U>(aEvent)) {}
template <typename... Us>
R(RevocableToken* aToken, const Function& aFunction, Us&&... aEvents)
: mToken(aToken)
, mFunction(aFunction)
, mEvents(Forward<Us>(aEvents)...) {}
template <typename... Vs, size_t... Is>
void Invoke(Tuple<Vs...>& aEvents, IndexSequence<Is...>) {
// Enable move whenever possible since mEvent won't be used anymore.
mFunction(Move(Get<Is>(aEvents))...);
}
NS_IMETHOD Run() override {
// Don't call the listener if it is disconnected.
if (!mToken->IsRevoked()) {
// Enable move whenever possible since mEvent won't be used anymore.
mFunction(Move(mEvent));
Invoke(mEvents, typename IndexSequenceFor<Ts...>::Type());
}
return NS_OK;
}
@@ -149,25 +157,29 @@ class ListenerHelper {
private:
RefPtr<RevocableToken> mToken;
Function mFunction;
ArgType mEvent;
template <typename T>
using ArgType = typename RemoveCV<typename RemoveReference<T>::Type>::Type;
Tuple<ArgType<Ts>...> mEvents;
};
public:
ListenerHelper(RevocableToken* aToken, Target* aTarget, const Function& aFunc)
: mToken(aToken), mTarget(aTarget), mFunction(aFunc) {}
// |F| takes one argument.
template <typename F, typename T>
// |F| takes one or more arguments.
template <typename F, typename... Ts>
typename EnableIf<TakeArgs<F>::value, void>::Type
Dispatch(const F& aFunc, T&& aEvent) {
nsCOMPtr<nsIRunnable> r = new R<T>(mToken, aFunc, Forward<T>(aEvent));
DispatchHelper(const F& aFunc, Ts&&... aEvents) {
nsCOMPtr<nsIRunnable> r =
new R<Ts...>(mToken, aFunc, Forward<Ts>(aEvents)...);
EventTarget<Target>::Dispatch(mTarget.get(), r.forget());
}
// |F| takes no arguments. Don't bother passing aEvent.
template <typename F, typename T>
template <typename F, typename... Ts>
typename EnableIf<!TakeArgs<F>::value, void>::Type
Dispatch(const F& aFunc, T&&) {
DispatchHelper(const F& aFunc, Ts&&...) {
const RefPtr<RevocableToken>& token = mToken;
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([=] () {
// Don't call the listener if it is disconnected.
@@ -178,9 +190,9 @@ public:
EventTarget<Target>::Dispatch(mTarget.get(), r.forget());
}
template <typename T>
void Dispatch(T&& aEvent) {
Dispatch(mFunction, Forward<T>(aEvent));
template <typename... Ts>
void Dispatch(Ts&&... aEvents) {
DispatchHelper(mFunction, Forward<Ts>(aEvents)...);
}
private:
@@ -194,12 +206,10 @@ private:
*
* @Copy Data will always be copied. Each listener gets a copy.
* @Move Data will always be moved.
* @Both Data will be moved when possible or copied when necessary.
*/
enum class EventPassMode : int8_t {
Copy,
Move,
Both
Move
};
class ListenerBase {
@@ -220,96 +230,82 @@ private:
* Since virtual methods can not be templated, this class is specialized
* to provide different Dispatch() overloads depending on EventPassMode.
*/
template <typename ArgType, EventPassMode Mode = EventPassMode::Copy>
template <EventPassMode Mode, typename... As>
class Listener : public ListenerBase {
public:
virtual ~Listener() {}
virtual void Dispatch(const ArgType& aEvent) = 0;
virtual void Dispatch(const As&... aEvents) = 0;
};
template <typename ArgType>
class Listener<ArgType, EventPassMode::Both> : public ListenerBase {
template <typename... As>
class Listener<EventPassMode::Move, As...> : public ListenerBase {
public:
virtual ~Listener() {}
virtual void Dispatch(const ArgType& aEvent) = 0;
virtual void Dispatch(ArgType&& aEvent) = 0;
};
template <typename ArgType>
class Listener<ArgType, EventPassMode::Move> : public ListenerBase {
public:
virtual ~Listener() {}
virtual void Dispatch(ArgType&& aEvent) = 0;
virtual void Dispatch(As&&... aEvents) = 0;
};
/**
* Store the registered target thread and function so it knows where and to
* whom to send the event data.
*/
template <typename Target, typename Function, typename ArgType, EventPassMode>
class ListenerImpl : public Listener<ArgType, EventPassMode::Copy> {
template <typename Target, typename Function, EventPassMode, typename... As>
class ListenerImpl : public Listener<EventPassMode::Copy, As...> {
public:
ListenerImpl(Target* aTarget, const Function& aFunction)
: mHelper(ListenerBase::Token(), aTarget, aFunction) {}
void Dispatch(const ArgType& aEvent) override {
mHelper.Dispatch(aEvent);
void Dispatch(const As&... aEvents) override {
mHelper.Dispatch(aEvents...);
}
private:
ListenerHelper<Target, Function> mHelper;
};
template <typename Target, typename Function, typename ArgType>
class ListenerImpl<Target, Function, ArgType, EventPassMode::Both>
: public Listener<ArgType, EventPassMode::Both> {
template <typename Target, typename Function, typename... As>
class ListenerImpl<Target, Function, EventPassMode::Move, As...>
: public Listener<EventPassMode::Move, As...> {
public:
ListenerImpl(Target* aTarget, const Function& aFunction)
: mHelper(ListenerBase::Token(), aTarget, aFunction) {}
void Dispatch(const ArgType& aEvent) override {
mHelper.Dispatch(aEvent);
}
void Dispatch(ArgType&& aEvent) override {
mHelper.Dispatch(Move(aEvent));
}
private:
ListenerHelper<Target, Function> mHelper;
};
template <typename Target, typename Function, typename ArgType>
class ListenerImpl<Target, Function, ArgType, EventPassMode::Move>
: public Listener<ArgType, EventPassMode::Move> {
public:
ListenerImpl(Target* aTarget, const Function& aFunction)
: mHelper(ListenerBase::Token(), aTarget, aFunction) {}
void Dispatch(ArgType&& aEvent) override {
mHelper.Dispatch(Move(aEvent));
void Dispatch(As&&... aEvents) override {
mHelper.Dispatch(Move(aEvents)...);
}
private:
ListenerHelper<Target, Function> mHelper;
};
/**
* Select EventPassMode based on ListenerMode and if the type is copyable.
* Select EventPassMode based on ListenerMode.
*
* @Copy Selected when ListenerMode is NonExclusive because each listener
* must get a copy.
*
* @Move Selected when ListenerMode is Exclusive and the type is move-only.
*
* @Both Selected when ListenerMode is Exclusive and the type is copyable.
* The data will be moved when possible and copied when necessary.
* @Move Selected when ListenerMode is Exclusive. All types passed to
* MediaEventProducer::Notify() must be movable.
*/
template <typename ArgType, ListenerMode Mode>
template <ListenerMode Mode>
struct PassModePicker {
// TODO: pick EventPassMode::Both when we can detect if a type is
// copy-constructible to allow copy-only types in Exclusive mode.
static const EventPassMode Value =
Mode == ListenerMode::NonExclusive ?
EventPassMode::Copy : EventPassMode::Move;
};
/**
* Return true if any type is a reference type.
*/
template <typename Head, typename... Tails>
struct IsAnyReference {
static const bool value = IsReference<Head>::value ||
IsAnyReference<Tails...>::value;
};
template <typename T>
struct IsAnyReference<T> {
static const bool value = IsReference<T>::value;
};
} // namespace detail
template <typename T, ListenerMode> class MediaEventSource;
template <ListenerMode, typename... Ts> class MediaEventSourceImpl;
/**
* Not thread-safe since this is not meant to be shared and therefore only
@@ -318,8 +314,8 @@ template <typename T, ListenerMode> class MediaEventSource;
* listener from an event source.
*/
class MediaEventListener {
template <typename T, ListenerMode>
friend class MediaEventSource;
template <ListenerMode, typename... Ts>
friend class MediaEventSourceImpl;
public:
MediaEventListener() {}
@@ -342,6 +338,12 @@ public:
mToken = nullptr;
}
void DisconnectIfExists() {
if (mToken) {
Disconnect();
}
}
private:
// Avoid exposing RevocableToken directly to the client code so that
// listeners can be disconnected in a controlled manner.
@@ -352,16 +354,22 @@ private:
/**
* A generic and thread-safe class to implement the observer pattern.
*/
template <typename EventType, ListenerMode Mode = ListenerMode::NonExclusive>
class MediaEventSource {
static_assert(!IsReference<EventType>::value, "Ref-type not supported!");
typedef typename detail::EventTypeTraits<EventType>::ArgType ArgType;
static const detail::EventPassMode PassMode
= detail::PassModePicker<ArgType, Mode>::Value;
typedef detail::Listener<ArgType, PassMode> Listener;
template <ListenerMode Mode, typename... Es>
class MediaEventSourceImpl {
static_assert(!detail::IsAnyReference<Es...>::value,
"Ref-type not supported!");
template <typename T>
using ArgType = typename detail::EventTypeTraits<T>::ArgType;
static const detail::EventPassMode PassMode =
detail::PassModePicker<Mode>::Value;
typedef detail::Listener<PassMode, ArgType<Es>...> Listener;
template<typename Target, typename Func>
using ListenerImpl = detail::ListenerImpl<Target, Func, ArgType, PassMode>;
using ListenerImpl =
detail::ListenerImpl<Target, Func, PassMode, ArgType<Es>...>;
template <typename Method>
using TakeArgs = detail::TakeArgs<Method>;
@@ -376,13 +384,13 @@ class MediaEventSource {
return MediaEventListener((*l)->Token());
}
// |Method| takes one argument.
// |Method| takes one or more arguments.
template <typename Target, typename This, typename Method>
typename EnableIf<TakeArgs<Method>::value, MediaEventListener>::Type
ConnectInternal(Target* aTarget, This* aThis, Method aMethod) {
detail::RawPtr<This> thiz(aThis);
auto f = [=] (ArgType&& aEvent) {
(thiz.get()->*aMethod)(Move(aEvent));
auto f = [=] (ArgType<Es>&&... aEvents) {
(thiz.get()->*aMethod)(Move(aEvents)...);
};
return ConnectInternal(aTarget, f);
}
@@ -443,10 +451,10 @@ public:
}
protected:
MediaEventSource() : mMutex("MediaEventSource::mMutex") {}
MediaEventSourceImpl() : mMutex("MediaEventSourceImpl::mMutex") {}
template <typename T>
void NotifyInternal(T&& aEvent) {
template <typename... Ts>
void NotifyInternal(Ts&&... aEvents) {
MutexAutoLock lock(mMutex);
for (int32_t i = mListeners.Length() - 1; i >= 0; --i) {
auto&& l = mListeners[i];
@@ -456,7 +464,7 @@ protected:
mListeners.RemoveElementAt(i);
continue;
}
l->Dispatch(Forward<T>(aEvent));
l->Dispatch(Forward<Ts>(aEvents)...);
}
}
@@ -465,17 +473,25 @@ private:
nsTArray<UniquePtr<Listener>> mListeners;
};
template <typename... Es>
using MediaEventSource =
MediaEventSourceImpl<ListenerMode::NonExclusive, Es...>;
template <typename... Es>
using MediaEventSourceExc =
MediaEventSourceImpl<ListenerMode::Exclusive, Es...>;
/**
* A class to separate the interface of event subject (MediaEventSource)
* and event publisher. Mostly used as a member variable to publish events
* to the listeners.
*/
template <typename EventType, ListenerMode Mode = ListenerMode::NonExclusive>
class MediaEventProducer : public MediaEventSource<EventType, Mode> {
template <typename... Es>
class MediaEventProducer : public MediaEventSource<Es...> {
public:
template <typename T>
void Notify(T&& aEvent) {
this->NotifyInternal(Forward<T>(aEvent));
template <typename... Ts>
void Notify(Ts&&... aEvents) {
this->NotifyInternal(Forward<Ts>(aEvents)...);
}
};
@@ -491,6 +507,18 @@ public:
}
};
/**
* A producer with Exclusive mode.
*/
template <typename... Es>
class MediaEventProducerExc : public MediaEventSourceExc<Es...> {
public:
template <typename... Ts>
void Notify(Ts&&... aEvents) {
this->NotifyInternal(Forward<Ts>(aEvents)...);
}
};
} // namespace mozilla
#endif //MediaEventSource_h_
+51 -8
View File
@@ -454,7 +454,8 @@ MediaFormatReader::RequestVideoData(bool aSkipToNextKeyframe,
media::TimeUnit timeThreshold{media::TimeUnit::FromMicroseconds(aTimeThreshold)};
if (ShouldSkip(aSkipToNextKeyframe, timeThreshold)) {
mVideo.mDecodingRequested = false;
// Cancel any pending demux request.
mVideo.mDemuxRequest.DisconnectIfExists();
Flush(TrackInfo::kVideoTrack);
RefPtr<VideoDataPromise> p = mVideo.mPromise.Ensure(__func__);
SkipVideoDemuxToNextKeyFrame(timeThreshold);
@@ -584,6 +585,7 @@ MediaFormatReader::NotifyNewOutput(TrackType aTrack, MediaData* aSample)
}
decoder.mOutput.AppendElement(aSample);
decoder.mNumSamplesOutput++;
decoder.mNumSamplesOutputTotal++;
ScheduleUpdate(aTrack);
}
@@ -602,6 +604,7 @@ MediaFormatReader::NotifyDrainComplete(TrackType aTrack)
{
MOZ_ASSERT(OnTaskQueue());
auto& decoder = GetDecoderData(aTrack);
LOG("%s", TrackTypeToStr(aTrack));
if (!decoder.mOutputRequested) {
LOG("MediaFormatReader called DrainComplete() before flushing, ignoring.");
return;
@@ -824,19 +827,20 @@ MediaFormatReader::HandleDemuxedSamples(TrackType aTrack,
decoder.mDecoder = nullptr;
if (sample->mKeyframe) {
decoder.mQueuedSamples.AppendElements(Move(samples));
ScheduleUpdate(aTrack);
NotifyDecodingRequested(aTrack);
} else {
MOZ_ASSERT(decoder.mTimeThreshold.isNothing());
LOG("Stream change occurred on a non-keyframe. Seeking to:%lld",
sample->mTime);
decoder.mTimeThreshold = Some(TimeUnit::FromMicroseconds(sample->mTime));
RefPtr<MediaFormatReader> self = this;
decoder.ResetDemuxer();
decoder.mSeekRequest.Begin(decoder.mTrackDemuxer->Seek(decoder.mTimeThreshold.ref())
->Then(OwnerThread(), __func__,
[self, aTrack] (media::TimeUnit aTime) {
auto& decoder = self->GetDecoderData(aTrack);
decoder.mSeekRequest.Complete();
self->ScheduleUpdate(aTrack);
self->NotifyDecodingRequested(aTrack);
},
[self, aTrack] (DemuxerFailureReason aResult) {
auto& decoder = self->GetDecoderData(aTrack);
@@ -919,7 +923,7 @@ MediaFormatReader::Update(TrackType aTrack)
{
MOZ_ASSERT(OnTaskQueue());
if (mShutdown || !mInitDone) {
if (mShutdown) {
return;
}
@@ -951,9 +955,9 @@ MediaFormatReader::Update(TrackType aTrack)
if (aTrack == TrackInfo::kVideoTrack) {
uint64_t delta =
decoder.mNumSamplesOutput - mLastReportedNumDecodedFrames;
decoder.mNumSamplesOutputTotal - mLastReportedNumDecodedFrames;
a.mDecoded = static_cast<uint32_t>(delta);
mLastReportedNumDecodedFrames = decoder.mNumSamplesOutput;
mLastReportedNumDecodedFrames = decoder.mNumSamplesOutputTotal;
}
if (decoder.HasPromise()) {
@@ -1281,11 +1285,14 @@ MediaFormatReader::Seek(int64_t aTime, int64_t aUnused)
return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
}
mPendingSeekTime.emplace(media::TimeUnit::FromMicroseconds(aTime));
mOriginalSeekTime = Some(media::TimeUnit::FromMicroseconds(aTime));
mPendingSeekTime = mOriginalSeekTime;
RefPtr<SeekPromise> p = mSeekPromise.Ensure(__func__);
AttemptSeek();
RefPtr<nsIRunnable> task(
NS_NewRunnableMethod(this, &MediaFormatReader::AttemptSeek));
OwnerThread()->Dispatch(task.forget());
return p;
}
@@ -1294,6 +1301,13 @@ void
MediaFormatReader::AttemptSeek()
{
MOZ_ASSERT(OnTaskQueue());
if (mPendingSeekTime.isNothing()) {
return;
}
// An internal seek may be pending due to Seek queueing multiple tasks calling
// AttemptSeek ; we can ignore those by resetting any pending demuxer's seek.
mAudio.mSeekRequest.DisconnectIfExists();
mVideo.mSeekRequest.DisconnectIfExists();
if (HasVideo()) {
DoVideoSeek();
} else if (HasAudio()) {
@@ -1315,6 +1329,34 @@ MediaFormatReader::OnSeekFailed(TrackType aTrack, DemuxerFailureReason aResult)
}
if (aResult == DemuxerFailureReason::WAITING_FOR_DATA) {
if (HasVideo() && aTrack == TrackType::kAudioTrack &&
mOriginalSeekTime.isSome() &&
mPendingSeekTime.ref() != mOriginalSeekTime.ref()) {
// We have failed to seek audio where video seeked to earlier.
// Attempt to seek instead to the closest point that we know we have in
// order to limit A/V sync discrepency.
// Ensure we have the most up to date buffered ranges.
UpdateReceivedNewData(TrackType::kAudioTrack);
Maybe<media::TimeUnit> nextSeekTime;
// Find closest buffered time found after video seeked time.
for (const auto& timeRange : mAudio.mTimeRanges) {
if (timeRange.mStart >= mPendingSeekTime.ref()) {
nextSeekTime.emplace(timeRange.mStart);
break;
}
}
if (nextSeekTime.isNothing() ||
nextSeekTime.ref() > mOriginalSeekTime.ref()) {
nextSeekTime = mOriginalSeekTime;
LOG("Unable to seek audio to video seek time. A/V sync may be broken");
} else {
mOriginalSeekTime.reset();
}
mPendingSeekTime = nextSeekTime;
DoAudioSeek();
return;
}
NotifyWaitingForData(aTrack);
return;
}
@@ -1343,6 +1385,7 @@ MediaFormatReader::OnVideoSeekCompleted(media::TimeUnit aTime)
if (HasAudio()) {
MOZ_ASSERT(mPendingSeekTime.isSome());
mPendingSeekTime = Some(aTime);
DoAudioSeek();
} else {
mPendingSeekTime.reset();
+5
View File
@@ -208,6 +208,7 @@ private:
, mDrainComplete(false)
, mNumSamplesInput(0)
, mNumSamplesOutput(0)
, mNumSamplesOutputTotal(0)
, mSizeOfQueue(0)
, mIsHardwareAccelerated(false)
, mLastStreamSourceID(UINT32_MAX)
@@ -267,6 +268,7 @@ private:
nsTArray<RefPtr<MediaData>> mOutput;
uint64_t mNumSamplesInput;
uint64_t mNumSamplesOutput;
uint64_t mNumSamplesOutputTotal;
// These get overriden in the templated concrete class.
// Indicate if we have a pending promise for decoded frame.
@@ -290,6 +292,7 @@ private:
mReceivedNewData = false;
mDiscontinuity = true;
mQueuedSamples.Clear();
mDecodingRequested = false;
mOutputRequested = false;
mInputExhausted = false;
mNeedDraining = false;
@@ -299,6 +302,7 @@ private:
mOutput.Clear();
mNumSamplesInput = 0;
mNumSamplesOutput = 0;
mSizeOfQueue = 0;
mNextStreamSourceID.reset();
}
@@ -421,6 +425,7 @@ private:
OnSeekFailed(TrackType::kAudioTrack, aFailure);
}
// Temporary seek information while we wait for the data
Maybe<media::TimeUnit> mOriginalSeekTime;
Maybe<media::TimeUnit> mPendingSeekTime;
MozPromiseHolder<SeekPromise> mSeekPromise;
+2 -4
View File
@@ -19,10 +19,8 @@
namespace mozilla {
class TimedMetadata;
typedef MediaEventProducer<TimedMetadata, ListenerMode::Exclusive>
TimedMetadataEventProducer;
typedef MediaEventSource<TimedMetadata, ListenerMode::Exclusive>
TimedMetadataEventSource;
typedef MediaEventProducerExc<TimedMetadata> TimedMetadataEventProducer;
typedef MediaEventSourceExc<TimedMetadata> TimedMetadataEventSource;
// A struct that contains the metadata of a media, and the time at which those
// metadata should start to be reported.
+4 -1
View File
@@ -80,7 +80,10 @@ VideoFrame::CreateBlackImage(const gfx::IntSize& aSize)
data.mStereoMode = StereoMode::MONO;
// SetData copies data, so we can free data.
planar->SetData(data);
if (!planar->SetData(data)) {
MOZ_ASSERT(false);
return nullptr;
}
return image.forget();
}
+80
View File
@@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 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/. */
#include "XiphExtradata.h"
namespace mozilla {
bool XiphHeadersToExtradata(MediaByteBuffer* aCodecSpecificConfig,
const nsTArray<const unsigned char*>& aHeaders,
const nsTArray<size_t>& aHeaderLens)
{
size_t nheaders = aHeaders.Length();
if (!nheaders || nheaders > 255) return false;
aCodecSpecificConfig->AppendElement(nheaders - 1);
for (size_t i = 0; i < nheaders - 1; i++) {
size_t headerLen;
for (headerLen = aHeaderLens[i]; headerLen >= 255; headerLen -= 255) {
aCodecSpecificConfig->AppendElement(255);
}
aCodecSpecificConfig->AppendElement(headerLen);
}
for (size_t i = 0; i < nheaders; i++) {
aCodecSpecificConfig->AppendElements(aHeaders[i], aHeaderLens[i]);
}
return true;
}
bool XiphExtradataToHeaders(nsTArray<unsigned char*>& aHeaders,
nsTArray<size_t>& aHeaderLens,
unsigned char* aData,
size_t aAvailable)
{
size_t total = 0;
if (aAvailable < 1) {
return false;
}
aAvailable--;
int nHeaders = *aData++ + 1;
for (int i = 0; i < nHeaders - 1; i++) {
size_t headerLen = 0;
for (;;) {
// After this test, we know that (aAvailable - total > headerLen) and
// (headerLen >= 0) so (aAvailable - total > 0). The loop decrements
// aAvailable by 1 and total remains fixed, so we know that in the next
// iteration (aAvailable - total >= 0). Thus (aAvailable - total) can
// never underflow.
if (aAvailable - total <= headerLen) {
return false;
}
// Since we know (aAvailable > total + headerLen), this can't overflow
// unless total is near 0 and both aAvailable and headerLen are within
// 255 bytes of the maximum representable size. However, that is
// impossible, since we would have had to have gone through this loop
// more than 255 times to make headerLen that large, and thus decremented
// aAvailable more than 255 times.
headerLen += *aData;
aAvailable--;
if (*aData++ != 255) break;
}
// And this check ensures updating total won't cause (aAvailable - total)
// to underflow.
if (aAvailable - total < headerLen) {
return false;
}
aHeaderLens.AppendElement(headerLen);
// Since we know aAvailable >= total + headerLen, this can't overflow.
total += headerLen;
}
aHeaderLens.AppendElement(aAvailable - total);
for (int i = 0; i < nHeaders; i++) {
aHeaders.AppendElement(aData);
aData += aHeaderLens[i];
}
return true;
}
} // namespace mozilla
+28
View File
@@ -0,0 +1,28 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 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/. */
#if !defined(XiphExtradata_h)
#define XiphExtradata_h
#include "MediaData.h"
namespace mozilla {
/* This converts a list of headers to the canonical form of extradata for Xiph
codecs in non-Ogg containers. We use it to pass those headers from demuxer
to decoder even when demuxing from an Ogg cotainer. */
bool XiphHeadersToExtradata(MediaByteBuffer* aCodecSpecificConfig,
const nsTArray<const unsigned char*>& aHeaders,
const nsTArray<size_t>& aHeaderLens);
/* This converts a set of extradata back into a list of headers. */
bool XiphExtradataToHeaders(nsTArray<unsigned char*>& aHeaders,
nsTArray<size_t>& aHeaderLens,
unsigned char* aData,
size_t aAvailable);
} // namespace mozilla
#endif // XiphExtradata_h
+160 -71
View File
@@ -4,14 +4,16 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "VP8TrackEncoder.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#include "GeckoProfiler.h"
#include "LayersLogging.h"
#include "libyuv.h"
#include "mozilla/gfx/2D.h"
#include "prsystem.h"
#include "VideoSegment.h"
#include "VideoUtils.h"
#include "prsystem.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#include "WebMWriter.h"
#include "libyuv.h"
#include "GeckoProfiler.h"
namespace mozilla {
@@ -23,6 +25,7 @@ PRLogModuleInfo* gVP8TrackEncoderLog;
#define DEFAULT_BITRATE_BPS 2500000
#define DEFAULT_ENCODE_FRAMERATE 30
using namespace mozilla::gfx;
using namespace mozilla::layers;
VP8TrackEncoder::VP8TrackEncoder()
@@ -259,91 +262,177 @@ nsresult VP8TrackEncoder::PrepareRawFrame(VideoChunk &aChunk)
img = aChunk.mFrame.GetImage();
}
if (img->GetSize() != IntSize(mFrameWidth, mFrameHeight)) {
VP8LOG("Dynamic resolution changes (was %dx%d, now %dx%d) are unsupported\n",
mFrameWidth, mFrameHeight, img->GetSize().width, img->GetSize().height);
return NS_ERROR_FAILURE;
}
ImageFormat format = img->GetFormat();
if (format != ImageFormat::PLANAR_YCBCR) {
VP8LOG("Unsupported video format\n");
return NS_ERROR_FAILURE;
}
if (format == ImageFormat::PLANAR_YCBCR) {
PlanarYCbCrImage* yuv = static_cast<PlanarYCbCrImage *>(img.get());
// Cast away constness b/c some of the accessors are non-const
PlanarYCbCrImage* yuv =
const_cast<PlanarYCbCrImage *>(static_cast<const PlanarYCbCrImage *>(img.get()));
// Big-time assumption here that this is all contiguous data coming
// from getUserMedia or other sources.
MOZ_ASSERT(yuv);
if (!yuv->IsValid()) {
NS_WARNING("PlanarYCbCrImage is not valid");
return NS_ERROR_FAILURE;
}
const PlanarYCbCrImage::Data *data = yuv->GetData();
if (isYUV420(data) && !data->mCbSkip) { // 420 planar
mVPXImageWrapper->planes[VPX_PLANE_Y] = data->mYChannel;
mVPXImageWrapper->planes[VPX_PLANE_U] = data->mCbChannel;
mVPXImageWrapper->planes[VPX_PLANE_V] = data->mCrChannel;
mVPXImageWrapper->stride[VPX_PLANE_Y] = data->mYStride;
mVPXImageWrapper->stride[VPX_PLANE_U] = data->mCbCrStride;
mVPXImageWrapper->stride[VPX_PLANE_V] = data->mCbCrStride;
} else {
uint32_t yPlaneSize = mFrameWidth * mFrameHeight;
uint32_t halfWidth = (mFrameWidth + 1) / 2;
uint32_t halfHeight = (mFrameHeight + 1) / 2;
uint32_t uvPlaneSize = halfWidth * halfHeight;
if (mI420Frame.IsEmpty()) {
mI420Frame.SetLength(yPlaneSize + uvPlaneSize * 2);
MOZ_ASSERT(yuv);
if (!yuv->IsValid()) {
NS_WARNING("PlanarYCbCrImage is not valid");
return NS_ERROR_FAILURE;
}
const PlanarYCbCrImage::Data *data = yuv->GetData();
MOZ_ASSERT(mI420Frame.Length() >= (yPlaneSize + uvPlaneSize * 2));
uint8_t *y = mI420Frame.Elements();
uint8_t *cb = mI420Frame.Elements() + yPlaneSize;
uint8_t *cr = mI420Frame.Elements() + yPlaneSize + uvPlaneSize;
if (isYUV420(data) && !data->mCbSkip) {
// 420 planar, no need for conversions
mVPXImageWrapper->planes[VPX_PLANE_Y] = data->mYChannel;
mVPXImageWrapper->planes[VPX_PLANE_U] = data->mCbChannel;
mVPXImageWrapper->planes[VPX_PLANE_V] = data->mCrChannel;
mVPXImageWrapper->stride[VPX_PLANE_Y] = data->mYStride;
mVPXImageWrapper->stride[VPX_PLANE_U] = data->mCbCrStride;
mVPXImageWrapper->stride[VPX_PLANE_V] = data->mCbCrStride;
return NS_OK;
}
}
// Not 420 planar, have to convert
uint32_t yPlaneSize = mFrameWidth * mFrameHeight;
uint32_t halfWidth = (mFrameWidth + 1) / 2;
uint32_t halfHeight = (mFrameHeight + 1) / 2;
uint32_t uvPlaneSize = halfWidth * halfHeight;
if (mI420Frame.IsEmpty()) {
mI420Frame.SetLength(yPlaneSize + uvPlaneSize * 2);
}
uint8_t *y = mI420Frame.Elements();
uint8_t *cb = mI420Frame.Elements() + yPlaneSize;
uint8_t *cr = mI420Frame.Elements() + yPlaneSize + uvPlaneSize;
if (format == ImageFormat::PLANAR_YCBCR) {
PlanarYCbCrImage* yuv = static_cast<PlanarYCbCrImage *>(img.get());
MOZ_ASSERT(yuv);
if (!yuv->IsValid()) {
NS_WARNING("PlanarYCbCrImage is not valid");
return NS_ERROR_FAILURE;
}
const PlanarYCbCrImage::Data *data = yuv->GetData();
int rv;
std::string yuvFormat;
if (isYUV420(data) && data->mCbSkip) {
// If mCbSkip is set, we assume it's nv12 or nv21.
if (data->mCbChannel < data->mCrChannel) { // nv12
libyuv::NV12ToI420(data->mYChannel, data->mYStride,
data->mCbChannel, data->mCbCrStride,
y, mFrameWidth,
cb, halfWidth,
cr, halfWidth,
mFrameWidth, mFrameHeight);
rv = libyuv::NV12ToI420(data->mYChannel, data->mYStride,
data->mCbChannel, data->mCbCrStride,
y, mFrameWidth,
cb, halfWidth,
cr, halfWidth,
mFrameWidth, mFrameHeight);
yuvFormat = "NV12";
} else { // nv21
libyuv::NV21ToI420(data->mYChannel, data->mYStride,
data->mCrChannel, data->mCbCrStride,
y, mFrameWidth,
cb, halfWidth,
cr, halfWidth,
mFrameWidth, mFrameHeight);
rv = libyuv::NV21ToI420(data->mYChannel, data->mYStride,
data->mCrChannel, data->mCbCrStride,
y, mFrameWidth,
cb, halfWidth,
cr, halfWidth,
mFrameWidth, mFrameHeight);
yuvFormat = "NV21";
}
} else if (isYUV444(data) && !data->mCbSkip) {
libyuv::I444ToI420(data->mYChannel, data->mYStride,
data->mCbChannel, data->mCbCrStride,
data->mCrChannel, data->mCbCrStride,
y, mFrameWidth,
cb, halfWidth,
cr, halfWidth,
mFrameWidth, mFrameHeight);
rv = libyuv::I444ToI420(data->mYChannel, data->mYStride,
data->mCbChannel, data->mCbCrStride,
data->mCrChannel, data->mCbCrStride,
y, mFrameWidth,
cb, halfWidth,
cr, halfWidth,
mFrameWidth, mFrameHeight);
yuvFormat = "I444";
} else if (isYUV422(data) && !data->mCbSkip) {
libyuv::I422ToI420(data->mYChannel, data->mYStride,
data->mCbChannel, data->mCbCrStride,
data->mCrChannel, data->mCbCrStride,
y, mFrameWidth,
cb, halfWidth,
cr, halfWidth,
mFrameWidth, mFrameHeight);
rv = libyuv::I422ToI420(data->mYChannel, data->mYStride,
data->mCbChannel, data->mCbCrStride,
data->mCrChannel, data->mCbCrStride,
y, mFrameWidth,
cb, halfWidth,
cr, halfWidth,
mFrameWidth, mFrameHeight);
yuvFormat = "I422";
} else {
VP8LOG("Unsupported planar format\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
mVPXImageWrapper->planes[VPX_PLANE_Y] = y;
mVPXImageWrapper->planes[VPX_PLANE_U] = cb;
mVPXImageWrapper->planes[VPX_PLANE_V] = cr;
mVPXImageWrapper->stride[VPX_PLANE_Y] = mFrameWidth;
mVPXImageWrapper->stride[VPX_PLANE_U] = halfWidth;
mVPXImageWrapper->stride[VPX_PLANE_V] = halfWidth;
if (rv != 0) {
VP8LOG("Converting an %s frame to I420 failed\n", yuvFormat.c_str());
return NS_ERROR_FAILURE;
}
VP8LOG("Converted an %s frame to I420\n");
} else {
// Not YCbCr at all. Try to get access to the raw data and convert.
RefPtr<SourceSurface> surf = img->GetAsSourceSurface();
if (!surf) {
VP8LOG("Getting surface from %s image failed\n", Stringify(format).c_str());
return NS_ERROR_FAILURE;
}
RefPtr<DataSourceSurface> data = surf->GetDataSurface();
if (!data) {
VP8LOG("Getting data surface from %s image with %s (%s) surface failed\n",
Stringify(format).c_str(), Stringify(surf->GetType()).c_str(),
Stringify(surf->GetFormat()).c_str());
return NS_ERROR_FAILURE;
}
DataSourceSurface::ScopedMap map(data, DataSourceSurface::READ);
if (!map.IsMapped()) {
VP8LOG("Reading DataSourceSurface from %s image with %s (%s) surface failed\n",
Stringify(format).c_str(), Stringify(surf->GetType()).c_str(),
Stringify(surf->GetFormat()).c_str());
return NS_ERROR_FAILURE;
}
int rv;
switch (surf->GetFormat()) {
case SurfaceFormat::B8G8R8A8:
case SurfaceFormat::B8G8R8X8:
rv = libyuv::ARGBToI420(static_cast<uint8*>(map.GetData()),
map.GetStride(),
y, mFrameWidth,
cb, halfWidth,
cr, halfWidth,
mFrameWidth, mFrameHeight);
break;
case SurfaceFormat::R5G6B5_UINT16:
rv = libyuv::RGB565ToI420(static_cast<uint8*>(map.GetData()),
map.GetStride(),
y, mFrameWidth,
cb, halfWidth,
cr, halfWidth,
mFrameWidth, mFrameHeight);
break;
default:
VP8LOG("Unsupported SourceSurface format %s\n",
Stringify(surf->GetFormat()).c_str());
return NS_ERROR_NOT_IMPLEMENTED;
}
if (rv != 0) {
VP8LOG("%s to I420 conversion failed\n",
Stringify(surf->GetFormat()).c_str());
return NS_ERROR_FAILURE;
}
VP8LOG("Converted a %s frame to I420\n",
Stringify(surf->GetFormat()).c_str());
}
mVPXImageWrapper->planes[VPX_PLANE_Y] = y;
mVPXImageWrapper->planes[VPX_PLANE_U] = cb;
mVPXImageWrapper->planes[VPX_PLANE_V] = cr;
mVPXImageWrapper->stride[VPX_PLANE_Y] = mFrameWidth;
mVPXImageWrapper->stride[VPX_PLANE_U] = halfWidth;
mVPXImageWrapper->stride[VPX_PLANE_V] = halfWidth;
return NS_OK;
}
+1 -1
View File
@@ -71,7 +71,7 @@ private:
// Muted frame, we only create it once.
RefPtr<layers::Image> mMuteFrame;
// I420 frame, convert the 4:4:4, 4:2:2 to I420.
// I420 frame, for converting to I420.
nsTArray<uint8_t> mI420Frame;
/**
+1 -1
View File
@@ -304,7 +304,7 @@ TEST(MediaEventSource, MoveOnly)
RefPtr<TaskQueue> queue = new TaskQueue(
GetMediaThreadPool(MediaThreadType::PLAYBACK));
MediaEventProducer<UniquePtr<int>, ListenerMode::Exclusive> source;
MediaEventProducerExc<UniquePtr<int>> source;
auto func = [] (UniquePtr<int>&& aEvent) {
EXPECT_EQ(*aEvent, 20);
+6 -3
View File
@@ -55,8 +55,9 @@ public:
private:
Image *CreateI420Image()
{
PlanarYCbCrImage *image = new PlanarYCbCrImage(new BufferRecycleBin());
PlanarYCbCrImage *image = new RecyclingPlanarYCbCrImage(new BufferRecycleBin());
PlanarYCbCrData data;
data.mPicSize = mImageSize;
const uint32_t yPlaneSize = mImageSize.width * mImageSize.height;
const uint32_t halfWidth = (mImageSize.width + 1) / 2;
@@ -92,8 +93,9 @@ private:
Image *CreateNV12Image()
{
PlanarYCbCrImage *image = new PlanarYCbCrImage(new BufferRecycleBin());
PlanarYCbCrImage *image = new RecyclingPlanarYCbCrImage(new BufferRecycleBin());
PlanarYCbCrData data;
data.mPicSize = mImageSize;
const uint32_t yPlaneSize = mImageSize.width * mImageSize.height;
const uint32_t halfWidth = (mImageSize.width + 1) / 2;
@@ -128,8 +130,9 @@ private:
Image *CreateNV21Image()
{
PlanarYCbCrImage *image = new PlanarYCbCrImage(new BufferRecycleBin());
PlanarYCbCrImage *image = new RecyclingPlanarYCbCrImage(new BufferRecycleBin());
PlanarYCbCrData data;
data.mPicSize = mImageSize;
const uint32_t yPlaneSize = mImageSize.width * mImageSize.height;
const uint32_t halfWidth = (mImageSize.width + 1) / 2;
@@ -64,7 +64,7 @@ SourceBufferResource::ReadInternal(char* aBuffer, uint32_t aCount, uint32_t* aBy
uint32_t available = GetLength() - readOffset;
uint32_t count = std::min(aCount, available);
SBR_DEBUGV("readOffset=%llu GetLength()=%u available=%u count=%u mEnded=%d",
this, readOffset, GetLength(), available, count, mEnded);
readOffset, GetLength(), available, count, mEnded);
if (available == 0) {
SBR_DEBUGV("reached EOF");
*aBytes = 0;
+39 -14
View File
@@ -74,7 +74,7 @@ TrackBuffersManager::TrackBuffersManager(dom::SourceBufferAttributes* aAttribute
, mAppendState(AppendState::WAITING_FOR_SEGMENT)
, mBufferFull(false)
, mFirstInitializationSegmentReceived(false)
, mNewSegmentStarted(false)
, mNewMediaSegmentStarted(false)
, mActiveTrack(false)
, mType(aType)
, mParser(ContainerParser::CreateForMIMEType(aType))
@@ -585,12 +585,11 @@ TrackBuffersManager::SegmentParserLoop()
// This is a new initialization segment. Obsolete the old one.
RecreateParser(false);
}
mNewSegmentStarted = true;
continue;
}
if (mParser->IsMediaSegmentPresent(mInputBuffer)) {
SetAppendState(AppendState::PARSING_MEDIA_SEGMENT);
mNewSegmentStarted = true;
mNewMediaSegmentStarted = true;
continue;
}
// We have neither an init segment nor a media segment, this is either
@@ -621,27 +620,43 @@ TrackBuffersManager::SegmentParserLoop()
RejectAppend(NS_ERROR_FAILURE, __func__);
return;
}
// 2. If the input buffer does not contain a complete media segment header yet, then jump to the need more data step below.
if (mParser->MediaHeaderRange().IsNull()) {
AppendDataToCurrentInputBuffer(mInputBuffer);
mInputBuffer = nullptr;
NeedMoreData();
return;
}
// We can't feed some demuxers (WebMDemuxer) with data that do not have
// monotonizally increasing timestamps. So we check if we have a
// discontinuity from the previous segment parsed.
// If so, recreate a new demuxer to ensure that the demuxer is only fed
// monotonically increasing data.
if (newData) {
if (mNewSegmentStarted && mLastParsedEndTime.isSome() &&
if (mNewMediaSegmentStarted) {
if (newData && mLastParsedEndTime.isSome() &&
start < mLastParsedEndTime.ref().ToMicroseconds()) {
MSE_DEBUG("Re-creating demuxer");
ResetDemuxingState();
return;
}
mNewSegmentStarted = false;
mLastParsedEndTime = Some(TimeUnit::FromMicroseconds(end));
if (newData || !mParser->MediaSegmentRange().IsNull()) {
if (mPendingInputBuffer) {
// We now have a complete media segment header. We can resume parsing
// the data.
AppendDataToCurrentInputBuffer(mPendingInputBuffer);
mPendingInputBuffer = nullptr;
}
mNewMediaSegmentStarted = false;
if (newData) {
mLastParsedEndTime = Some(TimeUnit::FromMicroseconds(end));
}
} else {
// We don't have any data to demux yet, stash aside the data.
// This also handles the case:
// 2. If the input buffer does not contain a complete media segment header yet, then jump to the need more data step below.
if (!mPendingInputBuffer) {
mPendingInputBuffer = mInputBuffer;
} else {
mPendingInputBuffer->AppendElements(*mInputBuffer);
}
mInputBuffer = nullptr;
NeedMoreData();
return;
}
}
// 3. If the input buffer contains one or more complete coded frames, then run the coded frame processing algorithm.
@@ -781,6 +796,16 @@ TrackBuffersManager::OnDemuxerResetDone(nsresult)
MOZ_ASSERT(mAudioTracks.mDemuxer);
}
if (mPendingInputBuffer) {
// We had a partial media segment header stashed aside.
// Reparse its content so we can continue parsing the current input buffer.
int64_t start, end;
mParser->ParseStartAndEndTimestamps(mPendingInputBuffer, start, end);
mProcessedInput += mPendingInputBuffer->Length();
}
mLastParsedEndTime.reset();
SegmentParserLoop();
}
+9 -4
View File
@@ -82,14 +82,14 @@ public:
MediaInfo GetMetadata();
const TrackBuffer& GetTrackBuffer(TrackInfo::TrackType aTrack);
const media::TimeIntervals& Buffered(TrackInfo::TrackType);
media:: TimeIntervals SafeBuffered(TrackInfo::TrackType) const;
media::TimeIntervals SafeBuffered(TrackInfo::TrackType) const;
bool IsEnded() const
{
return mEnded;
}
media::TimeUnit Seek(TrackInfo::TrackType aTrack,
const media::TimeUnit& aTime,
const media::TimeUnit& aFuzz);
const media::TimeUnit& aTime,
const media::TimeUnit& aFuzz);
uint32_t SkipToNextRandomAccessPoint(TrackInfo::TrackType aTrack,
const media::TimeUnit& aTimeThreadshold,
bool& aFound);
@@ -150,7 +150,7 @@ private:
Atomic<bool> mBufferFull;
bool mFirstInitializationSegmentReceived;
// Set to true once a new segment is started.
bool mNewSegmentStarted;
bool mNewMediaSegmentStarted;
bool mActiveTrack;
Maybe<media::TimeUnit> mGroupStartTimestamp;
media::TimeUnit mGroupEndTimestamp;
@@ -167,6 +167,11 @@ private:
// Demuxer objects and methods.
void AppendDataToCurrentInputBuffer(MediaByteBuffer* aData);
RefPtr<MediaByteBuffer> mInitData;
// Temporary input buffer to handle partial media segment header.
// We store the current input buffer content into it should we need to
// reinitialize the demuxer once we have some samples and a discontinuity is
// detected.
RefPtr<MediaByteBuffer> mPendingInputBuffer;
RefPtr<SourceBufferResource> mCurrentInputBuffer;
RefPtr<MediaDataDemuxer> mInputDemuxer;
// Length already processed in current media segment.
+2
View File
@@ -149,6 +149,7 @@ EXPORTS += [
'VideoSegment.h',
'VideoUtils.h',
'VorbisUtils.h',
'XiphExtradata.h',
]
EXPORTS.mozilla += [
@@ -246,6 +247,7 @@ UNIFIED_SOURCES += [
'VideoTrackList.cpp',
'VideoUtils.cpp',
'WebVTTListener.cpp',
'XiphExtradata.cpp',
]
if CONFIG['OS_TARGET'] == 'WINNT':
+18 -9
View File
@@ -241,10 +241,15 @@ PDMFactory::CreatePDMs()
{
RefPtr<PlatformDecoderModule> m;
if (sGMPDecoderEnabled) {
m = new GMPDecoderModule();
if (sUseBlankDecoder) {
m = CreateBlankDecoderModule();
StartupPDM(m);
// The Blank PDM SupportsMimeType reports true for all codecs; the creation
// of its decoder is infallible. As such it will be used for all media, we
// can stop creating more PDM from this point.
return;
}
#ifdef MOZ_WIDGET_ANDROID
if(sAndroidMCDecoderPreferred && sAndroidMCDecoderEnabled) {
m = new AndroidDecoderModule();
@@ -252,12 +257,16 @@ PDMFactory::CreatePDMs()
}
#endif
#ifdef XP_WIN
m = new WMFDecoderModule();
StartupPDM(m);
if (sWMFDecoderEnabled) {
m = new WMFDecoderModule();
StartupPDM(m);
}
#endif
#ifdef MOZ_FFMPEG
m = FFmpegRuntimeLinker::CreateDecoderModule();
StartupPDM(m);
if (sFFmpegDecoderEnabled) {
m = FFmpegRuntimeLinker::CreateDecoderModule();
StartupPDM(m);
}
#endif
#ifdef MOZ_APPLEMEDIA
m = new AppleDecoderModule();
@@ -279,10 +288,10 @@ PDMFactory::CreatePDMs()
m = new AgnosticDecoderModule();
StartupPDM(m);
if (sUseBlankDecoder) {
m = CreateBlankDecoderModule();
if (sGMPDecoderEnabled) {
m = new GMPDecoderModule();
StartupPDM(m);
}
}
}
bool
+2 -1
View File
@@ -185,7 +185,6 @@ public:
// The MediaFormatReader will not call Input() while it's calling Flush().
virtual nsresult Flush() = 0;
// Causes all complete samples in the pipeline that can be decoded to be
// output. If the decoder can't produce samples from the current output,
// it drops the input samples. The decoder may be holding onto samples
@@ -215,6 +214,8 @@ public:
// that the format of the next input sample is about to change.
// If video decoder, aConfig will be a VideoInfo object.
// If audio decoder, aConfig will be a AudioInfo object.
// It is not safe to store a reference to this object and the decoder must
// make a copy.
virtual nsresult ConfigurationChanged(const TrackInfo& aConfig)
{
return NS_OK;
+10 -15
View File
@@ -6,6 +6,7 @@
#include "VorbisDecoder.h"
#include "VorbisUtils.h"
#include "XiphExtradata.h"
#include "mozilla/PodOperations.h"
#include "nsAutoPtr.h"
@@ -70,23 +71,17 @@ VorbisDataDecoder::Init()
PodZero(&mVorbisDsp);
PodZero(&mVorbisBlock);
size_t available = mInfo.mCodecSpecificConfig->Length();
uint8_t *p = mInfo.mCodecSpecificConfig->Elements();
for(int i = 0; i < 3; i++) {
if (available < 2) {
nsAutoTArray<unsigned char*,4> headers;
nsAutoTArray<size_t,4> headerLens;
if (!XiphExtradataToHeaders(headers, headerLens,
mInfo.mCodecSpecificConfig->Elements(),
mInfo.mCodecSpecificConfig->Length())) {
return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
}
for (size_t i = 0; i < headers.Length(); i++) {
if (NS_FAILED(DecodeHeader(headers[i], headerLens[i]))) {
return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
}
available -= 2;
size_t length = BigEndian::readUint16(p);
p += 2;
if (available < length) {
return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
}
available -= length;
if (NS_FAILED(DecodeHeader((const unsigned char*)p, length))) {
return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
}
p += length;
}
MOZ_ASSERT(mPacketCount == 3);
@@ -10,7 +10,6 @@
#include "PlatformDecoderModule.h"
#include "FFmpegAudioDecoder.h"
#include "FFmpegH264Decoder.h"
#include "FFmpegRuntimeLinker.h"
namespace mozilla
{

Some files were not shown because too many files have changed in this diff Show More