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

- Bug 1199885 - Part 2: Add AsyncDragMetrics. r=kats (220a4f445e)
- Bug 1149482 - Localize the 'none' string for APZ in about:support. r=dvander (3e0128f62e)
- Bug 1199885 - Part 3: Add 'apz.drag.enabled' preference for async scrollbars. r=kats (5133061d3f)
- Bug 1199885 - Part 4: Let the hit testing tree know about the scroll thumb. r=kats (26a9a69443)
- Bug 1199885 - Part 5: Make mRootLayerTreeID const to prove that there's no data races. r=kats (88e2eb80f1)
- Bug 1199885 - Part 8: Add FindScrollNode to locate the scrollbar thumb. r=kats (a545ec9569)
- Bug 1199885 - Part 9: Let APZC handle the drag events. r=kats (4cc0f88153)
- Bug 1199885 - Part 9.5: Make the mouse events APZC aware. r=kats (69bd4caf94)
- Bug 1199885 - Part 10: Add APZTeeManager API to start an async scroll. r=kats (e212ee2750)
- Bug 1199885 - Part 12: Add StartScrollbarDrag IPC message. r=kats (705af3b233)
- Bug 1199885 - Part 13: Let nsSliderFrame trigger async scrolling via StartScrollbarDrag. r=kats (d31b5a790d)
- put in gstreamer as of 2015-10-05 Bug 1146482 (7cca45858c)
- pointer style (f8041af438)
- Bug 1197097 - Don't use a context-wide cycle-detection mechanism for detecting cycles during JSON.stringify. This prevents nested (yet separate) JSON.stringify, and it causes that algorithm to be affected by specification-unrelated operations like toSource. r=jonco (09652471c1)
- align to ugly grammaer of 1114782 (c760693693)
- remove space (7158a0c2bf)
- align to FF/TFF (27138a55bb)
- Bug 1205887 - Verify that MOZILLA_VERSION was set correctly, r=glandium (2269e8f31b)
- Bug 1205012 - Allow rust source code in SpiderMonkey; r=mshal (9ebca9ed28)
- Bug 1197281 - Use MOZ_FIND_WINSDK_VERSION for MOZ_WINSDK_MAXVER on mingw. r=glandium (2910b2160e)
- Bug 1207893 - Refactor how build backend execution is summarized. r=gps (56d8fecbc2)
- Bug 1207893 - Allow to create multiple build backends at once. r=gps (d8cba87d2b)
- Bug 1207897 - Add a configure option to build multiple build backends. r=gps (f9c7851d02)
- Bug 1188555 - part 1 - remove write-only configure.in variable NO_LD_ARCHIVE_FLAGS; r=mshal (461958b100)
- Bug 1188555 - part 2 - remove write-only configure.in variables MKSHLIB_{UN,}FORCE_ALL; r=mshal (1813210dda)
- Bug 1207882 - Ensure chrome manifests are created in a directory that exists when processing jar manifests. r=gps (59165a64cb)
- Bug 1204712 - Handle wildcards properly for localized content in jar manifests. r=gps (54dfb632c7)
- Bug 1188551: treat assertion failures as bad mozconfig; r=mshal (e307769de7)
- Bug 1181040 - Set ${var}_IS_SET variables for mk_add_options-defined variables. r=gps (19f169556b)
- Bug 1193015 - Require MOZ_GLX_USE_SURFACE_SHARING to enable WebGL surface sharing on GLX. r=jgilbert (9aa4fa8f41)
- Bug 1211324 (part 1) - Remove BILINEAR and GAUSSIAN filter constants. (3d9290ef02)
- Bug 1211324 (part 2) - Make gfx::FILTER::GOOD convert to GraphicsFilter::FILTER_GOOD. r=mattwoodrow. (16e7607c70)
- Bug 1208365 (part 1) - Remove unused EXTEND_PAD_EDGE. r=Bas. (10920e2bb6)
- Bug 1208365 (part 2) - Remove gfxPattern::Extend(). r=bas. (3703b9748a)
- Bug 1208365 (part 3) - Change gfxPattern::mExtend from a GraphicsExtend to a gfx::ExtendMode. r=bas. (b105d06e91)
- Bug 1208365 (part 4) - Remove gfxPattern::GraphicsExtend. r=bas. (7a16d48995)
- Bug 1211324 (part 3) - Remove GraphicsFilter::FILTER_FAST and replace it with FILTER_BEST. r=mattwoodrow. (b5101e049f)
- Bug 1211324 (part 4) - Replace GraphicsFilter constants with gfx::Filter equivalents. r=mattwoodrow. (c19b6b030e)
- Bug 1190117 - Track mLastProducerID and mLastFrameID explicitly in ImageLayerProperties. r=roc (ed9a5c777f)
- Bug 1211324 (part 5) - Remove GraphicsFilter and gfxGraphicsFilter. r=mattwoodrow. (0bd4ce7160)
- Bug 1194954 - Fix -Wunreachable-code warnings in gfx/layers and gfx/thebes. r=BenWa (1a3d68c490)
- Bug 1180509 - Fix judder of icons in Australis doorhanger menu at the end of its scale-in animation. r=roc (9b4df470fa)
- Bug 1206915 - Make paint dumping to a file e10s-friendly. r=mattwoodrow (87d2e12c2b)
- Bug 1206915 - Handle nested PaintFrame() calls correctly during paint dumping. r=mattwoodrow,BenWa (d30f77fbdd)
- Fix max texture size handling in displayport clamping. (bug 1135907 follow-up, r=kats) (a791894332)
- Fix bogus assertion in nsLayoutUtils::SetDisplayPortMargins. (bug 1156409, r=botond, a=philor) (b635b21c34)
- Bug 1169879 - Use only the critical displayport when computing image visibility. r=tn (9ec91c9527)
- Bug 1169881 - Recompute image visibility when display port margins change. r=tn (35a5bd3a51)
- Bug 1197765 - Compare text content inside frame instead of the content node for ruby autohiding. r=dbaron (00cf5b7674)
- Bug 1173580 - Record content descriptions in APZ test data. r=kats (7a72d1ac0a)
- Bug 1178971 - Changed line snapping behaviour depending on even/odd-ness of stroke width. r=mstange (495b32dc23)
- Bug 1208953: [mp3] Don't parse data we've already parsed. r=cpearce (72eed4309f)
- Bug 1137151: Marked destructor of |android::MediaCodecReader| as protected, r=sotaro (0632b34bc5)
- Bug 1205351 - Replace nsBaseHashtable::Enumerate() calls in dom/media/ with iterators r=cpearce (45976c24c0)
- Bug 1133624 - Add lang-specific ruby rules to ua.css. r=dbaron (46788cc220)
- Bug 1133624 - followup add fuzzy maxdiff on CLOSED TREE (1b6b62aded)
- Bug 1180443 - Consider whitespace collapse when calculating intrinsic isize of ruby. r=dbaron (3862184acd)
- Bug 1153764 - Avoid explicitly doing break before when there is ruby span. r=roc (71b4ec7749)
- add gstreamer parts (7e562556be)
- some preferences aligned to FF (b26d0b389c)
- Bug 1166301 - If APZ is enabled, clip fixed background images at the layer level rather than the display item level. r=mattwoodrow (5644e22090)
- Bug 1144990 - Dump display items with class id and name, r=roc (aa2e227e35)
- Bug 1205087 - Remove LayerManager parameter for ShouldFixToViewport. r=roc (00a1f2e36f)
- Bug 1205087 - Make nsSVGIntegrationUtils paint frame continuations manually since combining them meant that our reference frame wasn't an ancestor of all painted frames. r=roc (e40f6b7b81)
- Bug 1195400 - Check ancestor geometry roots when determining scrollability of a layer. r=mattwoodrow (4699b7e935)
- Bug 1205087 - Cache the AnimatedGeometryRoot on DisplayItem. r=roc (06bba311c3)
- Back out the bits of bug 1205087 that cache the AnimatedGeometryRoot on DisplayItem. r=backout (254057a6b6)
- Bug 1203190 - Don't intersect with the visible rect for fixed background images. r=mattwoodrow (1c5a432459)
- Bug 1208438 - Don't allow layers with scrolling clips to occlusion-cull layers behind them. r=mattwoodrow (c3d77a9846)
- Bug 1205630 - Translate a fixed background display item's clip rect correctly when setting it on the layer. r=mstange (49039f0e2d)
- Bug 1205630 - Reftest. r=mstange (a8db59eaee)
- Bug 1105832 - Also dump inactive layer managers when display list dumping is enabled. r=mattwoodrow (564fe5fcbc)
- Bug 1208661 - Move Dump() up from ContentClient to CompositableClient. r=BenWa (37915312b3)
This commit is contained in:
2022-09-22 10:16:52 +08:00
parent 0484be0c56
commit e1776c67f8
196 changed files with 5677 additions and 1164 deletions
Vendored
+1
View File
@@ -33,6 +33,7 @@ builtin(include, build/autoconf/ffi.m4)dnl
builtin(include, build/autoconf/clang-plugin.m4)dnl
builtin(include, build/autoconf/alloc.m4)dnl
builtin(include, build/autoconf/jemalloc.m4)dnl
builtin(include, build/autoconf/rust.m4)dnl
MOZ_PROG_CHECKMSYS()
+12
View File
@@ -222,3 +222,15 @@ MOZ_RUN_CONFIG_STATUS()],
define([AC_CONFIG_HEADER],
[m4_fatal([Use CONFIGURE_DEFINE_FILES in moz.build files to produce header files.])
])
define([MOZ_BUILD_BACKEND],
[
BUILD_BACKENDS="RecursiveMake"
MOZ_ARG_ENABLE_STRING(build-backend,
[ --enable-build-backend={AndroidEclipse,CppEclipse,VisualStudio,FasterMake}
Enable additional build backends],
[ BUILD_BACKENDS="RecursiveMake `echo $enableval | sed 's/,/ /g'`"])
AC_SUBST_LIST([BUILD_BACKENDS])
])
+35
View File
@@ -0,0 +1,35 @@
dnl This Source Code Form is subject to the terms of the Mozilla Public
dnl License, v. 2.0. If a copy of the MPL was not distributed with this
dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
AC_DEFUN([MOZ_RUST_SUPPORT], [
MOZ_PATH_PROG(RUSTC, rustc)
if test -n "$RUSTC"; then
AC_MSG_CHECKING([rustc version])
RUSTC_VERSION=`$RUSTC --version | cut -d ' ' -f 2`
# Parse out semversion elements.
_RUSTC_MAJOR_VERSION=`echo ${RUSTC_VERSION} | cut -d . -f 1`
_RUSTC_MINOR_VERSION=`echo ${RUSTC_VERSION} | cut -d . -f 2`
_RUSTC_EXTRA_VERSION=`echo ${RUSTC_VERSION} | cut -d . -f 3 | cut -d + -f 1`
_RUSTC_PATCH_VERSION=`echo ${_RUSTC_EXTRA_VERSION} | cut -d '-' -f 1`
AC_MSG_RESULT([$RUSTC_VERSION (v${_RUSTC_MAJOR_VERSION}.${_RUSTC_MINOR_VERSION}.${_RUSTC_PATCH_VERSION})])
fi
MOZ_ARG_ENABLE_BOOL([rust],
[ --enable-rust Include Rust language sources],
[MOZ_RUST=1],
[MOZ_RUST= ])
if test -z "$RUSTC" -a -n "$MOZ_RUST"; then
AC_MSG_ERROR([Rust compiler not found.
To compile rust language sources, you must have 'rustc' in your path.
See http://www.rust-lang.org/ for more information.])
fi
if test -n "$MOZ_RUST" && test -z "$_RUSTC_MAJOR_VERSION" -o \
"$_RUSTC_MAJOR_VERSION" -lt 1; then
AC_MSG_ERROR([Rust compiler ${RUSTC_VERSION} is too old.
To compile Rust language sources please install at least
version 1.0 of the 'rustc' toolchain and make sure it is
first in your path.
You can verify this by typing 'rustc --version'.])
fi
AC_SUBST(MOZ_RUST)
])
+76 -83
View File
@@ -137,6 +137,8 @@ MOZ_BUILD_ROOT=`pwd -W 2>/dev/null || pwd`
MOZ_PYTHON
MOZ_BUILD_BACKEND
MOZ_DEFAULT_COMPILER
COMPILE_ENVIRONMENT=1
@@ -424,6 +426,8 @@ MOZ_TOOL_VARIABLES
MOZ_CHECK_COMPILER_WRAPPER
MOZ_RUST_SUPPORT
dnl ========================================================
dnl Check for MacOS deployment target version
dnl ========================================================
@@ -448,6 +452,9 @@ esac
AC_SUBST(MACOSX_DEPLOYMENT_TARGET)
AC_PROG_CPP
AC_PROG_CXXCPP
dnl ========================================================
dnl Special win32 checks
dnl ========================================================
@@ -647,8 +654,6 @@ See https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
fi
CFLAGS="$CFLAGS -D_HAS_EXCEPTIONS=0"
CXXFLAGS="$CXXFLAGS -D_HAS_EXCEPTIONS=0"
MOZ_FIND_WINSDK_VERSION
else
# Check w32api version
_W32API_MAJOR_VERSION=`echo $W32API_VERSION | $AWK -F\. '{ print $1 }'`
@@ -700,10 +705,9 @@ See https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
# strsafe.h on mingw uses macros for function deprecation that pollutes namespace
# causing problems with local implementations with the same name.
AC_DEFINE(STRSAFE_NO_DEPRECATE)
MOZ_WINSDK_MAXVER=0x06030000
fi # !GNU_CC
MOZ_FIND_WINSDK_VERSION
AC_DEFINE_UNQUOTED(WINVER,0x$WINVER)
AC_DEFINE_UNQUOTED(_WIN32_WINNT,0x$WINVER)
# Require OS features provided by IE 6.0 SP2 (XP SP2)
@@ -727,9 +731,6 @@ See https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
;;
esac
AC_PROG_CPP
AC_PROG_CXXCPP
if test -n "$_WIN32_MSVC"; then
SKIP_PATH_CHECKS=1
SKIP_COMPILER_CHECKS=1
@@ -1648,46 +1649,6 @@ if test "$GCC_MAJOR_VERSION" -ge "6" ; then
CXXFLAGS="$CXXFLAGS -fno-delete-null-pointer-checks -fno-lifetime-dse -fno-schedule-insns2"
fi
dnl gcc can come with its own linker so it is better to use the pass-thru calls
dnl MKSHLIB_FORCE_ALL is used to force the linker to include all object
dnl files present in an archive. MKSHLIB_UNFORCE_ALL reverts the linker to
dnl normal behavior.
dnl ========================================================
MKSHLIB_FORCE_ALL=
MKSHLIB_UNFORCE_ALL=
if test "$COMPILE_ENVIRONMENT"; then
if test "$GNU_CC"; then
AC_MSG_CHECKING(whether ld has archive extraction flags)
AC_CACHE_VAL(ac_cv_mkshlib_force_and_unforce,
[_SAVE_LDFLAGS=$LDFLAGS; _SAVE_LIBS=$LIBS
ac_cv_mkshlib_force_and_unforce="no"
exec 3<&0 <<LOOP_INPUT
force="-Wl,--whole-archive"; unforce="-Wl,--no-whole-archive"
force="-Wl,-z -Wl,allextract"; unforce="-Wl,-z -Wl,defaultextract"
force="-Wl,-all"; unforce="-Wl,-none"
LOOP_INPUT
while read line
do
eval $line
LDFLAGS=$force
LIBS=$unforce
AC_TRY_LINK(,, ac_cv_mkshlib_force_and_unforce=$line; break)
done
exec 0<&3 3<&-
LDFLAGS=$_SAVE_LDFLAGS; LIBS=$_SAVE_LIBS
])
if test "$ac_cv_mkshlib_force_and_unforce" = "no"; then
AC_MSG_RESULT(no)
else
AC_MSG_RESULT(yes)
eval $ac_cv_mkshlib_force_and_unforce
MKSHLIB_FORCE_ALL=$force
MKSHLIB_UNFORCE_ALL=$unforce
fi
fi # GNU_CC
fi # COMPILE_ENVIRONMENT
dnl ========================================================
dnl Checking for 64-bit OS
dnl ========================================================
@@ -1867,6 +1828,9 @@ dnl ==============================================================
MOZILLA_VERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir`
MOZILLA_UAVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir --uaversion`
MOZILLA_SYMBOLVERSION=`$PYTHON $srcdir/python/mozbuild/mozbuild/milestone.py --topsrcdir $srcdir --symbolversion`
if test -z "$MOZILLA_VERSION"; then
AC_MSG_ERROR([failed to read version info from milestone file])
fi
AC_DEFINE_UNQUOTED(MOZILLA_VERSION,"$MOZILLA_VERSION")
AC_DEFINE_UNQUOTED(MOZILLA_VERSION_U,$MOZILLA_VERSION)
@@ -2175,9 +2139,7 @@ ia64*-hpux*)
IMPORT_LIB_SUFFIX=lib
MKSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
MKCSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
MKSHLIB_FORCE_ALL=
MKSHLIB_UNFORCE_ALL=
dnl Set subsystem version 6.
dnl Set subsystem version 5 for Windows XP.
WIN32_SUBSYSTEM_VERSION=5.01
if test "$HAVE_64BIT_BUILD"; then
WIN32_SUBSYSTEM_VERSION=5.02
@@ -2359,8 +2321,6 @@ ia64*-hpux*)
DSO_LDOPTS='-shared'
fi
# This will fail on a.out systems prior to 1.5.1_ALPHA.
MKSHLIB_FORCE_ALL='-Wl,--whole-archive'
MKSHLIB_UNFORCE_ALL='-Wl,--no-whole-archive'
if test "$LIBRUNPATH"; then
DSO_LDOPTS="-Wl,-R$LIBRUNPATH $DSO_LDOPTS"
fi
@@ -2410,8 +2370,6 @@ ia64*-hpux*)
MOZ_OPTIMIZE_FLAGS="-xO4"
MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_FLAGS) $(DSO_LDOPTS) -h $(DSO_SONAME) -o $@'
MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_FLAGS) $(DSO_LDOPTS) -h $(DSO_SONAME) -o $@'
MKSHLIB_FORCE_ALL='-z allextract'
MKSHLIB_UNFORCE_ALL='-z defaultextract'
DSO_LDOPTS='-G'
AR_LIST="$AR t"
AR_EXTRACT="$AR x"
@@ -2452,8 +2410,6 @@ ia64*-hpux*)
else
LDFLAGS="$LDFLAGS -Wl,-z,ignore -Wl,-R,'\$\$ORIGIN:\$\$ORIGIN/..' -Wl,-z,lazyload -Wl,-z,combreloc -Wl,-z,muldefs"
LIBS="-lc $LIBS"
MKSHLIB_FORCE_ALL='-Wl,-z -Wl,allextract'
MKSHLIB_UNFORCE_ALL='-Wl,-z -Wl,defaultextract'
ASFLAGS="$ASFLAGS -fPIC"
DSO_LDOPTS='-shared'
WARNINGS_AS_ERRORS='-Werror'
@@ -2503,31 +2459,6 @@ dnl Only one oddball right now (QNX), but this gives us flexibility
dnl if any other platforms need to override this in the future.
AC_DEFINE_UNQUOTED(D_INO,$DIRENT_INO)
dnl ========================================================
dnl Any platform that doesn't have MKSHLIB_FORCE_ALL defined
dnl by now will not have any way to link most binaries (tests
dnl as well as viewer, apprunner, etc.), because some symbols
dnl will be left out of the "composite" .so's by ld as unneeded.
dnl So, by defining NO_LD_ARCHIVE_FLAGS for these platforms,
dnl they can link in the static libs that provide the missing
dnl symbols.
dnl ========================================================
NO_LD_ARCHIVE_FLAGS=
if test -z "$MKSHLIB_FORCE_ALL" -o -z "$MKSHLIB_UNFORCE_ALL"; then
NO_LD_ARCHIVE_FLAGS=1
fi
case "$target" in
*-aix4.3*|*-aix5*)
NO_LD_ARCHIVE_FLAGS=
;;
*-mingw*)
if test -z "$GNU_CC"; then
NO_LD_ARCHIVE_FLAGS=
fi
;;
esac
AC_SUBST(NO_LD_ARCHIVE_FLAGS)
dnl ========================================================
dnl = Flags to strip unused symbols from .so components and
dnl = to export jemalloc symbols when linking a program
@@ -3740,6 +3671,7 @@ MOZ_WAVE=1
MOZ_SAMPLE_TYPE_FLOAT32=
MOZ_SAMPLE_TYPE_S16=
MOZ_WEBM=1
MOZ_GSTREAMER=
MOZ_DIRECTSHOW=
MOZ_WMF=
if test -n "$MOZ_FMP4"; then
@@ -5523,6 +5455,69 @@ fi
AC_SUBST(MOZ_PULSEAUDIO)
dnl ========================================================
dnl = Enable GStreamer
dnl ========================================================
case "$OS_TARGET" in
WINNT|Darwin|Android)
;;
*)
MOZ_GSTREAMER=1
GST_API_VERSION=0.10
;;
esac
MOZ_ARG_ENABLE_STRING(gstreamer,
[ --enable-gstreamer[=0.10] Enable GStreamer support],
[ MOZ_GSTREAMER=1
# API version, eg 0.10, 1.0 etc
if test -z "$enableval" -o "$enableval" = "yes"; then
GST_API_VERSION=0.10
elif test "$enableval" = "no"; then
MOZ_GSTREAMER=
else
GST_API_VERSION=$enableval
fi],
)
if test -n "$MOZ_GSTREAMER"; then
# core/base release number
if test "$GST_API_VERSION" = "1.0"; then
GST_VERSION=1.0
else
GST_VERSION=0.10.25
fi
PKG_CHECK_MODULES(GSTREAMER,
gstreamer-$GST_API_VERSION >= $GST_VERSION
gstreamer-app-$GST_API_VERSION
gstreamer-plugins-base-$GST_API_VERSION,
[_HAVE_GSTREAMER=1],
[_HAVE_GSTREAMER=])
if test -z "$_HAVE_GSTREAMER"; then
AC_MSG_ERROR([gstreamer and gstreamer-plugins-base development packages are needed to build gstreamer backend. Install them or disable gstreamer support with --disable-gstreamer])
fi
_SAVE_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS $GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION"
AC_TRY_LINK(,[return 0;],_HAVE_LIBGSTVIDEO=1,_HAVE_LIBGSTVIDEO=)
if test -n "$_HAVE_LIBGSTVIDEO" ; then
GSTREAMER_LIBS="$GSTREAMER_LIBS -lgstvideo-$GST_API_VERSION"
else
AC_MSG_ERROR([gstreamer-plugins-base found, but no libgstvideo. Something has gone terribly wrong. Try reinstalling gstreamer-plugins-base; failing that, disable the gstreamer backend with --disable-gstreamer.])
fi
LDFLAGS=$_SAVE_LDFLAGS
fi
AC_SUBST(MOZ_GSTREAMER)
AC_SUBST(GST_API_VERSION)
if test -n "$MOZ_GSTREAMER"; then
AC_DEFINE(MOZ_GSTREAMER)
AC_DEFINE_UNQUOTED(GST_API_VERSION, "$GST_API_VERSION")
fi
dnl ========================================================
dnl Permissions System
dnl ========================================================
@@ -8498,8 +8493,6 @@ AC_SUBST(MOZ_CHROME_FILE_FORMAT)
AC_SUBST(WRAP_LDFLAGS)
AC_SUBST(MKSHLIB)
AC_SUBST(MKCSHLIB)
AC_SUBST(MKSHLIB_FORCE_ALL)
AC_SUBST(MKSHLIB_UNFORCE_ALL)
AC_SUBST(DSO_CFLAGS)
AC_SUBST(DSO_PIC_CFLAGS)
AC_SUBST(DSO_LDOPTS)
+2
View File
@@ -1350,6 +1350,8 @@ public:
* are not converted into newlines. Only textnodes and cdata nodes are
* added to the result.
*
* @see nsLayoutUtils::GetFrameTextContent
*
* @param aNode Node to get textual contents of.
* @param aDeep If true child elements of aNode are recursivly descended
* into to find text children.
+1 -2
View File
@@ -4705,8 +4705,7 @@ CanvasRenderingContext2D::DrawDirectlyToCanvas(
auto result = image.mImgContainer->
Draw(context, scaledImageSize,
ImageRegion::Create(gfxRect(src.x, src.y, src.width, src.height)),
image.mWhichFrame, GraphicsFilter::FILTER_GOOD,
Some(svgContext), modifiedFlags);
image.mWhichFrame, Filter::GOOD, Some(svgContext), modifiedFlags);
if (result != DrawResult::SUCCESS) {
NS_WARNING("imgIContainer::Draw failed");
@@ -12,7 +12,6 @@
#include "nsIDocShell.h"
#include "nsRefreshDriver.h"
#include "mozilla/dom/HTMLCanvasElement.h"
#include "GraphicsFilter.h"
#include "mozilla/RefPtr.h"
#define NS_ICANVASRENDERINGCONTEXTINTERNAL_IID \
+7 -3
View File
@@ -60,6 +60,7 @@ using mozilla::CommandInt from "mozilla/EventForwards.h";
using mozilla::Modifiers from "mozilla/EventForwards.h";
using mozilla::layers::GeckoContentController::APZStateChange from "mozilla/layers/GeckoContentController.h";
using mozilla::WritingMode from "mozilla/WritingModes.h";
using mozilla::layers::AsyncDragMetrics from "mozilla/layers/AsyncDragMetrics.h";
using mozilla::layers::TouchBehaviorFlags from "mozilla/layers/APZUtils.h";
using nsIWidget::TouchPointerState from "nsIWidget.h";
using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h";
@@ -537,6 +538,9 @@ parent:
prio(high) sync DispatchMouseEvent(WidgetMouseEvent event);
prio(high) sync DispatchKeyboardEvent(WidgetKeyboardEvent event);
// Start an APZ drag on a scrollbar
async StartScrollbarDrag(AsyncDragMetrics aDragMetrics);
InvokeDragSession(IPCDataTransfer[] transfers, uint32_t action,
nsCString visualData, uint32_t width, uint32_t height,
uint32_t stride, uint8_t format, int32_t dragAreaX, int32_t dragAreaY);
@@ -619,7 +623,7 @@ child:
* When two consecutive mouse move events would be added to the message queue,
* they are 'compressed' by dumping the oldest one.
*/
RealMouseMoveEvent(WidgetMouseEvent event) compress;
RealMouseMoveEvent(WidgetMouseEvent event, ScrollableLayerGuid aGuid, uint64_t aInputBlockId) compress;
/**
* Mouse move events with |reason == eSynthesized| are sent via a separate
* message because they do not generate DOM 'mousemove' events, and the
@@ -627,8 +631,8 @@ child:
* |reason == eReal| event being dropped in favour of an |eSynthesized|
* event, and thus a DOM 'mousemove' event to be lost.
*/
SynthMouseMoveEvent(WidgetMouseEvent event);
RealMouseButtonEvent(WidgetMouseEvent event);
SynthMouseMoveEvent(WidgetMouseEvent event, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);
RealMouseButtonEvent(WidgetMouseEvent event, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);
RealKeyEvent(WidgetKeyboardEvent event, MaybeNativeKeyBinding keyBinding);
MouseWheelEvent(WidgetWheelEvent event, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);
RealTouchEvent(WidgetTouchEvent aEvent,
+15 -5
View File
@@ -33,6 +33,7 @@
#include "mozilla/layers/CompositorChild.h"
#include "mozilla/layers/DoubleTapToZoom.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/InputAPZContext.h"
#include "mozilla/layers/ShadowLayers.h"
#include "mozilla/layout/RenderFrameChild.h"
#include "mozilla/LookAndFeel.h"
@@ -1899,20 +1900,29 @@ TabChild::RecvMouseEvent(const nsString& aType,
}
bool
TabChild::RecvRealMouseMoveEvent(const WidgetMouseEvent& event)
TabChild::RecvRealMouseMoveEvent(const WidgetMouseEvent& event,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId)
{
return RecvRealMouseButtonEvent(event);
return RecvRealMouseButtonEvent(event, aGuid, aInputBlockId);
}
bool
TabChild::RecvSynthMouseMoveEvent(const WidgetMouseEvent& event)
TabChild::RecvSynthMouseMoveEvent(const WidgetMouseEvent& event,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId)
{
return RecvRealMouseButtonEvent(event);
return RecvRealMouseButtonEvent(event, aGuid, aInputBlockId);
}
bool
TabChild::RecvRealMouseButtonEvent(const WidgetMouseEvent& event)
TabChild::RecvRealMouseButtonEvent(const WidgetMouseEvent& event,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId)
{
nsEventStatus unused;
InputAPZContext context(aGuid, aInputBlockId, unused);
WidgetMouseEvent localEvent(event);
localEvent.widget = mPuppetWidget;
APZCCallbackHelper::DispatchWidgetEvent(localEvent);
+9 -3
View File
@@ -331,9 +331,15 @@ public:
const int32_t& aClickCount,
const int32_t& aModifiers,
const bool& aIgnoreRootScrollFrame) override;
virtual bool RecvRealMouseMoveEvent(const mozilla::WidgetMouseEvent& event) override;
virtual bool RecvSynthMouseMoveEvent(const mozilla::WidgetMouseEvent& event) override;
virtual bool RecvRealMouseButtonEvent(const mozilla::WidgetMouseEvent& event) override;
virtual bool RecvRealMouseMoveEvent(const mozilla::WidgetMouseEvent& event,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId) override;
virtual bool RecvSynthMouseMoveEvent(const mozilla::WidgetMouseEvent& event,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId) override;
virtual bool RecvRealMouseButtonEvent(const mozilla::WidgetMouseEvent& event,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId) override;
virtual bool RecvRealDragEvent(const WidgetDragEvent& aEvent,
const uint32_t& aDragAction,
const uint32_t& aDropEffect) override;
+18 -3
View File
@@ -28,6 +28,7 @@
#include "mozilla/IMEStateManager.h"
#include "mozilla/ipc/DocumentRendererParent.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "mozilla/layers/AsyncDragMetrics.h"
#include "mozilla/layers/CompositorParent.h"
#include "mozilla/layers/InputAPZContext.h"
#include "mozilla/layout/RenderFrameParent.h"
@@ -1437,14 +1438,19 @@ bool TabParent::SendRealMouseEvent(WidgetMouseEvent& event)
}
}
ScrollableLayerGuid guid;
uint64_t blockId;
ApzAwareEventRoutingToChild(&guid, &blockId, nullptr);
if (eMouseMove == event.mMessage) {
if (event.reason == WidgetMouseEvent::eSynthesized) {
return SendSynthMouseMoveEvent(event);
return SendSynthMouseMoveEvent(event, guid, blockId);
} else {
return SendRealMouseMoveEvent(event);
return SendRealMouseMoveEvent(event, guid, blockId);
}
}
return SendRealMouseButtonEvent(event);
return SendRealMouseButtonEvent(event, guid, blockId);
}
LayoutDeviceToCSSScale
@@ -2913,6 +2919,15 @@ TabParent::RecvSetTargetAPZC(const uint64_t& aInputBlockId,
return true;
}
bool
TabParent::RecvStartScrollbarDrag(const AsyncDragMetrics& aDragMetrics)
{
if (RenderFrameParent* rfp = GetRenderFrame()) {
rfp->StartScrollbarDrag(aDragMetrics);
}
return true;
}
bool
TabParent::RecvSetAllowedTouchBehavior(const uint64_t& aInputBlockId,
nsTArray<TouchBehaviorFlags>&& aFlags)
+3
View File
@@ -43,6 +43,7 @@ class CpowHolder;
} // namespace jsipc
namespace layers {
class AsyncDragMetrics;
struct FrameMetrics;
struct TextureFactoryIdentifier;
} // namespace layers
@@ -81,6 +82,7 @@ class TabParent final : public PBrowserParent
, public nsAPostRefreshObserver
{
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
typedef mozilla::layers::AsyncDragMetrics AsyncDragMetrics;
virtual ~TabParent();
@@ -239,6 +241,7 @@ public:
virtual bool RecvDispatchWheelEvent(const mozilla::WidgetWheelEvent& aEvent) override;
virtual bool RecvDispatchMouseEvent(const mozilla::WidgetMouseEvent& aEvent) override;
virtual bool RecvDispatchKeyboardEvent(const mozilla::WidgetKeyboardEvent& aEvent) override;
virtual bool RecvStartScrollbarDrag(const AsyncDragMetrics& aDragMetrics) override;
virtual PColorPickerParent*
AllocPColorPickerParent(const nsString& aTitle, const nsString& aInitialColor) override;
+19
View File
@@ -11,6 +11,7 @@
#include "mozilla/Mutex.h"
#include "nsString.h"
#include "Intervals.h"
namespace mozilla {
@@ -213,6 +214,24 @@ private:
};
class NotifyDataArrivedFilter {
public:
media::IntervalSet<int64_t> NotifyDataArrived(uint32_t aLength, int64_t aOffset) {
media::Interval<int64_t> interval(aOffset, aOffset + aLength);
media::IntervalSet<int64_t> newIntervals(interval);
newIntervals -= mIntervals;
mIntervals += interval;
return newIntervals;
}
const media::IntervalSet<int64_t>& GetIntervals() {
return mIntervals;
}
private:
media::IntervalSet<int64_t> mIntervals;
};
} // namespace mozilla
#endif
+8
View File
@@ -1478,6 +1478,14 @@ MediaDecoder::IsRtspEnabled()
}
#endif
#ifdef MOZ_GSTREAMER
bool
MediaDecoder::IsGStreamerEnabled()
{
return Preferences::GetBool("media.gstreamer.enabled");
}
#endif
#ifdef MOZ_OMX_DECODER
bool
MediaDecoder::IsOmxEnabled()
+4
View File
@@ -710,6 +710,10 @@ private:
static bool IsRtspEnabled();
#endif
#ifdef MOZ_GSTREAMER
static bool IsGStreamerEnabled();
#endif
#ifdef MOZ_OMX_DECODER
static bool IsOmxEnabled();
static bool IsOmxAsyncEnabled();
+16 -13
View File
@@ -520,20 +520,23 @@ AppleMP3Reader::NotifyDataArrivedInternal(uint32_t aLength, int64_t aOffset)
return;
}
nsRefPtr<MediaByteBuffer> bytes =
mDecoder->GetResource()->MediaReadAt(aOffset, aLength);
NS_ENSURE_TRUE_VOID(bytes);
mMP3FrameParser.Parse(bytes->Elements(), aLength, aOffset);
if (!mMP3FrameParser.IsMP3()) {
return;
}
IntervalSet<int64_t> intervals = mFilter.NotifyDataArrived(aLength, aOffset);
for (const auto& interval : intervals) {
nsRefPtr<MediaByteBuffer> bytes =
mResource.MediaReadAt(interval.mStart, interval.Length());
NS_ENSURE_TRUE_VOID(bytes);
mMP3FrameParser.Parse(bytes->Elements(), interval.Length(), interval.mStart);
if (!mMP3FrameParser.IsMP3()) {
return;
}
uint64_t duration = mMP3FrameParser.GetDuration();
if (duration != mDuration) {
LOGD("Updating media duration to %lluus\n", duration);
MOZ_ASSERT(mDecoder);
mDuration = duration;
mDecoder->DispatchUpdateEstimatedMediaDuration(duration);
uint64_t duration = mMP3FrameParser.GetDuration();
if (duration != mDuration) {
LOGD("Updating media duration to %lluus\n", duration);
MOZ_ASSERT(mDecoder);
mDuration = duration;
mDecoder->DispatchUpdateEstimatedMediaDuration(duration);
}
}
}
+1
View File
@@ -82,6 +82,7 @@ private:
MP3FrameParser mMP3FrameParser;
MediaResourceIndex mResource;
NotifyDataArrivedFilter mFilter;
};
} // namespace mozilla
+15 -11
View File
@@ -408,18 +408,22 @@ DirectShowReader::NotifyDataArrivedInternal(uint32_t aLength, int64_t aOffset)
return;
}
nsRefPtr<MediaByteBuffer> bytes = mDecoder->GetResource()->MediaReadAt(aOffset, aLength);
NS_ENSURE_TRUE_VOID(bytes);
mMP3FrameParser.Parse(bytes->Elements(), aLength, aOffset);
if (!mMP3FrameParser.IsMP3()) {
return;
}
IntervalSet<int64_t> intervals = mFilter.NotifyDataArrived(aLength, aOffset);
for (const auto& interval : intervals) {
nsRefPtr<MediaByteBuffer> bytes =
mDecoder->GetResource()->MediaReadAt(interval.mStart, interval.Length());
NS_ENSURE_TRUE_VOID(bytes);
mMP3FrameParser.Parse(bytes->Elements(), interval.Length(), interval.mStart);
if (!mMP3FrameParser.IsMP3()) {
return;
}
int64_t duration = mMP3FrameParser.GetDuration();
if (duration != mDuration) {
MOZ_ASSERT(mDecoder);
mDuration = duration;
mDecoder->DispatchUpdateEstimatedMediaDuration(mDuration);
int64_t duration = mMP3FrameParser.GetDuration();
if (duration != mDuration) {
MOZ_ASSERT(mDecoder);
mDuration = duration;
mDecoder->DispatchUpdateEstimatedMediaDuration(mDuration);
}
}
}
+2
View File
@@ -110,6 +110,8 @@ private:
// Duration of the stream, in microseconds.
int64_t mDuration;
NotifyDataArrivedFilter mFilter;
};
} // namespace mozilla
+7 -11
View File
@@ -283,20 +283,16 @@ GMPServiceChild::GetBridgedGMPContentParent(ProcessId aOtherPid,
mContentParents.Get(aOtherPid, aGMPContentParent);
}
static PLDHashOperator
FindAndRemoveGMPContentParent(const uint64_t& aKey,
nsRefPtr<GMPContentParent>& aData,
void* aUserArg)
{
return aData == aUserArg ?
(PLDHashOperator)(PL_DHASH_STOP | PL_DHASH_REMOVE) :
PL_DHASH_NEXT;
}
void
GMPServiceChild::RemoveGMPContentParent(GMPContentParent* aGMPContentParent)
{
mContentParents.Enumerate(FindAndRemoveGMPContentParent, aGMPContentParent);
for (auto iter = mContentParents.Iter(); !iter.Done(); iter.Next()) {
nsRefPtr<GMPContentParent>& parent = iter.Data();
if (parent == aGMPContentParent) {
iter.Remove();
break;
}
}
}
static PLDHashOperator
+201
View File
@@ -0,0 +1,201 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "GStreamerAllocator.h"
#include <gst/video/video.h>
#include <gst/video/gstvideometa.h>
#include "GStreamerLoader.h"
using namespace mozilla::layers;
namespace mozilla {
typedef struct
{
GstAllocator parent;
GStreamerReader *reader;
} MozGfxMemoryAllocator;
typedef struct
{
GstAllocatorClass parent;
} MozGfxMemoryAllocatorClass;
typedef struct
{
GstMemory memory;
PlanarYCbCrImage* image;
guint8* data;
} MozGfxMemory;
typedef struct
{
GstMeta meta;
} MozGfxMeta;
typedef struct
{
GstVideoBufferPoolClass parent_class;
} MozGfxBufferPoolClass;
typedef struct
{
GstVideoBufferPool pool;
} MozGfxBufferPool;
// working around GTK+ bug https://bugzilla.gnome.org/show_bug.cgi?id=723899
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
G_DEFINE_TYPE(MozGfxMemoryAllocator, moz_gfx_memory_allocator, GST_TYPE_ALLOCATOR);
G_DEFINE_TYPE(MozGfxBufferPool, moz_gfx_buffer_pool, GST_TYPE_VIDEO_BUFFER_POOL);
#pragma GCC diagnostic pop
void
moz_gfx_memory_reset(MozGfxMemory *mem)
{
if (mem->image)
mem->image->Release();
ImageContainer* container = ((MozGfxMemoryAllocator*) mem->memory.allocator)->reader->GetImageContainer();
mem->image = reinterpret_cast<PlanarYCbCrImage*>(container->CreateImage(ImageFormat::PLANAR_YCBCR).take());
mem->data = mem->image->AllocateAndGetNewBuffer(mem->memory.size);
}
static GstMemory*
moz_gfx_memory_allocator_alloc(GstAllocator* aAllocator, gsize aSize,
GstAllocationParams* aParams)
{
MozGfxMemory* mem = g_slice_new (MozGfxMemory);
gsize maxsize = aSize + aParams->prefix + aParams->padding;
gst_memory_init(GST_MEMORY_CAST (mem),
(GstMemoryFlags)aParams->flags,
aAllocator, NULL, maxsize, aParams->align,
aParams->prefix, aSize);
mem->image = NULL;
moz_gfx_memory_reset(mem);
return (GstMemory *) mem;
}
static void
moz_gfx_memory_allocator_free (GstAllocator * allocator, GstMemory * gmem)
{
MozGfxMemory *mem = (MozGfxMemory *) gmem;
if (mem->memory.parent)
goto sub_mem;
if (mem->image)
mem->image->Release();
sub_mem:
g_slice_free (MozGfxMemory, mem);
}
static gpointer
moz_gfx_memory_map (MozGfxMemory * mem, gsize maxsize, GstMapFlags flags)
{
// check that the allocation didn't fail
if (mem->data == nullptr)
return nullptr;
return mem->data + mem->memory.offset;
}
static gboolean
moz_gfx_memory_unmap (MozGfxMemory * mem)
{
return TRUE;
}
static MozGfxMemory *
moz_gfx_memory_share (MozGfxMemory * mem, gssize offset, gsize size)
{
MozGfxMemory *sub;
GstMemory *parent;
/* find the real parent */
if ((parent = mem->memory.parent) == NULL)
parent = (GstMemory *) mem;
if (size == (gsize) -1)
size = mem->memory.size - offset;
/* the shared memory is always readonly */
sub = g_slice_new (MozGfxMemory);
gst_memory_init (GST_MEMORY_CAST (sub),
(GstMemoryFlags) (GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY),
mem->memory.allocator, &mem->memory, mem->memory.maxsize, mem->memory.align,
mem->memory.offset + offset, size);
sub->image = mem->image;
sub->data = mem->data;
return sub;
}
static void
moz_gfx_memory_allocator_class_init (MozGfxMemoryAllocatorClass * klass)
{
GstAllocatorClass *allocator_class;
allocator_class = (GstAllocatorClass *) klass;
allocator_class->alloc = moz_gfx_memory_allocator_alloc;
allocator_class->free = moz_gfx_memory_allocator_free;
}
static void
moz_gfx_memory_allocator_init (MozGfxMemoryAllocator * allocator)
{
GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
alloc->mem_type = "moz-gfx-image";
alloc->mem_map = (GstMemoryMapFunction) moz_gfx_memory_map;
alloc->mem_unmap = (GstMemoryUnmapFunction) moz_gfx_memory_unmap;
alloc->mem_share = (GstMemoryShareFunction) moz_gfx_memory_share;
/* fallback copy and is_span */
}
void
moz_gfx_memory_allocator_set_reader(GstAllocator* aAllocator, GStreamerReader* aReader)
{
MozGfxMemoryAllocator *allocator = (MozGfxMemoryAllocator *) aAllocator;
allocator->reader = aReader;
}
nsRefPtr<PlanarYCbCrImage>
moz_gfx_memory_get_image(GstMemory *aMemory)
{
NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(aMemory->allocator), "Should be a gfx image");
return ((MozGfxMemory *) aMemory)->image;
}
void
moz_gfx_buffer_pool_reset_buffer (GstBufferPool* aPool, GstBuffer* aBuffer)
{
GstMemory* mem = gst_buffer_peek_memory(aBuffer, 0);
NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(mem->allocator), "Should be a gfx image");
moz_gfx_memory_reset((MozGfxMemory *) mem);
GST_BUFFER_POOL_CLASS(moz_gfx_buffer_pool_parent_class)->reset_buffer(aPool, aBuffer);
}
static void
moz_gfx_buffer_pool_class_init (MozGfxBufferPoolClass * klass)
{
GstBufferPoolClass *pool_class = (GstBufferPoolClass *) klass;
pool_class->reset_buffer = moz_gfx_buffer_pool_reset_buffer;
}
static void
moz_gfx_buffer_pool_init (MozGfxBufferPool * pool)
{
}
} // namespace mozilla
+25
View File
@@ -0,0 +1,25 @@
/* 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(GStreamerAllocator_h_)
#define GStreamerAllocator_h_
#include "GStreamerReader.h"
#define GST_TYPE_MOZ_GFX_MEMORY_ALLOCATOR (moz_gfx_memory_allocator_get_type())
#define GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MOZ_GFX_MEMORY_ALLOCATOR))
#define GST_TYPE_MOZ_GFX_BUFFER_POOL (moz_gfx_buffer_pool_get_type())
#define GST_IS_MOZ_GFX_BUFFER_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MOZ_GFX_BUFFER_POOL))
namespace mozilla {
GType moz_gfx_memory_allocator_get_type();
void moz_gfx_memory_allocator_set_reader(GstAllocator *aAllocator, GStreamerReader* aReader);
nsRefPtr<layers::PlanarYCbCrImage> moz_gfx_memory_get_image(GstMemory *aMemory);
GType moz_gfx_buffer_pool_get_type();
} // namespace mozilla
#endif
+28
View File
@@ -0,0 +1,28 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 "MediaDecoderStateMachine.h"
#include "GStreamerReader.h"
#include "GStreamerDecoder.h"
#include "GStreamerFormatHelper.h"
namespace mozilla {
MediaDecoderStateMachine* GStreamerDecoder::CreateStateMachine()
{
return new MediaDecoderStateMachine(this, new GStreamerReader(this));
}
bool
GStreamerDecoder::CanHandleMediaType(const nsACString& aMIMEType,
const nsAString* aCodecs)
{
return MediaDecoder::IsGStreamerEnabled() &&
GStreamerFormatHelper::Instance()->CanHandleMediaType(aMIMEType, aCodecs);
}
} // namespace mozilla
+25
View File
@@ -0,0 +1,25 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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(GStreamerDecoder_h_)
#define GStreamerDecoder_h_
#include "MediaDecoder.h"
#include "nsXPCOMStrings.h"
namespace mozilla {
class GStreamerDecoder : public MediaDecoder
{
public:
virtual MediaDecoder* Clone() { return new GStreamerDecoder(); }
virtual MediaDecoderStateMachine* CreateStateMachine();
static bool CanHandleMediaType(const nsACString& aMIMEType, const nsAString* aCodecs);
};
} // namespace mozilla
#endif
@@ -0,0 +1,373 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 "GStreamerFormatHelper.h"
#include "nsCharSeparatedTokenizer.h"
#include "nsString.h"
#include "GStreamerLoader.h"
#include "mozilla/Logging.h"
#include "mozilla/Preferences.h"
#define ENTRY_FORMAT(entry) entry[0]
#define ENTRY_CAPS(entry) entry[1]
namespace mozilla {
extern PRLogModuleInfo* gMediaDecoderLog;
#define LOG(msg, ...) \
MOZ_LOG(gMediaDecoderLog, LogLevel::Debug, ("GStreamerFormatHelper " msg, ##__VA_ARGS__))
GStreamerFormatHelper* GStreamerFormatHelper::gInstance = nullptr;
bool GStreamerFormatHelper::sLoadOK = false;
GStreamerFormatHelper* GStreamerFormatHelper::Instance() {
if (!gInstance) {
if ((sLoadOK = load_gstreamer())) {
gst_init(nullptr, nullptr);
}
gInstance = new GStreamerFormatHelper();
}
return gInstance;
}
void GStreamerFormatHelper::Shutdown() {
delete gInstance;
gInstance = nullptr;
}
static char const *const sContainers[][2] = {
{"video/mp4", "video/quicktime"},
{"video/x-m4v", "video/quicktime"},
{"video/quicktime", "video/quicktime"},
{"audio/mp4", "audio/x-m4a"},
{"audio/x-m4a", "audio/x-m4a"},
{"audio/mpeg", "audio/mpeg, mpegversion=(int)1"},
{"audio/mp3", "audio/mpeg, mpegversion=(int)1"},
};
static char const *const sCodecs[9][2] = {
{"avc1.42E01E", "video/x-h264"},
{"avc1.42001E", "video/x-h264"},
{"avc1.58A01E", "video/x-h264"},
{"avc1.4D401E", "video/x-h264"},
{"avc1.64001E", "video/x-h264"},
{"avc1.64001F", "video/x-h264"},
{"mp4v.20.3", "video/3gpp"},
{"mp4a.40.2", "audio/mpeg, mpegversion=(int)4"},
{"mp3", "audio/mpeg, mpegversion=(int)1"},
};
static char const * const sDefaultCodecCaps[][2] = {
{"video/mp4", "video/x-h264"},
{"video/x-m4v", "video/x-h264"},
{"video/quicktime", "video/x-h264"},
{"audio/mp4", "audio/mpeg, mpegversion=(int)4"},
{"audio/x-m4a", "audio/mpeg, mpegversion=(int)4"},
{"audio/mp3", "audio/mpeg, layer=(int)3"},
{"audio/mpeg", "audio/mpeg, layer=(int)3"}
};
static char const * const sPluginBlacklist[] = {
"flump3dec",
"h264parse",
};
GStreamerFormatHelper::GStreamerFormatHelper()
: mFactories(nullptr),
mCookie(static_cast<uint32_t>(-1))
{
if (!sLoadOK) {
return;
}
mSupportedContainerCaps = gst_caps_new_empty();
for (unsigned int i = 0; i < G_N_ELEMENTS(sContainers); i++) {
const char* capsString = sContainers[i][1];
GstCaps* caps = gst_caps_from_string(capsString);
gst_caps_append(mSupportedContainerCaps, caps);
}
mSupportedCodecCaps = gst_caps_new_empty();
for (unsigned int i = 0; i < G_N_ELEMENTS(sCodecs); i++) {
const char* capsString = sCodecs[i][1];
GstCaps* caps = gst_caps_from_string(capsString);
gst_caps_append(mSupportedCodecCaps, caps);
}
}
GStreamerFormatHelper::~GStreamerFormatHelper() {
if (!sLoadOK) {
return;
}
gst_caps_unref(mSupportedContainerCaps);
gst_caps_unref(mSupportedCodecCaps);
if (mFactories)
g_list_free(mFactories);
}
static GstCaps *
GetContainerCapsFromMIMEType(const char *aType) {
/* convert aMIMEType to gst container caps */
const char* capsString = nullptr;
for (uint32_t i = 0; i < G_N_ELEMENTS(sContainers); i++) {
if (!strcmp(ENTRY_FORMAT(sContainers[i]), aType)) {
capsString = ENTRY_CAPS(sContainers[i]);
break;
}
}
if (!capsString) {
/* we couldn't find any matching caps */
return nullptr;
}
return gst_caps_from_string(capsString);
}
static GstCaps *
GetDefaultCapsFromMIMEType(const char *aType) {
GstCaps *caps = GetContainerCapsFromMIMEType(aType);
for (uint32_t i = 0; i < G_N_ELEMENTS(sDefaultCodecCaps); i++) {
if (!strcmp(sDefaultCodecCaps[i][0], aType)) {
GstCaps *tmp = gst_caps_from_string(sDefaultCodecCaps[i][1]);
gst_caps_append(caps, tmp);
return caps;
}
}
return nullptr;
}
bool GStreamerFormatHelper::CanHandleMediaType(const nsACString& aMIMEType,
const nsAString* aCodecs) {
if (!sLoadOK) {
return false;
}
const char *type;
NS_CStringGetData(aMIMEType, &type, nullptr);
GstCaps *caps;
if (aCodecs && !aCodecs->IsEmpty()) {
caps = ConvertFormatsToCaps(type, aCodecs);
} else {
// Get a minimal set of codec caps for this MIME type we should support so
// that we don't overreport MIME types we are able to play.
caps = GetDefaultCapsFromMIMEType(type);
}
if (!caps) {
return false;
}
bool ret = HaveElementsToProcessCaps(caps);
gst_caps_unref(caps);
return ret;
}
GstCaps* GStreamerFormatHelper::ConvertFormatsToCaps(const char* aMIMEType,
const nsAString* aCodecs) {
NS_ASSERTION(sLoadOK, "GStreamer library not linked");
unsigned int i;
GstCaps *caps = GetContainerCapsFromMIMEType(aMIMEType);
if (!caps) {
return nullptr;
}
/* container only */
if (!aCodecs) {
return caps;
}
nsCharSeparatedTokenizer tokenizer(*aCodecs, ',');
while (tokenizer.hasMoreTokens()) {
const nsSubstring& codec = tokenizer.nextToken();
const char *capsString = nullptr;
for (i = 0; i < G_N_ELEMENTS(sCodecs); i++) {
if (codec.EqualsASCII(ENTRY_FORMAT(sCodecs[i]))) {
capsString = ENTRY_CAPS(sCodecs[i]);
break;
}
}
if (!capsString) {
gst_caps_unref(caps);
return nullptr;
}
GstCaps* tmp = gst_caps_from_string(capsString);
/* appends and frees tmp */
gst_caps_append(caps, tmp);
}
return caps;
}
/* static */ bool
GStreamerFormatHelper::IsBlacklistEnabled()
{
static bool sBlacklistEnabled;
static bool sBlacklistEnabledCached = false;
if (!sBlacklistEnabledCached) {
Preferences::AddBoolVarCache(&sBlacklistEnabled,
"media.gstreamer.enable-blacklist", true);
sBlacklistEnabledCached = true;
}
return sBlacklistEnabled;
}
/* static */ bool
GStreamerFormatHelper::IsPluginFeatureBlacklisted(GstPluginFeature *aFeature)
{
if (!IsBlacklistEnabled()) {
return false;
}
const gchar *factoryName =
gst_plugin_feature_get_name(aFeature);
for (unsigned int i = 0; i < G_N_ELEMENTS(sPluginBlacklist); i++) {
if (!strcmp(factoryName, sPluginBlacklist[i])) {
LOG("rejecting disabled plugin %s", factoryName);
return true;
}
}
return false;
}
static gboolean FactoryFilter(GstPluginFeature *aFeature, gpointer)
{
if (!GST_IS_ELEMENT_FACTORY(aFeature)) {
return FALSE;
}
const gchar *className =
gst_element_factory_get_klass(GST_ELEMENT_FACTORY_CAST(aFeature));
// NB: We skip filtering parsers here, because adding them to
// the list can give false decoder positives to canPlayType().
if (!strstr(className, "Decoder") && !strstr(className, "Demux")) {
return FALSE;
}
return
gst_plugin_feature_get_rank(aFeature) >= GST_RANK_MARGINAL &&
!GStreamerFormatHelper::IsPluginFeatureBlacklisted(aFeature);
}
/**
* Returns true if any |aFactory| caps intersect with |aCaps|
*/
static bool SupportsCaps(GstElementFactory *aFactory, GstCaps *aCaps)
{
for (const GList *iter = gst_element_factory_get_static_pad_templates(aFactory); iter; iter = iter->next) {
GstStaticPadTemplate *templ = static_cast<GstStaticPadTemplate *>(iter->data);
if (templ->direction == GST_PAD_SRC) {
continue;
}
GstCaps *caps = gst_static_caps_get(&templ->static_caps);
if (!caps) {
continue;
}
bool supported = gst_caps_can_intersect(caps, aCaps);
gst_caps_unref(caps);
if (supported) {
return true;
}
}
return false;
}
bool GStreamerFormatHelper::HaveElementsToProcessCaps(GstCaps* aCaps) {
NS_ASSERTION(sLoadOK, "GStreamer library not linked");
GList* factories = GetFactories();
/* here aCaps contains [containerCaps, [codecCaps1, [codecCaps2, ...]]] so process
* caps structures individually as we want one element for _each_
* structure */
for (unsigned int i = 0; i < gst_caps_get_size(aCaps); i++) {
GstStructure* s = gst_caps_get_structure(aCaps, i);
GstCaps* caps = gst_caps_new_full(gst_structure_copy(s), nullptr);
bool found = false;
for (GList *elem = factories; elem; elem = elem->next) {
if (SupportsCaps(GST_ELEMENT_FACTORY_CAST(elem->data), caps)) {
found = true;
break;
}
}
gst_caps_unref(caps);
if (!found) {
return false;
}
}
return true;
}
bool GStreamerFormatHelper::CanHandleContainerCaps(GstCaps* aCaps)
{
NS_ASSERTION(sLoadOK, "GStreamer library not linked");
return gst_caps_can_intersect(aCaps, mSupportedContainerCaps);
}
bool GStreamerFormatHelper::CanHandleCodecCaps(GstCaps* aCaps)
{
NS_ASSERTION(sLoadOK, "GStreamer library not linked");
return gst_caps_can_intersect(aCaps, mSupportedCodecCaps);
}
GList* GStreamerFormatHelper::GetFactories() {
NS_ASSERTION(sLoadOK, "GStreamer library not linked");
#if GST_VERSION_MAJOR >= 1
uint32_t cookie = gst_registry_get_feature_list_cookie(gst_registry_get());
#else
uint32_t cookie = gst_default_registry_get_feature_list_cookie();
#endif
if (cookie != mCookie) {
g_list_free(mFactories);
#if GST_VERSION_MAJOR >= 1
mFactories =
gst_registry_feature_filter(gst_registry_get(),
(GstPluginFeatureFilter)FactoryFilter,
false, nullptr);
#else
mFactories =
gst_default_registry_feature_filter((GstPluginFeatureFilter)FactoryFilter,
false, nullptr);
#endif
mCookie = cookie;
}
return mFactories;
}
} // namespace mozilla
@@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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(GStreamerFormatHelper_h_)
#define GStreamerFormatHelper_h_
#include <gst/gst.h>
#include <mozilla/Types.h>
#include "nsXPCOMStrings.h"
namespace mozilla {
class GStreamerFormatHelper {
/* This class can be used to query the GStreamer registry for the required
* demuxers/decoders from nsHTMLMediaElement::CanPlayType.
* It implements looking at the GstRegistry to check if elements to
* demux/decode the formats passed to CanPlayType() are actually installed.
*/
public:
static GStreamerFormatHelper* Instance();
~GStreamerFormatHelper();
bool CanHandleMediaType(const nsACString& aMIMEType,
const nsAString* aCodecs);
bool CanHandleContainerCaps(GstCaps* aCaps);
bool CanHandleCodecCaps(GstCaps* aCaps);
static bool IsBlacklistEnabled();
static bool IsPluginFeatureBlacklisted(GstPluginFeature *aFeature);
static GstCaps* ConvertFormatsToCaps(const char* aMIMEType,
const nsAString* aCodecs);
static void Shutdown();
private:
GStreamerFormatHelper();
char* const *CodecListFromCaps(GstCaps* aCaps);
bool HaveElementsToProcessCaps(GstCaps* aCaps);
GList* GetFactories();
static GStreamerFormatHelper* gInstance;
/* table to convert from container MIME types to GStreamer caps */
static char const *const mContainers[6][2];
/* table to convert from codec MIME types to GStreamer caps */
static char const *const mCodecs[9][2];
/*
* True iff we were able to find the proper GStreamer libs and the functions
* we need.
*/
static bool sLoadOK;
/* whitelist of supported container/codec gst caps */
GstCaps* mSupportedContainerCaps;
GstCaps* mSupportedCodecCaps;
/* list of GStreamer element factories
* Element factories are the basic types retrieved from the GStreamer
* registry, they describe all plugins and elements that GStreamer can
* create.
* This means that element factories are useful for automated element
* instancing, such as what autopluggers do,
* and for creating lists of available elements. */
GList* mFactories;
/* Storage for the default registrys feature list cookie.
* It changes every time a feature is added to or removed from the
* GStreamer registry. */
uint32_t mCookie;
};
} //namespace mozilla
#endif
+173
View File
@@ -0,0 +1,173 @@
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __APPLE__
/*
* List of symbol names we need to dlsym from the gstreamer library.
*/
GST_FUNC(LIBGSTAPP, gst_app_sink_get_type)
GST_FUNC(LIBGSTAPP, gst_app_sink_set_callbacks)
GST_FUNC(LIBGSTAPP, gst_app_src_end_of_stream)
GST_FUNC(LIBGSTAPP, gst_app_src_get_size)
GST_FUNC(LIBGSTAPP, gst_app_src_get_type)
GST_FUNC(LIBGSTAPP, gst_app_src_push_buffer)
GST_FUNC(LIBGSTAPP, gst_app_src_set_callbacks)
GST_FUNC(LIBGSTAPP, gst_app_src_set_caps)
GST_FUNC(LIBGSTAPP, gst_app_src_set_size)
GST_FUNC(LIBGSTAPP, gst_app_src_set_stream_type)
GST_FUNC(LIBGSTREAMER, gst_bin_get_by_name)
GST_FUNC(LIBGSTREAMER, gst_bin_get_type)
GST_FUNC(LIBGSTREAMER, gst_bin_iterate_recurse)
GST_FUNC(LIBGSTREAMER, gst_buffer_get_type)
GST_FUNC(LIBGSTREAMER, gst_buffer_new)
GST_FUNC(LIBGSTREAMER, gst_bus_set_sync_handler)
GST_FUNC(LIBGSTREAMER, gst_bus_timed_pop_filtered)
GST_FUNC(LIBGSTREAMER, gst_caps_append)
GST_FUNC(LIBGSTREAMER, gst_caps_can_intersect)
GST_FUNC(LIBGSTREAMER, gst_caps_from_string)
GST_FUNC(LIBGSTREAMER, gst_caps_get_size)
GST_FUNC(LIBGSTREAMER, gst_caps_get_structure)
GST_FUNC(LIBGSTREAMER, gst_caps_new_any)
GST_FUNC(LIBGSTREAMER, gst_caps_new_empty)
GST_FUNC(LIBGSTREAMER, gst_caps_new_full)
GST_FUNC(LIBGSTREAMER, gst_caps_new_simple)
GST_FUNC(LIBGSTREAMER, gst_caps_set_simple)
GST_FUNC(LIBGSTREAMER, gst_element_factory_get_static_pad_templates)
GST_FUNC(LIBGSTREAMER, gst_element_factory_get_type)
GST_FUNC(LIBGSTREAMER, gst_element_factory_make)
GST_FUNC(LIBGSTREAMER, gst_element_get_factory)
GST_FUNC(LIBGSTREAMER, gst_element_get_static_pad)
GST_FUNC(LIBGSTREAMER, gst_element_get_type)
GST_FUNC(LIBGSTREAMER, gst_element_query_convert)
GST_FUNC(LIBGSTREAMER, gst_element_query_duration)
GST_FUNC(LIBGSTREAMER, gst_element_seek_simple)
GST_FUNC(LIBGSTREAMER, gst_element_set_state)
GST_FUNC(LIBGSTREAMER, gst_flow_get_name)
GST_FUNC(LIBGSTREAMER, gst_init)
GST_FUNC(LIBGSTREAMER, gst_init_check)
GST_FUNC(LIBGSTREAMER, gst_iterator_free)
GST_FUNC(LIBGSTREAMER, gst_iterator_next)
GST_FUNC(LIBGSTREAMER, gst_message_parse_error)
GST_FUNC(LIBGSTREAMER, gst_message_type_get_name)
GST_FUNC(LIBGSTREAMER, gst_mini_object_ref)
GST_FUNC(LIBGSTREAMER, gst_mini_object_unref)
GST_FUNC(LIBGSTREAMER, gst_object_get_name)
GST_FUNC(LIBGSTREAMER, gst_object_get_parent)
GST_FUNC(LIBGSTREAMER, gst_object_unref)
GST_FUNC(LIBGSTREAMER, gst_pad_get_element_private)
GST_FUNC(LIBGSTREAMER, gst_pad_set_element_private)
GST_FUNC(LIBGSTREAMER, gst_parse_bin_from_description)
GST_FUNC(LIBGSTREAMER, gst_pipeline_get_bus)
GST_FUNC(LIBGSTREAMER, gst_pipeline_get_type)
GST_FUNC(LIBGSTREAMER, gst_plugin_feature_get_rank)
GST_FUNC(LIBGSTREAMER, gst_plugin_feature_get_type)
GST_FUNC(LIBGSTREAMER, gst_registry_feature_filter)
GST_FUNC(LIBGSTREAMER, gst_registry_get_feature_list_cookie)
GST_FUNC(LIBGSTREAMER, gst_segment_init)
GST_FUNC(LIBGSTREAMER, gst_segment_to_stream_time)
GST_FUNC(LIBGSTREAMER, gst_static_caps_get)
GST_FUNC(LIBGSTREAMER, gst_structure_copy)
GST_FUNC(LIBGSTREAMER, gst_structure_get_fraction)
GST_FUNC(LIBGSTREAMER, gst_structure_get_int)
GST_FUNC(LIBGSTREAMER, gst_structure_get_value)
GST_FUNC(LIBGSTREAMER, gst_structure_new)
GST_FUNC(LIBGSTREAMER, gst_util_uint64_scale)
#if GST_VERSION_MAJOR == 0
GST_FUNC(LIBGSTAPP, gst_app_sink_pull_buffer)
GST_FUNC(LIBGSTREAMER, gst_buffer_copy_metadata)
GST_FUNC(LIBGSTREAMER, gst_buffer_new_and_alloc)
GST_FUNC(LIBGSTREAMER, gst_caps_unref)
GST_FUNC(LIBGSTREAMER, gst_element_factory_get_klass)
GST_FUNC(LIBGSTREAMER, gst_element_get_pad)
GST_FUNC(LIBGSTREAMER, gst_event_parse_new_segment)
GST_FUNC(LIBGSTREAMER, gst_mini_object_get_type)
GST_FUNC(LIBGSTREAMER, gst_mini_object_new)
GST_FUNC(LIBGSTREAMER, gst_pad_add_event_probe)
GST_FUNC(LIBGSTREAMER, gst_pad_alloc_buffer)
GST_FUNC(LIBGSTREAMER, gst_pad_get_negotiated_caps)
GST_FUNC(LIBGSTREAMER, gst_pad_set_bufferalloc_function)
GST_FUNC(LIBGSTREAMER, gst_plugin_feature_get_name)
GST_FUNC(LIBGSTREAMER, gst_registry_get_default)
GST_FUNC(LIBGSTREAMER, gst_segment_set_newsegment)
GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_height)
GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_offset)
GST_FUNC(LIBGSTVIDEO, gst_video_format_get_component_width)
GST_FUNC(LIBGSTVIDEO, gst_video_format_get_pixel_stride)
GST_FUNC(LIBGSTVIDEO, gst_video_format_get_row_stride)
GST_FUNC(LIBGSTVIDEO, gst_video_format_parse_caps)
GST_FUNC(LIBGSTVIDEO, gst_video_parse_caps_pixel_aspect_ratio)
#else
GST_FUNC(LIBGSTAPP, gst_app_sink_pull_sample)
GST_FUNC(LIBGSTREAMER, _gst_caps_any)
GST_FUNC(LIBGSTREAMER, gst_allocator_get_type)
GST_FUNC(LIBGSTREAMER, gst_buffer_copy_into)
GST_FUNC(LIBGSTREAMER, gst_buffer_extract)
GST_FUNC(LIBGSTREAMER, gst_buffer_get_meta)
GST_FUNC(LIBGSTREAMER, gst_buffer_get_size)
GST_FUNC(LIBGSTREAMER, gst_buffer_map)
GST_FUNC(LIBGSTREAMER, gst_buffer_new_allocate)
GST_FUNC(LIBGSTREAMER, gst_buffer_n_memory)
GST_FUNC(LIBGSTREAMER, gst_buffer_peek_memory)
GST_FUNC(LIBGSTREAMER, gst_buffer_pool_acquire_buffer)
GST_FUNC(LIBGSTREAMER, gst_buffer_pool_config_set_allocator)
GST_FUNC(LIBGSTREAMER, gst_buffer_pool_config_set_params)
GST_FUNC(LIBGSTREAMER, gst_buffer_pool_get_config)
GST_FUNC(LIBGSTREAMER, gst_buffer_pool_get_type)
GST_FUNC(LIBGSTREAMER, gst_buffer_pool_is_active)
GST_FUNC(LIBGSTREAMER, gst_buffer_pool_set_active)
GST_FUNC(LIBGSTREAMER, gst_buffer_pool_set_config)
GST_FUNC(LIBGSTREAMER, gst_buffer_set_size)
GST_FUNC(LIBGSTREAMER, gst_buffer_unmap)
GST_FUNC(LIBGSTREAMER, gst_element_factory_get_metadata)
GST_FUNC(LIBGSTREAMER, gst_event_parse_segment)
GST_FUNC(LIBGSTREAMER, gst_event_type_get_name)
GST_FUNC(LIBGSTREAMER, gst_memory_init)
GST_FUNC(LIBGSTREAMER, gst_memory_map)
GST_FUNC(LIBGSTREAMER, gst_memory_unmap)
GST_FUNC(LIBGSTREAMER, gst_object_get_type)
GST_FUNC(LIBGSTREAMER, gst_pad_add_probe)
GST_FUNC(LIBGSTREAMER, gst_pad_get_current_caps)
GST_FUNC(LIBGSTREAMER, gst_pad_probe_info_get_query)
GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_meta)
GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_param)
GST_FUNC(LIBGSTREAMER, gst_query_add_allocation_pool)
GST_FUNC(LIBGSTREAMER, gst_query_parse_allocation)
GST_FUNC(LIBGSTREAMER, gst_registry_get)
GST_FUNC(LIBGSTREAMER, gst_sample_get_buffer)
GST_FUNC(LIBGSTREAMER, gst_segment_copy_into)
GST_FUNC(LIBGSTREAMER, gst_structure_free)
GST_FUNC(LIBGSTVIDEO, gst_buffer_pool_config_get_video_alignment)
GST_FUNC(LIBGSTVIDEO, gst_buffer_pool_has_option)
GST_FUNC(LIBGSTVIDEO, gst_video_buffer_pool_get_type)
GST_FUNC(LIBGSTVIDEO, gst_video_frame_map)
GST_FUNC(LIBGSTVIDEO, gst_video_frame_unmap)
GST_FUNC(LIBGSTVIDEO, gst_video_info_align)
GST_FUNC(LIBGSTVIDEO, gst_video_info_from_caps)
GST_FUNC(LIBGSTVIDEO, gst_video_info_init)
GST_FUNC(LIBGSTVIDEO, gst_video_meta_api_get_type)
GST_FUNC(LIBGSTVIDEO, gst_video_meta_map)
GST_FUNC(LIBGSTVIDEO, gst_video_meta_unmap)
#endif
/*
* Functions that have been defined in the header file. We replace them so that
* they don't try to use the global gstreamer functions.
*/
#ifdef REPLACE_FUNC
REPLACE_FUNC(gst_buffer_ref);
REPLACE_FUNC(gst_buffer_unref);
REPLACE_FUNC(gst_message_unref);
#if GST_VERSION_MAJOR == 1
REPLACE_FUNC(gst_caps_unref);
REPLACE_FUNC(gst_sample_unref);
#endif
#endif
#endif // !defined(__APPLE__)
+145
View File
@@ -0,0 +1,145 @@
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 <dlfcn.h>
#include <stdio.h>
#include "nsDebug.h"
#include "GStreamerLoader.h"
#define LIBGSTREAMER 0
#define LIBGSTAPP 1
#define LIBGSTVIDEO 2
#ifdef __OpenBSD__
#define LIB_GST_SUFFIX ".so"
#else
#define LIB_GST_SUFFIX ".so.0"
#endif
namespace mozilla {
/*
* Declare our function pointers using the types from the global gstreamer
* definitions.
*/
#define GST_FUNC(_, func) typeof(::func)* func;
#define REPLACE_FUNC(func) GST_FUNC(-1, func)
#include "GStreamerFunctionList.h"
#undef GST_FUNC
#undef REPLACE_FUNC
/*
* Redefinitions of functions that have been defined in the gstreamer headers to
* stop them calling the gstreamer functions in global scope.
*/
GstBuffer * gst_buffer_ref_impl(GstBuffer *buf);
void gst_buffer_unref_impl(GstBuffer *buf);
void gst_message_unref_impl(GstMessage *msg);
void gst_caps_unref_impl(GstCaps *caps);
#if GST_VERSION_MAJOR == 1
void gst_sample_unref_impl(GstSample *sample);
#endif
bool
load_gstreamer()
{
#ifdef __APPLE__
return true;
#endif
static bool loaded = false;
if (loaded) {
return true;
}
void *gstreamerLib = nullptr;
guint major = 0;
guint minor = 0;
guint micro, nano;
typedef typeof(::gst_version) VersionFuncType;
if (VersionFuncType *versionFunc = (VersionFuncType*)dlsym(RTLD_DEFAULT, "gst_version")) {
versionFunc(&major, &minor, &micro, &nano);
}
if (major == GST_VERSION_MAJOR && minor == GST_VERSION_MINOR) {
gstreamerLib = RTLD_DEFAULT;
} else {
gstreamerLib = dlopen("libgstreamer-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL);
}
void *handles[3] = {
gstreamerLib,
dlopen("libgstapp-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL),
dlopen("libgstvideo-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL)
};
for (size_t i = 0; i < sizeof(handles) / sizeof(handles[0]); i++) {
if (!handles[i]) {
NS_WARNING("Couldn't link gstreamer libraries");
goto fail;
}
}
#define GST_FUNC(lib, symbol) \
if (!(symbol = (typeof(symbol))dlsym(handles[lib], #symbol))) { \
NS_WARNING("Couldn't link symbol " #symbol); \
goto fail; \
}
#define REPLACE_FUNC(symbol) symbol = symbol##_impl;
#include "GStreamerFunctionList.h"
#undef GST_FUNC
#undef REPLACE_FUNC
loaded = true;
return true;
fail:
for (size_t i = 0; i < sizeof(handles) / sizeof(handles[0]); i++) {
if (handles[i] && handles[i] != RTLD_DEFAULT) {
dlclose(handles[i]);
}
}
return false;
}
GstBuffer *
gst_buffer_ref_impl(GstBuffer *buf)
{
return (GstBuffer *)gst_mini_object_ref(GST_MINI_OBJECT_CAST(buf));
}
void
gst_buffer_unref_impl(GstBuffer *buf)
{
gst_mini_object_unref(GST_MINI_OBJECT_CAST(buf));
}
void
gst_message_unref_impl(GstMessage *msg)
{
gst_mini_object_unref(GST_MINI_OBJECT_CAST(msg));
}
#if GST_VERSION_MAJOR == 1
void
gst_sample_unref_impl(GstSample *sample)
{
gst_mini_object_unref(GST_MINI_OBJECT_CAST(sample));
}
#endif
void
gst_caps_unref_impl(GstCaps *caps)
{
gst_mini_object_unref(GST_MINI_OBJECT_CAST(caps));
}
}
+53
View File
@@ -0,0 +1,53 @@
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GStreamerLoader_h_
#define GStreamerLoader_h_
#include <gst/gst.h>
#include <gst/gstbuffer.h>
#include <gst/gstelementfactory.h>
#include <gst/gststructure.h>
#include <gst/app/gstappsrc.h>
#include <gst/app/gstappsink.h>
// This include trips -Wreserved-user-defined-literal on clang. Ignoring it
// trips -Wpragmas on GCC (unknown warning), but ignoring that trips
// -Wunknown-pragmas on clang (unknown pragma).
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wreserved-user-defined-literal"
#include <gst/video/video.h>
#pragma GCC diagnostic pop
#if GST_VERSION_MAJOR == 1
#include <gst/video/gstvideometa.h>
#include <gst/video/gstvideopool.h>
#endif
namespace mozilla {
/*
* dlopens the required libraries and dlsyms the functions we need.
* Returns true on success, false otherwise.
*/
bool load_gstreamer();
/*
* Declare our extern function pointers using the types from the global
* gstreamer definitions.
*/
#define GST_FUNC(_, func) extern typeof(::func)* func;
#define REPLACE_FUNC(func) GST_FUNC(-1, func)
#include "GStreamerFunctionList.h"
#undef GST_FUNC
#undef REPLACE_FUNC
}
#undef GST_CAPS_ANY
#define GST_CAPS_ANY (*_gst_caps_any)
#endif // GStreamerLoader_h_
@@ -0,0 +1,123 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 <string.h>
#include "GStreamerReader.h"
#include "GStreamerMozVideoBuffer.h"
#include "ImageContainer.h"
namespace mozilla {
static GstMozVideoBuffer *gst_moz_video_buffer_copy(GstMozVideoBuffer* self);
static void gst_moz_video_buffer_finalize(GstMozVideoBuffer* self);
// working around GTK+ bug https://bugzilla.gnome.org/show_bug.cgi?id=723899
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
G_DEFINE_TYPE(GstMozVideoBuffer, gst_moz_video_buffer, GST_TYPE_BUFFER);
#pragma GCC diagnostic pop
static void
gst_moz_video_buffer_class_init(GstMozVideoBufferClass* klass)
{
g_return_if_fail(GST_IS_MOZ_VIDEO_BUFFER_CLASS(klass));
GstMiniObjectClass *mo_class = GST_MINI_OBJECT_CLASS(klass);
mo_class->copy =(GstMiniObjectCopyFunction)gst_moz_video_buffer_copy;
mo_class->finalize =(GstMiniObjectFinalizeFunction)gst_moz_video_buffer_finalize;
}
static void
gst_moz_video_buffer_init(GstMozVideoBuffer* self)
{
g_return_if_fail(GST_IS_MOZ_VIDEO_BUFFER(self));
}
static void
gst_moz_video_buffer_finalize(GstMozVideoBuffer* self)
{
g_return_if_fail(GST_IS_MOZ_VIDEO_BUFFER(self));
if(self->data)
g_boxed_free(GST_TYPE_MOZ_VIDEO_BUFFER_DATA, self->data);
GST_MINI_OBJECT_CLASS(gst_moz_video_buffer_parent_class)->finalize(GST_MINI_OBJECT(self));
}
static GstMozVideoBuffer*
gst_moz_video_buffer_copy(GstMozVideoBuffer* self)
{
GstMozVideoBuffer* copy;
g_return_val_if_fail(GST_IS_MOZ_VIDEO_BUFFER(self), nullptr);
copy = gst_moz_video_buffer_new();
/* we simply copy everything from our parent */
GST_BUFFER_DATA(GST_BUFFER_CAST(copy)) =
(guint8*)g_memdup(GST_BUFFER_DATA(GST_BUFFER_CAST(self)), GST_BUFFER_SIZE(GST_BUFFER_CAST(self)));
/* make sure it gets freed(even if the parent is subclassed, we return a
normal buffer) */
GST_BUFFER_MALLOCDATA(GST_BUFFER_CAST(copy)) = GST_BUFFER_DATA(GST_BUFFER_CAST(copy));
GST_BUFFER_SIZE(GST_BUFFER_CAST(copy)) = GST_BUFFER_SIZE(GST_BUFFER_CAST(self));
/* copy metadata */
gst_buffer_copy_metadata(GST_BUFFER_CAST(copy),
GST_BUFFER_CAST(self),
(GstBufferCopyFlags)GST_BUFFER_COPY_ALL);
/* copy videobuffer */
if(self->data)
copy->data = (GstMozVideoBufferData*)g_boxed_copy(GST_TYPE_MOZ_VIDEO_BUFFER_DATA, self->data);
return copy;
}
GstMozVideoBuffer*
gst_moz_video_buffer_new(void)
{
GstMozVideoBuffer *self;
self =(GstMozVideoBuffer*)gst_mini_object_new(GST_TYPE_MOZ_VIDEO_BUFFER);
self->data = nullptr;
return self;
}
void
gst_moz_video_buffer_set_data(GstMozVideoBuffer* self, GstMozVideoBufferData* data)
{
g_return_if_fail(GST_IS_MOZ_VIDEO_BUFFER(self));
self->data = data;
}
GstMozVideoBufferData*
gst_moz_video_buffer_get_data(const GstMozVideoBuffer* self)
{
g_return_val_if_fail(GST_IS_MOZ_VIDEO_BUFFER(self), nullptr);
return self->data;
}
GType
gst_moz_video_buffer_data_get_type(void)
{
static volatile gsize g_define_type_id__volatile = 0;
if(g_once_init_enter(&g_define_type_id__volatile)) {
GType g_define_type_id =
g_boxed_type_register_static(g_intern_static_string("GstMozVideoBufferData"),
(GBoxedCopyFunc)GstMozVideoBufferData::Copy,
(GBoxedFreeFunc)GstMozVideoBufferData::Free);
g_once_init_leave(&g_define_type_id__volatile, g_define_type_id);
}
return g_define_type_id__volatile;
}
}
@@ -0,0 +1,61 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __GST_MOZ_VIDEO_BUFFER_H__
#define __GST_MOZ_VIDEO_BUFFER_H__
#include <gst/gst.h>
#include "GStreamerLoader.h"
#include "MediaDecoderReader.h"
namespace mozilla {
#define GST_TYPE_MOZ_VIDEO_BUFFER_DATA (gst_moz_video_buffer_data_get_type())
#define GST_IS_MOZ_VIDEO_BUFFER_DATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MOZ_VIDEO_BUFFER_DATA))
#define GST_TYPE_MOZ_VIDEO_BUFFER (gst_moz_video_buffer_get_type())
#define GST_IS_MOZ_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MOZ_VIDEO_BUFFER))
#define GST_IS_MOZ_VIDEO_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MOZ_VIDEO_BUFFER))
#define GST_MOZ_VIDEO_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MOZ_VIDEO_BUFFER, GstMozVideoBuffer))
typedef struct _GstMozVideoBuffer GstMozVideoBuffer;
typedef struct _GstMozVideoBufferClass GstMozVideoBufferClass;
class GstMozVideoBufferData;
struct _GstMozVideoBuffer {
GstBuffer buffer;
GstMozVideoBufferData* data;
};
struct _GstMozVideoBufferClass {
GstBufferClass buffer_class;
};
GType gst_moz_video_buffer_get_type(void);
GstMozVideoBuffer* gst_moz_video_buffer_new(void);
void gst_moz_video_buffer_set_data(GstMozVideoBuffer* buf, GstMozVideoBufferData* data);
GstMozVideoBufferData* gst_moz_video_buffer_get_data(const GstMozVideoBuffer* buf);
class GstMozVideoBufferData {
public:
explicit GstMozVideoBufferData(layers::PlanarYCbCrImage* aImage) : mImage(aImage) {}
static void* Copy(void* aData) {
return new GstMozVideoBufferData(reinterpret_cast<GstMozVideoBufferData*>(aData)->mImage);
}
static void Free(void* aData) {
delete reinterpret_cast<GstMozVideoBufferData*>(aData);
}
nsRefPtr<layers::PlanarYCbCrImage> mImage;
};
GType gst_moz_video_buffer_data_get_type (void);
} // namespace mozilla
#endif /* __GST_MOZ_VIDEO_BUFFER_H__ */
@@ -0,0 +1,204 @@
#include "nsError.h"
#include "MediaDecoderStateMachine.h"
#include "AbstractMediaDecoder.h"
#include "MediaResource.h"
#include "GStreamerReader.h"
#include "GStreamerMozVideoBuffer.h"
#include "GStreamerFormatHelper.h"
#include "VideoUtils.h"
#include "mozilla/Endian.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
using mozilla::layers::PlanarYCbCrImage;
using mozilla::layers::ImageContainer;
GstFlowReturn GStreamerReader::AllocateVideoBufferCb(GstPad* aPad,
guint64 aOffset,
guint aSize,
GstCaps* aCaps,
GstBuffer** aBuf)
{
GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(gst_pad_get_element_private(aPad));
return reader->AllocateVideoBuffer(aPad, aOffset, aSize, aCaps, aBuf);
}
GstFlowReturn GStreamerReader::AllocateVideoBuffer(GstPad* aPad,
guint64 aOffset,
guint aSize,
GstCaps* aCaps,
GstBuffer** aBuf)
{
nsRefPtr<PlanarYCbCrImage> image;
return AllocateVideoBufferFull(aPad, aOffset, aSize, aCaps, aBuf, image);
}
GstFlowReturn GStreamerReader::AllocateVideoBufferFull(GstPad* aPad,
guint64 aOffset,
guint aSize,
GstCaps* aCaps,
GstBuffer** aBuf,
nsRefPtr<PlanarYCbCrImage>& aImage)
{
/* allocate an image using the container */
ImageContainer* container = mDecoder->GetImageContainer();
if (container == nullptr) {
return GST_FLOW_ERROR;
}
nsRefPtr<PlanarYCbCrImage> image =
container->CreateImage(ImageFormat::PLANAR_YCBCR).downcast<PlanarYCbCrImage>();
/* prepare a GstBuffer pointing to the underlying PlanarYCbCrImage buffer */
GstBuffer* buf = GST_BUFFER(gst_moz_video_buffer_new());
GST_BUFFER_SIZE(buf) = aSize;
/* allocate the actual YUV buffer */
GST_BUFFER_DATA(buf) = image->AllocateAndGetNewBuffer(aSize);
aImage = image;
/* create a GstMozVideoBufferData to hold the image */
GstMozVideoBufferData* bufferdata = new GstMozVideoBufferData(image);
/* Attach bufferdata to our GstMozVideoBuffer, it will take care to free it */
gst_moz_video_buffer_set_data(GST_MOZ_VIDEO_BUFFER(buf), bufferdata);
*aBuf = buf;
return GST_FLOW_OK;
}
gboolean GStreamerReader::EventProbe(GstPad* aPad, GstEvent* aEvent)
{
GstElement* parent = GST_ELEMENT(gst_pad_get_parent(aPad));
switch(GST_EVENT_TYPE(aEvent)) {
case GST_EVENT_NEWSEGMENT:
{
gboolean update;
gdouble rate;
GstFormat format;
gint64 start, stop, position;
GstSegment* segment;
/* Store the segments so we can convert timestamps to stream time, which
* is what the upper layers sync on.
*/
ReentrantMonitorAutoEnter mon(mGstThreadsMonitor);
gst_event_parse_new_segment(aEvent, &update, &rate, &format,
&start, &stop, &position);
if (parent == GST_ELEMENT(mVideoAppSink))
segment = &mVideoSegment;
else
segment = &mAudioSegment;
gst_segment_set_newsegment(segment, update, rate, format,
start, stop, position);
break;
}
case GST_EVENT_FLUSH_STOP:
/* Reset on seeks */
ResetDecode();
break;
default:
break;
}
gst_object_unref(parent);
return TRUE;
}
gboolean GStreamerReader::EventProbeCb(GstPad* aPad,
GstEvent* aEvent,
gpointer aUserData)
{
GStreamerReader* reader = reinterpret_cast<GStreamerReader*>(aUserData);
return reader->EventProbe(aPad, aEvent);
}
nsRefPtr<PlanarYCbCrImage> GStreamerReader::GetImageFromBuffer(GstBuffer* aBuffer)
{
if (!GST_IS_MOZ_VIDEO_BUFFER (aBuffer))
return nullptr;
nsRefPtr<PlanarYCbCrImage> image;
GstMozVideoBufferData* bufferdata = reinterpret_cast<GstMozVideoBufferData*>(gst_moz_video_buffer_get_data(GST_MOZ_VIDEO_BUFFER(aBuffer)));
image = bufferdata->mImage;
PlanarYCbCrImage::Data data;
data.mPicX = data.mPicY = 0;
data.mPicSize = gfx::IntSize(mPicture.width, mPicture.height);
data.mStereoMode = StereoMode::MONO;
data.mYChannel = GST_BUFFER_DATA(aBuffer);
data.mYStride = gst_video_format_get_row_stride(mFormat, 0, mPicture.width);
data.mYSize = gfx::IntSize(gst_video_format_get_component_width(mFormat, 0, mPicture.width),
gst_video_format_get_component_height(mFormat, 0, mPicture.height));
data.mYSkip = 0;
data.mCbCrStride = gst_video_format_get_row_stride(mFormat, 1, mPicture.width);
data.mCbCrSize = gfx::IntSize(gst_video_format_get_component_width(mFormat, 1, mPicture.width),
gst_video_format_get_component_height(mFormat, 1, mPicture.height));
data.mCbChannel = data.mYChannel + gst_video_format_get_component_offset(mFormat, 1,
mPicture.width, mPicture.height);
data.mCrChannel = data.mYChannel + gst_video_format_get_component_offset(mFormat, 2,
mPicture.width, mPicture.height);
data.mCbSkip = 0;
data.mCrSkip = 0;
image->SetDataNoCopy(data);
return image;
}
void GStreamerReader::CopyIntoImageBuffer(GstBuffer* aBuffer,
GstBuffer** aOutBuffer,
nsRefPtr<PlanarYCbCrImage> &aImage)
{
AllocateVideoBufferFull(nullptr, GST_BUFFER_OFFSET(aBuffer),
GST_BUFFER_SIZE(aBuffer), nullptr, aOutBuffer, aImage);
gst_buffer_copy_metadata(*aOutBuffer, aBuffer, (GstBufferCopyFlags)GST_BUFFER_COPY_ALL);
memcpy(GST_BUFFER_DATA(*aOutBuffer), GST_BUFFER_DATA(aBuffer), GST_BUFFER_SIZE(*aOutBuffer));
aImage = GetImageFromBuffer(*aOutBuffer);
}
GstCaps* GStreamerReader::BuildAudioSinkCaps()
{
GstCaps* caps;
#if MOZ_LITTLE_ENDIAN
int endianness = 1234;
#else
int endianness = 4321;
#endif
gint width;
#ifdef MOZ_SAMPLE_TYPE_FLOAT32
caps = gst_caps_from_string("audio/x-raw-float, channels={1,2}");
width = 32;
#else /* !MOZ_SAMPLE_TYPE_FLOAT32 */
caps = gst_caps_from_string("audio/x-raw-int, channels={1,2}");
width = 16;
#endif
gst_caps_set_simple(caps,
"width", G_TYPE_INT, width,
"endianness", G_TYPE_INT, endianness,
nullptr);
return caps;
}
void GStreamerReader::InstallPadCallbacks()
{
GstPad* sinkpad = gst_element_get_static_pad(GST_ELEMENT(mVideoAppSink), "sink");
gst_pad_add_event_probe(sinkpad,
G_CALLBACK(&GStreamerReader::EventProbeCb), this);
gst_pad_set_bufferalloc_function(sinkpad, GStreamerReader::AllocateVideoBufferCb);
gst_pad_set_element_private(sinkpad, this);
gst_object_unref(sinkpad);
sinkpad = gst_element_get_static_pad(GST_ELEMENT(mAudioAppSink), "sink");
gst_pad_add_event_probe(sinkpad,
G_CALLBACK(&GStreamerReader::EventProbeCb), this);
gst_object_unref(sinkpad);
}
File diff suppressed because it is too large Load Diff
+273
View File
@@ -0,0 +1,273 @@
/* 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(GStreamerReader_h_)
#define GStreamerReader_h_
#include <map>
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
#include <gst/app/gstappsink.h>
// This include trips -Wreserved-user-defined-literal on clang. Ignoring it
// trips -Wpragmas on GCC (unknown warning), but ignoring that trips
// -Wunknown-pragmas on clang (unknown pragma).
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wreserved-user-defined-literal"
#include <gst/video/video.h>
#pragma GCC diagnostic pop
#include "MediaDecoderReader.h"
#include "MediaResource.h"
#include "MP3FrameParser.h"
#include "ImageContainer.h"
#include "nsRect.h"
struct GstURIDecodeBin;
namespace mozilla {
class AbstractMediaDecoder;
class GStreamerReader : public MediaDecoderReader
{
typedef gfx::IntRect IntRect;
public:
explicit GStreamerReader(AbstractMediaDecoder* aDecoder);
virtual ~GStreamerReader();
virtual nsresult Init(MediaDecoderReader* aCloneDonor) override;
virtual nsRefPtr<ShutdownPromise> Shutdown() override;
virtual nsresult ResetDecode() override;
virtual bool DecodeAudioData() override;
virtual bool DecodeVideoFrame(bool &aKeyframeSkip,
int64_t aTimeThreshold) override;
virtual nsresult ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags) override;
virtual nsRefPtr<SeekPromise>
Seek(int64_t aTime, int64_t aEndTime) override;
virtual media::TimeIntervals GetBuffered() override;
protected:
virtual void NotifyDataArrivedInternal(uint32_t aLength,
int64_t aOffset) override;
public:
virtual bool HasAudio() override {
return mInfo.HasAudio();
}
virtual bool HasVideo() override {
return mInfo.HasVideo();
}
layers::ImageContainer* GetImageContainer() { return mDecoder->GetImageContainer(); }
virtual bool IsMediaSeekable() override;
private:
void ReadAndPushData(guint aLength);
nsRefPtr<layers::PlanarYCbCrImage> GetImageFromBuffer(GstBuffer* aBuffer);
void CopyIntoImageBuffer(GstBuffer *aBuffer, GstBuffer** aOutBuffer, nsRefPtr<layers::PlanarYCbCrImage> &image);
GstCaps* BuildAudioSinkCaps();
void InstallPadCallbacks();
#if GST_VERSION_MAJOR >= 1
void ImageDataFromVideoFrame(GstVideoFrame *aFrame, layers::PlanarYCbCrImage::Data *aData);
#endif
/* Called once the pipeline is setup to check that the stream only contains
* supported formats
*/
nsresult CheckSupportedFormats();
/* Gst callbacks */
static GstBusSyncReply ErrorCb(GstBus *aBus, GstMessage *aMessage, gpointer aUserData);
GstBusSyncReply Error(GstBus *aBus, GstMessage *aMessage);
/*
* We attach this callback to playbin so that when uridecodebin is
* constructed, we can then list for its autoplug-sort signal to blacklist
* the elements it can construct.
*/
static void ElementAddedCb(GstBin *aPlayBin,
GstElement *aElement,
gpointer aUserData);
/*
* Called on the autoplug-sort signal emitted by uridecodebin for filtering
* the elements it uses.
*/
static GValueArray *ElementFilterCb(GstURIDecodeBin *aBin,
GstPad *aPad,
GstCaps *aCaps,
GValueArray *aFactories,
gpointer aUserData);
GValueArray *ElementFilter(GstURIDecodeBin *aBin,
GstPad *aPad,
GstCaps *aCaps,
GValueArray *aFactories);
/* Called on the source-setup signal emitted by playbin. Used to
* configure appsrc .
*/
static void PlayBinSourceSetupCb(GstElement* aPlayBin,
GParamSpec* pspec,
gpointer aUserData);
void PlayBinSourceSetup(GstAppSrc* aSource);
/* Called from appsrc when we need to read more data from the resource */
static void NeedDataCb(GstAppSrc* aSrc, guint aLength, gpointer aUserData);
void NeedData(GstAppSrc* aSrc, guint aLength);
/* Called when appsrc has enough data and we can stop reading */
static void EnoughDataCb(GstAppSrc* aSrc, gpointer aUserData);
void EnoughData(GstAppSrc* aSrc);
/* Called when a seek is issued on the pipeline */
static gboolean SeekDataCb(GstAppSrc* aSrc,
guint64 aOffset,
gpointer aUserData);
gboolean SeekData(GstAppSrc* aSrc, guint64 aOffset);
/* Called when events reach the sinks. See inline comments */
#if GST_VERSION_MAJOR == 1
static GstPadProbeReturn EventProbeCb(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData);
GstPadProbeReturn EventProbe(GstPad *aPad, GstEvent *aEvent);
#else
static gboolean EventProbeCb(GstPad* aPad, GstEvent* aEvent, gpointer aUserData);
gboolean EventProbe(GstPad* aPad, GstEvent* aEvent);
#endif
/* Called when the video part of the pipeline allocates buffers. Used to
* provide PlanarYCbCrImage backed GstBuffers to the pipeline so that a memory
* copy can be avoided when handling YUV buffers from the pipeline to the gfx
* side.
*/
#if GST_VERSION_MAJOR == 1
static GstPadProbeReturn QueryProbeCb(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData);
GstPadProbeReturn QueryProbe(GstPad *aPad, GstPadProbeInfo *aInfo, gpointer aUserData);
#else
static GstFlowReturn AllocateVideoBufferCb(GstPad* aPad, guint64 aOffset, guint aSize,
GstCaps* aCaps, GstBuffer** aBuf);
GstFlowReturn AllocateVideoBufferFull(GstPad* aPad, guint64 aOffset, guint aSize,
GstCaps* aCaps, GstBuffer** aBuf, nsRefPtr<layers::PlanarYCbCrImage>& aImage);
GstFlowReturn AllocateVideoBuffer(GstPad* aPad, guint64 aOffset, guint aSize,
GstCaps* aCaps, GstBuffer** aBuf);
#endif
/* Called when the pipeline is prerolled, that is when at start or after a
* seek, the first audio and video buffers are queued in the sinks.
*/
static GstFlowReturn NewPrerollCb(GstAppSink* aSink, gpointer aUserData);
void VideoPreroll();
void AudioPreroll();
/* Called when buffers reach the sinks */
static GstFlowReturn NewBufferCb(GstAppSink* aSink, gpointer aUserData);
void NewVideoBuffer();
void NewAudioBuffer();
/* Called at end of stream, when decoding has finished */
static void EosCb(GstAppSink* aSink, gpointer aUserData);
/* Notifies that a sink will no longer receive any more data. If nullptr
* is passed to this, we'll assume all streams have reached EOS (for example
* an error has occurred). */
void Eos(GstAppSink* aSink = nullptr);
/* Called when an element is added inside playbin. We use it to find the
* decodebin instance.
*/
static void PlayElementAddedCb(GstBin *aBin, GstElement *aElement,
gpointer *aUserData);
/* Called during decoding, to decide whether a (sub)stream should be decoded or
* ignored */
static bool ShouldAutoplugFactory(GstElementFactory* aFactory, GstCaps* aCaps);
/* Called by decodebin during autoplugging. We use it to apply our
* container/codec blacklist.
*/
static GValueArray* AutoplugSortCb(GstElement* aElement,
GstPad* aPad, GstCaps* aCaps,
GValueArray* aFactories);
// Try to find MP3 headers in this stream using our MP3 frame parser.
nsresult ParseMP3Headers();
// Get the length of the stream, excluding any metadata we have ignored at the
// start of the stream: ID3 headers, for example.
int64_t GetDataLength();
// Use our own MP3 parser here, largely for consistency with other platforms.
MP3FrameParser mMP3FrameParser;
// The byte position in the stream where the actual media (ignoring, for
// example, ID3 tags) starts.
uint64_t mDataOffset;
// We want to be able to decide in |ReadMetadata| whether or not we use the
// duration from the MP3 frame parser, as this backend supports more than just
// MP3. But |NotifyDataArrived| can update the duration and is often called
// _before_ |ReadMetadata|. This flag stops the former from using the parser
// duration until we are sure we want to.
bool mUseParserDuration;
int64_t mLastParserDuration;
#if GST_VERSION_MAJOR >= 1
GstAllocator *mAllocator;
GstBufferPool *mBufferPool;
GstVideoInfo mVideoInfo;
#endif
GstElement* mPlayBin;
GstBus* mBus;
GstAppSrc* mSource;
/* video sink bin */
GstElement* mVideoSink;
/* the actual video app sink */
GstAppSink* mVideoAppSink;
/* audio sink bin */
GstElement* mAudioSink;
/* the actual audio app sink */
GstAppSink* mAudioAppSink;
GstVideoFormat mFormat;
IntRect mPicture;
int mVideoSinkBufferCount;
int mAudioSinkBufferCount;
GstAppSrcCallbacks mSrcCallbacks;
GstAppSinkCallbacks mSinkCallbacks;
/* monitor used to synchronize access to shared state between gstreamer
* threads and other gecko threads */
ReentrantMonitor mGstThreadsMonitor;
/* video and audio segments we use to convert absolute timestamps to [0,
* stream_duration]. They're set when the pipeline is started or after a seek.
* Concurrent access guarded with mGstThreadsMonitor.
*/
GstSegment mVideoSegment;
GstSegment mAudioSegment;
/* bool used to signal when gst has detected the end of stream and
* DecodeAudioData and DecodeVideoFrame should not expect any more data
*/
bool mReachedAudioEos;
bool mReachedVideoEos;
#if GST_VERSION_MAJOR >= 1
bool mConfigureAlignment;
#endif
int fpsNum;
int fpsDen;
MediaResourceIndex mResource;
NotifyDataArrivedFilter mFilter;
};
} // namespace mozilla
#endif
+38
View File
@@ -0,0 +1,38 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
EXPORTS += [
'GStreamerDecoder.h',
'GStreamerFormatHelper.h',
'GStreamerLoader.h',
'GStreamerReader.h',
]
SOURCES += [
'GStreamerDecoder.cpp',
'GStreamerFormatHelper.cpp',
'GStreamerLoader.cpp',
'GStreamerReader.cpp',
]
if CONFIG['GST_API_VERSION'] == '1.0':
SOURCES += [
'GStreamerAllocator.cpp',
]
else:
SOURCES += [
'GStreamerMozVideoBuffer.cpp',
'GStreamerReader-0.10.cpp',
]
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/dom/base',
'/dom/html',
]
CFLAGS += CONFIG['GSTREAMER_CFLAGS']
CXXFLAGS += CONFIG['GSTREAMER_CFLAGS']
+3
View File
@@ -46,6 +46,9 @@ if CONFIG['MOZ_WAVE']:
if CONFIG['MOZ_WEBM']:
DIRS += ['webm']
if CONFIG['MOZ_GSTREAMER']:
DIRS += ['gstreamer']
if CONFIG['MOZ_DIRECTSHOW']:
DIRS += ['directshow']
+32 -47
View File
@@ -526,27 +526,28 @@ void
MediaCodecReader::NotifyDataArrivedInternal(uint32_t aLength,
int64_t aOffset)
{
nsRefPtr<MediaByteBuffer> bytes =
mDecoder->GetResource()->MediaReadAt(aOffset, aLength);
NS_ENSURE_TRUE_VOID(bytes);
MonitorAutoLock monLock(mParserMonitor);
if (mNextParserPosition == mParsedDataLength &&
mNextParserPosition >= aOffset &&
mNextParserPosition <= aOffset + aLength) {
// No pending parsing runnable currently. And available data are adjacent to
// parsed data.
int64_t shift = mNextParserPosition - aOffset;
const char* buffer = reinterpret_cast<const char*>(bytes->Elements()) + shift;
uint32_t length = aLength - shift;
int64_t offset = mNextParserPosition;
if (length > 0) {
MonitorAutoUnlock monUnlock(mParserMonitor);
ParseDataSegment(buffer, length, offset);
IntervalSet<int64_t> intervals = mFilter.NotifyDataArrived(aLength, aOffset);
for (const auto& interval : intervals) {
nsRefPtr<MediaByteBuffer> bytes =
mDecoder->GetResource()->MediaReadAt(interval.mStart, interval.Length());
MonitorAutoLock monLock(mParserMonitor);
if (mNextParserPosition == mParsedDataLength &&
mNextParserPosition >= interval.mStart &&
mNextParserPosition <= interval.mEnd) {
// No pending parsing runnable currently. And available data are adjacent to
// parsed data.
int64_t shift = mNextParserPosition - interval.mStart;
const char* buffer = reinterpret_cast<const char*>(bytes->Elements()) + shift;
uint32_t length = interval.Length() - shift;
int64_t offset = mNextParserPosition;
if (length > 0) {
MonitorAutoUnlock monUnlock(mParserMonitor);
ParseDataSegment(buffer, length, offset);
}
mParseDataFromCache = false;
mParsedDataLength = offset + length;
mNextParserPosition = mParsedDataLength;
}
mParseDataFromCache = false;
mParsedDataLength = offset + length;
mNextParserPosition = mParsedDataLength;
}
}
@@ -847,32 +848,6 @@ MediaCodecReader::WaitFenceAndReleaseOutputBuffer()
}
}
PLDHashOperator
MediaCodecReader::ReleaseTextureClient(TextureClient* aClient,
size_t& aIndex,
void* aUserArg)
{
nsRefPtr<MediaCodecReader> reader = static_cast<MediaCodecReader*>(aUserArg);
MOZ_ASSERT(reader, "reader should not be nullptr in ReleaseTextureClient()");
return reader->ReleaseTextureClient(aClient, aIndex);
}
PLDHashOperator
MediaCodecReader::ReleaseTextureClient(TextureClient* aClient,
size_t& aIndex)
{
MOZ_ASSERT(aClient, "TextureClient should be a valid pointer");
aClient->ClearRecycleCallback();
if (mVideoTrack.mCodec != nullptr) {
mVideoTrack.mCodec->releaseOutputBuffer(aIndex);
}
return PL_DHASH_REMOVE;
}
void
MediaCodecReader::ReleaseAllTextureClients()
{
@@ -884,7 +859,17 @@ MediaCodecReader::ReleaseAllTextureClients()
}
printf_stderr("All TextureClients should be released already");
mTextureClientIndexes.Enumerate(MediaCodecReader::ReleaseTextureClient, this);
for (auto iter = mTextureClientIndexes.Iter(); !iter.Done(); iter.Next()) {
TextureClient* client = iter.Key();
size_t& index = iter.Data();
client->ClearRecycleCallback();
if (mVideoTrack.mCodec != nullptr) {
mVideoTrack.mCodec->releaseOutputBuffer(index);
}
iter.Remove();
}
mTextureClientIndexes.Clear();
}
+7 -6
View File
@@ -27,6 +27,8 @@
#include <ui/Fence.h>
#endif
#include "MP3FrameParser.h"
namespace android {
struct ALooper;
struct AMessage;
@@ -264,10 +266,12 @@ private:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SignalObject)
SignalObject(const char* aName);
~SignalObject();
void Wait();
void Signal();
protected:
~SignalObject();
private:
// Forbidden
SignalObject() = delete;
@@ -395,11 +399,6 @@ private:
void WaitFenceAndReleaseOutputBuffer();
void ReleaseRecycledTextureClients();
static PLDHashOperator ReleaseTextureClient(TextureClient* aClient,
size_t& aIndex,
void* aUserArg);
PLDHashOperator ReleaseTextureClient(TextureClient* aClient,
size_t& aIndex);
void ReleaseAllTextureClients();
@@ -439,6 +438,8 @@ private:
FenceHandle mReleaseFence;
};
nsTArray<ReleaseItem> mPendingReleaseItems;
NotifyDataArrivedFilter mFilter;
};
} // namespace mozilla
+14 -11
View File
@@ -474,18 +474,21 @@ void MediaOmxReader::NotifyDataArrivedInternal(uint32_t aLength, int64_t aOffset
return;
}
nsRefPtr<MediaByteBuffer> bytes =
mDecoder->GetResource()->MediaReadAt(aOffset, aLength);
NS_ENSURE_TRUE_VOID(bytes);
mMP3FrameParser.Parse(bytes->Elements(), aLength, aOffset);
if (!mMP3FrameParser.IsMP3()) {
return;
}
IntervalSet<int64_t> intervals = mFilter.NotifyDataArrived(aLength, aOffset);
for (const auto& interval : intervals) {
nsRefPtr<MediaByteBuffer> bytes =
mDecoder->GetResource()->MediaReadAt(interval.mStart, interval.Length());
NS_ENSURE_TRUE_VOID(bytes);
mMP3FrameParser.Parse(bytes->Elements(), interval.Length(), interval.mStart);
if (!mMP3FrameParser.IsMP3()) {
return;
}
int64_t duration = mMP3FrameParser.GetDuration();
if (duration != mLastParserDuration) {
mLastParserDuration = duration;
decoder->DispatchUpdateEstimatedMediaDuration(mLastParserDuration);
int64_t duration = mMP3FrameParser.GetDuration();
if (duration != mLastParserDuration) {
mLastParserDuration = duration;
decoder->DispatchUpdateEstimatedMediaDuration(mLastParserDuration);
}
}
}
+2
View File
@@ -128,6 +128,8 @@ private:
int64_t ProcessCachedData(int64_t aOffset);
already_AddRefed<AbstractMediaDecoder> SafeGetDecoder();
NotifyDataArrivedFilter mFilter;
};
} // namespace mozilla
+11 -16
View File
@@ -83,26 +83,21 @@ class OriginKeyStore : public nsISupports
return NS_OK;
}
static PLDHashOperator
HashCleaner(const nsACString& aOrigin, nsAutoPtr<OriginKey>& aOriginKey,
void *aUserArg)
{
OriginKey* since = static_cast<OriginKey*>(aUserArg);
LOG((((aOriginKey->mSecondsStamp >= since->mSecondsStamp)?
"%s: REMOVE %lld >= %lld" :
"%s: KEEP %lld < %lld"),
__FUNCTION__, aOriginKey->mSecondsStamp, since->mSecondsStamp));
return (aOriginKey->mSecondsStamp >= since->mSecondsStamp)?
PL_DHASH_REMOVE : PL_DHASH_NEXT;
}
void Clear(int64_t aSinceWhen)
{
// Avoid int64_t* <-> void* casting offset
OriginKey since(nsCString(), aSinceWhen / PR_USEC_PER_SEC);
mKeys.Enumerate(HashCleaner, &since);
for (auto iter = mKeys.Iter(); !iter.Done(); iter.Next()) {
nsAutoPtr<OriginKey>& originKey = iter.Data();
LOG((((originKey->mSecondsStamp >= since.mSecondsStamp)?
"%s: REMOVE %lld >= %lld" :
"%s: KEEP %lld < %lld"),
__FUNCTION__, originKey->mSecondsStamp, since.mSecondsStamp));
if (originKey->mSecondsStamp >= since.mSecondsStamp) {
iter.Remove();
}
}
mPersistCount = 0;
}
@@ -141,25 +141,6 @@ MediaSystemResourceService::ReleaseResource(media::MediaSystemResourceManagerPar
UpdateRequests(aResourceType);
}
struct ReleaseResourceData
{
MediaSystemResourceService* mSelf;
media::MediaSystemResourceManagerParent* mParent;
};
/*static*/PLDHashOperator
MediaSystemResourceService::ReleaseResourceForKey(const uint32_t& aKey,
nsAutoPtr<MediaSystemResource>& aData,
void* aClosure)
{
ReleaseResourceData* closure = static_cast<ReleaseResourceData*>(aClosure);
closure->mSelf->RemoveRequests(closure->mParent, static_cast<MediaSystemResourceType>(aKey));
closure->mSelf->UpdateRequests(static_cast<MediaSystemResourceType>(aKey));
return PLDHashOperator::PL_DHASH_NEXT;
}
void
MediaSystemResourceService::ReleaseResource(media::MediaSystemResourceManagerParent* aParent)
{
@@ -169,8 +150,11 @@ MediaSystemResourceService::ReleaseResource(media::MediaSystemResourceManagerPar
return;
}
ReleaseResourceData data = { this, aParent };
mResources.Enumerate(ReleaseResourceForKey, &data);
for (auto iter = mResources.Iter(); !iter.Done(); iter.Next()) {
const uint32_t& key = iter.Key();
RemoveRequests(aParent, static_cast<MediaSystemResourceType>(key));
UpdateRequests(static_cast<MediaSystemResourceType>(key));
}
}
void
@@ -77,10 +77,6 @@ private:
void UpdateRequests(MediaSystemResourceType aResourceType);
static PLDHashOperator ReleaseResourceForKey(const uint32_t& aKey,
nsAutoPtr<MediaSystemResource>& aData,
void* aClosure);
bool mDestroyed;
nsClassHashtable<nsUint32HashKey, MediaSystemResource> mResources;
@@ -495,40 +495,8 @@ nsPicoService::GetServiceType(SpeechServiceType* aServiceType)
return NS_OK;
}
struct VoiceTraverserData
{
nsPicoService* mService;
nsSynthVoiceRegistry* mRegistry;
};
// private methods
static PLDHashOperator
PicoAddVoiceTraverser(const nsAString& aUri,
nsRefPtr<PicoVoice>& aVoice,
void* aUserArg)
{
// If we are missing either a language or a voice resource, it is invalid.
if (aVoice->mTaFile.IsEmpty() || aVoice->mSgFile.IsEmpty()) {
return PL_DHASH_REMOVE;
}
VoiceTraverserData* data = static_cast<VoiceTraverserData*>(aUserArg);
nsAutoString name;
name.AssignLiteral("Pico ");
name.Append(aVoice->mLanguage);
// This service is multi-threaded and can handle more than one utterance at a
// time before previous utterances end. So, aQueuesUtterances == false
DebugOnly<nsresult> rv =
data->mRegistry->AddVoice(
data->mService, aUri, name, aVoice->mLanguage, true, false);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to add voice");
return PL_DHASH_NEXT;
}
void
nsPicoService::Init()
{
@@ -608,8 +576,28 @@ nsPicoService::Init()
void
nsPicoService::RegisterVoices()
{
VoiceTraverserData data = { this, nsSynthVoiceRegistry::GetInstance() };
mVoices.Enumerate(PicoAddVoiceTraverser, &data);
nsSynthVoiceRegistry* registry = nsSynthVoiceRegistry::GetInstance();
for (auto iter = mVoices.Iter(); !iter.Done(); iter.Next()) {
const nsAString& uri = iter.Key();
nsRefPtr<PicoVoice>& voice = iter.Data();
// If we are missing either a language or a voice resource, it is invalid.
if (voice->mTaFile.IsEmpty() || voice->mSgFile.IsEmpty()) {
iter.Remove();
continue;
}
nsAutoString name;
name.AssignLiteral("Pico ");
name.Append(voice->mLanguage);
// This service is multi-threaded and can handle more than one utterance at a
// time before previous utterances end. So, aQueuesUtterances == false
DebugOnly<nsresult> rv =
registry->AddVoice(this, uri, name, voice->mLanguage, true, false);
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to add voice");
}
mInitialized = true;
}
+1 -1
View File
@@ -235,7 +235,7 @@ SVGFEImageElement::GetPrimitiveDescription(nsSVGFilterInstance* aInstance,
Matrix TM = viewBoxTM;
TM.PostTranslate(aFilterSubregion.x, aFilterSubregion.y);
Filter filter = ToFilter(nsLayoutUtils::GetGraphicsFilterForFrame(frame));
Filter filter = nsLayoutUtils::GetGraphicsFilterForFrame(frame);
FilterPrimitiveDescription descr(PrimitiveType::Image);
descr.Attributes().Set(eImageFilter, (uint32_t)filter);
+2
View File
@@ -119,6 +119,8 @@ GfxFilterToCairoFilter(Filter filter)
return CAIRO_FILTER_BILINEAR;
case Filter::POINT:
return CAIRO_FILTER_NEAREST;
default:
MOZ_CRASH("bad filter");
}
return CAIRO_FILTER_BILINEAR;
+25 -13
View File
@@ -184,7 +184,8 @@ AppendEllipseToPath(PathBuilder* aPathBuilder,
bool
SnapLineToDevicePixelsForStroking(Point& aP1, Point& aP2,
const DrawTarget& aDrawTarget)
const DrawTarget& aDrawTarget,
Float aLineWidth)
{
Matrix mat = aDrawTarget.GetTransform();
if (mat.HasNonTranslation()) {
@@ -199,14 +200,21 @@ SnapLineToDevicePixelsForStroking(Point& aP1, Point& aP2,
p2.Round();
p1 -= mat.GetTranslation(); // back into user space
p2 -= mat.GetTranslation();
if (aP1.x == aP2.x) {
// snap vertical line, adding 0.5 to align it to be mid-pixel:
aP1 = p1 + Point(0.5, 0);
aP2 = p2 + Point(0.5, 0);
} else {
// snap horizontal line, adding 0.5 to align it to be mid-pixel:
aP1 = p1 + Point(0, 0.5);
aP2 = p2 + Point(0, 0.5);
aP1 = p1;
aP2 = p2;
bool lineWidthIsOdd = (int(aLineWidth) % 2) == 1;
if (lineWidthIsOdd) {
if (aP1.x == aP2.x) {
// snap vertical line, adding 0.5 to align it to be mid-pixel:
aP1 += Point(0.5, 0);
aP2 += Point(0.5, 0);
} else {
// snap horizontal line, adding 0.5 to align it to be mid-pixel:
aP1 += Point(0, 0.5);
aP2 += Point(0, 0.5);
}
}
return true;
}
@@ -222,22 +230,26 @@ StrokeSnappedEdgesOfRect(const Rect& aRect, DrawTarget& aDrawTarget,
Point p1 = aRect.TopLeft();
Point p2 = aRect.BottomLeft();
SnapLineToDevicePixelsForStroking(p1, p2, aDrawTarget);
SnapLineToDevicePixelsForStroking(p1, p2, aDrawTarget,
aStrokeOptions.mLineWidth);
aDrawTarget.StrokeLine(p1, p2, aColor, aStrokeOptions);
p1 = aRect.BottomLeft();
p2 = aRect.BottomRight();
SnapLineToDevicePixelsForStroking(p1, p2, aDrawTarget);
SnapLineToDevicePixelsForStroking(p1, p2, aDrawTarget,
aStrokeOptions.mLineWidth);
aDrawTarget.StrokeLine(p1, p2, aColor, aStrokeOptions);
p1 = aRect.TopLeft();
p2 = aRect.TopRight();
SnapLineToDevicePixelsForStroking(p1, p2, aDrawTarget);
SnapLineToDevicePixelsForStroking(p1, p2, aDrawTarget,
aStrokeOptions.mLineWidth);
aDrawTarget.StrokeLine(p1, p2, aColor, aStrokeOptions);
p1 = aRect.TopRight();
p2 = aRect.BottomRight();
SnapLineToDevicePixelsForStroking(p1, p2, aDrawTarget);
SnapLineToDevicePixelsForStroking(p1, p2, aDrawTarget,
aStrokeOptions.mLineWidth);
aDrawTarget.StrokeLine(p1, p2, aColor, aStrokeOptions);
}
+2 -1
View File
@@ -300,7 +300,8 @@ inline already_AddRefed<Path> MakePathForEllipse(const DrawTarget& aDrawTarget,
* false.
*/
GFX2D_API bool SnapLineToDevicePixelsForStroking(Point& aP1, Point& aP2,
const DrawTarget& aDrawTarget);
const DrawTarget& aDrawTarget,
Float aLineWidth);
/**
* This function paints each edge of aRect separately, snapping the edges using
+2 -1
View File
@@ -192,7 +192,8 @@ enum class AntialiasMode : int8_t {
enum class Filter : int8_t {
GOOD,
LINEAR,
POINT
POINT,
SENTINEL // one past the last valid value
};
enum class PatternType : int8_t {
+1 -1
View File
@@ -270,7 +270,7 @@ TextureImage::TextureImage(const gfx::IntSize& aSize,
: mSize(aSize)
, mWrapMode(aWrapMode)
, mContentType(aContentType)
, mFilter(GraphicsFilter::FILTER_GOOD)
, mFilter(Filter::GOOD)
, mFlags(aFlags)
{}
+2 -3
View File
@@ -11,7 +11,6 @@
#include "nsTArray.h"
#include "gfxTypes.h"
#include "GLContextTypes.h"
#include "GraphicsFilter.h"
#include "mozilla/gfx/Rect.h"
#include "mozilla/RefPtr.h"
@@ -199,7 +198,7 @@ public:
virtual bool InUpdate() const = 0;
GLenum GetWrapMode() const { return mWrapMode; }
void SetFilter(GraphicsFilter aFilter) { mFilter = aFilter; }
void SetFilter(gfx::Filter aFilter) { mFilter = aFilter; }
protected:
friend class GLContext;
@@ -224,7 +223,7 @@ protected:
GLenum mWrapMode;
ContentType mContentType;
gfx::SurfaceFormat mTextureFormat;
GraphicsFilter mFilter;
gfx::Filter mFilter;
Flags mFlags;
};
+7
View File
@@ -21,6 +21,7 @@ typedef XID GLXContextID;
typedef XID GLXWindow;
typedef XID GLXPbuffer;
// end of stuff from glx.h
#include "prenv.h"
struct PRLibrary;
class gfxASurface;
@@ -108,6 +109,12 @@ public:
bool SupportsTextureFromPixmap(gfxASurface* aSurface);
bool IsATI() { return mIsATI; }
bool GLXVersionCheck(int aMajor, int aMinor);
bool UseSurfaceSharing() {
// Disable surface sharing due to issues with compatible FBConfigs on
// NVIDIA drivers as described in bug 1193015.
static bool useSharing = PR_GetEnv("MOZ_GLX_USE_SURFACE_SHARING");
return mUseTextureFromPixmap && useSharing;
}
private:
+39 -6
View File
@@ -14,12 +14,12 @@
#include <stdint.h>
#include "mozilla/gfx/Matrix.h"
#include "GraphicsFilter.h"
#include "gfxPoint.h"
#include "gfxRect.h"
#include "nsRect.h"
#include "nsRegion.h"
#include "gfxTypes.h"
#include "mozilla/layers/AsyncDragMetrics.h"
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/CompositorTypes.h"
#include "FrameMetrics.h"
@@ -33,7 +33,6 @@
namespace mozilla {
typedef gfxImageFormat PixelFormat;
typedef ::GraphicsFilter GraphicsFilterType;
} // namespace mozilla
@@ -206,11 +205,11 @@ struct ParamTraits<gfxSurfaceType>
{};
template <>
struct ParamTraits<mozilla::GraphicsFilterType>
struct ParamTraits<mozilla::gfx::Filter>
: public ContiguousEnumSerializer<
mozilla::GraphicsFilterType,
GraphicsFilter::FILTER_FAST,
GraphicsFilter::FILTER_SENTINEL>
mozilla::gfx::Filter,
mozilla::gfx::Filter::GOOD,
mozilla::gfx::Filter::SENTINEL>
{};
template <>
@@ -1098,6 +1097,40 @@ struct ParamTraits<mozilla::layers::EventRegionsOverride>
mozilla::layers::EventRegionsOverride::ALL_BITS>
{};
template<>
struct ParamTraits<mozilla::layers::AsyncDragMetrics::DragDirection>
: public ContiguousEnumSerializer<
mozilla::layers::AsyncDragMetrics::DragDirection,
mozilla::layers::AsyncDragMetrics::DragDirection::NONE,
mozilla::layers::AsyncDragMetrics::DragDirection::SENTINEL>
{};
template<>
struct ParamTraits<mozilla::layers::AsyncDragMetrics>
{
typedef mozilla::layers::AsyncDragMetrics paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mViewId);
WriteParam(aMsg, aParam.mPresShellId);
WriteParam(aMsg, aParam.mDragStartSequenceNumber);
WriteParam(aMsg, aParam.mScrollbarDragOffset);
WriteParam(aMsg, aParam.mScrollTrack);
WriteParam(aMsg, aParam.mDirection);
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
return (ReadParam(aMsg, aIter, &aResult->mViewId) &&
ReadParam(aMsg, aIter, &aResult->mPresShellId) &&
ReadParam(aMsg, aIter, &aResult->mDragStartSequenceNumber) &&
ReadParam(aMsg, aIter, &aResult->mScrollbarDragOffset) &&
ReadParam(aMsg, aIter, &aResult->mScrollTrack) &&
ReadParam(aMsg, aIter, &aResult->mDirection));
}
};
} /* namespace IPC */
#endif /* __GFXMESSAGEUTILS_H__ */
+1 -1
View File
@@ -14,7 +14,7 @@ namespace mozilla {
namespace layers {
ImageLayer::ImageLayer(LayerManager* aManager, void* aImplData)
: Layer(aManager, aImplData), mFilter(GraphicsFilter::FILTER_GOOD)
: Layer(aManager, aImplData), mFilter(gfx::Filter::GOOD)
, mScaleMode(ScaleMode::SCALE_NONE), mDisallowBigImage(false)
{}
+3 -4
View File
@@ -7,7 +7,6 @@
#define GFX_IMAGELAYER_H
#include "Layers.h" // for Layer, etc
#include "GraphicsFilter.h" // for GraphicsFilter
#include "mozilla/gfx/BaseSize.h" // for BaseSize
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/layers/LayersTypes.h"
@@ -39,7 +38,7 @@ public:
* CONSTRUCTION PHASE ONLY
* Set the filter used to resample this image if necessary.
*/
void SetFilter(GraphicsFilter aFilter)
void SetFilter(gfx::Filter aFilter)
{
if (mFilter != aFilter) {
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Filter", this));
@@ -63,7 +62,7 @@ public:
ImageContainer* GetContainer() { return mContainer; }
GraphicsFilter GetFilter() { return mFilter; }
gfx::Filter GetFilter() { return mFilter; }
const gfx::IntSize& GetScaleToSize() { return mScaleToSize; }
ScaleMode GetScaleMode() { return mScaleMode; }
@@ -95,7 +94,7 @@ protected:
virtual void DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) override;
nsRefPtr<ImageContainer> mContainer;
GraphicsFilter mFilter;
gfx::Filter mFilter;
gfx::IntSize mScaleToSize;
ScaleMode mScaleMode;
bool mDisallowBigImage;
+23
View File
@@ -364,6 +364,29 @@ public:
return EventRegionsOverride::NoOverride;
}
Layer::ScrollDirection GetScrollbarDirection() const
{
MOZ_ASSERT(IsValid());
return mLayer->GetScrollbarDirection();
}
FrameMetrics::ViewID GetScrollbarTargetContainerId() const
{
MOZ_ASSERT(IsValid());
return mLayer->GetScrollbarTargetContainerId();
}
int32_t GetScrollbarSize() const
{
if (GetScrollbarDirection() == Layer::VERTICAL) {
return mLayer->GetVisibleRegion().GetBounds().height;
} else {
return mLayer->GetVisibleRegion().GetBounds().width;
}
}
// Expose an opaque pointer to the layer. Mostly used for printf
// purposes. This is not intended to be a general-purpose accessor
// for the underlying layer.
+17 -7
View File
@@ -10,7 +10,6 @@
#include "ImageLayers.h" // for ImageLayer, etc
#include "Layers.h" // for Layer, ContainerLayer, etc
#include "Units.h" // for ParentLayerIntRect
#include "GraphicsFilter.h" // for GraphicsFilter
#include "gfxRect.h" // for gfxRect
#include "gfxUtils.h" // for gfxUtils
#include "mozilla/gfx/BaseSize.h" // for BaseSize
@@ -403,9 +402,14 @@ struct ImageLayerProperties : public LayerPropertiesBase
, mFilter(aImage->GetFilter())
, mScaleToSize(aImage->GetScaleToSize())
, mScaleMode(aImage->GetScaleMode())
, mLastProducerID(-1)
, mLastFrameID(-1)
, mIsMask(aIsMask)
{
mFrameID = mImageHost ? mImageHost->GetFrameID() : -1;
if (mImageHost) {
mLastProducerID = mImageHost->GetLastProducerID();
mLastFrameID = mImageHost->GetLastFrameID();
}
}
virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback,
@@ -427,7 +431,8 @@ struct ImageLayerProperties : public LayerPropertiesBase
mScaleToSize != imageLayer->GetScaleToSize() ||
mScaleMode != imageLayer->GetScaleMode() ||
host != mImageHost ||
(host && host->GetFrameID() != mFrameID)) {
(host && host->GetProducerID() != mLastProducerID) ||
(host && host->GetFrameID() != mLastFrameID)) {
aGeometryChanged = true;
if (mIsMask) {
@@ -451,10 +456,11 @@ struct ImageLayerProperties : public LayerPropertiesBase
nsRefPtr<ImageContainer> mContainer;
nsRefPtr<ImageHost> mImageHost;
GraphicsFilter mFilter;
Filter mFilter;
gfx::IntSize mScaleToSize;
int32_t mFrameID;
ScaleMode mScaleMode;
int32_t mLastProducerID;
int32_t mLastFrameID;
bool mIsMask;
};
@@ -475,11 +481,15 @@ CloneLayerTreePropertiesInternal(Layer* aRoot, bool aIsMask /* = false */)
return MakeUnique<ColorLayerProperties>(static_cast<ColorLayer*>(aRoot));
case Layer::TYPE_IMAGE:
return MakeUnique<ImageLayerProperties>(static_cast<ImageLayer*>(aRoot), aIsMask);
default:
case Layer::TYPE_CANVAS:
case Layer::TYPE_READBACK:
case Layer::TYPE_SHADOW:
case Layer::TYPE_PAINTED:
return MakeUnique<LayerPropertiesBase>(aRoot);
}
return UniquePtr<LayerPropertiesBase>(nullptr);
MOZ_ASSERT_UNREACHABLE("Unexpected root layer type");
return MakeUnique<LayerPropertiesBase>(aRoot);
}
/* static */ UniquePtr<LayerProperties>
+8 -17
View File
@@ -2111,7 +2111,7 @@ void
CanvasLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
{
Layer::PrintInfo(aStream, aPrefix);
if (mFilter != GraphicsFilter::FILTER_GOOD) {
if (mFilter != Filter::GOOD) {
AppendToString(aStream, mFilter, " [filter=", "]");
}
}
@@ -2119,27 +2119,18 @@ CanvasLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
// This help function is used to assign the correct enum value
// to the packet
static void
DumpFilter(layerscope::LayersPacket::Layer* aLayer, const GraphicsFilter& aFilter)
DumpFilter(layerscope::LayersPacket::Layer* aLayer, const Filter& aFilter)
{
using namespace layerscope;
switch (aFilter) {
case GraphicsFilter::FILTER_FAST:
aLayer->set_filter(LayersPacket::Layer::FILTER_FAST);
break;
case GraphicsFilter::FILTER_GOOD:
case Filter::GOOD:
aLayer->set_filter(LayersPacket::Layer::FILTER_GOOD);
break;
case GraphicsFilter::FILTER_BEST:
aLayer->set_filter(LayersPacket::Layer::FILTER_BEST);
case Filter::LINEAR:
aLayer->set_filter(LayersPacket::Layer::FILTER_LINEAR);
break;
case GraphicsFilter::FILTER_NEAREST:
aLayer->set_filter(LayersPacket::Layer::FILTER_NEAREST);
break;
case GraphicsFilter::FILTER_BILINEAR:
aLayer->set_filter(LayersPacket::Layer::FILTER_BILINEAR);
break;
case GraphicsFilter::FILTER_GAUSSIAN:
aLayer->set_filter(LayersPacket::Layer::FILTER_GAUSSIAN);
case Filter::POINT:
aLayer->set_filter(LayersPacket::Layer::FILTER_POINT);
break;
default:
// ignore it
@@ -2162,7 +2153,7 @@ void
ImageLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
{
Layer::PrintInfo(aStream, aPrefix);
if (mFilter != GraphicsFilter::FILTER_GOOD) {
if (mFilter != Filter::GOOD) {
AppendToString(aStream, mFilter, " [filter=", "]");
}
}
+4 -5
View File
@@ -13,7 +13,6 @@
#include "Units.h" // for LayerMargin, LayerPoint, ParentLayerIntRect
#include "gfxContext.h"
#include "gfxTypes.h"
#include "GraphicsFilter.h" // for GraphicsFilter
#include "gfxPoint.h" // for gfxPoint
#include "gfxRect.h" // for gfxRect
#include "gfx2DGlue.h"
@@ -2372,7 +2371,7 @@ public:
* CONSTRUCTION PHASE ONLY
* Set the filter used to resample this image (if necessary).
*/
void SetFilter(GraphicsFilter aFilter)
void SetFilter(gfx::Filter aFilter)
{
if (mFilter != aFilter) {
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) Filter", this));
@@ -2380,7 +2379,7 @@ public:
Mutated();
}
}
GraphicsFilter GetFilter() const { return mFilter; }
gfx::Filter GetFilter() const { return mFilter; }
MOZ_LAYER_DECL_NAME("CanvasLayer", TYPE_CANVAS)
@@ -2404,7 +2403,7 @@ protected:
, mPreTransCallbackData(nullptr)
, mPostTransCallback(nullptr)
, mPostTransCallbackData(nullptr)
, mFilter(GraphicsFilter::FILTER_GOOD)
, mFilter(gfx::Filter::GOOD)
, mDirty(false)
{}
@@ -2427,7 +2426,7 @@ protected:
void* mPreTransCallbackData;
DidTransactionCallback mPostTransCallback;
void* mPostTransCallbackData;
GraphicsFilter mFilter;
gfx::Filter mFilter;
private:
/**
+3 -20
View File
@@ -28,25 +28,6 @@ AppendToString(std::stringstream& aStream, const void* p,
aStream << sfx;
}
void
AppendToString(std::stringstream& aStream, const GraphicsFilter& f,
const char* pfx, const char* sfx)
{
aStream << pfx;
switch (f) {
case GraphicsFilter::FILTER_FAST: aStream << "fast"; break;
case GraphicsFilter::FILTER_GOOD: aStream << "good"; break;
case GraphicsFilter::FILTER_BEST: aStream << "best"; break;
case GraphicsFilter::FILTER_NEAREST: aStream << "nearest"; break;
case GraphicsFilter::FILTER_BILINEAR: aStream << "bilinear"; break;
case GraphicsFilter::FILTER_GAUSSIAN: aStream << "gaussian"; break;
default:
NS_ERROR("unknown filter type");
aStream << "???";
}
aStream << sfx;
}
void
AppendToString(std::stringstream& aStream, FrameMetrics::ViewID n,
const char* pfx, const char* sfx)
@@ -276,7 +257,6 @@ AppendToString(std::stringstream& aStream, const Matrix5x4& m,
aStream << sfx;
}
void
AppendToString(std::stringstream& aStream, const Filter filter,
const char* pfx, const char* sfx)
@@ -287,6 +267,9 @@ AppendToString(std::stringstream& aStream, const Filter filter,
case Filter::GOOD: aStream << "Filter::GOOD"; break;
case Filter::LINEAR: aStream << "Filter::LINEAR"; break;
case Filter::POINT: aStream << "Filter::POINT"; break;
default:
NS_ERROR("unknown filter type");
aStream << "???";
}
aStream << sfx;
}
-5
View File
@@ -7,7 +7,6 @@
#define GFX_LAYERSLOGGING_H
#include "FrameMetrics.h" // for FrameMetrics, etc
#include "GraphicsFilter.h" // for GraphicsFilter
#include "mozilla/gfx/Point.h" // for IntSize, etc
#include "mozilla/gfx/Types.h" // for Filter, SurfaceFormat
#include "mozilla/layers/CompositorTypes.h" // for TextureFlags
@@ -30,10 +29,6 @@ void
AppendToString(std::stringstream& aStream, const void* p,
const char* pfx="", const char* sfx="");
void
AppendToString(std::stringstream& aStream, const GraphicsFilter& f,
const char* pfx="", const char* sfx="");
void
AppendToString(std::stringstream& aStream, FrameMetrics::ViewID n,
const char* pfx="", const char* sfx="");
+106
View File
@@ -14,6 +14,7 @@
#include "mozilla/gfx/Point.h" // for Point
#include "mozilla/layers/APZThreadUtils.h" // for AssertOnCompositorThread, etc
#include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform
#include "mozilla/layers/AsyncDragMetrics.h" // for AsyncDragMetrics
#include "mozilla/layers/CompositorParent.h" // for CompositorParent, etc
#include "mozilla/layers/LayerMetricsWrapper.h"
#include "mozilla/MouseEvents.h"
@@ -324,6 +325,21 @@ GetEventRegionsOverride(HitTestingTreeNode* aParent,
return result;
}
void
APZCTreeManager::StartScrollbarDrag(const ScrollableLayerGuid& aGuid,
const AsyncDragMetrics& aDragMetrics)
{
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aGuid);
if (!apzc) {
return;
}
// TODO Confirm the input block
//uint64_t inputBlockId = aDragMetrics.mDragStartSequenceNumber;
//mInputQueue->SetConfirmedMouseBlock(inputBlockId, apzc, aDragMetrics);
}
HitTestingTreeNode*
APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer,
const FrameMetrics& aMetrics,
@@ -352,6 +368,9 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer,
node->SetHitTestData(GetEventRegions(aLayer), aLayer.GetTransform(),
aLayer.GetClipRect() ? Some(ParentLayerIntRegion(*aLayer.GetClipRect())) : Nothing(),
GetEventRegionsOverride(aParent, aLayer));
node->SetScrollbarData(aLayer.GetScrollbarTargetContainerId(),
aLayer.GetScrollbarDirection(),
aLayer.GetScrollbarSize());
return node;
}
@@ -522,6 +541,9 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer,
GetEventRegionsOverride(aParent, aLayer));
}
node->SetScrollbarData(aLayer.GetScrollbarTargetContainerId(),
aLayer.GetScrollbarDirection(),
aLayer.GetScrollbarSize());
return node;
}
@@ -590,6 +612,18 @@ WillHandleWheelEvent(WidgetWheelEvent* aEvent)
!EventStateManager::WheelEventNeedsDeltaMultipliers(aEvent);
}
static bool
WillHandleMouseEvent(const WidgetMouseEventBase& aEvent)
{
if (!gfxPrefs::APZDragEnabled()) {
return false;
}
return aEvent.mMessage == eMouseMove ||
aEvent.mMessage == eMouseDown ||
aEvent.mMessage == eMouseUp;
}
template<typename PanGestureOrScrollWheelInput>
static bool
WillHandleInput(const PanGestureOrScrollWheelInput& aPanInput)
@@ -635,6 +669,28 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
MultiTouchInput& touchInput = aEvent.AsMultiTouchInput();
result = ProcessTouchInput(touchInput, aOutTargetGuid, aOutInputBlockId);
break;
} case MOUSE_INPUT: {
MouseInput& mouseInput = aEvent.AsMouseInput();
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(mouseInput.mOrigin,
&hitResult);
if (apzc) {
result = mInputQueue->ReceiveInputEvent(
apzc,
/* aTargetConfirmed = */ false,
mouseInput, aOutInputBlockId);
// Update the out-parameters so they are what the caller expects.
apzc->GetGuid(aOutTargetGuid);
// TODO Dagging on a scrollbar probably behaves differently from
// the other input types in that the gecko coordinates are the same
// as the screen coordinates even though the async transform on the APZC
// is changing. I'm not really sure at this point and it'll take some
// though to figure out properly.
//mouseInput.mOrigin = untransformedOrigin;
}
break;
} case SCROLLWHEEL_INPUT: {
FlushRepaintsToClearScreenToGeckoTransform();
@@ -951,6 +1007,21 @@ APZCTreeManager::ProcessEvent(WidgetInputEvent& aEvent,
return result;
}
nsEventStatus
APZCTreeManager::ProcessMouseEvent(WidgetMouseEventBase& aEvent,
ScrollableLayerGuid* aOutTargetGuid,
uint64_t* aOutInputBlockId)
{
MouseInput input(aEvent);
input.mOrigin = ScreenPoint(aEvent.refPoint.x, aEvent.refPoint.y);
nsEventStatus status = ReceiveInputEvent(input, aOutTargetGuid, aOutInputBlockId);
aEvent.refPoint.x = input.mOrigin.x;
aEvent.refPoint.y = input.mOrigin.y;
return status;
}
nsEventStatus
APZCTreeManager::ProcessWheelEvent(WidgetWheelEvent& aEvent,
ScrollableLayerGuid* aOutTargetGuid,
@@ -997,6 +1068,13 @@ APZCTreeManager::ReceiveInputEvent(WidgetInputEvent& aEvent,
}
switch (aEvent.mClass) {
case eMouseEventClass: {
WidgetMouseEventBase& mouseEvent = *aEvent.AsMouseEventBase();
if (WillHandleMouseEvent(mouseEvent)) {
return ProcessMouseEvent(mouseEvent, aOutTargetGuid, aOutInputBlockId);
}
return ProcessEvent(aEvent, aOutTargetGuid, aOutInputBlockId);
}
case eTouchEventClass: {
WidgetTouchEvent& touchEvent = *aEvent.AsTouchEvent();
MultiTouchInput touchInput(touchEvent);
@@ -1528,6 +1606,34 @@ APZCTreeManager::FindTargetNode(HitTestingTreeNode* aNode,
return nullptr;
}
nsRefPtr<HitTestingTreeNode>
APZCTreeManager::FindScrollNode(const AsyncDragMetrics& aDragMetrics)
{
MonitorAutoLock lock(mTreeLock);
return FindScrollNode(mRootNode, aDragMetrics);
}
HitTestingTreeNode*
APZCTreeManager::FindScrollNode(HitTestingTreeNode* aNode,
const AsyncDragMetrics& aDragMetrics)
{
mTreeLock.AssertCurrentThreadOwns();
for (HitTestingTreeNode* node = aNode; node; node = node->GetPrevSibling()) {
if (node->MatchesScrollDragMetrics(aDragMetrics)) {
return node;
}
HitTestingTreeNode* match = FindScrollNode(node->GetLastChild(), aDragMetrics);
if (match) {
return match;
}
}
return nullptr;
}
AsyncPanZoomController*
APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode,
const ParentLayerPoint& aHitTestPoint,
+17
View File
@@ -18,6 +18,7 @@
#include "mozilla/layers/APZUtils.h" // for HitTestResult
#include "mozilla/layers/TouchCounter.h"// for TouchCounter
#include "mozilla/Monitor.h" // for Monitor
#include "mozilla/TimeStamp.h" // for mozilla::TimeStamp
#include "mozilla/Vector.h" // for mozilla::Vector
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsCOMPtr.h" // for already_AddRefed
@@ -41,6 +42,7 @@ enum AllowedTouchBehavior {
};
class Layer;
class AsyncDragMetrics;
class AsyncPanZoomController;
class CompositorParent;
class OverscrollHandoffChain;
@@ -96,6 +98,7 @@ class APZCTreeManager {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(APZCTreeManager)
typedef mozilla::layers::AllowedTouchBehavior AllowedTouchBehavior;
typedef mozilla::layers::AsyncDragMetrics AsyncDragMetrics;
// Helper struct to hold some state while we build the hit-testing tree. The
// sole purpose of this struct is to shorten the argument list to
@@ -294,6 +297,12 @@ public:
*/
static float GetDPI() { return sDPI; }
/**
* Find the hit testing node for the scrollbar thumb that matches these
* drag metrics.
*/
nsRefPtr<HitTestingTreeNode> FindScrollNode(const AsyncDragMetrics& aDragMetrics);
/**
* Sets allowed touch behavior values for current touch-session for specific
* input block (determined by aInputBlock).
@@ -385,6 +394,9 @@ public:
nsRefPtr<const OverscrollHandoffChain> aOverscrollHandoffChain,
bool aHandoff);
void StartScrollbarDrag(const ScrollableLayerGuid& aGuid,
const AsyncDragMetrics& aDragMetrics);
/*
* Build the chain of APZCs that will handle overscroll for a pan starting at |aInitialTarget|.
*/
@@ -427,6 +439,8 @@ private:
HitTestingTreeNode* FindTargetNode(HitTestingTreeNode* aNode,
const ScrollableLayerGuid& aGuid,
GuidComparator aComparator);
HitTestingTreeNode* FindScrollNode(HitTestingTreeNode* aNode,
const AsyncDragMetrics& aDragMetrics);
AsyncPanZoomController* GetAPZCAtPoint(HitTestingTreeNode* aNode,
const ParentLayerPoint& aHitTestPoint,
HitTestResult* aOutHitResult);
@@ -445,6 +459,9 @@ private:
nsEventStatus ProcessEvent(WidgetInputEvent& inputEvent,
ScrollableLayerGuid* aOutTargetGuid,
uint64_t* aOutInputBlockId);
nsEventStatus ProcessMouseEvent(WidgetMouseEventBase& aInput,
ScrollableLayerGuid* aOutTargetGuid,
uint64_t* aOutInputBlockId);
void UpdateWheelTransaction(WidgetInputEvent& aEvent);
void UpdateZoomConstraintsRecursively(HitTestingTreeNode* aNode,
const ZoomConstraints& aConstraints);
+65
View File
@@ -0,0 +1,65 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_layers_DragMetrics_h
#define mozilla_layers_DragMetrics_h
#include "FrameMetrics.h"
namespace IPC {
template <typename T> struct ParamTraits;
} // namespace IPC
namespace mozilla {
namespace layers {
class AsyncDragMetrics {
friend struct IPC::ParamTraits<mozilla::layers::AsyncDragMetrics>;
public:
enum DragDirection {
NONE,
VERTICAL,
HORIZONTAL,
SENTINEL,
};
// IPC constructor
AsyncDragMetrics()
: mViewId(0)
, mPresShellId(0)
, mDragStartSequenceNumber(0)
, mScrollbarDragOffset(0)
, mDirection(NONE)
{}
AsyncDragMetrics(const FrameMetrics::ViewID& aViewId,
uint32_t aPresShellId,
uint64_t aDragStartSequenceNumber,
CSSIntCoord aScrollbarDragOffset,
const CSSIntRect& aScrollTrack,
DragDirection aDirection)
: mViewId(aViewId)
, mPresShellId(aPresShellId)
, mDragStartSequenceNumber(aDragStartSequenceNumber)
, mScrollbarDragOffset(aScrollbarDragOffset)
, mScrollTrack(aScrollTrack)
, mDirection(aDirection)
{}
FrameMetrics::ViewID mViewId;
uint32_t mPresShellId;
uint64_t mDragStartSequenceNumber;
CSSIntCoord mScrollbarDragOffset;
CSSIntRect mScrollTrack;
DragDirection mDirection;
};
}
}
#endif
+104 -1
View File
@@ -13,6 +13,7 @@
#include "Compositor.h" // for Compositor
#include "FrameMetrics.h" // for FrameMetrics, etc
#include "GestureEventListener.h" // for GestureEventListener
#include "HitTestingTreeNode.h" // for HitTestingTreeNode
#include "InputData.h" // for MultiTouchInput, etc
#include "InputBlockState.h" // for InputBlockState, TouchBlockState
#include "InputQueue.h" // for InputQueue
@@ -952,6 +953,95 @@ AsyncPanZoomController::ArePointerEventsConsumable(TouchBlockState* aBlock, uint
return true;
}
template <typename T>
static float GetAxisStart(AsyncDragMetrics::DragDirection aDir, T aValue) {
if (aDir == AsyncDragMetrics::HORIZONTAL) {
return aValue.x;
} else {
return aValue.y;
}
}
template <typename T>
static float GetAxisEnd(AsyncDragMetrics::DragDirection aDir, T aValue) {
if (aDir == AsyncDragMetrics::HORIZONTAL) {
return aValue.x + aValue.width;
} else {
return aValue.y + aValue.height;
}
}
template <typename T>
static float GetAxisSize(AsyncDragMetrics::DragDirection aDir, T aValue) {
if (aDir == AsyncDragMetrics::HORIZONTAL) {
return aValue.width;
} else {
return aValue.height;
}
}
template <typename T>
static float GetAxisScale(AsyncDragMetrics::DragDirection aDir, T aValue) {
if (aDir == AsyncDragMetrics::HORIZONTAL) {
return aValue.xScale;
} else {
return aValue.yScale;
}
}
nsEventStatus AsyncPanZoomController::HandleDragEvent(const MouseInput& aEvent,
const AsyncDragMetrics& aDragMetrics)
{
nsRefPtr<HitTestingTreeNode> node =
GetApzcTreeManager()->FindScrollNode(aDragMetrics);
if (!node) {
return nsEventStatus_eConsumeNoDefault;
}
CSSPoint scrollFramePoint = aEvent.mLocalOrigin / GetFrameMetrics().GetZoom();
// The scrollbar can be transformed with the frame but the pres shell
// resolution is only applied to the scroll frame.
CSSPoint scrollbarPoint = scrollFramePoint * GetFrameMetrics().GetPresShellResolution();
CSSRect cssCompositionBound = GetFrameMetrics().GetCompositionBounds() / GetFrameMetrics().GetZoom();
float mousePosition = GetAxisStart(aDragMetrics.mDirection, scrollbarPoint) -
aDragMetrics.mScrollbarDragOffset -
GetAxisStart(aDragMetrics.mDirection, cssCompositionBound) -
GetAxisStart(aDragMetrics.mDirection, aDragMetrics.mScrollTrack);
float scrollMax = GetAxisEnd(aDragMetrics.mDirection, aDragMetrics.mScrollTrack);
scrollMax -= node->GetScrollSize() /
GetAxisScale(aDragMetrics.mDirection, GetFrameMetrics().GetZoom()) *
GetFrameMetrics().GetPresShellResolution();
float scrollPercent = mousePosition / scrollMax;
float minScrollPosition =
GetAxisStart(aDragMetrics.mDirection, GetFrameMetrics().GetScrollableRect().TopLeft());
float maxScrollPosition =
GetAxisSize(aDragMetrics.mDirection, GetFrameMetrics().GetScrollableRect()) -
GetAxisSize(aDragMetrics.mDirection, GetFrameMetrics().GetCompositionBounds());
float scrollPosition = scrollPercent * maxScrollPosition;
scrollPosition = std::max(scrollPosition, minScrollPosition);
scrollPosition = std::min(scrollPosition, maxScrollPosition);
CSSPoint scrollOffset;
if (aDragMetrics.mDirection == AsyncDragMetrics::HORIZONTAL) {
scrollOffset = CSSPoint(scrollPosition, 0);
} else {
scrollOffset = CSSPoint(0, scrollPosition);
}
mFrameMetrics.SetScrollOffset(scrollOffset);
ScheduleCompositeAndMaybeRepaint();
UpdateSharedCompositorFrameMetrics();
// Here we consume the events. This means that the content scrollbars
// will only see the initial mouse down and the final mouse up.
// APZ will still update the scroll position.
return nsEventStatus_eConsumeNoDefault;
}
nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent,
const Matrix4x4& aTransformToApzc) {
APZThreadUtils::AssertOnControllerThread();
@@ -961,7 +1051,7 @@ nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent,
switch (aEvent.mInputType) {
case MULTITOUCH_INPUT: {
MultiTouchInput multiTouchInput = aEvent.AsMultiTouchInput();
if (!multiTouchInput.TransformToLocal(aTransformToApzc)) {
if (!multiTouchInput.TransformToLocal(aTransformToApzc)) {
return rv;
}
@@ -1001,6 +1091,16 @@ nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent,
}
break;
}
case MOUSE_INPUT: {
ScrollWheelInput scrollInput = aEvent.AsScrollWheelInput();
if (!scrollInput.TransformToLocal(aTransformToApzc)) {
return rv;
}
// TODO Need to implement blocks to properly handle this.
//rv = HandleDragEvent(scrollInput, dragMetrics);
break;
}
case SCROLLWHEEL_INPUT: {
ScrollWheelInput scrollInput = aEvent.AsScrollWheelInput();
if (!scrollInput.TransformToLocal(aTransformToApzc)) {
@@ -2950,6 +3050,9 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
bool smoothScrollRequested = aLayerMetrics.GetDoSmoothScroll()
&& (aLayerMetrics.GetScrollGeneration() != mFrameMetrics.GetScrollGeneration());
// TODO if we're in a drag and scrollOffsetUpdated is set then we want to
// ignore it
if (aIsFirstPaint || isDefault) {
// Initialize our internal state to something sane when the content
// that was just painted is something we knew nothing about previously
@@ -40,6 +40,7 @@ class SharedMemoryBasic;
namespace layers {
class AsyncDragMetrics;
struct ScrollableLayerGuid;
class CompositorParent;
class GestureEventListener;
@@ -266,6 +267,9 @@ public:
*/
void SendAsyncScrollEvent();
nsEventStatus HandleDragEvent(const MouseInput& aEvent,
const AsyncDragMetrics& aDragMetrics);
/**
* Handler for events which should not be intercepted by the touch listener.
*/
+24
View File
@@ -86,6 +86,30 @@ HitTestingTreeNode::SetLastChild(HitTestingTreeNode* aChild)
}
}
void
HitTestingTreeNode::SetScrollbarData(FrameMetrics::ViewID aScrollViewId, Layer::ScrollDirection aDir, int32_t aScrollSize)
{
mScrollViewId = aScrollViewId;
mScrollDir = aDir;
mScrollSize = aScrollSize;;
}
bool
HitTestingTreeNode::MatchesScrollDragMetrics(const AsyncDragMetrics& aDragMetrics) const
{
return ((mScrollDir == Layer::HORIZONTAL &&
aDragMetrics.mDirection == AsyncDragMetrics::HORIZONTAL) ||
(mScrollDir == Layer::VERTICAL &&
aDragMetrics.mDirection == AsyncDragMetrics::VERTICAL)) &&
mScrollViewId == aDragMetrics.mViewId;
}
int32_t
HitTestingTreeNode::GetScrollSize() const
{
return mScrollSize;
}
void
HitTestingTreeNode::SetPrevSibling(HitTestingTreeNode* aSibling)
{
+14 -1
View File
@@ -9,14 +9,16 @@
#include "APZUtils.h" // for HitTestResult
#include "FrameMetrics.h" // for ScrollableLayerGuid
#include "Layers.h"
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "mozilla/layers/LayersTypes.h" // for EventRegions
#include "mozilla/Maybe.h" // for Maybe
#include "mozilla/nsRefPtr.h" // for nsRefPtr
#include "mozilla/nsRefPtr.h" // for nsRefPtr
namespace mozilla {
namespace layers {
class AsyncDragMetrics;
class AsyncPanZoomController;
/**
@@ -87,6 +89,13 @@ public:
const Maybe<ParentLayerIntRegion>& aClipRegion,
const EventRegionsOverride& aOverride);
bool IsOutsideClip(const ParentLayerPoint& aPoint) const;
/* Scrollbar info */
void SetScrollbarData(FrameMetrics::ViewID aScrollViewId, Layer::ScrollDirection aDir, int32_t aScrollSize);
bool MatchesScrollDragMetrics(const AsyncDragMetrics& aDragMetrics) const;
int32_t GetScrollSize() const;
/* Convert aPoint into the LayerPixel space for the layer corresponding to
* this node. */
Maybe<LayerPoint> Untransform(const ParentLayerPoint& aPoint) const;
@@ -111,6 +120,10 @@ private:
uint64_t mLayersId;
FrameMetrics::ViewID mScrollViewId;
Layer::ScrollDirection mScrollDir;
int32_t mScrollSize;
/* Let {L,M} be the {layer, scrollable metrics} pair that this node
* corresponds to in the layer tree. mEventRegions contains the event regions
* from L, in the case where event-regions are enabled. If event-regions are
+1 -1
View File
@@ -52,7 +52,7 @@ BasicCanvasLayer::Paint(DrawTarget* aDT,
FillRectWithMask(aDT, aDeviceOffset,
Rect(0, 0, mBounds.width, mBounds.height),
mSurface, ToFilter(mFilter),
mSurface, mFilter,
DrawOptions(GetEffectiveOpacity(), GetEffectiveOperator(this)),
aMaskLayer);
+2 -2
View File
@@ -85,8 +85,8 @@ BasicImageLayer::Paint(DrawTarget* aDT,
}
gfx::IntSize size = mSize = surface->GetSize();
FillRectWithMask(aDT, aDeviceOffset, Rect(0, 0, size.width, size.height),
surface, ToFilter(mFilter),
FillRectWithMask(aDT, aDeviceOffset, Rect(0, 0, size.width, size.height),
surface, mFilter,
DrawOptions(GetEffectiveOpacity(), GetEffectiveOperator(this)),
aMaskLayer);
+1 -1
View File
@@ -92,7 +92,7 @@ ClientCanvasLayer::Initialize(const Data& aData)
#elif defined(MOZ_WIDGET_GONK)
factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext, caps, forwarder, mFlags);
#elif defined(GL_PROVIDER_GLX)
if (sGLXLibrary.UseTextureFromPixmap())
if (sGLXLibrary.UseSurfaceSharing())
factory = SurfaceFactory_GLXDrawable::Create(mGLContext, caps, forwarder, mFlags);
#else
if (mGLContext->GetContextType() == GLContextType::EGL) {
+4
View File
@@ -127,6 +127,10 @@ public:
explicit CompositableClient(CompositableForwarder* aForwarder, TextureFlags aFlags = TextureFlags::NO_FLAGS);
virtual void Dump(std::stringstream& aStream,
const char* aPrefix="",
bool aDumpHtml=false) {};
virtual TextureInfo GetTextureInfo() const = 0;
LayersBackend GetCompositorBackendType() const;
-4
View File
@@ -88,10 +88,6 @@ public:
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
virtual void Dump(std::stringstream& aStream,
const char* aPrefix="",
bool aDumpHtml=false) {};
virtual void Clear() = 0;
virtual RotatedContentBuffer::PaintState BeginPaintBuffer(PaintedLayer* aLayer,
uint32_t aFlags) = 0;
@@ -6,7 +6,6 @@
#include "CanvasLayerComposite.h"
#include "composite/CompositableHost.h" // for CompositableHost
#include "gfx2DGlue.h" // for ToFilter
#include "GraphicsFilter.h" // for GraphicsFilter
#include "gfxUtils.h" // for gfxUtils, etc
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "mozilla/gfx/Point.h" // for Point
@@ -129,7 +128,7 @@ CanvasLayerComposite::CleanupResources()
gfx::Filter
CanvasLayerComposite::GetEffectFilter()
{
GraphicsFilter filter = mFilter;
gfx::Filter filter = mFilter;
#ifdef ANDROID
// Bug 691354
// Using the LINEAR filter we get unexplained artifacts.
@@ -137,10 +136,10 @@ CanvasLayerComposite::GetEffectFilter()
Matrix matrix;
bool is2D = GetEffectiveTransform().Is2D(&matrix);
if (is2D && !ThebesMatrix(matrix).HasNonTranslationOrFlip()) {
filter = GraphicsFilter::FILTER_NEAREST;
filter = Filter::POINT;
}
#endif
return gfx::ToFilter(filter);
return filter;
}
void
+9
View File
@@ -91,6 +91,15 @@ public:
return img ? img->mFrameID : -1;
}
int32_t GetProducerID()
{
const TimedImage* img = ChooseImage();
return img ? img->mProducerID : -1;
}
int32_t GetLastFrameID() const { return mLastFrameID; }
int32_t GetLastProducerID() const { return mLastProducerID; }
enum Bias {
// Don't apply bias to frame times
BIAS_NONE,
+1 -1
View File
@@ -166,7 +166,7 @@ ImageLayerComposite::CleanupResources()
gfx::Filter
ImageLayerComposite::GetEffectFilter()
{
return gfx::ToFilter(mFilter);
return mFilter;
}
void
+1 -1
View File
@@ -544,6 +544,7 @@ CompositorParent::CompositorParent(nsIWidget* aWidget,
, mEGLSurfaceSize(aSurfaceWidth, aSurfaceHeight)
, mPauseCompositionMonitor("PauseCompositionMonitor")
, mResumeCompositionMonitor("ResumeCompositionMonitor")
, mRootLayerTreeID(AllocateLayerTreeId())
, mOverrideComposeReadiness(false)
, mForceCompositionTask(nullptr)
, mCompositorThreadHolder(sCompositorThreadHolder)
@@ -563,7 +564,6 @@ CompositorParent::CompositorParent(nsIWidget* aWidget,
CompositorLoop()->PostTask(FROM_HERE, NewRunnableFunction(SetThreadPriority));
mRootLayerTreeID = AllocateLayerTreeId();
{ // scope lock
MonitorAutoLock lock(*sIndirectLayerTreesLock);
+1 -1
View File
@@ -459,7 +459,7 @@ protected:
mozilla::Monitor mResumeCompositionMonitor;
uint64_t mCompositorID;
uint64_t mRootLayerTreeID;
const uint64_t mRootLayerTreeID;
bool mOverrideComposeReadiness;
CancelableTask* mForceCompositionTask;
+3 -3
View File
@@ -17,7 +17,7 @@ include "gfxipc/ShadowLayerUtils.h";
include "mozilla/GfxMessageUtils.h";
include "ImageLayers.h";
using mozilla::GraphicsFilterType from "mozilla/GfxMessageUtils.h";
using mozilla::gfx::Filter from "mozilla/gfx/2D.h";
using struct mozilla::gfx::Color from "mozilla/gfx/2D.h";
using struct mozilla::gfx::Point3D from "mozilla/gfx/Point.h";
using mozilla::gfx::IntPoint from "mozilla/gfx/Point.h";
@@ -252,14 +252,14 @@ struct ContainerLayerAttributes {
uint64_t hmdInfo;
};
struct ColorLayerAttributes { LayerColor color; IntRect bounds; };
struct CanvasLayerAttributes { GraphicsFilterType filter; IntRect bounds; };
struct CanvasLayerAttributes { Filter filter; IntRect bounds; };
struct RefLayerAttributes {
int64_t id;
// TODO: Once bug 1132895 is fixed we shouldn't need to propagate the override
// explicitly here.
EventRegionsOverride eventRegionsOverride;
};
struct ImageLayerAttributes { GraphicsFilterType filter; IntSize scaleToSize; ScaleMode scaleMode; };
struct ImageLayerAttributes { Filter filter; IntSize scaleToSize; ScaleMode scaleMode; };
union SpecificLayerAttributes {
null_t;
+1
View File
@@ -94,6 +94,7 @@ EXPORTS.mozilla.layers += [
# proper interface for the code there
'apz/src/APZCTreeManager.h',
'apz/src/APZUtils.h',
'apz/src/AsyncDragMetrics.h',
'apz/src/AsyncPanZoomAnimation.h',
'apz/src/TouchCounter.h',
'apz/testutil/APZTestData.h',
-2
View File
@@ -12,9 +12,7 @@
#include "GLUploadHelpers.h"
#include "Layers.h" // for WriteSnapshotToDumpFile
#include "LayerScope.h" // for LayerScope
#include "gfx2DGlue.h" // for ThebesFilter
#include "gfxCrashReporterUtils.h" // for ScopedGfxFeatureReporter
#include "GraphicsFilter.h" // for GraphicsFilter
#include "gfxPlatform.h" // for gfxPlatform
#include "gfxPrefs.h" // for gfxPrefs
#include "gfxRect.h" // for gfxRect
+1 -2
View File
@@ -18,9 +18,8 @@
#include "GLUploadHelpers.h"
#include "Layers.h" // for WriteSnapshotToDumpFile
#include "LayerScope.h" // for LayerScope
#include "gfx2DGlue.h" // for ThebesFilter
#include "gfxCrashReporterUtils.h" // for ScopedGfxFeatureReporter
#include "gfxMatrix.h" // for gfxMatrix
#include "GraphicsFilter.h" // for GraphicsFilter
#include "gfxPlatform.h" // for gfxPlatform
#include "gfxPrefs.h" // for gfxPrefs
#include "gfxRect.h" // for gfxRect
+2 -8
View File
@@ -1186,16 +1186,10 @@ bool LayersPacket_Layer_Filter_IsValid(int value) {
}
#ifndef _MSC_VER
const LayersPacket_Layer_Filter LayersPacket_Layer::FILTER_FAST;
const LayersPacket_Layer_Filter LayersPacket_Layer::FILTER_GOOD;
const LayersPacket_Layer_Filter LayersPacket_Layer::FILTER_BEST;
const LayersPacket_Layer_Filter LayersPacket_Layer::FILTER_NEAREST;
const LayersPacket_Layer_Filter LayersPacket_Layer::FILTER_BILINEAR;
const LayersPacket_Layer_Filter LayersPacket_Layer::FILTER_GAUSSIAN;
const LayersPacket_Layer_Filter LayersPacket_Layer::FILTER_LINEAR;
const LayersPacket_Layer_Filter LayersPacket_Layer::FILTER_POINT;
const LayersPacket_Layer_Filter LayersPacket_Layer::FILTER_SENTINEL;
const LayersPacket_Layer_Filter LayersPacket_Layer::Filter_MIN;
const LayersPacket_Layer_Filter LayersPacket_Layer::Filter_MAX;
const int LayersPacket_Layer::Filter_ARRAYSIZE;
#endif // _MSC_VER
#ifndef _MSC_VER
const int LayersPacket_Layer_Size::kWFieldNumber;
+6 -21
View File
@@ -76,18 +76,12 @@ const LayersPacket_Layer_ScrollingDirect LayersPacket_Layer_ScrollingDirect_Scro
const int LayersPacket_Layer_ScrollingDirect_ScrollingDirect_ARRAYSIZE = LayersPacket_Layer_ScrollingDirect_ScrollingDirect_MAX + 1;
enum LayersPacket_Layer_Filter {
LayersPacket_Layer_Filter_FILTER_FAST = 0,
LayersPacket_Layer_Filter_FILTER_GOOD = 1,
LayersPacket_Layer_Filter_FILTER_BEST = 2,
LayersPacket_Layer_Filter_FILTER_NEAREST = 3,
LayersPacket_Layer_Filter_FILTER_BILINEAR = 4,
LayersPacket_Layer_Filter_FILTER_GAUSSIAN = 5,
LayersPacket_Layer_Filter_FILTER_SENTINEL = 6
LayersPacket_Layer_Filter_FILTER_GOOD = 0,
LayersPacket_Layer_Filter_FILTER_LINEAR = 1,
LayersPacket_Layer_Filter_FILTER_POINT = 2,
LayersPacket_Layer_Filter_FILTER_SENTINEL = 3
};
bool LayersPacket_Layer_Filter_IsValid(int value);
const LayersPacket_Layer_Filter LayersPacket_Layer_Filter_Filter_MIN = LayersPacket_Layer_Filter_FILTER_FAST;
const LayersPacket_Layer_Filter LayersPacket_Layer_Filter_Filter_MAX = LayersPacket_Layer_Filter_FILTER_SENTINEL;
const int LayersPacket_Layer_Filter_Filter_ARRAYSIZE = LayersPacket_Layer_Filter_Filter_MAX + 1;
enum Packet_DataType {
Packet_DataType_FRAMESTART = 1,
@@ -1159,22 +1153,13 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite {
LayersPacket_Layer_ScrollingDirect_ScrollingDirect_ARRAYSIZE;
typedef LayersPacket_Layer_Filter Filter;
static const Filter FILTER_FAST = LayersPacket_Layer_Filter_FILTER_FAST;
static const Filter FILTER_GOOD = LayersPacket_Layer_Filter_FILTER_GOOD;
static const Filter FILTER_BEST = LayersPacket_Layer_Filter_FILTER_BEST;
static const Filter FILTER_NEAREST = LayersPacket_Layer_Filter_FILTER_NEAREST;
static const Filter FILTER_BILINEAR = LayersPacket_Layer_Filter_FILTER_BILINEAR;
static const Filter FILTER_GAUSSIAN = LayersPacket_Layer_Filter_FILTER_GAUSSIAN;
static const Filter FILTER_LINEAR = LayersPacket_Layer_Filter_FILTER_LINEAR;
static const Filter FILTER_POINT = LayersPacket_Layer_Filter_FILTER_POINT;
static const Filter FILTER_SENTINEL = LayersPacket_Layer_Filter_FILTER_SENTINEL;
static inline bool Filter_IsValid(int value) {
return LayersPacket_Layer_Filter_IsValid(value);
}
static const Filter Filter_MIN =
LayersPacket_Layer_Filter_Filter_MIN;
static const Filter Filter_MAX =
LayersPacket_Layer_Filter_Filter_MAX;
static const int Filter_ARRAYSIZE =
LayersPacket_Layer_Filter_Filter_ARRAYSIZE;
// accessors -------------------------------------------------------
-20
View File
@@ -1,20 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GraphicsFilter_h
#define GraphicsFilter_h
enum class GraphicsFilter : int {
FILTER_FAST,
FILTER_GOOD,
FILTER_BEST,
FILTER_NEAREST,
FILTER_BILINEAR,
FILTER_GAUSSIAN,
FILTER_SENTINEL
};
#endif
+2 -47
View File
@@ -1,3 +1,5 @@
/* -*- 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/. */
@@ -5,7 +7,6 @@
#ifndef GFX_2D_GLUE_H
#define GFX_2D_GLUE_H
#include "gfxPlatform.h"
#include "gfxRect.h"
#include "gfxMatrix.h"
@@ -60,52 +61,6 @@ inline Size ToSize(const gfxSize &aSize)
return Size(Float(aSize.width), Float(aSize.height));
}
inline Filter ToFilter(GraphicsFilter aFilter)
{
switch (aFilter) {
case GraphicsFilter::FILTER_NEAREST:
return Filter::POINT;
case GraphicsFilter::FILTER_GOOD:
return Filter::GOOD;
default:
return Filter::LINEAR;
}
}
inline GraphicsFilter ThebesFilter(Filter aFilter)
{
switch (aFilter) {
case Filter::POINT:
return GraphicsFilter::FILTER_NEAREST;
default:
return GraphicsFilter::FILTER_BEST;
}
}
inline ExtendMode ToExtendMode(gfxPattern::GraphicsExtend aExtend)
{
switch (aExtend) {
case gfxPattern::EXTEND_REPEAT:
return ExtendMode::REPEAT;
case gfxPattern::EXTEND_REFLECT:
return ExtendMode::REFLECT;
default:
return ExtendMode::CLAMP;
}
}
inline gfxPattern::GraphicsExtend ThebesExtend(ExtendMode aExtend)
{
switch (aExtend) {
case ExtendMode::REPEAT:
return gfxPattern::EXTEND_REPEAT;
case ExtendMode::REFLECT:
return gfxPattern::EXTEND_REFLECT;
default:
return gfxPattern::EXTEND_PAD;
}
}
inline gfxPoint ThebesPoint(const Point &aPoint)
{
return gfxPoint(aPoint.x, aPoint.y);
+8 -8
View File
@@ -34,7 +34,7 @@ gfxSurfaceDrawable::DrawWithSamplingRect(gfxContext* aContext,
const gfxRect& aFillRect,
const gfxRect& aSamplingRect,
bool aRepeat,
const GraphicsFilter& aFilter,
const Filter& aFilter,
gfxFloat aOpacity)
{
if (!mSourceSurface) {
@@ -60,7 +60,7 @@ bool
gfxSurfaceDrawable::Draw(gfxContext* aContext,
const gfxRect& aFillRect,
bool aRepeat,
const GraphicsFilter& aFilter,
const Filter& aFilter,
gfxFloat aOpacity,
const gfxMatrix& aTransform)
{
@@ -77,7 +77,7 @@ gfxSurfaceDrawable::DrawInternal(gfxContext* aContext,
const gfxRect& aFillRect,
const IntRect& aSamplingRect,
bool aRepeat,
const GraphicsFilter& aFilter,
const Filter& aFilter,
gfxFloat aOpacity,
const gfxMatrix& aTransform)
{
@@ -91,7 +91,7 @@ gfxSurfaceDrawable::DrawInternal(gfxContext* aContext,
patternTransform.Invert();
SurfacePattern pattern(mSourceSurface, extend,
patternTransform, ToFilter(aFilter), aSamplingRect);
patternTransform, aFilter, aSamplingRect);
Rect fillRect = ToRect(aFillRect);
DrawTarget* dt = aContext->GetDrawTarget();
@@ -116,7 +116,7 @@ gfxCallbackDrawable::gfxCallbackDrawable(gfxDrawingCallback* aCallback,
}
already_AddRefed<gfxSurfaceDrawable>
gfxCallbackDrawable::MakeSurfaceDrawable(const GraphicsFilter aFilter)
gfxCallbackDrawable::MakeSurfaceDrawable(const Filter aFilter)
{
SurfaceFormat format =
gfxPlatform::GetPlatform()->Optimal2DFormatForContent(gfxContentType::COLOR_ALPHA);
@@ -141,7 +141,7 @@ bool
gfxCallbackDrawable::Draw(gfxContext* aContext,
const gfxRect& aFillRect,
bool aRepeat,
const GraphicsFilter& aFilter,
const Filter& aFilter,
gfxFloat aOpacity,
const gfxMatrix& aTransform)
{
@@ -181,7 +181,7 @@ public:
virtual bool operator()(gfxContext* aContext,
const gfxRect& aFillRect,
const GraphicsFilter& aFilter,
const Filter& aFilter,
const gfxMatrix& aTransform = gfxMatrix())
{
return mDrawable->Draw(aContext, aFillRect, false, aFilter, 1.0,
@@ -205,7 +205,7 @@ bool
gfxPatternDrawable::Draw(gfxContext* aContext,
const gfxRect& aFillRect,
bool aRepeat,
const GraphicsFilter& aFilter,
const Filter& aFilter,
gfxFloat aOpacity,
const gfxMatrix& aTransform)
{
+19 -20
View File
@@ -9,7 +9,6 @@
#include "nsAutoPtr.h"
#include "gfxRect.h"
#include "gfxMatrix.h"
#include "GraphicsFilter.h"
#include "mozilla/gfx/2D.h"
class gfxContext;
@@ -36,14 +35,14 @@ public:
virtual bool Draw(gfxContext* aContext,
const gfxRect& aFillRect,
bool aRepeat,
const GraphicsFilter& aFilter,
const mozilla::gfx::Filter& aFilter,
gfxFloat aOpacity = 1.0,
const gfxMatrix& aTransform = gfxMatrix()) = 0;
virtual bool DrawWithSamplingRect(gfxContext* aContext,
const gfxRect& aFillRect,
const gfxRect& aSamplingRect,
bool aRepeat,
const GraphicsFilter& aFilter,
const mozilla::gfx::Filter& aFilter,
gfxFloat aOpacity = 1.0)
{
return false;
@@ -71,14 +70,14 @@ public:
virtual bool Draw(gfxContext* aContext,
const gfxRect& aFillRect,
bool aRepeat,
const GraphicsFilter& aFilter,
const mozilla::gfx::Filter& aFilter,
gfxFloat aOpacity = 1.0,
const gfxMatrix& aTransform = gfxMatrix());
virtual bool DrawWithSamplingRect(gfxContext* aContext,
const gfxRect& aFillRect,
const gfxRect& aSamplingRect,
bool aRepeat,
const GraphicsFilter& aFilter,
const mozilla::gfx::Filter& aFilter,
gfxFloat aOpacity = 1.0);
protected:
@@ -86,7 +85,7 @@ protected:
const gfxRect& aFillRect,
const mozilla::gfx::IntRect& aSamplingRect,
bool aRepeat,
const GraphicsFilter& aFilter,
const mozilla::gfx::Filter& aFilter,
gfxFloat aOpacity,
const gfxMatrix& aTransform = gfxMatrix());
@@ -113,9 +112,9 @@ public:
* @return whether drawing was successful
*/
virtual bool operator()(gfxContext* aContext,
const gfxRect& aFillRect,
const GraphicsFilter& aFilter,
const gfxMatrix& aTransform = gfxMatrix()) = 0;
const gfxRect& aFillRect,
const mozilla::gfx::Filter& aFilter,
const gfxMatrix& aTransform = gfxMatrix()) = 0;
};
@@ -129,14 +128,14 @@ public:
virtual ~gfxCallbackDrawable() {}
virtual bool Draw(gfxContext* aContext,
const gfxRect& aFillRect,
bool aRepeat,
const GraphicsFilter& aFilter,
gfxFloat aOpacity = 1.0,
const gfxMatrix& aTransform = gfxMatrix());
const gfxRect& aFillRect,
bool aRepeat,
const mozilla::gfx::Filter& aFilter,
gfxFloat aOpacity = 1.0,
const gfxMatrix& aTransform = gfxMatrix());
protected:
already_AddRefed<gfxSurfaceDrawable> MakeSurfaceDrawable(const GraphicsFilter aFilter = GraphicsFilter::FILTER_FAST);
already_AddRefed<gfxSurfaceDrawable> MakeSurfaceDrawable(mozilla::gfx::Filter aFilter = mozilla::gfx::Filter::LINEAR);
nsRefPtr<gfxDrawingCallback> mCallback;
nsRefPtr<gfxSurfaceDrawable> mSurfaceDrawable;
@@ -153,11 +152,11 @@ public:
virtual ~gfxPatternDrawable();
virtual bool Draw(gfxContext* aContext,
const gfxRect& aFillRect,
bool aRepeat,
const GraphicsFilter& aFilter,
gfxFloat aOpacity = 1.0,
const gfxMatrix& aTransform = gfxMatrix());
const gfxRect& aFillRect,
bool aRepeat,
const mozilla::gfx::Filter& aFilter,
gfxFloat aOpacity = 1.0,
const gfxMatrix& aTransform = gfxMatrix());
protected:
already_AddRefed<gfxCallbackDrawable> MakeCallbackDrawable();
+15 -23
View File
@@ -20,14 +20,14 @@
using namespace mozilla::gfx;
gfxPattern::gfxPattern(const Color& aColor)
: mExtend(EXTEND_NONE)
: mExtend(ExtendMode::CLAMP)
{
mGfxPattern.InitColorPattern(ToDeviceColor(aColor));
}
// linear
gfxPattern::gfxPattern(gfxFloat x0, gfxFloat y0, gfxFloat x1, gfxFloat y1)
: mExtend(EXTEND_NONE)
: mExtend(ExtendMode::CLAMP)
{
mGfxPattern.InitLinearGradientPattern(Point(x0, y0), Point(x1, y1), nullptr);
}
@@ -35,7 +35,7 @@ gfxPattern::gfxPattern(gfxFloat x0, gfxFloat y0, gfxFloat x1, gfxFloat y1)
// radial
gfxPattern::gfxPattern(gfxFloat cx0, gfxFloat cy0, gfxFloat radius0,
gfxFloat cx1, gfxFloat cy1, gfxFloat radius1)
: mExtend(EXTEND_NONE)
: mExtend(ExtendMode::CLAMP)
{
mGfxPattern.InitRadialGradientPattern(Point(cx0, cy0), Point(cx1, cy1),
radius0, radius1, nullptr);
@@ -44,9 +44,9 @@ gfxPattern::gfxPattern(gfxFloat cx0, gfxFloat cy0, gfxFloat radius0,
// Azure
gfxPattern::gfxPattern(SourceSurface *aSurface, const Matrix &aPatternToUserSpace)
: mPatternToUserSpace(aPatternToUserSpace)
, mExtend(EXTEND_NONE)
, mExtend(ExtendMode::CLAMP)
{
mGfxPattern.InitSurfacePattern(aSurface, ToExtendMode(mExtend), Matrix(), // matrix is overridden in GetPattern()
mGfxPattern.InitSurfacePattern(aSurface, mExtend, Matrix(), // matrix is overridden in GetPattern()
mozilla::gfx::Filter::GOOD);
}
@@ -75,8 +75,7 @@ gfxPattern::SetColorStops(GradientStops* aStops)
void
gfxPattern::CacheColorStops(const DrawTarget *aDT)
{
mStops = gfxGradientCache::GetOrCreateGradientStops(aDT, mStopsList,
ToExtendMode(mExtend));
mStops = gfxGradientCache::GetOrCreateGradientStops(aDT, mStopsList, mExtend);
}
void
@@ -132,15 +131,14 @@ gfxPattern::GetPattern(const DrawTarget *aTarget,
if (!mStops &&
!mStopsList.IsEmpty()) {
mStops = aTarget->CreateGradientStops(mStopsList.Elements(),
mStopsList.Length(),
ToExtendMode(mExtend));
mStopsList.Length(), mExtend);
}
switch (mGfxPattern.GetPattern()->GetType()) {
case PatternType::SURFACE: {
SurfacePattern* surfacePattern = static_cast<SurfacePattern*>(mGfxPattern.GetPattern());
surfacePattern->mMatrix = patternToUser;
surfacePattern->mExtendMode = ToExtendMode(mExtend);
surfacePattern->mExtendMode = mExtend;
break;
}
case PatternType::LINEAR_GRADIENT: {
@@ -164,9 +162,9 @@ gfxPattern::GetPattern(const DrawTarget *aTarget,
}
void
gfxPattern::SetExtend(GraphicsExtend extend)
gfxPattern::SetExtend(ExtendMode aExtend)
{
mExtend = extend;
mExtend = aExtend;
mStops = nullptr;
}
@@ -183,29 +181,23 @@ gfxPattern::IsOpaque()
return false;
}
gfxPattern::GraphicsExtend
gfxPattern::Extend() const
{
return mExtend;
}
void
gfxPattern::SetFilter(GraphicsFilter filter)
gfxPattern::SetFilter(gfx::Filter filter)
{
if (mGfxPattern.GetPattern()->GetType() != PatternType::SURFACE) {
return;
}
static_cast<SurfacePattern*>(mGfxPattern.GetPattern())->mFilter = ToFilter(filter);
static_cast<SurfacePattern*>(mGfxPattern.GetPattern())->mFilter = filter;
}
GraphicsFilter
Filter
gfxPattern::Filter() const
{
if (mGfxPattern.GetPattern()->GetType() != PatternType::SURFACE) {
return GraphicsFilter::FILTER_GOOD;
return gfx::Filter::GOOD;
}
return ThebesFilter(static_cast<const SurfacePattern*>(mGfxPattern.GetPattern())->mFilter);
return static_cast<const SurfacePattern*>(mGfxPattern.GetPattern())->mFilter;
}
bool
+5 -24
View File
@@ -12,7 +12,6 @@
#include "mozilla/Alignment.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/PatternHelpers.h"
#include "GraphicsFilter.h"
#include "nsISupportsImpl.h"
#include "nsAutoPtr.h"
#include "nsTArray.h"
@@ -53,31 +52,13 @@ public:
mozilla::gfx::Matrix *aOriginalUserToDevice = nullptr);
bool IsOpaque();
enum GraphicsExtend {
EXTEND_NONE,
EXTEND_REPEAT,
EXTEND_REFLECT,
EXTEND_PAD,
// Our own private flag for setting either NONE or PAD,
// depending on what the platform does for NONE. This is only
// relevant for surface patterns; for all other patterns, it
// behaves identical to PAD. On MacOS X, this becomes "NONE",
// because Quartz does the thing that we want at image edges;
// similarily on the win32 printing surface, since
// everything's done with GDI there. On other platforms, it
// usually becomes PAD.
EXTEND_PAD_EDGE = 1000
};
// none, repeat, reflect
void SetExtend(GraphicsExtend extend);
GraphicsExtend Extend() const;
// clamp, repeat, reflect
void SetExtend(mozilla::gfx::ExtendMode aExtend);
int CairoStatus();
void SetFilter(GraphicsFilter filter);
GraphicsFilter Filter() const;
void SetFilter(mozilla::gfx::Filter filter);
mozilla::gfx::Filter Filter() const;
/* returns TRUE if it succeeded */
bool GetSolidColor(mozilla::gfx::Color& aColorOut);
@@ -91,7 +72,7 @@ private:
mozilla::gfx::Matrix mPatternToUserSpace;
mozilla::RefPtr<mozilla::gfx::GradientStops> mStops;
nsTArray<mozilla::gfx::GradientStop> mStopsList;
GraphicsExtend mExtend;
mozilla::gfx::ExtendMode mExtend;
};
#endif /* GFX_PATTERN_H */
+11 -8
View File
@@ -2090,26 +2090,19 @@ gfxPlatform::GetLog(eGfxLog aWhichLog)
switch (aWhichLog) {
case eGfxLog_fontlist:
return sFontlistLog;
break;
case eGfxLog_fontinit:
return sFontInitLog;
break;
case eGfxLog_textrun:
return sTextrunLog;
break;
case eGfxLog_textrunui:
return sTextrunuiLog;
break;
case eGfxLog_cmapdata:
return sCmapDataLog;
break;
case eGfxLog_textperf:
return sTextPerfLog;
break;
default:
break;
}
MOZ_ASSERT_UNREACHABLE("Unexpected log type");
return nullptr;
}
@@ -2450,6 +2443,10 @@ gfxPlatform::GetApzSupportInfo(mozilla::widget::InfoObject& aObj)
if (SupportsApzTouchInput()) {
aObj.DefineProperty("ApzTouchInput", 1);
}
if (SupportsApzDragInput()) {
aObj.DefineProperty("ApzDragInput", 1);
}
}
/*static*/ bool
@@ -2567,3 +2564,9 @@ gfxPlatform::UpdateDeviceInitData()
SetDeviceInitData(data);
}
bool
gfxPlatform::SupportsApzDragInput() const
{
return gfxPrefs::APZDragEnabled();
}
+1
View File
@@ -632,6 +632,7 @@ public:
virtual bool SupportsApzTouchInput() const {
return false;
}
bool SupportsApzDragInput() const;
virtual void FlushContentDrawing() {}
+1
View File
@@ -150,6 +150,7 @@ private:
DECL_GFX_PREF(Live, "apz.cross_slide.enabled", APZCrossSlideEnabled, bool, false);
DECL_GFX_PREF(Live, "apz.danger_zone_x", APZDangerZoneX, int32_t, 50);
DECL_GFX_PREF(Live, "apz.danger_zone_y", APZDangerZoneY, int32_t, 100);
DECL_GFX_PREF(Live, "apz.drag.enabled", APZDragEnabled, bool, false);
DECL_GFX_PREF(Live, "apz.enlarge_displayport_when_clipped", APZEnlargeDisplayPortWhenClipped, bool, false);
DECL_GFX_PREF(Live, "apz.fling_accel_base_mult", APZFlingAccelBaseMultiplier, float, 1.0f);
DECL_GFX_PREF(Live, "apz.fling_accel_interval_ms", APZFlingAccelInterval, int32_t, 500);
+13 -13
View File
@@ -447,8 +447,8 @@ CreateSamplingRestrictedDrawable(gfxDrawable* aDrawable,
nsRefPtr<gfxContext> tmpCtx = new gfxContext(target);
tmpCtx->SetOp(OptimalFillOp());
aDrawable->Draw(tmpCtx, needed - needed.TopLeft(), true,
GraphicsFilter::FILTER_FAST, 1.0, gfxMatrix::Translation(needed.TopLeft()));
aDrawable->Draw(tmpCtx, needed - needed.TopLeft(), true, Filter::LINEAR,
1.0, gfxMatrix::Translation(needed.TopLeft()));
RefPtr<SourceSurface> surface = target->Snapshot();
nsRefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(surface, size, gfxMatrix::Translation(-needed.TopLeft()));
@@ -536,9 +536,9 @@ DeviceToImageTransform(gfxContext* aContext)
/* These heuristics are based on Source/WebCore/platform/graphics/skia/ImageSkia.cpp:computeResamplingMode() */
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
static GraphicsFilter ReduceResamplingFilter(GraphicsFilter aFilter,
int aImgWidth, int aImgHeight,
float aSourceWidth, float aSourceHeight)
static Filter ReduceResamplingFilter(Filter aFilter,
int aImgWidth, int aImgHeight,
float aSourceWidth, float aSourceHeight)
{
// Images smaller than this in either direction are considered "small" and
// are not resampled ever (see below).
@@ -553,7 +553,7 @@ static GraphicsFilter ReduceResamplingFilter(GraphicsFilter aFilter,
|| aImgHeight <= kSmallImageSizeThreshold) {
// Never resample small images. These are often used for borders and
// rules (think 1x1 images used to make lines).
return GraphicsFilter::FILTER_NEAREST;
return Filter::POINT;
}
if (aImgHeight * kLargeStretch <= aSourceHeight || aImgWidth * kLargeStretch <= aSourceWidth) {
@@ -564,7 +564,7 @@ static GraphicsFilter ReduceResamplingFilter(GraphicsFilter aFilter,
// (which might be large) and then is stretching it to fill some part
// of the page.
if (fabs(aSourceWidth - aImgWidth)/aImgWidth < 0.5 || fabs(aSourceHeight - aImgHeight)/aImgHeight < 0.5)
return GraphicsFilter::FILTER_NEAREST;
return Filter::POINT;
// The image is growing a lot and in more than one direction. Resampling
// is slow and doesn't give us very much when growing a lot.
@@ -592,9 +592,9 @@ static GraphicsFilter ReduceResamplingFilter(GraphicsFilter aFilter,
return aFilter;
}
#else
static GraphicsFilter ReduceResamplingFilter(GraphicsFilter aFilter,
int aImgWidth, int aImgHeight,
int aSourceWidth, int aSourceHeight)
static Filter ReduceResamplingFilter(Filter aFilter,
int aImgWidth, int aImgHeight,
int aSourceWidth, int aSourceHeight)
{
// Just pass the filter through unchanged
return aFilter;
@@ -621,7 +621,7 @@ PrescaleAndTileDrawable(gfxDrawable* aDrawable,
gfxContext* aContext,
const ImageRegion& aRegion,
Rect aImageRect,
const GraphicsFilter& aFilter,
const Filter& aFilter,
const SurfaceFormat aFormat,
gfxFloat aOpacity)
{
@@ -689,7 +689,7 @@ PrescaleAndTileDrawable(gfxDrawable* aDrawable,
aContext->CurrentAntialiasMode());
SurfacePattern scaledImagePattern(scaledImage, ExtendMode::REPEAT,
Matrix(), ToFilter(aFilter));
Matrix(), aFilter);
destDrawTarget->FillRect(scaledNeededRect, scaledImagePattern, drawOptions);
}
return true;
@@ -702,7 +702,7 @@ gfxUtils::DrawPixelSnapped(gfxContext* aContext,
const gfxSize& aImageSize,
const ImageRegion& aRegion,
const SurfaceFormat aFormat,
GraphicsFilter aFilter,
Filter aFilter,
uint32_t aImageFlags,
gfxFloat aOpacity)
{
+1 -2
View File
@@ -7,7 +7,6 @@
#define GFX_UTILS_H
#include "gfxTypes.h"
#include "GraphicsFilter.h"
#include "imgIContainer.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
@@ -79,7 +78,7 @@ public:
const gfxSize& aImageSize,
const ImageRegion& aRegion,
const mozilla::gfx::SurfaceFormat aFormat,
GraphicsFilter aFilter,
mozilla::gfx::Filter aFilter,
uint32_t aImageFlags = imgIContainer::FLAG_NONE,
gfxFloat aOpacity = 1.0);
+2 -2
View File
@@ -288,9 +288,9 @@ gfxWindowsNativeDrawing::PaintToContext()
pat->SetMatrix(m);
if (mNativeDrawFlags & DO_NEAREST_NEIGHBOR_FILTERING)
pat->SetFilter(GraphicsFilter::FILTER_FAST);
pat->SetFilter(Filter::LINEAR);
pat->SetExtend(gfxPattern::EXTEND_PAD);
pat->SetExtend(ExtendMode::CLAMP);
mContext->SetPattern(pat);
mContext->Fill();
mContext->Restore();
-1
View File
@@ -49,7 +49,6 @@ EXPORTS += [
'gfxTypes.h',
'gfxUserFontSet.h',
'gfxUtils.h',
'GraphicsFilter.h',
'RoundedRect.h',
'SoftwareVsyncSource.h',
'VsyncSource.h',
+5 -5
View File
@@ -92,7 +92,7 @@ public:
virtual bool operator()(gfxContext* aContext,
const gfxRect& aFillRect,
const GraphicsFilter& aFilter,
const Filter& aFilter,
const gfxMatrix& aTransform)
{
MOZ_ASSERT(aTransform.IsIdentity(),
@@ -266,7 +266,7 @@ ClippedImage::GetFrameInternal(const nsIntSize& aSize,
gfxUtils::DrawPixelSnapped(ctx, drawable, aSize,
ImageRegion::Create(aSize),
SurfaceFormat::B8G8R8A8,
GraphicsFilter::FILTER_FAST,
Filter::LINEAR,
imgIContainer::FLAG_CLAMP);
// Cache the resulting surface.
@@ -323,7 +323,7 @@ ClippedImage::Draw(gfxContext* aContext,
const nsIntSize& aSize,
const ImageRegion& aRegion,
uint32_t aWhichFrame,
GraphicsFilter aFilter,
Filter aFilter,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags)
{
@@ -381,7 +381,7 @@ ClippedImage::DrawSingleTile(gfxContext* aContext,
const nsIntSize& aSize,
const ImageRegion& aRegion,
uint32_t aWhichFrame,
GraphicsFilter aFilter,
Filter aFilter,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags)
{
@@ -440,7 +440,7 @@ ClippedImage::GetOrientation()
nsIntSize
ClippedImage::OptimalImageSizeForDest(const gfxSize& aDest,
uint32_t aWhichFrame,
GraphicsFilter aFilter, uint32_t aFlags)
Filter aFilter, uint32_t aFlags)
{
if (!ShouldClip()) {
return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame, aFilter,
+3 -3
View File
@@ -50,7 +50,7 @@ public:
const nsIntSize& aSize,
const ImageRegion& aRegion,
uint32_t aWhichFrame,
GraphicsFilter aFilter,
gfx::Filter aFilter,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags) override;
NS_IMETHOD RequestDiscard() override;
@@ -59,7 +59,7 @@ public:
override;
nsIntSize OptimalImageSizeForDest(const gfxSize& aDest,
uint32_t aWhichFrame,
GraphicsFilter aFilter,
gfx::Filter aFilter,
uint32_t aFlags) override;
protected:
@@ -78,7 +78,7 @@ private:
const nsIntSize& aSize,
const ImageRegion& aRegion,
uint32_t aWhichFrame,
GraphicsFilter aFilter,
gfx::Filter aFilter,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags);
+3 -4
View File
@@ -188,8 +188,7 @@ DynamicImage::GetFrameAtSize(const IntSize& aSize,
nsRefPtr<gfxContext> context = new gfxContext(dt);
auto result = Draw(context, aSize, ImageRegion::Create(aSize),
aWhichFrame, GraphicsFilter::FILTER_NEAREST,
Nothing(), aFlags);
aWhichFrame, Filter::POINT, Nothing(), aFlags);
return result == DrawResult::SUCCESS ? dt->Snapshot() : nullptr;
}
@@ -219,7 +218,7 @@ DynamicImage::Draw(gfxContext* aContext,
const nsIntSize& aSize,
const ImageRegion& aRegion,
uint32_t aWhichFrame,
GraphicsFilter aFilter,
Filter aFilter,
const Maybe<SVGImageContext>& aSVGContext,
uint32_t aFlags)
{
@@ -325,7 +324,7 @@ DynamicImage::SetAnimationStartTime(const mozilla::TimeStamp& aTime)
nsIntSize
DynamicImage::OptimalImageSizeForDest(const gfxSize& aDest,
uint32_t aWhichFrame,
GraphicsFilter aFilter, uint32_t aFlags)
Filter aFilter, uint32_t aFlags)
{
IntSize size(mDrawable->Size());
return nsIntSize(size.width, size.height);

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