Merge inbound to central, a=merge

MozReview-Commit-ID: ADcSE67n1t8
This commit is contained in:
Wes Kocher 2016-04-18 15:07:04 -07:00
Родитель 15c95c409e 1740fab4fd
Коммит 0a2f84202b
174 изменённых файлов: 2363 добавлений и 1048 удалений

Просмотреть файл

@ -2082,7 +2082,7 @@ Element::DispatchClickEvent(nsPresContext* aPresContext,
NS_PRECONDITION(aStatus, "Null out param?");
WidgetMouseEvent event(aSourceEvent->IsTrusted(), eMouseClick,
aSourceEvent->widget, WidgetMouseEvent::eReal);
aSourceEvent->mWidget, WidgetMouseEvent::eReal);
event.refPoint = aSourceEvent->refPoint;
uint32_t clickCount = 1;
float pressure = 0;

Просмотреть файл

@ -707,8 +707,7 @@ WriteBlob(JSStructuredCloneWriter* aWriter,
}
// A directory is serialized as:
// - pair of ints: SCTAG_DOM_DIRECTORY, 0
// - pair of ints: type (eDOMRootDirectory/eDOMNotRootDirectory) - path length
// - pair of ints: SCTAG_DOM_DIRECTORY, path length
// - path as string
bool
WriteDirectory(JSStructuredCloneWriter* aWriter,
@ -721,36 +720,25 @@ WriteDirectory(JSStructuredCloneWriter* aWriter,
aDirectory->GetFullRealPath(path);
size_t charSize = sizeof(nsString::char_type);
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_DIRECTORY, 0) &&
JS_WriteUint32Pair(aWriter, (uint32_t)aDirectory->Type(),
path.Length()) &&
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_DIRECTORY, path.Length()) &&
JS_WriteBytes(aWriter, path.get(), path.Length() * charSize);
}
JSObject*
ReadDirectory(JSContext* aCx,
JSStructuredCloneReader* aReader,
uint32_t aZero,
uint32_t aPathLength,
StructuredCloneHolder* aHolder)
{
MOZ_ASSERT(aCx);
MOZ_ASSERT(aReader);
MOZ_ASSERT(aHolder);
MOZ_ASSERT(aZero == 0);
uint32_t directoryType, lengthOfString;
if (!JS_ReadUint32Pair(aReader, &directoryType, &lengthOfString)) {
return nullptr;
}
MOZ_ASSERT(directoryType == Directory::eDOMRootDirectory ||
directoryType == Directory::eNotDOMRootDirectory);
nsAutoString path;
path.SetLength(lengthOfString);
path.SetLength(aPathLength);
size_t charSize = sizeof(nsString::char_type);
if (!JS_ReadBytes(aReader, (void*) path.BeginWriting(),
lengthOfString * charSize)) {
aPathLength * charSize)) {
return nullptr;
}
@ -769,8 +757,7 @@ ReadDirectory(JSContext* aCx,
JS::Rooted<JS::Value> val(aCx);
{
RefPtr<Directory> directory =
Directory::Create(aHolder->ParentDuringRead(), file,
(Directory::DirectoryType) directoryType);
Directory::Create(aHolder->ParentDuringRead(), file);
if (!ToJSValue(aCx, directory, &val)) {
return nullptr;

Просмотреть файл

@ -7798,7 +7798,6 @@ nsContentUtils::SendMouseEvent(nsCOMPtr<nsIPresShell> aPresShell,
event.mModifiers = GetWidgetModifiers(aModifiers);
event.button = aButton;
event.buttons = GetButtonsFlagForButton(aButton);
event.widget = widget;
event.pressure = aPressure;
event.inputSource = aInputSourceArg;
event.clickCount = aClickCount;

Просмотреть файл

@ -672,7 +672,6 @@ nsDOMWindowUtils::SendPointerEventCommon(const nsAString& aType,
event.mModifiers = nsContentUtils::GetWidgetModifiers(aModifiers);
event.button = aButton;
event.buttons = nsContentUtils::GetButtonsFlagForButton(aButton);
event.widget = widget;
event.pressure = aPressure;
event.inputSource = aInputSourceArg;
event.pointerId = aPointerId;
@ -805,7 +804,6 @@ nsDOMWindowUtils::SendWheelEvent(float aX,
(aOptions & WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS) != 0;
wheelEvent.mLineOrPageDeltaX = aLineOrPageDeltaX;
wheelEvent.mLineOrPageDeltaY = aLineOrPageDeltaY;
wheelEvent.widget = widget;
wheelEvent.mTime = PR_Now() / 1000;
@ -938,7 +936,6 @@ nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType,
}
WidgetTouchEvent event(true, msg, widget);
event.mModifiers = nsContentUtils::GetWidgetModifiers(aModifiers);
event.widget = widget;
event.mTime = PR_Now();
nsPresContext* presContext = GetPresContext();

Просмотреть файл

@ -1534,9 +1534,9 @@ ContentEventHandler::OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent)
// The root frame's widget might be different, e.g., the event was fired on
// a popup but the rootFrame is the document root.
if (rootWidget != aEvent->widget) {
NS_PRECONDITION(aEvent->widget, "The event must have the widget");
nsView* view = nsView::GetViewFor(aEvent->widget);
if (rootWidget != aEvent->mWidget) {
NS_PRECONDITION(aEvent->mWidget, "The event must have the widget");
nsView* view = nsView::GetViewFor(aEvent->mWidget);
NS_ENSURE_TRUE(view, NS_ERROR_FAILURE);
rootFrame = view->GetFrame();
NS_ENSURE_TRUE(rootFrame, NS_ERROR_FAILURE);
@ -1548,8 +1548,8 @@ ContentEventHandler::OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent)
rootWidget);
eventOnRoot.mUseNativeLineBreak = aEvent->mUseNativeLineBreak;
eventOnRoot.refPoint = aEvent->refPoint;
if (rootWidget != aEvent->widget) {
eventOnRoot.refPoint += aEvent->widget->WidgetToScreenOffset() -
if (rootWidget != aEvent->mWidget) {
eventOnRoot.refPoint += aEvent->mWidget->WidgetToScreenOffset() -
rootWidget->WidgetToScreenOffset();
}
nsPoint ptInRoot =
@ -1611,7 +1611,7 @@ ContentEventHandler::OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent)
return rv;
}
WidgetQueryContentEvent textRect(true, eQueryTextRect, aEvent->widget);
WidgetQueryContentEvent textRect(true, eQueryTextRect, aEvent->mWidget);
textRect.InitForQueryTextRect(offset, 1, aEvent->mUseNativeLineBreak);
rv = OnQueryTextRect(&textRect);
NS_ENSURE_SUCCESS(rv, rv);
@ -1637,14 +1637,15 @@ ContentEventHandler::OnQueryDOMWidgetHittest(WidgetQueryContentEvent* aEvent)
aEvent->mSucceeded = false;
aEvent->mReply.mWidgetIsHit = false;
NS_ENSURE_TRUE(aEvent->widget, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(aEvent->mWidget, NS_ERROR_FAILURE);
nsIDocument* doc = mPresShell->GetDocument();
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
nsIFrame* docFrame = mPresShell->GetRootFrame();
NS_ENSURE_TRUE(docFrame, NS_ERROR_FAILURE);
LayoutDeviceIntPoint eventLoc = aEvent->refPoint + aEvent->widget->WidgetToScreenOffset();
LayoutDeviceIntPoint eventLoc =
aEvent->refPoint + aEvent->mWidget->WidgetToScreenOffset();
nsIntRect docFrameRect = docFrame->GetScreenRect(); // Returns CSS pixels
CSSIntPoint eventLocCSS(
mPresContext->DevPixelsToIntCSSPixels(eventLoc.x) - docFrameRect.x,
@ -1661,7 +1662,7 @@ ContentEventHandler::OnQueryDOMWidgetHittest(WidgetQueryContentEvent* aEvent)
} else if (targetFrame) {
targetWidget = targetFrame->GetNearestWidget();
}
if (aEvent->widget == targetWidget) {
if (aEvent->mWidget == targetWidget) {
aEvent->mReply.mWidgetIsHit = true;
}
}

Просмотреть файл

@ -905,7 +905,7 @@ Event::GetScreenCoords(nsPresContext* aPresContext,
// Doing a straight conversion from LayoutDeviceIntPoint to CSSIntPoint
// seem incorrect, but it is needed to maintain legacy functionality.
WidgetGUIEvent* guiEvent = aEvent->AsGUIEvent();
if (!aPresContext || !(guiEvent && guiEvent->widget)) {
if (!aPresContext || !(guiEvent && guiEvent->mWidget)) {
return CSSIntPoint(aPoint.x, aPoint.y);
}
@ -916,7 +916,7 @@ Event::GetScreenCoords(nsPresContext* aPresContext,
pt = pt.RemoveResolution(nsLayoutUtils::GetCurrentAPZResolutionScale(ps));
}
pt += LayoutDevicePixel::ToAppUnits(guiEvent->widget->WidgetToScreenOffset(),
pt += LayoutDevicePixel::ToAppUnits(guiEvent->mWidget->WidgetToScreenOffset(),
aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom());
return CSSPixel::FromAppUnitsRounded(pt);
@ -964,7 +964,7 @@ Event::GetClientCoords(nsPresContext* aPresContext,
aEvent->mClass != ePointerEventClass &&
aEvent->mClass != eSimpleGestureEventClass) ||
!aPresContext ||
!aEvent->AsGUIEvent()->widget) {
!aEvent->AsGUIEvent()->mWidget) {
return aDefaultPoint;
}

Просмотреть файл

@ -822,7 +822,7 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
// composition event.
WidgetCompositionEvent* compositionEvent = aEvent->AsCompositionEvent();
WidgetQueryContentEvent selectedText(true, eQuerySelectedText,
compositionEvent->widget);
compositionEvent->mWidget);
HandleQueryContentEvent(&selectedText);
NS_ASSERTION(selectedText.mSucceeded, "Failed to get selected text");
compositionEvent->mData = selectedText.mReply.mString;
@ -1584,12 +1584,14 @@ EventStateManager::BeginTrackingDragGesture(nsPresContext* aPresContext,
WidgetMouseEvent* inDownEvent,
nsIFrame* inDownFrame)
{
if (!inDownEvent->widget)
if (!inDownEvent->mWidget) {
return;
}
// Note that |inDownEvent| could be either a mouse down event or a
// synthesized mouse move event.
mGestureDownPoint = inDownEvent->refPoint + inDownEvent->widget->WidgetToScreenOffset();
mGestureDownPoint =
inDownEvent->refPoint + inDownEvent->mWidget->WidgetToScreenOffset();
if (inDownFrame) {
inDownFrame->GetContentForEvent(inDownEvent,
@ -1632,13 +1634,14 @@ EventStateManager::StopTrackingDragGesture()
void
EventStateManager::FillInEventFromGestureDown(WidgetMouseEvent* aEvent)
{
NS_ASSERTION(aEvent->widget == mCurrentTarget->GetNearestWidget(),
NS_ASSERTION(aEvent->mWidget == mCurrentTarget->GetNearestWidget(),
"Incorrect widget in event");
// Set the coordinates in the new event to the coordinates of
// the old event, adjusted for the fact that the widget might be
// different
aEvent->refPoint = mGestureDownPoint - aEvent->widget->WidgetToScreenOffset();
aEvent->refPoint =
mGestureDownPoint - aEvent->mWidget->WidgetToScreenOffset();
aEvent->mModifiers = mGestureModifiers;
aEvent->buttons = mGestureDownButtons;
}
@ -1694,7 +1697,8 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
}
// fire drag gesture if mouse has moved enough
LayoutDeviceIntPoint pt = aEvent->refPoint + aEvent->widget->WidgetToScreenOffset();
LayoutDeviceIntPoint pt =
aEvent->refPoint + aEvent->mWidget->WidgetToScreenOffset();
LayoutDeviceIntPoint distance = pt - mGestureDownPoint;
if (Abs(distance.x) > AssertedCast<uint32_t>(pixelThresholdX) ||
Abs(distance.y) > AssertedCast<uint32_t>(pixelThresholdY)) {
@ -2294,11 +2298,10 @@ EventStateManager::SendLineScrollEvent(nsIFrame* aTargetFrame,
}
WidgetMouseScrollEvent event(aEvent->IsTrusted(),
eLegacyMouseLineOrPageScroll, aEvent->widget);
eLegacyMouseLineOrPageScroll, aEvent->mWidget);
event.mFlags.mDefaultPrevented = aState.mDefaultPrevented;
event.mFlags.mDefaultPreventedByContent = aState.mDefaultPreventedByContent;
event.refPoint = aEvent->refPoint;
event.widget = aEvent->widget;
event.mTime = aEvent->mTime;
event.mTimeStamp = aEvent->mTimeStamp;
event.mModifiers = aEvent->mModifiers;
@ -2334,11 +2337,10 @@ EventStateManager::SendPixelScrollEvent(nsIFrame* aTargetFrame,
}
WidgetMouseScrollEvent event(aEvent->IsTrusted(),
eLegacyMousePixelScroll, aEvent->widget);
eLegacyMousePixelScroll, aEvent->mWidget);
event.mFlags.mDefaultPrevented = aState.mDefaultPrevented;
event.mFlags.mDefaultPreventedByContent = aState.mDefaultPreventedByContent;
event.refPoint = aEvent->refPoint;
event.widget = aEvent->widget;
event.mTime = aEvent->mTime;
event.mTimeStamp = aEvent->mTimeStamp;
event.mModifiers = aEvent->mModifiers;
@ -3423,8 +3425,8 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
event.refPoint = mouseEvent->refPoint;
if (mouseEvent->widget) {
event.refPoint += mouseEvent->widget->WidgetToScreenOffset();
if (mouseEvent->mWidget) {
event.refPoint += mouseEvent->mWidget->WidgetToScreenOffset();
}
event.refPoint -= widget->WidgetToScreenOffset();
event.mModifiers = mouseEvent->mModifiers;
@ -3846,7 +3848,7 @@ CreateMouseOrPointerWidgetEvent(WidgetMouseEvent* aMouseEvent,
nsAutoPtr<WidgetPointerEvent> newPointerEvent;
newPointerEvent =
new WidgetPointerEvent(aMouseEvent->IsTrusted(), aMessage,
aMouseEvent->widget);
aMouseEvent->mWidget);
newPointerEvent->isPrimary = sourcePointer->isPrimary;
newPointerEvent->pointerId = sourcePointer->pointerId;
newPointerEvent->width = sourcePointer->width;
@ -3860,7 +3862,7 @@ CreateMouseOrPointerWidgetEvent(WidgetMouseEvent* aMouseEvent,
} else {
aNewEvent =
new WidgetMouseEvent(aMouseEvent->IsTrusted(), aMessage,
aMouseEvent->widget, WidgetMouseEvent::eReal);
aMouseEvent->mWidget, WidgetMouseEvent::eReal);
aNewEvent->relatedTarget = aRelatedContent;
}
aNewEvent->refPoint = aMouseEvent->refPoint;
@ -4205,7 +4207,7 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent)
// Mouse movement is reported on the MouseEvent.movement{X,Y} fields.
// Movement is calculated in UIEvent::GetMovementPoint() as:
// previous_mousemove_refPoint - current_mousemove_refPoint.
if (sIsPointerLocked && aMouseEvent->widget) {
if (sIsPointerLocked && aMouseEvent->mWidget) {
// The pointer is locked. If the pointer is not located at the center of
// the window, dispatch a synthetic mousemove to return the pointer there.
// Doing this between "real" pointer moves gives the impression that the
@ -4213,7 +4215,7 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent)
// boundary. We cancel the synthetic event so that we don't end up
// dispatching the centering move event to content.
LayoutDeviceIntPoint center =
GetWindowClientRectCenter(aMouseEvent->widget);
GetWindowClientRectCenter(aMouseEvent->mWidget);
aMouseEvent->lastRefPoint = center;
if (aMouseEvent->refPoint != center) {
// Mouse move doesn't finish at the center of the window. Dispatch a
@ -4222,8 +4224,8 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent)
// we've dispatched a synthetic mouse movement, so we can cancel it
// in the other branch here.
sSynthCenteringPoint = center;
aMouseEvent->widget->SynthesizeNativeMouseMove(
center + aMouseEvent->widget->WidgetToScreenOffset(), nullptr);
aMouseEvent->mWidget->SynthesizeNativeMouseMove(
center + aMouseEvent->mWidget->WidgetToScreenOffset(), nullptr);
} else if (aMouseEvent->refPoint == sSynthCenteringPoint) {
// This is the "synthetic native" event we dispatched to re-center the
// pointer. Cancel it so we don't expose the centering move to content.
@ -4290,7 +4292,7 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent)
OverOutElementsWrapper* helper = GetWrapperByEventID(aMouseEvent);
if (helper->mLastOverFrame &&
nsContentUtils::GetTopLevelWidget(aMouseEvent->widget) !=
nsContentUtils::GetTopLevelWidget(aMouseEvent->mWidget) !=
nsContentUtils::GetTopLevelWidget(helper->mLastOverFrame->GetNearestWidget())) {
// the Mouse/PointerOut event widget doesn't have same top widget with
// mLastOverFrame, it's a spurious event for mLastOverFrame
@ -4471,7 +4473,7 @@ EventStateManager::FireDragEnterOrExit(nsPresContext* aPresContext,
nsWeakFrame& aTargetFrame)
{
nsEventStatus status = nsEventStatus_eIgnore;
WidgetDragEvent event(aDragEvent->IsTrusted(), aMessage, aDragEvent->widget);
WidgetDragEvent event(aDragEvent->IsTrusted(), aMessage, aDragEvent->mWidget);
event.refPoint = aDragEvent->refPoint;
event.mModifiers = aDragEvent->mModifiers;
event.buttons = aDragEvent->buttons;
@ -4507,7 +4509,8 @@ EventStateManager::FireDragEnterOrExit(nsPresContext* aPresContext,
if (aMessage == eDragExit && IsRemoteTarget(aTargetContent)) {
nsEventStatus status = nsEventStatus_eIgnore;
WidgetDragEvent remoteEvent(aDragEvent->IsTrusted(), aMessage, aDragEvent->widget);
WidgetDragEvent remoteEvent(aDragEvent->IsTrusted(), aMessage,
aDragEvent->mWidget);
remoteEvent.AssignDragEventData(*aDragEvent, true);
HandleCrossProcessEvent(&remoteEvent, &status);
}
@ -4625,7 +4628,7 @@ EventStateManager::CheckForAndDispatchClick(WidgetMouseEvent* aEvent,
if (0 != aEvent->clickCount) {
//Check that the window isn't disabled before firing a click
//(see bug 366544).
if (aEvent->widget && !aEvent->widget->IsEnabled()) {
if (aEvent->mWidget && !aEvent->mWidget->IsEnabled()) {
return ret;
}
//fire click
@ -4634,7 +4637,7 @@ EventStateManager::CheckForAndDispatchClick(WidgetMouseEvent* aEvent,
aEvent->button == WidgetMouseEvent::eRightButton);
WidgetMouseEvent event(aEvent->IsTrusted(), eMouseClick,
aEvent->widget, WidgetMouseEvent::eReal);
aEvent->mWidget, WidgetMouseEvent::eReal);
event.refPoint = aEvent->refPoint;
event.clickCount = aEvent->clickCount;
event.mModifiers = aEvent->mModifiers;
@ -4668,7 +4671,7 @@ EventStateManager::CheckForAndDispatchClick(WidgetMouseEvent* aEvent,
mouseContent && mouseContent->IsInComposedDoc()) {
//fire double click
WidgetMouseEvent event2(aEvent->IsTrusted(), eMouseDoubleClick,
aEvent->widget, WidgetMouseEvent::eReal);
aEvent->mWidget, WidgetMouseEvent::eReal);
event2.refPoint = aEvent->refPoint;
event2.clickCount = aEvent->clickCount;
event2.mModifiers = aEvent->mModifiers;

Просмотреть файл

@ -870,7 +870,7 @@ protected:
/**
* Set the fields of aEvent to reflect the mouse position and modifier keys
* that were set when the user first pressed the mouse button (stored by
* BeginTrackingDragGesture). aEvent->widget must be
* BeginTrackingDragGesture). aEvent->mWidget must be
* mCurrentTarget->GetNearestWidget().
*/
void FillInEventFromGestureDown(WidgetMouseEvent* aEvent);

Просмотреть файл

@ -758,7 +758,7 @@ IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext,
}
if (!aMouseEvent->IsTrusted() ||
aMouseEvent->DefaultPrevented() ||
!aMouseEvent->widget) {
!aMouseEvent->mWidget) {
return false;
}
// Now, we need to notify only mouse down and mouse up event.
@ -776,7 +776,7 @@ IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext,
RefPtr<IMEContentObserver> kungFuDeathGrip(this);
WidgetQueryContentEvent charAtPt(true, eQueryCharacterAtPoint,
aMouseEvent->widget);
aMouseEvent->mWidget);
charAtPt.refPoint = aMouseEvent->refPoint;
ContentEventHandler handler(aPresContext);
handler.OnQueryCharacterAtPoint(&charAtPt);
@ -801,8 +801,8 @@ IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext,
}
// The refPt is relative to its widget.
// We should notify it with offset in the widget.
if (aMouseEvent->widget != mWidget) {
charAtPt.refPoint += aMouseEvent->widget->WidgetToScreenOffset() -
if (aMouseEvent->mWidget != mWidget) {
charAtPt.refPoint += aMouseEvent->mWidget->WidgetToScreenOffset() -
mWidget->WidgetToScreenOffset();
}

Просмотреть файл

@ -1147,7 +1147,7 @@ IMEStateManager::DispatchCompositionEvent(
("ISM: IMEStateManager::DispatchCompositionEvent(aNode=0x%p, "
"aPresContext=0x%p, aCompositionEvent={ mMessage=%s, "
"mNativeIMEContext={ mRawNativeIMEContext=0x%X, "
"mOriginProcessID=0x%X }, widget(0x%p)={ "
"mOriginProcessID=0x%X }, mWidget(0x%p)={ "
"GetNativeIMEContext()={ mRawNativeIMEContext=0x%X, "
"mOriginProcessID=0x%X }, Destroyed()=%s }, "
"mFlags={ mIsTrusted=%s, mPropagationStopped=%s } }, "
@ -1156,10 +1156,10 @@ IMEStateManager::DispatchCompositionEvent(
ToChar(aCompositionEvent->mMessage),
aCompositionEvent->mNativeIMEContext.mRawNativeIMEContext,
aCompositionEvent->mNativeIMEContext.mOriginProcessID,
aCompositionEvent->widget.get(),
aCompositionEvent->widget->GetNativeIMEContext().mRawNativeIMEContext,
aCompositionEvent->widget->GetNativeIMEContext().mOriginProcessID,
GetBoolName(aCompositionEvent->widget->Destroyed()),
aCompositionEvent->mWidget.get(),
aCompositionEvent->mWidget->GetNativeIMEContext().mRawNativeIMEContext,
aCompositionEvent->mWidget->GetNativeIMEContext().mOriginProcessID,
GetBoolName(aCompositionEvent->mWidget->Destroyed()),
GetBoolName(aCompositionEvent->mFlags.mIsTrusted),
GetBoolName(aCompositionEvent->mFlags.mPropagationStopped),
GetBoolName(aIsSynthesized), tabParent.get()));
@ -1217,7 +1217,7 @@ IMEStateManager::DispatchCompositionEvent(
composition->WasNativeCompositionEndEventDiscarded()) &&
aCompositionEvent->CausesDOMCompositionEndEvent()) {
TextCompositionArray::index_type i =
sTextCompositions->IndexOf(aCompositionEvent->widget);
sTextCompositions->IndexOf(aCompositionEvent->mWidget);
if (i != TextCompositionArray::NoIndex) {
MOZ_LOG(sISMLog, LogLevel::Debug,
("ISM: IMEStateManager::DispatchCompositionEvent(), "
@ -1266,7 +1266,7 @@ IMEStateManager::HandleSelectionEvent(nsPresContext* aPresContext,
}
RefPtr<TextComposition> composition = sTextCompositions ?
sTextCompositions->GetCompositionFor(aSelectionEvent->widget) : nullptr;
sTextCompositions->GetCompositionFor(aSelectionEvent->mWidget) : nullptr;
if (composition) {
// When there is a composition, TextComposition should guarantee that the
// selection event will be handled in same target as composition events.
@ -1290,17 +1290,17 @@ IMEStateManager::OnCompositionEventDiscarded(
MOZ_LOG(sISMLog, LogLevel::Info,
("ISM: IMEStateManager::OnCompositionEventDiscarded(aCompositionEvent={ "
"mMessage=%s, mNativeIMEContext={ mRawNativeIMEContext=0x%X, "
"mOriginProcessID=0x%X }, widget(0x%p)={ "
"mOriginProcessID=0x%X }, mWidget(0x%p)={ "
"GetNativeIMEContext()={ mRawNativeIMEContext=0x%X, "
"mOriginProcessID=0x%X }, Destroyed()=%s }, "
"mFlags={ mIsTrusted=%s } })",
ToChar(aCompositionEvent->mMessage),
aCompositionEvent->mNativeIMEContext.mRawNativeIMEContext,
aCompositionEvent->mNativeIMEContext.mOriginProcessID,
aCompositionEvent->widget.get(),
aCompositionEvent->widget->GetNativeIMEContext().mRawNativeIMEContext,
aCompositionEvent->widget->GetNativeIMEContext().mOriginProcessID,
GetBoolName(aCompositionEvent->widget->Destroyed()),
aCompositionEvent->mWidget.get(),
aCompositionEvent->mWidget->GetNativeIMEContext().mRawNativeIMEContext,
aCompositionEvent->mWidget->GetNativeIMEContext().mOriginProcessID,
GetBoolName(aCompositionEvent->mWidget->Destroyed()),
GetBoolName(aCompositionEvent->mFlags.mIsTrusted)));
if (!aCompositionEvent->IsTrusted()) {
@ -1314,7 +1314,7 @@ IMEStateManager::OnCompositionEventDiscarded(
}
RefPtr<TextComposition> composition =
sTextCompositions->GetCompositionFor(aCompositionEvent->widget);
sTextCompositions->GetCompositionFor(aCompositionEvent->mWidget);
if (!composition) {
// If the PresShell has been being destroyed during composition,
// a TextComposition instance for the composition was already removed from

Просмотреть файл

@ -95,7 +95,7 @@ TextComposition::MaybeDispatchCompositionUpdate(
{
MOZ_RELEASE_ASSERT(!mTabParent);
if (!IsValidStateForComposition(aCompositionEvent->widget)) {
if (!IsValidStateForComposition(aCompositionEvent->mWidget)) {
return false;
}
@ -103,7 +103,7 @@ TextComposition::MaybeDispatchCompositionUpdate(
return true;
}
CloneAndDispatchAs(aCompositionEvent, eCompositionUpdate);
return IsValidStateForComposition(aCompositionEvent->widget);
return IsValidStateForComposition(aCompositionEvent->mWidget);
}
BaseEventFlags
@ -115,11 +115,11 @@ TextComposition::CloneAndDispatchAs(
{
MOZ_RELEASE_ASSERT(!mTabParent);
MOZ_ASSERT(IsValidStateForComposition(aCompositionEvent->widget),
MOZ_ASSERT(IsValidStateForComposition(aCompositionEvent->mWidget),
"Should be called only when it's safe to dispatch an event");
WidgetCompositionEvent compositionEvent(aCompositionEvent->IsTrusted(),
aMessage, aCompositionEvent->widget);
aMessage, aCompositionEvent->mWidget);
compositionEvent.mTime = aCompositionEvent->mTime;
compositionEvent.mTimeStamp = aCompositionEvent->mTimeStamp;
compositionEvent.mData = aCompositionEvent->mData;
@ -279,7 +279,7 @@ TextComposition::DispatchCompositionEvent(
aCompositionEvent->mRanges = nullptr;
}
if (!IsValidStateForComposition(aCompositionEvent->widget)) {
if (!IsValidStateForComposition(aCompositionEvent->mWidget)) {
*aStatus = nsEventStatus_eConsumeNoDefault;
return;
}
@ -377,7 +377,7 @@ TextComposition::DispatchCompositionEvent(
*aStatus = nsEventStatus_eConsumeNoDefault;
}
if (!IsValidStateForComposition(aCompositionEvent->widget)) {
if (!IsValidStateForComposition(aCompositionEvent->mWidget)) {
return;
}

Просмотреть файл

@ -125,7 +125,7 @@ UIEvent::GetMovementPoint()
mEvent->mClass != eDragEventClass &&
mEvent->mClass != ePointerEventClass &&
mEvent->mClass != eSimpleGestureEventClass) ||
!mEvent->AsGUIEvent()->widget) {
!mEvent->AsGUIEvent()->mWidget) {
return nsIntPoint(0, 0);
}

Просмотреть файл

@ -338,8 +338,8 @@ WheelTransaction::SetTimeout()
WheelTransaction::GetScreenPoint(WidgetGUIEvent* aEvent)
{
NS_ASSERTION(aEvent, "aEvent is null");
NS_ASSERTION(aEvent->widget, "aEvent-widget is null");
return (aEvent->refPoint + aEvent->widget->WidgetToScreenOffset())
NS_ASSERTION(aEvent->mWidget, "aEvent-mWidget is null");
return (aEvent->refPoint + aEvent->mWidget->WidgetToScreenOffset())
.ToUnknownPoint();
}

Просмотреть файл

@ -119,9 +119,7 @@ CreateDirectoryTaskChild::HandlerCallback()
}
RefPtr<Directory> dir = Directory::Create(mFileSystem->GetParentObject(),
mTargetPath,
Directory::eNotDOMRootDirectory,
mFileSystem);
mTargetPath, mFileSystem);
MOZ_ASSERT(dir);
mPromise->MaybeResolve(dir);

Просмотреть файл

@ -115,10 +115,32 @@ DeviceStorageFileSystem::GetParentObject() const
}
void
DeviceStorageFileSystem::GetRootName(nsAString& aRetval) const
DeviceStorageFileSystem::GetDirectoryName(nsIFile* aFile, nsAString& aRetval,
ErrorResult& aRv) const
{
AssertIsOnOwningThread();
aRetval = mStorageName;
MOZ_ASSERT(aFile);
nsCOMPtr<nsIFile> rootPath;
aRv = NS_NewLocalFile(LocalOrDeviceStorageRootPath(), false,
getter_AddRefs(rootPath));
if (NS_WARN_IF(aRv.Failed())) {
return;
}
bool equal = false;
aRv = aFile->Equals(rootPath, &equal);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (equal) {
aRetval = mStorageName;
return;
}
FileSystemBase::GetDirectoryName(aFile, aRetval, aRv);
NS_WARN_IF(aRv.Failed());
}
bool

Просмотреть файл

@ -30,6 +30,9 @@ public:
virtual already_AddRefed<FileSystemBase>
Clone() override;
virtual bool
ShouldCreateDirectory() override { return true; }
virtual void
Shutdown() override;
@ -37,7 +40,8 @@ public:
GetParentObject() const override;
virtual void
GetRootName(nsAString& aRetval) const override;
GetDirectoryName(nsIFile* aFile, nsAString& aRetval,
ErrorResult& aRv) const override;
virtual bool
IsSafeFile(nsIFile* aFile) const override;

Просмотреть файл

@ -137,8 +137,7 @@ Directory::GetRoot(FileSystemBase* aFileSystem, ErrorResult& aRv)
}
RefPtr<GetFileOrDirectoryTaskChild> task =
GetFileOrDirectoryTaskChild::Create(aFileSystem, path, eDOMRootDirectory,
true, aRv);
GetFileOrDirectoryTaskChild::Create(aFileSystem, path, true, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
@ -149,7 +148,7 @@ Directory::GetRoot(FileSystemBase* aFileSystem, ErrorResult& aRv)
/* static */ already_AddRefed<Directory>
Directory::Create(nsISupports* aParent, nsIFile* aFile,
DirectoryType aType, FileSystemBase* aFileSystem)
FileSystemBase* aFileSystem)
{
MOZ_ASSERT(aParent);
MOZ_ASSERT(aFile);
@ -158,27 +157,17 @@ Directory::Create(nsISupports* aParent, nsIFile* aFile,
bool isDir;
nsresult rv = aFile->IsDirectory(&isDir);
MOZ_ASSERT(NS_SUCCEEDED(rv) && isDir);
if (aType == eNotDOMRootDirectory) {
RefPtr<nsIFile> parent;
rv = aFile->GetParent(getter_AddRefs(parent));
// We must have a parent if this is not the root directory.
MOZ_ASSERT(NS_SUCCEEDED(rv) && parent);
}
#endif
RefPtr<Directory> directory =
new Directory(aParent, aFile, aType, aFileSystem);
RefPtr<Directory> directory = new Directory(aParent, aFile, aFileSystem);
return directory.forget();
}
Directory::Directory(nsISupports* aParent,
nsIFile* aFile,
DirectoryType aType,
FileSystemBase* aFileSystem)
: mParent(aParent)
, mFile(aFile)
, mType(aType)
{
MOZ_ASSERT(aFile);
@ -213,18 +202,12 @@ Directory::GetName(nsAString& aRetval, ErrorResult& aRv)
{
aRetval.Truncate();
if (mType == eDOMRootDirectory) {
RefPtr<FileSystemBase> fs = GetFileSystem(aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
fs->GetRootName(aRetval);
RefPtr<FileSystemBase> fs = GetFileSystem(aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
aRv = mFile->GetLeafName(aRetval);
NS_WARN_IF(aRv.Failed());
fs->GetDirectoryName(mFile, aRetval, aRv);
}
already_AddRefed<Promise>
@ -318,8 +301,7 @@ Directory::Get(const nsAString& aPath, ErrorResult& aRv)
}
RefPtr<GetFileOrDirectoryTaskChild> task =
GetFileOrDirectoryTaskChild::Create(fs, realPath, eNotDOMRootDirectory,
false, aRv);
GetFileOrDirectoryTaskChild::Create(fs, realPath, false, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
@ -409,7 +391,7 @@ Directory::GetPath(nsAString& aRetval, ErrorResult& aRv)
return;
}
fs->GetDOMPath(mFile, mType, mPath, aRv);
fs->GetDOMPath(mFile, mPath, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
@ -438,7 +420,7 @@ Directory::GetFilesAndDirectories(ErrorResult& aRv)
}
RefPtr<GetDirectoryListingTaskChild> task =
GetDirectoryListingTaskChild::Create(fs, mFile, mType, mFilters, aRv);
GetDirectoryListingTaskChild::Create(fs, mFile, mFilters, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
@ -478,10 +460,6 @@ FileSystemBase*
Directory::GetFileSystem(ErrorResult& aRv)
{
if (!mFileSystem) {
// Any subdir inherits the FileSystem of the parent Directory. If we are
// here it's because we are dealing with the DOM root.
MOZ_ASSERT(mType == eDOMRootDirectory);
nsAutoString path;
aRv = mFile->GetPath(path);
if (NS_WARN_IF(aRv.Failed())) {

Просмотреть файл

@ -59,20 +59,9 @@ public:
static already_AddRefed<Promise>
GetRoot(FileSystemBase* aFileSystem, ErrorResult& aRv);
enum DirectoryType {
// When a directory is selected using a HTMLInputElement, that will be the
// DOM root directory and its name will be '/'. All the sub directory will
// be called with they real name. We use this enum to mark what we must
// consider the '/' of this DOM filesystem.
eDOMRootDirectory,
// All the sub directories of the '/' will be marked using this other value.
eNotDOMRootDirectory
};
static already_AddRefed<Directory>
Create(nsISupports* aParent, nsIFile* aDirectory,
DirectoryType aType, FileSystemBase* aFileSystem = 0);
FileSystemBase* aFileSystem = 0);
// ========= Begin WebIDL bindings. ===========
@ -145,17 +134,12 @@ public:
FileSystemBase*
GetFileSystem(ErrorResult& aRv);
DirectoryType Type() const
{
return mType;
}
bool
ClonableToDifferentThreadOrProcess() const;
private:
Directory(nsISupports* aParent,
nsIFile* aFile, DirectoryType aType,
nsIFile* aFile,
FileSystemBase* aFileSystem = nullptr);
~Directory();
@ -172,7 +156,6 @@ private:
nsCOMPtr<nsISupports> mParent;
RefPtr<FileSystemBase> mFileSystem;
nsCOMPtr<nsIFile> mFile;
DirectoryType mType;
nsString mFilters;
nsString mPath;

Просмотреть файл

@ -110,19 +110,26 @@ FileSystemBase::IsSafeDirectory(Directory* aDir) const
return false;
}
void
FileSystemBase::GetDirectoryName(nsIFile* aFile, nsAString& aRetval,
ErrorResult& aRv) const
{
AssertIsOnOwningThread();
MOZ_ASSERT(aFile);
aRv = aFile->GetLeafName(aRetval);
NS_WARN_IF(aRv.Failed());
}
void
FileSystemBase::GetDOMPath(nsIFile* aFile,
Directory::DirectoryType aType,
nsAString& aRetval,
ErrorResult& aRv) const
{
AssertIsOnOwningThread();
MOZ_ASSERT(aFile);
if (aType == Directory::eDOMRootDirectory) {
aRetval.AssignLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
return;
}
aRetval.Truncate();
nsCOMPtr<nsIFile> fileSystemPath;
aRv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(LocalOrDeviceStorageRootPath()),
@ -131,8 +138,6 @@ FileSystemBase::GetDOMPath(nsIFile* aFile,
return;
}
MOZ_ASSERT(FileSystemUtils::IsDescendantPath(fileSystemPath, aFile));
nsCOMPtr<nsIFile> path;
aRv = aFile->Clone(getter_AddRefs(path));
if (NS_WARN_IF(aRv.Failed())) {
@ -142,6 +147,14 @@ FileSystemBase::GetDOMPath(nsIFile* aFile,
nsTArray<nsString> parts;
while (true) {
nsAutoString leafName;
aRv = path->GetLeafName(leafName);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
parts.AppendElement(leafName);
bool equal = false;
aRv = fileSystemPath->Equals(path, &equal);
if (NS_WARN_IF(aRv.Failed())) {
@ -152,14 +165,6 @@ FileSystemBase::GetDOMPath(nsIFile* aFile,
break;
}
nsAutoString leafName;
aRv = path->GetLeafName(leafName);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
parts.AppendElement(leafName);
nsCOMPtr<nsIFile> parentPath;
aRv = path->GetParent(getter_AddRefs(parentPath));
if (NS_WARN_IF(aRv.Failed())) {
@ -176,8 +181,6 @@ FileSystemBase::GetDOMPath(nsIFile* aFile,
MOZ_ASSERT(!parts.IsEmpty());
aRetval.Truncate();
for (int32_t i = parts.Length() - 1; i >= 0; --i) {
aRetval.AppendLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
aRetval.Append(parts[i]);

Просмотреть файл

@ -37,19 +37,18 @@ public:
virtual already_AddRefed<FileSystemBase>
Clone() = 0;
virtual bool
ShouldCreateDirectory() = 0;
virtual nsISupports*
GetParentObject() const;
/*
* Get the virtual name of the root directory. This name will be exposed to
* the content page.
*/
virtual void
GetRootName(nsAString& aRetval) const = 0;
GetDirectoryName(nsIFile* aFile, nsAString& aRetval,
ErrorResult& aRv) const;
void
GetDOMPath(nsIFile* aFile, Directory::DirectoryType aType,
nsAString& aRetval, ErrorResult& aRv) const;
GetDOMPath(nsIFile* aFile, nsAString& aRetval, ErrorResult& aRv) const;
/*
* Return the local root path of the FileSystem implementation.

Просмотреть файл

@ -28,7 +28,6 @@ namespace dom {
/* static */ already_AddRefed<GetDirectoryListingTaskChild>
GetDirectoryListingTaskChild::Create(FileSystemBase* aFileSystem,
nsIFile* aTargetPath,
Directory::DirectoryType aType,
const nsAString& aFilters,
ErrorResult& aRv)
{
@ -36,7 +35,7 @@ GetDirectoryListingTaskChild::Create(FileSystemBase* aFileSystem,
aFileSystem->AssertIsOnOwningThread();
RefPtr<GetDirectoryListingTaskChild> task =
new GetDirectoryListingTaskChild(aFileSystem, aTargetPath, aType, aFilters);
new GetDirectoryListingTaskChild(aFileSystem, aTargetPath, aFilters);
// aTargetPath can be null. In this case SetError will be called.
@ -57,12 +56,10 @@ GetDirectoryListingTaskChild::Create(FileSystemBase* aFileSystem,
GetDirectoryListingTaskChild::GetDirectoryListingTaskChild(FileSystemBase* aFileSystem,
nsIFile* aTargetPath,
Directory::DirectoryType aType,
const nsAString& aFilters)
: FileSystemTaskChildBase(aFileSystem)
, mTargetPath(aTargetPath)
, mFilters(aFilters)
, mType(aType)
{
MOZ_ASSERT(aFileSystem);
aFileSystem->AssertIsOnOwningThread();
@ -93,7 +90,6 @@ GetDirectoryListingTaskChild::GetRequestParams(const nsString& aSerializedDOMPat
}
return FileSystemGetDirectoryListingParams(aSerializedDOMPath, path,
mType == Directory::eDOMRootDirectory,
mFilters);
}
@ -179,8 +175,7 @@ GetDirectoryListingTaskChild::HandlerCallback()
if (mTargetData[i].mType == Directory::FileOrDirectoryPath::eDirectoryPath) {
RefPtr<Directory> directory =
Directory::Create(mFileSystem->GetParentObject(), path,
Directory::eNotDOMRootDirectory, mFileSystem);
Directory::Create(mFileSystem->GetParentObject(), path, mFileSystem);
MOZ_ASSERT(directory);
// Propogate mFilter onto sub-Directory object:
@ -230,8 +225,6 @@ GetDirectoryListingTaskParent::Create(FileSystemBase* aFileSystem,
return nullptr;
}
task->mType = aParam.isRoot()
? Directory::eDOMRootDirectory : Directory::eNotDOMRootDirectory;
return task.forget();
}
@ -291,11 +284,10 @@ GetDirectoryListingTaskParent::IOWork()
}
if (!exists) {
if (mType == Directory::eNotDOMRootDirectory) {
if (!mFileSystem->ShouldCreateDirectory()) {
return NS_ERROR_DOM_FILE_NOT_FOUND_ERR;
}
// If the root directory doesn't exit, create it.
rv = mTargetPath->Create(nsIFile::DIRECTORY_TYPE, 0777);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;

Просмотреть файл

@ -23,7 +23,6 @@ public:
static already_AddRefed<GetDirectoryListingTaskChild>
Create(FileSystemBase* aFileSystem,
nsIFile* aTargetPath,
Directory::DirectoryType aType,
const nsAString& aFilters,
ErrorResult& aRv);
@ -40,7 +39,6 @@ private:
// If aDirectoryOnly is set, we should ensure that the target is a directory.
GetDirectoryListingTaskChild(FileSystemBase* aFileSystem,
nsIFile* aTargetPath,
Directory::DirectoryType aType,
const nsAString& aFilters);
virtual FileSystemParams
@ -57,7 +55,6 @@ private:
RefPtr<Promise> mPromise;
nsCOMPtr<nsIFile> mTargetPath;
nsString mFilters;
Directory::DirectoryType mType;
// We cannot store File or Directory objects bacause this object is created
// on a different thread and File and Directory are not thread-safe.
@ -89,7 +86,6 @@ private:
nsCOMPtr<nsIFile> mTargetPath;
nsString mFilters;
Directory::DirectoryType mType;
// We cannot store File or Directory objects bacause this object is created
// on a different thread and File and Directory are not thread-safe.

Просмотреть файл

@ -27,7 +27,6 @@ namespace dom {
/* static */ already_AddRefed<GetFileOrDirectoryTaskChild>
GetFileOrDirectoryTaskChild::Create(FileSystemBase* aFileSystem,
nsIFile* aTargetPath,
Directory::DirectoryType aType,
bool aDirectoryOnly,
ErrorResult& aRv)
{
@ -35,8 +34,7 @@ GetFileOrDirectoryTaskChild::Create(FileSystemBase* aFileSystem,
MOZ_ASSERT(aFileSystem);
RefPtr<GetFileOrDirectoryTaskChild> task =
new GetFileOrDirectoryTaskChild(aFileSystem, aTargetPath, aType,
aDirectoryOnly);
new GetFileOrDirectoryTaskChild(aFileSystem, aTargetPath, aDirectoryOnly);
// aTargetPath can be null. In this case SetError will be called.
@ -57,12 +55,10 @@ GetFileOrDirectoryTaskChild::Create(FileSystemBase* aFileSystem,
GetFileOrDirectoryTaskChild::GetFileOrDirectoryTaskChild(FileSystemBase* aFileSystem,
nsIFile* aTargetPath,
Directory::DirectoryType aType,
bool aDirectoryOnly)
: FileSystemTaskChildBase(aFileSystem)
, mTargetPath(aTargetPath)
, mIsDirectory(aDirectoryOnly)
, mType(aType)
{
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
MOZ_ASSERT(aFileSystem);
@ -92,8 +88,7 @@ GetFileOrDirectoryTaskChild::GetRequestParams(const nsString& aSerializedDOMPath
return FileSystemGetFileOrDirectoryParams();
}
return FileSystemGetFileOrDirectoryParams(aSerializedDOMPath, path,
mType == Directory::eDOMRootDirectory);
return FileSystemGetFileOrDirectoryParams(aSerializedDOMPath, path);
}
void
@ -151,7 +146,6 @@ GetFileOrDirectoryTaskChild::HandlerCallback()
if (mIsDirectory) {
RefPtr<Directory> dir = Directory::Create(mFileSystem->GetParentObject(),
mTargetPath,
mType,
mFileSystem);
MOZ_ASSERT(dir);
@ -195,8 +189,6 @@ GetFileOrDirectoryTaskParent::Create(FileSystemBase* aFileSystem,
return nullptr;
}
task->mType = aParam.isRoot()
? Directory::eDOMRootDirectory : Directory::eNotDOMRootDirectory;
return task.forget();
}
@ -248,11 +240,10 @@ GetFileOrDirectoryTaskParent::IOWork()
}
if (!exists) {
if (mType == Directory::eNotDOMRootDirectory) {
if (!mFileSystem->ShouldCreateDirectory()) {
return NS_ERROR_DOM_FILE_NOT_FOUND_ERR;
}
// If the root directory doesn't exit, create it.
rv = mTargetPath->Create(nsIFile::DIRECTORY_TYPE, 0777);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
@ -269,11 +260,6 @@ GetFileOrDirectoryTaskParent::IOWork()
return NS_OK;
}
// Check if the root is a directory.
if (mType == Directory::eDOMRootDirectory) {
return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR;
}
bool isFile;
// Get isFile
rv = mTargetPath->IsFile(&isFile);

Просмотреть файл

@ -23,7 +23,6 @@ public:
static already_AddRefed<GetFileOrDirectoryTaskChild>
Create(FileSystemBase* aFileSystem,
nsIFile* aTargetPath,
Directory::DirectoryType aType,
bool aDirectoryOnly,
ErrorResult& aRv);
@ -51,7 +50,6 @@ private:
// If aDirectoryOnly is set, we should ensure that the target is a directory.
GetFileOrDirectoryTaskChild(FileSystemBase* aFileSystem,
nsIFile* aTargetPath,
Directory::DirectoryType aType,
bool aDirectoryOnly);
RefPtr<Promise> mPromise;
@ -59,7 +57,6 @@ private:
// Whether we get a directory.
bool mIsDirectory;
Directory::DirectoryType mType;
};
class GetFileOrDirectoryTaskParent final : public FileSystemTaskParentBase
@ -90,7 +87,6 @@ private:
// Whether we get a directory.
bool mIsDirectory;
Directory::DirectoryType mType;
};
} // namespace dom

Просмотреть файл

@ -62,13 +62,6 @@ OSFileSystem::GetParentObject() const
return mParent;
}
void
OSFileSystem::GetRootName(nsAString& aRetval) const
{
AssertIsOnOwningThread();
aRetval.AssignLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
}
bool
OSFileSystem::IsSafeFile(nsIFile* aFile) const
{

Просмотреть файл

@ -25,12 +25,18 @@ public:
virtual already_AddRefed<FileSystemBase>
Clone() override;
virtual bool
ShouldCreateDirectory() override
{
MOZ_CRASH("This should not be called.");
// Because OSFileSystem should not be used when the creation of directories
// is needed. For that we have OSFileSystemParent.
return false;
}
virtual nsISupports*
GetParentObject() const override;
virtual void
GetRootName(nsAString& aRetval) const override;
virtual bool
IsSafeFile(nsIFile* aFile) const override;
@ -67,6 +73,9 @@ public:
return nullptr;
}
virtual bool
ShouldCreateDirectory() override { return false; }
virtual nsISupports*
GetParentObject() const override
{
@ -75,7 +84,8 @@ public:
}
virtual void
GetRootName(nsAString& aRetval) const override
GetDirectoryName(nsIFile* aFile, nsAString& aRetval,
ErrorResult& aRv) const override
{
MOZ_CRASH("This should not be called on the PBackground thread.");
}

Просмотреть файл

@ -31,7 +31,7 @@ struct FileSystemGetDirectoryListingParams
{
nsString filesystem;
nsString realPath;
bool isRoot;
// 'filters' could be an array rather than a semicolon separated string
// (we'd then use InfallibleTArray<nsString> internally), but that is
// wasteful. E10s requires us to pass the filters over as a string anyway,
@ -55,7 +55,6 @@ struct FileSystemGetFileOrDirectoryParams
{
nsString filesystem;
nsString realPath;
bool isRoot;
};
struct FileSystemRemoveParams

Просмотреть файл

@ -1,8 +1,7 @@
function test_basic(aDirectory, aNext) {
ok(aDirectory, "Directory exists.");
ok(aDirectory instanceof Directory, "We have a directory.");
is(aDirectory.name, '/', "directory.name must be '/'");
is(aDirectory.path, '/', "directory.path must be '/'");
is(aDirectory.path, '/' + aDirectory.name, "directory.path must be '/'+name");
aNext();
}
@ -16,7 +15,7 @@ function test_getFilesAndDirectories(aDirectory, aRecursive, aNext) {
isnot(data[i].name, '/', "Subdirectory should be called with the leafname");
isnot(data[i].path, '/', "Subdirectory path should be called with the leafname");
isnot(data[i].path, dir.path, "Subdirectory path should contain the parent path.");
is(data[i].path,dir.path + '/' + data[i].name, "Subdirectory path should be called parentdir.path + '/' + leafname");
is(data[i].path, dir.path + '/' + data[i].name, "Subdirectory path should be called parentdir.path + '/' + leafname");
}
}
}
@ -31,7 +30,7 @@ function test_getFilesAndDirectories(aDirectory, aRecursive, aNext) {
ok (data[i] instanceof File || data[i] instanceof Directory, "Just Files or Directories: " + data[i].name);
if (data[i] instanceof Directory) {
isnot(data[i].name, '/', "Subdirectory should be called with the leafname");
is(data[i].path, '/' + data[i].name, "Subdirectory path should be called '/' + leafname");
is(data[i].path, aDirectory.path + '/' + data[i].name, "Subdirectory path should be called parentdir.path + '/' + leafname");
if (aRecursive) {
promises.push(checkSubDir(data[i]));
}

Просмотреть файл

@ -272,8 +272,7 @@ class HTMLInputElementState final : public nsISupports
continue;
}
RefPtr<Directory> directory = Directory::Create(aWindow, file,
Directory::eDOMRootDirectory);
RefPtr<Directory> directory = Directory::Create(aWindow, file);
MOZ_ASSERT(directory);
OwningFileOrDirectory* element = aResult.AppendElement();
@ -2311,8 +2310,7 @@ HTMLInputElement::MozSetDirectory(const nsAString& aDirectoryPath,
return;
}
RefPtr<Directory> directory = Directory::Create(window, file,
Directory::eDOMRootDirectory);
RefPtr<Directory> directory = Directory::Create(window, file);
MOZ_ASSERT(directory);
nsTArray<OwningFileOrDirectory> array;

Просмотреть файл

@ -902,7 +902,7 @@ nsTextInputListener::HandleEvent(nsIDOMEvent* aEvent)
mTxtCtrlElement->IsTextArea() ?
nsIWidget::NativeKeyBindingsForMultiLineEditor :
nsIWidget::NativeKeyBindingsForSingleLineEditor;
nsIWidget* widget = keyEvent->widget;
nsIWidget* widget = keyEvent->mWidget;
// If the event is created by chrome script, the widget is nullptr.
if (!widget) {
widget = mFrame->GetNearestWidget();

Просмотреть файл

@ -425,6 +425,19 @@ private:
NS_IMPL_ISUPPORTS(ConsoleListener, nsIConsoleListener)
// Before we send the error to the parent process (which
// involves copying the memory), truncate any long lines. CSS
// errors in particular share the memory for long lines with
// repeated errors, but the IPC communication we're about to do
// will break that sharing, so we better truncate now.
static void
TruncateString(nsAString& aString)
{
if (aString.Length() > 1000) {
aString.Truncate(1000);
}
}
NS_IMETHODIMP
ConsoleListener::Observe(nsIConsoleMessage* aMessage)
{
@ -440,22 +453,13 @@ ConsoleListener::Observe(nsIConsoleMessage* aMessage)
nsresult rv = scriptError->GetErrorMessage(msg);
NS_ENSURE_SUCCESS(rv, rv);
TruncateString(msg);
rv = scriptError->GetSourceName(sourceName);
NS_ENSURE_SUCCESS(rv, rv);
TruncateString(sourceName);
rv = scriptError->GetSourceLine(sourceLine);
NS_ENSURE_SUCCESS(rv, rv);
// Before we send the error to the parent process (which
// involves copying the memory), truncate any long lines. CSS
// errors in particular share the memory for long lines with
// repeated errors, but the IPC communication we're about to do
// will break that sharing, so we better truncate now.
if (sourceName.Length() > 1000) {
sourceName.Truncate(1000);
}
if (sourceLine.Length() > 1000) {
sourceLine.Truncate(1000);
}
TruncateString(sourceLine);
rv = scriptError->GetCategory(getter_Copies(category));
NS_ENSURE_SUCCESS(rv, rv);
@ -465,6 +469,7 @@ ConsoleListener::Observe(nsIConsoleMessage* aMessage)
NS_ENSURE_SUCCESS(rv, rv);
rv = scriptError->GetFlags(&flags);
NS_ENSURE_SUCCESS(rv, rv);
mChild->SendScriptError(msg, sourceName, sourceLine,
lineNum, colNum, flags, category);
return NS_OK;

Просмотреть файл

@ -1856,7 +1856,7 @@ TabChild::RecvRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
InputAPZContext context(aGuid, aInputBlockId, unused);
WidgetMouseEvent localEvent(aEvent);
localEvent.widget = mPuppetWidget;
localEvent.mWidget = mPuppetWidget;
APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
mPuppetWidget->GetDefaultScale());
APZCCallbackHelper::DispatchWidgetEvent(localEvent);
@ -1879,7 +1879,7 @@ TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& aEvent,
}
WidgetWheelEvent localEvent(aEvent);
localEvent.widget = mPuppetWidget;
localEvent.mWidget = mPuppetWidget;
APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
mPuppetWidget->GetDefaultScale());
APZCCallbackHelper::DispatchWidgetEvent(localEvent);
@ -1923,7 +1923,7 @@ TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
TABC_LOG("Receiving touch event of type %d\n", aEvent.mMessage);
WidgetTouchEvent localEvent(aEvent);
localEvent.widget = mPuppetWidget;
localEvent.mWidget = mPuppetWidget;
APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
mPuppetWidget->GetDefaultScale());
@ -1968,7 +1968,7 @@ TabChild::RecvRealDragEvent(const WidgetDragEvent& aEvent,
const uint32_t& aDropEffect)
{
WidgetDragEvent localEvent(aEvent);
localEvent.widget = mPuppetWidget;
localEvent.mWidget = mPuppetWidget;
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
if (dragSession) {
@ -2004,7 +2004,7 @@ bool
TabChild::RecvPluginEvent(const WidgetPluginEvent& aEvent)
{
WidgetPluginEvent localEvent(aEvent);
localEvent.widget = mPuppetWidget;
localEvent.mWidget = mPuppetWidget;
nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
if (status != nsEventStatus_eConsumeNoDefault) {
// If not consumed, we should call default action
@ -2063,7 +2063,7 @@ TabChild::RecvRealKeyEvent(const WidgetKeyboardEvent& event,
}
WidgetKeyboardEvent localEvent(event);
localEvent.widget = mPuppetWidget;
localEvent.mWidget = mPuppetWidget;
nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
if (event.mMessage == eKeyDown) {
@ -2098,7 +2098,7 @@ bool
TabChild::RecvCompositionEvent(const WidgetCompositionEvent& event)
{
WidgetCompositionEvent localEvent(event);
localEvent.widget = mPuppetWidget;
localEvent.mWidget = mPuppetWidget;
APZCCallbackHelper::DispatchWidgetEvent(localEvent);
Unused << SendOnEventNeedingAckHandled(event.mMessage);
return true;
@ -2108,7 +2108,7 @@ bool
TabChild::RecvSelectionEvent(const WidgetSelectionEvent& event)
{
WidgetSelectionEvent localEvent(event);
localEvent.widget = mPuppetWidget;
localEvent.mWidget = mPuppetWidget;
APZCCallbackHelper::DispatchWidgetEvent(localEvent);
Unused << SendOnEventNeedingAckHandled(event.mMessage);
return true;

Просмотреть файл

@ -1250,7 +1250,7 @@ bool TabParent::RecvDispatchWheelEvent(const mozilla::WidgetWheelEvent& aEvent)
}
WidgetWheelEvent localEvent(aEvent);
localEvent.widget = widget;
localEvent.mWidget = widget;
localEvent.refPoint -= GetChildProcessOffset();
widget->DispatchInputEvent(&localEvent);
@ -1266,7 +1266,7 @@ TabParent::RecvDispatchMouseEvent(const mozilla::WidgetMouseEvent& aEvent)
}
WidgetMouseEvent localEvent(aEvent);
localEvent.widget = widget;
localEvent.mWidget = widget;
localEvent.refPoint -= GetChildProcessOffset();
widget->DispatchInputEvent(&localEvent);
@ -1282,7 +1282,7 @@ TabParent::RecvDispatchKeyboardEvent(const mozilla::WidgetKeyboardEvent& aEvent)
}
WidgetKeyboardEvent localEvent(aEvent);
localEvent.widget = widget;
localEvent.mWidget = widget;
localEvent.refPoint -= GetChildProcessOffset();
widget->DispatchInputEvent(&localEvent);
@ -2020,7 +2020,7 @@ TabParent::RecvDispatchAfterKeyboardEvent(const WidgetKeyboardEvent& aEvent)
NS_ENSURE_TRUE(mFrameElement, true);
WidgetKeyboardEvent localEvent(aEvent);
localEvent.widget = GetWidget();
localEvent.mWidget = GetWidget();
nsIDocument* doc = mFrameElement->OwnerDoc();
nsCOMPtr<nsIPresShell> presShell = doc->GetShell();

Просмотреть файл

@ -6,6 +6,7 @@
#include "AudioConverter.h"
#include <string.h>
#include <speex/speex_resampler.h>
/*
* Parts derived from MythTV AudioConvert Class
@ -20,9 +21,9 @@ namespace mozilla {
AudioConverter::AudioConverter(const AudioConfig& aIn, const AudioConfig& aOut)
: mIn(aIn)
, mOut(aOut)
, mResampler(nullptr)
{
MOZ_DIAGNOSTIC_ASSERT(aIn.Rate() == aOut.Rate() &&
aIn.Format() == aOut.Format() &&
MOZ_DIAGNOSTIC_ASSERT(aIn.Format() == aOut.Format() &&
aIn.Interleaved() == aOut.Interleaved(),
"No format or rate conversion is supported at this stage");
MOZ_DIAGNOSTIC_ASSERT((aIn.Channels() > aOut.Channels() && aOut.Channels() <= 2) ||
@ -30,28 +31,59 @@ AudioConverter::AudioConverter(const AudioConfig& aIn, const AudioConfig& aOut)
"Only downmixing to mono or stereo is supported at this stage");
MOZ_DIAGNOSTIC_ASSERT(aOut.Interleaved(), "planar audio format not supported");
mIn.Layout().MappingTable(mOut.Layout(), mChannelOrderMap);
if (aIn.Rate() != aOut.Rate()) {
int error;
mResampler = speex_resampler_init(aOut.Channels(),
aIn.Rate(),
aOut.Rate(),
SPEEX_RESAMPLER_QUALITY_DEFAULT,
&error);
if (error == RESAMPLER_ERR_SUCCESS) {
speex_resampler_skip_zeros(mResampler);
} else {
NS_WARNING("Failed to initialize resampler.");
mResampler = nullptr;
}
}
}
AudioConverter::~AudioConverter()
{
if (mResampler) {
speex_resampler_destroy(mResampler);
mResampler = nullptr;
}
}
bool
AudioConverter::CanWorkInPlace() const
{
return mIn.Channels() * mIn.Rate() * AudioConfig::SampleSize(mIn.Format()) >=
mOut.Channels() * mOut.Rate() * AudioConfig::SampleSize(mOut.Format());
bool needDownmix = mIn.Channels() > mOut.Channels();
bool canDownmixInPlace =
mIn.Channels() * AudioConfig::SampleSize(mIn.Format()) >=
mOut.Channels() * AudioConfig::SampleSize(mOut.Format());
bool needResample = mIn.Rate() != mOut.Rate();
bool canResampleInPlace = mIn.Rate() >= mOut.Rate();
// We should be able to work in place if 1s of audio input takes less space
// than 1s of audio output. However, as we downmix before resampling we can't
// perform any upsampling in place (e.g. if incoming rate >= outgoing rate)
return (!needDownmix || canDownmixInPlace) &&
(!needResample || canResampleInPlace);
}
size_t
AudioConverter::Process(void* aOut, const void* aIn, size_t aBytes)
AudioConverter::ProcessInternal(void* aOut, const void* aIn, size_t aFrames)
{
if (!CanWorkInPlace()) {
return 0;
}
if (mIn.Channels() > mOut.Channels()) {
return DownmixAudio(aOut, aIn, aBytes);
return DownmixAudio(aOut, aIn, aFrames);
} else if (mIn.Layout() != mOut.Layout() &&
CanReorderAudio()) {
ReOrderInterleavedChannels(aOut, aIn, aBytes);
ReOrderInterleavedChannels(aOut, aIn, aFrames);
} else if (aIn != aOut) {
memmove(aOut, aIn, FramesOutToBytes(aFrames));
}
return aBytes;
return aFrames;
}
// Reorder interleaved channels.
@ -78,7 +110,7 @@ _ReOrderInterleavedChannels(AudioDataType* aOut, const AudioDataType* aIn,
void
AudioConverter::ReOrderInterleavedChannels(void* aOut, const void* aIn,
size_t aDataSize) const
size_t aFrames) const
{
MOZ_DIAGNOSTIC_ASSERT(mIn.Channels() == mOut.Channels());
@ -89,7 +121,7 @@ AudioConverter::ReOrderInterleavedChannels(void* aOut, const void* aIn,
// If channel count is 1, planar and non-planar formats are the same and
// there's nothing to reorder.
if (aOut != aIn) {
memmove(aOut, aIn, aDataSize);
memmove(aOut, aIn, FramesOutToBytes(aFrames));
}
return;
}
@ -98,19 +130,16 @@ AudioConverter::ReOrderInterleavedChannels(void* aOut, const void* aIn,
switch (bits) {
case 8:
_ReOrderInterleavedChannels((uint8_t*)aOut, (const uint8_t*)aIn,
aDataSize/sizeof(uint8_t)/mIn.Channels(),
mIn.Channels(), mChannelOrderMap);
aFrames, mIn.Channels(), mChannelOrderMap);
break;
case 16:
_ReOrderInterleavedChannels((int16_t*)aOut,(const int16_t*)aIn,
aDataSize/sizeof(int16_t)/mIn.Channels(),
mIn.Channels(), mChannelOrderMap);
aFrames, mIn.Channels(), mChannelOrderMap);
break;
default:
MOZ_DIAGNOSTIC_ASSERT(AudioConfig::SampleSize(mOut.Format()) == 4);
_ReOrderInterleavedChannels((int32_t*)aOut,(const int32_t*)aIn,
aDataSize/sizeof(int32_t)/mIn.Channels(),
mIn.Channels(), mChannelOrderMap);
aFrames, mIn.Channels(), mChannelOrderMap);
break;
}
}
@ -121,7 +150,7 @@ static inline int16_t clipTo15(int32_t aX)
}
size_t
AudioConverter::DownmixAudio(void* aOut, const void* aIn, size_t aDataSize) const
AudioConverter::DownmixAudio(void* aOut, const void* aIn, size_t aFrames) const
{
MOZ_ASSERT(mIn.Format() == AudioConfig::FORMAT_S16 ||
mIn.Format() == AudioConfig::FORMAT_FLT);
@ -132,14 +161,12 @@ AudioConverter::DownmixAudio(void* aOut, const void* aIn, size_t aDataSize) cons
mOut.Layout() == AudioConfig::ChannelLayout(1));
uint32_t channels = mIn.Channels();
uint32_t frames =
aDataSize / AudioConfig::SampleSize(mOut.Format()) / channels;
if (channels == 1 && mOut.Channels() == 1) {
if (aOut != aIn) {
memmove(aOut, aIn, aDataSize);
memmove(aOut, aIn, FramesOutToBytes(aFrames));
}
return aDataSize;
return aFrames;
}
if (channels > 2) {
@ -156,7 +183,7 @@ AudioConverter::DownmixAudio(void* aOut, const void* aIn, size_t aDataSize) cons
// Re-write the buffer with downmixed data
const float* in = static_cast<const float*>(aIn);
float* out = static_cast<float*>(aOut);
for (uint32_t i = 0; i < frames; i++) {
for (uint32_t i = 0; i < aFrames; i++) {
float sampL = 0.0;
float sampR = 0.0;
for (uint32_t j = 0; j < channels; j++) {
@ -180,7 +207,7 @@ AudioConverter::DownmixAudio(void* aOut, const void* aIn, size_t aDataSize) cons
// Re-write the buffer with downmixed data
const int16_t* in = static_cast<const int16_t*>(aIn);
int16_t* out = static_cast<int16_t*>(aOut);
for (uint32_t i = 0; i < frames; i++) {
for (uint32_t i = 0; i < aFrames; i++) {
int32_t sampL = 0;
int32_t sampR = 0;
for (uint32_t j = 0; j < channels; j++) {
@ -204,7 +231,7 @@ AudioConverter::DownmixAudio(void* aOut, const void* aIn, size_t aDataSize) cons
if (mIn.Format() == AudioConfig::FORMAT_FLT) {
const float* in = static_cast<const float*>(aIn);
float* out = static_cast<float*>(aOut);
for (uint32_t fIdx = 0; fIdx < frames; ++fIdx) {
for (uint32_t fIdx = 0; fIdx < aFrames; ++fIdx) {
float sample = 0.0;
// The sample of the buffer would be interleaved.
sample = (in[fIdx*channels] + in[fIdx*channels + 1]) * 0.5;
@ -213,7 +240,7 @@ AudioConverter::DownmixAudio(void* aOut, const void* aIn, size_t aDataSize) cons
} else if (mIn.Format() == AudioConfig::FORMAT_S16) {
const int16_t* in = static_cast<const int16_t*>(aIn);
int16_t* out = static_cast<int16_t*>(aOut);
for (uint32_t fIdx = 0; fIdx < frames; ++fIdx) {
for (uint32_t fIdx = 0; fIdx < aFrames; ++fIdx) {
int32_t sample = 0.0;
// The sample of the buffer would be interleaved.
sample = (in[fIdx*channels] + in[fIdx*channels + 1]) * 0.5;
@ -223,7 +250,56 @@ AudioConverter::DownmixAudio(void* aOut, const void* aIn, size_t aDataSize) cons
MOZ_DIAGNOSTIC_ASSERT(false, "Unsupported data type");
}
}
return frames * AudioConfig::SampleSize(mOut.Format()) * mOut.Channels();
return aFrames;
}
} // namespace mozilla
size_t
AudioConverter::ResampleAudio(void* aOut, const void* aIn, size_t aFrames)
{
if (!mResampler) {
return 0;
}
uint32_t outframes = ResampleRecipientFrames(aFrames);
uint32_t inframes = aFrames;
if (mOut.Format() == AudioConfig::FORMAT_FLT) {
const float* in = reinterpret_cast<const float*>(aIn);
float* out = reinterpret_cast<float*>(aOut);
speex_resampler_process_interleaved_float(mResampler, in, &inframes,
out, &outframes);
} else if (mOut.Format() == AudioConfig::FORMAT_S16) {
const int16_t* in = reinterpret_cast<const int16_t*>(aIn);
int16_t* out = reinterpret_cast<int16_t*>(aOut);
speex_resampler_process_interleaved_int(mResampler, in, &inframes,
out, &outframes);
} else {
MOZ_DIAGNOSTIC_ASSERT(false, "Unsupported data type");
}
MOZ_ASSERT(inframes == aFrames, "Some frames will be dropped");
return outframes;
}
size_t
AudioConverter::ResampleRecipientFrames(size_t aFrames) const
{
return (uint64_t)aFrames * mOut.Rate() / mIn.Rate() + 1;
}
size_t
AudioConverter::FramesOutToSamples(size_t aFrames) const
{
return aFrames * mOut.Channels();
}
size_t
AudioConverter::SamplesInToFrames(size_t aSamples) const
{
return aSamples / mIn.Channels();
}
size_t
AudioConverter::FramesOutToBytes(size_t aFrames) const
{
return FramesOutToSamples(aFrames) * AudioConfig::SampleSize(mOut.Format());
}
} // namespace mozilla

Просмотреть файл

@ -9,6 +9,9 @@
#include "MediaInfo.h"
// Forward declaration
typedef struct SpeexResamplerState_ SpeexResamplerState;
namespace mozilla {
template <AudioConfig::SampleFormat T> struct AudioDataBufferTypeChooser;
@ -87,6 +90,16 @@ public:
static_assert(Format == AudioConfig::FORMAT_FLT,
"Conversion not implemented yet");
}
AudioDataBuffer& operator=(AudioDataBuffer&& aOther)
{
mBuffer = Move(aOther.mBuffer);
return *this;
}
AudioDataBuffer& operator=(const AudioDataBuffer& aOther)
{
mBuffer = aOther.mBuffer;
return *this;
}
Value* Data() const { return mBuffer.Data(); }
size_t Length() const { return mBuffer.Length(); }
@ -105,45 +118,110 @@ typedef AudioDataBuffer<AudioConfig::FORMAT_DEFAULT> AudioSampleBuffer;
class AudioConverter {
public:
AudioConverter(const AudioConfig& aIn, const AudioConfig& aOut);
~AudioConverter();
// Convert the AudioDataBuffer.
// Conversion will be done in place if possible. Otherwise a new buffer will
// be returned.
template <AudioConfig::SampleFormat Format, typename Value>
AudioDataBuffer<Format, Value> Process(AudioDataBuffer<Format, Value>&& aBuffer)
{
MOZ_DIAGNOSTIC_ASSERT(mIn.Format() == mOut.Format() && mIn.Format() == Format);
AudioDataBuffer<Format, Value> buffer = Move(aBuffer);
if (CanWorkInPlace()) {
size_t frames = SamplesInToFrames(buffer.Length());
frames = ProcessInternal(buffer.Data(), buffer.Data(), frames);
if (frames && mIn.Rate() != mOut.Rate()) {
frames = ResampleAudio(buffer.Data(), buffer.Data(), frames);
}
AlignedBuffer<Value> temp = buffer.Forget();
temp.SetLength(FramesOutToSamples(frames));
return AudioDataBuffer<Format, Value>(Move(temp));;
}
return Process(buffer);
}
template <AudioConfig::SampleFormat Format, typename Value>
AudioDataBuffer<Format, Value> Process(const AudioDataBuffer<Format, Value>& aBuffer)
{
MOZ_DIAGNOSTIC_ASSERT(mIn.Format() == mOut.Format() && mIn.Format() == Format);
// Perform the downmixing / reordering in temporary buffer.
size_t frames = SamplesInToFrames(aBuffer.Length());
AlignedBuffer<Value> temp1;
if (!temp1.SetLength(FramesOutToSamples(frames))) {
return AudioDataBuffer<Format, Value>(Move(temp1));
}
frames = ProcessInternal(temp1.Data(), aBuffer.Data(), frames);
if (!frames || mIn.Rate() == mOut.Rate()) {
temp1.SetLength(FramesOutToSamples(frames));
return AudioDataBuffer<Format, Value>(Move(temp1));
}
// At this point, temp1 contains the buffer reordered and downmixed.
// If we are downsampling we can re-use it.
AlignedBuffer<Value>* outputBuffer = &temp1;
AlignedBuffer<Value> temp2;
if (mOut.Rate() > mIn.Rate()) {
// We are upsampling, we can't work in place. Allocate another temporary
// buffer where the upsampling will occur.
temp2.SetLength(FramesOutToSamples(ResampleRecipientFrames(frames)));
outputBuffer = &temp2;
}
frames = ResampleAudio(outputBuffer->Data(), temp1.Data(), frames);
outputBuffer->SetLength(FramesOutToSamples(frames));
return AudioDataBuffer<Format, Value>(Move(*outputBuffer));
}
// Attempt to convert the AudioDataBuffer in place.
// Will return 0 if the conversion wasn't possible.
// Process may allocate memory internally should intermediary steps be
// required.
template <AudioConfig::SampleFormat Type, typename Value>
size_t Process(AudioDataBuffer<Type, Value>& aBuffer)
{
MOZ_DIAGNOSTIC_ASSERT(mIn.Format() == mOut.Format() && mIn.Format() == Type);
return Process(aBuffer.Data(), aBuffer.Data(), aBuffer.Size());
}
template <typename Value>
size_t Process(Value* aBuffer, size_t aSamples)
size_t Process(Value* aBuffer, size_t aFrames)
{
MOZ_DIAGNOSTIC_ASSERT(mIn.Format() == mOut.Format());
return Process(aBuffer, aBuffer, aSamples * AudioConfig::SampleSize(mIn.Format()));
if (!CanWorkInPlace()) {
return 0;
}
size_t frames = ProcessInternal(aBuffer, aBuffer, aFrames);
if (frames && mIn.Rate() != mOut.Rate()) {
frames = ResampleAudio(aBuffer, aBuffer, aFrames);
}
return frames;
}
bool CanWorkInPlace() const;
bool CanReorderAudio() const
{
return mIn.Layout().MappingTable(mOut.Layout());
}
const AudioConfig& InputConfig() const { return mIn; }
const AudioConfig& OutputConfig() const { return mOut; }
private:
const AudioConfig mIn;
const AudioConfig mOut;
uint8_t mChannelOrderMap[MAX_AUDIO_CHANNELS];
/**
* Process
* ProcessInternal
* Parameters:
* aOut : destination buffer where converted samples will be copied
* aIn : source buffer
* aBytes: size in bytes of source buffer
* aSamples: number of frames in source buffer
*
* Return Value: size in bytes of samples converted or 0 if error
* Return Value: number of frames converted or 0 if error
*/
size_t Process(void* aOut, const void* aIn, size_t aBytes);
void ReOrderInterleavedChannels(void* aOut, const void* aIn, size_t aDataSize) const;
size_t DownmixAudio(void* aOut, const void* aIn, size_t aDataSize) const;
size_t ProcessInternal(void* aOut, const void* aIn, size_t aFrames);
void ReOrderInterleavedChannels(void* aOut, const void* aIn, size_t aFrames) const;
size_t DownmixAudio(void* aOut, const void* aIn, size_t aFrames) const;
size_t FramesOutToSamples(size_t aFrames) const;
size_t SamplesInToFrames(size_t aSamples) const;
size_t FramesOutToBytes(size_t aFrames) const;
// Resampler context.
SpeexResamplerState* mResampler;
size_t ResampleAudio(void* aOut, const void* aIn, size_t aFrames);
size_t ResampleRecipientFrames(size_t aFrames) const;
};
} // namespace mozilla

Просмотреть файл

@ -331,7 +331,7 @@ AudioStream::Init(uint32_t aNumChannels, uint32_t aRate,
("%s channels: %d, rate: %d for %p", __FUNCTION__, aNumChannels, aRate, this));
mInRate = mOutRate = aRate;
mChannels = aNumChannels;
mOutChannels = (aNumChannels > 2) ? 2 : aNumChannels;
mOutChannels = mIsMonoAudioEnabled ? 1 : aNumChannels;
mDumpFile = OpenDumpFile(this);
@ -353,9 +353,11 @@ AudioStream::Init(uint32_t aNumChannels, uint32_t aRate,
params.format = ToCubebFormat<AUDIO_OUTPUT_FORMAT>::value;
mAudioClock.Init();
AudioConfig inConfig(mChannels, mInRate);
AudioConfig outConfig(mOutChannels, mOutRate);
mAudioConverter = MakeUnique<AudioConverter>(inConfig, outConfig);
if (mIsMonoAudioEnabled) {
AudioConfig inConfig(mChannels, mInRate);
AudioConfig outConfig(mOutChannels, mOutRate);
mAudioConverter = MakeUnique<AudioConverter>(inConfig, outConfig);
}
return OpenCubeb(params);
}
@ -561,14 +563,8 @@ AudioStream::Downmix(Chunk* aChunk)
return false;
}
if (aChunk->Channels() > 2) {
MOZ_ASSERT(mAudioConverter);
mAudioConverter->Process(aChunk->GetWritable(),
aChunk->Channels() * aChunk->Frames());
}
if (aChunk->Channels() >= 2 && mIsMonoAudioEnabled) {
DownmixStereoToMono(aChunk->GetWritable(), aChunk->Frames());
if (mAudioConverter) {
mAudioConverter->Process(aChunk->GetWritable(), aChunk->Frames());
}
return true;

Просмотреть файл

@ -604,6 +604,16 @@ public:
{
return mInterleaved;
}
bool operator==(const AudioConfig& aOther) const
{
return mChannelLayout == aOther.mChannelLayout &&
mRate == aOther.mRate && mFormat == aOther.mFormat &&
mInterleaved == aOther.mInterleaved;
}
bool operator!=(const AudioConfig& aOther) const
{
return !(*this == aOther);
}
static const char* FormatToString(SampleFormat aFormat);
static uint32_t SampleSize(SampleFormat aFormat);

Просмотреть файл

@ -34,10 +34,6 @@
#include "gmp-audio-decode.h"
#include "gmp-video-decode.h"
#if defined(XP_WIN) || defined(XP_MACOSX)
#define PRIMETIME_EME_SUPPORTED 1
#endif
namespace mozilla {
namespace dom {
@ -280,7 +276,7 @@ MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion, aOutMessage, aOutCdmVersion);
}
#ifdef PRIMETIME_EME_SUPPORTED
#ifdef MOZ_ADOBE_EME
if (aKeySystem.EqualsLiteral("com.adobe.primetime")) {
if (!Preferences::GetBool("media.gmp-eme-adobe.enabled", false)) {
aOutMessage = NS_LITERAL_CSTRING("Adobe EME disabled");

Просмотреть файл

@ -8,9 +8,11 @@
#include "MediaQueue.h"
#include "DecodedAudioDataSink.h"
#include "VideoUtils.h"
#include "AudioConverter.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/DebugOnly.h"
#include "gfxPrefs.h"
namespace mozilla {
@ -40,6 +42,14 @@ DecodedAudioDataSink::DecodedAudioDataSink(MediaQueue<MediaData>& aAudioQueue,
, mPlaying(true)
, mPlaybackComplete(false)
{
bool resampling = gfxPrefs::AudioSinkResampling();
uint32_t resamplingRate = gfxPrefs::AudioSinkResampleRate();
mConverter =
MakeUnique<AudioConverter>(
AudioConfig(mInfo.mChannels, mInfo.mRate),
AudioConfig(mInfo.mChannels > 2 && gfxPrefs::AudioSinkForceStereo()
? 2 : mInfo.mChannels,
resampling ? resamplingRate : mInfo.mRate));
}
DecodedAudioDataSink::~DecodedAudioDataSink()
@ -136,7 +146,9 @@ nsresult
DecodedAudioDataSink::InitializeAudioStream(const PlaybackParams& aParams)
{
mAudioStream = new AudioStream(*this);
nsresult rv = mAudioStream->Init(mInfo.mChannels, mInfo.mRate, mChannel);
nsresult rv = mAudioStream->Init(mConverter->OutputConfig().Channels(),
mConverter->OutputConfig().Rate(),
mChannel);
if (NS_FAILED(rv)) {
mAudioStream->Shutdown();
mAudioStream = nullptr;
@ -156,7 +168,8 @@ DecodedAudioDataSink::InitializeAudioStream(const PlaybackParams& aParams)
int64_t
DecodedAudioDataSink::GetEndTime() const
{
CheckedInt64 playedUsecs = FramesToUsecs(mWritten, mInfo.mRate) + mStartTime;
CheckedInt64 playedUsecs =
FramesToUsecs(mWritten, mConverter->OutputConfig().Rate()) + mStartTime;
if (!playedUsecs.isValid()) {
NS_WARNING("Int overflow calculating audio end time");
return -1;
@ -231,9 +244,11 @@ DecodedAudioDataSink::PopFrames(uint32_t aFrames)
// audio hardware, so we can play across the gap.
// Calculate the timestamp of the next chunk of audio in numbers of
// samples.
CheckedInt64 sampleTime = UsecsToFrames(AudioQueue().PeekFront()->mTime, mInfo.mRate);
CheckedInt64 sampleTime = UsecsToFrames(AudioQueue().PeekFront()->mTime,
mConverter->OutputConfig().Rate());
// Calculate the number of frames that have been pushed onto the audio hardware.
CheckedInt64 playedFrames = UsecsToFrames(mStartTime, mInfo.mRate) +
CheckedInt64 playedFrames = UsecsToFrames(mStartTime,
mConverter->OutputConfig().Rate()) +
static_cast<int64_t>(mWritten);
CheckedInt64 missingFrames = sampleTime - playedFrames;
@ -243,6 +258,9 @@ DecodedAudioDataSink::PopFrames(uint32_t aFrames)
return MakeUnique<Chunk>();
}
const uint32_t rate = mConverter->OutputConfig().Rate();
const uint32_t channels = mConverter->OutputConfig().Channels();
if (missingFrames.value() > AUDIO_FUZZ_FRAMES) {
// The next audio chunk begins some time after the end of the last chunk
// we pushed to the audio hardware. We must push silence into the audio
@ -251,10 +269,26 @@ DecodedAudioDataSink::PopFrames(uint32_t aFrames)
missingFrames = std::min<int64_t>(UINT32_MAX, missingFrames.value());
auto framesToPop = std::min<uint32_t>(missingFrames.value(), aFrames);
mWritten += framesToPop;
return MakeUnique<SilentChunk>(framesToPop, mInfo.mChannels, mInfo.mRate);
return MakeUnique<SilentChunk>(framesToPop, channels, rate);
}
RefPtr<AudioData> data =
dont_AddRef(AudioQueue().PopFront().take()->As<AudioData>());
if (mConverter->InputConfig() != mConverter->OutputConfig()) {
AlignedAudioBuffer convertedData =
mConverter->Process(AudioSampleBuffer(Move(data->mAudioData))).Forget();
mCurrentData =
new AudioData(data->mOffset,
data->mTime,
data->mDuration,
convertedData.Length() / channels,
Move(convertedData),
channels,
rate);
} else {
mCurrentData = Move(data);
}
mCurrentData = dont_AddRef(AudioQueue().PopFront().take()->As<AudioData>());
mCursor = MakeUnique<AudioBufferCursor>(mCurrentData->mAudioData.get(),
mCurrentData->mChannels,
mCurrentData->mFrames);

Просмотреть файл

@ -21,6 +21,8 @@
namespace mozilla {
class AudioConverter;
namespace media {
class DecodedAudioDataSink : public AudioSink,
@ -97,13 +99,15 @@ private:
*/
// The AudioData at which AudioStream::DataSource is reading.
RefPtr<AudioData> mCurrentData;
// Keep track of the read positoin of mCurrentData.
// Keep track of the read position of mCurrentData.
UniquePtr<AudioBufferCursor> mCursor;
// True if there is any error in processing audio data like overflow.
bool mErrored = false;
// Set on the callback thread of cubeb once the stream has drained.
Atomic<bool> mPlaybackComplete;
UniquePtr<AudioConverter> mConverter;
};
} // namespace media

Просмотреть файл

@ -227,7 +227,7 @@ VorbisDataDecoder::DoDecode(MediaRawData* aSample)
}
MOZ_ASSERT(mAudioConverter->CanWorkInPlace());
AudioSampleBuffer data(Move(buffer));
mAudioConverter->Process(data);
data = mAudioConverter->Process(Move(data));
aTotalFrames += frames;
mCallback->Output(new AudioData(aOffset,

Просмотреть файл

@ -287,7 +287,7 @@ AppleATDecoder::DecodeSample(MediaRawData* aSample)
}
if (mAudioConverter) {
MOZ_ASSERT(mAudioConverter->CanWorkInPlace());
mAudioConverter->Process(data);
data = mAudioConverter->Process(Move(data));
}
RefPtr<AudioData> audio = new AudioData(aSample->mOffset,

Просмотреть файл

@ -765,6 +765,7 @@ skip-if = toolkit == 'gonk' # bug 1128845
[test_preload_actions.html]
[test_preload_attribute.html]
[test_preload_suspend.html]
[test_preserve_playbackrate_after_ui_play.html]
[test_progress.html]
[test_reactivate.html]
skip-if = toolkit == 'gonk' # bug 1128845 on gonk

Просмотреть файл

@ -0,0 +1,60 @@
<!DOCTYPE HTML>
<html>
<head>
<title> Bug 1013933 - preserve playbackRate after clicking play button </title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<div id="content">
<video width="320" height="240" id="video" controls mozNoDynamicControls preload="auto"></video>
</div>
<script type="text/javascript">
/*
* Positions of the UI elements, relative to the upper-left corner of the
* <video> box.
*/
const videoHeight = 240;
const playButtonWidth = 28;
const playButtonHeight = 28;
const playButtonCenterX = 0 + Math.round(playButtonWidth / 2);
const playButtonCenterY = videoHeight - Math.round(playButtonHeight / 2);
var expectedPlaybackRate = 0.5
function runTest() {
var video = document.getElementById("video");
video.src = "audio.wav";
video.loop = true;
video.playbackRate = expectedPlaybackRate;
video.oncanplaythrough = function() {
video.oncanplaythrough = null;
is(video.paused, true, "video is not playing yet.");
is(video.playbackRate, expectedPlaybackRate,
"playbackRate is correct before clicking play button.");
// Click the play button
synthesizeMouse(video, playButtonCenterX, playButtonCenterY, { });
};
video.onplay = function() {
video.onplay = null;
is(video.paused, false, "video starts playing.");
is(video.playbackRate, expectedPlaybackRate,
"playbackRate is correct after clicking play button.");
video.pause();
SimpleTest.finish();
};
}
window.addEventListener("load", runTest, false);
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -628,8 +628,6 @@ WAVTrackDemuxer::Read(uint8_t* aBuffer, int64_t aOffset, int32_t aSize)
uint32_t
RIFFParser::Parse(ByteReader& aReader)
{
MOZ_ASSERT(&aReader);
while (aReader.CanRead8() && !mRiffHeader.ParseNext(aReader.ReadU8())) { }
if (mRiffHeader.IsValid()) {
@ -784,8 +782,6 @@ HeaderParser::ChunkHeader::Update(uint8_t c)
uint32_t
FormatParser::Parse(ByteReader& aReader)
{
MOZ_ASSERT(&aReader);
while (aReader.CanRead8() && !mFmtChunk.ParseNext(aReader.ReadU8())) { }
if (mFmtChunk.IsValid()) {

Просмотреть файл

@ -0,0 +1,29 @@
/* -*- 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/. */
#ifndef AlignmentUtils_h__
#define AlignmentUtils_h__
#define IS_ALIGNED16(ptr) ((((uintptr_t)ptr + 15) & ~0x0F) == (uintptr_t)ptr)
#ifdef DEBUG
#define ASSERT_ALIGNED16(ptr) \
MOZ_ASSERT(IS_ALIGNED16(ptr), \
#ptr " has to be aligned to a 16 byte boundary");
#else
#define ASSERT_ALIGNED16(ptr)
#endif
#ifdef DEBUG
#define ASSERT_MULTIPLE16(v) \
MOZ_ASSERT(v % 16 == 0, #v " has to be a a multiple of 16");
#else
#define ASSERT_MULTIPLE16(v)
#endif
#define ALIGNED16(ptr) (float*)(((uintptr_t)ptr + 15) & ~0x0F);
#endif

Просмотреть файл

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AudioBlock.h"
#include "AlignmentUtils.h"
namespace mozilla {
@ -17,9 +18,7 @@ namespace mozilla {
* buffer can reuse and modify its contents next iteration if other references
* are all downstream temporary references held by AudioBlock.
*
* This only guarantees 4-byte alignment of the data. For alignment we simply
* assume that the memory from malloc is at least 4-byte aligned and that
* AudioBlockBuffer's size is divisible by 4.
* We guarantee 16 byte alignment of the channel data.
*/
class AudioBlockBuffer final : public ThreadSharedObject {
public:
@ -28,7 +27,9 @@ public:
float* ChannelData(uint32_t aChannel)
{
return reinterpret_cast<float*>(this + 1) + aChannel * WEBAUDIO_BLOCK_SIZE;
float* base = reinterpret_cast<float*>(((uintptr_t)(this + 1) + 15) & ~0x0F);
ASSERT_ALIGNED16(base);
return base + aChannel * WEBAUDIO_BLOCK_SIZE;
}
static already_AddRefed<AudioBlockBuffer> Create(uint32_t aChannelCount)
@ -37,9 +38,11 @@ public:
size *= aChannelCount;
size *= sizeof(float);
size += sizeof(AudioBlockBuffer);
size += 15; //padding for alignment
if (!size.isValid()) {
MOZ_CRASH();
}
void* m = moz_xmalloc(size.value());
RefPtr<AudioBlockBuffer> p = new (m) AudioBlockBuffer();
NS_ASSERTION((reinterpret_cast<char*>(p.get() + 1) - reinterpret_cast<char*>(p.get())) % 4 == 0,
@ -150,8 +153,6 @@ AudioBlock::AllocateChannels(uint32_t aChannelCount)
}
}
// XXX for SIMD purposes we should do something here to make sure the
// channel buffers are 16-byte aligned.
RefPtr<AudioBlockBuffer> buffer = AudioBlockBuffer::Create(aChannelCount);
mChannelData.SetLength(aChannelCount);
for (uint32_t i = 0; i < aChannelCount; ++i) {

Просмотреть файл

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AudioDestinationNode.h"
#include "AlignmentUtils.h"
#include "AudioContext.h"
#include "mozilla/dom/AudioDestinationNodeBinding.h"
#include "mozilla/dom/ScriptSettings.h"
@ -87,7 +88,7 @@ public:
PodZero(outputData, duration);
} else {
const float* inputBuffer = static_cast<const float*>(aInput.mChannelData[i]);
if (duration == WEBAUDIO_BLOCK_SIZE) {
if (duration == WEBAUDIO_BLOCK_SIZE && IS_ALIGNED16(inputBuffer)) {
// Use the optimized version of the copy with scale operation
AudioBlockCopyChannelWithScale(inputBuffer, aInput.mVolume,
outputData);

Просмотреть файл

@ -9,6 +9,9 @@
#include "mozilla/arm.h"
#include "AudioNodeEngineNEON.h"
#endif
#ifdef USE_SSE2
#include "AudioNodeEngineSSE2.h"
#endif
namespace mozilla {
@ -71,6 +74,14 @@ void AudioBufferAddWithScale(const float* aInput,
return;
}
#endif
#ifdef USE_SSE2
if (mozilla::supports_sse2()) {
AudioBufferAddWithScale_SSE(aInput, aScale, aOutput, aSize);
return;
}
#endif
if (aScale == 1.0f) {
for (uint32_t i = 0; i < aSize; ++i) {
aOutput[i] += aInput[i];
@ -104,6 +115,14 @@ AudioBlockCopyChannelWithScale(const float* aInput,
return;
}
#endif
#ifdef USE_SSE2
if (mozilla::supports_sse2()) {
AudioBlockCopyChannelWithScale_SSE(aInput, aScale, aOutput);
return;
}
#endif
for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
aOutput[i] = aInput[i]*aScale;
}
@ -116,6 +135,14 @@ BufferComplexMultiply(const float* aInput,
float* aOutput,
uint32_t aSize)
{
#ifdef USE_SSE2
if (mozilla::supports_sse()) {
BufferComplexMultiply_SSE(aInput, aScale, aOutput, aSize);
return;
}
#endif
for (uint32_t i = 0; i < aSize * 2; i += 2) {
float real1 = aInput[i];
float imag1 = aInput[i + 1];
@ -152,6 +179,14 @@ AudioBlockCopyChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
return;
}
#endif
#ifdef USE_SSE2
if (mozilla::supports_sse2()) {
AudioBlockCopyChannelWithScale_SSE(aInput, aScale, aOutput);
return;
}
#endif
for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
aOutput[i] = aInput[i]*aScale[i];
}
@ -178,6 +213,14 @@ AudioBufferInPlaceScale(float* aBlock,
return;
}
#endif
#ifdef USE_SSE2
if (mozilla::supports_sse2()) {
AudioBufferInPlaceScale_SSE(aBlock, aScale, aSize);
return;
}
#endif
for (uint32_t i = 0; i < aSize; ++i) {
*aBlock++ *= aScale;
}
@ -220,6 +263,15 @@ AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE],
}
#endif
#ifdef USE_SSE2
if (mozilla::supports_sse2()) {
AudioBlockPanStereoToStereo_SSE(aInputL, aInputR,
aGainL, aGainR, aIsOnTheLeft,
aOutputL, aOutputR);
return;
}
#endif
uint32_t i;
if (aIsOnTheLeft) {
@ -269,6 +321,27 @@ float
AudioBufferSumOfSquares(const float* aInput, uint32_t aLength)
{
float sum = 0.0f;
#ifdef USE_SSE2
if (mozilla::supports_sse()) {
const float* alignedInput = ALIGNED16(aInput);
float vLength = (aLength >> 4) << 4;
// use scalar operations for any unaligned data at the beginning
while (aInput != alignedInput) {
sum += *aInput * *aInput;
++aInput;
}
sum += AudioBufferSumOfSquares_SSE(alignedInput, vLength);
// adjust aInput and aLength to use scalar operations for any
// remaining values
aInput = alignedInput + 1;
aLength -= vLength;
}
#endif
while (aLength--) {
sum += *aInput * *aInput;
++aInput;

Просмотреть файл

@ -0,0 +1,315 @@
/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* this source code form is subject to the terms of the mozilla public
* license, v. 2.0. if a copy of the mpl was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AlignmentUtils.h"
#include "AudioNodeEngineSSE2.h"
#include <emmintrin.h>
namespace mozilla {
void
AudioBufferAddWithScale_SSE(const float* aInput,
float aScale,
float* aOutput,
uint32_t aSize)
{
__m128 vin0, vin1, vin2, vin3,
vscaled0, vscaled1, vscaled2, vscaled3,
vout0, vout1, vout2, vout3,
vgain;
ASSERT_ALIGNED16(aInput);
ASSERT_ALIGNED16(aOutput);
ASSERT_MULTIPLE16(aSize);
vgain = _mm_load1_ps(&aScale);
for (unsigned i = 0; i < aSize; i+=16) {
vin0 = _mm_load_ps(&aInput[i]);
vin1 = _mm_load_ps(&aInput[i + 4]);
vin2 = _mm_load_ps(&aInput[i + 8]);
vin3 = _mm_load_ps(&aInput[i + 12]);
vscaled0 = _mm_mul_ps(vin0, vgain);
vscaled1 = _mm_mul_ps(vin1, vgain);
vscaled2 = _mm_mul_ps(vin2, vgain);
vscaled3 = _mm_mul_ps(vin3, vgain);
vin0 = _mm_load_ps(&aOutput[i]);
vin1 = _mm_load_ps(&aOutput[i + 4]);
vin2 = _mm_load_ps(&aOutput[i + 8]);
vin3 = _mm_load_ps(&aOutput[i + 12]);
vout0 = _mm_add_ps(vin0, vscaled0);
vout1 = _mm_add_ps(vin1, vscaled1);
vout2 = _mm_add_ps(vin2, vscaled2);
vout3 = _mm_add_ps(vin3, vscaled3);
_mm_store_ps(&aOutput[i], vout0);
_mm_store_ps(&aOutput[i + 4], vout1);
_mm_store_ps(&aOutput[i + 8], vout2);
_mm_store_ps(&aOutput[i + 12], vout3);
}
}
void
AudioBlockCopyChannelWithScale_SSE(const float* aInput,
float aScale,
float* aOutput)
{
__m128 vin0, vin1, vin2, vin3,
vout0, vout1, vout2, vout3;
ASSERT_ALIGNED16(aInput);
ASSERT_ALIGNED16(aOutput);
__m128 vgain = _mm_load1_ps(&aScale);
for (unsigned i = 0 ; i < WEBAUDIO_BLOCK_SIZE; i+=16) {
vin0 = _mm_load_ps(&aInput[i]);
vin1 = _mm_load_ps(&aInput[i + 4]);
vin2 = _mm_load_ps(&aInput[i + 8]);
vin3 = _mm_load_ps(&aInput[i + 12]);
vout0 = _mm_mul_ps(vin0, vgain);
vout1 = _mm_mul_ps(vin1, vgain);
vout2 = _mm_mul_ps(vin2, vgain);
vout3 = _mm_mul_ps(vin3, vgain);
_mm_store_ps(&aOutput[i], vout0);
_mm_store_ps(&aOutput[i + 4], vout1);
_mm_store_ps(&aOutput[i + 8], vout2);
_mm_store_ps(&aOutput[i + 12], vout3);
}
}
void
AudioBlockCopyChannelWithScale_SSE(const float aInput[WEBAUDIO_BLOCK_SIZE],
const float aScale[WEBAUDIO_BLOCK_SIZE],
float aOutput[WEBAUDIO_BLOCK_SIZE])
{
__m128 vin0, vin1, vin2, vin3,
vscaled0, vscaled1, vscaled2, vscaled3,
vout0, vout1, vout2, vout3;
ASSERT_ALIGNED16(aInput);
ASSERT_ALIGNED16(aScale);
ASSERT_ALIGNED16(aOutput);
for (unsigned i = 0 ; i < WEBAUDIO_BLOCK_SIZE; i+=16) {
vscaled0 = _mm_load_ps(&aScale[i]);
vscaled1 = _mm_load_ps(&aScale[i+4]);
vscaled2 = _mm_load_ps(&aScale[i+8]);
vscaled3 = _mm_load_ps(&aScale[i+12]);
vin0 = _mm_load_ps(&aInput[i]);
vin1 = _mm_load_ps(&aInput[i + 4]);
vin2 = _mm_load_ps(&aInput[i + 8]);
vin3 = _mm_load_ps(&aInput[i + 12]);
vout0 = _mm_mul_ps(vin0, vscaled0);
vout1 = _mm_mul_ps(vin1, vscaled1);
vout2 = _mm_mul_ps(vin2, vscaled2);
vout3 = _mm_mul_ps(vin3, vscaled3);
_mm_store_ps(&aOutput[i], vout0);
_mm_store_ps(&aOutput[i + 4], vout1);
_mm_store_ps(&aOutput[i + 8], vout2);
_mm_store_ps(&aOutput[i + 12], vout3);
}
}
void
AudioBufferInPlaceScale_SSE(float* aBlock,
float aScale,
uint32_t aSize)
{
__m128 vout0, vout1, vout2, vout3,
vin0, vin1, vin2, vin3;
ASSERT_ALIGNED16(aBlock);
ASSERT_MULTIPLE16(aSize);
__m128 vgain = _mm_load1_ps(&aScale);
for (unsigned i = 0; i < aSize; i+=16) {
vin0 = _mm_load_ps(&aBlock[i]);
vin1 = _mm_load_ps(&aBlock[i + 4]);
vin2 = _mm_load_ps(&aBlock[i + 8]);
vin3 = _mm_load_ps(&aBlock[i + 12]);
vout0 = _mm_mul_ps(vin0, vgain);
vout1 = _mm_mul_ps(vin1, vgain);
vout2 = _mm_mul_ps(vin2, vgain);
vout3 = _mm_mul_ps(vin3, vgain);
_mm_store_ps(&aBlock[i], vout0);
_mm_store_ps(&aBlock[i + 4], vout1);
_mm_store_ps(&aBlock[i + 8], vout2);
_mm_store_ps(&aBlock[i + 12], vout3);
}
}
void
AudioBlockPanStereoToStereo_SSE(const float aInputL[WEBAUDIO_BLOCK_SIZE],
const float aInputR[WEBAUDIO_BLOCK_SIZE],
float aGainL, float aGainR, bool aIsOnTheLeft,
float aOutputL[WEBAUDIO_BLOCK_SIZE],
float aOutputR[WEBAUDIO_BLOCK_SIZE])
{
__m128 vinl0, vinr0, vinl1, vinr1,
vout0, vout1,
vscaled0, vscaled1,
vgainl, vgainr;
ASSERT_ALIGNED16(aInputL);
ASSERT_ALIGNED16(aInputR);
ASSERT_ALIGNED16(aOutputL);
ASSERT_ALIGNED16(aOutputR);
vgainl = _mm_load1_ps(&aGainL);
vgainr = _mm_load1_ps(&aGainR);
if (aIsOnTheLeft) {
for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE; i+=8) {
vinl0 = _mm_load_ps(&aInputL[i]);
vinr0 = _mm_load_ps(&aInputR[i]);
vinl1 = _mm_load_ps(&aInputL[i+4]);
vinr1 = _mm_load_ps(&aInputR[i+4]);
/* left channel : aOutputL = aInputL + aInputR * gainL */
vscaled0 = _mm_mul_ps(vinr0, vgainl);
vscaled1 = _mm_mul_ps(vinr1, vgainl);
vout0 = _mm_add_ps(vscaled0, vinl0);
vout1 = _mm_add_ps(vscaled1, vinl1);
_mm_store_ps(&aOutputL[i], vout0);
_mm_store_ps(&aOutputL[i+4], vout1);
/* right channel : aOutputR = aInputR * gainR */
vscaled0 = _mm_mul_ps(vinr0, vgainr);
vscaled1 = _mm_mul_ps(vinr1, vgainr);
_mm_store_ps(&aOutputR[i], vscaled0);
_mm_store_ps(&aOutputR[i+4], vscaled1);
}
} else {
for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE; i+=8) {
vinl0 = _mm_load_ps(&aInputL[i]);
vinr0 = _mm_load_ps(&aInputR[i]);
vinl1 = _mm_load_ps(&aInputL[i+4]);
vinr1 = _mm_load_ps(&aInputR[i+4]);
/* left channel : aInputL * gainL */
vscaled0 = _mm_mul_ps(vinl0, vgainl);
vscaled1 = _mm_mul_ps(vinl1, vgainl);
_mm_store_ps(&aOutputL[i], vscaled0);
_mm_store_ps(&aOutputL[i+4], vscaled1);
/* right channel: aOutputR = aInputR + aInputL * gainR */
vscaled0 = _mm_mul_ps(vinl0, vgainr);
vscaled1 = _mm_mul_ps(vinl1, vgainr);
vout0 = _mm_add_ps(vscaled0, vinr0);
vout1 = _mm_add_ps(vscaled1, vinr1);
_mm_store_ps(&aOutputR[i], vout0);
_mm_store_ps(&aOutputR[i+4], vout1);
}
}
}
void BufferComplexMultiply_SSE(const float* aInput,
const float* aScale,
float* aOutput,
uint32_t aSize)
{
unsigned i;
__m128 in0, in1, in2, in3,
outreal0, outreal1, outreal2, outreal3,
outimag0, outimag1, outimag2, outimag3;
ASSERT_ALIGNED16(aInput);
ASSERT_ALIGNED16(aScale);
ASSERT_ALIGNED16(aOutput);
ASSERT_MULTIPLE16(aSize);
for (i = 0; i < aSize * 2; i += 16) {
in0 = _mm_load_ps(&aInput[i]);
in1 = _mm_load_ps(&aInput[i + 4]);
in2 = _mm_load_ps(&aInput[i + 8]);
in3 = _mm_load_ps(&aInput[i + 12]);
outreal0 = _mm_shuffle_ps(in0, in1, _MM_SHUFFLE(2, 0, 2, 0));
outimag0 = _mm_shuffle_ps(in0, in1, _MM_SHUFFLE(3, 1, 3, 1));
outreal2 = _mm_shuffle_ps(in2, in3, _MM_SHUFFLE(2, 0, 2, 0));
outimag2 = _mm_shuffle_ps(in2, in3, _MM_SHUFFLE(3, 1, 3, 1));
in0 = _mm_load_ps(&aScale[i]);
in1 = _mm_load_ps(&aScale[i + 4]);
in2 = _mm_load_ps(&aScale[i + 8]);
in3 = _mm_load_ps(&aScale[i + 12]);
outreal1 = _mm_shuffle_ps(in0, in1, _MM_SHUFFLE(2, 0, 2, 0));
outimag1 = _mm_shuffle_ps(in0, in1, _MM_SHUFFLE(3, 1, 3, 1));
outreal3 = _mm_shuffle_ps(in2, in3, _MM_SHUFFLE(2, 0, 2, 0));
outimag3 = _mm_shuffle_ps(in2, in3, _MM_SHUFFLE(3, 1, 3, 1));
in0 = _mm_sub_ps(_mm_mul_ps(outreal0, outreal1),
_mm_mul_ps(outimag0, outimag1));
in1 = _mm_add_ps(_mm_mul_ps(outreal0, outimag1),
_mm_mul_ps(outimag0, outreal1));
in2 = _mm_sub_ps(_mm_mul_ps(outreal2, outreal3),
_mm_mul_ps(outimag2, outimag3));
in3 = _mm_add_ps(_mm_mul_ps(outreal2, outimag3),
_mm_mul_ps(outimag2, outreal3));
outreal0 = _mm_unpacklo_ps(in0, in1);
outreal1 = _mm_unpackhi_ps(in0, in1);
outreal2 = _mm_unpacklo_ps(in2, in3);
outreal3 = _mm_unpackhi_ps(in2, in3);
_mm_store_ps(&aOutput[i], outreal0);
_mm_store_ps(&aOutput[i + 4], outreal1);
_mm_store_ps(&aOutput[i + 8], outreal2);
_mm_store_ps(&aOutput[i + 12], outreal3);
}
}
float
AudioBufferSumOfSquares_SSE(const float* aInput, uint32_t aLength)
{
unsigned i;
__m128 in0, in1, in2, in3,
acc0, acc1, acc2, acc3;
float out[4];
ASSERT_ALIGNED16(aInput);
ASSERT_MULTIPLE16(aLength);
acc0 = _mm_setzero_ps();
acc1 = _mm_setzero_ps();
acc2 = _mm_setzero_ps();
acc3 = _mm_setzero_ps();
for (i = 0; i < aLength; i+=16) {
in0 = _mm_load_ps(&aInput[i]);
in1 = _mm_load_ps(&aInput[i + 4]);
in2 = _mm_load_ps(&aInput[i + 8]);
in3 = _mm_load_ps(&aInput[i + 12]);
in0 = _mm_mul_ps(in0, in0);
in1 = _mm_mul_ps(in1, in1);
in2 = _mm_mul_ps(in2, in2);
in3 = _mm_mul_ps(in3, in3);
acc0 = _mm_add_ps(acc0, in0);
acc1 = _mm_add_ps(acc1, in1);
acc2 = _mm_add_ps(acc2, in2);
acc3 = _mm_add_ps(acc3, in3);
}
acc0 = _mm_add_ps(acc0, acc1);
acc0 = _mm_add_ps(acc0, acc2);
acc0 = _mm_add_ps(acc0, acc3);
_mm_store_ps(out, acc0);
return out[0] + out[1] + out[2] + out[3];
}
}

Просмотреть файл

@ -0,0 +1,45 @@
/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* this source code form is subject to the terms of the mozilla public
* license, v. 2.0. if a copy of the mpl was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AudioNodeEngine.h"
namespace mozilla {
void
AudioBufferAddWithScale_SSE(const float* aInput,
float aScale,
float* aOutput,
uint32_t aSize);
void
AudioBlockCopyChannelWithScale_SSE(const float* aInput,
float aScale,
float* aOutput);
void
AudioBlockCopyChannelWithScale_SSE(const float aInput[WEBAUDIO_BLOCK_SIZE],
const float aScale[WEBAUDIO_BLOCK_SIZE],
float aOutput[WEBAUDIO_BLOCK_SIZE]);
void
AudioBufferInPlaceScale_SSE(float* aBlock,
float aScale,
uint32_t aSize);
void
AudioBlockPanStereoToStereo_SSE(const float aInputL[WEBAUDIO_BLOCK_SIZE],
const float aInputR[WEBAUDIO_BLOCK_SIZE],
float aGainL, float aGainR, bool aIsOnTheLeft,
float aOutputL[WEBAUDIO_BLOCK_SIZE],
float aOutputR[WEBAUDIO_BLOCK_SIZE]);
float
AudioBufferSumOfSquares_SSE(const float* aInput, uint32_t aLength);
void
BufferComplexMultiply_SSE(const float* aInput,
const float* aScale,
float* aOutput,
uint32_t aSize);
}

Просмотреть файл

@ -3,6 +3,8 @@
* 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 "AlignedTArray.h"
#include "AlignmentUtils.h"
#include "AudioNodeEngine.h"
#include "AudioNodeExternalInputStream.h"
#include "AudioChannelFormat.h"
@ -90,9 +92,20 @@ static void ConvertSegmentToAudioBlock(AudioSegment* aSegment,
NS_ASSERTION(!ci.IsEnded(), "Should be at least one chunk!");
if (ci->GetDuration() == WEBAUDIO_BLOCK_SIZE &&
(ci->IsNull() || ci->mBufferFormat == AUDIO_FORMAT_FLOAT32)) {
bool aligned = true;
for (size_t i = 0; i < ci->mChannelData.Length(); ++i) {
if (!IS_ALIGNED16(ci->mChannelData[i])) {
aligned = false;
break;
}
}
// Return this chunk directly to avoid copying data.
*aBlock = *ci;
return;
if (aligned) {
*aBlock = *ci;
return;
}
}
}
@ -192,7 +205,10 @@ AudioNodeExternalInputStream::ProcessInput(GraphTime aFrom, GraphTime aTo,
uint32_t accumulateIndex = 0;
if (inputChannels) {
AutoTArray<float,GUESS_AUDIO_CHANNELS*WEBAUDIO_BLOCK_SIZE> downmixBuffer;
// TODO: See Bug 1261168. Ideally we would use an aligned version of
// AutoTArray (of size GUESS_AUDIO_CHANNELS*WEBAUDIO_BLOCK_SIZE) here.
AlignedTArray<float,16> downmixBuffer;
downmixBuffer.SetLength(GUESS_AUDIO_CHANNELS*WEBAUDIO_BLOCK_SIZE);
for (uint32_t i = 0; i < audioSegments.Length(); ++i) {
AudioBlock tmpChunk;
ConvertSegmentToAudioBlock(&audioSegments[i], &tmpChunk, inputChannels);

Просмотреть файл

@ -453,8 +453,10 @@ AudioNodeStream::ObtainInputBlock(AudioBlock& aTmpChunk,
}
aTmpChunk.AllocateChannels(outputChannelCount);
// The static storage here should be 1KB, so it's fine
AutoTArray<float, GUESS_AUDIO_CHANNELS*WEBAUDIO_BLOCK_SIZE> downmixBuffer;
// TODO: See Bug 1261168. Ideally we would use an aligned version of
// AutoTArray (of size GUESS_AUDIO_CHANNELS*WEBAUDIO_BLOCK_SIZE) here.
AlignedTArray<float, 16> downmixBuffer;
downmixBuffer.SetLength(GUESS_AUDIO_CHANNELS*WEBAUDIO_BLOCK_SIZE);
for (uint32_t i = 0; i < inputChunkCount; ++i) {
AccumulateInputChunk(i, *inputChunks[i], &aTmpChunk, &downmixBuffer);
@ -465,7 +467,7 @@ void
AudioNodeStream::AccumulateInputChunk(uint32_t aInputIndex,
const AudioBlock& aChunk,
AudioBlock* aBlock,
nsTArray<float>* aDownmixBuffer)
AlignedTArray<float, 16>* aDownmixBuffer)
{
AutoTArray<const float*,GUESS_AUDIO_CHANNELS> channels;
UpMixDownMixChunk(&aChunk, aBlock->ChannelCount(), channels, *aDownmixBuffer);
@ -491,7 +493,7 @@ void
AudioNodeStream::UpMixDownMixChunk(const AudioBlock* aChunk,
uint32_t aOutputChannelCount,
nsTArray<const float*>& aOutputChannels,
nsTArray<float>& aDownmixBuffer)
AlignedTArray<float, 16>& aDownmixBuffer)
{
for (uint32_t i = 0; i < aChunk->ChannelCount(); i++) {
aOutputChannels.AppendElement(static_cast<const float*>(aChunk->mChannelData[i]));

Просмотреть файл

@ -8,6 +8,7 @@
#include "MediaStreamGraph.h"
#include "mozilla/dom/AudioNodeBinding.h"
#include "AlignedTArray.h"
#include "AudioBlock.h"
namespace mozilla {
@ -190,10 +191,10 @@ protected:
void FinishOutput();
void AccumulateInputChunk(uint32_t aInputIndex, const AudioBlock& aChunk,
AudioBlock* aBlock,
nsTArray<float>* aDownmixBuffer);
AlignedTArray<float, 16>* aDownmixBuffer);
void UpMixDownMixChunk(const AudioBlock* aChunk, uint32_t aOutputChannelCount,
nsTArray<const float*>& aOutputChannels,
nsTArray<float>& aDownmixBuffer);
AlignedTArray<float, 16>& aDownmixBuffer);
uint32_t ComputedNumberOfChannels(uint32_t aInputChannelCount);
void ObtainInputBlock(AudioBlock& aTmpChunk, uint32_t aPortIndex);

Просмотреть файл

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BiquadFilterNode.h"
#include "AlignmentUtils.h"
#include "AudioNodeEngine.h"
#include "AudioNodeStream.h"
#include "AudioDestinationNode.h"
@ -137,7 +138,9 @@ public:
AudioBlock* aOutput,
bool* aFinished) override
{
float inputBuffer[WEBAUDIO_BLOCK_SIZE];
float inputBuffer[WEBAUDIO_BLOCK_SIZE + 4];
float* alignedInputBuffer = ALIGNED16(inputBuffer);
ASSERT_ALIGNED16(alignedInputBuffer);
if (aInput.IsNull()) {
bool hasTail = false;
@ -191,12 +194,12 @@ public:
for (uint32_t i = 0; i < numberOfChannels; ++i) {
const float* input;
if (aInput.IsNull()) {
input = inputBuffer;
input = alignedInputBuffer;
} else {
input = static_cast<const float*>(aInput.mChannelData[i]);
if (aInput.mVolume != 1.0) {
AudioBlockCopyChannelWithScale(input, aInput.mVolume, inputBuffer);
input = inputBuffer;
AudioBlockCopyChannelWithScale(input, aInput.mVolume, alignedInputBuffer);
input = alignedInputBuffer;
}
}
SetParamsOnBiquad(mBiquads[i], aStream->SampleRate(), mType, freq, q, gain, detune);

Просмотреть файл

@ -6,6 +6,7 @@
#include "ConvolverNode.h"
#include "mozilla/dom/ConvolverNodeBinding.h"
#include "AlignmentUtils.h"
#include "AudioNodeEngine.h"
#include "AudioNodeStream.h"
#include "blink/Reverb.h"
@ -261,11 +262,13 @@ ConvolverNode::SetBuffer(JSContext* aCx, AudioBuffer* aBuffer, ErrorResult& aRv)
length = WEBAUDIO_BLOCK_SIZE;
RefPtr<ThreadSharedFloatArrayBufferList> paddedBuffer =
new ThreadSharedFloatArrayBufferList(data->GetChannels());
float* channelData = (float*) malloc(sizeof(float) * length * data->GetChannels());
void* channelData = malloc(sizeof(float) * length * data->GetChannels() + 15);
float* alignedChannelData = ALIGNED16(channelData);
ASSERT_ALIGNED16(alignedChannelData);
for (uint32_t i = 0; i < data->GetChannels(); ++i) {
PodCopy(channelData + length * i, data->GetData(i), mBuffer->Length());
PodZero(channelData + length * i + mBuffer->Length(), WEBAUDIO_BLOCK_SIZE - mBuffer->Length());
paddedBuffer->SetData(i, (i == 0) ? channelData : nullptr, free, channelData);
PodCopy(alignedChannelData + length * i, data->GetData(i), mBuffer->Length());
PodZero(alignedChannelData + length * i + mBuffer->Length(), WEBAUDIO_BLOCK_SIZE - mBuffer->Length());
paddedBuffer->SetData(i, (i == 0) ? channelData : nullptr, free, alignedChannelData);
}
data = paddedBuffer;
}

Просмотреть файл

@ -6,6 +6,7 @@
#include "GainNode.h"
#include "mozilla/dom/GainNodeBinding.h"
#include "AlignmentUtils.h"
#include "AudioNodeEngine.h"
#include "AudioNodeStream.h"
#include "AudioDestinationNode.h"
@ -79,18 +80,20 @@ public:
// Compute the gain values for the duration of the input AudioChunk
StreamTime tick = mDestination->GraphTimeToStreamTime(aFrom);
float computedGain[WEBAUDIO_BLOCK_SIZE];
mGain.GetValuesAtTime(tick, computedGain, WEBAUDIO_BLOCK_SIZE);
float computedGain[WEBAUDIO_BLOCK_SIZE + 4];
float* alignedComputedGain = ALIGNED16(computedGain);
ASSERT_ALIGNED16(alignedComputedGain);
mGain.GetValuesAtTime(tick, alignedComputedGain, WEBAUDIO_BLOCK_SIZE);
for (size_t counter = 0; counter < WEBAUDIO_BLOCK_SIZE; ++counter) {
computedGain[counter] *= aInput.mVolume;
alignedComputedGain[counter] *= aInput.mVolume;
}
// Apply the gain to the output buffer
for (size_t channel = 0; channel < aOutput->ChannelCount(); ++channel) {
const float* inputBuffer = static_cast<const float*> (aInput.mChannelData[channel]);
float* buffer = aOutput->ChannelFloatsForWrite(channel);
AudioBlockCopyChannelWithScale(inputBuffer, computedGain, buffer);
AudioBlockCopyChannelWithScale(inputBuffer, alignedComputedGain, buffer);
}
}
}

Просмотреть файл

@ -9,6 +9,7 @@
#include "AudioNodeEngine.h"
#include "AudioNodeStream.h"
#include "AudioDestinationNode.h"
#include "AlignmentUtils.h"
#include "WebAudioUtils.h"
#include "PanningUtils.h"
#include "AudioParamTimeline.h"
@ -137,24 +138,26 @@ public:
panning <= 0);
}
} else {
float computedGain[2][WEBAUDIO_BLOCK_SIZE];
float computedGain[2*WEBAUDIO_BLOCK_SIZE + 4];
bool onLeft[WEBAUDIO_BLOCK_SIZE];
float values[WEBAUDIO_BLOCK_SIZE];
StreamTime tick = mDestination->GraphTimeToStreamTime(aFrom);
mPan.GetValuesAtTime(tick, values, WEBAUDIO_BLOCK_SIZE);
float* alignedComputedGain = ALIGNED16(computedGain);
ASSERT_ALIGNED16(alignedComputedGain);
for (size_t counter = 0; counter < WEBAUDIO_BLOCK_SIZE; ++counter) {
float left, right;
GetGainValuesForPanning(values[counter], monoToStereo, left, right);
computedGain[0][counter] = left * aInput.mVolume;
computedGain[1][counter] = right * aInput.mVolume;
alignedComputedGain[counter] = left * aInput.mVolume;
alignedComputedGain[WEBAUDIO_BLOCK_SIZE + counter] = right * aInput.mVolume;
onLeft[counter] = values[counter] <= 0;
}
// Apply the gain to the output buffer
ApplyStereoPanning(aInput, aOutput, computedGain[0], computedGain[1], onLeft);
ApplyStereoPanning(aInput, aOutput, alignedComputedGain, &alignedComputedGain[WEBAUDIO_BLOCK_SIZE], onLeft);
}
}

Просмотреть файл

@ -6,6 +6,7 @@
#include "WaveShaperNode.h"
#include "mozilla/dom/WaveShaperNodeBinding.h"
#include "AlignmentUtils.h"
#include "AudioNode.h"
#include "AudioNodeEngine.h"
#include "AudioNodeStream.h"
@ -231,13 +232,15 @@ public:
aOutput->AllocateChannels(channelCount);
for (uint32_t i = 0; i < channelCount; ++i) {
const float* inputSamples;
float scaledInput[WEBAUDIO_BLOCK_SIZE];
float scaledInput[WEBAUDIO_BLOCK_SIZE + 4];
float* alignedScaledInput = ALIGNED16(scaledInput);
ASSERT_ALIGNED16(alignedScaledInput);
if (aInput.mVolume != 1.0f) {
AudioBlockCopyChannelWithScale(
static_cast<const float*>(aInput.mChannelData[i]),
aInput.mVolume,
scaledInput);
inputSamples = scaledInput;
alignedScaledInput);
inputSamples = alignedScaledInput;
} else {
inputSamples = static_cast<const float*>(aInput.mChannelData[i]);
}

Просмотреть файл

@ -96,12 +96,30 @@ int ReverbAccumulationBuffer::accumulate(const float* source, size_t numberOfFra
if (!isSafe)
return 0;
AudioBufferAddWithScale(source, 1.0f, destination + writeIndex, numberOfFrames1);
#ifdef USE_SSE2
// It is unlikely either the source is aligned or the number of values
// is a multiple of 16, so we just add them here rather than calling
// AudioBufferAddWithScale.
//
// TODO: Ideally we would use scalar calls when necessary and switch
// to vector calls when we have aligned sources and destinations.
// See Bug 1263910.
for (uint32_t i = 0; i < numberOfFrames1; ++i) {
destination[writeIndex + i] += source[i];
}
// Handle wrap-around if necessary
// Handle wrap-around if necessary.
if (numberOfFrames2 > 0) {
for (uint32_t i = 0; i < numberOfFrames2; ++i) {
destination[i] += source[numberOfFrames1 + i];
}
}
#else
AudioBufferAddWithScale(source, 1.0f, destination + writeIndex, numberOfFrames1);
if (numberOfFrames2 > 0) {
AudioBufferAddWithScale(source + numberOfFrames1, 1.0f, destination, numberOfFrames2);
}
#endif
return writeIndex;
}

Просмотреть файл

@ -29,13 +29,11 @@
#ifndef ReverbAccumulationBuffer_h
#define ReverbAccumulationBuffer_h
#include "nsTArray.h"
#include "AlignedTArray.h"
#include "mozilla/MemoryReporting.h"
namespace WebCore {
typedef nsTArray<float> AudioFloatArray;
// ReverbAccumulationBuffer is a circular delay buffer with one client reading from it and multiple clients
// writing/accumulating to it at different delay offsets from the read position. The read operation will zero the memory
// just read from the buffer, so it will be ready for accumulation the next time around.
@ -65,7 +63,7 @@ public:
}
private:
AudioFloatArray m_buffer;
AlignedTArray<float, 16> m_buffer;
size_t m_readIndex;
size_t m_readTimeFrame; // for debugging (frame on continuous timeline)
};

Просмотреть файл

@ -23,6 +23,10 @@ UNIFIED_SOURCES += [
'ZeroPole.cpp',
]
# Are we targeting x86 or x64? If so, build SSE2 files.
if CONFIG['INTEL_ARCHITECTURE']:
DEFINES['USE_SSE2'] = True
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'

Просмотреть файл

@ -114,6 +114,13 @@ if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']:
'/media/openmax_dl/dl/api/'
]
# Are we targeting x86 or x64? If so, build SSE2 files.
if CONFIG['INTEL_ARCHITECTURE']:
SOURCES += ['AudioNodeEngineSSE2.cpp']
DEFINES['USE_SSE2'] = True
SOURCES['AudioNodeEngineSSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'

Просмотреть файл

@ -2539,7 +2539,7 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const WidgetGUIEvent& anEvent)
#ifdef MOZ_X11
// this code supports windowless plugins
nsIWidget* widget = anEvent.widget;
nsIWidget* widget = anEvent.mWidget;
XEvent pluginEvent = XEvent();
pluginEvent.type = 0;

Просмотреть файл

@ -1,8 +0,0 @@
#
# 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/.
RELATIVE_PATH=.
COCOA_NAME=Test
include @srcdir@/testplugin.mk

Просмотреть файл

@ -1,9 +0,0 @@
#
# 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/.
RELATIVE_PATH=..
COCOA_NAME=npswftest
include @srcdir@/../testplugin.mk

Просмотреть файл

@ -7,4 +7,5 @@
SharedLibrary('npswftest')
relative_path = 'flashplugin'
cocoa_name = 'npswftest'
include('../testplugin.mozbuild')

Просмотреть файл

@ -1,8 +0,0 @@
#
# 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/.
RELATIVE_PATH=..
COCOA_NAME=JavaTest
include @srcdir@/../testplugin.mk

Просмотреть файл

@ -7,4 +7,5 @@
SharedLibrary('nptestjava')
relative_path = 'javaplugin'
cocoa_name = 'JavaTest'
include('../testplugin.mozbuild')

Просмотреть файл

@ -9,4 +9,5 @@ DIRS += ['secondplugin', 'javaplugin', 'thirdplugin', 'flashplugin', 'silverligh
SharedLibrary('nptest')
relative_path = '.'
cocoa_name = 'Test'
include('testplugin.mozbuild')

Просмотреть файл

@ -1,8 +0,0 @@
#
# 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/.
RELATIVE_PATH=..
COCOA_NAME=SecondTest
include @srcdir@/../testplugin.mk

Просмотреть файл

@ -7,4 +7,5 @@
SharedLibrary('npsecondtest')
relative_path = 'secondplugin'
cocoa_name = 'SecondTest'
include('../testplugin.mozbuild')

Просмотреть файл

@ -1,9 +0,0 @@
#
# 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/.
RELATIVE_PATH=..
COCOA_NAME=npctrltest
include @srcdir@/../testplugin.mk

Просмотреть файл

@ -7,4 +7,5 @@
SharedLibrary('npctrltest')
relative_path = 'silverlightplugin'
cocoa_name = 'npctrltest'
include('../testplugin.mozbuild')

Просмотреть файл

@ -1,19 +0,0 @@
#
# 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/.
TEST_PLUGIN_FILES = $(SHARED_LIBRARY)
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
MAC_PLIST_FILES += $(srcdir)/Info.plist
MAC_PLIST_DEST = $(DIST)/plugins/$(COCOA_NAME).plugin/Contents
TEST_PLUGIN_DEST = $(DIST)/plugins/$(COCOA_NAME).plugin/Contents/MacOS
INSTALL_TARGETS += \
TEST_PLUGIN \
MAC_PLIST \
$(NULL)
else
TEST_PLUGIN_DEST = $(DIST)/plugins
INSTALL_TARGETS += TEST_PLUGIN
endif

Просмотреть файл

@ -4,8 +4,6 @@
# 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/.
DIST_INSTALL = False
UNIFIED_SOURCES += [
'nptest.cpp',
'nptest_utils.cpp',
@ -74,3 +72,9 @@ if CONFIG['_MSC_VER']:
# This is intended as a temporary hack to support building with VS2015.
# conversion from 'X' to 'Y' requires a narrowing conversion
CXXFLAGS += ['-wd4838']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
FINAL_TARGET = 'dist/plugins/%s.plugin/Contents/MacOS' % cocoa_name
OBJDIR_FILES.dist.plugins['%s.plugin' % cocoa_name].Contents += ['Info.plist']
else:
FINAL_TARGET = 'dist/plugins'

Просмотреть файл

@ -1,8 +0,0 @@
#
# 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/.
RELATIVE_PATH=..
COCOA_NAME=ThirdTest
include @srcdir@/../testplugin.mk

Просмотреть файл

@ -7,4 +7,5 @@
SharedLibrary('npthirdtest')
relative_path = 'thirdplugin'
cocoa_name = 'ThirdTest'
include('../testplugin.mozbuild')

Просмотреть файл

@ -706,13 +706,15 @@ StripURIForReporting(nsIURI* aURI,
// 1) If the origin of uri is a globally unique identifier (for example,
// aURI has a scheme of data, blob, or filesystem), then return the
// ASCII serialization of uris scheme.
bool isHttp =
(NS_SUCCEEDED(aURI->SchemeIs("http", &isHttp)) && isHttp) ||
(NS_SUCCEEDED(aURI->SchemeIs("https", &isHttp)) && isHttp);
if (!isHttp) {
bool isHttpOrFtp =
(NS_SUCCEEDED(aURI->SchemeIs("http", &isHttpOrFtp)) && isHttpOrFtp) ||
(NS_SUCCEEDED(aURI->SchemeIs("https", &isHttpOrFtp)) && isHttpOrFtp) ||
(NS_SUCCEEDED(aURI->SchemeIs("ftp", &isHttpOrFtp)) && isHttpOrFtp);
if (!isHttpOrFtp) {
// not strictly spec compliant, but what we really care about is
// http/https. If it's not http/https, then treat aURI as if
// it's a globally unique identifier and just return the scheme.
// http/https and also ftp. If it's not http/https or ftp, then treat aURI
// as if it's a globally unique identifier and just return the scheme.
aURI->GetScheme(outStrippedURI);
return;
}

Просмотреть файл

@ -212,4 +212,13 @@ function run_test() {
NetUtil.newURI(selfSpec + "#bar"),
null, null, null, null);
});
// test scheme of ftp:
makeTest(8, {"blocked-uri": "ftp://blocked.test"}, false,
function(csp) {
// shouldLoad creates and sends out the report here.
csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SCRIPT,
NetUtil.newURI("ftp://blocked.test/profile.png"),
null, null, null, null);
});
}

Просмотреть файл

@ -5092,7 +5092,7 @@ nsEditor::IsAcceptableInputEvent(nsIDOMEvent* aEvent)
break;
}
if (needsWidget &&
(!widgetGUIEvent || !widgetGUIEvent->widget)) {
(!widgetGUIEvent || !widgetGUIEvent->mWidget)) {
return false;
}

Просмотреть файл

@ -644,7 +644,7 @@ nsEditorEventListener::KeyPress(nsIDOMKeyEvent* aKeyEvent)
aKeyEvent->AsEvent()->WidgetEventPtr()->AsKeyboardEvent();
MOZ_ASSERT(keyEvent,
"DOM key event's internal event must be WidgetKeyboardEvent");
nsIWidget* widget = keyEvent->widget;
nsIWidget* widget = keyEvent->mWidget;
// If the event is created by chrome script, the widget is always nullptr.
if (!widget) {
nsCOMPtr<nsIPresShell> ps = GetPresShell();

Просмотреть файл

@ -55,6 +55,8 @@ WIN_LIBS= \
// This is for extending the dialog
#include <dlgs.h>
#include "nsWindowsHelpers.h"
// Default labels for the radio buttons
static const char* kAsLaidOutOnScreenStr = "As &laid out on the screen";
static const char* kTheSelectedFrameStr = "The selected &frame";
@ -462,79 +464,71 @@ static UINT CALLBACK PrintHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM
// This function assumes that aPrintName has already been converted from
// unicode
//
HGLOBAL CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, nsIPrintSettings* aPS)
static nsReturnRef<nsHGLOBAL>
CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName,
nsIPrintSettings* aPS)
{
HGLOBAL hGlobalDevMode = nullptr;
HANDLE hPrinter = nullptr;
nsHPRINTER hPrinter = nullptr;
// const cast kludge for silly Win32 api's
LPWSTR printName = const_cast<wchar_t*>(static_cast<const wchar_t*>(aPrintName.get()));
BOOL status = ::OpenPrinterW(printName, &hPrinter, nullptr);
if (status) {
LPDEVMODEW pNewDevMode;
DWORD dwNeeded, dwRet;
// Get the buffer size
dwNeeded = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, nullptr, nullptr, 0);
if (dwNeeded == 0) {
return nullptr;
}
// Allocate a buffer of the correct size.
pNewDevMode = (LPDEVMODEW)::HeapAlloc (::GetProcessHeap(), HEAP_ZERO_MEMORY, dwNeeded);
if (!pNewDevMode) return nullptr;
hGlobalDevMode = (HGLOBAL)::GlobalAlloc(GHND, dwNeeded);
if (!hGlobalDevMode) {
::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
return nullptr;
}
dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, pNewDevMode, nullptr, DM_OUT_BUFFER);
if (dwRet != IDOK) {
::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
::GlobalFree(hGlobalDevMode);
::ClosePrinter(hPrinter);
return nullptr;
}
// Lock memory and copy contents from DEVMODE (current printer)
// to Global Memory DEVMODE
LPDEVMODEW devMode = (DEVMODEW *)::GlobalLock(hGlobalDevMode);
if (devMode) {
memcpy(devMode, pNewDevMode, dwNeeded);
// Initialize values from the PrintSettings
nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aPS);
MOZ_ASSERT(psWin);
psWin->CopyToNative(devMode);
// Sets back the changes we made to the DevMode into the Printer Driver
dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, devMode, devMode, DM_IN_BUFFER | DM_OUT_BUFFER);
if (dwRet != IDOK) {
::GlobalUnlock(hGlobalDevMode);
::GlobalFree(hGlobalDevMode);
::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
::ClosePrinter(hPrinter);
return nullptr;
}
::GlobalUnlock(hGlobalDevMode);
} else {
::GlobalFree(hGlobalDevMode);
hGlobalDevMode = nullptr;
}
::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
::ClosePrinter(hPrinter);
} else {
return nullptr;
if (!status) {
return nsReturnRef<nsHGLOBAL>();
}
return hGlobalDevMode;
// Make sure hPrinter is closed on all paths
nsAutoPrinter autoPrinter(hPrinter);
// Get the buffer size
DWORD dwNeeded = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, nullptr,
nullptr, 0);
if (dwNeeded == 0) {
return nsReturnRef<nsHGLOBAL>();
}
// Allocate a buffer of the correct size.
nsAutoDevMode newDevMode((LPDEVMODEW)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY,
dwNeeded));
if (!newDevMode) {
return nsReturnRef<nsHGLOBAL>();
}
nsHGLOBAL hDevMode = ::GlobalAlloc(GHND, dwNeeded);
nsAutoGlobalMem globalDevMode(hDevMode);
if (!hDevMode) {
return nsReturnRef<nsHGLOBAL>();
}
DWORD dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, newDevMode,
nullptr, DM_OUT_BUFFER);
if (dwRet != IDOK) {
return nsReturnRef<nsHGLOBAL>();
}
// Lock memory and copy contents from DEVMODE (current printer)
// to Global Memory DEVMODE
LPDEVMODEW devMode = (DEVMODEW *)::GlobalLock(hDevMode);
if (!devMode) {
return nsReturnRef<nsHGLOBAL>();
}
memcpy(devMode, newDevMode.get(), dwNeeded);
// Initialize values from the PrintSettings
nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aPS);
MOZ_ASSERT(psWin);
psWin->CopyToNative(devMode);
// Sets back the changes we made to the DevMode into the Printer Driver
dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, devMode, devMode,
DM_IN_BUFFER | DM_OUT_BUFFER);
if (dwRet != IDOK) {
::GlobalUnlock(hDevMode);
return nsReturnRef<nsHGLOBAL>();
}
::GlobalUnlock(hDevMode);
return globalDevMode.out();
}
//------------------------------------------------------------------
@ -576,9 +570,6 @@ ShowNativePrintDialog(HWND aHWnd,
gDialogWasExtended = false;
HGLOBAL hGlobalDevMode = nullptr;
HGLOBAL hDevNames = nullptr;
// Get the Print Name to be used
nsXPIDLString printerName;
aPrintSettings->GetPrinterName(getter_Copies(printerName));
@ -588,7 +579,8 @@ ShowNativePrintDialog(HWND aHWnd,
GetDefaultPrinterNameFromGlobalPrinters(printerName);
} else {
HANDLE hPrinter = nullptr;
if(!::OpenPrinterW(const_cast<wchar_t*>(static_cast<const wchar_t*>(printerName.get())), &hPrinter, nullptr)) {
if(!::OpenPrinterW(const_cast<wchar_t*>(static_cast<const wchar_t*>(printerName.get())),
&hPrinter, nullptr)) {
// If the last used printer is not found, we should use default printer.
GetDefaultPrinterNameFromGlobalPrinters(printerName);
} else {
@ -599,15 +591,15 @@ ShowNativePrintDialog(HWND aHWnd,
// Now create a DEVNAMES struct so the the dialog is initialized correctly.
uint32_t len = printerName.Length();
hDevNames = (HGLOBAL)::GlobalAlloc(GHND, sizeof(wchar_t) * (len + 1) +
sizeof(DEVNAMES));
nsHGLOBAL hDevNames = ::GlobalAlloc(GHND, sizeof(wchar_t) * (len + 1)
+ sizeof(DEVNAMES));
nsAutoGlobalMem autoDevNames(hDevNames);
if (!hDevNames) {
return NS_ERROR_OUT_OF_MEMORY;
}
DEVNAMES* pDevNames = (DEVNAMES*)::GlobalLock(hDevNames);
if (!pDevNames) {
::GlobalFree(hDevNames);
return NS_ERROR_FAILURE;
}
pDevNames->wDriverOffset = sizeof(DEVNAMES)/sizeof(wchar_t);
@ -621,10 +613,8 @@ ShowNativePrintDialog(HWND aHWnd,
// Create a Moveable Memory Object that holds a new DevMode
// from the Printer Name
// The PRINTDLG.hDevMode requires that it be a moveable memory object
// NOTE: We only need to free hGlobalDevMode when the dialog is cancelled
// When the user prints, it comes back in the printdlg struct and
// is used and cleaned up later
hGlobalDevMode = CreateGlobalDevModeAndInit(printerName, aPrintSettings);
// NOTE: autoDevMode is automatically freed when any error occurred
nsAutoGlobalMem autoDevMode(CreateGlobalDevModeAndInit(printerName, aPrintSettings));
// Prepare to Display the Print Dialog
PRINTDLGW prntdlg;
@ -632,7 +622,7 @@ ShowNativePrintDialog(HWND aHWnd,
prntdlg.lStructSize = sizeof(prntdlg);
prntdlg.hwndOwner = aHWnd;
prntdlg.hDevMode = hGlobalDevMode;
prntdlg.hDevMode = autoDevMode.get();
prntdlg.hDevNames = hDevNames;
prntdlg.hDC = nullptr;
prntdlg.Flags = PD_ALLPAGES | PD_RETURNIC |
@ -682,13 +672,11 @@ ShowNativePrintDialog(HWND aHWnd,
NS_ENSURE_TRUE(aPrintSettings && prntdlg.hDevMode, NS_ERROR_FAILURE);
if (prntdlg.hDevNames == nullptr) {
::GlobalFree(hGlobalDevMode);
return NS_ERROR_FAILURE;
}
// Lock the deviceNames and check for nullptr
DEVNAMES *devnames = (DEVNAMES *)::GlobalLock(prntdlg.hDevNames);
if (devnames == nullptr) {
::GlobalFree(hGlobalDevMode);
return NS_ERROR_FAILURE;
}
@ -716,7 +704,6 @@ ShowNativePrintDialog(HWND aHWnd,
nsCOMPtr<nsIPrintSettingsWin> psWin(do_QueryInterface(aPrintSettings));
if (!psWin) {
::GlobalFree(hGlobalDevMode);
return NS_ERROR_FAILURE;
}
@ -772,7 +759,6 @@ ShowNativePrintDialog(HWND aHWnd,
// Transfer the settings from the native data to the PrintSettings
LPDEVMODEW devMode = (LPDEVMODEW)::GlobalLock(prntdlg.hDevMode);
if (!devMode || !prntdlg.hDC) {
::GlobalFree(hGlobalDevMode);
return NS_ERROR_FAILURE;
}
psWin->SetDevMode(devMode); // copies DevMode
@ -805,7 +791,6 @@ ShowNativePrintDialog(HWND aHWnd,
} else {
::SetFocus(aHWnd);
aPrintSettings->SetIsCancelled(true);
if (hGlobalDevMode) ::GlobalFree(hGlobalDevMode);
return NS_ERROR_ABORT;
}

Просмотреть файл

@ -9,6 +9,4 @@ nsresult NativeShowPrintDialog(HWND aHWnd,
nsIWebBrowserPrint* aWebBrowserPrint,
nsIPrintSettings* aPrintSettings);
HGLOBAL CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, nsIPrintSettings* aPS);
#endif /* nsFlyOwnDialog_h___ */

Просмотреть файл

@ -36,14 +36,6 @@ public:
*/
virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) = 0;
/**
* Acknowledges the recipt of a scroll offset update for the scrollable
* frame with the given scroll id. This is used to maintain consistency
* between APZ and other sources of scroll changes.
*/
virtual void AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId,
const uint32_t& aScrollGeneration) = 0;
/**
* Requests handling of a double tap. |aPoint| is in CSS pixels, relative to
* the current scroll offset. This should eventually round-trip back to

Просмотреть файл

@ -3457,7 +3457,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
mScrollMetadata = aScrollMetadata;
if (scrollOffsetUpdated) {
AcknowledgeScrollUpdate();
needContentRepaint = true;
}
mExpectedGeckoMetrics = aLayerMetrics;
ShareCompositorFrameMetrics();
@ -3532,7 +3532,6 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
// correct this we need to update mExpectedGeckoMetrics to be the
// last thing we know was painted by Gecko.
mFrameMetrics.CopyScrollInfoFrom(aLayerMetrics);
AcknowledgeScrollUpdate();
mExpectedGeckoMetrics = aLayerMetrics;
// Cancel the animation (which might also trigger a repaint request)
@ -3564,7 +3563,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
// See comment on the similar code in the |if (scrollOffsetUpdated)| block
// above.
mFrameMetrics.CopySmoothScrollInfoFrom(aLayerMetrics);
AcknowledgeScrollUpdate();
needContentRepaint = true;
mExpectedGeckoMetrics = aLayerMetrics;
SmoothScrollTo(mFrameMetrics.GetSmoothScrollOffset());
@ -3576,21 +3575,6 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
UpdateSharedCompositorFrameMetrics();
}
void
AsyncPanZoomController::AcknowledgeScrollUpdate() const
{
// Once layout issues a scroll offset update, it becomes impervious to
// scroll offset updates from APZ until we acknowledge the update it sent.
// This prevents APZ updates from clobbering scroll updates from other
// more "legitimate" sources like content scripts.
RefPtr<GeckoContentController> controller = GetGeckoContentController();
if (controller) {
APZC_LOG("%p sending scroll update acknowledgement with gen %u\n", this, mFrameMetrics.GetScrollGeneration());
controller->AcknowledgeScrollUpdate(mFrameMetrics.GetScrollId(),
mFrameMetrics.GetScrollGeneration());
}
}
const FrameMetrics& AsyncPanZoomController::GetFrameMetrics() const {
mMonitor.AssertCurrentThreadIn();
return mFrameMetrics;

Просмотреть файл

@ -896,8 +896,6 @@ private:
// Returns whether overscroll is allowed during an event.
bool AllowScrollHandoffInCurrentBlock() const;
void AcknowledgeScrollUpdate() const;
/* ===================================================================
* The functions and members in this section are used to make ancestor chains
* out of APZC instances. These chains can only be walked or manipulated

Просмотреть файл

@ -124,9 +124,9 @@ ScrollFrame(nsIContent* aContent,
// Scroll the window to the desired spot
nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aMetrics.GetScrollId());
if (sf) {
sf->ResetScrollInfoIfGeneration(aMetrics.GetScrollGeneration());
sf->SetScrollableByAPZ(!aMetrics.IsScrollInfoLayer());
}
bool scrollUpdated = false;
CSSPoint apzScrollOffset = aMetrics.GetScrollOffset();
CSSPoint actualScrollOffset = ScrollFrameTo(sf, apzScrollOffset, scrollUpdated);
@ -330,54 +330,6 @@ APZCCallbackHelper::InitializeRootDisplayport(nsIPresShell* aPresShell)
}
}
class AcknowledgeScrollUpdateEvent : public nsRunnable
{
typedef mozilla::layers::FrameMetrics::ViewID ViewID;
public:
AcknowledgeScrollUpdateEvent(const ViewID& aScrollId, const uint32_t& aScrollGeneration)
: mScrollId(aScrollId)
, mScrollGeneration(aScrollGeneration)
{
}
NS_IMETHOD Run() {
MOZ_ASSERT(NS_IsMainThread());
nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(mScrollId);
if (sf) {
sf->ResetScrollInfoIfGeneration(mScrollGeneration);
}
// Since the APZ and content are in sync, we need to clear any callback transform
// that might have been set on the last repaint request (which might have failed
// due to the inflight scroll update that this message is acknowledging).
nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(mScrollId);
if (content) {
content->SetProperty(nsGkAtoms::apzCallbackTransform, new CSSPoint(),
nsINode::DeleteProperty<CSSPoint>);
}
return NS_OK;
}
protected:
ViewID mScrollId;
uint32_t mScrollGeneration;
};
void
APZCCallbackHelper::AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId,
const uint32_t& aScrollGeneration)
{
nsCOMPtr<nsIRunnable> r1 = new AcknowledgeScrollUpdateEvent(aScrollId, aScrollGeneration);
if (!NS_IsMainThread()) {
NS_DispatchToMainThread(r1);
} else {
r1->Run();
}
}
nsIPresShell*
APZCCallbackHelper::GetRootContentDocumentPresShellForContent(nsIContent* aContent)
{
@ -514,8 +466,8 @@ nsEventStatus
APZCCallbackHelper::DispatchWidgetEvent(WidgetGUIEvent& aEvent)
{
nsEventStatus status = nsEventStatus_eConsumeNoDefault;
if (aEvent.widget) {
aEvent.widget->DispatchEvent(&aEvent, status);
if (aEvent.mWidget) {
aEvent.mWidget->DispatchEvent(&aEvent, status);
}
return status;
}
@ -530,7 +482,7 @@ APZCCallbackHelper::DispatchSynthesizedMouseEvent(EventMessage aMsg,
MOZ_ASSERT(aMsg == eMouseMove || aMsg == eMouseDown ||
aMsg == eMouseUp || aMsg == eMouseLongTap);
WidgetMouseEvent event(true, aMsg, nullptr,
WidgetMouseEvent event(true, aMsg, aWidget,
WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
event.refPoint = LayoutDeviceIntPoint(aRefPoint.x, aRefPoint.y);
event.mTime = aTime;
@ -541,7 +493,6 @@ APZCCallbackHelper::DispatchSynthesizedMouseEvent(EventMessage aMsg,
event.clickCount = 1;
}
event.mModifiers = aModifiers;
event.widget = aWidget;
return DispatchWidgetEvent(event);
}

Просмотреть файл

@ -66,11 +66,6 @@ public:
given presShell. */
static void InitializeRootDisplayport(nsIPresShell* aPresShell);
/* Tell layout that we received the scroll offset update for the given view ID, so
that it accepts future scroll offset updates from APZ. */
static void AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId,
const uint32_t& aScrollGeneration);
/* Get the pres shell associated with the root content document enclosing |aContent|. */
static nsIPresShell* GetRootContentDocumentPresShellForContent(nsIContent* aContent);

Просмотреть файл

@ -328,7 +328,7 @@ APZEventState::ProcessTouchEvent(const WidgetTouchEvent& aEvent,
}
}
nsEventStatus status;
cancelEvent.widget->DispatchEvent(&cancelEvent, status);
cancelEvent.mWidget->DispatchEvent(&cancelEvent, status);
}
}

Просмотреть файл

@ -68,13 +68,6 @@ ChromeProcessController::PostDelayedTask(Task* aTask, int aDelayMs)
MessageLoop::current()->PostDelayedTask(FROM_HERE, aTask, aDelayMs);
}
void
ChromeProcessController::AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId,
const uint32_t& aScrollGeneration)
{
APZCCallbackHelper::AcknowledgeScrollUpdate(aScrollId, aScrollGeneration);
}
void
ChromeProcessController::Destroy()
{

Просмотреть файл

@ -40,9 +40,6 @@ public:
// GeckoContentController interface
virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) override;
virtual void PostDelayedTask(Task* aTask, int aDelayMs) override;
virtual void AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId,
const uint32_t& aScrollGeneration) override;
virtual void HandleDoubleTap(const mozilla::CSSPoint& aPoint, Modifiers aModifiers,
const ScrollableLayerGuid& aGuid) override;
virtual void HandleSingleTap(const mozilla::CSSPoint& aPoint, Modifiers aModifiers,

Просмотреть файл

@ -94,14 +94,6 @@ APZChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics)
return mBrowser->UpdateFrame(aFrameMetrics);
}
bool
APZChild::RecvAcknowledgeScrollUpdate(const ViewID& aScrollId,
const uint32_t& aScrollGeneration)
{
APZCCallbackHelper::AcknowledgeScrollUpdate(aScrollId, aScrollGeneration);
return true;
}
bool
APZChild::RecvHandleDoubleTap(const CSSPoint& aPoint,
const Modifiers& aModifiers,

Просмотреть файл

@ -28,9 +28,6 @@ public:
virtual bool RecvUpdateFrame(const FrameMetrics& frame) override;
virtual bool RecvAcknowledgeScrollUpdate(const ViewID& aScrollId,
const uint32_t& aScrollGeneration) override;
virtual bool RecvHandleDoubleTap(const CSSPoint& aPoint,
const Modifiers& aModifiers,
const ScrollableLayerGuid& aGuid) override;

Просмотреть файл

@ -89,7 +89,6 @@ child:
// The following methods correspond to functions on the GeckoContentController
// interface in gfx/layers/apz/public/GeckoContentController.h. Refer to documentation
// in that file for these functions.
async AcknowledgeScrollUpdate(ViewID aScrollId, uint32_t aScrollGeneration);
async HandleDoubleTap(CSSPoint aPoint, Modifiers aModifiers, ScrollableLayerGuid aGuid);
async HandleSingleTap(CSSPoint aPoint, Modifiers aModifiers, ScrollableLayerGuid aGuid, bool aCallTakeFocusForClickFromTap);
async HandleLongTap(CSSPoint point, Modifiers aModifiers, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);

Просмотреть файл

@ -51,24 +51,6 @@ RemoteContentController::RequestContentRepaint(const FrameMetrics& aFrameMetrics
}
}
void
RemoteContentController::AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId,
const uint32_t& aScrollGeneration)
{
if (MessageLoop::current() != mUILoop) {
// We have to send this message from the "UI thread" (main
// thread).
mUILoop->PostTask(
FROM_HERE,
NewRunnableMethod(this, &RemoteContentController::AcknowledgeScrollUpdate,
aScrollId, aScrollGeneration));
return;
}
if (CanSend()) {
Unused << SendAcknowledgeScrollUpdate(aScrollId, aScrollGeneration);
}
}
void
RemoteContentController::HandleDoubleTap(const CSSPoint& aPoint,
Modifiers aModifiers,

Просмотреть файл

@ -42,9 +42,6 @@ public:
// Needs to be called on the main thread.
virtual void RequestContentRepaint(const FrameMetrics& aFrameMetrics) override;
virtual void AcknowledgeScrollUpdate(const FrameMetrics::ViewID& aScrollId,
const uint32_t& aScrollGeneration) override;
virtual void HandleDoubleTap(const CSSPoint& aPoint,
Modifiers aModifiers,
const ScrollableLayerGuid& aGuid) override;

Просмотреть файл

@ -135,6 +135,9 @@ private:
// It's a short time fix, and will be removed after landing bug 1206637.
DECL_GFX_PREF(Live, "accessibility.monoaudio.enable", MonoAudio, bool, false);
DECL_GFX_PREF(Live, "media.resampling.enabled", AudioSinkResampling, bool, false);
DECL_GFX_PREF(Live, "media.resampling.rate", AudioSinkResampleRate, uint32_t, 48000);
DECL_GFX_PREF(Live, "media.forcestereo.enabled", AudioSinkForceStereo, bool, true);
// The apz prefs are explained in AsyncPanZoomController.cpp
DECL_GFX_PREF(Live, "apz.allow_checkerboarding", APZAllowCheckerboarding, bool, true);

Просмотреть файл

@ -81,6 +81,16 @@ Unify(ExprType one, ExprType two)
return ExprType::Void;
}
static bool
IsI64Implemented()
{
#ifdef JS_CPU_X64
return true;
#else
return false;
#endif
}
class FunctionDecoder
{
JSContext* cx_;
@ -108,11 +118,9 @@ class FunctionDecoder
return Fail(cx_, d_, str);
}
bool checkI64Support() {
#ifdef JS_CPU_X64
if (!IsI64Implemented())
return fail("i64 NYI on this platform");
return true;
#else
return fail("i64 NYI on this platform");
#endif
}
MOZ_WARN_UNUSED_RESULT bool pushBlock() {
@ -1073,14 +1081,16 @@ DecodeFunctionTable(JSContext* cx, Decoder& d, ModuleGeneratorData* init)
static bool
CheckTypeForJS(JSContext* cx, Decoder& d, const Sig& sig)
{
bool allowI64 = IsI64Implemented() && JitOptions.wasmTestMode;
for (ValType argType : sig.args()) {
if (argType == ValType::I64)
if (argType == ValType::I64 && !allowI64)
return Fail(cx, d, "cannot import/export i64 argument");
if (IsSimdType(argType))
return Fail(cx, d, "cannot import/export SIMD argument");
}
if (sig.ret() == ExprType::I64)
if (sig.ret() == ExprType::I64 && !allowI64)
return Fail(cx, d, "cannot import/export i64 return type");
if (IsSimdType(sig.ret()))
return Fail(cx, d, "cannot import/export SIMD return type");

Просмотреть файл

@ -958,6 +958,12 @@ class FunctionCompiler
return numPushed;
}
static MDefinition* peekPushedDef(MBasicBlock* block)
{
MOZ_ASSERT(hasPushed(block));
return block->getSlot(block->stackDepth() - 1);
}
public:
void pushDef(MDefinition* def)
{
@ -968,21 +974,39 @@ class FunctionCompiler
curBlock_->push(def);
}
MDefinition* popDefIfPushed()
{
if (!hasPushed(curBlock_))
return nullptr;
MDefinition* def = curBlock_->pop();
MOZ_ASSERT(def->type() != MIRType_Value);
return def;
}
template <typename GetBlock>
void ensurePushInvariants(const GetBlock& getBlock, size_t numBlocks)
{
// Preserve the invariant that, for every iterated MBasicBlock,
// either: every MBasicBlock has a non-void pushed expression OR no
// MBasicBlock has any pushed expression. This is required by
// MBasicBlock::addPredecessor.
bool allPushed = true;
// Preserve the invariant that, for every iterated MBasicBlock, either:
// every MBasicBlock has a pushed expression with the same type (to
// prevent creating phis with type Value) OR no MBasicBlock has any
// pushed expression. This is required by MBasicBlock::addPredecessor.
if (numBlocks < 2)
return;
for (size_t i = 0; allPushed && i < numBlocks; i++)
allPushed = hasPushed(getBlock(i));
MBasicBlock* block = getBlock(0);
bool allPushed = hasPushed(block);
if (allPushed) {
MIRType type = peekPushedDef(block)->type();
for (size_t i = 1; allPushed && i < numBlocks; i++) {
block = getBlock(i);
allPushed = hasPushed(block) && peekPushedDef(block)->type() == type;
}
}
if (!allPushed) {
for (size_t i = 0; i < numBlocks; i++) {
MBasicBlock* block = getBlock(i);
block = getBlock(i);
if (hasPushed(block))
block->pop();
}
@ -1034,10 +1058,7 @@ class FunctionCompiler
}
curBlock_ = join;
if (hasPushed(curBlock_))
*def = curBlock_->pop();
else
*def = nullptr;
*def = popDefIfPushed();
return true;
}
@ -1357,7 +1378,7 @@ class FunctionCompiler
bool bindBranches(uint32_t absolute, MDefinition** def)
{
if (absolute >= blockPatches_.length() || blockPatches_[absolute].empty()) {
*def = !inDeadCode() && hasPushed(curBlock_) ? curBlock_->pop() : nullptr;
*def = inDeadCode() ? nullptr : popDefIfPushed();
return true;
}
@ -1400,7 +1421,7 @@ class FunctionCompiler
return false;
curBlock_ = join;
*def = hasPushed(curBlock_) ? curBlock_->pop() : nullptr;
*def = popDefIfPushed();
patches.clear();
return true;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше